X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fibex%2Fjs%2FJSScope.java;h=9b9a3b111875ddefb202d8d3339e435112ec324c;hb=3f8aa5300e178e8975b0edc896a5a9d303e7bdf3;hp=663e24d494bf046c94b426dc13c9e9bb0ae292a6;hpb=fffcafc33aa4066bdf85da7a32e1a1cdb9db2d6f;p=org.ibex.core.git diff --git a/src/org/ibex/js/JSScope.java b/src/org/ibex/js/JSScope.java index 663e24d..9b9a3b1 100644 --- a/src/org/ibex/js/JSScope.java +++ b/src/org/ibex/js/JSScope.java @@ -1,28 +1,66 @@ // Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL] package org.ibex.js; -// FIXME: should allow parentScope to be a JS, not a JSScope -// FIXME: Index local vars by number and lookup in an array /** Implementation of a JavaScript Scope */ -// HACK = JSScope doesn't really need the BT, this is just for Box.java -public class JSScope extends JS.BT { +class JSScope { - private JSScope parentScope; + private final int base; + private final JS[] vars; + final JSScope parent; - private static final Object NULL_PLACEHOLDER = new Object(); + public static class Top extends JSScope { + private final JS global; + public Top(JS global) { super(null,0,0); this.global = global; } + JS get(int i) throws JSExn { throw new JSExn("scope index out of range"); } + void put(int i, JS o) throws JSExn { throw new JSExn("scope index out of range"); } + JS getGlobal() { return global; } + }; + + // NOTE: We can't just set base to parent.base + parent.vars.length + // sometimes we only access part of a parent's scope + public JSScope(JSScope parent, int base, int size) { + this.parent = parent; + this.base = base; + this.vars = new JS[size]; + } + + final JS get(JS i) throws JSExn { + if(i==null) throw new NullPointerException(); + try { + return get(JS.toInt(i)); + } catch(ArrayIndexOutOfBoundsException e) { + throw new JSExn("scope index out of range"); + } + } + final void put(JS i, JS o) throws JSExn { + if(i==null) throw new NullPointerException(); + try { + put(JS.toInt(i),o); + } catch(ArrayIndexOutOfBoundsException e) { + throw new JSExn("scope index out of range"); + } + } + JS get(int i) throws JSExn { return i < base ? parent.get(i) : vars[i-base]; } + void put(int i, JS o) throws JSExn { if(i < base) parent.put(i,o); else vars[i-base] = o; } + + JS getGlobal() { return parent.getGlobal(); } + + /*private JSScope parentScope; + + private static final JS NULL_PLACEHOLDER = new JS() { }; public JSScope(JSScope parentScope) { this.parentScope = parentScope; } - public void declare(String s) throws JSExn { super.put(s, NULL_PLACEHOLDER); } + public void declare(JS s) throws JSExn { super.put(s, NULL_PLACEHOLDER); } public JSScope getParentScope() { return parentScope; } - public Object get(Object key) throws JSExn { - Object o = super.get(key); + public JS get(JS key) throws JSExn { + JS o = super.get(key); if (o != null) return o == NULL_PLACEHOLDER ? null : o; else return parentScope == null ? null : parentScope.get(key); } - public boolean has(Object key) throws JSExn { return super.get(key) != null; } - public void put(Object key, Object val) throws JSExn { + public boolean has(JS key) throws JSExn { return super.get(key) != null; } + public void put(JS key, JS val) throws JSExn { if (parentScope != null && !has(key)) parentScope.put(key, val); else super.put(key, val == null ? NULL_PLACEHOLDER : val); } @@ -34,12 +72,24 @@ public class JSScope extends JS.BT { } public static class Global extends JSScope { - private final static Double NaN = new Double(Double.NaN); - private final static Double POSITIVE_INFINITY = new Double(Double.POSITIVE_INFINITY); + private final static JS NaN = N(Double.NaN); + private final static JS POSITIVE_INFINITY = N(Double.POSITIVE_INFINITY); public Global() { super(null); } - public Object get(Object key) throws JSExn { - //#switch(key) + public Global(JSScope p) { super(p); } + + public void declare(JS k) throws JSExn { throw new JSExn("can't declare variables in the global scope"); } + + // HACK: "this" gets lost on the way back through the scope chain + // We'll have to do something better with this when Scope is rewritten + public JS get(JS key) throws JSExn { + JS ret = _get(key); + if(ret == METHOD) return new Interpreter.Stub(this,key); + return ret; + } + + public JS _get(JS key) throws JSExn { + //#jswitch(key) case "NaN": return NaN; case "Infinity": return POSITIVE_INFINITY; case "undefined": return null; @@ -58,43 +108,24 @@ public class JSScope extends JS.BT { return super.get(key); } - public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn { - switch(nargs) { - case 0: { - //#switch(method) - case "stringFromCharCode": - char buf[] = new char[nargs]; - for(int i=0; i