Skip to content

Commit d93927b

Browse files
author
Philip Guo
committed
yay
1 parent e60e744 commit d93927b

File tree

1 file changed

+59
-159
lines changed

1 file changed

+59
-159
lines changed

PyTutorGAE/js/edu-python.js

Lines changed: 59 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -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 "&nbsp;"!
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 + '">&nbsp;</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 "&nbsp;"!
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 + '">&nbsp;</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

Comments
 (0)