trim down public api
authorbrian <brian@brianweb.net>
Wed, 7 Jul 2004 15:40:03 +0000 (15:40 +0000)
committerbrian <brian@brianweb.net>
Wed, 7 Jul 2004 15:40:03 +0000 (15:40 +0000)
darcs-hash:20040707154003-24bed-4f708b758473332f378ac91fe706b494829dfc3e.gz

13 files changed:
src/org/ibex/core/Ibex.java
src/org/ibex/core/Main.java
src/org/ibex/js/Interpreter.java
src/org/ibex/js/JS.java
src/org/ibex/js/JSArray.java
src/org/ibex/js/JSFunction.java
src/org/ibex/js/JSMath.java
src/org/ibex/js/JSRegexp.java
src/org/ibex/js/JSString.java
src/org/ibex/js/Stream.java
src/org/ibex/net/HTTP.java
src/org/ibex/net/SOAP.java
src/org/ibex/net/XMLRPC.java

index e14a970..ccc6afb 100644 (file)
@@ -185,7 +185,7 @@ public final class Ibex extends JS implements JS.Cloneable {
                         throw new JSExn("invalid resource specifier " + url);
                     }
                     case "thread.sleep": sleep(JS.toInt(a)); return null;
-                    case "regexp": return new JSRegexp(a, null);
+                    case "regexp": return JS.newRegexp(a, null);
                     case "net.rpc.xml": return new XMLRPC(JS.toString(a), "");
                     case "crypto.rsa": /* FEATURE */ return null;
                     case "crypto.md5": /* FEATURE */ return null;
@@ -202,7 +202,7 @@ public final class Ibex extends JS implements JS.Cloneable {
                 case 2:
                     //#jswitch(name)
                     case "stream.watch": return new Stream.ProgressWatcher(a, b);
-                    case "regexp": return new JSRegexp(a, b);
+                    case "regexp": return JS.newRegexp(a, b);
                     //#end
                 case 3:
                     //#jswitch(name)
@@ -243,7 +243,7 @@ public final class Ibex extends JS implements JS.Cloneable {
         }
     }
     
