Author: ptw
Date: 2007-12-14 13:57:57 -0800 (Fri, 14 Dec 2007)
New Revision: 7550
Modified:
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/Assembler.java
Log:
Change 20071213-ptw-c by [EMAIL PROTECTED] on 2007-12-13 16:14:13 EST
in /Users/ptw/OpenLaszlo/ringding-2
for http://svn.openlaszlo.org/openlaszlo/trunk
Summary: Fix swf try/catch
Bugs Fixed:
LPP-5252 'try/catch for swf blows up in large programs'
Technical Reviewer: [EMAIL PROTECTED] (message://<[EMAIL PROTECTED]>)
Details:
Store the intermediate result as a relative value (i.e., store the
branch offset to get to the first label, then subtract that from
the branch offset of the second label to get the difference that
you really want)
Tests:
I can compile the LFC with try/catch now
Modified:
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/Assembler.java
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/Assembler.java
2007-12-14 21:52:31 UTC (rev 7549)
+++ openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/Assembler.java
2007-12-14 21:57:57 UTC (rev 7550)
@@ -43,6 +43,12 @@
private static byte[] backingStore;
Hashtable constants;
+ // relative indicates a normal relative reference if relative is
+ // false, this reference is part of label arithmetic, that is, a
+ // difference of two labels:
+ // (label2 - label1)
+ // this produces two references, one with positive=true and one
+ // with positive=false.
public static class LabelReference {
int patchloc;
boolean relative;
@@ -77,24 +83,31 @@
for (Iterator i = references.iterator(); i.hasNext(); ) {
LabelReference lr = (LabelReference)i.next();
int patchloc = lr.patchloc;
- int offset = location - (lr.relative ? (patchloc + 2) : 0);
- if (!lr.positive)
- offset = -offset;
-
- boolean rangecheck = true;
+ int offset = location - (patchloc + 2);
if (!lr.relative) {
- short curval = bytes.getShort(patchloc);
- offset += curval;
-
- // When we're in the middle of evaluating an expression like
- // (label1 - label0), the offset may be temporarily out of range,
- // so disable the check
-
- if (curval == 0)
- rangecheck = false;
+ // If we are doing label arithmetic, we store the relative
+ // offset of the first label we encounter, when the second
+ // label is encountered it will subtract its offset. When
+ // the instruction is first written, it will write 0 offsets
+ // at the patchloc. So, the test for curval == 0 is saying
+ // "is this the first label we have encountered for this
+ // location?" And if so, it will not do any arithmetic, it
+ // will simply write the offset of that label into the
+ // patchloc.
+ // FIXME [2007-12-14 ptw] (LPP-5262) This will fail if the
+ // blocks in the try are maximal
+ // Fetch unsigned:
+ int curval = bytes.getShort(patchloc) & MAX_OFFSET();
+ if (curval == 0) {
+ ;
+ } else if (lr.positive) {
+ offset = offset - curval;
+ } else {
+ offset = curval - offset;
+ }
}
- if (rangecheck && (offset < MIN_OFFSET() || offset > MAX_OFFSET())) {
+ if (offset < MIN_OFFSET() || offset > MAX_OFFSET()) {
throw new CompilerException((this instanceof Block?"Block":"Label")
+ " " +
name + ": jump offset " + offset + " too
large");
}
_______________________________________________
Laszlo-checkins mailing list
[email protected]
http://www.openlaszlo.org/mailman/listinfo/laszlo-checkins