Parser tree nodes of Token.CONVERT type are replaced by Token.TONUMBER and additional optimizer nodes to convert to double or object eliminating the need to distinguish them by Node.TYPE_PROPERTY.

This commit is contained in:
igor%mir2.org 2003-08-14 11:21:46 +00:00
Родитель 8b0aa84272
Коммит 13865e4143
6 изменённых файлов: 79 добавлений и 127 удалений

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

@ -768,7 +768,7 @@ public class IRFactory {
: Token.SUB,
childNode,
rhs,
ScriptRuntime.NumberClass,
true,
nodeOp == Token.POST);
}
@ -813,18 +813,18 @@ public class IRFactory {
public Object createAssignment(int assignOp, Object left, Object right)
{
return createAssignment(assignOp, (Node) left, (Node) right,
null, false);
false, false);
}
private Node createAssignment(int assignOp, Node left, Node right,
Class convert, boolean postfix)
boolean tonumber, boolean postfix)
{
int nodeType = left.getType();
String idString;
Node id = null;
switch (nodeType) {
case Token.NAME:
return createSetName(assignOp, left, right, convert, postfix);
return createSetName(assignOp, left, right, tonumber, postfix);
case Token.GETPROP:
idString = (String) left.getProp(Node.SPECIAL_PROP_PROP);
@ -835,7 +835,7 @@ public class IRFactory {
if (id == null)
id = left.getLastChild();
return createSetProp(nodeType, assignOp, left.getFirstChild(),
id, right, convert, postfix);
id, right, tonumber, postfix);
default:
// TODO: This should be a ReferenceError--but that's a runtime
// exception. Should we compile an exception into the code?
@ -844,16 +844,12 @@ public class IRFactory {
}
}
private Node createConvert(Class toType, Node expr) {
if (toType == null)
return expr;
Node result = new Node(Token.CONVERT, expr);
result.putProp(Node.TYPE_PROP, ScriptRuntime.NumberClass);
return result;
private Node createToNumber(Node expr) {
return new Node(Token.TONUMBER, expr);
}
private Node createSetName(int assignOp, Node left, Node right,
Class convert, boolean postfix)
boolean tonumber, boolean postfix)
{
if (assignOp == Token.NOP) {
left.setType(Token.BINDNAME);
@ -869,8 +865,8 @@ public class IRFactory {
}
Node opLeft = Node.newString(Token.NAME, s);
if (convert != null)
opLeft = createConvert(convert, opLeft);
if (tonumber)
opLeft = createToNumber(opLeft);
if (postfix)
opLeft = createNewTemp(opLeft);
Node op = new Node(assignOp, opLeft, right);
@ -948,7 +944,7 @@ public class IRFactory {
}
private Node createSetProp(int nodeType, int assignOp, Node obj, Node id,
Node expr, Class convert, boolean postfix)
Node expr, boolean tonumber, boolean postfix)
{
int type = nodeType == Token.GETPROP
? Token.SETPROP
@ -993,8 +989,8 @@ public class IRFactory {
opLeft = new Node(nodeType, obj, id);
}
if (convert != null)
opLeft = createConvert(convert, opLeft);
if (tonumber)
opLeft = createToNumber(opLeft);
if (postfix)
opLeft = createNewTemp(opLeft);
Node op = new Node(assignOp, opLeft, expr);

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

@ -600,16 +600,10 @@ public class Interpreter
itsStackDepth--;
break;
case Token.CONVERT : {
case Token.TONUMBER:
iCodeTop = generateICode(child, iCodeTop);
Object toType = node.getProp(Node.TYPE_PROP);
if (toType == ScriptRuntime.NumberClass) {
iCodeTop = addToken(Token.POS, iCodeTop);
} else {
badTree(node);
}
iCodeTop = addToken(Token.POS, iCodeTop);
break;
}
case Token.UNARYOP :
iCodeTop = generateICode(child, iCodeTop);

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

@ -291,10 +291,9 @@ public class Node implements Cloneable {
CASES_PROP = 12,
DEFAULT_PROP = 13,
CASEARRAY_PROP = 14,
TYPE_PROP = 15,
SPECIAL_PROP_PROP = 16,
LABEL_PROP = 17,
FINALLY_PROP = 18,
SPECIAL_PROP_PROP = 15,
LABEL_PROP = 16,
FINALLY_PROP = 17,
/*
the following properties are defined and manipulated by the
optimizer -
@ -309,13 +308,13 @@ public class Node implements Cloneable {
matches.
*/
TARGETBLOCK_PROP = 19,
VARIABLE_PROP = 20,
LASTUSE_PROP = 21,
ISNUMBER_PROP = 22,
DIRECTCALL_PROP = 23,
TARGETBLOCK_PROP = 18,
VARIABLE_PROP = 19,
LASTUSE_PROP = 20,
ISNUMBER_PROP = 21,
DIRECTCALL_PROP = 22,
SPECIALCALL_PROP = 24;
SPECIALCALL_PROP = 23;
public static final int // this value of the ISNUMBER_PROP specifies
BOTH = 0, // which of the children are Number types
@ -346,7 +345,6 @@ public class Node implements Cloneable {
case CASES_PROP: return "cases";
case DEFAULT_PROP: return "default";
case CASEARRAY_PROP: return "casearray";
case TYPE_PROP: return "type";
case SPECIAL_PROP_PROP: return "special_prop";
case LABEL_PROP: return "label";
case FINALLY_PROP: return "finally";

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

@ -215,7 +215,7 @@ public class Token
ENUMDONE = 116,
EXPRSTMT = 117,
PARENT = 118,
CONVERT = 119,
TONUMBER = 119,
JSR = 120,
NEWLOCAL = 121,
USELOCAL = 122,
@ -347,7 +347,7 @@ public class Token
case ENUMDONE: return "enumdone";
case EXPRSTMT: return "exprstmt";
case PARENT: return "parent";
case CONVERT: return "convert";
case TONUMBER: return "tonumber";
case JSR: return "jsr";
case NEWLOCAL: return "newlocal";
case USELOCAL: return "uselocal";
@ -355,6 +355,6 @@ public class Token
}
return "<unknown="+token+">";
}
return "";
return null;
}
}

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

@ -1258,41 +1258,38 @@ public class Codegen extends Interpreter {
visitBitOp(node, type, child);
break;
case Token.CONVERT: {
Object toType = node.getProp(Node.TYPE_PROP);
if (toType == ScriptRuntime.NumberClass) {
addByteCode(ByteCode.NEW, "java/lang/Double");
addByteCode(ByteCode.DUP);
generateCodeFromNode(child, node);
addScriptRuntimeInvoke("toNumber",
"(Ljava/lang/Object;)D");
addDoubleConstructor();
} else if (toType == ScriptRuntime.DoubleClass) {
// cnvt to double (not Double)
generateCodeFromNode(child, node);
addScriptRuntimeInvoke("toNumber",
"(Ljava/lang/Object;)D");
} else if (toType == ScriptRuntime.ObjectClass) {
// convert from double
int prop = -1;
if (child.getType() == Token.NUMBER) {
prop = child.getIntProp(Node.ISNUMBER_PROP, -1);
}
if (prop != -1) {
child.removeProp(Node.ISNUMBER_PROP);
generateCodeFromNode(child, node);
child.putIntProp(Node.ISNUMBER_PROP, prop);
} else {
addByteCode(ByteCode.NEW, "java/lang/Double");
addByteCode(ByteCode.DUP);
generateCodeFromNode(child, node);
addDoubleConstructor();
}
} else {
badTree();
}
case Token.TONUMBER:
addByteCode(ByteCode.NEW, "java/lang/Double");
addByteCode(ByteCode.DUP);
generateCodeFromNode(child, node);
addScriptRuntimeInvoke("toNumber", "(Ljava/lang/Object;)D");
addDoubleConstructor();
break;
case Optimizer.TO_DOUBLE:
// cnvt to double (not Double)
generateCodeFromNode(child, node);
addScriptRuntimeInvoke("toNumber", "(Ljava/lang/Object;)D");
break;
case Optimizer.TO_OBJECT: {
// convert from double
int prop = -1;
if (child.getType() == Token.NUMBER) {
prop = child.getIntProp(Node.ISNUMBER_PROP, -1);
}
if (prop != -1) {
child.removeProp(Node.ISNUMBER_PROP);
generateCodeFromNode(child, node);
child.putIntProp(Node.ISNUMBER_PROP, prop);
} else {
addByteCode(ByteCode.NEW, "java/lang/Double");
addByteCode(ByteCode.DUP);
generateCodeFromNode(child, node);
addDoubleConstructor();
}
break;
}
case Token.RELOP:
// need a result Object
@ -2784,12 +2781,10 @@ public class Codegen extends Interpreter {
private Node getConvertToObjectOfNumberNode(Node node)
{
if (node.getType() == Token.CONVERT) {
Object toType = node.getProp(Node.TYPE_PROP);
if (toType == ScriptRuntime.ObjectClass) {
Node convertChild = node.getFirstChild();
if (convertChild.getType() == Token.NUMBER)
return convertChild;
if (node.getType() == Optimizer.TO_OBJECT) {
Node convertChild = node.getFirstChild();
if (convertChild.getType() == Token.NUMBER) {
return convertChild;
}
}
return null;

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

@ -47,12 +47,16 @@ import java.io.IOException;
import java.util.Hashtable;
class Optimizer {
class Optimizer
{
static final int NoType = 0;
static final int NumberType = 1;
static final int AnyType = 3;
static final int TO_OBJECT = Token.LAST_TOKEN + 1;
static final int TO_DOUBLE = Token.LAST_TOKEN + 2;
// It is assumed that (NumberType | AnyType) == AnyType
Optimizer(IRFactory irFactory) {
@ -426,11 +430,7 @@ class Optimizer {
if ((theVar != null) && theVar.isNumber()) {
if (rType != NumberType) {
n.removeChild(rChild);
Node newRChild = new Node(Token.CONVERT,
rChild);
newRChild.putProp(Node.TYPE_PROP,
ScriptRuntime.DoubleClass);
n.addChildToBack(newRChild);
n.addChildToBack(new Node(TO_DOUBLE, rChild));
}
n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
markDCPNumberContext(rChild);
@ -440,10 +440,8 @@ class Optimizer {
if (rType == NumberType) {
if (!convertParameter(rChild)) {
n.removeChild(rChild);
Node newRChild = new Node(Token.CONVERT, rChild);
newRChild.putProp(Node.TYPE_PROP,
ScriptRuntime.ObjectClass);
n.addChildToBack(newRChild);
n.addChildToBack(new Node(TO_OBJECT,
rChild));
}
}
return NoType;
@ -463,19 +461,13 @@ class Optimizer {
if (lType == NumberType) {
if (!convertParameter(lChild)) {
n.removeChild(lChild);
Node nuChild = new Node(Token.CONVERT, lChild);
nuChild.putProp(Node.TYPE_PROP,
ScriptRuntime.ObjectClass);
n.addChildToFront(nuChild);
n.addChildToFront(new Node(TO_OBJECT, lChild));
}
}
if (rType == NumberType) {
if (!convertParameter(rChild)) {
n.removeChild(rChild);
Node nuChild = new Node(Token.CONVERT, rChild);
nuChild.putProp(Node.TYPE_PROP,
ScriptRuntime.ObjectClass);
n.addChildToBack(nuChild);
n.addChildToBack(new Node(TO_OBJECT, rChild));
}
}
}
@ -589,10 +581,7 @@ class Optimizer {
else {
if (!convertParameter(rChild)) {
n.removeChild(rChild);
Node newRChild = new Node(Token.CONVERT, rChild);
newRChild.putProp(Node.TYPE_PROP,
ScriptRuntime.DoubleClass);
n.addChildToBack(newRChild);
n.addChildToBack(new Node(TO_DOUBLE, rChild));
n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
}
return NumberType;
@ -602,10 +591,7 @@ class Optimizer {
if (rType == NumberType) {
if (!convertParameter(lChild)) {
n.removeChild(lChild);
Node newLChild = new Node(Token.CONVERT, lChild);
newLChild.putProp(Node.TYPE_PROP,
ScriptRuntime.DoubleClass);
n.addChildToFront(newLChild);
n.addChildToFront(new Node(TO_DOUBLE, lChild));
n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
}
return NumberType;
@ -613,17 +599,11 @@ class Optimizer {
else {
if (!convertParameter(lChild)) {
n.removeChild(lChild);
Node newLChild = new Node(Token.CONVERT, lChild);
newLChild.putProp(Node.TYPE_PROP,
ScriptRuntime.DoubleClass);
n.addChildToFront(newLChild);
n.addChildToFront(new Node(TO_DOUBLE, lChild));
}
if (!convertParameter(rChild)) {
n.removeChild(rChild);
Node newRChild = new Node(Token.CONVERT, rChild);
newRChild.putProp(Node.TYPE_PROP,
ScriptRuntime.DoubleClass);
n.addChildToBack(newRChild);
n.addChildToBack(new Node(TO_DOUBLE, rChild));
}
n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
return NumberType;
@ -638,10 +618,7 @@ class Optimizer {
if (baseType == NumberType) {// can never happen ???
if (!convertParameter(arrayBase)) {
n.removeChild(arrayBase);
Node nuChild = new Node(Token.CONVERT, arrayBase);
nuChild.putProp(Node.TYPE_PROP,
ScriptRuntime.ObjectClass);
n.addChildToFront(nuChild);
n.addChildToFront(new Node(TO_OBJECT, arrayBase));
}
}
int indexType = rewriteForNumberVariables(arrayIndex);
@ -656,10 +633,7 @@ class Optimizer {
if (rValueType == NumberType) {
if (!convertParameter(rValue)) {
n.removeChild(rValue);
Node nuChild = new Node(Token.CONVERT, rValue);
nuChild.putProp(Node.TYPE_PROP,
ScriptRuntime.ObjectClass);
n.addChildToBack(nuChild);
n.addChildToBack(new Node(TO_OBJECT, rValue));
}
}
return NoType;
@ -671,10 +645,7 @@ class Optimizer {
if (baseType == NumberType) {// can never happen ???
if (!convertParameter(arrayBase)) {
n.removeChild(arrayBase);
Node nuChild = new Node(Token.CONVERT, arrayBase);
nuChild.putProp(Node.TYPE_PROP,
ScriptRuntime.ObjectClass);
n.addChildToFront(nuChild);
n.addChildToFront(new Node(TO_OBJECT, arrayBase));
}
}
int indexType = rewriteForNumberVariables(arrayIndex);
@ -721,9 +692,7 @@ class Optimizer {
if (type == NumberType) {
if (!convertParameter(child)) {
n.removeChild(child);
Node nuChild = new Node(Token.CONVERT, child);
nuChild.putProp(Node.TYPE_PROP,
ScriptRuntime.ObjectClass);
Node nuChild = new Node(TO_OBJECT, child);
if (nextChild == null)
n.addChildToBack(nuChild);
else