From 434d61b704a72e8c8dcd43853a9dfbc0af68911d Mon Sep 17 00:00:00 2001 From: megacz Date: Fri, 30 Jan 2004 07:00:23 +0000 Subject: [PATCH] 2003/05/12 05:31:48 darcs-hash:20040130070023-2ba56-f361d23d2adc7369e11b850983bd48b69a2ef879.gz --- src/org/mozilla/javascript/Arguments.java | 150 -- src/org/mozilla/javascript/BaseFunction.java | 521 ---- src/org/mozilla/javascript/BinaryDigitReader.java | 75 - .../javascript/ClassDefinitionException.java | 48 - src/org/mozilla/javascript/ClassNameHelper.java | 63 - src/org/mozilla/javascript/ClassOutput.java | 57 - src/org/mozilla/javascript/Context.java | 2201 ----------------- src/org/mozilla/javascript/ContextListener.java | 53 - src/org/mozilla/javascript/DToA.java | 1197 ---------- .../mozilla/javascript/DebuggableEngineImpl.java | 111 - .../mozilla/javascript/DefaultErrorReporter.java | 65 - src/org/mozilla/javascript/Delegator.java | 250 -- src/org/mozilla/javascript/EcmaError.java | 152 -- src/org/mozilla/javascript/ErrorReporter.java | 103 - src/org/mozilla/javascript/EvaluatorException.java | 56 - src/org/mozilla/javascript/FlattenedObject.java | 341 --- src/org/mozilla/javascript/Function.java | 86 - src/org/mozilla/javascript/FunctionNode.java | 103 - src/org/mozilla/javascript/FunctionObject.java | 626 ----- src/org/mozilla/javascript/IRFactory.java | 1065 --------- src/org/mozilla/javascript/IdFunction.java | 164 -- src/org/mozilla/javascript/IdFunctionMaster.java | 54 - src/org/mozilla/javascript/IdScriptable.java | 577 ----- src/org/mozilla/javascript/ImporterTopLevel.java | 176 -- .../mozilla/javascript/InterpretedFunction.java | 135 -- src/org/mozilla/javascript/InterpretedScript.java | 102 - src/org/mozilla/javascript/Interpreter.java | 2514 -------------------- src/org/mozilla/javascript/InterpreterData.java | 130 - src/org/mozilla/javascript/InterpreterFrame.java | 77 - src/org/mozilla/javascript/Invoker.java | 54 - src/org/mozilla/javascript/JavaMembers.java | 591 ----- .../mozilla/javascript/JavaScriptException.java | 114 - src/org/mozilla/javascript/Label.java | 106 - src/org/mozilla/javascript/LabelTable.java | 80 - src/org/mozilla/javascript/LazilyLoadedCtor.java | 133 -- src/org/mozilla/javascript/LineBuffer.java | 412 ---- src/org/mozilla/javascript/ListenerArray.java | 131 - src/org/mozilla/javascript/LocalVariable.java | 79 - src/org/mozilla/javascript/NativeArray.java | 1147 --------- src/org/mozilla/javascript/NativeBoolean.java | 168 -- src/org/mozilla/javascript/NativeCall.java | 171 -- src/org/mozilla/javascript/NativeDate.java | 1713 ------------- src/org/mozilla/javascript/NativeError.java | 204 -- src/org/mozilla/javascript/NativeFunction.java | 798 ------- src/org/mozilla/javascript/NativeGlobal.java | 843 ------- src/org/mozilla/javascript/NativeJavaArray.java | 155 -- src/org/mozilla/javascript/NativeJavaClass.java | 275 --- .../mozilla/javascript/NativeJavaConstructor.java | 86 - src/org/mozilla/javascript/NativeJavaMethod.java | 517 ---- src/org/mozilla/javascript/NativeJavaObject.java | 926 ------- src/org/mozilla/javascript/NativeJavaPackage.java | 240 -- src/org/mozilla/javascript/NativeMath.java | 405 ---- src/org/mozilla/javascript/NativeNumber.java | 280 --- src/org/mozilla/javascript/NativeObject.java | 291 --- src/org/mozilla/javascript/NativeScript.java | 286 --- src/org/mozilla/javascript/NativeString.java | 950 -------- src/org/mozilla/javascript/NativeWith.java | 195 -- src/org/mozilla/javascript/Node.java | 489 ---- src/org/mozilla/javascript/NodeTransformer.java | 743 ------ .../mozilla/javascript/NotAFunctionException.java | 52 - src/org/mozilla/javascript/Parser.java | 1519 ------------ .../mozilla/javascript/PreorderNodeIterator.java | 92 - src/org/mozilla/javascript/PropertyException.java | 65 - src/org/mozilla/javascript/RegExpProxy.java | 68 - src/org/mozilla/javascript/Script.java | 73 - src/org/mozilla/javascript/ScriptRuntime.java | 2168 ----------------- src/org/mozilla/javascript/Scriptable.java | 339 --- src/org/mozilla/javascript/ScriptableObject.java | 1807 -------------- src/org/mozilla/javascript/SecuritySupport.java | 148 -- .../mozilla/javascript/ShallowNodeIterator.java | 69 - src/org/mozilla/javascript/SourceTextItem.java | 222 -- src/org/mozilla/javascript/SourceTextManager.java | 82 - src/org/mozilla/javascript/Synchronizer.java | 77 - src/org/mozilla/javascript/TokenStream.java | 1440 ----------- src/org/mozilla/javascript/UintMap.java | 468 ---- src/org/mozilla/javascript/Undefined.java | 138 -- src/org/mozilla/javascript/VariableTable.java | 158 -- src/org/mozilla/javascript/WrapHandler.java | 68 - src/org/mozilla/javascript/WrappedException.java | 115 - src/org/mozilla/javascript/Wrapper.java | 55 - 80 files changed, 33057 deletions(-) delete mode 100644 src/org/mozilla/javascript/Arguments.java delete mode 100644 src/org/mozilla/javascript/BaseFunction.java delete mode 100644 src/org/mozilla/javascript/BinaryDigitReader.java delete mode 100644 src/org/mozilla/javascript/ClassDefinitionException.java delete mode 100644 src/org/mozilla/javascript/ClassNameHelper.java delete mode 100644 src/org/mozilla/javascript/ClassOutput.java delete mode 100644 src/org/mozilla/javascript/Context.java delete mode 100644 src/org/mozilla/javascript/ContextListener.java delete mode 100644 src/org/mozilla/javascript/DToA.java delete mode 100644 src/org/mozilla/javascript/DebuggableEngineImpl.java delete mode 100644 src/org/mozilla/javascript/DefaultErrorReporter.java delete mode 100644 src/org/mozilla/javascript/Delegator.java delete mode 100644 src/org/mozilla/javascript/EcmaError.java delete mode 100644 src/org/mozilla/javascript/ErrorReporter.java delete mode 100644 src/org/mozilla/javascript/EvaluatorException.java delete mode 100644 src/org/mozilla/javascript/FlattenedObject.java delete mode 100644 src/org/mozilla/javascript/Function.java delete mode 100644 src/org/mozilla/javascript/FunctionNode.java delete mode 100644 src/org/mozilla/javascript/FunctionObject.java delete mode 100644 src/org/mozilla/javascript/IRFactory.java delete mode 100644 src/org/mozilla/javascript/IdFunction.java delete mode 100644 src/org/mozilla/javascript/IdFunctionMaster.java delete mode 100644 src/org/mozilla/javascript/IdScriptable.java delete mode 100644 src/org/mozilla/javascript/ImporterTopLevel.java delete mode 100644 src/org/mozilla/javascript/InterpretedFunction.java delete mode 100644 src/org/mozilla/javascript/InterpretedScript.java delete mode 100644 src/org/mozilla/javascript/Interpreter.java delete mode 100644 src/org/mozilla/javascript/InterpreterData.java delete mode 100644 src/org/mozilla/javascript/InterpreterFrame.java delete mode 100644 src/org/mozilla/javascript/Invoker.java delete mode 100644 src/org/mozilla/javascript/JavaMembers.java delete mode 100644 src/org/mozilla/javascript/JavaScriptException.java delete mode 100644 src/org/mozilla/javascript/Label.java delete mode 100644 src/org/mozilla/javascript/LabelTable.java delete mode 100644 src/org/mozilla/javascript/LazilyLoadedCtor.java delete mode 100644 src/org/mozilla/javascript/LineBuffer.java delete mode 100644 src/org/mozilla/javascript/ListenerArray.java delete mode 100644 src/org/mozilla/javascript/LocalVariable.java delete mode 100644 src/org/mozilla/javascript/NativeArray.java delete mode 100644 src/org/mozilla/javascript/NativeBoolean.java delete mode 100644 src/org/mozilla/javascript/NativeCall.java delete mode 100644 src/org/mozilla/javascript/NativeDate.java delete mode 100644 src/org/mozilla/javascript/NativeError.java delete mode 100644 src/org/mozilla/javascript/NativeFunction.java delete mode 100644 src/org/mozilla/javascript/NativeGlobal.java delete mode 100644 src/org/mozilla/javascript/NativeJavaArray.java delete mode 100644 src/org/mozilla/javascript/NativeJavaClass.java delete mode 100644 src/org/mozilla/javascript/NativeJavaConstructor.java delete mode 100644 src/org/mozilla/javascript/NativeJavaMethod.java delete mode 100644 src/org/mozilla/javascript/NativeJavaObject.java delete mode 100644 src/org/mozilla/javascript/NativeJavaPackage.java delete mode 100644 src/org/mozilla/javascript/NativeMath.java delete mode 100644 src/org/mozilla/javascript/NativeNumber.java delete mode 100644 src/org/mozilla/javascript/NativeObject.java delete mode 100644 src/org/mozilla/javascript/NativeScript.java delete mode 100644 src/org/mozilla/javascript/NativeString.java delete mode 100644 src/org/mozilla/javascript/NativeWith.java delete mode 100644 src/org/mozilla/javascript/Node.java delete mode 100644 src/org/mozilla/javascript/NodeTransformer.java delete mode 100644 src/org/mozilla/javascript/NotAFunctionException.java delete mode 100644 src/org/mozilla/javascript/Parser.java delete mode 100644 src/org/mozilla/javascript/PreorderNodeIterator.java delete mode 100644 src/org/mozilla/javascript/PropertyException.java delete mode 100644 src/org/mozilla/javascript/RegExpProxy.java delete mode 100644 src/org/mozilla/javascript/Script.java delete mode 100644 src/org/mozilla/javascript/ScriptRuntime.java delete mode 100644 src/org/mozilla/javascript/Scriptable.java delete mode 100644 src/org/mozilla/javascript/ScriptableObject.java delete mode 100644 src/org/mozilla/javascript/SecuritySupport.java delete mode 100644 src/org/mozilla/javascript/ShallowNodeIterator.java delete mode 100644 src/org/mozilla/javascript/SourceTextItem.java delete mode 100644 src/org/mozilla/javascript/SourceTextManager.java delete mode 100644 src/org/mozilla/javascript/Synchronizer.java delete mode 100644 src/org/mozilla/javascript/TokenStream.java delete mode 100644 src/org/mozilla/javascript/UintMap.java delete mode 100644 src/org/mozilla/javascript/Undefined.java delete mode 100644 src/org/mozilla/javascript/VariableTable.java delete mode 100644 src/org/mozilla/javascript/WrapHandler.java delete mode 100644 src/org/mozilla/javascript/WrappedException.java delete mode 100644 src/org/mozilla/javascript/Wrapper.java diff --git a/src/org/mozilla/javascript/Arguments.java b/src/org/mozilla/javascript/Arguments.java deleted file mode 100644 index 119b32f..0000000 --- a/src/org/mozilla/javascript/Arguments.java +++ /dev/null @@ -1,150 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -/** - * This class implements the "arguments" object. - * - * See ECMA 10.1.8 - * - * @see org.mozilla.javascript.NativeCall - * @author Norris Boyd - */ -class Arguments extends ScriptableObject { - - public Arguments(NativeCall activation) { - this.activation = activation; - - Scriptable parent = activation.getParentScope(); - setParentScope(parent); - setPrototype(ScriptableObject.getObjectPrototype(parent)); - - args = activation.getOriginalArguments(); - int length = args.length; - Object callee = activation.funObj; - - defineProperty("length", new Integer(length), - ScriptableObject.DONTENUM); - defineProperty("callee", callee, ScriptableObject.DONTENUM); - - hasCaller = (activation.funObj.version <= Context.VERSION_1_3 && - activation.funObj.version != Context.VERSION_DEFAULT); - } - - public String getClassName() { - return "Arguments"; - } - - public boolean has(String name, Scriptable start) { - return (hasCaller && name.equals("caller")) || super.has(name, start); - } - - public boolean has(int index, Scriptable start) { - Object[] args = activation.getOriginalArguments(); - return (0 <= index && index < args.length) || super.has(index, start); - } - - public Object get(String name, Scriptable start) { - if (hasCaller && name.equals("caller")) { - NativeCall caller = activation.caller; - if (caller == null || caller.originalArgs == null) return null; - return caller.get("arguments", caller); - - } else if (name.equals("cascade")) { - return org.xwt.Trap.cascadeFunction; - - } else if (name.equals("trapee")) { - return org.xwt.Trap.currentTrapee(); - - } else if (name.equals("trapname")) { - return org.xwt.Trap.currentTrapname(); - - } - - return super.get(name, start); - } - - public Object get(int index, Scriptable start) { - if (0 <= index && index < args.length) { - NativeFunction f = activation.funObj; - if (index < f.argCount) - return activation.get(f.argNames[index], activation); - return args[index]; - } - return super.get(index, start); - } - - public void put(String name, Scriptable start, Object value) { - if (name.equals("caller")) { - // Set "hasCaller" to false so that we won't look up a - // computed value. - hasCaller = false; - } - super.put(name, start, value); - } - - public void put(int index, Scriptable start, Object value) { - if (0 <= index && index < args.length) { - NativeFunction f = activation.funObj; - if (index < f.argCount) - activation.put(f.argNames[index], activation, value); - else - args[index] = value; - return; - } - super.put(index, start, value); - } - - public void delete(String name) { - if (name.equals("caller")) - hasCaller = false; - super.delete(name); - } - - public void delete(int index) { - if (0 <= index && index < args.length) { - NativeFunction f = activation.funObj; - if (index < f.argCount) - activation.delete(f.argNames[index]); - else - args[index] = Undefined.instance; - } - } - - private NativeCall activation; - private Object[] args; - private boolean hasCaller; -} diff --git a/src/org/mozilla/javascript/BaseFunction.java b/src/org/mozilla/javascript/BaseFunction.java deleted file mode 100644 index 79c4f36..0000000 --- a/src/org/mozilla/javascript/BaseFunction.java +++ /dev/null @@ -1,521 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * Igor Bukanov - * Roger Lawrence - * Mike McCabe - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -/** - * The base class for Function objects - * See ECMA 15.3. - * @author Norris Boyd - */ -public class BaseFunction extends IdScriptable implements Function { - - static void init(Context cx, Scriptable scope, boolean sealed) { - BaseFunction obj = new BaseFunction(); - obj.prototypeFlag = true; - obj.functionName = ""; - obj.prototypePropertyAttrs = DONTENUM | READONLY | PERMANENT; - obj.addAsPrototype(MAX_PROTOTYPE_ID, cx, scope, sealed); - } - - protected void fillConstructorProperties - (Context cx, IdFunction ctor, boolean sealed) - { - // Fix up bootstrapping problem: getPrototype of the IdFunction - // can not return Function.prototype because Function object is not - // yet defined. - ctor.setPrototype(this); - } - - public String getClassName() { - return "Function"; - } - - /** - * Implements the instanceof operator for JavaScript Function objects. - *

- * - * foo = new Foo();
- * foo instanceof Foo; // true
- *
- * - * @param instance The value that appeared on the LHS of the instanceof - * operator - * @return true if the "prototype" property of "this" appears in - * value's prototype chain - * - */ - public boolean hasInstance(Scriptable instance) { - Object protoProp = ScriptableObject.getProperty(this, "prototype"); - if (protoProp instanceof Scriptable && protoProp != Undefined.instance) - { - return ScriptRuntime.jsDelegatesTo(instance, (Scriptable)protoProp); - } - throw NativeGlobal.typeError1 - ("msg.instanceof.bad.prototype", functionName, instance); - } - - protected int getIdDefaultAttributes(int id) { - switch (id) { - case Id_length: - case Id_arity: - case Id_name: - return DONTENUM | READONLY | PERMANENT; - case Id_prototype: - return prototypePropertyAttrs; - case Id_arguments: - return EMPTY; - } - return super.getIdDefaultAttributes(id); - } - - protected boolean hasIdValue(int id) { - if (id == Id_prototype) { - return prototypeProperty != NOT_FOUND; - } - else if (id == Id_arguments) { - // Should after delete Function.arguments its activation still - // be available during Function call? - // This code assumes it should not: after default set/deleteIdValue - // hasIdValue/getIdValue would not be called again - // To handle the opposite case, set/deleteIdValue should be - // overwritten as well - return null != getActivation(Context.getContext()); - } - return super.hasIdValue(id); - } - - protected Object getIdValue(int id) { - switch (id) { - case Id_length: return wrap_int(getLength()); - case Id_arity: return wrap_int(getArity()); - case Id_name: return getFunctionName(); - case Id_prototype: return getPrototypeProperty(); - case Id_arguments: return getArguments(); - } - return super.getIdValue(id); - } - - protected void setIdValue(int id, Object value) { - if (id == Id_prototype) { - prototypeProperty = (value != null) ? value : NULL_TAG; - return; - } - super.setIdValue(id, value); - } - - protected void deleteIdValue(int id) { - if (id == Id_prototype) { - prototypeProperty = NOT_FOUND; - return; - } - super.deleteIdValue(id); - } - - public int methodArity(int methodId) { - if (prototypeFlag) { - switch (methodId) { - case Id_constructor: - case Id_toString: - case Id_apply: - case Id_call: - return 1; - } - } - return super.methodArity(methodId); - } - - public Object execMethod(int methodId, IdFunction f, Context cx, - Scriptable scope, Scriptable thisObj, - Object[] args) - throws JavaScriptException - { - if (prototypeFlag) { - switch (methodId) { - case Id_constructor: - return jsConstructor(cx, scope, args); - - case Id_toString: - return jsFunction_toString(cx, thisObj, args); - - case Id_apply: - return jsFunction_apply(cx, scope, thisObj, args); - - case Id_call: - return jsFunction_call(cx, scope, thisObj, args); - } - } - return super.execMethod(methodId, f, cx, scope, thisObj, args); - } - - /** - * Make value as DontEnum, DontDelete, ReadOnly - * prototype property of this Function object - */ - public void setImmunePrototypeProperty(Object value) { - prototypeProperty = (value != null) ? value : NULL_TAG; - prototypePropertyAttrs = DONTENUM | READONLY | PERMANENT; - } - - protected Scriptable getClassPrototype() { - Object protoVal = getPrototypeProperty(); - if (protoVal == null - || !(protoVal instanceof Scriptable) - || (protoVal == Undefined.instance)) - protoVal = getClassPrototype(this, "Object"); - return (Scriptable) protoVal; - } - - /** - * Should be overridden. - */ - public Object call(Context cx, Scriptable scope, Scriptable thisObj, - Object[] args) - throws JavaScriptException - { - return Undefined.instance; - } - - public Scriptable construct(Context cx, Scriptable scope, Object[] args) - throws JavaScriptException - { - Scriptable newInstance = new NativeObject(); - - newInstance.setPrototype(getClassPrototype()); - newInstance.setParentScope(getParentScope()); - - Object val = call(cx, scope, newInstance, args); - if (val instanceof Scriptable && val != Undefined.instance) { - return (Scriptable) val; - } - return newInstance; - } - - /** - * Decompile the source information associated with this js - * function/script back into a string. - * - * @param cx Current context - * - * @param indent How much to indent the decompiled result - * - * @param justbody Whether the decompilation should omit the - * function header and trailing brace. - */ - - public String decompile(Context cx, int indent, boolean justbody) { - StringBuffer sb = new StringBuffer(); - if (!justbody) { - sb.append("function "); - sb.append(getFunctionName()); - sb.append("() {\n\t"); - } - sb.append("[native code, arity="); - sb.append(getArity()); - sb.append("]\n"); - if (!justbody) { - sb.append("}\n"); - } - return sb.toString(); - } - - public int getArity() { return 0; } - - public int getLength() { return 0; } - - public String getFunctionName() { - if (functionName == null) - return ""; - if (functionName.equals("anonymous")) { - Context cx = Context.getCurrentContext(); - if (cx != null && cx.getLanguageVersion() == Context.VERSION_1_2) - return ""; - } - return functionName; - } - - private Object getPrototypeProperty() { - Object result = prototypeProperty; - if (result == null) { - synchronized (this) { - result = prototypeProperty; - if (result == null) { - setupDefaultPrototype(); - result = prototypeProperty; - } - } - } - else if (result == NULL_TAG) { result = null; } - return result; - } - - private void setupDefaultPrototype() { - NativeObject obj = new NativeObject(); - final int attr = ScriptableObject.DONTENUM | - ScriptableObject.READONLY | - ScriptableObject.PERMANENT; - obj.defineProperty("constructor", this, attr); - // put the prototype property into the object now, then in the - // wacky case of a user defining a function Object(), we don't - // get an infinite loop trying to find the prototype. - prototypeProperty = obj; - Scriptable proto = getObjectPrototype(this); - if (proto != obj) { - // not the one we just made, it must remain grounded - obj.setPrototype(proto); - } - } - - private Object getArguments() { - // .arguments is deprecated, so we use a slow - // way of getting it that doesn't add to the invocation cost. - // TODO: add warning, error based on version - NativeCall activation = getActivation(Context.getContext()); - return activation == null - ? null - : activation.get("arguments", activation); - } - - NativeCall getActivation(Context cx) { - NativeCall activation = cx.currentActivation; - while (activation != null) { - if (activation.getFunctionObject() == this) - return activation; - activation = activation.caller; - } - return null; - } - - private static Object jsConstructor(Context cx, Scriptable scope, - Object[] args) - { - int arglen = args.length; - StringBuffer funArgs = new StringBuffer(); - - /* Collect the arguments into a string. */ - - int i; - for (i = 0; i < arglen - 1; i++) { - if (i > 0) - funArgs.append(','); - funArgs.append(ScriptRuntime.toString(args[i])); - } - String funBody = arglen == 0 ? "" : ScriptRuntime.toString(args[i]); - - String source = "function (" + funArgs.toString() + ") {" + - funBody + "}"; - int[] linep = { 0 }; - String filename = Context.getSourcePositionFromStack(linep); - if (filename == null) { - filename = ""; - linep[0] = 1; - } - Object securityDomain = cx.getSecurityDomainForStackDepth(4); - Scriptable global = ScriptableObject.getTopLevelScope(scope); - - // Compile the function with opt level of -1 to force interpreter - // mode. - int oldOptLevel = cx.getOptimizationLevel(); - cx.setOptimizationLevel(-1); - NativeFunction fn; - try { - fn = (NativeFunction) cx.compileFunction(global, source, - filename, linep[0], - securityDomain); - } - finally { cx.setOptimizationLevel(oldOptLevel); } - - fn.functionName = "anonymous"; - fn.setPrototype(getFunctionPrototype(global)); - fn.setParentScope(global); - - return fn; - } - - private static Object jsFunction_toString(Context cx, Scriptable thisObj, - Object[] args) - { - int indent = ScriptRuntime.toInt32(args, 0); - Object val = thisObj.getDefaultValue(ScriptRuntime.FunctionClass); - if (val instanceof BaseFunction) { - return ((BaseFunction)val).decompile(cx, indent, false); - } - throw NativeGlobal.typeError1("msg.incompat.call", "toString", thisObj); - } - - /** - * Function.prototype.apply - * - * A proposed ECMA extension for round 2. - */ - private static Object jsFunction_apply(Context cx, Scriptable scope, - Scriptable thisObj, Object[] args) - throws JavaScriptException - { - if (args.length != 2) - return jsFunction_call(cx, scope, thisObj, args); - Object val = thisObj.getDefaultValue(ScriptRuntime.FunctionClass); - Scriptable newThis = args[0] == null - ? ScriptableObject.getTopLevelScope(thisObj) - : ScriptRuntime.toObject(scope, args[0]); - Object[] newArgs; - if (args.length > 1) { - if ((args[1] instanceof NativeArray) - || (args[1] instanceof Arguments)) - newArgs = cx.getElements((Scriptable) args[1]); - else - throw NativeGlobal.typeError0("msg.arg.isnt.array", thisObj); - } - else - newArgs = ScriptRuntime.emptyArgs; - return ScriptRuntime.call(cx, val, newThis, newArgs, newThis); - } - - /** - * Function.prototype.call - * - * A proposed ECMA extension for round 2. - */ - private static Object jsFunction_call(Context cx, Scriptable scope, - Scriptable thisObj, Object[] args) - throws JavaScriptException - { - Object val = thisObj.getDefaultValue(ScriptRuntime.FunctionClass); - if (args.length == 0) { - Scriptable s = ScriptRuntime.toObject(scope, val); - Scriptable topScope = s.getParentScope(); - return ScriptRuntime.call(cx, val, - topScope, ScriptRuntime.emptyArgs, - topScope); - } else { - Scriptable newThis = args[0] == null - ? ScriptableObject.getTopLevelScope(thisObj) - : ScriptRuntime.toObject(scope, args[0]); - - Object[] newArgs = new Object[args.length - 1]; - System.arraycopy(args, 1, newArgs, 0, newArgs.length); - return ScriptRuntime.call(cx, val, newThis, newArgs, newThis); - } - } - - protected int maxInstanceId() { return MAX_INSTANCE_ID; } - - protected String getIdName(int id) { - switch (id) { - case Id_length: return "length"; - case Id_arity: return "arity"; - case Id_name: return "name"; - case Id_prototype: return "prototype"; - case Id_arguments: return "arguments"; - } - - if (prototypeFlag) { - switch (id) { - case Id_constructor: return "constructor"; - case Id_toString: return "toString"; - case Id_apply: return "apply"; - case Id_call: return "call"; - } - } - return null; - } - -// #string_id_map# - - private static final int - Id_length = 1, - Id_arity = 2, - Id_name = 3, - Id_prototype = 4, - Id_arguments = 5, - - MAX_INSTANCE_ID = 5; - - protected int mapNameToId(String s) { - int id; -// #generated# Last update: 2001-05-20 00:12:12 GMT+02:00 - L0: { id = 0; String X = null; int c; - L: switch (s.length()) { - case 4: X="name";id=Id_name; break L; - case 5: X="arity";id=Id_arity; break L; - case 6: X="length";id=Id_length; break L; - case 9: c=s.charAt(0); - if (c=='a') { X="arguments";id=Id_arguments; } - else if (c=='p') { X="prototype";id=Id_prototype; } - break L; - } - if (X!=null && X!=s && !X.equals(s)) id = 0; - } -// #/generated# -// #/string_id_map# - - if (id != 0 || !prototypeFlag) { return id; } - -// #string_id_map# -// #generated# Last update: 2001-05-20 00:12:12 GMT+02:00 - L0: { id = 0; String X = null; - L: switch (s.length()) { - case 4: X="call";id=Id_call; break L; - case 5: X="apply";id=Id_apply; break L; - case 8: X="toString";id=Id_toString; break L; - case 11: X="constructor";id=Id_constructor; break L; - } - if (X!=null && X!=s && !X.equals(s)) id = 0; - } -// #/generated# - return id; - } - - private static final int - Id_constructor = MAX_INSTANCE_ID + 1, - Id_toString = MAX_INSTANCE_ID + 2, - Id_apply = MAX_INSTANCE_ID + 3, - Id_call = MAX_INSTANCE_ID + 4, - - MAX_PROTOTYPE_ID = MAX_INSTANCE_ID + 4; - -// #/string_id_map# - - protected String functionName; - - private Object prototypeProperty; - private int prototypePropertyAttrs = DONTENUM; - - private boolean prototypeFlag; -} - diff --git a/src/org/mozilla/javascript/BinaryDigitReader.java b/src/org/mozilla/javascript/BinaryDigitReader.java deleted file mode 100644 index a6b4771..0000000 --- a/src/org/mozilla/javascript/BinaryDigitReader.java +++ /dev/null @@ -1,75 +0,0 @@ - -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Waldemar Horwat - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ -package org.mozilla.javascript; - -final class BinaryDigitReader { - int lgBase; // Logarithm of base of number - int digit; // Current digit value in radix given by base - int digitPos; // Bit position of last bit extracted from digit - String digits; // String containing the digits - int start; // Index of the first remaining digit - int end; // Index past the last remaining digit - - BinaryDigitReader(int base, String digits, int start, int end) { - lgBase = 0; - while (base != 1) { - lgBase++; - base >>= 1; - } - digitPos = 0; - this.digits = digits; - this.start = start; - this.end = end; - } - - /* Return the next binary digit from the number or -1 if done */ - int getNextBinaryDigit() - { - if (digitPos == 0) { - if (start == end) - return -1; - - char c = digits.charAt(start++); - if ('0' <= c && c <= '9') - digit = c - '0'; - else if ('a' <= c && c <= 'z') - digit = c - 'a' + 10; - else digit = c - 'A' + 10; - digitPos = lgBase; - } - return digit >> --digitPos & 1; - } -} diff --git a/src/org/mozilla/javascript/ClassDefinitionException.java b/src/org/mozilla/javascript/ClassDefinitionException.java deleted file mode 100644 index 3b5a8e7..0000000 --- a/src/org/mozilla/javascript/ClassDefinitionException.java +++ /dev/null @@ -1,48 +0,0 @@ - -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ -// API class - -package org.mozilla.javascript; - -/** - * Thrown if errors are detected while attempting to define a host object - * from a Java class. - */ -public class ClassDefinitionException extends Exception { - - public ClassDefinitionException(String detail) { - super(detail); - } -} diff --git a/src/org/mozilla/javascript/ClassNameHelper.java b/src/org/mozilla/javascript/ClassNameHelper.java deleted file mode 100644 index 70cb600..0000000 --- a/src/org/mozilla/javascript/ClassNameHelper.java +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * Roger Lawrence - * Andi Vajda - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -public interface ClassNameHelper { - - public String getTargetClassFileName(); - - public void setTargetClassFileName(String classFileName); - - public String getTargetPackage(); - - public void setTargetPackage(String targetPackage); - - public String getTargetClassFileName(String className); - - public String getGeneratingDirectory(); - - public void setTargetExtends(Class extendsClass); - - public void setTargetImplements(Class[] implementsClasses); - - public ClassOutput getClassOutput(); - - public void setClassOutput(ClassOutput classOutput); - - public void reset(); -} diff --git a/src/org/mozilla/javascript/ClassOutput.java b/src/org/mozilla/javascript/ClassOutput.java deleted file mode 100644 index 997b89e..0000000 --- a/src/org/mozilla/javascript/ClassOutput.java +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Andi Vajda - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ -package org.mozilla.javascript; - -// API class - -import java.io.*; - -/** - * This interface is implemented by classes interested in the bytecode - * generated by the rhino compiler for script objects. - * - * @see Context - * @author Andi Vajda - */ -public interface ClassOutput { - /** - * @param className the name of the class for which bytecode is ready. - * @param isTopLevel if true, represents the top-level script being compiled - * @return a stream into which to write bytecode. - * @since 1.5 Release 2 - */ - public OutputStream getOutputStream(String className, boolean isTopLevel) - throws IOException; -} diff --git a/src/org/mozilla/javascript/Context.java b/src/org/mozilla/javascript/Context.java deleted file mode 100644 index 514bfdf..0000000 --- a/src/org/mozilla/javascript/Context.java +++ /dev/null @@ -1,2201 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Patrick Beard - * Norris Boyd - * Igor Bukanov - * Brendan Eich - * Roger Lawrence - * Mike McCabe - * Ian D. Stewart - * Andi Vajda - * Andrew Wason - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -// API class - -package org.mozilla.javascript; - -import java.beans.*; -import java.io.*; -import java.util.Vector; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Locale; -import java.util.ResourceBundle; -import java.util.ListResourceBundle; -import java.text.MessageFormat; -import java.lang.reflect.*; -import org.mozilla.javascript.debug.*; - -/** - * This class represents the runtime context of an executing script. - * - * Before executing a script, an instance of Context must be created - * and associated with the thread that will be executing the script. - * The Context will be used to store information about the executing - * of the script such as the call stack. Contexts are associated with - * the current thread using the enter() method.

- * - * The behavior of the execution engine may be altered through methods - * such as setErrorReporter.

- * - * Different forms of script execution are supported. Scripts may be - * evaluated from the source directly, or first compiled and then later - * executed. Interactive execution is also supported.

- * - * Some aspects of script execution, such as type conversions and - * object creation, may be accessed directly through methods of - * Context. - * - * @see Scriptable - * @author Norris Boyd - * @author Brendan Eich - */ - -public class Context { - public static final String languageVersionProperty = "language version"; - public static final String errorReporterProperty = "error reporter"; - - /** - * Create a new Context. - * - * Note that the Context must be associated with a thread before - * it can be used to execute a script. - * - * @see org.mozilla.javascript.Context#enter - */ - public Context() { - init(); - } - - /** - * Create a new context with the associated security support. - * - * @param securitySupport an encapsulation of the functionality - * needed to support security for scripts. - * @see org.mozilla.javascript.SecuritySupport - */ - public Context(SecuritySupport securitySupport) { - this.securitySupport = securitySupport; - init(); - } - - private void init() { - setLanguageVersion(VERSION_DEFAULT); - optimizationLevel = codegenClass != null ? 0 : -1; - Object[] array = contextListeners; - if (array != null) { - for (int i = array.length; i-- != 0;) { - ((ContextListener)array[i]).contextCreated(this); - } - } - } - - /** - * Get a context associated with the current thread, creating - * one if need be. - * - * The Context stores the execution state of the JavaScript - * engine, so it is required that the context be entered - * before execution may begin. Once a thread has entered - * a Context, then getCurrentContext() may be called to find - * the context that is associated with the current thread. - *

- * Calling enter() will - * return either the Context currently associated with the - * thread, or will create a new context and associate it - * with the current thread. Each call to enter() - * must have a matching call to exit(). For example, - *

-     *      Context cx = Context.enter();
-     *      ...
-     *      cx.evaluateString(...);
-     *      Context.exit();
-     * 
- * @return a Context associated with the current thread - * @see org.mozilla.javascript.Context#getCurrentContext - * @see org.mozilla.javascript.Context#exit - */ - public static Context enter() { - return enter(null); - } - - /** - * Get a Context associated with the current thread, using - * the given Context if need be. - *

- * The same as enter() except that cx - * is associated with the current thread and returned if - * the current thread has no associated context and cx - * is not associated with any other thread. - * @param cx a Context to associate with the thread if possible - * @return a Context associated with the current thread - */ - public static Context enter(Context cx) { - // There's some duplication of code in this method to avoid - // unnecessary synchronizations. - Thread t = Thread.currentThread(); - Context current = (Context) threadContexts.get(t); - if (current != null) { - synchronized (current) { - current.enterCount++; - } - } - else if (cx != null) { - synchronized (cx) { - if (cx.currentThread == null) { - cx.currentThread = t; - threadContexts.put(t, cx); - cx.enterCount++; - } - } - current = cx; - } - else { - current = new Context(); - current.currentThread = t; - threadContexts.put(t, current); - current.enterCount = 1; - } - Object[] array = contextListeners; - if (array != null) { - for (int i = array.length; i-- != 0;) { - ((ContextListener)array[i]).contextEntered(current); - } - } - return current; - } - - /** - * Exit a block of code requiring a Context. - * - * Calling exit() will remove the association between - * the current thread and a Context if the prior call to - * enter() on this thread newly associated a Context - * with this thread. - * Once the current thread no longer has an associated Context, - * it cannot be used to execute JavaScript until it is again associated - * with a Context. - * - * @see org.mozilla.javascript.Context#enter - */ - public static void exit() { - Context cx = getCurrentContext(); - boolean released = false; - if (cx != null) { - synchronized (cx) { - if (--cx.enterCount == 0) { - threadContexts.remove(cx.currentThread); - cx.currentThread = null; - released = true; - } - } - Object[] array = contextListeners; - if (array != null) { - for (int i = array.length; i-- != 0;) { - ContextListener l = (ContextListener)array[i]; - l.contextExited(cx); - if (released) { l.contextReleased(cx); } - } - } - } - } - - /** - * Get the current Context. - * - * The current Context is per-thread; this method looks up - * the Context associated with the current thread.

- * - * @return the Context associated with the current thread, or - * null if no context is associated with the current - * thread. - * @see org.mozilla.javascript.Context#enter - * @see org.mozilla.javascript.Context#exit - */ - public static Context getCurrentContext() { - Thread t = Thread.currentThread(); - return (Context) threadContexts.get(t); - } - - public static Context getContextForThread(Thread t) { - Context ret = (Context) threadContexts.get(t); - return ret == null ? Context.enter() : ret; - } - - /** - * Language versions - * - * All integral values are reserved for future version numbers. - */ - - /** - * The unknown version. - */ - public static final int VERSION_UNKNOWN = -1; - - /** - * The default version. - */ - public static final int VERSION_DEFAULT = 0; - - /** - * JavaScript 1.0 - */ - public static final int VERSION_1_0 = 100; - - /** - * JavaScript 1.1 - */ - public static final int VERSION_1_1 = 110; - - /** - * JavaScript 1.2 - */ - public static final int VERSION_1_2 = 120; - - /** - * JavaScript 1.3 - */ - public static final int VERSION_1_3 = 130; - - /** - * JavaScript 1.4 - */ - public static final int VERSION_1_4 = 140; - - /** - * JavaScript 1.5 - */ - public static final int VERSION_1_5 = 150; - - /** - * Get the current language version. - *

- * The language version number affects JavaScript semantics as detailed - * in the overview documentation. - * - * @return an integer that is one of VERSION_1_0, VERSION_1_1, etc. - */ - public int getLanguageVersion() { - return version; - } - - /** - * Set the language version. - * - *

- * Setting the language version will affect functions and scripts compiled - * subsequently. See the overview documentation for version-specific - * behavior. - * - * @param version the version as specified by VERSION_1_0, VERSION_1_1, etc. - */ - public void setLanguageVersion(int version) { - Object[] array = listeners; - if (array != null && version != this.version) { - firePropertyChangeImpl(array, languageVersionProperty, - new Integer(this.version), - new Integer(version)); - } - this.version = version; - } - - /** - * Get the implementation version. - * - *

- * The implementation version is of the form - *

-     *    "name langVer release relNum date"
-     * 
- * where name is the name of the product, langVer is - * the language version, relNum is the release number, and - * date is the release date for that specific - * release in the form "yyyy mm dd". - * - * @return a string that encodes the product, language version, release - * number, and date. - */ - public String getImplementationVersion() { - return "Rhino 1.5 release 2 2001 07 27"; - } - - /** - * Get the current error reporter. - * - * @see org.mozilla.javascript.ErrorReporter - */ - public ErrorReporter getErrorReporter() { - if (errorReporter == null) { - errorReporter = new DefaultErrorReporter(); - } - return errorReporter; - } - - /** - * Change the current error reporter. - * - * @return the previous error reporter - * @see org.mozilla.javascript.ErrorReporter - */ - public ErrorReporter setErrorReporter(ErrorReporter reporter) { - ErrorReporter result = errorReporter; - Object[] array = listeners; - if (array != null && errorReporter != reporter) { - firePropertyChangeImpl(array, errorReporterProperty, - errorReporter, reporter); - } - errorReporter = reporter; - return result; - } - - /** - * Get the current locale. Returns the default locale if none has - * been set. - * - * @see java.util.Locale - */ - - public Locale getLocale() { - if (locale == null) - locale = Locale.getDefault(); - return locale; - } - - /** - * Set the current locale. - * - * @see java.util.Locale - */ - public Locale setLocale(Locale loc) { - Locale result = locale; - locale = loc; - return result; - } - - /** - * Register an object to receive notifications when a bound property - * has changed - * @see java.beans.PropertyChangeEvent - * @see #removePropertyChangeListener(java.beans.PropertyChangeListener) - * @param listener the listener - */ - public void addPropertyChangeListener(PropertyChangeListener listener) { - synchronized (this) { - listeners = ListenerArray.add(listeners, listener); - } - } - - /** - * Remove an object from the list of objects registered to receive - * notification of changes to a bounded property - * @see java.beans.PropertyChangeEvent - * @see #addPropertyChangeListener(java.beans.PropertyChangeListener) - * @param listener the listener - */ - public void removePropertyChangeListener(PropertyChangeListener listener) { - synchronized (this) { - listeners = ListenerArray.remove(listeners, listener); - } - } - - /** - * Notify any registered listeners that a bounded property has changed - * @see #addPropertyChangeListener(java.beans.PropertyChangeListener) - * @see #removePropertyChangeListener(java.beans.PropertyChangeListener) - * @see java.beans.PropertyChangeListener - * @see java.beans.PropertyChangeEvent - * @param property the bound property - * @param oldValue the old value - * @param newVale the new value - */ - void firePropertyChange(String property, Object oldValue, - Object newValue) - { - Object[] array = listeners; - if (array != null) { - firePropertyChangeImpl(array, property, oldValue, newValue); - } - } - - private void firePropertyChangeImpl(Object[] array, String property, - Object oldValue, Object newValue) - { - for (int i = array.length; i-- != 0;) { - Object obj = array[i]; - if (obj instanceof PropertyChangeListener) { - PropertyChangeListener l = (PropertyChangeListener)obj; - l.propertyChange(new PropertyChangeEvent( - this, property, oldValue, newValue)); - } - } - } - - /** - * Report a warning using the error reporter for the current thread. - * - * @param message the warning message to report - * @param sourceName a string describing the source, such as a filename - * @param lineno the starting line number - * @param lineSource the text of the line (may be null) - * @param lineOffset the offset into lineSource where problem was detected - * @see org.mozilla.javascript.ErrorReporter - */ - public static void reportWarning(String message, String sourceName, - int lineno, String lineSource, - int lineOffset) - { - Context cx = Context.getContext(); - cx.getErrorReporter().warning(message, sourceName, lineno, - lineSource, lineOffset); - } - - /** - * Report a warning using the error reporter for the current thread. - * - * @param message the warning message to report - * @see org.mozilla.javascript.ErrorReporter - */ - public static void reportWarning(String message) { - int[] linep = { 0 }; - String filename = getSourcePositionFromStack(linep); - Context.reportWarning(message, filename, linep[0], null, 0); - } - - /** - * Report an error using the error reporter for the current thread. - * - * @param message the error message to report - * @param sourceName a string describing the source, such as a filename - * @param lineno the starting line number - * @param lineSource the text of the line (may be null) - * @param lineOffset the offset into lineSource where problem was detected - * @see org.mozilla.javascript.ErrorReporter - */ - public static void reportError(String message, String sourceName, - int lineno, String lineSource, - int lineOffset) - { - Context cx = getCurrentContext(); - if (cx != null) { - cx.errorCount++; - cx.getErrorReporter().error(message, sourceName, lineno, - lineSource, lineOffset); - } else { - throw new EvaluatorException(message); - } - } - - /** - * Report an error using the error reporter for the current thread. - * - * @param message the error message to report - * @see org.mozilla.javascript.ErrorReporter - */ - public static void reportError(String message) { - int[] linep = { 0 }; - String filename = getSourcePositionFromStack(linep); - Context.reportError(message, filename, linep[0], null, 0); - } - - /** - * Report a runtime error using the error reporter for the current thread. - * - * @param message the error message to report - * @param sourceName a string describing the source, such as a filename - * @param lineno the starting line number - * @param lineSource the text of the line (may be null) - * @param lineOffset the offset into lineSource where problem was detected - * @return a runtime exception that will be thrown to terminate the - * execution of the script - * @see org.mozilla.javascript.ErrorReporter - */ - public static EvaluatorException reportRuntimeError(String message, - String sourceName, - int lineno, - String lineSource, - int lineOffset) - { - Context cx = getCurrentContext(); - if (cx != null) { - cx.errorCount++; - return cx.getErrorReporter(). - runtimeError(message, sourceName, lineno, - lineSource, lineOffset); - } else { - throw new EvaluatorException(message); - } - } - - static EvaluatorException reportRuntimeError0(String messageId) { - return reportRuntimeError(getMessage0(messageId)); - } - - static EvaluatorException reportRuntimeError1 - (String messageId, Object arg1) - { - return reportRuntimeError(getMessage1(messageId, arg1)); - } - - static EvaluatorException reportRuntimeError2 - (String messageId, Object arg1, Object arg2) - { - return reportRuntimeError(getMessage2(messageId, arg1, arg2)); - } - - static EvaluatorException reportRuntimeError3 - (String messageId, Object arg1, Object arg2, Object arg3) - { - return reportRuntimeError(getMessage3(messageId, arg1, arg2, arg3)); - } - - /** - * Report a runtime error using the error reporter for the current thread. - * - * @param message the error message to report - * @see org.mozilla.javascript.ErrorReporter - */ - public static EvaluatorException reportRuntimeError(String message) { - int[] linep = { 0 }; - String filename = getSourcePositionFromStack(linep); - return Context.reportRuntimeError(message, filename, linep[0], null, 0); - } - - /** - * Initialize the standard objects. - * - * Creates instances of the standard objects and their constructors - * (Object, String, Number, Date, etc.), setting up 'scope' to act - * as a global object as in ECMA 15.1.

- * - * This method must be called to initialize a scope before scripts - * can be evaluated in that scope. - * - * @param scope the scope to initialize, or null, in which case a new - * object will be created to serve as the scope - * @return the initialized scope - */ - public Scriptable initStandardObjects(ScriptableObject scope) { - return initStandardObjects(scope, false); - } - - /** - * Initialize the standard objects. - * - * Creates instances of the standard objects and their constructors - * (Object, String, Number, Date, etc.), setting up 'scope' to act - * as a global object as in ECMA 15.1.

- * - * This method must be called to initialize a scope before scripts - * can be evaluated in that scope.

- * - * This form of the method also allows for creating "sealed" standard - * objects. An object that is sealed cannot have properties added or - * removed. This is useful to create a "superglobal" that can be shared - * among several top-level objects. Note that sealing is not allowed in - * the current ECMA/ISO language specification, but is likely for - * the next version. - * - * @param scope the scope to initialize, or null, in which case a new - * object will be created to serve as the scope - * @param sealed whether or not to create sealed standard objects that - * cannot be modified. - * @return the initialized scope - * @since 1.4R3 - */ - public ScriptableObject initStandardObjects(ScriptableObject scope, - boolean sealed) - { - if (scope == null) - scope = new NativeObject(); - - BaseFunction.init(this, scope, sealed); - NativeObject.init(this, scope, sealed); - - Scriptable objectProto = ScriptableObject.getObjectPrototype(scope); - - // Function.prototype.__proto__ should be Object.prototype - Scriptable functionProto = ScriptableObject.getFunctionPrototype(scope); - functionProto.setPrototype(objectProto); - - // Set the prototype of the object passed in if need be - if (scope.getPrototype() == null) - scope.setPrototype(objectProto); - - // must precede NativeGlobal since it's needed therein - NativeError.init(this, scope, sealed); - NativeGlobal.init(this, scope, sealed); - - NativeArray.init(this, scope, sealed); - NativeString.init(this, scope, sealed); - NativeBoolean.init(this, scope, sealed); - NativeNumber.init(this, scope, sealed); - NativeDate.init(this, scope, sealed); - NativeMath.init(this, scope, sealed); - - NativeWith.init(this, scope, sealed); - NativeCall.init(this, scope, sealed); - NativeScript.init(this, scope, sealed); - - new LazilyLoadedCtor(scope, - "RegExp", - "org.mozilla.javascript.regexp.NativeRegExp", - sealed); - - // This creates the Packages and java package roots. - new LazilyLoadedCtor(scope, - "Packages", - "org.mozilla.javascript.NativeJavaPackage", - sealed); - new LazilyLoadedCtor(scope, - "java", - "org.mozilla.javascript.NativeJavaPackage", - sealed); - new LazilyLoadedCtor(scope, - "getClass", - "org.mozilla.javascript.NativeJavaPackage", - sealed); - - // Define the JavaAdapter class, allowing it to be overridden. - String adapterClass = "org.mozilla.javascript.JavaAdapter"; - String adapterProperty = "JavaAdapter"; - try { - adapterClass = System.getProperty(adapterClass, adapterClass); - adapterProperty = System.getProperty - ("org.mozilla.javascript.JavaAdapterClassName", - adapterProperty); - } - catch (SecurityException e) { - // We may not be allowed to get system properties. Just - // use the default adapter in that case. - } - - new LazilyLoadedCtor(scope, adapterProperty, adapterClass, sealed); - - return scope; - } - - /** - * Get the singleton object that represents the JavaScript Undefined value. - */ - public static Object getUndefinedValue() { - return Undefined.instance; - } - - /** - * Evaluate a JavaScript source string. - * - * The provided source name and line number are used for error messages - * and for producing debug information. - * - * @param scope the scope to execute in - * @param source the JavaScript source - * @param sourceName a string describing the source, such as a filename - * @param lineno the starting line number - * @param securityDomain an arbitrary object that specifies security - * information about the origin or owner of the script. For - * implementations that don't care about security, this value - * may be null. - * @return the result of evaluating the string - * @exception JavaScriptException if an uncaught JavaScript exception - * occurred while evaluating the source string - * @see org.mozilla.javascript.SecuritySupport - */ - public Object evaluateString(Scriptable scope, String source, - String sourceName, int lineno, - Object securityDomain) - throws JavaScriptException - { - try { - Reader in = new StringReader(source); - return evaluateReader(scope, in, sourceName, lineno, - securityDomain); - } - catch (IOException ioe) { - // Should never occur because we just made the reader from a String - throw new RuntimeException(); - } - } - - /** - * Evaluate a reader as JavaScript source. - * - * All characters of the reader are consumed. - * - * @param scope the scope to execute in - * @param in the Reader to get JavaScript source from - * @param sourceName a string describing the source, such as a filename - * @param lineno the starting line number - * @param securityDomain an arbitrary object that specifies security - * information about the origin or owner of the script. For - * implementations that don't care about security, this value - * may be null. - * @return the result of evaluating the source - * - * @exception IOException if an IOException was generated by the Reader - * @exception JavaScriptException if an uncaught JavaScript exception - * occurred while evaluating the Reader - */ - public Object evaluateReader(Scriptable scope, Reader in, - String sourceName, int lineno, - Object securityDomain) - throws IOException, JavaScriptException - { - Script script = compileReader(scope, in, sourceName, lineno, - securityDomain); - if (script != null) - return script.exec(this, scope); - else - return null; - } - - /** - * Check whether a string is ready to be compiled. - *

- * stringIsCompilableUnit is intended to support interactive compilation of - * javascript. If compiling the string would result in an error - * that might be fixed by appending more source, this method - * returns false. In every other case, it returns true. - *

- * Interactive shells may accumulate source lines, using this - * method after each new line is appended to check whether the - * statement being entered is complete. - * - * @param source the source buffer to check - * @return whether the source is ready for compilation - * @since 1.4 Release 2 - */ - synchronized public boolean stringIsCompilableUnit(String source) - { - Reader in = new StringReader(source); - // no source name or source text manager, because we're just - // going to throw away the result. - TokenStream ts = new TokenStream(in, null, null, 1); - - // Temporarily set error reporter to always be the exception-throwing - // DefaultErrorReporter. (This is why the method is synchronized...) - ErrorReporter currentReporter = - setErrorReporter(new DefaultErrorReporter()); - - boolean errorseen = false; - try { - IRFactory irf = new IRFactory(ts, null); - Parser p = new Parser(irf); - p.parse(ts); - } catch (IOException ioe) { - errorseen = true; - } catch (EvaluatorException ee) { - errorseen = true; - } finally { - // Restore the old error reporter. - setErrorReporter(currentReporter); - } - // Return false only if an error occurred as a result of reading past - // the end of the file, i.e. if the source could be fixed by - // appending more source. - if (errorseen && ts.eof()) - return false; - else - return true; - } - - /** - * Compiles the source in the given reader. - *

- * Returns a script that may later be executed. - * Will consume all the source in the reader. - * - * @param scope if nonnull, will be the scope in which the script object - * is created. The script object will be a valid JavaScript object - * as if it were created using the JavaScript1.3 Script constructor - * @param in the input reader - * @param sourceName a string describing the source, such as a filename - * @param lineno the starting line number for reporting errors - * @param securityDomain an arbitrary object that specifies security - * information about the origin or owner of the script. For - * implementations that don't care about security, this value - * may be null. - * @return a script that may later be executed - * @see org.mozilla.javascript.Script#exec - * @exception IOException if an IOException was generated by the Reader - */ - public Script compileReader(Scriptable scope, Reader in, String sourceName, - int lineno, Object securityDomain) - throws IOException - { - return (Script) compile(scope, in, sourceName, lineno, securityDomain, - false); - } - - - /** - * Compile a JavaScript function. - *

- * The function source must be a function definition as defined by - * ECMA (e.g., "function f(a) { return a; }"). - * - * @param scope the scope to compile relative to - * @param source the function definition source - * @param sourceName a string describing the source, such as a filename - * @param lineno the starting line number - * @param securityDomain an arbitrary object that specifies security - * information about the origin or owner of the script. For - * implementations that don't care about security, this value - * may be null. - * @return a Function that may later be called - * @see org.mozilla.javascript.Function - */ - public Function compileFunction(Scriptable scope, String source, - String sourceName, int lineno, - Object securityDomain) - { - Reader in = new StringReader(source); - try { - return (Function) compile(scope, in, sourceName, lineno, - securityDomain, true); - } - catch (IOException ioe) { - // Should never happen because we just made the reader - // from a String - throw new RuntimeException(); - } - } - - /** - * Decompile the script. - *

- * The canonical source of the script is returned. - * - * @param script the script to decompile - * @param scope the scope under which to decompile - * @param indent the number of spaces to indent the result - * @return a string representing the script source - */ - public String decompileScript(Script script, Scriptable scope, - int indent) - { - NativeScript ns = (NativeScript) script; - ns.initScript(scope); - return ns.decompile(this, indent, false); - } - - /** - * Decompile a JavaScript Function. - *

- * Decompiles a previously compiled JavaScript function object to - * canonical source. - *

- * Returns function body of '[native code]' if no decompilation - * information is available. - * - * @param fun the JavaScript function to decompile - * @param indent the number of spaces to indent the result - * @return a string representing the function source - */ - public String decompileFunction(Function fun, int indent) { - if (fun instanceof BaseFunction) - return ((BaseFunction)fun).decompile(this, indent, false); - else - return "function " + fun.getClassName() + - "() {\n\t[native code]\n}\n"; - } - - /** - * Decompile the body of a JavaScript Function. - *

- * Decompiles the body a previously compiled JavaScript Function - * object to canonical source, omitting the function header and - * trailing brace. - * - * Returns '[native code]' if no decompilation information is available. - * - * @param fun the JavaScript function to decompile - * @param indent the number of spaces to indent the result - * @return a string representing the function body source. - */ - public String decompileFunctionBody(Function fun, int indent) { - if (fun instanceof BaseFunction) - return ((BaseFunction)fun).decompile(this, indent, true); - else - // not sure what the right response here is. JSRef currently - // dumps core. - return "[native code]\n"; - } - - /** - * Create a new JavaScript object. - * - * Equivalent to evaluating "new Object()". - * @param scope the scope to search for the constructor and to evaluate - * against - * @return the new object - * @exception PropertyException if "Object" cannot be found in - * the scope - * @exception NotAFunctionException if the "Object" found in the scope - * is not a function - * @exception JavaScriptException if an uncaught JavaScript exception - * occurred while creating the object - */ - public Scriptable newObject(Scriptable scope) - throws PropertyException, - NotAFunctionException, - JavaScriptException - { - return newObject(scope, "Object", null); - } - - /** - * Create a new JavaScript object by executing the named constructor. - * - * The call newObject(scope, "Foo") is equivalent to - * evaluating "new Foo()". - * - * @param scope the scope to search for the constructor and to evaluate against - * @param constructorName the name of the constructor to call - * @return the new object - * @exception PropertyException if a property with the constructor - * name cannot be found in the scope - * @exception NotAFunctionException if the property found in the scope - * is not a function - * @exception JavaScriptException if an uncaught JavaScript exception - * occurred while creating the object - */ - public Scriptable newObject(Scriptable scope, String constructorName) - throws PropertyException, - NotAFunctionException, - JavaScriptException - { - return newObject(scope, constructorName, null); - } - - /** - * Creates a new JavaScript object by executing the named constructor. - * - * Searches scope for the named constructor, calls it with - * the given arguments, and returns the result.

- * - * The code - *

-     * Object[] args = { "a", "b" };
-     * newObject(scope, "Foo", args)
- * is equivalent to evaluating "new Foo('a', 'b')", assuming that the Foo - * constructor has been defined in scope. - * - * @param scope The scope to search for the constructor and to evaluate - * against - * @param constructorName the name of the constructor to call - * @param args the array of arguments for the constructor - * @return the new object - * @exception PropertyException if a property with the constructor - * name cannot be found in the scope - * @exception NotAFunctionException if the property found in the scope - * is not a function - * @exception JavaScriptException if an uncaught JavaScript exception - * occurs while creating the object - */ - public Scriptable newObject(Scriptable scope, String constructorName, - Object[] args) - throws PropertyException, - NotAFunctionException, - JavaScriptException - { - Object ctorVal = ScriptRuntime.getTopLevelProp(scope, constructorName); - if (ctorVal == Scriptable.NOT_FOUND) { - String message = getMessage1("msg.ctor.not.found", constructorName); - throw new PropertyException(message); - } - if (!(ctorVal instanceof Function)) { - String message = getMessage1("msg.not.ctor", constructorName); - throw new NotAFunctionException(message); - } - Function ctor = (Function) ctorVal; - return ctor.construct(this, ctor.getParentScope(), - (args == null) ? ScriptRuntime.emptyArgs : args); - } - - /** - * Create an array with a specified initial length. - *

- * @param scope the scope to create the object in - * @param length the initial length (JavaScript arrays may have - * additional properties added dynamically). - * @return the new array object - */ - public Scriptable newArray(Scriptable scope, int length) { - Scriptable result = new NativeArray(length); - newArrayHelper(scope, result); - return result; - } - - /** - * Create an array with a set of initial elements. - *

- * @param scope the scope to create the object in - * @param elements the initial elements. Each object in this array - * must be an acceptable JavaScript type. - * @return the new array object - */ - public Scriptable newArray(Scriptable scope, Object[] elements) { - Scriptable result = new NativeArray(elements); - newArrayHelper(scope, result); - return result; - } - - /** - * Get the elements of a JavaScript array. - *

- * If the object defines a length property, a Java array with that - * length is created and initialized with the values obtained by - * calling get() on object for each value of i in [0,length-1]. If - * there is not a defined value for a property the Undefined value - * is used to initialize the corresponding element in the array. The - * Java array is then returned. - * If the object doesn't define a length property, null is returned. - * @param object the JavaScript array or array-like object - * @return a Java array of objects - * @since 1.4 release 2 - */ - public Object[] getElements(Scriptable object) { - double doubleLen = NativeArray.getLengthProperty(object); - if (doubleLen != doubleLen) - return null; - int len = (int) doubleLen; - Object[] result = new Object[len]; - for (int i=0; i < len; i++) { - Object elem = object.get(i, object); - result[i] = elem == Scriptable.NOT_FOUND ? Undefined.instance - : elem; - } - return result; - } - - /** - * Convert the value to a JavaScript boolean value. - *

- * See ECMA 9.2. - * - * @param value a JavaScript value - * @return the corresponding boolean value converted using - * the ECMA rules - */ - public static boolean toBoolean(Object value) { - return ScriptRuntime.toBoolean(value); - } - - /** - * Convert the value to a JavaScript Number value. - *

- * Returns a Java double for the JavaScript Number. - *

- * See ECMA 9.3. - * - * @param value a JavaScript value - * @return the corresponding double value converted using - * the ECMA rules - */ - public static double toNumber(Object value) { - return ScriptRuntime.toNumber(value); - } - - /** - * Convert the value to a JavaScript String value. - *

- * See ECMA 9.8. - *

- * @param value a JavaScript value - * @return the corresponding String value converted using - * the ECMA rules - */ - public static String toString(Object value) { - return ScriptRuntime.toString(value); - } - - /** - * Convert the value to an JavaScript object value. - *

- * Note that a scope must be provided to look up the constructors - * for Number, Boolean, and String. - *

- * See ECMA 9.9. - *

- * Additionally, arbitrary Java objects and classes will be - * wrapped in a Scriptable object with its Java fields and methods - * reflected as JavaScript properties of the object. - * - * @param value any Java object - * @param scope global scope containing constructors for Number, - * Boolean, and String - * @return new JavaScript object - */ - public static Scriptable toObject(Object value, Scriptable scope) { - return ScriptRuntime.toObject(scope, value, null); - } - - /** - * Convert the value to an JavaScript object value. - *

- * Note that a scope must be provided to look up the constructors - * for Number, Boolean, and String. - *

- * See ECMA 9.9. - *

- * Additionally, arbitrary Java objects and classes will be - * wrapped in a Scriptable object with its Java fields and methods - * reflected as JavaScript properties of the object. If the - * "staticType" parameter is provided, it will be used as the static - * type of the Java value to create. - * - * @param value any Java object - * @param scope global scope containing constructors for Number, - * Boolean, and String - * @param staticType the static type of the Java value to create - * @return new JavaScript object - */ - public static Scriptable toObject(Object value, Scriptable scope, - Class staticType) { - if (value == null && staticType != null) - return null; - return ScriptRuntime.toObject(scope, value, staticType); - } - - /** - * Tell whether debug information is being generated. - * @since 1.3 - */ - public boolean isGeneratingDebug() { - return generatingDebug; - } - - /** - * Specify whether or not debug information should be generated. - *

- * Setting the generation of debug information on will set the - * optimization level to zero. - * @since 1.3 - */ - public void setGeneratingDebug(boolean generatingDebug) { - generatingDebugChanged = true; - if (generatingDebug) - setOptimizationLevel(0); - this.generatingDebug = generatingDebug; - } - - /** - * Tell whether source information is being generated. - * @since 1.3 - */ - public boolean isGeneratingSource() { - return generatingSource; - } - - /** - * Specify whether or not source information should be generated. - *

- * Without source information, evaluating the "toString" method - * on JavaScript functions produces only "[native code]" for - * the body of the function. - * Note that code generated without source is not fully ECMA - * conformant. - * @since 1.3 - */ - public void setGeneratingSource(boolean generatingSource) { - this.generatingSource = generatingSource; - } - - /** - * Get the current optimization level. - *

- * The optimization level is expressed as an integer between -1 and - * 9. - * @since 1.3 - * - */ - public int getOptimizationLevel() { - return optimizationLevel; - } - - /** - * Set the current optimization level. - *

- * The optimization level is expected to be an integer between -1 and - * 9. Any negative values will be interpreted as -1, and any values - * greater than 9 will be interpreted as 9. - * An optimization level of -1 indicates that interpretive mode will - * always be used. Levels 0 through 9 indicate that class files may - * be generated. Higher optimization levels trade off compile time - * performance for runtime performance. - * The optimizer level can't be set greater than -1 if the optimizer - * package doesn't exist at run time. - * @param optimizationLevel an integer indicating the level of - * optimization to perform - * @since 1.3 - * - */ - public void setOptimizationLevel(int optimizationLevel) { - if (optimizationLevel < 0) { - optimizationLevel = -1; - } else if (optimizationLevel > 9) { - optimizationLevel = 9; - } - if (codegenClass == null) - optimizationLevel = -1; - this.optimizationLevel = optimizationLevel; - } - - /** - * Get the current target class file name. - *

- * If nonnull, requests to compile source will result in one or - * more class files being generated. - * @since 1.3 - */ - public String getTargetClassFileName() { - return nameHelper == null - ? null - : nameHelper.getTargetClassFileName(); - } - - /** - * Set the current target class file name. - *

- * If nonnull, requests to compile source will result in one or - * more class files being generated. If null, classes will only - * be generated in memory. - * - * @since 1.3 - */ - public void setTargetClassFileName(String classFileName) { - if (nameHelper != null) - nameHelper.setTargetClassFileName(classFileName); - } - - /** - * Get the current package to generate classes into. - * - * @since 1.3 - */ - public String getTargetPackage() { - return (nameHelper == null) ? null : nameHelper.getTargetPackage(); - } - - /** - * Set the package to generate classes into. - * - * @since 1.3 - */ - public void setTargetPackage(String targetPackage) { - if (nameHelper != null) - nameHelper.setTargetPackage(targetPackage); - } - - /** - * Get the current interface to write class bytes into. - * - * @see ClassOutput - * @since 1.5 Release 2 - */ - public ClassOutput getClassOutput() { - return nameHelper == null ? null : nameHelper.getClassOutput(); - } - - /** - * Set the interface to write class bytes into. - * Unless setTargetClassFileName() has been called classOutput will be - * used each time the javascript compiler has generated the bytecode for a - * script class. - * - * @see ClassOutput - * @since 1.5 Release 2 - */ - public void setClassOutput(ClassOutput classOutput) { - if (nameHelper != null) - nameHelper.setClassOutput(classOutput); - } - - /** - * Add a Context listener. - */ - public static void addContextListener(ContextListener listener) { - synchronized (staticDataLock) { - contextListeners = ListenerArray.add(contextListeners, listener); - } - } - - /** - * Remove a Context listener. - * @param listener the listener to remove. - */ - public static void removeContextListener(ContextListener listener) { - synchronized (staticDataLock) { - contextListeners = ListenerArray.remove(contextListeners, listener); - } - } - - /** - * Set the security support for this context. - *

SecuritySupport may only be set if it is currently null. - * Otherwise a SecurityException is thrown. - * @param supportObj a SecuritySupport object - * @throws SecurityException if there is already a SecuritySupport - * object for this Context - */ - public synchronized void setSecuritySupport(SecuritySupport supportObj) { - if (securitySupport != null) { - throw new SecurityException("Cannot overwrite existing " + - "SecuritySupport object"); - } - securitySupport = supportObj; - } - - /** - * Return true if a security domain is required on calls to - * compile and evaluate scripts. - * - * @since 1.4 Release 2 - */ - public static boolean isSecurityDomainRequired() { - return requireSecurityDomain; - } - - /** - * Returns the security context associated with the innermost - * script or function being executed by the interpreter. - * @since 1.4 release 2 - */ - public Object getInterpreterSecurityDomain() { - return interpreterSecurityDomain; - } - - /** - * Returns true if the class parameter is a class in the - * interpreter. Typically used by embeddings that get a class - * context to check security. These embeddings must know - * whether to get the security context associated with the - * interpreter or not. - * - * @param cl a class to test whether or not it is an interpreter - * class - * @return true if cl is an interpreter class - * @since 1.4 release 2 - */ - public boolean isInterpreterClass(Class cl) { - return cl == Interpreter.class; - } - - /** - * Set the class that the generated target will extend. - * - * @param extendsClass the class it extends - */ - public void setTargetExtends(Class extendsClass) { - if (nameHelper != null) { - nameHelper.setTargetExtends(extendsClass); - } - } - - /** - * Set the interfaces that the generated target will implement. - * - * @param implementsClasses an array of Class objects, one for each - * interface the target will extend - */ - public void setTargetImplements(Class[] implementsClasses) { - if (nameHelper != null) { - nameHelper.setTargetImplements(implementsClasses); - } - } - - /** - * Get a value corresponding to a key. - *

- * Since the Context is associated with a thread it can be - * used to maintain values that can be later retrieved using - * the current thread. - *

- * Note that the values are maintained with the Context, so - * if the Context is disassociated from the thread the values - * cannot be retreived. Also, if private data is to be maintained - * in this manner the key should be a java.lang.Object - * whose reference is not divulged to untrusted code. - * @param key the key used to lookup the value - * @return a value previously stored using putThreadLocal. - */ - public Object getThreadLocal(Object key) { - if (hashtable == null) - return null; - return hashtable.get(key); - } - - /** - * Put a value that can later be retrieved using a given key. - *

- * @param key the key used to index the value - * @param value the value to save - */ - public void putThreadLocal(Object key, Object value) { - if (hashtable == null) - hashtable = new Hashtable(); - hashtable.put(key, value); - } - - /** - * Remove values from thread-local storage. - * @param key the key for the entry to remove. - * @since 1.5 release 2 - */ - public void removeThreadLocal(Object key) { - if (hashtable == null) - return; - hashtable.remove(key); - } - - /** - * Return whether functions are compiled by this context using - * dynamic scope. - *

- * If functions are compiled with dynamic scope, then they execute - * in the scope of their caller, rather than in their parent scope. - * This is useful for sharing functions across multiple scopes. - * @since 1.5 Release 1 - */ - public boolean hasCompileFunctionsWithDynamicScope() { - return compileFunctionsWithDynamicScopeFlag; - } - - /** - * Set whether functions compiled by this context should use - * dynamic scope. - *

- * @param flag if true, compile functions with dynamic scope - * @since 1.5 Release 1 - */ - public void setCompileFunctionsWithDynamicScope(boolean flag) { - compileFunctionsWithDynamicScopeFlag = flag; - } - - /** - * Set whether to cache some values statically. - *

- * By default, the engine will cache some values statically - * (reflected Java classes, for instance). This can speed - * execution dramatically, but increases the memory footprint. - * Also, with caching enabled, references may be held to - * objects past the lifetime of any real usage. - *

- * If caching is enabled and this method is called with a - * false argument, the caches will be emptied. - * So one strategy could be to clear the caches at times - * appropriate to the application. - *

- * Caching is enabled by default. - * - * @param cachingEnabled if true, caching is enabled - * @since 1.5 Release 1 - */ - public static void setCachingEnabled(boolean cachingEnabled) { - if (isCachingEnabled && !cachingEnabled) { - // Caching is being turned off. Empty caches. - JavaMembers.classTable = new Hashtable(); - nameHelper.reset(); - } - isCachingEnabled = cachingEnabled; - FunctionObject.setCachingEnabled(cachingEnabled); - } - - /** - * Set a WrapHandler for this Context. - *

- * The WrapHandler allows custom object wrapping behavior for - * Java object manipulated with JavaScript. - * @see org.mozilla.javascript.WrapHandler - * @since 1.5 Release 2 - */ - public void setWrapHandler(WrapHandler wrapHandler) { - this.wrapHandler = wrapHandler; - } - - /** - * Return the current WrapHandler, or null if none is defined. - * @see org.mozilla.javascript.WrapHandler - * @since 1.5 Release 2 - */ - public WrapHandler getWrapHandler() { - return wrapHandler; - } - - public DebuggableEngine getDebuggableEngine() { - if (debuggableEngine == null) - debuggableEngine = new DebuggableEngineImpl(this); - return debuggableEngine; - } - - - /** - * if hasFeature(FEATURE_NON_ECMA_GET_YEAR) returns true, - * Date.prototype.getYear subtructs 1900 only if 1900 <= date < 2000 - * in deviation with Ecma B.2.4 - */ - public static final int FEATURE_NON_ECMA_GET_YEAR = 1; - - /** - * Controls certain aspects of script semantics. - * Should be overwritten to alter default behavior. - * @param featureIndex feature index to check - * @return true if the featureIndex feature is turned on - * @see #FEATURE_NON_ECMA_GET_YEAR - */ - public boolean hasFeature(int featureIndex) { - if (featureIndex == FEATURE_NON_ECMA_GET_YEAR) { - /* - * During the great date rewrite of 1.3, we tried to track the - * evolving ECMA standard, which then had a definition of - * getYear which always subtracted 1900. Which we - * implemented, not realizing that it was incompatible with - * the old behavior... now, rather than thrash the behavior - * yet again, we've decided to leave it with the - 1900 - * behavior and point people to the getFullYear method. But - * we try to protect existing scripts that have specified a - * version... - */ - return (version == Context.VERSION_1_0 - || version == Context.VERSION_1_1 - || version == Context.VERSION_1_2); - } - throw new RuntimeException("Bad feature index: " + featureIndex); - } - - /** - * Get/Set threshold of executed instructions counter that triggers call to - * observeInstructionCount(). - * When the threshold is zero, instruction counting is disabled, - * otherwise each time the run-time executes at least the threshold value - * of script instructions, observeInstructionCount() will - * be called. - */ - public int getInstructionObserverThreshold() { - return instructionThreshold; - } - - public void setInstructionObserverThreshold(int threshold) { - instructionThreshold = threshold; - } - - /** - * Allow application to monitor counter of executed script instructions - * in Context subclasses. - * Run-time calls this when instruction counting is enabled and the counter - * reaches limit set by setInstructionObserverThreshold(). - * The method is useful to observe long running scripts and if necessary - * to terminate them. - * @param instructionCount amount of script instruction executed since - * last call to observeInstructionCount - * @throws Error to terminate the script - */ - protected void observeInstructionCount(int instructionCount) {} - - /********** end of API **********/ - - void pushFrame(DebugFrame frame) { - if (frameStack == null) - frameStack = new java.util.Stack(); - frameStack.push(frame); - } - - void popFrame() { - frameStack.pop(); - } - - - - static String getMessage0(String messageId) { - return getMessage(messageId, null); - } - - static String getMessage1(String messageId, Object arg1) { - Object[] arguments = {arg1}; - return getMessage(messageId, arguments); - } - - static String getMessage2(String messageId, Object arg1, Object arg2) { - Object[] arguments = {arg1, arg2}; - return getMessage(messageId, arguments); - } - - static String getMessage3 - (String messageId, Object arg1, Object arg2, Object arg3) { - Object[] arguments = {arg1, arg2, arg3}; - return getMessage(messageId, arguments); - } - /** - * Internal method that reports an error for missing calls to - * enter(). - */ - static Context getContext() { - Thread t = Thread.currentThread(); - Context cx = (Context) threadContexts.get(t); - if (cx == null) { - throw new RuntimeException( - "No Context associated with current Thread"); - } - return cx; - } - - /** GCJ doesn't have an easy way to bundle up .properties files, so we do this */ - static class HardCodedResourceBundle extends ListResourceBundle { - public Object[][] getContents() { return contents; } - static final Object[][] contents = { - { "msg.dup.parms", "Duplicate parameter name \"{0}\"." }, - { "msg.ctor.not.found", "Constructor for \"{0}\" not found." }, - { "msg.not.ctor", "\"{0}\" is not a constructor." }, - { "msg.varargs.ctor", "Method or constructor \"{0}\" must be static with the signature \"(Context cx, Object[] args, Function ctorObj, boolean inNewExpr)\" to define a variable arguments constructor." }, - { "msg.varargs.fun", "Method \"{0}\" must be static with the signature \"(Context cx, Scriptable thisObj, Object[] args, Function funObj)\" to define a variable arguments function." }, - { "msg.incompat.call", "Method \"{0}\" called on incompatible object." }, - { "msg.bad.parms", "Bad method parameters for \"{0}\"." }, - { "msg.no.overload", "Method \"{0}\" occurs multiple times in class \"{1}\"." }, - { "msg.method.not.found", "Method \"{0}\" not found in \"{1}\"." }, - { "msg.bad.for.in.lhs", "Invalid left-hand side of for..in loop." }, - { "msg.bad.lhs.assign", "Invalid assignment left-hand side." }, - { "msg.mult.index", "Only one variable allowed in for..in loop." }, - { "msg.cant.convert", "Can''t convert to type \"{0}\"." }, - { "msg.cant.call.indirect", "Function \"{0}\" must be called directly, and not by way of a function of another name." }, - { "msg.eval.nonstring", "Calling eval() with anything other than a primitive string value will simply return the value. Is this what you intended?" }, - { "msg.only.from.new", "\"{0}\" may only be invoked from a \"new\" expression." }, - { "msg.deprec.ctor", "The \"{0}\" constructor is deprecated." }, - { "msg.no.function.ref.found.in", "no source found in {1} to decompile function reference {0}" }, - { "msg.no.function.ref.found", "no source found to decompile function reference {0}" }, - { "msg.arg.isnt.array", "second argument to Function.prototype.apply must be an array" }, - { "msg.bad.esc.mask", "invalid string escape mask" }, - { "msg.cant.instantiate", "error instantiating ({0}): class {1} is interface or abstract" }, - { "msg.bad.ctor.sig", "Found constructor with wrong signature: {0} calling {1} with signature {2}" }, - { "msg.not.java.obj", "Expected argument to getClass() to be a Java object." }, - { "msg.no.java.ctor", "Java constructor for \"{0}\" with arguments \"{1}\" not found." }, - { "msg.method.ambiguous", "The choice of Java method {0}.{1} matching JavaScript argument types ({2}) is ambiguous; candidate methods are: {3}" }, - { "msg.constructor.ambiguous", "The choice of Java constructor {0} matching JavaScript argument types ({1}) is ambiguous; candidate constructors are: {2}" }, - { "msg.conversion.not.allowed", "Cannot convert {0} to {1}" }, - { "msg.bad.quant", "Invalid quantifier {0}" }, - { "msg.overlarge.max", "Overly large maximum {0}" }, - { "msg.zero.quant", "Zero quantifier {0}" }, - { "msg.max.lt.min", "Maximum {0} less than minimum" }, - { "msg.unterm.quant", "Unterminated quantifier {0}" }, - { "msg.unterm.paren", "Unterminated parenthetical {0}" }, - { "msg.unterm.class", "Unterminated character class {0}" }, - { "msg.bad.range", "Invalid range in character class." }, - { "msg.trail.backslash", "Trailing \\ in regular expression." }, - { "msg.no.regexp", "Regular expressions are not available." }, - { "msg.bad.backref", "back-reference exceeds number of capturing parentheses." }, - { "msg.dup.label", "Duplicate label {0}." }, - { "msg.undef.label", "Undefined label {0}." }, - { "msg.bad.break", "Unlabelled break must be inside loop or switch." }, - { "msg.continue.outside", "continue must be inside loop." }, - { "msg.continue.nonloop", "Can only continue to labeled iteration statement." }, - { "msg.fn.redecl", "Function \"{0}\" redeclared; prior definition will be ignored." }, - { "msg.no.paren.parms", "missing ( before function parameters" }, - { "msg.no.parm", "missing formal parameter" }, - { "msg.no.paren.after.parms", "missing ) after formal parameters" }, - { "msg.no.brace.body", "missing open brace before function body" }, - { "msg.no.brace.after.body", "missing close brace after function body" }, - { "msg.no.paren.cond", "missing ( before condition" }, - { "msg.no.paren.after.cond", "missing ) after condition" }, - { "msg.no.semi.stmt", "missing ; before statement" }, - { "msg.no.name.after.dot", "missing name after . operator" }, - { "msg.no.bracket.index", "missing ] in index expression" }, - { "msg.no.paren.switch", "missing ( before switch expression" }, - { "msg.no.paren.after.switch", "missing ) after switch expression" }, - { "msg.no.brace.switch", "missing open brace before switch body" }, - { "msg.bad.switch", "invalid switch statement" }, - { "msg.no.colon.case", "missing : after case expression" }, - { "msg.no.while.do", "missing while after do-loop body" }, - { "msg.no.paren.for", "missing ( after for" }, - { "msg.no.semi.for", "missing ; after for-loop initializer" }, - { "msg.no.semi.for.cond", "missing ; after for-loop condition" }, - { "msg.no.paren.for.ctrl", "missing ) after for-loop control" }, - { "msg.no.paren.with", "missing ( before with-statement object" }, - { "msg.no.paren.after.with", "missing ) after with-statement object" }, - { "msg.bad.return", "invalid return" }, - { "msg.no.brace.block", "missing close brace in compound statement" }, - { "msg.bad.label", "invalid label" }, - { "msg.bad.var", "missing variable name" }, - { "msg.bad.var.init", "invalid variable initialization" }, - { "msg.no.colon.cond", "missing : in conditional expression" }, - { "msg.no.paren.arg", "missing ) after argument list" }, - { "msg.no.bracket.arg", "missing ] after element list" }, - { "msg.bad.prop", "invalid property id" }, - { "msg.no.colon.prop", "missing : after property id" }, - { "msg.no.brace.prop", "missing close brace after property list" }, - { "msg.no.paren", "missing ) in parenthetical" }, - { "msg.reserved.id", "identifier is a reserved word" }, - { "msg.no.paren.catch", "missing ( before catch-block condition" }, - { "msg.bad.catchcond", "invalid catch block condition" }, - { "msg.catch.unreachable", "any catch clauses following an unqualified catch are unreachable" }, - { "msg.no.brace.catchblock", "missing open brace before catch-block body" }, - { "msg.try.no.catchfinally", "''try'' without ''catch'' or ''finally''" }, - { "msg.syntax", "syntax error" }, - { "msg.assn.create", "Assignment to undefined \"{0}\" will create a new variable. Add a variable statement at the top level scope to remove this warning." }, - { "msg.prop.not.found", "Property not found." }, - { "msg.invalid.type", "Invalid JavaScript value of type {0}" }, - { "msg.primitive.expected", "Primitive type expected (had {0} instead)" }, - { "msg.null.to.object", "Cannot convert null to an object." }, - { "msg.undef.to.object", "Cannot convert undefined to an object." }, - { "msg.cyclic.value", "Cyclic {0} value not allowed." }, - { "msg.is.not.defined", "\"{0}\" is not defined." }, - { "msg.isnt.function", "{0} is not a function." }, - { "msg.bad.default.value", "Object''s getDefaultValue() method returned an object." }, - { "msg.instanceof.not.object", " Can''t use instanceof on a non-object." }, - { "msg.instanceof.bad.prototype", " ''prototype'' property of {0} is not an object." }, - { "msg.bad.radix", " illegal radix {0}." }, - { "msg.default.value", "Cannot find default value for object." }, - { "msg.zero.arg.ctor", "Cannot load class \"{0}\" which has no zero-parameter constructor." }, - { "msg.multiple.ctors", "Cannot have more than one constructor method, but found both {0} and {1}." }, - { "msg.ctor.multiple.parms", "Can''t define constructor or class {0} since more than one constructor has multiple parameters." }, - { "msg.extend.scriptable", "{0} must extend ScriptableObject in order to define property {1}." }, - { "msg.bad.getter.parms", "In order to define a property, getter {0} must have zero parameters or a single ScriptableObject parameter." }, - { "msg.obj.getter.parms", "Expected static or delegated getter {0} to take a ScriptableObject parameter." }, - { "msg.getter.static", "Getter and setter must both be static or neither be static." }, - { "msg.setter2.parms", "Two-parameter setter must take a ScriptableObject as its first parameter." }, - { "msg.setter1.parms", "Expected single parameter setter for {0}" }, - { "msg.setter2.expected", "Expected static or delegated setter {0} to take two parameters." }, - { "msg.setter.parms", "Expected either one or two parameters for setter." }, - { "msg.add.sealed", "Cannot add a property to a sealed object." }, - { "msg.remove.sealed", "Cannot remove a property from a sealed object." }, - { "msg.token.replaces.pushback", "ungot token {0} replaces pushback token {1}" }, - { "msg.missing.exponent", "missing exponent" }, - { "msg.caught.nfe", "number format error: {0}" }, - { "msg.unterminated.string.lit", "unterminated string literal" }, - { "msg.oct.esc.too.large", "octal escape too large" }, - { "msg.nested.comment", "nested comment" }, - { "msg.unterminated.comment", "unterminated comment" }, - { "msg.unterminated.re.lit", "unterminated regular expression literal" }, - { "msg.invalid.re.flag", "invalid flag after regular expression" }, - { "msg.no.re.input.for", "no input for {0}" }, - { "msg.illegal.character", "illegal character" }, - { "msg.invalid.escape", "invalid Unicode escape sequence" }, - { "msg.bad.octal.literal", "illegal octal literal digit {0}; interpreting it as a decimal digit" }, - { "msg.undefined", "The undefined value has no properties." }, - { "msg.java.internal.field.type", "Internal error: type conversion of {0} to assign to {1} on {2} failed." }, - { "msg.java.conversion.implicit_method", "Can''t find converter method \"{0}\" on class {1}." }, - { "msg.java.method.assign", "Java method \"{0}\" cannot be assigned to." }, - { "msg.java.internal.private", "Internal error: attempt to access private/protected field \"{0}\"." }, - { "msg.java.no_such_method", "Can''t find method {0}." }, - { "msg.script.is.not.constructor", "Script objects are not constructors." }, - { "msg.nonjava.method", "Java method \"{0}\" was invoked with a ''this'' value that was not a Java object." }, - { "msg.java.member.not.found", "Java class \"{0}\" has no public instance field or method named \"{1}\"." }, - { "msg.pkg.int", "Java package names may not be numbers." }, - { "msg.ambig.import", "Ambiguous import: \"{0}\" and and \"{1}\"." }, - { "msg.not.pkg", "Function importPackage must be called with a package; had \"{0}\" instead." }, - { "msg.not.class", "Function importClass must be called with a class; had \"{0}\" instead." }, - { "msg.prop.defined", "Cannot import \"{0}\" since a property by that name is already defined." }, - { "msg.arraylength.bad", "Inappropriate array length." }, - { "msg.bad.uri", "Malformed URI sequence." }, - { "msg.bad.precision", "Precision {0} out of range." } - }; - } - - static final ResourceBundle myresources = new HardCodedResourceBundle(); - - /* OPT there's a noticable delay for the first error! Maybe it'd - * make sense to use a ListResourceBundle instead of a properties - * file to avoid (synchronized) text parsing. - */ - static String getMessage(String messageId, Object[] arguments) { - Context cx = getCurrentContext(); - Locale locale = cx != null ? cx.getLocale() : Locale.getDefault(); - - // ResourceBundle does cacheing. - ResourceBundle rb = myresources; - - String formatString; - try { - formatString = rb.getString(messageId); - } catch (java.util.MissingResourceException mre) { - throw new RuntimeException - ("no message resource found for message property "+ messageId); - } - - /* - * It's OK to format the string, even if 'arguments' is null; - * we need to format it anyway, to make double ''s collapse to - * single 's. - */ - // TODO: MessageFormat is not available on pJava - MessageFormat formatter = new MessageFormat(formatString); - return formatter.format(arguments); - } - - // debug flags - static final boolean printTrees = false; - - /** - * Compile a script. - * - * Reads script source from the reader and compiles it, returning - * a class for either the script or the function depending on the - * value of returnFunction. - * - * @param scope the scope to compile relative to - * @param in the Reader to read source from - * @param sourceName the name of the origin of the source (usually - * a file or URL) - * @param lineno the line number of the start of the source - * @param securityDomain an arbitrary object that specifies security - * information about the origin or owner of the script. For - * implementations that don't care about security, this value - * may be null. - * @param returnFunction if true, will expect the source to contain - * a function; return value is assumed to - * then be a org.mozilla.javascript.Function - * @return a class for the script or function - * @see org.mozilla.javascript.Context#compileReader - */ - private Object compile(Scriptable scope, Reader in, String sourceName, - int lineno, Object securityDomain, - boolean returnFunction) - throws IOException - { - if (debugger != null && in != null) { - in = new DebugReader(in); - } - TokenStream ts = new TokenStream(in, scope, sourceName, lineno); - return compile(scope, ts, securityDomain, in, returnFunction); - } - - private static Class codegenClass = null; - private static ClassNameHelper nameHelper = null; - static { - /* - try { - codegenClass = Class.forName( - "org.mozilla.javascript.optimizer.Codegen"); - Class nameHelperClass = Class.forName( - "org.mozilla.javascript.optimizer.OptClassNameHelper"); - nameHelper = (ClassNameHelper)nameHelperClass.newInstance(); - } catch (ClassNotFoundException x) { - // ...must be running lite, that's ok - codegenClass = null; - } catch (IllegalAccessException x) { - codegenClass = null; - } catch (InstantiationException x) { - codegenClass = null; - } - */ - } - - private Interpreter getCompiler() { - if (codegenClass != null) { - try { - return (Interpreter) codegenClass.newInstance(); - } - catch (SecurityException x) { - } - catch (IllegalArgumentException x) { - } - catch (InstantiationException x) { - } - catch (IllegalAccessException x) { - } - // fall through - } - return new Interpreter(); - } - - private Object compile(Scriptable scope, TokenStream ts, - Object securityDomain, Reader in, - boolean returnFunction) - throws IOException - { - Interpreter compiler = optimizationLevel == -1 - ? new Interpreter() - : getCompiler(); - - errorCount = 0; - IRFactory irf = compiler.createIRFactory(ts, nameHelper, scope); - Parser p = new Parser(irf); - Node tree = (Node) p.parse(ts); - if (tree == null) - return null; - - tree = compiler.transform(tree, ts, scope); - - if (printTrees) - System.out.println(tree.toStringTree()); - - if (returnFunction) { - Node first = tree.getFirstChild(); - if (first == null) - return null; - tree = (Node) first.getProp(Node.FUNCTION_PROP); - if (tree == null) - return null; - } - - if (in instanceof DebugReader) { - DebugReader dr = (DebugReader) in; - tree.putProp(Node.DEBUGSOURCE_PROP, dr.getSaved()); - } - - Object result = compiler.compile(this, scope, tree, securityDomain, - securitySupport, nameHelper); - - return errorCount == 0 ? result : null; - } - - static String getSourcePositionFromStack(int[] linep) { - Context cx = getCurrentContext(); - if (cx == null) - return null; - if (cx.interpreterLine > 0 && cx.interpreterSourceFile != null) { - linep[0] = cx.interpreterLine; - return cx.interpreterSourceFile; - } - /** - * A bit of a hack, but the only way to get filename and line - * number from an enclosing frame. - */ - CharArrayWriter writer = new CharArrayWriter(); - RuntimeException re = new RuntimeException(); - re.printStackTrace(new PrintWriter(writer)); - String s = writer.toString(); - int open = -1; - int close = -1; - int colon = -1; - for (int i=0; i < s.length(); i++) { - char c = s.charAt(i); - if (c == ':') - colon = i; - else if (c == '(') - open = i; - else if (c == ')') - close = i; - else if (c == '\n' && open != -1 && close != -1 && colon != -1 && - open < colon && colon < close) - { - String fileStr = s.substring(open + 1, colon); - if (fileStr.endsWith(".js")) { - String lineStr = s.substring(colon + 1, close); - try { - linep[0] = Integer.parseInt(lineStr); - return fileStr; - } - catch (NumberFormatException e) { - // fall through - } - } - open = close = colon = -1; - } - } - - return null; - } - - RegExpProxy getRegExpProxy() { - if (regExpProxy == null) { - try { - Class c = Class.forName( - "org.mozilla.javascript.regexp.RegExpImpl"); - regExpProxy = (RegExpProxy) c.newInstance(); - return regExpProxy; - } catch (ClassNotFoundException e) { - } catch (InstantiationException e) { - } catch (IllegalAccessException e) { - } - } - return regExpProxy; - } - - private void newArrayHelper(Scriptable scope, Scriptable array) { - array.setParentScope(scope); - Object ctor = ScriptRuntime.getTopLevelProp(scope, "Array"); - if (ctor != null && ctor instanceof Scriptable) { - Scriptable s = (Scriptable) ctor; - array.setPrototype((Scriptable) s.get("prototype", s)); - } - } - - final boolean isVersionECMA1() { - return version == VERSION_DEFAULT || version >= VERSION_1_3; - } - - /** - * Get the security context from the given class. - *

- * When some form of security check needs to be done, the class context - * must retrieved from the security manager to determine what class is - * requesting some form of privileged access. - * @since 1.4 release 2 - */ - Object getSecurityDomainFromClass(Class cl) { - if (cl == Interpreter.class) - return interpreterSecurityDomain; - return securitySupport.getSecurityDomain(cl); - } - - SecuritySupport getSecuritySupport() { - return securitySupport; - } - - Object getSecurityDomainForStackDepth(int depth) { - Object result = null; - if (securitySupport != null) { - Class[] classes = securitySupport.getClassContext(); - if (classes != null) { - if (depth != -1) { - int depth1 = depth + 1; - result = getSecurityDomainFromClass(classes[depth1]); - } else { - for (int i=1; i < classes.length; i++) { - result = getSecurityDomainFromClass(classes[i]); - if (result != null) - break; - } - } - } - } - if (result != null) - return result; - if (requireSecurityDomain) - checkSecurityDomainRequired(); - return null; - } - - private static boolean requireSecurityDomain = false; - private static boolean resourceMissing = false; - - final static String securityResourceName = "org.mozilla.javascript.resources.Security"; - - final public static void checkSecurityDomainRequired() { } - - public boolean isGeneratingDebugChanged() { - return generatingDebugChanged; - } - - - /** - * Add a name to the list of names forcing the creation of real - * activation objects for functions. - * - * @param name the name of the object to add to the list - */ - public void addActivationName(String name) { - if (activationNames == null) - activationNames = new Hashtable(5); - activationNames.put(name, name); - } - - /** - * Check whether the name is in the list of names of objects - * forcing the creation of activation objects. - * - * @param name the name of the object to test - * - * @return true if an function activation object is needed. - */ - public boolean isActivationNeeded(String name) { - if ("arguments".equals(name)) - return true; - return activationNames != null && activationNames.containsKey(name); - } - - /** - * Remove a name from the list of names forcing the creation of real - * activation objects for functions. - * - * @param name the name of the object to remove from the list - */ - public void removeActivationName(String name) { - if (activationNames != null) - activationNames.remove(name); - } - - - static final boolean useJSObject = false; - - /** - * The activation of the currently executing function or script. - */ - NativeCall currentActivation; - - // for Objects, Arrays to tag themselves as being printed out, - // so they don't print themselves out recursively. - Hashtable iterating; - - Object interpreterSecurityDomain; - - int version; - int errorCount; - static boolean isCachingEnabled = true; - - private SecuritySupport securitySupport; - private ErrorReporter errorReporter; - private Thread currentThread; - private static Hashtable threadContexts = new Hashtable(11); - private RegExpProxy regExpProxy; - private Locale locale; - private boolean generatingDebug; - private boolean generatingDebugChanged; - private boolean generatingSource=true; - private boolean compileFunctionsWithDynamicScopeFlag; - private int optimizationLevel; - WrapHandler wrapHandler; - Debugger debugger; - DebuggableEngine debuggableEngine; - boolean inLineStepMode; - java.util.Stack frameStack; - private int enterCount; - private Object[] listeners; - private Hashtable hashtable; - - /** - * This is the list of names of objects forcing the creation of - * function activation records. - */ - private Hashtable activationNames; - - // Private lock for static fields to avoid a possibility of denial - // of service via synchronized (Context.class) { while (true) {} } - private static final Object staticDataLock = new Object(); - private static Object[] contextListeners; - public Function currentFunction; - Vector arrayCache = new Vector(10); - - // For the interpreter to indicate line/source for error reports. - public int interpreterLine; - public String interpreterSourceFile; - - public int stackDepth = 0; - - // For instruction counting (interpreter only) - int instructionCount; - int instructionThreshold; -} diff --git a/src/org/mozilla/javascript/ContextListener.java b/src/org/mozilla/javascript/ContextListener.java deleted file mode 100644 index fb8c040..0000000 --- a/src/org/mozilla/javascript/ContextListener.java +++ /dev/null @@ -1,53 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -// API class - -package org.mozilla.javascript; - -/** - * Embeddings that wish to - * @see org.mozilla.javascript.Context#addContextListener - */ -public interface ContextListener { - - public void contextCreated(Context cx); - - public void contextEntered(Context cx); - - public void contextExited(Context cx); - - public void contextReleased(Context cx); -} diff --git a/src/org/mozilla/javascript/DToA.java b/src/org/mozilla/javascript/DToA.java deleted file mode 100644 index 76cde25..0000000 --- a/src/org/mozilla/javascript/DToA.java +++ /dev/null @@ -1,1197 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Waldemar Horwat - * Roger Lawrence - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -import java.math.BigInteger; - -class DToA { - - -/* "-0.0000...(1073 zeros after decimal point)...0001\0" is the longest string that we could produce, - * which occurs when printing -5e-324 in binary. We could compute a better estimate of the size of - * the output string and malloc fewer bytes depending on d and base, but why bother? */ - - static final int DTOBASESTR_BUFFER_SIZE = 1078; - - static char BASEDIGIT(int digit) { - return (char)((digit >= 10) ? 'a' - 10 + digit : '0' + digit); - } - - static final int - DTOSTR_STANDARD = 0, /* Either fixed or exponential format; round-trip */ - DTOSTR_STANDARD_EXPONENTIAL = 1, /* Always exponential format; round-trip */ - DTOSTR_FIXED = 2, /* Round to digits after the decimal point; exponential if number is large */ - DTOSTR_EXPONENTIAL = 3, /* Always exponential format; significant digits */ - DTOSTR_PRECISION = 4; /* Either fixed or exponential format; significant digits */ - - - static final int Frac_mask = 0xfffff; - static final int Exp_shift = 20; - static final int Exp_msk1 = 0x100000; - static final int Bias = 1023; - static final int P = 53; - - static final int Exp_shift1 = 20; - static final int Exp_mask = 0x7ff00000; - static final int Bndry_mask = 0xfffff; - static final int Log2P = 1; - - static final int Sign_bit = 0x80000000; - static final int Exp_11 = 0x3ff00000; - static final int Ten_pmax = 22; - static final int Quick_max = 14; - static final int Bletch = 0x10; - static final int Frac_mask1 = 0xfffff; - static final int Int_max = 14; - static final int n_bigtens = 5; - - - static final double tens[] = { - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, - 1e20, 1e21, 1e22 - }; - - static final double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; - - static int lo0bits(int y) - { - int k; - int x = y; - - if ((x & 7) != 0) { - if ((x & 1) != 0) - return 0; - if ((x & 2) != 0) { - return 1; - } - return 2; - } - k = 0; - if ((x & 0xffff) == 0) { - k = 16; - x >>>= 16; - } - if ((x & 0xff) == 0) { - k += 8; - x >>>= 8; - } - if ((x & 0xf) == 0) { - k += 4; - x >>>= 4; - } - if ((x & 0x3) == 0) { - k += 2; - x >>>= 2; - } - if ((x & 1) == 0) { - k++; - x >>>= 1; - if ((x & 1) == 0) - return 32; - } - return k; - } - - /* Return the number (0 through 32) of most significant zero bits in x. */ - static int hi0bits(int x) - { - int k = 0; - - if ((x & 0xffff0000) == 0) { - k = 16; - x <<= 16; - } - if ((x & 0xff000000) == 0) { - k += 8; - x <<= 8; - } - if ((x & 0xf0000000) == 0) { - k += 4; - x <<= 4; - } - if ((x & 0xc0000000) == 0) { - k += 2; - x <<= 2; - } - if ((x & 0x80000000) == 0) { - k++; - if ((x & 0x40000000) == 0) - return 32; - } - return k; - } - - static void stuffBits(byte bits[], int offset, int val) - { - bits[offset] = (byte)(val >> 24); - bits[offset + 1] = (byte)(val >> 16); - bits[offset + 2] = (byte)(val >> 8); - bits[offset + 3] = (byte)(val); - } - - /* Convert d into the form b*2^e, where b is an odd integer. b is the returned - * Bigint and e is the returned binary exponent. Return the number of significant - * bits in b in bits. d must be finite and nonzero. */ - static BigInteger d2b(double d, int[] e, int[] bits) - { - byte dbl_bits[]; - int i, k, y, z, de; - long dBits = Double.doubleToLongBits(d); - int d0 = (int)(dBits >>> 32); - int d1 = (int)(dBits); - - z = d0 & Frac_mask; - d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ - - if ((de = (int)(d0 >>> Exp_shift)) != 0) - z |= Exp_msk1; - - if ((y = d1) != 0) { - dbl_bits = new byte[8]; - k = lo0bits(y); - y >>>= k; - if (k != 0) { - stuffBits(dbl_bits, 4, y | z << (32 - k)); - z >>= k; - } - else - stuffBits(dbl_bits, 4, y); - stuffBits(dbl_bits, 0, z); - i = (z != 0) ? 2 : 1; - } - else { - // JS_ASSERT(z); - dbl_bits = new byte[4]; - k = lo0bits(z); - z >>>= k; - stuffBits(dbl_bits, 0, z); - k += 32; - i = 1; - } - if (de != 0) { - e[0] = de - Bias - (P-1) + k; - bits[0] = P - k; - } - else { - e[0] = de - Bias - (P-1) + 1 + k; - bits[0] = 32*i - hi0bits(z); - } - return new BigInteger(dbl_bits); - } - - public static String JS_dtobasestr(int base, double d) - { - char[] buffer; /* The output string */ - int p; /* index to current position in the buffer */ - int pInt; /* index to the beginning of the integer part of the string */ - - int q; - int digit; - double di; /* d truncated to an integer */ - double df; /* The fractional part of d */ - -// JS_ASSERT(base >= 2 && base <= 36); - - buffer = new char[DTOBASESTR_BUFFER_SIZE]; - - p = 0; - if (d < 0.0) { - buffer[p++] = '-'; - d = -d; - } - - /* Check for Infinity and NaN */ - if (Double.isNaN(d)) - return "NaN"; - else - if (Double.isInfinite(d)) - return "Infinity"; - - /* Output the integer part of d with the digits in reverse order. */ - pInt = p; - di = (int)d; - BigInteger b = BigInteger.valueOf((int)di); - String intDigits = b.toString(base); - intDigits.getChars(0, intDigits.length(), buffer, p); - p += intDigits.length(); - - df = d - di; - if (df != 0.0) { - /* We have a fraction. */ - buffer[p++] = '.'; - - long dBits = Double.doubleToLongBits(d); - int word0 = (int)(dBits >> 32); - int word1 = (int)(dBits); - - int[] e = new int[1]; - int[] bbits = new int[1]; - - b = d2b(df, e, bbits); -// JS_ASSERT(e < 0); - /* At this point df = b * 2^e. e must be less than zero because 0 < df < 1. */ - - int s2 = -(word0 >>> Exp_shift1 & Exp_mask >> Exp_shift1); - if (s2 == 0) - s2 = -1; - s2 += Bias + P; - /* 1/2^s2 = (nextDouble(d) - d)/2 */ -// JS_ASSERT(-s2 < e); - BigInteger mlo = BigInteger.valueOf(1); - BigInteger mhi = mlo; - if ((word1 == 0) && ((word0 & Bndry_mask) == 0) - && ((word0 & (Exp_mask & Exp_mask << 1)) != 0)) { - /* The special case. Here we want to be within a quarter of the last input - significant digit instead of one half of it when the output string's value is less than d. */ - s2 += Log2P; - mhi = BigInteger.valueOf(1< df = b/2^s2 > 0; - * (d - prevDouble(d))/2 = mlo/2^s2; - * (nextDouble(d) - d)/2 = mhi/2^s2. */ - BigInteger bigBase = BigInteger.valueOf(base); - - boolean done = false; - do { - b = b.multiply(bigBase); - BigInteger[] divResult = b.divideAndRemainder(s); - b = divResult[1]; - digit = (char)(divResult[0].intValue()); - if (mlo == mhi) - mlo = mhi = mlo.multiply(bigBase); - else { - mlo = mlo.multiply(bigBase); - mhi = mhi.multiply(bigBase); - } - - /* Do we yet have the shortest string that will round to d? */ - int j = b.compareTo(mlo); - /* j is b/2^s2 compared with mlo/2^s2. */ - BigInteger delta = s.subtract(mhi); - int j1 = (delta.signum() <= 0) ? 1 : b.compareTo(delta); - /* j1 is b/2^s2 compared with 1 - mhi/2^s2. */ - if (j1 == 0 && ((word1 & 1) == 0)) { - if (j > 0) - digit++; - done = true; - } else - if (j < 0 || (j == 0 && ((word1 & 1) == 0))) { - if (j1 > 0) { - /* Either dig or dig+1 would work here as the least significant digit. - Use whichever would produce an output value closer to d. */ - b = b.shiftLeft(1); - j1 = b.compareTo(s); - if (j1 > 0) /* The even test (|| (j1 == 0 && (digit & 1))) is not here because it messes up odd base output - * such as 3.5 in base 3. */ - digit++; - } - done = true; - } else if (j1 > 0) { - digit++; - done = true; - } -// JS_ASSERT(digit < (uint32)base); - buffer[p++] = BASEDIGIT(digit); - } while (!done); - } - - return new String(buffer, 0, p); - } - - /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. - * - * Inspired by "How to Print Floating-Point Numbers Accurately" by - * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101]. - * - * Modifications: - * 1. Rather than iterating, we use a simple numeric overestimate - * to determine k = floor(log10(d)). We scale relevant - * quantities using O(log2(k)) rather than O(k) multiplications. - * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't - * try to generate digits strictly left to right. Instead, we - * compute with fewer bits and propagate the carry if necessary - * when rounding the final digit up. This is often faster. - * 3. Under the assumption that input will be rounded nearest, - * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. - * That is, we allow equality in stopping tests when the - * round-nearest rule will give the same floating-point value - * as would satisfaction of the stopping test with strict - * inequality. - * 4. We remove common factors of powers of 2 from relevant - * quantities. - * 5. When converting floating-point integers less than 1e16, - * we use floating-point arithmetic rather than resorting - * to multiple-precision integers. - * 6. When asked to produce fewer than 15 digits, we first try - * to get by with floating-point arithmetic; we resort to - * multiple-precision integer arithmetic only if we cannot - * guarantee that the floating-point calculation has given - * the correctly rounded result. For k requested digits and - * "uniformly" distributed input, the probability is - * something like 10^(k-15) that we must resort to the Long - * calculation. - */ - - static int word0(double d) - { - long dBits = Double.doubleToLongBits(d); - return (int)(dBits >> 32); - } - - static double setWord0(double d, int i) - { - long dBits = Double.doubleToLongBits(d); - dBits = ((long)i << 32) | (dBits & 0x0FFFFFFFFL); - return Double.longBitsToDouble(dBits); - } - - static int word1(double d) - { - long dBits = Double.doubleToLongBits(d); - return (int)(dBits); - } - - /* Return b * 5^k. k must be nonnegative. */ - // XXXX the C version built a cache of these - static BigInteger pow5mult(BigInteger b, int k) - { - return b.multiply(BigInteger.valueOf(5).pow(k)); - } - - static boolean roundOff(StringBuffer buf) - { - char lastCh; - while ((lastCh = buf.charAt(buf.length() - 1)) == '9') { - buf.setLength(buf.length() - 1); - if (buf.length() == 0) { - return true; - } - } - buf.append((char)(lastCh + 1)); - return false; - } - - /* Always emits at least one digit. */ - /* If biasUp is set, then rounding in modes 2 and 3 will round away from zero - * when the number is exactly halfway between two representable values. For example, - * rounding 2.5 to zero digits after the decimal point will return 3 and not 2. - * 2.49 will still round to 2, and 2.51 will still round to 3. */ - /* bufsize should be at least 20 for modes 0 and 1. For the other modes, - * bufsize should be two greater than the maximum number of output characters expected. */ - static int - JS_dtoa(double d, int mode, boolean biasUp, int ndigits, - boolean[] sign, StringBuffer buf) - { - /* Arguments ndigits, decpt, sign are similar to those - of ecvt and fcvt; trailing zeros are suppressed from - the returned string. If not null, *rve is set to point - to the end of the return value. If d is +-Infinity or NaN, - then *decpt is set to 9999. - - mode: - 0 ==> shortest string that yields d when read in - and rounded to nearest. - 1 ==> like 0, but with Steele & White stopping rule; - e.g. with IEEE P754 arithmetic , mode 0 gives - 1e23 whereas mode 1 gives 9.999999999999999e22. - 2 ==> max(1,ndigits) significant digits. This gives a - return value similar to that of ecvt, except - that trailing zeros are suppressed. - 3 ==> through ndigits past the decimal point. This - gives a return value similar to that from fcvt, - except that trailing zeros are suppressed, and - ndigits can be negative. - 4-9 should give the same return values as 2-3, i.e., - 4 <= mode <= 9 ==> same return as mode - 2 + (mode & 1). These modes are mainly for - debugging; often they run slower but sometimes - faster than modes 2-3. - 4,5,8,9 ==> left-to-right digit generation. - 6-9 ==> don't try fast floating-point estimate - (if applicable). - - Values of mode other than 0-9 are treated as mode 0. - - Sufficient space is allocated to the return value - to hold the suppressed trailing zeros. - */ - - int b2, b5, i, ieps, ilim, ilim0, ilim1, - j, j1, k, k0, m2, m5, s2, s5; - char dig; - long L; - long x; - BigInteger b, b1, delta, mlo, mhi, S; - int[] be = new int[1]; - int[] bbits = new int[1]; - double d2, ds, eps; - boolean spec_case, denorm, k_check, try_quick, leftright; - - if ((word0(d) & Sign_bit) != 0) { - /* set sign for everything, including 0's and NaNs */ - sign[0] = true; - // word0(d) &= ~Sign_bit; /* clear sign bit */ - d = setWord0(d, word0(d) & ~Sign_bit); - } - else - sign[0] = false; - - if ((word0(d) & Exp_mask) == Exp_mask) { - /* Infinity or NaN */ - buf.append(((word1(d) == 0) && ((word0(d) & Frac_mask) == 0)) ? "Infinity" : "NaN"); - return 9999; - } - if (d == 0) { -// no_digits: - buf.setLength(0); - buf.append('0'); /* copy "0" to buffer */ - return 1; - } - - b = d2b(d, be, bbits); - if ((i = (int)(word0(d) >>> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) { - d2 = setWord0(d, (word0(d) & Frac_mask1) | Exp_11); - /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 - * log10(x) = log(x) / log(10) - * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) - * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) - * - * This suggests computing an approximation k to log10(d) by - * - * k = (i - Bias)*0.301029995663981 - * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); - * - * We want k to be too large rather than too small. - * The error in the first-order Taylor series approximation - * is in our favor, so we just round up the constant enough - * to compensate for any error in the multiplication of - * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, - * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, - * adding 1e-13 to the constant term more than suffices. - * Hence we adjust the constant term to 0.1760912590558. - * (We could get a more accurate k by invoking log10, - * but this is probably not worthwhile.) - */ - i -= Bias; - denorm = false; - } - else { - /* d is denormalized */ - i = bbits[0] + be[0] + (Bias + (P-1) - 1); - x = (i > 32) ? word0(d) << (64 - i) | word1(d) >>> (i - 32) : word1(d) << (32 - i); -// d2 = x; -// word0(d2) -= 31*Exp_msk1; /* adjust exponent */ - d2 = setWord0(x, word0(x) - 31*Exp_msk1); - i -= (Bias + (P-1) - 1) + 1; - denorm = true; - } - /* At this point d = f*2^i, where 1 <= f < 2. d2 is an approximation of f. */ - ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; - k = (int)ds; - if (ds < 0.0 && ds != k) - k--; /* want k = floor(ds) */ - k_check = true; - if (k >= 0 && k <= Ten_pmax) { - if (d < tens[k]) - k--; - k_check = false; - } - /* At this point floor(log10(d)) <= k <= floor(log10(d))+1. - If k_check is zero, we're guaranteed that k = floor(log10(d)). */ - j = bbits[0] - i - 1; - /* At this point d = b/2^j, where b is an odd integer. */ - if (j >= 0) { - b2 = 0; - s2 = j; - } - else { - b2 = -j; - s2 = 0; - } - if (k >= 0) { - b5 = 0; - s5 = k; - s2 += k; - } - else { - b2 -= k; - b5 = -k; - s5 = 0; - } - /* At this point d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5), where b is an odd integer, - b2 >= 0, b5 >= 0, s2 >= 0, and s5 >= 0. */ - if (mode < 0 || mode > 9) - mode = 0; - try_quick = true; - if (mode > 5) { - mode -= 4; - try_quick = false; - } - leftright = true; - ilim = ilim1 = 0; - switch(mode) { - case 0: - case 1: - ilim = ilim1 = -1; - i = 18; - ndigits = 0; - break; - case 2: - leftright = false; - /* no break */ - case 4: - if (ndigits <= 0) - ndigits = 1; - ilim = ilim1 = i = ndigits; - break; - case 3: - leftright = false; - /* no break */ - case 5: - i = ndigits + k + 1; - ilim = i; - ilim1 = i - 1; - if (i <= 0) - i = 1; - } - /* ilim is the maximum number of significant digits we want, based on k and ndigits. */ - /* ilim1 is the maximum number of significant digits we want, based on k and ndigits, - when it turns out that k was computed too high by one. */ - - boolean fast_failed = false; - if (ilim >= 0 && ilim <= Quick_max && try_quick) { - - /* Try to get by with floating-point arithmetic. */ - - i = 0; - d2 = d; - k0 = k; - ilim0 = ilim; - ieps = 2; /* conservative */ - /* Divide d by 10^k, keeping track of the roundoff error and avoiding overflows. */ - if (k > 0) { - ds = tens[k&0xf]; - j = k >> 4; - if ((j & Bletch) != 0) { - /* prevent overflows */ - j &= Bletch - 1; - d /= bigtens[n_bigtens-1]; - ieps++; - } - for(; (j != 0); j >>= 1, i++) - if ((j & 1) != 0) { - ieps++; - ds *= bigtens[i]; - } - d /= ds; - } - else if ((j1 = -k) != 0) { - d *= tens[j1 & 0xf]; - for(j = j1 >> 4; (j != 0); j >>= 1, i++) - if ((j & 1) != 0) { - ieps++; - d *= bigtens[i]; - } - } - /* Check that k was computed correctly. */ - if (k_check && d < 1.0 && ilim > 0) { - if (ilim1 <= 0) - fast_failed = true; - else { - ilim = ilim1; - k--; - d *= 10.; - ieps++; - } - } - /* eps bounds the cumulative error. */ -// eps = ieps*d + 7.0; -// word0(eps) -= (P-1)*Exp_msk1; - eps = ieps*d + 7.0; - eps = setWord0(eps, word0(eps) - (P-1)*Exp_msk1); - if (ilim == 0) { - S = mhi = null; - d -= 5.0; - if (d > eps) { - buf.append('1'); - k++; - return k + 1; - } - if (d < -eps) { - buf.setLength(0); - buf.append('0'); /* copy "0" to buffer */ - return 1; - } - fast_failed = true; - } - if (!fast_failed) { - fast_failed = true; - if (leftright) { - /* Use Steele & White method of only - * generating digits needed. - */ - eps = 0.5/tens[ilim-1] - eps; - for(i = 0;;) { - L = (long)d; - d -= L; - buf.append((char)('0' + L)); - if (d < eps) { - return k + 1; - } - if (1.0 - d < eps) { -// goto bump_up; - char lastCh; - while (true) { - lastCh = buf.charAt(buf.length() - 1); - buf.setLength(buf.length() - 1); - if (lastCh != '9') break; - if (buf.length() == 0) { - k++; - lastCh = '0'; - break; - } - } - buf.append((char)(lastCh + 1)); - return k + 1; - } - if (++i >= ilim) - break; - eps *= 10.0; - d *= 10.0; - } - } - else { - /* Generate ilim digits, then fix them up. */ - eps *= tens[ilim-1]; - for(i = 1;; i++, d *= 10.0) { - L = (long)d; - d -= L; - buf.append((char)('0' + L)); - if (i == ilim) { - if (d > 0.5 + eps) { -// goto bump_up; - char lastCh; - while (true) { - lastCh = buf.charAt(buf.length() - 1); - buf.setLength(buf.length() - 1); - if (lastCh != '9') break; - if (buf.length() == 0) { - k++; - lastCh = '0'; - break; - } - } - buf.append((char)(lastCh + 1)); - return k + 1; - } - else - if (d < 0.5 - eps) { - while (buf.charAt(buf.length() - 1) == '0') - buf.setLength(buf.length() - 1); -// while(*--s == '0') ; -// s++; - return k + 1; - } - break; - } - } - } - } - if (fast_failed) { - buf.setLength(0); - d = d2; - k = k0; - ilim = ilim0; - } - } - - /* Do we have a "small" integer? */ - - if (be[0] >= 0 && k <= Int_max) { - /* Yes. */ - ds = tens[k]; - if (ndigits < 0 && ilim <= 0) { - S = mhi = null; - if (ilim < 0 || d < 5*ds || (!biasUp && d == 5*ds)) { - buf.setLength(0); - buf.append('0'); /* copy "0" to buffer */ - return 1; - } - buf.append('1'); - k++; - return k + 1; - } - for(i = 1;; i++) { - L = (long) (d / ds); - d -= L*ds; - buf.append((char)('0' + L)); - if (i == ilim) { - d += d; - if ((d > ds) || (d == ds && (((L & 1) != 0) || biasUp))) { -// bump_up: -// while(*--s == '9') -// if (s == buf) { -// k++; -// *s = '0'; -// break; -// } -// ++*s++; - char lastCh; - while (true) { - lastCh = buf.charAt(buf.length() - 1); - buf.setLength(buf.length() - 1); - if (lastCh != '9') break; - if (buf.length() == 0) { - k++; - lastCh = '0'; - break; - } - } - buf.append((char)(lastCh + 1)); - } - break; - } - d *= 10.0; - if (d == 0) - break; - } - return k + 1; - } - - m2 = b2; - m5 = b5; - mhi = mlo = null; - if (leftright) { - if (mode < 2) { - i = (denorm) ? be[0] + (Bias + (P-1) - 1 + 1) : 1 + P - bbits[0]; - /* i is 1 plus the number of trailing zero bits in d's significand. Thus, - (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 lsb of d)/10^k. */ - } - else { - j = ilim - 1; - if (m5 >= j) - m5 -= j; - else { - s5 += j -= m5; - b5 += j; - m5 = 0; - } - if ((i = ilim) < 0) { - m2 -= i; - i = 0; - } - /* (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 * 10^(1-ilim))/10^k. */ - } - b2 += i; - s2 += i; - mhi = BigInteger.valueOf(1); - /* (mhi * 2^m2 * 5^m5) / (2^s2 * 5^s5) = one-half of last printed (when mode >= 2) or - input (when mode < 2) significant digit, divided by 10^k. */ - } - /* We still have d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5). Reduce common factors in - b2, m2, and s2 without changing the equalities. */ - if (m2 > 0 && s2 > 0) { - i = (m2 < s2) ? m2 : s2; - b2 -= i; - m2 -= i; - s2 -= i; - } - - /* Fold b5 into b and m5 into mhi. */ - if (b5 > 0) { - if (leftright) { - if (m5 > 0) { - mhi = pow5mult(mhi, m5); - b1 = mhi.multiply(b); - b = b1; - } - if ((j = b5 - m5) != 0) - b = pow5mult(b, j); - } - else - b = pow5mult(b, b5); - } - /* Now we have d/10^k = (b * 2^b2) / (2^s2 * 5^s5) and - (mhi * 2^m2) / (2^s2 * 5^s5) = one-half of last printed or input significant digit, divided by 10^k. */ - - S = BigInteger.valueOf(1); - if (s5 > 0) - S = pow5mult(S, s5); - /* Now we have d/10^k = (b * 2^b2) / (S * 2^s2) and - (mhi * 2^m2) / (S * 2^s2) = one-half of last printed or input significant digit, divided by 10^k. */ - - /* Check for special case that d is a normalized power of 2. */ - spec_case = false; - if (mode < 2) { - if ( (word1(d) == 0) && ((word0(d) & Bndry_mask) == 0) - && ((word0(d) & (Exp_mask & Exp_mask << 1)) != 0) - ) { - /* The special case. Here we want to be within a quarter of the last input - significant digit instead of one half of it when the decimal output string's value is less than d. */ - b2 += Log2P; - s2 += Log2P; - spec_case = true; - } - } - - /* Arrange for convenient computation of quotients: - * shift left if necessary so divisor has 4 leading 0 bits. - * - * Perhaps we should just compute leading 28 bits of S once - * and for all and pass them and a shift to quorem, so it - * can do shifts and ors to compute the numerator for q. - */ - byte [] S_bytes = S.toByteArray(); - int S_hiWord = 0; - for (int idx = 0; idx < 4; idx++) { - S_hiWord = (S_hiWord << 8); - if (idx < S_bytes.length) - S_hiWord |= (S_bytes[idx] & 0xFF); - } - if ((i = (((s5 != 0) ? 32 - hi0bits(S_hiWord) : 1) + s2) & 0x1f) != 0) - i = 32 - i; - /* i is the number of leading zero bits in the most significant word of S*2^s2. */ - if (i > 4) { - i -= 4; - b2 += i; - m2 += i; - s2 += i; - } - else if (i < 4) { - i += 28; - b2 += i; - m2 += i; - s2 += i; - } - /* Now S*2^s2 has exactly four leading zero bits in its most significant word. */ - if (b2 > 0) - b = b.shiftLeft(b2); - if (s2 > 0) - S = S.shiftLeft(s2); - /* Now we have d/10^k = b/S and - (mhi * 2^m2) / S = maximum acceptable error, divided by 10^k. */ - if (k_check) { - if (b.compareTo(S) < 0) { - k--; - b = b.multiply(BigInteger.valueOf(10)); /* we botched the k estimate */ - if (leftright) - mhi = mhi.multiply(BigInteger.valueOf(10)); - ilim = ilim1; - } - } - /* At this point 1 <= d/10^k = b/S < 10. */ - - if (ilim <= 0 && mode > 2) { - /* We're doing fixed-mode output and d is less than the minimum nonzero output in this mode. - Output either zero or the minimum nonzero output depending on which is closer to d. */ - if ((ilim < 0 ) - || ((i = b.compareTo(S = S.multiply(BigInteger.valueOf(5)))) < 0) - || ((i == 0 && !biasUp))) { - /* Always emit at least one digit. If the number appears to be zero - using the current mode, then emit one '0' digit and set decpt to 1. */ - /*no_digits: - k = -1 - ndigits; - goto ret; */ - buf.setLength(0); - buf.append('0'); /* copy "0" to buffer */ - return 1; -// goto no_digits; - } -// one_digit: - buf.append('1'); - k++; - return k + 1; - } - if (leftright) { - if (m2 > 0) - mhi = mhi.shiftLeft(m2); - - /* Compute mlo -- check for special case - * that d is a normalized power of 2. - */ - - mlo = mhi; - if (spec_case) { - mhi = mlo; - mhi = mhi.shiftLeft(Log2P); - } - /* mlo/S = maximum acceptable error, divided by 10^k, if the output is less than d. */ - /* mhi/S = maximum acceptable error, divided by 10^k, if the output is greater than d. */ - - for(i = 1;;i++) { - BigInteger[] divResult = b.divideAndRemainder(S); - b = divResult[1]; - dig = (char)(divResult[0].intValue() + '0'); - /* Do we yet have the shortest decimal string - * that will round to d? - */ - j = b.compareTo(mlo); - /* j is b/S compared with mlo/S. */ - delta = S.subtract(mhi); - j1 = (delta.signum() <= 0) ? 1 : b.compareTo(delta); - /* j1 is b/S compared with 1 - mhi/S. */ - if ((j1 == 0) && (mode == 0) && ((word1(d) & 1) == 0)) { - if (dig == '9') { - buf.append('9'); - if (roundOff(buf)) { - k++; - buf.append('1'); - } - return k + 1; -// goto round_9_up; - } - if (j > 0) - dig++; - buf.append(dig); - return k + 1; - } - if ((j < 0) - || ((j == 0) - && (mode == 0) - && ((word1(d) & 1) == 0) - )) { - if (j1 > 0) { - /* Either dig or dig+1 would work here as the least significant decimal digit. - Use whichever would produce a decimal value closer to d. */ - b = b.shiftLeft(1); - j1 = b.compareTo(S); - if (((j1 > 0) || (j1 == 0 && (((dig & 1) == 1) || biasUp))) - && (dig++ == '9')) { - buf.append('9'); - if (roundOff(buf)) { - k++; - buf.append('1'); - } - return k + 1; -// goto round_9_up; - } - } - buf.append(dig); - return k + 1; - } - if (j1 > 0) { - if (dig == '9') { /* possible if i == 1 */ -// round_9_up: -// *s++ = '9'; -// goto roundoff; - buf.append('9'); - if (roundOff(buf)) { - k++; - buf.append('1'); - } - return k + 1; - } - buf.append((char)(dig + 1)); - return k + 1; - } - buf.append(dig); - if (i == ilim) - break; - b = b.multiply(BigInteger.valueOf(10)); - if (mlo == mhi) - mlo = mhi = mhi.multiply(BigInteger.valueOf(10)); - else { - mlo = mlo.multiply(BigInteger.valueOf(10)); - mhi = mhi.multiply(BigInteger.valueOf(10)); - } - } - } - else - for(i = 1;; i++) { -// (char)(dig = quorem(b,S) + '0'); - BigInteger[] divResult = b.divideAndRemainder(S); - b = divResult[1]; - dig = (char)(divResult[0].intValue() + '0'); - buf.append(dig); - if (i >= ilim) - break; - b = b.multiply(BigInteger.valueOf(10)); - } - - /* Round off last digit */ - - b = b.shiftLeft(1); - j = b.compareTo(S); - if ((j > 0) || (j == 0 && (((dig & 1) == 1) || biasUp))) { -// roundoff: -// while(*--s == '9') -// if (s == buf) { -// k++; -// *s++ = '1'; -// goto ret; -// } -// ++*s++; - if (roundOff(buf)) { - k++; - buf.append('1'); - return k + 1; - } - } - else { - /* Strip trailing zeros */ - while (buf.charAt(buf.length() - 1) == '0') - buf.setLength(buf.length() - 1); -// while(*--s == '0') ; -// s++; - } -// ret: -// Bfree(S); -// if (mhi) { -// if (mlo && mlo != mhi) -// Bfree(mlo); -// Bfree(mhi); -// } -// ret1: -// Bfree(b); -// JS_ASSERT(s < buf + bufsize); - return k + 1; - } - - /* Mapping of JSDToStrMode -> JS_dtoa mode */ - private static final int dtoaModes[] = { - 0, /* DTOSTR_STANDARD */ - 0, /* DTOSTR_STANDARD_EXPONENTIAL, */ - 3, /* DTOSTR_FIXED, */ - 2, /* DTOSTR_EXPONENTIAL, */ - 2}; /* DTOSTR_PRECISION */ - - static void - JS_dtostr(StringBuffer buffer, int mode, int precision, double d) - { - int decPt; /* Position of decimal point relative to first digit returned by JS_dtoa */ - boolean[] sign = new boolean[1]; /* true if the sign bit was set in d */ - int nDigits; /* Number of significand digits returned by JS_dtoa */ - -// JS_ASSERT(bufferSize >= (size_t)(mode <= DTOSTR_STANDARD_EXPONENTIAL ? DTOSTR_STANDARD_BUFFER_SIZE : -// DTOSTR_VARIABLE_BUFFER_SIZE(precision))); - - if (mode == DTOSTR_FIXED && (d >= 1e21 || d <= -1e21)) - mode = DTOSTR_STANDARD; /* Change mode here rather than below because the buffer may not be large enough to hold a large integer. */ - - decPt = JS_dtoa(d, dtoaModes[mode], mode >= DTOSTR_FIXED, precision, sign, buffer); - nDigits = buffer.length(); - - /* If Infinity, -Infinity, or NaN, return the string regardless of the mode. */ - if (decPt != 9999) { - boolean exponentialNotation = false; - int minNDigits = 0; /* Minimum number of significand digits required by mode and precision */ - int p; - int q; - - switch (mode) { - case DTOSTR_STANDARD: - if (decPt < -5 || decPt > 21) - exponentialNotation = true; - else - minNDigits = decPt; - break; - - case DTOSTR_FIXED: - if (precision >= 0) - minNDigits = decPt + precision; - else - minNDigits = decPt; - break; - - case DTOSTR_EXPONENTIAL: -// JS_ASSERT(precision > 0); - minNDigits = precision; - /* Fall through */ - case DTOSTR_STANDARD_EXPONENTIAL: - exponentialNotation = true; - break; - - case DTOSTR_PRECISION: -// JS_ASSERT(precision > 0); - minNDigits = precision; - if (decPt < -5 || decPt > precision) - exponentialNotation = true; - break; - } - - /* If the number has fewer than minNDigits, pad it with zeros at the end */ - if (nDigits < minNDigits) { - p = minNDigits; - nDigits = minNDigits; - do { - buffer.append('0'); - } while (buffer.length() != p); - } - - if (exponentialNotation) { - /* Insert a decimal point if more than one significand digit */ - if (nDigits != 1) { - buffer.insert(1, '.'); - } - buffer.append('e'); - if ((decPt - 1) >= 0) - buffer.append('+'); - buffer.append(decPt - 1); -// JS_snprintf(numEnd, bufferSize - (numEnd - buffer), "e%+d", decPt-1); - } else if (decPt != nDigits) { - /* Some kind of a fraction in fixed notation */ -// JS_ASSERT(decPt <= nDigits); - if (decPt > 0) { - /* dd...dd . dd...dd */ - buffer.insert(decPt, '.'); - } else { - /* 0 . 00...00dd...dd */ - for (int i = 0; i < 1 - decPt; i++) - buffer.insert(0, '0'); - buffer.insert(1, '.'); - } - } - } - - /* If negative and neither -0.0 nor NaN, output a leading '-'. */ - if (sign[0] && - !(word0(d) == Sign_bit && word1(d) == 0) && - !((word0(d) & Exp_mask) == Exp_mask && - ((word1(d) != 0) || ((word0(d) & Frac_mask) != 0)))) { - buffer.insert(0, '-'); - } - } - -} - diff --git a/src/org/mozilla/javascript/DebuggableEngineImpl.java b/src/org/mozilla/javascript/DebuggableEngineImpl.java deleted file mode 100644 index 3896871..0000000 --- a/src/org/mozilla/javascript/DebuggableEngineImpl.java +++ /dev/null @@ -1,111 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -// API class - -package org.mozilla.javascript; - -import org.mozilla.javascript.debug.*; - -public class DebuggableEngineImpl implements DebuggableEngine { - - public DebuggableEngineImpl(Context cx) { - this.cx = cx; - } - - /** - * Set whether the engine should break when it encounters - * the next line. - *

- * The engine will call the attached debugger's handleBreakpointHit - * method on the next line it executes if isLineStep is true. - * May be used from another thread to interrupt execution. - * - * @param isLineStep if true, break next line - */ - public void setBreakNextLine(boolean isLineStep) { - cx.inLineStepMode = isLineStep; - } - - /** - * Return the value of the breakNextLine flag. - * @return true if the engine will break on execution of the - * next line. - */ - public boolean getBreakNextLine() { - return cx.inLineStepMode; - } - - /** - * Set the associated debugger. - * @param debugger the debugger to be used on callbacks from - * the engine. - */ - public void setDebugger(Debugger debugger) { - cx.debugger = debugger; - } - - /** - * Return the current debugger. - * @return the debugger, or null if none is attached. - */ - public Debugger getDebugger() { - return cx.debugger; - } - - /** - * Return the number of frames in current execution. - * @return the count of current frames - */ - public int getFrameCount() { - return cx.frameStack == null ? 0 : cx.frameStack.size(); - } - - /** - * Return a frame from the current execution. - * Frames are numbered starting from 0 for the innermost - * frame. - * @param frameNumber the number of the frame in the range - * [0,frameCount-1] - * @return the relevant DebugFrame, or null if frameNumber is out - * of range or the engine isn't currently saving - * frames - */ - public DebugFrame getFrame(int frameNumber) { - return (DebugFrame) cx.frameStack.elementAt(cx.frameStack.size() - frameNumber - 1); - } - - private Context cx; -} diff --git a/src/org/mozilla/javascript/DefaultErrorReporter.java b/src/org/mozilla/javascript/DefaultErrorReporter.java deleted file mode 100644 index 10044e8..0000000 --- a/src/org/mozilla/javascript/DefaultErrorReporter.java +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -/** - * This is the default error reporter for JavaScript. - * - * @author Norris Boyd - */ -class DefaultErrorReporter implements ErrorReporter { - - public void warning(String message, String sourceName, int line, - String lineSource, int lineOffset) - { - // do nothing - } - - public void error(String message, String sourceName, int line, - String lineSource, int lineOffset) - { - //System.out.println("error at " + sourceName + ":" + line + " -- " + message); - throw new EvaluatorException(message + " at " + sourceName + ":" + line); - } - - public EvaluatorException runtimeError(String message, String sourceName, - int line, String lineSource, - int lineOffset) - { - //System.out.println("error at " + sourceName + ":" + line + " -- " + message); - return new EvaluatorException(message + " at " + sourceName + ":" + line); - } -} diff --git a/src/org/mozilla/javascript/Delegator.java b/src/org/mozilla/javascript/Delegator.java deleted file mode 100644 index ee93fcc..0000000 --- a/src/org/mozilla/javascript/Delegator.java +++ /dev/null @@ -1,250 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the - * License for the specific language governing rights and limitations - * under the License. - * - * The Original Code is Delegator.java, released Sep 27, 2000. - * - * The Initial Developer of the Original Code is Matthias Radestock. - * . Portions created by Matthias Radestock are - * Copyright (C) 2000 Matthias Radestock. All Rights Reserved. - * - * Contributor(s): - * Redfig Ltd (http://www.redfig.com) - * LShift Ltd (http://www.lshift.net) - * - * Alternatively, the contents of this file may be used under the terms - * of the GNU Public License (the "GPL License"), in which case the - * provisions of the GPL License are applicable instead of those - * above. If you wish to allow use of your version of this file only - * under the terms of the GPL License and not to allow others to use - * your version of this file under the MPL, indicate your decision by - * deleting the provisions above and replace them with the notice and - * other provisions required by the GPL License. If you do not delete - * the provisions above, a recipient may use your version of this file - * under either the MPL or the GPL License. - */ - -// API class - -package org.mozilla.javascript; - -/** - * This is a helper class for implementing wrappers around Scriptable - * objects. It implements the Function interface and delegates all - * invocations to a delegee Scriptable object. The normal use of this - * class involves creating a sub-class and overriding one or more of - * the methods. - * - * A useful application is the implementation of interceptors, - * pre/post conditions, debugging. - * - * @see Function - * @see Scriptable - * @author Matthias Radestock - */ - -public class Delegator implements Function { - - protected Scriptable obj = null; - - /** - * Create a Delegator prototype. - * - * This constructor should only be used for creating prototype - * objects of Delegator. - * - * @see org.mozilla.javascript.Delegator#construct - */ - public Delegator() { - } - - /** - * Create a new Delegator that forwards requests to a delegee - * Scriptable object. - * - * @param obj the delegee - * @see org.mozilla.javascript.Scriptable - */ - public Delegator(Scriptable obj) { - this.obj = obj; - } - - /** - * Retrieve the delegee. - * - * @return the delegee - */ - public Scriptable getDelegee() { - return obj; - } - /** - * Set the delegee. - * - * @param obj the delegee - * @see org.mozilla.javascript.Scriptable - */ - public void setDelegee(Scriptable obj) { - this.obj = obj; - } - /** - * @see org.mozilla.javascript.Scriptable#getClassName - */ - public String getClassName() { - return obj.getClassName(); - } - /** - * @see org.mozilla.javascript.Scriptable#get - */ - public Object get(String name, Scriptable start) { - return obj.get(name,start); - } - /** - * @see org.mozilla.javascript.Scriptable#get - */ - public Object get(int index, Scriptable start) { - return obj.get(index,start); - } - /** - * @see org.mozilla.javascript.Scriptable#has - */ - public boolean has(String name, Scriptable start) { - return obj.has(name,start); - } - /** - * @see org.mozilla.javascript.Scriptable#has - */ - public boolean has(int index, Scriptable start) { - return obj.has(index,start); - } - /** - * @see org.mozilla.javascript.Scriptable#put - */ - public void put(String name, Scriptable start, Object value) { - obj.put(name,start,value); - } - /** - * @see org.mozilla.javascript.Scriptable#put - */ - public void put(int index, Scriptable start, Object value) { - obj.put(index,start,value); - } - /** - * @see org.mozilla.javascript.Scriptable#delete - */ - public void delete(String name) { - obj.delete(name); - } - /** - * @see org.mozilla.javascript.Scriptable#delete - */ - public void delete(int index) { - obj.delete(index); - } - /** - * @see org.mozilla.javascript.Scriptable#getPrototype - */ - public Scriptable getPrototype() { - return obj.getPrototype(); - } - /** - * @see org.mozilla.javascript.Scriptable#setPrototype - */ - public void setPrototype(Scriptable prototype) { - obj.setPrototype(prototype); - } - /** - * @see org.mozilla.javascript.Scriptable#getParentScope - */ - public Scriptable getParentScope() { - return obj.getParentScope(); - } - /** - * @see org.mozilla.javascript.Scriptable#setParentScope - */ - public void setParentScope(Scriptable parent) { - obj.setParentScope(parent); - } - /** - * @see org.mozilla.javascript.Scriptable#getIds - */ - public Object[] getIds() { - return obj.getIds(); - } - /** - * Note that this method does not get forwarded to the delegee if - * the hint parameter is null, - * ScriptRuntime.ScriptableClass or - * ScriptRuntime.FunctionClass. Instead the object - * itself is returned. - * - * @param hint the type hint - * @return the default value - * - * @see org.mozilla.javascript.Scriptable#getDefaultValue - */ - public Object getDefaultValue(Class hint) { - return (hint == null || - hint == ScriptRuntime.ScriptableClass || - hint == ScriptRuntime.FunctionClass) ? - this : obj.getDefaultValue(hint); - } - /** - * @see org.mozilla.javascript.Scriptable#hasInstance - */ - public boolean hasInstance(Scriptable instance) { - return obj.hasInstance(instance); - } - /** - * @see org.mozilla.javascript.Function#call - */ - public Object call(Context cx, Scriptable scope, Scriptable thisObj, - Object[] args) - throws JavaScriptException { - return ((Function)obj).call(cx,scope,thisObj,args); - } - - /** - * Note that if the delegee is null, - * this method creates a new instance of the Delegator itself - * rathert than forwarding the call to the - * delegee. This permits the use of Delegator - * prototypes. - * - * @param cx the current Context for this thread - * @param scope an enclosing scope of the caller except - * when the function is called from a closure. - * @param args the array of arguments - * @return the allocated object - * @exception JavaScriptException if an uncaught exception - * occurred while executing the constructor - * - * @see org.mozilla.javascript.Function#construct - */ - public Scriptable construct(Context cx, Scriptable scope, Object[] args) - throws JavaScriptException { - if (obj == null) { - //this little trick allows us to declare prototype objects for - //Delegators - try { - Delegator n = (Delegator)this.getClass().newInstance(); - n.setDelegee((Scriptable)args[0]); - return n; - } - catch (Exception e) { - e.printStackTrace(); - throw new Error("exception in org.mozilla.javascript.Delegator.construct()"); - //System.exit(0); - } - } - else { - return ((Function)obj).construct(cx,scope,args); - } - } -} diff --git a/src/org/mozilla/javascript/EcmaError.java b/src/org/mozilla/javascript/EcmaError.java deleted file mode 100644 index 46c3e2b..0000000 --- a/src/org/mozilla/javascript/EcmaError.java +++ /dev/null @@ -1,152 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Roger Lawrence - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -// API class - -package org.mozilla.javascript; - -/** - * The class of exceptions raised by the engine as described in - * ECMA edition 3. See section 15.11.6 in particular. - */ -public class EcmaError extends RuntimeException { - - /** - * Create an exception with the specified detail message. - * - * Errors internal to the JavaScript engine will simply throw a - * RuntimeException. - * - * @param nativeError the NativeError object constructed for this error - * @param sourceName the name of the source reponsible for the error - * @param lineNumber the line number of the source - * @param columnNumber the columnNumber of the source (may be zero if - * unknown) - * @param lineSource the source of the line containing the error (may be - * null if unknown) - */ - public EcmaError(NativeError nativeError, String sourceName, - int lineNumber, int columnNumber, String lineSource) - { - super("EcmaError"); - errorObject = nativeError; - this.sourceName = sourceName; - this.lineNumber = lineNumber; - this.columnNumber = columnNumber; - this.lineSource = lineSource; - } - - /** - * Return a string representation of the error, which currently consists - * of the name of the error together with the message. - */ - public String toString() { - if (sourceName != null && lineNumber > 0) - return errorObject.toString() + " (" + sourceName + - "; line " + lineNumber + ")"; - else - return errorObject.toString(); - } - - /** - * Gets the name of the error. - * - * ECMA edition 3 defines the following - * errors: EvalError, RangeError, ReferenceError, - * SyntaxError, TypeError, and URIError. Additional error names - * may be added in the future. - * - * See ECMA edition 3, 15.11.7.9. - * - * @return the name of the error. - */ - public String getName() { - return errorObject.getName(); - } - - /** - * Gets the message corresponding to the error. - * - * See ECMA edition 3, 15.11.7.10. - * - * @return an implemenation-defined string describing the error. - */ - public String getMessage() { - return errorObject.getMessage(); - } - - /** - * Get the name of the source containing the error, or null - * if that information is not available. - */ - public String getSourceName() { - return sourceName; - } - - /** - * Returns the line number of the statement causing the error, - * or zero if not available. - */ - public int getLineNumber() { - return lineNumber; - } - - /** - * Get the error object corresponding to this exception. - */ - public Scriptable getErrorObject() { - return errorObject; - } - - /** - * The column number of the location of the error, or zero if unknown. - */ - public int getColumnNumber() { - return columnNumber; - } - - /** - * The source of the line causing the error, or zero if unknown. - */ - public String getLineSource() { - return lineSource; - } - - private NativeError errorObject; - private String sourceName; - private int lineNumber; - private int columnNumber; - private String lineSource; -} diff --git a/src/org/mozilla/javascript/ErrorReporter.java b/src/org/mozilla/javascript/ErrorReporter.java deleted file mode 100644 index b945e7e..0000000 --- a/src/org/mozilla/javascript/ErrorReporter.java +++ /dev/null @@ -1,103 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -// API class - -package org.mozilla.javascript; - -/** - * This is interface defines a protocol for the reporting of - * errors during JavaScript translation or execution. - * - * @author Norris Boyd - */ - -public interface ErrorReporter { - - /** - * Report a warning. - * - * The implementing class may choose to ignore the warning - * if it desires. - * - * @param message a String describing the warning - * @param sourceName a String describing the JavaScript source - * where the warning occured; typically a filename or URL - * @param line the line number associated with the warning - * @param lineSource the text of the line (may be null) - * @param lineOffset the offset into lineSource where problem was detected - */ - void warning(String message, String sourceName, int line, - String lineSource, int lineOffset); - - /** - * Report an error. - * - * The implementing class is free to throw an exception if - * it desires. - * - * If execution has not yet begun, the JavaScript engine is - * free to find additional errors rather than terminating - * the translation. It will not execute a script that had - * errors, however. - * - * @param message a String describing the error - * @param sourceName a String describing the JavaScript source - * where the error occured; typically a filename or URL - * @param line the line number associated with the error - * @param lineSource the text of the line (may be null) - * @param lineOffset the offset into lineSource where problem was detected - */ - void error(String message, String sourceName, int line, - String lineSource, int lineOffset); - - /** - * Creates an EvaluatorException that may be thrown. - * - * runtimeErrors, unlike errors, will always terminate the - * current script. - * - * @param message a String describing the error - * @param sourceName a String describing the JavaScript source - * where the error occured; typically a filename or URL - * @param line the line number associated with the error - * @param lineSource the text of the line (may be null) - * @param lineOffset the offset into lineSource where problem was detected - * @return an EvaluatorException that will be thrown. - */ - EvaluatorException runtimeError(String message, String sourceName, - int line, String lineSource, - int lineOffset); -} diff --git a/src/org/mozilla/javascript/EvaluatorException.java b/src/org/mozilla/javascript/EvaluatorException.java deleted file mode 100644 index 5f31201..0000000 --- a/src/org/mozilla/javascript/EvaluatorException.java +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - - -package org.mozilla.javascript; - -/** - * The class of exceptions thrown by the JavaScript engine. - */ -public class EvaluatorException extends RuntimeException { - - /** - * Create an exception with the specified detail message. - * - * Errors internal to the JavaScript engine will simply throw a - * RuntimeException. - * - * @param detail a message with detail about the exception - */ - public EvaluatorException(String detail) { - super(detail); - } - -} diff --git a/src/org/mozilla/javascript/FlattenedObject.java b/src/org/mozilla/javascript/FlattenedObject.java deleted file mode 100644 index 85c5f0b..0000000 --- a/src/org/mozilla/javascript/FlattenedObject.java +++ /dev/null @@ -1,341 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * Roger Lawrence - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -import java.util.Hashtable; -import java.util.Enumeration; - -/** - * Manipulate a Scriptable object as if its prototype chain were flattened. - *

- * This class has been deprecated in favor of the static methods - * getProperty, putProperty, and - * deleteProperty of ScripableObject. Those methods provide the - * same functionality without the confusing and inefficient need to construct - * a new object instance. - * - * @see org.mozilla.javascript.ScriptableObject - * @deprecated - * @author Norris Boyd - */ - -public class FlattenedObject { - - /** - * Construct a new FlattenedObject. - * - * @param object the object to be viewed with flattened properties - * @deprecated - */ - public FlattenedObject(Scriptable object) { - this.obj = object; - } - - /** - * Get the associated Scriptable object. - * @deprecated - */ - public Scriptable getObject() { - return obj; - } - - /** - * Determine if a property exists in an object. - * - * This is a more convenient (and less efficient) form than - * Scriptable.has(). - * It returns true if and only if the property - * exists in this object or any of the objects in its prototype - * chain. - * - * @param id the property index, which may be either a String or a - * Number - * @return true if and only if the property exists in the prototype - * chain - * @see org.mozilla.javascript.Scriptable#has - * @deprecated As of 1.5R2, replaced by ScriptableObject.getProperty - */ - public boolean hasProperty(Object id) { - String stringId = ScriptRuntime.toString(id); - String s = ScriptRuntime.getStringId(stringId); - if (s == null) - return getBase(obj, ScriptRuntime.getIntId(stringId)) != null; - return getBase(obj, s) != null; - } - - /** - * Get a property of an object. - *

- * This is a more convenient (and less efficient) form than - * Scriptable.get(). It corresponds exactly to the - * expression obj[id] in JavaScript. This method - * will traverse the prototype chain of an object to find the - * property.

- * - * If the property does not exist in the object or its prototype - * chain, the undefined value will be returned. - * - * @param id the property index; can be a String or a Number; the - * String may contain characters representing a number - * @return the value of the property or the undefined value - * @see org.mozilla.javascript.Scriptable#get - * @see org.mozilla.javascript.Context#getUndefinedValue - * @deprecated As of 1.5R2, replaced by ScriptableObject.getProperty - */ - public Object getProperty(Object id) { - String s = ScriptRuntime.getStringId(id); - int index = s == null ? ScriptRuntime.getIntId(id) : 0; - Scriptable m = obj; - Object result; - for(;;) { - result = s == null ? m.get(index, obj) : m.get(s, obj); - if (result != Scriptable.NOT_FOUND) - break; - m = m.getPrototype(); - if (m == null) - return Undefined.instance; - } - if (result instanceof Scriptable) - return new FlattenedObject((Scriptable) result); - return result; - } - - /** - * Set a property of an object. - * - * This is a more convenient (and less efficient) form than that - * provided in Scriptable. It corresponds exactly to the - * expression obj[id] = val in JavaScript.

- * - * @param id the property index, which may be either a String or - * a Number - * @param value the value of the property - * @see org.mozilla.javascript.Scriptable#put - * @deprecated As of 1.5R2, replaced by ScriptableObject.putProperty - */ - public void putProperty(Object id, Object value) { - String s = ScriptRuntime.getStringId(id); - if (value instanceof FlattenedObject) - value = ((FlattenedObject) value).getObject(); - Scriptable x; - if (s == null) { - int index = ScriptRuntime.getIntId(id); - x = getBase(obj, index); - if (x == null) - x = obj; - x.put(index, obj, value); - return; - } - x = getBase(obj, s); - if (x == null) - x = obj; - x.put(s, obj, value); - } - - /** - * Remove a property. - * - * This method provides the functionality of the delete - * operator in JavaScript. - * - * @param id the property index, which may be either a String or - * a Number - * @return true if the property didn't exist, or existed and was removed - * @see org.mozilla.javascript.Scriptable#delete - * @deprecated as of 1.5R2, replaced by ScriptableObject.deleteProperty - */ - public boolean deleteProperty(Object id) { - String s = ScriptRuntime.getStringId(id); - if (s == null) { - int index = ScriptRuntime.getIntId(id); - Scriptable base = getBase(obj, index); - if (base == null) - return true; - base.delete(index); - return !base.has(index, base); - } - Scriptable base = getBase(obj, s); - if (base == null) - return true; - base.delete(s); - return !base.has(s, base); - } - - /** - * Return an array that contains the ids of the properties. - * - *

This method will walk the prototype chain and collect the - * ids of all objects in the prototype chain.

- * - * If an id appears in more than one object in the prototype chain, - * it will only be in the array once. (So all the entries in the - * array will be unique respective to equals().) - * - * @see org.mozilla.javascript.Scriptable#getIds - * @deprecated - */ - public Object[] getIds() { - Hashtable h = new Hashtable(11); - Scriptable m = obj; - while (m != null) { - Object[] e = m.getIds(); - for (int i=0; i < e.length; i++) { - h.put(e[i], Boolean.TRUE); - } - m = m.getPrototype(); - } - Enumeration keys = h.keys(); - Object elem; - Object[] result = new Object[h.size()]; - int index = 0; - while (keys.hasMoreElements()) { - elem = keys.nextElement(); - result[index++] = elem; - } - return result; - } - - /** - * Consider this object to be a function, and call it. - * - * @param cx the current Context for this thread - * @param thisObj the JavaScript 'this' for the call - * @param args the arguments for the call - * @return the result of the JavaScript function call - * @exception NotAFunctionException if this object is not a function - * @exception JavaScriptException if an uncaught JavaScript exception - * occurred while executing the function - * @see org.mozilla.javascript.Function#call - * @deprecated - */ - public Object call(Context cx, Scriptable thisObj, Object[] args) - throws NotAFunctionException, - JavaScriptException - { - if (!(obj instanceof Function)) { - throw new NotAFunctionException(); - } - return ScriptRuntime.call(cx, obj, thisObj, args, (Function) obj); - } - - /** - * Consider this object to be a function, and invoke it as a - * constructor call. - * - * @param cx the current Context for this thread - * @param args the arguments for the constructor call - * @return the allocated object - * @exception NotAFunctionException if this object is not a function - * @exception JavaScriptException if an uncaught JavaScript exception - * occurred while executing the constructor - * @see org.mozilla.javascript.Function#construct - * @deprecated - */ - public Scriptable construct(Context cx, Object[] args) - throws NotAFunctionException, - JavaScriptException - { - if (!(obj instanceof Function)) { - throw new NotAFunctionException(); - } - return ScriptRuntime.newObject(cx, obj, args, null); - } - - /** - * Get the property indicated by the id, and invoke it with the - * specified arguments. - *

- * For example, for a FlattenedObject obj, - * and a Java array a consisting of a single string - * "hi", the call

-     * obj.callMethod("m", a)
- * is equivalent to the JavaScript code obj.m("hi").

- * - * If the property is not found or is not a function, an - * exception will be thrown. - * - * @param id the Number or String to use to find the function property - * to call - * @param args the arguments for the constructor call - * @return the result of the call - * @exception PropertyException if the designated property - * was not found - * @exception NotAFunctionException if this object is not a function - * @exception JavaScriptException if an uncaught JavaScript exception - * occurred while executing the method - * @see org.mozilla.javascript.Function#call - * @deprecated - */ - public Object callMethod(Object id, Object[] args) - throws PropertyException, - NotAFunctionException, - JavaScriptException - { - if (!hasProperty(id)) { - throw PropertyException.withMessage0("msg.prop.not.found"); - } - Object o = getProperty(id); - if (o instanceof FlattenedObject) - return ((FlattenedObject) o).call(Context.getContext(), obj, args); - throw new NotAFunctionException(); - } - - /****** End of API *******/ - - private static Scriptable getBase(Scriptable obj, String s) { - Scriptable m = obj; - while (m != null) { - if (m.has(s, obj)) - return m; - m = m.getPrototype(); - } - return null; - } - - private static Scriptable getBase(Scriptable obj, int index) { - Scriptable m = obj; - while (m != null) { - if (m.has(index, obj)) - return m; - m = m.getPrototype(); - } - return null; - } - - private Scriptable obj; -} - diff --git a/src/org/mozilla/javascript/Function.java b/src/org/mozilla/javascript/Function.java deleted file mode 100644 index c958d5b..0000000 --- a/src/org/mozilla/javascript/Function.java +++ /dev/null @@ -1,86 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -// API class - -package org.mozilla.javascript; - -/** - * This is interface that all functions in JavaScript must implement. - * The interface provides for calling functions and constructors. - * - * @see org.mozilla.javascript.Scriptable - * @author Norris Boyd - */ - -public interface Function extends Scriptable { - /** - * Call the function. - * - * Note that the array of arguments is not guaranteed to have - * length greater than 0. - * - * @param cx the current Context for this thread - * @param scope the scope to execute the function relative to. This is - * set to the value returned by getParentScope() except - * when the function is called from a closure. - * @param thisObj the JavaScript this object - * @param args the array of arguments - * @return the result of the call - * @exception JavaScriptException if an uncaught exception - * occurred while executing the function - */ - public Object call(Context cx, Scriptable scope, Scriptable thisObj, - Object[] args) - throws JavaScriptException; - - /** - * Call the function as a constructor. - * - * This method is invoked by the runtime in order to satisfy a use - * of the JavaScript new operator. This method is - * expected to create a new object and return it. - * - * @param cx the current Context for this thread - * @param scope an enclosing scope of the caller except - * when the function is called from a closure. - * @param args the array of arguments - * @return the allocated object - * @exception JavaScriptException if an uncaught exception - * occurred while executing the constructor - */ - public Scriptable construct(Context cx, Scriptable scope, Object[] args) - throws JavaScriptException; -} diff --git a/src/org/mozilla/javascript/FunctionNode.java b/src/org/mozilla/javascript/FunctionNode.java deleted file mode 100644 index 1584bc4..0000000 --- a/src/org/mozilla/javascript/FunctionNode.java +++ /dev/null @@ -1,103 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * Roger Lawrence - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -import java.util.*; - -public class FunctionNode extends Node { - - public FunctionNode(String name, Node left, Node right) { - super(TokenStream.FUNCTION, left, right, name); - itsVariableTable = new VariableTable(); - } - - public String getFunctionName() { - return getString(); - } - - public VariableTable getVariableTable() { - return itsVariableTable; - } - - public boolean requiresActivation() { - return itsNeedsActivation; - } - - public boolean setRequiresActivation(boolean b) { - return itsNeedsActivation = b; - } - - public boolean getCheckThis() { - return itsCheckThis; - } - - public void setCheckThis(boolean b) { - itsCheckThis = b; - } - - /** - * There are three types of functions that can be defined. The first - * is a function statement. This is a function appearing as a top-level - * statement (i.e., not nested inside some other statement) in either a - * script or a function. - * - * The second is a function expression, which is a function appearing in - * an expression except for the third type, which is... - * - * The third type is a function expression where the expression is the - * top-level expression in an expression statement. - * - * The three types of functions have different treatment and must be - * distinquished. - */ - public static final byte FUNCTION_STATEMENT = 1; - public static final byte FUNCTION_EXPRESSION = 2; - public static final byte FUNCTION_EXPRESSION_STATEMENT = 3; - - public byte getFunctionType() { - return itsFunctionType; - } - - public void setFunctionType(byte functionType) { - itsFunctionType = functionType; - } - - protected VariableTable itsVariableTable; - protected boolean itsNeedsActivation; - protected boolean itsCheckThis; - protected byte itsFunctionType; -} diff --git a/src/org/mozilla/javascript/FunctionObject.java b/src/org/mozilla/javascript/FunctionObject.java deleted file mode 100644 index 50a3e93..0000000 --- a/src/org/mozilla/javascript/FunctionObject.java +++ /dev/null @@ -1,626 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * Igor Bukanov - * David C. Navas - * Ted Neward - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -// API class - -package org.mozilla.javascript; - -import java.util.Vector; -import java.lang.reflect.Constructor; -import java.lang.reflect.Member; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.reflect.InvocationTargetException; - -public class FunctionObject extends NativeFunction { - - /** - * Create a JavaScript function object from a Java method. - * - *

The member argument must be either a java.lang.reflect.Method - * or a java.lang.reflect.Constructor and must match one of two forms.

- * - * The first form is a member with zero or more parameters - * of the following types: Object, String, boolean, Scriptable, - * byte, short, int, float, or double. The Long type is not supported - * because the double representation of a long (which is the - * EMCA-mandated storage type for Numbers) may lose precision. - * If the member is a Method, the return value must be void or one - * of the types allowed for parameters.

- * - * The runtime will perform appropriate conversions based - * upon the type of the parameter. A parameter type of - * Object specifies that no conversions are to be done. A parameter - * of type String will use Context.toString to convert arguments. - * Similarly, parameters of type double, boolean, and Scriptable - * will cause Context.toNumber, Context.toBoolean, and - * Context.toObject, respectively, to be called.

- * - * If the method is not static, the Java 'this' value will - * correspond to the JavaScript 'this' value. Any attempt - * to call the function with a 'this' value that is not - * of the right Java type will result in an error.

- * - * The second form is the variable arguments (or "varargs") - * form. If the FunctionObject will be used as a constructor, - * the member must have the following parameters - *

-     *      (Context cx, Object[] args, Function ctorObj,
-     *       boolean inNewExpr)
- * and if it is a Method, be static and return an Object result.

- * - * Otherwise, if the FunctionObject will not be used to define a - * constructor, the member must be a static Method with parameters - * (Context cx, Scriptable thisObj, Object[] args, - * Function funObj) - *

-     * and an Object result.

- * - * When the function varargs form is called as part of a function call, - * the args parameter contains the - * arguments, with thisObj - * set to the JavaScript 'this' value. funObj - * is the function object for the invoked function.

- * - * When the constructor varargs form is called or invoked while evaluating - * a new expression, args contains the - * arguments, ctorObj refers to this FunctionObject, and - * inNewExpr is true if and only if a new - * expression caused the call. This supports defining a function that - * has different behavior when called as a constructor than when - * invoked as a normal function call. (For example, the Boolean - * constructor, when called as a function, - * will convert to boolean rather than creating a new object.)

- * - * @param name the name of the function - * @param methodOrConstructor a java.lang.reflect.Method or a java.lang.reflect.Constructor - * that defines the object - * @param scope enclosing scope of function - * @see org.mozilla.javascript.Scriptable - */ - public FunctionObject(String name, Member methodOrConstructor, - Scriptable scope) - { - String methodName; - if (methodOrConstructor instanceof Constructor) { - ctor = (Constructor) methodOrConstructor; - isStatic = true; // well, doesn't take a 'this' - types = ctor.getParameterTypes(); - methodName = ctor.getName(); - } else { - method = (Method) methodOrConstructor; - isStatic = Modifier.isStatic(method.getModifiers()); - types = method.getParameterTypes(); - methodName = method.getName(); - } - this.functionName = name; - int length; - if (types.length == 4 && (types[1].isArray() || types[2].isArray())) { - // Either variable args or an error. - if (types[1].isArray()) { - if (!isStatic || - types[0] != Context.class || - types[1].getComponentType() != ScriptRuntime.ObjectClass || - types[2] != ScriptRuntime.FunctionClass || - types[3] != Boolean.TYPE) - { - throw Context.reportRuntimeError1( - "msg.varargs.ctor", methodName); - } - parmsLength = VARARGS_CTOR; - } else { - if (!isStatic || - types[0] != Context.class || - types[1] != ScriptRuntime.ScriptableClass || - types[2].getComponentType() != ScriptRuntime.ObjectClass || - types[3] != ScriptRuntime.FunctionClass) - { - throw Context.reportRuntimeError1( - "msg.varargs.fun", methodName); - } - parmsLength = VARARGS_METHOD; - } - // XXX check return type - length = 1; - } else { - parmsLength = (short) types.length; - for (int i=0; i < parmsLength; i++) { - Class type = types[i]; - if (type != ScriptRuntime.ObjectClass && - type != ScriptRuntime.StringClass && - type != ScriptRuntime.BooleanClass && - !ScriptRuntime.NumberClass.isAssignableFrom(type) && - !Scriptable.class.isAssignableFrom(type) && - type != Boolean.TYPE && - type != Byte.TYPE && - type != Short.TYPE && - type != Integer.TYPE && - type != Float.TYPE && - type != Double.TYPE) - { - // Note that long is not supported. - throw Context.reportRuntimeError1("msg.bad.parms", - methodName); - } - } - length = parmsLength; - } - - // Initialize length property - lengthPropertyValue = (short) length; - - hasVoidReturn = method != null && method.getReturnType() == Void.TYPE; - this.argCount = (short) length; - - setParentScope(scope); - setPrototype(getFunctionPrototype(scope)); - Context cx = Context.getCurrentContext(); - useDynamicScope = cx != null && - cx.hasCompileFunctionsWithDynamicScope(); - } - - /** - * Return the value defined by the method used to construct the object - * (number of parameters of the method, or 1 if the method is a "varargs" - * form), unless setLength has been called with a new value. - * Overrides getLength in BaseFunction. - * - * @see org.mozilla.javascript.FunctionObject#setLength - * @see org.mozilla.javascript.BaseFunction#getLength - */ - public int getLength() { - return lengthPropertyValue; - } - - /** - * Set the value of the "length" property. - * - *

Changing the value of the "length" property of a FunctionObject only - * affects the value retrieved from get() and does not affect the way - * the method itself is called.

- * - * The "length" property will be defined by default as the number - * of parameters of the method used to construct the FunctionObject, - * unless the method is a "varargs" form, in which case the "length" - * property will be defined to 1. - * - * @param length the new length - */ - public void setLength(short length) { - lengthPropertyValue = length; - } - - // TODO: Make not public - /** - * Finds methods of a given name in a given class. - * - *

Searches clazz for methods with name - * name. Maintains a cache so that multiple - * lookups on the same class are cheap. - * - * @param clazz the class to search - * @param name the name of the methods to find - * @return an array of the found methods, or null if no methods - * by that name were found. - * @see java.lang.Class#getMethods - */ - public static Method[] findMethods(Class clazz, String name) { - return findMethods(getMethodList(clazz), name); - } - - static Method[] findMethods(Method[] methods, String name) { - // Usually we're just looking for a single method, so optimize - // for that case. - Vector v = null; - Method first = null; - for (int i=0; i < methods.length; i++) { - if (methods[i] == null) - continue; - if (methods[i].getName().equals(name)) { - if (first == null) { - first = methods[i]; - } else { - if (v == null) { - v = new Vector(5); - v.addElement(first); - } - v.addElement(methods[i]); - } - } - } - if (v == null) { - if (first == null) - return null; - Method[] single = { first }; - return single; - } - Method[] result = new Method[v.size()]; - v.copyInto(result); - return result; - } - - static Method[] getMethodList(Class clazz) { - Method[] cached = methodsCache; // get once to avoid synchronization - if (cached != null && cached[0].getDeclaringClass() == clazz) - return cached; - Method[] methods = null; - try { - // getDeclaredMethods may be rejected by the security manager - // but getMethods is more expensive - if (!sawSecurityException) - methods = clazz.getDeclaredMethods(); - } catch (SecurityException e) { - // If we get an exception once, give up on getDeclaredMethods - sawSecurityException = true; - } - if (methods == null) { - methods = clazz.getMethods(); - } - int count = 0; - for (int i=0; i < methods.length; i++) { - if (sawSecurityException - ? methods[i].getDeclaringClass() != clazz - : !Modifier.isPublic(methods[i].getModifiers())) - { - methods[i] = null; - } else { - count++; - } - } - Method[] result = new Method[count]; - int j=0; - for (int i=0; i < methods.length; i++) { - if (methods[i] != null) - result[j++] = methods[i]; - } - if (result.length > 0 && Context.isCachingEnabled) - methodsCache = result; - return result; - } - - /** - * Define this function as a JavaScript constructor. - *

- * Sets up the "prototype" and "constructor" properties. Also - * calls setParent and setPrototype with appropriate values. - * Then adds the function object as a property of the given scope, using - * prototype.getClassName() - * as the name of the property. - * - * @param scope the scope in which to define the constructor (typically - * the global object) - * @param prototype the prototype object - * @see org.mozilla.javascript.Scriptable#setParentScope - * @see org.mozilla.javascript.Scriptable#setPrototype - * @see org.mozilla.javascript.Scriptable#getClassName - */ - public void addAsConstructor(Scriptable scope, Scriptable prototype) { - setParentScope(scope); - setPrototype(getFunctionPrototype(scope)); - setImmunePrototypeProperty(prototype); - - prototype.setParentScope(this); - - final int attr = ScriptableObject.DONTENUM | - ScriptableObject.PERMANENT | - ScriptableObject.READONLY; - defineProperty(prototype, "constructor", this, attr); - - String name = prototype.getClassName(); - defineProperty(scope, name, this, ScriptableObject.DONTENUM); - - setParentScope(scope); - } - - static public Object convertArg(Scriptable scope, - Object arg, Class desired) - { - if (desired == ScriptRuntime.StringClass) - return ScriptRuntime.toString(arg); - if (desired == ScriptRuntime.IntegerClass || - desired == Integer.TYPE) - { - return new Integer(ScriptRuntime.toInt32(arg)); - } - if (desired == ScriptRuntime.BooleanClass || - desired == Boolean.TYPE) - { - return ScriptRuntime.toBoolean(arg) ? Boolean.TRUE - : Boolean.FALSE; - } - if (desired == ScriptRuntime.DoubleClass || - desired == Double.TYPE) - { - return new Double(ScriptRuntime.toNumber(arg)); - } - if (desired == ScriptRuntime.ScriptableClass) - return ScriptRuntime.toObject(scope, arg); - if (desired == ScriptRuntime.ObjectClass) - return arg; - - // Note that the long type is not supported; see the javadoc for - // the constructor for this class - throw Context.reportRuntimeError1 - ("msg.cant.convert", desired.getName()); - } - - /** - * Performs conversions on argument types if needed and - * invokes the underlying Java method or constructor. - *

- * Implements Function.call. - * - * @see org.mozilla.javascript.Function#call - * @exception JavaScriptException if the underlying Java method or - * constructor threw an exception - */ - public Object call(Context cx, Scriptable scope, Scriptable thisObj, - Object[] args) - throws JavaScriptException - { - if (parmsLength < 0) { - return callVarargs(cx, thisObj, args, false); - } - if (!isStatic) { - // OPT: cache "clazz"? - Class clazz = method != null ? method.getDeclaringClass() - : ctor.getDeclaringClass(); - while (!clazz.isInstance(thisObj)) { - thisObj = thisObj.getPrototype(); - if (thisObj == null || !useDynamicScope) { - // Couldn't find an object to call this on. - throw NativeGlobal.typeError1 - ("msg.incompat.call", functionName, scope); - } - } - } - Object[] invokeArgs; - int i; - if (parmsLength == args.length) { - invokeArgs = args; - // avoid copy loop if no conversions needed - i = (types == null) ? parmsLength : 0; - } else { - invokeArgs = new Object[parmsLength]; - i = 0; - } - for (; i < parmsLength; i++) { - Object arg = (i < args.length) - ? args[i] - : Undefined.instance; - if (types != null) { - arg = convertArg(this, arg, types[i]); - } - invokeArgs[i] = arg; - } - try { - Object result = method == null ? ctor.newInstance(invokeArgs) - : doInvoke(thisObj, invokeArgs); - return hasVoidReturn ? Undefined.instance : result; - } - catch (InvocationTargetException e) { - throw JavaScriptException.wrapException(scope, e); - } - catch (IllegalAccessException e) { - throw WrappedException.wrapException(e); - } - catch (InstantiationException e) { - throw WrappedException.wrapException(e); - } - } - - /** - * Performs conversions on argument types if needed and - * invokes the underlying Java method or constructor - * to create a new Scriptable object. - *

- * Implements Function.construct. - * - * @param cx the current Context for this thread - * @param scope the scope to execute the function relative to. This - * set to the value returned by getParentScope() except - * when the function is called from a closure. - * @param args arguments to the constructor - * @see org.mozilla.javascript.Function#construct - * @exception JavaScriptException if the underlying Java method or constructor - * threw an exception - */ - public Scriptable construct(Context cx, Scriptable scope, Object[] args) - throws JavaScriptException - { - if (method == null || parmsLength == VARARGS_CTOR) { - Scriptable result; - if (method != null) { - result = (Scriptable) callVarargs(cx, null, args, true); - } else { - result = (Scriptable) call(cx, scope, null, args); - } - - if (result.getPrototype() == null) - result.setPrototype(getClassPrototype()); - if (result.getParentScope() == null) { - Scriptable parent = getParentScope(); - if (result != parent) - result.setParentScope(parent); - } - - return result; - } else if (method != null && !isStatic) { - Scriptable result; - try { - result = (Scriptable) method.getDeclaringClass().newInstance(); - } catch (IllegalAccessException e) { - throw WrappedException.wrapException(e); - } catch (InstantiationException e) { - throw WrappedException.wrapException(e); - } - - result.setPrototype(getClassPrototype()); - result.setParentScope(getParentScope()); - - Object val = call(cx, scope, result, args); - if (val != null && val != Undefined.instance && - val instanceof Scriptable) - { - return (Scriptable) val; - } - return result; - } - - return super.construct(cx, scope, args); - } - - private final Object doInvoke(Object thisObj, Object[] args) - throws IllegalAccessException, InvocationTargetException - { - Invoker master = invokerMaster; - if (master != null) { - if (invoker == null) { - invoker = master.createInvoker(method, types); - } - try { - return invoker.invoke(thisObj, args); - } catch (RuntimeException e) { - throw new InvocationTargetException(e); - } - } - return method.invoke(thisObj, args); - } - - private Object callVarargs(Context cx, Scriptable thisObj, Object[] args, - boolean inNewExpr) - throws JavaScriptException - { - try { - Object[] invokeArgs; - Object ret; - if (cx.arrayCache.size() > 0) invokeArgs = (Object[])cx.arrayCache.lastElement(); - else invokeArgs = new Object[4]; - - if (parmsLength == VARARGS_METHOD) { - invokeArgs[0] = cx; - invokeArgs[1] = thisObj; - invokeArgs[2] = args; - invokeArgs[3] = this; - Object result = doInvoke(null, invokeArgs); - ret = hasVoidReturn ? Undefined.instance : result; - } else { - Boolean b = inNewExpr ? Boolean.TRUE : Boolean.FALSE; - invokeArgs[0] = cx; - invokeArgs[1] = args; - invokeArgs[2] = this; - invokeArgs[3] = b; - ret = (method == null) - ? ctor.newInstance(invokeArgs) - : doInvoke(null, invokeArgs); - } - - cx.arrayCache.addElement(invokeArgs); - return ret; - } - catch (InvocationTargetException e) { - Throwable target = e.getTargetException(); - if (target instanceof EvaluatorException) - throw (EvaluatorException) target; - if (target instanceof EcmaError) - throw (EcmaError) target; - Scriptable scope = thisObj == null ? this : thisObj; - throw JavaScriptException.wrapException(scope, target); - } - catch (IllegalAccessException e) { - throw WrappedException.wrapException(e); - } - catch (InstantiationException e) { - throw WrappedException.wrapException(e); - } - } - - boolean isVarArgsMethod() { - return parmsLength == VARARGS_METHOD; - } - - boolean isVarArgsConstructor() { - return parmsLength == VARARGS_CTOR; - } - - static void setCachingEnabled(boolean enabled) { - if (!enabled) { - methodsCache = null; - invokerMaster = null; - } else if (invokerMaster == null) { - invokerMaster = newInvokerMaster(); - } - } - - /** Get default master implementation or null if not available */ - private static Invoker newInvokerMaster() { - /* - try { - Class cl = ScriptRuntime.loadClassName(INVOKER_MASTER_CLASS); - return (Invoker)cl.newInstance(); - } - catch (ClassNotFoundException ex) {} - catch (IllegalAccessException ex) {} - catch (InstantiationException ex) {} - catch (SecurityException ex) {} - */ - return null; - } - - private static final String - INVOKER_MASTER_CLASS = "org.mozilla.javascript.optimizer.InvokerImpl"; - - static Invoker invokerMaster = newInvokerMaster(); - - private static final short VARARGS_METHOD = -1; - private static final short VARARGS_CTOR = -2; - - private static boolean sawSecurityException; - - static Method[] methodsCache; - - Method method; - Constructor ctor; - private Class[] types; - Invoker invoker; - private short parmsLength; - private short lengthPropertyValue; - private boolean hasVoidReturn; - private boolean isStatic; - private boolean useDynamicScope; -} diff --git a/src/org/mozilla/javascript/IRFactory.java b/src/org/mozilla/javascript/IRFactory.java deleted file mode 100644 index 948ac10..0000000 --- a/src/org/mozilla/javascript/IRFactory.java +++ /dev/null @@ -1,1065 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -/** - * This class allows the creation of nodes, and follows the Factory pattern. - * - * @see Node - * @author Mike McCabe - * @author Norris Boyd - */ -public class IRFactory { - - public IRFactory(TokenStream ts, Scriptable scope) { - this.ts = ts; - this.scope = scope; - } - - /** - * Script (for associating file/url names with toplevel scripts.) - */ - public Object createScript(Object body, String sourceName, - int baseLineno, int endLineno, Object source) - { - Node result = new Node(TokenStream.SCRIPT, sourceName); - Node children = ((Node) body).getFirstChild(); - if (children != null) - result.addChildrenToBack(children); - result.putProp(Node.SOURCENAME_PROP, sourceName); - result.putProp(Node.BASE_LINENO_PROP, new Integer(baseLineno)); - result.putProp(Node.END_LINENO_PROP, new Integer(endLineno)); - if (source != null) - result.putProp(Node.SOURCE_PROP, source); - return result; - } - - /** - * Leaf - */ - public Object createLeaf(int nodeType) { - return new Node(nodeType); - } - - public Object createLeaf(int nodeType, String id) { - return new Node(nodeType, id); - } - - public Object createLeaf(int nodeType, int nodeOp) { - return new Node(nodeType, new Integer(nodeOp)); - } - - /** - * Statement leaf nodes. - */ - - public Object createSwitch(int lineno) { - return new Node(TokenStream.SWITCH, new Integer(lineno)); - } - - public Object createVariables(int lineno) { - return new Node(TokenStream.VAR, new Integer(lineno)); - } - - public Object createExprStatement(Object expr, int lineno) { - return new Node(TokenStream.EXPRSTMT, (Node) expr, new Integer(lineno)); - } - - /** - * Name - */ - public Object createName(String name) { - return new Node(TokenStream.NAME, name); - } - - /** - * String (for literals) - */ - public Object createString(String string) { - return new Node(TokenStream.STRING, string); - } - - /** - * Number (for literals) - */ - public Object createNumber(Number number) { - return new Node(TokenStream.NUMBER, number); - } - - /** - * Catch clause of try/catch/finally - * @param varName the name of the variable to bind to the exception - * @param catchCond the condition under which to catch the exception. - * May be null if no condition is given. - * @param stmts the statements in the catch clause - * @param lineno the starting line number of the catch clause - */ - public Object createCatch(String varName, Object catchCond, Object stmts, - int lineno) - { - if (catchCond == null) - catchCond = new Node(TokenStream.PRIMARY, - new Integer(TokenStream.TRUE)); - Node result = new Node(TokenStream.CATCH, (Node)createName(varName), - (Node)catchCond, (Node)stmts); - result.setDatum(new Integer(lineno)); - return result; - } - - /** - * Throw - */ - public Object createThrow(Object expr, int lineno) { - return new Node(TokenStream.THROW, (Node)expr, new Integer(lineno)); - } - - /** - * Return - */ - public Object createReturn(Object expr, int lineno) { - return expr == null - ? new Node(TokenStream.RETURN, new Integer(lineno)) - : new Node(TokenStream.RETURN, (Node)expr, new Integer(lineno)); - } - - /** - * Assert - */ - public Object createAssert(Object expr, int lineno) { - return expr == null - ? new Node(TokenStream.ASSERT, new Integer(lineno)) - : new Node(TokenStream.ASSERT, (Node)expr, new Integer(lineno)); - } - - /** - * Label - */ - public Object createLabel(String label, int lineno) { - Node result = new Node(TokenStream.LABEL, new Integer(lineno)); - Node name = new Node(TokenStream.NAME, label); - result.addChildToBack(name); - return result; - } - - /** - * Break (possibly labeled) - */ - public Object createBreak(String label, int lineno) { - Node result = new Node(TokenStream.BREAK, new Integer(lineno)); - if (label == null) { - return result; - } else { - Node name = new Node(TokenStream.NAME, label); - result.addChildToBack(name); - return result; - } - } - - /** - * Continue (possibly labeled) - */ - public Object createContinue(String label, int lineno) { - Node result = new Node(TokenStream.CONTINUE, new Integer(lineno)); - if (label == null) { - return result; - } else { - Node name = new Node(TokenStream.NAME, label); - result.addChildToBack(name); - return result; - } - } - - /** - * Statement block - * Creates the empty statement block - * Must make subsequent calls to add statements to the node - */ - public Object createBlock(int lineno) { - return new Node(TokenStream.BLOCK, new Integer(lineno)); - } - - public Object createFunctionNode(String name, Object args, - Object statements) - { - if (name == null) - name = ""; - return new FunctionNode(name, (Node) args, (Node) statements); - } - - public Object createFunction(String name, Object args, Object statements, - String sourceName, int baseLineno, - int endLineno, Object source, - boolean isExpr) - { - FunctionNode f = (FunctionNode) createFunctionNode(name, args, - statements); - f.setFunctionType(isExpr ? FunctionNode.FUNCTION_EXPRESSION - : FunctionNode.FUNCTION_STATEMENT); - f.putProp(Node.SOURCENAME_PROP, sourceName); - f.putProp(Node.BASE_LINENO_PROP, new Integer(baseLineno)); - f.putProp(Node.END_LINENO_PROP, new Integer(endLineno)); - if (source != null) - f.putProp(Node.SOURCE_PROP, source); - Node result = new Node(TokenStream.FUNCTION, name); - result.putProp(Node.FUNCTION_PROP, f); - return result; - } - - public void setFunctionExpressionStatement(Object o) { - Node n = (Node) o; - FunctionNode f = (FunctionNode) n.getProp(Node.FUNCTION_PROP); - f.setFunctionType(FunctionNode.FUNCTION_EXPRESSION_STATEMENT); - } - - /** - * Add a child to the back of the given node. This function - * breaks the Factory abstraction, but it removes a requirement - * from implementors of Node. - */ - public void addChildToBack(Object parent, Object child) { - ((Node)parent).addChildToBack((Node)child); - } - - /** - * While - */ - public Object createWhile(Object cond, Object body, int lineno) { - // Just add a GOTO to the condition in the do..while - Node result = (Node) createDoWhile(body, cond, lineno); - Node condTarget = (Node) result.getProp(Node.CONTINUE_PROP); - Node GOTO = new Node(TokenStream.GOTO); - GOTO.putProp(Node.TARGET_PROP, condTarget); - result.addChildToFront(GOTO); - return result; - } - - /** - * DoWhile - */ - public Object createDoWhile(Object body, Object cond, int lineno) { - Node result = new Node(TokenStream.LOOP, new Integer(lineno)); - Node bodyTarget = new Node(TokenStream.TARGET); - Node condTarget = new Node(TokenStream.TARGET); - Node IFEQ = new Node(TokenStream.IFEQ, (Node)cond); - IFEQ.putProp(Node.TARGET_PROP, bodyTarget); - Node breakTarget = new Node(TokenStream.TARGET); - - result.addChildToBack(bodyTarget); - result.addChildrenToBack((Node)body); - result.addChildToBack(condTarget); - result.addChildToBack(IFEQ); - result.addChildToBack(breakTarget); - - result.putProp(Node.BREAK_PROP, breakTarget); - result.putProp(Node.CONTINUE_PROP, condTarget); - - return result; - } - - /** - * For - */ - public Object createFor(Object init, Object test, Object incr, - Object body, int lineno) - { - if (((Node) test).getType() == TokenStream.VOID) { - test = new Node(TokenStream.PRIMARY, - new Integer(TokenStream.TRUE)); - } - Node result = (Node)createWhile(test, body, lineno); - Node initNode = (Node) init; - if (initNode.getType() != TokenStream.VOID) { - if (initNode.getType() != TokenStream.VAR) - initNode = new Node(TokenStream.POP, initNode); - result.addChildToFront(initNode); - } - Node condTarget = (Node)result.getProp(Node.CONTINUE_PROP); - Node incrTarget = new Node(TokenStream.TARGET); - result.addChildBefore(incrTarget, condTarget); - if (((Node) incr).getType() != TokenStream.VOID) { - incr = createUnary(TokenStream.POP, incr); - result.addChildAfter((Node)incr, incrTarget); - } - result.putProp(Node.CONTINUE_PROP, incrTarget); - return result; - } - - /** - * For .. In - * - */ - public Object createForIn(Object lhs, Object obj, Object body, int lineno) { - String name; - Node lhsNode = (Node) lhs; - Node objNode = (Node) obj; - int type = lhsNode.getType(); - - Node lvalue = lhsNode; - switch (type) { - - case TokenStream.NAME: - case TokenStream.GETPROP: - case TokenStream.GETELEM: - break; - - case TokenStream.VAR: - /* - * check that there was only one variable given. - * we can't do this in the parser, because then the - * parser would have to know something about the - * 'init' node of the for-in loop. - */ - Node lastChild = lhsNode.getLastChild(); - if (lhsNode.getFirstChild() != lastChild) { - reportError("msg.mult.index"); - } - lvalue = new Node(TokenStream.NAME, lastChild.getString()); - break; - - default: - reportError("msg.bad.for.in.lhs"); - return objNode; - } - - Node init = new Node(TokenStream.ENUMINIT, objNode); - Node next = new Node(TokenStream.ENUMNEXT); - next.putProp(Node.ENUM_PROP, init); - Node temp = createNewTemp(next); - Node cond = new Node(TokenStream.EQOP, new Integer(TokenStream.NE)); - cond.addChildToBack(temp); - cond.addChildToBack(new Node(TokenStream.PRIMARY, - new Integer(TokenStream.NULL))); - Node newBody = new Node(TokenStream.BLOCK); - Node assign = (Node) createAssignment(TokenStream.NOP, lvalue, - createUseTemp(temp), null, - false); - newBody.addChildToBack(new Node(TokenStream.POP, assign)); - newBody.addChildToBack((Node) body); - Node result = (Node) createWhile(cond, newBody, lineno); - - result.addChildToFront(init); - if (type == TokenStream.VAR) - result.addChildToFront(lhsNode); - - Node done = new Node(TokenStream.ENUMDONE); - done.putProp(Node.ENUM_PROP, init); - result.addChildToBack(done); - - return result; - } - - /** - * Try/Catch/Finally - * - * The IRFactory tries to express as much as possible in the tree; - * the responsibilities remaining for Codegen are to add the Java - * handlers: (Either (but not both) of TARGET and FINALLY might not - * be defined) - - * - a catch handler for javascript exceptions that unwraps the - * exception onto the stack and GOTOes to the catch target - - * TARGET_PROP in the try node. - - * - a finally handler that catches any exception, stores it to a - * temporary, and JSRs to the finally target - FINALLY_PROP in the - * try node - before re-throwing the exception. - - * ... and a goto to GOTO around these handlers. - */ - public Object createTryCatchFinally(Object tryblock, Object catchblocks, - Object finallyblock, int lineno) - { - Node trynode = (Node)tryblock; - - // short circuit - if (trynode.getType() == TokenStream.BLOCK && !trynode.hasChildren()) - return trynode; - - Node pn = new Node(TokenStream.TRY, trynode, new Integer(lineno)); - Node catchNodes = (Node)catchblocks; - boolean hasCatch = catchNodes.hasChildren(); - boolean hasFinally = false; - Node finallyNode = null; - Node finallyTarget = null; - if (finallyblock != null) { - finallyNode = (Node)finallyblock; - hasFinally = (finallyNode.getType() != TokenStream.BLOCK - || finallyNode.hasChildren()); - if (hasFinally) { - // make a TARGET for the finally that the tcf node knows about - finallyTarget = new Node(TokenStream.TARGET); - pn.putProp(Node.FINALLY_PROP, finallyTarget); - - // add jsr finally to the try block - Node jsrFinally = new Node(TokenStream.JSR); - jsrFinally.putProp(Node.TARGET_PROP, finallyTarget); - pn.addChildToBack(jsrFinally); - } - } - - // short circuit - if (!hasFinally && !hasCatch) // bc finally might be an empty block... - return trynode; - - Node endTarget = new Node(TokenStream.TARGET); - Node GOTOToEnd = new Node(TokenStream.GOTO); - GOTOToEnd.putProp(Node.TARGET_PROP, endTarget); - pn.addChildToBack(GOTOToEnd); - - if (hasCatch) { - /* - * - Given - - try { - throw 3; - } catch (e: e instanceof Object) { - print("object"); - } catch (e2) { - print(e2); - } - - rewrite as - - try { - throw 3; - } catch (x) { - o = newScope(); - o.e = x; - with (o) { - if (e instanceof Object) { - print("object"); - } - } - o2 = newScope(); - o2.e2 = x; - with (o2) { - if (true) { - print(e2); - } - } - } - */ - // make a TARGET for the catch that the tcf node knows about - Node catchTarget = new Node(TokenStream.TARGET); - pn.putProp(Node.TARGET_PROP, catchTarget); - // mark it - pn.addChildToBack(catchTarget); - - // get the exception object and store it in a temp - Node exn = createNewLocal(new Node(TokenStream.VOID)); - pn.addChildToBack(new Node(TokenStream.POP, exn)); - - Node endCatch = new Node(TokenStream.TARGET); - - // add [jsr finally?] goto end to each catch block - // expects catchNode children to be (cond block) pairs. - Node cb = catchNodes.getFirstChild(); - while (cb != null) { - Node catchStmt = new Node(TokenStream.BLOCK); - int catchLineNo = ((Integer)cb.getDatum()).intValue(); - - Node name = cb.getFirstChild(); - Node cond = name.getNextSibling(); - Node catchBlock = cond.getNextSibling(); - cb.removeChild(name); - cb.removeChild(cond); - cb.removeChild(catchBlock); - - Node newScope = createNewLocal(new Node(TokenStream.NEWSCOPE)); - Node initScope = new Node(TokenStream.SETPROP, newScope, - new Node(TokenStream.STRING, - name.getString()), - createUseLocal(exn)); - catchStmt.addChildToBack(new Node(TokenStream.POP, initScope)); - - catchBlock.addChildToBack(new Node(TokenStream.LEAVEWITH)); - Node GOTOToEndCatch = new Node(TokenStream.GOTO); - GOTOToEndCatch.putProp(Node.TARGET_PROP, endCatch); - catchBlock.addChildToBack(GOTOToEndCatch); - - Node ifStmt = (Node) createIf(cond, catchBlock, null, catchLineNo); - // Try..catch produces "with" code in order to limit - // the scope of the exception object. - // OPT: We should be able to figure out the correct - // scoping at compile-time and avoid the - // runtime overhead. - Node withStmt = (Node) createWith(createUseLocal(newScope), - ifStmt, catchLineNo); - catchStmt.addChildToBack(withStmt); - - pn.addChildToBack(catchStmt); - - // move to next cb - cb = cb.getNextSibling(); - } - - // Generate code to rethrow if no catch clause was executed - Node rethrow = new Node(TokenStream.THROW, createUseLocal(exn)); - pn.addChildToBack(rethrow); - - pn.addChildToBack(endCatch); - // add a JSR finally if needed - if (hasFinally) { - Node jsrFinally = new Node(TokenStream.JSR); - jsrFinally.putProp(Node.TARGET_PROP, finallyTarget); - pn.addChildToBack(jsrFinally); - Node GOTO = new Node(TokenStream.GOTO); - GOTO.putProp(Node.TARGET_PROP, endTarget); - pn.addChildToBack(GOTO); - } - } - - if (hasFinally) { - pn.addChildToBack(finallyTarget); - Node returnTemp = createNewLocal(new Node(TokenStream.VOID)); - Node popAndMake = new Node(TokenStream.POP, returnTemp); - pn.addChildToBack(popAndMake); - pn.addChildToBack(finallyNode); - Node ret = createUseLocal(returnTemp); - - // add the magic prop that makes it output a RET - ret.putProp(Node.TARGET_PROP, Boolean.TRUE); - pn.addChildToBack(ret); - } - pn.addChildToBack(endTarget); - return pn; - } - - /** - * Throw, Return, Label, Break and Continue are defined in ASTFactory. - */ - - /** - * With - */ - public Object createWith(Object obj, Object body, int lineno) { - Node result = new Node(TokenStream.BLOCK, new Integer(lineno)); - result.addChildToBack(new Node(TokenStream.ENTERWITH, (Node)obj)); - Node bodyNode = new Node(TokenStream.WITH, (Node) body, - new Integer(lineno)); - result.addChildrenToBack(bodyNode); - result.addChildToBack(new Node(TokenStream.LEAVEWITH)); - return result; - } - - /** - * Array Literal - *
createArrayLiteral rewrites its argument as array creation - * plus a series of array element entries, so later compiler - * stages don't need to know about array literals. - */ - public Object createArrayLiteral(Object obj) { - Node array; - Node result; - array = result = new Node(TokenStream.NEW, - new Node(TokenStream.NAME, "Array")); - Node temp = createNewTemp(result); - result = temp; - - java.util.Enumeration children = ((Node) obj).getChildIterator(); - - Node elem = null; - int i = 0; - while (children.hasMoreElements()) { - elem = (Node) children.nextElement(); - if (elem.getType() == TokenStream.PRIMARY && - elem.getInt() == TokenStream.UNDEFINED) - { - i++; - continue; - } - Node addelem = new Node(TokenStream.SETELEM, createUseTemp(temp), - new Node(TokenStream.NUMBER, - new Integer(i)), - elem); - i++; - result = new Node(TokenStream.COMMA, result, addelem); - } - - /* - * If the version is 120, then new Array(4) means create a new - * array with 4 as the first element. In this case, we might - * need to explicitly check against trailing undefined - * elements in the array literal, and set the length manually - * if these occur. Otherwise, we can add an argument to the - * node specifying new Array() to provide the array length. - * (Which will make Array optimizations involving allocating a - * Java array to back the javascript array work better.) - */ - if (Context.getContext().getLanguageVersion() == Context.VERSION_1_2) { - /* When last array element is empty, we need to set the - * length explicitly, because we can't depend on SETELEM - * to do it for us - because empty [,,] array elements - * never set anything at all. */ - if (elem != null && - elem.getType() == TokenStream.PRIMARY && - elem.getInt() == TokenStream.UNDEFINED) - { - Node setlength = new Node(TokenStream.SETPROP, - createUseTemp(temp), - new Node(TokenStream.STRING, - "length"), - new Node(TokenStream.NUMBER, - new Integer(i))); - result = new Node(TokenStream.COMMA, result, setlength); - } - } else { - array.addChildToBack(new Node(TokenStream.NUMBER, - new Integer(i))); - } - return new Node(TokenStream.COMMA, result, createUseTemp(temp)); - } - - /** - * Object Literals - *
createObjectLiteral rewrites its argument as object - * creation plus object property entries, so later compiler - * stages don't need to know about object literals. - */ - public Object createObjectLiteral(Object obj) { - Node result = new Node(TokenStream.NEW, new Node(TokenStream.NAME, - "Object")); - Node temp = createNewTemp(result); - result = temp; - - java.util.Enumeration children = ((Node) obj).getChildIterator(); - - while (children.hasMoreElements()) { - Node elem = (Node)children.nextElement(); - - int op = (elem.getType() == TokenStream.NAME) - ? TokenStream.SETPROP - : TokenStream.SETELEM; - Node addelem = new Node(op, createUseTemp(temp), - elem, (Node)children.nextElement()); - result = new Node(TokenStream.COMMA, result, addelem); - } - return new Node(TokenStream.COMMA, result, createUseTemp(temp)); - } - - /** - * Regular expressions - */ - public Object createRegExp(String string, String flags) { - return flags.length() == 0 - ? new Node(TokenStream.OBJECT, - new Node(TokenStream.STRING, string)) - : new Node(TokenStream.OBJECT, - new Node(TokenStream.STRING, string), - new Node(TokenStream.STRING, flags)); - } - - /** - * If statement - */ - public Object createIf(Object cond, Object ifTrue, Object ifFalse, - int lineno) - { - Node result = new Node(TokenStream.BLOCK, new Integer(lineno)); - Node ifNotTarget = new Node(TokenStream.TARGET); - Node IFNE = new Node(TokenStream.IFNE, (Node) cond); - IFNE.putProp(Node.TARGET_PROP, ifNotTarget); - - result.addChildToBack(IFNE); - result.addChildrenToBack((Node)ifTrue); - - if (ifFalse != null) { - Node GOTOToEnd = new Node(TokenStream.GOTO); - Node endTarget = new Node(TokenStream.TARGET); - GOTOToEnd.putProp(Node.TARGET_PROP, endTarget); - result.addChildToBack(GOTOToEnd); - result.addChildToBack(ifNotTarget); - result.addChildrenToBack((Node)ifFalse); - result.addChildToBack(endTarget); - } else { - result.addChildToBack(ifNotTarget); - } - - return result; - } - - public Object createTernary(Object cond, Object ifTrue, Object ifFalse) { - return createIf(cond, ifTrue, ifFalse, -1); - } - - /** - * Unary - */ - public Object createUnary(int nodeType, Object child) { - Node childNode = (Node) child; - if (nodeType == TokenStream.DELPROP) { - int childType = childNode.getType(); - Node left; - Node right; - if (childType == TokenStream.NAME) { - // Transform Delete(Name "a") - // to Delete(Bind("a"), String("a")) - childNode.setType(TokenStream.BINDNAME); - left = childNode; - right = childNode.cloneNode(); - right.setType(TokenStream.STRING); - } else if (childType == TokenStream.GETPROP || - childType == TokenStream.GETELEM) - { - left = childNode.getFirstChild(); - right = childNode.getLastChild(); - childNode.removeChild(left); - childNode.removeChild(right); - } else { - return new Node(TokenStream.PRIMARY, - new Integer(TokenStream.TRUE)); - } - return new Node(nodeType, left, right); - } - return new Node(nodeType, childNode); - } - - public Object createUnary(int nodeType, int nodeOp, Object child) { - Node childNode = (Node) child; - int childType = childNode.getType(); - if (nodeOp == TokenStream.TYPEOF && - childType == TokenStream.NAME) - { - childNode.setType(TokenStream.TYPEOF); - return childNode; - } - - if (nodeType == TokenStream.INC || nodeType == TokenStream.DEC) { - - if (!hasSideEffects(childNode) - && (nodeOp == TokenStream.POST) - && (childType == TokenStream.NAME - || childType == TokenStream.GETPROP - || childType == TokenStream.GETELEM)) - { - // if it's not a LHS type, createAssignment (below) will throw - // an exception. - return new Node(nodeType, childNode); - } - - /* - * Transform INC/DEC ops to +=1, -=1, - * expecting later optimization of all +/-=1 cases to INC, DEC. - */ - // we have to use Double for now, because - // 0.0 and 1.0 are stored as dconst_[01], - // and using a Float creates a stack mismatch. - Node rhs = (Node) createNumber(new Double(1.0)); - - return createAssignment(nodeType == TokenStream.INC - ? TokenStream.ADD - : TokenStream.SUB, - childNode, - rhs, - ScriptRuntime.NumberClass, - nodeOp == TokenStream.POST); - } - - Node result = new Node(nodeType, new Integer(nodeOp)); - result.addChildToBack((Node)child); - return result; - } - - /** - * Binary - */ - public Object createBinary(int nodeType, Object left, Object right) { - Node temp; - switch (nodeType) { - - case TokenStream.DOT: - nodeType = TokenStream.GETPROP; - Node idNode = (Node) right; - idNode.setType(TokenStream.STRING); - String id = idNode.getString(); - if (id.equals("__proto__") || id.equals("__parent__")) { - Node result = new Node(nodeType, (Node) left); - result.putProp(Node.SPECIAL_PROP_PROP, id); - return result; - } - break; - - case TokenStream.LB: - // OPT: could optimize to GETPROP iff string can't be a number - nodeType = TokenStream.GETELEM; - break; -/* - case TokenStream.AND: - temp = createNewTemp((Node) left); - return createTernary(temp, right, createUseTemp(temp)); - - case TokenStream.OR: - temp = createNewTemp((Node) left); - return createTernary(temp, createUseTemp(temp), right); -*/ - } - return new Node(nodeType, (Node)left, (Node)right); - } - - public Object createBinary(int nodeType, int nodeOp, Object left, - Object right) - { - if (nodeType == TokenStream.ASSIGN) { - return createAssignment(nodeOp, (Node) left, (Node) right, - null, false); - } - return new Node(nodeType, (Node) left, (Node) right, - new Integer(nodeOp)); - } - - public Object createAssignment(int nodeOp, Node left, Node right, - Class convert, boolean postfix) - { - int nodeType = left.getType(); - String idString; - Node id = null; - switch (nodeType) { - case TokenStream.NAME: - return createSetName(nodeOp, left, right, convert, postfix); - - case TokenStream.GETPROP: - idString = (String) left.getProp(Node.SPECIAL_PROP_PROP); - if (idString != null) - id = new Node(TokenStream.STRING, idString); - /* fall through */ - case TokenStream.GETELEM: - if (id == null) - id = left.getLastChild(); - return createSetProp(nodeType, nodeOp, left.getFirstChild(), - id, right, convert, postfix); - default: - // TODO: This should be a ReferenceError--but that's a runtime - // exception. Should we compile an exception into the code? - reportError("msg.bad.lhs.assign"); - return left; - } - } - - private Node createConvert(Class toType, Node expr) { - if (toType == null) - return expr; - Node result = new Node(TokenStream.CONVERT, expr); - result.putProp(Node.TYPE_PROP, ScriptRuntime.NumberClass); - return result; - } - - private Object createSetName(int nodeOp, Node left, Node right, - Class convert, boolean postfix) - { - if (nodeOp == TokenStream.NOP) { - left.setType(TokenStream.BINDNAME); - return new Node(TokenStream.SETNAME, left, right); - } - - String s = left.getString(); - - if (s.equals("__proto__") || s.equals("__parent__")) { - Node result = new Node(TokenStream.SETPROP, left, right); - result.putProp(Node.SPECIAL_PROP_PROP, s); - return result; - } - - Node opLeft = new Node(TokenStream.NAME, s); - if (convert != null) - opLeft = createConvert(convert, opLeft); - if (postfix) - opLeft = createNewTemp(opLeft); - Node op = new Node(nodeOp, opLeft, right); - - Node lvalueLeft = new Node(TokenStream.BINDNAME, s); - Node result = new Node(TokenStream.SETNAME, lvalueLeft, op); - if (postfix) { - result = new Node(TokenStream.COMMA, result, - createUseTemp(opLeft)); - } - return result; - } - - public Node createNewTemp(Node n) { - int type = n.getType(); - if (type == TokenStream.STRING || type == TokenStream.NUMBER) { - // Optimization: clone these values rather than storing - // and loading from a temp - return n; - } - Node result = new Node(TokenStream.NEWTEMP, n); - return result; - } - - public Node createUseTemp(Node newTemp) { - int type = newTemp.getType(); - if (type == TokenStream.NEWTEMP) { - Node result = new Node(TokenStream.USETEMP); - result.putProp(Node.TEMP_PROP, newTemp); - Integer n = (Integer) newTemp.getProp(Node.USES_PROP); - if (n == null) { - n = new Integer(1); - } else { - if (n.intValue() < Integer.MAX_VALUE) - n = new Integer(n.intValue() + 1); - } - newTemp.putProp(Node.USES_PROP, n); - return result; - } - return newTemp.cloneNode(); - } - - public Node createNewLocal(Node n) { - Node result = new Node(TokenStream.NEWLOCAL, n); - return result; - } - - public Node createUseLocal(Node newLocal) { - int type = newLocal.getType(); - if (type == TokenStream.NEWLOCAL) { - Node result = new Node(TokenStream.USELOCAL); - result.putProp(Node.LOCAL_PROP, newLocal); - return result; - } - return newLocal.cloneNode(); // what's this path for ? - } - - public static boolean hasSideEffects(Node exprTree) { - switch (exprTree.getType()) { - case TokenStream.INC: - case TokenStream.DEC: - case TokenStream.SETPROP: - case TokenStream.SETELEM: - case TokenStream.SETNAME: - case TokenStream.CALL: - case TokenStream.NEW: - return true; - default: - Node child = exprTree.getFirstChild(); - while (child != null) { - if (hasSideEffects(child)) - return true; - else - child = child.getNextSibling(); - } - break; - } - return false; - } - - private Node createSetProp(int nodeType, int nodeOp, Node obj, Node id, - Node expr, Class convert, boolean postfix) - { - int type = nodeType == TokenStream.GETPROP - ? TokenStream.SETPROP - : TokenStream.SETELEM; - - Object datum = id.getDatum(); - if (type == TokenStream.SETPROP && datum != null && - datum instanceof String) - { - String s = (String) datum; - if (s.equals("__proto__") || s.equals("__parent__")) { - Node result = new Node(type, obj, expr); - result.putProp(Node.SPECIAL_PROP_PROP, s); - return result; - } - } - - if (nodeOp == TokenStream.NOP) - return new Node(type, obj, id, expr); -/* -* If the RHS expression could modify the LHS we have -* to construct a temporary to hold the LHS context -* prior to running the expression. Ditto, if the id -* expression has side-effects. -* -* XXX If the hasSideEffects tests take too long, we -* could make this an optimizer-only transform -* and always do the temp assignment otherwise. -* -*/ - Node tmp1, tmp2, opLeft; - if (hasSideEffects(expr) - || hasSideEffects(id) - || (obj.getType() != TokenStream.NAME)) { - tmp1 = createNewTemp(obj); - Node useTmp1 = createUseTemp(tmp1); - - tmp2 = createNewTemp(id); - Node useTmp2 = createUseTemp(tmp2); - - opLeft = new Node(nodeType, useTmp1, useTmp2); - } else { - tmp1 = obj.cloneNode(); - tmp2 = id.cloneNode(); - opLeft = new Node(nodeType, obj, id); - } - - if (convert != null) - opLeft = createConvert(convert, opLeft); - if (postfix) - opLeft = createNewTemp(opLeft); - Node op = new Node(nodeOp, opLeft, expr); - - Node result = new Node(type, tmp1, tmp2, op); - if (postfix) { - result = new Node(TokenStream.COMMA, result, - createUseTemp(opLeft)); - } - - return result; - } - - private void reportError(String msgResource) { - - if (scope != null) - throw NativeGlobal.constructError( - Context.getContext(), "SyntaxError", - ScriptRuntime.getMessage0(msgResource), - scope); - else { - String message = Context.getMessage0(msgResource); - Context.reportError(message, ts.getSourceName(), ts.getLineno(), - ts.getLine(), ts.getOffset()); - } - } - - // Only needed to get file/line information. Could create an interface - // that TokenStream implements if we want to make the connection less - // direct. - private TokenStream ts; - - // Only needed to pass to the Erorr exception constructors - private Scriptable scope; -} - diff --git a/src/org/mozilla/javascript/IdFunction.java b/src/org/mozilla/javascript/IdFunction.java deleted file mode 100644 index ec5dc3e..0000000 --- a/src/org/mozilla/javascript/IdFunction.java +++ /dev/null @@ -1,164 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Igor Bukanov - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -// API class - -package org.mozilla.javascript; - -public class IdFunction extends BaseFunction -{ - public static final int FUNCTION_ONLY = 0; - - public static final int CONSTRUCTOR_ONLY = 1; - - public static final int FUNCTION_AND_CONSTRUCTOR = 2; - - public IdFunction(IdFunctionMaster master, String name, int id) { - this.functionName = name; - this.master = master; - this.methodId = id; - } - - public final int functionType() { - return functionType; - } - - public void setFunctionType(int type) { - functionType = type; - } - - public Scriptable getPrototype() { - // Lazy initialization of prototype: for native functions this - // may not be called at all - Scriptable proto = super.getPrototype(); - if (proto == null) { - proto = getFunctionPrototype(getParentScope()); - setPrototype(proto); - } - return proto; - } - - public Object call(Context cx, Scriptable scope, Scriptable thisObj, - Object[] args) - throws JavaScriptException - { - if (functionType != CONSTRUCTOR_ONLY) { - return master.execMethod(methodId, this, cx, scope, thisObj, args); - } - else { - return Undefined.instance; - } - } - - public Scriptable construct(Context cx, Scriptable scope, Object[] args) - throws JavaScriptException - { - if (functionType != FUNCTION_ONLY) { - // It is program error not to return Scriptable from constructor - Scriptable result = (Scriptable)master.execMethod(methodId, this, - cx, scope, - null, args); - postConstruction(result); - return result; - } - else { - return Undefined.instance; - } - } - - public String decompile(Context cx, int indent, boolean justbody) { - StringBuffer sb = new StringBuffer(); - if (!justbody) { - sb.append("function "); - sb.append(getFunctionName()); - sb.append("() { "); - } - sb.append("[native code for "); - if (master instanceof Scriptable) { - Scriptable smaster = (Scriptable)master; - sb.append(smaster.getClassName()); - sb.append('.'); - } - sb.append(getFunctionName()); - sb.append(", arity="); - sb.append(getArity()); - sb.append(justbody ? "]\n" : "] }\n"); - return sb.toString(); - } - - public int getArity() { - int arity = master.methodArity(methodId); - if (arity < 0) { - throw onBadMethodId(master, methodId); - } - return arity; - } - - public int getLength() { return getArity(); } - - /** Prepare to be used as constructor . - ** @param scope constructor scope - ** @param prototype DontEnum, DontDelete, ReadOnly prototype property - ** of the constructor */ - public void initAsConstructor(Scriptable scope, Scriptable prototype) { - setFunctionType(FUNCTION_AND_CONSTRUCTOR); - setParentScope(scope); - setImmunePrototypeProperty(prototype); - } - - static RuntimeException onBadMethodId(IdFunctionMaster master, int id) { - // It is program error to call id-like methods for unknown or - // non-function id - return new RuntimeException("BAD FUNCTION ID="+id+" MASTER="+master); - } - - // Copied from NativeFunction.construct - private void postConstruction(Scriptable newObj) { - if (newObj.getPrototype() == null) { - newObj.setPrototype(getClassPrototype()); - } - if (newObj.getParentScope() == null) { - Scriptable parent = getParentScope(); - if (newObj != parent) { - newObj.setParentScope(parent); - } - } - } - - protected IdFunctionMaster master; - protected int methodId; - - protected int functionType = FUNCTION_ONLY; -} diff --git a/src/org/mozilla/javascript/IdFunctionMaster.java b/src/org/mozilla/javascript/IdFunctionMaster.java deleted file mode 100644 index 0a04e58..0000000 --- a/src/org/mozilla/javascript/IdFunctionMaster.java +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Igor Bukanov - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -/** Master for id-based functions that knows their properties and how to - ** execute them - */ -public interface IdFunctionMaster { - /** 'thisObj' will be null if invoked as constructor, in which case - ** instance of Scriptable should be returned */ - public Object execMethod(int methodId, IdFunction function, - Context cx, Scriptable scope, - Scriptable thisObj, Object[] args) - throws JavaScriptException; - - /** Get arity or defined argument count for method with given id. - ** Should return -1 if methodId is not known or can not be used - ** with execMethod call */ - public int methodArity(int methodId); -} - diff --git a/src/org/mozilla/javascript/IdScriptable.java b/src/org/mozilla/javascript/IdScriptable.java deleted file mode 100644 index 84fbc92..0000000 --- a/src/org/mozilla/javascript/IdScriptable.java +++ /dev/null @@ -1,577 +0,0 @@ -/* -*- Mode: java; tab-width: 4; indent-tabs-mode: 1; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Igor Bukanov - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -/** -Base class for native object implementation that uses IdFunction to export its methods to script via .prototype object. - -Any descendant should implement at least the following methods: - mapNameToId - getIdName - execMethod - methodArity - -To define non-function properties, the descendant should customize - getIdValue - setIdValue - getIdDefaultAttributes - maxInstanceId -to get/set property value and provide its default attributes. - -To customize initializition of constructor and protype objects, descendant -may override scopeInit or fillConstructorProperties methods. - -*/ -public abstract class IdScriptable extends ScriptableObject - implements IdFunctionMaster -{ - /** NULL_TAG can be used to distinguish between uninitialized and null - ** values - */ - protected static final Object NULL_TAG = new Object(); - - public IdScriptable() { - activateIdMap(maxInstanceId()); - } - - public boolean has(String name, Scriptable start) { - if (maxId != 0) { - int id = mapNameToId(name); - if (id != 0) { - return hasValue(id); - } - } - return super.has(name, start); - } - - public Object get(String name, Scriptable start) { - if (CACHE_NAMES) { - int maxId = this.maxId; - L:if (maxId != 0) { - Object[] data = idMapData; - if (data == null) { - int id = mapNameToId(name); - if (id != 0) { - return getIdValue(id); - } - } - else { - int id = lastIdCache; - if (data[id - 1 + maxId] != name) { - id = mapNameToId(name); - if (id == 0) { break L; } - data[id - 1 + maxId] = name; - lastIdCache = id; - } - Object value = data[id - 1]; - if (value == null) { - value = getIdValue(id); - } - else if (value == NULL_TAG) { - value = null; - } - return value; - } - } - } - else { - if (maxId != 0) { - int id = mapNameToId(name); - if (id != 0) { - Object[] data = idMapData; - if (data == null) { - return getIdValue(id); - } - else { - Object value = data[id - 1]; - if (value == null) { - value = getIdValue(id); - } - else if (value == NULL_TAG) { - value = null; - } - return value; - } - } - } - } - return super.get(name, start); - } - - public void put(String name, Scriptable start, Object value) { - if (maxId != 0) { - int id = mapNameToId(name); - if (id != 0) { - int attr = getAttributes(id); - if ((attr & READONLY) == 0) { - if (start == this) { - setIdValue(id, value); - } - else { - start.put(name, start, value); - } - } - return; - } - } - super.put(name, start, value); - } - - public void delete(String name) { - if (maxId != 0) { - int id = mapNameToId(name); - if (id != 0) { - // Let the super class to throw exceptions for sealed objects - if (!isSealed()) { - int attr = getAttributes(id); - if ((attr & PERMANENT) == 0) { - deleteIdValue(id); - } - return; - } - } - } - super.delete(name); - } - - public int getAttributes(String name, Scriptable start) - throws PropertyException - { - if (maxId != 0) { - int id = mapNameToId(name); - if (id != 0) { - if (hasValue(id)) { - return getAttributes(id); - } - // For ids with deleted values super will throw exceptions - } - } - return super.getAttributes(name, start); - } - - public void setAttributes(String name, Scriptable start, - int attributes) - throws PropertyException - { - if (maxId != 0) { - int id = mapNameToId(name); - if (id != 0) { - if (hasValue(id)) { - synchronized (this) { - setAttributes(id, attributes); - } - return; - } - // For ids with deleted values super will throw exceptions - } - } - super.setAttributes(name, start, attributes); - } - - synchronized void addPropertyAttribute(int attribute) { - extraIdAttributes |= (byte)attribute; - super.addPropertyAttribute(attribute); - } - - /** - * Redefine ScriptableObject.defineProperty to allow changing - * values/attributes of id-based properties unless - * getIdDefaultAttributes contains the READONLY attribute. - * @see #getIdDefaultAttributes - * @see org.mozilla.javascript.ScriptableObject#defineProperty - */ - public void defineProperty(String propertyName, Object value, - int attributes) - { - if (maxId != 0) { - int id = mapNameToId(propertyName); - if (id != 0) { - int default_attributes = getIdDefaultAttributes(id); - if ((default_attributes & READONLY) != 0) { - // It is a bug to redefine id with readonly attributes - throw new RuntimeException - ("Attempt to redefine read-only id " + propertyName); - } - setAttributes(id, attributes); - setIdValue(id, value); - return; - } - } - super.defineProperty(propertyName, value, attributes); - } - - Object[] getIds(boolean getAll) { - Object[] result = super.getIds(getAll); - - if (maxId != 0) { - Object[] ids = null; - int count = 0; - - for (int id = maxId; id != 0; --id) { - if (hasValue(id)) { - if (getAll || (getAttributes(id) & DONTENUM) == 0) { - if (count == 0) { - // Need extra room for nor more then [1..id] names - ids = new Object[id]; - } - ids[count++] = getIdName(id); - } - } - } - if (count != 0) { - if (result.length == 0 && ids.length == count) { - result = ids; - } - else { - Object[] tmp = new Object[result.length + count]; - System.arraycopy(result, 0, tmp, 0, result.length); - System.arraycopy(ids, 0, tmp, result.length, count); - result = tmp; - } - } - } - return result; - } - - /** Return maximum id number that should be present in each instance. */ - protected int maxInstanceId() { return 0; } - - /** - * Map name to id of prototype or instance property. - * Should return 0 if not found - */ - protected abstract int mapNameToId(String name); - - /** Map id back to property name it defines. - */ - protected abstract String getIdName(int id); - - /** Get default attributes for id. - ** Default implementation return DONTENUM that is the standard attribute - ** for core EcmaScript function. Typically descendants need to overwrite - ** this for non-function attributes like length to return - ** DONTENUM | READONLY | PERMANENT or DONTENUM | PERMANENT - */ - protected int getIdDefaultAttributes(int id) { - return DONTENUM; - } - - /** Check if id value exists. - ** Default implementation always returns true */ - protected boolean hasIdValue(int id) { - return true; - } - - /** Get id value. - ** If id value is constant, descendant can call cacheIdValue to store - ** value in the permanent cache. - ** Default implementation creates IdFunction instance for given id - ** and cache its value - */ - protected Object getIdValue(int id) { - IdFunction f = newIdFunction(id); - f.setParentScope(getParentScope()); - return cacheIdValue(id, f); - } - - /** - * Set id value. - * IdScriptable never calls this method if result of - * getIdDefaultAttributes(id) contains READONLY attribute. - * Descendants can overwrite this method to provide custom handler for - * property assignments. - */ - protected void setIdValue(int id, Object value) { - synchronized (this) { - ensureIdData()[id - 1] = (value != null) ? value : NULL_TAG; - } - } - - /** - * Store value in permanent cache unless value was already assigned to id. - * After this call IdScriptable never calls hasIdValue and getIdValue - * for the given id. - */ - protected Object cacheIdValue(int id, Object value) { - synchronized (this) { - Object[] data = ensureIdData(); - Object curValue = data[id - 1]; - if (curValue == null) { - data[id - 1] = (value != null) ? value : NULL_TAG; - } - else { - value = curValue; - } - } - return value; - } - - /** - * Delete value represented by id so hasIdValue return false. - * IdScriptable never calls this method if result of - * getIdDefaultAttributes(id) contains PERMANENT attribute. - * Descendants can overwrite this method to provide custom handler for - * property delete. - */ - protected void deleteIdValue(int id) { - synchronized (this) { - ensureIdData()[id - 1] = NOT_FOUND; - } - } - - /** 'thisObj' will be null if invoked as constructor, in which case - ** instance of Scriptable should be returned. */ - public Object execMethod(int methodId, IdFunction function, - Context cx, Scriptable scope, - Scriptable thisObj, Object[] args) - throws JavaScriptException - { - throw IdFunction.onBadMethodId(this, methodId); - } - - /** Get arity or defined argument count for method with given id. - ** Should return -1 if methodId is not known or can not be used - ** with execMethod call. */ - public int methodArity(int methodId) { - return -1; - } - - /** Activate id support with the given maximum id */ - protected void activateIdMap(int maxId) { - this.maxId = maxId; - } - - /** Sets whether newly constructed function objects should be sealed */ - protected void setSealFunctionsFlag(boolean sealed) { - setSetupFlag(SEAL_FUNCTIONS_FLAG, sealed); - } - - /** - * Set parameters of function properties. - * Currently only determines whether functions should use dynamic scope. - * @param cx context to read function parameters. - * - * @see org.mozilla.javascript.Context#hasCompileFunctionsWithDynamicScope - */ - protected void setFunctionParametrs(Context cx) { - setSetupFlag(USE_DYNAMIC_SCOPE_FLAG, - cx.hasCompileFunctionsWithDynamicScope()); - } - - private void setSetupFlag(int flag, boolean value) { - setupFlags = (byte)(value ? setupFlags | flag : setupFlags & ~flag); - } - - /** - * Prepare this object to serve as the prototype property of constructor - * object with name getClassName() defined in - * scope. - * @param maxId maximum id available in prototype object - * @param cx current context - * @param scope object to define constructor in. - * @param sealed indicates whether object and all its properties should - * be sealed - */ - public void addAsPrototype(int maxId, Context cx, Scriptable scope, - boolean sealed) - { - activateIdMap(maxId); - - setSealFunctionsFlag(sealed); - setFunctionParametrs(cx); - - int constructorId = mapNameToId("constructor"); - if (constructorId == 0) { - // It is a bug to call this function without id for constructor - throw new RuntimeException("No id for constructor property"); - } - - IdFunction ctor = newIdFunction(constructorId); - ctor.initAsConstructor(scope, this); - fillConstructorProperties(cx, ctor, sealed); - if (sealed) { - ctor.sealObject(); - ctor.addPropertyAttribute(READONLY); - } - - setParentScope(ctor); - setPrototype(getObjectPrototype(scope)); - cacheIdValue(constructorId, ctor); - - if (sealed) { - sealObject(); - } - - defineProperty(scope, getClassName(), ctor, ScriptableObject.DONTENUM); - } - - protected void fillConstructorProperties - (Context cx, IdFunction ctor, boolean sealed) - { - } - - protected void addIdFunctionProperty - (Scriptable obj, int id, boolean sealed) - { - IdFunction f = newIdFunction(id); - if (sealed) { f.sealObject(); } - defineProperty(obj, getIdName(id), f, DONTENUM); - } - - /** - * Utility method for converting target object into native this. - * Possible usage would be to have a private function like realThis: - *

-       private NativeSomething realThis(Scriptable thisObj,
-                                        IdFunction f, boolean readOnly)
-       {
-           while (!(thisObj instanceof NativeSomething)) {
-               thisObj = nextInstanceCheck(thisObj, f, readOnly);
-           }
-           return (NativeSomething)thisObj;
-       }
-    * 
- * Note that although such function can be implemented universally via - * java.lang.Class.isInstance(), it would be much more slower. - * @param readOnly specify if the function f does not change state of object. - * @return Scriptable object suitable for a check by the instanceof operator. - * @throws RuntimeException if no more instanceof target can be found - */ - protected Scriptable nextInstanceCheck(Scriptable thisObj, - IdFunction f, - boolean readOnly) - { - if (readOnly && 0 != (setupFlags & USE_DYNAMIC_SCOPE_FLAG)) { - // for read only functions under dynamic scope look prototype chain - thisObj = thisObj.getPrototype(); - if (thisObj != null) { return thisObj; } - } - throw NativeGlobal.typeError1("msg.incompat.call", - f.getFunctionName(), f); - } - - protected IdFunction newIdFunction(int id) { - IdFunction f = new IdFunction(this, getIdName(id), id); - if (0 != (setupFlags & SEAL_FUNCTIONS_FLAG)) { f.sealObject(); } - return f; - } - - protected final Object wrap_double(double x) { - return (x == x) ? new Double(x) : ScriptRuntime.NaNobj; - } - - protected final Object wrap_int(int x) { - byte b = (byte)x; - if (b == x) { return new Byte(b); } - return new Integer(x); - } - - protected final Object wrap_long(long x) { - int i = (int)x; - if (i == x) { return wrap_int(i); } - return new Long(x); - } - - protected final Object wrap_boolean(boolean x) { - return x ? Boolean.TRUE : Boolean.FALSE; - } - - private boolean hasValue(int id) { - Object value; - Object[] data = idMapData; - if (data == null || (value = data[id - 1]) == null) { - return hasIdValue(id); - } - else { - return value != NOT_FOUND; - } - } - - // Must be called only from synchronized (this) - private Object[] ensureIdData() { - Object[] data = idMapData; - if (data == null) { - idMapData = data = new Object[CACHE_NAMES ? maxId * 2 : maxId]; - } - return data; - } - - private int getAttributes(int id) { - int attributes = getIdDefaultAttributes(id) | extraIdAttributes; - byte[] array = attributesArray; - if (array != null) { - attributes |= 0xFF & array[id - 1]; - } - return attributes; - } - - private void setAttributes(int id, int attributes) { - int defaultAttrs = getIdDefaultAttributes(id); - if ((attributes & defaultAttrs) != defaultAttrs) { - // It is a bug to set attributes to less restrictive values - // then given by defaultAttrs - throw new RuntimeException("Attempt to unset default attributes"); - } - // Store only additional bits - attributes &= ~defaultAttrs; - byte[] array = attributesArray; - if (array == null && attributes != 0) { - synchronized (this) { - array = attributesArray; - if (array == null) { - attributesArray = array = new byte[maxId]; - } - } - } - if (array != null) { - array[id - 1] = (byte)attributes; - } - } - - private int maxId; - private Object[] idMapData; - private byte[] attributesArray; - - private static final boolean CACHE_NAMES = true; - private int lastIdCache; - - private static final int USE_DYNAMIC_SCOPE_FLAG = 1 << 0; - private static final int SEAL_FUNCTIONS_FLAG = 1 << 1; - - private byte setupFlags; - private byte extraIdAttributes; -} - diff --git a/src/org/mozilla/javascript/ImporterTopLevel.java b/src/org/mozilla/javascript/ImporterTopLevel.java deleted file mode 100644 index ea4540d..0000000 --- a/src/org/mozilla/javascript/ImporterTopLevel.java +++ /dev/null @@ -1,176 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * Matthias Radestock - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -// API class - -package org.mozilla.javascript; - -import java.util.Vector; - -/** - * Class ImporterTopLevel - * - * This class defines a ScriptableObject that can be instantiated - * as a top-level ("global") object to provide functionality similar - * to Java's "import" statement. - *

- * This class can be used to create a top-level scope using the following code: - *

- *  Scriptable scope = new ImporterTopLevel(cx);
- * 
- * Then JavaScript code will have access to the following methods: - *
    - *
  • importClass - will "import" a class by making its unqualified name - * available as a property of the top-level scope - *
  • importPackage - will "import" all the classes of the package by - * searching for unqualified names as classes qualified - * by the given package. - *
- * The following code from the shell illustrates this use: - *
- * js> importClass(java.io.File)
- * js> f = new File('help.txt')
- * help.txt
- * js> importPackage(java.util)
- * js> v = new Vector()
- * []
- * 
- * @author Norris Boyd
- */
-public class ImporterTopLevel extends ScriptableObject {
-    
-    /**
-     * @deprecated
-     */
-    public ImporterTopLevel() {
-        init();
-    }
-
-    public ImporterTopLevel(Context cx) {
-        cx.initStandardObjects(this);
-        init();
-    }
-    
-    private void init() {
-        String[] names = { "importClass", "importPackage" };
-
-        try {
-            this.defineFunctionProperties(names, ImporterTopLevel.class,
-                                          ScriptableObject.DONTENUM);
-        } catch (PropertyException e) {
-            throw new Error();  // should never happen
-        }
-    }
-
-    public String getClassName() { 
-        return "global";
-    }
-    
-    public Object get(String name, Scriptable start) {
-        Object result = super.get(name, start);
-        if (result != NOT_FOUND) 
-            return result;
-        if (name.equals("_packages_")) 
-            return result;
-        Object plist = ScriptableObject.getProperty(start,"_packages_");
-        if (plist == NOT_FOUND) 
-            return result;
-        Context cx = Context.enter();
-        Object[] elements = cx.getElements((Scriptable)plist);
-        Context.exit();
-        for (int i=0; i < elements.length; i++) {
-            NativeJavaPackage p = (NativeJavaPackage) elements[i];
-            Object v = p.getPkgProperty(name, start, false);
-            if (v != null && !(v instanceof NativeJavaPackage)) {
-                if (result == NOT_FOUND) {
-                    result = v;
-                } else {
-                    throw Context.reportRuntimeError2(
-                        "msg.ambig.import", result.toString(), v.toString());
-                }
-            }
-        }
-        return result;
-    }
-    
-    public static void importClass(Context cx, Scriptable thisObj,
-                                   Object[] args, Function funObj) {
-        for (int i=0; i 200) {
-            NativeError ne = new NativeError();
-            ne.put("message", ne, "maximum interpreter stack depth limit exceeded");
-            cx.stackDepth--;
-            throw new EcmaError(ne, cx.interpreterSourceFile, cx.interpreterLine, 0, "");
-        }
-        cx.currentFunction = this;
-        cx.interpreterSourceFile = itsData.itsSourceFile;
-        if (itsClosure != null)
-            scope = itsClosure;
-        else if (!itsData.itsUseDynamicScope)
-            scope = getParentScope();
-
-        if (itsData.itsCheckThis) 
-            thisObj = ScriptRuntime.getThis(thisObj);
-        
-        if (itsData.itsNeedsActivation) {
-            scope = ScriptRuntime.initVarObj(cx, scope, this, thisObj, args);
-        }
-        try {
-            return Interpreter.interpret(cx, scope, thisObj, args, this,
-                                         itsData);
-        } finally {
-            if (itsData.itsNeedsActivation) {
-                ScriptRuntime.popActivation(cx);
-            }
-            cx.currentFunction = temp;
-            cx.stackDepth--;
-        }
-    }
-    
-    public boolean isFunction() {
-        return true;
-    }
-    
-    public Scriptable getScriptable() {
-        return this;
-    }
-    
-    public String getSourceName() {
-        return itsData.itsSourceFile;
-    }
-    
-    public int[] getLineNumbers() { 
-        return itsData.itsLineNumberTable.getKeys();
-    }
-    
-    public boolean placeBreakpoint(int line) { // XXX throw exn?
-        return itsData.placeBreakpoint(line);
-    }
-    
-    public boolean removeBreakpoint(int line) {
-        return itsData.removeBreakpoint(line);
-    }
-    
-    InterpreterData itsData;
-    Scriptable itsClosure;
-}
-    
diff --git a/src/org/mozilla/javascript/InterpretedScript.java b/src/org/mozilla/javascript/InterpretedScript.java
deleted file mode 100644
index 2c7ef2e..0000000
--- a/src/org/mozilla/javascript/InterpretedScript.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * The contents of this file are subject to the Netscape Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/NPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is Rhino code, released
- * May 6, 1999.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation.  Portions created by Netscape are
- * Copyright (C) 1997-1999 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s): 
- * Roger Lawrence
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU Public License (the "GPL"), in which case the
- * provisions of the GPL are applicable instead of those above.
- * If you wish to allow use of your version of this file only
- * under the terms of the GPL and not to allow others to use your
- * version of this file under the NPL, indicate your decision by
- * deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL.  If you do not delete
- * the provisions above, a recipient may use your version of this
- * file under either the NPL or the GPL.
- */
-
-package org.mozilla.javascript;
-
-import org.mozilla.javascript.debug.*;
-
-import java.util.*;
-
-public class InterpretedScript extends NativeScript implements DebuggableScript {
-
-    InterpretedScript(Context cx,
-                      InterpreterData theData, 
-                      String[] argNames, short argCount)
-    {
-        itsData = theData;
-        this.argNames = argNames;
-        this.argCount = argCount;
-        functionName = "";
-        nestedFunctions = itsData.itsNestedFunctions;
-        version = (short)cx.getLanguageVersion();   
-    }
-    
-    public Object exec(Context cx, Scriptable scope)
-        throws JavaScriptException
-    {
-        return call(cx, scope, scope, null);    
-    }
-
-    public Object call(Context cx, Scriptable scope, 
-                       Scriptable thisObj, Object[] args)
-        throws JavaScriptException
-    {
-        Function temp = cx.currentFunction;
-        cx.currentFunction = this;
-        cx.interpreterSourceFile = itsData.itsSourceFile;
-        scope = ScriptRuntime.initScript(cx, scope, this, thisObj, 
-                                         itsData.itsFromEvalCode);
-        Object ret = Interpreter.interpret(cx, scope, thisObj, args, this, itsData);    
-        cx.currentFunction = temp;
-        return ret;
-    }
-    
-    public boolean isFunction() {
-        return false;
-    }
-    
-    public Scriptable getScriptable() {
-        return this;
-    }
-    
-    public String getSourceName() {
-        return itsData.itsSourceFile;
-    }
-    
-    public int[] getLineNumbers() {
-        return itsData.itsLineNumberTable.getKeys();
-    }
-    
-    public boolean placeBreakpoint(int line) { // XXX throw exn?
-        return itsData.placeBreakpoint(line);
-    }
-    
-    public boolean removeBreakpoint(int line) {
-        return itsData.removeBreakpoint(line);
-    }
-    
-    InterpreterData itsData;
-}
-
diff --git a/src/org/mozilla/javascript/Interpreter.java b/src/org/mozilla/javascript/Interpreter.java
deleted file mode 100644
index 77cc0cb..0000000
--- a/src/org/mozilla/javascript/Interpreter.java
+++ /dev/null
@@ -1,2514 +0,0 @@
-/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * The contents of this file are subject to the Netscape Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/NPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is Rhino code, released
- * May 6, 1999.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation.  Portions created by Netscape are
- * Copyright (C) 1997-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s): 
- * Patrick Beard
- * Norris Boyd
- * Igor Bukanov
- * Roger Lawrence
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU Public License (the "GPL"), in which case the
- * provisions of the GPL are applicable instead of those above.
- * If you wish to allow use of your version of this file only
- * under the terms of the GPL and not to allow others to use your
- * version of this file under the NPL, indicate your decision by
- * deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL.  If you do not delete
- * the provisions above, a recipient may use your version of this
- * file under either the NPL or the GPL.
- */
-
-package org.mozilla.javascript;
-
-import java.io.*;
-import java.util.Vector;
-import java.util.Enumeration;
-
-import org.mozilla.javascript.debug.*;
-
-public class Interpreter extends LabelTable {
-    
-    public static final boolean printICode = false;
-    
-    public IRFactory createIRFactory(TokenStream ts, 
-                                     ClassNameHelper nameHelper, Scriptable scope) 
-    {
-        return new IRFactory(ts, scope);
-    }
-    
-    public Node transform(Node tree, TokenStream ts, Scriptable scope) {
-        return (new NodeTransformer()).transform(tree, null, ts, scope);
-    }
-    
-    public Object compile(Context cx, Scriptable scope, Node tree, 
-                          Object securityDomain,
-                          SecuritySupport securitySupport,
-                          ClassNameHelper nameHelper)
-        throws IOException
-    {
-        version = cx.getLanguageVersion();
-        itsData = new InterpreterData(0, 0, 0, securityDomain, 
-                    cx.hasCompileFunctionsWithDynamicScope(), false);
-        if (tree instanceof FunctionNode) {
-            FunctionNode f = (FunctionNode) tree;
-            InterpretedFunction result = 
-                generateFunctionICode(cx, scope, f, securityDomain);
-            result.itsData.itsFunctionType = f.getFunctionType();
-            createFunctionObject(result, scope);
-            return result;
-        }
-        return generateScriptICode(cx, scope, tree, securityDomain);
-    }
-       
-    private void generateICodeFromTree(Node tree, 
-                                       VariableTable varTable, 
-                                       boolean needsActivation,
-                                       Object securityDomain)
-    {
-        int theICodeTop = 0;
-        itsVariableTable = varTable;
-        itsData.itsNeedsActivation = needsActivation;
-        theICodeTop = generateICode(tree, theICodeTop);
-        itsData.itsICodeTop = theICodeTop;
-        if (itsEpilogLabel != -1)
-            markLabel(itsEpilogLabel, theICodeTop);
-        for (int i = 0; i < itsLabelTableTop; i++)
-            itsLabelTable[i].fixGotos(itsData.itsICode);            
-    }
-
-    private Object[] generateRegExpLiterals(Context cx,
-                                            Scriptable scope,
-                                            Vector regexps)
-    {
-        Object[] result = new Object[regexps.size()];
-        RegExpProxy rep = cx.getRegExpProxy();
-        for (int i = 0; i < regexps.size(); i++) {
-            Node regexp = (Node) regexps.elementAt(i);
-            Node left = regexp.getFirstChild();
-            Node right = regexp.getLastChild();
-            result[i] = rep.newRegExp(cx, scope, left.getString(), 
-                                (left != right) ? right.getString() : null, false);
-            regexp.putProp(Node.REGEXP_PROP, new Integer(i));
-        }
-        return result;
-    }
-        
-    private InterpretedScript generateScriptICode(Context cx, 
-                                                  Scriptable scope, 
-                                                  Node tree,
-                                                  Object securityDomain)
-    {        
-        itsSourceFile = (String) tree.getProp(Node.SOURCENAME_PROP);
-        itsData.itsSourceFile = itsSourceFile;
-        itsFunctionList = (Vector) tree.getProp(Node.FUNCTION_PROP);        
-        debugSource = (StringBuffer) tree.getProp(Node.DEBUGSOURCE_PROP);
-        if (itsFunctionList != null)
-            generateNestedFunctions(scope, cx, securityDomain);
-        Object[] regExpLiterals = null;
-        Vector regexps = (Vector)tree.getProp(Node.REGEXP_PROP);
-        if (regexps != null) 
-            regExpLiterals = generateRegExpLiterals(cx, scope, regexps);
-        
-        VariableTable varTable = (VariableTable)tree.getProp(Node.VARS_PROP);
-        // The default is not to generate debug information
-        boolean activationNeeded = cx.isGeneratingDebugChanged() && 
-                                   cx.isGeneratingDebug();
-        generateICodeFromTree(tree, varTable, activationNeeded, securityDomain);
-        itsData.itsNestedFunctions = itsNestedFunctions;
-        itsData.itsRegExpLiterals = regExpLiterals;
-        if (printICode) dumpICode(itsData);
-                                                               
-        String[] argNames = itsVariableTable.getAllNames();
-        short argCount = (short)itsVariableTable.getParameterCount();
-        InterpretedScript
-            result = new InterpretedScript(cx, itsData, argNames, argCount);
-        if (cx.debugger != null) {
-            cx.debugger.handleCompilationDone(cx, result, debugSource);
-        }
-        return result;
-    }
-    
-    private void generateNestedFunctions(Scriptable scope,
-                                         Context cx, 
-                                         Object securityDomain)
-    {
-        itsNestedFunctions = new InterpretedFunction[itsFunctionList.size()];
-        for (short i = 0; i < itsFunctionList.size(); i++) {
-            FunctionNode def = (FunctionNode)itsFunctionList.elementAt(i);
-            Interpreter jsi = new Interpreter();
-            jsi.itsSourceFile = itsSourceFile;
-            jsi.itsData = new InterpreterData(0, 0, 0, securityDomain,
-                            cx.hasCompileFunctionsWithDynamicScope(),
-                            def.getCheckThis());
-            jsi.itsData.itsFunctionType = def.getFunctionType();
-            jsi.itsInFunctionFlag = true;
-            jsi.debugSource = debugSource;
-            itsNestedFunctions[i] = jsi.generateFunctionICode(cx, scope, def, 
-                                                              securityDomain);
-            def.putProp(Node.FUNCTION_PROP, new Short(i));
-        }
-    }        
-    
-    private InterpretedFunction 
-    generateFunctionICode(Context cx, Scriptable scope, 
-                          FunctionNode theFunction, Object securityDomain)
-    {
-        itsFunctionList = (Vector) theFunction.getProp(Node.FUNCTION_PROP);
-        if (itsFunctionList != null) 
-            generateNestedFunctions(scope, cx, securityDomain);
-        Object[] regExpLiterals = null;
-        Vector regexps = (Vector)theFunction.getProp(Node.REGEXP_PROP);
-        if (regexps != null) 
-            regExpLiterals = generateRegExpLiterals(cx, scope, regexps);
-
-        VariableTable varTable = theFunction.getVariableTable();
-        boolean needsActivation = theFunction.requiresActivation() ||
-                                  (cx.isGeneratingDebugChanged() && 
-                                   cx.isGeneratingDebug());
-        generateICodeFromTree(theFunction.getLastChild(), 
-                              varTable, needsActivation,
-                              securityDomain);
-            
-        itsData.itsName = theFunction.getFunctionName();
-        itsData.itsSourceFile = (String) theFunction.getProp(
-                                    Node.SOURCENAME_PROP);
-        itsData.itsSource = (String)theFunction.getProp(Node.SOURCE_PROP);
-        itsData.itsNestedFunctions = itsNestedFunctions;
-        itsData.itsRegExpLiterals = regExpLiterals;
-        if (printICode) dumpICode(itsData);            
-            
-        String[] argNames = itsVariableTable.getAllNames();
-        short argCount = (short)itsVariableTable.getParameterCount();
-        InterpretedFunction 
-            result = new InterpretedFunction(cx, itsData, argNames, argCount); 
-        if (cx.debugger != null) {
-            cx.debugger.handleCompilationDone(cx, result, debugSource);
-        }
-        return result;
-    }
-    
-    boolean itsInFunctionFlag;
-    Vector itsFunctionList;
-    
-    InterpreterData itsData;
-    VariableTable itsVariableTable;
-    int itsTryDepth = 0;
-    int itsStackDepth = 0;
-    int itsEpilogLabel = -1;
-    String itsSourceFile;
-    int itsLineNumber = 0;
-    InterpretedFunction[] itsNestedFunctions = null;
-    
-    private int updateLineNumber(Node node, int iCodeTop)
-    {
-        Object datum = node.getDatum();
-        if (datum == null || !(datum instanceof Number))
-            return iCodeTop;
-        short lineNumber = ((Number) datum).shortValue(); 
-        if (lineNumber != itsLineNumber) {
-            itsLineNumber = lineNumber;
-            if (itsData.itsLineNumberTable == null && 
-                Context.getCurrentContext().isGeneratingDebug())
-            {
-                itsData.itsLineNumberTable = new UintMap();
-            }
-            if (itsData.itsLineNumberTable != null) {
-                itsData.itsLineNumberTable.put(lineNumber, iCodeTop);
-            }
-            iCodeTop = addByte((byte) TokenStream.LINE, iCodeTop);
-            iCodeTop = addByte((byte)(lineNumber >> 8), iCodeTop);
-            iCodeTop = addByte((byte)(lineNumber & 0xff), iCodeTop);
-            
-        }
-        
-        return iCodeTop;
-    }
-    
-    private void badTree(Node node)
-    {
-        try {
-            out = new PrintWriter(new FileOutputStream("icode.txt", true));
-            out.println("Un-handled node : " + node.toString());
-            out.close();
-        }
-        catch (IOException x) {}
-        throw new RuntimeException("Un-handled node : "
-                                        + node.toString());
-    }
-    
-    private int generateICode(Node node, int iCodeTop) {
-        int type = node.getType();
-        Node child = node.getFirstChild();
-        Node firstChild = child;
-        switch (type) {
-            
-            case TokenStream.FUNCTION : {                                        
-                    iCodeTop = addByte((byte) TokenStream.CLOSURE, iCodeTop);
-                    Node fn = (Node) node.getProp(Node.FUNCTION_PROP);
-                    Short index = (Short) fn.getProp(Node.FUNCTION_PROP);
-                    iCodeTop = addByte((byte)(index.shortValue() >> 8), iCodeTop);
-                    iCodeTop = addByte((byte)(index.shortValue() & 0xff), iCodeTop);                    
-                    itsStackDepth++;
-                    if (itsStackDepth > itsData.itsMaxStack)
-                        itsData.itsMaxStack = itsStackDepth;
-                }
-                break;
-
-            case TokenStream.SCRIPT :
-                iCodeTop = updateLineNumber(node, iCodeTop);
-                while (child != null) {
-                    if (child.getType() != TokenStream.FUNCTION) 
-                        iCodeTop = generateICode(child, iCodeTop);
-                    child = child.getNextSibling();
-                }
-                break;
-
-            case TokenStream.CASE :
-                iCodeTop = updateLineNumber(node, iCodeTop);
-                child = child.getNextSibling();
-                while (child != null) {
-                    iCodeTop = generateICode(child, iCodeTop);
-                    child = child.getNextSibling();
-                }
-                break;
-                
-            case TokenStream.LABEL :
-            case TokenStream.WITH :
-            case TokenStream.LOOP :
-            case TokenStream.DEFAULT :
-            case TokenStream.BLOCK :
-            case TokenStream.VOID :
-            case TokenStream.NOP :
-                iCodeTop = updateLineNumber(node, iCodeTop);
-                while (child != null) {
-                    iCodeTop = generateICode(child, iCodeTop);
-                    child = child.getNextSibling();
-                }
-                break;
-
-            case TokenStream.COMMA :
-                iCodeTop = generateICode(child, iCodeTop);
-                iCodeTop = addByte((byte) TokenStream.POP, iCodeTop);
-                itsStackDepth--;
-                child = child.getNextSibling();
-                iCodeTop = generateICode(child, iCodeTop);
-                break;
-               
-            case TokenStream.SWITCH : {
-                    iCodeTop = updateLineNumber(node, iCodeTop);
-                    iCodeTop = generateICode(child, iCodeTop);
-                    int theLocalSlot = itsData.itsMaxLocals++;
-                    iCodeTop = addByte((byte) TokenStream.NEWTEMP, iCodeTop);
-                    iCodeTop = addByte((byte)theLocalSlot, iCodeTop);
-                    iCodeTop = addByte((byte) TokenStream.POP, iCodeTop);
-                    itsStackDepth--;
-         /*
-            reminder - below we construct new GOTO nodes that aren't
-            linked into the tree just for the purpose of having a node
-            to pass to the addGoto routine. (Parallels codegen here).
-            Seems unnecessary.        
-         */
-                    Vector cases = (Vector) node.getProp(Node.CASES_PROP);
-                    for (int i = 0; i < cases.size(); i++) {
-                        Node thisCase = (Node)cases.elementAt(i);
-                        Node first = thisCase.getFirstChild();
-                        // the case expression is the firstmost child
-                        // the rest will be generated when the case
-                        // statements are encountered as siblings of
-                        // the switch statement.
-                        iCodeTop = generateICode(first, iCodeTop);                   
-                        iCodeTop = addByte((byte) TokenStream.USETEMP, iCodeTop);
-                        itsStackDepth++;
-                        if (itsStackDepth > itsData.itsMaxStack)
-                            itsData.itsMaxStack = itsStackDepth;
-                        iCodeTop = addByte((byte) theLocalSlot, iCodeTop);
-                        iCodeTop = addByte((byte) TokenStream.SHEQ, iCodeTop);
-                        Node target = new Node(TokenStream.TARGET);
-                        thisCase.addChildAfter(target, first);
-                        Node branch = new Node(TokenStream.IFEQ);
-                        branch.putProp(Node.TARGET_PROP, target);
-                        iCodeTop = addGoto(branch, TokenStream.IFEQ, 
-                                           iCodeTop);
-                        itsStackDepth--;
-                    }
-
-                    Node defaultNode = (Node) node.getProp(Node.DEFAULT_PROP);
-                    if (defaultNode != null) {
-                        Node defaultTarget = new Node(TokenStream.TARGET);
-                        defaultNode.getFirstChild().addChildToFront(defaultTarget);
-                        Node branch = new Node(TokenStream.GOTO);
-                        branch.putProp(Node.TARGET_PROP, defaultTarget);
-                        iCodeTop = addGoto(branch, TokenStream.GOTO,
-                                                            iCodeTop);                    
-                    }
-
-                    Node breakTarget = (Node) node.getProp(Node.BREAK_PROP);
-                    Node branch = new Node(TokenStream.GOTO);
-                    branch.putProp(Node.TARGET_PROP, breakTarget);
-                    iCodeTop = addGoto(branch, TokenStream.GOTO, 
-                                       iCodeTop);                    
-                }
-                break;
-                                
-            case TokenStream.TARGET : { 
-                    Object lblObect = node.getProp(Node.LABEL_PROP);
-                    if (lblObect == null) {
-                        int label = markLabel(acquireLabel(), iCodeTop);
-                        node.putProp(Node.LABEL_PROP, new Integer(label));
-                    }
-                    else {
-                        int label = ((Integer)lblObect).intValue();
-                        markLabel(label, iCodeTop);
-                    }
-                    // if this target has a FINALLY_PROP, it is a JSR target
-                    // and so has a PC value on the top of the stack
-                    if (node.getProp(Node.FINALLY_PROP) != null) {
-                        itsStackDepth = 1;
-                        if (itsStackDepth > itsData.itsMaxStack)
-                            itsData.itsMaxStack = itsStackDepth;
-                    }
-                }
-                break;
-                
-            case TokenStream.EQOP :
-            case TokenStream.RELOP : {
-                    iCodeTop = generateICode(child, iCodeTop);
-                    child = child.getNextSibling();
-                    iCodeTop = generateICode(child, iCodeTop);
-                    int op = node.getInt();
-                    if (version == Context.VERSION_1_2) {
-                        if (op == TokenStream.EQ)
-                            op = TokenStream.SHEQ;
-                        else if (op == TokenStream.NE)
-                            op = TokenStream.SHNE;
-                    }
-                    iCodeTop = addByte((byte) op, iCodeTop);
-                    itsStackDepth--;
-                }
-                break;
-                
-            case TokenStream.NEW :
-            case TokenStream.CALL : {
-                    if (itsSourceFile != null && (itsData.itsSourceFile == null || ! itsSourceFile.equals(itsData.itsSourceFile))) 
-                        itsData.itsSourceFile = itsSourceFile;
-                    iCodeTop = addByte((byte)TokenStream.SOURCEFILE, iCodeTop);
-                    
-                    int childCount = 0;
-                    short nameIndex = -1;
-                    while (child != null) {
-                        iCodeTop = generateICode(child, iCodeTop);
-                        if (nameIndex == -1) {
-                            if (child.getType() == TokenStream.NAME)
-                                nameIndex = (short)(itsData.itsStringTableIndex - 1);
-                            else if (child.getType() == TokenStream.GETPROP)
-                                nameIndex = (short)(itsData.itsStringTableIndex - 1);
-                        }
-                        child = child.getNextSibling();
-                        childCount++;
-                    }
-                    if (node.getProp(Node.SPECIALCALL_PROP) != null) {
-                        // embed line number and source filename
-                        iCodeTop = addByte((byte) TokenStream.CALLSPECIAL, iCodeTop);
-                        iCodeTop = addByte((byte)(itsLineNumber >> 8), iCodeTop);
-                        iCodeTop = addByte((byte)(itsLineNumber & 0xff), iCodeTop);
-                        iCodeTop = addString(itsSourceFile, iCodeTop);
-                    } else {
-                        iCodeTop = addByte((byte) type, iCodeTop);
-                        iCodeTop = addByte((byte)(nameIndex >> 8), iCodeTop);
-                        iCodeTop = addByte((byte)(nameIndex & 0xFF), iCodeTop);
-                    }
-                    
-                    itsStackDepth -= (childCount - 1);  // always a result value
-                    // subtract from child count to account for [thisObj &] fun
-                    if (type == TokenStream.NEW)
-                        childCount -= 1;
-                    else
-                        childCount -= 2;
-                    iCodeTop = addByte((byte)(childCount >> 8), iCodeTop);
-                    iCodeTop = addByte((byte)(childCount & 0xff), iCodeTop);
-                    if (childCount > itsData.itsMaxArgs)
-                        itsData.itsMaxArgs = childCount;
-                    
-                    iCodeTop = addByte((byte)TokenStream.SOURCEFILE, iCodeTop);
-                }
-                break;
-                
-            case TokenStream.NEWLOCAL :
-            case TokenStream.NEWTEMP : {
-                    iCodeTop = generateICode(child, iCodeTop);
-                    iCodeTop = addByte((byte) TokenStream.NEWTEMP, iCodeTop);
-                    iCodeTop = addLocalRef(node, iCodeTop);
-                }
-                break;                
-                   
-            case TokenStream.USELOCAL : {
-                    if (node.getProp(Node.TARGET_PROP) != null) 
-                        iCodeTop = addByte((byte) TokenStream.RETSUB, iCodeTop);
-                    else {
-                        iCodeTop = addByte((byte) TokenStream.USETEMP, iCodeTop);
-                        itsStackDepth++;
-                        if (itsStackDepth > itsData.itsMaxStack)
-                            itsData.itsMaxStack = itsStackDepth;
-                    }
-                    Node temp = (Node) node.getProp(Node.LOCAL_PROP);
-                    iCodeTop = addLocalRef(temp, iCodeTop);
-                }
-                break;                
-
-            case TokenStream.USETEMP : {
-                    iCodeTop = addByte((byte) TokenStream.USETEMP, iCodeTop);
-                    Node temp = (Node) node.getProp(Node.TEMP_PROP);
-                    iCodeTop = addLocalRef(temp, iCodeTop);
-                    itsStackDepth++;
-                    if (itsStackDepth > itsData.itsMaxStack)
-                        itsData.itsMaxStack = itsStackDepth;
-                }
-                break;                
-                
-            case TokenStream.IFEQ :
-            case TokenStream.IFNE :
-                iCodeTop = generateICode(child, iCodeTop);
-                itsStackDepth--;    // after the conditional GOTO, really
-                    // fall thru...
-            case TokenStream.GOTO :
-                iCodeTop = addGoto(node, (byte) type, iCodeTop);
-                break;
-
-            case TokenStream.JSR : {
-                /*
-                    mark the target with a FINALLY_PROP to indicate
-                    that it will have an incoming PC value on the top
-                    of the stack.
-                    !!! 
-                    This only works if the target follows the JSR
-                    in the tree.
-                    !!!
-                */
-                    Node target = (Node)(node.getProp(Node.TARGET_PROP));
-                    target.putProp(Node.FINALLY_PROP, node);
-                    iCodeTop = addGoto(node, TokenStream.GOSUB, iCodeTop);
-                }
-                break;
-            
-            case TokenStream.AND : {            
-                    iCodeTop = generateICode(child, iCodeTop);
-                    iCodeTop = addByte((byte) TokenStream.DUP, iCodeTop);                
-                    itsStackDepth++;
-                    if (itsStackDepth > itsData.itsMaxStack)
-                        itsData.itsMaxStack = itsStackDepth;
-                    int falseTarget = acquireLabel();
-                    iCodeTop = addGoto(falseTarget, TokenStream.IFNE, 
-                                                    iCodeTop);
-                    iCodeTop = addByte((byte) TokenStream.POP, iCodeTop);
-                    itsStackDepth--;
-                    child = child.getNextSibling();
-                    iCodeTop = generateICode(child, iCodeTop);
-                    markLabel(falseTarget, iCodeTop);
-                }
-                break;
-
-            case TokenStream.OR : {
-                    iCodeTop = generateICode(child, iCodeTop);
-                    iCodeTop = addByte((byte) TokenStream.DUP, iCodeTop);                
-                    itsStackDepth++;
-                    if (itsStackDepth > itsData.itsMaxStack)
-                        itsData.itsMaxStack = itsStackDepth;
-                    int trueTarget = acquireLabel();
-                    iCodeTop = addGoto(trueTarget, TokenStream.IFEQ,
-                                       iCodeTop);
-                    iCodeTop = addByte((byte) TokenStream.POP, iCodeTop);                
-                    itsStackDepth--;
-                    child = child.getNextSibling();
-                    iCodeTop = generateICode(child, iCodeTop);
-                    markLabel(trueTarget, iCodeTop);
-                }
-                break;
-
-            case TokenStream.GETPROP : {
-                    iCodeTop = generateICode(child, iCodeTop);
-                    String s = (String) node.getProp(Node.SPECIAL_PROP_PROP);
-                    if (s != null) {
-                        if (s.equals("__proto__"))
-                            iCodeTop = addByte((byte) TokenStream.GETPROTO, iCodeTop);
-                        else
-                            if (s.equals("__parent__"))
-                                iCodeTop = addByte((byte) TokenStream.GETSCOPEPARENT, iCodeTop);
-                            else
-                                badTree(node);
-                    }
-                    else {
-                        child = child.getNextSibling();
-                        iCodeTop = generateICode(child, iCodeTop);
-                        iCodeTop = addByte((byte) TokenStream.GETPROP, iCodeTop);
-                        itsStackDepth--;
-                    }
-                }
-                break;
-
-            case TokenStream.DELPROP :                
-            case TokenStream.BITAND :                
-            case TokenStream.BITOR :
-            case TokenStream.BITXOR :
-            case TokenStream.LSH :
-            case TokenStream.RSH :
-            case TokenStream.URSH :
-            case TokenStream.ADD :
-            case TokenStream.SUB :
-            case TokenStream.MOD :
-            case TokenStream.DIV :
-            case TokenStream.MUL :
-            case TokenStream.GETELEM :
-                iCodeTop = generateICode(child, iCodeTop);
-                child = child.getNextSibling();
-                iCodeTop = generateICode(child, iCodeTop);
-                iCodeTop = addByte((byte) type, iCodeTop);
-                itsStackDepth--;
-                break;
-
-            case TokenStream.CONVERT : {
-                    iCodeTop = generateICode(child, iCodeTop);
-                    Object toType = node.getProp(Node.TYPE_PROP);
-                    if (toType == ScriptRuntime.NumberClass)
-                        iCodeTop = addByte((byte) TokenStream.POS, iCodeTop);
-                    else
-                        badTree(node);
-                }
-                break;
-
-            case TokenStream.UNARYOP :
-                iCodeTop = generateICode(child, iCodeTop);
-                switch (node.getInt()) {
-                    case TokenStream.VOID :
-                        iCodeTop = addByte((byte) TokenStream.POP, iCodeTop);
-                        iCodeTop = addByte((byte) TokenStream.UNDEFINED, iCodeTop);
-                        break;
-                    case TokenStream.NOT : {
-                            int trueTarget = acquireLabel();
-                            int beyond = acquireLabel();
-                            iCodeTop = addGoto(trueTarget, TokenStream.IFEQ,
-                                                        iCodeTop);
-                            iCodeTop = addByte((byte) TokenStream.TRUE, iCodeTop);
-                            iCodeTop = addGoto(beyond, TokenStream.GOTO, 
-                                                        iCodeTop);
-                            markLabel(trueTarget, iCodeTop);
-                            iCodeTop = addByte((byte) TokenStream.FALSE, iCodeTop);
-                            markLabel(beyond, iCodeTop);
-                        }
-                        break;
-                    case TokenStream.BITNOT :
-                        iCodeTop = addByte((byte) TokenStream.BITNOT, iCodeTop);
-                        break;
-                    case TokenStream.TYPEOF :
-                        iCodeTop = addByte((byte) TokenStream.TYPEOF, iCodeTop);
-                        break;
-                    case TokenStream.SUB :
-                        iCodeTop = addByte((byte) TokenStream.NEG, iCodeTop);
-                        break;
-                    case TokenStream.ADD :
-                        iCodeTop = addByte((byte) TokenStream.POS, iCodeTop);
-                        break;
-                    default:
-                        badTree(node);
-                        break;
-                }
-                break;
-
-            case TokenStream.SETPROP : {
-                    iCodeTop = generateICode(child, iCodeTop);
-                    child = child.getNextSibling();
-                    iCodeTop = generateICode(child, iCodeTop);
-                    String s = (String) node.getProp(Node.SPECIAL_PROP_PROP);
-                    if (s != null) {
-                        if (s.equals("__proto__"))
-                            iCodeTop = addByte((byte) TokenStream.SETPROTO, iCodeTop);
-                        else
-                            if (s.equals("__parent__"))
-                                iCodeTop = addByte((byte) TokenStream.SETPARENT, iCodeTop);
-                            else
-                                badTree(node);
-                    }
-                    else {
-                        child = child.getNextSibling();
-                        iCodeTop = generateICode(child, iCodeTop);
-                        iCodeTop = addByte((byte) TokenStream.SETPROP, iCodeTop);
-                        itsStackDepth -= 2;
-                    }
-                }
-                break;            
-
-            case TokenStream.SETELEM :
-                iCodeTop = generateICode(child, iCodeTop);
-                child = child.getNextSibling();
-                iCodeTop = generateICode(child, iCodeTop);
-                child = child.getNextSibling();
-                iCodeTop = generateICode(child, iCodeTop);
-                iCodeTop = addByte((byte) type, iCodeTop);
-                itsStackDepth -= 2;
-                break;
-
-            case TokenStream.SETNAME :
-                iCodeTop = generateICode(child, iCodeTop);
-                child = child.getNextSibling();
-                iCodeTop = generateICode(child, iCodeTop);
-                iCodeTop = addByte((byte) TokenStream.SETNAME, iCodeTop);                
-                iCodeTop = addString(firstChild.getString(), iCodeTop);
-                itsStackDepth--;
-                break;
-                
-            case TokenStream.TYPEOF : {
-                    String name = node.getString();
-                    int index = -1;
-                    // use typeofname if an activation frame exists
-                    // since the vars all exist there instead of in jregs
-                    if (itsInFunctionFlag && !itsData.itsNeedsActivation)
-                        index = itsVariableTable.getOrdinal(name);
-                    if (index == -1) {                    
-                        iCodeTop = addByte((byte) TokenStream.TYPEOFNAME, iCodeTop);
-                        iCodeTop = addString(name, iCodeTop);
-                    }
-                    else {
-                        iCodeTop = addByte((byte) TokenStream.GETVAR, iCodeTop);
-                        iCodeTop = addByte((byte) index, iCodeTop);
-                        iCodeTop = addByte((byte) TokenStream.TYPEOF, iCodeTop);
-                    }
-                    itsStackDepth++;
-                    if (itsStackDepth > itsData.itsMaxStack)
-                        itsData.itsMaxStack = itsStackDepth;
-                }
-                break;
-
-            case TokenStream.PARENT :
-                iCodeTop = generateICode(child, iCodeTop);
-                iCodeTop = addByte((byte) TokenStream.GETPARENT, iCodeTop);
-                break;
-
-            case TokenStream.GETBASE :
-            case TokenStream.BINDNAME :
-            case TokenStream.NAME :
-            case TokenStream.STRING :
-                iCodeTop = addByte((byte) type, iCodeTop);
-                iCodeTop = addString(node.getString(), iCodeTop);
-                itsStackDepth++;
-                if (itsStackDepth > itsData.itsMaxStack)
-                    itsData.itsMaxStack = itsStackDepth;
-                break;
-
-            case TokenStream.INC :
-            case TokenStream.DEC : {
-                    int childType = child.getType();
-                    switch (childType) {
-                        case TokenStream.GETVAR : {
-                                String name = child.getString();
-                                if (itsData.itsNeedsActivation) {
-                                    iCodeTop = addByte((byte) TokenStream.SCOPE, iCodeTop);
-                                    iCodeTop = addByte((byte) TokenStream.STRING, iCodeTop);
-                                    iCodeTop = addString(name, iCodeTop);
-                                    itsStackDepth += 2;
-                                    if (itsStackDepth > itsData.itsMaxStack)
-                                        itsData.itsMaxStack = itsStackDepth;
-                                    iCodeTop = addByte((byte)
-                                                (type == TokenStream.INC
-                                                    ? TokenStream.PROPINC 
-                                                    : TokenStream.PROPDEC),
-                                                 iCodeTop);
-                                    itsStackDepth--;                                        
-                                }
-                                else {
-                                    iCodeTop = addByte((byte)
-                                                (type == TokenStream.INC
-                                                    ? TokenStream.VARINC
-                                                    : TokenStream.VARDEC),
-                                                iCodeTop);
-                                    int i = itsVariableTable.getOrdinal(name);
-                                    iCodeTop = addByte((byte)i, iCodeTop);
-                                    itsStackDepth++;
-                                    if (itsStackDepth > itsData.itsMaxStack)
-                                        itsData.itsMaxStack = itsStackDepth;
-                                }
-                            }
-                            break;
-                        case TokenStream.GETPROP :
-                        case TokenStream.GETELEM : {
-                                Node getPropChild = child.getFirstChild();
-                                iCodeTop = generateICode(getPropChild,
-                                                              iCodeTop);
-                                getPropChild = getPropChild.getNextSibling();
-                                iCodeTop = generateICode(getPropChild,
-                                                              iCodeTop);
-                                if (childType == TokenStream.GETPROP)
-                                    iCodeTop = addByte((byte)
-                                                    (type == TokenStream.INC
-                                                        ? TokenStream.PROPINC 
-                                                        : TokenStream.PROPDEC),
-                                                    iCodeTop);
-                                else                                                        
-                                    iCodeTop = addByte((byte)
-                                                    (type == TokenStream.INC
-                                                        ? TokenStream.ELEMINC 
-                                                        : TokenStream.ELEMDEC),
-                                                    iCodeTop);
-                                itsStackDepth--;                                        
-                            }
-                            break;
-                        default : {
-                                iCodeTop = addByte((byte)
-                                                    (type == TokenStream.INC 
-                                                        ? TokenStream.NAMEINC 
-                                                        : TokenStream.NAMEDEC),
-                                                    iCodeTop);
-                                iCodeTop = addString(child.getString(), 
-                                                            iCodeTop);
-                                itsStackDepth++;
-                                if (itsStackDepth > itsData.itsMaxStack)
-                                    itsData.itsMaxStack = itsStackDepth;
-                            }
-                            break;
-                    }
-                }
-                break;
-
-            case TokenStream.NUMBER : {
-                double num = node.getDouble();
-                if (num == 0.0) {
-                    iCodeTop = addByte((byte) TokenStream.ZERO, iCodeTop);
-                }
-                else if (num == 1.0) {
-                    iCodeTop = addByte((byte) TokenStream.ONE, iCodeTop);
-                }
-                else {
-                    iCodeTop = addByte((byte) TokenStream.NUMBER, iCodeTop);
-                    iCodeTop = addNumber(num, iCodeTop);
-                }
-                itsStackDepth++;
-                if (itsStackDepth > itsData.itsMaxStack)
-                    itsData.itsMaxStack = itsStackDepth;
-                break;
-            }
-
-            case TokenStream.POP :
-            case TokenStream.POPV :
-                iCodeTop = updateLineNumber(node, iCodeTop);
-            case TokenStream.ENTERWITH :
-                iCodeTop = generateICode(child, iCodeTop);
-                iCodeTop = addByte((byte) type, iCodeTop);
-                itsStackDepth--;
-                break;
-
-            case TokenStream.GETTHIS :
-                iCodeTop = generateICode(child, iCodeTop);
-                iCodeTop = addByte((byte) type, iCodeTop);
-                break;
-                
-            case TokenStream.NEWSCOPE :
-                iCodeTop = addByte((byte) type, iCodeTop);
-                itsStackDepth++;
-                if (itsStackDepth > itsData.itsMaxStack)
-                    itsData.itsMaxStack = itsStackDepth;
-                break;
-
-            case TokenStream.LEAVEWITH :
-                iCodeTop = addByte((byte) type, iCodeTop);
-                break;
-
-            case TokenStream.TRY : {
-                    itsTryDepth++;
-                    if (itsTryDepth > itsData.itsMaxTryDepth)
-                        itsData.itsMaxTryDepth = itsTryDepth;
-                    Node catchTarget = (Node)node.getProp(Node.TARGET_PROP);
-                    Node finallyTarget = (Node)node.getProp(Node.FINALLY_PROP);
-                    if (catchTarget == null) {
-                        iCodeTop = addByte((byte) TokenStream.TRY, iCodeTop);
-                        iCodeTop = addByte((byte)0, iCodeTop);
-                        iCodeTop = addByte((byte)0, iCodeTop);
-                    }
-                    else
-                        iCodeTop = 
-                            addGoto(node, TokenStream.TRY, iCodeTop);
-                    int finallyHandler = 0;
-                    if (finallyTarget != null) {
-                        finallyHandler = acquireLabel();
-                        int theLabel = finallyHandler & 0x7FFFFFFF;
-                        itsLabelTable[theLabel].addFixup(iCodeTop);
-                    }
-                    iCodeTop = addByte((byte)0, iCodeTop);
-                    iCodeTop = addByte((byte)0, iCodeTop);
-                    
-                    Node lastChild = null;
-                    /*
-                        when we encounter the child of the catchTarget, we
-                        set the stackDepth to 1 to account for the incoming
-                        exception object.
-                    */
-                    boolean insertedEndTry = false;
-                    while (child != null) {
-                        if (catchTarget != null && lastChild == catchTarget) {
-                            itsStackDepth = 1;
-                            if (itsStackDepth > itsData.itsMaxStack)
-                                itsData.itsMaxStack = itsStackDepth;
-                        }
-                        /*
-                            When the following child is the catchTarget
-                            (or the finallyTarget if there are no catches),
-                            the current child is the goto at the end of
-                            the try statemets, we need to emit the endtry
-                            before that goto.
-                        */
-                        Node nextSibling = child.getNextSibling();
-                        if (!insertedEndTry && nextSibling != null &&
-                            (nextSibling == catchTarget ||
-                             nextSibling == finallyTarget))
-                        {
-                            iCodeTop = addByte((byte) TokenStream.ENDTRY,
-                                               iCodeTop);
-                            insertedEndTry = true;
-                        }
-                        iCodeTop = generateICode(child, iCodeTop);
-                        lastChild = child;
-                        child = child.getNextSibling();
-                    }
-                    itsStackDepth = 0;
-                    if (finallyTarget != null) {
-                        // normal flow goes around the finally handler stublet
-                        int skippy = acquireLabel();
-                        iCodeTop = 
-                            addGoto(skippy, TokenStream.GOTO, iCodeTop);
-                        // on entry the stack will have the exception object
-                        markLabel(finallyHandler, iCodeTop);
-                        itsStackDepth = 1;
-                        if (itsStackDepth > itsData.itsMaxStack)
-                            itsData.itsMaxStack = itsStackDepth;
-                        int theLocalSlot = itsData.itsMaxLocals++;
-                        iCodeTop = addByte((byte) TokenStream.NEWTEMP, iCodeTop);
-                        iCodeTop = addByte((byte)theLocalSlot, iCodeTop);
-                        iCodeTop = addByte((byte) TokenStream.POP, iCodeTop);
-                        Integer finallyLabel 
-                           = (Integer)(finallyTarget.getProp(Node.LABEL_PROP));
-                        iCodeTop = addGoto(finallyLabel.intValue(), 
-                                         TokenStream.GOSUB, iCodeTop);
-                        iCodeTop = addByte((byte) TokenStream.USETEMP, iCodeTop);
-                        iCodeTop = addByte((byte)theLocalSlot, iCodeTop);
-                        iCodeTop = addByte((byte) TokenStream.JTHROW, iCodeTop);
-                        itsStackDepth = 0;
-                        markLabel(skippy, iCodeTop);
-                    }
-                    itsTryDepth--;
-                }
-                break;
-                
-            case TokenStream.THROW :
-                iCodeTop = updateLineNumber(node, iCodeTop);
-                iCodeTop = generateICode(child, iCodeTop);
-                iCodeTop = addByte((byte) TokenStream.THROW, iCodeTop);
-                itsStackDepth--;
-                break;
-                
-            case TokenStream.ASSERT:
-                iCodeTop = updateLineNumber(node, iCodeTop);
-                if (child != null) 
-                    iCodeTop = generateICode(child, iCodeTop);
-                else {
-                    iCodeTop = addByte((byte) TokenStream.UNDEFINED, iCodeTop);
-                    itsStackDepth++;
-                    if (itsStackDepth > itsData.itsMaxStack)
-                        itsData.itsMaxStack = itsStackDepth;
-                }
-                iCodeTop = addGoto(node, TokenStream.ASSERT, iCodeTop);
-                itsStackDepth--;
-                break;
-                
-            case TokenStream.RETURN :
-                iCodeTop = updateLineNumber(node, iCodeTop);
-                if (child != null) 
-                    iCodeTop = generateICode(child, iCodeTop);
-                else {
-                    iCodeTop = addByte((byte) TokenStream.UNDEFINED, iCodeTop);
-                    itsStackDepth++;
-                    if (itsStackDepth > itsData.itsMaxStack)
-                        itsData.itsMaxStack = itsStackDepth;
-                }
-                iCodeTop = addGoto(node, TokenStream.RETURN, iCodeTop);
-                itsStackDepth--;
-                break;
-                
-            case TokenStream.GETVAR : {
-                    String name = node.getString();
-                    if (itsData.itsNeedsActivation) {
-                        // SETVAR handled this by turning into a SETPROP, but
-                        // we can't do that to a GETVAR without manufacturing
-                        // bogus children. Instead we use a special op to
-                        // push the current scope.
-                        iCodeTop = addByte((byte) TokenStream.SCOPE, iCodeTop);
-                        iCodeTop = addByte((byte) TokenStream.STRING, iCodeTop);
-                        iCodeTop = addString(name, iCodeTop);
-                        itsStackDepth += 2;
-                        if (itsStackDepth > itsData.itsMaxStack)
-                            itsData.itsMaxStack = itsStackDepth;
-                        iCodeTop = addByte((byte) TokenStream.GETPROP, iCodeTop);
-                        itsStackDepth--;
-                    }
-                    else {
-                        int index = itsVariableTable.getOrdinal(name);
-                        iCodeTop = addByte((byte) TokenStream.GETVAR, iCodeTop);
-                        iCodeTop = addByte((byte)index, iCodeTop);
-                        itsStackDepth++;
-                        if (itsStackDepth > itsData.itsMaxStack)
-                            itsData.itsMaxStack = itsStackDepth;
-                    }
-                }
-                break;
-                
-            case TokenStream.SETVAR : {
-                    if (itsData.itsNeedsActivation) {
-                        child.setType(TokenStream.BINDNAME);
-                        node.setType(TokenStream.SETNAME);
-                        iCodeTop = generateICode(node, iCodeTop);
-                    }
-                    else {
-                        String name = child.getString();
-                        child = child.getNextSibling();
-                        iCodeTop = generateICode(child, iCodeTop);
-                        int index = itsVariableTable.getOrdinal(name);
-                        iCodeTop = addByte((byte) TokenStream.SETVAR, iCodeTop);
-                        iCodeTop = addByte((byte)index, iCodeTop);
-                    }
-                }
-                break;
-                
-            case TokenStream.PRIMARY:
-                iCodeTop = addByte((byte) node.getInt(), iCodeTop);
-                itsStackDepth++;
-                if (itsStackDepth > itsData.itsMaxStack)
-                    itsData.itsMaxStack = itsStackDepth;
-                break;
-
-            case TokenStream.ENUMINIT :
-                iCodeTop = generateICode(child, iCodeTop);
-                iCodeTop = addByte((byte) TokenStream.ENUMINIT, iCodeTop);
-                iCodeTop = addLocalRef(node, iCodeTop);
-                itsStackDepth--;
-                break;
-                
-            case TokenStream.ENUMNEXT : {
-                    iCodeTop = addByte((byte) TokenStream.ENUMNEXT, iCodeTop);
-                    Node init = (Node)node.getProp(Node.ENUM_PROP);
-                    iCodeTop = addLocalRef(init, iCodeTop);
-                    itsStackDepth++;
-                    if (itsStackDepth > itsData.itsMaxStack)
-                        itsData.itsMaxStack = itsStackDepth;
-                }                        
-                break;
-                
-            case TokenStream.ENUMDONE :
-                // could release the local here??
-                break;
-                
-            case TokenStream.OBJECT : {
-                    Node regexp = (Node) node.getProp(Node.REGEXP_PROP);
-                    int index = ((Integer)(regexp.getProp(
-                                            Node.REGEXP_PROP))).intValue();
-                    iCodeTop = addByte((byte) TokenStream.OBJECT, iCodeTop);
-                    iCodeTop = addByte((byte)(index >> 8), iCodeTop);
-                    iCodeTop = addByte((byte)(index & 0xff), iCodeTop);
-                    itsStackDepth++;
-                    if (itsStackDepth > itsData.itsMaxStack)
-                        itsData.itsMaxStack = itsStackDepth;
-                }
-                break;
-                
-            default : 
-                badTree(node);
-                break;
-        }
-        return iCodeTop;
-    }
-    
-    private int addLocalRef(Node node, int iCodeTop)
-    {
-        int theLocalSlot;
-        Integer localProp = (Integer)node.getProp(Node.LOCAL_PROP);
-        if (localProp == null) {
-            theLocalSlot = itsData.itsMaxLocals++;
-            node.putProp(Node.LOCAL_PROP, new Integer(theLocalSlot));
-        }
-        else
-            theLocalSlot = localProp.intValue();
-        iCodeTop = addByte((byte)theLocalSlot, iCodeTop);
-        if (theLocalSlot >= itsData.itsMaxLocals)
-            itsData.itsMaxLocals = theLocalSlot + 1;
-        return iCodeTop;            
-    }
-    
-    private int addGoto(Node node, int gotoOp, int iCodeTop)
-    {
-        int targetLabel;
-        if (node.getType() == TokenStream.RETURN || node.getType() == TokenStream.ASSERT) {
-            if (itsEpilogLabel == -1)
-                itsEpilogLabel = acquireLabel();
-            targetLabel = itsEpilogLabel;
-        }
-        else {
-            Node target = (Node)(node.getProp(Node.TARGET_PROP));
-            Object lblObect = target.getProp(Node.LABEL_PROP);
-            if (lblObect == null) {
-                targetLabel = acquireLabel();
-                target.putProp(Node.LABEL_PROP, new Integer(targetLabel));
-            }
-            else
-                targetLabel = ((Integer)lblObect).intValue();
-        }
-        iCodeTop = addGoto(targetLabel, (byte) gotoOp, iCodeTop);
-        return iCodeTop;
-    }
-    
-    private int addGoto(int targetLabel, int gotoOp, int iCodeTop)
-    {
-        int gotoPC = iCodeTop;
-        iCodeTop = addByte((byte) gotoOp, iCodeTop);
-        int theLabel = targetLabel & 0x7FFFFFFF;
-        int targetPC = itsLabelTable[theLabel].getPC();
-        if (targetPC != -1) {
-            short offset = (short)(targetPC - gotoPC);
-            iCodeTop = addByte((byte)(offset >> 8), iCodeTop);
-            iCodeTop = addByte((byte)offset, iCodeTop);
-        }
-        else {
-            itsLabelTable[theLabel].addFixup(gotoPC + 1);
-            iCodeTop = addByte((byte)0, iCodeTop);
-            iCodeTop = addByte((byte)0, iCodeTop);
-        }
-        return iCodeTop;
-    }
-    
-    private final int addByte(byte b, int iCodeTop) {
-        if (itsData.itsICode.length == iCodeTop) {
-            byte[] ba = new byte[iCodeTop * 2];
-            System.arraycopy(itsData.itsICode, 0, ba, 0, iCodeTop);
-            itsData.itsICode = ba;
-        }
-        itsData.itsICode[iCodeTop++] = b;
-        return iCodeTop;
-    }
-    
-    private final int addString(String str, int iCodeTop)
-    {
-        int index = itsData.itsStringTableIndex;
-        if (itsData.itsStringTable.length == index) {
-            String[] sa = new String[index * 2];
-            System.arraycopy(itsData.itsStringTable, 0, sa, 0, index);
-            itsData.itsStringTable = sa;
-        }
-        itsData.itsStringTable[index] = str;
-        itsData.itsStringTableIndex = index + 1;
-
-        iCodeTop = addByte((byte)(index >> 8), iCodeTop);
-        iCodeTop = addByte((byte)(index & 0xFF), iCodeTop);
-        return iCodeTop;
-    }
-    
-    private final int addNumber(double num, int iCodeTop)
-    {
-        int index = itsData.itsNumberTableIndex;
-        if (itsData.itsNumberTable.length == index) {
-            double[] na = new double[index * 2];
-            System.arraycopy(itsData.itsNumberTable, 0, na, 0, index);
-            itsData.itsNumberTable = na;
-        }
-        itsData.itsNumberTable[index] = num;
-        itsData.itsNumberTableIndex = index + 1;
-
-        iCodeTop = addByte((byte)(index >> 8), iCodeTop);
-        iCodeTop = addByte((byte)(index & 0xFF), iCodeTop);
-        return iCodeTop;
-    }
-    
-    private static String getString(String[] theStringTable, byte[] iCode, 
-                                    int pc)
-    {
-        int index = (iCode[pc] << 8) + (iCode[pc + 1] & 0xFF);
-        return theStringTable[index];
-    }
-    
-    private static double getNumber(double[] theNumberTable, byte[] iCode, 
-                                    int pc)
-    {
-        int index = (iCode[pc] << 8) + (iCode[pc + 1] & 0xFF);
-        return theNumberTable[index];
-    }
-    
-    private static int getTarget(byte[] iCode, int pc)
-    {
-        int displacement = (iCode[pc] << 8) + (iCode[pc + 1] & 0xFF);
-        return pc - 1 + displacement;
-    }
-    
-    static PrintWriter out;
-    static {
-        if (printICode) {
-            try {
-                out = new PrintWriter(new FileOutputStream("icode.txt"));
-                out.close();
-            }
-            catch (IOException x) {
-            }
-        }
-    }   
-    
-    private static void dumpICode(InterpreterData theData) {
-        if (printICode) {
-            try {
-                int iCodeLength = theData.itsICodeTop;
-                byte iCode[] = theData.itsICode;
-                
-                out = new PrintWriter(new FileOutputStream("icode.txt", true));
-                out.println("ICode dump, for " + theData.itsName + ", length = " + iCodeLength);
-                out.println("MaxStack = " + theData.itsMaxStack);
-                
-                for (int pc = 0; pc < iCodeLength; ) {
-                    out.print("[" + pc + "] ");
-                    switch ((int)(iCode[pc] & 0xff)) {
-                        case TokenStream.SCOPE :
-                        case TokenStream.GETPROTO :
-                        case TokenStream.GETPARENT :
-                        case TokenStream.GETSCOPEPARENT :
-                        case TokenStream.SETPROTO :
-                        case TokenStream.SETPARENT :
-                        case TokenStream.DELPROP :
-                        case TokenStream.TYPEOF :
-                        case TokenStream.NEWSCOPE :
-                        case TokenStream.ENTERWITH :
-                        case TokenStream.LEAVEWITH :
-                        case TokenStream.ENDTRY :
-                        case TokenStream.THROW :
-                        case TokenStream.JTHROW :
-                        case TokenStream.GETTHIS :
-                        case TokenStream.SETELEM :
-                        case TokenStream.GETELEM :
-                        case TokenStream.SETPROP :
-                        case TokenStream.GETPROP :
-                        case TokenStream.PROPINC :
-                        case TokenStream.PROPDEC :
-                        case TokenStream.ELEMINC :
-                        case TokenStream.ELEMDEC :
-                        case TokenStream.BITNOT :                
-                        case TokenStream.BITAND :                
-                        case TokenStream.BITOR :
-                        case TokenStream.BITXOR :
-                        case TokenStream.LSH :
-                        case TokenStream.RSH :
-                        case TokenStream.URSH :
-                        case TokenStream.NEG :
-                        case TokenStream.POS :
-                        case TokenStream.SUB :
-                        case TokenStream.MUL :
-                        case TokenStream.DIV :
-                        case TokenStream.MOD :
-                        case TokenStream.ADD :
-                        case TokenStream.POPV :
-                        case TokenStream.POP :
-                        case TokenStream.DUP :
-                        case TokenStream.LT :
-                        case TokenStream.GT :
-                        case TokenStream.LE :
-                        case TokenStream.GE :
-                        case TokenStream.IN :
-                        case TokenStream.INSTANCEOF :
-                        case TokenStream.EQ :
-                        case TokenStream.NE :
-                        case TokenStream.SHEQ :
-                        case TokenStream.SHNE :
-                        case TokenStream.ZERO :
-                        case TokenStream.ONE :
-                        case TokenStream.NULL :
-                        case TokenStream.THIS :
-                        case TokenStream.THISFN :
-                        case TokenStream.FALSE :
-                        case TokenStream.TRUE :
-                        case TokenStream.UNDEFINED :
-                        case TokenStream.SOURCEFILE : 
-                            out.println(TokenStream.tokenToName(iCode[pc] & 0xff));
-                            break;
-                        case TokenStream.GOSUB :
-                        case TokenStream.RETURN :
-                        case TokenStream.GOTO :
-                        case TokenStream.IFEQ :
-                        case TokenStream.IFNE : {
-                                int newPC = getTarget(iCode, pc + 1);                    
-                                out.println(
-                                    TokenStream.tokenToName(iCode[pc] & 0xff) +
-                                    " " + newPC);
-                                pc += 2;
-                            }
-                            break;
-                        case TokenStream.TRY : {
-                                int newPC1 = getTarget(iCode, pc + 1);                    
-                                int newPC2 = getTarget(iCode, pc + 3);                    
-                                out.println(
-                                    TokenStream.tokenToName(iCode[pc] & 0xff) +
-                                    " " + newPC1 +
-                                    " " + newPC2);
-                                pc += 4;
-                            }
-                            break;
-                        case TokenStream.RETSUB :                        
-                        case TokenStream.ENUMINIT :
-                        case TokenStream.ENUMNEXT :
-                        case TokenStream.VARINC :
-                        case TokenStream.VARDEC :
-                        case TokenStream.GETVAR :
-                        case TokenStream.SETVAR :
-                        case TokenStream.NEWTEMP :
-                        case TokenStream.USETEMP : {
-                                int slot = (iCode[pc + 1] & 0xFF);
-                                out.println(
-                                    TokenStream.tokenToName(iCode[pc] & 0xff) +
-                                    " " + slot);
-                                pc++;
-                            }
-                            break;
-                        case TokenStream.CALLSPECIAL : {
-                                int line = (iCode[pc + 1] << 8) 
-                                                        | (iCode[pc + 2] & 0xFF);
-                                String name = getString(theData.itsStringTable,
-                                                                  iCode, pc + 3);
-                                int count = (iCode[pc + 5] << 8) | (iCode[pc + 6] & 0xFF);
-                                out.println(
-                                    TokenStream.tokenToName(iCode[pc] & 0xff) +
-                                    " " + count + " " + line + " " + name);
-                                pc += 6;
-                            }
-                            break;
-                        case TokenStream.OBJECT :
-                        case TokenStream.CLOSURE :
-                        case TokenStream.NEW :
-                        case TokenStream.CALL : {
-                                int count = (iCode[pc + 3] << 8) | (iCode[pc + 4] & 0xFF);
-                                out.println(
-                                    TokenStream.tokenToName(iCode[pc] & 0xff) +
-                                    " " + count + " \"" + 
-                                    getString(theData.itsStringTable, iCode, 
-                                              pc + 1) + "\"");
-                                pc += 5;
-                            }
-                            break;
-                        case TokenStream.NUMBER :
-                            out.println(
-                                TokenStream.tokenToName(iCode[pc] & 0xff) + 
-                                " " + getNumber(theData.itsNumberTable,
-                                                iCode, pc + 1));
-                            pc += 2;
-                            break;
-                        case TokenStream.TYPEOFNAME :
-                        case TokenStream.GETBASE :
-                        case TokenStream.BINDNAME :
-                        case TokenStream.SETNAME :
-                        case TokenStream.NAME :
-                        case TokenStream.NAMEINC :
-                        case TokenStream.NAMEDEC :
-                        case TokenStream.STRING :
-                            out.println(
-                                TokenStream.tokenToName(iCode[pc] & 0xff) +
-                                " \"" +
-                                getString(theData.itsStringTable, iCode, pc + 1) +
-                                "\"");
-                            pc += 2;
-                            break;
-                        case TokenStream.LINE : {
-                                int line = (iCode[pc + 1] << 8) | (iCode[pc + 2] & 0xFF);
-                                out.println(
-                                    TokenStream.tokenToName(iCode[pc] & 0xff) + " : " + line);
-                                pc += 2;
-                            }
-                            break;
-                        default :
-                            out.close();
-                            throw new RuntimeException("Unknown icode : "
-                                                    + (iCode[pc] & 0xff)  + " @ pc : " + pc);
-                    }
-                    pc++;
-                }
-                out.close();
-            }
-            catch (IOException x) {}
-        }
-    }
-    
-    private static void createFunctionObject(InterpretedFunction fn, 
-                                             Scriptable scope)
-    {
-        fn.setPrototype(ScriptableObject.getClassPrototype(scope, "Function"));
-        fn.setParentScope(scope);
-        InterpreterData id = fn.itsData;
-        if (id.itsName.length() == 0)
-            return;
-        if ((id.itsFunctionType == FunctionNode.FUNCTION_STATEMENT &&
-             fn.itsClosure == null) ||
-            (id.itsFunctionType == FunctionNode.FUNCTION_EXPRESSION_STATEMENT &&
-             fn.itsClosure != null))
-        {
-            ScriptRuntime.setProp(scope, fn.itsData.itsName, fn, scope);
-        }
-    }
-    
-    public static Object interpret(Context cx, Scriptable scope, 
-                                   Scriptable thisObj, Object[] args, 
-                                   NativeFunction fnOrScript,
-                                   InterpreterData theData)
-        throws JavaScriptException
-    {
-        int i;
-        Object lhs;
-
-        final int maxStack = theData.itsMaxStack;
-        final int maxVars = (fnOrScript.argNames == null) 
-                            ? 0 : fnOrScript.argNames.length;
-        final int maxLocals = theData.itsMaxLocals;
-        final int maxTryDepth = theData.itsMaxTryDepth;
-        
-        final int VAR_SHFT = maxStack; 
-        final int LOCAL_SHFT = VAR_SHFT + maxVars; 
-        final int TRY_SCOPE_SHFT = LOCAL_SHFT + maxLocals;
-
-// stack[0 <= i < VAR_SHFT]: stack data
-// stack[VAR_SHFT <= i < LOCAL_SHFT]: variables
-// stack[LOCAL_SHFT <= i < TRY_SCOPE_SHFT]: used for newtemp/usetemp
-// stack[TRY_SCOPE_SHFT <= i]: try scopes
-// when 0 <= i < LOCAL_SHFT and stack[x] == DBL_MRK, 
-// sDbl[i]  gives the number value
-
-        final Object DBL_MRK = Interpreter.DBL_MRK;
-        
-        Object[] stack = new Object[TRY_SCOPE_SHFT + maxTryDepth];
-        double[] sDbl = new double[TRY_SCOPE_SHFT];
-        int stackTop = -1;
-        byte[] iCode = theData.itsICode;        
-        int pc = 0;
-        int iCodeLength = theData.itsICodeTop;
-        
-        final Scriptable undefined = Undefined.instance;
-        if (maxVars != 0) {
-            int definedArgs = fnOrScript.argCount;
-            if (definedArgs != 0) {
-                if (definedArgs > args.length) { definedArgs = args.length;    }
-                for (i = 0; i != definedArgs; ++i) {
-                    stack[VAR_SHFT + i] = args[i];    
-                }
-            }
-            for (i = definedArgs; i != maxVars; ++i) {
-                stack[VAR_SHFT + i] = undefined;
-            }
-        }
-        
-        if (theData.itsNestedFunctions != null) {
-            for (i = 0; i < theData.itsNestedFunctions.length; i++)
-                createFunctionObject(theData.itsNestedFunctions[i], scope);
-        }        
-
-        Object id;
-        Object rhs, val;
-        double valDbl;
-        boolean valBln;
-
-        int count;
-        int slot;
-                
-        String name = null;
-               
-        Object[] outArgs;
-
-        int lIntValue;
-        long lLongValue;
-        double lDbl;
-        int rIntValue;
-        double rDbl;
-                
-        int[] catchStack = null;
-        int tryStackTop = 0;
-        InterpreterFrame frame = null;
-        
-        if (cx.debugger != null) {
-            frame = new InterpreterFrame(scope, theData, fnOrScript);
-            cx.pushFrame(frame);
-        }
-            
-        if (maxTryDepth != 0) {
-            // catchStack[2 * i]: starting pc of catch block
-            // catchStack[2 * i + 1]: starting pc of finally block
-            catchStack = new int[maxTryDepth * 2];
-        }
-        
-        /* Save the security domain. Must restore upon normal exit. 
-         * If we exit the interpreter loop by throwing an exception,
-         * set cx.interpreterSecurityDomain to null, and require the
-         * catching function to restore it.
-         */
-        Object savedSecurityDomain = cx.interpreterSecurityDomain;
-        cx.interpreterSecurityDomain = theData.securityDomain;
-        Object result = undefined;
-        
-        int pcPrevBranch = pc;
-        final int instructionThreshold = cx.instructionThreshold;
-        // During function call this will be set to -1 so catch can properly
-        // adjust it
-        int instructionCount = cx.instructionCount;
-        // arbitrary number to add to instructionCount when calling 
-        // other functions
-        final int INVOCATION_COST = 100;
-        
-        while (pc < iCodeLength) {
-            try {
-                switch (iCode[pc] & 0xff) {
-                    case TokenStream.ENDTRY :
-                        tryStackTop--;
-                        break;
-                    case TokenStream.TRY :
-                        i = getTarget(iCode, pc + 1);
-                        if (i == pc) i = 0;
-                        catchStack[tryStackTop * 2] = i;
-                        i = getTarget(iCode, pc + 3);
-                        if (i == (pc + 2)) i = 0;
-                        catchStack[tryStackTop * 2 + 1] = i;
-                        stack[TRY_SCOPE_SHFT + tryStackTop] = scope;
-                        ++tryStackTop;
-                        pc += 4;
-                        break;
-                    case TokenStream.GE :
-                        --stackTop;
-                        rhs = stack[stackTop + 1];    
-                        lhs = stack[stackTop];
-                        if (rhs == DBL_MRK || lhs == DBL_MRK) {
-                            rDbl = stack_double(stack, sDbl, stackTop + 1);
-                            lDbl = stack_double(stack, sDbl, stackTop);
-                            valBln = (rDbl == rDbl && lDbl == lDbl 
-                                      && rDbl <= lDbl);
-                        }
-                        else {
-                            valBln = (1 == ScriptRuntime.cmp_LE(rhs, lhs));
-                        }
-                        stack[stackTop] = valBln ? Boolean.TRUE : Boolean.FALSE;
-                        break;
-                    case TokenStream.LE :
-                        --stackTop;
-                        rhs = stack[stackTop + 1];    
-                        lhs = stack[stackTop];
-                        if (rhs == DBL_MRK || lhs == DBL_MRK) {
-                            rDbl = stack_double(stack, sDbl, stackTop + 1);
-                            lDbl = stack_double(stack, sDbl, stackTop);
-                            valBln = (rDbl == rDbl && lDbl == lDbl 
-                                      && lDbl <= rDbl);
-                        }
-                        else {
-                            valBln = (1 == ScriptRuntime.cmp_LE(lhs, rhs));
-                        }
-                        stack[stackTop] = valBln ? Boolean.TRUE : Boolean.FALSE;
-                        break;
-                    case TokenStream.GT :
-                        --stackTop;
-                        rhs = stack[stackTop + 1];    
-                        lhs = stack[stackTop];
-                        if (rhs == DBL_MRK || lhs == DBL_MRK) {
-                            rDbl = stack_double(stack, sDbl, stackTop + 1);
-                            lDbl = stack_double(stack, sDbl, stackTop);
-                            valBln = (rDbl == rDbl && lDbl == lDbl 
-                                      && rDbl < lDbl);
-                        }
-                        else {
-                            valBln = (1 == ScriptRuntime.cmp_LT(rhs, lhs));
-                        }
-                        stack[stackTop] = valBln ? Boolean.TRUE : Boolean.FALSE;
-                        break;
-                    case TokenStream.LT :
-                        --stackTop;
-                        rhs = stack[stackTop + 1];    
-                        lhs = stack[stackTop];
-                        if (rhs == DBL_MRK || lhs == DBL_MRK) {
-                            rDbl = stack_double(stack, sDbl, stackTop + 1);
-                            lDbl = stack_double(stack, sDbl, stackTop);
-                            valBln = (rDbl == rDbl && lDbl == lDbl 
-                                      && lDbl < rDbl);
-                        }
-                        else {
-                            valBln = (1 == ScriptRuntime.cmp_LT(lhs, rhs));
-                        }
-                        stack[stackTop] = valBln ? Boolean.TRUE : Boolean.FALSE;
-                        break;
-                    case TokenStream.IN :
-                        rhs = stack[stackTop];    
-                        if (rhs == DBL_MRK) rhs = doubleWrap(sDbl[stackTop]);
-                        --stackTop;
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        valBln = ScriptRuntime.in(lhs, rhs, scope);
-                        stack[stackTop] = valBln ? Boolean.TRUE : Boolean.FALSE;
-                        break;
-                    case TokenStream.INSTANCEOF :
-                        rhs = stack[stackTop];    
-                        if (rhs == DBL_MRK) rhs = doubleWrap(sDbl[stackTop]);
-                        --stackTop;
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        valBln = ScriptRuntime.instanceOf(scope, lhs, rhs);
-                        stack[stackTop] = valBln ? Boolean.TRUE : Boolean.FALSE;
-                        break;
-                    case TokenStream.EQ :
-                        --stackTop;
-                        valBln = do_eq(stack, sDbl, stackTop);
-                        stack[stackTop] = valBln ? Boolean.TRUE : Boolean.FALSE;
-                        break;
-                    case TokenStream.NE :
-                        --stackTop;
-                        valBln = !do_eq(stack, sDbl, stackTop);
-                        stack[stackTop] = valBln ? Boolean.TRUE : Boolean.FALSE;
-                        break;
-                    case TokenStream.SHEQ :
-                        --stackTop;
-                        valBln = do_sheq(stack, sDbl, stackTop);
-                        stack[stackTop] = valBln ? Boolean.TRUE : Boolean.FALSE;
-                        break;
-                    case TokenStream.SHNE :
-                        --stackTop;
-                        valBln = !do_sheq(stack, sDbl, stackTop);
-                        stack[stackTop] = valBln ? Boolean.TRUE : Boolean.FALSE;
-                        break;
-                    case TokenStream.IFNE :
-                        val = stack[stackTop];
-                        if (val != DBL_MRK) {
-                            valBln = !ScriptRuntime.toBoolean(val);
-                        }
-                        else {
-                            valDbl = sDbl[stackTop];
-                            valBln = !(valDbl == valDbl && valDbl != 0.0);
-                        }
-                        --stackTop;
-                        if (valBln) {
-                            if (instructionThreshold != 0) {
-                                instructionCount += pc + 3 - pcPrevBranch;
-                                if (instructionCount > instructionThreshold) {
-                                    cx.observeInstructionCount
-                                        (instructionCount);
-                                    instructionCount = 0;
-                                }
-                            }
-                            pcPrevBranch = pc = getTarget(iCode, pc + 1);
-                            continue;
-                        }
-                        pc += 2;
-                        break;
-                    case TokenStream.IFEQ :
-                        val = stack[stackTop];
-                        if (val != DBL_MRK) {
-                            valBln = ScriptRuntime.toBoolean(val);
-                        }
-                        else {
-                            valDbl = sDbl[stackTop];
-                            valBln = (valDbl == valDbl && valDbl != 0.0);
-                        }
-                        --stackTop;
-                        if (valBln) {
-                            if (instructionThreshold != 0) {
-                                instructionCount += pc + 3 - pcPrevBranch;
-                                if (instructionCount > instructionThreshold) {
-                                    cx.observeInstructionCount
-                                        (instructionCount);
-                                    instructionCount = 0;
-                                }
-                            }
-                            pcPrevBranch = pc = getTarget(iCode, pc + 1);
-                            continue;
-                        }
-                        pc += 2;
-                        break;
-                    case TokenStream.GOTO :
-                        if (instructionThreshold != 0) {
-                            instructionCount += pc + 3 - pcPrevBranch;
-                            if (instructionCount > instructionThreshold) {
-                                cx.observeInstructionCount(instructionCount);
-                                instructionCount = 0;
-                            }
-                        }
-                        pcPrevBranch = pc = getTarget(iCode, pc + 1);
-                        continue;
-                    case TokenStream.GOSUB :
-                        sDbl[++stackTop] = pc + 3;
-                        if (instructionThreshold != 0) {
-                            instructionCount += pc + 3 - pcPrevBranch;
-                            if (instructionCount > instructionThreshold) {
-                                cx.observeInstructionCount(instructionCount);
-                                instructionCount = 0;
-                            }
-                        }
-                        pcPrevBranch = pc = getTarget(iCode, pc + 1);                                    continue;
-                    case TokenStream.RETSUB :
-                        slot = (iCode[pc + 1] & 0xFF);
-                        if (instructionThreshold != 0) {
-                            instructionCount += pc + 2 - pcPrevBranch;
-                            if (instructionCount > instructionThreshold) {
-                                cx.observeInstructionCount(instructionCount);
-                                instructionCount = 0;
-                            }
-                        }
-                        pcPrevBranch = pc = (int)sDbl[LOCAL_SHFT + slot];
-                        continue;
-                    case TokenStream.POP :
-                        stackTop--;
-                        break;
-                    case TokenStream.DUP :
-                        stack[stackTop + 1] = stack[stackTop];
-                        sDbl[stackTop + 1] = sDbl[stackTop];
-                        stackTop++;
-                        break;
-                    case TokenStream.POPV :
-                        result = stack[stackTop];    
-                        if (result == DBL_MRK) 
-                            result = doubleWrap(sDbl[stackTop]);
-                        --stackTop;
-                        break;
-                    case TokenStream.RETURN :
-                        result = stack[stackTop];    
-                        if (result == DBL_MRK) 
-                            result = doubleWrap(sDbl[stackTop]);
-                        --stackTop;
-                        pc = getTarget(iCode, pc + 1);
-                        break;
-                    case TokenStream.ASSERT :
-                        val = stack[stackTop];
-                        if (val != DBL_MRK) {
-                            valBln = ScriptRuntime.toBoolean(val);
-                        } else {
-                            valDbl = sDbl[stackTop];
-                            valBln = (valDbl == valDbl && valDbl != 0.0);
-                        }
-                        --stackTop;
-                        if (!valBln) {
-                            throw new Error("assertion failed");
-                            //System.exit(-1);
-                        }
-                        pc += 2;
-                        break;
-                    case TokenStream.BITNOT :
-                        rIntValue = stack_int32(stack, sDbl, stackTop);
-                        stack[stackTop] = DBL_MRK;
-                        sDbl[stackTop] = ~rIntValue;
-                        break;
-                    case TokenStream.BITAND :                
-                        rIntValue = stack_int32(stack, sDbl, stackTop);
-                        --stackTop;
-                        lIntValue = stack_int32(stack, sDbl, stackTop);
-                        stack[stackTop] = DBL_MRK;
-                        sDbl[stackTop] = lIntValue & rIntValue;
-                        break;
-                    case TokenStream.BITOR :
-                        rIntValue = stack_int32(stack, sDbl, stackTop);
-                        --stackTop;
-                        lIntValue = stack_int32(stack, sDbl, stackTop);
-                        stack[stackTop] = DBL_MRK;
-                        sDbl[stackTop] = lIntValue | rIntValue;
-                        break;
-                    case TokenStream.BITXOR :
-                        rIntValue = stack_int32(stack, sDbl, stackTop);
-                        --stackTop;
-                        lIntValue = stack_int32(stack, sDbl, stackTop);
-                        stack[stackTop] = DBL_MRK;
-                        sDbl[stackTop] = lIntValue ^ rIntValue;
-                        break;
-                    case TokenStream.LSH :
-                        rIntValue = stack_int32(stack, sDbl, stackTop);
-                        --stackTop;
-                        lIntValue = stack_int32(stack, sDbl, stackTop);
-                        stack[stackTop] = DBL_MRK;
-                        sDbl[stackTop] = lIntValue << rIntValue;
-                        break;
-                    case TokenStream.RSH :
-                        rIntValue = stack_int32(stack, sDbl, stackTop);
-                        --stackTop;
-                        lIntValue = stack_int32(stack, sDbl, stackTop);
-                        stack[stackTop] = DBL_MRK;
-                        sDbl[stackTop] = lIntValue >> rIntValue;
-                        break;
-                    case TokenStream.URSH :
-                        rIntValue = stack_int32(stack, sDbl, stackTop) & 0x1F;
-                        --stackTop;
-                        lLongValue = stack_uint32(stack, sDbl, stackTop);
-                        stack[stackTop] = DBL_MRK;
-                        sDbl[stackTop] = lLongValue >>> rIntValue;
-                        break;
-                    case TokenStream.ADD :
-                        --stackTop;
-                        do_add(stack, sDbl, stackTop);
-                        break;
-                    case TokenStream.SUB :
-                        rDbl = stack_double(stack, sDbl, stackTop);
-                        --stackTop;
-                        lDbl = stack_double(stack, sDbl, stackTop);
-                        stack[stackTop] = DBL_MRK;
-                        sDbl[stackTop] = lDbl - rDbl;
-                        break;
-                    case TokenStream.NEG :
-                        rDbl = stack_double(stack, sDbl, stackTop);
-                        stack[stackTop] = DBL_MRK;
-                        sDbl[stackTop] = -rDbl;
-                        break;
-                    case TokenStream.POS :
-                        rDbl = stack_double(stack, sDbl, stackTop);
-                        stack[stackTop] = DBL_MRK;
-                        sDbl[stackTop] = rDbl;
-                        break;
-                    case TokenStream.MUL :
-                        rDbl = stack_double(stack, sDbl, stackTop);
-                        --stackTop;
-                        lDbl = stack_double(stack, sDbl, stackTop);
-                        stack[stackTop] = DBL_MRK;
-                        sDbl[stackTop] = lDbl * rDbl;
-                        break;
-                    case TokenStream.DIV :
-                        rDbl = stack_double(stack, sDbl, stackTop);
-                        --stackTop;
-                        lDbl = stack_double(stack, sDbl, stackTop);
-                        stack[stackTop] = DBL_MRK;
-                        // Detect the divide by zero or let Java do it ?
-                        sDbl[stackTop] = lDbl / rDbl;
-                        break;
-                    case TokenStream.MOD :
-                        rDbl = stack_double(stack, sDbl, stackTop);
-                        --stackTop;
-                        lDbl = stack_double(stack, sDbl, stackTop);
-                        stack[stackTop] = DBL_MRK;
-                        sDbl[stackTop] = lDbl % rDbl;
-                        break;
-                    case TokenStream.BINDNAME :
-                        stack[++stackTop] = 
-                                ScriptRuntime.bind(scope, 
-                                         getString(theData.itsStringTable, 
-                                                   iCode, pc + 1));
-                        pc += 2;
-                        break;
-                    case TokenStream.GETBASE :
-                        stack[++stackTop] =
-                                ScriptRuntime.getBase(scope, 
-                                         getString(theData.itsStringTable,
-                                                                iCode, pc + 1));
-                        pc += 2;
-                        break;
-                    case TokenStream.SETNAME :
-                        rhs = stack[stackTop];    
-                        if (rhs == DBL_MRK) rhs = doubleWrap(sDbl[stackTop]);
-                        --stackTop;
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        // what about class cast exception here ?
-                        stack[stackTop] = ScriptRuntime.setName
-                            ((Scriptable)lhs, rhs, scope, 
-                             getString(theData.itsStringTable, iCode, pc + 1));
-                        pc += 2;
-                        break;
-                    case TokenStream.DELPROP :
-                        rhs = stack[stackTop];    
-                        if (rhs == DBL_MRK) rhs = doubleWrap(sDbl[stackTop]);
-                        --stackTop;
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        stack[stackTop] = ScriptRuntime.delete(lhs, rhs);
-                        break;
-                    case TokenStream.GETPROP :
-                        name = (String)stack[stackTop];
-                        --stackTop;
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        stack[stackTop] 
-                                = ScriptRuntime.getProp(lhs, name, scope);
-                        break;
-                    case TokenStream.SETPROP :
-                        rhs = stack[stackTop];    
-                        if (rhs == DBL_MRK) rhs = doubleWrap(sDbl[stackTop]);
-                        --stackTop;
-                        name = (String)stack[stackTop];
-                        --stackTop;
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        stack[stackTop] 
-                                = ScriptRuntime.setProp(lhs, name, rhs, scope);
-                        break;
-                    case TokenStream.GETELEM :
-                        id = stack[stackTop];    
-                        if (id == DBL_MRK) id = doubleWrap(sDbl[stackTop]);
-                        --stackTop;
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        stack[stackTop] 
-                                = ScriptRuntime.getElem(lhs, id, scope);
-                        break;
-                    case TokenStream.SETELEM :
-                        rhs = stack[stackTop];    
-                        if (rhs == DBL_MRK) rhs = doubleWrap(sDbl[stackTop]);
-                        --stackTop;
-                        id = stack[stackTop];    
-                        if (id == DBL_MRK) id = doubleWrap(sDbl[stackTop]);
-                        --stackTop;
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        stack[stackTop] 
-                                = ScriptRuntime.setElem(lhs, id, rhs, scope);
-                        break;
-                    case TokenStream.PROPINC :
-                        name = (String)stack[stackTop];
-                        --stackTop;
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        stack[stackTop] 
-                                = ScriptRuntime.postIncrement(lhs, name, scope);
-                        break;
-                    case TokenStream.PROPDEC :
-                        name = (String)stack[stackTop];
-                        --stackTop;
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        stack[stackTop] 
-                                = ScriptRuntime.postDecrement(lhs, name, scope);
-                        break;
-                    case TokenStream.ELEMINC :
-                        rhs = stack[stackTop];    
-                        if (rhs == DBL_MRK) rhs = doubleWrap(sDbl[stackTop]);
-                        --stackTop;
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        stack[stackTop] 
-                           = ScriptRuntime.postIncrementElem(lhs, rhs, scope);
-                        break;
-                    case TokenStream.ELEMDEC :
-                        rhs = stack[stackTop];    
-                        if (rhs == DBL_MRK) rhs = doubleWrap(sDbl[stackTop]);
-                        --stackTop;
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        stack[stackTop] 
-                           = ScriptRuntime.postDecrementElem(lhs, rhs, scope);
-                        break;
-                    case TokenStream.GETTHIS :
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        stack[stackTop] 
-                            = ScriptRuntime.getThis((Scriptable)lhs);
-                        break;
-                    case TokenStream.NEWTEMP :
-                        slot = (iCode[++pc] & 0xFF);
-                        stack[LOCAL_SHFT + slot] = stack[stackTop];
-                        sDbl[LOCAL_SHFT + slot] = sDbl[stackTop];
-                        break;
-                    case TokenStream.USETEMP :
-                        slot = (iCode[++pc] & 0xFF);
-                        ++stackTop;
-                        stack[stackTop] = stack[LOCAL_SHFT + slot];
-                        sDbl[stackTop] = sDbl[LOCAL_SHFT + slot];
-                        break;
-                    case TokenStream.CALLSPECIAL :
-                        if (instructionThreshold != 0) {
-                            instructionCount += INVOCATION_COST;
-                            cx.instructionCount = instructionCount;
-                            instructionCount = -1;
-                        }
-                        int lineNum = (iCode[pc + 1] << 8) 
-                                      | (iCode[pc + 2] & 0xFF);   
-                        name = getString(theData.itsStringTable, iCode, pc + 3);
-                        count = (iCode[pc + 5] << 8) | (iCode[pc + 6] & 0xFF);
-                        outArgs = new Object[count];
-                        for (i = count - 1; i >= 0; i--) {
-                            val = stack[stackTop];    
-                            if (val == DBL_MRK) 
-                                val = doubleWrap(sDbl[stackTop]);
-                            outArgs[i] = val;
-                            --stackTop;
-                        }
-                        rhs = stack[stackTop];    
-                        if (rhs == DBL_MRK) rhs = doubleWrap(sDbl[stackTop]);
-                        --stackTop;
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        stack[stackTop] = ScriptRuntime.callSpecial(
-                                            cx, lhs, rhs, outArgs, 
-                                            thisObj, scope, name, lineNum);
-                        pc += 6;
-                        instructionCount = cx.instructionCount;
-                        break;
-                    case TokenStream.CALL :
-                        if (instructionThreshold != 0) {
-                            instructionCount += INVOCATION_COST;
-                            cx.instructionCount = instructionCount;
-                            instructionCount = -1;
-                        }
-                        cx.instructionCount = instructionCount;
-                        count = (iCode[pc + 3] << 8) | (iCode[pc + 4] & 0xFF);
-                        outArgs = new Object[count];
-                        for (i = count - 1; i >= 0; i--) {
-                            val = stack[stackTop];    
-                            if (val == DBL_MRK) 
-                                val = doubleWrap(sDbl[stackTop]);
-                            outArgs[i] = val;
-                            --stackTop;
-                        }
-                        rhs = stack[stackTop];    
-                        if (rhs == DBL_MRK) rhs = doubleWrap(sDbl[stackTop]);
-                        --stackTop;
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        if (lhs == undefined) {
-                            lhs = getString(theData.itsStringTable, iCode, 
-                                            pc + 1);
-                        }
-                        Scriptable calleeScope = scope;
-                        if (theData.itsNeedsActivation) {
-                            calleeScope = ScriptableObject.
-                                getTopLevelScope(scope);
-                        }
-                        stack[stackTop] = ScriptRuntime.call(cx, lhs, rhs, 
-                                                             outArgs, 
-                                                             calleeScope);
-                        pc += 4;                                                                         instructionCount = cx.instructionCount;
-                        break;
-                    case TokenStream.NEW :
-                        if (instructionThreshold != 0) {
-                            instructionCount += INVOCATION_COST;
-                            cx.instructionCount = instructionCount;
-                            instructionCount = -1;
-                        }
-                        count = (iCode[pc + 3] << 8) | (iCode[pc + 4] & 0xFF);
-                        outArgs = new Object[count];
-                        for (i = count - 1; i >= 0; i--) {
-                            val = stack[stackTop];    
-                            if (val == DBL_MRK) 
-                                val = doubleWrap(sDbl[stackTop]);
-                            outArgs[i] = val;
-                            --stackTop;
-                        }
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        if (lhs == undefined && 
-                            (iCode[pc+1] << 8) + (iCode[pc+2] & 0xFF) != -1) 
-                        {
-                            // special code for better error message for call 
-                            //  to undefined
-                            lhs = getString(theData.itsStringTable, iCode, 
-                                            pc + 1);
-                        }
-                        stack[stackTop] = ScriptRuntime.newObject(cx, lhs, 
-                                                                  outArgs, 
-                                                                  scope);
-                        pc += 4;                                                                         instructionCount = cx.instructionCount;
-                        break;
-                    case TokenStream.TYPEOF :
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        stack[stackTop] = ScriptRuntime.typeof(lhs);
-                        break;
-                    case TokenStream.TYPEOFNAME :
-                        name = getString(theData.itsStringTable, iCode, pc + 1);
-                        stack[++stackTop] 
-                                    = ScriptRuntime.typeofName(scope, name);
-                        pc += 2;
-                        break;
-                    case TokenStream.STRING :
-                        stack[++stackTop] = getString(theData.itsStringTable,
-                                                                iCode, pc + 1);
-                        pc += 2;
-                        break;
-                    case TokenStream.NUMBER :
-                        ++stackTop;
-                        stack[stackTop] = DBL_MRK;
-                        sDbl[stackTop] = getNumber(theData.itsNumberTable,
-                                                   iCode, pc + 1);
-                        pc += 2;
-                        break;
-                    case TokenStream.NAME :
-                        stack[++stackTop] = ScriptRuntime.name(scope,
-                                       getString(theData.itsStringTable,
-                                                                iCode, pc + 1));
-                        pc += 2;
-                        break;
-                    case TokenStream.NAMEINC :
-                        stack[++stackTop] = ScriptRuntime.postIncrement(scope,
-                                       getString(theData.itsStringTable,
-                                                                iCode, pc + 1));
-                        pc += 2;
-                        break;
-                    case TokenStream.NAMEDEC :
-                        stack[++stackTop] = ScriptRuntime.postDecrement(scope,
-                                       getString(theData.itsStringTable,
-                                                                iCode, pc + 1));
-                        pc += 2;
-                        break;
-                    case TokenStream.SETVAR :
-                        slot = (iCode[++pc] & 0xFF);
-                        stack[VAR_SHFT + slot] = stack[stackTop];
-                        sDbl[VAR_SHFT + slot] = sDbl[stackTop];
-                        break;
-                    case TokenStream.GETVAR :
-                        slot = (iCode[++pc] & 0xFF);
-                        ++stackTop;
-                        stack[stackTop] = stack[VAR_SHFT + slot];
-                        sDbl[stackTop] = sDbl[VAR_SHFT + slot];
-                        break;
-                    case TokenStream.VARINC :
-                        slot = (iCode[++pc] & 0xFF);
-                        ++stackTop;
-                        stack[stackTop] = stack[VAR_SHFT + slot];
-                        sDbl[stackTop] = sDbl[VAR_SHFT + slot];
-                        stack[VAR_SHFT + slot] = DBL_MRK;
-                        sDbl[VAR_SHFT + slot] 
-                            = stack_double(stack, sDbl, stackTop) + 1.0;
-                        break;
-                    case TokenStream.VARDEC :
-                        slot = (iCode[++pc] & 0xFF);
-                        ++stackTop;
-                        stack[stackTop] = stack[VAR_SHFT + slot];
-                        sDbl[stackTop] = sDbl[VAR_SHFT + slot];
-                        stack[VAR_SHFT + slot] = DBL_MRK;
-                        sDbl[VAR_SHFT + slot] 
-                            = stack_double(stack, sDbl, stackTop) - 1.0;
-                        break;
-                    case TokenStream.ZERO :
-                        ++stackTop;
-                        stack[stackTop] = DBL_MRK;
-                        sDbl[stackTop] = 0;
-                        break;
-                    case TokenStream.ONE :
-                        ++stackTop;
-                        stack[stackTop] = DBL_MRK;
-                        sDbl[stackTop] = 1;
-                        break;
-                    case TokenStream.NULL :
-                        stack[++stackTop] = null;
-                        break;
-                    case TokenStream.THIS :
-                        stack[++stackTop] = thisObj;
-                        break;
-                    case TokenStream.THISFN :
-                        stack[++stackTop] = fnOrScript;
-                        break;
-                    case TokenStream.FALSE :
-                        stack[++stackTop] = Boolean.FALSE;
-                        break;
-                    case TokenStream.TRUE :
-                        stack[++stackTop] = Boolean.TRUE;
-                        break;
-                    case TokenStream.UNDEFINED :
-                        stack[++stackTop] = Undefined.instance;
-                        break;
-                    case TokenStream.THROW :
-                        result = stack[stackTop];
-                        if (result == DBL_MRK) 
-                            result = doubleWrap(sDbl[stackTop]);
-                        --stackTop;
-                        throw new JavaScriptException(result);
-                    case TokenStream.JTHROW :
-                        result = stack[stackTop];
-                        // No need to check for DBL_MRK: result is Exception
-                        --stackTop;
-                        if (result instanceof JavaScriptException)
-                            throw (JavaScriptException)result;
-                        else
-                            throw (RuntimeException)result;
-                    case TokenStream.ENTERWITH :
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        --stackTop;
-                        scope = ScriptRuntime.enterWith(lhs, scope);
-                        break;
-                    case TokenStream.LEAVEWITH :
-                        scope = ScriptRuntime.leaveWith(scope);
-                        break;
-                    case TokenStream.NEWSCOPE :
-                        stack[++stackTop] = ScriptRuntime.newScope();
-                        break;
-                    case TokenStream.ENUMINIT :
-                        slot = (iCode[++pc] & 0xFF);
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        --stackTop;
-                        stack[LOCAL_SHFT + slot] 
-                            = ScriptRuntime.initEnum(lhs, scope);
-                        break;
-                    case TokenStream.ENUMNEXT :
-                        slot = (iCode[++pc] & 0xFF);
-                        val = stack[LOCAL_SHFT + slot];    
-                        ++stackTop;
-                        stack[stackTop] = ScriptRuntime.
-                            nextEnum((Enumeration)val);
-                        break;
-                    case TokenStream.GETPROTO :
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        stack[stackTop] = ScriptRuntime.getProto(lhs, scope);
-                        break;
-                    case TokenStream.GETPARENT :
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        stack[stackTop] = ScriptRuntime.getParent(lhs);
-                        break;
-                    case TokenStream.GETSCOPEPARENT :
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        stack[stackTop] = ScriptRuntime.getParent(lhs, scope);
-                        break;
-                    case TokenStream.SETPROTO :
-                        rhs = stack[stackTop];    
-                        if (rhs == DBL_MRK) rhs = doubleWrap(sDbl[stackTop]);
-                        --stackTop;
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        stack[stackTop]
-                                = ScriptRuntime.setProto(lhs, rhs, scope);
-                        break;
-                    case TokenStream.SETPARENT :
-                        rhs = stack[stackTop];    
-                        if (rhs == DBL_MRK) rhs = doubleWrap(sDbl[stackTop]);
-                        --stackTop;
-                        lhs = stack[stackTop];    
-                        if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
-                        stack[stackTop]
-                                = ScriptRuntime.setParent(lhs, rhs, scope);
-                        break;
-                    case TokenStream.SCOPE :
-                        stack[++stackTop] = scope;
-                        break;
-                    case TokenStream.CLOSURE :
-                        i = (iCode[pc + 1] << 8) | (iCode[pc + 2] & 0xFF);
-                        stack[++stackTop] 
-                            = new InterpretedFunction(
-                                    theData.itsNestedFunctions[i],
-                                    scope, cx);
-                        createFunctionObject(
-                              (InterpretedFunction)stack[stackTop], scope);
-                        pc += 2;
-                        break;
-                    case TokenStream.OBJECT :
-                        i = (iCode[pc + 1] << 8) | (iCode[pc + 2] & 0xFF);                    
-                        stack[++stackTop] = theData.itsRegExpLiterals[i];
-                        pc += 2;
-                        break;
-                    case TokenStream.SOURCEFILE :    
-                        cx.interpreterSourceFile = theData.itsSourceFile;
-                        break;
-                    case TokenStream.LINE :    
-                    case TokenStream.BREAKPOINT :
-                        i = (iCode[pc + 1] << 8) | (iCode[pc + 2] & 0xFF);                    
-                        cx.interpreterLine = i;
-                        if (frame != null)
-                            frame.setLineNumber(i);
-                        if ((iCode[pc] & 0xff) == TokenStream.BREAKPOINT ||
-                            cx.inLineStepMode) 
-                        {
-                            cx.getDebuggableEngine().
-                                getDebugger().handleBreakpointHit(cx);
-                        }
-                        pc += 2;
-                        break;
-                    default :
-                        dumpICode(theData);
-                        throw new RuntimeException("Unknown icode : "
-                                     + (iCode[pc] & 0xff) + " @ pc : " + pc);
-                }
-                pc++;
-            }
-            catch (Throwable ex) {
-                cx.interpreterSecurityDomain = null;
-            
-                if (instructionThreshold != 0) {
-                    if (instructionCount < 0) {
-                        // throw during function call
-                        instructionCount = cx.instructionCount;
-                    }
-                    else {
-                        // throw during any other operation
-                        instructionCount += pc - pcPrevBranch;
-                        cx.instructionCount = instructionCount;
-                    }
-                }
-
-                final int SCRIPT_THROW = 0, ECMA = 1, RUNTIME = 2, OTHER = 3;
-
-                int exType;
-                Object errObj; // Object seen by catch
-                if (ex instanceof JavaScriptException) {
-                    errObj = ScriptRuntime.
-                        unwrapJavaScriptException((JavaScriptException)ex);
-                    exType = SCRIPT_THROW;
-                }
-                else if (ex instanceof EcmaError) {
-                    // an offical ECMA error object,
-                    errObj = ((EcmaError)ex).getErrorObject();
-                    exType = ECMA;
-                }
-                else if (ex instanceof RuntimeException) {
-                    errObj = ex;
-                    exType = RUNTIME;
-                }
-                else {
-                    errObj = ex; // Error instance
-                    exType = OTHER;
-                }
-
-                if (exType != OTHER && cx.debugger != null) {
-                    cx.debugger.handleExceptionThrown(cx, errObj);
-                }
-
-                boolean rethrow = true;
-                if (exType != OTHER && tryStackTop > 0) {
-                    --tryStackTop;
-                    if (exType == SCRIPT_THROW || exType == ECMA) {
-                        // Check for catch only for 
-                        // JavaScriptException and EcmaError
-                        pc = catchStack[tryStackTop * 2];
-                        if (pc != 0) {
-                            // Has catch block
-                            rethrow = false;
-                        }
-                    }
-                    if (rethrow) {
-                        pc = catchStack[tryStackTop * 2 + 1];
-                        if (pc != 0) {
-                            // has finally block
-                            rethrow = false;
-                            errObj = ex;
-                        }
-                    }
-                }
-
-                if (rethrow) {
-                    if (frame != null)
-                        cx.popFrame();
-                    
-                    if (exType == SCRIPT_THROW)
-                        throw (JavaScriptException)ex;
-                    if (exType == ECMA || exType == RUNTIME) 
-                        throw (RuntimeException)ex;
-                    throw (Error)ex;
-                }
-            
-                // We caught an exception,
-
-                // Notify instruction observer if necessary
-                // and point pcPrevBranch to start of catch/finally block
-                if (instructionThreshold != 0) {
-                    if (instructionCount > instructionThreshold) {
-                        // Note: this can throw Error 
-                        cx.observeInstructionCount(instructionCount);
-                        instructionCount = 0;
-                    }
-                }
-                pcPrevBranch = pc;
-
-                // prepare stack and restore this function's security domain.
-                scope = (Scriptable)stack[TRY_SCOPE_SHFT + tryStackTop];
-                stackTop = 0;
-                stack[0] = errObj;
-                cx.interpreterSecurityDomain = theData.securityDomain;
-            }
-        }
-        cx.interpreterSecurityDomain = savedSecurityDomain;
-        if (frame != null)
-            cx.popFrame();
-
-        if (instructionThreshold != 0) {
-            if (instructionCount > instructionThreshold) {
-                cx.observeInstructionCount(instructionCount);
-                instructionCount = 0;
-            }
-            cx.instructionCount = instructionCount;
-        }
-
-        return result;    
-    }
-    
-    private static Object doubleWrap(double x) {
-        return new Double(x);
-    }
-
-    private static int stack_int32(Object[] stack, double[] stackDbl, int i) {
-        Object x = stack[i];
-        return (x != DBL_MRK)
-            ? ScriptRuntime.toInt32(x)
-            : ScriptRuntime.toInt32(stackDbl[i]);
-    }
-    
-    private static long stack_uint32(Object[] stack, double[] stackDbl, int i) {
-        Object x = stack[i];
-        return (x != DBL_MRK)
-            ? ScriptRuntime.toUint32(x)
-            : ScriptRuntime.toUint32(stackDbl[i]);
-    }
-    
-    private static double stack_double(Object[] stack, double[] stackDbl, 
-                                       int i) 
-    {
-        Object x = stack[i];
-        return (x != DBL_MRK) ? ScriptRuntime.toNumber(x) : stackDbl[i];
-    }
-    
-    private static void do_add(Object[] stack, double[] stackDbl, int stackTop)
-    {
-        Object rhs = stack[stackTop + 1];    
-        Object lhs = stack[stackTop];
-        if (rhs == DBL_MRK) {
-            double rDbl = stackDbl[stackTop + 1];
-            if (lhs == DBL_MRK) {
-                stackDbl[stackTop] += rDbl;
-            }
-            else {
-                do_add(lhs, rDbl, stack, stackDbl, stackTop, true);
-            }
-        }
-        else if (lhs == DBL_MRK) {
-            do_add(rhs, stackDbl[stackTop], stack, stackDbl, stackTop, false);
-        }
-        else {
-            if (lhs instanceof Scriptable)
-                lhs = ((Scriptable) lhs).getDefaultValue(null);
-            if (rhs instanceof Scriptable)
-                rhs = ((Scriptable) rhs).getDefaultValue(null);
-            if (lhs instanceof String || rhs instanceof String) {
-                stack[stackTop] = ScriptRuntime.toString(lhs)
-                                   + ScriptRuntime.toString(rhs);
-            }
-            else {
-                double lDbl = (lhs instanceof Number)
-                    ? ((Number)lhs).doubleValue() : ScriptRuntime.toNumber(lhs);
-                double rDbl = (rhs instanceof Number)
-                    ? ((Number)rhs).doubleValue() : ScriptRuntime.toNumber(rhs);
-                stack[stackTop] = DBL_MRK;
-                stackDbl[stackTop] = lDbl + rDbl;
-            }
-        }
-    }
-    
-    // x + y when x is Number, see 
-    private static void do_add
-        (Object lhs, double rDbl, 
-         Object[] stack, double[] stackDbl, int stackTop, 
-         boolean left_right_order) 
-    {
-        if (lhs instanceof Scriptable) {
-            if (lhs == Undefined.instance) { lhs = ScriptRuntime.NaNobj; }
-            lhs = ((Scriptable)lhs).getDefaultValue(null);
-        }
-        if (lhs instanceof String) {
-            if (left_right_order) {
-                stack[stackTop] = (String)lhs + ScriptRuntime.toString(rDbl);
-            }
-            else {
-                stack[stackTop] = ScriptRuntime.toString(rDbl) + (String)lhs;
-            }
-        }
-        else {
-            double lDbl = (lhs instanceof Number) 
-                ? ((Number)lhs).doubleValue() : ScriptRuntime.toNumber(lhs);
-            stack[stackTop] = DBL_MRK;
-            stackDbl[stackTop] = lDbl + rDbl;
-        }
-    }
-
-
-    
-    private static boolean do_eq(Object[] stack, double[] stackDbl,
-                                 int stackTop)
-    {
-        boolean result;
-        Object rhs = stack[stackTop + 1];    
-        Object lhs = stack[stackTop];
-        if (rhs == DBL_MRK) {
-            if (lhs == DBL_MRK) {
-                result = (stackDbl[stackTop] == stackDbl[stackTop + 1]);
-            }
-            else {
-                result = do_eq(stackDbl[stackTop + 1], lhs);
-            }
-        }
-        else {
-            if (lhs == DBL_MRK) {
-                result = do_eq(stackDbl[stackTop], rhs);
-            }
-            else {
-                result = ScriptRuntime.eq(lhs, rhs);
-            }
-        }
-        return result;
-    }
-    
-// Optimized version of ScriptRuntime.eq if x is a Number    
-    private static boolean do_eq(double x, Object y) {
-        for (;;) {
-            if (y instanceof Number) {
-                return x == ((Number) y).doubleValue();
-            }
-            if (y instanceof String) {
-                return x == ScriptRuntime.toNumber((String)y);
-            }
-            if (y instanceof Boolean) {
-                return x == (((Boolean)y).booleanValue() ? 1 : 0);
-            }
-            if (y instanceof Scriptable) {
-                if (y == Undefined.instance) { return false; }
-                y = ScriptRuntime.toPrimitive(y);
-                continue;
-            }
-            return false;
-        }
-    }
-
-    private static boolean do_sheq(Object[] stack, double[] stackDbl,
-                                   int stackTop)
-    {
-        boolean result;
-        Object rhs = stack[stackTop + 1];    
-        Object lhs = stack[stackTop];
-        if (rhs == DBL_MRK) {
-            double rDbl = stackDbl[stackTop + 1];
-            if (lhs == DBL_MRK) {
-                result = (stackDbl[stackTop] == rDbl);
-            }
-            else {
-                result = (lhs instanceof Number);
-                if (result) {
-                    result = (((Number)lhs).doubleValue() == rDbl);
-                }
-            }
-        }
-        else if (rhs instanceof Number) {
-            double rDbl = ((Number)rhs).doubleValue();
-            if (lhs == DBL_MRK) {
-                result = (stackDbl[stackTop] == rDbl);
-            }
-            else {
-                result = (lhs instanceof Number);
-                if (result) {
-                    result = (((Number)lhs).doubleValue() == rDbl);
-                }
-            }
-        }
-        else {
-            result = ScriptRuntime.shallowEq(lhs, rhs);
-        }
-        return result;
-    }
-    
-    private int version;
-    private boolean inLineStepMode;
-    private StringBuffer debugSource;
-
-    private static final Object DBL_MRK = new Object();
-}
diff --git a/src/org/mozilla/javascript/InterpreterData.java b/src/org/mozilla/javascript/InterpreterData.java
deleted file mode 100644
index cdf4e45..0000000
--- a/src/org/mozilla/javascript/InterpreterData.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * The contents of this file are subject to the Netscape Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/NPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is Rhino code, released
- * May 6, 1999.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation.  Portions created by Netscape are
- * Copyright (C) 1997-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s): 
- * Norris Boyd
- * Roger Lawrence
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU Public License (the "GPL"), in which case the
- * provisions of the GPL are applicable instead of those above.
- * If you wish to allow use of your version of this file only
- * under the terms of the GPL and not to allow others to use your
- * version of this file under the NPL, indicate your decision by
- * deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL.  If you do not delete
- * the provisions above, a recipient may use your version of this
- * file under either the NPL or the GPL.
- */
-
-package org.mozilla.javascript;
-
-import java.util.Vector;
-
-class InterpreterData {
-    
-    static final int INITIAL_MAX_ICODE_LENGTH = 1024;
-    static final int INITIAL_STRINGTABLE_SIZE = 64;
-    static final int INITIAL_NUMBERTABLE_SIZE = 64;
-    
-    InterpreterData(int lastICodeTop, int lastStringTableIndex, 
-                    int lastNumberTableIndex, Object securityDomain,
-                    boolean useDynamicScope, boolean checkThis)
-    {
-        itsICodeTop = lastICodeTop == 0 
-                      ? INITIAL_MAX_ICODE_LENGTH
-                      : lastICodeTop * 2;
-        itsICode = new byte[itsICodeTop];
-
-        itsStringTable = new String[lastStringTableIndex == 0
-                                    ? INITIAL_STRINGTABLE_SIZE
-                                    : lastStringTableIndex * 2];
-
-        itsNumberTable = new double[lastNumberTableIndex == 0
-                                    ? INITIAL_NUMBERTABLE_SIZE
-                                    : lastNumberTableIndex * 2];
-        
-        itsUseDynamicScope = useDynamicScope;
-        itsCheckThis = checkThis;
-        if (securityDomain == null)
-            Context.checkSecurityDomainRequired();
-        this.securityDomain = securityDomain;
-    }
-    
-    public boolean placeBreakpoint(int line) { // XXX throw exn?
-        int offset = getOffset(line);
-        if (offset != -1 && (itsICode[offset] == (byte)TokenStream.LINE ||
-                             itsICode[offset] == (byte)TokenStream.BREAKPOINT))
-        {
-            itsICode[offset] = (byte) TokenStream.BREAKPOINT;
-            return true;
-        }
-        return false;
-    }
-    
-    public boolean removeBreakpoint(int line) {
-        int offset = getOffset(line);
-        if (offset != -1 && itsICode[offset] == (byte) TokenStream.BREAKPOINT)
-        {
-            itsICode[offset] = (byte) TokenStream.LINE;
-            return true;
-        }
-        return false;
-    }
-    
-    private int getOffset(int line) {
-        int offset = itsLineNumberTable.getInt(line, -1);
-        if (0 <= offset && offset <= itsICode.length) {
-            return offset;
-        }
-        return -1;
-    }    
-    
-    String itsName;
-    String itsSource;
-    String itsSourceFile;
-    boolean itsNeedsActivation;
-    boolean itsFromEvalCode;
-    boolean itsUseDynamicScope;
-    boolean itsCheckThis;
-    byte itsFunctionType;
-
-    String[] itsStringTable;
-    int itsStringTableIndex;
-
-    double[] itsNumberTable;
-    int itsNumberTableIndex;
-    
-    InterpretedFunction[] itsNestedFunctions;
-    
-    Object[] itsRegExpLiterals;
-
-    byte[] itsICode;
-    int itsICodeTop;
-    
-    int itsMaxLocals;
-    int itsMaxArgs;
-    int itsMaxStack;
-    int itsMaxTryDepth;
-    
-    UintMap itsLineNumberTable;
-
-    Object securityDomain;
-}
diff --git a/src/org/mozilla/javascript/InterpreterFrame.java b/src/org/mozilla/javascript/InterpreterFrame.java
deleted file mode 100644
index 3df4fce..0000000
--- a/src/org/mozilla/javascript/InterpreterFrame.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * The contents of this file are subject to the Netscape Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/NPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is Rhino code, released
- * May 6, 1999.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation.  Portions created by Netscape are
- * Copyright (C) 1997-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s): 
- * Norris Boyd
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU Public License (the "GPL"), in which case the
- * provisions of the GPL are applicable instead of those above.
- * If you wish to allow use of your version of this file only
- * under the terms of the GPL and not to allow others to use your
- * version of this file under the NPL, indicate your decision by
- * deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL.  If you do not delete
- * the provisions above, a recipient may use your version of this
- * file under either the NPL or the GPL.
- */
-
-package org.mozilla.javascript;
-
-import java.util.Vector;
-
-import org.mozilla.javascript.debug.*;
-
-class InterpreterFrame implements DebugFrame {
-    
-    InterpreterFrame(Scriptable scope, InterpreterData data, Scriptable obj) {
-        this.scope = scope;
-        this.data = data;
-        this.lineNumber = -1;
-        this.obj = obj;
-    }
-
-    public Scriptable getVariableObject() {
-        return scope;
-    }
-    
-    public String getSourceName() {
-        return data.itsSourceFile;
-    }
-    
-    public void setLineNumber(int lineNumber) {
-        this.lineNumber = lineNumber;
-    }
-    
-    public int getLineNumber() {
-        return lineNumber;
-    }
-    
-    public DebuggableScript getScript() {
-        if (obj instanceof DebuggableScript)
-            return (DebuggableScript) obj;
-        return null;
-    }
-    
-    private Scriptable scope;
-    private InterpreterData data;
-    private Scriptable obj;
-    private int lineNumber;
-}
diff --git a/src/org/mozilla/javascript/Invoker.java b/src/org/mozilla/javascript/Invoker.java
deleted file mode 100644
index 1d877d1..0000000
--- a/src/org/mozilla/javascript/Invoker.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * The contents of this file are subject to the Netscape Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/NPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is Rhino code, released
- * May 6, 1999.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation.  Portions created by Netscape are
- * Copyright (C) 1997-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- * Norris Boyd
- * David C. Navas
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU Public License (the "GPL"), in which case the
- * provisions of the GPL are applicable instead of those above.
- * If you wish to allow use of your version of this file only
- * under the terms of the GPL and not to allow others to use your
- * version of this file under the NPL, indicate your decision by
- * deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL.  If you do not delete
- * the provisions above, a recipient may use your version of this
- * file under either the NPL or the GPL.
- */
-
-package org.mozilla.javascript;
-
-import java.lang.reflect.Method;
-
-/**
- * Avoid cost of java.lang.reflect.Method.invoke() by compiling a class to
- * perform the method call directly.
- */
-public abstract class Invoker {
-
-    public abstract Object invoke(Object that, Object [] args);
-
-    /** Factory method to get invoker for given method */
-    public Invoker createInvoker(Method method, Class[] types) {
-        return null;
-    }
-
-}
diff --git a/src/org/mozilla/javascript/JavaMembers.java b/src/org/mozilla/javascript/JavaMembers.java
deleted file mode 100644
index fbe225c..0000000
--- a/src/org/mozilla/javascript/JavaMembers.java
+++ /dev/null
@@ -1,591 +0,0 @@
-/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * The contents of this file are subject to the Netscape Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/NPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is Rhino code, released
- * May 6, 1999.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation.  Portions created by Netscape are
- * Copyright (C) 1997-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s): 
- * Norris Boyd
- * Frank Mitchell
- * Mike Shaver
- * Kurt Westerfeld
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU Public License (the "GPL"), in which case the
- * provisions of the GPL are applicable instead of those above.
- * If you wish to allow use of your version of this file only
- * under the terms of the GPL and not to allow others to use your
- * version of this file under the NPL, indicate your decision by
- * deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL.  If you do not delete
- * the provisions above, a recipient may use your version of this
- * file under either the NPL or the GPL.
- */
-
-package org.mozilla.javascript;
-
-import java.lang.reflect.*;
-import java.util.Hashtable;
-import java.util.Enumeration;
-
-/**
- *
- * @author Mike Shaver
- * @author Norris Boyd
- * @see NativeJavaObject
- * @see NativeJavaClass
- */
-class JavaMembers {
-
-    JavaMembers(Scriptable scope, Class cl) {
-        this.members = new Hashtable(23);
-        this.staticMembers = new Hashtable(7);
-        this.cl = cl;
-        reflect(scope, cl);
-    }
-
-    boolean has(String name, boolean isStatic) {
-        Hashtable ht = isStatic ? staticMembers : members;
-        Object obj = ht.get(name);
-        if (obj != null) {
-            return true;
-        } else {
-            Member member = this.findExplicitFunction(name, isStatic);
-            return member != null;
-        }
-    }
-
-    Object get(Scriptable scope, String name, Object javaObject,
-               boolean isStatic)
-    {
-        Hashtable ht = isStatic ? staticMembers : members;
-        Object member = ht.get(name);
-        if (!isStatic && member == null) {
-            // Try to get static member from instance (LC3)
-            member = staticMembers.get(name);
-        }
-        if (member == null) {
-            member = this.getExplicitFunction(scope, name, 
-                                              javaObject, isStatic);
-            if (member == null)
-                return Scriptable.NOT_FOUND;
-        }
-        if (member instanceof Scriptable)
-            return member;      // why is this here?
-        Object rval;
-        Class type;
-        try {
-            if (member instanceof BeanProperty) {
-                BeanProperty bp = (BeanProperty) member;
-                rval = bp.getter.invoke(javaObject, ScriptRuntime.emptyArgs);
-                type = bp.getter.getReturnType();
-            } else {
-                Field field = (Field) member;
-                rval = field.get(isStatic ? null : javaObject);
-                type = field.getType();
-            }
-        } catch (IllegalAccessException accEx) {
-            throw new RuntimeException("unexpected IllegalAccessException "+
-                                       "accessing Java field");
-        } catch (InvocationTargetException e) {
-            throw WrappedException.wrapException(
-                JavaScriptException.wrapException(scope, e));
-        }
-        // Need to wrap the object before we return it.
-        scope = ScriptableObject.getTopLevelScope(scope);
-        return NativeJavaObject.wrap(scope, rval, type);
-    }
-
-    Member findExplicitFunction(String name, boolean isStatic) {
-        Hashtable ht = isStatic ? staticMembers : members;
-        int sigStart = name.indexOf('(');
-        Member[] methodsOrCtors = null;
-        NativeJavaMethod method = null;
-        boolean isCtor = (isStatic && sigStart == 0);
-
-        if (isCtor) {
-            // Explicit request for an overloaded constructor
-            methodsOrCtors = ctors;
-        }
-        else if (sigStart > 0) {
-            // Explicit request for an overloaded method
-            String trueName = name.substring(0,sigStart);
-            Object obj = ht.get(trueName);
-            if (!isStatic && obj == null) {
-                // Try to get static member from instance (LC3)
-                obj = staticMembers.get(trueName);
-            }
-            if (obj != null && obj instanceof NativeJavaMethod) {
-                method = (NativeJavaMethod)obj;
-                methodsOrCtors = method.getMethods();
-            }
-        }
-
-        if (methodsOrCtors != null) {
-            for (int i = 0; i < methodsOrCtors.length; i++) {
-                String nameWithSig = 
-                    NativeJavaMethod.signature(methodsOrCtors[i]);
-                if (name.equals(nameWithSig)) {
-                    return methodsOrCtors[i];
-                }
-            }
-        }
-
-        return null;
-    }
-
-    Object getExplicitFunction(Scriptable scope, String name, 
-                               Object javaObject, boolean isStatic) 
-    {
-        Hashtable ht = isStatic ? staticMembers : members;
-        Object member = null;
-        Member methodOrCtor = this.findExplicitFunction(name, isStatic);
-
-        if (methodOrCtor != null) {
-            Scriptable prototype = 
-                ScriptableObject.getFunctionPrototype(scope);
-
-            if (methodOrCtor instanceof Constructor) {
-                NativeJavaConstructor fun = 
-                    new NativeJavaConstructor((Constructor)methodOrCtor);
-                fun.setPrototype(prototype);
-                member = fun;
-                ht.put(name, fun);
-            } else {
-                String trueName = methodOrCtor.getName();
-                member = ht.get(trueName);
-
-                if (member instanceof NativeJavaMethod &&
-                    ((NativeJavaMethod)member).getMethods().length > 1 ) {
-                    NativeJavaMethod fun = 
-                        new NativeJavaMethod((Method)methodOrCtor, name);
-                    fun.setPrototype(prototype);
-                    ht.put(name, fun);
-                    member = fun;
-                }
-            }
-        }
-
-        return member;
-    }
-
-
-    public void put(Scriptable scope, String name, Object javaObject, 
-                    Object value, boolean isStatic)
-    {
-        Hashtable ht = isStatic ? staticMembers : members;
-        Object member = ht.get(name);
-        if (!isStatic && member == null) {
-            // Try to get static member from instance (LC3)
-            member = staticMembers.get(name);
-        }
-        if (member == null)
-            throw reportMemberNotFound(name);
-        if (member instanceof FieldAndMethods) {
-            FieldAndMethods fam = (FieldAndMethods) ht.get(name);
-            member = fam.getField();
-        }
-        
-        // Is this a bean property "set"?
-        if (member instanceof BeanProperty) { 
-            try {
-                Method method = ((BeanProperty) member).setter;
-                if (method == null)
-                    throw reportMemberNotFound(name);
-                Class[] types = method.getParameterTypes();
-                Object[] params = { NativeJavaObject.coerceType(types[0], value) };
-                method.invoke(javaObject, params);
-            } catch (IllegalAccessException accessEx) {
-                throw new RuntimeException("unexpected IllegalAccessException " +
-                                           "accessing Java field");
-            } catch (InvocationTargetException e) {
-                throw WrappedException.wrapException(
-                    JavaScriptException.wrapException(scope, e));
-            }
-        }
-        else {
-            Field field = null;
-            try {
-                field = (Field) member;
-                if (field == null) {
-                    throw Context.reportRuntimeError1(
-                        "msg.java.internal.private", name);
-                }
-                field.set(javaObject,
-                          NativeJavaObject.coerceType(field.getType(), value));
-            } catch (ClassCastException e) {
-                throw Context.reportRuntimeError1(
-                    "msg.java.method.assign", name);
-            } catch (IllegalAccessException accessEx) {
-                throw new RuntimeException("unexpected IllegalAccessException "+
-                                           "accessing Java field");
-            } catch (IllegalArgumentException argEx) {
-                throw Context.reportRuntimeError3(
-                    "msg.java.internal.field.type", 
-                    value.getClass().getName(), field,
-                    javaObject.getClass().getName());
-            }
-        }
-    }
-
-    Object[] getIds(boolean isStatic) {
-        Hashtable ht = isStatic ? staticMembers : members;
-        int len = ht.size();
-        Object[] result = new Object[len];
-        Enumeration keys = ht.keys();
-        for (int i=0; i < len; i++)
-            result[i] = keys.nextElement();
-        return result;
-    }
-    
-    Class getReflectedClass() {
-        return cl;
-    }
-    
-    void reflectField(Scriptable scope, Field field) {
-        int mods = field.getModifiers();
-        if (!Modifier.isPublic(mods))
-            return;
-        boolean isStatic = Modifier.isStatic(mods);
-        Hashtable ht = isStatic ? staticMembers : members;
-        String name = field.getName();
-        Object member = ht.get(name);
-        if (member != null) {
-            if (member instanceof NativeJavaMethod) {
-                NativeJavaMethod method = (NativeJavaMethod) member;
-                FieldAndMethods fam = new FieldAndMethods(method.getMethods(),
-                                                          field,
-                                                          null);
-                fam.setPrototype(ScriptableObject.getFunctionPrototype(scope));
-                getFieldAndMethodsTable(isStatic).put(name, fam);
-                ht.put(name, fam);
-                return;
-            }
-            if (member instanceof Field) {
-            	Field oldField = (Field) member;
-            	// If this newly reflected field shadows an inherited field, 
-                // then replace it. Otherwise, since access to the field 
-                // would be ambiguous from Java, no field should be reflected.
-            	// For now, the first field found wins, unless another field 
-                // explicitly shadows it.
-            	if (oldField.getDeclaringClass().isAssignableFrom(field.getDeclaringClass()))
-            		ht.put(name, field);
-            	return;
-            }
-            throw new RuntimeException("unknown member type");
-        }
-        ht.put(name, field);
-    }
-
-    void reflectMethod(Scriptable scope, Method method) {
-        int mods = method.getModifiers();
-        if (!Modifier.isPublic(mods))
-            return;
-        boolean isStatic = Modifier.isStatic(mods);
-        Hashtable ht = isStatic ? staticMembers : members;
-        String name = method.getName();
-        NativeJavaMethod fun = (NativeJavaMethod) ht.get(name);
-        if (fun == null) {
-            fun = new NativeJavaMethod();
-            if (scope != null)
-                fun.setPrototype(ScriptableObject.getFunctionPrototype(scope));
-            ht.put(name, fun);
-            fun.add(method);
-        } else {
-            fun.add(method);
-        }
-    }
-
-    void reflect(Scriptable scope, Class cl) {
-        // We reflect methods first, because we want overloaded field/method
-        // names to be allocated to the NativeJavaMethod before the field
-        // gets in the way.
-        Method[] methods = cl.getMethods();
-        for (int i = 0; i < methods.length; i++)
-            reflectMethod(scope, methods[i]);
-        
-        Field[] fields = cl.getFields();
-        for (int i = 0; i < fields.length; i++)
-            reflectField(scope, fields[i]);
-
-        makeBeanProperties(scope, false);
-        makeBeanProperties(scope, true);
-        
-        ctors = cl.getConstructors();
-    }
-    
-    Hashtable getFieldAndMethodsTable(boolean isStatic) {
-        Hashtable fmht = isStatic ? staticFieldAndMethods
-                                  : fieldAndMethods;
-        if (fmht == null) {
-            fmht = new Hashtable(11);
-            if (isStatic)
-                staticFieldAndMethods = fmht;
-            else
-                fieldAndMethods = fmht;
-        }
-        
-        return fmht;
-    }
-
-    void makeBeanProperties(Scriptable scope, boolean isStatic) {
-        Hashtable ht = isStatic ? staticMembers : members;
-        Hashtable toAdd = new Hashtable();
-        
-        // Now, For each member, make "bean" properties.
-        for (Enumeration e = ht.keys(); e.hasMoreElements(); ) {
-            
-            // Is this a getter?
-            String name = (String) e.nextElement();
-            boolean memberIsGetMethod = name.startsWith("get");
-            boolean memberIsIsMethod = name.startsWith("is");
-            if (memberIsGetMethod || memberIsIsMethod) {
-                // Double check name component.
-                String nameComponent = name.substring(memberIsGetMethod ? 3 : 2);
-                if (nameComponent.length() == 0) 
-                    continue;
-                
-                // Make the bean property name.
-                String beanPropertyName = nameComponent;
-                if (Character.isUpperCase(nameComponent.charAt(0))) {
-                    if (nameComponent.length() == 1) {
-                        beanPropertyName = nameComponent.substring(0, 1).toLowerCase();
-                    } else if (!Character.isUpperCase(nameComponent.charAt(1))) {
-                        beanPropertyName = Character.toLowerCase(nameComponent.charAt(0)) + 
-                                           nameComponent.substring(1);
-                    }
-                }
-                
-                // If we already have a member by this name, don't do this
-                // property.
-                if (ht.containsKey(beanPropertyName))
-                    continue;
-                
-                // Get the method by this name.
-                Object method = ht.get(name);
-                if (!(method instanceof NativeJavaMethod))
-                    continue;
-                NativeJavaMethod getJavaMethod = (NativeJavaMethod) method;
-                
-                // Grab and inspect the getter method; does it have an empty parameter list,
-                // with a return value (eg. a getSomething() or isSomething())?
-                Class[] params;
-                Method[] getMethods = getJavaMethod.getMethods();
-                Class type;
-                if (getMethods != null && 
-                    getMethods.length == 1 && 
-                    (type = getMethods[0].getReturnType()) != null &&
-                    (params = getMethods[0].getParameterTypes()) != null && 
-                    params.length == 0) 
-                { 
-                    
-                    // Make sure the method static-ness is preserved for this property.
-                    if (isStatic && !Modifier.isStatic(getMethods[0].getModifiers()))
-                        continue;
-                        
-                    // We have a getter.  Now, do we have a setter?
-                    Method setMethod = null;
-                    String setter = "set" + nameComponent;
-                    if (ht.containsKey(setter)) { 
-
-                        // Is this value a method?
-                        method = ht.get(setter);
-                        if (method instanceof NativeJavaMethod) {
-                        
-                            //
-                            // Note: it may be preferable to allow NativeJavaMethod.findFunction()
-                            //       to find the appropriate setter; unfortunately, it requires an
-                            //       instance of the target arg to determine that.
-                            //
-
-                            // Make two passes: one to find a method with direct type assignment, 
-                            // and one to find a widening conversion.
-                            NativeJavaMethod setJavaMethod = (NativeJavaMethod) method;
-                            Method[] setMethods = setJavaMethod.getMethods();
-                            for (int pass = 1; pass <= 2 && setMethod == null; ++pass) {
-                                for (int i = 0; i < setMethods.length; ++i) {
-                                    if (setMethods[i].getReturnType() == void.class &&
-                                        (!isStatic || Modifier.isStatic(setMethods[i].getModifiers())) &&
-                                        (params = setMethods[i].getParameterTypes()) != null && 
-                                        params.length == 1 ) { 
-                                        
-                                        if ((pass == 1 && params[0] == type) ||
-                                            (pass == 2 && params[0].isAssignableFrom(type))) { 
-                                            setMethod = setMethods[i];
-                                            break;
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                            
-                    // Make the property.
-                    BeanProperty bp = new BeanProperty(getMethods[0], setMethod);
-                    toAdd.put(beanPropertyName, bp);
-                }
-            }
-        }           
-        
-        // Add the new bean properties.
-        for (Enumeration e = toAdd.keys(); e.hasMoreElements();) {
-            String key = (String) e.nextElement();
-            Object value = toAdd.get(key);
-            ht.put(key, value);
-        }
-    }
-
-    Hashtable getFieldAndMethodsObjects(Scriptable scope, Object javaObject,
-                                        boolean isStatic) 
-    {
-        Hashtable ht = isStatic ? staticFieldAndMethods : fieldAndMethods;
-        if (ht == null)
-            return null;
-        int len = ht.size();
-        Hashtable result = new Hashtable(Math.max(len,1));
-        Enumeration e = ht.elements();
-        while (len-- > 0) {
-            FieldAndMethods fam = (FieldAndMethods) e.nextElement();
-            fam = (FieldAndMethods) fam.clone();
-            fam.setJavaObject(javaObject);
-            result.put(fam.getName(), fam);
-        }
-        return result;
-    }
-
-    Constructor[] getConstructors() {
-        return ctors;
-    }
-
-    static JavaMembers lookupClass(Scriptable scope, Class dynamicType,
-                                   Class staticType)
-    {
-        Class cl = dynamicType;
-        Hashtable ct = classTable;  // use local reference to avoid synchronize
-        JavaMembers members = (JavaMembers) ct.get(cl);
-        if (members != null)
-            return members;
-        if (staticType != null && staticType != dynamicType &&
-            !Modifier.isPublic(dynamicType.getModifiers()) &&
-            Modifier.isPublic(staticType.getModifiers()))
-        {
-            cl = staticType;
-            
-            // We can use the static type, and that is OK, but we'll trace
-            // back the java class chain here to look for something more suitable.
-            for (Class parentType = dynamicType; 
-                 parentType != null && parentType != ScriptRuntime.ObjectClass;
-                 parentType = parentType.getSuperclass())
-            {
-                if (Modifier.isPublic(parentType.getModifiers())) {
-                   cl = parentType;
-                   break;
-                }
-            }
-        }
-        try {
-            members = new JavaMembers(scope, cl);
-        } catch (SecurityException e) {
-            // Reflection may fail for objects that are in a restricted 
-            // access package (e.g. sun.*).  If we get a security
-            // exception, try again with the static type. Otherwise, 
-            // rethrow the exception.
-            if (cl != staticType)
-                members = new JavaMembers(scope, staticType);
-            else
-                throw e;
-        }
-        if (Context.isCachingEnabled) 
-            ct.put(cl, members);
-        return members;
-    }
-
-    RuntimeException reportMemberNotFound(String memberName) {
-        return Context.reportRuntimeError2(
-            "msg.java.member.not.found", cl.getName(), memberName);
-    }
-
-    static Hashtable classTable = new Hashtable();
-
-    private Class cl;
-    private Hashtable members;
-    private Hashtable fieldAndMethods;
-    private Hashtable staticMembers;
-    private Hashtable staticFieldAndMethods;
-    private Constructor[] ctors;
-}
-
-class BeanProperty {
-    BeanProperty(Method getter, Method setter) {
-        this.getter = getter;
-        this.setter = setter;
-    }
-    Method getter;
-    Method setter;
-}
-
-class FieldAndMethods extends NativeJavaMethod {
-
-    FieldAndMethods(Method[] methods, Field field, String name) {
-        super(methods);
-        this.field = field;
-        this.name = name;
-    }
-
-    void setJavaObject(Object javaObject) {
-        this.javaObject = javaObject;
-    }
-
-    String getName() {
-        if (field == null)
-            return name;
-        return field.getName();
-    }
-
-    Field getField() {
-        return field;
-    }
-    
-    public Object getDefaultValue(Class hint) {
-        if (hint == ScriptRuntime.FunctionClass)
-            return this;
-        Object rval;
-        Class type;
-        try {
-            rval = field.get(javaObject);
-            type = field.getType();
-        } catch (IllegalAccessException accEx) {
-            throw Context.reportRuntimeError1(
-                "msg.java.internal.private", getName());
-        }
-        rval = NativeJavaObject.wrap(this, rval, type);
-        if (rval instanceof Scriptable) {
-            rval = ((Scriptable) rval).getDefaultValue(hint);
-        }
-        return rval;
-    }
-
-    public Object clone() {
-        FieldAndMethods result = new FieldAndMethods(methods, field, name);
-        result.javaObject = javaObject;
-        return result;
-    }
-    
-    private Field field;
-    private Object javaObject;
-    private String name;
-}
diff --git a/src/org/mozilla/javascript/JavaScriptException.java b/src/org/mozilla/javascript/JavaScriptException.java
deleted file mode 100644
index d7ca4f5..0000000
--- a/src/org/mozilla/javascript/JavaScriptException.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * The contents of this file are subject to the Netscape Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/NPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is Rhino code, released
- * May 6, 1999.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation.  Portions created by Netscape are
- * Copyright (C) 1997-1999 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s): 
- * Norris Boyd
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU Public License (the "GPL"), in which case the
- * provisions of the GPL are applicable instead of those above.
- * If you wish to allow use of your version of this file only
- * under the terms of the GPL and not to allow others to use your
- * version of this file under the NPL, indicate your decision by
- * deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL.  If you do not delete
- * the provisions above, a recipient may use your version of this
- * file under either the NPL or the GPL.
- */
-
-// API class
-
-package org.mozilla.javascript;
-
-import java.lang.reflect.InvocationTargetException;
-
-/**
- * Java reflection of JavaScript exceptions.  (Possibly wrapping a Java exception.)
- *
- * @author Mike McCabe
- */
-public class JavaScriptException extends Exception {
-
-    public int line;
-    public String sourceFile;
-
-    /**
-     * Create a JavaScript exception wrapping the given JavaScript value.
-     *
-     * Instances of this class are thrown by the JavaScript 'throw' keyword.
-     *
-     * @param value the JavaScript value thrown.
-     */
-    public JavaScriptException(Object value) {
-        super(ScriptRuntime.toString(value));
-        line = Context.enter().interpreterLine;
-        sourceFile = Context.enter().interpreterSourceFile;
-        this.value = value;
-    }
-
-    /**
-     * Get the exception message.
-     *
-     * 

Will just convert the wrapped exception to a string. - */ - public String getMessage() { - return ScriptRuntime.toString(value); - } - - static JavaScriptException wrapException(Scriptable scope, - Throwable exn) - { - if (exn instanceof InvocationTargetException) - exn = ((InvocationTargetException)exn).getTargetException(); - if (exn instanceof JavaScriptException) - return (JavaScriptException)exn; - Object wrapper = NativeJavaObject.wrap(scope, exn, Throwable.class); - return new JavaScriptException(wrapper); - } - - /** - * Get the exception value originally thrown. This may be a - * JavaScript value (null, undefined, Boolean, Number, String, - * Scriptable or Function) or a Java exception value thrown from a - * host object or from Java called through LiveConnect. - * - * @return the value wrapped by this exception - */ - public Object getValue() { - if (value != null && value instanceof Wrapper) - // this will also catch NativeStrings... - return ((Wrapper)value).unwrap(); - else - return value; - } - - /** - * The JavaScript exception value. This value is not - * intended for general use; if the JavaScriptException wraps a - * Java exception, getScriptableValue may return a Scriptable - * wrapping the original Java exception object. - * - * We would prefer to go through a getter to encapsulate the value, - * however that causes the bizarre error "nanosecond timeout value - * out of range" on the MS JVM. - * @serial - */ - Object value; -} diff --git a/src/org/mozilla/javascript/Label.java b/src/org/mozilla/javascript/Label.java deleted file mode 100644 index 8e42d46..0000000 --- a/src/org/mozilla/javascript/Label.java +++ /dev/null @@ -1,106 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Roger Lawrence - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -public class Label { - - private static final int FIXUPTABLE_SIZE = 8; - - private static final boolean DEBUG = true; - - public Label() - { - itsPC = -1; - } - - public short getPC() - { - return itsPC; - } - - public void fixGotos(byte theCodeBuffer[]) - { - if (DEBUG) { - if ((itsPC == -1) && (itsFixupTable != null)) - throw new RuntimeException("Unlocated label"); - } - if (itsFixupTable != null) { - for (int i = 0; i < itsFixupTableTop; i++) { - int fixupSite = itsFixupTable[i]; - // -1 to get delta from instruction start - short offset = (short)(itsPC - (fixupSite - 1)); - theCodeBuffer[fixupSite++] = (byte)(offset >> 8); - theCodeBuffer[fixupSite] = (byte)offset; - } - } - itsFixupTable = null; - } - - public void setPC(short thePC) - { - if (DEBUG) { - if ((itsPC != -1) && (itsPC != thePC)) { - throw new RuntimeException("Duplicate label"); - } - } - - itsPC = thePC; - } - - public void addFixup(int fixupSite) - { - if (itsFixupTable == null) { - itsFixupTableTop = 1; - itsFixupTable = new int[FIXUPTABLE_SIZE]; - itsFixupTable[0] = fixupSite; - } - else { - if (itsFixupTableTop == itsFixupTable.length) { - int oldLength = itsFixupTable.length; - int newTable[] = new int[oldLength + FIXUPTABLE_SIZE]; - System.arraycopy(itsFixupTable, 0, newTable, 0, oldLength); - itsFixupTable = newTable; - } - itsFixupTable[itsFixupTableTop++] = fixupSite; - } - } - - private short itsPC = -1; - private int itsFixupTable[]; - private int itsFixupTableTop; - -} - diff --git a/src/org/mozilla/javascript/LabelTable.java b/src/org/mozilla/javascript/LabelTable.java deleted file mode 100644 index 43dd9ae..0000000 --- a/src/org/mozilla/javascript/LabelTable.java +++ /dev/null @@ -1,80 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Roger Lawrence - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -public class LabelTable { - - private static final boolean DEBUGLABELS = false; - - private static final int LabelTableSize = 32; - protected Label itsLabelTable[]; - protected int itsLabelTableTop; - - public int acquireLabel() - { - if (itsLabelTable == null) { - itsLabelTable = new Label[LabelTableSize]; - itsLabelTable[0] = new Label(); - itsLabelTableTop = 1; - return 0x80000000; - } - else { - if (itsLabelTableTop == itsLabelTable.length) { - Label oldTable[] = itsLabelTable; - itsLabelTable = new Label[itsLabelTableTop * 2]; - System.arraycopy(oldTable, 0, itsLabelTable, 0, itsLabelTableTop); - } - itsLabelTable[itsLabelTableTop] = new Label(); - int result = itsLabelTableTop++; - return result | 0x80000000; - } - } - - public int markLabel(int theLabel, int pc) - { - if (DEBUGLABELS) { - if ((theLabel & 0x80000000) != 0x80000000) - throw new RuntimeException("Bad label, no biscuit"); - } - theLabel &= 0x7FFFFFFF; - if (DEBUGLABELS) { - System.out.println("Marking label " + theLabel + " at " + pc); - } - itsLabelTable[theLabel].setPC((short)pc); - return theLabel | 0x80000000; - } - -} diff --git a/src/org/mozilla/javascript/LazilyLoadedCtor.java b/src/org/mozilla/javascript/LazilyLoadedCtor.java deleted file mode 100644 index 37fd30c..0000000 --- a/src/org/mozilla/javascript/LazilyLoadedCtor.java +++ /dev/null @@ -1,133 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -import java.lang.reflect.*; - -/** - * Avoid loading classes unless they are used. - * - *

This improves startup time and average memory usage. - */ -public final class LazilyLoadedCtor { - - public LazilyLoadedCtor(ScriptableObject scope, - String ctorName, String className, boolean sealed) - { - - this.className = className; - this.ctorName = ctorName; - this.sealed = sealed; - - if (getter == null) { - Method[] all = FunctionObject.getMethodList(getClass()); - getter = FunctionObject.findMethods(all, "getProperty")[0]; - setter = FunctionObject.findMethods(all, "setProperty")[0]; - } - - try { - scope.defineProperty(ctorName, this, getter, setter, - ScriptableObject.DONTENUM); - } - catch (PropertyException e) { - throw WrappedException.wrapException(e); - } - } - - public Object getProperty(ScriptableObject obj) { - synchronized (obj) { - if (!isReplaced) { - boolean removeOnError = false; - - // Treat security exceptions as absence of object. - // They can be due to the following reasons: - // java.lang.RuntimePermission createClassLoader - // java.util.PropertyPermission - // org.mozilla.javascript.JavaAdapter read - - Class cl = null; - try { cl = Class.forName(className); } - catch (ClassNotFoundException ex) { removeOnError = true; } - catch (SecurityException ex) { removeOnError = true; } - - if (cl != null) { - try { - ScriptableObject.defineClass(obj, cl, sealed); - isReplaced = true; - } - catch (InstantiationException e) { - throw WrappedException.wrapException(e); - } - catch (IllegalAccessException e) { - throw WrappedException.wrapException(e); - } - catch (InvocationTargetException e) { - throw WrappedException.wrapException(e); - } - catch (ClassDefinitionException e) { - throw WrappedException.wrapException(e); - } - catch (PropertyException e) { - throw WrappedException.wrapException(e); - } - catch (SecurityException ex) { - removeOnError = true; - } - } - if (removeOnError) { - obj.delete(ctorName); - return Scriptable.NOT_FOUND; - } - } - } - // Get just added object - return obj.get(ctorName, obj); - } - - public Object setProperty(ScriptableObject obj, Object val) { - synchronized (obj) { - isReplaced = true; - return val; - } - } - - private static Method getter, setter; - - private String ctorName; - private String className; - private boolean sealed; - private boolean isReplaced; -} diff --git a/src/org/mozilla/javascript/LineBuffer.java b/src/org/mozilla/javascript/LineBuffer.java deleted file mode 100644 index d3f0ec4..0000000 --- a/src/org/mozilla/javascript/LineBuffer.java +++ /dev/null @@ -1,412 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Mike McCabe - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -import java.io.Reader; -import java.io.IOException; - -/** - * An input buffer that combines fast character-based access with - * (slower) support for retrieving the text of the current line. It - * also supports building strings directly out of the internal buffer - * to support fast scanning with minimal object creation. - * - * Note that it is customized in several ways to support the - * TokenStream class, and should not be considered general. - * - * Credits to Kipp Hickman and John Bandhauer. - * - * @author Mike McCabe - */ -final class LineBuffer { - /* - * for smooth operation of getLine(), this should be greater than - * the length of any expected line. Currently, 256 is 3% slower - * than 4096 for large compiles, but seems safer given evaluateString. - * Strings for the scanner are are built with StringBuffers - * instead of directly out of the buffer whenever a string crosses - * a buffer boundary, so small buffer sizes will mean that more - * objects are created. - */ - static final int BUFLEN = 256; - - LineBuffer(Reader in, int lineno) { - this.in = in; - this.lineno = lineno; - } - - int read() throws IOException { - for(;;) { - if (end == offset && !fill()) - return -1; - - // Do only a bitmask + branch per character, at the cost of - // three branches per low-bits-only (or 2028/9) character. - if ((buffer[offset] & '\udfd0') == 0) { - if (buffer[offset] == '\r') { - // if the next character is a newline, skip past it. - if ((offset + 1) < end) { - if (buffer[offset + 1] == '\n') - offset++; - } else { - // set a flag for fill(), in case the first char of the - // next fill is a newline. - lastWasCR = true; - } - } - else - if ((buffer[offset] != '\n') - && (buffer[offset] != '\u2028') - && (buffer[offset] != '\u2029')) - { - if (Character.getType(buffer[offset]) - == Character.FORMAT) { - hadCFSinceStringStart = true; - offset++; - continue; - } - return (int) buffer[offset++]; - } - offset++; - prevStart = lineStart; - lineStart = offset; - lineno++; - return '\n'; - } - if ((buffer[offset] >= 128) - && (Character.getType(buffer[offset]) == Character.FORMAT)) { - hadCFSinceStringStart = true; - offset++; - } - else - break; - } - - return (int) buffer[offset++]; - } - - void unread() { - if (offset == 0) - // We can get here when we're asked to unread() an - // implicit EOF_CHAR. - - // This would also be wrong behavior in the general case, - // because a peek() could map a buffer.length offset to 0 - // in the process of a fill(), and leave it there. But - // the scanner never calls peek() or a failed match() - // followed by unread()... this would violate 1-character - // lookahead. So we're OK. - return; - offset--; - if ((buffer[offset] & '\ufff0') == 0 - && (buffer[offset] == '\r' || buffer[offset] == '\n')) { - // back off from the line start we presumably just registered... - lineStart = prevStart; - lineno--; - } - } - - int peek() throws IOException { - if (end == offset && !fill()) - return -1; - - if (buffer[offset] == '\r') - return '\n'; - - return buffer[offset]; - } - - boolean match(char c) throws IOException { - if (end == offset && !fill()) - return false; - - // This'd be a place where we'd need to map '\r' to '\n' and - // do other updates, but TokenStream never looks ahead for - // '\n', so we don't bother. - if (buffer[offset] == c) { - offset++; - return true; - } - return false; - } - - // Reconstruct a source line from the buffers. This can be slow... - String getLine() { - StringBuffer result = new StringBuffer(); - - int start = lineStart; - if (start >= offset) { - // the line begins somewhere in the other buffer; get that first. - if (otherStart < otherEnd) - // if a line ending was seen in the other buffer... otherwise - // just ignore this strange case. - result.append(otherBuffer, otherStart, - otherEnd - otherStart); - start = 0; - } - - // get the part of the line in the current buffer. - result.append(buffer, start, offset - start); - - // Get the remainder of the line. - int i = offset; - while(true) { - if (i == buffer.length) { - // we're out of buffer, let's just expand it. We do - // this instead of reading into a StringBuffer to - // preserve the stream for later reads. - char[] newBuffer = new char[buffer.length * 2]; - System.arraycopy(buffer, 0, newBuffer, 0, buffer.length); - buffer = newBuffer; - int charsRead = 0; - try { - charsRead = in.read(buffer, end, buffer.length - end); - } catch (IOException ioe) { - // ignore it, we're already displaying an error... - } - if (charsRead < 0) - break; - end += charsRead; - } - if (buffer[i] == '\r' || buffer[i] == '\n') - break; - i++; - } - - result.append(buffer, offset, i - offset); - return result.toString(); - } - - // Get the offset of the current character, relative to - // the line that getLine() returns. - int getOffset() { - if (lineStart >= offset) - // The line begins somewhere in the other buffer. - return offset + (otherEnd - otherStart); - else - return offset - lineStart; - } - - // Set a mark to indicate that the reader should begin - // accumulating characters for getString(). The string begins - // with the last character read. - void startString() { - if (offset == 0) { - // We can get here if startString is called after a peek() - // or failed match() with offset past the end of the - // buffer. - - // We're at the beginning of the buffer, and the previous character - // (which we want to include) is at the end of the last one, so - // we just go to StringBuffer mode. - stringSoFar = new StringBuffer(); - - stringSoFar.append(otherBuffer, otherEnd - 1, 1); - - stringStart = -1; // Set sentinel value. - hadCFSinceStringStart = ((otherBuffer[otherEnd - 1] >= 128) - && Character.getType(otherBuffer[otherEnd - 1]) - == Character.FORMAT); - } else { - // Support restarting strings - stringSoFar = null; - stringStart = offset - 1; - hadCFSinceStringStart = ((buffer[stringStart] >= 128) - && Character.getType(buffer[stringStart]) == Character.FORMAT); - } - - } - - // Get a string consisting of the characters seen since the last - // startString. - String getString() { - String result; - - /* - * There's one strange case here: If the character offset currently - * points to (which we never want to include in the string) is - * a newline, then if the previous character is a carriage return, - * we probably want to exclude that as well. If the offset is 0, - * then we hope that fill() handled excluding it from stringSoFar. - */ - int loseCR = (offset > 0 && - buffer[offset] == '\n' && buffer[offset - 1] == '\r') ? - 1 : 0; - - if (stringStart != -1) { - // String mark is valid, and in this buffer. - - result = new String(buffer, stringStart, - offset - stringStart - loseCR); - } else { - if (stringSoFar == null) - stringSoFar = new StringBuffer(); - // Exclude cr as well as nl of newline. If offset is 0, then - // hopefully fill() did the right thing. - result = (stringSoFar.append(buffer, 0, offset - loseCR)).toString(); - } - - stringStart = -1; - stringSoFar = null; - - if (hadCFSinceStringStart) { - char c[] = result.toCharArray(); - StringBuffer x = null; - for (int i = 0; i < c.length; i++) { - if (Character.getType(c[i]) == Character.FORMAT) { - if (x == null) { - x = new StringBuffer(); - x.append(c, 0, i); - } - } - else - if (x != null) x.append(c[i]); - } - if (x != null) result = x.toString(); - } - - return result; - } - - boolean fill() throws IOException { - // not sure I care... - if (end - offset != 0) - throw new IOException("fill of non-empty buffer"); - - // If there's a string currently being accumulated, save - // off the progress. - - /* - * Exclude an end-of-buffer carriage return. NOTE this is not - * fully correct in the general case, because we really only - * want to exclude the carriage return if it's followed by a - * linefeed at the beginning of the next buffer. But we fudge - * because the scanner doesn't do this. - */ - int loseCR = (offset > 0 && lastWasCR) ? 1 : 0; - - if (stringStart != -1) { - // The mark is in the current buffer, save off from the mark to the - // end. - stringSoFar = new StringBuffer(); - - stringSoFar.append(buffer, stringStart, end - stringStart - loseCR); - stringStart = -1; - } else if (stringSoFar != null) { - // the string began prior to the current buffer, so save the - // whole current buffer. - stringSoFar.append(buffer, 0, end - loseCR); - } - - // swap buffers - char[] tempBuffer = buffer; - buffer = otherBuffer; - otherBuffer = tempBuffer; - - // allocate the buffers lazily, in case we're handed a short string. - if (buffer == null) { - buffer = new char[BUFLEN]; - } - - // buffers have switched, so move the newline marker. - otherStart = lineStart; - otherEnd = end; - - // set lineStart to a sentinel value, unless this is the first - // time around. - prevStart = lineStart = (otherBuffer == null) ? 0 : buffer.length + 1; - - offset = 0; - end = in.read(buffer, 0, buffer.length); - if (end < 0) { - end = 0; - - // can't null buffers here, because a string might be retrieved - // out of the other buffer, and a 0-length string might be - // retrieved out of this one. - - hitEOF = true; - return false; - } - - // If the last character of the previous fill was a carriage return, - // then ignore a newline. - - // There's another bizzare special case here. If lastWasCR is - // true, and we see a newline, and the buffer length is - // 1... then we probably just read the last character of the - // file, and returning after advancing offset is not the right - // thing to do. Instead, we try to ignore the newline (and - // likely get to EOF for real) by doing yet another fill(). - if (lastWasCR) { - if (buffer[0] == '\n') { - offset++; - if (end == 1) - return fill(); - } - lineStart = offset; - lastWasCR = false; - } - return true; - } - - int getLineno() { return lineno; } - boolean eof() { return hitEOF; } - - private Reader in; - private char[] otherBuffer = null; - private char[] buffer = null; - - // Yes, there are too too many of these. - private int offset = 0; - private int end = 0; - private int otherEnd; - private int lineno; - - private int lineStart = 0; - private int otherStart = 0; - private int prevStart = 0; - - private boolean lastWasCR = false; - private boolean hitEOF = false; - - private int stringStart = -1; - private StringBuffer stringSoFar = null; - private boolean hadCFSinceStringStart = false; - -} - - diff --git a/src/org/mozilla/javascript/ListenerArray.java b/src/org/mozilla/javascript/ListenerArray.java deleted file mode 100644 index 3687b10..0000000 --- a/src/org/mozilla/javascript/ListenerArray.java +++ /dev/null @@ -1,131 +0,0 @@ -/* -*- Mode: java; tab-width: 4; indent-tabs-mode: 1; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Igor Bukanov - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -/* Helper class to add/remove listeners from Object array */ - -package org.mozilla.javascript; - -/** - * Utility class to manage listeners array. - * A possible usage would be: -

-    private Object[] listeners;
-    ...
-    void addListener(ListenerType listener) {
-        synchronized (this) {
-            listeners = ListenerArray.add(listeners, listener);
-        }
-    }
-
-    void removeListener(ListenerType listener) {
-        synchronized (this) {
-            listeners = ListenerArray.remove(listeners, listener);
-        }
-    }
-
- * Here is a thread safe while synchronization free example of event firing -
-    void fireEvent(EventType event) {
-        Object[] array = listeners;
-        if (array != null) {
-            for (int i = array.length; i-- != 0;) {
-                ((ListenerType)array[i]).onEvent(event);
-            }
-        }
-
-    }
-
- - * or if listeners of different types can present in listeners array: -
-    void fireEvent(EventType event) {
-        Object[] array = listeners;
-        if (array != null) {
-            for (int i = array.length; i-- != 0;) {
-                Object obj = array[i];
-                if (obj instanceof ListenerType) {
-                    ((ListenerType)obj).onEvent(event);
-                }
-            }
-        }
-
-    }
-
- */ -public class ListenerArray { - - /** Return newly allocated array that contains listener and all elements - ** from data array. - ** Note: listener is added to resulting array even if it is already - ** present in data */ - public static Object[] add(Object[] data, Object listener) { - if (data == null) { - data = new Object[1]; - } - else { - int N = data.length; - Object[] tmp = new Object[N + 1]; - System.arraycopy(data, 0, tmp, 1, N); - data = tmp; - } - data[0] = listener; - return data; - } - - /** Return a copy of data array with the first occurrence of listener - ** removed. - ** If listener is not present in data, simply return data. - ** Note: return null if listener is the single element - ** of data. */ - public static Object[] remove(Object[] data, Object listener) { - if (data != null) { - int N = data.length; - for (int i = 0; i != N; ++i) { - if (data[i] == listener) { - if (N == 1) { data = null; } - else { - Object[] tmp = new Object[N - 1]; - System.arraycopy(data, 0, tmp, 0, i); - System.arraycopy(data, i + 1, tmp, i, N - 1 - i); - data = tmp; - } - break; - } - } - } - return data; - } - -} diff --git a/src/org/mozilla/javascript/LocalVariable.java b/src/org/mozilla/javascript/LocalVariable.java deleted file mode 100644 index bb673c1..0000000 --- a/src/org/mozilla/javascript/LocalVariable.java +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Roger Lawrence - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -public class LocalVariable { - - public LocalVariable(String name, boolean isParameter) { - itsName = name; - itsIsParameter = isParameter; - } - - public void setIndex(int index){ itsIndex = index; } - public int getIndex() { return itsIndex; } - - public void setIsParameter() { itsIsParameter = true; } - public boolean isParameter() { return itsIsParameter; } - - public String getName() { return itsName; } - - /** - * Return the starting PC where this variable is live, or -1 - * if it is not a Java register. - */ - public int getStartPC() { - return -1; - } - - /** - * Return the Java register number or -1 if it is not a Java register. - */ - public short getJRegister() { - return -1; - } - - /** - * Return true if the local variable is a Java register with double type. - */ - public boolean isNumber() { - return false; - } - - private String itsName; - private int itsIndex = -1; - - private boolean itsIsParameter; -} diff --git a/src/org/mozilla/javascript/NativeArray.java b/src/org/mozilla/javascript/NativeArray.java deleted file mode 100644 index 37d81f8..0000000 --- a/src/org/mozilla/javascript/NativeArray.java +++ /dev/null @@ -1,1147 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * Mike McCabe - * Igor Bukanov - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; -import java.util.Hashtable; - -/** - * This class implements the Array native object. - * @author Norris Boyd - * @author Mike McCabe - */ -public class NativeArray extends IdScriptable { - - /* - * Optimization possibilities and open issues: - * - Long vs. double schizophrenia. I suspect it might be better - * to use double throughout. - - * - Most array operations go through getElem or setElem (defined - * in this file) to handle the full 2^32 range; it might be faster - * to have versions of most of the loops in this file for the - * (infinitely more common) case of indices < 2^31. - - * - Functions that need a new Array call "new Array" in the - * current scope rather than using a hardwired constructor; - * "Array" could be redefined. It turns out that js calls the - * equivalent of "new Array" in the current scope, except that it - * always gets at least an object back, even when Array == null. - */ - - public static void init(Context cx, Scriptable scope, boolean sealed) { - NativeArray obj = new NativeArray(); - obj.prototypeFlag = true; - obj.addAsPrototype(MAX_PROTOTYPE_ID, cx, scope, sealed); - } - - /** - * Zero-parameter constructor: just used to create Array.prototype - */ - public NativeArray() { - dense = null; - this.length = 0; - } - - public NativeArray(long length) { - int intLength = (int) length; - if (intLength == length && intLength > 0) { - if (intLength > maximumDenseLength) - intLength = maximumDenseLength; - dense = new Object[intLength]; - for (int i=0; i < intLength; i++) - dense[i] = NOT_FOUND; - } - this.length = length; - } - - public NativeArray(Object[] array) { - dense = array; - this.length = array.length; - } - - public String getClassName() { - return "Array"; - } - - protected int getIdDefaultAttributes(int id) { - if (id == Id_length) { - return DONTENUM | PERMANENT; - } - return super.getIdDefaultAttributes(id); - } - - protected Object getIdValue(int id) { - if (id == Id_length) { - return wrap_double(length); - } - return super.getIdValue(id); - } - - protected void setIdValue(int id, Object value) { - if (id == Id_length) { - jsSet_length(value); return; - } - super.setIdValue(id, value); - } - - public int methodArity(int methodId) { - if (prototypeFlag) { - switch (methodId) { - case Id_constructor: return 1; - case Id_toString: return 0; - case Id_toLocaleString: return 1; - case Id_join: return 1; - case Id_reverse: return 0; - case Id_sort: return 1; - case Id_push: return 1; - case Id_pop: return 1; - case Id_shift: return 1; - case Id_unshift: return 1; - case Id_splice: return 1; - case Id_concat: return 1; - case Id_slice: return 1; - } - } - return super.methodArity(methodId); - } - - public Object execMethod - (int methodId, IdFunction f, - Context cx, Scriptable scope, Scriptable thisObj, Object[] args) - throws JavaScriptException - { - if (prototypeFlag) { - switch (methodId) { - case Id_constructor: - return jsConstructor(cx, scope, args, f, thisObj == null); - - case Id_toString: - return jsFunction_toString(cx, thisObj, args); - - case Id_toLocaleString: - return jsFunction_toLocaleString(cx, thisObj, args); - - case Id_join: - return jsFunction_join(cx, thisObj, args); - - case Id_reverse: - return jsFunction_reverse(cx, thisObj, args); - - case Id_sort: - return jsFunction_sort(cx, scope, thisObj, args); - - case Id_push: - return jsFunction_push(cx, thisObj, args); - - case Id_pop: - return jsFunction_pop(cx, thisObj, args); - - case Id_shift: - return jsFunction_shift(cx, thisObj, args); - - case Id_unshift: - return jsFunction_unshift(cx, thisObj, args); - - case Id_splice: - return jsFunction_splice(cx, scope, thisObj, args); - - case Id_concat: - return jsFunction_concat(cx, scope, thisObj, args); - - case Id_slice: - return jsFunction_slice(cx, thisObj, args); - } - } - return super.execMethod(methodId, f, cx, scope, thisObj, args); - } - - public Object get(int index, Scriptable start) { - if (dense != null && 0 <= index && index < dense.length) - return dense[index]; - return super.get(index, start); - } - - public boolean has(int index, Scriptable start) { - if (dense != null && 0 <= index && index < dense.length) - return dense[index] != NOT_FOUND; - return super.has(index, start); - } - - public void put(String id, Scriptable start, Object value) { - if (start == this) { - // only set the array length if given an array index (ECMA 15.4.0) - - // try to get an array index from id - double d = ScriptRuntime.toNumber(id); - - if (ScriptRuntime.toUint32(d) == d && - ScriptRuntime.numberToString(d, 10).equals(id) && - this.length <= d && d != 4294967295.0) - { - this.length = (long)d + 1; - } - } - super.put(id, start, value); - } - - public void put(int index, Scriptable start, Object value) { - if (start == this) { - // only set the array length if given an array index (ECMA 15.4.0) - if (this.length <= index) { - // avoid overflowing index! - this.length = (long)index + 1; - } - - if (dense != null && 0 <= index && index < dense.length) { - dense[index] = value; - return; - } - } - super.put(index, start, value); - } - - public void delete(int index) { - if (!isSealed()) { - if (dense != null && 0 <= index && index < dense.length) { - dense[index] = NOT_FOUND; - return; - } - } - super.delete(index); - } - - public Object[] getIds() { - Object[] superIds = super.getIds(); - if (dense == null) - return superIds; - int count = 0; - int last = dense.length; - if (last > length) - last = (int) length; - for (int i=last-1; i >= 0; i--) { - if (dense[i] != NOT_FOUND) - count++; - } - count += superIds.length; - Object[] result = new Object[count]; - System.arraycopy(superIds, 0, result, 0, superIds.length); - for (int i=last-1; i >= 0; i--) { - if (dense[i] != NOT_FOUND) - result[--count] = new Integer(i); - } - return result; - } - - public Object getDefaultValue(Class hint) { - if (hint == ScriptRuntime.NumberClass) { - Context cx = Context.getContext(); - if (cx.getLanguageVersion() == Context.VERSION_1_2) - return new Long(length); - } - return super.getDefaultValue(hint); - } - - /** - * See ECMA 15.4.1,2 - */ - private static Object jsConstructor(Context cx, Scriptable scope, - Object[] args, IdFunction ctorObj, - boolean inNewExpr) - throws JavaScriptException - { - if (!inNewExpr) { - // FunctionObject.construct will set up parent, proto - return ctorObj.construct(cx, scope, args); - } - if (args.length == 0) - return new NativeArray(); - - // Only use 1 arg as first element for version 1.2; for - // any other version (including 1.3) follow ECMA and use it as - // a length. - if (cx.getLanguageVersion() == cx.VERSION_1_2) { - return new NativeArray(args); - } - else { - if ((args.length > 1) || (!(args[0] instanceof Number))) - return new NativeArray(args); - else { - long len = ScriptRuntime.toUint32(args[0]); - if (len != (((Number)(args[0])).doubleValue())) - throw Context.reportRuntimeError0("msg.arraylength.bad"); - return new NativeArray(len); - } - } - } - - public long jsGet_length() { - return length; - } - - private void jsSet_length(Object val) { - /* XXX do we satisfy this? - * 15.4.5.1 [[Put]](P, V): - * 1. Call the [[CanPut]] method of A with name P. - * 2. If Result(1) is false, return. - * ? - */ - - if (!(val instanceof Number)) - throw Context.reportRuntimeError0("msg.arraylength.bad"); - - long longVal = ScriptRuntime.toUint32(val); - if (longVal != (((Number)val).doubleValue())) - throw Context.reportRuntimeError0("msg.arraylength.bad"); - - if (longVal < length) { - // remove all properties between longVal and length - if (length - longVal > 0x1000) { - // assume that the representation is sparse - Object[] e = getIds(); // will only find in object itself - for (int i=0; i < e.length; i++) { - if (e[i] instanceof String) { - // > MAXINT will appear as string - String id = (String) e[i]; - double d = ScriptRuntime.toNumber(id); - if (d == d && d < length) - delete(id); - continue; - } - int index = ((Number) e[i]).intValue(); - if (index >= longVal) - delete(index); - } - } else { - // assume a dense representation - for (long i=longVal; i < length; i++) { - // only delete if defined in the object itself - if (hasElem(this, i)) - ScriptRuntime.delete(this, new Long(i)); - } - } - } - length = longVal; - } - - /* Support for generic Array-ish objects. Most of the Array - * functions try to be generic; anything that has a length - * property is assumed to be an array. hasLengthProperty is - * needed in addition to getLengthProperty, because - * getLengthProperty always succeeds - tries to convert strings, etc. - */ - static double getLengthProperty(Scriptable obj) { - // These will both give numeric lengths within Uint32 range. - if (obj instanceof NativeString) - return (double)((NativeString)obj).jsGet_length(); - if (obj instanceof NativeArray) - return (double)((NativeArray)obj).jsGet_length(); - return ScriptRuntime.toUint32(ScriptRuntime - .getProp(obj, "length", obj)); - } - - static boolean hasLengthProperty(Object obj) { - if (!(obj instanceof Scriptable) || obj == Context.getUndefinedValue()) - return false; - if (obj instanceof NativeString || obj instanceof NativeArray) - return true; - Scriptable sobj = (Scriptable)obj; - - // XXX some confusion as to whether or not to walk to get the length - // property. Pending review of js/[new ecma submission] treatment - // of 'arrayness'. - - Object property = ScriptRuntime.getProp(sobj, "length", sobj); - return property instanceof Number; - } - - /* Utility functions to encapsulate index > Integer.MAX_VALUE - * handling. Also avoids unnecessary object creation that would - * be necessary to use the general ScriptRuntime.get/setElem - * functions... though this is probably premature optimization. - */ - private static boolean hasElem(Scriptable target, long index) { - return index > Integer.MAX_VALUE - ? target.has(Long.toString(index), target) - : target.has((int)index, target); - } - - private static Object getElem(Scriptable target, long index) { - if (index > Integer.MAX_VALUE) { - String id = Long.toString(index); - return ScriptRuntime.getElem(target, id, target); - } else { - return ScriptRuntime.getElem(target, (int)index); - } - } - - private static void setElem(Scriptable target, long index, Object value) { - if (index > Integer.MAX_VALUE) { - String id = Long.toString(index); - ScriptRuntime.setElem(target, id, value, target); - } else { - ScriptRuntime.setElem(target, (int)index, value); - } - } - - private static String jsFunction_toString(Context cx, Scriptable thisObj, - Object[] args) - throws JavaScriptException - { - return toStringHelper(cx, thisObj, - cx.getLanguageVersion() == cx.VERSION_1_2, - false); - } - - private static String jsFunction_toLocaleString(Context cx, - Scriptable thisObj, - Object[] args) - throws JavaScriptException - { - return toStringHelper(cx, thisObj, false, true); - } - - private static String toStringHelper(Context cx, Scriptable thisObj, - boolean toSource, boolean toLocale) - throws JavaScriptException - { - /* It's probably redundant to handle long lengths in this - * function; StringBuffers are limited to 2^31 in java. - */ - - long length = (long)getLengthProperty(thisObj); - - StringBuffer result = new StringBuffer(); - - if (cx.iterating == null) - cx.iterating = new Hashtable(31); - boolean iterating = cx.iterating.get(thisObj) == Boolean.TRUE; - - // whether to return '4,unquoted,5' or '[4, "quoted", 5]' - String separator; - - if (toSource) { - result.append('['); - separator = ", "; - } else { - separator = ","; - } - - boolean haslast = false; - long i = 0; - - if (!iterating) { - for (i = 0; i < length; i++) { - if (i > 0) - result.append(separator); - Object elem = getElem(thisObj, i); - if (elem == null || elem == Undefined.instance) { - haslast = false; - continue; - } - haslast = true; - - if (elem instanceof String) { - if (toSource) { - result.append('\"'); - result.append(ScriptRuntime.escapeString - (ScriptRuntime.toString(elem))); - result.append('\"'); - } else { - result.append(ScriptRuntime.toString(elem)); - } - } else { - /* wrap changes to cx.iterating in a try/finally - * so that the reference always gets removed, and - * we don't leak memory. Good place for weak - * references, if we had them. */ - try { - // stop recursion. - cx.iterating.put(thisObj, Boolean.TRUE); - if (toLocale && elem != Undefined.instance && - elem != null) - { - Scriptable obj = cx.toObject(elem, thisObj); - Object tls = ScriptRuntime.getProp(obj, - "toLocaleString", thisObj); - elem = ScriptRuntime.call(cx, tls, elem, - ScriptRuntime.emptyArgs); - } - result.append(ScriptRuntime.toString(elem)); - } finally { - cx.iterating.remove(thisObj); - } - } - } - } - - if (toSource) { - //for [,,].length behavior; we want toString to be symmetric. - if (!haslast && i > 0) - result.append(", ]"); - else - result.append(']'); - } - return result.toString(); - } - - /** - * See ECMA 15.4.4.3 - */ - private static String jsFunction_join(Context cx, Scriptable thisObj, - Object[] args) - { - StringBuffer result = new StringBuffer(); - String separator; - - double length = getLengthProperty(thisObj); - - // if no args, use "," as separator - if (args.length < 1) { - separator = ","; - } else { - separator = ScriptRuntime.toString(args[0]); - } - for (long i=0; i < length; i++) { - if (i > 0) - result.append(separator); - Object temp = getElem(thisObj, i); - if (temp == null || temp == Undefined.instance) - continue; - result.append(ScriptRuntime.toString(temp)); - } - return result.toString(); - } - - /** - * See ECMA 15.4.4.4 - */ - private static Scriptable jsFunction_reverse(Context cx, - Scriptable thisObj, - Object[] args) - { - long len = (long)getLengthProperty(thisObj); - - long half = len / 2; - for(long i=0; i < half; i++) { - long j = len - i - 1; - Object temp1 = getElem(thisObj, i); - Object temp2 = getElem(thisObj, j); - setElem(thisObj, i, temp2); - setElem(thisObj, j, temp1); - } - return thisObj; - } - - /** - * See ECMA 15.4.4.5 - */ - private static Scriptable jsFunction_sort(Context cx, Scriptable scope, - Scriptable thisObj, - Object[] args) - throws JavaScriptException - { - long length = (long)getLengthProperty(thisObj); - - Object compare; - if (args.length > 0 && Undefined.instance != args[0]) - // sort with given compare function - compare = args[0]; - else - // sort with default compare - compare = null; - - - // OPT: Would it make sense to use the extended sort for very small - // arrays? - - // Should we use the extended sort function, or the faster one? - if (length >= Integer.MAX_VALUE) { - qsort_extended(cx, compare, thisObj, 0, length - 1); - } else { - // copy the JS array into a working array, so it can be - // sorted cheaply. - Object[] working = new Object[(int)length]; - for (int i=0; i 0) { - length--; - - // Get the to-be-deleted property's value. - result = getElem(thisObj, (long)length); - - // We don't need to delete the last property, because - // setLength does that for us. - } else { - result = Context.getUndefinedValue(); - } - // necessary to match js even when length < 0; js pop will give a - // length property to any target it is called on. - ScriptRuntime.setProp(thisObj, "length", new Double(length), thisObj); - - return result; - } - - private static Object jsFunction_shift(Context cx, Scriptable thisObj, - Object[] args) - { - Object result; - double length = getLengthProperty(thisObj); - if (length > 0) { - long i = 0; - length--; - - // Get the to-be-deleted property's value. - result = getElem(thisObj, i); - - /* - * Slide down the array above the first element. Leave i - * set to point to the last element. - */ - if (length > 0) { - for (i = 1; i <= length; i++) { - Object temp = getElem(thisObj, i); - setElem(thisObj, i - 1, temp); - } - } - // We don't need to delete the last property, because - // setLength does that for us. - } else { - result = Context.getUndefinedValue(); - } - ScriptRuntime.setProp(thisObj, "length", new Double(length), thisObj); - return result; - } - - private static Object jsFunction_unshift(Context cx, Scriptable thisObj, - Object[] args) - { - Object result; - double length = (double)getLengthProperty(thisObj); - int argc = args.length; - - if (args.length > 0) { - /* Slide up the array to make room for args at the bottom */ - if (length > 0) { - for (long last = (long)length - 1; last >= 0; last--) { - Object temp = getElem(thisObj, last); - setElem(thisObj, last + argc, temp); - } - } - - /* Copy from argv to the bottom of the array. */ - for (int i = 0; i < args.length; i++) { - setElem(thisObj, i, args[i]); - } - - /* Follow Perl by returning the new array length. */ - length += args.length; - ScriptRuntime.setProp(thisObj, "length", - new Double(length), thisObj); - } - return new Long((long)length); - } - - private static Object jsFunction_splice(Context cx, Scriptable scope, - Scriptable thisObj, Object[] args) - { - /* create an empty Array to return. */ - scope = getTopLevelScope(scope); - Object result = ScriptRuntime.newObject(cx, scope, "Array", null); - int argc = args.length; - if (argc == 0) - return result; - double length = getLengthProperty(thisObj); - - /* Convert the first argument into a starting index. */ - double begin = ScriptRuntime.toInteger(args[0]); - double end; - double delta; - double count; - - if (begin < 0) { - begin += length; - if (begin < 0) - begin = 0; - } else if (begin > length) { - begin = length; - } - argc--; - - /* Convert the second argument from a count into a fencepost index. */ - delta = length - begin; - - if (args.length == 1) { - count = delta; - end = length; - } else { - count = ScriptRuntime.toInteger(args[1]); - if (count < 0) - count = 0; - else if (count > delta) - count = delta; - end = begin + count; - - argc--; - } - - long lbegin = (long)begin; - long lend = (long)end; - - /* If there are elements to remove, put them into the return value. */ - if (count > 0) { - if (count == 1 - && (cx.getLanguageVersion() == Context.VERSION_1_2)) - { - /* - * JS lacks "list context", whereby in Perl one turns the - * single scalar that's spliced out into an array just by - * assigning it to @single instead of $single, or by using it - * as Perl push's first argument, for instance. - * - * JS1.2 emulated Perl too closely and returned a non-Array for - * the single-splice-out case, requiring callers to test and - * wrap in [] if necessary. So JS1.3, default, and other - * versions all return an array of length 1 for uniformity. - */ - result = getElem(thisObj, lbegin); - } else { - for (long last = lbegin; last < lend; last++) { - Scriptable resultArray = (Scriptable)result; - Object temp = getElem(thisObj, last); - setElem(resultArray, last - lbegin, temp); - } - } - } else if (count == 0 - && cx.getLanguageVersion() == Context.VERSION_1_2) - { - /* Emulate C JS1.2; if no elements are removed, return undefined. */ - result = Context.getUndefinedValue(); - } - - /* Find the direction (up or down) to copy and make way for argv. */ - delta = argc - count; - - if (delta > 0) { - for (long last = (long)length - 1; last >= lend; last--) { - Object temp = getElem(thisObj, last); - setElem(thisObj, last + (long)delta, temp); - } - } else if (delta < 0) { - for (long last = lend; last < length; last++) { - Object temp = getElem(thisObj, last); - setElem(thisObj, last + (long)delta, temp); - } - } - - /* Copy from argv into the hole to complete the splice. */ - int argoffset = args.length - argc; - for (int i = 0; i < argc; i++) { - setElem(thisObj, lbegin + i, args[i + argoffset]); - } - - /* Update length in case we deleted elements from the end. */ - ScriptRuntime.setProp(thisObj, "length", - new Double(length + delta), thisObj); - return result; - } - - /* - * Python-esque sequence operations. - */ - private static Scriptable jsFunction_concat(Context cx, Scriptable scope, - Scriptable thisObj, - Object[] args) - { - /* Concat tries to keep the definition of an array as general - * as possible; if it finds that an object has a numeric - * 'length' property, then it treats that object as an array. - * This treats string atoms and string objects differently; as - * string objects have a length property and are accessible by - * index, they get exploded into arrays when added, while - * atomic strings are just added as strings. - */ - - // create an empty Array to return. - scope = getTopLevelScope(scope); - Scriptable result = ScriptRuntime.newObject(cx, scope, "Array", null); - double length; - long slot = 0; - - /* Put the target in the result array; only add it as an array - * if it looks like one. - */ - if (hasLengthProperty(thisObj)) { - length = getLengthProperty(thisObj); - - // Copy from the target object into the result - for (slot = 0; slot < length; slot++) { - Object temp = getElem(thisObj, slot); - setElem(result, slot, temp); - } - } else { - setElem(result, slot++, thisObj); - } - - /* Copy from the arguments into the result. If any argument - * has a numeric length property, treat it as an array and add - * elements separately; otherwise, just copy the argument. - */ - for (int i = 0; i < args.length; i++) { - if (hasLengthProperty(args[i])) { - // hasLengthProperty => instanceOf Scriptable. - Scriptable arg = (Scriptable)args[i]; - length = getLengthProperty(arg); - for (long j = 0; j < length; j++, slot++) { - Object temp = getElem(arg, j); - setElem(result, slot, temp); - } - } else { - setElem(result, slot++, args[i]); - } - } - return result; - } - - private Scriptable jsFunction_slice(Context cx, Scriptable thisObj, - Object[] args) - { - Scriptable scope = getTopLevelScope(this); - Scriptable result = ScriptRuntime.newObject(cx, scope, "Array", null); - double length = getLengthProperty(thisObj); - - double begin = 0; - double end = length; - - if (args.length > 0) { - begin = ScriptRuntime.toInteger(args[0]); - if (begin < 0) { - begin += length; - if (begin < 0) - begin = 0; - } else if (begin > length) { - begin = length; - } - - if (args.length > 1) { - end = ScriptRuntime.toInteger(args[1]); - if (end < 0) { - end += length; - if (end < 0) - end = 0; - } else if (end > length) { - end = length; - } - } - } - - long lbegin = (long)begin; - long lend = (long)end; - for (long slot = lbegin; slot < lend; slot++) { - Object temp = getElem(thisObj, slot); - setElem(result, slot - lbegin, temp); - } - - return result; - } - - protected int maxInstanceId() { return MAX_INSTANCE_ID; } - - protected String getIdName(int id) { - if (id == Id_length) { return "length"; } - - if (prototypeFlag) { - switch (id) { - case Id_constructor: return "constructor"; - case Id_toString: return "toString"; - case Id_toLocaleString: return "toLocaleString"; - case Id_join: return "join"; - case Id_reverse: return "reverse"; - case Id_sort: return "sort"; - case Id_push: return "push"; - case Id_pop: return "pop"; - case Id_shift: return "shift"; - case Id_unshift: return "unshift"; - case Id_splice: return "splice"; - case Id_concat: return "concat"; - case Id_slice: return "slice"; - } - } - return null; - } - - private static final int - Id_length = 1, - MAX_INSTANCE_ID = 1; - - protected int mapNameToId(String s) { - if (s.equals("length")) { return Id_length; } - else if (prototypeFlag) { - return toPrototypeId(s); - } - return 0; - } - -// #string_id_map# - - private static int toPrototypeId(String s) { - int id; -// #generated# Last update: 2001-04-23 11:46:01 GMT+02:00 - L0: { id = 0; String X = null; int c; - L: switch (s.length()) { - case 3: X="pop";id=Id_pop; break L; - case 4: c=s.charAt(0); - if (c=='j') { X="join";id=Id_join; } - else if (c=='p') { X="push";id=Id_push; } - else if (c=='s') { X="sort";id=Id_sort; } - break L; - case 5: c=s.charAt(1); - if (c=='h') { X="shift";id=Id_shift; } - else if (c=='l') { X="slice";id=Id_slice; } - break L; - case 6: c=s.charAt(0); - if (c=='c') { X="concat";id=Id_concat; } - else if (c=='l') { X="length";id=Id_length; } - else if (c=='s') { X="splice";id=Id_splice; } - break L; - case 7: c=s.charAt(0); - if (c=='r') { X="reverse";id=Id_reverse; } - else if (c=='u') { X="unshift";id=Id_unshift; } - break L; - case 8: X="toString";id=Id_toString; break L; - case 11: X="constructor";id=Id_constructor; break L; - case 14: X="toLocaleString";id=Id_toLocaleString; break L; - } - if (X!=null && X!=s && !X.equals(s)) id = 0; - } -// #/generated# - return id; - } - - private static final int - Id_constructor = MAX_INSTANCE_ID + 1, - Id_toString = MAX_INSTANCE_ID + 2, - Id_toLocaleString = MAX_INSTANCE_ID + 3, - Id_join = MAX_INSTANCE_ID + 4, - Id_reverse = MAX_INSTANCE_ID + 5, - Id_sort = MAX_INSTANCE_ID + 6, - Id_push = MAX_INSTANCE_ID + 7, - Id_pop = MAX_INSTANCE_ID + 8, - Id_shift = MAX_INSTANCE_ID + 9, - Id_unshift = MAX_INSTANCE_ID + 10, - Id_splice = MAX_INSTANCE_ID + 11, - Id_concat = MAX_INSTANCE_ID + 12, - Id_slice = MAX_INSTANCE_ID + 13, - - MAX_PROTOTYPE_ID = MAX_INSTANCE_ID + 13; - -// #/string_id_map# - - private long length; - private Object[] dense; - private static final int maximumDenseLength = 10000; - - private boolean prototypeFlag; -} diff --git a/src/org/mozilla/javascript/NativeBoolean.java b/src/org/mozilla/javascript/NativeBoolean.java deleted file mode 100644 index 9841b5f..0000000 --- a/src/org/mozilla/javascript/NativeBoolean.java +++ /dev/null @@ -1,168 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * Igor Bukanov - * Mike McCabe - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -/** - * This class implements the Boolean native object. - * See ECMA 15.6. - * @author Norris Boyd - */ -public class NativeBoolean extends IdScriptable { - - public static void init(Context cx, Scriptable scope, boolean sealed) { - NativeBoolean obj = new NativeBoolean(); - obj.prototypeFlag = true; - obj.addAsPrototype(MAX_PROTOTYPE_ID, cx, scope, sealed); - } - - /** - * Zero-parameter constructor: just used to create Boolean.prototype - */ - public NativeBoolean() { - } - - public NativeBoolean(boolean b) { - booleanValue = b; - } - - public String getClassName() { - return "Boolean"; - } - - public Object getDefaultValue(Class typeHint) { - // This is actually non-ECMA, but will be proposed - // as a change in round 2. - if (typeHint == ScriptRuntime.BooleanClass) - return wrap_boolean(booleanValue); - return super.getDefaultValue(typeHint); - } - - public int methodArity(int methodId) { - if (prototypeFlag) { - if (methodId == Id_constructor) return 1; - if (methodId == Id_toString) return 0; - if (methodId == Id_valueOf) return 0; - } - return super.methodArity(methodId); - } - - public Object execMethod - (int methodId, IdFunction f, - Context cx, Scriptable scope, Scriptable thisObj, Object[] args) - throws JavaScriptException - { - if (prototypeFlag) { - if (methodId == Id_constructor) { - return jsConstructor(args, thisObj == null); - } - else if (methodId == Id_toString) { - return realThis(thisObj, f).jsFunction_toString(); - } - else if (methodId == Id_valueOf) { - return wrap_boolean(realThis(thisObj, f).jsFunction_valueOf()); - } - } - - return super.execMethod(methodId, f, cx, scope, thisObj, args); - } - - private NativeBoolean realThis(Scriptable thisObj, IdFunction f) { - while (!(thisObj instanceof NativeBoolean)) { - thisObj = nextInstanceCheck(thisObj, f, true); - } - return (NativeBoolean)thisObj; - } - - - private Object jsConstructor(Object[] args, boolean inNewExpr) { - boolean b = ScriptRuntime.toBoolean(args, 0); - if (inNewExpr) { - // new Boolean(val) creates a new boolean object. - return new NativeBoolean(b); - } - - // Boolean(val) converts val to a boolean. - return wrap_boolean(b); - } - - private String jsFunction_toString() { - return booleanValue ? "true" : "false"; - } - - private boolean jsFunction_valueOf() { - return booleanValue; - } - - protected String getIdName(int id) { - if (prototypeFlag) { - if (id == Id_constructor) return "constructor"; - if (id == Id_toString) return "toString"; - if (id == Id_valueOf) return "valueOf"; - } - return null; - } - -// #string_id_map# - - protected int mapNameToId(String s) { - if (!prototypeFlag) { return 0; } - int id; -// #generated# Last update: 2001-04-23 10:38:18 CEST - L0: { id = 0; String X = null; - int s_length = s.length(); - if (s_length==7) { X="valueOf";id=Id_valueOf; } - else if (s_length==8) { X="toString";id=Id_toString; } - else if (s_length==11) { X="constructor";id=Id_constructor; } - if (X!=null && X!=s && !X.equals(s)) id = 0; - } -// #/generated# - return id; - } - - private static final int - Id_constructor = 1, - Id_toString = 2, - Id_valueOf = 3, - MAX_PROTOTYPE_ID = 3; - -// #/string_id_map# - - private boolean booleanValue; - - private boolean prototypeFlag; -} diff --git a/src/org/mozilla/javascript/NativeCall.java b/src/org/mozilla/javascript/NativeCall.java deleted file mode 100644 index fdab7b6..0000000 --- a/src/org/mozilla/javascript/NativeCall.java +++ /dev/null @@ -1,171 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -/** - * This class implements the activation object. - * - * See ECMA 10.1.6 - * - * @see org.mozilla.javascript.Arguments - * @author Norris Boyd - */ -public final class NativeCall extends IdScriptable { - - static void init(Context cx, Scriptable scope, boolean sealed) { - NativeCall obj = new NativeCall(); - obj.prototypeFlag = true; - obj.addAsPrototype(MAX_PROTOTYPE_ID, cx, scope, sealed); - } - - NativeCall(Context cx, Scriptable scope, NativeFunction funObj, - Scriptable thisObj, Object[] args) - { - this.funObj = funObj; - this.thisObj = thisObj; - - setParentScope(scope); - // leave prototype null - - // save current activation - this.caller = cx.currentActivation; - cx.currentActivation = this; - - this.originalArgs = (args == null) ? ScriptRuntime.emptyArgs : args; - - // initialize values of arguments - String[] argNames = funObj.argNames; - if (argNames != null) { - for (int i=0; i < funObj.argCount; i++) { - Object val = i < args.length ? args[i] - : Undefined.instance; - super.put(argNames[i], this, val); - } - } - - // initialize "arguments" property - super.put("arguments", this, new Arguments(this)); - } - - private NativeCall() { - } - - public String getClassName() { - return "Call"; - } - - private static Object jsConstructor(Context cx, Object[] args, - Function ctorObj, boolean inNewExpr) - { - if (!inNewExpr) { - throw Context.reportRuntimeError1("msg.only.from.new", "Call"); - } - ScriptRuntime.checkDeprecated(cx, "Call"); - NativeCall result = new NativeCall(); - result.setPrototype(getObjectPrototype(ctorObj)); - return result; - } - - NativeCall getActivation(Function f) { - NativeCall x = this; - do { - if (x.funObj == f) - return x; - x = x.caller; - } while (x != null); - return null; - } - - public Function getFunctionObject() { - return funObj; - } - - public Object[] getOriginalArguments() { - return originalArgs; - } - - public NativeCall getCaller() { - return caller; - } - - public Scriptable getThisObj() { - return thisObj; - } - - public int methodArity(int methodId) { - if (prototypeFlag) { - if (methodId == Id_constructor) return 1; - } - return super.methodArity(methodId); - } - - public Object execMethod - (int methodId, IdFunction f, - Context cx, Scriptable scope, Scriptable thisObj, Object[] args) - throws JavaScriptException - { - if (prototypeFlag) { - if (methodId == Id_constructor) { - return jsConstructor(cx, args, f, thisObj == null); - } - } - return super.execMethod(methodId, f, cx, scope, thisObj, args); - } - - protected String getIdName(int id) { - if (prototypeFlag) { - if (id == Id_constructor) return "constructor"; - } - return null; - } - - protected int mapNameToId(String s) { - if (!prototypeFlag) { return 0; } - return s.equals("constructor") ? Id_constructor : 0; - } - - private static final int - Id_constructor = 1, - MAX_PROTOTYPE_ID = 1; - - NativeCall caller; - NativeFunction funObj; - Scriptable thisObj; - Object[] originalArgs; - public int debugPC; - - private boolean prototypeFlag; -} diff --git a/src/org/mozilla/javascript/NativeDate.java b/src/org/mozilla/javascript/NativeDate.java deleted file mode 100644 index e8bd7e0..0000000 --- a/src/org/mozilla/javascript/NativeDate.java +++ /dev/null @@ -1,1713 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * Mike McCabe - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -import java.util.Date; -import java.util.TimeZone; -import java.util.Locale; -import java.text.NumberFormat; -import java.text.DateFormat; -import java.text.SimpleDateFormat; - -/** - * This class implements the Date native object. - * See ECMA 15.9. - * @author Mike McCabe - */ -public class NativeDate extends IdScriptable { - - public static void init(Context cx, Scriptable scope, boolean sealed) { - NativeDate obj = new NativeDate(); - obj.prototypeFlag = true; - - // Set the value of the prototype Date to NaN ('invalid date'); - obj.date = ScriptRuntime.NaN; - - obj.addAsPrototype(MAX_PROTOTYPE_ID, cx, scope, sealed); - } - - public NativeDate() { - if (thisTimeZone == null) { - // j.u.TimeZone is synchronized, so setting class statics from it - // should be OK. - thisTimeZone = java.util.TimeZone.getDefault(); - LocalTZA = thisTimeZone.getRawOffset(); - } - } - - public String getClassName() { - return "Date"; - } - - public Object getDefaultValue(Class typeHint) { - if (typeHint == null) - typeHint = ScriptRuntime.StringClass; - return super.getDefaultValue(typeHint); - } - - protected void fillConstructorProperties - (Context cx, IdFunction ctor, boolean sealed) - { - addIdFunctionProperty(ctor, ConstructorId_UTC, sealed); - addIdFunctionProperty(ctor, ConstructorId_parse, sealed); - super.fillConstructorProperties(cx, ctor, sealed); - } - - public int methodArity(int methodId) { - if (prototypeFlag) { - switch (methodId) { - case ConstructorId_UTC: return 1; - case ConstructorId_parse: return 1; - case Id_constructor: return 1; - case Id_toString: return 0; - case Id_toTimeString: return 0; - case Id_toDateString: return 0; - case Id_toLocaleString: return 0; - case Id_toLocaleTimeString: return 0; - case Id_toLocaleDateString: return 0; - case Id_toUTCString: return 0; - case Id_valueOf: return 0; - case Id_getTime: return 0; - case Id_getYear: return 0; - case Id_getFullYear: return 0; - case Id_getUTCFullYear: return 0; - case Id_getMonth: return 0; - case Id_getUTCMonth: return 0; - case Id_getDate: return 0; - case Id_getUTCDate: return 0; - case Id_getDay: return 0; - case Id_getUTCDay: return 0; - case Id_getHours: return 0; - case Id_getUTCHours: return 0; - case Id_getMinutes: return 0; - case Id_getUTCMinutes: return 0; - case Id_getSeconds: return 0; - case Id_getUTCSeconds: return 0; - case Id_getMilliseconds: return 0; - case Id_getUTCMilliseconds: return 0; - case Id_getTimezoneOffset: return 0; - case Id_setTime: return 1; - case Id_setMilliseconds: return 1; - case Id_setUTCMilliseconds: return 1; - case Id_setSeconds: return 2; - case Id_setUTCSeconds: return 2; - case Id_setMinutes: return 3; - case Id_setUTCMinutes: return 3; - case Id_setHours: return 4; - case Id_setUTCHours: return 4; - case Id_setDate: return 1; - case Id_setUTCDate: return 1; - case Id_setMonth: return 2; - case Id_setUTCMonth: return 2; - case Id_setFullYear: return 3; - case Id_setUTCFullYear: return 3; - case Id_setYear: return 1; - } - } - return super.methodArity(methodId); - } - - public String toString() { - return date_format(date, FORMATSPEC_FULL); - } - - public Object execMethod - (int methodId, IdFunction f, - Context cx, Scriptable scope, Scriptable thisObj, Object[] args) - throws JavaScriptException - { - if (prototypeFlag) { - switch (methodId) { - case ConstructorId_UTC: - return wrap_double(jsStaticFunction_UTC(args)); - - case ConstructorId_parse: - return wrap_double(jsStaticFunction_parse - (ScriptRuntime.toString(args, 0))); - - case Id_constructor: - return jsConstructor(args, thisObj == null); - - case Id_toString: { - double t = realThis(thisObj, f, true).date; - return date_format(t, FORMATSPEC_FULL); - } - - case Id_toTimeString: { - double t = realThis(thisObj, f, true).date; - return date_format(t, FORMATSPEC_TIME); - } - - case Id_toDateString: { - double t = realThis(thisObj, f, true).date; - return date_format(t, FORMATSPEC_DATE); - } - - case Id_toLocaleString: { - double t = realThis(thisObj, f, true).date; - return jsFunction_toLocaleString(t); - } - - case Id_toLocaleTimeString: { - double t = realThis(thisObj, f, true).date; - return jsFunction_toLocaleTimeString(t); - } - - case Id_toLocaleDateString: { - double t = realThis(thisObj, f, true).date; - return jsFunction_toLocaleDateString(t); - } - - case Id_toUTCString: { - double t = realThis(thisObj, f, true).date; - if (t == t) { return jsFunction_toUTCString(t); } - return jsFunction_NaN_date_str; - } - - case Id_valueOf: - return wrap_double(realThis(thisObj, f, true).date); - - case Id_getTime: - return wrap_double(realThis(thisObj, f, true).date); - - case Id_getYear: { - double t = realThis(thisObj, f, true).date; - if (t == t) { t = jsFunction_getYear(cx, t); } - return wrap_double(t); - } - - case Id_getFullYear: { - double t = realThis(thisObj, f, true).date; - if (t == t) { t = YearFromTime(LocalTime(t)); } - return wrap_double(t); - } - - case Id_getUTCFullYear: { - double t = realThis(thisObj, f, true).date; - if (t == t) { t = YearFromTime(t); } - return wrap_double(t); - } - - case Id_getMonth: { - double t = realThis(thisObj, f, true).date; - if (t == t) { t = MonthFromTime(LocalTime(t)); } - return wrap_double(t); - } - - case Id_getUTCMonth: { - double t = realThis(thisObj, f, true).date; - if (t == t) { t = MonthFromTime(t); } - return wrap_double(t); - } - - case Id_getDate: { - double t = realThis(thisObj, f, true).date; - if (t == t) { t = DateFromTime(LocalTime(t)); } - return wrap_double(t); - } - - case Id_getUTCDate: { - double t = realThis(thisObj, f, true).date; - if (t == t) { t = DateFromTime(t); } - return wrap_double(t); - } - - case Id_getDay: { - double t = realThis(thisObj, f, true).date; - if (t == t) { t = WeekDay(LocalTime(t)); } - return wrap_double(t); - } - - case Id_getUTCDay: { - double t = realThis(thisObj, f, true).date; - if (t == t) { t = WeekDay(t); } - return wrap_double(t); - } - - case Id_getHours: { - double t = realThis(thisObj, f, true).date; - if (t == t) { t = HourFromTime(LocalTime(t)); } - return wrap_double(t); - } - - case Id_getUTCHours: { - double t = realThis(thisObj, f, true).date; - if (t == t) { t = HourFromTime(t); } - return wrap_double(t); - } - - case Id_getMinutes: { - double t = realThis(thisObj, f, true).date; - if (t == t) { t = MinFromTime(LocalTime(t)); } - return wrap_double(t); - } - - case Id_getUTCMinutes: { - double t = realThis(thisObj, f, true).date; - if (t == t) { t = MinFromTime(t); } - return wrap_double(t); - } - - case Id_getSeconds: { - double t = realThis(thisObj, f, true).date; - if (t == t) { t = SecFromTime(LocalTime(t)); } - return wrap_double(t); - } - - case Id_getUTCSeconds: { - double t = realThis(thisObj, f, true).date; - if (t == t) { t = SecFromTime(t); } - return wrap_double(t); - } - - case Id_getMilliseconds: { - double t = realThis(thisObj, f, true).date; - if (t == t) { t = msFromTime(LocalTime(t)); } - return wrap_double(t); - } - - case Id_getUTCMilliseconds: { - double t = realThis(thisObj, f, true).date; - if (t == t) { t = msFromTime(t); } - return wrap_double(t); - } - - case Id_getTimezoneOffset: { - double t = realThis(thisObj, f, true).date; - if (t == t) { t = jsFunction_getTimezoneOffset(t); } - return wrap_double(t); - } - - case Id_setTime: - return wrap_double(realThis(thisObj, f, true). - jsFunction_setTime(ScriptRuntime.toNumber(args, 0))); - - case Id_setMilliseconds: - return wrap_double(realThis(thisObj, f, false). - makeTime(args, 1, true)); - - case Id_setUTCMilliseconds: - return wrap_double(realThis(thisObj, f, false). - makeTime(args, 1, false)); - - case Id_setSeconds: - return wrap_double(realThis(thisObj, f, false). - makeTime(args, 2, true)); - - case Id_setUTCSeconds: - return wrap_double(realThis(thisObj, f, false). - makeTime(args, 2, false)); - - case Id_setMinutes: - return wrap_double(realThis(thisObj, f, false). - makeTime(args, 3, true)); - - case Id_setUTCMinutes: - return wrap_double(realThis(thisObj, f, false). - makeTime(args, 3, false)); - - case Id_setHours: - return wrap_double(realThis(thisObj, f, false). - makeTime(args, 4, true)); - - case Id_setUTCHours: - return wrap_double(realThis(thisObj, f, false). - makeTime(args, 4, false)); - - case Id_setDate: - return wrap_double(realThis(thisObj, f, false). - makeDate(args, 1, true)); - - case Id_setUTCDate: - return wrap_double(realThis(thisObj, f, false). - makeDate(args, 1, false)); - - case Id_setMonth: - return wrap_double(realThis(thisObj, f, false). - makeDate(args, 2, true)); - - case Id_setUTCMonth: - return wrap_double(realThis(thisObj, f, false). - makeDate(args, 2, false)); - - case Id_setFullYear: - return wrap_double(realThis(thisObj, f, false). - makeDate(args, 3, true)); - - case Id_setUTCFullYear: - return wrap_double(realThis(thisObj, f, false). - makeDate(args, 3, false)); - - case Id_setYear: - return wrap_double(realThis(thisObj, f, false). - jsFunction_setYear(ScriptRuntime.toNumber(args, 0))); - } - } - - return super.execMethod(methodId, f, cx, scope, thisObj, args); - } - - private NativeDate realThis(Scriptable thisObj, IdFunction f, - boolean readOnly) - { - while (!(thisObj instanceof NativeDate)) { - thisObj = nextInstanceCheck(thisObj, f, readOnly); - } - return (NativeDate)thisObj; - } - - /* ECMA helper functions */ - - private static final double HalfTimeDomain = 8.64e15; - private static final double HoursPerDay = 24.0; - private static final double MinutesPerHour = 60.0; - private static final double SecondsPerMinute = 60.0; - private static final double msPerSecond = 1000.0; - private static final double MinutesPerDay = (HoursPerDay * MinutesPerHour); - private static final double SecondsPerDay = (MinutesPerDay * SecondsPerMinute); - private static final double SecondsPerHour = (MinutesPerHour * SecondsPerMinute); - private static final double msPerDay = (SecondsPerDay * msPerSecond); - private static final double msPerHour = (SecondsPerHour * msPerSecond); - private static final double msPerMinute = (SecondsPerMinute * msPerSecond); - - private static double Day(double t) { - return Math.floor(t / msPerDay); - } - - private static double TimeWithinDay(double t) { - double result; - result = t % msPerDay; - if (result < 0) - result += msPerDay; - return result; - } - - private static int DaysInYear(int y) { - if (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) - return 366; - else - return 365; - } - - - /* math here has to be f.p, because we need - * floor((1968 - 1969) / 4) == -1 - */ - private static double DayFromYear(double y) { - return ((365 * ((y)-1970) + Math.floor(((y)-1969)/4.0) - - Math.floor(((y)-1901)/100.0) + Math.floor(((y)-1601)/400.0))); - } - - private static double TimeFromYear(double y) { - return DayFromYear(y) * msPerDay; - } - - private static int YearFromTime(double t) { - int lo = (int) Math.floor((t / msPerDay) / 366) + 1970; - int hi = (int) Math.floor((t / msPerDay) / 365) + 1970; - int mid; - - /* above doesn't work for negative dates... */ - if (hi < lo) { - int temp = lo; - lo = hi; - hi = temp; - } - - /* Use a simple binary search algorithm to find the right - year. This seems like brute force... but the computation - of hi and lo years above lands within one year of the - correct answer for years within a thousand years of - 1970; the loop below only requires six iterations - for year 270000. */ - while (hi > lo) { - mid = (hi + lo) / 2; - if (TimeFromYear(mid) > t) { - hi = mid - 1; - } else { - if (TimeFromYear(mid) <= t) { - int temp = mid + 1; - if (TimeFromYear(temp) > t) { - return mid; - } - lo = mid + 1; - } - } - } - return lo; - } - - private static boolean InLeapYear(double t) { - return DaysInYear(YearFromTime(t)) == 366; - } - - private static int DayWithinYear(double t) { - int year = YearFromTime(t); - return (int) (Day(t) - DayFromYear(year)); - } - /* - * The following array contains the day of year for the first day of - * each month, where index 0 is January, and day 0 is January 1. - */ - - private static double DayFromMonth(int m, boolean leap) { - int day = m * 30; - - if (m >= 7) { day += m / 2 - 1; } - else if (m >= 2) { day += (m - 1) / 2 - 1; } - else { day += m; } - - if (leap && m >= 2) { ++day; } - - return day; - } - - private static int MonthFromTime(double t) { - int d, step; - - d = DayWithinYear(t); - - if (d < (step = 31)) - return 0; - - // Originally coded as step += (InLeapYear(t) ? 29 : 28); - // but some jits always returned 28! - if (InLeapYear(t)) - step += 29; - else - step += 28; - - if (d < step) - return 1; - if (d < (step += 31)) - return 2; - if (d < (step += 30)) - return 3; - if (d < (step += 31)) - return 4; - if (d < (step += 30)) - return 5; - if (d < (step += 31)) - return 6; - if (d < (step += 31)) - return 7; - if (d < (step += 30)) - return 8; - if (d < (step += 31)) - return 9; - if (d < (step += 30)) - return 10; - return 11; - } - - private static int DateFromTime(double t) { - int d, step, next; - - d = DayWithinYear(t); - if (d <= (next = 30)) - return d + 1; - step = next; - - // Originally coded as next += (InLeapYear(t) ? 29 : 28); - // but some jits always returned 28! - if (InLeapYear(t)) - next += 29; - else - next += 28; - - if (d <= next) - return d - step; - step = next; - if (d <= (next += 31)) - return d - step; - step = next; - if (d <= (next += 30)) - return d - step; - step = next; - if (d <= (next += 31)) - return d - step; - step = next; - if (d <= (next += 30)) - return d - step; - step = next; - if (d <= (next += 31)) - return d - step; - step = next; - if (d <= (next += 31)) - return d - step; - step = next; - if (d <= (next += 30)) - return d - step; - step = next; - if (d <= (next += 31)) - return d - step; - step = next; - if (d <= (next += 30)) - return d - step; - step = next; - - return d - step; - } - - private static int WeekDay(double t) { - double result; - result = Day(t) + 4; - result = result % 7; - if (result < 0) - result += 7; - return (int) result; - } - - private static double Now() { - return (double) System.currentTimeMillis(); - } - - /* Should be possible to determine the need for this dynamically - * if we go with the workaround... I'm not using it now, because I - * can't think of any clean way to make toLocaleString() and the - * time zone (comment) in toString match the generated string - * values. Currently it's wrong-but-consistent in all but the - * most recent betas of the JRE - seems to work in 1.1.7. - */ - private final static boolean TZO_WORKAROUND = false; - private static double DaylightSavingTA(double t) { - if (!TZO_WORKAROUND) { - Date date = new Date((long) t); - if (thisTimeZone.inDaylightTime(date)) - return msPerHour; - else - return 0; - } else { - /* Use getOffset if inDaylightTime() is broken, because it - * seems to work acceptably. We don't switch over to it - * entirely, because it requires (expensive) exploded date arguments, - * and the api makes it impossible to handle dst - * changeovers cleanly. - */ - - // Hardcode the assumption that the changeover always - // happens at 2:00 AM: - t += LocalTZA + (HourFromTime(t) <= 2 ? msPerHour : 0); - - int year = YearFromTime(t); - double offset = thisTimeZone.getOffset(year > 0 ? 1 : 0, - year, - MonthFromTime(t), - DateFromTime(t), - WeekDay(t), - (int)TimeWithinDay(t)); - - if ((offset - LocalTZA) != 0) - return msPerHour; - else - return 0; - // return offset - LocalTZA; - } - } - - private static double LocalTime(double t) { - return t + LocalTZA + DaylightSavingTA(t); - } - - public static double internalUTC(double t) { - return t - LocalTZA - DaylightSavingTA(t - LocalTZA); - } - - private static int HourFromTime(double t) { - double result; - result = Math.floor(t / msPerHour) % HoursPerDay; - if (result < 0) - result += HoursPerDay; - return (int) result; - } - - private static int MinFromTime(double t) { - double result; - result = Math.floor(t / msPerMinute) % MinutesPerHour; - if (result < 0) - result += MinutesPerHour; - return (int) result; - } - - private static int SecFromTime(double t) { - double result; - result = Math.floor(t / msPerSecond) % SecondsPerMinute; - if (result < 0) - result += SecondsPerMinute; - return (int) result; - } - - private static int msFromTime(double t) { - double result; - result = t % msPerSecond; - if (result < 0) - result += msPerSecond; - return (int) result; - } - - private static double MakeTime(double hour, double min, - double sec, double ms) - { - return ((hour * MinutesPerHour + min) * SecondsPerMinute + sec) - * msPerSecond + ms; - } - - private static double MakeDay(double year, double month, double date) { - double result; - boolean leap; - double yearday; - double monthday; - - year += Math.floor(month / 12); - - month = month % 12; - if (month < 0) - month += 12; - - leap = (DaysInYear((int) year) == 366); - - yearday = Math.floor(TimeFromYear(year) / msPerDay); - monthday = DayFromMonth((int) month, leap); - - result = yearday - + monthday - + date - 1; - return result; - } - - private static double MakeDate(double day, double time) { - return day * msPerDay + time; - } - - private static double TimeClip(double d) { - if (d != d || - d == Double.POSITIVE_INFINITY || - d == Double.NEGATIVE_INFINITY || - Math.abs(d) > HalfTimeDomain) - { - return ScriptRuntime.NaN; - } - if (d > 0.0) - return Math.floor(d + 0.); - else - return Math.ceil(d + 0.); - } - - /* end of ECMA helper functions */ - - /* find UTC time from given date... no 1900 correction! */ - public static double date_msecFromDate(double year, double mon, - double mday, double hour, - double min, double sec, - double msec) - { - double day; - double time; - double result; - - day = MakeDay(year, mon, mday); - time = MakeTime(hour, min, sec, msec); - result = MakeDate(day, time); - return result; - } - - - private static final int MAXARGS = 7; - private static double jsStaticFunction_UTC(Object[] args) { - double array[] = new double[MAXARGS]; - int loop; - double d; - - for (loop = 0; loop < MAXARGS; loop++) { - if (loop < args.length) { - d = ScriptRuntime.toNumber(args[loop]); - if (d != d || Double.isInfinite(d)) { - return ScriptRuntime.NaN; - } - array[loop] = ScriptRuntime.toInteger(args[loop]); - } else { - array[loop] = 0; - } - } - - /* adjust 2-digit years into the 20th century */ - if (array[0] >= 0 && array[0] <= 99) - array[0] += 1900; - - /* if we got a 0 for 'date' (which is out of range) - * pretend it's a 1. (So Date.UTC(1972, 5) works) */ - if (array[2] < 1) - array[2] = 1; - - d = date_msecFromDate(array[0], array[1], array[2], - array[3], array[4], array[5], array[6]); - d = TimeClip(d); - return d; - // return new Double(d); - } - - /* - * Use ported code from jsdate.c rather than the locale-specific - * date-parsing code from Java, to keep js and rhino consistent. - * Is this the right strategy? - */ - - /* for use by date_parse */ - - /* replace this with byte arrays? Cheaper? */ - private static String wtb[] = { - "am", "pm", - "monday", "tuesday", "wednesday", "thursday", "friday", - "saturday", "sunday", - "january", "february", "march", "april", "may", "june", - "july", "august", "september", "october", "november", "december", - "gmt", "ut", "utc", "est", "edt", "cst", "cdt", - "mst", "mdt", "pst", "pdt" - /* time zone table needs to be expanded */ - }; - - private static int ttb[] = { - -1, -2, 0, 0, 0, 0, 0, 0, 0, /* AM/PM */ - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 10000 + 0, 10000 + 0, 10000 + 0, /* UT/UTC */ - 10000 + 5 * 60, 10000 + 4 * 60, /* EDT */ - 10000 + 6 * 60, 10000 + 5 * 60, - 10000 + 7 * 60, 10000 + 6 * 60, - 10000 + 8 * 60, 10000 + 7 * 60 - }; - - /* helper for date_parse */ - private static boolean date_regionMatches(String s1, int s1off, - String s2, int s2off, - int count) - { - boolean result = false; - /* return true if matches, otherwise, false */ - int s1len = s1.length(); - int s2len = s2.length(); - - while (count > 0 && s1off < s1len && s2off < s2len) { - if (Character.toLowerCase(s1.charAt(s1off)) != - Character.toLowerCase(s2.charAt(s2off))) - break; - s1off++; - s2off++; - count--; - } - - if (count == 0) { - result = true; - } - return result; - } - - private static double date_parseString(String s) { - double msec; - - int year = -1; - int mon = -1; - int mday = -1; - int hour = -1; - int min = -1; - int sec = -1; - char c = 0; - char si = 0; - int i = 0; - int n = -1; - double tzoffset = -1; - char prevc = 0; - int limit = 0; - boolean seenplusminus = false; - - if (s == null) // ??? Will s be null? - return ScriptRuntime.NaN; - limit = s.length(); - while (i < limit) { - c = s.charAt(i); - i++; - if (c <= ' ' || c == ',' || c == '-') { - if (i < limit) { - si = s.charAt(i); - if (c == '-' && '0' <= si && si <= '9') { - prevc = c; - } - } - continue; - } - if (c == '(') { /* comments) */ - int depth = 1; - while (i < limit) { - c = s.charAt(i); - i++; - if (c == '(') - depth++; - else if (c == ')') - if (--depth <= 0) - break; - } - continue; - } - if ('0' <= c && c <= '9') { - n = c - '0'; - while (i < limit && '0' <= (c = s.charAt(i)) && c <= '9') { - n = n * 10 + c - '0'; - i++; - } - - /* allow TZA before the year, so - * 'Wed Nov 05 21:49:11 GMT-0800 1997' - * works */ - - /* uses of seenplusminus allow : in TZA, so Java - * no-timezone style of GMT+4:30 works - */ - if ((prevc == '+' || prevc == '-')/* && year>=0 */) { - /* make ':' case below change tzoffset */ - seenplusminus = true; - - /* offset */ - if (n < 24) - n = n * 60; /* EG. "GMT-3" */ - else - n = n % 100 + n / 100 * 60; /* eg "GMT-0430" */ - if (prevc == '+') /* plus means east of GMT */ - n = -n; - if (tzoffset != 0 && tzoffset != -1) - return ScriptRuntime.NaN; - tzoffset = n; - } else if (n >= 70 || - (prevc == '/' && mon >= 0 && mday >= 0 && year < 0)) { - if (year >= 0) - return ScriptRuntime.NaN; - else if (c <= ' ' || c == ',' || c == '/' || i >= limit) - year = n < 100 ? n + 1900 : n; - else - return ScriptRuntime.NaN; - } else if (c == ':') { - if (hour < 0) - hour = /*byte*/ n; - else if (min < 0) - min = /*byte*/ n; - else - return ScriptRuntime.NaN; - } else if (c == '/') { - if (mon < 0) - mon = /*byte*/ n-1; - else if (mday < 0) - mday = /*byte*/ n; - else - return ScriptRuntime.NaN; - } else if (i < limit && c != ',' && c > ' ' && c != '-') { - return ScriptRuntime.NaN; - } else if (seenplusminus && n < 60) { /* handle GMT-3:30 */ - if (tzoffset < 0) - tzoffset -= n; - else - tzoffset += n; - } else if (hour >= 0 && min < 0) { - min = /*byte*/ n; - } else if (min >= 0 && sec < 0) { - sec = /*byte*/ n; - } else if (mday < 0) { - mday = /*byte*/ n; - } else { - return ScriptRuntime.NaN; - } - prevc = 0; - } else if (c == '/' || c == ':' || c == '+' || c == '-') { - prevc = c; - } else { - int st = i - 1; - int k; - while (i < limit) { - c = s.charAt(i); - if (!(('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'))) - break; - i++; - } - if (i <= st + 1) - return ScriptRuntime.NaN; - for (k = wtb.length; --k >= 0;) - if (date_regionMatches(wtb[k], 0, s, st, i-st)) { - int action = ttb[k]; - if (action != 0) { - if (action < 0) { - /* - * AM/PM. Count 12:30 AM as 00:30, 12:30 PM as - * 12:30, instead of blindly adding 12 if PM. - */ - if (hour > 12 || hour < 0) { - return ScriptRuntime.NaN; - } else { - if (action == -1 && hour == 12) { // am - hour = 0; - } else if (action == -2 && hour != 12) {// pm - hour += 12; - } - } - } else if (action <= 13) { /* month! */ - if (mon < 0) { - mon = /*byte*/ (action - 2); - } else { - return ScriptRuntime.NaN; - } - } else { - tzoffset = action - 10000; - } - } - break; - } - if (k < 0) - return ScriptRuntime.NaN; - prevc = 0; - } - } - if (year < 0 || mon < 0 || mday < 0) - return ScriptRuntime.NaN; - if (sec < 0) - sec = 0; - if (min < 0) - min = 0; - if (hour < 0) - hour = 0; - if (tzoffset == -1) { /* no time zone specified, have to use local */ - double time; - time = date_msecFromDate(year, mon, mday, hour, min, sec, 0); - return internalUTC(time); - } - - msec = date_msecFromDate(year, mon, mday, hour, min, sec, 0); - msec += tzoffset * msPerMinute; - return msec; - } - - private static double jsStaticFunction_parse(String s) { - return date_parseString(s); - } - - private static final int FORMATSPEC_FULL = 0; - private static final int FORMATSPEC_DATE = 1; - private static final int FORMATSPEC_TIME = 2; - - private static String date_format(double t, int format) { - if (t != t) - return jsFunction_NaN_date_str; - - StringBuffer result = new StringBuffer(60); - double local = LocalTime(t); - - /* offset from GMT in minutes. The offset includes daylight savings, - if it applies. */ - int minutes = (int) Math.floor((LocalTZA + DaylightSavingTA(t)) - / msPerMinute); - /* map 510 minutes to 0830 hours */ - int offset = (minutes / 60) * 100 + minutes % 60; - - String dateStr = Integer.toString(DateFromTime(local)); - String hourStr = Integer.toString(HourFromTime(local)); - String minStr = Integer.toString(MinFromTime(local)); - String secStr = Integer.toString(SecFromTime(local)); - String offsetStr = Integer.toString(offset > 0 ? offset : -offset); - int year = YearFromTime(local); - String yearStr = Integer.toString(year > 0 ? year : -year); - - /* Tue Oct 31 09:41:40 GMT-0800 (PST) 2000 */ - /* Tue Oct 31 2000 */ - /* 09:41:40 GMT-0800 (PST) */ - - if (format != FORMATSPEC_TIME) { - result.append(days[WeekDay(local)]); - result.append(' '); - result.append(months[MonthFromTime(local)]); - if (dateStr.length() == 1) - result.append(" 0"); - else - result.append(' '); - result.append(dateStr); - result.append(' '); - } - - if (format != FORMATSPEC_DATE) { - if (hourStr.length() == 1) - result.append('0'); - result.append(hourStr); - if (minStr.length() == 1) - result.append(":0"); - else - result.append(':'); - result.append(minStr); - if (secStr.length() == 1) - result.append(":0"); - else - result.append(':'); - result.append(secStr); - if (offset > 0) - result.append(" GMT+"); - else - result.append(" GMT-"); - for (int i = offsetStr.length(); i < 4; i++) - result.append('0'); - result.append(offsetStr); - - if (timeZoneFormatter == null) - timeZoneFormatter = new java.text.SimpleDateFormat("zzz"); - - if (timeZoneFormatter != null) { - result.append(" ("); - java.util.Date date = new Date((long) t); - result.append(timeZoneFormatter.format(date)); - result.append(')'); - } - if (format != FORMATSPEC_TIME) - result.append(' '); - } - - if (format != FORMATSPEC_TIME) { - if (year < 0) - result.append('-'); - for (int i = yearStr.length(); i < 4; i++) - result.append('0'); - result.append(yearStr); - } - - return result.toString(); - } - - /* the javascript constructor */ - private static Object jsConstructor(Object[] args, boolean inNewExpr) { - // if called as a function, just return a string - // representing the current time. - if (!inNewExpr) - return date_format(Now(), FORMATSPEC_FULL); - - NativeDate obj = new NativeDate(); - - // if called as a constructor with no args, - // return a new Date with the current time. - if (args.length == 0) { - obj.date = Now(); - return obj; - } - - // if called with just one arg - - if (args.length == 1) { - double date; - if (args[0] instanceof Scriptable) - args[0] = ((Scriptable) args[0]).getDefaultValue(null); - if (!(args[0] instanceof String)) { - // if it's not a string, use it as a millisecond date - date = ScriptRuntime.toNumber(args[0]); - } else { - // it's a string; parse it. - String str = (String) args[0]; - date = date_parseString(str); - } - obj.date = TimeClip(date); - return obj; - } - - // multiple arguments; year, month, day etc. - double array[] = new double[MAXARGS]; - int loop; - double d; - - for (loop = 0; loop < MAXARGS; loop++) { - if (loop < args.length) { - d = ScriptRuntime.toNumber(args[loop]); - - if (d != d || Double.isInfinite(d)) { - obj.date = ScriptRuntime.NaN; - return obj; - } - array[loop] = ScriptRuntime.toInteger(args[loop]); - } else { - array[loop] = 0; - } - } - - /* adjust 2-digit years into the 20th century */ - if (array[0] >= 0 && array[0] <= 99) - array[0] += 1900; - - /* if we got a 0 for 'date' (which is out of range) - * pretend it's a 1 */ - if (array[2] < 1) - array[2] = 1; - - double day = MakeDay(array[0], array[1], array[2]); - double time = MakeTime(array[3], array[4], array[5], array[6]); - time = MakeDate(day, time); - time = internalUTC(time); - obj.date = TimeClip(time); - - return obj; - } - - /* constants for toString, toUTCString */ - private static String jsFunction_NaN_date_str = "Invalid Date"; - - private static String[] days = { - "Sun","Mon","Tue","Wed","Thu","Fri","Sat" - }; - - private static String[] months = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }; - - private static String toLocale_helper(double t, - java.text.DateFormat formatter) - { - if (t != t) - return jsFunction_NaN_date_str; - - java.util.Date tempdate = new Date((long) t); - return formatter.format(tempdate); - } - - private static String jsFunction_toLocaleString(double date) { - if (localeDateTimeFormatter == null) - localeDateTimeFormatter = - DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG); - - return toLocale_helper(date, localeDateTimeFormatter); - } - - private static String jsFunction_toLocaleTimeString(double date) { - if (localeTimeFormatter == null) - localeTimeFormatter = DateFormat.getTimeInstance(DateFormat.LONG); - - return toLocale_helper(date, localeTimeFormatter); - } - - private static String jsFunction_toLocaleDateString(double date) { - if (localeDateFormatter == null) - localeDateFormatter = DateFormat.getDateInstance(DateFormat.LONG); - - return toLocale_helper(date, localeDateFormatter); - } - - private static String jsFunction_toUTCString(double date) { - StringBuffer result = new StringBuffer(60); - - String dateStr = Integer.toString(DateFromTime(date)); - String hourStr = Integer.toString(HourFromTime(date)); - String minStr = Integer.toString(MinFromTime(date)); - String secStr = Integer.toString(SecFromTime(date)); - int year = YearFromTime(date); - String yearStr = Integer.toString(year > 0 ? year : -year); - - result.append(days[WeekDay(date)]); - result.append(", "); - if (dateStr.length() == 1) - result.append('0'); - result.append(dateStr); - result.append(' '); - result.append(months[MonthFromTime(date)]); - if (year < 0) - result.append(" -"); - else - result.append(' '); - int i; - for (i = yearStr.length(); i < 4; i++) - result.append('0'); - result.append(yearStr); - - if (hourStr.length() == 1) - result.append(" 0"); - else - result.append(' '); - result.append(hourStr); - if (minStr.length() == 1) - result.append(":0"); - else - result.append(':'); - result.append(minStr); - if (secStr.length() == 1) - result.append(":0"); - else - result.append(':'); - result.append(secStr); - - result.append(" GMT"); - return result.toString(); - } - - private static double jsFunction_getYear(Context cx, double date) { - - int result = YearFromTime(LocalTime(date)); - - if (cx.hasFeature(Context.FEATURE_NON_ECMA_GET_YEAR)) { - if (result >= 1900 && result < 2000) { - result -= 1900; - } - } - else { - result -= 1900; - } - return result; - } - - private static double jsFunction_getTimezoneOffset(double date) { - return (date - LocalTime(date)) / msPerMinute; - } - - public double jsFunction_setTime(double time) { - this.date = TimeClip(time); - return this.date; - } - - private double makeTime(Object[] args, int maxargs, boolean local) { - int i; - double conv[] = new double[4]; - double hour, min, sec, msec; - double lorutime; /* Local or UTC version of date */ - - double time; - double result; - - double date = this.date; - - /* just return NaN if the date is already NaN */ - if (date != date) - return date; - - /* Satisfy the ECMA rule that if a function is called with - * fewer arguments than the specified formal arguments, the - * remaining arguments are set to undefined. Seems like all - * the Date.setWhatever functions in ECMA are only varargs - * beyond the first argument; this should be set to undefined - * if it's not given. This means that "d = new Date(); - * d.setMilliseconds()" returns NaN. Blech. - */ - if (args.length == 0) - args = ScriptRuntime.padArguments(args, 1); - - for (i = 0; i < args.length && i < maxargs; i++) { - conv[i] = ScriptRuntime.toNumber(args[i]); - - // limit checks that happen in MakeTime in ECMA. - if (conv[i] != conv[i] || Double.isInfinite(conv[i])) { - this.date = ScriptRuntime.NaN; - return this.date; - } - conv[i] = ScriptRuntime.toInteger(conv[i]); - } - - if (local) - lorutime = LocalTime(date); - else - lorutime = date; - - i = 0; - int stop = args.length; - - if (maxargs >= 4 && i < stop) - hour = conv[i++]; - else - hour = HourFromTime(lorutime); - - if (maxargs >= 3 && i < stop) - min = conv[i++]; - else - min = MinFromTime(lorutime); - - if (maxargs >= 2 && i < stop) - sec = conv[i++]; - else - sec = SecFromTime(lorutime); - - if (maxargs >= 1 && i < stop) - msec = conv[i++]; - else - msec = msFromTime(lorutime); - - time = MakeTime(hour, min, sec, msec); - result = MakeDate(Day(lorutime), time); - - if (local) - result = internalUTC(result); - date = TimeClip(result); - - this.date = date; - return date; - } - - private double jsFunction_setHours(Object[] args) { - return makeTime(args, 4, true); - } - - private double jsFunction_setUTCHours(Object[] args) { - return makeTime(args, 4, false); - } - - private double makeDate(Object[] args, int maxargs, boolean local) { - int i; - double conv[] = new double[3]; - double year, month, day; - double lorutime; /* local or UTC version of date */ - double result; - - double date = this.date; - - /* See arg padding comment in makeTime.*/ - if (args.length == 0) - args = ScriptRuntime.padArguments(args, 1); - - for (i = 0; i < args.length && i < maxargs; i++) { - conv[i] = ScriptRuntime.toNumber(args[i]); - - // limit checks that happen in MakeDate in ECMA. - if (conv[i] != conv[i] || Double.isInfinite(conv[i])) { - this.date = ScriptRuntime.NaN; - return this.date; - } - conv[i] = ScriptRuntime.toInteger(conv[i]); - } - - /* return NaN if date is NaN and we're not setting the year, - * If we are, use 0 as the time. */ - if (date != date) { - if (args.length < 3) { - return ScriptRuntime.NaN; - } else { - lorutime = 0; - } - } else { - if (local) - lorutime = LocalTime(date); - else - lorutime = date; - } - - i = 0; - int stop = args.length; - - if (maxargs >= 3 && i < stop) - year = conv[i++]; - else - year = YearFromTime(lorutime); - - if (maxargs >= 2 && i < stop) - month = conv[i++]; - else - month = MonthFromTime(lorutime); - - if (maxargs >= 1 && i < stop) - day = conv[i++]; - else - day = DateFromTime(lorutime); - - day = MakeDay(year, month, day); /* day within year */ - result = MakeDate(day, TimeWithinDay(lorutime)); - - if (local) - result = internalUTC(result); - - date = TimeClip(result); - - this.date = date; - return date; - } - - private double jsFunction_setYear(double year) { - double day, result; - if (year != year || Double.isInfinite(year)) { - this.date = ScriptRuntime.NaN; - return this.date; - } - - if (this.date != this.date) { - this.date = 0; - } else { - this.date = LocalTime(this.date); - } - - if (year >= 0 && year <= 99) - year += 1900; - - day = MakeDay(year, MonthFromTime(this.date), DateFromTime(this.date)); - result = MakeDate(day, TimeWithinDay(this.date)); - result = internalUTC(result); - - this.date = TimeClip(result); - return this.date; - } - - protected String getIdName(int id) { - if (prototypeFlag) { - switch (id) { - case ConstructorId_UTC: return "UTC"; - case ConstructorId_parse: return "parse"; - case Id_constructor: return "constructor"; - case Id_toString: return "toString"; - case Id_toTimeString: return "toTimeString"; - case Id_toDateString: return "toDateString"; - case Id_toLocaleString: return "toLocaleString"; - case Id_toLocaleTimeString: return "toLocaleTimeString"; - case Id_toLocaleDateString: return "toLocaleDateString"; - case Id_toUTCString: return "toUTCString"; - case Id_valueOf: return "valueOf"; - case Id_getTime: return "getTime"; - case Id_getYear: return "getYear"; - case Id_getFullYear: return "getFullYear"; - case Id_getUTCFullYear: return "getUTCFullYear"; - case Id_getMonth: return "getMonth"; - case Id_getUTCMonth: return "getUTCMonth"; - case Id_getDate: return "getDate"; - case Id_getUTCDate: return "getUTCDate"; - case Id_getDay: return "getDay"; - case Id_getUTCDay: return "getUTCDay"; - case Id_getHours: return "getHours"; - case Id_getUTCHours: return "getUTCHours"; - case Id_getMinutes: return "getMinutes"; - case Id_getUTCMinutes: return "getUTCMinutes"; - case Id_getSeconds: return "getSeconds"; - case Id_getUTCSeconds: return "getUTCSeconds"; - case Id_getMilliseconds: return "getMilliseconds"; - case Id_getUTCMilliseconds: return "getUTCMilliseconds"; - case Id_getTimezoneOffset: return "getTimezoneOffset"; - case Id_setTime: return "setTime"; - case Id_setMilliseconds: return "setMilliseconds"; - case Id_setUTCMilliseconds: return "setUTCMilliseconds"; - case Id_setSeconds: return "setSeconds"; - case Id_setUTCSeconds: return "setUTCSeconds"; - case Id_setMinutes: return "setMinutes"; - case Id_setUTCMinutes: return "setUTCMinutes"; - case Id_setHours: return "setHours"; - case Id_setUTCHours: return "setUTCHours"; - case Id_setDate: return "setDate"; - case Id_setUTCDate: return "setUTCDate"; - case Id_setMonth: return "setMonth"; - case Id_setUTCMonth: return "setUTCMonth"; - case Id_setFullYear: return "setFullYear"; - case Id_setUTCFullYear: return "setUTCFullYear"; - case Id_setYear: return "setYear"; - } - } - return null; - } - -// #string_id_map# - - protected int mapNameToId(String s) { - if (!prototypeFlag) { return 0; } - int id; -// #generated# Last update: 2001-04-22 23:46:59 CEST - L0: { id = 0; String X = null; int c; - L: switch (s.length()) { - case 6: X="getDay";id=Id_getDay; break L; - case 7: switch (s.charAt(3)) { - case 'D': c=s.charAt(0); - if (c=='g') { X="getDate";id=Id_getDate; } - else if (c=='s') { X="setDate";id=Id_setDate; } - break L; - case 'T': c=s.charAt(0); - if (c=='g') { X="getTime";id=Id_getTime; } - else if (c=='s') { X="setTime";id=Id_setTime; } - break L; - case 'Y': c=s.charAt(0); - if (c=='g') { X="getYear";id=Id_getYear; } - else if (c=='s') { X="setYear";id=Id_setYear; } - break L; - case 'u': X="valueOf";id=Id_valueOf; break L; - } break L; - case 8: c=s.charAt(0); - if (c=='g') { - c=s.charAt(7); - if (c=='h') { X="getMonth";id=Id_getMonth; } - else if (c=='s') { X="getHours";id=Id_getHours; } - } - else if (c=='s') { - c=s.charAt(7); - if (c=='h') { X="setMonth";id=Id_setMonth; } - else if (c=='s') { X="setHours";id=Id_setHours; } - } - else if (c=='t') { X="toString";id=Id_toString; } - break L; - case 9: X="getUTCDay";id=Id_getUTCDay; break L; - case 10: c=s.charAt(3); - if (c=='M') { - c=s.charAt(0); - if (c=='g') { X="getMinutes";id=Id_getMinutes; } - else if (c=='s') { X="setMinutes";id=Id_setMinutes; } - } - else if (c=='S') { - c=s.charAt(0); - if (c=='g') { X="getSeconds";id=Id_getSeconds; } - else if (c=='s') { X="setSeconds";id=Id_setSeconds; } - } - else if (c=='U') { - c=s.charAt(0); - if (c=='g') { X="getUTCDate";id=Id_getUTCDate; } - else if (c=='s') { X="setUTCDate";id=Id_setUTCDate; } - } - break L; - case 11: switch (s.charAt(3)) { - case 'F': c=s.charAt(0); - if (c=='g') { X="getFullYear";id=Id_getFullYear; } - else if (c=='s') { X="setFullYear";id=Id_setFullYear; } - break L; - case 'M': X="toGMTString";id=Id_toGMTString; break L; - case 'T': X="toUTCString";id=Id_toUTCString; break L; - case 'U': c=s.charAt(0); - if (c=='g') { - c=s.charAt(9); - if (c=='r') { X="getUTCHours";id=Id_getUTCHours; } - else if (c=='t') { X="getUTCMonth";id=Id_getUTCMonth; } - } - else if (c=='s') { - c=s.charAt(9); - if (c=='r') { X="setUTCHours";id=Id_setUTCHours; } - else if (c=='t') { X="setUTCMonth";id=Id_setUTCMonth; } - } - break L; - case 's': X="constructor";id=Id_constructor; break L; - } break L; - case 12: c=s.charAt(2); - if (c=='D') { X="toDateString";id=Id_toDateString; } - else if (c=='T') { X="toTimeString";id=Id_toTimeString; } - break L; - case 13: c=s.charAt(0); - if (c=='g') { - c=s.charAt(6); - if (c=='M') { X="getUTCMinutes";id=Id_getUTCMinutes; } - else if (c=='S') { X="getUTCSeconds";id=Id_getUTCSeconds; } - } - else if (c=='s') { - c=s.charAt(6); - if (c=='M') { X="setUTCMinutes";id=Id_setUTCMinutes; } - else if (c=='S') { X="setUTCSeconds";id=Id_setUTCSeconds; } - } - break L; - case 14: c=s.charAt(0); - if (c=='g') { X="getUTCFullYear";id=Id_getUTCFullYear; } - else if (c=='s') { X="setUTCFullYear";id=Id_setUTCFullYear; } - else if (c=='t') { X="toLocaleString";id=Id_toLocaleString; } - break L; - case 15: c=s.charAt(0); - if (c=='g') { X="getMilliseconds";id=Id_getMilliseconds; } - else if (c=='s') { X="setMilliseconds";id=Id_setMilliseconds; } - break L; - case 17: X="getTimezoneOffset";id=Id_getTimezoneOffset; break L; - case 18: c=s.charAt(0); - if (c=='g') { X="getUTCMilliseconds";id=Id_getUTCMilliseconds; } - else if (c=='s') { X="setUTCMilliseconds";id=Id_setUTCMilliseconds; } - else if (c=='t') { - c=s.charAt(8); - if (c=='D') { X="toLocaleDateString";id=Id_toLocaleDateString; } - else if (c=='T') { X="toLocaleTimeString";id=Id_toLocaleTimeString; } - } - break L; - } - if (X!=null && X!=s && !X.equals(s)) id = 0; - } -// #/generated# - return id; - } - - private static final int - ConstructorId_UTC = -2, - ConstructorId_parse = -1, - - Id_constructor = 1, - Id_toString = 2, - Id_toTimeString = 3, - Id_toDateString = 4, - Id_toLocaleString = 5, - Id_toLocaleTimeString = 6, - Id_toLocaleDateString = 7, - Id_toUTCString = 8, - Id_valueOf = 9, - Id_getTime = 10, - Id_getYear = 11, - Id_getFullYear = 12, - Id_getUTCFullYear = 13, - Id_getMonth = 14, - Id_getUTCMonth = 15, - Id_getDate = 16, - Id_getUTCDate = 17, - Id_getDay = 18, - Id_getUTCDay = 19, - Id_getHours = 20, - Id_getUTCHours = 21, - Id_getMinutes = 22, - Id_getUTCMinutes = 23, - Id_getSeconds = 24, - Id_getUTCSeconds = 25, - Id_getMilliseconds = 26, - Id_getUTCMilliseconds = 27, - Id_getTimezoneOffset = 28, - Id_setTime = 29, - Id_setMilliseconds = 30, - Id_setUTCMilliseconds = 31, - Id_setSeconds = 32, - Id_setUTCSeconds = 33, - Id_setMinutes = 34, - Id_setUTCMinutes = 35, - Id_setHours = 36, - Id_setUTCHours = 37, - Id_setDate = 38, - Id_setUTCDate = 39, - Id_setMonth = 40, - Id_setUTCMonth = 41, - Id_setFullYear = 42, - Id_setUTCFullYear = 43, - Id_setYear = 44, - - MAX_PROTOTYPE_ID = 44; - - private static final int - Id_toGMTString = Id_toUTCString; // Alias, see Ecma B.2.6 -// #/string_id_map# - - /* cached values */ - private static java.util.TimeZone thisTimeZone; - private static double LocalTZA; - private static java.text.DateFormat timeZoneFormatter; - private static java.text.DateFormat localeDateTimeFormatter; - private static java.text.DateFormat localeDateFormatter; - private static java.text.DateFormat localeTimeFormatter; - - private double date; - - private boolean prototypeFlag; - - public long getRawTime() { return (long)this.date; } -} - - diff --git a/src/org/mozilla/javascript/NativeError.java b/src/org/mozilla/javascript/NativeError.java deleted file mode 100644 index 982d0fc..0000000 --- a/src/org/mozilla/javascript/NativeError.java +++ /dev/null @@ -1,204 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Igor Bukanov - * Roger Lawrence - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - - -package org.mozilla.javascript; - -/** - * - * The class of error objects - * - * ECMA 15.11 - */ -public class NativeError extends IdScriptable { - - public static void init(Context cx, Scriptable scope, boolean sealed) { - NativeError obj = new NativeError(); - obj.prototypeFlag = true; - obj.messageValue = ""; - obj.nameValue = "Error"; - obj.addAsPrototype(MAX_PROTOTYPE_ID, cx, scope, sealed); - } - - protected int getIdDefaultAttributes(int id) { - if (id == Id_message || id == Id_name) { return EMPTY; } - return super.getIdDefaultAttributes(id); - } - - protected boolean hasIdValue(int id) { - if (id == Id_message) { return messageValue != NOT_FOUND; } - if (id == Id_name) { return nameValue != NOT_FOUND; } - return super.hasIdValue(id); - } - - protected Object getIdValue(int id) { - if (id == Id_message) { return messageValue; } - if (id == Id_name) { return nameValue; } - return super.getIdValue(id); - } - - protected void setIdValue(int id, Object value) { - if (id == Id_message) { messageValue = value; return; } - if (id == Id_name) { nameValue = value; return; } - super.setIdValue(id, value); - } - - protected void deleteIdValue(int id) { - if (id == Id_message) { messageValue = NOT_FOUND; return; } - if (id == Id_name) { nameValue = NOT_FOUND; return; } - super.deleteIdValue(id); - } - - public int methodArity(int methodId) { - if (prototypeFlag) { - if (methodId == Id_constructor) return 1; - if (methodId == Id_toString) return 0; - } - return super.methodArity(methodId); - } - - public Object execMethod - (int methodId, IdFunction f, - Context cx, Scriptable scope, Scriptable thisObj, Object[] args) - throws JavaScriptException - { - if (prototypeFlag) { - if (methodId == Id_constructor) { - return jsConstructor(cx, args, f, thisObj == null); - } - else if (methodId == Id_toString) { - return realThis(thisObj, f).toString(); - } - } - return super.execMethod(methodId, f, cx, scope, thisObj, args); - } - - private NativeError realThis(Scriptable thisObj, IdFunction f) { - while (!(thisObj instanceof NativeError)) { - thisObj = nextInstanceCheck(thisObj, f, true); - } - return (NativeError)thisObj; - } - - private static Object jsConstructor(Context cx, Object[] args, - Function funObj, boolean inNewExpr) - { - NativeError result = new NativeError(); - if (args.length >= 1) - result.messageValue = ScriptRuntime.toString(args[0]); - result.setPrototype(getClassPrototype(funObj, "Error")); - return result; - } - - public String getClassName() { - return "Error"; - } - - public String toString() { - return getName() + ": " + getMessage(); - } - - public String getName() { - Object val = nameValue; - return ScriptRuntime.toString(val != NOT_FOUND ? val - : Undefined.instance); - } - - public String getMessage() { - Object val = messageValue; - return ScriptRuntime.toString(val != NOT_FOUND ? val - : Undefined.instance); - } - - protected int maxInstanceId() { return MAX_INSTANCE_ID; } - - protected String getIdName(int id) { - if (id == Id_message) { return "message"; } - if (id == Id_name) { return "name"; } - if (prototypeFlag) { - if (id == Id_constructor) return "constructor"; - if (id == Id_toString) return "toString"; - } - return null; - } - -// #string_id_map# - - private static final int - Id_message = 1, - Id_name = 2, - - MAX_INSTANCE_ID = 2; - - protected int mapNameToId(String s) { - int id; -// #generated# Last update: 2001-05-19 21:55:23 CEST - L0: { id = 0; String X = null; - int s_length = s.length(); - if (s_length==4) { X="name";id=Id_name; } - else if (s_length==7) { X="message";id=Id_message; } - if (X!=null && X!=s && !X.equals(s)) id = 0; - } -// #/generated# -// #/string_id_map# - - if (id != 0 || !prototypeFlag) { return id; } - -// #string_id_map# -// #generated# Last update: 2001-05-19 21:55:23 CEST - L0: { id = 0; String X = null; - int s_length = s.length(); - if (s_length==8) { X="toString";id=Id_toString; } - else if (s_length==11) { X="constructor";id=Id_constructor; } - if (X!=null && X!=s && !X.equals(s)) id = 0; - } -// #/generated# - return id; - } - - private static final int - Id_constructor = MAX_INSTANCE_ID + 1, - Id_toString = MAX_INSTANCE_ID + 2, - - MAX_PROTOTYPE_ID = MAX_INSTANCE_ID + 2; - -// #/string_id_map# - - private Object messageValue = NOT_FOUND; - private Object nameValue = NOT_FOUND; - - private boolean prototypeFlag; -} diff --git a/src/org/mozilla/javascript/NativeFunction.java b/src/org/mozilla/javascript/NativeFunction.java deleted file mode 100644 index dbc2e77..0000000 --- a/src/org/mozilla/javascript/NativeFunction.java +++ /dev/null @@ -1,798 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * Igor Bukanov - * Roger Lawrence - * Mike McCabe - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -import java.util.Hashtable; - -/** - * This class implements the Function native object. - * See ECMA 15.3. - * @author Norris Boyd - */ -public class NativeFunction extends BaseFunction { - - private boolean nextIs(int i, int token) { - if (i + 1 < source.length()) - return source.charAt(i + 1) == token; - return false; - } - - // how much to indent - private final static int OFFSET = 4; - - // less how much for case labels - private final static int SETBACK = 2; - - // whether to do a debug print of the source information, when - // decompiling. - private static final boolean printSource = false; - - /** - * Decompile the source information associated with this js - * function/script back into a string. For the most part, this - * just means translating tokens back to their string - * representations; there's a little bit of lookahead logic to - * decide the proper spacing/indentation. Most of the work in - * mapping the original source to the prettyprinted decompiled - * version is done by the parser. - * - * Note that support for Context.decompileFunctionBody is hacked - * on through special cases; I suspect that js makes a distinction - * between function header and function body that rhino - * decompilation does not. - * - * @param cx Current context - * - * @param indent How much to indent the decompiled result - * - * @param justbody Whether the decompilation should omit the - * function header and trailing brace. - */ - - public String decompile(Context cx, int indent, boolean justbody) { - StringBuffer result = new StringBuffer(); - decompile(indent, true, justbody, result); - return result.toString(); - - } - - private void decompile(int indent, boolean toplevel, boolean justbody, - StringBuffer result) - { - if (source == null) { - if (!justbody) { - result.append("function "); - result.append(getFunctionName()); - result.append("() {\n\t"); - } - result.append("[native code]\n"); - if (!justbody) { - result.append("}\n"); - } - return; - } - - // Spew tokens in source, for debugging. - // as TYPE number char - if (printSource) { - System.err.println("length:" + source.length()); - for (int i = 0; i < source.length(); i++) { - // Note that tokenToName will fail unless Context.printTrees - // is true. - String tokenname = TokenStream.tokenToName(source.charAt(i)); - if (tokenname == null) - tokenname = "---"; - String pad = tokenname.length() > 7 - ? "\t" - : "\t\t"; - System.err.println - (tokenname - + pad + (int)source.charAt(i) - + "\t'" + ScriptRuntime.escapeString - (source.substring(i, i+1)) - + "'"); - } - System.err.println(); - } - - int i = 0; - - if (source.length() > 0) { - /* special-case FUNCTION as the first token; if it is, - * (and it's not followed by a NAME or LP) then we're - * decompiling a function (and not the toplevel script.) - - * FUNCTION appearing elsewhere is an escape that means we'll - * need to call toString of the given function (object). - - * If not at the top level, don't add an initial indent; - * let the caller do it, so functions as expressions look - * reasonable. */ - - if (toplevel) { - // add an initial newline to exactly match js. - if (!justbody) - result.append('\n'); - for (int j = 0; j < indent; j++) - result.append(' '); - } - - if (source.charAt(0) == TokenStream.FUNCTION - // make sure it's not a script that begins with a - // reference to a function definition. - && source.length() > 1 - && (source.charAt(1) == TokenStream.NAME - || source.charAt(1) == TokenStream.LP)) - { - if (!justbody) { - result.append("function "); - - /* version != 1.2 Function constructor behavior - if - * there's no function name in the source info, and - * the names[0] entry is the empty string, then it must - * have been created by the Function constructor; - * print 'anonymous' as the function name if the - * version (under which the function was compiled) is - * less than 1.2... or if it's greater than 1.2, because - * we need to be closer to ECMA. (ToSource, please?) - */ - if (nextIs(i, TokenStream.LP) - && this.version != Context.VERSION_1_2 - && this.functionName != null - && this.functionName.equals("anonymous")) - result.append("anonymous"); - i++; - } else { - /* Skip past the entire function header to the next EOL. - * Depends on how NAMEs are encoded. - */ - while (i < source.length() - && (source.charAt(i) != TokenStream.EOL - // the length char of a NAME sequence - // can look like an EOL. - || (i > 0 - && source.charAt(i-1) == TokenStream.NAME))) - { - i++; - } - // Skip past the EOL, too. - i++; - } - } - } - - while (i < source.length()) { - int stop; - switch(source.charAt(i)) { - case TokenStream.NAME: - case TokenStream.OBJECT: // re-wrapped in '/'s in parser... - /* NAMEs are encoded as NAME, (char) length, string... - * Note that lookahead for detecting labels depends on - * this encoding; change there if this changes. - - * Also change function-header skipping code above, - * used when decompling under decompileFunctionBody. - */ - i++; - stop = i + (int)source.charAt(i); - result.append(source.substring(i + 1, stop + 1)); - i = stop; - break; - - case TokenStream.NUMBER: - i++; - long lbits = 0; - switch(source.charAt(i)) { - case 'S': - i++; - result.append((int)source.charAt(i)); - break; - - case 'J': - i++; - lbits |= (long)source.charAt(i++) << 48; - lbits |= (long)source.charAt(i++) << 32; - lbits |= (long)source.charAt(i++) << 16; - lbits |= (long)source.charAt(i); - - result.append(lbits); - break; - case 'D': - i++; - - lbits |= (long)source.charAt(i++) << 48; - lbits |= (long)source.charAt(i++) << 32; - lbits |= (long)source.charAt(i++) << 16; - lbits |= (long)source.charAt(i); - - double dval = Double.longBitsToDouble(lbits); - result.append(ScriptRuntime.numberToString(dval, 10)); - break; - } - break; - - case TokenStream.STRING: - i++; - stop = i + (int)source.charAt(i); - result.append('"'); - result.append(ScriptRuntime.escapeString - (source.substring(i + 1, stop + 1))); - result.append('"'); - i = stop; - break; - - case TokenStream.PRIMARY: - i++; - switch(source.charAt(i)) { - case TokenStream.TRUE: - result.append("true"); - break; - - case TokenStream.FALSE: - result.append("false"); - break; - - case TokenStream.NULL: - result.append("null"); - break; - - case TokenStream.THIS: - result.append("this"); - break; - - case TokenStream.TYPEOF: - result.append("typeof"); - break; - - case TokenStream.VOID: - result.append("void"); - break; - - case TokenStream.UNDEFINED: - result.append("undefined"); - break; - } - break; - - case TokenStream.FUNCTION: { - /* decompile a FUNCTION token as an escape; call - * toString on the nth enclosed nested function, - * where n is given by the byte that follows. - */ - - i++; - int functionNumber = source.charAt(i); - if (nestedFunctions == null - || functionNumber > nestedFunctions.length) - { - String message; - if (functionName != null && functionName.length() > 0) { - message = Context.getMessage2 - ("msg.no.function.ref.found.in", - new Integer((int)source.charAt(i)), functionName); - } else { - message = Context.getMessage1 - ("msg.no.function.ref.found", - new Integer((int)source.charAt(i))); - } - throw Context.reportRuntimeError(message); - } - nestedFunctions[functionNumber]. - decompile(indent, false, false, result); - break; - } - case TokenStream.COMMA: - result.append(", "); - break; - - case TokenStream.LC: - if (nextIs(i, TokenStream.EOL)) - indent += OFFSET; - result.append('{'); - break; - - case TokenStream.RC: - /* don't print the closing RC if it closes the - * toplevel function and we're called from - * decompileFunctionBody. - */ - if (justbody && toplevel && i + 1 == source.length()) - break; - - if (nextIs(i, TokenStream.EOL)) - indent -= OFFSET; - if (nextIs(i, TokenStream.WHILE) - || nextIs(i, TokenStream.ELSE)) { - indent -= OFFSET; - result.append("} "); - } - else - result.append('}'); - break; - - case TokenStream.LP: - result.append('('); - break; - - case TokenStream.RP: - if (nextIs(i, TokenStream.LC)) - result.append(") "); - else - result.append(')'); - break; - - case TokenStream.LB: - result.append('['); - break; - - case TokenStream.RB: - result.append(']'); - break; - - case TokenStream.EOL: - result.append('\n'); - - /* add indent if any tokens remain, - * less setback if next token is - * a label, case or default. - */ - if (i + 1 < source.length()) { - int less = 0; - if (nextIs(i, TokenStream.CASE) - || nextIs(i, TokenStream.DEFAULT)) - less = SETBACK; - else if (nextIs(i, TokenStream.RC)) - less = OFFSET; - - /* elaborate check against label... skip past a - * following inlined NAME and look for a COLON. - * Depends on how NAME is encoded. - */ - else if (nextIs(i, TokenStream.NAME)) { - int skip = source.charAt(i + 2); - if (source.charAt(i + skip + 3) == TokenStream.COLON) - less = OFFSET; - } - - for (; less < indent; less++) - result.append(' '); - } - break; - - case TokenStream.DOT: - result.append('.'); - break; - - case TokenStream.NEW: - result.append("new "); - break; - - case TokenStream.DELPROP: - result.append("delete "); - break; - - case TokenStream.IF: - result.append("if "); - break; - - case TokenStream.ELSE: - result.append("else "); - break; - - case TokenStream.FOR: - result.append("for "); - break; - - case TokenStream.IN: - result.append(" in "); - break; - - case TokenStream.WITH: - result.append("with "); - break; - - case TokenStream.WHILE: - result.append("while "); - break; - - case TokenStream.DO: - result.append("do "); - break; - - case TokenStream.TRY: - result.append("try "); - break; - - case TokenStream.CATCH: - result.append("catch "); - break; - - case TokenStream.FINALLY: - result.append("finally "); - break; - - case TokenStream.THROW: - result.append("throw "); - break; - - case TokenStream.SWITCH: - result.append("switch "); - break; - - case TokenStream.BREAK: - if (nextIs(i, TokenStream.NAME)) - result.append("break "); - else - result.append("break"); - break; - - case TokenStream.CONTINUE: - if (nextIs(i, TokenStream.NAME)) - result.append("continue "); - else - result.append("continue"); - break; - - case TokenStream.CASE: - result.append("case "); - break; - - case TokenStream.DEFAULT: - result.append("default"); - break; - - case TokenStream.RETURN: - if (nextIs(i, TokenStream.SEMI)) - result.append("return"); - else - result.append("return "); - break; - - case TokenStream.VAR: - result.append("var "); - break; - - case TokenStream.SEMI: - if (nextIs(i, TokenStream.EOL)) - // statement termination - result.append(';'); - else - // separators in FOR - result.append("; "); - break; - - case TokenStream.ASSIGN: - i++; - switch(source.charAt(i)) { - case TokenStream.NOP: - result.append(" = "); - break; - - case TokenStream.ADD: - result.append(" += "); - break; - - case TokenStream.SUB: - result.append(" -= "); - break; - - case TokenStream.MUL: - result.append(" *= "); - break; - - case TokenStream.DIV: - result.append(" /= "); - break; - - case TokenStream.MOD: - result.append(" %= "); - break; - - case TokenStream.BITOR: - result.append(" |= "); - break; - - case TokenStream.BITXOR: - result.append(" ^= "); - break; - - case TokenStream.BITAND: - result.append(" &= "); - break; - - case TokenStream.LSH: - result.append(" <<= "); - break; - - case TokenStream.RSH: - result.append(" >>= "); - break; - - case TokenStream.URSH: - result.append(" >>>= "); - break; - } - break; - - case TokenStream.HOOK: - result.append(" ? "); - break; - - case TokenStream.OBJLIT: - // pun OBJLIT to mean colon in objlit property initialization. - // this needs to be distinct from COLON in the general case - // to distinguish from the colon in a ternary... which needs - // different spacing. - result.append(':'); - break; - - case TokenStream.COLON: - if (nextIs(i, TokenStream.EOL)) - // it's the end of a label - result.append(':'); - else - // it's the middle part of a ternary - result.append(" : "); - break; - - case TokenStream.OR: - result.append(" || "); - break; - - case TokenStream.AND: - result.append(" && "); - break; - - case TokenStream.BITOR: - result.append(" | "); - break; - - case TokenStream.BITXOR: - result.append(" ^ "); - break; - - case TokenStream.BITAND: - result.append(" & "); - break; - - case TokenStream.EQOP: - i++; - switch(source.charAt(i)) { - case TokenStream.SHEQ: - /* - * Emulate the C engine; if we're under version - * 1.2, then the == operator behaves like the === - * operator (and the source is generated by - * decompiling a === opcode), so print the === - * operator as ==. - */ - result.append(this.version == Context.VERSION_1_2 ? " == " - : " === "); - break; - - case TokenStream.SHNE: - result.append(this.version == Context.VERSION_1_2 ? " != " - : " !== "); - break; - - case TokenStream.EQ: - result.append(" == "); - break; - - case TokenStream.NE: - result.append(" != "); - break; - } - break; - - case TokenStream.RELOP: - i++; - switch(source.charAt(i)) { - case TokenStream.LE: - result.append(" <= "); - break; - - case TokenStream.LT: - result.append(" < "); - break; - - case TokenStream.GE: - result.append(" >= "); - break; - - case TokenStream.GT: - result.append(" > "); - break; - - case TokenStream.INSTANCEOF: - result.append(" instanceof "); - break; - } - break; - - case TokenStream.SHOP: - i++; - switch(source.charAt(i)) { - case TokenStream.LSH: - result.append(" << "); - break; - - case TokenStream.RSH: - result.append(" >> "); - break; - - case TokenStream.URSH: - result.append(" >>> "); - break; - } - break; - - case TokenStream.UNARYOP: - i++; - switch(source.charAt(i)) { - case TokenStream.TYPEOF: - result.append("typeof "); - break; - - case TokenStream.VOID: - result.append("void "); - break; - - case TokenStream.NOT: - result.append('!'); - break; - - case TokenStream.BITNOT: - result.append('~'); - break; - - case TokenStream.ADD: - result.append('+'); - break; - - case TokenStream.SUB: - result.append('-'); - break; - } - break; - - case TokenStream.INC: - result.append("++"); - break; - - case TokenStream.DEC: - result.append("--"); - break; - - case TokenStream.ADD: - result.append(" + "); - break; - - case TokenStream.SUB: - result.append(" - "); - break; - - case TokenStream.MUL: - result.append(" * "); - break; - - case TokenStream.DIV: - result.append(" / "); - break; - - case TokenStream.MOD: - result.append(" % "); - break; - - default: - // If we don't know how to decompile it, raise an exception. - throw new RuntimeException("Unknown token " + - source.charAt(i)); - } - i++; - } - - // add that trailing newline if it's an outermost function. - if (toplevel && !justbody) - result.append('\n'); - } - - public int getLength() { - Context cx = Context.getContext(); - if (cx != null && cx.getLanguageVersion() != Context.VERSION_1_2) - return argCount; - NativeCall activation = getActivation(cx); - if (activation == null) - return argCount; - return activation.getOriginalArguments().length; - } - - public int getArity() { - return argCount; - } - - public String getFunctionName() { - if (functionName == null) - return ""; - if (functionName.equals("anonymous")) { - Context cx = Context.getCurrentContext(); - if (cx != null && cx.getLanguageVersion() == Context.VERSION_1_2) - return ""; - } - return functionName; - } - - /** - * For backwards compatibility keep an old method name used by - * Batik and possibly others. - */ - public String jsGet_name() { - return getFunctionName(); - } - - /** - * The "argsNames" array has the following information: - * argNames[0] through argNames[argCount - 1]: the names of the parameters - * argNames[argCount] through argNames[args.length-1]: the names of the - * variables declared in var statements - */ - protected String[] argNames; - protected short argCount; - protected short version; - - /** - * An encoded representation of the function source, for - * decompiling. Needs to be visible (only) to generated - * subclasses of NativeFunction. - */ - protected String source; - - /** - * An array of NativeFunction values for each nested function. - * Used internally, and also for decompiling nested functions. - */ - public NativeFunction[] nestedFunctions; - - // For all generated subclass objects debug_level is set to 0 or higher. - // So, if debug_level remains -1 in some object, then that object is - // known to have not been generated. - public int debug_level = -1; - public String debug_srcName; -} - diff --git a/src/org/mozilla/javascript/NativeGlobal.java b/src/org/mozilla/javascript/NativeGlobal.java deleted file mode 100644 index 6f7df59..0000000 --- a/src/org/mozilla/javascript/NativeGlobal.java +++ /dev/null @@ -1,843 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * Igor Bukanov - * Mike McCabe - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -import java.io.StringReader; -import java.io.IOException; -import java.lang.reflect.Method; - -/** - * This class implements the global native object (function and value - * properties only). - * - * See ECMA 15.1.[12]. - * - * @author Mike Shaver - */ - -public class NativeGlobal implements IdFunctionMaster { - - public static void init(Context cx, Scriptable scope, boolean sealed) { - NativeGlobal obj = new NativeGlobal(); - obj.scopeSlaveFlag = true; - - for (int id = 1; id <= LAST_SCOPE_FUNCTION_ID; ++id) { - String name = getMethodName(id); - IdFunction f = new IdFunction(obj, name, id); - f.setParentScope(scope); - if (sealed) { f.sealObject(); } - ScriptableObject.defineProperty(scope, name, f, - ScriptableObject.DONTENUM); - } - - ScriptableObject.defineProperty(scope, "NaN", - ScriptRuntime.NaNobj, - ScriptableObject.DONTENUM); - ScriptableObject.defineProperty(scope, "Infinity", - new Double(Double.POSITIVE_INFINITY), - ScriptableObject.DONTENUM); - /* - ScriptableObject.defineProperty(scope, "undefined", - Undefined.instance, - ScriptableObject.DONTENUM); - */ - - String[] errorMethods = { "ConversionError", - "EvalError", - "RangeError", - "ReferenceError", - "SyntaxError", - "TypeError", - "URIError" - }; - - /* - Each error constructor gets its own Error object as a prototype, - with the 'name' property set to the name of the error. - */ - for (int i = 0; i < errorMethods.length; i++) { - String name = errorMethods[i]; - IdFunction ctor = new IdFunction(obj, name, Id_new_CommonError); - ctor.setFunctionType(IdFunction.FUNCTION_AND_CONSTRUCTOR); - ctor.setParentScope(scope); - ScriptableObject.defineProperty(scope, name, ctor, - ScriptableObject.DONTENUM); - - Scriptable errorProto = ScriptRuntime.newObject - (cx, scope, "Error", ScriptRuntime.emptyArgs); - - errorProto.put("name", errorProto, name); - ctor.put("prototype", ctor, errorProto); - if (sealed) { - ctor.sealObject(); - if (errorProto instanceof ScriptableObject) { - ((ScriptableObject)errorProto).sealObject(); - } - } - } - } - - public Object execMethod(int methodId, IdFunction function, Context cx, - Scriptable scope, Scriptable thisObj, - Object[] args) - throws JavaScriptException - { - if (scopeSlaveFlag) { - switch (methodId) { - case Id_decodeURI: - return js_decodeURI(cx, args); - - case Id_decodeURIComponent: - return js_decodeURIComponent(cx, args); - - case Id_encodeURI: - return js_encodeURI(cx, args); - - case Id_encodeURIComponent: - return js_encodeURIComponent(cx, args); - - case Id_escape: - return js_escape(cx, args); - - case Id_eval: - return js_eval(cx, scope, args); - - case Id_isFinite: - return js_isFinite(cx, args); - - case Id_isNaN: - return js_isNaN(cx, args); - - case Id_parseFloat: - return js_parseFloat(cx, args); - - case Id_parseInt: - return js_parseInt(cx, args); - - case Id_unescape: - return js_unescape(cx, args); - - case Id_new_CommonError: - return new_CommonError(function, cx, scope, args); - } - } - throw IdFunction.onBadMethodId(this, methodId); - } - - public int methodArity(int methodId) { - if (scopeSlaveFlag) { - switch (methodId) { - case Id_decodeURI: return 1; - case Id_decodeURIComponent: return 1; - case Id_encodeURI: return 1; - case Id_encodeURIComponent: return 1; - case Id_escape: return 1; - case Id_eval: return 1; - case Id_isFinite: return 1; - case Id_isNaN: return 1; - case Id_parseFloat: return 1; - case Id_parseInt: return 2; - case Id_unescape: return 1; - - case Id_new_CommonError: return 1; - } - } - return -1; - } - - private static String getMethodName(int methodId) { - switch (methodId) { - case Id_decodeURI: return "decodeURI"; - case Id_decodeURIComponent: return "decodeURIComponent"; - case Id_encodeURI: return "encodeURI"; - case Id_encodeURIComponent: return "encodeURIComponent"; - case Id_escape: return "escape"; - case Id_eval: return "eval"; - case Id_isFinite: return "isFinite"; - case Id_isNaN: return "isNaN"; - case Id_parseFloat: return "parseFloat"; - case Id_parseInt: return "parseInt"; - case Id_unescape: return "unescape"; - } - return null; - } - - /** - * The global method parseInt, as per ECMA-262 15.1.2.2. - */ - private Object js_parseInt(Context cx, Object[] args) { - String s = ScriptRuntime.toString(args, 0); - int radix = ScriptRuntime.toInt32(args, 1); - - int len = s.length(); - if (len == 0) - return ScriptRuntime.NaNobj; - - boolean negative = false; - int start = 0; - char c; - do { - c = s.charAt(start); - if (!Character.isWhitespace(c)) - break; - start++; - } while (start < len); - - if (c == '+' || (negative = (c == '-'))) - start++; - - final int NO_RADIX = -1; - if (radix == 0) { - radix = NO_RADIX; - } else if (radix < 2 || radix > 36) { - return ScriptRuntime.NaNobj; - } else if (radix == 16 && len - start > 1 && s.charAt(start) == '0') { - c = s.charAt(start+1); - if (c == 'x' || c == 'X') - start += 2; - } - - if (radix == NO_RADIX) { - radix = 10; - if (len - start > 1 && s.charAt(start) == '0') { - c = s.charAt(start+1); - if (c == 'x' || c == 'X') { - radix = 16; - start += 2; - } else if (c != '.') { - radix = 8; - start++; - } - } - } - - double d = ScriptRuntime.stringToNumber(s, start, radix); - return new Double(negative ? -d : d); - } - - /** - * The global method parseFloat, as per ECMA-262 15.1.2.3. - * - * @param cx unused - * @param thisObj unused - * @param args the arguments to parseFloat, ignoring args[>=1] - * @param funObj unused - */ - private Object js_parseFloat(Context cx, Object[] args) { - if (args.length < 1) - return ScriptRuntime.NaNobj; - String s = ScriptRuntime.toString(args[0]); - int len = s.length(); - if (len == 0) - return ScriptRuntime.NaNobj; - - int i; - char c; - // Scan forward to the first digit or . - for (i=0; TokenStream.isJSSpace(c = s.charAt(i)) && i+1 < len; i++) - /* empty */ - ; - - int start = i; - - if (c == '+' || c == '-') - c = s.charAt(++i); - - if (c == 'I') { - // check for "Infinity" - double d; - if (i+8 <= len && s.substring(i, i+8).equals("Infinity")) - d = s.charAt(start) == '-' ? Double.NEGATIVE_INFINITY - : Double.POSITIVE_INFINITY; - else - return ScriptRuntime.NaNobj; - return new Double(d); - } - - // Find the end of the legal bit - int decimal = -1; - int exponent = -1; - for (; i < len; i++) { - switch (s.charAt(i)) { - case '.': - if (decimal != -1) // Only allow a single decimal point. - break; - decimal = i; - continue; - - case 'e': - case 'E': - if (exponent != -1) - break; - exponent = i; - continue; - - case '+': - case '-': - // Only allow '+' or '-' after 'e' or 'E' - if (exponent != i-1) - break; - continue; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - continue; - - default: - break; - } - break; - } - s = s.substring(start, i); - try { - return Double.valueOf(s); - } - catch (NumberFormatException ex) { - return ScriptRuntime.NaNobj; - } - } - - /** - * The global method escape, as per ECMA-262 15.1.2.4. - - * Includes code for the 'mask' argument supported by the C escape - * method, which used to be part of the browser imbedding. Blame - * for the strange constant names should be directed there. - */ - - private Object js_escape(Context cx, Object[] args) { - final int - URL_XALPHAS = 1, - URL_XPALPHAS = 2, - URL_PATH = 4; - - String s = ScriptRuntime.toString(args, 0); - - int mask = URL_XALPHAS | URL_XPALPHAS | URL_PATH; - if (args.length > 1) { // the 'mask' argument. Non-ECMA. - double d = ScriptRuntime.toNumber(args[1]); - if (d != d || ((mask = (int) d) != d) || - 0 != (mask & ~(URL_XALPHAS | URL_XPALPHAS | URL_PATH))) - { - String message = Context.getMessage0("msg.bad.esc.mask"); - cx.reportError(message); - // do the ecma thing, in case reportError returns. - mask = URL_XALPHAS | URL_XPALPHAS | URL_PATH; - } - } - - StringBuffer R = new StringBuffer(); - for (int k = 0; k < s.length(); k++) { - int c = s.charAt(k), d; - if (mask != 0 && ((c >= '0' && c <= '9') || - (c >= 'A' && c <= 'Z') || - (c >= 'a' && c <= 'z') || - c == '@' || c == '*' || c == '_' || - c == '-' || c == '.' || - ((c == '/' || c == '+') && mask > 3))) - R.append((char)c); - else if (c < 256) { - if (c == ' ' && mask == URL_XPALPHAS) { - R.append('+'); - } else { - R.append('%'); - R.append(hex_digit_to_char(c >>> 4)); - R.append(hex_digit_to_char(c & 0xF)); - } - } else { - R.append('%'); - R.append('u'); - R.append(hex_digit_to_char(c >>> 12)); - R.append(hex_digit_to_char((c & 0xF00) >>> 8)); - R.append(hex_digit_to_char((c & 0xF0) >>> 4)); - R.append(hex_digit_to_char(c & 0xF)); - } - } - return R.toString(); - } - - private static char hex_digit_to_char(int x) { - return (char)(x <= 9 ? x + '0' : x + ('A' - 10)); - } - - /** - * The global unescape method, as per ECMA-262 15.1.2.5. - */ - - private Object js_unescape(Context cx, Object[] args) - { - String s = ScriptRuntime.toString(args, 0); - int firstEscapePos = s.indexOf('%'); - if (firstEscapePos >= 0) { - int L = s.length(); - char[] buf = s.toCharArray(); - int destination = firstEscapePos; - for (int k = firstEscapePos; k != L;) { - char c = buf[k]; - ++k; - if (c == '%' && k != L) { - int end, start; - if (buf[k] == 'u') { - start = k + 1; - end = k + 5; - } else { - start = k; - end = k + 2; - } - if (end <= L) { - int x = 0; - for (int i = start; i != end; ++i) { - x = (x << 4) | TokenStream.xDigitToInt(buf[i]); - } - if (x >= 0) { - c = (char)x; - k = end; - } - } - } - buf[destination] = c; - ++destination; - } - s = new String(buf, 0, destination); - } - return s; - } - - /** - * The global method isNaN, as per ECMA-262 15.1.2.6. - */ - - private Object js_isNaN(Context cx, Object[] args) { - if (args.length < 1) - return Boolean.TRUE; - double d = ScriptRuntime.toNumber(args[0]); - return (d != d) ? Boolean.TRUE : Boolean.FALSE; - } - - private Object js_isFinite(Context cx, Object[] args) { - if (args.length < 1) - return Boolean.FALSE; - double d = ScriptRuntime.toNumber(args[0]); - return (d != d || d == Double.POSITIVE_INFINITY || - d == Double.NEGATIVE_INFINITY) - ? Boolean.FALSE - : Boolean.TRUE; - } - - private Object js_eval(Context cx, Scriptable scope, Object[] args) - throws JavaScriptException - { - String m = ScriptRuntime.getMessage1("msg.cant.call.indirect", "eval"); - throw NativeGlobal.constructError(cx, "EvalError", m, scope); - } - - /** - * The eval function property of the global object. - * - * See ECMA 15.1.2.1 - */ - public static Object evalSpecial(Context cx, Scriptable scope, - Object thisArg, Object[] args, - String filename, int lineNumber) - throws JavaScriptException - { - throw NativeGlobal.constructError(cx, "EvalError", "XWT does not allow eval()", scope); - /* - if (args.length < 1) - return Undefined.instance; - Object x = args[0]; - if (!(x instanceof String)) { - String message = Context.getMessage0("msg.eval.nonstring"); - Context.reportWarning(message); - return x; - } - int[] linep = { lineNumber }; - if (filename == null) { - filename = Context.getSourcePositionFromStack(linep); - if (filename == null) { - filename = ""; - linep[0] = 1; - } - } - filename += "(eval)"; - - try { - StringReader in = new StringReader((String) x); - Object securityDomain = cx.getSecurityDomainForStackDepth(3); - - // Compile the reader with opt level of -1 to force interpreter - // mode. - int oldOptLevel = cx.getOptimizationLevel(); - cx.setOptimizationLevel(-1); - Script script = cx.compileReader(scope, in, filename, linep[0], - securityDomain); - cx.setOptimizationLevel(oldOptLevel); - - // if the compile fails, an error has been reported by the - // compiler, but we need to stop execution to avoid - // infinite looping on while(true) { eval('foo bar') } - - // so we throw an EvaluatorException. - if (script == null) { - String message = Context.getMessage0("msg.syntax"); - throw new EvaluatorException(message); - } - - InterpretedScript is = (InterpretedScript) script; - is.itsData.itsFromEvalCode = true; - Object result = is.call(cx, scope, (Scriptable) thisArg, null); - - return result; - } - catch (IOException ioe) { - // should never happen since we just made the Reader from a String - throw new RuntimeException("unexpected io exception"); - } - */ - } - - - /** - * The NativeError functions - * - * See ECMA 15.11.6 - */ - public static EcmaError constructError(Context cx, - String error, - String message, - Object scope) - { - int[] linep = { 0 }; - String filename = cx.getSourcePositionFromStack(linep); - return constructError(cx, error, message, scope, - filename, linep[0], 0, null); - } - - static EcmaError typeError0(String messageId, Object scope) { - return constructError(Context.getContext(), "TypeError", - ScriptRuntime.getMessage0(messageId), scope); - } - - static EcmaError typeError1(String messageId, Object arg1, Object scope) { - return constructError(Context.getContext(), "TypeError", - ScriptRuntime.getMessage1(messageId, arg1), scope); - } - - /** - * The NativeError functions - * - * See ECMA 15.11.6 - */ - public static EcmaError constructError(Context cx, - String error, - String message, - Object scope, - String sourceName, - int lineNumber, - int columnNumber, - String lineSource) - { - Scriptable scopeObject; - try { - scopeObject = (Scriptable) scope; - } - catch (ClassCastException x) { - throw new RuntimeException(x.toString()); - } - - Object args[] = { message }; - try { - Object errorObject = cx.newObject(scopeObject, error, args); - return new EcmaError((NativeError)errorObject, sourceName, - lineNumber, columnNumber, lineSource); - } - catch (PropertyException x) { - throw new RuntimeException(x.toString()); - } - catch (JavaScriptException x) { - throw new RuntimeException(x.toString()); - } - catch (NotAFunctionException x) { - throw new RuntimeException(x.toString()); - } - } - - /** - * The implementation of all the ECMA error constructors (SyntaxError, - * TypeError, etc.) - */ - private Object new_CommonError(IdFunction ctorObj, Context cx, - Scriptable scope, Object[] args) - { - Scriptable newInstance = new NativeError(); - newInstance.setPrototype((Scriptable)(ctorObj.get("prototype", ctorObj))); - newInstance.setParentScope(scope); - if (args.length > 0) - newInstance.put("message", newInstance, args[0]); - return newInstance; - } - - /* - * ECMA 3, 15.1.3 URI Handling Function Properties - * - * The following are implementations of the algorithms - * given in the ECMA specification for the hidden functions - * 'Encode' and 'Decode'. - */ - private static String encode(Context cx, String str, String unescapedSet) { - int j, k = 0, L; - char C, C2; - int V; - char utf8buf[] = new char[6]; - StringBuffer R; - - R = new StringBuffer(); - - while (k < str.length()) { - C = str.charAt(k); - if (unescapedSet.indexOf(C) != -1) { - R.append(C); - } else { - if ((C >= 0xDC00) && (C <= 0xDFFF)) { - throw cx.reportRuntimeError0("msg.bad.uri"); - } - if ((C < 0xD800) || (C > 0xDBFF)) - V = C; - else { - k++; - if (k == str.length()) { - throw cx.reportRuntimeError0("msg.bad.uri"); - } - C2 = str.charAt(k); - if ((C2 < 0xDC00) || (C2 > 0xDFFF)) { - throw cx.reportRuntimeError0("msg.bad.uri"); - } - V = ((C - 0xD800) << 10) + (C2 - 0xDC00) + 0x10000; - } - L = oneUcs4ToUtf8Char(utf8buf, V); - for (j = 0; j < L; j++) { - R.append('%'); - if (utf8buf[j] < 16) - R.append('0'); - R.append(Integer.toHexString(utf8buf[j])); - } - } - k++; - } - return R.toString(); - } - - private static boolean isHex(char c) { - return ((c >= '0' && c <= '9') - || (c >= 'a' && c <= 'f') - || (c >= 'A' && c <= 'F')); - } - - private static int unHex(char c) { - if (c >= '0' && c <= '9') - return c - '0'; - else - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - else - return c - 'A' +10; - } - - private static String decode(Context cx, String str, String reservedSet) { - int start, k = 0; - char C, H; - int V; - int B; - char[] octets = new char[6]; - StringBuffer R; - int j, n; - - R = new StringBuffer(); - - while (k < str.length()) { - C = str.charAt(k); - if (C == '%') { - start = k; - if ((k + 2) >= str.length()) - throw cx.reportRuntimeError0("msg.bad.uri"); - if (!isHex(str.charAt(k + 1)) || !isHex(str.charAt(k + 2))) - throw cx.reportRuntimeError0("msg.bad.uri"); - B = unHex(str.charAt(k + 1)) * 16 + unHex(str.charAt(k + 2)); - k += 2; - if ((B & 0x80) == 0) - C = (char)B; - else { - n = 1; - while ((B & (0x80 >>> n)) != 0) n++; - if ((n == 1) || (n > 6)) - throw cx.reportRuntimeError0("msg.bad.uri"); - octets[0] = (char)B; - if ((k + 3 * (n - 1)) >= str.length()) - throw cx.reportRuntimeError0("msg.bad.uri"); - for (j = 1; j < n; j++) { - k++; - if (str.charAt(k) != '%') - throw cx.reportRuntimeError0("msg.bad.uri"); - if (!isHex(str.charAt(k + 1)) - || !isHex(str.charAt(k + 2))) - throw cx.reportRuntimeError0("msg.bad.uri"); - B = unHex(str.charAt(k + 1)) * 16 - + unHex(str.charAt(k + 2)); - if ((B & 0xC0) != 0x80) - throw cx.reportRuntimeError0("msg.bad.uri"); - k += 2; - octets[j] = (char)B; - } - V = utf8ToOneUcs4Char(octets, n); - if (V >= 0x10000) { - V -= 0x10000; - if (V > 0xFFFFF) - throw cx.reportRuntimeError0("msg.bad.uri"); - C = (char)((V & 0x3FF) + 0xDC00); - H = (char)((V >>> 10) + 0xD800); - R.append(H); - } - else - C = (char)V; - } - if (reservedSet.indexOf(C) != -1) { - for (int x = 0; x < (k - start + 1); x++) - R.append(str.charAt(start + x)); - } - else - R.append(C); - } - else - R.append(C); - k++; - } - return R.toString(); - } - - private static String uriReservedPlusPound = ";/?:@&=+$,#"; - private static String uriUnescaped = - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_.!~*'()"; - - private String js_decodeURI(Context cx, Object[] args) { - String str = ScriptRuntime.toString(args, 0); - return decode(cx, str, uriReservedPlusPound); - } - - private String js_decodeURIComponent(Context cx, Object[] args) { - String str = ScriptRuntime.toString(args, 0); - return decode(cx, str, ""); - } - - private Object js_encodeURI(Context cx, Object[] args) { - String str = ScriptRuntime.toString(args, 0); - return encode(cx, str, uriReservedPlusPound + uriUnescaped); - } - - private String js_encodeURIComponent(Context cx, Object[] args) { - String str = ScriptRuntime.toString(args, 0); - return encode(cx, str, uriUnescaped); - } - - /* Convert one UCS-4 char and write it into a UTF-8 buffer, which must be - * at least 6 bytes long. Return the number of UTF-8 bytes of data written. - */ - private static int oneUcs4ToUtf8Char(char[] utf8Buffer, int ucs4Char) { - int utf8Length = 1; - - //JS_ASSERT(ucs4Char <= 0x7FFFFFFF); - if ((ucs4Char & ~0x7F) == 0) - utf8Buffer[0] = (char)ucs4Char; - else { - int i; - int a = ucs4Char >>> 11; - utf8Length = 2; - while (a != 0) { - a >>>= 5; - utf8Length++; - } - i = utf8Length; - while (--i > 0) { - utf8Buffer[i] = (char)((ucs4Char & 0x3F) | 0x80); - ucs4Char >>>= 6; - } - utf8Buffer[0] = (char)(0x100 - (1 << (8-utf8Length)) + ucs4Char); - } - return utf8Length; - } - - - /* Convert a utf8 character sequence into a UCS-4 character and return that - * character. It is assumed that the caller already checked that the sequence is valid. - */ - private static int utf8ToOneUcs4Char(char[] utf8Buffer, int utf8Length) { - int ucs4Char; - int k = 0; - //JS_ASSERT(utf8Length >= 1 && utf8Length <= 6); - if (utf8Length == 1) { - ucs4Char = utf8Buffer[0]; - // JS_ASSERT(!(ucs4Char & 0x80)); - } else { - //JS_ASSERT((*utf8Buffer & (0x100 - (1 << (7-utf8Length)))) == (0x100 - (1 << (8-utf8Length)))); - ucs4Char = utf8Buffer[k++] & ((1<<(7-utf8Length))-1); - while (--utf8Length > 0) { - //JS_ASSERT((*utf8Buffer & 0xC0) == 0x80); - ucs4Char = ucs4Char<<6 | (utf8Buffer[k++] & 0x3F); - } - } - return ucs4Char; - } - - private static final int - Id_decodeURI = 1, - Id_decodeURIComponent = 2, - Id_encodeURI = 3, - Id_encodeURIComponent = 4, - Id_escape = 5, - Id_eval = 6, - Id_isFinite = 7, - Id_isNaN = 8, - Id_parseFloat = 9, - Id_parseInt = 10, - Id_unescape = 11, - - LAST_SCOPE_FUNCTION_ID = 11, - - Id_new_CommonError = 12; - - private boolean scopeSlaveFlag; - -} diff --git a/src/org/mozilla/javascript/NativeJavaArray.java b/src/org/mozilla/javascript/NativeJavaArray.java deleted file mode 100644 index 42e2d2e..0000000 --- a/src/org/mozilla/javascript/NativeJavaArray.java +++ /dev/null @@ -1,155 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * Frank Mitchell - * Mike Shaver - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -import java.lang.reflect.Array; - -/** - * This class reflects Java arrays into the JavaScript environment. - * - * @author Mike Shaver - * @see NativeJavaClass - * @see NativeJavaObject - * @see NativeJavaPackage - */ - -public class NativeJavaArray extends NativeJavaObject { - - public String getClassName() { - return "JavaArray"; - } - - public static NativeJavaArray wrap(Scriptable scope, Object array) { - return new NativeJavaArray(scope, array); - } - - public Object unwrap() { - return array; - } - - public NativeJavaArray(Scriptable scope, Object array) { - super(scope, null, ScriptRuntime.ObjectClass); - Class cl = array.getClass(); - if (!cl.isArray()) { - throw new RuntimeException("Array expected"); - } - this.array = array; - this.length = Array.getLength(array); - this.cls = cl.getComponentType(); - } - - public boolean has(String id, Scriptable start) { - return id.equals("length") || super.has(id, start); - } - - public boolean has(int index, Scriptable start) { - return 0 <= index && index < length; - } - - public Object get(String id, Scriptable start) { - if (id.equals("length")) - return new Integer(length); - Object result = super.get(id, start); - if (result == NOT_FOUND && - !ScriptRuntime.hasProp(getPrototype(), id)) - { - throw Context.reportRuntimeError2( - "msg.java.member.not.found", array.getClass().getName(), id); - } - return result; - } - - public Object get(int index, Scriptable start) { - if (0 <= index && index < length) - return NativeJavaObject.wrap(this, Array.get(array, index), cls); - return Undefined.instance; - } - - public void put(String id, Scriptable start, Object value) { - // Ignore assignments to "length"--it's readonly. - if (!id.equals("length")) - super.put(id, start, value); - } - - public void put(int index, Scriptable start, Object value) { - if (0 <= index && index < length) { - Array.set(array, index, NativeJavaObject.coerceType(cls, value)); - return; - } - super.put(index, start, value); - } - - public Object getDefaultValue(Class hint) { - if (hint == null || hint == ScriptRuntime.StringClass) - return array.toString(); - if (hint == ScriptRuntime.BooleanClass) - return Boolean.TRUE; - if (hint == ScriptRuntime.NumberClass) - return ScriptRuntime.NaNobj; - return this; - } - - public Object[] getIds() { - Object[] result = new Object[length]; - int i = length; - while (--i >= 0) - result[i] = new Integer(i); - return result; - } - - public boolean hasInstance(Scriptable value) { - if (!(value instanceof Wrapper)) - return false; - Object instance = ((Wrapper)value).unwrap(); - return cls.isInstance(instance); - } - - public Scriptable getPrototype() { - if (prototype == null) { - prototype = - ScriptableObject.getClassPrototype(this.getParentScope(), - "Array"); - } - return prototype; - } - - Object array; - int length; - Class cls; - Scriptable prototype; -} diff --git a/src/org/mozilla/javascript/NativeJavaClass.java b/src/org/mozilla/javascript/NativeJavaClass.java deleted file mode 100644 index 8b46c94..0000000 --- a/src/org/mozilla/javascript/NativeJavaClass.java +++ /dev/null @@ -1,275 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * Frank Mitchell - * Mike Shaver - * Kurt Westerfeld - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -import java.lang.reflect.*; -import java.util.Hashtable; - -/** - * This class reflects Java classes into the JavaScript environment, mainly - * for constructors and static members. We lazily reflect properties, - * and currently do not guarantee that a single j.l.Class is only - * reflected once into the JS environment, although we should. - * The only known case where multiple reflections - * are possible occurs when a j.l.Class is wrapped as part of a - * method return or property access, rather than by walking the - * Packages/java tree. - * - * @author Mike Shaver - * @see NativeJavaArray - * @see NativeJavaObject - * @see NativeJavaPackage - */ - -public class NativeJavaClass extends NativeJavaObject implements Function { - - public NativeJavaClass(Scriptable scope, Class cl) { - super(scope, cl, JavaMembers.lookupClass(scope, cl, cl)); - fieldAndMethods = members.getFieldAndMethodsObjects(this, javaObject, - true); - } - - public String getClassName() { - return "JavaClass"; - } - - public boolean has(String name, Scriptable start) { - return members.has(name, true); - } - - public Object get(String name, Scriptable start) { - // When used as a constructor, ScriptRuntime.newObject() asks - // for our prototype to create an object of the correct type. - // We don't really care what the object is, since we're returning - // one constructed out of whole cloth, so we return null. - - if (name.equals("prototype")) - return null; - - Object result = Scriptable.NOT_FOUND; - - if (fieldAndMethods != null) { - result = fieldAndMethods.get(name); - if (result != null) - return result; - } - - if (members.has(name, true)) { - result = members.get(this, name, javaObject, true); - } else { - // experimental: look for nested classes by appending $name to current class' name. - try { - String nestedName = getClassObject().getName() + '$' + name; - Class nestedClass = ScriptRuntime.loadClassName(nestedName); - Scriptable nestedValue = wrap(ScriptableObject.getTopLevelScope(this), nestedClass); - nestedValue.setParentScope(this); - result = nestedValue; - } catch (ClassNotFoundException ex) { - throw members.reportMemberNotFound(name); - } catch (IllegalArgumentException e) { - throw members.reportMemberNotFound(name); - } - } - - return result; - } - - public void put(String name, Scriptable start, Object value) { - members.put(this, name, javaObject, value, true); - } - - public Object[] getIds() { - return members.getIds(true); - } - - public Class getClassObject() { - return (Class) super.unwrap(); - } - - // XXX ?? - public static NativeJavaClass wrap(Scriptable scope, Class cls) { - return new NativeJavaClass(scope, cls); - } - - public Object getDefaultValue(Class hint) { - if (hint == null || hint == ScriptRuntime.StringClass) - return this.toString(); - if (hint == ScriptRuntime.BooleanClass) - return Boolean.TRUE; - if (hint == ScriptRuntime.NumberClass) - return ScriptRuntime.NaNobj; - return this; - } - - public Object call(Context cx, Scriptable scope, Scriptable thisObj, - Object[] args) - throws JavaScriptException - { - // If it looks like a "cast" of an object to this class type, - // walk the prototype chain to see if there's a wrapper of a - // object that's an instanceof this class. - if (args.length == 1 && args[0] instanceof Scriptable) { - Class c = getClassObject(); - Scriptable p = (Scriptable) args[0]; - do { - if (p instanceof Wrapper) { - Object o = ((Wrapper) p).unwrap(); - if (c.isInstance(o)) - return p; - } - p = p.getPrototype(); - } while (p != null); - } - return construct(cx, scope, args); - } - - public Scriptable construct(Context cx, Scriptable scope, Object[] args) - throws JavaScriptException - { - Class classObject = getClassObject(); - int modifiers = classObject.getModifiers(); - if (! (Modifier.isInterface(modifiers) || - Modifier.isAbstract(modifiers))) - { - Constructor[] ctors = members.getConstructors(); - Member member = NativeJavaMethod.findFunction(ctors, args); - Constructor ctor = (Constructor) member; - if (ctor == null) { - String sig = NativeJavaMethod.scriptSignature(args); - throw Context.reportRuntimeError2( - "msg.no.java.ctor", classObject.getName(), sig); - } - - // Found the constructor, so try invoking it. - return NativeJavaClass.constructSpecific(cx, scope, - this, ctor, args); - } else { - Scriptable topLevel = ScriptableObject.getTopLevelScope(this); - String msg = ""; - try { - // trying to construct an interface; use JavaAdapter to - // construct a new class on the fly that implements this - // interface. - Object v = topLevel.get("JavaAdapter", topLevel); - if (v != NOT_FOUND) { - Function f = (Function) v; - Object[] adapterArgs = { this, args[0] }; - return (Scriptable) f.construct(cx, topLevel, - adapterArgs); - } - } catch (Exception ex) { - // fall through to error - String m = ex.getMessage(); - if (m != null) - msg = m; - } - throw Context.reportRuntimeError2( - "msg.cant.instantiate", msg, classObject.getName()); - } - } - - public static Scriptable constructSpecific(Context cx, - Scriptable scope, - Scriptable thisObj, - Constructor ctor, - Object[] args) - throws JavaScriptException - { - Scriptable topLevel = ScriptableObject.getTopLevelScope(thisObj); - Class classObject = ctor.getDeclaringClass(); - - Class[] paramTypes = ctor.getParameterTypes(); - for (int i = 0; i < args.length; i++) { - args[i] = NativeJavaObject.coerceType(paramTypes[i], args[i]); - } - try { - // we need to force this to be wrapped, because construct _has_ - // to return a scriptable - return - (Scriptable) NativeJavaObject.wrap(topLevel, - ctor.newInstance(args), - classObject); - - } catch (InstantiationException instEx) { - throw Context.reportRuntimeError2( - "msg.cant.instantiate", - instEx.getMessage(), classObject.getName()); - } catch (IllegalArgumentException argEx) { - String signature = NativeJavaMethod.scriptSignature(args); - String ctorString = ctor.toString(); - throw Context.reportRuntimeError3( - "msg.bad.ctor.sig", argEx.getMessage(), ctorString, signature); - } catch (InvocationTargetException e) { - throw JavaScriptException.wrapException(scope, e); - } catch (IllegalAccessException accessEx) { - throw Context.reportRuntimeError1( - "msg.java.internal.private", accessEx.getMessage()); - } - } - - public String toString() { - return "[JavaClass " + getClassObject().getName() + "]"; - } - - /** - * Determines if prototype is a wrapped Java object and performs - * a Java "instanceof". - * Exception: if value is an instance of NativeJavaClass, it isn't - * considered an instance of the Java class; this forestalls any - * name conflicts between java.lang.Class's methods and the - * static methods exposed by a JavaNativeClass. - */ - public boolean hasInstance(Scriptable value) { - - if (value instanceof Wrapper && - !(value instanceof NativeJavaClass)) { - Object instance = ((Wrapper)value).unwrap(); - - return getClassObject().isInstance(instance); - } - - // value wasn't something we understand - return false; - } - - private Hashtable fieldAndMethods; - - // beard: need a scope for finding top-level prototypes. - private Scriptable parent; -} diff --git a/src/org/mozilla/javascript/NativeJavaConstructor.java b/src/org/mozilla/javascript/NativeJavaConstructor.java deleted file mode 100644 index 4f2fbfc..0000000 --- a/src/org/mozilla/javascript/NativeJavaConstructor.java +++ /dev/null @@ -1,86 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * Frank Mitchell - * Mike Shaver - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -import java.lang.reflect.*; - -/** - * This class reflects a single Java constructor into the JavaScript - * environment. It satisfies a request for an overloaded constructor, - * as introduced in LiveConnect 3. - * All NativeJavaConstructors behave as JSRef `bound' methods, in that they - * always construct the same NativeJavaClass regardless of any reparenting - * that may occur. - * - * @author Frank Mitchell - * @see NativeJavaMethod - * @see NativeJavaPackage - * @see NativeJavaClass - */ - -public class NativeJavaConstructor extends NativeFunction implements Function { - - public NativeJavaConstructor(Constructor ctor) { - this.constructor = ctor; - this.functionName = "" + NativeJavaMethod.signature(ctor); - } - - public Object call(Context cx, Scriptable scope, Scriptable thisObj, - Object[] args) - throws JavaScriptException - { - // Find a method that matches the types given. - if (constructor == null) { - throw new RuntimeException("No constructor defined for call"); - } - - return NativeJavaClass.constructSpecific(cx, scope, - this, constructor, args); - } - - public String toString() { - return "[JavaConstructor " + constructor.getName() + "]"; - } - - Constructor getConstructor() { - return constructor; - } - - Constructor constructor; -} - diff --git a/src/org/mozilla/javascript/NativeJavaMethod.java b/src/org/mozilla/javascript/NativeJavaMethod.java deleted file mode 100644 index 8d3e88d..0000000 --- a/src/org/mozilla/javascript/NativeJavaMethod.java +++ /dev/null @@ -1,517 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * Frank Mitchell - * Mike Shaver - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -import java.lang.reflect.*; - -/** - * This class reflects Java methods into the JavaScript environment. It - * handles overloading of methods, and method/field name conflicts. - * All NativeJavaMethods behave as JSRef `bound' methods, in that they - * always operate on the object underlying the original NativeJavaObject - * parent regardless of any reparenting that may occur. - * - * @author Mike Shaver - * @see NativeJavaArray - * @see NativeJavaPackage - * @see NativeJavaClass - */ - -public class NativeJavaMethod extends NativeFunction implements Function { - - public NativeJavaMethod() { - this.functionName = null; - } - - public NativeJavaMethod(Method[] methods) { - this.methods = methods; - this.functionName = methods[0].getName(); - } - - public NativeJavaMethod(Method method, String name) { - this.methods = new Method[1]; - this.methods[0] = method; - this.functionName = name; - } - - public void add(Method method) { - if (functionName == null) { - functionName = method.getName(); - } else if (!functionName.equals(method.getName())) { - throw new RuntimeException("internal method name mismatch"); - } - // XXX a more intelligent growth algorithm would be nice - int len = methods == null ? 0 : methods.length; - Method[] newMeths = new Method[len + 1]; - for (int i = 0; i < len; i++) - newMeths[i] = methods[i]; - newMeths[len] = method; - methods = newMeths; - } - - static String scriptSignature(Object value) { - if (value == null) { - return "null"; - } - else { - Class type = value.getClass(); - if (type == ScriptRuntime.UndefinedClass) - return "undefined"; - if (type == ScriptRuntime.BooleanClass) - return "boolean"; - if (type == ScriptRuntime.StringClass) - return "string"; - if (ScriptRuntime.NumberClass.isAssignableFrom(type)) - return "number"; - if (value instanceof Wrapper) { - return ((Wrapper)value).unwrap().getClass().getName(); - } - if (value instanceof Scriptable) { - if (value instanceof Function) - return "function"; - return "object"; - } - return javaSignature(type); - } - } - - static String scriptSignature(Object[] values) { - StringBuffer sig = new StringBuffer(); - for (int i = 0; i < values.length; i++) { - if (i != 0) - sig.append(','); - sig.append(scriptSignature(values[i])); - } - return sig.toString(); - } - - static String javaSignature(Class type) { - if (type == null) { - return "null"; - } - else if (type.isArray()) { - return javaSignature(type.getComponentType()) + "[]"; - } - return type.getName(); - } - - static String javaSignature(Class[] types) { - StringBuffer sig = new StringBuffer(); - for (int i = 0; i < types.length; i++) { - if (i != 0) - sig.append(','); - sig.append(javaSignature(types[i])); - } - return sig.toString(); - } - - static String signature(Member member) { - Class paramTypes[]; - - if (member instanceof Method) { - paramTypes = ((Method) member).getParameterTypes(); - return member.getName() + "(" + javaSignature(paramTypes) + ")"; - } - else { - paramTypes = ((Constructor) member).getParameterTypes(); - return "(" + javaSignature(paramTypes) + ")"; - } - } - - public String decompile(Context cx, int indent, boolean justbody) { - StringBuffer sb = new StringBuffer(); - if (!justbody) { - sb.append("function "); - sb.append(getFunctionName()); - sb.append("() {"); - } - sb.append("/*\n"); - toString(sb); - sb.append(justbody ? "*/\n" : "*/}\n"); - return sb.toString(); - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - toString(sb); - return sb.toString(); - } - - private void toString(StringBuffer sb) { - for (int i=0; i < methods.length; i++) { - sb.append(javaSignature(methods[i].getReturnType())); - sb.append(' '); - sb.append(signature(methods[i])); - sb.append('\n'); - } - } - - public Object call(Context cx, Scriptable scope, Scriptable thisObj, - Object[] args) - throws JavaScriptException - { - // Find a method that matches the types given. - if (methods.length == 0) { - throw new RuntimeException("No methods defined for call"); - } - - Method meth = (Method) findFunction(methods, args); - if (meth == null) { - Class c = methods[0].getDeclaringClass(); - String sig = c.getName() + "." + functionName + "(" + - scriptSignature(args) + ")"; - throw Context.reportRuntimeError1("msg.java.no_such_method", sig); - } - - // OPT: already retrieved in findFunction, so we should inline that - // OPT: or pass it back somehow - Class paramTypes[] = meth.getParameterTypes(); - - // First, we marshall the args. - for (int i = 0; i < args.length; i++) { - args[i] = NativeJavaObject.coerceType(paramTypes[i], args[i]); - } - Object javaObject; - if (Modifier.isStatic(meth.getModifiers())) { - javaObject = null; // don't need an object - } else { - Scriptable o = thisObj; - while (!(o instanceof Wrapper)) { - o = o.getPrototype(); - if (o == null) { - throw Context.reportRuntimeError1( - "msg.nonjava.method", functionName); - } - } - javaObject = ((Wrapper) o).unwrap(); - } - try { - if (debug) { - printDebug("Calling ", meth, args); - } - - Object retval = meth.invoke(javaObject, args); - Class staticType = meth.getReturnType(); - - if (debug) { - Class actualType = (retval == null) ? null : retval.getClass(); - System.err.println(" ----- Returned " + retval + - " actual = " + actualType + - " expect = " + staticType); - } - - Object wrapped = NativeJavaObject.wrap(scope, retval, staticType); - - if (debug) { - Class actualType = (wrapped == null) ? null : wrapped.getClass(); - System.err.println(" ----- Wrapped as " + wrapped + - " class = " + actualType); - } - - if (wrapped == Undefined.instance) - return wrapped; - if (wrapped == null && staticType == Void.TYPE) - return Undefined.instance; - return wrapped; - } catch (IllegalAccessException accessEx) { - throw Context.reportRuntimeError(accessEx.getMessage()); - } catch (InvocationTargetException e) { - throw JavaScriptException.wrapException(scope, e); - } - } - - /** - * Find the correct function to call given the set of methods - * or constructors and the arguments. - * If no function can be found to call, return null. - */ - static Member findFunction(Member[] methodsOrCtors, Object[] args) { - if (methodsOrCtors.length == 0) - return null; - boolean hasMethods = methodsOrCtors[0] instanceof Method; - if (Context.useJSObject && - NativeJavaObject.jsObjectClass != null) - { - try { - for (int i = 0; i < args.length; i++) { - if (NativeJavaObject.jsObjectClass.isInstance(args[i])) - args[i] = NativeJavaObject.jsObjectGetScriptable.invoke( - args[i], ScriptRuntime.emptyArgs); - } - } - catch (InvocationTargetException e) { - // Just abandon conversion from JSObject - } - catch (IllegalAccessException e) { - // Just abandon conversion from JSObject - } - } - - Member bestFit = null; - Class[] bestFitTypes = null; - - java.util.Vector ambiguousMethods = null; - - for (int i = 0; i < methodsOrCtors.length; i++) { - Member member = methodsOrCtors[i]; - Class paramTypes[] = hasMethods - ? ((Method) member).getParameterTypes() - : ((Constructor) member).getParameterTypes(); - if (paramTypes.length != args.length) { - continue; - } - if (bestFitTypes == null) { - int j; - for (j = 0; j < paramTypes.length; j++) { - if (!NativeJavaObject.canConvert(args[j], paramTypes[j])) { - if (debug) printDebug("Rejecting (args can't convert) ", - member, args); - break; - } - } - if (j == paramTypes.length) { - if (debug) printDebug("Found ", member, args); - bestFit = member; - bestFitTypes = paramTypes; - } - } - else { - int preference = - NativeJavaMethod.preferSignature(args, - paramTypes, - bestFitTypes); - if (preference == PREFERENCE_AMBIGUOUS) { - if (debug) printDebug("Deferring ", member, args); - // add to "ambiguity list" - if (ambiguousMethods == null) - ambiguousMethods = new java.util.Vector(); - ambiguousMethods.addElement(member); - } - else if (preference == PREFERENCE_FIRST_ARG) { - if (debug) printDebug("Substituting ", member, args); - bestFit = member; - bestFitTypes = paramTypes; - } - else { - if (preference == PREFERENCE_EQUAL && - Modifier.isStatic(bestFit.getModifiers()) && - bestFit.getDeclaringClass().isAssignableFrom( - member.getDeclaringClass())) - { - // On some JVMs, Class.getMethods will return all - // static methods of the class heirarchy, even if - // a derived class's parameters match exactly. - // We want to call the dervied class's method. - if (debug) printDebug("Rejecting (overridden static)", - member, args); - bestFit = member; - bestFitTypes = paramTypes; - } else { - if (debug) printDebug("Rejecting ", member, args); - } - } - } - } - - if (ambiguousMethods == null) - return bestFit; - - // Compare ambiguous methods with best fit, in case - // the current best fit removes the ambiguities. - for (int i = ambiguousMethods.size() - 1; i >= 0 ; i--) { - Member member = (Member)ambiguousMethods.elementAt(i); - Class paramTypes[] = hasMethods - ? ((Method) member).getParameterTypes() - : ((Constructor) member).getParameterTypes(); - int preference = - NativeJavaMethod.preferSignature(args, - paramTypes, - bestFitTypes); - - if (preference == PREFERENCE_FIRST_ARG) { - if (debug) printDebug("Substituting ", member, args); - bestFit = member; - bestFitTypes = paramTypes; - ambiguousMethods.removeElementAt(i); - } - else if (preference == PREFERENCE_SECOND_ARG) { - if (debug) printDebug("Rejecting ", member, args); - ambiguousMethods.removeElementAt(i); - } - else { - if (debug) printDebug("UNRESOLVED: ", member, args); - } - } - - if (ambiguousMethods.size() > 0) { - // PENDING: report remaining ambiguity - StringBuffer buf = new StringBuffer(); - boolean isCtor = (bestFit instanceof Constructor); - - ambiguousMethods.addElement(bestFit); - - for (int i = 0; i < ambiguousMethods.size(); i++) { - if (i != 0) { - buf.append(", "); - } - Member member = (Member)ambiguousMethods.elementAt(i); - if (!isCtor) { - Class rtnType = ((Method)member).getReturnType(); - buf.append(rtnType); - buf.append(' '); - } - buf.append(NativeJavaMethod.signature(member)); - } - - String errMsg; - if (isCtor) { - Object errArgs[] = { - bestFit.getName(), - NativeJavaMethod.scriptSignature(args), - buf.toString() - }; - errMsg = - Context.getMessage("msg.constructor.ambiguous", errArgs); - } - else { - Object errArgs[] = { - bestFit.getDeclaringClass().getName(), - bestFit.getName(), - NativeJavaMethod.scriptSignature(args), - buf.toString() - }; - errMsg = Context.getMessage("msg.method.ambiguous", errArgs); - } - - throw - Context.reportRuntimeError(errMsg); - } - - return bestFit; - } - - /** Types are equal */ - static final int PREFERENCE_EQUAL = 0; - static final int PREFERENCE_FIRST_ARG = 1; - static final int PREFERENCE_SECOND_ARG = 2; - /** No clear "easy" conversion */ - static final int PREFERENCE_AMBIGUOUS = 3; - - /** - * Determine which of two signatures is the closer fit. - * Returns one of PREFERENCE_EQUAL, PREFERENCE_FIRST_ARG, - * PREFERENCE_SECOND_ARG, or PREFERENCE_AMBIGUOUS. - */ - public static int preferSignature(Object[] args, - Class[] sig1, Class[] sig2) - { - int preference = 0; - - for (int j = 0; j < args.length; j++) { - Class type1 = sig1[j]; - Class type2 = sig2[j]; - - if (type1 == type2) { - continue; - } - - preference |= - NativeJavaMethod.preferConversion(args[j], - type1, - type2); - - if (preference == PREFERENCE_AMBIGUOUS) { - break; - } - } - return preference; - } - - - /** - * Determine which of two types is the easier conversion. - * Returns one of PREFERENCE_EQUAL, PREFERENCE_FIRST_ARG, - * PREFERENCE_SECOND_ARG, or PREFERENCE_AMBIGUOUS. - */ - public static int preferConversion(Object fromObj, - Class toClass1, Class toClass2) { - - int rank1 = - NativeJavaObject.getConversionWeight(fromObj, toClass1); - int rank2 = - NativeJavaObject.getConversionWeight(fromObj, toClass2); - - if (rank1 == NativeJavaObject.CONVERSION_NONTRIVIAL && - rank2 == NativeJavaObject.CONVERSION_NONTRIVIAL) { - - if (toClass1.isAssignableFrom(toClass2)) { - return PREFERENCE_SECOND_ARG; - } - else if (toClass2.isAssignableFrom(toClass1)) { - return PREFERENCE_FIRST_ARG; - } - } - else { - if (rank1 < rank2) { - return PREFERENCE_FIRST_ARG; - } - else if (rank1 > rank2) { - return PREFERENCE_SECOND_ARG; - } - } - return PREFERENCE_AMBIGUOUS; - } - - Method[] getMethods() { - return methods; - } - - private static final boolean debug = false; - - private static void printDebug(String msg, Member member, Object[] args) { - if (debug) { - System.err.println(" ----- " + msg + - member.getDeclaringClass().getName() + - "." + signature(member) + - " for arguments (" + scriptSignature(args) + ")"); - } - } - - Method methods[]; -} - diff --git a/src/org/mozilla/javascript/NativeJavaObject.java b/src/org/mozilla/javascript/NativeJavaObject.java deleted file mode 100644 index 283252f..0000000 --- a/src/org/mozilla/javascript/NativeJavaObject.java +++ /dev/null @@ -1,926 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * Igor Bukanov - * Frank Mitchell - * Mike Shaver - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -import java.lang.reflect.*; -import java.util.Hashtable; -import java.util.Enumeration; - -/** - * This class reflects non-Array Java objects into the JavaScript environment. It - * reflect fields directly, and uses NativeJavaMethod objects to reflect (possibly - * overloaded) methods.

- * - * @author Mike Shaver - * @see NativeJavaArray - * @see NativeJavaPackage - * @see NativeJavaClass - */ - -public class NativeJavaObject implements Scriptable, Wrapper { - - public NativeJavaObject(Scriptable scope, Object javaObject, - JavaMembers members) - { - this.parent = scope; - this.javaObject = javaObject; - this.members = members; - } - - public NativeJavaObject(Scriptable scope, Object javaObject, - Class staticType) - { - this.parent = scope; - this.javaObject = javaObject; - Class dynamicType = javaObject != null ? javaObject.getClass() - : staticType; - members = JavaMembers.lookupClass(scope, dynamicType, staticType); - fieldAndMethods = members.getFieldAndMethodsObjects(this, javaObject, false); - } - - public boolean has(String name, Scriptable start) { - return members.has(name, false); - } - - public boolean has(int index, Scriptable start) { - return false; - } - - public Object get(String name, Scriptable start) { - if (fieldAndMethods != null) { - Object result = fieldAndMethods.get(name); - if (result != null) { - return result; - } - } - // TODO: passing 'this' as the scope is bogus since it has - // no parent scope - return members.get(this, name, javaObject, false); - } - - public Object get(int index, Scriptable start) { - throw members.reportMemberNotFound(Integer.toString(index)); - } - - public void put(String name, Scriptable start, Object value) { - // We could be asked to modify the value of a property in the - // prototype. Since we can't add a property to a Java object, - // we modify it in the prototype rather than copy it down. - if (prototype == null || members.has(name, false)) - members.put(this, name, javaObject, value, false); - else - prototype.put(name, prototype, value); - } - - public void put(int index, Scriptable start, Object value) { - throw members.reportMemberNotFound(Integer.toString(index)); - } - - public boolean hasInstance(Scriptable value) { - // This is an instance of a Java class, so always return false - return false; - } - - public void delete(String name) { - } - - public void delete(int index) { - } - - public Scriptable getPrototype() { - if (prototype == null && javaObject.getClass() == ScriptRuntime.StringClass) { - return ScriptableObject.getClassPrototype(parent, "String"); - } - return prototype; - } - - /** - * Sets the prototype of the object. - */ - public void setPrototype(Scriptable m) { - prototype = m; - } - - /** - * Returns the parent (enclosing) scope of the object. - */ - public Scriptable getParentScope() { - return parent; - } - - /** - * Sets the parent (enclosing) scope of the object. - */ - public void setParentScope(Scriptable m) { - parent = m; - } - - public Object[] getIds() { - return members.getIds(false); - } - - public static Object wrap(Scriptable scope, Object obj, Class staticType) - { - if (obj == null) - return obj; - Context cx = Context.getCurrentContext(); - if (cx != null && cx.wrapHandler != null) { - Object result = cx.wrapHandler.wrap(scope, obj, staticType); - if (result != null) - return result; - } - Class cls = obj.getClass(); - if (staticType != null && staticType.isPrimitive()) { - if (staticType == Void.TYPE) - return Undefined.instance; - if (staticType == Character.TYPE) - return new Integer((int) ((Character) obj).charValue()); - return obj; - } - if (cls.isArray()) - return NativeJavaArray.wrap(scope, obj); - if (obj instanceof Scriptable) - return obj; - if (Context.useJSObject && jsObjectClass != null && - staticType != jsObjectClass && jsObjectClass.isInstance(obj)) - { - try { - return jsObjectGetScriptable.invoke(obj, ScriptRuntime.emptyArgs); - } - catch (InvocationTargetException e) { - // Just abandon conversion from JSObject - } - catch (IllegalAccessException e) { - // Just abandon conversion from JSObject - } - } - return new NativeJavaObject(scope, obj, staticType); - } - - public Object unwrap() { - return javaObject; - } - - public String getClassName() { - return "JavaObject"; - } - - Function getConverter(String converterName) { - Object converterFunction = get(converterName, this); - if (converterFunction instanceof Function) { - return (Function) converterFunction; - } - return null; - } - - Object callConverter(Function converterFunction) - throws JavaScriptException - { - Function f = (Function) converterFunction; - return f.call(Context.getContext(), f.getParentScope(), - this, ScriptRuntime.emptyArgs); - } - - Object callConverter(String converterName) - throws JavaScriptException - { - Function converter = getConverter(converterName); - if (converter == null) { - return javaObject.toString(); - } - return callConverter(converter); - } - - public Object getDefaultValue(Class hint) { - if (hint == null || hint == ScriptRuntime.StringClass) - return javaObject.toString(); - try { - if (hint == ScriptRuntime.BooleanClass) - return callConverter("booleanValue"); - if (hint == ScriptRuntime.NumberClass) { - return callConverter("doubleValue"); - } - // fall through to error message - } catch (JavaScriptException jse) { - // fall through to error message - } - throw Context.reportRuntimeError0("msg.default.value"); - } - - - /** - * Determine whether we can/should convert between the given type and the - * desired one. This should be superceded by a conversion-cost calculation - * function, but for now I'll hide behind precedent. - */ - public static boolean canConvert(Object fromObj, Class to) { - int weight = NativeJavaObject.getConversionWeight(fromObj, to); - - return (weight < CONVERSION_NONE); - } - - static final int JSTYPE_UNDEFINED = 0; // undefined type - static final int JSTYPE_NULL = 1; // null - static final int JSTYPE_BOOLEAN = 2; // boolean - static final int JSTYPE_NUMBER = 3; // number - static final int JSTYPE_STRING = 4; // string - static final int JSTYPE_JAVA_CLASS = 5; // JavaClass - static final int JSTYPE_JAVA_OBJECT = 6; // JavaObject - static final int JSTYPE_JAVA_ARRAY = 7; // JavaArray - static final int JSTYPE_OBJECT = 8; // Scriptable - - public static final byte CONVERSION_TRIVIAL = 1; - public static final byte CONVERSION_NONTRIVIAL = 0; - public static final byte CONVERSION_NONE = 99; - - /** - * Derive a ranking based on how "natural" the conversion is. - * The special value CONVERSION_NONE means no conversion is possible, - * and CONVERSION_NONTRIVIAL signals that more type conformance testing - * is required. - * Based on - * - * "preferred method conversions" from Live Connect 3 - */ - public static int getConversionWeight(Object fromObj, Class to) { - int fromCode = NativeJavaObject.getJSTypeCode(fromObj); - - int result = CONVERSION_NONE; - - switch (fromCode) { - - case JSTYPE_UNDEFINED: - if (to == ScriptRuntime.StringClass || - to == ScriptRuntime.ObjectClass) { - result = 1; - } - break; - - case JSTYPE_NULL: - if (!to.isPrimitive()) { - result = 1; - } - break; - - case JSTYPE_BOOLEAN: - // "boolean" is #1 - if (to == Boolean.TYPE) { - result = 1; - } - else if (to == ScriptRuntime.BooleanClass) { - result = 2; - } - else if (to == ScriptRuntime.ObjectClass) { - result = 3; - } - else if (to == ScriptRuntime.StringClass) { - result = 4; - } - break; - - case JSTYPE_NUMBER: - if (to.isPrimitive()) { - if (to == Double.TYPE) { - result = 1; - } - else if (to != Boolean.TYPE) { - result = 1 + NativeJavaObject.getSizeRank(to); - } - } - else { - if (to == ScriptRuntime.StringClass) { - // native numbers are #1-8 - result = 9; - } - else if (to == ScriptRuntime.ObjectClass) { - result = 10; - } - else if (ScriptRuntime.NumberClass.isAssignableFrom(to)) { - // "double" is #1 - result = 2; - } - } - break; - - case JSTYPE_STRING: - if (to == ScriptRuntime.StringClass) { - result = 1; - } - else if (to == ScriptRuntime.ObjectClass) { - result = 2; - } - else if (to.isPrimitive() && to != Boolean.TYPE) { - if (to == Character.TYPE) { - result = 3; - } - else { - result = 4; - } - } - break; - - case JSTYPE_JAVA_CLASS: - if (to == ScriptRuntime.ClassClass) { - result = 1; - } - else if (Context.useJSObject && jsObjectClass != null && - jsObjectClass.isAssignableFrom(to)) { - result = 2; - } - else if (to == ScriptRuntime.ObjectClass) { - result = 3; - } - else if (to == ScriptRuntime.StringClass) { - result = 4; - } - break; - - case JSTYPE_JAVA_OBJECT: - case JSTYPE_JAVA_ARRAY: - if (to == ScriptRuntime.StringClass) { - result = 2; - } - else if (to.isPrimitive() && to != Boolean.TYPE) { - result = - (fromCode == JSTYPE_JAVA_ARRAY) ? - CONVERSION_NONTRIVIAL : - 2 + NativeJavaObject.getSizeRank(to); - } - else { - Object javaObj = fromObj; - if (javaObj instanceof Wrapper) { - javaObj = ((Wrapper)javaObj).unwrap(); - } - if (to.isInstance(javaObj)) { - result = CONVERSION_NONTRIVIAL; - } - } - break; - - case JSTYPE_OBJECT: - // Other objects takes #1-#3 spots - if (Context.useJSObject && jsObjectClass != null && - jsObjectClass.isAssignableFrom(to)) { - result = 1; - } - else if (fromObj instanceof NativeArray && to.isArray()) { - // This is a native array conversion to a java array - // Array conversions are all equal, and preferable to object - // and string conversion, per LC3. - result = 1; - } - else if (to == ScriptRuntime.ObjectClass) { - result = 2; - } - else if (to == ScriptRuntime.StringClass) { - result = 3; - } - else if (to.isPrimitive() || to != Boolean.TYPE) { - result = 3 + NativeJavaObject.getSizeRank(to); - } - break; - } - - return result; - - } - - static int getSizeRank(Class aType) { - if (aType == Double.TYPE) { - return 1; - } - else if (aType == Float.TYPE) { - return 2; - } - else if (aType == Long.TYPE) { - return 3; - } - else if (aType == Integer.TYPE) { - return 4; - } - else if (aType == Short.TYPE) { - return 5; - } - else if (aType == Character.TYPE) { - return 6; - } - else if (aType == Byte.TYPE) { - return 7; - } - else if (aType == Boolean.TYPE) { - return CONVERSION_NONE; - } - else { - return 8; - } - } - - static int getJSTypeCode(Object value) { - if (value == null) { - return JSTYPE_NULL; - } - else if (value == Undefined.instance) { - return JSTYPE_UNDEFINED; - } - else if (value instanceof Scriptable) { - if (value instanceof NativeJavaClass) { - return JSTYPE_JAVA_CLASS; - } - else if (value instanceof NativeJavaArray) { - return JSTYPE_JAVA_ARRAY; - } - else if (value instanceof NativeJavaObject) { - return JSTYPE_JAVA_OBJECT; - } - else { - return JSTYPE_OBJECT; - } - } - else { - Class valueClass = value.getClass(); - - if (valueClass == ScriptRuntime.StringClass) { - return JSTYPE_STRING; - } - else if (valueClass == ScriptRuntime.BooleanClass) { - return JSTYPE_BOOLEAN; - } - else if (value instanceof Number) { - return JSTYPE_NUMBER; - } - else if (valueClass == ScriptRuntime.ClassClass) { - return JSTYPE_JAVA_CLASS; - } - else if (valueClass.isArray()) { - return JSTYPE_JAVA_ARRAY; - } - else { - return JSTYPE_JAVA_OBJECT; - } - } - } - - /** - * Type-munging for field setting and method invocation. - * Conforms to LC3 specification - */ - public static Object coerceType(Class type, Object value) { - if (value != null && value.getClass() == type) { - return value; - } - - switch (NativeJavaObject.getJSTypeCode(value)) { - - case JSTYPE_NULL: - // raise error if type.isPrimitive() - if (type.isPrimitive()) { - reportConversionError(value, type); - } - return null; - - case JSTYPE_UNDEFINED: - if (type == ScriptRuntime.StringClass || - type == ScriptRuntime.ObjectClass) { - return "undefined"; - } - else { - reportConversionError("undefined", type); - } - break; - - case JSTYPE_BOOLEAN: - // Under LC3, only JS Booleans can be coerced into a Boolean value - if (type == Boolean.TYPE || - type == ScriptRuntime.BooleanClass || - type == ScriptRuntime.ObjectClass) { - return value; - } - else if (type == ScriptRuntime.StringClass) { - return value.toString(); - } - else { - reportConversionError(value, type); - } - break; - - case JSTYPE_NUMBER: - if (type == ScriptRuntime.StringClass) { - return ScriptRuntime.toString(value); - } - else if (type == ScriptRuntime.ObjectClass) { - return coerceToNumber(Double.TYPE, value); - } - else if ((type.isPrimitive() && type != Boolean.TYPE) || - ScriptRuntime.NumberClass.isAssignableFrom(type)) { - return coerceToNumber(type, value); - } - else { - reportConversionError(value, type); - } - break; - - case JSTYPE_STRING: - if (type == ScriptRuntime.StringClass || - type == ScriptRuntime.ObjectClass) { - return value; - } - else if (type == Character.TYPE || - type == ScriptRuntime.CharacterClass) { - // Special case for converting a single char string to a - // character - // Placed here because it applies *only* to JS strings, - // not other JS objects converted to strings - if (((String)value).length() == 1) { - return new Character(((String)value).charAt(0)); - } - else { - return coerceToNumber(type, value); - } - } - else if ((type.isPrimitive() && type != Boolean.TYPE) || - ScriptRuntime.NumberClass.isAssignableFrom(type)) { - return coerceToNumber(type, value); - } - else { - reportConversionError(value, type); - } - break; - - case JSTYPE_JAVA_CLASS: - if (Context.useJSObject && jsObjectClass != null && - (type == ScriptRuntime.ObjectClass || - jsObjectClass.isAssignableFrom(type))) { - return coerceToJSObject(type, (Scriptable)value); - } - else { - if (value instanceof Wrapper) { - value = ((Wrapper)value).unwrap(); - } - - if (type == ScriptRuntime.ClassClass || - type == ScriptRuntime.ObjectClass) { - return value; - } - else if (type == ScriptRuntime.StringClass) { - return value.toString(); - } - else { - reportConversionError(value, type); - } - } - break; - - case JSTYPE_JAVA_OBJECT: - case JSTYPE_JAVA_ARRAY: - if (type.isPrimitive()) { - if (type == Boolean.TYPE) { - reportConversionError(value, type); - } - return coerceToNumber(type, value); - } - else { - if (value instanceof Wrapper) { - value = ((Wrapper)value).unwrap(); - } - if (type == ScriptRuntime.StringClass) { - return value.toString(); - } - else { - if (type.isInstance(value)) { - return value; - } - else { - reportConversionError(value, type); - } - } - } - break; - - case JSTYPE_OBJECT: - if (Context.useJSObject && jsObjectClass != null && - (type == ScriptRuntime.ObjectClass || - jsObjectClass.isAssignableFrom(type))) { - return coerceToJSObject(type, (Scriptable)value); - } - else if (type == ScriptRuntime.StringClass) { - return ScriptRuntime.toString(value); - } - else if (type.isPrimitive()) { - if (type == Boolean.TYPE) { - reportConversionError(value, type); - } - return coerceToNumber(type, value); - } - else if (type.isInstance(value)) { - return value; - } - else if (type.isArray() && value instanceof NativeArray) { - // Make a new java array, and coerce the JS array components - // to the target (component) type. - NativeArray array = (NativeArray) value; - long length = array.jsGet_length(); - Class arrayType = type.getComponentType(); - Object Result = Array.newInstance(arrayType, (int)length); - for (int i = 0 ; i < length ; ++i) { - try { - Array.set(Result, i, coerceType(arrayType, - array.get(i, array))); - } - catch (EvaluatorException ee) { - reportConversionError(value, type); - } - } - - return Result; - } - else if (value instanceof Wrapper) { - value = ((Wrapper)value).unwrap(); - if (type.isInstance(value)) - return value; - reportConversionError(value, type); - } - else { - reportConversionError(value, type); - } - break; - } - - return value; - } - - static Object coerceToJSObject(Class type, Scriptable value) { - // If JSObject compatibility is enabled, and the method wants it, - // wrap the Scriptable value in a JSObject. - - if (ScriptRuntime.ScriptableClass.isAssignableFrom(type)) - return value; - - try { - Object ctorArgs[] = { value }; - return jsObjectCtor.newInstance(ctorArgs); - } catch (InstantiationException instEx) { - throw new EvaluatorException("error generating JSObject wrapper for " + - value); - } catch (IllegalArgumentException argEx) { - throw new EvaluatorException("JSObject constructor doesn't want [Scriptable]!"); - } catch (InvocationTargetException e) { - throw WrappedException.wrapException(e.getTargetException()); - } catch (IllegalAccessException accessEx) { - throw new EvaluatorException("JSObject constructor is protected/private!"); - } - } - - static Object coerceToNumber(Class type, Object value) { - Class valueClass = value.getClass(); - - // Character - if (type == Character.TYPE || type == ScriptRuntime.CharacterClass) { - if (valueClass == ScriptRuntime.CharacterClass) { - return value; - } - return new Character((char)toInteger(value, - ScriptRuntime.CharacterClass, - (double)Character.MIN_VALUE, - (double)Character.MAX_VALUE)); - } - - // Double, Float - if (type == ScriptRuntime.ObjectClass || - type == ScriptRuntime.DoubleClass || type == Double.TYPE) { - return valueClass == ScriptRuntime.DoubleClass - ? value - : new Double(toDouble(value)); - } - - if (type == ScriptRuntime.FloatClass || type == Float.TYPE) { - if (valueClass == ScriptRuntime.FloatClass) { - return value; - } - else { - double number = toDouble(value); - if (Double.isInfinite(number) || Double.isNaN(number) - || number == 0.0) { - return new Float((float)number); - } - else { - double absNumber = Math.abs(number); - if (absNumber < (double)Float.MIN_VALUE) { - return new Float((number > 0.0) ? +0.0 : -0.0); - } - else if (absNumber > (double)Float.MAX_VALUE) { - return new Float((number > 0.0) ? - Float.POSITIVE_INFINITY : - Float.NEGATIVE_INFINITY); - } - else { - return new Float((float)number); - } - } - } - } - - // Integer, Long, Short, Byte - if (type == ScriptRuntime.IntegerClass || type == Integer.TYPE) { - if (valueClass == ScriptRuntime.IntegerClass) { - return value; - } - else { - return new Integer((int)toInteger(value, - ScriptRuntime.IntegerClass, - (double)Integer.MIN_VALUE, - (double)Integer.MAX_VALUE)); - } - } - - if (type == ScriptRuntime.LongClass || type == Long.TYPE) { - if (valueClass == ScriptRuntime.LongClass) { - return value; - } - else { - /* Long values cannot be expressed exactly in doubles. - * We thus use the largest and smallest double value that - * has a value expressible as a long value. We build these - * numerical values from their hexidecimal representations - * to avoid any problems caused by attempting to parse a - * decimal representation. - */ - final double max = Double.longBitsToDouble(0x43dfffffffffffffL); - final double min = Double.longBitsToDouble(0xc3e0000000000000L); - return new Long(toInteger(value, - ScriptRuntime.LongClass, - min, - max)); - } - } - - if (type == ScriptRuntime.ShortClass || type == Short.TYPE) { - if (valueClass == ScriptRuntime.ShortClass) { - return value; - } - else { - return new Short((short)toInteger(value, - ScriptRuntime.ShortClass, - (double)Short.MIN_VALUE, - (double)Short.MAX_VALUE)); - } - } - - if (type == ScriptRuntime.ByteClass || type == Byte.TYPE) { - if (valueClass == ScriptRuntime.ByteClass) { - return value; - } - else { - return new Byte((byte)toInteger(value, - ScriptRuntime.ByteClass, - (double)Byte.MIN_VALUE, - (double)Byte.MAX_VALUE)); - } - } - - return new Double(toDouble(value)); - } - - - static double toDouble(Object value) { - if (value instanceof Number) { - return ((Number)value).doubleValue(); - } - else if (value instanceof String) { - return ScriptRuntime.toNumber((String)value); - } - else if (value instanceof Scriptable) { - if (value instanceof Wrapper) { - // XXX: optimize tail-recursion? - return toDouble(((Wrapper)value).unwrap()); - } - else { - return ScriptRuntime.toNumber(value); - } - } - else { - Method meth; - try { - meth = value.getClass().getMethod("doubleValue", null); - } - catch (NoSuchMethodException e) { - meth = null; - } - catch (SecurityException e) { - meth = null; - } - if (meth != null) { - try { - return ((Number)meth.invoke(value, null)).doubleValue(); - } - catch (IllegalAccessException e) { - // XXX: ignore, or error message? - reportConversionError(value, Double.TYPE); - } - catch (InvocationTargetException e) { - // XXX: ignore, or error message? - reportConversionError(value, Double.TYPE); - } - } - return ScriptRuntime.toNumber(value.toString()); - } - } - - static long toInteger(Object value, Class type, double min, double max) { - double d = toDouble(value); - - if (Double.isInfinite(d) || Double.isNaN(d)) { - // Convert to string first, for more readable message - reportConversionError(ScriptRuntime.toString(value), type); - } - - if (d > 0.0) { - d = Math.floor(d); - } - else { - d = Math.ceil(d); - } - - if (d < min || d > max) { - // Convert to string first, for more readable message - reportConversionError(ScriptRuntime.toString(value), type); - } - return (long)d; - } - - static void reportConversionError(Object value, Class type) { - throw Context.reportRuntimeError2 - ("msg.conversion.not.allowed", - value.toString(), NativeJavaMethod.javaSignature(type)); - } - - public static void initJSObject() { - // if netscape.javascript.JSObject is in the CLASSPATH, enable JSObject - // compatability wrappers - jsObjectClass = null; - try { - jsObjectClass = Class.forName("netscape.javascript.JSObject"); - Class ctorParms[] = { ScriptRuntime.ScriptableClass }; - jsObjectCtor = jsObjectClass.getConstructor(ctorParms); - jsObjectGetScriptable = jsObjectClass.getMethod("getScriptable", - new Class[0]); - } catch (ClassNotFoundException classEx) { - // jsObjectClass already null - } catch (NoSuchMethodException methEx) { - // jsObjectClass already null - } - } - - /** - * The prototype of this object. - */ - protected Scriptable prototype; - - /** - * The parent scope of this object. - */ - protected Scriptable parent; - - protected Object javaObject; - protected JavaMembers members; - private Hashtable fieldAndMethods; - static Class jsObjectClass; - static Constructor jsObjectCtor; - static Method jsObjectGetScriptable; -} - diff --git a/src/org/mozilla/javascript/NativeJavaPackage.java b/src/org/mozilla/javascript/NativeJavaPackage.java deleted file mode 100644 index 5a8c652..0000000 --- a/src/org/mozilla/javascript/NativeJavaPackage.java +++ /dev/null @@ -1,240 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * Frank Mitchell - * Mike Shaver - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -import java.lang.reflect.*; - -/** - * This class reflects Java packages into the JavaScript environment. We - * lazily reflect classes and subpackages, and use a caching/sharing - * system to ensure that members reflected into one JavaPackage appear - * in all other references to the same package (as with Packages.java.lang - * and java.lang). - * - * @author Mike Shaver - * @see NativeJavaArray - * @see NativeJavaObject - * @see NativeJavaClass - */ - -public class NativeJavaPackage extends ScriptableObject { - - // we know these are packages so we can skip the class check - // note that this is ok even if the package isn't present. - static final String[] commonPackages = { - "java.lang", - "java.lang.reflect", - "java.io", - "java.math", - "java.util", - "java.util.zip", - "java.text", - "java.text.resources", - "java.applet", - }; - - public static Scriptable init(Scriptable scope) - throws PropertyException - { - NativeJavaPackage packages = new NativeJavaPackage(""); - packages.setPrototype(getObjectPrototype(scope)); - packages.setParentScope(scope); - - // We want to get a real alias, and not a distinct JavaPackage - // with the same packageName, so that we share classes and packages - // that are underneath. - NativeJavaPackage javaAlias = (NativeJavaPackage)packages.get("java", - packages); - - // It's safe to downcast here since initStandardObjects takes - // a ScriptableObject. - ScriptableObject global = (ScriptableObject) scope; - - global.defineProperty("Packages", packages, ScriptableObject.DONTENUM); - global.defineProperty("java", javaAlias, ScriptableObject.DONTENUM); - - for (int i = 0; i < commonPackages.length; i++) - packages.forcePackage(commonPackages[i]); - - if (Context.useJSObject) - NativeJavaObject.initJSObject(); - - Method[] m = FunctionObject.findMethods(NativeJavaPackage.class, - "jsFunction_getClass"); - FunctionObject f = new FunctionObject("getClass", m[0], global); - global.defineProperty("getClass", f, ScriptableObject.DONTENUM); - - // I think I'm supposed to return the prototype, but I don't have one. - return packages; - } - - // set up a name which is known to be a package so we don't - // need to look for a class by that name - void forcePackage(String name) { - NativeJavaPackage pkg; - int end = name.indexOf('.'); - if (end == -1) - end = name.length(); - - String id = name.substring(0, end); - Object cached = super.get(id, this); - if (cached != null && cached instanceof NativeJavaPackage) { - pkg = (NativeJavaPackage) cached; - } else { - String newPackage = packageName.length() == 0 - ? id - : packageName + "." + id; - pkg = new NativeJavaPackage(newPackage); - pkg.setParentScope(this); - pkg.setPrototype(this.prototype); - super.put(id, this, pkg); - } - if (end < name.length()) - pkg.forcePackage(name.substring(end+1)); - } - - public NativeJavaPackage(String packageName) { - this.packageName = packageName; - } - - public String getClassName() { - return "JavaPackage"; - } - - public boolean has(String id, int index, Scriptable start) { - return true; - } - - public void put(String id, Scriptable start, Object value) { - // Can't add properties to Java packages. Sorry. - } - - public void put(int index, Scriptable start, Object value) { - throw Context.reportRuntimeError0("msg.pkg.int"); - } - - public Object get(String id, Scriptable start) { - return getPkgProperty(id, start, true); - } - - public Object get(int index, Scriptable start) { - return NOT_FOUND; - } - - synchronized Object getPkgProperty(String name, Scriptable start, - boolean createPkg) - { - Object cached = super.get(name, start); - if (cached != NOT_FOUND) - return cached; - - String newPackage = packageName.length() == 0 - ? name - : packageName + "." + name; - Context cx = Context.getContext(); - SecuritySupport ss = cx.getSecuritySupport(); - Scriptable newValue; - try { - /* - if (ss != null && !ss.visibleToScripts(newPackage)) - */ - throw new ClassNotFoundException(); - /* - Class newClass = ScriptRuntime.loadClassName(newPackage); - newValue = NativeJavaClass.wrap(getTopLevelScope(this), newClass); - newValue.setParentScope(this); - newValue.setPrototype(this.prototype); - */ - } catch (ClassNotFoundException ex) { - if (createPkg) { - NativeJavaPackage pkg = new NativeJavaPackage(newPackage); - pkg.setParentScope(this); - pkg.setPrototype(this.prototype); - newValue = pkg; - } else { - newValue = null; - } - } - if (newValue != null) { - // Make it available for fast lookup and sharing of - // lazily-reflected constructors and static members. - super.put(name, start, newValue); - } - return newValue; - } - - public Object getDefaultValue(Class ignored) { - return toString(); - } - - public String toString() { - return "[JavaPackage " + packageName + "]"; - } - - public static Scriptable jsFunction_getClass(Context cx, - Scriptable thisObj, - Object[] args, - Function funObj) - { - if (args.length > 0 && args[0] instanceof Wrapper) { - Scriptable result = getTopLevelScope(thisObj); - Class cl = ((Wrapper) args[0]).unwrap().getClass(); - // Evaluate the class name by getting successive properties of - // the string to find the appropriate NativeJavaClass object - String name = "Packages." + cl.getName(); - int offset = 0; - for (;;) { - int index = name.indexOf('.', offset); - String propName = index == -1 - ? name.substring(offset) - : name.substring(offset, index); - Object prop = result.get(propName, result); - if (!(prop instanceof Scriptable)) - break; // fall through to error - result = (Scriptable) prop; - if (index == -1) - return result; - offset = index+1; - } - } - throw Context.reportRuntimeError( - Context.getMessage0("msg.not.java.obj")); - } - - private String packageName; -} diff --git a/src/org/mozilla/javascript/NativeMath.java b/src/org/mozilla/javascript/NativeMath.java deleted file mode 100644 index a6e58c6..0000000 --- a/src/org/mozilla/javascript/NativeMath.java +++ /dev/null @@ -1,405 +0,0 @@ -/* -*- Mode: java; tab-width: 4; indent-tabs-mode: 1; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * Igor Bukanov - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -/** - * This class implements the Math native object. - * See ECMA 15.8. - * @author Norris Boyd - */ - -public class NativeMath extends IdScriptable -{ - public static void init(Context cx, Scriptable scope, boolean sealed) { - NativeMath obj = new NativeMath(); - obj.setSealFunctionsFlag(sealed); - obj.setFunctionParametrs(cx); - obj.setPrototype(getObjectPrototype(scope)); - obj.setParentScope(scope); - if (sealed) { obj.sealObject(); } - ScriptableObject.defineProperty(scope, "Math", obj, - ScriptableObject.DONTENUM); - } - - public String getClassName() { return "Math"; } - - protected int getIdDefaultAttributes(int id) { - if (id > LAST_METHOD_ID) { - return DONTENUM | READONLY | PERMANENT; - } - return super.getIdDefaultAttributes(id); - } - - protected Object getIdValue(int id) { - if (id > LAST_METHOD_ID) { - return cacheIdValue(id, wrap_double(getField(id))); - } - return super.getIdValue(id); - } - - private double getField(int fieldId) { - switch (fieldId) { - case Id_E: return E; - case Id_PI: return PI; - case Id_LN10: return LN10; - case Id_LN2: return LN2; - case Id_LOG2E: return LOG2E; - case Id_LOG10E: return LOG10E; - case Id_SQRT1_2: return SQRT1_2; - case Id_SQRT2: return SQRT2; - } - return 0; // Unreachable - } - - public int methodArity(int methodId) { - switch (methodId) { - case Id_abs: return 1; - case Id_acos: return 1; - case Id_asin: return 1; - case Id_atan: return 1; - case Id_atan2: return 2; - case Id_ceil: return 1; - case Id_cos: return 1; - case Id_exp: return 1; - case Id_floor: return 1; - case Id_log: return 1; - case Id_max: return 2; - case Id_min: return 2; - case Id_pow: return 2; - case Id_random: return 0; - case Id_round: return 1; - case Id_sin: return 1; - case Id_sqrt: return 1; - case Id_tan: return 1; - } - return super.methodArity(methodId); - } - - public Object execMethod - (int methodId, IdFunction f, - Context cx, Scriptable scope, Scriptable thisObj, Object[] args) - throws JavaScriptException - { - switch (methodId) { - case Id_abs: return wrap_double - (js_abs(ScriptRuntime.toNumber(args, 0))); - - case Id_acos: return wrap_double - (js_acos(ScriptRuntime.toNumber(args, 0))); - - case Id_asin: return wrap_double - (js_asin(ScriptRuntime.toNumber(args, 0))); - - case Id_atan: return wrap_double - (js_atan(ScriptRuntime.toNumber(args, 0))); - - case Id_atan2: return wrap_double - (js_atan2(ScriptRuntime.toNumber(args, 0), - ScriptRuntime.toNumber(args, 1))); - - case Id_ceil: return wrap_double - (js_ceil(ScriptRuntime.toNumber(args, 0))); - - case Id_cos: return wrap_double - (js_cos(ScriptRuntime.toNumber(args, 0))); - - case Id_exp: return wrap_double - (js_exp(ScriptRuntime.toNumber(args, 0))); - - case Id_floor: return wrap_double - (js_floor(ScriptRuntime.toNumber(args, 0))); - - case Id_log: return wrap_double - (js_log(ScriptRuntime.toNumber(args, 0))); - - case Id_max: return wrap_double - (js_max(args)); - - case Id_min: return wrap_double - (js_min(args)); - - case Id_pow: return wrap_double - (js_pow(ScriptRuntime.toNumber(args, 0), - ScriptRuntime.toNumber(args, 1))); - - case Id_random: return wrap_double - (js_random()); - - case Id_round: return wrap_double - (js_round(ScriptRuntime.toNumber(args, 0))); - - case Id_sin: return wrap_double - (js_sin(ScriptRuntime.toNumber(args, 0))); - - case Id_sqrt: return wrap_double - (js_sqrt(ScriptRuntime.toNumber(args, 0))); - - case Id_tan: return wrap_double - (js_tan(ScriptRuntime.toNumber(args, 0))); - } - return super.execMethod(methodId, f, cx, scope, thisObj, args); - } - - private double js_abs(double x) { - // abs(-0.0) should be 0.0, but -0.0 < 0.0 == false - return (x == 0.0) ? 0.0 : (x < 0.0) ? -x : x; - } - - private double js_acos(double x) { - return (x == x && -1.0 <= x && x <= 1.0) ? Math.acos(x) : Double.NaN; - } - - private double js_asin(double x) { - return (x == x && -1.0 <= x && x <= 1.0) ? Math.asin(x) : Double.NaN; - } - - private double js_atan(double x) { return Math.atan(x); } - - private double js_atan2(double x, double y) { return Math.atan2(x, y); } - - private double js_ceil(double x) { return Math.ceil(x); } - - private double js_cos(double x) { return Math.cos(x); } - - private double js_exp(double x) { - return (x == Double.POSITIVE_INFINITY) ? x - : (x == Double.NEGATIVE_INFINITY) ? 0.0 - : Math.exp(x); - } - - private double js_floor(double x) { return Math.floor(x); } - - private double js_log(double x) { - // Java's log(<0) = -Infinity; we need NaN - return (x < 0) ? Double.NaN : Math.log(x); - } - - private double js_max(Object[] args) { - double result = Double.NEGATIVE_INFINITY; - if (args.length == 0) - return result; - for (int i = 0; i < args.length; i++) { - double d = ScriptRuntime.toNumber(args[i]); - if (d != d) return d; - // if (result < d) result = d; does not work due to -0.0 >= +0.0 - result = Math.max(result, d); - } - return result; - } - - private double js_min(Object[] args) { - double result = Double.POSITIVE_INFINITY; - if (args.length == 0) - return result; - for (int i = 0; i < args.length; i++) { - double d = ScriptRuntime.toNumber(args[i]); - if (d != d) return d; - // if (result > d) result = d; does not work due to -0.0 >= +0.0 - result = Math.min(result, d); - } - return result; - } - - private double js_pow(double x, double y) { - if (y == 0) return 1.0; // Java's pow(NaN, 0) = NaN; we need 1 - if ((x == 0) && (y < 0)) { - if (1 / x > 0) { - // x is +0, Java is -oo, we need +oo - return Double.POSITIVE_INFINITY; - } - /* if x is -0 and y is an odd integer, -oo */ - int y_int = (int)y; - if (y_int == y && (y_int & 0x1) != 0) - return Double.NEGATIVE_INFINITY; - return Double.POSITIVE_INFINITY; - } - return Math.pow(x, y); - } - - private double js_random() { return Math.random(); } - - private double js_round(double d) { - if (d != d) - return d; // NaN - if (d == Double.POSITIVE_INFINITY || d == Double.NEGATIVE_INFINITY) - return d; - long l = Math.round(d); - if (l == 0) { - // We must propagate the sign of d into the result - if (d < 0.0) - return ScriptRuntime.negativeZero; - return d == 0.0 ? d : 0.0; - } - return (double) l; - } - - private double js_sin(double x) { return Math.sin(x); } - - private double js_sqrt(double x) { return Math.sqrt(x); } - - private double js_tan(double x) { return Math.tan(x); } - - protected int maxInstanceId() { return MAX_INSTANCE_ID; } - - protected String getIdName(int id) { - switch (id) { - case Id_abs: return "abs"; - case Id_acos: return "acos"; - case Id_asin: return "asin"; - case Id_atan: return "atan"; - case Id_atan2: return "atan2"; - case Id_ceil: return "ceil"; - case Id_cos: return "cos"; - case Id_exp: return "exp"; - case Id_floor: return "floor"; - case Id_log: return "log"; - case Id_max: return "max"; - case Id_min: return "min"; - case Id_pow: return "pow"; - case Id_random: return "random"; - case Id_round: return "round"; - case Id_sin: return "sin"; - case Id_sqrt: return "sqrt"; - case Id_tan: return "tan"; - - case Id_E: return "E"; - case Id_PI: return "PI"; - case Id_LN10: return "LN10"; - case Id_LN2: return "LN2"; - case Id_LOG2E: return "LOG2E"; - case Id_LOG10E: return "LOG10E"; - case Id_SQRT1_2: return "SQRT1_2"; - case Id_SQRT2: return "SQRT2"; - } - return null; - } - -// #string_id_map# - - protected int mapNameToId(String s) { - int id; -// #generated# Last update: 2001-03-23 13:50:14 GMT+01:00 - L0: { id = 0; String X = null; int c; - L: switch (s.length()) { - case 1: if (s.charAt(0)=='E') {id=Id_E; break L0;} break L; - case 2: if (s.charAt(0)=='P' && s.charAt(1)=='I') {id=Id_PI; break L0;} break L; - case 3: switch (s.charAt(0)) { - case 'L': if (s.charAt(2)=='2' && s.charAt(1)=='N') {id=Id_LN2; break L0;} break L; - case 'a': if (s.charAt(2)=='s' && s.charAt(1)=='b') {id=Id_abs; break L0;} break L; - case 'c': if (s.charAt(2)=='s' && s.charAt(1)=='o') {id=Id_cos; break L0;} break L; - case 'e': if (s.charAt(2)=='p' && s.charAt(1)=='x') {id=Id_exp; break L0;} break L; - case 'l': if (s.charAt(2)=='g' && s.charAt(1)=='o') {id=Id_log; break L0;} break L; - case 'm': c=s.charAt(2); - if (c=='n') { if (s.charAt(1)=='i') {id=Id_min; break L0;} } - else if (c=='x') { if (s.charAt(1)=='a') {id=Id_max; break L0;} } - break L; - case 'p': if (s.charAt(2)=='w' && s.charAt(1)=='o') {id=Id_pow; break L0;} break L; - case 's': if (s.charAt(2)=='n' && s.charAt(1)=='i') {id=Id_sin; break L0;} break L; - case 't': if (s.charAt(2)=='n' && s.charAt(1)=='a') {id=Id_tan; break L0;} break L; - } break L; - case 4: switch (s.charAt(1)) { - case 'N': X="LN10";id=Id_LN10; break L; - case 'c': X="acos";id=Id_acos; break L; - case 'e': X="ceil";id=Id_ceil; break L; - case 'q': X="sqrt";id=Id_sqrt; break L; - case 's': X="asin";id=Id_asin; break L; - case 't': X="atan";id=Id_atan; break L; - } break L; - case 5: switch (s.charAt(0)) { - case 'L': X="LOG2E";id=Id_LOG2E; break L; - case 'S': X="SQRT2";id=Id_SQRT2; break L; - case 'a': X="atan2";id=Id_atan2; break L; - case 'f': X="floor";id=Id_floor; break L; - case 'r': X="round";id=Id_round; break L; - } break L; - case 6: c=s.charAt(0); - if (c=='L') { X="LOG10E";id=Id_LOG10E; } - else if (c=='r') { X="random";id=Id_random; } - break L; - case 7: X="SQRT1_2";id=Id_SQRT1_2; break L; - } - if (X!=null && X!=s && !X.equals(s)) id = 0; - } -// #/generated# - return id; - } - - private static final int - Id_abs = 1, - Id_acos = 2, - Id_asin = 3, - Id_atan = 4, - Id_atan2 = 5, - Id_ceil = 6, - Id_cos = 7, - Id_exp = 8, - Id_floor = 9, - Id_log = 10, - Id_max = 11, - Id_min = 12, - Id_pow = 13, - Id_random = 14, - Id_round = 15, - Id_sin = 16, - Id_sqrt = 17, - Id_tan = 18, - - LAST_METHOD_ID = 18, - - Id_E = 19, - Id_PI = 20, - Id_LN10 = 21, - Id_LN2 = 22, - Id_LOG2E = 23, - Id_LOG10E = 24, - Id_SQRT1_2 = 25, - Id_SQRT2 = 26, - - MAX_INSTANCE_ID = 26; - -// #/string_id_map# - - private static final double - E = Math.E, - PI = Math.PI, - LN10 = 2.302585092994046, - LN2 = 0.6931471805599453, - LOG2E = 1.4426950408889634, - LOG10E = 0.4342944819032518, - SQRT1_2 = 0.7071067811865476, - SQRT2 = 1.4142135623730951; -} diff --git a/src/org/mozilla/javascript/NativeNumber.java b/src/org/mozilla/javascript/NativeNumber.java deleted file mode 100644 index 4ec2dcb..0000000 --- a/src/org/mozilla/javascript/NativeNumber.java +++ /dev/null @@ -1,280 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * Igor Bukanov - * Mike McCabe - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -/** - * This class implements the Number native object. - * - * See ECMA 15.7. - * - * @author Norris Boyd - */ -public class NativeNumber extends IdScriptable { - - private static final int MAX_PRECISION = 100; - - public static void init(Context cx, Scriptable scope, boolean sealed) { - NativeNumber obj = new NativeNumber(); - obj.prototypeFlag = true; - obj.addAsPrototype(MAX_PROTOTYPE_ID, cx, scope, sealed); - } - - /** - * Zero-parameter constructor: just used to create Number.prototype - */ - public NativeNumber() { - doubleValue = defaultValue; - } - - public NativeNumber(double number) { - doubleValue = number; - } - - public String getClassName() { - return "Number"; - } - - protected void fillConstructorProperties - (Context cx, IdFunction ctor, boolean sealed) - { - final int attr = ScriptableObject.DONTENUM | - ScriptableObject.PERMANENT | - ScriptableObject.READONLY; - - ctor.defineProperty("NaN", wrap_double(ScriptRuntime.NaN), attr); - ctor.defineProperty("POSITIVE_INFINITY", - wrap_double(Double.POSITIVE_INFINITY), attr); - ctor.defineProperty("NEGATIVE_INFINITY", - wrap_double(Double.NEGATIVE_INFINITY), attr); - ctor.defineProperty("MAX_VALUE", wrap_double(Double.MAX_VALUE), attr); - ctor.defineProperty("MIN_VALUE", wrap_double(Double.MIN_VALUE), attr); - - super.fillConstructorProperties(cx, ctor, sealed); - } - - public int methodArity(int methodId) { - if (prototypeFlag) { - switch (methodId) { - case Id_constructor: return 1; - case Id_toString: return 1; - case Id_valueOf: return 0; - case Id_toLocaleString: return 1; - case Id_toFixed: return 1; - case Id_toExponential: return 1; - case Id_toPrecision: return 1; - } - } - return super.methodArity(methodId); - } - - public Object execMethod - (int methodId, IdFunction f, - Context cx, Scriptable scope, Scriptable thisObj, Object[] args) - throws JavaScriptException - { - if (prototypeFlag) { - switch (methodId) { - case Id_constructor: - return jsConstructor(args, thisObj == null); - - case Id_toString: return realThis(thisObj, f). - jsFunction_toString(toBase(args, 0)); - - case Id_valueOf: return wrap_double(realThis(thisObj, f). - jsFunction_valueOf()); - - case Id_toLocaleString: return realThis(thisObj, f). - jsFunction_toLocaleString(toBase(args, 0)); - - case Id_toFixed: return realThis(thisObj, f). - jsFunction_toFixed(cx, args); - - case Id_toExponential: return realThis(thisObj, f). - jsFunction_toExponential(cx, args); - - case Id_toPrecision:return realThis(thisObj, f). - jsFunction_toPrecision(cx, args); - } - } - return super.execMethod(methodId, f, cx, scope, thisObj, args); - } - - private NativeNumber realThis(Scriptable thisObj, IdFunction f) { - while (!(thisObj instanceof NativeNumber)) { - thisObj = nextInstanceCheck(thisObj, f, true); - } - return (NativeNumber)thisObj; - } - - private static int toBase(Object[] args, int index) { - return (index < args.length) ? ScriptRuntime.toInt32(args[index]) : 10; - } - - private Object jsConstructor(Object[] args, boolean inNewExpr) { - double d = args.length >= 1 - ? ScriptRuntime.toNumber(args[0]) - : defaultValue; - if (inNewExpr) { - // new Number(val) creates a new Number object. - return new NativeNumber(d); - } - // Number(val) converts val to a number value. - return wrap_double(d); - } - - public String toString() { - return jsFunction_toString(10); - } - - private String jsFunction_toString(int base) { - return ScriptRuntime.numberToString(doubleValue, base); - } - - private double jsFunction_valueOf() { - return doubleValue; - } - - private String jsFunction_toLocaleString(int base) { - return jsFunction_toString(base); - } - - private String jsFunction_toFixed(Context cx, Object[] args) { - /* We allow a larger range of precision than - ECMA requires; this is permitted by ECMA. */ - return num_to(cx, args, DToA.DTOSTR_FIXED, DToA.DTOSTR_FIXED, - -20, MAX_PRECISION, 0); - } - - private String jsFunction_toExponential(Context cx, Object[] args) { - /* We allow a larger range of precision than - ECMA requires; this is permitted by ECMA. */ - return num_to(cx, args, - DToA.DTOSTR_STANDARD_EXPONENTIAL, - DToA.DTOSTR_EXPONENTIAL, - 0, MAX_PRECISION, 1); - } - - private String jsFunction_toPrecision(Context cx, Object[] args) { - /* We allow a larger range of precision than - ECMA requires; this is permitted by ECMA. */ - return num_to(cx, args, DToA.DTOSTR_STANDARD, DToA.DTOSTR_PRECISION, - 1, MAX_PRECISION, 0); - } - - private String num_to(Context cx, Object[] args, - int zeroArgMode, int oneArgMode, - int precisionMin, int precisionMax, - int precisionOffset) - { - int precision; - - if (args.length == 0) { - precision = 0; - oneArgMode = zeroArgMode; - } else { - precision = ScriptRuntime.toInt32(args[0]); - if (precision < precisionMin || precision > precisionMax) { - String msg = ScriptRuntime.getMessage1( - "msg.bad.precision", ScriptRuntime.toString(args[0])); - throw NativeGlobal.constructError(cx, "RangeError", msg, this); - } - } - StringBuffer result = new StringBuffer(); - DToA.JS_dtostr(result, oneArgMode, precision + precisionOffset, - doubleValue); - return result.toString(); - } - - protected String getIdName(int id) { - if (prototypeFlag) { - switch (id) { - case Id_constructor: return "constructor"; - case Id_toString: return "toString"; - case Id_valueOf: return "valueOf"; - case Id_toLocaleString: return "toLocaleString"; - case Id_toFixed: return "toFixed"; - case Id_toExponential: return "toExponential"; - case Id_toPrecision: return "toPrecision"; - } - } - return null; - } - -// #string_id_map# - - protected int mapNameToId(String s) { - if (!prototypeFlag) { return 0; } - int id; -// #generated# Last update: 2001-04-23 10:40:45 CEST - L0: { id = 0; String X = null; int c; - L: switch (s.length()) { - case 7: c=s.charAt(0); - if (c=='t') { X="toFixed";id=Id_toFixed; } - else if (c=='v') { X="valueOf";id=Id_valueOf; } - break L; - case 8: X="toString";id=Id_toString; break L; - case 11: c=s.charAt(0); - if (c=='c') { X="constructor";id=Id_constructor; } - else if (c=='t') { X="toPrecision";id=Id_toPrecision; } - break L; - case 13: X="toExponential";id=Id_toExponential; break L; - case 14: X="toLocaleString";id=Id_toLocaleString; break L; - } - if (X!=null && X!=s && !X.equals(s)) id = 0; - } -// #/generated# - return id; - } - - private static final int - Id_constructor = 1, - Id_toString = 2, - Id_valueOf = 3, - Id_toLocaleString = 4, - Id_toFixed = 5, - Id_toExponential = 6, - Id_toPrecision = 7, - MAX_PROTOTYPE_ID = 7; - -// #/string_id_map# - - private static final double defaultValue = +0.0; - private double doubleValue; - - private boolean prototypeFlag; -} diff --git a/src/org/mozilla/javascript/NativeObject.java b/src/org/mozilla/javascript/NativeObject.java deleted file mode 100644 index a2b8dee..0000000 --- a/src/org/mozilla/javascript/NativeObject.java +++ /dev/null @@ -1,291 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * Mike McCabe - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -import java.util.Hashtable; - -/** - * This class implements the Object native object. - * See ECMA 15.2. - * @author Norris Boyd - */ -public class NativeObject extends IdScriptable { - - public static void init(Context cx, Scriptable scope, boolean sealed) { - NativeObject obj = new NativeObject(); - obj.prototypeFlag = true; - obj.addAsPrototype(MAX_PROTOTYPE_ID, cx, scope, sealed); - } - - public String getClassName() { - return "Object"; - } - - public int methodArity(int methodId) { - if (prototypeFlag) { - switch (methodId) { - case Id_constructor: return 1; - case Id_toString: return 0; - case Id_toLocaleString: return 0; - case Id_valueOf: return 0; - case Id_hasOwnProperty: return 1; - case Id_propertyIsEnumerable: return 1; - case Id_isPrototypeOf: return 1; - } - } - return super.methodArity(methodId); - } - - public Object execMethod - (int methodId, IdFunction f, - Context cx, Scriptable scope, Scriptable thisObj, Object[] args) - throws JavaScriptException - { - if (prototypeFlag) { - switch (methodId) { - case Id_constructor: - return jsConstructor(cx, args, f, thisObj == null); - - case Id_toString: - return jsFunction_toString(cx, thisObj); - - case Id_toLocaleString: - return jsFunction_toLocaleString(cx, thisObj); - - case Id_valueOf: - return jsFunction_valueOf(thisObj); - - case Id_hasOwnProperty: - return jsFunction_hasOwnProperty(thisObj, args); - - case Id_propertyIsEnumerable: - return jsFunction_propertyIsEnumerable(cx, thisObj, args); - - case Id_isPrototypeOf: - return jsFunction_isPrototypeOf(cx, thisObj, args); - } - } - return super.execMethod(methodId, f, cx, scope, thisObj, args); - } - - private static Object jsConstructor(Context cx, Object[] args, - Function ctorObj, boolean inNewExpr) - throws JavaScriptException - { - if (!inNewExpr) { - // FunctionObject.construct will set up parent, proto - return ctorObj.construct(cx, ctorObj.getParentScope(), args); - } - if (args.length == 0 || args[0] == null || - args[0] == Undefined.instance) - { - return new NativeObject(); - } - return ScriptRuntime.toObject(ctorObj.getParentScope(), args[0]); - } - - public String toString() { - Context cx = Context.getCurrentContext(); - if (cx != null) - return jsFunction_toString(cx, this); - else - return "[object " + getClassName() + "]"; - } - - private static String jsFunction_toString(Context cx, Scriptable thisObj) - { - if (cx.getLanguageVersion() != cx.VERSION_1_2) - return "[object " + thisObj.getClassName() + "]"; - - return toSource(cx, thisObj); - } - - private static String jsFunction_toLocaleString(Context cx, - Scriptable thisObj) - { - return jsFunction_toString(cx, thisObj); - } - - private static String toSource(Context cx, Scriptable thisObj) - { - Scriptable m = thisObj; - - if (cx.iterating == null) - cx.iterating = new Hashtable(31); - - if (cx.iterating.get(m) == Boolean.TRUE) { - return "{}"; // stop recursion - } else { - StringBuffer result = new StringBuffer("{"); - Object[] ids = m.getIds(); - - for(int i=0; i < ids.length; i++) { - if (i > 0) - result.append(", "); - - Object id = ids[i]; - String idString = ScriptRuntime.toString(id); - Object p = (id instanceof String) - ? m.get((String) id, m) - : m.get(((Number) id).intValue(), m); - if (p instanceof String) { - result.append(idString + ":\"" - + ScriptRuntime - .escapeString(ScriptRuntime.toString(p)) - + "\""); - } else { - /* wrap changes to cx.iterating in a try/finally - * so that the reference always gets removed, and - * we don't leak memory. Good place for weak - * references, if we had them. - */ - try { - cx.iterating.put(m, Boolean.TRUE); // stop recursion. - result.append(idString + ":" + ScriptRuntime.toString(p)); - } finally { - cx.iterating.remove(m); - } - } - } - result.append('}'); - return result.toString(); - } - } - - private static Object jsFunction_valueOf(Scriptable thisObj) { - return thisObj; - } - - private static Object jsFunction_hasOwnProperty(Scriptable thisObj, - Object[] args) - { - if (args.length != 0) { - if (thisObj.has(ScriptRuntime.toString(args[0]), thisObj)) - return Boolean.TRUE; - } - return Boolean.FALSE; - } - - private static Object jsFunction_propertyIsEnumerable(Context cx, - Scriptable thisObj, - Object[] args) - { - try { - if (args.length != 0) { - String name = ScriptRuntime.toString(args[0]); - if (thisObj.has(name, thisObj)) { - int a = ((ScriptableObject)thisObj).getAttributes(name, thisObj); - if ((a & ScriptableObject.DONTENUM) == 0) - return Boolean.TRUE; - } - } - } - catch (PropertyException x) { - } - catch (ClassCastException x) { - } - return Boolean.FALSE; - } - - private static Object jsFunction_isPrototypeOf(Context cx, - Scriptable thisObj, - Object[] args) - { - if (args.length != 0 && args[0] instanceof Scriptable) { - Scriptable v = (Scriptable) args[0]; - do { - v = v.getPrototype(); - if (v == thisObj) - return Boolean.TRUE; - } while (v != null); - } - return Boolean.FALSE; - } - - protected String getIdName(int id) { - if (prototypeFlag) { - switch (id) { - case Id_constructor: return "constructor"; - case Id_toString: return "toString"; - case Id_toLocaleString: return "toLocaleString"; - case Id_valueOf: return "valueOf"; - case Id_hasOwnProperty: return "hasOwnProperty"; - case Id_propertyIsEnumerable: return "propertyIsEnumerable"; - case Id_isPrototypeOf: return "isPrototypeOf"; - } - } - return null; - } - -// #string_id_map# - - protected int mapNameToId(String s) { - if (!prototypeFlag) { return 0; } - int id; -// #generated# Last update: 2001-04-24 12:37:03 GMT+02:00 - L0: { id = 0; String X = null; int c; - L: switch (s.length()) { - case 7: X="valueOf";id=Id_valueOf; break L; - case 8: X="toString";id=Id_toString; break L; - case 11: X="constructor";id=Id_constructor; break L; - case 13: X="isPrototypeOf";id=Id_isPrototypeOf; break L; - case 14: c=s.charAt(0); - if (c=='h') { X="hasOwnProperty";id=Id_hasOwnProperty; } - else if (c=='t') { X="toLocaleString";id=Id_toLocaleString; } - break L; - case 20: X="propertyIsEnumerable";id=Id_propertyIsEnumerable; break L; - } - if (X!=null && X!=s && !X.equals(s)) id = 0; - } -// #/generated# - return id; - } - - private static final int - Id_constructor = 1, - Id_toString = 2, - Id_toLocaleString = 3, - Id_valueOf = 4, - Id_hasOwnProperty = 5, - Id_propertyIsEnumerable = 6, - Id_isPrototypeOf = 7, - MAX_PROTOTYPE_ID = 7; - -// #/string_id_map# - - private boolean prototypeFlag; -} diff --git a/src/org/mozilla/javascript/NativeScript.java b/src/org/mozilla/javascript/NativeScript.java deleted file mode 100644 index cb6d855..0000000 --- a/src/org/mozilla/javascript/NativeScript.java +++ /dev/null @@ -1,286 +0,0 @@ -/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * Roger Lawrence - * Mike McCabe - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - -package org.mozilla.javascript; - -import java.io.StringReader; -import java.io.IOException; - -/** - * The JavaScript Script object. - * - * Note that the C version of the engine uses XDR as the format used - * by freeze and thaw. Since this depends on the internal format of - * structures in the C runtime, we cannot duplicate it. - * - * Since we cannot replace 'this' as a result of the compile method, - * this class has a dual nature. Generated scripts will have a null - * 'script' field and will override 'exec' and 'call'. Scripts created - * using the JavaScript constructor will forward requests to the - * nonnull 'script' field. - * - * @since 1.3 - * @author Norris Boyd - */ - -public class NativeScript extends NativeFunction implements Script { - - public static void init(Context cx, Scriptable scope, boolean sealed) { - NativeScript obj = new NativeScript(); - obj.scopeInit(cx, scope, sealed); - } - - public NativeScript() { - } - - private void scopeInit(Context cx, Scriptable scope, boolean sealed) { - // prototypeIdShift != 0 serves as indicator of prototype instance - // and as id offset to take into account ids present in each instance - // of the base class NativeFunction. - // Not to depend on the assumption NativeFunction.maxInstanceId() != 0, - // 1 is added super.maxInstanceId() to make sure that - // prototypeIdShift != 0 in the NativeScript prototype. - // In a similar way the following methods use - // methodId - prototypeIdShift + 1, not methodId - prototypeIdShift - // to unshift prototype id to [1 .. MAX_PROTOTYPE_ID] interval - prototypeIdShift = super.maxInstanceId() + 1; - addAsPrototype(MAX_PROTOTYPE_ID + prototypeIdShift - 1, - cx, scope, sealed); - } - - /** - * Returns the name of this JavaScript class, "Script". - */ - public String getClassName() { - return "Script"; - } - - /** - * Initialize script. - * - * Does nothing here, but scripts will override with code - * to initialize contained functions, regexp literals, etc. - */ - public void initScript(Scriptable scope) { - } - - public int methodArity(int methodId) { - if (prototypeIdShift != 0) { - switch (methodId - prototypeIdShift + 1) { - case Id_constructor: return 1; - case Id_toString: return 0; - case Id_exec: return 0; - case Id_compile: return 1; - } - } - return super.methodArity(methodId); - } - - public Object execMethod(int methodId, IdFunction f, Context cx, - Scriptable scope, Scriptable thisObj, - Object[] args) - throws JavaScriptException - { - if (prototypeIdShift != 0) { - switch (methodId - prototypeIdShift + 1) { - case Id_constructor: - return jsConstructor(cx, scope, args); - - case Id_toString: - return realThis(thisObj, f, true). - jsFunction_toString(cx, args); - - case Id_exec: - return realThis(thisObj, f, true).jsFunction_exec(); - - case Id_compile: - return realThis(thisObj, f, false). - jsFunction_compile(ScriptRuntime.toString(args, 0)); - } - } - - return super.execMethod(methodId, f, cx, scope, thisObj, args); - } - - private NativeScript realThis(Scriptable thisObj, IdFunction f, - boolean readOnly) - { - while (!(thisObj instanceof NativeScript)) { - thisObj = nextInstanceCheck(thisObj, f, readOnly); - } - return (NativeScript)thisObj; - } - - /** - * The Java method defining the JavaScript Script constructor. - * - */ - private static Object jsConstructor(Context cx, Scriptable scope, - Object[] args) - { - String source = args.length == 0 - ? "" - : ScriptRuntime.toString(args[0]); - return compile(scope, source); - } - - public static Script compile(Scriptable scope, String source) { - Context cx = Context.getContext(); - StringReader reader = new StringReader(source); - try { - int[] linep = { 0 }; - String filename = Context.getSourcePositionFromStack(linep); - if (filename == null) { - filename = "