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, | |
Yang
2012/11/27 16:46:23
One argument per line please.
Peter Rybin
2012/11/27 18:24:28
Done.
| |
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++) { | |
Yang
2012/11/27 16:46:23
Instead of iterating over all the keys, wouldn't i
Peter Rybin
2012/11/27 21:36:13
Done.
| |
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 (when arg[0] is break id) | |
11426 // args[2]: number: inlined frame index (when arg[0] is break id) | |
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 |