зеркало из https://github.com/mozilla/gecko-dev.git
Bug 480759 - TM: trace RegExp constructors (r=gal).
This commit is contained in:
Родитель
1426d5bdd2
Коммит
cb20b7a6e7
153
js/src/jsapi.cpp
153
js/src/jsapi.cpp
|
@ -2750,158 +2750,9 @@ JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
|
|||
JSPropertySpec *ps, JSFunctionSpec *fs,
|
||||
JSPropertySpec *static_ps, JSFunctionSpec *static_fs)
|
||||
{
|
||||
return JS_InitTraceableClass(cx, obj, parent_proto, clasp, constructor, nargs,
|
||||
ps, fs, static_ps, static_fs, NULL);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_InitTraceableClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
|
||||
JSClass *clasp, JSNative constructor, uintN nargs,
|
||||
JSPropertySpec *ps, JSFunctionSpec *fs,
|
||||
JSPropertySpec *static_ps, JSFunctionSpec *static_fs,
|
||||
JSTraceableNative *trcinfo)
|
||||
{
|
||||
JSAtom *atom;
|
||||
JSProtoKey key;
|
||||
JSObject *proto, *ctor;
|
||||
JSTempValueRooter tvr;
|
||||
jsval cval, rval;
|
||||
JSBool named;
|
||||
JSFunction *fun;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
atom = js_Atomize(cx, clasp->name, strlen(clasp->name), 0);
|
||||
if (!atom)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* When initializing a standard class, if no parent_proto (grand-proto of
|
||||
* instances of the class, parent-proto of the class's prototype object)
|
||||
* is given, we must use Object.prototype if it is available. Otherwise,
|
||||
* we could look up the wrong binding for a class name in obj. Example:
|
||||
*
|
||||
* String = Array;
|
||||
* print("hi there".join);
|
||||
*
|
||||
* should print undefined, not Array.prototype.join. This is required by
|
||||
* ECMA-262, alas. It might have been better to make String readonly and
|
||||
* permanent in the global object, instead -- but that's too big a change
|
||||
* to swallow at this point.
|
||||
*/
|
||||
key = JSCLASS_CACHED_PROTO_KEY(clasp);
|
||||
if (key != JSProto_Null &&
|
||||
!parent_proto &&
|
||||
!js_GetClassPrototype(cx, obj, INT_TO_JSID(JSProto_Object),
|
||||
&parent_proto)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create a prototype object for this class. */
|
||||
proto = js_NewObject(cx, clasp, parent_proto, obj, 0);
|
||||
if (!proto)
|
||||
return NULL;
|
||||
|
||||
/* After this point, control must exit via label bad or out. */
|
||||
JS_PUSH_TEMP_ROOT_OBJECT(cx, proto, &tvr);
|
||||
|
||||
if (!constructor) {
|
||||
JS_ASSERT(!trcinfo);
|
||||
|
||||
/*
|
||||
* Lacking a constructor, name the prototype (e.g., Math) unless this
|
||||
* class (a) is anonymous, i.e. for internal use only; (b) the class
|
||||
* of obj (the global object) is has a reserved slot indexed by key;
|
||||
* and (c) key is not the null key.
|
||||
*/
|
||||
if ((clasp->flags & JSCLASS_IS_ANONYMOUS) &&
|
||||
(OBJ_GET_CLASS(cx, obj)->flags & JSCLASS_IS_GLOBAL) &&
|
||||
key != JSProto_Null) {
|
||||
named = JS_FALSE;
|
||||
} else {
|
||||
named = OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom),
|
||||
OBJECT_TO_JSVAL(proto),
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
(clasp->flags & JSCLASS_IS_ANONYMOUS)
|
||||
? JSPROP_READONLY | JSPROP_PERMANENT
|
||||
: 0,
|
||||
NULL);
|
||||
if (!named)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
ctor = proto;
|
||||
} else {
|
||||
/* Define the constructor function in obj's scope. */
|
||||
fun = js_DefineFunction(cx, obj, atom, constructor, nargs,
|
||||
JSFUN_STUB_GSOPS);
|
||||
named = (fun != NULL);
|
||||
if (!fun)
|
||||
goto bad;
|
||||
|
||||
/*
|
||||
* Remember the class this function is a constructor for so that
|
||||
* we know to create an object of this class when we call the
|
||||
* constructor.
|
||||
*/
|
||||
FUN_CLASP(fun) = clasp;
|
||||
|
||||
/*
|
||||
* If we have a traceable native constructor, update the function to
|
||||
* point at the given trcinfo and flag it.
|
||||
*/
|
||||
if (trcinfo) {
|
||||
fun->u.n.trcinfo = trcinfo;
|
||||
fun->flags |= JSFUN_TRACEABLE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Optionally construct the prototype object, before the class has
|
||||
* been fully initialized. Allow the ctor to replace proto with a
|
||||
* different object, as is done for operator new -- and as at least
|
||||
* XML support requires.
|
||||
*/
|
||||
ctor = FUN_OBJECT(fun);
|
||||
if (clasp->flags & JSCLASS_CONSTRUCT_PROTOTYPE) {
|
||||
cval = OBJECT_TO_JSVAL(ctor);
|
||||
if (!js_InternalConstruct(cx, proto, cval, 0, NULL, &rval))
|
||||
goto bad;
|
||||
if (!JSVAL_IS_PRIMITIVE(rval) && JSVAL_TO_OBJECT(rval) != proto)
|
||||
proto = JSVAL_TO_OBJECT(rval);
|
||||
}
|
||||
|
||||
/* Connect constructor and prototype by named properties. */
|
||||
if (!js_SetClassPrototype(cx, ctor, proto,
|
||||
JSPROP_READONLY | JSPROP_PERMANENT)) {
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* Bootstrap Function.prototype (see also JS_InitStandardClasses). */
|
||||
if (OBJ_GET_CLASS(cx, ctor) == clasp) {
|
||||
OBJ_SET_PROTO(cx, ctor, proto);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add properties and methods to the prototype and the constructor. */
|
||||
if ((ps && !JS_DefineProperties(cx, proto, ps)) ||
|
||||
(fs && !JS_DefineFunctions(cx, proto, fs)) ||
|
||||
(static_ps && !JS_DefineProperties(cx, ctor, static_ps)) ||
|
||||
(static_fs && !JS_DefineFunctions(cx, ctor, static_fs))) {
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* If this is a standard class, cache its prototype. */
|
||||
if (key != JSProto_Null && !js_SetClassObject(cx, obj, key, ctor))
|
||||
goto bad;
|
||||
|
||||
out:
|
||||
JS_POP_TEMP_ROOT(cx, &tvr);
|
||||
return proto;
|
||||
|
||||
bad:
|
||||
if (named)
|
||||
(void) OBJ_DELETE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), &rval);
|
||||
proto = NULL;
|
||||
goto out;
|
||||
return js_InitClass(cx, obj, parent_proto, clasp, constructor, nargs,
|
||||
ps, fs, static_ps, static_fs, NULL);
|
||||
}
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
|
|
|
@ -1568,13 +1568,6 @@ JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
|
|||
JSPropertySpec *ps, JSFunctionSpec *fs,
|
||||
JSPropertySpec *static_ps, JSFunctionSpec *static_fs);
|
||||
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_InitTraceableClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
|
||||
JSClass *clasp, JSNative constructor, uintN nargs,
|
||||
JSPropertySpec *ps, JSFunctionSpec *fs,
|
||||
JSPropertySpec *static_ps, JSFunctionSpec *static_fs,
|
||||
JSTraceableNative *trcinfo);
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
extern JS_PUBLIC_API(JSClass *)
|
||||
JS_GetClass(JSContext *cx, JSObject *obj);
|
||||
|
|
|
@ -2175,29 +2175,17 @@ static JSObject* FASTCALL
|
|||
Date_tn(JSContext* cx, JSObject* proto)
|
||||
{
|
||||
JS_ASSERT(JS_ON_TRACE(cx));
|
||||
JSObject* obj = (JSObject*) js_NewGCThing(cx, GCX_OBJECT, sizeof(JSObject));
|
||||
JSObject* obj = js_NewNativeObject(cx, &js_DateClass, proto, JSSLOT_LOCAL_TIME + 1);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
JSClass* clasp = &js_DateClass;
|
||||
obj->classword = jsuword(clasp);
|
||||
|
||||
obj->fslots[JSSLOT_PROTO] = OBJECT_TO_JSVAL(proto);
|
||||
obj->fslots[JSSLOT_PARENT] = proto->fslots[JSSLOT_PARENT];
|
||||
|
||||
jsdouble* date = js_NewWeaklyRootedDouble(cx, 0.0);
|
||||
if (!date)
|
||||
return NULL;
|
||||
*date = date_now_tn(cx);
|
||||
|
||||
obj->fslots[JSSLOT_UTC_TIME] = DOUBLE_TO_JSVAL(date);
|
||||
obj->fslots[JSSLOT_LOCAL_TIME] = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
|
||||
for (unsigned i = JSSLOT_LOCAL_TIME + 1; i != JS_INITIAL_NSLOTS; ++i)
|
||||
obj->fslots[i] = JSVAL_VOID;
|
||||
|
||||
JS_ASSERT(!clasp->getObjectOps);
|
||||
JS_ASSERT(proto->map->ops == &js_ObjectOps);
|
||||
obj->map = js_HoldObjectMap(cx, proto->map);
|
||||
obj->dslots = NULL;
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -2218,9 +2206,9 @@ js_InitDateClass(JSContext *cx, JSObject *obj)
|
|||
|
||||
/* set static LocalTZA */
|
||||
LocalTZA = -(PRMJ_LocalGMTDifference() * msPerSecond);
|
||||
proto = JS_InitTraceableClass(cx, obj, NULL, &js_DateClass, js_Date, MAXARGS,
|
||||
NULL, date_methods, NULL, date_static_methods,
|
||||
js_Date_trcinfo);
|
||||
proto = js_InitClass(cx, obj, NULL, &js_DateClass, js_Date, MAXARGS,
|
||||
NULL, date_methods, NULL, date_static_methods,
|
||||
js_Date_trcinfo);
|
||||
if (!proto)
|
||||
return NULL;
|
||||
|
||||
|
|
182
js/src/jsobj.cpp
182
js/src/jsobj.cpp
|
@ -2002,9 +2002,11 @@ NewNativeObject(JSContext* cx, JSObject* proto, JSObject *parent)
|
|||
obj->classword = jsuword(&js_ObjectClass);
|
||||
obj->fslots[JSSLOT_PROTO] = OBJECT_TO_JSVAL(proto);
|
||||
obj->fslots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(parent);
|
||||
for (unsigned i = JSSLOT_PRIVATE; i != JS_INITIAL_NSLOTS; ++i)
|
||||
for (unsigned i = JSSLOT_PRIVATE; i < JS_INITIAL_NSLOTS; ++i)
|
||||
obj->fslots[i] = JSVAL_VOID;
|
||||
|
||||
JS_ASSERT(!OBJ_GET_CLASS(cx, proto)->getObjectOps);
|
||||
JS_ASSERT(proto->map->ops == &js_ObjectOps);
|
||||
obj->map = js_HoldObjectMap(cx, proto->map);
|
||||
obj->dslots = NULL;
|
||||
return obj;
|
||||
|
@ -2644,9 +2646,157 @@ js_InitEval(JSContext *cx, JSObject *obj)
|
|||
JSObject *
|
||||
js_InitObjectClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return JS_InitTraceableClass(cx, obj, NULL, &js_ObjectClass, js_Object, 1,
|
||||
object_props, object_methods, NULL, object_static_methods,
|
||||
js_Object_trcinfo);
|
||||
return js_InitClass(cx, obj, NULL, &js_ObjectClass, js_Object, 1,
|
||||
object_props, object_methods, NULL, object_static_methods,
|
||||
js_Object_trcinfo);
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
|
||||
JSClass *clasp, JSNative constructor, uintN nargs,
|
||||
JSPropertySpec *ps, JSFunctionSpec *fs,
|
||||
JSPropertySpec *static_ps, JSFunctionSpec *static_fs,
|
||||
JSTraceableNative *trcinfo)
|
||||
{
|
||||
JSAtom *atom;
|
||||
JSProtoKey key;
|
||||
JSObject *proto, *ctor;
|
||||
JSTempValueRooter tvr;
|
||||
jsval cval, rval;
|
||||
JSBool named;
|
||||
JSFunction *fun;
|
||||
|
||||
atom = js_Atomize(cx, clasp->name, strlen(clasp->name), 0);
|
||||
if (!atom)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* When initializing a standard class, if no parent_proto (grand-proto of
|
||||
* instances of the class, parent-proto of the class's prototype object)
|
||||
* is given, we must use Object.prototype if it is available. Otherwise,
|
||||
* we could look up the wrong binding for a class name in obj. Example:
|
||||
*
|
||||
* String = Array;
|
||||
* print("hi there".join);
|
||||
*
|
||||
* should print undefined, not Array.prototype.join. This is required by
|
||||
* ECMA-262, alas. It might have been better to make String readonly and
|
||||
* permanent in the global object, instead -- but that's too big a change
|
||||
* to swallow at this point.
|
||||
*/
|
||||
key = JSCLASS_CACHED_PROTO_KEY(clasp);
|
||||
if (key != JSProto_Null &&
|
||||
!parent_proto &&
|
||||
!js_GetClassPrototype(cx, obj, INT_TO_JSID(JSProto_Object),
|
||||
&parent_proto)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create a prototype object for this class. */
|
||||
proto = js_NewObject(cx, clasp, parent_proto, obj, 0);
|
||||
if (!proto)
|
||||
return NULL;
|
||||
|
||||
/* After this point, control must exit via label bad or out. */
|
||||
JS_PUSH_TEMP_ROOT_OBJECT(cx, proto, &tvr);
|
||||
|
||||
if (!constructor) {
|
||||
JS_ASSERT(!trcinfo);
|
||||
|
||||
/*
|
||||
* Lacking a constructor, name the prototype (e.g., Math) unless this
|
||||
* class (a) is anonymous, i.e. for internal use only; (b) the class
|
||||
* of obj (the global object) is has a reserved slot indexed by key;
|
||||
* and (c) key is not the null key.
|
||||
*/
|
||||
if ((clasp->flags & JSCLASS_IS_ANONYMOUS) &&
|
||||
(OBJ_GET_CLASS(cx, obj)->flags & JSCLASS_IS_GLOBAL) &&
|
||||
key != JSProto_Null) {
|
||||
named = JS_FALSE;
|
||||
} else {
|
||||
named = OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom),
|
||||
OBJECT_TO_JSVAL(proto),
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
(clasp->flags & JSCLASS_IS_ANONYMOUS)
|
||||
? JSPROP_READONLY | JSPROP_PERMANENT
|
||||
: 0,
|
||||
NULL);
|
||||
if (!named)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
ctor = proto;
|
||||
} else {
|
||||
/* Define the constructor function in obj's scope. */
|
||||
fun = js_DefineFunction(cx, obj, atom, constructor, nargs,
|
||||
JSFUN_STUB_GSOPS);
|
||||
named = (fun != NULL);
|
||||
if (!fun)
|
||||
goto bad;
|
||||
|
||||
/*
|
||||
* Remember the class this function is a constructor for so that
|
||||
* we know to create an object of this class when we call the
|
||||
* constructor.
|
||||
*/
|
||||
FUN_CLASP(fun) = clasp;
|
||||
|
||||
/*
|
||||
* If we have a traceable native constructor, update the function to
|
||||
* point at the given trcinfo and flag it.
|
||||
*/
|
||||
if (trcinfo) {
|
||||
fun->u.n.trcinfo = trcinfo;
|
||||
fun->flags |= JSFUN_TRACEABLE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Optionally construct the prototype object, before the class has
|
||||
* been fully initialized. Allow the ctor to replace proto with a
|
||||
* different object, as is done for operator new -- and as at least
|
||||
* XML support requires.
|
||||
*/
|
||||
ctor = FUN_OBJECT(fun);
|
||||
if (clasp->flags & JSCLASS_CONSTRUCT_PROTOTYPE) {
|
||||
cval = OBJECT_TO_JSVAL(ctor);
|
||||
if (!js_InternalConstruct(cx, proto, cval, 0, NULL, &rval))
|
||||
goto bad;
|
||||
if (!JSVAL_IS_PRIMITIVE(rval) && JSVAL_TO_OBJECT(rval) != proto)
|
||||
proto = JSVAL_TO_OBJECT(rval);
|
||||
}
|
||||
|
||||
/* Connect constructor and prototype by named properties. */
|
||||
if (!js_SetClassPrototype(cx, ctor, proto,
|
||||
JSPROP_READONLY | JSPROP_PERMANENT)) {
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* Bootstrap Function.prototype (see also JS_InitStandardClasses). */
|
||||
if (OBJ_GET_CLASS(cx, ctor) == clasp)
|
||||
OBJ_SET_PROTO(cx, ctor, proto);
|
||||
}
|
||||
|
||||
/* Add properties and methods to the prototype and the constructor. */
|
||||
if ((ps && !JS_DefineProperties(cx, proto, ps)) ||
|
||||
(fs && !JS_DefineFunctions(cx, proto, fs)) ||
|
||||
(static_ps && !JS_DefineProperties(cx, ctor, static_ps)) ||
|
||||
(static_fs && !JS_DefineFunctions(cx, ctor, static_fs))) {
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* If this is a standard class, cache its prototype. */
|
||||
if (key != JSProto_Null && !js_SetClassObject(cx, obj, key, ctor))
|
||||
goto bad;
|
||||
|
||||
out:
|
||||
JS_POP_TEMP_ROOT(cx, &tvr);
|
||||
return proto;
|
||||
|
||||
bad:
|
||||
if (named)
|
||||
(void) OBJ_DELETE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), &rval);
|
||||
proto = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2928,7 +3078,7 @@ js_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto,
|
|||
STOBJ_SET_PARENT(obj, parent);
|
||||
|
||||
/* Initialize the remaining fixed slots. */
|
||||
for (i = JSSLOT_PRIVATE; i != JS_INITIAL_NSLOTS; ++i)
|
||||
for (i = JSSLOT_PRIVATE; i < JS_INITIAL_NSLOTS; ++i)
|
||||
obj->fslots[i] = JSVAL_VOID;
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -3022,6 +3172,28 @@ earlybad:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
js_NewNativeObject(JSContext *cx, JSClass *clasp, JSObject *proto, uint32 slot)
|
||||
{
|
||||
JSObject* obj = (JSObject*) js_NewGCThing(cx, GCX_OBJECT, sizeof(JSObject));
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
obj->classword = jsuword(clasp);
|
||||
obj->fslots[JSSLOT_PROTO] = OBJECT_TO_JSVAL(proto);
|
||||
obj->fslots[JSSLOT_PARENT] = proto->fslots[JSSLOT_PARENT];
|
||||
|
||||
JS_ASSERT(slot > JSSLOT_PARENT);
|
||||
while (slot < JS_INITIAL_NSLOTS)
|
||||
obj->fslots[slot++] = JSVAL_VOID;
|
||||
|
||||
JS_ASSERT(!clasp->getObjectOps);
|
||||
JS_ASSERT(proto->map->ops == &js_ObjectOps);
|
||||
obj->map = js_HoldObjectMap(cx, proto->map);
|
||||
obj->dslots = NULL;
|
||||
return obj;
|
||||
}
|
||||
|
||||
JS_BEGIN_EXTERN_C
|
||||
|
||||
static JSObject *
|
||||
|
|
|
@ -438,6 +438,13 @@ js_InitEval(JSContext *cx, JSObject *obj);
|
|||
extern JSObject *
|
||||
js_InitObjectClass(JSContext *cx, JSObject *obj);
|
||||
|
||||
extern JSObject *
|
||||
js_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
|
||||
JSClass *clasp, JSNative constructor, uintN nargs,
|
||||
JSPropertySpec *ps, JSFunctionSpec *fs,
|
||||
JSPropertySpec *static_ps, JSFunctionSpec *static_fs,
|
||||
JSTraceableNative *trcinfo);
|
||||
|
||||
/*
|
||||
* Select Object.prototype method names shared between jsapi.cpp and jsobj.cpp.
|
||||
*/
|
||||
|
@ -485,6 +492,19 @@ extern JSObject *
|
|||
js_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto,
|
||||
JSObject *parent, uintN objectSize);
|
||||
|
||||
/*
|
||||
* Allocate a new native object and initialize all fslots with JSVAL_VOID
|
||||
* starting with the specified slot. The parent slot is set to the value of
|
||||
* proto's parent slot.
|
||||
*
|
||||
* Note that this is the correct global object for native class instances, but
|
||||
* not for user-defined functions called as constructors. Functions used as
|
||||
* constructors must create instances parented by the parent of the function
|
||||
* object, not by the parent of its .prototype object value.
|
||||
*/
|
||||
extern JSObject*
|
||||
js_NewNativeObject(JSContext *cx, JSClass *clasp, JSObject *proto, uint32 slot);
|
||||
|
||||
/*
|
||||
* Fast access to immutable standard objects (constructors and prototypes).
|
||||
*/
|
||||
|
|
|
@ -125,6 +125,7 @@ typedef struct JSScopeProperty JSScopeProperty;
|
|||
typedef struct JSStackHeader JSStackHeader;
|
||||
typedef struct JSStringBuffer JSStringBuffer;
|
||||
typedef struct JSSubString JSSubString;
|
||||
typedef struct JSTraceableNative JSTraceableNative;
|
||||
typedef struct JSXML JSXML;
|
||||
typedef struct JSXMLArray JSXMLArray;
|
||||
typedef struct JSXMLArrayCursor JSXMLArrayCursor;
|
||||
|
|
|
@ -150,7 +150,6 @@ typedef struct JSRuntime JSTaskState; /* XXX deprecated name */
|
|||
typedef struct JSScript JSScript;
|
||||
typedef struct JSStackFrame JSStackFrame;
|
||||
typedef struct JSString JSString;
|
||||
typedef struct JSTraceableNative JSTraceableNative;
|
||||
typedef struct JSXDRState JSXDRState;
|
||||
typedef struct JSExceptionState JSExceptionState;
|
||||
typedef struct JSLocaleCallbacks JSLocaleCallbacks;
|
||||
|
|
|
@ -4950,35 +4950,72 @@ RegExp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
return regexp_compile_sub(cx, obj, argc, argv, rval);
|
||||
}
|
||||
|
||||
static JSObject* FASTCALL
|
||||
RegExp_tn1(JSContext *cx, JSObject *proto, JSString *str)
|
||||
{
|
||||
JSObject* obj = js_NewNativeObject(cx, &js_RegExpClass, proto, JSSLOT_PRIVATE);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
jsval argv[] = { JSVAL_NULL, OBJECT_TO_JSVAL(obj), STRING_TO_JSVAL(str) };
|
||||
jsval rval;
|
||||
|
||||
if (!regexp_compile_sub(cx, obj, 1, argv + 2, &rval))
|
||||
return NULL;
|
||||
|
||||
JS_ASSERT(JSVAL_IS_OBJECT(rval));
|
||||
return JSVAL_TO_OBJECT(rval);
|
||||
}
|
||||
|
||||
static JSObject* FASTCALL
|
||||
RegExp_tn2(JSContext *cx, JSObject *proto, JSString *str, JSString *opt)
|
||||
{
|
||||
JSObject* obj = js_NewNativeObject(cx, &js_RegExpClass, proto, JSSLOT_PRIVATE);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
jsval argv[] = { JSVAL_NULL, OBJECT_TO_JSVAL(obj), STRING_TO_JSVAL(str), STRING_TO_JSVAL(opt) };
|
||||
jsval rval;
|
||||
|
||||
if (!regexp_compile_sub(cx, obj, 2, argv + 2, &rval))
|
||||
return NULL;
|
||||
|
||||
JS_ASSERT(JSVAL_IS_OBJECT(rval));
|
||||
return JSVAL_TO_OBJECT(rval);
|
||||
}
|
||||
|
||||
JS_DEFINE_TRCINFO_2(RegExp,
|
||||
(3, (extern, CONSTRUCTOR_RETRY, RegExp_tn1, CONTEXT, CALLEE_PROTOTYPE, STRING, 0, 0)),
|
||||
(4, (extern, CONSTRUCTOR_RETRY, RegExp_tn2, CONTEXT, CALLEE_PROTOTYPE, STRING, STRING, 0, 0)))
|
||||
|
||||
JSObject *
|
||||
js_InitRegExpClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JSObject *proto, *ctor;
|
||||
jsval rval;
|
||||
JSObject *proto = js_InitClass(cx, obj, NULL, &js_RegExpClass, RegExp, 1,
|
||||
regexp_props, regexp_methods,
|
||||
regexp_static_props, NULL,
|
||||
RegExp_trcinfo);
|
||||
|
||||
proto = JS_InitClass(cx, obj, NULL, &js_RegExpClass, RegExp, 1,
|
||||
regexp_props, regexp_methods,
|
||||
regexp_static_props, NULL);
|
||||
|
||||
if (!proto || !(ctor = JS_GetConstructor(cx, proto)))
|
||||
if (!proto)
|
||||
return NULL;
|
||||
|
||||
JSObject *ctor = JS_GetConstructor(cx, proto);
|
||||
if (!ctor)
|
||||
return NULL;
|
||||
|
||||
/* Give RegExp.prototype private data so it matches the empty string. */
|
||||
jsval rval;
|
||||
if (!JS_AliasProperty(cx, ctor, "input", "$_") ||
|
||||
!JS_AliasProperty(cx, ctor, "multiline", "$*") ||
|
||||
!JS_AliasProperty(cx, ctor, "lastMatch", "$&") ||
|
||||
!JS_AliasProperty(cx, ctor, "lastParen", "$+") ||
|
||||
!JS_AliasProperty(cx, ctor, "leftContext", "$`") ||
|
||||
!JS_AliasProperty(cx, ctor, "rightContext", "$'")) {
|
||||
goto bad;
|
||||
!JS_AliasProperty(cx, ctor, "rightContext", "$'") ||
|
||||
!regexp_compile_sub(cx, proto, 0, NULL, &rval)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Give RegExp.prototype private data so it matches the empty string. */
|
||||
if (!regexp_compile_sub(cx, proto, 0, NULL, &rval))
|
||||
goto bad;
|
||||
return proto;
|
||||
|
||||
bad:
|
||||
JS_DeleteProperty(cx, obj, js_RegExpClass.name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
|
|
|
@ -3002,7 +3002,7 @@ js_CheckGlobalObjectShape(JSContext* cx, JSTraceMonitor* tm, JSObject* globalObj
|
|||
AUDIT(globalShapeMismatchAtEntry);
|
||||
debug_only_v(printf("Global shape mismatch (%u vs. %u), flushing cache.\n",
|
||||
globalShape, ti->globalShape);)
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
if (shape)
|
||||
*shape = globalShape;
|
||||
|
@ -3013,7 +3013,6 @@ js_CheckGlobalObjectShape(JSContext* cx, JSTraceMonitor* tm, JSObject* globalObj
|
|||
|
||||
/* No recorder, search for a tracked global-state (or allocate one). */
|
||||
for (size_t i = 0; i < MONITOR_N_GLOBAL_STATES; ++i) {
|
||||
|
||||
GlobalState &state = tm->globalStates[i];
|
||||
|
||||
if (state.globalShape == (uint32) -1) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче