This commit is contained in:
nboyd%atg.com 2000-07-07 14:41:35 +00:00
Родитель d87ffe8750
Коммит 0a9b985a17
17 изменённых файлов: 402 добавлений и 185 удалений

Просмотреть файл

@ -72,33 +72,28 @@ public class Control {
// ignore
}
FlattenedObject global = new FlattenedObject(scope);
FlattenedObject f = (FlattenedObject) global.getProperty("obj");
Scriptable obj = (Scriptable) scope.get("obj", scope);
// Should print "obj == result" (Since the result of an assignment
// expression is the value that was assigned)
System.out.println("obj " + (f.getObject() == result ? "==" : "!=") +
System.out.println("obj " + (obj == result ? "==" : "!=") +
" result");
// Should print "f.a == 1"
System.out.println("f.a == " + f.getProperty("a"));
// Should print "obj.a == 1"
System.out.println("obj.a == " + obj.get("a", obj));
FlattenedObject b = (FlattenedObject) f.getProperty("b");
Scriptable b = (Scriptable) obj.get("b", obj);
// Should print "f.b[0] == x"
System.out.println("f.b[0] == " + b.getProperty(new Integer(0)));
// Should print "obj.b[0] == x"
System.out.println("obj.b[0] == " + b.get(0, b));
// Should print "f.b[1] == y"
System.out.println("f.b[1] == " + b.getProperty(new Integer(1)));
// Should print "obj.b[1] == y"
System.out.println("obj.b[1] == " + b.get(1, b));
try {
// Should print {a:1, b:["x", "y"]}
System.out.println(f.callMethod("toString", new Object[0]));
} catch (PropertyException e) {
// ignore
} catch (NotAFunctionException e) {
// ignore
Function fn = (Function) ScriptableObject.getProperty(obj, "toString");
System.out.println(fn.call(cx, scope, obj, new Object[0]));
} catch (JavaScriptException e) {
// ignore
}

Просмотреть файл

@ -34,7 +34,7 @@
*/
package org.mozilla.javascript;
// API Class
// API class
import java.io.*;

Просмотреть файл

@ -34,8 +34,6 @@
* file under either the NPL or the GPL.
*/
// API class
package org.mozilla.javascript;
import java.util.Hashtable;
@ -44,19 +42,13 @@ import java.util.Enumeration;
/**
* Manipulate a Scriptable object as if its prototype chain were flattened.
* <p>
* Compared to the Scriptable interface, FlattenedObject provides a view of
* Scriptable objects that is easier to use and more closely matches a script
* writer's view of a JavaScript object. <p>
* This class has been deprecated in favor of the static methods
* <code>getProperty</code>, <code>putProperty</code>, and
* <code>deleteProperty</code>. Those methods provide the
* same functionality without the confusing and inefficient need to construct
* a new object instance.
*
* A FlattenedObject is "flattened" in the sense that multiple objects in a
* prototype chain appear to have their properties all appear in the
* FlattenedObject. <p>
*
* Another convenience provided by Flattened object is the ability to access
* properties by a single java.lang.Object id. This id is then converted into
* a String or an int before methods of the Scriptable object are called.
*
* @see org.mozilla.javascript.Scriptable
* @see org.mozilla.javascript.ScriptableObject
*
* @author Norris Boyd
*/
@ -67,6 +59,7 @@ 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;
@ -74,6 +67,7 @@ public class FlattenedObject {
/**
* Get the associated Scriptable object.
* @deprecated
*/
public Scriptable getObject() {
return obj;
@ -93,6 +87,7 @@ public class FlattenedObject {
* @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);
@ -119,6 +114,7 @@ public class FlattenedObject {
* @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);
@ -149,6 +145,7 @@ public class FlattenedObject {
* 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);
@ -179,6 +176,7 @@ public class FlattenedObject {
* 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);
@ -208,6 +206,7 @@ public class FlattenedObject {
* array will be unique respective to equals().)
*
* @see org.mozilla.javascript.Scriptable#getIds
* @deprecated
*/
public Object[] getIds() {
Hashtable h = new Hashtable(11);
@ -241,6 +240,7 @@ public class FlattenedObject {
* @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,
@ -263,6 +263,7 @@ public class FlattenedObject {
* @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,
@ -297,6 +298,7 @@ public class FlattenedObject {
* @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,

Просмотреть файл

@ -214,7 +214,8 @@ public class JavaAdapter extends ScriptableObject {
Scriptable p = (Scriptable) f;
if (!(p instanceof Function))
continue;
length = (int) Context.toNumber(getProperty(p, "length"));
length = (int) Context.toNumber(
ScriptableObject.getProperty(p, "length"));
} else if (f instanceof FunctionNode) {
length = ((FunctionNode) f).getVariableTable().getParameterCount();
} else {
@ -771,24 +772,6 @@ public class JavaAdapter extends ScriptableObject {
return sb;
}
/**
* Looks up a property of a scriptable object, searching the entire prototype
* chain. Works like FlattenedObject.getProperty() without the overhead.
*/
private static Object getProperty(Scriptable obj, String id) {
Scriptable m = obj;
Object result = null;
for(;;) {
result = m.get(id, obj);
if (result != Scriptable.NOT_FOUND)
break;
m = m.getPrototype();
if (m == null)
return Undefined.instance;
}
return result;
}
static final class MyClassLoader extends ClassLoader {
public Class defineClass(String name, byte data[]) {
return super.defineClass(name, data, 0, data.length);

Просмотреть файл

@ -115,13 +115,9 @@ public class NativeFunction extends ScriptableObject implements Function {
*
*/
public boolean hasInstance(Scriptable instance) {
FlattenedObject flat = new FlattenedObject(this);
Object protoProp = flat.getProperty("prototype");
if (protoProp instanceof FlattenedObject) {
protoProp = ((FlattenedObject)protoProp).getObject();
if (protoProp != Undefined.instance)
return ScriptRuntime.jsDelegatesTo(instance,
(Scriptable)protoProp);
Object protoProp = ScriptableObject.getProperty(this, "prototype");
if (protoProp instanceof Scriptable && protoProp != Undefined.instance) {
return ScriptRuntime.jsDelegatesTo(instance, (Scriptable)protoProp);
}
Object[] args = { names[0] };
String m = ScriptRuntime.getMessage("msg.instanceof.bad.prototype",

Просмотреть файл

@ -183,8 +183,6 @@ public class NativeJavaObject implements Scriptable, Wrapper {
// Just abandon conversion from JSObject
}
}
if (cls == ScriptRuntime.ClassClass)
return NativeJavaClass.wrap(scope, (Class) obj);
return new NativeJavaObject(scope, obj, staticType);
}

Просмотреть файл

@ -1059,10 +1059,11 @@ public class ScriptRuntime {
* method doesn't return a value.
*/
public static Object delete(Object obj, Object id) {
if (!(obj instanceof Scriptable))
return Boolean.TRUE;
FlattenedObject f = new FlattenedObject((Scriptable) obj);
return f.deleteProperty(id) ? Boolean.TRUE : Boolean.FALSE;
String s = getStringId(id);
boolean result = s != null
? ScriptableObject.deleteProperty((Scriptable) obj, s)
: ScriptableObject.deleteProperty((Scriptable) obj, getIntId(id));
return result ? Boolean.TRUE : Boolean.FALSE;
}
/**
@ -1730,9 +1731,11 @@ public class ScriptRuntime {
Context.getContext(), "TypeError",
ScriptRuntime.getMessage("msg.instanceof.not.object", null), a);
}
// OPT do it here rather than making a new FlattenedObject.
FlattenedObject rhs = new FlattenedObject((Scriptable)b);
return rhs.hasProperty(a);
String s = getStringId(a);
Object result = s != null
? ScriptableObject.getProperty((Scriptable) b, s)
: ScriptableObject.getProperty((Scriptable) b, getIntId(a));
return result != Scriptable.NOT_FOUND;
}
public static Boolean cmp_LTB(Object val1, Object val2) {

Просмотреть файл

@ -45,12 +45,12 @@ package org.mozilla.javascript;
* Host system implementors may find it easier to extend the ScriptableObject
* class rather than implementing Scriptable when writing host objects.
* <p>
* There are many convenience methods defined in FlattenedObject that make
* accessing objects easier.
* There are many static methods defined in ScriptableObject that perform
* the multiple calls to the Scriptable interface needed in order to
* manipulate properties in prototype chains.
* <p>
*
* @see org.mozilla.javascript.ScriptableObject
* @see org.mozilla.javascript.FlattenedObject
* @author Norris Boyd
* @author Nick Thompson
* @author Brendan Eich
@ -137,7 +137,7 @@ public interface Scriptable {
* @param start the object in which the lookup began
* @return true if and only if the named property is found in the object
* @see org.mozilla.javascript.Scriptable#get
* @see org.mozilla.javascript.FlattenedObject#hasProperty
* @see org.mozilla.javascript.ScriptableObject#getProperty
*/
public boolean has(String name, Scriptable start);
@ -153,7 +153,7 @@ public interface Scriptable {
* @param start the object in which the lookup began
* @return true if and only if the indexed property is found in the object
* @see org.mozilla.javascript.Scriptable#get
* @see org.mozilla.javascript.FlattenedObject#hasProperty
* @see org.mozilla.javascript.ScriptableObject#getProperty
*/
public boolean has(int index, Scriptable start);
@ -167,8 +167,8 @@ public interface Scriptable {
* <code>get</code>. A class that implements this method may choose
* to ignore calls to set certain properties, in which case those
* properties are effectively read-only.<p>
* For a more convenient (and less efficient) form of this method,
* see <code>putProperty</code> in FlattenedObject. <p>
* For properties defined in a prototype chain,
* use <code>putProperty</code> in ScriptableObject. <p>
* Note that if a property <i>a</i> is defined in the prototype <i>p</i>
* of an object <i>o</i>, then evaluating <code>o.a = 23</code> will cause
* <code>set</code> to be called on the prototype <i>p</i> with
@ -198,7 +198,7 @@ public interface Scriptable {
* @param value value to set the property to
* @see org.mozilla.javascript.Scriptable#has
* @see org.mozilla.javascript.Scriptable#get
* @see org.mozilla.javascript.FlattenedObject#putProperty
* @see org.mozilla.javascript.ScriptableObject#putProperty
*/
public void put(String name, Scriptable start, Object value);
@ -217,7 +217,7 @@ public interface Scriptable {
* @see org.mozilla.javascript.Scriptable#has
* @see org.mozilla.javascript.Scriptable#get
* @see org.mozilla.javascript.Scriptable#put(String,Scriptable,Object)
* @see org.mozilla.javascript.FlattenedObject#putProperty
* @see org.mozilla.javascript.ScriptaleObject#putProperty
*/
public void put(int index, Scriptable start, Object value);
@ -235,11 +235,11 @@ public interface Scriptable {
* The property is specified by a String name
* as defined for <code>get</code>.
* <p>
* For a more convenient form of this method,
* see deleteProperty in FlattenedObject.
* To delete properties defined in a prototype chain,
* see deleteProperty in ScriptableObject.
* @param name the identifier for the property
* @see org.mozilla.javascript.Scriptable#get
* @see org.mozilla.javascript.FlattenedObject#deleteProperty
* @see org.mozilla.javascript.ScriptableObject#deleteProperty
*/
public void delete(String name);
@ -249,15 +249,15 @@ public interface Scriptable {
* The property is specified by an integral index
* as defined for <code>get</code>.
* <p>
* For a more convenient form of this method,
* see deleteProperty in FlattenedObject.
* To delete properties defined in a prototype chain,
* see deleteProperty in ScriptableObject.
*
* Identical to <code>delete(String)</code> except that
* an integral index is used to select the property.
*
* @param index the numeric index for the property
* @see org.mozilla.javascript.Scriptable#get
* @see org.mozilla.javascript.FlattenedObject#deleteProperty
* @see org.mozilla.javascript.ScriptableObject#deleteProperty
*/
public void delete(int index);

Просмотреть файл

@ -524,17 +524,17 @@ public abstract class ScriptableObject implements Scriptable {
*/
public Object getDefaultValue(Class typeHint) {
Object val;
FlattenedObject f = new FlattenedObject(this);
Context cx = null;
try {
for (int i=0; i < 2; i++) {
if (typeHint == ScriptRuntime.StringClass ? i == 0 : i == 1) {
Function fun = getFunctionProperty(f, "toString");
if (fun == null)
Object v = getProperty(this, "toString");
if (!(v instanceof Function))
continue;
Function fun = (Function) v;
if (cx == null)
cx = Context.getContext();
val = fun.call(cx, fun.getParentScope(), f.getObject(),
val = fun.call(cx, fun.getParentScope(), this,
ScriptRuntime.emptyArgs);
} else {
String hint;
@ -566,14 +566,14 @@ public abstract class ScriptableObject implements Scriptable {
throw Context.reportRuntimeError(
Context.getMessage("msg.invalid.type", args));
}
Function fun = getFunctionProperty(f, "valueOf");
if (fun == null)
Object v = getProperty(this, "valueOf");
if (!(v instanceof Function))
continue;
Function fun = (Function) v;
Object[] args = { hint };
if (cx == null)
cx = Context.getContext();
val = fun.call(cx, fun.getParentScope(), f.getObject(),
args);
val = fun.call(cx, fun.getParentScope(), this, args);
}
if (val != null && (val == Undefined.instance ||
!(val instanceof Scriptable) ||
@ -1327,6 +1327,145 @@ public abstract class ScriptableObject implements Scriptable {
return count == -1;
}
/**
* Gets a named property from an object or any object in its prototype chain.
* <p>
* Searches the prototype chain for a property named <code>name</code>.
* <p>
* @param obj a JavaScript object
* @param name a property name
* @return the value of a property with name <code>name</code> found in
* <code>obj</code> or any object in its prototype chain, or
* <code>Scriptable.NOT_FOUND</code> if not found
*/
public static Object getProperty(Scriptable obj, String name) {
Scriptable start = obj;
Object result;
do {
result = obj.get(name, start);
if (result != Scriptable.NOT_FOUND)
break;
obj = obj.getPrototype();
} while (obj != null);
return result;
}
/**
* Gets an indexed property from an object or any object in its prototype chain.
* <p>
* Searches the prototype chain for a property with integral index
* <code>index</code>. Note that if you wish to look for properties with numerical
* but non-integral indicies, you should use getProperty(Scriptable,String) with
* the string value of the index.
* <p>
* @param obj a JavaScript object
* @param index an integral index
* @return the value of a property with index <code>index</code> found in
* <code>obj</code> or any object in its prototype chain, or
* <code>Scriptable.NOT_FOUND</code> if not found
*/
public static Object getProperty(Scriptable obj, int index) {
Scriptable start = obj;
Object result;
do {
result = obj.get(index, start);
if (result != Scriptable.NOT_FOUND)
break;
obj = obj.getPrototype();
} while (obj != null);
return result;
}
/**
* Puts a named property in an object or in an object in its prototype chain.
* <p>
* Seaches for the named property in the prototype chain. If it is found,
* the value of the property is changed. If it is not found, a new
* property is added in <code>obj</code>.
* @param obj a JavaScript object
* @param name a property name
* @param value any JavaScript value accepted by Scriptable.put
*/
public static void putProperty(Scriptable obj, String name, Object value) {
Scriptable base = getBase(obj, name);
if (base == null)
base = obj;
base.put(name, obj, value);
}
/**
* Puts an indexed property in an object or in an object in its prototype chain.
* <p>
* Seaches for the indexed property in the prototype chain. If it is found,
* the value of the property is changed. If it is not found, a new
* property is added in <code>obj</code>.
* @param obj a JavaScript object
* @param index a property index
* @param value any JavaScript value accepted by Scriptable.put
*/
public static void putProperty(Scriptable obj, int index, Object value) {
Scriptable base = getBase(obj, index);
if (base == null)
base = obj;
base.put(index, obj, value);
}
/**
* Removes the property from an object or its prototype chain.
* <p>
* Searches for a property with <code>name</code> in obj or
* its prototype chain. If it is found, the object's delete
* method is called.
* @param obj a JavaScript object
* @param name a property name
* @return true if the property doesn't exist or was successfully removed
*/
public static boolean deleteProperty(Scriptable obj, String name) {
Scriptable base = getBase(obj, name);
if (base == null)
return true;
base.delete(name);
return base.get(name, obj) == NOT_FOUND;
}
/**
* Removes the property from an object or its prototype chain.
* <p>
* Searches for a property with <code>index</code> in obj or
* its prototype chain. If it is found, the object's delete
* method is called.
* @param obj a JavaScript object
* @param index a property index
* @return true if the property doesn't exist or was successfully removed
*/
public static boolean deleteProperty(Scriptable obj, int index) {
Scriptable base = getBase(obj, index);
if (base == null)
return true;
base.delete(index);
return base.get(index, obj) == NOT_FOUND;
}
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;
}
/**
* Adds a property attribute to all properties.
*/
@ -1476,16 +1615,6 @@ public abstract class ScriptableObject implements Scriptable {
slots = newSlots;
}
private Function getFunctionProperty(FlattenedObject f, String name) {
Object val = f.getProperty(name);
if (val == null || !(val instanceof FlattenedObject))
return null;
Scriptable s = ((FlattenedObject) val).getObject();
if (s instanceof Function)
return (Function) s;
return null;
}
private static Hashtable getExclusionList() {
if (exclusionList != null)
return exclusionList;

Просмотреть файл

@ -34,7 +34,7 @@
*/
package org.mozilla.javascript;
// API Class
// API class
import java.io.*;

Просмотреть файл

@ -34,8 +34,6 @@
* file under either the NPL or the GPL.
*/
// API class
package org.mozilla.javascript;
import java.util.Hashtable;
@ -44,19 +42,13 @@ import java.util.Enumeration;
/**
* Manipulate a Scriptable object as if its prototype chain were flattened.
* <p>
* Compared to the Scriptable interface, FlattenedObject provides a view of
* Scriptable objects that is easier to use and more closely matches a script
* writer's view of a JavaScript object. <p>
* This class has been deprecated in favor of the static methods
* <code>getProperty</code>, <code>putProperty</code>, and
* <code>deleteProperty</code>. Those methods provide the
* same functionality without the confusing and inefficient need to construct
* a new object instance.
*
* A FlattenedObject is "flattened" in the sense that multiple objects in a
* prototype chain appear to have their properties all appear in the
* FlattenedObject. <p>
*
* Another convenience provided by Flattened object is the ability to access
* properties by a single java.lang.Object id. This id is then converted into
* a String or an int before methods of the Scriptable object are called.
*
* @see org.mozilla.javascript.Scriptable
* @see org.mozilla.javascript.ScriptableObject
*
* @author Norris Boyd
*/
@ -67,6 +59,7 @@ 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;
@ -74,6 +67,7 @@ public class FlattenedObject {
/**
* Get the associated Scriptable object.
* @deprecated
*/
public Scriptable getObject() {
return obj;
@ -93,6 +87,7 @@ public class FlattenedObject {
* @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);
@ -119,6 +114,7 @@ public class FlattenedObject {
* @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);
@ -149,6 +145,7 @@ public class FlattenedObject {
* 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);
@ -179,6 +176,7 @@ public class FlattenedObject {
* 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);
@ -208,6 +206,7 @@ public class FlattenedObject {
* array will be unique respective to equals().)
*
* @see org.mozilla.javascript.Scriptable#getIds
* @deprecated
*/
public Object[] getIds() {
Hashtable h = new Hashtable(11);
@ -241,6 +240,7 @@ public class FlattenedObject {
* @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,
@ -263,6 +263,7 @@ public class FlattenedObject {
* @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,
@ -297,6 +298,7 @@ public class FlattenedObject {
* @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,

Просмотреть файл

@ -214,7 +214,8 @@ public class JavaAdapter extends ScriptableObject {
Scriptable p = (Scriptable) f;
if (!(p instanceof Function))
continue;
length = (int) Context.toNumber(getProperty(p, "length"));
length = (int) Context.toNumber(
ScriptableObject.getProperty(p, "length"));
} else if (f instanceof FunctionNode) {
length = ((FunctionNode) f).getVariableTable().getParameterCount();
} else {
@ -771,24 +772,6 @@ public class JavaAdapter extends ScriptableObject {
return sb;
}
/**
* Looks up a property of a scriptable object, searching the entire prototype
* chain. Works like FlattenedObject.getProperty() without the overhead.
*/
private static Object getProperty(Scriptable obj, String id) {
Scriptable m = obj;
Object result = null;
for(;;) {
result = m.get(id, obj);
if (result != Scriptable.NOT_FOUND)
break;
m = m.getPrototype();
if (m == null)
return Undefined.instance;
}
return result;
}
static final class MyClassLoader extends ClassLoader {
public Class defineClass(String name, byte data[]) {
return super.defineClass(name, data, 0, data.length);

Просмотреть файл

@ -115,13 +115,9 @@ public class NativeFunction extends ScriptableObject implements Function {
*
*/
public boolean hasInstance(Scriptable instance) {
FlattenedObject flat = new FlattenedObject(this);
Object protoProp = flat.getProperty("prototype");
if (protoProp instanceof FlattenedObject) {
protoProp = ((FlattenedObject)protoProp).getObject();
if (protoProp != Undefined.instance)
return ScriptRuntime.jsDelegatesTo(instance,
(Scriptable)protoProp);
Object protoProp = ScriptableObject.getProperty(this, "prototype");
if (protoProp instanceof Scriptable && protoProp != Undefined.instance) {
return ScriptRuntime.jsDelegatesTo(instance, (Scriptable)protoProp);
}
Object[] args = { names[0] };
String m = ScriptRuntime.getMessage("msg.instanceof.bad.prototype",

Просмотреть файл

@ -183,8 +183,6 @@ public class NativeJavaObject implements Scriptable, Wrapper {
// Just abandon conversion from JSObject
}
}
if (cls == ScriptRuntime.ClassClass)
return NativeJavaClass.wrap(scope, (Class) obj);
return new NativeJavaObject(scope, obj, staticType);
}

Просмотреть файл

@ -1059,10 +1059,11 @@ public class ScriptRuntime {
* method doesn't return a value.
*/
public static Object delete(Object obj, Object id) {
if (!(obj instanceof Scriptable))
return Boolean.TRUE;
FlattenedObject f = new FlattenedObject((Scriptable) obj);
return f.deleteProperty(id) ? Boolean.TRUE : Boolean.FALSE;
String s = getStringId(id);
boolean result = s != null
? ScriptableObject.deleteProperty((Scriptable) obj, s)
: ScriptableObject.deleteProperty((Scriptable) obj, getIntId(id));
return result ? Boolean.TRUE : Boolean.FALSE;
}
/**
@ -1730,9 +1731,11 @@ public class ScriptRuntime {
Context.getContext(), "TypeError",
ScriptRuntime.getMessage("msg.instanceof.not.object", null), a);
}
// OPT do it here rather than making a new FlattenedObject.
FlattenedObject rhs = new FlattenedObject((Scriptable)b);
return rhs.hasProperty(a);
String s = getStringId(a);
Object result = s != null
? ScriptableObject.getProperty((Scriptable) b, s)
: ScriptableObject.getProperty((Scriptable) b, getIntId(a));
return result != Scriptable.NOT_FOUND;
}
public static Boolean cmp_LTB(Object val1, Object val2) {

Просмотреть файл

@ -45,12 +45,12 @@ package org.mozilla.javascript;
* Host system implementors may find it easier to extend the ScriptableObject
* class rather than implementing Scriptable when writing host objects.
* <p>
* There are many convenience methods defined in FlattenedObject that make
* accessing objects easier.
* There are many static methods defined in ScriptableObject that perform
* the multiple calls to the Scriptable interface needed in order to
* manipulate properties in prototype chains.
* <p>
*
* @see org.mozilla.javascript.ScriptableObject
* @see org.mozilla.javascript.FlattenedObject
* @author Norris Boyd
* @author Nick Thompson
* @author Brendan Eich
@ -137,7 +137,7 @@ public interface Scriptable {
* @param start the object in which the lookup began
* @return true if and only if the named property is found in the object
* @see org.mozilla.javascript.Scriptable#get
* @see org.mozilla.javascript.FlattenedObject#hasProperty
* @see org.mozilla.javascript.ScriptableObject#getProperty
*/
public boolean has(String name, Scriptable start);
@ -153,7 +153,7 @@ public interface Scriptable {
* @param start the object in which the lookup began
* @return true if and only if the indexed property is found in the object
* @see org.mozilla.javascript.Scriptable#get
* @see org.mozilla.javascript.FlattenedObject#hasProperty
* @see org.mozilla.javascript.ScriptableObject#getProperty
*/
public boolean has(int index, Scriptable start);
@ -167,8 +167,8 @@ public interface Scriptable {
* <code>get</code>. A class that implements this method may choose
* to ignore calls to set certain properties, in which case those
* properties are effectively read-only.<p>
* For a more convenient (and less efficient) form of this method,
* see <code>putProperty</code> in FlattenedObject. <p>
* For properties defined in a prototype chain,
* use <code>putProperty</code> in ScriptableObject. <p>
* Note that if a property <i>a</i> is defined in the prototype <i>p</i>
* of an object <i>o</i>, then evaluating <code>o.a = 23</code> will cause
* <code>set</code> to be called on the prototype <i>p</i> with
@ -198,7 +198,7 @@ public interface Scriptable {
* @param value value to set the property to
* @see org.mozilla.javascript.Scriptable#has
* @see org.mozilla.javascript.Scriptable#get
* @see org.mozilla.javascript.FlattenedObject#putProperty
* @see org.mozilla.javascript.ScriptableObject#putProperty
*/
public void put(String name, Scriptable start, Object value);
@ -217,7 +217,7 @@ public interface Scriptable {
* @see org.mozilla.javascript.Scriptable#has
* @see org.mozilla.javascript.Scriptable#get
* @see org.mozilla.javascript.Scriptable#put(String,Scriptable,Object)
* @see org.mozilla.javascript.FlattenedObject#putProperty
* @see org.mozilla.javascript.ScriptaleObject#putProperty
*/
public void put(int index, Scriptable start, Object value);
@ -235,11 +235,11 @@ public interface Scriptable {
* The property is specified by a String name
* as defined for <code>get</code>.
* <p>
* For a more convenient form of this method,
* see deleteProperty in FlattenedObject.
* To delete properties defined in a prototype chain,
* see deleteProperty in ScriptableObject.
* @param name the identifier for the property
* @see org.mozilla.javascript.Scriptable#get
* @see org.mozilla.javascript.FlattenedObject#deleteProperty
* @see org.mozilla.javascript.ScriptableObject#deleteProperty
*/
public void delete(String name);
@ -249,15 +249,15 @@ public interface Scriptable {
* The property is specified by an integral index
* as defined for <code>get</code>.
* <p>
* For a more convenient form of this method,
* see deleteProperty in FlattenedObject.
* To delete properties defined in a prototype chain,
* see deleteProperty in ScriptableObject.
*
* Identical to <code>delete(String)</code> except that
* an integral index is used to select the property.
*
* @param index the numeric index for the property
* @see org.mozilla.javascript.Scriptable#get
* @see org.mozilla.javascript.FlattenedObject#deleteProperty
* @see org.mozilla.javascript.ScriptableObject#deleteProperty
*/
public void delete(int index);

Просмотреть файл

@ -524,17 +524,17 @@ public abstract class ScriptableObject implements Scriptable {
*/
public Object getDefaultValue(Class typeHint) {
Object val;
FlattenedObject f = new FlattenedObject(this);
Context cx = null;
try {
for (int i=0; i < 2; i++) {
if (typeHint == ScriptRuntime.StringClass ? i == 0 : i == 1) {
Function fun = getFunctionProperty(f, "toString");
if (fun == null)
Object v = getProperty(this, "toString");
if (!(v instanceof Function))
continue;
Function fun = (Function) v;
if (cx == null)
cx = Context.getContext();
val = fun.call(cx, fun.getParentScope(), f.getObject(),
val = fun.call(cx, fun.getParentScope(), this,
ScriptRuntime.emptyArgs);
} else {
String hint;
@ -566,14 +566,14 @@ public abstract class ScriptableObject implements Scriptable {
throw Context.reportRuntimeError(
Context.getMessage("msg.invalid.type", args));
}
Function fun = getFunctionProperty(f, "valueOf");
if (fun == null)
Object v = getProperty(this, "valueOf");
if (!(v instanceof Function))
continue;
Function fun = (Function) v;
Object[] args = { hint };
if (cx == null)
cx = Context.getContext();
val = fun.call(cx, fun.getParentScope(), f.getObject(),
args);
val = fun.call(cx, fun.getParentScope(), this, args);
}
if (val != null && (val == Undefined.instance ||
!(val instanceof Scriptable) ||
@ -1327,6 +1327,145 @@ public abstract class ScriptableObject implements Scriptable {
return count == -1;
}
/**
* Gets a named property from an object or any object in its prototype chain.
* <p>
* Searches the prototype chain for a property named <code>name</code>.
* <p>
* @param obj a JavaScript object
* @param name a property name
* @return the value of a property with name <code>name</code> found in
* <code>obj</code> or any object in its prototype chain, or
* <code>Scriptable.NOT_FOUND</code> if not found
*/
public static Object getProperty(Scriptable obj, String name) {
Scriptable start = obj;
Object result;
do {
result = obj.get(name, start);
if (result != Scriptable.NOT_FOUND)
break;
obj = obj.getPrototype();
} while (obj != null);
return result;
}
/**
* Gets an indexed property from an object or any object in its prototype chain.
* <p>
* Searches the prototype chain for a property with integral index
* <code>index</code>. Note that if you wish to look for properties with numerical
* but non-integral indicies, you should use getProperty(Scriptable,String) with
* the string value of the index.
* <p>
* @param obj a JavaScript object
* @param index an integral index
* @return the value of a property with index <code>index</code> found in
* <code>obj</code> or any object in its prototype chain, or
* <code>Scriptable.NOT_FOUND</code> if not found
*/
public static Object getProperty(Scriptable obj, int index) {
Scriptable start = obj;
Object result;
do {
result = obj.get(index, start);
if (result != Scriptable.NOT_FOUND)
break;
obj = obj.getPrototype();
} while (obj != null);
return result;
}
/**
* Puts a named property in an object or in an object in its prototype chain.
* <p>
* Seaches for the named property in the prototype chain. If it is found,
* the value of the property is changed. If it is not found, a new
* property is added in <code>obj</code>.
* @param obj a JavaScript object
* @param name a property name
* @param value any JavaScript value accepted by Scriptable.put
*/
public static void putProperty(Scriptable obj, String name, Object value) {
Scriptable base = getBase(obj, name);
if (base == null)
base = obj;
base.put(name, obj, value);
}
/**
* Puts an indexed property in an object or in an object in its prototype chain.
* <p>
* Seaches for the indexed property in the prototype chain. If it is found,
* the value of the property is changed. If it is not found, a new
* property is added in <code>obj</code>.
* @param obj a JavaScript object
* @param index a property index
* @param value any JavaScript value accepted by Scriptable.put
*/
public static void putProperty(Scriptable obj, int index, Object value) {
Scriptable base = getBase(obj, index);
if (base == null)
base = obj;
base.put(index, obj, value);
}
/**
* Removes the property from an object or its prototype chain.
* <p>
* Searches for a property with <code>name</code> in obj or
* its prototype chain. If it is found, the object's delete
* method is called.
* @param obj a JavaScript object
* @param name a property name
* @return true if the property doesn't exist or was successfully removed
*/
public static boolean deleteProperty(Scriptable obj, String name) {
Scriptable base = getBase(obj, name);
if (base == null)
return true;
base.delete(name);
return base.get(name, obj) == NOT_FOUND;
}
/**
* Removes the property from an object or its prototype chain.
* <p>
* Searches for a property with <code>index</code> in obj or
* its prototype chain. If it is found, the object's delete
* method is called.
* @param obj a JavaScript object
* @param index a property index
* @return true if the property doesn't exist or was successfully removed
*/
public static boolean deleteProperty(Scriptable obj, int index) {
Scriptable base = getBase(obj, index);
if (base == null)
return true;
base.delete(index);
return base.get(index, obj) == NOT_FOUND;
}
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;
}
/**
* Adds a property attribute to all properties.
*/
@ -1476,16 +1615,6 @@ public abstract class ScriptableObject implements Scriptable {
slots = newSlots;
}
private Function getFunctionProperty(FlattenedObject f, String name) {
Object val = f.getProperty(name);
if (val == null || !(val instanceof FlattenedObject))
return null;
Scriptable s = ((FlattenedObject) val).getObject();
if (s instanceof Function)
return (Function) s;
return null;
}
private static Hashtable getExclusionList() {
if (exclusionList != null)
return exclusionList;