| 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 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 | 133 |
| 134 if (preview_only) { | 134 if (preview_only) { |
| 135 return preview_description; | 135 return preview_description; |
| 136 } | 136 } |
| 137 | 137 |
| 138 HarvestTodo(root_old_node); | 138 HarvestTodo(root_old_node); |
| 139 | 139 |
| 140 // Collect shared infos for functions whose code need to be patched. | 140 // Collect shared infos for functions whose code need to be patched. |
| 141 var replaced_function_infos = new Array(); | 141 var replaced_function_infos = new Array(); |
| 142 for (var i = 0; i < replace_code_list.length; i++) { | 142 for (var i = 0; i < replace_code_list.length; i++) { |
| 143 var info_wrapper = replace_code_list[i].live_shared_info_wrapper; | 143 var live_shared_function_infos = |
| 144 if (info_wrapper) { | 144 replace_code_list[i].live_shared_function_infos; |
| 145 replaced_function_infos.push(info_wrapper); | 145 |
| 146 if (live_shared_function_infos) { |
| 147 for (var i = 0; i < live_shared_function_infos.length; i++) { |
| 148 replaced_function_infos.push(live_shared_function_infos[i]); |
| 149 } |
| 146 } | 150 } |
| 147 } | 151 } |
| 148 | 152 |
| 149 // We haven't changed anything before this line yet. | 153 // We haven't changed anything before this line yet. |
| 150 // Committing all changes. | 154 // Committing all changes. |
| 151 | 155 |
| 152 // Check that function being patched is not currently on stack or drop them. | 156 // Check that function being patched is not currently on stack or drop them. |
| 153 var dropped_functions_number = | 157 var dropped_functions_number = |
| 154 CheckStackActivations(replaced_function_infos, change_log); | 158 CheckStackActivations(replaced_function_infos, change_log); |
| 155 | 159 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 } | 201 } |
| 198 | 202 |
| 199 var position_patch_report = new Array(); | 203 var position_patch_report = new Array(); |
| 200 change_log.push( {position_patched: position_patch_report} ); | 204 change_log.push( {position_patched: position_patch_report} ); |
| 201 | 205 |
| 202 for (var i = 0; i < update_positions_list.length; i++) { | 206 for (var i = 0; i < update_positions_list.length; i++) { |
| 203 // TODO(LiveEdit): take into account wether it's source_changed or | 207 // TODO(LiveEdit): take into account wether it's source_changed or |
| 204 // unchanged and whether positions changed at all. | 208 // unchanged and whether positions changed at all. |
| 205 PatchPositions(update_positions_list[i], diff_array, | 209 PatchPositions(update_positions_list[i], diff_array, |
| 206 position_patch_report); | 210 position_patch_report); |
| 211 |
| 212 if (update_positions_list[i].live_shared_function_infos) { |
| 213 update_positions_list[i].live_shared_function_infos. |
| 214 forEach(function (info) { |
| 215 %LiveEditFunctionSourceUpdated(info.raw_array); |
| 216 }); |
| 217 } |
| 207 } | 218 } |
| 208 | 219 |
| 209 break_points_restorer(pos_translator, old_script); | 220 break_points_restorer(pos_translator, old_script); |
| 210 | 221 |
| 211 preview_description.updated = true; | 222 preview_description.updated = true; |
| 212 return preview_description; | 223 return preview_description; |
| 213 } | 224 } |
| 214 // Function is public. | 225 // Function is public. |
| 215 this.ApplyPatchMultiChunk = ApplyPatchMultiChunk; | 226 this.ApplyPatchMultiChunk = ApplyPatchMultiChunk; |
| 216 | 227 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 ResetIndexes(-1, -1); | 298 ResetIndexes(-1, -1); |
| 288 Assert(current_index == compile_info.length); | 299 Assert(current_index == compile_info.length); |
| 289 | 300 |
| 290 return compile_info; | 301 return compile_info; |
| 291 } | 302 } |
| 292 | 303 |
| 293 | 304 |
| 294 // Replaces function's Code. | 305 // Replaces function's Code. |
| 295 function PatchFunctionCode(old_node, change_log) { | 306 function PatchFunctionCode(old_node, change_log) { |
| 296 var new_info = old_node.corresponding_node.info; | 307 var new_info = old_node.corresponding_node.info; |
| 297 var shared_info_wrapper = old_node.live_shared_info_wrapper; | 308 if (old_node.live_shared_function_infos) { |
| 298 if (shared_info_wrapper) { | 309 old_node.live_shared_function_infos.forEach(function (old_info) { |
| 299 %LiveEditReplaceFunctionCode(new_info.raw_array, | 310 %LiveEditReplaceFunctionCode(new_info.raw_array, |
| 300 shared_info_wrapper.raw_array); | 311 old_info.raw_array); |
| 301 | 312 |
| 302 // The function got a new code. However, this new code brings all new | 313 // The function got a new code. However, this new code brings all new |
| 303 // instances of SharedFunctionInfo for nested functions. However, | 314 // instances of SharedFunctionInfo for nested functions. However, |
| 304 // we want the original instances to be used wherever possible. | 315 // we want the original instances to be used wherever possible. |
| 305 // (This is because old instances and new instances will be both | 316 // (This is because old instances and new instances will be both |
| 306 // linked to a script and breakpoints subsystem does not really | 317 // linked to a script and breakpoints subsystem does not really |
| 307 // expects this; neither does LiveEdit subsystem on next call). | 318 // expects this; neither does LiveEdit subsystem on next call). |
| 308 for (var i = 0; i < old_node.children.length; i++) { | 319 for (var i = 0; i < old_node.children.length; i++) { |
| 309 if (old_node.children[i].corresponding_node) { | 320 if (old_node.children[i].corresponding_node) { |
| 310 var corresponding_child = old_node.children[i].corresponding_node; | 321 var corresponding_child_info = |
| 311 var child_shared_info_wrapper = | 322 old_node.children[i].corresponding_node.info. |
| 312 old_node.children[i].live_shared_info_wrapper; | 323 shared_function_info; |
| 313 if (child_shared_info_wrapper) { | 324 |
| 314 %LiveEditReplaceRefToNestedFunction(shared_info_wrapper.info, | 325 if (old_node.children[i].live_shared_function_infos) { |
| 315 corresponding_child.info.shared_function_info, | 326 old_node.children[i].live_shared_function_infos. |
| 316 child_shared_info_wrapper.info); | 327 forEach(function (old_child_info) { |
| 328 %LiveEditReplaceRefToNestedFunction(old_info.info, |
| 329 corresponding_child_info
, |
| 330 old_child_info.info); |
| 331 }); |
| 332 } |
| 317 } | 333 } |
| 318 } | 334 } |
| 319 } | 335 }); |
| 320 | 336 |
| 321 change_log.push( {function_patched: new_info.function_name} ); | 337 change_log.push( {function_patched: new_info.function_name} ); |
| 322 } else { | 338 } else { |
| 323 change_log.push( {function_patched: new_info.function_name, | 339 change_log.push( {function_patched: new_info.function_name, |
| 324 function_info_not_found: true} ); | 340 function_info_not_found: true} ); |
| 325 } | 341 } |
| 326 } | 342 } |
| 327 | 343 |
| 328 | 344 |
| 329 // Makes a function associated with another instance of a script (the | 345 // Makes a function associated with another instance of a script (the |
| 330 // one representing its old version). This way the function still | 346 // one representing its old version). This way the function still |
| 331 // may access its own text. | 347 // may access its own text. |
| 332 function LinkToOldScript(old_info_node, old_script, report_array) { | 348 function LinkToOldScript(old_info_node, old_script, report_array) { |
| 333 var shared_info = old_info_node.live_shared_info_wrapper; | 349 if (old_info_node.live_shared_function_infos) { |
| 334 if (shared_info) { | 350 old_info_node.live_shared_function_infos. |
| 335 %LiveEditFunctionSetScript(shared_info.info, old_script); | 351 forEach(function (info) { |
| 336 report_array.push( { name: shared_info.function_name } ); | 352 %LiveEditFunctionSetScript(info.info, old_script); |
| 353 }); |
| 354 |
| 355 report_array.push( { name: old_info_node.info.function_name } ); |
| 337 } else { | 356 } else { |
| 338 report_array.push( | 357 report_array.push( |
| 339 { name: old_info_node.info.function_name, not_found: true } ); | 358 { name: old_info_node.info.function_name, not_found: true } ); |
| 340 } | 359 } |
| 341 } | 360 } |
| 342 | 361 |
| 343 | 362 |
| 344 // Returns function that restores breakpoints. | 363 // Returns function that restores breakpoints. |
| 345 function TemporaryRemoveBreakPoints(original_script, change_log) { | 364 function TemporaryRemoveBreakPoints(original_script, change_log) { |
| 346 var script_break_points = GetScriptBreakPoints(original_script); | 365 var script_break_points = GetScriptBreakPoints(original_script); |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 | 537 |
| 519 // 'Textual' correspondence/matching is weaker than 'pure' | 538 // 'Textual' correspondence/matching is weaker than 'pure' |
| 520 // correspondence/matching. We need 'textual' level for visual presentation | 539 // correspondence/matching. We need 'textual' level for visual presentation |
| 521 // in UI, we use 'pure' level for actual code manipulation. | 540 // in UI, we use 'pure' level for actual code manipulation. |
| 522 // Sometimes only function body is changed (functions in old and new script | 541 // Sometimes only function body is changed (functions in old and new script |
| 523 // textually correspond), but we cannot patch the code, so we see them | 542 // textually correspond), but we cannot patch the code, so we see them |
| 524 // as an old function deleted and new function created. | 543 // as an old function deleted and new function created. |
| 525 this.textual_corresponding_node = void 0; | 544 this.textual_corresponding_node = void 0; |
| 526 this.textually_unmatched_new_nodes = void 0; | 545 this.textually_unmatched_new_nodes = void 0; |
| 527 | 546 |
| 528 this.live_shared_info_wrapper = void 0; | 547 this.live_shared_function_infos = void 0; |
| 529 } | 548 } |
| 530 | 549 |
| 531 // From array of function infos that is implicitly a tree creates | 550 // From array of function infos that is implicitly a tree creates |
| 532 // an actual tree of functions in script. | 551 // an actual tree of functions in script. |
| 533 function BuildCodeInfoTree(code_info_array) { | 552 function BuildCodeInfoTree(code_info_array) { |
| 534 // Throughtout all function we iterate over input array. | 553 // Throughtout all function we iterate over input array. |
| 535 var index = 0; | 554 var index = 0; |
| 536 | 555 |
| 537 // Recursive function that builds a branch of tree. | 556 // Recursive function that builds a branch of tree. |
| 538 function BuildNode() { | 557 function BuildNode() { |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 758 | 777 |
| 759 function FindLiveSharedInfos(old_code_tree, script) { | 778 function FindLiveSharedInfos(old_code_tree, script) { |
| 760 var shared_raw_list = %LiveEditFindSharedFunctionInfosForScript(script); | 779 var shared_raw_list = %LiveEditFindSharedFunctionInfosForScript(script); |
| 761 | 780 |
| 762 var shared_infos = new Array(); | 781 var shared_infos = new Array(); |
| 763 | 782 |
| 764 for (var i = 0; i < shared_raw_list.length; i++) { | 783 for (var i = 0; i < shared_raw_list.length; i++) { |
| 765 shared_infos.push(new SharedInfoWrapper(shared_raw_list[i])); | 784 shared_infos.push(new SharedInfoWrapper(shared_raw_list[i])); |
| 766 } | 785 } |
| 767 | 786 |
| 768 // Finds SharedFunctionInfo that corresponds compile info with index | 787 // Finds all SharedFunctionInfos that corresponds to compile info |
| 769 // in old version of the script. | 788 // in old version of the script. |
| 770 function FindFunctionInfo(compile_info) { | 789 function FindFunctionInfos(compile_info) { |
| 790 var wrappers = []; |
| 791 |
| 771 for (var i = 0; i < shared_infos.length; i++) { | 792 for (var i = 0; i < shared_infos.length; i++) { |
| 772 var wrapper = shared_infos[i]; | 793 var wrapper = shared_infos[i]; |
| 773 if (wrapper.start_position == compile_info.start_position && | 794 if (wrapper.start_position == compile_info.start_position && |
| 774 wrapper.end_position == compile_info.end_position) { | 795 wrapper.end_position == compile_info.end_position) { |
| 775 return wrapper; | 796 wrappers.push(wrapper); |
| 776 } | 797 } |
| 777 } | 798 } |
| 799 |
| 800 if (wrappers.length > 0) { |
| 801 return wrappers; |
| 802 } |
| 778 } | 803 } |
| 779 | 804 |
| 780 function TraverseTree(node) { | 805 function TraverseTree(node) { |
| 781 var info_wrapper = FindFunctionInfo(node.info); | 806 node.live_shared_function_infos = FindFunctionInfos(node.info); |
| 782 if (info_wrapper) { | 807 |
| 783 node.live_shared_info_wrapper = info_wrapper; | |
| 784 } | |
| 785 for (var i = 0; i < node.children.length; i++) { | 808 for (var i = 0; i < node.children.length; i++) { |
| 786 TraverseTree(node.children[i]); | 809 TraverseTree(node.children[i]); |
| 787 } | 810 } |
| 788 } | 811 } |
| 789 | 812 |
| 790 TraverseTree(old_code_tree); | 813 TraverseTree(old_code_tree); |
| 791 } | 814 } |
| 792 | 815 |
| 793 | 816 |
| 794 // An object describing function compilation details. Its index fields | 817 // An object describing function compilation details. Its index fields |
| (...skipping 15 matching lines...) Expand all Loading... |
| 810 function SharedInfoWrapper(raw_array) { | 833 function SharedInfoWrapper(raw_array) { |
| 811 this.function_name = raw_array[0]; | 834 this.function_name = raw_array[0]; |
| 812 this.start_position = raw_array[1]; | 835 this.start_position = raw_array[1]; |
| 813 this.end_position = raw_array[2]; | 836 this.end_position = raw_array[2]; |
| 814 this.info = raw_array[3]; | 837 this.info = raw_array[3]; |
| 815 this.raw_array = raw_array; | 838 this.raw_array = raw_array; |
| 816 } | 839 } |
| 817 | 840 |
| 818 // Changes positions (including all statments) in function. | 841 // Changes positions (including all statments) in function. |
| 819 function PatchPositions(old_info_node, diff_array, report_array) { | 842 function PatchPositions(old_info_node, diff_array, report_array) { |
| 820 var shared_info_wrapper = old_info_node.live_shared_info_wrapper; | 843 if (old_info_node.live_shared_function_infos) { |
| 821 if (!shared_info_wrapper) { | 844 old_info_node.live_shared_function_infos.forEach(function (info) { |
| 845 %LiveEditPatchFunctionPositions(info.raw_array, |
| 846 diff_array); |
| 847 }); |
| 848 |
| 849 report_array.push( { name: old_info_node.info.function_name } ); |
| 850 } else { |
| 822 // TODO(LiveEdit): function is not compiled yet or is already collected. | 851 // TODO(LiveEdit): function is not compiled yet or is already collected. |
| 823 report_array.push( | 852 report_array.push( |
| 824 { name: old_info_node.info.function_name, info_not_found: true } ); | 853 { name: old_info_node.info.function_name, info_not_found: true } ); |
| 825 return; | |
| 826 } | 854 } |
| 827 %LiveEditPatchFunctionPositions(shared_info_wrapper.raw_array, | |
| 828 diff_array); | |
| 829 report_array.push( { name: old_info_node.info.function_name } ); | |
| 830 } | 855 } |
| 831 | 856 |
| 832 // Adds a suffix to script name to mark that it is old version. | 857 // Adds a suffix to script name to mark that it is old version. |
| 833 function CreateNameForOldScript(script) { | 858 function CreateNameForOldScript(script) { |
| 834 // TODO(635): try better than this; support several changes. | 859 // TODO(635): try better than this; support several changes. |
| 835 return script.name + " (old)"; | 860 return script.name + " (old)"; |
| 836 } | 861 } |
| 837 | 862 |
| 838 // Compares a function interface old and new version, whether it | 863 // Compares a function interface old and new version, whether it |
| 839 // changed or not. Returns explanation if they differ. | 864 // changed or not. Returns explanation if they differ. |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1048 } | 1073 } |
| 1049 | 1074 |
| 1050 | 1075 |
| 1051 // Functions are public for tests. | 1076 // Functions are public for tests. |
| 1052 this.TestApi = { | 1077 this.TestApi = { |
| 1053 PosTranslator: PosTranslator, | 1078 PosTranslator: PosTranslator, |
| 1054 CompareStringsLinewise: CompareStringsLinewise, | 1079 CompareStringsLinewise: CompareStringsLinewise, |
| 1055 ApplySingleChunkPatch: ApplySingleChunkPatch | 1080 ApplySingleChunkPatch: ApplySingleChunkPatch |
| 1056 } | 1081 } |
| 1057 } | 1082 } |
| OLD | NEW |