From 99df75fa8a07e5d0029d4ecc9dd1983a48abfdd7 Mon Sep 17 00:00:00 2001 From: "igor%mir2.org" Date: Fri, 21 Mar 2008 08:19:27 +0000 Subject: [PATCH] bug=423874 r=brendan a1.9b5=dsicore Allocating native functions together with JSObject git-svn-id: svn://10.0.0.236/trunk@248353 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/caps/src/nsScriptSecurityManager.cpp | 7 +- mozilla/js/jsd/jsd_xpc.cpp | 6 +- mozilla/js/src/js.c | 55 +-- mozilla/js/src/jsapi.c | 118 +++--- mozilla/js/src/jsarray.c | 6 +- mozilla/js/src/jsdate.c | 2 +- mozilla/js/src/jsdbgapi.c | 79 ++-- mozilla/js/src/jsdtracef.c | 10 +- mozilla/js/src/jsemit.c | 10 +- mozilla/js/src/jsemit.h | 2 +- mozilla/js/src/jsexn.c | 19 +- mozilla/js/src/jsfun.c | 381 ++++++++++-------- mozilla/js/src/jsfun.h | 126 ++++-- mozilla/js/src/jsgc.c | 35 +- mozilla/js/src/jsgc.h | 22 +- mozilla/js/src/jsinterp.c | 121 +++--- mozilla/js/src/jsinterp.h | 2 +- mozilla/js/src/jsiter.c | 6 +- mozilla/js/src/jsobj.c | 27 +- mozilla/js/src/jsobj.h | 5 +- mozilla/js/src/jsopcode.c | 277 +++++++------ mozilla/js/src/jsopcode.h | 21 +- mozilla/js/src/jsparse.c | 16 +- mozilla/js/src/jsparse.h | 3 +- mozilla/js/src/jsprvtd.h | 4 +- mozilla/js/src/jsregexp.c | 8 +- mozilla/js/src/jsscript.c | 31 +- mozilla/js/src/jsscript.h | 6 +- mozilla/js/src/jsxml.c | 25 +- mozilla/js/src/liveconnect/nsCLiveconnect.cpp | 4 +- mozilla/js/src/xpconnect/src/nsXPConnect.cpp | 6 +- 31 files changed, 827 insertions(+), 613 deletions(-) diff --git a/mozilla/caps/src/nsScriptSecurityManager.cpp b/mozilla/caps/src/nsScriptSecurityManager.cpp index b0d16759a14..c1f235ab041 100644 --- a/mozilla/caps/src/nsScriptSecurityManager.cpp +++ b/mozilla/caps/src/nsScriptSecurityManager.cpp @@ -1636,8 +1636,7 @@ nsScriptSecurityManager::CheckFunctionAccess(JSContext *aCx, void *aFunObj, { #ifdef DEBUG { - JSFunction *fun = - (JSFunction *)caps_GetJSPrivate((JSObject *)aFunObj); + JSFunction *fun = GET_FUNCTION_PRIVATE(aCx, (JSObject *)aFunObj); JSScript *script = JS_GetFunctionScript(aCx, fun); NS_ASSERTION(!script, "Null principal for non-native function!"); @@ -2152,7 +2151,7 @@ nsScriptSecurityManager::GetFunctionObjectPrincipal(JSContext *cx, nsresult *rv) { NS_PRECONDITION(rv, "Null out param"); - JSFunction *fun = (JSFunction *) caps_GetJSPrivate(obj); + JSFunction *fun = GET_FUNCTION_PRIVATE(cx, obj); JSScript *script = JS_GetFunctionScript(cx, fun); *rv = NS_OK; @@ -2221,7 +2220,7 @@ nsScriptSecurityManager::GetFramePrincipal(JSContext *cx, #ifdef DEBUG if (NS_SUCCEEDED(*rv) && !result) { - JSFunction *fun = (JSFunction *)caps_GetJSPrivate(obj); + JSFunction *fun = GET_FUNCTION_PRIVATE(cx, obj); JSScript *script = JS_GetFunctionScript(cx, fun); NS_ASSERTION(!script, "Null principal for non-native function!"); diff --git a/mozilla/js/jsd/jsd_xpc.cpp b/mozilla/js/jsd/jsd_xpc.cpp index bc33a848810..1d2dc56c51f 100644 --- a/mozilla/js/jsd/jsd_xpc.cpp +++ b/mozilla/js/jsd/jsd_xpc.cpp @@ -1033,7 +1033,9 @@ jsdScript::CreatePPLineMap() PRBool scriptOwner = PR_FALSE; if (fun) { - if (fun->nargs > 12) + PRUint32 nargs = JS_GetFunctionArity(fun); + + if (nargs > 12) return nsnull; JSString *jsstr = JS_DecompileFunctionBody (cx, fun, 4); if (!jsstr) @@ -1042,7 +1044,7 @@ jsdScript::CreatePPLineMap() const char *argnames[] = {"arg1", "arg2", "arg3", "arg4", "arg5", "arg6", "arg7", "arg8", "arg9", "arg10", "arg11", "arg12" }; - fun = JS_CompileUCFunction (cx, obj, "ppfun", fun->nargs, argnames, + fun = JS_CompileUCFunction (cx, obj, "ppfun", nargs, argnames, JS_GetStringChars(jsstr), JS_GetStringLength(jsstr), "x-jsd:ppbuffer?type=function", 3); diff --git a/mozilla/js/src/js.c b/mozilla/js/src/js.c index 62940032779..310d4c9f4e1 100644 --- a/mozilla/js/src/js.c +++ b/mozilla/js/src/js.c @@ -933,15 +933,15 @@ CountHeap(JSContext *cx, uintN argc, jsval *vp) const char *name; int32 kind; } traceKindNames[] = { - { "all", -1 }, - { "object", JSTRACE_OBJECT }, - { "double", JSTRACE_DOUBLE }, - { "string", JSTRACE_STRING }, - { "function", JSTRACE_FUNCTION }, + { "all", -1 }, + { "object", JSTRACE_OBJECT }, + { "double", JSTRACE_DOUBLE }, + { "string", JSTRACE_STRING }, + { "function", JSTRACE_SCRIPTED_FUNCTION }, #if JS_HAS_XML_SUPPORT - { "namespace", JSTRACE_NAMESPACE }, - { "qname", JSTRACE_QNAME }, - { "xml", JSTRACE_XML }, + { "namespace", JSTRACE_NAMESPACE }, + { "qname", JSTRACE_QNAME }, + { "xml", JSTRACE_XML }, #endif }; @@ -1029,7 +1029,7 @@ ValueToScript(JSContext *cx, jsval v) fun = JS_ValueToFunction(cx, v); if (!fun) return NULL; - script = FUN_SCRIPT(fun); + script = JS_GetFunctionScript(cx, fun); } return script; } @@ -1371,26 +1371,31 @@ Disassemble(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) return JS_FALSE; if (VALUE_IS_FUNCTION(cx, argv[i])) { - JSFunction *fun = JS_ValueToFunction(cx, argv[i]); - if (fun && (fun->flags & JSFUN_FLAGS_MASK)) { - uint16 flags = fun->flags; - fputs("flags:", stdout); + JSFunction *fun; + uint16 flags; + + fun = JS_ValueToFunction(cx, argv[i]); + if (fun) { + flags = JS_GetFunctionFlags(fun); + if (flags & JSFUN_FLAGS_MASK) { + fputs("flags:", stdout); #define SHOW_FLAG(flag) if (flags & JSFUN_##flag) fputs(" " #flag, stdout); - SHOW_FLAG(LAMBDA); - SHOW_FLAG(SETTER); - SHOW_FLAG(GETTER); - SHOW_FLAG(BOUND_METHOD); - SHOW_FLAG(HEAVYWEIGHT); - SHOW_FLAG(THISP_STRING); - SHOW_FLAG(THISP_NUMBER); - SHOW_FLAG(THISP_BOOLEAN); - SHOW_FLAG(EXPR_CLOSURE); - SHOW_FLAG(INTERPRETED); + SHOW_FLAG(LAMBDA); + SHOW_FLAG(SETTER); + SHOW_FLAG(GETTER); + SHOW_FLAG(BOUND_METHOD); + SHOW_FLAG(HEAVYWEIGHT); + SHOW_FLAG(THISP_STRING); + SHOW_FLAG(THISP_NUMBER); + SHOW_FLAG(THISP_BOOLEAN); + SHOW_FLAG(EXPR_CLOSURE); + SHOW_FLAG(SCRIPTED); #undef SHOW_FLAG - putchar('\n'); + putchar('\n'); + } } } @@ -2947,7 +2952,7 @@ Help(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) type = JS_TypeOfValue(cx, argv[i]); if (type == JSTYPE_FUNCTION) { fun = JS_ValueToFunction(cx, argv[i]); - str = fun->atom ? ATOM_TO_STRING(fun->atom) : NULL; + str = JS_GetFunctionId(fun); } else if (type == JSTYPE_STRING) { str = JSVAL_TO_STRING(argv[i]); } else { diff --git a/mozilla/js/src/jsapi.c b/mozilla/js/src/jsapi.c index b1a40d8e51f..4ce96e73813 100644 --- a/mozilla/js/src/jsapi.c +++ b/mozilla/js/src/jsapi.c @@ -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,7 +2014,7 @@ JS_PrintTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc, name = "double"; break; - case JSTRACE_FUNCTION: + case JSTRACE_SCRIPTED_FUNCTION: name = "function"; break; @@ -2074,9 +2074,9 @@ JS_PrintTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc, JS_snprintf(buf, bufsize, "%g", *(jsdouble *)thing); break; - case JSTRACE_FUNCTION: + case JSTRACE_SCRIPTED_FUNCTION: { - JSFunction *fun = (JSFunction *)thing; + JSScriptedFunction *fun = (JSScriptedFunction *)thing; if (fun->atom && ATOM_IS_STRING(fun->atom)) js_PutEscapedString(buf, bufsize, ATOM_TO_STRING(fun->atom), 0); @@ -2668,7 +2668,7 @@ JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto, JSTempValueRooter tvr; jsval cval, rval; JSBool named; - JSFunction *fun; + JSNativeFunction *fun; CHECK_REQUEST(cx); atom = js_Atomize(cx, clasp->name, strlen(clasp->name), 0); @@ -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; @@ -2741,7 +2741,7 @@ JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto, * we know to create an object of this class when we call the * constructor. */ - fun->u.n.clasp = clasp; + fun->clasp = clasp; /* * Optionally construct the prototype object, before the class has @@ -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; 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; @@ -4197,6 +4197,7 @@ JS_NewFunction(JSContext *cx, JSNative native, uintN nargs, uintN flags, JSObject *parent, const char *name) { JSAtom *atom; + JSNativeFunction *fun; CHECK_REQUEST(cx); @@ -4207,7 +4208,8 @@ JS_NewFunction(JSContext *cx, JSNative native, uintN nargs, uintN flags, if (!atom) return NULL; } - return js_NewFunction(cx, NULL, native, nargs, flags, parent, atom); + fun = js_NewNativeFunction(cx, native, nargs, flags, parent, atom); + return fun ? NATIVE_TO_FUN(fun) : NULL; } JS_PUBLIC_API(JSObject *) @@ -4224,49 +4226,43 @@ JS_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent) JS_PUBLIC_API(JSObject *) JS_GetFunctionObject(JSFunction *fun) { - return fun->object; + return FUN_OBJECT(fun); } JS_PUBLIC_API(const char *) JS_GetFunctionName(JSFunction *fun) { - return fun->atom - ? JS_GetStringBytes(ATOM_TO_STRING(fun->atom)) - : js_anonymous_str; + JSAtom *atom; + + atom = FUN_ATOM(fun); + return atom ? JS_GetStringBytes(ATOM_TO_STRING(atom)) : js_anonymous_str; } JS_PUBLIC_API(JSString *) JS_GetFunctionId(JSFunction *fun) { - return fun->atom ? ATOM_TO_STRING(fun->atom) : NULL; + JSAtom *atom; + + atom = FUN_ATOM(fun); + return atom ? ATOM_TO_STRING(atom) : NULL; } JS_PUBLIC_API(uintN) JS_GetFunctionFlags(JSFunction *fun) { -#ifdef MOZILLA_1_8_BRANCH - uintN flags = fun->flags; - - return JSFUN_DISJOINT_FLAGS(flags) | - (JSFUN_GETTER_TEST(flags) ? JSFUN_GETTER : 0) | - (JSFUN_SETTER_TEST(flags) ? JSFUN_SETTER : 0) | - (JSFUN_BOUND_METHOD_TEST(flags) ? JSFUN_BOUND_METHOD : 0) | - (JSFUN_HEAVYWEIGHT_TEST(flags) ? JSFUN_HEAVYWEIGHT : 0); -#else - return fun->flags; -#endif + return FUN_FLAGS(fun); } JS_PUBLIC_API(uint16) JS_GetFunctionArity(JSFunction *fun) { - return fun->nargs; + return FUN_NARGS(fun); } JS_PUBLIC_API(JSBool) JS_ObjectIsFunction(JSContext *cx, JSObject *obj) { - return OBJ_GET_CLASS(cx, obj) == &js_FunctionClass; + return HAS_FUNCTION_CLASS(obj); } JS_STATIC_DLL_CALLBACK(JSBool) @@ -4386,6 +4382,7 @@ JS_DefineFunctions(JSContext *cx, JSObject *obj, JSFunctionSpec *fs) uintN flags; JSObject *ctor; JSFunction *fun; + JSNativeFunction *native; CHECK_REQUEST(cx); ctor = NULL; @@ -4412,14 +4409,16 @@ JS_DefineFunctions(JSContext *cx, JSObject *obj, JSFunctionSpec *fs) fs->nargs + 1, flags); if (!fun) return JS_FALSE; - fun->u.n.extra = (uint16)fs->extra; - fun->u.n.minargs = (uint16)(fs->extra >> 16); + native = FUN_TO_NATIVE(fun); + native->extra = (uint16)fs->extra; + native->minargs = (uint16)(fs->extra >> 16); /* * 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, &native->object, 0, + PRIVATE_TO_JSVAL(fs))) return JS_FALSE; } @@ -4428,8 +4427,9 @@ JS_DefineFunctions(JSContext *cx, JSObject *obj, JSFunctionSpec *fs) fun = JS_DefineFunction(cx, obj, fs->name, fs->call, fs->nargs, flags); if (!fun) return JS_FALSE; - fun->u.n.extra = (uint16)fs->extra; - fun->u.n.minargs = (uint16)(fs->extra >> 16); + native = FUN_TO_NATIVE(fun); + native->extra = (uint16)fs->extra; + native->minargs = (uint16)(fs->extra >> 16); } return JS_TRUE; } @@ -4439,12 +4439,14 @@ JS_DefineFunction(JSContext *cx, JSObject *obj, const char *name, JSNative call, uintN nargs, uintN attrs) { JSAtom *atom; + JSNativeFunction *fun; CHECK_REQUEST(cx); atom = js_Atomize(cx, name, strlen(name), 0); if (!atom) return NULL; - return js_DefineFunction(cx, obj, atom, call, nargs, attrs); + fun = js_DefineFunction(cx, obj, atom, call, nargs, attrs); + return fun ? NATIVE_TO_FUN(fun) : NULL; } JS_PUBLIC_API(JSFunction *) @@ -4453,11 +4455,13 @@ JS_DefineUCFunction(JSContext *cx, JSObject *obj, uintN nargs, uintN attrs) { JSAtom *atom; + JSNativeFunction *fun; atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0); if (!atom) return NULL; - return js_DefineFunction(cx, obj, atom, call, nargs, attrs); + fun = js_DefineFunction(cx, obj, atom, call, nargs, attrs); + return fun ? NATIVE_TO_FUN(fun) : NULL; } JS_PUBLIC_API(JSScript *) @@ -4635,10 +4639,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; @@ -4723,7 +4727,7 @@ JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj, const jschar *chars, size_t length, const char *filename, uintN lineno) { - JSFunction *fun; + JSScriptedFunction *fun; JSTempValueRooter tvr; JSAtom *funAtom, *argAtom; uintN i; @@ -4738,7 +4742,7 @@ JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj, goto out2; } } - fun = js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED, obj, funAtom); + fun = js_NewScriptedFunction(cx, NULL, 0, obj, funAtom); if (!fun) goto out2; @@ -4782,12 +4786,12 @@ JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj, #endif out: - cx->weakRoots.newborn[JSTRACE_FUNCTION] = fun; + cx->weakRoots.newborn[JSTRACE_SCRIPTED_FUNCTION] = fun; JS_POP_TEMP_ROOT(cx, &tvr); out2: LAST_FRAME_CHECKS(cx, fun); - return fun; + return fun ? SCRIPTED_TO_FUN(fun) : NULL; } JS_PUBLIC_API(JSString *) @@ -4798,7 +4802,7 @@ JS_DecompileScript(JSContext *cx, JSScript *script, const char *name, JSString *str; CHECK_REQUEST(cx); - jp = JS_NEW_PRINTER(cx, name, NULL, + jp = JS_NEW_PRINTER(cx, name, indent & ~JS_DONT_PRETTY_PRINT, !(indent & JS_DONT_PRETTY_PRINT)); if (!jp) @@ -4818,15 +4822,18 @@ JS_DecompileFunction(JSContext *cx, JSFunction *fun, uintN indent) JSString *str; CHECK_REQUEST(cx); - jp = JS_NEW_PRINTER(cx, "JS_DecompileFunction", fun, + jp = JS_NEW_PRINTER(cx, "JS_DecompileFunction", indent & ~JS_DONT_PRETTY_PRINT, !(indent & JS_DONT_PRETTY_PRINT)); if (!jp) return NULL; - if (js_DecompileFunction(jp)) + if (FUN_IS_SCRIPTED(fun) + ? js_DecompileFunction(jp, FUN_TO_SCRIPTED(fun)) + : js_DecompileNativeFunction(jp, FUN_TO_NATIVE(fun))) { str = js_GetPrinterOutput(jp); - else + } else { str = NULL; + } js_DestroyPrinter(jp); return str; } @@ -4838,15 +4845,19 @@ JS_DecompileFunctionBody(JSContext *cx, JSFunction *fun, uintN indent) JSString *str; CHECK_REQUEST(cx); - jp = JS_NEW_PRINTER(cx, "JS_DecompileFunctionBody", fun, + + jp = JS_NEW_PRINTER(cx, "JS_DecompileFunctionBody", indent & ~JS_DONT_PRETTY_PRINT, !(indent & JS_DONT_PRETTY_PRINT)); if (!jp) return NULL; - if (js_DecompileFunctionBody(jp)) + if (FUN_IS_SCRIPTED(fun) + ? js_DecompileFunctionBody(jp, FUN_TO_SCRIPTED(fun)) + : js_DecompileNativeFunctionBody(jp, FUN_TO_NATIVE(fun))) { str = js_GetPrinterOutput(jp); - else + } else { str = NULL; + } js_DestroyPrinter(jp); return str; } @@ -4972,10 +4983,11 @@ JS_CallFunction(JSContext *cx, JSObject *obj, JSFunction *fun, uintN argc, jsval *argv, jsval *rval) { JSBool ok; + jsval funval; CHECK_REQUEST(cx); - ok = js_InternalCall(cx, obj, OBJECT_TO_JSVAL(fun->object), argc, argv, - rval); + funval = OBJECT_TO_JSVAL(FUN_OBJECT(fun)); + ok = js_InternalCall(cx, obj, funval, argc, argv, rval); LAST_FRAME_CHECKS(cx, ok); return ok; } diff --git a/mozilla/js/src/jsarray.c b/mozilla/js/src/jsarray.c index 724dff49655..59eff2cfa4d 100644 --- a/mozilla/js/src/jsarray.c +++ b/mozilla/js/src/jsarray.c @@ -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; diff --git a/mozilla/js/src/jsdate.c b/mozilla/js/src/jsdate.c index 75ba8cf8f6f..fc884698e56 100644 --- a/mozilla/js/src/jsdate.c +++ b/mozilla/js/src/jsdate.c @@ -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; diff --git a/mozilla/js/src/jsdbgapi.c b/mozilla/js/src/jsdbgapi.c index f3cd80740db..4f99b35b502 100644 --- a/mozilla/js/src/jsdbgapi.c +++ b/mozilla/js/src/jsdbgapi.c @@ -564,7 +564,9 @@ js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp) clasp = OBJ_GET_CLASS(cx, closure); if (clasp == &js_FunctionClass) { fun = GET_FUNCTION_PRIVATE(cx, closure); - script = FUN_SCRIPT(fun); + script = FUN_IS_SCRIPTED(fun) + ? FUN_TO_SCRIPTED(fun)->script + : NULL; } else if (clasp == &js_ScriptClass) { fun = NULL; script = (JSScript *) JS_GetPrivate(cx, closure); @@ -576,10 +578,15 @@ js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp) nslots = 2; injectFrame = JS_TRUE; if (fun) { - nslots += FUN_MINARGS(fun); - if (!FUN_INTERPRETED(fun)) { - nslots += fun->u.n.extra; - injectFrame = !(fun->flags & JSFUN_FAST_NATIVE); + if (FUN_IS_SCRIPTED(fun)) { + nslots += FUN_TO_SCRIPTED(fun)->nargs; + } else { + JSNativeFunction *nfun; + + nfun = FUN_TO_NATIVE(fun); + nslots += NATIVE_FUN_MINARGS(nfun); + nslots += nfun->extra; + injectFrame = !(nfun->flags & JSFUN_FAST_NATIVE); } } @@ -657,7 +664,7 @@ js_watch_set_wrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, funobj = JSVAL_TO_OBJECT(argv[-2]); JS_ASSERT(OBJ_GET_CLASS(cx, funobj) == &js_FunctionClass); wrapper = GET_FUNCTION_PRIVATE(cx, funobj); - userid = ATOM_KEY(wrapper->atom); + userid = ATOM_KEY(FUN_ATOM(wrapper)); *rval = argv[0]; return js_watch_set(cx, obj, userid, rval); } @@ -666,7 +673,7 @@ JSPropertyOp js_WrapWatchedSetter(JSContext *cx, jsid id, uintN attrs, JSPropertyOp setter) { JSAtom *atom; - JSFunction *wrapper; + JSNativeFunction *wrapper; if (!(attrs & JSPROP_SETTER)) return &js_watch_set; /* & to silence schoolmarmish MSVC */ @@ -680,12 +687,12 @@ js_WrapWatchedSetter(JSContext *cx, jsid id, uintN attrs, JSPropertyOp setter) } else { atom = NULL; } - wrapper = js_NewFunction(cx, NULL, js_watch_set_wrapper, 1, 0, - OBJ_GET_PARENT(cx, (JSObject *)setter), - atom); + wrapper = js_NewNativeFunction(cx, js_watch_set_wrapper, 1, 0, + OBJ_GET_PARENT(cx, (JSObject *)setter), + atom); if (!wrapper) return NULL; - return (JSPropertyOp) wrapper->object; + return (JSPropertyOp) &wrapper->object; } JS_PUBLIC_API(JSBool) @@ -918,19 +925,33 @@ JS_LineNumberToPC(JSContext *cx, JSScript *script, uintN lineno) JS_PUBLIC_API(JSScript *) JS_GetFunctionScript(JSContext *cx, JSFunction *fun) { - return FUN_SCRIPT(fun); + return FUN_IS_SCRIPTED(fun) ? FUN_TO_SCRIPTED(fun)->script : NULL; } JS_PUBLIC_API(JSNative) JS_GetFunctionNative(JSContext *cx, JSFunction *fun) { - return FUN_NATIVE(fun); + JSNativeFunction *nfun; + + if (FUN_IS_SCRIPTED(fun)) + return NULL; + + nfun = FUN_TO_NATIVE(fun); + return (nfun->flags & JSFUN_FAST_NATIVE) ? NULL : nfun->native; } JS_PUBLIC_API(JSFastNative) JS_GetFunctionFastNative(JSContext *cx, JSFunction *fun) { - return FUN_FAST_NATIVE(fun); + JSNativeFunction *nfun; + + if (FUN_IS_SCRIPTED(fun)) + return NULL; + + nfun = FUN_TO_NATIVE(fun); + return (nfun->flags & JSFUN_FAST_NATIVE) + ? (JSFastNative) nfun->native + : NULL; } JS_PUBLIC_API(JSPrincipals *) @@ -983,7 +1004,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 */ } @@ -1552,13 +1573,25 @@ JS_GetFunctionTotalSize(JSContext *cx, JSFunction *fun) { size_t nbytes; - nbytes = sizeof *fun; - if (fun->object) - nbytes += JS_GetObjectTotalSize(cx, fun->object); - if (FUN_INTERPRETED(fun)) - nbytes += JS_GetScriptTotalSize(cx, fun->u.i.script); - if (fun->atom) - nbytes += GetAtomTotalSize(cx, fun->atom); + if (FUN_IS_SCRIPTED(fun)) { + JSScriptedFunction *sfun; + + sfun = FUN_TO_SCRIPTED(fun); + nbytes = sizeof *sfun; + nbytes += JS_GetScriptTotalSize(cx, sfun->script); + if (sfun->object) + nbytes += JS_GetObjectTotalSize(cx, sfun->object); + if (sfun->atom) + nbytes += GetAtomTotalSize(cx, sfun->atom); + } else { + JSNativeFunction *nfun; + + nfun = FUN_TO_NATIVE(fun); + nbytes = sizeof(JSNativeFunction) - sizeof(JSObject); + nbytes += JS_GetObjectTotalSize(cx, &nfun->object); + if (nfun->atom) + nbytes += GetAtomTotalSize(cx, nfun->atom); + } return nbytes; } @@ -1667,7 +1700,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; diff --git a/mozilla/js/src/jsdtracef.c b/mozilla/js/src/jsdtracef.c index 194dfcd7b73..cec2bf1838a 100644 --- a/mozilla/js/src/jsdtracef.c +++ b/mozilla/js/src/jsdtracef.c @@ -54,9 +54,13 @@ static char dempty[] = ""; char * jsdtrace_funcclass_name(JSFunction *fun) { - return (!FUN_INTERPRETED(fun) && fun->u.n.clasp) - ? (char *)fun->u.n.clasp->name - : dempty; + JSNativeFunction *nfun; + + if (FUN_IS_SCRIPTED(fun)) + return dempty; + + nfun = FUN_TO_NATIVE(fun); + return nfun->clasp ? (char *) nfun->clasp->name : dempty; } char * diff --git a/mozilla/js/src/jsemit.c b/mozilla/js/src/jsemit.c index a6c8cd21f67..f2c584777b5 100644 --- a/mozilla/js/src/jsemit.c +++ b/mozilla/js/src/jsemit.c @@ -2037,7 +2037,7 @@ CheckSideEffects(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn, JSBool *answer) { JSBool ok; - JSFunction *fun; + JSScriptedFunction *fun; JSParseNode *pn2; ok = JS_TRUE; @@ -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 = FUN_TO_SCRIPTED(GET_FUNCTION_PRIVATE(cx, pn->pn_funpob->object)); if (fun->atom) *answer = JS_TRUE; break; @@ -3924,7 +3924,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn) switch (pn->pn_type) { case TOK_FUNCTION: { - JSFunction *fun; + JSScriptedFunction *fun; void *cg2mark; JSCodeGenerator *cg2; uintN slot; @@ -3937,8 +3937,8 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn) } #endif - fun = GET_FUNCTION_PRIVATE(cx, pn->pn_funpob->object); - if (fun->u.i.script) { + fun = FUN_TO_SCRIPTED(GET_FUNCTION_PRIVATE(cx, pn->pn_funpob->object)); + if (fun->script) { /* * This second pass is needed to emit JSOP_NOP with a source note * for the already-emitted function. See comments in the TOK_LC diff --git a/mozilla/js/src/jsemit.h b/mozilla/js/src/jsemit.h index 5a7af255bf1..be501e4869d 100644 --- a/mozilla/js/src/jsemit.h +++ b/mozilla/js/src/jsemit.h @@ -175,7 +175,7 @@ struct JSTreeContext { /* tree context for semantic checks */ XXX combine with blockChain? */ JSAtomList decls; /* function, const, and var declarations */ JSParseContext *parseContext; - JSFunction *fun; /* function to store argument and variable + JSScriptedFunction *fun; /* function to store argument and variable names when flags & TCF_IN_FUNCTION */ }; diff --git a/mozilla/js/src/jsexn.c b/mozilla/js/src/jsexn.c index bb8684046ae..2be34f56445 100644 --- a/mozilla/js/src/jsexn.c +++ b/mozilla/js/src/jsexn.c @@ -321,8 +321,11 @@ InitExnPrivate(JSContext *cx, JSObject *exnObject, JSString *message, elem->funName = NULL; elem->argc = 0; } else { - elem->funName = fp->fun->atom - ? ATOM_TO_STRING(fp->fun->atom) + JSAtom *atom; + + atom = FUN_ATOM(fp->fun); + elem->funName = atom + ? ATOM_TO_STRING(atom) : cx->runtime->emptyString; elem->argc = fp->argc; memcpy(values, fp->argv, fp->argc * sizeof(jsval)); @@ -750,7 +753,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); @@ -1043,7 +1046,7 @@ js_InitExceptionClasses(JSContext *cx, JSObject *obj) /* Initialize the prototypes first. */ for (i = 0; exceptions[i].name != 0; i++) { JSAtom *atom; - JSFunction *fun; + JSNativeFunction *fun; JSObject *funobj; JSString *nameString; int protoIndex = exceptions[i].protoIndex; @@ -1053,7 +1056,7 @@ js_InitExceptionClasses(JSContext *cx, JSObject *obj) (protoIndex != JSEXN_NONE) ? protos[protoIndex] : obj_proto, - obj); + obj, 0); if (!protos[i]) break; @@ -1067,10 +1070,10 @@ js_InitExceptionClasses(JSContext *cx, JSObject *obj) break; /* Make this constructor make objects of class Exception. */ - fun->u.n.clasp = &js_ErrorClass; + fun->clasp = &js_ErrorClass; /* Extract the constructor object. */ - funobj = fun->object; + funobj = &fun->object; /* Make the prototype and constructor links. */ if (!js_SetClassPrototype(cx, funobj, protos[i], @@ -1223,7 +1226,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; diff --git a/mozilla/js/src/jsfun.c b/mozilla/js/src/jsfun.c index a1893152f1a..60b72e83e1e 100644 --- a/mozilla/js/src/jsfun.c +++ b/mozilla/js/src/jsfun.c @@ -242,7 +242,8 @@ js_GetArgsObject(JSContext *cx, JSStackFrame *fp) * We must be in a function activation; the function must be lightweight * or else fp must have a variable object. */ - JS_ASSERT(fp->fun && (!(fp->fun->flags & JSFUN_HEAVYWEIGHT) || fp->varobj)); + JS_ASSERT(fp->fun); + JS_ASSERT_IF(FUN_FLAGS(fp->fun) & JSFUN_HEAVYWEIGHT, fp->varobj); /* Skip eval and debugger frames. */ while (fp->flags & JSFRAME_SPECIAL) @@ -254,7 +255,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; @@ -418,7 +419,7 @@ args_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) break; default: - if (FUN_INTERPRETED(fp->fun) && + if (FUN_IS_SCRIPTED(fp->fun) && (uintN)slot < fp->argc && !ArgWasDeleted(cx, fp, slot)) { fp->argv[slot] = *vp; @@ -602,7 +603,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; @@ -669,7 +670,7 @@ call_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) fp = (JSStackFrame *) JS_GetPrivate(cx, obj); if (!fp) return JS_TRUE; - JS_ASSERT(fp->fun); + JS_ASSERT(fp->fun && FUN_IS_SCRIPTED(fp->fun)); slot = JSVAL_TO_INT(id); switch (slot) { @@ -683,7 +684,7 @@ call_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) break; default: - if ((uintN)slot < JS_MAX(fp->argc, fp->fun->nargs)) + if ((uintN)slot < JS_MAX(fp->argc, FUN_TO_SCRIPTED(fp->fun)->nargs)) *vp = fp->argv[slot]; break; } @@ -701,7 +702,7 @@ call_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) fp = (JSStackFrame *) JS_GetPrivate(cx, obj); if (!fp) return JS_TRUE; - JS_ASSERT(fp->fun); + JS_ASSERT(fp->fun && FUN_IS_SCRIPTED(fp->fun)); slot = JSVAL_TO_INT(id); switch (slot) { @@ -710,7 +711,7 @@ call_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) break; default: - if ((uintN)slot < JS_MAX(fp->argc, fp->fun->nargs)) + if ((uintN)slot < JS_MAX(fp->argc, FUN_TO_SCRIPTED(fp->fun)->nargs)) fp->argv[slot] = *vp; break; } @@ -749,7 +750,7 @@ static JSBool call_enumerate(JSContext *cx, JSObject *obj) { JSStackFrame *fp; - JSFunction *fun; + JSScriptedFunction *fun; uintN n, i, slot; void *mark; jsuword *names; @@ -769,7 +770,7 @@ call_enumerate(JSContext *cx, JSObject *obj) * and functions in fp->vars for declared variables and nested-at-top-level * local functions. */ - fun = fp->fun; + fun = FUN_TO_SCRIPTED(fp->fun); n = JS_GET_LOCAL_NAME_COUNT(fun); if (n == 0) return JS_TRUE; @@ -821,6 +822,7 @@ call_resolve(JSContext *cx, JSObject *obj, jsval idval, uintN flags, { JSStackFrame *fp; jsid id; + JSScriptedFunction *fun; JSLocalKind localKind; JSPropertyOp getter, setter; uintN slot, attrs; @@ -829,7 +831,7 @@ call_resolve(JSContext *cx, JSObject *obj, jsval idval, uintN flags, fp = (JSStackFrame *) JS_GetPrivate(cx, obj); if (!fp) return JS_TRUE; - JS_ASSERT(fp->fun); + JS_ASSERT(fp->fun && FUN_IS_SCRIPTED(fp->fun)); JS_ASSERT(GET_FUNCTION_PRIVATE(cx, fp->callee) == fp->fun); if (!JSVAL_IS_STRING(idval)) @@ -838,16 +840,17 @@ call_resolve(JSContext *cx, JSObject *obj, jsval idval, uintN flags, if (!js_ValueToStringId(cx, idval, &id)) return JS_FALSE; - localKind = js_LookupLocal(cx, fp->fun, JSID_TO_ATOM(id), &slot); + fun = FUN_TO_SCRIPTED(fp->fun); + localKind = js_LookupLocal(cx, fun, JSID_TO_ATOM(id), &slot); if (localKind != JSLOCAL_NONE) { if (localKind == JSLOCAL_ARG) { - JS_ASSERT(slot < fp->fun->nargs); + JS_ASSERT(slot < fun->nargs); vp = fp->argv; getter = setter = NULL; attrs = JSPROP_PERMANENT; } else { JS_ASSERT(localKind == JSLOCAL_VAR || localKind == JSLOCAL_CONST); - JS_ASSERT(fp->fun->u.i.nvars == fp->nvars); + JS_ASSERT(FUN_TO_SCRIPTED(fp->fun)->nvars == fp->nvars); JS_ASSERT(slot < fp->nvars); vp = fp->vars; getter = js_GetCallVariable; @@ -1012,14 +1015,16 @@ fun_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) case ARGS_LENGTH: case FUN_ARITY: - *vp = INT_TO_JSVAL((jsint)fun->nargs); + *vp = INT_TO_JSVAL((jsint) FUN_NARGS(fun)); break; - case FUN_NAME: - *vp = fun->atom - ? ATOM_KEY(fun->atom) - : STRING_TO_JSVAL(cx->runtime->emptyString); + case FUN_NAME: { + JSAtom *atom; + + atom = FUN_ATOM(fun); + *vp = atom ? ATOM_KEY(atom) : STRING_TO_JSVAL(cx->runtime->emptyString); break; + } case FUN_CALLER: if (fp && fp->down && fp->down->fun) @@ -1035,7 +1040,7 @@ fun_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) default: /* XXX fun[0] and fun.arguments[0] are equivalent. */ - if (fp && fp->fun && (uintN)slot < fp->fun->nargs) + if (fp && fp->fun && (uintN)slot < FUN_NARGS(fp->fun)) *vp = fp->argv[slot]; break; } @@ -1070,7 +1075,7 @@ fun_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, return JS_TRUE; fun = GET_FUNCTION_PRIVATE(cx, obj); - JS_ASSERT(fun->object); + JS_ASSERT(FUN_OBJECT(fun)); /* * No need to reflect fun.prototype in 'fun.prototype = ... '. @@ -1099,7 +1104,7 @@ fun_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, * Beware of the wacky case of a user function named Object -- trying * to find a prototype for that will recur back here _ad perniciem_. */ - if (fun->atom == CLASS_ATOM(cx, Object)) + if (FUN_ATOM(fun) == CLASS_ATOM(cx, Object)) return JS_TRUE; /* @@ -1107,7 +1112,7 @@ fun_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, * object itself. */ proto = js_NewObject(cx, &js_ObjectClass, NULL, - OBJ_GET_PARENT(cx, obj)); + OBJ_GET_PARENT(cx, obj), 0); if (!proto) return JS_FALSE; @@ -1166,7 +1171,7 @@ static JSBool fun_xdrObject(JSXDRState *xdr, JSObject **objp) { JSContext *cx; - JSFunction *fun; + JSScriptedFunction *fun; uint32 nullAtom; /* flag to indicate if fun->atom is NULL */ uintN nargs, nvars, n; uint32 localsword; /* word to xdr argument and variable counts */ @@ -1176,20 +1181,23 @@ fun_xdrObject(JSXDRState *xdr, JSObject **objp) cx = xdr->cx; if (xdr->mode == JSXDR_ENCODE) { - fun = GET_FUNCTION_PRIVATE(cx, *objp); - if (!FUN_INTERPRETED(fun)) { + JSFunction *f; + + f = GET_FUNCTION_PRIVATE(cx, *objp); + if (!FUN_IS_SCRIPTED(f)) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NOT_SCRIPTED_FUNCTION, - JS_GetFunctionName(fun)); + JS_GetFunctionName(f)); return JS_FALSE; } + fun = FUN_TO_SCRIPTED(f); nullAtom = !fun->atom; nargs = fun->nargs; - nvars = fun->u.i.nvars; + nvars = fun->nvars; localsword = (nargs << 16) | nvars; flagsword = fun->flags; } else { - fun = js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED, NULL, NULL); + fun = js_NewScriptedFunction(cx, NULL, 0, NULL, NULL); if (!fun) return JS_FALSE; STOBJ_SET_PARENT(fun->object, NULL); @@ -1215,7 +1223,7 @@ fun_xdrObject(JSXDRState *xdr, JSObject **objp) if (xdr->mode == JSXDR_DECODE) { nargs = localsword >> 16; nvars = localsword & JS_BITMASK(16); - JS_ASSERT(flagsword | JSFUN_INTERPRETED); + JS_ASSERT(flagsword | JSFUN_SCRIPTED); fun->flags = (uint16) flagsword; } @@ -1316,15 +1324,15 @@ fun_xdrObject(JSXDRState *xdr, JSObject **objp) js_FreezeLocalNames(cx, fun); } - if (!js_XDRScript(xdr, &fun->u.i.script, NULL)) + if (!js_XDRScript(xdr, &fun->script, NULL)) goto bad; if (xdr->mode == JSXDR_DECODE) { *objp = fun->object; #ifdef CHECK_SCRIPT_OWNER - fun->u.i.script->owner = NULL; + fun->script->owner = NULL; #endif - js_CallNewScriptHook(cx, fun->u.i.script, fun); + js_CallNewScriptHook(cx, fun->script, fun); } out: @@ -1376,17 +1384,30 @@ static void fun_trace(JSTracer *trc, JSObject *obj) { JSFunction *fun; + JSNativeFunction *native; /* 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_IS_SCRIPTED(fun)) { + JS_CALL_TRACER(trc, FUN_TO_SCRIPTED(fun), + JSTRACE_SCRIPTED_FUNCTION, "private"); + return; + } + + native = (JSNativeFunction *) obj; + JS_ASSERT(FUN_TO_NATIVE(fun) == native); + if (native->atom) + JS_CALL_STRING_TRACER(trc, ATOM_TO_STRING(native->atom), "atom"); } static uint32 fun_reserveSlots(JSContext *cx, JSObject *obj) { JSFunction *fun; + JSScript *script; /* * We use JS_GetPrivate and not GET_FUNCTION_PRIVATE because during @@ -1394,9 +1415,12 @@ fun_reserveSlots(JSContext *cx, JSObject *obj) * private slot of the function object is set. */ fun = (JSFunction *) JS_GetPrivate(cx, obj); - return (fun && FUN_INTERPRETED(fun) && - fun->u.i.script && fun->u.i.script->regexpsOffset != 0) - ? JS_SCRIPT_REGEXPS(fun->u.i.script)->length + if (!fun || !FUN_IS_SCRIPTED(fun)) + return 0; + + script = FUN_TO_SCRIPTED(fun)->script; + return (script && script->regexpsOffset != 0) + ? JS_SCRIPT_REGEXPS(script)->length : 0; } @@ -1699,7 +1723,7 @@ static JSBool Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { JSStackFrame *fp, *caller; - JSFunction *fun; + JSScriptedFunction *fun; JSObject *parent; uintN i, n, lineno; JSAtom *atom; @@ -1715,7 +1739,7 @@ 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); @@ -1725,8 +1749,7 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) * 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) + if (JS_GetPrivate(cx, obj)) return JS_TRUE; /* @@ -1741,8 +1764,8 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) */ parent = OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(argv[-2])); - fun = js_NewFunction(cx, obj, NULL, 0, JSFUN_LAMBDA | JSFUN_INTERPRETED, - parent, cx->runtime->atomState.anonymousAtom); + fun = js_NewScriptedFunction(cx, obj, JSFUN_LAMBDA, parent, + cx->runtime->atomState.anonymousAtom); if (!fun) return JS_FALSE; @@ -1754,7 +1777,9 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) * are built for Function.prototype.call or .apply activations that invoke * Function indirectly from a script. */ - JS_ASSERT(!fp->script && fp->fun && fp->fun->u.n.native == Function); + JS_ASSERT(fp->fun && + !FUN_IS_SCRIPTED(fp->fun) && + FUN_TO_NATIVE(fp->fun)->native == Function); caller = JS_GetScriptedCaller(cx, fp); if (caller) { principals = JS_EvalFramePrincipals(cx, fp, caller); @@ -1932,7 +1957,7 @@ js_InitFunctionClass(JSContext *cx, JSObject *obj) { JSObject *proto; JSAtom *atom; - JSFunction *fun; + JSScriptedFunction *fun; proto = JS_InitClass(cx, obj, NULL, &js_FunctionClass, Function, 1, function_props, function_methods, NULL, NULL); @@ -1942,15 +1967,15 @@ js_InitFunctionClass(JSContext *cx, JSObject *obj) 0); if (!atom) goto bad; - fun = js_NewFunction(cx, proto, NULL, 0, JSFUN_INTERPRETED, obj, NULL); + fun = js_NewScriptedFunction(cx, proto, 0, obj, NULL); if (!fun) goto bad; - fun->u.i.script = js_NewScript(cx, 1, 0, 0, 0, 0, 0); - if (!fun->u.i.script) + fun->script = js_NewScript(cx, 1, 0, 0, 0, 0, 0); + if (!fun->script) goto bad; - fun->u.i.script->code[0] = JSOP_STOP; + fun->script->code[0] = JSOP_STOP; #ifdef CHECK_SCRIPT_OWNER - fun->u.i.script->owner = NULL; + fun->script->owner = NULL; #endif return proto; @@ -1977,18 +2002,20 @@ js_InitCallClass(JSContext *cx, JSObject *obj) return proto; } -JSFunction * -js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN nargs, - uintN flags, JSObject *parent, JSAtom *atom) +JSScriptedFunction * +js_NewScriptedFunction(JSContext *cx, JSObject *funobj, uintN flags, + JSObject *parent, JSAtom *atom) { - JSFunction *fun; + JSScriptedFunction *sfun; JSTempValueRooter tvr; + JS_ASSERT((flags & ~JSFUN_LAMBDA) == 0); + /* If funobj is null, allocate an object for it. */ if (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; } @@ -2000,115 +2027,134 @@ js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN nargs, * 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) + sfun = (JSScriptedFunction *) + js_NewGCThing(cx, GCX_FUNCTION, sizeof(JSScriptedFunction)); + if (!sfun) goto out; /* Initialize all function members. */ - fun->object = NULL; - fun->nargs = nargs; - fun->flags = flags & (JSFUN_FLAGS_MASK | JSFUN_INTERPRETED); - if (flags & JSFUN_INTERPRETED) { - JS_ASSERT(!native); - JS_ASSERT(nargs == 0); - fun->u.i.nvars = 0; - fun->u.i.spare = 0; - fun->u.i.script = NULL; + sfun->object = NULL; + sfun->flags = (flags & JSFUN_FLAGS_MASK) | JSFUN_SCRIPTED; + sfun->nargs = 0; + sfun->nvars = 0; + sfun->spare = 0; + sfun->script = NULL; #ifdef DEBUG - fun->u.i.names.taggedAtom = 0; + sfun->names.taggedAtom = 0; #endif - } else { - fun->u.n.native = native; - fun->u.n.extra = 0; - fun->u.n.minargs = 0; - fun->u.n.clasp = NULL; - } - fun->atom = atom; + sfun->atom = atom; /* Link fun to funobj and vice versa. */ - if (!js_LinkFunctionObject(cx, fun, funobj)) { - cx->weakRoots.newborn[GCX_OBJECT] = NULL; - fun = NULL; - } + sfun->object = funobj; + JS_SetPrivate(cx, funobj, SCRIPTED_TO_FUN(sfun)); out: JS_POP_TEMP_ROOT(cx, &tvr); - return fun; + return sfun; +} + +JSNativeFunction * +js_NewNativeFunction(JSContext *cx, JSNative native, uintN nargs, + uintN flags, JSObject *parent, JSAtom *atom) +{ + JSNativeFunction *nfun; + + JS_ASSERT(!(flags & (JSFUN_LAMBDA | JSFUN_SCRIPTED))); + nfun = (JSNativeFunction *) js_NewObject(cx, &js_FunctionClass, NULL, + parent, + sizeof(JSNativeFunction) - + sizeof(JSObject)); + if (!nfun) + return NULL; + + /* Initialize all function members. */ + nfun->flags = flags & (JSFUN_FLAGS_MASK | JSFUN_SCRIPTED); + nfun->nargs = nargs; + nfun->native = native; + nfun->extra = 0; + nfun->minargs = 0; + nfun->clasp = NULL; + nfun->atom = atom; + JS_SetPrivate(cx, &nfun->object, NATIVE_TO_FUN(nfun)); + + return nfun; } static void -TraceLocalNames(JSTracer *trc, JSFunction *fun); +TraceLocalNames(JSTracer *trc, JSScriptedFunction *fun); void -js_TraceFunction(JSTracer *trc, JSFunction *fun) +js_TraceFunction(JSTracer *trc, JSScriptedFunction *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); - } + if (fun->script) + js_TraceScript(trc, fun->script); + TraceLocalNames(trc, fun); } static void -DestroyLocalNames(JSContext *cx, JSFunction *fun); +DestroyLocalNames(JSContext *cx, JSScriptedFunction *fun); void -js_FinalizeFunction(JSContext *cx, JSFunction *fun) +js_FinalizeFunction(JSContext *cx, JSScriptedFunction *fun) { /* - * Null-check of i.script is required since the parser sets interpreted - * very early. + * Null-check of i.script is required since the parser creates + * JSScriptedFunction very early. */ - if (FUN_INTERPRETED(fun)) { - if (fun->u.i.script) - js_DestroyScript(cx, fun->u.i.script); - DestroyLocalNames(cx, fun); - } + if (fun->script) + js_DestroyScript(cx, fun->script); + DestroyLocalNames(cx, fun); } JSObject * js_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent) { - JSObject *newfunobj; JSFunction *fun; + JSObject *newfunobj; JS_ASSERT(OBJ_GET_CLASS(cx, funobj) == &js_FunctionClass); - newfunobj = js_NewObject(cx, &js_FunctionClass, NULL, parent); - if (!newfunobj) - return NULL; fun = GET_FUNCTION_PRIVATE(cx, funobj); - if (!js_LinkFunctionObject(cx, fun, newfunobj)) { - cx->weakRoots.newborn[GCX_OBJECT] = NULL; - return NULL; + if (FUN_IS_SCRIPTED(fun)) { + JSScriptedFunction *sfun; + + sfun = FUN_TO_SCRIPTED(fun); + JS_ASSERT(sfun->object); + newfunobj = js_NewObject(cx, &js_FunctionClass, NULL, parent, 0); + if (!newfunobj) + return NULL; + JS_SetPrivate(cx, newfunobj, SCRIPTED_TO_FUN(sfun)); + } else { + JS_ASSERT((JSNativeFunction *) funobj == FUN_TO_NATIVE(fun)); + newfunobj = js_NewObject(cx, &js_FunctionClass, NULL, parent, + sizeof(JSNativeFunction) - sizeof(JSObject)); + if (!newfunobj) + return NULL; + memcpy((uint8 *) newfunobj + sizeof(JSObject), + (uint8 *) funobj + sizeof(JSObject), + sizeof(JSNativeFunction) - sizeof(JSObject)); + JS_SetPrivate(cx, newfunobj, + NATIVE_TO_FUN((JSNativeFunction *) newfunobj)); } return newfunobj; } -JSBool -js_LinkFunctionObject(JSContext *cx, JSFunction *fun, JSObject *funobj) -{ - if (!fun->object) - fun->object = funobj; - return JS_SetPrivate(cx, funobj, fun); -} - -JSFunction * +JSNativeFunction * js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, JSNative native, uintN nargs, uintN attrs) { - JSFunction *fun; + JSNativeFunction *fun; JSPropertyOp gsop; - fun = js_NewFunction(cx, NULL, native, nargs, attrs, obj, atom); + fun = js_NewNativeFunction(cx, native, nargs, attrs, obj, atom); if (!fun) 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), gsop, gsop, attrs & ~JSFUN_FLAGS_MASK, NULL)) { return NULL; @@ -2148,6 +2194,7 @@ js_ValueToFunctionObject(JSContext *cx, jsval *vp, uintN flags) { JSFunction *fun; JSObject *funobj; + JSAtom *atom; JSStackFrame *caller; JSPrincipals *principals; @@ -2157,7 +2204,19 @@ js_ValueToFunctionObject(JSContext *cx, jsval *vp, uintN flags) fun = js_ValueToFunction(cx, vp, flags); if (!fun) return NULL; - funobj = fun->object; + if (FUN_IS_SCRIPTED(fun)) { + JSScriptedFunction *sfun; + + sfun = FUN_TO_SCRIPTED(fun); + funobj = sfun->object; + atom = sfun->atom; + } else { + JSNativeFunction *nfun; + + nfun = FUN_TO_NATIVE(fun); + funobj = &nfun->object; + atom = nfun->atom; + } *vp = OBJECT_TO_JSVAL(funobj); caller = JS_GetScriptedCaller(cx, cx->fp); @@ -2169,8 +2228,8 @@ js_ValueToFunctionObject(JSContext *cx, jsval *vp, uintN flags) } if (!js_CheckPrincipalsAccess(cx, funobj, principals, - fun->atom - ? fun->atom + atom + ? atom : cx->runtime->atomState.anonymousAtom)) { return NULL; } @@ -2321,7 +2380,8 @@ HashLocalName(JSContext *cx, JSLocalNameMap *map, JSAtom *name, } JSBool -js_AddLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, JSLocalKind kind) +js_AddLocal(JSContext *cx, JSScriptedFunction *fun, JSAtom *atom, + JSLocalKind kind) { jsuword taggedAtom; uint16 *indexp; @@ -2329,14 +2389,13 @@ js_AddLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, JSLocalKind kind) jsuword *array; JSLocalNameMap *map; - JS_ASSERT(FUN_INTERPRETED(fun)); - JS_ASSERT(!fun->u.i.script); + JS_ASSERT(!fun->script); JS_ASSERT(((jsuword) atom & 1) == 0); taggedAtom = (jsuword) atom; if (kind == JSLOCAL_ARG) { indexp = &fun->nargs; } else { - indexp = &fun->u.i.nvars; + indexp = &fun->nvars; if (kind == JSLOCAL_CONST) taggedAtom |= 1; else @@ -2344,17 +2403,17 @@ js_AddLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, JSLocalKind kind) } n = JS_GET_LOCAL_NAME_COUNT(fun); if (n == 0) { - JS_ASSERT(fun->u.i.names.taggedAtom == 0); - fun->u.i.names.taggedAtom = taggedAtom; + JS_ASSERT(fun->names.taggedAtom == 0); + fun->names.taggedAtom = taggedAtom; } else if (n < MAX_ARRAY_LOCALS) { if (n > 1) { - array = fun->u.i.names.array; + array = fun->names.array; } else { array = (jsuword *) JS_malloc(cx, MAX_ARRAY_LOCALS * sizeof *array); if (!array) return JS_FALSE; - array[0] = fun->u.i.names.taggedAtom; - fun->u.i.names.array = array; + array[0] = fun->names.taggedAtom; + fun->names.array = array; } if (kind == JSLOCAL_ARG) { /* @@ -2362,19 +2421,19 @@ js_AddLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, JSLocalKind kind) * so for the following arguments nvars != 0. */ #if JS_HAS_DESTRUCTURING - if (fun->u.i.nvars != 0) { + if (fun->nvars != 0) { memmove(array + fun->nargs + 1, array + fun->nargs, - fun->u.i.nvars * sizeof *array); + fun->nvars * sizeof *array); } #else - JS_ASSERT(fun->u.i.nvars == 0); + JS_ASSERT(fun->nvars == 0); #endif array[fun->nargs] = taggedAtom; } else { array[n] = taggedAtom; } } else if (n == MAX_ARRAY_LOCALS) { - array = fun->u.i.names.array; + array = fun->names.array; map = (JSLocalNameMap *) JS_malloc(cx, sizeof *map); if (!map) return JS_FALSE; @@ -2408,7 +2467,7 @@ js_AddLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, JSLocalKind kind) * At this point the entry is added and we cannot fail. It is time * to replace fun->u.i.names with the built map. */ - fun->u.i.names.map = map; + fun->names.map = map; JS_free(cx, array); } else { if (*indexp == JS_BITMASK(16)) { @@ -2418,7 +2477,7 @@ js_AddLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, JSLocalKind kind) : JSMSG_TOO_MANY_FUN_VARS); return JS_FALSE; } - if (!HashLocalName(cx, fun->u.i.names.map, atom, kind, *indexp)) + if (!HashLocalName(cx, fun->names.map, atom, kind, *indexp)) return JS_FALSE; } @@ -2428,18 +2487,18 @@ js_AddLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, JSLocalKind kind) } JSLocalKind -js_LookupLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, uintN *indexp) +js_LookupLocal(JSContext *cx, JSScriptedFunction *fun, JSAtom *atom, + uintN *indexp) { uintN n, i; jsuword *array; JSLocalNameHashEntry *entry; - JS_ASSERT(FUN_INTERPRETED(fun)); n = JS_GET_LOCAL_NAME_COUNT(fun); if (n == 0) return JSLOCAL_NONE; if (n <= MAX_ARRAY_LOCALS) { - array = (n == 1) ? &fun->u.i.names.taggedAtom : fun->u.i.names.array; + array = (n == 1) ? &fun->names.taggedAtom : fun->names.array; /* Search from the tail to pick up the last duplicated name. */ i = n; @@ -2460,7 +2519,7 @@ js_LookupLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, uintN *indexp) } while (i != 0); } else { entry = (JSLocalNameHashEntry *) - JS_DHashTableOperate(&fun->u.i.names.map->names, atom, + JS_DHashTableOperate(&fun->names.map->names, atom, JS_DHASH_LOOKUP); if (JS_DHASH_ENTRY_IS_BUSY(&entry->hdr)) { JS_ASSERT(entry->localKind != JSLOCAL_NONE); @@ -2473,11 +2532,11 @@ js_LookupLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, uintN *indexp) } typedef struct JSLocalNameEnumeratorArgs { - JSFunction *fun; - jsuword *names; + JSScriptedFunction *fun; + jsuword *names; #ifdef DEBUG - uintN nCopiedArgs; - uintN nCopiedVars; + uintN nCopiedArgs; + uintN nCopiedVars; #endif } JSLocalNameEnumeratorArgs; @@ -2501,8 +2560,8 @@ get_local_names_enumerator(JSDHashTable *table, JSDHashEntryHdr *hdr, } else { JS_ASSERT(entry->localKind == JSLOCAL_VAR || entry->localKind == JSLOCAL_CONST); - JS_ASSERT(entry->index < args->fun->u.i.nvars); - JS_ASSERT(args->nCopiedVars++ < args->fun->u.i.nvars); + JS_ASSERT(entry->index < args->fun->nvars); + JS_ASSERT(args->nCopiedVars++ < args->fun->nvars); i = args->fun->nargs + entry->index; constFlag = (entry->localKind == JSLOCAL_CONST); } @@ -2511,7 +2570,7 @@ get_local_names_enumerator(JSDHashTable *table, JSDHashEntryHdr *hdr, } jsuword * -js_GetLocalNameArray(JSContext *cx, JSFunction *fun, JSArenaPool *pool) +js_GetLocalNameArray(JSContext *cx, JSScriptedFunction *fun, JSArenaPool *pool) { uintN n; jsuword *names; @@ -2519,12 +2578,11 @@ js_GetLocalNameArray(JSContext *cx, JSFunction *fun, JSArenaPool *pool) JSLocalNameEnumeratorArgs args; JSNameIndexPair *dup; - JS_ASSERT(FUN_INTERPRETED(fun)); n = JS_GET_LOCAL_NAME_COUNT(fun); JS_ASSERT(n != 0); if (n <= MAX_ARRAY_LOCALS) - return (n == 1) ? &fun->u.i.names.taggedAtom : fun->u.i.names.array; + return (n == 1) ? &fun->names.taggedAtom : fun->names.array; /* * No need to check for overflow of the allocation size as we are making a @@ -2540,7 +2598,7 @@ js_GetLocalNameArray(JSContext *cx, JSFunction *fun, JSArenaPool *pool) /* Some parameter names can be NULL due to destructuring patterns. */ memset(names, 0, fun->nargs * sizeof *names); #endif - map = fun->u.i.names.map; + map = fun->names.map; args.fun = fun; args.names = names; #ifdef DEBUG @@ -2556,7 +2614,7 @@ js_GetLocalNameArray(JSContext *cx, JSFunction *fun, JSArenaPool *pool) #if !JS_HAS_DESTRUCTURING JS_ASSERT(args.nCopiedArgs == fun->nargs); #endif - JS_ASSERT(args.nCopiedVars == fun->u.i.nvars); + JS_ASSERT(args.nCopiedVars == fun->nvars); return names; } @@ -2579,18 +2637,17 @@ trace_local_names_enumerator(JSDHashTable *table, JSDHashEntryHdr *hdr, } static void -TraceLocalNames(JSTracer *trc, JSFunction *fun) +TraceLocalNames(JSTracer *trc, JSScriptedFunction *fun) { uintN n, i; JSAtom *atom; jsuword *array; - JS_ASSERT(FUN_INTERPRETED(fun)); n = JS_GET_LOCAL_NAME_COUNT(fun); if (n == 0) return; if (n <= MAX_ARRAY_LOCALS) { - array = (n == 1) ? &fun->u.i.names.taggedAtom : fun->u.i.names.array; + array = (n == 1) ? &fun->names.taggedAtom : fun->names.array; i = n; do { --i; @@ -2603,7 +2660,7 @@ TraceLocalNames(JSTracer *trc, JSFunction *fun) } } while (i != 0); } else { - JS_DHashTableEnumerate(&fun->u.i.names.map->names, + JS_DHashTableEnumerate(&fun->names.map->names, trace_local_names_enumerator, trc); /* @@ -2614,33 +2671,31 @@ TraceLocalNames(JSTracer *trc, JSFunction *fun) } void -DestroyLocalNames(JSContext *cx, JSFunction *fun) +DestroyLocalNames(JSContext *cx, JSScriptedFunction *fun) { uintN n; - n = fun->nargs + fun->u.i.nvars; + n = fun->nargs + fun->nvars; if (n <= 1) return; if (n <= MAX_ARRAY_LOCALS) - JS_free(cx, fun->u.i.names.array); + JS_free(cx, fun->names.array); else - FreeLocalNameHash(cx, fun->u.i.names.map); + FreeLocalNameHash(cx, fun->names.map); } void -js_FreezeLocalNames(JSContext *cx, JSFunction *fun) +js_FreezeLocalNames(JSContext *cx, JSScriptedFunction *fun) { uintN n; jsuword *array; - JS_ASSERT(FUN_INTERPRETED(fun)); - JS_ASSERT(!fun->u.i.script); - n = fun->nargs + fun->u.i.nvars; + JS_ASSERT(!fun->script); + n = fun->nargs + fun->nvars; if (2 <= n && n < MAX_ARRAY_LOCALS) { /* Shrink over-allocated array ignoring realloc failures. */ - array = (jsuword *) JS_realloc(cx, fun->u.i.names.array, - n * sizeof *array); + array = (jsuword *) JS_realloc(cx, fun->names.array, n * sizeof *array); if (array) - fun->u.i.names.array = array; + fun->names.array = array; } } diff --git a/mozilla/js/src/jsfun.h b/mozilla/js/src/jsfun.h index fce8c783d12..18fd6b8009f 100644 --- a/mozilla/js/src/jsfun.h +++ b/mozilla/js/src/jsfun.h @@ -44,6 +44,7 @@ */ #include "jsprvtd.h" #include "jspubtd.h" +#include "jsobj.h" JS_BEGIN_EXTERN_C @@ -62,44 +63,73 @@ typedef union JSLocalNames { JSLocalNameMap *map; } JSLocalNames; -struct JSFunction { - JSObject *object; /* back-pointer to GC'ed object header */ +struct JSNativeFunction { + JSObject object; + uint16 flags; /* bound method and other flags, see jsapi.h */ uint16 nargs; /* maximum number of specified arguments, reflected as f.length/f.arity */ - uint16 flags; /* bound method and other flags, see jsapi.h */ - union { - struct { - uint16 extra; /* number of arg slots for local GC roots */ - uint16 minargs;/* minimum number of specified arguments, used + uint16 extra; /* number of arg slots for local GC roots */ + uint16 minargs; /* minimum number of specified arguments, used only when calling fast native */ - JSNative native; /* native method pointer or null */ - JSClass *clasp; /* if non-null, constructor for this class */ - } n; - struct { - uint16 nvars; /* number of local variables */ - uint16 spare; /* reserved for future use */ - JSScript *script;/* interpreted bytecode descriptor or null */ - JSLocalNames names; /* argument and variable names */ - } i; - } u; + JSNative native; /* native method pointer or null */ + JSClass *clasp; /* if non-null, constructor for this class */ + JSAtom *atom; /* name for diagnostics and decompiling */ +}; + +struct JSScriptedFunction { + JSObject *object; /* back-pointer to GC'ed object header */ + uint16 flags; /* bound method and other flags, see jsapi.h */ + uint16 nargs; /* number of arguments */ + uint16 nvars; /* number of local variables */ + uint16 spare; /* reserved for future use */ + JSScript *script; /* interpreted bytecode descriptor or null */ + JSLocalNames names; /* argument and variable names */ JSAtom *atom; /* name for diagnostics and decompiling */ }; #define JSFUN_EXPR_CLOSURE 0x4000 /* expression closure: function(x)x*x */ -#define JSFUN_INTERPRETED 0x8000 /* use u.i if set, u.n if unset */ +#define JSFUN_SCRIPTED 0x8000 /* use FUN_TO_SCRIPTED if set, + FUN_TO_NATIVE if unset */ -#define JSFUN_SCRIPT_OR_FAST_NATIVE (JSFUN_INTERPRETED | JSFUN_FAST_NATIVE) -#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) -#define FUN_NATIVE(fun) (FUN_SLOW_NATIVE(fun) ? (fun)->u.n.native : NULL) -#define FUN_FAST_NATIVE(fun) (((fun)->flags & JSFUN_FAST_NATIVE) \ - ? (JSFastNative) (fun)->u.n.native \ - : NULL) -#define FUN_MINARGS(fun) (((fun)->flags & JSFUN_FAST_NATIVE) \ - ? (fun)->u.n.minargs \ - : (fun)->nargs) +/* + * JSFunction * points into the flags field of either JSNativeFunction + * or JSScriptedFunction. + */ +#define FUN_FLAGS(fun) (*(uint16 *) (fun)) + +#define FUN_IS_SCRIPTED(fun) (FUN_FLAGS(fun) & JSFUN_SCRIPTED) + +#define FUN_TO_SCRIPTED(fun) \ + (JS_ASSERT(FUN_IS_SCRIPTED(fun)), \ + (JSScriptedFunction *)((uint8 *)fun - offsetof(JSScriptedFunction, flags))) + +#define FUN_TO_NATIVE(fun) \ + (JS_ASSERT(!FUN_IS_SCRIPTED(fun)), \ + (JSNativeFunction *)((uint8 *)fun - offsetof(JSNativeFunction, flags))) + +#define NATIVE_TO_FUN(nfun) \ + (JS_ASSERT(((nfun)->flags & JSFUN_SCRIPTED) == 0), \ + (JSFunction *) (void *) &(nfun)->flags) + +#define SCRIPTED_TO_FUN(sfun) \ + (JS_ASSERT((sfun)->flags & JSFUN_SCRIPTED), \ + (JSFunction *) (void *) &(sfun)->flags) + +#define FUN_NARGS(fun) (FUN_IS_SCRIPTED(fun) \ + ? FUN_TO_SCRIPTED(fun)->nargs \ + : FUN_TO_NATIVE(fun)->nargs) + +#define FUN_OBJECT(fun) (FUN_IS_SCRIPTED(fun) \ + ? FUN_TO_SCRIPTED(fun)->object \ + : &FUN_TO_NATIVE(fun)->object) + +#define FUN_ATOM(fun) (FUN_IS_SCRIPTED(fun) \ + ? FUN_TO_SCRIPTED(fun)->atom \ + : FUN_TO_NATIVE(fun)->atom) + +#define NATIVE_FUN_MINARGS(nfun) \ + (((nfun)->flags & JSFUN_FAST_NATIVE) ? (nfun)->minargs : (nfun)->nargs) extern JSClass js_ArgumentsClass; extern JS_FRIEND_DATA(JSClass) js_CallClass; @@ -107,19 +137,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 * @@ -135,19 +166,24 @@ extern JSFunction * js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN nargs, uintN flags, JSObject *parent, JSAtom *atom); -extern void -js_TraceFunction(JSTracer *trc, JSFunction *fun); +extern JSNativeFunction * +js_NewNativeFunction(JSContext *cx, JSNative native, uintN nargs, uintN flags, + JSObject *parent, JSAtom *atom); + +extern JSScriptedFunction * +js_NewScriptedFunction(JSContext *cx, JSObject *funobj, uintN flags, + JSObject *parent, JSAtom *atom); extern void -js_FinalizeFunction(JSContext *cx, JSFunction *fun); +js_TraceFunction(JSTracer *trc, JSScriptedFunction *fun); + +extern void +js_FinalizeFunction(JSContext *cx, JSScriptedFunction *fun); extern JSObject * js_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent); -extern JSBool -js_LinkFunctionObject(JSContext *cx, JSFunction *fun, JSObject *object); - -extern JSFunction * +extern JSNativeFunction * js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, JSNative native, uintN nargs, uintN flags); @@ -206,10 +242,11 @@ typedef enum JSLocalKind { JSLOCAL_CONST } JSLocalKind; -#define JS_GET_LOCAL_NAME_COUNT(fun) ((fun)->nargs + (fun)->u.i.nvars) +#define JS_GET_LOCAL_NAME_COUNT(fun) ((fun)->nargs + (fun)->nvars) extern JSBool -js_AddLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, JSLocalKind kind); +js_AddLocal(JSContext *cx, JSScriptedFunction *fun, JSAtom *atom, + JSLocalKind kind); /* * Look up an argument or variable name returning its kind when found or @@ -218,7 +255,8 @@ js_AddLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, JSLocalKind kind); * variable. */ extern JSLocalKind -js_LookupLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, uintN *indexp); +js_LookupLocal(JSContext *cx, JSScriptedFunction *fun, JSAtom *atom, + uintN *indexp); /* * Functions to work with local names as an array of words. @@ -235,7 +273,7 @@ js_LookupLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, uintN *indexp); * corresponds to the const declaration. */ extern jsuword * -js_GetLocalNameArray(JSContext *cx, JSFunction *fun, JSArenaPool *pool); +js_GetLocalNameArray(JSContext *cx, JSScriptedFunction *fun, JSArenaPool *pool); #define JS_LOCAL_NAME_TO_ATOM(nameWord) \ ((JSAtom *) ((nameWord) & ~(jsuword) 1)) @@ -244,7 +282,7 @@ js_GetLocalNameArray(JSContext *cx, JSFunction *fun, JSArenaPool *pool); ((((nameWord) & (jsuword) 1)) != 0) extern void -js_FreezeLocalNames(JSContext *cx, JSFunction *fun); +js_FreezeLocalNames(JSContext *cx, JSScriptedFunction *fun); JS_END_EXTERN_C diff --git a/mozilla/js/src/jsgc.c b/mozilla/js/src/jsgc.c index 53dcf4061f7..e601f90c061 100644 --- a/mozilla/js/src/jsgc.c +++ b/mozilla/js/src/jsgc.c @@ -2250,8 +2250,8 @@ 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); + case JSTRACE_SCRIPTED_FUNCTION: + js_TraceFunction(trc, (JSScriptedFunction *) thing); break; #if JS_HAS_XML_SUPPORT @@ -2660,7 +2660,7 @@ gc_lock_traversal(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 num, void js_TraceStackFrame(JSTracer *trc, JSStackFrame *fp) { - uintN nslots, minargs, skip; + uintN nslots, skip; if (fp->callobj) JS_CALL_OBJECT_TRACER(trc, fp->callobj, "call"); @@ -2682,8 +2682,8 @@ js_TraceStackFrame(JSTracer *trc, JSStackFrame *fp) } /* Allow for primitive this parameter due to JSFUN_THISP_* flags. */ - JS_ASSERT(JSVAL_IS_OBJECT((jsval)fp->thisp) || - (fp->fun && JSFUN_THISP_FLAGS(fp->fun->flags))); + JS_ASSERT_IF(!JSVAL_IS_OBJECT((jsval)fp->thisp), + fp->fun && JSFUN_THISP_FLAGS(FUN_FLAGS(fp->fun))); JS_CALL_VALUE_TRACER(trc, (jsval)fp->thisp, "this"); if (fp->callee) @@ -2693,14 +2693,22 @@ js_TraceStackFrame(JSTracer *trc, JSStackFrame *fp) nslots = fp->argc; skip = 0; if (fp->fun) { - minargs = FUN_MINARGS(fp->fun); - if (minargs > nslots) - nslots = minargs; - if (!FUN_INTERPRETED(fp->fun)) { - JS_ASSERT(!(fp->fun->flags & JSFUN_FAST_NATIVE)); - nslots += fp->fun->u.n.extra; + if (FUN_IS_SCRIPTED(fp->fun)) { + JSScriptedFunction *sfun; + + sfun = FUN_TO_SCRIPTED(fp->fun); + if (nslots < sfun->nargs) + nslots = sfun->nargs; + } else { + JSNativeFunction *nfun; + + JS_ASSERT(!(FUN_FLAGS(fp->fun) & JSFUN_FAST_NATIVE)); + nfun = FUN_TO_NATIVE(fp->fun); + if (nslots < nfun->nargs) + nslots = nfun->nargs; + nslots += nfun->extra; } - if (fp->fun->flags & JSFRAME_ROOTED_ARGV) + if (fp->flags & JSFRAME_ROOTED_ARGV) skip = 2 + fp->argc; } TRACE_JSVALS(trc, 2 + nslots - skip, fp->argv - 2 + skip, "operand"); @@ -3328,7 +3336,8 @@ js_GC(JSContext *cx, JSGCInvocationKind gckind) /* Do nothing. */ break; case GCX_FUNCTION: - js_FinalizeFunction(cx, (JSFunction *) thing); + js_FinalizeFunction(cx, + (JSScriptedFunction *) thing); break; #if JS_HAS_XML_SUPPORT case GCX_NAMESPACE: diff --git a/mozilla/js/src/jsgc.h b/mozilla/js/src/jsgc.h index 99f51e40cf5..43deb2602d6 100644 --- a/mozilla/js/src/jsgc.h +++ b/mozilla/js/src/jsgc.h @@ -52,15 +52,15 @@ 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_SCRIPTED_FUNCTION 3 +#define JSTRACE_NAMESPACE 4 +#define JSTRACE_QNAME 5 +#define JSTRACE_XML 6 /* * One past the maximum trace kind. */ -#define JSTRACE_LIMIT 7 +#define JSTRACE_LIMIT 7 /* * We use the trace kinds as the types for all GC things except external @@ -69,7 +69,8 @@ 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_FUNCTION JSTRACE_SCRIPTED_FUNCTION + /* JSScriptedFunction */ #define GCX_NAMESPACE JSTRACE_NAMESPACE /* JSXMLNamespace */ #define GCX_QNAME JSTRACE_QNAME /* JSXMLQName */ #define GCX_XML JSTRACE_XML /* JSXML */ @@ -235,14 +236,15 @@ 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_SCRIPTED_FUNCTION) #endif /* - * JS_IS_VALID_TRACE_KIND assumes that JSTRACE_FUNCTION is the last non-xml - * trace kind when JS_HAS_XML_SUPPORT is false. + * JS_IS_VALID_TRACE_KIND assumes that JSTRACE_SCRIPTED_FUNCTION 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_SCRIPTED_FUNCTION + 1 == JSTRACE_NAMESPACE); /* * Trace jsval when JSVAL_IS_OBJECT(v) can be an arbitrary GC thing casted as diff --git a/mozilla/js/src/jsinterp.c b/mozilla/js/src/jsinterp.c index ea684580599..dd062e24dbb 100644 --- a/mozilla/js/src/jsinterp.c +++ b/mozilla/js/src/jsinterp.c @@ -645,7 +645,7 @@ js_GetScopeChain(JSContext *cx, JSStackFrame *fp) * insist that there is a call object for a heavyweight function call. */ JS_ASSERT(!fp->fun || - !(fp->fun->flags & JSFUN_HEAVYWEIGHT) || + !(FUN_FLAGS(fp->fun) & JSFUN_HEAVYWEIGHT) || fp->callobj); JS_ASSERT(fp->scopeChain); return fp->scopeChain; @@ -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; @@ -1088,20 +1088,27 @@ js_Invoke(JSContext *cx, uintN argc, jsval *vp, uintN flags) have_fun: /* Get private data and set derived locals from it. */ fun = GET_FUNCTION_PRIVATE(cx, funobj); - nslots = FUN_MINARGS(fun); - nslots = (nslots > argc) ? nslots - argc : 0; - if (FUN_INTERPRETED(fun)) { + if (FUN_IS_SCRIPTED(fun)) { + JSScriptedFunction *sfun; + + sfun = FUN_TO_SCRIPTED(fun); native = NULL; - script = fun->u.i.script; - nvars = fun->u.i.nvars; + script = sfun->script; + nvars = sfun->nvars; + nslots = (sfun->nargs > argc) ? sfun->nargs - argc : 0; } else { - native = fun->u.n.native; + JSNativeFunction *nfun; + + nfun = FUN_TO_NATIVE(fun); + native = nfun->native; script = NULL; nvars = 0; - nslots += fun->u.n.extra; + nslots = NATIVE_FUN_MINARGS(nfun); + nslots = (nslots > argc) ? nslots - argc : 0; + nslots += nfun->extra; } - if (JSFUN_BOUND_METHOD_TEST(fun->flags)) { + if (JSFUN_BOUND_METHOD_TEST(FUN_FLAGS(fun))) { /* Handle bound method special case. */ vp[1] = OBJECT_TO_JSVAL(parent); } else if (!JSVAL_IS_OBJECT(vp[1])) { @@ -1124,7 +1131,7 @@ have_fun: * JS_THIS or JS_THIS_OBJECT, and scripted functions will go through * the appropriate this-computing bytecode, e.g., JSOP_THIS. */ - if (native && (!fun || !(fun->flags & JSFUN_FAST_NATIVE))) { + if (native && (!fun || !(FUN_FLAGS(fun) & JSFUN_FAST_NATIVE))) { if (!js_ComputeThis(cx, JS_FALSE, vp + 2)) { ok = JS_FALSE; goto out2; @@ -1164,7 +1171,7 @@ have_fun: } while (--i != 0); } - if (native && fun && (fun->flags & JSFUN_FAST_NATIVE)) { + if (native && fun && (FUN_FLAGS(fun) & JSFUN_FAST_NATIVE)) { JSTempValueRooter tvr; #ifdef DEBUG_NOT_THROWING JSBool alreadyThrowing = cx->throwing; @@ -1286,7 +1293,7 @@ have_fun: } else if (script) { /* Use parent scope so js_GetCallObject can find the right "Call". */ frame.scopeChain = parent; - if (JSFUN_HEAVYWEIGHT_TEST(fun->flags)) { + if (JSFUN_HEAVYWEIGHT_TEST(FUN_FLAGS(fun))) { /* Scope with a call object parented by the callee's parent. */ if (!js_GetCallObject(cx, &frame, parent)) { ok = JS_FALSE; @@ -1401,7 +1408,7 @@ js_InternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, jsval fval, JS_ASSERT(mode == JSACC_READ || mode == JSACC_WRITE); if (cx->runtime->checkObjectAccess && VALUE_IS_FUNCTION(cx, fval) && - FUN_INTERPRETED(GET_FUNCTION_PRIVATE(cx, JSVAL_TO_OBJECT(fval))) && + FUN_IS_SCRIPTED(GET_FUNCTION_PRIVATE(cx, JSVAL_TO_OBJECT(fval))) && !cx->runtime->checkObjectAccess(cx, obj, ID_TO_VALUE(id), mode, &fval)) { return JS_FALSE; @@ -1835,11 +1842,16 @@ js_InvokeConstructor(JSContext *cx, jsval *vp, uintN argc) if (OBJ_GET_CLASS(cx, obj2) == &js_FunctionClass) { fun2 = GET_FUNCTION_PRIVATE(cx, obj2); - if (!FUN_INTERPRETED(fun2) && fun2->u.n.clasp) - clasp = fun2->u.n.clasp; + if (!FUN_IS_SCRIPTED(fun2)) { + JSNativeFunction *nfun; + + nfun = FUN_TO_NATIVE(fun2); + if (nfun->clasp) + clasp = nfun->clasp; + } } } - obj = js_NewObject(cx, clasp, proto, parent); + obj = js_NewObject(cx, clasp, proto, parent, 0); if (!obj) return JS_FALSE; @@ -2452,6 +2464,7 @@ js_Interpret(JSContext *cx) jsdouble d, d2; JSClass *clasp; JSFunction *fun; + JSScriptedFunction *sfun; JSType type; #if !JS_THREADED_INTERP && defined DEBUG FILE *tracefp = NULL; @@ -3114,13 +3127,13 @@ interrupt: switch (op) { case JSOP_FORARG: slot = GET_ARGNO(regs.pc); - JS_ASSERT(slot < fp->fun->nargs); + JS_ASSERT(slot < FUN_TO_SCRIPTED(fp->fun)->nargs); fp->argv[slot] = rval; break; case JSOP_FORVAR: slot = GET_VARNO(regs.pc); - JS_ASSERT(slot < fp->fun->u.i.nvars); + JS_ASSERT(slot < FUN_TO_SCRIPTED(fp->fun)->nvars); fp->vars[slot] = rval; break; @@ -3951,7 +3964,7 @@ interrupt: do_arg_incop: slot = GET_ARGNO(regs.pc); - JS_ASSERT(slot < fp->fun->nargs); + JS_ASSERT(slot < FUN_TO_SCRIPTED(fp->fun)->nargs); METER_SLOT_OP(op, slot); vp = fp->argv + slot; goto do_int_fast_incop; @@ -3987,7 +4000,7 @@ interrupt: */ do_var_incop: slot = GET_VARNO(regs.pc); - JS_ASSERT(slot < fp->fun->u.i.nvars); + JS_ASSERT(slot < FUN_TO_SCRIPTED(fp->fun)->nvars); METER_SLOT_OP(op, slot); vp = fp->vars + slot; @@ -4087,7 +4100,7 @@ interrupt: BEGIN_CASE(JSOP_GETARGPROP) i = ARGNO_LEN; slot = GET_ARGNO(regs.pc); - JS_ASSERT(slot < fp->fun->nargs); + JS_ASSERT(slot < FUN_TO_SCRIPTED(fp->fun)->nargs); PUSH_OPND(fp->argv[slot]); len = JSOP_GETARGPROP_LENGTH; goto do_getprop_body; @@ -4095,7 +4108,7 @@ interrupt: BEGIN_CASE(JSOP_GETVARPROP) i = VARNO_LEN; slot = GET_VARNO(regs.pc); - JS_ASSERT(slot < fp->fun->u.i.nvars); + JS_ASSERT(slot < FUN_TO_SCRIPTED(fp->fun)->nvars); PUSH_OPND(fp->vars[slot]); len = JSOP_GETVARPROP_LENGTH; goto do_getprop_body; @@ -4601,10 +4614,11 @@ interrupt: vp = regs.sp - (argc + 2); lval = *vp; if (VALUE_IS_FUNCTION(cx, lval)) { + JSNativeFunction *nfun; + obj = JSVAL_TO_OBJECT(lval); fun = GET_FUNCTION_PRIVATE(cx, obj); - - if (FUN_INTERPRETED(fun)) { + if (FUN_IS_SCRIPTED(fun)) { uintN nframeslots, nvars, missing; JSArena *a; jsuword nbytes; @@ -4616,8 +4630,9 @@ interrupt: /* Compute the total number of stack slots needed by fun. */ nframeslots = JS_HOWMANY(sizeof(JSInlineFrame), sizeof(jsval)); - nvars = fun->u.i.nvars; - script = fun->u.i.script; + sfun = FUN_TO_SCRIPTED(fun); + nvars = sfun->nvars; + script = sfun->script; atoms = script->atomMap.vector; nbytes = (nframeslots + nvars + script->depth) * sizeof(jsval); @@ -4625,10 +4640,10 @@ interrupt: /* Allocate missing expected args adjacent to actuals. */ a = cx->stackPool.current; newmark = (void *) a->avail; - if (fun->nargs <= argc) { + if (sfun->nargs <= argc) { missing = 0; } else { - newsp = vp + 2 + fun->nargs; + newsp = vp + 2 + sfun->nargs; JS_ASSERT(newsp > regs.sp); if ((jsuword) newsp <= a->limit) { if ((jsuword) newsp > a->avail) @@ -4638,8 +4653,8 @@ interrupt: } while (newsp != regs.sp); missing = 0; } else { - missing = fun->nargs - argc; - nbytes += (2 + fun->nargs) * sizeof(jsval); + missing = sfun->nargs - argc; + nbytes += (2 + sfun->nargs) * sizeof(jsval); } } @@ -4700,7 +4715,7 @@ interrupt: newifp->mark = newmark; /* Compute the 'this' parameter now that argv is set. */ - JS_ASSERT(!JSFUN_BOUND_METHOD_TEST(fun->flags)); + JS_ASSERT(!JSFUN_BOUND_METHOD_TEST(sfun->flags)); JS_ASSERT(JSVAL_IS_OBJECT(vp[1])); newifp->frame.thisp = (JSObject *)vp[1]; @@ -4722,7 +4737,7 @@ interrupt: } /* Scope with a call object parented by callee's parent. */ - if (JSFUN_HEAVYWEIGHT_TEST(fun->flags) && + if (JSFUN_HEAVYWEIGHT_TEST(sfun->flags) && !js_GetCallObject(cx, &newifp->frame, parent)) { goto bad_inline_call; } @@ -4780,16 +4795,17 @@ interrupt: } #endif - if (fun->flags & JSFUN_FAST_NATIVE) { - JS_ASSERT(fun->u.n.extra == 0); - if (argc < fun->u.n.minargs) { - uintN nargs; + nfun = FUN_TO_NATIVE(fun); + if (nfun->flags & JSFUN_FAST_NATIVE) { + uintN nargs; + JS_ASSERT(nfun->extra == 0); + if (argc < nfun->minargs) { /* * If we can't fit missing args and local roots in * this frame's operand stack, take the slow path. */ - nargs = fun->u.n.minargs - argc; + nargs = nfun->minargs - argc; if (regs.sp + nargs > fp->spbase + script->depth) goto do_invoke; do { @@ -4800,7 +4816,7 @@ interrupt: JS_ASSERT(JSVAL_IS_OBJECT(vp[1]) || PRIMITIVE_THIS_TEST(fun, vp[1])); - ok = ((JSFastNative) fun->u.n.native)(cx, argc, vp); + ok = ((JSFastNative) nfun->native)(cx, argc, vp); #ifdef INCLUDE_MOZILLA_DTRACE if (VALUE_IS_FUNCTION(cx, lval)) { if (JAVASCRIPT_FUNCTION_RVAL_ENABLED()) @@ -5394,7 +5410,7 @@ interrupt: BEGIN_CASE(JSOP_GETARG) BEGIN_CASE(JSOP_CALLARG) slot = GET_ARGNO(regs.pc); - JS_ASSERT(slot < fp->fun->nargs); + JS_ASSERT(slot < FUN_TO_SCRIPTED(fp->fun)->nargs); METER_SLOT_OP(op, slot); PUSH_OPND(fp->argv[slot]); if (op == JSOP_CALLARG) @@ -5403,7 +5419,7 @@ interrupt: BEGIN_CASE(JSOP_SETARG) slot = GET_ARGNO(regs.pc); - JS_ASSERT(slot < fp->fun->nargs); + JS_ASSERT(slot < FUN_TO_SCRIPTED(fp->fun)->nargs); METER_SLOT_OP(op, slot); vp = &fp->argv[slot]; GC_POKE(cx, *vp); @@ -5413,7 +5429,7 @@ interrupt: BEGIN_CASE(JSOP_GETVAR) BEGIN_CASE(JSOP_CALLVAR) slot = GET_VARNO(regs.pc); - JS_ASSERT(slot < fp->fun->u.i.nvars); + JS_ASSERT(slot < FUN_TO_SCRIPTED(fp->fun)->nvars); METER_SLOT_OP(op, slot); PUSH_OPND(fp->vars[slot]); if (op == JSOP_CALLVAR) @@ -5422,7 +5438,7 @@ interrupt: BEGIN_CASE(JSOP_SETVAR) slot = GET_VARNO(regs.pc); - JS_ASSERT(slot < fp->fun->u.i.nvars); + JS_ASSERT(slot < FUN_TO_SCRIPTED(fp->fun)->nvars); METER_SLOT_OP(op, slot); vp = &fp->vars[slot]; GC_POKE(cx, *vp); @@ -5601,8 +5617,8 @@ 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); + sfun = FUN_TO_SCRIPTED(GET_FUNCTION_PRIVATE(cx, obj)); + flags = JSFUN_GSFLAG2ATTR(sfun->flags); if (flags) { attrs |= flags | JSPROP_SHARED; rval = JSVAL_VOID; @@ -5622,7 +5638,7 @@ interrupt: * here at runtime as well as at compile-time, to handle eval * as well as multiple HTML script tags. */ - id = ATOM_TO_JSID(fun->atom); + id = ATOM_TO_JSID(sfun->atom); ok = js_CheckRedeclaration(cx, parent, id, attrs, NULL, NULL); if (ok) { if (attrs == JSPROP_ENUMERATE) { @@ -5705,7 +5721,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; @@ -5738,16 +5754,17 @@ interrupt: /* * 4. Create a property in the object Result(1). The property's - * name is [fun->atom, the identifier parsed by the compiler], + * name is [sfun->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); + sfun = FUN_TO_SCRIPTED(GET_FUNCTION_PRIVATE(cx, obj)); + attrs = JSFUN_GSFLAG2ATTR(sfun->flags); if (attrs) { attrs |= JSPROP_SHARED; rval = JSVAL_VOID; } - ok = OBJ_DEFINE_PROPERTY(cx, parent, ATOM_TO_JSID(fun->atom), rval, + ok = OBJ_DEFINE_PROPERTY(cx, parent, ATOM_TO_JSID(sfun->atom), + rval, (attrs & JSPROP_GETTER) ? JS_EXTENSION (JSPropertyOp) obj : JS_PropertyStub, @@ -5908,7 +5925,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)); diff --git a/mozilla/js/src/jsinterp.h b/mozilla/js/src/jsinterp.h index 1a8cc02e57c..962d58001a8 100644 --- a/mozilla/js/src/jsinterp.h +++ b/mozilla/js/src/jsinterp.h @@ -397,7 +397,7 @@ extern const uint16 js_PrimitiveTestFlags[]; #define PRIMITIVE_THIS_TEST(fun,thisv) \ (JS_ASSERT(thisv != JSVAL_VOID), \ - JSFUN_THISP_TEST(JSFUN_THISP_FLAGS((fun)->flags), \ + JSFUN_THISP_TEST(JSFUN_THISP_FLAGS(FUN_FLAGS(fun)), \ js_PrimitiveTestFlags[JSVAL_TAG(thisv) - 1])) /* diff --git a/mozilla/js/src/jsiter.c b/mozilla/js/src/jsiter.c index 8511e5d8d37..3e058fe27e9 100644 --- a/mozilla/js/src/jsiter.c +++ b/mozilla/js/src/jsiter.c @@ -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,13 +725,13 @@ 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; /* Load and compute stack slot counts. */ argc = fp->argc; - nargs = JS_MAX(argc, fp->fun->nargs); + nargs = JS_MAX(argc, FUN_TO_SCRIPTED(fp->fun)->nargs); nvars = fp->nvars; nslots = 2 + nargs + nvars + fp->script->depth; diff --git a/mozilla/js/src/jsobj.c b/mozilla/js/src/jsobj.c index b14864db2f0..d4482d06fdd 100644 --- a/mozilla/js/src/jsobj.c +++ b/mozilla/js/src/jsobj.c @@ -863,8 +863,9 @@ obj_toSource(JSContext *cx, uintN argc, jsval *vp) * they might appear here. This code can be confused by people * defining Function.prototype.toString, so let's be cautious. */ - if (JSFUN_GETTER_TEST(fun->flags) || - JSFUN_SETTER_TEST(fun->flags)) { /* skip "getter/setter" */ + if (JSFUN_GETTER_TEST(FUN_FLAGS(fun)) || + JSFUN_SETTER_TEST(FUN_FLAGS(fun))) { + /* skip "getter/setter" */ const jschar *tmp = js_strchr_limit(vchars, ' ', end); if (tmp) vchars = tmp + 1; @@ -1754,7 +1755,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; } @@ -1895,7 +1896,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)); @@ -1914,7 +1915,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); @@ -1932,7 +1933,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)); @@ -2418,7 +2419,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 extraBytes) { jsid id; @@ -2435,12 +2437,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, extraBytes); } JSObject * js_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto, - JSObject *parent) + JSObject *parent, uintN extraBytes) { JSObject *obj; JSObjectOps *ops; @@ -2464,7 +2466,8 @@ js_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto, * GC-thing allocations under js_GetClassPrototype or clasp->getObjectOps, * to avoid displacing the newborn root for obj. */ - obj = (JSObject *) js_NewGCThing(cx, GCX_OBJECT, sizeof(JSObject)); + obj = (JSObject *) js_NewGCThing(cx, GCX_OBJECT, + sizeof(JSObject) + extraBytes); if (!obj) goto earlybad; @@ -2766,7 +2769,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; @@ -4651,7 +4654,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); diff --git a/mozilla/js/src/jsobj.h b/mozilla/js/src/jsobj.h index c9d41131960..3941de994e5 100644 --- a/mozilla/js/src/jsobj.h +++ b/mozilla/js/src/jsobj.h @@ -432,14 +432,15 @@ 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 extraBytes); /* * See jsapi.h, JS_NewObjectWithGivenProto. */ extern JSObject * js_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto, - JSObject *parent); + JSObject *parent, uintN extraBytes); /* * Fast access to immutable standard objects (constructors and prototypes). diff --git a/mozilla/js/src/jsopcode.c b/mozilla/js/src/jsopcode.c index d791927bad6..c3f466991e7 100644 --- a/mozilla/js/src/jsopcode.c +++ b/mozilla/js/src/jsopcode.c @@ -617,7 +617,7 @@ struct JSPrinter { JSScript *script; /* script being printed */ jsbytecode *dvgfence; /* DecompileExpression fencepost */ jsbytecode **pcstack; /* DecompileExpression modelled stack */ - JSFunction *fun; /* interpreted function */ + JSScriptedFunction *fun; /* interpreted function */ jsuword *localNames; /* argument and variable names */ }; @@ -630,8 +630,7 @@ struct JSPrinter { #define JS_IN_GROUP_CONTEXT 0x10000 JSPrinter * -JS_NEW_PRINTER(JSContext *cx, const char *name, JSFunction *fun, - uintN indent, JSBool pretty) +JS_NEW_PRINTER(JSContext *cx, const char *name, uintN indent, JSBool pretty) { JSPrinter *jp; @@ -646,15 +645,8 @@ JS_NEW_PRINTER(JSContext *cx, const char *name, JSFunction *fun, jp->script = NULL; jp->dvgfence = NULL; jp->pcstack = NULL; - jp->fun = fun; jp->localNames = NULL; - if (fun && FUN_INTERPRETED(fun) && JS_GET_LOCAL_NAME_COUNT(fun)) { - jp->localNames = js_GetLocalNameArray(cx, fun, &jp->pool); - if (!jp->localNames) { - js_DestroyPrinter(jp); - return NULL; - } - } + jp->fun = NULL; return jp; } @@ -665,6 +657,21 @@ js_DestroyPrinter(JSPrinter *jp) JS_free(jp->sprinter.context, jp); } +static JSBool +InitFunctionPrinter(JSPrinter *jp, JSScriptedFunction *fun) +{ + JS_ASSERT(!jp->fun); + JS_ASSERT(!jp->localNames); + if (JS_GET_LOCAL_NAME_COUNT(fun) != 0) { + jp->localNames = js_GetLocalNameArray(jp->sprinter.context, fun, + &jp->pool); + if (!jp->localNames) + return JS_FALSE; + } + jp->fun = fun; + return JS_TRUE; +} + JSString * js_GetPrinterOutput(JSPrinter *jp) { @@ -789,7 +796,7 @@ ReconstructPCStack(JSContext *cx, JSScript *script, jsbytecode *pc, * decompiled string on success. */ static char * -DecompileExpression(JSContext *cx, JSScript *script, JSFunction *fun, +DecompileExpression(JSContext *cx, JSScript *script, JSScriptedFunction *fun, jsbytecode *pc); /* @@ -1129,17 +1136,15 @@ DecompileSwitch(SprintStack *ss, TableEntry *table, uintN tableLength, static JSAtom * GetSlotAtom(JSPrinter *jp, JSBool argument, uintN slot) { - JSFunction *fun; JSAtom *name; - fun = jp->fun; LOCAL_ASSERT_RV(jp->fun, NULL); LOCAL_ASSERT_RV(jp->localNames, NULL); if (argument) { - LOCAL_ASSERT_RV(slot < fun->nargs, NULL); + LOCAL_ASSERT_RV(slot < jp->fun->nargs, NULL); } else { - LOCAL_ASSERT_RV(slot < fun->u.i.nvars, NULL); - slot += fun->nargs; + LOCAL_ASSERT_RV(slot < jp->fun->nvars, NULL); + slot += jp->fun->nargs; } name = JS_LOCAL_NAME_TO_ATOM(jp->localNames[slot]); #if !JS_HAS_DESTRUCTURING @@ -1631,7 +1636,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop) char **argv; JSAtom *atom; JSObject *obj; - JSFunction *fun; + JSScriptedFunction *fun; JSString *str; JSBool ok; #if JS_HAS_XML_SUPPORT @@ -2020,12 +2025,12 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop) obj); do_function: js_puts(jp, "\n"); - fun = GET_FUNCTION_PRIVATE(cx, obj); - jp2 = JS_NEW_PRINTER(cx, "nested_function", fun, + jp2 = JS_NEW_PRINTER(cx, "nested_function", jp->indent, jp->pretty); if (!jp2) return NULL; - ok = js_DecompileFunction(jp2); + fun = FUN_TO_SCRIPTED(GET_FUNCTION_PRIVATE(cx, obj)); + ok = js_DecompileFunction(jp2, fun); if (ok && jp2->sprinter.base) js_puts(jp, jp2->sprinter.base); js_DestroyPrinter(jp2); @@ -3767,9 +3772,8 @@ 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; + fun = FUN_TO_SCRIPTED(GET_FUNCTION_PRIVATE(cx, obj)); + inner = fun->script; /* * All allocation when decompiling is LIFO, using malloc @@ -3884,10 +3888,11 @@ 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); + fun = FUN_TO_SCRIPTED(GET_FUNCTION_PRIVATE(cx, obj)); if (!(fun->flags & JSFUN_EXPR_CLOSURE)) indent |= JS_IN_GROUP_CONTEXT; - str = JS_DecompileFunction(cx, fun, indent); + str = JS_DecompileFunction(cx, SCRIPTED_TO_FUN(fun), + indent); if (!str) return NULL; } @@ -4615,55 +4620,83 @@ out: return ok; } +static const char native_code_str[] = "\t[native code]\n"; + +JSBool +js_DecompileNativeFunction(JSPrinter *jp, JSNativeFunction *fun) +{ + if (jp->pretty) + js_printf(jp, "\t"); + if (JSFUN_GETTER_TEST(fun->flags)) + js_printf(jp, "%s ", js_getter_str); + else if (JSFUN_SETTER_TEST(fun->flags)) + js_printf(jp, "%s ", js_setter_str); + + js_printf(jp, "%s ", js_function_str); + if (fun->atom && !QuoteString(&jp->sprinter, ATOM_TO_STRING(fun->atom), 0)) + return JS_FALSE; + js_printf(jp, "() {\n"); + jp->indent += 4; + js_printf(jp, native_code_str); + jp->indent -= 4; + js_printf(jp, "\t}"); + + return JS_TRUE; +} + +JSBool +js_DecompileNativeFunctionBody(JSPrinter *jp, JSNativeFunction *fun) +{ + js_printf(jp, native_code_str); + return JS_TRUE; +} + JSBool js_DecompileScript(JSPrinter *jp, JSScript *script) { return DecompileCode(jp, script, script->code, (uintN)script->length, 0); } -static const char native_code_str[] = "\t[native code]\n"; - JSBool -js_DecompileFunctionBody(JSPrinter *jp) +js_DecompileFunctionBody(JSPrinter *jp, JSScriptedFunction *fun) { JSScript *script; - JS_ASSERT(jp->fun); JS_ASSERT(!jp->script); - if (!FUN_INTERPRETED(jp->fun)) { - js_printf(jp, native_code_str); - return JS_TRUE; - } - - script = jp->fun->u.i.script; + JS_ASSERT(!jp->fun); + if (!InitFunctionPrinter(jp, fun)) + return JS_FALSE; + script = fun->script; return DecompileCode(jp, script, script->code, (uintN)script->length, 0); } JSBool -js_DecompileFunction(JSPrinter *jp) +js_DecompileFunction(JSPrinter *jp, JSScriptedFunction *fun) { - JSFunction *fun; uintN i; JSAtom *param; jsbytecode *pc, *endpc; ptrdiff_t len; JSBool ok; +#ifdef JS_HAS_DESTRUCTURING + SprintStack ss; + void *mark; +#endif - fun = jp->fun; - JS_ASSERT(fun); JS_ASSERT(!jp->script); + if (!InitFunctionPrinter(jp, fun)) + return JS_FALSE; /* * If pretty, conform to ECMA-262 Edition 3, 15.3.4.2, by decompiling a * FunctionDeclaration. Otherwise, check the JSFUN_LAMBDA flag and force * an expression by parenthesizing. */ - if (jp->pretty) { + if (jp->pretty) js_printf(jp, "\t"); - } else { - if (!jp->grouped && (fun->flags & JSFUN_LAMBDA)) - js_puts(jp, "("); - } + else if (!jp->grouped && (fun->flags & JSFUN_LAMBDA)) + js_puts(jp, "("); + if (JSFUN_GETTER_TEST(fun->flags)) js_printf(jp, "%s ", js_getter_str); else if (JSFUN_SETTER_TEST(fun->flags)) @@ -4674,102 +4707,89 @@ js_DecompileFunction(JSPrinter *jp) return JS_FALSE; js_puts(jp, "("); - if (!FUN_INTERPRETED(fun)) { - js_printf(jp, ") {\n"); - jp->indent += 4; - js_printf(jp, native_code_str); - jp->indent -= 4; - js_printf(jp, "\t}"); - } else { -#ifdef JS_HAS_DESTRUCTURING - SprintStack ss; - void *mark; -#endif - - /* Print the parameters. */ - pc = fun->u.i.script->main; - endpc = pc + fun->u.i.script->length; - ok = JS_TRUE; + /* Print the parameters. */ + pc = fun->script->main; + endpc = pc + fun->script->length; + ok = JS_TRUE; #ifdef JS_HAS_DESTRUCTURING - /* Skip JSOP_GENERATOR in case of destructuring parameters. */ - if (*pc == JSOP_GENERATOR) - pc += JSOP_GENERATOR_LENGTH; + /* Skip JSOP_GENERATOR in case of destructuring parameters. */ + if (*pc == JSOP_GENERATOR) + pc += JSOP_GENERATOR_LENGTH; - ss.printer = NULL; - jp->script = fun->u.i.script; - mark = JS_ARENA_MARK(&jp->sprinter.context->tempPool); + ss.printer = NULL; + jp->script = fun->script; + mark = JS_ARENA_MARK(&jp->sprinter.context->tempPool); #endif - for (i = 0; i < fun->nargs; i++) { - if (i > 0) - js_puts(jp, ", "); + for (i = 0; i < fun->nargs; i++) { + if (i > 0) + js_puts(jp, ", "); - param = GetSlotAtom(jp, JS_TRUE, i); + param = GetSlotAtom(jp, JS_TRUE, i); #if JS_HAS_DESTRUCTURING #define LOCAL_ASSERT(expr) LOCAL_ASSERT_RV(expr, JS_FALSE) - if (!param) { - ptrdiff_t todo; - const char *lval; + if (!param) { + ptrdiff_t todo; + const char *lval; - LOCAL_ASSERT(*pc == JSOP_GETARG); - pc += JSOP_GETARG_LENGTH; - LOCAL_ASSERT(*pc == JSOP_DUP); - if (!ss.printer) { - ok = InitSprintStack(jp->sprinter.context, &ss, jp, - fun->u.i.script->depth); - if (!ok) - break; - } - pc = DecompileDestructuring(&ss, pc, endpc); - if (!pc) { - ok = JS_FALSE; + LOCAL_ASSERT(*pc == JSOP_GETARG); + pc += JSOP_GETARG_LENGTH; + LOCAL_ASSERT(*pc == JSOP_DUP); + if (!ss.printer) { + ok = InitSprintStack(jp->sprinter.context, &ss, jp, + fun->script->depth); + if (!ok) break; - } - LOCAL_ASSERT(*pc == JSOP_POP); - pc += JSOP_POP_LENGTH; - lval = PopStr(&ss, JSOP_NOP); - todo = SprintCString(&jp->sprinter, lval); - if (todo < 0) { - ok = JS_FALSE; - break; - } - continue; } + pc = DecompileDestructuring(&ss, pc, endpc); + if (!pc) { + ok = JS_FALSE; + break; + } + LOCAL_ASSERT(*pc == JSOP_POP); + pc += JSOP_POP_LENGTH; + lval = PopStr(&ss, JSOP_NOP); + todo = SprintCString(&jp->sprinter, lval); + if (todo < 0) { + ok = JS_FALSE; + break; + } + continue; + } #undef LOCAL_ASSERT #endif - if (!QuoteString(&jp->sprinter, ATOM_TO_STRING(param), 0)) { - ok = JS_FALSE; - break; - } + if (!QuoteString(&jp->sprinter, ATOM_TO_STRING(param), 0)) { + ok = JS_FALSE; + break; } + } #ifdef JS_HAS_DESTRUCTURING - jp->script = NULL; - JS_ARENA_RELEASE(&jp->sprinter.context->tempPool, mark); + jp->script = NULL; + JS_ARENA_RELEASE(&jp->sprinter.context->tempPool, mark); #endif - if (!ok) - return JS_FALSE; - if (fun->flags & JSFUN_EXPR_CLOSURE) { - js_printf(jp, ") "); - } else { - js_printf(jp, ") {\n"); - jp->indent += 4; - } + if (!ok) + return JS_FALSE; + if (fun->flags & JSFUN_EXPR_CLOSURE) { + js_printf(jp, ") "); + } else { + js_printf(jp, ") {\n"); + jp->indent += 4; + } - len = fun->u.i.script->code + fun->u.i.script->length - pc; - ok = DecompileCode(jp, fun->u.i.script, pc, (uintN)len, 0); - if (!ok) - return JS_FALSE; + len = fun->script->code + fun->script->length - pc; + ok = DecompileCode(jp, fun->script, pc, (uintN)len, 0); + if (!ok) + return JS_FALSE; - if (!(fun->flags & JSFUN_EXPR_CLOSURE)) { - jp->indent -= 4; - js_printf(jp, "\t}"); - } + if (!(fun->flags & JSFUN_EXPR_CLOSURE)) { + jp->indent -= 4; + js_printf(jp, "\t}"); } if (!jp->pretty && !jp->grouped && (fun->flags & JSFUN_LAMBDA)) @@ -4861,7 +4881,9 @@ js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v, goto do_fallback; } - name = DecompileExpression(cx, script, fp->fun, pc); + name = DecompileExpression(cx, script, + fp->fun ? FUN_TO_SCRIPTED(fp->fun) : NULL, + pc); if (name != FAILED_EXPRESSION_DECOMPILER) return name; @@ -4876,7 +4898,7 @@ js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v, } static char * -DecompileExpression(JSContext *cx, JSScript *script, JSFunction *fun, +DecompileExpression(JSContext *cx, JSScript *script, JSScriptedFunction *fun, jsbytecode *pc) { JSOp op; @@ -4957,13 +4979,16 @@ DecompileExpression(JSContext *cx, JSScript *script, JSFunction *fun, } name = NULL; - jp = JS_NEW_PRINTER(cx, "js_DecompileValueGenerator", fun, 0, JS_FALSE); + jp = JS_NEW_PRINTER(cx, "js_DecompileValueGenerator", 0, JS_FALSE); if (jp) { - jp->dvgfence = end; - jp->pcstack = pcstack; - if (DecompileCode(jp, script, begin, (uintN) len, (uintN) pcdepth)) { - name = (jp->sprinter.base) ? jp->sprinter.base : (char *) ""; - name = JS_strdup(cx, name); + if (!fun || InitFunctionPrinter(jp, fun)) { + jp->dvgfence = end; + jp->pcstack = pcstack; + if (DecompileCode(jp, script, begin, (uintN) len, + (uintN) pcdepth)) { + name = (jp->sprinter.base) ? jp->sprinter.base : (char *) ""; + name = JS_strdup(cx, name); + } } js_DestroyPrinter(jp); } diff --git a/mozilla/js/src/jsopcode.h b/mozilla/js/src/jsopcode.h index 8cbbb9cccaf..4cb5a3fe6f5 100644 --- a/mozilla/js/src/jsopcode.h +++ b/mozilla/js/src/jsopcode.h @@ -282,16 +282,15 @@ js_QuoteString(JSContext *cx, JSString *str, jschar quote); */ #ifdef JS_ARENAMETER -# define JS_NEW_PRINTER(cx, name, fun, indent, pretty) \ - js_NewPrinter(cx, name, fun, indent, pretty) +# define JS_NEW_PRINTER(cx, name, indent, pretty) \ + js_NewPrinter(cx, name, indent, pretty) #else -# define JS_NEW_PRINTER(cx, name, fun, indent, pretty) \ - js_NewPrinter(cx, fun, indent, pretty) +# define JS_NEW_PRINTER(cx, name, indent, pretty) \ + js_NewPrinter(cx, indent, pretty) #endif extern JSPrinter * -JS_NEW_PRINTER(JSContext *cx, const char *name, JSFunction *fun, - uintN indent, JSBool pretty); +JS_NEW_PRINTER(JSContext *cx, const char *name, uintN indent, JSBool pretty); extern void js_DestroyPrinter(JSPrinter *jp); @@ -361,14 +360,20 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc, /* * Decompilers, for script, function, and expression pretty-printing. */ +extern JSBool +js_DecompileNativeFunctionBody(JSPrinter *jp, JSNativeFunction *fun); + +JSBool +js_DecompileNativeFunction(JSPrinter *jp, JSNativeFunction *fun); + extern JSBool js_DecompileScript(JSPrinter *jp, JSScript *script); extern JSBool -js_DecompileFunctionBody(JSPrinter *jp); +js_DecompileFunctionBody(JSPrinter *jp, JSScriptedFunction *fun); extern JSBool -js_DecompileFunction(JSPrinter *jp); +js_DecompileFunction(JSPrinter *jp, JSScriptedFunction *fun); /* * Find the source expression that resulted in v, and return a newly allocated diff --git a/mozilla/js/src/jsparse.c b/mozilla/js/src/jsparse.c index da360852385..ca68cd43774 100644 --- a/mozilla/js/src/jsparse.c +++ b/mozilla/js/src/jsparse.c @@ -891,7 +891,8 @@ FunctionBody(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) * handler attribute in an HTML tag. */ JSBool -js_CompileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipals *principals, +js_CompileFunctionBody(JSContext *cx, JSScriptedFunction *fun, + JSPrincipals *principals, const jschar *chars, size_t length, const char *filename, uintN lineno) { @@ -997,7 +998,7 @@ BindArg(JSContext *cx, JSAtom *atom, JSTreeContext *tc) } static JSBool -BindLocalVariable(JSContext *cx, JSFunction *fun, JSAtom *atom, +BindLocalVariable(JSContext *cx, JSScriptedFunction *fun, JSAtom *atom, JSLocalKind localKind) { JS_ASSERT(localKind == JSLOCAL_VAR || localKind == JSLOCAL_CONST); @@ -1055,17 +1056,16 @@ BindDestructuringArg(JSContext *cx, BindData *data, JSAtom *atom, } #endif /* JS_HAS_DESTRUCTURING */ -static JSFunction * +static JSScriptedFunction * NewCompilerFunction(JSContext *cx, JSTreeContext *tc, JSAtom *atom, uintN lambda) { JSObject *parent; - JSFunction *fun; + JSScriptedFunction *fun; JS_ASSERT((lambda & ~JSFUN_LAMBDA) == 0); parent = (tc->flags & TCF_IN_FUNCTION) ? tc->fun->object : cx->fp->varobj; - fun = js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED | lambda, - parent, atom); + fun = js_NewScriptedFunction(cx, NULL, lambda, parent, atom); if (fun && !(tc->flags & TCF_COMPILE_N_GO)) { STOBJ_SET_PARENT(fun->object, NULL); STOBJ_SET_PROTO(fun->object, NULL); @@ -1083,7 +1083,7 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, JSAtom *funAtom; JSParsedObjectBox *funpob; JSAtomListElement *ale; - JSFunction *fun; + JSScriptedFunction *fun; JSTreeContext funtc; #if JS_HAS_DESTRUCTURING JSParseNode *item, *list = NULL; @@ -4253,7 +4253,7 @@ GeneratorExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, uintN oldflags, JSParseNode *pn, JSParseNode *kid) { JSParseNode *body, *lambda; - JSFunction *fun; + JSScriptedFunction *fun; /* Initialize pn, connecting it to kid. */ JS_ASSERT(pn->pn_arity == PN_UNARY); diff --git a/mozilla/js/src/jsparse.h b/mozilla/js/src/jsparse.h index 9b40abefa42..22ce4df5bf8 100644 --- a/mozilla/js/src/jsparse.h +++ b/mozilla/js/src/jsparse.h @@ -464,7 +464,8 @@ js_CompileScript(JSContext *cx, JSObject *obj, JSPrincipals *principals, FILE *file, const char *filename, uintN lineno); extern JSBool -js_CompileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipals *principals, +js_CompileFunctionBody(JSContext *cx, JSScriptedFunction *fun, + JSPrincipals *principals, const jschar *chars, size_t length, const char *filename, uintN lineno); diff --git a/mozilla/js/src/jsprvtd.h b/mozilla/js/src/jsprvtd.h index ab988e83709..f7cefb5afa4 100644 --- a/mozilla/js/src/jsprvtd.h +++ b/mozilla/js/src/jsprvtd.h @@ -92,10 +92,12 @@ typedef struct JSArgumentFormatMap JSArgumentFormatMap; typedef struct JSCodeGenerator JSCodeGenerator; typedef struct JSGCThing JSGCThing; typedef struct JSGenerator JSGenerator; +typedef struct JSNativeFunction JSNativeFunction; typedef struct JSParseContext JSParseContext; typedef struct JSParsedObjectBox JSParsedObjectBox; typedef struct JSParseNode JSParseNode; typedef struct JSPropCacheEntry JSPropCacheEntry; +typedef struct JSScriptedFunction JSScriptedFunction; typedef struct JSSharpObjectMap JSSharpObjectMap; typedef struct JSTempValueRooter JSTempValueRooter; typedef struct JSThread JSThread; @@ -237,7 +239,7 @@ typedef union JSTempValueUnion { jsval value; JSObject *object; JSString *string; - JSFunction *function; + JSScriptedFunction *function; JSXML *xml; JSXMLQName *qname; JSTempValueTrace trace; diff --git a/mozilla/js/src/jsregexp.c b/mozilla/js/src/jsregexp.c index 0e214a6aa7f..64754feefd4 100644 --- a/mozilla/js/src/jsregexp.c +++ b/mozilla/js/src/jsregexp.c @@ -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); diff --git a/mozilla/js/src/jsscript.c b/mozilla/js/src/jsscript.c index 2f18de8ad92..7c2cdba7004 100644 --- a/mozilla/js/src/jsscript.c +++ b/mozilla/js/src/jsscript.c @@ -880,7 +880,7 @@ Script(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { /* If not constructing, replace obj with a new Script object. */ if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) { - obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL); + obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL, 0); if (!obj) return JS_FALSE; @@ -904,7 +904,7 @@ script_static_thaw(JSContext *cx, uintN argc, jsval *vp) { JSObject *obj; - obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL); + obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL, 0); if (!obj) return JS_FALSE; vp[1] = OBJECT_TO_JSVAL(obj); @@ -1407,7 +1407,7 @@ js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg) uint32 mainLength, prologLength, nsrcnotes; JSScript *script; const char *filename; - JSFunction *fun; + JSScriptedFunction *fun; /* The counts of indexed things must be checked during code generation. */ JS_ASSERT(cg->atomList.count <= INDEX_LIMIT); @@ -1452,16 +1452,13 @@ js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg) if (cg->regexpList.length != 0) FinishParsedObjects(&cg->regexpList, JS_SCRIPT_REGEXPS(script)); - /* - * We initialize fun->u.script to be the script constructed above - * so that the debugger has a valid FUN_SCRIPT(fun). - */ + /* Initialize fun->script early for the debugger. */ fun = NULL; if (cg->treeContext.flags & TCF_IN_FUNCTION) { fun = cg->treeContext.fun; - JS_ASSERT(FUN_INTERPRETED(fun) && !FUN_SCRIPT(fun)); + JS_ASSERT(!fun->script); js_FreezeLocalNames(cx, fun); - fun->u.i.script = script; + fun->script = script; #ifdef CHECK_SCRIPT_OWNER script->owner = NULL; #endif @@ -1485,21 +1482,22 @@ bad: return NULL; } -JS_FRIEND_API(void) -js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun) +void +js_CallNewScriptHook(JSContext *cx, JSScript *script, JSScriptedFunction *fun) { JSNewScriptHook hook; hook = cx->debugHooks->newScriptHook; if (hook) { JS_KEEP_ATOMS(cx->runtime); - hook(cx, script->filename, script->lineno, script, fun, + hook(cx, script->filename, script->lineno, script, + fun ? SCRIPTED_TO_FUN(fun) : NULL, cx->debugHooks->newScriptHookData); JS_UNKEEP_ATOMS(cx->runtime); } } -JS_FRIEND_API(void) +void js_CallDestroyScriptHook(JSContext *cx, JSScript *script) { JSDestroyScriptHook hook; @@ -1679,7 +1677,7 @@ uintN js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc) { JSObject *obj; - JSFunction *fun; + JSScriptedFunction *fun; uintN lineno; ptrdiff_t offset, target; jssrcnote *sn; @@ -1697,9 +1695,8 @@ js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc) 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)); - return fun->u.i.script->lineno; + fun = FUN_TO_SCRIPTED(GET_FUNCTION_PRIVATE(cx, obj)); + return fun->script->lineno; } /* diff --git a/mozilla/js/src/jsscript.h b/mozilla/js/src/jsscript.h index 8b7d9f004fd..d9363b53477 100644 --- a/mozilla/js/src/jsscript.h +++ b/mozilla/js/src/jsscript.h @@ -227,10 +227,10 @@ js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg); * of js_XDRScript, the hook should be invoked only after successful decode * of any owning function (the fun parameter) or script object (null fun). */ -extern JS_FRIEND_API(void) -js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun); +extern void +js_CallNewScriptHook(JSContext *cx, JSScript *script, JSScriptedFunction *fun); -extern JS_FRIEND_API(void) +extern void js_CallDestroyScriptHook(JSContext *cx, JSScript *script); extern void diff --git a/mozilla/js/src/jsxml.c b/mozilla/js/src/jsxml.c index 9749d57153d..38e7914eb98 100644 --- a/mozilla/js/src/jsxml.c +++ b/mozilla/js/src/jsxml.c @@ -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); @@ -830,6 +830,7 @@ QName(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { jsval nameval, nsval; JSBool isQName, isNamespace; + JSFunction *fun; JSXMLQName *qn; JSString *uri, *prefix, *name; JSObject *nsobj; @@ -854,9 +855,8 @@ QName(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) * Use the constructor's clasp so we can be shared by AttributeName * (see below after this function). */ - obj = js_NewObject(cx, - JS_ValueToFunction(cx, argv[-2])->u.n.clasp, - NULL, NULL); + fun = JS_ValueToFunction(cx, argv[-2]); + obj = js_NewObject(cx, FUN_TO_NATIVE(fun)->clasp, 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_TO_NATIVE(fun)->object, proto, JSPROP_READONLY | JSPROP_PERMANENT)) { return NULL; } @@ -7877,7 +7877,7 @@ js_SetDefaultXMLNamespace(JSContext *cx, jsval v) return JS_FALSE; } } else { - JS_ASSERT(fp->fun && !JSFUN_HEAVYWEIGHT_TEST(fp->fun->flags)); + JS_ASSERT(fp->fun && !JSFUN_HEAVYWEIGHT_TEST(FUN_FLAGS(fp->fun))); } fp->xmlNamespace = JSVAL_TO_OBJECT(v); return JS_TRUE; @@ -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; diff --git a/mozilla/js/src/liveconnect/nsCLiveconnect.cpp b/mozilla/js/src/liveconnect/nsCLiveconnect.cpp index 417d666174a..846d98f61e3 100644 --- a/mozilla/js/src/liveconnect/nsCLiveconnect.cpp +++ b/mozilla/js/src/liveconnect/nsCLiveconnect.cpp @@ -53,10 +53,10 @@ #include "jsj_private.h" #include "jsjava.h" -#include "jsdbgapi.h" #include "jsarena.h" -#include "jsfun.h" #include "jscntxt.h" /* For js_ReportErrorAgain().*/ +#include "jsdbgapi.h" +#include "jsfun.h" #include "jsscript.h" #include "netscape_javascript_JSObject.h" /* javah-generated headers */ diff --git a/mozilla/js/src/xpconnect/src/nsXPConnect.cpp b/mozilla/js/src/xpconnect/src/nsXPConnect.cpp index 2f2577bf1d9..f0995d79221 100644 --- a/mozilla/js/src/xpconnect/src/nsXPConnect.cpp +++ b/mozilla/js/src/xpconnect/src/nsXPConnect.cpp @@ -533,12 +533,12 @@ 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_SCRIPTED_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_OBJECT || (_kind) == JSTRACE_SCRIPTED_FUNCTION || \ (_kind) == JSTRACE_XML) #ifdef DEBUG_CC