Index: test/cctest/test-receiver-check-hidden-prototype.cc |
diff --git a/test/cctest/test-receiver-check-hidden-prototype.cc b/test/cctest/test-receiver-check-hidden-prototype.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..90ed8e7b56d724361df0907421d4e0a584f6ed86 |
--- /dev/null |
+++ b/test/cctest/test-receiver-check-hidden-prototype.cc |
@@ -0,0 +1,73 @@ |
+// Copyright 2014 the V8 project authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <stdlib.h> |
+ |
+#include "include/v8-experimental.h" |
+#include "src/v8.h" |
+#include "test/cctest/cctest.h" |
+ |
+namespace { |
+ |
+ |
+static void SlowCallback(const v8::FunctionCallbackInfo<v8::Value>& info) { |
+ info.GetReturnValue().Set(41); |
+} |
+ |
+ |
+TEST(CompatibleReceiverBuiltin) { |
+ // Check that the HandleFastApiCall builtin visits the hidden prototypes |
+ // during the compatible receiver check. |
+ LocalContext context; |
+ v8::Isolate* isolate = context->GetIsolate(); |
+ v8::HandleScope handle_scope(isolate); |
+ v8::Local<v8::Context> current_context = isolate->GetCurrentContext(); |
+ |
+ v8::Local<v8::FunctionTemplate> constructor_template = |
+ v8::FunctionTemplate::New(isolate); |
+ v8::Local<v8::FunctionTemplate> prototype_template = |
+ v8::FunctionTemplate::New(isolate); |
+ prototype_template->SetHiddenPrototype(true); |
+ |
+ v8::Local<v8::ObjectTemplate> proto_instance_template = |
+ prototype_template->InstanceTemplate(); |
+ |
+ v8::experimental::FastAccessorBuilder* fast_accessor_builder = |
+ v8::experimental::FastAccessorBuilder::New(isolate); |
+ fast_accessor_builder->ReturnValue( |
+ fast_accessor_builder->IntegerConstant(42)); |
+ v8::Local<v8::FunctionTemplate> accessor_template = |
+ v8::FunctionTemplate::NewWithFastHandler( |
+ isolate, SlowCallback, fast_accessor_builder, v8::Local<v8::Value>(), |
+ v8::Signature::New(isolate, prototype_template)); |
+ |
+ proto_instance_template->SetAccessorProperty( |
+ v8_str("bar"), accessor_template, v8::Local<v8::FunctionTemplate>(), |
+ v8::ReadOnly); |
+ |
+ v8::Local<v8::Object> object = |
+ constructor_template->GetFunction(current_context) |
+ .ToLocalChecked() |
+ ->NewInstance(current_context) |
+ .ToLocalChecked(); |
+ |
+ v8::Local<v8::Object> hidden_prototype = |
+ prototype_template->GetFunction(current_context) |
+ .ToLocalChecked() |
+ ->NewInstance(current_context) |
+ .ToLocalChecked(); |
+ |
+ CHECK(object->SetPrototype(current_context, hidden_prototype).FromJust()); |
+ |
+ context->Global() |
+ ->Set(current_context, v8_str("object"), object) |
+ .FromMaybe(false); |
+ |
+ CHECK_EQ(42, CompileRun("var getter = object.__lookupGetter__('bar');" |
+ "getter.call(object)") |
+ ->Int32Value(current_context) |
+ .FromJust()); |
+} |
+ |
+} // namespace |