2003/11/16 02:40:44
authormegacz <megacz@xwt.org>
Fri, 30 Jan 2004 07:41:26 +0000 (07:41 +0000)
committermegacz <megacz@xwt.org>
Fri, 30 Jan 2004 07:41:26 +0000 (07:41 +0000)
darcs-hash:20040130074126-2ba56-a08e4bb82bf52ff007b9ae2c753738a23025edbd.gz

src/org/xwt/js/Internal.java
src/org/xwt/js/JSCallable.java
src/org/xwt/js/JSContext.java
src/org/xwt/js/JSFunction.java
src/org/xwt/js/JSMath.java
src/org/xwt/js/JSScope.java
src/org/xwt/js/Parser.java
src/org/xwt/plat/AWT.java
src/org/xwt/plat/Java2.java
src/org/xwt/plat/OpenGL.java
src/org/xwt/plat/Win32.java

index d23794b..6d1fece 100644 (file)
@@ -130,7 +130,7 @@ class Internal {
             final Object target = o;
             final String method = key.toString();
             return new JSCallable() {
-                public Object call(JSArray args) { return callMethodOnPrimitive(target,method,args); }
+                public Object call(Object notUsed, JSArray args) { return callMethodOnPrimitive(target,method,args); }
             };
         }
         return null;
index 42def05..8865f3b 100644 (file)
@@ -18,7 +18,18 @@ public abstract class JSCallable extends JSObj {
         return call(method, args);
     }
     public Object call(Object method, JSArray args) throws JS.Exn {
-        throw new JS.Exn("cannot invoke this method with " + args.size() + " arguments");
+        if (method != null) {
+            Object meth = get(method);
+            if (meth == null) throw new JS.Exn("attempt to invoke the null method");
+            if (!(meth instanceof JSCallable)) throw new JS.Exn("cannot call a " + meth.getClass().getName());
+            switch (args.size()) {
+                case 0: return ((JSCallable)meth).call0(null);
+                case 1: return ((JSCallable)meth).call1(null, args.elementAt(0));
+                case 2: return ((JSCallable)meth).call2(null, args.elementAt(0), args.elementAt(1));
+                default: return ((JSCallable)meth).call(null, args);
+            }
+        }
+        throw new JS.Exn("cannot invoke method " + method + " on object " + this.getClass().getName() + " with " + args.size() + " arguments");
     }
 }
 
