| Index: src/runtime.cc
|
| diff --git a/src/runtime.cc b/src/runtime.cc
|
| index b5f04e3f31f7359246105bbd65f13d13c318056f..a1c98331711bd4c7bef7c3179aa3960c10523ed7 100644
|
| --- a/src/runtime.cc
|
| +++ b/src/runtime.cc
|
| @@ -4155,6 +4155,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) {
|
| ASSERT(args.length() == 2);
|
| CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
|
| CONVERT_ARG_HANDLE_CHECKED(String, key, 1);
|
| + // In rare cases the global object backing the global proxy may already be
|
| + // invalid. In that case, return undefined.
|
| + if (object->IsJSGlobalProxy() &&
|
| + !object->GetPrototype()->IsJSGlobalObject()) {
|
| + return isolate->heap()->undefined_value();
|
| + }
|
| LookupResult lookup(isolate);
|
| object->LookupRealNamedProperty(*key, &lookup);
|
| if (!lookup.IsFound()) return isolate->heap()->undefined_value();
|
| @@ -4644,14 +4650,21 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) {
|
| }
|
|
|
|
|
| -RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) {
|
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNamesNoSideEffect) {
|
| HandleScope scope(isolate);
|
| ASSERT(args.length() == 1);
|
| CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
|
| + // In rare cases the global object backing the global proxy may already be
|
| + // invalid. In that case, return an empty array.
|
| + if (object->IsJSGlobalProxy() &&
|
| + !object->GetPrototype()->IsJSGlobalObject()) {
|
| + return *isolate->factory()->NewJSArray(0);
|
| + }
|
| bool threw = false;
|
| - Handle<JSArray> result = GetKeysFor(object, &threw);
|
| + Handle<FixedArray> elements =
|
| + GetKeysInFixedArrayFor<false>(object, INCLUDE_PROTOS, &threw);
|
| if (threw) return Failure::Exception();
|
| - return *result;
|
| + return *isolate->factory()->NewJSArrayWithElements(elements);
|
| }
|
|
|
|
|
| @@ -4671,7 +4684,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNamesFast) {
|
| Handle<JSReceiver> object(raw_object);
|
| bool threw = false;
|
| Handle<FixedArray> content =
|
| - GetKeysInFixedArrayFor(object, INCLUDE_PROTOS, &threw);
|
| + GetKeysInFixedArrayFor<true>(object, INCLUDE_PROTOS, &threw);
|
| if (threw) return Failure::Exception();
|
|
|
| // Test again, since cache may have been built by preceding call.
|
| @@ -4871,7 +4884,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LocalKeys) {
|
|
|
| bool threw = false;
|
| Handle<FixedArray> contents =
|
| - GetKeysInFixedArrayFor(object, LOCAL_ONLY, &threw);
|
| + GetKeysInFixedArrayFor<true>(object, LOCAL_ONLY, &threw);
|
| if (threw) return Failure::Exception();
|
|
|
| // Some fast paths through GetKeysInFixedArrayFor reuse a cached
|
| @@ -10021,7 +10034,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) {
|
| // keys that are not integers in the range 0 to length-1.
|
| bool threw = false;
|
| Handle<FixedArray> keys =
|
| - GetKeysInFixedArrayFor(array, INCLUDE_PROTOS, &threw);
|
| + GetKeysInFixedArrayFor<true>(array, INCLUDE_PROTOS, &threw);
|
| if (threw) return Failure::Exception();
|
|
|
| int keys_length = keys->length();
|
| @@ -10836,7 +10849,7 @@ static Handle<JSObject> MaterializeLocalScopeWithFrameInspector(
|
| Handle<JSObject> ext(JSObject::cast(function_context->extension()));
|
| bool threw = false;
|
| Handle<FixedArray> keys =
|
| - GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw);
|
| + GetKeysInFixedArrayFor<true>(ext, INCLUDE_PROTOS, &threw);
|
| if (threw) return Handle<JSObject>();
|
|
|
| for (int i = 0; i < keys->length(); i++) {
|
| @@ -10987,7 +11000,7 @@ static Handle<JSObject> MaterializeClosure(Isolate* isolate,
|
| Handle<JSObject> ext(JSObject::cast(context->extension()));
|
| bool threw = false;
|
| Handle<FixedArray> keys =
|
| - GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw);
|
| + GetKeysInFixedArrayFor<true>(ext, INCLUDE_PROTOS, &threw);
|
| if (threw) return Handle<JSObject>();
|
|
|
| for (int i = 0; i < keys->length(); i++) {
|
| @@ -13078,30 +13091,31 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_MarkOneShotGetter) {
|
|
|
| // Retrieve the stack trace. This could be the raw stack trace collected
|
| // on stack overflow or the already formatted stack trace string.
|
| -RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOverflowedStackTrace) {
|
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOverflowStackTrace) {
|
| HandleScope scope(isolate);
|
| ASSERT_EQ(args.length(), 1);
|
| CONVERT_ARG_CHECKED(JSObject, error_object, 0);
|
| - String* key = isolate->heap()->hidden_stack_trace_symbol();
|
| + String* key = isolate->heap()->overflow_stack_trace_symbol();
|
| Object* result = error_object->GetHiddenProperty(key);
|
| RUNTIME_ASSERT(result->IsJSArray() ||
|
| result->IsString() ||
|
| + result->IsJSObject() ||
|
| result->IsUndefined());
|
| return result;
|
| }
|
|
|
|
|
| // Set or clear the stack trace attached to an stack overflow error object.
|
| -RUNTIME_FUNCTION(MaybeObject*, Runtime_SetOverflowedStackTrace) {
|
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_SetOverflowStackTrace) {
|
| HandleScope scope(isolate);
|
| ASSERT_EQ(args.length(), 2);
|
| CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
|
| CONVERT_ARG_HANDLE_CHECKED(HeapObject, value, 1);
|
| - Handle<String> key = isolate->factory()->hidden_stack_trace_symbol();
|
| + Handle<String> key = isolate->factory()->overflow_stack_trace_symbol();
|
| if (value->IsUndefined()) {
|
| error_object->DeleteHiddenProperty(*key);
|
| } else {
|
| - RUNTIME_ASSERT(value->IsString());
|
| + RUNTIME_ASSERT(value->IsString() || value->IsJSObject());
|
| JSObject::SetHiddenProperty(error_object, key, value);
|
| }
|
| return *error_object;
|
|
|