OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 10997 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11008 // Fill all context locals. | 11008 // Fill all context locals. |
11009 if (!CopyContextLocalsToScopeObject( | 11009 if (!CopyContextLocalsToScopeObject( |
11010 isolate, scope_info, context, module_scope)) { | 11010 isolate, scope_info, context, module_scope)) { |
11011 return Handle<JSObject>(); | 11011 return Handle<JSObject>(); |
11012 } | 11012 } |
11013 | 11013 |
11014 return module_scope; | 11014 return module_scope; |
11015 } | 11015 } |
11016 | 11016 |
11017 | 11017 |
11018 // Iterate over the actual scopes visible from a stack frame. The iteration | 11018 // Iterate over the actual scopes visible from a stack frame or from a closure. |
11019 // proceeds from the innermost visible nested scope outwards. All scopes are | 11019 // The iteration proceeds from the innermost visible nested scope outwards. |
11020 // backed by an actual context except the local scope, which is inserted | 11020 // All scopes are backed by an actual context except the local scope, |
11021 // "artificially" in the context chain. | 11021 // which is inserted "artificially" in the context chain. |
11022 class ScopeIterator { | 11022 class ScopeIterator { |
11023 public: | 11023 public: |
11024 enum ScopeType { | 11024 enum ScopeType { |
11025 ScopeTypeGlobal = 0, | 11025 ScopeTypeGlobal = 0, |
11026 ScopeTypeLocal, | 11026 ScopeTypeLocal, |
11027 ScopeTypeWith, | 11027 ScopeTypeWith, |
11028 ScopeTypeClosure, | 11028 ScopeTypeClosure, |
11029 ScopeTypeCatch, | 11029 ScopeTypeCatch, |
11030 ScopeTypeBlock, | 11030 ScopeTypeBlock, |
11031 ScopeTypeModule | 11031 ScopeTypeModule |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11112 // A failed reparse indicates that the preparser has diverged from the | 11112 // A failed reparse indicates that the preparser has diverged from the |
11113 // parser or that the preparse data given to the initial parse has been | 11113 // parser or that the preparse data given to the initial parse has been |
11114 // faulty. We fail in debug mode but in release mode we only provide the | 11114 // faulty. We fail in debug mode but in release mode we only provide the |
11115 // information we get from the context chain but nothing about | 11115 // information we get from the context chain but nothing about |
11116 // completely stack allocated scopes or stack allocated locals. | 11116 // completely stack allocated scopes or stack allocated locals. |
11117 UNREACHABLE(); | 11117 UNREACHABLE(); |
11118 } | 11118 } |
11119 } | 11119 } |
11120 } | 11120 } |
11121 | 11121 |
11122 ScopeIterator(Isolate* isolate, | |
11123 Handle<JSFunction> function) | |
11124 : isolate_(isolate), | |
11125 frame_(NULL), | |
11126 inlined_jsframe_index_(0), | |
11127 function_(function), | |
11128 context_(function->context()) { | |
11129 if (function->IsBuiltin()) { | |
11130 context_ = Handle<Context>(); | |
11131 } | |
11132 } | |
11133 | |
11122 // More scopes? | 11134 // More scopes? |
11123 bool Done() { return context_.is_null(); } | 11135 bool Done() { return context_.is_null(); } |
11124 | 11136 |
11125 // Move to the next scope. | 11137 // Move to the next scope. |
11126 void Next() { | 11138 void Next() { |
11127 ScopeType scope_type = Type(); | 11139 ScopeType scope_type = Type(); |
11128 if (scope_type == ScopeTypeGlobal) { | 11140 if (scope_type == ScopeTypeGlobal) { |
11129 // The global scope is always the last in the chain. | 11141 // The global scope is always the last in the chain. |
11130 ASSERT(context_->IsGlobalContext()); | 11142 ASSERT(context_->IsGlobalContext()); |
11131 context_ = Handle<Context>(); | 11143 context_ = Handle<Context>(); |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11332 } | 11344 } |
11333 | 11345 |
11334 return Smi::FromInt(n); | 11346 return Smi::FromInt(n); |
11335 } | 11347 } |
11336 | 11348 |
11337 | 11349 |
11338 static const int kScopeDetailsTypeIndex = 0; | 11350 static const int kScopeDetailsTypeIndex = 0; |
11339 static const int kScopeDetailsObjectIndex = 1; | 11351 static const int kScopeDetailsObjectIndex = 1; |
11340 static const int kScopeDetailsSize = 2; | 11352 static const int kScopeDetailsSize = 2; |
11341 | 11353 |
11354 | |
11355 static MaybeObject* MaterializeScopeDetails(Isolate* isolate, | |
11356 ScopeIterator* it) { | |
11357 // Calculate the size of the result. | |
11358 int details_size = kScopeDetailsSize; | |
11359 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size); | |
11360 | |
11361 // Fill in scope details. | |
11362 details->set(kScopeDetailsTypeIndex, Smi::FromInt(it->Type())); | |
11363 Handle<JSObject> scope_object = it->ScopeObject(); | |
11364 RETURN_IF_EMPTY_HANDLE(isolate, scope_object); | |
11365 details->set(kScopeDetailsObjectIndex, *scope_object); | |
11366 | |
11367 return *isolate->factory()->NewJSArrayWithElements(details); | |
11368 } | |
11369 | |
11342 // Return an array with scope details | 11370 // Return an array with scope details |
11343 // args[0]: number: break id | 11371 // args[0]: number: break id |
11344 // args[1]: number: frame index | 11372 // args[1]: number: frame index |
11345 // args[2]: number: inlined frame index | 11373 // args[2]: number: inlined frame index |
11346 // args[3]: number: scope index | 11374 // args[3]: number: scope index |
11347 // | 11375 // |
11348 // The array returned contains the following information: | 11376 // The array returned contains the following information: |
11349 // 0: Scope type | 11377 // 0: Scope type |
11350 // 1: Scope object | 11378 // 1: Scope object |
11351 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) { | 11379 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) { |
(...skipping 17 matching lines...) Expand all Loading... | |
11369 | 11397 |
11370 // Find the requested scope. | 11398 // Find the requested scope. |
11371 int n = 0; | 11399 int n = 0; |
11372 ScopeIterator it(isolate, frame, inlined_jsframe_index); | 11400 ScopeIterator it(isolate, frame, inlined_jsframe_index); |
11373 for (; !it.Done() && n < index; it.Next()) { | 11401 for (; !it.Done() && n < index; it.Next()) { |
11374 n++; | 11402 n++; |
11375 } | 11403 } |
11376 if (it.Done()) { | 11404 if (it.Done()) { |
11377 return isolate->heap()->undefined_value(); | 11405 return isolate->heap()->undefined_value(); |
11378 } | 11406 } |
11407 return MaterializeScopeDetails(isolate, &it); | |
11408 } | |
11409 | |
11410 | |
11411 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionScopeCount) { | |
11412 HandleScope scope(isolate); | |
11413 ASSERT(args.length() == 1); | |
11414 | |
11415 // Check arguments. | |
11416 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); | |
11417 | |
11418 // Count the visible scopes. | |
11419 int n = 0; | |
11420 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.
| |
11421 !it.Done(); | |
11422 it.Next()) { | |
11423 n++; | |
11424 } | |
11425 | |
11426 return Smi::FromInt(n); | |
11427 } | |
11428 | |
11429 | |
11430 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionScopeDetails) { | |
11431 HandleScope scope(isolate); | |
11432 ASSERT(args.length() == 2); | |
11433 | |
11434 // Check arguments. | |
11435 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); | |
11436 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); | |
11437 | |
11438 // Find the requested scope. | |
11439 int n = 0; | |
11440 ScopeIterator it(isolate, fun); | |
11441 for (; !it.Done() && n < index; it.Next()) { | |
11442 n++; | |
11443 } | |
11444 if (it.Done()) { | |
11445 return isolate->heap()->undefined_value(); | |
11446 } | |
11379 | 11447 |
11380 // Calculate the size of the result. | 11448 return MaterializeScopeDetails(isolate, &it); |
11381 int details_size = kScopeDetailsSize; | |
11382 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size); | |
11383 | |
11384 // Fill in scope details. | |
11385 details->set(kScopeDetailsTypeIndex, Smi::FromInt(it.Type())); | |
11386 Handle<JSObject> scope_object = it.ScopeObject(); | |
11387 RETURN_IF_EMPTY_HANDLE(isolate, scope_object); | |
11388 details->set(kScopeDetailsObjectIndex, *scope_object); | |
11389 | |
11390 return *isolate->factory()->NewJSArrayWithElements(details); | |
11391 } | 11449 } |
11392 | 11450 |
11393 | 11451 |
11394 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrintScopes) { | 11452 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrintScopes) { |
11395 HandleScope scope(isolate); | 11453 HandleScope scope(isolate); |
11396 ASSERT(args.length() == 0); | 11454 ASSERT(args.length() == 0); |
11397 | 11455 |
11398 #ifdef DEBUG | 11456 #ifdef DEBUG |
11399 // Print the scopes for the top frame. | 11457 // Print the scopes for the top frame. |
11400 StackFrameLocator locator; | 11458 StackFrameLocator locator; |
(...skipping 2032 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13433 // Handle last resort GC and make sure to allow future allocations | 13491 // Handle last resort GC and make sure to allow future allocations |
13434 // to grow the heap without causing GCs (if possible). | 13492 // to grow the heap without causing GCs (if possible). |
13435 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13493 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13436 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13494 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13437 "Runtime::PerformGC"); | 13495 "Runtime::PerformGC"); |
13438 } | 13496 } |
13439 } | 13497 } |
13440 | 13498 |
13441 | 13499 |
13442 } } // namespace v8::internal | 13500 } } // namespace v8::internal |
OLD | NEW |