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 10918 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10929 // Fill all context locals. | 10929 // Fill all context locals. |
10930 if (!CopyContextLocalsToScopeObject( | 10930 if (!CopyContextLocalsToScopeObject( |
10931 isolate, scope_info, context, module_scope)) { | 10931 isolate, scope_info, context, module_scope)) { |
10932 return Handle<JSObject>(); | 10932 return Handle<JSObject>(); |
10933 } | 10933 } |
10934 | 10934 |
10935 return module_scope; | 10935 return module_scope; |
10936 } | 10936 } |
10937 | 10937 |
10938 | 10938 |
10939 // Iterate over the actual scopes visible from a stack frame. The iteration | 10939 // Iterate over the actual scopes visible from a stack frame or from a closure. |
10940 // proceeds from the innermost visible nested scope outwards. All scopes are | 10940 // The iteration proceeds from the innermost visible nested scope outwards. |
10941 // backed by an actual context except the local scope, which is inserted | 10941 // All scopes are backed by an actual context except the local scope, |
10942 // "artificially" in the context chain. | 10942 // which is inserted "artificially" in the context chain. |
10943 class ScopeIterator { | 10943 class ScopeIterator { |
10944 public: | 10944 public: |
10945 enum ScopeType { | 10945 enum ScopeType { |
10946 ScopeTypeGlobal = 0, | 10946 ScopeTypeGlobal = 0, |
10947 ScopeTypeLocal, | 10947 ScopeTypeLocal, |
10948 ScopeTypeWith, | 10948 ScopeTypeWith, |
10949 ScopeTypeClosure, | 10949 ScopeTypeClosure, |
10950 ScopeTypeCatch, | 10950 ScopeTypeCatch, |
10951 ScopeTypeBlock, | 10951 ScopeTypeBlock, |
10952 ScopeTypeModule | 10952 ScopeTypeModule |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11033 // A failed reparse indicates that the preparser has diverged from the | 11033 // A failed reparse indicates that the preparser has diverged from the |
11034 // parser or that the preparse data given to the initial parse has been | 11034 // parser or that the preparse data given to the initial parse has been |
11035 // faulty. We fail in debug mode but in release mode we only provide the | 11035 // faulty. We fail in debug mode but in release mode we only provide the |
11036 // information we get from the context chain but nothing about | 11036 // information we get from the context chain but nothing about |
11037 // completely stack allocated scopes or stack allocated locals. | 11037 // completely stack allocated scopes or stack allocated locals. |
11038 UNREACHABLE(); | 11038 UNREACHABLE(); |
11039 } | 11039 } |
11040 } | 11040 } |
11041 } | 11041 } |
11042 | 11042 |
| 11043 ScopeIterator(Isolate* isolate, |
| 11044 Handle<JSFunction> function) |
| 11045 : isolate_(isolate), |
| 11046 frame_(NULL), |
| 11047 inlined_jsframe_index_(0), |
| 11048 function_(function), |
| 11049 context_(function->context()) { |
| 11050 // TODO: Should we hide a context of some internal functions? |
| 11051 } |
| 11052 |
11043 // More scopes? | 11053 // More scopes? |
11044 bool Done() { return context_.is_null(); } | 11054 bool Done() { return context_.is_null(); } |
11045 | 11055 |
11046 // Move to the next scope. | 11056 // Move to the next scope. |
11047 void Next() { | 11057 void Next() { |
11048 ScopeType scope_type = Type(); | 11058 ScopeType scope_type = Type(); |
11049 if (scope_type == ScopeTypeGlobal) { | 11059 if (scope_type == ScopeTypeGlobal) { |
11050 // The global scope is always the last in the chain. | 11060 // The global scope is always the last in the chain. |
11051 ASSERT(context_->IsGlobalContext()); | 11061 ASSERT(context_->IsGlobalContext()); |
11052 context_ = Handle<Context>(); | 11062 context_ = Handle<Context>(); |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11253 } | 11263 } |
11254 | 11264 |
11255 return Smi::FromInt(n); | 11265 return Smi::FromInt(n); |
11256 } | 11266 } |
11257 | 11267 |
11258 | 11268 |
11259 static const int kScopeDetailsTypeIndex = 0; | 11269 static const int kScopeDetailsTypeIndex = 0; |
11260 static const int kScopeDetailsObjectIndex = 1; | 11270 static const int kScopeDetailsObjectIndex = 1; |
11261 static const int kScopeDetailsSize = 2; | 11271 static const int kScopeDetailsSize = 2; |
11262 | 11272 |
| 11273 |
| 11274 static MaybeObject* MaterializeScopeDetails(Isolate* isolate, |
| 11275 ScopeIterator* it) { |
| 11276 // Calculate the size of the result. |
| 11277 int details_size = kScopeDetailsSize; |
| 11278 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size); |
| 11279 |
| 11280 // Fill in scope details. |
| 11281 details->set(kScopeDetailsTypeIndex, Smi::FromInt(it->Type())); |
| 11282 Handle<JSObject> scope_object = it->ScopeObject(); |
| 11283 RETURN_IF_EMPTY_HANDLE(isolate, scope_object); |
| 11284 details->set(kScopeDetailsObjectIndex, *scope_object); |
| 11285 |
| 11286 return *isolate->factory()->NewJSArrayWithElements(details); |
| 11287 } |
| 11288 |
11263 // Return an array with scope details | 11289 // Return an array with scope details |
11264 // args[0]: number: break id | 11290 // args[0]: number: break id |
11265 // args[1]: number: frame index | 11291 // args[1]: number: frame index |
11266 // args[2]: number: inlined frame index | 11292 // args[2]: number: inlined frame index |
11267 // args[3]: number: scope index | 11293 // args[3]: number: scope index |
11268 // | 11294 // |
11269 // The array returned contains the following information: | 11295 // The array returned contains the following information: |
11270 // 0: Scope type | 11296 // 0: Scope type |
11271 // 1: Scope object | 11297 // 1: Scope object |
11272 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) { | 11298 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) { |
(...skipping 17 matching lines...) Expand all Loading... |
11290 | 11316 |
11291 // Find the requested scope. | 11317 // Find the requested scope. |
11292 int n = 0; | 11318 int n = 0; |
11293 ScopeIterator it(isolate, frame, inlined_jsframe_index); | 11319 ScopeIterator it(isolate, frame, inlined_jsframe_index); |
11294 for (; !it.Done() && n < index; it.Next()) { | 11320 for (; !it.Done() && n < index; it.Next()) { |
11295 n++; | 11321 n++; |
11296 } | 11322 } |
11297 if (it.Done()) { | 11323 if (it.Done()) { |
11298 return isolate->heap()->undefined_value(); | 11324 return isolate->heap()->undefined_value(); |
11299 } | 11325 } |
| 11326 return MaterializeScopeDetails(isolate, &it); |
| 11327 } |
| 11328 |
| 11329 |
| 11330 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionScopeCount) { |
| 11331 HandleScope scope(isolate); |
| 11332 ASSERT(args.length() == 1); |
| 11333 |
| 11334 // Check arguments. |
| 11335 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); |
| 11336 |
| 11337 // Count the visible scopes. |
| 11338 int n = 0; |
| 11339 for (ScopeIterator it(isolate, fun); |
| 11340 !it.Done(); |
| 11341 it.Next()) { |
| 11342 n++; |
| 11343 } |
| 11344 |
| 11345 return Smi::FromInt(n); |
| 11346 } |
| 11347 |
| 11348 |
| 11349 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionScopeDetails) { |
| 11350 HandleScope scope(isolate); |
| 11351 ASSERT(args.length() == 2); |
| 11352 |
| 11353 // Check arguments. |
| 11354 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); |
| 11355 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); |
| 11356 |
| 11357 // Find the requested scope. |
| 11358 int n = 0; |
| 11359 ScopeIterator it(isolate, fun); |
| 11360 for (; !it.Done() && n < index; it.Next()) { |
| 11361 n++; |
| 11362 } |
| 11363 if (it.Done()) { |
| 11364 return isolate->heap()->undefined_value(); |
| 11365 } |
11300 | 11366 |
11301 // Calculate the size of the result. | 11367 return MaterializeScopeDetails(isolate, &it); |
11302 int details_size = kScopeDetailsSize; | |
11303 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size); | |
11304 | |
11305 // Fill in scope details. | |
11306 details->set(kScopeDetailsTypeIndex, Smi::FromInt(it.Type())); | |
11307 Handle<JSObject> scope_object = it.ScopeObject(); | |
11308 RETURN_IF_EMPTY_HANDLE(isolate, scope_object); | |
11309 details->set(kScopeDetailsObjectIndex, *scope_object); | |
11310 | |
11311 return *isolate->factory()->NewJSArrayWithElements(details); | |
11312 } | 11368 } |
11313 | 11369 |
11314 | 11370 |
11315 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrintScopes) { | 11371 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrintScopes) { |
11316 HandleScope scope(isolate); | 11372 HandleScope scope(isolate); |
11317 ASSERT(args.length() == 0); | 11373 ASSERT(args.length() == 0); |
11318 | 11374 |
11319 #ifdef DEBUG | 11375 #ifdef DEBUG |
11320 // Print the scopes for the top frame. | 11376 // Print the scopes for the top frame. |
11321 StackFrameLocator locator; | 11377 StackFrameLocator locator; |
(...skipping 2032 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13354 // Handle last resort GC and make sure to allow future allocations | 13410 // Handle last resort GC and make sure to allow future allocations |
13355 // to grow the heap without causing GCs (if possible). | 13411 // to grow the heap without causing GCs (if possible). |
13356 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13412 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13357 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13413 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13358 "Runtime::PerformGC"); | 13414 "Runtime::PerformGC"); |
13359 } | 13415 } |
13360 } | 13416 } |
13361 | 13417 |
13362 | 13418 |
13363 } } // namespace v8::internal | 13419 } } // namespace v8::internal |
OLD | NEW |