Chromium Code Reviews| Index: src/runtime.cc |
| diff --git a/src/runtime.cc b/src/runtime.cc |
| index 7b7a3e48ab809102e771d19723713eb4b9409da4..aaa97162a1e76d3f4a7c77126510bb16b3da08e3 100644 |
| --- a/src/runtime.cc |
| +++ b/src/runtime.cc |
| @@ -11015,10 +11015,10 @@ static Handle<JSObject> MaterializeModuleScope( |
| } |
| -// Iterate over the actual scopes visible from a stack frame. The iteration |
| -// proceeds from the innermost visible nested scope outwards. All scopes are |
| -// backed by an actual context except the local scope, which is inserted |
| -// "artificially" in the context chain. |
| +// Iterate over the actual scopes visible from a stack frame or from a closure. |
| +// The iteration proceeds from the innermost visible nested scope outwards. |
| +// All scopes are backed by an actual context except the local scope, |
| +// which is inserted "artificially" in the context chain. |
| class ScopeIterator { |
| public: |
| enum ScopeType { |
| @@ -11119,6 +11119,18 @@ class ScopeIterator { |
| } |
| } |
| + ScopeIterator(Isolate* isolate, |
| + Handle<JSFunction> function) |
| + : isolate_(isolate), |
| + frame_(NULL), |
| + inlined_jsframe_index_(0), |
| + function_(function), |
| + context_(function->context()) { |
| + if (function->IsBuiltin()) { |
| + context_ = Handle<Context>(); |
| + } |
| + } |
| + |
| // More scopes? |
| bool Done() { return context_.is_null(); } |
| @@ -11339,6 +11351,22 @@ static const int kScopeDetailsTypeIndex = 0; |
| static const int kScopeDetailsObjectIndex = 1; |
| static const int kScopeDetailsSize = 2; |
| + |
| +static MaybeObject* MaterializeScopeDetails(Isolate* isolate, |
| + ScopeIterator* it) { |
| + // Calculate the size of the result. |
| + int details_size = kScopeDetailsSize; |
| + Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size); |
| + |
| + // Fill in scope details. |
| + details->set(kScopeDetailsTypeIndex, Smi::FromInt(it->Type())); |
| + Handle<JSObject> scope_object = it->ScopeObject(); |
| + RETURN_IF_EMPTY_HANDLE(isolate, scope_object); |
| + details->set(kScopeDetailsObjectIndex, *scope_object); |
| + |
| + return *isolate->factory()->NewJSArrayWithElements(details); |
| +} |
| + |
| // Return an array with scope details |
| // args[0]: number: break id |
| // args[1]: number: frame index |
| @@ -11376,18 +11404,48 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) { |
| if (it.Done()) { |
| return isolate->heap()->undefined_value(); |
| } |
| + return MaterializeScopeDetails(isolate, &it); |
| +} |
| - // Calculate the size of the result. |
| - int details_size = kScopeDetailsSize; |
| - Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size); |
| - // Fill in scope details. |
| - details->set(kScopeDetailsTypeIndex, Smi::FromInt(it.Type())); |
| - Handle<JSObject> scope_object = it.ScopeObject(); |
| - RETURN_IF_EMPTY_HANDLE(isolate, scope_object); |
| - details->set(kScopeDetailsObjectIndex, *scope_object); |
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionScopeCount) { |
| + HandleScope scope(isolate); |
| + ASSERT(args.length() == 1); |
| - return *isolate->factory()->NewJSArrayWithElements(details); |
| + // Check arguments. |
| + CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); |
| + |
| + // Count the visible scopes. |
| + int n = 0; |
| + for (ScopeIterator it(isolate, fun); |
|
ulan
2012/04/25 14:14:55
This fits in one line.
Peter Rybin
2012/04/25 22:56:49
Done.
|
| + !it.Done(); |
| + it.Next()) { |
| + n++; |
| + } |
| + |
| + return Smi::FromInt(n); |
| +} |
| + |
| + |
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionScopeDetails) { |
| + HandleScope scope(isolate); |
| + ASSERT(args.length() == 2); |
| + |
| + // Check arguments. |
| + CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); |
| + CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); |
| + |
| + // Find the requested scope. |
| + int n = 0; |
| + ScopeIterator it(isolate, fun); |
| + for (; !it.Done() && n < index; it.Next()) { |
| + n++; |
| + } |
| + if (it.Done()) { |
| + return isolate->heap()->undefined_value(); |
| + } |
| + |
| + return MaterializeScopeDetails(isolate, &it); |
| } |