Index: src/heap.cc |
diff --git a/src/heap.cc b/src/heap.cc |
index dbf3b95a941beca96cd1f77a35ea69de95a1a73c..c152ee8b57624bea639da4bfedcde96188809681 100644 |
--- a/src/heap.cc |
+++ b/src/heap.cc |
@@ -3276,11 +3276,36 @@ MaybeObject* Heap::AllocateJSProxy(Object* handler, Object* prototype) { |
map->set_prototype(prototype); |
// Allocate the proxy object. |
- Object* result; |
+ JSProxy* result; |
MaybeObject* maybe_result = Allocate(map, NEW_SPACE); |
- if (!maybe_result->ToObject(&result)) return maybe_result; |
- JSProxy::cast(result)->set_handler(handler); |
- JSProxy::cast(result)->set_padding(Smi::FromInt(0)); |
+ if (!maybe_result->To<JSProxy>(&result)) return maybe_result; |
+ result->InitializeBody(map->instance_size(), Smi::FromInt(0)); |
+ result->set_handler(handler); |
+ return result; |
+} |
+ |
+ |
+MaybeObject* Heap::AllocateJSFunctionProxy(Object* handler, |
+ Object* call_trap, |
+ Object* construct_trap, |
+ Object* prototype) { |
+ // Allocate map. |
+ // TODO(rossberg): Once we optimize proxies, think about a scheme to share |
+ // maps. Will probably depend on the identity of the handler object, too. |
+ Map* map; |
+ MaybeObject* maybe_map_obj = |
+ AllocateMap(JS_FUNCTION_PROXY_TYPE, JSFunctionProxy::kSize); |
+ if (!maybe_map_obj->To<Map>(&map)) return maybe_map_obj; |
+ map->set_prototype(prototype); |
+ |
+ // Allocate the proxy object. |
+ JSFunctionProxy* result; |
+ MaybeObject* maybe_result = Allocate(map, NEW_SPACE); |
+ if (!maybe_result->To<JSFunctionProxy>(&result)) return maybe_result; |
+ result->InitializeBody(map->instance_size(), Smi::FromInt(0)); |
+ result->set_handler(handler); |
+ result->set_call_trap(call_trap); |
+ result->set_construct_trap(construct_trap); |
return result; |
} |
@@ -3425,16 +3450,19 @@ MaybeObject* Heap::CopyJSObject(JSObject* source) { |
} |
-MaybeObject* Heap::ReinitializeJSProxyAsJSObject(JSProxy* object) { |
+MaybeObject* Heap::ReinitializeJSReceiver( |
+ JSReceiver* object, InstanceType type, int size) { |
+ ASSERT(type >= FIRST_JS_RECEIVER_TYPE); |
+ |
// Allocate fresh map. |
// TODO(rossberg): Once we optimize proxies, cache these maps. |
Map* map; |
- MaybeObject* maybe_map_obj = |
- AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
+ MaybeObject* maybe_map_obj = AllocateMap(type, size); |
if (!maybe_map_obj->To<Map>(&map)) return maybe_map_obj; |
- // Check that the receiver has the same size as a fresh object. |
- ASSERT(map->instance_size() == object->map()->instance_size()); |
+ // Check that the receiver has at least the size of the fresh object. |
+ int size_difference = object->map()->instance_size() - map->instance_size(); |
+ ASSERT(size_difference >= 0); |
map->set_prototype(object->map()->prototype()); |
@@ -3451,6 +3479,28 @@ MaybeObject* Heap::ReinitializeJSProxyAsJSObject(JSProxy* object) { |
// Reinitialize the object from the constructor map. |
InitializeJSObjectFromMap(JSObject::cast(object), |
FixedArray::cast(properties), map); |
+ |
+ // Functions require some minimal initialization. |
+ if (type == JS_FUNCTION_TYPE) { |
+ String* name; |
+ MaybeObject* maybe_name = LookupAsciiSymbol("<freezing call trap>"); |
+ if (!maybe_name->To<String>(&name)) return maybe_name; |
+ SharedFunctionInfo* shared; |
+ MaybeObject* maybe_shared = AllocateSharedFunctionInfo(name); |
+ if (!maybe_shared->To<SharedFunctionInfo>(&shared)) return maybe_shared; |
+ JSFunction* func; |
+ MaybeObject* maybe_func = |
+ InitializeFunction(JSFunction::cast(object), shared, the_hole_value()); |
+ if (!maybe_func->To<JSFunction>(&func)) return maybe_func; |
+ func->set_context(isolate()->context()->global_context()); |
+ } |
+ |
+ // Put in filler if the new object is smaller than the old. |
+ if (size_difference > 0) { |
+ CreateFillerObjectAt( |
+ object->address() + map->instance_size(), size_difference); |
+ } |
+ |
return object; |
} |