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 // TODO(code review): alternative approach is to generalize MaterializeClosure |
| 10811 // method so that it merely iterates properties, and a visitor |
| 10812 // materizalises or changes their values. |
| 10813 // But it would make code more complicated. |
| 10814 static bool SetClosureVariableValue(Isolate* isolate, Handle<Context> context, |
| 10815 Handle<String> variable_name, |
| 10816 Handle<Object> new_value) { |
| 10817 ASSERT(context->IsFunctionContext()); |
| 10818 |
| 10819 Handle<SharedFunctionInfo> shared(context->closure()->shared()); |
| 10820 Handle<ScopeInfo> scope_info(shared->scope_info()); |
| 10821 |
| 10822 // Context locals to the context extension. |
| 10823 for (int i = 0; i < scope_info->ContextLocalCount(); i++) { |
| 10824 Handle<String> next_name(scope_info->ContextLocalName(i)); |
| 10825 if (variable_name->Equals(*next_name)) { |
| 10826 VariableMode mode; |
| 10827 InitializationFlag init_flag; |
| 10828 int context_index = |
| 10829 scope_info->ContextSlotIndex(*next_name, &mode, &init_flag); |
| 10830 if (context_index < 0) { |
| 10831 return false; |
| 10832 } |
| 10833 context->set(context_index, *new_value); |
| 10834 return true; |
| 10835 } |
| 10836 } |
| 10837 |
| 10838 // Properties from the function context extension. This will |
| 10839 // be variables introduced by eval. |
| 10840 if (context->has_extension()) { |
| 10841 Handle<JSObject> ext(JSObject::cast(context->extension())); |
| 10842 bool threw = false; |
| 10843 Handle<FixedArray> keys = |
| 10844 GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw); |
| 10845 if (threw) return false; |
| 10846 |
| 10847 for (int i = 0; i < keys->length(); i++) { |
| 10848 // Names of variables introduced by eval are strings. |
| 10849 ASSERT(keys->get(i)->IsString()); |
| 10850 Handle<String> key(String::cast(keys->get(i))); |
| 10851 if (key->Equals(*variable_name)) { |
| 10852 // We don't expect this to do anything except replacing property value. |
| 10853 // TODO(code review): should we do it more accurately? |
| 10854 SetProperty(ext, |
| 10855 key, |
| 10856 new_value, |
| 10857 NONE, |
| 10858 kNonStrictMode); |
| 10859 return true; |
| 10860 } |
| 10861 } |
| 10862 } |
| 10863 |
| 10864 return false; |
| 10865 } |
| 10866 |
| 10867 |
10809 // Create a plain JSObject which materializes the scope for the specified | 10868 // Create a plain JSObject which materializes the scope for the specified |
10810 // catch context. | 10869 // catch context. |
10811 static Handle<JSObject> MaterializeCatchScope(Isolate* isolate, | 10870 static Handle<JSObject> MaterializeCatchScope(Isolate* isolate, |
10812 Handle<Context> context) { | 10871 Handle<Context> context) { |
10813 ASSERT(context->IsCatchContext()); | 10872 ASSERT(context->IsCatchContext()); |
10814 Handle<String> name(String::cast(context->extension())); | 10873 Handle<String> name(String::cast(context->extension())); |
10815 Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX)); | 10874 Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX)); |
10816 Handle<JSObject> catch_scope = | 10875 Handle<JSObject> catch_scope = |
10817 isolate->factory()->NewJSObject(isolate->object_function()); | 10876 isolate->factory()->NewJSObject(isolate->object_function()); |
10818 RETURN_IF_EMPTY_HANDLE_VALUE( | 10877 RETURN_IF_EMPTY_HANDLE_VALUE( |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11074 return MaterializeClosure(isolate_, CurrentContext()); | 11133 return MaterializeClosure(isolate_, CurrentContext()); |
11075 case ScopeIterator::ScopeTypeBlock: | 11134 case ScopeIterator::ScopeTypeBlock: |
11076 return MaterializeBlockScope(isolate_, CurrentContext()); | 11135 return MaterializeBlockScope(isolate_, CurrentContext()); |
11077 case ScopeIterator::ScopeTypeModule: | 11136 case ScopeIterator::ScopeTypeModule: |
11078 return MaterializeModuleScope(isolate_, CurrentContext()); | 11137 return MaterializeModuleScope(isolate_, CurrentContext()); |
11079 } | 11138 } |
11080 UNREACHABLE(); | 11139 UNREACHABLE(); |
11081 return Handle<JSObject>(); | 11140 return Handle<JSObject>(); |
11082 } | 11141 } |
11083 | 11142 |
| 11143 bool SetVariableValue(Handle<String> variable_name, |
| 11144 Handle<Object> new_value) { |
| 11145 ASSERT(!failed_); |
| 11146 switch (Type()) { |
| 11147 case ScopeIterator::ScopeTypeGlobal: |
| 11148 break; |
| 11149 case ScopeIterator::ScopeTypeLocal: |
| 11150 // TODO(2399): implement. |
| 11151 break; |
| 11152 case ScopeIterator::ScopeTypeWith: |
| 11153 break; |
| 11154 case ScopeIterator::ScopeTypeCatch: |
| 11155 // TODO(2399): implement. |
| 11156 break; |
| 11157 case ScopeIterator::ScopeTypeClosure: |
| 11158 return SetClosureVariableValue(isolate_, CurrentContext(), |
| 11159 variable_name, new_value); |
| 11160 case ScopeIterator::ScopeTypeBlock: |
| 11161 // TODO(2399): should we implement it? |
| 11162 break; |
| 11163 case ScopeIterator::ScopeTypeModule: |
| 11164 // TODO(2399): should we implement it? |
| 11165 break; |
| 11166 } |
| 11167 return false; |
| 11168 } |
| 11169 |
11084 Handle<ScopeInfo> CurrentScopeInfo() { | 11170 Handle<ScopeInfo> CurrentScopeInfo() { |
11085 ASSERT(!failed_); | 11171 ASSERT(!failed_); |
11086 if (!nested_scope_chain_.is_empty()) { | 11172 if (!nested_scope_chain_.is_empty()) { |
11087 return nested_scope_chain_.last(); | 11173 return nested_scope_chain_.last(); |
11088 } else if (context_->IsBlockContext()) { | 11174 } else if (context_->IsBlockContext()) { |
11089 return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension())); | 11175 return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension())); |
11090 } else if (context_->IsFunctionContext()) { | 11176 } else if (context_->IsFunctionContext()) { |
11091 return Handle<ScopeInfo>(context_->closure()->shared()->scope_info()); | 11177 return Handle<ScopeInfo>(context_->closure()->shared()->scope_info()); |
11092 } | 11178 } |
11093 return Handle<ScopeInfo>::null(); | 11179 return Handle<ScopeInfo>::null(); |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11313 n++; | 11399 n++; |
11314 } | 11400 } |
11315 if (it.Done()) { | 11401 if (it.Done()) { |
11316 return isolate->heap()->undefined_value(); | 11402 return isolate->heap()->undefined_value(); |
11317 } | 11403 } |
11318 | 11404 |
11319 return MaterializeScopeDetails(isolate, &it); | 11405 return MaterializeScopeDetails(isolate, &it); |
11320 } | 11406 } |
11321 | 11407 |
11322 | 11408 |
| 11409 static bool SetScopeVariableValue(ScopeIterator* it, int index, |
| 11410 Handle<String> variable_name, |
| 11411 Handle<Object> new_value) { |
| 11412 int n = 0; |
| 11413 for (; !it->Done() && n < index; it->Next()) { |
| 11414 n++; |
| 11415 } |
| 11416 if (it->Done()) { |
| 11417 return false; |
| 11418 } |
| 11419 return it->SetVariableValue(variable_name, new_value); |
| 11420 } |
| 11421 |
| 11422 |
| 11423 // Change variable value in closure or local scope |
| 11424 // args[0]: number or JsFunction: break id or function |
| 11425 // args[1]: number: frame index |
| 11426 // args[2]: number: inlined frame index |
| 11427 // args[3]: number: scope index |
| 11428 // args[4]: string: variable name |
| 11429 // args[5]: object: new value |
| 11430 // |
| 11431 // Return true if success and false otherwise |
| 11432 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetScopeVariableValue) { |
| 11433 HandleScope scope(isolate); |
| 11434 ASSERT(args.length() == 6); |
| 11435 |
| 11436 // Check arguments. |
| 11437 CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]); |
| 11438 CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 4); |
| 11439 Handle<Object> new_value = args.at<Object>(5); |
| 11440 |
| 11441 bool res; |
| 11442 if (args[0]->IsNumber()) { |
| 11443 Object* check; |
| 11444 { MaybeObject* maybe_check = Runtime_CheckExecutionState( |
| 11445 RUNTIME_ARGUMENTS(isolate, args)); |
| 11446 if (!maybe_check->ToObject(&check)) return maybe_check; |
| 11447 } |
| 11448 CONVERT_SMI_ARG_CHECKED(wrapped_id, 1); |
| 11449 CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]); |
| 11450 |
| 11451 // Get the frame where the debugging is performed. |
| 11452 StackFrame::Id id = UnwrapFrameId(wrapped_id); |
| 11453 JavaScriptFrameIterator frame_it(isolate, id); |
| 11454 JavaScriptFrame* frame = frame_it.frame(); |
| 11455 |
| 11456 ScopeIterator it(isolate, frame, inlined_jsframe_index); |
| 11457 res = SetScopeVariableValue(&it, index, variable_name, new_value); |
| 11458 } else { |
| 11459 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); |
| 11460 ScopeIterator it(isolate, fun); |
| 11461 res = SetScopeVariableValue(&it, index, variable_name, new_value); |
| 11462 } |
| 11463 |
| 11464 return isolate->heap()->ToBoolean(res); |
| 11465 } |
| 11466 |
| 11467 |
11323 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrintScopes) { | 11468 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrintScopes) { |
11324 HandleScope scope(isolate); | 11469 HandleScope scope(isolate); |
11325 ASSERT(args.length() == 0); | 11470 ASSERT(args.length() == 0); |
11326 | 11471 |
11327 #ifdef DEBUG | 11472 #ifdef DEBUG |
11328 // Print the scopes for the top frame. | 11473 // Print the scopes for the top frame. |
11329 StackFrameLocator locator; | 11474 StackFrameLocator locator; |
11330 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); | 11475 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); |
11331 for (ScopeIterator it(isolate, frame, 0); | 11476 for (ScopeIterator it(isolate, frame, 0); |
11332 !it.Done(); | 11477 !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 | 13462 // Handle last resort GC and make sure to allow future allocations |
13318 // to grow the heap without causing GCs (if possible). | 13463 // to grow the heap without causing GCs (if possible). |
13319 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13464 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13320 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13465 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13321 "Runtime::PerformGC"); | 13466 "Runtime::PerformGC"); |
13322 } | 13467 } |
13323 } | 13468 } |
13324 | 13469 |
13325 | 13470 |
13326 } } // namespace v8::internal | 13471 } } // namespace v8::internal |
OLD | NEW |