@@ -603,16 +603,27 @@ function renderDataStructures(curEntry, vizDiv) {
603603 }
604604
605605
606+
606607 // variables are displayed in the following order, so lay out heap objects in the same order:
607608 // - globals
608609 // - stack entries (regular and zombies)
610+
611+ // if there are multiple aliases to the same object, we want to render
612+ // the one "deepest" in the stack, so that we can hopefully prevent
613+ // objects from jumping around as functions are called and returned.
614+ // e.g., if a list L appears as a global variable and as a local in a
615+ // function, we want to render L when rendering the global frame.
616+ //
617+ // this is straightforward: just go through globals first and then
618+ // each stack frame in order :)
619+
609620 $ . each ( curEntry . ordered_globals , function ( i , varname ) {
610621 var val = curEntry . globals [ varname ] ;
611622 // (use '!==' to do an EXACT match against undefined)
612623 if ( val !== undefined ) { // might not be defined at this line, which is OKAY!
613624 if ( ! isPrimitiveType ( val ) ) {
614625 layoutHeapObject ( val ) ;
615- console . log ( 'global:' , varname , getRefID ( val ) ) ;
626+ // console.log('global:', varname, getRefID(val));
616627 }
617628 }
618629 } ) ;
@@ -629,18 +640,20 @@ function renderDataStructures(curEntry, vizDiv) {
629640
630641 if ( ! isPrimitiveType ( val ) ) {
631642 layoutHeapObject ( val ) ;
632- console . log ( frame . func_name + ':' , varname , getRefID ( val ) ) ;
643+ // console.log(frame.func_name + ':', varname, getRefID(val));
633644 }
634645 } ) ;
635646 }
636647 } ) ;
637648
638649
639650 // print toplevelHeapLayout
651+ /*
640652 $.each(toplevelHeapLayout, function(i, elt) {
641653 console.log(elt);
642654 });
643655 console.log('---');
656+ */
644657
645658
646659 var renderedObjectIDs = { } ; // set (TODO: refactor all sets to use d3.map)
@@ -673,7 +686,7 @@ function renderDataStructures(curEntry, vizDiv) {
673686
674687 function renderNestedObject ( obj , d3DomElement ) {
675688 if ( isPrimitiveType ( obj ) ) {
676- renderPrimitiveObject ( obj , d3DomElement , false ) ;
689+ renderPrimitiveObject ( obj , d3DomElement ) ;
677690 }
678691 else {
679692 renderCompoundObject ( getRefID ( obj ) , d3DomElement , false ) ;
@@ -814,7 +827,7 @@ function renderDataStructures(curEntry, vizDiv) {
814827 else {
815828 var superclassStr = '' ;
816829 if ( obj [ 2 ] . length > 0 ) {
817- superclassStr += ( '[extends ' + obj [ 2 ] . join ( ',' ) + '] ' ) ;
830+ superclassStr += ( '[extends ' + obj [ 2 ] . join ( ', ' ) + '] ' ) ;
818831 }
819832 d3DomElement . append ( '<div class="typeLabel">' + obj [ 1 ] + ' class ' + superclassStr + '</div>' ) ;
820833 }
@@ -875,12 +888,11 @@ function renderDataStructures(curEntry, vizDiv) {
875888 // prepend heap header after all the dust settles:
876889 $ ( vizDiv + ' #heap' ) . prepend ( '<div id="heapHeader">Objects</div>' ) ;
877890
878- return ;
879891
880892
881- // Key: CSS ID of the div element representing the variable
882- // (or heap object, for heap->heap connections, where the
883- // format is: 'heap_pointer_src_<src id>')
893+ // Key: CSS ID of the div element representing the stack frame variable
894+ // (for stack->heap connections) or heap object ( for heap->heap connections)
895+ // the format is: 'heap_pointer_src_<src id>'
884896 // Value: CSS ID of the div element representing the value rendered in the heap
885897 // (the format is: 'heap_object_<id>')
886898 var connectionEndpointIDs = { } ;
@@ -889,45 +901,50 @@ function renderDataStructures(curEntry, vizDiv) {
889901 var heap_pointer_src_id = 1 ; // increment this to be unique for each heap_pointer_src_*
890902
891903
892- function renderGlobals ( ) {
893- // render all global variables IN THE ORDER they were created by the program,
894- // in order to ensure continuity:
895- if ( curEntry . ordered_globals . length > 0 ) {
896- $ ( vizDiv + " #stack" ) . append ( '<div class="stackFrame" id="globals"><div id="globals_header" class="stackFrameHeader">Global variables</div></div>' ) ;
904+ // Render globals and then stack frames:
897905
898- $ ( vizDiv + " #stack #globals" ) . append ( '<table class="stackFrameVarTable" id="global_table"></table>' ) ;
906+ // render all global variables IN THE ORDER they were created by the program,
907+ // in order to ensure continuity:
908+ if ( curEntry . ordered_globals . length > 0 ) {
909+ $ ( vizDiv + " #stack" ) . append ( '<div class="stackFrame" id="globals"><div id="globals_header" class="stackFrameHeader">Global variables</div></div>' ) ;
910+ $ ( vizDiv + " #stack #globals" ) . append ( '<table class="stackFrameVarTable" id="global_table"></table>' ) ;
899911
900- var tbl = $ ( vizDiv + " #global_table" ) ;
901- // iterate IN ORDER (it's possible that not all vars are in curEntry.globals)
902- $ . each ( curEntry . ordered_globals , function ( i , varname ) {
903- var val = curEntry . globals [ varname ] ;
904- // (use '!==' to do an EXACT match against undefined)
905- if ( val !== undefined ) { // might not be defined at this line, which is OKAY!
906- tbl . append ( '<tr><td class="stackFrameVar">' + varname + '</td><td class="stackFrameValue"></td></tr>' ) ;
907- var curTr = tbl . find ( 'tr:last' ) ;
912+ var tbl = $ ( vizDiv + " #global_table" ) ;
908913
909- if ( renderInline ( val ) ) {
910- renderData ( val , curTr . find ( "td.stackFrameValue" ) , false /* don't wrap it in a .heapObject div */ ) ;
911- }
912- else {
913- // add a stub so that we can connect it with a connector later.
914- // IE needs this div to be NON-EMPTY in order to properly
915- // render jsPlumb endpoints, so that's why we add an " "!
914+ $ . each ( curEntry . ordered_globals , function ( i , varname ) {
915+ var val = curEntry . globals [ varname ] ;
916+ // (use '!==' to do an EXACT match against undefined)
917+ if ( val !== undefined ) { // might not be defined at this line, which is OKAY!
918+ tbl . append ( '<tr><td class="stackFrameVar">' + varname + '</td><td class="stackFrameValue"></td></tr>' ) ;
919+ var curTr = tbl . find ( 'tr:last' ) ;
916920
917- // make sure varname doesn't contain any weird
918- // characters that are illegal for CSS ID's ...
919- var varDivID = 'global__' + varnameToCssID ( varname ) ;
920- curTr . find ( "td.stackFrameValue" ) . append ( '<div id="' + varDivID + '"> </div>' ) ;
921+ if ( isPrimitiveType ( val ) ) {
922+ renderPrimitiveObject ( val , curTr . find ( "td.stackFrameValue" ) ) ;
923+ }
924+ else {
925+ // add a stub so that we can connect it with a connector later.
926+ // IE needs this div to be NON-EMPTY in order to properly
927+ // render jsPlumb endpoints, so that's why we add an " "!
921928
922- assert ( connectionEndpointIDs [ varDivID ] === undefined ) ;
923- var heapObjID = 'heap_object_' + getObjectID ( val ) ;
924- connectionEndpointIDs [ varDivID ] = heapObjID ;
925- }
929+ // make sure varname doesn't contain any weird
930+ // characters that are illegal for CSS ID's ...
931+ var varDivID = 'global__' + varnameToCssID ( varname ) ;
932+ curTr . find ( "td.stackFrameValue" ) . append ( '<div id="' + varDivID + '"> </div>' ) ;
933+
934+ assert ( connectionEndpointIDs [ varDivID ] === undefined ) ;
935+ var heapObjID = 'heap_object_' + getRefID ( val ) ;
936+ connectionEndpointIDs [ varDivID ] = heapObjID ;
926937 }
927- } ) ;
928- }
938+ }
939+ } ) ;
929940 }
930941
942+
943+ $ . each ( stack_to_render , function ( i , e ) {
944+ renderStackFrame ( e , i , e . is_zombie ) ;
945+ } ) ;
946+
947+
931948 function renderStackFrame ( frame , ind , is_zombie ) {
932949 var funcName = htmlspecialchars ( frame . func_name ) ; // might contain '<' or '>' for weird names like <genexpr>
933950 var frameID = frame . frame_id ; // optional (btw, this isn't a CSS id)
@@ -965,7 +982,6 @@ function renderDataStructures(curEntry, vizDiv) {
965982 }
966983 $ ( vizDiv + " #stack #" + divID ) . append ( '<div id="' + headerDivID + '" class="stackFrameHeader">' + headerLabel + '</div>' ) ;
967984
968-
969985 if ( frame . ordered_varnames . length > 0 ) {
970986 var tableID = divID + '_table' ;
971987 $ ( vizDiv + " #stack #" + divID ) . append ( '<table class="stackFrameVarTable" id="' + tableID + '"></table>' ) ;
@@ -996,8 +1012,8 @@ function renderDataStructures(curEntry, vizDiv) {
9961012
9971013 var curTr = tbl . find ( 'tr:last' ) ;
9981014
999- if ( renderInline ( val ) ) {
1000- renderData ( val , curTr . find ( "td.stackFrameValue" ) , false /* don't wrap it in a .heapObject div */ ) ;
1015+ if ( isPrimitiveType ( val ) ) {
1016+ renderPrimitiveObject ( val , curTr . find ( "td.stackFrameValue" ) ) ;
10011017 }
10021018 else {
10031019 // add a stub so that we can connect it with a connector later.
@@ -1014,127 +1030,11 @@ function renderDataStructures(curEntry, vizDiv) {
10141030 connectionEndpointIDs [ varDivID ] = heapObjID ;
10151031 }
10161032 } ) ;
1017-
1018- }
1019-
1020- }
1021-
1022-
1023- // first render the stack (and global vars)
1024- renderGlobals ( ) ;
1025-
1026- // merge zombie_stack_locals and stack_locals into one master
1027- // ordered list using some simple rules for aesthetics
1028- var stack_to_render = [ ] ;
1029-
1030- // first push all regular stack entries backwards
1031- if ( curEntry . stack_locals ) {
1032- for ( var i = curEntry . stack_locals . length - 1 ; i >= 0 ; i -- ) {
1033- var entry = curEntry . stack_locals [ i ] ;
1034- entry . is_zombie = false ;
1035- entry . is_highlighted = ( i == 0 ) ;
1036- stack_to_render . push ( entry ) ;
1037- }
1038- }
1039-
1040- // zombie stack consists of exited functions that have returned nested functions
1041- // push zombie stack entries at the BEGINNING of stack_to_render,
1042- // EXCEPT put zombie entries BEHIND regular entries that are their parents
1043- if ( curEntry . zombie_stack_locals ) {
1044-
1045- for ( var i = curEntry . zombie_stack_locals . length - 1 ; i >= 0 ; i -- ) {
1046- var entry = curEntry . zombie_stack_locals [ i ] ;
1047- entry . is_zombie = true ;
1048- entry . is_highlighted = false ; // never highlight zombie entries
1049-
1050- // j should be 0 most of the time, so we're always inserting new
1051- // elements to the front of stack_to_render (which is why we are
1052- // iterating backwards over zombie_stack_locals).
1053- var j = 0 ;
1054- for ( j = 0 ; j < stack_to_render . length ; j ++ ) {
1055- if ( $ . inArray ( stack_to_render [ j ] . frame_id , entry . parent_frame_id_list ) >= 0 ) {
1056- continue ;
1057- }
1058- break ;
1059- }
1060-
1061- stack_to_render . splice ( j , 0 , entry ) ;
10621033 }
1063-
10641034 }
10651035
10661036
1067- $ . each ( stack_to_render , function ( i , e ) {
1068- renderStackFrame ( e , i , e . is_zombie ) ;
1069- } ) ;
1070-
1071-
1072- // then render the heap
1073-
1074- alreadyRenderedObjectIDs = { } ; // set of object IDs that have already been rendered
1075-
1076- // if addToEnd is true, then APPEND to the end of the heap,
1077- // otherwise PREPEND to the front
1078- function renderHeapObjectDEPRECATED ( obj , addToEnd ) {
1079- var objectID = getObjectID ( obj ) ;
1080-
1081- if ( alreadyRenderedObjectIDs [ objectID ] === undefined ) {
1082- var toplevelHeapObjID = 'toplevel_heap_object_' + objectID ;
1083- var newDiv = '<table class="heapRow"><tr><td class="toplevelHeapObject" id="' + toplevelHeapObjID + '"></td></tr></table>' ;
1084-
1085- if ( addToEnd ) {
1086- $ ( vizDiv + ' #heap' ) . append ( newDiv ) ;
1087- }
1088- else {
1089- $ ( vizDiv + ' #heap' ) . prepend ( newDiv ) ;
1090- }
1091- renderData ( obj , $ ( vizDiv + ' #heap #' + toplevelHeapObjID ) , true ) ;
1092-
1093- alreadyRenderedObjectIDs [ objectID ] = 1 ;
1094- }
1095- }
1096-
1097-
1098- // if there are multiple aliases to the same object, we want to render
1099- // the one deepest in the stack, so that we can hopefully prevent
1100- // objects from jumping around as functions are called and returned.
1101- // e.g., if a list L appears as a global variable and as a local in a
1102- // function, we want to render L when rendering the global frame.
1103-
1104- // this is straightforward: just go through globals first and then
1105- // each stack frame in order :)
1106-
1107- $ . each ( curEntry . ordered_globals , function ( i , varname ) {
1108- var val = curEntry . globals [ varname ] ;
1109- if ( ! renderInline ( val ) ) {
1110- renderHeapObject ( val , true ) ; // APPEND
1111- }
1112- } ) ;
1113-
1114-
1115- $ . each ( stack_to_render , function ( i , frame ) {
1116- var localVars = frame . encoded_locals ;
1117-
1118- $ . each ( frame . ordered_varnames , function ( i2 , varname ) {
1119-
1120- // don't render return values for zombie frames
1121- if ( frame . is_zombie && varname == '__return__' ) {
1122- return ;
1123- }
1124-
1125- var val = localVars [ varname ] ;
1126- if ( ! renderInline ( val ) ) {
1127- renderHeapObject ( val , true ) ; // APPEND
1128- }
1129- } ) ;
1130- } ) ;
1131-
1132-
1133- // prepend heap header after all the dust settles:
1134- $ ( vizDiv + ' #heap' ) . prepend ( '<div id="heapHeader">Objects</div>' ) ;
1135-
1136-
1137- // finally connect stack variables to heap objects via connectors
1037+ // finally add all the connectors!
11381038 for ( varID in connectionEndpointIDs ) {
11391039 var valueID = connectionEndpointIDs [ varID ] ;
11401040 jsPlumb . connect ( { source : varID , target : valueID } ) ;
0 commit comments