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

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

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

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

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

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

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

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

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

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

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