diff --git a/mozilla/js/src/jsfun.c b/mozilla/js/src/jsfun.c index 384ad28d805..fe15a9677b2 100644 --- a/mozilla/js/src/jsfun.c +++ b/mozilla/js/src/jsfun.c @@ -1082,7 +1082,6 @@ fun_xdrObject(JSXDRState *xdr, JSObject **objp) JSString *atomstr; char *propname; JSScopeProperty *sprop; - JSBool magic; jsid propid; JSAtom *atom; uintN i; @@ -1185,10 +1184,9 @@ fun_xdrObject(JSXDRState *xdr, JSObject **objp) } } } - if (!js_XDRScript(xdr, &fun->script, &magic) || - !magic) { + + if (!js_XDRScript(xdr, &fun->script, NULL)) return JS_FALSE; - } if (xdr->mode == JSXDR_DECODE) { *objp = fun->object; @@ -1204,6 +1202,8 @@ fun_xdrObject(JSXDRState *xdr, JSObject **objp) return JS_FALSE; } } + + js_CallNewScriptHook(cx, fun->script, fun); } return JS_TRUE; diff --git a/mozilla/js/src/jsscript.c b/mozilla/js/src/jsscript.c index 1555af35086..1f5056309ea 100644 --- a/mozilla/js/src/jsscript.c +++ b/mozilla/js/src/jsscript.c @@ -350,16 +350,22 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *hasMagic) if (magic != JSXDR_MAGIC_SCRIPT_3 && magic != JSXDR_MAGIC_SCRIPT_2 && magic != JSXDR_MAGIC_SCRIPT_1) { + if (!hasMagic) { + JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, + JSMSG_BAD_SCRIPT_MAGIC); + return JS_FALSE; + } *hasMagic = JS_FALSE; return JS_TRUE; } - *hasMagic = JS_TRUE; + if (hasMagic) + *hasMagic = JS_TRUE; if (xdr->mode == JSXDR_ENCODE) { jssrcnote *sn = script->notes; length = script->length; prologLength = script->main - script->code; - version = (int32) script->version; + version = (int32)script->version; lineno = (uint32)script->lineno; depth = (uint32)script->depth; @@ -397,6 +403,7 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *hasMagic) *scriptp = script; } + /* Control hereafter must goto error on failure, to destroy script. */ if (!JS_XDRBytes(xdr, (char **)&script->code, length) || !XDRAtomMap(xdr, &script->atomMap) || !JS_XDRUint32(xdr, ¬elen) || @@ -607,6 +614,7 @@ script_thaw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, js_DestroyScript(cx, oldscript); script->object = obj; + js_CallNewScriptHook(cx, script, NULL); out: /* @@ -785,8 +793,6 @@ js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg, JSFunction *fun) JSTryNote *trynotes; jssrcnote *notes; JSScript *script; - JSRuntime *rt; - JSNewScriptHook hook; if (!js_FinishTakingTryNotes(cx, cg, &trynotes)) return NULL; @@ -804,6 +810,16 @@ js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg, JSFunction *fun) } /* Tell the debugger about this compiled script. */ + js_CallNewScriptHook(cx, script, fun); + return script; +} + +JS_FRIEND_API(void) +js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun) +{ + JSRuntime *rt; + JSNewScriptHook hook; + rt = cx->runtime; hook = rt->newScriptHook; if (hook) { @@ -822,12 +838,11 @@ js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg, JSFunction *fun) dummy.script = script; cx->fp = &dummy; - (*hook)(cx, cg->filename, cg->firstLine, script, fun, - rt->newScriptHookData); + hook(cx, script->filename, script->lineno, script, fun, + rt->newScriptHookData); cx->fp = dummy.down; } - return script; } void diff --git a/mozilla/js/src/jsscript.h b/mozilla/js/src/jsscript.h index c2881f1da28..15e2ee79b36 100644 --- a/mozilla/js/src/jsscript.h +++ b/mozilla/js/src/jsscript.h @@ -89,6 +89,17 @@ extern JS_FRIEND_DATA(JSClass) js_ScriptClass; extern JSObject * js_InitScriptClass(JSContext *cx, JSObject *obj); +/* + * Three successively less primitive ways to make a new JSScript. The first + * two do *not* call a non-null cx->runtime->newScriptHook -- only the last, + * js_NewScriptFromCG, calls this optional debugger hook. + * + * The js_NewScript function can't know whether the script it creates belongs + * to a function, or is top-level or eval code, but the debugger wants access + * to the newly made script's function, if any -- so callers of js_NewScript + * are responsible for notifying the debugger after successfully creating any + * kind (function or other) of new JSScript. + */ extern JSScript * js_NewScript(JSContext *cx, uint32 length); @@ -102,6 +113,15 @@ js_NewScriptFromParams(JSContext *cx, jsbytecode *code, uint32 length, extern JS_FRIEND_API(JSScript *) js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg, JSFunction *fun); +/* + * New-script-hook calling is factored from js_NewScriptFromCG so that it + * and callers of js_XDRScript can share this code. In the case of callers + * 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_DestroyScript(JSContext *cx, JSScript *script); @@ -120,6 +140,15 @@ js_LineNumberToPC(JSScript *script, uintN lineno); extern uintN js_GetScriptLineExtent(JSScript *script); +/* + * If magic is non-null, js_XDRScript succeeds on magic number mismatch but + * returns false in *magic; it reflects a match via a true *magic out param. + * If magic is null, js_XDRScript returns false on bad magic number errors, + * which it reports. + * + * NB: callers must call js_CallNewScriptHook after successful JSXDR_DECODE + * and subsequent set-up of owning function or script object, if any. + */ extern JSBool js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *magic); diff --git a/mozilla/js/src/jsxdrapi.c b/mozilla/js/src/jsxdrapi.c index fa434576ffa..c8172cc9abb 100644 --- a/mozilla/js/src/jsxdrapi.c +++ b/mozilla/js/src/jsxdrapi.c @@ -574,15 +574,10 @@ JS_XDRValue(JSXDRState *xdr, jsval *vp) JS_PUBLIC_API(JSBool) JS_XDRScript(JSXDRState *xdr, JSScript **scriptp) { - JSBool hasMagic; - - if (!js_XDRScript(xdr, scriptp, &hasMagic)) + if (!js_XDRScript(xdr, scriptp, NULL)) return JS_FALSE; - if (!hasMagic) { - JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, - JSMSG_BAD_SCRIPT_MAGIC); - return JS_FALSE; - } + if (xdr->mode == JSXDR_DECODE) + js_CallNewScriptHook(xdr->cx, *scriptp, NULL); return JS_TRUE; }