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 |