Revision: 21066
Author:   [email protected]
Date:     Tue Apr 29 17:48:07 2014 UTC
Log: Pass in the prototype to CreateApiFunction rather than setting it on the result.

BUG=
[email protected]

Review URL: https://codereview.chromium.org/253603003
http://code.google.com/p/v8/source/detail?r=21066

Modified:
 /branches/bleeding_edge/src/apinatives.js
 /branches/bleeding_edge/src/bootstrapper.cc
 /branches/bleeding_edge/src/factory.cc
 /branches/bleeding_edge/src/factory.h
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/src/runtime.h

=======================================
--- /branches/bleeding_edge/src/apinatives.js   Tue Apr 29 06:42:26 2014 UTC
+++ /branches/bleeding_edge/src/apinatives.js   Tue Apr 29 17:48:07 2014 UTC
@@ -48,31 +48,29 @@
    (serialNumber in cache) && (cache[serialNumber] != kUninitialized);
   if (!isFunctionCached) {
     try {
-      var fun = %CreateApiFunction(data);
-      if (name) %FunctionSetName(fun, name);
       var flags = %GetTemplateField(data, kApiFlagOffset);
-      var doNotCache = flags & (1 << kDoNotCacheBit);
-      if (!doNotCache) cache[serialNumber] = fun;
-      if (flags & (1 << kRemovePrototypeBit)) {
-        %FunctionRemovePrototype(fun);
-      } else {
- var prototype = %GetTemplateField(data, kApiPrototypeTemplateOffset);
-        // Note: Do not directly use an object template as a condition, our
-        // internal ToBoolean doesn't handle that!
-        fun.prototype = typeof prototype === 'undefined' ?
-            {} : Instantiate(prototype);
-        if (flags & (1 << kReadOnlyPrototypeBit)) {
-          %FunctionSetReadOnlyPrototype(fun);
-        }
-        %SetProperty(fun.prototype, "constructor", fun, DONT_ENUM);
+      var has_proto = !(flags & (1 << kRemovePrototypeBit));
+      var prototype;
+      if (has_proto) {
+ var template = %GetTemplateField(data, kApiPrototypeTemplateOffset);
+        prototype = typeof template === 'undefined'
+            ?  {} : Instantiate(template);
+
         var parent = %GetTemplateField(data, kApiParentTemplateOffset);
// Note: Do not directly use a function template as a condition, our
         // internal ToBoolean doesn't handle that!
-        if (!(typeof parent === 'undefined')) {
+        if (typeof parent !== 'undefined') {
           var parent_fun = Instantiate(parent);
-          %SetPrototype(fun.prototype, parent_fun.prototype);
+          %SetPrototype(prototype, parent_fun.prototype);
         }
       }
+      var fun = %CreateApiFunction(data, prototype);
+      if (name) %FunctionSetName(fun, name);
+      var doNotCache = flags & (1 << kDoNotCacheBit);
+      if (!doNotCache) cache[serialNumber] = fun;
+      if (has_proto && flags & (1 << kReadOnlyPrototypeBit)) {
+        %FunctionSetReadOnlyPrototype(fun);
+      }
       ConfigureTemplateInstance(fun, data);
       if (doNotCache) return fun;
     } catch (e) {
=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Tue Apr 29 13:43:17 2014 UTC
+++ /branches/bleeding_edge/src/bootstrapper.cc Tue Apr 29 17:48:07 2014 UTC
@@ -729,6 +729,7 @@
         FunctionTemplateInfo::cast(js_global_template->constructor()));
     js_global_function =
         factory()->CreateApiFunction(js_global_constructor,
+                                     factory()->the_hole_value(),
                                      factory()->InnerGlobalObject);
   }

@@ -756,6 +757,7 @@
             FunctionTemplateInfo::cast(data->constructor()));
     global_proxy_function =
         factory()->CreateApiFunction(global_constructor,
+                                     factory()->the_hole_value(),
                                      factory()->OuterGlobalObject);
   }

=======================================
--- /branches/bleeding_edge/src/factory.cc      Tue Apr 29 13:58:55 2014 UTC
+++ /branches/bleeding_edge/src/factory.cc      Tue Apr 29 17:48:07 2014 UTC
@@ -1255,19 +1255,30 @@
 }


