Yet another reference reorganization:

References now are represented by the pairs (ref, ref_target) where ref is Ref (former Reference) instance and ref_target is Scriptable to apply the reference for.

To return the pair from Reference creation function Context.scratchRefTarget is used to store the target part.

This change allowed to extend XMLName from Ref eliminating the need for XMLReference.
This commit is contained in:
igor%mir2.org 2004-10-03 23:55:04 +00:00
Родитель 7054085f10
Коммит e35e735319
16 изменённых файлов: 357 добавлений и 164 удалений

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

@ -349,8 +349,8 @@ public class BaseFunction extends IdScriptableObject implements Function
/**
* EXPERIMENTAL: subject to change/removal
*/
protected Reference referenceCall(Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
protected Ref callRef(Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
return null;
}

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

@ -2597,4 +2597,7 @@ public class Context
// It can be used to return the second Scriptable result from function
Scriptable scratchScriptable;
// It is used to return the target component for Ref instance
Scriptable scratchRefTarget;
}

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

@ -858,6 +858,7 @@ public class Interpreter
int type = node.getType();
Node child = node.getFirstChild();
int savedStackDepth = itsStackDepth;
int expectedStackDelta = 1;
switch (type) {
case Token.FUNCTION:
@ -901,9 +902,12 @@ public class Interpreter
stackChange(1);
break;
case Token.REF_CALL:
// account for the reference represented as pair (ref, target)
expectedStackDelta = 2;
// fallthrough
case Token.CALL:
case Token.NEW:
case Token.REF_CALL:
{
if (type == Token.NEW) {
visitExpression(child, 0);
@ -932,12 +936,13 @@ public class Interpreter
addIndexOp(type, argCount);
}
// adjust stack
if (type == Token.NEW) {
// f, args -> results
stackChange(-argCount);
if (type == Token.NEW || type == Token.REF_CALL) {
// new: f, args -> result
// ref_call: f, thisObj, args -> ref ref_target
stackChange(-argCount);
} else {
// f, thisObj, args -> results
stackChange(-1 - argCount);
// f, thisObj, args -> result
stackChange(-1 - argCount);
}
if (argCount > itsData.itsMaxCalleeArgs) {
itsData.itsMaxCalleeArgs = argCount;
@ -1026,8 +1031,6 @@ public class Interpreter
case Token.BITNOT:
case Token.TYPEOF:
case Token.VOID:
case Token.GET_REF:
case Token.DEL_REF:
visitExpression(child, 0);
if (type == Token.VOID) {
addIcode(Icode_POP);
@ -1037,6 +1040,13 @@ public class Interpreter
}
break;
case Token.GET_REF:
case Token.DEL_REF:
visitExpression(child, 0);
addToken(type);
stackChange(-1);
break;
case Token.SETPROP:
case Token.SETPROP_OP:
{
@ -1081,15 +1091,16 @@ public class Interpreter
visitExpression(child, 0);
child = child.getNext();
if (type == Token.SET_REF_OP) {
addIcode(Icode_DUP);
stackChange(1);
addIcode(Icode_DUP2);
stackChange(2);
addToken(Token.GET_REF);
stackChange(-1);
// Compensate for the following USE_STACK
stackChange(-1);
}
visitExpression(child, 0);
addToken(Token.SET_REF);
stackChange(-1);
stackChange(-2);
break;
case Token.SETNAME:
@ -1229,6 +1240,8 @@ public class Interpreter
case Token.REF_SPECIAL:
visitExpression(child, 0);
addStringOp(type, (String)node.getProp(Node.NAME_PROP));
stackChange(1);
expectedStackDelta = 2;
break;
case Token.REF_MEMBER:
@ -1245,7 +1258,8 @@ public class Interpreter
child = child.getNext();
} while (child != null);
addIndexOp(type, memberTypeFlags);
stackChange(1 - childCount);
stackChange(2 - childCount);
expectedStackDelta = 2;
}
break;
@ -1272,7 +1286,7 @@ public class Interpreter
default:
throw badTree(node);
}
if (savedStackDepth + 1 != itsStackDepth) {
if (savedStackDepth + expectedStackDelta != itsStackDepth) {
Kit.codeBug();
}
}
@ -1366,6 +1380,7 @@ public class Interpreter
visitExpression(ref, 0);
addIcode(Icode_REF_INC_DEC);
addUint8(incrDecrMask);
stackChange(-1);
break;
}
default : {
@ -2794,27 +2809,35 @@ switch (op) {
continue Loop;
}
case Token.GET_REF : {
Reference ref = (Reference)stack[stackTop];
stack[stackTop] = ScriptRuntime.getReference(ref, cx);
Scriptable target = (Scriptable)stack[stackTop];
--stackTop;
Ref ref = (Ref)stack[stackTop];
stack[stackTop] = ScriptRuntime.refGet(ref, target, cx);
continue Loop;
}
case Token.SET_REF : {
Object value = stack[stackTop];
if (value == DBL_MRK) value = ScriptRuntime.wrapNumber(sDbl[stackTop]);
--stackTop;
Reference ref = (Reference)stack[stackTop];
stack[stackTop] = ScriptRuntime.setReference(ref, value, cx);
Scriptable target = (Scriptable)stack[stackTop];
--stackTop;
Ref ref = (Ref)stack[stackTop];
stack[stackTop] = ScriptRuntime.refSet(ref, target, value, cx);
continue Loop;
}
case Token.DEL_REF : {
Reference ref = (Reference)stack[stackTop];
stack[stackTop] = ScriptRuntime.deleteReference(ref, cx);
Scriptable target = (Scriptable)stack[stackTop];
--stackTop;
Ref ref = (Ref)stack[stackTop];
stack[stackTop] = ScriptRuntime.refDel(ref, target, cx);
continue Loop;
}
case Icode_REF_INC_DEC : {
Reference ref = (Reference)stack[stackTop];
stack[stackTop] = ScriptRuntime.referenceIncrDecr(ref, cx,
iCode[frame.pc]);
Scriptable target = (Scriptable)stack[stackTop];
--stackTop;
Ref ref = (Ref)stack[stackTop];
stack[stackTop] = ScriptRuntime.refIncrDecr(ref, target, cx,
iCode[frame.pc]);
++frame.pc;
continue Loop;
}
@ -2923,9 +2946,10 @@ switch (op) {
if (op == Token.REF_CALL) {
Object[] outArgs = getArgsArray(stack, sDbl, stackTop + 2,
indexReg);
stack[stackTop] = ScriptRuntime.referenceCall(fun, funThisObj,
outArgs, cx,
calleeScope);
stack[stackTop] = ScriptRuntime.callRef(fun, funThisObj, outArgs,
cx, calleeScope);
++stackTop;
stack[stackTop] = Ref.popTarget(cx);
continue Loop;
}
@ -3217,6 +3241,8 @@ switch (op) {
Object obj = stack[stackTop];
if (obj == DBL_MRK) obj = ScriptRuntime.wrapNumber(sDbl[stackTop]);
stack[stackTop] = ScriptRuntime.specialRef(obj, stringReg, cx);
++stackTop;
stack[stackTop] = Ref.popTarget(cx);
continue Loop;
}
case Token.REF_MEMBER: {
@ -3227,6 +3253,8 @@ switch (op) {
Object obj = stack[stackTop];
if (obj == DBL_MRK) obj = ScriptRuntime.wrapNumber(sDbl[stackTop]);
stack[stackTop] = ScriptRuntime.memberRef(obj, elem, cx, indexReg);
++stackTop;
stack[stackTop] = Ref.popTarget(cx);
continue Loop;
}
case Token.REF_NS_MEMBER: {
@ -3240,6 +3268,8 @@ switch (op) {
Object obj = stack[stackTop];
if (obj == DBL_MRK) obj = ScriptRuntime.wrapNumber(sDbl[stackTop]);
stack[stackTop] = ScriptRuntime.memberRef(obj, ns, elem, cx, indexReg);
++stackTop;
stack[stackTop] = Ref.popTarget(cx);
continue Loop;
}
case Token.REF_NAME: {
@ -3248,6 +3278,8 @@ switch (op) {
if (name == DBL_MRK) name = ScriptRuntime.wrapNumber(sDbl[stackTop]);
stack[stackTop] = ScriptRuntime.nameRef(name, cx, frame.scope,
indexReg);
++stackTop;
stack[stackTop] = Ref.popTarget(cx);
continue Loop;
}
case Token.REF_NS_NAME: {
@ -3259,6 +3291,8 @@ switch (op) {
if (ns == DBL_MRK) ns = ScriptRuntime.wrapNumber(sDbl[stackTop]);
stack[stackTop] = ScriptRuntime.nameRef(ns, name, cx, frame.scope,
indexReg);
++stackTop;
stack[stackTop] = Ref.popTarget(cx);
continue Loop;
}
case Icode_SCOPE :

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

@ -0,0 +1,75 @@
/* -*- 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 or
* 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):
* Igor Bukanov, igor@fastmail.fm
*
* 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.io.Serializable;
/**
* Generic notion of reference object that know how to query/modify the
* target objects based on some property/index.
*/
public abstract class Ref implements Serializable
{
public static Ref pushTarget(Context cx, Ref ref, Scriptable target)
{
if (cx.scratchRefTarget != null) throw new IllegalStateException();
cx.scratchRefTarget = target;
return ref;
}
public static Scriptable popTarget(Context cx)
{
Scriptable target = cx.scratchRefTarget;
cx.scratchRefTarget = null;
return target;
}
public boolean has(Context cx, Scriptable target)
{
return true;
}
public abstract Object get(Context cx, Scriptable target);
public abstract Object set(Context cx, Scriptable target, Object value);
public boolean delete(Context cx, Scriptable target)
{
return false;
}
}

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

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

@ -1516,19 +1516,20 @@ public class ScriptRuntime {
return result;
}
public static Object getReference(Reference ref, Context cx)
public static Object refGet(Ref ref, Scriptable target, Context cx)
{
return ref.get(cx);
return ref.get(cx, target);
}
public static Object setReference(Reference ref, Object value, Context cx)
public static Object refSet(Ref ref, Scriptable target,
Object value, Context cx)
{
return ref.set(cx, value);
return ref.set(cx, target, value);
}
public static Object deleteReference(Reference ref, Context cx)
public static Object refDel(Ref ref, Scriptable target, Context cx)
{
return wrapBoolean(ref.delete(cx));
return wrapBoolean(ref.delete(cx, target));
}
static boolean isSpecialProperty(String s)
@ -1536,8 +1537,8 @@ public class ScriptRuntime {
return s.equals("__proto__") || s.equals("__parent__");
}
public static Reference specialRef(Object obj, String specialProperty,
Context cx)
public static Ref specialRef(Object obj, String specialProperty,
Context cx)
{
return SpecialRef.createSpecial(cx, obj, specialProperty);
}
@ -2032,20 +2033,22 @@ public class ScriptRuntime {
/**
* Perform function call in reference context. Should always
* return value that can be passed to
* {@link #getReference(Object)} or @link #setReference(Object, Object)}
* {@link #refGet(Object)} or @link #refSet(Object, Object)}
* arbitrary number of times.
* The args array reference should not be stored in any object that is
* can be GC-reachable after this method returns. If this is necessary,
* store args.clone(), not args array itself.
*/
public static Object referenceCall(Function function, Scriptable thisObj,
Object[] args,
Context cx, Scriptable scope)
public static Object callRef(Function function, Scriptable thisObj,
Object[] args, Context cx, Scriptable scope)
{
if (function instanceof BaseFunction) {
BaseFunction bf = (BaseFunction)function;
Reference ref = bf.referenceCall(cx, scope, thisObj, args);
if (ref != null) { return ref; }
Ref ref = bf.callRef(cx, scope, thisObj, args);
if (ref != null) {
storeScriptable(cx, thisObj);
return ref;
}
}
// No runtime support for now
String msg = getMessage1("msg.no.ref.from.function",
@ -2413,10 +2416,10 @@ public class ScriptRuntime {
}
}
public static Object referenceIncrDecr(Reference ref, Context cx,
int incrDecrMask)
public static Object refIncrDecr(Ref ref, Scriptable target,
Context cx, int incrDecrMask)
{
Object value = ref.get(cx);
Object value = ref.get(cx, target);
boolean post = ((incrDecrMask & Node.POST_FLAG) != 0);
double number;
if (value instanceof Number) {
@ -2434,7 +2437,7 @@ public class ScriptRuntime {
--number;
}
Number result = wrapNumber(number);
ref.set(cx, result);
ref.set(cx, target, result);
if (post) {
return value;
} else {
@ -3395,8 +3398,8 @@ public class ScriptRuntime {
return xmlLib.escapeTextValue(value);
}
public static Reference memberRef(Object obj, Object elem, Context cx,
int memberTypeFlags)
public static Ref memberRef(Object obj, Object elem,
Context cx, int memberTypeFlags)
{
if (!(obj instanceof XMLObject)) {
throw notXmlError(obj);
@ -3405,9 +3408,8 @@ public class ScriptRuntime {
return xmlObject.memberRef(cx, elem, memberTypeFlags);
}
public static Reference memberRef(Object obj, Object namespace,
Object elem, Context cx,
int memberTypeFlags)
public static Ref memberRef(Object obj, Object namespace, Object elem,
Context cx, int memberTypeFlags)
{
if (!(obj instanceof XMLObject)) {
throw notXmlError(obj);
@ -3416,15 +3418,15 @@ public class ScriptRuntime {
return xmlObject.memberRef(cx, namespace, elem, memberTypeFlags);
}
public static Reference nameRef(Object name, Context cx,
Scriptable scope, int memberTypeFlags)
public static Ref nameRef(Object name, Context cx,
Scriptable scope, int memberTypeFlags)
{
XMLLib xmlLib = currentXMLLib(cx);
return xmlLib.nameRef(cx, name, scope, memberTypeFlags);
}
public static Reference nameRef(Object namespace, Object name, Context cx,
Scriptable scope, int memberTypeFlags)
public static Ref nameRef(Object namespace, Object name, Context cx,
Scriptable scope, int memberTypeFlags)
{
XMLLib xmlLib = currentXMLLib(cx);
return xmlLib.nameRef(cx, namespace, name, scope, memberTypeFlags);
@ -3457,8 +3459,6 @@ public class ScriptRuntime {
private static void storeScriptable(Context cx, Scriptable value)
{
if (value == null)
throw new IllegalArgumentException();
// The previosly stored scratchScriptable should be consumed
if (cx.scratchScriptable != null)
throw new IllegalStateException();
@ -3468,9 +3468,6 @@ public class ScriptRuntime {
public static Scriptable lastStoredScriptable(Context cx)
{
Scriptable result = cx.scratchScriptable;
if (result == null)
throw new IllegalStateException();
// Consume the result
cx.scratchScriptable = null;
return result;
}

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

@ -35,24 +35,22 @@
package org.mozilla.javascript;
class SpecialRef extends Reference
class SpecialRef extends Ref
{
private static final int SPECIAL_NONE = 0;
private static final int SPECIAL_PROTO = 1;
private static final int SPECIAL_PARENT = 2;
private int type;
private Scriptable target;
private String name;
private SpecialRef(int type, Scriptable target, String name)
private SpecialRef(int type, String name)
{
this.type = type;
this.target = target;
this.name = name;
}
static Reference createSpecial(Context cx, Object object, String name)
static Ref createSpecial(Context cx, Object object, String name)
{
Scriptable target = ScriptRuntime.toObjectOrNull(cx, object);
if (target == null) {
@ -73,10 +71,10 @@ class SpecialRef extends Reference
type = SPECIAL_NONE;
}
return new SpecialRef(type, target, name);
return Ref.pushTarget(cx, new SpecialRef(type, name), target);
}
public Object get(Context cx)
public Object get(Context cx, Scriptable target)
{
switch (type) {
case SPECIAL_NONE:
@ -90,7 +88,7 @@ class SpecialRef extends Reference
}
}
public Object set(Context cx, Object value)
public Object set(Context cx, Scriptable target, Object value)
{
switch (type) {
case SPECIAL_NONE:
@ -127,7 +125,7 @@ class SpecialRef extends Reference
}
}
public boolean has(Context cx)
public boolean has(Context cx, Scriptable target)
{
if (type == SPECIAL_NONE) {
return ScriptRuntime.hasObjectElem(target, name, cx);
@ -135,7 +133,7 @@ class SpecialRef extends Reference
return true;
}
public boolean delete(Context cx)
public boolean delete(Context cx, Scriptable target)
{
if (type == SPECIAL_NONE) {
return ScriptRuntime.deleteObjectElem(target, name, cx);

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

@ -1700,13 +1700,15 @@ class BodyCodegen
cfw.addALoad(contextLocal);
cfw.addALoad(variableObjectLocal);
addScriptRuntimeInvoke(
"referenceCall",
"callRef",
"(Lorg/mozilla/javascript/Function;"
+"Lorg/mozilla/javascript/Scriptable;"
+"[Ljava/lang/Object;"
+"Lorg/mozilla/javascript/Context;"
+"Lorg/mozilla/javascript/Scriptable;"
+")Ljava/lang/Object;");
// Load reference target stored in cx by refCal
refTargetToStack();
break;
case Token.NUMBER:
@ -2021,11 +2023,12 @@ class BodyCodegen
break;
case Token.GET_REF:
generateExpression(child, node); // reference
generateExpression(child, node); // reference and target
cfw.addALoad(contextLocal);
addScriptRuntimeInvoke(
"getReference",
"(Lorg/mozilla/javascript/Reference;"
"refGet",
"(Lorg/mozilla/javascript/Ref;"
+"Lorg/mozilla/javascript/Scriptable;"
+"Lorg/mozilla/javascript/Context;"
+")Ljava/lang/Object;");
break;
@ -2058,19 +2061,21 @@ class BodyCodegen
generateExpression(child, node);
child = child.getNext();
if (type == Token.SET_REF_OP) {
cfw.add(ByteCode.DUP);
cfw.add(ByteCode.DUP2);
cfw.addALoad(contextLocal);
addScriptRuntimeInvoke(
"getReference",
"(Lorg/mozilla/javascript/Reference;"
"refGet",
"(Lorg/mozilla/javascript/Ref;"
+"Lorg/mozilla/javascript/Scriptable;"
+"Lorg/mozilla/javascript/Context;"
+")Ljava/lang/Object;");
}
generateExpression(child, node);
cfw.addALoad(contextLocal);
addScriptRuntimeInvoke(
"setReference",
"(Lorg/mozilla/javascript/Reference;"
"refSet",
"(Lorg/mozilla/javascript/Ref;"
+"Lorg/mozilla/javascript/Scriptable;"
+"Ljava/lang/Object;"
+"Lorg/mozilla/javascript/Context;"
+")Ljava/lang/Object;");
@ -2080,8 +2085,9 @@ class BodyCodegen
case Token.DEL_REF:
generateExpression(child, node);
cfw.addALoad(contextLocal);
addScriptRuntimeInvoke("deleteReference",
"(Lorg/mozilla/javascript/Reference;"
addScriptRuntimeInvoke("refDel",
"(Lorg/mozilla/javascript/Ref;"
+"Lorg/mozilla/javascript/Scriptable;"
+"Lorg/mozilla/javascript/Context;"
+")Ljava/lang/Object;");
break;
@ -2132,7 +2138,9 @@ class BodyCodegen
"(Ljava/lang/Object;"
+"Ljava/lang/String;"
+"Lorg/mozilla/javascript/Context;"
+")Lorg/mozilla/javascript/Reference;");
+")Lorg/mozilla/javascript/Ref;");
// Load reference target stored in cx by specialRef
refTargetToStack();
}
break;
@ -2157,7 +2165,7 @@ class BodyCodegen
+"Ljava/lang/Object;"
+"Lorg/mozilla/javascript/Context;"
+"I"
+")Lorg/mozilla/javascript/Reference;";
+")Lorg/mozilla/javascript/Ref;";
break;
case Token.REF_NS_MEMBER:
methodName = "memberRef";
@ -2166,7 +2174,7 @@ class BodyCodegen
+"Ljava/lang/Object;"
+"Lorg/mozilla/javascript/Context;"
+"I"
+")Lorg/mozilla/javascript/Reference;";
+")Lorg/mozilla/javascript/Ref;";
break;
case Token.REF_NAME:
methodName = "nameRef";
@ -2174,7 +2182,7 @@ class BodyCodegen
+"Lorg/mozilla/javascript/Context;"
+"Lorg/mozilla/javascript/Scriptable;"
+"I"
+")Lorg/mozilla/javascript/Reference;";
+")Lorg/mozilla/javascript/Ref;";
cfw.addALoad(variableObjectLocal);
break;
case Token.REF_NS_NAME:
@ -2183,7 +2191,7 @@ class BodyCodegen
+"Lorg/mozilla/javascript/Context;"
+"Lorg/mozilla/javascript/Scriptable;"
+"I"
+")Lorg/mozilla/javascript/Reference;";
+")Lorg/mozilla/javascript/Ref;";
cfw.addALoad(variableObjectLocal);
break;
default:
@ -2191,6 +2199,8 @@ class BodyCodegen
}
cfw.addPush(memberTypeFlags);
addScriptRuntimeInvoke(methodName, signature);
// Load reference target stored in cx by methodName
refTargetToStack();
}
break;
@ -3168,8 +3178,9 @@ Else pass the JS object in the aReg and 0.0 in the dReg.
cfw.addALoad(contextLocal);
cfw.addPush(incrDecrMask);
addScriptRuntimeInvoke(
"referenceIncrDecr",
"(Lorg/mozilla/javascript/Reference;"
"refIncrDecr",
"(Lorg/mozilla/javascript/Ref;"
+"Lorg/mozilla/javascript/Scriptable;"
+"Lorg/mozilla/javascript/Context;"
+"I)Ljava/lang/Object;");
break;
@ -3865,11 +3876,21 @@ Else pass the JS object in the aReg and 0.0 in the dReg.
}
}
private void refTargetToStack()
{
cfw.addALoad(contextLocal);
cfw.addInvoke(ByteCode.INVOKESTATIC,
"org.mozilla.javascript.Ref",
"popTarget",
"(Lorg/mozilla/javascript/Context;"
+")Lorg/mozilla/javascript/Scriptable;");
}
private void addScriptRuntimeInvoke(String methodName,
String methodSignature)
{
cfw.addInvoke(ByteCode.INVOKESTATIC,
"org/mozilla/javascript/ScriptRuntime",
"org.mozilla.javascript.ScriptRuntime",
methodName,
methodSignature);
}

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

@ -78,11 +78,11 @@ public abstract class XMLLib
public abstract boolean isXMLName(Context cx, Object name);
public abstract Reference nameRef(Context cx, Object name,
Scriptable scope, int memberTypeFlags);
public abstract Ref nameRef(Context cx, Object name,
Scriptable scope, int memberTypeFlags);
public abstract Reference nameRef(Context cx, Object namespace, Object name,
Scriptable scope, int memberTypeFlags);
public abstract Ref nameRef(Context cx, Object namespace, Object name,
Scriptable scope, int memberTypeFlags);
/**
* Escapes the reserved characters in a value of an attribute

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

@ -85,14 +85,14 @@ public abstract class XMLObject extends IdScriptableObject
/**
* Generic reference to implement x.@y, x..y etc.
*/
public abstract Reference memberRef(Context cx, Object elem,
int memberTypeFlags);
public abstract Ref memberRef(Context cx, Object elem,
int memberTypeFlags);
/**
* Generic reference to implement x::ns, x.@ns::y, x..@ns::y etc.
*/
public abstract Reference memberRef(Context cx, Object namespace,
Object elem, int memberTypeFlags);
public abstract Ref memberRef(Context cx, Object namespace, Object elem,
int memberTypeFlags);
/**
* Wrap this object into NativeWith to implement the with statement.

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

@ -1151,7 +1151,7 @@ todo need to handle namespace prefix not found in XML look for namespace type in
* @param start
* @return
*/
boolean hasXMLProperty(XMLName xmlName, boolean descendants)
boolean hasXMLProperty(XMLName xmlName)
{
boolean result = false;
@ -1169,7 +1169,7 @@ todo need to handle namespace prefix not found in XML look for namespace type in
// Has now should return true if the property would have results > 0 or
// if it's a method name
String name = xmlName.localName();
if ((getPropertyList(xmlName, descendants).length() > 0) ||
if ((getPropertyList(xmlName).length() > 0) ||
(getMethod(name) != NOT_FOUND))
{
result = true;
@ -1229,7 +1229,7 @@ todo need to handle namespace prefix not found in XML look for namespace type in
* @param start
* @return
*/
Object getXMLProperty(XMLName xmlName, boolean descendants)
Object getXMLProperty(XMLName xmlName)
{
Object result = NOT_FOUND;
@ -1241,7 +1241,7 @@ todo need to handle namespace prefix not found in XML look for namespace type in
}
else
{
result = getPropertyList(xmlName, descendants);
result = getPropertyList(xmlName);
}
return result;
@ -1318,7 +1318,7 @@ todo need to handle namespace prefix not found in XML look for namespace type in
xmlValue = makeXmlFromString(lib, xmlName, ScriptRuntime.toString(value));
}
XMLList matches = (XMLList)getPropertyList(xmlName, false);
XMLList matches = (XMLList)getPropertyList(xmlName);
if (matches.length() == 0)
{
@ -1357,9 +1357,9 @@ todo need to handle namespace prefix not found in XML look for namespace type in
*
* @param name
*/
void deleteXMLProperty(XMLName name, boolean descendants)
void deleteXMLProperty(XMLName name)
{
if (!descendants && name.isAttributeName())
if (!name.isDescendants() && name.isAttributeName())
{
XmlCursor curs = newCursor();
@ -1387,7 +1387,7 @@ todo need to handle namespace prefix not found in XML look for namespace type in
}
else
{
XMLList matches = (XMLList)getPropertyList(name, descendants);
XMLList matches = (XMLList)getPropertyList(name);
matches.remove();
}
@ -2229,7 +2229,7 @@ todo need to handle namespace prefix not found in XML look for namespace type in
}
else
{
hasProperty = (getPropertyList(xmlName, false).length() > 0);
hasProperty = (getPropertyList(xmlName).length() > 0);
}
return hasProperty;
@ -2588,7 +2588,7 @@ todo need to handle namespace prefix not found in XML look for namespace type in
*/
boolean propertyIsEnumerable(XMLName xmlName)
{
return (getPropertyList(xmlName, false).length() > 0);
return (getPropertyList(xmlName).length() > 0);
}
/**
@ -2734,7 +2734,7 @@ todo need to handle namespace prefix not found in XML look for namespace type in
{
// remove all children
XMLName xmlName = XMLName.formStar();
XMLList matches = (XMLList)getPropertyList(xmlName, false);
XMLList matches = (XMLList)getPropertyList(xmlName);
matches.remove();
// append new children
@ -3014,12 +3014,12 @@ todo need to handle namespace prefix not found in XML look for namespace type in
* @param start
* @return
*/
XMLList getPropertyList(XMLName name, boolean descendants)
XMLList getPropertyList(XMLName name)
{
XMLList result;
// Get the named property
if (descendants)
if (name.isDescendants())
{
result = descendants(name);
}

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

@ -523,8 +523,8 @@ public final class XMLLibImpl extends XMLLib
return XMLName.formProperty(uri, localName);
}
public Reference nameRef(Context cx, Object name,
Scriptable scope, int memberTypeFlags)
public Ref nameRef(Context cx, Object name,
Scriptable scope, int memberTypeFlags)
{
if ((memberTypeFlags & Node.ATTRIBUTE_FLAG) == 0) {
// should only be called foir cases like @name or @[expr]
@ -534,8 +534,8 @@ public final class XMLLibImpl extends XMLLib
return xmlPrimaryReference(cx, xmlName, scope);
}
public Reference nameRef(Context cx, Object namespace, Object name,
Scriptable scope, int memberTypeFlags)
public Ref nameRef(Context cx, Object namespace, Object name,
Scriptable scope, int memberTypeFlags)
{
XMLName xmlName = toQualifiedName(cx, namespace, name);
if ((memberTypeFlags & Node.ATTRIBUTE_FLAG) != 0) {
@ -546,9 +546,8 @@ public final class XMLLibImpl extends XMLLib
return xmlPrimaryReference(cx, xmlName, scope);
}
private Reference xmlPrimaryReference(Context cx,
XMLName xmlName,
Scriptable scope)
private Ref xmlPrimaryReference(Context cx, XMLName xmlName,
Scriptable scope)
{
XMLObjectImpl xmlObj;
XMLObjectImpl firstXmlObject = null;
@ -557,7 +556,7 @@ public final class XMLLibImpl extends XMLLib
// of XMLWithScope
if (scope instanceof XMLWithScope) {
xmlObj = (XMLObjectImpl)scope.getPrototype();
if (xmlObj.hasXMLProperty(xmlName, false)) {
if (xmlObj.hasXMLProperty(xmlName)) {
break;
}
if (firstXmlObject == null) {
@ -571,8 +570,9 @@ public final class XMLLibImpl extends XMLLib
}
}
// xmlName == null corresponds to undefined
return new XMLReference(false, xmlObj, xmlName);
// xmlObj == null corresponds to undefined as the target of
// the reference
return Ref.pushTarget(cx, xmlName, xmlObj);
}
/**

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

@ -323,14 +323,14 @@ class XMLList extends XMLObjectImpl implements Function
* @param start
* @return
*/
boolean hasXMLProperty(XMLName xmlName, boolean descendants)
boolean hasXMLProperty(XMLName xmlName)
{
boolean result = false;
// Has now should return true if the property would have results > 0 or
// if it's a method name
String name = xmlName.localName();
if ((getPropertyList(xmlName, descendants).length() > 0) ||
if ((getPropertyList(xmlName).length() > 0) ||
(getMethod(name) != NOT_FOUND))
{
result = true;
@ -427,9 +427,9 @@ class XMLList extends XMLObjectImpl implements Function
* @param name
* @return
*/
Object getXMLProperty(XMLName name, boolean descendants)
Object getXMLProperty(XMLName name)
{
return getPropertyList(name, descendants);
return getPropertyList(name);
}
/**
@ -563,7 +563,7 @@ class XMLList extends XMLObjectImpl implements Function
*
* @param name
*/
void deleteXMLProperty(XMLName name, boolean descendants)
void deleteXMLProperty(XMLName name)
{
for (int i = 0; i < length(); i++)
{
@ -571,7 +571,7 @@ class XMLList extends XMLObjectImpl implements Function
if (xml.tokenType() == XmlCursor.TokenType.START)
{
xml.deleteXMLProperty(name, descendants);
xml.deleteXMLProperty(name);
}
}
}
@ -993,7 +993,7 @@ class XMLList extends XMLObjectImpl implements Function
}
else
{
hasProperty = (getPropertyList(xmlName, false).length() > 0);
hasProperty = (getPropertyList(xmlName).length() > 0);
}
return hasProperty;
@ -1256,7 +1256,7 @@ class XMLList extends XMLObjectImpl implements Function
*/
boolean propertyIsEnumerable(XMLName xmlName)
{
return hasXMLProperty(xmlName, false);
return hasXMLProperty(xmlName);
}
/**
@ -1495,12 +1495,12 @@ class XMLList extends XMLObjectImpl implements Function
* @param start
* @return
*/
private XMLList getPropertyList(XMLName name, boolean descendants)
private XMLList getPropertyList(XMLName name)
{
XMLList propertyList = new XMLList(lib);
javax.xml.namespace.QName qname = null;
if (!descendants && !name.isAttributeName())
if (!name.isDescendants() && !name.isAttributeName())
{
// Only set the targetProperty if this is a regular child get
// and not a descendant or attribute get
@ -1511,8 +1511,8 @@ class XMLList extends XMLObjectImpl implements Function
for (int i = 0; i < length(); i++)
{
propertyList.addToList(getXmlFromAnnotation(i).
getPropertyList(name, descendants));
propertyList.addToList(
getXmlFromAnnotation(i).getPropertyList(name));
}
return propertyList;

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

@ -36,11 +36,19 @@
package org.mozilla.javascript.xmlimpl;
class XMLName
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Kit;
import org.mozilla.javascript.Ref;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptRuntime;
import org.mozilla.javascript.Undefined;
class XMLName extends Ref
{
private String uri;
private String localName;
private boolean isAttributeName;
private boolean isDescendants;
private XMLName(String uri, String localName)
{
@ -48,6 +56,16 @@ class XMLName
this.localName = localName;
}
static XMLName formStar()
{
return new XMLName(null, "*");
}
static XMLName formProperty(String uri, String localName)
{
return new XMLName(uri, localName);
}
String uri()
{
return uri;
@ -65,38 +83,81 @@ class XMLName
void setAttributeName()
{
if (isAttributeName)
throw new IllegalStateException();
if (isAttributeName) throw new IllegalStateException();
isAttributeName = true;
}
boolean isDescendants()
{
return isDescendants;
}
void setIsDescendants()
{
if (isDescendants) throw new IllegalStateException();
isDescendants = true;
}
public boolean has(Context cx, Scriptable target)
{
XMLObjectImpl xmlObject = (XMLObjectImpl)target;
if (xmlObject == null) {
return false;
}
return xmlObject.hasXMLProperty(this);
}
public Object get(Context cx, Scriptable target)
{
XMLObjectImpl xmlObject = (XMLObjectImpl)target;
if (xmlObject == null) {
throw ScriptRuntime.undefReadError(Undefined.instance,
toString());
}
return xmlObject.getXMLProperty(this);
}
public Object set(Context cx, Scriptable target, Object value)
{
XMLObjectImpl xmlObject = (XMLObjectImpl)target;
if (xmlObject == null) {
throw ScriptRuntime.undefWriteError(Undefined.instance,
toString(),
value);
}
// Assignment to descendants causes parse error on bad reference
// and this should not be called
if (isDescendants) throw Kit.codeBug();
xmlObject.putXMLProperty(this, value);
return value;
}
public boolean delete(Context cx, Scriptable target)
{
XMLObjectImpl xmlObject = (XMLObjectImpl)target;
if (xmlObject == null) {
return true;
}
xmlObject.deleteXMLProperty(this);
return !xmlObject.hasXMLProperty(this);
}
public String toString()
{
//return qname.localName();
StringBuffer buff = new StringBuffer();
if(isAttributeName()) buff.append('@');
if(uri() == null)
{
if (isDescendants) buff.append("..");
if (isAttributeName) buff.append('@');
if (uri == null) {
buff.append('*');
if(localName().equals("*"))
if(localName().equals("*")) {
return buff.toString();
}
else
{
}
} else {
buff.append('"').append(uri()).append('"');
}
buff.append(':').append(localName());
return buff.toString();
}
static XMLName formStar()
{
return new XMLName(null, "*");
}
static XMLName formProperty(String uri, String localName)
{
return new XMLName(uri, localName);
}
}

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

@ -63,13 +63,13 @@ abstract class XMLObjectImpl extends XMLObject
* ecmaHas(cx, id) calls this after resolving when id to XMLName
* and checking it is not Uint32 index.
*/
abstract boolean hasXMLProperty(XMLName name, boolean descendants);
abstract boolean hasXMLProperty(XMLName name);
/**
* ecmaGet(cx, id) calls this after resolving when id to XMLName
* and checking it is not Uint32 index.
*/
abstract Object getXMLProperty(XMLName name, boolean descendants);
abstract Object getXMLProperty(XMLName name);
/**
* ecmaPut(cx, id, value) calls this after resolving when id to XMLName
@ -81,7 +81,7 @@ abstract class XMLObjectImpl extends XMLObject
* ecmaDelete(cx, id) calls this after resolving when id to XMLName
* and checking it is not Uint32 index.
*/
abstract void deleteXMLProperty(XMLName name, boolean descendants);
abstract void deleteXMLProperty(XMLName name);
/**
* Test XML equality with target the target.
@ -190,7 +190,7 @@ abstract class XMLObjectImpl extends XMLObject
// XXX Fix this cast
return has((int)index, this);
}
return hasXMLProperty(xmlName, false);
return hasXMLProperty(xmlName);
}
/**
@ -209,7 +209,7 @@ abstract class XMLObjectImpl extends XMLObject
}
return result;
}
return getXMLProperty(xmlName, false);
return getXMLProperty(xmlName);
}
/**
@ -241,11 +241,11 @@ abstract class XMLObjectImpl extends XMLObject
delete((int)index);
return true;
}
deleteXMLProperty(xmlName, false);
deleteXMLProperty(xmlName);
return true;
}
public Reference memberRef(Context cx, Object elem, int memberTypeFlags)
public Ref memberRef(Context cx, Object elem, int memberTypeFlags)
{
XMLName xmlName;
if ((memberTypeFlags & Node.ATTRIBUTE_FLAG) != 0) {
@ -259,15 +259,17 @@ abstract class XMLObjectImpl extends XMLObject
}
xmlName = lib.toXMLName(cx, elem);
}
boolean descendants = ((memberTypeFlags & Node.DESCENDANTS_FLAG) != 0);
return new XMLReference(descendants, this, xmlName);
if ((memberTypeFlags & Node.DESCENDANTS_FLAG) != 0) {
xmlName.setIsDescendants();
}
return Ref.pushTarget(cx, xmlName, this);
}
/**
* Generic reference to implement x::ns, x.@ns::y, x..@ns::y etc.
*/
public Reference memberRef(Context cx, Object namespace, Object elem,
int memberTypeFlags)
public Ref memberRef(Context cx, Object namespace, Object elem,
int memberTypeFlags)
{
XMLName xmlName = lib.toQualifiedName(cx, namespace, elem);
if ((memberTypeFlags & Node.ATTRIBUTE_FLAG) != 0) {
@ -275,8 +277,10 @@ abstract class XMLObjectImpl extends XMLObject
xmlName.setAttributeName();
}
}
boolean descendants = ((memberTypeFlags & Node.DESCENDANTS_FLAG) != 0);
return new XMLReference(descendants, this, xmlName);
if ((memberTypeFlags & Node.DESCENDANTS_FLAG) != 0) {
xmlName.setIsDescendants();
}
return Ref.pushTarget(cx, xmlName, this);
}
public NativeWith enterWith(Scriptable scope)

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