Chromium Code Reviews| Index: src/runtime.cc |
| diff --git a/src/runtime.cc b/src/runtime.cc |
| index ee7fc8ea834f345debfb8c3c7d74d33b9363dc21..31e31a31caf85072adc11efcccef711dc9422a87 100644 |
| --- a/src/runtime.cc |
| +++ b/src/runtime.cc |
| @@ -614,31 +614,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHandler) { |
| } |
| -RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateCatchExtensionObject) { |
| - ASSERT(args.length() == 2); |
| - CONVERT_CHECKED(String, key, args[0]); |
| - Object* value = args[1]; |
| - ASSERT(!value->IsFailure()); |
| - // Create a catch context extension object. |
| - JSFunction* constructor = |
| - isolate->context()->global_context()-> |
| - context_extension_function(); |
| - Object* object; |
| - { MaybeObject* maybe_object = isolate->heap()->AllocateJSObject(constructor); |
| - if (!maybe_object->ToObject(&object)) return maybe_object; |
| - } |
| - // Assign the exception value to the catch variable and make sure |
| - // that the catch variable is DontDelete. |
| - { MaybeObject* maybe_value = |
| - // Passing non-strict per ECMA-262 5th Ed. 12.14. Catch, bullet #4. |
| - JSObject::cast(object)->SetProperty( |
| - key, value, DONT_DELETE, kNonStrictMode); |
| - if (!maybe_value->ToObject(&value)) return maybe_value; |
| - } |
| - return object; |
| -} |
| - |
| - |
| RUNTIME_FUNCTION(MaybeObject*, Runtime_ClassOf) { |
| NoHandleAllocation ha; |
| ASSERT(args.length() == 1); |
| @@ -1310,7 +1285,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) { |
| Handle<JSObject> context_ext; |
| if (context->has_extension()) { |
| // The function context's extension context exists - use it. |
| - context_ext = Handle<JSObject>(context->extension()); |
| + context_ext = Handle<JSObject>(JSObject::cast(context->extension())); |
| } else { |
| // The function context's extension context does not exists - allocate |
| // it. |
| @@ -7942,12 +7917,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_PushWithContext) { |
| RUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) { |
| NoHandleAllocation ha; |
| - ASSERT(args.length() == 1); |
| - JSObject* extension_object = JSObject::cast(args[0]); |
| + ASSERT(args.length() == 2); |
| + String* name = String::cast(args[0]); |
| + Object* thrown_object = args[1]; |
| Context* context; |
| MaybeObject* maybe_context = |
| isolate->heap()->AllocateCatchContext(isolate->context(), |
| - extension_object); |
| + name, |
| + thrown_object); |
| if (!maybe_context->To(&context)) return maybe_context; |
| isolate->set_context(context); |
| return context; |
| @@ -10200,6 +10177,23 @@ static Handle<JSObject> MaterializeClosure(Isolate* isolate, |
| } |
| +// Create a plain JSObject which materializes the scope for the specified |
| +// catch context. |
| +static Handle<JSObject> MaterializeCatchScope(Isolate* isolate, |
| + Handle<Context> context) { |
| + ASSERT(context->IsCatchContext()); |
| + Handle<String> name(String::cast(context->extension())); |
| + Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX)); |
| + Handle<JSObject> catch_scope = |
| + isolate->factory()->NewJSObject(isolate->object_function()); |
|
Mads Ager (chromium)
2011/06/14 11:54:17
Do we really want this to be a plain JSObject. Don
Kevin Millikin (Chromium)
2011/06/14 12:06:35
I'm pretty sure this is what we want. This is an
Søren Thygesen Gjesse
2011/06/14 12:18:32
It looks fine. The objects representing the differ
|
| + RETURN_IF_EMPTY_HANDLE_VALUE( |
| + isolate, |
| + SetProperty(catch_scope, name, thrown_object, NONE, kNonStrictMode), |
| + Handle<JSObject>()); |
| + return catch_scope; |
| +} |
| + |
| + |
| // Iterate over the actual scopes visible from a stack frame. All scopes are |
| // backed by an actual context except the local scope, which is inserted |
| // "artifically" in the context chain. |
| @@ -10210,10 +10204,6 @@ class ScopeIterator { |
| ScopeTypeLocal, |
| ScopeTypeWith, |
| ScopeTypeClosure, |
| - // Every catch block contains an implicit with block (its parameter is |
| - // a JSContextExtensionObject) that extends current scope with a variable |
| - // holding exception object. Such with blocks are treated as scopes of their |
| - // own type. |
| ScopeTypeCatch |
| }; |
| @@ -10291,12 +10281,7 @@ class ScopeIterator { |
| return ScopeTypeClosure; |
| } |
| ASSERT(context_->has_extension()); |
| - // Current scope is either an explicit with statement or a with statement |
| - // implicitely generated for a catch block. |
| - // If the extension object here is a JSContextExtensionObject then |
| - // current with statement is one frome a catch block otherwise it's a |
| - // regular with statement. |
| - if (context_->extension()->IsJSContextExtensionObject()) { |
| + if (context_->IsCatchContext()) { |
| return ScopeTypeCatch; |
| } |
| return ScopeTypeWith; |
| @@ -10307,20 +10292,17 @@ class ScopeIterator { |
| switch (Type()) { |
| case ScopeIterator::ScopeTypeGlobal: |
| return Handle<JSObject>(CurrentContext()->global()); |
| - break; |
| case ScopeIterator::ScopeTypeLocal: |
| // Materialize the content of the local scope into a JSObject. |
| return MaterializeLocalScope(isolate_, frame_); |
| - break; |
| case ScopeIterator::ScopeTypeWith: |
| - case ScopeIterator::ScopeTypeCatch: |
| // Return the with object. |
| - return Handle<JSObject>(CurrentContext()->extension()); |
| - break; |
| + return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); |
| + case ScopeIterator::ScopeTypeCatch: |
| + return MaterializeCatchScope(isolate_, CurrentContext()); |
| case ScopeIterator::ScopeTypeClosure: |
| // Materialize the content of the closure scope into a JSObject. |
| return MaterializeClosure(isolate_, CurrentContext()); |
| - break; |
| } |
| UNREACHABLE(); |
| return Handle<JSObject>(); |
| @@ -10351,8 +10333,7 @@ class ScopeIterator { |
| if (!CurrentContext().is_null()) { |
| CurrentContext()->Print(); |
| if (CurrentContext()->has_extension()) { |
| - Handle<JSObject> extension = |
| - Handle<JSObject>(CurrentContext()->extension()); |
| + Handle<Object> extension(CurrentContext()->extension()); |
| if (extension->IsJSContextExtensionObject()) { |
| extension->Print(); |
| } |
| @@ -10361,34 +10342,27 @@ class ScopeIterator { |
| break; |
| } |
| - case ScopeIterator::ScopeTypeWith: { |
| + case ScopeIterator::ScopeTypeWith: |
| PrintF("With:\n"); |
| - Handle<JSObject> extension = |
| - Handle<JSObject>(CurrentContext()->extension()); |
| - extension->Print(); |
| + CurrentContext()->extension()->Print(); |
| break; |
| - } |
| - case ScopeIterator::ScopeTypeCatch: { |
| + case ScopeIterator::ScopeTypeCatch: |
| PrintF("Catch:\n"); |
| - Handle<JSObject> extension = |
| - Handle<JSObject>(CurrentContext()->extension()); |
| - extension->Print(); |
| + CurrentContext()->extension()->Print(); |
| + CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print(); |
| break; |
| - } |
| - case ScopeIterator::ScopeTypeClosure: { |
| + case ScopeIterator::ScopeTypeClosure: |
| PrintF("Closure:\n"); |
| CurrentContext()->Print(); |
| if (CurrentContext()->has_extension()) { |
| - Handle<JSObject> extension = |
| - Handle<JSObject>(CurrentContext()->extension()); |
| + Handle<Object> extension(CurrentContext()->extension()); |
| if (extension->IsJSContextExtensionObject()) { |
| extension->Print(); |
| } |
| } |
| break; |
| - } |
| default: |
| UNREACHABLE(); |
| @@ -10867,10 +10841,17 @@ static Handle<Context> CopyWithContextChain(Isolate* isolate, |
| HandleScope scope(isolate); |
| Handle<Context> previous(current->previous()); |
| Handle<Context> new_previous = CopyWithContextChain(isolate, previous, base); |
| - Handle<JSObject> extension(JSObject::cast(current->extension())); |
| - Handle<Context> new_current = current->IsCatchContext() |
| - ? isolate->factory()->NewCatchContext(new_previous, extension) |
| - : isolate->factory()->NewWithContext(new_previous, extension); |
| + Handle<Context> new_current; |
| + if (current->IsCatchContext()) { |
| + Handle<String> name(String::cast(current->extension())); |
| + Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX)); |
| + new_current = |
| + isolate->factory()->NewCatchContext(new_previous, name, thrown_object); |
| + } else { |
| + Handle<JSObject> extension(JSObject::cast(current->extension())); |
| + new_current = |
| + isolate->factory()->NewWithContext(new_previous, extension); |
| + } |
| return scope.CloseAndEscape(new_current); |
| } |