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); |
} |