jsinterp.c
来自「java script test programing source code」· C语言 代码 · 共 1,863 行 · 第 1/5 页
C
1,863 行
fp->sp = oldsp; if (oldfp != fp) cx->fp = oldfp; return ok;}JSBooljs_InternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, jsval fval, JSAccessMode mode, uintN argc, jsval *argv, jsval *rval){ int stackDummy; /* * js_InternalInvoke could result in another try to get or set the same id * again, see bug 355497. */ if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_OVER_RECURSED); return JS_FALSE; } /* * Check general (not object-ops/class-specific) access from the running * script to obj.id only if id has a scripted getter or setter that we're * about to invoke. If we don't check this case, nothing else will -- no * other native code has the chance to check. * * Contrast this non-native (scripted) case with native getter and setter * accesses, where the native itself must do an access check, if security * policies requires it. We make a checkAccess or checkObjectAccess call * back to the embedding program only in those cases where we're not going * to call an embedding-defined native function, getter, setter, or class * hook anyway. Where we do call such a native, there's no need for the * engine to impose a separate access check callback on all embeddings -- * many embeddings have no security policy at all. */ JS_ASSERT(mode == JSACC_READ || mode == JSACC_WRITE); if (cx->runtime->checkObjectAccess && VALUE_IS_FUNCTION(cx, fval) && FUN_INTERPRETED((JSFunction *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(fval))) && !cx->runtime->checkObjectAccess(cx, obj, ID_TO_VALUE(id), mode, &fval)) { return JS_FALSE; } return js_InternalCall(cx, obj, fval, argc, argv, rval);}JSBooljs_Execute(JSContext *cx, JSObject *chain, JSScript *script, JSStackFrame *down, uintN flags, jsval *result){ JSInterpreterHook hook; void *hookData, *mark; JSStackFrame *oldfp, frame; JSObject *obj, *tmp; JSBool ok; hook = cx->runtime->executeHook; hookData = mark = NULL; oldfp = cx->fp; frame.script = script; if (down) { /* Propagate arg/var state for eval and the debugger API. */ frame.callobj = down->callobj; frame.argsobj = down->argsobj; frame.varobj = down->varobj; frame.fun = down->fun; frame.thisp = down->thisp; frame.argc = down->argc; frame.argv = down->argv; frame.nvars = down->nvars; frame.vars = down->vars; frame.annotation = down->annotation; frame.sharpArray = down->sharpArray; } else { frame.callobj = frame.argsobj = NULL; obj = chain; if (cx->options & JSOPTION_VAROBJFIX) { while ((tmp = OBJ_GET_PARENT(cx, obj)) != NULL) obj = tmp; } frame.varobj = obj; frame.fun = NULL; frame.thisp = chain; frame.argc = 0; frame.argv = NULL; frame.nvars = script->numGlobalVars; if (frame.nvars) { frame.vars = js_AllocRawStack(cx, frame.nvars, &mark); if (!frame.vars) return JS_FALSE; memset(frame.vars, 0, frame.nvars * sizeof(jsval)); } else { frame.vars = NULL; } frame.annotation = NULL; frame.sharpArray = NULL; } frame.rval = JSVAL_VOID; frame.down = down; frame.scopeChain = chain; frame.pc = NULL; frame.sp = oldfp ? oldfp->sp : NULL; frame.spbase = NULL; frame.sharpDepth = 0; frame.flags = flags; frame.dormantNext = NULL; frame.xmlNamespace = NULL; frame.blockChain = NULL; /* * Here we wrap the call to js_Interpret with code to (conditionally) * save and restore the old stack frame chain into a chain of 'dormant' * frame chains. Since we are replacing cx->fp, we were running into * the problem that if GC was called under this frame, some of the GC * things associated with the old frame chain (available here only in * the C variable 'oldfp') were not rooted and were being collected. * * So, now we preserve the links to these 'dormant' frame chains in cx * before calling js_Interpret and cleanup afterwards. The GC walks * these dormant chains and marks objects in the same way that it marks * objects in the primary cx->fp chain. */ if (oldfp && oldfp != down) { JS_ASSERT(!oldfp->dormantNext); oldfp->dormantNext = cx->dormantFrameChain; cx->dormantFrameChain = oldfp; } cx->fp = &frame; if (hook) hookData = hook(cx, &frame, JS_TRUE, 0, cx->runtime->executeHookData); /* * Use frame.rval, not result, so the last result stays rooted across any * GC activations nested within this js_Interpret. */ ok = js_Interpret(cx, script->code, &frame.rval); *result = frame.rval; if (hookData) { hook = cx->runtime->executeHook; if (hook) hook(cx, &frame, JS_FALSE, &ok, hookData); } if (mark) js_FreeRawStack(cx, mark); cx->fp = oldfp; if (oldfp && oldfp != down) { JS_ASSERT(cx->dormantFrameChain == oldfp); cx->dormantFrameChain = oldfp->dormantNext; oldfp->dormantNext = NULL; } return ok;}#if JS_HAS_EXPORT_IMPORT/* * If id is JSVAL_VOID, import all exported properties from obj. */static JSBoolImportProperty(JSContext *cx, JSObject *obj, jsid id){ JSBool ok; JSIdArray *ida; JSProperty *prop; JSObject *obj2, *target, *funobj, *closure; JSString *str; uintN attrs; jsint i; jsval value; if (JSVAL_IS_VOID(id)) { ida = JS_Enumerate(cx, obj); if (!ida) return JS_FALSE; ok = JS_TRUE; if (ida->length == 0) goto out; } else { ida = NULL; if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop)) return JS_FALSE; if (!prop) { str = js_DecompileValueGenerator(cx, JSDVG_IGNORE_STACK, ID_TO_VALUE(id), NULL); if (str) js_ReportIsNotDefined(cx, JS_GetStringBytes(str)); return JS_FALSE; } ok = OBJ_GET_ATTRIBUTES(cx, obj, id, prop, &attrs); OBJ_DROP_PROPERTY(cx, obj2, prop); if (!ok) return JS_FALSE; if (!(attrs & JSPROP_EXPORTED)) { str = js_DecompileValueGenerator(cx, JSDVG_IGNORE_STACK, ID_TO_VALUE(id), NULL); if (str) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NOT_EXPORTED, JS_GetStringBytes(str)); } return JS_FALSE; } } target = cx->fp->varobj; i = 0; do { if (ida) { id = ida->vector[i]; ok = OBJ_GET_ATTRIBUTES(cx, obj, id, NULL, &attrs); if (!ok) goto out; if (!(attrs & JSPROP_EXPORTED)) continue; } ok = OBJ_CHECK_ACCESS(cx, obj, id, JSACC_IMPORT, &value, &attrs); if (!ok) goto out; if (VALUE_IS_FUNCTION(cx, value)) { funobj = JSVAL_TO_OBJECT(value); closure = js_CloneFunctionObject(cx, funobj, obj); if (!closure) { ok = JS_FALSE; goto out; } value = OBJECT_TO_JSVAL(closure); } /* * Handle the case of importing a property that refers to a local * variable or formal parameter of a function activation. These * properties are accessed by opcodes using stack slot numbers * generated by the compiler rather than runtime name-lookup. These * local references, therefore, bypass the normal scope chain lookup. * So, instead of defining a new property in the activation object, * modify the existing value in the stack slot. */ if (OBJ_GET_CLASS(cx, target) == &js_CallClass) { ok = OBJ_LOOKUP_PROPERTY(cx, target, id, &obj2, &prop); if (!ok) goto out; } else { prop = NULL; } if (prop && target == obj2) { ok = OBJ_SET_PROPERTY(cx, target, id, &value); } else { ok = OBJ_DEFINE_PROPERTY(cx, target, id, value, NULL, NULL, attrs & ~(JSPROP_EXPORTED | JSPROP_GETTER | JSPROP_SETTER), NULL); } if (prop) OBJ_DROP_PROPERTY(cx, obj2, prop); if (!ok) goto out; } while (ida && ++i < ida->length);out: if (ida) JS_DestroyIdArray(cx, ida); return ok;}#endif /* JS_HAS_EXPORT_IMPORT */JSBooljs_CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs, JSObject **objp, JSProperty **propp){ JSObject *obj2; JSProperty *prop; uintN oldAttrs, report; JSBool isFunction; jsval value; const char *type, *name; if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop)) return JS_FALSE; if (propp) { *objp = obj2; *propp = prop; } if (!prop) return JS_TRUE; /* * Use prop as a speedup hint to OBJ_GET_ATTRIBUTES, but drop it on error. * An assertion at label bad: will insist that it is null. */ if (!OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &oldAttrs)) { OBJ_DROP_PROPERTY(cx, obj2, prop);#ifdef DEBUG prop = NULL;#endif goto bad; } /* * From here, return true, or else goto bad on failure to null out params. * If our caller doesn't want prop, drop it (we don't need it any longer). */ if (!propp) { OBJ_DROP_PROPERTY(cx, obj2, prop); prop = NULL; } /* If either property is readonly, we have an error. */ report = ((oldAttrs | attrs) & JSPROP_READONLY) ? JSREPORT_ERROR : JSREPORT_WARNING | JSREPORT_STRICT; if (report != JSREPORT_ERROR) { /* * Allow redeclaration of variables and functions, but insist that the * new value is not a getter if the old value was, ditto for setters -- * unless prop is impermanent (in which case anyone could delete it and * redefine it, willy-nilly). */ if (!(attrs & (JSPROP_GETTER | JSPROP_SETTER))) return JS_TRUE; if ((~(oldAttrs ^ attrs) & (JSPROP_GETTER | JSPROP_SETTER)) == 0) return JS_TRUE; if (!(oldAttrs & JSPROP_PERMANENT)) return JS_TRUE; report = JSREPORT_ERROR; } isFunction = (oldAttrs & (JSPROP_GETTER | JSPROP_SETTER)) != 0; if (!isFunction) { if (!OBJ_GET_PROPERTY(cx, obj, id, &value)) goto bad; isFunction = VALUE_IS_FUNCTION(cx, value); } type = (oldAttrs & attrs & JSPROP_GETTER) ? js_getter_str : (oldAttrs & attrs & JSPROP_SETTER) ? js_setter_str : (oldAttrs & JSPROP_READONLY) ? js_const_str : isFunction ? js_function_str : js_var_str; name = js_AtomToPrintableString(cx, JSID_TO_ATOM(id)); if (!name) goto bad; return JS_ReportErrorFlagsAndNumber(cx, report, js_GetErrorMessage, NULL, JSMSG_REDECLARED_VAR, type, name);bad: if (propp) { *objp = NULL; *propp = NULL; } JS_ASSERT(!prop); return JS_FALSE;}JSBooljs_StrictlyEqual(jsval lval, jsval rval){ jsval ltag = JSVAL_TAG(lval), rt
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?