// Copyright 2000-2005 the Contributors, as shown in the revision logs. // Licensed under the Apache Public Source License 2.0 ("the License"). // You may not use this file except in compliance with the License. package org.ibex.js; /** Implementation of a JavaScript Scope */ class JSScope { private final int base; private final JS[] vars; final JSScope parent; 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(JSU.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(JSU.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(); } public static class Global extends JS.Immutable { private final static JS NaN = JSU.N(Double.NaN); private final static JS POSITIVE_INFINITY = JSU.N(Double.POSITIVE_INFINITY); private final static JS.Method METHOD = new JS.Method(); public Global() { } public JS get(JS key) throws JSExn { //#jsswitch(key) case "NaN": return NaN; case "Infinity": return POSITIVE_INFINITY; case "undefined": return null; case "stringFromCharCode": return METHOD; case "parseInt": return METHOD; case "isNaN": return METHOD; case "isFinite": return METHOD; case "decodeURI": return METHOD; case "decodeURIComponent": return METHOD; case "encodeURI": return METHOD; case "encodeURIComponent": return METHOD; case "escape": return METHOD; case "unescape": return METHOD; case "parseInt": return METHOD; //#end return super.get(key); } public JS call(JS method, JS[] args) throws JSExn { switch(args.length) { case 0: { //#jsswitch(method) case "stringFromCharCode": char buf[] = new char[args.length]; for(int i=0; i 36)) return NaN; while (start < length && Character.isWhitespace(s.charAt(start))) start++; if ((length >= start+1) && (s.charAt(start) == '+' || s.charAt(start) == '-')) { sign = s.charAt(start) == '+' ? 1 : -1; start++; } if(radix == 0 && length >= start+1 && s.charAt(start) == '0') { start++; if(length >= start+1 && (s.charAt(start) == 'x' || s.charAt(start) == 'X')) { start++; radix = 16; } else { radix = 8; if(length == start || Character.digit(s.charAt(start+1),8)==-1) return JSU.ZERO; } } if(radix == 0) radix = 10; if(length == start || Character.digit(s.charAt(start),radix) == -1) return NaN; // try the fast way first try { String s2 = start == 0 ? s : s.substring(start); return JSU.N(sign*Integer.parseInt(s2,radix)); } catch(NumberFormatException e) { } // fall through to a slower but emca-compliant method for(int i=start;i