| Index: test/cctest/test-api.cc
|
| diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
|
| index 2093dbb29295db0389cb3ca1e50c506cf822347f..b4f962c1415544ca8812ab299a4cc27d9279cd6c 100644
|
| --- a/test/cctest/test-api.cc
|
| +++ b/test/cctest/test-api.cc
|
| @@ -805,66 +805,211 @@ THREADED_TEST(GlobalProperties) {
|
| }
|
|
|
|
|
| +template<typename T>
|
| +static void CheckReturnValue(const T& t) {
|
| + v8::ReturnValue<v8::Value> rv = t.GetReturnValue();
|
| + i::Object** o = *reinterpret_cast<i::Object***>(&rv);
|
| + CHECK_EQ(t.GetIsolate(), v8::Isolate::GetCurrent());
|
| + CHECK((*o)->IsTheHole() || (*o)->IsUndefined());
|
| +}
|
| +
|
| static v8::Handle<Value> handle_call(const v8::Arguments& args) {
|
| ApiTestFuzzer::Fuzz();
|
| + CheckReturnValue(args);
|
| + args.GetReturnValue().Set(v8_str("bad value"));
|
| return v8_num(102);
|
| }
|
|
|
| +static v8::Handle<Value> handle_call_indirect(const v8::Arguments& args) {
|
| + ApiTestFuzzer::Fuzz();
|
| + CheckReturnValue(args);
|
| + args.GetReturnValue().Set(v8_str("bad value"));
|
| + args.GetReturnValue().Set(v8_num(102));
|
| + return v8::Handle<Value>();
|
| +}
|
| +
|
| +static void handle_callback(const v8::FunctionCallbackInfo<Value>& info) {
|
| + ApiTestFuzzer::Fuzz();
|
| + CheckReturnValue(info);
|
| + info.GetReturnValue().Set(v8_str("bad value"));
|
| + info.GetReturnValue().Set(v8_num(102));
|
| +}
|
| +
|
|
|
| static v8::Handle<Value> construct_call(const v8::Arguments& args) {
|
| ApiTestFuzzer::Fuzz();
|
| + CheckReturnValue(args);
|
| args.This()->Set(v8_str("x"), v8_num(1));
|
| args.This()->Set(v8_str("y"), v8_num(2));
|
| + args.GetReturnValue().Set(v8_str("bad value"));
|
| return args.This();
|
| }
|
|
|
| -static v8::Handle<Value> Return239(Local<String> name, const AccessorInfo&) {
|
| +static v8::Handle<Value> construct_call_indirect(const v8::Arguments& args) {
|
| + ApiTestFuzzer::Fuzz();
|
| + CheckReturnValue(args);
|
| + args.This()->Set(v8_str("x"), v8_num(1));
|
| + args.This()->Set(v8_str("y"), v8_num(2));
|
| + args.GetReturnValue().Set(v8_str("bad value"));
|
| + args.GetReturnValue().Set(args.This());
|
| + return v8::Handle<Value>();
|
| +}
|
| +
|
| +static void construct_callback(
|
| + const v8::FunctionCallbackInfo<Value>& info) {
|
| + ApiTestFuzzer::Fuzz();
|
| + CheckReturnValue(info);
|
| + info.This()->Set(v8_str("x"), v8_num(1));
|
| + info.This()->Set(v8_str("y"), v8_num(2));
|
| + info.GetReturnValue().Set(v8_str("bad value"));
|
| + info.GetReturnValue().Set(info.This());
|
| +}
|
| +
|
| +
|
| +static v8::Handle<Value> Return239(
|
| + Local<String> name, const AccessorInfo& info) {
|
| ApiTestFuzzer::Fuzz();
|
| + CheckReturnValue(info);
|
| + info.GetReturnValue().Set(v8_str("bad value"));
|
| return v8_num(239);
|
| }
|
|
|
| +static v8::Handle<Value> Return239Indirect(
|
| + Local<String> name, const AccessorInfo& info) {
|
| + ApiTestFuzzer::Fuzz();
|
| + CheckReturnValue(info);
|
| + Handle<Value> value = v8_num(239);
|
| + info.GetReturnValue().Set(v8_str("bad value"));
|
| + info.GetReturnValue().Set(value);
|
| + return v8::Handle<Value>();
|
| +}
|
|
|
| -THREADED_TEST(FunctionTemplate) {
|
| - LocalContext env;
|
| - v8::HandleScope scope(env->GetIsolate());
|
| +static void Return239Callback(
|
| + Local<String> name, const v8::PropertyCallbackInfo<Value>& info) {
|
| + ApiTestFuzzer::Fuzz();
|
| + CheckReturnValue(info);
|
| + info.GetReturnValue().Set(v8_str("bad value"));
|
| + info.GetReturnValue().Set(v8_num(239));
|
| +}
|
| +
|
| +
|
| +template<typename Handler>
|
| +static void TestFunctionTemplateInitializer(Handler handler) {
|
| + // Test constructor calls.
|
| {
|
| + LocalContext env;
|
| + v8::HandleScope scope(env->GetIsolate());
|
| Local<v8::FunctionTemplate> fun_templ =
|
| - v8::FunctionTemplate::New(handle_call);
|
| + v8::FunctionTemplate::New(handler);
|
| Local<Function> fun = fun_templ->GetFunction();
|
| env->Global()->Set(v8_str("obj"), fun);
|
| Local<Script> script = v8_compile("obj()");
|
| - CHECK_EQ(102, script->Run()->Int32Value());
|
| + for (int i = 0; i < 30; i++) {
|
| + CHECK_EQ(102, script->Run()->Int32Value());
|
| + }
|
| }
|
| // Use SetCallHandler to initialize a function template, should work like the
|
| // previous one.
|
| {
|
| + LocalContext env;
|
| + v8::HandleScope scope(env->GetIsolate());
|
| Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
|
| - fun_templ->SetCallHandler(handle_call);
|
| + fun_templ->SetCallHandler(handler);
|
| Local<Function> fun = fun_templ->GetFunction();
|
| env->Global()->Set(v8_str("obj"), fun);
|
| Local<Script> script = v8_compile("obj()");
|
| - CHECK_EQ(102, script->Run()->Int32Value());
|
| + for (int i = 0; i < 30; i++) {
|
| + CHECK_EQ(102, script->Run()->Int32Value());
|
| + }
|
| }
|
| - // Test constructor calls.
|
| - {
|
| - Local<v8::FunctionTemplate> fun_templ =
|
| - v8::FunctionTemplate::New(construct_call);
|
| - fun_templ->SetClassName(v8_str("funky"));
|
| - fun_templ->InstanceTemplate()->SetAccessor(v8_str("m"), Return239);
|
| - Local<Function> fun = fun_templ->GetFunction();
|
| - env->Global()->Set(v8_str("obj"), fun);
|
| - Local<Script> script = v8_compile("var s = new obj(); s.x");
|
| +}
|
| +
|
| +
|
| +template<typename Constructor, typename Accessor>
|
| +static void TestFunctionTemplateAccessor(Constructor constructor,
|
| + Accessor accessor) {
|
| + LocalContext env;
|
| + v8::HandleScope scope(env->GetIsolate());
|
| + Local<v8::FunctionTemplate> fun_templ =
|
| + v8::FunctionTemplate::New(constructor);
|
| + fun_templ->SetClassName(v8_str("funky"));
|
| + fun_templ->InstanceTemplate()->SetAccessor(v8_str("m"), accessor);
|
| + Local<Function> fun = fun_templ->GetFunction();
|
| + env->Global()->Set(v8_str("obj"), fun);
|
| + Local<Value> result = v8_compile("(new obj()).toString()")->Run();
|
| + CHECK_EQ(v8_str("[object funky]"), result);
|
| + CompileRun("var obj_instance = new obj();");
|
| + Local<Script> script;
|
| + script = v8_compile("obj_instance.x");
|
| + for (int i = 0; i < 30; i++) {
|
| CHECK_EQ(1, script->Run()->Int32Value());
|
| + }
|
| + script = v8_compile("obj_instance.m");
|
| + for (int i = 0; i < 30; i++) {
|
| + CHECK_EQ(239, script->Run()->Int32Value());
|
| + }
|
| +}
|
| +
|
| +
|
| +THREADED_TEST(FunctionTemplate) {
|
| + TestFunctionTemplateInitializer(handle_call);
|
| + TestFunctionTemplateInitializer(handle_call_indirect);
|
| + TestFunctionTemplateInitializer(handle_callback);
|
| +
|
| + TestFunctionTemplateAccessor(construct_call, Return239);
|
| + TestFunctionTemplateAccessor(construct_call_indirect, Return239Indirect);
|
| + TestFunctionTemplateAccessor(construct_callback, Return239Callback);
|
| +}
|
| +
|
| +
|
| +static v8::Handle<v8::Value> SimpleDirectCallback(const v8::Arguments& args) {
|
| + ApiTestFuzzer::Fuzz();
|
| + CheckReturnValue(args);
|
| + args.GetReturnValue().Set(v8_str("bad value"));
|
| + return v8_num(51423 + args.Length());
|
| +}
|
| +
|
| +static v8::Handle<v8::Value> SimpleIndirectCallback(const v8::Arguments& args) {
|
| + ApiTestFuzzer::Fuzz();
|
| + CheckReturnValue(args);
|
| + args.GetReturnValue().Set(v8_num(51423 + args.Length()));
|
| + return v8::Handle<v8::Value>();
|
| +}
|
| +
|
| +static void SimpleCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
|
| + ApiTestFuzzer::Fuzz();
|
| + CheckReturnValue(info);
|
| + info.GetReturnValue().Set(v8_num(51423 + info.Length()));
|
| +}
|
|
|
| - Local<Value> result = v8_compile("(new obj()).toString()")->Run();
|
| - CHECK_EQ(v8_str("[object funky]"), result);
|
|
|
| - result = v8_compile("(new obj()).m")->Run();
|
| - CHECK_EQ(239, result->Int32Value());
|
| +template<typename Callback>
|
| +static void TestSimpleCallback(Callback callback) {
|
| + LocalContext env;
|
| + v8::HandleScope scope(env->GetIsolate());
|
| + v8::Handle<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New();
|
| + object_template->Set("callback", v8::FunctionTemplate::New(callback));
|
| + v8::Local<v8::Object> object = object_template->NewInstance();
|
| + (*env)->Global()->Set(v8_str("callback_object"), object);
|
| + v8::Handle<v8::Script> script;
|
| + script = v8_compile("callback_object.callback(17)");
|
| + for (int i = 0; i < 30; i++) {
|
| + CHECK_EQ(51424, script->Run()->Int32Value());
|
| + }
|
| + script = v8_compile("callback_object.callback(17, 24)");
|
| + for (int i = 0; i < 30; i++) {
|
| + CHECK_EQ(51425, script->Run()->Int32Value());
|
| }
|
| }
|
|
|
|
|
| +THREADED_TEST(SimpleCallback) {
|
| + TestSimpleCallback(SimpleDirectCallback);
|
| + TestSimpleCallback(SimpleIndirectCallback);
|
| + TestSimpleCallback(SimpleCallback);
|
| +}
|
| +
|
| +
|
| THREADED_TEST(FunctionTemplateSetLength) {
|
| LocalContext env;
|
| v8::HandleScope scope(env->GetIsolate());
|
| @@ -4649,7 +4794,10 @@ THREADED_TEST(SetterOnly) {
|
| THREADED_TEST(NoAccessors) {
|
| v8::HandleScope scope(v8::Isolate::GetCurrent());
|
| Local<ObjectTemplate> templ = ObjectTemplate::New();
|
| - templ->SetAccessor(v8_str("x"), NULL, NULL, v8_str("donut"));
|
| + templ->SetAccessor(v8_str("x"),
|
| + static_cast<v8::AccessorGetter>(NULL),
|
| + NULL,
|
| + v8_str("donut"));
|
| LocalContext context;
|
| context->Global()->Set(v8_str("obj"), templ->NewInstance());
|
| Local<Script> script = Script::Compile(v8_str("obj.x = 4; obj.x"));
|
| @@ -5308,8 +5456,7 @@ THREADED_TEST(UndetectableObject) {
|
| LocalContext env;
|
| v8::HandleScope scope(env->GetIsolate());
|
|
|
| - Local<v8::FunctionTemplate> desc =
|
| - v8::FunctionTemplate::New(0, v8::Handle<Value>());
|
| + Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New();
|
| desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable
|
|
|
| Local<v8::Object> obj = desc->GetFunction()->NewInstance();
|
| @@ -5352,8 +5499,7 @@ THREADED_TEST(VoidLiteral) {
|
| LocalContext env;
|
| v8::HandleScope scope(env->GetIsolate());
|
|
|
| - Local<v8::FunctionTemplate> desc =
|
| - v8::FunctionTemplate::New(0, v8::Handle<Value>());
|
| + Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New();
|
| desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable
|
|
|
| Local<v8::Object> obj = desc->GetFunction()->NewInstance();
|
| @@ -5396,8 +5542,7 @@ THREADED_TEST(ExtensibleOnUndetectable) {
|
| LocalContext env;
|
| v8::HandleScope scope(env->GetIsolate());
|
|
|
| - Local<v8::FunctionTemplate> desc =
|
| - v8::FunctionTemplate::New(0, v8::Handle<Value>());
|
| + Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New();
|
| desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable
|
|
|
| Local<v8::Object> obj = desc->GetFunction()->NewInstance();
|
| @@ -10398,6 +10543,7 @@ THREADED_TEST(InterceptorCallICCachedFromGlobal) {
|
| static v8::Handle<Value> InterceptorCallICFastApi(Local<String> name,
|
| const AccessorInfo& info) {
|
| ApiTestFuzzer::Fuzz();
|
| + CheckReturnValue(info);
|
| int* call_count =
|
| reinterpret_cast<int*>(v8::External::Cast(*info.Data())->Value());
|
| ++(*call_count);
|
| @@ -10410,6 +10556,7 @@ static v8::Handle<Value> InterceptorCallICFastApi(Local<String> name,
|
| static v8::Handle<Value> FastApiCallback_TrivialSignature(
|
| const v8::Arguments& args) {
|
| ApiTestFuzzer::Fuzz();
|
| + CheckReturnValue(args);
|
| v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
| CHECK_EQ(isolate, args.GetIsolate());
|
| CHECK_EQ(args.This(), args.Holder());
|
| @@ -10420,6 +10567,7 @@ static v8::Handle<Value> FastApiCallback_TrivialSignature(
|
| static v8::Handle<Value> FastApiCallback_SimpleSignature(
|
| const v8::Arguments& args) {
|
| ApiTestFuzzer::Fuzz();
|
| + CheckReturnValue(args);
|
| v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
| CHECK_EQ(isolate, args.GetIsolate());
|
| CHECK_EQ(args.This()->GetPrototype(), args.Holder());
|
| @@ -10497,29 +10645,59 @@ THREADED_TEST(CallICFastApi_DirectCall_Throw) {
|
| }
|
|
|
|
|
| -v8::Handle<v8::Value> DirectGetterCallback(Local<String> name,
|
| - const v8::AccessorInfo& info) {
|
| +static Handle<Value> DoDirectGetter() {
|
| if (++p_getter_count % 3 == 0) {
|
| HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
|
| GenerateSomeGarbage();
|
| }
|
| + return v8_str("Direct Getter Result");
|
| +}
|
| +
|
| +static v8::Handle<v8::Value> DirectGetter(Local<String> name,
|
| + const v8::AccessorInfo& info) {
|
| + CheckReturnValue(info);
|
| + info.GetReturnValue().Set(v8_str("Garbage"));
|
| + return DoDirectGetter();
|
| +}
|
| +
|
| +static v8::Handle<v8::Value> DirectGetterIndirect(
|
| + Local<String> name,
|
| + const v8::AccessorInfo& info) {
|
| + CheckReturnValue(info);
|
| + info.GetReturnValue().Set(DoDirectGetter());
|
| return v8::Handle<v8::Value>();
|
| }
|
|
|
| +static void DirectGetterCallback(
|
| + Local<String> name,
|
| + const v8::PropertyCallbackInfo<v8::Value>& info) {
|
| + CheckReturnValue(info);
|
| + info.GetReturnValue().Set(DoDirectGetter());
|
| +}
|
|
|
| -THREADED_TEST(LoadICFastApi_DirectCall_GCMoveStub) {
|
| +
|
| +template<typename Accessor>
|
| +static void LoadICFastApi_DirectCall_GCMoveStub(Accessor accessor) {
|
| LocalContext context;
|
| v8::HandleScope scope(context->GetIsolate());
|
| v8::Handle<v8::ObjectTemplate> obj = v8::ObjectTemplate::New();
|
| - obj->SetAccessor(v8_str("p1"), DirectGetterCallback);
|
| + obj->SetAccessor(v8_str("p1"), accessor);
|
| context->Global()->Set(v8_str("o1"), obj->NewInstance());
|
| p_getter_count = 0;
|
| - CompileRun(
|
| + v8::Handle<v8::Value> result = CompileRun(
|
| "function f() {"
|
| " for (var i = 0; i < 30; i++) o1.p1;"
|
| + " return o1.p1"
|
| "}"
|
| "f();");
|
| - CHECK_EQ(30, p_getter_count);
|
| + CHECK_EQ(v8_str("Direct Getter Result"), result);
|
| + CHECK_EQ(31, p_getter_count);
|
| +}
|
| +
|
| +THREADED_TEST(LoadICFastApi_DirectCall_GCMoveStub) {
|
| + LoadICFastApi_DirectCall_GCMoveStub(DirectGetterIndirect);
|
| + LoadICFastApi_DirectCall_GCMoveStub(DirectGetterCallback);
|
| + LoadICFastApi_DirectCall_GCMoveStub(DirectGetter);
|
| }
|
|
|
|
|
| @@ -11198,7 +11376,7 @@ THREADED_TEST(InterceptorICSetterExceptions) {
|
| THREADED_TEST(NullNamedInterceptor) {
|
| v8::HandleScope scope(v8::Isolate::GetCurrent());
|
| v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
|
| - templ->SetNamedPropertyHandler(0);
|
| + templ->SetNamedPropertyHandler(static_cast<v8::NamedPropertyGetter>(0));
|
| LocalContext context;
|
| templ->Set("x", v8_num(42));
|
| v8::Handle<v8::Object> obj = templ->NewInstance();
|
| @@ -11213,7 +11391,7 @@ THREADED_TEST(NullNamedInterceptor) {
|
| THREADED_TEST(NullIndexedInterceptor) {
|
| v8::HandleScope scope(v8::Isolate::GetCurrent());
|
| v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
|
| - templ->SetIndexedPropertyHandler(0);
|
| + templ->SetIndexedPropertyHandler(static_cast<v8::IndexedPropertyGetter>(0));
|
| LocalContext context;
|
| templ->Set("42", v8_num(42));
|
| v8::Handle<v8::Object> obj = templ->NewInstance();
|
|
|