| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 6144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6155 ASSERT(keys->get(i)->IsString()); | 6155 ASSERT(keys->get(i)->IsString()); |
| 6156 Handle<String> key(String::cast(keys->get(i))); | 6156 Handle<String> key(String::cast(keys->get(i))); |
| 6157 SetProperty(local_scope, key, GetProperty(ext, key), NONE); | 6157 SetProperty(local_scope, key, GetProperty(ext, key), NONE); |
| 6158 } | 6158 } |
| 6159 } | 6159 } |
| 6160 } | 6160 } |
| 6161 return local_scope; | 6161 return local_scope; |
| 6162 } | 6162 } |
| 6163 | 6163 |
| 6164 | 6164 |
| 6165 // Write back the to the local scope from a materialized local scope. |
| 6166 static void DematerializeLocalScope(JavaScriptFrame* frame, |
| 6167 Handle<JSObject> local_scope, |
| 6168 Handle<JSObject> arguments) { |
| 6169 Handle<JSFunction> function(JSFunction::cast(frame->function())); |
| 6170 Handle<Code> code(function->code()); |
| 6171 ScopeInfo<> scope_info(*code); |
| 6172 Handle<Context> frame_context(Context::cast(frame->context())); |
| 6173 Handle<Context> function_context(frame_context->fcontext()); |
| 6174 |
| 6175 // Locate the arguments shadow (.arguments) variable if it exists either as a |
| 6176 // context allocated or stack allocated variable. |
| 6177 Handle<JSObject> arguments_shadow; |
| 6178 |
| 6179 // First write back to the function context extension. This will be variables |
| 6180 // introduced by eval. |
| 6181 if (function_context->has_extension() && |
| 6182 !function_context->IsGlobalContext()) { |
| 6183 Handle<JSObject> ext(JSObject::cast(function_context->extension())); |
| 6184 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext); |
| 6185 for (int i = 0; i < keys->length(); i++) { |
| 6186 // Names of variables introduced by eval are strings. |
| 6187 ASSERT(keys->get(i)->IsString()); |
| 6188 Handle<String> key(String::cast(keys->get(i))); |
| 6189 SetProperty(ext, key, GetProperty(local_scope, key), NONE); |
| 6190 } |
| 6191 } |
| 6192 |
| 6193 // Second write back all context locals. |
| 6194 for (int i = Context::MIN_CONTEXT_SLOTS; |
| 6195 i < scope_info.number_of_context_slots(); |
| 6196 i++) { |
| 6197 Handle<String> name = scope_info.context_slot_name(i); |
| 6198 // Don't write to the arguments shadow (.arguments). |
| 6199 if (*name != Heap::arguments_shadow_symbol()) { |
| 6200 function_context->set(i, *GetProperty(local_scope, name)); |
| 6201 } else { |
| 6202 arguments_shadow = |
| 6203 Handle<JSObject>(JSObject::cast(function_context->get(i))); |
| 6204 } |
| 6205 } |
| 6206 |
| 6207 // Third write back all stack locals. |
| 6208 for (int i = 0; i < scope_info.number_of_stack_slots(); i++) { |
| 6209 Handle<String> name = scope_info.stack_slot_name(i); |
| 6210 // Don't write to the arguments shadow (.arguments). |
| 6211 if (*name != Heap::arguments_shadow_symbol()) { |
| 6212 frame->SetExpression(i, *GetProperty(local_scope, name)); |
| 6213 } else { |
| 6214 arguments_shadow = |
| 6215 Handle<JSObject>(JSObject::cast(frame->GetExpression(i))); |
| 6216 } |
| 6217 } |
| 6218 |
| 6219 // Finally write back all parameters. Parameters are written to the stack and |
| 6220 // to the arguments shadow (.arguments) variable if it exists. |
| 6221 for (int i = 0; i < scope_info.number_of_parameters(); ++i) { |
| 6222 Handle<Object> obj = |
| 6223 GetProperty(local_scope, scope_info.parameter_name(i)); |
| 6224 frame->SetParameter(i, *obj); |
| 6225 |
| 6226 // Write to arguments shadow if it exists. |
| 6227 if (!arguments_shadow.is_null()) { |
| 6228 SetElement(arguments_shadow, i, obj); |
| 6229 } |
| 6230 } |
| 6231 |
| 6232 // If the frame has an adaptor frame then the parameters needs to be written |
| 6233 // back to this frame as well. |
| 6234 if (frame->has_adapted_arguments()) { |
| 6235 StackFrameIterator it(false, frame->fp(), frame->sp()); |
| 6236 ASSERT(it.frame()->is_java_script()); |
| 6237 it.Advance(); |
| 6238 ASSERT(!it.done()); |
| 6239 ASSERT(it.frame()->is_arguments_adaptor()); |
| 6240 JavaScriptFrame* adaptor_frame = |
| 6241 reinterpret_cast<JavaScriptFrame*>(it.frame()); |
| 6242 for (int i = 0; i < adaptor_frame->GetProvidedParametersCount(); i++) { |
| 6243 if (i < scope_info.number_of_parameters()) { |
| 6244 Handle<Object> obj = |
| 6245 GetProperty(local_scope, scope_info.parameter_name(i)); |
| 6246 adaptor_frame->SetParameter(i, *obj); |
| 6247 } else { |
| 6248 adaptor_frame->SetParameter(i, arguments->GetElement(i)); |
| 6249 } |
| 6250 } |
| 6251 } |
| 6252 } |
| 6253 |
| 6254 |
| 6165 // Create a plain JSObject which materializes the closure content for the | 6255 // Create a plain JSObject which materializes the closure content for the |
| 6166 // context. | 6256 // context. |
| 6167 static Handle<JSObject> MaterializeClosure(Handle<Context> context) { | 6257 static Handle<JSObject> MaterializeClosure(Handle<Context> context) { |
| 6168 ASSERT(context->is_function_context()); | 6258 ASSERT(context->is_function_context()); |
| 6169 | 6259 |
| 6170 Handle<Code> code(context->closure()->code()); | 6260 Handle<Code> code(context->closure()->code()); |
| 6171 ScopeInfo<> scope_info(*code); | 6261 ScopeInfo<> scope_info(*code); |
| 6172 | 6262 |
| 6173 // Allocate and initialize a JSObject with all the content of theis function | 6263 // Allocate and initialize a JSObject with all the content of theis function |
| 6174 // closure. | 6264 // closure. |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6339 case ScopeIterator::ScopeTypeGlobal: | 6429 case ScopeIterator::ScopeTypeGlobal: |
| 6340 PrintF("Global:\n"); | 6430 PrintF("Global:\n"); |
| 6341 CurrentContext()->Print(); | 6431 CurrentContext()->Print(); |
| 6342 break; | 6432 break; |
| 6343 | 6433 |
| 6344 case ScopeIterator::ScopeTypeLocal: { | 6434 case ScopeIterator::ScopeTypeLocal: { |
| 6345 PrintF("Local:\n"); | 6435 PrintF("Local:\n"); |
| 6346 Handle<Code> code(function_->code()); | 6436 Handle<Code> code(function_->code()); |
| 6347 ScopeInfo<> scope_info(*code); | 6437 ScopeInfo<> scope_info(*code); |
| 6348 scope_info.Print(); | 6438 scope_info.Print(); |
| 6439 |
| 6349 if (!CurrentContext().is_null()) { | 6440 if (!CurrentContext().is_null()) { |
| 6350 CurrentContext()->Print(); | 6441 CurrentContext()->Print(); |
| 6351 if (CurrentContext()->has_extension()) { | 6442 if (CurrentContext()->has_extension()) { |
| 6352 Handle<JSObject> extension = | 6443 Handle<JSObject> extension = |
| 6353 Handle<JSObject>(CurrentContext()->extension()); | 6444 Handle<JSObject>(CurrentContext()->extension()); |
| 6354 if (extension->IsJSContextExtensionObject()) { | 6445 if (extension->IsJSContextExtensionObject()) { |
| 6355 extension->Print(); | 6446 extension->Print(); |
| 6356 } | 6447 } |
| 6357 } | 6448 } |
| 6358 } | 6449 } |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6847 Handle<JSObject> extension(JSObject::cast(context_chain->extension())); | 6938 Handle<JSObject> extension(JSObject::cast(context_chain->extension())); |
| 6848 return Factory::NewWithContext( | 6939 return Factory::NewWithContext( |
| 6849 CopyWithContextChain(function_context, previous), | 6940 CopyWithContextChain(function_context, previous), |
| 6850 extension, | 6941 extension, |
| 6851 context_chain->IsCatchContext()); | 6942 context_chain->IsCatchContext()); |
| 6852 } | 6943 } |
| 6853 | 6944 |
| 6854 | 6945 |
| 6855 // Helper function to find or create the arguments object for | 6946 // Helper function to find or create the arguments object for |
| 6856 // Runtime_DebugEvaluate. | 6947 // Runtime_DebugEvaluate. |
| 6857 static Handle<Object> GetArgumentsObject(JavaScriptFrame* frame, | 6948 static Handle<JSObject> GetArgumentsObject(JavaScriptFrame* frame, |
| 6858 Handle<JSFunction> function, | 6949 Handle<JSFunction> function, |
| 6859 Handle<Code> code, | 6950 Handle<Code> code, |
| 6860 const ScopeInfo<>* sinfo, | 6951 const ScopeInfo<>* sinfo, |
| 6861 Handle<Context> function_context) { | 6952 Handle<Context> function_context) { |
| 6862 // Try to find the value of 'arguments' to pass as parameter. If it is not | 6953 // Try to find the value of 'arguments' to pass as parameter. If it is not |
| 6863 // found (that is the debugged function does not reference 'arguments' and | 6954 // found (that is the debugged function does not reference 'arguments' and |
| 6864 // does not support eval) then create an 'arguments' object. | 6955 // does not support eval) then create an 'arguments' object. |
| 6865 int index; | 6956 int index; |
| 6866 if (sinfo->number_of_stack_slots() > 0) { | 6957 if (sinfo->number_of_stack_slots() > 0) { |
| 6867 index = ScopeInfo<>::StackSlotIndex(*code, Heap::arguments_symbol()); | 6958 index = ScopeInfo<>::StackSlotIndex(*code, Heap::arguments_symbol()); |
| 6868 if (index != -1) { | 6959 if (index != -1) { |
| 6869 return Handle<Object>(frame->GetExpression(index)); | 6960 return Handle<JSObject>(JSObject::cast(frame->GetExpression(index))); |
| 6870 } | 6961 } |
| 6871 } | 6962 } |
| 6872 | 6963 |
| 6873 if (sinfo->number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) { | 6964 if (sinfo->number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) { |
| 6874 index = ScopeInfo<>::ContextSlotIndex(*code, Heap::arguments_symbol(), | 6965 index = ScopeInfo<>::ContextSlotIndex(*code, Heap::arguments_symbol(), |
| 6875 NULL); | 6966 NULL); |
| 6876 if (index != -1) { | 6967 if (index != -1) { |
| 6877 return Handle<Object>(function_context->get(index)); | 6968 return Handle<JSObject>(JSObject::cast(function_context->get(index))); |
| 6878 } | 6969 } |
| 6879 } | 6970 } |
| 6880 | 6971 |
| 6881 const int length = frame->GetProvidedParametersCount(); | 6972 // Locate the actual frame which holds all the passed arguments. Either the |
| 6973 // current JavaScript frame or the adaptor frame just below it. |
| 6974 JavaScriptFrame* actual_frame = frame; |
| 6975 StackFrameIterator it(false, frame->fp(), frame->sp()); |
| 6976 if (frame->has_adapted_arguments()) { |
| 6977 ASSERT(it.frame()->is_java_script()); |
| 6978 it.Advance(); |
| 6979 ASSERT(!it.done()); |
| 6980 ASSERT(it.frame()->is_arguments_adaptor()); |
| 6981 actual_frame = reinterpret_cast<JavaScriptFrame*>(it.frame()); |
| 6982 } |
| 6983 |
| 6984 // Fill an array with all the passed arguments. |
| 6985 const int length = actual_frame->GetProvidedParametersCount(); |
| 6882 Handle<JSObject> arguments = Factory::NewArgumentsObject(function, length); | 6986 Handle<JSObject> arguments = Factory::NewArgumentsObject(function, length); |
| 6883 Handle<FixedArray> array = Factory::NewFixedArray(length); | 6987 Handle<FixedArray> array = Factory::NewFixedArray(length); |
| 6884 WriteBarrierMode mode = array->GetWriteBarrierMode(); | 6988 WriteBarrierMode mode = array->GetWriteBarrierMode(); |
| 6885 for (int i = 0; i < length; i++) { | 6989 for (int i = 0; i < length; i++) { |
| 6886 array->set(i, frame->GetParameter(i), mode); | 6990 array->set(i, actual_frame->GetParameter(i), mode); |
| 6887 } | 6991 } |
| 6888 arguments->set_elements(*array); | 6992 arguments->set_elements(*array); |
| 6889 return arguments; | 6993 return arguments; |
| 6890 } | 6994 } |
| 6891 | 6995 |
| 6892 | 6996 |
| 6893 // Evaluate a piece of JavaScript in the context of a stack frame for | 6997 // Evaluate a piece of JavaScript in the context of a stack frame for |
| 6894 // debugging. This is accomplished by creating a new context which in its | 6998 // debugging. This is accomplished by creating a new context which in its |
| 6895 // extension part has all the parameters and locals of the function on the | 6999 // extension part has all the parameters and locals of the function on the |
| 6896 // stack frame. A function which calls eval with the code to evaluate is then | 7000 // stack frame. A function which calls eval with the code to evaluate is then |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6983 Factory::NewFunctionFromBoilerplate(boilerplate, context); | 7087 Factory::NewFunctionFromBoilerplate(boilerplate, context); |
| 6984 | 7088 |
| 6985 // Invoke the result of the compilation to get the evaluation function. | 7089 // Invoke the result of the compilation to get the evaluation function. |
| 6986 bool has_pending_exception; | 7090 bool has_pending_exception; |
| 6987 Handle<Object> receiver(frame->receiver()); | 7091 Handle<Object> receiver(frame->receiver()); |
| 6988 Handle<Object> evaluation_function = | 7092 Handle<Object> evaluation_function = |
| 6989 Execution::Call(compiled_function, receiver, 0, NULL, | 7093 Execution::Call(compiled_function, receiver, 0, NULL, |
| 6990 &has_pending_exception); | 7094 &has_pending_exception); |
| 6991 if (has_pending_exception) return Failure::Exception(); | 7095 if (has_pending_exception) return Failure::Exception(); |
| 6992 | 7096 |
| 6993 Handle<Object> arguments = GetArgumentsObject(frame, function, code, &sinfo, | 7097 Handle<JSObject> arguments = GetArgumentsObject(frame, function, code, &sinfo, |
| 6994 function_context); | 7098 function_context); |
| 6995 | 7099 |
| 6996 // Invoke the evaluation function and return the result. | 7100 // Invoke the evaluation function and return the result. |
| 6997 const int argc = 2; | 7101 const int argc = 2; |
| 6998 Object** argv[argc] = { arguments.location(), | 7102 Object** argv[argc] = { reinterpret_cast<Object**>(arguments.location()), |
| 6999 Handle<Object>::cast(source).location() }; | 7103 Handle<Object>::cast(source).location() }; |
| 7000 Handle<Object> result = | 7104 Handle<Object> result = |
| 7001 Execution::Call(Handle<JSFunction>::cast(evaluation_function), receiver, | 7105 Execution::Call(Handle<JSFunction>::cast(evaluation_function), receiver, |
| 7002 argc, argv, &has_pending_exception); | 7106 argc, argv, &has_pending_exception); |
| 7107 // Write back the content of the materialized scope to where it came from to |
| 7108 // reflect changes from the evaluation.This must be done before returning any |
| 7109 // exceptions. |
| 7110 DematerializeLocalScope(frame, local_scope, arguments); |
| 7003 if (has_pending_exception) return Failure::Exception(); | 7111 if (has_pending_exception) return Failure::Exception(); |
| 7004 | 7112 |
| 7005 // Skip the global proxy as it has no properties and always delegates to the | 7113 // Skip the global proxy as it has no properties and always delegates to the |
| 7006 // real global object. | 7114 // real global object. |
| 7007 if (result->IsJSGlobalProxy()) { | 7115 if (result->IsJSGlobalProxy()) { |
| 7008 result = Handle<JSObject>(JSObject::cast(result->GetPrototype())); | 7116 result = Handle<JSObject>(JSObject::cast(result->GetPrototype())); |
| 7009 } | 7117 } |
| 7010 | 7118 |
| 7011 return *result; | 7119 return *result; |
| 7012 } | 7120 } |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7455 } else { | 7563 } else { |
| 7456 // Handle last resort GC and make sure to allow future allocations | 7564 // Handle last resort GC and make sure to allow future allocations |
| 7457 // to grow the heap without causing GCs (if possible). | 7565 // to grow the heap without causing GCs (if possible). |
| 7458 Counters::gc_last_resort_from_js.Increment(); | 7566 Counters::gc_last_resort_from_js.Increment(); |
| 7459 Heap::CollectAllGarbage(); | 7567 Heap::CollectAllGarbage(); |
| 7460 } | 7568 } |
| 7461 } | 7569 } |
| 7462 | 7570 |
| 7463 | 7571 |
| 7464 } } // namespace v8::internal | 7572 } } // namespace v8::internal |
| OLD | NEW |