Handlify JSFunction::SetPrototype method.
authormstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 18 Jul 2013 07:59:48 +0000 (07:59 +0000)
committermstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 18 Jul 2013 07:59:48 +0000 (07:59 +0000)
R=verwaest@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15738 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/accessors.cc
src/accessors.h
src/bootstrapper.cc
src/factory.cc
src/handles.cc
src/handles.h
src/objects.cc
src/objects.h

index e441de4..648f113 100644 (file)
@@ -450,26 +450,23 @@ Handle<Object> Accessors::FunctionGetPrototype(Handle<Object> object) {
 
 MaybeObject* Accessors::FunctionGetPrototype(Object* object, void*) {
   Isolate* isolate = Isolate::Current();
-  JSFunction* function = FindInstanceOf<JSFunction>(isolate, object);
-  if (function == NULL) return isolate->heap()->undefined_value();
-  while (!function->should_have_prototype()) {
-    function = FindInstanceOf<JSFunction>(isolate, function->GetPrototype());
+  JSFunction* function_raw = FindInstanceOf<JSFunction>(isolate, object);
+  if (function_raw == NULL) return isolate->heap()->undefined_value();
+  while (!function_raw->should_have_prototype()) {
+    function_raw = FindInstanceOf<JSFunction>(isolate,
+                                              function_raw->GetPrototype());
     // There has to be one because we hit the getter.
-    ASSERT(function != NULL);
+    ASSERT(function_raw != NULL);
   }
 
-  if (!function->has_prototype()) {
-    Object* prototype;
-    { MaybeObject* maybe_prototype
-          = isolate->heap()->AllocateFunctionPrototype(function);
-      if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype;
-    }
-    Object* result;
-    { MaybeObject* maybe_result = function->SetPrototype(prototype);
-      if (!maybe_result->ToObject(&result)) return maybe_result;
-    }
+  if (!function_raw->has_prototype()) {
+    HandleScope scope(isolate);
+    Handle<JSFunction> function(function_raw);
+    Handle<Object> proto = isolate->factory()->NewFunctionPrototype(function);
+    JSFunction::SetPrototype(function, proto);
+    function_raw = *function;
   }
-  return function->prototype();
+  return function_raw->prototype();
 }
 
 
@@ -503,9 +500,7 @@ MaybeObject* Accessors::FunctionSetPrototype(JSObject* object,
       old_value = isolate->factory()->NewFunctionPrototype(function);
   }
 
-  Handle<Object> result;
-  MaybeObject* maybe_result = function->SetPrototype(*value);
-  if (!maybe_result->ToHandle(&result, isolate)) return maybe_result;
+  JSFunction::SetPrototype(function, value);
   ASSERT(function->prototype() == *value);
 
   if (is_observed && !old_value->SameValue(*value)) {
index 9a83ab8..a7e67b5 100644 (file)
@@ -77,8 +77,6 @@ class Accessors : public AllStatic {
   };
 
   // Accessor functions called directly from the runtime system.
-  MUST_USE_RESULT static MaybeObject* FunctionGetPrototype(Object* object,
-                                                           void*);
   static Handle<Object> FunctionGetPrototype(Handle<Object> object);
 
   MUST_USE_RESULT static MaybeObject* FunctionSetPrototype(JSObject* object,
@@ -95,6 +93,7 @@ class Accessors : public AllStatic {
   static MaybeObject* FunctionGetLength(Object* object, void*);
   static MaybeObject* FunctionGetName(Object* object, void*);
   static MaybeObject* FunctionGetCaller(Object* object, void*);
+  static MaybeObject* FunctionGetPrototype(Object* object, void*);
   MUST_USE_RESULT static MaybeObject* ArraySetLength(JSObject* object,
                                                      Object* value, void*);
   static MaybeObject* ArrayGetLength(Object* object, void*);
index 249b31c..d8d065c 100644 (file)
@@ -200,7 +200,7 @@ class Genesis BASE_EMBEDDED {
   // detached from the other objects in the snapshot.
   void HookUpInnerGlobal(Handle<GlobalObject> inner_global);
   // New context initialization.  Used for creating a context from scratch.
-  bool InitializeGlobal(Handle<GlobalObject> inner_global,
+  void InitializeGlobal(Handle<GlobalObject> inner_global,
                         Handle<JSFunction> empty_function);
   void InitializeExperimentalGlobal();
   // Installs the contents of the native .js files on the global objects.
@@ -829,7 +829,7 @@ void Genesis::HookUpInnerGlobal(Handle<GlobalObject> inner_global) {
 
 // This is only called if we are not using snapshots.  The equivalent
 // work in the snapshot case is done in HookUpInnerGlobal.
-bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
+void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
                                Handle<JSFunction> empty_function) {
   // --- G l o b a l   C o n t e x t ---
   // Use the empty function as closure (no scope info).
@@ -1053,10 +1053,8 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
     Handle<String> name = factory->NewStringFromAscii(CStrVector("JSON"));
     Handle<JSFunction> cons = factory->NewFunction(name,
                                                    factory->the_hole_value());
-    { MaybeObject* result = cons->SetInstancePrototype(
-        native_context()->initial_object_prototype());
-      if (result->IsFailure()) return false;
-    }
+    JSFunction::SetInstancePrototype(cons,
+        Handle<Object>(native_context()->initial_object_prototype(), isolate));
     cons->SetInstanceClassName(*name);
     Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
     ASSERT(json_object->IsJSObject());
@@ -1277,7 +1275,6 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
     native_context()->set_random_seed(*zeroed_byte_array);
     memset(zeroed_byte_array->GetDataStartAddress(), 0, kRandomStateSize);
   }
-  return true;
 }
 
 
@@ -2632,7 +2629,7 @@ Genesis::Genesis(Isolate* isolate,
     Handle<JSGlobalProxy> global_proxy =
         CreateNewGlobals(global_template, global_object, &inner_global);
     HookUpGlobalProxy(inner_global, global_proxy);
-    if (!InitializeGlobal(inner_global, empty_function)) return;
+    InitializeGlobal(inner_global, empty_function);
     InstallJSFunctionResultCaches();
     InitializeNormalizedMapCaches();
     if (!InstallNatives()) return;
index dc07768..b135a9c 100644 (file)
@@ -935,7 +935,7 @@ Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name,
     initial_map->set_constructor(*function);
   }
 
-  SetPrototypeProperty(function, prototype);
+  JSFunction::SetPrototype(function, prototype);
   return function;
 }
 
index c02801f..48114d9 100644 (file)
@@ -169,12 +169,6 @@ void SetExpectedNofProperties(Handle<JSFunction> func, int nof) {
 }
 
 
-void SetPrototypeProperty(Handle<JSFunction> func, Handle<JSObject> value) {
-  CALL_HEAP_FUNCTION_VOID(func->GetIsolate(),
-                          func->SetPrototype(*value));
-}
-
-
 static int ExpectedNofPropertiesFromEstimate(int estimate) {
   // If no properties are added in the constructor, they are more likely
   // to be added later.
index 140c34e..90db7d1 100644 (file)
@@ -313,9 +313,6 @@ Handle<String> SubString(Handle<String> str,
 // Sets the expected number of properties for the function's instances.
 void SetExpectedNofProperties(Handle<JSFunction> func, int nof);
 
-// Sets the prototype property for a function instance.
-void SetPrototypeProperty(Handle<JSFunction> func, Handle<JSObject> value);
-
 // Sets the expected number of properties based on estimate from compiler.
 void SetExpectedNofPropertiesFromEstimate(Handle<SharedFunctionInfo> shared,
                                           int estimate);
index bb6b4fd..5f2a7b5 100644 (file)
@@ -9532,57 +9532,53 @@ Handle<Object> CacheInitialJSArrayMaps(Handle<Context> native_context,
 }
 
 
-MaybeObject* JSFunction::SetInstancePrototype(Object* value) {
+void JSFunction::SetInstancePrototype(Handle<JSFunction> function,
+                                      Handle<Object> value) {
   ASSERT(value->IsJSReceiver());
-  Heap* heap = GetHeap();
 
   // First some logic for the map of the prototype to make sure it is in fast
   // mode.
   if (value->IsJSObject()) {
-    MaybeObject* ok = JSObject::cast(value)->OptimizeAsPrototype();
-    if (ok->IsFailure()) return ok;
+    JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value));
   }
 
   // Now some logic for the maps of the objects that are created by using this
   // function as a constructor.
-  if (has_initial_map()) {
+  if (function->has_initial_map()) {
     // If the function has allocated the initial map replace it with a
     // copy containing the new prototype.  Also complete any in-object
     // slack tracking that is in progress at this point because it is
     // still tracking the old copy.
-    if (shared()->IsInobjectSlackTrackingInProgress()) {
-      shared()->CompleteInobjectSlackTracking();
+    if (function->shared()->IsInobjectSlackTrackingInProgress()) {
+      function->shared()->CompleteInobjectSlackTracking();
     }
-    Map* new_map;
-    MaybeObject* maybe_object = initial_map()->Copy();
-    if (!maybe_object->To(&new_map)) return maybe_object;
-    new_map->set_prototype(value);
+    Handle<Map> new_map = Map::Copy(handle(function->initial_map()));
+    new_map->set_prototype(*value);
 
     // If the function is used as the global Array function, cache the
     // initial map (and transitioned versions) in the native context.
-    Context* native_context = context()->native_context();
+    Context* native_context = function->context()->native_context();
     Object* array_function = native_context->get(Context::ARRAY_FUNCTION_INDEX);
     if (array_function->IsJSFunction() &&
-        this == JSFunction::cast(array_function)) {
-      MaybeObject* ok = CacheInitialJSArrayMaps(native_context, new_map);
-      if (ok->IsFailure()) return ok;
+        *function == JSFunction::cast(array_function)) {
+      CacheInitialJSArrayMaps(handle(native_context), new_map);
     }
 
-    set_initial_map(new_map);
+    function->set_initial_map(*new_map);
   } else {
     // Put the value in the initial map field until an initial map is
     // needed.  At that point, a new initial map is created and the
     // prototype is put into the initial map where it belongs.
-    set_prototype_or_initial_map(value);
+    function->set_prototype_or_initial_map(*value);
   }
-  heap->ClearInstanceofCache();
-  return value;
+  function->GetHeap()->ClearInstanceofCache();
 }
 
 
-MaybeObject* JSFunction::SetPrototype(Object* value) {
-  ASSERT(should_have_prototype());
-  Object* construct_prototype = value;
+void JSFunction::SetPrototype(Handle<JSFunction> function,
+                              Handle<Object> value) {
+  ASSERT(function->should_have_prototype());
+  Handle<Object> construct_prototype = value;
 
   // If the value is not a JSReceiver, store the value in the map's
   // constructor field so it can be accessed.  Also, set the prototype
@@ -9592,22 +9588,20 @@ MaybeObject* JSFunction::SetPrototype(Object* value) {
     // Copy the map so this does not affect unrelated functions.
     // Remove map transitions because they point to maps with a
     // different prototype.
-    Map* new_map;
-    MaybeObject* maybe_new_map = map()->Copy();
-    if (!maybe_new_map->To(&new_map)) return maybe_new_map;
+    Handle<Map> new_map = Map::Copy(handle(function->map()));
 
-    Heap* heap = new_map->GetHeap();
-    set_map(new_map);
-    new_map->set_constructor(value);
+    function->set_map(*new_map);
+    new_map->set_constructor(*value);
     new_map->set_non_instance_prototype(true);
-    construct_prototype =
-        heap->isolate()->context()->native_context()->
-            initial_object_prototype();
+    Isolate* isolate = new_map->GetIsolate();
+    construct_prototype = handle(
+        isolate->context()->native_context()->initial_object_prototype(),
+        isolate);
   } else {
-    map()->set_non_instance_prototype(false);
+    function->map()->set_non_instance_prototype(false);
   }
 
-  return SetInstancePrototype(construct_prototype);
+  return SetInstancePrototype(function, construct_prototype);
 }
 
 
index 3f8ff36..08b1e10 100644 (file)
@@ -6695,8 +6695,10 @@ class JSFunction: public JSObject {
   inline bool has_instance_prototype();
   inline Object* prototype();
   inline Object* instance_prototype();
-  MUST_USE_RESULT MaybeObject* SetInstancePrototype(Object* value);
-  MUST_USE_RESULT MaybeObject* SetPrototype(Object* value);
+  static void SetPrototype(Handle<JSFunction> function,
+                           Handle<Object> value);
+  static void SetInstancePrototype(Handle<JSFunction> function,
+                                   Handle<Object> value);
 
   // After prototype is removed, it will not be created when accessed, and
   // [[Construct]] from this function will not be allowed.