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 *