Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index 1de2b4a9358b84da1927a028fb118bb1fde47960..c118f827b2644a0d3e297a054d0953ca2cc39ab2 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -8049,7 +8049,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewFunctionContext) { |
RUNTIME_FUNCTION(MaybeObject*, Runtime_PushWithContext) { |
NoHandleAllocation ha; |
- ASSERT(args.length() == 1); |
+ ASSERT(args.length() == 2); |
JSObject* extension_object; |
if (args[0]->IsJSObject()) { |
extension_object = JSObject::cast(args[0]); |
@@ -8070,9 +8070,20 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_PushWithContext) { |
} |
} |
+ JSFunction* function; |
+ if (args[1]->IsSmi()) { |
+ // A smi sentinel indicates a context nested inside global code rather |
+ // than some function. There is a canonical empty function that can be |
+ // gotten from the global context. |
+ function = isolate->context()->global_context()->closure(); |
+ } else { |
+ function = JSFunction::cast(args[1]); |
+ } |
+ |
Context* context; |
MaybeObject* maybe_context = |
- isolate->heap()->AllocateWithContext(isolate->context(), |
+ isolate->heap()->AllocateWithContext(function, |
+ isolate->context(), |
extension_object); |
if (!maybe_context->To(&context)) return maybe_context; |
isolate->set_context(context); |
@@ -8082,12 +8093,22 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_PushWithContext) { |
RUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) { |
NoHandleAllocation ha; |
- ASSERT(args.length() == 2); |
+ ASSERT(args.length() == 3); |
String* name = String::cast(args[0]); |
Object* thrown_object = args[1]; |
+ JSFunction* function; |
+ if (args[2]->IsSmi()) { |
+ // A smi sentinel indicates a context nested inside global code rather |
+ // than some function. There is a canonical empty function that can be |
+ // gotten from the global context. |
+ function = isolate->context()->global_context()->closure(); |
+ } else { |
+ function = JSFunction::cast(args[2]); |
+ } |
Context* context; |
MaybeObject* maybe_context = |
- isolate->heap()->AllocateCatchContext(isolate->context(), |
+ isolate->heap()->AllocateCatchContext(function, |
+ isolate->context(), |
name, |
thrown_object); |
if (!maybe_context->To(&context)) return maybe_context; |
@@ -10967,6 +10988,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearStepping) { |
// Creates a copy of the with context chain. The copy of the context chain is |
// is linked to the function context supplied. |
static Handle<Context> CopyWithContextChain(Isolate* isolate, |
+ Handle<JSFunction> function, |
Handle<Context> current, |
Handle<Context> base) { |
// At the end of the chain. Return the base context to link to. |
@@ -10977,17 +10999,21 @@ static Handle<Context> CopyWithContextChain(Isolate* isolate, |
// Recursively copy the with and catch contexts. |
HandleScope scope(isolate); |
Handle<Context> previous(current->previous()); |
- Handle<Context> new_previous = CopyWithContextChain(isolate, previous, base); |
+ Handle<Context> new_previous = |
+ CopyWithContextChain(isolate, function, previous, base); |
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); |
+ isolate->factory()->NewCatchContext(function, |
+ new_previous, |
+ name, |
+ thrown_object); |
} else { |
Handle<JSObject> extension(JSObject::cast(current->extension())); |
new_current = |
- isolate->factory()->NewWithContext(new_previous, extension); |
+ isolate->factory()->NewWithContext(function, new_previous, extension); |
} |
return scope.CloseAndEscape(new_current); |
} |
@@ -11118,11 +11144,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { |
// Copy any with contexts present and chain them in front of this context. |
Handle<Context> frame_context(Context::cast(frame->context())); |
Handle<Context> function_context(frame_context->declaration_context()); |
- context = CopyWithContextChain(isolate, frame_context, context); |
+ context = CopyWithContextChain(isolate, go_between, frame_context, context); |
if (additional_context->IsJSObject()) { |
Handle<JSObject> extension = Handle<JSObject>::cast(additional_context); |
- context = isolate->factory()->NewWithContext(context, extension); |
+ context = isolate->factory()->NewWithContext(go_between, context, extension); |
} |
// Wrap the evaluation statement in a new function compiled in the newly |