v8/test/cctest/test-api-accessors.cc
vogelheim 5819e4be5b Re-re-land FastAccessorBuilder.
... using the RawMachineAssembler and the work in crrev.com/1407313004.

The original change collided with crrev.com/1513543003.

BUG=chromium:508898
LOG=Y

Committed: https://crrev.com/515d9ccd8e6df7bf2ca01e2a55aaad30226399e1
Cr-Commit-Position: refs/heads/master@{#32742}

patch from issue 1474543004 at patchset 260001 (http://crrev.com/1474543004#ps260001)

Committed: https://crrev.com/ee5c38d7db907ff86dd4049721c0cb4bc90a6c4d
Cr-Commit-Position: refs/heads/master@{#32753}

patch from issue 1504713012 at patchset 20001 (http://crrev.com/1504713012#ps20001)

Review URL: https://codereview.chromium.org/1518703002

Cr-Commit-Position: refs/heads/master@{#32786}
2015-12-11 09:54:00 +00:00

116 lines
3.5 KiB
C++

// Copyright 2015 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 "test/cctest/cctest.h"
#include "include/v8.h"
#include "include/v8-experimental.h"
namespace i = v8::internal;
static void CppAccessor42(const v8::FunctionCallbackInfo<v8::Value>& info) {
info.GetReturnValue().Set(42);
}
static void CppAccessor41(const v8::FunctionCallbackInfo<v8::Value>& info) {
info.GetReturnValue().Set(41);
}
v8::experimental::FastAccessorBuilder* FastAccessor(v8::Isolate* isolate) {
auto builder = v8::experimental::FastAccessorBuilder::New(isolate);
builder->ReturnValue(builder->IntegerConstant(41));
return builder;
}
TEST(FastAccessors) {
if (i::FLAG_always_opt || i::FLAG_optimize_for_size) return;
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
LocalContext env;
// We emulate Embedder-created DOM Node instances. Specifically:
// - 'parent': FunctionTemplate ~= DOM Node superclass
// - 'child': FunctionTemplate ~= a specific DOM node type, like a <div />
//
// We'll install both a C++-based and a JS-based accessor on the parent,
// and expect it to be callable on the child.
// Setup the parent template ( =~ DOM Node w/ accessors).
v8::Local<v8::FunctionTemplate> parent = v8::FunctionTemplate::New(isolate);
{
auto signature = v8::Signature::New(isolate, parent);
// cpp accessor as "firstChild":
parent->PrototypeTemplate()->SetAccessorProperty(
v8_str("firstChild"),
v8::FunctionTemplate::New(isolate, CppAccessor42,
v8::Local<v8::Value>(), signature));
// JS accessor as "firstChildRaw":
parent->PrototypeTemplate()->SetAccessorProperty(
v8_str("firstChildRaw"),
v8::FunctionTemplate::NewWithFastHandler(
isolate, CppAccessor41, FastAccessor(isolate),
v8::Local<v8::Value>(), signature));
}
// Setup child object ( =~ a specific DOM Node, e.g. a <div> ).
// Also, make a creation function on the global object, so we can access it
// in a test.
v8::Local<v8::FunctionTemplate> child = v8::FunctionTemplate::New(isolate);
child->Inherit(parent);
CHECK(env->Global()
->Set(env.local(), v8_str("Node"),
child->GetFunction(env.local()).ToLocalChecked())
.IsJust());
// Setup done: Let's test it:
// The simple case: Run it once.
ExpectInt32("var n = new Node(); n.firstChild", 42);
ExpectInt32("var n = new Node(); n.firstChildRaw", 41);
// Run them in a loop. This will likely trigger the optimizing compiler:
ExpectInt32(
"var m = new Node(); "
"var sum = 0; "
"for (var i = 0; i < 10; ++i) { "
" sum += m.firstChild; "
" sum += m.firstChildRaw; "
"}; "
"sum;",
10 * (42 + 41));
// Obtain the accessor and call it via apply on the Node:
ExpectInt32(
"var n = new Node(); "
"var g = Object.getOwnPropertyDescriptor("
" n.__proto__.__proto__, 'firstChild')['get']; "
"g.apply(n);",
42);
ExpectInt32(
"var n = new Node(); "
"var g = Object.getOwnPropertyDescriptor("
" n.__proto__.__proto__, 'firstChildRaw')['get']; "
"g.apply(n);",
41);
ExpectInt32(
"var n = new Node();"
"var g = Object.getOwnPropertyDescriptor("
" n.__proto__.__proto__, 'firstChildRaw')['get'];"
"try {"
" var f = { firstChildRaw: '51' };"
" g.apply(f);"
"} catch(e) {"
" 31415;"
"}",
31415);
}