-Handle<JSFunction> Factory::NewFunction(Handle<String> name,
+Handle<JSFunction> Factory::NewFunction(MaybeHandle<Object> maybe_prototype,
+                                        Handle<String> name,
                                         InstanceType type,
                                         int instance_size,
                                         Handle<Code> code,
                                         bool force_initial_map) {
   // Allocate the function
-  Handle<JSFunction> function = NewFunction(name, code, the_hole_value());
+  Handle<JSFunction> function = NewFunction(name, code, maybe_prototype);

-  if (force_initial_map ||
-      type != JS_OBJECT_TYPE ||
-      instance_size != JSObject::kHeaderSize) {
+  Handle<Object> prototype;
+  if (maybe_prototype.ToHandle(&prototype) &&
+      (force_initial_map ||
+       type != JS_OBJECT_TYPE ||
+       instance_size != JSObject::kHeaderSize)) {
     Handle<Map> initial_map = NewMap(type, instance_size);
-    Handle<JSObject> prototype = NewFunctionPrototype(function);
+    if (prototype->IsJSObject()) {
+      JSObject::SetLocalPropertyIgnoreAttributes(
+          Handle<JSObject>::cast(prototype),
+          constructor_string(),
+          function,
+          DONT_ENUM).Assert();
+    } else if (!function->shared()->is_generator()) {
+      prototype = NewFunctionPrototype(function);
+    }
     initial_map->set_prototype(*prototype);
     function->set_initial_map(*initial_map);
     initial_map->set_constructor(*function);
@@ -1280,6 +1291,16 @@
 }


+Handle<JSFunction> Factory::NewFunction(Handle<String> name,
+                                        InstanceType type,
+                                        int instance_size,
+                                        Handle<Code> code,
+                                        bool force_initial_map) {
+  return NewFunction(
+ the_hole_value(), name, type, instance_size, code, force_initial_map);
+}
+
+
 Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name,
                                                      InstanceType type,
                                                      int instance_size,
@@ -2057,7 +2078,9 @@


 Handle<JSFunction> Factory::CreateApiFunction(
-    Handle<FunctionTemplateInfo> obj, ApiInstanceType instance_type) {
+    Handle<FunctionTemplateInfo> obj,
+    Handle<Object> prototype,
+    ApiInstanceType instance_type) {
   Handle<Code> code = isolate()->builtins()->HandleApiCall();
Handle<Code> construct_stub = isolate()->builtins()->JSConstructStubApi();

@@ -2092,21 +2115,32 @@
       type = JS_OBJECT_TYPE;  // Keep the compiler happy.
       break;
   }
+
+  MaybeHandle<Object> maybe_prototype = prototype;
+  if (obj->remove_prototype()) maybe_prototype = MaybeHandle<Object>();

   Handle<JSFunction> result = NewFunction(
-      Factory::empty_string(), type, instance_size, code, true);
+      maybe_prototype, Factory::empty_string(), type,
+      instance_size, code, true);

-  // Set length.
   result->shared()->set_length(obj->length());
-
-  // Set class name.
-  Handle<Object> class_name = Handle<Object>(obj->class_name(), isolate());
+  Handle<Object> class_name(obj->class_name(), isolate());
   if (class_name->IsString()) {
     result->shared()->set_instance_class_name(*class_name);
     result->shared()->set_name(*class_name);
   }
+  result->shared()->set_function_data(*obj);
+  result->shared()->set_construct_stub(*construct_stub);
+  result->shared()->DontAdaptArguments();

-  Handle<Map> map = Handle<Map>(result->initial_map());
+  if (obj->remove_prototype()) {
+    ASSERT(result->shared()->IsApiFunction());
+    return result;
+  }
+  // Down from here is only valid for API functions that can be used as a
+  // constructor (don't set the "remove prototype" flag).
+
+  Handle<Map> map(result->initial_map());

   // Mark as undetectable if needed.
   if (obj->undetectable()) {
@@ -2135,10 +2169,6 @@
   if (!obj->instance_call_handler()->IsUndefined()) {
     map->set_has_instance_call_handler();
   }
-
-  result->shared()->set_function_data(*obj);
-  result->shared()->set_construct_stub(*construct_stub);
-  result->shared()->DontAdaptArguments();

   // Recursively copy parent instance templates' accessors,
   // 'data' may be modified.
=======================================
--- /branches/bleeding_edge/src/factory.h       Tue Apr 29 13:58:55 2014 UTC
+++ /branches/bleeding_edge/src/factory.h       Tue Apr 29 17:48:07 2014 UTC
@@ -464,6 +464,12 @@
       Handle<Context> context,
       PretenureFlag pretenure = TENURED);

+  Handle<JSFunction> NewFunction(MaybeHandle<Object> maybe_prototype,
+                                 Handle<String> name,
+                                 InstanceType type,
+                                 int instance_size,
+                                 Handle<Code> code,
+                                 bool force_initial_map);
   Handle<JSFunction> NewFunction(Handle<String> name,
                                  InstanceType type,
                                  int instance_size,
@@ -551,6 +557,7 @@

   Handle<JSFunction> CreateApiFunction(
       Handle<FunctionTemplateInfo> data,
+      Handle<Object> prototype,
       ApiInstanceType type = JavaScriptObject);

   Handle<JSFunction> InstallMembers(Handle<JSFunction> function);
=======================================
--- /branches/bleeding_edge/src/runtime.cc      Tue Apr 29 14:16:38 2014 UTC
+++ /branches/bleeding_edge/src/runtime.cc      Tue Apr 29 17:48:07 2014 UTC
@@ -2112,9 +2112,10 @@

 RUNTIME_FUNCTION(Runtime_CreateApiFunction) {
   HandleScope scope(isolate);
-  ASSERT(args.length() == 1);
+  ASSERT(args.length() == 2);
   CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0);
-  return *isolate->factory()->CreateApiFunction(data);
+  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
+  return *isolate->factory()->CreateApiFunction(data, prototype);
 }


@@ -2786,7 +2787,8 @@
   Handle<String> key = isolate->factory()->InternalizeUtf8String(name);
   Handle<Code> code(isolate->builtins()->builtin(builtin_name));
   Handle<JSFunction> optimized =
-      isolate->factory()->NewFunction(key,
+      isolate->factory()->NewFunction(MaybeHandle<Object>(),
+                                      key,
                                       JS_OBJECT_TYPE,
                                       JSObject::kHeaderSize,
                                       code,
=======================================
--- /branches/bleeding_edge/src/runtime.h       Tue Apr 29 06:42:26 2014 UTC
+++ /branches/bleeding_edge/src/runtime.h       Tue Apr 29 17:48:07 2014 UTC
@@ -202,7 +202,7 @@
   F(SetCode, 2, 1) \
   F(SetExpectedNumberOfProperties, 2, 1) \
   \
-  F(CreateApiFunction, 1, 1) \
+  F(CreateApiFunction, 2, 1) \
   F(IsTemplate, 1, 1) \
   F(GetTemplateField, 2, 1) \
   F(DisableAccessChecks, 1, 1) \

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to