This commit is contained in:
Luke Wagner 2010-07-14 23:19:36 -07:00
Родитель 29d5a7430a
Коммит 7371ad00ed
213 изменённых файлов: 17677 добавлений и 15170 удалений

Просмотреть файл

@ -51,7 +51,7 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
[noscript] void checkPropertyAccess(in JSContextPtr aJSContext, [noscript] void checkPropertyAccess(in JSContextPtr aJSContext,
in JSObjectPtr aJSObject, in JSObjectPtr aJSObject,
in string aClassName, in string aClassName,
in jsval aProperty, in jsid aProperty,
in PRUint32 aAction); in PRUint32 aAction);
/** /**

Просмотреть файл

@ -175,7 +175,7 @@ union SecurityLevel
struct PropertyPolicy : public PLDHashEntryHdr struct PropertyPolicy : public PLDHashEntryHdr
{ {
jsval key; // property name as jsval JSString *key; // interned string
SecurityLevel mGet; SecurityLevel mGet;
SecurityLevel mSet; SecurityLevel mSet;
}; };
@ -186,7 +186,7 @@ InitPropertyPolicyEntry(PLDHashTable *table,
const void *key) const void *key)
{ {
PropertyPolicy* pp = (PropertyPolicy*)entry; PropertyPolicy* pp = (PropertyPolicy*)entry;
pp->key = (jsval)key; pp->key = (JSString *)key;
pp->mGet.level = SCRIPT_SECURITY_UNDEFINED_ACCESS; pp->mGet.level = SCRIPT_SECURITY_UNDEFINED_ACCESS;
pp->mSet.level = SCRIPT_SECURITY_UNDEFINED_ACCESS; pp->mSet.level = SCRIPT_SECURITY_UNDEFINED_ACCESS;
return PR_TRUE; return PR_TRUE;
@ -196,7 +196,7 @@ static void
ClearPropertyPolicyEntry(PLDHashTable *table, PLDHashEntryHdr *entry) ClearPropertyPolicyEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
{ {
PropertyPolicy* pp = (PropertyPolicy*)entry; PropertyPolicy* pp = (PropertyPolicy*)entry;
pp->key = JSVAL_VOID; pp->key = NULL;
} }
// Class Policy // Class Policy
@ -426,7 +426,7 @@ private:
static JSBool static JSBool
CheckObjectAccess(JSContext *cx, JSObject *obj, CheckObjectAccess(JSContext *cx, JSObject *obj,
jsval id, JSAccessMode mode, jsid id, JSAccessMode mode,
jsval *vp); jsval *vp);
// Decides, based on CSP, whether or not eval() and stuff can be executed. // Decides, based on CSP, whether or not eval() and stuff can be executed.
@ -453,7 +453,7 @@ private:
JSContext* cx, JSObject* aJSObject, JSContext* cx, JSObject* aJSObject,
nsISupports* aObj, nsIURI* aTargetURI, nsISupports* aObj, nsIURI* aTargetURI,
nsIClassInfo* aClassInfo, nsIClassInfo* aClassInfo,
const char* aClassName, jsval aProperty, const char* aClassName, jsid aProperty,
void** aCachedClassPolicy); void** aCachedClassPolicy);
nsresult nsresult
@ -463,7 +463,7 @@ private:
nsresult nsresult
LookupPolicy(nsIPrincipal* principal, LookupPolicy(nsIPrincipal* principal,
ClassInfoData& aClassData, jsval aProperty, ClassInfoData& aClassData, jsid aProperty,
PRUint32 aAction, PRUint32 aAction,
ClassPolicy** aCachedClassPolicy, ClassPolicy** aCachedClassPolicy,
SecurityLevel* result); SecurityLevel* result);
@ -612,7 +612,7 @@ private:
}; };
// JS strings we need to clean up on shutdown // JS strings we need to clean up on shutdown
static jsval sEnabledID; static jsid sEnabledID;
inline void inline void
ScriptSecurityPrefChanged(); ScriptSecurityPrefChanged();

Просмотреть файл

@ -116,9 +116,15 @@ static JSEqualityOp sXPCWrappedNativeEqualityOps;
/////////////////////////// ///////////////////////////
// Result of this function should not be freed. // Result of this function should not be freed.
static inline const PRUnichar * static inline const PRUnichar *
JSValIDToString(JSContext *cx, const jsval idval) IDToString(JSContext *cx, jsid id)
{ {
if (JSID_IS_STRING(id))
return reinterpret_cast<PRUnichar*>(JS_GetStringChars(JSID_TO_STRING(id)));
JSAutoRequest ar(cx); JSAutoRequest ar(cx);
jsval idval;
if (!JS_IdToValue(cx, id, &idval))
return nsnull;
JSString *str = JS_ValueToString(cx, idval); JSString *str = JS_ValueToString(cx, idval);
if(!str) if(!str)
return nsnull; return nsnull;
@ -565,7 +571,7 @@ nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(JSContext *cx)
JSBool JSBool
nsScriptSecurityManager::CheckObjectAccess(JSContext *cx, JSObject *obj, nsScriptSecurityManager::CheckObjectAccess(JSContext *cx, JSObject *obj,
jsval id, JSAccessMode mode, jsid id, JSAccessMode mode,
jsval *vp) jsval *vp)
{ {
// Get the security manager // Get the security manager
@ -604,7 +610,7 @@ NS_IMETHODIMP
nsScriptSecurityManager::CheckPropertyAccess(JSContext* cx, nsScriptSecurityManager::CheckPropertyAccess(JSContext* cx,
JSObject* aJSObject, JSObject* aJSObject,
const char* aClassName, const char* aClassName,
jsval aProperty, jsid aProperty,
PRUint32 aAction) PRUint32 aAction)
{ {
return CheckPropertyAccessImpl(aAction, nsnull, cx, aJSObject, return CheckPropertyAccessImpl(aAction, nsnull, cx, aJSObject,
@ -684,7 +690,7 @@ nsScriptSecurityManager::CheckPropertyAccessImpl(PRUint32 aAction,
JSContext* cx, JSObject* aJSObject, JSContext* cx, JSObject* aJSObject,
nsISupports* aObj, nsIURI* aTargetURI, nsISupports* aObj, nsIURI* aTargetURI,
nsIClassInfo* aClassInfo, nsIClassInfo* aClassInfo,
const char* aClassName, jsval aProperty, const char* aClassName, jsid aProperty,
void** aCachedClassPolicy) void** aCachedClassPolicy)
{ {
nsresult rv; nsresult rv;
@ -703,7 +709,7 @@ nsScriptSecurityManager::CheckPropertyAccessImpl(PRUint32 aAction,
ClassInfoData classInfoData(aClassInfo, aClassName); ClassInfoData classInfoData(aClassInfo, aClassName);
#ifdef DEBUG_CAPS_CheckPropertyAccessImpl #ifdef DEBUG_CAPS_CheckPropertyAccessImpl
nsCAutoString propertyName; nsCAutoString propertyName;
propertyName.AssignWithConversion((PRUnichar*)JSValIDToString(cx, aProperty)); propertyName.AssignWithConversion((PRUnichar*)IDToString(cx, aProperty));
printf("### CanAccess(%s.%s, %i) ", classInfoData.GetName(), printf("### CanAccess(%s.%s, %i) ", classInfoData.GetName(),
propertyName.get(), aAction); propertyName.get(), aAction);
#endif #endif
@ -825,17 +831,17 @@ nsScriptSecurityManager::CheckPropertyAccessImpl(PRUint32 aAction,
{ {
case nsIXPCSecurityManager::ACCESS_GET_PROPERTY: case nsIXPCSecurityManager::ACCESS_GET_PROPERTY:
checkedComponent->CanGetProperty(objIID, checkedComponent->CanGetProperty(objIID,
JSValIDToString(cx, aProperty), IDToString(cx, aProperty),
getter_Copies(objectSecurityLevel)); getter_Copies(objectSecurityLevel));
break; break;
case nsIXPCSecurityManager::ACCESS_SET_PROPERTY: case nsIXPCSecurityManager::ACCESS_SET_PROPERTY:
checkedComponent->CanSetProperty(objIID, checkedComponent->CanSetProperty(objIID,
JSValIDToString(cx, aProperty), IDToString(cx, aProperty),
getter_Copies(objectSecurityLevel)); getter_Copies(objectSecurityLevel));
break; break;
case nsIXPCSecurityManager::ACCESS_CALL_METHOD: case nsIXPCSecurityManager::ACCESS_CALL_METHOD:
checkedComponent->CanCallMethod(objIID, checkedComponent->CanCallMethod(objIID,
JSValIDToString(cx, aProperty), IDToString(cx, aProperty),
getter_Copies(objectSecurityLevel)); getter_Copies(objectSecurityLevel));
} }
} }
@ -906,7 +912,7 @@ nsScriptSecurityManager::CheckPropertyAccessImpl(PRUint32 aAction,
{ {
subjectOriginUnicode.get(), subjectOriginUnicode.get(),
className.get(), className.get(),
JSValIDToString(cx, aProperty), IDToString(cx, aProperty),
objectOriginUnicode.get(), objectOriginUnicode.get(),
subjectDomainUnicode.get(), subjectDomainUnicode.get(),
objectDomainUnicode.get() objectDomainUnicode.get()
@ -1075,7 +1081,7 @@ nsScriptSecurityManager::CheckSameOriginDOMProp(nsIPrincipal* aSubject,
nsresult nsresult
nsScriptSecurityManager::LookupPolicy(nsIPrincipal* aPrincipal, nsScriptSecurityManager::LookupPolicy(nsIPrincipal* aPrincipal,
ClassInfoData& aClassData, ClassInfoData& aClassData,
jsval aProperty, jsid aProperty,
PRUint32 aAction, PRUint32 aAction,
ClassPolicy** aCachedClassPolicy, ClassPolicy** aCachedClassPolicy,
SecurityLevel* result) SecurityLevel* result)
@ -1186,6 +1192,15 @@ nsScriptSecurityManager::LookupPolicy(nsIPrincipal* aPrincipal,
*aCachedClassPolicy = cpolicy; *aCachedClassPolicy = cpolicy;
} }
NS_ASSERTION(JSID_IS_INT(aProperty) || JSID_IS_OBJECT(aProperty) ||
JSID_IS_STRING(aProperty), "Property must be a valid id");
// Only atomized strings are stored in the policies' hash tables.
if (!JSID_IS_STRING(aProperty))
return NS_OK;
JSString *propertyKey = JSID_TO_STRING(aProperty);
// We look for a PropertyPolicy in the following places: // We look for a PropertyPolicy in the following places:
// 1) The ClassPolicy for our class we got from our DomainPolicy // 1) The ClassPolicy for our class we got from our DomainPolicy
// 2) The mWildcardPolicy of our DomainPolicy // 2) The mWildcardPolicy of our DomainPolicy
@ -1196,7 +1211,7 @@ nsScriptSecurityManager::LookupPolicy(nsIPrincipal* aPrincipal,
{ {
ppolicy = static_cast<PropertyPolicy*> ppolicy = static_cast<PropertyPolicy*>
(PL_DHashTableOperate(cpolicy->mPolicy, (PL_DHashTableOperate(cpolicy->mPolicy,
(void*)aProperty, propertyKey,
PL_DHASH_LOOKUP)); PL_DHASH_LOOKUP));
} }
@ -1208,7 +1223,7 @@ nsScriptSecurityManager::LookupPolicy(nsIPrincipal* aPrincipal,
ppolicy = ppolicy =
static_cast<PropertyPolicy*> static_cast<PropertyPolicy*>
(PL_DHashTableOperate(dpolicy->mWildcardPolicy->mPolicy, (PL_DHashTableOperate(dpolicy->mWildcardPolicy->mPolicy,
(void*)aProperty, propertyKey,
PL_DHASH_LOOKUP)); PL_DHASH_LOOKUP));
} }
@ -1228,7 +1243,7 @@ nsScriptSecurityManager::LookupPolicy(nsIPrincipal* aPrincipal,
ppolicy = ppolicy =
static_cast<PropertyPolicy*> static_cast<PropertyPolicy*>
(PL_DHashTableOperate(cpolicy->mPolicy, (PL_DHashTableOperate(cpolicy->mPolicy,
(void*)aProperty, propertyKey,
PL_DHASH_LOOKUP)); PL_DHASH_LOOKUP));
} }
@ -1238,7 +1253,7 @@ nsScriptSecurityManager::LookupPolicy(nsIPrincipal* aPrincipal,
ppolicy = ppolicy =
static_cast<PropertyPolicy*> static_cast<PropertyPolicy*>
(PL_DHashTableOperate(mDefaultPolicy->mWildcardPolicy->mPolicy, (PL_DHashTableOperate(mDefaultPolicy->mWildcardPolicy->mPolicy,
(void*)aProperty, propertyKey,
PL_DHASH_LOOKUP)); PL_DHASH_LOOKUP));
} }
} }
@ -2368,7 +2383,7 @@ nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj
JSObject* origObj = aObj; JSObject* origObj = aObj;
#endif #endif
const JSClass *jsClass = aObj->getClass(); js::Class *jsClass = aObj->getClass();
// A common case seen in this code is that we enter this function // A common case seen in this code is that we enter this function
// with aObj being a Function object, whose parent is a Call // with aObj being a Function object, whose parent is a Call
@ -3041,11 +3056,11 @@ nsScriptSecurityManager::CheckComponentPermissions(JSContext *cx,
// Look up the policy for this class. // Look up the policy for this class.
// while this isn't a property we'll treat it as such, using ACCESS_CALL_METHOD // while this isn't a property we'll treat it as such, using ACCESS_CALL_METHOD
JSAutoRequest ar(cx); JSAutoRequest ar(cx);
jsval cidVal = STRING_TO_JSVAL(::JS_InternString(cx, cid.get())); jsid cidId = INTERNED_STRING_TO_JSID(::JS_InternString(cx, cid.get()));
ClassInfoData nameData(nsnull, "ClassID"); ClassInfoData nameData(nsnull, "ClassID");
SecurityLevel securityLevel; SecurityLevel securityLevel;
rv = LookupPolicy(subjectPrincipal, nameData, cidVal, rv = LookupPolicy(subjectPrincipal, nameData, cidId,
nsIXPCSecurityManager::ACCESS_CALL_METHOD, nsIXPCSecurityManager::ACCESS_CALL_METHOD,
nsnull, &securityLevel); nsnull, &securityLevel);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
@ -3148,7 +3163,7 @@ nsScriptSecurityManager::CanAccess(PRUint32 aAction,
JSObject* aJSObject, JSObject* aJSObject,
nsISupports* aObj, nsISupports* aObj,
nsIClassInfo* aClassInfo, nsIClassInfo* aClassInfo,
jsval aPropertyName, jsid aPropertyName,
void** aPolicy) void** aPolicy)
{ {
return CheckPropertyAccessImpl(aAction, aCallContext, cx, return CheckPropertyAccessImpl(aAction, aCallContext, cx,
@ -3348,8 +3363,8 @@ nsresult nsScriptSecurityManager::Init()
if (!cx) return NS_ERROR_FAILURE; // this can happen of xpt loading fails if (!cx) return NS_ERROR_FAILURE; // this can happen of xpt loading fails
::JS_BeginRequest(cx); ::JS_BeginRequest(cx);
if (sEnabledID == JSVAL_VOID) if (sEnabledID == JSID_VOID)
sEnabledID = STRING_TO_JSVAL(::JS_InternString(cx, "enabled")); sEnabledID = INTERNED_STRING_TO_JSID(::JS_InternString(cx, "enabled"));
::JS_EndRequest(cx); ::JS_EndRequest(cx);
InitPrefs(); InitPrefs();
@ -3402,7 +3417,7 @@ nsresult nsScriptSecurityManager::Init()
static nsScriptSecurityManager *gScriptSecMan = nsnull; static nsScriptSecurityManager *gScriptSecMan = nsnull;
jsval nsScriptSecurityManager::sEnabledID = JSVAL_VOID; jsid nsScriptSecurityManager::sEnabledID = JSID_VOID;
nsScriptSecurityManager::~nsScriptSecurityManager(void) nsScriptSecurityManager::~nsScriptSecurityManager(void)
{ {
@ -3421,7 +3436,7 @@ nsScriptSecurityManager::Shutdown()
JS_SetRuntimeSecurityCallbacks(sRuntime, NULL); JS_SetRuntimeSecurityCallbacks(sRuntime, NULL);
sRuntime = nsnull; sRuntime = nsnull;
} }
sEnabledID = JSVAL_VOID; sEnabledID = JSID_VOID;
NS_IF_RELEASE(sIOService); NS_IF_RELEASE(sIOService);
NS_IF_RELEASE(sXPConnect); NS_IF_RELEASE(sXPConnect);
@ -3751,11 +3766,9 @@ nsScriptSecurityManager::InitDomainPolicy(JSContext* cx,
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
// Store this property in the class policy // Store this property in the class policy
const void* ppkey =
reinterpret_cast<const void*>(STRING_TO_JSVAL(propertyKey));
PropertyPolicy* ppolicy = PropertyPolicy* ppolicy =
static_cast<PropertyPolicy*> static_cast<PropertyPolicy*>
(PL_DHashTableOperate(cpolicy->mPolicy, ppkey, (PL_DHashTableOperate(cpolicy->mPolicy, propertyKey,
PL_DHASH_ADD)); PL_DHASH_ADD));
if (!ppolicy) if (!ppolicy)
break; break;
@ -4023,7 +4036,7 @@ PrintPropertyPolicy(PLDHashTable *table, PLDHashEntryHdr *entry,
JSContext* cx = (JSContext*)arg; JSContext* cx = (JSContext*)arg;
prop.AppendInt((PRUint32)pp->key); prop.AppendInt((PRUint32)pp->key);
prop += ' '; prop += ' ';
prop.AppendWithConversion((PRUnichar*)JSValIDToString(cx, pp->key)); prop.AppendWithConversion((PRUnichar*)JS_GetStringChars(pp->key));
prop += ": Get="; prop += ": Get=";
if (SECURITY_ACCESS_LEVEL_FLAG(pp->mGet)) if (SECURITY_ACCESS_LEVEL_FLAG(pp->mGet))
prop.AppendInt(pp->mGet.level); prop.AppendInt(pp->mGet.level);

Просмотреть файл

@ -1803,7 +1803,7 @@ public:
~nsAutoGCRoot() { ~nsAutoGCRoot() {
if (NS_SUCCEEDED(mResult)) { if (NS_SUCCEEDED(mResult)) {
RemoveJSGCRoot(mPtr, mRootType); RemoveJSGCRoot((jsval *)mPtr, mRootType);
} }
} }

Просмотреть файл

@ -5619,15 +5619,6 @@ CloneSimpleValues(JSContext* cx,
return SetPropertyOnValueOrObject(cx, val, rval, robj, rid); return SetPropertyOnValueOrObject(cx, val, rval, robj, rid);
} }
// Clone doubles.
if (JSVAL_IS_DOUBLE(val)) {
jsval newVal;
if (!JS_NewDoubleValue(cx, *JSVAL_TO_DOUBLE(val), &newVal)) {
return NS_ERROR_OUT_OF_MEMORY;
}
return SetPropertyOnValueOrObject(cx, newVal, rval, robj, rid);
}
// We'll use immutable strings to prevent copying if we can. // We'll use immutable strings to prevent copying if we can.
if (JSVAL_IS_STRING(val)) { if (JSVAL_IS_STRING(val)) {
if (!JS_MakeStringImmutable(cx, JSVAL_TO_STRING(val))) { if (!JS_MakeStringImmutable(cx, JSVAL_TO_STRING(val))) {

Просмотреть файл

@ -422,11 +422,11 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
js::AutoValueRooter argv(ctx); js::AutoValueRooter argv(ctx);
argv.setObject(param); argv.set(OBJECT_TO_JSVAL(param));
JSObject* thisObject = JSVAL_TO_OBJECT(thisValue); JSObject* thisObject = JSVAL_TO_OBJECT(thisValue);
JS_CallFunctionValue(ctx, thisObject, JS_CallFunctionValue(ctx, thisObject,
funval, 1, argv.addr(), &rval); funval, 1, argv.jsval_addr(), &rval);
if (aJSONRetVal) { if (aJSONRetVal) {
nsString json; nsString json;
if (JS_TryJSON(ctx, &rval) && if (JS_TryJSON(ctx, &rval) &&

Просмотреть файл

@ -44,14 +44,14 @@ typedef nsresult (NS_STDCALL nsIDOMCanvasRenderingContext2D::*CanvasStyleSetterT
typedef nsresult (NS_STDCALL nsIDOMCanvasRenderingContext2D::*CanvasStyleGetterType)(nsAString &, nsISupports **, PRInt32 *); typedef nsresult (NS_STDCALL nsIDOMCanvasRenderingContext2D::*CanvasStyleGetterType)(nsAString &, nsISupports **, PRInt32 *);
static JSBool static JSBool
Canvas2D_SetStyleHelper(JSContext *cx, JSObject *obj, jsval id, jsval *vp, Canvas2D_SetStyleHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
CanvasStyleSetterType setfunc) CanvasStyleSetterType setfunc)
{ {
XPC_QS_ASSERT_CONTEXT_OK(cx); XPC_QS_ASSERT_CONTEXT_OK(cx);
nsIDOMCanvasRenderingContext2D *self; nsIDOMCanvasRenderingContext2D *self;
xpc_qsSelfRef selfref; xpc_qsSelfRef selfref;
js::AutoValueRooter tvr(cx); js::AutoValueRooter tvr(cx);
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull)) if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
return JS_FALSE; return JS_FALSE;
nsresult rv; nsresult rv;
@ -69,7 +69,7 @@ Canvas2D_SetStyleHelper(JSContext *cx, JSObject *obj, jsval id, jsval *vp,
xpc_qsSelfRef arg0ref; xpc_qsSelfRef arg0ref;
rv = xpc_qsUnwrapArg<nsISupports>(cx, *vp, &arg0, &arg0ref.ptr, vp); rv = xpc_qsUnwrapArg<nsISupports>(cx, *vp, &arg0, &arg0ref.ptr, vp);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
xpc_qsThrowBadSetterValue(cx, rv, JSVAL_TO_OBJECT(*tvr.addr()), id); xpc_qsThrowBadSetterValue(cx, rv, JSVAL_TO_OBJECT(*tvr.jsval_addr()), id);
return JS_FALSE; return JS_FALSE;
} }
@ -80,13 +80,13 @@ Canvas2D_SetStyleHelper(JSContext *cx, JSObject *obj, jsval id, jsval *vp,
} }
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return xpc_qsThrowGetterSetterFailed(cx, rv, JSVAL_TO_OBJECT(*tvr.addr()), id); return xpc_qsThrowGetterSetterFailed(cx, rv, JSVAL_TO_OBJECT(*tvr.jsval_addr()), id);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
Canvas2D_GetStyleHelper(JSContext *cx, JSObject *obj, jsval id, jsval *vp, Canvas2D_GetStyleHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
CanvasStyleGetterType getfunc) CanvasStyleGetterType getfunc)
{ {
XPC_QS_ASSERT_CONTEXT_OK(cx); XPC_QS_ASSERT_CONTEXT_OK(cx);
@ -122,25 +122,25 @@ Canvas2D_GetStyleHelper(JSContext *cx, JSObject *obj, jsval id, jsval *vp,
} }
static JSBool static JSBool
nsIDOMCanvasRenderingContext2D_SetStrokeStyle(JSContext *cx, JSObject *obj, jsval id, jsval *vp) nsIDOMCanvasRenderingContext2D_SetStrokeStyle(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{ {
return Canvas2D_SetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::SetStrokeStyle_multi); return Canvas2D_SetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::SetStrokeStyle_multi);
} }
static JSBool static JSBool
nsIDOMCanvasRenderingContext2D_GetStrokeStyle(JSContext *cx, JSObject *obj, jsval id, jsval *vp) nsIDOMCanvasRenderingContext2D_GetStrokeStyle(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{ {
return Canvas2D_GetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::GetStrokeStyle_multi); return Canvas2D_GetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::GetStrokeStyle_multi);
} }
static JSBool static JSBool
nsIDOMCanvasRenderingContext2D_SetFillStyle(JSContext *cx, JSObject *obj, jsval id, jsval *vp) nsIDOMCanvasRenderingContext2D_SetFillStyle(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{ {
return Canvas2D_SetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::SetFillStyle_multi); return Canvas2D_SetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::SetFillStyle_multi);
} }
static JSBool static JSBool
nsIDOMCanvasRenderingContext2D_GetFillStyle(JSContext *cx, JSObject *obj, jsval id, jsval *vp) nsIDOMCanvasRenderingContext2D_GetFillStyle(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{ {
return Canvas2D_GetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::GetFillStyle_multi); return Canvas2D_GetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::GetFillStyle_multi);
} }
@ -179,14 +179,14 @@ nsIDOMCanvasRenderingContext2D_CreateImageData(JSContext *cx, uintN argc, jsval
// create the fast typed array; it's initialized to 0 by default // create the fast typed array; it's initialized to 0 by default
JSObject *darray = js_CreateTypedArray(cx, js::TypedArray::TYPE_UINT8_CLAMPED, len); JSObject *darray = js_CreateTypedArray(cx, js::TypedArray::TYPE_UINT8_CLAMPED, len);
js::AutoValueRooter rd(cx, darray); js::AutoObjectRooter rd(cx, darray);
if (!darray) if (!darray)
return JS_FALSE; return JS_FALSE;
// Do JS_NewObject after CreateTypedArray, so that gc will get // Do JS_NewObject after CreateTypedArray, so that gc will get
// triggered here if necessary // triggered here if necessary
JSObject *result = JS_NewObject(cx, NULL, NULL, NULL); JSObject *result = JS_NewObject(cx, NULL, NULL, NULL);
js::AutoValueRooter rr(cx, result); js::AutoObjectRooter rr(cx, result);
if (!result) if (!result)
return JS_FALSE; return JS_FALSE;
@ -213,7 +213,7 @@ nsIDOMCanvasRenderingContext2D_GetImageData(JSContext *cx, uintN argc, jsval *vp
nsIDOMCanvasRenderingContext2D *self; nsIDOMCanvasRenderingContext2D *self;
xpc_qsSelfRef selfref; xpc_qsSelfRef selfref;
js::AutoValueRooter tvr(cx); js::AutoValueRooter tvr(cx);
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull)) if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
return JS_FALSE; return JS_FALSE;
if (argc < 4) if (argc < 4)
@ -246,7 +246,7 @@ nsIDOMCanvasRenderingContext2D_GetImageData(JSContext *cx, uintN argc, jsval *vp
// create the fast typed array // create the fast typed array
JSObject *darray = js_CreateTypedArray(cx, js::TypedArray::TYPE_UINT8_CLAMPED, len); JSObject *darray = js_CreateTypedArray(cx, js::TypedArray::TYPE_UINT8_CLAMPED, len);
js::AutoValueRooter rd(cx, darray); js::AutoObjectRooter rd(cx, darray);
if (!darray) if (!darray)
return JS_FALSE; return JS_FALSE;
@ -260,7 +260,7 @@ nsIDOMCanvasRenderingContext2D_GetImageData(JSContext *cx, uintN argc, jsval *vp
// Do JS_NewObject after CreateTypedArray, so that gc will get // Do JS_NewObject after CreateTypedArray, so that gc will get
// triggered here if necessary // triggered here if necessary
JSObject *result = JS_NewObject(cx, NULL, NULL, NULL); JSObject *result = JS_NewObject(cx, NULL, NULL, NULL);
js::AutoValueRooter rr(cx, result); js::AutoObjectRooter rr(cx, result);
if (!result) if (!result)
return JS_FALSE; return JS_FALSE;
@ -287,7 +287,7 @@ nsIDOMCanvasRenderingContext2D_PutImageData(JSContext *cx, uintN argc, jsval *vp
nsIDOMCanvasRenderingContext2D *self; nsIDOMCanvasRenderingContext2D *self;
xpc_qsSelfRef selfref; xpc_qsSelfRef selfref;
js::AutoValueRooter tvr(cx); js::AutoValueRooter tvr(cx);
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull)) if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
return JS_FALSE; return JS_FALSE;
if (argc < 3) if (argc < 3)
@ -310,12 +310,12 @@ nsIDOMCanvasRenderingContext2D_PutImageData(JSContext *cx, uintN argc, jsval *vp
// grab width, height, and the dense array from the dataObject // grab width, height, and the dense array from the dataObject
js::AutoValueRooter tv(cx); js::AutoValueRooter tv(cx);
if (!JS_GetProperty(cx, dataObject, "width", tv.addr()) || if (!JS_GetProperty(cx, dataObject, "width", tv.jsval_addr()) ||
!JS_ValueToECMAInt32(cx, tv.value(), &wi)) !JS_ValueToECMAInt32(cx, tv.jsval_value(), &wi))
return JS_FALSE; return JS_FALSE;
if (!JS_GetProperty(cx, dataObject, "height", tv.addr()) || if (!JS_GetProperty(cx, dataObject, "height", tv.jsval_addr()) ||
!JS_ValueToECMAInt32(cx, tv.value(), &hi)) !JS_ValueToECMAInt32(cx, tv.jsval_value(), &hi))
return JS_FALSE; return JS_FALSE;
if (wi <= 0 || hi <= 0) if (wi <= 0 || hi <= 0)
@ -324,10 +324,10 @@ nsIDOMCanvasRenderingContext2D_PutImageData(JSContext *cx, uintN argc, jsval *vp
uint32 w = (uint32) wi; uint32 w = (uint32) wi;
uint32 h = (uint32) hi; uint32 h = (uint32) hi;
if (!JS_GetProperty(cx, dataObject, "data", tv.addr()) || if (!JS_GetProperty(cx, dataObject, "data", tv.jsval_addr()) ||
JSVAL_IS_PRIMITIVE(tv.value())) JSVAL_IS_PRIMITIVE(tv.jsval_value()))
return JS_FALSE; return JS_FALSE;
darray = JSVAL_TO_OBJECT(tv.value()); darray = JSVAL_TO_OBJECT(tv.jsval_value());
js::AutoValueRooter tsrc_tvr(cx); js::AutoValueRooter tsrc_tvr(cx);
@ -342,7 +342,7 @@ nsIDOMCanvasRenderingContext2D_PutImageData(JSContext *cx, uintN argc, jsval *vp
if (!nobj) if (!nobj)
return JS_FALSE; return JS_FALSE;
*tsrc_tvr.addr() = OBJECT_TO_JSVAL(nobj); *tsrc_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
tsrc = js::TypedArray::fromJSObject(nobj); tsrc = js::TypedArray::fromJSObject(nobj);
} else { } else {
// yeah, no. // yeah, no.

Просмотреть файл

@ -92,7 +92,7 @@ nsICanvasRenderingContextWebGL_BufferData(JSContext *cx, uintN argc, jsval *vp)
nsICanvasRenderingContextWebGL *self; nsICanvasRenderingContextWebGL *self;
xpc_qsSelfRef selfref; xpc_qsSelfRef selfref;
js::AutoValueRooter tvr(cx); js::AutoValueRooter tvr(cx);
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull)) if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
return JS_FALSE; return JS_FALSE;
if (argc < 3) if (argc < 3)
@ -158,7 +158,7 @@ nsICanvasRenderingContextWebGL_BufferSubData(JSContext *cx, uintN argc, jsval *v
nsICanvasRenderingContextWebGL *self; nsICanvasRenderingContextWebGL *self;
xpc_qsSelfRef selfref; xpc_qsSelfRef selfref;
js::AutoValueRooter tvr(cx); js::AutoValueRooter tvr(cx);
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull)) if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
return JS_FALSE; return JS_FALSE;
if (argc < 3) if (argc < 3)
@ -226,7 +226,7 @@ nsICanvasRenderingContextWebGL_ReadPixels(JSContext *cx, uintN argc, jsval *vp)
nsICanvasRenderingContextWebGL *self; nsICanvasRenderingContextWebGL *self;
xpc_qsSelfRef selfref; xpc_qsSelfRef selfref;
js::AutoValueRooter tvr(cx); js::AutoValueRooter tvr(cx);
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull)) if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
return JS_FALSE; return JS_FALSE;
// XXX we currently allow passing only 6 args to support the API. Eventually drop that. // XXX we currently allow passing only 6 args to support the API. Eventually drop that.
@ -323,7 +323,7 @@ nsICanvasRenderingContextWebGL_TexImage2D(JSContext *cx, uintN argc, jsval *vp)
nsICanvasRenderingContextWebGL *self; nsICanvasRenderingContextWebGL *self;
xpc_qsSelfRef selfref; xpc_qsSelfRef selfref;
js::AutoValueRooter tvr(cx); js::AutoValueRooter tvr(cx);
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull)) if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
return JS_FALSE; return JS_FALSE;
// XXX we currently allow passing only 3 args to support the API. Eventually drop that. // XXX we currently allow passing only 3 args to support the API. Eventually drop that.
@ -447,7 +447,7 @@ nsICanvasRenderingContextWebGL_TexSubImage2D(JSContext *cx, uintN argc, jsval *v
nsICanvasRenderingContextWebGL *self; nsICanvasRenderingContextWebGL *self;
xpc_qsSelfRef selfref; xpc_qsSelfRef selfref;
js::AutoValueRooter tvr(cx); js::AutoValueRooter tvr(cx);
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull)) if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
return JS_FALSE; return JS_FALSE;
if (argc < 7 || argc == 8) if (argc < 7 || argc == 8)
@ -548,7 +548,7 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_iv(JSContext *cx, uintN argc, js
nsICanvasRenderingContextWebGL *self; nsICanvasRenderingContextWebGL *self;
xpc_qsSelfRef selfref; xpc_qsSelfRef selfref;
js::AutoValueRooter tvr(cx); js::AutoValueRooter tvr(cx);
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull)) if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
return JS_FALSE; return JS_FALSE;
if (argc < 2) if (argc < 2)
@ -584,7 +584,7 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_iv(JSContext *cx, uintN argc, js
return JS_FALSE; return JS_FALSE;
} }
*obj_tvr.addr() = OBJECT_TO_JSVAL(nobj); *obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
wa = js::TypedArray::fromJSObject(nobj); wa = js::TypedArray::fromJSObject(nobj);
} else { } else {
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 1); xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 1);
@ -622,7 +622,7 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_fv(JSContext *cx, uintN argc, js
nsICanvasRenderingContextWebGL *self; nsICanvasRenderingContextWebGL *self;
xpc_qsSelfRef selfref; xpc_qsSelfRef selfref;
js::AutoValueRooter tvr(cx); js::AutoValueRooter tvr(cx);
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull)) if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
return JS_FALSE; return JS_FALSE;
if (argc < 2) if (argc < 2)
@ -658,7 +658,7 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_fv(JSContext *cx, uintN argc, js
return JS_FALSE; return JS_FALSE;
} }
*obj_tvr.addr() = OBJECT_TO_JSVAL(nobj); *obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
wa = js::TypedArray::fromJSObject(nobj); wa = js::TypedArray::fromJSObject(nobj);
} else { } else {
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 1); xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 1);
@ -696,7 +696,7 @@ helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv(JSContext *cx, uintN ar
nsICanvasRenderingContextWebGL *self; nsICanvasRenderingContextWebGL *self;
xpc_qsSelfRef selfref; xpc_qsSelfRef selfref;
js::AutoValueRooter tvr(cx); js::AutoValueRooter tvr(cx);
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull)) if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
return JS_FALSE; return JS_FALSE;
if (argc < 3) if (argc < 3)
@ -736,7 +736,7 @@ helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv(JSContext *cx, uintN ar
return JS_FALSE; return JS_FALSE;
} }
*obj_tvr.addr() = OBJECT_TO_JSVAL(nobj); *obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
wa = js::TypedArray::fromJSObject(nobj); wa = js::TypedArray::fromJSObject(nobj);
} else { } else {
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 2); xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 2);
@ -771,7 +771,7 @@ helper_nsICanvasRenderingContextWebGL_VertexAttrib_x_fv(JSContext *cx, uintN arg
nsICanvasRenderingContextWebGL *self; nsICanvasRenderingContextWebGL *self;
xpc_qsSelfRef selfref; xpc_qsSelfRef selfref;
js::AutoValueRooter tvr(cx); js::AutoValueRooter tvr(cx);
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull)) if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
return JS_FALSE; return JS_FALSE;
if (argc < 2) if (argc < 2)
@ -803,7 +803,7 @@ helper_nsICanvasRenderingContextWebGL_VertexAttrib_x_fv(JSContext *cx, uintN arg
return JS_FALSE; return JS_FALSE;
} }
*obj_tvr.addr() = OBJECT_TO_JSVAL(nobj); *obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
wa = js::TypedArray::fromJSObject(nobj); wa = js::TypedArray::fromJSObject(nobj);
} else { } else {
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 1); xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 1);
@ -919,7 +919,7 @@ nsICanvasRenderingContextWebGL_VertexAttrib4fv(JSContext *cx, uintN argc, jsval
#ifdef JS_TRACER #ifdef JS_TRACER
static inline jsval FASTCALL static inline void FASTCALL
helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(JSContext *cx, JSObject *obj, JSObject *locationobj, helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(JSContext *cx, JSObject *obj, JSObject *locationobj,
JSObject *arg, int nElements) JSObject *arg, int nElements)
{ {
@ -930,7 +930,7 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(JSContext *cx, JSObject *o
xpc_qsArgValArray<3> vp(cx); xpc_qsArgValArray<3> vp(cx);
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, &vp.array[0], nsnull)) { if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, &vp.array[0], nsnull)) {
js_SetTraceableNativeFailed(cx); js_SetTraceableNativeFailed(cx);
return JSVAL_VOID; return;
} }
js::AutoValueRooter obj_tvr(cx); js::AutoValueRooter obj_tvr(cx);
@ -941,7 +941,7 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(JSContext *cx, JSObject *o
= xpc_qsUnwrapThis(cx, locationobj, nsnull, &location, &location_selfref.ptr, &vp.array[1], nsnull); = xpc_qsUnwrapThis(cx, locationobj, nsnull, &location, &location_selfref.ptr, &vp.array[1], nsnull);
if (NS_FAILED(rv_convert_arg0)) { if (NS_FAILED(rv_convert_arg0)) {
js_SetTraceableNativeFailed(cx); js_SetTraceableNativeFailed(cx);
return JSVAL_VOID; return;
} }
js::TypedArray *wa = 0; js::TypedArray *wa = 0;
@ -953,15 +953,15 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(JSContext *cx, JSObject *o
if (!nobj) { if (!nobj) {
// XXX this will likely return a strange error message if it goes wrong // XXX this will likely return a strange error message if it goes wrong
js_SetTraceableNativeFailed(cx); js_SetTraceableNativeFailed(cx);
return JSVAL_VOID; return;
} }
*obj_tvr.addr() = OBJECT_TO_JSVAL(nobj); *obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
wa = js::TypedArray::fromJSObject(nobj); wa = js::TypedArray::fromJSObject(nobj);
} else { } else {
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformNiv"); xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformNiv");
js_SetTraceableNativeFailed(cx); js_SetTraceableNativeFailed(cx);
return JSVAL_VOID; return;
} }
nsresult rv; nsresult rv;
@ -980,11 +980,9 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(JSContext *cx, JSObject *o
xpc_qsThrowMethodFailedWithDetails(cx, rv, "nsICanvasRenderingContextWebGL", "uniformNiv"); xpc_qsThrowMethodFailedWithDetails(cx, rv, "nsICanvasRenderingContextWebGL", "uniformNiv");
js_SetTraceableNativeFailed(cx); js_SetTraceableNativeFailed(cx);
} }
return JSVAL_VOID;
} }
static inline jsval FASTCALL static inline void FASTCALL
helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(JSContext *cx, JSObject *obj, JSObject *locationobj, helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(JSContext *cx, JSObject *obj, JSObject *locationobj,
JSObject *arg, int nElements) JSObject *arg, int nElements)
{ {
@ -995,7 +993,7 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(JSContext *cx, JSObject *o
xpc_qsArgValArray<3> vp(cx); xpc_qsArgValArray<3> vp(cx);
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, &vp.array[0], nsnull)) { if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, &vp.array[0], nsnull)) {
js_SetTraceableNativeFailed(cx); js_SetTraceableNativeFailed(cx);
return JSVAL_VOID; return;
} }
js::AutoValueRooter obj_tvr(cx); js::AutoValueRooter obj_tvr(cx);
@ -1006,7 +1004,7 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(JSContext *cx, JSObject *o
= xpc_qsUnwrapThis(cx, locationobj, nsnull, &location, &location_selfref.ptr, &vp.array[1], nsnull); = xpc_qsUnwrapThis(cx, locationobj, nsnull, &location, &location_selfref.ptr, &vp.array[1], nsnull);
if (NS_FAILED(rv_convert_arg0)) { if (NS_FAILED(rv_convert_arg0)) {
js_SetTraceableNativeFailed(cx); js_SetTraceableNativeFailed(cx);
return JSVAL_VOID; return;
} }
js::TypedArray *wa = 0; js::TypedArray *wa = 0;
@ -1018,15 +1016,15 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(JSContext *cx, JSObject *o
if (!nobj) { if (!nobj) {
// XXX this will likely return a strange error message if it goes wrong // XXX this will likely return a strange error message if it goes wrong
js_SetTraceableNativeFailed(cx); js_SetTraceableNativeFailed(cx);
return JSVAL_VOID; return;
} }
*obj_tvr.addr() = OBJECT_TO_JSVAL(nobj); *obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
wa = js::TypedArray::fromJSObject(nobj); wa = js::TypedArray::fromJSObject(nobj);
} else { } else {
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformNfv"); xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformNfv");
js_SetTraceableNativeFailed(cx); js_SetTraceableNativeFailed(cx);
return JSVAL_VOID; return;
} }
nsresult rv; nsresult rv;
@ -1046,10 +1044,10 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(JSContext *cx, JSObject *o
js_SetTraceableNativeFailed(cx); js_SetTraceableNativeFailed(cx);
} }
return JSVAL_VOID; return;
} }
static inline jsval FASTCALL static inline void FASTCALL
helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(JSContext *cx, JSObject *obj, JSObject *locationobj, helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(JSContext *cx, JSObject *obj, JSObject *locationobj,
JSBool transpose, JSObject *arg, int nElements) JSBool transpose, JSObject *arg, int nElements)
{ {
@ -1060,7 +1058,7 @@ helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(JSContext *cx, JSObj
xpc_qsArgValArray<4> vp(cx); xpc_qsArgValArray<4> vp(cx);
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, &vp.array[0], nsnull)) { if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, &vp.array[0], nsnull)) {
js_SetTraceableNativeFailed(cx); js_SetTraceableNativeFailed(cx);
return JSVAL_VOID; return;
} }
js::AutoValueRooter obj_tvr(cx); js::AutoValueRooter obj_tvr(cx);
@ -1071,7 +1069,7 @@ helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(JSContext *cx, JSObj
= xpc_qsUnwrapThis(cx, locationobj, nsnull, &location, &location_selfref.ptr, &vp.array[1], nsnull); = xpc_qsUnwrapThis(cx, locationobj, nsnull, &location, &location_selfref.ptr, &vp.array[1], nsnull);
if (NS_FAILED(rv_convert_arg0)) { if (NS_FAILED(rv_convert_arg0)) {
js_SetTraceableNativeFailed(cx); js_SetTraceableNativeFailed(cx);
return JSVAL_VOID; return;
} }
js::TypedArray *wa = 0; js::TypedArray *wa = 0;
@ -1083,15 +1081,15 @@ helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(JSContext *cx, JSObj
if (!nobj) { if (!nobj) {
// XXX this will likely return a strange error message if it goes wrong // XXX this will likely return a strange error message if it goes wrong
js_SetTraceableNativeFailed(cx); js_SetTraceableNativeFailed(cx);
return JSVAL_VOID; return;
} }
*obj_tvr.addr() = OBJECT_TO_JSVAL(nobj); *obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
wa = js::TypedArray::fromJSObject(nobj); wa = js::TypedArray::fromJSObject(nobj);
} else { } else {
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformMatrixNfv"); xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformMatrixNfv");
js_SetTraceableNativeFailed(cx); js_SetTraceableNativeFailed(cx);
return JSVAL_VOID; return;
} }
nsresult rv; nsresult rv;
@ -1107,107 +1105,138 @@ helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(JSContext *cx, JSObj
xpc_qsThrowMethodFailedWithDetails(cx, rv, "nsICanvasRenderingContextWebGL", "uniformMatrixNfv"); xpc_qsThrowMethodFailedWithDetails(cx, rv, "nsICanvasRenderingContextWebGL", "uniformMatrixNfv");
js_SetTraceableNativeFailed(cx); js_SetTraceableNativeFailed(cx);
} }
return JSVAL_VOID;
} }
static jsval FASTCALL // FIXME This should return void, not uint32
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
static uint32 FASTCALL
nsICanvasRenderingContextWebGL_Uniform1iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg) nsICanvasRenderingContextWebGL_Uniform1iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
{ {
return helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 1); helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 1);
return 0;
} }
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform1iv, JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform1iv,
(4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform1iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY))) (4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform1iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
static jsval FASTCALL // FIXME This should return void, not uint32
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
static uint32 FASTCALL
nsICanvasRenderingContextWebGL_Uniform2iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg) nsICanvasRenderingContextWebGL_Uniform2iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
{ {
return helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 2); helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 2);
return 0;
} }
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform2iv, JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform2iv,
(4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform2iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY))) (4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform2iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
static jsval FASTCALL // FIXME This should return void, not uint32
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
static uint32 FASTCALL
nsICanvasRenderingContextWebGL_Uniform3iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg) nsICanvasRenderingContextWebGL_Uniform3iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
{ {
return helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 3); helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 3);
return 0;
} }
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform3iv, JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform3iv,
(4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform3iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY))) (4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform3iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
static jsval FASTCALL // FIXME This should return void, not uint32
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
static uint32 FASTCALL
nsICanvasRenderingContextWebGL_Uniform4iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg) nsICanvasRenderingContextWebGL_Uniform4iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
{ {
return helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 4); helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 4);
return 0;
} }
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform4iv, JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform4iv,
(4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform4iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY))) (4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform4iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
static jsval FASTCALL // FIXME This should return void, not uint32
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
static uint32 FASTCALL
nsICanvasRenderingContextWebGL_Uniform1fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg) nsICanvasRenderingContextWebGL_Uniform1fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
{ {
return helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 1); helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 1);
return 0;
} }
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform1fv, JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform1fv,
(4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform1fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY))) (4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform1fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
static jsval FASTCALL // FIXME This should return void, not uint32
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
static uint32 FASTCALL
nsICanvasRenderingContextWebGL_Uniform2fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg) nsICanvasRenderingContextWebGL_Uniform2fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
{ {
return helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 2); helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 2);
return 0;
} }
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform2fv, JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform2fv,
(4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform2fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY))) (4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform2fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
static jsval FASTCALL // FIXME This should return void, not uint32
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
static uint32 FASTCALL
nsICanvasRenderingContextWebGL_Uniform3fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg) nsICanvasRenderingContextWebGL_Uniform3fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
{ {
return helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 3); helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 3);
return 0;
} }
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform3fv, JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform3fv,
(4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform3fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY))) (4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform3fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
static jsval FASTCALL // FIXME This should return void, not uint32
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
static uint32 FASTCALL
nsICanvasRenderingContextWebGL_Uniform4fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg) nsICanvasRenderingContextWebGL_Uniform4fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
{ {
return helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 4); helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 4);
return 0;
} }
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform4fv, JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform4fv,
(4, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_Uniform4fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY))) (4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform4fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACC_STORE_ANY)))
static jsval FASTCALL // FIXME This should return void, not uint32
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
static uint32 FASTCALL
nsICanvasRenderingContextWebGL_UniformMatrix2fv_tn(JSContext *cx, JSObject *obj, JSObject *loc, JSBool transpose, JSObject *arg) nsICanvasRenderingContextWebGL_UniformMatrix2fv_tn(JSContext *cx, JSObject *obj, JSObject *loc, JSBool transpose, JSObject *arg)
{ {
return helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(cx, obj, loc, transpose, arg, 2); helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(cx, obj, loc, transpose, arg, 2);
return 0;
} }
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_UniformMatrix2fv, JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_UniformMatrix2fv,
(5, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_UniformMatrix2fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACC_STORE_ANY))) (5, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_UniformMatrix2fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACC_STORE_ANY)))
static jsval FASTCALL // FIXME This should return void, not uint32
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
static uint32 FASTCALL
nsICanvasRenderingContextWebGL_UniformMatrix3fv_tn(JSContext *cx, JSObject *obj, JSObject *loc, JSBool transpose, JSObject *arg) nsICanvasRenderingContextWebGL_UniformMatrix3fv_tn(JSContext *cx, JSObject *obj, JSObject *loc, JSBool transpose, JSObject *arg)
{ {
return helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(cx, obj, loc, transpose, arg, 3); helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(cx, obj, loc, transpose, arg, 3);
return 0;
} }
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_UniformMatrix3fv, JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_UniformMatrix3fv,
(5, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_UniformMatrix3fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACC_STORE_ANY))) (5, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_UniformMatrix3fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACC_STORE_ANY)))
static jsval FASTCALL // FIXME This should return void, not uint32
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
static uint32 FASTCALL
nsICanvasRenderingContextWebGL_UniformMatrix4fv_tn(JSContext *cx, JSObject *obj, JSObject *loc, JSBool transpose, JSObject *arg) nsICanvasRenderingContextWebGL_UniformMatrix4fv_tn(JSContext *cx, JSObject *obj, JSObject *loc, JSBool transpose, JSObject *arg)
{ {
return helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(cx, obj, loc, transpose, arg, 4); helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(cx, obj, loc, transpose, arg, 4);
return 0;
} }
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_UniformMatrix4fv, JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_UniformMatrix4fv,
(5, (static, JSVAL_FAIL, nsICanvasRenderingContextWebGL_UniformMatrix4fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACC_STORE_ANY))) (5, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_UniformMatrix4fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACC_STORE_ANY)))
#endif /* JS_TRACER */ #endif /* JS_TRACER */

Просмотреть файл

@ -15,6 +15,5 @@ void
NativeJSContext::ReleaseGCRoot(JSObject **aPtr) NativeJSContext::ReleaseGCRoot(JSObject **aPtr)
{ {
NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!"); NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
::JS_RemoveObjectRoot(ctx, aPtr); ::JS_RemoveObjectRoot(ctx, aPtr);
} }

Просмотреть файл

@ -67,33 +67,22 @@ public:
void SetRetVal (PRInt32 val) { void SetRetVal (PRInt32 val) {
NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!"); NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
if (INT_FITS_IN_JSVAL(val))
SetRetValAsJSVal(INT_TO_JSVAL(val)); SetRetValAsJSVal(INT_TO_JSVAL(val));
else
SetRetVal((double) val);
} }
void SetRetVal (PRUint32 val) { void SetRetVal (PRUint32 val) {
NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!"); NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
if (INT_FITS_IN_JSVAL(val)) SetRetValAsJSVal(UINT_TO_JSVAL(val));
SetRetValAsJSVal(INT_TO_JSVAL((int) val));
else
SetRetVal((double) val);
} }
void SetRetVal (double val) { void SetRetVal (double val) {
NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!"); NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
jsval *vp; SetRetValAsJSVal(DOUBLE_TO_JSVAL(val));
ncc->GetRetValPtr(&vp);
JS_NewDoubleValue(ctx, val, vp);
} }
void SetBoolRetVal (PRBool val) { void SetBoolRetVal (PRBool val) {
NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!"); NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
if (val) SetRetValAsJSVal(BOOLEAN_TO_JSVAL(val));
SetRetValAsJSVal(JSVAL_TRUE);
else
SetRetValAsJSVal(JSVAL_FALSE);
} }
void SetRetVal (PRInt32 *vp, PRUint32 len) { void SetRetVal (PRInt32 *vp, PRUint32 len) {
@ -103,13 +92,8 @@ public:
if (!JS_EnterLocalRootScope(ctx)) if (!JS_EnterLocalRootScope(ctx))
return; // XXX ??? return; // XXX ???
for (PRUint32 i = 0; i < len; i++) { for (PRUint32 i = 0; i < len; i++)
if (INT_FITS_IN_JSVAL(vp[i])) {
jsvector[i] = INT_TO_JSVAL(vp[i]); jsvector[i] = INT_TO_JSVAL(vp[i]);
} else {
JS_NewDoubleValue(ctx, vp[i], &jsvector[i]);
}
}
JSObject *jsarr = JS_NewArrayObject(ctx, len, jsvector.get()); JSObject *jsarr = JS_NewArrayObject(ctx, len, jsvector.get());
SetRetVal(jsarr); SetRetVal(jsarr);
@ -124,9 +108,8 @@ public:
if (!JS_EnterLocalRootScope(ctx)) if (!JS_EnterLocalRootScope(ctx))
return; // XXX ??? return; // XXX ???
for (PRUint32 i = 0; i < len; i++) { for (PRUint32 i = 0; i < len; i++)
JS_NewNumberValue(ctx, vp[i], &jsvector[i]); jsvector[i] = UINT_TO_JSVAL(vp[i]);
}
JSObject *jsarr = JS_NewArrayObject(ctx, len, jsvector.get()); JSObject *jsarr = JS_NewArrayObject(ctx, len, jsvector.get());
SetRetVal(jsarr); SetRetVal(jsarr);
@ -142,7 +125,7 @@ public:
return; // XXX ??? return; // XXX ???
for (PRUint32 i = 0; i < len; i++) for (PRUint32 i = 0; i < len; i++)
JS_NewDoubleValue(ctx, (jsdouble) dp[i], &jsvector[i]); jsvector[i] = DOUBLE_TO_JSVAL(dp[i]);
JSObject *jsarr = JS_NewArrayObject(ctx, len, jsvector.get()); JSObject *jsarr = JS_NewArrayObject(ctx, len, jsvector.get());
SetRetVal(jsarr); SetRetVal(jsarr);
@ -158,7 +141,8 @@ public:
return; // XXX ??? return; // XXX ???
for (PRUint32 i = 0; i < len; i++) for (PRUint32 i = 0; i < len; i++)
JS_NewDoubleValue(ctx, (jsdouble) fp[i], &jsvector[i]); jsvector[i] = DOUBLE_TO_JSVAL(fp[i]);
JSObject *jsarr = JS_NewArrayObject(ctx, len, jsvector.get()); JSObject *jsarr = JS_NewArrayObject(ctx, len, jsvector.get());
SetRetVal(jsarr); SetRetVal(jsarr);
@ -342,11 +326,7 @@ public:
} }
PRBool DefineProperty(const char *name, double val) { PRBool DefineProperty(const char *name, double val) {
jsval dv; jsval dv = DOUBLE_TO_JSVAL(val);
if (!JS_NewDoubleValue(mCtx->ctx, val, &dv))
return PR_FALSE;
if (!JS_DefineProperty(mCtx->ctx, mObject, name, dv, NULL, NULL, JSPROP_ENUMERATE)) if (!JS_DefineProperty(mCtx->ctx, mObject, name, dv, NULL, NULL, JSPROP_ENUMERATE))
return PR_FALSE; return PR_FALSE;
return PR_TRUE; return PR_TRUE;
@ -360,7 +340,7 @@ public:
// Blah. We can't name this DefineProperty also because PRBool is the same as PRInt32 // Blah. We can't name this DefineProperty also because PRBool is the same as PRInt32
PRBool DefineBoolProperty(const char *name, PRBool val) { PRBool DefineBoolProperty(const char *name, PRBool val) {
if (!JS_DefineProperty(mCtx->ctx, mObject, name, val ? JS_TRUE : JS_FALSE, NULL, NULL, JSPROP_ENUMERATE)) if (!JS_DefineProperty(mCtx->ctx, mObject, name, val ? JSVAL_TRUE : JSVAL_FALSE, NULL, NULL, JSPROP_ENUMERATE))
return PR_FALSE; return PR_FALSE;
return PR_TRUE; return PR_TRUE;
} }

Просмотреть файл

@ -311,7 +311,7 @@ void
nsEventListenerManager::Shutdown() nsEventListenerManager::Shutdown()
{ {
NS_IF_RELEASE(gSystemEventGroup); NS_IF_RELEASE(gSystemEventGroup);
sAddListenerID = JSVAL_VOID; sAddListenerID = JSID_VOID;
nsDOMEvent::Shutdown(); nsDOMEvent::Shutdown();
} }
@ -841,8 +841,8 @@ nsEventListenerManager::RemoveScriptEventListener(nsIAtom* aName)
return NS_OK; return NS_OK;
} }
jsval jsid
nsEventListenerManager::sAddListenerID = JSVAL_VOID; nsEventListenerManager::sAddListenerID = JSID_VOID;
NS_IMETHODIMP NS_IMETHODIMP
nsEventListenerManager::RegisterScriptEventListener(nsIScriptContext *aContext, nsEventListenerManager::RegisterScriptEventListener(nsIScriptContext *aContext,
@ -866,10 +866,10 @@ nsEventListenerManager::RegisterScriptEventListener(nsIScriptContext *aContext,
return rv; return rv;
if (cx) { if (cx) {
if (sAddListenerID == JSVAL_VOID) { if (sAddListenerID == JSID_VOID) {
JSAutoRequest ar(cx); JSAutoRequest ar(cx);
sAddListenerID = sAddListenerID =
STRING_TO_JSVAL(::JS_InternString(cx, "addEventListener")); INTERNED_STRING_TO_JSID(::JS_InternString(cx, "addEventListener"));
} }
if (aContext->GetScriptTypeID() == nsIProgrammingLanguage::JAVASCRIPT) { if (aContext->GetScriptTypeID() == nsIProgrammingLanguage::JAVASCRIPT) {

Просмотреть файл

@ -231,7 +231,7 @@ protected:
nsCOMPtr<nsIAtom> mNoListenerForEventAtom; nsCOMPtr<nsIAtom> mNoListenerForEventAtom;
static PRUint32 mInstanceCount; static PRUint32 mInstanceCount;
static jsval sAddListenerID; static jsid sAddListenerID;
friend class nsEventTargetChainItem; friend class nsEventTargetChainItem;
static PRUint32 sCreatedCount; static PRUint32 sCreatedCount;

Просмотреть файл

@ -3635,10 +3635,10 @@ ConvertToMidasInternalCommand(const nsAString & inCommandID,
dummyBool, dummyBool, PR_TRUE); dummyBool, dummyBool, PR_TRUE);
} }
jsval jsid
nsHTMLDocument::sCutCopyInternal_id = JSVAL_VOID; nsHTMLDocument::sCutCopyInternal_id = JSID_VOID;
jsval jsid
nsHTMLDocument::sPasteInternal_id = JSVAL_VOID; nsHTMLDocument::sPasteInternal_id = JSID_VOID;
/* Helper function to check security of clipboard commands. If aPaste is */ /* Helper function to check security of clipboard commands. If aPaste is */
/* true, we check paste, else we check cutcopy */ /* true, we check paste, else we check cutcopy */
@ -3664,17 +3664,17 @@ nsHTMLDocument::DoClipboardSecurityCheck(PRBool aPaste)
nsIScriptSecurityManager *secMan = nsContentUtils::GetSecurityManager(); nsIScriptSecurityManager *secMan = nsContentUtils::GetSecurityManager();
if (aPaste) { if (aPaste) {
if (nsHTMLDocument::sPasteInternal_id == JSVAL_VOID) { if (nsHTMLDocument::sPasteInternal_id == JSID_VOID) {
nsHTMLDocument::sPasteInternal_id = nsHTMLDocument::sPasteInternal_id =
STRING_TO_JSVAL(::JS_InternString(cx, "paste")); INTERNED_STRING_TO_JSID(::JS_InternString(cx, "paste"));
} }
rv = secMan->CheckPropertyAccess(cx, nsnull, classNameStr.get(), rv = secMan->CheckPropertyAccess(cx, nsnull, classNameStr.get(),
nsHTMLDocument::sPasteInternal_id, nsHTMLDocument::sPasteInternal_id,
nsIXPCSecurityManager::ACCESS_GET_PROPERTY); nsIXPCSecurityManager::ACCESS_GET_PROPERTY);
} else { } else {
if (nsHTMLDocument::sCutCopyInternal_id == JSVAL_VOID) { if (nsHTMLDocument::sCutCopyInternal_id == JSID_VOID) {
nsHTMLDocument::sCutCopyInternal_id = nsHTMLDocument::sCutCopyInternal_id =
STRING_TO_JSVAL(::JS_InternString(cx, "cutcopy")); INTERNED_STRING_TO_JSID(::JS_InternString(cx, "cutcopy"));
} }
rv = secMan->CheckPropertyAccess(cx, nsnull, classNameStr.get(), rv = secMan->CheckPropertyAccess(cx, nsnull, classNameStr.get(),
nsHTMLDocument::sCutCopyInternal_id, nsHTMLDocument::sCutCopyInternal_id,

Просмотреть файл

@ -371,8 +371,8 @@ protected:
EditingState mEditingState; EditingState mEditingState;
nsresult DoClipboardSecurityCheck(PRBool aPaste); nsresult DoClipboardSecurityCheck(PRBool aPaste);
static jsval sCutCopyInternal_id; static jsid sCutCopyInternal_id;
static jsval sPasteInternal_id; static jsid sPasteInternal_id;
// When false, the .cookies property is completely disabled // When false, the .cookies property is completely disabled
PRBool mDisableCookieAccess; PRBool mDisableCookieAccess;

Просмотреть файл

@ -123,7 +123,7 @@ XBLFinalize(JSContext *cx, JSObject *obj)
} }
static JSBool static JSBool
XBLResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, XBLResolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
JSObject **objp) JSObject **objp)
{ {
// Note: if we get here, that means that the implementation for some binding // Note: if we get here, that means that the implementation for some binding
@ -136,7 +136,7 @@ XBLResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
JSObject* origObj = *objp; JSObject* origObj = *objp;
*objp = NULL; *objp = NULL;
if (!JSVAL_IS_STRING(id)) { if (!JSID_IS_STRING(id)) {
return JS_TRUE; return JS_TRUE;
} }

Просмотреть файл

@ -81,7 +81,7 @@ public:
// nsIScriptObjectPrincipal methods // nsIScriptObjectPrincipal methods
virtual nsIPrincipal* GetPrincipal(); virtual nsIPrincipal* GetPrincipal();
static JSBool doCheckAccess(JSContext *cx, JSObject *obj, jsval id, static JSBool doCheckAccess(JSContext *cx, JSObject *obj, jsid id,
PRUint32 accessType); PRUint32 accessType);
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXBLDocGlobalObject, NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXBLDocGlobalObject,
@ -104,7 +104,7 @@ protected:
}; };
JSBool JSBool
nsXBLDocGlobalObject::doCheckAccess(JSContext *cx, JSObject *obj, jsval id, PRUint32 accessType) nsXBLDocGlobalObject::doCheckAccess(JSContext *cx, JSObject *obj, jsid id, PRUint32 accessType)
{ {
nsIScriptSecurityManager *ssm = nsContentUtils::GetSecurityManager(); nsIScriptSecurityManager *ssm = nsContentUtils::GetSecurityManager();
if (!ssm) { if (!ssm) {
@ -129,7 +129,7 @@ nsXBLDocGlobalObject::doCheckAccess(JSContext *cx, JSObject *obj, jsval id, PRUi
static JSBool static JSBool
nsXBLDocGlobalObject_getProperty(JSContext *cx, JSObject *obj, nsXBLDocGlobalObject_getProperty(JSContext *cx, JSObject *obj,
jsval id, jsval *vp) jsid id, jsval *vp)
{ {
return nsXBLDocGlobalObject:: return nsXBLDocGlobalObject::
doCheckAccess(cx, obj, id, nsIXPCSecurityManager::ACCESS_GET_PROPERTY); doCheckAccess(cx, obj, id, nsIXPCSecurityManager::ACCESS_GET_PROPERTY);
@ -137,14 +137,14 @@ nsXBLDocGlobalObject_getProperty(JSContext *cx, JSObject *obj,
static JSBool static JSBool
nsXBLDocGlobalObject_setProperty(JSContext *cx, JSObject *obj, nsXBLDocGlobalObject_setProperty(JSContext *cx, JSObject *obj,
jsval id, jsval *vp) jsid id, jsval *vp)
{ {
return nsXBLDocGlobalObject:: return nsXBLDocGlobalObject::
doCheckAccess(cx, obj, id, nsIXPCSecurityManager::ACCESS_SET_PROPERTY); doCheckAccess(cx, obj, id, nsIXPCSecurityManager::ACCESS_SET_PROPERTY);
} }
static JSBool static JSBool
nsXBLDocGlobalObject_checkAccess(JSContext *cx, JSObject *obj, jsval id, nsXBLDocGlobalObject_checkAccess(JSContext *cx, JSObject *obj, jsid id,
JSAccessMode mode, jsval *vp) JSAccessMode mode, jsval *vp)
{ {
PRUint32 translated; PRUint32 translated;
@ -173,7 +173,7 @@ nsXBLDocGlobalObject_finalize(JSContext *cx, JSObject *obj)
} }
static JSBool static JSBool
nsXBLDocGlobalObject_resolve(JSContext *cx, JSObject *obj, jsval id) nsXBLDocGlobalObject_resolve(JSContext *cx, JSObject *obj, jsid id)
{ {
JSBool did_resolve = JS_FALSE; JSBool did_resolve = JS_FALSE;
return JS_ResolveStandardClass(cx, obj, id, &did_resolve); return JS_ResolveStandardClass(cx, obj, id, &did_resolve);

Просмотреть файл

@ -132,7 +132,7 @@ nsXULPDGlobalObject_finalize(JSContext *cx, JSObject *obj)
JSBool JSBool
nsXULPDGlobalObject_resolve(JSContext *cx, JSObject *obj, jsval id) nsXULPDGlobalObject_resolve(JSContext *cx, JSObject *obj, jsid id)
{ {
JSBool did_resolve = JS_FALSE; JSBool did_resolve = JS_FALSE;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -217,10 +217,10 @@ protected:
// Checks if id is a number and returns the number, if aIsNumber is // Checks if id is a number and returns the number, if aIsNumber is
// non-null it's set to true if the id is a number and false if it's // non-null it's set to true if the id is a number and false if it's
// not a number. If id is not a number this method returns -1 // not a number. If id is not a number this method returns -1
static PRInt32 GetArrayIndexFromId(JSContext *cx, jsval id, static PRInt32 GetArrayIndexFromId(JSContext *cx, jsid id,
PRBool *aIsNumber = nsnull); PRBool *aIsNumber = nsnull);
static inline PRBool IsReadonlyReplaceable(jsval id) static inline PRBool IsReadonlyReplaceable(jsid id)
{ {
return (id == sTop_id || return (id == sTop_id ||
id == sParent_id || id == sParent_id ||
@ -241,7 +241,7 @@ protected:
id == sSelf_id); id == sSelf_id);
} }
static inline PRBool IsWritableReplaceable(jsval id) static inline PRBool IsWritableReplaceable(jsid id)
{ {
return (id == sInnerHeight_id || return (id == sInnerHeight_id ||
id == sInnerWidth_id || id == sInnerWidth_id ||
@ -264,91 +264,91 @@ protected:
static PRBool sDisableDocumentAllSupport; static PRBool sDisableDocumentAllSupport;
static PRBool sDisableGlobalScopePollutionSupport; static PRBool sDisableGlobalScopePollutionSupport;
static jsval sTop_id; static jsid sTop_id;
static jsval sParent_id; static jsid sParent_id;
static jsval sScrollbars_id; static jsid sScrollbars_id;
static jsval sLocation_id; static jsid sLocation_id;
static jsval sConstructor_id; static jsid sConstructor_id;
static jsval s_content_id; static jsid s_content_id;
static jsval sContent_id; static jsid sContent_id;
static jsval sMenubar_id; static jsid sMenubar_id;
static jsval sToolbar_id; static jsid sToolbar_id;
static jsval sLocationbar_id; static jsid sLocationbar_id;
static jsval sPersonalbar_id; static jsid sPersonalbar_id;
static jsval sStatusbar_id; static jsid sStatusbar_id;
static jsval sDialogArguments_id; static jsid sDialogArguments_id;
static jsval sControllers_id; static jsid sControllers_id;
static jsval sLength_id; static jsid sLength_id;
static jsval sInnerHeight_id; static jsid sInnerHeight_id;
static jsval sInnerWidth_id; static jsid sInnerWidth_id;
static jsval sOuterHeight_id; static jsid sOuterHeight_id;
static jsval sOuterWidth_id; static jsid sOuterWidth_id;
static jsval sScreenX_id; static jsid sScreenX_id;
static jsval sScreenY_id; static jsid sScreenY_id;
static jsval sStatus_id; static jsid sStatus_id;
static jsval sName_id; static jsid sName_id;
static jsval sOnmousedown_id; static jsid sOnmousedown_id;
static jsval sOnmouseup_id; static jsid sOnmouseup_id;
static jsval sOnclick_id; static jsid sOnclick_id;
static jsval sOndblclick_id; static jsid sOndblclick_id;
static jsval sOncontextmenu_id; static jsid sOncontextmenu_id;
static jsval sOnmouseover_id; static jsid sOnmouseover_id;
static jsval sOnmouseout_id; static jsid sOnmouseout_id;
static jsval sOnkeydown_id; static jsid sOnkeydown_id;
static jsval sOnkeyup_id; static jsid sOnkeyup_id;
static jsval sOnkeypress_id; static jsid sOnkeypress_id;
static jsval sOnmousemove_id; static jsid sOnmousemove_id;
static jsval sOnfocus_id; static jsid sOnfocus_id;
static jsval sOnblur_id; static jsid sOnblur_id;
static jsval sOnsubmit_id; static jsid sOnsubmit_id;
static jsval sOnreset_id; static jsid sOnreset_id;
static jsval sOnchange_id; static jsid sOnchange_id;
static jsval sOnselect_id; static jsid sOnselect_id;
static jsval sOnload_id; static jsid sOnload_id;
static jsval sOnpopstate_id; static jsid sOnpopstate_id;
static jsval sOnbeforeunload_id; static jsid sOnbeforeunload_id;
static jsval sOnunload_id; static jsid sOnunload_id;
static jsval sOnhashchange_id; static jsid sOnhashchange_id;
static jsval sOnreadystatechange_id; static jsid sOnreadystatechange_id;
static jsval sOnpageshow_id; static jsid sOnpageshow_id;
static jsval sOnpagehide_id; static jsid sOnpagehide_id;
static jsval sOnabort_id; static jsid sOnabort_id;
static jsval sOnerror_id; static jsid sOnerror_id;
static jsval sOnpaint_id; static jsid sOnpaint_id;
static jsval sOnresize_id; static jsid sOnresize_id;
static jsval sOnscroll_id; static jsid sOnscroll_id;
static jsval sOndrag_id; static jsid sOndrag_id;
static jsval sOndragend_id; static jsid sOndragend_id;
static jsval sOndragenter_id; static jsid sOndragenter_id;
static jsval sOndragleave_id; static jsid sOndragleave_id;
static jsval sOndragover_id; static jsid sOndragover_id;
static jsval sOndragstart_id; static jsid sOndragstart_id;
static jsval sOndrop_id; static jsid sOndrop_id;
static jsval sScrollX_id; static jsid sScrollX_id;
static jsval sScrollY_id; static jsid sScrollY_id;
static jsval sScrollMaxX_id; static jsid sScrollMaxX_id;
static jsval sScrollMaxY_id; static jsid sScrollMaxY_id;
static jsval sOpen_id; static jsid sOpen_id;
static jsval sItem_id; static jsid sItem_id;
static jsval sNamedItem_id; static jsid sNamedItem_id;
static jsval sEnumerate_id; static jsid sEnumerate_id;
static jsval sNavigator_id; static jsid sNavigator_id;
static jsval sDocument_id; static jsid sDocument_id;
static jsval sWindow_id; static jsid sWindow_id;
static jsval sFrames_id; static jsid sFrames_id;
static jsval sSelf_id; static jsid sSelf_id;
static jsval sOpener_id; static jsid sOpener_id;
static jsval sAll_id; static jsid sAll_id;
static jsval sTags_id; static jsid sTags_id;
static jsval sAddEventListener_id; static jsid sAddEventListener_id;
static jsval sBaseURIObject_id; static jsid sBaseURIObject_id;
static jsval sNodePrincipal_id; static jsid sNodePrincipal_id;
static jsval sDocumentURIObject_id; static jsid sDocumentURIObject_id;
static jsval sOncopy_id; static jsid sOncopy_id;
static jsval sOncut_id; static jsid sOncut_id;
static jsval sOnpaste_id; static jsid sOnpaste_id;
static jsval sJava_id; static jsid sJava_id;
static jsval sPackages_id; static jsid sPackages_id;
static JSPropertyOp sXPCNativeWrapperGetPropertyOp; static JSPropertyOp sXPCNativeWrapperGetPropertyOp;
static JSPropertyOp sXrayWrapperPropertyHolderGetPropertyOp; static JSPropertyOp sXrayWrapperPropertyHolderGetPropertyOp;
@ -408,13 +408,13 @@ protected:
{ {
} }
static PRBool ReallyIsEventName(jsval id, jschar aFirstChar); static PRBool ReallyIsEventName(jsid id, jschar aFirstChar);
static inline PRBool IsEventName(jsval id) static inline PRBool IsEventName(jsid id)
{ {
NS_ASSERTION(JSVAL_IS_STRING(id), "Don't pass non-string jsval's here!"); NS_ASSERTION(JSID_IS_STRING(id), "Don't pass non-string jsid's here!");
jschar *str = ::JS_GetStringChars(JSVAL_TO_STRING(id)); jschar *str = ::JS_GetStringChars(JSID_TO_STRING(id));
if (str[0] == 'o' && str[1] == 'n') { if (str[0] == 'o' && str[1] == 'n') {
return ReallyIsEventName(id, str[2]); return ReallyIsEventName(id, str[2]);
@ -424,19 +424,19 @@ protected:
} }
nsresult RegisterCompileHandler(nsIXPConnectWrappedNative *wrapper, nsresult RegisterCompileHandler(nsIXPConnectWrappedNative *wrapper,
JSContext *cx, JSObject *obj, jsval id, JSContext *cx, JSObject *obj, jsid id,
PRBool compile, PRBool remove, PRBool compile, PRBool remove,
PRBool *did_define); PRBool *did_define);
public: public:
NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, PRUint32 flags, JSObject *obj, jsid id, PRUint32 flags,
JSObject **objp, PRBool *_retval); JSObject **objp, PRBool *_retval);
NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, JSObject *obj, jsid id, jsval *vp,
PRBool *_retval); PRBool *_retval);
NS_IMETHOD AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
}; };
// Simpler than nsEventReceiverSH // Simpler than nsEventReceiverSH
@ -455,7 +455,7 @@ public:
NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx, NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
JSObject *globalObj, JSObject **parentObj); JSObject *globalObj, JSObject **parentObj);
NS_IMETHOD AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
virtual void PreserveWrapper(nsISupports *aNative); virtual void PreserveWrapper(nsISupports *aNative);
@ -510,15 +510,15 @@ public:
} }
#endif #endif
NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
NS_IMETHOD AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
NS_IMETHOD DelProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD DelProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, PRUint32 flags, JSObject *obj, jsid id, PRUint32 flags,
JSObject **objp, PRBool *_retval); JSObject **objp, PRBool *_retval);
NS_IMETHOD NewEnumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD NewEnumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, PRUint32 enum_op, jsval *statep, JSObject *obj, PRUint32 enum_op, jsval *statep,
@ -526,18 +526,18 @@ public:
NS_IMETHOD Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj); JSObject *obj);
NS_IMETHOD Equality(nsIXPConnectWrappedNative *wrapper, JSContext * cx, NS_IMETHOD Equality(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, jsval val, PRBool *bp); JSObject * obj, const jsval &val, PRBool *bp);
NS_IMETHOD OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx, NS_IMETHOD OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, JSObject * *_retval); JSObject * obj, JSObject * *_retval);
NS_IMETHOD InnerObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx, NS_IMETHOD InnerObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, JSObject * *_retval); JSObject * obj, JSObject * *_retval);
static JSBool GlobalScopePolluterNewResolve(JSContext *cx, JSObject *obj, static JSBool GlobalScopePolluterNewResolve(JSContext *cx, JSObject *obj,
jsval id, uintN flags, jsid id, uintN flags,
JSObject **objp); JSObject **objp);
static JSBool GlobalScopePolluterGetProperty(JSContext *cx, JSObject *obj, static JSBool GlobalScopePolluterGetProperty(JSContext *cx, JSObject *obj,
jsval id, jsval *vp); jsid id, jsval *vp);
static JSBool SecurityCheckOnSetProp(JSContext *cx, JSObject *obj, jsval id, static JSBool SecurityCheckOnSetProp(JSContext *cx, JSObject *obj, jsid id,
jsval *vp); jsval *vp);
static void InvalidateGlobalScopePolluter(JSContext *cx, JSObject *obj); static void InvalidateGlobalScopePolluter(JSContext *cx, JSObject *obj);
static nsresult InstallGlobalScopePolluter(JSContext *cx, JSObject *obj, static nsresult InstallGlobalScopePolluter(JSContext *cx, JSObject *obj,
@ -565,7 +565,7 @@ protected:
public: public:
NS_IMETHOD CheckAccess(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD CheckAccess(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, PRUint32 mode, JSObject *obj, jsid id, PRUint32 mode,
jsval *vp, PRBool *_retval); jsval *vp, PRBool *_retval);
NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx, NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
@ -627,21 +627,21 @@ protected:
// work so it's safe to just return whatever it returns. |obj| is the object // work so it's safe to just return whatever it returns. |obj| is the object
// we're defining on, |id| is the name of the prop. This must be a string // we're defining on, |id| is the name of the prop. This must be a string
// jsval. |objp| is the out param if we define successfully. // jsval. |objp| is the out param if we define successfully.
nsresult DefineVoidProp(JSContext* cx, JSObject* obj, jsval id, nsresult DefineVoidProp(JSContext* cx, JSObject* obj, jsid id,
JSObject** objp); JSObject** objp);
public: public:
NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx, NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
JSObject *globalObj, JSObject **parentObj); JSObject *globalObj, JSObject **parentObj);
NS_IMETHOD AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, PRUint32 flags, JSObject *obj, jsid id, PRUint32 flags,
JSObject **objp, PRBool *_retval); JSObject **objp, PRBool *_retval);
NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
NS_IMETHOD GetFlags(PRUint32 *aFlags); NS_IMETHOD GetFlags(PRUint32 *aFlags);
virtual void PreserveWrapper(nsISupports *aNative); virtual void PreserveWrapper(nsISupports *aNative);
@ -696,7 +696,7 @@ protected:
public: public:
NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, PRUint32 flags, JSObject *obj, jsid id, PRUint32 flags,
JSObject **objp, PRBool *_retval); JSObject **objp, PRBool *_retval);
NS_IMETHOD Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, PRBool *_retval); JSObject *obj, PRBool *_retval);
@ -731,7 +731,7 @@ protected:
public: public:
NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
private: private:
// Not implemented, nothing should create an instance of this class. // Not implemented, nothing should create an instance of this class.
@ -783,7 +783,7 @@ protected:
public: public:
NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
private: private:
// Not implemented, nothing should create an instance of this class. // Not implemented, nothing should create an instance of this class.
@ -895,12 +895,12 @@ public:
public: public:
NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, PRUint32 flags, JSObject *obj, jsid id, PRUint32 flags,
JSObject **objp, PRBool *_retval); JSObject **objp, PRBool *_retval);
NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
NS_IMETHOD GetFlags(PRUint32* aFlags); NS_IMETHOD GetFlags(PRUint32* aFlags);
NS_IMETHOD PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj); JSObject *obj);
@ -926,7 +926,7 @@ protected:
} }
static nsresult ResolveImpl(JSContext *cx, static nsresult ResolveImpl(JSContext *cx,
nsIXPConnectWrappedNative *wrapper, jsval id, nsIXPConnectWrappedNative *wrapper, jsid id,
nsISupports **result); nsISupports **result);
static JSBool DocumentOpen(JSContext *cx, JSObject *obj, uintN argc, static JSBool DocumentOpen(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval); jsval *argv, jsval *rval);
@ -935,27 +935,27 @@ protected:
nsIDOMNodeList **nodeList); nsIDOMNodeList **nodeList);
public: public:
static JSBool DocumentAllGetProperty(JSContext *cx, JSObject *obj, jsval id, static JSBool DocumentAllGetProperty(JSContext *cx, JSObject *obj, jsid id,
jsval *vp); jsval *vp);
static JSBool DocumentAllNewResolve(JSContext *cx, JSObject *obj, jsval id, static JSBool DocumentAllNewResolve(JSContext *cx, JSObject *obj, jsid id,
uintN flags, JSObject **objp); uintN flags, JSObject **objp);
static void ReleaseDocument(JSContext *cx, JSObject *obj); static void ReleaseDocument(JSContext *cx, JSObject *obj);
static JSBool CallToGetPropMapper(JSContext *cx, JSObject *obj, uintN argc, static JSBool CallToGetPropMapper(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval); jsval *argv, jsval *rval);
static JSBool DocumentAllHelperGetProperty(JSContext *cx, JSObject *obj, static JSBool DocumentAllHelperGetProperty(JSContext *cx, JSObject *obj,
jsval id, jsval *vp); jsid id, jsval *vp);
static JSBool DocumentAllHelperNewResolve(JSContext *cx, JSObject *obj, static JSBool DocumentAllHelperNewResolve(JSContext *cx, JSObject *obj,
jsval id, uintN flags, jsid id, uintN flags,
JSObject **objp); JSObject **objp);
static JSBool DocumentAllTagsNewResolve(JSContext *cx, JSObject *obj, static JSBool DocumentAllTagsNewResolve(JSContext *cx, JSObject *obj,
jsval id, uintN flags, jsid id, uintN flags,
JSObject **objp); JSObject **objp);
NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, PRUint32 flags, JSObject *obj, jsid id, PRUint32 flags,
JSObject **objp, PRBool *_retval); JSObject **objp, PRBool *_retval);
NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
static nsIClassInfo *doCreate(nsDOMClassInfoData* aData) static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
{ {
@ -979,15 +979,15 @@ protected:
public: public:
NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, PRUint32 flags, JSObject *obj, jsid id, PRUint32 flags,
JSObject **objp, PRBool *_retval); JSObject **objp, PRBool *_retval);
NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, JSObject *obj, jsid id, jsval *vp,
PRBool *_retval); PRBool *_retval);
NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
static nsIClassInfo *doCreate(nsDOMClassInfoData* aData) static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
{ {
@ -1014,10 +1014,10 @@ protected:
public: public:
NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, PRUint32 flags, JSObject *obj, jsid id, PRUint32 flags,
JSObject **objp, PRBool *_retval); JSObject **objp, PRBool *_retval);
NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, JSObject *obj, jsid id, jsval *vp,
PRBool *_retval); PRBool *_retval);
NS_IMETHOD NewEnumerate(nsIXPConnectWrappedNative *wrapper, NS_IMETHOD NewEnumerate(nsIXPConnectWrappedNative *wrapper,
@ -1047,10 +1047,10 @@ protected:
public: public:
NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, JSObject *obj, jsid id, jsval *vp,
PRBool *_retval); PRBool *_retval);
NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
static nsresult SetOption(JSContext *cx, jsval *vp, PRUint32 aIndex, static nsresult SetOption(JSContext *cx, jsval *vp, PRUint32 aIndex,
nsIDOMNSHTMLOptionCollection *aOptCollection); nsIDOMNSHTMLOptionCollection *aOptCollection);
@ -1087,16 +1087,16 @@ protected:
public: public:
NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, PRUint32 flags, JSObject *obj, jsid id, PRUint32 flags,
JSObject **objp, PRBool *_retval); JSObject **objp, PRBool *_retval);
NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx, NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
JSObject *globalObj, JSObject **parentObj); JSObject *globalObj, JSObject **parentObj);
NS_IMETHOD PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj); JSObject *obj);
NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
NS_IMETHOD Call(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD Call(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, PRUint32 argc, jsval *argv, jsval *vp, JSObject *obj, PRUint32 argc, jsval *argv, jsval *vp,
PRBool *_retval); PRBool *_retval);
@ -1128,7 +1128,7 @@ protected:
public: public:
NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
static nsIClassInfo *doCreate(nsDOMClassInfoData* aData) static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
{ {
@ -1242,7 +1242,7 @@ protected:
public: public:
NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
}; };
@ -1264,7 +1264,7 @@ protected:
public: public:
NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
static nsIClassInfo *doCreate(nsDOMClassInfoData* aData) static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
{ {
@ -1537,12 +1537,12 @@ protected:
} }
NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, PRUint32 flags, JSObject *obj, jsid id, PRUint32 flags,
JSObject **objp, PRBool *_retval); JSObject **objp, PRBool *_retval);
NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
NS_IMETHOD DelProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD DelProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
NS_IMETHOD NewEnumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD NewEnumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, PRUint32 enum_op, jsval *statep, JSObject *obj, PRUint32 enum_op, jsval *statep,
jsid *idp, PRBool *_retval); jsid *idp, PRBool *_retval);
@ -1577,14 +1577,14 @@ protected:
} }
NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, PRUint32 flags, JSObject *obj, jsid id, PRUint32 flags,
JSObject **objp, PRBool *_retval); JSObject **objp, PRBool *_retval);
NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
NS_IMETHOD DelProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD DelProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval); JSObject *obj, jsid id, jsval *vp, PRBool *_retval);
NS_IMETHOD NewEnumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD NewEnumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, PRUint32 enum_op, jsval *statep, JSObject *obj, PRUint32 enum_op, jsval *statep,
jsid *idp, PRBool *_retval); jsid *idp, PRBool *_retval);
@ -1671,7 +1671,7 @@ public:
jsval *vp, PRBool *_retval); jsval *vp, PRBool *_retval);
NS_IMETHOD HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_IMETHOD HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval val, PRBool *bp, JSObject *obj, const jsval &val, PRBool *bp,
PRBool *_retval); PRBool *_retval);
static nsIClassInfo *doCreate(nsDOMClassInfoData* aData) static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)

Просмотреть файл

@ -1222,7 +1222,7 @@ nsJSContext::DOMOperationCallback(JSContext *cx)
cx->debugHooks-> cx->debugHooks->
debuggerHandlerData)) { debuggerHandlerData)) {
case JSTRAP_RETURN: case JSTRAP_RETURN:
fp->rval = rval; fp->rval = js::Valueify(rval);
return JS_TRUE; return JS_TRUE;
case JSTRAP_ERROR: case JSTRAP_ERROR:
cx->throwing = JS_FALSE; cx->throwing = JS_FALSE;
@ -3053,10 +3053,10 @@ static JSPropertySpec OptionsProperties[] = {
}; };
static JSBool static JSBool
GetOptionsProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) GetOptionsProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{ {
if (JSVAL_IS_INT(id)) { if (JSID_IS_INT(id)) {
uint32 optbit = (uint32) JSVAL_TO_INT(id); uint32 optbit = (uint32) JSID_TO_INT(id);
if (((optbit & (optbit - 1)) == 0 && optbit <= JSOPTION_WERROR) || if (((optbit & (optbit - 1)) == 0 && optbit <= JSOPTION_WERROR) ||
optbit == JSOPTION_RELIMIT) optbit == JSOPTION_RELIMIT)
*vp = (JS_GetOptions(cx) & optbit) ? JSVAL_TRUE : JSVAL_FALSE; *vp = (JS_GetOptions(cx) & optbit) ? JSVAL_TRUE : JSVAL_FALSE;
@ -3065,10 +3065,10 @@ GetOptionsProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
} }
static JSBool static JSBool
SetOptionsProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) SetOptionsProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{ {
if (JSVAL_IS_INT(id)) { if (JSID_IS_INT(id)) {
uint32 optbit = (uint32) JSVAL_TO_INT(id); uint32 optbit = (uint32) JSID_TO_INT(id);
// Don't let options other than strict, werror, or relimit be set -- it // Don't let options other than strict, werror, or relimit be set -- it
// would be bad if web page script could clear // would be bad if web page script could clear
@ -3946,7 +3946,7 @@ SetMemoryHighWaterMarkPrefChangedCallback(const char* aPrefName, void* aClosure)
// Let's limit the high water mark for the first one to 32MB, // Let's limit the high water mark for the first one to 32MB,
// and second one to 0xffffffff. // and second one to 0xffffffff.
JS_SetGCParameter(nsJSRuntime::sRuntime, JSGC_MAX_MALLOC_BYTES, JS_SetGCParameter(nsJSRuntime::sRuntime, JSGC_MAX_MALLOC_BYTES,
32L * 1024L * 1024L); 64L * 1024L * 1024L);
JS_SetGCParameter(nsJSRuntime::sRuntime, JSGC_MAX_BYTES, JS_SetGCParameter(nsJSRuntime::sRuntime, JSGC_MAX_BYTES,
0xffffffff); 0xffffffff);
} else { } else {

Просмотреть файл

@ -81,6 +81,12 @@ public:
{ {
} }
explicit nsDependentJSString(jsid id)
: nsDependentString((PRUnichar *)::JS_GetStringChars(JSID_TO_STRING(id)),
::JS_GetStringLength(JSID_TO_STRING(id)))
{
}
explicit nsDependentJSString(JSString *str) explicit nsDependentJSString(JSString *str)
: nsDependentString((PRUnichar *)::JS_GetStringChars(str), ::JS_GetStringLength(str)) : nsDependentString((PRUnichar *)::JS_GetStringChars(str), ::JS_GetStringLength(str))
{ {

Просмотреть файл

@ -365,7 +365,7 @@ IDBCursor::GetValue(JSContext* aCx,
} }
NS_IMETHODIMP NS_IMETHODIMP
IDBCursor::Continue(jsval aKey, IDBCursor::Continue(const jsval &aKey,
JSContext* aCx, JSContext* aCx,
PRUint8 aOptionalArgCount, PRUint8 aOptionalArgCount,
PRBool* _retval) PRBool* _retval)
@ -410,7 +410,7 @@ IDBCursor::Continue(jsval aKey,
} }
NS_IMETHODIMP NS_IMETHODIMP
IDBCursor::Update(jsval aValue, IDBCursor::Update(const jsval &aValue,
JSContext* aCx, JSContext* aCx,
nsIIDBRequest** _retval) nsIIDBRequest** _retval)
{ {
@ -436,7 +436,7 @@ IDBCursor::Update(jsval aValue,
js::AutoValueRooter clone(aCx); js::AutoValueRooter clone(aCx);
nsresult rv = nsContentUtils::CreateStructuredClone(aCx, aValue, nsresult rv = nsContentUtils::CreateStructuredClone(aCx, aValue,
clone.addr()); clone.jsval_addr());
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
@ -449,22 +449,22 @@ IDBCursor::Update(jsval aValue,
const size_t keyPathLen = keyPath.Length(); const size_t keyPathLen = keyPath.Length();
js::AutoValueRooter prop(aCx); js::AutoValueRooter prop(aCx);
JSBool ok = JS_GetUCProperty(aCx, JSVAL_TO_OBJECT(clone.value()), JSBool ok = JS_GetUCProperty(aCx, JSVAL_TO_OBJECT(clone.jsval_value()),
keyPathChars, keyPathLen, prop.addr()); keyPathChars, keyPathLen, prop.jsval_addr());
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
if (JSVAL_IS_VOID(prop.value())) { if (JSVAL_IS_VOID(prop.jsval_value())) {
rv = IDBObjectStore::GetJSValFromKey(key, aCx, prop.addr()); rv = IDBObjectStore::GetJSValFromKey(key, aCx, prop.jsval_addr());
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
ok = JS_DefineUCProperty(aCx, JSVAL_TO_OBJECT(clone.value()), ok = JS_DefineUCProperty(aCx, JSVAL_TO_OBJECT(clone.jsval_value()),
keyPathChars, keyPathLen, prop.value(), nsnull, keyPathChars, keyPathLen, prop.jsval_value(), nsnull,
nsnull, JSPROP_ENUMERATE); nsnull, JSPROP_ENUMERATE);
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
} }
else { else {
Key newKey; Key newKey;
rv = IDBObjectStore::GetKeyFromJSVal(prop.value(), newKey); rv = IDBObjectStore::GetKeyFromJSVal(prop.jsval_value(), newKey);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (newKey.IsUnset() || newKey.IsNull() || newKey != key) { if (newKey.IsUnset() || newKey.IsNull() || newKey != key) {
@ -475,13 +475,13 @@ IDBCursor::Update(jsval aValue,
nsTArray<IndexUpdateInfo> indexUpdateInfo; nsTArray<IndexUpdateInfo> indexUpdateInfo;
rv = IDBObjectStore::GetIndexUpdateInfo(mObjectStore->GetObjectStoreInfo(), rv = IDBObjectStore::GetIndexUpdateInfo(mObjectStore->GetObjectStoreInfo(),
aCx, clone.value(), indexUpdateInfo); aCx, clone.jsval_value(), indexUpdateInfo);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIJSON> json(new nsJSON()); nsCOMPtr<nsIJSON> json(new nsJSON());
nsString jsonValue; nsString jsonValue;
rv = json->EncodeFromJSVal(clone.addr(), aCx, jsonValue); rv = json->EncodeFromJSVal(clone.jsval_addr(), aCx, jsonValue);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<IDBRequest> request = GenerateWriteRequest(); nsRefPtr<IDBRequest> request = GenerateWriteRequest();

Просмотреть файл

@ -473,14 +473,14 @@ GetAllSuccessEvent::GetResult(JSContext* aCx,
nsString jsonValue = values[index]; nsString jsonValue = values[index];
values[index].Truncate(); values[index].Truncate();
nsresult rv = json->DecodeToJSVal(jsonValue, aCx, value.addr()); nsresult rv = json->DecodeToJSVal(jsonValue, aCx, value.jsval_addr());
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
mCachedValue = JSVAL_VOID; mCachedValue = JSVAL_VOID;
NS_ERROR("Failed to decode!"); NS_ERROR("Failed to decode!");
return rv; return rv;
} }
if (!JS_SetElement(aCx, array, index, value.addr())) { if (!JS_SetElement(aCx, array, index, value.jsval_addr())) {
mCachedValue = JSVAL_VOID; mCachedValue = JSVAL_VOID;
NS_ERROR("Failed to set array element!"); NS_ERROR("Failed to set array element!");
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@ -539,14 +539,14 @@ GetAllKeySuccessEvent::GetResult(JSContext* aCx,
const Key& key = keys[index]; const Key& key = keys[index];
NS_ASSERTION(!key.IsUnset() && !key.IsNull(), "Bad key!"); NS_ASSERTION(!key.IsUnset() && !key.IsNull(), "Bad key!");
nsresult rv = IDBObjectStore::GetJSValFromKey(key, aCx, value.addr()); nsresult rv = IDBObjectStore::GetJSValFromKey(key, aCx, value.jsval_addr());
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
mCachedValue = JSVAL_VOID; mCachedValue = JSVAL_VOID;
NS_WARNING("Failed to get jsval for key!"); NS_WARNING("Failed to get jsval for key!");
return rv; return rv;
} }
if (!JS_SetElement(aCx, array, index, value.addr())) { if (!JS_SetElement(aCx, array, index, value.jsval_addr())) {
mCachedValue = JSVAL_VOID; mCachedValue = JSVAL_VOID;
NS_WARNING("Failed to set array element!"); NS_WARNING("Failed to set array element!");
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;

Просмотреть файл

@ -373,7 +373,7 @@ IDBObjectStore::GetKeyFromJSVal(jsval aKeyVal,
aKey = JSVAL_TO_INT(aKeyVal); aKey = JSVAL_TO_INT(aKeyVal);
} }
else if (JSVAL_IS_DOUBLE(aKeyVal)) { else if (JSVAL_IS_DOUBLE(aKeyVal)) {
aKey = *JSVAL_TO_DOUBLE(aKeyVal); aKey = JSVAL_TO_DOUBLE(aKeyVal);
} }
else { else {
return NS_ERROR_INVALID_ARG; return NS_ERROR_INVALID_ARG;
@ -452,14 +452,14 @@ IDBObjectStore::GetJSONFromArg0(/* jsval arg0, */
JSAutoRequest ar(cx); JSAutoRequest ar(cx);
js::AutoValueRooter clone(cx); js::AutoValueRooter clone(cx);
rv = nsContentUtils::CreateStructuredClone(cx, argv[0], clone.addr()); rv = nsContentUtils::CreateStructuredClone(cx, argv[0], clone.jsval_addr());
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
nsCOMPtr<nsIJSON> json(new nsJSON()); nsCOMPtr<nsIJSON> json(new nsJSON());
rv = json->EncodeFromJSVal(clone.addr(), cx, aJSON); rv = json->EncodeFromJSVal(clone.jsval_addr(), cx, aJSON);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
return NS_OK; return NS_OK;
@ -488,16 +488,16 @@ IDBObjectStore::GetKeyPathValueFromJSON(const nsAString& aJSON,
js::AutoValueRooter clone(*aCx); js::AutoValueRooter clone(*aCx);
nsCOMPtr<nsIJSON> json(new nsJSON()); nsCOMPtr<nsIJSON> json(new nsJSON());
rv = json->DecodeToJSVal(aJSON, *aCx, clone.addr()); rv = json->DecodeToJSVal(aJSON, *aCx, clone.jsval_addr());
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (JSVAL_IS_PRIMITIVE(clone.value())) { if (JSVAL_IS_PRIMITIVE(clone.jsval_value())) {
// This isn't an object, so just leave the key unset. // This isn't an object, so just leave the key unset.
aValue = Key::UNSETKEY; aValue = Key::UNSETKEY;
return NS_OK; return NS_OK;
} }
JSObject* obj = JSVAL_TO_OBJECT(clone.value()); JSObject* obj = JSVAL_TO_OBJECT(clone.jsval_value());
const jschar* keyPathChars = const jschar* keyPathChars =
reinterpret_cast<const jschar*>(aKeyPath.BeginReading()); reinterpret_cast<const jschar*>(aKeyPath.BeginReading());
@ -505,10 +505,10 @@ IDBObjectStore::GetKeyPathValueFromJSON(const nsAString& aJSON,
js::AutoValueRooter value(*aCx); js::AutoValueRooter value(*aCx);
JSBool ok = JS_GetUCProperty(*aCx, obj, keyPathChars, keyPathLen, JSBool ok = JS_GetUCProperty(*aCx, obj, keyPathChars, keyPathLen,
value.addr()); value.jsval_addr());
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
rv = GetKeyFromJSVal(value.value(), aValue); rv = GetKeyFromJSVal(value.jsval_value(), aValue);
if (NS_FAILED(rv) || aValue.IsNull()) { if (NS_FAILED(rv) || aValue.IsNull()) {
// If the object doesn't have a value that we can use for our index then we // If the object doesn't have a value that we can use for our index then we
// leave it unset. // leave it unset.
@ -729,7 +729,7 @@ IDBObjectStore::GetAddInfo(JSContext* aCx,
js::AutoValueRooter clone(aCx); js::AutoValueRooter clone(aCx);
nsresult rv = nsContentUtils::CreateStructuredClone(aCx, aValue, nsresult rv = nsContentUtils::CreateStructuredClone(aCx, aValue,
clone.addr()); clone.jsval_addr());
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
@ -740,11 +740,11 @@ IDBObjectStore::GetAddInfo(JSContext* aCx,
} }
else { else {
// Inline keys live on the object. Make sure it is an object. // Inline keys live on the object. Make sure it is an object.
if (JSVAL_IS_PRIMITIVE(clone.value())) { if (JSVAL_IS_PRIMITIVE(clone.jsval_value())) {
return NS_ERROR_INVALID_ARG; return NS_ERROR_INVALID_ARG;
} }
rv = GetKeyFromObject(aCx, JSVAL_TO_OBJECT(clone.value()), mKeyPath, aKey); rv = GetKeyFromObject(aCx, JSVAL_TO_OBJECT(clone.jsval_value()), mKeyPath, aKey);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
// Except if null was passed, in which case we're supposed to generate the // Except if null was passed, in which case we're supposed to generate the
@ -762,11 +762,11 @@ IDBObjectStore::GetAddInfo(JSContext* aCx,
ObjectStoreInfo* objectStoreInfo = GetObjectStoreInfo(); ObjectStoreInfo* objectStoreInfo = GetObjectStoreInfo();
NS_ENSURE_TRUE(objectStoreInfo, NS_ERROR_FAILURE); NS_ENSURE_TRUE(objectStoreInfo, NS_ERROR_FAILURE);
rv = GetIndexUpdateInfo(objectStoreInfo, aCx, clone.value(), aUpdateInfoArray); rv = GetIndexUpdateInfo(objectStoreInfo, aCx, clone.jsval_value(), aUpdateInfoArray);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIJSON> json(new nsJSON()); nsCOMPtr<nsIJSON> json(new nsJSON());
rv = json->EncodeFromJSVal(clone.addr(), aCx, aJSON); rv = json->EncodeFromJSVal(clone.jsval_addr(), aCx, aJSON);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
return NS_OK; return NS_OK;
@ -904,8 +904,8 @@ IDBObjectStore::GetAll(nsIIDBKeyRange* aKeyRange,
} }
NS_IMETHODIMP NS_IMETHODIMP
IDBObjectStore::Add(jsval aValue, IDBObjectStore::Add(const jsval &aValue,
jsval aKey, const jsval &aKey,
JSContext* aCx, JSContext* aCx,
PRUint8 aOptionalArgCount, PRUint8 aOptionalArgCount,
nsIIDBRequest** _retval) nsIIDBRequest** _retval)
@ -920,15 +920,13 @@ IDBObjectStore::Add(jsval aValue,
return NS_ERROR_OBJECT_IS_IMMUTABLE; return NS_ERROR_OBJECT_IS_IMMUTABLE;
} }
if (aOptionalArgCount < 1) { jsval keyval = (aOptionalArgCount >= 1) ? aKey : JSVAL_VOID;
aKey = JSVAL_VOID;
}
nsString jsonValue; nsString jsonValue;
Key key; Key key;
nsTArray<IndexUpdateInfo> updateInfo; nsTArray<IndexUpdateInfo> updateInfo;
nsresult rv = GetAddInfo(aCx, aValue, aKey, jsonValue, key, updateInfo); nsresult rv = GetAddInfo(aCx, aValue, keyval, jsonValue, key, updateInfo);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
@ -951,8 +949,8 @@ IDBObjectStore::Add(jsval aValue,
} }
NS_IMETHODIMP NS_IMETHODIMP
IDBObjectStore::Modify(jsval aValue, IDBObjectStore::Modify(const jsval &aValue,
jsval aKey, const jsval &aKey,
JSContext* aCx, JSContext* aCx,
PRUint8 aOptionalArgCount, PRUint8 aOptionalArgCount,
nsIIDBRequest** _retval) nsIIDBRequest** _retval)
@ -967,15 +965,13 @@ IDBObjectStore::Modify(jsval aValue,
return NS_ERROR_OBJECT_IS_IMMUTABLE; return NS_ERROR_OBJECT_IS_IMMUTABLE;
} }
if (aOptionalArgCount < 1) { jsval keyval = (aOptionalArgCount >= 1) ? aKey : JSVAL_VOID;
aKey = JSVAL_VOID;
}
nsString jsonValue; nsString jsonValue;
Key key; Key key;
nsTArray<IndexUpdateInfo> updateInfo; nsTArray<IndexUpdateInfo> updateInfo;
nsresult rv = GetAddInfo(aCx, aValue, aKey, jsonValue, key, updateInfo); nsresult rv = GetAddInfo(aCx, aValue, keyval, jsonValue, key, updateInfo);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
@ -998,8 +994,8 @@ IDBObjectStore::Modify(jsval aValue,
} }
NS_IMETHODIMP NS_IMETHODIMP
IDBObjectStore::AddOrModify(jsval aValue, IDBObjectStore::AddOrModify(const jsval &aValue,
jsval aKey, const jsval &aKey,
JSContext* aCx, JSContext* aCx,
PRUint8 aOptionalArgCount, PRUint8 aOptionalArgCount,
nsIIDBRequest** _retval) nsIIDBRequest** _retval)
@ -1014,15 +1010,13 @@ IDBObjectStore::AddOrModify(jsval aValue,
return NS_ERROR_OBJECT_IS_IMMUTABLE; return NS_ERROR_OBJECT_IS_IMMUTABLE;
} }
if (aOptionalArgCount < 1) { jsval keyval = (aOptionalArgCount >= 1) ? aKey : JSVAL_VOID;
aKey = JSVAL_VOID;
}
nsString jsonValue; nsString jsonValue;
Key key; Key key;
nsTArray<IndexUpdateInfo> updateInfo; nsTArray<IndexUpdateInfo> updateInfo;
nsresult rv = GetAddInfo(aCx, aValue, aKey, jsonValue, key, updateInfo); nsresult rv = GetAddInfo(aCx, aValue, keyval, jsonValue, key, updateInfo);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
@ -1473,10 +1467,10 @@ AddHelper::ModifyValueForNewKey()
js::AutoValueRooter clone(cx); js::AutoValueRooter clone(cx);
nsCOMPtr<nsIJSON> json(new nsJSON()); nsCOMPtr<nsIJSON> json(new nsJSON());
rv = json->DecodeToJSVal(mValue, cx, clone.addr()); rv = json->DecodeToJSVal(mValue, cx, clone.jsval_addr());
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
JSObject* obj = JSVAL_TO_OBJECT(clone.value()); JSObject* obj = JSVAL_TO_OBJECT(clone.jsval_value());
JSBool ok; JSBool ok;
js::AutoValueRooter key(cx); js::AutoValueRooter key(cx);
@ -1484,18 +1478,18 @@ AddHelper::ModifyValueForNewKey()
const size_t keyPathLen = mKeyPath.Length(); const size_t keyPathLen = mKeyPath.Length();
#ifdef DEBUG #ifdef DEBUG
ok = JS_GetUCProperty(cx, obj, keyPathChars, keyPathLen, key.addr()); ok = JS_GetUCProperty(cx, obj, keyPathChars, keyPathLen, key.jsval_addr());
NS_ASSERTION(ok && JSVAL_IS_VOID(key.value()), "Already has a key prop!"); NS_ASSERTION(ok && JSVAL_IS_VOID(key.jsval_value()), "Already has a key prop!");
#endif #endif
ok = JS_NewNumberValue(cx, mKey.IntValue(), key.addr()); ok = JS_NewNumberValue(cx, mKey.IntValue(), key.jsval_addr());
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
ok = JS_DefineUCProperty(cx, obj, keyPathChars, keyPathLen, key.value(), ok = JS_DefineUCProperty(cx, obj, keyPathChars, keyPathLen, key.jsval_value(),
nsnull, nsnull, JSPROP_ENUMERATE); nsnull, nsnull, JSPROP_ENUMERATE);
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
rv = json->EncodeFromJSVal(clone.addr(), cx, mValue); rv = json->EncodeFromJSVal(clone.jsval_addr(), cx, mValue);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
return NS_OK; return NS_OK;

Просмотреть файл

@ -116,7 +116,7 @@ public:
#ifdef BUILD_CTYPES #ifdef BUILD_CTYPES
static JSBool static JSBool
CTypesLazyGetter(JSContext* aCx, JSObject* aObj, jsval aId, jsval* aVp); CTypesLazyGetter(JSContext* aCx, JSObject* aObj, jsid aId, jsval* aVp);
#endif #endif
private: private:
@ -434,14 +434,14 @@ nsDOMWorkerFunctions::MakeNewWorker(JSContext* aCx,
JSBool JSBool
nsDOMWorkerFunctions::CTypesLazyGetter(JSContext* aCx, nsDOMWorkerFunctions::CTypesLazyGetter(JSContext* aCx,
JSObject* aObj, JSObject* aObj,
jsval aId, jsid aId,
jsval* aVp) jsval* aVp)
{ {
#ifdef DEBUG #ifdef DEBUG
{ {
NS_ASSERTION(JS_GetGlobalForObject(aCx, aObj) == aObj, "Bad object!"); NS_ASSERTION(JS_GetGlobalForObject(aCx, aObj) == aObj, "Bad object!");
NS_ASSERTION(JSVAL_IS_STRING(aId), "Not a string!"); NS_ASSERTION(JSID_IS_STRING(aId), "Not a string!");
JSString* str = JSVAL_TO_STRING(aId); JSString* str = JSID_TO_STRING(aId);
NS_ASSERTION(nsDependentJSString(str).EqualsLiteral("ctypes"), "Bad id!"); NS_ASSERTION(nsDependentJSString(str).EqualsLiteral("ctypes"), "Bad id!");
} }
#endif #endif
@ -453,11 +453,9 @@ nsDOMWorkerFunctions::CTypesLazyGetter(JSContext* aCx,
return JS_FALSE; return JS_FALSE;
} }
js::AutoIdRooter rooter(aCx); return JS_DeletePropertyById(aCx, aObj, aId) &&
return JS_ValueToId(aCx, aId, rooter.addr()) &&
JS_DeletePropertyById(aCx, aObj, rooter.id()) &&
JS_InitCTypesClass(aCx, aObj) && JS_InitCTypesClass(aCx, aObj) &&
JS_GetPropertyById(aCx, aObj, rooter.id(), aVp); JS_GetPropertyById(aCx, aObj, aId, aVp);
} }
#endif #endif
@ -586,7 +584,7 @@ NS_IMETHODIMP
nsDOMWorkerScope::AddProperty(nsIXPConnectWrappedNative* aWrapper, nsDOMWorkerScope::AddProperty(nsIXPConnectWrappedNative* aWrapper,
JSContext* aCx, JSContext* aCx,
JSObject* aObj, JSObject* aObj,
jsval aId, jsid aId,
jsval* aVp, jsval* aVp,
PRBool* _retval) PRBool* _retval)
{ {
@ -598,14 +596,14 @@ nsDOMWorkerScope::AddProperty(nsIXPConnectWrappedNative* aWrapper,
// someone making an 'onmessage' or 'onerror' function so aId must be a // someone making an 'onmessage' or 'onerror' function so aId must be a
// string and aVp must be a function. // string and aVp must be a function.
JSObject* funObj; JSObject* funObj;
if (!(JSVAL_IS_STRING(aId) && if (!(JSID_IS_STRING(aId) &&
JSVAL_IS_OBJECT(*aVp) && JSVAL_IS_OBJECT(*aVp) &&
(funObj = JSVAL_TO_OBJECT(*aVp)) && (funObj = JSVAL_TO_OBJECT(*aVp)) &&
JS_ObjectIsFunction(aCx, funObj))) { JS_ObjectIsFunction(aCx, funObj))) {
return NS_OK; return NS_OK;
} }
const char* name = JS_GetStringBytes(JSVAL_TO_STRING(aId)); const char* name = JS_GetStringBytes(JSID_TO_STRING(aId));
// Figure out which listener we're setting. // Figure out which listener we're setting.
SetListenerFunc func; SetListenerFunc func;

Просмотреть файл

@ -108,7 +108,7 @@ nsDOMWorkerSecurityManager::CanAccess(PRUint32 aAction,
JSObject* aJSObject, JSObject* aJSObject,
nsISupports* aObj, nsISupports* aObj,
nsIClassInfo* aClassInfo, nsIClassInfo* aClassInfo,
jsval aName, jsid aName,
void** aPolicy) void** aPolicy)
{ {
return NS_OK; return NS_OK;
@ -123,7 +123,7 @@ nsDOMWorkerSecurityManager::WorkerPrincipal()
JSBool JSBool
nsDOMWorkerSecurityManager::JSCheckAccess(JSContext* aCx, nsDOMWorkerSecurityManager::JSCheckAccess(JSContext* aCx,
JSObject* aObj, JSObject* aObj,
jsval aId, jsid aId,
JSAccessMode aMode, JSAccessMode aMode,
jsval* aVp) jsval* aVp)
{ {

Просмотреть файл

@ -50,7 +50,7 @@ public:
static JSPrincipals* WorkerPrincipal(); static JSPrincipals* WorkerPrincipal();
static JSBool JSCheckAccess(JSContext* aCx, JSObject* aObj, jsval aId, static JSBool JSCheckAccess(JSContext* aCx, JSObject* aObj, jsid aId,
JSAccessMode aMode, jsval* aVp); JSAccessMode aMode, jsval* aVp);
static JSPrincipals* JSFindPrincipal(JSContext* aCx, JSObject* aObj); static JSPrincipals* JSFindPrincipal(JSContext* aCx, JSObject* aObj);

Просмотреть файл

@ -96,7 +96,7 @@ AutoConfigSecMan::CanAccess(PRUint32 aAction,
nsAXPCNativeCallContext *aCallContext, nsAXPCNativeCallContext *aCallContext,
JSContext *aJSContext, JSObject *aJSObject, JSContext *aJSContext, JSObject *aJSObject,
nsISupports *aObj, nsIClassInfo *aClassInfo, nsISupports *aObj, nsIClassInfo *aClassInfo,
jsval aName, void **aPolicy) jsid aName, void **aPolicy)
{ {
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -116,7 +116,7 @@ TestShellCommandParent::SetCallback(JSContext* aCx,
JSBool JSBool
TestShellCommandParent::RunCallback(const nsString& aResponse) TestShellCommandParent::RunCallback(const nsString& aResponse)
{ {
NS_ENSURE_TRUE(mCallback && mCx, JS_FALSE); NS_ENSURE_TRUE(mCallback != JSVAL_NULL && mCx, JS_FALSE);
JSAutoRequest ar(mCx); JSAutoRequest ar(mCx);

Просмотреть файл

@ -737,7 +737,7 @@ FullTrustSecMan::CanAccess(PRUint32 aAction,
JSObject * aJSObject, JSObject * aJSObject,
nsISupports *aObj, nsISupports *aObj,
nsIClassInfo *aClassInfo, nsIClassInfo *aClassInfo,
jsval aName, jsid aName,
void * *aPolicy) void * *aPolicy)
{ {
return NS_OK; return NS_OK;
@ -747,7 +747,7 @@ NS_IMETHODIMP
FullTrustSecMan::CheckPropertyAccess(JSContext * aJSContext, FullTrustSecMan::CheckPropertyAccess(JSContext * aJSContext,
JSObject * aJSObject, JSObject * aJSObject,
const char *aClassName, const char *aClassName,
jsval aProperty, jsid aProperty,
PRUint32 aAction) PRUint32 aAction)
{ {
return NS_OK; return NS_OK;

Просмотреть файл

@ -195,7 +195,7 @@ ObjectWrapperChild::jsval_to_JSVariant(JSContext* cx, jsval from, JSVariant* to)
if (JSVAL_IS_INT(from)) if (JSVAL_IS_INT(from))
*to = JSVAL_TO_INT(from); *to = JSVAL_TO_INT(from);
else if (JSVAL_IS_DOUBLE(from)) else if (JSVAL_IS_DOUBLE(from))
*to = *JSVAL_TO_DOUBLE(from); *to = JSVAL_TO_DOUBLE(from);
else return false; else return false;
return true; return true;
case JSTYPE_BOOLEAN: case JSTYPE_BOOLEAN:
@ -216,7 +216,7 @@ JSObject_from_PObjectWrapperChild(JSContext*,
{ {
const ObjectWrapperChild* owc = const ObjectWrapperChild* owc =
static_cast<const ObjectWrapperChild*>(from); static_cast<const ObjectWrapperChild*>(from);
*to = owc ? owc->mObj : JSVAL_NULL; *to = owc ? owc->mObj : NULL;
return true; return true;
} }
@ -263,7 +263,7 @@ ObjectWrapperChild::jsval_from_JSVariant(JSContext* cx, const JSVariant& from,
*to = INT_TO_JSVAL(from.get_int()); *to = INT_TO_JSVAL(from.get_int());
return true; return true;
case JSVariant::Tdouble: case JSVariant::Tdouble:
return !!JS_NewDoubleValue(cx, from.get_double(), to); return !!JS_NewNumberValue(cx, from.get_double(), to);
case JSVariant::Tbool: case JSVariant::Tbool:
*to = BOOLEAN_TO_JSVAL(from.get_bool()); *to = BOOLEAN_TO_JSVAL(from.get_bool());
return true; return true;
@ -444,7 +444,7 @@ ObjectWrapperChild::AnswerNewEnumerateInit(/* no in-parameters */
JSObject* state = JS_NewObjectWithGivenProto(cx, clasp, NULL, NULL); JSObject* state = JS_NewObjectWithGivenProto(cx, clasp, NULL, NULL);
if (!state) if (!state)
return false; return false;
AutoValueRooter tvr(cx, state); AutoObjectRooter tvr(cx, state);
for (JSObject* proto = mObj; for (JSObject* proto = mObj;
proto; proto;

Просмотреть файл

@ -230,7 +230,7 @@ ObjectWrapperParent::GetJSObject(JSContext* cx) const
static ObjectWrapperParent* static ObjectWrapperParent*
Unwrap(JSContext* cx, JSObject* obj) Unwrap(JSContext* cx, JSObject* obj)
{ {
while (obj->getClass() != &ObjectWrapperParent::sCPOW_JSClass.base) while (obj->getJSClass() != &ObjectWrapperParent::sCPOW_JSClass.base)
if (!(obj = obj->getProto())) if (!(obj = obj->getProto()))
return NULL; return NULL;
@ -275,7 +275,7 @@ ObjectWrapperParent::jsval_to_JSVariant(JSContext* cx, jsval from,
if (JSVAL_IS_INT(from)) if (JSVAL_IS_INT(from))
*to = JSVAL_TO_INT(from); *to = JSVAL_TO_INT(from);
else if (JSVAL_IS_DOUBLE(from)) else if (JSVAL_IS_DOUBLE(from))
*to = *JSVAL_TO_DOUBLE(from); *to = JSVAL_TO_DOUBLE(from);
else return false; else return false;
return true; return true;
case JSTYPE_BOOLEAN: case JSTYPE_BOOLEAN:
@ -310,7 +310,7 @@ ObjectWrapperParent::jsval_from_JSVariant(JSContext* cx, const JSVariant& from,
*to = INT_TO_JSVAL(from.get_int()); *to = INT_TO_JSVAL(from.get_int());
return true; return true;
case JSVariant::Tdouble: case JSVariant::Tdouble:
return !!JS_NewDoubleValue(cx, from.get_double(), to); return !!JS_NewNumberValue(cx, from.get_double(), to);
case JSVariant::Tbool: case JSVariant::Tbool:
*to = BOOLEAN_TO_JSVAL(from.get_bool()); *to = BOOLEAN_TO_JSVAL(from.get_bool());
return true; return true;
@ -379,10 +379,12 @@ jsid_from_nsString(JSContext* cx, const nsString& from, jsid* to)
} }
static bool static bool
jsval_to_nsString(JSContext* cx, jsval from, nsString* to) jsval_to_nsString(JSContext* cx, jsid from, nsString* to)
{ {
JSString* str; JSString* str;
if ((str = JS_ValueToString(cx, from))) { jsval idval;
if (JS_IdToValue(cx, from, &idval) &&
(str = JS_ValueToString(cx, idval))) {
*to = JS_GetStringChars(str); *to = JS_GetStringChars(str);
return true; return true;
} }
@ -390,7 +392,7 @@ jsval_to_nsString(JSContext* cx, jsval from, nsString* to)
} }
/*static*/ JSBool /*static*/ JSBool
ObjectWrapperParent::CPOW_AddProperty(JSContext *cx, JSObject *obj, jsval id, ObjectWrapperParent::CPOW_AddProperty(JSContext *cx, JSObject *obj, jsid id,
jsval *vp) jsval *vp)
{ {
CPOW_LOG(("Calling CPOW_AddProperty (%s)...", CPOW_LOG(("Calling CPOW_AddProperty (%s)...",
@ -417,7 +419,7 @@ ObjectWrapperParent::CPOW_AddProperty(JSContext *cx, JSObject *obj, jsval id,
} }
/*static*/ JSBool /*static*/ JSBool
ObjectWrapperParent::CPOW_GetProperty(JSContext *cx, JSObject *obj, jsval id, ObjectWrapperParent::CPOW_GetProperty(JSContext *cx, JSObject *obj, jsid id,
jsval *vp) jsval *vp)
{ {
CPOW_LOG(("Calling CPOW_GetProperty (%s)...", CPOW_LOG(("Calling CPOW_GetProperty (%s)...",
@ -444,7 +446,7 @@ ObjectWrapperParent::CPOW_GetProperty(JSContext *cx, JSObject *obj, jsval id,
} }
/*static*/ JSBool /*static*/ JSBool
ObjectWrapperParent::CPOW_SetProperty(JSContext *cx, JSObject *obj, jsval id, ObjectWrapperParent::CPOW_SetProperty(JSContext *cx, JSObject *obj, jsid id,
jsval *vp) jsval *vp)
{ {
CPOW_LOG(("Calling CPOW_SetProperty (%s)...", CPOW_LOG(("Calling CPOW_SetProperty (%s)...",
@ -473,7 +475,7 @@ ObjectWrapperParent::CPOW_SetProperty(JSContext *cx, JSObject *obj, jsval id,
} }
/*static*/ JSBool /*static*/ JSBool
ObjectWrapperParent::CPOW_DelProperty(JSContext *cx, JSObject *obj, jsval id, ObjectWrapperParent::CPOW_DelProperty(JSContext *cx, JSObject *obj, jsid id,
jsval *vp) jsval *vp)
{ {
CPOW_LOG(("Calling CPOW_DelProperty (%s)...", CPOW_LOG(("Calling CPOW_DelProperty (%s)...",
@ -580,7 +582,7 @@ ObjectWrapperParent::CPOW_NewEnumerate(JSContext *cx, JSObject *obj,
} }
/*static*/ JSBool /*static*/ JSBool
ObjectWrapperParent::CPOW_NewResolve(JSContext *cx, JSObject *obj, jsval id, ObjectWrapperParent::CPOW_NewResolve(JSContext *cx, JSObject *obj, jsid id,
uintN flags, JSObject **objp) uintN flags, JSObject **objp)
{ {
CPOW_LOG(("Calling CPOW_NewResolve (%s)...", CPOW_LOG(("Calling CPOW_NewResolve (%s)...",
@ -606,11 +608,9 @@ ObjectWrapperParent::CPOW_NewResolve(JSContext *cx, JSObject *obj, jsval id,
!JSObject_from_PObjectWrapperParent(cx, out_pobj, objp)) !JSObject_from_PObjectWrapperParent(cx, out_pobj, objp))
return JS_FALSE; return JS_FALSE;
jsid interned_id; if (*objp) {
if (*objp &&
JS_ValueToId(cx, id, &interned_id)) {
AutoResolveFlag arf(cx, *objp); AutoResolveFlag arf(cx, *objp);
JS_DefinePropertyById(cx, *objp, interned_id, JSVAL_VOID, NULL, NULL, JS_DefinePropertyById(cx, *objp, id, JSVAL_VOID, NULL, NULL,
JSPROP_ENUMERATE); JSPROP_ENUMERATE);
} }
return JS_TRUE; return JS_TRUE;
@ -708,7 +708,7 @@ ObjectWrapperParent::CPOW_Construct(JSContext *cx, JSObject *obj, uintN argc,
} }
/*static*/ JSBool /*static*/ JSBool
ObjectWrapperParent::CPOW_HasInstance(JSContext *cx, JSObject *obj, jsval v, ObjectWrapperParent::CPOW_HasInstance(JSContext *cx, JSObject *obj, const jsval *v,
JSBool *bp) JSBool *bp)
{ {
CPOW_LOG(("Calling CPOW_HasInstance...")); CPOW_LOG(("Calling CPOW_HasInstance..."));
@ -723,7 +723,7 @@ ObjectWrapperParent::CPOW_HasInstance(JSContext *cx, JSObject *obj, jsval v,
JSVariant in_v; JSVariant in_v;
if (!jsval_to_JSVariant(cx, v, &in_v)) if (!jsval_to_JSVariant(cx, *v, &in_v))
return JS_FALSE; return JS_FALSE;
return (self->Manager()->RequestRunToCompletion() && return (self->Manager()->RequestRunToCompletion() &&
@ -733,7 +733,7 @@ ObjectWrapperParent::CPOW_HasInstance(JSContext *cx, JSObject *obj, jsval v,
} }
/*static*/ JSBool /*static*/ JSBool
ObjectWrapperParent::CPOW_Equality(JSContext *cx, JSObject *obj, jsval v, ObjectWrapperParent::CPOW_Equality(JSContext *cx, JSObject *obj, const jsval *v,
JSBool *bp) JSBool *bp)
{ {
CPOW_LOG(("Calling CPOW_Equality...")); CPOW_LOG(("Calling CPOW_Equality..."));
@ -744,10 +744,10 @@ ObjectWrapperParent::CPOW_Equality(JSContext *cx, JSObject *obj, jsval v,
if (!self) if (!self)
return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_Equality"); return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_Equality");
if (JSVAL_IS_PRIMITIVE(v)) if (JSVAL_IS_PRIMITIVE(*v))
return JS_TRUE; return JS_TRUE;
ObjectWrapperParent* other = Unwrap(cx, JSVAL_TO_OBJECT(v)); ObjectWrapperParent* other = Unwrap(cx, JSVAL_TO_OBJECT(*v));
if (!other) if (!other)
return JS_TRUE; return JS_TRUE;

Просмотреть файл

@ -88,16 +88,16 @@ private:
mutable JSObject* mObj; mutable JSObject* mObj;
static JSBool static JSBool
CPOW_AddProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp); CPOW_AddProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
static JSBool static JSBool
CPOW_DelProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp); CPOW_DelProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
static JSBool static JSBool
CPOW_GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp); CPOW_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
static JSBool static JSBool
CPOW_SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp); CPOW_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
JSBool NewEnumerateInit(JSContext* cx, jsval* statep, jsid* idp); JSBool NewEnumerateInit(JSContext* cx, jsval* statep, jsid* idp);
JSBool NewEnumerateNext(JSContext* cx, jsval* statep, jsid* idp); JSBool NewEnumerateNext(JSContext* cx, jsval* statep, jsid* idp);
@ -107,7 +107,7 @@ private:
jsval *statep, jsid *idp); jsval *statep, jsid *idp);
static JSBool static JSBool
CPOW_NewResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, CPOW_NewResolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
JSObject **objp); JSObject **objp);
static JSBool static JSBool
@ -125,10 +125,10 @@ private:
jsval *rval); jsval *rval);
static JSBool static JSBool
CPOW_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp); CPOW_HasInstance(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp);
static JSBool static JSBool
CPOW_Equality(JSContext *cx, JSObject *obj, jsval v, JSBool *bp); CPOW_Equality(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp);
static bool jsval_to_JSVariant(JSContext* cx, jsval from, JSVariant* to); static bool jsval_to_JSVariant(JSContext* cx, jsval from, JSVariant* to);
static bool jsval_from_JSVariant(JSContext* cx, const JSVariant& from, static bool jsval_from_JSVariant(JSContext* cx, const JSVariant& from,

Просмотреть файл

@ -160,7 +160,7 @@ private:
static Handle* static Handle*
Unwrap(JSContext* cx, JSObject* obj) { Unwrap(JSContext* cx, JSObject* obj) {
while (obj && obj->getClass() != &sHandle_JSClass) while (obj && obj->getJSClass() != &sHandle_JSClass)
obj = obj->getProto(); obj = obj->getProto();
if (!obj) if (!obj)
@ -175,7 +175,7 @@ private:
} }
static JSBool static JSBool
GetParent(JSContext* cx, JSObject* obj, jsval, jsval* vp) { GetParent(JSContext* cx, JSObject* obj, jsid, jsval* vp) {
JS_SET_RVAL(cx, vp, JSVAL_NULL); JS_SET_RVAL(cx, vp, JSVAL_NULL);
Handle* self = Unwrap(cx, obj); Handle* self = Unwrap(cx, obj);
@ -193,7 +193,7 @@ private:
} }
static JSBool static JSBool
GetIsValid(JSContext* cx, JSObject* obj, jsval, jsval* vp) { GetIsValid(JSContext* cx, JSObject* obj, jsid, jsval* vp) {
Handle* self = Unwrap(cx, obj); Handle* self = Unwrap(cx, obj);
JS_SET_RVAL(cx, vp, BOOLEAN_TO_JSVAL(!!self)); JS_SET_RVAL(cx, vp, BOOLEAN_TO_JSVAL(!!self));
return JS_TRUE; return JS_TRUE;

Просмотреть файл

@ -146,7 +146,7 @@ JetpackActorCommon::jsval_to_PrimVariant(JSContext* cx, JSType type, jsval from,
if (JSVAL_IS_INT(from)) if (JSVAL_IS_INT(from))
*to = JSVAL_TO_INT(from); *to = JSVAL_TO_INT(from);
else if (JSVAL_IS_DOUBLE(from)) else if (JSVAL_IS_DOUBLE(from))
*to = *JSVAL_TO_DOUBLE(from); *to = JSVAL_TO_DOUBLE(from);
else else
return false; return false;
return true; return true;
@ -278,7 +278,7 @@ JetpackActorCommon::jsval_from_PrimVariant(JSContext* cx,
return true; return true;
case PrimVariant::Tdouble: case PrimVariant::Tdouble:
return !!JS_NewDoubleValue(cx, from.get_double(), to); return !!JS_NewNumberValue(cx, from.get_double(), to);
case PrimVariant::TnsString: { case PrimVariant::TnsString: {
const nsString& str = from.get_nsString(); const nsString& str = from.get_nsString();
@ -349,11 +349,11 @@ JetpackActorCommon::jsval_from_CompVariant(JSContext* cx,
for (PRUint32 i = 0; i < kvs.Length(); ++i) { for (PRUint32 i = 0; i < kvs.Length(); ++i) {
const KeyValue& kv = kvs.ElementAt(i); const KeyValue& kv = kvs.ElementAt(i);
js::AutoValueRooter toSet(cx); js::AutoValueRooter toSet(cx);
if (!jsval_from_Variant(cx, kv.value(), toSet.addr(), seen) || if (!jsval_from_Variant(cx, kv.value(), toSet.jsval_addr(), seen) ||
!JS_SetUCProperty(cx, obj, !JS_SetUCProperty(cx, obj,
kv.key().get(), kv.key().get(),
kv.key().Length(), kv.key().Length(),
toSet.addr())) toSet.jsval_addr()))
return false; return false;
} }
@ -456,11 +456,11 @@ JetpackActorCommon::RecvMessage(JSContext* cx,
Variant* vp = results ? results->AppendElement() : NULL; Variant* vp = results ? results->AppendElement() : NULL;
rval.set(JSVAL_VOID); rval.set(JSVAL_VOID);
if (!JS_CallFunctionValue(cx, implGlobal, snapshot[i], argc, argv, if (!JS_CallFunctionValue(cx, implGlobal, snapshot[i], argc, argv,
rval.addr())) { rval.jsval_addr())) {
(void) JS_ReportPendingException(cx); (void) JS_ReportPendingException(cx);
if (vp) if (vp)
*vp = void_t(); *vp = void_t();
} else if (vp && !jsval_to_Variant(cx, rval.value(), vp)) } else if (vp && !jsval_to_Variant(cx, rval.jsval_value(), vp))
*vp = void_t(); *vp = void_t();
} }

Просмотреть файл

@ -158,7 +158,7 @@ JetpackChild::RecvEvalScript(const nsString& code)
js::AutoValueRooter ignored(mCx); js::AutoValueRooter ignored(mCx);
(void) JS_EvaluateUCScript(mCx, JS_GetGlobalObject(mCx), code.get(), (void) JS_EvaluateUCScript(mCx, JS_GetGlobalObject(mCx), code.get(),
code.Length(), "", 1, ignored.addr()); code.Length(), "", 1, ignored.jsval_addr());
return true; return true;
} }
@ -442,7 +442,7 @@ JetpackChild::EvalInSandbox(JSContext* cx, uintN argc, jsval* vp)
js::AutoValueRooter ignored(cx); js::AutoValueRooter ignored(cx);
return JS_EvaluateUCScript(cx, obj, JS_GetStringChars(str), JS_GetStringLength(str), "", 1, return JS_EvaluateUCScript(cx, obj, JS_GetStringChars(str), JS_GetStringLength(str), "", 1,
ignored.addr()); ignored.jsval_addr());
} }
} // namespace jetpack } // namespace jetpack

Просмотреть файл

@ -103,7 +103,7 @@ JetpackParent::SendMessage(const nsAString& aMessageName)
NS_IMETHODIMP NS_IMETHODIMP
JetpackParent::RegisterReceiver(const nsAString& aMessageName, JetpackParent::RegisterReceiver(const nsAString& aMessageName,
jsval aReceiver) const jsval &aReceiver)
{ {
return JetpackActorCommon::RegisterReceiver(mContext, return JetpackActorCommon::RegisterReceiver(mContext,
nsString(aMessageName), nsString(aMessageName),
@ -112,7 +112,7 @@ JetpackParent::RegisterReceiver(const nsAString& aMessageName,
NS_IMETHODIMP NS_IMETHODIMP
JetpackParent::UnregisterReceiver(const nsAString& aMessageName, JetpackParent::UnregisterReceiver(const nsAString& aMessageName,
jsval aReceiver) const jsval &aReceiver)
{ {
JetpackActorCommon::UnregisterReceiver(nsString(aMessageName), JetpackActorCommon::UnregisterReceiver(nsString(aMessageName),
aReceiver); aReceiver);

Просмотреть файл

@ -966,7 +966,7 @@ jsd_GetValueBoolean(JSDContext* jsdc, JSDValue* jsdval);
extern int32 extern int32
jsd_GetValueInt(JSDContext* jsdc, JSDValue* jsdval); jsd_GetValueInt(JSDContext* jsdc, JSDValue* jsdval);
extern jsdouble* extern jsdouble
jsd_GetValueDouble(JSDContext* jsdc, JSDValue* jsdval); jsd_GetValueDouble(JSDContext* jsdc, JSDValue* jsdval);
extern JSString* extern JSString*

Просмотреть файл

@ -203,13 +203,12 @@ jsd_GetValueInt(JSDContext* jsdc, JSDValue* jsdval)
return JSVAL_TO_INT(val); return JSVAL_TO_INT(val);
} }
jsdouble* jsdouble
jsd_GetValueDouble(JSDContext* jsdc, JSDValue* jsdval) jsd_GetValueDouble(JSDContext* jsdc, JSDValue* jsdval)
{ {
jsval val = jsdval->val; if(!JSVAL_IS_DOUBLE(jsdval->val))
if(!JSVAL_IS_DOUBLE(val))
return 0; return 0;
return JSVAL_TO_DOUBLE(val); return JSVAL_TO_DOUBLE(jsdval->val);
} }
JSString* JSString*
@ -492,7 +491,8 @@ jsd_GetValueProperty(JSDContext* jsdc, JSDValue* jsdval, JSString* name)
JSPropertyDesc pd; JSPropertyDesc pd;
const jschar * nameChars; const jschar * nameChars;
size_t nameLen; size_t nameLen;
jsval val; jsval val, nameval;
jsid nameid;
if(!jsd_IsValueObject(jsdc, jsdval)) if(!jsd_IsValueObject(jsdc, jsdval))
return NULL; return NULL;
@ -548,8 +548,14 @@ jsd_GetValueProperty(JSDContext* jsdc, JSDValue* jsdval, JSString* name)
JS_EndRequest(cx); JS_EndRequest(cx);
pd.id = STRING_TO_JSVAL(name); nameval = STRING_TO_JSVAL(name);
pd.alias = pd.slot = pd.spare = 0; if (!JS_ValueToId(cx, nameval, &nameid) ||
!JS_IdToValue(cx, nameid, &pd.id)) {
return NULL;
}
pd.slot = pd.spare = 0;
pd.alias = JSVAL_NULL;
pd.flags |= (attrs & JSPROP_ENUMERATE) ? JSPD_ENUMERATE : 0 pd.flags |= (attrs & JSPROP_ENUMERATE) ? JSPD_ENUMERATE : 0
| (attrs & JSPROP_READONLY) ? JSPD_READONLY : 0 | (attrs & JSPROP_READONLY) ? JSPD_READONLY : 0
| (attrs & JSPROP_PERMANENT) ? JSPD_PERMANENT : 0; | (attrs & JSPROP_PERMANENT) ? JSPD_PERMANENT : 0;

Просмотреть файл

@ -38,8 +38,6 @@
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#include "jsdbgapi.h" #include "jsdbgapi.h"
#include "jscntxt.h"
#include "jsfun.h"
#include "jsd_xpc.h" #include "jsd_xpc.h"
#include "nsIXPConnect.h" #include "nsIXPConnect.h"
@ -1014,7 +1012,8 @@ jsdScript::CreatePPLineMap()
PRBool scriptOwner = PR_FALSE; PRBool scriptOwner = PR_FALSE;
if (fun) { if (fun) {
if (fun->nargs > 12) uintN nargs = JS_GetFunctionArgumentCount(cx, fun);
if (nargs > 12)
return nsnull; return nsnull;
JSString *jsstr = JS_DecompileFunctionBody (cx, fun, 4); JSString *jsstr = JS_DecompileFunctionBody (cx, fun, 4);
if (!jsstr) if (!jsstr)
@ -1023,7 +1022,7 @@ jsdScript::CreatePPLineMap()
const char *argnames[] = {"arg1", "arg2", "arg3", "arg4", const char *argnames[] = {"arg1", "arg2", "arg3", "arg4",
"arg5", "arg6", "arg7", "arg8", "arg5", "arg6", "arg7", "arg8",
"arg9", "arg10", "arg11", "arg12" }; "arg9", "arg10", "arg11", "arg12" };
fun = JS_CompileUCFunction (cx, obj, "ppfun", fun->nargs, argnames, fun = JS_CompileUCFunction (cx, obj, "ppfun", nargs, argnames,
JS_GetStringChars(jsstr), JS_GetStringChars(jsstr),
JS_GetStringLength(jsstr), JS_GetStringLength(jsstr),
"x-jsd:ppbuffer?type=function", 3); "x-jsd:ppbuffer?type=function", 3);
@ -1232,37 +1231,32 @@ jsdScript::GetParameterNames(PRUint32* count, PRUnichar*** paramNames)
JSAutoRequest ar(cx); JSAutoRequest ar(cx);
if (!fun || !fun->hasLocalNames() || fun->nargs == 0) { uintN nargs = JS_GetFunctionArgumentCount(cx, fun);
if (!fun || !JS_FunctionHasLocalNames(cx, fun) || nargs == 0) {
*count = 0; *count = 0;
*paramNames = nsnull; *paramNames = nsnull;
return NS_OK; return NS_OK;
} }
PRUnichar **ret = PRUnichar **ret =
static_cast<PRUnichar**>(NS_Alloc(fun->nargs * sizeof(PRUnichar*))); static_cast<PRUnichar**>(NS_Alloc(nargs * sizeof(PRUnichar*)));
if (!ret) if (!ret)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
void *mark = JS_ARENA_MARK(&cx->tempPool); void *mark;
jsuword *names = js_GetLocalNameArray(cx, fun, &cx->tempPool); jsuword *names = JS_GetFunctionLocalNameArray(cx, fun, &mark);
if (!names) { if (!names) {
NS_Free(ret); NS_Free(ret);
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
nsresult rv = NS_OK; nsresult rv = NS_OK;
for (uintN i = 0; i < fun->nargs; ++i) { for (uintN i = 0; i < nargs; ++i) {
JSAtom *atom = JS_LOCAL_NAME_TO_ATOM(names[i]); JSAtom *atom = JS_LocalNameToAtom(names[i]);
if (!atom) { if (!atom) {
ret[i] = 0; ret[i] = 0;
} else { } else {
jsval atomVal = ATOM_KEY(atom); JSString *str = JS_AtomKey(atom);
if (!JSVAL_IS_STRING(atomVal)) {
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(i, ret);
rv = NS_ERROR_UNEXPECTED;
break;
}
JSString *str = JSVAL_TO_STRING(atomVal);
ret[i] = NS_strndup(reinterpret_cast<PRUnichar*>(JS_GetStringChars(str)), ret[i] = NS_strndup(reinterpret_cast<PRUnichar*>(JS_GetStringChars(str)),
JS_GetStringLength(str)); JS_GetStringLength(str));
if (!ret[i]) { if (!ret[i]) {
@ -1272,10 +1266,10 @@ jsdScript::GetParameterNames(PRUint32* count, PRUnichar*** paramNames)
} }
} }
} }
JS_ARENA_RELEASE(&cx->tempPool, mark); JS_ReleaseFunctionLocalNameArray(cx, mark);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return rv; return rv;
*count = fun->nargs; *count = nargs;
*paramNames = ret; *paramNames = ret;
return NS_OK; return NS_OK;
} }
@ -1484,8 +1478,7 @@ jsdScript::SetBreakpoint(PRUint32 aPC)
{ {
ASSERT_VALID_EPHEMERAL; ASSERT_VALID_EPHEMERAL;
jsuword pc = mFirstPC + aPC; jsuword pc = mFirstPC + aPC;
JSD_SetExecutionHook (mCx, mScript, pc, jsds_ExecutionHookProc, JSD_SetExecutionHook (mCx, mScript, pc, jsds_ExecutionHookProc, NULL);
reinterpret_cast<void *>(PRIVATE_TO_JSVAL(NULL)));
return NS_OK; return NS_OK;
} }
@ -1990,7 +1983,7 @@ jsdStackFrame::Eval (const nsAString &bytes, const nsACString &fileName,
if (JS_IsExceptionPending(cx)) if (JS_IsExceptionPending(cx))
JS_GetPendingException (cx, &jv); JS_GetPendingException (cx, &jv);
else else
jv = 0; jv = JSVAL_NULL;
} }
JS_RestoreExceptionState (cx, estate); JS_RestoreExceptionState (cx, estate);
@ -2195,10 +2188,7 @@ NS_IMETHODIMP
jsdValue::GetDoubleValue(double *_rval) jsdValue::GetDoubleValue(double *_rval)
{ {
ASSERT_VALID_EPHEMERAL; ASSERT_VALID_EPHEMERAL;
double *dp = JSD_GetValueDouble (mCx, mValue); *_rval = JSD_GetValueDouble (mCx, mValue);
if (!dp)
return NS_ERROR_FAILURE;
*_rval = *dp;
return NS_OK; return NS_OK;
} }
@ -2907,7 +2897,7 @@ jsdService::WrapValue(jsdIValue **_rval)
} }
NS_IMETHODIMP NS_IMETHODIMP
jsdService::WrapJSValue(jsval value, jsdIValue** _rval) jsdService::WrapJSValue(const jsval &value, jsdIValue** _rval)
{ {
JSDValue *jsdv = JSD_NewValue(mCx, value); JSDValue *jsdv = JSD_NewValue(mCx, value);
if (!jsdv) if (!jsdv)

Просмотреть файл

@ -1112,7 +1112,7 @@ JSD_GetValueInt(JSDContext* jsdc, JSDValue* jsdval)
return jsd_GetValueInt(jsdc, jsdval); return jsd_GetValueInt(jsdc, jsdval);
} }
JSD_PUBLIC_API(jsdouble*) JSD_PUBLIC_API(jsdouble)
JSD_GetValueDouble(JSDContext* jsdc, JSDValue* jsdval) JSD_GetValueDouble(JSDContext* jsdc, JSDValue* jsdval)
{ {
JSD_ASSERT_VALID_CONTEXT(jsdc); JSD_ASSERT_VALID_CONTEXT(jsdc);

Просмотреть файл

@ -54,13 +54,11 @@ extern "C"
} }
#endif #endif
JS_BEGIN_EXTERN_C
#include "jsapi.h" #include "jsapi.h"
#include "jsdbgapi.h" #include "jsdbgapi.h"
#ifdef LIVEWIRE #ifdef LIVEWIRE
#include "lwdbgapi.h" #include "lwdbgapi.h"
#endif #endif
JS_END_EXTERN_C
JS_BEGIN_EXTERN_C JS_BEGIN_EXTERN_C
@ -1270,7 +1268,7 @@ JSD_GetValueInt(JSDContext* jsdc, JSDValue* jsdval);
* Return double value (does NOT do conversion). * Return double value (does NOT do conversion).
* *** new for version 1.1 **** * *** new for version 1.1 ****
*/ */
extern JSD_PUBLIC_API(jsdouble*) extern JSD_PUBLIC_API(jsdouble)
JSD_GetValueDouble(JSDContext* jsdc, JSDValue* jsdval); JSD_GetValueDouble(JSDContext* jsdc, JSDValue* jsdval);
/* /*

Просмотреть файл

@ -226,6 +226,7 @@ INSTALLED_HEADERS = \
jsscript.h \ jsscript.h \
jsscriptinlines.h \ jsscriptinlines.h \
jsstaticcheck.h \ jsstaticcheck.h \
jsstdint.h \
jsstr.h \ jsstr.h \
jstask.h \ jstask.h \
jstracer.h \ jstracer.h \
@ -239,6 +240,8 @@ INSTALLED_HEADERS = \
jswrapper.h \ jswrapper.h \
jsxdrapi.h \ jsxdrapi.h \
jsxml.h \ jsxml.h \
jsval.h \
jsvalue.h \
prmjtime.h \ prmjtime.h \
$(NULL) $(NULL)

Просмотреть файл

@ -1,91 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sw=4 et tw=0 ft=C:
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released
* June 22, 2008.
*
* The Initial Developer of the Original Code is
* Andreas Gal <gal@uci.edu>
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/**
* This file declares builtin functions that can be called from JITted code.
* Each line starts with "BUILTIN" and an integer, the number of arguments the
* builtin takes. Builtins with no arguments are not supported.
*
* The macro arguments are:
*
* - 'extern' to indicate extern linkage for these functions and the associated
* CallInfo.
*
* - The return type. This identifier must name one of the _JS_TYPEINFO_*
* macros defined in jsbuiltins.h.
*
* - The builtin name. Prefixed with "js_" this gives the native function name.
*
* - The parameter types.
*
* - The cse flag. 1 if the builtin call can be optimized away by common
* subexpression elimination; otherwise 0. This should be 1 only if the
* function is idempotent and the return value is determined solely by the
* arguments.
*
* - The fold flag. Reserved. The same as cse for now.
*/
/*
* NB: bool FASTCALL is not compatible with Nanojit's calling convention usage.
* Do not use bool FASTCALL, use JSBool only!
*/
BUILTIN2(extern, JSVAL, js_BoxDouble, CONTEXT, DOUBLE, 1, 1)
BUILTIN2(extern, JSVAL, js_BoxInt32, CONTEXT, INT32, 1, 1)
BUILTIN1(extern, DOUBLE, js_UnboxDouble, JSVAL, 1, 1)
BUILTIN1(extern, INT32, js_UnboxInt32, JSVAL, 1, 1)
BUILTIN2(extern, DOUBLE, js_dmod, DOUBLE, DOUBLE, 1, 1)
BUILTIN2(extern, INT32, js_imod, INT32, INT32, 1, 1)
BUILTIN1(extern, INT32, js_DoubleToInt32, DOUBLE, 1, 1)
BUILTIN1(extern, UINT32, js_DoubleToUint32, DOUBLE, 1, 1)
BUILTIN2(extern, DOUBLE, js_StringToNumber, CONTEXT, STRING, 1, 1)
BUILTIN2(extern, INT32, js_StringToInt32, CONTEXT, STRING, 1, 1)
BUILTIN2(FRIEND, BOOL, js_CloseIterator, CONTEXT, JSVAL, 0, 0)
BUILTIN2(extern, SIDEEXIT, js_CallTree, INTERPSTATE, FRAGMENT, 0, 0)
BUILTIN3(extern, BOOL, js_AddProperty, CONTEXT, OBJECT, SCOPEPROP, 0, 0)
BUILTIN3(extern, BOOL, js_HasNamedProperty, CONTEXT, OBJECT, STRING, 0, 0)
BUILTIN3(extern, BOOL, js_HasNamedPropertyInt32, CONTEXT, OBJECT, INT32, 0, 0)
BUILTIN3(extern, JSVAL, js_CallGetter, CONTEXT, OBJECT, SCOPEPROP, 0, 0)
BUILTIN2(extern, STRING, js_TypeOfObject, CONTEXT, OBJECT, 1, 1)
BUILTIN2(extern, STRING, js_TypeOfBoolean, CONTEXT, INT32, 1, 1)
BUILTIN2(extern, DOUBLE, js_BooleanOrUndefinedToNumber, CONTEXT, INT32, 1, 1)
BUILTIN2(extern, STRING, js_BooleanOrUndefinedToString, CONTEXT, INT32, 1, 1)
BUILTIN2(extern, OBJECT, js_Arguments, CONTEXT, OBJECT 0, 0)
BUILTIN4(extern, OBJECT, js_NewNullClosure, CONTEXT, OBJECT, OBJECT, OBJECT, 0, 0)

Просмотреть файл

@ -519,7 +519,8 @@ case "$target" in
CFLAGS="$CFLAGS -TC -nologo" CFLAGS="$CFLAGS -TC -nologo"
CXXFLAGS="$CXXFLAGS -TP -nologo" CXXFLAGS="$CXXFLAGS -TP -nologo"
# MSVC warning C4345 warns of newly conformant behavior as of VS2003. # MSVC warning C4345 warns of newly conformant behavior as of VS2003.
CXXFLAGS="$CXXFLAGS -wd4345" # MSVC warning C4800 is ubiquitous, useless, and annoying.
CXXFLAGS="$CXXFLAGS -wd4345 -wd4800"
AC_LANG_SAVE AC_LANG_SAVE
AC_LANG_C AC_LANG_C
AC_TRY_COMPILE([#include <stdio.h>], AC_TRY_COMPILE([#include <stdio.h>],

Просмотреть файл

@ -89,17 +89,17 @@ namespace CType {
static void Finalize(JSContext* cx, JSObject* obj); static void Finalize(JSContext* cx, JSObject* obj);
static void FinalizeProtoClass(JSContext* cx, JSObject* obj); static void FinalizeProtoClass(JSContext* cx, JSObject* obj);
static JSBool PrototypeGetter(JSContext* cx, JSObject* obj, jsval idval, static JSBool PrototypeGetter(JSContext* cx, JSObject* obj, jsid idval,
jsval* vp); jsval* vp);
static JSBool NameGetter(JSContext* cx, JSObject* obj, jsval idval, static JSBool NameGetter(JSContext* cx, JSObject* obj, jsid idval,
jsval* vp); jsval* vp);
static JSBool SizeGetter(JSContext* cx, JSObject* obj, jsval idval, static JSBool SizeGetter(JSContext* cx, JSObject* obj, jsid idval,
jsval* vp); jsval* vp);
static JSBool PtrGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp); static JSBool PtrGetter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp);
static JSBool CreateArray(JSContext* cx, uintN argc, jsval* vp); static JSBool CreateArray(JSContext* cx, uintN argc, jsval* vp);
static JSBool ToString(JSContext* cx, uintN argc, jsval* vp); static JSBool ToString(JSContext* cx, uintN argc, jsval* vp);
static JSBool ToSource(JSContext* cx, uintN argc, jsval* vp); static JSBool ToSource(JSContext* cx, uintN argc, jsval* vp);
static JSBool HasInstance(JSContext* cx, JSObject* obj, jsval v, JSBool* bp); static JSBool HasInstance(JSContext* cx, JSObject* obj, const jsval *v, JSBool* bp);
} }
namespace PointerType { namespace PointerType {
@ -107,11 +107,11 @@ namespace PointerType {
static JSBool ConstructData(JSContext* cx, JSObject* obj, uintN argc, static JSBool ConstructData(JSContext* cx, JSObject* obj, uintN argc,
jsval* argv, jsval* rval); jsval* argv, jsval* rval);
static JSBool TargetTypeGetter(JSContext* cx, JSObject* obj, jsval idval, static JSBool TargetTypeGetter(JSContext* cx, JSObject* obj, jsid idval,
jsval* vp); jsval* vp);
static JSBool ContentsGetter(JSContext* cx, JSObject* obj, jsval idval, static JSBool ContentsGetter(JSContext* cx, JSObject* obj, jsid idval,
jsval* vp); jsval* vp);
static JSBool ContentsSetter(JSContext* cx, JSObject* obj, jsval idval, static JSBool ContentsSetter(JSContext* cx, JSObject* obj, jsid idval,
jsval* vp); jsval* vp);
static JSBool IsNull(JSContext* cx, uintN argc, jsval* vp); static JSBool IsNull(JSContext* cx, uintN argc, jsval* vp);
} }
@ -121,12 +121,12 @@ namespace ArrayType {
static JSBool ConstructData(JSContext* cx, JSObject* obj, uintN argc, static JSBool ConstructData(JSContext* cx, JSObject* obj, uintN argc,
jsval* argv, jsval* rval); jsval* argv, jsval* rval);
static JSBool ElementTypeGetter(JSContext* cx, JSObject* obj, jsval idval, static JSBool ElementTypeGetter(JSContext* cx, JSObject* obj, jsid idval,
jsval* vp); jsval* vp);
static JSBool LengthGetter(JSContext* cx, JSObject* obj, jsval idval, static JSBool LengthGetter(JSContext* cx, JSObject* obj, jsid idval,
jsval* vp); jsval* vp);
static JSBool Getter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp); static JSBool Getter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp);
static JSBool Setter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp); static JSBool Setter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp);
static JSBool AddressOfElement(JSContext* cx, uintN argc, jsval* vp); static JSBool AddressOfElement(JSContext* cx, uintN argc, jsval* vp);
} }
@ -135,11 +135,11 @@ namespace StructType {
static JSBool ConstructData(JSContext* cx, JSObject* obj, uintN argc, static JSBool ConstructData(JSContext* cx, JSObject* obj, uintN argc,
jsval* argv, jsval* rval); jsval* argv, jsval* rval);
static JSBool FieldsArrayGetter(JSContext* cx, JSObject* obj, jsval idval, static JSBool FieldsArrayGetter(JSContext* cx, JSObject* obj, jsid idval,
jsval* vp); jsval* vp);
static JSBool FieldGetter(JSContext* cx, JSObject* obj, jsval idval, static JSBool FieldGetter(JSContext* cx, JSObject* obj, jsid idval,
jsval* vp); jsval* vp);
static JSBool FieldSetter(JSContext* cx, JSObject* obj, jsval idval, static JSBool FieldSetter(JSContext* cx, JSObject* obj, jsid idval,
jsval* vp); jsval* vp);
static JSBool AddressOfField(JSContext* cx, uintN argc, jsval* vp); static JSBool AddressOfField(JSContext* cx, uintN argc, jsval* vp);
static JSBool Define(JSContext* cx, uintN argc, jsval* vp); static JSBool Define(JSContext* cx, uintN argc, jsval* vp);
@ -153,12 +153,12 @@ namespace FunctionType {
static JSBool Call(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, static JSBool Call(JSContext* cx, JSObject* obj, uintN argc, jsval* argv,
jsval* rval); jsval* rval);
static JSBool ArgTypesGetter(JSContext* cx, JSObject* obj, jsval idval, static JSBool ArgTypesGetter(JSContext* cx, JSObject* obj, jsid idval,
jsval* vp); jsval* vp);
static JSBool ReturnTypeGetter(JSContext* cx, JSObject* obj, jsval idval, static JSBool ReturnTypeGetter(JSContext* cx, JSObject* obj, jsid idval,
jsval* vp); jsval* vp);
static JSBool ABIGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp); static JSBool ABIGetter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp);
static JSBool IsVariadicGetter(JSContext* cx, JSObject* obj, jsval idval, static JSBool IsVariadicGetter(JSContext* cx, JSObject* obj, jsid idval,
jsval* vp); jsval* vp);
} }
@ -174,9 +174,9 @@ namespace CClosure {
namespace CData { namespace CData {
static void Finalize(JSContext* cx, JSObject* obj); static void Finalize(JSContext* cx, JSObject* obj);
static JSBool ValueGetter(JSContext* cx, JSObject* obj, jsval idval, static JSBool ValueGetter(JSContext* cx, JSObject* obj, jsid idval,
jsval* vp); jsval* vp);
static JSBool ValueSetter(JSContext* cx, JSObject* obj, jsval idval, static JSBool ValueSetter(JSContext* cx, JSObject* obj, jsid idval,
jsval* vp); jsval* vp);
static JSBool Address(JSContext* cx, uintN argc, jsval* vp); static JSBool Address(JSContext* cx, uintN argc, jsval* vp);
static JSBool ReadString(JSContext* cx, uintN argc, jsval* vp); static JSBool ReadString(JSContext* cx, uintN argc, jsval* vp);
@ -514,7 +514,7 @@ JSBool
TypeError(JSContext* cx, const char* expected, jsval actual) TypeError(JSContext* cx, const char* expected, jsval actual)
{ {
JSString* str = JS_ValueToSource(cx, actual); JSString* str = JS_ValueToSource(cx, actual);
js::AutoValueRooter root(cx, str); js::AutoStringRooter root(cx, str);
const char* src; const char* src;
if (str) { if (str) {
@ -682,7 +682,7 @@ InitTypeConstructor(JSContext* cx,
dataProto = JS_NewObject(cx, &sCDataProtoClass, CDataProto, parent); dataProto = JS_NewObject(cx, &sCDataProtoClass, CDataProto, parent);
if (!dataProto) if (!dataProto)
return false; return false;
js::AutoValueRooter protoroot(cx, dataProto); js::AutoObjectRooter protoroot(cx, dataProto);
// Define functions and properties on the 'dataProto' object that are common // Define functions and properties on the 'dataProto' object that are common
// to all CData objects created from this type constructor. (These will // to all CData objects created from this type constructor. (These will
@ -816,27 +816,27 @@ InitTypeClasses(JSContext* cx, JSObject* parent)
sPointerInstanceFunctions, sPointerInstanceProps, sPointerInstanceFunctions, sPointerInstanceProps,
protos[SLOT_POINTERPROTO], protos[SLOT_POINTERDATAPROTO])) protos[SLOT_POINTERPROTO], protos[SLOT_POINTERDATAPROTO]))
return false; return false;
js::AutoValueRooter proot(cx, protos[SLOT_POINTERDATAPROTO]); js::AutoObjectRooter proot(cx, protos[SLOT_POINTERDATAPROTO]);
if (!InitTypeConstructor(cx, parent, CTypeProto, CDataProto, if (!InitTypeConstructor(cx, parent, CTypeProto, CDataProto,
sArrayFunction, NULL, sArrayProps, sArrayFunction, NULL, sArrayProps,
sArrayInstanceFunctions, sArrayInstanceProps, sArrayInstanceFunctions, sArrayInstanceProps,
protos[SLOT_ARRAYPROTO], protos[SLOT_ARRAYDATAPROTO])) protos[SLOT_ARRAYPROTO], protos[SLOT_ARRAYDATAPROTO]))
return false; return false;
js::AutoValueRooter aroot(cx, protos[SLOT_ARRAYDATAPROTO]); js::AutoObjectRooter aroot(cx, protos[SLOT_ARRAYDATAPROTO]);
if (!InitTypeConstructor(cx, parent, CTypeProto, CDataProto, if (!InitTypeConstructor(cx, parent, CTypeProto, CDataProto,
sStructFunction, sStructFunctions, sStructProps, sStructFunction, sStructFunctions, sStructProps,
sStructInstanceFunctions, NULL, sStructInstanceFunctions, NULL,
protos[SLOT_STRUCTPROTO], protos[SLOT_STRUCTDATAPROTO])) protos[SLOT_STRUCTPROTO], protos[SLOT_STRUCTDATAPROTO]))
return false; return false;
js::AutoValueRooter sroot(cx, protos[SLOT_STRUCTDATAPROTO]); js::AutoObjectRooter sroot(cx, protos[SLOT_STRUCTDATAPROTO]);
if (!InitTypeConstructor(cx, parent, CTypeProto, CDataProto, if (!InitTypeConstructor(cx, parent, CTypeProto, CDataProto,
sFunctionFunction, NULL, sFunctionProps, NULL, NULL, sFunctionFunction, NULL, sFunctionProps, NULL, NULL,
protos[SLOT_FUNCTIONPROTO], protos[SLOT_FUNCTIONDATAPROTO])) protos[SLOT_FUNCTIONPROTO], protos[SLOT_FUNCTIONDATAPROTO]))
return false; return false;
js::AutoValueRooter froot(cx, protos[SLOT_FUNCTIONDATAPROTO]); js::AutoObjectRooter froot(cx, protos[SLOT_FUNCTIONDATAPROTO]);
protos[SLOT_CDATAPROTO] = CDataProto; protos[SLOT_CDATAPROTO] = CDataProto;
@ -1106,7 +1106,7 @@ jsvalToBool(JSContext* cx, jsval val, bool* result)
return i == 0 || i == 1; return i == 0 || i == 1;
} }
if (JSVAL_IS_DOUBLE(val)) { if (JSVAL_IS_DOUBLE(val)) {
jsdouble d = *JSVAL_TO_DOUBLE(val); jsdouble d = JSVAL_TO_DOUBLE(val);
*result = d != 0; *result = d != 0;
// Allow -0. // Allow -0.
return d == 1 || d == 0; return d == 1 || d == 0;
@ -1133,7 +1133,7 @@ jsvalToInteger(JSContext* cx, jsval val, IntegerType* result)
if (JSVAL_IS_DOUBLE(val)) { if (JSVAL_IS_DOUBLE(val)) {
// Don't silently lose bits here -- check that val really is an // Don't silently lose bits here -- check that val really is an
// integer value, and has the right sign. // integer value, and has the right sign.
jsdouble d = *JSVAL_TO_DOUBLE(val); jsdouble d = JSVAL_TO_DOUBLE(val);
return ConvertExact(d, result); return ConvertExact(d, result);
} }
if (!JSVAL_IS_PRIMITIVE(val)) { if (!JSVAL_IS_PRIMITIVE(val)) {
@ -1214,7 +1214,7 @@ jsvalToFloat(JSContext *cx, jsval val, FloatType* result)
return true; return true;
} }
if (JSVAL_IS_DOUBLE(val)) { if (JSVAL_IS_DOUBLE(val)) {
*result = FloatType(*JSVAL_TO_DOUBLE(val)); *result = FloatType(JSVAL_TO_DOUBLE(val));
return true; return true;
} }
if (!JSVAL_IS_PRIMITIVE(val)) { if (!JSVAL_IS_PRIMITIVE(val)) {
@ -1276,7 +1276,7 @@ jsvalToBigInteger(JSContext* cx,
if (JSVAL_IS_DOUBLE(val)) { if (JSVAL_IS_DOUBLE(val)) {
// Don't silently lose bits here -- check that val really is an // Don't silently lose bits here -- check that val really is an
// integer value, and has the right sign. // integer value, and has the right sign.
jsdouble d = *JSVAL_TO_DOUBLE(val); jsdouble d = JSVAL_TO_DOUBLE(val);
return ConvertExact(d, result); return ConvertExact(d, result);
} }
if (allowString && JSVAL_IS_STRING(val)) { if (allowString && JSVAL_IS_STRING(val)) {
@ -1317,6 +1317,62 @@ jsvalToSize(JSContext* cx, jsval val, bool allowString, size_t* result)
return Convert<size_t>(jsdouble(*result)) == *result; return Convert<size_t>(jsdouble(*result)) == *result;
} }
// Implicitly convert val to IntegerType, allowing jsint, jsdouble,
// Int64, UInt64, and optionally a decimal or hexadecimal string argument.
// (This is common code shared by jsvalToSize and the Int64/UInt64 constructors.)
template<class IntegerType>
static bool
jsidToBigInteger(JSContext* cx,
jsid val,
bool allowString,
IntegerType* result)
{
JS_STATIC_ASSERT(numeric_limits<IntegerType>::is_exact);
if (JSID_IS_INT(val)) {
// Make sure the integer fits in the alotted precision, and has the right
// sign.
jsint i = JSID_TO_INT(val);
return ConvertExact(i, result);
}
if (allowString && JSID_IS_STRING(val)) {
// Allow conversion from base-10 or base-16 strings, provided the result
// fits in IntegerType. (This allows an Int64 or UInt64 object to be passed
// to the JS array element operator, which will automatically call
// toString() on the object for us.)
return StringToInteger(cx, JSID_TO_STRING(val), result);
}
if (JSID_IS_OBJECT(val)) {
// Allow conversion from an Int64 or UInt64 object directly.
JSObject* obj = JSID_TO_OBJECT(val);
if (UInt64::IsUInt64(cx, obj)) {
// Make sure the integer fits in IntegerType.
JSUint64 i = Int64Base::GetInt(cx, obj);
return ConvertExact(i, result);
}
if (Int64::IsInt64(cx, obj)) {
// Make sure the integer fits in IntegerType.
JSInt64 i = Int64Base::GetInt(cx, obj);
return ConvertExact(i, result);
}
}
return false;
}
// Implicitly convert val to a size value, where the size value is represented
// by size_t but must also fit in a jsdouble.
static bool
jsidToSize(JSContext* cx, jsid val, bool allowString, size_t* result)
{
if (!jsidToBigInteger(cx, val, allowString, result))
return false;
// Also check that the result fits in a jsdouble.
return Convert<size_t>(jsdouble(*result)) == *result;
}
// Implicitly convert a size value to a jsval, ensuring that the size_t value // Implicitly convert a size value to a jsval, ensuring that the size_t value
// fits in a jsdouble. // fits in a jsdouble.
static JSBool static JSBool
@ -1339,7 +1395,7 @@ jsvalToIntegerExplicit(JSContext* cx, jsval val, IntegerType* result)
if (JSVAL_IS_DOUBLE(val)) { if (JSVAL_IS_DOUBLE(val)) {
// Convert -Inf, Inf, and NaN to 0; otherwise, convert by C-style cast. // Convert -Inf, Inf, and NaN to 0; otherwise, convert by C-style cast.
jsdouble d = *JSVAL_TO_DOUBLE(val); jsdouble d = JSVAL_TO_DOUBLE(val);
*result = FloatIsFinite(d) ? IntegerType(d) : 0; *result = FloatIsFinite(d) ? IntegerType(d) : 0;
return true; return true;
} }
@ -1372,7 +1428,7 @@ jsvalToPtrExplicit(JSContext* cx, jsval val, uintptr_t* result)
return true; return true;
} }
if (JSVAL_IS_DOUBLE(val)) { if (JSVAL_IS_DOUBLE(val)) {
jsdouble d = *JSVAL_TO_DOUBLE(val); jsdouble d = JSVAL_TO_DOUBLE(val);
if (d < 0) { if (d < 0) {
// Cast through an intptr_t intermediate to sign-extend. // Cast through an intptr_t intermediate to sign-extend.
intptr_t i = Convert<intptr_t>(d); intptr_t i = Convert<intptr_t>(d);
@ -1859,11 +1915,11 @@ ImplicitConvert(JSContext* cx,
for (jsuint i = 0; i < sourceLength; ++i) { for (jsuint i = 0; i < sourceLength; ++i) {
js::AutoValueRooter item(cx); js::AutoValueRooter item(cx);
if (!JS_GetElement(cx, sourceArray, i, item.addr())) if (!JS_GetElement(cx, sourceArray, i, item.jsval_addr()))
return false; return false;
char* data = intermediate.get() + elementSize * i; char* data = intermediate.get() + elementSize * i;
if (!ImplicitConvert(cx, item.value(), baseType, data, false, NULL)) if (!ImplicitConvert(cx, item.jsval_value(), baseType, data, false, NULL))
return false; return false;
} }
@ -1884,7 +1940,7 @@ ImplicitConvert(JSContext* cx,
JSObject* iter = JS_NewPropertyIterator(cx, obj); JSObject* iter = JS_NewPropertyIterator(cx, obj);
if (!iter) if (!iter)
return false; return false;
js::AutoValueRooter iterroot(cx, iter); js::AutoObjectRooter iterroot(cx, iter);
// Convert into an intermediate, in case of failure. // Convert into an intermediate, in case of failure.
size_t structSize = CType::GetSize(cx, targetType); size_t structSize = CType::GetSize(cx, targetType);
@ -1899,30 +1955,29 @@ ImplicitConvert(JSContext* cx,
while (1) { while (1) {
if (!JS_NextProperty(cx, iter, &id)) if (!JS_NextProperty(cx, iter, &id))
return false; return false;
if (JSVAL_IS_VOID(id)) if (JSID_IS_VOID(id))
break; break;
js::AutoValueRooter fieldVal(cx); js::AutoValueRooter fieldVal(cx);
if (!JS_IdToValue(cx, id, fieldVal.addr())) JS_IdToValue(cx, id, fieldVal.jsval_addr());
return false; if (!JSVAL_IS_STRING(fieldVal.jsval_value())) {
if (!JSVAL_IS_STRING(fieldVal.value())) {
JS_ReportError(cx, "property name is not a string"); JS_ReportError(cx, "property name is not a string");
return false; return false;
} }
const FieldInfo* field = StructType::LookupField(cx, targetType, const FieldInfo* field = StructType::LookupField(cx, targetType,
fieldVal.value()); JSVAL_TO_STRING(fieldVal.jsval_value()));
if (!field) if (!field)
return false; return false;
JSString* name = JSVAL_TO_STRING(fieldVal.value()); JSString* name = JSVAL_TO_STRING(fieldVal.jsval_value());
js::AutoValueRooter prop(cx); js::AutoValueRooter prop(cx);
if (!JS_GetUCProperty(cx, obj, name->chars(), name->length(), prop.addr())) if (!JS_GetUCProperty(cx, obj, name->chars(), name->length(), prop.jsval_addr()))
return false; return false;
// Convert the field via ImplicitConvert(). // Convert the field via ImplicitConvert().
char* fieldData = intermediate.get() + field->mOffset; char* fieldData = intermediate.get() + field->mOffset;
if (!ImplicitConvert(cx, prop.value(), field->mType, fieldData, false, NULL)) if (!ImplicitConvert(cx, prop.jsval_value(), field->mType, fieldData, false, NULL))
return false; return false;
++i; ++i;
@ -1963,7 +2018,7 @@ ExplicitConvert(JSContext* cx, jsval val, JSObject* targetType, void* buffer)
// hard failure (out of memory, or some other similarly serious condition). // hard failure (out of memory, or some other similarly serious condition).
// We store any pending exception in case we need to re-throw it. // We store any pending exception in case we need to re-throw it.
js::AutoValueRooter ex(cx); js::AutoValueRooter ex(cx);
if (!JS_GetPendingException(cx, ex.addr())) if (!JS_GetPendingException(cx, ex.jsval_addr()))
return false; return false;
// Otherwise, assume soft failure. Clear the pending exception so that we // Otherwise, assume soft failure. Clear the pending exception so that we
@ -2011,7 +2066,7 @@ ExplicitConvert(JSContext* cx, jsval val, JSObject* targetType, void* buffer)
case TYPE_array: case TYPE_array:
case TYPE_struct: case TYPE_struct:
// ImplicitConvert is sufficient. Re-throw the exception it generated. // ImplicitConvert is sufficient. Re-throw the exception it generated.
JS_SetPendingException(cx, ex.value()); JS_SetPendingException(cx, ex.jsval_value());
return false; return false;
case TYPE_void_t: case TYPE_void_t:
case TYPE_function: case TYPE_function:
@ -2529,7 +2584,7 @@ CType::Create(JSContext* cx,
JSObject* typeObj = JS_NewObject(cx, &sCTypeClass, typeProto, parent); JSObject* typeObj = JS_NewObject(cx, &sCTypeClass, typeProto, parent);
if (!typeObj) if (!typeObj)
return NULL; return NULL;
js::AutoValueRooter root(cx, typeObj); js::AutoObjectRooter root(cx, typeObj);
// Set up the reserved slots. // Set up the reserved slots.
if (!JS_SetReservedSlot(cx, typeObj, SLOT_TYPECODE, INT_TO_JSVAL(type)) || if (!JS_SetReservedSlot(cx, typeObj, SLOT_TYPECODE, INT_TO_JSVAL(type)) ||
@ -2544,7 +2599,7 @@ CType::Create(JSContext* cx,
JSObject* prototype = JS_NewObject(cx, &sCDataProtoClass, dataProto, parent); JSObject* prototype = JS_NewObject(cx, &sCDataProtoClass, dataProto, parent);
if (!prototype) if (!prototype)
return NULL; return NULL;
js::AutoValueRooter protoroot(cx, prototype); js::AutoObjectRooter protoroot(cx, prototype);
if (!JS_DefineProperty(cx, prototype, "constructor", OBJECT_TO_JSVAL(typeObj), if (!JS_DefineProperty(cx, prototype, "constructor", OBJECT_TO_JSVAL(typeObj),
NULL, NULL, JSPROP_READONLY | JSPROP_PERMANENT)) NULL, NULL, JSPROP_READONLY | JSPROP_PERMANENT))
@ -2582,7 +2637,7 @@ CType::DefineBuiltin(JSContext* cx,
JSString* nameStr = JS_NewStringCopyZ(cx, name); JSString* nameStr = JS_NewStringCopyZ(cx, name);
if (!nameStr) if (!nameStr)
return NULL; return NULL;
js::AutoValueRooter nameRoot(cx, nameStr); js::AutoStringRooter nameRoot(cx, nameStr);
// Create a new CType object with the common properties and slots. // Create a new CType object with the common properties and slots.
JSObject* typeObj = Create(cx, typeProto, dataProto, type, nameStr, size, JSObject* typeObj = Create(cx, typeProto, dataProto, type, nameStr, size,
@ -2808,7 +2863,7 @@ CType::GetSafeSize(JSContext* cx, JSObject* obj, size_t* result)
return true; return true;
} }
if (JSVAL_IS_DOUBLE(size)) { if (JSVAL_IS_DOUBLE(size)) {
*result = Convert<size_t>(*JSVAL_TO_DOUBLE(size)); *result = Convert<size_t>(JSVAL_TO_DOUBLE(size));
return true; return true;
} }
@ -2831,7 +2886,7 @@ CType::GetSize(JSContext* cx, JSObject* obj)
// For callers who know it can never be JSVAL_VOID, return a size_t directly. // For callers who know it can never be JSVAL_VOID, return a size_t directly.
if (JSVAL_IS_INT(size)) if (JSVAL_IS_INT(size))
return JSVAL_TO_INT(size); return JSVAL_TO_INT(size);
return Convert<size_t>(*JSVAL_TO_DOUBLE(size)); return Convert<size_t>(JSVAL_TO_DOUBLE(size));
} }
bool bool
@ -2944,7 +2999,7 @@ CType::GetProtoFromType(JSContext* cx, JSObject* obj, CTypeProtoSlot slot)
} }
JSBool JSBool
CType::PrototypeGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp) CType::PrototypeGetter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
{ {
if (!CType::IsCType(cx, obj)) { if (!CType::IsCType(cx, obj)) {
JS_ReportError(cx, "not a CType"); JS_ReportError(cx, "not a CType");
@ -2957,7 +3012,7 @@ CType::PrototypeGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp)
} }
JSBool JSBool
CType::NameGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp) CType::NameGetter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
{ {
if (!CType::IsCType(cx, obj)) { if (!CType::IsCType(cx, obj)) {
JS_ReportError(cx, "not a CType"); JS_ReportError(cx, "not a CType");
@ -2973,7 +3028,7 @@ CType::NameGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp)
} }
JSBool JSBool
CType::SizeGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp) CType::SizeGetter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
{ {
if (!CType::IsCType(cx, obj)) { if (!CType::IsCType(cx, obj)) {
JS_ReportError(cx, "not a CType"); JS_ReportError(cx, "not a CType");
@ -2986,7 +3041,7 @@ CType::SizeGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp)
} }
JSBool JSBool
CType::PtrGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp) CType::PtrGetter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
{ {
if (!CType::IsCType(cx, obj)) { if (!CType::IsCType(cx, obj)) {
JS_ReportError(cx, "not a CType"); JS_ReportError(cx, "not a CType");
@ -3079,7 +3134,7 @@ CType::ToSource(JSContext* cx, uintN argc, jsval *vp)
} }
JSBool JSBool
CType::HasInstance(JSContext* cx, JSObject* obj, jsval v, JSBool* bp) CType::HasInstance(JSContext* cx, JSObject* obj, const jsval *v, JSBool* bp)
{ {
JS_ASSERT(CType::IsCType(cx, obj)); JS_ASSERT(CType::IsCType(cx, obj));
@ -3090,10 +3145,10 @@ CType::HasInstance(JSContext* cx, JSObject* obj, jsval v, JSBool* bp)
JS_ASSERT(JS_GET_CLASS(cx, prototype) == &sCDataProtoClass); JS_ASSERT(JS_GET_CLASS(cx, prototype) == &sCDataProtoClass);
*bp = JS_FALSE; *bp = JS_FALSE;
if (JSVAL_IS_PRIMITIVE(v)) if (JSVAL_IS_PRIMITIVE(*v))
return JS_TRUE; return JS_TRUE;
JSObject* proto = JSVAL_TO_OBJECT(v); JSObject* proto = JSVAL_TO_OBJECT(*v);
while ((proto = JS_GetPrototype(cx, proto))) { while ((proto = JS_GetPrototype(cx, proto))) {
if (proto == prototype) { if (proto == prototype) {
*bp = JS_TRUE; *bp = JS_TRUE;
@ -3153,7 +3208,7 @@ PointerType::CreateInternal(JSContext* cx, JSObject* baseType)
&ffi_type_pointer); &ffi_type_pointer);
if (!typeObj) if (!typeObj)
return NULL; return NULL;
js::AutoValueRooter root(cx, typeObj); js::AutoObjectRooter root(cx, typeObj);
// Set the target type. (This will be 'null' for an opaque pointer type.) // Set the target type. (This will be 'null' for an opaque pointer type.)
if (!JS_SetReservedSlot(cx, typeObj, SLOT_TARGET_T, OBJECT_TO_JSVAL(baseType))) if (!JS_SetReservedSlot(cx, typeObj, SLOT_TARGET_T, OBJECT_TO_JSVAL(baseType)))
@ -3238,7 +3293,7 @@ PointerType::GetBaseType(JSContext* cx, JSObject* obj)
JSBool JSBool
PointerType::TargetTypeGetter(JSContext* cx, PointerType::TargetTypeGetter(JSContext* cx,
JSObject* obj, JSObject* obj,
jsval idval, jsid idval,
jsval* vp) jsval* vp)
{ {
if (!CType::IsCType(cx, obj) || CType::GetTypeCode(cx, obj) != TYPE_pointer) { if (!CType::IsCType(cx, obj) || CType::GetTypeCode(cx, obj) != TYPE_pointer) {
@ -3278,7 +3333,7 @@ PointerType::IsNull(JSContext* cx, uintN argc, jsval* vp)
JSBool JSBool
PointerType::ContentsGetter(JSContext* cx, PointerType::ContentsGetter(JSContext* cx,
JSObject* obj, JSObject* obj,
jsval idval, jsid idval,
jsval* vp) jsval* vp)
{ {
if (!CData::IsCData(cx, obj)) { if (!CData::IsCData(cx, obj)) {
@ -3316,7 +3371,7 @@ PointerType::ContentsGetter(JSContext* cx,
JSBool JSBool
PointerType::ContentsSetter(JSContext* cx, PointerType::ContentsSetter(JSContext* cx,
JSObject* obj, JSObject* obj,
jsval idval, jsid idval,
jsval* vp) jsval* vp)
{ {
if (!CData::IsCData(cx, obj)) { if (!CData::IsCData(cx, obj)) {
@ -3423,7 +3478,7 @@ ArrayType::CreateInternal(JSContext* cx,
sizeVal, INT_TO_JSVAL(align), NULL); sizeVal, INT_TO_JSVAL(align), NULL);
if (!typeObj) if (!typeObj)
return NULL; return NULL;
js::AutoValueRooter root(cx, typeObj); js::AutoObjectRooter root(cx, typeObj);
// Set the element type. // Set the element type.
if (!JS_SetReservedSlot(cx, typeObj, SLOT_ELEMENT_T, OBJECT_TO_JSVAL(baseType))) if (!JS_SetReservedSlot(cx, typeObj, SLOT_ELEMENT_T, OBJECT_TO_JSVAL(baseType)))
@ -3478,8 +3533,8 @@ ArrayType::ConstructData(JSContext* cx,
// This could be a JS array, or a CData array. // This could be a JS array, or a CData array.
JSObject* arg = JSVAL_TO_OBJECT(argv[0]); JSObject* arg = JSVAL_TO_OBJECT(argv[0]);
js::AutoValueRooter lengthVal(cx); js::AutoValueRooter lengthVal(cx);
if (!JS_GetProperty(cx, arg, "length", lengthVal.addr()) || if (!JS_GetProperty(cx, arg, "length", lengthVal.jsval_addr()) ||
!jsvalToSize(cx, lengthVal.value(), false, &length)) { !jsvalToSize(cx, lengthVal.jsval_value(), false, &length)) {
JS_ReportError(cx, "argument must be an array object or length"); JS_ReportError(cx, "argument must be an array object or length");
return JS_FALSE; return JS_FALSE;
} }
@ -3522,7 +3577,7 @@ ArrayType::ConstructData(JSContext* cx,
} }
// Root the CType object, in case we created one above. // Root the CType object, in case we created one above.
js::AutoValueRooter root(cx, obj); js::AutoObjectRooter root(cx, obj);
JSObject* result = CData::Create(cx, obj, NULL, NULL, true); JSObject* result = CData::Create(cx, obj, NULL, NULL, true);
if (!result) if (!result)
@ -3566,7 +3621,7 @@ ArrayType::GetSafeLength(JSContext* cx, JSObject* obj, size_t* result)
return true; return true;
} }
if (JSVAL_IS_DOUBLE(length)) { if (JSVAL_IS_DOUBLE(length)) {
*result = Convert<size_t>(*JSVAL_TO_DOUBLE(length)); *result = Convert<size_t>(JSVAL_TO_DOUBLE(length));
return true; return true;
} }
@ -3590,7 +3645,7 @@ ArrayType::GetLength(JSContext* cx, JSObject* obj)
// For callers who know it can never be JSVAL_VOID, return a size_t directly. // For callers who know it can never be JSVAL_VOID, return a size_t directly.
if (JSVAL_IS_INT(length)) if (JSVAL_IS_INT(length))
return JSVAL_TO_INT(length); return JSVAL_TO_INT(length);
return Convert<size_t>(*JSVAL_TO_DOUBLE(length)); return Convert<size_t>(JSVAL_TO_DOUBLE(length));
} }
ffi_type* ffi_type*
@ -3637,7 +3692,7 @@ ArrayType::BuildFFIType(JSContext* cx, JSObject* obj)
} }
JSBool JSBool
ArrayType::ElementTypeGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp) ArrayType::ElementTypeGetter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
{ {
if (!CType::IsCType(cx, obj) || CType::GetTypeCode(cx, obj) != TYPE_array) { if (!CType::IsCType(cx, obj) || CType::GetTypeCode(cx, obj) != TYPE_array) {
JS_ReportError(cx, "not an ArrayType"); JS_ReportError(cx, "not an ArrayType");
@ -3650,7 +3705,7 @@ ArrayType::ElementTypeGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* v
} }
JSBool JSBool
ArrayType::LengthGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp) ArrayType::LengthGetter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
{ {
// This getter exists for both CTypes and CDatas of the ArrayType persuasion. // This getter exists for both CTypes and CDatas of the ArrayType persuasion.
// If we're dealing with a CData, get the CType from it. // If we're dealing with a CData, get the CType from it.
@ -3668,7 +3723,7 @@ ArrayType::LengthGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp)
} }
JSBool JSBool
ArrayType::Getter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp) ArrayType::Getter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
{ {
// This should never happen, but we'll check to be safe. // This should never happen, but we'll check to be safe.
if (!CData::IsCData(cx, obj)) { if (!CData::IsCData(cx, obj)) {
@ -3685,8 +3740,8 @@ ArrayType::Getter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp)
// Convert the index to a size_t and bounds-check it. // Convert the index to a size_t and bounds-check it.
size_t index; size_t index;
size_t length = GetLength(cx, typeObj); size_t length = GetLength(cx, typeObj);
bool ok = jsvalToSize(cx, idval, true, &index); bool ok = jsidToSize(cx, idval, true, &index);
if (!ok && JSVAL_IS_STRING(idval)) { if (!ok && JSID_IS_STRING(idval)) {
// String either isn't a number, or doesn't fit in size_t. // String either isn't a number, or doesn't fit in size_t.
// Chances are it's a regular property lookup, so return. // Chances are it's a regular property lookup, so return.
return JS_TRUE; return JS_TRUE;
@ -3703,7 +3758,7 @@ ArrayType::Getter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp)
} }
JSBool JSBool
ArrayType::Setter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp) ArrayType::Setter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
{ {
// This should never happen, but we'll check to be safe. // This should never happen, but we'll check to be safe.
if (!CData::IsCData(cx, obj)) { if (!CData::IsCData(cx, obj)) {
@ -3720,8 +3775,8 @@ ArrayType::Setter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp)
// Convert the index to a size_t and bounds-check it. // Convert the index to a size_t and bounds-check it.
size_t index; size_t index;
size_t length = GetLength(cx, typeObj); size_t length = GetLength(cx, typeObj);
bool ok = jsvalToSize(cx, idval, true, &index); bool ok = jsidToSize(cx, idval, true, &index);
if (!ok && JSVAL_IS_STRING(idval)) { if (!ok && JSID_IS_STRING(idval)) {
// String either isn't a number, or doesn't fit in size_t. // String either isn't a number, or doesn't fit in size_t.
// Chances are it's a regular property lookup, so return. // Chances are it's a regular property lookup, so return.
return JS_TRUE; return JS_TRUE;
@ -3763,7 +3818,7 @@ ArrayType::AddressOfElement(JSContext* cx, uintN argc, jsval *vp)
JSObject* pointerType = PointerType::CreateInternal(cx, baseType); JSObject* pointerType = PointerType::CreateInternal(cx, baseType);
if (!pointerType) if (!pointerType)
return JS_FALSE; return JS_FALSE;
js::AutoValueRooter root(cx, pointerType); js::AutoObjectRooter root(cx, pointerType);
// Create a PointerType CData object containing null. // Create a PointerType CData object containing null.
JSObject* result = CData::Create(cx, pointerType, NULL, NULL, true); JSObject* result = CData::Create(cx, pointerType, NULL, NULL, true);
@ -3806,35 +3861,38 @@ ExtractStructField(JSContext* cx, jsval val, JSObject** typeObj)
JSObject* iter = JS_NewPropertyIterator(cx, obj); JSObject* iter = JS_NewPropertyIterator(cx, obj);
if (!iter) if (!iter)
return NULL; return NULL;
js::AutoValueRooter iterroot(cx, iter); js::AutoObjectRooter iterroot(cx, iter);
jsid id; jsid id;
if (!JS_NextProperty(cx, iter, &id)) if (!JS_NextProperty(cx, iter, &id))
return NULL; return NULL;
if (JSID_IS_VOID(id)) {
js::AutoValueRooter nameVal(cx);
if (!JS_IdToValue(cx, id, nameVal.addr()))
return NULL;
if (!JSVAL_IS_STRING(nameVal.value())) {
JS_ReportError(cx, "struct field descriptors require a valid name and type"); JS_ReportError(cx, "struct field descriptors require a valid name and type");
return NULL; return NULL;
} }
JSString* name = JSVAL_TO_STRING(nameVal.value());
js::AutoValueRooter nameVal(cx);
JS_IdToValue(cx, id, nameVal.jsval_addr());
if (!JSVAL_IS_STRING(nameVal.jsval_value())) {
JS_ReportError(cx, "struct field descriptors require a valid name and type");
return NULL;
}
JSString* name = JSVAL_TO_STRING(nameVal.jsval_value());
// make sure we have one, and only one, property // make sure we have one, and only one, property
if (!JS_NextProperty(cx, iter, &id)) if (!JS_NextProperty(cx, iter, &id))
return NULL; return NULL;
if (!JSVAL_IS_VOID(id)) { if (!JSID_IS_VOID(id)) {
JS_ReportError(cx, "struct field descriptors must contain one property"); JS_ReportError(cx, "struct field descriptors must contain one property");
return NULL; return NULL;
} }
js::AutoValueRooter propVal(cx); js::AutoValueRooter propVal(cx);
if (!JS_GetUCProperty(cx, obj, name->chars(), name->length(), propVal.addr())) if (!JS_GetUCProperty(cx, obj, name->chars(), name->length(), propVal.jsval_addr()))
return NULL; return NULL;
if (JSVAL_IS_PRIMITIVE(propVal.value()) || if (propVal.value().isPrimitive() ||
!CType::IsCType(cx, JSVAL_TO_OBJECT(propVal.value()))) { !CType::IsCType(cx, JSVAL_TO_OBJECT(propVal.jsval_value()))) {
JS_ReportError(cx, "struct field descriptors require a valid name and type"); JS_ReportError(cx, "struct field descriptors require a valid name and type");
return NULL; return NULL;
} }
@ -3842,7 +3900,7 @@ ExtractStructField(JSContext* cx, jsval val, JSObject** typeObj)
// Undefined size or zero size struct members are illegal. // Undefined size or zero size struct members are illegal.
// (Zero-size arrays are legal as struct members in C++, but libffi will // (Zero-size arrays are legal as struct members in C++, but libffi will
// choke on a zero-size struct, so we disallow them.) // choke on a zero-size struct, so we disallow them.)
*typeObj = JSVAL_TO_OBJECT(propVal.value()); *typeObj = JSVAL_TO_OBJECT(propVal.jsval_value());
size_t size; size_t size;
if (!CType::GetSafeSize(cx, *typeObj, &size) || size == 0) { if (!CType::GetSafeSize(cx, *typeObj, &size) || size == 0) {
JS_ReportError(cx, "struct field types must have defined and nonzero size"); JS_ReportError(cx, "struct field types must have defined and nonzero size");
@ -3903,7 +3961,7 @@ StructType::Create(JSContext* cx, uintN argc, jsval* vp)
JSVAL_TO_STRING(name), JSVAL_VOID, JSVAL_VOID, NULL); JSVAL_TO_STRING(name), JSVAL_VOID, JSVAL_VOID, NULL);
if (!result) if (!result)
return JS_FALSE; return JS_FALSE;
js::AutoValueRooter root(cx, result); js::AutoObjectRooter root(cx, result);
if (argc == 2) { if (argc == 2) {
if (JSVAL_IS_PRIMITIVE(argv[1]) || if (JSVAL_IS_PRIMITIVE(argv[1]) ||
@ -3938,7 +3996,7 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj, JSObject* fieldsObj
JSObject* prototype = JS_NewObject(cx, &sCDataProtoClass, dataProto, NULL); JSObject* prototype = JS_NewObject(cx, &sCDataProtoClass, dataProto, NULL);
if (!prototype) if (!prototype)
return JS_FALSE; return JS_FALSE;
js::AutoValueRooter protoroot(cx, prototype); js::AutoObjectRooter protoroot(cx, prototype);
if (!JS_DefineProperty(cx, prototype, "constructor", OBJECT_TO_JSVAL(typeObj), if (!JS_DefineProperty(cx, prototype, "constructor", OBJECT_TO_JSVAL(typeObj),
NULL, NULL, JSPROP_READONLY | JSPROP_PERMANENT)) NULL, NULL, JSPROP_READONLY | JSPROP_PERMANENT))
@ -3968,11 +4026,11 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj, JSObject* fieldsObj
for (jsuint i = 0; i < len; ++i) { for (jsuint i = 0; i < len; ++i) {
js::AutoValueRooter item(cx); js::AutoValueRooter item(cx);
if (!JS_GetElement(cx, fieldsObj, i, item.addr())) if (!JS_GetElement(cx, fieldsObj, i, item.jsval_addr()))
return JS_FALSE; return JS_FALSE;
JSObject* fieldType; JSObject* fieldType;
JSString* name = ExtractStructField(cx, item.value(), &fieldType); JSString* name = ExtractStructField(cx, item.jsval_value(), &fieldType);
if (!name) if (!name)
return JS_FALSE; return JS_FALSE;
@ -4238,12 +4296,11 @@ StructType::GetFieldInfo(JSContext* cx, JSObject* obj)
} }
const FieldInfo* const FieldInfo*
StructType::LookupField(JSContext* cx, JSObject* obj, jsval idval) StructType::LookupField(JSContext* cx, JSObject* obj, JSString *name)
{ {
JS_ASSERT(CType::IsCType(cx, obj)); JS_ASSERT(CType::IsCType(cx, obj));
JS_ASSERT(CType::GetTypeCode(cx, obj) == TYPE_struct); JS_ASSERT(CType::GetTypeCode(cx, obj) == TYPE_struct);
JSString* name = JSVAL_TO_STRING(idval);
FieldInfoHash::Ptr ptr = GetFieldInfo(cx, obj)->lookup(name); FieldInfoHash::Ptr ptr = GetFieldInfo(cx, obj)->lookup(name);
if (ptr) if (ptr)
return &ptr->value; return &ptr->value;
@ -4272,7 +4329,7 @@ StructType::BuildFieldsArray(JSContext* cx, JSObject* obj)
js_NewArrayObjectWithCapacity(cx, len, &fieldsVec); js_NewArrayObjectWithCapacity(cx, len, &fieldsVec);
if (!fieldsProp) if (!fieldsProp)
return NULL; return NULL;
js::AutoValueRooter root(cx, fieldsProp); js::AutoObjectRooter root(cx, fieldsProp);
JS_ASSERT(len == 0 || fieldsVec); JS_ASSERT(len == 0 || fieldsVec);
for (FieldInfoHash::Range r = fields->all(); !r.empty(); r.popFront()) { for (FieldInfoHash::Range r = fields->all(); !r.empty(); r.popFront()) {
@ -4291,7 +4348,7 @@ StructType::BuildFieldsArray(JSContext* cx, JSObject* obj)
} }
JSBool JSBool
StructType::FieldsArrayGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp) StructType::FieldsArrayGetter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
{ {
if (!CType::IsCType(cx, obj) || CType::GetTypeCode(cx, obj) != TYPE_struct) { if (!CType::IsCType(cx, obj) || CType::GetTypeCode(cx, obj) != TYPE_struct) {
JS_ReportError(cx, "not a StructType"); JS_ReportError(cx, "not a StructType");
@ -4321,7 +4378,7 @@ StructType::FieldsArrayGetter(JSContext* cx, JSObject* obj, jsval idval, jsval*
} }
JSBool JSBool
StructType::FieldGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp) StructType::FieldGetter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
{ {
if (!CData::IsCData(cx, obj)) { if (!CData::IsCData(cx, obj)) {
JS_ReportError(cx, "not a CData"); JS_ReportError(cx, "not a CData");
@ -4334,7 +4391,7 @@ StructType::FieldGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp)
return JS_FALSE; return JS_FALSE;
} }
const FieldInfo* field = LookupField(cx, typeObj, idval); const FieldInfo* field = LookupField(cx, typeObj, JSID_TO_STRING(idval));
if (!field) if (!field)
return JS_FALSE; return JS_FALSE;
@ -4343,7 +4400,7 @@ StructType::FieldGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp)
} }
JSBool JSBool
StructType::FieldSetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp) StructType::FieldSetter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
{ {
if (!CData::IsCData(cx, obj)) { if (!CData::IsCData(cx, obj)) {
JS_ReportError(cx, "not a CData"); JS_ReportError(cx, "not a CData");
@ -4356,7 +4413,7 @@ StructType::FieldSetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp)
return JS_FALSE; return JS_FALSE;
} }
const FieldInfo* field = LookupField(cx, typeObj, idval); const FieldInfo* field = LookupField(cx, typeObj, JSID_TO_STRING(idval));
if (!field) if (!field)
return JS_FALSE; return JS_FALSE;
@ -4386,7 +4443,8 @@ StructType::AddressOfField(JSContext* cx, uintN argc, jsval *vp)
return JS_FALSE; return JS_FALSE;
} }
const FieldInfo* field = LookupField(cx, typeObj, JS_ARGV(cx, vp)[0]); const FieldInfo* field = LookupField(cx, typeObj,
JSVAL_TO_STRING(JS_ARGV(cx, vp)[0]));
if (!field) if (!field)
return JS_FALSE; return JS_FALSE;
@ -4394,7 +4452,7 @@ StructType::AddressOfField(JSContext* cx, uintN argc, jsval *vp)
JSObject* pointerType = PointerType::CreateInternal(cx, baseType); JSObject* pointerType = PointerType::CreateInternal(cx, baseType);
if (!pointerType) if (!pointerType)
return JS_FALSE; return JS_FALSE;
js::AutoValueRooter root(cx, pointerType); js::AutoObjectRooter root(cx, pointerType);
// Create a PointerType CData object containing null. // Create a PointerType CData object containing null.
JSObject* result = CData::Create(cx, pointerType, NULL, NULL, true); JSObject* result = CData::Create(cx, pointerType, NULL, NULL, true);
@ -4729,7 +4787,7 @@ FunctionType::CreateInternal(JSContext* cx,
NULL, JSVAL_VOID, JSVAL_VOID, NULL); NULL, JSVAL_VOID, JSVAL_VOID, NULL);
if (!typeObj) if (!typeObj)
return NULL; return NULL;
js::AutoValueRooter root(cx, typeObj); js::AutoObjectRooter root(cx, typeObj);
// Stash the FunctionInfo in a reserved slot. // Stash the FunctionInfo in a reserved slot.
if (!JS_SetReservedSlot(cx, typeObj, SLOT_FNINFO, if (!JS_SetReservedSlot(cx, typeObj, SLOT_FNINFO,
@ -4760,7 +4818,7 @@ FunctionType::ConstructData(JSContext* cx,
JSObject* closureObj = CClosure::Create(cx, typeObj, fnObj, thisObj, data); JSObject* closureObj = CClosure::Create(cx, typeObj, fnObj, thisObj, data);
if (!closureObj) if (!closureObj)
return JS_FALSE; return JS_FALSE;
js::AutoValueRooter root(cx, closureObj); js::AutoObjectRooter root(cx, closureObj);
// Set the closure object as the referent of the new CData object. // Set the closure object as the referent of the new CData object.
if (!JS_SetReservedSlot(cx, dataObj, SLOT_REFERENT, if (!JS_SetReservedSlot(cx, dataObj, SLOT_REFERENT,
@ -4945,7 +5003,7 @@ CheckFunctionType(JSContext* cx, JSObject* obj)
} }
JSBool JSBool
FunctionType::ArgTypesGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp) FunctionType::ArgTypesGetter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
{ {
if (!CheckFunctionType(cx, obj)) if (!CheckFunctionType(cx, obj))
return JS_FALSE; return JS_FALSE;
@ -4964,7 +5022,7 @@ FunctionType::ArgTypesGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* v
js_NewArrayObjectWithCapacity(cx, len, &vec); js_NewArrayObjectWithCapacity(cx, len, &vec);
if (!argTypes) if (!argTypes)
return JS_FALSE; return JS_FALSE;
js::AutoValueRooter argsroot(cx, argTypes); js::AutoObjectRooter argsroot(cx, argTypes);
JS_ASSERT(len == 0 || vec); JS_ASSERT(len == 0 || vec);
for (size_t i = 0; i < len; ++i) for (size_t i = 0; i < len; ++i)
@ -4980,7 +5038,7 @@ FunctionType::ArgTypesGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* v
} }
JSBool JSBool
FunctionType::ReturnTypeGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp) FunctionType::ReturnTypeGetter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
{ {
if (!CheckFunctionType(cx, obj)) if (!CheckFunctionType(cx, obj))
return JS_FALSE; return JS_FALSE;
@ -4991,7 +5049,7 @@ FunctionType::ReturnTypeGetter(JSContext* cx, JSObject* obj, jsval idval, jsval*
} }
JSBool JSBool
FunctionType::ABIGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp) FunctionType::ABIGetter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
{ {
if (!CheckFunctionType(cx, obj)) if (!CheckFunctionType(cx, obj))
return JS_FALSE; return JS_FALSE;
@ -5002,7 +5060,7 @@ FunctionType::ABIGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp)
} }
JSBool JSBool
FunctionType::IsVariadicGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp) FunctionType::IsVariadicGetter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
{ {
if (!CheckFunctionType(cx, obj)) if (!CheckFunctionType(cx, obj))
return JS_FALSE; return JS_FALSE;
@ -5025,7 +5083,7 @@ CClosure::Create(JSContext* cx,
JSObject* result = JS_NewObject(cx, &sCClosureClass, NULL, NULL); JSObject* result = JS_NewObject(cx, &sCClosureClass, NULL, NULL);
if (!result) if (!result)
return NULL; return NULL;
js::AutoValueRooter root(cx, result); js::AutoObjectRooter root(cx, result);
// Get the FunctionInfo from the FunctionType. // Get the FunctionInfo from the FunctionType.
FunctionInfo* fninfo = FunctionType::GetFunctionInfo(cx, typeObj); FunctionInfo* fninfo = FunctionType::GetFunctionInfo(cx, typeObj);
@ -5125,9 +5183,12 @@ CClosure::Trace(JSTracer* trc, JSObject* obj)
// Identify our objects to the tracer. (There's no need to identify // Identify our objects to the tracer. (There's no need to identify
// 'closureObj', since that's us.) // 'closureObj', since that's us.)
JS_CALL_TRACER(trc, cinfo->typeObj, JSTRACE_OBJECT, "typeObj"); if (cinfo->typeObj)
JS_CALL_TRACER(trc, cinfo->thisObj, JSTRACE_OBJECT, "thisObj"); JS_CALL_OBJECT_TRACER(trc, cinfo->typeObj, "typeObj");
JS_CALL_TRACER(trc, cinfo->jsfnObj, JSTRACE_OBJECT, "jsfnObj"); if (cinfo->thisObj)
JS_CALL_OBJECT_TRACER(trc, cinfo->thisObj, "thisObj");
if (cinfo->jsfnObj)
JS_CALL_OBJECT_TRACER(trc, cinfo->jsfnObj, "jsfnObj");
} }
void void
@ -5177,7 +5238,7 @@ CClosure::ClosureStub(ffi_cif* cif, void* result, void** args, void* userData)
JS_ASSERT(cif == &fninfo->mCIF); JS_ASSERT(cif == &fninfo->mCIF);
// Get a death grip on 'closureObj'. // Get a death grip on 'closureObj'.
js::AutoValueRooter root(cx, cinfo->closureObj); js::AutoObjectRooter root(cx, cinfo->closureObj);
// Set up an array for converted arguments. // Set up an array for converted arguments.
Array<jsval, 16> argv; Array<jsval, 16> argv;
@ -5189,7 +5250,7 @@ CClosure::ClosureStub(ffi_cif* cif, void* result, void** args, void* userData)
for (JSUint32 i = 0; i < cif->nargs; ++i) for (JSUint32 i = 0; i < cif->nargs; ++i)
argv[i] = JSVAL_VOID; argv[i] = JSVAL_VOID;
js::AutoArrayRooter roots(cx, argv.length(), argv.begin()); js::AutoArrayRooter roots(cx, argv.length(), Valueify(argv.begin()));
for (JSUint32 i = 0; i < cif->nargs; ++i) { for (JSUint32 i = 0; i < cif->nargs; ++i) {
// Convert each argument, and have any CData objects created depend on // Convert each argument, and have any CData objects created depend on
// the existing buffers. // the existing buffers.
@ -5263,7 +5324,7 @@ CData::Create(JSContext* cx,
JSObject* dataObj = JS_NewObject(cx, &sCDataClass, proto, parent); JSObject* dataObj = JS_NewObject(cx, &sCDataClass, proto, parent);
if (!dataObj) if (!dataObj)
return NULL; return NULL;
js::AutoValueRooter root(cx, dataObj); js::AutoObjectRooter root(cx, dataObj);
// set the CData's associated type // set the CData's associated type
if (!JS_SetReservedSlot(cx, dataObj, SLOT_CTYPE, OBJECT_TO_JSVAL(typeObj))) if (!JS_SetReservedSlot(cx, dataObj, SLOT_CTYPE, OBJECT_TO_JSVAL(typeObj)))
@ -5369,7 +5430,7 @@ CData::IsCData(JSContext* cx, JSObject* obj)
} }
JSBool JSBool
CData::ValueGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp) CData::ValueGetter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
{ {
if (!IsCData(cx, obj)) { if (!IsCData(cx, obj)) {
JS_ReportError(cx, "not a CData"); JS_ReportError(cx, "not a CData");
@ -5384,7 +5445,7 @@ CData::ValueGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp)
} }
JSBool JSBool
CData::ValueSetter(JSContext* cx, JSObject* obj, jsval idval, jsval* vp) CData::ValueSetter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
{ {
if (!IsCData(cx, obj)) { if (!IsCData(cx, obj)) {
JS_ReportError(cx, "not a CData"); JS_ReportError(cx, "not a CData");
@ -5414,7 +5475,7 @@ CData::Address(JSContext* cx, uintN argc, jsval *vp)
JSObject* pointerType = PointerType::CreateInternal(cx, typeObj); JSObject* pointerType = PointerType::CreateInternal(cx, typeObj);
if (!pointerType) if (!pointerType)
return JS_FALSE; return JS_FALSE;
js::AutoValueRooter root(cx, pointerType); js::AutoObjectRooter root(cx, pointerType);
// Create a PointerType CData object containing null. // Create a PointerType CData object containing null.
JSObject* result = CData::Create(cx, pointerType, NULL, NULL, true); JSObject* result = CData::Create(cx, pointerType, NULL, NULL, true);
@ -5617,7 +5678,7 @@ Int64Base::Construct(JSContext* cx,
JSObject* result = JS_NewObject(cx, clasp, proto, JS_GetParent(cx, proto)); JSObject* result = JS_NewObject(cx, clasp, proto, JS_GetParent(cx, proto));
if (!result) if (!result)
return NULL; return NULL;
js::AutoValueRooter root(cx, result); js::AutoObjectRooter root(cx, result);
// attach the Int64's data // attach the Int64's data
JSUint64* buffer = new JSUint64(data); JSUint64* buffer = new JSUint64(data);

Просмотреть файл

@ -448,7 +448,7 @@ namespace StructType {
JSBool DefineInternal(JSContext* cx, JSObject* typeObj, JSObject* fieldsObj); JSBool DefineInternal(JSContext* cx, JSObject* typeObj, JSObject* fieldsObj);
const FieldInfoHash* GetFieldInfo(JSContext* cx, JSObject* obj); const FieldInfoHash* GetFieldInfo(JSContext* cx, JSObject* obj);
const FieldInfo* LookupField(JSContext* cx, JSObject* obj, jsval idval); const FieldInfo* LookupField(JSContext* cx, JSObject* obj, JSString *name);
JSObject* BuildFieldsArray(JSContext* cx, JSObject* obj); JSObject* BuildFieldsArray(JSContext* cx, JSObject* obj);
ffi_type* BuildFFIType(JSContext* cx, JSObject* obj); ffi_type* BuildFFIType(JSContext* cx, JSObject* obj);
} }

Просмотреть файл

@ -85,7 +85,7 @@ Library::Create(JSContext* cx, jsval aPath)
JSObject* libraryObj = JS_NewObject(cx, &sLibraryClass, NULL, NULL); JSObject* libraryObj = JS_NewObject(cx, &sLibraryClass, NULL, NULL);
if (!libraryObj) if (!libraryObj)
return NULL; return NULL;
js::AutoValueRooter root(cx, libraryObj); js::AutoObjectRooter root(cx, libraryObj);
// initialize the library // initialize the library
if (!JS_SetReservedSlot(cx, libraryObj, SLOT_LIBRARY, PRIVATE_TO_JSVAL(NULL))) if (!JS_SetReservedSlot(cx, libraryObj, SLOT_LIBRARY, PRIVATE_TO_JSVAL(NULL)))
@ -241,7 +241,7 @@ Library::Declare(JSContext* cx, uintN argc, jsval* vp)
return JS_FALSE; return JS_FALSE;
JSObject* typeObj; JSObject* typeObj;
js::AutoValueRooter root(cx); js::AutoObjectRooter root(cx);
bool isFunction = argc > 2; bool isFunction = argc > 2;
if (isFunction) { if (isFunction) {
// Case 1). // Case 1).

Просмотреть файл

@ -9,7 +9,7 @@
int called_test_fn; int called_test_fn;
int called_test_prop_get; int called_test_prop_get;
static JSBool test_prop_get( JSContext *cx, JSObject *obj, jsval idval, jsval *vp ) static JSBool test_prop_get( JSContext *cx, JSObject *obj, jsid id, jsval *vp )
{ {
called_test_prop_get++; called_test_prop_get++;
return JS_TRUE; return JS_TRUE;

Просмотреть файл

@ -4,11 +4,6 @@
BEGIN_TEST(testConservativeGC) BEGIN_TEST(testConservativeGC)
{ {
jsval v1;
EVAL("Math.sqrt(42);", &v1);
CHECK(JSVAL_IS_DOUBLE(v1));
double numCopy = *JSVAL_TO_DOUBLE(v1);
jsval v2; jsval v2;
EVAL("({foo: 'bar'});", &v2); EVAL("({foo: 'bar'});", &v2);
CHECK(JSVAL_IS_OBJECT(v2)); CHECK(JSVAL_IS_OBJECT(v2));
@ -20,11 +15,6 @@ BEGIN_TEST(testConservativeGC)
JSString strCopy = *JSVAL_TO_STRING(v3); JSString strCopy = *JSVAL_TO_STRING(v3);
jsval tmp; jsval tmp;
EVAL("Math.sqrt(41);", &tmp);
CHECK(JSVAL_IS_DOUBLE(tmp));
jsdouble *num2 = JSVAL_TO_DOUBLE(tmp);
jsdouble num2Copy = *num2;
EVAL("({foo2: 'bar2'});", &tmp); EVAL("({foo2: 'bar2'});", &tmp);
CHECK(JSVAL_IS_OBJECT(tmp)); CHECK(JSVAL_IS_OBJECT(tmp));
JSObject *obj2 = JSVAL_TO_OBJECT(tmp); JSObject *obj2 = JSVAL_TO_OBJECT(tmp);
@ -46,11 +36,9 @@ BEGIN_TEST(testConservativeGC)
JS_GC(cx); JS_GC(cx);
CHECK(numCopy == *JSVAL_TO_DOUBLE(v1));
CHECK(!memcmp(&objCopy, JSVAL_TO_OBJECT(v2), sizeof(objCopy))); CHECK(!memcmp(&objCopy, JSVAL_TO_OBJECT(v2), sizeof(objCopy)));
CHECK(!memcmp(&strCopy, JSVAL_TO_STRING(v3), sizeof(strCopy))); CHECK(!memcmp(&strCopy, JSVAL_TO_STRING(v3), sizeof(strCopy)));
CHECK(num2Copy == *num2);
CHECK(!memcmp(&obj2Copy, obj2, sizeof(obj2Copy))); CHECK(!memcmp(&obj2Copy, obj2, sizeof(obj2Copy)));
CHECK(!memcmp(&str2Copy, str2, sizeof(str2Copy))); CHECK(!memcmp(&str2Copy, str2, sizeof(str2Copy)));

Просмотреть файл

@ -23,21 +23,25 @@ BEGIN_TEST(testDefineGetterSetterNonEnumerable)
jsvalRoot vget(cx); jsvalRoot vget(cx);
JSFunction *funGet = JS_NewFunction(cx, native, 0, 0, NULL, "get"); JSFunction *funGet = JS_NewFunction(cx, native, 0, 0, NULL, "get");
CHECK(funGet); CHECK(funGet);
JSObject *funGetObj = JS_GetFunctionObject(funGet);
vget = OBJECT_TO_JSVAL(funGetObj);
jsvalRoot vset(cx); jsvalRoot vset(cx);
JSFunction *funSet = JS_NewFunction(cx, native, 1, 0, NULL, "set"); JSFunction *funSet = JS_NewFunction(cx, native, 1, 0, NULL, "set");
CHECK(funSet); CHECK(funSet);
JSObject *funSetObj = JS_GetFunctionObject(funSet);
vset = OBJECT_TO_JSVAL(funSetObj);
CHECK(JS_DefineProperty(cx, JSVAL_TO_OBJECT(vobj), PROPERTY_NAME, CHECK(JS_DefineProperty(cx, JSVAL_TO_OBJECT(vobj), PROPERTY_NAME,
JSVAL_VOID, JSVAL_VOID,
JS_DATA_TO_FUNC_PTR(JSPropertyOp, jsval(vget)), JS_DATA_TO_FUNC_PTR(JSPropertyOp, funGetObj),
JS_DATA_TO_FUNC_PTR(JSPropertyOp, jsval(vset)), JS_DATA_TO_FUNC_PTR(JSPropertyOp, funSetObj),
JSPROP_GETTER | JSPROP_SETTER | JSPROP_ENUMERATE)); JSPROP_GETTER | JSPROP_SETTER | JSPROP_ENUMERATE));
CHECK(JS_DefineProperty(cx, JSVAL_TO_OBJECT(vobj), PROPERTY_NAME, CHECK(JS_DefineProperty(cx, JSVAL_TO_OBJECT(vobj), PROPERTY_NAME,
JSVAL_VOID, JSVAL_VOID,
JS_DATA_TO_FUNC_PTR(JSPropertyOp, jsval(vget)), JS_DATA_TO_FUNC_PTR(JSPropertyOp, funGetObj),
JS_DATA_TO_FUNC_PTR(JSPropertyOp, jsval(vset)), JS_DATA_TO_FUNC_PTR(JSPropertyOp, funSetObj),
JSPROP_GETTER | JSPROP_SETTER | JSPROP_PERMANENT)); JSPROP_GETTER | JSPROP_SETTER | JSPROP_PERMANENT));
JSBool found = JS_FALSE; JSBool found = JS_FALSE;

Просмотреть файл

@ -8,7 +8,7 @@
#include "tests.h" #include "tests.h"
static JSBool static JSBool
my_Equality(JSContext *cx, JSObject *obj, jsval v, JSBool *bp) my_Equality(JSContext *cx, JSObject *obj, const jsval *, JSBool *bp)
{ {
*bp = JS_TRUE; *bp = JS_TRUE;
return JS_TRUE; return JS_TRUE;

Просмотреть файл

@ -60,7 +60,7 @@ BEGIN_TEST(testGCChunkAlloc)
"var max = 0; (function() {" "var max = 0; (function() {"
" var array = [];" " var array = [];"
" for (; ; ++max)" " for (; ; ++max)"
" array.push(max + 0.1);" " array.push({});"
"})();"; "})();";
JSBool ok = JS_EvaluateScript(cx, global, source, strlen(source), "", 1, JSBool ok = JS_EvaluateScript(cx, global, source, strlen(source), "", 1,
root.addr()); root.addr());
@ -76,7 +76,7 @@ BEGIN_TEST(testGCChunkAlloc)
" var array = [];" " var array = [];"
" for (var i = max >> 1; i != 0;) {" " for (var i = max >> 1; i != 0;) {"
" --i;" " --i;"
" array.push(i + 0.1);" " array.push({});"
" }" " }"
"})();", root.addr()); "})();", root.addr());
CHECK(errorCount == 1); CHECK(errorCount == 1);

Просмотреть файл

@ -83,7 +83,7 @@ cls_testIsAboutToBeFinalized_bug528645::createAndTestRooted()
* Make sure to include unit and numeric strings to the set. * Make sure to include unit and numeric strings to the set.
*/ */
EVAL("var x = 1.1; " EVAL("var x = 1.1; "
"[x + 0.1, ''+x, 'a', '42', 'something'.substring(1), " "[''+x, 'a', '42', 'something'.substring(1), "
"{}, [], new Function('return 10;'), <xml/>];", "{}, [], new Function('return 10;'), <xml/>];",
root.addr()); root.addr());

Просмотреть файл

@ -33,7 +33,7 @@ BEGIN_TEST(testLookup_bug522590)
END_TEST(testLookup_bug522590) END_TEST(testLookup_bug522590)
JSBool JSBool
document_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp) document_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags, JSObject **objp)
{ {
// If id is "all", and we're not detecting, resolve document.all=true. // If id is "all", and we're not detecting, resolve document.all=true.
jsvalRoot v(cx); jsvalRoot v(cx);

Просмотреть файл

@ -67,7 +67,6 @@ BEGIN_TEST(testNewObject_1)
CHECK(len == 4); CHECK(len == 4);
// With N arguments. // With N arguments.
JS_ASSERT(INT_FITS_IN_JSVAL(N));
for (size_t i = 0; i < N; i++) for (size_t i = 0; i < N; i++)
argv[i] = INT_TO_JSVAL(i); argv[i] = INT_TO_JSVAL(i);
obj = JS_New(cx, Array, N, argv); obj = JS_New(cx, Array, N, argv);

Просмотреть файл

@ -7,7 +7,7 @@
static int g_counter; static int g_counter;
static JSBool static JSBool
CounterAdd(JSContext *cx, JSObject *obj, jsval idval, jsval *vp) CounterAdd(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{ {
g_counter++; g_counter++;
return JS_TRUE; return JS_TRUE;

Просмотреть файл

@ -6,8 +6,6 @@
BEGIN_TEST(testSameValue) BEGIN_TEST(testSameValue)
{ {
jsvalRoot v1(cx);
jsvalRoot v2(cx);
/* /*
* NB: passing a double that fits in an integer jsval is API misuse. As a * NB: passing a double that fits in an integer jsval is API misuse. As a
@ -16,9 +14,8 @@ BEGIN_TEST(testSameValue)
* double, and this is believed to be the only way to make such a * double, and this is believed to be the only way to make such a
* comparison possible. * comparison possible.
*/ */
CHECK(JS_NewDoubleValue(cx, 0.0, v1.addr())); jsval v1 = DOUBLE_TO_JSVAL(0.0);
CHECK(JSVAL_IS_DOUBLE(v1)); jsval v2 = DOUBLE_TO_JSVAL(-0.0);
CHECK(JS_NewNumberValue(cx, -0.0, v2.addr()));
CHECK(!JS_SameValue(cx, v1, v2)); CHECK(!JS_SameValue(cx, v1, v2));
return true; return true;
} }

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -52,172 +52,409 @@
JS_BEGIN_EXTERN_C JS_BEGIN_EXTERN_C
/* /*
* Type tags stored in the low bits of a jsval. * In release builds, jsval and jsid are defined to be integral types. This
*/ * prevents many bugs from being caught at compile time. E.g.:
typedef enum jsvaltag {
JSVAL_OBJECT = 0x0, /* untagged reference to object */
JSVAL_INT = 0x1, /* tagged 31-bit integer value */
JSVAL_DOUBLE = 0x2, /* tagged reference to double */
JSVAL_STRING = 0x4, /* tagged reference to string */
JSVAL_SPECIAL = 0x6 /* tagged boolean or private value */
} jsvaltag;
/* Type tag bitfield length and derived macros. */
#define JSVAL_TAGBITS 3
#define JSVAL_TAGMASK ((jsval) JS_BITMASK(JSVAL_TAGBITS))
#define JSVAL_ALIGN JS_BIT(JSVAL_TAGBITS)
/* Not a function, because we have static asserts that use it */
#define JSVAL_TAG(v) ((jsvaltag)((v) & JSVAL_TAGMASK))
/* Not a function, because we have static asserts that use it */
#define JSVAL_SETTAG(v, t) ((v) | (t))
static JS_ALWAYS_INLINE jsval
JSVAL_CLRTAG(jsval v)
{
return v & ~(jsval)JSVAL_TAGMASK;
}
/*
* Well-known JS values. The extern'd variables are initialized when the
* first JSContext is created by JS_NewContext (see below).
*/
#define JSVAL_NULL ((jsval) 0)
#define JSVAL_ZERO INT_TO_JSVAL(0)
#define JSVAL_ONE INT_TO_JSVAL(1)
#define JSVAL_FALSE SPECIAL_TO_JSVAL(JS_FALSE)
#define JSVAL_TRUE SPECIAL_TO_JSVAL(JS_TRUE)
#define JSVAL_VOID SPECIAL_TO_JSVAL(2)
/*
* A "special" value is a 29-bit (for 32-bit jsval) or 61-bit (for 64-bit jsval)
* value whose tag is JSVAL_SPECIAL. These values include the booleans 0 and 1.
* *
* JSVAL_VOID is a non-boolean special value, but embedders MUST NOT rely on * jsval v = ...
* this. All other possible special values are implementation-reserved * if (v == JS_TRUE) // error
* and MUST NOT be constructed by any embedding of SpiderMonkey. * ...
*
* jsid id = v; // error
*
* To catch more errors, jsval and jsid are given struct types in debug builds.
* Struct assignment and (in C++) operator== allow correct code to be mostly
* oblivious to the change. This feature can be explicitly disabled in debug
* builds by defining JS_NO_JSVAL_JSID_STRUCT_TYPES.
*/ */
#define JSVAL_TO_SPECIAL(v) ((JSBool) ((v) >> JSVAL_TAGBITS)) #ifdef JS_USE_JSVAL_JSID_STRUCT_TYPES
#define SPECIAL_TO_JSVAL(b) \
JSVAL_SETTAG((jsval) (b) << JSVAL_TAGBITS, JSVAL_SPECIAL)
/* Predicates for type testing. */ /* Well-known JS values. N.B. These constants are initialized at startup. */
static JS_ALWAYS_INLINE JSBool extern JS_PUBLIC_DATA(jsval) JSVAL_NULL;
JSVAL_IS_OBJECT(jsval v) extern JS_PUBLIC_DATA(jsval) JSVAL_ZERO;
{ extern JS_PUBLIC_DATA(jsval) JSVAL_ONE;
return JSVAL_TAG(v) == JSVAL_OBJECT; extern JS_PUBLIC_DATA(jsval) JSVAL_FALSE;
} extern JS_PUBLIC_DATA(jsval) JSVAL_TRUE;
extern JS_PUBLIC_DATA(jsval) JSVAL_VOID;
static JS_ALWAYS_INLINE JSBool #else
JSVAL_IS_INT(jsval v)
{
return (JSBool)(v & JSVAL_INT);
}
static JS_ALWAYS_INLINE JSBool /* Well-known JS values. */
JSVAL_IS_DOUBLE(jsval v) #define JSVAL_NULL BUILD_JSVAL(JSVAL_TAG_NULL, 0)
{ #define JSVAL_ZERO BUILD_JSVAL(JSVAL_TAG_INT32, 0)
return JSVAL_TAG(v) == JSVAL_DOUBLE; #define JSVAL_ONE BUILD_JSVAL(JSVAL_TAG_INT32, 1)
} #define JSVAL_FALSE BUILD_JSVAL(JSVAL_TAG_BOOLEAN, JS_FALSE)
#define JSVAL_TRUE BUILD_JSVAL(JSVAL_TAG_BOOLEAN, JS_TRUE)
#define JSVAL_VOID BUILD_JSVAL(JSVAL_TAG_UNDEFINED, 0)
static JS_ALWAYS_INLINE JSBool #endif
JSVAL_IS_NUMBER(jsval v)
{
return JSVAL_IS_INT(v) || JSVAL_IS_DOUBLE(v);
}
static JS_ALWAYS_INLINE JSBool /************************************************************************/
JSVAL_IS_STRING(jsval v)
{
return JSVAL_TAG(v) == JSVAL_STRING;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_SPECIAL(jsval v)
{
return JSVAL_TAG(v) == JSVAL_SPECIAL;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_BOOLEAN(jsval v)
{
return (v & ~((jsval)1 << JSVAL_TAGBITS)) == JSVAL_SPECIAL;
}
static JS_ALWAYS_INLINE JSBool static JS_ALWAYS_INLINE JSBool
JSVAL_IS_NULL(jsval v) JSVAL_IS_NULL(jsval v)
{ {
return v == JSVAL_NULL; jsval_layout l;
l.asBits = JSVAL_BITS(v);
return JSVAL_IS_NULL_IMPL(l);
} }
static JS_ALWAYS_INLINE JSBool static JS_ALWAYS_INLINE JSBool
JSVAL_IS_VOID(jsval v) JSVAL_IS_VOID(jsval v)
{ {
return v == JSVAL_VOID; jsval_layout l;
l.asBits = JSVAL_BITS(v);
return JSVAL_IS_UNDEFINED_IMPL(l);
} }
static JS_ALWAYS_INLINE JSBool static JS_ALWAYS_INLINE JSBool
JSVAL_IS_PRIMITIVE(jsval v) JSVAL_IS_INT(jsval v)
{ {
return !JSVAL_IS_OBJECT(v) || JSVAL_IS_NULL(v); jsval_layout l;
l.asBits = JSVAL_BITS(v);
return JSVAL_IS_INT32_IMPL(l);
}
static JS_ALWAYS_INLINE jsint
JSVAL_TO_INT(jsval v)
{
jsval_layout l;
JS_ASSERT(JSVAL_IS_INT(v));
l.asBits = JSVAL_BITS(v);
return JSVAL_TO_INT32_IMPL(l);
}
#define JSVAL_INT_BITS 32
#define JSVAL_INT_MIN ((jsint)0x80000000)
#define JSVAL_INT_MAX ((jsint)0x7fffffff)
static JS_ALWAYS_INLINE jsval
INT_TO_JSVAL(int32 i)
{
return IMPL_TO_JSVAL(INT32_TO_JSVAL_IMPL(i));
} }
/* Objects, strings, and doubles are GC'ed. */
static JS_ALWAYS_INLINE JSBool static JS_ALWAYS_INLINE JSBool
JSVAL_IS_GCTHING(jsval v) JSVAL_IS_DOUBLE(jsval v)
{ {
return !(v & JSVAL_INT) && JSVAL_TAG(v) != JSVAL_SPECIAL; jsval_layout l;
l.asBits = JSVAL_BITS(v);
return JSVAL_IS_DOUBLE_IMPL(l);
} }
static JS_ALWAYS_INLINE void * static JS_ALWAYS_INLINE jsdouble
JSVAL_TO_GCTHING(jsval v)
{
JS_ASSERT(JSVAL_IS_GCTHING(v));
return (void *) JSVAL_CLRTAG(v);
}
static JS_ALWAYS_INLINE JSObject *
JSVAL_TO_OBJECT(jsval v)
{
JS_ASSERT(JSVAL_IS_OBJECT(v));
return (JSObject *) JSVAL_TO_GCTHING(v);
}
static JS_ALWAYS_INLINE jsdouble *
JSVAL_TO_DOUBLE(jsval v) JSVAL_TO_DOUBLE(jsval v)
{ {
jsval_layout l;
JS_ASSERT(JSVAL_IS_DOUBLE(v)); JS_ASSERT(JSVAL_IS_DOUBLE(v));
return (jsdouble *) JSVAL_TO_GCTHING(v); l.asBits = JSVAL_BITS(v);
return l.asDouble;
}
static JS_ALWAYS_INLINE jsval
DOUBLE_TO_JSVAL(jsdouble d)
{
return IMPL_TO_JSVAL(DOUBLE_TO_JSVAL_IMPL(d));
}
static JS_ALWAYS_INLINE jsval
UINT_TO_JSVAL(uint32 i)
{
if (i <= JSVAL_INT_MAX)
return INT_TO_JSVAL((int32)i);
return DOUBLE_TO_JSVAL((jsdouble)i);
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_NUMBER(jsval v)
{
jsval_layout l;
l.asBits = JSVAL_BITS(v);
return JSVAL_IS_NUMBER_IMPL(l);
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_STRING(jsval v)
{
jsval_layout l;
l.asBits = JSVAL_BITS(v);
return JSVAL_IS_STRING_IMPL(l);
} }
static JS_ALWAYS_INLINE JSString * static JS_ALWAYS_INLINE JSString *
JSVAL_TO_STRING(jsval v) JSVAL_TO_STRING(jsval v)
{ {
jsval_layout l;
JS_ASSERT(JSVAL_IS_STRING(v)); JS_ASSERT(JSVAL_IS_STRING(v));
return (JSString *) JSVAL_TO_GCTHING(v); l.asBits = JSVAL_BITS(v);
} return JSVAL_TO_STRING_IMPL(l);
static JS_ALWAYS_INLINE jsval
OBJECT_TO_JSVAL(JSObject *obj)
{
JS_ASSERT(((jsval) obj & JSVAL_TAGMASK) == JSVAL_OBJECT);
return (jsval) obj;
}
static JS_ALWAYS_INLINE jsval
DOUBLE_TO_JSVAL(jsdouble *dp)
{
JS_ASSERT(((jsword) dp & JSVAL_TAGMASK) == 0);
return JSVAL_SETTAG((jsval) dp, JSVAL_DOUBLE);
} }
static JS_ALWAYS_INLINE jsval static JS_ALWAYS_INLINE jsval
STRING_TO_JSVAL(JSString *str) STRING_TO_JSVAL(JSString *str)
{ {
return JSVAL_SETTAG((jsval) str, JSVAL_STRING); return IMPL_TO_JSVAL(STRING_TO_JSVAL_IMPL(str));
} }
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_OBJECT(jsval v)
{
jsval_layout l;
l.asBits = JSVAL_BITS(v);
return JSVAL_IS_OBJECT_OR_NULL_IMPL(l);
}
static JS_ALWAYS_INLINE JSObject *
JSVAL_TO_OBJECT(jsval v)
{
jsval_layout l;
JS_ASSERT(JSVAL_IS_OBJECT(v));
l.asBits = JSVAL_BITS(v);
return JSVAL_TO_OBJECT_IMPL(l);
}
static JS_ALWAYS_INLINE jsval
OBJECT_TO_JSVAL(JSObject *obj)
{
if (obj)
return IMPL_TO_JSVAL(OBJECT_TO_JSVAL_IMPL(obj));
return JSVAL_NULL;
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_BOOLEAN(jsval v)
{
jsval_layout l;
l.asBits = JSVAL_BITS(v);
return JSVAL_IS_BOOLEAN_IMPL(l);
}
static JS_ALWAYS_INLINE JSBool
JSVAL_TO_BOOLEAN(jsval v)
{
jsval_layout l;
JS_ASSERT(JSVAL_IS_BOOLEAN(v));
l.asBits = JSVAL_BITS(v);
return JSVAL_TO_BOOLEAN_IMPL(l);
}
static JS_ALWAYS_INLINE jsval
BOOLEAN_TO_JSVAL(JSBool b)
{
return IMPL_TO_JSVAL(BOOLEAN_TO_JSVAL_IMPL(b));
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_PRIMITIVE(jsval v)
{
jsval_layout l;
l.asBits = JSVAL_BITS(v);
return JSVAL_IS_PRIMITIVE_IMPL(l);
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_GCTHING(jsval v)
{
jsval_layout l;
l.asBits = JSVAL_BITS(v);
return JSVAL_IS_GCTHING_IMPL(l);
}
static JS_ALWAYS_INLINE void *
JSVAL_TO_GCTHING(jsval v)
{
jsval_layout l;
JS_ASSERT(JSVAL_IS_GCTHING(v));
l.asBits = JSVAL_BITS(v);
return JSVAL_TO_GCTHING_IMPL(l);
}
/* To be GC-safe, privates are tagged as doubles. */
static JS_ALWAYS_INLINE jsval
PRIVATE_TO_JSVAL(void *ptr)
{
return IMPL_TO_JSVAL(PRIVATE_PTR_TO_JSVAL_IMPL(ptr));
}
static JS_ALWAYS_INLINE void *
JSVAL_TO_PRIVATE(jsval v)
{
jsval_layout l;
JS_ASSERT(JSVAL_IS_DOUBLE(v));
l.asBits = JSVAL_BITS(v);
return JSVAL_TO_PRIVATE_PTR_IMPL(l);
}
static JS_ALWAYS_INLINE JSBool
JSVAL_IS_UNDERLYING_TYPE_OF_PRIVATE(jsval v)
{
jsval_layout l;
l.asBits = JSVAL_BITS(v);
return JSVAL_IS_UNDERLYING_TYPE_OF_PRIVATE_IMPL(l);
}
/************************************************************************/
/*
* A jsid is an identifier for a property or method of an object which is
* either a 31-bit signed integer, interned string or object. If XML is
* enabled, there is an additional singleton jsid value; see
* JS_DEFAULT_XML_NAMESPACE_ID below. Finally, there is an additional jsid
* value, JSID_VOID, which does not occur in JS scripts but may be used to
* indicate the absence of a valid jsid.
*
* A jsid is not implicitly convertible to or from a jsval; JS_ValueToId or
* JS_IdToValue must be used instead.
*/
#define JSID_TYPE_STRING 0x0
#define JSID_TYPE_INT 0x1
#define JSID_TYPE_VOID 0x2
#define JSID_TYPE_OBJECT 0x4
#define JSID_TYPE_DEFAULT_XML_NAMESPACE 0x6
#define JSID_TYPE_MASK 0x7
/*
* Do not use canonical 'id' for jsid parameters since this is a magic word in
* Objective-C++ which, apparently, wants to be able to #include jsapi.h.
*/
static JS_ALWAYS_INLINE JSBool
JSID_IS_STRING(jsid iden)
{
return (JSID_BITS(iden) & JSID_TYPE_MASK) == 0;
}
static JS_ALWAYS_INLINE JSString *
JSID_TO_STRING(jsid iden)
{
JS_ASSERT(JSID_IS_STRING(iden));
return (JSString *)(JSID_BITS(iden));
}
JS_PUBLIC_API(JSBool)
JS_StringHasBeenInterned(JSString *str);
/* A jsid may only hold an interned JSString. */
static JS_ALWAYS_INLINE jsid
INTERNED_STRING_TO_JSID(JSString *str)
{
jsid iden;
JS_ASSERT(JS_StringHasBeenInterned(str));
JS_ASSERT(((size_t)str & JSID_TYPE_MASK) == 0);
JSID_BITS(iden) = (size_t)str;
return iden;
}
static JS_ALWAYS_INLINE JSBool
JSID_IS_INT(jsid iden)
{
return !!(JSID_BITS(iden) & JSID_TYPE_INT);
}
static JS_ALWAYS_INLINE int32
JSID_TO_INT(jsid iden)
{
JS_ASSERT(JSID_IS_INT(iden));
return ((int32)JSID_BITS(iden)) >> 1;
}
#define JSID_INT_MIN (-(1 << 30))
#define JSID_INT_MAX ((1 << 30) - 1)
static JS_ALWAYS_INLINE JSBool
INT_FITS_IN_JSID(int32 i)
{
return ((jsuint)(i) - (jsuint)JSID_INT_MIN <=
(jsuint)(JSID_INT_MAX - JSID_INT_MIN));
}
static JS_ALWAYS_INLINE jsid
INT_TO_JSID(int32 i)
{
jsid iden;
JS_ASSERT(INT_FITS_IN_JSID(i));
JSID_BITS(iden) = ((i << 1) | JSID_TYPE_INT);
return iden;
}
static JS_ALWAYS_INLINE JSBool
JSID_IS_OBJECT(jsid iden)
{
return (JSID_BITS(iden) & JSID_TYPE_MASK) == JSID_TYPE_OBJECT;
}
static JS_ALWAYS_INLINE JSObject *
JSID_TO_OBJECT(jsid iden)
{
JS_ASSERT(JSID_IS_OBJECT(iden));
return (JSObject *)(JSID_BITS(iden) & ~(size_t)JSID_TYPE_MASK);
}
static JS_ALWAYS_INLINE jsid
OBJECT_TO_JSID(JSObject *obj)
{
jsid iden;
JS_ASSERT(obj != NULL);
JS_ASSERT(((size_t)obj & JSID_TYPE_MASK) == 0);
JSID_BITS(iden) = ((size_t)obj | JSID_TYPE_OBJECT);
return iden;
}
static JS_ALWAYS_INLINE JSBool
JSID_IS_GCTHING(jsid iden)
{
return JSID_IS_STRING(iden) || JSID_IS_OBJECT(iden);
}
static JS_ALWAYS_INLINE void *
JSID_TO_GCTHING(jsid iden)
{
return (void *)(JSID_BITS(iden) & ~(size_t)JSID_TYPE_MASK);
}
/*
* The magic XML namespace id is not a valid jsid. Global object classes in
* embeddings that enable JS_HAS_XML_SUPPORT (E4X) should handle this id.
*/
static JS_ALWAYS_INLINE JSBool
JSID_IS_DEFAULT_XML_NAMESPACE(jsid iden)
{
JS_ASSERT_IF(((size_t)JSID_BITS(iden) & JSID_TYPE_MASK) == JSID_TYPE_DEFAULT_XML_NAMESPACE,
JSID_BITS(iden) == JSID_TYPE_DEFAULT_XML_NAMESPACE);
return ((size_t)JSID_BITS(iden) == JSID_TYPE_DEFAULT_XML_NAMESPACE);
}
#ifdef JS_USE_JSVAL_JSID_STRUCT_TYPES
extern JS_PUBLIC_DATA(jsid) JS_DEFAULT_XML_NAMESPACE_ID;
#else
#define JS_DEFAULT_XML_NAMESPACE_ID ((jsid)JSID_TYPE_DEFAULT_XML_NAMESPACE)
#endif
/*
* A void jsid is not a valid id and only arises as an exceptional API return
* value, such as in JS_NextProperty. Embeddings must not pass JSID_VOID into
* JSAPI entry points expecting a jsid and do not need to handle JSID_VOID in
* hooks receiving a jsid except when explicitly noted in the API contract.
*/
static JS_ALWAYS_INLINE JSBool
JSID_IS_VOID(jsid iden)
{
JS_ASSERT_IF(((size_t)JSID_BITS(iden) & JSID_TYPE_MASK) == JSID_TYPE_VOID,
JSID_BITS(iden) == JSID_TYPE_VOID);
return ((size_t)JSID_BITS(iden) == JSID_TYPE_VOID);
}
#ifdef JS_USE_JSVAL_JSID_STRUCT_TYPES
extern JS_PUBLIC_DATA(jsid) JSID_VOID;
#else
#define JSID_VOID ((jsid)JSID_TYPE_VOID)
#endif
/************************************************************************/
/* Lock and unlock the GC thing held by a jsval. */ /* Lock and unlock the GC thing held by a jsval. */
#define JSVAL_LOCK(cx,v) (JSVAL_IS_GCTHING(v) \ #define JSVAL_LOCK(cx,v) (JSVAL_IS_GCTHING(v) \
? JS_LockGCThing(cx, JSVAL_TO_GCTHING(v)) \ ? JS_LockGCThing(cx, JSVAL_TO_GCTHING(v)) \
@ -226,52 +463,6 @@ STRING_TO_JSVAL(JSString *str)
? JS_UnlockGCThing(cx, JSVAL_TO_GCTHING(v)) \ ? JS_UnlockGCThing(cx, JSVAL_TO_GCTHING(v)) \
: JS_TRUE) : JS_TRUE)
/* Domain limits for the jsval int type. */
#define JSVAL_INT_BITS 31
#define JSVAL_INT_POW2(n) ((jsval)1 << (n))
#define JSVAL_INT_MIN (-JSVAL_INT_POW2(30))
#define JSVAL_INT_MAX (JSVAL_INT_POW2(30) - 1)
/* Not a function, because we have static asserts that use it */
#define INT_FITS_IN_JSVAL(i) ((jsuint)(i) - (jsuint)JSVAL_INT_MIN <= \
(jsuint)(JSVAL_INT_MAX - JSVAL_INT_MIN))
static JS_ALWAYS_INLINE jsint
JSVAL_TO_INT(jsval v)
{
JS_ASSERT(JSVAL_IS_INT(v));
return (jsint) v >> 1;
}
/* Not a function, because we have static asserts that use it */
#define INT_TO_JSVAL_CONSTEXPR(i) (((jsval)(i) << 1) | JSVAL_INT)
static JS_ALWAYS_INLINE jsval
INT_TO_JSVAL(jsint i)
{
JS_ASSERT(INT_FITS_IN_JSVAL(i));
return INT_TO_JSVAL_CONSTEXPR(i);
}
/* Convert between boolean and jsval, asserting that inputs are valid. */
static JS_ALWAYS_INLINE JSBool
JSVAL_TO_BOOLEAN(jsval v)
{
JS_ASSERT(v == JSVAL_TRUE || v == JSVAL_FALSE);
return JSVAL_TO_SPECIAL(v);
}
static JS_ALWAYS_INLINE jsval
BOOLEAN_TO_JSVAL(JSBool b)
{
JS_ASSERT(b == JS_TRUE || b == JS_FALSE);
return SPECIAL_TO_JSVAL(b);
}
/* A private data pointer (2-byte-aligned) can be stored as an int jsval. */
#define JSVAL_TO_PRIVATE(v) ((void *)((v) & ~JSVAL_INT))
#define PRIVATE_TO_JSVAL(p) ((jsval)(ptrdiff_t)(p) | JSVAL_INT)
/* Property attributes, set in JSPropertySpec and passed to API functions. */ /* Property attributes, set in JSPropertySpec and passed to API functions. */
#define JSPROP_ENUMERATE 0x01 /* property is visible to for/in loop */ #define JSPROP_ENUMERATE 0x01 /* property is visible to for/in loop */
#define JSPROP_READONLY 0x02 /* not settable: assignment is no-op */ #define JSPROP_READONLY 0x02 /* not settable: assignment is no-op */
@ -833,7 +1024,7 @@ JS_InitStandardClasses(JSContext *cx, JSObject *obj);
* loops any classes not yet resolved lazily. * loops any classes not yet resolved lazily.
*/ */
extern JS_PUBLIC_API(JSBool) extern JS_PUBLIC_API(JSBool)
JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsval id, JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsid id,
JSBool *resolved); JSBool *resolved);
extern JS_PUBLIC_API(JSBool) extern JS_PUBLIC_API(JSBool)
@ -898,7 +1089,7 @@ JS_InitCTypesClass(JSContext *cx, JSObject *global);
#define JS_CALLEE(cx,vp) ((vp)[0]) #define JS_CALLEE(cx,vp) ((vp)[0])
#define JS_ARGV_CALLEE(argv) ((argv)[-2]) #define JS_ARGV_CALLEE(argv) ((argv)[-2])
#define JS_THIS(cx,vp) JS_ComputeThis(cx, vp) #define JS_THIS(cx,vp) JS_ComputeThis(cx, vp)
#define JS_THIS_OBJECT(cx,vp) ((JSObject *) JS_THIS(cx,vp)) #define JS_THIS_OBJECT(cx,vp) (JSVAL_TO_OBJECT(JS_THIS(cx,vp)))
#define JS_ARGV(cx,vp) ((vp) + 2) #define JS_ARGV(cx,vp) ((vp) + 2)
#define JS_RVAL(cx,vp) (*(vp)) #define JS_RVAL(cx,vp) (*(vp))
#define JS_SET_RVAL(cx,vp,v) (*(vp) = (v)) #define JS_SET_RVAL(cx,vp,v) (*(vp) = (v))
@ -921,12 +1112,6 @@ JS_updateMallocCounter(JSContext *cx, size_t nbytes);
extern JS_PUBLIC_API(char *) extern JS_PUBLIC_API(char *)
JS_strdup(JSContext *cx, const char *s); JS_strdup(JSContext *cx, const char *s);
extern JS_PUBLIC_API(jsdouble *)
JS_NewDouble(JSContext *cx, jsdouble d);
extern JS_PUBLIC_API(JSBool)
JS_NewDoubleValue(JSContext *cx, jsdouble d, jsval *rval);
extern JS_PUBLIC_API(JSBool) extern JS_PUBLIC_API(JSBool)
JS_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval); JS_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval);
@ -964,9 +1149,6 @@ JS_AddStringRoot(JSContext *cx, JSString **rp);
extern JS_PUBLIC_API(JSBool) extern JS_PUBLIC_API(JSBool)
JS_AddObjectRoot(JSContext *cx, JSObject **rp); JS_AddObjectRoot(JSContext *cx, JSObject **rp);
extern JS_PUBLIC_API(JSBool)
JS_AddDoubleRoot(JSContext *cx, jsdouble **rp);
extern JS_PUBLIC_API(JSBool) extern JS_PUBLIC_API(JSBool)
JS_AddGCThingRoot(JSContext *cx, void **rp); JS_AddGCThingRoot(JSContext *cx, void **rp);
@ -976,7 +1158,6 @@ JS_AddGCThingRoot(JSContext *cx, void **rp);
#define JS_AddValueRoot(cx,vp) JS_AddNamedValueRoot((cx), (vp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__)) #define JS_AddValueRoot(cx,vp) JS_AddNamedValueRoot((cx), (vp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__))
#define JS_AddStringRoot(cx,rp) JS_AddNamedStringRoot((cx), (rp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__)) #define JS_AddStringRoot(cx,rp) JS_AddNamedStringRoot((cx), (rp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__))
#define JS_AddObjectRoot(cx,rp) JS_AddNamedObjectRoot((cx), (rp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__)) #define JS_AddObjectRoot(cx,rp) JS_AddNamedObjectRoot((cx), (rp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__))
#define JS_AddDoubleRoot(cx,rp) JS_AddNamedDoubleRoot((cx), (rp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__))
#define JS_AddGCThingRoot(cx,rp) JS_AddNamedGCThingRoot((cx), (rp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__)) #define JS_AddGCThingRoot(cx,rp) JS_AddNamedGCThingRoot((cx), (rp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__))
#endif #endif
@ -989,9 +1170,6 @@ JS_AddNamedStringRoot(JSContext *cx, JSString **rp, const char *name);
extern JS_PUBLIC_API(JSBool) extern JS_PUBLIC_API(JSBool)
JS_AddNamedObjectRoot(JSContext *cx, JSObject **rp, const char *name); JS_AddNamedObjectRoot(JSContext *cx, JSObject **rp, const char *name);
extern JS_PUBLIC_API(JSBool)
JS_AddNamedDoubleRoot(JSContext *cx, jsdouble **rp, const char *name);
extern JS_PUBLIC_API(JSBool) extern JS_PUBLIC_API(JSBool)
JS_AddNamedGCThingRoot(JSContext *cx, void **rp, const char *name); JS_AddNamedGCThingRoot(JSContext *cx, void **rp, const char *name);
@ -1004,9 +1182,6 @@ JS_RemoveStringRoot(JSContext *cx, JSString **rp);
extern JS_PUBLIC_API(JSBool) extern JS_PUBLIC_API(JSBool)
JS_RemoveObjectRoot(JSContext *cx, JSObject **rp); JS_RemoveObjectRoot(JSContext *cx, JSObject **rp);
extern JS_PUBLIC_API(JSBool)
JS_RemoveDoubleRoot(JSContext *cx, jsdouble **rp);
extern JS_PUBLIC_API(JSBool) extern JS_PUBLIC_API(JSBool)
JS_RemoveGCThingRoot(JSContext *cx, void **rp); JS_RemoveGCThingRoot(JSContext *cx, void **rp);
@ -1036,10 +1211,15 @@ JS_ClearNewbornRoots(JSContext *cx);
#define JS_LeaveLocalRootScopeWithResult(cx, rval) ((void) 0) #define JS_LeaveLocalRootScopeWithResult(cx, rval) ((void) 0)
#define JS_ForgetLocalRoot(cx, thing) ((void) 0) #define JS_ForgetLocalRoot(cx, thing) ((void) 0)
typedef enum JSGCRootType {
JS_GC_ROOT_VALUE_PTR,
JS_GC_ROOT_GCTHING_PTR
} JSGCRootType;
#ifdef DEBUG #ifdef DEBUG
extern JS_PUBLIC_API(void) extern JS_PUBLIC_API(void)
JS_DumpNamedRoots(JSRuntime *rt, JS_DumpNamedRoots(JSRuntime *rt,
void (*dump)(const char *name, void *rp, void *data), void (*dump)(const char *name, void *rp, JSGCRootType type, void *data),
void *data); void *data);
#endif #endif
@ -1059,6 +1239,10 @@ JS_DumpNamedRoots(JSRuntime *rt,
* or any JS API entry point that acquires locks, without double-tripping or * or any JS API entry point that acquires locks, without double-tripping or
* deadlocking on the GC lock. * deadlocking on the GC lock.
* *
* The JSGCRootType parameter indicates whether rp is a pointer to a Value
* (which is obtained by '(Value *)rp') or a pointer to a GC-thing pointer
* (which is obtained by '(void **)rp').
*
* JS_MapGCRoots returns the count of roots that were successfully mapped. * JS_MapGCRoots returns the count of roots that were successfully mapped.
*/ */
#define JS_MAP_GCROOT_NEXT 0 /* continue mapping entries */ #define JS_MAP_GCROOT_NEXT 0 /* continue mapping entries */
@ -1066,7 +1250,7 @@ JS_DumpNamedRoots(JSRuntime *rt,
#define JS_MAP_GCROOT_REMOVE 2 /* remove and free the current entry */ #define JS_MAP_GCROOT_REMOVE 2 /* remove and free the current entry */
typedef intN typedef intN
(* JSGCRootMapFun)(void *rp, const char *name, void *data); (* JSGCRootMapFun)(void *rp, JSGCRootType type, const char *name, void *data);
extern JS_PUBLIC_API(uint32) extern JS_PUBLIC_API(uint32)
JS_MapGCRoots(JSRuntime *rt, JSGCRootMapFun map, void *data); JS_MapGCRoots(JSRuntime *rt, JSGCRootMapFun map, void *data);
@ -1098,7 +1282,7 @@ JS_SetExtraGCRoots(JSRuntime *rt, JSTraceDataOp traceOp, void *data);
* instead. * instead.
*/ */
extern JS_PUBLIC_API(void) extern JS_PUBLIC_API(void)
JS_MarkGCThing(JSContext *cx, void *thing, const char *name, void *arg); JS_MarkGCThing(JSContext *cx, jsval v, const char *name, void *arg);
/* /*
* JS_CallTracer API and related macros for implementors of JSTraceOp, to * JS_CallTracer API and related macros for implementors of JSTraceOp, to
@ -1114,16 +1298,34 @@ JS_MarkGCThing(JSContext *cx, void *thing, const char *name, void *arg);
/* Trace kinds to pass to JS_Tracing. */ /* Trace kinds to pass to JS_Tracing. */
#define JSTRACE_OBJECT 0 #define JSTRACE_OBJECT 0
#define JSTRACE_DOUBLE 1 #define JSTRACE_STRING 1
#define JSTRACE_STRING 2
/* /*
* Use the following macros to check if a particular jsval is a traceable * Use the following macros to check if a particular jsval is a traceable
* thing and to extract the thing and its kind to pass to JS_CallTracer. * thing and to extract the thing and its kind to pass to JS_CallTracer.
*/ */
#define JSVAL_IS_TRACEABLE(v) (JSVAL_IS_GCTHING(v) && !JSVAL_IS_NULL(v)) static JS_ALWAYS_INLINE JSBool
#define JSVAL_TO_TRACEABLE(v) (JSVAL_TO_GCTHING(v)) JSVAL_IS_TRACEABLE(jsval v)
#define JSVAL_TRACE_KIND(v) (JSVAL_TAG(v) >> 1) {
jsval_layout l;
l.asBits = JSVAL_BITS(v);
return JSVAL_IS_TRACEABLE_IMPL(l);
}
static JS_ALWAYS_INLINE void *
JSVAL_TO_TRACEABLE(jsval v)
{
return JSVAL_TO_GCTHING(v);
}
static JS_ALWAYS_INLINE uint32
JSVAL_TRACE_KIND(jsval v)
{
jsval_layout l;
JS_ASSERT(JSVAL_IS_GCTHING(v));
l.asBits = JSVAL_BITS(v);
return JSVAL_TRACE_KIND_IMPL(l);
}
struct JSTracer { struct JSTracer {
JSContext *context; JSContext *context;
@ -1220,13 +1422,6 @@ JS_CallTracer(JSTracer *trc, void *thing, uint32 kind);
JS_CALL_TRACER((trc), str_, JSTRACE_STRING, name); \ JS_CALL_TRACER((trc), str_, JSTRACE_STRING, name); \
JS_END_MACRO JS_END_MACRO
#define JS_CALL_DOUBLE_TRACER(trc, number, name) \
JS_BEGIN_MACRO \
jsdouble *num_ = (number); \
JS_ASSERT(num_); \
JS_CALL_TRACER((trc), num_, JSTRACE_DOUBLE, name); \
JS_END_MACRO
/* /*
* API for JSTraceCallback implementations. * API for JSTraceCallback implementations.
*/ */
@ -1377,7 +1572,7 @@ JS_RemoveExternalStringFinalizer(JSStringFinalizeOp finalizer);
/* /*
* Create a new JSString whose chars member refers to external memory, i.e., * Create a new JSString whose chars member refers to external memory, i.e.,
* memory requiring special, type-specific finalization. The type code must * memory requiring spe, type-specific finalization. The type code must
* be a nonnegative return value from JS_AddExternalStringFinalizer. * be a nonnegative return value from JS_AddExternalStringFinalizer.
*/ */
extern JS_PUBLIC_API(JSString *) extern JS_PUBLIC_API(JSString *)
@ -1548,13 +1743,6 @@ JS_ValueToId(JSContext *cx, jsval v, jsid *idp);
extern JS_PUBLIC_API(JSBool) extern JS_PUBLIC_API(JSBool)
JS_IdToValue(JSContext *cx, jsid id, jsval *vp); JS_IdToValue(JSContext *cx, jsid id, jsval *vp);
/*
* The magic XML namespace id is int-tagged, but not a valid integer jsval.
* Global object classes in embeddings that enable JS_HAS_XML_SUPPORT (E4X)
* should handle this id specially before converting id via JSVAL_TO_INT.
*/
#define JS_DEFAULT_XML_NAMESPACE_ID ((jsid) JSVAL_VOID)
/* /*
* JSNewResolveOp flag bits. * JSNewResolveOp flag bits.
*/ */
@ -1566,13 +1754,13 @@ JS_IdToValue(JSContext *cx, jsid id, jsval *vp);
#define JSRESOLVE_WITH 0x20 /* resolve inside a with statement */ #define JSRESOLVE_WITH 0x20 /* resolve inside a with statement */
extern JS_PUBLIC_API(JSBool) extern JS_PUBLIC_API(JSBool)
JS_PropertyStub(JSContext *cx, JSObject *obj, jsval id, jsval *vp); JS_PropertyStub(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
extern JS_PUBLIC_API(JSBool) extern JS_PUBLIC_API(JSBool)
JS_EnumerateStub(JSContext *cx, JSObject *obj); JS_EnumerateStub(JSContext *cx, JSObject *obj);
extern JS_PUBLIC_API(JSBool) extern JS_PUBLIC_API(JSBool)
JS_ResolveStub(JSContext *cx, JSObject *obj, jsval id); JS_ResolveStub(JSContext *cx, JSObject *obj, jsid id);
extern JS_PUBLIC_API(JSBool) extern JS_PUBLIC_API(JSBool)
JS_ConvertStub(JSContext *cx, JSObject *obj, JSType type, jsval *vp); JS_ConvertStub(JSContext *cx, JSObject *obj, JSType type, jsval *vp);
@ -1829,8 +2017,8 @@ struct JSPropertyDescriptor {
uintN attrs; uintN attrs;
JSPropertyOp getter; JSPropertyOp getter;
JSPropertyOp setter; JSPropertyOp setter;
uintN shortid;
jsval value; jsval value;
uintN shortid;
}; };
/* /*
@ -2015,7 +2203,7 @@ JS_NewPropertyIterator(JSContext *cx, JSObject *obj);
/* /*
* Return true on success with *idp containing the id of the next enumerable * Return true on success with *idp containing the id of the next enumerable
* property to visit using iterobj, or JSVAL_VOID if there is no such property * property to visit using iterobj, or JSID_IS_VOID if there is no such property
* left to visit. Return false on error. * left to visit. Return false on error.
*/ */
extern JS_PUBLIC_API(JSBool) extern JS_PUBLIC_API(JSBool)

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -46,14 +46,49 @@
#include "jspubtd.h" #include "jspubtd.h"
#include "jsobj.h" #include "jsobj.h"
JS_BEGIN_EXTERN_C
#define ARRAY_CAPACITY_MIN 7 #define ARRAY_CAPACITY_MIN 7
extern JSBool extern JSBool
js_IdIsIndex(jsval id, jsuint *indexp); js_StringIsIndex(JSString *str, jsuint *indexp);
extern JSClass js_ArrayClass, js_SlowArrayClass; inline JSBool
js_IdIsIndex(jsid id, jsuint *indexp)
{
if (JSID_IS_INT(id)) {
jsint i;
i = JSID_TO_INT(id);
if (i < 0)
return JS_FALSE;
*indexp = (jsuint)i;
return JS_TRUE;
}
if (JS_UNLIKELY(!JSID_IS_STRING(id)))
return JS_FALSE;
return js_StringIsIndex(JSID_TO_STRING(id), indexp);
}
/* XML really wants to pretend jsvals are jsids. */
inline JSBool
js_IdValIsIndex(jsval id, jsuint *indexp)
{
if (JSVAL_IS_INT(id)) {
jsint i;
i = JSVAL_TO_INT(id);
if (i < 0)
return JS_FALSE;
*indexp = (jsuint)i;
return JS_TRUE;
}
if (!JSVAL_IS_STRING(id))
return JS_FALSE;
return js_StringIsIndex(JSVAL_TO_STRING(id), indexp);
}
extern js::Class js_ArrayClass, js_SlowArrayClass;
inline bool inline bool
JSObject::isDenseArray() const JSObject::isDenseArray() const
@ -112,7 +147,7 @@ extern JSObject * JS_FASTCALL
js_NewArrayWithSlots(JSContext* cx, JSObject* proto, uint32 len); js_NewArrayWithSlots(JSContext* cx, JSObject* proto, uint32 len);
extern JSObject * extern JSObject *
js_NewArrayObject(JSContext *cx, jsuint length, const jsval *vector, bool holey = false); js_NewArrayObject(JSContext *cx, jsuint length, const js::Value *vector, bool holey = false);
/* Create an array object that starts out already made slow/sparse. */ /* Create an array object that starts out already made slow/sparse. */
extern JSObject * extern JSObject *
@ -145,25 +180,33 @@ js_IsArrayLike(JSContext *cx, JSObject *obj, JSBool *answerp, jsuint *lengthp);
*/ */
typedef JSBool (*JSComparator)(void *arg, const void *a, const void *b, typedef JSBool (*JSComparator)(void *arg, const void *a, const void *b,
int *result); int *result);
enum JSMergeSortElemType {
JS_SORTING_VALUES,
JS_SORTING_GENERIC
};
/* /*
* NB: vec is the array to be sorted, tmp is temporary space at least as big * NB: vec is the array to be sorted, tmp is temporary space at least as big
* as vec. Both should be GC-rooted if appropriate. * as vec. Both should be GC-rooted if appropriate.
* *
* isValue should true iff vec points to an array of js::Value
*
* The sorted result is in vec. vec may be in an inconsistent state if the * The sorted result is in vec. vec may be in an inconsistent state if the
* comparator function cmp returns an error inside a comparison, so remember * comparator function cmp returns an error inside a comparison, so remember
* to check the return value of this function. * to check the return value of this function.
*/ */
extern JSBool extern bool
js_MergeSort(void *vec, size_t nel, size_t elsize, JSComparator cmp, js_MergeSort(void *vec, size_t nel, size_t elsize, JSComparator cmp,
void *arg, void *tmp); void *arg, void *tmp, JSMergeSortElemType elemType);
#ifdef DEBUG_ARRAYS #ifdef DEBUG_ARRAYS
extern JSBool extern JSBool
js_ArrayInfo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); js_ArrayInfo(JSContext *cx, JSObject *obj, uintN argc, js::Value *argv, js::Value *rval);
#endif #endif
extern JSBool JS_FASTCALL extern JSBool
js_ArrayCompPush(JSContext *cx, JSObject *obj, jsval v); js_ArrayCompPush(JSContext *cx, JSObject *obj, const js::Value &vp);
/* /*
* Fast dense-array-to-buffer conversion for use by canvas. * Fast dense-array-to-buffer conversion for use by canvas.
@ -192,12 +235,12 @@ js_PrototypeHasIndexedProperties(JSContext *cx, JSObject *obj);
* Utility to access the value from the id returned by array_lookupProperty. * Utility to access the value from the id returned by array_lookupProperty.
*/ */
JSBool JSBool
js_GetDenseArrayElementValue(JSContext *cx, JSObject *obj, JSProperty *prop, js_GetDenseArrayElementValue(JSContext *cx, JSObject *obj, jsid id,
jsval *vp); js::Value *vp);
/* Array constructor native. Exposed only so the JIT can know its address. */ /* Array constructor native. Exposed only so the JIT can know its address. */
JSBool JSBool
js_Array(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval); js_Array(JSContext* cx, JSObject* obj, uintN argc, js::Value* argv, js::Value* rval);
/* /*
* Friend api function that allows direct creation of an array object with a * Friend api function that allows direct creation of an array object with a
@ -209,9 +252,14 @@ js_Array(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval);
* without triggering GC (so this method is allowed to leave those * without triggering GC (so this method is allowed to leave those
* uninitialized) and to set them to non-JSVAL_HOLE values, so that the * uninitialized) and to set them to non-JSVAL_HOLE values, so that the
* resulting array has length and count both equal to |capacity|. * resulting array has length and count both equal to |capacity|.
*
* FIXME: for some strange reason, when this file is included from
* dom/ipc/TabParent.cpp in MSVC, jsuint resolves to a slightly different
* builtin than when mozjs.dll is built, resulting in a link error in xul.dll.
* It would be useful to find out what is causing this insanity.
*/ */
JS_FRIEND_API(JSObject *) JS_FRIEND_API(JSObject *)
js_NewArrayObjectWithCapacity(JSContext *cx, jsuint capacity, jsval **vector); js_NewArrayObjectWithCapacity(JSContext *cx, uint32_t capacity, jsval **vector);
/* /*
* Makes a fast clone of a dense array as long as the array only contains * Makes a fast clone of a dense array as long as the array only contains
@ -233,6 +281,4 @@ js_CloneDensePrimitiveArray(JSContext *cx, JSObject *obj, JSObject **clone);
JS_FRIEND_API(JSBool) JS_FRIEND_API(JSBool)
js_IsDensePrimitiveArray(JSObject *obj); js_IsDensePrimitiveArray(JSObject *obj);
JS_END_EXTERN_C
#endif /* jsarray_h___ */ #endif /* jsarray_h___ */

Просмотреть файл

@ -58,7 +58,13 @@
#include "jsscan.h" #include "jsscan.h"
#include "jsstr.h" #include "jsstr.h"
#include "jsversion.h" #include "jsversion.h"
#include "jsxml.h"
#include "jsstrinlines.h" #include "jsstrinlines.h"
#include "jsatominlines.h"
#include "jsobjinlines.h"
using namespace js;
using namespace js; using namespace js;
@ -87,7 +93,7 @@ JS_STATIC_ASSERT((1 + 2) * sizeof(JSAtom *) ==
const char * const char *
js_AtomToPrintableString(JSContext *cx, JSAtom *atom) js_AtomToPrintableString(JSContext *cx, JSAtom *atom)
{ {
return js_ValueToPrintableString(cx, ATOM_KEY(atom)); return js_ValueToPrintableString(cx, StringValue(ATOM_TO_STRING(atom)));
} }
#define JS_PROTO(name,code,init) const char js_##name##_str[] = #name; #define JS_PROTO(name,code,init) const char js_##name##_str[] = #name;
@ -292,9 +298,9 @@ const char js_current_str[] = "current";
#endif #endif
/* /*
* JSAtomState.doubleAtoms and JSAtomState.stringAtoms hashtable entry. To * JSAtomState.stringAtoms hashtable entry. To support pinned and interned
* support pinned and interned string atoms, we use the lowest bits of the * string atoms, we use the lowest bits of the keyAndFlags field to store
* keyAndFlags field to store ATOM_PINNED and ATOM_INTERNED flags. * ATOM_PINNED and ATOM_INTERNED flags.
*/ */
typedef struct JSAtomHashEntry { typedef struct JSAtomHashEntry {
JSDHashEntryHdr hdr; JSDHashEntryHdr hdr;
@ -303,14 +309,14 @@ typedef struct JSAtomHashEntry {
#define ATOM_ENTRY_FLAG_MASK (ATOM_PINNED | ATOM_INTERNED) #define ATOM_ENTRY_FLAG_MASK (ATOM_PINNED | ATOM_INTERNED)
JS_STATIC_ASSERT(ATOM_ENTRY_FLAG_MASK < JSVAL_ALIGN); JS_STATIC_ASSERT(ATOM_ENTRY_FLAG_MASK < JS_GCTHING_ALIGN);
/* /*
* Helper macros to access and modify JSAtomHashEntry. * Helper macros to access and modify JSAtomHashEntry.
*/ */
#define TO_ATOM_ENTRY(hdr) ((JSAtomHashEntry *) hdr) #define TO_ATOM_ENTRY(hdr) ((JSAtomHashEntry *) hdr)
#define ATOM_ENTRY_KEY(entry) \ #define ATOM_ENTRY_KEY(entry) \
((void *)((entry)->keyAndFlags & ~ATOM_ENTRY_FLAG_MASK)) ((JSString *)((entry)->keyAndFlags & ~ATOM_ENTRY_FLAG_MASK))
#define ATOM_ENTRY_FLAGS(entry) \ #define ATOM_ENTRY_FLAGS(entry) \
((uintN)((entry)->keyAndFlags & ATOM_ENTRY_FLAG_MASK)) ((uintN)((entry)->keyAndFlags & ATOM_ENTRY_FLAG_MASK))
#define INIT_ATOM_ENTRY(entry, key) \ #define INIT_ATOM_ENTRY(entry, key) \
@ -320,29 +326,12 @@ JS_STATIC_ASSERT(ATOM_ENTRY_FLAG_MASK < JSVAL_ALIGN);
#define CLEAR_ATOM_ENTRY_FLAGS(entry, flags) \ #define CLEAR_ATOM_ENTRY_FLAGS(entry, flags) \
((void)((entry)->keyAndFlags &= ~(jsuword)(flags))) ((void)((entry)->keyAndFlags &= ~(jsuword)(flags)))
static JSDHashNumber
HashDouble(JSDHashTable *table, const void *key);
static JSBool
MatchDouble(JSDHashTable *table, const JSDHashEntryHdr *hdr, const void *key);
static JSDHashNumber static JSDHashNumber
HashString(JSDHashTable *table, const void *key); HashString(JSDHashTable *table, const void *key);
static JSBool static JSBool
MatchString(JSDHashTable *table, const JSDHashEntryHdr *hdr, const void *key); MatchString(JSDHashTable *table, const JSDHashEntryHdr *hdr, const void *key);
static const JSDHashTableOps DoubleHashOps = {
JS_DHashAllocTable,
JS_DHashFreeTable,
HashDouble,
MatchDouble,
JS_DHashMoveEntryStub,
JS_DHashClearEntryStub,
JS_DHashFinalizeStub,
NULL
};
static const JSDHashTableOps StringHashOps = { static const JSDHashTableOps StringHashOps = {
JS_DHashAllocTable, JS_DHashAllocTable,
JS_DHashFreeTable, JS_DHashFreeTable,
@ -354,55 +343,19 @@ static const JSDHashTableOps StringHashOps = {
NULL NULL
}; };
#define IS_DOUBLE_TABLE(table) ((table)->ops == &DoubleHashOps) #define IS_INITIALIZED_STATE(state) ((state)->stringAtoms.ops != NULL)
#define IS_STRING_TABLE(table) ((table)->ops == &StringHashOps)
#define IS_INITIALIZED_STATE(state) IS_DOUBLE_TABLE(&(state)->doubleAtoms)
static JSDHashNumber
HashDouble(JSDHashTable *table, const void *key)
{
JS_ASSERT(IS_DOUBLE_TABLE(table));
return JS_HASH_DOUBLE(*(jsdouble *)key);
}
static JSDHashNumber static JSDHashNumber
HashString(JSDHashTable *table, const void *key) HashString(JSDHashTable *table, const void *key)
{ {
JS_ASSERT(IS_STRING_TABLE(table));
return js_HashString((JSString *)key); return js_HashString((JSString *)key);
} }
static JSBool
MatchDouble(JSDHashTable *table, const JSDHashEntryHdr *hdr, const void *key)
{
JSAtomHashEntry *entry = TO_ATOM_ENTRY(hdr);
jsdouble d1, d2;
JS_ASSERT(IS_DOUBLE_TABLE(table));
if (entry->keyAndFlags == 0) {
/* See comments in MatchString. */
return JS_FALSE;
}
d1 = *(jsdouble *)ATOM_ENTRY_KEY(entry);
d2 = *(jsdouble *)key;
if (JSDOUBLE_IS_NaN(d1))
return JSDOUBLE_IS_NaN(d2);
#if defined(XP_WIN)
/* XXX MSVC miscompiles such that (NaN == 0) */
if (JSDOUBLE_IS_NaN(d2))
return JS_FALSE;
#endif
return d1 == d2;
}
static JSBool static JSBool
MatchString(JSDHashTable *table, const JSDHashEntryHdr *hdr, const void *key) MatchString(JSDHashTable *table, const JSDHashEntryHdr *hdr, const void *key)
{ {
JSAtomHashEntry *entry = TO_ATOM_ENTRY(hdr); JSAtomHashEntry *entry = TO_ATOM_ENTRY(hdr);
JS_ASSERT(IS_STRING_TABLE(table));
if (entry->keyAndFlags == 0) { if (entry->keyAndFlags == 0) {
/* /*
* This happens when js_AtomizeString adds a new hash entry and * This happens when js_AtomizeString adds a new hash entry and
@ -418,7 +371,7 @@ MatchString(JSDHashTable *table, const JSDHashEntryHdr *hdr, const void *key)
*/ */
return JS_FALSE; return JS_FALSE;
} }
return js_EqualStrings((JSString *)ATOM_ENTRY_KEY(entry), (JSString *)key); return js_EqualStrings(ATOM_ENTRY_KEY(entry), (JSString *)key);
} }
/* /*
@ -428,7 +381,6 @@ MatchString(JSDHashTable *table, const JSDHashEntryHdr *hdr, const void *key)
* atomized strings with just 1K entries. * atomized strings with just 1K entries.
*/ */
#define JS_STRING_HASH_COUNT 1024 #define JS_STRING_HASH_COUNT 1024
#define JS_DOUBLE_HASH_COUNT 64
JSBool JSBool
js_InitAtomState(JSRuntime *rt) js_InitAtomState(JSRuntime *rt)
@ -439,7 +391,6 @@ js_InitAtomState(JSRuntime *rt)
* The caller must zero the state before calling this function. * The caller must zero the state before calling this function.
*/ */
JS_ASSERT(!state->stringAtoms.ops); JS_ASSERT(!state->stringAtoms.ops);
JS_ASSERT(!state->doubleAtoms.ops);
if (!JS_DHashTableInit(&state->stringAtoms, &StringHashOps, if (!JS_DHashTableInit(&state->stringAtoms, &StringHashOps,
NULL, sizeof(JSAtomHashEntry), NULL, sizeof(JSAtomHashEntry),
@ -447,17 +398,6 @@ js_InitAtomState(JSRuntime *rt)
state->stringAtoms.ops = NULL; state->stringAtoms.ops = NULL;
return JS_FALSE; return JS_FALSE;
} }
JS_ASSERT(IS_STRING_TABLE(&state->stringAtoms));
if (!JS_DHashTableInit(&state->doubleAtoms, &DoubleHashOps,
NULL, sizeof(JSAtomHashEntry),
JS_DHASH_DEFAULT_CAPACITY(JS_DOUBLE_HASH_COUNT))) {
state->doubleAtoms.ops = NULL;
JS_DHashTableFinish(&state->stringAtoms);
state->stringAtoms.ops = NULL;
return JS_FALSE;
}
JS_ASSERT(IS_DOUBLE_TABLE(&state->doubleAtoms));
#ifdef JS_THREADSAFE #ifdef JS_THREADSAFE
js_InitLock(&state->lock); js_InitLock(&state->lock);
@ -478,9 +418,8 @@ js_string_uninterner(JSDHashTable *table, JSDHashEntryHdr *hdr,
* Any string entry that remains at this point must be initialized, as the * Any string entry that remains at this point must be initialized, as the
* last GC should clean any uninitialized ones. * last GC should clean any uninitialized ones.
*/ */
JS_ASSERT(IS_STRING_TABLE(table));
JS_ASSERT(entry->keyAndFlags != 0); JS_ASSERT(entry->keyAndFlags != 0);
str = (JSString *)ATOM_ENTRY_KEY(entry); str = ATOM_ENTRY_KEY(entry);
js_FinalizeStringRT(rt, str); js_FinalizeStringRT(rt, str);
return JS_DHASH_NEXT; return JS_DHASH_NEXT;
@ -501,7 +440,6 @@ js_FinishAtomState(JSRuntime *rt)
JS_DHashTableEnumerate(&state->stringAtoms, js_string_uninterner, rt); JS_DHashTableEnumerate(&state->stringAtoms, js_string_uninterner, rt);
JS_DHashTableFinish(&state->stringAtoms); JS_DHashTableFinish(&state->stringAtoms);
JS_DHashTableFinish(&state->doubleAtoms);
#ifdef JS_THREADSAFE #ifdef JS_THREADSAFE
js_FinishLock(&state->lock); js_FinishLock(&state->lock);
@ -536,7 +474,6 @@ static JSDHashOperator
js_atom_unpinner(JSDHashTable *table, JSDHashEntryHdr *hdr, js_atom_unpinner(JSDHashTable *table, JSDHashEntryHdr *hdr,
uint32 number, void *arg) uint32 number, void *arg)
{ {
JS_ASSERT(IS_STRING_TABLE(table));
CLEAR_ATOM_ENTRY_FLAGS(TO_ATOM_ENTRY(hdr), ATOM_PINNED); CLEAR_ATOM_ENTRY_FLAGS(TO_ATOM_ENTRY(hdr), ATOM_PINNED);
return JS_DHASH_NEXT; return JS_DHASH_NEXT;
} }
@ -565,8 +502,7 @@ js_locked_atom_tracer(JSDHashTable *table, JSDHashEntryHdr *hdr,
return JS_DHASH_NEXT; return JS_DHASH_NEXT;
} }
JS_SET_TRACING_INDEX(trc, "locked_atom", (size_t)number); JS_SET_TRACING_INDEX(trc, "locked_atom", (size_t)number);
js_CallGCMarker(trc, ATOM_ENTRY_KEY(entry), Mark(trc, ATOM_ENTRY_KEY(entry), JSTRACE_STRING);
IS_STRING_TABLE(table) ? JSTRACE_STRING : JSTRACE_DOUBLE);
return JS_DHASH_NEXT; return JS_DHASH_NEXT;
} }
@ -578,14 +514,13 @@ js_pinned_atom_tracer(JSDHashTable *table, JSDHashEntryHdr *hdr,
JSTracer *trc = (JSTracer *)arg; JSTracer *trc = (JSTracer *)arg;
uintN flags = ATOM_ENTRY_FLAGS(entry); uintN flags = ATOM_ENTRY_FLAGS(entry);
JS_ASSERT(IS_STRING_TABLE(table));
if (flags & (ATOM_PINNED | ATOM_INTERNED)) { if (flags & (ATOM_PINNED | ATOM_INTERNED)) {
JS_SET_TRACING_INDEX(trc, JS_SET_TRACING_INDEX(trc,
flags & ATOM_PINNED flags & ATOM_PINNED
? "pinned_atom" ? "pinned_atom"
: "interned_atom", : "interned_atom",
(size_t)number); (size_t)number);
js_CallGCMarker(trc, ATOM_ENTRY_KEY(entry), JSTRACE_STRING); Mark(trc, ATOM_ENTRY_KEY(entry), JSTRACE_STRING);
} }
return JS_DHASH_NEXT; return JS_DHASH_NEXT;
} }
@ -596,13 +531,11 @@ js_TraceAtomState(JSTracer *trc)
JSRuntime *rt = trc->context->runtime; JSRuntime *rt = trc->context->runtime;
JSAtomState *state = &rt->atomState; JSAtomState *state = &rt->atomState;
if (rt->gcKeepAtoms) { if (rt->gcKeepAtoms)
JS_DHashTableEnumerate(&state->doubleAtoms, js_locked_atom_tracer, trc);
JS_DHashTableEnumerate(&state->stringAtoms, js_locked_atom_tracer, trc); JS_DHashTableEnumerate(&state->stringAtoms, js_locked_atom_tracer, trc);
} else { else
JS_DHashTableEnumerate(&state->stringAtoms, js_pinned_atom_tracer, trc); JS_DHashTableEnumerate(&state->stringAtoms, js_pinned_atom_tracer, trc);
} }
}
static JSDHashOperator static JSDHashOperator
js_atom_sweeper(JSDHashTable *table, JSDHashEntryHdr *hdr, js_atom_sweeper(JSDHashTable *table, JSDHashEntryHdr *hdr,
@ -629,74 +562,19 @@ js_SweepAtomState(JSContext *cx)
{ {
JSAtomState *state = &cx->runtime->atomState; JSAtomState *state = &cx->runtime->atomState;
JS_DHashTableEnumerate(&state->doubleAtoms, js_atom_sweeper, NULL);
JS_DHashTableEnumerate(&state->stringAtoms, js_atom_sweeper, NULL); JS_DHashTableEnumerate(&state->stringAtoms, js_atom_sweeper, NULL);
/* /*
* Optimize for simplicity and mutate table generation numbers even if the * Optimize for simplicity and mutate table generation numbers even if the
* sweeper has not removed any entries. * sweeper has not removed any entries.
*/ */
state->doubleAtoms.generation++;
state->stringAtoms.generation++; state->stringAtoms.generation++;
} }
JSAtom *
js_AtomizeDouble(JSContext *cx, jsdouble d)
{
JSAtomState *state;
JSDHashTable *table;
JSAtomHashEntry *entry;
uint32 gen;
jsdouble *key;
jsval v;
state = &cx->runtime->atomState;
table = &state->doubleAtoms;
JS_LOCK(cx, &state->lock);
entry = TO_ATOM_ENTRY(JS_DHashTableOperate(table, &d, JS_DHASH_ADD));
if (!entry)
goto failed_hash_add;
if (entry->keyAndFlags == 0) {
gen = ++table->generation;
JS_UNLOCK(cx, &state->lock);
key = js_NewWeaklyRootedDouble(cx, d);
if (!key)
return NULL;
JS_LOCK(cx, &state->lock);
if (table->generation == gen) {
JS_ASSERT(entry->keyAndFlags == 0);
} else {
entry = TO_ATOM_ENTRY(JS_DHashTableOperate(table, key,
JS_DHASH_ADD));
if (!entry)
goto failed_hash_add;
if (entry->keyAndFlags != 0)
goto finish;
++table->generation;
}
INIT_ATOM_ENTRY(entry, key);
}
finish:
v = DOUBLE_TO_JSVAL((jsdouble *)ATOM_ENTRY_KEY(entry));
cx->weakRoots.lastAtom = v;
JS_UNLOCK(cx, &state->lock);
return (JSAtom *)v;
failed_hash_add:
JS_UNLOCK(cx, &state->lock);
JS_ReportOutOfMemory(cx);
return NULL;
}
JSAtom * JSAtom *
js_AtomizeString(JSContext *cx, JSString *str, uintN flags) js_AtomizeString(JSContext *cx, JSString *str, uintN flags)
{ {
jsval v; JSAtom *atom;
JSAtomState *state; JSAtomState *state;
JSDHashTable *table; JSDHashTable *table;
JSAtomHashEntry *entry; JSAtomHashEntry *entry;
@ -707,13 +585,13 @@ js_AtomizeString(JSContext *cx, JSString *str, uintN flags)
JS_ASSERT_IF(flags & ATOM_NOCOPY, flags & ATOM_TMPSTR); JS_ASSERT_IF(flags & ATOM_NOCOPY, flags & ATOM_TMPSTR);
if (str->isAtomized()) if (str->isAtomized())
return (JSAtom *) STRING_TO_JSVAL(str); return STRING_TO_ATOM(str);
size_t length = str->length(); size_t length = str->length();
if (length == 1) { if (length == 1) {
jschar c = str->chars()[0]; jschar c = str->chars()[0];
if (c < UNIT_STRING_LIMIT) if (c < UNIT_STRING_LIMIT)
return (JSAtom *) STRING_TO_JSVAL(JSString::unitString(c)); return STRING_TO_ATOM(JSString::unitString(c));
} }
/* /*
@ -734,7 +612,7 @@ js_AtomizeString(JSContext *cx, JSString *str, uintN flags)
if (length == 3) if (length == 3)
i = i * 10 + chars[2] - '0'; i = i * 10 + chars[2] - '0';
if (jsuint(i) < INT_STRING_LIMIT) if (jsuint(i) < INT_STRING_LIMIT)
return (JSAtom *) STRING_TO_JSVAL(JSString::intString(i)); return STRING_TO_ATOM(JSString::intString(i));
} }
} }
@ -746,7 +624,7 @@ js_AtomizeString(JSContext *cx, JSString *str, uintN flags)
if (!entry) if (!entry)
goto failed_hash_add; goto failed_hash_add;
if (entry->keyAndFlags != 0) { if (entry->keyAndFlags != 0) {
key = (JSString *)ATOM_ENTRY_KEY(entry); key = ATOM_ENTRY_KEY(entry);
} else { } else {
/* /*
* We created a new hashtable entry. Unless str is already allocated * We created a new hashtable entry. Unless str is already allocated
@ -791,7 +669,7 @@ js_AtomizeString(JSContext *cx, JSString *str, uintN flags)
if (!entry) if (!entry)
goto failed_hash_add; goto failed_hash_add;
if (entry->keyAndFlags != 0) { if (entry->keyAndFlags != 0) {
key = (JSString *)ATOM_ENTRY_KEY(entry); key = ATOM_ENTRY_KEY(entry);
goto finish; goto finish;
} }
++table->generation; ++table->generation;
@ -804,10 +682,10 @@ js_AtomizeString(JSContext *cx, JSString *str, uintN flags)
finish: finish:
ADD_ATOM_ENTRY_FLAGS(entry, flags & (ATOM_PINNED | ATOM_INTERNED)); ADD_ATOM_ENTRY_FLAGS(entry, flags & (ATOM_PINNED | ATOM_INTERNED));
JS_ASSERT(key->isAtomized()); JS_ASSERT(key->isAtomized());
v = STRING_TO_JSVAL(key); atom = STRING_TO_ATOM(key);
cx->weakRoots.lastAtom = v; cx->weakRoots.lastAtom = atom;
JS_UNLOCK(cx, &state->lock); JS_UNLOCK(cx, &state->lock);
return (JSAtom *)v; return atom;
failed_hash_add: failed_hash_add:
JS_UNLOCK(cx, &state->lock); JS_UNLOCK(cx, &state->lock);
@ -874,7 +752,7 @@ js_GetExistingStringAtom(JSContext *cx, const jschar *chars, size_t length)
if (length == 1) { if (length == 1) {
jschar c = *chars; jschar c = *chars;
if (c < UNIT_STRING_LIMIT) if (c < UNIT_STRING_LIMIT)
return (JSAtom *) STRING_TO_JSVAL(JSString::unitString(c)); return STRING_TO_ATOM(JSString::unitString(c));
} }
str.initFlat((jschar *)chars, length); str.initFlat((jschar *)chars, length);
@ -883,33 +761,11 @@ js_GetExistingStringAtom(JSContext *cx, const jschar *chars, size_t length)
JS_LOCK(cx, &state->lock); JS_LOCK(cx, &state->lock);
hdr = JS_DHashTableOperate(&state->stringAtoms, &str, JS_DHASH_LOOKUP); hdr = JS_DHashTableOperate(&state->stringAtoms, &str, JS_DHASH_LOOKUP);
str2 = JS_DHASH_ENTRY_IS_BUSY(hdr) str2 = JS_DHASH_ENTRY_IS_BUSY(hdr)
? (JSString *)ATOM_ENTRY_KEY(TO_ATOM_ENTRY(hdr)) ? ATOM_ENTRY_KEY(TO_ATOM_ENTRY(hdr))
: NULL; : NULL;
JS_UNLOCK(cx, &state->lock); JS_UNLOCK(cx, &state->lock);
return str2 ? (JSAtom *)STRING_TO_JSVAL(str2) : NULL; return str2 ? STRING_TO_ATOM(str2) : NULL;
}
JSBool
js_AtomizePrimitiveValue(JSContext *cx, jsval v, JSAtom **atomp)
{
JSAtom *atom;
if (JSVAL_IS_STRING(v)) {
atom = js_AtomizeString(cx, JSVAL_TO_STRING(v), 0);
if (!atom)
return JS_FALSE;
} else if (JSVAL_IS_DOUBLE(v)) {
atom = js_AtomizeDouble(cx, *JSVAL_TO_DOUBLE(v));
if (!atom)
return JS_FALSE;
} else {
JS_ASSERT(JSVAL_IS_INT(v) || JSVAL_IS_BOOLEAN(v) ||
JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v));
atom = (JSAtom *)v;
}
*atomp = atom;
return JS_TRUE;
} }
#ifdef DEBUG #ifdef DEBUG
@ -920,7 +776,7 @@ atom_dumper(JSDHashTable *table, JSDHashEntryHdr *hdr,
{ {
JSAtomHashEntry *entry = TO_ATOM_ENTRY(hdr); JSAtomHashEntry *entry = TO_ATOM_ENTRY(hdr);
FILE *fp = (FILE *)arg; FILE *fp = (FILE *)arg;
void *key; JSString *key;
uintN flags; uintN flags;
fprintf(fp, "%3u %08x ", number, (uintN)entry->hdr.keyHash); fprintf(fp, "%3u %08x ", number, (uintN)entry->hdr.keyHash);
@ -928,12 +784,7 @@ atom_dumper(JSDHashTable *table, JSDHashEntryHdr *hdr,
fputs("<uninitialized>", fp); fputs("<uninitialized>", fp);
} else { } else {
key = ATOM_ENTRY_KEY(entry); key = ATOM_ENTRY_KEY(entry);
if (IS_DOUBLE_TABLE(table)) { js_FileEscapedString(fp, key, '"');
fprintf(fp, "%.16g", *(jsdouble *)key);
} else {
JS_ASSERT(IS_STRING_TABLE(table));
js_FileEscapedString(fp, (JSString *)key, '"');
}
flags = ATOM_ENTRY_FLAGS(entry); flags = ATOM_ENTRY_FLAGS(entry);
if (flags != 0) { if (flags != 0) {
fputs((flags & (ATOM_PINNED | ATOM_INTERNED)) fputs((flags & (ATOM_PINNED | ATOM_INTERNED))
@ -959,7 +810,6 @@ js_DumpAtoms(JSContext *cx, FILE *fp)
putc('\n', fp); putc('\n', fp);
fprintf(fp, "doubleAtoms table contents:\n"); fprintf(fp, "doubleAtoms table contents:\n");
JS_DHashTableEnumerate(&state->doubleAtoms, atom_dumper, fp);
#ifdef JS_DHASHMETER #ifdef JS_DHASHMETER
JS_DHashTableDumpMeter(&state->doubleAtoms, atom_dumper, fp); JS_DHashTableDumpMeter(&state->doubleAtoms, atom_dumper, fp);
#endif #endif
@ -1296,3 +1146,49 @@ js_InitAtomMap(JSContext *cx, JSAtomMap *map, JSAtomList *al)
} }
al->clear(); al->clear();
} }
#if JS_HAS_XML_SUPPORT
bool
js_InternNonIntElementIdSlow(JSContext *cx, JSObject *obj, const Value &idval,
jsid *idp)
{
JS_ASSERT(idval.isObject());
if (obj->isXML()) {
*idp = OBJECT_TO_JSID(&idval.toObject());
return true;
}
if (!js_IsFunctionQName(cx, &idval.toObject(), idp))
return JS_FALSE;
if (!JSID_IS_VOID(*idp))
return true;
return js_ValueToStringId(cx, idval, idp);
}
bool
js_InternNonIntElementIdSlow(JSContext *cx, JSObject *obj, const Value &idval,
jsid *idp, Value *vp)
{
JS_ASSERT(idval.isObject());
if (obj->isXML()) {
JSObject &idobj = idval.toObject();
*idp = OBJECT_TO_JSID(&idobj);
vp->setObject(idobj);
return true;
}
if (!js_IsFunctionQName(cx, &idval.toObject(), idp))
return JS_FALSE;
if (!JSID_IS_VOID(*idp)) {
*vp = IdToValue(*idp);
return true;
}
if (js_ValueToStringId(cx, idval, idp)) {
vp->setString(JSID_TO_STRING(*idp));
return true;
}
return false;
}
#endif

Просмотреть файл

@ -51,19 +51,76 @@
#include "jsprvtd.h" #include "jsprvtd.h"
#include "jspubtd.h" #include "jspubtd.h"
#include "jslock.h" #include "jslock.h"
#include "jsvalue.h"
JS_BEGIN_EXTERN_C
#define ATOM_PINNED 0x1 /* atom is pinned against GC */ #define ATOM_PINNED 0x1 /* atom is pinned against GC */
#define ATOM_INTERNED 0x2 /* pinned variant for JS_Intern* API */ #define ATOM_INTERNED 0x2 /* pinned variant for JS_Intern* API */
#define ATOM_NOCOPY 0x4 /* don't copy atom string bytes */ #define ATOM_NOCOPY 0x4 /* don't copy atom string bytes */
#define ATOM_TMPSTR 0x8 /* internal, to avoid extra string */ #define ATOM_TMPSTR 0x8 /* internal, to avoid extra string */
#define ATOM_KEY(atom) ((jsval)(atom)) #define STRING_TO_ATOM(str) (JS_ASSERT(str->isAtomized()), \
#define ATOM_IS_DOUBLE(atom) JSVAL_IS_DOUBLE(ATOM_KEY(atom)) (JSAtom *)str)
#define ATOM_TO_DOUBLE(atom) JSVAL_TO_DOUBLE(ATOM_KEY(atom)) #define ATOM_TO_STRING(atom) ((JSString *)atom)
#define ATOM_IS_STRING(atom) JSVAL_IS_STRING(ATOM_KEY(atom)) #define ATOM_TO_JSVAL(atom) STRING_TO_JSVAL(ATOM_TO_STRING(atom))
#define ATOM_TO_STRING(atom) JSVAL_TO_STRING(ATOM_KEY(atom))
/* Engine-internal extensions of jsid */
static JS_ALWAYS_INLINE jsid
JSID_FROM_BITS(size_t bits)
{
jsid id;
JSID_BITS(id) = bits;
return id;
}
static JS_ALWAYS_INLINE jsid
ATOM_TO_JSID(JSAtom *atom)
{
JS_ASSERT(((size_t)atom & 0x7) == 0);
return JSID_FROM_BITS((size_t)atom);
}
/* All strings stored in jsids are atomized. */
static JS_ALWAYS_INLINE JSBool
JSID_IS_ATOM(jsid id)
{
return JSID_IS_STRING(id);
}
static JS_ALWAYS_INLINE JSBool
JSID_IS_ATOM(jsid id, JSAtom *atom)
{
return JSID_BITS(id) == JSID_BITS(ATOM_TO_JSID(atom));
}
static JS_ALWAYS_INLINE JSAtom *
JSID_TO_ATOM(jsid id)
{
return (JSAtom *)JSID_TO_STRING(id);
}
namespace js {
static JS_ALWAYS_INLINE Value
IdToValue(jsid id)
{
if (JSID_IS_STRING(id))
return StringValue(JSID_TO_STRING(id));
if (JS_LIKELY(JSID_IS_INT(id)))
return Int32Value(JSID_TO_INT(id));
if (JS_LIKELY(JSID_IS_OBJECT(id)))
return ObjectValue(*JSID_TO_OBJECT(id));
JS_ASSERT(JSID_IS_DEFAULT_XML_NAMESPACE(id) || JSID_IS_VOID(id));
return UndefinedValue();
}
static JS_ALWAYS_INLINE jsval
IdToJsval(jsid id)
{
return Jsvalify(IdToValue(id));
}
}
#if JS_BYTES_PER_WORD == 4 #if JS_BYTES_PER_WORD == 4
# define ATOM_HASH(atom) ((JSHashNumber)(atom) >> 2) # define ATOM_HASH(atom) ((JSHashNumber)(atom) >> 2)
@ -88,7 +145,7 @@ struct JSAtomListElement {
#define ALE_ATOM(ale) ((JSAtom *) (ale)->entry.key) #define ALE_ATOM(ale) ((JSAtom *) (ale)->entry.key)
#define ALE_INDEX(ale) (jsatomid(uintptr_t((ale)->entry.value))) #define ALE_INDEX(ale) (jsatomid(uintptr_t((ale)->entry.value)))
#define ALE_VALUE(ale) ((jsval) (ale)->entry.value) #define ALE_VALUE(ale) ((jsboxedword) (ale)->entry.value)
#define ALE_NEXT(ale) ((JSAtomListElement *) (ale)->entry.next) #define ALE_NEXT(ale) ((JSAtomListElement *) (ale)->entry.next)
/* /*
@ -119,8 +176,6 @@ struct JSAtomSet {
jsuint count; /* count of indexed literals */ jsuint count; /* count of indexed literals */
}; };
#ifdef __cplusplus
struct JSAtomList : public JSAtomSet struct JSAtomList : public JSAtomSet
{ {
#ifdef DEBUG #ifdef DEBUG
@ -198,8 +253,6 @@ class JSAtomListIterator {
JSAtomListElement* operator ()(); JSAtomListElement* operator ()();
}; };
#endif /* __cplusplus */
struct JSAtomMap { struct JSAtomMap {
JSAtom **vector; /* array of ptrs to indexed atoms */ JSAtom **vector; /* array of ptrs to indexed atoms */
jsatomid length; /* count of (to-be-)indexed atoms */ jsatomid length; /* count of (to-be-)indexed atoms */
@ -207,7 +260,6 @@ struct JSAtomMap {
struct JSAtomState { struct JSAtomState {
JSDHashTable stringAtoms; /* hash table with shared strings */ JSDHashTable stringAtoms; /* hash table with shared strings */
JSDHashTable doubleAtoms; /* hash table with shared doubles */
#ifdef JS_THREADSAFE #ifdef JS_THREADSAFE
JSThinLock lock; JSThinLock lock;
#endif #endif
@ -483,13 +535,6 @@ js_InitCommonAtoms(JSContext *cx);
extern void extern void
js_FinishCommonAtoms(JSContext *cx); js_FinishCommonAtoms(JSContext *cx);
/*
* Find or create the atom for a double value. Return null on failure to
* allocate memory.
*/
extern JSAtom *
js_AtomizeDouble(JSContext *cx, jsdouble d);
/* /*
* Find or create the atom for a string. Return null on failure to allocate * Find or create the atom for a string. Return null on failure to allocate
* memory. * memory.
@ -510,12 +555,6 @@ js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags);
extern JSAtom * extern JSAtom *
js_GetExistingStringAtom(JSContext *cx, const jschar *chars, size_t length); js_GetExistingStringAtom(JSContext *cx, const jschar *chars, size_t length);
/*
* This variant handles all primitive values.
*/
JSBool
js_AtomizePrimitiveValue(JSContext *cx, jsval v, JSAtom **atomp);
#ifdef DEBUG #ifdef DEBUG
extern JS_FRIEND_API(void) extern JS_FRIEND_API(void)
@ -523,6 +562,18 @@ js_DumpAtoms(JSContext *cx, FILE *fp);
#endif #endif
inline bool
js_ValueToAtom(JSContext *cx, const js::Value &v, JSAtom **atomp);
inline bool
js_ValueToStringId(JSContext *cx, const js::Value &v, jsid *idp);
inline bool
js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval,
jsid *idp);
inline bool
js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval,
jsid *idp, js::Value *vp);
/* /*
* For all unmapped atoms recorded in al, add a mapping from the atom's index * For all unmapped atoms recorded in al, add a mapping from the atom's index
* to its address. map->length must already be set to the number of atoms in * to its address. map->length must already be set to the number of atoms in
@ -531,6 +582,4 @@ js_DumpAtoms(JSContext *cx, FILE *fp);
extern void extern void
js_InitAtomMap(JSContext *cx, JSAtomMap *map, JSAtomList *al); js_InitAtomMap(JSContext *cx, JSAtomMap *map, JSAtomList *al);
JS_END_EXTERN_C
#endif /* jsatom_h___ */ #endif /* jsatom_h___ */

Просмотреть файл

@ -46,8 +46,8 @@
/* /*
* Convert v to an atomized string and wrap it as an id. * Convert v to an atomized string and wrap it as an id.
*/ */
inline JSBool inline bool
js_ValueToStringId(JSContext *cx, jsval v, jsid *idp) js_ValueToAtom(JSContext *cx, const js::Value &v, JSAtom **atomp)
{ {
JSString *str; JSString *str;
JSAtom *atom; JSAtom *atom;
@ -59,37 +59,87 @@ js_ValueToStringId(JSContext *cx, jsval v, jsid *idp)
* done in js_js_AtomizeString) ensures the caller that the resulting id at * done in js_js_AtomizeString) ensures the caller that the resulting id at
* is least weakly rooted. * is least weakly rooted.
*/ */
if (JSVAL_IS_STRING(v)) { if (v.isString()) {
str = JSVAL_TO_STRING(v); str = v.toString();
if (str->isAtomized()) { if (str->isAtomized()) {
cx->weakRoots.lastAtom = v; cx->weakRoots.lastAtom = *atomp = STRING_TO_ATOM(str);
*idp = ATOM_TO_JSID((JSAtom *) v); return true;
return JS_TRUE;
} }
} else { } else {
str = js_ValueToString(cx, v); str = js_ValueToString(cx, v);
if (!str) if (!str)
return JS_FALSE; return false;
} }
atom = js_AtomizeString(cx, str, 0); atom = js_AtomizeString(cx, str, 0);
if (!atom) if (!atom)
return JS_FALSE; return false;
*idp = ATOM_TO_JSID(atom); *atomp = atom;
return JS_TRUE; return true;
} }
inline JSBool inline bool
js_ValueToStringId(JSContext *cx, const js::Value &v, jsid *idp)
{
JSAtom *atom;
if (js_ValueToAtom(cx, v, &atom)) {
*idp = ATOM_TO_JSID(atom);
return true;
}
return false;
}
inline bool
js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval,
jsid *idp)
{
JS_ASSERT(!idval.isInt32() || !INT_FITS_IN_JSID(idval.toInt32()));
#if JS_HAS_XML_SUPPORT
extern bool js_InternNonIntElementIdSlow(JSContext *, JSObject *,
const js::Value &, jsid *);
if (idval.isObject())
return js_InternNonIntElementIdSlow(cx, obj, idval, idp);
#endif
return js_ValueToStringId(cx, idval, idp);
}
inline bool
js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval,
jsid *idp, js::Value *vp)
{
JS_ASSERT(!idval.isInt32() || !INT_FITS_IN_JSID(idval.toInt32()));
#if JS_HAS_XML_SUPPORT
extern bool js_InternNonIntElementIdSlow(JSContext *, JSObject *,
const js::Value &,
jsid *, js::Value *);
if (idval.isObject())
return js_InternNonIntElementIdSlow(cx, obj, idval, idp, vp);
#endif
JSAtom *atom;
if (js_ValueToAtom(cx, idval, &atom)) {
*idp = ATOM_TO_JSID(atom);
vp->setString(ATOM_TO_STRING(atom));
return true;
}
return false;
}
inline bool
js_Int32ToId(JSContext* cx, int32 index, jsid* id) js_Int32ToId(JSContext* cx, int32 index, jsid* id)
{ {
if (INT_FITS_IN_JSVAL(index)) { if (INT_FITS_IN_JSID(index)) {
*id = INT_TO_JSID(index); *id = INT_TO_JSID(index);
JS_ASSERT(INT_JSID_TO_JSVAL(*id) == INT_TO_JSVAL(index)); return true;
return JS_TRUE;
} }
JSString* str = js_NumberToString(cx, index); JSString* str = js_NumberToString(cx, index);
if (!str) if (!str)
return JS_FALSE; return false;
return js_ValueToStringId(cx, STRING_TO_JSVAL(str), id);
return js_ValueToStringId(cx, js::StringValue(str), id);
} }
#endif /* jsatominlines_h___ */ #endif /* jsatominlines_h___ */

Просмотреть файл

@ -56,19 +56,14 @@
#include "jsobjinlines.h" #include "jsobjinlines.h"
/* Check pseudo-booleans values. */
JS_STATIC_ASSERT(!(JSVAL_TRUE & JSVAL_HOLE_FLAG));
JS_STATIC_ASSERT(!(JSVAL_FALSE & JSVAL_HOLE_FLAG));
JS_STATIC_ASSERT(!(JSVAL_VOID & JSVAL_HOLE_FLAG));
JS_STATIC_ASSERT((JSVAL_HOLE & JSVAL_HOLE_FLAG));
JS_STATIC_ASSERT((JSVAL_HOLE & ~JSVAL_HOLE_FLAG) == JSVAL_VOID);
JS_STATIC_ASSERT(!(JSVAL_ARETURN & JSVAL_HOLE_FLAG));
JSClass js_BooleanClass = { using namespace js;
Class js_BooleanClass = {
"Boolean", "Boolean",
JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_HAS_CACHED_PROTO(JSProto_Boolean), JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_HAS_CACHED_PROTO(JSProto_Boolean),
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, PropertyStub, PropertyStub, PropertyStub, PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL, EnumerateStub, ResolveStub, ConvertStub, NULL,
JSCLASS_NO_OPTIONAL_MEMBERS JSCLASS_NO_OPTIONAL_MEMBERS
}; };
@ -76,48 +71,45 @@ JSClass js_BooleanClass = {
#include "jsprf.h" #include "jsprf.h"
static JSBool static JSBool
bool_toSource(JSContext *cx, uintN argc, jsval *vp) bool_toSource(JSContext *cx, uintN argc, Value *vp)
{ {
jsval v; const Value *primp;
char buf[32]; if (!js_GetPrimitiveThis(cx, vp, &js_BooleanClass, &primp))
JSString *str;
if (!js_GetPrimitiveThis(cx, vp, &js_BooleanClass, &v))
return JS_FALSE; return JS_FALSE;
JS_ASSERT(JSVAL_IS_BOOLEAN(v)); char buf[32];
JS_snprintf(buf, sizeof buf, "(new %s(%s))", JS_snprintf(buf, sizeof buf, "(new %s(%s))",
js_BooleanClass.name, js_BooleanClass.name,
JS_BOOLEAN_STR(JSVAL_TO_BOOLEAN(v))); JS_BOOLEAN_STR(primp->toBoolean()));
str = JS_NewStringCopyZ(cx, buf); JSString *str = JS_NewStringCopyZ(cx, buf);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
*vp = STRING_TO_JSVAL(str); vp->setString(str);
return JS_TRUE; return JS_TRUE;
} }
#endif #endif
static JSBool static JSBool
bool_toString(JSContext *cx, uintN argc, jsval *vp) bool_toString(JSContext *cx, uintN argc, Value *vp)
{ {
jsval v; const Value *primp;
JSAtom *atom; if (!js_GetPrimitiveThis(cx, vp, &js_BooleanClass, &primp))
JSString *str;
if (!js_GetPrimitiveThis(cx, vp, &js_BooleanClass, &v))
return JS_FALSE; return JS_FALSE;
JS_ASSERT(JSVAL_IS_BOOLEAN(v)); JSAtom *atom = cx->runtime->atomState.booleanAtoms[primp->toBoolean() ? 1 : 0];
atom = cx->runtime->atomState.booleanAtoms[JSVAL_TO_BOOLEAN(v) ? 1 : 0]; JSString *str = ATOM_TO_STRING(atom);
str = ATOM_TO_STRING(atom);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
*vp = STRING_TO_JSVAL(str); vp->setString(str);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
bool_valueOf(JSContext *cx, uintN argc, jsval *vp) bool_valueOf(JSContext *cx, uintN argc, Value *vp)
{ {
return js_GetPrimitiveThis(cx, vp, &js_BooleanClass, vp); const Value *primp;
if (!js_GetPrimitiveThis(cx, vp, &js_BooleanClass, &primp))
return JS_FALSE;
*vp = *primp;
return JS_TRUE;
} }
static JSFunctionSpec boolean_methods[] = { static JSFunctionSpec boolean_methods[] = {
@ -131,13 +123,14 @@ static JSFunctionSpec boolean_methods[] = {
}; };
static JSBool static JSBool
Boolean(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Boolean(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
{ {
jsval bval; Value bval;
bval = (argc != 0) if (argc != 0)
? BOOLEAN_TO_JSVAL(js_ValueToBoolean(argv[0])) bval.setBoolean(!!js_ValueToBoolean(argv[0]));
: JSVAL_FALSE; else
bval.setBoolean(false);
if (!JS_IsConstructing(cx)) if (!JS_IsConstructing(cx))
*rval = bval; *rval = bval;
else else
@ -150,11 +143,11 @@ js_InitBooleanClass(JSContext *cx, JSObject *obj)
{ {
JSObject *proto; JSObject *proto;
proto = JS_InitClass(cx, obj, NULL, &js_BooleanClass, Boolean, 1, proto = js_InitClass(cx, obj, NULL, &js_BooleanClass, Boolean, 1,
NULL, boolean_methods, NULL, NULL); NULL, boolean_methods, NULL, NULL);
if (!proto) if (!proto)
return NULL; return NULL;
proto->setPrimitiveThis(JSVAL_FALSE); proto->setPrimitiveThis(BooleanValue(false));
return proto; return proto;
} }
@ -172,22 +165,22 @@ js_BooleanToCharBuffer(JSContext *cx, JSBool b, JSCharBuffer &cb)
} }
JSBool JSBool
js_ValueToBoolean(jsval v) js_ValueToBoolean(const Value &v)
{ {
if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v)) if (v.isNullOrUndefined())
return JS_FALSE; return JS_FALSE;
if (JSVAL_IS_OBJECT(v)) if (v.isObject())
return JS_TRUE; return JS_TRUE;
if (JSVAL_IS_STRING(v)) if (v.isString())
return JSVAL_TO_STRING(v)->length() != 0; return v.toString()->length() != 0;
if (JSVAL_IS_INT(v)) if (v.isInt32())
return JSVAL_TO_INT(v) != 0; return v.toInt32() != 0;
if (JSVAL_IS_DOUBLE(v)) { if (v.isDouble()) {
jsdouble d; jsdouble d;
d = *JSVAL_TO_DOUBLE(v); d = v.toDouble();
return !JSDOUBLE_IS_NaN(d) && d != 0; return !JSDOUBLE_IS_NaN(d) && d != 0;
} }
JS_ASSERT(JSVAL_IS_BOOLEAN(v)); JS_ASSERT(v.isBoolean());
return JSVAL_TO_BOOLEAN(v); return v.toBoolean();
} }

Просмотреть файл

@ -46,27 +46,7 @@
#include "jsapi.h" #include "jsapi.h"
#include "jsobj.h" #include "jsobj.h"
JS_BEGIN_EXTERN_C extern js::Class js_BooleanClass;
/*
* Special values, not visible to script but used internally by the engine.
*
* JSVAL_HOLE is a useful value for identifying a hole in an array. It's also
* used in the interpreter to represent "no exception pending". In general it
* can be used to represent "no value".
*
* A JSVAL_HOLE can be cheaply converted to undefined without affecting any
* other boolean (or special value) by masking out JSVAL_HOLE_FLAG.
*
* JSVAL_ARETURN is used to throw asynchronous return for generator.close().
*
* NB: SPECIAL_TO_JSVAL(2) is JSVAL_VOID (see jsapi.h).
*/
#define JSVAL_HOLE_FLAG jsval(4 << JSVAL_TAGBITS)
#define JSVAL_HOLE (JSVAL_VOID | JSVAL_HOLE_FLAG)
#define JSVAL_ARETURN SPECIAL_TO_JSVAL(8)
extern JSClass js_BooleanClass;
inline bool inline bool
JSObject::isBoolean() const JSObject::isBoolean() const
@ -84,8 +64,6 @@ extern JSBool
js_BooleanToCharBuffer(JSContext *cx, JSBool b, JSCharBuffer &cb); js_BooleanToCharBuffer(JSContext *cx, JSBool b, JSCharBuffer &cb);
extern JSBool extern JSBool
js_ValueToBoolean(jsval v); js_ValueToBoolean(const js::Value &v);
JS_END_EXTERN_C
#endif /* jsbool_h___ */ #endif /* jsbool_h___ */

Просмотреть файл

@ -103,69 +103,55 @@ js_imod(int32 a, int32 b)
} }
JS_DEFINE_CALLINFO_2(extern, INT32, js_imod, INT32, INT32, 1, ACC_NONE) JS_DEFINE_CALLINFO_2(extern, INT32, js_imod, INT32, INT32, 1, ACC_NONE)
jsval FASTCALL #if JS_BITS_PER_WORD == 32
js_BoxDouble(JSContext* cx, jsdouble d)
{
int32 i;
if (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i))
return INT_TO_JSVAL(i);
JS_ASSERT(JS_ON_TRACE(cx));
jsval v; /* not rooted but ok here because we know GC won't run */
if (!js_NewDoubleInRootedValue(cx, d, &v))
return JSVAL_NULL;
return v;
}
JS_DEFINE_CALLINFO_2(extern, JSVAL, js_BoxDouble, CONTEXT, DOUBLE, 1, ACC_NONE)
jsval FASTCALL
js_BoxInt32(JSContext* cx, int32 i)
{
if (JS_LIKELY(INT_FITS_IN_JSVAL(i)))
return INT_TO_JSVAL(i);
JS_ASSERT(JS_ON_TRACE(cx));
jsval v; /* not rooted but ok here because we know GC won't run */
jsdouble d = (jsdouble)i;
if (!js_NewDoubleInRootedValue(cx, d, &v))
return JSVAL_NULL;
return v;
}
JS_DEFINE_CALLINFO_2(extern, JSVAL, js_BoxInt32, CONTEXT, INT32, 1, ACC_NONE)
jsdouble FASTCALL jsdouble FASTCALL
js_UnboxDouble(jsval v) js_UnboxDouble(uint32 tag, uint32 payload)
{ {
if (JS_LIKELY(JSVAL_IS_INT(v))) if (tag == JSVAL_TAG_INT32)
return (jsdouble)JSVAL_TO_INT(v); return (double)(int32)payload;
return *JSVAL_TO_DOUBLE(v);
jsval_layout l;
l.s.tag = (JSValueTag)tag;
l.s.payload.u32 = payload;
return l.asDouble;
}
JS_DEFINE_CALLINFO_2(extern, DOUBLE, js_UnboxDouble, UINT32, UINT32, 1, ACC_NONE)
int32 FASTCALL
js_UnboxInt32(uint32 tag, uint32 payload)
{
if (tag == JSVAL_TAG_INT32)
return (int32)payload;
jsval_layout l;
l.s.tag = (JSValueTag)tag;
l.s.payload.u32 = payload;
return js_DoubleToECMAInt32(l.asDouble);
}
JS_DEFINE_CALLINFO_2(extern, INT32, js_UnboxInt32, UINT32, UINT32, 1, ACC_NONE)
#elif JS_BITS_PER_WORD == 64
jsdouble FASTCALL
js_UnboxDouble(Value v)
{
if (v.isInt32())
return (jsdouble)v.toInt32();
return v.toDouble();
} }
JS_DEFINE_CALLINFO_1(extern, DOUBLE, js_UnboxDouble, JSVAL, 1, ACC_NONE) JS_DEFINE_CALLINFO_1(extern, DOUBLE, js_UnboxDouble, JSVAL, 1, ACC_NONE)
int32 FASTCALL int32 FASTCALL
js_UnboxInt32(jsval v) js_UnboxInt32(Value v)
{ {
if (JS_LIKELY(JSVAL_IS_INT(v))) if (v.isInt32())
return JSVAL_TO_INT(v); return v.toInt32();
return js_DoubleToECMAInt32(*JSVAL_TO_DOUBLE(v)); return js_DoubleToECMAInt32(v.toDouble());
} }
JS_DEFINE_CALLINFO_1(extern, INT32, js_UnboxInt32, JSVAL, 1, ACC_NONE) JS_DEFINE_CALLINFO_1(extern, INT32, js_UnboxInt32, VALUE, 1, ACC_NONE)
JSBool FASTCALL #endif
js_TryUnboxInt32(jsval v, int32* i32p)
{
if (JS_LIKELY(JSVAL_IS_INT(v))) {
*i32p = JSVAL_TO_INT(v);
return JS_TRUE;
}
if (!JSVAL_IS_DOUBLE(v))
return JS_FALSE;
int32 i;
jsdouble d = *JSVAL_TO_DOUBLE(v);
if (!JSDOUBLE_IS_INT(d, i))
return JS_FALSE;
*i32p = i;
return JS_TRUE;
}
JS_DEFINE_CALLINFO_2(extern, BOOL, js_TryUnboxInt32, JSVAL, INT32PTR, 1, ACC_NONE)
int32 FASTCALL int32 FASTCALL
js_DoubleToInt32(jsdouble d) js_DoubleToInt32(jsdouble d)
@ -217,7 +203,7 @@ AddPropertyHelper(JSContext* cx, JSObject* obj, JSScopeProperty* sprop, bool isD
if (!scope->table) { if (!scope->table) {
if (slot < obj->numSlots()) { if (slot < obj->numSlots()) {
JS_ASSERT(JSVAL_IS_VOID(obj->getSlot(scope->freeslot))); JS_ASSERT(obj->getSlot(scope->freeslot).isUndefined());
++scope->freeslot; ++scope->freeslot;
} else { } else {
if (!js_AllocSlot(cx, obj, &slot)) if (!js_AllocSlot(cx, obj, &slot))
@ -270,16 +256,16 @@ HasProperty(JSContext* cx, JSObject* obj, jsid id)
// Check that we know how the lookup op will behave. // Check that we know how the lookup op will behave.
for (JSObject* pobj = obj; pobj; pobj = pobj->getProto()) { for (JSObject* pobj = obj; pobj; pobj = pobj->getProto()) {
if (pobj->map->ops->lookupProperty != js_LookupProperty) if (pobj->map->ops->lookupProperty != js_LookupProperty)
return JSVAL_TO_SPECIAL(JSVAL_VOID); return JS_NEITHER;
JSClass* clasp = pobj->getClass(); Class* clasp = pobj->getClass();
if (clasp->resolve != JS_ResolveStub && clasp != &js_StringClass) if (clasp->resolve != JS_ResolveStub && clasp != &js_StringClass)
return JSVAL_TO_SPECIAL(JSVAL_VOID); return JS_NEITHER;
} }
JSObject* obj2; JSObject* obj2;
JSProperty* prop; JSProperty* prop;
if (js_LookupPropertyWithFlags(cx, obj, id, JSRESOLVE_QUALIFIED, &obj2, &prop) < 0) if (js_LookupPropertyWithFlags(cx, obj, id, JSRESOLVE_QUALIFIED, &obj2, &prop) < 0)
return JSVAL_TO_SPECIAL(JSVAL_VOID); return JS_NEITHER;
if (prop) if (prop)
obj2->dropProperty(cx, prop); obj2->dropProperty(cx, prop);
return prop != NULL; return prop != NULL;
@ -288,11 +274,11 @@ HasProperty(JSContext* cx, JSObject* obj, jsid id)
JSBool FASTCALL JSBool FASTCALL
js_HasNamedProperty(JSContext* cx, JSObject* obj, JSString* idstr) js_HasNamedProperty(JSContext* cx, JSObject* obj, JSString* idstr)
{ {
jsid id; JSAtom *atom = js_AtomizeString(cx, idstr, 0);
if (!js_ValueToStringId(cx, STRING_TO_JSVAL(idstr), &id)) if (!atom)
return JSVAL_TO_BOOLEAN(JSVAL_VOID); return JS_NEITHER;
return HasProperty(cx, obj, id); return HasProperty(cx, obj, ATOM_TO_JSID(atom));
} }
JS_DEFINE_CALLINFO_3(extern, BOOL, js_HasNamedProperty, CONTEXT, OBJECT, STRING, 0, ACC_STORE_ANY) JS_DEFINE_CALLINFO_3(extern, BOOL, js_HasNamedProperty, CONTEXT, OBJECT, STRING, 0, ACC_STORE_ANY)
@ -301,7 +287,7 @@ js_HasNamedPropertyInt32(JSContext* cx, JSObject* obj, int32 index)
{ {
jsid id; jsid id;
if (!js_Int32ToId(cx, index, &id)) if (!js_Int32ToId(cx, index, &id))
return JSVAL_TO_BOOLEAN(JSVAL_VOID); return JS_NEITHER;
return HasProperty(cx, obj, id); return HasProperty(cx, obj, id);
} }
@ -311,23 +297,11 @@ JS_DEFINE_CALLINFO_3(extern, BOOL, js_HasNamedPropertyInt32, CONTEXT, OBJECT, IN
JSString* FASTCALL JSString* FASTCALL
js_TypeOfObject(JSContext* cx, JSObject* obj) js_TypeOfObject(JSContext* cx, JSObject* obj)
{ {
if (!obj) JS_ASSERT(obj);
return ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[JSTYPE_OBJECT]);
return ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[obj->typeOf(cx)]); return ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[obj->typeOf(cx)]);
} }
JS_DEFINE_CALLINFO_2(extern, STRING, js_TypeOfObject, CONTEXT, OBJECT, 1, ACC_NONE) JS_DEFINE_CALLINFO_2(extern, STRING, js_TypeOfObject, CONTEXT, OBJECT, 1, ACC_NONE)
JSString* FASTCALL
js_TypeOfBoolean(JSContext* cx, int32 unboxed)
{
/* Watch out for pseudo-booleans. */
jsval boxed = SPECIAL_TO_JSVAL(unboxed);
JS_ASSERT(JSVAL_IS_VOID(boxed) || JSVAL_IS_BOOLEAN(boxed));
JSType type = JS_TypeOfValue(cx, boxed);
return ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[type]);
}
JS_DEFINE_CALLINFO_2(extern, STRING, js_TypeOfBoolean, CONTEXT, INT32, 1, ACC_NONE)
JSString* FASTCALL JSString* FASTCALL
js_BooleanIntToString(JSContext *cx, int32 unboxed) js_BooleanIntToString(JSContext *cx, int32 unboxed)
{ {
@ -350,8 +324,7 @@ js_NewNullClosure(JSContext* cx, JSObject* funobj, JSObject* proto, JSObject* pa
if (!closure) if (!closure)
return NULL; return NULL;
closure->initSharingEmptyScope(&js_FunctionClass, proto, parent, closure->initSharingEmptyScope(&js_FunctionClass, proto, parent, PrivateValue(fun));
reinterpret_cast<jsval>(fun));
return closure; return closure;
} }
JS_DEFINE_CALLINFO_4(extern, OBJECT, js_NewNullClosure, CONTEXT, OBJECT, OBJECT, OBJECT, 0, JS_DEFINE_CALLINFO_4(extern, OBJECT, js_NewNullClosure, CONTEXT, OBJECT, OBJECT, OBJECT, 0,

Просмотреть файл

@ -48,9 +48,15 @@
#undef THIS #undef THIS
#endif #endif
enum JSTNErrType { INFALLIBLE, FAIL_STATUS, FAIL_NULL, FAIL_NEG, FAIL_VOID }; enum JSTNErrType { INFALLIBLE, FAIL_STATUS, FAIL_NULL, FAIL_NEG, FAIL_NEITHER };
enum { JSTN_ERRTYPE_MASK = 0x07, JSTN_UNBOX_AFTER = 0x08, JSTN_MORE = 0x10, enum {
JSTN_CONSTRUCTOR = 0x20 }; JSTN_ERRTYPE_MASK = 0x07,
JSTN_UNBOX_AFTER = 0x08,
JSTN_MORE = 0x10,
JSTN_CONSTRUCTOR = 0x20,
JSTN_RETURN_NULLABLE_STR = 0x40,
JSTN_RETURN_NULLABLE_OBJ = 0x80
};
#define JSTN_ERRTYPE(jstn) ((jstn)->flags & JSTN_ERRTYPE_MASK) #define JSTN_ERRTYPE(jstn) ((jstn)->flags & JSTN_ERRTYPE_MASK)
@ -80,7 +86,7 @@ enum { JSTN_ERRTYPE_MASK = 0x07, JSTN_UNBOX_AFTER = 0x08, JSTN_MORE = 0x10,
* 'o': a JSObject* argument * 'o': a JSObject* argument
* 'r': a JSObject* argument that is of class js_RegExpClass * 'r': a JSObject* argument that is of class js_RegExpClass
* 'f': a JSObject* argument that is of class js_FunctionClass * 'f': a JSObject* argument that is of class js_FunctionClass
* 'v': a jsval argument (boxing whatever value is actually being passed in) * 'v': a value argument: on 32-bit, a Value*, on 64-bit, a jsval
*/ */
struct JSSpecializedNative { struct JSSpecializedNative {
const nanojit::CallInfo *builtin; const nanojit::CallInfo *builtin;
@ -110,6 +116,8 @@ struct JSNativeTraceInfo {
#define _JS_I32_ARGTYPE nanojit::ARGTYPE_I #define _JS_I32_ARGTYPE nanojit::ARGTYPE_I
#define _JS_I32_RETTYPE nanojit::ARGTYPE_I #define _JS_I32_RETTYPE nanojit::ARGTYPE_I
#define _JS_U64_ARGTYPE nanojit::ARGTYPE_Q
#define _JS_U64_RETTYPE nanojit::ARGTYPE_Q
#define _JS_F64_ARGTYPE nanojit::ARGTYPE_D #define _JS_F64_ARGTYPE nanojit::ARGTYPE_D
#define _JS_F64_RETTYPE nanojit::ARGTYPE_D #define _JS_F64_RETTYPE nanojit::ARGTYPE_D
#define _JS_PTR_ARGTYPE nanojit::ARGTYPE_P #define _JS_PTR_ARGTYPE nanojit::ARGTYPE_P
@ -148,7 +156,7 @@ struct ClosureVarInfo;
* _RETRY builtins indicate failure with a special return value that * _RETRY builtins indicate failure with a special return value that
* depends on the return type: * depends on the return type:
* *
* BOOL_RETRY: JSVAL_TO_BOOLEAN(JSVAL_VOID) * BOOL_RETRY: JS_NEITHER
* INT32_RETRY: any negative value * INT32_RETRY: any negative value
* STRING_RETRY: NULL * STRING_RETRY: NULL
* OBJECT_RETRY_NULL: NULL * OBJECT_RETRY_NULL: NULL
@ -172,7 +180,6 @@ struct ClosureVarInfo;
* effects. * effects.
*/ */
#define _JS_CTYPE(ctype, size, pch, ach, flags) (ctype, size, pch, ach, flags) #define _JS_CTYPE(ctype, size, pch, ach, flags) (ctype, size, pch, ach, flags)
#define _JS_JSVAL_CTYPE(size, pch, ach, flags) (jsval, size, pch, ach, (flags | JSTN_UNBOX_AFTER))
#define _JS_CTYPE_CONTEXT _JS_CTYPE(JSContext *, _JS_PTR,"C", "", INFALLIBLE) #define _JS_CTYPE_CONTEXT _JS_CTYPE(JSContext *, _JS_PTR,"C", "", INFALLIBLE)
#define _JS_CTYPE_RUNTIME _JS_CTYPE(JSRuntime *, _JS_PTR,"R", "", INFALLIBLE) #define _JS_CTYPE_RUNTIME _JS_CTYPE(JSRuntime *, _JS_PTR,"R", "", INFALLIBLE)
@ -183,12 +190,12 @@ struct ClosureVarInfo;
#define _JS_CTYPE_CALLEE_PROTOTYPE _JS_CTYPE(JSObject *, _JS_PTR,"p","", INFALLIBLE) #define _JS_CTYPE_CALLEE_PROTOTYPE _JS_CTYPE(JSObject *, _JS_PTR,"p","", INFALLIBLE)
#define _JS_CTYPE_FUNCTION _JS_CTYPE(JSFunction *, _JS_PTR, --, --, INFALLIBLE) #define _JS_CTYPE_FUNCTION _JS_CTYPE(JSFunction *, _JS_PTR, --, --, INFALLIBLE)
#define _JS_CTYPE_PC _JS_CTYPE(jsbytecode *, _JS_PTR,"P", "", INFALLIBLE) #define _JS_CTYPE_PC _JS_CTYPE(jsbytecode *, _JS_PTR,"P", "", INFALLIBLE)
#define _JS_CTYPE_JSVALPTR _JS_CTYPE(jsval *, _JS_PTR,"P", "", INFALLIBLE) #define _JS_CTYPE_VALUEPTR _JS_CTYPE(js::Value *, _JS_PTR, --, --, INFALLIBLE)
#define _JS_CTYPE_JSVAL _JS_JSVAL_CTYPE( _JS_PTR, "","v", INFALLIBLE) #define _JS_CTYPE_CVALUEPTR _JS_CTYPE(const js::Value *, _JS_PTR, --, --, INFALLIBLE)
#define _JS_CTYPE_JSVAL_FAIL _JS_JSVAL_CTYPE( _JS_PTR, --, --, FAIL_STATUS)
#define _JS_CTYPE_JSID _JS_CTYPE(jsid, _JS_PTR, --, --, INFALLIBLE) #define _JS_CTYPE_JSID _JS_CTYPE(jsid, _JS_PTR, --, --, INFALLIBLE)
#define _JS_CTYPE_JSVAL _JS_CTYPE(js::Value, _JS_U64, --, --, INFALLIBLE)
#define _JS_CTYPE_BOOL _JS_CTYPE(JSBool, _JS_I32, "","i", INFALLIBLE) #define _JS_CTYPE_BOOL _JS_CTYPE(JSBool, _JS_I32, "","i", INFALLIBLE)
#define _JS_CTYPE_BOOL_RETRY _JS_CTYPE(JSBool, _JS_I32, --, --, FAIL_VOID) #define _JS_CTYPE_BOOL_RETRY _JS_CTYPE(JSBool, _JS_I32, --, --, FAIL_NEITHER)
#define _JS_CTYPE_BOOL_FAIL _JS_CTYPE(JSBool, _JS_I32, --, --, FAIL_STATUS) #define _JS_CTYPE_BOOL_FAIL _JS_CTYPE(JSBool, _JS_I32, --, --, FAIL_STATUS)
#define _JS_CTYPE_BOOLPTR _JS_CTYPE(JSBool *, _JS_PTR, --, --, INFALLIBLE) #define _JS_CTYPE_BOOLPTR _JS_CTYPE(JSBool *, _JS_PTR, --, --, INFALLIBLE)
#define _JS_CTYPE_INT32 _JS_CTYPE(int32, _JS_I32, "","i", INFALLIBLE) #define _JS_CTYPE_INT32 _JS_CTYPE(int32, _JS_I32, "","i", INFALLIBLE)
@ -203,10 +210,14 @@ struct ClosureVarInfo;
#define _JS_CTYPE_STRING _JS_CTYPE(JSString *, _JS_PTR, "","s", INFALLIBLE) #define _JS_CTYPE_STRING _JS_CTYPE(JSString *, _JS_PTR, "","s", INFALLIBLE)
#define _JS_CTYPE_STRING_RETRY _JS_CTYPE(JSString *, _JS_PTR, --, --, FAIL_NULL) #define _JS_CTYPE_STRING_RETRY _JS_CTYPE(JSString *, _JS_PTR, --, --, FAIL_NULL)
#define _JS_CTYPE_STRING_FAIL _JS_CTYPE(JSString *, _JS_PTR, --, --, FAIL_STATUS) #define _JS_CTYPE_STRING_FAIL _JS_CTYPE(JSString *, _JS_PTR, --, --, FAIL_STATUS)
#define _JS_CTYPE_STRING_OR_NULL_FAIL _JS_CTYPE(JSString *, _JS_PTR, --, --, FAIL_STATUS | \
JSTN_RETURN_NULLABLE_STR)
#define _JS_CTYPE_STRINGPTR _JS_CTYPE(JSString **, _JS_PTR, --, --, INFALLIBLE) #define _JS_CTYPE_STRINGPTR _JS_CTYPE(JSString **, _JS_PTR, --, --, INFALLIBLE)
#define _JS_CTYPE_OBJECT _JS_CTYPE(JSObject *, _JS_PTR, "","o", INFALLIBLE) #define _JS_CTYPE_OBJECT _JS_CTYPE(JSObject *, _JS_PTR, "","o", INFALLIBLE)
#define _JS_CTYPE_OBJECT_RETRY _JS_CTYPE(JSObject *, _JS_PTR, --, --, FAIL_NULL) #define _JS_CTYPE_OBJECT_RETRY _JS_CTYPE(JSObject *, _JS_PTR, --, --, FAIL_NULL)
#define _JS_CTYPE_OBJECT_FAIL _JS_CTYPE(JSObject *, _JS_PTR, --, --, FAIL_STATUS) #define _JS_CTYPE_OBJECT_FAIL _JS_CTYPE(JSObject *, _JS_PTR, --, --, FAIL_STATUS)
#define _JS_CTYPE_OBJECT_OR_NULL_FAIL _JS_CTYPE(JSObject *, _JS_PTR, --, --, FAIL_STATUS | \
JSTN_RETURN_NULLABLE_OBJ)
#define _JS_CTYPE_OBJECTPTR _JS_CTYPE(JSObject **, _JS_PTR, --, --, INFALLIBLE) #define _JS_CTYPE_OBJECTPTR _JS_CTYPE(JSObject **, _JS_PTR, --, --, INFALLIBLE)
#define _JS_CTYPE_CONSTRUCTOR_RETRY _JS_CTYPE(JSObject *, _JS_PTR, --, --, FAIL_NULL | \ #define _JS_CTYPE_CONSTRUCTOR_RETRY _JS_CTYPE(JSObject *, _JS_PTR, --, --, FAIL_NULL | \
JSTN_CONSTRUCTOR) JSTN_CONSTRUCTOR)
@ -214,13 +225,32 @@ struct ClosureVarInfo;
#define _JS_CTYPE_SCOPEPROP _JS_CTYPE(JSScopeProperty *, _JS_PTR, --, --, INFALLIBLE) #define _JS_CTYPE_SCOPEPROP _JS_CTYPE(JSScopeProperty *, _JS_PTR, --, --, INFALLIBLE)
#define _JS_CTYPE_TRACERSTATE _JS_CTYPE(TracerState *, _JS_PTR, --, --, INFALLIBLE) #define _JS_CTYPE_TRACERSTATE _JS_CTYPE(TracerState *, _JS_PTR, --, --, INFALLIBLE)
#define _JS_CTYPE_FRAGMENT _JS_CTYPE(nanojit::Fragment *, _JS_PTR, --, --, INFALLIBLE) #define _JS_CTYPE_FRAGMENT _JS_CTYPE(nanojit::Fragment *, _JS_PTR, --, --, INFALLIBLE)
#define _JS_CTYPE_CLASS _JS_CTYPE(JSClass *, _JS_PTR, --, --, INFALLIBLE) #define _JS_CTYPE_CLASS _JS_CTYPE(js::Class *, _JS_PTR, --, --, INFALLIBLE)
#define _JS_CTYPE_DOUBLEPTR _JS_CTYPE(double *, _JS_PTR, --, --, INFALLIBLE) #define _JS_CTYPE_DOUBLEPTR _JS_CTYPE(double *, _JS_PTR, --, --, INFALLIBLE)
#define _JS_CTYPE_CHARPTR _JS_CTYPE(char *, _JS_PTR, --, --, INFALLIBLE) #define _JS_CTYPE_CHARPTR _JS_CTYPE(char *, _JS_PTR, --, --, INFALLIBLE)
#define _JS_CTYPE_APNPTR _JS_CTYPE(ArgsPrivateNative *, _JS_PTR, --, --, INFALLIBLE) #define _JS_CTYPE_APNPTR _JS_CTYPE(ArgsPrivateNative *, _JS_PTR, --, --, INFALLIBLE)
#define _JS_CTYPE_CVIPTR _JS_CTYPE(const ClosureVarInfo *, _JS_PTR, --, --, INFALLIBLE) #define _JS_CTYPE_CVIPTR _JS_CTYPE(const ClosureVarInfo *, _JS_PTR, --, --, INFALLIBLE)
#define _JS_CTYPE_FRAMEINFO _JS_CTYPE(FrameInfo *, _JS_PTR, --, --, INFALLIBLE) #define _JS_CTYPE_FRAMEINFO _JS_CTYPE(FrameInfo *, _JS_PTR, --, --, INFALLIBLE)
/*
* The "VALUE" type is used to indicate that a native takes a js::Value
* parameter by value. Unfortunately, for technical reasons, we can't simply
* have the parameter type be js::Value. Furthermore, the right thing to pass
* differs based on word size. Thus, a native that declares a parameter of type
* VALUE should have the corresponding argument type be:
* - on 32-bit: const Value*
* - on 64-bit: jsval (which is a uint64)
*
* To write code that just does the right thing, use the pattern:
* void foo(js::ValueArgType arg) {
* const js::Value &v = js::ValueArgToConstRef(arg);
*/
#if JS_BITS_PER_WORD == 32
# define _JS_CTYPE_VALUE _JS_CTYPE(js::ValueArgType, _JS_PTR, "","v", INFALLIBLE)
#elif JS_BITS_PER_WORD == 64
# define _JS_CTYPE_VALUE _JS_CTYPE(js::ValueArgType, _JS_U64, "","v", INFALLIBLE)
#endif
#define _JS_EXPAND(tokens) tokens #define _JS_EXPAND(tokens) tokens
#define _JS_CTYPE_TYPE2(t,s,p,a,f) t #define _JS_CTYPE_TYPE2(t,s,p,a,f) t
@ -549,14 +579,11 @@ JS_DECLARE_CALLINFO(js_Array_dense_setelem_double)
JS_DECLARE_CALLINFO(js_NewEmptyArray) JS_DECLARE_CALLINFO(js_NewEmptyArray)
JS_DECLARE_CALLINFO(js_NewEmptyArrayWithLength) JS_DECLARE_CALLINFO(js_NewEmptyArrayWithLength)
JS_DECLARE_CALLINFO(js_NewArrayWithSlots) JS_DECLARE_CALLINFO(js_NewArrayWithSlots)
JS_DECLARE_CALLINFO(js_ArrayCompPush) JS_DECLARE_CALLINFO(js_ArrayCompPush_tn)
/* Defined in jsbuiltins.cpp. */ /* Defined in jsbuiltins.cpp. */
JS_DECLARE_CALLINFO(js_BoxDouble)
JS_DECLARE_CALLINFO(js_BoxInt32)
JS_DECLARE_CALLINFO(js_UnboxDouble) JS_DECLARE_CALLINFO(js_UnboxDouble)
JS_DECLARE_CALLINFO(js_UnboxInt32) JS_DECLARE_CALLINFO(js_UnboxInt32)
JS_DECLARE_CALLINFO(js_TryUnboxInt32)
JS_DECLARE_CALLINFO(js_dmod) JS_DECLARE_CALLINFO(js_dmod)
JS_DECLARE_CALLINFO(js_imod) JS_DECLARE_CALLINFO(js_imod)
JS_DECLARE_CALLINFO(js_DoubleToInt32) JS_DECLARE_CALLINFO(js_DoubleToInt32)
@ -568,7 +595,6 @@ JS_DECLARE_CALLINFO(js_AddAtomProperty)
JS_DECLARE_CALLINFO(js_HasNamedProperty) JS_DECLARE_CALLINFO(js_HasNamedProperty)
JS_DECLARE_CALLINFO(js_HasNamedPropertyInt32) JS_DECLARE_CALLINFO(js_HasNamedPropertyInt32)
JS_DECLARE_CALLINFO(js_TypeOfObject) JS_DECLARE_CALLINFO(js_TypeOfObject)
JS_DECLARE_CALLINFO(js_TypeOfBoolean)
JS_DECLARE_CALLINFO(js_BooleanIntToString) JS_DECLARE_CALLINFO(js_BooleanIntToString)
JS_DECLARE_CALLINFO(js_NewNullClosure) JS_DECLARE_CALLINFO(js_NewNullClosure)
JS_DECLARE_CALLINFO(js_PopInterpFrame) JS_DECLARE_CALLINFO(js_PopInterpFrame)

Просмотреть файл

@ -135,21 +135,21 @@ StackSpace::init()
void *check = VirtualAlloc(p, COMMIT_BYTES, MEM_COMMIT, PAGE_READWRITE); void *check = VirtualAlloc(p, COMMIT_BYTES, MEM_COMMIT, PAGE_READWRITE);
if (p != check) if (p != check)
return false; return false;
base = reinterpret_cast<jsval *>(p); base = reinterpret_cast<Value *>(p);
commitEnd = base + COMMIT_VALS; commitEnd = base + COMMIT_VALS;
end = base + CAPACITY_VALS; end = base + CAPACITY_VALS;
#elif defined(XP_OS2) #elif defined(XP_OS2)
if (DosAllocMem(&p, CAPACITY_BYTES, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_ANY) && if (DosAllocMem(&p, CAPACITY_BYTES, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_ANY) &&
DosAllocMem(&p, CAPACITY_BYTES, PAG_COMMIT | PAG_READ | PAG_WRITE)) DosAllocMem(&p, CAPACITY_BYTES, PAG_COMMIT | PAG_READ | PAG_WRITE))
return false; return false;
base = reinterpret_cast<jsval *>(p); base = reinterpret_cast<Value *>(p);
end = base + CAPACITY_VALS; end = base + CAPACITY_VALS;
#else #else
JS_ASSERT(CAPACITY_BYTES % getpagesize() == 0); JS_ASSERT(CAPACITY_BYTES % getpagesize() == 0);
p = mmap(NULL, CAPACITY_BYTES, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); p = mmap(NULL, CAPACITY_BYTES, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (p == MAP_FAILED) if (p == MAP_FAILED)
return false; return false;
base = reinterpret_cast<jsval *>(p); base = reinterpret_cast<Value *>(p);
end = base + CAPACITY_VALS; end = base + CAPACITY_VALS;
#endif #endif
return true; return true;
@ -159,22 +159,22 @@ void
StackSpace::finish() StackSpace::finish()
{ {
#ifdef XP_WIN #ifdef XP_WIN
VirtualFree(base, (commitEnd - base) * sizeof(jsval), MEM_DECOMMIT); VirtualFree(base, (commitEnd - base) * sizeof(Value), MEM_DECOMMIT);
VirtualFree(base, 0, MEM_RELEASE); VirtualFree(base, 0, MEM_RELEASE);
#elif defined(XP_OS2) #elif defined(XP_OS2)
DosFreeMem(base); DosFreeMem(base);
#else #else
munmap(base, CAPACITY_BYTES); munmap((caddr_t)base, CAPACITY_BYTES);
#endif #endif
} }
#ifdef XP_WIN #ifdef XP_WIN
JS_FRIEND_API(bool) JS_FRIEND_API(bool)
StackSpace::bumpCommit(jsval *from, ptrdiff_t nvals) const StackSpace::bumpCommit(Value *from, ptrdiff_t nvals) const
{ {
JS_ASSERT(end - from >= nvals); JS_ASSERT(end - from >= nvals);
jsval *newCommit = commitEnd; Value *newCommit = commitEnd;
jsval *request = from + nvals; Value *request = from + nvals;
/* Use a dumb loop; will probably execute once. */ /* Use a dumb loop; will probably execute once. */
JS_ASSERT((end - newCommit) % COMMIT_VALS == 0); JS_ASSERT((end - newCommit) % COMMIT_VALS == 0);
@ -184,7 +184,7 @@ StackSpace::bumpCommit(jsval *from, ptrdiff_t nvals) const
} while (newCommit < request); } while (newCommit < request);
/* The cast is safe because CAPACITY_BYTES is small. */ /* The cast is safe because CAPACITY_BYTES is small. */
int32 size = static_cast<int32>(newCommit - commitEnd) * sizeof(jsval); int32 size = static_cast<int32>(newCommit - commitEnd) * sizeof(Value);
if (!VirtualAlloc(commitEnd, size, MEM_COMMIT, PAGE_READWRITE)) if (!VirtualAlloc(commitEnd, size, MEM_COMMIT, PAGE_READWRITE))
return false; return false;
@ -200,7 +200,7 @@ StackSpace::mark(JSTracer *trc)
* The correctness/completeness of marking depends on the continuity * The correctness/completeness of marking depends on the continuity
* invariants described by the CallStack and StackSpace definitions. * invariants described by the CallStack and StackSpace definitions.
*/ */
jsval *end = firstUnused(); Value *end = firstUnused();
for (CallStack *cs = currentCallStack; cs; cs = cs->getPreviousInThread()) { for (CallStack *cs = currentCallStack; cs; cs = cs->getPreviousInThread()) {
if (cs->inContext()) { if (cs->inContext()) {
/* This may be the only pointer to the initialVarObj. */ /* This may be the only pointer to the initialVarObj. */
@ -209,22 +209,22 @@ StackSpace::mark(JSTracer *trc)
/* Mark slots/args trailing off of the last stack frame. */ /* Mark slots/args trailing off of the last stack frame. */
JSStackFrame *fp = cs->getCurrentFrame(); JSStackFrame *fp = cs->getCurrentFrame();
TraceValues(trc, fp->slots(), end, "stack"); MarkValueRange(trc, fp->slots(), end, "stack");
/* Mark stack frames and slots/args between stack frames. */ /* Mark stack frames and slots/args between stack frames. */
JSStackFrame *initialFrame = cs->getInitialFrame(); JSStackFrame *initialFrame = cs->getInitialFrame();
for (JSStackFrame *f = fp; f != initialFrame; f = f->down) { for (JSStackFrame *f = fp; f != initialFrame; f = f->down) {
js_TraceStackFrame(trc, f); js_TraceStackFrame(trc, f);
TraceValues(trc, f->down->slots(), f->argEnd(), "stack"); MarkValueRange(trc, f->down->slots(), f->argEnd(), "stack");
} }
/* Mark initialFrame stack frame and leading args. */ /* Mark initialFrame stack frame and leading args. */
js_TraceStackFrame(trc, initialFrame); js_TraceStackFrame(trc, initialFrame);
TraceValues(trc, cs->getInitialArgBegin(), initialFrame->argEnd(), "stack"); MarkValueRange(trc, cs->getInitialArgBegin(), initialFrame->argEnd(), "stack");
} else { } else {
/* Mark slots/args trailing off callstack. */ /* Mark slots/args trailing off callstack. */
JS_ASSERT(end == cs->getInitialArgEnd()); JS_ASSERT(end == cs->getInitialArgEnd());
TraceValues(trc, cs->getInitialArgBegin(), cs->getInitialArgEnd(), "stack"); MarkValueRange(trc, cs->getInitialArgBegin(), cs->getInitialArgEnd(), "stack");
} }
end = cs->previousCallStackEnd(); end = cs->previousCallStackEnd();
} }
@ -233,14 +233,14 @@ StackSpace::mark(JSTracer *trc)
JS_REQUIRES_STACK bool JS_REQUIRES_STACK bool
StackSpace::pushInvokeArgs(JSContext *cx, uintN argc, InvokeArgsGuard &ag) StackSpace::pushInvokeArgs(JSContext *cx, uintN argc, InvokeArgsGuard &ag)
{ {
jsval *start = firstUnused(); Value *start = firstUnused();
uintN vplen = 2 + argc; uintN vplen = 2 + argc;
ptrdiff_t nvals = VALUES_PER_CALL_STACK + vplen; ptrdiff_t nvals = VALUES_PER_CALL_STACK + vplen;
if (!ensureSpace(cx, start, nvals)) if (!ensureSpace(cx, start, nvals))
return false; return false;
jsval *vp = start + VALUES_PER_CALL_STACK; Value *vp = start + VALUES_PER_CALL_STACK;
jsval *vpend = vp + vplen; Value *vpend = vp + vplen;
memset(vp, 0, vplen * sizeof(jsval)); /* Init so GC-safe on exit. */ memset(vp, 0, vplen * sizeof(Value)); /* Init so GC-safe on exit. */
CallStack *cs = new(start) CallStack; CallStack *cs = new(start) CallStack;
cs->setInitialArgEnd(vpend); cs->setInitialArgEnd(vpend);
@ -278,7 +278,7 @@ StackSpace::getInvokeFrame(JSContext *cx, const InvokeArgsGuard &ag,
{ {
if (ag.cs) { if (ag.cs) {
JS_ASSERT(ag.cs == currentCallStack && !ag.cs->inContext()); JS_ASSERT(ag.cs == currentCallStack && !ag.cs->inContext());
jsval *start = ag.cs->getInitialArgEnd(); Value *start = ag.cs->getInitialArgEnd();
ptrdiff_t nvals = nmissing + VALUES_PER_STACK_FRAME + nfixed; ptrdiff_t nvals = nmissing + VALUES_PER_STACK_FRAME + nfixed;
if (!ensureSpace(cx, start, nvals)) if (!ensureSpace(cx, start, nvals))
return false; return false;
@ -288,7 +288,7 @@ StackSpace::getInvokeFrame(JSContext *cx, const InvokeArgsGuard &ag,
assertIsCurrent(cx); assertIsCurrent(cx);
JS_ASSERT(currentCallStack->isActive()); JS_ASSERT(currentCallStack->isActive());
jsval *start = cx->regs->sp; Value *start = cx->regs->sp;
ptrdiff_t nvals = nmissing + VALUES_PER_CALL_STACK + VALUES_PER_STACK_FRAME + nfixed; ptrdiff_t nvals = nmissing + VALUES_PER_CALL_STACK + VALUES_PER_STACK_FRAME + nfixed;
if (!ensureSpace(cx, start, nvals)) if (!ensureSpace(cx, start, nvals))
return false; return false;
@ -358,7 +358,7 @@ StackSpace::getExecuteFrame(JSContext *cx, JSStackFrame *down,
uintN vplen, uintN nfixed, uintN vplen, uintN nfixed,
ExecuteFrameGuard &fg) const ExecuteFrameGuard &fg) const
{ {
jsval *start = firstUnused(); Value *start = firstUnused();
ptrdiff_t nvals = VALUES_PER_CALL_STACK + vplen + VALUES_PER_STACK_FRAME + nfixed; ptrdiff_t nvals = VALUES_PER_CALL_STACK + vplen + VALUES_PER_STACK_FRAME + nfixed;
if (!ensureSpace(cx, start, nvals)) if (!ensureSpace(cx, start, nvals))
return false; return false;
@ -395,7 +395,7 @@ StackSpace::popExecuteFrame(JSContext *cx)
JS_REQUIRES_STACK void JS_REQUIRES_STACK void
StackSpace::getSynthesizedSlowNativeFrame(JSContext *cx, CallStack *&cs, JSStackFrame *&fp) StackSpace::getSynthesizedSlowNativeFrame(JSContext *cx, CallStack *&cs, JSStackFrame *&fp)
{ {
jsval *start = firstUnused(); Value *start = firstUnused();
JS_ASSERT(size_t(end - start) >= VALUES_PER_CALL_STACK + VALUES_PER_STACK_FRAME); JS_ASSERT(size_t(end - start) >= VALUES_PER_CALL_STACK + VALUES_PER_STACK_FRAME);
cs = new(start) CallStack; cs = new(start) CallStack;
fp = reinterpret_cast<JSStackFrame *>(cs + 1); fp = reinterpret_cast<JSStackFrame *>(cs + 1);
@ -429,16 +429,16 @@ StackSpace::popSynthesizedSlowNativeFrame(JSContext *cx)
* up-frame's address is the top of the down-frame's stack, modulo missing * up-frame's address is the top of the down-frame's stack, modulo missing
* arguments. * arguments.
*/ */
static inline jsval * static inline Value *
InlineDownFrameSP(JSStackFrame *up) InlineDownFrameSP(JSStackFrame *up)
{ {
JS_ASSERT(up->fun && up->script); JS_ASSERT(up->fun && up->script);
jsval *sp = up->argv + up->argc; Value *sp = up->argv + up->argc;
#ifdef DEBUG #ifdef DEBUG
uint16 nargs = up->fun->nargs; uint16 nargs = up->fun->nargs;
uintN argc = up->argc; uintN argc = up->argc;
uintN missing = argc < nargs ? nargs - argc : 0; uintN missing = argc < nargs ? nargs - argc : 0;
JS_ASSERT(sp == (jsval *)up - missing); JS_ASSERT(sp == (Value *)up - missing);
#endif #endif
return sp; return sp;
} }
@ -488,12 +488,12 @@ FrameRegsIter::operator++()
* scan, keeping track of what is immediately after down in memory. * scan, keeping track of what is immediately after down in memory.
*/ */
curcs = curcs->getPreviousInContext(); curcs = curcs->getPreviousInContext();
cursp = curcs->getSuspendedSP(); cursp = curcs->getSuspendedRegs()->sp;
JSStackFrame *f = curcs->getSuspendedFrame(); JSStackFrame *f = curcs->getSuspendedFrame();
while (f != down) { while (f != down) {
if (f == curcs->getInitialFrame()) { if (f == curcs->getInitialFrame()) {
curcs = curcs->getPreviousInContext(); curcs = curcs->getPreviousInContext();
cursp = curcs->getSuspendedSP(); cursp = curcs->getSuspendedRegs()->sp;
f = curcs->getSuspendedFrame(); f = curcs->getSuspendedFrame();
} else { } else {
cursp = InlineDownFrameSP(f); cursp = InlineDownFrameSP(f);
@ -1246,7 +1246,7 @@ resolving_HashKey(JSDHashTable *table, const void *ptr)
{ {
const JSResolvingKey *key = (const JSResolvingKey *)ptr; const JSResolvingKey *key = (const JSResolvingKey *)ptr;
return (JSDHashNumber(uintptr_t(key->obj)) >> JSVAL_TAGBITS) ^ key->id; return (JSDHashNumber(uintptr_t(key->obj)) >> JS_GCTHING_ALIGN) ^ JSID_BITS(key->id);
} }
static JSBool static JSBool
@ -1779,13 +1779,13 @@ js_ReportIsNotDefined(JSContext *cx, const char *name)
} }
JSBool JSBool
js_ReportIsNullOrUndefined(JSContext *cx, intN spindex, jsval v, js_ReportIsNullOrUndefined(JSContext *cx, intN spindex, const Value &v,
JSString *fallback) JSString *fallback)
{ {
char *bytes; char *bytes;
JSBool ok; JSBool ok;
bytes = js_DecompileValueGenerator(cx, spindex, v, fallback); bytes = DecompileValueGenerator(cx, spindex, v, fallback);
if (!bytes) if (!bytes)
return JS_FALSE; return JS_FALSE;
@ -1795,13 +1795,13 @@ js_ReportIsNullOrUndefined(JSContext *cx, intN spindex, jsval v,
js_GetErrorMessage, NULL, js_GetErrorMessage, NULL,
JSMSG_NO_PROPERTIES, bytes, JSMSG_NO_PROPERTIES, bytes,
NULL, NULL); NULL, NULL);
} else if (JSVAL_IS_VOID(v)) { } else if (v.isUndefined()) {
ok = JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, ok = JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR,
js_GetErrorMessage, NULL, js_GetErrorMessage, NULL,
JSMSG_UNEXPECTED_TYPE, bytes, JSMSG_UNEXPECTED_TYPE, bytes,
js_undefined_str, NULL); js_undefined_str, NULL);
} else { } else {
JS_ASSERT(JSVAL_IS_NULL(v)); JS_ASSERT(v.isNull());
ok = JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, ok = JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR,
js_GetErrorMessage, NULL, js_GetErrorMessage, NULL,
JSMSG_UNEXPECTED_TYPE, bytes, JSMSG_UNEXPECTED_TYPE, bytes,
@ -1813,7 +1813,7 @@ js_ReportIsNullOrUndefined(JSContext *cx, intN spindex, jsval v,
} }
void void
js_ReportMissingArg(JSContext *cx, jsval *vp, uintN arg) js_ReportMissingArg(JSContext *cx, const Value &v, uintN arg)
{ {
char argbuf[11]; char argbuf[11];
char *bytes; char *bytes;
@ -1821,10 +1821,10 @@ js_ReportMissingArg(JSContext *cx, jsval *vp, uintN arg)
JS_snprintf(argbuf, sizeof argbuf, "%u", arg); JS_snprintf(argbuf, sizeof argbuf, "%u", arg);
bytes = NULL; bytes = NULL;
if (VALUE_IS_FUNCTION(cx, *vp)) { if (IsFunctionObject(v)) {
atom = GET_FUNCTION_PRIVATE(cx, JSVAL_TO_OBJECT(*vp))->atom; atom = GET_FUNCTION_PRIVATE(cx, &v.toObject())->atom;
bytes = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, *vp, bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK,
ATOM_TO_STRING(atom)); v, ATOM_TO_STRING(atom));
if (!bytes) if (!bytes)
return; return;
} }
@ -1836,7 +1836,7 @@ js_ReportMissingArg(JSContext *cx, jsval *vp, uintN arg)
JSBool JSBool
js_ReportValueErrorFlags(JSContext *cx, uintN flags, const uintN errorNumber, js_ReportValueErrorFlags(JSContext *cx, uintN flags, const uintN errorNumber,
intN spindex, jsval v, JSString *fallback, intN spindex, const Value &v, JSString *fallback,
const char *arg1, const char *arg2) const char *arg1, const char *arg2)
{ {
char *bytes; char *bytes;
@ -1844,7 +1844,7 @@ js_ReportValueErrorFlags(JSContext *cx, uintN flags, const uintN errorNumber,
JS_ASSERT(js_ErrorFormatString[errorNumber].argCount >= 1); JS_ASSERT(js_ErrorFormatString[errorNumber].argCount >= 1);
JS_ASSERT(js_ErrorFormatString[errorNumber].argCount <= 3); JS_ASSERT(js_ErrorFormatString[errorNumber].argCount <= 3);
bytes = js_DecompileValueGenerator(cx, spindex, v, fallback); bytes = DecompileValueGenerator(cx, spindex, v, fallback);
if (!bytes) if (!bytes)
return JS_FALSE; return JS_FALSE;
@ -2230,3 +2230,14 @@ JSContext::purge()
FreeOldArenas(runtime, &regexpPool); FreeOldArenas(runtime, &regexpPool);
} }
namespace js {
void
SetPendingException(JSContext *cx, const Value &v)
{
cx->throwing = JS_TRUE;
cx->exception = v;
}
} /* namespace js */

Просмотреть файл

@ -207,7 +207,7 @@ struct TracerState
// Used when calling natives from trace to root the vp vector. // Used when calling natives from trace to root the vp vector.
uintN nativeVpLen; uintN nativeVpLen;
jsval* nativeVp; js::Value* nativeVp;
// The regs pointed to by cx->regs while a deep-bailed slow native // The regs pointed to by cx->regs while a deep-bailed slow native
// completes execution. // completes execution.
@ -298,14 +298,19 @@ class CallStack
/* If this callstack is suspended, the top of the callstack. */ /* If this callstack is suspended, the top of the callstack. */
JSStackFrame *suspendedFrame; JSStackFrame *suspendedFrame;
/* If this callstack is suspended, |cx->regs| when it was suspended. */ /*
JSFrameRegs *suspendedRegs; * To achieve a sizeof(CallStack) that is a multiple of sizeof(Value), we
* compress two fields into one word:
/* This callstack was suspended by JS_SaveFrameChain. */ *
bool saved; * suspendedRegs: If this callstack is suspended, |cx->regs| when it was
* suspended.
*
* saved: Whether this callstack was suspended by JS_SaveFrameChain.
*/
AlignedPtrAndFlag<JSFrameRegs> suspendedRegsAndSaved;
/* End of arguments before the first frame. See StackSpace comment. */ /* End of arguments before the first frame. See StackSpace comment. */
jsval *initialArgEnd; Value *initialArgEnd;
/* The varobj on entry to initialFrame. */ /* The varobj on entry to initialFrame. */
JSObject *initialVarObj; JSObject *initialVarObj;
@ -313,18 +318,19 @@ class CallStack
public: public:
CallStack() CallStack()
: cx(NULL), previousInContext(NULL), previousInThread(NULL), : cx(NULL), previousInContext(NULL), previousInThread(NULL),
initialFrame(NULL), suspendedFrame(NULL), saved(false), initialFrame(NULL), suspendedFrame(NULL),
initialArgEnd(NULL), initialVarObj(NULL) suspendedRegsAndSaved(NULL, false), initialArgEnd(NULL),
initialVarObj(NULL)
{} {}
/* Safe casts guaranteed by the contiguous-stack layout. */ /* Safe casts guaranteed by the contiguous-stack layout. */
jsval *previousCallStackEnd() const { Value *previousCallStackEnd() const {
return (jsval *)this; return (Value *)this;
} }
jsval *getInitialArgBegin() const { Value *getInitialArgBegin() const {
return (jsval *)(this + 1); return (Value *)(this + 1);
} }
/* /*
@ -340,8 +346,8 @@ class CallStack
bool inContext() const { bool inContext() const {
JS_ASSERT(!!cx == !!initialFrame); JS_ASSERT(!!cx == !!initialFrame);
JS_ASSERT_IF(!initialFrame, !suspendedFrame && !saved); JS_ASSERT_IF(!initialFrame, !suspendedFrame && !suspendedRegsAndSaved.flag());
return cx; return !!cx;
} }
bool isActive() const { bool isActive() const {
@ -350,15 +356,15 @@ class CallStack
} }
bool isSuspended() const { bool isSuspended() const {
JS_ASSERT_IF(!suspendedFrame, !saved); JS_ASSERT_IF(!suspendedFrame, !suspendedRegsAndSaved.flag());
JS_ASSERT_IF(suspendedFrame, inContext()); JS_ASSERT_IF(suspendedFrame, inContext());
return suspendedFrame; return !!suspendedFrame;
} }
/* Substate of suspended, queryable in any state. */ /* Substate of suspended, queryable in any state. */
bool isSaved() const { bool isSaved() const {
JS_ASSERT_IF(saved, isSuspended()); JS_ASSERT_IF(suspendedRegsAndSaved.flag(), isSuspended());
return saved; return suspendedRegsAndSaved.flag();
} }
/* Transitioning between inContext <--> isActive */ /* Transitioning between inContext <--> isActive */
@ -388,7 +394,7 @@ class CallStack
JS_ASSERT(fp && contains(fp)); JS_ASSERT(fp && contains(fp));
suspendedFrame = fp; suspendedFrame = fp;
JS_ASSERT(isSuspended()); JS_ASSERT(isSuspended());
suspendedRegs = regs; suspendedRegsAndSaved.setPtr(regs);
} }
void resume() { void resume() {
@ -402,25 +408,25 @@ class CallStack
void save(JSStackFrame *fp, JSFrameRegs *regs) { void save(JSStackFrame *fp, JSFrameRegs *regs) {
JS_ASSERT(!isSaved()); JS_ASSERT(!isSaved());
suspend(fp, regs); suspend(fp, regs);
saved = true; suspendedRegsAndSaved.setFlag();
JS_ASSERT(isSaved()); JS_ASSERT(isSaved());
} }
void restore() { void restore() {
JS_ASSERT(isSaved()); JS_ASSERT(isSaved());
saved = false; suspendedRegsAndSaved.unsetFlag();
resume(); resume();
JS_ASSERT(!isSaved()); JS_ASSERT(!isSaved());
} }
/* Data available when !inContext */ /* Data available when !inContext */
void setInitialArgEnd(jsval *v) { void setInitialArgEnd(Value *v) {
JS_ASSERT(!inContext() && !initialArgEnd); JS_ASSERT(!inContext() && !initialArgEnd);
initialArgEnd = v; initialArgEnd = v;
} }
jsval *getInitialArgEnd() const { Value *getInitialArgEnd() const {
JS_ASSERT(!inContext() && initialArgEnd); JS_ASSERT(!inContext() && initialArgEnd);
return initialArgEnd; return initialArgEnd;
} }
@ -443,12 +449,7 @@ class CallStack
JSFrameRegs *getSuspendedRegs() const { JSFrameRegs *getSuspendedRegs() const {
JS_ASSERT(isSuspended()); JS_ASSERT(isSuspended());
return suspendedRegs; return suspendedRegsAndSaved.ptr();
}
jsval *getSuspendedSP() const {
JS_ASSERT(isSuspended());
return suspendedRegs->sp;
} }
/* JSContext / js::StackSpace bookkeeping. */ /* JSContext / js::StackSpace bookkeeping. */
@ -485,26 +486,26 @@ class CallStack
}; };
static const size_t VALUES_PER_CALL_STACK = sizeof(CallStack) / sizeof(jsval); static const size_t VALUES_PER_CALL_STACK = sizeof(CallStack) / sizeof(Value);
JS_STATIC_ASSERT(sizeof(CallStack) % sizeof(jsval) == 0); JS_STATIC_ASSERT(sizeof(CallStack) % sizeof(Value) == 0);
/* /*
* The ternary constructor is used when arguments are already pushed on the * The ternary constructor is used when arguments are already pushed on the
* stack (as the sp of the current frame), which should only happen from within * stack (as the sp of the current frame), which should only happen from within
* js_Interpret. Otherwise, see StackSpace::pushInvokeArgs. * Interpret. Otherwise, see StackSpace::pushInvokeArgs.
*/ */
class InvokeArgsGuard class InvokeArgsGuard
{ {
friend class StackSpace; friend class StackSpace;
JSContext *cx; JSContext *cx;
CallStack *cs; /* null implies nothing pushed */ CallStack *cs; /* null implies nothing pushed */
jsval *vp; Value *vp;
uintN argc; uintN argc;
public: public:
inline InvokeArgsGuard(); inline InvokeArgsGuard();
inline InvokeArgsGuard(jsval *vp, uintN argc); inline InvokeArgsGuard(Value *vp, uintN argc);
inline ~InvokeArgsGuard(); inline ~InvokeArgsGuard();
jsval *getvp() const { return vp; } Value *getvp() const { return vp; }
uintN getArgc() const { JS_ASSERT(vp != NULL); return argc; } uintN getArgc() const { JS_ASSERT(vp != NULL); return argc; }
}; };
@ -527,13 +528,13 @@ class ExecuteFrameGuard
friend class StackSpace; friend class StackSpace;
JSContext *cx; /* null implies nothing pushed */ JSContext *cx; /* null implies nothing pushed */
CallStack *cs; CallStack *cs;
jsval *vp; Value *vp;
JSStackFrame *fp; JSStackFrame *fp;
JSStackFrame *down; JSStackFrame *down;
public: public:
ExecuteFrameGuard(); ExecuteFrameGuard();
JS_REQUIRES_STACK ~ExecuteFrameGuard(); JS_REQUIRES_STACK ~ExecuteFrameGuard();
jsval *getvp() const { return vp; } Value *getvp() const { return vp; }
JSStackFrame *getFrame() const { return fp; } JSStackFrame *getFrame() const { return fp; }
}; };
@ -563,11 +564,11 @@ class ExecuteFrameGuard
* down down down * down down down
* *
* Moreover, the bytes in the following ranges form a contiguous array of * Moreover, the bytes in the following ranges form a contiguous array of
* jsvals that are marked during GC: * Values that are marked during GC:
* 1. between a callstack and its first frame * 1. between a callstack and its first frame
* 2. between two adjacent frames in a callstack * 2. between two adjacent frames in a callstack
* 3. between a callstack's current frame and (if fp->regs) fp->regs->sp * 3. between a callstack's current frame and (if fp->regs) fp->regs->sp
* Thus, the VM must ensure that all such jsvals are safe to be marked. * Thus, the VM must ensure that all such Values are safe to be marked.
* *
* An empty callstack roots the initial slots before the initial frame is * An empty callstack roots the initial slots before the initial frame is
* pushed and after the initial frame has been popped (perhaps to be followed * pushed and after the initial frame has been popped (perhaps to be followed
@ -608,16 +609,16 @@ class ExecuteFrameGuard
*/ */
class StackSpace class StackSpace
{ {
jsval *base; Value *base;
#ifdef XP_WIN #ifdef XP_WIN
mutable jsval *commitEnd; mutable Value *commitEnd;
#endif #endif
jsval *end; Value *end;
CallStack *currentCallStack; CallStack *currentCallStack;
/* Although guards are friends, XGuard should only call popX(). */ /* Although guards are friends, XGuard should only call popX(). */
friend class InvokeArgsGuard; friend class InvokeArgsGuard;
JS_REQUIRES_STACK inline void popInvokeArgs(JSContext *cx, jsval *vp); JS_REQUIRES_STACK inline void popInvokeArgs(JSContext *cx, Value *vp);
friend class InvokeFrameGuard; friend class InvokeFrameGuard;
JS_REQUIRES_STACK void popInvokeFrame(JSContext *cx, CallStack *maybecs); JS_REQUIRES_STACK void popInvokeFrame(JSContext *cx, CallStack *maybecs);
friend class ExecuteFrameGuard; friend class ExecuteFrameGuard;
@ -625,7 +626,7 @@ class StackSpace
/* Return a pointer to the first unused slot. */ /* Return a pointer to the first unused slot. */
JS_REQUIRES_STACK JS_REQUIRES_STACK
inline jsval *firstUnused() const; inline Value *firstUnused() const;
inline void assertIsCurrent(JSContext *cx) const; inline void assertIsCurrent(JSContext *cx) const;
#ifdef DEBUG #ifdef DEBUG
@ -636,18 +637,18 @@ class StackSpace
* Allocate nvals on the top of the stack, report error on failure. * Allocate nvals on the top of the stack, report error on failure.
* N.B. the caller must ensure |from == firstUnused()|. * N.B. the caller must ensure |from == firstUnused()|.
*/ */
inline bool ensureSpace(JSContext *maybecx, jsval *from, ptrdiff_t nvals) const; inline bool ensureSpace(JSContext *maybecx, Value *from, ptrdiff_t nvals) const;
#ifdef XP_WIN #ifdef XP_WIN
/* Commit more memory from the reserved stack space. */ /* Commit more memory from the reserved stack space. */
JS_FRIEND_API(bool) bumpCommit(jsval *from, ptrdiff_t nvals) const; JS_FRIEND_API(bool) bumpCommit(Value *from, ptrdiff_t nvals) const;
#endif #endif
public: public:
static const size_t CAPACITY_VALS = 512 * 1024; static const size_t CAPACITY_VALS = 512 * 1024;
static const size_t CAPACITY_BYTES = CAPACITY_VALS * sizeof(jsval); static const size_t CAPACITY_BYTES = CAPACITY_VALS * sizeof(Value);
static const size_t COMMIT_VALS = 16 * 1024; static const size_t COMMIT_VALS = 16 * 1024;
static const size_t COMMIT_BYTES = COMMIT_VALS * sizeof(jsval); static const size_t COMMIT_BYTES = COMMIT_VALS * sizeof(Value);
/* Kept as a member of JSThreadData; cannot use constructor/destructor. */ /* Kept as a member of JSThreadData; cannot use constructor/destructor. */
bool init(); bool init();
@ -730,7 +731,7 @@ class StackSpace
* call pushInlineFrame/popInlineFrame. * call pushInlineFrame/popInlineFrame.
*/ */
JS_REQUIRES_STACK JS_REQUIRES_STACK
inline JSStackFrame *getInlineFrame(JSContext *cx, jsval *sp, inline JSStackFrame *getInlineFrame(JSContext *cx, Value *sp,
uintN nmissing, uintN nfixed) const; uintN nmissing, uintN nfixed) const;
JS_REQUIRES_STACK JS_REQUIRES_STACK
@ -775,7 +776,7 @@ class FrameRegsIter
{ {
CallStack *curcs; CallStack *curcs;
JSStackFrame *curfp; JSStackFrame *curfp;
jsval *cursp; Value *cursp;
jsbytecode *curpc; jsbytecode *curpc;
public: public:
@ -785,7 +786,7 @@ class FrameRegsIter
FrameRegsIter &operator++(); FrameRegsIter &operator++();
JSStackFrame *fp() const { return curfp; } JSStackFrame *fp() const { return curfp; }
jsval *sp() const { return cursp; } Value *sp() const { return cursp; }
jsbytecode *pc() const { return curpc; } jsbytecode *pc() const { return curpc; }
}; };
@ -1134,7 +1135,7 @@ struct GCPtrHasher
typedef void *Lookup; typedef void *Lookup;
static HashNumber hash(void *key) { static HashNumber hash(void *key) {
return HashNumber(uintptr_t(key) >> JSVAL_TAGBITS); return HashNumber(uintptr_t(key) >> JS_GCTHING_ZEROBITS);
} }
static bool match(void *l, void *k) { static bool match(void *l, void *k) {
@ -1142,25 +1143,41 @@ struct GCPtrHasher
} }
}; };
typedef HashMap<void *, const char *, GCPtrHasher, SystemAllocPolicy> GCRoots;
typedef HashMap<void *, uint32, GCPtrHasher, SystemAllocPolicy> GCLocks; typedef HashMap<void *, uint32, GCPtrHasher, SystemAllocPolicy> GCLocks;
struct RootInfo {
RootInfo() {}
RootInfo(const char *name, JSGCRootType type) : name(name), type(type) {}
const char *name;
JSGCRootType type;
};
typedef js::HashMap<void *,
RootInfo,
js::DefaultHasher<void *>,
js::SystemAllocPolicy> RootedValueMap;
/* If HashNumber grows, need to change WrapperHasher. */
JS_STATIC_ASSERT(sizeof(HashNumber) == 4);
struct WrapperHasher struct WrapperHasher
{ {
typedef jsval Lookup; typedef Value Lookup;
static HashNumber hash(jsval key) { static HashNumber hash(Value key) {
return GCPtrHasher::hash(JSVAL_TO_GCTHING(key)); uint64 bits = JSVAL_BITS(Jsvalify(key));
return (uint32)bits ^ (uint32)(bits >> 32);
} }
static bool match(jsval l, jsval k) { static bool match(const Value &l, const Value &k) {
return l == k; return l == k;
} }
}; };
typedef HashMap<jsval, jsval, WrapperHasher, SystemAllocPolicy> WrapperMap; typedef HashMap<Value, Value, WrapperHasher, SystemAllocPolicy> WrapperMap;
class AutoValueVector; class AutoValueVector;
class AutoIdVector;
} /* namespace js */ } /* namespace js */
@ -1175,13 +1192,13 @@ struct JSCompartment {
bool init(); bool init();
bool wrap(JSContext *cx, jsval *vp); bool wrap(JSContext *cx, js::Value *vp);
bool wrap(JSContext *cx, JSString **strp); bool wrap(JSContext *cx, JSString **strp);
bool wrap(JSContext *cx, JSObject **objp); bool wrap(JSContext *cx, JSObject **objp);
bool wrapId(JSContext *cx, jsid *idp); bool wrapId(JSContext *cx, jsid *idp);
bool wrap(JSContext *cx, JSPropertyOp *op); bool wrap(JSContext *cx, js::PropertyOp *op);
bool wrap(JSContext *cx, JSPropertyDescriptor *desc); bool wrap(JSContext *cx, js::PropertyDescriptor *desc);
bool wrap(JSContext *cx, js::AutoValueVector &props); bool wrap(JSContext *cx, js::AutoIdVector &props);
bool wrapException(JSContext *cx); bool wrapException(JSContext *cx);
void sweep(JSContext *cx); void sweep(JSContext *cx);
@ -1221,8 +1238,7 @@ struct JSRuntime {
JSGCArena *gcEmptyArenaList; JSGCArena *gcEmptyArenaList;
#endif #endif
JSGCArenaList gcArenaList[FINALIZE_LIMIT]; JSGCArenaList gcArenaList[FINALIZE_LIMIT];
JSGCDoubleArenaList gcDoubleArenaList; js::RootedValueMap gcRootsHash;
js::GCRoots gcRootsHash;
js::GCLocks gcLocksHash; js::GCLocks gcLocksHash;
jsrefcount gcKeepAtoms; jsrefcount gcKeepAtoms;
size_t gcBytes; size_t gcBytes;
@ -1296,9 +1312,9 @@ struct JSRuntime {
void *gcExtraRootsData; void *gcExtraRootsData;
/* Well-known numbers held for use by this runtime's contexts. */ /* Well-known numbers held for use by this runtime's contexts. */
jsval NaNValue; js::Value NaNValue;
jsval negativeInfinityValue; js::Value negativeInfinityValue;
jsval positiveInfinityValue; js::Value positiveInfinityValue;
js::DeflatedStringCache *deflatedStringCache; js::DeflatedStringCache *deflatedStringCache;
@ -1685,7 +1701,7 @@ struct JSContext
/* /*
* cx->resolvingTable is non-null and non-empty if we are initializing * cx->resolvingTable is non-null and non-empty if we are initializing
* standard classes lazily, or if we are otherwise recursing indirectly * standard classes lazily, or if we are otherwise recursing indirectly
* from js_LookupProperty through a JSClass.resolve hook. It is used to * from js_LookupProperty through a Class.resolve hook. It is used to
* limit runaway recursion (see jsapi.c and jsobj.c). * limit runaway recursion (see jsapi.c and jsobj.c).
*/ */
JSDHashTable *resolvingTable; JSDHashTable *resolvingTable;
@ -1701,7 +1717,7 @@ struct JSContext
/* Exception state -- the exception member is a GC root by definition. */ /* Exception state -- the exception member is a GC root by definition. */
JSPackedBool throwing; /* is there a pending exception? */ JSPackedBool throwing; /* is there a pending exception? */
jsval exception; /* most-recently-thrown exception */ js::Value exception; /* most-recently-thrown exception */
/* Limit pointer for checking native stack consumption during recursion. */ /* Limit pointer for checking native stack consumption during recursion. */
jsuword stackLimit; jsuword stackLimit;
@ -1728,7 +1744,7 @@ struct JSContext
private: private:
friend class js::StackSpace; friend class js::StackSpace;
friend JSBool js_Interpret(JSContext *); friend bool js::Interpret(JSContext *);
/* 'fp' and 'regs' must only be changed by calling these functions. */ /* 'fp' and 'regs' must only be changed by calling these functions. */
void setCurrentFrame(JSStackFrame *fp) { void setCurrentFrame(JSStackFrame *fp) {
@ -1799,7 +1815,7 @@ struct JSContext
/* Return whether this context has an active callstack. */ /* Return whether this context has an active callstack. */
bool hasActiveCallStack() const { bool hasActiveCallStack() const {
assertCallStacksInSync(); assertCallStacksInSync();
return fp; return !!fp;
} }
/* Assuming there is an active callstack, return it. */ /* Assuming there is an active callstack, return it. */
@ -1869,7 +1885,7 @@ struct JSContext
int64 rngSeed; int64 rngSeed;
/* Location to stash the iteration value between JSOP_MOREITER and JSOP_FOR*. */ /* Location to stash the iteration value between JSOP_MOREITER and JSOP_FOR*. */
jsval iterValue; js::Value iterValue;
#ifdef JS_TRACER #ifdef JS_TRACER
/* /*
@ -2070,8 +2086,8 @@ struct JSContext
#ifdef DEBUG #ifdef DEBUG
void assertValidStackDepth(uintN depth) { void assertValidStackDepth(uintN depth) {
JS_ASSERT(0 <= regs->sp - StackBase(fp)); JS_ASSERT(0 <= regs->sp - fp->base());
JS_ASSERT(depth <= uintptr_t(regs->sp - StackBase(fp))); JS_ASSERT(depth <= uintptr_t(regs->sp - fp->base()));
} }
#else #else
void assertValidStackDepth(uintN /*depth*/) {} void assertValidStackDepth(uintN /*depth*/) {}
@ -2116,7 +2132,7 @@ JSStackFrame::pc(JSContext *cx) const
namespace js { namespace js {
JS_ALWAYS_INLINE void JS_ALWAYS_INLINE void
StackSpace::popInvokeArgs(JSContext *cx, jsval *vp) StackSpace::popInvokeArgs(JSContext *cx, Value *vp)
{ {
JS_ASSERT(!currentCallStack->inContext()); JS_ASSERT(!currentCallStack->inContext());
currentCallStack = currentCallStack->getPreviousInThread(); currentCallStack = currentCallStack->getPreviousInThread();
@ -2128,7 +2144,7 @@ InvokeArgsGuard::InvokeArgsGuard()
{} {}
JS_ALWAYS_INLINE JS_ALWAYS_INLINE
InvokeArgsGuard::InvokeArgsGuard(jsval *vp, uintN argc) InvokeArgsGuard::InvokeArgsGuard(Value *vp, uintN argc)
: cx(NULL), cs(NULL), vp(vp), argc(argc) : cx(NULL), cs(NULL), vp(vp), argc(argc)
{} {}
@ -2218,7 +2234,7 @@ class AutoGCRooter {
/* /*
* Discriminates actual subclass of this being used. If non-negative, the * Discriminates actual subclass of this being used. If non-negative, the
* subclass roots an array of jsvals of the length stored in this field. * subclass roots an array of values of the length stored in this field.
* If negative, meaning is indicated by the corresponding value in the enum * If negative, meaning is indicated by the corresponding value in the enum
* below. Any other negative value indicates some deeper problem such as * below. Any other negative value indicates some deeper problem such as
* memory corruption. * memory corruption.
@ -2235,13 +2251,15 @@ class AutoGCRooter {
SCRIPT = -5, /* js::AutoScriptRooter */ SCRIPT = -5, /* js::AutoScriptRooter */
ENUMERATOR = -6, /* js::AutoEnumStateRooter */ ENUMERATOR = -6, /* js::AutoEnumStateRooter */
IDARRAY = -7, /* js::AutoIdArray */ IDARRAY = -7, /* js::AutoIdArray */
DESCRIPTORS = -8, /* js::AutoDescriptorArray */ DESCRIPTORS = -8, /* js::AutoPropDescArrayRooter */
NAMESPACES = -9, /* js::AutoNamespaceArray */ NAMESPACES = -9, /* js::AutoNamespaceArray */
XML = -10, /* js::AutoXMLRooter */ XML = -10, /* js::AutoXMLRooter */
OBJECT = -11, /* js::AutoObjectRooter */ OBJECT = -11, /* js::AutoObjectRooter */
ID = -12, /* js::AutoIdRooter */ ID = -12, /* js::AutoIdRooter */
VECTOR = -13, /* js::AutoValueVector */ VALVECTOR = -13, /* js::AutoValueVector */
DESCRIPTOR = -14 /* js::AutoDescriptor */ DESCRIPTOR = -14, /* js::AutoPropertyDescriptorRooter */
STRING = -15, /* js::AutoStringRooter */
IDVECTOR = -16 /* js::AutoIdVector */
}; };
private: private:
@ -2276,61 +2294,67 @@ class AutoPreserveWeakRoots : private AutoGCRooter
class AutoValueRooter : private AutoGCRooter class AutoValueRooter : private AutoGCRooter
{ {
public: public:
explicit AutoValueRooter(JSContext *cx, jsval v = JSVAL_NULL explicit AutoValueRooter(JSContext *cx
JS_GUARD_OBJECT_NOTIFIER_PARAM)
: AutoGCRooter(cx, JSVAL), val(js::NullValue())
{
JS_GUARD_OBJECT_NOTIFIER_INIT;
}
AutoValueRooter(JSContext *cx, const Value &v
JS_GUARD_OBJECT_NOTIFIER_PARAM) JS_GUARD_OBJECT_NOTIFIER_PARAM)
: AutoGCRooter(cx, JSVAL), val(v) : AutoGCRooter(cx, JSVAL), val(v)
{ {
JS_GUARD_OBJECT_NOTIFIER_INIT; JS_GUARD_OBJECT_NOTIFIER_INIT;
} }
AutoValueRooter(JSContext *cx, JSString *str
AutoValueRooter(JSContext *cx, jsval v
JS_GUARD_OBJECT_NOTIFIER_PARAM) JS_GUARD_OBJECT_NOTIFIER_PARAM)
: AutoGCRooter(cx, JSVAL), val(STRING_TO_JSVAL(str)) : AutoGCRooter(cx, JSVAL), val(js::Valueify(v))
{
JS_GUARD_OBJECT_NOTIFIER_INIT;
}
AutoValueRooter(JSContext *cx, JSObject *obj
JS_GUARD_OBJECT_NOTIFIER_PARAM)
: AutoGCRooter(cx, JSVAL), val(OBJECT_TO_JSVAL(obj))
{ {
JS_GUARD_OBJECT_NOTIFIER_INIT; JS_GUARD_OBJECT_NOTIFIER_INIT;
} }
void set(jsval v) { /*
* If you are looking for Object* overloads, use AutoObjectRooter instead;
* rooting Object*s as a js::Value requires discerning whether or not it is
* a function object. Also, AutoObjectRooter is smaller.
*/
void set(Value v) {
JS_ASSERT(tag == JSVAL); JS_ASSERT(tag == JSVAL);
val = v; val = v;
} }
void setObject(JSObject *obj) { void set(jsval v) {
JS_ASSERT(tag == JSVAL); JS_ASSERT(tag == JSVAL);
val = OBJECT_TO_JSVAL(obj); val = js::Valueify(v);
} }
void setString(JSString *str) { const Value &value() const {
JS_ASSERT(tag == JSVAL);
JS_ASSERT(str);
val = STRING_TO_JSVAL(str);
}
void setDouble(jsdouble *dp) {
JS_ASSERT(tag == JSVAL);
JS_ASSERT(dp);
val = DOUBLE_TO_JSVAL(dp);
}
jsval value() const {
JS_ASSERT(tag == JSVAL); JS_ASSERT(tag == JSVAL);
return val; return val;
} }
jsval *addr() { Value *addr() {
JS_ASSERT(tag == JSVAL); JS_ASSERT(tag == JSVAL);
return &val; return &val;
} }
const jsval &jsval_value() const {
JS_ASSERT(tag == JSVAL);
return Jsvalify(val);
}
jsval *jsval_addr() {
JS_ASSERT(tag == JSVAL);
return Jsvalify(&val);
}
friend void AutoGCRooter::trace(JSTracer *trc); friend void AutoGCRooter::trace(JSTracer *trc);
private: private:
jsval val; Value val;
JS_DECL_USE_GUARD_OBJECT_NOTIFIER JS_DECL_USE_GUARD_OBJECT_NOTIFIER
}; };
@ -2362,9 +2386,37 @@ class AutoObjectRooter : private AutoGCRooter {
JS_DECL_USE_GUARD_OBJECT_NOTIFIER JS_DECL_USE_GUARD_OBJECT_NOTIFIER
}; };
class AutoStringRooter : private AutoGCRooter {
public:
AutoStringRooter(JSContext *cx, JSString *str = NULL
JS_GUARD_OBJECT_NOTIFIER_PARAM)
: AutoGCRooter(cx, STRING), str(str)
{
JS_GUARD_OBJECT_NOTIFIER_INIT;
}
void setString(JSString *str) {
this->str = str;
}
JSString * string() const {
return str;
}
JSString ** addr() {
return &str;
}
friend void AutoGCRooter::trace(JSTracer *trc);
private:
JSString *str;
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
};
class AutoArrayRooter : private AutoGCRooter { class AutoArrayRooter : private AutoGCRooter {
public: public:
AutoArrayRooter(JSContext *cx, size_t len, jsval *vec AutoArrayRooter(JSContext *cx, size_t len, Value *vec
JS_GUARD_OBJECT_NOTIFIER_PARAM) JS_GUARD_OBJECT_NOTIFIER_PARAM)
: AutoGCRooter(cx, len), array(vec) : AutoGCRooter(cx, len), array(vec)
{ {
@ -2372,17 +2424,25 @@ class AutoArrayRooter : private AutoGCRooter {
JS_ASSERT(tag >= 0); JS_ASSERT(tag >= 0);
} }
AutoArrayRooter(JSContext *cx, size_t len, jsval *vec
JS_GUARD_OBJECT_NOTIFIER_PARAM)
: AutoGCRooter(cx, len), array(Valueify(vec))
{
JS_GUARD_OBJECT_NOTIFIER_INIT;
JS_ASSERT(tag >= 0);
}
void changeLength(size_t newLength) { void changeLength(size_t newLength) {
tag = ptrdiff_t(newLength); tag = ptrdiff_t(newLength);
JS_ASSERT(tag >= 0); JS_ASSERT(tag >= 0);
} }
void changeArray(jsval *newArray, size_t newLength) { void changeArray(Value *newArray, size_t newLength) {
changeLength(newLength); changeLength(newLength);
array = newArray; array = newArray;
} }
jsval *array; Value *array;
friend void AutoGCRooter::trace(JSTracer *trc); friend void AutoGCRooter::trace(JSTracer *trc);
@ -2431,23 +2491,23 @@ class AutoIdRooter : private AutoGCRooter
public: public:
explicit AutoIdRooter(JSContext *cx, jsid id = INT_TO_JSID(0) explicit AutoIdRooter(JSContext *cx, jsid id = INT_TO_JSID(0)
JS_GUARD_OBJECT_NOTIFIER_PARAM) JS_GUARD_OBJECT_NOTIFIER_PARAM)
: AutoGCRooter(cx, ID), idval(id) : AutoGCRooter(cx, ID), id_(id)
{ {
JS_GUARD_OBJECT_NOTIFIER_INIT; JS_GUARD_OBJECT_NOTIFIER_INIT;
} }
jsid id() { jsid id() {
return idval; return id_;
} }
jsid * addr() { jsid * addr() {
return &idval; return &id_;
} }
friend void AutoGCRooter::trace(JSTracer *trc); friend void AutoGCRooter::trace(JSTracer *trc);
private: private:
jsid idval; jsid id_;
JS_DECL_USE_GUARD_OBJECT_NOTIFIER JS_DECL_USE_GUARD_OBJECT_NOTIFIER
}; };
@ -2500,14 +2560,14 @@ class AutoEnumStateRooter : private AutoGCRooter
public: public:
AutoEnumStateRooter(JSContext *cx, JSObject *obj AutoEnumStateRooter(JSContext *cx, JSObject *obj
JS_GUARD_OBJECT_NOTIFIER_PARAM) JS_GUARD_OBJECT_NOTIFIER_PARAM)
: AutoGCRooter(cx, ENUMERATOR), obj(obj), stateValue(JSVAL_NULL) : AutoGCRooter(cx, ENUMERATOR), obj(obj), stateValue()
{ {
JS_GUARD_OBJECT_NOTIFIER_INIT; JS_GUARD_OBJECT_NOTIFIER_INIT;
JS_ASSERT(obj); JS_ASSERT(obj);
} }
~AutoEnumStateRooter() { ~AutoEnumStateRooter() {
if (!JSVAL_IS_NULL(stateValue)) { if (!stateValue.isNull()) {
#ifdef DEBUG #ifdef DEBUG
JSBool ok = JSBool ok =
#endif #endif
@ -2518,8 +2578,8 @@ class AutoEnumStateRooter : private AutoGCRooter
friend void AutoGCRooter::trace(JSTracer *trc); friend void AutoGCRooter::trace(JSTracer *trc);
jsval state() const { return stateValue; } const Value &state() const { return stateValue; }
jsval * addr() { return &stateValue; } Value *addr() { return &stateValue; }
protected: protected:
void trace(JSTracer *trc) { void trace(JSTracer *trc) {
@ -2529,7 +2589,7 @@ class AutoEnumStateRooter : private AutoGCRooter
JSObject * const obj; JSObject * const obj;
private: private:
jsval stateValue; Value stateValue;
JS_DECL_USE_GUARD_OBJECT_NOTIFIER JS_DECL_USE_GUARD_OBJECT_NOTIFIER
}; };
@ -2753,7 +2813,7 @@ extern JS_FRIEND_API(JSContext *)
js_NextActiveContext(JSRuntime *, JSContext *); js_NextActiveContext(JSRuntime *, JSContext *);
/* /*
* JSClass.resolve and watchpoint recursion damping machinery. * Class.resolve and watchpoint recursion damping machinery.
*/ */
extern JSBool extern JSBool
js_StartResolving(JSContext *cx, JSResolvingKey *key, uint32 flag, js_StartResolving(JSContext *cx, JSResolvingKey *key, uint32 flag,
@ -2833,11 +2893,11 @@ js_ReportIsNotDefined(JSContext *cx, const char *name);
* Report an attempt to access the property of a null or undefined value (v). * Report an attempt to access the property of a null or undefined value (v).
*/ */
extern JSBool extern JSBool
js_ReportIsNullOrUndefined(JSContext *cx, intN spindex, jsval v, js_ReportIsNullOrUndefined(JSContext *cx, intN spindex, const js::Value &v,
JSString *fallback); JSString *fallback);
extern void extern void
js_ReportMissingArg(JSContext *cx, jsval *vp, uintN arg); js_ReportMissingArg(JSContext *cx, const js::Value &v, uintN arg);
/* /*
* Report error using js_DecompileValueGenerator(cx, spindex, v, fallback) as * Report error using js_DecompileValueGenerator(cx, spindex, v, fallback) as
@ -2846,7 +2906,7 @@ js_ReportMissingArg(JSContext *cx, jsval *vp, uintN arg);
*/ */
extern JSBool extern JSBool
js_ReportValueErrorFlags(JSContext *cx, uintN flags, const uintN errorNumber, js_ReportValueErrorFlags(JSContext *cx, uintN flags, const uintN errorNumber,
intN spindex, jsval v, JSString *fallback, intN spindex, const js::Value &v, JSString *fallback,
const char *arg1, const char *arg2); const char *arg1, const char *arg2);
#define js_ReportValueError(cx,errorNumber,spindex,v,fallback) \ #define js_ReportValueError(cx,errorNumber,spindex,v,fallback) \
@ -2931,7 +2991,7 @@ LeaveTrace(JSContext *cx)
static JS_INLINE void static JS_INLINE void
LeaveTraceIfGlobalObject(JSContext *cx, JSObject *obj) LeaveTraceIfGlobalObject(JSContext *cx, JSObject *obj)
{ {
if (!obj->fslots[JSSLOT_PARENT]) if (obj->fslots[JSSLOT_PARENT].isNull())
LeaveTrace(cx); LeaveTrace(cx);
} }
@ -2946,6 +3006,9 @@ CanLeaveTrace(JSContext *cx)
#endif #endif
} }
extern void
SetPendingException(JSContext *cx, const Value &v);
} /* namespace js */ } /* namespace js */
/* /*
@ -3015,20 +3078,21 @@ class AutoValueVector : private AutoGCRooter
public: public:
explicit AutoValueVector(JSContext *cx explicit AutoValueVector(JSContext *cx
JS_GUARD_OBJECT_NOTIFIER_PARAM) JS_GUARD_OBJECT_NOTIFIER_PARAM)
: AutoGCRooter(cx, VECTOR), vector(cx) : AutoGCRooter(cx, VALVECTOR), vector(cx)
{ {
JS_GUARD_OBJECT_NOTIFIER_INIT; JS_GUARD_OBJECT_NOTIFIER_INIT;
} }
size_t length() const { return vector.length(); } size_t length() const { return vector.length(); }
bool append(jsval v) { return vector.append(v); } bool append(const Value &v) { return vector.append(v); }
bool append(JSString *str) { return append(STRING_TO_JSVAL(str)); }
bool append(JSObject *obj) { return append(OBJECT_TO_JSVAL(obj)); }
bool append(jsdouble *dp) { return append(DOUBLE_TO_JSVAL(dp)); }
void popBack() { vector.popBack(); } void popBack() { vector.popBack(); }
bool growBy(size_t inc) {
return vector.growBy(inc);
}
bool resize(size_t newLength) { bool resize(size_t newLength) {
return vector.resize(newLength); return vector.resize(newLength);
} }
@ -3037,29 +3101,113 @@ class AutoValueVector : private AutoGCRooter
return vector.reserve(newLength); return vector.reserve(newLength);
} }
jsval &operator[](size_t i) { return vector[i]; } Value &operator[](size_t i) { return vector[i]; }
jsval operator[](size_t i) const { return vector[i]; } const Value &operator[](size_t i) const { return vector[i]; }
const jsval *begin() const { return vector.begin(); } const Value *begin() const { return vector.begin(); }
jsval *begin() { return vector.begin(); } Value *begin() { return vector.begin(); }
const jsval *end() const { return vector.end(); } const Value *end() const { return vector.end(); }
jsval *end() { return vector.end(); } Value *end() { return vector.end(); }
jsval back() const { return end()[-1]; } const Value &back() const { return vector.back(); }
friend void AutoGCRooter::trace(JSTracer *trc); friend void AutoGCRooter::trace(JSTracer *trc);
private: private:
Vector<jsval, 8> vector; Vector<Value, 8> vector;
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
};
class AutoIdVector : private AutoGCRooter
{
public:
explicit AutoIdVector(JSContext *cx
JS_GUARD_OBJECT_NOTIFIER_PARAM)
: AutoGCRooter(cx, IDVECTOR), vector(cx)
{
JS_GUARD_OBJECT_NOTIFIER_INIT;
}
size_t length() const { return vector.length(); }
bool append(jsid id) { return vector.append(id); }
void popBack() { vector.popBack(); }
bool growBy(size_t inc) {
return vector.growBy(inc);
}
bool resize(size_t newLength) {
return vector.resize(newLength);
}
bool reserve(size_t newLength) {
return vector.reserve(newLength);
}
jsid &operator[](size_t i) { return vector[i]; }
const jsid &operator[](size_t i) const { return vector[i]; }
const jsid *begin() const { return vector.begin(); }
jsid *begin() { return vector.begin(); }
const jsid *end() const { return vector.end(); }
jsid *end() { return vector.end(); }
const jsid &back() const { return vector.back(); }
friend void AutoGCRooter::trace(JSTracer *trc);
private:
Vector<jsid, 8> vector;
JS_DECL_USE_GUARD_OBJECT_NOTIFIER JS_DECL_USE_GUARD_OBJECT_NOTIFIER
}; };
JSIdArray * JSIdArray *
NewIdArray(JSContext *cx, jsint length); NewIdArray(JSContext *cx, jsint length);
static JS_ALWAYS_INLINE void
MakeValueRangeGCSafe(Value *vec, uintN len)
{
PodZero(vec, len);
} }
static JS_ALWAYS_INLINE void
MakeValueRangeGCSafe(Value *beg, Value *end)
{
PodZero(beg, end - beg);
}
static JS_ALWAYS_INLINE void
SetValueRangeToUndefined(Value *beg, Value *end)
{
for (Value *v = beg; v != end; ++v)
v->setUndefined();
}
static JS_ALWAYS_INLINE void
SetValueRangeToUndefined(Value *vec, uintN len)
{
return SetValueRangeToUndefined(vec, vec + len);
}
static JS_ALWAYS_INLINE void
SetValueRangeToNull(Value *beg, Value *end)
{
for (Value *v = beg; v != end; ++v)
v->setNull();
}
static JS_ALWAYS_INLINE void
SetValueRangeToNull(Value *vec, uintN len)
{
return SetValueRangeToNull(vec, vec + len);
}
} /* namespace js */
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(pop) #pragma warning(pop)
#pragma warning(pop) #pragma warning(pop)

Просмотреть файл

@ -63,7 +63,7 @@ CallStack::getCurrentFrame() const
return isSuspended() ? getSuspendedFrame() : cx->fp; return isSuspended() ? getSuspendedFrame() : cx->fp;
} }
JS_REQUIRES_STACK inline jsval * JS_REQUIRES_STACK inline Value *
StackSpace::firstUnused() const StackSpace::firstUnused() const
{ {
CallStack *ccs = currentCallStack; CallStack *ccs = currentCallStack;
@ -89,7 +89,7 @@ StackSpace::assertIsCurrent(JSContext *cx) const
} }
JS_ALWAYS_INLINE bool JS_ALWAYS_INLINE bool
StackSpace::ensureSpace(JSContext *maybecx, jsval *from, ptrdiff_t nvals) const StackSpace::ensureSpace(JSContext *maybecx, Value *from, ptrdiff_t nvals) const
{ {
JS_ASSERT(from == firstUnused()); JS_ASSERT(from == firstUnused());
#ifdef XP_WIN #ifdef XP_WIN
@ -127,7 +127,7 @@ StackSpace::ensureEnoughSpaceToEnterTrace()
} }
JS_REQUIRES_STACK JS_ALWAYS_INLINE JSStackFrame * JS_REQUIRES_STACK JS_ALWAYS_INLINE JSStackFrame *
StackSpace::getInlineFrame(JSContext *cx, jsval *sp, StackSpace::getInlineFrame(JSContext *cx, Value *sp,
uintN nmissing, uintN nfixed) const uintN nmissing, uintN nfixed) const
{ {
assertIsCurrent(cx); assertIsCurrent(cx);
@ -178,7 +178,7 @@ StackSpace::popInlineFrame(JSContext *cx, JSStackFrame *up, JSStackFrame *down)
void void
AutoIdArray::trace(JSTracer *trc) { AutoIdArray::trace(JSTracer *trc) {
JS_ASSERT(tag == IDARRAY); JS_ASSERT(tag == IDARRAY);
js::TraceValues(trc, idArray->length, idArray->vector, "JSAutoIdArray.idArray"); MarkIdRange(trc, idArray->length, idArray->vector, "JSAutoIdArray.idArray");
} }
class AutoNamespaceArray : protected AutoGCRooter { class AutoNamespaceArray : protected AutoGCRooter {
@ -239,9 +239,13 @@ class CompartmentChecker
check(obj->getCompartment(context)); check(obj->getCompartment(context));
} }
void check(const js::Value &v) {
if (v.isObject())
check(&v.toObject());
}
void check(jsval v) { void check(jsval v) {
if (!JSVAL_IS_PRIMITIVE(v)) check(Valueify(v));
check(JSVAL_TO_OBJECT(v));
} }
void check(const ValueArray &arr) { void check(const ValueArray &arr) {
@ -249,10 +253,22 @@ class CompartmentChecker
check(arr.array[i]); check(arr.array[i]);
} }
void check(const JSValueArray &arr) {
for (size_t i = 0; i < arr.length; i++)
check(arr.array[i]);
}
void check(jsid id) {
if (JSID_IS_OBJECT(id))
check(JSID_TO_OBJECT(id));
}
void check(JSIdArray *ida) { void check(JSIdArray *ida) {
if (ida) { if (ida) {
for (jsint i = 0; i < ida->length; i++) for (jsint i = 0; i < ida->length; i++) {
check(ID_TO_VALUE(ida->vector[i])); if (JSID_IS_OBJECT(ida->vector[i]))
check(ida->vector[i]);
}
} }
} }
@ -333,7 +349,7 @@ assertSameCompartment(JSContext *cx, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
#undef START_ASSERT_SAME_COMPARTMENT #undef START_ASSERT_SAME_COMPARTMENT
inline JSBool inline JSBool
callJSNative(JSContext *cx, JSNative native, JSObject *thisobj, uintN argc, jsval *argv, jsval *rval) callJSNative(JSContext *cx, js::Native native, JSObject *thisobj, uintN argc, js::Value *argv, js::Value *rval)
{ {
assertSameCompartment(cx, thisobj, ValueArray(argv, argc)); assertSameCompartment(cx, thisobj, ValueArray(argv, argc));
JSBool ok = native(cx, thisobj, argc, argv, rval); JSBool ok = native(cx, thisobj, argc, argv, rval);
@ -343,7 +359,7 @@ callJSNative(JSContext *cx, JSNative native, JSObject *thisobj, uintN argc, jsva
} }
inline JSBool inline JSBool
callJSFastNative(JSContext *cx, JSFastNative native, uintN argc, jsval *vp) callJSFastNative(JSContext *cx, js::FastNative native, uintN argc, js::Value *vp)
{ {
assertSameCompartment(cx, ValueArray(vp, argc + 2)); assertSameCompartment(cx, ValueArray(vp, argc + 2));
JSBool ok = native(cx, argc, vp); JSBool ok = native(cx, argc, vp);
@ -353,22 +369,22 @@ callJSFastNative(JSContext *cx, JSFastNative native, uintN argc, jsval *vp)
} }
inline JSBool inline JSBool
callJSPropertyOp(JSContext *cx, JSPropertyOp op, JSObject *obj, jsval idval, jsval *vp) callJSPropertyOp(JSContext *cx, js::PropertyOp op, JSObject *obj, jsid id, js::Value *vp)
{ {
assertSameCompartment(cx, obj, idval, *vp); assertSameCompartment(cx, obj, id, *vp);
JSBool ok = op(cx, obj, idval, vp); JSBool ok = op(cx, obj, id, vp);
if (ok) if (ok)
assertSameCompartment(cx, obj, *vp); assertSameCompartment(cx, obj, *vp);
return ok; return ok;
} }
inline JSBool inline JSBool
callJSPropertyOpSetter(JSContext *cx, JSPropertyOp op, JSObject *obj, jsval idval, jsval *vp) callJSPropertyOpSetter(JSContext *cx, js::PropertyOp op, JSObject *obj, jsid id, js::Value *vp)
{ {
assertSameCompartment(cx, obj, idval, *vp); assertSameCompartment(cx, obj, id, *vp);
return op(cx, obj, idval, vp); return op(cx, obj, id, vp);
} }
} } /* namespace js */
#endif /* jscntxtinlines_h___ */ #endif /* jscntxtinlines_h___ */

Просмотреть файл

@ -481,12 +481,12 @@ msFromTime(jsdouble t)
* Other Support routines and definitions * Other Support routines and definitions
*/ */
JSClass js_DateClass = { Class js_DateClass = {
js_Date_str, js_Date_str,
JSCLASS_HAS_RESERVED_SLOTS(JSObject::DATE_FIXED_RESERVED_SLOTS) | JSCLASS_HAS_RESERVED_SLOTS(JSObject::DATE_FIXED_RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_Date), JSCLASS_HAS_CACHED_PROTO(JSProto_Date),
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, PropertyStub, PropertyStub, PropertyStub, PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL, EnumerateStub, ResolveStub, ConvertStub, NULL,
JSCLASS_NO_OPTIONAL_MEMBERS JSCLASS_NO_OPTIONAL_MEMBERS
}; };
@ -565,7 +565,7 @@ date_msecFromDate(jsdouble year, jsdouble mon, jsdouble mday, jsdouble hour,
#define MAXARGS 7 #define MAXARGS 7
static JSBool static JSBool
date_msecFromArgs(JSContext *cx, uintN argc, jsval *argv, jsdouble *rval) date_msecFromArgs(JSContext *cx, uintN argc, Value *argv, jsdouble *rval)
{ {
uintN loop; uintN loop;
jsdouble array[MAXARGS]; jsdouble array[MAXARGS];
@ -605,7 +605,7 @@ date_msecFromArgs(JSContext *cx, uintN argc, jsval *argv, jsdouble *rval)
* See ECMA 15.9.4.[3-10]; * See ECMA 15.9.4.[3-10];
*/ */
static JSBool static JSBool
date_UTC(JSContext *cx, uintN argc, jsval *vp) date_UTC(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble msec_time; jsdouble msec_time;
@ -614,7 +614,8 @@ date_UTC(JSContext *cx, uintN argc, jsval *vp)
msec_time = TIMECLIP(msec_time); msec_time = TIMECLIP(msec_time);
return js_NewNumberInRootedValue(cx, msec_time, vp); vp->setNumber(msec_time);
return JS_TRUE;
} }
/* /*
@ -1141,26 +1142,27 @@ syntax:
} }
static JSBool static JSBool
date_parse(JSContext *cx, uintN argc, jsval *vp) date_parse(JSContext *cx, uintN argc, Value *vp)
{ {
JSString *str; JSString *str;
jsdouble result; jsdouble result;
if (argc == 0) { if (argc == 0) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return true; return true;
} }
str = js_ValueToString(cx, vp[2]); str = js_ValueToString(cx, vp[2]);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
vp[2] = STRING_TO_JSVAL(str); vp[2].setString(str);
if (!date_parseString(str, &result, cx)) { if (!date_parseString(str, &result, cx)) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return true; return true;
} }
result = TIMECLIP(result); result = TIMECLIP(result);
return js_NewNumberInRootedValue(cx, result, vp); vp->setNumber(result);
return true;
} }
static inline jsdouble static inline jsdouble
@ -1170,9 +1172,10 @@ NowAsMillis()
} }
static JSBool static JSBool
date_now(JSContext *cx, uintN argc, jsval *vp) date_now(JSContext *cx, uintN argc, Value *vp)
{ {
return js_NewDoubleInRootedValue(cx, NowAsMillis(), vp); vp->setDouble(NowAsMillis());
return JS_TRUE;
} }
#ifdef JS_TRACER #ifdef JS_TRACER
@ -1188,38 +1191,37 @@ date_now_tn(JSContext*)
* Date type. * Date type.
*/ */
static JSBool static JSBool
GetUTCTime(JSContext *cx, JSObject *obj, jsval *vp, jsdouble *dp) GetUTCTime(JSContext *cx, JSObject *obj, Value *vp, jsdouble *dp)
{ {
if (!JS_InstanceOf(cx, obj, &js_DateClass, vp ? vp + 2 : NULL)) if (!InstanceOf(cx, obj, &js_DateClass, vp ? vp + 2 : NULL))
return JS_FALSE; return JS_FALSE;
*dp = *JSVAL_TO_DOUBLE(obj->getDateUTCTime()); *dp = obj->getDateUTCTime().toNumber();
return JS_TRUE; return JS_TRUE;
} }
static void static void
SetDateToNaN(JSContext *cx, JSObject *obj, jsval *vp = NULL) SetDateToNaN(JSContext *cx, JSObject *obj, Value *vp = NULL)
{ {
JS_ASSERT(obj->getClass() == &js_DateClass); JS_ASSERT(obj->getClass() == &js_DateClass);
obj->setDateLocalTime(cx->runtime->NaNValue); obj->setDateLocalTime(cx->runtime->NaNValue);
obj->setDateUTCTime(cx->runtime->NaNValue); obj->setDateUTCTime(cx->runtime->NaNValue);
if (vp) if (vp)
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
} }
/* /*
* Set UTC time to a given time and invalidate cached local time. * Set UTC time to a given time and invalidate cached local time.
*/ */
static JSBool static JSBool
SetUTCTime(JSContext *cx, JSObject *obj, jsdouble t, jsval *vp = NULL) SetUTCTime(JSContext *cx, JSObject *obj, jsdouble t, Value *vp = NULL)
{ {
JS_ASSERT(obj->getClass() == &js_DateClass); JS_ASSERT(obj->getClass() == &js_DateClass);
obj->setDateLocalTime(cx->runtime->NaNValue); obj->setDateLocalTime(cx->runtime->NaNValue);
if (!js_NewDoubleInRootedValue(cx, t, obj->addressOfDateUTCTime())) obj->setDateUTCTime(DoubleValue(t));
return false;
if (vp) if (vp)
*vp = obj->getDateUTCTime(); vp->setDouble(t);
return true; return true;
} }
@ -1228,22 +1230,20 @@ SetUTCTime(JSContext *cx, JSObject *obj, jsdouble t, jsval *vp = NULL)
* (e.g., NaN), the local time slot is set to the UTC time without conversion. * (e.g., NaN), the local time slot is set to the UTC time without conversion.
*/ */
static JSBool static JSBool
GetAndCacheLocalTime(JSContext *cx, JSObject *obj, jsval *vp, jsdouble *dp) GetAndCacheLocalTime(JSContext *cx, JSObject *obj, Value *vp, jsdouble *dp)
{ {
if (!obj || !JS_InstanceOf(cx, obj, &js_DateClass, vp ? vp + 2 : NULL)) if (!obj || !InstanceOf(cx, obj, &js_DateClass, vp ? vp + 2 : NULL))
return false; return false;
jsval *slotp = obj->addressOfDateLocalTime(); jsdouble result = obj->getDateLocalTime().toNumber();
jsdouble result = *JSVAL_TO_DOUBLE(*slotp);
if (JSDOUBLE_IS_NaN(result)) { if (JSDOUBLE_IS_NaN(result)) {
result = *JSVAL_TO_DOUBLE(obj->getDateUTCTime()); result = obj->getDateUTCTime().toDouble();
/* if result is NaN, it couldn't be finite. */ /* if result is NaN, it couldn't be finite. */
if (JSDOUBLE_IS_FINITE(result)) if (JSDOUBLE_IS_FINITE(result))
result = LocalTime(result, cx); result = LocalTime(result, cx);
if (!js_NewDoubleInRootedValue(cx, result, slotp)) obj->setDateLocalTime(DoubleValue(result));
return false;
} }
*dp = result; *dp = result;
@ -1254,20 +1254,22 @@ GetAndCacheLocalTime(JSContext *cx, JSObject *obj, jsval *vp, jsdouble *dp)
* See ECMA 15.9.5.4 thru 15.9.5.23 * See ECMA 15.9.5.4 thru 15.9.5.23
*/ */
static JSBool static JSBool
date_getTime(JSContext *cx, uintN argc, jsval *vp) date_getTime(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble result; jsdouble result;
return GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result) && if (!GetUTCTime(cx, ComputeThisFromVp(cx, vp), vp, &result))
js_NewNumberInRootedValue(cx, result, vp); return JS_FALSE;
vp->setNumber(result);
return JS_TRUE;
} }
static JSBool static JSBool
GetYear(JSContext *cx, JSBool fullyear, jsval *vp) GetYear(JSContext *cx, JSBool fullyear, Value *vp)
{ {
jsdouble result; jsdouble result;
if (!GetAndCacheLocalTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result)) if (!GetAndCacheLocalTime(cx, ComputeThisFromVp(cx, vp), vp, &result))
return JS_FALSE; return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result)) { if (JSDOUBLE_IS_FINITE(result)) {
@ -1278,214 +1280,228 @@ GetYear(JSContext *cx, JSBool fullyear, jsval *vp)
result -= 1900; result -= 1900;
} }
return js_NewNumberInRootedValue(cx, result, vp); vp->setNumber(result);
return JS_TRUE;
} }
static JSBool static JSBool
date_getYear(JSContext *cx, uintN argc, jsval *vp) date_getYear(JSContext *cx, uintN argc, Value *vp)
{ {
return GetYear(cx, JS_FALSE, vp); return GetYear(cx, JS_FALSE, vp);
} }
static JSBool static JSBool
date_getFullYear(JSContext *cx, uintN argc, jsval *vp) date_getFullYear(JSContext *cx, uintN argc, Value *vp)
{ {
return GetYear(cx, JS_TRUE, vp); return GetYear(cx, JS_TRUE, vp);
} }
static JSBool static JSBool
date_getUTCFullYear(JSContext *cx, uintN argc, jsval *vp) date_getUTCFullYear(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble result; jsdouble result;
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result)) if (!GetUTCTime(cx, ComputeThisFromVp(cx, vp), vp, &result))
return JS_FALSE; return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result)) if (JSDOUBLE_IS_FINITE(result))
result = YearFromTime(result); result = YearFromTime(result);
return js_NewNumberInRootedValue(cx, result, vp); vp->setNumber(result);
return JS_TRUE;
} }
static JSBool static JSBool
date_getMonth(JSContext *cx, uintN argc, jsval *vp) date_getMonth(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble result; jsdouble result;
if (!GetAndCacheLocalTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result)) if (!GetAndCacheLocalTime(cx, ComputeThisFromVp(cx, vp), vp, &result))
return JS_FALSE; return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result)) if (JSDOUBLE_IS_FINITE(result))
result = MonthFromTime(result); result = MonthFromTime(result);
return js_NewNumberInRootedValue(cx, result, vp); vp->setNumber(result);
return JS_TRUE;
} }
static JSBool static JSBool
date_getUTCMonth(JSContext *cx, uintN argc, jsval *vp) date_getUTCMonth(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble result; jsdouble result;
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result)) if (!GetUTCTime(cx, ComputeThisFromVp(cx, vp), vp, &result))
return JS_FALSE; return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result)) if (JSDOUBLE_IS_FINITE(result))
result = MonthFromTime(result); result = MonthFromTime(result);
return js_NewNumberInRootedValue(cx, result, vp); vp->setNumber(result);
return JS_TRUE;
} }
static JSBool static JSBool
date_getDate(JSContext *cx, uintN argc, jsval *vp) date_getDate(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble result; jsdouble result;
if (!GetAndCacheLocalTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result)) if (!GetAndCacheLocalTime(cx, ComputeThisFromVp(cx, vp), vp, &result))
return JS_FALSE; return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result)) if (JSDOUBLE_IS_FINITE(result))
result = DateFromTime(result); result = DateFromTime(result);
return js_NewNumberInRootedValue(cx, result, vp); vp->setNumber(result);
return JS_TRUE;
} }
static JSBool static JSBool
date_getUTCDate(JSContext *cx, uintN argc, jsval *vp) date_getUTCDate(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble result; jsdouble result;
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result)) if (!GetUTCTime(cx, ComputeThisFromVp(cx, vp), vp, &result))
return JS_FALSE; return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result)) if (JSDOUBLE_IS_FINITE(result))
result = DateFromTime(result); result = DateFromTime(result);
return js_NewNumberInRootedValue(cx, result, vp); vp->setNumber(result);
return JS_TRUE;
} }
static JSBool static JSBool
date_getDay(JSContext *cx, uintN argc, jsval *vp) date_getDay(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble result; jsdouble result;
if (!GetAndCacheLocalTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result)) if (!GetAndCacheLocalTime(cx, ComputeThisFromVp(cx, vp), vp, &result))
return JS_FALSE; return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result)) if (JSDOUBLE_IS_FINITE(result))
result = WeekDay(result); result = WeekDay(result);
return js_NewNumberInRootedValue(cx, result, vp); vp->setNumber(result);
return JS_TRUE;
} }
static JSBool static JSBool
date_getUTCDay(JSContext *cx, uintN argc, jsval *vp) date_getUTCDay(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble result; jsdouble result;
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result)) if (!GetUTCTime(cx, ComputeThisFromVp(cx, vp), vp, &result))
return JS_FALSE; return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result)) if (JSDOUBLE_IS_FINITE(result))
result = WeekDay(result); result = WeekDay(result);
return js_NewNumberInRootedValue(cx, result, vp); vp->setNumber(result);
return JS_TRUE;
} }
static JSBool static JSBool
date_getHours(JSContext *cx, uintN argc, jsval *vp) date_getHours(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble result; jsdouble result;
if (!GetAndCacheLocalTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result)) if (!GetAndCacheLocalTime(cx, ComputeThisFromVp(cx, vp), vp, &result))
return JS_FALSE; return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result)) if (JSDOUBLE_IS_FINITE(result))
result = HourFromTime(result); result = HourFromTime(result);
return js_NewNumberInRootedValue(cx, result, vp); vp->setNumber(result);
return JS_TRUE;
} }
static JSBool static JSBool
date_getUTCHours(JSContext *cx, uintN argc, jsval *vp) date_getUTCHours(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble result; jsdouble result;
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result)) if (!GetUTCTime(cx, ComputeThisFromVp(cx, vp), vp, &result))
return JS_FALSE; return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result)) if (JSDOUBLE_IS_FINITE(result))
result = HourFromTime(result); result = HourFromTime(result);
return js_NewNumberInRootedValue(cx, result, vp); vp->setNumber(result);
return JS_TRUE;
} }
static JSBool static JSBool
date_getMinutes(JSContext *cx, uintN argc, jsval *vp) date_getMinutes(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble result; jsdouble result;
if (!GetAndCacheLocalTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result)) if (!GetAndCacheLocalTime(cx, ComputeThisFromVp(cx, vp), vp, &result))
return JS_FALSE; return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result)) if (JSDOUBLE_IS_FINITE(result))
result = MinFromTime(result); result = MinFromTime(result);
return js_NewNumberInRootedValue(cx, result, vp); vp->setNumber(result);
return JS_TRUE;
} }
static JSBool static JSBool
date_getUTCMinutes(JSContext *cx, uintN argc, jsval *vp) date_getUTCMinutes(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble result; jsdouble result;
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result)) if (!GetUTCTime(cx, ComputeThisFromVp(cx, vp), vp, &result))
return JS_FALSE; return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result)) if (JSDOUBLE_IS_FINITE(result))
result = MinFromTime(result); result = MinFromTime(result);
return js_NewNumberInRootedValue(cx, result, vp); vp->setNumber(result);
return JS_TRUE;
} }
/* Date.getSeconds is mapped to getUTCSeconds */ /* Date.getSeconds is mapped to getUTCSeconds */
static JSBool static JSBool
date_getUTCSeconds(JSContext *cx, uintN argc, jsval *vp) date_getUTCSeconds(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble result; jsdouble result;
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result)) if (!GetUTCTime(cx, ComputeThisFromVp(cx, vp), vp, &result))
return JS_FALSE; return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result)) if (JSDOUBLE_IS_FINITE(result))
result = SecFromTime(result); result = SecFromTime(result);
return js_NewNumberInRootedValue(cx, result, vp); vp->setNumber(result);
return JS_TRUE;
} }
/* Date.getMilliseconds is mapped to getUTCMilliseconds */ /* Date.getMilliseconds is mapped to getUTCMilliseconds */
static JSBool static JSBool
date_getUTCMilliseconds(JSContext *cx, uintN argc, jsval *vp) date_getUTCMilliseconds(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble result; jsdouble result;
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &result)) if (!GetUTCTime(cx, ComputeThisFromVp(cx, vp), vp, &result))
return JS_FALSE; return JS_FALSE;
if (JSDOUBLE_IS_FINITE(result)) if (JSDOUBLE_IS_FINITE(result))
result = msFromTime(result); result = msFromTime(result);
return js_NewNumberInRootedValue(cx, result, vp); vp->setNumber(result);
return JS_TRUE;
} }
static JSBool static JSBool
date_getTimezoneOffset(JSContext *cx, uintN argc, jsval *vp) date_getTimezoneOffset(JSContext *cx, uintN argc, Value *vp)
{ {
JSObject *obj; JSObject *obj;
jsdouble utctime, localtime, result; jsdouble utctime, localtime, result;
obj = JS_THIS_OBJECT(cx, vp); obj = ComputeThisFromVp(cx, vp);
if (!GetUTCTime(cx, obj, vp, &utctime)) if (!GetUTCTime(cx, obj, vp, &utctime))
return JS_FALSE; return JS_FALSE;
if (!GetAndCacheLocalTime(cx, obj, NULL, &localtime)) if (!GetAndCacheLocalTime(cx, obj, NULL, &localtime))
@ -1497,14 +1513,15 @@ date_getTimezoneOffset(JSContext *cx, uintN argc, jsval *vp)
* daylight savings time. * daylight savings time.
*/ */
result = (utctime - localtime) / msPerMinute; result = (utctime - localtime) / msPerMinute;
return js_NewNumberInRootedValue(cx, result, vp); vp->setNumber(result);
return JS_TRUE;
} }
static JSBool static JSBool
date_setTime(JSContext *cx, uintN argc, jsval *vp) date_setTime(JSContext *cx, uintN argc, Value *vp)
{ {
JSObject *obj = JS_THIS_OBJECT(cx, vp); JSObject *obj = ComputeThisFromVp(cx, vp);
if (!JS_InstanceOf(cx, obj, &js_DateClass, vp + 2)) if (!InstanceOf(cx, obj, &js_DateClass, vp + 2))
return false; return false;
if (argc == 0) { if (argc == 0) {
@ -1520,10 +1537,10 @@ date_setTime(JSContext *cx, uintN argc, jsval *vp)
} }
static JSBool static JSBool
date_makeTime(JSContext *cx, uintN maxargs, JSBool local, uintN argc, jsval *vp) date_makeTime(JSContext *cx, uintN maxargs, JSBool local, uintN argc, Value *vp)
{ {
JSObject *obj; JSObject *obj;
jsval *argv; Value *argv;
uintN i; uintN i;
jsdouble args[4], *argp, *stop; jsdouble args[4], *argp, *stop;
jsdouble hour, min, sec, msec; jsdouble hour, min, sec, msec;
@ -1532,13 +1549,15 @@ date_makeTime(JSContext *cx, uintN maxargs, JSBool local, uintN argc, jsval *vp)
jsdouble msec_time; jsdouble msec_time;
jsdouble result; jsdouble result;
obj = JS_THIS_OBJECT(cx, vp); obj = ComputeThisFromVp(cx, vp);
if (!GetUTCTime(cx, obj, vp, &result)) if (!GetUTCTime(cx, obj, vp, &result))
return false; return false;
/* just return NaN if the date is already NaN */ /* just return NaN if the date is already NaN */
if (!JSDOUBLE_IS_FINITE(result)) if (!JSDOUBLE_IS_FINITE(result)) {
return js_NewNumberInRootedValue(cx, result, vp); vp->setNumber(result);
return true;
}
/* /*
* Satisfy the ECMA rule that if a function is called with * Satisfy the ECMA rule that if a function is called with
@ -1609,65 +1628,65 @@ date_makeTime(JSContext *cx, uintN maxargs, JSBool local, uintN argc, jsval *vp)
} }
static JSBool static JSBool
date_setMilliseconds(JSContext *cx, uintN argc, jsval *vp) date_setMilliseconds(JSContext *cx, uintN argc, Value *vp)
{ {
return date_makeTime(cx, 1, JS_TRUE, argc, vp); return date_makeTime(cx, 1, JS_TRUE, argc, vp);
} }
static JSBool static JSBool
date_setUTCMilliseconds(JSContext *cx, uintN argc, jsval *vp) date_setUTCMilliseconds(JSContext *cx, uintN argc, Value *vp)
{ {
return date_makeTime(cx, 1, JS_FALSE, argc, vp); return date_makeTime(cx, 1, JS_FALSE, argc, vp);
} }
static JSBool static JSBool
date_setSeconds(JSContext *cx, uintN argc, jsval *vp) date_setSeconds(JSContext *cx, uintN argc, Value *vp)
{ {
return date_makeTime(cx, 2, JS_TRUE, argc, vp); return date_makeTime(cx, 2, JS_TRUE, argc, vp);
} }
static JSBool static JSBool
date_setUTCSeconds(JSContext *cx, uintN argc, jsval *vp) date_setUTCSeconds(JSContext *cx, uintN argc, Value *vp)
{ {
return date_makeTime(cx, 2, JS_FALSE, argc, vp); return date_makeTime(cx, 2, JS_FALSE, argc, vp);
} }
static JSBool static JSBool
date_setMinutes(JSContext *cx, uintN argc, jsval *vp) date_setMinutes(JSContext *cx, uintN argc, Value *vp)
{ {
return date_makeTime(cx, 3, JS_TRUE, argc, vp); return date_makeTime(cx, 3, JS_TRUE, argc, vp);
} }
static JSBool static JSBool
date_setUTCMinutes(JSContext *cx, uintN argc, jsval *vp) date_setUTCMinutes(JSContext *cx, uintN argc, Value *vp)
{ {
return date_makeTime(cx, 3, JS_FALSE, argc, vp); return date_makeTime(cx, 3, JS_FALSE, argc, vp);
} }
static JSBool static JSBool
date_setHours(JSContext *cx, uintN argc, jsval *vp) date_setHours(JSContext *cx, uintN argc, Value *vp)
{ {
return date_makeTime(cx, 4, JS_TRUE, argc, vp); return date_makeTime(cx, 4, JS_TRUE, argc, vp);
} }
static JSBool static JSBool
date_setUTCHours(JSContext *cx, uintN argc, jsval *vp) date_setUTCHours(JSContext *cx, uintN argc, Value *vp)
{ {
return date_makeTime(cx, 4, JS_FALSE, argc, vp); return date_makeTime(cx, 4, JS_FALSE, argc, vp);
} }
static JSBool static JSBool
date_makeDate(JSContext *cx, uintN maxargs, JSBool local, uintN argc, jsval *vp) date_makeDate(JSContext *cx, uintN maxargs, JSBool local, uintN argc, Value *vp)
{ {
JSObject *obj; JSObject *obj;
jsval *argv; Value *argv;
uintN i; uintN i;
jsdouble lorutime; /* local or UTC version of *date */ jsdouble lorutime; /* local or UTC version of *date */
jsdouble args[3], *argp, *stop; jsdouble args[3], *argp, *stop;
jsdouble year, month, day; jsdouble year, month, day;
jsdouble result; jsdouble result;
obj = JS_THIS_OBJECT(cx, vp); obj = ComputeThisFromVp(cx, vp);
if (!GetUTCTime(cx, obj, vp, &result)) if (!GetUTCTime(cx, obj, vp, &result))
return false; return false;
@ -1694,8 +1713,10 @@ date_makeDate(JSContext *cx, uintN maxargs, JSBool local, uintN argc, jsval *vp)
/* return NaN if date is NaN and we're not setting the year, /* return NaN if date is NaN and we're not setting the year,
* If we are, use 0 as the time. */ * If we are, use 0 as the time. */
if (!(JSDOUBLE_IS_FINITE(result))) { if (!(JSDOUBLE_IS_FINITE(result))) {
if (maxargs < 3) if (maxargs < 3) {
return js_NewNumberInRootedValue(cx, result, vp); vp->setDouble(result);
return true;
}
lorutime = +0.; lorutime = +0.;
} else { } else {
lorutime = local ? LocalTime(result, cx) : result; lorutime = local ? LocalTime(result, cx) : result;
@ -1728,45 +1749,45 @@ date_makeDate(JSContext *cx, uintN maxargs, JSBool local, uintN argc, jsval *vp)
} }
static JSBool static JSBool
date_setDate(JSContext *cx, uintN argc, jsval *vp) date_setDate(JSContext *cx, uintN argc, Value *vp)
{ {
return date_makeDate(cx, 1, JS_TRUE, argc, vp); return date_makeDate(cx, 1, JS_TRUE, argc, vp);
} }
static JSBool static JSBool
date_setUTCDate(JSContext *cx, uintN argc, jsval *vp) date_setUTCDate(JSContext *cx, uintN argc, Value *vp)
{ {
return date_makeDate(cx, 1, JS_FALSE, argc, vp); return date_makeDate(cx, 1, JS_FALSE, argc, vp);
} }
static JSBool static JSBool
date_setMonth(JSContext *cx, uintN argc, jsval *vp) date_setMonth(JSContext *cx, uintN argc, Value *vp)
{ {
return date_makeDate(cx, 2, JS_TRUE, argc, vp); return date_makeDate(cx, 2, JS_TRUE, argc, vp);
} }
static JSBool static JSBool
date_setUTCMonth(JSContext *cx, uintN argc, jsval *vp) date_setUTCMonth(JSContext *cx, uintN argc, Value *vp)
{ {
return date_makeDate(cx, 2, JS_FALSE, argc, vp); return date_makeDate(cx, 2, JS_FALSE, argc, vp);
} }
static JSBool static JSBool
date_setFullYear(JSContext *cx, uintN argc, jsval *vp) date_setFullYear(JSContext *cx, uintN argc, Value *vp)
{ {
return date_makeDate(cx, 3, JS_TRUE, argc, vp); return date_makeDate(cx, 3, JS_TRUE, argc, vp);
} }
static JSBool static JSBool
date_setUTCFullYear(JSContext *cx, uintN argc, jsval *vp) date_setUTCFullYear(JSContext *cx, uintN argc, Value *vp)
{ {
return date_makeDate(cx, 3, JS_FALSE, argc, vp); return date_makeDate(cx, 3, JS_FALSE, argc, vp);
} }
static JSBool static JSBool
date_setYear(JSContext *cx, uintN argc, jsval *vp) date_setYear(JSContext *cx, uintN argc, Value *vp)
{ {
JSObject *obj = JS_THIS_OBJECT(cx, vp); JSObject *obj = ComputeThisFromVp(cx, vp);
jsdouble result; jsdouble result;
if (!GetUTCTime(cx, obj, vp, &result)) if (!GetUTCTime(cx, obj, vp, &result))
@ -1838,14 +1859,14 @@ print_iso_string(char* buf, size_t size, jsdouble utctime)
} }
static JSBool static JSBool
date_utc_format(JSContext *cx, jsval *vp, date_utc_format(JSContext *cx, Value *vp,
void (*printFunc)(char*, size_t, jsdouble)) void (*printFunc)(char*, size_t, jsdouble))
{ {
char buf[100]; char buf[100];
JSString *str; JSString *str;
jsdouble utctime; jsdouble utctime;
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &utctime)) if (!GetUTCTime(cx, ComputeThisFromVp(cx, vp), vp, &utctime))
return JS_FALSE; return JS_FALSE;
if (!JSDOUBLE_IS_FINITE(utctime)) { if (!JSDOUBLE_IS_FINITE(utctime)) {
@ -1856,18 +1877,18 @@ date_utc_format(JSContext *cx, jsval *vp,
str = JS_NewStringCopyZ(cx, buf); str = JS_NewStringCopyZ(cx, buf);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
*vp = STRING_TO_JSVAL(str); vp->setString(str);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
date_toGMTString(JSContext *cx, uintN argc, jsval *vp) date_toGMTString(JSContext *cx, uintN argc, Value *vp)
{ {
return date_utc_format(cx, vp, print_gmt_string); return date_utc_format(cx, vp, print_gmt_string);
} }
static JSBool static JSBool
date_toISOString(JSContext *cx, uintN argc, jsval *vp) date_toISOString(JSContext *cx, uintN argc, Value *vp)
{ {
return date_utc_format(cx, vp, print_iso_string); return date_utc_format(cx, vp, print_iso_string);
} }
@ -1900,7 +1921,7 @@ typedef enum formatspec {
/* helper function */ /* helper function */
static JSBool static JSBool
date_format(JSContext *cx, jsdouble date, formatspec format, jsval *rval) date_format(JSContext *cx, jsdouble date, formatspec format, Value *rval)
{ {
char buf[100]; char buf[100];
JSString *str; JSString *str;
@ -2008,12 +2029,12 @@ date_format(JSContext *cx, jsdouble date, formatspec format, jsval *rval)
str = JS_NewStringCopyZ(cx, buf); str = JS_NewStringCopyZ(cx, buf);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
*rval = STRING_TO_JSVAL(str); rval->setString(str);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
date_toLocaleHelper(JSContext *cx, const char *format, jsval *vp) date_toLocaleHelper(JSContext *cx, const char *format, Value *vp)
{ {
JSObject *obj; JSObject *obj;
char buf[100]; char buf[100];
@ -2021,7 +2042,7 @@ date_toLocaleHelper(JSContext *cx, const char *format, jsval *vp)
PRMJTime split; PRMJTime split;
jsdouble utctime; jsdouble utctime;
obj = JS_THIS_OBJECT(cx, vp); obj = ComputeThisFromVp(cx, vp);
if (!GetUTCTime(cx, obj, vp, &utctime)) if (!GetUTCTime(cx, obj, vp, &utctime))
return JS_FALSE; return JS_FALSE;
@ -2055,17 +2076,17 @@ date_toLocaleHelper(JSContext *cx, const char *format, jsval *vp)
} }
if (cx->localeCallbacks && cx->localeCallbacks->localeToUnicode) if (cx->localeCallbacks && cx->localeCallbacks->localeToUnicode)
return cx->localeCallbacks->localeToUnicode(cx, buf, vp); return cx->localeCallbacks->localeToUnicode(cx, buf, Jsvalify(vp));
str = JS_NewStringCopyZ(cx, buf); str = JS_NewStringCopyZ(cx, buf);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
*vp = STRING_TO_JSVAL(str); vp->setString(str);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
date_toLocaleString(JSContext *cx, uintN argc, jsval *vp) date_toLocaleString(JSContext *cx, uintN argc, Value *vp)
{ {
/* Use '%#c' for windows, because '%c' is /* Use '%#c' for windows, because '%c' is
* backward-compatible and non-y2k with msvc; '%#c' requests that a * backward-compatible and non-y2k with msvc; '%#c' requests that a
@ -2081,7 +2102,7 @@ date_toLocaleString(JSContext *cx, uintN argc, jsval *vp)
} }
static JSBool static JSBool
date_toLocaleDateString(JSContext *cx, uintN argc, jsval *vp) date_toLocaleDateString(JSContext *cx, uintN argc, Value *vp)
{ {
/* Use '%#x' for windows, because '%x' is /* Use '%#x' for windows, because '%x' is
* backward-compatible and non-y2k with msvc; '%#x' requests that a * backward-compatible and non-y2k with msvc; '%#x' requests that a
@ -2097,13 +2118,13 @@ date_toLocaleDateString(JSContext *cx, uintN argc, jsval *vp)
} }
static JSBool static JSBool
date_toLocaleTimeString(JSContext *cx, uintN argc, jsval *vp) date_toLocaleTimeString(JSContext *cx, uintN argc, Value *vp)
{ {
return date_toLocaleHelper(cx, "%X", vp); return date_toLocaleHelper(cx, "%X", vp);
} }
static JSBool static JSBool
date_toLocaleFormat(JSContext *cx, uintN argc, jsval *vp) date_toLocaleFormat(JSContext *cx, uintN argc, Value *vp)
{ {
JSString *fmt; JSString *fmt;
const char *fmtbytes; const char *fmtbytes;
@ -2114,7 +2135,7 @@ date_toLocaleFormat(JSContext *cx, uintN argc, jsval *vp)
fmt = js_ValueToString(cx, vp[2]); fmt = js_ValueToString(cx, vp[2]);
if (!fmt) if (!fmt)
return JS_FALSE; return JS_FALSE;
vp[2] = STRING_TO_JSVAL(fmt); vp[2].setString(fmt);
fmtbytes = js_GetStringBytes(cx, fmt); fmtbytes = js_GetStringBytes(cx, fmt);
if (!fmtbytes) if (!fmtbytes)
return JS_FALSE; return JS_FALSE;
@ -2123,21 +2144,21 @@ date_toLocaleFormat(JSContext *cx, uintN argc, jsval *vp)
} }
static JSBool static JSBool
date_toTimeString(JSContext *cx, uintN argc, jsval *vp) date_toTimeString(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble utctime; jsdouble utctime;
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &utctime)) if (!GetUTCTime(cx, ComputeThisFromVp(cx, vp), vp, &utctime))
return JS_FALSE; return JS_FALSE;
return date_format(cx, utctime, FORMATSPEC_TIME, vp); return date_format(cx, utctime, FORMATSPEC_TIME, vp);
} }
static JSBool static JSBool
date_toDateString(JSContext *cx, uintN argc, jsval *vp) date_toDateString(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble utctime; jsdouble utctime;
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &utctime)) if (!GetUTCTime(cx, ComputeThisFromVp(cx, vp), vp, &utctime))
return JS_FALSE; return JS_FALSE;
return date_format(cx, utctime, FORMATSPEC_DATE, vp); return date_format(cx, utctime, FORMATSPEC_DATE, vp);
} }
@ -2147,13 +2168,13 @@ date_toDateString(JSContext *cx, uintN argc, jsval *vp)
#include "jsdtoa.h" #include "jsdtoa.h"
static JSBool static JSBool
date_toSource(JSContext *cx, uintN argc, jsval *vp) date_toSource(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble utctime; jsdouble utctime;
char buf[DTOSTR_STANDARD_BUFFER_SIZE], *numStr, *bytes; char buf[DTOSTR_STANDARD_BUFFER_SIZE], *numStr, *bytes;
JSString *str; JSString *str;
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &utctime)) if (!GetUTCTime(cx, ComputeThisFromVp(cx, vp), vp, &utctime))
return JS_FALSE; return JS_FALSE;
numStr = js_dtostr(JS_THREAD_DATA(cx)->dtoaState, buf, sizeof buf, DTOSTR_STANDARD, 0, utctime); numStr = js_dtostr(JS_THREAD_DATA(cx)->dtoaState, buf, sizeof buf, DTOSTR_STANDARD, 0, utctime);
@ -2173,23 +2194,23 @@ date_toSource(JSContext *cx, uintN argc, jsval *vp)
js_free(bytes); js_free(bytes);
return JS_FALSE; return JS_FALSE;
} }
*vp = STRING_TO_JSVAL(str); vp->setString(str);
return JS_TRUE; return JS_TRUE;
} }
#endif #endif
static JSBool static JSBool
date_toString(JSContext *cx, uintN argc, jsval *vp) date_toString(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble utctime; jsdouble utctime;
if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &utctime)) if (!GetUTCTime(cx, ComputeThisFromVp(cx, vp), vp, &utctime))
return JS_FALSE; return JS_FALSE;
return date_format(cx, utctime, FORMATSPEC_FULL, vp); return date_format(cx, utctime, FORMATSPEC_FULL, vp);
} }
static JSBool static JSBool
date_valueOf(JSContext *cx, uintN argc, jsval *vp) date_valueOf(JSContext *cx, uintN argc, Value *vp)
{ {
JSString *str, *number_str; JSString *str, *number_str;
@ -2277,7 +2298,7 @@ static JSFunctionSpec date_methods[] = {
}; };
JSBool JSBool
js_Date(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) js_Date(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
{ {
/* Date called as function. */ /* Date called as function. */
if (!JS_IsConstructing(cx)) if (!JS_IsConstructing(cx))
@ -2288,7 +2309,7 @@ js_Date(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
if (argc == 0) { if (argc == 0) {
d = NowAsMillis(); d = NowAsMillis();
} else if (argc == 1) { } else if (argc == 1) {
if (!JSVAL_IS_STRING(argv[0])) { if (!argv[0].isString()) {
/* the argument is a millisecond number */ /* the argument is a millisecond number */
if (!ValueToNumber(cx, argv[0], &d)) if (!ValueToNumber(cx, argv[0], &d))
return JS_FALSE; return JS_FALSE;
@ -2298,7 +2319,7 @@ js_Date(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
JSString *str = js_ValueToString(cx, argv[0]); JSString *str = js_ValueToString(cx, argv[0]);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
argv[0] = STRING_TO_JSVAL(str); argv[0].setString(str);
if (!date_parseString(str, &d, cx)) if (!date_parseString(str, &d, cx))
d = js_NaN; d = js_NaN;
@ -2344,8 +2365,8 @@ js_InitDateClass(JSContext *cx, JSObject *obj)
jsid toUTCStringId = ATOM_TO_JSID(cx->runtime->atomState.toUTCStringAtom); jsid toUTCStringId = ATOM_TO_JSID(cx->runtime->atomState.toUTCStringAtom);
jsid toGMTStringId = ATOM_TO_JSID(cx->runtime->atomState.toGMTStringAtom); jsid toGMTStringId = ATOM_TO_JSID(cx->runtime->atomState.toGMTStringAtom);
if (!js_GetProperty(cx, proto, toUTCStringId, toUTCStringFun.addr()) || if (!js_GetProperty(cx, proto, toUTCStringId, toUTCStringFun.addr()) ||
!js_DefineProperty(cx, proto, toGMTStringId, toUTCStringFun.value(), !js_DefineProperty(cx, proto, toGMTStringId, toUTCStringFun.addr(),
JS_PropertyStub, JS_PropertyStub, 0)) { PropertyStub, PropertyStub, 0)) {
return NULL; return NULL;
} }

Просмотреть файл

@ -46,9 +46,7 @@
#include "jsobj.h" #include "jsobj.h"
JS_BEGIN_EXTERN_C extern js::Class js_DateClass;
extern JSClass js_DateClass;
inline bool inline bool
JSObject::isDate() const JSObject::isDate() const
@ -134,8 +132,6 @@ js_IntervalNow();
/* Date constructor native. Exposed only so the JIT can know its address. */ /* Date constructor native. Exposed only so the JIT can know its address. */
JSBool JSBool
js_Date(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); js_Date(JSContext *cx, JSObject *obj, uintN argc, js::Value *argv, js::Value *rval);
JS_END_EXTERN_C
#endif /* jsdate_h___ */ #endif /* jsdate_h___ */

Просмотреть файл

@ -295,8 +295,7 @@ js_MarkTraps(JSTracer *trc)
for (JSTrap *trap = (JSTrap *) rt->trapList.next; for (JSTrap *trap = (JSTrap *) rt->trapList.next;
&trap->links != &rt->trapList; &trap->links != &rt->trapList;
trap = (JSTrap *) trap->links.next) { trap = (JSTrap *) trap->links.next) {
JS_SET_TRACING_NAME(trc, "trap->closure"); MarkValue(trc, Valueify(trap->closure), "trap->closure");
js_CallValueTracerIfGCThing(trc, trap->closure);
} }
} }
@ -415,7 +414,7 @@ typedef struct JSWatchPoint {
JSCList links; JSCList links;
JSObject *object; /* weak link, see js_FinalizeObject */ JSObject *object; /* weak link, see js_FinalizeObject */
JSScopeProperty *sprop; JSScopeProperty *sprop;
JSPropertyOp setter; PropertyOp setter;
JSWatchPointHandler handler; JSWatchPointHandler handler;
JSObject *closure; JSObject *closure;
uintN flags; uintN flags;
@ -436,7 +435,7 @@ DropWatchPointAndUnlock(JSContext *cx, JSWatchPoint *wp, uintN flag)
JSBool ok; JSBool ok;
JSScopeProperty *sprop; JSScopeProperty *sprop;
JSScope *scope; JSScope *scope;
JSPropertyOp setter; PropertyOp setter;
ok = JS_TRUE; ok = JS_TRUE;
wp->flags &= ~flag; wp->flags &= ~flag;
@ -506,8 +505,7 @@ js_TraceWatchPoints(JSTracer *trc, JSObject *obj)
wp->sprop->trace(trc); wp->sprop->trace(trc);
if (wp->sprop->hasSetterValue() && wp->setter) if (wp->sprop->hasSetterValue() && wp->setter)
JS_CALL_OBJECT_TRACER(trc, CastAsObject(wp->setter), "wp->setter"); JS_CALL_OBJECT_TRACER(trc, CastAsObject(wp->setter), "wp->setter");
JS_SET_TRACING_NAME(trc, "wp->closure"); JS_CALL_OBJECT_TRACER(trc, wp->closure, "wp->closure");
js_CallValueTracerIfGCThing(trc, OBJECT_TO_JSVAL(wp->closure));
} }
} }
} }
@ -574,11 +572,11 @@ js_FindWatchPoint(JSRuntime *rt, JSScope *scope, jsid id)
* Secret handshake with DropWatchPointAndUnlock: if (!scope), we know our * Secret handshake with DropWatchPointAndUnlock: if (!scope), we know our
* caller has acquired rt->debuggerLock, so we don't have to. * caller has acquired rt->debuggerLock, so we don't have to.
*/ */
JSPropertyOp PropertyOp
js_GetWatchedSetter(JSRuntime *rt, JSScope *scope, js_GetWatchedSetter(JSRuntime *rt, JSScope *scope,
const JSScopeProperty *sprop) const JSScopeProperty *sprop)
{ {
JSPropertyOp setter; PropertyOp setter;
JSWatchPoint *wp; JSWatchPoint *wp;
setter = NULL; setter = NULL;
@ -598,7 +596,7 @@ js_GetWatchedSetter(JSRuntime *rt, JSScope *scope,
} }
JSBool JSBool
js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp) js_watch_set(JSContext *cx, JSObject *obj, jsid id, Value *vp)
{ {
JSRuntime *rt = cx->runtime; JSRuntime *rt = cx->runtime;
DBG_LOCK(rt); DBG_LOCK(rt);
@ -612,17 +610,17 @@ js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
DBG_UNLOCK(rt); DBG_UNLOCK(rt);
JS_LOCK_OBJ(cx, obj); JS_LOCK_OBJ(cx, obj);
jsval propid = ID_TO_VALUE(sprop->id); jsid propid = sprop->id;
jsval userid = SPROP_USERID(sprop); jsid userid = SPROP_USERID(sprop);
JSScope *scope = obj->scope(); JSScope *scope = obj->scope();
JS_UNLOCK_OBJ(cx, obj); JS_UNLOCK_OBJ(cx, obj);
/* NB: wp is held, so we can safely dereference it still. */ /* NB: wp is held, so we can safely dereference it still. */
if (!wp->handler(cx, obj, propid, if (!wp->handler(cx, obj, propid,
SPROP_HAS_VALID_SLOT(sprop, scope) SPROP_HAS_VALID_SLOT(sprop, scope)
? obj->getSlotMT(cx, sprop->slot) ? Jsvalify(obj->getSlotMT(cx, sprop->slot))
: JSVAL_VOID, : JSVAL_VOID,
vp, wp->closure)) { Jsvalify(vp), wp->closure)) {
DBG_LOCK(rt); DBG_LOCK(rt);
DropWatchPointAndUnlock(cx, wp, JSWP_HELD); DropWatchPointAndUnlock(cx, wp, JSWP_HELD);
return JS_FALSE; return JS_FALSE;
@ -640,7 +638,7 @@ js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
* trusted. * trusted.
*/ */
JSObject *closure = wp->closure; JSObject *closure = wp->closure;
JSClass *clasp = closure->getClass(); Class *clasp = closure->getClass();
JSFunction *fun; JSFunction *fun;
JSScript *script; JSScript *script;
if (clasp == &js_FunctionClass) { if (clasp == &js_FunctionClass) {
@ -677,16 +675,18 @@ js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
} }
/* Initialize slots/frame. */ /* Initialize slots/frame. */
jsval *vp = frame.getvp(); Value *vp = frame.getvp();
PodZero(vp, vplen); MakeValueRangeGCSafe(vp, vplen);
vp[0] = OBJECT_TO_JSVAL(closure); vp[0].setObject(*closure);
vp[1].setNull(); // satisfy LeaveTree assert
JSStackFrame *fp = frame.getFrame(); JSStackFrame *fp = frame.getFrame();
PodZero(fp->slots(), nfixed);
PodZero(fp); PodZero(fp);
MakeValueRangeGCSafe(fp->slots(), nfixed);
fp->script = script; fp->script = script;
fp->fun = fun; fp->fun = fun;
fp->argv = vp + 2; fp->argv = vp + 2;
fp->scopeChain = closure->getParent(); fp->scopeChain = closure->getParent();
fp->argsobj = NULL;
/* Initialize regs. */ /* Initialize regs. */
regs.pc = script ? script->code : NULL; regs.pc = script ? script->code : NULL;
@ -706,8 +706,8 @@ js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
JSBool ok = !wp->setter || JSBool ok = !wp->setter ||
(sprop->hasSetterValue() (sprop->hasSetterValue()
? js_InternalCall(cx, obj, ? InternalCall(cx, obj,
CastAsObjectJSVal(wp->setter), ObjectValue(*CastAsObject(wp->setter)),
1, vp, vp) 1, vp, vp)
: callJSPropertyOpSetter(cx, wp->setter, obj, userid, vp)); : callJSPropertyOpSetter(cx, wp->setter, obj, userid, vp));
@ -724,16 +724,16 @@ js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
} }
JSBool JSBool
js_watch_set_wrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, js_watch_set_wrapper(JSContext *cx, JSObject *obj, uintN argc, Value *argv,
jsval *rval) Value *rval)
{ {
JSObject *funobj; JSObject *funobj;
JSFunction *wrapper; JSFunction *wrapper;
jsval userid; jsid userid;
funobj = JSVAL_TO_OBJECT(argv[-2]); funobj = &argv[-2].toObject();
wrapper = GET_FUNCTION_PRIVATE(cx, funobj); wrapper = GET_FUNCTION_PRIVATE(cx, funobj);
userid = ATOM_KEY(wrapper->atom); userid = ATOM_TO_JSID(wrapper->atom);
*rval = argv[0]; *rval = argv[0];
return js_watch_set(cx, obj, userid, rval); return js_watch_set(cx, obj, userid, rval);
} }
@ -752,8 +752,8 @@ IsWatchedProperty(JSContext *cx, JSScopeProperty *sprop)
return sprop->setterOp() == js_watch_set; return sprop->setterOp() == js_watch_set;
} }
JSPropertyOp PropertyOp
js_WrapWatchedSetter(JSContext *cx, jsid id, uintN attrs, JSPropertyOp setter) js_WrapWatchedSetter(JSContext *cx, jsid id, uintN attrs, PropertyOp setter)
{ {
JSAtom *atom; JSAtom *atom;
JSFunction *wrapper; JSFunction *wrapper;
@ -764,7 +764,7 @@ js_WrapWatchedSetter(JSContext *cx, jsid id, uintN attrs, JSPropertyOp setter)
if (JSID_IS_ATOM(id)) { if (JSID_IS_ATOM(id)) {
atom = JSID_TO_ATOM(id); atom = JSID_TO_ATOM(id);
} else if (JSID_IS_INT(id)) { } else if (JSID_IS_INT(id)) {
if (!js_ValueToStringId(cx, INT_JSID_TO_JSVAL(id), &id)) if (!js_ValueToStringId(cx, IdToValue(id), &id))
return NULL; return NULL;
atom = JSID_TO_ATOM(id); atom = JSID_TO_ATOM(id);
} else { } else {
@ -779,11 +779,11 @@ js_WrapWatchedSetter(JSContext *cx, jsid id, uintN attrs, JSPropertyOp setter)
} }
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval idval, JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsid id,
JSWatchPointHandler handler, void *closure) JSWatchPointHandler handler, void *closure)
{ {
JSObject *origobj; JSObject *origobj;
jsval v; Value v;
uintN attrs; uintN attrs;
jsid propid; jsid propid;
JSObject *pobj; JSObject *pobj;
@ -792,7 +792,7 @@ JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval idval,
JSRuntime *rt; JSRuntime *rt;
JSBool ok; JSBool ok;
JSWatchPoint *wp; JSWatchPoint *wp;
JSPropertyOp watcher; PropertyOp watcher;
origobj = obj; origobj = obj;
obj = obj->wrappedObject(cx); obj = obj->wrappedObject(cx);
@ -801,13 +801,13 @@ JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval idval,
return JS_FALSE; return JS_FALSE;
AutoValueRooter idroot(cx); AutoValueRooter idroot(cx);
if (JSVAL_IS_INT(idval)) { if (JSID_IS_INT(id)) {
propid = INT_JSVAL_TO_JSID(idval); propid = id;
} else { } else {
if (!js_ValueToStringId(cx, idval, &propid)) if (!js_ValueToStringId(cx, IdToValue(id), &propid))
return JS_FALSE; return JS_FALSE;
propid = js_CheckForStringIndex(propid); propid = js_CheckForStringIndex(propid);
idroot.set(ID_TO_VALUE(propid)); idroot.set(IdToValue(propid));
} }
/* /*
@ -832,7 +832,7 @@ JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval idval,
sprop = js_FindWatchPoint(rt, obj->scope(), propid); sprop = js_FindWatchPoint(rt, obj->scope(), propid);
if (!sprop) { if (!sprop) {
/* Make a new property in obj so we can watch for the first set. */ /* Make a new property in obj so we can watch for the first set. */
if (!js_DefineNativeProperty(cx, obj, propid, JSVAL_VOID, NULL, NULL, if (!js_DefineNativeProperty(cx, obj, propid, UndefinedValue(), NULL, NULL,
JSPROP_ENUMERATE, 0, 0, &prop)) { JSPROP_ENUMERATE, 0, 0, &prop)) {
return JS_FALSE; return JS_FALSE;
} }
@ -841,14 +841,14 @@ JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval idval,
} else if (pobj != obj) { } else if (pobj != obj) {
/* Clone the prototype property so we can watch the right object. */ /* Clone the prototype property so we can watch the right object. */
AutoValueRooter valroot(cx); AutoValueRooter valroot(cx);
JSPropertyOp getter, setter; PropertyOp getter, setter;
uintN attrs, flags; uintN attrs, flags;
intN shortid; intN shortid;
if (pobj->isNative()) { if (pobj->isNative()) {
valroot.set(SPROP_HAS_VALID_SLOT(sprop, pobj->scope()) valroot.set(SPROP_HAS_VALID_SLOT(sprop, pobj->scope())
? pobj->lockedGetSlot(sprop->slot) ? pobj->lockedGetSlot(sprop->slot)
: JSVAL_VOID); : UndefinedValue());
getter = sprop->getter(); getter = sprop->getter();
setter = sprop->setter(); setter = sprop->setter();
attrs = sprop->attributes(); attrs = sprop->attributes();
@ -933,7 +933,7 @@ out:
} }
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_ClearWatchPoint(JSContext *cx, JSObject *obj, jsval id, JS_ClearWatchPoint(JSContext *cx, JSObject *obj, jsid id,
JSWatchPointHandler *handlerp, void **closurep) JSWatchPointHandler *handlerp, void **closurep)
{ {
JSRuntime *rt; JSRuntime *rt;
@ -1024,6 +1024,43 @@ JS_LineNumberToPC(JSContext *cx, JSScript *script, uintN lineno)
return js_LineNumberToPC(script, lineno); return js_LineNumberToPC(script, lineno);
} }
JS_PUBLIC_API(uintN)
JS_GetFunctionArgumentCount(JSContext *cx, JSFunction *fun)
{
return fun->nargs;
}
JS_PUBLIC_API(JSBool)
JS_FunctionHasLocalNames(JSContext *cx, JSFunction *fun)
{
return fun->hasLocalNames();
}
extern JS_PUBLIC_API(jsuword *)
JS_GetFunctionLocalNameArray(JSContext *cx, JSFunction *fun, void **markp)
{
*markp = JS_ARENA_MARK(&cx->tempPool);
return js_GetLocalNameArray(cx, fun, &cx->tempPool);
}
extern JS_PUBLIC_API(JSAtom *)
JS_LocalNameToAtom(jsuword w)
{
return JS_LOCAL_NAME_TO_ATOM(w);
}
extern JS_PUBLIC_API(JSString *)
JS_AtomKey(JSAtom *atom)
{
return ATOM_TO_STRING(atom);
}
extern JS_PUBLIC_API(void)
JS_ReleaseFunctionLocalNameArray(JSContext *cx, void *mark)
{
JS_ARENA_RELEASE(&cx->tempPool, mark);
}
JS_PUBLIC_API(JSScript *) JS_PUBLIC_API(JSScript *)
JS_GetFunctionScript(JSContext *cx, JSFunction *fun) JS_GetFunctionScript(JSContext *cx, JSFunction *fun)
{ {
@ -1033,13 +1070,13 @@ JS_GetFunctionScript(JSContext *cx, JSFunction *fun)
JS_PUBLIC_API(JSNative) JS_PUBLIC_API(JSNative)
JS_GetFunctionNative(JSContext *cx, JSFunction *fun) JS_GetFunctionNative(JSContext *cx, JSFunction *fun)
{ {
return FUN_NATIVE(fun); return Jsvalify(FUN_NATIVE(fun));
} }
JS_PUBLIC_API(JSFastNative) JS_PUBLIC_API(JSFastNative)
JS_GetFunctionFastNative(JSContext *cx, JSFunction *fun) JS_GetFunctionFastNative(JSContext *cx, JSFunction *fun)
{ {
return FUN_FAST_NATIVE(fun); return Jsvalify(FUN_FAST_NATIVE(fun));
} }
JS_PUBLIC_API(JSPrincipals *) JS_PUBLIC_API(JSPrincipals *)
@ -1242,13 +1279,13 @@ JS_IsDebuggerFrame(JSContext *cx, JSStackFrame *fp)
JS_PUBLIC_API(jsval) JS_PUBLIC_API(jsval)
JS_GetFrameReturnValue(JSContext *cx, JSStackFrame *fp) JS_GetFrameReturnValue(JSContext *cx, JSStackFrame *fp)
{ {
return fp->rval; return Jsvalify(fp->rval);
} }
JS_PUBLIC_API(void) JS_PUBLIC_API(void)
JS_SetFrameReturnValue(JSContext *cx, JSStackFrame *fp, jsval rval) JS_SetFrameReturnValue(JSContext *cx, JSStackFrame *fp, jsval rval)
{ {
fp->rval = rval; fp->rval = Valueify(rval);
} }
/************************************************************************/ /************************************************************************/
@ -1362,8 +1399,8 @@ JS_EvaluateUCInStackFrame(JSContext *cx, JSStackFrame *fp,
} }
} }
ok = js_Execute(cx, scobj, script, fp, JSFRAME_DEBUGGER | JSFRAME_EVAL, ok = Execute(cx, scobj, script, fp, JSFRAME_DEBUGGER | JSFRAME_EVAL,
rval); Valueify(rval));
if (cx->fp != fp) if (cx->fp != fp)
memcpy(cx->display, displayCopy, sizeof cx->display); memcpy(cx->display, displayCopy, sizeof cx->display);
@ -1415,19 +1452,19 @@ JS_PUBLIC_API(JSBool)
JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop,
JSPropertyDesc *pd) JSPropertyDesc *pd)
{ {
pd->id = ID_TO_VALUE(sprop->id); pd->id = IdToJsval(sprop->id);
JSBool wasThrowing = cx->throwing; JSBool wasThrowing = cx->throwing;
AutoValueRooter lastException(cx, cx->exception); AutoValueRooter lastException(cx, cx->exception);
cx->throwing = JS_FALSE; cx->throwing = JS_FALSE;
if (!js_GetProperty(cx, obj, sprop->id, &pd->value)) { if (!js_GetProperty(cx, obj, sprop->id, Valueify(&pd->value))) {
if (!cx->throwing) { if (!cx->throwing) {
pd->flags = JSPD_ERROR; pd->flags = JSPD_ERROR;
pd->value = JSVAL_VOID; pd->value = JSVAL_VOID;
} else { } else {
pd->flags = JSPD_EXCEPTION; pd->flags = JSPD_EXCEPTION;
pd->value = cx->exception; pd->value = Jsvalify(cx->exception);
} }
} else { } else {
pd->flags = 0; pd->flags = 0;
@ -1457,7 +1494,7 @@ JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop,
JSScopeProperty *aprop; JSScopeProperty *aprop;
for (aprop = scope->lastProperty(); aprop; aprop = aprop->parent) { for (aprop = scope->lastProperty(); aprop; aprop = aprop->parent) {
if (aprop != sprop && aprop->slot == sprop->slot) { if (aprop != sprop && aprop->slot == sprop->slot) {
pd->alias = ID_TO_VALUE(aprop->id); pd->alias = IdToJsval(aprop->id);
break; break;
} }
} }
@ -1468,13 +1505,12 @@ JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop,
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda) JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda)
{ {
JSClass *clasp;
JSScope *scope; JSScope *scope;
uint32 i, n; uint32 i, n;
JSPropertyDesc *pd; JSPropertyDesc *pd;
JSScopeProperty *sprop; JSScopeProperty *sprop;
clasp = obj->getClass(); Class *clasp = obj->getClass();
if (!obj->isNative() || (clasp->flags & JSCLASS_NEW_ENUMERATE)) { if (!obj->isNative() || (clasp->flags & JSCLASS_NEW_ENUMERATE)) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_CANT_DESCRIBE_PROPS, clasp->name); JSMSG_CANT_DESCRIBE_PROPS, clasp->name);
@ -1497,13 +1533,13 @@ JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda)
return JS_FALSE; return JS_FALSE;
i = 0; i = 0;
for (sprop = scope->lastProperty(); sprop; sprop = sprop->parent) { for (sprop = scope->lastProperty(); sprop; sprop = sprop->parent) {
if (!js_AddRoot(cx, &pd[i].id, NULL)) if (!js_AddRoot(cx, Valueify(&pd[i].id), NULL))
goto bad; goto bad;
if (!js_AddRoot(cx, &pd[i].value, NULL)) if (!js_AddRoot(cx, Valueify(&pd[i].value), NULL))
goto bad; goto bad;
if (!JS_GetPropertyDesc(cx, obj, sprop, &pd[i])) if (!JS_GetPropertyDesc(cx, obj, sprop, &pd[i]))
goto bad; goto bad;
if ((pd[i].flags & JSPD_ALIAS) && !js_AddRoot(cx, &pd[i].alias, NULL)) if ((pd[i].flags & JSPD_ALIAS) && !js_AddRoot(cx, Valueify(&pd[i].alias), NULL))
goto bad; goto bad;
if (++i == n) if (++i == n)
break; break;
@ -1548,9 +1584,10 @@ SetupFakeFrame(JSContext *cx, ExecuteFrameGuard &frame, JSFrameRegs &regs, JSObj
if (!cx->stack().getExecuteFrame(cx, js_GetTopStackFrame(cx), vplen, nfixed, frame)) if (!cx->stack().getExecuteFrame(cx, js_GetTopStackFrame(cx), vplen, nfixed, frame))
return false; return false;
jsval *vp = frame.getvp(); Value *vp = frame.getvp();
PodZero(vp, vplen); PodZero(vp, vplen);
vp[0] = OBJECT_TO_JSVAL(scopeobj); vp[0].setObject(*scopeobj);
vp[1].setNull(); // satisfy LeaveTree assert
JSStackFrame *fp = frame.getFrame(); JSStackFrame *fp = frame.getFrame();
PodZero(fp); PodZero(fp);
@ -1700,7 +1737,7 @@ JS_GetObjectTotalSize(JSContext *cx, JSObject *obj)
nbytes = sizeof *obj; nbytes = sizeof *obj;
if (obj->dslots) { if (obj->dslots) {
nbytes += ((uint32)obj->dslots[-1] - JS_INITIAL_NSLOTS + 1) nbytes += (obj->dslots[-1].toPrivateUint32() - JS_INITIAL_NSLOTS + 1)
* sizeof obj->dslots[0]; * sizeof obj->dslots[0];
} }
if (obj->isNative()) { if (obj->isNative()) {
@ -1719,12 +1756,8 @@ GetAtomTotalSize(JSContext *cx, JSAtom *atom)
size_t nbytes; size_t nbytes;
nbytes = sizeof(JSAtom *) + sizeof(JSDHashEntryStub); nbytes = sizeof(JSAtom *) + sizeof(JSDHashEntryStub);
if (ATOM_IS_STRING(atom)) {
nbytes += sizeof(JSString); nbytes += sizeof(JSString);
nbytes += (ATOM_TO_STRING(atom)->flatLength() + 1) * sizeof(jschar); nbytes += (ATOM_TO_STRING(atom)->flatLength() + 1) * sizeof(jschar);
} else if (ATOM_IS_DOUBLE(atom)) {
nbytes += sizeof(jsdouble);
}
return nbytes; return nbytes;
} }

Просмотреть файл

@ -87,11 +87,11 @@ JS_ClearInterrupt(JSRuntime *rt, JSInterruptHook *handlerp, void **closurep);
/************************************************************************/ /************************************************************************/
extern JS_PUBLIC_API(JSBool) extern JS_PUBLIC_API(JSBool)
JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval id, JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsid id,
JSWatchPointHandler handler, void *closure); JSWatchPointHandler handler, void *closure);
extern JS_PUBLIC_API(JSBool) extern JS_PUBLIC_API(JSBool)
JS_ClearWatchPoint(JSContext *cx, JSObject *obj, jsval id, JS_ClearWatchPoint(JSContext *cx, JSObject *obj, jsid id,
JSWatchPointHandler *handlerp, void **closurep); JSWatchPointHandler *handlerp, void **closurep);
extern JS_PUBLIC_API(JSBool) extern JS_PUBLIC_API(JSBool)
@ -114,22 +114,26 @@ js_SweepWatchPoints(JSContext *cx);
extern JSScopeProperty * extern JSScopeProperty *
js_FindWatchPoint(JSRuntime *rt, JSScope *scope, jsid id); js_FindWatchPoint(JSRuntime *rt, JSScope *scope, jsid id);
#ifdef __cplusplus
/* /*
* NB: callers outside of jsdbgapi.c must pass non-null scope. * NB: callers outside of jsdbgapi.c must pass non-null scope.
*/ */
extern JSPropertyOp extern js::PropertyOp
js_GetWatchedSetter(JSRuntime *rt, JSScope *scope, js_GetWatchedSetter(JSRuntime *rt, JSScope *scope,
const JSScopeProperty *sprop); const JSScopeProperty *sprop);
extern JSBool extern JSBool
js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp); js_watch_set(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
extern JSBool extern JSBool
js_watch_set_wrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, js_watch_set_wrapper(JSContext *cx, JSObject *obj, uintN argc, js::Value *argv,
jsval *rval); js::Value *rval);
extern JSPropertyOp extern js::PropertyOp
js_WrapWatchedSetter(JSContext *cx, jsid id, uintN attrs, JSPropertyOp setter); js_WrapWatchedSetter(JSContext *cx, jsid id, uintN attrs, js::PropertyOp setter);
#endif
#endif /* JS_HAS_OBJ_WATCHPOINT */ #endif /* JS_HAS_OBJ_WATCHPOINT */
@ -141,6 +145,29 @@ JS_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc);
extern JS_PUBLIC_API(jsbytecode *) extern JS_PUBLIC_API(jsbytecode *)
JS_LineNumberToPC(JSContext *cx, JSScript *script, uintN lineno); JS_LineNumberToPC(JSContext *cx, JSScript *script, uintN lineno);
extern JS_PUBLIC_API(uintN)
JS_GetFunctionArgumentCount(JSContext *cx, JSFunction *fun);
extern JS_PUBLIC_API(JSBool)
JS_FunctionHasLocalNames(JSContext *cx, JSFunction *fun);
/*
* N.B. The mark is in the context temp pool and thus the caller must take care
* to call JS_ReleaseFunctionLocalNameArray in a LIFO manner (wrt to any other
* call that may use the temp pool.
*/
extern JS_PUBLIC_API(jsuword *)
JS_GetFunctionLocalNameArray(JSContext *cx, JSFunction *fun, void **markp);
extern JS_PUBLIC_API(JSAtom *)
JS_LocalNameToAtom(jsuword w);
extern JS_PUBLIC_API(JSString *)
JS_AtomKey(JSAtom *atom);
extern JS_PUBLIC_API(void)
JS_ReleaseFunctionLocalNameArray(JSContext *cx, void *mark);
extern JS_PUBLIC_API(JSScript *) extern JS_PUBLIC_API(JSScript *)
JS_GetFunctionScript(JSContext *cx, JSFunction *fun); JS_GetFunctionScript(JSContext *cx, JSFunction *fun);
@ -298,7 +325,7 @@ JS_EvaluateInStackFrame(JSContext *cx, JSStackFrame *fp,
/************************************************************************/ /************************************************************************/
typedef struct JSPropertyDesc { typedef struct JSPropertyDesc {
jsval id; /* primary id, a string or int */ jsval id; /* primary id, atomized string, or int */
jsval value; /* property value */ jsval value; /* property value */
uint8 flags; /* flags, see below */ uint8 flags; /* flags, see below */
uint8 spare; /* unused */ uint8 spare; /* unused */

Просмотреть файл

@ -51,6 +51,8 @@
#include "jslibmath.h" #include "jslibmath.h"
#include "jscntxt.h" #include "jscntxt.h"
#include "jsobjinlines.h"
#ifdef IS_LITTLE_ENDIAN #ifdef IS_LITTLE_ENDIAN
#define IEEE_8087 #define IEEE_8087
#else #else

Просмотреть файл

@ -106,30 +106,28 @@ jsdtrace_frame_linenumber(JSContext *cx, JSStackFrame *fp)
* provide raw (unmasked) jsvals should type info be useful from D scripts. * provide raw (unmasked) jsvals should type info be useful from D scripts.
*/ */
static void * static void *
jsdtrace_jsvaltovoid(JSContext *cx, const jsval argval) jsdtrace_jsvaltovoid(JSContext *cx, const js::Value &argval)
{ {
JSType type = TYPEOF(cx, argval); if (argval.isNull())
return (void *)JS_TYPE_STR(JSTYPE_NULL);
switch (type) { if (argval.isUndefined())
case JSTYPE_NULL: return (void *)JS_TYPE_STR(JSTYPE_VOID);
case JSTYPE_VOID:
return (void *)JS_TYPE_STR(type);
case JSTYPE_BOOLEAN: if (argval.isBoolean())
return (void *)JSVAL_TO_BOOLEAN(argval); return (void *)argval.toBoolean();
case JSTYPE_STRING: if (argval.isString())
return (void *)js_GetStringBytes(cx, JSVAL_TO_STRING(argval)); return (void *)js_GetStringBytes(cx, argval.toString());
case JSTYPE_NUMBER: if (argval.isNumber()) {
if (JSVAL_IS_INT(argval)) if (argval.isInt32())
return (void *)JSVAL_TO_INT(argval); return (void *)argval.toInt32();
return JSVAL_TO_DOUBLE(argval); // FIXME Now what?
//return (void *)argval.toDouble();
default:
return JSVAL_TO_GCTHING(argval);
} }
/* NOTREACHED */
return argval.asGCThing();
} }
static char * static char *
@ -176,7 +174,7 @@ DTrace::handleFunctionInfo(JSContext *cx, JSStackFrame *fp, JSStackFrame *dfp, J
void void
DTrace::handleFunctionArgs(JSContext *cx, JSStackFrame *fp, const JSFunction *fun, jsuint argc, DTrace::handleFunctionArgs(JSContext *cx, JSStackFrame *fp, const JSFunction *fun, jsuint argc,
jsval *argv) js::Value *argv)
{ {
JAVASCRIPT_FUNCTION_ARGS(jsdtrace_filename(fp), jsdtrace_fun_classname(fun), JAVASCRIPT_FUNCTION_ARGS(jsdtrace_filename(fp), jsdtrace_fun_classname(fun),
jsdtrace_fun_name(cx, fun), argc, (void *)argv, jsdtrace_fun_name(cx, fun), argc, (void *)argv,
@ -188,7 +186,7 @@ DTrace::handleFunctionArgs(JSContext *cx, JSStackFrame *fp, const JSFunction *fu
} }
void void
DTrace::handleFunctionRval(JSContext *cx, JSStackFrame *fp, JSFunction *fun, jsval rval) DTrace::handleFunctionRval(JSContext *cx, JSStackFrame *fp, JSFunction *fun, const js::Value &rval)
{ {
JAVASCRIPT_FUNCTION_RVAL(jsdtrace_filename(fp), jsdtrace_fun_classname(fun), JAVASCRIPT_FUNCTION_RVAL(jsdtrace_filename(fp), jsdtrace_fun_classname(fun),
jsdtrace_fun_name(cx, fun), jsdtrace_fun_linenumber(cx, fun), jsdtrace_fun_name(cx, fun), jsdtrace_fun_linenumber(cx, fun),
@ -224,7 +222,7 @@ DTrace::ObjectCreationScope::handleCreationImpl(JSObject *obj)
void void
DTrace::finalizeObjectImpl(JSObject *obj) DTrace::finalizeObjectImpl(JSObject *obj)
{ {
JSClass *clasp = obj->getClass(); Class *clasp = obj->getClass();
/* the first arg is NULL - reserved for future use (filename?) */ /* the first arg is NULL - reserved for future use (filename?) */
JAVASCRIPT_OBJECT_FINALIZE(NULL, (char *)clasp->name, (uintptr_t)obj); JAVASCRIPT_OBJECT_FINALIZE(NULL, (char *)clasp->name, (uintptr_t)obj);

Просмотреть файл

@ -49,8 +49,9 @@ class DTrace {
static void handleFunctionInfo(JSContext *cx, JSStackFrame *fp, JSStackFrame *dfp, static void handleFunctionInfo(JSContext *cx, JSStackFrame *fp, JSStackFrame *dfp,
JSFunction *fun); JSFunction *fun);
static void handleFunctionArgs(JSContext *cx, JSStackFrame *fp, const JSFunction *fun, static void handleFunctionArgs(JSContext *cx, JSStackFrame *fp, const JSFunction *fun,
jsuint argc, jsval *argv); jsuint argc, js::Value *argv);
static void handleFunctionRval(JSContext *cx, JSStackFrame *fp, JSFunction *fun, jsval rval); static void handleFunctionRval(JSContext *cx, JSStackFrame *fp, JSFunction *fun,
const js::Value &rval);
static void handleFunctionReturn(JSContext *cx, JSStackFrame *fp, JSFunction *fun); static void handleFunctionReturn(JSContext *cx, JSStackFrame *fp, JSFunction *fun);
static void finalizeObjectImpl(JSObject *obj); static void finalizeObjectImpl(JSObject *obj);
public: public:
@ -59,9 +60,11 @@ class DTrace {
* it is a function as a predicate to the dtrace event emission. * it is a function as a predicate to the dtrace event emission.
*/ */
static void enterJSFun(JSContext *cx, JSStackFrame *fp, JSFunction *fun, static void enterJSFun(JSContext *cx, JSStackFrame *fp, JSFunction *fun,
JSStackFrame *dfp, jsuint argc, jsval *argv, jsval *lval = NULL); JSStackFrame *dfp, jsuint argc, js::Value *argv,
static void exitJSFun(JSContext *cx, JSStackFrame *fp, JSFunction *fun, jsval rval, js::Value *lval = NULL);
jsval *lval = NULL); static void exitJSFun(JSContext *cx, JSStackFrame *fp, JSFunction *fun,
const js::Value &rval,
js::Value *lval = NULL);
static void finalizeObject(JSObject *obj); static void finalizeObject(JSObject *obj);
@ -77,12 +80,12 @@ class DTrace {
class ObjectCreationScope { class ObjectCreationScope {
JSContext * const cx; JSContext * const cx;
JSStackFrame * const fp; JSStackFrame * const fp;
JSClass * const clasp; js::Class * const clasp;
void handleCreationStart(); void handleCreationStart();
void handleCreationImpl(JSObject *obj); void handleCreationImpl(JSObject *obj);
void handleCreationEnd(); void handleCreationEnd();
public: public:
ObjectCreationScope(JSContext *cx, JSStackFrame *fp, JSClass *clasp); ObjectCreationScope(JSContext *cx, JSStackFrame *fp, js::Class *clasp);
void handleCreation(JSObject *obj); void handleCreation(JSObject *obj);
~ObjectCreationScope(); ~ObjectCreationScope();
}; };
@ -91,10 +94,10 @@ class DTrace {
inline void inline void
DTrace::enterJSFun(JSContext *cx, JSStackFrame *fp, JSFunction *fun, JSStackFrame *dfp, DTrace::enterJSFun(JSContext *cx, JSStackFrame *fp, JSFunction *fun, JSStackFrame *dfp,
jsuint argc, jsval *argv, jsval *lval) jsuint argc, js::Value *argv, js::Value *lval)
{ {
#ifdef INCLUDE_MOZILLA_DTRACE #ifdef INCLUDE_MOZILLA_DTRACE
if (!lval || VALUE_IS_FUNCTION(cx, *lval)) { if (!lval || lval->isFunObj()) {
if (JAVASCRIPT_FUNCTION_ENTRY_ENABLED()) if (JAVASCRIPT_FUNCTION_ENTRY_ENABLED())
enterJSFunImpl(cx, fp, fun); enterJSFunImpl(cx, fp, fun);
if (JAVASCRIPT_FUNCTION_INFO_ENABLED()) if (JAVASCRIPT_FUNCTION_INFO_ENABLED())
@ -106,10 +109,11 @@ DTrace::enterJSFun(JSContext *cx, JSStackFrame *fp, JSFunction *fun, JSStackFram
} }
inline void inline void
DTrace::exitJSFun(JSContext *cx, JSStackFrame *fp, JSFunction *fun, jsval rval, jsval *lval) DTrace::exitJSFun(JSContext *cx, JSStackFrame *fp, JSFunction *fun,
const js::Value &rval, js::Value *lval)
{ {
#ifdef INCLUDE_MOZILLA_DTRACE #ifdef INCLUDE_MOZILLA_DTRACE
if (!lval || VALUE_IS_FUNCTION(cx, *lval)) { if (!lval || lval->isFunObj()) {
if (JAVASCRIPT_FUNCTION_RVAL_ENABLED()) if (JAVASCRIPT_FUNCTION_RVAL_ENABLED())
handleFunctionRval(cx, fp, fun, rval); handleFunctionRval(cx, fp, fun, rval);
if (JAVASCRIPT_FUNCTION_RETURN_ENABLED()) if (JAVASCRIPT_FUNCTION_RETURN_ENABLED())
@ -151,7 +155,7 @@ DTrace::ExecutionScope::~ExecutionScope()
/* Object creation scope. */ /* Object creation scope. */
inline inline
DTrace::ObjectCreationScope::ObjectCreationScope(JSContext *cx, JSStackFrame *fp, JSClass *clasp) DTrace::ObjectCreationScope::ObjectCreationScope(JSContext *cx, JSStackFrame *fp, js::Class *clasp)
: cx(cx), fp(fp), clasp(clasp) : cx(cx), fp(fp), clasp(clasp)
{ {
#ifdef INCLUDE_MOZILLA_DTRACE #ifdef INCLUDE_MOZILLA_DTRACE

Просмотреть файл

@ -100,7 +100,8 @@ JSCodeGenerator::JSCodeGenerator(Parser *parser,
numSpanDeps(0), numJumpTargets(0), spanDepTodo(0), numSpanDeps(0), numJumpTargets(0), spanDepTodo(0),
arrayCompDepth(0), arrayCompDepth(0),
emitLevel(0), emitLevel(0),
constMap(parser->context) constMap(parser->context),
constList(parser->context)
{ {
flags = TCF_COMPILING; flags = TCF_COMPILING;
memset(&prolog, 0, sizeof prolog); memset(&prolog, 0, sizeof prolog);
@ -214,7 +215,7 @@ UpdateDepth(JSContext *cx, JSCodeGenerator *cg, ptrdiff_t target)
JS_ASSERT(nuses == 0); JS_ASSERT(nuses == 0);
blockObj = cg->objectList.lastbox->object; blockObj = cg->objectList.lastbox->object;
JS_ASSERT(blockObj->getClass() == &js_BlockClass); JS_ASSERT(blockObj->getClass() == &js_BlockClass);
JS_ASSERT(JSVAL_IS_VOID(blockObj->fslots[JSSLOT_BLOCK_DEPTH])); JS_ASSERT(blockObj->fslots[JSSLOT_BLOCK_DEPTH].isUndefined());
OBJ_SET_BLOCK_DEPTH(cx, blockObj, cg->stackDepth); OBJ_SET_BLOCK_DEPTH(cx, blockObj, cg->stackDepth);
ndefs = OBJ_BLOCK_COUNT(cx, blockObj); ndefs = OBJ_BLOCK_COUNT(cx, blockObj);
@ -1549,28 +1550,9 @@ JSBool
js_DefineCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom, js_DefineCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom,
JSParseNode *pn) JSParseNode *pn)
{ {
jsdouble dval;
jsint ival;
JSAtom *valueAtom;
jsval v;
/* XXX just do numbers for now */ /* XXX just do numbers for now */
if (pn->pn_type == TOK_NUMBER) { if (pn->pn_type == TOK_NUMBER) {
dval = pn->pn_dval; if (!cg->constMap.put(atom, NumberValue(pn->pn_dval)))
if (JSDOUBLE_IS_INT(dval, ival) && INT_FITS_IN_JSVAL(ival)) {
v = INT_TO_JSVAL(ival);
} else {
/*
* We atomize double to root a jsdouble instance that we wrap as
* jsval and store in cg->constList. This works because atoms are
* protected from GC during compilation.
*/
valueAtom = js_AtomizeDouble(cx, dval);
if (!valueAtom)
return JS_FALSE;
v = ATOM_KEY(valueAtom);
}
if (!cg->constMap.put(atom, v))
return JS_FALSE; return JS_FALSE;
} }
return JS_TRUE; return JS_TRUE;
@ -1601,8 +1583,8 @@ js_LexicalLookup(JSTreeContext *tc, JSAtom *atom, jsint *slotp, JSStmtInfo *stmt
JS_ASSERT(sprop->hasShortID()); JS_ASSERT(sprop->hasShortID());
if (slotp) { if (slotp) {
JS_ASSERT(JSVAL_IS_INT(obj->fslots[JSSLOT_BLOCK_DEPTH])); JS_ASSERT(obj->fslots[JSSLOT_BLOCK_DEPTH].isInt32());
*slotp = JSVAL_TO_INT(obj->fslots[JSSLOT_BLOCK_DEPTH]) + *slotp = obj->fslots[JSSLOT_BLOCK_DEPTH].toInt32() +
sprop->shortid; sprop->shortid;
} }
return stmt; return stmt;
@ -1615,12 +1597,12 @@ js_LexicalLookup(JSTreeContext *tc, JSAtom *atom, jsint *slotp, JSStmtInfo *stmt
} }
/* /*
* The function sets vp to JSVAL_HOLE when the atom does not corresponds to a * The function sets vp to NO_CONSTANT when the atom does not corresponds to a
* name defining a constant. * name defining a constant.
*/ */
static JSBool static JSBool
LookupCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom, LookupCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom,
jsval *vp) Value *constp)
{ {
JSStmtInfo *stmt; JSStmtInfo *stmt;
JSObject *obj; JSObject *obj;
@ -1630,7 +1612,7 @@ LookupCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom,
* This enables propagating consts from top-level into switch cases in a * This enables propagating consts from top-level into switch cases in a
* function compiled along with the top-level script. * function compiled along with the top-level script.
*/ */
*vp = JSVAL_HOLE; constp->setMagic(JS_NO_CONSTANT);
do { do {
if (cg->inFunction() || cg->compileAndGo()) { if (cg->inFunction() || cg->compileAndGo()) {
/* XXX this will need revising if 'const' becomes block-scoped. */ /* XXX this will need revising if 'const' becomes block-scoped. */
@ -1639,8 +1621,8 @@ LookupCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom,
return JS_TRUE; return JS_TRUE;
if (JSCodeGenerator::ConstMap::Ptr p = cg->constMap.lookup(atom)) { if (JSCodeGenerator::ConstMap::Ptr p = cg->constMap.lookup(atom)) {
JS_ASSERT(p->value != JSVAL_HOLE); JS_ASSERT(!p->value.isMagic(JS_NO_CONSTANT));
*vp = p->value; *constp = p->value;
return JS_TRUE; return JS_TRUE;
} }
@ -1670,7 +1652,7 @@ LookupCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom,
*/ */
if (!sprop->writable() && !sprop->configurable() && if (!sprop->writable() && !sprop->configurable() &&
sprop->hasDefaultGetter() && SPROP_HAS_VALID_SLOT(sprop, scope)) { sprop->hasDefaultGetter() && SPROP_HAS_VALID_SLOT(sprop, scope)) {
*vp = obj->lockedGetSlot(sprop->slot); *constp = obj->lockedGetSlot(sprop->slot);
} }
} }
JS_UNLOCK_SCOPE(cx, scope); JS_UNLOCK_SCOPE(cx, scope);
@ -1849,15 +1831,15 @@ EmitEnterBlock(JSContext *cx, JSParseNode *pn, JSCodeGenerator *cg)
uintN base = JSSLOT_FREE(&js_BlockClass); uintN base = JSSLOT_FREE(&js_BlockClass);
for (uintN slot = base, limit = base + OBJ_BLOCK_COUNT(cx, blockObj); slot < limit; slot++) { for (uintN slot = base, limit = base + OBJ_BLOCK_COUNT(cx, blockObj); slot < limit; slot++) {
jsval v = blockObj->getSlot(slot); const Value &v = blockObj->getSlot(slot);
/* Beware the empty destructuring dummy. */ /* Beware the empty destructuring dummy. */
if (JSVAL_IS_VOID(v)) { if (v.isUndefined()) {
JS_ASSERT(slot + 1 <= limit); JS_ASSERT(slot + 1 <= limit);
continue; continue;
} }
JSDefinition *dn = (JSDefinition *) JSVAL_TO_PRIVATE(v); JSDefinition *dn = (JSDefinition *) v.toPrivate();
JS_ASSERT(dn->pn_defn); JS_ASSERT(dn->pn_defn);
JS_ASSERT(uintN(dn->frameSlot() + depth) < JS_BIT(16)); JS_ASSERT(uintN(dn->frameSlot() + depth) < JS_BIT(16));
dn->pn_cookie.set(dn->pn_cookie.level(), dn->frameSlot() + depth); dn->pn_cookie.set(dn->pn_cookie.level(), dn->frameSlot() + depth);
@ -2819,7 +2801,7 @@ EmitElemOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
{ {
ptrdiff_t top; ptrdiff_t top;
JSParseNode *left, *right, *next, ltmp, rtmp; JSParseNode *left, *right, *next, ltmp, rtmp;
jsint slot; int32_t slot;
top = CG_OFFSET(cg); top = CG_OFFSET(cg);
if (pn->pn_arity == PN_LIST) { if (pn->pn_arity == PN_LIST) {
@ -2839,7 +2821,7 @@ EmitElemOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
if (!BindNameToSlot(cx, cg, left)) if (!BindNameToSlot(cx, cg, left))
return JS_FALSE; return JS_FALSE;
if (left->pn_op == JSOP_ARGUMENTS && if (left->pn_op == JSOP_ARGUMENTS &&
JSDOUBLE_IS_INT(next->pn_dval, slot) && JSDOUBLE_IS_INT32(next->pn_dval, &slot) &&
(jsuint)slot < JS_BIT(16)) { (jsuint)slot < JS_BIT(16)) {
/* /*
* arguments[i]() requires arguments object as "this". * arguments[i]() requires arguments object as "this".
@ -2894,7 +2876,6 @@ EmitElemOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
} }
right = &rtmp; right = &rtmp;
right->pn_type = TOK_STRING; right->pn_type = TOK_STRING;
JS_ASSERT(ATOM_IS_STRING(pn->pn_atom));
right->pn_op = js_IsIdentifier(ATOM_TO_STRING(pn->pn_atom)) right->pn_op = js_IsIdentifier(ATOM_TO_STRING(pn->pn_atom))
? JSOP_QNAMEPART ? JSOP_QNAMEPART
: JSOP_STRING; : JSOP_STRING;
@ -2914,7 +2895,7 @@ EmitElemOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
if (!BindNameToSlot(cx, cg, left)) if (!BindNameToSlot(cx, cg, left))
return JS_FALSE; return JS_FALSE;
if (left->pn_op == JSOP_ARGUMENTS && if (left->pn_op == JSOP_ARGUMENTS &&
JSDOUBLE_IS_INT(right->pn_dval, slot) && JSDOUBLE_IS_INT32(right->pn_dval, &slot) &&
(jsuint)slot < JS_BIT(16)) { (jsuint)slot < JS_BIT(16)) {
left->pn_offset = right->pn_offset = top; left->pn_offset = right->pn_offset = top;
EMIT_UINT16_IMM_OP(JSOP_ARGSUB, (jsatomid)slot); EMIT_UINT16_IMM_OP(JSOP_ARGSUB, (jsatomid)slot);
@ -2939,14 +2920,12 @@ EmitElemOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
static JSBool static JSBool
EmitNumberOp(JSContext *cx, jsdouble dval, JSCodeGenerator *cg) EmitNumberOp(JSContext *cx, jsdouble dval, JSCodeGenerator *cg)
{ {
jsint ival; int32_t ival;
uint32 u; uint32 u;
ptrdiff_t off; ptrdiff_t off;
jsbytecode *pc; jsbytecode *pc;
JSAtom *atom;
JSAtomListElement *ale;
if (JSDOUBLE_IS_INT(dval, ival) && INT_FITS_IN_JSVAL(ival)) { if (JSDOUBLE_IS_INT32(dval, &ival)) {
if (ival == 0) if (ival == 0)
return js_Emit1(cx, cg, JSOP_ZERO) >= 0; return js_Emit1(cx, cg, JSOP_ZERO) >= 0;
if (ival == 1) if (ival == 1)
@ -2973,14 +2952,26 @@ EmitNumberOp(JSContext *cx, jsdouble dval, JSCodeGenerator *cg)
return JS_TRUE; return JS_TRUE;
} }
atom = js_AtomizeDouble(cx, dval); if (!cg->constList.append(DoubleValue(dval)))
if (!atom)
return JS_FALSE; return JS_FALSE;
ale = cg->atomList.add(cg->parser, atom); return EmitIndexOp(cx, JSOP_DOUBLE, cg->constList.length() - 1, cg);
if (!ale) }
return JS_FALSE;
return EmitIndexOp(cx, JSOP_DOUBLE, ALE_INDEX(ale), cg); /*
* To avoid bloating all parse nodes for the special case of switch, values are
* allocated in the temp pool and pointed to by the parse node. These values
* are not currently recycled (like parse nodes) and the temp pool is only
* flushed at the end of compiling a script, so these values are technically
* leaked. This would only be a problem for scripts containing a large number
* of large switches, which seems unlikely.
*/
static Value *
AllocateSwitchConstant(JSContext *cx)
{
Value *pv;
JS_ARENA_ALLOCATE_TYPE(pv, Value, &cx->tempPool);
return pv;
} }
static JSBool static JSBool
@ -2993,10 +2984,7 @@ EmitSwitch(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
JSParseNode *pn2, *pn3, *pn4; JSParseNode *pn2, *pn3, *pn4;
uint32 caseCount, tableLength; uint32 caseCount, tableLength;
JSParseNode **table; JSParseNode **table;
jsdouble d; int32_t i, low, high;
jsint i, low, high;
jsval v;
JSAtom *atom;
JSAtomListElement *ale; JSAtomListElement *ale;
intN noteIndex; intN noteIndex;
size_t switchSize, tableSize; size_t switchSize, tableSize;
@ -3110,30 +3098,22 @@ EmitSwitch(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
pn4 = pn3->pn_left; pn4 = pn3->pn_left;
while (pn4->pn_type == TOK_RP) while (pn4->pn_type == TOK_RP)
pn4 = pn4->pn_kid; pn4 = pn4->pn_kid;
Value constVal;
switch (pn4->pn_type) { switch (pn4->pn_type) {
case TOK_NUMBER: case TOK_NUMBER:
d = pn4->pn_dval; constVal.setNumber(pn4->pn_dval);
if (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i)) {
pn3->pn_val = INT_TO_JSVAL(i);
} else {
atom = js_AtomizeDouble(cx, d);
if (!atom) {
ok = JS_FALSE;
goto release;
}
pn3->pn_val = ATOM_KEY(atom);
}
break; break;
case TOK_STRING: case TOK_STRING:
pn3->pn_val = ATOM_KEY(pn4->pn_atom); constVal.setString(ATOM_TO_STRING(pn4->pn_atom));
break; break;
case TOK_NAME: case TOK_NAME:
if (!pn4->maybeExpr()) { if (!pn4->maybeExpr()) {
ok = LookupCompileTimeConstant(cx, cg, pn4->pn_atom, &v); ok = LookupCompileTimeConstant(cx, cg, pn4->pn_atom, &constVal);
if (!ok) if (!ok)
goto release; goto release;
if (v != JSVAL_HOLE) { if (!constVal.isMagic(JS_NO_CONSTANT)) {
if (!JSVAL_IS_PRIMITIVE(v)) { if (constVal.isObject()) {
/* /*
* XXX JSOP_LOOKUPSWITCH does not support const- * XXX JSOP_LOOKUPSWITCH does not support const-
* propagated object values, see bug 407186. * propagated object values, see bug 407186.
@ -3141,7 +3121,6 @@ EmitSwitch(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
switchOp = JSOP_CONDSWITCH; switchOp = JSOP_CONDSWITCH;
continue; continue;
} }
pn3->pn_val = v;
constPropagated = JS_TRUE; constPropagated = JS_TRUE;
break; break;
} }
@ -3149,15 +3128,15 @@ EmitSwitch(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
/* FALL THROUGH */ /* FALL THROUGH */
case TOK_PRIMARY: case TOK_PRIMARY:
if (pn4->pn_op == JSOP_TRUE) { if (pn4->pn_op == JSOP_TRUE) {
pn3->pn_val = JSVAL_TRUE; constVal.setBoolean(true);
break; break;
} }
if (pn4->pn_op == JSOP_FALSE) { if (pn4->pn_op == JSOP_FALSE) {
pn3->pn_val = JSVAL_FALSE; constVal.setBoolean(false);
break; break;
} }
if (pn4->pn_op == JSOP_NULL) { if (pn4->pn_op == JSOP_NULL) {
pn3->pn_val = JSVAL_NULL; constVal.setNull();
break; break;
} }
/* FALL THROUGH */ /* FALL THROUGH */
@ -3165,16 +3144,23 @@ EmitSwitch(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
switchOp = JSOP_CONDSWITCH; switchOp = JSOP_CONDSWITCH;
continue; continue;
} }
JS_ASSERT(constVal.isPrimitive());
JS_ASSERT(JSVAL_IS_PRIMITIVE(pn3->pn_val)); pn3->pn_pval = AllocateSwitchConstant(cx);
if (!pn3->pn_pval) {
ok = JS_FALSE;
goto release;
}
*pn3->pn_pval = constVal;
if (switchOp != JSOP_TABLESWITCH) if (switchOp != JSOP_TABLESWITCH)
continue; continue;
if (!JSVAL_IS_INT(pn3->pn_val)) { if (!pn3->pn_pval->isInt32()) {
switchOp = JSOP_LOOKUPSWITCH; switchOp = JSOP_LOOKUPSWITCH;
continue; continue;
} }
i = JSVAL_TO_INT(pn3->pn_val); i = pn3->pn_pval->toInt32();
if ((jsuint)(i + (jsint)JS_BIT(15)) >= (jsuint)JS_BIT(16)) { if ((jsuint)(i + (jsint)JS_BIT(15)) >= (jsuint)JS_BIT(16)) {
switchOp = JSOP_LOOKUPSWITCH; switchOp = JSOP_LOOKUPSWITCH;
continue; continue;
@ -3237,7 +3223,7 @@ EmitSwitch(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
* switch generation and use conditional switch if it exceeds * switch generation and use conditional switch if it exceeds
* the limit. * the limit.
*/ */
if (caseCount + cg->atomList.count > JS_BIT(16)) if (caseCount + cg->constList.length() > JS_BIT(16))
switchOp = JSOP_CONDSWITCH; switchOp = JSOP_CONDSWITCH;
} }
} }
@ -3369,7 +3355,7 @@ EmitSwitch(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) { for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
if (pn3->pn_type == TOK_DEFAULT) if (pn3->pn_type == TOK_DEFAULT)
continue; continue;
i = JSVAL_TO_INT(pn3->pn_val); i = pn3->pn_pval->toInt32();
i -= low; i -= low;
JS_ASSERT((uint32)i < tableLength); JS_ASSERT((uint32)i < tableLength);
table[i] = pn3; table[i] = pn3;
@ -3512,12 +3498,9 @@ EmitSwitch(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) { for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
if (pn3->pn_type == TOK_DEFAULT) if (pn3->pn_type == TOK_DEFAULT)
continue; continue;
if (!js_AtomizePrimitiveValue(cx, pn3->pn_val, &atom)) if (!cg->constList.append(*pn3->pn_pval))
goto bad; goto bad;
ale = cg->atomList.add(cg->parser, atom); SET_INDEX(pc, cg->constList.length() - 1);
if (!ale)
goto bad;
SET_INDEX(pc, ALE_INDEX(ale));
pc += INDEX_LEN; pc += INDEX_LEN;
off = pn3->pn_offset - top; off = pn3->pn_offset - top;
@ -6306,7 +6289,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
* For operator new applied to other expressions than E4X ones, we emit * For operator new applied to other expressions than E4X ones, we emit
* JSOP_GETPROP instead of JSOP_CALLPROP, etc. This is necessary to * JSOP_GETPROP instead of JSOP_CALLPROP, etc. This is necessary to
* interpose the lambda-initialized method read barrier -- see the code * interpose the lambda-initialized method read barrier -- see the code
* in jsops.cpp for JSOP_LAMBDA followed by JSOP_{SET,INIT}PROP. * in jsinterp.cpp for JSOP_LAMBDA followed by JSOP_{SET,INIT}PROP.
* *
* Then (or in a call case that has no explicit reference-base object) * Then (or in a call case that has no explicit reference-base object)
* we emit JSOP_NULL as a placeholder local GC root to hold the |this| * we emit JSOP_NULL as a placeholder local GC root to hold the |this|
@ -7404,3 +7387,13 @@ JSCGObjectList::finish(JSObjectArray *array)
} while ((objbox = objbox->emitLink) != NULL); } while ((objbox = objbox->emitLink) != NULL);
JS_ASSERT(cursor == array->vector); JS_ASSERT(cursor == array->vector);
} }
void
JSGCConstList::finish(JSConstArray *array)
{
JS_ASSERT(array->length == list.length());
Value *src = list.begin(), *srcend = list.end();
Value *dst = array->vector;
for (; src != srcend; ++src, ++dst)
*dst = *src;
}

Просмотреть файл

@ -430,6 +430,16 @@ struct JSCGObjectList {
void finish(JSObjectArray *array); void finish(JSObjectArray *array);
}; };
class JSGCConstList {
js::Vector<js::Value> list;
public:
JSGCConstList(JSContext *cx) : list(cx) {}
bool append(js::Value v) { return list.append(v); }
size_t length() const { return list.length(); }
void finish(JSConstArray *array);
};
struct JSCodeGenerator : public JSTreeContext struct JSCodeGenerator : public JSTreeContext
{ {
JSArenaPool *codePool; /* pointer to thread code arena pool */ JSArenaPool *codePool; /* pointer to thread code arena pool */
@ -469,9 +479,11 @@ struct JSCodeGenerator : public JSTreeContext
uintN emitLevel; /* js_EmitTree recursion level */ uintN emitLevel; /* js_EmitTree recursion level */
typedef js::HashMap<JSAtom *, jsval> ConstMap; typedef js::HashMap<JSAtom *, js::Value> ConstMap;
ConstMap constMap; /* compile time constants */ ConstMap constMap; /* compile time constants */
JSGCConstList constList; /* constants to be included with the script */
JSCGObjectList objectList; /* list of emitted objects */ JSCGObjectList objectList; /* list of emitted objects */
JSCGObjectList regexpList; /* list of emitted regexp that will be JSCGObjectList regexpList; /* list of emitted regexp that will be
cloned during execution */ cloned during execution */
@ -487,7 +499,6 @@ struct JSCodeGenerator : public JSTreeContext
JSCodeGenerator(js::Parser *parser, JSCodeGenerator(js::Parser *parser,
JSArenaPool *codePool, JSArenaPool *notePool, JSArenaPool *codePool, JSArenaPool *notePool,
uintN lineno); uintN lineno);
bool init(); bool init();
/* /*

Просмотреть файл

@ -41,7 +41,6 @@
/* /*
* JS standard exception implementation. * JS standard exception implementation.
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "jstypes.h" #include "jstypes.h"
@ -63,13 +62,14 @@
#include "jsscript.h" #include "jsscript.h"
#include "jsstaticcheck.h" #include "jsstaticcheck.h"
#include "jscntxtinlines.h"
#include "jsobjinlines.h" #include "jsobjinlines.h"
using namespace js; using namespace js;
/* Forward declarations for js_ErrorClass's initializer. */ /* Forward declarations for js_ErrorClass's initializer. */
static JSBool static JSBool
Exception(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); Exception(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval);
static void static void
exn_trace(JSTracer *trc, JSObject *obj); exn_trace(JSTracer *trc, JSObject *obj);
@ -81,15 +81,15 @@ static JSBool
exn_enumerate(JSContext *cx, JSObject *obj); exn_enumerate(JSContext *cx, JSObject *obj);
static JSBool static JSBool
exn_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, exn_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
JSObject **objp); JSObject **objp);
JSClass js_ErrorClass = { Class js_ErrorClass = {
js_Error_str, js_Error_str,
JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_MARK_IS_TRACE |
JSCLASS_HAS_CACHED_PROTO(JSProto_Error), JSCLASS_HAS_CACHED_PROTO(JSProto_Error),
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, PropertyStub, PropertyStub, PropertyStub, PropertyStub,
exn_enumerate, (JSResolveOp)exn_resolve, JS_ConvertStub, exn_finalize, exn_enumerate, (JSResolveOp)exn_resolve, ConvertStub, exn_finalize,
NULL, NULL, NULL, Exception, NULL, NULL, NULL, Exception,
NULL, NULL, JS_CLASS_TRACE(exn_trace), NULL NULL, NULL, JS_CLASS_TRACE(exn_trace), NULL
}; };
@ -251,10 +251,10 @@ InitExnPrivate(JSContext *cx, JSObject *exnObject, JSString *message,
JSString *filename, uintN lineno, JSErrorReport *report) JSString *filename, uintN lineno, JSErrorReport *report)
{ {
JSSecurityCallbacks *callbacks; JSSecurityCallbacks *callbacks;
JSCheckAccessOp checkAccess; CheckAccessOp checkAccess;
JSErrorReporter older; JSErrorReporter older;
JSExceptionState *state; JSExceptionState *state;
jsval callerid, v; jsid callerid;
JSStackFrame *fp, *fpstop; JSStackFrame *fp, *fpstop;
size_t stackDepth, valueCount, size; size_t stackDepth, valueCount, size;
JSBool overflow; JSBool overflow;
@ -273,17 +273,17 @@ InitExnPrivate(JSContext *cx, JSObject *exnObject, JSString *message,
*/ */
callbacks = JS_GetSecurityCallbacks(cx); callbacks = JS_GetSecurityCallbacks(cx);
checkAccess = callbacks checkAccess = callbacks
? callbacks->checkObjectAccess ? Valueify(callbacks->checkObjectAccess)
: NULL; : NULL;
older = JS_SetErrorReporter(cx, NULL); older = JS_SetErrorReporter(cx, NULL);
state = JS_SaveExceptionState(cx); state = JS_SaveExceptionState(cx);
callerid = ATOM_KEY(cx->runtime->atomState.callerAtom); callerid = ATOM_TO_JSID(cx->runtime->atomState.callerAtom);
stackDepth = 0; stackDepth = 0;
valueCount = 0; valueCount = 0;
for (fp = js_GetTopStackFrame(cx); fp; fp = fp->down) { for (fp = js_GetTopStackFrame(cx); fp; fp = fp->down) {
if (fp->fun && fp->argv) { if (fp->fun && fp->argv) {
v = JSVAL_NULL; Value v = NullValue();
if (checkAccess && if (checkAccess &&
!checkAccess(cx, fp->callee(), callerid, JSACC_READ, &v)) { !checkAccess(cx, fp->callee(), callerid, JSACC_READ, &v)) {
break; break;
@ -446,7 +446,7 @@ exn_enumerate(JSContext *cx, JSObject *obj)
} }
static JSBool static JSBool
exn_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, exn_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
JSObject **objp) JSObject **objp)
{ {
JSExnPrivate *priv; JSExnPrivate *priv;
@ -458,8 +458,8 @@ exn_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
*objp = NULL; *objp = NULL;
priv = GetExnPrivate(cx, obj); priv = GetExnPrivate(cx, obj);
if (priv && JSVAL_IS_STRING(id)) { if (priv && JSID_IS_ATOM(id)) {
str = JSVAL_TO_STRING(id); str = JSID_TO_STRING(id);
atom = cx->runtime->atomState.messageAtom; atom = cx->runtime->atomState.messageAtom;
if (str == ATOM_TO_STRING(atom)) { if (str == ATOM_TO_STRING(atom)) {
@ -528,13 +528,13 @@ ValueToShortSource(JSContext *cx, jsval v)
/* Avoid toSource bloat and fallibility for object types. */ /* Avoid toSource bloat and fallibility for object types. */
if (JSVAL_IS_PRIMITIVE(v)) { if (JSVAL_IS_PRIMITIVE(v)) {
str = js_ValueToSource(cx, v); str = js_ValueToSource(cx, Valueify(v));
} else if (VALUE_IS_FUNCTION(cx, v)) { } else if (VALUE_IS_FUNCTION(cx, v)) {
/* /*
* XXX Avoid function decompilation bloat for now. * XXX Avoid function decompilation bloat for now.
*/ */
str = JS_GetFunctionId(JS_ValueToFunction(cx, v)); str = JS_GetFunctionId(JS_ValueToFunction(cx, v));
if (!str && !(str = js_ValueToSource(cx, v))) { if (!str && !(str = js_ValueToSource(cx, Valueify(v)))) {
/* /*
* Continue to soldier on if the function couldn't be * Continue to soldier on if the function couldn't be
* converted into a string. * converted into a string.
@ -685,7 +685,7 @@ StringToFilename(JSContext *cx, JSString *str)
} }
static JSBool static JSBool
Exception(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Exception(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
{ {
JSString *message, *filename; JSString *message, *filename;
JSStackFrame *fp; JSStackFrame *fp;
@ -698,17 +698,17 @@ Exception(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
* NewNativeClassInstance to find the class prototype, we must get the * NewNativeClassInstance to find the class prototype, we must get the
* class prototype ourselves. * class prototype ourselves.
*/ */
if (!JSVAL_TO_OBJECT(argv[-2])->getProperty(cx, if (!argv[-2].toObject().getProperty(cx,
ATOM_TO_JSID(cx->runtime->atomState ATOM_TO_JSID(cx->runtime->atomState
.classPrototypeAtom), .classPrototypeAtom),
rval)) { rval)) {
return JS_FALSE; return JS_FALSE;
} }
JSObject *errProto = JSVAL_TO_OBJECT(*rval); JSObject *errProto = &rval->toObject();
obj = NewNativeClassInstance(cx, &js_ErrorClass, errProto, errProto->getParent()); obj = NewNativeClassInstance(cx, &js_ErrorClass, errProto, errProto->getParent());
if (!obj) if (!obj)
return JS_FALSE; return JS_FALSE;
*rval = OBJECT_TO_JSVAL(obj); rval->setObject(*obj);
} }
/* /*
@ -723,7 +723,7 @@ Exception(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
message = js_ValueToString(cx, argv[0]); message = js_ValueToString(cx, argv[0]);
if (!message) if (!message)
return JS_FALSE; return JS_FALSE;
argv[0] = STRING_TO_JSVAL(message); argv[0].setString(message);
} else { } else {
message = cx->runtime->emptyString; message = cx->runtime->emptyString;
} }
@ -733,7 +733,7 @@ Exception(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
filename = js_ValueToString(cx, argv[1]); filename = js_ValueToString(cx, argv[1]);
if (!filename) if (!filename)
return JS_FALSE; return JS_FALSE;
argv[1] = STRING_TO_JSVAL(filename); argv[1].setString(filename);
fp = NULL; fp = NULL;
} else { } else {
fp = js_GetScriptedCaller(cx, NULL); fp = js_GetScriptedCaller(cx, NULL);
@ -778,7 +778,7 @@ exn_toString(JSContext *cx, uintN argc, jsval *vp)
size_t name_length, message_length, length; size_t name_length, message_length, length;
obj = JS_THIS_OBJECT(cx, vp); obj = JS_THIS_OBJECT(cx, vp);
if (!obj || !obj->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.nameAtom), &v)) if (!obj || !obj->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.nameAtom), Valueify(&v)))
return JS_FALSE; return JS_FALSE;
name = JSVAL_IS_STRING(v) ? JSVAL_TO_STRING(v) : cx->runtime->emptyString; name = JSVAL_IS_STRING(v) ? JSVAL_TO_STRING(v) : cx->runtime->emptyString;
*vp = STRING_TO_JSVAL(name); *vp = STRING_TO_JSVAL(name);
@ -832,27 +832,27 @@ exn_toSource(JSContext *cx, uintN argc, jsval *vp)
jschar *chars, *cp; jschar *chars, *cp;
obj = JS_THIS_OBJECT(cx, vp); obj = JS_THIS_OBJECT(cx, vp);
if (!obj || !obj->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.nameAtom), vp)) if (!obj || !obj->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.nameAtom), Valueify(vp)))
return false; return false;
name = js_ValueToString(cx, *vp); name = js_ValueToString(cx, Valueify(*vp));
if (!name) if (!name)
return false; return false;
*vp = STRING_TO_JSVAL(name); *vp = STRING_TO_JSVAL(name);
{ {
AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(localroots), localroots); AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(localroots), Valueify(localroots));
#ifdef __GNUC__ #ifdef __GNUC__
message = filename = NULL; message = filename = NULL;
#endif #endif
if (!JS_GetProperty(cx, obj, js_message_str, &localroots[0]) || if (!JS_GetProperty(cx, obj, js_message_str, &localroots[0]) ||
!(message = js_ValueToSource(cx, localroots[0]))) { !(message = js_ValueToSource(cx, Valueify(localroots[0])))) {
return false; return false;
} }
localroots[0] = STRING_TO_JSVAL(message); localroots[0] = STRING_TO_JSVAL(message);
if (!JS_GetProperty(cx, obj, js_fileName_str, &localroots[1]) || if (!JS_GetProperty(cx, obj, js_fileName_str, &localroots[1]) ||
!(filename = js_ValueToSource(cx, localroots[1]))) { !(filename = js_ValueToSource(cx, Valueify(localroots[1])))) {
return false; return false;
} }
localroots[1] = STRING_TO_JSVAL(filename); localroots[1] = STRING_TO_JSVAL(filename);
@ -860,11 +860,11 @@ exn_toSource(JSContext *cx, uintN argc, jsval *vp)
if (!JS_GetProperty(cx, obj, js_lineNumber_str, &localroots[2])) if (!JS_GetProperty(cx, obj, js_lineNumber_str, &localroots[2]))
return false; return false;
uint32_t lineno; uint32_t lineno;
if (!ValueToECMAUint32(cx, localroots[2], &lineno)) if (!ValueToECMAUint32(cx, Valueify(localroots[2]), &lineno))
return false; return false;
if (lineno != 0) { if (lineno != 0) {
lineno_as_str = js_ValueToString(cx, localroots[2]); lineno_as_str = js_ValueToString(cx, Valueify(localroots[2]));
if (!lineno_as_str) if (!lineno_as_str)
return false; return false;
lineno_length = lineno_as_str->length(); lineno_length = lineno_as_str->length();
@ -989,7 +989,7 @@ js_InitExceptionClasses(JSContext *cx, JSObject *obj)
return NULL; return NULL;
PodArrayZero(roots); PodArrayZero(roots);
AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(roots), roots); AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(roots), Valueify(roots));
#ifdef __GNUC__ #ifdef __GNUC__
error_proto = NULL; /* quell GCC overwarning */ error_proto = NULL; /* quell GCC overwarning */
@ -1034,7 +1034,8 @@ js_InitExceptionClasses(JSContext *cx, JSObject *obj)
} }
/* Add the name property to the prototype. */ /* Add the name property to the prototype. */
if (!JS_DefineProperty(cx, proto, js_name_str, ATOM_KEY(atom), if (!JS_DefineProperty(cx, proto, js_name_str,
STRING_TO_JSVAL(ATOM_TO_STRING(atom)),
NULL, NULL, JSPROP_ENUMERATE)) { NULL, NULL, JSPROP_ENUMERATE)) {
return NULL; return NULL;
} }
@ -1139,7 +1140,7 @@ js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp,
/* Protect the newly-created strings below from nesting GCs. */ /* Protect the newly-created strings below from nesting GCs. */
PodArrayZero(tv); PodArrayZero(tv);
AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(tv), tv); AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(tv), Valueify(tv));
/* /*
* Try to get an appropriate prototype by looking up the corresponding * Try to get an appropriate prototype by looking up the corresponding
@ -1204,7 +1205,7 @@ js_ReportUncaughtException(JSContext *cx)
return false; return false;
PodArrayZero(roots); PodArrayZero(roots);
AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(roots), roots); AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(roots), Valueify(roots));
/* /*
* Because js_ValueToString below could error and an exception object * Because js_ValueToString below could error and an exception object
@ -1223,7 +1224,7 @@ js_ReportUncaughtException(JSContext *cx)
reportp = js_ErrorFromException(cx, exn); reportp = js_ErrorFromException(cx, exn);
/* XXX L10N angels cry once again (see also jsemit.c, /L10N gaffes/) */ /* XXX L10N angels cry once again (see also jsemit.c, /L10N gaffes/) */
str = js_ValueToString(cx, exn); str = js_ValueToString(cx, Valueify(exn));
if (!str) { if (!str) {
bytes = "unknown (can't convert to string)"; bytes = "unknown (can't convert to string)";
} else { } else {
@ -1246,7 +1247,7 @@ js_ReportUncaughtException(JSContext *cx)
if (!JS_GetProperty(cx, exnObject, js_fileName_str, &roots[3])) if (!JS_GetProperty(cx, exnObject, js_fileName_str, &roots[3]))
return false; return false;
str = js_ValueToString(cx, roots[3]); str = js_ValueToString(cx, Valueify(roots[3]));
if (!str) if (!str)
return false; return false;
filename = StringToFilename(cx, str); filename = StringToFilename(cx, str);
@ -1256,7 +1257,7 @@ js_ReportUncaughtException(JSContext *cx)
if (!JS_GetProperty(cx, exnObject, js_lineNumber_str, &roots[4])) if (!JS_GetProperty(cx, exnObject, js_lineNumber_str, &roots[4]))
return false; return false;
uint32_t lineno; uint32_t lineno;
if (!ValueToECMAUint32 (cx, roots[4], &lineno)) if (!ValueToECMAUint32 (cx, Valueify(roots[4]), &lineno))
return false; return false;
reportp = &report; reportp = &report;

Просмотреть файл

@ -44,9 +44,7 @@
#ifndef jsexn_h___ #ifndef jsexn_h___
#define jsexn_h___ #define jsexn_h___
JS_BEGIN_EXTERN_C extern js::Class js_ErrorClass;
extern JSClass js_ErrorClass;
/* /*
* Initialize the exception constructor/prototype hierarchy. * Initialize the exception constructor/prototype hierarchy.
@ -92,6 +90,4 @@ extern const JSErrorFormatString *
js_GetLocalizedErrorMessage(JSContext* cx, void *userRef, const char *locale, js_GetLocalizedErrorMessage(JSContext* cx, void *userRef, const char *locale,
const uintN errorNumber); const uintN errorNumber);
JS_END_EXTERN_C
#endif /* jsexn_h___ */ #endif /* jsexn_h___ */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -46,8 +46,6 @@
#include "jspubtd.h" #include "jspubtd.h"
#include "jsobj.h" #include "jsobj.h"
JS_BEGIN_EXTERN_C
typedef struct JSLocalNameMap JSLocalNameMap; typedef struct JSLocalNameMap JSLocalNameMap;
/* /*
@ -117,7 +115,7 @@ typedef union JSLocalNames {
#define FUN_SCRIPT(fun) (FUN_INTERPRETED(fun) ? (fun)->u.i.script : NULL) #define FUN_SCRIPT(fun) (FUN_INTERPRETED(fun) ? (fun)->u.i.script : NULL)
#define FUN_NATIVE(fun) (FUN_SLOW_NATIVE(fun) ? (fun)->u.n.native : NULL) #define FUN_NATIVE(fun) (FUN_SLOW_NATIVE(fun) ? (fun)->u.n.native : NULL)
#define FUN_FAST_NATIVE(fun) (((fun)->flags & JSFUN_FAST_NATIVE) \ #define FUN_FAST_NATIVE(fun) (((fun)->flags & JSFUN_FAST_NATIVE) \
? (JSFastNative) (fun)->u.n.native \ ? (js::FastNative) (fun)->u.n.native \
: NULL) : NULL)
#define FUN_MINARGS(fun) (((fun)->flags & JSFUN_FAST_NATIVE) \ #define FUN_MINARGS(fun) (((fun)->flags & JSFUN_FAST_NATIVE) \
? 0 \ ? 0 \
@ -137,8 +135,8 @@ struct JSFunction : public JSObject
struct { struct {
uint16 extra; /* number of arg slots for local GC roots */ uint16 extra; /* number of arg slots for local GC roots */
uint16 spare; /* reserved for future use */ uint16 spare; /* reserved for future use */
JSNative native; /* native method pointer or null */ js::Native native; /* native method pointer or null */
JSClass *clasp; /* class of objects constructed js::Class *clasp; /* class of objects constructed
by this function */ by this function */
JSNativeTraceInfo *trcinfo; JSNativeTraceInfo *trcinfo;
} n; } n;
@ -164,7 +162,7 @@ struct JSFunction : public JSObject
bool optimizedClosure() const { return FUN_KIND(this) > JSFUN_INTERPRETED; } bool optimizedClosure() const { return FUN_KIND(this) > JSFUN_INTERPRETED; }
bool needsWrapper() const { return FUN_NULL_CLOSURE(this) && u.i.skipmin != 0; } bool needsWrapper() const { return FUN_NULL_CLOSURE(this) && u.i.skipmin != 0; }
bool isInterpreted() const { return FUN_INTERPRETED(this); } bool isInterpreted() const { return FUN_INTERPRETED(this); }
bool isFastNative() const { return flags & JSFUN_FAST_NATIVE; } bool isFastNative() const { return !!(flags & JSFUN_FAST_NATIVE); }
bool isHeavyweight() const { return JSFUN_HEAVYWEIGHT_TEST(flags); } bool isHeavyweight() const { return JSFUN_HEAVYWEIGHT_TEST(flags); }
unsigned minArgs() const { return FUN_MINARGS(this); } unsigned minArgs() const { return FUN_MINARGS(this); }
@ -206,9 +204,11 @@ struct JSFunction : public JSObject
} }
}; };
JS_STATIC_ASSERT(sizeof(JSFunction) % JS_GCTHING_ALIGN == 0);
/* /*
* Trace-annotated native. This expands to a JSFunctionSpec initializer (like * Trace-annotated native. This expands to a JSFunctionSpec initializer (like
* JS_FN in jsapi.h). fastcall is a JSFastNative; trcinfo is a * JS_FN in jsapi.h). fastcall is a FastNative; trcinfo is a
* JSNativeTraceInfo*. * JSNativeTraceInfo*.
*/ */
#ifdef JS_TRACER #ifdef JS_TRACER
@ -234,7 +234,7 @@ struct JSFunction : public JSObject
* Yes, this is an incompatible change, which prefigures the impending move to * Yes, this is an incompatible change, which prefigures the impending move to
* single-threaded objects and GC heaps. * single-threaded objects and GC heaps.
*/ */
extern JSClass js_ArgumentsClass; extern js::Class js_ArgumentsClass;
inline bool inline bool
JSObject::isArguments() const JSObject::isArguments() const
@ -242,13 +242,11 @@ JSObject::isArguments() const
return getClass() == &js_ArgumentsClass; return getClass() == &js_ArgumentsClass;
} }
extern JS_FRIEND_DATA(JSClass) js_CallClass; extern JS_PUBLIC_DATA(js::Class) js_CallClass;
extern JSClass js_DeclEnvClass; extern JS_PUBLIC_DATA(js::Class) js_FunctionClass;
extern js::Class js_DeclEnvClass;
extern const uint32 CALL_CLASS_FIXED_RESERVED_SLOTS; extern const uint32 CALL_CLASS_FIXED_RESERVED_SLOTS;
/* JS_FRIEND_DATA so that VALUE_IS_FUNCTION is callable from the shell. */
extern JS_FRIEND_DATA(JSClass) js_FunctionClass;
inline bool inline bool
JSObject::isFunction() const JSObject::isFunction() const
{ {
@ -265,9 +263,9 @@ JSObject::isCallable()
} }
static inline bool static inline bool
js_IsCallable(jsval v) js_IsCallable(const js::Value &v)
{ {
return !JSVAL_IS_PRIMITIVE(v) && JSVAL_TO_OBJECT(v)->isCallable(); return v.isObject() && v.toObject().isCallable();
} }
/* /*
@ -276,6 +274,18 @@ js_IsCallable(jsval v)
#define VALUE_IS_FUNCTION(cx, v) \ #define VALUE_IS_FUNCTION(cx, v) \
(!JSVAL_IS_PRIMITIVE(v) && JSVAL_TO_OBJECT(v)->isFunction()) (!JSVAL_IS_PRIMITIVE(v) && JSVAL_TO_OBJECT(v)->isFunction())
static JS_ALWAYS_INLINE bool
IsFunctionObject(const js::Value &v)
{
return v.isObject() && v.toObject().isFunction();
}
static JS_ALWAYS_INLINE bool
IsFunctionObject(const js::Value &v, JSObject **funobj)
{
return v.isObject() && (*funobj = &v.toObject())->isFunction();
}
/* /*
* Macro to access the private slot of the function object after the slot is * Macro to access the private slot of the function object after the slot is
* initialized. * initialized.
@ -318,7 +328,7 @@ extern JSObject *
js_InitArgumentsClass(JSContext *cx, JSObject *obj); js_InitArgumentsClass(JSContext *cx, JSObject *obj);
extern JSFunction * extern JSFunction *
js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN nargs, js_NewFunction(JSContext *cx, JSObject *funobj, js::Native native, uintN nargs,
uintN flags, JSObject *parent, JSAtom *atom); uintN flags, JSObject *parent, JSAtom *atom);
extern void extern void
@ -338,7 +348,6 @@ CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent)
JSObject *proto; JSObject *proto;
if (!js_GetClassPrototype(cx, parent, JSProto_Function, &proto)) if (!js_GetClassPrototype(cx, parent, JSProto_Function, &proto))
return NULL; return NULL;
JS_ASSERT(proto);
return js_CloneFunctionObject(cx, fun, parent, proto); return js_CloneFunctionObject(cx, fun, parent, proto);
} }
@ -349,7 +358,7 @@ extern JS_REQUIRES_STACK JSObject *
js_NewDebuggableFlatClosure(JSContext *cx, JSFunction *fun); js_NewDebuggableFlatClosure(JSContext *cx, JSFunction *fun);
extern JSFunction * extern JSFunction *
js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, JSNative native, js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, js::Native native,
uintN nargs, uintN flags); uintN nargs, uintN flags);
/* /*
@ -361,16 +370,16 @@ js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, JSNative native,
#define JSV2F_SEARCH_STACK 0x10000 #define JSV2F_SEARCH_STACK 0x10000
extern JSFunction * extern JSFunction *
js_ValueToFunction(JSContext *cx, jsval *vp, uintN flags); js_ValueToFunction(JSContext *cx, const js::Value *vp, uintN flags);
extern JSObject * extern JSObject *
js_ValueToFunctionObject(JSContext *cx, jsval *vp, uintN flags); js_ValueToFunctionObject(JSContext *cx, js::Value *vp, uintN flags);
extern JSObject * extern JSObject *
js_ValueToCallableObject(JSContext *cx, jsval *vp, uintN flags); js_ValueToCallableObject(JSContext *cx, js::Value *vp, uintN flags);
extern void extern void
js_ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags); js_ReportIsNotFunction(JSContext *cx, const js::Value *vp, uintN flags);
extern JSObject * extern JSObject *
js_GetCallObject(JSContext *cx, JSStackFrame *fp); js_GetCallObject(JSContext *cx, JSStackFrame *fp);
@ -382,48 +391,36 @@ extern void
js_PutCallObject(JSContext *cx, JSStackFrame *fp); js_PutCallObject(JSContext *cx, JSStackFrame *fp);
extern JSBool JS_FASTCALL extern JSBool JS_FASTCALL
js_PutCallObjectOnTrace(JSContext *cx, JSObject *scopeChain, uint32 nargs, jsval *argv, js_PutCallObjectOnTrace(JSContext *cx, JSObject *scopeChain, uint32 nargs,
uint32 nvars, jsval *slots); js::Value *argv, uint32 nvars, js::Value *slots);
extern JSFunction * extern JSFunction *
js_GetCallObjectFunction(JSObject *obj); js_GetCallObjectFunction(JSObject *obj);
extern JSBool extern JSBool
js_GetCallArg(JSContext *cx, JSObject *obj, jsid id, jsval *vp); js_GetCallArg(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
extern JSBool extern JSBool
js_GetCallVar(JSContext *cx, JSObject *obj, jsid id, jsval *vp); js_GetCallVar(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
extern JSBool extern JSBool
SetCallArg(JSContext *cx, JSObject *obj, jsid id, jsval *vp); SetCallArg(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
extern JSBool extern JSBool
SetCallVar(JSContext *cx, JSObject *obj, jsid id, jsval *vp); SetCallVar(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
/*
* js_SetCallArg and js_SetCallVar are extern fastcall copies of the setter
* functions. These versions are required in order to set call vars from traces.
* The normal versions must not be fastcall because they are stored in the
* property ops map.
*/
extern JSBool JS_FASTCALL
js_SetCallArg(JSContext *cx, JSObject *obj, jsid id, jsval v);
extern JSBool JS_FASTCALL
js_SetCallVar(JSContext *cx, JSObject *obj, jsid id, jsval v);
/* /*
* Slower version of js_GetCallVar used when call_resolve detects an attempt to * Slower version of js_GetCallVar used when call_resolve detects an attempt to
* leak an optimized closure via indirect or debugger eval. * leak an optimized closure via indirect or debugger eval.
*/ */
extern JSBool extern JSBool
js_GetCallVarChecked(JSContext *cx, JSObject *obj, jsid id, jsval *vp); js_GetCallVarChecked(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
extern JSBool extern JSBool
js_GetArgsValue(JSContext *cx, JSStackFrame *fp, jsval *vp); js_GetArgsValue(JSContext *cx, JSStackFrame *fp, js::Value *vp);
extern JSBool extern JSBool
js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id, jsval *vp); js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id, js::Value *vp);
extern JSObject * extern JSObject *
js_GetArgsObject(JSContext *cx, JSStackFrame *fp); js_GetArgsObject(JSContext *cx, JSStackFrame *fp);
@ -452,7 +449,7 @@ const uint32 JS_ARGS_LENGTH_MAX = JS_BIT(19) - 1024;
* we check first that the shift does not overflow uint32. * we check first that the shift does not overflow uint32.
*/ */
JS_STATIC_ASSERT(JS_ARGS_LENGTH_MAX <= JS_BIT(30)); JS_STATIC_ASSERT(JS_ARGS_LENGTH_MAX <= JS_BIT(30));
JS_STATIC_ASSERT(jsval((JS_ARGS_LENGTH_MAX << 1) | 1) <= JSVAL_INT_MAX); JS_STATIC_ASSERT(((JS_ARGS_LENGTH_MAX << 1) | 1) <= JSVAL_INT_MAX);
extern JSBool extern JSBool
js_XDRFunctionObject(JSXDRState *xdr, JSObject **objp); js_XDRFunctionObject(JSXDRState *xdr, JSObject **objp);
@ -495,7 +492,7 @@ js_LookupLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, uintN *indexp);
* If nameWord does not name a formal parameter, use JS_LOCAL_NAME_IS_CONST to * If nameWord does not name a formal parameter, use JS_LOCAL_NAME_IS_CONST to
* check if nameWord corresponds to the const declaration. * check if nameWord corresponds to the const declaration.
*/ */
extern JS_FRIEND_API(jsuword *) extern jsuword *
js_GetLocalNameArray(JSContext *cx, JSFunction *fun, struct JSArenaPool *pool); js_GetLocalNameArray(JSContext *cx, JSFunction *fun, struct JSArenaPool *pool);
#define JS_LOCAL_NAME_TO_ATOM(nameWord) \ #define JS_LOCAL_NAME_TO_ATOM(nameWord) \
@ -508,19 +505,16 @@ extern void
js_FreezeLocalNames(JSContext *cx, JSFunction *fun); js_FreezeLocalNames(JSContext *cx, JSFunction *fun);
extern JSBool extern JSBool
js_fun_apply(JSContext *cx, uintN argc, jsval *vp); js_fun_apply(JSContext *cx, uintN argc, js::Value *vp);
extern JSBool extern JSBool
js_fun_call(JSContext *cx, uintN argc, jsval *vp); js_fun_call(JSContext *cx, uintN argc, js::Value *vp);
JS_END_EXTERN_C
namespace js { namespace js {
extern JSString * extern JSString *
fun_toStringHelper(JSContext *cx, JSObject *obj, uintN indent); fun_toStringHelper(JSContext *cx, JSObject *obj, uintN indent);
} }
#endif /* jsfun_h___ */ #endif /* jsfun_h___ */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -54,12 +54,12 @@
#include "jsvector.h" #include "jsvector.h"
#include "jsversion.h" #include "jsversion.h"
#define JSTRACE_XML 3 #define JSTRACE_XML 2
/* /*
* One past the maximum trace kind. * One past the maximum trace kind.
*/ */
#define JSTRACE_LIMIT 4 #define JSTRACE_LIMIT 3
const uintN JS_EXTERNAL_STRING_LIMIT = 8; const uintN JS_EXTERNAL_STRING_LIMIT = 8;
@ -102,7 +102,7 @@ js_ChangeExternalStringFinalizer(JSStringFinalizeOp oldop,
JSStringFinalizeOp newop); JSStringFinalizeOp newop);
extern JSBool extern JSBool
js_AddRoot(JSContext *cx, jsval *vp, const char *name); js_AddRoot(JSContext *cx, js::Value *vp, const char *name);
extern JSBool extern JSBool
js_AddGCThingRoot(JSContext *cx, void **rp, const char *name); js_AddGCThingRoot(JSContext *cx, void **rp, const char *name);
@ -110,7 +110,7 @@ js_AddGCThingRoot(JSContext *cx, void **rp, const char *name);
#ifdef DEBUG #ifdef DEBUG
extern void extern void
js_DumpNamedRoots(JSRuntime *rt, js_DumpNamedRoots(JSRuntime *rt,
void (*dump)(const char *name, void *rp, void *data), void (*dump)(const char *name, void *rp, JSGCRootType type, void *data),
void *data); void *data);
#endif #endif
@ -126,20 +126,6 @@ typedef struct JSPtrTable {
extern JSBool extern JSBool
js_RegisterCloseableIterator(JSContext *cx, JSObject *obj); js_RegisterCloseableIterator(JSContext *cx, JSObject *obj);
/*
* Allocate a new double jsval and store the result in *vp. vp must be a root.
* The function does not copy the result into any weak root.
*/
extern JSBool
js_NewDoubleInRootedValue(JSContext *cx, jsdouble d, jsval *vp);
/*
* Return a pointer to a new GC-allocated and weakly-rooted jsdouble number,
* or null when the allocation fails.
*/
extern jsdouble *
js_NewWeaklyRootedDouble(JSContext *cx, jsdouble d);
#ifdef JS_TRACER #ifdef JS_TRACER
extern JSBool extern JSBool
js_ReserveObjects(JSContext *cx, size_t nobjects); js_ReserveObjects(JSContext *cx, size_t nobjects);
@ -166,14 +152,6 @@ js_IsAboutToBeFinalized(void *thing);
# define JS_IS_VALID_TRACE_KIND(kind) ((uint32)(kind) <= JSTRACE_STRING) # define JS_IS_VALID_TRACE_KIND(kind) ((uint32)(kind) <= JSTRACE_STRING)
#endif #endif
/*
* Trace jsval when JSVAL_IS_OBJECT(v) can be a GC thing pointer tagged as a
* jsval. NB: punning an arbitrary JSString * as an untagged (object-tagged)
* jsval no longer works due to static int and unit strings!
*/
extern void
js_CallValueTracerIfGCThing(JSTracer *trc, jsval v);
extern void extern void
js_TraceStackFrame(JSTracer *trc, JSStackFrame *fp); js_TraceStackFrame(JSTracer *trc, JSStackFrame *fp);
@ -231,9 +209,6 @@ js_WaitForGC(JSRuntime *rt);
#endif #endif
extern void
js_CallGCMarker(JSTracer *trc, void *thing, uint32 kind);
/* /*
* The kind of GC thing with a finalizer. The external strings follow the * The kind of GC thing with a finalizer. The external strings follow the
* ordinary string to simplify js_GetExternalStringGCType. * ordinary string to simplify js_GetExternalStringGCType.
@ -318,13 +293,7 @@ struct JSGCArenaList {
*/ */
}; };
struct JSGCDoubleArenaList {
JSGCArena *head; /* list start */
JSGCArena *cursor; /* next arena with free cells */
};
struct JSGCFreeLists { struct JSGCFreeLists {
JSGCThing *doubles;
JSGCThing *finalizables[FINALIZE_LIMIT]; JSGCThing *finalizables[FINALIZE_LIMIT];
void purge(); void purge();
@ -332,8 +301,6 @@ struct JSGCFreeLists {
#ifdef DEBUG #ifdef DEBUG
bool isEmpty() const { bool isEmpty() const {
if (doubles)
return false;
for (size_t i = 0; i != JS_ARRAY_LENGTH(finalizables); ++i) { for (size_t i = 0; i != JS_ARRAY_LENGTH(finalizables); ++i) {
if (finalizables[i]) if (finalizables[i])
return false; return false;
@ -349,13 +316,12 @@ js_DestroyScriptsToGC(JSContext *cx, JSThreadData *data);
struct JSWeakRoots { struct JSWeakRoots {
/* Most recently created things by type, members of the GC's root set. */ /* Most recently created things by type, members of the GC's root set. */
void *finalizableNewborns[FINALIZE_LIMIT]; void *finalizableNewborns[FINALIZE_LIMIT];
jsdouble *newbornDouble;
/* Atom root for the last-looked-up atom on this context. */ /* Atom root for the last-looked-up atom on this context. */
jsval lastAtom; JSAtom *lastAtom;
/* Root for the result of the most recent js_InternalInvoke call. */ /* Root for the result of the most recent js_InternalInvoke call. */
jsval lastInternalResult; void *lastInternalResult;
void mark(JSTracer *trc); void mark(JSTracer *trc);
}; };
@ -448,15 +414,13 @@ const bool JS_WANT_GC_METER_PRINT = false;
struct JSConservativeGCStats { struct JSConservativeGCStats {
uint32 words; /* number of words on native stacks */ uint32 words; /* number of words on native stacks */
uint32 oddaddress; /* excluded because low bit was set */ uint32 lowbitset; /* excluded because one of the low bits was set */
uint32 special; /* excluded because a special value */
uint32 notarena; /* not within arena range in a chunk */ uint32 notarena; /* not within arena range in a chunk */
uint32 notchunk; /* not within a valid chunk */ uint32 notchunk; /* not within a valid chunk */
uint32 freearena; /* not within non-free arena */ uint32 freearena; /* not within non-free arena */
uint32 wrongtag; /* tagged pointer but wrong type */ uint32 wrongtag; /* tagged pointer but wrong type */
uint32 notlive; /* gcthing is not allocated */ uint32 notlive; /* gcthing is not allocated */
uint32 gcthings; /* number of live gcthings */ uint32 gcthings; /* number of live gcthings */
uint32 raw; /* number of raw pointers marked */
uint32 unmarked; /* number of unmarked gc things discovered on the uint32 unmarked; /* number of unmarked gc things discovered on the
stack */ stack */
}; };
@ -499,7 +463,7 @@ struct JSGCStats {
uint32 poke; /* number of potentially useful GC calls */ uint32 poke; /* number of potentially useful GC calls */
uint32 afree; /* thing arenas freed so far */ uint32 afree; /* thing arenas freed so far */
uint32 stackseg; /* total extraordinary stack segments scanned */ uint32 stackseg; /* total extraordinary stack segments scanned */
uint32 segslots; /* total stack segment jsval slots scanned */ uint32 segslots; /* total stack segment value slots scanned */
uint32 nclose; /* number of objects with close hooks */ uint32 nclose; /* number of objects with close hooks */
uint32 maxnclose; /* max number of objects with close hooks */ uint32 maxnclose; /* max number of objects with close hooks */
uint32 closelater; /* number of close hooks scheduled to run */ uint32 closelater; /* number of close hooks scheduled to run */
@ -510,7 +474,6 @@ struct JSGCStats {
uint32 maxnchunks; /* maximum number of allocated chunks */ uint32 maxnchunks; /* maximum number of allocated chunks */
JSGCArenaStats arenaStats[FINALIZE_LIMIT]; JSGCArenaStats arenaStats[FINALIZE_LIMIT];
JSGCArenaStats doubleArenaStats;
JSConservativeGCStats conservative; JSConservativeGCStats conservative;
}; };
@ -539,25 +502,133 @@ namespace js {
extern bool extern bool
SetProtoCheckingForCycles(JSContext *cx, JSObject *obj, JSObject *proto); SetProtoCheckingForCycles(JSContext *cx, JSObject *obj, JSObject *proto);
/* N.B. Assumes JS_SET_TRACING_NAME/INDEX has already been called. */
void void
TraceObjectVector(JSTracer *trc, JSObject **vec, uint32 len); Mark(JSTracer *trc, void *thing, uint32 kind);
inline void static inline void
TraceValues(JSTracer *trc, jsval *beg, jsval *end, const char *name) Mark(JSTracer *trc, void *thing, uint32 kind, const char *name)
{ {
for (jsval *vp = beg; vp < end; ++vp) { JS_ASSERT(thing);
jsval v = *vp; JS_SET_TRACING_NAME(trc, name);
if (JSVAL_IS_TRACEABLE(v)) { Mark(trc, thing, kind);
}
static inline void
MarkString(JSTracer *trc, JSString *str, const char *name)
{
JS_ASSERT(str);
JS_SET_TRACING_NAME(trc, name);
Mark(trc, str, JSTRACE_STRING);
}
static inline void
MarkAtomRange(JSTracer *trc, size_t len, JSAtom **vec, const char *name)
{
for (uint32 i = 0; i < len; i++) {
if (JSAtom *atom = vec[i]) {
JS_SET_TRACING_INDEX(trc, name, i);
Mark(trc, ATOM_TO_STRING(atom), JSTRACE_STRING);
}
}
}
static inline void
MarkObject(JSTracer *trc, JSObject *obj, const char *name)
{
JS_ASSERT(obj);
JS_SET_TRACING_NAME(trc, name);
Mark(trc, obj, JSTRACE_OBJECT);
}
static inline void
MarkObjectRange(JSTracer *trc, size_t len, JSObject **vec, const char *name)
{
for (uint32 i = 0; i < len; i++) {
if (JSObject *obj = vec[i]) {
JS_SET_TRACING_INDEX(trc, name, i);
Mark(trc, obj, JSTRACE_OBJECT);
}
}
}
/* N.B. Assumes JS_SET_TRACING_NAME/INDEX has already been called. */
static inline void
MarkValueRaw(JSTracer *trc, const js::Value &v)
{
if (v.isMarkable())
return Mark(trc, v.asGCThing(), v.gcKind());
}
static inline void
MarkValue(JSTracer *trc, const js::Value &v, const char *name)
{
JS_SET_TRACING_NAME(trc, name);
MarkValueRaw(trc, v);
}
static inline void
MarkValueRange(JSTracer *trc, Value *beg, Value *end, const char *name)
{
for (Value *vp = beg; vp < end; ++vp) {
JS_SET_TRACING_INDEX(trc, name, vp - beg); JS_SET_TRACING_INDEX(trc, name, vp - beg);
js_CallGCMarker(trc, JSVAL_TO_TRACEABLE(v), JSVAL_TRACE_KIND(v)); MarkValueRaw(trc, *vp);
}
} }
} }
inline void static inline void
TraceValues(JSTracer *trc, size_t len, jsval *vec, const char *name) MarkValueRange(JSTracer *trc, size_t len, Value *vec, const char *name)
{ {
TraceValues(trc, vec, vec + len, name); MarkValueRange(trc, vec, vec + len, name);
}
static inline void
MarkId(JSTracer *trc, jsid id)
{
if (JSID_IS_STRING(id))
Mark(trc, JSID_TO_STRING(id), JSTRACE_STRING);
else if (JS_UNLIKELY(JSID_IS_OBJECT(id)))
Mark(trc, JSID_TO_OBJECT(id), JSTRACE_OBJECT);
}
static inline void
MarkId(JSTracer *trc, jsid id, const char *name)
{
JS_SET_TRACING_NAME(trc, name);
MarkId(trc, id);
}
static inline void
MarkIdRange(JSTracer *trc, jsid *beg, jsid *end, const char *name)
{
for (jsid *idp = beg; idp != end; ++idp) {
JS_SET_TRACING_INDEX(trc, name, (idp - beg));
MarkId(trc, *idp);
}
}
static inline void
MarkIdRange(JSTracer *trc, size_t len, jsid *vec, const char *name)
{
MarkIdRange(trc, vec, vec + len, name);
}
/* N.B. Assumes JS_SET_TRACING_NAME/INDEX has already been called. */
void
MarkGCThing(JSTracer *trc, void *thing);
static inline void
MarkGCThing(JSTracer *trc, void *thing, const char *name)
{
JS_SET_TRACING_NAME(trc, name);
MarkGCThing(trc, thing);
}
static inline void
MarkGCThing(JSTracer *trc, void *thing, const char *name, size_t index)
{
JS_SET_TRACING_INDEX(trc, name, index);
MarkGCThing(trc, thing);
} }
JSCompartment * JSCompartment *

Просмотреть файл

@ -40,8 +40,8 @@
#ifndef jsgchunk_h__ #ifndef jsgchunk_h__
#define jsgchunk_h__ #define jsgchunk_h__
#include "jsapi.h"
#include "jsprvtd.h" #include "jsprvtd.h"
#include "jspubtd.h"
#include "jsutil.h" #include "jsutil.h"
namespace js { namespace js {
@ -55,6 +55,10 @@ const size_t GC_CHUNK_SHIFT = 20;
const size_t GC_CHUNK_SIZE = size_t(1) << GC_CHUNK_SHIFT; const size_t GC_CHUNK_SIZE = size_t(1) << GC_CHUNK_SHIFT;
const size_t GC_CHUNK_MASK = GC_CHUNK_SIZE - 1; const size_t GC_CHUNK_MASK = GC_CHUNK_SIZE - 1;
#if defined(XP_WIN) && defined(_M_X64)
bool InitNtAllocAPIs();
#endif
JS_FRIEND_API(void *) JS_FRIEND_API(void *)
AllocGCChunk(); AllocGCChunk();

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -48,12 +48,11 @@
#include "jsfun.h" #include "jsfun.h"
#include "jsopcode.h" #include "jsopcode.h"
#include "jsscript.h" #include "jsscript.h"
#include "jsvalue.h"
JS_BEGIN_EXTERN_C
typedef struct JSFrameRegs { typedef struct JSFrameRegs {
jsbytecode *pc; /* program counter */ jsbytecode *pc; /* program counter */
jsval *sp; /* stack pointer */ js::Value *sp; /* stack pointer */
} JSFrameRegs; } JSFrameRegs;
/* JS stack frame flags. */ /* JS stack frame flags. */
@ -85,14 +84,13 @@ struct JSStackFrame
{ {
jsbytecode *imacpc; /* null or interpreter macro call pc */ jsbytecode *imacpc; /* null or interpreter macro call pc */
JSObject *callobj; /* lazily created Call object */ JSObject *callobj; /* lazily created Call object */
jsval argsobj; /* lazily created arguments object, must be JSObject *argsobj; /* lazily created arguments object */
JSVAL_OBJECT */
JSScript *script; /* script being interpreted */ JSScript *script; /* script being interpreted */
JSFunction *fun; /* function being called or null */ JSFunction *fun; /* function being called or null */
jsval thisv; /* "this" pointer if in method */ js::Value thisv; /* "this" pointer if in method */
uintN argc; /* actual argument count */ uintN argc; /* actual argument count */
jsval *argv; /* base of argument stack slots */ js::Value *argv; /* base of argument stack slots */
jsval rval; /* function return value */ js::Value rval; /* function return value */
void *annotation; /* used by Java security */ void *annotation; /* used by Java security */
/* Maintained by StackSpace operations */ /* Maintained by StackSpace operations */
@ -139,10 +137,7 @@ struct JSStackFrame
* also used in some other cases --- entering 'with' blocks, for * also used in some other cases --- entering 'with' blocks, for
* example. * example.
*/ */
union {
JSObject *scopeChain; JSObject *scopeChain;
jsval scopeChainVal;
};
JSObject *blockChain; JSObject *blockChain;
uint32 flags; /* frame flags -- see below */ uint32 flags; /* frame flags -- see below */
@ -169,26 +164,25 @@ struct JSStackFrame
/* Get the frame's current bytecode, assuming |this| is in |cx|. */ /* Get the frame's current bytecode, assuming |this| is in |cx|. */
jsbytecode *pc(JSContext *cx) const; jsbytecode *pc(JSContext *cx) const;
jsval *argEnd() const { js::Value *argEnd() const {
return (jsval *)this; return (js::Value *)this;
} }
jsval *slots() const { js::Value *slots() const {
return (jsval *)(this + 1); return (js::Value *)(this + 1);
} }
jsval calleeValue() { js::Value *base() const {
return slots() + script->nfixed;
}
const js::Value &calleeValue() {
JS_ASSERT(argv); JS_ASSERT(argv);
return argv[-2]; return argv[-2];
} }
JSObject *calleeObject() {
JS_ASSERT(argv);
return JSVAL_TO_OBJECT(argv[-2]);
}
JSObject *callee() { JSObject *callee() {
return argv ? JSVAL_TO_OBJECT(argv[-2]) : NULL; return argv ? &argv[-2].toObject() : NULL;
} }
/* /*
@ -203,13 +197,10 @@ struct JSStackFrame
inline JSObject *getThisObject(JSContext *cx); inline JSObject *getThisObject(JSContext *cx);
bool isGenerator() const { return flags & JSFRAME_GENERATOR; } bool isGenerator() const { return !!(flags & JSFRAME_GENERATOR); }
bool isFloatingGenerator() const { bool isFloatingGenerator() const {
if (flags & JSFRAME_FLOATING_GENERATOR) { JS_ASSERT_IF(flags & JSFRAME_FLOATING_GENERATOR, isGenerator());
JS_ASSERT(isGenerator()); return !!(flags & JSFRAME_FLOATING_GENERATOR);
return true;
}
return false;
} }
bool isDummyFrame() const { return !script && !fun; } bool isDummyFrame() const { return !script && !fun; }
@ -217,16 +208,13 @@ struct JSStackFrame
namespace js { namespace js {
static const size_t VALUES_PER_STACK_FRAME = sizeof(JSStackFrame) / sizeof(jsval); JS_STATIC_ASSERT(sizeof(JSStackFrame) % sizeof(Value) == 0);
JS_STATIC_ASSERT(sizeof(JSStackFrame) % sizeof(jsval) == 0); static const size_t VALUES_PER_STACK_FRAME = sizeof(JSStackFrame) / sizeof(Value);
} JS_STATIC_ASSERT(offsetof(JSStackFrame, rval) % sizeof(Value) == 0);
JS_STATIC_ASSERT(offsetof(JSStackFrame, thisv) % sizeof(Value) == 0);
static JS_INLINE jsval * } /* namespace js */
StackBase(JSStackFrame *fp)
{
return fp->slots() + fp->script->nfixed;
}
static JS_INLINE uintN static JS_INLINE uintN
GlobalVarCount(JSStackFrame *fp) GlobalVarCount(JSStackFrame *fp)
@ -252,10 +240,13 @@ js_GetScopeChain(JSContext *cx, JSStackFrame *fp);
* instance of clasp and extract its private slot value to return via *thisvp. * instance of clasp and extract its private slot value to return via *thisvp.
* *
* NB: this function loads and uses *vp before storing *thisvp, so the two may * NB: this function loads and uses *vp before storing *thisvp, so the two may
* alias the same jsval. * alias the same Value.
*/ */
extern JSBool extern JSBool
js_GetPrimitiveThis(JSContext *cx, jsval *vp, JSClass *clasp, jsval *thisvp); js_GetPrimitiveThis(JSContext *cx, js::Value *vp, js::Class *clasp,
const js::Value **vpp);
namespace js {
/* /*
* For a call with arguments argv including argv[-1] (nominal |this|) and * For a call with arguments argv including argv[-1] (nominal |this|) and
@ -265,14 +256,22 @@ js_GetPrimitiveThis(JSContext *cx, jsval *vp, JSClass *clasp, jsval *thisvp);
* must not be a JSVAL_VOID. * must not be a JSVAL_VOID.
*/ */
extern JSObject * extern JSObject *
js_ComputeThis(JSContext *cx, jsval *argv); ComputeThisFromArgv(JSContext *cx, js::Value *argv);
extern const uint16 js_PrimitiveTestFlags[]; JS_ALWAYS_INLINE JSObject *
ComputeThisFromVp(JSContext *cx, js::Value *vp)
{
return ComputeThisFromArgv(cx, vp + 2);
}
#define PRIMITIVE_THIS_TEST(fun,thisv) \ JS_ALWAYS_INLINE bool
(JS_ASSERT(!JSVAL_IS_VOID(thisv)), \ PrimitiveThisTest(JSFunction *fun, const Value &v)
JSFUN_THISP_TEST(JSFUN_THISP_FLAGS((fun)->flags), \ {
js_PrimitiveTestFlags[JSVAL_TAG(thisv) - 1])) uint16 flags = fun->flags;
return (v.isString() && !!(flags & JSFUN_THISP_STRING)) ||
(v.isNumber() && !!(flags & JSFUN_THISP_NUMBER)) ||
(v.isBoolean() && !!(flags & JSFUN_THISP_BOOLEAN));
}
/* /*
* The js::InvokeArgumentsGuard passed to js_Invoke must come from an * The js::InvokeArgumentsGuard passed to js_Invoke must come from an
@ -282,8 +281,11 @@ extern const uint16 js_PrimitiveTestFlags[];
* and the range [args.getvp() + 2, args.getvp() + 2 + args.getArgc()) should * and the range [args.getvp() + 2, args.getvp() + 2 + args.getArgc()) should
* be initialized actual arguments. * be initialized actual arguments.
*/ */
extern JS_REQUIRES_STACK JS_FRIEND_API(JSBool) extern JS_REQUIRES_STACK bool
js_Invoke(JSContext *cx, const js::InvokeArgsGuard &args, uintN flags); Invoke(JSContext *cx, const InvokeArgsGuard &args, uintN flags);
extern JS_REQUIRES_STACK JS_FRIEND_API(bool)
InvokeFriendAPI(JSContext *cx, const InvokeArgsGuard &args, uintN flags);
/* /*
* Consolidated js_Invoke flags simply rename certain JSFRAME_* flags, so that * Consolidated js_Invoke flags simply rename certain JSFRAME_* flags, so that
@ -309,51 +311,81 @@ js_Invoke(JSContext *cx, const js::InvokeArgsGuard &args, uintN flags);
* "Internal" calls may come from C or C++ code using a JSContext on which no * "Internal" calls may come from C or C++ code using a JSContext on which no
* JS is running (!cx->fp), so they may need to push a dummy JSStackFrame. * JS is running (!cx->fp), so they may need to push a dummy JSStackFrame.
*/ */
#define js_InternalCall(cx,obj,fval,argc,argv,rval) \
js_InternalInvoke(cx, OBJECT_TO_JSVAL(obj), fval, 0, argc, argv, rval)
#define js_InternalConstruct(cx,obj,fval,argc,argv,rval) \
js_InternalInvoke(cx, OBJECT_TO_JSVAL(obj), fval, JSINVOKE_CONSTRUCT, argc, argv, rval)
extern JSBool extern JSBool
js_InternalInvoke(JSContext *cx, jsval thisv, jsval fval, uintN flags, InternalInvoke(JSContext *cx, const Value &thisv, const Value &fval, uintN flags,
uintN argc, jsval *argv, jsval *rval); uintN argc, Value *argv, Value *rval);
extern JSBool static JS_ALWAYS_INLINE bool
js_InternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, jsval fval, InternalCall(JSContext *cx, JSObject *obj, const Value &fval,
JSAccessMode mode, uintN argc, jsval *argv, jsval *rval); uintN argc, Value *argv, Value *rval)
{
return InternalInvoke(cx, ObjectOrNullValue(obj), fval, 0, argc, argv, rval);
}
extern JS_FORCES_STACK JSBool static JS_ALWAYS_INLINE bool
js_Execute(JSContext *cx, JSObject *chain, JSScript *script, InternalConstruct(JSContext *cx, JSObject *obj, const Value &fval,
JSStackFrame *down, uintN flags, jsval *result); uintN argc, Value *argv, Value *rval)
{
return InternalInvoke(cx, ObjectOrNullValue(obj), fval, JSINVOKE_CONSTRUCT, argc, argv, rval);
}
extern JS_REQUIRES_STACK JSBool extern bool
js_InvokeConstructor(JSContext *cx, const js::InvokeArgsGuard &args); InternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, const Value &fval,
JSAccessMode mode, uintN argc, Value *argv, Value *rval);
extern JS_REQUIRES_STACK JSBool extern JS_FORCES_STACK bool
js_Interpret(JSContext *cx); Execute(JSContext *cx, JSObject *chain, JSScript *script,
JSStackFrame *down, uintN flags, Value *result);
extern JS_REQUIRES_STACK bool
InvokeConstructor(JSContext *cx, const InvokeArgsGuard &args);
extern JS_REQUIRES_STACK bool
Interpret(JSContext *cx);
#define JSPROP_INITIALIZER 0x100 /* NB: Not a valid property attribute. */ #define JSPROP_INITIALIZER 0x100 /* NB: Not a valid property attribute. */
extern JSBool extern bool
js_CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs, CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs,
JSObject **objp, JSProperty **propp); JSObject **objp, JSProperty **propp);
extern JSBool extern bool
js_StrictlyEqual(JSContext *cx, jsval lval, jsval rval); StrictlyEqual(JSContext *cx, const Value &lval, const Value &rval);
/* === except that NaN is the same as NaN and -0 is not the same as +0. */ /* === except that NaN is the same as NaN and -0 is not the same as +0. */
extern JSBool extern bool
js_SameValue(jsval v1, jsval v2, JSContext *cx); SameValue(const Value &v1, const Value &v2, JSContext *cx);
extern JSBool extern JSType
js_InternNonIntElementId(JSContext *cx, JSObject *obj, jsval idval, jsid *idp); TypeOfValue(JSContext *cx, const Value &v);
inline bool
InstanceOf(JSContext *cx, JSObject *obj, Class *clasp, Value *argv)
{
if (obj && obj->getClass() == clasp)
return true;
extern bool InstanceOfSlow(JSContext *, JSObject *, Class *, Value *);
return InstanceOfSlow(cx, obj, clasp, argv);
}
inline void *
GetInstancePrivate(JSContext *cx, JSObject *obj, Class *clasp, Value *argv)
{
if (!InstanceOf(cx, obj, clasp, argv))
return NULL;
return obj->getPrivate();
}
extern bool
ValueToId(JSContext *cx, const Value &v, jsid *idp);
} /* namespace js */
/* /*
* Given an active context, a static scope level, and an upvar cookie, return * Given an active context, a static scope level, and an upvar cookie, return
* the value of the upvar. * the value of the upvar.
*/ */
extern jsval & extern const js::Value &
js_GetUpvar(JSContext *cx, uintN level, js::UpvarCookie cookie); js_GetUpvar(JSContext *cx, uintN level, js::UpvarCookie cookie);
/* /*
@ -382,31 +414,13 @@ js_GetUpvar(JSContext *cx, uintN level, js::UpvarCookie cookie);
#else #else
# define JS_STATIC_INTERPRET # define JS_STATIC_INTERPRET
/*
* ECMA requires "the global object", but in embeddings such as the browser,
* which have multiple top-level objects (windows, frames, etc. in the DOM),
* we prefer fun's parent. An example that causes this code to run:
*
* // in window w1
* function f() { return this }
* function g() { return f }
*
* // in window w2
* var h = w1.g()
* alert(h() == w1)
*
* The alert should display "true".
*/
extern JSObject *
js_ComputeGlobalThis(JSContext *cx, jsval *argv);
extern JS_REQUIRES_STACK JSBool extern JS_REQUIRES_STACK JSBool
js_EnterWith(JSContext *cx, jsint stackIndex); js_EnterWith(JSContext *cx, jsint stackIndex);
extern JS_REQUIRES_STACK void extern JS_REQUIRES_STACK void
js_LeaveWith(JSContext *cx); js_LeaveWith(JSContext *cx);
extern JS_REQUIRES_STACK JSClass * extern JS_REQUIRES_STACK js::Class *
js_IsActiveWithOrBlock(JSContext *cx, JSObject *obj, int stackDepth); js_IsActiveWithOrBlock(JSContext *cx, JSObject *obj, int stackDepth);
/* /*
@ -417,7 +431,7 @@ extern JS_REQUIRES_STACK JSBool
js_UnwindScope(JSContext *cx, jsint stackDepth, JSBool normalUnwind); js_UnwindScope(JSContext *cx, jsint stackDepth, JSBool normalUnwind);
extern JSBool extern JSBool
js_OnUnknownMethod(JSContext *cx, jsval *vp); js_OnUnknownMethod(JSContext *cx, js::Value *vp);
/* /*
* Find the results of incrementing or decrementing *vp. For pre-increments, * Find the results of incrementing or decrementing *vp. For pre-increments,
@ -426,7 +440,7 @@ js_OnUnknownMethod(JSContext *cx, jsval *vp);
* the result. Both vp and vp2 must be roots. * the result. Both vp and vp2 must be roots.
*/ */
extern JSBool extern JSBool
js_DoIncDec(JSContext *cx, const JSCodeSpec *cs, jsval *vp, jsval *vp2); js_DoIncDec(JSContext *cx, const JSCodeSpec *cs, js::Value *vp, js::Value *vp2);
/* /*
* Opcode tracing helper. When len is not 0, cx->fp->regs->pc[-len] gives the * Opcode tracing helper. When len is not 0, cx->fp->regs->pc[-len] gives the
@ -446,19 +460,16 @@ js_MeterSlotOpcode(JSOp op, uint32 slot);
#endif /* JS_LONE_INTERPRET */ #endif /* JS_LONE_INTERPRET */
JS_END_EXTERN_C
inline JSObject * inline JSObject *
JSStackFrame::getThisObject(JSContext *cx) JSStackFrame::getThisObject(JSContext *cx)
{ {
if (flags & JSFRAME_COMPUTED_THIS) if (flags & JSFRAME_COMPUTED_THIS)
return JSVAL_TO_OBJECT(thisv); /* JSVAL_COMPUTED_THIS invariant */ return &thisv.toObject();
JSObject* obj = js_ComputeThis(cx, argv); if (!js::ComputeThisFromArgv(cx, argv))
if (!obj)
return NULL; return NULL;
thisv = OBJECT_TO_JSVAL(obj); thisv = argv[-1];
flags |= JSFRAME_COMPUTED_THIS; flags |= JSFRAME_COMPUTED_THIS;
return obj; return &thisv.toObject();
} }
#endif /* jsinterp_h___ */ #endif /* jsinterp_h___ */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -47,8 +47,6 @@
#include "jspubtd.h" #include "jspubtd.h"
#include "jsversion.h" #include "jsversion.h"
JS_BEGIN_EXTERN_C
/* /*
* NB: these flag bits are encoded into the bytecode stream in the immediate * NB: these flag bits are encoded into the bytecode stream in the immediate
* operand of JSOP_ITER, so don't change them without advancing jsxdrapi.h's * operand of JSOP_ITER, so don't change them without advancing jsxdrapi.h's
@ -62,48 +60,95 @@ JS_BEGIN_EXTERN_C
struct NativeIterator { struct NativeIterator {
JSObject *obj; JSObject *obj;
jsval *props_array; void *props_array;
jsval *props_cursor; void *props_cursor;
jsval *props_end; void *props_end;
uint32 *shapes_array; uint32 *shapes_array;
uint32 shapes_length; uint32 shapes_length;
uint32 shapes_key; uint32 shapes_key;
uintN flags; uintN flags;
JSObject *next; JSObject *next;
static NativeIterator *allocate(JSContext *cx, JSObject *obj, uintN flags, bool isKeyIter() const { return (flags & JSITER_FOREACH) == 0; }
uint32 *sarray, uint32 slength, uint32 key,
js::AutoValueVector &props);
inline size_t length() const { inline jsid *beginKey() const {
return props_end - props_array; JS_ASSERT(isKeyIter());
return (jsid *)props_array;
} }
inline jsval *begin() const { inline jsid *endKey() const {
return props_array; JS_ASSERT(isKeyIter());
return (jsid *)props_end;
} }
size_t numKeys() const {
return endKey() - beginKey();
}
jsid *currentKey() const {
JS_ASSERT(isKeyIter());
return reinterpret_cast<jsid *>(props_cursor);
}
void incKeyCursor() {
JS_ASSERT(isKeyIter());
props_cursor = reinterpret_cast<jsid *>(props_cursor) + 1;
}
inline js::Value *beginValue() const {
JS_ASSERT(!isKeyIter());
return (js::Value *)props_array;
}
inline js::Value *endValue() const {
JS_ASSERT(!isKeyIter());
return (js::Value *)props_end;
}
size_t numValues() const {
return endValue() - beginValue();
}
js::Value *currentValue() const {
JS_ASSERT(!isKeyIter());
return reinterpret_cast<js::Value *>(props_cursor);
}
void incValueCursor() {
JS_ASSERT(!isKeyIter());
props_cursor = reinterpret_cast<js::Value *>(props_cursor) + 1;
}
static NativeIterator *allocateKeyIterator(JSContext *cx, uint32 slength,
const js::AutoIdVector &props);
static NativeIterator *allocateValueIterator(JSContext *cx, uint32 slength,
const js::AutoValueVector &props);
void init(JSObject *obj, uintN flags, const uint32 *sarray, uint32 slength, uint32 key);
void mark(JSTracer *trc); void mark(JSTracer *trc);
}; };
bool
VectorToIdArray(JSContext *cx, js::AutoIdVector &props, JSIdArray **idap);
bool
GetPropertyNames(JSContext *cx, JSObject *obj, uintN flags, js::AutoIdVector &props);
bool
GetIterator(JSContext *cx, JSObject *obj, uintN flags, js::Value *vp);
bool
VectorToKeyIterator(JSContext *cx, JSObject *obj, uintN flags, js::AutoIdVector &props, js::Value *vp);
bool
VectorToValueIterator(JSContext *cx, JSObject *obj, uintN flags, js::AutoValueVector &props, js::Value *vp);
/* /*
* Magic jsval that indicates that a custom enumerate hook forwarded * Creates either a key or value iterator, depending on flags. For a value
* to js_Enumerate, which really means the object can be enumerated like * iterator, performs value-lookup to convert the given list of jsids.
* a native object.
*/ */
static const jsval JSVAL_NATIVE_ENUMERATE_COOKIE = SPECIAL_TO_JSVAL(0x220576);
bool bool
VectorToIdArray(JSContext *cx, js::AutoValueVector &props, JSIdArray **idap); EnumeratedIdVectorToIterator(JSContext *cx, JSObject *obj, uintN flags, js::AutoIdVector &props, js::Value *vp);
bool
GetPropertyNames(JSContext *cx, JSObject *obj, uintN flags, js::AutoValueVector &props);
bool
GetIterator(JSContext *cx, JSObject *obj, uintN flags, jsval *vp);
bool
IdVectorToIterator(JSContext *cx, JSObject *obj, uintN flags, js::AutoValueVector &props, jsval *vp);
/* /*
* Convert the value stored in *vp to its iteration object. The flags should * Convert the value stored in *vp to its iteration object. The flags should
@ -112,10 +157,10 @@ IdVectorToIterator(JSContext *cx, JSObject *obj, uintN flags, js::AutoValueVecto
* iterator will never be exposed to scripts. * iterator will never be exposed to scripts.
*/ */
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
js_ValueToIterator(JSContext *cx, uintN flags, jsval *vp); js_ValueToIterator(JSContext *cx, uintN flags, js::Value *vp);
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
js_CloseIterator(JSContext *cx, jsval v); js_CloseIterator(JSContext *cx, JSObject *iterObj);
bool bool
js_SuppressDeletedProperty(JSContext *cx, JSObject *obj, jsid id); js_SuppressDeletedProperty(JSContext *cx, JSObject *obj, jsid id);
@ -126,10 +171,10 @@ js_SuppressDeletedProperty(JSContext *cx, JSObject *obj, jsid id);
* picked up by IteratorNext(). The value is cached in the current context. * picked up by IteratorNext(). The value is cached in the current context.
*/ */
extern JSBool extern JSBool
js_IteratorMore(JSContext *cx, JSObject *iterobj, jsval *rval); js_IteratorMore(JSContext *cx, JSObject *iterobj, js::Value *rval);
extern JSBool extern JSBool
js_IteratorNext(JSContext *cx, JSObject *iterobj, jsval *rval); js_IteratorNext(JSContext *cx, JSObject *iterobj, js::Value *rval);
extern JSBool extern JSBool
js_ThrowStopIteration(JSContext *cx); js_ThrowStopIteration(JSContext *cx);
@ -154,7 +199,7 @@ struct JSGenerator {
uintN vplen; uintN vplen;
JSStackFrame *liveFrame; JSStackFrame *liveFrame;
JSObject *enumerators; JSObject *enumerators;
jsval floatingStack[1]; js::Value floatingStack[1];
JSStackFrame *getFloatingFrame() { JSStackFrame *getFloatingFrame() {
return reinterpret_cast<JSStackFrame *>(floatingStack + vplen); return reinterpret_cast<JSStackFrame *>(floatingStack + vplen);
@ -204,20 +249,17 @@ js_LiveFrameIfGenerator(JSStackFrame *fp)
#endif #endif
extern JSExtendedClass js_GeneratorClass; extern js::ExtendedClass js_GeneratorClass;
extern JSExtendedClass js_IteratorClass; extern js::ExtendedClass js_IteratorClass;
extern JSClass js_StopIterationClass; extern js::Class js_StopIterationClass;
static inline bool static inline bool
js_ValueIsStopIteration(jsval v) js_ValueIsStopIteration(const js::Value &v)
{ {
return !JSVAL_IS_PRIMITIVE(v) && return v.isObject() && v.toObject().getClass() == &js_StopIterationClass;
JSVAL_TO_OBJECT(v)->getClass() == &js_StopIterationClass;
} }
extern JSObject * extern JSObject *
js_InitIteratorClasses(JSContext *cx, JSObject *obj); js_InitIteratorClasses(JSContext *cx, JSObject *obj);
JS_END_EXTERN_C
#endif /* jsiter_h___ */ #endif /* jsiter_h___ */

Просмотреть файл

@ -500,16 +500,16 @@ FinishSharingTitle(JSContext *cx, JSTitle *title)
uint32 nslots = scope->freeslot; uint32 nslots = scope->freeslot;
JS_ASSERT(nslots >= JSSLOT_START(obj->getClass())); JS_ASSERT(nslots >= JSSLOT_START(obj->getClass()));
for (uint32 i = JSSLOT_START(obj->getClass()); i != nslots; ++i) { for (uint32 i = JSSLOT_START(obj->getClass()); i != nslots; ++i) {
jsval v = obj->getSlot(i); Value v = obj->getSlot(i);
if (JSVAL_IS_STRING(v) && if (v.isString() &&
!js_MakeStringImmutable(cx, JSVAL_TO_STRING(v))) { !js_MakeStringImmutable(cx, v.toString())) {
/* /*
* FIXME bug 363059: The following error recovery changes * FIXME bug 363059: The following error recovery changes
* runtime execution semantics, arbitrarily and silently * runtime execution semantics, arbitrarily and silently
* ignoring errors except out-of-memory, which should have been * ignoring errors except out-of-memory, which should have been
* reported through JS_ReportOutOfMemory at this point. * reported through JS_ReportOutOfMemory at this point.
*/ */
obj->setSlot(i, JSVAL_VOID); obj->setSlot(i, UndefinedValue());
} }
} }
} }
@ -717,7 +717,7 @@ js_GetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot)
if (CX_THREAD_IS_RUNNING_GC(cx) || if (CX_THREAD_IS_RUNNING_GC(cx) ||
scope->sealed() || scope->sealed() ||
(title->ownercx && ClaimTitle(title, cx))) { (title->ownercx && ClaimTitle(title, cx))) {
return obj->getSlot(slot); return Jsvalify(obj->getSlot(slot));
} }
#ifndef NSPR_LOCK #ifndef NSPR_LOCK
@ -732,7 +732,7 @@ js_GetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot)
* lock release followed by fat lock acquisition. * lock release followed by fat lock acquisition.
*/ */
if (scope == obj->scope()) { if (scope == obj->scope()) {
v = obj->getSlot(slot); v = Jsvalify(obj->getSlot(slot));
if (!NativeCompareAndSwap(&tl->owner, me, 0)) { if (!NativeCompareAndSwap(&tl->owner, me, 0)) {
/* Assert that scope locks never revert to flyweight. */ /* Assert that scope locks never revert to flyweight. */
JS_ASSERT(title->ownercx != cx); JS_ASSERT(title->ownercx != cx);
@ -746,12 +746,12 @@ js_GetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot)
js_Dequeue(tl); js_Dequeue(tl);
} }
else if (Thin_RemoveWait(ReadWord(tl->owner)) == me) { else if (Thin_RemoveWait(ReadWord(tl->owner)) == me) {
return obj->getSlot(slot); return Jsvalify(obj->getSlot(slot));
} }
#endif #endif
js_LockObj(cx, obj); js_LockObj(cx, obj);
v = obj->getSlot(slot); v = Jsvalify(obj->getSlot(slot));
/* /*
* Test whether cx took ownership of obj's scope during js_LockObj. * Test whether cx took ownership of obj's scope during js_LockObj.
@ -805,7 +805,7 @@ js_SetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot, jsval v)
if (CX_THREAD_IS_RUNNING_GC(cx) || if (CX_THREAD_IS_RUNNING_GC(cx) ||
scope->sealed() || scope->sealed() ||
(title->ownercx && ClaimTitle(title, cx))) { (title->ownercx && ClaimTitle(title, cx))) {
obj->lockedSetSlot(slot, v); obj->lockedSetSlot(slot, Valueify(v));
return; return;
} }
@ -815,7 +815,7 @@ js_SetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot, jsval v)
JS_ASSERT(CURRENT_THREAD_IS_ME(me)); JS_ASSERT(CURRENT_THREAD_IS_ME(me));
if (NativeCompareAndSwap(&tl->owner, 0, me)) { if (NativeCompareAndSwap(&tl->owner, 0, me)) {
if (scope == obj->scope()) { if (scope == obj->scope()) {
obj->lockedSetSlot(slot, v); obj->lockedSetSlot(slot, Valueify(v));
if (!NativeCompareAndSwap(&tl->owner, me, 0)) { if (!NativeCompareAndSwap(&tl->owner, me, 0)) {
/* Assert that scope locks never revert to flyweight. */ /* Assert that scope locks never revert to flyweight. */
JS_ASSERT(title->ownercx != cx); JS_ASSERT(title->ownercx != cx);
@ -828,13 +828,13 @@ js_SetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot, jsval v)
if (!NativeCompareAndSwap(&tl->owner, me, 0)) if (!NativeCompareAndSwap(&tl->owner, me, 0))
js_Dequeue(tl); js_Dequeue(tl);
} else if (Thin_RemoveWait(ReadWord(tl->owner)) == me) { } else if (Thin_RemoveWait(ReadWord(tl->owner)) == me) {
obj->lockedSetSlot(slot, v); obj->lockedSetSlot(slot, Valueify(v));
return; return;
} }
#endif #endif
js_LockObj(cx, obj); js_LockObj(cx, obj);
obj->lockedSetSlot(slot, v); obj->lockedSetSlot(slot, Valueify(v));
/* /*
* Same drill as above, in js_GetSlotThreadSafe. * Same drill as above, in js_GetSlotThreadSafe.

Просмотреть файл

@ -40,8 +40,8 @@
#define jslock_h__ #define jslock_h__
#include "jstypes.h" #include "jstypes.h"
#include "jsprvtd.h" /* for JSScope, etc. */ #include "jsapi.h"
#include "jspubtd.h" /* for JSRuntime, etc. */ #include "jsprvtd.h"
#ifdef JS_THREADSAFE #ifdef JS_THREADSAFE
# include "pratom.h" # include "pratom.h"

Просмотреть файл

@ -54,7 +54,6 @@
#include "jsmath.h" #include "jsmath.h"
#include "jsnum.h" #include "jsnum.h"
#include "jslibmath.h" #include "jslibmath.h"
#include "jsobj.h"
using namespace js; using namespace js;
@ -95,84 +94,88 @@ static JSConstDoubleSpec math_constants[] = {
{0,0,0,{0,0,0}} {0,0,0,{0,0,0}}
}; };
JSClass js_MathClass = { Class js_MathClass = {
js_Math_str, js_Math_str,
JSCLASS_HAS_CACHED_PROTO(JSProto_Math), JSCLASS_HAS_CACHED_PROTO(JSProto_Math),
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, PropertyStub, PropertyStub, PropertyStub, PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL, EnumerateStub, ResolveStub, ConvertStub, NULL,
JSCLASS_NO_OPTIONAL_MEMBERS JSCLASS_NO_OPTIONAL_MEMBERS
}; };
static JSBool static JSBool
math_abs(JSContext *cx, uintN argc, jsval *vp) math_abs(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
if (!ValueToNumber(cx, vp[2], &x)) if (!ValueToNumber(cx, vp[2], &x))
return JS_FALSE; return JS_FALSE;
z = fabs(x); z = fabs(x);
return js_NewNumberInRootedValue(cx, z, vp); vp->setNumber(z);
return JS_TRUE;
} }
static JSBool static JSBool
math_acos(JSContext *cx, uintN argc, jsval *vp) math_acos(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
if (!ValueToNumber(cx, vp[2], &x)) if (!ValueToNumber(cx, vp[2], &x))
return JS_FALSE; return JS_FALSE;
#if defined(SOLARIS) && defined(__GNUC__) #if defined(SOLARIS) && defined(__GNUC__)
if (x < -1 || 1 < x) { if (x < -1 || 1 < x) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
#endif #endif
z = acos(x); z = acos(x);
return js_NewNumberInRootedValue(cx, z, vp); vp->setDouble(z);
return JS_TRUE;
} }
static JSBool static JSBool
math_asin(JSContext *cx, uintN argc, jsval *vp) math_asin(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
if (!ValueToNumber(cx, vp[2], &x)) if (!ValueToNumber(cx, vp[2], &x))
return JS_FALSE; return JS_FALSE;
#if defined(SOLARIS) && defined(__GNUC__) #if defined(SOLARIS) && defined(__GNUC__)
if (x < -1 || 1 < x) { if (x < -1 || 1 < x) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
#endif #endif
z = asin(x); z = asin(x);
return js_NewNumberInRootedValue(cx, z, vp); vp->setDouble(z);
return JS_TRUE;
} }
static JSBool static JSBool
math_atan(JSContext *cx, uintN argc, jsval *vp) math_atan(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
if (!ValueToNumber(cx, vp[2], &x)) if (!ValueToNumber(cx, vp[2], &x))
return JS_FALSE; return JS_FALSE;
z = atan(x); z = atan(x);
return js_NewNumberInRootedValue(cx, z, vp); vp->setDouble(z);
return JS_TRUE;
} }
static inline jsdouble JS_FASTCALL static inline jsdouble JS_FASTCALL
@ -206,19 +209,21 @@ math_atan2_kernel(jsdouble x, jsdouble y)
} }
static JSBool static JSBool
math_atan2(JSContext *cx, uintN argc, jsval *vp) math_atan2(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble x, y; jsdouble x, y, z;
if (argc <= 1) { if (argc <= 1) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
if (!ValueToNumber(cx, vp[2], &x)) if (!ValueToNumber(cx, vp[2], &x))
return JS_FALSE; return JS_FALSE;
if (!ValueToNumber(cx, vp[3], &y)) if (!ValueToNumber(cx, vp[3], &y))
return JS_FALSE; return JS_FALSE;
return js_NewNumberInRootedValue(cx, math_atan2_kernel (x, y), vp); z = math_atan2_kernel(x, y);
vp->setDouble(z);
return JS_TRUE;
} }
static inline jsdouble JS_FASTCALL static inline jsdouble JS_FASTCALL
@ -232,42 +237,44 @@ math_ceil_kernel(jsdouble x)
} }
JSBool JSBool
js_math_ceil(JSContext *cx, uintN argc, jsval *vp) js_math_ceil(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
if (!ValueToNumber(cx, vp[2], &x)) if (!ValueToNumber(cx, vp[2], &x))
return JS_FALSE; return JS_FALSE;
z = math_ceil_kernel(x); z = math_ceil_kernel(x);
return js_NewNumberInRootedValue(cx, z, vp); vp->setNumber(z);
return JS_TRUE;
} }
static JSBool static JSBool
math_cos(JSContext *cx, uintN argc, jsval *vp) math_cos(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
if (!ValueToNumber(cx, vp[2], &x)) if (!ValueToNumber(cx, vp[2], &x))
return JS_FALSE; return JS_FALSE;
z = cos(x); z = cos(x);
return js_NewNumberInRootedValue(cx, z, vp); vp->setDouble(z);
return JS_TRUE;
} }
static JSBool static JSBool
math_exp(JSContext *cx, uintN argc, jsval *vp) math_exp(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
if (!ValueToNumber(cx, vp[2], &x)) if (!ValueToNumber(cx, vp[2], &x))
@ -275,64 +282,67 @@ math_exp(JSContext *cx, uintN argc, jsval *vp)
#ifdef _WIN32 #ifdef _WIN32
if (!JSDOUBLE_IS_NaN(x)) { if (!JSDOUBLE_IS_NaN(x)) {
if (x == js_PositiveInfinity) { if (x == js_PositiveInfinity) {
*vp = cx->runtime->positiveInfinityValue; vp->setDouble(js_PositiveInfinity);
return JS_TRUE; return JS_TRUE;
} }
if (x == js_NegativeInfinity) { if (x == js_NegativeInfinity) {
*vp = JSVAL_ZERO; vp->setInt32(0);
return JS_TRUE; return JS_TRUE;
} }
} }
#endif #endif
z = exp(x); z = exp(x);
return js_NewNumberInRootedValue(cx, z, vp); vp->setNumber(z);
return JS_TRUE;
} }
JSBool JSBool
js_math_floor(JSContext *cx, uintN argc, jsval *vp) js_math_floor(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
if (!ValueToNumber(cx, vp[2], &x)) if (!ValueToNumber(cx, vp[2], &x))
return JS_FALSE; return JS_FALSE;
z = floor(x); z = floor(x);
return js_NewNumberInRootedValue(cx, z, vp); vp->setNumber(z);
return JS_TRUE;
} }
static JSBool static JSBool
math_log(JSContext *cx, uintN argc, jsval *vp) math_log(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
if (!ValueToNumber(cx, vp[2], &x)) if (!ValueToNumber(cx, vp[2], &x))
return JS_FALSE; return JS_FALSE;
#if defined(SOLARIS) && defined(__GNUC__) #if defined(SOLARIS) && defined(__GNUC__)
if (x < 0) { if (x < 0) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
#endif #endif
z = log(x); z = log(x);
return js_NewNumberInRootedValue(cx, z, vp); vp->setNumber(z);
return JS_TRUE;
} }
JSBool JSBool
js_math_max(JSContext *cx, uintN argc, jsval *vp) js_math_max(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble x, z = js_NegativeInfinity; jsdouble x, z = js_NegativeInfinity;
jsval *argv; Value *argv;
uintN i; uintN i;
if (argc == 0) { if (argc == 0) {
*vp = cx->runtime->negativeInfinityValue; vp->setDouble(js_NegativeInfinity);
return JS_TRUE; return JS_TRUE;
} }
argv = vp + 2; argv = vp + 2;
@ -340,7 +350,7 @@ js_math_max(JSContext *cx, uintN argc, jsval *vp)
if (!ValueToNumber(cx, argv[i], &x)) if (!ValueToNumber(cx, argv[i], &x))
return JS_FALSE; return JS_FALSE;
if (JSDOUBLE_IS_NaN(x)) { if (JSDOUBLE_IS_NaN(x)) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
if (x == 0 && x == z) { if (x == 0 && x == z) {
@ -350,18 +360,19 @@ js_math_max(JSContext *cx, uintN argc, jsval *vp)
z = (x > z) ? x : z; z = (x > z) ? x : z;
} }
} }
return js_NewNumberInRootedValue(cx, z, vp); vp->setNumber(z);
return JS_TRUE;
} }
JSBool JSBool
js_math_min(JSContext *cx, uintN argc, jsval *vp) js_math_min(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble x, z = js_PositiveInfinity; jsdouble x, z = js_PositiveInfinity;
jsval *argv; Value *argv;
uintN i; uintN i;
if (argc == 0) { if (argc == 0) {
*vp = cx->runtime->positiveInfinityValue; vp->setDouble(js_PositiveInfinity);
return JS_TRUE; return JS_TRUE;
} }
argv = vp + 2; argv = vp + 2;
@ -369,7 +380,7 @@ js_math_min(JSContext *cx, uintN argc, jsval *vp)
if (!ValueToNumber(cx, argv[i], &x)) if (!ValueToNumber(cx, argv[i], &x))
return JS_FALSE; return JS_FALSE;
if (JSDOUBLE_IS_NaN(x)) { if (JSDOUBLE_IS_NaN(x)) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
if (x == 0 && x == z) { if (x == 0 && x == z) {
@ -379,16 +390,17 @@ js_math_min(JSContext *cx, uintN argc, jsval *vp)
z = (x < z) ? x : z; z = (x < z) ? x : z;
} }
} }
return js_NewNumberInRootedValue(cx, z, vp); vp->setNumber(z);
return JS_TRUE;
} }
static JSBool static JSBool
math_pow(JSContext *cx, uintN argc, jsval *vp) math_pow(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble x, y, z; jsdouble x, y, z;
if (argc <= 1) { if (argc <= 1) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
if (!ValueToNumber(cx, vp[2], &x)) if (!ValueToNumber(cx, vp[2], &x))
@ -400,16 +412,17 @@ math_pow(JSContext *cx, uintN argc, jsval *vp)
* we need to wrap the libm call to make it ECMA compliant. * we need to wrap the libm call to make it ECMA compliant.
*/ */
if (!JSDOUBLE_IS_FINITE(y) && (x == 1.0 || x == -1.0)) { if (!JSDOUBLE_IS_FINITE(y) && (x == 1.0 || x == -1.0)) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
/* pow(x, +-0) is always 1, even for x = NaN. */ /* pow(x, +-0) is always 1, even for x = NaN. */
if (y == 0) { if (y == 0) {
*vp = JSVAL_ONE; vp->setInt32(1);
return JS_TRUE; return JS_TRUE;
} }
z = pow(x, y); z = pow(x, y);
return js_NewNumberInRootedValue(cx, z, vp); vp->setNumber(z);
return JS_TRUE;
} }
static const int64 RNG_MULTIPLIER = 0x5DEECE66DLL; static const int64 RNG_MULTIPLIER = 0x5DEECE66DLL;
@ -458,10 +471,11 @@ random_nextDouble(JSContext *cx)
} }
static JSBool static JSBool
math_random(JSContext *cx, uintN argc, jsval *vp) math_random(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble z = random_nextDouble(cx); jsdouble z = random_nextDouble(cx);
return js_NewNumberInRootedValue(cx, z, vp); vp->setDouble(z);
return JS_TRUE;
} }
#if defined _WIN32 && !defined WINCE && _MSC_VER < 1400 #if defined _WIN32 && !defined WINCE && _MSC_VER < 1400
@ -480,70 +494,74 @@ js_copysign(double x, double y)
#endif #endif
JSBool JSBool
js_math_round(JSContext *cx, uintN argc, jsval *vp) js_math_round(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
if (!ValueToNumber(cx, vp[2], &x)) if (!ValueToNumber(cx, vp[2], &x))
return JS_FALSE; return JS_FALSE;
z = js_copysign(floor(x + 0.5), x); z = js_copysign(floor(x + 0.5), x);
return js_NewNumberInRootedValue(cx, z, vp); vp->setNumber(z);
return JS_TRUE;
} }
static JSBool static JSBool
math_sin(JSContext *cx, uintN argc, jsval *vp) math_sin(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
if (!ValueToNumber(cx, vp[2], &x)) if (!ValueToNumber(cx, vp[2], &x))
return JS_FALSE; return JS_FALSE;
z = sin(x); z = sin(x);
return js_NewNumberInRootedValue(cx, z, vp); vp->setDouble(z);
return JS_TRUE;
} }
static JSBool static JSBool
math_sqrt(JSContext *cx, uintN argc, jsval *vp) math_sqrt(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
if (!ValueToNumber(cx, vp[2], &x)) if (!ValueToNumber(cx, vp[2], &x))
return JS_FALSE; return JS_FALSE;
z = sqrt(x); z = sqrt(x);
return js_NewNumberInRootedValue(cx, z, vp); vp->setDouble(z);
return JS_TRUE;
} }
static JSBool static JSBool
math_tan(JSContext *cx, uintN argc, jsval *vp) math_tan(JSContext *cx, uintN argc, Value *vp)
{ {
jsdouble x, z; jsdouble x, z;
if (argc == 0) { if (argc == 0) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
if (!ValueToNumber(cx, vp[2], &x)) if (!ValueToNumber(cx, vp[2], &x))
return JS_FALSE; return JS_FALSE;
z = tan(x); z = tan(x);
return js_NewNumberInRootedValue(cx, z, vp); vp->setDouble(z);
return JS_TRUE;
} }
#if JS_HAS_TOSOURCE #if JS_HAS_TOSOURCE
static JSBool static JSBool
math_toSource(JSContext *cx, uintN argc, jsval *vp) math_toSource(JSContext *cx, uintN argc, Value *vp)
{ {
*vp = ATOM_KEY(CLASS_ATOM(cx, Math)); vp->setString(ATOM_TO_STRING(CLASS_ATOM(cx, Math)));
return JS_TRUE; return JS_TRUE;
} }
#endif #endif
@ -737,7 +755,7 @@ js_InitMathClass(JSContext *cx, JSObject *obj)
{ {
JSObject *Math; JSObject *Math;
Math = JS_NewObject(cx, &js_MathClass, NULL, obj); Math = JS_NewObject(cx, Jsvalify(&js_MathClass), NULL, obj);
if (!Math) if (!Math)
return NULL; return NULL;
if (!JS_DefineProperty(cx, obj, js_Math_str, OBJECT_TO_JSVAL(Math), if (!JS_DefineProperty(cx, obj, js_Math_str, OBJECT_TO_JSVAL(Math),

Просмотреть файл

@ -43,9 +43,7 @@
* JS math functions. * JS math functions.
*/ */
JS_BEGIN_EXTERN_C extern js::Class js_MathClass;
extern JSClass js_MathClass;
extern JSObject * extern JSObject *
js_InitMathClass(JSContext *cx, JSObject *obj); js_InitMathClass(JSContext *cx, JSObject *obj);
@ -54,20 +52,18 @@ extern void
js_InitRandom(JSContext *cx); js_InitRandom(JSContext *cx);
extern JSBool extern JSBool
js_math_ceil(JSContext *cx, uintN argc, jsval *vp); js_math_ceil(JSContext *cx, uintN argc, js::Value *vp);
extern JSBool extern JSBool
js_math_floor(JSContext *cx, uintN argc, jsval *vp); js_math_floor(JSContext *cx, uintN argc, js::Value *vp);
extern JSBool extern JSBool
js_math_max(JSContext *cx, uintN argc, jsval *vp); js_math_max(JSContext *cx, uintN argc, js::Value *vp);
extern JSBool extern JSBool
js_math_min(JSContext *cx, uintN argc, jsval *vp); js_math_min(JSContext *cx, uintN argc, js::Value *vp);
extern JSBool extern JSBool
js_math_round(JSContext *cx, uintN argc, jsval *vp); js_math_round(JSContext *cx, uintN argc, js::Value *vp);
JS_END_EXTERN_C
#endif /* jsmath_h___ */ #endif /* jsmath_h___ */

Просмотреть файл

@ -103,42 +103,42 @@ JS_STATIC_ASSERT(uintptr_t(PTRDIFF_MAX) + uintptr_t(1) == uintptr_t(PTRDIFF_MIN)
#endif /* JS_HAVE_STDINT_H */ #endif /* JS_HAVE_STDINT_H */
static JSBool static JSBool
num_isNaN(JSContext *cx, uintN argc, jsval *vp) num_isNaN(JSContext *cx, uintN argc, Value *vp)
{ {
if (argc == 0) { if (argc == 0) {
*vp = JSVAL_TRUE; vp->setBoolean(true);
return JS_TRUE; return JS_TRUE;
} }
jsdouble x; jsdouble x;
if (!ValueToNumber(cx, vp[2], &x)) if (!ValueToNumber(cx, vp[2], &x))
return false; return false;
*vp = BOOLEAN_TO_JSVAL(JSDOUBLE_IS_NaN(x)); vp->setBoolean(JSDOUBLE_IS_NaN(x));
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
num_isFinite(JSContext *cx, uintN argc, jsval *vp) num_isFinite(JSContext *cx, uintN argc, Value *vp)
{ {
if (argc == 0) { if (argc == 0) {
*vp = JSVAL_FALSE; vp->setBoolean(false);
return JS_TRUE; return JS_TRUE;
} }
jsdouble x; jsdouble x;
if (!ValueToNumber(cx, vp[2], &x)) if (!ValueToNumber(cx, vp[2], &x))
return JS_FALSE; return JS_FALSE;
*vp = BOOLEAN_TO_JSVAL(JSDOUBLE_IS_FINITE(x)); vp->setBoolean(JSDOUBLE_IS_FINITE(x));
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
num_parseFloat(JSContext *cx, uintN argc, jsval *vp) num_parseFloat(JSContext *cx, uintN argc, Value *vp)
{ {
JSString *str; JSString *str;
jsdouble d; jsdouble d;
const jschar *bp, *end, *ep; const jschar *bp, *end, *ep;
if (argc == 0) { if (argc == 0) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
str = js_ValueToString(cx, vp[2]); str = js_ValueToString(cx, vp[2]);
@ -148,10 +148,11 @@ num_parseFloat(JSContext *cx, uintN argc, jsval *vp)
if (!js_strtod(cx, bp, end, &ep, &d)) if (!js_strtod(cx, bp, end, &ep, &d))
return JS_FALSE; return JS_FALSE;
if (ep == bp) { if (ep == bp) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
return js_NewNumberInRootedValue(cx, d, vp); vp->setNumber(d);
return JS_TRUE;
} }
#ifdef JS_TRACER #ifdef JS_TRACER
@ -172,14 +173,14 @@ ParseFloat(JSContext* cx, JSString* str)
/* See ECMA 15.1.2.2. */ /* See ECMA 15.1.2.2. */
static JSBool static JSBool
num_parseInt(JSContext *cx, uintN argc, jsval *vp) num_parseInt(JSContext *cx, uintN argc, Value *vp)
{ {
JSString *str; JSString *str;
jsdouble d; jsdouble d;
const jschar *bp, *end, *ep; const jschar *bp, *end, *ep;
if (argc == 0) { if (argc == 0) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
int32_t radix; int32_t radix;
@ -190,11 +191,11 @@ num_parseInt(JSContext *cx, uintN argc, jsval *vp)
radix = 0; radix = 0;
} }
if (radix != 0 && (radix < 2 || radix > 36)) { if (radix != 0 && (radix < 2 || radix > 36)) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
if (JSVAL_IS_INT(vp[2]) && (radix == 0 || radix == 10)) { if (vp[2].isInt32() && (radix == 0 || radix == 10)) {
*vp = vp[2]; *vp = vp[2];
return JS_TRUE; return JS_TRUE;
} }
@ -206,10 +207,11 @@ num_parseInt(JSContext *cx, uintN argc, jsval *vp)
if (!js_strtointeger(cx, bp, end, &ep, radix, &d)) if (!js_strtointeger(cx, bp, end, &ep, radix, &d))
return JS_FALSE; return JS_FALSE;
if (ep == bp) { if (ep == bp) {
*vp = cx->runtime->NaNValue; vp->setDouble(js_NaN);
return JS_TRUE; return JS_TRUE;
} }
return js_NewNumberInRootedValue(cx, d, vp); vp->setNumber(d);
return JS_TRUE;
} }
#ifdef JS_TRACER #ifdef JS_TRACER
@ -266,46 +268,43 @@ static JSFunctionSpec number_functions[] = {
JS_FS_END JS_FS_END
}; };
JSClass js_NumberClass = { Class js_NumberClass = {
js_Number_str, js_Number_str,
JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_HAS_CACHED_PROTO(JSProto_Number), JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_HAS_CACHED_PROTO(JSProto_Number),
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, PropertyStub, PropertyStub, PropertyStub, PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL, EnumerateStub, ResolveStub, ConvertStub, NULL,
JSCLASS_NO_OPTIONAL_MEMBERS JSCLASS_NO_OPTIONAL_MEMBERS
}; };
static JSBool static JSBool
Number(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) Number(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
{ {
jsval v; Value v;
if (argc != 0) { if (argc != 0) {
if (!ValueToNumberValue(cx, &argv[0])) if (!ValueToNumber(cx, &argv[0]))
return JS_FALSE; return JS_FALSE;
v = argv[0];
} else { } else {
v = JSVAL_ZERO; argv[0].setInt32(0);
} }
if (!JS_IsConstructing(cx)) if (!JS_IsConstructing(cx))
*rval = v; *rval = argv[0];
else else
obj->setPrimitiveThis(v); obj->setPrimitiveThis(argv[0]);
return true; return true;
} }
#if JS_HAS_TOSOURCE #if JS_HAS_TOSOURCE
static JSBool static JSBool
num_toSource(JSContext *cx, uintN argc, jsval *vp) num_toSource(JSContext *cx, uintN argc, Value *vp)
{ {
jsval v;
jsdouble d;
char numBuf[DTOSTR_STANDARD_BUFFER_SIZE], *numStr; char numBuf[DTOSTR_STANDARD_BUFFER_SIZE], *numStr;
char buf[64]; char buf[64];
JSString *str; JSString *str;
if (!js_GetPrimitiveThis(cx, vp, &js_NumberClass, &v)) const Value *primp;
if (!js_GetPrimitiveThis(cx, vp, &js_NumberClass, &primp))
return JS_FALSE; return JS_FALSE;
JS_ASSERT(JSVAL_IS_NUMBER(v)); double d = primp->toNumber();
d = JSVAL_IS_INT(v) ? (jsdouble)JSVAL_TO_INT(v) : *JSVAL_TO_DOUBLE(v);
numStr = js_dtostr(JS_THREAD_DATA(cx)->dtoaState, numBuf, sizeof numBuf, numStr = js_dtostr(JS_THREAD_DATA(cx)->dtoaState, numBuf, sizeof numBuf,
DTOSTR_STANDARD, 0, d); DTOSTR_STANDARD, 0, d);
if (!numStr) { if (!numStr) {
@ -316,7 +315,7 @@ num_toSource(JSContext *cx, uintN argc, jsval *vp)
str = JS_NewStringCopyZ(cx, buf); str = JS_NewStringCopyZ(cx, buf);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
*vp = STRING_TO_JSVAL(str); vp->setString(str);
return JS_TRUE; return JS_TRUE;
} }
#endif #endif
@ -372,18 +371,14 @@ static JSString * JS_FASTCALL
js_NumberToStringWithBase(JSContext *cx, jsdouble d, jsint base); js_NumberToStringWithBase(JSContext *cx, jsdouble d, jsint base);
static JSBool static JSBool
num_toString(JSContext *cx, uintN argc, jsval *vp) num_toString(JSContext *cx, uintN argc, Value *vp)
{ {
jsval v; const Value *primp;
jsdouble d; if (!js_GetPrimitiveThis(cx, vp, &js_NumberClass, &primp))
JSString *str;
if (!js_GetPrimitiveThis(cx, vp, &js_NumberClass, &v))
return JS_FALSE; return JS_FALSE;
JS_ASSERT(JSVAL_IS_NUMBER(v)); double d = primp->toNumber();
d = JSVAL_IS_INT(v) ? (jsdouble)JSVAL_TO_INT(v) : *JSVAL_TO_DOUBLE(v);
int32_t base = 10; int32_t base = 10;
if (argc != 0 && !JSVAL_IS_VOID(vp[2])) { if (argc != 0 && !vp[2].isUndefined()) {
if (!ValueToECMAInt32(cx, vp[2], &base)) if (!ValueToECMAInt32(cx, vp[2], &base))
return JS_FALSE; return JS_FALSE;
@ -395,22 +390,22 @@ num_toString(JSContext *cx, uintN argc, jsval *vp)
return JS_FALSE; return JS_FALSE;
} }
} }
str = js_NumberToStringWithBase(cx, d, base); JSString *str = js_NumberToStringWithBase(cx, d, base);
if (!str) { if (!str) {
JS_ReportOutOfMemory(cx); JS_ReportOutOfMemory(cx);
return JS_FALSE; return JS_FALSE;
} }
*vp = STRING_TO_JSVAL(str); vp->setString(str);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
num_toLocaleString(JSContext *cx, uintN argc, jsval *vp) num_toLocaleString(JSContext *cx, uintN argc, Value *vp)
{ {
size_t thousandsLength, decimalLength; size_t thousandsLength, decimalLength;
const char *numGrouping, *tmpGroup; const char *numGrouping, *tmpGroup;
JSRuntime *rt; JSRuntime *rt;
JSString *numStr, *str; JSString *str;
const char *num, *end, *tmpSrc; const char *num, *end, *tmpSrc;
char *buf, *tmpDest; char *buf, *tmpDest;
const char *nint; const char *nint;
@ -422,9 +417,8 @@ num_toLocaleString(JSContext *cx, uintN argc, jsval *vp)
*/ */
if (!num_toString(cx, 0, vp)) if (!num_toString(cx, 0, vp))
return JS_FALSE; return JS_FALSE;
JS_ASSERT(JSVAL_IS_STRING(*vp)); JS_ASSERT(vp->isString());
numStr = JSVAL_TO_STRING(*vp); num = js_GetStringBytes(cx, vp->toString());
num = js_GetStringBytes(cx, numStr);
if (!num) if (!num)
return JS_FALSE; return JS_FALSE;
@ -500,7 +494,7 @@ num_toLocaleString(JSContext *cx, uintN argc, jsval *vp)
} }
if (cx->localeCallbacks && cx->localeCallbacks->localeToUnicode) if (cx->localeCallbacks && cx->localeCallbacks->localeToUnicode)
return cx->localeCallbacks->localeToUnicode(cx, buf, vp); return cx->localeCallbacks->localeToUnicode(cx, buf, Jsvalify(vp));
str = JS_NewString(cx, buf, size); str = JS_NewString(cx, buf, size);
if (!str) { if (!str) {
@ -508,23 +502,19 @@ num_toLocaleString(JSContext *cx, uintN argc, jsval *vp)
return JS_FALSE; return JS_FALSE;
} }
*vp = STRING_TO_JSVAL(str); vp->setString(str);
return JS_TRUE; return JS_TRUE;
} }
static JSBool static JSBool
num_valueOf(JSContext *cx, uintN argc, jsval *vp) num_valueOf(JSContext *cx, uintN argc, Value *vp)
{ {
jsval v; if (vp[1].isNumber()) {
JSObject *obj; *vp = vp[1];
v = vp[1];
if (JSVAL_IS_NUMBER(v)) {
*vp = v;
return JS_TRUE; return JS_TRUE;
} }
obj = JS_THIS_OBJECT(cx, vp); JSObject *obj = ComputeThisFromVp(cx, vp);
if (!JS_InstanceOf(cx, obj, &js_NumberClass, vp + 2)) if (!InstanceOf(cx, obj, &js_NumberClass, vp + 2))
return JS_FALSE; return JS_FALSE;
*vp = obj->getPrimitiveThis(); *vp = obj->getPrimitiveThis();
return JS_TRUE; return JS_TRUE;
@ -536,21 +526,18 @@ num_valueOf(JSContext *cx, uintN argc, jsval *vp)
static JSBool static JSBool
num_to(JSContext *cx, JSDToStrMode zeroArgMode, JSDToStrMode oneArgMode, num_to(JSContext *cx, JSDToStrMode zeroArgMode, JSDToStrMode oneArgMode,
jsint precisionMin, jsint precisionMax, jsint precisionOffset, jsint precisionMin, jsint precisionMax, jsint precisionOffset,
uintN argc, jsval *vp) uintN argc, Value *vp)
{ {
jsval v;
jsdouble d, precision;
JSString *str;
/* Use MAX_PRECISION+1 because precisionOffset can be 1. */ /* Use MAX_PRECISION+1 because precisionOffset can be 1. */
char buf[DTOSTR_VARIABLE_BUFFER_SIZE(MAX_PRECISION+1)]; char buf[DTOSTR_VARIABLE_BUFFER_SIZE(MAX_PRECISION+1)];
char *numStr; char *numStr;
if (!js_GetPrimitiveThis(cx, vp, &js_NumberClass, &v)) const Value *primp;
if (!js_GetPrimitiveThis(cx, vp, &js_NumberClass, &primp))
return JS_FALSE; return JS_FALSE;
JS_ASSERT(JSVAL_IS_NUMBER(v)); double d = primp->toNumber();
d = JSVAL_IS_INT(v) ? (jsdouble)JSVAL_TO_INT(v) : *JSVAL_TO_DOUBLE(v);
double precision;
if (argc == 0) { if (argc == 0) {
precision = 0.0; precision = 0.0;
oneArgMode = zeroArgMode; oneArgMode = zeroArgMode;
@ -575,10 +562,10 @@ num_to(JSContext *cx, JSDToStrMode zeroArgMode, JSDToStrMode oneArgMode,
JS_ReportOutOfMemory(cx); JS_ReportOutOfMemory(cx);
return JS_FALSE; return JS_FALSE;
} }
str = JS_NewStringCopyZ(cx, numStr); JSString *str = JS_NewStringCopyZ(cx, numStr);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
*vp = STRING_TO_JSVAL(str); vp->setString(str);
return JS_TRUE; return JS_TRUE;
} }
@ -587,23 +574,23 @@ num_to(JSContext *cx, JSDToStrMode zeroArgMode, JSDToStrMode oneArgMode,
* than ECMA requires; this is permitted by ECMA-262. * than ECMA requires; this is permitted by ECMA-262.
*/ */
static JSBool static JSBool
num_toFixed(JSContext *cx, uintN argc, jsval *vp) num_toFixed(JSContext *cx, uintN argc, Value *vp)
{ {
return num_to(cx, DTOSTR_FIXED, DTOSTR_FIXED, -20, MAX_PRECISION, 0, return num_to(cx, DTOSTR_FIXED, DTOSTR_FIXED, -20, MAX_PRECISION, 0,
argc, vp); argc, vp);
} }
static JSBool static JSBool
num_toExponential(JSContext *cx, uintN argc, jsval *vp) num_toExponential(JSContext *cx, uintN argc, Value *vp)
{ {
return num_to(cx, DTOSTR_STANDARD_EXPONENTIAL, DTOSTR_EXPONENTIAL, 0, return num_to(cx, DTOSTR_STANDARD_EXPONENTIAL, DTOSTR_EXPONENTIAL, 0,
MAX_PRECISION, 1, argc, vp); MAX_PRECISION, 1, argc, vp);
} }
static JSBool static JSBool
num_toPrecision(JSContext *cx, uintN argc, jsval *vp) num_toPrecision(JSContext *cx, uintN argc, Value *vp)
{ {
if (argc == 0 || JSVAL_IS_VOID(vp[2])) if (argc == 0 || vp[2].isUndefined())
return num_toString(cx, 0, vp); return num_toString(cx, 0, vp);
return num_to(cx, DTOSTR_STANDARD, DTOSTR_PRECISION, 1, MAX_PRECISION, 0, return num_to(cx, DTOSTR_STANDARD, DTOSTR_PRECISION, 1, MAX_PRECISION, 0,
argc, vp); argc, vp);
@ -685,31 +672,25 @@ inline void FIX_FPU() {
JSBool JSBool
js_InitRuntimeNumberState(JSContext *cx) js_InitRuntimeNumberState(JSContext *cx)
{ {
JS_STATIC_ASSERT(JSVAL_NULL == jsval(0));
JSRuntime *rt = cx->runtime; JSRuntime *rt = cx->runtime;
JS_ASSERT(JSVAL_IS_NULL(rt->NaNValue));
FIX_FPU(); FIX_FPU();
jsdpun u; jsdpun u;
u.s.hi = JSDOUBLE_HI32_EXPMASK | JSDOUBLE_HI32_MANTMASK; u.s.hi = 0x7ff80000;
u.s.lo = 0xffffffff; u.s.lo = 0x00000000;
number_constants[NC_NaN].dval = js_NaN = u.d; number_constants[NC_NaN].dval = js_NaN = u.d;
if (!js_NewDoubleInRootedValue(cx, u.d, &rt->NaNValue)) rt->NaNValue.setDouble(u.d);
return false;
u.s.hi = JSDOUBLE_HI32_EXPMASK; u.s.hi = JSDOUBLE_HI32_EXPMASK;
u.s.lo = 0x00000000; u.s.lo = 0x00000000;
number_constants[NC_POSITIVE_INFINITY].dval = js_PositiveInfinity = u.d; number_constants[NC_POSITIVE_INFINITY].dval = js_PositiveInfinity = u.d;
if (!js_NewDoubleInRootedValue(cx, u.d, &rt->positiveInfinityValue)) rt->positiveInfinityValue.setDouble(u.d);
return false;
u.s.hi = JSDOUBLE_HI32_SIGNBIT | JSDOUBLE_HI32_EXPMASK; u.s.hi = JSDOUBLE_HI32_SIGNBIT | JSDOUBLE_HI32_EXPMASK;
u.s.lo = 0x00000000; u.s.lo = 0x00000000;
number_constants[NC_NEGATIVE_INFINITY].dval = js_NegativeInfinity = u.d; number_constants[NC_NEGATIVE_INFINITY].dval = js_NegativeInfinity = u.d;
if (!js_NewDoubleInRootedValue(cx, u.d, &rt->negativeInfinityValue)) rt->negativeInfinityValue.setDouble(u.d);
return false;
u.s.hi = 0; u.s.hi = 0;
u.s.lo = 1; u.s.lo = 1;
@ -732,32 +713,11 @@ js_InitRuntimeNumberState(JSContext *cx)
return rt->thousandsSeparator && rt->decimalSeparator && rt->numGrouping; return rt->thousandsSeparator && rt->decimalSeparator && rt->numGrouping;
} }
void
js_TraceRuntimeNumberState(JSTracer *trc)
{
JSRuntime *rt = trc->context->runtime;
if (!JSVAL_IS_NULL(rt->NaNValue))
JS_CALL_DOUBLE_TRACER(trc, JSVAL_TO_DOUBLE(rt->NaNValue), "NaN");
if (!JSVAL_IS_NULL(rt->positiveInfinityValue)) {
JS_CALL_DOUBLE_TRACER(trc, JSVAL_TO_DOUBLE(rt->positiveInfinityValue),
"+Infinity");
}
if (!JSVAL_IS_NULL(rt->negativeInfinityValue)) {
JS_CALL_DOUBLE_TRACER(trc, JSVAL_TO_DOUBLE(rt->negativeInfinityValue),
"-Infinity");
}
}
void void
js_FinishRuntimeNumberState(JSContext *cx) js_FinishRuntimeNumberState(JSContext *cx)
{ {
JSRuntime *rt = cx->runtime; JSRuntime *rt = cx->runtime;
rt->NaNValue = JSVAL_NULL;
rt->negativeInfinityValue = JSVAL_NULL;
rt->positiveInfinityValue = JSVAL_NULL;
cx->free((void *) rt->thousandsSeparator); cx->free((void *) rt->thousandsSeparator);
cx->free((void *) rt->decimalSeparator); cx->free((void *) rt->decimalSeparator);
cx->free((void *) rt->numGrouping); cx->free((void *) rt->numGrouping);
@ -776,23 +736,24 @@ js_InitNumberClass(JSContext *cx, JSObject *obj)
if (!JS_DefineFunctions(cx, obj, number_functions)) if (!JS_DefineFunctions(cx, obj, number_functions))
return NULL; return NULL;
proto = JS_InitClass(cx, obj, NULL, &js_NumberClass, Number, 1, proto = js_InitClass(cx, obj, NULL, &js_NumberClass, Number, 1,
NULL, number_methods, NULL, NULL); NULL, number_methods, NULL, NULL);
if (!proto || !(ctor = JS_GetConstructor(cx, proto))) if (!proto || !(ctor = JS_GetConstructor(cx, proto)))
return NULL; return NULL;
proto->setPrimitiveThis(JSVAL_ZERO); proto->setPrimitiveThis(Int32Value(0));
if (!JS_DefineConstDoubles(cx, ctor, number_constants)) if (!JS_DefineConstDoubles(cx, ctor, number_constants))
return NULL; return NULL;
/* ECMA 15.1.1.1 */ /* ECMA 15.1.1.1 */
rt = cx->runtime; rt = cx->runtime;
if (!JS_DefineProperty(cx, obj, js_NaN_str, rt->NaNValue, JS_PropertyStub, JS_PropertyStub, if (!JS_DefineProperty(cx, obj, js_NaN_str, Jsvalify(rt->NaNValue),
JS_PropertyStub, JS_PropertyStub,
JSPROP_PERMANENT | JSPROP_READONLY)) { JSPROP_PERMANENT | JSPROP_READONLY)) {
return NULL; return NULL;
} }
/* ECMA 15.1.1.2 */ /* ECMA 15.1.1.2 */
if (!JS_DefineProperty(cx, obj, js_Infinity_str, rt->positiveInfinityValue, if (!JS_DefineProperty(cx, obj, js_Infinity_str, Jsvalify(rt->positiveInfinityValue),
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JSPROP_PERMANENT | JSPROP_READONLY)) { JSPROP_PERMANENT | JSPROP_READONLY)) {
return NULL; return NULL;
@ -800,29 +761,6 @@ js_InitNumberClass(JSContext *cx, JSObject *obj)
return proto; return proto;
} }
JSBool
js_NewNumberInRootedValue(JSContext *cx, jsdouble d, jsval *vp)
{
jsint i;
if (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i)) {
*vp = INT_TO_JSVAL(i);
return JS_TRUE;
}
return js_NewDoubleInRootedValue(cx, d, vp);
}
JSBool
js_NewWeaklyRootedNumber(JSContext *cx, jsdouble d, jsval *rval)
{
jsint i;
if (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i)) {
*rval = INT_TO_JSVAL(i);
return JS_TRUE;
}
return JS_NewDoubleValue(cx, d, rval);
}
/* /*
* Convert a number to C string. The buf must be large enough to accommodate * Convert a number to C string. The buf must be large enough to accommodate
* the result, including '-' and '\0', if base == 10 or d is an integer that * the result, including '-' and '\0', if base == 10 or d is an integer that
@ -832,11 +770,11 @@ js_NewWeaklyRootedNumber(JSContext *cx, jsdouble d, jsval *rval)
static char * static char *
NumberToCString(JSContext *cx, jsdouble d, jsint base, char *buf, size_t bufSize) NumberToCString(JSContext *cx, jsdouble d, jsint base, char *buf, size_t bufSize)
{ {
jsint i; int32_t i;
char *numStr; char *numStr;
JS_ASSERT(bufSize >= DTOSTR_STANDARD_BUFFER_SIZE); JS_ASSERT(bufSize >= DTOSTR_STANDARD_BUFFER_SIZE);
if (JSDOUBLE_IS_INT(d, i)) { if (JSDOUBLE_IS_INT32(d, &i)) {
numStr = IntToCString(i, base, buf, bufSize); numStr = IntToCString(i, base, buf, bufSize);
} else { } else {
if (base == 10) if (base == 10)
@ -883,8 +821,8 @@ js_NumberToStringWithBase(JSContext *cx, jsdouble d, jsint base)
if (base < 2 || base > 36) if (base < 2 || base > 36)
return NULL; return NULL;
jsint i; int32_t i;
if (JSDOUBLE_IS_INT(d, i)) { if (JSDOUBLE_IS_INT32(d, &i)) {
if (base == 10 && jsuint(i) < INT_STRING_LIMIT) if (base == 10 && jsuint(i) < INT_STRING_LIMIT)
return JSString::intString(i); return JSString::intString(i);
if (jsuint(i) < jsuint(base)) { if (jsuint(i) < jsuint(base)) {
@ -915,18 +853,17 @@ js_NumberToString(JSContext *cx, jsdouble d)
} }
JSBool JS_FASTCALL JSBool JS_FASTCALL
js_NumberValueToCharBuffer(JSContext *cx, jsval v, JSCharBuffer &cb) js_NumberValueToCharBuffer(JSContext *cx, const Value &v, JSCharBuffer &cb)
{ {
/* Convert to C-string. */ /* Convert to C-string. */
static const size_t arrSize = DTOSTR_STANDARD_BUFFER_SIZE; static const size_t arrSize = DTOSTR_STANDARD_BUFFER_SIZE;
char arr[arrSize]; char arr[arrSize];
const char *cstr; const char *cstr;
if (JSVAL_IS_INT(v)) { if (v.isInt32()) {
cstr = IntToCString(JSVAL_TO_INT(v), 10, arr, arrSize); cstr = IntToCString(v.toInt32(), 10, arr, arrSize);
} else { } else {
JS_ASSERT(JSVAL_IS_DOUBLE(v));
cstr = js_dtostr(JS_THREAD_DATA(cx)->dtoaState, arr, arrSize, cstr = js_dtostr(JS_THREAD_DATA(cx)->dtoaState, arr, arrSize,
DTOSTR_STANDARD, 0, *JSVAL_TO_DOUBLE(v)); DTOSTR_STANDARD, 0, v.toDouble());
} }
if (!cstr) if (!cstr)
return JS_FALSE; return JS_FALSE;
@ -938,7 +875,7 @@ js_NumberValueToCharBuffer(JSContext *cx, jsval v, JSCharBuffer &cb)
size_t cstrlen = strlen(cstr); size_t cstrlen = strlen(cstr);
JS_ASSERT(cstrlen < arrSize); JS_ASSERT(cstrlen < arrSize);
size_t sizeBefore = cb.length(); size_t sizeBefore = cb.length();
if (!cb.growBy(cstrlen)) if (!cb.growByUninitialized(cstrlen))
return JS_FALSE; return JS_FALSE;
jschar *appendBegin = cb.begin() + sizeBefore; jschar *appendBegin = cb.begin() + sizeBefore;
#ifdef DEBUG #ifdef DEBUG
@ -952,87 +889,59 @@ js_NumberValueToCharBuffer(JSContext *cx, jsval v, JSCharBuffer &cb)
namespace js { namespace js {
jsval bool
ValueToNumberSlow(JSContext *cx, jsval v, double *out) ValueToNumberSlow(JSContext *cx, Value v, double *out)
{ {
JS_ASSERT(!JSVAL_IS_INT(v) && !JSVAL_IS_DOUBLE(v)); JS_ASSERT(!v.isNumber());
goto skip_int_double; goto skip_int_double;
for (;;) { for (;;) {
if (JSVAL_IS_INT(v)) { if (v.isNumber()) {
*out = (double)JSVAL_TO_INT(v); *out = v.toNumber();
return v; return true;
}
if (JSVAL_IS_DOUBLE(v)) {
*out = *JSVAL_TO_DOUBLE(v);
return v;
} }
skip_int_double: skip_int_double:
if (JSVAL_IS_STRING(v)) { if (v.isString()) {
JSString *str = JSVAL_TO_STRING(v); jsdouble d = StringToNumberType<jsdouble>(cx, v.toString());
jsdouble d = StringToNumberType<jsdouble>(cx, str);
if (JSDOUBLE_IS_NaN(d)) if (JSDOUBLE_IS_NaN(d))
break; break;
/*
* JSVAL_TRUE indicates that double jsval was never constructed
* for the result.
*/
*out = d; *out = d;
return JSVAL_TRUE; return true;
} }
if (JSVAL_IS_BOOLEAN(v)) { if (v.isBoolean()) {
if (JSVAL_TO_BOOLEAN(v)) { if (v.toBoolean()) {
*out = 1.0; *out = 1.0;
return JSVAL_ONE; return true;
} }
*out = 0.0; *out = 0.0;
return JSVAL_ZERO; return true;
} }
if (JSVAL_IS_NULL(v)) { if (v.isNull()) {
*out = 0.0; *out = 0.0;
return JSVAL_ZERO; return true;
} }
if (JSVAL_IS_VOID(v)) if (v.isUndefined())
break; break;
JS_ASSERT(!JSVAL_IS_PRIMITIVE(v)); JS_ASSERT(v.isObject());
if (!DefaultValue(cx, JSVAL_TO_OBJECT(v), JSTYPE_NUMBER, &v)) if (!DefaultValue(cx, &v.toObject(), JSTYPE_NUMBER, &v))
return JSVAL_NULL; return false;
if (!JSVAL_IS_PRIMITIVE(v)) if (v.isObject())
break; break;
} }
*out = js_NaN; *out = js_NaN;
return cx->runtime->NaNValue; return true;
} }
bool bool
ValueToNumberValueSlow(JSContext *cx, jsval *vp, double *out) ValueToECMAInt32Slow(JSContext *cx, const Value &v, int32_t *out)
{ {
jsval v = *vp = ValueToNumberSlow(cx, *vp, out); JS_ASSERT(!v.isInt32());
return !JSVAL_IS_NULL(v) &&
(v != JSVAL_TRUE || js_NewNumberInRootedValue(cx, *out, vp));
}
bool
ValueToNumberValueSlow(JSContext *cx, jsval *vp)
{
double d;
jsval v = *vp = ValueToNumberSlow(cx, *vp, &d);
return !JSVAL_IS_NULL(v) &&
(v != JSVAL_TRUE || js_NewNumberInRootedValue(cx, d, vp));
}
bool
ValueToECMAInt32Slow(JSContext *cx, jsval v, int32_t *out)
{
JS_ASSERT(!JSVAL_IS_INT(v));
jsdouble d; jsdouble d;
if (JSVAL_IS_DOUBLE(v)) { if (v.isDouble()) {
d = *JSVAL_TO_DOUBLE(v); d = v.toDouble();
} else { } else {
if (JSVAL_IS_NULL(ValueToNumberSlow(cx, v, &d))) if (!ValueToNumberSlow(cx, v, &d))
return false; return false;
} }
*out = js_DoubleToECMAInt32(d); *out = js_DoubleToECMAInt32(d);
@ -1040,14 +949,14 @@ ValueToECMAInt32Slow(JSContext *cx, jsval v, int32_t *out)
} }
bool bool
ValueToECMAUint32Slow(JSContext *cx, jsval v, uint32_t *out) ValueToECMAUint32Slow(JSContext *cx, const Value &v, uint32_t *out)
{ {
JS_ASSERT(!JSVAL_IS_INT(v)); JS_ASSERT(!v.isInt32());
jsdouble d; jsdouble d;
if (JSVAL_IS_DOUBLE(v)) { if (v.isDouble()) {
d = *JSVAL_TO_DOUBLE(v); d = v.toDouble();
} else { } else {
if (JSVAL_IS_NULL(ValueToNumberSlow(cx, v, &d))) if (!ValueToNumberSlow(cx, v, &d))
return false; return false;
} }
*out = js_DoubleToECMAUint32(d); *out = js_DoubleToECMAUint32(d);
@ -1069,7 +978,7 @@ js_DoubleToECMAUint32(jsdouble d)
/* /*
* We check whether d fits int32, not uint32, as all but the ">>>" bit * We check whether d fits int32, not uint32, as all but the ">>>" bit
* manipulation bytecode stores the result as int, not uint. When the * manipulation bytecode stores the result as int, not uint. When the
* result does not fit int jsval, it will be stored as a negative double. * result does not fit int Value, it will be stored as a negative double.
*/ */
i = (int32) d; i = (int32) d;
if ((jsdouble) i == d) if ((jsdouble) i == d)
@ -1088,20 +997,14 @@ js_DoubleToECMAUint32(jsdouble d)
namespace js { namespace js {
bool bool
ValueToInt32Slow(JSContext *cx, jsval v, int32_t *out) ValueToInt32Slow(JSContext *cx, const Value &v, int32_t *out)
{ {
JS_ASSERT(!JSVAL_IS_INT(v)); JS_ASSERT(!v.isInt32());
jsdouble d; jsdouble d;
if (JSVAL_IS_DOUBLE(v)) { if (v.isDouble()) {
d = *JSVAL_TO_DOUBLE(v); d = v.toDouble();
} else { } else if (!ValueToNumberSlow(cx, v, &d)) {
jsval v2 = ValueToNumberSlow(cx, v, &d);
if (JSVAL_IS_NULL(v2))
return false; return false;
if (JSVAL_IS_INT(v2)) {
*out = JSVAL_TO_INT(v2);
return true;
}
} }
if (JSDOUBLE_IS_NaN(d) || d <= -2147483649.0 || 2147483648.0 <= d) { if (JSDOUBLE_IS_NaN(d) || d <= -2147483649.0 || 2147483648.0 <= d) {
@ -1114,20 +1017,14 @@ ValueToInt32Slow(JSContext *cx, jsval v, int32_t *out)
} }
bool bool
ValueToUint16Slow(JSContext *cx, jsval v, uint16_t *out) ValueToUint16Slow(JSContext *cx, const Value &v, uint16_t *out)
{ {
JS_ASSERT(!JSVAL_IS_INT(v)); JS_ASSERT(!v.isInt32());
jsdouble d; jsdouble d;
if (JSVAL_IS_DOUBLE(v)) { if (v.isDouble()) {
d = *JSVAL_TO_DOUBLE(v); d = v.toDouble();
} else { } else if (!ValueToNumberSlow(cx, v, &d)) {
jsval v2 = ValueToNumberSlow(cx, v, &d);
if (JSVAL_IS_NULL(v2))
return false; return false;
if (JSVAL_IS_INT(v2)) {
*out = (uint16_t) JSVAL_TO_INT(v2);
return true;
}
} }
if (d == 0 || !JSDOUBLE_IS_FINITE(d)) { if (d == 0 || !JSDOUBLE_IS_FINITE(d)) {

Просмотреть файл

@ -47,6 +47,7 @@
#ifdef SOLARIS #ifdef SOLARIS
#include <ieeefp.h> #include <ieeefp.h>
#endif #endif
#include "jsvalue.h"
#include "jsstdint.h" #include "jsstdint.h"
#include "jsstr.h" #include "jsstr.h"
@ -117,31 +118,11 @@ JSDOUBLE_IS_INFINITE(jsdouble d)
#endif #endif
} }
static inline int
JSDOUBLE_IS_NEGZERO(jsdouble d)
{
#ifdef WIN32
return (d == 0 && (_fpclass(d) & _FPCLASS_NZ));
#elif defined(SOLARIS)
return (d == 0 && copysign(1, d) < 0);
#else
return (d == 0 && signbit(d));
#endif
}
#define JSDOUBLE_HI32_SIGNBIT 0x80000000 #define JSDOUBLE_HI32_SIGNBIT 0x80000000
#define JSDOUBLE_HI32_EXPMASK 0x7ff00000 #define JSDOUBLE_HI32_EXPMASK 0x7ff00000
#define JSDOUBLE_HI32_MANTMASK 0x000fffff #define JSDOUBLE_HI32_MANTMASK 0x000fffff
static inline int static inline bool
JSDOUBLE_IS_INT(jsdouble d, jsint& i)
{
if (JSDOUBLE_IS_NEGZERO(d))
return false;
return d == (i = jsint(d));
}
static inline int
JSDOUBLE_IS_NEG(jsdouble d) JSDOUBLE_IS_NEG(jsdouble d)
{ {
#ifdef WIN32 #ifdef WIN32
@ -178,14 +159,11 @@ extern jsdouble js_NegativeInfinity;
extern JSBool extern JSBool
js_InitRuntimeNumberState(JSContext *cx); js_InitRuntimeNumberState(JSContext *cx);
extern void
js_TraceRuntimeNumberState(JSTracer *trc);
extern void extern void
js_FinishRuntimeNumberState(JSContext *cx); js_FinishRuntimeNumberState(JSContext *cx);
/* Initialize the Number class, returning its prototype object. */ /* Initialize the Number class, returning its prototype object. */
extern JSClass js_NumberClass; extern js::Class js_NumberClass;
inline bool inline bool
JSObject::isNumber() const JSObject::isNumber() const
@ -193,7 +171,7 @@ JSObject::isNumber() const
return getClass() == &js_NumberClass; return getClass() == &js_NumberClass;
} }
extern "C" JSObject * extern JSObject *
js_InitNumberClass(JSContext *cx, JSObject *obj); js_InitNumberClass(JSContext *cx, JSObject *obj);
/* /*
@ -206,19 +184,6 @@ extern const char js_isFinite_str[];
extern const char js_parseFloat_str[]; extern const char js_parseFloat_str[];
extern const char js_parseInt_str[]; extern const char js_parseInt_str[];
/*
* vp must be a root.
*/
extern JSBool
js_NewNumberInRootedValue(JSContext *cx, jsdouble d, jsval *vp);
/*
* Create a weakly rooted integer or double jsval as appropriate for the given
* jsdouble.
*/
extern JSBool
js_NewWeaklyRootedNumber(JSContext *cx, jsdouble d, jsval *vp);
extern JSString * JS_FASTCALL extern JSString * JS_FASTCALL
js_IntToString(JSContext *cx, jsint i); js_IntToString(JSContext *cx, jsint i);
@ -226,131 +191,99 @@ extern JSString * JS_FASTCALL
js_NumberToString(JSContext *cx, jsdouble d); js_NumberToString(JSContext *cx, jsdouble d);
/* /*
* Convert an integer or double (contained in the given jsval) to a string and * Convert an integer or double (contained in the given value) to a string and
* append to the given buffer. * append to the given buffer.
*/ */
extern JSBool JS_FASTCALL extern JSBool JS_FASTCALL
js_NumberValueToCharBuffer(JSContext *cx, jsval v, JSCharBuffer &cb); js_NumberValueToCharBuffer(JSContext *cx, const js::Value &v, JSCharBuffer &cb);
namespace js { namespace js {
/* /*
* Convert a value to a number, returning the converted value in 'out' if the * Convert a value to a number, returning the converted value in 'out' if the
* conversion succeeds. v most be a copy of a rooted jsval. * conversion succeeds.
*/ */
JS_ALWAYS_INLINE bool JS_ALWAYS_INLINE bool
ValueToNumber(JSContext *cx, jsval v, double *out) ValueToNumber(JSContext *cx, const js::Value &v, double *out)
{ {
if (JSVAL_IS_INT(v)) { if (v.isNumber()) {
*out = JSVAL_TO_INT(v); *out = v.toNumber();
return true; return true;
} }
if (JSVAL_IS_DOUBLE(v)) { extern bool ValueToNumberSlow(JSContext *, js::Value, double *);
*out = *JSVAL_TO_DOUBLE(v); return ValueToNumberSlow(cx, v, out);
return true;
}
extern jsval ValueToNumberSlow(JSContext *, jsval, double *);
return !JSVAL_IS_NULL(ValueToNumberSlow(cx, v, out));
} }
/* /* Convert a value to a number, replacing 'vp' with the converted value. */
* Convert a value to a number, replacing 'vp' with the converted value and
* returning the value as a double in 'out'. vp must point to a rooted jsval.
*
* N.B. this function will allocate a new double if needed; callers needing
* only a double, not a value, should use ValueToNumber instead.
*/
JS_ALWAYS_INLINE bool JS_ALWAYS_INLINE bool
ValueToNumberValue(JSContext *cx, jsval *vp, double *out) ValueToNumber(JSContext *cx, js::Value *vp)
{ {
jsval v = *vp; if (vp->isNumber())
if (JSVAL_IS_INT(v)) {
*out = JSVAL_TO_INT(v);
return true; return true;
} double d;
if (JSVAL_IS_DOUBLE(v)) { extern bool ValueToNumberSlow(JSContext *, js::Value, double *);
*out = *JSVAL_TO_DOUBLE(v); if (!ValueToNumberSlow(cx, *vp, &d))
return false;
vp->setNumber(d);
return true; return true;
} }
extern bool ValueToNumberValueSlow(JSContext *, jsval *, double *);
return ValueToNumberValueSlow(cx, vp, out);
}
/*
* Convert a value to a number, replacing 'vp' with the converted value. vp
* must point to a rooted jsval.
*
* N.B. this function will allocate a new double if needed; callers needing
* only a double, not a value, should use ValueToNumber instead.
*/
JS_ALWAYS_INLINE bool
ValueToNumberValue(JSContext *cx, jsval *vp)
{
jsval v = *vp;
if (JSVAL_IS_INT(v))
return true;
if (JSVAL_IS_DOUBLE(v))
return true;
extern bool ValueToNumberValueSlow(JSContext *, jsval *);
return ValueToNumberValueSlow(cx, vp);
}
/* /*
* Convert a value to an int32 or uint32, according to the ECMA rules for * Convert a value to an int32 or uint32, according to the ECMA rules for
* ToInt32 and ToUint32. Return converted value on success, !ok on failure. v * ToInt32 and ToUint32. Return converted value in *out on success, !ok on
* must be a copy of a rooted jsval. * failure.
*/ */
JS_ALWAYS_INLINE bool JS_ALWAYS_INLINE bool
ValueToECMAInt32(JSContext *cx, jsval v, int32_t *out) ValueToECMAInt32(JSContext *cx, const js::Value &v, int32_t *out)
{ {
if (JSVAL_IS_INT(v)) { if (v.isInt32()) {
*out = JSVAL_TO_INT(v); *out = v.toInt32();
return true; return true;
} }
extern bool ValueToECMAInt32Slow(JSContext *, jsval, int32_t *); extern bool ValueToECMAInt32Slow(JSContext *, const js::Value &, int32_t *);
return ValueToECMAInt32Slow(cx, v, out); return ValueToECMAInt32Slow(cx, v, out);
} }
JS_ALWAYS_INLINE bool JS_ALWAYS_INLINE bool
ValueToECMAUint32(JSContext *cx, jsval v, uint32_t *out) ValueToECMAUint32(JSContext *cx, const js::Value &v, uint32_t *out)
{ {
if (JSVAL_IS_INT(v)) { if (v.isInt32()) {
*out = (uint32_t)JSVAL_TO_INT(v); *out = (uint32_t)v.toInt32();
return true; return true;
} }
extern bool ValueToECMAUint32Slow(JSContext *, jsval, uint32_t *); extern bool ValueToECMAUint32Slow(JSContext *, const js::Value &, uint32_t *);
return ValueToECMAUint32Slow(cx, v, out); return ValueToECMAUint32Slow(cx, v, out);
} }
/* /*
* Convert a value to a number, then to an int32 if it fits by rounding to * Convert a value to a number, then to an int32 if it fits by rounding to
* nearest. Return converted value on success, !ok on failure. v must be a copy * nearest. Return converted value in *out on success, !ok on failure. As a
* of a rooted jsval. * side effect, *vp will be mutated to match *out.
*/ */
JS_ALWAYS_INLINE bool JS_ALWAYS_INLINE bool
ValueToInt32(JSContext *cx, jsval v, int32_t *out) ValueToInt32(JSContext *cx, const js::Value &v, int32_t *out)
{ {
if (JSVAL_IS_INT(v)) { if (v.isInt32()) {
*out = JSVAL_TO_INT(v); *out = v.toInt32();
return true; return true;
} }
extern bool ValueToInt32Slow(JSContext *, jsval, int32_t *); extern bool ValueToInt32Slow(JSContext *, const js::Value &, int32_t *);
return ValueToInt32Slow(cx, v, out); return ValueToInt32Slow(cx, v, out);
} }
/* /*
* Convert a value to a number, then to a uint16 according to the ECMA rules * Convert a value to a number, then to a uint16 according to the ECMA rules
* for ToUint16. Return converted value on success, !ok on failure. v must be a * for ToUint16. Return converted value on success, !ok on failure. v must be a
* copy of a rooted jsval. * copy of a rooted value.
*/ */
JS_ALWAYS_INLINE bool JS_ALWAYS_INLINE bool
ValueToUint16(JSContext *cx, jsval v, uint16_t *out) ValueToUint16(JSContext *cx, const js::Value &v, uint16_t *out)
{ {
if (JSVAL_IS_INT(v)) { if (v.isInt32()) {
*out = (uint16_t)JSVAL_TO_INT(v); *out = (uint16_t)v.toInt32();
return true; return true;
} }
extern bool ValueToUint16Slow(JSContext *, jsval, uint16_t *); extern bool ValueToUint16Slow(JSContext *, const js::Value &, uint16_t *);
return ValueToUint16Slow(cx, v, out); return ValueToUint16Slow(cx, v, out);
} }
@ -638,6 +571,16 @@ js_strtointeger(JSContext *cx, const jschar *s, const jschar *send,
namespace js { namespace js {
static JS_ALWAYS_INLINE bool
ValueFitsInInt32(const Value &v, int32_t *pi)
{
if (v.isInt32()) {
*pi = v.toInt32();
return true;
}
return v.isDouble() && JSDOUBLE_IS_INT32(v.toDouble(), pi);
}
template<typename T> struct NumberTraits { }; template<typename T> struct NumberTraits { };
template<> struct NumberTraits<int32> { template<> struct NumberTraits<int32> {
static JS_ALWAYS_INLINE int32 NaN() { return 0; } static JS_ALWAYS_INLINE int32 NaN() { return 0; }

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -52,22 +52,52 @@
#include "jshash.h" /* Added by JSIFY */ #include "jshash.h" /* Added by JSIFY */
#include "jspubtd.h" #include "jspubtd.h"
#include "jsprvtd.h" #include "jsprvtd.h"
#include "jsvalue.h"
#include "jsvector.h" #include "jsvector.h"
namespace js { class AutoDescriptorArray; class JSProxyHandler; } namespace js {
class JSProxyHandler;
class AutoPropDescArrayRooter;
static inline PropertyOp
CastAsPropertyOp(JSObject *object)
{
return JS_DATA_TO_FUNC_PTR(PropertyOp, object);
}
static inline JSPropertyOp
CastAsJSPropertyOp(JSObject *object)
{
return JS_DATA_TO_FUNC_PTR(JSPropertyOp, object);
}
inline JSObject *
CastAsObject(PropertyOp op)
{
return JS_FUNC_TO_DATA_PTR(JSObject *, op);
}
inline Value
CastAsObjectJsval(PropertyOp op)
{
return ObjectValue(*CastAsObject(op));
}
} /* namespace js */
/* /*
* A representation of ECMA-262 ed. 5's internal property descriptor data * A representation of ECMA-262 ed. 5's internal property descriptor data
* structure. * structure.
*/ */
struct PropertyDescriptor { struct PropDesc {
friend class js::AutoDescriptorArray; friend class js::AutoPropDescArrayRooter;
PropertyDescriptor(); PropDesc();
public: public:
/* 8.10.5 ToPropertyDescriptor(Obj) */ /* 8.10.5 ToPropertyDescriptor(Obj) */
bool initialize(JSContext* cx, jsid id, jsval v); bool initialize(JSContext* cx, jsid id, const js::Value &v);
/* 8.10.1 IsAccessorDescriptor(desc) */ /* 8.10.1 IsAccessorDescriptor(desc) */
bool isAccessorDescriptor() const { bool isAccessorDescriptor() const {
@ -97,32 +127,32 @@ struct PropertyDescriptor {
} }
JSObject* getterObject() const { JSObject* getterObject() const {
return (get != JSVAL_VOID) ? JSVAL_TO_OBJECT(get) : NULL; return get.isUndefined() ? NULL : &get.toObject();
} }
JSObject* setterObject() const { JSObject* setterObject() const {
return (set != JSVAL_VOID) ? JSVAL_TO_OBJECT(set) : NULL; return set.isUndefined() ? NULL : &set.toObject();
} }
jsval getterValue() const { const js::Value &getterValue() const {
return get; return get;
} }
jsval setterValue() const { const js::Value &setterValue() const {
return set; return set;
} }
JSPropertyOp getter() const { js::PropertyOp getter() const {
return js::CastAsPropertyOp(getterObject()); return js::CastAsPropertyOp(getterObject());
} }
JSPropertyOp setter() const { js::PropertyOp setter() const {
return js::CastAsPropertyOp(setterObject()); return js::CastAsPropertyOp(setterObject());
} }
static void traceDescriptorArray(JSTracer* trc, JSObject* obj); static void traceDescriptorArray(JSTracer* trc, JSObject* obj);
static void finalizeDescriptorArray(JSContext* cx, JSObject* obj); static void finalizeDescriptorArray(JSContext* cx, JSObject* obj);
jsval pd; js::Value pd;
jsid id; jsid id;
jsval value, get, set; js::Value value, get, set;
/* Property descriptor boolean fields. */ /* Property descriptor boolean fields. */
uint8 attrs; uint8 attrs;
@ -137,11 +167,9 @@ struct PropertyDescriptor {
}; };
namespace js { namespace js {
typedef Vector<PropertyDescriptor, 1> PropertyDescriptorArray; typedef Vector<PropDesc, 1> PropDescArray;
} }
JS_BEGIN_EXTERN_C
/* For detailed comments on these function pointer types, see jsprvtd.h. */ /* For detailed comments on these function pointer types, see jsprvtd.h. */
struct JSObjectOps { struct JSObjectOps {
/* /*
@ -153,21 +181,21 @@ struct JSObjectOps {
/* Mandatory non-null function pointer members. */ /* Mandatory non-null function pointer members. */
JSLookupPropOp lookupProperty; JSLookupPropOp lookupProperty;
JSDefinePropOp defineProperty; js::DefinePropOp defineProperty;
JSPropertyIdOp getProperty; js::PropertyIdOp getProperty;
JSPropertyIdOp setProperty; js::PropertyIdOp setProperty;
JSAttributesOp getAttributes; JSAttributesOp getAttributes;
JSAttributesOp setAttributes; JSAttributesOp setAttributes;
JSPropertyIdOp deleteProperty; js::PropertyIdOp deleteProperty;
JSNewEnumerateOp enumerate; js::NewEnumerateOp enumerate;
JSTypeOfOp typeOf; JSTypeOfOp typeOf;
JSTraceOp trace; JSTraceOp trace;
/* Optionally non-null members start here. */ /* Optionally non-null members start here. */
JSObjectOp thisObject; JSObjectOp thisObject;
JSCallOp call; js::CallOp call;
JSNative construct; js::Native construct;
JSHasInstanceOp hasInstance; js::HasInstanceOp hasInstance;
JSFinalizeOp clear; JSFinalizeOp clear;
bool inline isNative() const; bool inline isNative() const;
@ -208,25 +236,18 @@ const uint32 JSSLOT_PARENT = 0;
/* /*
* The first available slot to store generic value. For JSCLASS_HAS_PRIVATE * The first available slot to store generic value. For JSCLASS_HAS_PRIVATE
* classes the slot stores a pointer to private data reinterpreted as jsval. * classes the slot stores a pointer to private data stuffed in a Value.
* Such pointer is stored as is without an overhead of PRIVATE_TO_JSVAL * Such pointer is stored as is without an overhead of PRIVATE_TO_JSVAL
* tagging and should be accessed using the (get|set)Private methods of * tagging and should be accessed using the (get|set)Private methods of
* JSObject. * JSObject.
*/ */
const uint32 JSSLOT_PRIVATE = 1; const uint32 JSSLOT_PRIVATE = 1;
const uintptr_t JSSLOT_CLASS_MASK_BITS = 3;
/* /*
* JSObject struct, with members sized to fit in 32 bytes on 32-bit targets, * JSObject struct, with members sized to fit in 32 bytes on 32-bit targets,
* 64 bytes on 64-bit systems. The JSFunction struct is an extension of this * 64 bytes on 64-bit systems. The JSFunction struct is an extension of this
* struct allocated from a larger GC size-class. * struct allocated from a larger GC size-class.
* *
* The classword member stores the JSClass pointer for this object, with the
* least two bits encoding whether this object is a "delegate" or a "system"
* object. We do *not* synchronize updates of classword -- API clients must
* take care.
*
* An object is a delegate if it is on another object's prototype (linked by * An object is a delegate if it is on another object's prototype (linked by
* JSSLOT_PROTO) or scope (JSSLOT_PARENT) chain, and therefore the delegate * JSSLOT_PROTO) or scope (JSSLOT_PARENT) chain, and therefore the delegate
* might be asked implicitly to get or set a property on behalf of another * might be asked implicitly to get or set a property on behalf of another
@ -242,11 +263,11 @@ const uintptr_t JSSLOT_CLASS_MASK_BITS = 3;
* to be complementary to this bit, but it is up to the API client to implement * to be complementary to this bit, but it is up to the API client to implement
* any such association. * any such association.
* *
* Both these classword tag bits are initially zero; they may be set or queried * Both these flags are initially zero; they may be set or queried using the
* using the (is|set)(Delegate|System) inline methods. * (is|set)(Delegate|System) inline methods.
* *
* The dslots member is null or a pointer into a dynamically allocated vector * The dslots member is null or a pointer into a dynamically allocated vector
* of jsvals for reserved and dynamic slots. If dslots is not null, dslots[-1] * of Values for reserved and dynamic slots. If dslots is not null, dslots[-1]
* records the number of available slots. * records the number of available slots.
*/ */
struct JSObject { struct JSObject {
@ -257,30 +278,42 @@ struct JSObject {
friend class js::TraceRecorder; friend class js::TraceRecorder;
JSObjectMap *map; /* property map, see jsscope.h */ JSObjectMap *map; /* property map, see jsscope.h */
jsuword classword; /* JSClass ptr | bits, see above */ js::Class *clasp; /* class pointer */
jsuword flags; /* see above */
JSObject *proto; /* object's prototype */ JSObject *proto; /* object's prototype */
jsval fslots[JS_INITIAL_NSLOTS]; /* small number of fixed slots */ js::Value *dslots; /* dynamically allocated slots */
jsval *dslots; /* dynamically allocated slots */ #if JS_BITS_PER_WORD == 32
// TODO: this is needed to pad out fslots. alternatively, clasp could be
// merged by with flags and the padding removed, but I think the upcoming
// removal of JSScope will change this all anyway so I will leave this
// here for now.
uint32 padding;
#endif
js::Value fslots[JS_INITIAL_NSLOTS]; /* small number of fixed slots */
bool isNative() const { return map->ops->isNative(); } bool isNative() const { return map->ops->isNative(); }
JSClass *getClass() const { js::Class *getClass() const {
return (JSClass *) (classword & ~JSSLOT_CLASS_MASK_BITS); return clasp;
} }
bool hasClass(const JSClass *clasp) const { JSClass *getJSClass() const {
return clasp == getClass(); return Jsvalify(clasp);
}
bool hasClass(const js::Class *c) const {
return c == clasp;
} }
inline JSScope *scope() const; inline JSScope *scope() const;
inline uint32 shape() const; inline uint32 shape() const;
bool isDelegate() const { bool isDelegate() const {
return (classword & jsuword(1)) != jsuword(0); return (flags & jsuword(1)) != jsuword(0);
} }
void setDelegate() { void setDelegate() {
classword |= jsuword(1); flags |= jsuword(1);
} }
static void setDelegateNullSafe(JSObject *obj) { static void setDelegateNullSafe(JSObject *obj) {
@ -289,15 +322,15 @@ struct JSObject {
} }
bool isSystem() const { bool isSystem() const {
return (classword & jsuword(2)) != jsuword(0); return (flags & jsuword(2)) != jsuword(0);
} }
void setSystem() { void setSystem() {
classword |= jsuword(2); flags |= jsuword(2);
} }
uint32 numSlots(void) const { uint32 numSlots(void) const {
return dslots ? (uint32)dslots[-1] : (uint32)JS_INITIAL_NSLOTS; return dslots ? dslots[-1].toPrivateUint32() : (uint32)JS_INITIAL_NSLOTS;
} }
private: private:
@ -316,31 +349,31 @@ struct JSObject {
bool growSlots(JSContext *cx, size_t nslots); bool growSlots(JSContext *cx, size_t nslots);
void shrinkSlots(JSContext *cx, size_t nslots); void shrinkSlots(JSContext *cx, size_t nslots);
jsval& getSlotRef(uintN slot) { js::Value& getSlotRef(uintN slot) {
return (slot < JS_INITIAL_NSLOTS) return (slot < JS_INITIAL_NSLOTS)
? fslots[slot] ? fslots[slot]
: (JS_ASSERT(slot < (uint32)dslots[-1]), : (JS_ASSERT(slot < dslots[-1].toPrivateUint32()),
dslots[slot - JS_INITIAL_NSLOTS]); dslots[slot - JS_INITIAL_NSLOTS]);
} }
jsval getSlot(uintN slot) const { const js::Value &getSlot(uintN slot) const {
return (slot < JS_INITIAL_NSLOTS) return (slot < JS_INITIAL_NSLOTS)
? fslots[slot] ? fslots[slot]
: (JS_ASSERT(slot < (uint32)dslots[-1]), : (JS_ASSERT(slot < dslots[-1].toPrivateUint32()),
dslots[slot - JS_INITIAL_NSLOTS]); dslots[slot - JS_INITIAL_NSLOTS]);
} }
void setSlot(uintN slot, jsval value) { void setSlot(uintN slot, const js::Value &value) {
if (slot < JS_INITIAL_NSLOTS) { if (slot < JS_INITIAL_NSLOTS) {
fslots[slot] = value; fslots[slot] = value;
} else { } else {
JS_ASSERT(slot < (uint32)dslots[-1]); JS_ASSERT(slot < dslots[-1].toPrivateUint32());
dslots[slot - JS_INITIAL_NSLOTS] = value; dslots[slot - JS_INITIAL_NSLOTS] = value;
} }
} }
inline jsval lockedGetSlot(uintN slot) const; inline const js::Value &lockedGetSlot(uintN slot) const;
inline void lockedSetSlot(uintN slot, jsval value); inline void lockedSetSlot(uintN slot, const js::Value &value);
/* /*
* These ones are for multi-threaded ("MT") objects. Use getSlot(), * These ones are for multi-threaded ("MT") objects. Use getSlot(),
@ -348,10 +381,10 @@ struct JSObject {
* one thread can access obj, or when accessing read-only slots within * one thread can access obj, or when accessing read-only slots within
* JS_INITIAL_NSLOTS. * JS_INITIAL_NSLOTS.
*/ */
inline jsval getSlotMT(JSContext *cx, uintN slot); inline js::Value getSlotMT(JSContext *cx, uintN slot);
inline void setSlotMT(JSContext *cx, uintN slot, jsval value); inline void setSlotMT(JSContext *cx, uintN slot, const js::Value &value);
inline jsval getReservedSlot(uintN index) const; inline js::Value getReservedSlot(uintN index) const;
JSObject *getProto() const { JSObject *getProto() const {
return proto; return proto;
@ -371,11 +404,11 @@ struct JSObject {
} }
JSObject *getParent() const { JSObject *getParent() const {
return JSVAL_TO_OBJECT(fslots[JSSLOT_PARENT]); return fslots[JSSLOT_PARENT].toObjectOrNull();
} }
void clearParent() { void clearParent() {
fslots[JSSLOT_PARENT] = JSVAL_NULL; fslots[JSSLOT_PARENT].setNull();
} }
void setParent(JSObject *newParent) { void setParent(JSObject *newParent) {
@ -384,7 +417,7 @@ struct JSObject {
JS_ASSERT(obj != this); JS_ASSERT(obj != this);
#endif #endif
setDelegateNullSafe(newParent); setDelegateNullSafe(newParent);
fslots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(newParent); fslots[JSSLOT_PARENT].setObjectOrNull(newParent);
} }
void traceProtoAndParent(JSTracer *trc) const { void traceProtoAndParent(JSTracer *trc) const {
@ -398,22 +431,20 @@ struct JSObject {
void *getPrivate() const { void *getPrivate() const {
JS_ASSERT(getClass()->flags & JSCLASS_HAS_PRIVATE); JS_ASSERT(getClass()->flags & JSCLASS_HAS_PRIVATE);
jsval v = fslots[JSSLOT_PRIVATE]; void *priv = fslots[JSSLOT_PRIVATE].toPrivate();
JS_ASSERT((v & jsval(1)) == jsval(0)); return priv;
return reinterpret_cast<void *>(v);
} }
void setPrivate(void *data) { void setPrivate(void *data) {
JS_ASSERT(getClass()->flags & JSCLASS_HAS_PRIVATE); JS_ASSERT(getClass()->flags & JSCLASS_HAS_PRIVATE);
jsval v = reinterpret_cast<jsval>(data); JS_ASSERT((size_t(data) & 1) == 0);
JS_ASSERT((v & jsval(1)) == jsval(0)); fslots[JSSLOT_PRIVATE].setPrivate(data);
fslots[JSSLOT_PRIVATE] = v;
} }
static jsval defaultPrivate(JSClass *clasp) { static js::Value defaultPrivate(js::Class *clasp) {
return (clasp->flags & JSCLASS_HAS_PRIVATE) if (clasp->flags & JSCLASS_HAS_PRIVATE)
? JSVAL_NULL return js::PrivateValue(NULL);
: JSVAL_VOID; return js::UndefinedValue();
} }
/* /*
@ -424,8 +455,8 @@ struct JSObject {
static const uint32 JSSLOT_PRIMITIVE_THIS = JSSLOT_PRIVATE; static const uint32 JSSLOT_PRIMITIVE_THIS = JSSLOT_PRIVATE;
public: public:
inline jsval getPrimitiveThis() const; inline const js::Value &getPrimitiveThis() const;
inline void setPrimitiveThis(jsval pthis); inline void setPrimitiveThis(const js::Value &pthis);
/* /*
* Array-specific getters and setters (for both dense and slow arrays). * Array-specific getters and setters (for both dense and slow arrays).
@ -464,11 +495,11 @@ struct JSObject {
inline bool isDenseArrayMinLenCapOk(bool strictAboutLength = true) const; inline bool isDenseArrayMinLenCapOk(bool strictAboutLength = true) const;
inline jsval getDenseArrayElement(uint32 i) const; inline const js::Value &getDenseArrayElement(uint32 i) const;
inline jsval *addressOfDenseArrayElement(uint32 i); inline js::Value *addressOfDenseArrayElement(uint32 i);
inline void setDenseArrayElement(uint32 i, jsval v); inline void setDenseArrayElement(uint32 i, const js::Value &v);
inline jsval *getDenseArrayElements() const; // returns pointer to the Array's elements array inline js::Value *getDenseArrayElements() const; // returns pointer to the Array's elements array
bool resizeDenseArrayElements(JSContext *cx, uint32 oldcap, uint32 newcap, bool resizeDenseArrayElements(JSContext *cx, uint32 oldcap, uint32 newcap,
bool initializeAllSlots = true); bool initializeAllSlots = true);
bool ensureDenseArrayElements(JSContext *cx, uint32 newcap, bool ensureDenseArrayElements(JSContext *cx, uint32 newcap,
@ -509,11 +540,12 @@ struct JSObject {
inline void setArgsLengthOverridden(); inline void setArgsLengthOverridden();
inline bool isArgsLengthOverridden() const; inline bool isArgsLengthOverridden() const;
inline jsval getArgsCallee() const; inline const js::Value &getArgsCallee() const;
inline void setArgsCallee(jsval callee); inline void setArgsCallee(const js::Value &callee);
inline jsval getArgsElement(uint32 i) const; inline const js::Value &getArgsElement(uint32 i) const;
inline void setArgsElement(uint32 i, jsval v); inline js::Value *addressOfArgsElement(uint32 i) const;
inline void setArgsElement(uint32 i, const js::Value &v);
/* /*
* Date-specific getters and setters. * Date-specific getters and setters.
@ -527,13 +559,11 @@ struct JSObject {
public: public:
static const uint32 DATE_FIXED_RESERVED_SLOTS = 2; static const uint32 DATE_FIXED_RESERVED_SLOTS = 2;
inline jsval getDateLocalTime() const; inline const js::Value &getDateLocalTime() const;
inline jsval *addressOfDateLocalTime(); inline void setDateLocalTime(const js::Value &pthis);
inline void setDateLocalTime(jsval pthis);
inline jsval getDateUTCTime() const; inline const js::Value &getDateUTCTime() const;
inline jsval *addressOfDateUTCTime(); inline void setDateUTCTime(const js::Value &pthis);
inline void setDateUTCTime(jsval pthis);
/* /*
* RegExp-specific getters and setters. * RegExp-specific getters and setters.
@ -545,8 +575,8 @@ struct JSObject {
public: public:
static const uint32 REGEXP_FIXED_RESERVED_SLOTS = 1; static const uint32 REGEXP_FIXED_RESERVED_SLOTS = 1;
inline jsval getRegExpLastIndex() const; inline const js::Value &getRegExpLastIndex() const;
inline jsval *addressOfRegExpLastIndex(); inline void setRegExpLastIndex(const js::Value &v);
inline void zeroRegExpLastIndex(); inline void zeroRegExpLastIndex();
/* /*
@ -596,8 +626,8 @@ struct JSObject {
*/ */
inline js::JSProxyHandler *getProxyHandler() const; inline js::JSProxyHandler *getProxyHandler() const;
inline jsval getProxyPrivate() const; inline const js::Value &getProxyPrivate() const;
inline void setProxyPrivate(jsval priv); inline void setProxyPrivate(const js::Value &priv);
/* /*
* With object-specific getters and setters. * With object-specific getters and setters.
@ -612,22 +642,20 @@ struct JSObject {
inline bool isCallable(); inline bool isCallable();
/* The map field is not initialized here and should be set separately. */ /* The map field is not initialized here and should be set separately. */
void init(JSClass *clasp, JSObject *proto, JSObject *parent, void init(js::Class *aclasp, JSObject *proto, JSObject *parent,
jsval privateSlotValue) { const js::Value &privateSlotValue) {
JS_ASSERT(((jsuword) clasp & 3) == 0);
JS_STATIC_ASSERT(JSSLOT_PRIVATE + 3 == JS_INITIAL_NSLOTS); JS_STATIC_ASSERT(JSSLOT_PRIVATE + 3 == JS_INITIAL_NSLOTS);
JS_ASSERT_IF(clasp->flags & JSCLASS_HAS_PRIVATE,
(privateSlotValue & jsval(1)) == jsval(0));
classword = jsuword(clasp); clasp = aclasp;
flags = 0;
JS_ASSERT(!isDelegate()); JS_ASSERT(!isDelegate());
JS_ASSERT(!isSystem()); JS_ASSERT(!isSystem());
setProto(proto); setProto(proto);
setParent(parent); setParent(parent);
fslots[JSSLOT_PRIVATE] = privateSlotValue; fslots[JSSLOT_PRIVATE] = privateSlotValue;
fslots[JSSLOT_PRIVATE + 1] = JSVAL_VOID; fslots[JSSLOT_PRIVATE + 1].setUndefined();
fslots[JSSLOT_PRIVATE + 2] = JSVAL_VOID; fslots[JSSLOT_PRIVATE + 2].setUndefined();
dslots = NULL; dslots = NULL;
} }
@ -635,8 +663,10 @@ struct JSObject {
* Like init, but also initializes map. The catch: proto must be the result * Like init, but also initializes map. The catch: proto must be the result
* of a call to js_InitClass(...clasp, ...). * of a call to js_InitClass(...clasp, ...).
*/ */
inline void initSharingEmptyScope(JSClass *clasp, JSObject *proto, JSObject *parent, inline void initSharingEmptyScope(js::Class *clasp,
jsval privateSlotValue); JSObject *proto,
JSObject *parent,
const js::Value &privateSlotValue);
inline bool hasSlotsArray() const { return !!dslots; } inline bool hasSlotsArray() const { return !!dslots; }
@ -648,18 +678,18 @@ struct JSObject {
return map->ops->lookupProperty(cx, this, id, objp, propp); return map->ops->lookupProperty(cx, this, id, objp, propp);
} }
JSBool defineProperty(JSContext *cx, jsid id, jsval value, JSBool defineProperty(JSContext *cx, jsid id, const js::Value &value,
JSPropertyOp getter = JS_PropertyStub, js::PropertyOp getter = js::PropertyStub,
JSPropertyOp setter = JS_PropertyStub, js::PropertyOp setter = js::PropertyStub,
uintN attrs = JSPROP_ENUMERATE) { uintN attrs = JSPROP_ENUMERATE) {
return map->ops->defineProperty(cx, this, id, value, getter, setter, attrs); return map->ops->defineProperty(cx, this, id, &value, getter, setter, attrs);
} }
JSBool getProperty(JSContext *cx, jsid id, jsval *vp) { JSBool getProperty(JSContext *cx, jsid id, js::Value *vp) {
return map->ops->getProperty(cx, this, id, vp); return map->ops->getProperty(cx, this, id, vp);
} }
JSBool setProperty(JSContext *cx, jsid id, jsval *vp) { JSBool setProperty(JSContext *cx, jsid id, js::Value *vp) {
return map->ops->setProperty(cx, this, id, vp); return map->ops->setProperty(cx, this, id, vp);
} }
@ -671,11 +701,11 @@ struct JSObject {
return map->ops->setAttributes(cx, this, id, attrsp); return map->ops->setAttributes(cx, this, id, attrsp);
} }
JSBool deleteProperty(JSContext *cx, jsid id, jsval *rval) { JSBool deleteProperty(JSContext *cx, jsid id, js::Value *rval) {
return map->ops->deleteProperty(cx, this, id, rval); return map->ops->deleteProperty(cx, this, id, rval);
} }
JSBool enumerate(JSContext *cx, JSIterateOp op, jsval *statep, JSBool enumerate(JSContext *cx, JSIterateOp op, js::Value *statep,
jsid *idp) { jsid *idp) {
return map->ops->enumerate(cx, this, op, statep, idp); return map->ops->enumerate(cx, this, op, statep, idp);
} }
@ -690,6 +720,7 @@ struct JSObject {
JSObject *thisObject(JSContext *cx) { JSObject *thisObject(JSContext *cx) {
return map->ops->thisObject ? map->ops->thisObject(cx, this) : this; return map->ops->thisObject ? map->ops->thisObject(cx, this) : this;
} }
static bool thisObject(JSContext *cx, const js::Value &v, js::Value *vp);
inline void dropProperty(JSContext *cx, JSProperty *prop); inline void dropProperty(JSContext *cx, JSProperty *prop);
@ -720,8 +751,13 @@ struct JSObject {
JS_FRIEND_API(JSObject *) unwrap(uintN *flagsp = NULL); JS_FRIEND_API(JSObject *) unwrap(uintN *flagsp = NULL);
inline bool unbrand(JSContext *cx); inline bool unbrand(JSContext *cx);
inline void initArrayClass();
}; };
JS_STATIC_ASSERT(offsetof(JSObject, fslots) % sizeof(js::Value) == 0);
JS_STATIC_ASSERT(sizeof(JSObject) % JS_GCTHING_ALIGN == 0);
#define JSSLOT_START(clasp) (((clasp)->flags & JSCLASS_HAS_PRIVATE) \ #define JSSLOT_START(clasp) (((clasp)->flags & JSCLASS_HAS_PRIVATE) \
? JSSLOT_PRIVATE + 1 \ ? JSSLOT_PRIVATE + 1 \
: JSSLOT_PRIVATE) : JSSLOT_PRIVATE)
@ -734,8 +770,8 @@ struct JSObject {
* obj->dslots[-1] that is used to store the length of the vector biased by * obj->dslots[-1] that is used to store the length of the vector biased by
* JS_INITIAL_NSLOTS (and again net of the slot at index -1). * JS_INITIAL_NSLOTS (and again net of the slot at index -1).
*/ */
#define MAX_DSLOTS_LENGTH (~size_t(0) / sizeof(jsval) - 1) #define MAX_DSLOTS_LENGTH (~size_t(0) / sizeof(js::Value) - 1)
#define MAX_DSLOTS_LENGTH32 (~uint32(0) / sizeof(jsval) - 1) #define MAX_DSLOTS_LENGTH32 (~uint32(0) / sizeof(js::Value) - 1)
#define OBJ_CHECK_SLOT(obj,slot) \ #define OBJ_CHECK_SLOT(obj,slot) \
(JS_ASSERT((obj)->isNative()), JS_ASSERT(slot < (obj)->scope()->freeslot)) (JS_ASSERT((obj)->isNative()), JS_ASSERT(slot < (obj)->scope()->freeslot))
@ -758,9 +794,9 @@ struct JSObject {
inline void inline void
OBJ_TO_INNER_OBJECT(JSContext *cx, JSObject *&obj) OBJ_TO_INNER_OBJECT(JSContext *cx, JSObject *&obj)
{ {
JSClass *clasp = obj->getClass(); js::Class *clasp = obj->getClass();
if (clasp->flags & JSCLASS_IS_EXTENDED) { if (clasp->flags & JSCLASS_IS_EXTENDED) {
JSExtendedClass *xclasp = (JSExtendedClass *) clasp; js::ExtendedClass *xclasp = (js::ExtendedClass *) clasp;
if (xclasp->innerObject) if (xclasp->innerObject)
obj = xclasp->innerObject(cx, obj); obj = xclasp->innerObject(cx, obj);
} }
@ -773,25 +809,33 @@ OBJ_TO_INNER_OBJECT(JSContext *cx, JSObject *&obj)
inline void inline void
OBJ_TO_OUTER_OBJECT(JSContext *cx, JSObject *&obj) OBJ_TO_OUTER_OBJECT(JSContext *cx, JSObject *&obj)
{ {
JSClass *clasp = obj->getClass(); js::Class *clasp = obj->getClass();
if (clasp->flags & JSCLASS_IS_EXTENDED) { if (clasp->flags & JSCLASS_IS_EXTENDED) {
JSExtendedClass *xclasp = (JSExtendedClass *) clasp; js::ExtendedClass *xclasp = (js::ExtendedClass *) clasp;
if (xclasp->outerObject) if (xclasp->outerObject)
obj = xclasp->outerObject(cx, obj); obj = xclasp->outerObject(cx, obj);
} }
} }
class ValueArray { class JSValueArray {
public: public:
jsval *array; jsval *array;
size_t length; size_t length;
ValueArray(jsval *v, size_t c) : array(v), length(c) {} JSValueArray(jsval *v, size_t c) : array(v), length(c) {}
}; };
extern JSClass js_ObjectClass; class ValueArray {
extern JSClass js_WithClass; public:
extern JSClass js_BlockClass; js::Value *array;
size_t length;
ValueArray(js::Value *v, size_t c) : array(v), length(c) {}
};
extern js::Class js_ObjectClass;
extern js::Class js_WithClass;
extern js::Class js_BlockClass;
/* /*
* Block scope object macros. The slots reserved by js_BlockClass are: * Block scope object macros. The slots reserved by js_BlockClass are:
@ -824,9 +868,9 @@ js_DefineBlockVariable(JSContext *cx, JSObject *obj, jsid id, intN index);
#define OBJ_BLOCK_COUNT(cx,obj) \ #define OBJ_BLOCK_COUNT(cx,obj) \
((OBJ_IS_CLONED_BLOCK(obj) ? obj->getProto() : obj)->scope()->entryCount) ((OBJ_IS_CLONED_BLOCK(obj) ? obj->getProto() : obj)->scope()->entryCount)
#define OBJ_BLOCK_DEPTH(cx,obj) \ #define OBJ_BLOCK_DEPTH(cx,obj) \
JSVAL_TO_INT(obj->getSlot(JSSLOT_BLOCK_DEPTH)) obj->getSlot(JSSLOT_BLOCK_DEPTH).toInt32()
#define OBJ_SET_BLOCK_DEPTH(cx,obj,depth) \ #define OBJ_SET_BLOCK_DEPTH(cx,obj,depth) \
obj->setSlot(JSSLOT_BLOCK_DEPTH, INT_TO_JSVAL(depth)) obj->setSlot(JSSLOT_BLOCK_DEPTH, Value(Int32Value(depth)))
/* /*
* To make sure this slot is well-defined, always call js_NewWithObject to * To make sure this slot is well-defined, always call js_NewWithObject to
@ -895,21 +939,23 @@ js_TraceSharpMap(JSTracer *trc, JSSharpObjectMap *map);
extern JSBool extern JSBool
js_HasOwnPropertyHelper(JSContext *cx, JSLookupPropOp lookup, uintN argc, js_HasOwnPropertyHelper(JSContext *cx, JSLookupPropOp lookup, uintN argc,
jsval *vp); js::Value *vp);
extern JSBool extern JSBool
js_HasOwnProperty(JSContext *cx, JSLookupPropOp lookup, JSObject *obj, jsid id, js_HasOwnProperty(JSContext *cx, JSLookupPropOp lookup, JSObject *obj, jsid id,
JSObject **objp, JSProperty **propp); JSObject **objp, JSProperty **propp);
extern JSBool extern JSBool
js_NewPropertyDescriptorObject(JSContext *cx, jsid id, uintN attrs, jsval getter, jsval setter, jsval value, jsval *vp); js_NewPropertyDescriptorObject(JSContext *cx, jsid id, uintN attrs,
const js::Value &getter, const js::Value &setter,
const js::Value &value, js::Value *vp);
extern JSBool extern JSBool
js_PropertyIsEnumerable(JSContext *cx, JSObject *obj, jsid id, jsval *vp); js_PropertyIsEnumerable(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
#ifdef OLD_GETTER_SETTER_METHODS #ifdef OLD_GETTER_SETTER_METHODS
JS_FRIEND_API(JSBool) js_obj_defineGetter(JSContext *cx, uintN argc, jsval *vp); JS_FRIEND_API(JSBool) js_obj_defineGetter(JSContext *cx, uintN argc, js::Value *vp);
JS_FRIEND_API(JSBool) js_obj_defineSetter(JSContext *cx, uintN argc, jsval *vp); JS_FRIEND_API(JSBool) js_obj_defineSetter(JSContext *cx, uintN argc, js::Value *vp);
#endif #endif
extern JSObject * extern JSObject *
@ -917,7 +963,7 @@ js_InitObjectClass(JSContext *cx, JSObject *obj);
extern JSObject * extern JSObject *
js_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto, js_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
JSClass *clasp, JSNative constructor, uintN nargs, js::Class *clasp, js::Native constructor, uintN nargs,
JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *ps, JSFunctionSpec *fs,
JSPropertySpec *static_ps, JSFunctionSpec *static_fs); JSPropertySpec *static_ps, JSFunctionSpec *static_fs);
@ -950,8 +996,8 @@ extern const char js_lookupSetter_str[];
* object, not by the parent of its .prototype object value. * object, not by the parent of its .prototype object value.
*/ */
extern JSObject* extern JSObject*
js_NewObjectWithClassProto(JSContext *cx, JSClass *clasp, JSObject *proto, js_NewObjectWithClassProto(JSContext *cx, js::Class *clasp, JSObject *proto,
jsval privateSlotValue); const js::Value &privateSlotValue);
extern JSBool extern JSBool
js_PopulateObject(JSContext *cx, JSObject *newborn, JSObject *props); js_PopulateObject(JSContext *cx, JSObject *newborn, JSObject *props);
@ -972,12 +1018,12 @@ js_SetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key,
* JSProto_Null, clasp must non-null. * JSProto_Null, clasp must non-null.
*/ */
extern JSBool extern JSBool
js_FindClassObject(JSContext *cx, JSObject *start, JSProtoKey key, jsval *vp, js_FindClassObject(JSContext *cx, JSObject *start, JSProtoKey key,
JSClass *clasp = NULL); js::Value *vp, js::Class *clasp = NULL);
extern JSObject * extern JSObject *
js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto, js_ConstructObject(JSContext *cx, js::Class *clasp, JSObject *proto,
JSObject *parent, uintN argc, jsval *argv); JSObject *parent, uintN argc, js::Value *argv);
extern JSBool extern JSBool
js_AllocSlot(JSContext *cx, JSObject *obj, uint32 *slotp); js_AllocSlot(JSContext *cx, JSObject *obj, uint32 *slotp);
@ -1021,7 +1067,7 @@ js_PurgeScopeChain(JSContext *cx, JSObject *obj, jsid id)
*/ */
extern JSScopeProperty * extern JSScopeProperty *
js_AddNativeProperty(JSContext *cx, JSObject *obj, jsid id, js_AddNativeProperty(JSContext *cx, JSObject *obj, jsid id,
JSPropertyOp getter, JSPropertyOp setter, uint32 slot, js::PropertyOp getter, js::PropertyOp setter, uint32 slot,
uintN attrs, uintN flags, intN shortid); uintN attrs, uintN flags, intN shortid);
/* /*
@ -1032,14 +1078,15 @@ js_AddNativeProperty(JSContext *cx, JSObject *obj, jsid id,
extern JSScopeProperty * extern JSScopeProperty *
js_ChangeNativePropertyAttrs(JSContext *cx, JSObject *obj, js_ChangeNativePropertyAttrs(JSContext *cx, JSObject *obj,
JSScopeProperty *sprop, uintN attrs, uintN mask, JSScopeProperty *sprop, uintN attrs, uintN mask,
JSPropertyOp getter, JSPropertyOp setter); js::PropertyOp getter, js::PropertyOp setter);
extern JSBool extern JSBool
js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value, js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, const js::Value *value,
JSPropertyOp getter, JSPropertyOp setter, uintN attrs); js::PropertyOp getter, js::PropertyOp setter, uintN attrs);
extern JSBool extern JSBool
js_DefineOwnProperty(JSContext *cx, JSObject *obj, jsid id, jsval descriptor, JSBool *bp); js_DefineOwnProperty(JSContext *cx, JSObject *obj, jsid id,
const js::Value &descriptor, JSBool *bp);
/* /*
* Flags for the defineHow parameter of js_DefineNativeProperty. * Flags for the defineHow parameter of js_DefineNativeProperty.
@ -1061,8 +1108,8 @@ const uintN JSDNP_UNQUALIFIED = 8; /* Unqualified property set. Only used in
* the held property, and to release the lock on obj. * the held property, and to release the lock on obj.
*/ */
extern JSBool extern JSBool
js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, jsval value, js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const js::Value &value,
JSPropertyOp getter, JSPropertyOp setter, uintN attrs, js::PropertyOp getter, js::PropertyOp setter, uintN attrs,
uintN flags, intN shortid, JSProperty **propp, uintN flags, intN shortid, JSProperty **propp,
uintN defineHow = 0); uintN defineHow = 0);
@ -1095,11 +1142,11 @@ js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
static inline bool static inline bool
js_IsCacheableNonGlobalScope(JSObject *obj) js_IsCacheableNonGlobalScope(JSObject *obj)
{ {
extern JS_FRIEND_DATA(JSClass) js_CallClass; extern JS_FRIEND_DATA(js::Class) js_CallClass;
extern JS_FRIEND_DATA(JSClass) js_DeclEnvClass; extern JS_FRIEND_DATA(js::Class) js_DeclEnvClass;
JS_ASSERT(obj->getParent()); JS_ASSERT(obj->getParent());
JSClass *clasp = obj->getClass(); js::Class *clasp = obj->getClass();
bool cacheable = (clasp == &js_CallClass || bool cacheable = (clasp == &js_CallClass ||
clasp == &js_BlockClass || clasp == &js_BlockClass ||
clasp == &js_DeclEnvClass); clasp == &js_DeclEnvClass);
@ -1154,24 +1201,24 @@ const uintN JSGET_NO_METHOD_BARRIER = 2; // call to joined function can't leak
*/ */
extern JSBool extern JSBool
js_NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj, js_NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj,
JSScopeProperty *sprop, uintN getHow, jsval *vp); JSScopeProperty *sprop, uintN getHow, js::Value *vp);
extern JSBool extern JSBool
js_NativeSet(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, bool added, js_NativeSet(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, bool added,
jsval *vp); js::Value *vp);
extern JSBool extern JSBool
js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN getHow, js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN getHow,
jsval *vp); js::Value *vp);
extern JSBool extern JSBool
js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp); js_GetProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
extern JSBool extern JSBool
js_GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, jsval *vp); js_GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
extern JSBool extern JSBool
js_GetMethod(JSContext *cx, JSObject *obj, jsid id, uintN getHow, jsval *vp); js_GetMethod(JSContext *cx, JSObject *obj, jsid id, uintN getHow, js::Value *vp);
/* /*
* Check whether it is OK to assign an undeclared property with name * Check whether it is OK to assign an undeclared property with name
@ -1180,14 +1227,14 @@ js_GetMethod(JSContext *cx, JSObject *obj, jsid id, uintN getHow, jsval *vp);
* when it returns false). * when it returns false).
*/ */
extern JS_FRIEND_API(bool) extern JS_FRIEND_API(bool)
js_CheckUndeclaredVarAssignment(JSContext *cx, jsval propname); js_CheckUndeclaredVarAssignment(JSContext *cx, JSString *propname);
extern JSBool extern JSBool
js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow, js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow,
jsval *vp); js::Value *vp);
extern JSBool extern JSBool
js_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp); js_SetProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
extern JSBool extern JSBool
js_GetAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp); js_GetAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp);
@ -1204,24 +1251,24 @@ js_SetNativeAttributes(JSContext *cx, JSObject *obj, JSScopeProperty *sprop,
uintN attrs); uintN attrs);
extern JSBool extern JSBool
js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval); js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *rval);
namespace js { namespace js {
extern JSBool extern JSBool
DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp); DefaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp);
} }
extern JSBool extern JSBool
js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
jsval *statep, jsid *idp); js::Value *statep, jsid *idp);
namespace js { namespace js {
extern JSBool extern JSBool
CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
jsval *vp, uintN *attrsp); js::Value *vp, uintN *attrsp);
} }
@ -1229,17 +1276,17 @@ extern JSType
js_TypeOf(JSContext *cx, JSObject *obj); js_TypeOf(JSContext *cx, JSObject *obj);
extern JSBool extern JSBool
js_Call(JSContext *cx, uintN argc, jsval *vp); js_Call(JSContext *cx, uintN argc, js::Value *vp);
extern JSBool extern JSBool
js_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, js_Construct(JSContext *cx, JSObject *obj, uintN argc, js::Value *argv,
jsval *rval); js::Value *rval);
extern JSBool extern JSBool
js_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp); js_HasInstance(JSContext *cx, JSObject *obj, const js::Value *v, JSBool *bp);
extern JSBool extern bool
js_IsDelegate(JSContext *cx, JSObject *obj, jsval v, JSBool *bp); js_IsDelegate(JSContext *cx, JSObject *obj, const js::Value &v);
/* /*
* If protoKey is not JSProto_Null, then clasp is ignored. If protoKey is * If protoKey is not JSProto_Null, then clasp is ignored. If protoKey is
@ -1247,7 +1294,7 @@ js_IsDelegate(JSContext *cx, JSObject *obj, jsval v, JSBool *bp);
*/ */
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
js_GetClassPrototype(JSContext *cx, JSObject *scope, JSProtoKey protoKey, js_GetClassPrototype(JSContext *cx, JSObject *scope, JSProtoKey protoKey,
JSObject **protop, JSClass *clasp = NULL); JSObject **protop, js::Class *clasp = NULL);
extern JSBool extern JSBool
js_SetClassPrototype(JSContext *cx, JSObject *ctor, JSObject *proto, js_SetClassPrototype(JSContext *cx, JSObject *ctor, JSObject *proto,
@ -1258,20 +1305,28 @@ js_SetClassPrototype(JSContext *cx, JSObject *ctor, JSObject *proto,
* *vp must not be an object, null or undefined. * *vp must not be an object, null or undefined.
*/ */
extern JSBool extern JSBool
js_PrimitiveToObject(JSContext *cx, jsval *vp); js_PrimitiveToObject(JSContext *cx, js::Value *vp);
/*
* v and vp may alias. On successful return, vp->isObjectOrNull(). If vp is not
* rooted, the caller must root vp before the next possible GC.
*/
extern JSBool extern JSBool
js_ValueToObject(JSContext *cx, jsval v, JSObject **objp); js_ValueToObjectOrNull(JSContext *cx, const js::Value &v, JSObject **objp);
/*
* v and vp may alias. On successful return, vp->isObject(). If vp is not
* rooted, the caller must root vp before the next possible GC.
*/
extern JSObject * extern JSObject *
js_ValueToNonNullObject(JSContext *cx, jsval v); js_ValueToNonNullObject(JSContext *cx, const js::Value &v);
extern JSBool extern JSBool
js_TryValueOf(JSContext *cx, JSObject *obj, JSType type, jsval *rval); js_TryValueOf(JSContext *cx, JSObject *obj, JSType type, js::Value *rval);
extern JSBool extern JSBool
js_TryMethod(JSContext *cx, JSObject *obj, JSAtom *atom, js_TryMethod(JSContext *cx, JSObject *obj, JSAtom *atom,
uintN argc, jsval *argv, jsval *rval); uintN argc, js::Value *argv, js::Value *rval);
extern JSBool extern JSBool
js_XDRObject(JSXDRState *xdr, JSObject **objp); js_XDRObject(JSXDRState *xdr, JSObject **objp);
@ -1286,18 +1341,14 @@ extern void
js_Clear(JSContext *cx, JSObject *obj); js_Clear(JSContext *cx, JSObject *obj);
extern bool extern bool
js_GetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval *vp); js_GetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, js::Value *vp);
extern bool extern bool
js_SetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval v); js_SetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, const js::Value &v);
/* /*
* Precondition: obj must be locked. * Precondition: obj must be locked.
*/ */
extern JSBool
js_ReallocSlots(JSContext *cx, JSObject *obj, uint32 nslots,
JSBool exactAllocation);
extern JSObject * extern JSObject *
js_CheckScopeChainValidity(JSContext *cx, JSObject *scopeobj, const char *caller); js_CheckScopeChainValidity(JSContext *cx, JSObject *scopeobj, const char *caller);
@ -1322,15 +1373,15 @@ extern JSBool
js_ReportGetterOnlyAssignment(JSContext *cx); js_ReportGetterOnlyAssignment(JSContext *cx);
extern JS_FRIEND_API(JSBool) extern JS_FRIEND_API(JSBool)
js_GetterOnlyPropertyStub(JSContext *cx, JSObject *obj, jsval id, jsval *vp); js_GetterOnlyPropertyStub(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
#ifdef DEBUG #ifdef DEBUG
JS_FRIEND_API(void) js_DumpChars(const jschar *s, size_t n); JS_FRIEND_API(void) js_DumpChars(const jschar *s, size_t n);
JS_FRIEND_API(void) js_DumpString(JSString *str); JS_FRIEND_API(void) js_DumpString(JSString *str);
JS_FRIEND_API(void) js_DumpAtom(JSAtom *atom); JS_FRIEND_API(void) js_DumpAtom(JSAtom *atom);
JS_FRIEND_API(void) js_DumpValue(jsval val);
JS_FRIEND_API(void) js_DumpId(jsid id);
JS_FRIEND_API(void) js_DumpObject(JSObject *obj); JS_FRIEND_API(void) js_DumpObject(JSObject *obj);
JS_FRIEND_API(void) js_DumpValue(const js::Value &val);
JS_FRIEND_API(void) js_DumpId(jsid id);
JS_FRIEND_API(void) js_DumpStackFrame(JSContext *cx, JSStackFrame *start = NULL); JS_FRIEND_API(void) js_DumpStackFrame(JSContext *cx, JSStackFrame *start = NULL);
#endif #endif
@ -1339,9 +1390,8 @@ js_InferFlags(JSContext *cx, uintN defaultFlags);
/* Object constructor native. Exposed only so the JIT can know its address. */ /* Object constructor native. Exposed only so the JIT can know its address. */
JSBool JSBool
js_Object(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); js_Object(JSContext *cx, JSObject *obj, uintN argc, js::Value *argv, js::Value *rval);
JS_END_EXTERN_C
namespace js { namespace js {
@ -1356,5 +1406,4 @@ extern JSString *
obj_toStringHelper(JSContext *cx, JSObject *obj); obj_toStringHelper(JSContext *cx, JSObject *obj);
} }
#endif /* jsobj_h___ */ #endif /* jsobj_h___ */

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше