OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
214 } | 214 } |
215 | 215 |
216 for (var i = 0; i < replace_code_list.length; i++) { | 216 for (var i = 0; i < replace_code_list.length; i++) { |
217 PatchFunctionCode(replace_code_list[i], change_log); | 217 PatchFunctionCode(replace_code_list[i], change_log); |
218 } | 218 } |
219 | 219 |
220 var position_patch_report = new Array(); | 220 var position_patch_report = new Array(); |
221 change_log.push( {position_patched: position_patch_report} ); | 221 change_log.push( {position_patched: position_patch_report} ); |
222 | 222 |
223 for (var i = 0; i < update_positions_list.length; i++) { | 223 for (var i = 0; i < update_positions_list.length; i++) { |
224 // TODO(LiveEdit): take into account wether it's source_changed or | 224 // TODO(LiveEdit): take into account wether it's source_changed or |
aandrey
2013/09/20 12:35:21
wether -> whether
Peter.Rybin
2013/09/20 13:16:51
Done.
| |
225 // unchanged and whether positions changed at all. | 225 // unchanged and whether positions changed at all. |
226 PatchPositions(update_positions_list[i], diff_array, | 226 PatchPositions(update_positions_list[i], diff_array, |
227 position_patch_report); | 227 position_patch_report); |
228 | 228 |
229 if (update_positions_list[i].live_shared_function_infos) { | 229 if (update_positions_list[i].live_shared_function_infos) { |
230 update_positions_list[i].live_shared_function_infos. | 230 update_positions_list[i].live_shared_function_infos. |
231 forEach(function (info) { | 231 forEach(function (info) { |
232 %LiveEditFunctionSourceUpdated(info.raw_array); | 232 %LiveEditFunctionSourceUpdated(info.raw_array); |
233 }); | 233 }); |
234 } | 234 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
281 if (k != i) { | 281 if (k != i) { |
282 var temp_info = compile_info[k]; | 282 var temp_info = compile_info[k]; |
283 var temp_index = old_index_map[k]; | 283 var temp_index = old_index_map[k]; |
284 compile_info[k] = compile_info[i]; | 284 compile_info[k] = compile_info[i]; |
285 old_index_map[k] = old_index_map[i]; | 285 old_index_map[k] = old_index_map[i]; |
286 compile_info[i] = temp_info; | 286 compile_info[i] = temp_info; |
287 old_index_map[i] = temp_index; | 287 old_index_map[i] = temp_index; |
288 } | 288 } |
289 } | 289 } |
290 | 290 |
291 // After sorting update outer_inder field using old_index_map. Also | 291 // After sorting update outer_inder field using old_index_map. Also |
aandrey
2013/09/20 12:35:21
outer_inder -> outer_index
Peter.Rybin
2013/09/20 13:16:51
Done.
| |
292 // set next_sibling_index field. | 292 // set next_sibling_index field. |
293 var current_index = 0; | 293 var current_index = 0; |
294 | 294 |
295 // The recursive function, that goes over all children of a particular | 295 // The recursive function, that goes over all children of a particular |
296 // node (i.e. function info). | 296 // node (i.e. function info). |
297 function ResetIndexes(new_parent_index, old_parent_index) { | 297 function ResetIndexes(new_parent_index, old_parent_index) { |
298 var previous_sibling = -1; | 298 var previous_sibling = -1; |
299 while (current_index < compile_info.length && | 299 while (current_index < compile_info.length && |
300 compile_info[current_index].outer_index == old_parent_index) { | 300 compile_info[current_index].outer_index == old_parent_index) { |
301 var saved_index = current_index; | 301 var saved_index = current_index; |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
685 } | 685 } |
686 | 686 |
687 function ProcessUnchangedChild(node) { | 687 function ProcessUnchangedChild(node) { |
688 node.new_start_pos = chunk_it.TranslatePos(node.info.start_position); | 688 node.new_start_pos = chunk_it.TranslatePos(node.info.start_position); |
689 node.new_end_pos = chunk_it.TranslatePos(node.info.end_position); | 689 node.new_end_pos = chunk_it.TranslatePos(node.info.end_position); |
690 } | 690 } |
691 | 691 |
692 ProcessInternals(code_info_tree); | 692 ProcessInternals(code_info_tree); |
693 } | 693 } |
694 | 694 |
695 // For ecah old function (if it is not damaged) tries to find a corresponding | 695 // For ecah old function (if it is not damaged) tries to find a corresponding |
Yang
2013/09/20 12:17:34
For each
Peter.Rybin
2013/09/20 13:16:51
Done.
| |
696 // function in new script. Typically it should succeed (non-damaged functions | 696 // function in new script. Typically it should succeed (non-damaged functions |
697 // by definition may only have changes inside their bodies). However there are | 697 // by definition may only have changes inside their bodies). However there are |
698 // reasons for corresponence not to be found; function with unmodified text | 698 // reasons for corresponence not to be found; function with unmodified text |
Yang
2013/09/20 12:17:34
correspondence
Peter.Rybin
2013/09/20 13:16:51
Done.
| |
699 // in new script may become enclosed into other function; the innocent change | 699 // in new script may become enclosed into other function; the innocent change |
700 // inside function body may in fact be something like "} function B() {" that | 700 // inside function body may in fact be something like "} function B() {" that |
701 // splits a function into 2 functions. | 701 // splits a function into 2 functions. |
702 function FindCorrespondingFunctions(old_code_tree, new_code_tree) { | 702 function FindCorrespondingFunctions(old_code_tree, new_code_tree) { |
703 | 703 |
704 // A recursive function that tries to find a correspondence for all | 704 // A recursive function that tries to find a correspondence for all |
705 // child functions and for their inner functions. | 705 // child functions and for their inner functions. |
706 function ProcessChildren(old_node, new_node) { | 706 function ProcessNode(old_node, new_node) { |
707 var scope_change_description = | |
708 IsFunctionContextLocalsChanged(old_node.info, new_node.info); | |
709 if (scope_change_description) { | |
710 old_node.status = FunctionStatus.CHANGED; | |
711 } | |
712 | |
707 var old_children = old_node.children; | 713 var old_children = old_node.children; |
708 var new_children = new_node.children; | 714 var new_children = new_node.children; |
709 | 715 |
710 var unmatched_new_nodes_list = []; | 716 var unmatched_new_nodes_list = []; |
711 var textually_unmatched_new_nodes_list = []; | 717 var textually_unmatched_new_nodes_list = []; |
712 | 718 |
713 var old_index = 0; | 719 var old_index = 0; |
714 var new_index = 0; | 720 var new_index = 0; |
715 while (old_index < old_children.length) { | 721 while (old_index < old_children.length) { |
716 if (old_children[old_index].status == FunctionStatus.DAMAGED) { | 722 if (old_children[old_index].status == FunctionStatus.DAMAGED) { |
717 old_index++; | 723 old_index++; |
718 } else if (new_index < new_children.length) { | 724 } else if (new_index < new_children.length) { |
719 if (new_children[new_index].info.start_position < | 725 if (new_children[new_index].info.start_position < |
720 old_children[old_index].new_start_pos) { | 726 old_children[old_index].new_start_pos) { |
721 unmatched_new_nodes_list.push(new_children[new_index]); | 727 unmatched_new_nodes_list.push(new_children[new_index]); |
722 textually_unmatched_new_nodes_list.push(new_children[new_index]); | 728 textually_unmatched_new_nodes_list.push(new_children[new_index]); |
723 new_index++; | 729 new_index++; |
724 } else if (new_children[new_index].info.start_position == | 730 } else if (new_children[new_index].info.start_position == |
725 old_children[old_index].new_start_pos) { | 731 old_children[old_index].new_start_pos) { |
726 if (new_children[new_index].info.end_position == | 732 if (new_children[new_index].info.end_position == |
727 old_children[old_index].new_end_pos) { | 733 old_children[old_index].new_end_pos) { |
728 old_children[old_index].corresponding_node = | 734 old_children[old_index].corresponding_node = |
729 new_children[new_index]; | 735 new_children[new_index]; |
730 old_children[old_index].textual_corresponding_node = | 736 old_children[old_index].textual_corresponding_node = |
731 new_children[new_index]; | 737 new_children[new_index]; |
732 if (old_children[old_index].status != FunctionStatus.UNCHANGED) { | 738 if (scope_change_description) { |
733 ProcessChildren(old_children[old_index], | 739 old_children[old_index].status = FunctionStatus.DAMAGED; |
740 old_children[old_index].status_explanation = | |
741 "Enclosing function is now incompatible. " + | |
742 scope_change_description; | |
743 old_children[old_index].corresponding_node = void 0; | |
744 } else if (old_children[old_index].status != | |
745 FunctionStatus.UNCHANGED) { | |
746 ProcessNode(old_children[old_index], | |
734 new_children[new_index]); | 747 new_children[new_index]); |
735 if (old_children[old_index].status == FunctionStatus.DAMAGED) { | 748 if (old_children[old_index].status == FunctionStatus.DAMAGED) { |
736 unmatched_new_nodes_list.push( | 749 unmatched_new_nodes_list.push( |
737 old_children[old_index].corresponding_node); | 750 old_children[old_index].corresponding_node); |
738 old_children[old_index].corresponding_node = void 0; | 751 old_children[old_index].corresponding_node = void 0; |
739 old_node.status = FunctionStatus.CHANGED; | 752 old_node.status = FunctionStatus.CHANGED; |
740 } | 753 } |
741 } | 754 } |
742 } else { | 755 } else { |
743 old_children[old_index].status = FunctionStatus.DAMAGED; | 756 old_children[old_index].status = FunctionStatus.DAMAGED; |
(...skipping 21 matching lines...) Expand all Loading... | |
765 } | 778 } |
766 } | 779 } |
767 | 780 |
768 while (new_index < new_children.length) { | 781 while (new_index < new_children.length) { |
769 unmatched_new_nodes_list.push(new_children[new_index]); | 782 unmatched_new_nodes_list.push(new_children[new_index]); |
770 textually_unmatched_new_nodes_list.push(new_children[new_index]); | 783 textually_unmatched_new_nodes_list.push(new_children[new_index]); |
771 new_index++; | 784 new_index++; |
772 } | 785 } |
773 | 786 |
774 if (old_node.status == FunctionStatus.CHANGED) { | 787 if (old_node.status == FunctionStatus.CHANGED) { |
775 var why_wrong_expectations = | 788 if (old_node.info.param_num != new_node.info.param_num) { |
776 WhyFunctionExpectationsDiffer(old_node.info, new_node.info); | |
777 if (why_wrong_expectations) { | |
778 old_node.status = FunctionStatus.DAMAGED; | 789 old_node.status = FunctionStatus.DAMAGED; |
779 old_node.status_explanation = why_wrong_expectations; | 790 old_node.status_explanation = "Changed parameter number: " + |
791 old_node.info.param_num + " and " + new_node.info.param_num; | |
780 } | 792 } |
781 } | 793 } |
782 old_node.unmatched_new_nodes = unmatched_new_nodes_list; | 794 old_node.unmatched_new_nodes = unmatched_new_nodes_list; |
783 old_node.textually_unmatched_new_nodes = | 795 old_node.textually_unmatched_new_nodes = |
784 textually_unmatched_new_nodes_list; | 796 textually_unmatched_new_nodes_list; |
785 } | 797 } |
786 | 798 |
787 ProcessChildren(old_code_tree, new_code_tree); | 799 ProcessNode(old_code_tree, new_code_tree); |
788 | 800 |
789 old_code_tree.corresponding_node = new_code_tree; | 801 old_code_tree.corresponding_node = new_code_tree; |
790 old_code_tree.textual_corresponding_node = new_code_tree; | 802 old_code_tree.textual_corresponding_node = new_code_tree; |
791 | 803 |
792 Assert(old_code_tree.status != FunctionStatus.DAMAGED, | 804 Assert(old_code_tree.status != FunctionStatus.DAMAGED, |
793 "Script became damaged"); | 805 "Script became damaged"); |
794 } | 806 } |
795 | 807 |
796 function FindLiveSharedInfos(old_code_tree, script) { | 808 function FindLiveSharedInfos(old_code_tree, script) { |
797 var shared_raw_list = %LiveEditFindSharedFunctionInfosForScript(script); | 809 var shared_raw_list = %LiveEditFindSharedFunctionInfosForScript(script); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
849 } | 861 } |
850 | 862 |
851 function SharedInfoWrapper(raw_array) { | 863 function SharedInfoWrapper(raw_array) { |
852 this.function_name = raw_array[0]; | 864 this.function_name = raw_array[0]; |
853 this.start_position = raw_array[1]; | 865 this.start_position = raw_array[1]; |
854 this.end_position = raw_array[2]; | 866 this.end_position = raw_array[2]; |
855 this.info = raw_array[3]; | 867 this.info = raw_array[3]; |
856 this.raw_array = raw_array; | 868 this.raw_array = raw_array; |
857 } | 869 } |
858 | 870 |
859 // Changes positions (including all statments) in function. | 871 // Changes positions (including all statments) in function. |
aandrey
2013/09/20 12:35:21
statments -> statements
Peter.Rybin
2013/09/20 13:16:51
Done.
| |
860 function PatchPositions(old_info_node, diff_array, report_array) { | 872 function PatchPositions(old_info_node, diff_array, report_array) { |
861 if (old_info_node.live_shared_function_infos) { | 873 if (old_info_node.live_shared_function_infos) { |
862 old_info_node.live_shared_function_infos.forEach(function (info) { | 874 old_info_node.live_shared_function_infos.forEach(function (info) { |
863 %LiveEditPatchFunctionPositions(info.raw_array, | 875 %LiveEditPatchFunctionPositions(info.raw_array, |
864 diff_array); | 876 diff_array); |
865 }); | 877 }); |
866 | 878 |
867 report_array.push( { name: old_info_node.info.function_name } ); | 879 report_array.push( { name: old_info_node.info.function_name } ); |
868 } else { | 880 } else { |
869 // TODO(LiveEdit): function is not compiled yet or is already collected. | 881 // TODO(LiveEdit): function is not compiled yet or is already collected. |
870 report_array.push( | 882 report_array.push( |
871 { name: old_info_node.info.function_name, info_not_found: true } ); | 883 { name: old_info_node.info.function_name, info_not_found: true } ); |
872 } | 884 } |
873 } | 885 } |
874 | 886 |
875 // Adds a suffix to script name to mark that it is old version. | 887 // Adds a suffix to script name to mark that it is old version. |
876 function CreateNameForOldScript(script) { | 888 function CreateNameForOldScript(script) { |
877 // TODO(635): try better than this; support several changes. | 889 // TODO(635): try better than this; support several changes. |
878 return script.name + " (old)"; | 890 return script.name + " (old)"; |
879 } | 891 } |
880 | 892 |
881 // Compares a function interface old and new version, whether it | 893 // Compares a function scope heap structure, old and new version, whether it |
882 // changed or not. Returns explanation if they differ. | 894 // changed or not. Returns explanation if they differ. |
883 function WhyFunctionExpectationsDiffer(function_info1, function_info2) { | 895 function IsFunctionContextLocalsChanged(function_info1, function_info2) { |
884 // Check that function has the same number of parameters (there may exist | |
885 // an adapter, that won't survive function parameter number change). | |
886 if (function_info1.param_num != function_info2.param_num) { | |
887 return "Changed parameter number: " + function_info1.param_num + | |
888 " and " + function_info2.param_num; | |
889 } | |
890 var scope_info1 = function_info1.scope_info; | 896 var scope_info1 = function_info1.scope_info; |
891 var scope_info2 = function_info2.scope_info; | 897 var scope_info2 = function_info2.scope_info; |
892 | 898 |
893 var scope_info1_text; | 899 var scope_info1_text; |
894 var scope_info2_text; | 900 var scope_info2_text; |
895 | 901 |
896 if (scope_info1) { | 902 if (scope_info1) { |
897 scope_info1_text = scope_info1.toString(); | 903 scope_info1_text = scope_info1.toString(); |
898 } else { | 904 } else { |
899 scope_info1_text = ""; | 905 scope_info1_text = ""; |
900 } | 906 } |
901 if (scope_info2) { | 907 if (scope_info2) { |
902 scope_info2_text = scope_info2.toString(); | 908 scope_info2_text = scope_info2.toString(); |
903 } else { | 909 } else { |
904 scope_info2_text = ""; | 910 scope_info2_text = ""; |
905 } | 911 } |
906 | 912 |
907 if (scope_info1_text != scope_info2_text) { | 913 if (scope_info1_text != scope_info2_text) { |
908 return "Incompatible variable maps: [" + scope_info1_text + | 914 return "Variable map changed: [" + scope_info1_text + |
909 "] and [" + scope_info2_text + "]"; | 915 "] => [" + scope_info2_text + "]"; |
910 } | 916 } |
911 // No differences. Return undefined. | 917 // No differences. Return undefined. |
912 return; | 918 return; |
913 } | 919 } |
914 | 920 |
915 // Minifier forward declaration. | 921 // Minifier forward declaration. |
916 var FunctionPatchabilityStatus; | 922 var FunctionPatchabilityStatus; |
917 | 923 |
918 // For array of wrapped shared function infos checks that none of them | 924 // For array of wrapped shared function infos checks that none of them |
919 // have activations on stack (of any thread). Throws a Failure exception | 925 // have activations on stack (of any thread). Throws a Failure exception |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1128 // Function is public. | 1134 // Function is public. |
1129 this.RestartFrame = RestartFrame; | 1135 this.RestartFrame = RestartFrame; |
1130 | 1136 |
1131 // Functions are public for tests. | 1137 // Functions are public for tests. |
1132 this.TestApi = { | 1138 this.TestApi = { |
1133 PosTranslator: PosTranslator, | 1139 PosTranslator: PosTranslator, |
1134 CompareStrings: CompareStrings, | 1140 CompareStrings: CompareStrings, |
1135 ApplySingleChunkPatch: ApplySingleChunkPatch | 1141 ApplySingleChunkPatch: ApplySingleChunkPatch |
1136 }; | 1142 }; |
1137 }; | 1143 }; |
OLD | NEW |