📄 jsscript.c
字号:
nsrcnotes++; /* room for the terminator */ /* Count the trynotes. */ if (script->trynotes) { while (script->trynotes[ntrynotes].catchStart) ntrynotes++; ntrynotes++; /* room for the end marker */ } } if (!JS_XDRUint32(xdr, &length)) return JS_FALSE; if (magic >= JSXDR_MAGIC_SCRIPT_2) { if (!JS_XDRUint32(xdr, &prologLength)) return JS_FALSE; if (!JS_XDRUint32(xdr, &version)) return JS_FALSE; /* To fuse allocations, we need srcnote and trynote counts early. */ if (magic >= JSXDR_MAGIC_SCRIPT_4) { if (!JS_XDRUint32(xdr, &nsrcnotes)) return JS_FALSE; if (!JS_XDRUint32(xdr, &ntrynotes)) return JS_FALSE; } } if (xdr->mode == JSXDR_DECODE) { script = js_NewScript(cx, length, nsrcnotes, ntrynotes); if (!script) return JS_FALSE; if (magic >= JSXDR_MAGIC_SCRIPT_2) { script->main += prologLength; script->version = (JSVersion) version; /* If we know nsrcnotes, we allocated space for notes in script. */ if (magic >= JSXDR_MAGIC_SCRIPT_4) notes = SCRIPT_NOTES(script); } *scriptp = script; } /* * Control hereafter must goto error on failure, in order for the DECODE * case to destroy script and conditionally free notes, which if non-null * in the (DECODE and version < _4) case must point at a temporary vector * allocated just below. */ if (!JS_XDRBytes(xdr, (char *)script->code, length * sizeof(jsbytecode)) || !XDRAtomMap(xdr, &script->atomMap)) { goto error; } if (magic < JSXDR_MAGIC_SCRIPT_4) { if (!JS_XDRUint32(xdr, &nsrcnotes)) goto error; if (xdr->mode == JSXDR_DECODE) { notes = (jssrcnote *) JS_malloc(cx, nsrcnotes * sizeof(jssrcnote)); if (!notes) goto error; } } if (!JS_XDRBytes(xdr, (char *)notes, nsrcnotes * sizeof(jssrcnote)) || !JS_XDRCStringOrNull(xdr, (char **)&script->filename) || !JS_XDRUint32(xdr, &lineno) || !JS_XDRUint32(xdr, &depth) || (magic < JSXDR_MAGIC_SCRIPT_4 && !JS_XDRUint32(xdr, &ntrynotes))) { goto error; } /* Script principals transcoding support comes with versions >= _3. */ if (magic >= JSXDR_MAGIC_SCRIPT_3) { JSPrincipals *principals; uint32 encodeable; if (xdr->mode == JSXDR_ENCODE) { principals = script->principals; encodeable = (cx->runtime->principalsTranscoder != NULL); if (!JS_XDRUint32(xdr, &encodeable)) goto error; if (encodeable && !cx->runtime->principalsTranscoder(xdr, &principals)) { goto error; } } else { if (!JS_XDRUint32(xdr, &encodeable)) goto error; if (encodeable) { if (!cx->runtime->principalsTranscoder) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_DECODE_PRINCIPALS); goto error; } if (!cx->runtime->principalsTranscoder(xdr, &principals)) goto error; script->principals = principals; } } } if (xdr->mode == JSXDR_DECODE) { const char *filename = script->filename; if (filename) { filename = js_SaveScriptFilename(cx, filename); if (!filename) goto error; JS_free(cx, (void *) script->filename); script->filename = filename; filenameWasSaved = JS_TRUE; } script->lineno = (uintN)lineno; script->depth = (uintN)depth; if (magic < JSXDR_MAGIC_SCRIPT_4) { /* * Argh, we have to reallocate script, copy notes into the extra * space after the bytecodes, and free the temporary notes vector. * First, add enough slop to nsrcnotes so we can align the address * after the srcnotes of the first trynote. */ uint32 osrcnotes = nsrcnotes; if (ntrynotes) nsrcnotes += JSTRYNOTE_ALIGNMASK; newscript = (JSScript *) JS_realloc(cx, script, sizeof(JSScript) + length * sizeof(jsbytecode) + nsrcnotes * sizeof(jssrcnote) + ntrynotes * sizeof(JSTryNote)); if (!newscript) goto error; *scriptp = script = newscript; script->code = (jsbytecode *)(script + 1); script->main = script->code + prologLength; memcpy(script->code + length, notes, osrcnotes * sizeof(jssrcnote)); JS_free(cx, (void *) notes); notes = NULL; if (ntrynotes) { script->trynotes = (JSTryNote *) ((jsword)(SCRIPT_NOTES(script) + nsrcnotes) & ~(jsword)JSTRYNOTE_ALIGNMASK); } } } while (ntrynotes) { JSTryNote *tn = &script->trynotes[--ntrynotes]; uint32 start = (uint32) tn->start, catchLength = (uint32) tn->length, catchStart = (uint32) tn->catchStart; if (!JS_XDRUint32(xdr, &start) || !JS_XDRUint32(xdr, &catchLength) || !JS_XDRUint32(xdr, &catchStart)) { goto error; } tn->start = (ptrdiff_t) start; tn->length = (ptrdiff_t) catchLength; tn->catchStart = (ptrdiff_t) catchStart; } return JS_TRUE; error: if (xdr->mode == JSXDR_DECODE) { if (script->filename && !filenameWasSaved) { JS_free(cx, (void *) script->filename); script->filename = NULL; } if (notes && magic < JSXDR_MAGIC_SCRIPT_4) JS_free(cx, (void *) notes); js_DestroyScript(cx, script); *scriptp = NULL; } return JS_FALSE;}#if JS_HAS_XDR_FREEZE_THAW/* * These cannot be exposed to web content, and chrome does not need them, so * we take them out of the Mozilla client altogether. Fortunately, there is * no way to serialize a native function (see fun_xdrObject in jsfun.c). */static JSBoolscript_freeze(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSXDRState *xdr; JSScript *script; JSBool ok, hasMagic; uint32 len; void *buf; JSString *str; if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv)) return JS_FALSE; script = (JSScript *) JS_GetPrivate(cx, obj); if (!script) return JS_TRUE; /* create new XDR */ xdr = JS_XDRNewMem(cx, JSXDR_ENCODE); if (!xdr) return JS_FALSE; /* write */ ok = js_XDRScript(xdr, &script, &hasMagic); if (!ok) goto out; if (!hasMagic) { *rval = JSVAL_VOID; goto out; } buf = JS_XDRMemGetData(xdr, &len); if (!buf) { ok = JS_FALSE; goto out; } JS_ASSERT((jsword)buf % sizeof(jschar) == 0); len /= sizeof(jschar); str = JS_NewUCStringCopyN(cx, (jschar *)buf, len); if (!str) { ok = JS_FALSE; goto out; }#if IS_BIG_ENDIAN { jschar *chars; uint32 i; /* Swap bytes in Unichars to keep frozen strings machine-independent. */ chars = JS_GetStringChars(str); for (i = 0; i < len; i++) chars[i] = JSXDR_SWAB16(chars[i]); }#endif *rval = STRING_TO_JSVAL(str);out: JS_XDRDestroy(xdr); return ok;}static JSBoolscript_thaw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSXDRState *xdr; JSString *str; void *buf; uint32 len; JSScript *script, *oldscript; JSBool ok, hasMagic; if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv)) return JS_FALSE; if (argc == 0) return JS_TRUE; str = js_ValueToString(cx, argv[0]); if (!str) return JS_FALSE; /* create new XDR */ xdr = JS_XDRNewMem(cx, JSXDR_DECODE); if (!xdr) return JS_FALSE; buf = JS_GetStringChars(str); len = JS_GetStringLength(str);#if IS_BIG_ENDIAN { jschar *from, *to; uint32 i; /* Swap bytes in Unichars to keep frozen strings machine-independent. */ from = (jschar *)buf; to = (jschar *) JS_malloc(cx, len * sizeof(jschar)); if (!to) { JS_XDRDestroy(xdr); return JS_FALSE; } for (i = 0; i < len; i++) to[i] = JSXDR_SWAB16(from[i]); buf = (char *)to; }#endif len *= sizeof(jschar); JS_XDRMemSetData(xdr, buf, len); /* XXXbe should magic mismatch be error, or false return value? */ ok = js_XDRScript(xdr, &script, &hasMagic); if (!ok) goto out; if (!hasMagic) { *rval = JSVAL_FALSE; goto out; } /* Swap script for obj's old script, if any. */ oldscript = (JSScript *) JS_GetPrivate(cx, obj); ok = JS_SetPrivate(cx, obj, script); if (!ok) { JS_free(cx, script); goto out; } if (oldscript) js_DestroyScript(cx, oldscript); script->object = obj; js_CallNewScriptHook(cx, script, NULL);out: /* * We reset the buffer to be NULL so that it doesn't free the chars * memory owned by str (argv[0]). */ JS_XDRMemSetData(xdr, NULL, 0); JS_XDRDestroy(xdr);#if IS_BIG_ENDIAN JS_free(cx, buf);#endif *rval = JSVAL_TRUE; return ok;}static const char js_thaw_str[] = "thaw";#endif /* JS_HAS_XDR_FREEZE_THAW */#endif /* JS_HAS_XDR */static JSFunctionSpec script_methods[] = {#if JS_HAS_TOSOURCE {js_toSource_str, script_toSource, 0,0,0},#endif {js_toString_str, script_toString, 0,0,0}, {"compile", script_compile, 2,0,0}, {"exec", script_exec, 1,0,0},#if JS_HAS_XDR_FREEZE_THAW {"freeze", script_freeze, 0,0,0}, {js_thaw_str, script_thaw, 1,0,0},#endif /* JS_HAS_XDR_FREEZE_THAW */ {0,0,0,0,0}};#endif /* JS_HAS_SCRIPT_OBJECT */static voidscript_finalize(JSContext *cx, JSObject *obj){ JSScript *script; script = (JSScript *) JS_GetPrivate(cx, obj); if (script) js_DestroyScript(cx, script);}static JSBoolscript_call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){#if JS_HAS_SCRIPT_OBJECT return script_exec(cx, JSVAL_TO_OBJECT(argv[-2]), argc, argv, rval);#else return JS_FALSE;#endif}static uint32script_mark(JSContext *cx, JSObject *obj, void *arg){ JSScript *script; script = (JSScript *) JS_GetPrivate(cx, obj); if (script) js_MarkScript(cx, script, arg); return 0;}JS_FRIEND_DATA(JSClass) js_ScriptClass = { js_Script_str, JSCLASS_HAS_PRIVATE, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, script_finalize, NULL, NULL, script_call, NULL,/*XXXbe xdr*/ NULL, NULL, script_mark, 0};#if JS_HAS_SCRIPT_OBJECTstatic JSBoolScript(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); if (!obj) return JS_FALSE; } return script_compile(cx, obj, argc, argv, rval);}#if JS_HAS_XDR_FREEZE_THAWstatic JSBoolscript_static_thaw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL); if (!obj) return JS_FALSE; if (!script_thaw(cx, obj, argc, argv, rval)) return JS_FALSE; *rval = OBJECT_TO_JSVAL(obj); return JS_TRUE;}static JSFunctionSpec script_static_methods[] = { {js_thaw_str, script_static_thaw, 1,0,0}, {0,0,0,0,0}};#else /* !JS_HAS_XDR_FREEZE_THAW */#define script_static_methods NULL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -