diff --git a/js-assembler/package.rkt b/js-assembler/package.rkt index 35aee10..8ac1e58 100644 --- a/js-assembler/package.rkt +++ b/js-assembler/package.rkt @@ -410,60 +410,7 @@ EOF @@ -472,6 +419,7 @@ var invokeMainModule = function() { EOF js + invoke-main-module-code )) @@ -522,7 +470,7 @@ var invokeMainModule = function() { } }, function(MACHINE, e) { - var contMarkSet, appNames, i, appName; + var contMarkSet, context, i, appName; // On main module invokation failure if (window.console && window.console.log) { window.console.log(e.stack || e); @@ -535,19 +483,27 @@ var invokeMainModule = function() { plt.baselib.exceptions.isExn(e.racketError)) { contMarkSet = plt.baselib.exceptions.exnContMarks(e.racketError); if (contMarkSet) { - appNames = contMarkSet.ref(plt.runtime.getTracedAppKey(MACHINE)); - while (plt.baselib.lists.isPair(appNames)) { - appName = appNames.first; - MACHINE.params.currentErrorDisplayer( - MACHINE, - $('
').text(' at ' + appName.elts[0] + - ', line ' + appName.elts[2] + - ', column ' + appName.elts[3]) - .addClass('stacktrace') - .css('margin-left', '10px') - .css('whitespace', 'pre') - .css('color', 'red')); - appNames = appNames.rest; + context = contMarkSet.getContext(MACHINE); + for (i = 0; i < context.length; i++) { + if (plt.runtime.isVector(context[i])) { + MACHINE.params.currentErrorDisplayer( + MACHINE, + $('
').text(' at ' + context[i].elts[0] + + ', line ' + context[i].elts[2] + + ', column ' + context[i].elts[3]) + .addClass('stacktrace') + .css('margin-left', '10px') + .css('whitespace', 'pre') + .css('color', 'red')); + } else if (plt.runtime.isProcedure(context[i])) { + MACHINE.params.currentErrorDisplayer( + MACHINE, + $('
').text(' in ' + context[i].displayName) + .addClass('stacktrace') + .css('margin-left', '10px') + .css('whitespace', 'pre') + .css('color', 'red')); + } } } } diff --git a/js-assembler/runtime-src/baselib-contmarks.js b/js-assembler/runtime-src/baselib-contmarks.js index c836ac7..62d5dab 100644 --- a/js-assembler/runtime-src/baselib-contmarks.js +++ b/js-assembler/runtime-src/baselib-contmarks.js @@ -1,3 +1,4 @@ +/*global plt*/ /*jslint browser: true, unparam: true, vars: true, white: true, maxerr: 50, indent: 4 */ // Continuation marks @@ -42,6 +43,37 @@ + // Returns an approximate stack trace. + // getContext: MACHINE -> (arrayof (U Procedure (Vector source line column position span))) + ContinuationMarkSet.prototype.getContext = function(MACHINE) { + var i, j; + var result = []; + var kvlist; + + var tracedAppKey = plt.runtime.getTracedAppKey(MACHINE); + var tracedCalleeKey = plt.runtime.getTracedCalleeKey(MACHINE); + var proc, locationVector; + + for (i = 0; i < this.kvlists.length; i++) { + kvlist = this.kvlists[i]; + for (j = 0; j < kvlist.length; j++) { + if (kvlist[j][0] === tracedAppKey) { + locationVector = kvlist[j][1]; + result.push(locationVector); + } else if (kvlist[j][0] === tracedCalleeKey) { + proc = kvlist[j][1]; + if (proc !== null) { + result.push(proc); + } + } + } + } + return result; + }; + + + + // A continuation prompt tag labels a prompt frame. var ContinuationPromptTag = function(name) { diff --git a/js-assembler/runtime-src/baselib-functions.js b/js-assembler/runtime-src/baselib-functions.js index e4e9953..9f659cb 100644 --- a/js-assembler/runtime-src/baselib-functions.js +++ b/js-assembler/runtime-src/baselib-functions.js @@ -184,7 +184,7 @@ }; MACHINE.control.push( - new baselib.frames.CallFrame(afterGoodInvoke, null)); + new baselib.frames.CallFrame(afterGoodInvoke, v)); MACHINE.argcount = arguments.length - 2; var i; for (i = 0; i < arguments.length - 2; i++) { @@ -281,7 +281,7 @@ }; MACHINE.control.push( - new baselib.frames.CallFrame(afterGoodInvoke, null)); + new baselib.frames.CallFrame(afterGoodInvoke, proc)); MACHINE.argcount = arguments.length - 4; for (i = 0; i < arguments.length - 4; i++) { MACHINE.env.push(arguments[arguments.length - 1 - i]); diff --git a/js-assembler/runtime-src/runtime.js b/js-assembler/runtime-src/runtime.js index 6a2fd27..6f9d636 100644 --- a/js-assembler/runtime-src/runtime.js +++ b/js-assembler/runtime-src/runtime.js @@ -270,6 +270,22 @@ }; + // Try to get the continuation mark key used for procedure application tracing. + var getTracedAppKey = function(MACHINE) { + if (MACHINE.modules['whalesong/lang/private/traced-app.rkt']) { + return MACHINE.modules['whalesong/lang/private/traced-app.rkt'].namespace['traced-app-key']; + } + return undefined; + }; + + var getTracedCalleeKey = function(MACHINE) { + if (MACHINE.modules['whalesong/lang/private/traced-app.rkt']) { + return MACHINE.modules['whalesong/lang/private/traced-app.rkt'].namespace['traced-callee-key']; + } + return undefined; + }; + + // captureControl implements the continuation-capturing part of // call/cc. It grabs the control frames up to (but not including) the @@ -360,10 +376,17 @@ var kvLists = []; var i; var control = this.control; + var tracedCalleeKey = getTracedCalleeKey(this); for (i = control.length-1; i >= 0; i--) { if (control[i].marks.length !== 0) { kvLists.push(control[i].marks); } + + if (tracedCalleeKey !== null && + control[i] instanceof CallFrame && + control[i].proc !== null) { + kvLists.push([[tracedCalleeKey, control[i].proc]]); + } } return new baselib.contmarks.ContinuationMarkSet(kvLists); }; @@ -424,7 +447,6 @@ var MACHINE = this; var thunk = initialJump; var startTime = (new Date()).valueOf(); - var contMarks; MACHINE.callsBeforeTrampoline = STACK_LIMIT_ESTIMATE; MACHINE.params.numBouncesBeforeYield = MACHINE.params.maxNumBouncesBeforeYield; @@ -509,13 +531,8 @@ - // Try to get the continuation mark key used for procedure application tracing. - var getTracedAppKey = function(MACHINE) { - if (MACHINE.modules['whalesong/lang/private/traced-app.rkt']) { - return MACHINE.modules['whalesong/lang/private/traced-app.rkt'].namespace['traced-app-key']; - } - return undefined; - }; + + @@ -732,6 +749,7 @@ exports['isNumber'] = isNumber; exports['isNatural'] = isNatural; exports['isReal'] = isReal; + exports['isProcedure'] = plt.baselib.functions.isProcedure; exports['equals'] = equals; exports['toDomNode'] = toDomNode; @@ -755,5 +773,6 @@ exports['StructType'] = StructType; exports['getTracedAppKey'] = getTracedAppKey; + exports['getTracedCalleeKey'] = getTracedCalleeKey; }(this.plt, this.plt.baselib)); \ No newline at end of file diff --git a/lang/private/traced-app.rkt b/lang/private/traced-app.rkt index ef595c1..738ee4b 100644 --- a/lang/private/traced-app.rkt +++ b/lang/private/traced-app.rkt @@ -2,9 +2,10 @@ (require (for-syntax racket/base)) -(provide traced-app traced-app-key) +(provide traced-app traced-app-key traced-callee-key) (define traced-app-key (gensym 'traced-app-key)) +(define traced-callee-key (gensym 'traced-callee-key)) (define-syntax-parameter traced-app