| 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 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 // expects this; neither does LiveEdit subsystem on next call). | 318 // expects this; neither does LiveEdit subsystem on next call). |
| 319 for (var i = 0; i < old_node.children.length; i++) { | 319 for (var i = 0; i < old_node.children.length; i++) { |
| 320 if (old_node.children[i].corresponding_node) { | 320 if (old_node.children[i].corresponding_node) { |
| 321 var corresponding_child_info = | 321 var corresponding_child_info = |
| 322 old_node.children[i].corresponding_node.info. | 322 old_node.children[i].corresponding_node.info. |
| 323 shared_function_info; | 323 shared_function_info; |
| 324 | 324 |
| 325 if (old_node.children[i].live_shared_function_infos) { | 325 if (old_node.children[i].live_shared_function_infos) { |
| 326 old_node.children[i].live_shared_function_infos. | 326 old_node.children[i].live_shared_function_infos. |
| 327 forEach(function (old_child_info) { | 327 forEach(function (old_child_info) { |
| 328 %LiveEditReplaceRefToNestedFunction(old_info.info, | 328 %LiveEditReplaceRefToNestedFunction( |
| 329 corresponding_child_info
, | 329 old_info.info, |
| 330 old_child_info.info); | 330 corresponding_child_info, |
| 331 old_child_info.info); |
| 331 }); | 332 }); |
| 332 } | 333 } |
| 333 } | 334 } |
| 334 } | 335 } |
| 335 }); | 336 }); |
| 336 | 337 |
| 337 change_log.push( {function_patched: new_info.function_name} ); | 338 change_log.push( {function_patched: new_info.function_name} ); |
| 338 } else { | 339 } else { |
| 339 change_log.push( {function_patched: new_info.function_name, | 340 change_log.push( {function_patched: new_info.function_name, |
| 340 function_info_not_found: true} ); | 341 function_info_not_found: true} ); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 break_point.clear(); | 375 break_point.clear(); |
| 375 | 376 |
| 376 // TODO(LiveEdit): be careful with resource offset here. | 377 // TODO(LiveEdit): be careful with resource offset here. |
| 377 var break_point_position = Debug.findScriptSourcePosition(original_script, | 378 var break_point_position = Debug.findScriptSourcePosition(original_script, |
| 378 break_point.line(), break_point.column()); | 379 break_point.line(), break_point.column()); |
| 379 | 380 |
| 380 var old_position_description = { | 381 var old_position_description = { |
| 381 position: break_point_position, | 382 position: break_point_position, |
| 382 line: break_point.line(), | 383 line: break_point.line(), |
| 383 column: break_point.column() | 384 column: break_point.column() |
| 384 } | 385 }; |
| 385 break_point_old_positions.push(old_position_description); | 386 break_point_old_positions.push(old_position_description); |
| 386 } | 387 } |
| 387 | 388 |
| 388 | 389 |
| 389 // Restores breakpoints and creates their copies in the "old" copy of | 390 // Restores breakpoints and creates their copies in the "old" copy of |
| 390 // the script. | 391 // the script. |
| 391 return function (pos_translator, old_script_copy_opt) { | 392 return function (pos_translator, old_script_copy_opt) { |
| 392 // Update breakpoints (change positions and restore them in old version | 393 // Update breakpoints (change positions and restore them in old version |
| 393 // of script. | 394 // of script. |
| 394 for (var i = 0; i < script_break_points.length; i++) { | 395 for (var i = 0; i < script_break_points.length; i++) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 411 | 412 |
| 412 var new_location = | 413 var new_location = |
| 413 original_script.locationFromPosition(updated_position, false); | 414 original_script.locationFromPosition(updated_position, false); |
| 414 | 415 |
| 415 break_point.update_positions(new_location.line, new_location.column); | 416 break_point.update_positions(new_location.line, new_location.column); |
| 416 | 417 |
| 417 var new_position_description = { | 418 var new_position_description = { |
| 418 position: updated_position, | 419 position: updated_position, |
| 419 line: new_location.line, | 420 line: new_location.line, |
| 420 column: new_location.column | 421 column: new_location.column |
| 421 } | 422 }; |
| 422 | 423 |
| 423 break_point.set(original_script); | 424 break_point.set(original_script); |
| 424 | 425 |
| 425 break_points_update_report.push( { type: "position_changed", | 426 break_points_update_report.push( { type: "position_changed", |
| 426 id: break_point.number(), | 427 id: break_point.number(), |
| 427 old_positions: break_point_old_positions[i], | 428 old_positions: break_point_old_positions[i], |
| 428 new_positions: new_position_description | 429 new_positions: new_position_description |
| 429 } ); | 430 } ); |
| 430 } | 431 } |
| 431 } | 432 }; |
| 432 } | 433 } |
| 433 | 434 |
| 434 | 435 |
| 435 function Assert(condition, message) { | 436 function Assert(condition, message) { |
| 436 if (!condition) { | 437 if (!condition) { |
| 437 if (message) { | 438 if (message) { |
| 438 throw "Assert " + message; | 439 throw "Assert " + message; |
| 439 } else { | 440 } else { |
| 440 throw "Assert"; | 441 throw "Assert"; |
| 441 } | 442 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 458 var pos1_end = diff_array[i + 1]; | 459 var pos1_end = diff_array[i + 1]; |
| 459 var pos2_end = diff_array[i + 2]; | 460 var pos2_end = diff_array[i + 2]; |
| 460 chunks.push(new DiffChunk(pos1_begin, pos2_begin, pos1_end - pos1_begin, | 461 chunks.push(new DiffChunk(pos1_begin, pos2_begin, pos1_end - pos1_begin, |
| 461 pos2_end - pos2_begin)); | 462 pos2_end - pos2_begin)); |
| 462 current_diff = pos2_end - pos1_end; | 463 current_diff = pos2_end - pos1_end; |
| 463 } | 464 } |
| 464 this.chunks = chunks; | 465 this.chunks = chunks; |
| 465 } | 466 } |
| 466 PosTranslator.prototype.GetChunks = function() { | 467 PosTranslator.prototype.GetChunks = function() { |
| 467 return this.chunks; | 468 return this.chunks; |
| 468 } | 469 }; |
| 469 | 470 |
| 470 PosTranslator.prototype.Translate = function(pos, inside_chunk_handler) { | 471 PosTranslator.prototype.Translate = function(pos, inside_chunk_handler) { |
| 471 var array = this.chunks; | 472 var array = this.chunks; |
| 472 if (array.length == 0 || pos < array[0].pos1) { | 473 if (array.length == 0 || pos < array[0].pos1) { |
| 473 return pos; | 474 return pos; |
| 474 } | 475 } |
| 475 var chunk_index1 = 0; | 476 var chunk_index1 = 0; |
| 476 var chunk_index2 = array.length - 1; | 477 var chunk_index2 = array.length - 1; |
| 477 | 478 |
| 478 while (chunk_index1 < chunk_index2) { | 479 while (chunk_index1 < chunk_index2) { |
| 479 var middle_index = Math.floor((chunk_index1 + chunk_index2) / 2); | 480 var middle_index = Math.floor((chunk_index1 + chunk_index2) / 2); |
| 480 if (pos < array[middle_index + 1].pos1) { | 481 if (pos < array[middle_index + 1].pos1) { |
| 481 chunk_index2 = middle_index; | 482 chunk_index2 = middle_index; |
| 482 } else { | 483 } else { |
| 483 chunk_index1 = middle_index + 1; | 484 chunk_index1 = middle_index + 1; |
| 484 } | 485 } |
| 485 } | 486 } |
| 486 var chunk = array[chunk_index1]; | 487 var chunk = array[chunk_index1]; |
| 487 if (pos >= chunk.pos1 + chunk.len1) { | 488 if (pos >= chunk.pos1 + chunk.len1) { |
| 488 return pos + chunk.pos2 + chunk.len2 - chunk.pos1 - chunk.len1; | 489 return pos + chunk.pos2 + chunk.len2 - chunk.pos1 - chunk.len1; |
| 489 } | 490 } |
| 490 | 491 |
| 491 if (!inside_chunk_handler) { | 492 if (!inside_chunk_handler) { |
| 492 inside_chunk_handler = PosTranslator.DefaultInsideChunkHandler; | 493 inside_chunk_handler = PosTranslator.DefaultInsideChunkHandler; |
| 493 } | 494 } |
| 494 return inside_chunk_handler(pos, chunk); | 495 return inside_chunk_handler(pos, chunk); |
| 495 } | 496 }; |
| 496 | 497 |
| 497 PosTranslator.DefaultInsideChunkHandler = function(pos, diff_chunk) { | 498 PosTranslator.DefaultInsideChunkHandler = function(pos, diff_chunk) { |
| 498 Assert(false, "Cannot translate position in changed area"); | 499 Assert(false, "Cannot translate position in changed area"); |
| 499 } | 500 }; |
| 500 | 501 |
| 501 PosTranslator.ShiftWithTopInsideChunkHandler = | 502 PosTranslator.ShiftWithTopInsideChunkHandler = |
| 502 function(pos, diff_chunk) { | 503 function(pos, diff_chunk) { |
| 503 // We carelessly do not check whether we stay inside the chunk after | 504 // We carelessly do not check whether we stay inside the chunk after |
| 504 // translation. | 505 // translation. |
| 505 return pos - diff_chunk.pos1 + diff_chunk.pos2; | 506 return pos - diff_chunk.pos1 + diff_chunk.pos2; |
| 506 } | 507 }; |
| 507 | 508 |
| 508 var FunctionStatus = { | 509 var FunctionStatus = { |
| 509 // No change to function or its inner functions; however its positions | 510 // No change to function or its inner functions; however its positions |
| 510 // in script may have been shifted. | 511 // in script may have been shifted. |
| 511 UNCHANGED: "unchanged", | 512 UNCHANGED: "unchanged", |
| 512 // The code of a function remains unchanged, but something happened inside | 513 // The code of a function remains unchanged, but something happened inside |
| 513 // some inner functions. | 514 // some inner functions. |
| 514 SOURCE_CHANGED: "source changed", | 515 SOURCE_CHANGED: "source changed", |
| 515 // The code of a function is changed or some nested function cannot be | 516 // The code of a function is changed or some nested function cannot be |
| 516 // properly patched so this function must be recompiled. | 517 // properly patched so this function must be recompiled. |
| 517 CHANGED: "changed", | 518 CHANGED: "changed", |
| 518 // Function is changed but cannot be patched. | 519 // Function is changed but cannot be patched. |
| 519 DAMAGED: "damaged" | 520 DAMAGED: "damaged" |
| 520 } | 521 }; |
| 521 | 522 |
| 522 function CodeInfoTreeNode(code_info, children, array_index) { | 523 function CodeInfoTreeNode(code_info, children, array_index) { |
| 523 this.info = code_info; | 524 this.info = code_info; |
| 524 this.children = children; | 525 this.children = children; |
| 525 // an index in array of compile_info | 526 // an index in array of compile_info |
| 526 this.array_index = array_index; | 527 this.array_index = array_index; |
| 527 this.parent = void 0; | 528 this.parent = void 0; |
| 528 | 529 |
| 529 this.status = FunctionStatus.UNCHANGED; | 530 this.status = FunctionStatus.UNCHANGED; |
| 530 // Status explanation is used for debugging purposes and will be shown | 531 // Status explanation is used for debugging purposes and will be shown |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 // Applies a list of the textual diff chunks onto the tree of functions. | 579 // Applies a list of the textual diff chunks onto the tree of functions. |
| 579 // Determines status of each function (from unchanged to damaged). However | 580 // Determines status of each function (from unchanged to damaged). However |
| 580 // children of unchanged functions are ignored. | 581 // children of unchanged functions are ignored. |
| 581 function MarkChangedFunctions(code_info_tree, chunks) { | 582 function MarkChangedFunctions(code_info_tree, chunks) { |
| 582 | 583 |
| 583 // A convenient interator over diff chunks that also translates | 584 // A convenient interator over diff chunks that also translates |
| 584 // positions from old to new in a current non-changed part of script. | 585 // positions from old to new in a current non-changed part of script. |
| 585 var chunk_it = new function() { | 586 var chunk_it = new function() { |
| 586 var chunk_index = 0; | 587 var chunk_index = 0; |
| 587 var pos_diff = 0; | 588 var pos_diff = 0; |
| 588 this.current = function() { return chunks[chunk_index]; } | 589 this.current = function() { return chunks[chunk_index]; }; |
| 589 this.next = function() { | 590 this.next = function() { |
| 590 var chunk = chunks[chunk_index]; | 591 var chunk = chunks[chunk_index]; |
| 591 pos_diff = chunk.pos2 + chunk.len2 - (chunk.pos1 + chunk.len1); | 592 pos_diff = chunk.pos2 + chunk.len2 - (chunk.pos1 + chunk.len1); |
| 592 chunk_index++; | 593 chunk_index++; |
| 593 } | 594 }; |
| 594 this.done = function() { return chunk_index >= chunks.length; } | 595 this.done = function() { return chunk_index >= chunks.length; }; |
| 595 this.TranslatePos = function(pos) { return pos + pos_diff; } | 596 this.TranslatePos = function(pos) { return pos + pos_diff; }; |
| 596 }; | 597 }; |
| 597 | 598 |
| 598 // A recursive function that processes internals of a function and all its | 599 // A recursive function that processes internals of a function and all its |
| 599 // inner functions. Iterator chunk_it initially points to a chunk that is | 600 // inner functions. Iterator chunk_it initially points to a chunk that is |
| 600 // below function start. | 601 // below function start. |
| 601 function ProcessInternals(info_node) { | 602 function ProcessInternals(info_node) { |
| 602 info_node.new_start_pos = chunk_it.TranslatePos( | 603 info_node.new_start_pos = chunk_it.TranslatePos( |
| 603 info_node.info.start_position); | 604 info_node.info.start_position); |
| 604 var child_index = 0; | 605 var child_index = 0; |
| 605 var code_changed = false; | 606 var code_changed = false; |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 939 return dropped.length; | 940 return dropped.length; |
| 940 } | 941 } |
| 941 | 942 |
| 942 // A copy of the FunctionPatchabilityStatus enum from liveedit.h | 943 // A copy of the FunctionPatchabilityStatus enum from liveedit.h |
| 943 var FunctionPatchabilityStatus = { | 944 var FunctionPatchabilityStatus = { |
| 944 AVAILABLE_FOR_PATCH: 1, | 945 AVAILABLE_FOR_PATCH: 1, |
| 945 BLOCKED_ON_ACTIVE_STACK: 2, | 946 BLOCKED_ON_ACTIVE_STACK: 2, |
| 946 BLOCKED_ON_OTHER_STACK: 3, | 947 BLOCKED_ON_OTHER_STACK: 3, |
| 947 BLOCKED_UNDER_NATIVE_CODE: 4, | 948 BLOCKED_UNDER_NATIVE_CODE: 4, |
| 948 REPLACED_ON_ACTIVE_STACK: 5 | 949 REPLACED_ON_ACTIVE_STACK: 5 |
| 949 } | 950 }; |
| 950 | 951 |
| 951 FunctionPatchabilityStatus.SymbolName = function(code) { | 952 FunctionPatchabilityStatus.SymbolName = function(code) { |
| 952 var enum = FunctionPatchabilityStatus; | 953 var enumeration = FunctionPatchabilityStatus; |
| 953 for (name in enum) { | 954 for (name in enumeration) { |
| 954 if (enum[name] == code) { | 955 if (enumeration[name] == code) { |
| 955 return name; | 956 return name; |
| 956 } | 957 } |
| 957 } | 958 } |
| 958 } | 959 }; |
| 959 | 960 |
| 960 | 961 |
| 961 // A logical failure in liveedit process. This means that change_log | 962 // A logical failure in liveedit process. This means that change_log |
| 962 // is valid and consistent description of what happened. | 963 // is valid and consistent description of what happened. |
| 963 function Failure(message) { | 964 function Failure(message) { |
| 964 this.message = message; | 965 this.message = message; |
| 965 } | 966 } |
| 966 // Function (constructor) is public. | 967 // Function (constructor) is public. |
| 967 this.Failure = Failure; | 968 this.Failure = Failure; |
| 968 | 969 |
| 969 Failure.prototype.toString = function() { | 970 Failure.prototype.toString = function() { |
| 970 return "LiveEdit Failure: " + this.message; | 971 return "LiveEdit Failure: " + this.message; |
| 971 } | 972 }; |
| 972 | 973 |
| 973 // A testing entry. | 974 // A testing entry. |
| 974 function GetPcFromSourcePos(func, source_pos) { | 975 function GetPcFromSourcePos(func, source_pos) { |
| 975 return %GetFunctionCodePositionFromSource(func, source_pos); | 976 return %GetFunctionCodePositionFromSource(func, source_pos); |
| 976 } | 977 } |
| 977 // Function is public. | 978 // Function is public. |
| 978 this.GetPcFromSourcePos = GetPcFromSourcePos; | 979 this.GetPcFromSourcePos = GetPcFromSourcePos; |
| 979 | 980 |
| 980 // LiveEdit main entry point: changes a script text to a new string. | 981 // LiveEdit main entry point: changes a script text to a new string. |
| 981 function SetScriptSource(script, new_source, preview_only, change_log) { | 982 function SetScriptSource(script, new_source, preview_only, change_log) { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1071 | 1072 |
| 1072 return ProcessOldNode(old_code_tree); | 1073 return ProcessOldNode(old_code_tree); |
| 1073 } | 1074 } |
| 1074 | 1075 |
| 1075 | 1076 |
| 1076 // Functions are public for tests. | 1077 // Functions are public for tests. |
| 1077 this.TestApi = { | 1078 this.TestApi = { |
| 1078 PosTranslator: PosTranslator, | 1079 PosTranslator: PosTranslator, |
| 1079 CompareStrings: CompareStrings, | 1080 CompareStrings: CompareStrings, |
| 1080 ApplySingleChunkPatch: ApplySingleChunkPatch | 1081 ApplySingleChunkPatch: ApplySingleChunkPatch |
| 1081 } | 1082 }; |
| 1082 } | 1083 }; |
| OLD | NEW |