📄 jsapi.c
字号:
jsrefcount saveDepth = cx->requestDepth; while (cx->requestDepth) JS_EndRequest(cx); return saveDepth;}JS_PUBLIC_API(void)JS_ResumeRequest(JSContext *cx, jsrefcount saveDepth){ JS_ASSERT(!cx->requestDepth); while (--saveDepth >= 0) JS_BeginRequest(cx);}#endif /* JS_THREADSAFE */JS_PUBLIC_API(void)JS_Lock(JSRuntime *rt){ JS_LOCK_RUNTIME(rt);}JS_PUBLIC_API(void)JS_Unlock(JSRuntime *rt){ JS_UNLOCK_RUNTIME(rt);}JS_PUBLIC_API(JSContextCallback)JS_SetContextCallback(JSRuntime *rt, JSContextCallback cxCallback){ JSContextCallback old; old = rt->cxCallback; rt->cxCallback = cxCallback; return old;}JS_PUBLIC_API(JSContext *)JS_NewContext(JSRuntime *rt, size_t stackChunkSize){ return js_NewContext(rt, stackChunkSize);}JS_PUBLIC_API(void)JS_DestroyContext(JSContext *cx){ js_DestroyContext(cx, JSDCM_FORCE_GC);}JS_PUBLIC_API(void)JS_DestroyContextNoGC(JSContext *cx){ js_DestroyContext(cx, JSDCM_NO_GC);}JS_PUBLIC_API(void)JS_DestroyContextMaybeGC(JSContext *cx){ js_DestroyContext(cx, JSDCM_MAYBE_GC);}JS_PUBLIC_API(void *)JS_GetContextPrivate(JSContext *cx){ return cx->data;}JS_PUBLIC_API(void)JS_SetContextPrivate(JSContext *cx, void *data){ cx->data = data;}JS_PUBLIC_API(JSRuntime *)JS_GetRuntime(JSContext *cx){ return cx->runtime;}JS_PUBLIC_API(JSContext *)JS_ContextIterator(JSRuntime *rt, JSContext **iterp){ return js_ContextIterator(rt, JS_TRUE, iterp);}JS_PUBLIC_API(JSVersion)JS_GetVersion(JSContext *cx){ return cx->version & JSVERSION_MASK;}JS_PUBLIC_API(JSVersion)JS_SetVersion(JSContext *cx, JSVersion version){ JSVersion oldVersion; JS_ASSERT(version != JSVERSION_UNKNOWN); JS_ASSERT((version & ~JSVERSION_MASK) == 0); oldVersion = cx->version & JSVERSION_MASK; if (version == oldVersion) return oldVersion; /* We no longer support 1.4 or below. */ if (version != JSVERSION_DEFAULT && version <= JSVERSION_1_4) return oldVersion; cx->version = (cx->version & ~JSVERSION_MASK) | version; js_OnVersionChange(cx); return oldVersion;}static struct v2smap { JSVersion version; const char *string;} v2smap[] = { {JSVERSION_1_0, "1.0"}, {JSVERSION_1_1, "1.1"}, {JSVERSION_1_2, "1.2"}, {JSVERSION_1_3, "1.3"}, {JSVERSION_1_4, "1.4"}, {JSVERSION_ECMA_3, "ECMAv3"}, {JSVERSION_1_5, "1.5"}, {JSVERSION_1_6, "1.6"}, {JSVERSION_1_7, "1.7"}, {JSVERSION_DEFAULT, js_default_str}, {JSVERSION_UNKNOWN, NULL}, /* must be last, NULL is sentinel */};JS_PUBLIC_API(const char *)JS_VersionToString(JSVersion version){ int i; for (i = 0; v2smap[i].string; i++) if (v2smap[i].version == version) return v2smap[i].string; return "unknown";}JS_PUBLIC_API(JSVersion)JS_StringToVersion(const char *string){ int i; for (i = 0; v2smap[i].string; i++) if (strcmp(v2smap[i].string, string) == 0) return v2smap[i].version; return JSVERSION_UNKNOWN;}JS_PUBLIC_API(uint32)JS_GetOptions(JSContext *cx){ return cx->options;}#define SYNC_OPTIONS_TO_VERSION(cx) \ JS_BEGIN_MACRO \ if ((cx)->options & JSOPTION_XML) \ (cx)->version |= JSVERSION_HAS_XML; \ else \ (cx)->version &= ~JSVERSION_HAS_XML; \ JS_END_MACROJS_PUBLIC_API(uint32)JS_SetOptions(JSContext *cx, uint32 options){ uint32 oldopts = cx->options; cx->options = options; SYNC_OPTIONS_TO_VERSION(cx); return oldopts;}JS_PUBLIC_API(uint32)JS_ToggleOptions(JSContext *cx, uint32 options){ uint32 oldopts = cx->options; cx->options ^= options; SYNC_OPTIONS_TO_VERSION(cx); return oldopts;}JS_PUBLIC_API(const char *)JS_GetImplementationVersion(void){ return "JavaScript-C 1.7.0 2007-10-03";}JS_PUBLIC_API(JSObject *)JS_GetGlobalObject(JSContext *cx){ return cx->globalObject;}JS_PUBLIC_API(void)JS_SetGlobalObject(JSContext *cx, JSObject *obj){ cx->globalObject = obj;#if JS_HAS_XML_SUPPORT cx->xmlSettingFlags = 0;#endif}JSObject *js_InitFunctionAndObjectClasses(JSContext *cx, JSObject *obj){ JSDHashTable *table; JSBool resolving; JSRuntime *rt; JSResolvingKey key; JSResolvingEntry *entry; JSObject *fun_proto, *obj_proto; /* If cx has no global object, use obj so prototypes can be found. */ if (!cx->globalObject) JS_SetGlobalObject(cx, obj); /* Record Function and Object in cx->resolvingTable, if we are resolving. */ table = cx->resolvingTable; resolving = (table && table->entryCount); rt = cx->runtime; key.obj = obj; if (resolving) { key.id = ATOM_TO_JSID(rt->atomState.classAtoms[JSProto_Function]); entry = (JSResolvingEntry *) JS_DHashTableOperate(table, &key, JS_DHASH_ADD); if (entry && entry->key.obj && (entry->flags & JSRESFLAG_LOOKUP)) { /* Already resolving Function, record Object too. */ JS_ASSERT(entry->key.obj == obj); key.id = ATOM_TO_JSID(rt->atomState.classAtoms[JSProto_Object]); entry = (JSResolvingEntry *) JS_DHashTableOperate(table, &key, JS_DHASH_ADD); } if (!entry) { JS_ReportOutOfMemory(cx); return NULL; } JS_ASSERT(!entry->key.obj && entry->flags == 0); entry->key = key; entry->flags = JSRESFLAG_LOOKUP; } else { key.id = ATOM_TO_JSID(rt->atomState.classAtoms[JSProto_Object]); if (!js_StartResolving(cx, &key, JSRESFLAG_LOOKUP, &entry)) return NULL; key.id = ATOM_TO_JSID(rt->atomState.classAtoms[JSProto_Function]); if (!js_StartResolving(cx, &key, JSRESFLAG_LOOKUP, &entry)) { key.id = ATOM_TO_JSID(rt->atomState.classAtoms[JSProto_Object]); JS_DHashTableOperate(table, &key, JS_DHASH_REMOVE); return NULL; } table = cx->resolvingTable; } /* Initialize the function class first so constructors can be made. */ fun_proto = js_InitFunctionClass(cx, obj); if (!fun_proto) goto out; /* Initialize the object class next so Object.prototype works. */ obj_proto = js_InitObjectClass(cx, obj); if (!obj_proto) { fun_proto = NULL; goto out; } /* Function.prototype and the global object delegate to Object.prototype. */ OBJ_SET_PROTO(cx, fun_proto, obj_proto); if (!OBJ_GET_PROTO(cx, obj)) OBJ_SET_PROTO(cx, obj, obj_proto);out: /* If resolving, remove the other entry (Object or Function) from table. */ JS_DHashTableOperate(table, &key, JS_DHASH_REMOVE); if (!resolving) { /* If not resolving, remove the first entry added above, for Object. */ JS_ASSERT(key.id == \ ATOM_TO_JSID(rt->atomState.classAtoms[JSProto_Function])); key.id = ATOM_TO_JSID(rt->atomState.classAtoms[JSProto_Object]); JS_DHashTableOperate(table, &key, JS_DHASH_REMOVE); } return fun_proto;}JS_PUBLIC_API(JSBool)JS_InitStandardClasses(JSContext *cx, JSObject *obj){ JSAtom *atom; CHECK_REQUEST(cx); /* Define a top-level property 'undefined' with the undefined value. */ atom = cx->runtime->atomState.typeAtoms[JSTYPE_VOID]; if (!OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), JSVAL_VOID, NULL, NULL, JSPROP_PERMANENT, NULL)) { return JS_FALSE; } /* Function and Object require cooperative bootstrapping magic. */ if (!js_InitFunctionAndObjectClasses(cx, obj)) return JS_FALSE; /* Initialize the rest of the standard objects and functions. */ return js_InitArrayClass(cx, obj) && js_InitBlockClass(cx, obj) && js_InitBooleanClass(cx, obj) && js_InitCallClass(cx, obj) && js_InitExceptionClasses(cx, obj) && js_InitMathClass(cx, obj) && js_InitNumberClass(cx, obj) && js_InitRegExpClass(cx, obj) && js_InitStringClass(cx, obj) &&#if JS_HAS_SCRIPT_OBJECT js_InitScriptClass(cx, obj) &&#endif#if JS_HAS_XML_SUPPORT js_InitXMLClasses(cx, obj) &&#endif#if JS_HAS_FILE_OBJECT js_InitFileClass(cx, obj) &&#endif#if JS_HAS_GENERATORS js_InitIteratorClasses(cx, obj) &&#endif js_InitDateClass(cx, obj);}#define ATOM_OFFSET(name) offsetof(JSAtomState,name##Atom)#define CLASS_ATOM_OFFSET(name) offsetof(JSAtomState,classAtoms[JSProto_##name])#define OFFSET_TO_ATOM(rt,off) (*(JSAtom **)((char*)&(rt)->atomState + (off)))#define CLASP(name) (JSClass *)&js_##name##Class#define EAGER_ATOM(name) ATOM_OFFSET(name), NULL#define EAGER_CLASS_ATOM(name) CLASS_ATOM_OFFSET(name), NULL#define EAGER_ATOM_AND_CLASP(name) EAGER_CLASS_ATOM(name), CLASP(name)#define LAZY_ATOM(name) ATOM_OFFSET(lazy.name), js_##name##_strtypedef struct JSStdName { JSObjectOp init; size_t atomOffset; /* offset of atom pointer in JSAtomState */ const char *name; /* null if atom is pre-pinned, else name */ JSClass *clasp;} JSStdName;static JSAtom *StdNameToAtom(JSContext *cx, JSStdName *stdn){ size_t offset; JSAtom *atom; const char *name; offset = stdn->atomOffset; atom = OFFSET_TO_ATOM(cx->runtime, offset); if (!atom) { name = stdn->name; if (name) { atom = js_Atomize(cx, name, strlen(name), ATOM_PINNED); OFFSET_TO_ATOM(cx->runtime, offset) = atom; } } return atom;}/* * Table of class initializers and their atom offsets in rt->atomState. * If you add a "standard" class, remember to update this table. */static JSStdName standard_class_atoms[] = { {js_InitFunctionAndObjectClasses, EAGER_ATOM_AND_CLASP(Function)}, {js_InitFunctionAndObjectClasses, EAGER_ATOM_AND_CLASP(Object)}, {js_InitArrayClass, EAGER_ATOM_AND_CLASP(Array)}, {js_InitBlockClass, EAGER_ATOM_AND_CLASP(Block)}, {js_InitBooleanClass, EAGER_ATOM_AND_CLASP(Boolean)}, {js_InitDateClass, EAGER_ATOM_AND_CLASP(Date)}, {js_InitMathClass, EAGER_ATOM_AND_CLASP(Math)}, {js_InitNumberClass, EAGER_ATOM_AND_CLASP(Number)}, {js_InitStringClass, EAGER_ATOM_AND_CLASP(String)}, {js_InitCallClass, EAGER_ATOM_AND_CLASP(Call)}, {js_InitExceptionClasses, EAGER_ATOM_AND_CLASP(Error)}, {js_InitRegExpClass, EAGER_ATOM_AND_CLASP(RegExp)},#if JS_HAS_SCRIPT_OBJECT {js_InitScriptClass, EAGER_ATOM_AND_CLASP(Script)},#endif#if JS_HAS_XML_SUPPORT {js_InitXMLClass, EAGER_ATOM_AND_CLASP(XML)}, {js_InitNamespaceClass, EAGER_ATOM_AND_CLASP(Namespace)}, {js_InitQNameClass, EAGER_ATOM_AND_CLASP(QName)},#endif#if JS_HAS_FILE_OBJECT {js_InitFileClass, EAGER_ATOM_AND_CLASP(File)},#endif#if JS_HAS_GENERATORS {js_InitIteratorClasses, EAGER_ATOM_AND_CLASP(StopIteration)},#endif {NULL, 0, NULL, NULL}};/* * Table of top-level function and constant names and their init functions. * If you add a "standard" global function or property, remember to update * this table. */static JSStdName standard_class_names[] = { /* ECMA requires that eval be a direct property of the global object. */ {js_InitObjectClass, EAGER_ATOM(eval), NULL}, /* Global properties and functions defined by the Number class. */ {js_InitNumberClass, LAZY_ATOM(NaN), NULL}, {js_InitNumberClass, LAZY_ATOM(Infinity), NULL}, {js_InitNumberClass, LAZY_ATOM(isNaN), NULL}, {js_InitNumberClass, LAZY_ATOM(isFinite), NULL}, {js_InitNumberClass, LAZY_ATOM(parseFloat), NULL}, {js_InitNumberClass, LAZY_ATOM(parseInt), NULL}, /* String global functions. */ {js_InitStringClass, LAZY_ATOM(escape), NULL}, {js_InitStringClass, LAZY_ATOM(unescape), NULL}, {js_InitStringClass, LAZY_ATOM(decodeURI), NULL}, {js_InitStringClass, LAZY_ATOM(encodeURI), NULL}, {js_InitStringClass, LAZY_ATOM(decodeURIComponent), NULL}, {js_InitStringClass, LAZY_ATOM(encodeURIComponent), NULL},#if JS_HAS_UNEVAL {js_InitStringClass, LAZY_ATOM(uneval), NULL},#endif /* Exception constructors. */ {js_InitExceptionClasses, EAGER_CLASS_ATOM(Error), CLASP(Error)}, {js_InitExceptionClasses, EAGER_CLASS_ATOM(InternalError), CLASP(Error)}, {js_InitExceptionClasses, EAGER_CLASS_ATOM(EvalError), CLASP(Error)}, {js_InitExceptionClasses, EAGER_CLASS_ATOM(RangeError), CLASP(Error)}, {js_InitExceptionClasses, EAGER_CLASS_ATOM(ReferenceError), CLASP(Error)}, {js_InitExceptionClasses, EAGER_CLASS_ATOM(SyntaxError), CLASP(Error)}, {js_InitExceptionClasses, EAGER_CLASS_ATOM(TypeError), CLASP(Error)}, {js_InitExceptionClasses, EAGER_CLASS_ATOM(URIError), CLASP(Error)},#if JS_HAS_XML_SUPPORT {js_InitAnyNameClass, EAGER_ATOM_AND_CLASP(AnyName)}, {js_InitAttributeNameClass, EAGER_ATOM_AND_CLASP(AttributeName)}, {js_InitXMLClass, LAZY_ATOM(XMLList), &js_XMLClass}, {js_InitXMLClass, LAZY_ATOM(isXMLName), NULL},#endif#if JS_HAS_GENERATORS {js_InitIteratorClasses, EAGER_ATOM_AND_CLASP(Iterator)}, {js_InitIteratorClasses, EAGER_ATOM_AND_CLASP(Generator)},#endif {NULL, 0, NULL, NULL}};static JSStdName object_prototype_names[] = { /* Object.prototype properties (global delegates to Object.prototype). */ {js_InitObjectClass, EAGER_ATOM(proto), NULL}, {js_InitObjectClass, EAGER_ATOM(parent), NULL},
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -