jsscript.c
来自「java script test programing source code」· C语言 代码 · 共 1,718 行 · 第 1/4 页
C
1,718 行
/* Swap script for obj's old script, if any. */ v = LOCKED_OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE); oldscript = !JSVAL_IS_VOID(v) ? (JSScript *) JSVAL_TO_PRIVATE(v) : NULL; LOCKED_OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(script)); JS_UNLOCK_OBJ(cx, obj); 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); return 0;}#if !JS_HAS_SCRIPT_OBJECTconst char js_Script_str[] = "Script";#define JSProto_Script JSProto_Object#endifJS_FRIEND_DATA(JSClass) js_ScriptClass = { js_Script_str, JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Script) | JSCLASS_HAS_RESERVED_SLOTS(1), 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; /* * script_compile does not use rval to root its temporaries * so we can use it to root obj. */ *rval = OBJECT_TO_JSVAL(obj); } if (!JS_SetReservedSlot(cx, obj, 0, INT_TO_JSVAL(0))) 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#endif /* !JS_HAS_XDR_FREEZE_THAW */JSObject *js_InitScriptClass(JSContext *cx, JSObject *obj){ return JS_InitClass(cx, obj, NULL, &js_ScriptClass, Script, 1, NULL, script_methods, NULL, script_static_methods);}#endif /* JS_HAS_SCRIPT_OBJECT *//* * Shared script filename management. */JS_STATIC_DLL_CALLBACK(int)js_compare_strings(const void *k1, const void *k2){ return strcmp(k1, k2) == 0;}/* Shared with jsatom.c to save code space. */extern void * JS_DLL_CALLBACKjs_alloc_table_space(void *priv, size_t size);extern void JS_DLL_CALLBACKjs_free_table_space(void *priv, void *item);/* NB: This struct overlays JSHashEntry -- see jshash.h, do not reorganize. */typedef struct ScriptFilenameEntry { JSHashEntry *next; /* hash chain linkage */ JSHashNumber keyHash; /* key hash function result */ const void *key; /* ptr to filename, below */ uint32 flags; /* user-defined filename prefix flags */ JSPackedBool mark; /* GC mark flag */ char filename[3]; /* two or more bytes, NUL-terminated */} ScriptFilenameEntry;JS_STATIC_DLL_CALLBACK(JSHashEntry *)js_alloc_sftbl_entry(void *priv, const void *key){ size_t nbytes = offsetof(ScriptFilenameEntry, filename) + strlen(key) + 1; return (JSHashEntry *) malloc(JS_MAX(nbytes, sizeof(JSHashEntry)));}JS_STATIC_DLL_CALLBACK(void)js_free_sftbl_entry(void *priv, JSHashEntry *he, uintN flag){ if (flag != HT_FREE_ENTRY) return; free(he);}static JSHashAllocOps sftbl_alloc_ops = { js_alloc_table_space, js_free_table_space, js_alloc_sftbl_entry, js_free_sftbl_entry};JSBooljs_InitRuntimeScriptState(JSRuntime *rt){#ifdef JS_THREADSAFE JS_ASSERT(!rt->scriptFilenameTableLock); rt->scriptFilenameTableLock = JS_NEW_LOCK(); if (!rt->scriptFilenameTableLock) return JS_FALSE;#endif JS_ASSERT(!rt->scriptFilenameTable); rt->scriptFilenameTable = JS_NewHashTable(16, JS_HashString, js_compare_strings, NULL, &sftbl_alloc_ops, NULL); if (!rt->scriptFilenameTable) { js_FinishRuntimeScriptState(rt); /* free lock if threadsafe */ return JS_FALSE; } JS_INIT_CLIST(&rt->scriptFilenamePrefixes); return JS_TRUE;}typedef struct ScriptFilenamePrefix { JSCList links; /* circular list linkage for easy deletion */ const char *name; /* pointer to pinned ScriptFilenameEntry string */ size_t length; /* prefix string length, precomputed */ uint32 flags; /* user-defined flags to inherit from this prefix */} ScriptFilenamePrefix;voidjs_FinishRuntimeScriptState(JSRuntime *rt){ if (rt->scriptFilenameTable) { JS_HashTableDestroy(rt->scriptFilenameTable); rt->scriptFilenameTable = NULL; }#ifdef JS_THREADSAFE if (rt->scriptFilenameTableLock) { JS_DESTROY_LOCK(rt->scriptFilenameTableLock); rt->scriptFilenameTableLock = NULL; }#endif}voidjs_FreeRuntimeScriptState(JSRuntime *rt){ ScriptFilenamePrefix *sfp; if (!rt->scriptFilenameTable) return; while (!JS_CLIST_IS_EMPTY(&rt->scriptFilenamePrefixes)) { sfp = (ScriptFilenamePrefix *) rt->scriptFilenamePrefixes.next; JS_REMOVE_LINK(&sfp->links); free(sfp); } js_FinishRuntimeScriptState(rt);}#ifdef DEBUG_brendan#define DEBUG_SFTBL#endif#ifdef DEBUG_SFTBLsize_t sftbl_savings = 0;#endifstatic ScriptFilenameEntry *SaveScriptFilename(JSRuntime *rt, const char *filename, uint32 flags){ JSHashTable *table; JSHashNumber hash; JSHashEntry **hep; ScriptFilenameEntry *sfe; size_t length; JSCList *head, *link; ScriptFilenamePrefix *sfp; table = rt->scriptFilenameTable; hash = JS_HashString(filename); hep = JS_HashTableRawLookup(table, hash, filename); sfe = (ScriptFilenameEntry *) *hep;#ifdef DEBUG_SFTBL if (sfe) sftbl_savings += strlen(sfe->filename);#endif if (!sfe) { sfe = (ScriptFilenameEntry *) JS_HashTableRawAdd(table, hep, hash, filename, NULL); if (!sfe) return NULL; sfe->key = strcpy(sfe->filename, filename); sfe->flags = 0; sfe->mark = JS_FALSE; } /* If saving a prefix, add it to the set in rt->scriptFilenamePrefixes. */ if (flags != 0) { /* Search in case filename was saved already; we must be idempotent. */ sfp = NULL; length = strlen(filename); for (head = link = &rt->scriptFilenamePrefixes; link->next != head; link = link->next) { /* Lag link behind sfp to insert in non-increasing length order. */ sfp = (ScriptFilenamePrefix *) link->next; if (!strcmp(sfp->name, filename)) break; if (sfp->length <= length) { sfp = NULL; break; } sfp = NULL; } if (!sfp) { /* No such prefix: add one now. */ sfp = (ScriptFilenamePrefix *) malloc(sizeof(ScriptFilenamePrefix)); if (!sfp) return NULL; JS_INSERT_AFTER(&sfp->links, link); sfp->name = sfe->filename; sfp->length = length; sfp->flags = 0; } /* * Accumulate flags in both sfe and sfp: sfe for later access from the * JS_GetScriptedCallerFilenameFlags debug-API, and sfp so that longer * filename entries can inherit by prefix. */ sfe->flags |= flags; sfp->flags |= flags; } return sfe;}const char *js_SaveScriptFilename(JSContext *cx, const char *filename){ JSRuntime *rt; ScriptFilenameEntry *sfe; JSCList *head, *link; ScriptFilenamePrefix *sfp; rt = cx->runtime; JS_ACQUIRE_LOCK(rt->scriptFilenameTableLock); sfe = SaveScriptFilename(rt, filename, 0); if (!sfe) { JS_RELEASE_LOCK(rt->scriptFilenameTableLock); JS_ReportOutOfMemory(cx); return NULL; } /* * Try to inherit flags by prefix. We assume there won't be more than a * few (dozen! ;-) prefixes, so linear search is tolerable. * XXXbe every time I've assumed that in the JS engine, I've been wrong! */ for (head = &rt->scriptFilenamePrefixes, link = head->next; link != head; link = link->next) { sfp = (ScriptFilenamePrefix *) link; if (!strncmp(sfp->name, filename, sfp->length)) { sfe->flags |= sfp->flags; break; } } JS_RELEASE_LOCK(rt->scriptFilenameTableLock); return sfe->filename;}const char *js_SaveScriptFilenameRT(JSRuntime *rt, const char *filename, uint32 flags){ ScriptFilenameEntry *sfe; /* This may be called very early, via the jsdbgapi.h entry point. */ if (!rt->scriptFilenameTable && !js_InitRuntimeScriptState(rt)) return NULL; JS_ACQUIRE_LOCK(rt->scriptFilenameTableLock); sfe = SaveScriptFilename(rt, filename, flags); JS_RELEASE_LOCK(rt->scriptFilenameTableLock); if (!sfe) return NULL; return sfe->filename;}/* * Back up from a saved filename by its offset within its hash table entry. */#define FILENAME_TO_SFE(fn) \ ((ScriptFilenameEntry *) ((fn) - offsetof(ScriptFilenameEntry, filename)))/* * The sfe->key member, redundant given sfe->filename but required by the old * jshash.c code, here gives us a useful sanity check. This assertion will * very likely botch if someone tries to mark a string that wasn't allocated * as an sfe->filename. */#define ASSERT_VALID_SFE(sfe) JS_ASSERT((sfe)->key == (sfe)->filename)uint32js_GetScriptFilenameFlags(const char *filename){ ScriptFilenameEntry *sfe; sfe = FILENAME_TO_SFE(filename); ASSERT_VALID_SFE(sfe); return sfe->flags;}voidjs_MarkScriptFilename(const char *filename){ ScriptFilenameEntry *sfe; sfe = FILENAME_TO_SFE(filename); ASSERT_VALID_SFE(sfe); sfe->mark = JS_TRUE;}JS_STATIC_DLL_CALLBACK(intN)js_script_filename_marker(JSHashEntry *he, intN i, void *arg){ ScriptFilenameEntry *sfe = (ScriptFilenameEntry *) he;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?