📄 test-api.cc
字号:
LocalContext env; env->Global()->Set(v8_str("obj"), templ->GetFunction()->NewInstance()); CHECK_EQ(echo_named_call_count, 0); v8_compile("obj.x")->Run(); CHECK_EQ(echo_named_call_count, 1); const char* code = "var str = 'oddle'; obj[str] + obj.poddle;"; v8::Handle<Value> str = CompileRun(code); String::AsciiValue value(str); CHECK_EQ(*value, "oddlepoddle"); // Check default behavior CHECK_EQ(v8_compile("obj.flob = 10;")->Run()->Int32Value(), 10); CHECK(v8_compile("'myProperty' in obj")->Run()->BooleanValue()); CHECK(v8_compile("delete obj.myProperty")->Run()->BooleanValue());}int echo_indexed_call_count = 0;static v8::Handle<Value> EchoIndexedProperty(uint32_t index, const AccessorInfo& info) { ApiTestFuzzer::Fuzz(); CHECK_EQ(v8_num(637), info.Data()); echo_indexed_call_count++; return v8_num(index);}THREADED_TEST(IndexedPropertyHandlerGetter) { v8::HandleScope scope; v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); templ->InstanceTemplate()->SetIndexedPropertyHandler(EchoIndexedProperty, 0, 0, 0, 0, v8_num(637)); LocalContext env; env->Global()->Set(v8_str("obj"), templ->GetFunction()->NewInstance()); Local<Script> script = v8_compile("obj[900]"); CHECK_EQ(script->Run()->Int32Value(), 900);}v8::Handle<v8::Object> bottom;static v8::Handle<Value> CheckThisIndexedPropertyHandler( uint32_t index, const AccessorInfo& info) { ApiTestFuzzer::Fuzz(); CHECK(info.This()->Equals(bottom)); return v8::Handle<Value>();}static v8::Handle<Value> CheckThisNamedPropertyHandler( Local<String> name, const AccessorInfo& info) { ApiTestFuzzer::Fuzz(); CHECK(info.This()->Equals(bottom)); return v8::Handle<Value>();}v8::Handle<Value> CheckThisIndexedPropertySetter(uint32_t index, Local<Value> value, const AccessorInfo& info) { ApiTestFuzzer::Fuzz(); CHECK(info.This()->Equals(bottom)); return v8::Handle<Value>();}v8::Handle<Value> CheckThisNamedPropertySetter(Local<String> property, Local<Value> value, const AccessorInfo& info) { ApiTestFuzzer::Fuzz(); CHECK(info.This()->Equals(bottom)); return v8::Handle<Value>();}v8::Handle<v8::Boolean> CheckThisIndexedPropertyQuery( uint32_t index, const AccessorInfo& info) { ApiTestFuzzer::Fuzz(); CHECK(info.This()->Equals(bottom)); return v8::Handle<v8::Boolean>();}v8::Handle<v8::Boolean> CheckThisNamedPropertyQuery(Local<String> property, const AccessorInfo& info) { ApiTestFuzzer::Fuzz(); CHECK(info.This()->Equals(bottom)); return v8::Handle<v8::Boolean>();}v8::Handle<v8::Boolean> CheckThisIndexedPropertyDeleter( uint32_t index, const AccessorInfo& info) { ApiTestFuzzer::Fuzz(); CHECK(info.This()->Equals(bottom)); return v8::Handle<v8::Boolean>();}v8::Handle<v8::Boolean> CheckThisNamedPropertyDeleter( Local<String> property, const AccessorInfo& info) { ApiTestFuzzer::Fuzz(); CHECK(info.This()->Equals(bottom)); return v8::Handle<v8::Boolean>();}v8::Handle<v8::Array> CheckThisIndexedPropertyEnumerator( const AccessorInfo& info) { ApiTestFuzzer::Fuzz(); CHECK(info.This()->Equals(bottom)); return v8::Handle<v8::Array>();}v8::Handle<v8::Array> CheckThisNamedPropertyEnumerator( const AccessorInfo& info) { ApiTestFuzzer::Fuzz(); CHECK(info.This()->Equals(bottom)); return v8::Handle<v8::Array>();}THREADED_TEST(PropertyHandlerInPrototype) { v8::HandleScope scope; LocalContext env; // Set up a prototype chain with three interceptors. v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); templ->InstanceTemplate()->SetIndexedPropertyHandler( CheckThisIndexedPropertyHandler, CheckThisIndexedPropertySetter, CheckThisIndexedPropertyQuery, CheckThisIndexedPropertyDeleter, CheckThisIndexedPropertyEnumerator); templ->InstanceTemplate()->SetNamedPropertyHandler( CheckThisNamedPropertyHandler, CheckThisNamedPropertySetter, CheckThisNamedPropertyQuery, CheckThisNamedPropertyDeleter, CheckThisNamedPropertyEnumerator); bottom = templ->GetFunction()->NewInstance(); Local<v8::Object> top = templ->GetFunction()->NewInstance(); Local<v8::Object> middle = templ->GetFunction()->NewInstance(); bottom->Set(v8_str("__proto__"), middle); middle->Set(v8_str("__proto__"), top); env->Global()->Set(v8_str("obj"), bottom); // Indexed and named get. Script::Compile(v8_str("obj[0]"))->Run(); Script::Compile(v8_str("obj.x"))->Run(); // Indexed and named set. Script::Compile(v8_str("obj[1] = 42"))->Run(); Script::Compile(v8_str("obj.y = 42"))->Run(); // Indexed and named query. Script::Compile(v8_str("0 in obj"))->Run(); Script::Compile(v8_str("'x' in obj"))->Run(); // Indexed and named deleter. Script::Compile(v8_str("delete obj[0]"))->Run(); Script::Compile(v8_str("delete obj.x"))->Run(); // Enumerators. Script::Compile(v8_str("for (var p in obj) ;"))->Run();}v8::Handle<Value> pre_post_global;static v8::Handle<Value> PrePropertyHandlerGet(Local<String> key, const AccessorInfo& info) { ApiTestFuzzer::Fuzz(); CHECK(info.This()->Equals(pre_post_global)); CHECK(info.Holder()->Equals(pre_post_global)); if (v8_str("pre")->Equals(key)) { return v8_str("PrePropertyHandler: pre"); } return v8::Handle<String>();}static v8::Handle<v8::Boolean> PrePropertyHandlerHas(Local<String> key, const AccessorInfo&) { if (v8_str("pre")->Equals(key)) { return v8::True(); } return v8::Handle<v8::Boolean>(); // do not intercept the call}THREADED_TEST(PrePropertyHandler) { v8::HandleScope scope; v8::Handle<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(); desc->InstanceTemplate()->SetNamedPropertyHandler(PrePropertyHandlerGet, 0, PrePropertyHandlerHas); LocalContext env(NULL, desc->InstanceTemplate()); pre_post_global = env->Global(); Script::Compile(v8_str( "var pre = 'Object: pre'; var on = 'Object: on';"))->Run(); v8::Handle<Value> result_pre = Script::Compile(v8_str("pre"))->Run(); CHECK_EQ(v8_str("PrePropertyHandler: pre"), result_pre); v8::Handle<Value> result_on = Script::Compile(v8_str("on"))->Run(); CHECK_EQ(v8_str("Object: on"), result_on); v8::Handle<Value> result_post = Script::Compile(v8_str("post"))->Run(); CHECK(result_post.IsEmpty());}v8::Handle<Script> call_recursively_script;static const int kTargetRecursionDepth = 300; // near maximumstatic v8::Handle<Value> CallScriptRecursivelyCall(const v8::Arguments& args) { ApiTestFuzzer::Fuzz(); int depth = args.This()->Get(v8_str("depth"))->Int32Value(); if (depth == kTargetRecursionDepth) return v8::Undefined(); args.This()->Set(v8_str("depth"), v8::Integer::New(depth + 1)); return call_recursively_script->Run();}static v8::Handle<Value> CallFunctionRecursivelyCall( const v8::Arguments& args) { ApiTestFuzzer::Fuzz(); int depth = args.This()->Get(v8_str("depth"))->Int32Value(); if (depth == kTargetRecursionDepth) { printf("[depth = %d]\n", depth); return v8::Undefined(); } args.This()->Set(v8_str("depth"), v8::Integer::New(depth + 1)); v8::Handle<Value> function = args.This()->Get(v8_str("callFunctionRecursively")); return v8::Handle<Function>::Cast(function)->Call(args.This(), 0, NULL);}THREADED_TEST(DeepCrossLanguageRecursion) { v8::HandleScope scope; v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New(); global->Set(v8_str("callScriptRecursively"), v8::FunctionTemplate::New(CallScriptRecursivelyCall)); global->Set(v8_str("callFunctionRecursively"), v8::FunctionTemplate::New(CallFunctionRecursivelyCall)); LocalContext env(NULL, global); env->Global()->Set(v8_str("depth"), v8::Integer::New(0)); call_recursively_script = v8_compile("callScriptRecursively()"); v8::Handle<Value> result = call_recursively_script->Run(); call_recursively_script = v8::Handle<Script>(); env->Global()->Set(v8_str("depth"), v8::Integer::New(0)); Script::Compile(v8_str("callFunctionRecursively()"))->Run();}static v8::Handle<Value> ThrowingPropertyHandlerGet(Local<String> key, const AccessorInfo&) { ApiTestFuzzer::Fuzz(); return v8::ThrowException(key);}static v8::Handle<Value> ThrowingPropertyHandlerSet(Local<String> key, Local<Value>, const AccessorInfo&) { v8::ThrowException(key); return v8::Undefined(); // not the same as v8::Handle<v8::Value>()}THREADED_TEST(CallbackExceptionRegression) { v8::HandleScope scope; v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); obj->SetNamedPropertyHandler(ThrowingPropertyHandlerGet, ThrowingPropertyHandlerSet); LocalContext env; env->Global()->Set(v8_str("obj"), obj->NewInstance()); v8::Handle<Value> otto = Script::Compile(v8_str( "try { with (obj) { otto; } } catch (e) { e; }"))->Run(); CHECK_EQ(v8_str("otto"), otto); v8::Handle<Value> netto = Script::Compile(v8_str( "try { with (obj) { netto = 4; } } catch (e) { e; }"))->Run(); CHECK_EQ(v8_str("netto"), netto);}static v8::Handle<Value> ThrowingGetAccessor(Local<String> name, const AccessorInfo& info) { ApiTestFuzzer::Fuzz(); return v8::ThrowException(v8_str("g"));}static void ThrowingSetAccessor(Local<String> name, Local<Value> value, const AccessorInfo& info) { v8::ThrowException(value);}THREADED_TEST(Regress1054726) { v8::HandleScope scope; v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); obj->SetAccessor(v8_str("x"), ThrowingGetAccessor, ThrowingSetAccessor, Local<Value>()); LocalContext env; env->Global()->Set(v8_str("obj"), obj->NewInstance()); // Use the throwing property setter/getter in a loop to force // the accessor ICs to be initialized. v8::Handle<Value> result; result = Script::Compile(v8_str( "var result = '';" "for (var i = 0; i < 5; i++) {" " try { obj.x; } catch (e) { result += e; }" "}; result"))->Run(); CHECK_EQ(v8_str("ggggg"), result); result = Script::Compile(String::New( "var result = '';" "for (var i = 0; i < 5; i++) {" " try { obj.x = i; } catch (e) { result += e; }" "}; result"))->Run(); CHECK_EQ(v8_str("01234"), result);}THREADED_TEST(FunctionPrototype) { v8::HandleScope scope; Local<v8::FunctionTemplate> Foo = v8::FunctionTemplate::New(); Foo->PrototypeTemplate()->Set(v8_str("plak"), v8_num(321)); LocalContext env; env->Global()->Set(v8_str("Foo"), Foo->GetFunction()); Local<Script> script = Script::Compile(v8_str("Foo.prototype.plak")); CHECK_EQ(script->Run()->Int32Value(), 321);}THREADED_TEST(InternalFields) { v8::HandleScope scope; Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate(); instance_templ->SetInternalFieldCount(1); LocalContext env(0, instance_templ); CHECK_EQ(1, env->Global()->InternalFieldCount()); Local<v8::Object> obj = templ->GetFunction()->NewInstance(); CHECK_EQ(1, obj->InternalFieldCount()); CHECK(obj->GetInternalField(0)->IsUndefined()); obj->SetInternalField(0, v8_num(17)); CHECK_EQ(17, obj->GetInternalField(0)->Int32Value());}THREADED_TEST(External) { v8::HandleScope scope; int x = 3; Local<v8::External> ext = v8::External::New(&x); LocalContext env; env->Global()->Set(v8_str("ext"), ext); Local<Value> reext_obj = Script::Compile(v8_str("this.ext"))->Run(); v8::Handle<v8::External> reext = v8::Handle<v8::External>::Cast(reext_obj); int* ptr = static_cast<int*>(reext->Value()); CHECK_EQ(x, 3); *ptr = 10; CHECK_EQ(x, 10);}THREADED_TEST(GlobalHandle) { v8::Persistent<String> global; { v8::HandleScope scope; Local<String> str = v8_str("str"); global = v8::Persistent<String>::New(str); } CHECK_EQ(global->Length(), 3); global.Dispose();}THREADED_TEST(ScriptException) { v8::HandleScope scope; LocalContext env; Local<Script> script = Script::Compile(v8_str("throw 'panama!';")); v8::TryCatch try_catch; Local<Value> result = script->Run(); CHECK(result.IsEmpty());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -