X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2Fjs%2FCompiledFunctionImpl.java;h=e111040d8d220cfa1bc0501d949a07fd7c625913;hb=59e6b17875dbdfdfd9850fd783be5231eed1a7b8;hp=692db3f7cb4987a67edd2b586b63bbe125d90274;hpb=b32cea3f3e272ab00899d134d75a8bd7bcf6c8c0;p=org.ibex.core.git diff --git a/src/org/xwt/js/CompiledFunctionImpl.java b/src/org/xwt/js/CompiledFunctionImpl.java index 692db3f..e111040 100644 --- a/src/org/xwt/js/CompiledFunctionImpl.java +++ b/src/org/xwt/js/CompiledFunctionImpl.java @@ -4,8 +4,9 @@ package org.xwt.js; import org.xwt.util.*; import java.io.*; +// FIXME: could use some cleaning up /** a JavaScript function, compiled into bytecode */ -public class CompiledFunctionImpl extends JS.Callable implements ByteCodes, Tokens { +class CompiledFunctionImpl extends JSCallable implements ByteCodes, Tokens { // Fields and Accessors /////////////////////////////////////////////// @@ -13,13 +14,12 @@ public class CompiledFunctionImpl extends JS.Callable implements ByteCodes, Toke private String sourceName; public String getSourceName() throws JS.Exn { return sourceName; } - /** the first line of this function */ - private int firstLine; - public int getFirstLine() throws JS.Exn { return firstLine; } - /** the line numbers */ private int[] line = new int[10]; + /** the first line of this script */ + private int firstLine = -1; + /** the instructions */ private int[] op = new int[10]; @@ -48,36 +48,29 @@ public class CompiledFunctionImpl extends JS.Callable implements ByteCodes, Toke this.parentScope = parentScope; if (sourceCode == null) return; Parser p = new Parser(sourceCode, sourceName, firstLine); - try { - while(true) { - int s = size(); - p.parseStatement(this, null); - if (s == size()) break; - } - add(-1, Tokens.RETURN); - } catch (Exception e) { - if (Log.on) Log.log(Parser.class, e); + while(true) { + int s = size(); + p.parseStatement(this, null); + if (s == size()) break; } + add(-1, Tokens.RETURN); } public Object call(JS.Array args) throws JS.Exn { return call(args, new FunctionScope(sourceName, parentScope)); } public Object call(JS.Array args, JS.Scope scope) throws JS.Exn { - CompiledFunctionImpl saved = (CompiledFunctionImpl)Context.currentFunction.get(Thread.currentThread()); + JS.Thread cx = JS.Thread.fromJavaThread(java.lang.Thread.currentThread()); + CompiledFunction saved = cx.currentCompiledFunction; try { - Context.currentFunction.put(Thread.currentThread(), this); - Context cx = Context.getContextForThread(Thread.currentThread()); + cx.currentCompiledFunction = (CompiledFunction)this; int size = cx.stack.size(); - cx.stack.push(new Context.CallMarker()); + cx.stack.push(new CallMarker()); cx.stack.push(args); eval(scope); Object ret = cx.stack.pop(); - if (cx.stack.size() > size) - Log.log(this, "warning, stack grew by " + (cx.stack.size() - size) + - " elements during call to " + Context.getCurrentSourceNameAndLine()); + if (cx.stack.size() > size) Log.logJS(this, "warning, stack grew by " + (cx.stack.size() - size) + " elements during call"); return ret; } finally { - if (saved == null) Context.currentFunction.remove(Thread.currentThread()); - else Context.currentFunction.put(Thread.currentThread(), saved); + cx.currentCompiledFunction = saved; } } @@ -107,9 +100,11 @@ public class CompiledFunctionImpl extends JS.Callable implements ByteCodes, Toke int pc = 0; void eval(JS.Scope s) { - final Vec t = Context.getContextForThread(Thread.currentThread()).stack; + final JS.Thread cx = JS.Thread.fromJavaThread(java.lang.Thread.currentThread()); + final Vec t = cx.stack; OUTER: for(pc=0; pc 0 && op[pc - 1] == LABEL ? (String)arg[pc - 1] : (String)null)); + t.push(new LoopMarker(pc, pc > 0 && op[pc - 1] == LABEL ? (String)arg[pc - 1] : (String)null)); t.push(Boolean.TRUE); break; } @@ -171,10 +166,10 @@ public class CompiledFunctionImpl extends JS.Callable implements ByteCodes, Toke case CONTINUE: while(t.size() > 0) { Object o = t.pop(); - if (o instanceof Context.CallMarker) ee("break or continue not within a loop"); - if (o != null && o instanceof Context.LoopMarker) { - if (arg[pc] == null || arg[pc].equals(((Context.LoopMarker)o).label)) { - int loopInstructionLocation = ((Context.LoopMarker)o).location; + if (o instanceof CallMarker) ee("break or continue not within a loop"); + if (o != null && o instanceof LoopMarker) { + if (arg[pc] == null || arg[pc].equals(((LoopMarker)o).label)) { + int loopInstructionLocation = ((LoopMarker)o).location; int endOfLoop = ((Integer)arg[loopInstructionLocation]).intValue() + loopInstructionLocation; s = (JS.Scope)t.pop(); if (op[pc] == CONTINUE) { t.push(s); t.push(o); t.push(Boolean.FALSE); } @@ -186,7 +181,7 @@ public class CompiledFunctionImpl extends JS.Callable implements ByteCodes, Toke throw new Error("CONTINUE/BREAK invoked but couldn't find a LoopMarker at " + sourceName + ":" + line); case TRY: { - t.push(new Context.TryMarker(pc + ((Integer)arg[pc]).intValue(), s)); + t.push(new TryMarker(pc + ((Integer)arg[pc]).intValue(), s)); break; } @@ -194,7 +189,7 @@ public class CompiledFunctionImpl extends JS.Callable implements ByteCodes, Toke Object retval = t.pop(); while(t.size() > 0) { Object o = t.pop(); - if (o != null && o instanceof Context.CallMarker) { + if (o != null && o instanceof CallMarker) { t.push(retval); return; } @@ -261,10 +256,10 @@ public class CompiledFunctionImpl extends JS.Callable implements ByteCodes, Toke Object exn = t.pop(); while(t.size() > 0) { Object o = t.pop(); - if (o instanceof Context.TryMarker) { + if (o instanceof TryMarker) { t.push(exn); - pc = ((Context.TryMarker)o).location - 1; - s = ((Context.TryMarker)o).scope; + pc = ((TryMarker)o).location - 1; + s = ((TryMarker)o).scope; continue OUTER; } } @@ -352,14 +347,14 @@ public class CompiledFunctionImpl extends JS.Callable implements ByteCodes, Toke // Helpers for Number, String, and Boolean //////////////////////////////////////// - private Object getFromString(final String o, final Object v) { + private static Object getFromString(final String o, final Object v) { if (v.equals("length")) return new Integer(((String)o).length()); else if (v.equals("substring")) return new JS.Callable() { 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(), JS.toNumber(args.elementAt(1)).intValue()); - else throw je("String.substring() can only take one or two arguments"); + else throw new JS.Exn("String.substring() can only take one or two arguments"); } }; else if (v.equals("toLowerCase")) return new JS.Callable() { @@ -384,7 +379,7 @@ public class CompiledFunctionImpl extends JS.Callable implements ByteCodes, Toke if (args.length() != 1) return null; return new Integer(((String)o).indexOf(args.elementAt(0).toString())); } }; - throw je("Not Implemented: propery " + v + " on String objects"); + throw new JS.Exn("Not Implemented: propery " + v + " on String objects"); } @@ -407,4 +402,29 @@ public class CompiledFunctionImpl extends JS.Callable implements ByteCodes, Toke return super.get(key); } } + + + // Markers ////////////////////////////////////////////////////////////////////// + + public static class CallMarker { public CallMarker() { } } + public static class LoopMarker { + public int location; + public String label; + public LoopMarker(int location, String label) { + this.location = location; + this.label = label; + } + } + public static class TryMarker { + public int location; + public JS.Scope scope; + public TryMarker(int location, JS.Scope scope) { + this.location = location; + this.scope = scope; + } + } + +} + +class JSCallable extends JS.Callable { }