X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2Fjs%2FJS.java;h=f2946ea1c009d475df89b11b3c13bac8974f99ec;hb=345865827e473f64410c7e3c07e73d20a8db7c4f;hp=0a949e38c0d097e569aaa66c7b09c1a8d1e5b9be;hpb=395d61dea4f5f7b22120e8b0b3fd9b75351c0a98;p=org.ibex.core.git diff --git a/src/org/xwt/js/JS.java b/src/org/xwt/js/JS.java index 0a949e3..f2946ea 100644 --- a/src/org/xwt/js/JS.java +++ b/src/org/xwt/js/JS.java @@ -1,31 +1,64 @@ // Copyright 2002 Adam Megacz, see the COPYING file for licensing [GPL] - + package org.xwt.js; import org.xwt.util.*; +import java.io.*; +import java.util.*; /** The public API for the JS engine */ // FEATURE: try using mutable, recycled 'Num' objects -public interface JS { +public abstract class JS { + + // Static Methods ////////////////////////////////////////////////////////////////////// + + public static Function getCurrentFunction() { + return (Function)currentFunction.get(Thread.currentThread()); + } + public static String getCurrentFunctionSourceName() { + return getCurrentFunctionSourceName(Thread.currentThread()); + } + public static String getCurrentFunctionSourceName(Thread t) { + Function f = (Function)currentFunction.get(t); + if (f == null) return "null"; + return f.getSourceName(); + } + public static String getFileAndLine() { + return "unknown:??"; + } + + + // Instance Methods //////////////////////////////////////////////////////////////////// public abstract Object get(Object key) throws JS.Exn; public abstract void put(Object key, Object val) throws JS.Exn; - public abstract Object[] enumerateProperties(); + public abstract Object[] keys(); + + public Number coerceToNumber() { throw new Error("you cannot coerce a " + this.getClass().getName() + " into a Number"); } + public String coerceToString() { throw new Error("you cannot coerce a " + this.getClass().getName() + " into a String"); } + public boolean coerceToBoolean() { throw new Error("you cannot coerce a " + this.getClass().getName() + " into a Boolean"); } + - public abstract Number coerceToNumber() throws JS.Exn; - public abstract boolean coerceToBoolean() throws JS.Exn; - public abstract String coerceToString() throws JS.Exn; + // Subclasses ///////////////////////////////////////////////////////////////////////// - public static class Obj implements JS { - private Hash entries; - public Obj() { } + public static class Obj extends JS { + private Hash entries = new Hash(); + private boolean sealed = false; + public Obj() { this(false); } + public Obj(boolean sealed) { this.sealed = sealed; } + public void setSeal(boolean sealed) { this.sealed = sealed; } public Object get(Object key) { return entries.get(key); } - public void put(Object key, Object val) { entries.put(key, val); } - public Object[] enumerateProperties() { return(entries.keys()); } - public Number coerceToNumber() { throw new Error("tried to turn a Object into a Number"); } - public String coerceToString() { throw new Error("tried to turn a Object into a String"); } - public boolean coerceToBoolean() { throw new Error("tried to turn a Object into a Boolean"); } + public void put(Object key, Object val) { if (!sealed) entries.put(key, val); } + public Object[] keys() { return(entries.keys()); } } + public static class Exn extends RuntimeException { + private Object js = null; + public Exn(Object js) { this.js = js; } + public String toString() { return "JS.Exn: " + js.toString(); } + public String getMessage() { return toString(); } + public Object getObject() { return js; } + } + public static class Array extends Obj { private Vec vec = new Vec(); private static int intVal(Object o) { @@ -39,55 +72,112 @@ public interface JS { for(int i=0; i '9') return Integer.MIN_VALUE; return Integer.parseInt(s); } - public Object get(Object key) { + public Object get(Object key) throws JS.Exn { + // FIXME: HACK! + if (key.equals("cascade")) return org.xwt.Trap.cascadeFunction; + if (key.equals("trapee")) return org.xwt.Trap.currentTrapee(); if (key.equals("length")) return new Long(vec.size()); int i = intVal(key); if (i == Integer.MIN_VALUE) return super.get(key); - return vec.elementAt(i); + try { + return vec.elementAt(i); + } catch (ArrayIndexOutOfBoundsException e) { + throw new JS.Exn(e.getMessage()); + } } public void put(Object key, Object val) { - if (key.equals("length")) vec.setSize(Expr.toNumber(val).intValue()); + if (key.equals("length")) vec.setSize(Parser.toNumber(val).intValue()); int i = intVal(key); if (i == Integer.MIN_VALUE) super.put(key, val); - else vec.setElementAt(val, i); + else { + if (i >= vec.size()) vec.setSize(i+1); + vec.setElementAt(val, i); + } } - public Object[] enumerateProperties() { return null; } // FIXME - void addElement(Object o) { vec.addElement(o); } + public Object[] keys() { + Object[] sup = super.keys(); + Object[] ret = new Object[vec.size() + 1 + sup.length]; + System.arraycopy(sup, 0, ret, vec.size(), sup.length); + for(int i=0; i