@@ -378,12 +378,15 @@ function renderDataStructuresVersion1(curEntry, vizDiv) {
378378//
379379// This version was originally created in September 2011
380380function renderDataStructuresVersion2 ( curEntry , vizDiv ) {
381- console . log ( curEntry ) ;
381+ // console.log(curEntry);
382382
383383 $ ( vizDiv ) . html ( '' ) ; // CLEAR IT!
384384
385+ // create a tabular layout for stack and heap side-by-side
386+ // TODO: figure out how to do this using CSS in a robust way!
387+ $ ( vizDiv ) . html ( '<table id="stackHeapTable"><tr><td><div id="stack"></div></td><td><div id="heap"></div></td></tr></table>' ) ;
388+
385389 // first render the stack (and global vars)
386- $ ( vizDiv ) . append ( '<div id="stack"></div>' ) ;
387390
388391 // render locals on stack:
389392 if ( curEntry . stack_locals != undefined ) {
@@ -460,10 +463,12 @@ function renderDataStructuresVersion2(curEntry, vizDiv) {
460463 }
461464 }
462465
466+
467+ // render all global variables IN THE ORDER they were created by the program,
468+ // in order to ensure continuity:
469+ var orderedGlobals = [ ]
470+
463471 if ( nonEmptyGlobals ) {
464- // render all global variables IN THE ORDER they were created by the program,
465- // in order to ensure continuity:
466- var orderedGlobals = [ ]
467472
468473 // iterating over ALL instructions up to curInstr
469474 // (could be SLOW if not for our optimization below)
@@ -531,13 +536,99 @@ function renderDataStructuresVersion2(curEntry, vizDiv) {
531536
532537 // then render the heap
533538
539+ alreadyRenderedObjectIDs = { } ; // set of object IDs that have already been rendered
540+
541+ // now go BACKWARDS starting at globals and then crawling up the stack
542+ // from bottom to top, so that we can hopefully prevent objects from
543+ // jumping around
544+
545+ orderedGlobals . reverse ( ) ; // so that we can iterate backwards
546+
547+ $ . each ( orderedGlobals , function ( i , varname ) {
548+ var val = curEntry . globals [ varname ] ;
549+
550+ // remember that primitive types are already rendered in the stack
551+ if ( ! isPrimitiveType ( val ) ) {
552+ var objectID = getObjectID ( val ) ;
553+
554+ // don't double-render objects with the same ID
555+ if ( alreadyRenderedObjectIDs [ objectID ] === undefined ) {
556+ var heapObjID = 'heap_object_' + objectID ;
557+
558+ // use prepend to push in front
559+ $ ( vizDiv + ' #heap' ) . prepend ( '<div class="heapObject" id="' + heapObjID + '"></div>' ) ;
560+ renderData ( val , $ ( vizDiv + ' #heap #' + heapObjID ) ) ;
561+
562+ alreadyRenderedObjectIDs [ objectID ] = 1 ;
563+ }
564+ }
565+ } ) ;
566+
567+
568+ if ( curEntry . stack_locals != undefined ) {
569+ // go BACKWARDS
570+ for ( var i = curEntry . stack_locals . length - 1 ; i >= 0 ; i -- ) {
571+ var frame = curEntry . stack_locals [ i ] ;
572+ var funcName = htmlspecialchars ( frame [ 0 ] ) ; // might contain '<' or '>' for weird names like <genexpr>
573+ var localVars = frame [ 1 ] ;
574+
575+ // the stackFrame div's id is simply its index ("stack<index>")
576+ var divID = "stack" + i ;
577+
578+ var orderedVarnames = [ ] ;
579+
580+ // use plain ole' iteration rather than jQuery $.each() since
581+ // the latter breaks when a variable is named "length"
582+ for ( varname in localVars ) {
583+ orderedVarnames . push ( varname ) ;
584+ }
585+ orderedVarnames . sort ( ) ;
586+
587+ orderedVarnames . reverse ( ) ; // so that we can iterate backwards
588+
589+ if ( orderedVarnames . length > 0 ) {
590+ $ . each ( orderedVarnames , function ( i , varname ) {
591+ var val = localVars [ varname ] ;
592+
593+ if ( ! isPrimitiveType ( val ) ) {
594+ var objectID = getObjectID ( val ) ;
595+
596+ if ( alreadyRenderedObjectIDs [ objectID ] === undefined ) {
597+ var heapObjID = 'heap_object_' + objectID ;
598+ // use prepend to push in front
599+ $ ( vizDiv + ' #heap' ) . prepend ( '<div class="heapObject" id="' + heapObjID + '"></div>' ) ;
600+ renderData ( val , $ ( vizDiv + ' #heap #' + heapObjID ) ) ;
601+
602+ alreadyRenderedObjectIDs [ objectID ] = 1 ;
603+ }
604+
605+ }
606+ } ) ;
607+ }
608+ }
609+ }
610+
611+
534612 // finally connect stack variables to heap objects via connectors
535613
536614}
537615
538616function isPrimitiveType ( obj ) {
539617 var typ = typeof obj ;
540- return ( ( obj == null ) || ( typ == "number" ) || ( typ == "boolean" ) || ( typ == "string" ) ) ;
618+ return ( ( obj == null ) || ( typ != "object" ) ) ;
619+ }
620+
621+ function getObjectID ( obj ) {
622+ // pre-condition
623+ assert ( ! isPrimitiveType ( obj ) ) ;
624+ assert ( $ . isArray ( obj ) ) ;
625+
626+ if ( ( obj [ 0 ] == 'INSTANCE' ) || ( obj [ 0 ] == 'CLASS' ) ) {
627+ return obj [ 2 ] ;
628+ }
629+ else {
630+ return obj [ 1 ] ;
631+ }
541632}
542633
543634
0 commit comments