| 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 |