From: megacz Date: Fri, 30 Jan 2004 07:00:58 +0000 (+0000) Subject: 2003/06/09 06:38:36 X-Git-Tag: RC3~933 X-Git-Url: http://git.megacz.com/?p=org.ibex.core.git;a=commitdiff_plain;h=2a94571c07db6db966f6bfa32583a72287f4db29 2003/06/09 06:38:36 darcs-hash:20040130070058-2ba56-d6fca2757abec5586a8c422d91e8d7241777d070.gz --- diff --git a/src/org/xwt/js/ByteCodeBlock.java b/src/org/xwt/js/ByteCodeBlock.java index 2da760d..54b8169 100644 --- a/src/org/xwt/js/ByteCodeBlock.java +++ b/src/org/xwt/js/ByteCodeBlock.java @@ -109,7 +109,8 @@ public class ByteCodeBlock implements ByteCodes, Tokens { Object key = t.pop(); JS target = (JS)t.peek(); if (target == null) - throw new JS.Exn("tried to put a value to the " + key + " property on the null value"); + throw new JS.Exn(sourceName + ":" + line + ": tried to put a value to the " + key + + " property on the null value"); target.put(key, val); t.push(val); break; @@ -136,7 +137,7 @@ public class ByteCodeBlock implements ByteCodes, Tokens { arguments.setSize(numArgs); for(int j=numArgs - 1; j >= 0; j--) arguments.setElementAt(t.pop(), j); JS.Function f = (JS.Function)t.pop(); - if (f == null) throw new JS.Exn("attempted to call null"); + if (f == null) throw new JS.Exn(sourceName + ":" + line + ": attempted to call null"); t.push(f.call(arguments)); break; } @@ -214,10 +215,10 @@ public class ByteCodeBlock implements ByteCodes, Tokens { public Object doGet(final Object o, final Object v) { if (o == null) - throw new JS.Exn("tried to get property \"" + v + "\" from the null value"); + throw new JS.Exn(sourceName + ":" + line + ": tried to get property \"" + v + "\" from the null value"); if (o instanceof String) { if (v.equals("length")) return new Integer(((String)o).length()); - else if (v.equals("substring")) return new JS.Function() { + else if (v.equals("substring")) return new JS.Function(-1, "java", null, null) { public Object _call(JS.Array args) { if (args.length() == 1) return ((String)o).substring(JS.toNumber(args.elementAt(0)).intValue()); else if (args.length() == 2) return ((String)o).substring(JS.toNumber(args.elementAt(0)).intValue(), @@ -225,24 +226,24 @@ public class ByteCodeBlock implements ByteCodes, Tokens { else throw new Error("String.substring() can only take one or two arguments"); } }; - else if (v.equals("toLowerCase")) return new JS.Function() { + else if (v.equals("toLowerCase")) return new JS.Function(-1, "java", null, null) { public Object _call(JS.Array args) { return ((String)o).toLowerCase(); } }; - else if (v.equals("toUpperCase")) return new JS.Function() { + else if (v.equals("toUpperCase")) return new JS.Function(-1, "java", null, null) { public Object _call(JS.Array args) { return ((String)o).toString().toUpperCase(); } }; - else if (v.equals("charAt")) return new JS.Function() { + else if (v.equals("charAt")) return new JS.Function(-1, "java", null, null) { public Object _call(JS.Array args) { return ((String)o).charAt(JS.toNumber(args.elementAt(0)).intValue()) + ""; } }; - else if (v.equals("lastIndexOf")) return new JS.Function() { + else if (v.equals("lastIndexOf")) return new JS.Function(-1, "java", null, null) { public Object _call(JS.Array args) { if (args.length() != 1) return null; return new Integer(((String)o).lastIndexOf(args.elementAt(0).toString())); } }; - else if (v.equals("indexOf")) return new JS.Function() { + else if (v.equals("indexOf")) return new JS.Function(-1, "java", null, null) { public Object _call(JS.Array args) { if (args.length() != 1) return null; return new Integer(((String)o).indexOf(args.elementAt(0).toString())); diff --git a/src/org/xwt/js/JS.java b/src/org/xwt/js/JS.java index b0d54e5..d3da1f1 100644 --- a/src/org/xwt/js/JS.java +++ b/src/org/xwt/js/JS.java @@ -104,7 +104,7 @@ public abstract class JS { try { return vec.elementAt(i); } catch (ArrayIndexOutOfBoundsException e) { - throw new JS.Exn(e.getMessage()); + return null; } } public void put(Object key, Object val) { @@ -137,24 +137,28 @@ public abstract class JS { int line; String sourceName; Scope parentScope; - public Function() { this(-1, "unknown", null, null); } public Function(int line, String sourceName, ByteCodeBlock bytecodes, Scope parentScope) { this.sourceName = sourceName; this.line = line; this.bytecodes = bytecodes; this.parentScope = parentScope; } + public Function cloneWithNewParentScope(Scope s) { + if (this.getClass() != Function.class) + throw new Error("org.xwt.js.JS.Function.cloneWithNewParentScope() is not valid for subclasses"); + return new Function(line, sourceName, bytecodes, s); + } public String getSourceName() throws JS.Exn { return sourceName; } public int getLine() throws JS.Exn { return line; } public Object _call(JS.Array args) throws JS.Exn, ByteCodeBlock.ControlTransferException { if (bytecodes == null) throw new Error("tried to call() a JS.Function with bytecodes == null"); Vec stack = new Vec(); stack.push(args); - return bytecodes.eval(new FunctionScope(sourceName, parentScope), stack); + return bytecodes.eval(args == null ? parentScope : new FunctionScope(sourceName, parentScope), stack); } public final Object call(JS.Array args) throws JS.Exn { Function saved = (Function)currentFunction.get(Thread.currentThread()); - currentFunction.put(Thread.currentThread(), this); + if (!getSourceName().equals("java")) currentFunction.put(Thread.currentThread(), this); try { return _call(args); } catch (ByteCodeBlock.ReturnException e) { // ignore @@ -169,29 +173,19 @@ public abstract class JS { } } - public static class Script extends Function { - Vector e = null; - private Script(Vector e) { this.e = e; } - public String getSourceName() throws JS.Exn { return ((ByteCodeBlock)e.elementAt(0)).getSourceName(); } - public Object _call(JS.Array args) throws JS.Exn, ByteCodeBlock.ControlTransferException { - Scope rootScope = (Scope)args.elementAt(0); - for(int i=0; i 0 && precedence[tok] != 0) - if (precedence[tok] < minPrecedence || (precedence[tok] == minPrecedence && !isRightAssociative[tok])) - { pushBackToken(); return; } ByteCodeBlock b = appendTo; @@ -111,7 +104,8 @@ class Parser extends Lexer implements ByteCodes { } case SUB: { consume(NUMBER); - continueExpr(b.add(ByteCodeBlock.LITERAL, new Double(number.doubleValue() * -1)), minPrecedence); + b.add(ByteCodeBlock.LITERAL, new Double(number.doubleValue() * -1)); + continueExpr(b, minPrecedence); return; } case LP: { @@ -536,7 +530,8 @@ class Parser extends Lexer implements ByteCodes { consume(LP); tok = getToken(); - if (tok == VAR) tok = getToken(); + boolean hadVar = false; + if (tok == VAR) { hadVar = true; tok = getToken(); } String varName = string; boolean forIn = peekToken() == IN; pushBackToken(tok, varName); @@ -566,14 +561,13 @@ class Parser extends Lexer implements ByteCodes { break; } else { + if (hadVar) pushBackToken(VAR, null); ByteCodeBlock b2 = newbb(curLine); b.add(SCOPE, b2); b.add(POP); int size = b2.size(); - startExpr(b2); - if (b2.size() - size > 0) b2.add(POP); - consume(SEMI); + parseStatement(false, b2); ByteCodeBlock e2 = startExpr(); consume(SEMI); if (e2 == null) e2 = newbb(curLine).add(b.LITERAL, null); @@ -593,7 +587,7 @@ class Parser extends Lexer implements ByteCodes { b3.add(JT, new Integer(2)); b3.add(BREAK); parseStatement(false, b3); - b3.add(BREAK); + b3.add(CONTINUE); break; } }