mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
[JAEGER] Merge from fatval.
This commit is contained in:
commit
dff194f865
@ -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* vp, 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;
|
||||||
|
|
||||||
@ -1105,7 +1105,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;
|
||||||
@ -1132,7 +1132,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)) {
|
||||||
@ -1213,7 +1213,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)) {
|
||||||
@ -1275,7 +1275,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)) {
|
||||||
@ -1338,7 +1338,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;
|
||||||
}
|
}
|
||||||
@ -1371,7 +1371,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);
|
||||||
@ -1858,11 +1858,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, Jsvalify(item.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, Jsvalify(item.value()), baseType, data, false, NULL))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1883,7 +1883,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);
|
||||||
@ -1902,26 +1902,25 @@ ImplicitConvert(JSContext* cx,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
js::AutoValueRooter fieldVal(cx);
|
js::AutoValueRooter fieldVal(cx);
|
||||||
if (!JS_IdToValue(cx, id, fieldVal.addr()))
|
JS_IdToValue(cx, id, Jsvalify(fieldVal.addr()));
|
||||||
return false;
|
if (!fieldVal.value().isString()) {
|
||||||
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());
|
Jsvalify(fieldVal.value()));
|
||||||
if (!field)
|
if (!field)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
JSString* name = JSVAL_TO_STRING(fieldVal.value());
|
JSString* name = fieldVal.value().asString();
|
||||||
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(), Jsvalify(prop.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, Jsvalify(prop.value()), field->mType, fieldData, false, NULL))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
++i;
|
++i;
|
||||||
@ -1962,7 +1961,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, Jsvalify(ex.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
|
||||||
@ -2010,7 +2009,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, Jsvalify(ex.value()));
|
||||||
return false;
|
return false;
|
||||||
case TYPE_void_t:
|
case TYPE_void_t:
|
||||||
case TYPE_function:
|
case TYPE_function:
|
||||||
@ -2528,7 +2527,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)) ||
|
||||||
@ -2543,7 +2542,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))
|
||||||
@ -2581,7 +2580,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,
|
||||||
@ -2807,7 +2806,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2830,7 +2829,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
|
||||||
@ -2943,7 +2942,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");
|
||||||
@ -2956,7 +2955,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");
|
||||||
@ -2972,7 +2971,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");
|
||||||
@ -2985,7 +2984,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");
|
||||||
@ -3078,7 +3077,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* vp, JSBool* bp)
|
||||||
{
|
{
|
||||||
JS_ASSERT(CType::IsCType(cx, obj));
|
JS_ASSERT(CType::IsCType(cx, obj));
|
||||||
|
|
||||||
@ -3089,10 +3088,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(*vp))
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
|
|
||||||
JSObject* proto = JSVAL_TO_OBJECT(v);
|
JSObject* proto = JSVAL_TO_OBJECT(*vp);
|
||||||
while ((proto = JS_GetPrototype(cx, proto))) {
|
while ((proto = JS_GetPrototype(cx, proto))) {
|
||||||
if (proto == prototype) {
|
if (proto == prototype) {
|
||||||
*bp = JS_TRUE;
|
*bp = JS_TRUE;
|
||||||
@ -3152,7 +3151,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)))
|
||||||
@ -3237,7 +3236,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) {
|
||||||
@ -3277,7 +3276,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)) {
|
||||||
@ -3315,7 +3314,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)) {
|
||||||
@ -3422,7 +3421,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)))
|
||||||
@ -3477,8 +3476,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", Jsvalify(lengthVal.addr())) ||
|
||||||
!jsvalToSize(cx, lengthVal.value(), false, &length)) {
|
!jsvalToSize(cx, Jsvalify(lengthVal.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;
|
||||||
}
|
}
|
||||||
@ -3521,7 +3520,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)
|
||||||
@ -3565,7 +3564,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3589,7 +3588,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*
|
||||||
@ -3636,7 +3635,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");
|
||||||
@ -3649,7 +3648,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.
|
||||||
@ -3667,7 +3666,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)) {
|
||||||
@ -3702,7 +3701,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)) {
|
||||||
@ -3762,7 +3761,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);
|
||||||
@ -3805,20 +3804,19 @@ 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;
|
||||||
|
|
||||||
js::AutoValueRooter nameVal(cx);
|
js::AutoValueRooter nameVal(cx);
|
||||||
if (!JS_IdToValue(cx, id, nameVal.addr()))
|
JS_IdToValue(cx, id, Jsvalify(nameVal.addr()));
|
||||||
return NULL;
|
if (!nameVal.value().isString()) {
|
||||||
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());
|
JSString* name = nameVal.value().asString();
|
||||||
|
|
||||||
// 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))
|
||||||
@ -3829,11 +3827,11 @@ ExtractStructField(JSContext* cx, jsval val, JSObject** typeObj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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(), Jsvalify(propVal.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, &propVal.value().asObject())) {
|
||||||
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;
|
||||||
}
|
}
|
||||||
@ -3841,7 +3839,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 = &propVal.value().asObject();
|
||||||
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");
|
||||||
@ -3902,7 +3900,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]) ||
|
||||||
@ -3937,7 +3935,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))
|
||||||
@ -3967,11 +3965,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, Jsvalify(item.addr())))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
|
|
||||||
JSObject* fieldType;
|
JSObject* fieldType;
|
||||||
JSString* name = ExtractStructField(cx, item.value(), &fieldType);
|
JSString* name = ExtractStructField(cx, Jsvalify(item.value()), &fieldType);
|
||||||
if (!name)
|
if (!name)
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
|
|
||||||
@ -4268,10 +4266,10 @@ StructType::BuildFieldsArray(JSContext* cx, JSObject* obj)
|
|||||||
// Prepare a new array for the 'fields' property of the StructType.
|
// Prepare a new array for the 'fields' property of the StructType.
|
||||||
jsval* fieldsVec;
|
jsval* fieldsVec;
|
||||||
JSObject* fieldsProp =
|
JSObject* fieldsProp =
|
||||||
js_NewArrayObjectWithCapacity(cx, len, &fieldsVec);
|
js_NewArrayObjectWithCapacity(cx, len, Valueify(&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()) {
|
||||||
@ -4290,7 +4288,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");
|
||||||
@ -4320,7 +4318,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");
|
||||||
@ -4342,7 +4340,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");
|
||||||
@ -4393,7 +4391,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);
|
||||||
@ -4689,7 +4687,7 @@ FunctionType::Create(JSContext* cx, uintN argc, jsval* vp)
|
|||||||
|
|
||||||
// Pull out the argument types from the array, if any.
|
// Pull out the argument types from the array, if any.
|
||||||
JS_ASSERT(!argTypes.length() || arrayObj);
|
JS_ASSERT(!argTypes.length() || arrayObj);
|
||||||
js::AutoArrayRooter items(cx, argTypes.length(), argTypes.begin());
|
js::AutoArrayRooter items(cx, argTypes.length(), Valueify(argTypes.begin()));
|
||||||
for (jsuint i = 0; i < argTypes.length(); ++i) {
|
for (jsuint i = 0; i < argTypes.length(); ++i) {
|
||||||
if (!JS_GetElement(cx, arrayObj, i, &argTypes[i]))
|
if (!JS_GetElement(cx, arrayObj, i, &argTypes[i]))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
@ -4728,7 +4726,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,
|
||||||
@ -4759,7 +4757,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,
|
||||||
@ -4944,7 +4942,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;
|
||||||
@ -4960,10 +4958,10 @@ FunctionType::ArgTypesGetter(JSContext* cx, JSObject* obj, jsval idval, jsval* v
|
|||||||
// Prepare a new array.
|
// Prepare a new array.
|
||||||
jsval* vec;
|
jsval* vec;
|
||||||
JSObject* argTypes =
|
JSObject* argTypes =
|
||||||
js_NewArrayObjectWithCapacity(cx, len, &vec);
|
js_NewArrayObjectWithCapacity(cx, len, Valueify(&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)
|
||||||
@ -4979,7 +4977,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;
|
||||||
@ -4990,7 +4988,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;
|
||||||
@ -5001,7 +4999,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;
|
||||||
@ -5024,7 +5022,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);
|
||||||
@ -5176,7 +5174,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;
|
||||||
@ -5188,7 +5186,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.
|
||||||
@ -5262,7 +5260,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)))
|
||||||
@ -5368,7 +5366,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");
|
||||||
@ -5383,7 +5381,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");
|
||||||
@ -5413,7 +5411,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);
|
||||||
@ -5616,7 +5614,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);
|
||||||
|
@ -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).
|
||||||
|
@ -539,6 +539,11 @@ JSRuntime::init(uint32 maxbytes)
|
|||||||
if (!js_InitGC(this, maxbytes) || !js_InitAtomState(this))
|
if (!js_InitGC(this, maxbytes) || !js_InitAtomState(this))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
#ifdef _M_X64
|
||||||
|
if (!JSString::initStringTables())
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
deflatedStringCache = new js::DeflatedStringCache();
|
deflatedStringCache = new js::DeflatedStringCache();
|
||||||
if (!deflatedStringCache || !deflatedStringCache->init())
|
if (!deflatedStringCache || !deflatedStringCache->init())
|
||||||
return false;
|
return false;
|
||||||
@ -2531,7 +2536,6 @@ JS_DestroyIdArray(JSContext *cx, JSIdArray *ida)
|
|||||||
JS_PUBLIC_API(jsval)
|
JS_PUBLIC_API(jsval)
|
||||||
JSID_TO_JSVAL(jsid id)
|
JSID_TO_JSVAL(jsid id)
|
||||||
{
|
{
|
||||||
CHECK_REQUEST(cx);
|
|
||||||
return Jsvalify(IdToValue(id));
|
return Jsvalify(IdToValue(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2594,7 +2598,7 @@ JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
|
|||||||
JS_PUBLIC_API(JSClass *)
|
JS_PUBLIC_API(JSClass *)
|
||||||
JS_GetClass(JSContext *cx, JSObject *obj)
|
JS_GetClass(JSContext *cx, JSObject *obj)
|
||||||
{
|
{
|
||||||
return obj->getClass();
|
return Jsvalify(obj->getClass());
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
JS_PUBLIC_API(JSClass *)
|
JS_PUBLIC_API(JSClass *)
|
||||||
|
264
js/src/jsapi.h
264
js/src/jsapi.h
@ -52,12 +52,12 @@
|
|||||||
JS_BEGIN_EXTERN_C
|
JS_BEGIN_EXTERN_C
|
||||||
|
|
||||||
/* Well-known JS values, initialized on startup. */
|
/* Well-known JS values, initialized on startup. */
|
||||||
#define JSVAL_NULL JSVAL_CONSTANT(JSVAL_MASK32_NULL, 0)
|
#define JSVAL_NULL BUILD_JSVAL(JSVAL_MASK32_NULL, 0)
|
||||||
#define JSVAL_ZERO JSVAL_CONSTANT(JSVAL_MASK32_INT32, 0)
|
#define JSVAL_ZERO BUILD_JSVAL(JSVAL_MASK32_INT32, 0)
|
||||||
#define JSVAL_ONE JSVAL_CONSTANT(JSVAL_MASK32_INT32, 1)
|
#define JSVAL_ONE BUILD_JSVAL(JSVAL_MASK32_INT32, 1)
|
||||||
#define JSVAL_FALSE JSVAL_CONSTANT(JSVAL_MASK32_BOOLEAN, JS_FALSE)
|
#define JSVAL_FALSE BUILD_JSVAL(JSVAL_MASK32_BOOLEAN, JS_FALSE)
|
||||||
#define JSVAL_TRUE JSVAL_CONSTANT(JSVAL_MASK32_BOOLEAN, JS_TRUE)
|
#define JSVAL_TRUE BUILD_JSVAL(JSVAL_MASK32_BOOLEAN, JS_TRUE)
|
||||||
#define JSVAL_VOID JSVAL_CONSTANT(JSVAL_MASK32_UNDEFINED, 0)
|
#define JSVAL_VOID BUILD_JSVAL(JSVAL_MASK32_UNDEFINED, 0)
|
||||||
|
|
||||||
/* Predicates for type testing. */
|
/* Predicates for type testing. */
|
||||||
|
|
||||||
@ -65,14 +65,14 @@ static JS_ALWAYS_INLINE JSBool
|
|||||||
JSVAL_IS_NULL(jsval v)
|
JSVAL_IS_NULL(jsval v)
|
||||||
{
|
{
|
||||||
jsval_layout l = { v };
|
jsval_layout l = { v };
|
||||||
return l.s.mask32 == JSVAL_MASK32_NULL;
|
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)
|
||||||
{
|
{
|
||||||
jsval_layout l = { v };
|
jsval_layout l = { v };
|
||||||
return l.s.mask32 == JSVAL_MASK32_UNDEFINED;
|
return JSVAL_IS_UNDEFINED_IMPL(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JS_ALWAYS_INLINE JSBool
|
static JS_ALWAYS_INLINE JSBool
|
||||||
@ -103,17 +103,14 @@ INT_FITS_IN_JSVAL(jsint i)
|
|||||||
static JS_ALWAYS_INLINE jsval
|
static JS_ALWAYS_INLINE jsval
|
||||||
INT_TO_JSVAL(int32 i)
|
INT_TO_JSVAL(int32 i)
|
||||||
{
|
{
|
||||||
jsval_layout l;
|
return INT32_TO_JSVAL_IMPL(i).asBits;
|
||||||
l.s.mask32 = JSVAL_MASK32_INT32;
|
|
||||||
l.s.payload.i32 = i;
|
|
||||||
return l.asBits;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static JS_ALWAYS_INLINE JSBool
|
static JS_ALWAYS_INLINE JSBool
|
||||||
JSVAL_IS_DOUBLE(jsval v)
|
JSVAL_IS_DOUBLE(jsval v)
|
||||||
{
|
{
|
||||||
jsval_layout l = { v };
|
jsval_layout l = { v };
|
||||||
return l.s.mask32 < JSVAL_MASK32_CLEAR;
|
return JSVAL_IS_DOUBLE_IMPL(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JS_ALWAYS_INLINE jsdouble
|
static JS_ALWAYS_INLINE jsdouble
|
||||||
@ -127,16 +124,14 @@ JSVAL_TO_DOUBLE(jsval v)
|
|||||||
static JS_ALWAYS_INLINE jsval
|
static JS_ALWAYS_INLINE jsval
|
||||||
DOUBLE_TO_JSVAL(jsdouble d)
|
DOUBLE_TO_JSVAL(jsdouble d)
|
||||||
{
|
{
|
||||||
jsval_layout l;
|
return DOUBLE_TO_JSVAL_IMPL(d).asBits;
|
||||||
l.asDouble = d;
|
|
||||||
JS_ASSERT(l.s.tag.nanBits != JSVAL_NANBOX_PATTERN);
|
|
||||||
return l.asBits;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static JS_ALWAYS_INLINE JSBool
|
static JS_ALWAYS_INLINE JSBool
|
||||||
JSVAL_IS_NUMBER(jsval v)
|
JSVAL_IS_NUMBER(jsval v)
|
||||||
{
|
{
|
||||||
return JSVAL_IS_INT(v) | JSVAL_IS_DOUBLE(v);
|
jsval_layout l = { v };
|
||||||
|
return JSVAL_IS_NUMBER_IMPL(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JS_ALWAYS_INLINE JSBool
|
static JS_ALWAYS_INLINE JSBool
|
||||||
@ -151,30 +146,20 @@ JSVAL_TO_STRING(jsval v)
|
|||||||
{
|
{
|
||||||
JS_ASSERT(JSVAL_IS_STRING(v));
|
JS_ASSERT(JSVAL_IS_STRING(v));
|
||||||
jsval_layout l = { v };
|
jsval_layout l = { v };
|
||||||
return l.s.payload.str;
|
return JSVAL_TO_STRING_IMPL(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JS_ALWAYS_INLINE jsval
|
static JS_ALWAYS_INLINE jsval
|
||||||
STRING_TO_JSVAL(JSString *str)
|
STRING_TO_JSVAL(JSString *str)
|
||||||
{
|
{
|
||||||
jsval_layout l;
|
return STRING_TO_JSVAL_IMPL(str).asBits;
|
||||||
l.s.mask32 = JSVAL_MASK32_STRING;
|
|
||||||
l.s.payload.str = str;
|
|
||||||
return l.asBits;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* N.B. These functions use the older meaning of "object" as "object or null".
|
|
||||||
* This is not a problem if code only works with jsvals or only works with
|
|
||||||
* js::Value, but if both uses are mixed, it is important not to get confused
|
|
||||||
* by the two meanings. For example, JSVAL_IS_OBJECT(v) does not imply
|
|
||||||
* v.isObject().
|
|
||||||
*/
|
|
||||||
static JS_ALWAYS_INLINE JSBool
|
static JS_ALWAYS_INLINE JSBool
|
||||||
JSVAL_IS_OBJECT(jsval v)
|
JSVAL_IS_OBJECT(jsval v)
|
||||||
{
|
{
|
||||||
jsval_layout l = { v };
|
jsval_layout l = { v };
|
||||||
return (l.s.mask32 & JSVAL_MASK32_OBJORNULL) > JSVAL_MASK32_CLEAR;
|
return JSVAL_IS_OBJECT_OR_NULL_IMPL(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JS_ALWAYS_INLINE JSObject *
|
static JS_ALWAYS_INLINE JSObject *
|
||||||
@ -182,9 +167,10 @@ JSVAL_TO_OBJECT(jsval v)
|
|||||||
{
|
{
|
||||||
JS_ASSERT(JSVAL_IS_OBJECT(v));
|
JS_ASSERT(JSVAL_IS_OBJECT(v));
|
||||||
jsval_layout l = { v };
|
jsval_layout l = { v };
|
||||||
return l.s.payload.obj;
|
return JSVAL_TO_OBJECT_IMPL(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* N.B. Not cheap; uses public API instead of obj->isFunction()! */
|
||||||
static JS_ALWAYS_INLINE jsval
|
static JS_ALWAYS_INLINE jsval
|
||||||
OBJECT_TO_JSVAL(JSObject *obj)
|
OBJECT_TO_JSVAL(JSObject *obj)
|
||||||
{
|
{
|
||||||
@ -193,12 +179,10 @@ OBJECT_TO_JSVAL(JSObject *obj)
|
|||||||
|
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return JSVAL_NULL;
|
return JSVAL_NULL;
|
||||||
uint32 mask = JS_ObjectIsFunction(NULL, obj) ? JSVAL_MASK32_FUNOBJ
|
|
||||||
: JSVAL_MASK32_NONFUNOBJ;
|
JSValueMask32 mask = JS_ObjectIsFunction(NULL, obj) ? JSVAL_MASK32_FUNOBJ
|
||||||
jsval_layout l;
|
: JSVAL_MASK32_NONFUNOBJ;
|
||||||
l.s.mask32 = mask;
|
return OBJECT_TO_JSVAL_IMPL(mask, obj).asBits;
|
||||||
l.s.payload.obj = obj;
|
|
||||||
return l.asBits;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static JS_ALWAYS_INLINE JSBool
|
static JS_ALWAYS_INLINE JSBool
|
||||||
@ -219,24 +203,21 @@ JSVAL_TO_BOOLEAN(jsval v)
|
|||||||
static JS_ALWAYS_INLINE jsval
|
static JS_ALWAYS_INLINE jsval
|
||||||
BOOLEAN_TO_JSVAL(JSBool b)
|
BOOLEAN_TO_JSVAL(JSBool b)
|
||||||
{
|
{
|
||||||
jsval_layout l;
|
return BOOLEAN_TO_JSVAL_IMPL(b).asBits;
|
||||||
l.s.mask32 = JSVAL_MASK32_BOOLEAN;
|
|
||||||
l.s.payload.boo = b;
|
|
||||||
return l.asBits;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static JS_ALWAYS_INLINE JSBool
|
static JS_ALWAYS_INLINE JSBool
|
||||||
JSVAL_IS_PRIMITIVE(jsval v)
|
JSVAL_IS_PRIMITIVE(jsval v)
|
||||||
{
|
{
|
||||||
jsval_layout l = { v };
|
jsval_layout l = { v };
|
||||||
return (l.s.mask32 & JSVAL_MASK32_OBJECT) <= JSVAL_MASK32_CLEAR;
|
return JSVAL_IS_PRIMITIVE_IMPL(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JS_ALWAYS_INLINE JSBool
|
static JS_ALWAYS_INLINE JSBool
|
||||||
JSVAL_IS_GCTHING(jsval v)
|
JSVAL_IS_GCTHING(jsval v)
|
||||||
{
|
{
|
||||||
jsval_layout l = { v };
|
jsval_layout l = { v };
|
||||||
return (l.s.mask32 & JSVAL_MASK32_GCTHING) > JSVAL_MASK32_CLEAR;
|
return JSVAL_IS_GCTHING_IMPL(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JS_ALWAYS_INLINE void *
|
static JS_ALWAYS_INLINE void *
|
||||||
@ -244,24 +225,23 @@ JSVAL_TO_GCTHING(jsval v)
|
|||||||
{
|
{
|
||||||
JS_ASSERT(JSVAL_IS_GCTHING(v));
|
JS_ASSERT(JSVAL_IS_GCTHING(v));
|
||||||
jsval_layout l = { v };
|
jsval_layout l = { v };
|
||||||
return l.s.payload.ptr;
|
return JSVAL_TO_GCTHING_IMPL(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* To be GC-safe, privates are tagged as doubles. */
|
||||||
|
|
||||||
static JS_ALWAYS_INLINE jsval
|
static JS_ALWAYS_INLINE jsval
|
||||||
PRIVATE_TO_JSVAL(void *ptr)
|
PRIVATE_TO_JSVAL(void *ptr)
|
||||||
{
|
{
|
||||||
jsval_layout l;
|
return PRIVATE_TO_JSVAL_IMPL(ptr).asBits;
|
||||||
l.s.mask32 = JSVAL_MASK32_INT32;
|
|
||||||
l.s.payload.ptr = ptr;
|
|
||||||
return l.asBits;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static JS_ALWAYS_INLINE void *
|
static JS_ALWAYS_INLINE void *
|
||||||
JSVAL_TO_PRIVATE(jsval v)
|
JSVAL_TO_PRIVATE(jsval v)
|
||||||
{
|
{
|
||||||
JS_ASSERT(JSVAL_IS_INT(v));
|
JS_ASSERT(JSVAL_IS_DOUBLE(v));
|
||||||
jsval_layout l = { v };
|
jsval_layout l = { v };
|
||||||
return l.s.payload.ptr;
|
return JSVAL_TO_PRIVATE_IMPL(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lock and unlock the GC thing held by a jsval. */
|
/* Lock and unlock the GC thing held by a jsval. */
|
||||||
@ -1189,7 +1169,7 @@ JSVAL_TRACE_KIND(jsval v)
|
|||||||
{
|
{
|
||||||
JS_ASSERT(JSVAL_IS_GCTHING(v));
|
JS_ASSERT(JSVAL_IS_GCTHING(v));
|
||||||
jsval_layout l = { v };
|
jsval_layout l = { v };
|
||||||
return (uint32)(l.s.mask32 == JSVAL_MASK32_STRING);
|
return JSVAL_TRACE_KIND_IMPL(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct JSTracer {
|
struct JSTracer {
|
||||||
@ -3007,44 +2987,26 @@ class Value
|
|||||||
* break this encapsulation should be listed as friends below. Also see
|
* break this encapsulation should be listed as friends below. Also see
|
||||||
* uses of public jsval members in jsapi.h/jspubtd.h.
|
* uses of public jsval members in jsapi.h/jspubtd.h.
|
||||||
*/
|
*/
|
||||||
friend bool StrictlyEqual(JSContext *, const Value &, const Value &);
|
|
||||||
friend bool Interpret(JSContext *); /* grep "value representation" */
|
|
||||||
friend class PrimitiveValue;
|
friend class PrimitiveValue;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* Type masks */
|
/* Type masks */
|
||||||
|
|
||||||
|
template <int I> class T {};
|
||||||
|
|
||||||
void staticAssertions() {
|
void staticAssertions() {
|
||||||
JS_STATIC_ASSERT(sizeof(void *) == 4);
|
|
||||||
JS_STATIC_ASSERT(sizeof(jsval) == 8);
|
|
||||||
JS_STATIC_ASSERT(sizeof(JSBool) == 4);
|
|
||||||
JS_STATIC_ASSERT(sizeof(JSValueMask16) == 2);
|
JS_STATIC_ASSERT(sizeof(JSValueMask16) == 2);
|
||||||
JS_STATIC_ASSERT(sizeof(jsval_payload) == 4);
|
JS_STATIC_ASSERT(JSVAL_NANBOX_PATTERN == 0xFFFF);
|
||||||
|
JS_STATIC_ASSERT(sizeof(JSValueMask32) == 4);
|
||||||
|
JS_STATIC_ASSERT(JSVAL_MASK32_CLEAR == 0xFFFF0000);
|
||||||
|
JS_STATIC_ASSERT(sizeof(JSBool) == 4);
|
||||||
JS_STATIC_ASSERT(sizeof(JSWhyMagic) <= 4);
|
JS_STATIC_ASSERT(sizeof(JSWhyMagic) <= 4);
|
||||||
|
JS_STATIC_ASSERT(sizeof(((jsval_layout *)0)->s.payload) == 4);
|
||||||
|
JS_STATIC_ASSERT(sizeof(jsval) == 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
jsval_layout data;
|
jsval_layout data;
|
||||||
|
|
||||||
static bool isNullOrUndefinedMask(uint32 mask) {
|
|
||||||
return (mask & JSVAL_MASK32_SINGLETON) > JSVAL_MASK32_CLEAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isDoubleMask(uint32 mask) {
|
|
||||||
return mask < JSVAL_MASK32_CLEAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isNumberMask(uint32 mask) {
|
|
||||||
return (mask < JSVAL_MASK32_CLEAR) | (mask == JSVAL_MASK32_INT32);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isObjectMask(uint32 mask) {
|
|
||||||
return (mask & JSVAL_MASK32_OBJECT) > JSVAL_MASK32_CLEAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isObjectOrNullMask(uint32 mask) {
|
|
||||||
return (mask & JSVAL_MASK32_OBJORNULL) > JSVAL_MASK32_CLEAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/* Constructors */
|
/* Constructors */
|
||||||
|
|
||||||
@ -3075,18 +3037,15 @@ class Value
|
|||||||
/* Change to a Value of a single type */
|
/* Change to a Value of a single type */
|
||||||
|
|
||||||
void setNull() {
|
void setNull() {
|
||||||
data.s.mask32 = JSVAL_MASK32_NULL;
|
data.asBits = JSVAL_NULL;
|
||||||
data.s.payload.obj = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setUndefined() {
|
void setUndefined() {
|
||||||
data.s.mask32 = JSVAL_MASK32_UNDEFINED;
|
data.asBits = JSVAL_VOID;
|
||||||
data.s.payload.obj = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setInt32(int32 i) {
|
void setInt32(int32 i) {
|
||||||
data.s.mask32 = JSVAL_MASK32_INT32;
|
data = INT32_TO_JSVAL_IMPL(i);
|
||||||
data.s.payload.i32 = i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 &asInt32Ref() {
|
int32 &asInt32Ref() {
|
||||||
@ -3096,8 +3055,7 @@ class Value
|
|||||||
|
|
||||||
void setDouble(double d) {
|
void setDouble(double d) {
|
||||||
ASSERT_DOUBLE_ALIGN();
|
ASSERT_DOUBLE_ALIGN();
|
||||||
data.asDouble = d;
|
data = DOUBLE_TO_JSVAL_IMPL(d);
|
||||||
JS_ASSERT(data.s.tag.nanBits != JSVAL_NANBOX_PATTERN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double &asDoubleRef() {
|
double &asDoubleRef() {
|
||||||
@ -3107,62 +3065,54 @@ class Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setString(JSString *str) {
|
void setString(JSString *str) {
|
||||||
data.s.mask32 = JSVAL_MASK32_STRING;
|
data = STRING_TO_JSVAL_IMPL(str);
|
||||||
data.s.payload.str = str;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFunObj(JSObject &arg) {
|
void setFunObj(JSObject &arg) {
|
||||||
JS_ASSERT(JS_ObjectIsFunction(NULL, &arg));
|
JS_ASSERT(JS_ObjectIsFunction(NULL, &arg));
|
||||||
data.s.mask32 = JSVAL_MASK32_FUNOBJ;
|
data = OBJECT_TO_JSVAL_IMPL(JSVAL_MASK32_FUNOBJ, &arg);
|
||||||
data.s.payload.obj = &arg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setNonFunObj(JSObject &arg) {
|
void setNonFunObj(JSObject &arg) {
|
||||||
JS_ASSERT(!JS_ObjectIsFunction(NULL, &arg));
|
JS_ASSERT(!JS_ObjectIsFunction(NULL, &arg));
|
||||||
data.s.mask32 = JSVAL_MASK32_NONFUNOBJ;
|
data = OBJECT_TO_JSVAL_IMPL(JSVAL_MASK32_NONFUNOBJ, &arg);
|
||||||
data.s.payload.obj = &arg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setBoolean(bool b) {
|
void setBoolean(bool b) {
|
||||||
data.s.mask32 = JSVAL_MASK32_BOOLEAN;
|
data = BOOLEAN_TO_JSVAL_IMPL(b);
|
||||||
data.s.payload.boo = b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setMagic(JSWhyMagic why) {
|
void setMagic(JSWhyMagic why) {
|
||||||
data.s.mask32 = JSVAL_MASK32_MAGIC;
|
data = MAGIC_TO_JSVAL_IMPL(why);
|
||||||
data.s.payload.why = why;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Change to a Value of a type dynamically chosen from a set of types */
|
/* Change to a Value of a type dynamically chosen from a set of types */
|
||||||
|
|
||||||
void setNumber(uint32 ui) {
|
void setNumber(uint32 ui) {
|
||||||
if (ui > JSVAL_INT_MAX) {
|
if (ui > JSVAL_INT_MAX)
|
||||||
data.asDouble = ui;
|
data = DOUBLE_TO_JSVAL_IMPL(ui);
|
||||||
JS_ASSERT(data.s.tag.nanBits != JSVAL_NANBOX_PATTERN);
|
else
|
||||||
} else {
|
data = INT32_TO_JSVAL_IMPL((int32)ui);
|
||||||
data.s.mask32 = JSVAL_MASK32_INT32;
|
|
||||||
data.s.payload.i32 = (int32)ui;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setNumber(double d);
|
inline void setNumber(double d);
|
||||||
|
|
||||||
void setFunObjOrNull(JSObject *arg) {
|
void setFunObjOrNull(JSObject *arg) {
|
||||||
JS_ASSERT_IF(arg, JS_ObjectIsFunction(NULL, arg));
|
JS_ASSERT_IF(arg, JS_ObjectIsFunction(NULL, arg));
|
||||||
data.s.mask32 = arg ? JSVAL_MASK32_FUNOBJ : JSVAL_MASK32_NULL;
|
JSValueMask32 mask = arg ? JSVAL_MASK32_FUNOBJ : JSVAL_MASK32_NULL;
|
||||||
data.s.payload.obj = arg;
|
data = OBJECT_TO_JSVAL_IMPL(mask, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFunObjOrUndefined(JSObject *arg) {
|
void setFunObjOrUndefined(JSObject *arg) {
|
||||||
JS_ASSERT_IF(arg, JS_ObjectIsFunction(NULL, arg));
|
JS_ASSERT_IF(arg, JS_ObjectIsFunction(NULL, arg));
|
||||||
data.s.mask32 = arg ? JSVAL_MASK32_FUNOBJ : JSVAL_MASK32_UNDEFINED;
|
JSValueMask32 mask = arg ? JSVAL_MASK32_FUNOBJ : JSVAL_MASK32_UNDEFINED;
|
||||||
data.s.payload.obj = arg;
|
data = OBJECT_TO_JSVAL_IMPL(mask, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setNonFunObjOrNull(JSObject *arg) {
|
void setNonFunObjOrNull(JSObject *arg) {
|
||||||
JS_ASSERT_IF(arg, !JS_ObjectIsFunction(NULL, arg));
|
JS_ASSERT_IF(arg, !JS_ObjectIsFunction(NULL, arg));
|
||||||
data.s.mask32 = arg ? JSVAL_MASK32_NONFUNOBJ : JSVAL_MASK32_NULL;
|
JSValueMask32 mask = arg ? JSVAL_MASK32_NONFUNOBJ : JSVAL_MASK32_NULL;
|
||||||
data.s.payload.obj = arg;
|
data = OBJECT_TO_JSVAL_IMPL(mask, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setObject(JSObject &arg);
|
inline void setObject(JSObject &arg);
|
||||||
@ -3171,15 +3121,15 @@ class Value
|
|||||||
/* Query a Value's type */
|
/* Query a Value's type */
|
||||||
|
|
||||||
bool isUndefined() const {
|
bool isUndefined() const {
|
||||||
return data.s.mask32 == JSVAL_MASK32_UNDEFINED;
|
return JSVAL_IS_UNDEFINED_IMPL(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isNull() const {
|
bool isNull() const {
|
||||||
return data.s.mask32 == JSVAL_MASK32_NULL;
|
return JSVAL_IS_NULL_IMPL(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isNullOrUndefined() const {
|
bool isNullOrUndefined() const {
|
||||||
return isNullOrUndefinedMask(data.s.mask32);
|
return JSVAL_IS_SINGLETON_IMPL(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isInt32() const {
|
bool isInt32() const {
|
||||||
@ -3187,16 +3137,15 @@ class Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isInt32(int32 i32) const {
|
bool isInt32(int32 i32) const {
|
||||||
return (data.s.mask32 == JSVAL_MASK32_INT32) &
|
return JSVAL_IS_SPECIFIC_INT32_IMPL(data, i32);
|
||||||
(data.s.payload.i32 == i32);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isDouble() const {
|
bool isDouble() const {
|
||||||
return isDoubleMask(data.s.mask32);
|
return JSVAL_IS_DOUBLE_IMPL(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isNumber() const {
|
bool isNumber() const {
|
||||||
return isNumberMask(data.s.mask32);
|
return JSVAL_IS_NUMBER_IMPL(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isString() const {
|
bool isString() const {
|
||||||
@ -3212,19 +3161,19 @@ class Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isObject() const {
|
bool isObject() const {
|
||||||
return isObjectMask(data.s.mask32);
|
return JSVAL_IS_OBJECT_IMPL(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isPrimitive() const {
|
bool isPrimitive() const {
|
||||||
return !isObject();
|
return JSVAL_IS_PRIMITIVE_IMPL(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isObjectOrNull() const {
|
bool isObjectOrNull() const {
|
||||||
return isObjectOrNullMask(data.s.mask32);
|
return JSVAL_IS_OBJECT_OR_NULL_IMPL(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isGCThing() const {
|
bool isGCThing() const {
|
||||||
return (data.s.mask32 & JSVAL_MASK32_GCTHING) > JSVAL_MASK32_CLEAR;
|
return JSVAL_IS_GCTHING_IMPL(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isBoolean() const {
|
bool isBoolean() const {
|
||||||
@ -3232,13 +3181,11 @@ class Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isTrue() const {
|
bool isTrue() const {
|
||||||
return data.s.mask32 == JSVAL_MASK32_BOOLEAN &&
|
return JSVAL_IS_SPECIFIC_BOOLEAN(data, true);
|
||||||
data.s.payload.boo == JS_TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isFalse() const {
|
bool isFalse() const {
|
||||||
return data.s.mask32 == JSVAL_MASK32_BOOLEAN &&
|
return JSVAL_IS_SPECIFIC_BOOLEAN(data, false);
|
||||||
data.s.payload.boo == JS_FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isMagic() const {
|
bool isMagic() const {
|
||||||
@ -3252,13 +3199,17 @@ class Value
|
|||||||
|
|
||||||
int32 traceKind() const {
|
int32 traceKind() const {
|
||||||
JS_ASSERT(isGCThing());
|
JS_ASSERT(isGCThing());
|
||||||
return (int32)(data.s.mask32 == JSVAL_MASK32_STRING);
|
return JSVAL_TRACE_KIND_IMPL(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
JSWhyMagic whyMagic() const {
|
JSWhyMagic whyMagic() const {
|
||||||
JS_ASSERT(isMagic());
|
JS_ASSERT(isMagic());
|
||||||
return data.s.payload.why;
|
return data.s.payload.why;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Comparison */
|
||||||
|
|
||||||
bool operator==(const Value &rhs) const {
|
bool operator==(const Value &rhs) const {
|
||||||
return data.asBits == rhs.data.asBits;
|
return data.asBits == rhs.data.asBits;
|
||||||
@ -3268,6 +3219,18 @@ class Value
|
|||||||
return data.asBits != rhs.data.asBits;
|
return data.asBits != rhs.data.asBits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend bool SamePrimitiveTypeOrBothObjects(const Value &lhs, const Value &rhs) {
|
||||||
|
return JSVAL_SAME_PRIMITIVE_TYPE_OR_BOTH_OBJECTS_IMPL(lhs.data, rhs.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool BothInt32(const Value &lhs, const Value &rhs) {
|
||||||
|
return JSVAL_BOTH_INT32_IMPL(lhs.data, rhs.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool BothString(const Value &lhs, const Value &rhs) {
|
||||||
|
return JSVAL_BOTH_STRING_IMPL(lhs.data, rhs.data);
|
||||||
|
}
|
||||||
|
|
||||||
/* Extract a Value's payload */
|
/* Extract a Value's payload */
|
||||||
|
|
||||||
int32 asInt32() const {
|
int32 asInt32() const {
|
||||||
@ -3288,32 +3251,32 @@ class Value
|
|||||||
|
|
||||||
JSString *asString() const {
|
JSString *asString() const {
|
||||||
JS_ASSERT(isString());
|
JS_ASSERT(isString());
|
||||||
return data.s.payload.str;
|
return JSVAL_TO_STRING_IMPL(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSObject &asNonFunObj() const {
|
JSObject &asNonFunObj() const {
|
||||||
JS_ASSERT(isNonFunObj());
|
JS_ASSERT(isNonFunObj());
|
||||||
return *data.s.payload.obj;
|
return *JSVAL_TO_OBJECT_IMPL(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSObject &asFunObj() const {
|
JSObject &asFunObj() const {
|
||||||
JS_ASSERT(isFunObj());
|
JS_ASSERT(isFunObj());
|
||||||
return *data.s.payload.obj;
|
return *JSVAL_TO_OBJECT_IMPL(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSObject &asObject() const {
|
JSObject &asObject() const {
|
||||||
JS_ASSERT(isObject());
|
JS_ASSERT(isObject());
|
||||||
return *data.s.payload.obj;
|
return *JSVAL_TO_OBJECT_IMPL(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSObject *asObjectOrNull() const {
|
JSObject *asObjectOrNull() const {
|
||||||
JS_ASSERT(isObjectOrNull());
|
JS_ASSERT(isObjectOrNull());
|
||||||
return data.s.payload.obj;
|
return JSVAL_TO_OBJECT_IMPL(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *asGCThing() const {
|
void *asGCThing() const {
|
||||||
JS_ASSERT(isGCThing());
|
JS_ASSERT(isGCThing());
|
||||||
return data.s.payload.ptr;
|
return JSVAL_TO_GCTHING_IMPL(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool asBoolean() const {
|
bool asBoolean() const {
|
||||||
@ -3321,6 +3284,11 @@ class Value
|
|||||||
return data.s.payload.boo;
|
return data.s.payload.boo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 asRawUint32() const {
|
||||||
|
JS_ASSERT(!isDouble());
|
||||||
|
return data.s.payload.u32;
|
||||||
|
}
|
||||||
|
|
||||||
/* Swap two Values */
|
/* Swap two Values */
|
||||||
|
|
||||||
void swap(Value &rhs) {
|
void swap(Value &rhs) {
|
||||||
@ -3343,28 +3311,25 @@ class Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setPrivateVoidPtr(void *ptr) {
|
void setPrivateVoidPtr(void *ptr) {
|
||||||
data.s.mask32 = JSVAL_MASK32_INT32;
|
data = PRIVATE_TO_JSVAL_IMPL(ptr);
|
||||||
data.s.payload.ptr = ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *asPrivateVoidPtr() const {
|
void *asPrivateVoidPtr() const {
|
||||||
JS_ASSERT(data.s.mask32 == JSVAL_MASK32_INT32);
|
JS_ASSERT(isDouble());
|
||||||
return data.s.payload.ptr;
|
return JSVAL_TO_PRIVATE_IMPL(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPrivateUint32(uint32 u) {
|
void setPrivateUint32(uint32 u) {
|
||||||
data.s.mask32 = JSVAL_MASK32_INT32;
|
setInt32((int32)u);
|
||||||
data.s.payload.u32 = u;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 asPrivateUint32() const {
|
uint32 asPrivateUint32() const {
|
||||||
JS_ASSERT(data.s.mask32 == JSVAL_MASK32_INT32);
|
return (uint32)asInt32();
|
||||||
return data.s.payload.u32;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 &asPrivateUint32Ref() {
|
uint32 &asPrivateUint32Ref() {
|
||||||
JS_ASSERT(data.s.mask32 == JSVAL_MASK32_INT32);
|
JS_ASSERT(isInt32());
|
||||||
return data.s.payload.u32;
|
return data.s.payload.u32;
|
||||||
}
|
}
|
||||||
} VALUE_ALIGNMENT;
|
} VALUE_ALIGNMENT;
|
||||||
|
|
||||||
@ -3372,14 +3337,15 @@ class Value
|
|||||||
* As asserted above, js::Value and jsval are layout equivalent. To provide
|
* As asserted above, js::Value and jsval are layout equivalent. To provide
|
||||||
* widespread casting, the following safe casts are provided.
|
* widespread casting, the following safe casts are provided.
|
||||||
*/
|
*/
|
||||||
static inline jsval * Jsvalify(Value *v) { return (jsval *)v; }
|
static inline jsval * Jsvalify(Value *v) { return (jsval *)v; }
|
||||||
static inline const jsval * Jsvalify(const Value *v) { return (const jsval *)v; }
|
static inline const jsval * Jsvalify(const Value *v) { return (const jsval *)v; }
|
||||||
static inline jsval & Jsvalify(Value &v) { return (jsval &)v; }
|
static inline jsval & Jsvalify(Value &v) { return (jsval &)v; }
|
||||||
static inline const jsval & Jsvalify(const Value &v) { return (const jsval &)v; }
|
static inline const jsval & Jsvalify(const Value &v) { return (const jsval &)v; }
|
||||||
static inline Value * Valueify(jsval *v) { return (Value *)v; }
|
static inline Value * Valueify(jsval *v) { return (Value *)v; }
|
||||||
static inline const Value * Valueify(const jsval *v) { return (const Value *)v; }
|
static inline const Value * Valueify(const jsval *v) { return (const Value *)v; }
|
||||||
static inline Value & Valueify(jsval &v) { return (Value &)v; }
|
static inline Value ** Valueify(jsval **v) { return (Value **)v; }
|
||||||
static inline const Value & Valueify(const jsval &v) { return (const Value &)v; }
|
static inline Value & Valueify(jsval &v) { return (Value &)v; }
|
||||||
|
static inline const Value & Valueify(const jsval &v) { return (const Value &)v; }
|
||||||
|
|
||||||
/* Convenience inlines. */
|
/* Convenience inlines. */
|
||||||
static inline Value undefinedValue() { return UndefinedTag(); }
|
static inline Value undefinedValue() { return UndefinedTag(); }
|
||||||
|
@ -2040,8 +2040,10 @@ array_sort(JSContext *cx, uintN argc, Value *vp)
|
|||||||
str = js_ValueToString(cx, v);
|
str = js_ValueToString(cx, v);
|
||||||
if (!str)
|
if (!str)
|
||||||
return false;
|
return false;
|
||||||
vec[2 * i].setString(str);
|
// Copying v must come first, because the following line overwrites v
|
||||||
|
// when i == 0.
|
||||||
vec[2 * i + 1] = v;
|
vec[2 * i + 1] = v;
|
||||||
|
vec[2 * i].setString(str);
|
||||||
} while (i != 0);
|
} while (i != 0);
|
||||||
|
|
||||||
JS_ASSERT(tvr.array == vec);
|
JS_ASSERT(tvr.array == vec);
|
||||||
@ -2730,7 +2732,7 @@ array_indexOfHelper(JSContext *cx, JSBool isLast, uintN argc, Value *vp)
|
|||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
}
|
}
|
||||||
if (!hole && StrictlyEqual(cx, *vp, tosearch)) {
|
if (!hole && StrictlyEqual(cx, *vp, tosearch)) {
|
||||||
Uint32ToValue(i, vp);
|
vp->setNumber(i);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
if (i == stop)
|
if (i == stop)
|
||||||
|
@ -911,6 +911,11 @@ struct JSGCLockHashEntry : public JSDHashEntryHdr
|
|||||||
JSBool
|
JSBool
|
||||||
js_InitGC(JSRuntime *rt, uint32 maxbytes)
|
js_InitGC(JSRuntime *rt, uint32 maxbytes)
|
||||||
{
|
{
|
||||||
|
#if defined(XP_WIN) && defined(_M_X64)
|
||||||
|
if (!InitNtAllocAPIs())
|
||||||
|
return JS_FALSE;
|
||||||
|
#endif
|
||||||
|
|
||||||
InitGCArenaLists(rt);
|
InitGCArenaLists(rt);
|
||||||
if (!rt->gcRootsHash.init(GC_ROOTS_SIZE))
|
if (!rt->gcRootsHash.init(GC_ROOTS_SIZE))
|
||||||
return false;
|
return false;
|
||||||
|
@ -39,6 +39,10 @@
|
|||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
|
|
||||||
|
#ifdef _M_X64
|
||||||
|
# include "jsstr.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
# ifdef _MSC_VER
|
# ifdef _MSC_VER
|
||||||
# pragma warning( disable: 4267 4996 4146 )
|
# pragma warning( disable: 4267 4996 4146 )
|
||||||
# endif
|
# endif
|
||||||
@ -140,6 +144,68 @@ UnmapPages(void *p, size_t size)
|
|||||||
|
|
||||||
# else /* WINCE */
|
# else /* WINCE */
|
||||||
|
|
||||||
|
# ifdef _M_X64
|
||||||
|
|
||||||
|
typedef long (*ntavm_fun)(HANDLE handle, void **addr, ULONG zbits,
|
||||||
|
size_t *size, ULONG alloctype, ULONG prot);
|
||||||
|
typedef long (*ntfvm_fun)(HANDLE handle, void **addr, size_t *size,
|
||||||
|
ULONG freetype);
|
||||||
|
|
||||||
|
static ntavm_fun NtAllocateVirtualMemory;
|
||||||
|
static ntfvm_fun NtFreeVirtualMemory;
|
||||||
|
|
||||||
|
bool
|
||||||
|
js::InitNtAllocAPIs()
|
||||||
|
{
|
||||||
|
HMODULE h = GetModuleHandle("ntdll.dll");
|
||||||
|
if (!h)
|
||||||
|
return false;
|
||||||
|
NtAllocateVirtualMemory = ntavm_fun(GetProcAddress(h, "NtAllocateVirtualMemory"));
|
||||||
|
if (!NtAllocateVirtualMemory)
|
||||||
|
return false;
|
||||||
|
NtFreeVirtualMemory = ntfvm_fun(GetProcAddress(h, "NtFreeVirtualMemory"));
|
||||||
|
if (!NtFreeVirtualMemory)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate pages with 32-bit addresses (i.e., top 16 bits are all 0).
|
||||||
|
static void *
|
||||||
|
MapPages(void *addr, size_t size)
|
||||||
|
{
|
||||||
|
long rc = NtAllocateVirtualMemory(INVALID_HANDLE_VALUE, &addr, 1, &size,
|
||||||
|
MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
|
||||||
|
return rc ? NULL : addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
UnmapPages(void *addr, size_t size)
|
||||||
|
{
|
||||||
|
NtFreeVirtualMemory(INVALID_HANDLE_VALUE, &addr, &size, MEM_RELEASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
JSString::initStringTables()
|
||||||
|
{
|
||||||
|
char *p = (char *) MapPages(NULL, unitStringTableSize + intStringTableSize);
|
||||||
|
if (!p)
|
||||||
|
return false;
|
||||||
|
unitStringTable = (JSString*) memcpy(p, staticUnitStringTable, unitStringTableSize);
|
||||||
|
intStringTable = (JSString*) memcpy(p + unitStringTableSize,
|
||||||
|
staticIntStringTable, intStringTableSize);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
JSString::freeStringTables()
|
||||||
|
{
|
||||||
|
UnmapPages(unitStringTable, unitStringTableSize + intStringTableSize);
|
||||||
|
unitStringTable = NULL;
|
||||||
|
intStringTable = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
# else /* _M_X64 */
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
MapPages(void *addr, size_t size)
|
MapPages(void *addr, size_t size)
|
||||||
{
|
{
|
||||||
@ -154,6 +220,8 @@ UnmapPages(void *addr, size_t size)
|
|||||||
JS_ALWAYS_TRUE(VirtualFree(addr, 0, MEM_RELEASE));
|
JS_ALWAYS_TRUE(VirtualFree(addr, 0, MEM_RELEASE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# endif /* _M_X64 */
|
||||||
|
|
||||||
# endif /* !WINCE */
|
# endif /* !WINCE */
|
||||||
|
|
||||||
#elif defined(XP_MACOSX) || defined(DARWIN)
|
#elif defined(XP_MACOSX) || defined(DARWIN)
|
||||||
@ -203,8 +271,9 @@ MapAlignedPages(size_t size, size_t alignment)
|
|||||||
* We don't use MAP_FIXED here, because it can cause the *replacement*
|
* We don't use MAP_FIXED here, because it can cause the *replacement*
|
||||||
* of existing mappings, and we only want to create new mappings.
|
* of existing mappings, and we only want to create new mappings.
|
||||||
*/
|
*/
|
||||||
|
// TODO: this is totally a hack for now; need to replace
|
||||||
void *p = mmap((caddr_t) alignment, size, PROT_READ | PROT_WRITE,
|
void *p = mmap((caddr_t) alignment, size, PROT_READ | PROT_WRITE,
|
||||||
MAP_PRIVATE | MAP_NOSYNC | MAP_ALIGN | MAP_ANON, -1, 0);
|
MAP_PRIVATE | MAP_NOSYNC | MAP_ALIGN | MAP_ANON | MAP_32BIT, -1, 0);
|
||||||
if (p == MAP_FAILED)
|
if (p == MAP_FAILED)
|
||||||
return NULL;
|
return NULL;
|
||||||
return p;
|
return p;
|
||||||
@ -219,7 +288,8 @@ MapPages(void *addr, size_t size)
|
|||||||
* We don't use MAP_FIXED here, because it can cause the *replacement*
|
* We don't use MAP_FIXED here, because it can cause the *replacement*
|
||||||
* of existing mappings, and we only want to create new mappings.
|
* of existing mappings, and we only want to create new mappings.
|
||||||
*/
|
*/
|
||||||
void *p = mmap(addr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON,
|
// TODO: this is totally a hack for now; need to replace
|
||||||
|
void *p = mmap(addr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_32BIT,
|
||||||
-1, 0);
|
-1, 0);
|
||||||
if (p == MAP_FAILED)
|
if (p == MAP_FAILED)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -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
|
||||||
|
|
||||||
void *
|
void *
|
||||||
AllocGCChunk();
|
AllocGCChunk();
|
||||||
|
|
||||||
|
@ -387,8 +387,7 @@ NoSuchMethod(JSContext *cx, uintN argc, Value *vp, uint32 flags)
|
|||||||
|
|
||||||
namespace js {
|
namespace js {
|
||||||
|
|
||||||
static const uint32 FAKE_NUMBER_MASK = JSVAL_MASK32_INT32 |
|
static const uint32 FAKE_NUMBER_MASK = JSVAL_MASK32_INT32 | PrimitiveValue::DOUBLE_MASK;
|
||||||
PrimitiveValue::DOUBLE_MASK;
|
|
||||||
|
|
||||||
const uint32 PrimitiveValue::Masks[PrimitiveValue::THISP_ARRAY_SIZE] = {
|
const uint32 PrimitiveValue::Masks[PrimitiveValue::THISP_ARRAY_SIZE] = {
|
||||||
0, /* 000 */
|
0, /* 000 */
|
||||||
@ -1001,36 +1000,29 @@ EqualObjects(JSContext *cx, JSObject *lobj, JSObject *robj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
StrictlyEqual(JSContext *cx, const Value &lval, const Value &rval)
|
StrictlyEqual(JSContext *cx, const Value &lref, const Value &rref)
|
||||||
{
|
{
|
||||||
uint32 lmask = lval.data.s.mask32;
|
Value lval = lref, rval = rref;
|
||||||
uint32 rmask = rval.data.s.mask32;
|
if (SamePrimitiveTypeOrBothObjects(lval, rval)) {
|
||||||
if (lmask == rmask) {
|
if (lval.isString())
|
||||||
if (lmask == JSVAL_MASK32_STRING)
|
return js_EqualStrings(lval.asString(), rval.asString());
|
||||||
return js_EqualStrings(lval.data.s.payload.str, rval.data.s.payload.str);
|
if (lval.isDouble())
|
||||||
if (Value::isObjectMask(lmask))
|
return JSDOUBLE_COMPARE(lval.asDouble(), ==, rval.asDouble(), JS_FALSE);
|
||||||
return EqualObjects(cx, lval.data.s.payload.obj, rval.data.s.payload.obj);
|
if (lval.isObject())
|
||||||
if (Value::isDoubleMask(lmask))
|
return EqualObjects(cx, &lval.asObject(), &rval.asObject());
|
||||||
return JSDOUBLE_COMPARE(lval.data.asDouble, ==, rval.data.asDouble, JS_FALSE);
|
return lval.asRawUint32() == rval.asRawUint32();
|
||||||
JS_ASSERT(lmask == JSVAL_MASK32_NULL ||
|
|
||||||
lmask == JSVAL_MASK32_UNDEFINED ||
|
|
||||||
lmask == JSVAL_MASK32_INT32 ||
|
|
||||||
lmask == JSVAL_MASK32_FUNOBJ ||
|
|
||||||
lmask == JSVAL_MASK32_NONFUNOBJ ||
|
|
||||||
lmask == JSVAL_MASK32_BOOLEAN);
|
|
||||||
return lval.data.s.payload.u32 == rval.data.s.payload.u32;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Value::isNumberMask(lmask) && Value::isNumberMask(rmask)) {
|
if (lval.isDouble() && rval.isInt32()) {
|
||||||
double ld = lmask == JSVAL_MASK32_INT32 ? lval.data.s.payload.i32
|
double ld = lval.asDouble();
|
||||||
: lval.data.asDouble;
|
double rd = rval.asInt32();
|
||||||
double rd = rmask == JSVAL_MASK32_INT32 ? rval.data.s.payload.i32
|
return JSDOUBLE_COMPARE(ld, ==, rd, JS_FALSE);
|
||||||
: rval.data.asDouble;
|
}
|
||||||
|
if (lval.isInt32() && rval.isDouble()) {
|
||||||
|
double ld = lval.asInt32();
|
||||||
|
double rd = rval.asDouble();
|
||||||
return JSDOUBLE_COMPARE(ld, ==, rd, JS_FALSE);
|
return JSDOUBLE_COMPARE(ld, ==, rd, JS_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Value::isObjectMask(lmask) && Value::isObjectMask(rmask))
|
|
||||||
return EqualObjects(cx, lval.data.s.payload.obj, rval.data.s.payload.obj);
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1824,9 +1816,11 @@ namespace reprmeter {
|
|||||||
if ((vp)->isObject()) { \
|
if ((vp)->isObject()) { \
|
||||||
obj = &(vp)->asObject(); \
|
obj = &(vp)->asObject(); \
|
||||||
} else { \
|
} else { \
|
||||||
if (!js_ValueToNonNullObject(cx, *(vp), (vp))) \
|
Value v; \
|
||||||
|
if (!js_ValueToNonNullObject(cx, *(vp), &v)) \
|
||||||
goto error; \
|
goto error; \
|
||||||
obj = &(vp)->asObject(); \
|
*(vp) = v; \
|
||||||
|
obj = &v.asObject(); \
|
||||||
} \
|
} \
|
||||||
JS_END_MACRO
|
JS_END_MACRO
|
||||||
|
|
||||||
@ -1836,6 +1830,15 @@ namespace reprmeter {
|
|||||||
VALUE_TO_OBJECT(cx, vp_, obj); \
|
VALUE_TO_OBJECT(cx, vp_, obj); \
|
||||||
JS_END_MACRO
|
JS_END_MACRO
|
||||||
|
|
||||||
|
#define DEFAULT_VALUE(cx, n, hint, v) \
|
||||||
|
JS_BEGIN_MACRO \
|
||||||
|
JS_ASSERT(v.isObject()); \
|
||||||
|
JS_ASSERT(v == regs.sp[n]); \
|
||||||
|
if (!v.asObject().defaultValue(cx, hint, ®s.sp[n])) \
|
||||||
|
goto error; \
|
||||||
|
v = regs.sp[n]; \
|
||||||
|
JS_END_MACRO
|
||||||
|
|
||||||
/* Test whether v is an int in the range [-2^31 + 1, 2^31 - 2] */
|
/* Test whether v is an int in the range [-2^31 + 1, 2^31 - 2] */
|
||||||
static JS_ALWAYS_INLINE bool
|
static JS_ALWAYS_INLINE bool
|
||||||
CanIncDecWithoutOverflow(int32_t i)
|
CanIncDecWithoutOverflow(int32_t i)
|
||||||
|
@ -289,7 +289,7 @@ class PrimitiveValue
|
|||||||
static const uint32 Masks[THISP_ARRAY_SIZE];
|
static const uint32 Masks[THISP_ARRAY_SIZE];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const uint32 DOUBLE_MASK = 0x8000;
|
static const uint32 DOUBLE_MASK = 0xFFFF8000;
|
||||||
|
|
||||||
static bool test(JSFunction *fun, const Value &v) {
|
static bool test(JSFunction *fun, const Value &v) {
|
||||||
uint32 mask = Masks[(fun->flags >> THISP_SHIFT) & THISP_MASK];
|
uint32 mask = Masks[(fun->flags >> THISP_SHIFT) & THISP_MASK];
|
||||||
|
@ -493,16 +493,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.asString())) {
|
||||||
/*
|
/*
|
||||||
* 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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -710,7 +710,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
|
||||||
@ -725,7 +725,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);
|
||||||
@ -739,12 +739,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.
|
||||||
@ -798,7 +798,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -808,7 +808,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);
|
||||||
@ -821,13 +821,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.
|
||||||
|
@ -600,15 +600,6 @@ ValueFitsInInt32(const Value &v, int32_t *pi)
|
|||||||
return v.isDouble() && JSDOUBLE_IS_INT32(v.asDouble(), *pi);
|
return v.isDouble() && JSDOUBLE_IS_INT32(v.asDouble(), *pi);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JS_ALWAYS_INLINE void
|
|
||||||
Uint32ToValue(uint32_t u, Value *vp)
|
|
||||||
{
|
|
||||||
if (JS_UNLIKELY(u > INT32_MAX))
|
|
||||||
vp->setDouble(u);
|
|
||||||
else
|
|
||||||
vp->setInt32((int32_t)u);
|
|
||||||
}
|
|
||||||
|
|
||||||
JS_ALWAYS_INLINE
|
JS_ALWAYS_INLINE
|
||||||
Value::Value(NumberTag arg)
|
Value::Value(NumberTag arg)
|
||||||
{
|
{
|
||||||
|
@ -1484,7 +1484,7 @@ obj_unwatch(JSContext *cx, uintN argc, Value *vp)
|
|||||||
if (argc == 0)
|
if (argc == 0)
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
jsid id;
|
jsid id;
|
||||||
if (ValueToId(cx, vp[2], &id))
|
if (!ValueToId(cx, vp[2], &id))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
return JS_ClearWatchPoint(cx, obj, id, NULL, NULL);
|
return JS_ClearWatchPoint(cx, obj, id, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
@ -65,8 +65,8 @@ JSObject::getSlotMT(JSContext *cx, uintN slot)
|
|||||||
*/
|
*/
|
||||||
OBJ_CHECK_SLOT(this, slot);
|
OBJ_CHECK_SLOT(this, slot);
|
||||||
return (scope()->title.ownercx == cx)
|
return (scope()->title.ownercx == cx)
|
||||||
? this->lockedGetSlot(slot)
|
? this->lockedGetSlot(slot)
|
||||||
: js_GetSlotThreadSafe(cx, this, slot);
|
: js::Valueify(js_GetSlotThreadSafe(cx, this, slot));
|
||||||
#else
|
#else
|
||||||
return this->lockedGetSlot(slot);
|
return this->lockedGetSlot(slot);
|
||||||
#endif
|
#endif
|
||||||
@ -81,7 +81,7 @@ JSObject::setSlotMT(JSContext *cx, uintN slot, const js::Value &value)
|
|||||||
if (scope()->title.ownercx == cx)
|
if (scope()->title.ownercx == cx)
|
||||||
this->lockedSetSlot(slot, value);
|
this->lockedSetSlot(slot, value);
|
||||||
else
|
else
|
||||||
js_SetSlotThreadSafe(cx, this, slot, value);
|
js_SetSlotThreadSafe(cx, this, slot, Jsvalify(value));
|
||||||
#else
|
#else
|
||||||
this->lockedSetSlot(slot, value);
|
this->lockedSetSlot(slot, value);
|
||||||
#endif
|
#endif
|
||||||
@ -643,35 +643,35 @@ NewObject(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
|
|||||||
JS_ALWAYS_INLINE
|
JS_ALWAYS_INLINE
|
||||||
Value::Value(ObjectTag arg)
|
Value::Value(ObjectTag arg)
|
||||||
{
|
{
|
||||||
data.s.mask32 = arg.obj.isFunction() ? JSVAL_MASK32_FUNOBJ
|
JSValueMask32 mask = arg.obj.isFunction() ? JSVAL_MASK32_FUNOBJ
|
||||||
: JSVAL_MASK32_NONFUNOBJ;
|
: JSVAL_MASK32_NONFUNOBJ;
|
||||||
data.s.payload.obj = &arg.obj;
|
data = OBJECT_TO_JSVAL_IMPL(mask, &arg.obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_ALWAYS_INLINE
|
JS_ALWAYS_INLINE
|
||||||
Value::Value(ObjectOrNullTag arg)
|
Value::Value(ObjectOrNullTag arg)
|
||||||
{
|
{
|
||||||
data.s.mask32 = arg.obj ? arg.obj->isFunction() ? JSVAL_MASK32_FUNOBJ
|
JSValueMask32 mask = arg.obj ? arg.obj->isFunction() ? JSVAL_MASK32_FUNOBJ
|
||||||
: JSVAL_MASK32_NONFUNOBJ
|
: JSVAL_MASK32_NONFUNOBJ
|
||||||
: JSVAL_MASK32_NULL;
|
: JSVAL_MASK32_NULL;
|
||||||
data.s.payload.obj = arg.obj;
|
data = OBJECT_TO_JSVAL_IMPL(mask, arg.obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_ALWAYS_INLINE void
|
JS_ALWAYS_INLINE void
|
||||||
Value::setObject(JSObject &arg)
|
Value::setObject(JSObject &arg)
|
||||||
{
|
{
|
||||||
data.s.mask32 = arg.isFunction() ? JSVAL_MASK32_FUNOBJ
|
JSValueMask32 mask = arg.isFunction() ? JSVAL_MASK32_FUNOBJ
|
||||||
: JSVAL_MASK32_NONFUNOBJ;
|
: JSVAL_MASK32_NONFUNOBJ;
|
||||||
data.s.payload.obj = &arg;
|
data = OBJECT_TO_JSVAL_IMPL(mask, &arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_ALWAYS_INLINE void
|
JS_ALWAYS_INLINE void
|
||||||
Value::setObjectOrNull(JSObject *arg)
|
Value::setObjectOrNull(JSObject *arg)
|
||||||
{
|
{
|
||||||
data.s.mask32 = arg ? arg->isFunction() ? JSVAL_MASK32_FUNOBJ
|
JSValueMask32 mask = arg ? arg->isFunction() ? JSVAL_MASK32_FUNOBJ
|
||||||
: JSVAL_MASK32_NONFUNOBJ
|
: JSVAL_MASK32_NONFUNOBJ
|
||||||
: JSVAL_MASK32_NULL;
|
: JSVAL_MASK32_NULL;
|
||||||
data.s.payload.obj = arg;
|
data = OBJECT_TO_JSVAL_IMPL(mask, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace js */
|
} /* namespace js */
|
||||||
|
184
js/src/jsops.cpp
184
js/src/jsops.cpp
@ -816,9 +816,9 @@ END_CASE(JSOP_BITAND)
|
|||||||
*/
|
*/
|
||||||
#if JS_HAS_XML_SUPPORT
|
#if JS_HAS_XML_SUPPORT
|
||||||
#define XML_EQUALITY_OP(OP) \
|
#define XML_EQUALITY_OP(OP) \
|
||||||
if ((lmask == JSVAL_MASK32_NONFUNOBJ && lref.asObject().isXML()) || \
|
if ((lval.isNonFunObj() && lval.asObject().isXML()) || \
|
||||||
(rmask == JSVAL_MASK32_NONFUNOBJ && rref.asObject().isXML())) { \
|
(rval.isNonFunObj() && rval.asObject().isXML())) { \
|
||||||
if (!js_TestXMLEquality(cx, lref, rref, &cond)) \
|
if (!js_TestXMLEquality(cx, lval, rval, &cond)) \
|
||||||
goto error; \
|
goto error; \
|
||||||
cond = cond OP JS_TRUE; \
|
cond = cond OP JS_TRUE; \
|
||||||
} else
|
} else
|
||||||
@ -826,7 +826,7 @@ END_CASE(JSOP_BITAND)
|
|||||||
#define EXTENDED_EQUALITY_OP(OP) \
|
#define EXTENDED_EQUALITY_OP(OP) \
|
||||||
if (((clasp = l->getClass())->flags & JSCLASS_IS_EXTENDED) && \
|
if (((clasp = l->getClass())->flags & JSCLASS_IS_EXTENDED) && \
|
||||||
((ExtendedClass *)clasp)->equality) { \
|
((ExtendedClass *)clasp)->equality) { \
|
||||||
if (!((ExtendedClass *)clasp)->equality(cx, l, &rref, &cond)) \
|
if (!((ExtendedClass *)clasp)->equality(cx, l, &lval, &cond)) \
|
||||||
goto error; \
|
goto error; \
|
||||||
cond = cond OP JS_TRUE; \
|
cond = cond OP JS_TRUE; \
|
||||||
} else
|
} else
|
||||||
@ -837,57 +837,42 @@ END_CASE(JSOP_BITAND)
|
|||||||
|
|
||||||
#define EQUALITY_OP(OP, IFNAN) \
|
#define EQUALITY_OP(OP, IFNAN) \
|
||||||
JS_BEGIN_MACRO \
|
JS_BEGIN_MACRO \
|
||||||
/* Depends on the value representation. */ \
|
|
||||||
Class *clasp; \
|
Class *clasp; \
|
||||||
JSBool cond; \
|
JSBool cond; \
|
||||||
Value &rref = regs.sp[-1]; \
|
Value rval = regs.sp[-1]; \
|
||||||
Value &lref = regs.sp[-2]; \
|
Value lval = regs.sp[-2]; \
|
||||||
uint32 rmask = rref.data.s.mask32; \
|
|
||||||
uint32 lmask = lref.data.s.mask32; \
|
|
||||||
XML_EQUALITY_OP(OP) \
|
XML_EQUALITY_OP(OP) \
|
||||||
if (lmask == rmask || \
|
if (SamePrimitiveTypeOrBothObjects(lval, rval)) { \
|
||||||
(Value::isObjectMask(lmask) && Value::isObjectMask(rmask))) { \
|
if (lval.isString()) { \
|
||||||
if (lmask == JSVAL_MASK32_STRING) { \
|
JSString *l = lval.asString(), *r = rval.asString(); \
|
||||||
JSString *l = lref.asString(), *r = rref.asString(); \
|
|
||||||
cond = js_EqualStrings(l, r) OP JS_TRUE; \
|
cond = js_EqualStrings(l, r) OP JS_TRUE; \
|
||||||
} else if (Value::isObjectMask(lmask)) { \
|
} else if (lval.isDouble()) { \
|
||||||
JSObject *l = &lref.asObject(), *r = &rref.asObject(); \
|
double l = lval.asDouble(), r = rval.asDouble(); \
|
||||||
|
cond = JSDOUBLE_COMPARE(l, OP, r, IFNAN); \
|
||||||
|
} else if (lval.isObject()) { \
|
||||||
|
JSObject *l = &lval.asObject(), *r = &rval.asObject(); \
|
||||||
EXTENDED_EQUALITY_OP(OP) \
|
EXTENDED_EQUALITY_OP(OP) \
|
||||||
cond = l OP r; \
|
cond = l OP r; \
|
||||||
} else if (JS_UNLIKELY(Value::isDoubleMask(lmask))) { \
|
|
||||||
double l = lref.asDouble(), r = rref.asDouble(); \
|
|
||||||
cond = JSDOUBLE_COMPARE(l, OP, r, IFNAN); \
|
|
||||||
} else { \
|
} else { \
|
||||||
cond = lref.data.s.payload.u32 OP rref.data.s.payload.u32; \
|
cond = lval.asRawUint32() OP rval.asRawUint32(); \
|
||||||
} \
|
} \
|
||||||
} else if (Value::isDoubleMask(lmask) && Value::isDoubleMask(rmask)) { \
|
|
||||||
double l = lref.asDouble(), r = rref.asDouble(); \
|
|
||||||
cond = JSDOUBLE_COMPARE(l, OP, r, IFNAN); \
|
|
||||||
} else { \
|
} else { \
|
||||||
if (Value::isNullOrUndefinedMask(lmask)) { \
|
if (lval.isNullOrUndefined()) { \
|
||||||
cond = Value::isNullOrUndefinedMask(rmask) OP true; \
|
cond = rval.isNullOrUndefined() OP true; \
|
||||||
} else if (Value::isNullOrUndefinedMask(rmask)) { \
|
} else if (rval.isNullOrUndefined()) { \
|
||||||
cond = true OP false; \
|
cond = true OP false; \
|
||||||
} else { \
|
} else { \
|
||||||
if (Value::isObjectMask(lmask)) { \
|
if (lval.isObject()) \
|
||||||
JSObject &obj = lref.asObject(); \
|
DEFAULT_VALUE(cx, -2, JSTYPE_VOID, lval); \
|
||||||
if (!obj.defaultValue(cx, JSTYPE_VOID, &lref)) \
|
if (rval.isObject()) \
|
||||||
goto error; \
|
DEFAULT_VALUE(cx, -1, JSTYPE_VOID, rval); \
|
||||||
lmask = lref.data.s.mask32; \
|
if (BothString(lval, rval)) { \
|
||||||
} \
|
JSString *l = lval.asString(), *r = rval.asString(); \
|
||||||
if (Value::isObjectMask(rmask)) { \
|
|
||||||
JSObject &obj = rref.asObject(); \
|
|
||||||
if (!obj.defaultValue(cx, JSTYPE_VOID, &rref)) \
|
|
||||||
goto error; \
|
|
||||||
rmask = rref.data.s.mask32; \
|
|
||||||
} \
|
|
||||||
if (lmask == JSVAL_MASK32_STRING && rmask == JSVAL_MASK32_STRING) { \
|
|
||||||
JSString *l = lref.asString(), *r = rref.asString(); \
|
|
||||||
cond = js_EqualStrings(l, r) OP JS_TRUE; \
|
cond = js_EqualStrings(l, r) OP JS_TRUE; \
|
||||||
} else { \
|
} else { \
|
||||||
double l, r; \
|
double l, r; \
|
||||||
if (!ValueToNumber(cx, lref, &l) || \
|
if (!ValueToNumber(cx, lval, &l) || \
|
||||||
!ValueToNumber(cx, rref, &r)) { \
|
!ValueToNumber(cx, rval, &r)) { \
|
||||||
goto error; \
|
goto error; \
|
||||||
} \
|
} \
|
||||||
cond = JSDOUBLE_COMPARE(l, OP, r, IFNAN); \
|
cond = JSDOUBLE_COMPARE(l, OP, r, IFNAN); \
|
||||||
@ -963,39 +948,24 @@ END_CASE(JSOP_CASEX)
|
|||||||
|
|
||||||
#define RELATIONAL_OP(OP) \
|
#define RELATIONAL_OP(OP) \
|
||||||
JS_BEGIN_MACRO \
|
JS_BEGIN_MACRO \
|
||||||
/* Depends on the value representation */ \
|
Value rval = regs.sp[-1]; \
|
||||||
Value &rref = regs.sp[-1]; \
|
Value lval = regs.sp[-2]; \
|
||||||
Value &lref = regs.sp[-2]; \
|
|
||||||
uint32 rmask = rref.data.s.mask32; \
|
|
||||||
uint32 lmask = lref.data.s.mask32; \
|
|
||||||
uint32 maskand = lmask & rmask; \
|
|
||||||
bool cond; \
|
bool cond; \
|
||||||
/* Optimize for two int-tagged operands (typical loop control). */ \
|
/* Optimize for two int-tagged operands (typical loop control). */ \
|
||||||
if (maskand == JSVAL_MASK32_INT32) { \
|
if (BothInt32(lval, rval)) { \
|
||||||
cond = lref.asInt32() OP rref.asInt32(); \
|
cond = lval.asInt32() OP rval.asInt32(); \
|
||||||
} else { \
|
} else { \
|
||||||
if (Value::isObjectMask(lmask | rmask)) { \
|
if (lval.isObject()) \
|
||||||
if (Value::isObjectMask(lmask)) { \
|
DEFAULT_VALUE(cx, -2, JSTYPE_NUMBER, lval); \
|
||||||
JSObject &obj = lref.asObject(); \
|
if (rval.isObject()) \
|
||||||
if (!obj.defaultValue(cx, JSTYPE_NUMBER, &lref)) \
|
DEFAULT_VALUE(cx, -1, JSTYPE_NUMBER, rval); \
|
||||||
goto error; \
|
if (BothString(lval, rval)) { \
|
||||||
lmask = lref.data.s.mask32; \
|
JSString *l = lval.asString(), *r = rval.asString(); \
|
||||||
} \
|
|
||||||
if (Value::isObjectMask(rmask)) { \
|
|
||||||
JSObject &obj = rref.asObject(); \
|
|
||||||
if (!obj.defaultValue(cx, JSTYPE_NUMBER, &rref)) \
|
|
||||||
goto error; \
|
|
||||||
rmask = rref.data.s.mask32; \
|
|
||||||
} \
|
|
||||||
maskand = lmask & rmask; \
|
|
||||||
} \
|
|
||||||
if (maskand == JSVAL_MASK32_STRING) { \
|
|
||||||
JSString *l = lref.asString(), *r = rref.asString(); \
|
|
||||||
cond = js_CompareStrings(l, r) OP 0; \
|
cond = js_CompareStrings(l, r) OP 0; \
|
||||||
} else { \
|
} else { \
|
||||||
double l, r; \
|
double l, r; \
|
||||||
if (!ValueToNumber(cx, lref, &l) || \
|
if (!ValueToNumber(cx, lval, &l) || \
|
||||||
!ValueToNumber(cx, rref, &r)) { \
|
!ValueToNumber(cx, rval, &r)) { \
|
||||||
goto error; \
|
goto error; \
|
||||||
} \
|
} \
|
||||||
cond = JSDOUBLE_COMPARE(l, OP, r, false); \
|
cond = JSDOUBLE_COMPARE(l, OP, r, false); \
|
||||||
@ -1058,20 +1028,17 @@ BEGIN_CASE(JSOP_URSH)
|
|||||||
u >>= (j & 31);
|
u >>= (j & 31);
|
||||||
|
|
||||||
regs.sp--;
|
regs.sp--;
|
||||||
Uint32ToValue(u, ®s.sp[-1]);
|
regs.sp[-1].setNumber(uint32(u));
|
||||||
}
|
}
|
||||||
END_CASE(JSOP_URSH)
|
END_CASE(JSOP_URSH)
|
||||||
|
|
||||||
BEGIN_CASE(JSOP_ADD)
|
BEGIN_CASE(JSOP_ADD)
|
||||||
{
|
{
|
||||||
/* Depends on the value representation */
|
Value rval = regs.sp[-1];
|
||||||
Value &rref = regs.sp[-1];
|
Value lval = regs.sp[-2];
|
||||||
Value &lref = regs.sp[-2];
|
|
||||||
uint32 rmask = rref.data.s.mask32;
|
|
||||||
uint32 lmask = lref.data.s.mask32;
|
|
||||||
|
|
||||||
if ((lmask & rmask) == JSVAL_MASK32_INT32) {
|
if (BothInt32(lval, rval)) {
|
||||||
int32_t l = lref.asInt32(), r = rref.asInt32();
|
int32_t l = lval.asInt32(), r = rval.asInt32();
|
||||||
int32_t sum = l + r;
|
int32_t sum = l + r;
|
||||||
regs.sp--;
|
regs.sp--;
|
||||||
if (JS_UNLIKELY(bool((l ^ sum) & (r ^ sum) & 0x80000000)))
|
if (JS_UNLIKELY(bool((l ^ sum) & (r ^ sum) & 0x80000000)))
|
||||||
@ -1080,50 +1047,47 @@ BEGIN_CASE(JSOP_ADD)
|
|||||||
regs.sp[-1].setInt32(sum);
|
regs.sp[-1].setInt32(sum);
|
||||||
} else
|
} else
|
||||||
#if JS_HAS_XML_SUPPORT
|
#if JS_HAS_XML_SUPPORT
|
||||||
if (lmask == JSVAL_MASK32_NONFUNOBJ && lref.asObject().isXML() &&
|
if (lval.isNonFunObj() && lval.asObject().isXML() &&
|
||||||
rmask == JSVAL_MASK32_NONFUNOBJ && rref.asObject().isXML()) {
|
rval.isNonFunObj() && rval.asObject().isXML()) {
|
||||||
Value rval;
|
Value rval;
|
||||||
if (!js_ConcatenateXML(cx, &lref.asObject(), &rref.asObject(), &rval))
|
if (!js_ConcatenateXML(cx, &lval.asObject(), &rval.asObject(), &rval))
|
||||||
goto error;
|
goto error;
|
||||||
regs.sp--;
|
regs.sp--;
|
||||||
regs.sp[-1] = rval;
|
regs.sp[-1] = rval;
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (Value::isObjectMask(lmask)) {
|
if (lval.isObject())
|
||||||
if (!lref.asObject().defaultValue(cx, JSTYPE_VOID, &lref))
|
DEFAULT_VALUE(cx, -2, JSTYPE_VOID, lval);
|
||||||
goto error;
|
if (rval.isObject())
|
||||||
lmask = lref.data.s.mask32;
|
DEFAULT_VALUE(cx, -1, JSTYPE_VOID, rval);
|
||||||
}
|
bool lIsString, rIsString;
|
||||||
if (Value::isObjectMask(rmask)) {
|
if ((lIsString = lval.isString()) | (rIsString = rval.isString())) {
|
||||||
if (!rref.asObject().defaultValue(cx, JSTYPE_VOID, &rref))
|
JSString *lstr, *rstr;
|
||||||
goto error;
|
if (lIsString) {
|
||||||
rmask = rref.data.s.mask32;
|
lstr = lval.asString();
|
||||||
}
|
|
||||||
if (lmask == JSVAL_MASK32_STRING || rmask == JSVAL_MASK32_STRING) {
|
|
||||||
JSString *str1, *str2;
|
|
||||||
if (lmask == rmask) {
|
|
||||||
str1 = lref.asString();
|
|
||||||
str2 = rref.asString();
|
|
||||||
} else if (lmask == JSVAL_MASK32_STRING) {
|
|
||||||
str1 = lref.asString();
|
|
||||||
str2 = js_ValueToString(cx, rref);
|
|
||||||
if (!str2)
|
|
||||||
goto error;
|
|
||||||
} else {
|
} else {
|
||||||
str2 = rref.asString();
|
lstr = js_ValueToString(cx, lval);
|
||||||
str1 = js_ValueToString(cx, lref);
|
if (!lstr)
|
||||||
if (!str1)
|
|
||||||
goto error;
|
goto error;
|
||||||
|
regs.sp[-2].setString(lstr);
|
||||||
}
|
}
|
||||||
JSString *str = js_ConcatStrings(cx, str1, str2);
|
if (rIsString) {
|
||||||
|
rstr = rval.asString();
|
||||||
|
} else {
|
||||||
|
rstr = js_ValueToString(cx, rval);
|
||||||
|
if (!rstr)
|
||||||
|
goto error;
|
||||||
|
regs.sp[-1].setString(rstr);
|
||||||
|
}
|
||||||
|
JSString *str = js_ConcatStrings(cx, lstr, rstr);
|
||||||
if (!str)
|
if (!str)
|
||||||
goto error;
|
goto error;
|
||||||
regs.sp--;
|
regs.sp--;
|
||||||
regs.sp[-1].setString(str);
|
regs.sp[-1].setString(str);
|
||||||
} else {
|
} else {
|
||||||
double l, r;
|
double l, r;
|
||||||
if (!ValueToNumber(cx, lref, &l) || !ValueToNumber(cx, rref, &r))
|
if (!ValueToNumber(cx, lval, &l) || !ValueToNumber(cx, rval, &r))
|
||||||
goto error;
|
goto error;
|
||||||
l += r;
|
l += r;
|
||||||
regs.sp--;
|
regs.sp--;
|
||||||
@ -1788,9 +1752,7 @@ BEGIN_CASE(JSOP_CALLPROP)
|
|||||||
if (!atom) {
|
if (!atom) {
|
||||||
ASSERT_VALID_PROPERTY_CACHE_HIT(0, aobj, obj2, entry);
|
ASSERT_VALID_PROPERTY_CACHE_HIT(0, aobj, obj2, entry);
|
||||||
if (entry->vword.isFunObj()) {
|
if (entry->vword.isFunObj()) {
|
||||||
regs.sp[-1].setFunObj(entry->vword.toFunObj());
|
rval.setFunObj(entry->vword.toFunObj());
|
||||||
PUSH_COPY(lval);
|
|
||||||
goto end_callprop;
|
|
||||||
} else if (entry->vword.isSlot()) {
|
} else if (entry->vword.isSlot()) {
|
||||||
uint32 slot = entry->vword.toSlot();
|
uint32 slot = entry->vword.toSlot();
|
||||||
JS_ASSERT(slot < obj2->scope()->freeslot);
|
JS_ASSERT(slot < obj2->scope()->freeslot);
|
||||||
@ -2150,15 +2112,10 @@ END_CASE(JSOP_GETELEM)
|
|||||||
|
|
||||||
BEGIN_CASE(JSOP_CALLELEM)
|
BEGIN_CASE(JSOP_CALLELEM)
|
||||||
{
|
{
|
||||||
/* Depends on the value representation. */
|
|
||||||
|
|
||||||
/* Fetch the left part and resolve it to a non-null object. */
|
/* Fetch the left part and resolve it to a non-null object. */
|
||||||
JSObject *obj;
|
JSObject *obj;
|
||||||
FETCH_OBJECT(cx, -2, obj);
|
FETCH_OBJECT(cx, -2, obj);
|
||||||
|
|
||||||
/* Save the mask so that we don't need to query it later. */
|
|
||||||
uint32 objmask = regs.sp[-2].data.s.mask32;
|
|
||||||
|
|
||||||
/* Fetch index and convert it to id suitable for use with obj. */
|
/* Fetch index and convert it to id suitable for use with obj. */
|
||||||
jsid id;
|
jsid id;
|
||||||
FETCH_ELEMENT_ID(obj, -1, id);
|
FETCH_ELEMENT_ID(obj, -1, id);
|
||||||
@ -2176,8 +2133,7 @@ BEGIN_CASE(JSOP_CALLELEM)
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
regs.sp[-1].data.s.mask32 = objmask;
|
regs.sp[-1].setObject(*obj);
|
||||||
regs.sp[-1].data.s.payload.obj = obj;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
END_CASE(JSOP_CALLELEM)
|
END_CASE(JSOP_CALLELEM)
|
||||||
|
463
js/src/jspubtd.h
463
js/src/jspubtd.h
@ -158,35 +158,12 @@ typedef struct JSONParser JSONParser;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: wrong, fix, explain more
|
* TODO: explain boxing strategy
|
||||||
* Engine-internal value details:
|
|
||||||
*
|
|
||||||
* A jsval has an abstract type which is represented by a mask which assigns a
|
|
||||||
* bit to each type. This allows fast set-membership queries. However, we give
|
|
||||||
* one type (null) a mask of 0 for two reasons:
|
|
||||||
*
|
|
||||||
* 1. memset'ing values to 0 produces a valid value. This was true of the old,
|
|
||||||
* boxed jsvals (and now jsboxedwords) and eases the transition.
|
|
||||||
*
|
|
||||||
* 2. Testing for null can often be compiled to slightly shorter/faster code.
|
|
||||||
*
|
|
||||||
* The down-side is that set-membership queries need to be done more carefully.
|
|
||||||
* E.g., to test whether a value v is undefined or null, the correct test is:
|
|
||||||
*
|
|
||||||
* (v.mask & ~UndefinedMask) == 0
|
|
||||||
*
|
|
||||||
* instead of the intuitive (but incorrect) test:
|
|
||||||
*
|
|
||||||
* (v.mask & (NullMask | UndefinedMask)) != 0
|
|
||||||
*
|
|
||||||
* Since the value representation is kept a private detail of js::Value and
|
|
||||||
* only exposed to a few functions through friendship, this type of error
|
|
||||||
* should be hidden behind simple inline methods like v.isNullOrUndefined().
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef enum JSValueMask16
|
typedef enum JSValueMask16
|
||||||
#if defined(_MSC_VER) && _MSC_VER >= 1400
|
#if defined(_MSC_VER)
|
||||||
: unsigned short
|
: uint16
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
JSVAL_MASK16_NULL = (uint16)0x0001,
|
JSVAL_MASK16_NULL = (uint16)0x0001,
|
||||||
@ -203,6 +180,11 @@ typedef enum JSValueMask16
|
|||||||
JSVAL_MASK16_OBJORNULL = JSVAL_MASK16_OBJECT | JSVAL_MASK16_NULL,
|
JSVAL_MASK16_OBJORNULL = JSVAL_MASK16_OBJECT | JSVAL_MASK16_NULL,
|
||||||
JSVAL_MASK16_GCTHING = JSVAL_MASK16_OBJECT | JSVAL_MASK16_STRING,
|
JSVAL_MASK16_GCTHING = JSVAL_MASK16_OBJECT | JSVAL_MASK16_STRING,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This enumerator value plus __attribute__((packed)) plus the static
|
||||||
|
* assert that sizeof(JSValueMask16) == 2 should guarantee that enumerators
|
||||||
|
* are uint16 in GCC.
|
||||||
|
*/
|
||||||
JSVAL_NANBOX_PATTERN = ((uint16)0xFFFF)
|
JSVAL_NANBOX_PATTERN = ((uint16)0xFFFF)
|
||||||
}
|
}
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
@ -210,45 +192,36 @@ __attribute__((packed))
|
|||||||
#endif
|
#endif
|
||||||
JSValueMask16;
|
JSValueMask16;
|
||||||
|
|
||||||
#define JSVAL_MASK32_CLEAR ((uint32)0xFFFF0000)
|
typedef enum JSValueMask32
|
||||||
|
#if defined(_MSC_VER)
|
||||||
#define JSVAL_MASK32_NULL ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_NULL))
|
: uint32
|
||||||
#define JSVAL_MASK32_UNDEFINED ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_UNDEFINED))
|
|
||||||
#define JSVAL_MASK32_INT32 ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_INT32))
|
|
||||||
#define JSVAL_MASK32_STRING ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_STRING))
|
|
||||||
#define JSVAL_MASK32_NONFUNOBJ ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_NONFUNOBJ))
|
|
||||||
#define JSVAL_MASK32_FUNOBJ ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_FUNOBJ))
|
|
||||||
#define JSVAL_MASK32_BOOLEAN ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_BOOLEAN))
|
|
||||||
#define JSVAL_MASK32_MAGIC ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_MAGIC))
|
|
||||||
|
|
||||||
#define JSVAL_MASK32_SINGLETON ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_SINGLETON))
|
|
||||||
#define JSVAL_MASK32_OBJECT ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_OBJECT))
|
|
||||||
#define JSVAL_MASK32_OBJORNULL ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_OBJORNULL))
|
|
||||||
#define JSVAL_MASK32_GCTHING ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_GCTHING))
|
|
||||||
|
|
||||||
typedef enum JSWhyMagic
|
|
||||||
{
|
|
||||||
JS_ARRAY_HOLE, /* a hole in a dense array */
|
|
||||||
JS_ARGS_HOLE, /* a hole in the args object's array */
|
|
||||||
JS_NATIVE_ENUMERATE, /* indicates that a custom enumerate hook forwarded
|
|
||||||
* to js_Enumerate, which really means the object can be
|
|
||||||
* enumerated like a native object. */
|
|
||||||
JS_NO_ITER_VALUE, /* there is not a pending iterator value */
|
|
||||||
JS_GENERATOR_CLOSING /* exception value thrown when closing a generator */
|
|
||||||
} JSWhyMagic;
|
|
||||||
|
|
||||||
typedef union jsval_payload
|
|
||||||
{
|
|
||||||
int32 i32;
|
|
||||||
uint32 u32;
|
|
||||||
JSBool boo;
|
|
||||||
#if JS_BITS_PER_WORD == 32
|
|
||||||
JSString *str;
|
|
||||||
JSObject *obj;
|
|
||||||
void *ptr;
|
|
||||||
#endif
|
#endif
|
||||||
JSWhyMagic why;
|
{
|
||||||
} jsval_data;
|
/*
|
||||||
|
* This enumerator value plus __attribute__((packed)) plus the static
|
||||||
|
* assert that sizeof(JSValueMask32) == 4 should guarantee that enumerators
|
||||||
|
* are uint32 in GCC.
|
||||||
|
*/
|
||||||
|
JSVAL_MASK32_CLEAR = ((uint32)0xFFFF0000),
|
||||||
|
|
||||||
|
JSVAL_MASK32_NULL = ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_NULL)),
|
||||||
|
JSVAL_MASK32_UNDEFINED = ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_UNDEFINED)),
|
||||||
|
JSVAL_MASK32_INT32 = ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_INT32)),
|
||||||
|
JSVAL_MASK32_STRING = ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_STRING)),
|
||||||
|
JSVAL_MASK32_NONFUNOBJ = ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_NONFUNOBJ)),
|
||||||
|
JSVAL_MASK32_FUNOBJ = ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_FUNOBJ)),
|
||||||
|
JSVAL_MASK32_BOOLEAN = ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_BOOLEAN)),
|
||||||
|
JSVAL_MASK32_MAGIC = ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_MAGIC)),
|
||||||
|
|
||||||
|
JSVAL_MASK32_SINGLETON = ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_SINGLETON)),
|
||||||
|
JSVAL_MASK32_OBJECT = ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_OBJECT)),
|
||||||
|
JSVAL_MASK32_OBJORNULL = ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_OBJORNULL)),
|
||||||
|
JSVAL_MASK32_GCTHING = ((uint32)(JSVAL_MASK32_CLEAR | JSVAL_MASK16_GCTHING))
|
||||||
|
}
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
__attribute__((packed))
|
||||||
|
#endif
|
||||||
|
JSValueMask32;
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
# define VALUE_ALIGNMENT __attribute__((aligned (8)))
|
# define VALUE_ALIGNMENT __attribute__((aligned (8)))
|
||||||
@ -264,32 +237,376 @@ typedef union jsval_payload
|
|||||||
# error "TODO: do something for compiler"
|
# error "TODO: do something for compiler"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef VALUE_ALIGNMENT uint64 jsval;
|
||||||
|
|
||||||
|
#define BUILD_JSVAL(mask32, payload) ((jsval)((((uint64)(uint32)(mask32)) << 32) | (uint32)(payload)))
|
||||||
|
|
||||||
|
typedef enum JSWhyMagic
|
||||||
|
{
|
||||||
|
JS_ARRAY_HOLE, /* a hole in a dense array */
|
||||||
|
JS_ARGS_HOLE, /* a hole in the args object's array */
|
||||||
|
JS_NATIVE_ENUMERATE, /* indicates that a custom enumerate hook forwarded
|
||||||
|
* to js_Enumerate, which really means the object can be
|
||||||
|
* enumerated like a native object. */
|
||||||
|
JS_NO_ITER_VALUE, /* there is not a pending iterator value */
|
||||||
|
JS_GENERATOR_CLOSING /* exception value thrown when closing a generator */
|
||||||
|
} JSWhyMagic;
|
||||||
|
|
||||||
#if !defined(IS_LITTLE_ENDIAN)
|
#if !defined(IS_LITTLE_ENDIAN)
|
||||||
# error "Need to fix up jsval_layout"
|
# error "Unsupported configuration"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO: explain
|
|
||||||
typedef union jsval_layout
|
typedef union jsval_layout
|
||||||
{
|
{
|
||||||
uint64 asBits;
|
uint64 asBits;
|
||||||
struct {
|
struct {
|
||||||
jsval_payload payload;
|
union {
|
||||||
|
int32 i32;
|
||||||
|
uint32 u32;
|
||||||
|
JSBool boo;
|
||||||
|
#if JS_BITS_PER_WORD == 32
|
||||||
|
JSString *str;
|
||||||
|
JSObject *obj;
|
||||||
|
void *ptr;
|
||||||
|
#elif JS_BITS_PER_WORD == 64
|
||||||
|
uint32 ptr;
|
||||||
|
#else
|
||||||
|
# error "Unsupported configuration"
|
||||||
|
#endif
|
||||||
|
JSWhyMagic why;
|
||||||
|
} payload;
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
JSValueMask16 mask16;
|
JSValueMask16 mask16;
|
||||||
uint16 nanBits;
|
uint16 nanBits;
|
||||||
} tag;
|
} tag;
|
||||||
uint32 mask32;
|
JSValueMask32 mask32;
|
||||||
};
|
};
|
||||||
} s;
|
} s;
|
||||||
double asDouble;
|
double asDouble;
|
||||||
} jsval_layout;
|
} jsval_layout;
|
||||||
|
|
||||||
typedef uint64 jsval;
|
#if JS_BITS_PER_WORD == 32
|
||||||
|
|
||||||
/* These are engine-internal details, not part of the public API */
|
static JS_ALWAYS_INLINE JSBool
|
||||||
#define DOUBLE_AS_JSVAL(d) (*(jsval *)&(d))
|
JSVAL_IS_NULL_IMPL(jsval_layout l)
|
||||||
#define JSVAL_CONSTANT(mask32, payload) ((jsval)((((uint64)(mask32)) << 32) | (payload)))
|
{
|
||||||
|
return l.s.mask32 == JSVAL_MASK32_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSBool
|
||||||
|
JSVAL_IS_UNDEFINED_IMPL(jsval_layout l)
|
||||||
|
{
|
||||||
|
return l.s.mask32 == JSVAL_MASK32_UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSBool
|
||||||
|
JSVAL_IS_SPECIFIC_INT32_IMPL(jsval_layout l, int32 i32)
|
||||||
|
{
|
||||||
|
return l.s.mask32 == JSVAL_MASK32_INT32 && l.s.payload.i32 == i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE jsval_layout
|
||||||
|
INT32_TO_JSVAL_IMPL(int32 i)
|
||||||
|
{
|
||||||
|
jsval_layout l;
|
||||||
|
l.s.mask32 = JSVAL_MASK32_INT32;
|
||||||
|
l.s.payload.i32 = i;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSBool
|
||||||
|
JSVAL_IS_DOUBLE_IMPL(jsval_layout l)
|
||||||
|
{
|
||||||
|
return l.s.mask32 < JSVAL_MASK32_CLEAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE jsval_layout
|
||||||
|
DOUBLE_TO_JSVAL_IMPL(jsdouble d)
|
||||||
|
{
|
||||||
|
jsval_layout l;
|
||||||
|
l.asDouble = d;
|
||||||
|
JS_ASSERT(l.s.tag.nanBits != JSVAL_NANBOX_PATTERN);
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE jsval_layout
|
||||||
|
STRING_TO_JSVAL_IMPL(JSString *str)
|
||||||
|
{
|
||||||
|
jsval_layout l;
|
||||||
|
l.s.mask32 = JSVAL_MASK32_STRING;
|
||||||
|
l.s.payload.str = str;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSString *
|
||||||
|
JSVAL_TO_STRING_IMPL(jsval_layout l)
|
||||||
|
{
|
||||||
|
return l.s.payload.str;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSObject *
|
||||||
|
JSVAL_TO_OBJECT_IMPL(jsval_layout l)
|
||||||
|
{
|
||||||
|
return l.s.payload.obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE jsval_layout
|
||||||
|
OBJECT_TO_JSVAL_IMPL(JSValueMask32 mask, JSObject *obj)
|
||||||
|
{
|
||||||
|
jsval_layout l;
|
||||||
|
l.s.mask32 = mask;
|
||||||
|
l.s.payload.obj = obj;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE jsval_layout
|
||||||
|
BOOLEAN_TO_JSVAL_IMPL(JSBool b)
|
||||||
|
{
|
||||||
|
jsval_layout l;
|
||||||
|
l.s.mask32 = JSVAL_MASK32_BOOLEAN;
|
||||||
|
l.s.payload.boo = b;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE void *
|
||||||
|
JSVAL_TO_GCTHING_IMPL(jsval_layout l)
|
||||||
|
{
|
||||||
|
return l.s.payload.ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSBool
|
||||||
|
JSVAL_IS_SPECIFIC_BOOLEAN(jsval_layout l, JSBool b)
|
||||||
|
{
|
||||||
|
return (l.s.mask32 == JSVAL_MASK32_BOOLEAN) && (l.s.payload.boo == b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE jsval_layout
|
||||||
|
PRIVATE_TO_JSVAL_IMPL(void *ptr)
|
||||||
|
{
|
||||||
|
JS_ASSERT(((uint32)ptr & 1) == 0);
|
||||||
|
jsval_layout l;
|
||||||
|
l.s.tag.nanBits = 0;
|
||||||
|
l.s.payload.ptr = ptr;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE void *
|
||||||
|
JSVAL_TO_PRIVATE_IMPL(jsval_layout l)
|
||||||
|
{
|
||||||
|
return l.s.payload.ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE jsval_layout
|
||||||
|
MAGIC_TO_JSVAL_IMPL(JSWhyMagic why)
|
||||||
|
{
|
||||||
|
jsval_layout l;
|
||||||
|
l.s.mask32 = JSVAL_MASK32_MAGIC;
|
||||||
|
l.s.payload.why = why;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSBool
|
||||||
|
JSVAL_SAME_PRIMITIVE_TYPE_OR_BOTH_OBJECTS_IMPL(jsval_layout lhs, jsval_layout rhs)
|
||||||
|
{
|
||||||
|
return ((lhs.s.mask32 ^ rhs.s.mask32) & ~(uint32)JSVAL_MASK16_OBJECT) == 0 ||
|
||||||
|
(lhs.s.mask32 < JSVAL_MASK32_CLEAR && rhs.s.mask32 < JSVAL_MASK32_CLEAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSBool
|
||||||
|
JSVAL_BOTH_STRING_IMPL(jsval_layout lhs, jsval_layout rhs)
|
||||||
|
{
|
||||||
|
return (lhs.s.mask32 & rhs.s.mask32) == JSVAL_MASK32_STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSBool
|
||||||
|
JSVAL_BOTH_INT32_IMPL(jsval_layout lhs, jsval_layout rhs)
|
||||||
|
{
|
||||||
|
return (lhs.s.mask32 & rhs.s.mask32) == JSVAL_MASK32_INT32;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif JS_BITS_PER_WORD == 64
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSBool
|
||||||
|
JSVAL_IS_NULL_IMPL(jsval_layout l)
|
||||||
|
{
|
||||||
|
return l.asBits == BUILD_JSVAL(JSVAL_MASK32_NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSBool
|
||||||
|
JSVAL_IS_UNDEFINED_IMPL(jsval_layout l)
|
||||||
|
{
|
||||||
|
return l.asBits == BUILD_JSVAL(JSVAL_MASK32_UNDEFINED, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSBool
|
||||||
|
JSVAL_IS_SPECIFIC_INT32_IMPL(jsval_layout l, int32 i32)
|
||||||
|
{
|
||||||
|
return l.asBits == BUILD_JSVAL(JSVAL_MASK32_INT32, i32);
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE jsval_layout
|
||||||
|
INT32_TO_JSVAL_IMPL(int32 i)
|
||||||
|
{
|
||||||
|
jsval_layout l;
|
||||||
|
l.asBits = BUILD_JSVAL(JSVAL_MASK32_INT32, i);
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSBool
|
||||||
|
JSVAL_IS_DOUBLE_IMPL(jsval_layout l)
|
||||||
|
{
|
||||||
|
return l.asBits < BUILD_JSVAL(JSVAL_MASK32_CLEAR, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE jsval_layout
|
||||||
|
DOUBLE_TO_JSVAL_IMPL(jsdouble d)
|
||||||
|
{
|
||||||
|
jsval_layout l;
|
||||||
|
l.asDouble = d;
|
||||||
|
JS_ASSERT(l.s.tag.nanBits != JSVAL_NANBOX_PATTERN);
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE jsval_layout
|
||||||
|
STRING_TO_JSVAL_IMPL(JSString *str)
|
||||||
|
{
|
||||||
|
JS_ASSERT((size_t)str < (size_t)0xFFFFFFFF);
|
||||||
|
jsval_layout l;
|
||||||
|
l.asBits = BUILD_JSVAL(JSVAL_MASK32_STRING, (uint32)(size_t)str);
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSString *
|
||||||
|
JSVAL_TO_STRING_IMPL(jsval_layout l)
|
||||||
|
{
|
||||||
|
return (JSString *)(uint64)l.s.payload.ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSObject *
|
||||||
|
JSVAL_TO_OBJECT_IMPL(jsval_layout l)
|
||||||
|
{
|
||||||
|
return (JSObject *)(uint64)l.s.payload.ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE jsval_layout
|
||||||
|
OBJECT_TO_JSVAL_IMPL(JSValueMask32 mask32, JSObject *obj)
|
||||||
|
{
|
||||||
|
JS_ASSERT((size_t)obj < (size_t)0xFFFFFFFF);
|
||||||
|
jsval_layout l;
|
||||||
|
l.asBits = BUILD_JSVAL(mask32, (uint32)(size_t)obj);
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE jsval_layout
|
||||||
|
BOOLEAN_TO_JSVAL_IMPL(JSBool b)
|
||||||
|
{
|
||||||
|
jsval_layout l;
|
||||||
|
l.asBits = BUILD_JSVAL(JSVAL_MASK32_BOOLEAN, b);
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE void *
|
||||||
|
JSVAL_TO_GCTHING_IMPL(jsval_layout l)
|
||||||
|
{
|
||||||
|
return (void *)(uint64)l.s.payload.ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSBool
|
||||||
|
JSVAL_IS_SPECIFIC_BOOLEAN(jsval_layout l, JSBool b)
|
||||||
|
{
|
||||||
|
return l.asBits == BUILD_JSVAL(JSVAL_MASK32_BOOLEAN, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE jsval_layout
|
||||||
|
PRIVATE_TO_JSVAL_IMPL(void *ptr)
|
||||||
|
{
|
||||||
|
JS_ASSERT(((uint32)(size_t)ptr & 1) == 0);
|
||||||
|
jsval_layout l;
|
||||||
|
l.asBits = 0x8000000000000000LL | ((size_t)ptr >> 1);
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE void *
|
||||||
|
JSVAL_TO_PRIVATE_IMPL(jsval_layout l)
|
||||||
|
{
|
||||||
|
return (void *)(l.asBits << 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE jsval_layout
|
||||||
|
MAGIC_TO_JSVAL_IMPL(JSWhyMagic why)
|
||||||
|
{
|
||||||
|
jsval_layout l;
|
||||||
|
l.asBits = BUILD_JSVAL(JSVAL_MASK32_MAGIC, why);
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSBool
|
||||||
|
JSVAL_SAME_PRIMITIVE_TYPE_OR_BOTH_OBJECTS_IMPL(jsval_layout lhs, jsval_layout rhs)
|
||||||
|
{
|
||||||
|
uint32 xor32 = (uint32)((lhs.asBits ^ rhs.asBits) >> 32);
|
||||||
|
return (xor32 & ~(uint32)JSVAL_MASK16_OBJECT) == 0 ||
|
||||||
|
(JSVAL_IS_DOUBLE_IMPL(lhs) && JSVAL_IS_DOUBLE_IMPL(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSBool
|
||||||
|
JSVAL_BOTH_STRING_IMPL(jsval_layout lhs, jsval_layout rhs)
|
||||||
|
{
|
||||||
|
return (uint32)((lhs.asBits & rhs.asBits) >> 32) == JSVAL_MASK32_STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSBool
|
||||||
|
JSVAL_BOTH_INT32_IMPL(jsval_layout lhs, jsval_layout rhs)
|
||||||
|
{
|
||||||
|
return (uint32)((lhs.asBits & rhs.asBits) >> 32) == JSVAL_MASK32_INT32;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
# error "Unsupported configuration"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSBool
|
||||||
|
JSVAL_IS_SINGLETON_IMPL(jsval_layout l)
|
||||||
|
{
|
||||||
|
return (l.s.mask32 & JSVAL_MASK32_SINGLETON) > JSVAL_MASK32_CLEAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSBool
|
||||||
|
JSVAL_IS_NUMBER_IMPL(jsval_layout l)
|
||||||
|
{
|
||||||
|
JSValueMask32 mask = l.s.mask32;
|
||||||
|
return mask < JSVAL_MASK32_CLEAR || mask == JSVAL_MASK32_INT32;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSBool
|
||||||
|
JSVAL_IS_OBJECT_IMPL(jsval_layout l)
|
||||||
|
{
|
||||||
|
return (l.s.mask32 & JSVAL_MASK32_OBJECT) > JSVAL_MASK32_CLEAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSBool
|
||||||
|
JSVAL_IS_OBJECT_OR_NULL_IMPL(jsval_layout l)
|
||||||
|
{
|
||||||
|
return (l.s.mask32 & JSVAL_MASK32_OBJORNULL) > JSVAL_MASK32_CLEAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSBool
|
||||||
|
JSVAL_IS_PRIMITIVE_IMPL(jsval_layout l)
|
||||||
|
{
|
||||||
|
return (l.s.mask32 & JSVAL_MASK32_OBJECT) <= JSVAL_MASK32_CLEAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE JSBool
|
||||||
|
JSVAL_IS_GCTHING_IMPL(jsval_layout l)
|
||||||
|
{
|
||||||
|
return (l.s.mask32 & JSVAL_MASK32_GCTHING) > JSVAL_MASK32_CLEAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JS_ALWAYS_INLINE uint32
|
||||||
|
JSVAL_TRACE_KIND_IMPL(jsval_layout l)
|
||||||
|
{
|
||||||
|
return (uint32)(l.s.mask32 == JSVAL_MASK32_STRING);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Boxed word macros (private engine detail)
|
* Boxed word macros (private engine detail)
|
||||||
@ -396,7 +713,7 @@ static JS_ALWAYS_INLINE jsint
|
|||||||
JSBOXEDWORD_TO_SPECIAL(jsboxedword w)
|
JSBOXEDWORD_TO_SPECIAL(jsboxedword w)
|
||||||
{
|
{
|
||||||
JS_ASSERT(JSBOXEDWORD_IS_SPECIAL(w));
|
JS_ASSERT(JSBOXEDWORD_IS_SPECIAL(w));
|
||||||
return w >> JSBOXEDWORD_TAGBITS;
|
return jsint(w >> JSBOXEDWORD_TAGBITS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JS_ALWAYS_INLINE jsboxedword
|
static JS_ALWAYS_INLINE jsboxedword
|
||||||
|
@ -633,7 +633,7 @@ Class js_StringClass = {
|
|||||||
static JSString *
|
static JSString *
|
||||||
NormalizeThis(JSContext *cx, Value *vp)
|
NormalizeThis(JSContext *cx, Value *vp)
|
||||||
{
|
{
|
||||||
if (vp[1].isNull() || !ComputeThisFromVpInPlace(cx, vp) || vp[1].isNull())
|
if (vp[1].isNull() && (!ComputeThisFromVpInPlace(cx, vp) || vp[1].isNull()))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2640,7 +2640,11 @@ static const jschar UnitStringData[] = {
|
|||||||
#pragma pack(push, 8)
|
#pragma pack(push, 8)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef _M_X64
|
||||||
JSString JSString::unitStringTable[]
|
JSString JSString::unitStringTable[]
|
||||||
|
#else
|
||||||
|
JSString JSString::staticUnitStringTable[]
|
||||||
|
#endif
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
__attribute__ ((aligned (8)))
|
__attribute__ ((aligned (8)))
|
||||||
#endif
|
#endif
|
||||||
@ -2679,6 +2683,11 @@ __attribute__ ((aligned (8)))
|
|||||||
U(0xf8), U(0xf9), U(0xfa), U(0xfb), U(0xfc), U(0xfd), U(0xfe), U(0xff)
|
U(0xf8), U(0xf9), U(0xfa), U(0xfb), U(0xfc), U(0xfd), U(0xfe), U(0xff)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef _M_X64
|
||||||
|
JSString *JSString::unitStringTable = staticUnitStringTable;
|
||||||
|
size_t JSString::unitStringTableSize = sizeof(staticUnitStringTable);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __SUNPRO_CC
|
#ifdef __SUNPRO_CC
|
||||||
#pragma pack(0)
|
#pragma pack(0)
|
||||||
#else
|
#else
|
||||||
@ -2749,7 +2758,11 @@ static const jschar Hundreds[] = {
|
|||||||
#pragma pack(push, 8)
|
#pragma pack(push, 8)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef _M_X64
|
||||||
JSString JSString::intStringTable[]
|
JSString JSString::intStringTable[]
|
||||||
|
#else
|
||||||
|
JSString JSString::staticIntStringTable[]
|
||||||
|
#endif
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
__attribute__ ((aligned (8)))
|
__attribute__ ((aligned (8)))
|
||||||
#endif
|
#endif
|
||||||
@ -2788,6 +2801,11 @@ __attribute__ ((aligned (8)))
|
|||||||
L3(0xf8), L3(0xf9), L3(0xfa), L3(0xfb), L3(0xfc), L3(0xfd), L3(0xfe), L3(0xff)
|
L3(0xf8), L3(0xf9), L3(0xfa), L3(0xfb), L3(0xfc), L3(0xfd), L3(0xfe), L3(0xff)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef _M_X64
|
||||||
|
JSString *JSString::intStringTable = staticIntStringTable;
|
||||||
|
size_t JSString::intStringTableSize = sizeof(staticIntStringTable);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __SUNPRO_CC
|
#ifdef __SUNPRO_CC
|
||||||
#pragma pack(0)
|
#pragma pack(0)
|
||||||
#else
|
#else
|
||||||
|
@ -289,8 +289,20 @@ struct JSString {
|
|||||||
#pragma align 8 (__1cIJSStringPunitStringTable_, __1cIJSStringOintStringTable_)
|
#pragma align 8 (__1cIJSStringPunitStringTable_, __1cIJSStringOintStringTable_)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef _M_X64
|
||||||
static JSString unitStringTable[];
|
static JSString unitStringTable[];
|
||||||
static JSString intStringTable[];
|
static JSString intStringTable[];
|
||||||
|
#else
|
||||||
|
static JSString staticUnitStringTable[];
|
||||||
|
static JSString staticIntStringTable[];
|
||||||
|
static JSString *unitStringTable;
|
||||||
|
static JSString *intStringTable;
|
||||||
|
|
||||||
|
static size_t unitStringTableSize;
|
||||||
|
static size_t intStringTableSize;
|
||||||
|
static bool initStringTables();
|
||||||
|
static void freeStringTables();
|
||||||
|
#endif
|
||||||
static const char *deflatedIntStringTable[];
|
static const char *deflatedIntStringTable[];
|
||||||
static const char deflatedUnitStringTable[];
|
static const char deflatedUnitStringTable[];
|
||||||
|
|
||||||
|
@ -3298,10 +3298,10 @@ Scatter(JSContext *cx, uintN argc, jsval *vp)
|
|||||||
goto fail;
|
goto fail;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
sd.results[i] = JSVAL_VOID;
|
sd.results[i] = JSVAL_VOID;
|
||||||
ok = JS_AddRoot(cx, &sd.results[i]);
|
ok = JS_AddValueRoot(cx, &sd.results[i]);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
while (i-- > 0)
|
while (i-- > 0)
|
||||||
JS_RemoveRoot(cx, &sd.results[i]);
|
JS_RemoveValueRoot(cx, &sd.results[i]);
|
||||||
free(sd.results);
|
free(sd.results);
|
||||||
sd.results = NULL;
|
sd.results = NULL;
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -3318,14 +3318,14 @@ Scatter(JSContext *cx, uintN argc, jsval *vp)
|
|||||||
sd.threads[i].cx = NULL;
|
sd.threads[i].cx = NULL;
|
||||||
sd.threads[i].fn = JSVAL_NULL;
|
sd.threads[i].fn = JSVAL_NULL;
|
||||||
|
|
||||||
ok = JS_AddRoot(cx, &sd.threads[i].fn);
|
ok = JS_AddValueRoot(cx, &sd.threads[i].fn);
|
||||||
if (ok && !JS_GetElement(cx, inArr, (jsint) i, &sd.threads[i].fn)) {
|
if (ok && !JS_GetElement(cx, inArr, (jsint) i, &sd.threads[i].fn)) {
|
||||||
JS_RemoveRoot(cx, &sd.threads[i].fn);
|
JS_RemoveValueRoot(cx, &sd.threads[i].fn);
|
||||||
ok = JS_FALSE;
|
ok = JS_FALSE;
|
||||||
}
|
}
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
while (i-- > 0)
|
while (i-- > 0)
|
||||||
JS_RemoveRoot(cx, &sd.threads[i].fn);
|
JS_RemoveValueRoot(cx, &sd.threads[i].fn);
|
||||||
free(sd.threads);
|
free(sd.threads);
|
||||||
sd.threads = NULL;
|
sd.threads = NULL;
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -3393,7 +3393,7 @@ out:
|
|||||||
JSContext *acx;
|
JSContext *acx;
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
JS_RemoveRoot(cx, &sd.threads[i].fn);
|
JS_RemoveValueRoot(cx, &sd.threads[i].fn);
|
||||||
acx = sd.threads[i].cx;
|
acx = sd.threads[i].cx;
|
||||||
if (acx) {
|
if (acx) {
|
||||||
JS_SetContextThread(acx);
|
JS_SetContextThread(acx);
|
||||||
@ -3404,7 +3404,7 @@ out:
|
|||||||
}
|
}
|
||||||
if (sd.results) {
|
if (sd.results) {
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
JS_RemoveRoot(cx, &sd.results[i]);
|
JS_RemoveValueRoot(cx, &sd.results[i]);
|
||||||
free(sd.results);
|
free(sd.results);
|
||||||
}
|
}
|
||||||
if (sd.cvar)
|
if (sd.cvar)
|
||||||
@ -5091,7 +5091,7 @@ main(int argc, char **argv, char **envp)
|
|||||||
JSObject *newGlobalObject(JSContext *cx) { return NewGlobalObject(cx); }
|
JSObject *newGlobalObject(JSContext *cx) { return NewGlobalObject(cx); }
|
||||||
};
|
};
|
||||||
ShellWorkerHooks hooks;
|
ShellWorkerHooks hooks;
|
||||||
if (!JS_AddNamedRoot(cx, &gWorkers, "Workers") ||
|
if (!JS_AddNamedObjectRoot(cx, &gWorkers, "Workers") ||
|
||||||
!js::workers::init(cx, &hooks, glob, &gWorkers)) {
|
!js::workers::init(cx, &hooks, glob, &gWorkers)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -5101,7 +5101,7 @@ main(int argc, char **argv, char **envp)
|
|||||||
|
|
||||||
#ifdef JS_THREADSAFE
|
#ifdef JS_THREADSAFE
|
||||||
js::workers::finish(cx, gWorkers);
|
js::workers::finish(cx, gWorkers);
|
||||||
JS_RemoveRoot(cx, &gWorkers);
|
JS_RemoveObjectRoot(cx, &gWorkers);
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
result = gExitCode;
|
result = gExitCode;
|
||||||
#endif
|
#endif
|
||||||
|
@ -670,7 +670,7 @@ class Worker : public WorkerParent
|
|||||||
return !w->checkTermination();
|
return !w->checkTermination();
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool jsResolveGlobal(JSContext *cx, JSObject *obj, jsval id, uintN flags,
|
static JSBool jsResolveGlobal(JSContext *cx, JSObject *obj, jsid id, uintN flags,
|
||||||
JSObject **objp)
|
JSObject **objp)
|
||||||
{
|
{
|
||||||
if ((flags & JSRESOLVE_ASSIGNING) == 0) {
|
if ((flags & JSRESOLVE_ASSIGNING) == 0) {
|
||||||
@ -869,7 +869,7 @@ class InitEvent : public Event
|
|||||||
return fail;
|
return fail;
|
||||||
|
|
||||||
AutoValueRooter rval(cx);
|
AutoValueRooter rval(cx);
|
||||||
JSBool ok = JS_ExecuteScript(cx, child->getGlobal(), script, rval.addr());
|
JSBool ok = JS_ExecuteScript(cx, child->getGlobal(), script, Jsvalify(rval.addr()));
|
||||||
JS_DestroyScript(cx, script);
|
JS_DestroyScript(cx, script);
|
||||||
return Result(ok);
|
return Result(ok);
|
||||||
}
|
}
|
||||||
@ -906,7 +906,7 @@ class ErrorEvent : public Event
|
|||||||
JSString *data = NULL;
|
JSString *data = NULL;
|
||||||
jsval exc;
|
jsval exc;
|
||||||
if (JS_GetPendingException(cx, &exc)) {
|
if (JS_GetPendingException(cx, &exc)) {
|
||||||
AutoValueRooter tvr(cx, exc);
|
AutoValueRooter tvr(cx, Valueify(exc));
|
||||||
JS_ClearPendingException(cx);
|
JS_ClearPendingException(cx);
|
||||||
|
|
||||||
// Determine what error message to put in the error event.
|
// Determine what error message to put in the error event.
|
||||||
|
@ -125,10 +125,10 @@ class ResultsSink:
|
|||||||
# key is (result, expect, random)
|
# key is (result, expect, random)
|
||||||
# value is (tinderbox label, dev test category)
|
# value is (tinderbox label, dev test category)
|
||||||
LABELS = {
|
LABELS = {
|
||||||
(TestResult.CRASH, False, False): ('TEST-UNEXPECTED-CRASH', 'REGRESSIONS'),
|
(TestResult.CRASH, False, False): ('TEST-UNEXPECTED-FAIL', 'REGRESSIONS'),
|
||||||
(TestResult.CRASH, False, True): ('TEST-UNEXPECTED-CRASH', 'REGRESSIONS'),
|
(TestResult.CRASH, False, True): ('TEST-UNEXPECTED-FAIL', 'REGRESSIONS'),
|
||||||
(TestResult.CRASH, True, False): ('TEST-UNEXPECTED-CRASH', 'REGRESSIONS'),
|
(TestResult.CRASH, True, False): ('TEST-UNEXPECTED-FAIL', 'REGRESSIONS'),
|
||||||
(TestResult.CRASH, True, True): ('TEST-UNEXPECTED-CRASH', 'REGRESSIONS'),
|
(TestResult.CRASH, True, True): ('TEST-UNEXPECTED-FAIL', 'REGRESSIONS'),
|
||||||
|
|
||||||
(TestResult.FAIL, False, False): ('TEST-KNOWN-FAIL', ''),
|
(TestResult.FAIL, False, False): ('TEST-KNOWN-FAIL', ''),
|
||||||
(TestResult.FAIL, False, True): ('TEST-KNOWN-FAIL (EXPECTED RANDOM)', ''),
|
(TestResult.FAIL, False, True): ('TEST-KNOWN-FAIL (EXPECTED RANDOM)', ''),
|
||||||
|
Loading…
Reference in New Issue
Block a user