index 625c834..e707326 100644 (file)
@@ -54,6 +54,7 @@ public class JSContext {
         pausecount++;
         return new Callback() { public Object call(Object o) {
             stack.push(o);
+            pc++;
             resume();
             return null;
         } };
index 0aabebf..00244c6 100644 (file)
@@ -113,11 +113,11 @@ public class JSFunction extends JSCallable implements ByteCodes, Tokens {
             case JMP: cx.pc += JS.toNumber(arg).intValue() - 1; break;
             case POP: cx.stack.pop(); break;
             case SWAP: {
-                int depth = (1 + (arg == null ? 1 : toInt(arg)));
+                int depth = (arg == null ? 1 : toInt(arg));
                 Object save = cx.stack.elementAt(cx.stack.size() - 1);
-                for(int i=cx.stack.size() - 1; i > cx.stack.size() - depth; i--)
+                for(int i=cx.stack.size() - 1; i > cx.stack.size() - 1 - depth; i--)
                     cx.stack.setElementAt(cx.stack.elementAt(i-1), i);
-                cx.stack.setElementAt(save, cx.stack.size() - depth);
+                cx.stack.setElementAt(save, cx.stack.size() - depth - 1);
                 break; }
             case DUP: cx.stack.push(cx.stack.peek()); break;
             case NEWSCOPE: cx.scope = new JSScope(cx.scope); break;
@@ -281,7 +281,7 @@ public class JSFunction extends JSCallable implements ByteCodes, Tokens {
                 }
                 Object ret = null;
                 if (v == null) throw je("tried to get the null key from " + o);
-                if (o == null) throw je("tried to get property \"" + v + "\" from the null value");
+                if (o == null) throw je("tried to get property \"" + v + "\" from the null value @" + cx.pc + "\n" + cx.f.dump());
                 if (o instanceof String || o instanceof Number || o instanceof Boolean) {
                     ret = Internal.getFromPrimitive(o,v);
                     cx.stack.push(ret);
@@ -316,62 +316,61 @@ public class JSFunction extends JSCallable implements ByteCodes, Tokens {
             
             case CALL: case CALLMETHOD: {
                 int numArgs = JS.toInt(arg);
-                JSArray arguments = null;
-                Object arg0 = null;
-                Object arg1 = null;
-                Object o = cx.stack.pop();
-                if(o == null) throw je("attempted to call null");
-                Object ret;
                 Object method = null;
+                Object object = null;
+                Object ret = null;
+                JSArray arguments = null;
+
                 if(op == CALLMETHOD) {
-                    method = o;
-                    if (method == null) throw new JS.Exn("cannot call the null method");
-                    o = cx.stack.pop();
-                    if(o instanceof String || o instanceof Number || o instanceof Boolean) {
-                        arguments = new JSArray();
-                        for(int j=numArgs - 1; j >= 0; j--) arguments.setElementAt(cx.stack.pop(), j);
-                        ret = Internal.callMethodOnPrimitive(o, method, arguments);
-                        cx.stack.push(ret);
-                        cx.pc += 2;  // skip the GET and CALL
-                        break;
-                    } else if (o instanceof JSCallable) {
-                        cx.pc += 2;  // skip the GET and CALL
-                        // fall through
-                    } else {
-                        // put the args back on the stack and let the GET followed by CALL happen
-                        cx.stack.push(o);
-                        cx.stack.push(method);
-                        break;
+                    Object getResult = cx.stack.pop();
+                    method = cx.stack.pop();
+                    object = cx.stack.pop();
+                    if (getResult != null) {
+                        method = null;
+                        object = getResult;
                     }
+                } else {
+                    method = null;
+                    object = cx.stack.pop();
+                }
+
+                if (object instanceof String || object instanceof Number || object instanceof Boolean) {
+                    arguments = new JSArray(); for(int j=numArgs - 1; j >= 0; j--) arguments.setElementAt(cx.stack.pop(), j);
+                    ret = Internal.callMethodOnPrimitive(object, method, arguments);
 
-                } else if (o instanceof JSFunction) {
+                } else if (object instanceof JSFunction) {
                     // FEATURE: use something similar to call0/call1/call2 here
-                    arguments = new JSArray();
-                    for(int j=numArgs - 1; j >= 0; j--) arguments.setElementAt(cx.stack.pop(), j);
+                    arguments = new JSArray(); for(int j=numArgs - 1; j >= 0; j--) arguments.setElementAt(cx.stack.pop(), j);
                     cx.stack.push(new CallMarker(cx));
                     cx.stack.push(arguments);
-                    cx.f = (JSFunction)o;
+                    cx.f = (JSFunction)object;
                     cx.scope = new JSScope(cx.f.parentJSScope);
                     cx.pc = -1;
                     break;
-                }
 
-                if (!(o instanceof JSCallable)) throw new JS.Exn("can't call " + o + " @ " + cx.pc + "\n" + cx.f.dump());
-                JSCallable c = ((JSCallable)o);
-                switch(numArgs) {
-                    case 0: ret = c.call0(method); break;
-                    case 1: ret = c.call1(method, cx.stack.pop()); break;
-                    case 2: { Object first = cx.stack.pop(); ret = c.call2(method, cx.stack.pop(), first); break; }
-                    default: {
-                        arguments = new JSArray();
-                        for(int j=numArgs - 1; j >= 0; j--) arguments.setElementAt(cx.stack.pop(), j);
-                        ret = c.call(method, arguments);
-                        if (cx.pausecount > initialPauseCount) return null;   // we were paused
-                        break;
+                } else if (object instanceof JSCallable) {
+                    JSCallable c = (JSCallable)object;
+                    switch(numArgs) {
+                        case 0: ret = c.call0(method); break;
+                        case 1: ret = c.call1(method, cx.stack.pop()); break;
+                        case 2: {
+                            Object first = cx.stack.pop();
+                            Object second = cx.stack.pop();
+                            ret = c.call2(method, second, first);
+                            break;
+                        }
+                        default: {
+                            arguments = new JSArray();
+                            for(int j=numArgs - 1; j >= 0; j--) arguments.setElementAt(cx.stack.pop(), j);
+                            ret = c.call(method, arguments);
+                            break;
+                        }
                     }
+                } else {
+                    throw new JS.Exn("can't call a " + object.getClass().getName() + " @" + cx.pc + "\n" + cx.f.dump());
                 }
+                if (cx.pausecount > initialPauseCount) return null;
                 cx.stack.push(ret);
-
                 break;
             }
 
index 5a2ea4b..91a8a9e 100644 (file)
@@ -6,7 +6,7 @@ import java.io.*;
 import java.util.*;
 
 /** The JavaScript Math object */
-public class JSMath extends JSObj {
+public class JSMath extends JSCallable {
 
     public static JSMath singleton = new JSMath();
 
index 8327ea1..54dc446 100644 (file)
@@ -46,7 +46,7 @@ public class JSScope extends JSCallable {
 
         public Object call(Object method, JSArray args) {
             if (method.equals("stringFromCharCode")) return stringFromCharCode(args);
-            else throw new JS.Exn("method not found");
+            return super.call(method, args);
         }
 
         public Object call1(Object method, Object arg0) {
@@ -61,12 +61,12 @@ public class JSScope extends JSCallable {
             case "escape": throw new JS.Exn("unimplemented");
             case "unescape": throw new JS.Exn("unimplemented");
             //#end
-            return null;
+            return super.call1(method, arg0);
         }
 
         public Object call2(Object method, Object arg1, Object arg2) {
             if (method.equals("parseInt")) return parseInt(arg1, arg2);
-            return null;
+            return super.call2(method, arg1, arg2);
         }
 
         private Object stringFromCharCode(JSArray args) {
index b3c1742..4b288a8 100644 (file)
@@ -204,7 +204,7 @@ class Parser extends Lexer implements ByteCodes {
                 throw pe("prefixed increment/decrement can only be performed on a valid assignment target");
             b.add(parserLine, GET_PRESERVE, Boolean.TRUE);
             b.add(parserLine, LITERAL, new Integer(1));
-            b.add(parserLine, tok == INC ? ADD : SUB, null);
+            b.add(parserLine, tok == INC ? ADD : SUB, new Integer(2));
             b.add(parserLine, PUT, null);
             b.add(parserLine, SWAP, null);
             b.add(parserLine, POP, null);
@@ -334,7 +334,7 @@ class Parser extends Lexer implements ByteCodes {
         case INC: case DEC: { // postfix
             b.add(parserLine, GET_PRESERVE, Boolean.TRUE);
             b.add(parserLine, LITERAL, new Integer(1));
-            b.add(parserLine, tok == INC ? ADD : SUB, null);
+            b.add(parserLine, tok == INC ? ADD : SUB, new Integer(2));
             b.add(parserLine, PUT, null);
             b.add(parserLine, SWAP, null);
             b.add(parserLine, POP, null);
@@ -350,12 +350,9 @@ class Parser extends Lexer implements ByteCodes {
             break;
         }
         case LP: {
-            int n = parseArgs(b);
-
-            // if the object supports CALLMETHOD, we use this, and jump over the following two instructions
-            b.add(parserLine,CALLMETHOD,new Integer(n));
-            b.add(parserLine,GET);
-            b.add(parserLine,CALL,new Integer(n));
+            int n = parseArgs(b, 2);
+            b.add(parserLine, GET_PRESERVE);
+            b.add(parserLine, CALLMETHOD, new Integer(n));
             break;
         }
         default: {
@@ -397,7 +394,7 @@ class Parser extends Lexer implements ByteCodes {
 
         switch (tok) {
         case LP: {  // invocation (not grouping)
-            int n = parseArgs(b);
+            int n = parseArgs(b, 1);
             b.add(parserLine, CALL, new Integer(n));
             break;
         }
@@ -476,13 +473,13 @@ class Parser extends Lexer implements ByteCodes {
     
     // parse a set of comma separated function arguments, assume LP has already been consumed
     // if swap is true, (because the function is already on the stack) we will SWAP after each argument to keep it on top
-    private int parseArgs(JSFunction b) throws IOException {
+    private int parseArgs(JSFunction b, int pushdown) throws IOException {
         int i = 0;
         while(peekToken() != RP) {
             i++;
             if (peekToken() != COMMA) {
                 startExpr(b, NO_COMMA);
-                b.add(parserLine, SWAP, new Integer(2));
+                b.add(parserLine, SWAP, new Integer(pushdown));
                 if (peekToken() == RP) break;
             }
             consume(COMMA);
index dac9e57..bcde5f0 100644 (file)
@@ -193,7 +193,7 @@ public class AWT extends JVM {
         }
 
         // FIXME: try to use os acceleration
-        public void fillJSTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int argb) {
+        public void fillTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int argb) {
             g.setColor(new Color((argb & 0x00FF0000) >> 16, (argb & 0x0000FF00) >> 8, (argb & 0x000000FF)));
             if (x1 == x3 && x2 == x4) {
                 g.fillRect(x1, y1, x4 - x1, y2 - y1);
index e596c62..d2785a9 100644 (file)
@@ -83,7 +83,7 @@ public class Java2 extends AWT {
                         else return null;
 
                     } catch (Throwable e) {
-                        if (Log.on) Log.log(this, "exception while querying sun.plugin.protocol.PluginProxyHandler: " + e);
+                        if (Log.on) Log.log(this, "No proxy information found in Java Plugin classes");
                         return null;
                     }
                 }});
index 8ed60c2..20fbacb 100644 (file)
@@ -74,7 +74,7 @@ abstract class OpenGL {
         
         public native void setClip(int x, int y, int x2, int y2);
         public native void resetClip();
-        public native void fillJSTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int color);
+        public native void fillTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int color);
             
         public void drawString(String font, String text, int x, int y, int color) {
             //System.out.println("drawString(): " + text);
index 100da9b..b26fd38 100644 (file)
@@ -274,7 +274,7 @@ public class Win32 extends GCJ {
         public native void finalize();
 
         // FIXME: try to use os acceleration
-        public void fillJSTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int argb) {
+        public void fillTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int argb) {
             if (x1 == x3 && x2 == x4) {
                 fillRect(x1, y1, x4, y2, argb);
             } else for(int y=y1; y<y2; y++) {