jsscript.c
来自「java script test programing source code」· C语言 代码 · 共 1,718 行 · 第 1/4 页
C
1,718 行
index = i; if (!JS_XDRUint32(xdr, &index)) goto bad; /* * Assert that, when decoding, the read index is valid and points to * an unoccupied element of atoms array. */ JS_ASSERT(index < natoms); JS_ASSERT(xdr->mode == JSXDR_ENCODE || !atoms[index]); if (!js_XDRAtom(xdr, &atoms[index])) goto bad; } return JS_TRUE; bad: if (xdr->mode == JSXDR_DECODE) { JS_free(cx, atoms); map->vector = NULL; map->length = 0; } return JS_FALSE;}JSBooljs_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *hasMagic){ JSContext *cx; JSScript *script, *newscript, *oldscript; uint32 length, lineno, depth, magic, nsrcnotes, ntrynotes; uint32 prologLength, version; JSBool filenameWasSaved; jssrcnote *notes, *sn; cx = xdr->cx; script = *scriptp; nsrcnotes = ntrynotes = 0; filenameWasSaved = JS_FALSE; notes = NULL; /* * Encode prologLength and version after script->length (_2 or greater), * but decode both new (>= _2) and old, prolog&version-free (_1) scripts. * Version _3 supports principals serialization. Version _4 reorders the * nsrcnotes and ntrynotes fields to come before everything except magic, * length, prologLength, and version, so that srcnote and trynote storage * can be allocated as part of the JSScript (along with bytecode storage). * * So far, the magic number has not changed for every jsopcode.tbl change. * We stipulate forward compatibility by requiring old bytecodes never to * change or go away (modulo a few exceptions before the XDR interfaces * evolved, and a few exceptions during active trunk development). With * the addition of JSOP_STOP to support JS_THREADED_INTERP, we make a new * magic number (_5) so that we know to append JSOP_STOP to old scripts * when deserializing. */ if (xdr->mode == JSXDR_ENCODE) magic = JSXDR_MAGIC_SCRIPT_CURRENT; if (!JS_XDRUint32(xdr, &magic)) return JS_FALSE; JS_ASSERT((uint32)JSXDR_MAGIC_SCRIPT_5 - (uint32)JSXDR_MAGIC_SCRIPT_1 == 4); if (magic - (uint32)JSXDR_MAGIC_SCRIPT_1 > 4) { if (!hasMagic) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_SCRIPT_MAGIC); return JS_FALSE; } *hasMagic = JS_FALSE; return JS_TRUE; } if (hasMagic) *hasMagic = JS_TRUE; if (xdr->mode == JSXDR_ENCODE) { length = script->length; prologLength = PTRDIFF(script->main, script->code, jsbytecode); JS_ASSERT((int16)script->version != JSVERSION_UNKNOWN); version = (uint32)script->version | (script->numGlobalVars << 16); lineno = (uint32)script->lineno; depth = (uint32)script->depth; /* Count the srcnotes, keeping notes pointing at the first one. */ notes = SCRIPT_NOTES(script); for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) continue; nsrcnotes = PTRDIFF(sn, notes, jssrcnote); 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) { size_t alloclength = length; if (magic < JSXDR_MAGIC_SCRIPT_5) ++alloclength; /* add a byte for JSOP_STOP */ script = js_NewScript(cx, alloclength, nsrcnotes, ntrynotes); if (!script) return JS_FALSE; if (magic >= JSXDR_MAGIC_SCRIPT_2) { script->main += prologLength; script->version = (JSVersion) (version & 0xffff); script->numGlobalVars = (uint16) (version >> 16); /* 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 magic < _4) case must point at a temporary vector * allocated just below. */ oldscript = xdr->script; xdr->script = script; if (!JS_XDRBytes(xdr, (char *)script->code, length * sizeof(jsbytecode)) || !XDRAtomMap(xdr, &script->atomMap)) { goto error; } if (magic < JSXDR_MAGIC_SCRIPT_5) { if (xdr->mode == JSXDR_DECODE) { /* * Append JSOP_STOP to old scripts, to relieve the interpreter * from having to bounds-check pc. Also take care to increment * length, as it is used below and must count all bytecode. */ script->code[length++] = JSOP_STOP; } 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); memset(script->trynotes, 0, ntrynotes * sizeof(JSTryNote)); } } } 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; } xdr->script = oldscript; 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; jsval v; 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; argv[0] = STRING_TO_JSVAL(str); /* 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; } JS_LOCK_OBJ(cx, obj); execDepth = GetScriptExecDepth(cx, obj); /* * execDepth must be 0 to allow compilation here, otherwise the JSScript * struct can be released while running. */ if (execDepth > 0) { JS_UNLOCK_OBJ(cx, obj); JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_COMPILE_EXECED_SCRIPT); goto out; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?