зеркало из https://github.com/mozilla/pjs.git
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:
Родитель
e3e8425f72
Коммит
4db86ff03e
|
@ -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;");
|
||||
|
|
Загрузка…
Ссылка в новой задаче