X-Git-Url: http://git.megacz.com/?p=org.ibex.core.git;a=blobdiff_plain;f=src%2Forg%2Fibex%2Fjs%2FJS.java;h=81feec199093394a70e63231faf9b51d17edf3c8;hp=0290e46c363a86653358c275ef8097e80bc1ac56;hb=fffcafc33aa4066bdf85da7a32e1a1cdb9db2d6f;hpb=592fa04faf2d7c5bbf5fceae5a81da13f4791261 diff --git a/src/org/ibex/js/JS.java b/src/org/ibex/js/JS.java index 0290e46..81feec1 100644 --- a/src/org/ibex/js/JS.java +++ b/src/org/ibex/js/JS.java @@ -6,29 +6,68 @@ import java.io.*; import java.util.*; /** The minimum set of functionality required for objects which are manipulated by JavaScript */ -public class JS extends org.ibex.util.BalancedTree { +public abstract class JS { public static boolean checkAssertions = false; public static final Object METHOD = new Object() { public String toString() { return "JS.METHOD"; } }; public final JS unclone() { return _unclone(); } public final JS jsclone() throws JSExn { return new Clone(this); } - public Enumeration keys() throws JSExn { return entries == null ? emptyEnumeration : entries.keys(); } - public Object get(Object key) throws JSExn { return entries == null ? null : entries.get(key, null); } - public void put(Object key, Object val) throws JSExn { (entries==null?entries=new Hash():entries).put(key,null,val); } + + public Enumeration keys() throws JSExn { throw new JSExn("you can't enumerate the keys of this object (class=" + this.getClass().getName() +")"); } + public Object get(Object key) throws JSExn { return null; } + public void put(Object key, Object val) throws JSExn { throw new JSExn("this object is read only (class=" + this.getClass().getName() +")"); } + + public final boolean hasTrap(Object key) { return getTrap(key) != null; } + public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn { - throw new JSExn("you cannot call this object (class=" + this.getClass().getName() +")"); + throw new JSExn("method not found (" + method + ")"); } + // FIXME: JSArgs objects, pointers into stack frame public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn { throw new JSExn("you cannot call this object (class=" + this.getClass().getName() +")"); } + Trap getTrap(Object key) { return null; } + void putTrap(Object key, Trap value) throws JSExn { throw new JSExn("traps cannot be placed on this object (class=" + this.getClass().getName() +")"); } + + public static class O extends JS { + private Hash entries; + + public Enumeration keys() throws JSExn { return entries == null ? emptyEnumeration : entries.keys(); } + public Object get(Object key) throws JSExn { return entries == null ? null : entries.get(key, null); } + public void put(Object key, Object val) throws JSExn { (entries==null?entries=new Hash():entries).put(key,null,val); } + + /** retrieve a trap from the entries hash */ + final Trap getTrap(Object key) { + return entries == null ? null : (Trap)entries.get(key, Trap.class); + } + + /** retrieve a trap from the entries hash */ + final void putTrap(Object key, Trap value) { + if (entries == null) entries = new Hash(); + entries.put(key, Trap.class, value); + } + } + + public static class BT extends O { + private BalancedTree bt; + private final BalancedTree bt() { if(bt != null) return bt; return bt = new BalancedTree(); } + public final void insertNode(int index, Object o) { bt().insertNode(index,o); } + public final void clear() { bt().clear(); } + public final Object getNode(int i) { return bt().getNode(i); } + public final int treeSize() { return bt().treeSize(); } + public final Object deleteNode(int i) { return bt().deleteNode(i); } + public final void replaceNode(int index, Object o) { bt().replaceNode(index,o); } + public final int indexNode(Object o) { return bt().indexNode(o); } + } + JS _unclone() { return this; } public interface Cloneable { } - public static class Clone extends JS implements Cloneable { + public static class Clone extends JS.O implements Cloneable { protected JS clonee; JS _unclone() { return clonee.unclone(); } public JS getClonee() { return clonee; } @@ -178,8 +217,6 @@ public class JS extends org.ibex.util.BalancedTree { public Object nextElement() { throw new NoSuchElementException(); } }; - private Hash entries = null; - public static JS fromReader(String sourceName, int firstLine, Reader sourceCode) throws IOException { return JSFunction._fromReader(sourceName, firstLine, sourceCode); } @@ -192,11 +229,6 @@ public class JS extends org.ibex.util.BalancedTree { // Trap support ////////////////////////////////////////////////////////////////////////////// - /** override and return true to allow placing traps on this object. - * if isRead true, this is a read trap, otherwise write trap - **/ - protected boolean isTrappable(Object name, boolean isRead) { return true; } - /** performs a put, triggering traps if present; traps are run in an unpauseable interpreter */ public void putAndTriggerTraps(Object key, Object value) throws JSExn { Trap t = getTrap(key); @@ -211,28 +243,16 @@ public class JS extends org.ibex.util.BalancedTree { else return get(key); } - /** retrieve a trap from the entries hash */ - protected final Trap getTrap(Object key) { - return entries == null ? null : (Trap)entries.get(key, Trap.class); - } - - /** retrieve a trap from the entries hash */ - protected final void putTrap(Object key, Trap value) { - if (entries == null) entries = new Hash(); - entries.put(key, Trap.class, value); - } - /** adds a trap, avoiding duplicates */ protected final void addTrap(Object name, JSFunction f) throws JSExn { if (f.numFormalArgs > 1) throw new JSExn("traps must take either one argument (write) or no arguments (read)"); boolean isRead = f.numFormalArgs == 0; - if (!isTrappable(name, isRead)) throw new JSExn("not allowed "+(isRead?"read":"write")+" trap on property: "+name); for(Trap t = getTrap(name); t != null; t = t.next) if (t.f == f) return; putTrap(name, new Trap(this, name.toString(), f, (Trap)getTrap(name))); } /** deletes a trap, if present */ - protected final void delTrap(Object name, JSFunction f) { + protected final void delTrap(Object name, JSFunction f) throws JSExn { Trap t = (Trap)getTrap(name); if (t == null) return; if (t.f == f) { putTrap(t.name, t.next); return; }