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); !it.Done(); it.Next()) { |
| 11421 n++; |
| 11422 } |
| 11423 |
| 11424 return Smi::FromInt(n); |
| 11425 } |
| 11426 |
| 11427 |
| 11428 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionScopeDetails) { |
| 11429 HandleScope scope(isolate); |
| 11430 ASSERT(args.length() == 2); |
| 11431 |
| 11432 // Check arguments. |
| 11433 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); |
| 11434 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); |
| 11435 |
| 11436 // Find the requested scope. |
| 11437 int n = 0; |
| 11438 ScopeIterator it(isolate, fun); |
| 11439 for (; !it.Done() && n < index; it.Next()) { |
| 11440 n++; |
| 11441 } |
| 11442 if (it.Done()) { |
| 11443 return isolate->heap()->undefined_value(); |
| 11444 } |
11379 | 11445 |
11380 // Calculate the size of the result. | 11446 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 } | 11447 } |
11392 | 11448 |
11393 | 11449 |
11394 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrintScopes) { | 11450 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrintScopes) { |
11395 HandleScope scope(isolate); | 11451 HandleScope scope(isolate); |
11396 ASSERT(args.length() == 0); | 11452 ASSERT(args.length() == 0); |
11397 | 11453 |
11398 #ifdef DEBUG | 11454 #ifdef DEBUG |
11399 // Print the scopes for the top frame. | 11455 // Print the scopes for the top frame. |
11400 StackFrameLocator locator; | 11456 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 | 13489 // Handle last resort GC and make sure to allow future allocations |
13434 // to grow the heap without causing GCs (if possible). | 13490 // to grow the heap without causing GCs (if possible). |
13435 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13491 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13436 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13492 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13437 "Runtime::PerformGC"); | 13493 "Runtime::PerformGC"); |
13438 } | 13494 } |
13439 } | 13495 } |
13440 | 13496 |
13441 | 13497 |
13442 } } // namespace v8::internal | 13498 } } // namespace v8::internal |
OLD | NEW |