📄 jsobj.c
字号:
val = argv + 2; for (i = 0, length = ida->length; i < length; i++) { JSBool idIsLexicalIdentifier, needOldStyleGetterSetter; /* Get strings for id and value and GC-root them via argv. */ id = ida->vector[i];#if JS_HAS_GETTER_SETTER ok = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop); if (!ok) goto error;#endif /* * Convert id to a jsval and then to a string. Decide early whether we * prefer get/set or old getter/setter syntax. */ atom = JSID_IS_ATOM(id) ? JSID_TO_ATOM(id) : NULL; idstr = js_ValueToString(cx, ID_TO_VALUE(id)); if (!idstr) { ok = JS_FALSE; OBJ_DROP_PROPERTY(cx, obj2, prop); goto error; } *rval = STRING_TO_JSVAL(idstr); /* local root */ idIsLexicalIdentifier = js_IsIdentifier(idstr); needOldStyleGetterSetter = !idIsLexicalIdentifier || js_CheckKeyword(JSSTRING_CHARS(idstr), JSSTRING_LENGTH(idstr)) != TOK_EOF;#if JS_HAS_GETTER_SETTER valcnt = 0; if (prop) { ok = OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &attrs); if (!ok) { OBJ_DROP_PROPERTY(cx, obj2, prop); goto error; } if (OBJ_IS_NATIVE(obj2) && (attrs & (JSPROP_GETTER | JSPROP_SETTER))) { if (attrs & JSPROP_GETTER) { val[valcnt] = (jsval) ((JSScopeProperty *)prop)->getter; gsopold[valcnt] = ATOM_TO_STRING(cx->runtime->atomState.getterAtom); gsop[valcnt] = ATOM_TO_STRING(cx->runtime->atomState.getAtom); valcnt++; } if (attrs & JSPROP_SETTER) { val[valcnt] = (jsval) ((JSScopeProperty *)prop)->setter; gsopold[valcnt] = ATOM_TO_STRING(cx->runtime->atomState.setterAtom); gsop[valcnt] = ATOM_TO_STRING(cx->runtime->atomState.setAtom); valcnt++; } } else { valcnt = 1; gsop[0] = NULL; gsopold[0] = NULL; ok = OBJ_GET_PROPERTY(cx, obj, id, &val[0]); } OBJ_DROP_PROPERTY(cx, obj2, prop); }#else /* !JS_HAS_GETTER_SETTER */ /* * We simplify the source code at the price of minor dead code bloat in * the ECMA version (for testing only, see jsconfig.h). The null * default values in gsop[j] suffice to disable non-ECMA getter and * setter code. */ valcnt = 1; gsop[0] = NULL; gsopold[0] = NULL; ok = OBJ_GET_PROPERTY(cx, obj, id, &val[0]);#endif /* !JS_HAS_GETTER_SETTER */ if (!ok) goto error; /* * If id is a string that's not an identifier, then it needs to be * quoted. Also, negative integer ids must be quoted. */ if (atom ? !idIsLexicalIdentifier : (JSID_IS_OBJECT(id) || JSID_TO_INT(id) < 0)) { idstr = js_QuoteString(cx, idstr, (jschar)'\''); if (!idstr) { ok = JS_FALSE; goto error; } *rval = STRING_TO_JSVAL(idstr); /* local root */ } idstrchars = JSSTRING_CHARS(idstr); idstrlength = JSSTRING_LENGTH(idstr); for (j = 0; j < valcnt; j++) { /* Convert val[j] to its canonical source form. */ valstr = js_ValueToSource(cx, val[j]); if (!valstr) { ok = JS_FALSE; goto error; } argv[j] = STRING_TO_JSVAL(valstr); /* local root */ vchars = JSSTRING_CHARS(valstr); vlength = JSSTRING_LENGTH(valstr); if (vchars[0] == '#') needOldStyleGetterSetter = JS_TRUE; if (needOldStyleGetterSetter) gsop[j] = gsopold[j];#ifndef OLD_GETTER_SETTER /* * Remove '(function ' from the beginning of valstr and ')' from the * end so that we can put "get" in front of the function definition. */ if (gsop[j] && VALUE_IS_FUNCTION(cx, val[j]) && !needOldStyleGetterSetter) { const jschar *start = vchars; if (vchars[0] == '(') vchars++; vchars = js_strchr_limit(vchars, '(', vchars + vlength); if (vchars) { vlength -= vchars - start + 1; } else { gsop[j] = NULL; vchars = start; } }#else needOldStyleGetterSetter = JS_TRUE; gsop[j] = gsopold[j];#endif /* If val[j] is a non-sharp object, consider sharpening it. */ vsharp = NULL; vsharplength = 0;#if JS_HAS_SHARP_VARS if (!JSVAL_IS_PRIMITIVE(val[j]) && vchars[0] != '#') { he = js_EnterSharpObject(cx, JSVAL_TO_OBJECT(val[j]), NULL, &vsharp); if (!he) { ok = JS_FALSE; goto error; } if (IS_SHARP(he)) { vchars = vsharp; vlength = js_strlen(vchars); needOldStyleGetterSetter = JS_TRUE; gsop[j] = gsopold[j]; } else { if (vsharp) { vsharplength = js_strlen(vsharp); MAKE_SHARP(he); needOldStyleGetterSetter = JS_TRUE; gsop[j] = gsopold[j]; } js_LeaveSharpObject(cx, NULL); } }#endif#define SAFE_ADD(n) \ JS_BEGIN_MACRO \ size_t n_ = (n); \ curlen += n_; \ if (curlen < n_) \ goto overflow; \ JS_END_MACRO curlen = nchars; if (comma) SAFE_ADD(2); SAFE_ADD(idstrlength + 1); if (gsop[j]) SAFE_ADD(JSSTRING_LENGTH(gsop[j]) + 1); SAFE_ADD(vsharplength); SAFE_ADD(vlength); /* Account for the trailing null. */ SAFE_ADD((outermost ? 2 : 1) + 1);#undef SAFE_ADD if (curlen > (size_t)-1 / sizeof(jschar)) goto overflow; /* Allocate 1 + 1 at end for closing brace and terminating 0. */ chars = (jschar *) realloc((ochars = chars), curlen * sizeof(jschar)); if (!chars) { /* Save code space on error: let JS_free ignore null vsharp. */ JS_free(cx, vsharp); free(ochars); goto error; } if (comma) { chars[nchars++] = comma[0]; chars[nchars++] = comma[1]; } comma = ", "; if (needOldStyleGetterSetter) { js_strncpy(&chars[nchars], idstrchars, idstrlength); nchars += idstrlength; if (gsop[j]) { chars[nchars++] = ' '; gsoplength = JSSTRING_LENGTH(gsop[j]); js_strncpy(&chars[nchars], JSSTRING_CHARS(gsop[j]), gsoplength); nchars += gsoplength; } chars[nchars++] = ':'; } else { /* New style "decompilation" */ if (gsop[j]) { gsoplength = JSSTRING_LENGTH(gsop[j]); js_strncpy(&chars[nchars], JSSTRING_CHARS(gsop[j]), gsoplength); nchars += gsoplength; chars[nchars++] = ' '; } js_strncpy(&chars[nchars], idstrchars, idstrlength); nchars += idstrlength; /* Extraneous space after id here will be extracted later */ chars[nchars++] = gsop[j] ? ' ' : ':'; } if (vsharplength) { js_strncpy(&chars[nchars], vsharp, vsharplength); nchars += vsharplength; } js_strncpy(&chars[nchars], vchars, vlength); nchars += vlength; if (vsharp) JS_free(cx, vsharp);#ifdef DUMP_CALL_TABLE if (outermost && nchars >= js_LogCallToSourceLimit) break;#endif } } chars[nchars++] = '}'; if (outermost) chars[nchars++] = ')'; chars[nchars] = 0; error: js_LeaveSharpObject(cx, &ida); if (!ok) { if (chars) free(chars); return ok; } if (!chars) { JS_ReportOutOfMemory(cx); return JS_FALSE; } make_string: str = js_NewString(cx, chars, nchars, 0); if (!str) { free(chars); return JS_FALSE; } *rval = STRING_TO_JSVAL(str); return JS_TRUE; overflow: JS_free(cx, vsharp); free(chars); chars = NULL; goto error;}#endif /* JS_HAS_TOSOURCE */JSBooljs_obj_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ jschar *chars; size_t nchars; const char *clazz, *prefix; JSString *str; clazz = OBJ_GET_CLASS(cx, obj)->name; nchars = 9 + strlen(clazz); /* 9 for "[object ]" */ chars = (jschar *) JS_malloc(cx, (nchars + 1) * sizeof(jschar)); if (!chars) return JS_FALSE; prefix = "[object "; nchars = 0; while ((chars[nchars] = (jschar)*prefix) != 0) nchars++, prefix++; while ((chars[nchars] = (jschar)*clazz) != 0) nchars++, clazz++; chars[nchars++] = ']'; chars[nchars] = 0; str = js_NewString(cx, chars, nchars, 0); if (!str) { JS_free(cx, chars); return JS_FALSE; } *rval = STRING_TO_JSVAL(str); return JS_TRUE;}static JSBooljs_obj_toLocaleString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSString *str; str = js_ValueToString(cx, argv[-1]); if (!str) return JS_FALSE; *rval = STRING_TO_JSVAL(str); return JS_TRUE;}static JSBoolobj_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ *rval = OBJECT_TO_JSVAL(obj); return JS_TRUE;}/* * Check whether principals subsumes scopeobj's principals, and return true * if so (or if scopeobj has no principals, for backward compatibility with * the JS API, which does not require principals), and false otherwise. */JSBooljs_CheckPrincipalsAccess(JSContext *cx, JSObject *scopeobj, JSPrincipals *principals, JSAtom *caller){ JSRuntime *rt; JSPrincipals *scopePrincipals; const char *callerstr; rt = cx->runtime; if (rt->findObjectPrincipals) { scopePrincipals = rt->findObjectPrincipals(cx, scopeobj); if (!principals || !scopePrincipals || !principals->subsume(principals, scopePrincipals)) { callerstr = js_AtomToPrintableString(cx, caller); if (!callerstr) return JS_FALSE; JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_INDIRECT_CALL, callerstr); return JS_FALSE; } } return JS_TRUE;}JSObject *js_CheckScopeChainValidity(JSContext *cx, JSObject *scopeobj, const char *caller){ JSClass *clasp; JSExtendedClass *xclasp; JSObject *inner; if (!scopeobj) goto bad; OBJ_TO_INNER_OBJECT(cx, scopeobj); if (!scopeobj) return NULL; inner = scopeobj; /* XXX This is an awful gross hack. */ while (scopeobj) { clasp = OBJ_GET_CLASS(cx, scopeobj); if (clasp->flags & JSCLASS_IS_EXTENDED) { xclasp = (JSExtendedClass*)clasp; if (xclasp->innerObject && xclasp->innerObject(cx, scopeobj) != scopeobj) { goto bad; } } scopeobj = OBJ_GET_PARENT(cx, scopeobj); } return inner;bad: JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_INDIRECT_CALL, caller); return NULL;}static JSBoolobj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSStackFrame *fp, *caller; JSBool indirectCall; JSObject *scopeobj; JSString *str; const char *file; uintN line;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -