зеркало из https://github.com/mozilla/gecko-dev.git
Remove deprecated FlattenedObject.
Patch from Igor: The 2 attached patches allow to avoid wrapping of array indexes to Double object when Interpreter knows that the index is an integer number. It speed up array benchmark by 5-10% array_access.diff adds to ScriptRuntime getStrIdElem and setStrIdElem to get/set properties which known to be strings plus it modifies NativeArray to use these methods. interpreter.diff contains the Interpreter modifications to call get/setElem for integer or string properties when the property type is known for sure.
This commit is contained in:
Родитель
1bc0630719
Коммит
250051383e
|
@ -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.
|
|
||||||
* <p>
|
|
||||||
* This class has been deprecated in favor of the static methods
|
|
||||||
* <code>getProperty</code>, <code>putProperty</code>, and
|
|
||||||
* <code>deleteProperty</code> 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
|
|
||||||
* <code>Scriptable.has()</code>.
|
|
||||||
* 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.
|
|
||||||
* <p>
|
|
||||||
* This is a more convenient (and less efficient) form than
|
|
||||||
* <code>Scriptable.get()</code>. It corresponds exactly to the
|
|
||||||
* expression <code>obj[id]</code> in JavaScript. This method
|
|
||||||
* will traverse the prototype chain of an object to find the
|
|
||||||
* property.<p>
|
|
||||||
*
|
|
||||||
* 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 <code>obj[id] = val</code> in JavaScript.<p>
|
|
||||||
*
|
|
||||||
* @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 <code>delete</code>
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* <p>This method will walk the prototype chain and collect the
|
|
||||||
* ids of all objects in the prototype chain.<p>
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
* <p>
|
|
||||||
* For example, for a FlattenedObject <code>obj</code>,
|
|
||||||
* and a Java array <code>a</code> consisting of a single string
|
|
||||||
* <code>"hi"</code>, the call <pre>
|
|
||||||
* obj.callMethod("m", a)</pre>
|
|
||||||
* is equivalent to the JavaScript code <code>obj.m("hi")</code>.<p>
|
|
||||||
*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1139,7 +1139,7 @@ public class Interpreter extends LabelTable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getShort(byte[] iCode, int pc) {
|
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) {
|
private static int getInt(byte[] iCode, int pc) {
|
||||||
|
@ -1821,25 +1821,12 @@ public class Interpreter extends LabelTable {
|
||||||
= ScriptRuntime.setProp(lhs, name, rhs, scope);
|
= ScriptRuntime.setProp(lhs, name, rhs, scope);
|
||||||
break;
|
break;
|
||||||
case TokenStream.GETELEM :
|
case TokenStream.GETELEM :
|
||||||
id = stack[stackTop];
|
do_getElem(stack, sDbl, stackTop, scope);
|
||||||
if (id == DBL_MRK) id = doubleWrap(sDbl[stackTop]);
|
|
||||||
--stackTop;
|
--stackTop;
|
||||||
lhs = stack[stackTop];
|
|
||||||
if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
|
|
||||||
stack[stackTop]
|
|
||||||
= ScriptRuntime.getElem(lhs, id, scope);
|
|
||||||
break;
|
break;
|
||||||
case TokenStream.SETELEM :
|
case TokenStream.SETELEM :
|
||||||
rhs = stack[stackTop];
|
do_setElem(stack, sDbl, stackTop, scope);
|
||||||
if (rhs == DBL_MRK) rhs = doubleWrap(sDbl[stackTop]);
|
stackTop -= 2;
|
||||||
--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;
|
break;
|
||||||
case TokenStream.PROPINC :
|
case TokenStream.PROPINC :
|
||||||
name = (String)stack[stackTop];
|
name = (String)stack[stackTop];
|
||||||
|
@ -2376,8 +2363,6 @@ public class Interpreter extends LabelTable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static boolean do_eq(Object[] stack, double[] stackDbl,
|
private static boolean do_eq(Object[] stack, double[] stackDbl,
|
||||||
int stackTop)
|
int stackTop)
|
||||||
{
|
{
|
||||||
|
@ -2460,6 +2445,64 @@ public class Interpreter extends LabelTable {
|
||||||
return result;
|
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,
|
private static Object[] getArgsArray(Object[] stack, double[] sDbl,
|
||||||
int stackTop, int count)
|
int stackTop, int count)
|
||||||
{
|
{
|
||||||
|
|
|
@ -419,7 +419,7 @@ public class NativeArray extends IdScriptable {
|
||||||
private static Object getElem(Scriptable target, long index) {
|
private static Object getElem(Scriptable target, long index) {
|
||||||
if (index > Integer.MAX_VALUE) {
|
if (index > Integer.MAX_VALUE) {
|
||||||
String id = Long.toString(index);
|
String id = Long.toString(index);
|
||||||
return ScriptRuntime.getElem(target, id, target);
|
return ScriptRuntime.getStrIdElem(target, id);
|
||||||
} else {
|
} else {
|
||||||
return ScriptRuntime.getElem(target, (int)index);
|
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) {
|
private static void setElem(Scriptable target, long index, Object value) {
|
||||||
if (index > Integer.MAX_VALUE) {
|
if (index > Integer.MAX_VALUE) {
|
||||||
String id = Long.toString(index);
|
String id = Long.toString(index);
|
||||||
ScriptRuntime.setElem(target, id, value, target);
|
ScriptRuntime.setStrIdElem(target, id, value, target);
|
||||||
} else {
|
} else {
|
||||||
ScriptRuntime.setElem(target, (int)index, value);
|
ScriptRuntime.setElem(target, (int)index, value);
|
||||||
}
|
}
|
||||||
|
@ -482,8 +482,7 @@ public class NativeArray extends IdScriptable {
|
||||||
|
|
||||||
if (!iterating) {
|
if (!iterating) {
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
if (i > 0)
|
if (i > 0) result.append(separator);
|
||||||
result.append(separator);
|
|
||||||
Object elem = getElem(thisObj, i);
|
Object elem = getElem(thisObj, i);
|
||||||
if (elem == null || elem == Undefined.instance) {
|
if (elem == null || elem == Undefined.instance) {
|
||||||
haslast = false;
|
haslast = false;
|
||||||
|
@ -492,13 +491,13 @@ public class NativeArray extends IdScriptable {
|
||||||
haslast = true;
|
haslast = true;
|
||||||
|
|
||||||
if (elem instanceof String) {
|
if (elem instanceof String) {
|
||||||
|
String s = (String)elem;
|
||||||
if (toSource) {
|
if (toSource) {
|
||||||
result.append('\"');
|
result.append('\"');
|
||||||
result.append(ScriptRuntime.escapeString
|
result.append(ScriptRuntime.escapeString(s));
|
||||||
(ScriptRuntime.toString(elem)));
|
|
||||||
result.append('\"');
|
result.append('\"');
|
||||||
} else {
|
} else {
|
||||||
result.append(ScriptRuntime.toString(elem));
|
result.append(s);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* wrap changes to cx.iterating in a try/finally
|
/* wrap changes to cx.iterating in a try/finally
|
||||||
|
|
|
@ -932,7 +932,7 @@ public class ScriptRuntime {
|
||||||
index = (int) d;
|
index = (int) d;
|
||||||
s = ((double) index) == d ? null : toString(id);
|
s = ((double) index) == d ? null : toString(id);
|
||||||
} else {
|
} else {
|
||||||
s = toString(id);
|
s = (id instanceof String) ? (String)id : toString(id);
|
||||||
long indexTest = indexFromString(s);
|
long indexTest = indexFromString(s);
|
||||||
if (indexTest >= 0) {
|
if (indexTest >= 0) {
|
||||||
index = (int)indexTest;
|
index = (int)indexTest;
|
||||||
|
@ -941,30 +941,16 @@ public class ScriptRuntime {
|
||||||
index = 0;
|
index = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Scriptable start = obj instanceof Scriptable
|
Scriptable start = obj instanceof Scriptable
|
||||||
? (Scriptable) obj
|
? (Scriptable) obj
|
||||||
: toObject(scope, obj);
|
: toObject(scope, obj);
|
||||||
Scriptable m = start;
|
|
||||||
if (s != null) {
|
if (s != null) {
|
||||||
if (s.equals("__proto__"))
|
return getStrIdElem(start, s);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
while (m != null) {
|
else {
|
||||||
Object result = m.get(index, start);
|
return getElem(start, index);
|
||||||
if (result != Scriptable.NOT_FOUND)
|
|
||||||
return result;
|
|
||||||
m = m.getPrototype();
|
|
||||||
}
|
}
|
||||||
return Undefined.instance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -972,8 +958,7 @@ public class ScriptRuntime {
|
||||||
* A cheaper and less general version of the above for well-known argument
|
* A cheaper and less general version of the above for well-known argument
|
||||||
* types.
|
* types.
|
||||||
*/
|
*/
|
||||||
public static Object getElem(Scriptable obj, int index)
|
public static Object getElem(Scriptable obj, int index) {
|
||||||
{
|
|
||||||
Scriptable m = obj;
|
Scriptable m = obj;
|
||||||
while (m != null) {
|
while (m != null) {
|
||||||
Object result = m.get(index, obj);
|
Object result = m.get(index, obj);
|
||||||
|
@ -984,6 +969,24 @@ public class ScriptRuntime {
|
||||||
return Undefined.instance;
|
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,
|
public static Object setElem(Object obj, Object id, Object value,
|
||||||
Scriptable scope)
|
Scriptable scope)
|
||||||
{
|
{
|
||||||
|
@ -994,7 +997,7 @@ public class ScriptRuntime {
|
||||||
index = (int) d;
|
index = (int) d;
|
||||||
s = ((double) index) == d ? null : toString(id);
|
s = ((double) index) == d ? null : toString(id);
|
||||||
} else {
|
} else {
|
||||||
s = toString(id);
|
s = (id instanceof String) ? (String)id : toString(id);
|
||||||
long indexTest = indexFromString(s);
|
long indexTest = indexFromString(s);
|
||||||
if (indexTest >= 0) {
|
if (indexTest >= 0) {
|
||||||
index = (int)indexTest;
|
index = (int)indexTest;
|
||||||
|
@ -1007,41 +1010,19 @@ public class ScriptRuntime {
|
||||||
Scriptable start = obj instanceof Scriptable
|
Scriptable start = obj instanceof Scriptable
|
||||||
? (Scriptable) obj
|
? (Scriptable) obj
|
||||||
: toObject(scope, obj);
|
: toObject(scope, obj);
|
||||||
Scriptable m = start;
|
|
||||||
if (s != null) {
|
if (s != null) {
|
||||||
if (s.equals("__proto__"))
|
return setStrIdElem(start, s, value, scope);
|
||||||
return setProto(obj, value, scope);
|
}
|
||||||
if (s.equals("__parent__"))
|
else {
|
||||||
return setParent(obj, value, scope);
|
return setElem(start, index, value);
|
||||||
|
}
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A cheaper and less general version of the above for well-known argument
|
* A cheaper and less general version of the above for well-known argument
|
||||||
* types.
|
* types.
|
||||||
*/
|
*/
|
||||||
public static Object setElem(Scriptable obj, int index, Object value)
|
public static Object setElem(Scriptable obj, int index, Object value) {
|
||||||
{
|
|
||||||
Scriptable m = obj;
|
Scriptable m = obj;
|
||||||
do {
|
do {
|
||||||
if (m.has(index, obj)) {
|
if (m.has(index, obj)) {
|
||||||
|
@ -1054,6 +1035,28 @@ public class ScriptRuntime {
|
||||||
return value;
|
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
|
* The delete operator
|
||||||
*
|
*
|
||||||
|
|
Загрузка…
Ссылка в новой задаче