diff --git a/js/rhino/src/org/mozilla/javascript/BaseFunction.java b/js/rhino/src/org/mozilla/javascript/BaseFunction.java index 2870b2e37939..4b3171146058 100644 --- a/js/rhino/src/org/mozilla/javascript/BaseFunction.java +++ b/js/rhino/src/org/mozilla/javascript/BaseFunction.java @@ -56,6 +56,15 @@ public class BaseFunction extends IdScriptableObject implements Function obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed); } + public BaseFunction() + { + } + + public BaseFunction(Scriptable scope, Scriptable prototype) + { + super(scope, prototype); + } + public String getClassName() { return "Function"; } diff --git a/js/rhino/src/org/mozilla/javascript/Context.java b/js/rhino/src/org/mozilla/javascript/Context.java index d4208e388bcd..9f43e77a2613 100644 --- a/js/rhino/src/org/mozilla/javascript/Context.java +++ b/js/rhino/src/org/mozilla/javascript/Context.java @@ -1099,69 +1099,9 @@ public class Context public ScriptableObject initStandardObjects(ScriptableObject scope, boolean sealed) { - if (scope == null) { - scope = new NativeObject(); - } - (new ClassCache()).associate(scope); - - BaseFunction.init(this, scope, sealed); - NativeObject.init(this, scope, sealed); - - Scriptable objectProto = ScriptableObject.getObjectPrototype(scope); - - // Function.prototype.__proto__ should be Object.prototype - Scriptable functionProto = ScriptableObject.getFunctionPrototype(scope); - functionProto.setPrototype(objectProto); - - // Set the prototype of the object passed in if need be - if (scope.getPrototype() == null) - scope.setPrototype(objectProto); - - // must precede NativeGlobal since it's needed therein - NativeError.init(this, scope, sealed); - NativeGlobal.init(this, scope, sealed); - - NativeArray.init(this, scope, sealed); - NativeString.init(this, scope, sealed); - NativeBoolean.init(this, scope, sealed); - NativeNumber.init(this, scope, sealed); - NativeDate.init(this, scope, sealed); - NativeMath.init(this, scope, sealed); - - NativeWith.init(this, scope, sealed); - NativeCall.init(this, scope, sealed); - NativeScript.init(this, scope, sealed); - - boolean withXml = hasFeature(FEATURE_E4X); - - for (int i = 0; i != lazilyNames.length; i += 2) { - String topProperty = lazilyNames[i]; - String className = lazilyNames[i + 1]; - if (!withXml && className == XML_INIT_CLASS) { - continue; - } - new LazilyLoadedCtor(scope, topProperty, className, sealed); - } - - return scope; + return ScriptRuntime.initStandardObjects(this, scope, sealed); } - private static final String - XML_INIT_CLASS = "org.mozilla.javascript.xmlimpl.XMLLibImpl"; - - private static final String[] lazilyNames = { - "RegExp", "org.mozilla.javascript.regexp.NativeRegExp", - "Packages", "org.mozilla.javascript.NativeJavaTopPackage", - "java", "org.mozilla.javascript.NativeJavaTopPackage", - "getClass", "org.mozilla.javascript.NativeJavaTopPackage", - "JavaAdapter", "org.mozilla.javascript.JavaAdapter", - "JavaImporter", "org.mozilla.javascript.ImporterTopLevel", - "XML", XML_INIT_CLASS, - "XMLList", XML_INIT_CLASS, - "Namespace", XML_INIT_CLASS, - "QName", XML_INIT_CLASS, - }; - /** * Get the singleton object that represents the JavaScript Undefined value. */ diff --git a/js/rhino/src/org/mozilla/javascript/IdFunctionObject.java b/js/rhino/src/org/mozilla/javascript/IdFunctionObject.java index 3ce578829dd0..4c64b44e8cdf 100644 --- a/js/rhino/src/org/mozilla/javascript/IdFunctionObject.java +++ b/js/rhino/src/org/mozilla/javascript/IdFunctionObject.java @@ -41,6 +41,9 @@ public class IdFunctionObject extends BaseFunction { public IdFunctionObject(IdFunctionCall idcall, Object tag, int id, int arity) { + if (arity < 0) + throw new IllegalArgumentException(); + this.idcall = idcall; this.tag = tag; this.methodId = id; @@ -49,10 +52,20 @@ public class IdFunctionObject extends BaseFunction } public IdFunctionObject(IdFunctionCall idcall, Object tag, int id, - String name, int arity, Scriptable scope) + String name, int arity, Scriptable scope) { - this(idcall, tag, id, arity); - initFunction(name, scope); + super(scope, null); + + if (arity < 0) + throw new IllegalArgumentException(); + if (name == null) + throw new IllegalArgumentException(); + + this.idcall = idcall; + this.tag = tag; + this.methodId = id; + this.arity = arity; + this.functionName = name; } public void initFunction(String name, Scriptable scope) diff --git a/js/rhino/src/org/mozilla/javascript/IdScriptableObject.java b/js/rhino/src/org/mozilla/javascript/IdScriptableObject.java index b30ce8cb5ec5..6f8e3eaff961 100644 --- a/js/rhino/src/org/mozilla/javascript/IdScriptableObject.java +++ b/js/rhino/src/org/mozilla/javascript/IdScriptableObject.java @@ -323,6 +323,11 @@ public abstract class IdScriptableObject extends ScriptableObject { } + public IdScriptableObject(Scriptable scope, Scriptable prototype) + { + super(scope, prototype); + } + public boolean has(String name, Scriptable start) { if (maxInstanceId != 0) { diff --git a/js/rhino/src/org/mozilla/javascript/Interpreter.java b/js/rhino/src/org/mozilla/javascript/Interpreter.java index c656719f2289..5d1c8b597b66 100644 --- a/js/rhino/src/org/mozilla/javascript/Interpreter.java +++ b/js/rhino/src/org/mozilla/javascript/Interpreter.java @@ -45,8 +45,6 @@ import java.io.*; import org.mozilla.javascript.debug.*; -import org.mozilla.javascript.xml.XMLObject; - public class Interpreter { @@ -3202,19 +3200,15 @@ switch (op) { if (lhs == DBL_MRK) { sDbl[stackTop] += rDbl; } else { - do_add(lhs, rDbl, stack, sDbl, stackTop, true); + do_add(lhs, rDbl, stack, sDbl, stackTop, true, cx); } } else if (lhs == DBL_MRK) { - do_add(rhs, sDbl[stackTop], stack, sDbl, stackTop, false); + do_add(rhs, sDbl[stackTop], stack, sDbl, stackTop, false, cx); } else { - if (lhs instanceof XMLObject || rhs instanceof XMLObject) { + if (lhs instanceof Scriptable || rhs instanceof Scriptable) { stack[stackTop] = ScriptRuntime.add(lhs, rhs, cx); return stackTop; } - if (lhs instanceof Scriptable) - lhs = ((Scriptable) lhs).getDefaultValue(null); - if (rhs instanceof Scriptable) - rhs = ((Scriptable) rhs).getDefaultValue(null); if (lhs instanceof String) { String lstr = (String)lhs; String rstr = ScriptRuntime.toString(rhs); @@ -3239,14 +3233,17 @@ switch (op) { private static void do_add (Object lhs, double rDbl, Object[] stack, double[] stackDbl, int stackTop, - boolean left_right_order) + boolean left_right_order, Context cx) { if (lhs instanceof Scriptable) { - if (lhs == Undefined.instance) { - lhs = ScriptRuntime.NaNobj; - } else { - lhs = ((Scriptable)lhs).getDefaultValue(null); + Object rhs = doubleWrap(rDbl); + if (!left_right_order) { + Object tmp = lhs; + lhs = rhs; + rhs = tmp; } + stack[stackTop] = ScriptRuntime.add(lhs, rhs, cx); + return; } if (lhs instanceof String) { String lstr = (String)lhs; diff --git a/js/rhino/src/org/mozilla/javascript/JavaMembers.java b/js/rhino/src/org/mozilla/javascript/JavaMembers.java index 48b6b01fc535..b90c5ab41611 100644 --- a/js/rhino/src/org/mozilla/javascript/JavaMembers.java +++ b/js/rhino/src/org/mozilla/javascript/JavaMembers.java @@ -357,9 +357,9 @@ class JavaMembers ht.put(name, field); } else if (member instanceof NativeJavaMethod) { NativeJavaMethod method = (NativeJavaMethod) member; - FieldAndMethods fam = new FieldAndMethods(method.methods, + FieldAndMethods fam = new FieldAndMethods(scope, + method.methods, field); - fam.setPrototype(ScriptableObject.getFunctionPrototype(scope)); getFieldAndMethodsTable(isStatic).put(name, fam); ht.put(name, fam); } else if (member instanceof Field) { @@ -583,7 +583,7 @@ class JavaMembers Enumeration e = ht.elements(); while (len-- > 0) { FieldAndMethods fam = (FieldAndMethods) e.nextElement(); - FieldAndMethods famNew = new FieldAndMethods(fam.methods, + FieldAndMethods famNew = new FieldAndMethods(scope, fam.methods, fam.field); famNew.javaObject = javaObject; result.put(fam.field.getName(), famNew); @@ -664,10 +664,12 @@ class BeanProperty class FieldAndMethods extends NativeJavaMethod { - FieldAndMethods(MemberBox[] methods, Field field) + FieldAndMethods(Scriptable scope, MemberBox[] methods, Field field) { super(methods); this.field = field; + setParentScope(scope); + setPrototype(ScriptableObject.getFunctionPrototype(scope)); } public Object getDefaultValue(Class hint) diff --git a/js/rhino/src/org/mozilla/javascript/NativeWith.java b/js/rhino/src/org/mozilla/javascript/NativeWith.java index a40b01c8d69b..96801493cd37 100644 --- a/js/rhino/src/org/mozilla/javascript/NativeWith.java +++ b/js/rhino/src/org/mozilla/javascript/NativeWith.java @@ -150,7 +150,7 @@ public class NativeWith implements Scriptable, IdFunctionCall { /** * Must return null to continue looping or the final collection result. */ - public Object updateDotQuery(boolean value) + protected Object updateDotQuery(boolean value) { // NativeWith itself does not support it throw new IllegalStateException(); diff --git a/js/rhino/src/org/mozilla/javascript/ScriptRuntime.java b/js/rhino/src/org/mozilla/javascript/ScriptRuntime.java index 6dc91bafc804..f6596257d50a 100644 --- a/js/rhino/src/org/mozilla/javascript/ScriptRuntime.java +++ b/js/rhino/src/org/mozilla/javascript/ScriptRuntime.java @@ -97,6 +97,92 @@ public class ScriptRuntime { ScriptableObjectClass = Kit.classOrNull("org.mozilla.javascript.ScriptableObject"), UndefinedClass = Kit.classOrNull("org.mozilla.javascript.Undefined"); + private static final String + XML_INIT_CLASS = "org.mozilla.javascript.xmlimpl.XMLLibImpl"; + + private static final String[] lazilyNames = { + "RegExp", "org.mozilla.javascript.regexp.NativeRegExp", + "Packages", "org.mozilla.javascript.NativeJavaTopPackage", + "java", "org.mozilla.javascript.NativeJavaTopPackage", + "getClass", "org.mozilla.javascript.NativeJavaTopPackage", + "JavaAdapter", "org.mozilla.javascript.JavaAdapter", + "JavaImporter", "org.mozilla.javascript.ImporterTopLevel", + "XML", XML_INIT_CLASS, + "XMLList", XML_INIT_CLASS, + "Namespace", XML_INIT_CLASS, + "QName", XML_INIT_CLASS, + }; + + private static final Object LIBRARY_SCOPE_KEY = new Object(); + + public static ScriptableObject initStandardObjects(Context cx, + ScriptableObject scope, + boolean sealed) + { + if (scope == null) { + scope = new NativeObject(); + } + scope.associateValue(LIBRARY_SCOPE_KEY, LIBRARY_SCOPE_KEY); + + (new ClassCache()).associate(scope); + + BaseFunction.init(cx, scope, sealed); + NativeObject.init(cx, scope, sealed); + + Scriptable objectProto = ScriptableObject.getObjectPrototype(scope); + + // Function.prototype.__proto__ should be Object.prototype + Scriptable functionProto = ScriptableObject.getFunctionPrototype(scope); + functionProto.setPrototype(objectProto); + + // Set the prototype of the object passed in if need be + if (scope.getPrototype() == null) + scope.setPrototype(objectProto); + + // must precede NativeGlobal since it's needed therein + NativeError.init(cx, scope, sealed); + NativeGlobal.init(cx, scope, sealed); + + NativeArray.init(cx, scope, sealed); + NativeString.init(cx, scope, sealed); + NativeBoolean.init(cx, scope, sealed); + NativeNumber.init(cx, scope, sealed); + NativeDate.init(cx, scope, sealed); + NativeMath.init(cx, scope, sealed); + + NativeWith.init(cx, scope, sealed); + NativeCall.init(cx, scope, sealed); + NativeScript.init(cx, scope, sealed); + + boolean withXml = cx.hasFeature(Context.FEATURE_E4X); + + for (int i = 0; i != lazilyNames.length; i += 2) { + String topProperty = lazilyNames[i]; + String className = lazilyNames[i + 1]; + if (!withXml && className == XML_INIT_CLASS) { + continue; + } + new LazilyLoadedCtor(scope, topProperty, className, sealed); + } + + return scope; + } + + public static ScriptableObject getLibraryScope(Scriptable scope) + { + scope = ScriptableObject.getTopLevelScope(scope); + do { + if (scope instanceof ScriptableObject) { + ScriptableObject so = (ScriptableObject)scope; + if (null != so.getAssociatedValue(LIBRARY_SCOPE_KEY)) { + return so; + } + } + scope = scope.getPrototype(); + } while (scope != null); + throw new IllegalStateException("Failed to find library scope"); + } + public static Boolean wrapBoolean(boolean b) { return b ? Boolean.TRUE : Boolean.FALSE; @@ -2171,20 +2257,18 @@ public class ScriptRuntime { return new Double(((Number)val1).doubleValue() + ((Number)val2).doubleValue()); } - - if (val1 instanceof XMLObject && val2 instanceof XMLObject) { - XMLObject xml1 = (XMLObject)val1; - XMLObject xml2 = (XMLObject)val2; - XMLLib xmlLib = xml1.lib(); - return xmlLib.addXMLObjects(cx, xml1, xml2); - } else if (val1 == Undefined.instance && val2 instanceof XMLObject) { - // Undefined added to any XML or XMLList the undefined needs - // to be "". - val1 = ""; - } else if (val2 == Undefined.instance && val1 instanceof XMLObject) { - val2 = ""; + if (val1 instanceof XMLObject) { + Object test = ((XMLObject)val1).addValues(cx, true, val2); + if (test != Scriptable.NOT_FOUND) { + return test; + } + } + if (val2 instanceof XMLObject) { + Object test = ((XMLObject)val2).addValues(cx, false, val1); + if (test != Scriptable.NOT_FOUND) { + return test; + } } - if (val1 instanceof Scriptable) val1 = ((Scriptable) val1).getDefaultValue(null); if (val2 instanceof Scriptable) @@ -2792,8 +2876,7 @@ public class ScriptRuntime { public static Scriptable enterWith(Object value, Scriptable scope) { if (value instanceof XMLObject) { XMLObject object = (XMLObject)value; - XMLLib xmlLib = object.lib(); - return xmlLib.enterXMLWith(object, scope); + return object.enterWith(scope); } return new NativeWith(scope, toObject(scope, value)); } @@ -2812,8 +2895,7 @@ public class ScriptRuntime { ScriptRuntime.toString(value)); } XMLObject object = (XMLObject)value; - XMLLib xmlLib = object.lib(); - return xmlLib.enterDotQuery(object, scope); + return object.enterDotQuery(scope); } public static Object updateDotQuery(boolean value, Scriptable scope) diff --git a/js/rhino/src/org/mozilla/javascript/ScriptableObject.java b/js/rhino/src/org/mozilla/javascript/ScriptableObject.java index 9659fc5db79f..454217818bf6 100644 --- a/js/rhino/src/org/mozilla/javascript/ScriptableObject.java +++ b/js/rhino/src/org/mozilla/javascript/ScriptableObject.java @@ -111,6 +111,19 @@ public abstract class ScriptableObject implements Scriptable, Serializable, } } + public ScriptableObject() + { + } + + public ScriptableObject(Scriptable scope, Scriptable prototype) + { + if (scope == null) + throw new IllegalArgumentException(); + + parentScopeObject = scope; + prototypeObject = prototype; + } + /** * Return the name of the class. * @@ -434,25 +447,12 @@ public abstract class ScriptableObject implements Scriptable, Serializable, slot.attributes = (short) attributes; } - /** - * Returns the default value for prototype of the object. - */ - protected Scriptable defaultPrototype() - { - return null; - } - /** * Returns the prototype of the object. */ public Scriptable getPrototype() { - Scriptable x = prototypeObject; - if (x == UNSET_SCRIPTABLE_FIELD) { - x = defaultPrototype(); - prototypeObject = x; - } - return x; + return prototypeObject; } /** @@ -463,26 +463,12 @@ public abstract class ScriptableObject implements Scriptable, Serializable, prototypeObject = m; } - - /** - * Returns the default value for prototype of the object. - */ - protected Scriptable defaultParentScope() - { - return null; - } - /** * Returns the parent (enclosing) scope of the object. */ public Scriptable getParentScope() { - Scriptable x = parentScopeObject; - if (x == UNSET_SCRIPTABLE_FIELD) { - x = defaultParentScope(); - parentScopeObject = x; - } - return x; + return parentScopeObject; } /** @@ -648,7 +634,7 @@ public abstract class ScriptableObject implements Scriptable, Serializable, * if this == value or null otherwise to indicate no custom * equality is available unless value is this. */ - public Boolean equivalentValues(Object value) + protected Boolean equivalentValues(Object value) { return (this == value) ? Boolean.TRUE : null; } @@ -1921,17 +1907,15 @@ public abstract class ScriptableObject implements Scriptable, Serializable, } } - private static final Scriptable UNSET_SCRIPTABLE_FIELD = new NativeObject(); - /** * The prototype of this object. */ - private Scriptable prototypeObject = UNSET_SCRIPTABLE_FIELD; + private Scriptable prototypeObject; /** * The parent scope of this object. */ - private Scriptable parentScopeObject = UNSET_SCRIPTABLE_FIELD; + private Scriptable parentScopeObject; private static final Object HAS_STATIC_ACCESSORS = Void.TYPE; private static final Slot REMOVED = new Slot(); diff --git a/js/rhino/src/org/mozilla/javascript/xml/XMLLib.java b/js/rhino/src/org/mozilla/javascript/xml/XMLLib.java index 1902a6c3c61d..0bbe9f8a5042 100644 --- a/js/rhino/src/org/mozilla/javascript/xml/XMLLib.java +++ b/js/rhino/src/org/mozilla/javascript/xml/XMLLib.java @@ -39,14 +39,17 @@ import org.mozilla.javascript.*; public abstract class XMLLib { + private static final Object XML_LIB_KEY = new Object(); + public static XMLLib extractFromScopeOrNull(Scriptable scope) { - scope = ScriptableObject.getTopLevelScope(scope); - Object testXML = ScriptableObject.getClassPrototype(scope, "XML"); - if (testXML instanceof XMLObject) { - return ((XMLObject)testXML).lib(); - } - return null; + ScriptableObject so = ScriptRuntime.getLibraryScope(scope); + + // Ensure lazily initialization of real XML library instance + // which is done on first access to XML property + ScriptableObject.getProperty(so, "XML"); + + return (XMLLib)so.getAssociatedValue(XML_LIB_KEY); } public static XMLLib extractFromScope(Scriptable scope) @@ -59,6 +62,12 @@ public abstract class XMLLib throw Context.reportRuntimeError(msg); } + protected final XMLLib bindToScope(Scriptable scope) + { + ScriptableObject so = ScriptRuntime.getLibraryScope(scope); + return (XMLLib)so.associateValue(XML_LIB_KEY, this); + } + public abstract boolean isXMLName(Context cx, Object name); public abstract Object toQualifiedName(String namespace, @@ -72,12 +81,6 @@ public abstract class XMLLib public abstract Reference xmlPrimaryReference(Object nameObject, Scriptable scope); - public abstract Scriptable enterXMLWith(XMLObject object, - Scriptable scope); - - public abstract Scriptable enterDotQuery(XMLObject object, - Scriptable scope); - /** * Escapes the reserved characters in a value of an attribute * @@ -95,13 +98,6 @@ public abstract class XMLLib public abstract String escapeTextValue(Object value); - /** - * Must calculate obj1 + obj2 - */ - public abstract Object addXMLObjects(Context cx, - XMLObject obj1, - XMLObject obj2); - /** * Construct namespace for default xml statement. */ diff --git a/js/rhino/src/org/mozilla/javascript/xml/XMLObject.java b/js/rhino/src/org/mozilla/javascript/xml/XMLObject.java index 8fe9cd2ebc40..0239e5915fb9 100644 --- a/js/rhino/src/org/mozilla/javascript/xml/XMLObject.java +++ b/js/rhino/src/org/mozilla/javascript/xml/XMLObject.java @@ -48,7 +48,14 @@ import org.mozilla.javascript.xml.*; */ public abstract class XMLObject extends IdScriptableObject { - public abstract XMLLib lib(); + public XMLObject() + { + } + + public XMLObject(Scriptable scope, Scriptable prototype) + { + super(scope, prototype); + } /** * Implementation of ECMAScript [[Has]]. @@ -69,4 +76,34 @@ public abstract class XMLObject extends IdScriptableObject * Implementation of ECMAScript [[Delete]]. */ public abstract boolean ecmaDelete(Context cx, Object id); + + /** + * Wrap this object into NativeWith to implement the with statement. + */ + public abstract NativeWith enterWith(Scriptable scope); + + /** + * Wrap this object into NativeWith to implement the .() query. + */ + public abstract NativeWith enterDotQuery(Scriptable scope); + + /** + * Custom + operator. + * Should return {@link Scriptable#NOT_FOUND} if this object does not have + * custom addition operator for the given value, + * or the result of the addition operation. + *

+ * The default implementation returns {@link Scriptable#NOT_FOUND} + * to indicate no custom addition operation. + * + * @param cx the Context object associated with the current thread. + * @param thisIsLeft if true, the object should calculate this + value + * if false, the object should calculate value + this. + * @param value the second argument for addition operation. + */ + public Object addValues(Context cx, boolean thisIsLeft, Object value) + { + return Scriptable.NOT_FOUND; + } + } diff --git a/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/Namespace.java b/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/Namespace.java index f4569dcfb837..3c487d1a0d24 100644 --- a/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/Namespace.java +++ b/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/Namespace.java @@ -53,6 +53,8 @@ class Namespace extends IdScriptableObject public Namespace(XMLLibImpl lib, String uri) { + super(lib.globalScope(), lib.namespacePrototype); + if (uri == null) throw new IllegalArgumentException(); @@ -64,6 +66,8 @@ class Namespace extends IdScriptableObject public Namespace(XMLLibImpl lib, String prefix, String uri) { + super(lib.globalScope(), lib.namespacePrototype); + if (uri == null) throw new IllegalArgumentException(); if (uri.length() == 0) { @@ -152,20 +156,6 @@ class Namespace extends IdScriptableObject return uri(); } - protected Scriptable defaultPrototype() - { - Scriptable result = lib.namespacePrototype; - if (result == this) { - result = null; - } - return result; - } - - protected Scriptable defaultParentScope() - { - return lib.globalScope(); - } - // #string_id_map# private static final int Id_prefix = 1, diff --git a/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/QName.java b/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/QName.java index 3c19cdd31541..8b96f74bd79d 100644 --- a/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/QName.java +++ b/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/QName.java @@ -52,15 +52,9 @@ final class QName extends IdScriptableObject private String localName; private String uri; - static void init(XMLLibImpl lib, boolean sealed) - { - QName obj = new QName(lib, "", "", ""); - lib.qnamePrototype = obj; - obj.exportAsJSClass(MAX_PROTOTYPE_ID, lib.globalScope(), sealed); - } - public QName(XMLLibImpl lib, String uri, String localName, String prefix) { + super(lib.globalScope(), lib.qnamePrototype); if (localName == null) throw new IllegalArgumentException(); this.lib = lib; this.uri = uri; @@ -153,20 +147,6 @@ final class QName extends IdScriptableObject return toString(); } - protected Scriptable defaultPrototype() - { - Scriptable result = lib.qnamePrototype; - if (result == this) { - result = null; - } - return result; - } - - protected Scriptable defaultParentScope() - { - return lib.globalScope(); - } - // #string_id_map# private static final int Id_localName = 1, diff --git a/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/XML.java b/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/XML.java index f3061805bf71..90e856f65dea 100644 --- a/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/XML.java +++ b/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/XML.java @@ -177,7 +177,7 @@ class XML extends XMLObjectImpl */ XML(XMLLibImpl lib) { - super(lib); + super(lib, lib.xmlPrototype); XmlObject xo = XmlObject.Factory.newInstance(); XmlCursor curs = xo.newCursor(); @@ -198,7 +198,7 @@ class XML extends XMLObjectImpl */ private XML(XMLLibImpl lib, XScriptAnnotation anno) { - super(lib); + super(lib, lib.xmlPrototype); _anno = anno; _anno._xScriptXML = this; } @@ -209,7 +209,7 @@ class XML extends XMLObjectImpl */ XML(XMLLibImpl lib, Object inputObject) { - super(lib); + super(lib, lib.xmlPrototype); XmlObject xo; boolean isText = false; String frag; @@ -377,7 +377,7 @@ todo need to handle namespace prefix not found in XML look for namespace type in */ private XML(XMLLibImpl lib, XmlCursor cursor) { - super(lib); + super(lib, lib.xmlPrototype); if(cursor == null || !cursor.isAttr()) { // Make default empty XML @@ -1148,15 +1148,6 @@ todo need to handle namespace prefix not found in XML look for namespace type in return "XML"; } - protected Scriptable defaultPrototype() - { - Scriptable result = lib.xmlPrototype; - if (result == this) { - result = null; - } - return result; - } - // // // methods overriding IdScriptableObject diff --git a/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLLibImpl.java b/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLLibImpl.java index 74b8e8e7ed20..1b5221749f46 100644 --- a/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLLibImpl.java +++ b/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLLibImpl.java @@ -72,7 +72,10 @@ public final class XMLLibImpl extends XMLLib public static void init(Context cx, Scriptable scope, boolean sealed) { XMLLibImpl lib = new XMLLibImpl(scope); - lib.exportToScope(sealed); + XMLLib bound = lib.bindToScope(scope); + if (bound == lib) { + lib.exportToScope(sealed); + } } private void exportToScope(boolean sealed) @@ -527,6 +530,36 @@ public final class XMLLibImpl extends XMLLib return new QName(this, uri, localName, prefix); } + Object addXMLObjects(Context cx, XMLObject obj1, XMLObject obj2) + { + XMLList listToAdd = new XMLList(this); + + if (obj1 instanceof XMLList) { + XMLList list1 = (XMLList)obj1; + if (list1.length() == 1) { + listToAdd.addToList(list1.item(0)); + } else { + // Might be xmlFragment + xmlFragment + xmlFragment + ...; + // then the result will be an XMLList which we want to be an + // rValue and allow it to be assigned to an lvalue. + listToAdd = new XMLList(this, obj1); + } + } else { + listToAdd.addToList(((XML)obj1)); + } + + if (obj2 instanceof XMLList) { + XMLList list2 = (XMLList)obj2; + for (int i = 0; i < list2.length(); i++) { + listToAdd.addToList(list2.item(i)); + } + } else if (obj2 instanceof XML) { + listToAdd.addToList(((XML)obj2)); + } + + return listToAdd; + } + // // // Overriding XMLLib methods @@ -608,37 +641,6 @@ public final class XMLLibImpl extends XMLLib return new XMLReference(xmlObj, xmlName); } - public Scriptable enterXMLWith(XMLObject object, Scriptable scope) - { - return new XMLWithScope(this, scope, object); - } - - public Scriptable enterDotQuery(XMLObject object, Scriptable scope) - { - XMLWithScope xws = new XMLWithScope(this, scope, object); - - // XMLWithScope also handles the .(xxx) DotQuery for XML - // basically DotQuery is a for/in/with statement and in - // the following 3 statements we setup to signal it's - // DotQuery, - // the index and the object being looped over. The - // xws.setPrototype is the scope of the object which is - // is a element of the lhs (XMLList). - xws.setCurrIndex(0); - xws.setDQPrototype(object); - - if (object instanceof XMLList) { - XMLList xl = (XMLList)object; - if (xl.length() > 0) { - xws.setPrototype((Scriptable)(xl.get(0, null))); - } - } - // Always return the outer-most type of XML lValue of - // XML to left of dotQuery. - xws.setXMLList(new XMLList(this)); - return xws; - } - /** * Escapes the reserved characters in a value of an attribute * @@ -695,36 +697,6 @@ public final class XMLLibImpl extends XMLLib return (begin < end) ? elementText.substring(begin, end) : ""; } - public Object addXMLObjects(Context cx, XMLObject obj1, XMLObject obj2) - { - XMLList listToAdd = new XMLList(this); - - if (obj1 instanceof XMLList) { - XMLList list1 = (XMLList)obj1; - if (list1.length() == 1) { - listToAdd.addToList(list1.item(0)); - } else { - // Might be xmlFragment + xmlFragment + xmlFragment + ...; - // then the result will be an XMLList which we want to be an - // rValue and allow it to be assigned to an lvalue. - listToAdd = new XMLList(this, obj1); - } - } else { - listToAdd.addToList(((XML)obj1)); - } - - if (obj2 instanceof XMLList) { - XMLList list2 = (XMLList)obj2; - for (int i = 0; i < list2.length(); i++) { - listToAdd.addToList(list2.item(i)); - } - } else if (obj2 instanceof XML) { - listToAdd.addToList(((XML)obj2)); - } - - return listToAdd; - } - public Object toDefaultXmlNamespace(Context cx, Object uriValue) { return constructNamespace(cx, uriValue); @@ -765,6 +737,4 @@ public final class XMLLibImpl extends XMLLib return Undefined.instance; } - - } diff --git a/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLList.java b/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLList.java index cb67376674ae..2865b8dd5485 100644 --- a/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLList.java +++ b/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLList.java @@ -102,7 +102,7 @@ class XMLList extends XMLObjectImpl implements Function */ XMLList(XMLLibImpl lib) { - super(lib); + super(lib, lib.xmlListPrototype); _annos = new AnnotationList(); } @@ -112,7 +112,7 @@ class XMLList extends XMLObjectImpl implements Function */ XMLList(XMLLibImpl lib, Object inputObject) { - super(lib); + super(lib, lib.xmlListPrototype); String frag; if (inputObject == null || inputObject instanceof Undefined) @@ -291,15 +291,6 @@ class XMLList extends XMLObjectImpl implements Function return "XMLList"; } - protected Scriptable defaultPrototype() - { - Scriptable result = lib.xmlListPrototype; - if (result == this) { - result = null; - } - return result; - } - // // // methods overriding IdScriptableObject diff --git a/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLObjectImpl.java b/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLObjectImpl.java index 10c67a783634..2787a69837fb 100644 --- a/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLObjectImpl.java +++ b/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLObjectImpl.java @@ -53,8 +53,9 @@ abstract class XMLObjectImpl extends XMLObject protected final XMLLibImpl lib; protected boolean prototypeFlag; - protected XMLObjectImpl(XMLLibImpl lib) + protected XMLObjectImpl(XMLLibImpl lib, XMLObject prototype) { + super(lib.globalScope(), prototype); this.lib = lib; } @@ -149,11 +150,6 @@ abstract class XMLObjectImpl extends XMLObject return toString(); } - protected final Scriptable defaultParentScope() - { - return lib.globalScope(); - } - public void delete(String name) { throw new IllegalArgumentException("String: [" + name + "]"); @@ -164,7 +160,7 @@ abstract class XMLObjectImpl extends XMLObject * never returns null for them but rather calls equivalentXml(value) * and box the result as Boolean. */ - public final Boolean equivalentValues(Object value) + protected final Boolean equivalentValues(Object value) { boolean result = equivalentXml(value); @@ -249,6 +245,40 @@ abstract class XMLObjectImpl extends XMLObject return true; } + public NativeWith enterWith(Scriptable scope) + { + return new XMLWithScope(lib, scope, this); + } + + public NativeWith enterDotQuery(Scriptable scope) + { + XMLWithScope xws = new XMLWithScope(lib, scope, this); + xws.initAsDotQuery(); + return xws; + } + + public final Object addValues(Context cx, boolean thisIsLeft, + Object value) + { + if (value instanceof XMLObject) { + XMLObject v1, v2; + if (thisIsLeft) { + v1 = this; + v2 = (XMLObject)value; + } else { + v1 = (XMLObject)value; + v2 = this; + } + return lib.addXMLObjects(cx, v1, v2); + } + if (value == Undefined.instance) { + // both "xml + undefined" and "undefined + xml" gives String(xml) + return ScriptRuntime.toString(this); + } + + return super.addValues(cx, thisIsLeft, value); + } + // // // IdScriptableObject machinery diff --git a/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLWithScope.java b/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLWithScope.java index d3fd62613d42..89274c2bbf6f 100644 --- a/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLWithScope.java +++ b/js/rhino/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLWithScope.java @@ -43,50 +43,45 @@ import org.mozilla.javascript.xml.*; final class XMLWithScope extends NativeWith { - private XMLLib lib; + private XMLLibImpl lib; private int _currIndex; - private XMLList _xmlList = null; - private Scriptable _dqPrototype; + private XMLList _xmlList; + private XMLObject _dqPrototype; - XMLWithScope(XMLLib lib, Scriptable parent, XMLObject prototype) + XMLWithScope(XMLLibImpl lib, Scriptable parent, XMLObject prototype) { super(parent, prototype); this.lib = lib; } - public XMLLib lib() + void initAsDotQuery() { - return lib; + XMLObject prototype = (XMLObject)getPrototype(); + // XMLWithScope also handles the .(xxx) DotQuery for XML + // basically DotQuery is a for/in/with statement and in + // the following 3 statements we setup to signal it's + // DotQuery, + // the index and the object being looped over. The + // xws.setPrototype is the scope of the object which is + // is a element of the lhs (XMLList). + _currIndex = 0; + _dqPrototype = prototype; + if (prototype instanceof XMLList) { + XMLList xl = (XMLList)prototype; + if (xl.length() > 0) { + setPrototype((Scriptable)(xl.get(0, null))); + } + } + // Always return the outer-most type of XML lValue of + // XML to left of dotQuery. + _xmlList = new XMLList(lib); } - public void setCurrIndex (int idx) - { - _currIndex = idx; - } - - public int getCurrIndex () - { - return _currIndex; - } - - public void setXMLList (XMLList l) - { - _xmlList = l; - } - - public Scriptable getDQPrototype() { - return _dqPrototype; - } - - public void setDQPrototype(Scriptable dqPrototype) { - _dqPrototype = dqPrototype; - } - - public Object updateDotQuery(boolean value) + protected Object updateDotQuery(boolean value) { // Return null to continue looping - Scriptable seed = getDQPrototype(); + XMLObject seed = _dqPrototype; XMLList xmlL = _xmlList; Object result; @@ -96,7 +91,7 @@ final class XMLWithScope extends NativeWith // to our result list. If false, we try the next element. XMLList orgXmlL = (XMLList)seed; - int idx = getCurrIndex(); + int idx = _currIndex; if (value) { xmlL.addToList(orgXmlL.get(idx, null)); @@ -107,7 +102,7 @@ final class XMLWithScope extends NativeWith // Yes, set our new index, get the next element and // reset the expression to run with this object as // the WITH selector. - setCurrIndex(idx); + _currIndex = idx; setPrototype((Scriptable)(orgXmlL.get(idx, null))); // continue looping