📄 jsapi.c
字号:
}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;}JS_PUBLIC_API(JSVersion)JS_SetVersion(JSContext *cx, JSVersion version){ JSVersion oldVersion; oldVersion = cx->version; if (version == oldVersion) return oldVersion; cx->version = version;#if !JS_BUG_FALLIBLE_EQOPS if (cx->version == JSVERSION_1_2) { cx->jsop_eq = JSOP_NEW_EQ; cx->jsop_ne = JSOP_NEW_NE; } else { cx->jsop_eq = JSOP_EQ; cx->jsop_ne = JSOP_NE; }#endif /* !JS_BUG_FALLIBLE_EQOPS */ 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_DEFAULT, "default"}, {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;}JS_PUBLIC_API(uint32)JS_SetOptions(JSContext *cx, uint32 options){ uint32 oldopts = cx->options; cx->options = options; return oldopts;}JS_PUBLIC_API(uint32)JS_ToggleOptions(JSContext *cx, uint32 options){ uint32 oldopts = cx->options; cx->options ^= options; return oldopts;}JS_PUBLIC_API(const char *)JS_GetImplementationVersion(void){ return "JavaScript-C 1.5 pre-release 6 2004-01-27";}JS_PUBLIC_API(JSObject *)JS_GetGlobalObject(JSContext *cx){ return cx->globalObject;}JS_PUBLIC_API(void)JS_SetGlobalObject(JSContext *cx, JSObject *obj){ cx->globalObject = obj;}static JSObject *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) cx->globalObject = obj; /* Record Function and Object in cx->resolvingTable, if we are resolving. */ table = cx->resolvingTable; resolving = (table && table->entryCount); if (resolving) { rt = cx->runtime; key.obj = obj; key.id = (jsid) rt->atomState.FunctionAtom; 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 = (jsid) rt->atomState.ObjectAtom; 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; } /* 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. */ if (resolving) JS_DHashTableOperate(table, &key, JS_DHASH_REMOVE); return fun_proto;}JS_PUBLIC_API(JSBool)JS_InitStandardClasses(JSContext *cx, JSObject *obj){ CHECK_REQUEST(cx);#if JS_HAS_UNDEFINED{ /* Define a top-level property 'undefined' with the undefined value. */ JSAtom *atom = cx->runtime->atomState.typeAtoms[JSTYPE_VOID]; if (!OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, JSVAL_VOID, NULL, NULL, JSPROP_PERMANENT, NULL)) { return JS_FALSE; }}#endif /* Function and Object require cooperative bootstrapping magic. */ if (!InitFunctionAndObjectClasses(cx, obj)) return JS_FALSE; /* Initialize the rest of the standard objects and functions. */ return js_InitArrayClass(cx, obj) && js_InitBooleanClass(cx, obj) && js_InitMathClass(cx, obj) && js_InitNumberClass(cx, obj) && js_InitStringClass(cx, obj) &&#if JS_HAS_CALL_OBJECT js_InitCallClass(cx, obj) &&#endif#if JS_HAS_REGEXPS js_InitRegExpClass(cx, obj) &&#endif#if JS_HAS_SCRIPT_OBJECT js_InitScriptClass(cx, obj) &&#endif#if JS_HAS_ERROR_EXCEPTIONS js_InitExceptionClasses(cx, obj) &&#endif#if JS_HAS_FILE_OBJECT js_InitFileClass(cx, obj, JS_TRUE) &&#endif js_InitDateClass(cx, obj);}#define ATOM_OFFSET(name) offsetof(JSAtomState, name##Atom)#define OFFSET_TO_ATOM(rt,off) (*(JSAtom **)((char*)&(rt)->atomState + (off)))/* * Table of class initializers and their atom offsets in rt->atomState. * If you add a "standard" class, remember to update this table. */static struct { JSObjectOp init; size_t atomOffset;} standard_class_atoms[] = { {InitFunctionAndObjectClasses, ATOM_OFFSET(Function)}, {InitFunctionAndObjectClasses, ATOM_OFFSET(Object)}, {js_InitArrayClass, ATOM_OFFSET(Array)}, {js_InitBooleanClass, ATOM_OFFSET(Boolean)}, {js_InitDateClass, ATOM_OFFSET(Date)}, {js_InitMathClass, ATOM_OFFSET(Math)}, {js_InitNumberClass, ATOM_OFFSET(Number)}, {js_InitStringClass, ATOM_OFFSET(String)},#if JS_HAS_CALL_OBJECT {js_InitCallClass, ATOM_OFFSET(Call)},#endif#if JS_HAS_ERROR_EXCEPTIONS {js_InitExceptionClasses, ATOM_OFFSET(Error)},#endif#if JS_HAS_REGEXPS {js_InitRegExpClass, ATOM_OFFSET(RegExp)},#endif#if JS_HAS_SCRIPT_OBJECT {js_InitScriptClass, ATOM_OFFSET(Script)},#endif {NULL, 0}};/* * 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. */typedef struct JSStdName { JSObjectOp init; size_t atomOffset; /* offset of atom pointer in JSAtomState */ const char *name; /* null if atom is pre-pinned, else name */} 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;}#define EAGERLY_PINNED_ATOM(name) ATOM_OFFSET(name), NULL#define LAZILY_PINNED_ATOM(name) ATOM_OFFSET(lazy.name), js_##name##_strstatic JSStdName standard_class_names[] = { /* ECMA requires that eval be a direct property of the global object. */ {js_InitObjectClass, EAGERLY_PINNED_ATOM(eval)}, /* Global properties and functions defined by the Number class. */ {js_InitNumberClass, LAZILY_PINNED_ATOM(NaN)}, {js_InitNumberClass, LAZILY_PINNED_ATOM(Infinity)}, {js_InitNumberClass, LAZILY_PINNED_ATOM(isNaN)}, {js_InitNumberClass, LAZILY_PINNED_ATOM(isFinite)}, {js_InitNumberClass, LAZILY_PINNED_ATOM(parseFloat)}, {js_InitNumberClass, LAZILY_PINNED_ATOM(parseInt)}, /* String global functions. */ {js_InitStringClass, LAZILY_PINNED_ATOM(escape)}, {js_InitStringClass, LAZILY_PINNED_ATOM(unescape)}, {js_InitStringClass, LAZILY_PINNED_ATOM(decodeURI)}, {js_InitStringClass, LAZILY_PINNED_ATOM(encodeURI)}, {js_InitStringClass, LAZILY_PINNED_ATOM(decodeURIComponent)}, {js_InitStringClass, LAZILY_PINNED_ATOM(encodeURIComponent)},#if JS_HAS_UNEVAL {js_InitStringClass, LAZILY_PINNED_ATOM(uneval)},#endif /* Exception constructors. */#if JS_HAS_ERROR_EXCEPTIONS {js_InitExceptionClasses, EAGERLY_PINNED_ATOM(Error)}, {js_InitExceptionClasses, LAZILY_PINNED_ATOM(InternalError)}, {js_InitExceptionClasses, LAZILY_PINNED_ATOM(EvalError)}, {js_InitExceptionClasses, LAZILY_PINNED_ATOM(RangeError)}, {js_InitExceptionClasses, LAZILY_PINNED_ATOM(ReferenceError)}, {js_InitExceptionClasses, LAZILY_PINNED_ATOM(SyntaxError)}, {js_InitExceptionClasses, LAZILY_PINNED_ATOM(TypeError)}, {js_InitExceptionClasses, LAZILY_PINNED_ATOM(URIError)},#endif {NULL, 0, NULL}};static JSStdName object_prototype_names[] = { /* Object.prototype properties (global delegates to Object.prototype). */ {js_InitObjectClass, EAGERLY_PINNED_ATOM(proto)}, {js_InitObjectClass, EAGERLY_PINNED_ATOM(parent)}, {js_InitObjectClass, EAGERLY_PINNED_ATOM(count)},#if JS_HAS_TOSOURCE {js_InitObjectClass, EAGERLY_PINNED_ATOM(toSource)},#endif {js_InitObjectClass, EAGERLY_PINNED_ATOM(toString)}, {js_InitObjectClass, EAGERLY_PINNED_ATOM(toLocaleString)}, {js_InitObjectClass, EAGERLY_PINNED_ATOM(valueOf)},#if JS_HAS_OBJ_WATCHPOINT {js_InitObjectClass, LAZILY_PINNED_ATOM(watch)}, {js_InitObjectClass, LAZILY_PINNED_ATOM(unwatch)},#endif#if JS_HAS_NEW_OBJ_METHODS {js_InitObjectClass, LAZILY_PINNED_ATOM(hasOwnProperty)}, {js_InitObjectClass, LAZILY_PINNED_ATOM(isPrototypeOf)}, {js_InitObjectClass, LAZILY_PINNED_ATOM(propertyIsEnumerable)},#endif#if JS_HAS_GETTER_SETTER {js_InitObjectClass, LAZILY_PINNED_ATOM(defineGetter)}, {js_InitObjectClass, LAZILY_PINNED_ATOM(defineSetter)}, {js_InitObjectClass, LAZILY_PINNED_ATOM(lookupGetter)}, {js_InitObjectClass, LAZILY_PINNED_ATOM(lookupSetter)},#endif {NULL, 0, NULL}};#undef EAGERLY_PINNED_ATOM#undef LAZILY_PINNED_ATOMJS_PUBLIC_API(JSBool)JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsval id, JSBool *resolved){ JSString *idstr; JSRuntime *rt; JSAtom *atom; JSObjectOp init; uintN i; CHECK_REQUEST(cx); *resolved = JS_FALSE; if (!JSVAL_IS_STRING(id)) return JS_TRUE; idstr = JSVAL_TO_STRING(id); rt = cx->runtime;#if JS_HAS_UNDEFINED /* See if we're resolving 'undefined', and define it if so. */ atom = rt->atomState.typeAtoms[JSTYPE_VOID]; if (idstr == ATOM_TO_STRING(atom)) { *resolved = JS_TRUE; return OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, JSVAL_VOID, NULL, NULL, JSPROP_PERMANENT, NULL); }#endif /* Try for class constructors/prototypes named by well-known atoms. */ init = NULL; for (i = 0; standard_class_atoms[i].init; i++) { atom = OFFSET_TO_ATOM(rt, standard_class_atoms[i].atomOffset); if (idstr == ATOM_TO_STRING(atom)) { init = standard_class_atoms[i].init; break; } } if (!init) { /* Try less frequently used top-level functions and constants. */ for (i = 0; standard_class_names[i].init; i++) { atom = StdNameToAtom(cx, &standard_class_names[i]); if (!atom) return JS_FALSE; if (idstr == ATOM_TO_STRING(atom)) { init = standard_class_names[i].init; break; } } if (!init && !OBJ_GET_PROTO(cx, obj)) { /* * Try even less frequently used names delegated from the global * object to Object.prototype, but only if the Object class hasn't * yet been initialized. */ for (i = 0; object_prototype_names[i].init; i++) { atom = StdNameToAtom(cx, &object_prototype_names[i]); if (!atom) return JS_FALSE; if (idstr == ATOM_TO_STRING(atom)) { init = standard_class_names[i].init; break; } } } } if (init) { if (!init(cx, obj)) return JS_FALSE; *resolved = JS_TRUE; } return JS_TRUE;}static JSBoolHasOwnProperty(JSContext *cx, JSObject *obj, JSAtom *atom, JSBool *ownp){ JSObject *pobj; JSProperty *prop; if (!OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, &pobj, &prop)) return JS_FALSE; if (prop) OBJ_DROP_PROPERTY(cx, pobj, prop); *ownp = (pobj == obj && prop); return JS_TRUE;}JS_PUBLIC_API(JSBool)JS_EnumerateStandardClasses(JSContext *cx, JSObject *obj){ JSRuntime *rt; JSAtom *atom; JSBool found; uintN i; CHECK_REQUEST(cx); rt = cx->runtime;#if JS_HAS_UNDEFINED /* See if we need to bind 'undefined' and define it if so. */ atom = rt->atomState.typeAtoms[JSTYPE_VOID]; if (!HasOwnProperty(cx, obj, atom, &found)) return JS_FALSE; if (!found && !OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, JSVAL_VOID, NULL, NULL, JSPROP_PERMANENT, NULL)) { return JS_FALSE; }#endif /* Initialize any classes that have not been resolved yet. */ for (i = 0; standard_class_atoms[i].init; i++) { atom = OFFSET_TO_ATOM(rt, standard_class_atoms[i].atomOffset); if (!HasOwnProperty(cx, obj, atom, &found)) return JS_FALSE; if (!found && !standard_class_atoms[i].init(cx, obj)) return JS_FALSE; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -