OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
410 FunctionLiteral* lit = MakeAST(is_global, script, extension, pre_data); | 410 FunctionLiteral* lit = MakeAST(is_global, script, extension, pre_data); |
411 | 411 |
412 // Check for parse errors. | 412 // Check for parse errors. |
413 if (lit == NULL) { | 413 if (lit == NULL) { |
414 ASSERT(Top::has_pending_exception()); | 414 ASSERT(Top::has_pending_exception()); |
415 return; | 415 return; |
416 } | 416 } |
417 | 417 |
418 // Compile the code. | 418 // Compile the code. |
419 CompilationInfo info(lit, script, is_eval); | 419 CompilationInfo info(lit, script, is_eval); |
| 420 |
| 421 LiveEditFunctionTracker tracker(lit); |
420 Handle<Code> code = MakeCodeForLiveEdit(&info); | 422 Handle<Code> code = MakeCodeForLiveEdit(&info); |
421 | 423 |
422 // Check for stack-overflow exceptions. | 424 // Check for stack-overflow exceptions. |
423 if (code.is_null()) { | 425 if (code.is_null()) { |
424 Top::StackOverflow(); | 426 Top::StackOverflow(); |
425 return; | 427 return; |
426 } | 428 } |
| 429 tracker.RecordRootFunctionInfo(code); |
427 } | 430 } |
428 | 431 |
429 // Unwraps JSValue object, returning its field "value" | 432 // Unwraps JSValue object, returning its field "value" |
430 static Handle<Object> UnwrapJSValue(Handle<JSValue> jsValue) { | 433 static Handle<Object> UnwrapJSValue(Handle<JSValue> jsValue) { |
431 return Handle<Object>(jsValue->value()); | 434 return Handle<Object>(jsValue->value()); |
432 } | 435 } |
433 | 436 |
434 // Wraps any object into a OpaqueReference, that will hide the object | 437 // Wraps any object into a OpaqueReference, that will hide the object |
435 // from JavaScript. | 438 // from JavaScript. |
436 static Handle<JSValue> WrapInJSValue(Object* object) { | 439 static Handle<JSValue> WrapInJSValue(Object* object) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 this->SetField(kFunctionNameOffset_, name); | 497 this->SetField(kFunctionNameOffset_, name); |
495 this->SetSmiValueField(kStartPositionOffset_, start_position); | 498 this->SetSmiValueField(kStartPositionOffset_, start_position); |
496 this->SetSmiValueField(kEndPositionOffset_, end_position); | 499 this->SetSmiValueField(kEndPositionOffset_, end_position); |
497 this->SetSmiValueField(kParamNumOffset_, param_num); | 500 this->SetSmiValueField(kParamNumOffset_, param_num); |
498 this->SetSmiValueField(kParentIndexOffset_, parent_index); | 501 this->SetSmiValueField(kParentIndexOffset_, parent_index); |
499 } | 502 } |
500 void SetFunctionCode(Handle<Code> function_code) { | 503 void SetFunctionCode(Handle<Code> function_code) { |
501 Handle<JSValue> wrapper = WrapInJSValue(*function_code); | 504 Handle<JSValue> wrapper = WrapInJSValue(*function_code); |
502 this->SetField(kCodeOffset_, wrapper); | 505 this->SetField(kCodeOffset_, wrapper); |
503 } | 506 } |
504 void SetScopeInfo(Handle<JSArray> scope_info_array) { | 507 void SetScopeInfo(Handle<Object> scope_info_array) { |
505 this->SetField(kScopeInfoOffset_, scope_info_array); | 508 this->SetField(kScopeInfoOffset_, scope_info_array); |
506 } | 509 } |
| 510 void SetSharedFunctionInfo(Handle<SharedFunctionInfo> info) { |
| 511 Handle<JSValue> info_holder = WrapInJSValue(*info); |
| 512 this->SetField(kSharedFunctionInfoOffset_, info_holder); |
| 513 } |
507 int GetParentIndex() { | 514 int GetParentIndex() { |
508 return this->GetSmiValueField(kParentIndexOffset_); | 515 return this->GetSmiValueField(kParentIndexOffset_); |
509 } | 516 } |
510 Handle<Code> GetFunctionCode() { | 517 Handle<Code> GetFunctionCode() { |
511 Handle<Object> raw_result = UnwrapJSValue(Handle<JSValue>( | 518 Handle<Object> raw_result = UnwrapJSValue(Handle<JSValue>( |
512 JSValue::cast(this->GetField(kCodeOffset_)))); | 519 JSValue::cast(this->GetField(kCodeOffset_)))); |
513 return Handle<Code>::cast(raw_result); | 520 return Handle<Code>::cast(raw_result); |
514 } | 521 } |
515 int GetStartPosition() { | 522 int GetStartPosition() { |
516 return this->GetSmiValueField(kStartPositionOffset_); | 523 return this->GetSmiValueField(kStartPositionOffset_); |
517 } | 524 } |
518 int GetEndPosition() { | 525 int GetEndPosition() { |
519 return this->GetSmiValueField(kEndPositionOffset_); | 526 return this->GetSmiValueField(kEndPositionOffset_); |
520 } | 527 } |
521 | 528 |
522 private: | 529 private: |
523 static const int kFunctionNameOffset_ = 0; | 530 static const int kFunctionNameOffset_ = 0; |
524 static const int kStartPositionOffset_ = 1; | 531 static const int kStartPositionOffset_ = 1; |
525 static const int kEndPositionOffset_ = 2; | 532 static const int kEndPositionOffset_ = 2; |
526 static const int kParamNumOffset_ = 3; | 533 static const int kParamNumOffset_ = 3; |
527 static const int kCodeOffset_ = 4; | 534 static const int kCodeOffset_ = 4; |
528 static const int kScopeInfoOffset_ = 5; | 535 static const int kScopeInfoOffset_ = 5; |
529 static const int kParentIndexOffset_ = 6; | 536 static const int kParentIndexOffset_ = 6; |
530 static const int kSize_ = 7; | 537 static const int kSharedFunctionInfoOffset_ = 7; |
| 538 static const int kSize_ = 8; |
531 | 539 |
532 friend class JSArrayBasedStruct<FunctionInfoWrapper>; | 540 friend class JSArrayBasedStruct<FunctionInfoWrapper>; |
533 }; | 541 }; |
534 | 542 |
535 // Wraps SharedFunctionInfo along with some of its fields for passing it | 543 // Wraps SharedFunctionInfo along with some of its fields for passing it |
536 // back to JavaScript. SharedFunctionInfo object itself is additionally | 544 // back to JavaScript. SharedFunctionInfo object itself is additionally |
537 // wrapped into BlindReference for sanitizing reasons. | 545 // wrapped into BlindReference for sanitizing reasons. |
538 class SharedInfoWrapper : public JSArrayBasedStruct<SharedInfoWrapper> { | 546 class SharedInfoWrapper : public JSArrayBasedStruct<SharedInfoWrapper> { |
539 public: | 547 public: |
540 explicit SharedInfoWrapper(Handle<JSArray> array) | 548 explicit SharedInfoWrapper(Handle<JSArray> array) |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
586 len_++; | 594 len_++; |
587 } | 595 } |
588 | 596 |
589 void FunctionDone() { | 597 void FunctionDone() { |
590 HandleScope scope; | 598 HandleScope scope; |
591 FunctionInfoWrapper info = | 599 FunctionInfoWrapper info = |
592 FunctionInfoWrapper::cast(result_->GetElement(current_parent_index_)); | 600 FunctionInfoWrapper::cast(result_->GetElement(current_parent_index_)); |
593 current_parent_index_ = info.GetParentIndex(); | 601 current_parent_index_ = info.GetParentIndex(); |
594 } | 602 } |
595 | 603 |
596 void FunctionScope(Scope* scope) { | 604 // TODO(LiveEdit): Move private method below. |
| 605 // This private section was created here to avoid moving the function |
| 606 // to keep already complex diff simpler. |
| 607 private: |
| 608 Object* SerializeFunctionScope(Scope* scope) { |
597 HandleScope handle_scope; | 609 HandleScope handle_scope; |
598 | 610 |
599 Handle<JSArray> scope_info_list = Factory::NewJSArray(10); | 611 Handle<JSArray> scope_info_list = Factory::NewJSArray(10); |
600 int scope_info_length = 0; | 612 int scope_info_length = 0; |
601 | 613 |
602 // Saves some description of scope. It stores name and indexes of | 614 // Saves some description of scope. It stores name and indexes of |
603 // variables in the whole scope chain. Null-named slots delimit | 615 // variables in the whole scope chain. Null-named slots delimit |
604 // scopes of this chain. | 616 // scopes of this chain. |
605 Scope* outer_scope = scope->outer_scope(); | 617 Scope* outer_scope = scope->outer_scope(); |
606 if (outer_scope == NULL) { | 618 if (outer_scope == NULL) { |
607 return; | 619 return Heap::undefined_value(); |
608 } | 620 } |
609 do { | 621 do { |
610 ZoneList<Variable*> list(10); | 622 ZoneList<Variable*> list(10); |
611 outer_scope->CollectUsedVariables(&list); | 623 outer_scope->CollectUsedVariables(&list); |
612 int j = 0; | 624 int j = 0; |
613 for (int i = 0; i < list.length(); i++) { | 625 for (int i = 0; i < list.length(); i++) { |
614 Variable* var1 = list[i]; | 626 Variable* var1 = list[i]; |
615 Slot* slot = var1->slot(); | 627 Slot* slot = var1->slot(); |
616 if (slot != NULL && slot->type() == Slot::CONTEXT) { | 628 if (slot != NULL && slot->type() == Slot::CONTEXT) { |
617 if (j != i) { | 629 if (j != i) { |
(...skipping 20 matching lines...) Expand all Loading... |
638 Handle<Smi>(Smi::FromInt(list[i]->slot()->index()))); | 650 Handle<Smi>(Smi::FromInt(list[i]->slot()->index()))); |
639 scope_info_length++; | 651 scope_info_length++; |
640 } | 652 } |
641 SetElement(scope_info_list, scope_info_length, | 653 SetElement(scope_info_list, scope_info_length, |
642 Handle<Object>(Heap::null_value())); | 654 Handle<Object>(Heap::null_value())); |
643 scope_info_length++; | 655 scope_info_length++; |
644 | 656 |
645 outer_scope = outer_scope->outer_scope(); | 657 outer_scope = outer_scope->outer_scope(); |
646 } while (outer_scope != NULL); | 658 } while (outer_scope != NULL); |
647 | 659 |
648 FunctionInfoWrapper info = | 660 return *scope_info_list; |
649 FunctionInfoWrapper::cast(result_->GetElement(current_parent_index_)); | |
650 info.SetScopeInfo(scope_info_list); | |
651 } | 661 } |
652 | 662 |
| 663 public: |
| 664 // Saves only function code, because for a script function we |
| 665 // may never create a SharedFunctionInfo object. |
653 void FunctionCode(Handle<Code> function_code) { | 666 void FunctionCode(Handle<Code> function_code) { |
654 FunctionInfoWrapper info = | 667 FunctionInfoWrapper info = |
655 FunctionInfoWrapper::cast(result_->GetElement(current_parent_index_)); | 668 FunctionInfoWrapper::cast(result_->GetElement(current_parent_index_)); |
656 info.SetFunctionCode(function_code); | 669 info.SetFunctionCode(function_code); |
657 } | 670 } |
658 | 671 |
| 672 // Saves full information about a function: its code, its scope info |
| 673 // and a SharedFunctionInfo object. |
| 674 void FunctionInfo(Handle<SharedFunctionInfo> shared, Scope* scope) { |
| 675 if (!shared->IsSharedFunctionInfo()) { |
| 676 return; |
| 677 } |
| 678 FunctionInfoWrapper info = |
| 679 FunctionInfoWrapper::cast(result_->GetElement(current_parent_index_)); |
| 680 info.SetFunctionCode(Handle<Code>(shared->code())); |
| 681 info.SetSharedFunctionInfo(shared); |
| 682 |
| 683 Handle<Object> scope_info_list(SerializeFunctionScope(scope)); |
| 684 info.SetScopeInfo(scope_info_list); |
| 685 } |
| 686 |
659 Handle<JSArray> GetResult() { | 687 Handle<JSArray> GetResult() { |
660 return result_; | 688 return result_; |
661 } | 689 } |
662 | 690 |
663 private: | 691 private: |
664 Handle<JSArray> result_; | 692 Handle<JSArray> result_; |
665 int len_; | 693 int len_; |
666 int current_parent_index_; | 694 int current_parent_index_; |
667 }; | 695 }; |
668 | 696 |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
808 | 836 |
809 void LiveEdit::ReplaceFunctionCode(Handle<JSArray> new_compile_info_array, | 837 void LiveEdit::ReplaceFunctionCode(Handle<JSArray> new_compile_info_array, |
810 Handle<JSArray> shared_info_array) { | 838 Handle<JSArray> shared_info_array) { |
811 HandleScope scope; | 839 HandleScope scope; |
812 | 840 |
813 FunctionInfoWrapper compile_info_wrapper(new_compile_info_array); | 841 FunctionInfoWrapper compile_info_wrapper(new_compile_info_array); |
814 SharedInfoWrapper shared_info_wrapper(shared_info_array); | 842 SharedInfoWrapper shared_info_wrapper(shared_info_array); |
815 | 843 |
816 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo(); | 844 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo(); |
817 | 845 |
818 | |
819 if (IsJSFunctionCode(shared_info->code())) { | 846 if (IsJSFunctionCode(shared_info->code())) { |
820 ReplaceCodeObject(shared_info->code(), | 847 ReplaceCodeObject(shared_info->code(), |
821 *(compile_info_wrapper.GetFunctionCode())); | 848 *(compile_info_wrapper.GetFunctionCode())); |
822 } | 849 } |
823 | 850 |
824 if (shared_info->debug_info()->IsDebugInfo()) { | 851 if (shared_info->debug_info()->IsDebugInfo()) { |
825 Handle<DebugInfo> debug_info(DebugInfo::cast(shared_info->debug_info())); | 852 Handle<DebugInfo> debug_info(DebugInfo::cast(shared_info->debug_info())); |
826 Handle<Code> new_original_code = | 853 Handle<Code> new_original_code = |
827 Factory::CopyCode(compile_info_wrapper.GetFunctionCode()); | 854 Factory::CopyCode(compile_info_wrapper.GetFunctionCode()); |
828 debug_info->set_original_code(*new_original_code); | 855 debug_info->set_original_code(*new_original_code); |
829 } | 856 } |
830 | 857 |
831 shared_info->set_start_position(compile_info_wrapper.GetStartPosition()); | 858 shared_info->set_start_position(compile_info_wrapper.GetStartPosition()); |
832 shared_info->set_end_position(compile_info_wrapper.GetEndPosition()); | 859 shared_info->set_end_position(compile_info_wrapper.GetEndPosition()); |
833 | 860 |
834 shared_info->set_construct_stub( | 861 shared_info->set_construct_stub( |
835 Builtins::builtin(Builtins::JSConstructStubGeneric)); | 862 Builtins::builtin(Builtins::JSConstructStubGeneric)); |
836 // update breakpoints | 863 // update breakpoints |
837 } | 864 } |
838 | 865 |
839 | 866 |
840 // TODO(635): Eval caches its scripts (same text -- same compiled info). | 867 // TODO(635): Eval caches its scripts (same text -- same compiled info). |
841 // Make sure we clear such caches. | 868 // Make sure we clear such caches. |
842 void LiveEdit::RelinkFunctionToScript(Handle<JSArray> shared_info_array, | 869 void LiveEdit::SetFunctionScript(Handle<JSValue> function_wrapper, |
843 Handle<Script> script_handle) { | 870 Handle<Object> script_handle) { |
844 SharedInfoWrapper shared_info_wrapper(shared_info_array); | 871 Handle<SharedFunctionInfo> shared_info = |
845 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo(); | 872 Handle<SharedFunctionInfo>::cast(UnwrapJSValue(function_wrapper)); |
846 | |
847 shared_info->set_script(*script_handle); | 873 shared_info->set_script(*script_handle); |
848 } | 874 } |
849 | 875 |
850 | 876 |
851 // For a script text change (defined as position_change_array), translates | 877 // For a script text change (defined as position_change_array), translates |
852 // position in unchanged text to position in changed text. | 878 // position in unchanged text to position in changed text. |
853 // Text change is a set of non-overlapping regions in text, that have changed | 879 // Text change is a set of non-overlapping regions in text, that have changed |
854 // their contents and length. It is specified as array of groups of 3 numbers: | 880 // their contents and length. It is specified as array of groups of 3 numbers: |
855 // (change_begin, change_end, change_end_new_position). | 881 // (change_begin, change_end, change_end_new_position). |
856 // Each group describes a change in text; groups are sorted by change_begin. | 882 // Each group describes a change in text; groups are sorted by change_begin. |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
991 } else { | 1017 } else { |
992 // Relocation info section now has different size. We cannot simply | 1018 // Relocation info section now has different size. We cannot simply |
993 // rewrite it inside code object. Instead we have to create a new | 1019 // rewrite it inside code object. Instead we have to create a new |
994 // code object. | 1020 // code object. |
995 Handle<Code> result(Factory::CopyCode(code, buffer)); | 1021 Handle<Code> result(Factory::CopyCode(code, buffer)); |
996 return result; | 1022 return result; |
997 } | 1023 } |
998 } | 1024 } |
999 | 1025 |
1000 | 1026 |
1001 static Handle<Object> GetBreakPointObjectsForJS( | 1027 void LiveEdit::PatchFunctionPositions( |
1002 Handle<BreakPointInfo> break_point_info) { | |
1003 if (break_point_info->break_point_objects()->IsFixedArray()) { | |
1004 Handle<FixedArray> fixed_array( | |
1005 FixedArray::cast(break_point_info->break_point_objects())); | |
1006 Handle<Object> array = Factory::NewJSArrayWithElements(fixed_array); | |
1007 return array; | |
1008 } else { | |
1009 return Handle<Object>(break_point_info->break_point_objects()); | |
1010 } | |
1011 } | |
1012 | |
1013 | |
1014 Handle<JSArray> LiveEdit::PatchFunctionPositions( | |
1015 Handle<JSArray> shared_info_array, Handle<JSArray> position_change_array) { | 1028 Handle<JSArray> shared_info_array, Handle<JSArray> position_change_array) { |
1016 SharedInfoWrapper shared_info_wrapper(shared_info_array); | 1029 SharedInfoWrapper shared_info_wrapper(shared_info_array); |
1017 Handle<SharedFunctionInfo> info = shared_info_wrapper.GetInfo(); | 1030 Handle<SharedFunctionInfo> info = shared_info_wrapper.GetInfo(); |
1018 | 1031 |
1019 int old_function_start = info->start_position(); | 1032 int old_function_start = info->start_position(); |
1020 int new_function_start = TranslatePosition(old_function_start, | 1033 int new_function_start = TranslatePosition(old_function_start, |
1021 position_change_array); | 1034 position_change_array); |
1022 info->set_start_position(new_function_start); | 1035 info->set_start_position(new_function_start); |
1023 info->set_end_position(TranslatePosition(info->end_position(), | 1036 info->set_end_position(TranslatePosition(info->end_position(), |
1024 position_change_array)); | 1037 position_change_array)); |
1025 | 1038 |
1026 info->set_function_token_position( | 1039 info->set_function_token_position( |
1027 TranslatePosition(info->function_token_position(), | 1040 TranslatePosition(info->function_token_position(), |
1028 position_change_array)); | 1041 position_change_array)); |
1029 | 1042 |
1030 if (IsJSFunctionCode(info->code())) { | 1043 if (IsJSFunctionCode(info->code())) { |
1031 // Patch relocation info section of the code. | 1044 // Patch relocation info section of the code. |
1032 Handle<Code> patched_code = PatchPositionsInCode(Handle<Code>(info->code()), | 1045 Handle<Code> patched_code = PatchPositionsInCode(Handle<Code>(info->code()), |
1033 position_change_array); | 1046 position_change_array); |
1034 if (*patched_code != info->code()) { | 1047 if (*patched_code != info->code()) { |
1035 // Replace all references to the code across the heap. In particular, | 1048 // Replace all references to the code across the heap. In particular, |
1036 // some stubs may refer to this code and this code may be being executed | 1049 // some stubs may refer to this code and this code may be being executed |
1037 // on stack (it is safe to substitute the code object on stack, because | 1050 // on stack (it is safe to substitute the code object on stack, because |
1038 // we only change the structure of rinfo and leave instructions | 1051 // we only change the structure of rinfo and leave instructions |
1039 // untouched). | 1052 // untouched). |
1040 ReplaceCodeObject(info->code(), *patched_code); | 1053 ReplaceCodeObject(info->code(), *patched_code); |
1041 } | 1054 } |
1042 } | 1055 } |
| 1056 } |
1043 | 1057 |
1044 | 1058 |
1045 Handle<JSArray> result = Factory::NewJSArray(0); | 1059 static Handle<Script> CreateScriptCopy(Handle<Script> original) { |
1046 int result_len = 0; | 1060 Handle<String> original_source(String::cast(original->source())); |
1047 | 1061 |
1048 if (info->debug_info()->IsDebugInfo()) { | 1062 Handle<Script> copy = Factory::NewScript(original_source); |
1049 Handle<DebugInfo> debug_info(DebugInfo::cast(info->debug_info())); | |
1050 Handle<Code> patched_orig_code = | |
1051 PatchPositionsInCode(Handle<Code>(debug_info->original_code()), | |
1052 position_change_array); | |
1053 if (*patched_orig_code != debug_info->original_code()) { | |
1054 // Do not use expensive ReplaceCodeObject for original_code, because we | |
1055 // do not expect any other references except this one. | |
1056 debug_info->set_original_code(*patched_orig_code); | |
1057 } | |
1058 | 1063 |
1059 Handle<FixedArray> break_point_infos(debug_info->break_points()); | 1064 copy->set_name(original->name()); |
1060 for (int i = 0; i < break_point_infos->length(); i++) { | 1065 copy->set_line_offset(original->line_offset()); |
1061 if (!break_point_infos->get(i)->IsBreakPointInfo()) { | 1066 copy->set_column_offset(original->column_offset()); |
1062 continue; | 1067 copy->set_data(original->data()); |
1063 } | 1068 copy->set_type(original->type()); |
1064 Handle<BreakPointInfo> info( | 1069 copy->set_context_data(original->context_data()); |
1065 BreakPointInfo::cast(break_point_infos->get(i))); | 1070 copy->set_compilation_type(original->compilation_type()); |
1066 int old_in_script_position = info->source_position()->value() + | 1071 copy->set_eval_from_shared(original->eval_from_shared()); |
1067 old_function_start; | 1072 copy->set_eval_from_instructions_offset( |
1068 int new_in_script_position = TranslatePosition(old_in_script_position, | 1073 original->eval_from_instructions_offset()); |
1069 position_change_array); | 1074 |
1070 info->set_source_position( | 1075 return copy; |
1071 Smi::FromInt(new_in_script_position - new_function_start)); | 1076 } |
1072 if (old_in_script_position != new_in_script_position) { | 1077 |
1073 SetElement(result, result_len, | 1078 |
1074 Handle<Smi>(Smi::FromInt(new_in_script_position))); | 1079 Object* LiveEdit::ChangeScriptSource(Handle<Script> original_script, |
1075 SetElement(result, result_len + 1, | 1080 Handle<String> new_source, |
1076 GetBreakPointObjectsForJS(info)); | 1081 Handle<Object> old_script_name) { |
1077 result_len += 2; | 1082 Handle<Object> old_script_object; |
| 1083 if (old_script_name->IsString()) { |
| 1084 Handle<Script> old_script = CreateScriptCopy(original_script); |
| 1085 old_script->set_name(String::cast(*old_script_name)); |
| 1086 old_script_object = old_script; |
| 1087 Debugger::OnAfterCompile(old_script, Debugger::SEND_WHEN_DEBUGGING); |
| 1088 } else { |
| 1089 old_script_object = Handle<Object>(Heap::null_value()); |
| 1090 } |
| 1091 |
| 1092 original_script->set_source(*new_source); |
| 1093 |
| 1094 // Drop line ends so that they will be recalculated. |
| 1095 original_script->set_line_ends(Heap::undefined_value()); |
| 1096 |
| 1097 return *old_script_object; |
| 1098 } |
| 1099 |
| 1100 |
| 1101 |
| 1102 void LiveEdit::ReplaceRefToNestedFunction( |
| 1103 Handle<JSValue> parent_function_wrapper, |
| 1104 Handle<JSValue> orig_function_wrapper, |
| 1105 Handle<JSValue> subst_function_wrapper) { |
| 1106 |
| 1107 Handle<SharedFunctionInfo> parent_shared = |
| 1108 Handle<SharedFunctionInfo>::cast(UnwrapJSValue(parent_function_wrapper)); |
| 1109 Handle<SharedFunctionInfo> orig_shared = |
| 1110 Handle<SharedFunctionInfo>::cast(UnwrapJSValue(orig_function_wrapper)); |
| 1111 Handle<SharedFunctionInfo> subst_shared = |
| 1112 Handle<SharedFunctionInfo>::cast(UnwrapJSValue(subst_function_wrapper)); |
| 1113 |
| 1114 for (RelocIterator it(parent_shared->code()); !it.done(); it.next()) { |
| 1115 if (it.rinfo()->rmode() == RelocInfo::EMBEDDED_OBJECT) { |
| 1116 if (it.rinfo()->target_object() == *orig_shared) { |
| 1117 it.rinfo()->set_target_object(*subst_shared); |
1078 } | 1118 } |
1079 } | 1119 } |
1080 } | 1120 } |
1081 return result; | |
1082 } | 1121 } |
1083 | 1122 |
1084 | 1123 |
1085 // Check an activation against list of functions. If there is a function | 1124 // Check an activation against list of functions. If there is a function |
1086 // that matches, its status in result array is changed to status argument value. | 1125 // that matches, its status in result array is changed to status argument value. |
1087 static bool CheckActivation(Handle<JSArray> shared_info_array, | 1126 static bool CheckActivation(Handle<JSArray> shared_info_array, |
1088 Handle<JSArray> result, StackFrame* frame, | 1127 Handle<JSArray> result, StackFrame* frame, |
1089 LiveEdit::FunctionPatchabilityStatus status) { | 1128 LiveEdit::FunctionPatchabilityStatus status) { |
1090 if (!frame->is_java_script()) { | 1129 if (!frame->is_java_script()) { |
1091 return false; | 1130 return false; |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1355 } | 1394 } |
1356 | 1395 |
1357 | 1396 |
1358 LiveEditFunctionTracker::~LiveEditFunctionTracker() { | 1397 LiveEditFunctionTracker::~LiveEditFunctionTracker() { |
1359 if (active_function_info_listener != NULL) { | 1398 if (active_function_info_listener != NULL) { |
1360 active_function_info_listener->FunctionDone(); | 1399 active_function_info_listener->FunctionDone(); |
1361 } | 1400 } |
1362 } | 1401 } |
1363 | 1402 |
1364 | 1403 |
1365 void LiveEditFunctionTracker::RecordFunctionCode(Handle<Code> code) { | 1404 void LiveEditFunctionTracker::RecordFunctionInfo( |
| 1405 Handle<SharedFunctionInfo> info, FunctionLiteral* lit) { |
1366 if (active_function_info_listener != NULL) { | 1406 if (active_function_info_listener != NULL) { |
1367 active_function_info_listener->FunctionCode(code); | 1407 active_function_info_listener->FunctionInfo(info, lit->scope()); |
1368 } | 1408 } |
1369 } | 1409 } |
1370 | 1410 |
1371 | 1411 |
1372 void LiveEditFunctionTracker::RecordFunctionScope(Scope* scope) { | 1412 void LiveEditFunctionTracker::RecordRootFunctionInfo(Handle<Code> code) { |
1373 if (active_function_info_listener != NULL) { | 1413 active_function_info_listener->FunctionCode(code); |
1374 active_function_info_listener->FunctionScope(scope); | |
1375 } | |
1376 } | 1414 } |
1377 | 1415 |
1378 | 1416 |
1379 bool LiveEditFunctionTracker::IsActive() { | 1417 bool LiveEditFunctionTracker::IsActive() { |
1380 return active_function_info_listener != NULL; | 1418 return active_function_info_listener != NULL; |
1381 } | 1419 } |
1382 | 1420 |
1383 | 1421 |
1384 #else // ENABLE_DEBUGGER_SUPPORT | 1422 #else // ENABLE_DEBUGGER_SUPPORT |
1385 | 1423 |
1386 // This ifdef-else-endif section provides working or stub implementation of | 1424 // This ifdef-else-endif section provides working or stub implementation of |
1387 // LiveEditFunctionTracker. | 1425 // LiveEditFunctionTracker. |
1388 LiveEditFunctionTracker::LiveEditFunctionTracker(FunctionLiteral* fun) { | 1426 LiveEditFunctionTracker::LiveEditFunctionTracker(FunctionLiteral* fun) { |
1389 } | 1427 } |
1390 | 1428 |
1391 | 1429 |
1392 LiveEditFunctionTracker::~LiveEditFunctionTracker() { | 1430 LiveEditFunctionTracker::~LiveEditFunctionTracker() { |
1393 } | 1431 } |
1394 | 1432 |
1395 | 1433 |
1396 void LiveEditFunctionTracker::RecordFunctionCode(Handle<Code> code) { | 1434 void LiveEditFunctionTracker::RecordFunctionInfo( |
| 1435 Handle<SharedFunctionInfo> info, FunctionLiteral* lit) { |
1397 } | 1436 } |
1398 | 1437 |
1399 | 1438 |
1400 void LiveEditFunctionTracker::RecordFunctionScope(Scope* scope) { | 1439 void LiveEditFunctionTracker::RecordRootFunctionInfo(Handle<Code> code) { |
1401 } | 1440 } |
1402 | 1441 |
1403 | 1442 |
1404 bool LiveEditFunctionTracker::IsActive() { | 1443 bool LiveEditFunctionTracker::IsActive() { |
1405 return false; | 1444 return false; |
1406 } | 1445 } |
1407 | 1446 |
1408 #endif // ENABLE_DEBUGGER_SUPPORT | 1447 #endif // ENABLE_DEBUGGER_SUPPORT |
1409 | 1448 |
1410 | 1449 |
1411 | 1450 |
1412 } } // namespace v8::internal | 1451 } } // namespace v8::internal |
OLD | NEW |