| Index: test/cctest/test-api-accessors.cc
|
| diff --git a/test/cctest/test-api-accessors.cc b/test/cctest/test-api-accessors.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..213e9b9485ba49d96a1d4a575b5f01ae8286e3a1
|
| --- /dev/null
|
| +++ b/test/cctest/test-api-accessors.cc
|
| @@ -0,0 +1,111 @@
|
| +// Copyright 2015 the V8 project authors. All rights reserved.
|
| +// Redistribution and use in source and binary forms, with or without
|
| +// modification, are permitted provided that the following conditions are
|
| +// met:
|
| +//
|
| +// * Redistributions of source code must retain the above copyright
|
| +// notice, this list of conditions and the following disclaimer.
|
| +// * Redistributions in binary form must reproduce the above
|
| +// copyright notice, this list of conditions and the following
|
| +// disclaimer in the documentation and/or other materials provided
|
| +// with the distribution.
|
| +// * Neither the name of Google Inc. nor the names of its
|
| +// contributors may be used to endorse or promote products derived
|
| +// from this software without specific prior written permission.
|
| +//
|
| +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| +
|
| +
|
| +#include "test/cctest/test-api.h"
|
| +
|
| +#include "include/v8.h"
|
| +
|
| +
|
| +#ifdef V8_JS_ACCESSORS
|
| +static void CppAccessor(const v8::FunctionCallbackInfo<v8::Value>& info) {
|
| + info.GetReturnValue().Set(42);
|
| +}
|
| +
|
| +static const char* JsAccessor =
|
| + "function firstChildJS(value) { return 41; }; firstChildJS";
|
| +
|
| +TEST(JavascriptAccessors) {
|
| + 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, CppAccessor, v8::Local<v8::Value>(),
|
| + signature));
|
| +
|
| + // JS accessor as "firstChildJS":
|
| + auto js_accessor = v8::Local<v8::Function>::Cast(CompileRun(JsAccessor));
|
| + parent->PrototypeTemplate()->SetAccessorProperty(v8_str("firstChildJS"),
|
| + js_accessor);
|
| + }
|
| +
|
| + // 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);
|
| + env->Global()->Set(v8_str("Node"), child->GetFunction());
|
| +
|
| + // 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.firstChildJS", 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 < 3; ++i) { "
|
| + " sum += m.firstChild; "
|
| + " sum += m.firstChildJS; "
|
| + "}; "
|
| + "sum;",
|
| + 3 * (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__, 'firstChildJS')['get']; "
|
| + "g.apply(n);",
|
| + 41);
|
| +
|
| + // TODO(vogelheim): Verify compatible receiver check works.
|
| +}
|
| +#endif // V8_JS_ACCESSORS
|
|
|