diff --git a/js/rhino/src/org/mozilla/javascript/FlattenedObject.java b/js/rhino/src/org/mozilla/javascript/FlattenedObject.java deleted file mode 100644 index 191132f76cd9..000000000000 --- a/js/rhino/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/js/rhino/src/org/mozilla/javascript/Interpreter.java b/js/rhino/src/org/mozilla/javascript/Interpreter.java index d47c31ef069a..e3c6b64e8bcc 100644 --- a/js/rhino/src/org/mozilla/javascript/Interpreter.java +++ b/js/rhino/src/org/mozilla/javascript/Interpreter.java @@ -1139,7 +1139,7 @@ public class Interpreter extends LabelTable { } private static int getShort(byte[] iCode, int pc) { - return (iCode[pc] << 8) + (iCode[pc + 1] & 0xFF); + return (iCode[pc] << 8) | (iCode[pc + 1] & 0xFF); } private static int getInt(byte[] iCode, int pc) { @@ -1821,25 +1821,12 @@ public class Interpreter extends LabelTable { = ScriptRuntime.setProp(lhs, name, rhs, scope); break; case TokenStream.GETELEM : - id = stack[stackTop]; - if (id == DBL_MRK) id = doubleWrap(sDbl[stackTop]); + do_getElem(stack, sDbl, stackTop, scope); --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); + do_setElem(stack, sDbl, stackTop, scope); + stackTop -= 2; break; case TokenStream.PROPINC : name = (String)stack[stackTop]; @@ -2376,8 +2363,6 @@ public class Interpreter extends LabelTable { } } - - private static boolean do_eq(Object[] stack, double[] stackDbl, int stackTop) { @@ -2460,6 +2445,64 @@ public class Interpreter extends LabelTable { return result; } + private static void do_getElem(Object[] stack, double[] stackDbl, + int stackTop, Scriptable scope) + { + Object lhs = stack[stackTop - 1]; + if (lhs == DBL_MRK) lhs = doubleWrap(stackDbl[stackTop - 1]); + + Object result; + Object id = stack[stackTop]; + if (id != DBL_MRK) { + result = ScriptRuntime.getElem(lhs, id, scope); + } + else { + Scriptable obj = (lhs instanceof Scriptable) + ? (Scriptable)lhs + : ScriptRuntime.toObject(scope, lhs); + double val = stackDbl[stackTop]; + int index = (int)val; + if (index == val) { + result = ScriptRuntime.getElem(obj, index); + } + else { + String s = ScriptRuntime.toString(val); + result = ScriptRuntime.getStrIdElem(obj, s); + } + } + stack[stackTop - 1] = result; + } + + private static void do_setElem(Object[] stack, double[] stackDbl, + int stackTop, Scriptable scope) + { + Object rhs = stack[stackTop]; + if (rhs == DBL_MRK) rhs = doubleWrap(stackDbl[stackTop]); + Object lhs = stack[stackTop - 2]; + if (lhs == DBL_MRK) lhs = doubleWrap(stackDbl[stackTop - 2]); + + Object result; + Object id = stack[stackTop - 1]; + if (id != DBL_MRK) { + result = ScriptRuntime.setElem(lhs, id, rhs, scope); + } + else { + Scriptable obj = (lhs instanceof Scriptable) + ? (Scriptable)lhs + : ScriptRuntime.toObject(scope, lhs); + double val = stackDbl[stackTop - 1]; + int index = (int)val; + if (index == val) { + result = ScriptRuntime.setElem(obj, index, rhs); + } + else { + String s = ScriptRuntime.toString(val); + result = ScriptRuntime.setStrIdElem(obj, s, rhs, scope); + } + } + stack[stackTop - 2] = result; + } + private static Object[] getArgsArray(Object[] stack, double[] sDbl, int stackTop, int count) { diff --git a/js/rhino/src/org/mozilla/javascript/NativeArray.java b/js/rhino/src/org/mozilla/javascript/NativeArray.java index a1e454c0631e..36943c9a954a 100644 --- a/js/rhino/src/org/mozilla/javascript/NativeArray.java +++ b/js/rhino/src/org/mozilla/javascript/NativeArray.java @@ -419,7 +419,7 @@ public class NativeArray extends IdScriptable { private static Object getElem(Scriptable target, long index) { if (index > Integer.MAX_VALUE) { String id = Long.toString(index); - return ScriptRuntime.getElem(target, id, target); + return ScriptRuntime.getStrIdElem(target, id); } else { return ScriptRuntime.getElem(target, (int)index); } @@ -428,7 +428,7 @@ public class NativeArray extends IdScriptable { 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); + ScriptRuntime.setStrIdElem(target, id, value, target); } else { ScriptRuntime.setElem(target, (int)index, value); } @@ -482,8 +482,7 @@ public class NativeArray extends IdScriptable { if (!iterating) { for (i = 0; i < length; i++) { - if (i > 0) - result.append(separator); + if (i > 0) result.append(separator); Object elem = getElem(thisObj, i); if (elem == null || elem == Undefined.instance) { haslast = false; @@ -492,13 +491,13 @@ public class NativeArray extends IdScriptable { haslast = true; if (elem instanceof String) { + String s = (String)elem; if (toSource) { result.append('\"'); - result.append(ScriptRuntime.escapeString - (ScriptRuntime.toString(elem))); + result.append(ScriptRuntime.escapeString(s)); result.append('\"'); } else { - result.append(ScriptRuntime.toString(elem)); + result.append(s); } } else { /* wrap changes to cx.iterating in a try/finally diff --git a/js/rhino/src/org/mozilla/javascript/ScriptRuntime.java b/js/rhino/src/org/mozilla/javascript/ScriptRuntime.java index 38f3db2c71cb..9f009fe4a0e9 100644 --- a/js/rhino/src/org/mozilla/javascript/ScriptRuntime.java +++ b/js/rhino/src/org/mozilla/javascript/ScriptRuntime.java @@ -932,7 +932,7 @@ public class ScriptRuntime { index = (int) d; s = ((double) index) == d ? null : toString(id); } else { - s = toString(id); + s = (id instanceof String) ? (String)id : toString(id); long indexTest = indexFromString(s); if (indexTest >= 0) { index = (int)indexTest; @@ -941,30 +941,16 @@ public class ScriptRuntime { index = 0; } } + Scriptable start = obj instanceof Scriptable ? (Scriptable) obj : toObject(scope, obj); - Scriptable m = start; if (s != null) { - if (s.equals("__proto__")) - return start.getPrototype(); - if (s.equals("__parent__")) - return start.getParentScope(); - while (m != null) { - Object result = m.get(s, start); - if (result != Scriptable.NOT_FOUND) - return result; - m = m.getPrototype(); - } - return Undefined.instance; + return getStrIdElem(start, s); } - while (m != null) { - Object result = m.get(index, start); - if (result != Scriptable.NOT_FOUND) - return result; - m = m.getPrototype(); + else { + return getElem(start, index); } - return Undefined.instance; } @@ -972,8 +958,7 @@ public class ScriptRuntime { * A cheaper and less general version of the above for well-known argument * types. */ - public static Object getElem(Scriptable obj, int index) - { + public static Object getElem(Scriptable obj, int index) { Scriptable m = obj; while (m != null) { Object result = m.get(index, obj); @@ -984,6 +969,24 @@ public class ScriptRuntime { return Undefined.instance; } + static Object getStrIdElem(Scriptable obj, String id) { + int l = id.length(); + if (l == 9) { + if (id.equals("__proto__")) { return obj.getPrototype(); } + } + else if (l == 10) { + if (id.equals("__parent__")) { return obj.getParentScope(); } + } + Scriptable m = obj; + while (m != null) { + Object result = m.get(id, obj); + if (result != Scriptable.NOT_FOUND) + return result; + m = m.getPrototype(); + } + return Undefined.instance; + } + public static Object setElem(Object obj, Object id, Object value, Scriptable scope) { @@ -994,7 +997,7 @@ public class ScriptRuntime { index = (int) d; s = ((double) index) == d ? null : toString(id); } else { - s = toString(id); + s = (id instanceof String) ? (String)id : toString(id); long indexTest = indexFromString(s); if (indexTest >= 0) { index = (int)indexTest; @@ -1007,41 +1010,19 @@ public class ScriptRuntime { Scriptable start = obj instanceof Scriptable ? (Scriptable) obj : toObject(scope, obj); - Scriptable m = start; if (s != null) { - if (s.equals("__proto__")) - return setProto(obj, value, scope); - if (s.equals("__parent__")) - return setParent(obj, value, scope); - - do { - if (m.has(s, start)) { - m.put(s, start, value); - return value; - } - m = m.getPrototype(); - } while (m != null); - start.put(s, start, value); - return value; - } - - do { - if (m.has(index, start)) { - m.put(index, start, value); - return value; - } - m = m.getPrototype(); - } while (m != null); - start.put(index, start, value); - return value; + return setStrIdElem(start, s, value, scope); + } + else { + return setElem(start, index, value); + } } /* * A cheaper and less general version of the above for well-known argument * types. */ - public static Object setElem(Scriptable obj, int index, Object value) - { + public static Object setElem(Scriptable obj, int index, Object value) { Scriptable m = obj; do { if (m.has(index, obj)) { @@ -1054,6 +1035,28 @@ public class ScriptRuntime { return value; } + static Object setStrIdElem(Scriptable obj, String id, Object value, + Scriptable scope) + { + int l = id.length(); + if (l == 9) { + if (id.equals("__proto__")) return setProto(obj, value, scope); + } + else if (l == 10) { + if (id.equals("__parent__")) return setParent(obj, value, scope); + } + Scriptable m = obj; + do { + if (m.has(id, obj)) { + m.put(id, obj, value); + return value; + } + m = m.getPrototype(); + } while (m != null); + obj.put(id, obj, value); + return value; + } + /** * The delete operator *