Skip to content

Commit 9ca63bb

Browse files
author
Philip Guo
committed
on we march ...
1 parent f4dc20d commit 9ca63bb

2 files changed

Lines changed: 106 additions & 11 deletions

File tree

edu-python.css

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ span {
9494
margin-bottom: 40px;
9595
}
9696

97+
table#stackHeapTable td {
98+
vertical-align:top;
99+
}
97100

98101
table#pyOutputPane {
99102
padding: 15px;
@@ -244,7 +247,8 @@ button.bigBtn {
244247
}
245248

246249
.customObj {
247-
font-style: italic;
250+
font-family: Andale mono, monospace;
251+
/*font-style: italic;*/
248252
font-size: 10pt;
249253
}
250254

@@ -423,8 +427,8 @@ td.dictKey .typeLabel {
423427
div#stack {
424428
float: left;
425429
padding-left: 10px;
426-
padding-right: 35px;
427-
border-right: 1px dashed #cccccc;
430+
padding-right: 30px;
431+
border-right: 1px dashed #bbbbbb;
428432
}
429433

430434
div.stackFrame {
@@ -449,7 +453,7 @@ div.topStackFrame {
449453
border-left: 1px solid #F15149;
450454
}
451455

452-
div.stackFrame div.stackFrameHeader {
456+
div.stackFrameHeader {
453457
font-family: Andale mono, monospace;
454458
font-size: 10pt;
455459
margin-top: 4px;
@@ -484,7 +488,7 @@ div.stackFrame .stackFrameVarTable {
484488

485489
div#heap {
486490
float: left;
487-
padding-left: 35px;
491+
padding-left: 30px;
488492
}
489493

490494
div.heapObject {

edu-python.js

Lines changed: 97 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -378,12 +378,15 @@ function renderDataStructuresVersion1(curEntry, vizDiv) {
378378
//
379379
// This version was originally created in September 2011
380380
function 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

538616
function 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

Comments
 (0)