зеркало из 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) {
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
Загрузка…
Ссылка в новой задаче