From: brian Date: Fri, 30 Jan 2004 07:02:47 +0000 (+0000) Subject: 2003/07/05 03:23:21 X-Git-Tag: RC3~820 X-Git-Url: http://git.megacz.com/?p=org.ibex.core.git;a=commitdiff_plain;h=7d13f43cfd04ddf5d4b9fee176697c12e1f9d0c9 2003/07/05 03:23:21 darcs-hash:20040130070247-aa32f-a833065fd8321407e92d83822176c0e7567ef034.gz --- diff --git a/src/org/xwt/js/Internal.java b/src/org/xwt/js/Internal.java new file mode 100644 index 0000000..93aae21 --- /dev/null +++ b/src/org/xwt/js/Internal.java @@ -0,0 +1,135 @@ +// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL] + +package org.xwt.js; +import org.xwt.util.*; + +/** + * Misc static methods used internally by the JS engine + */ +class Internal { + // Package Helper Methods ////////////////////////////////////////////////////////////// + + private static Object wrapInt(int i) { return new Integer(i); } + static Object callMethodOnPrimitive(Object o, Object method, JS.Array args) { + int alength = args.length(); + String s; + if(o instanceof Number) { + if(method.equals("toFixed")) throw new JS.Exn("toFixed() not implemented"); + if(method.equals("toExponential")) throw new JS.Exn("toExponential() not implemented"); + if(method.equals("toPrecision")) throw new JS.Exn("toPrecision() not implemented"); + if(method.equals("toString")) { + int radix = alength >= 1 ? JS.toInt(args.elementAt(0)) : 10; + return Long.toString(((Number)o).longValue(),radix); + } + } else if(o instanceof Boolean) { + // No methods for Booleans + } + s = o.toString(); + int slength = s.length(); + if(method.equals("substring")) { + int a = alength >= 1 ? JS.toInt(args.elementAt(0)) : 0; + int b = alength >= 2 ? JS.toInt(args.elementAt(1)) : slength; + if(a > slength) a = slength; + if(b > slength) b = slength; + if(a < 0) a = 0; + if(b < 0) b = 0; + if(a > b) { int tmp = a; a = b; b = tmp; } + return s.substring(a,b); + } + if(method.equals("charAt")) { + int p = alength >= 1 ? JS.toInt(args.elementAt(0)) : 0; + if(p < 0 || p >= slength) return ""; + return s.substring(p,p+1); + } + if(method.equals("charCodeAt")) { + int p = alength >= 1 ? JS.toInt(args.elementAt(0)) : 0; + if(p < 0 || p >= slength) return new Double(Double.NaN); + return wrapInt(s.charAt(p)); + } + if(method.equals("concat")) { + StringBuffer sb = new StringBuffer(slength*2).append(s); + for(int i=0;i= 1 ? args.elementAt(0).toString() : "null"; + int start = alength >= 2 ? JS.toInt(args.elementAt(1)) : 0; + // Java's indexOf handles an out of bounds start index, it'll return -1 + return wrapInt(s.indexOf(search,start)); + } + if(method.equals("lastIndexOf")) { + String search = alength >= 1 ? args.elementAt(0).toString() : "null"; + int start = alength >= 2 ? JS.toInt(args.elementAt(1)) : 0; + // Java's indexOf handles an out of bounds start index, it'll return -1 + return wrapInt(s.lastIndexOf(search,start)); + } + if(method.equals("match")) { + return Regexp.stringMatch(s,args); + } + if(method.equals("replace")) { + return Regexp.stringReplace(s,args); + } + if(method.equals("search")) { + return Regexp.stringSearch(s,args); + } + if(method.equals("slice")) { + int a = alength >= 1 ? JS.toInt(args.elementAt(0)) : 0; + int b = alength >= 2 ? JS.toInt(args.elementAt(1)) : slength; + if(a < 0) a = slength + a; + if(b < 0) b = slength + b; + if(a < 0) a = 0; + if(b < 0) b = 0; + if(a > slength) a = slength; + if(b > slength) b = slength; + if(a > b) return ""; + return s.substring(a,b); + } + if(method.equals("split")){ + return Regexp.stringSplit(s,args); + } + if(method.equals("toLowerCase")) return s.toLowerCase(); + if(method.equals("toUpperCase")) return s.toUpperCase(); + if(method.equals("toString")) return s; + throw new JS.Exn("Attempted to call non-existent method: " + method); + } + + static Object getFromPrimitive(Object o, Object key) { + boolean returnCallable = false; + if(o instanceof Boolean) { + // no properties for Booleans + } else if(o instanceof Number) { + if(key.equals("toPrecision") || key.equals("toExponential") || key.equals("toFixed")) + returnCallable = true; + } + if(!returnCallable) { + // the string stuff applies to everything + String s = o.toString(); + + if(key.equals("length")) return wrapInt(s.length()); + + // this is sort of ugly, but this list should never change + // These should provide a complete (enough) implementation of the ECMA-262 String object + if(key.equals("substring") || key.equals("charAt") || key.equals("charCodeAt") || key.equals("concat") || + key.equals("indexOf") || key.equals("lastIndexOf") || key.equals("match") || key.equals("replace") || + key.equals("seatch") || key.equals("slice") || key.equals("split") || key.equals("toLowerCase") || + key.equals("toUpperCase") || key.equals("toString") + ) + returnCallable = true; + } + if(returnCallable) { + final Object target = o; + final String method = key.toString(); + return new JS.Callable() { + public Object call(JS.Array args) { return callMethodOnPrimitive(target,method,args); } + }; + } + return null; + } + + static class CallableStub extends JS.Callable { + private Object method; + private JS.Obj obj; + public CallableStub(JS.Obj obj, Object method) { this.obj = obj; this.method = method; } + public Object call(JS.Array args) { return obj.callMethod(method,args,false); } + } +}