Reviewers: ,
Description:
Implement NewInstance method for Object in the API
Patch by Peter Varga.
BUG=v8:1348
TEST=cctest/test-api/ConstructorForObject
Please review this at http://codereview.chromium.org/6902108/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M include/v8.h
M src/api.cc
M test/cctest/test-api.cc
Index: include/v8.h
diff --git a/include/v8.h b/include/v8.h
index
4ab1ec2b4f8c54c83f36f4ee2ecd53ddec1be599..0bc076832c776f7af5f681acb0b81e91a3173562
100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -1689,6 +1689,8 @@ class Object : public Value {
V8EXPORT static Local<Object> New();
static inline Object* Cast(Value* obj);
+
+ V8EXPORT Local<Object> NewInstance(int argc, Handle<Value> argv[]) const;
private:
V8EXPORT Object();
V8EXPORT static void CheckCast(Value* obj);
Index: src/api.cc
diff --git a/src/api.cc b/src/api.cc
index
e6833530041b9794dbd0c63f34e5c6e26d33d0e9..3e019dd020a414561f856c84af7deaf3e1941405
100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -3193,6 +3193,33 @@ int
v8::Object::GetIndexedPropertiesExternalArrayDataLength() {
}
+Local<v8::Object> Object::NewInstance(int argc,
+ v8::Handle<v8::Value> argv[]) const {
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ON_BAILOUT(isolate, "v8::Object::NewInstance()",
+ return Local<v8::Object>());
+ LOG_API(isolate, "Object::NewInstance");
+ ENTER_V8(isolate);
+ HandleScope scope;
+ i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
+ STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
+ i::Object*** args = reinterpret_cast<i::Object***>(argv);
+ EXCEPTION_PREAMBLE(isolate);
+ i::Handle<i::Object> returned;
+ if (obj->IsJSFunction()) {
+ i::Handle<i::JSFunction> function =
i::Handle<i::JSFunction>::cast(obj);
+ returned = i::Execution::New(function, argc, args,
&has_pending_exception);
+ } else {
+ i::Handle<i::JSFunction> delegate =
+
i::Handle<i::JSFunction>::cast(i::Execution::GetConstructorDelegate(obj));
+ returned =
+ i::Execution::Call(delegate, obj, argc, args,
&has_pending_exception);
+ }
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
+ return
scope.Close(Utils::ToLocal(i::Handle<i::JSObject>::cast(returned)));
+}
+
+
Local<v8::Object> Function::NewInstance() const {
return NewInstance(0, NULL);
}
Index: test/cctest/test-api.cc
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index
a228a6f4999b6d02748aaac768944aaf10213f2c..995c683947a0b425be9e19dbc9e3ecad15597bac
100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -6744,6 +6744,49 @@ THREADED_TEST(Constructor) {
CHECK(value->BooleanValue());
}
+
+static Handle<Value> ConstructorCallback(const Arguments& args) {
+ ApiTestFuzzer::Fuzz();
+ if (args[0]->IsInt32()) {
+ Local<Object> This;
+
+ if (args.IsConstructCall()) {
+ Local<Object> Holder = args.Holder();
+ This = Object::New();
+ Local<Value> proto = Holder->GetPrototype();
+ if (proto->IsObject())
+ This->SetPrototype(proto);
+ } else {
+ This = args.This();
+ }
+
+ This->Set(v8_str("a"), v8_num(args[0]->Int32Value()));
+ return This;
+ }
+
+ return args[0];
+}
+
+
+THREADED_TEST(ConstructorForObject) {
+ v8::HandleScope handle_scope;
+ LocalContext context;
+ Local<ObjectTemplate> instance_template = ObjectTemplate::New();
+ instance_template->SetCallAsFunctionHandler(ConstructorCallback);
+ Local<Object> instance = instance_template->NewInstance();
+
+ context->Global()->Set(v8_str("obj"), instance);
+ Local<Value> value1 =
+ CompileRun("(function() { var o = new obj(28); return o.a; })()");
+ CHECK_EQ(28, value1->Int32Value());
+
+ Local<Value> args[] = { v8_num(29) };
+ Local<Object> object = instance->NewInstance(1, args);
+ Local<Value> value2 = object->Get(v8_str("a"));
+ CHECK_EQ(29, value2->Int32Value());
+}
+
+
THREADED_TEST(FunctionDescriptorException) {
v8::HandleScope handle_scope;
LocalContext context;
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev