зеркало из https://github.com/mozilla/gecko-dev.git
[Bug 423874] Allocating functions together with JSObject. r=brendan a1.9=blocking1.9
This commit is contained in:
Родитель
d545086c33
Коммит
5e262850d9
|
@ -937,7 +937,6 @@ CountHeap(JSContext *cx, uintN argc, jsval *vp)
|
|||
{ "object", JSTRACE_OBJECT },
|
||||
{ "double", JSTRACE_DOUBLE },
|
||||
{ "string", JSTRACE_STRING },
|
||||
{ "function", JSTRACE_FUNCTION },
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
{ "namespace", JSTRACE_NAMESPACE },
|
||||
{ "qname", JSTRACE_QNAME },
|
||||
|
|
|
@ -369,7 +369,7 @@ JS_PushArgumentsVA(JSContext *cx, void **markp, const char *format, va_list ap)
|
|||
break;
|
||||
case 'f':
|
||||
fun = va_arg(ap, JSFunction *);
|
||||
*sp = fun ? OBJECT_TO_JSVAL(fun->object) : JSVAL_NULL;
|
||||
*sp = fun ? OBJECT_TO_JSVAL(FUN_OBJECT(fun)) : JSVAL_NULL;
|
||||
break;
|
||||
case 'v':
|
||||
*sp = va_arg(ap, jsval);
|
||||
|
@ -2014,10 +2014,6 @@ JS_PrintTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc,
|
|||
name = "double";
|
||||
break;
|
||||
|
||||
case JSTRACE_FUNCTION:
|
||||
name = "function";
|
||||
break;
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
case JSTRACE_NAMESPACE:
|
||||
name = "namespace";
|
||||
|
@ -2053,7 +2049,20 @@ JS_PrintTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc,
|
|||
{
|
||||
JSObject *obj = (JSObject *)thing;
|
||||
JSClass *clasp = STOBJ_GET_CLASS(obj);
|
||||
if (clasp->flags & JSCLASS_HAS_PRIVATE) {
|
||||
if (clasp == &js_FunctionClass) {
|
||||
JSFunction *fun = (JSFunction *)
|
||||
JS_GetPrivate(trc->context, obj);
|
||||
|
||||
if (!fun) {
|
||||
JS_snprintf(buf, bufsize, "<newborn>");
|
||||
} else if (FUN_OBJECT(fun) != obj) {
|
||||
JS_snprintf(buf, bufsize, "%p", fun);
|
||||
} else {
|
||||
if (fun->atom && ATOM_IS_STRING(fun->atom))
|
||||
js_PutEscapedString(buf, bufsize,
|
||||
ATOM_TO_STRING(fun->atom), 0);
|
||||
}
|
||||
} else if (clasp->flags & JSCLASS_HAS_PRIVATE) {
|
||||
jsval privateValue = STOBJ_GET_SLOT(obj, JSSLOT_PRIVATE);
|
||||
void *privateThing = JSVAL_IS_VOID(privateValue)
|
||||
? NULL
|
||||
|
@ -2074,15 +2083,6 @@ JS_PrintTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc,
|
|||
JS_snprintf(buf, bufsize, "%g", *(jsdouble *)thing);
|
||||
break;
|
||||
|
||||
case JSTRACE_FUNCTION:
|
||||
{
|
||||
JSFunction *fun = (JSFunction *)thing;
|
||||
|
||||
if (fun->atom && ATOM_IS_STRING(fun->atom))
|
||||
js_PutEscapedString(buf, bufsize, ATOM_TO_STRING(fun->atom), 0);
|
||||
break;
|
||||
}
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
case JSTRACE_NAMESPACE:
|
||||
{
|
||||
|
@ -2698,7 +2698,7 @@ JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
|
|||
}
|
||||
|
||||
/* Create a prototype object for this class. */
|
||||
proto = js_NewObject(cx, clasp, parent_proto, obj);
|
||||
proto = js_NewObject(cx, clasp, parent_proto, obj, 0);
|
||||
if (!proto)
|
||||
return NULL;
|
||||
|
||||
|
@ -2749,7 +2749,7 @@ JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
|
|||
* different object, as is done for operator new -- and as at least
|
||||
* XML support requires.
|
||||
*/
|
||||
ctor = fun->object;
|
||||
ctor = FUN_OBJECT(fun);
|
||||
if (clasp->flags & JSCLASS_CONSTRUCT_PROTOTYPE) {
|
||||
cval = OBJECT_TO_JSVAL(ctor);
|
||||
if (!js_InternalConstruct(cx, proto, cval, 0, NULL, &rval))
|
||||
|
@ -2966,7 +2966,7 @@ JS_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent)
|
|||
CHECK_REQUEST(cx);
|
||||
if (!clasp)
|
||||
clasp = &js_ObjectClass; /* default class is Object */
|
||||
return js_NewObject(cx, clasp, proto, parent);
|
||||
return js_NewObject(cx, clasp, proto, parent, 0);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
|
@ -2976,7 +2976,7 @@ JS_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto,
|
|||
CHECK_REQUEST(cx);
|
||||
if (!clasp)
|
||||
clasp = &js_ObjectClass; /* default class is Object */
|
||||
return js_NewObjectWithGivenProto(cx, clasp, proto, parent);
|
||||
return js_NewObjectWithGivenProto(cx, clasp, proto, parent, 0);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
|
@ -3120,7 +3120,7 @@ JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, JSClass *clasp,
|
|||
CHECK_REQUEST(cx);
|
||||
if (!clasp)
|
||||
clasp = &js_ObjectClass; /* default class is Object */
|
||||
nobj = js_NewObject(cx, clasp, proto, obj);
|
||||
nobj = js_NewObject(cx, clasp, proto, obj, 0);
|
||||
if (!nobj)
|
||||
return NULL;
|
||||
if (!DefineProperty(cx, obj, name, OBJECT_TO_JSVAL(nobj), NULL, NULL, attrs,
|
||||
|
@ -3999,7 +3999,7 @@ JS_NewPropertyIterator(JSContext *cx, JSObject *obj)
|
|||
JSIdArray *ida;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
iterobj = js_NewObject(cx, &prop_iter_class, NULL, obj);
|
||||
iterobj = js_NewObject(cx, &prop_iter_class, NULL, obj, 0);
|
||||
if (!iterobj)
|
||||
return NULL;
|
||||
|
||||
|
@ -4218,13 +4218,13 @@ JS_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent)
|
|||
/* Indicate we cannot clone this object. */
|
||||
return funobj;
|
||||
}
|
||||
return js_CloneFunctionObject(cx, funobj, parent);
|
||||
return js_CloneFunctionObject(cx, GET_FUNCTION_PRIVATE(cx, funobj), parent);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_GetFunctionObject(JSFunction *fun)
|
||||
{
|
||||
return fun->object;
|
||||
return FUN_OBJECT(fun);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(const char *)
|
||||
|
@ -4419,7 +4419,7 @@ JS_DefineFunctions(JSContext *cx, JSObject *obj, JSFunctionSpec *fs)
|
|||
* As jsapi.h notes, fs must point to storage that lives as long
|
||||
* as fun->object lives.
|
||||
*/
|
||||
if (!JS_SetReservedSlot(cx, fun->object, 0, PRIVATE_TO_JSVAL(fs)))
|
||||
if (!JS_SetReservedSlot(cx, FUN_OBJECT(fun), 0, PRIVATE_TO_JSVAL(fs)))
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -4635,10 +4635,10 @@ JS_NewScriptObject(JSContext *cx, JSScript *script)
|
|||
JSObject *obj;
|
||||
|
||||
if (!script)
|
||||
return js_NewObject(cx, &js_ScriptClass, NULL, NULL);
|
||||
return js_NewObject(cx, &js_ScriptClass, NULL, NULL, 0);
|
||||
|
||||
JS_PUSH_TEMP_ROOT_SCRIPT(cx, script, &tvr);
|
||||
obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL);
|
||||
obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL, 0);
|
||||
if (obj) {
|
||||
JS_SetPrivate(cx, obj, script);
|
||||
script->object = obj;
|
||||
|
@ -4743,7 +4743,7 @@ JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj,
|
|||
goto out2;
|
||||
|
||||
/* From this point the control must flow through the label out. */
|
||||
JS_PUSH_TEMP_ROOT_FUNCTION(cx, fun, &tvr);
|
||||
JS_PUSH_TEMP_ROOT_OBJECT(cx, FUN_OBJECT(fun), &tvr);
|
||||
for (i = 0; i < nargs; i++) {
|
||||
argAtom = js_Atomize(cx, argnames[i], strlen(argnames[i]), 0);
|
||||
if (!argAtom) {
|
||||
|
@ -4765,7 +4765,7 @@ JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj,
|
|||
if (obj &&
|
||||
funAtom &&
|
||||
!OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(funAtom),
|
||||
OBJECT_TO_JSVAL(fun->object),
|
||||
OBJECT_TO_JSVAL(FUN_OBJECT(fun)),
|
||||
NULL, NULL, JSPROP_ENUMERATE, NULL)) {
|
||||
fun = NULL;
|
||||
}
|
||||
|
@ -4782,7 +4782,7 @@ JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj,
|
|||
#endif
|
||||
|
||||
out:
|
||||
cx->weakRoots.newborn[JSTRACE_FUNCTION] = fun;
|
||||
cx->weakRoots.newborn[JSTRACE_OBJECT] = FUN_OBJECT(fun);
|
||||
JS_POP_TEMP_ROOT(cx, &tvr);
|
||||
|
||||
out2:
|
||||
|
@ -4974,7 +4974,7 @@ JS_CallFunction(JSContext *cx, JSObject *obj, JSFunction *fun, uintN argc,
|
|||
JSBool ok;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
ok = js_InternalCall(cx, obj, OBJECT_TO_JSVAL(fun->object), argc, argv,
|
||||
ok = js_InternalCall(cx, obj, OBJECT_TO_JSVAL(FUN_OBJECT(fun)), argc, argv,
|
||||
rval);
|
||||
LAST_FRAME_CHECKS(cx, ok);
|
||||
return ok;
|
||||
|
|
|
@ -2879,7 +2879,7 @@ Array(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
|
||||
/* If called without new, replace obj with a new Array object. */
|
||||
if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
|
||||
obj = js_NewObject(cx, &js_ArrayClass, NULL, NULL);
|
||||
obj = js_NewObject(cx, &js_ArrayClass, NULL, NULL, 0);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
*rval = OBJECT_TO_JSVAL(obj);
|
||||
|
@ -2929,7 +2929,7 @@ js_NewArrayObject(JSContext *cx, jsuint length, jsval *vector)
|
|||
JSTempValueRooter tvr;
|
||||
JSObject *obj;
|
||||
|
||||
obj = js_NewObject(cx, &js_ArrayClass, NULL, NULL);
|
||||
obj = js_NewObject(cx, &js_ArrayClass, NULL, NULL, 0);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
|
@ -2946,7 +2946,7 @@ js_NewArrayObject(JSContext *cx, jsuint length, jsval *vector)
|
|||
JSObject *
|
||||
js_NewSlowArrayObject(JSContext *cx)
|
||||
{
|
||||
JSObject *obj = js_NewObject(cx, &js_SlowArrayClass, NULL, NULL);
|
||||
JSObject *obj = js_NewObject(cx, &js_SlowArrayClass, NULL, NULL, 0);
|
||||
if (obj)
|
||||
obj->fslots[JSSLOT_ARRAY_LENGTH] = 0;
|
||||
return obj;
|
||||
|
|
|
@ -619,9 +619,6 @@ JS_STATIC_ASSERT(sizeof(JSTempValueUnion) == sizeof(void *));
|
|||
#define JS_PUSH_TEMP_ROOT_STRING(cx,str,tvr) \
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, str, tvr, JSTVU_SINGLE, string)
|
||||
|
||||
#define JS_PUSH_TEMP_ROOT_FUNCTION(cx,fun,tvr) \
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, fun, tvr, JSTVU_SINGLE, function)
|
||||
|
||||
#define JS_PUSH_TEMP_ROOT_QNAME(cx,qn,tvr) \
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, qn, tvr, JSTVU_SINGLE, qname)
|
||||
|
||||
|
|
|
@ -2150,7 +2150,7 @@ js_NewDateObjectMsec(JSContext *cx, jsdouble msec_time)
|
|||
JSObject *obj;
|
||||
jsdouble *date;
|
||||
|
||||
obj = js_NewObject(cx, &js_DateClass, NULL, NULL);
|
||||
obj = js_NewObject(cx, &js_DateClass, NULL, NULL, 0);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -697,7 +697,7 @@ js_WrapWatchedSetter(JSContext *cx, jsid id, uintN attrs, JSPropertyOp setter)
|
|||
atom);
|
||||
if (!wrapper)
|
||||
return NULL;
|
||||
return (JSPropertyOp) wrapper->object;
|
||||
return (JSPropertyOp) FUN_OBJECT(wrapper);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
|
@ -995,7 +995,7 @@ JS_StackFramePrincipals(JSContext *cx, JSStackFrame *fp)
|
|||
JSRuntime *rt = cx->runtime;
|
||||
|
||||
if (rt->findObjectPrincipals) {
|
||||
if (fp->fun->object != fp->callee)
|
||||
if (FUN_OBJECT(fp->fun) != fp->callee)
|
||||
return rt->findObjectPrincipals(cx, fp->callee);
|
||||
/* FALL THROUGH */
|
||||
}
|
||||
|
@ -1554,8 +1554,7 @@ JS_GetFunctionTotalSize(JSContext *cx, JSFunction *fun)
|
|||
size_t nbytes;
|
||||
|
||||
nbytes = sizeof *fun;
|
||||
if (fun->object)
|
||||
nbytes += JS_GetObjectTotalSize(cx, fun->object);
|
||||
nbytes += JS_GetObjectTotalSize(cx, FUN_OBJECT(fun));
|
||||
if (FUN_INTERPRETED(fun))
|
||||
nbytes += JS_GetScriptTotalSize(cx, fun->u.i.script);
|
||||
if (fun->atom)
|
||||
|
@ -1668,7 +1667,7 @@ JS_NewSystemObject(JSContext *cx, JSClass *clasp, JSObject *proto,
|
|||
{
|
||||
JSObject *obj;
|
||||
|
||||
obj = js_NewObject(cx, clasp, proto, parent);
|
||||
obj = js_NewObject(cx, clasp, proto, parent, 0);
|
||||
if (obj && system)
|
||||
STOBJ_SET_SYSTEM(obj);
|
||||
return obj;
|
||||
|
|
|
@ -2053,7 +2053,7 @@ CheckSideEffects(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
|
|||
* name in that scope object. See comments at case JSOP_NAMEDFUNOBJ:
|
||||
* in jsinterp.c.
|
||||
*/
|
||||
fun = GET_FUNCTION_PRIVATE(cx, pn->pn_funpob->object);
|
||||
fun = (JSFunction *) pn->pn_funpob->object;
|
||||
if (fun->atom)
|
||||
*answer = JS_TRUE;
|
||||
break;
|
||||
|
@ -3937,7 +3937,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
}
|
||||
#endif
|
||||
|
||||
fun = GET_FUNCTION_PRIVATE(cx, pn->pn_funpob->object);
|
||||
fun = (JSFunction *) pn->pn_funpob->object;
|
||||
if (fun->u.i.script) {
|
||||
/*
|
||||
* This second pass is needed to emit JSOP_NOP with a source note
|
||||
|
|
|
@ -750,7 +750,7 @@ Exception(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
.classPrototypeAtom),
|
||||
rval))
|
||||
return JS_FALSE;
|
||||
obj = js_NewObject(cx, &js_ErrorClass, JSVAL_TO_OBJECT(*rval), NULL);
|
||||
obj = js_NewObject(cx, &js_ErrorClass, JSVAL_TO_OBJECT(*rval), NULL, 0);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
*rval = OBJECT_TO_JSVAL(obj);
|
||||
|
@ -1044,7 +1044,6 @@ js_InitExceptionClasses(JSContext *cx, JSObject *obj)
|
|||
for (i = 0; exceptions[i].name != 0; i++) {
|
||||
JSAtom *atom;
|
||||
JSFunction *fun;
|
||||
JSObject *funobj;
|
||||
JSString *nameString;
|
||||
int protoIndex = exceptions[i].protoIndex;
|
||||
|
||||
|
@ -1053,7 +1052,7 @@ js_InitExceptionClasses(JSContext *cx, JSObject *obj)
|
|||
(protoIndex != JSEXN_NONE)
|
||||
? protos[protoIndex]
|
||||
: obj_proto,
|
||||
obj);
|
||||
obj, 0);
|
||||
if (!protos[i])
|
||||
break;
|
||||
|
||||
|
@ -1069,11 +1068,8 @@ js_InitExceptionClasses(JSContext *cx, JSObject *obj)
|
|||
/* Make this constructor make objects of class Exception. */
|
||||
fun->u.n.clasp = &js_ErrorClass;
|
||||
|
||||
/* Extract the constructor object. */
|
||||
funobj = fun->object;
|
||||
|
||||
/* Make the prototype and constructor links. */
|
||||
if (!js_SetClassPrototype(cx, funobj, protos[i],
|
||||
if (!js_SetClassPrototype(cx, FUN_OBJECT(fun), protos[i],
|
||||
JSPROP_READONLY | JSPROP_PERMANENT)) {
|
||||
break;
|
||||
}
|
||||
|
@ -1092,7 +1088,7 @@ js_InitExceptionClasses(JSContext *cx, JSObject *obj)
|
|||
}
|
||||
|
||||
/* Finally, stash the constructor for later uses. */
|
||||
if (!js_SetClassObject(cx, obj, exceptions[i].key, funobj))
|
||||
if (!js_SetClassObject(cx, obj, exceptions[i].key, FUN_OBJECT(fun)))
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1223,7 +1219,7 @@ js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp)
|
|||
goto out;
|
||||
tv[0] = OBJECT_TO_JSVAL(errProto);
|
||||
|
||||
errObject = js_NewObject(cx, &js_ErrorClass, errProto, NULL);
|
||||
errObject = js_NewObject(cx, &js_ErrorClass, errProto, NULL, 0);
|
||||
if (!errObject) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
|
|
187
js/src/jsfun.c
187
js/src/jsfun.c
|
@ -254,7 +254,7 @@ js_GetArgsObject(JSContext *cx, JSStackFrame *fp)
|
|||
return argsobj;
|
||||
|
||||
/* Link the new object to fp so it can get actual argument values. */
|
||||
argsobj = js_NewObject(cx, &js_ArgumentsClass, NULL, NULL);
|
||||
argsobj = js_NewObject(cx, &js_ArgumentsClass, NULL, NULL, 0);
|
||||
if (!argsobj || !JS_SetPrivate(cx, argsobj, fp)) {
|
||||
cx->weakRoots.newborn[GCX_OBJECT] = NULL;
|
||||
return NULL;
|
||||
|
@ -602,7 +602,7 @@ js_GetCallObject(JSContext *cx, JSStackFrame *fp, JSObject *parent)
|
|||
}
|
||||
|
||||
/* Create the call object and link it to its stack frame. */
|
||||
callobj = js_NewObject(cx, &js_CallClass, NULL, parent);
|
||||
callobj = js_NewObject(cx, &js_CallClass, NULL, parent, 0);
|
||||
if (!callobj || !JS_SetPrivate(cx, callobj, fp)) {
|
||||
cx->weakRoots.newborn[GCX_OBJECT] = NULL;
|
||||
return NULL;
|
||||
|
@ -1076,7 +1076,6 @@ fun_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
|
|||
return JS_TRUE;
|
||||
|
||||
fun = GET_FUNCTION_PRIVATE(cx, obj);
|
||||
JS_ASSERT(fun->object);
|
||||
|
||||
/*
|
||||
* No need to reflect fun.prototype in 'fun.prototype = ... '.
|
||||
|
@ -1112,8 +1111,8 @@ fun_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
|
|||
* Make the prototype object to have the same parent as the function
|
||||
* object itself.
|
||||
*/
|
||||
proto = js_NewObject(cx, &js_ObjectClass, NULL,
|
||||
OBJ_GET_PARENT(cx, obj));
|
||||
proto = js_NewObject(cx, &js_ObjectClass, NULL, OBJ_GET_PARENT(cx, obj),
|
||||
0);
|
||||
if (!proto)
|
||||
return JS_FALSE;
|
||||
|
||||
|
@ -1198,15 +1197,15 @@ fun_xdrObject(JSXDRState *xdr, JSObject **objp)
|
|||
fun = js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED, NULL, NULL);
|
||||
if (!fun)
|
||||
return JS_FALSE;
|
||||
STOBJ_SET_PARENT(fun->object, NULL);
|
||||
STOBJ_SET_PROTO(fun->object, NULL);
|
||||
STOBJ_SET_PARENT(FUN_OBJECT(fun), NULL);
|
||||
STOBJ_SET_PROTO(FUN_OBJECT(fun), NULL);
|
||||
#ifdef __GNUC__
|
||||
nvars = nargs = 0; /* quell GCC uninitialized warning */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* From here on, control flow must flow through label out. */
|
||||
JS_PUSH_TEMP_ROOT_OBJECT(cx, fun->object, &tvr);
|
||||
JS_PUSH_TEMP_ROOT_OBJECT(cx, FUN_OBJECT(fun), &tvr);
|
||||
ok = JS_TRUE;
|
||||
|
||||
if (!JS_XDRUint32(xdr, &nullAtom))
|
||||
|
@ -1226,7 +1225,8 @@ fun_xdrObject(JSXDRState *xdr, JSObject **objp)
|
|||
}
|
||||
|
||||
/* do arguments and local vars */
|
||||
if (fun->object && (n = nargs + nvars) != 0) {
|
||||
n = nargs + nvars;
|
||||
if (n != 0) {
|
||||
void *mark;
|
||||
uintN i;
|
||||
uintN bitmapLength;
|
||||
|
@ -1326,7 +1326,7 @@ fun_xdrObject(JSXDRState *xdr, JSObject **objp)
|
|||
goto bad;
|
||||
|
||||
if (xdr->mode == JSXDR_DECODE) {
|
||||
*objp = fun->object;
|
||||
*objp = FUN_OBJECT(fun);
|
||||
#ifdef CHECK_SCRIPT_OWNER
|
||||
fun->u.i.script->owner = NULL;
|
||||
#endif
|
||||
|
@ -1378,6 +1378,12 @@ fun_hasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
|
|||
return js_IsDelegate(cx, JSVAL_TO_OBJECT(pval), v, bp);
|
||||
}
|
||||
|
||||
static void
|
||||
TraceLocalNames(JSTracer *trc, JSFunction *fun);
|
||||
|
||||
static void
|
||||
DestroyLocalNames(JSContext *cx, JSFunction *fun);
|
||||
|
||||
static void
|
||||
fun_trace(JSTracer *trc, JSObject *obj)
|
||||
{
|
||||
|
@ -1385,8 +1391,42 @@ fun_trace(JSTracer *trc, JSObject *obj)
|
|||
|
||||
/* A newborn function object may have a not yet initialized private slot. */
|
||||
fun = (JSFunction *) JS_GetPrivate(trc->context, obj);
|
||||
if (fun)
|
||||
JS_CALL_TRACER(trc, fun, JSTRACE_FUNCTION, "private");
|
||||
if (!fun)
|
||||
return;
|
||||
|
||||
if (FUN_OBJECT(fun) != obj) {
|
||||
/* obj is cloned function object, trace the original. */
|
||||
JS_CALL_TRACER(trc, FUN_OBJECT(fun), JSTRACE_OBJECT, "private");
|
||||
return;
|
||||
}
|
||||
if (fun->atom)
|
||||
JS_CALL_STRING_TRACER(trc, ATOM_TO_STRING(fun->atom), "atom");
|
||||
if (FUN_INTERPRETED(fun)) {
|
||||
if (fun->u.i.script)
|
||||
js_TraceScript(trc, fun->u.i.script);
|
||||
TraceLocalNames(trc, fun);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fun_finalize(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JSFunction *fun;
|
||||
|
||||
/* Ignore newborn and cloned function objects. */
|
||||
fun = (JSFunction *) JS_GetPrivate(cx, obj);
|
||||
if (!fun || FUN_OBJECT(fun) != obj)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Null-check of u.i.script is required since the parser sets interpreted
|
||||
* very early.
|
||||
*/
|
||||
if (FUN_INTERPRETED(fun)) {
|
||||
if (fun->u.i.script)
|
||||
js_DestroyScript(cx, fun->u.i.script);
|
||||
DestroyLocalNames(cx, fun);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32
|
||||
|
@ -1418,7 +1458,7 @@ JS_FRIEND_DATA(JSClass) js_FunctionClass = {
|
|||
JS_PropertyStub, JS_PropertyStub,
|
||||
fun_getProperty, JS_PropertyStub,
|
||||
fun_enumerate, (JSResolveOp)fun_resolve,
|
||||
fun_convert, JS_FinalizeStub,
|
||||
fun_convert, fun_finalize,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
fun_xdrObject, fun_hasInstance,
|
||||
|
@ -1721,20 +1761,19 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
|
||||
fp = cx->fp;
|
||||
if (!(fp->flags & JSFRAME_CONSTRUCTING)) {
|
||||
obj = js_NewObject(cx, &js_FunctionClass, NULL, NULL);
|
||||
obj = js_NewObject(cx, &js_FunctionClass, NULL, NULL, 0);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
*rval = OBJECT_TO_JSVAL(obj);
|
||||
} else {
|
||||
/*
|
||||
* The constructor is called before the private slot is initialized so
|
||||
* we must use JS_GetPrivate, not GET_FUNCTION_PRIVATE here.
|
||||
*/
|
||||
if (JS_GetPrivate(cx, obj))
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* The constructor is called before the private slot is initialized so we
|
||||
* must use JS_GetPrivate, not GET_FUNCTION_PRIVATE here.
|
||||
*/
|
||||
fun = (JSFunction *) JS_GetPrivate(cx, obj);
|
||||
if (fun)
|
||||
return JS_TRUE;
|
||||
|
||||
/*
|
||||
* NB: (new Function) is not lexically closed by its caller, it's just an
|
||||
* anonymous function in the top-level scope that its constructor inhabits.
|
||||
|
@ -1988,30 +2027,19 @@ js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN nargs,
|
|||
uintN flags, JSObject *parent, JSAtom *atom)
|
||||
{
|
||||
JSFunction *fun;
|
||||
JSTempValueRooter tvr;
|
||||
|
||||
/* If funobj is null, allocate an object for it. */
|
||||
if (funobj) {
|
||||
JS_ASSERT(HAS_FUNCTION_CLASS(funobj));
|
||||
OBJ_SET_PARENT(cx, funobj, parent);
|
||||
} else {
|
||||
funobj = js_NewObject(cx, &js_FunctionClass, NULL, parent);
|
||||
funobj = js_NewObject(cx, &js_FunctionClass, NULL, parent, 0);
|
||||
if (!funobj)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Protect fun from any potential GC callback. */
|
||||
JS_PUSH_SINGLE_TEMP_ROOT(cx, OBJECT_TO_JSVAL(funobj), &tvr);
|
||||
|
||||
/*
|
||||
* Allocate fun after allocating funobj so allocations in js_NewObject
|
||||
* and hooks called from it do not wipe out fun from newborn[GCX_FUNCTION].
|
||||
*/
|
||||
fun = (JSFunction *) js_NewGCThing(cx, GCX_FUNCTION, sizeof(JSFunction));
|
||||
if (!fun)
|
||||
goto out;
|
||||
JS_ASSERT(funobj->fslots[JSSLOT_PRIVATE] == JSVAL_VOID);
|
||||
fun = (JSFunction *) funobj;
|
||||
|
||||
/* Initialize all function members. */
|
||||
fun->object = NULL;
|
||||
fun->nargs = nargs;
|
||||
fun->flags = flags & (JSFUN_FLAGS_MASK | JSFUN_INTERPRETED);
|
||||
if (flags & JSFUN_INTERPRETED) {
|
||||
|
@ -2031,75 +2059,26 @@ js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN nargs,
|
|||
}
|
||||
fun->atom = atom;
|
||||
|
||||
/* Link fun to funobj and vice versa. */
|
||||
if (!js_LinkFunctionObject(cx, fun, funobj)) {
|
||||
cx->weakRoots.newborn[GCX_OBJECT] = NULL;
|
||||
fun = NULL;
|
||||
}
|
||||
|
||||
out:
|
||||
JS_POP_TEMP_ROOT(cx, &tvr);
|
||||
/* Set private to self to indicate non-cloned fully initialized function. */
|
||||
FUN_OBJECT(fun)->fslots[JSSLOT_PRIVATE] = PRIVATE_TO_JSVAL(fun);
|
||||
return fun;
|
||||
}
|
||||
|
||||
static void
|
||||
TraceLocalNames(JSTracer *trc, JSFunction *fun);
|
||||
|
||||
void
|
||||
js_TraceFunction(JSTracer *trc, JSFunction *fun)
|
||||
{
|
||||
if (fun->object)
|
||||
JS_CALL_OBJECT_TRACER(trc, fun->object, "object");
|
||||
if (fun->atom)
|
||||
JS_CALL_STRING_TRACER(trc, ATOM_TO_STRING(fun->atom), "atom");
|
||||
if (FUN_INTERPRETED(fun)) {
|
||||
if (fun->u.i.script)
|
||||
js_TraceScript(trc, fun->u.i.script);
|
||||
TraceLocalNames(trc, fun);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
DestroyLocalNames(JSContext *cx, JSFunction *fun);
|
||||
|
||||
void
|
||||
js_FinalizeFunction(JSContext *cx, JSFunction *fun)
|
||||
{
|
||||
/*
|
||||
* Null-check of i.script is required since the parser sets interpreted
|
||||
* very early.
|
||||
*/
|
||||
if (FUN_INTERPRETED(fun)) {
|
||||
if (fun->u.i.script)
|
||||
js_DestroyScript(cx, fun->u.i.script);
|
||||
DestroyLocalNames(cx, fun);
|
||||
}
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent)
|
||||
js_CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent)
|
||||
{
|
||||
JSObject *newfunobj;
|
||||
JSFunction *fun;
|
||||
JSObject *clone;
|
||||
|
||||
JS_ASSERT(OBJ_GET_CLASS(cx, funobj) == &js_FunctionClass);
|
||||
newfunobj = js_NewObject(cx, &js_FunctionClass, NULL, parent);
|
||||
if (!newfunobj)
|
||||
/*
|
||||
* The cloned function object does not need the extra fields beyond
|
||||
* JSObject as it points to fun via the private slot.
|
||||
*/
|
||||
clone = js_NewObject(cx, &js_FunctionClass, NULL, parent,
|
||||
sizeof(JSObject));
|
||||
if (!clone)
|
||||
return NULL;
|
||||
fun = GET_FUNCTION_PRIVATE(cx, funobj);
|
||||
if (!js_LinkFunctionObject(cx, fun, newfunobj)) {
|
||||
cx->weakRoots.newborn[GCX_OBJECT] = NULL;
|
||||
return NULL;
|
||||
}
|
||||
return newfunobj;
|
||||
}
|
||||
|
||||
JSBool
|
||||
js_LinkFunctionObject(JSContext *cx, JSFunction *fun, JSObject *funobj)
|
||||
{
|
||||
if (!fun->object)
|
||||
fun->object = funobj;
|
||||
return JS_SetPrivate(cx, funobj, fun);
|
||||
clone->fslots[JSSLOT_PRIVATE] = PRIVATE_TO_JSVAL(fun);
|
||||
return clone;
|
||||
}
|
||||
|
||||
JSFunction *
|
||||
|
@ -2114,7 +2093,7 @@ js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, JSNative native,
|
|||
return NULL;
|
||||
gsop = (attrs & JSFUN_STUB_GSOPS) ? JS_PropertyStub : NULL;
|
||||
if (!OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom),
|
||||
OBJECT_TO_JSVAL(fun->object),
|
||||
OBJECT_TO_JSVAL(FUN_OBJECT(fun)),
|
||||
gsop, gsop,
|
||||
attrs & ~JSFUN_FLAGS_MASK, NULL)) {
|
||||
return NULL;
|
||||
|
@ -2153,7 +2132,6 @@ JSObject *
|
|||
js_ValueToFunctionObject(JSContext *cx, jsval *vp, uintN flags)
|
||||
{
|
||||
JSFunction *fun;
|
||||
JSObject *funobj;
|
||||
JSStackFrame *caller;
|
||||
JSPrincipals *principals;
|
||||
|
||||
|
@ -2163,8 +2141,7 @@ js_ValueToFunctionObject(JSContext *cx, jsval *vp, uintN flags)
|
|||
fun = js_ValueToFunction(cx, vp, flags);
|
||||
if (!fun)
|
||||
return NULL;
|
||||
funobj = fun->object;
|
||||
*vp = OBJECT_TO_JSVAL(funobj);
|
||||
*vp = OBJECT_TO_JSVAL(FUN_OBJECT(fun));
|
||||
|
||||
caller = JS_GetScriptedCaller(cx, cx->fp);
|
||||
if (caller) {
|
||||
|
@ -2174,13 +2151,13 @@ js_ValueToFunctionObject(JSContext *cx, jsval *vp, uintN flags)
|
|||
principals = NULL;
|
||||
}
|
||||
|
||||
if (!js_CheckPrincipalsAccess(cx, funobj, principals,
|
||||
if (!js_CheckPrincipalsAccess(cx, FUN_OBJECT(fun), principals,
|
||||
fun->atom
|
||||
? fun->atom
|
||||
: cx->runtime->atomState.anonymousAtom)) {
|
||||
return NULL;
|
||||
}
|
||||
return funobj;
|
||||
return FUN_OBJECT(fun);
|
||||
}
|
||||
|
||||
JSObject *
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
*/
|
||||
#include "jsprvtd.h"
|
||||
#include "jspubtd.h"
|
||||
#include "jsobj.h"
|
||||
|
||||
JS_BEGIN_EXTERN_C
|
||||
|
||||
|
@ -63,7 +64,7 @@ typedef union JSLocalNames {
|
|||
} JSLocalNames;
|
||||
|
||||
struct JSFunction {
|
||||
JSObject *object; /* back-pointer to GC'ed object header */
|
||||
JSObject object; /* GC'ed object header */
|
||||
uint16 nargs; /* maximum number of specified arguments,
|
||||
reflected as f.length/f.arity */
|
||||
uint16 flags; /* bound method and other flags, see jsapi.h */
|
||||
|
@ -90,6 +91,7 @@ struct JSFunction {
|
|||
|
||||
#define JSFUN_SCRIPT_OR_FAST_NATIVE (JSFUN_INTERPRETED | JSFUN_FAST_NATIVE)
|
||||
|
||||
#define FUN_OBJECT(fun) (&(fun)->object)
|
||||
#define FUN_INTERPRETED(fun) ((fun)->flags & JSFUN_INTERPRETED)
|
||||
#define FUN_SLOW_NATIVE(fun) (!((fun)->flags & JSFUN_SCRIPT_OR_FAST_NATIVE))
|
||||
#define FUN_SCRIPT(fun) (FUN_INTERPRETED(fun) ? (fun)->u.i.script : NULL)
|
||||
|
@ -107,19 +109,20 @@ extern JS_FRIEND_DATA(JSClass) js_CallClass;
|
|||
/* JS_FRIEND_DATA so that VALUE_IS_FUNCTION is callable from the shell. */
|
||||
extern JS_FRIEND_DATA(JSClass) js_FunctionClass;
|
||||
|
||||
#define HAS_FUNCTION_CLASS(obj) (STOBJ_GET_CLASS(obj) == &js_FunctionClass)
|
||||
|
||||
/*
|
||||
* NB: jsapi.h and jsobj.h must be included before any call to this macro.
|
||||
*/
|
||||
#define VALUE_IS_FUNCTION(cx, v) \
|
||||
(!JSVAL_IS_PRIMITIVE(v) && \
|
||||
OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_FunctionClass)
|
||||
(!JSVAL_IS_PRIMITIVE(v) && HAS_FUNCTION_CLASS(JSVAL_TO_OBJECT(v)))
|
||||
|
||||
/*
|
||||
* Macro to access the private slot of the function object after the slot is
|
||||
* initialized.
|
||||
*/
|
||||
#define GET_FUNCTION_PRIVATE(cx, funobj) \
|
||||
(JS_ASSERT(OBJ_GET_CLASS(cx, funobj) == &js_FunctionClass), \
|
||||
(JS_ASSERT(HAS_FUNCTION_CLASS(funobj)), \
|
||||
(JSFunction *) OBJ_GET_PRIVATE(cx, funobj))
|
||||
|
||||
extern JSObject *
|
||||
|
@ -142,7 +145,7 @@ extern void
|
|||
js_FinalizeFunction(JSContext *cx, JSFunction *fun);
|
||||
|
||||
extern JSObject *
|
||||
js_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent);
|
||||
js_CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent);
|
||||
|
||||
extern JSBool
|
||||
js_LinkFunctionObject(JSContext *cx, JSFunction *fun, JSObject *object);
|
||||
|
|
|
@ -2250,10 +2250,6 @@ JS_TraceChildren(JSTracer *trc, void *thing, uint32 kind)
|
|||
JS_CALL_STRING_TRACER(trc, JSSTRDEP_BASE(str), "base");
|
||||
break;
|
||||
|
||||
case JSTRACE_FUNCTION:
|
||||
js_TraceFunction(trc, (JSFunction *)thing);
|
||||
break;
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
case JSTRACE_NAMESPACE:
|
||||
js_TraceXMLNamespace(trc, (JSXMLNamespace *)thing);
|
||||
|
@ -2728,7 +2724,6 @@ TraceWeakRoots(JSTracer *trc, JSWeakRoots *wr)
|
|||
"newborn object",
|
||||
"newborn double",
|
||||
"newborn string",
|
||||
"newborn function",
|
||||
"newborn namespace",
|
||||
"newborn qname",
|
||||
"newborn xml"
|
||||
|
@ -3327,9 +3322,6 @@ js_GC(JSContext *cx, JSGCInvocationKind gckind)
|
|||
case GCX_DOUBLE:
|
||||
/* Do nothing. */
|
||||
break;
|
||||
case GCX_FUNCTION:
|
||||
js_FinalizeFunction(cx, (JSFunction *) thing);
|
||||
break;
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
case GCX_NAMESPACE:
|
||||
js_FinalizeXMLNamespace(cx,
|
||||
|
|
|
@ -52,15 +52,14 @@ JS_BEGIN_EXTERN_C
|
|||
|
||||
JS_STATIC_ASSERT(JSTRACE_STRING == 2);
|
||||
|
||||
#define JSTRACE_FUNCTION 3
|
||||
#define JSTRACE_NAMESPACE 4
|
||||
#define JSTRACE_QNAME 5
|
||||
#define JSTRACE_XML 6
|
||||
#define JSTRACE_NAMESPACE 3
|
||||
#define JSTRACE_QNAME 4
|
||||
#define JSTRACE_XML 5
|
||||
|
||||
/*
|
||||
* One past the maximum trace kind.
|
||||
*/
|
||||
#define JSTRACE_LIMIT 7
|
||||
#define JSTRACE_LIMIT 6
|
||||
|
||||
/*
|
||||
* We use the trace kinds as the types for all GC things except external
|
||||
|
@ -69,7 +68,6 @@ JS_STATIC_ASSERT(JSTRACE_STRING == 2);
|
|||
#define GCX_OBJECT JSTRACE_OBJECT /* JSObject */
|
||||
#define GCX_DOUBLE JSTRACE_DOUBLE /* jsdouble */
|
||||
#define GCX_STRING JSTRACE_STRING /* JSString */
|
||||
#define GCX_FUNCTION JSTRACE_FUNCTION /* JSFunction */
|
||||
#define GCX_NAMESPACE JSTRACE_NAMESPACE /* JSXMLNamespace */
|
||||
#define GCX_QNAME JSTRACE_QNAME /* JSXMLQName */
|
||||
#define GCX_XML JSTRACE_XML /* JSXML */
|
||||
|
@ -235,14 +233,14 @@ js_IsAboutToBeFinalized(JSContext *cx, void *thing);
|
|||
#if JS_HAS_XML_SUPPORT
|
||||
# define JS_IS_VALID_TRACE_KIND(kind) ((uint32)(kind) <= JSTRACE_XML)
|
||||
#else
|
||||
# define JS_IS_VALID_TRACE_KIND(kind) ((uint32)(kind) <= JSTRACE_FUNCTION)
|
||||
# define JS_IS_VALID_TRACE_KIND(kind) ((uint32)(kind) <= JSTRACE_STRING)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* JS_IS_VALID_TRACE_KIND assumes that JSTRACE_FUNCTION is the last non-xml
|
||||
* JS_IS_VALID_TRACE_KIND assumes that JSTRACE_STRING is the last non-xml
|
||||
* trace kind when JS_HAS_XML_SUPPORT is false.
|
||||
*/
|
||||
JS_STATIC_ASSERT(JSTRACE_FUNCTION + 1 == JSTRACE_NAMESPACE);
|
||||
JS_STATIC_ASSERT(JSTRACE_STRING + 1 == JSTRACE_NAMESPACE);
|
||||
|
||||
/*
|
||||
* Trace jsval when JSVAL_IS_OBJECT(v) can be an arbitrary GC thing casted as
|
||||
|
|
|
@ -931,7 +931,7 @@ js_OnUnknownMethod(JSContext *cx, jsval *vp)
|
|||
vp[0] = ID_TO_VALUE(id);
|
||||
}
|
||||
#endif
|
||||
obj = js_NewObject(cx, &js_NoSuchMethodClass, NULL, NULL);
|
||||
obj = js_NewObject(cx, &js_NoSuchMethodClass, NULL, NULL, 0);
|
||||
if (!obj) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
|
@ -1600,7 +1600,9 @@ js_ImportProperty(JSContext *cx, JSObject *obj, jsid id)
|
|||
goto out;
|
||||
if (VALUE_IS_FUNCTION(cx, value)) {
|
||||
funobj = JSVAL_TO_OBJECT(value);
|
||||
closure = js_CloneFunctionObject(cx, funobj, obj);
|
||||
closure = js_CloneFunctionObject(cx,
|
||||
GET_FUNCTION_PRIVATE(cx, funobj),
|
||||
obj);
|
||||
if (!closure) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
|
@ -1839,7 +1841,7 @@ js_InvokeConstructor(JSContext *cx, jsval *vp, uintN argc)
|
|||
clasp = fun2->u.n.clasp;
|
||||
}
|
||||
}
|
||||
obj = js_NewObject(cx, clasp, proto, parent);
|
||||
obj = js_NewObject(cx, clasp, proto, parent, 0);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
|
||||
|
@ -2546,10 +2548,7 @@ js_Interpret(JSContext *cx)
|
|||
JS_GET_SCRIPT_OBJECT(script, GET_FULL_INDEX(PCOFF), obj)
|
||||
|
||||
#define LOAD_FUNCTION(PCOFF) \
|
||||
JS_BEGIN_MACRO \
|
||||
LOAD_OBJECT(PCOFF); \
|
||||
JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_FunctionClass); \
|
||||
JS_END_MACRO
|
||||
JS_GET_SCRIPT_FUNCTION(script, GET_FULL_INDEX(PCOFF), fun)
|
||||
|
||||
/*
|
||||
* Prepare to call a user-supplied branch handler, and abort the script
|
||||
|
@ -5586,8 +5585,9 @@ interrupt:
|
|||
* have seen the right parent already and created a sufficiently
|
||||
* well-scoped function object.
|
||||
*/
|
||||
obj = FUN_OBJECT(fun);
|
||||
if (OBJ_GET_PARENT(cx, obj) != obj2) {
|
||||
obj = js_CloneFunctionObject(cx, obj, obj2);
|
||||
obj = js_CloneFunctionObject(cx, fun, obj2);
|
||||
if (!obj)
|
||||
goto error;
|
||||
}
|
||||
|
@ -5605,7 +5605,6 @@ interrupt:
|
|||
* and setters do not need a slot, their value is stored elsewhere
|
||||
* in the property itself, not in obj slots.
|
||||
*/
|
||||
fun = GET_FUNCTION_PRIVATE(cx, obj);
|
||||
flags = JSFUN_GSFLAG2ATTR(fun->flags);
|
||||
if (flags) {
|
||||
attrs |= flags | JSPROP_SHARED;
|
||||
|
@ -5670,7 +5669,7 @@ interrupt:
|
|||
if (!parent)
|
||||
goto error;
|
||||
|
||||
obj = js_CloneFunctionObject(cx, obj, parent);
|
||||
obj = js_CloneFunctionObject(cx, fun, parent);
|
||||
if (!obj)
|
||||
goto error;
|
||||
|
||||
|
@ -5685,8 +5684,9 @@ interrupt:
|
|||
parent = js_GetScopeChain(cx, fp);
|
||||
if (!parent)
|
||||
goto error;
|
||||
obj = FUN_OBJECT(fun);
|
||||
if (OBJ_GET_PARENT(cx, obj) != parent) {
|
||||
obj = js_CloneFunctionObject(cx, obj, parent);
|
||||
obj = js_CloneFunctionObject(cx, fun, parent);
|
||||
if (!obj)
|
||||
goto error;
|
||||
}
|
||||
|
@ -5694,11 +5694,11 @@ interrupt:
|
|||
END_CASE(JSOP_ANONFUNOBJ)
|
||||
|
||||
BEGIN_CASE(JSOP_NAMEDFUNOBJ)
|
||||
/* ECMA ed. 3 FunctionExpression: function Identifier [etc.]. */
|
||||
LOAD_FUNCTION(0);
|
||||
rval = OBJECT_TO_JSVAL(obj);
|
||||
|
||||
/*
|
||||
* ECMA ed. 3 FunctionExpression: function Identifier [etc.].
|
||||
*
|
||||
* 1. Create a new object as if by the expression new Object().
|
||||
* 2. Add Result(1) to the front of the scope chain.
|
||||
*
|
||||
|
@ -5709,7 +5709,7 @@ interrupt:
|
|||
obj2 = js_GetScopeChain(cx, fp);
|
||||
if (!obj2)
|
||||
goto error;
|
||||
parent = js_NewObject(cx, &js_ObjectClass, NULL, obj2);
|
||||
parent = js_NewObject(cx, &js_ObjectClass, NULL, obj2, 0);
|
||||
if (!parent)
|
||||
goto error;
|
||||
|
||||
|
@ -5719,16 +5719,10 @@ interrupt:
|
|||
* that was parsed by the compiler into a Function object, and
|
||||
* saved in the script's atom map].
|
||||
*
|
||||
* Protect parent from GC after js_CloneFunctionObject calls into
|
||||
* js_NewObject, which displaces the newborn object root in cx by
|
||||
* allocating the clone, then runs a last-ditch GC while trying
|
||||
* to allocate the clone's slots vector. Another, multi-threaded
|
||||
* path: js_CloneFunctionObject => js_NewObject => OBJ_GET_CLASS
|
||||
* which may suspend the current request in ClaimScope, with the
|
||||
* newborn displaced as in the first scenario.
|
||||
* Protect parent from the GC.
|
||||
*/
|
||||
fp->scopeChain = parent;
|
||||
obj = js_CloneFunctionObject(cx, JSVAL_TO_OBJECT(rval), parent);
|
||||
obj = js_CloneFunctionObject(cx, fun, parent);
|
||||
if (!obj)
|
||||
goto error;
|
||||
|
||||
|
@ -5745,7 +5739,6 @@ interrupt:
|
|||
* name is [fun->atom, the identifier parsed by the compiler],
|
||||
* value is Result(3), and attributes are { DontDelete, ReadOnly }.
|
||||
*/
|
||||
fun = GET_FUNCTION_PRIVATE(cx, obj);
|
||||
attrs = JSFUN_GSFLAG2ATTR(fun->flags);
|
||||
if (attrs) {
|
||||
attrs |= JSPROP_SHARED;
|
||||
|
@ -5912,7 +5905,7 @@ interrupt:
|
|||
JS_ASSERT(i == JSProto_Array || i == JSProto_Object);
|
||||
obj = (i == JSProto_Array)
|
||||
? js_NewArrayObject(cx, 0, NULL)
|
||||
: js_NewObject(cx, &js_ObjectClass, NULL, NULL);
|
||||
: js_NewObject(cx, &js_ObjectClass, NULL, NULL, 0);
|
||||
if (!obj)
|
||||
goto error;
|
||||
PUSH_OPND(OBJECT_TO_JSVAL(obj));
|
||||
|
|
|
@ -400,7 +400,7 @@ js_ValueToIterator(JSContext *cx, uintN flags, jsval *vp)
|
|||
* we use the parent slot to keep track of the iterable, we must
|
||||
* fix it up after.
|
||||
*/
|
||||
iterobj = js_NewObject(cx, &js_IteratorClass, NULL, NULL);
|
||||
iterobj = js_NewObject(cx, &js_IteratorClass, NULL, NULL, 0);
|
||||
if (!iterobj)
|
||||
goto bad;
|
||||
|
||||
|
@ -725,7 +725,7 @@ js_NewGenerator(JSContext *cx, JSStackFrame *fp)
|
|||
jsval *newsp;
|
||||
|
||||
/* After the following return, failing control flow must goto bad. */
|
||||
obj = js_NewObject(cx, &js_GeneratorClass, NULL, NULL);
|
||||
obj = js_NewObject(cx, &js_GeneratorClass, NULL, NULL, 0);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -1759,7 +1759,7 @@ Object(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
JS_ASSERT(!argc || JSVAL_IS_NULL(argv[0]) || JSVAL_IS_VOID(argv[0]));
|
||||
if (cx->fp->flags & JSFRAME_CONSTRUCTING)
|
||||
return JS_TRUE;
|
||||
obj = js_NewObject(cx, &js_ObjectClass, NULL, NULL);
|
||||
obj = js_NewObject(cx, &js_ObjectClass, NULL, NULL, 0);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
@ -1900,7 +1900,7 @@ js_NewWithObject(JSContext *cx, JSObject *proto, JSObject *parent, jsint depth)
|
|||
{
|
||||
JSObject *obj;
|
||||
|
||||
obj = js_NewObject(cx, &js_WithClass, proto, parent);
|
||||
obj = js_NewObject(cx, &js_WithClass, proto, parent, 0);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
STOBJ_SET_SLOT(obj, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(cx->fp));
|
||||
|
@ -1919,7 +1919,7 @@ js_NewBlockObject(JSContext *cx)
|
|||
* scopes. Make sure obj has its own scope too, since clearing proto does
|
||||
* not affect OBJ_SCOPE(obj).
|
||||
*/
|
||||
obj = js_NewObject(cx, &js_BlockClass, NULL, NULL);
|
||||
obj = js_NewObject(cx, &js_BlockClass, NULL, NULL, 0);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
JS_LOCK_OBJ(cx, obj);
|
||||
|
@ -1937,7 +1937,7 @@ js_CloneBlockObject(JSContext *cx, JSObject *proto, JSObject *parent,
|
|||
{
|
||||
JSObject *clone;
|
||||
|
||||
clone = js_NewObject(cx, &js_BlockClass, proto, parent);
|
||||
clone = js_NewObject(cx, &js_BlockClass, proto, parent, 0);
|
||||
if (!clone)
|
||||
return NULL;
|
||||
STOBJ_SET_SLOT(clone, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(fp));
|
||||
|
@ -2423,7 +2423,8 @@ js_GetClassId(JSContext *cx, JSClass *clasp, jsid *idp)
|
|||
}
|
||||
|
||||
JSObject *
|
||||
js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent)
|
||||
js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent,
|
||||
uintN objectSize)
|
||||
{
|
||||
jsid id;
|
||||
|
||||
|
@ -2440,12 +2441,12 @@ js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent)
|
|||
}
|
||||
}
|
||||
|
||||
return js_NewObjectWithGivenProto(cx, clasp, proto, parent);
|
||||
return js_NewObjectWithGivenProto(cx, clasp, proto, parent, objectSize);
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto,
|
||||
JSObject *parent)
|
||||
JSObject *parent, uintN objectSize)
|
||||
{
|
||||
JSObject *obj;
|
||||
JSObjectOps *ops;
|
||||
|
@ -2459,24 +2460,25 @@ js_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto,
|
|||
jsdtrace_object_create_start(cx->fp, clasp);
|
||||
#endif
|
||||
|
||||
/* Always call the class's getObjectOps hook if it has one. */
|
||||
ops = clasp->getObjectOps
|
||||
? clasp->getObjectOps(cx, clasp)
|
||||
: &js_ObjectOps;
|
||||
/* Currently only functions can have non-standard allocation size. */
|
||||
if (clasp == &js_FunctionClass) {
|
||||
if (objectSize == 0)
|
||||
objectSize = sizeof(JSFunction);
|
||||
else
|
||||
JS_ASSERT(objectSize == sizeof(JSObject));
|
||||
} else {
|
||||
JS_ASSERT(objectSize == 0);
|
||||
objectSize = sizeof(JSObject);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a zeroed object from the GC heap. Do this *after* any other
|
||||
* GC-thing allocations under js_GetClassPrototype or clasp->getObjectOps,
|
||||
* to avoid displacing the newborn root for obj.
|
||||
* Allocate an object from the GC heap and initialize all its fields before
|
||||
* doing any operation that can potentially trigger GC.
|
||||
*/
|
||||
obj = (JSObject *) js_NewGCThing(cx, GCX_OBJECT, sizeof(JSObject));
|
||||
obj = (JSObject *) js_NewGCThing(cx, GCX_OBJECT, objectSize);
|
||||
if (!obj)
|
||||
goto earlybad;
|
||||
|
||||
/*
|
||||
* Initialize all JSObject fields before doing any operation that can
|
||||
* potentially trigger GC.
|
||||
*/
|
||||
obj->map = NULL;
|
||||
obj->dslots = NULL;
|
||||
|
||||
|
@ -2496,6 +2498,11 @@ js_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto,
|
|||
for (i = JSSLOT_PRIVATE; i != JS_INITIAL_NSLOTS; ++i)
|
||||
obj->fslots[i] = JSVAL_VOID;
|
||||
|
||||
#ifdef DEBUG
|
||||
memset((uint8 *) obj + sizeof(JSObject), JS_FREE_PATTERN,
|
||||
objectSize - sizeof(JSObject));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Root obj to prevent it from being collected out from under this call to
|
||||
* js_NewObject. There's a possibilty of GC under the objectHook call-out
|
||||
|
@ -2503,11 +2510,16 @@ js_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto,
|
|||
*/
|
||||
JS_PUSH_TEMP_ROOT_OBJECT(cx, obj, &tvr);
|
||||
|
||||
/* Always call the class's getObjectOps hook if it has one. */
|
||||
ops = clasp->getObjectOps
|
||||
? clasp->getObjectOps(cx, clasp)
|
||||
: &js_ObjectOps;
|
||||
|
||||
/*
|
||||
* Default parent to the parent of the prototype, which was set from
|
||||
* the parent of the prototype's constructor.
|
||||
*/
|
||||
if (!parent && proto)
|
||||
if (proto && !parent)
|
||||
STOBJ_SET_PARENT(obj, OBJ_GET_PARENT(cx, proto));
|
||||
|
||||
/*
|
||||
|
@ -2771,7 +2783,7 @@ js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
|
|||
proto = JSVAL_TO_OBJECT(rval);
|
||||
}
|
||||
|
||||
obj = js_NewObject(cx, clasp, proto, parent);
|
||||
obj = js_NewObject(cx, clasp, proto, parent, 0);
|
||||
if (!obj)
|
||||
goto out;
|
||||
|
||||
|
@ -4656,7 +4668,7 @@ js_PrimitiveToObject(JSContext *cx, jsval *vp)
|
|||
JS_ASSERT(!JSVAL_IS_OBJECT(*vp));
|
||||
JS_ASSERT(*vp != JSVAL_VOID);
|
||||
clasp = PrimitiveClasses[JSVAL_TAG(*vp) - 1];
|
||||
obj = js_NewObject(cx, clasp, NULL, NULL);
|
||||
obj = js_NewObject(cx, clasp, NULL, NULL, 0);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
STOBJ_SET_SLOT(obj, JSSLOT_PRIVATE, *vp);
|
||||
|
|
|
@ -425,14 +425,18 @@ extern JSBool
|
|||
js_GetClassId(JSContext *cx, JSClass *clasp, jsid *idp);
|
||||
|
||||
extern JSObject *
|
||||
js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent);
|
||||
js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent,
|
||||
uintN objectSize);
|
||||
|
||||
/*
|
||||
* See jsapi.h, JS_NewObjectWithGivenProto.
|
||||
*
|
||||
* objectSize is either the explicit size for the allocated object or 0
|
||||
* indicating to use the default size based on object's class.
|
||||
*/
|
||||
extern JSObject *
|
||||
js_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto,
|
||||
JSObject *parent);
|
||||
JSObject *parent, uintN objectSize);
|
||||
|
||||
/*
|
||||
* Fast access to immutable standard objects (constructors and prototypes).
|
||||
|
|
|
@ -1700,7 +1700,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
GET_OBJECT_FROM_BYTECODE(jp->script, pc, PCOFF, obj)
|
||||
|
||||
#define LOAD_FUNCTION(PCOFF) \
|
||||
GET_FUNCTION_FROM_BYTECODE(jp->script, pc, PCOFF, obj)
|
||||
GET_FUNCTION_FROM_BYTECODE(jp->script, pc, PCOFF, fun)
|
||||
|
||||
#define LOAD_REGEXP(PCOFF) \
|
||||
GET_REGEXP_FROM_BYTECODE(jp->script, pc, PCOFF, obj)
|
||||
|
@ -2016,11 +2016,11 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
break;
|
||||
|
||||
case SRC_FUNCDEF:
|
||||
JS_GET_SCRIPT_OBJECT(jp->script, js_GetSrcNoteOffset(sn, 0),
|
||||
obj);
|
||||
JS_GET_SCRIPT_FUNCTION(jp->script,
|
||||
js_GetSrcNoteOffset(sn, 0),
|
||||
fun);
|
||||
do_function:
|
||||
js_puts(jp, "\n");
|
||||
fun = GET_FUNCTION_PRIVATE(cx, obj);
|
||||
jp2 = JS_NEW_PRINTER(cx, "nested_function", fun,
|
||||
jp->indent, jp->pretty);
|
||||
if (!jp2)
|
||||
|
@ -3767,8 +3767,6 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
SprintStack ss2;
|
||||
|
||||
LOAD_FUNCTION(0);
|
||||
fun = GET_FUNCTION_PRIVATE(cx, obj);
|
||||
LOCAL_ASSERT(FUN_INTERPRETED(fun));
|
||||
inner = fun->u.i.script;
|
||||
|
||||
/*
|
||||
|
@ -3884,7 +3882,6 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
* parenthesization without confusing getter/setter code
|
||||
* that checks for JSOP_ANONFUNOBJ and JSOP_NAMEDFUNOBJ.
|
||||
*/
|
||||
fun = GET_FUNCTION_PRIVATE(cx, obj);
|
||||
if (!(fun->flags & JSFUN_EXPR_CLOSURE))
|
||||
indent |= JS_IN_GROUP_CONTEXT;
|
||||
str = JS_DecompileFunction(cx, fun, indent);
|
||||
|
|
|
@ -332,10 +332,10 @@ js_GetIndexFromBytecode(JSContext *cx, JSScript *script, jsbytecode *pc,
|
|||
JS_GET_SCRIPT_OBJECT((script), index_, obj); \
|
||||
JS_END_MACRO
|
||||
|
||||
#define GET_FUNCTION_FROM_BYTECODE(script, pc, pcoff, obj) \
|
||||
#define GET_FUNCTION_FROM_BYTECODE(script, pc, pcoff, fun) \
|
||||
JS_BEGIN_MACRO \
|
||||
GET_OBJECT_FROM_BYTECODE(script, pc, pcoff, obj); \
|
||||
JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_FunctionClass); \
|
||||
uintN index_ = js_GetIndexFromBytecode(cx, (script), (pc), (pcoff)); \
|
||||
JS_GET_SCRIPT_FUNCTION((script), index_, fun); \
|
||||
JS_END_MACRO
|
||||
|
||||
#define GET_REGEXP_FROM_BYTECODE(script, pc, pcoff, obj) \
|
||||
|
|
|
@ -1063,12 +1063,12 @@ NewCompilerFunction(JSContext *cx, JSTreeContext *tc, JSAtom *atom,
|
|||
JSFunction *fun;
|
||||
|
||||
JS_ASSERT((lambda & ~JSFUN_LAMBDA) == 0);
|
||||
parent = (tc->flags & TCF_IN_FUNCTION) ? tc->fun->object : cx->fp->varobj;
|
||||
parent = (tc->flags & TCF_IN_FUNCTION) ? FUN_OBJECT(tc->fun) : cx->fp->varobj;
|
||||
fun = js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED | lambda,
|
||||
parent, atom);
|
||||
if (fun && !(tc->flags & TCF_COMPILE_N_GO)) {
|
||||
STOBJ_SET_PARENT(fun->object, NULL);
|
||||
STOBJ_SET_PROTO(fun->object, NULL);
|
||||
STOBJ_SET_PARENT(FUN_OBJECT(fun), NULL);
|
||||
STOBJ_SET_PROTO(FUN_OBJECT(fun), NULL);
|
||||
}
|
||||
return fun;
|
||||
}
|
||||
|
@ -1191,7 +1191,7 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
|||
* Create wrapping box for fun->object early to protect against a
|
||||
* last-ditch GC.
|
||||
*/
|
||||
funpob = js_NewParsedObjectBox(cx, tc->parseContext, fun->object);
|
||||
funpob = js_NewParsedObjectBox(cx, tc->parseContext, FUN_OBJECT(fun));
|
||||
if (!funpob)
|
||||
return NULL;
|
||||
|
||||
|
@ -4293,7 +4293,7 @@ GeneratorExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
|||
lambda->pn_op = JSOP_ANONFUNOBJ;
|
||||
lambda->pn_pos.begin = body->pn_pos.begin;
|
||||
lambda->pn_funpob = js_NewParsedObjectBox(cx, tc->parseContext,
|
||||
fun->object);
|
||||
FUN_OBJECT(fun));
|
||||
if (!lambda->pn_funpob)
|
||||
return NULL;
|
||||
lambda->pn_body = body;
|
||||
|
|
|
@ -237,7 +237,6 @@ typedef union JSTempValueUnion {
|
|||
jsval value;
|
||||
JSObject *object;
|
||||
JSString *string;
|
||||
JSFunction *function;
|
||||
JSXML *xml;
|
||||
JSXMLQName *qname;
|
||||
JSTempValueTrace trace;
|
||||
|
|
|
@ -3868,7 +3868,7 @@ regexp_xdrObject(JSXDRState *xdr, JSObject **objp)
|
|||
return JS_FALSE;
|
||||
}
|
||||
if (xdr->mode == JSXDR_DECODE) {
|
||||
obj = js_NewObject(xdr->cx, &js_RegExpClass, NULL, NULL);
|
||||
obj = js_NewObject(xdr->cx, &js_RegExpClass, NULL, NULL, 0);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
STOBJ_SET_PARENT(obj, NULL);
|
||||
|
@ -4236,7 +4236,7 @@ RegExp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
}
|
||||
|
||||
/* Otherwise, replace obj with a new RegExp object. */
|
||||
obj = js_NewObject(cx, &js_RegExpClass, NULL, NULL);
|
||||
obj = js_NewObject(cx, &js_RegExpClass, NULL, NULL, 0);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
|
||||
|
@ -4296,7 +4296,7 @@ js_NewRegExpObject(JSContext *cx, JSTokenStream *ts,
|
|||
if (!re)
|
||||
return NULL;
|
||||
JS_PUSH_TEMP_ROOT_STRING(cx, str, &tvr);
|
||||
obj = js_NewObject(cx, &js_RegExpClass, NULL, NULL);
|
||||
obj = js_NewObject(cx, &js_RegExpClass, NULL, NULL, 0);
|
||||
if (!obj || !JS_SetPrivate(cx, obj, re)) {
|
||||
js_DestroyRegExp(cx, re);
|
||||
obj = NULL;
|
||||
|
@ -4314,7 +4314,7 @@ js_CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *parent)
|
|||
JSRegExp *re;
|
||||
|
||||
JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_RegExpClass);
|
||||
clone = js_NewObject(cx, &js_RegExpClass, NULL, parent);
|
||||
clone = js_NewObject(cx, &js_RegExpClass, NULL, parent, 0);
|
||||
if (!clone)
|
||||
return NULL;
|
||||
re = (JSRegExp *) JS_GetPrivate(cx, obj);
|
||||
|
|
|
@ -1692,7 +1692,6 @@ js_GetSrcNoteCached(JSContext *cx, JSScript *script, jsbytecode *pc)
|
|||
uintN
|
||||
js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
|
||||
{
|
||||
JSObject *obj;
|
||||
JSFunction *fun;
|
||||
uintN lineno;
|
||||
ptrdiff_t offset, target;
|
||||
|
@ -1710,9 +1709,7 @@ js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
|
|||
if (js_CodeSpec[*pc].format & JOF_INDEXBASE)
|
||||
pc += js_CodeSpec[*pc].length;
|
||||
if (*pc == JSOP_DEFFUN) {
|
||||
GET_FUNCTION_FROM_BYTECODE(script, pc, 0, obj);
|
||||
fun = GET_FUNCTION_PRIVATE(cx, obj);
|
||||
JS_ASSERT(FUN_INTERPRETED(fun));
|
||||
GET_FUNCTION_FROM_BYTECODE(script, pc, 0, fun);
|
||||
return fun->u.i.script->lineno;
|
||||
}
|
||||
|
||||
|
|
|
@ -140,6 +140,17 @@ struct JSScript {
|
|||
(obj) = objects_->vector[(index)]; \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_GET_SCRIPT_FUNCTION(script, index, fun) \
|
||||
JS_BEGIN_MACRO \
|
||||
JSObject *funobj_; \
|
||||
\
|
||||
JS_GET_SCRIPT_OBJECT(script, index, funobj_); \
|
||||
JS_ASSERT(HAS_FUNCTION_CLASS(funobj_)); \
|
||||
JS_ASSERT(funobj_ == (JSObject *) STOBJ_GET_PRIVATE(funobj_)); \
|
||||
(fun) = (JSFunction *) funobj_; \
|
||||
JS_ASSERT(FUN_INTERPRETED(fun)); \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_GET_SCRIPT_REGEXP(script, index, obj) \
|
||||
JS_BEGIN_MACRO \
|
||||
JSObjectArray *regexps_ = JS_SCRIPT_REGEXPS(script); \
|
||||
|
|
|
@ -331,7 +331,7 @@ js_GetXMLNamespaceObject(JSContext *cx, JSXMLNamespace *ns)
|
|||
JS_ASSERT(JS_GetPrivate(cx, obj) == ns);
|
||||
return obj;
|
||||
}
|
||||
obj = js_NewObject(cx, &js_NamespaceClass.base, NULL, NULL);
|
||||
obj = js_NewObject(cx, &js_NamespaceClass.base, NULL, NULL, 0);
|
||||
if (!obj || !JS_SetPrivate(cx, obj, ns)) {
|
||||
cx->weakRoots.newborn[GCX_OBJECT] = NULL;
|
||||
return NULL;
|
||||
|
@ -607,7 +607,7 @@ js_GetXMLQNameObject(JSContext *cx, JSXMLQName *qn)
|
|||
JS_ASSERT(JS_GetPrivate(cx, obj) == qn);
|
||||
return obj;
|
||||
}
|
||||
obj = js_NewObject(cx, &js_QNameClass.base, NULL, NULL);
|
||||
obj = js_NewObject(cx, &js_QNameClass.base, NULL, NULL, 0);
|
||||
if (!obj || !JS_SetPrivate(cx, obj, qn)) {
|
||||
cx->weakRoots.newborn[GCX_OBJECT] = NULL;
|
||||
return NULL;
|
||||
|
@ -632,7 +632,7 @@ js_GetAttributeNameObject(JSContext *cx, JSXMLQName *qn)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
obj = js_NewObject(cx, &js_AttributeNameClass, NULL, NULL);
|
||||
obj = js_NewObject(cx, &js_AttributeNameClass, NULL, NULL, 0);
|
||||
if (!obj || !JS_SetPrivate(cx, obj, qn)) {
|
||||
cx->weakRoots.newborn[GCX_OBJECT] = NULL;
|
||||
return NULL;
|
||||
|
@ -748,7 +748,7 @@ Namespace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
}
|
||||
|
||||
/* Create and return a new QName object exactly as if constructed. */
|
||||
obj = js_NewObject(cx, &js_NamespaceClass.base, NULL, NULL);
|
||||
obj = js_NewObject(cx, &js_NamespaceClass.base, NULL, NULL, 0);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
*rval = OBJECT_TO_JSVAL(obj);
|
||||
|
@ -856,7 +856,7 @@ QName(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
*/
|
||||
obj = js_NewObject(cx,
|
||||
JS_ValueToFunction(cx, argv[-2])->u.n.clasp,
|
||||
NULL, NULL);
|
||||
NULL, NULL, 0);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
*rval = OBJECT_TO_JSVAL(obj);
|
||||
|
@ -7584,7 +7584,7 @@ NewXMLObject(JSContext *cx, JSXML *xml)
|
|||
{
|
||||
JSObject *obj;
|
||||
|
||||
obj = js_NewObject(cx, &js_XMLClass, NULL, NULL);
|
||||
obj = js_NewObject(cx, &js_XMLClass, NULL, NULL, 0);
|
||||
if (!obj || !JS_SetPrivate(cx, obj, xml)) {
|
||||
cx->weakRoots.newborn[GCX_OBJECT] = NULL;
|
||||
return NULL;
|
||||
|
@ -7713,7 +7713,7 @@ js_InitXMLClass(JSContext *cx, JSObject *obj)
|
|||
fun = JS_DefineFunction(cx, obj, js_XMLList_str, XMLList, 1, 0);
|
||||
if (!fun)
|
||||
return NULL;
|
||||
if (!js_SetClassPrototype(cx, fun->object, proto,
|
||||
if (!js_SetClassPrototype(cx, FUN_OBJECT(fun), proto,
|
||||
JSPROP_READONLY | JSPROP_PERMANENT)) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -7997,7 +7997,8 @@ js_GetAnyName(JSContext *cx, jsval *vp)
|
|||
break;
|
||||
}
|
||||
|
||||
obj = js_NewObjectWithGivenProto(cx, &js_AnyNameClass, NULL, NULL);
|
||||
obj = js_NewObjectWithGivenProto(cx, &js_AnyNameClass, NULL,
|
||||
NULL, 0);
|
||||
if (!obj || !JS_SetPrivate(cx, obj, qn)) {
|
||||
cx->weakRoots.newborn[GCX_OBJECT] = NULL;
|
||||
ok = JS_FALSE;
|
||||
|
@ -8311,7 +8312,7 @@ js_StepXMLListFilter(JSContext *cx, JSBool initialized)
|
|||
return JS_FALSE;
|
||||
}
|
||||
|
||||
filterobj = js_NewObject(cx, &js_XMLFilterClass, NULL, NULL);
|
||||
filterobj = js_NewObject(cx, &js_XMLFilterClass, NULL, NULL, 0);
|
||||
if (!filterobj)
|
||||
return JS_FALSE;
|
||||
|
||||
|
|
|
@ -533,13 +533,9 @@ nsXPConnect::Collect()
|
|||
return gCollected;
|
||||
}
|
||||
|
||||
// JSTRACE_FUNCTION can hold on to a lot of objects, adding it to the cycle
|
||||
// collector reduces the number of edges to those objects.
|
||||
// JSTRACE_XML can recursively hold on to more JSTRACE_XML objects, adding it to
|
||||
// the cycle collector avoids stack overflow.
|
||||
#define ADD_TO_CC(_kind) \
|
||||
((_kind) == JSTRACE_OBJECT || (_kind) == JSTRACE_FUNCTION || \
|
||||
(_kind) == JSTRACE_XML)
|
||||
#define ADD_TO_CC(_kind) ((_kind) == JSTRACE_OBJECT || (_kind) == JSTRACE_XML)
|
||||
|
||||
#ifdef DEBUG_CC
|
||||
struct NoteJSRootTracer : public JSTracer
|
||||
|
|
Загрузка…
Ссылка в новой задаче