Author: ptw
Date: 2007-09-05 05:53:39 -0700 (Wed, 05 Sep 2007)
New Revision: 6361
Modified:
openlaszlo/branches/wafflecone/WEB-INF/lps/lfc/compiler/LzRuntime.lzs
openlaszlo/branches/wafflecone/WEB-INF/lps/lfc/debugger/LzBacktrace.lzs
openlaszlo/branches/wafflecone/WEB-INF/lps/lfc/debugger/LzMessage.lzs
openlaszlo/branches/wafflecone/WEB-INF/lps/lfc/debugger/platform/dhtml/LzDebug.js
openlaszlo/branches/wafflecone/WEB-INF/lps/lfc/debugger/platform/swf/LzDebug.as
openlaszlo/branches/wafflecone/WEB-INF/lps/server/src/org/openlaszlo/sc/CodeGenerator.java
openlaszlo/branches/wafflecone/WEB-INF/lps/server/src/org/openlaszlo/sc/Compiler.java
openlaszlo/branches/wafflecone/WEB-INF/lps/server/src/org/openlaszlo/sc/JavascriptGenerator.java
Log:
Change 20070903-ptw-a by [EMAIL PROTECTED] on 2007-09-03 18:01:48 EDT
in /Users/ptw/OpenLaszlo/wafflecone-2
for http://svn.openlaszlo.org/openlaszlo/branches/wafflecone
Summary: Add file/line information to backtraces
Bugs Fixed:
LPP-4549 'runtime warnings should include file references, line #s'
Technical Reviewer: max (Message-ID: <[EMAIL PROTECTED]>), [EMAIL PROTECTED]
(pending)
QA Reviewer: ewinard (pending)
Details:
LzMessage: Get file/line information from backtrace if available,
tweak format of locationString.
LzDebug.*: correct padding computation for computeSlotDescription.
LzDebug.js: _dbg_name takes precedence over runtime function name.
LzBacktrace, LzRuntime: Move backtraceStack creation to runtime so it is
available as early as needed.
LzBacktrace: Add __LzStackFrame.isUserFrame,
.filename, .lineno. Update _dbg_name to display file and line
information. Add LzBacktrace.userStackFrame to get first non-LFC
frame from a backtrace.
Compiler: Correct precedence computations for unparser, ensure
parens are added in all the appropriate places. Needed to handle
expression-lists that backtrace annotation inserts.
JavascriptGenerator, CodeGenerator: Copy location info when
re-writing functions. Note line numbers of call sites for
backtrace. Note file and line on functions for backtraces.
Tests:
smokecheck with backtrace on shows file/line information in debug
messages and in backtraces.
Modified: openlaszlo/branches/wafflecone/WEB-INF/lps/lfc/compiler/LzRuntime.lzs
===================================================================
--- openlaszlo/branches/wafflecone/WEB-INF/lps/lfc/compiler/LzRuntime.lzs
2007-09-05 05:18:10 UTC (rev 6360)
+++ openlaszlo/branches/wafflecone/WEB-INF/lps/lfc/compiler/LzRuntime.lzs
2007-09-05 12:53:39 UTC (rev 6361)
@@ -189,6 +189,15 @@
*/
var Debug = new Object;
+ /** Backtrace stack
+ * @access private
+ */
+ Debug.backtraceStack = new Array();
+ /** Max depth allowed
+ * @access private
+ */
+ Debug.backtraceStack.maxDepth = 100;
+
/**
* Doc'd on real definition
* Bootstrap version
Modified:
openlaszlo/branches/wafflecone/WEB-INF/lps/lfc/debugger/LzBacktrace.lzs
===================================================================
--- openlaszlo/branches/wafflecone/WEB-INF/lps/lfc/debugger/LzBacktrace.lzs
2007-09-05 05:18:10 UTC (rev 6360)
+++ openlaszlo/branches/wafflecone/WEB-INF/lps/lfc/debugger/LzBacktrace.lzs
2007-09-05 12:53:39 UTC (rev 6361)
@@ -12,16 +12,10 @@
*/
// Support for backtraces in the debugger
+// -- Declared in LzRuntime
+// Debug.backtraceStack = new Array();
+// Debug.backtraceStack.maxDepth = 100;
-/** Backtrace stack
- * @access private
- */
-Debug.backtraceStack = new Array();
-/** Max depth allowed
- * @access private
- */
-Debug.backtraceStack.maxDepth = 100;
-
{
#pragma "debugBacktrace=false"
/** @access private */
@@ -59,17 +53,45 @@
var __LzStackFrame = function (args) {
if (args instanceof Array) {
this['this'] = args['this'];
- this['function'] = args['callee'];
+ this['function'] = args.callee;
+ this.__lineno = ('lineno' in args) ? args.lineno :
this['function']._dbg_lineno;
}
this.arguments = args;
}
/**
+ * Is this a user stack frame?
+ * @access private
+ */
+ __LzStackFrame.prototype.isUserFrame = function () {
+ return this['function']._dbg_filename.indexOf('lfc') != 0;
+ }
+
+/**
+ * Filename associated with a stack frame
+ * @access private
+ */
+ __LzStackFrame.prototype.filename = function () {
+ return this['function']._dbg_filename;
+ }
+
+/**
+ * Lineno associated with a stack frame
+ * @access private
+ */
+ __LzStackFrame.prototype.lineno = function () {
+ return this.__lineno;
+ }
+
+/**
* Debug printer
* @access private
*/
__LzStackFrame.prototype._dbg_name = function () {
- return Debug.formatToString('%0.72w.apply(%w, %w)', this['function'],
this['this'], this.arguments);
+ var callee = this['function'];
+ var filename = callee._dbg_filename;
+ var lineno = this.__lineno;
+ return Debug.formatToString('%0.64w @%s#%d', callee, filename, lineno);
}
/**
@@ -98,8 +120,9 @@
for (var i = 0; i < l; i++) {
var fr = bs[i];
// Reuse stack frames so they are unique
- if (! fr.hasOwnProperty('__LzStackFrame')) {
-#pragma "passThrough=true"
+ if ((! fr.hasOwnProperty('__LzStackFrame')) ||
+ // Bad modularity
+ (fr.lineno != fr.__LzStackFrame.__lineno)) {
fr.__LzStackFrame = new __LzStackFrame(fr);
}
this[i] = fr.__LzStackFrame;
@@ -113,6 +136,19 @@
// LzBacktrace.prototype.constructor = LzBacktrace;
/**
+ * Find the topmost user stack frame
+ * @access private
+ */
+ LzBacktrace.prototype.userStackFrame = function () {
+ for (var i = this.length - 1; i >= 0; i--) {
+ var fr = this[i];
+ if (fr.isUserFrame()) {
+ return fr;
+ }
+ }
+ }
+
+/**
* Convert a backtrace to a string
* @param printer:Function the function to print the backtrace
* functions with. Defaults to Debug.__String
@@ -157,6 +193,12 @@
}
/**
+ * Debug printer
+ * @access private
+ */
+LzBacktrace.prototype._dbg_typename = "Backtrace";
+
+/**
* Snapshot the current call stack into a LzBacktrace object which
* can be printed or inspected
*
Modified: openlaszlo/branches/wafflecone/WEB-INF/lps/lfc/debugger/LzMessage.lzs
===================================================================
--- openlaszlo/branches/wafflecone/WEB-INF/lps/lfc/debugger/LzMessage.lzs
2007-09-05 05:18:10 UTC (rev 6360)
+++ openlaszlo/branches/wafflecone/WEB-INF/lps/lfc/debugger/LzMessage.lzs
2007-09-05 12:53:39 UTC (rev 6361)
@@ -14,10 +14,16 @@
/**
* A message is a string with annotations for the objects represented.
+ *
+ * This replaces the bootstrap LzMessage class in
+ * compiler/LzFormatter
+ *
* @param String message: initial message
* @access private
+ *
+ * @devnote TODO: [2007-09-05 ptw] Convert to class declaration
*/
-var LzMessage = function (message) {
+var LzMessage = function LzMessage (message) {
// A Message would like to be a subclass of string, but mutable
// TODO: [2006-04-11 ptw] Make this a real class
this.constructor = arguments.callee;
@@ -255,7 +261,7 @@
* @seealso LzSourceMessage.format
* @access private
*/
-var LzSourceMessage = function (file, line, message) {
+function LzSourceMessage (file, line, message) {
switch (arguments.length) {
case 0:
file = null;
@@ -264,13 +270,6 @@
case 2:
message = '';
}
- this.file = file;
- this.line = line;
- if (message instanceof LzMessage) {
- this.message = message;
- } else {
- this.message = new LzMessage(message);
- }
// Append a backtrace if there is one -- skip back to the
// $reportSourceWarning or warnInternal frames.
if ('backtraceStack' in Debug) {
@@ -288,12 +287,25 @@
}
if (Debug.backtraceStack.length > skip) {
this.backtrace = Debug.backtrace(skip);
+ // Heuristicate file/line from backtrace if available
+ if (file == null && this.backtrace) {
+ var top = this.backtrace.userStackFrame();
+ if (top) {
+ file = top.filename();
+ line = top.lineno();
+ }
+ }
}
}
+ this.file = file;
+ this.line = line;
+ if (message instanceof LzMessage) {
+ this.message = message;
+ } else {
+ this.message = new LzMessage(message);
+ }
}
-/* Correct constructor */
-LzSourceMessage.prototype.constructor = LzSourceMessage;
LzSourceMessage.prototype.type = '';
LzSourceMessage.prototype.color = '#000000';
@@ -343,17 +355,16 @@
* Get the location as a string
*/
LzSourceMessage.prototype.locationString = function () {
- var str = this.type + ':';
+ var str = this.type;
if (this.file) {
- str += ' ';
+ str += ' @';
str += this.file;
- str += ':';
if (this.line) {
+ str += '#';
str += this.line;
- str += ':';
}
}
- str += ' ';
+ str += ': ';
return str;
}
@@ -407,7 +418,7 @@
* An Warn is a sourceMessage with the tag 'WARN'
* @access private
*/
-var LzWarning = function(file, line, message) {
+function LzWarning (file, line, message) {
// super.apply(arguments);
LzSourceMessage.apply(this, arguments);
}
@@ -423,7 +434,7 @@
* An Error is a sourceMessage with the tag 'ERROR'
* @access private
*/
-var LzError = function(file, line, message) {
+function LzError (file, line, message) {
// super.apply(arguments);
LzSourceMessage.apply(this, arguments);
}
@@ -438,7 +449,7 @@
* An Info is a sourceMessage with the tag 'INFO'
* @access private
*/
-var LzInfo = function(file, line, message) {
+function LzInfo (file, line, message) {
// super.apply(arguments);
LzSourceMessage.apply(this, arguments);
}
@@ -453,7 +464,7 @@
* An Debug is a sourceMessage with the tag 'DEBUG'
* @access private
*/
-var LzDebug = function(file, line, message) {
+function LzDebug (file, line, message) {
// super.apply(arguments);
LzSourceMessage.apply(this, arguments);
}
Modified:
openlaszlo/branches/wafflecone/WEB-INF/lps/lfc/debugger/platform/dhtml/LzDebug.js
===================================================================
---
openlaszlo/branches/wafflecone/WEB-INF/lps/lfc/debugger/platform/dhtml/LzDebug.js
2007-09-05 05:18:10 UTC (rev 6360)
+++
openlaszlo/branches/wafflecone/WEB-INF/lps/lfc/debugger/platform/dhtml/LzDebug.js
2007-09-05 12:53:39 UTC (rev 6361)
@@ -94,13 +94,16 @@
*/
Debug.functionName = function (fn, mustBeUnique) {
if (fn && (fn instanceof Function)) {
- // tip o' the pin to osteele.com
- var fstring = fn.toString();
- var m = fstring.match(this.functionNamePattern);
- if (m) {
- var n = m[1];
- } else if (fn.hasOwnProperty('_dbg_name')) {
+ // _dbg_name takes precedence over the actual function name
+ if (fn.hasOwnProperty('_dbg_name')) {
var n = fn._dbg_name;
+ } else {
+ // tip o' the pin to osteele.com
+ var fstring = fn.toString();
+ var m = fstring.match(this.functionNamePattern);
+ if (m) {
+ var n = m[1];
+ }
}
if (n) {
if ((! mustBeUnique) || (fn === global[n])) {
@@ -550,6 +553,7 @@
*/
Debug.computeSlotDescription = function (obj, key, val, wid) {
var r = key + ':';
+ wid++;
try {
// Annotate 'weight' if available
if (this.markGeneration > 0) {
Modified:
openlaszlo/branches/wafflecone/WEB-INF/lps/lfc/debugger/platform/swf/LzDebug.as
===================================================================
---
openlaszlo/branches/wafflecone/WEB-INF/lps/lfc/debugger/platform/swf/LzDebug.as
2007-09-05 05:18:10 UTC (rev 6360)
+++
openlaszlo/branches/wafflecone/WEB-INF/lps/lfc/debugger/platform/swf/LzDebug.as
2007-09-05 12:53:39 UTC (rev 6361)
@@ -614,6 +614,7 @@
*/
Debug.computeSlotDescription = function (obj, key, val, wid) {
var r = key + ':';
+ wid++;
// Annotate 'weight' if available
if (this.markGeneration > 0) {
var annotation = this.annotation;
Modified:
openlaszlo/branches/wafflecone/WEB-INF/lps/server/src/org/openlaszlo/sc/CodeGenerator.java
===================================================================
---
openlaszlo/branches/wafflecone/WEB-INF/lps/server/src/org/openlaszlo/sc/CodeGenerator.java
2007-09-05 05:18:10 UTC (rev 6360)
+++
openlaszlo/branches/wafflecone/WEB-INF/lps/server/src/org/openlaszlo/sc/CodeGenerator.java
2007-09-05 12:53:39 UTC (rev 6361)
@@ -831,6 +831,7 @@
assert c.length == 3;
p.add(c[0]);
SimpleNode funexpr = new ASTFunctionExpression(0);
+ funexpr.setBeginLocation(n.filename, n.beginLine, n.beginColumn);
funexpr.setChildren(c);
p.add(funexpr);
} else if (n instanceof ASTVariableStatement) {
@@ -2028,6 +2029,22 @@
}
}
+ // Note current call-site in a function context and backtracing
+ if ((options.getBoolean(Compiler.DEBUG_BACKTRACE) && (node.beginLine !=
0)) &&
+ (context.findFunctionContext() != null)) {
+ Map registers = (Map)context.get(TranslationContext.REGISTERS);
+ // We know arguments register will exist if we are doing
+ // bactraces because it will be referenced in the function
+ // prefix.
+ if (registers != null && registers.containsKey("arguments")) {
+
collector.push(Values.Register(((Instructions.Register)registers.get("arguments")).regno));
+ collector.push("lineno");
+ collector.push(node.beginLine);
+ collector.emit(Instructions.SetMember);
+ }
+ }
+
+ // Okay, it is not going to be transformed. Just do it!
visitCallParameters(node, isReferenced, args);
boolean isref = translateReferenceForCall(fnexpr, true, node);
if (isref) {
@@ -2293,6 +2310,7 @@
return true;
}
+ // useName => declaration not expression
void translateFunction(SimpleNode node, boolean useName, SimpleNode[]
children) {
// label for profiling return
String label = newLabel(node);
@@ -2329,6 +2347,7 @@
}
// Internal helper function for above
+ // useName => declaration not expression
SimpleNode translateFunctionInternal(SimpleNode node, boolean useName,
SimpleNode[] children) {
// ast can be any of:
// FunctionDefinition(name, args, body)
@@ -2757,6 +2776,30 @@
collector.push("name");
collector.push(userFunctionName);
collector.emit(Instructions.SetMember);
+ if (options.getBoolean(Compiler.DEBUG_BACKTRACE)) {
+ // TODO: [2007-09-04 ptw] Come up with a better way to
+ // distinguish LFC from user stack frames. See
+ // lfc/debugger/LzBactrace
+ String fn = (options.getBoolean(Compiler.FLASH_COMPILER_COMPATABILITY)
? "lfc/" : "") + filename;
+ if (functionName != null) {
+ collector.push(functionName);
+ collector.emit(Instructions.GetVariable);
+ } else {
+ collector.emit(Instructions.DUP);
+ }
+ collector.push("_dbg_filename");
+ collector.push(fn);
+ collector.emit(Instructions.SetMember);
+ if (functionName != null) {
+ collector.push(functionName);
+ collector.emit(Instructions.GetVariable);
+ } else {
+ collector.emit(Instructions.DUP);
+ }
+ collector.push("_dbg_lineno");
+ collector.push(lineno);
+ collector.emit(Instructions.SetMember);
+ }
}
if (options.getBoolean(Compiler.CONSTRAINT_FUNCTION)) {
// assert (functionName != null);
Modified:
openlaszlo/branches/wafflecone/WEB-INF/lps/server/src/org/openlaszlo/sc/Compiler.java
===================================================================
---
openlaszlo/branches/wafflecone/WEB-INF/lps/server/src/org/openlaszlo/sc/Compiler.java
2007-09-05 05:18:10 UTC (rev 6360)
+++
openlaszlo/branches/wafflecone/WEB-INF/lps/server/src/org/openlaszlo/sc/Compiler.java
2007-09-05 12:53:39 UTC (rev 6361)
@@ -1035,6 +1035,9 @@
// TODO: [2005-11-17 ptw] Not quite right, but javacc doesn't
// tell us the range of its Ops
for (int i = 0; i < 256; i++) { on.add("<" + Integer.toString(i) + ">");
}
+ on.set(Ops.LPAREN, "(");
+ on.set(Ops.LBRACKET, "[");
+ on.set(Ops.DOT, ".");
on.set(Ops.ASSIGN, "=");
on.set(Ops.COMMA, ",");
on.set(Ops.GT, ">");
@@ -1088,22 +1091,14 @@
public String visitAssignmentExpression(SimpleNode node, String[]
children) {
int thisPrec = prec(((ASTOperator)node.get(1)).getOperator(), false);
- for (int i = 1; i < children.length; i += 2) {
- children[i] = maybeAddParens(thisPrec, node.get(i), children[i]);
- }
+ assert children.length == 3;
+ children[2] = maybeAddParens(thisPrec, node.get(2), children[2], true);
return children[0] + SPACE + children[1] + delimit(children [2], false);
}
public String visitCallExpression(SimpleNode node, String[] children) {
- SimpleNode c = node.get(0);
- // Only needed because our parser is broken
- if (c instanceof ASTFunctionExpression) {
- return "(" + children[0] + ")(" + children[1] + ")";
- } else {
- // CallExpression is prec 0, even though it has no operator
- // but associativity means you don't need parens
-// children[0] = maybeAddParens(0, c, children[0])
- return children[0] + "(" + children[1] + ")";
- }
+ int thisPrec = prec(Ops.LPAREN, true);
+ children[0] = maybeAddParens(thisPrec, node.get(0), children[0], true);
+ return children[0] + "(" + children[1] + ")";
}
public String visitSuperCallExpression(SimpleNode node, String[] children)
{
// Same as above
@@ -1111,7 +1106,7 @@
}
public String visitConditionalExpression(SimpleNode node, String[]
children) {
int thisPrec = prec(Ops.COLON, false);
- for (int i = 1; i < children.length; i++) {
+ for (int i = 0; i < children.length; i++) {
children[i] = maybeAddParens(thisPrec, node.get(i), children[i]);
}
return children[0] + CONDITIONAL + children[1] + ALTERNATIVE +
children[2];
@@ -1218,7 +1213,7 @@
public int prec(int op, boolean unary) {
String n = OperatorNames[op];
String classes[][] = {
- {"()", "[]", ".", "new"},
+ {"(", "[", ".", "new"},
{"!", "~", "-", "+", "--", "++", "typeof", "void", "delete"},
{"*", "/", "%"},
{"+", "-"},
@@ -1240,6 +1235,10 @@
}
public String visitArrayLiteral(SimpleNode node, String[] children) {
+ int thisPrec = prec(Ops.COMMA, false);
+ for (int i = 0; i < children.length; i++) {
+ children[i] = maybeAddParens(thisPrec, node.get(i), children[i],
false);
+ }
return "[" + join(COMMA, children) + "]";
}
@@ -1247,6 +1246,12 @@
return maybeAddParens(parentPrec, node, nodeRep, false);
}
+ // Set assoc to true if the sub-expression appears in a place
+ // where operator associativity implies the parens, e.g. on the
+ // left operand of a binary operator that is left-to-right
+ // associative. (It is always safe to leave it false, you will
+ // just end up with extra parens where you don't need them, which
+ // will impact compression but not correctness.)
public String maybeAddParens(int parentPrec, SimpleNode node, String
nodeRep, boolean assoc) {
int thisPrec = Integer.MAX_VALUE;
if (node instanceof ASTBinaryExpressionSequence ||
@@ -1264,14 +1269,31 @@
thisPrec = prec(Ops.COLON, false);
} else if (node instanceof ASTNewExpression) {
thisPrec = prec(Ops.NEW, true);
- } else if (node instanceof ASTCallExpression ||
- node instanceof ASTPropertyValueReference ||
- node instanceof ASTPropertyIdentifierReference) {
- // These have prec of 0 even though they don't have ops
- thisPrec = 0;
+ } else if (node instanceof ASTCallExpression) {
+ thisPrec = prec(Ops.LPAREN, true);
+ } else if (node instanceof ASTPropertyValueReference) {
+ thisPrec = prec(Ops.DOT, true);
+ } else if (node instanceof ASTPropertyIdentifierReference) {
+ thisPrec = prec(Ops.LBRACKET, true);
} else if (node instanceof ASTExpressionList) {
thisPrec = prec(Ops.COMMA, false);
+ } else if (// Our compiler is broken -- if one of these shows up
+ // in an expression, it had to have been in an
+ // expression list initially
+ node instanceof ASTFunctionExpression ||
+ node instanceof ASTFunctionDeclaration) {
+ thisPrec = prec(Ops.ASSIGN, false);
+ } else if (node instanceof ASTObjectLiteral ||
+ node instanceof ASTArrayLiteral ||
+ node instanceof ASTIdentifier ||
+ node instanceof ASTThisReference ||
+ node instanceof ASTLiteral) {
+ ;
+ } else {
+ System.err.println("No prec for " + node + " in " + nodeString(node));
+ (new CompilerException()).printStackTrace();
}
+
if (assoc ? (thisPrec < parentPrec) : (thisPrec <= parentPrec)) {
nodeRep = "(" + nodeRep + ")";
}
@@ -1383,15 +1405,19 @@
public String visitObjectLiteral(SimpleNode node, String[] children) {
StringBuffer s = new StringBuffer("{");
int len = children.length - 1;
+ int thisPrec = prec(Ops.COMMA, false);
for (int i = 0; i < len; i++) {
- s.append(children[i]);
if (i % 2 != 0) {
+ children[i] = maybeAddParens(thisPrec, node.get(i), children[i],
false);
+ s.append(children[i]);
s.append(COMMA);
} else {
+ s.append(children[i]);
s.append(COLON);
}
}
if (len > 0) {
+ children[len] = maybeAddParens(thisPrec, node.get(len), children[len],
false);
s.append(children[len]);
}
s.append("}");
@@ -1405,6 +1431,9 @@
public String visitVariableDeclaration(SimpleNode node, String[] children)
{
if (children.length > 1) {
+ int thisPrec = prec(Ops.ASSIGN, false);
+ assert children.length == 2;
+ children[1] = maybeAddParens(thisPrec, node.get(1), children[1], true);
return "var " + children[0] + ASSIGN + children[1];
} else {
return "var " + children[0];
Modified:
openlaszlo/branches/wafflecone/WEB-INF/lps/server/src/org/openlaszlo/sc/JavascriptGenerator.java
===================================================================
---
openlaszlo/branches/wafflecone/WEB-INF/lps/server/src/org/openlaszlo/sc/JavascriptGenerator.java
2007-09-05 05:18:10 UTC (rev 6360)
+++
openlaszlo/branches/wafflecone/WEB-INF/lps/server/src/org/openlaszlo/sc/JavascriptGenerator.java
2007-09-05 12:53:39 UTC (rev 6361)
@@ -670,6 +670,7 @@
assert c.length == 3;
p.add(c[0]);
SimpleNode funexpr = new ASTFunctionExpression(0);
+ funexpr.setBeginLocation(n.filename, n.beginLine, n.beginColumn);
funexpr.setChildren(c);
p.add(funexpr);
} else if (n instanceof ASTVariableStatement) {
@@ -1517,6 +1518,14 @@
// if (options.getBoolean(Compiler.WARN_UNDEFINED_REFERENCES)) {
// return makeCheckedNode(node);
// }
+ // Note current call-site in a function context and backtracing
+ if ((options.getBoolean(Compiler.DEBUG_BACKTRACE) && (node.beginLine !=
0)) &&
+ (context.findFunctionContext() != null)) {
+ SimpleNode newNode = new ASTExpressionList(0);
+ newNode.set(0, (new Compiler.Parser()).parse("$lzsc$a.lineno = " +
node.beginLine).get(0).get(0));
+ newNode.set(1, new Compiler.PassThroughNode(node));
+ return visitExpression(newNode);
+ }
return node;
}
@@ -1679,6 +1688,7 @@
return node;
}
+ // useName => declaration not expression
SimpleNode translateFunction(SimpleNode node, boolean useName, SimpleNode[]
children) {
// TODO: [2003-04-15 ptw] bind context slot macro
SimpleNode[] result;
@@ -1720,6 +1730,7 @@
static java.util.regex.Pattern identifierPattern =
java.util.regex.Pattern.compile("[\\w$_]+");
// Internal helper function for above
+ // useName => declaration not expression
SimpleNode[] translateFunctionInternal(SimpleNode node, boolean useName,
SimpleNode[] children) {
// ast can be any of:
// FunctionDefinition(name, args, body)
@@ -2007,6 +2018,7 @@
if (scriptElement || used.containsKey(name)) {
SimpleNode fundecl = (SimpleNode)fundefs.get(name);
SimpleNode funexpr = new ASTFunctionExpression(0);
+ funexpr.setBeginLocation(fundecl.filename, fundecl.beginLine,
fundecl.beginColumn);
funexpr.setChildren(fundecl.getChildren());
Map map = new HashMap();
map.put("_1", funexpr);
@@ -2048,13 +2060,34 @@
// Finally replace the function body with that whole enchilada
children[stmtsIndex] = newStmts;
if ( options.getBoolean(Compiler.NAME_FUNCTIONS)) {
- if (functionName != null) {
- // the name will be available from the runtime
+ // TODO: [2007-09-04 ptw] Come up with a better way to
+ // distinguish LFC from user stack frames. See
+ // lfc/debugger/LzBactrace
+ String fn = (options.getBoolean(Compiler.FLASH_COMPILER_COMPATABILITY) ?
"lfc/" : "") + filename;
+ if (functionName != null &&
+ // Either it is a declaration or we are not doing
+ // backtraces, so the name will be available from the
+ // runtime
+ (useName || (! (options.getBoolean(Compiler.DEBUG_BACKTRACE))))) {
+ if (options.getBoolean(Compiler.DEBUG_BACKTRACE)) {
+ SimpleNode newNode = new ASTStatementList(0);
+ newNode.set(0, new Compiler.PassThroughNode(node));
+ newNode.set(1, parseFragment(functionName + "._dbg_filename = " +
ScriptCompiler.quote(fn)));
+ newNode.set(2, parseFragment(functionName + "._dbg_lineno = " +
lineno));
+ node = visitStatement(newNode);
+ }
} else {
Map map = new HashMap();
map.put("_1", node);
SimpleNode newNode = new Compiler.PassThroughNode((new
Compiler.Parser()).substitute(
- "(function () {var $lzsc$temp = _1; $lzsc$temp._dbg_name = " +
ScriptCompiler.quote(userFunctionName) + "; return $lzsc$temp})()",
+ "(function () {" +
+ " var $lzsc$temp = _1;" +
+ " $lzsc$temp._dbg_name = " +
ScriptCompiler.quote(userFunctionName) + ";" +
+ ((options.getBoolean(Compiler.DEBUG_BACKTRACE)) ?
+ (" $lzsc$temp._dbg_filename = " + ScriptCompiler.quote(fn) + ";" +
+ " $lzsc$temp._dbg_lineno = " + lineno + ";") :
+ "") +
+ " return $lzsc$temp})()",
map));
node = newNode;
}
_______________________________________________
Laszlo-checkins mailing list
[email protected]
http://www.openlaszlo.org/mailman/listinfo/laszlo-checkins