Chromium Code Reviews| Index: src/runtime.cc |
| diff --git a/src/runtime.cc b/src/runtime.cc |
| index 5cf2d44cb50f13a3a956142fc705466d8d5c2f66..90b370876ac3fb2a35a1cccc51e1193273241c10 100644 |
| --- a/src/runtime.cc |
| +++ b/src/runtime.cc |
| @@ -10853,6 +10853,94 @@ static Handle<JSObject> MaterializeLocalScope( |
| } |
| +// Set the context local variable value. |
| +static bool SetContextLocalValue( |
| + Isolate* isolate, |
|
Yang
2012/12/10 14:15:11
I'd prefer having the first argument in the same l
Peter Rybin
2012/12/11 23:20:44
Done.
|
| + Handle<ScopeInfo> scope_info, |
| + Handle<Context> context, |
| + Handle<String> variable_name, |
| + Handle<Object> new_value) { |
| + for (int i = 0; i < scope_info->ContextLocalCount(); i++) { |
| + Handle<String> next_name(scope_info->ContextLocalName(i)); |
| + if (variable_name->Equals(*next_name)) { |
| + VariableMode mode; |
| + InitializationFlag init_flag; |
| + int context_index = |
| + scope_info->ContextSlotIndex(*next_name, &mode, &init_flag); |
| + context->set(context_index, *new_value); |
| + return true; |
| + } |
| + } |
| + |
| + return false; |
| +} |
| + |
| + |
| +static bool SetLocalVariableValue( |
| + Isolate* isolate, |
|
Yang
2012/12/10 14:15:11
Ditto about argument formatting.
Peter Rybin
2012/12/11 23:20:44
Done.
|
| + JavaScriptFrame* frame, |
| + int inlined_jsframe_index, |
| + Handle<String> variable_name, |
| + Handle<Object> new_value) { |
| + if (inlined_jsframe_index != 0 || frame->is_optimized()) { |
| + // Optimized frames are not supported. |
| + return false; |
| + } |
| + |
| + Handle<JSFunction> function(JSFunction::cast(frame->function())); |
| + Handle<SharedFunctionInfo> shared(function->shared()); |
| + Handle<ScopeInfo> scope_info(shared->scope_info()); |
| + |
| + // Parameters. |
| + for (int i = 0; i < scope_info->ParameterCount(); ++i) { |
| + if (scope_info->ParameterName(i)->Equals(*variable_name)) { |
| + frame->SetParameterValue(i, *new_value); |
| + return true; |
| + } |
| + } |
| + |
| + // Stack locals. |
| + for (int i = 0; i < scope_info->StackLocalCount(); ++i) { |
| + if (scope_info->StackLocalName(i)->Equals(*variable_name)) { |
| + frame->SetExpression(i, *new_value); |
| + return true; |
| + } |
| + } |
| + |
| + if (scope_info->HasContext()) { |
| + // Context locals. |
| + Handle<Context> frame_context(Context::cast(frame->context())); |
| + Handle<Context> function_context(frame_context->declaration_context()); |
| + if (SetContextLocalValue(isolate, scope_info, function_context, |
|
Yang
2012/12/10 14:15:11
could you put all arguments on the second line?
Peter Rybin
2012/12/11 23:20:44
Done.
|
| + variable_name, new_value)) { |
| + return true; |
| + } |
| + |
| + // Function context extension. These are variables introduced by eval. |
| + if (function_context->closure() == *function) { |
| + if (function_context->has_extension() && |
| + !function_context->IsNativeContext()) { |
| + Handle<JSObject> ext(JSObject::cast(function_context->extension())); |
| + |
| + if (ext->HasProperty(*variable_name)) { |
| + // We don't expect this to do anything except replacing |
| + // property value. |
| + SetProperty(isolate, |
| + ext, |
| + variable_name, |
| + new_value, |
| + NONE, |
| + kNonStrictMode); |
| + return true; |
| + } |
| + } |
| + } |
| + } |
| + |
| + return false; |
| +} |
| + |
| + |
| // Create a plain JSObject which materializes the closure content for the |
| // context. |
| static Handle<JSObject> MaterializeClosure(Isolate* isolate, |
| @@ -10913,19 +11001,9 @@ static bool SetClosureVariableValue(Isolate* isolate, |
| Handle<ScopeInfo> scope_info(shared->scope_info()); |
| // Context locals to the context extension. |
| - for (int i = 0; i < scope_info->ContextLocalCount(); i++) { |
| - Handle<String> next_name(scope_info->ContextLocalName(i)); |
| - if (variable_name->Equals(*next_name)) { |
| - VariableMode mode; |
| - InitializationFlag init_flag; |
| - int context_index = |
| - scope_info->ContextSlotIndex(*next_name, &mode, &init_flag); |
| - if (context_index < 0) { |
| - return false; |
| - } |
| - context->set(context_index, *new_value); |
| - return true; |
| - } |
| + if (SetContextLocalValue( |
| + isolate, scope_info, context, variable_name, new_value)) { |
| + return true; |
| } |
| // Properties from the function context extension. This will |
| @@ -10970,6 +11048,20 @@ static Handle<JSObject> MaterializeCatchScope(Isolate* isolate, |
| } |
| +static bool SetCatchVariableValue(Isolate* isolate, |
| + Handle<Context> context, |
| + Handle<String> variable_name, |
| + Handle<Object> new_value) { |
| + ASSERT(context->IsCatchContext()); |
| + Handle<String> name(String::cast(context->extension())); |
| + if (!name->Equals(*variable_name)) { |
| + return false; |
| + } |
| + context->set(Context::THROWN_OBJECT_INDEX, *new_value); |
| + return true; |
| +} |
| + |
| + |
| // Create a plain JSObject which materializes the block scope for the specified |
| // block context. |
| static Handle<JSObject> MaterializeBlockScope( |
| @@ -11235,13 +11327,13 @@ class ScopeIterator { |
| case ScopeIterator::ScopeTypeGlobal: |
| break; |
| case ScopeIterator::ScopeTypeLocal: |
| - // TODO(2399): implement. |
| - break; |
| + return SetLocalVariableValue(isolate_, frame_, inlined_jsframe_index_, |
| + variable_name, new_value); |
| case ScopeIterator::ScopeTypeWith: |
| break; |
| case ScopeIterator::ScopeTypeCatch: |
| - // TODO(2399): implement. |
| - break; |
| + return SetCatchVariableValue(isolate_, CurrentContext(), |
| + variable_name, new_value); |
| case ScopeIterator::ScopeTypeClosure: |
| return SetClosureVariableValue(isolate_, CurrentContext(), |
| variable_name, new_value); |