bool doResolve(JSHandleObject obj, JSHandleId id, unsigned flags, JSMutableHandleObject objp) { CHECK_EQUAL(resolveExitCount, 0); AutoIncrCounters incr(this); CHECK_EQUAL(obj, obj1 || obj == obj2); CHECK(JSID_IS_STRING(id)); JSFlatString *str = JS_FlattenString(cx, JSID_TO_STRING(id)); CHECK(str); JS::RootedValue v(cx); if (JS_FlatStringEqualsAscii(str, "x")) { if (obj == obj1) { /* First resolve hook invocation. */ CHECK_EQUAL(resolveEntryCount, 1); EVAL("obj2.y = true", v.address()); CHECK_SAME(v, JSVAL_TRUE); CHECK(JS_DefinePropertyById(cx, obj, id, JSVAL_FALSE, NULL, NULL, 0)); objp.set(obj); return true; } if (obj == obj2) { CHECK_EQUAL(resolveEntryCount, 4); objp.set(NULL); return true; } } else if (JS_FlatStringEqualsAscii(str, "y")) { if (obj == obj2) { CHECK_EQUAL(resolveEntryCount, 2); CHECK(JS_DefinePropertyById(cx, obj, id, JSVAL_NULL, NULL, NULL, 0)); EVAL("obj1.x", v.address()); CHECK(JSVAL_IS_VOID(v)); EVAL("obj1.y", v.address()); CHECK_SAME(v, JSVAL_ZERO); objp.set(obj); return true; } if (obj == obj1) { CHECK_EQUAL(resolveEntryCount, 3); EVAL("obj1.x", v.address()); CHECK(JSVAL_IS_VOID(v)); EVAL("obj1.y", v.address()); CHECK(JSVAL_IS_VOID(v)); EVAL("obj2.y", v.address()); CHECK(JSVAL_IS_NULL(v)); EVAL("obj2.x", v.address()); CHECK(JSVAL_IS_VOID(v)); EVAL("obj1.y = 0", v.address()); CHECK_SAME(v, JSVAL_ZERO); objp.set(obj); return true; } } CHECK(false); return false; }
bool doResolve(JSObject *obj, jsid id, uintN flags, JSObject **objp) { CHECK_EQUAL(resolveExitCount, 0); AutoIncrCounters incr(this); CHECK_EQUAL(obj, obj1 || obj == obj2); CHECK(JSID_IS_STRING(id)); JSFlatString *str = JS_FlattenString(cx, JSID_TO_STRING(id)); CHECK(str); jsval v; if (JS_FlatStringEqualsAscii(str, "x")) { if (obj == obj1) { /* First resolve hook invocation. */ CHECK_EQUAL(resolveEntryCount, 1); EVAL("obj2.y = true", &v); CHECK_SAME(v, JSVAL_TRUE); CHECK(JS_DefinePropertyById(cx, obj, id, JSVAL_FALSE, NULL, NULL, 0)); *objp = obj; return true; } if (obj == obj2) { CHECK_EQUAL(resolveEntryCount, 4); *objp = NULL; return true; } } else if (JS_FlatStringEqualsAscii(str, "y")) { if (obj == obj2) { CHECK_EQUAL(resolveEntryCount, 2); CHECK(JS_DefinePropertyById(cx, obj, id, JSVAL_NULL, NULL, NULL, 0)); EVAL("obj1.x", &v); CHECK(JSVAL_IS_VOID(v)); EVAL("obj1.y", &v); CHECK_SAME(v, JSVAL_ZERO); *objp = obj; return true; } if (obj == obj1) { CHECK_EQUAL(resolveEntryCount, 3); EVAL("obj1.x", &v); CHECK(JSVAL_IS_VOID(v)); EVAL("obj1.y", &v); CHECK(JSVAL_IS_VOID(v)); EVAL("obj2.y", &v); CHECK(JSVAL_IS_NULL(v)); EVAL("obj2.x", &v); CHECK(JSVAL_IS_VOID(v)); EVAL("obj1.y = 0", &v); CHECK_SAME(v, JSVAL_ZERO); *objp = obj; return true; } } CHECK(false); return false; }
bool doResolve(JS::HandleObject obj, JS::HandleId id, bool *resolvedp) { CHECK_EQUAL(resolveExitCount, 0); AutoIncrCounters incr(this); CHECK(obj == obj1 || obj == obj2); CHECK(JSID_IS_STRING(id)); JSFlatString *str = JS_FlattenString(cx, JSID_TO_STRING(id)); CHECK(str); JS::RootedValue v(cx); if (JS_FlatStringEqualsAscii(str, "x")) { if (obj == obj1) { /* First resolve hook invocation. */ CHECK_EQUAL(resolveEntryCount, 1); EVAL("obj2.y = true", &v); CHECK_SAME(v, JSVAL_TRUE); CHECK(JS_DefinePropertyById(cx, obj, id, JS::FalseHandleValue, 0)); *resolvedp = true; return true; } if (obj == obj2) { CHECK_EQUAL(resolveEntryCount, 4); *resolvedp = false; return true; } } else if (JS_FlatStringEqualsAscii(str, "y")) { if (obj == obj2) { CHECK_EQUAL(resolveEntryCount, 2); CHECK(JS_DefinePropertyById(cx, obj, id, JS::NullHandleValue, 0)); EVAL("obj1.x", &v); CHECK(v.isUndefined()); EVAL("obj1.y", &v); CHECK_SAME(v, JSVAL_ZERO); *resolvedp = true; return true; } if (obj == obj1) { CHECK_EQUAL(resolveEntryCount, 3); EVAL("obj1.x", &v); CHECK(v.isUndefined()); EVAL("obj1.y", &v); CHECK(v.isUndefined()); EVAL("obj2.y", &v); CHECK(v.isNull()); EVAL("obj2.x", &v); CHECK(v.isUndefined()); EVAL("obj1.y = 0", &v); CHECK_SAME(v, JSVAL_ZERO); *resolvedp = true; return true; } } CHECK(false); return false; }
template<size_t N> inline bool TryParse(JSContext *cx, const char (&input)[N], jsval filter) { AutoInflatedString str(cx); jsval v; str = input; CHECK(JS_ParseJSONWithReviver(cx, str.chars(), str.length(), filter, &v)); CHECK_SAME(v, JSVAL_NULL); return true; }
template<size_t N> inline bool TryParse(JSContext *cx, const char (&input)[N], const jsval &expected) { AutoInflatedString str(cx); jsval v; str = input; CHECK(JS_ParseJSON(cx, str.chars(), str.length(), &v)); CHECK_SAME(v, expected); return true; }
bool testIndirectEval(JSObject *scope, JSObject *g, const char *code, int expectedHits) { EXEC("hits = 0;"); { JSAutoEnterCompartment ae; CHECK(ae.enter(cx, scope)); JSString *codestr = JS_NewStringCopyZ(cx, code); CHECK(codestr); jsval argv[1] = { STRING_TO_JSVAL(codestr) }; jsval v; CHECK(JS_CallFunctionName(cx, g, "eval", 1, argv, &v)); } jsval hitsv; EVAL("hits", &hitsv); CHECK_SAME(hitsv, INT_TO_JSVAL(expectedHits)); return true; }
bool testIndirectEval(JS::HandleObject scope, const char *code) { EXEC("hits = 0;"); { JSAutoCompartment ae(cx, scope); JSString *codestr = JS_NewStringCopyZ(cx, code); CHECK(codestr); jsval argv[1] = { STRING_TO_JSVAL(codestr) }; JS::AutoArrayRooter rooter(cx, 1, argv); jsval v; CHECK(JS_CallFunctionName(cx, scope, "eval", 1, argv, &v)); } js::RootedValue hitsv(cx); EVAL("hits", hitsv.address()); CHECK_SAME(hitsv, INT_TO_JSVAL(1)); return true; }