Pass __proto__ and __parent__ special properties to code generation as strings to allow to support application-specific special properties without altering code generation.

This commit is contained in:
igor%mir2.org 2004-06-02 09:13:12 +00:00
Родитель e3e8425f72
Коммит 4db86ff03e
5 изменённых файлов: 25 добавлений и 54 удалений

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

@ -868,20 +868,9 @@ class IRFactory
nodeType = Token.GETPROP;
right.setType(Token.STRING);
String id = right.getString();
int idlength = id.length();
int special = 0;
if (idlength == 9) {
if (id.equals("__proto__")) {
special = Node.SPECIAL_PROP_PROTO;
}
} else if (idlength == 10) {
if (id.equals("__parent__")) {
special = Node.SPECIAL_PROP_PARENT;
}
}
if (special != 0) {
if (ScriptRuntime.isSpecialProperty(id)) {
Node ref = new Node(Token.SPECIAL_REF, left);
ref.putIntProp(Node.SPECIAL_PROP_PROP, special);
ref.putProp(Node.SPECIAL_PROP_PROP, id);
return new Node(Token.GET_REF, ref);
}
checkActivationName(id, Token.GETPROP);

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

@ -1047,9 +1047,8 @@ public class Interpreter
case Token.SPECIAL_REF: {
stackDelta = 1;
iCodeTop = generateICode(child, iCodeTop);
int special = node.getExistingIntProp(Node.SPECIAL_PROP_PROP);
iCodeTop = addToken(Token.SPECIAL_REF, iCodeTop);
iCodeTop = addByte(special, iCodeTop);
String special = (String)node.getProp(Node.SPECIAL_PROP_PROP);
iCodeTop = addStringOp(Token.SPECIAL_REF, special, iCodeTop);
break;
}
@ -1697,13 +1696,6 @@ public class Interpreter
break;
}
case Token.SPECIAL_REF : {
int specialType = iCode[pc];
out.println(tname + " " + specialType);
++pc;
break;
}
case Icode_CALLSPECIAL : {
int callType = iCode[pc] & 0xFF;
boolean isNew = (iCode[pc + 1] != 0);
@ -1863,10 +1855,6 @@ public class Interpreter
// type of ++/--
return 1 + 1;
case Token.SPECIAL_REF:
// type of special property
return 1 + 1;
case Icode_SHORTNUMBER :
// short number
return 1 + 2;
@ -2831,11 +2819,11 @@ switch (op) {
continue Loop;
}
case Token.SPECIAL_REF : {
//stringReg: name of special property
Object lhs = stack[stackTop];
if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
stack[stackTop] = ScriptRuntime.specialReference(lhs, iCode[pc],
stack[stackTop] = ScriptRuntime.specialReference(lhs, stringReg,
cx, scope);
++pc;
continue Loop;
}
case Token.GENERIC_REF : {

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

@ -77,11 +77,6 @@ public class Node
INCRDECR_PROP = 16, // pre or post type of increment/decerement
LAST_PROP = 16;
// values of SPECIAL_PROP_PROP
public static final int
SPECIAL_PROP_PROTO = 1,
SPECIAL_PROP_PARENT = 2;
// values of ISNUMBER_PROP to specify
// which of the children are Number types
public static final int
@ -634,18 +629,6 @@ public class Node
case LOCAL_BLOCK_PROP : // can't add this as it is dull
value = "last local block";
break;
case SPECIAL_PROP_PROP:
switch (x.intValue) {
case SPECIAL_PROP_PROTO:
value = "__proto__";
break;
case SPECIAL_PROP_PARENT:
value = "__parent__";
break;
default:
throw Kit.codeBug();
}
break;
case ISNUMBER_PROP:
switch (x.intValue) {
case BOTH:

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

@ -1276,20 +1276,30 @@ public class ScriptRuntime {
ref.set(value);
}
static boolean isSpecialProperty(String s)
{
return s.equals("__proto__") || s.equals("__parent__");
}
public static Object specialReference(final Object obj,
final int specialType,
String specialProperty,
Context cx,
final Scriptable scope)
{
if (!(specialType == Node.SPECIAL_PROP_PROTO
|| specialType == Node.SPECIAL_PROP_PARENT))
{
final int PROTO = 0;
final int PARENT = 1;
final int id;
if (specialProperty.equals("__proto__")) {
id = PROTO;
} else if (specialProperty.equals("__parent__")) {
id = PARENT;
} else {
throw Kit.codeBug();
}
return new Reference() {
public Object get()
{
if (specialType == Node.SPECIAL_PROP_PROTO) {
if (id == PROTO) {
return getProto(obj, scope);
} else {
return getParent(obj, scope);
@ -1298,7 +1308,7 @@ public class ScriptRuntime {
public void set(Object value)
{
if (specialType == Node.SPECIAL_PROP_PROTO) {
if (id == PROTO) {
setProto(obj, value, scope);
} else {
setParent(obj, value, scope);

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

@ -3510,13 +3510,14 @@ class BodyCodegen
private void visitSpecialRef(Node node, Node child)
{
int special = node.getExistingIntProp(Node.SPECIAL_PROP_PROP);
String special = (String)node.getProp(Node.SPECIAL_PROP_PROP);
generateCodeFromNode(child, node);
cfw.addPush(special);
cfw.addALoad(contextLocal);
cfw.addALoad(variableObjectLocal);
addScriptRuntimeInvoke("specialReference",
"(Ljava/lang/Object;I"
"(Ljava/lang/Object;"
+"Ljava/lang/String;"
+"Lorg/mozilla/javascript/Context;"
+"Lorg/mozilla/javascript/Scriptable;"
+")Ljava/lang/Object;");