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