| Index: test/cctest/test-api.cc
|
| diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
|
| index 9f79a4379432f3d99d36e7f33c495e2f6c1f2d39..1e572ba95bbecc7ad9f7269bd1a59b984ac7779c 100644
|
| --- a/test/cctest/test-api.cc
|
| +++ b/test/cctest/test-api.cc
|
| @@ -224,78 +224,98 @@ THREADED_TEST(IsolateOfContext) {
|
| }
|
|
|
|
|
| +static void TestSignature(const char* loop_js, Local<Value> receiver) {
|
| + i::ScopedVector<char> source(200);
|
| + i::OS::SNPrintF(source,
|
| + "for (var i = 0; i < 10; i++) {"
|
| + " %s"
|
| + "}",
|
| + loop_js);
|
| + signature_callback_count = 0;
|
| + signature_expected_receiver = receiver;
|
| + bool expected_to_throw = receiver.IsEmpty();
|
| + v8::TryCatch try_catch;
|
| + CompileRun(source.start());
|
| + CHECK_EQ(expected_to_throw, try_catch.HasCaught());
|
| + if (!expected_to_throw) {
|
| + CHECK_EQ(10, signature_callback_count);
|
| + } else {
|
| + CHECK_EQ(v8_str("TypeError: Illegal invocation"),
|
| + try_catch.Exception()->ToString());
|
| + }
|
| +}
|
| +
|
| +
|
| THREADED_TEST(ReceiverSignature) {
|
| LocalContext env;
|
| v8::HandleScope scope(env->GetIsolate());
|
| + // Setup templates.
|
| v8::Handle<v8::FunctionTemplate> fun = v8::FunctionTemplate::New();
|
| v8::Handle<v8::Signature> sig = v8::Signature::New(fun);
|
| - fun->PrototypeTemplate()->Set(
|
| - v8_str("m"),
|
| - v8::FunctionTemplate::New(IncrementingSignatureCallback,
|
| - v8::Handle<Value>(),
|
| - sig));
|
| - fun->PrototypeTemplate()->SetAccessorProperty(
|
| - v8_str("n"),
|
| - v8::FunctionTemplate::New(IncrementingSignatureCallback,
|
| - v8::Handle<Value>(),
|
| - sig));
|
| - env->Global()->Set(v8_str("Fun"), fun->GetFunction());
|
| - Local<Value> fun_instance = fun->InstanceTemplate()->NewInstance();
|
| - env->Global()->Set(v8_str("fun_instance"), fun_instance);
|
| - signature_callback_count = 0;
|
| - int expected_count = 0;
|
| - signature_expected_receiver = fun_instance;
|
| - CompileRun(
|
| - "var o = fun_instance;"
|
| - "var key_n = 'n';"
|
| - "for (var i = 0; i < 10; i++) o.m();"
|
| - "for (var i = 0; i < 10; i++) o.n;"
|
| - "for (var i = 0; i < 10; i++) o[key_n];");
|
| - expected_count += 30;
|
| - CHECK_EQ(expected_count, signature_callback_count);
|
| + v8::Handle<v8::FunctionTemplate> callback_sig =
|
| + v8::FunctionTemplate::New(
|
| + IncrementingSignatureCallback, Local<Value>(), sig);
|
| + v8::Handle<v8::FunctionTemplate> callback =
|
| + v8::FunctionTemplate::New(IncrementingSignatureCallback);
|
| v8::Handle<v8::FunctionTemplate> sub_fun = v8::FunctionTemplate::New();
|
| sub_fun->Inherit(fun);
|
| - fun_instance = sub_fun->InstanceTemplate()->NewInstance();
|
| - env->Global()->Set(v8_str("fun_instance"), fun_instance);
|
| - signature_expected_receiver = fun_instance;
|
| - CompileRun(
|
| - "var o = fun_instance;"
|
| - "var key_n = 'n';"
|
| - "for (var i = 0; i < 10; i++) o.m();"
|
| - "for (var i = 0; i < 10; i++) o.n;"
|
| - "for (var i = 0; i < 10; i++) o[key_n];");
|
| - expected_count += 30;
|
| - CHECK_EQ(expected_count, signature_callback_count);
|
| - v8::TryCatch try_catch;
|
| - CompileRun(
|
| - "var o = { };"
|
| - "o.m = Fun.prototype.m;"
|
| - "o.m();");
|
| - CHECK_EQ(expected_count, signature_callback_count);
|
| - CHECK(try_catch.HasCaught());
|
| - CompileRun(
|
| - "var o = { };"
|
| - "o.n = Fun.prototype.n;"
|
| - "o.n;");
|
| - CHECK_EQ(expected_count, signature_callback_count);
|
| - CHECK(try_catch.HasCaught());
|
| - try_catch.Reset();
|
| v8::Handle<v8::FunctionTemplate> unrel_fun = v8::FunctionTemplate::New();
|
| - sub_fun->Inherit(fun);
|
| + // Install properties.
|
| + v8::Handle<v8::ObjectTemplate> fun_proto = fun->PrototypeTemplate();
|
| + fun_proto->Set(v8_str("prop_sig"), callback_sig);
|
| + fun_proto->Set(v8_str("prop"), callback);
|
| + fun_proto->SetAccessorProperty(
|
| + v8_str("accessor_sig"), callback_sig, callback_sig);
|
| + fun_proto->SetAccessorProperty(v8_str("accessor"), callback, callback);
|
| + // Instantiate templates.
|
| + Local<Value> fun_instance = fun->InstanceTemplate()->NewInstance();
|
| + Local<Value> sub_fun_instance = sub_fun->InstanceTemplate()->NewInstance();
|
| + // Setup global variables.
|
| + env->Global()->Set(v8_str("Fun"), fun->GetFunction());
|
| env->Global()->Set(v8_str("UnrelFun"), unrel_fun->GetFunction());
|
| + env->Global()->Set(v8_str("fun_instance"), fun_instance);
|
| + env->Global()->Set(v8_str("sub_fun_instance"), sub_fun_instance);
|
| CompileRun(
|
| - "var o = new UnrelFun();"
|
| - "o.m = Fun.prototype.m;"
|
| - "o.m();");
|
| - CHECK_EQ(expected_count, signature_callback_count);
|
| - CHECK(try_catch.HasCaught());
|
| - try_catch.Reset();
|
| - CompileRun(
|
| - "var o = new UnrelFun();"
|
| - "o.n = Fun.prototype.n;"
|
| - "o.n;");
|
| - CHECK_EQ(expected_count, signature_callback_count);
|
| - CHECK(try_catch.HasCaught());
|
| + "var accessor_sig_key = 'accessor_sig';"
|
| + "var accessor_key = 'accessor';"
|
| + "var prop_sig_key = 'prop_sig';"
|
| + "var prop_key = 'prop';"
|
| + ""
|
| + "function copy_props(obj) {"
|
| + " var keys = [accessor_sig_key, accessor_key, prop_sig_key, prop_key];"
|
| + " var source = Fun.prototype;"
|
| + " for (var i in keys) {"
|
| + " var key = keys[i];"
|
| + " var desc = Object.getOwnPropertyDescriptor(source, key);"
|
| + " Object.defineProperty(obj, key, desc);"
|
| + " }"
|
| + "}"
|
| + ""
|
| + "var obj = {};"
|
| + "copy_props(obj);"
|
| + "var unrel = new UnrelFun();"
|
| + "copy_props(unrel);");
|
| + // Test with and without ICs
|
| + const char* test_objects[] = {
|
| + "fun_instance", "sub_fun_instance", "obj", "unrel" };
|
| + unsigned bad_signature_start_offset = 2;
|
| + for (unsigned i = 0; i < ARRAY_SIZE(test_objects); i++) {
|
| + i::ScopedVector<char> source(200);
|
| + i::OS::SNPrintF(
|
| + source, "var test_object = %s; test_object", test_objects[i]);
|
| + Local<Value> test_object = CompileRun(source.start());
|
| + TestSignature("test_object.prop();", test_object);
|
| + TestSignature("test_object.accessor;", test_object);
|
| + TestSignature("test_object[accessor_key];", test_object);
|
| + TestSignature("test_object.accessor = 1;", test_object);
|
| + TestSignature("test_object[accessor_key] = 1;", test_object);
|
| + if (i >= bad_signature_start_offset) test_object = Local<Value>();
|
| + TestSignature("test_object.prop_sig();", test_object);
|
| + TestSignature("test_object.accessor_sig;", test_object);
|
| + TestSignature("test_object[accessor_sig_key];", test_object);
|
| + TestSignature("test_object.accessor_sig = 1;", test_object);
|
| + TestSignature("test_object[accessor_sig_key] = 1;", test_object);
|
| + }
|
| }
|
|
|
|
|
|
|