Index: src/runtime.cc |
=================================================================== |
--- src/runtime.cc (revision 2947) |
+++ src/runtime.cc (working copy) |
@@ -1208,7 +1208,15 @@ |
: Heap::false_value(); |
} |
+static Object* Runtime_FunctionIsBuiltin(Arguments args) { |
+ NoHandleAllocation ha; |
+ ASSERT(args.length() == 1); |
+ CONVERT_CHECKED(JSFunction, f, args[0]); |
+ return f->IsBuiltin() ? Heap::true_value() : Heap::false_value(); |
+} |
+ |
+ |
static Object* Runtime_SetCode(Arguments args) { |
HandleScope scope; |
ASSERT(args.length() == 2); |
@@ -2992,7 +3000,8 @@ |
HandleScope scope; |
Handle<JSObject> object(raw_object); |
- Handle<FixedArray> content = GetKeysInFixedArrayFor(object); |
+ Handle<FixedArray> content = GetKeysInFixedArrayFor(object, |
+ INCLUDE_PROTOS); |
// Test again, since cache may have been built by preceding call. |
if (object->IsSimpleEnum()) return object->map(); |
@@ -3001,6 +3010,22 @@ |
} |
+static Object* Runtime_LocalKeys(Arguments args) { |
+ ASSERT_EQ(args.length(), 1); |
+ CONVERT_CHECKED(JSObject, raw_object, args[0]); |
+ HandleScope scope; |
+ Handle<JSObject> object(raw_object); |
+ Handle<FixedArray> contents = GetKeysInFixedArrayFor(object, |
+ LOCAL_ONLY); |
+ // Some fast paths through GetKeysInFixedArrayFor reuse a cached |
+ // property array and since the result is mutable we have to create |
+ // a fresh clone on each invocation. |
+ Handle<FixedArray> copy = Factory::NewFixedArray(contents->length()); |
+ contents->CopyTo(0, *copy, 0, contents->length()); |
+ return *Factory::NewJSArrayWithElements(copy); |
+} |
+ |
+ |
static Object* Runtime_GetArgumentsProperty(Arguments args) { |
NoHandleAllocation ha; |
ASSERT(args.length() == 1); |
@@ -5516,7 +5541,7 @@ |
if (array->elements()->IsDictionary()) { |
// Create an array and get all the keys into it, then remove all the |
// keys that are not integers in the range 0 to length-1. |
- Handle<FixedArray> keys = GetKeysInFixedArrayFor(array); |
+ Handle<FixedArray> keys = GetKeysInFixedArrayFor(array, INCLUDE_PROTOS); |
int keys_length = keys->length(); |
for (int i = 0; i < keys_length; i++) { |
Object* key = keys->get(i); |
@@ -5738,55 +5763,51 @@ |
int length = LocalPrototypeChainLength(*obj); |
// Try local lookup on each of the objects. |
- LookupResult result; |
Handle<JSObject> jsproto = obj; |
for (int i = 0; i < length; i++) { |
+ LookupResult result; |
jsproto->LocalLookup(*name, &result); |
if (result.IsProperty()) { |
- break; |
+ // LookupResult is not GC safe as it holds raw object pointers. |
+ // GC can happen later in this code so put the required fields into |
+ // local variables using handles when required for later use. |
+ PropertyType result_type = result.type(); |
+ Handle<Object> result_callback_obj; |
+ if (result_type == CALLBACKS) { |
+ result_callback_obj = Handle<Object>(result.GetCallbackObject()); |
+ } |
+ Smi* property_details = result.GetPropertyDetails().AsSmi(); |
+ // DebugLookupResultValue can cause GC so details from LookupResult needs |
+ // to be copied to handles before this. |
+ bool caught_exception = false; |
+ Object* raw_value = DebugLookupResultValue(*obj, *name, &result, |
+ &caught_exception); |
+ if (raw_value->IsFailure()) return raw_value; |
+ Handle<Object> value(raw_value); |
+ |
+ // If the callback object is a fixed array then it contains JavaScript |
+ // getter and/or setter. |
+ bool hasJavaScriptAccessors = result_type == CALLBACKS && |
+ result_callback_obj->IsFixedArray(); |
+ Handle<FixedArray> details = |
+ Factory::NewFixedArray(hasJavaScriptAccessors ? 5 : 2); |
+ details->set(0, *value); |
+ details->set(1, property_details); |
+ if (hasJavaScriptAccessors) { |
+ details->set(2, |
+ caught_exception ? Heap::true_value() |
+ : Heap::false_value()); |
+ details->set(3, FixedArray::cast(*result_callback_obj)->get(0)); |
+ details->set(4, FixedArray::cast(*result_callback_obj)->get(1)); |
+ } |
+ |
+ return *Factory::NewJSArrayWithElements(details); |
} |
if (i < length - 1) { |
jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); |
} |
} |
- if (result.IsProperty()) { |
- // LookupResult is not GC safe as all its members are raw object pointers. |
- // When calling DebugLookupResultValue GC can happen as this might invoke |
- // callbacks. After the call to DebugLookupResultValue the callback object |
- // in the LookupResult might still be needed. Put it into a handle for later |
- // use. |
- PropertyType result_type = result.type(); |
- Handle<Object> result_callback_obj; |
- if (result_type == CALLBACKS) { |
- result_callback_obj = Handle<Object>(result.GetCallbackObject()); |
- } |
- |
- // Find the actual value. Don't use result after this call as it's content |
- // can be invalid. |
- bool caught_exception = false; |
- Object* value = DebugLookupResultValue(*obj, *name, &result, |
- &caught_exception); |
- if (value->IsFailure()) return value; |
- Handle<Object> value_handle(value); |
- |
- // If the callback object is a fixed array then it contains JavaScript |
- // getter and/or setter. |
- bool hasJavaScriptAccessors = result_type == CALLBACKS && |
- result_callback_obj->IsFixedArray(); |
- Handle<FixedArray> details = |
- Factory::NewFixedArray(hasJavaScriptAccessors ? 5 : 2); |
- details->set(0, *value_handle); |
- details->set(1, result.GetPropertyDetails().AsSmi()); |
- if (hasJavaScriptAccessors) { |
- details->set(2, |
- caught_exception ? Heap::true_value() : Heap::false_value()); |
- details->set(3, FixedArray::cast(result.GetCallbackObject())->get(0)); |
- details->set(4, FixedArray::cast(result.GetCallbackObject())->get(1)); |
- } |
- |
- return *Factory::NewJSArrayWithElements(details); |
- } |
return Heap::undefined_value(); |
} |
@@ -6271,7 +6292,7 @@ |
if (function_context->has_extension() && |
!function_context->IsGlobalContext()) { |
Handle<JSObject> ext(JSObject::cast(function_context->extension())); |
- Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext); |
+ Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS); |
for (int i = 0; i < keys->length(); i++) { |
// Names of variables introduced by eval are strings. |
ASSERT(keys->get(i)->IsString()); |
@@ -6320,7 +6341,7 @@ |
// be variables introduced by eval. |
if (context->has_extension()) { |
Handle<JSObject> ext(JSObject::cast(context->extension())); |
- Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext); |
+ Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS); |
for (int i = 0; i < keys->length(); i++) { |
// Names of variables introduced by eval are strings. |
ASSERT(keys->get(i)->IsString()); |