| Index: src/runtime.cc
|
| diff --git a/src/runtime.cc b/src/runtime.cc
|
| index 82733a7c1d35ea4d65646f3e33fc31fca3f5e3bb..e3dba22bf66e21e182445f758c1280a161f11843 100644
|
| --- a/src/runtime.cc
|
| +++ b/src/runtime.cc
|
| @@ -8314,6 +8314,30 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) {
|
| }
|
|
|
|
|
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_PushBlockContext) {
|
| + NoHandleAllocation ha;
|
| + ASSERT(args.length() == 2);
|
| + SerializedScopeInfo* scope_info = SerializedScopeInfo::cast(args[0]);
|
| + 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()->AllocateBlockContext(function,
|
| + isolate->context(),
|
| + scope_info);
|
| + if (!maybe_context->To(&context)) return maybe_context;
|
| + isolate->set_context(context);
|
| + return context;
|
| +}
|
| +
|
| +
|
| RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) {
|
| HandleScope scope(isolate);
|
| ASSERT(args.length() == 2);
|
| @@ -10639,6 +10663,34 @@ static Handle<JSObject> MaterializeCatchScope(Isolate* isolate,
|
| }
|
|
|
|
|
| +// Create a plain JSObject which materializes the block scope for the specified
|
| +// block context.
|
| +static Handle<JSObject> MaterializeBlockScope(
|
| + Isolate* isolate,
|
| + Handle<Context> context) {
|
| + ASSERT(context->IsBlockContext());
|
| + Handle<SerializedScopeInfo> serialized_scope_info(
|
| + SerializedScopeInfo::cast(context->extension()));
|
| + ScopeInfo<> scope_info(*serialized_scope_info);
|
| +
|
| + // Allocate and initialize a JSObject with all the arguments, stack locals
|
| + // heap locals and extension properties of the debugged function.
|
| + Handle<JSObject> block_scope =
|
| + isolate->factory()->NewJSObject(isolate->object_function());
|
| +
|
| + // Fill all context locals.
|
| + if (scope_info.number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) {
|
| + if (!CopyContextLocalsToScopeObject(isolate,
|
| + serialized_scope_info, scope_info,
|
| + context, block_scope)) {
|
| + return Handle<JSObject>();
|
| + }
|
| + }
|
| +
|
| + return block_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.
|
| @@ -10649,7 +10701,8 @@ class ScopeIterator {
|
| ScopeTypeLocal,
|
| ScopeTypeWith,
|
| ScopeTypeClosure,
|
| - ScopeTypeCatch
|
| + ScopeTypeCatch,
|
| + ScopeTypeBlock
|
| };
|
|
|
| ScopeIterator(Isolate* isolate,
|
| @@ -10675,8 +10728,10 @@ class ScopeIterator {
|
| } else if (context_->IsFunctionContext()) {
|
| at_local_ = true;
|
| } else if (context_->closure() != *function_) {
|
| - // The context_ is a with or catch block from the outer function.
|
| - ASSERT(context_->IsWithContext() || context_->IsCatchContext());
|
| + // The context_ is a block or with or catch block from the outer function.
|
| + ASSERT(context_->IsWithContext() ||
|
| + context_->IsCatchContext() ||
|
| + context_->IsBlockContext());
|
| at_local_ = true;
|
| }
|
| }
|
| @@ -10731,6 +10786,9 @@ class ScopeIterator {
|
| if (context_->IsCatchContext()) {
|
| return ScopeTypeCatch;
|
| }
|
| + if (context_->IsBlockContext()) {
|
| + return ScopeTypeBlock;
|
| + }
|
| ASSERT(context_->IsWithContext());
|
| return ScopeTypeWith;
|
| }
|
| @@ -10751,6 +10809,8 @@ class ScopeIterator {
|
| case ScopeIterator::ScopeTypeClosure:
|
| // Materialize the content of the closure scope into a JSObject.
|
| return MaterializeClosure(isolate_, CurrentContext());
|
| + case ScopeIterator::ScopeTypeBlock:
|
| + return MaterializeBlockScope(isolate_, CurrentContext());
|
| }
|
| UNREACHABLE();
|
| return Handle<JSObject>();
|
| @@ -11307,7 +11367,13 @@ static Handle<Context> CopyWithContextChain(Isolate* isolate,
|
| new_previous,
|
| name,
|
| thrown_object);
|
| + } else if (current->IsBlockContext()) {
|
| + Handle<SerializedScopeInfo> scope_info(
|
| + SerializedScopeInfo::cast(current->extension()));
|
| + new_current =
|
| + isolate->factory()->NewBlockContext(function, new_previous, scope_info);
|
| } else {
|
| + ASSERT(current->IsWithContext());
|
| Handle<JSObject> extension(JSObject::cast(current->extension()));
|
| new_current =
|
| isolate->factory()->NewWithContext(function, new_previous, extension);
|
|
|