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 6088 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6099 Context::cast(Context::cast(it.frame()->context())->global_context())); | 6099 Context::cast(Context::cast(it.frame()->context())->global_context())); |
6100 receiver = Factory::ToObject(receiver, calling_frames_global_context); | 6100 receiver = Factory::ToObject(receiver, calling_frames_global_context); |
6101 } | 6101 } |
6102 details->set(kFrameDetailsReceiverIndex, *receiver); | 6102 details->set(kFrameDetailsReceiverIndex, *receiver); |
6103 | 6103 |
6104 ASSERT_EQ(details_size, details_index); | 6104 ASSERT_EQ(details_size, details_index); |
6105 return *Factory::NewJSArrayWithElements(details); | 6105 return *Factory::NewJSArrayWithElements(details); |
6106 } | 6106 } |
6107 | 6107 |
6108 | 6108 |
| 6109 // Copy all the context locals into an object used to materialize a scope. |
| 6110 static void CopyContextLocalsToScopeObject(Handle<Code> code, |
| 6111 ScopeInfo<>& scope_info, |
| 6112 Handle<Context> context, |
| 6113 Handle<JSObject> scope_object) { |
| 6114 // Fill all context locals to the context extension. |
| 6115 for (int i = Context::MIN_CONTEXT_SLOTS; |
| 6116 i < scope_info.number_of_context_slots(); |
| 6117 i++) { |
| 6118 int context_index = |
| 6119 ScopeInfo<>::ContextSlotIndex(*code, |
| 6120 *scope_info.context_slot_name(i), |
| 6121 NULL); |
| 6122 |
| 6123 // Don't include the arguments shadow (.arguments) context variable. |
| 6124 if (*scope_info.context_slot_name(i) != Heap::arguments_shadow_symbol()) { |
| 6125 SetProperty(scope_object, |
| 6126 scope_info.context_slot_name(i), |
| 6127 Handle<Object>(context->get(context_index)), NONE); |
| 6128 } |
| 6129 } |
| 6130 } |
| 6131 |
| 6132 |
| 6133 // Create a plain JSObject which materializes the local scope for the specified |
| 6134 // frame. |
| 6135 static Handle<JSObject> MaterializeLocalScope(JavaScriptFrame* frame) { |
| 6136 Handle<JSFunction> function(JSFunction::cast(frame->function())); |
| 6137 Handle<Code> code(function->code()); |
| 6138 ScopeInfo<> scope_info(*code); |
| 6139 |
| 6140 // Allocate and initialize a JSObject with all the arguments, stack locals |
| 6141 // heap locals and extension properties of the debugged function. |
| 6142 Handle<JSObject> local_scope = Factory::NewJSObject(Top::object_function()); |
| 6143 |
| 6144 // First fill all parameters. |
| 6145 for (int i = 0; i < scope_info.number_of_parameters(); ++i) { |
| 6146 SetProperty(local_scope, |
| 6147 scope_info.parameter_name(i), |
| 6148 Handle<Object>(frame->GetParameter(i)), NONE); |
| 6149 } |
| 6150 |
| 6151 // Second fill all stack locals. |
| 6152 for (int i = 0; i < scope_info.number_of_stack_slots(); i++) { |
| 6153 SetProperty(local_scope, |
| 6154 scope_info.stack_slot_name(i), |
| 6155 Handle<Object>(frame->GetExpression(i)), NONE); |
| 6156 } |
| 6157 |
| 6158 // Third fill all context locals. |
| 6159 Handle<Context> frame_context(Context::cast(frame->context())); |
| 6160 Handle<Context> function_context(frame_context->fcontext()); |
| 6161 CopyContextLocalsToScopeObject(code, scope_info, |
| 6162 function_context, local_scope); |
| 6163 |
| 6164 // Finally copy any properties from the function context extension. This will |
| 6165 // be variables introduced by eval. |
| 6166 if (function_context->closure() == *function) { |
| 6167 if (function_context->has_extension() && |
| 6168 !function_context->IsGlobalContext()) { |
| 6169 Handle<JSObject> ext(JSObject::cast(function_context->extension())); |
| 6170 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext); |
| 6171 for (int i = 0; i < keys->length(); i++) { |
| 6172 // Names of variables introduced by eval are strings. |
| 6173 ASSERT(keys->get(i)->IsString()); |
| 6174 Handle<String> key(String::cast(keys->get(i))); |
| 6175 SetProperty(local_scope, key, GetProperty(ext, key), NONE); |
| 6176 } |
| 6177 } |
| 6178 } |
| 6179 return local_scope; |
| 6180 } |
| 6181 |
| 6182 |
| 6183 // Create a plain JSObject which materializes the closure content for the |
| 6184 // context. |
| 6185 static Handle<JSObject> MaterializeClosure(Handle<Context> context) { |
| 6186 ASSERT(context->is_function_context()); |
| 6187 |
| 6188 Handle<Code> code(context->closure()->code()); |
| 6189 ScopeInfo<> scope_info(*code); |
| 6190 |
| 6191 // Allocate and initialize a JSObject with all the content of theis function |
| 6192 // closure. |
| 6193 Handle<JSObject> closure_scope = Factory::NewJSObject(Top::object_function()); |
| 6194 |
| 6195 // Check whether the arguments shadow object exists. |
| 6196 int arguments_shadow_index = |
| 6197 ScopeInfo<>::ContextSlotIndex(*code, |
| 6198 Heap::arguments_shadow_symbol(), |
| 6199 NULL); |
| 6200 if (arguments_shadow_index >= 0) { |
| 6201 // In this case all the arguments are available in the arguments shadow |
| 6202 // object. |
| 6203 Handle<JSObject> arguments_shadow( |
| 6204 JSObject::cast(context->get(arguments_shadow_index))); |
| 6205 for (int i = 0; i < scope_info.number_of_parameters(); ++i) { |
| 6206 SetProperty(closure_scope, |
| 6207 scope_info.parameter_name(i), |
| 6208 Handle<Object>(arguments_shadow->GetElement(i)), NONE); |
| 6209 } |
| 6210 } |
| 6211 |
| 6212 // Fill all context locals to the context extension. |
| 6213 CopyContextLocalsToScopeObject(code, scope_info, context, closure_scope); |
| 6214 |
| 6215 // Finally copy any properties from the function context extension. This will |
| 6216 // be variables introduced by eval. |
| 6217 if (context->has_extension()) { |
| 6218 Handle<JSObject> ext(JSObject::cast(context->extension())); |
| 6219 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext); |
| 6220 for (int i = 0; i < keys->length(); i++) { |
| 6221 // Names of variables introduced by eval are strings. |
| 6222 ASSERT(keys->get(i)->IsString()); |
| 6223 Handle<String> key(String::cast(keys->get(i))); |
| 6224 SetProperty(closure_scope, key, GetProperty(ext, key), NONE); |
| 6225 } |
| 6226 } |
| 6227 |
| 6228 return closure_scope; |
| 6229 } |
| 6230 |
| 6231 |
| 6232 // Iterate over the actual scopes visible from a stack frame. All scopes are |
| 6233 // backed by an actual context except the local scope, which is inserted |
| 6234 // "artifically" in the context chain. |
| 6235 class ScopeIterator { |
| 6236 public: |
| 6237 enum ScopeType { |
| 6238 ScopeTypeGlobal = 0, |
| 6239 ScopeTypeLocal, |
| 6240 ScopeTypeWith, |
| 6241 ScopeTypeClosure |
| 6242 }; |
| 6243 |
| 6244 explicit ScopeIterator(JavaScriptFrame* frame) |
| 6245 : frame_(frame), |
| 6246 function_(JSFunction::cast(frame->function())), |
| 6247 context_(Context::cast(frame->context())), |
| 6248 local_done_(false), |
| 6249 at_local_(false) { |
| 6250 |
| 6251 // Check whether the first scope is actually a local scope. |
| 6252 if (context_->IsGlobalContext()) { |
| 6253 // If there is a stack slot for .result then this local scope has been |
| 6254 // created for evaluating top level code and it is not a real local scope. |
| 6255 // Checking for the existence of .result seems fragile, but the scope info |
| 6256 // saved with the code object does not otherwise have that information. |
| 6257 Handle<Code> code(function_->code()); |
| 6258 int index = ScopeInfo<>::StackSlotIndex(*code, Heap::result_symbol()); |
| 6259 at_local_ = index < 0; |
| 6260 } else if (context_->is_function_context()) { |
| 6261 at_local_ = true; |
| 6262 } |
| 6263 } |
| 6264 |
| 6265 // More scopes? |
| 6266 bool Done() { return context_.is_null(); } |
| 6267 |
| 6268 // Move to the next scope. |
| 6269 void Next() { |
| 6270 // If at a local scope mark the local scope as passed. |
| 6271 if (at_local_) { |
| 6272 at_local_ = false; |
| 6273 local_done_ = true; |
| 6274 |
| 6275 // If the current context is not associated with the local scope the |
| 6276 // current context is the next real scope, so don't move to the next |
| 6277 // context in this case. |
| 6278 if (context_->closure() != *function_) { |
| 6279 return; |
| 6280 } |
| 6281 } |
| 6282 |
| 6283 // The global scope is always the last in the chain. |
| 6284 if (context_->IsGlobalContext()) { |
| 6285 context_ = Handle<Context>(); |
| 6286 return; |
| 6287 } |
| 6288 |
| 6289 // Move to the next context. |
| 6290 if (context_->is_function_context()) { |
| 6291 context_ = Handle<Context>(Context::cast(context_->closure()->context())); |
| 6292 } else { |
| 6293 context_ = Handle<Context>(context_->previous()); |
| 6294 } |
| 6295 |
| 6296 // If passing the local scope indicate that the current scope is now the |
| 6297 // local scope. |
| 6298 if (!local_done_ && |
| 6299 (context_->IsGlobalContext() || (context_->is_function_context()))) { |
| 6300 at_local_ = true; |
| 6301 } |
| 6302 } |
| 6303 |
| 6304 // Return the type of the current scope. |
| 6305 int Type() { |
| 6306 if (at_local_) { |
| 6307 return ScopeTypeLocal; |
| 6308 } |
| 6309 if (context_->IsGlobalContext()) { |
| 6310 ASSERT(context_->global()->IsGlobalObject()); |
| 6311 return ScopeTypeGlobal; |
| 6312 } |
| 6313 if (context_->is_function_context()) { |
| 6314 return ScopeTypeClosure; |
| 6315 } |
| 6316 ASSERT(context_->has_extension()); |
| 6317 ASSERT(!context_->extension()->IsJSContextExtensionObject()); |
| 6318 return ScopeTypeWith; |
| 6319 } |
| 6320 |
| 6321 // Return the JavaScript object with the content of the current scope. |
| 6322 Handle<JSObject> ScopeObject() { |
| 6323 switch (Type()) { |
| 6324 case ScopeIterator::ScopeTypeGlobal: |
| 6325 return Handle<JSObject>(CurrentContext()->global()); |
| 6326 break; |
| 6327 case ScopeIterator::ScopeTypeLocal: |
| 6328 // Materialize the content of the local scope into a JSObject. |
| 6329 return MaterializeLocalScope(frame_); |
| 6330 break; |
| 6331 case ScopeIterator::ScopeTypeWith: |
| 6332 // Return the with object. |
| 6333 return Handle<JSObject>(CurrentContext()->extension()); |
| 6334 break; |
| 6335 case ScopeIterator::ScopeTypeClosure: |
| 6336 // Materialize the content of the closure scope into a JSObject. |
| 6337 return MaterializeClosure(CurrentContext()); |
| 6338 break; |
| 6339 default: |
| 6340 UNREACHABLE(); |
| 6341 return Handle<JSObject>(); |
| 6342 } |
| 6343 } |
| 6344 |
| 6345 // Return the context for this scope. For the local context there might not |
| 6346 // be an actual context. |
| 6347 Handle<Context> CurrentContext() { |
| 6348 if (at_local_ && context_->closure() != *function_) { |
| 6349 return Handle<Context>(); |
| 6350 } |
| 6351 return context_; |
| 6352 } |
| 6353 |
| 6354 #ifdef DEBUG |
| 6355 // Debug print of the content of the current scope. |
| 6356 void DebugPrint() { |
| 6357 switch (Type()) { |
| 6358 case ScopeIterator::ScopeTypeGlobal: |
| 6359 PrintF("Global:\n"); |
| 6360 CurrentContext()->Print(); |
| 6361 break; |
| 6362 |
| 6363 case ScopeIterator::ScopeTypeLocal: { |
| 6364 PrintF("Local:\n"); |
| 6365 Handle<Code> code(function_->code()); |
| 6366 ScopeInfo<> scope_info(*code); |
| 6367 scope_info.Print(); |
| 6368 if (!CurrentContext().is_null()) { |
| 6369 CurrentContext()->Print(); |
| 6370 if (CurrentContext()->has_extension()) { |
| 6371 Handle<JSObject> extension = |
| 6372 Handle<JSObject>(CurrentContext()->extension()); |
| 6373 if (extension->IsJSContextExtensionObject()) { |
| 6374 extension->Print(); |
| 6375 } |
| 6376 } |
| 6377 } |
| 6378 break; |
| 6379 } |
| 6380 |
| 6381 case ScopeIterator::ScopeTypeWith: { |
| 6382 PrintF("With:\n"); |
| 6383 Handle<JSObject> extension = |
| 6384 Handle<JSObject>(CurrentContext()->extension()); |
| 6385 extension->Print(); |
| 6386 break; |
| 6387 } |
| 6388 |
| 6389 case ScopeIterator::ScopeTypeClosure: { |
| 6390 PrintF("Closure:\n"); |
| 6391 CurrentContext()->Print(); |
| 6392 if (CurrentContext()->has_extension()) { |
| 6393 Handle<JSObject> extension = |
| 6394 Handle<JSObject>(CurrentContext()->extension()); |
| 6395 if (extension->IsJSContextExtensionObject()) { |
| 6396 extension->Print(); |
| 6397 } |
| 6398 } |
| 6399 break; |
| 6400 } |
| 6401 |
| 6402 default: |
| 6403 UNREACHABLE(); |
| 6404 } |
| 6405 PrintF("\n"); |
| 6406 } |
| 6407 #endif |
| 6408 |
| 6409 private: |
| 6410 JavaScriptFrame* frame_; |
| 6411 Handle<JSFunction> function_; |
| 6412 Handle<Context> context_; |
| 6413 bool local_done_; |
| 6414 bool at_local_; |
| 6415 |
| 6416 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator); |
| 6417 }; |
| 6418 |
| 6419 |
| 6420 static Object* Runtime_GetScopeCount(Arguments args) { |
| 6421 HandleScope scope; |
| 6422 ASSERT(args.length() == 2); |
| 6423 |
| 6424 // Check arguments. |
| 6425 Object* check = Runtime_CheckExecutionState(args); |
| 6426 if (check->IsFailure()) return check; |
| 6427 CONVERT_CHECKED(Smi, wrapped_id, args[1]); |
| 6428 |
| 6429 // Get the frame where the debugging is performed. |
| 6430 StackFrame::Id id = UnwrapFrameId(wrapped_id); |
| 6431 JavaScriptFrameIterator it(id); |
| 6432 JavaScriptFrame* frame = it.frame(); |
| 6433 |
| 6434 // Count the visible scopes. |
| 6435 int n = 0; |
| 6436 for (ScopeIterator it(frame); !it.Done(); it.Next()) { |
| 6437 n++; |
| 6438 } |
| 6439 |
| 6440 return Smi::FromInt(n); |
| 6441 } |
| 6442 |
| 6443 |
| 6444 static const int kScopeDetailsTypeIndex = 0; |
| 6445 static const int kScopeDetailsObjectIndex = 1; |
| 6446 static const int kScopeDetailsSize = 2; |
| 6447 |
| 6448 // Return an array with scope details |
| 6449 // args[0]: number: break id |
| 6450 // args[1]: number: frame index |
| 6451 // args[2]: number: scope index |
| 6452 // |
| 6453 // The array returned contains the following information: |
| 6454 // 0: Scope type |
| 6455 // 1: Scope object |
| 6456 static Object* Runtime_GetScopeDetails(Arguments args) { |
| 6457 HandleScope scope; |
| 6458 ASSERT(args.length() == 3); |
| 6459 |
| 6460 // Check arguments. |
| 6461 Object* check = Runtime_CheckExecutionState(args); |
| 6462 if (check->IsFailure()) return check; |
| 6463 CONVERT_CHECKED(Smi, wrapped_id, args[1]); |
| 6464 CONVERT_NUMBER_CHECKED(int, index, Int32, args[2]); |
| 6465 |
| 6466 // Get the frame where the debugging is performed. |
| 6467 StackFrame::Id id = UnwrapFrameId(wrapped_id); |
| 6468 JavaScriptFrameIterator frame_it(id); |
| 6469 JavaScriptFrame* frame = frame_it.frame(); |
| 6470 |
| 6471 // Find the requested scope. |
| 6472 int n = 0; |
| 6473 ScopeIterator it(frame); |
| 6474 for (; !it.Done() && n < index; it.Next()) { |
| 6475 n++; |
| 6476 } |
| 6477 if (it.Done()) { |
| 6478 return Heap::undefined_value(); |
| 6479 } |
| 6480 |
| 6481 // Calculate the size of the result. |
| 6482 int details_size = kScopeDetailsSize; |
| 6483 Handle<FixedArray> details = Factory::NewFixedArray(details_size); |
| 6484 |
| 6485 // Fill in scope details. |
| 6486 details->set(kScopeDetailsTypeIndex, Smi::FromInt(it.Type())); |
| 6487 details->set(kScopeDetailsObjectIndex, *it.ScopeObject()); |
| 6488 |
| 6489 return *Factory::NewJSArrayWithElements(details); |
| 6490 } |
| 6491 |
| 6492 |
| 6493 static Object* Runtime_DebugPrintScopes(Arguments args) { |
| 6494 HandleScope scope; |
| 6495 ASSERT(args.length() == 0); |
| 6496 |
| 6497 #ifdef DEBUG |
| 6498 // Print the scopes for the top frame. |
| 6499 StackFrameLocator locator; |
| 6500 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); |
| 6501 for (ScopeIterator it(frame); !it.Done(); it.Next()) { |
| 6502 it.DebugPrint(); |
| 6503 } |
| 6504 #endif |
| 6505 return Heap::undefined_value(); |
| 6506 } |
| 6507 |
| 6508 |
6109 static Object* Runtime_GetCFrames(Arguments args) { | 6509 static Object* Runtime_GetCFrames(Arguments args) { |
6110 HandleScope scope; | 6510 HandleScope scope; |
6111 ASSERT(args.length() == 1); | 6511 ASSERT(args.length() == 1); |
6112 Object* result = Runtime_CheckExecutionState(args); | 6512 Object* result = Runtime_CheckExecutionState(args); |
6113 if (result->IsFailure()) return result; | 6513 if (result->IsFailure()) return result; |
6114 | 6514 |
6115 #if V8_HOST_ARCH_64_BIT | 6515 #if V8_HOST_ARCH_64_BIT |
6116 UNIMPLEMENTED(); | 6516 UNIMPLEMENTED(); |
6117 return Heap::undefined_value(); | 6517 return Heap::undefined_value(); |
6118 #else | 6518 #else |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6561 // are looked at before the extension object. | 6961 // are looked at before the extension object. |
6562 Handle<JSFunction> go_between = | 6962 Handle<JSFunction> go_between = |
6563 Factory::NewFunction(Factory::empty_string(), Factory::undefined_value()); | 6963 Factory::NewFunction(Factory::empty_string(), Factory::undefined_value()); |
6564 go_between->set_context(function->context()); | 6964 go_between->set_context(function->context()); |
6565 #ifdef DEBUG | 6965 #ifdef DEBUG |
6566 ScopeInfo<> go_between_sinfo(go_between->shared()->code()); | 6966 ScopeInfo<> go_between_sinfo(go_between->shared()->code()); |
6567 ASSERT(go_between_sinfo.number_of_parameters() == 0); | 6967 ASSERT(go_between_sinfo.number_of_parameters() == 0); |
6568 ASSERT(go_between_sinfo.number_of_context_slots() == 0); | 6968 ASSERT(go_between_sinfo.number_of_context_slots() == 0); |
6569 #endif | 6969 #endif |
6570 | 6970 |
6571 // Allocate and initialize a context extension object with all the | 6971 // Materialize the content of the local scope into a JSObject. |
6572 // arguments, stack locals heap locals and extension properties of the | 6972 Handle<JSObject> local_scope = MaterializeLocalScope(frame); |
6573 // debugged function. | |
6574 Handle<JSObject> context_ext = Factory::NewJSObject(Top::object_function()); | |
6575 // First fill all parameters to the context extension. | |
6576 for (int i = 0; i < sinfo.number_of_parameters(); ++i) { | |
6577 SetProperty(context_ext, | |
6578 sinfo.parameter_name(i), | |
6579 Handle<Object>(frame->GetParameter(i)), NONE); | |
6580 } | |
6581 // Second fill all stack locals to the context extension. | |
6582 for (int i = 0; i < sinfo.number_of_stack_slots(); i++) { | |
6583 SetProperty(context_ext, | |
6584 sinfo.stack_slot_name(i), | |
6585 Handle<Object>(frame->GetExpression(i)), NONE); | |
6586 } | |
6587 // Third fill all context locals to the context extension. | |
6588 Handle<Context> frame_context(Context::cast(frame->context())); | |
6589 Handle<Context> function_context(frame_context->fcontext()); | |
6590 for (int i = Context::MIN_CONTEXT_SLOTS; | |
6591 i < sinfo.number_of_context_slots(); | |
6592 ++i) { | |
6593 int context_index = | |
6594 ScopeInfo<>::ContextSlotIndex(*code, *sinfo.context_slot_name(i), NULL); | |
6595 SetProperty(context_ext, | |
6596 sinfo.context_slot_name(i), | |
6597 Handle<Object>(function_context->get(context_index)), NONE); | |
6598 } | |
6599 // Finally copy any properties from the function context extension. This will | |
6600 // be variables introduced by eval. | |
6601 if (function_context->has_extension() && | |
6602 !function_context->IsGlobalContext()) { | |
6603 Handle<JSObject> ext(JSObject::cast(function_context->extension())); | |
6604 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext); | |
6605 for (int i = 0; i < keys->length(); i++) { | |
6606 // Names of variables introduced by eval are strings. | |
6607 ASSERT(keys->get(i)->IsString()); | |
6608 Handle<String> key(String::cast(keys->get(i))); | |
6609 SetProperty(context_ext, key, GetProperty(ext, key), NONE); | |
6610 } | |
6611 } | |
6612 | 6973 |
6613 // Allocate a new context for the debug evaluation and set the extension | 6974 // Allocate a new context for the debug evaluation and set the extension |
6614 // object build. | 6975 // object build. |
6615 Handle<Context> context = | 6976 Handle<Context> context = |
6616 Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, go_between); | 6977 Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, go_between); |
6617 context->set_extension(*context_ext); | 6978 context->set_extension(*local_scope); |
6618 // Copy any with contexts present and chain them in front of this context. | 6979 // Copy any with contexts present and chain them in front of this context. |
| 6980 Handle<Context> frame_context(Context::cast(frame->context())); |
| 6981 Handle<Context> function_context(frame_context->fcontext()); |
6619 context = CopyWithContextChain(frame_context, context); | 6982 context = CopyWithContextChain(frame_context, context); |
6620 | 6983 |
6621 // Wrap the evaluation statement in a new function compiled in the newly | 6984 // Wrap the evaluation statement in a new function compiled in the newly |
6622 // created context. The function has one parameter which has to be called | 6985 // created context. The function has one parameter which has to be called |
6623 // 'arguments'. This it to have access to what would have been 'arguments' in | 6986 // 'arguments'. This it to have access to what would have been 'arguments' in |
6624 // the function being debugged. | 6987 // the function being debugged. |
6625 // function(arguments,__source__) {return eval(__source__);} | 6988 // function(arguments,__source__) {return eval(__source__);} |
6626 static const char* source_str = | 6989 static const char* source_str = |
6627 "function(arguments,__source__){return eval(__source__);}"; | 6990 "function(arguments,__source__){return eval(__source__);}"; |
6628 static const int source_str_length = strlen(source_str); | 6991 static const int source_str_length = strlen(source_str); |
(...skipping 21 matching lines...) Expand all Loading... |
6650 function_context); | 7013 function_context); |
6651 | 7014 |
6652 // Invoke the evaluation function and return the result. | 7015 // Invoke the evaluation function and return the result. |
6653 const int argc = 2; | 7016 const int argc = 2; |
6654 Object** argv[argc] = { arguments.location(), | 7017 Object** argv[argc] = { arguments.location(), |
6655 Handle<Object>::cast(source).location() }; | 7018 Handle<Object>::cast(source).location() }; |
6656 Handle<Object> result = | 7019 Handle<Object> result = |
6657 Execution::Call(Handle<JSFunction>::cast(evaluation_function), receiver, | 7020 Execution::Call(Handle<JSFunction>::cast(evaluation_function), receiver, |
6658 argc, argv, &has_pending_exception); | 7021 argc, argv, &has_pending_exception); |
6659 if (has_pending_exception) return Failure::Exception(); | 7022 if (has_pending_exception) return Failure::Exception(); |
| 7023 |
| 7024 // Skip the global proxy as it has no properties and always delegates to the |
| 7025 // real global object. |
| 7026 if (result->IsJSGlobalProxy()) { |
| 7027 result = Handle<JSObject>(JSObject::cast(result->GetPrototype())); |
| 7028 } |
| 7029 |
6660 return *result; | 7030 return *result; |
6661 } | 7031 } |
6662 | 7032 |
6663 | 7033 |
6664 static Object* Runtime_DebugEvaluateGlobal(Arguments args) { | 7034 static Object* Runtime_DebugEvaluateGlobal(Arguments args) { |
6665 HandleScope scope; | 7035 HandleScope scope; |
6666 | 7036 |
6667 // Check the execution state and decode arguments frame and source to be | 7037 // Check the execution state and decode arguments frame and source to be |
6668 // evaluated. | 7038 // evaluated. |
6669 ASSERT(args.length() == 3); | 7039 ASSERT(args.length() == 3); |
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7104 } else { | 7474 } else { |
7105 // Handle last resort GC and make sure to allow future allocations | 7475 // Handle last resort GC and make sure to allow future allocations |
7106 // to grow the heap without causing GCs (if possible). | 7476 // to grow the heap without causing GCs (if possible). |
7107 Counters::gc_last_resort_from_js.Increment(); | 7477 Counters::gc_last_resort_from_js.Increment(); |
7108 Heap::CollectAllGarbage(); | 7478 Heap::CollectAllGarbage(); |
7109 } | 7479 } |
7110 } | 7480 } |
7111 | 7481 |
7112 | 7482 |
7113 } } // namespace v8::internal | 7483 } } // namespace v8::internal |
OLD | NEW |