| 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
|
|
|