2003/09/24 07:33:32
[org.ibex.core.git] / src / org / xwt / js / CompiledFunctionImpl.java
index 5771060..f118b76 100644 (file)
@@ -4,12 +4,14 @@ package org.xwt.js;
 import org.xwt.util.*;
 import java.io.*;
 
-// FIXME: could use some cleaning up
 /** a JavaScript function, compiled into bytecode */
-class CompiledFunctionImpl extends JSCallable implements ByteCodes, Tokens {
+class CompiledFunctionImpl extends JS.Callable implements ByteCodes, Tokens {
 
     // Fields and Accessors ///////////////////////////////////////////////
 
+    /** the number of formal arguments */
+    int numFormalArgs = 0;
+
     /** the source code file that this block was drawn from */
     private String sourceName;
     public String getSourceName() throws JS.Exn { return sourceName; }
@@ -74,7 +76,8 @@ class CompiledFunctionImpl extends JSCallable implements ByteCodes, Tokens {
             Object ret = cx.stack.pop();
             if (cx.stack.size() > size)
                 // this should never happen
-                throw new Error("ERROR: stack grew by " + (cx.stack.size() - size) + " elements during call at " + sourceName + ":" + firstLine);
+                throw new Error("ERROR: stack grew by " + (cx.stack.size() - size) +
+                                " elements during call at " + sourceName + ":" + firstLine);
             return ret;
         } catch(Error e) {
             // Unwind the stack
@@ -323,7 +326,34 @@ class CompiledFunctionImpl extends JSCallable implements ByteCodes, Tokens {
                 break;
             }
             
-            
+            case ASSIGN_SUB: case ASSIGN_ADD: {
+                Object val = t.pop();
+                Object old = t.pop();
+                Object key = t.pop();
+                Object obj = t.peek();
+                if (val instanceof CompiledFunction) {
+                    if (obj instanceof JS.Scope) {
+                        JS.Scope parent = (JS.Scope)obj;
+                        while(parent.getParentScope() != null) parent = parent.getParentScope();
+                        if (parent instanceof org.xwt.Box) {
+                            if (curOP == ASSIGN_ADD) {
+                                ((org.xwt.Box)parent).addTrap(key, val);
+                            } else {
+                                ((org.xwt.Box)parent).delTrap(key, val);
+                            }
+                            // skip over the "normal" implementation of +=/-=
+                            pc += ((Integer)arg[pc]).intValue() - 1;
+                            break;
+                        }
+                    }
+                }
+                // use the "normal" implementation
+                t.push(key);
+                t.push(old);
+                t.push(arg);
+                break;
+            }
+
             case ADD: {
                 int count = ((Number)arg[pc]).intValue();
                 if(count < 2) throw new Error("this should never happen");
@@ -333,31 +363,31 @@ class CompiledFunctionImpl extends JSCallable implements ByteCodes, Tokens {
                     Object left = t.pop();
                     if(left instanceof String || right instanceof String) t.push(JS.toString(left).concat(JS.toString(right)));
                     else t.push(new Double(JS.toDouble(left) + JS.toDouble(right)));
-                    break;
-                }
-                Object[] args = new Object[count];
-                while(--count >= 0) args[count] = t.pop();
-                if(args[0] instanceof String) {
-                    StringBuffer sb = new StringBuffer(64);
-                    for(int i=0;i<args.length;i++) sb.append(JS.toString(args[i]));
-                    t.push(sb.toString());
                 } else {
-                    int numStrings = 0;
-                    for(int i=0;i<args.length;i++) if(args[i] instanceof String) numStrings++;
-                    if(numStrings == 0) {
-                        double d = 0.0;
-                        for(int i=0;i<args.length;i++) d += JS.toDouble(args[i]);
-                        t.push(new Double(d));
-                    } else {
-                        double d=0.0;
-                        int i=0;
-                        do {
-                            d += JS.toDouble(args[i++]);
-                        } while(!(args[i] instanceof String));
+                    Object[] args = new Object[count];
+                    while(--count >= 0) args[count] = t.pop();
+                    if(args[0] instanceof String) {
                         StringBuffer sb = new StringBuffer(64);
-                        sb.append(JS.toString(new Double(d)));
-                        while(i < args.length) sb.append(JS.toString(args[i++]));
+                        for(int i=0;i<args.length;i++) sb.append(JS.toString(args[i]));
                         t.push(sb.toString());
+                    } else {
+                        int numStrings = 0;
+                        for(int i=0;i<args.length;i++) if(args[i] instanceof String) numStrings++;
+                        if(numStrings == 0) {
+                            double d = 0.0;
+                            for(int i=0;i<args.length;i++) d += JS.toDouble(args[i]);
+                            t.push(new Double(d));
+                        } else {
+                            double d=0.0;
+                            int i=0;
+                            do {
+                                d += JS.toDouble(args[i++]);
+                            } while(!(args[i] instanceof String));
+                            StringBuffer sb = new StringBuffer(64);
+                            sb.append(JS.toString(new Double(d)));
+                            while(i < args.length) sb.append(JS.toString(args[i++]));
+                            t.push(sb.toString());
+                        }
                     }
                 }
                 break;