Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index 0ce58366d2c5441734325fa79a9702eac56c6860..40c41e91a78cdd10c96f9be850aafd8421c02a49 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -1960,6 +1960,58 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetPrototype) { |
} |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionReadOnlyPrototype) { |
+ NoHandleAllocation ha; |
+ RUNTIME_ASSERT(args.length() == 1); |
+ CONVERT_CHECKED(JSFunction, object, args[0]); |
Rico
2011/07/25 13:05:42
it's a function, maybe call it fun, function or f
Jakob Kummerow
2011/07/25 14:57:05
Done.
|
+ |
+ MaybeObject* maybe_name = |
+ isolate->heap()->AllocateStringFromAscii(CStrVector("prototype")); |
+ String* name; |
+ if (!maybe_name->To(&name)) return maybe_name; |
+ |
+ if (object->HasFastProperties()) { |
Rico
2011/07/25 13:05:42
If it is not performance critical to keep fast pro
Jakob Kummerow
2011/07/25 14:57:05
I'd prefer to keep performance as it is since this
|
+ // Construct a new field descriptor with updated attributes. |
+ DescriptorArray* instance_desc = object->map()->instance_descriptors(); |
+ int index = instance_desc->Search(name); |
Rico
2011/07/25 13:05:42
assert that index != kNotFound
Jakob Kummerow
2011/07/25 14:57:05
Done.
|
+ PropertyDetails details(instance_desc->GetDetails(index)); |
+ CallbacksDescriptor new_desc(name, |
+ instance_desc->GetValue(index), |
+ static_cast<PropertyAttributes>(details.attributes() | READ_ONLY), |
+ details.index()); |
+ // Construct a new field descriptors array containing the new descriptor. |
+ Object* descriptors_unchecked; |
+ { MaybeObject* maybe_descriptors_unchecked = |
+ instance_desc->CopyInsert(&new_desc, REMOVE_TRANSITIONS); |
+ if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) { |
+ return maybe_descriptors_unchecked; |
+ } |
+ } |
+ DescriptorArray* new_descriptors = |
+ DescriptorArray::cast(descriptors_unchecked); |
+ // Create a new map featuring the new field descriptors array. |
+ Object* map_unchecked; |
+ { MaybeObject* maybe_map_unchecked = object->map()->CopyDropDescriptors(); |
+ if (!maybe_map_unchecked->ToObject(&map_unchecked)) { |
+ return maybe_map_unchecked; |
+ } |
+ } |
+ Map* new_map = Map::cast(map_unchecked); |
+ new_map->set_instance_descriptors(new_descriptors); |
+ object->set_map(new_map); |
+ } else { // Dictionary properties. |
+ // Directly manipulate the property details. |
+ int entry = object->property_dictionary()->FindEntry(name); |
Rico
2011/07/25 13:05:42
assert that entry != kNotFound
Jakob Kummerow
2011/07/25 14:57:05
Done.
|
+ PropertyDetails details = object->property_dictionary()->DetailsAt(entry); |
+ PropertyDetails new_details( |
+ static_cast<PropertyAttributes>(details.attributes() | READ_ONLY), |
+ details.type(), details.index()); |
Rico
2011/07/25 13:05:42
nit, put last argument on seperate line
Jakob Kummerow
2011/07/25 14:57:05
Done.
|
+ object->property_dictionary()->DetailsAtPut(entry, new_details); |
+ } |
+ return object; |
+} |
+ |
+ |
RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsAPIFunction) { |
NoHandleAllocation ha; |
ASSERT(args.length() == 1); |