📄 test-api.cc
字号:
int32_t int32_value = obj->Int32Value(); CHECK_EQ(0, int32_value); CheckUncle(&try_catch); uint32_t uint32_value = obj->Uint32Value(); CHECK_EQ(0, uint32_value); CheckUncle(&try_catch); double number_value = obj->NumberValue(); CHECK_NE(0, IsNaN(number_value)); CheckUncle(&try_catch); int64_t integer_value = obj->IntegerValue(); CHECK_EQ(0.0, static_cast<double>(integer_value)); CheckUncle(&try_catch);}v8::Handle<Value> ThrowFromC(const v8::Arguments& args) { ApiTestFuzzer::Fuzz(); return v8::ThrowException(v8_str("konto"));}THREADED_TEST(APICatch) { v8::HandleScope scope; Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->Set(v8_str("ThrowFromC"), v8::FunctionTemplate::New(ThrowFromC)); LocalContext context(0, templ); CompileRun( "var thrown = false;" "try {" " ThrowFromC();" "} catch (e) {" " thrown = true;" "}"); Local<Value> thrown = context->Global()->Get(v8_str("thrown")); CHECK(thrown->BooleanValue());}THREADED_TEST(ExternalScriptException) { v8::HandleScope scope; Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->Set(v8_str("ThrowFromC"), v8::FunctionTemplate::New(ThrowFromC)); LocalContext context(0, templ); v8::TryCatch try_catch; Local<Script> script = Script::Compile(v8_str("ThrowFromC(); throw 'panama';")); Local<Value> result = script->Run(); CHECK(result.IsEmpty()); CHECK(try_catch.HasCaught()); String::AsciiValue exception_value(try_catch.Exception()); CHECK_EQ("konto", *exception_value);}v8::Handle<Value> CThrowCountDown(const v8::Arguments& args) { ApiTestFuzzer::Fuzz(); CHECK_EQ(4, args.Length()); int count = args[0]->Int32Value(); int cInterval = args[2]->Int32Value(); if (count == 0) { return v8::ThrowException(v8_str("FromC")); } else { Local<v8::Object> global = Context::GetCurrent()->Global(); Local<Value> fun = global->Get(v8_str("JSThrowCountDown")); v8::Handle<Value> argv[] = { v8_num(count - 1), args[1], args[2], args[3] }; if (count % cInterval == 0) { v8::TryCatch try_catch; Local<Value> result = v8::Handle<Function>::Cast(fun)->Call(global, 4, argv); int expected = args[3]->Int32Value(); if (try_catch.HasCaught()) { CHECK_EQ(expected, count); CHECK(!i::Top::has_scheduled_exception()); } else { CHECK_NE(expected, count); } return result; } else { return v8::Handle<Function>::Cast(fun)->Call(global, 4, argv); } }}v8::Handle<Value> JSCheck(const v8::Arguments& args) { ApiTestFuzzer::Fuzz(); CHECK_EQ(3, args.Length()); bool equality = args[0]->BooleanValue(); int count = args[1]->Int32Value(); int expected = args[2]->Int32Value(); if (equality) { CHECK_EQ(count, expected); } else { CHECK_NE(count, expected); } return v8::Undefined();}// This test works by making a stack of alternating JavaScript and C// activations. These activations set up exception handlers with regular// intervals, one interval for C activations and another for JavaScript// activations. When enough activations have been created an exception is// thrown and we check that the right activation catches the exception and that// no other activations do. The right activation is always the topmost one with// a handler, regardless of whether it is in JavaScript or C.//// The notation used to describe a test case looks like this://// *JS[4] *C[3] @JS[2] C[1] JS[0]//// Each entry is an activation, either JS or C. The index is the count at that// level. Stars identify activations with exception handlers, the @ identifies// the exception handler that should catch the exception.THREADED_TEST(ExceptionOrder) { v8::HandleScope scope; Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->Set(v8_str("check"), v8::FunctionTemplate::New(JSCheck)); templ->Set(v8_str("CThrowCountDown"), v8::FunctionTemplate::New(CThrowCountDown)); LocalContext context(0, templ); CompileRun( "function JSThrowCountDown(count, jsInterval, cInterval, expected) {" " if (count == 0) throw 'FromJS';" " if (count % jsInterval == 0) {" " try {" " var value = CThrowCountDown(count - 1," " jsInterval," " cInterval," " expected);" " check(false, count, expected);" " return value;" " } catch (e) {" " check(true, count, expected);" " }" " } else {" " return CThrowCountDown(count - 1, jsInterval, cInterval, expected);" " }" "}"); Local<Function> fun = Local<Function>::Cast(context->Global()->Get(v8_str("JSThrowCountDown"))); const int argc = 4; // count jsInterval cInterval expected // *JS[4] *C[3] @JS[2] C[1] JS[0] v8::Handle<Value> a0[argc] = { v8_num(4), v8_num(2), v8_num(3), v8_num(2) }; fun->Call(fun, argc, a0); // JS[5] *C[4] JS[3] @C[2] JS[1] C[0] v8::Handle<Value> a1[argc] = { v8_num(5), v8_num(6), v8_num(1), v8_num(2) }; fun->Call(fun, argc, a1); // JS[6] @C[5] JS[4] C[3] JS[2] C[1] JS[0] v8::Handle<Value> a2[argc] = { v8_num(6), v8_num(7), v8_num(5), v8_num(5) }; fun->Call(fun, argc, a2); // @JS[6] C[5] JS[4] C[3] JS[2] C[1] JS[0] v8::Handle<Value> a3[argc] = { v8_num(6), v8_num(6), v8_num(7), v8_num(6) }; fun->Call(fun, argc, a3); // JS[6] *C[5] @JS[4] C[3] JS[2] C[1] JS[0] v8::Handle<Value> a4[argc] = { v8_num(6), v8_num(4), v8_num(5), v8_num(4) }; fun->Call(fun, argc, a4); // JS[6] C[5] *JS[4] @C[3] JS[2] C[1] JS[0] v8::Handle<Value> a5[argc] = { v8_num(6), v8_num(4), v8_num(3), v8_num(3) }; fun->Call(fun, argc, a5);}v8::Handle<Value> ThrowValue(const v8::Arguments& args) { ApiTestFuzzer::Fuzz(); CHECK_EQ(1, args.Length()); return v8::ThrowException(args[0]);}THREADED_TEST(ThrowValues) { v8::HandleScope scope; Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->Set(v8_str("Throw"), v8::FunctionTemplate::New(ThrowValue)); LocalContext context(0, templ); v8::Handle<v8::Array> result = v8::Handle<v8::Array>::Cast(CompileRun( "function Run(obj) {" " try {" " Throw(obj);" " } catch (e) {" " return e;" " }" " return 'no exception';" "}" "[Run('str'), Run(1), Run(0), Run(null), Run(void 0)];")); CHECK_EQ(5, result->Length()); CHECK(result->Get(v8::Integer::New(0))->IsString()); CHECK(result->Get(v8::Integer::New(1))->IsNumber()); CHECK_EQ(1, result->Get(v8::Integer::New(1))->Int32Value()); CHECK(result->Get(v8::Integer::New(2))->IsNumber()); CHECK_EQ(0, result->Get(v8::Integer::New(2))->Int32Value()); CHECK(result->Get(v8::Integer::New(3))->IsNull()); CHECK(result->Get(v8::Integer::New(4))->IsUndefined());}THREADED_TEST(CatchZero) { v8::HandleScope scope; LocalContext context; v8::TryCatch try_catch; CHECK(!try_catch.HasCaught()); Script::Compile(v8_str("throw 10"))->Run(); CHECK(try_catch.HasCaught()); CHECK_EQ(10, try_catch.Exception()->Int32Value()); try_catch.Reset(); CHECK(!try_catch.HasCaught()); Script::Compile(v8_str("throw 0"))->Run(); CHECK(try_catch.HasCaught()); CHECK_EQ(0, try_catch.Exception()->Int32Value());}THREADED_TEST(CatchExceptionFromWith) { v8::HandleScope scope; LocalContext context; v8::TryCatch try_catch; CHECK(!try_catch.HasCaught()); Script::Compile(v8_str("var o = {}; with (o) { throw 42; }"))->Run(); CHECK(try_catch.HasCaught());}THREADED_TEST(Equality) { v8::HandleScope scope; LocalContext context; // Check that equality works at all before relying on CHECK_EQ CHECK(v8_str("a")->Equals(v8_str("a"))); CHECK(!v8_str("a")->Equals(v8_str("b"))); CHECK_EQ(v8_str("a"), v8_str("a")); CHECK_NE(v8_str("a"), v8_str("b")); CHECK_EQ(v8_num(1), v8_num(1)); CHECK_EQ(v8_num(1.00), v8_num(1)); CHECK_NE(v8_num(1), v8_num(2)); // Assume String is not symbol. CHECK(v8_str("a")->StrictEquals(v8_str("a"))); CHECK(!v8_str("a")->StrictEquals(v8_str("b"))); CHECK(!v8_str("5")->StrictEquals(v8_num(5))); CHECK(v8_num(1)->StrictEquals(v8_num(1))); CHECK(!v8_num(1)->StrictEquals(v8_num(2))); CHECK(v8_num(0)->StrictEquals(v8_num(-0))); Local<Value> not_a_number = v8_num(i::OS::nan_value()); CHECK(!not_a_number->StrictEquals(not_a_number)); CHECK(v8::False()->StrictEquals(v8::False())); CHECK(!v8::False()->StrictEquals(v8::Undefined())); v8::Handle<v8::Object> obj = v8::Object::New(); v8::Persistent<v8::Object> alias = v8::Persistent<v8::Object>::New(obj); CHECK(alias->StrictEquals(obj)); alias.Dispose();}THREADED_TEST(MultiRun) { v8::HandleScope scope; LocalContext context; Local<Script> script = Script::Compile(v8_str("x")); for (int i = 0; i < 10; i++) script->Run();}static v8::Handle<Value> GetXValue(Local<String> name, const AccessorInfo& info) { ApiTestFuzzer::Fuzz(); CHECK_EQ(info.Data(), v8_str("donut")); CHECK_EQ(name, v8_str("x")); return name;}THREADED_TEST(SimplePropertyRead) { v8::HandleScope scope; Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")); LocalContext context; context->Global()->Set(v8_str("obj"), templ->NewInstance()); Local<Script> script = Script::Compile(v8_str("obj.x")); for (int i = 0; i < 10; i++) { Local<Value> result = script->Run(); CHECK_EQ(result, v8_str("x")); }}v8::Persistent<Value> xValue;static void SetXValue(Local<String> name, Local<Value> value, const AccessorInfo& info) { CHECK_EQ(value, v8_num(4)); CHECK_EQ(info.Data(), v8_str("donut")); CHECK_EQ(name, v8_str("x")); CHECK(xValue.IsEmpty()); xValue = v8::Persistent<Value>::New(value);}THREADED_TEST(SimplePropertyWrite) { v8::HandleScope scope; Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetAccessor(v8_str("x"), GetXValue, SetXValue, v8_str("donut")); LocalContext context; context->Global()->Set(v8_str("obj"), templ->NewInstance()); Local<Script> script = Script::Compile(v8_str("obj.x = 4")); for (int i = 0; i < 10; i++) { CHECK(xValue.IsEmpty()); script->Run(); CHECK_EQ(v8_num(4), xValue); xValue.Dispose(); xValue = v8::Persistent<Value>(); }}static v8::Handle<Value> XPropertyGetter(Local<String> property, const AccessorInfo& info) { ApiTestFuzzer::Fuzz(); CHECK(info.Data()->IsUndefined()); return property;}THREADED_TEST(NamedInterceporPropertyRead) { v8::HandleScope scope; Local<ObjectTemplate> templ = ObjectTemplate::New(); templ->SetNamedPropertyHandler(XPropertyGetter); LocalContext context; context->Global()->Set(v8_str("obj"), templ->NewInstance()); Local<Script> script = Script::Compile(v8_str("obj.x")); for (int i = 0; i < 10; i++) { Local<Value> result = script->Run(); CHECK_EQ(result, v8_str("x")); }}THREADED_TEST(MultiContexts) { v8::HandleScope scope; v8::Handle<ObjectTemplate> templ = ObjectTemplate::New(); templ->Set(v8_str("dummy"), v8::FunctionTemplate::New(DummyCallHandler)); Local<String> password = v8_str("Password"); // Create an environment LocalContext context0(0, templ); context0->SetSecurityToken(password); v8::Handle<v8::Object> global0 = context0->Global(); global0->Set(v8_str("custom"), v8_num(1234)); CHECK_EQ(1234, global0->Get(v8_str("custom"))->Int32Value()); // Create an independent environment LocalContext context1(0, templ); context1->SetSecurityToken(password); v8::Handle<v8::Object> global1 = context1->Global(); global1->Set(v8_str("custom"), v8_num(1234)); CHECK_NE(global0, global1); CHECK_EQ(1234, global0->Get(v8_str("custom"))->Int32Value()); CHECK_EQ(1234, global1->Get(v8_str("custom"))->Int32Value()); // Now create a new context with the old global LocalContext context2(0, templ, global1); context2->SetSecurityToken(password); v8::Handle<v8::Object> global2 = context2->Global(); CHECK_EQ(global1, global2); CHECK_EQ(0, global1->Get(v8_str("custom"))->Int32Value()); CHECK_EQ(0, global2->Get(v8_str("custom"))->Int32Value());}THREADED_TEST(FunctionPrototypeAcrossContexts) { // Make sure that functions created by cloning boilerplates cannot // communicate through their __proto__ field. v8::HandleScope scope; LocalContext env0; v8::Handle<v8::Object> global0 = env0->Global(); v8::Handle<v8::Object> object0 =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -