mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Introduce ObjectOps for typeOf and make trace a mandatory ObjectOp (547314, r=brendan).
This commit is contained in:
parent
bfa1d960a9
commit
7fc1c8efb0
@ -496,49 +496,13 @@ JS_TypeOfValue(JSContext *cx, jsval v)
|
||||
{
|
||||
JSType type;
|
||||
JSObject *obj;
|
||||
const JSObjectOps *ops;
|
||||
JSClass *clasp;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
if (JSVAL_IS_OBJECT(v)) {
|
||||
type = JSTYPE_OBJECT; /* XXXbe JSTYPE_NULL for JS2 */
|
||||
obj = JSVAL_TO_OBJECT(v);
|
||||
if (obj) {
|
||||
obj = js_GetWrappedObject(cx, obj);
|
||||
|
||||
ops = obj->map->ops;
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
if (ops == &js_XMLObjectOps) {
|
||||
type = JSTYPE_XML;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/*
|
||||
* ECMA 262, 11.4.3 says that any native object that implements
|
||||
* [[Call]] should be of type "function". However, RegExp is of
|
||||
* type "object", not "function", for Web compatibility.
|
||||
*/
|
||||
clasp = OBJ_GET_CLASS(cx, obj);
|
||||
if ((ops == &js_ObjectOps)
|
||||
? (clasp->call
|
||||
? clasp == &js_ScriptClass
|
||||
: clasp == &js_FunctionClass)
|
||||
: ops->call != NULL) {
|
||||
type = JSTYPE_FUNCTION;
|
||||
} else {
|
||||
#ifdef NARCISSUS
|
||||
JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);
|
||||
|
||||
if (!obj->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.__call__Atom),
|
||||
&v)) {
|
||||
JS_ClearPendingException(cx);
|
||||
} else if (VALUE_IS_FUNCTION(cx, v)) {
|
||||
type = JSTYPE_FUNCTION;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
if (obj)
|
||||
return obj->map->ops->typeOf(cx, obj);
|
||||
return JSTYPE_OBJECT;
|
||||
} else if (JSVAL_IS_NUMBER(v)) {
|
||||
type = JSTYPE_NUMBER;
|
||||
} else if (JSVAL_IS_STRING(v)) {
|
||||
|
@ -828,6 +828,12 @@ static JSBool
|
||||
slowarray_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
||||
jsval *statep, jsid *idp);
|
||||
|
||||
static JSType
|
||||
array_typeOf(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return JSTYPE_OBJECT;
|
||||
}
|
||||
|
||||
/* The same as js_ObjectOps except for the .enumerate and .call hooks. */
|
||||
static JSObjectOps js_SlowArrayObjectOps = {
|
||||
NULL,
|
||||
@ -836,10 +842,10 @@ static JSObjectOps js_SlowArrayObjectOps = {
|
||||
js_GetAttributes, js_SetAttributes,
|
||||
js_DeleteProperty, js_DefaultValue,
|
||||
slowarray_enumerate, js_CheckAccess,
|
||||
array_typeOf, js_TraceObject,
|
||||
NULL, NATIVE_DROP_PROPERTY,
|
||||
NULL, js_Construct,
|
||||
js_HasInstance, js_TraceObject,
|
||||
js_Clear
|
||||
js_HasInstance, js_Clear
|
||||
};
|
||||
|
||||
static JSObjectOps *
|
||||
@ -1248,10 +1254,10 @@ JSObjectOps js_ArrayObjectOps = {
|
||||
array_getAttributes, array_setAttributes,
|
||||
array_deleteProperty, js_DefaultValue,
|
||||
array_enumerate, js_CheckAccess,
|
||||
array_typeOf, array_trace,
|
||||
NULL, array_dropProperty,
|
||||
NULL, NULL,
|
||||
js_HasInstance, array_trace,
|
||||
NULL
|
||||
js_HasInstance, NULL
|
||||
};
|
||||
|
||||
static JSObjectOps *
|
||||
|
@ -329,8 +329,7 @@ JS_DEFINE_CALLINFO_3(extern, BOOL, js_HasNamedPropertyInt32, CONTEXT, OBJECT, IN
|
||||
JSString* FASTCALL
|
||||
js_TypeOfObject(JSContext* cx, JSObject* obj)
|
||||
{
|
||||
JSType type = JS_TypeOfValue(cx, OBJECT_TO_JSVAL(obj));
|
||||
return ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[type]);
|
||||
return ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[obj->typeOf(cx)]);
|
||||
}
|
||||
JS_DEFINE_CALLINFO_2(extern, STRING, js_TypeOfObject, CONTEXT, OBJECT, 1, 1)
|
||||
|
||||
|
@ -111,10 +111,10 @@ JS_FRIEND_DATA(JSObjectOps) js_ObjectOps = {
|
||||
js_GetAttributes, js_SetAttributes,
|
||||
js_DeleteProperty, js_DefaultValue,
|
||||
js_Enumerate, js_CheckAccess,
|
||||
js_TypeOf, js_TraceObject,
|
||||
NULL, NATIVE_DROP_PROPERTY,
|
||||
js_Call, js_Construct,
|
||||
js_HasInstance, js_TraceObject,
|
||||
js_Clear
|
||||
js_HasInstance, js_Clear
|
||||
};
|
||||
|
||||
JSClass js_ObjectClass = {
|
||||
@ -1821,7 +1821,7 @@ js_obj_defineGetter(JSContext *cx, uintN argc, jsval *vp)
|
||||
JSObject *obj;
|
||||
uintN attrs;
|
||||
|
||||
if (argc <= 1 || JS_TypeOfValue(cx, vp[3]) != JSTYPE_FUNCTION) {
|
||||
if (argc <= 1 || !js_IsCallable(cx, vp[3])) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_BAD_GETTER_OR_SETTER,
|
||||
js_getter_str);
|
||||
@ -1854,7 +1854,7 @@ js_obj_defineSetter(JSContext *cx, uintN argc, jsval *vp)
|
||||
JSObject *obj;
|
||||
uintN attrs;
|
||||
|
||||
if (argc <= 1 || JS_TypeOfValue(cx, vp[3]) != JSTYPE_FUNCTION) {
|
||||
if (argc <= 1 || !js_IsCallable(cx, vp[3])) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_BAD_GETTER_OR_SETTER,
|
||||
js_setter_str);
|
||||
@ -3319,6 +3319,12 @@ with_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
|
||||
return proto->checkAccess(cx, id, mode, vp, attrsp);
|
||||
}
|
||||
|
||||
static JSType
|
||||
with_TypeOf(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return JSTYPE_OBJECT;
|
||||
}
|
||||
|
||||
static JSObject *
|
||||
with_ThisObject(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
@ -3335,10 +3341,10 @@ JS_FRIEND_DATA(JSObjectOps) js_WithObjectOps = {
|
||||
with_GetAttributes, with_SetAttributes,
|
||||
with_DeleteProperty, with_DefaultValue,
|
||||
with_Enumerate, with_CheckAccess,
|
||||
with_TypeOf, js_TraceObject,
|
||||
with_ThisObject, NATIVE_DROP_PROPERTY,
|
||||
NULL, NULL,
|
||||
NULL, js_TraceObject,
|
||||
js_Clear
|
||||
NULL, js_Clear
|
||||
};
|
||||
|
||||
static JSObjectOps *
|
||||
@ -6017,6 +6023,38 @@ js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
|
||||
return !check || check(cx, pobj, ID_TO_VALUE(id), mode, vp);
|
||||
}
|
||||
|
||||
JSType
|
||||
js_TypeOf(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
/*
|
||||
* Wrappers should also intercept js_TypeOf and answer accordingly.
|
||||
*/
|
||||
JS_ASSERT(js_GetWrappedObject(cx, obj) == obj);
|
||||
|
||||
/*
|
||||
* ECMA 262, 11.4.3 says that any native object that implements
|
||||
* [[Call]] should be of type "function". However, RegExp is of
|
||||
* type "object", not "function", for Web compatibility.
|
||||
*/
|
||||
if (obj->isCallable(cx)) {
|
||||
return (obj->getClass() != &js_RegExpClass)
|
||||
? JSTYPE_FUNCTION
|
||||
: JSTYPE_OBJECT;
|
||||
}
|
||||
|
||||
#ifdef NARCISSUS
|
||||
JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);
|
||||
|
||||
if (!obj->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.__call__Atom), &v)) {
|
||||
JS_ClearPendingException(cx);
|
||||
} else if (VALUE_IS_FUNCTION(cx, v)) {
|
||||
return JSTYPE_FUNCTION;
|
||||
}
|
||||
#endif
|
||||
|
||||
return JSTYPE_OBJECT;
|
||||
}
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
void
|
||||
js_DropProperty(JSContext *cx, JSObject *obj, JSProperty *prop)
|
||||
|
@ -154,6 +154,8 @@ struct JSObjectOps {
|
||||
JSConvertOp defaultValue;
|
||||
JSNewEnumerateOp enumerate;
|
||||
JSCheckAccessIdOp checkAccess;
|
||||
JSTypeOfOp typeOf;
|
||||
JSTraceOp trace;
|
||||
|
||||
/* Optionally non-null members start here. */
|
||||
JSObjectOp thisObject;
|
||||
@ -161,7 +163,6 @@ struct JSObjectOps {
|
||||
JSNative call;
|
||||
JSNative construct;
|
||||
JSHasInstanceOp hasInstance;
|
||||
JSTraceOp trace;
|
||||
JSFinalizeOp clear;
|
||||
|
||||
bool inline isNative() const;
|
||||
@ -414,6 +415,10 @@ struct JSObject {
|
||||
return map->ops->checkAccess(cx, this, id, mode, vp, attrsp);
|
||||
}
|
||||
|
||||
JSType typeOf(JSContext *cx) {
|
||||
return map->ops->typeOf(cx, this);
|
||||
}
|
||||
|
||||
/* These four are time-optimized to avoid stub calls. */
|
||||
JSObject *thisObject(JSContext *cx) {
|
||||
return map->ops->thisObject ? map->ops->thisObject(cx, this) : this;
|
||||
@ -1002,6 +1007,9 @@ extern JSBool
|
||||
js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
|
||||
jsval *vp, uintN *attrsp);
|
||||
|
||||
extern JSType
|
||||
js_TypeOf(JSContext *cx, JSObject *obj);
|
||||
|
||||
extern JSBool
|
||||
js_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
|
@ -3292,7 +3292,7 @@ BEGIN_CASE(JSOP_SETTER)
|
||||
if (id == 0)
|
||||
FETCH_ELEMENT_ID(obj, i, id);
|
||||
|
||||
if (JS_TypeOfValue(cx, rval) != JSTYPE_FUNCTION) {
|
||||
if (!js_IsCallable(cx, rval)) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_BAD_GETTER_OR_SETTER,
|
||||
(op == JSOP_GETTER)
|
||||
|
@ -260,6 +260,12 @@ typedef JSBool
|
||||
typedef JSBool
|
||||
(* JSConvertOp)(JSContext *cx, JSObject *obj, JSType type, jsval *vp);
|
||||
|
||||
/*
|
||||
* Delegate typeof to an object so it can cloak a primitive or another object.
|
||||
*/
|
||||
typedef JSType
|
||||
(* JSTypeOfOp)(JSContext *cx, JSObject *obj);
|
||||
|
||||
/*
|
||||
* Finalize obj, which the garbage collector has determined to be unreachable
|
||||
* from other live objects or from GC roots. Obviously, finalizers must never
|
||||
|
@ -1953,7 +1953,7 @@ str_replace(JSContext *cx, uintN argc, jsval *vp)
|
||||
NORMALIZE_THIS(cx, vp, rdata.str);
|
||||
|
||||
/* Extract replacement string/function. */
|
||||
if (argc >= 2 && JS_TypeOfValue(cx, vp[3]) == JSTYPE_FUNCTION) {
|
||||
if (argc >= 2 && js_IsCallable(cx, vp[3])) {
|
||||
rdata.lambda = JSVAL_TO_OBJECT(vp[3]);
|
||||
rdata.repstr = NULL;
|
||||
rdata.dollar = rdata.dollarEnd = NULL;
|
||||
|
@ -599,6 +599,12 @@ class TypedArrayTemplate
|
||||
return true;
|
||||
}
|
||||
|
||||
static JSType
|
||||
obj_typeOf(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return JSTYPE_OBJECT;
|
||||
}
|
||||
|
||||
/*
|
||||
* new [Type]Array(length)
|
||||
* new [Type]Array(otherTypedArray)
|
||||
@ -1186,10 +1192,11 @@ template<> JSObjectOps _typedArray::fastObjectOps = { \
|
||||
js_DefaultValue, \
|
||||
_typedArray::obj_enumerate, \
|
||||
js_CheckAccess, \
|
||||
_typedArray::obj_typeOf, \
|
||||
_typedArray::obj_trace, \
|
||||
NULL, \
|
||||
_typedArray::obj_dropProperty, \
|
||||
NULL, NULL, NULL, \
|
||||
TypedArray::obj_trace, \
|
||||
NULL \
|
||||
}; \
|
||||
template<> JSFunctionSpec _typedArray::jsfuncs[] = { \
|
||||
|
@ -84,7 +84,6 @@
|
||||
* - Fuse objects and their JSXML* private data into single GC-things
|
||||
* - fix function::foo vs. x.(foo == 42) collision using proper namespacing
|
||||
* - JSCLASS_DOCUMENT_OBSERVER support -- live two-way binding to Gecko's DOM!
|
||||
* - JS_TypeOfValue sure could use a cleaner interface to "types"
|
||||
*/
|
||||
|
||||
#ifdef XML_METERING
|
||||
@ -5045,6 +5044,12 @@ xml_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSType
|
||||
xml_typeOf(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return JSTYPE_XML;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
xml_hasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
|
||||
{
|
||||
@ -5314,10 +5319,10 @@ JS_FRIEND_DATA(JSObjectOps) js_XMLObjectOps = {
|
||||
xml_getAttributes, xml_setAttributes,
|
||||
xml_deleteProperty, xml_defaultValue,
|
||||
xml_enumerate, js_CheckAccess,
|
||||
xml_typeOf, js_TraceObject,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
xml_hasInstance, js_TraceObject,
|
||||
xml_clear
|
||||
xml_hasInstance, xml_clear
|
||||
};
|
||||
|
||||
static JSObjectOps *
|
||||
|
@ -1405,6 +1405,18 @@ XPC_WN_JSOp_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
||||
return js_ObjectOps.enumerate(cx, obj, enum_op, statep, idp);
|
||||
}
|
||||
|
||||
static JSType
|
||||
XPC_WN_JSOp_TypeOf_Object(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return JSTYPE_OBJECT;
|
||||
}
|
||||
|
||||
static JSType
|
||||
XPC_WN_JSOp_TypeOf_Function(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return JSTYPE_FUNCTION;
|
||||
}
|
||||
|
||||
static void
|
||||
XPC_WN_JSOp_Clear(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
@ -1554,11 +1566,13 @@ JSBool xpc_InitWrappedNativeJSOps()
|
||||
XPC_WN_NoCall_JSOps.enumerate = XPC_WN_JSOp_Enumerate;
|
||||
XPC_WN_NoCall_JSOps.call = nsnull;
|
||||
XPC_WN_NoCall_JSOps.construct = nsnull;
|
||||
XPC_WN_NoCall_JSOps.typeOf = XPC_WN_JSOp_TypeOf_Object;
|
||||
XPC_WN_NoCall_JSOps.clear = XPC_WN_JSOp_Clear;
|
||||
XPC_WN_NoCall_JSOps.thisObject = XPC_WN_JSOp_ThisObject;
|
||||
|
||||
memcpy(&XPC_WN_WithCall_JSOps, &js_ObjectOps, sizeof(JSObjectOps));
|
||||
XPC_WN_WithCall_JSOps.enumerate = XPC_WN_JSOp_Enumerate;
|
||||
XPC_WN_WithCall_JSOps.typeOf = XPC_WN_JSOp_TypeOf_Function;
|
||||
XPC_WN_WithCall_JSOps.clear = XPC_WN_JSOp_Clear;
|
||||
XPC_WN_WithCall_JSOps.thisObject = XPC_WN_JSOp_ThisObject;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user