import org.xwt.util.*;
import java.io.*;
+// FIXME: could use some cleaning up
/** a JavaScript function, compiled into bytecode */
-class CompiledFunctionImpl extends JS.Callable implements ByteCodes, Tokens {
+class CompiledFunctionImpl extends JSCallable implements ByteCodes, Tokens {
// Fields and Accessors ///////////////////////////////////////////////
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];
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)); }
int pc = 0;
void eval(JS.Scope s) {
- final Vec t = JS.Thread.fromJavaThread(java.lang.Thread.currentThread()).stack;
+ final JS.Thread cx = JS.Thread.fromJavaThread(java.lang.Thread.currentThread());
+ final Vec t = cx.stack;
OUTER: for(pc=0; pc<size; pc++) {
String label = null;
+ cx.line = line[pc];
switch(op[pc]) {
case LITERAL: t.push(arg[pc]); break;
case OBJECT: t.push(new JS.Obj()); break;
// 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() {
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");
}
}
}
+
+/** this class exists solely to work around a GCJ bug */
+abstract class JSCallable extends JS.Callable {
+ public abstract Object call(JS.Array args) throws JS.Exn;
+}