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 |