From a19b897271a8ab6b25aba63e4b30223c2477c28d Mon Sep 17 00:00:00 2001 From: brian Date: Wed, 7 Jul 2004 15:40:03 +0000 Subject: [PATCH] trim down public api darcs-hash:20040707154003-24bed-4f708b758473332f378ac91fe706b494829dfc3e.gz --- src/org/ibex/core/Ibex.java | 10 +++++----- src/org/ibex/core/Main.java | 5 +++-- src/org/ibex/js/Interpreter.java | 7 +------ src/org/ibex/js/JS.java | 24 +++++++++++++++--------- src/org/ibex/js/JSArray.java | 2 +- src/org/ibex/js/JSFunction.java | 2 +- src/org/ibex/js/JSMath.java | 5 +---- src/org/ibex/js/JSRegexp.java | 12 ++++++------ src/org/ibex/js/JSString.java | 19 +++++++++++-------- src/org/ibex/js/Stream.java | 1 + src/org/ibex/net/HTTP.java | 7 ++++--- src/org/ibex/net/SOAP.java | 17 +++++++++-------- src/org/ibex/net/XMLRPC.java | 20 ++++++++------------ 13 files changed, 66 insertions(+), 65 deletions(-) diff --git a/src/org/ibex/core/Ibex.java b/src/org/ibex/core/Ibex.java index e14a970..ccc6afb 100644 --- a/src/org/ibex/core/Ibex.java +++ b/src/org/ibex/core/Ibex.java @@ -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); } }; diff --git a/src/org/ibex/core/Main.java b/src/org/ibex/core/Main.java index 3a0ec17..0a4ff91 100644 --- a/src/org/ibex/core/Main.java +++ b/src/org/ibex/core/Main.java @@ -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 write log to a file on disk"); - System.err.println(" -a check assertions"); + //System.err.println(" -a check assertions"); System.err.println(" -w 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], ","); diff --git a/src/org/ibex/js/Interpreter.java b/src/org/ibex/js/Interpreter.java index 3b4dd28..83ff539 100644 --- a/src/org/ibex/js/Interpreter.java +++ b/src/org/ibex/js/Interpreter.java @@ -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; diff --git a/src/org/ibex/js/JS.java b/src/org/ibex/js/JS.java index 65ba3f6..cd63638 100644 --- a/src/org/ibex/js/JS.java +++ b/src/org/ibex/js/JS.java @@ -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); } diff --git a/src/org/ibex/js/JSArray.java b/src/org/ibex/js/JSArray.java index d0cd550..4777213 100644 --- a/src/org/ibex/js/JSArray.java +++ b/src/org/ibex/js/JSArray.java @@ -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() { } diff --git a/src/org/ibex/js/JSFunction.java b/src/org/ibex/js/JSFunction.java index b36a592..71da162 100644 --- a/src/org/ibex/js/JSFunction.java +++ b/src/org/ibex/js/JSFunction.java @@ -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) { diff --git a/src/org/ibex/js/JSMath.java b/src/org/ibex/js/JSMath.java index 816c3e8..32d730d 100644 --- a/src/org/ibex/js/JSMath.java +++ b/src/org/ibex/js/JSMath.java @@ -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)); diff --git a/src/org/ibex/js/JSRegexp.java b/src/org/ibex/js/JSRegexp.java index 00a6f40..d352ce6 100644 --- a/src/org/ibex/js/JSRegexp.java +++ b/src/org/ibex/js/JSRegexp.java @@ -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) { diff --git a/src/org/ibex/js/JSString.java b/src/org/ibex/js/JSString.java index 1484e54..5dc2334 100644 --- a/src/org/ibex/js/JSString.java +++ b/src/org/ibex/js/JSString.java @@ -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; } } diff --git a/src/org/ibex/js/Stream.java b/src/org/ibex/js/Stream.java index 8ed5759..685f990 100644 --- a/src/org/ibex/js/Stream.java +++ b/src/org/ibex/js/Stream.java @@ -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 ////////////////////////////////////////////////////////////////////////////// diff --git a/src/org/ibex/net/HTTP.java b/src/org/ibex/net/HTTP.java index 3c2d970..5aa3408 100644 --- a/src/org/ibex/net/HTTP.java +++ b/src/org/ibex/net/HTTP.java @@ -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; } diff --git a/src/org/ibex/net/SOAP.java b/src/org/ibex/net/SOAP.java index 3d998d5..fbbb9bc 100644 --- a/src/org/ibex/net/SOAP.java +++ b/src/org/ibex/net/SOAP.java @@ -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(" \r\n"); diff --git a/src/org/ibex/net/XMLRPC.java b/src/org/ibex/net/XMLRPC.java index 66908d8..e6a3f65 100644 --- a/src/org/ibex/net/XMLRPC.java +++ b/src/org/ibex/net/XMLRPC.java @@ -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\n"); @@ -175,9 +175,9 @@ public class XMLRPC extends JS { content.append(method); content.append("\n"); content.append(" \n"); - for(int i=0; i\n"); - appendObject(args.elementAt(i), content); + appendObject(args[i], content); content.append(" \n"); } content.append(" \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