| Index: src/runtime.cc
|
| diff --git a/src/runtime.cc b/src/runtime.cc
|
| index d50e5ee8d0361cee87b04de8ffd6e131428ad979..ab462490e193fc78d76279939cc3f4678edfcc59 100644
|
| --- a/src/runtime.cc
|
| +++ b/src/runtime.cc
|
| @@ -10843,7 +10843,8 @@ class ScopeIterator {
|
| inlined_jsframe_index_(inlined_jsframe_index),
|
| function_(JSFunction::cast(frame->function())),
|
| context_(Context::cast(frame->context())),
|
| - nested_scope_chain_(4) {
|
| + nested_scope_chain_(4),
|
| + failed_(false) {
|
|
|
| // Catch the case when the debugger stops in an internal function.
|
| Handle<SharedFunctionInfo> shared_info(function_->shared());
|
| @@ -10917,17 +10918,24 @@ class ScopeIterator {
|
| frame_(NULL),
|
| inlined_jsframe_index_(0),
|
| function_(function),
|
| - context_(function->context()) {
|
| + context_(function->context()),
|
| + failed_(false) {
|
| if (function->IsBuiltin()) {
|
| context_ = Handle<Context>();
|
| }
|
| }
|
|
|
| // More scopes?
|
| - bool Done() { return context_.is_null(); }
|
| + bool Done() {
|
| + ASSERT(!failed_);
|
| + return context_.is_null();
|
| + }
|
| +
|
| + bool Failed() { return failed_; }
|
|
|
| // Move to the next scope.
|
| void Next() {
|
| + ASSERT(!failed_);
|
| ScopeType scope_type = Type();
|
| if (scope_type == ScopeTypeGlobal) {
|
| // The global scope is always the last in the chain.
|
| @@ -10948,6 +10956,7 @@ class ScopeIterator {
|
|
|
| // Return the type of the current scope.
|
| ScopeType Type() {
|
| + ASSERT(!failed_);
|
| if (!nested_scope_chain_.is_empty()) {
|
| Handle<ScopeInfo> scope_info = nested_scope_chain_.last();
|
| switch (scope_info->Type()) {
|
| @@ -10997,6 +11006,7 @@ class ScopeIterator {
|
|
|
| // Return the JavaScript object with the content of the current scope.
|
| Handle<JSObject> ScopeObject() {
|
| + ASSERT(!failed_);
|
| switch (Type()) {
|
| case ScopeIterator::ScopeTypeGlobal:
|
| return Handle<JSObject>(CurrentContext()->global_object());
|
| @@ -11022,6 +11032,7 @@ class ScopeIterator {
|
| }
|
|
|
| Handle<ScopeInfo> CurrentScopeInfo() {
|
| + ASSERT(!failed_);
|
| if (!nested_scope_chain_.is_empty()) {
|
| return nested_scope_chain_.last();
|
| } else if (context_->IsBlockContext()) {
|
| @@ -11035,6 +11046,7 @@ class ScopeIterator {
|
| // Return the context for this scope. For the local context there might not
|
| // be an actual context.
|
| Handle<Context> CurrentContext() {
|
| + ASSERT(!failed_);
|
| if (Type() == ScopeTypeGlobal ||
|
| nested_scope_chain_.is_empty()) {
|
| return context_;
|
| @@ -11048,6 +11060,7 @@ class ScopeIterator {
|
| #ifdef DEBUG
|
| // Debug print of the content of the current scope.
|
| void DebugPrint() {
|
| + ASSERT(!failed_);
|
| switch (Type()) {
|
| case ScopeIterator::ScopeTypeGlobal:
|
| PrintF("Global:\n");
|
| @@ -11105,6 +11118,7 @@ class ScopeIterator {
|
| Handle<JSFunction> function_;
|
| Handle<Context> context_;
|
| List<Handle<ScopeInfo> > nested_scope_chain_;
|
| + bool failed_;
|
|
|
| void RetrieveScopeChain(Scope* scope,
|
| Handle<SharedFunctionInfo> shared_info) {
|
| @@ -11117,7 +11131,9 @@ class ScopeIterator {
|
| // faulty. We fail in debug mode but in release mode we only provide the
|
| // information we get from the context chain but nothing about
|
| // completely stack allocated scopes or stack allocated locals.
|
| - UNREACHABLE();
|
| + // Or it could be due to stack overflow.
|
| + ASSERT(isolate_->has_pending_exception());
|
| + failed_ = true;
|
| }
|
| }
|
|
|
| @@ -11542,6 +11558,8 @@ static Handle<Context> CopyNestedScopeContextChain(Isolate* isolate,
|
| List<Handle<Context> > context_chain;
|
|
|
| ScopeIterator it(isolate, frame, inlined_jsframe_index);
|
| + if (it.Failed()) return Handle<Context>::null();
|
| +
|
| for (; it.Type() != ScopeIterator::ScopeTypeGlobal &&
|
| it.Type() != ScopeIterator::ScopeTypeLocal ; it.Next()) {
|
| ASSERT(!it.Done());
|
| @@ -11570,9 +11588,7 @@ static Handle<Context> CopyNestedScopeContextChain(Isolate* isolate,
|
| // Materialize the contents of the block scope into a JSObject.
|
| Handle<JSObject> block_scope_object =
|
| MaterializeBlockScope(isolate, current);
|
| - if (block_scope_object.is_null()) {
|
| - return Handle<Context>::null();
|
| - }
|
| + CHECK(!block_scope_object.is_null());
|
| // Allocate a new function context for the debug evaluation and set the
|
| // extension object.
|
| Handle<Context> new_context =
|
| @@ -11733,6 +11749,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
|
| context,
|
| frame,
|
| inlined_jsframe_index);
|
| + if (context.is_null()) {
|
| + ASSERT(isolate->has_pending_exception());
|
| + MaybeObject* exception = isolate->pending_exception();
|
| + isolate->clear_pending_exception();
|
| + return exception;
|
| + }
|
|
|
| if (additional_context->IsJSObject()) {
|
| Handle<JSObject> extension = Handle<JSObject>::cast(additional_context);
|
|
|