Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 1 | // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include <stdlib.h> |
| 6 | |
| 7 | #include "include/v8-experimental.h" |
| 8 | #include "src/v8.h" |
| 9 | #include "test/cctest/cctest.h" |
| 10 | |
| 11 | namespace { |
| 12 | |
| 13 | |
| 14 | static void SlowCallback(const v8::FunctionCallbackInfo<v8::Value>& info) { |
| 15 | info.GetReturnValue().Set(41); |
| 16 | } |
| 17 | |
| 18 | |
| 19 | TEST(CompatibleReceiverBuiltin) { |
| 20 | // Check that the HandleFastApiCall builtin visits the hidden prototypes |
| 21 | // during the compatible receiver check. |
| 22 | LocalContext context; |
| 23 | v8::Isolate* isolate = context->GetIsolate(); |
| 24 | v8::HandleScope handle_scope(isolate); |
| 25 | v8::Local<v8::Context> current_context = isolate->GetCurrentContext(); |
| 26 | |
| 27 | v8::Local<v8::FunctionTemplate> constructor_template = |
| 28 | v8::FunctionTemplate::New(isolate); |
| 29 | v8::Local<v8::FunctionTemplate> prototype_template = |
| 30 | v8::FunctionTemplate::New(isolate); |
| 31 | prototype_template->SetHiddenPrototype(true); |
| 32 | |
| 33 | v8::Local<v8::ObjectTemplate> proto_instance_template = |
| 34 | prototype_template->InstanceTemplate(); |
| 35 | |
| 36 | v8::experimental::FastAccessorBuilder* fast_accessor_builder = |
| 37 | v8::experimental::FastAccessorBuilder::New(isolate); |
| 38 | fast_accessor_builder->ReturnValue( |
| 39 | fast_accessor_builder->IntegerConstant(42)); |
| 40 | v8::Local<v8::FunctionTemplate> accessor_template = |
| 41 | v8::FunctionTemplate::NewWithFastHandler( |
| 42 | isolate, SlowCallback, fast_accessor_builder, v8::Local<v8::Value>(), |
| 43 | v8::Signature::New(isolate, prototype_template)); |
| 44 | |
| 45 | proto_instance_template->SetAccessorProperty( |
| 46 | v8_str("bar"), accessor_template, v8::Local<v8::FunctionTemplate>(), |
| 47 | v8::ReadOnly); |
| 48 | |
| 49 | v8::Local<v8::Object> object = |
| 50 | constructor_template->GetFunction(current_context) |
| 51 | .ToLocalChecked() |
| 52 | ->NewInstance(current_context) |
| 53 | .ToLocalChecked(); |
| 54 | |
| 55 | v8::Local<v8::Object> hidden_prototype = |
| 56 | prototype_template->GetFunction(current_context) |
| 57 | .ToLocalChecked() |
| 58 | ->NewInstance(current_context) |
| 59 | .ToLocalChecked(); |
| 60 | |
| 61 | CHECK(object->SetPrototype(current_context, hidden_prototype).FromJust()); |
| 62 | |
| 63 | context->Global() |
| 64 | ->Set(current_context, v8_str("object"), object) |
| 65 | .FromMaybe(false); |
| 66 | |
| 67 | CHECK_EQ(42, CompileRun("var getter = object.__lookupGetter__('bar');" |
| 68 | "getter.call(object)") |
| 69 | ->Int32Value(current_context) |
| 70 | .FromJust()); |
| 71 | } |
| 72 | |
| 73 | } // namespace |