-    public static final JSMath ibexMath = new JSMath() {
+    public static final JS ibexMath = new JS() {
             // FEATURE: find a cleaner way to do this
             private JS gs = /*new JSScope.Global();*/ null; // FIXME: Global scope
             public JS get(JS key) throws JSExn {
@@ -253,7 +253,7 @@ public final class Ibex extends JS implements JS.Cloneable {
                 case "NaN": return METHOD;
                 case "Infinity": return METHOD;
                 //#end
-                return super.get(key);
+                return MATH.get(key);
             }
             public JS callMethod(JS name, JS a, JS b, JS c, JS[] rest, int nargs) throws JSExn {
                 //#jswitch(name)
@@ -262,7 +262,7 @@ public final class Ibex extends JS implements JS.Cloneable {
                 case "NaN": return gs.callMethod(name,a,b,c,rest,nargs);
                 case "Infinity": return gs.callMethod(name,a,b,c,rest,nargs);
                 //#end
-                return super.callMethod(name,a,b,c,rest,nargs);
+                return MATH.callMethod(name,a,b,c,rest,nargs);
             }
     };
 
index 3a0ec17..0a4ff91 100644 (file)
@@ -35,7 +35,7 @@ public class Main {
         System.err.println("    -l user@host    email log to user@host");
         System.err.println("    -l host:port    emit log to TCP socket");
         System.err.println("    -l <file>       write log to a file on disk");
-        System.err.println("    -a              check assertions");
+        //System.err.println("    -a              check assertions");
         System.err.println("    -w <window-id>  reserved for libibex");
         System.err.println("    -p              dump profiling information [not yet supported]");
         Runtime.getRuntime().exit(-1);
@@ -45,7 +45,8 @@ public class Main {
         int startargs = 0;
         while (true) {
             if (startargs > args.length - 1) printUsage();
-            else if (args[startargs].equals("-a")) JS.checkAssertions = true;
+            // FEATURE: This should be enabled at the parser level - there shouldn't even be an assert bytecode
+            /*else if (args[startargs].equals("-a")) JS.checkAssertions = true;*/
             else if (args[startargs].equals("-l")) {
                 startargs++;
                 StringTokenizer opts = new StringTokenizer(args[startargs], ",");
index 3b4dd28..83ff539 100644 (file)
@@ -99,12 +99,7 @@ class Interpreter implements ByteCodes, Tokens {
             case DUP: stack.push(stack.peek()); break;
             case NEWSCOPE: scope = new JSScope(scope); break;
             case OLDSCOPE: scope = scope.getParentScope(); break;
-            case ASSERT: {
-                JS o = stack.pop();
-                if (JS.checkAssertions && !JS.toBoolean(o))
-                    throw je("ibex.assertion.failed");
-                break;
-            }
+            case ASSERT: if (!JS.toBoolean(stack.pop())) throw je("ibex.assertion.failed"); break;
             case BITNOT: stack.push(JS.N(~JS.toLong(stack.pop()))); break;
             case BANG: stack.push(JS.B(!JS.toBoolean(stack.pop()))); break;
             case NEWFUNCTION: stack.push(((JSFunction)arg)._cloneWithNewParentScope(scope)); break;
index 65ba3f6..cd63638 100644 (file)
@@ -7,9 +7,6 @@ import java.util.*;
 
 /** The minimum set of functionality required for objects which are manipulated by JavaScript */
 public abstract class JS { 
-
-    public static boolean checkAssertions = false;
-
     public static final JS METHOD = new JS() { };
     public final JS unclone() { return _unclone(); }
     public final JS jsclone() throws JSExn { return new Clone(this); }
@@ -34,15 +31,19 @@ public abstract class JS {
     
     public final boolean equals(Object o) { return this == o || ((o instanceof JS) && jsequals((JS)o)); }
     
-    // FIXME: Remove this, eventually
-    public final String toString() { throw new Error("you shouldn't use toString() on JS objects"); }
+    public final String toString() {
+        // Discourage people from using toString()
+        String s = "JS Object [class=" + getClass().getName() + "]";
+        String ext = extendedToString();
+        return ext == null ? s : s + " " + ext;
+    }
     
     // These are only used internally by org.ibex.js
     Trap getTrap(JS key) { return null; }
     void putTrap(JS key, Trap value) throws JSExn { throw new JSExn("traps cannot be placed on this object (class=" + this.getClass().getName() +")"); }
     String coerceToString() throws JSExn { throw new JSExn("can't coerce to a string (class=" + getClass().getName() +")"); }
-    String debugToString() { return "[class=" + getClass().getName() + "]"; }
     boolean jsequals(JS o) { return this == o; }
+    String extendedToString() { return null; }
     
     public static class O extends JS implements Cloneable {
         private Hash entries;
@@ -183,7 +184,7 @@ public abstract class JS {
     public static boolean toBoolean(JS o) {
         if(o == null) return false;
         if(o instanceof JSNumber) return ((JSNumber)o).toBoolean();
-        if(o instanceof JSString) return ((JSString)o).length() != 0;
+        if(o instanceof JSString) return ((JSString)o).s.length() != 0;
         return true;
     }
     //#repeat long/int/double/float toLong/toInt/toDouble/toFloat Long/Integer/Double/Float parseLong/parseInt/parseDouble/parseFloat
@@ -203,7 +204,7 @@ public abstract class JS {
     
     public static String debugToString(JS o) {
         try { return toString(o); }
-        catch(JSExn e) { return o.debugToString(); }
+        catch(JSExn e) { return o.toString(); }
     }
     
     public static boolean isInt(JS o) {
@@ -227,12 +228,16 @@ public abstract class JS {
         if(o instanceof JSString) return true;
         return false;
     }
+    
+    public static JS newArray() { return new JSArray(); }
+    public static JS newRegexp(JS pat, JS flags) throws JSExn { return new JSRegexp(pat,flags); }
 
     // Instance Methods ////////////////////////////////////////////////////////////////////
  
     public final static JS NaN = new JSNumber.D(Double.NaN);
     public final static JS ZERO = new JSNumber.I(0);
     public final static JS ONE = new JSNumber.I(1);
+    public final static JS MATH = new JSMath();
         
     public static final JS T = new JSNumber.B(true);
     public static final JS F = new JSNumber.B(false);
@@ -242,13 +247,14 @@ public abstract class JS {
     
     private static final int CACHE_SIZE = 65536 / 4; // must be a power of two
     private static final JSString[] stringCache = new JSString[CACHE_SIZE];
-    public static final JS S(String s)  {
+    public static final JS S(String s) {
         if(s == null) return null;
         int slot = s.hashCode()&(CACHE_SIZE-1);
         JSString ret = stringCache[slot];
         if(ret == null || !ret.s.equals(s)) stringCache[slot] = ret = new JSString(s);
         return ret;
     }
+    public static final JS S(String s, boolean intern) { return intern ? JSString.intern(s) : S(s); }
 
     public static final JS N(double d) { return new JSNumber.D(d); }
     public static final JS N(long l) { return new JSNumber.L(l); }
index d0cd550..4777213 100644 (file)
@@ -5,7 +5,7 @@ import org.ibex.util.*;
 import java.util.*;
 
 /** A JavaScript JSArray */
-public class JSArray extends JS.BT {
+class JSArray extends JS.BT {
     private static final Object NULL = new Object();
     
     public JSArray() { }
index b36a592..71da162 100644 (file)
@@ -98,7 +98,7 @@ class JSFunction extends JS implements ByteCodes, Tokens, Task {
 
     // Debugging //////////////////////////////////////////////////////////////////////
 
-    String debugToString() { return "JSFunction [" + sourceName + ":" + firstLine + "]"; }
+    String extendedToString() { return "[" + sourceName + ":" + firstLine + "]"; }
 
     String dump() { return dump(""); }
     private  String dump(String prefix) {
index 816c3e8..32d730d 100644 (file)
@@ -3,10 +3,7 @@
 package org.ibex.js; 
 
 /** The JavaScript Math object */
-public class JSMath extends JS {
-
-    public static JSMath singleton = new JSMath();
-
+class JSMath extends JS {
     private static final JS E       = JS.N(java.lang.Math.E);
     private static final JS PI      = JS.N(java.lang.Math.PI);
     private static final JS LN10    = JS.N(java.lang.Math.log(10));
index 00a6f40..d352ce6 100644 (file)
@@ -4,7 +4,7 @@ package org.ibex.js;
 import gnu.regexp.*;
 
 /** A JavaScript regular expression object */
-public class JSRegexp extends JS {
+class JSRegexp extends JS {
     private boolean global;
     private RE re;
     private int lastIndex;
@@ -127,7 +127,7 @@ public class JSRegexp extends JS {
         return sb.toString();
     }
     
-    public static JS stringMatch(JS o, JS arg0) throws JSExn {
+    static JS stringMatch(JS o, JS arg0) throws JSExn {
         String s = JS.toString(o);
         RE re;
         JSRegexp regexp = null;
@@ -151,14 +151,14 @@ public class JSRegexp extends JS {
         return ret;
     }
     
-    public static JS stringSearch(JS o, JS arg0) throws JSExn  {
+    static JS stringSearch(JS o, JS arg0) throws JSExn  {
         String s = JS.toString(o);
         RE re = arg0 instanceof JSRegexp ? ((JSRegexp)arg0).re : newRE(JS.toString(arg0),0);
         REMatch match = re.getMatch(s);
         return match == null ? N(-1) : N(match.getStartIndex());
     }
     
-    public static JS stringReplace(JS o, JS arg0, JS arg1) throws JSExn {
+    static JS stringReplace(JS o, JS arg0, JS arg1) throws JSExn {
         String s = JS.toString(o);
         RE re;
         JSFunction replaceFunc = null;
@@ -279,7 +279,7 @@ public class JSRegexp extends JS {
     }
                     
     
-    public static JS stringSplit(JS s_, JS arg0, JS arg1, int nargs) throws JSExn {
+    static JS stringSplit(JS s_, JS arg0, JS arg1, int nargs) throws JSExn {
         String s = JS.toString(s_);
         int limit = nargs < 2 ? Integer.MAX_VALUE : JS.toInt(arg1);
         if(limit < 0) limit = Integer.MAX_VALUE;
@@ -333,7 +333,7 @@ public class JSRegexp extends JS {
         return ret;
     }
     
-    public static RE newRE(String pattern, int flags) throws JSExn {
+    private static RE newRE(String pattern, int flags) throws JSExn {
         try {
             return new RE(pattern,flags,RESyntax.RE_SYNTAX_PERL5);
         } catch(REException e) {
index 1484e54..5dc2334 100644 (file)
@@ -2,7 +2,7 @@ package org.ibex.js;
 
 import org.ibex.util.*;
 
-final class JSString extends JSPrimitive {
+class JSString extends JSPrimitive {
     final String s;
     public JSString(String s) { this.s = s; }
     public int hashCode() { return s.hashCode(); }
@@ -18,15 +18,18 @@ final class JSString extends JSPrimitive {
         }
     }
     
-    int length() { return s.length(); }
-    
-    private static Hash internHash = new Hash();
+    private final static Hash internHash = new Hash();
     static synchronized JS intern(String s) {
-        JS js = (JS)internHash.get(s);
-        if(js == null) internHash.put(s,js = new JSString(s));
-        return js;
+        synchronized(internHash) {
+            JS js = (JS)internHash.get(s);
+            if(js == null) internHash.put(s,js = new Intern(s));
+            return js;
+        }
+    }
+    static class Intern extends JSString {
+        public Intern(String s) { super(s); }
+        protected void finalize() { synchronized(internHash) { internHash.put(s,null); } }
     }
-    JS intern() { return intern(s); }
     
     String coerceToString() { return s; }
 }
index 8ed5759..685f990 100644 (file)
@@ -13,6 +13,7 @@ import org.ibex.net.*;
  *   be totally independent of the others (ie separate stream position
  *   and state) although they draw from the same data source.
  */
+// FEATURE: Should this be in org.ibex.js?
 public abstract class Stream extends JS implements JS.Cloneable {
 
     // Public Interface //////////////////////////////////////////////////////////////////////////////
index 3c2d970..5aa3408 100644 (file)
@@ -751,15 +751,16 @@ public class HTTP {
             } catch (Exception e) {
                 if (Log.on) {
                     Log.info(Platform.class, "WPAD detection failed due to:");
-                    if (e instanceof JSExn) {
+                    // I have no idea what this was supposed to do
+                    /*if (e instanceof JSExn) {
                         try {
                             org.ibex.js.JSArray arr = new org.ibex.js.JSArray();
                             arr.addElement(((JSExn)e).getObject());
                         } catch (Exception e2) {
                             Log.info(Platform.class, e);
                         }
-                    }
-                    else Log.info(Platform.class, e);
+                    }*/
+                    Log.info(Platform.class, e);
                 }
                 return null;
             }
index 3d998d5..fbbb9bc 100644 (file)
@@ -67,7 +67,7 @@ public class SOAP extends XMLRPC {
                     objects.addElement(null);
                 } else if (value.endsWith("arrayType") || value.endsWith("JSArray") || key.endsWith("arrayType")) {
                     objects.removeElementAt(objects.size() - 1);
-                    objects.addElement(new JSArray());
+                    objects.addElement(JS.newArray());
                 }
             }
         }
@@ -145,11 +145,12 @@ public class SOAP extends XMLRPC {
         if (objects.size() < 2) return;
 
         // our parent "should" be an aggregate type -- add ourselves to it.
-        if (parent != null && parent instanceof JSArray) {
+        // FIXME: Can we get away without JSArray being public?
+        /*if (parent != null && parent instanceof JSArray) {
             objects.removeElementAt(objects.size() - 1);
             ((JSArray)parent).addElement(me);
 
-        } else if (parent != null && parent instanceof JS) {
+        } else */ if (parent != null && parent instanceof JS) {
             objects.removeElementAt(objects.size() - 1);
             try {
                 ((JS)parent).put(JS.S(name), me);
@@ -244,7 +245,7 @@ public class SOAP extends XMLRPC {
         }*/
     }
 
-    protected String buildRequest(JSArray args) throws JSExn, IOException {
+    protected String buildRequest(JS[] args) throws JSExn, IOException {
         // build up the request
         StringBuffer content = new StringBuffer();
         content.append("SOAPAction: " + action + "\r\n\r\n");
@@ -259,11 +260,11 @@ public class SOAP extends XMLRPC {
         content.append(method);
         content.append(nameSpace != null ? " xmlns=\"" + nameSpace + "\"" : "");
         content.append(">\r\n");
-        if (args.length() > 0) {
-            Enumeration e = ((JS)args.elementAt(0)).keys();
+        if (args.length > 0) {
+            Enumeration e = args[0].keys();
             while(e.hasMoreElements()) {
-                Object key = e.nextElement();
-                appendObject((String)key, args.elementAt(0).get((JS)key), content);
+                JS key = e.nextElement();
+                appendObject(JS.toString(key), args[0].get(key), content);
             }
         }
         content.append("    </" + method + "></SOAP-ENV:Body></SOAP-ENV:Envelope>\r\n");
index 66908d8..e6a3f65 100644 (file)
@@ -141,7 +141,7 @@ public class XMLRPC extends JS {
             case "data":
                 int i;
                 for(i=objects.size() - 1; objects.elementAt(i) != null; i--);
-                JSArray arr = new JSArray();
+                JS arr = JS.newArray();
                 try {
                     for(int j = i + 1; j<objects.size(); j++) arr.put(JS.N(j - i - 1), (JS)objects.elementAt(j));
                 } catch (JSExn e) {
@@ -166,7 +166,7 @@ public class XMLRPC extends JS {
 
     // Send ///////////////////////////////////////////////////////////////////////////
 
-    protected String buildRequest(JSArray args) throws JSExn, IOException {
+    protected String buildRequest(JS[] args) throws JSExn, IOException {
         StringBuffer content = new StringBuffer();
         content.append("\r\n");
         content.append("<?xml version=\"1.0\"?>\n");
@@ -175,9 +175,9 @@ public class XMLRPC extends JS {
         content.append(method);
         content.append("</methodName>\n");
         content.append("        <params>\n");
-        for(int i=0; i<args.length(); i++) {
+        for(int i=0; i<args.length; i++) {
             content.append("            <param>\n");
-            appendObject(args.elementAt(i), content);
+            appendObject(args[i], content);
             content.append("            </param>\n");
         }
         content.append("        </params>\n");
@@ -303,22 +303,18 @@ public class XMLRPC extends JS {
     // Call Sequence //////////////////////////////////////////////////////////////////////////
 
     public final JS call(JS a0, JS a1, JS a2, JS[] rest, int nargs) throws JSExn {
-        JSArray args = new JSArray();
-        for(int i=0; i<nargs; i++) args.addElement(i==0?a0:i==1?a1:i==2?a2:rest[i-3]);
-        return call(args);
-    }
-
-    public final JS call(final JSArray args) throws JSExn {
+        final JS[] args = new JS[nargs];
+        for(int i=0;i<nargs;i++) args[i]= i==0?a0:i==1?a1:i==2?a2:rest[i-3];
         try {
             final JS.UnpauseCallback callback = JS.pause();
-            new java.lang.Thread() { public void run() { call(callback, args); }  }.start();
+            new java.lang.Thread() { public void run() { call(callback,args); }  }.start();
             return null; // doesn't matter since we paused
         } catch (NotPauseableException npe) {
             throw new JSExn("cannot invoke an XML-RPC call in the foreground thread");
         }
     }
 
-    final void call(final JS.UnpauseCallback callback, final JSArray args) {
+    final void call(final JS.UnpauseCallback callback, JS[] args) {
         try {
             if (Log.rpc) Log.info(this, "call to " + url + " : " + method);
             if (tracker == null) tracker = new Hash();