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

Reply via email to