Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/runtime/runtime-utils.h" | 5 #include "src/runtime/runtime-utils.h" |
| 6 | 6 |
| 7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
| 8 #include "src/debug/debug-evaluate.h" | 8 #include "src/debug/debug-evaluate.h" |
| 9 #include "src/debug/debug-frames.h" | 9 #include "src/debug/debug-frames.h" |
| 10 #include "src/debug/debug-scopes.h" | 10 #include "src/debug/debug-scopes.h" |
| 11 #include "src/debug/debug.h" | 11 #include "src/debug/debug.h" |
| 12 #include "src/frames-inl.h" | 12 #include "src/frames-inl.h" |
| 13 #include "src/interpreter/bytecodes.h" | 13 #include "src/interpreter/bytecodes.h" |
| 14 #include "src/interpreter/interpreter.h" | 14 #include "src/interpreter/interpreter.h" |
| 15 #include "src/isolate-inl.h" | 15 #include "src/isolate-inl.h" |
| 16 #include "src/runtime/runtime.h" | 16 #include "src/runtime/runtime.h" |
| 17 #include "src/wasm/wasm-module.h" | |
| 17 | 18 |
| 18 namespace v8 { | 19 namespace v8 { |
| 19 namespace internal { | 20 namespace internal { |
| 20 | 21 |
| 21 RUNTIME_FUNCTION(Runtime_DebugBreak) { | 22 RUNTIME_FUNCTION(Runtime_DebugBreak) { |
| 22 SealHandleScope shs(isolate); | 23 SealHandleScope shs(isolate); |
| 23 DCHECK(args.length() == 1); | 24 DCHECK(args.length() == 1); |
| 24 CONVERT_ARG_HANDLE_CHECKED(Object, value, 0); | 25 CONVERT_ARG_HANDLE_CHECKED(Object, value, 0); |
| 25 isolate->debug()->set_return_value(value); | 26 isolate->debug()->set_return_value(value); |
| 26 | 27 |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 446 RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id)); | 447 RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id)); |
| 447 | 448 |
| 448 // Count all frames which are relevant to debugging stack trace. | 449 // Count all frames which are relevant to debugging stack trace. |
| 449 int n = 0; | 450 int n = 0; |
| 450 StackFrame::Id id = isolate->debug()->break_frame_id(); | 451 StackFrame::Id id = isolate->debug()->break_frame_id(); |
| 451 if (id == StackFrame::NO_ID) { | 452 if (id == StackFrame::NO_ID) { |
| 452 // If there is no JavaScript stack frame count is 0. | 453 // If there is no JavaScript stack frame count is 0. |
| 453 return Smi::FromInt(0); | 454 return Smi::FromInt(0); |
| 454 } | 455 } |
| 455 | 456 |
| 456 for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) { | 457 for (StackTraceFrameIterator it(isolate, id); !it.done(); it.Advance()) { |
| 457 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); | 458 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); |
| 458 it.frame()->Summarize(&frames); | 459 if (it.is_wasm()) { |
| 459 for (int i = frames.length() - 1; i >= 0; i--) { | 460 n++; |
| 460 // Omit functions from native and extension scripts. | 461 } else { |
| 461 if (frames[i].function()->shared()->IsSubjectToDebugging()) n++; | 462 it.javascript_frame()->Summarize(&frames); |
| 463 for (int i = frames.length() - 1; i >= 0; i--) { | |
| 464 // Omit functions from native and extension scripts. | |
| 465 if (frames[i].function()->shared()->IsSubjectToDebugging()) n++; | |
| 466 } | |
| 462 } | 467 } |
| 463 } | 468 } |
| 464 return Smi::FromInt(n); | 469 return Smi::FromInt(n); |
| 465 } | 470 } |
| 466 | 471 |
| 467 | 472 |
| 468 static const int kFrameDetailsFrameIdIndex = 0; | 473 static const int kFrameDetailsFrameIdIndex = 0; |
| 469 static const int kFrameDetailsReceiverIndex = 1; | 474 static const int kFrameDetailsReceiverIndex = 1; |
| 470 static const int kFrameDetailsFunctionIndex = 2; | 475 static const int kFrameDetailsFunctionIndex = 2; |
| 471 static const int kFrameDetailsArgumentCountIndex = 3; | 476 static const int kFrameDetailsScriptIndex = 3; |
| 472 static const int kFrameDetailsLocalCountIndex = 4; | 477 static const int kFrameDetailsArgumentCountIndex = 4; |
| 473 static const int kFrameDetailsSourcePositionIndex = 5; | 478 static const int kFrameDetailsLocalCountIndex = 5; |
| 474 static const int kFrameDetailsConstructCallIndex = 6; | 479 static const int kFrameDetailsSourcePositionIndex = 6; |
| 475 static const int kFrameDetailsAtReturnIndex = 7; | 480 static const int kFrameDetailsConstructCallIndex = 7; |
| 476 static const int kFrameDetailsFlagsIndex = 8; | 481 static const int kFrameDetailsAtReturnIndex = 8; |
| 477 static const int kFrameDetailsFirstDynamicIndex = 9; | 482 static const int kFrameDetailsFlagsIndex = 9; |
| 478 | 483 static const int kFrameDetailsFirstDynamicIndex = 10; |
| 479 | 484 |
| 480 // Return an array with frame details | 485 // Return an array with frame details |
| 481 // args[0]: number: break id | 486 // args[0]: number: break id |
| 482 // args[1]: number: frame index | 487 // args[1]: number: frame index |
| 483 // | 488 // |
| 484 // The array returned contains the following information: | 489 // The array returned contains the following information: |
| 485 // 0: Frame id | 490 // 0: Frame id |
| 486 // 1: Receiver | 491 // 1: Receiver |
| 487 // 2: Function | 492 // 2: Function |
| 488 // 3: Argument count | 493 // 3: Script |
| 489 // 4: Local count | 494 // 4: Argument count |
| 490 // 5: Source position | 495 // 5: Local count |
| 491 // 6: Constructor call | 496 // 6: Source position |
| 492 // 7: Is at return | 497 // 7: Constructor call |
| 493 // 8: Flags | 498 // 8: Is at return |
| 499 // 9: Flags | |
| 494 // Arguments name, value | 500 // Arguments name, value |
| 495 // Locals name, value | 501 // Locals name, value |
| 496 // Return value if any | 502 // Return value if any |
| 497 RUNTIME_FUNCTION(Runtime_GetFrameDetails) { | 503 RUNTIME_FUNCTION(Runtime_GetFrameDetails) { |
| 498 HandleScope scope(isolate); | 504 HandleScope scope(isolate); |
| 499 DCHECK(args.length() == 2); | 505 DCHECK(args.length() == 2); |
| 500 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); | 506 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); |
| 501 RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id)); | 507 RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id)); |
| 502 | 508 |
| 503 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); | 509 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); |
| 504 Heap* heap = isolate->heap(); | 510 Heap* heap = isolate->heap(); |
| 505 | 511 |
| 506 // Find the relevant frame with the requested index. | 512 // Find the relevant frame with the requested index. |
| 507 StackFrame::Id id = isolate->debug()->break_frame_id(); | 513 StackFrame::Id id = isolate->debug()->break_frame_id(); |
| 508 if (id == StackFrame::NO_ID) { | 514 if (id == StackFrame::NO_ID) { |
| 509 // If there are no JavaScript stack frames return undefined. | 515 // If there are no JavaScript stack frames return undefined. |
| 510 return heap->undefined_value(); | 516 return heap->undefined_value(); |
| 511 } | 517 } |
| 512 | 518 |
| 513 JavaScriptFrameIterator it(isolate, id); | 519 StackTraceFrameIterator it(isolate, id); |
| 514 // Inlined frame index in optimized frame, starting from outer function. | 520 // Inlined frame index in optimized frame, starting from outer function. |
| 515 int inlined_jsframe_index = | 521 int inlined_jsframe_index = |
| 516 DebugFrameHelper::FindIndexedNonNativeFrame(&it, index); | 522 DebugFrameHelper::FindIndexedNonNativeFrame(&it, index); |
| 517 if (inlined_jsframe_index == -1) return heap->undefined_value(); | 523 if (inlined_jsframe_index == -1) return heap->undefined_value(); |
| 518 | 524 |
| 519 FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate); | 525 FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate); |
| 520 bool is_optimized = it.frame()->is_optimized(); | 526 bool is_optimized = it.frame()->is_optimized(); |
| 521 | 527 |
| 522 // Traverse the saved contexts chain to find the active context for the | 528 // Traverse the saved contexts chain to find the active context for the |
| 523 // selected frame. | 529 // selected frame. |
| 524 SaveContext* save = | 530 SaveContext* save = |
| 525 DebugFrameHelper::FindSavedContextForFrame(isolate, it.frame()); | 531 DebugFrameHelper::FindSavedContextForFrame(isolate, it.frame()); |
| 526 | 532 |
| 527 // Get the frame id. | 533 // Get the frame id. |
| 528 Handle<Object> frame_id(DebugFrameHelper::WrapFrameId(it.frame()->id()), | 534 Handle<Object> frame_id(DebugFrameHelper::WrapFrameId(it.frame()->id()), |
| 529 isolate); | 535 isolate); |
| 530 | 536 |
| 531 // Find source position in unoptimized code. | 537 // Find source position in unoptimized code. |
| 532 int position = frame_inspector.GetSourcePosition(); | 538 int position = frame_inspector.GetSourcePosition(); |
| 533 | 539 |
| 534 // Check for constructor frame. | 540 // Check for constructor frame. |
| 535 bool constructor = frame_inspector.IsConstructor(); | 541 bool constructor = frame_inspector.IsConstructor(); |
| 536 | 542 |
| 537 // Get scope info and read from it for local variable information. | 543 Handle<ScopeInfo> scope_info; |
| 538 Handle<JSFunction> function = | |
| 539 Handle<JSFunction>::cast(frame_inspector.GetFunction()); | |
| 540 RUNTIME_ASSERT(function->shared()->IsSubjectToDebugging()); | |
| 541 Handle<SharedFunctionInfo> shared(function->shared()); | |
| 542 Handle<ScopeInfo> scope_info(shared->scope_info()); | |
| 543 DCHECK(*scope_info != ScopeInfo::Empty(isolate)); | |
| 544 | 544 |
| 545 // Get the locals names and values into a temporary array. | 545 // Get the locals names and values into a temporary array. |
| 546 int local_count = scope_info->LocalCount(); | 546 Handle<FixedArray> locals; |
|
Yang
2016/06/24 05:56:37
Can we re-organize this file like this?
if (it.is
Clemens Hammacher
2016/06/24 09:23:31
Done.
| |
| 547 for (int slot = 0; slot < scope_info->LocalCount(); ++slot) { | 547 if (it.is_wasm()) { |
| 548 // Hide compiler-introduced temporary variables, whether on the stack or on | 548 // TODO(clemensh): add names and values of local variables. |
| 549 // the context. | 549 locals = isolate->factory()->NewFixedArray(0); |
| 550 if (ScopeInfo::VariableIsSynthetic(scope_info->LocalName(slot))) { | 550 } else { |
| 551 local_count--; | 551 // Get scope info and read from it for local variable information. |
| 552 SharedFunctionInfo* shared = frame_inspector.GetFunction()->shared(); | |
| 553 RUNTIME_ASSERT(shared->IsSubjectToDebugging()); | |
| 554 scope_info = handle(shared->scope_info(), isolate); | |
| 555 DCHECK(*scope_info != ScopeInfo::Empty(isolate)); | |
| 556 | |
| 557 int local_count = scope_info->LocalCount(); | |
| 558 for (int slot = 0; slot < scope_info->LocalCount(); ++slot) { | |
| 559 // Hide compiler-introduced temporary variables, whether on the stack or | |
| 560 // on the context. | |
| 561 if (ScopeInfo::VariableIsSynthetic(scope_info->LocalName(slot))) { | |
| 562 local_count--; | |
| 563 } | |
| 552 } | 564 } |
| 553 } | |
| 554 | 565 |
| 555 Handle<FixedArray> locals = | 566 locals = isolate->factory()->NewFixedArray(local_count * 2); |
| 556 isolate->factory()->NewFixedArray(local_count * 2); | |
| 557 | 567 |
| 558 // Fill in the values of the locals. | 568 // Fill in the values of the locals. |
| 559 int local = 0; | 569 int local = 0; |
| 560 int i = 0; | 570 int i = 0; |
| 561 for (; i < scope_info->StackLocalCount(); ++i) { | 571 for (; i < scope_info->StackLocalCount(); ++i) { |
| 562 // Use the value from the stack. | 572 // Use the value from the stack. |
| 563 if (ScopeInfo::VariableIsSynthetic(scope_info->LocalName(i))) continue; | 573 if (ScopeInfo::VariableIsSynthetic(scope_info->LocalName(i))) continue; |
| 564 locals->set(local * 2, scope_info->LocalName(i)); | 574 locals->set(local * 2, scope_info->LocalName(i)); |
| 565 Handle<Object> value = | 575 Handle<Object> value = |
| 566 frame_inspector.GetExpression(scope_info->StackLocalIndex(i)); | 576 frame_inspector.GetExpression(scope_info->StackLocalIndex(i)); |
| 567 // TODO(yangguo): We convert optimized out values to {undefined} when they | 577 // TODO(yangguo): We convert optimized out values to {undefined} when they |
| 568 // are passed to the debugger. Eventually we should handle them somehow. | 578 // are passed to the debugger. Eventually we should handle them somehow. |
| 569 if (value->IsOptimizedOut(isolate)) { | 579 if (value->IsOptimizedOut(isolate)) { |
| 570 value = isolate->factory()->undefined_value(); | 580 value = isolate->factory()->undefined_value(); |
| 581 } | |
| 582 locals->set(local * 2 + 1, *value); | |
| 583 local++; | |
| 571 } | 584 } |
| 572 locals->set(local * 2 + 1, *value); | 585 if (local < local_count) { |
| 573 local++; | 586 // Get the context containing declarations. |
| 574 } | 587 Handle<Context> context( |
| 575 if (local < local_count) { | 588 Handle<Context>::cast(frame_inspector.GetContext()) |
| 576 // Get the context containing declarations. | 589 ->closure_context()); |
| 577 Handle<Context> context( | 590 for (; i < scope_info->LocalCount(); ++i) { |
| 578 Handle<Context>::cast(frame_inspector.GetContext())->closure_context()); | 591 Handle<String> name(scope_info->LocalName(i)); |
| 579 for (; i < scope_info->LocalCount(); ++i) { | 592 if (ScopeInfo::VariableIsSynthetic(*name)) continue; |
| 580 Handle<String> name(scope_info->LocalName(i)); | 593 VariableMode mode; |
| 581 if (ScopeInfo::VariableIsSynthetic(*name)) continue; | 594 InitializationFlag init_flag; |
| 582 VariableMode mode; | 595 MaybeAssignedFlag maybe_assigned_flag; |
| 583 InitializationFlag init_flag; | 596 locals->set(local * 2, *name); |
| 584 MaybeAssignedFlag maybe_assigned_flag; | 597 int context_slot_index = ScopeInfo::ContextSlotIndex( |
| 585 locals->set(local * 2, *name); | 598 scope_info, name, &mode, &init_flag, &maybe_assigned_flag); |
| 586 int context_slot_index = ScopeInfo::ContextSlotIndex( | 599 Object* value = context->get(context_slot_index); |
| 587 scope_info, name, &mode, &init_flag, &maybe_assigned_flag); | 600 locals->set(local * 2 + 1, value); |
| 588 Object* value = context->get(context_slot_index); | 601 local++; |
| 589 locals->set(local * 2 + 1, value); | 602 } |
| 590 local++; | |
| 591 } | 603 } |
| 592 } | 604 } |
| 593 | 605 |
| 594 // Check whether this frame is positioned at return. If not top | 606 // Check whether this frame is positioned at return. If not top |
| 595 // frame or if the frame is optimized it cannot be at a return. | 607 // frame or if the frame is optimized it cannot be at a return. |
| 596 bool at_return = false; | 608 bool at_return = false; |
| 597 if (!is_optimized && index == 0) { | 609 if (!is_optimized && index == 0) { |
| 598 at_return = isolate->debug()->IsBreakAtReturn(it.frame()); | 610 at_return = isolate->debug()->IsBreakAtReturn(it.frame()); |
| 599 } | 611 } |
| 600 | 612 |
| 601 // If positioned just before return find the value to be returned and add it | 613 // If positioned just before return find the value to be returned and add it |
| 602 // to the frame information. | 614 // to the frame information. |
| 603 Handle<Object> return_value = isolate->factory()->undefined_value(); | 615 Handle<Object> return_value = isolate->factory()->undefined_value(); |
| 604 if (at_return) { | 616 if (at_return) { |
| 605 return_value = isolate->debug()->return_value(); | 617 return_value = isolate->debug()->return_value(); |
| 606 } | 618 } |
| 607 | 619 |
| 608 // Now advance to the arguments adapter frame (if any). It contains all | 620 // Now advance to the arguments adapter frame (if any). It contains all |
| 609 // the provided parameters whereas the function frame always have the number | 621 // the provided parameters whereas the function frame always have the number |
| 610 // of arguments matching the functions parameters. The rest of the | 622 // of arguments matching the functions parameters. The rest of the |
| 611 // information (except for what is collected above) is the same. | 623 // information (except for what is collected above) is the same. |
| 612 if ((inlined_jsframe_index == 0) && it.frame()->has_adapted_arguments()) { | 624 if ((inlined_jsframe_index == 0) && it.frame()->is_java_script() && |
| 625 it.javascript_frame()->has_adapted_arguments()) { | |
| 613 it.AdvanceToArgumentsFrame(); | 626 it.AdvanceToArgumentsFrame(); |
| 614 frame_inspector.SetArgumentsFrame(it.frame()); | 627 frame_inspector.SetArgumentsFrame(it.frame()); |
| 615 } | 628 } |
| 616 | 629 |
| 617 // Find the number of arguments to fill. At least fill the number of | 630 // Find the number of arguments to fill. At least fill the number of |
| 618 // parameters for the function and fill more if more parameters are provided. | 631 // parameters for the function and fill more if more parameters are provided. |
| 619 int argument_count = scope_info->ParameterCount(); | 632 int argument_count = frame_inspector.GetParametersCount(); |
| 620 if (argument_count < frame_inspector.GetParametersCount()) { | 633 if (!it.is_wasm()) { |
| 621 argument_count = frame_inspector.GetParametersCount(); | 634 int scope_param_count = scope_info->ParameterCount(); |
| 635 if (scope_param_count > argument_count) argument_count = scope_param_count; | |
| 622 } | 636 } |
| 623 | 637 |
| 624 // Calculate the size of the result. | 638 // Calculate the size of the result. |
| 625 int details_size = kFrameDetailsFirstDynamicIndex + | 639 int details_size = kFrameDetailsFirstDynamicIndex + 2 * argument_count + |
| 626 2 * (argument_count + local_count) + (at_return ? 1 : 0); | 640 locals->length() + (at_return ? 1 : 0); |
| 627 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size); | 641 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size); |
| 628 | 642 |
| 629 // Add the frame id. | 643 // Add the frame id. |
| 630 details->set(kFrameDetailsFrameIdIndex, *frame_id); | 644 details->set(kFrameDetailsFrameIdIndex, *frame_id); |
| 631 | 645 |
| 632 // Add the function (same as in function frame). | 646 // Add the function (same as in function frame). |
| 633 details->set(kFrameDetailsFunctionIndex, *(frame_inspector.GetFunction())); | 647 if (it.is_wasm()) { |
| 648 Handle<Object> wasm_obj(it.wasm_frame()->wasm_obj(), isolate); | |
| 649 int func_index = it.wasm_frame()->function_index(); | |
| 650 Handle<String> func_name = | |
| 651 wasm::GetWasmFunctionName(isolate, wasm_obj, func_index); | |
| 652 details->set(kFrameDetailsFunctionIndex, *func_name); | |
| 653 } else { | |
| 654 details->set(kFrameDetailsFunctionIndex, *frame_inspector.GetFunction()); | |
| 655 } | |
| 656 | |
| 657 // Add the script wrapper | |
| 658 Handle<Object> script_wrapper = | |
| 659 Script::GetWrapper(frame_inspector.GetScript()); | |
| 660 details->set(kFrameDetailsScriptIndex, *script_wrapper); | |
| 634 | 661 |
| 635 // Add the arguments count. | 662 // Add the arguments count. |
| 636 details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count)); | 663 details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count)); |
| 637 | 664 |
| 638 // Add the locals count | 665 // Add the locals count |
| 639 details->set(kFrameDetailsLocalCountIndex, Smi::FromInt(local_count)); | 666 details->set(kFrameDetailsLocalCountIndex, |
| 667 Smi::FromInt(locals->length() / 2)); | |
| 640 | 668 |
| 641 // Add the source position. | 669 // Add the source position. |
| 642 if (position != RelocInfo::kNoPosition) { | 670 if (position != RelocInfo::kNoPosition) { |
| 643 details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position)); | 671 details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position)); |
| 644 } else { | 672 } else { |
| 645 details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value()); | 673 details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value()); |
| 646 } | 674 } |
| 647 | 675 |
| 648 // Add the constructor information. | 676 // Add the constructor information. |
| 649 details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor)); | 677 details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor)); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 662 if (is_optimized) { | 690 if (is_optimized) { |
| 663 flags |= 1 << 1; | 691 flags |= 1 << 1; |
| 664 flags |= inlined_jsframe_index << 2; | 692 flags |= inlined_jsframe_index << 2; |
| 665 } | 693 } |
| 666 details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags)); | 694 details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags)); |
| 667 | 695 |
| 668 // Fill the dynamic part. | 696 // Fill the dynamic part. |
| 669 int details_index = kFrameDetailsFirstDynamicIndex; | 697 int details_index = kFrameDetailsFirstDynamicIndex; |
| 670 | 698 |
| 671 // Add arguments name and value. | 699 // Add arguments name and value. |
| 672 for (int i = 0; i < argument_count; i++) { | 700 for (int i = 0; i < argument_count; i++, details_index += 2) { |
| 673 // Name of the argument. | 701 // Name of the argument. |
| 674 if (i < scope_info->ParameterCount()) { | 702 if (!scope_info.is_null() && i < scope_info->ParameterCount()) { |
| 675 details->set(details_index++, scope_info->ParameterName(i)); | 703 details->set(details_index, scope_info->ParameterName(i)); |
| 676 } else { | |
| 677 details->set(details_index++, heap->undefined_value()); | |
| 678 } | 704 } |
| 679 | 705 |
| 680 // Parameter value. | 706 // Parameter value. |
| 681 if (i < frame_inspector.GetParametersCount()) { | 707 if (i < frame_inspector.GetParametersCount()) { |
| 682 // Get the value from the stack. | 708 // Get the value from the stack. |
| 683 details->set(details_index++, *(frame_inspector.GetParameter(i))); | 709 details->set(details_index + 1, *frame_inspector.GetParameter(i)); |
| 684 } else { | |
| 685 details->set(details_index++, heap->undefined_value()); | |
| 686 } | 710 } |
| 687 } | 711 } |
| 688 | 712 |
| 689 // Add locals name and value from the temporary copy from the function frame. | 713 // Add locals name and value from the temporary copy from the function frame. |
| 690 for (int i = 0; i < local_count * 2; i++) { | 714 for (int i = 0, l = locals->length(); i < l; ++i) { |
| 691 details->set(details_index++, locals->get(i)); | 715 details->set(details_index++, locals->get(i)); |
| 692 } | 716 } |
| 693 | 717 |
| 694 // Add the value being returned. | 718 // Add the value being returned. |
| 695 if (at_return) { | 719 if (at_return) { |
| 696 details->set(details_index++, *return_value); | 720 details->set(details_index++, *return_value); |
| 697 } | 721 } |
| 698 | 722 |
| 699 // Add the receiver (same as in function frame). | 723 // Add the receiver (same as in function frame). |
| 700 Handle<Object> receiver(it.frame()->receiver(), isolate); | 724 Handle<Object> receiver(it.frame()->receiver(), isolate); |
| 701 DCHECK(!function->shared()->IsBuiltin()); | 725 DCHECK(it.is_wasm() || !frame_inspector.GetFunction()->shared()->IsBuiltin()); |
| 702 DCHECK_IMPLIES(is_sloppy(shared->language_mode()), receiver->IsJSReceiver()); | 726 DCHECK_IMPLIES( |
| 727 !it.is_wasm() && | |
| 728 is_sloppy(frame_inspector.GetFunction()->shared()->language_mode()), | |
| 729 receiver->IsJSReceiver()); | |
| 703 details->set(kFrameDetailsReceiverIndex, *receiver); | 730 details->set(kFrameDetailsReceiverIndex, *receiver); |
| 704 | 731 |
| 705 DCHECK_EQ(details_size, details_index); | 732 DCHECK_EQ(details_size, details_index); |
| 706 return *isolate->factory()->NewJSArrayWithElements(details); | 733 return *isolate->factory()->NewJSArrayWithElements(details); |
| 707 } | 734 } |
| 708 | 735 |
| 709 | 736 |
| 710 RUNTIME_FUNCTION(Runtime_GetScopeCount) { | 737 RUNTIME_FUNCTION(Runtime_GetScopeCount) { |
| 711 HandleScope scope(isolate); | 738 HandleScope scope(isolate); |
| 712 DCHECK(args.length() == 2); | 739 DCHECK(args.length() == 2); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 788 CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]); | 815 CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]); |
| 789 | 816 |
| 790 ScopeIterator::Option option = ScopeIterator::DEFAULT; | 817 ScopeIterator::Option option = ScopeIterator::DEFAULT; |
| 791 if (args.length() == 4) { | 818 if (args.length() == 4) { |
| 792 CONVERT_BOOLEAN_ARG_CHECKED(flag, 3); | 819 CONVERT_BOOLEAN_ARG_CHECKED(flag, 3); |
| 793 if (flag) option = ScopeIterator::IGNORE_NESTED_SCOPES; | 820 if (flag) option = ScopeIterator::IGNORE_NESTED_SCOPES; |
| 794 } | 821 } |
| 795 | 822 |
| 796 // Get the frame where the debugging is performed. | 823 // Get the frame where the debugging is performed. |
| 797 StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id); | 824 StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id); |
| 798 JavaScriptFrameIterator frame_it(isolate, id); | 825 StackTraceFrameIterator frame_it(isolate, id); |
| 799 JavaScriptFrame* frame = frame_it.frame(); | 826 StandardFrame* frame = frame_it.frame(); |
|
Yang
2016/06/24 05:56:37
We need to return an empty array if the frame is n
Clemens Hammacher
2016/06/24 09:23:31
This happens implicitely, as the ScopeIterator wil
Yang
2016/06/24 10:02:57
It will be empty because of the check in ScopeIter
Clemens Hammacher
2016/06/24 10:45:42
The check is in debug-scopes.cc:25:
if (!frame_ins
Yang
2016/06/24 10:52:25
I see. Can we at least add an assertion in ScopeIt
Clemens Hammacher
2016/06/24 15:11:58
Done.
| |
| 800 FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate); | 827 FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate); |
| 801 | 828 |
| 802 List<Handle<JSObject> > result(4); | 829 List<Handle<JSObject> > result(4); |
| 803 ScopeIterator it(isolate, &frame_inspector, option); | 830 ScopeIterator it(isolate, &frame_inspector, option); |
| 804 for (; !it.Done(); it.Next()) { | 831 for (; !it.Done(); it.Next()) { |
| 805 Handle<JSObject> details; | 832 Handle<JSObject> details; |
| 806 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, details, | 833 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, details, |
| 807 it.MaterializeScopeDetails()); | 834 it.MaterializeScopeDetails()); |
|
Yang
2016/06/24 05:56:37
I don't think we can correctly materialize any sco
Clemens Hammacher
2016/06/24 09:23:31
See above. This will generate an empty array.
| |
| 808 result.Add(details); | 835 result.Add(details); |
| 809 } | 836 } |
| 810 | 837 |
| 811 Handle<FixedArray> array = isolate->factory()->NewFixedArray(result.length()); | 838 Handle<FixedArray> array = isolate->factory()->NewFixedArray(result.length()); |
| 812 for (int i = 0; i < result.length(); ++i) { | 839 for (int i = 0; i < result.length(); ++i) { |
| 813 array->set(i, *result[i]); | 840 array->set(i, *result[i]); |
| 814 } | 841 } |
| 815 return *isolate->factory()->NewJSArrayWithElements(array); | 842 return *isolate->factory()->NewJSArrayWithElements(array); |
| 816 } | 843 } |
| 817 | 844 |
| (...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1548 | 1575 |
| 1549 static Handle<Object> GetJSPositionInfo(Handle<Script> script, int position, | 1576 static Handle<Object> GetJSPositionInfo(Handle<Script> script, int position, |
| 1550 Script::OffsetFlag offset_flag, | 1577 Script::OffsetFlag offset_flag, |
| 1551 Isolate* isolate) { | 1578 Isolate* isolate) { |
| 1552 Script::PositionInfo info; | 1579 Script::PositionInfo info; |
| 1553 if (!script->GetPositionInfo(position, &info, offset_flag)) { | 1580 if (!script->GetPositionInfo(position, &info, offset_flag)) { |
| 1554 return handle(isolate->heap()->null_value(), isolate); | 1581 return handle(isolate->heap()->null_value(), isolate); |
| 1555 } | 1582 } |
| 1556 | 1583 |
| 1557 Handle<String> source = handle(String::cast(script->source()), isolate); | 1584 Handle<String> source = handle(String::cast(script->source()), isolate); |
| 1558 Handle<String> sourceText = | 1585 Handle<String> sourceText = info.line_end > source->length() |
|
Yang
2016/06/24 05:56:37
can we do a script->is_wasm check instead?
Clemens Hammacher
2016/06/24 09:23:31
Done.
| |
| 1559 isolate->factory()->NewSubString(source, info.line_start, info.line_end); | 1586 ? isolate->factory()->empty_string() |
| 1587 : isolate->factory()->NewSubString( | |
| 1588 source, info.line_start, info.line_end); | |
| 1560 | 1589 |
| 1561 Handle<JSObject> jsinfo = | 1590 Handle<JSObject> jsinfo = |
| 1562 isolate->factory()->NewJSObject(isolate->object_function()); | 1591 isolate->factory()->NewJSObject(isolate->object_function()); |
| 1563 | 1592 |
| 1564 JSObject::AddProperty(jsinfo, isolate->factory()->script_string(), script, | 1593 JSObject::AddProperty(jsinfo, isolate->factory()->script_string(), script, |
| 1565 NONE); | 1594 NONE); |
| 1566 JSObject::AddProperty(jsinfo, isolate->factory()->position_string(), | 1595 JSObject::AddProperty(jsinfo, isolate->factory()->position_string(), |
| 1567 handle(Smi::FromInt(position), isolate), NONE); | 1596 handle(Smi::FromInt(position), isolate), NONE); |
| 1568 JSObject::AddProperty(jsinfo, isolate->factory()->line_string(), | 1597 JSObject::AddProperty(jsinfo, isolate->factory()->line_string(), |
| 1569 handle(Smi::FromInt(info.line), isolate), NONE); | 1598 handle(Smi::FromInt(info.line), isolate), NONE); |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1752 return Smi::FromInt(isolate->debug()->is_active()); | 1781 return Smi::FromInt(isolate->debug()->is_active()); |
| 1753 } | 1782 } |
| 1754 | 1783 |
| 1755 | 1784 |
| 1756 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { | 1785 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { |
| 1757 UNIMPLEMENTED(); | 1786 UNIMPLEMENTED(); |
| 1758 return NULL; | 1787 return NULL; |
| 1759 } | 1788 } |
| 1760 } // namespace internal | 1789 } // namespace internal |
| 1761 } // namespace v8 | 1790 } // namespace v8 |
| OLD | NEW |