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 10788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10799 NONE, | 10799 NONE, |
10800 kNonStrictMode), | 10800 kNonStrictMode), |
10801 Handle<JSObject>()); | 10801 Handle<JSObject>()); |
10802 } | 10802 } |
10803 } | 10803 } |
10804 | 10804 |
10805 return closure_scope; | 10805 return closure_scope; |
10806 } | 10806 } |
10807 | 10807 |
10808 | 10808 |
| 10809 // This method copies structure of MaterializeClosure method above. |
| 10810 static bool SetClosureVariableValue(Isolate* isolate, |
| 10811 Handle<Context> context, |
| 10812 Handle<String> variable_name, |
| 10813 Handle<Object> new_value) { |
| 10814 ASSERT(context->IsFunctionContext()); |
| 10815 |
| 10816 Handle<SharedFunctionInfo> shared(context->closure()->shared()); |
| 10817 Handle<ScopeInfo> scope_info(shared->scope_info()); |
| 10818 |
| 10819 // Context locals to the context extension. |
| 10820 for (int i = 0; i < scope_info->ContextLocalCount(); i++) { |
| 10821 Handle<String> next_name(scope_info->ContextLocalName(i)); |
| 10822 if (variable_name->Equals(*next_name)) { |
| 10823 VariableMode mode; |
| 10824 InitializationFlag init_flag; |
| 10825 int context_index = |
| 10826 scope_info->ContextSlotIndex(*next_name, &mode, &init_flag); |
| 10827 if (context_index < 0) { |
| 10828 return false; |
| 10829 } |
| 10830 context->set(context_index, *new_value); |
| 10831 return true; |
| 10832 } |
| 10833 } |
| 10834 |
| 10835 // Properties from the function context extension. This will |
| 10836 // be variables introduced by eval. |
| 10837 if (context->has_extension()) { |
| 10838 Handle<JSObject> ext(JSObject::cast(context->extension())); |
| 10839 if (ext->HasProperty(*variable_name)) { |
| 10840 // We don't expect this to do anything except replacing property value. |
| 10841 SetProperty(ext, |
| 10842 variable_name, |
| 10843 new_value, |
| 10844 NONE, |
| 10845 kNonStrictMode); |
| 10846 return true; |
| 10847 } |
| 10848 } |
| 10849 |
| 10850 return false; |
| 10851 } |
| 10852 |
| 10853 |
10809 // Create a plain JSObject which materializes the scope for the specified | 10854 // Create a plain JSObject which materializes the scope for the specified |
10810 // catch context. | 10855 // catch context. |
10811 static Handle<JSObject> MaterializeCatchScope(Isolate* isolate, | 10856 static Handle<JSObject> MaterializeCatchScope(Isolate* isolate, |
10812 Handle<Context> context) { | 10857 Handle<Context> context) { |
10813 ASSERT(context->IsCatchContext()); | 10858 ASSERT(context->IsCatchContext()); |
10814 Handle<String> name(String::cast(context->extension())); | 10859 Handle<String> name(String::cast(context->extension())); |
10815 Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX)); | 10860 Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX)); |
10816 Handle<JSObject> catch_scope = | 10861 Handle<JSObject> catch_scope = |
10817 isolate->factory()->NewJSObject(isolate->object_function()); | 10862 isolate->factory()->NewJSObject(isolate->object_function()); |
10818 RETURN_IF_EMPTY_HANDLE_VALUE( | 10863 RETURN_IF_EMPTY_HANDLE_VALUE( |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11074 return MaterializeClosure(isolate_, CurrentContext()); | 11119 return MaterializeClosure(isolate_, CurrentContext()); |
11075 case ScopeIterator::ScopeTypeBlock: | 11120 case ScopeIterator::ScopeTypeBlock: |
11076 return MaterializeBlockScope(isolate_, CurrentContext()); | 11121 return MaterializeBlockScope(isolate_, CurrentContext()); |
11077 case ScopeIterator::ScopeTypeModule: | 11122 case ScopeIterator::ScopeTypeModule: |
11078 return MaterializeModuleScope(isolate_, CurrentContext()); | 11123 return MaterializeModuleScope(isolate_, CurrentContext()); |
11079 } | 11124 } |
11080 UNREACHABLE(); | 11125 UNREACHABLE(); |
11081 return Handle<JSObject>(); | 11126 return Handle<JSObject>(); |
11082 } | 11127 } |
11083 | 11128 |
| 11129 bool SetVariableValue(Handle<String> variable_name, |
| 11130 Handle<Object> new_value) { |
| 11131 ASSERT(!failed_); |
| 11132 switch (Type()) { |
| 11133 case ScopeIterator::ScopeTypeGlobal: |
| 11134 break; |
| 11135 case ScopeIterator::ScopeTypeLocal: |
| 11136 // TODO(2399): implement. |
| 11137 break; |
| 11138 case ScopeIterator::ScopeTypeWith: |
| 11139 break; |
| 11140 case ScopeIterator::ScopeTypeCatch: |
| 11141 // TODO(2399): implement. |
| 11142 break; |
| 11143 case ScopeIterator::ScopeTypeClosure: |
| 11144 return SetClosureVariableValue(isolate_, CurrentContext(), |
| 11145 variable_name, new_value); |
| 11146 case ScopeIterator::ScopeTypeBlock: |
| 11147 // TODO(2399): should we implement it? |
| 11148 break; |
| 11149 case ScopeIterator::ScopeTypeModule: |
| 11150 // TODO(2399): should we implement it? |
| 11151 break; |
| 11152 } |
| 11153 return false; |
| 11154 } |
| 11155 |
11084 Handle<ScopeInfo> CurrentScopeInfo() { | 11156 Handle<ScopeInfo> CurrentScopeInfo() { |
11085 ASSERT(!failed_); | 11157 ASSERT(!failed_); |
11086 if (!nested_scope_chain_.is_empty()) { | 11158 if (!nested_scope_chain_.is_empty()) { |
11087 return nested_scope_chain_.last(); | 11159 return nested_scope_chain_.last(); |
11088 } else if (context_->IsBlockContext()) { | 11160 } else if (context_->IsBlockContext()) { |
11089 return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension())); | 11161 return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension())); |
11090 } else if (context_->IsFunctionContext()) { | 11162 } else if (context_->IsFunctionContext()) { |
11091 return Handle<ScopeInfo>(context_->closure()->shared()->scope_info()); | 11163 return Handle<ScopeInfo>(context_->closure()->shared()->scope_info()); |
11092 } | 11164 } |
11093 return Handle<ScopeInfo>::null(); | 11165 return Handle<ScopeInfo>::null(); |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11313 n++; | 11385 n++; |
11314 } | 11386 } |
11315 if (it.Done()) { | 11387 if (it.Done()) { |
11316 return isolate->heap()->undefined_value(); | 11388 return isolate->heap()->undefined_value(); |
11317 } | 11389 } |
11318 | 11390 |
11319 return MaterializeScopeDetails(isolate, &it); | 11391 return MaterializeScopeDetails(isolate, &it); |
11320 } | 11392 } |
11321 | 11393 |
11322 | 11394 |
| 11395 static bool SetScopeVariableValue(ScopeIterator* it, int index, |
| 11396 Handle<String> variable_name, |
| 11397 Handle<Object> new_value) { |
| 11398 for (int n = 0; !it->Done() && n < index; it->Next()) { |
| 11399 n++; |
| 11400 } |
| 11401 if (it->Done()) { |
| 11402 return false; |
| 11403 } |
| 11404 return it->SetVariableValue(variable_name, new_value); |
| 11405 } |
| 11406 |
| 11407 |
| 11408 // Change variable value in closure or local scope |
| 11409 // args[0]: number or JsFunction: break id or function |
| 11410 // args[1]: number: frame index (when arg[0] is break id) |
| 11411 // args[2]: number: inlined frame index (when arg[0] is break id) |
| 11412 // args[3]: number: scope index |
| 11413 // args[4]: string: variable name |
| 11414 // args[5]: object: new value |
| 11415 // |
| 11416 // Return true if success and false otherwise |
| 11417 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetScopeVariableValue) { |
| 11418 HandleScope scope(isolate); |
| 11419 ASSERT(args.length() == 6); |
| 11420 |
| 11421 // Check arguments. |
| 11422 CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]); |
| 11423 CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 4); |
| 11424 Handle<Object> new_value = args.at<Object>(5); |
| 11425 |
| 11426 bool res; |
| 11427 if (args[0]->IsNumber()) { |
| 11428 Object* check; |
| 11429 { MaybeObject* maybe_check = Runtime_CheckExecutionState( |
| 11430 RUNTIME_ARGUMENTS(isolate, args)); |
| 11431 if (!maybe_check->ToObject(&check)) return maybe_check; |
| 11432 } |
| 11433 CONVERT_SMI_ARG_CHECKED(wrapped_id, 1); |
| 11434 CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]); |
| 11435 |
| 11436 // Get the frame where the debugging is performed. |
| 11437 StackFrame::Id id = UnwrapFrameId(wrapped_id); |
| 11438 JavaScriptFrameIterator frame_it(isolate, id); |
| 11439 JavaScriptFrame* frame = frame_it.frame(); |
| 11440 |
| 11441 ScopeIterator it(isolate, frame, inlined_jsframe_index); |
| 11442 res = SetScopeVariableValue(&it, index, variable_name, new_value); |
| 11443 } else { |
| 11444 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); |
| 11445 ScopeIterator it(isolate, fun); |
| 11446 res = SetScopeVariableValue(&it, index, variable_name, new_value); |
| 11447 } |
| 11448 |
| 11449 return isolate->heap()->ToBoolean(res); |
| 11450 } |
| 11451 |
| 11452 |
11323 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrintScopes) { | 11453 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrintScopes) { |
11324 HandleScope scope(isolate); | 11454 HandleScope scope(isolate); |
11325 ASSERT(args.length() == 0); | 11455 ASSERT(args.length() == 0); |
11326 | 11456 |
11327 #ifdef DEBUG | 11457 #ifdef DEBUG |
11328 // Print the scopes for the top frame. | 11458 // Print the scopes for the top frame. |
11329 StackFrameLocator locator; | 11459 StackFrameLocator locator; |
11330 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); | 11460 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); |
11331 for (ScopeIterator it(isolate, frame, 0); | 11461 for (ScopeIterator it(isolate, frame, 0); |
11332 !it.Done(); | 11462 !it.Done(); |
(...skipping 1984 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13317 // Handle last resort GC and make sure to allow future allocations | 13447 // Handle last resort GC and make sure to allow future allocations |
13318 // to grow the heap without causing GCs (if possible). | 13448 // to grow the heap without causing GCs (if possible). |
13319 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13449 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13320 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13450 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13321 "Runtime::PerformGC"); | 13451 "Runtime::PerformGC"); |
13322 } | 13452 } |
13323 } | 13453 } |
13324 | 13454 |
13325 | 13455 |
13326 } } // namespace v8::internal | 13456 } } // namespace v8::internal |
OLD | NEW |