// 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; import org.ibex.util.*; /** A JavaScript function, compiled into bytecode */ class JSFunction extends JS.Immutable implements ByteCodes, Tokens, Pausable { private static final JS[] emptyArgs = new JS[0]; // Fields and Accessors /////////////////////////////////////////////// int numFormalArgs = 0; ///< the number of formal arguments String sourceName; ///< the source code file that this block was drawn from private int firstLine = -1; ///< the first line of this script int[] line = new int[10]; ///< the line numbers int[] op = new int[10]; ///< the instructions Object[] arg = new Object[10]; ///< the arguments to the instructions int size = 0; ///< the number of instruction/argument pairs JSScope parentScope; ///< the default scope to use as a parent scope when executing this // Public ////////////////////////////////////////////////////////////////////////////// private Interpreter runner = null; public Object run(Object o) throws JSExn { if (runner == null) runner = new Interpreter(this, true, emptyArgs); Object ret = runner.run(o); if (runner.f == null) runner = null; return ret; } public void pause() throws NotPausableException { if (runner == null) throw new NotPausableException(); runner.pause(); } public JSFunction _cloneWithNewParentScope(JSScope s) { JSFunction ret = new JSFunction(sourceName, firstLine, s); // Reuse the same op, arg, line, and size variables for the new "instance" of the function // NOTE: Neither *this* function nor the new function should be modified after this call ret.op = this.op; ret.arg = this.arg; ret.line = this.line; ret.size = this.size; ret.numFormalArgs = this.numFormalArgs; return ret; } public JS call(JS method, JS[] args) throws JSExn { if (method != null) return super.call(method, args); return (JS)new Interpreter(this, false, args).run(null); } JSScope getParentScope() { return parentScope; } // Adding and Altering Bytecodes /////////////////////////////////////////////////// JSFunction(String sourceName, int firstLine, JSScope parentScope) { this.sourceName = sourceName; this.firstLine = firstLine; this.parentScope = parentScope; } int get(int pos) { return op[pos]; } Object getArg(int pos) { return arg[pos]; } void set(int pos, int op_, Object arg_) { op[pos] = op_; arg[pos] = arg_; } void set(int pos, Object arg_) { arg[pos] = arg_; } int pop() { size--; arg[size] = null; return op[size]; } void paste(JSFunction other) { for(int i=0; i>>16) + " size: " + (n&0xffff)); } sb.append("\n"); } return sb.toString(); } }