Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(199)

Side by Side Diff: src/runtime.cc

Issue 125115: Added mutation of locals to debugger (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/frames.cc ('k') | test/mjsunit/debug-evaluate.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/frames.cc ('k') | test/mjsunit/debug-evaluate.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698