dart2js cps: Streamline expressions and primitives.

SetStatic, SetField, and SetMutableVariable are now primitives instead
of interior expressions. They are valueless primitives, i.e. they are
bound by LetPrim but their value is never referenced.

This should simplify basic block traversal, since there are now fewer
types of interior expressions.

The four remaining interior expressions are: LetPrim, LetCont,
LetHandler, and LetMutable. Incidentally, these are exactly the four
expressions that can bind definitions.

GetMutableVariable and SetMutableVariable have also been renamed
to GetMutable and SetMutable to be uniform with LetMutable.

BUG=
R=karlklose@google.com

Review URL: https://codereview.chromium.org//1240263002.
This commit is contained in:
Asger Feldthaus 2015-07-20 15:59:41 +02:00
parent 5b6cdbb0ca
commit 4d933a2d0d
11 changed files with 169 additions and 184 deletions

View file

@ -273,14 +273,12 @@ class CpsFragment {
/// Reads the value of the given mutable variable.
Primitive getMutable(MutableVariable variable) {
return letPrim(new GetMutableVariable(variable));
return letPrim(new GetMutable(variable));
}
/// Sets the value of the given mutable variable.
void setMutable(MutableVariable variable, Primitive value) {
SetMutableVariable setter = new SetMutableVariable(variable, value);
put(setter);
context = setter;
letPrim(new SetMutable(variable, value));
}
/// Declare a new mutable variable.

View file

@ -1014,7 +1014,7 @@ class IrBuilder {
ir.Primitive buildStaticFieldSet(FieldElement field,
ir.Primitive value,
[SourceInformation sourceInformation]) {
add(new ir.SetStatic(field, value, sourceInformation));
addPrimitive(new ir.SetStatic(field, value, sourceInformation));
return value;
}
@ -2291,9 +2291,10 @@ class IrBuilder {
state.functionParameters.add(parameter);
ClosureLocation location = state.boxedVariables[parameterElement];
if (location != null) {
add(new ir.SetField(environment.lookup(location.box),
location.field,
parameter));
addPrimitive(new ir.SetField(
environment.lookup(location.box),
location.field,
parameter));
} else {
environment.extend(parameterElement, parameter);
}
@ -2315,12 +2316,14 @@ class IrBuilder {
}
ClosureLocation location = state.boxedVariables[variableElement];
if (location != null) {
add(new ir.SetField(environment.lookup(location.box),
location.field,
initialValue));
addPrimitive(new ir.SetField(
environment.lookup(location.box),
location.field,
initialValue));
} else if (isInMutableVariable(variableElement)) {
add(new ir.LetMutable(getMutableVariable(variableElement),
initialValue));
add(new ir.LetMutable(
getMutableVariable(variableElement),
initialValue));
} else {
initialValue.useElementAsHint(variableElement);
environment.extend(variableElement, initialValue);
@ -2361,7 +2364,7 @@ class IrBuilder {
result.useElementAsHint(local);
return addPrimitive(result);
} else if (isInMutableVariable(local)) {
return addPrimitive(new ir.GetMutableVariable(getMutableVariable(local)));
return addPrimitive(new ir.GetMutable(getMutableVariable(local)));
} else {
return environment.lookup(local);
}
@ -2373,11 +2376,13 @@ class IrBuilder {
assert(isOpen);
ClosureLocation location = state.boxedVariables[local];
if (location != null) {
add(new ir.SetField(environment.lookup(location.box),
location.field,
value));
addPrimitive(new ir.SetField(
environment.lookup(location.box),
location.field,
value));
} else if (isInMutableVariable(local)) {
add(new ir.SetMutableVariable(getMutableVariable(local), value));
addPrimitive(new ir.SetMutable(
getMutableVariable(local), value));
} else {
value.useElementAsHint(local);
environment.update(local, value);
@ -2421,7 +2426,7 @@ class IrBuilder {
for (VariableElement loopVar in scope.boxedLoopVariables) {
ClosureLocation location = scope.capturedVariables[loopVar];
ir.Primitive value = addPrimitive(new ir.GetField(box, location.field));
add(new ir.SetField(newBox, location.field, value));
addPrimitive(new ir.SetField(newBox, location.field, value));
}
environment.update(scope.box, newBox);
}
@ -2443,7 +2448,7 @@ class IrBuilder {
void buildFieldSet(ir.Primitive receiver,
FieldElement target,
ir.Primitive value) {
add(new ir.SetField(receiver, target, value));
addPrimitive(new ir.SetField(receiver, target, value));
}
ir.Primitive buildSuperFieldGet(FieldElement target) {
@ -2451,7 +2456,7 @@ class IrBuilder {
}
ir.Primitive buildSuperFieldSet(FieldElement target, ir.Primitive value) {
add(new ir.SetField(buildThis(), target, value));
addPrimitive(new ir.SetField(buildThis(), target, value));
return value;
}

View file

@ -3399,18 +3399,6 @@ class CleanupPass extends ir.RecursiveVisitor {
node.body = replacementFor(node.body);
}
processSetMutableVariable(ir.SetMutableVariable node) {
node.body = replacementFor(node.body);
}
processSetField(ir.SetField node) {
node.body = replacementFor(node.body);
}
processSetStatic(ir.SetStatic node) {
node.body = replacementFor(node.body);
}
processContinuation(ir.Continuation node) {
node.body = replacementFor(node.body);
}

View file

@ -64,7 +64,11 @@ abstract class InteriorNode extends Node {
void set body(Expression body);
}
/// An expression with a subexpression as body.
/// An expression that creates new bindings and continues evaluation in
/// a subexpression.
///
/// The interior expressions are [LetPrim], [LetCont], [LetHandler], and
/// [LetMutable].
abstract class InteriorExpression extends Expression implements InteriorNode {
Expression get next => body;
}
@ -557,17 +561,17 @@ class Unreachable extends TailExpression {
/// Gets the value from a [MutableVariable].
///
/// [MutableVariable]s can be seen as ref cells that are not first-class
/// values. A [LetPrim] with a [GetMutableVariable] can then be seen as:
/// values. A [LetPrim] with a [GetMutable] can then be seen as:
///
/// let prim p = ![variable] in [body]
///
class GetMutableVariable extends Primitive {
class GetMutable extends Primitive {
final Reference<MutableVariable> variable;
GetMutableVariable(MutableVariable variable)
GetMutable(MutableVariable variable)
: this.variable = new Reference<MutableVariable>(variable);
accept(Visitor visitor) => visitor.visitGetMutableVariable(this);
accept(Visitor visitor) => visitor.visitGetMutable(this);
bool get isSafeForElimination => true;
bool get isSafeForReordering => false;
@ -579,21 +583,18 @@ class GetMutableVariable extends Primitive {
/// values. This can be seen as a dereferencing assignment:
///
/// { [variable] := [value]; [body] }
class SetMutableVariable extends InteriorExpression {
class SetMutable extends Primitive {
final Reference<MutableVariable> variable;
final Reference<Primitive> value;
Expression body;
SetMutableVariable(MutableVariable variable, Primitive value)
SetMutable(MutableVariable variable, Primitive value)
: this.variable = new Reference<MutableVariable>(variable),
this.value = new Reference<Primitive>(value);
accept(Visitor visitor) => visitor.visitSetMutableVariable(this);
accept(Visitor visitor) => visitor.visitSetMutable(this);
Expression plug(Expression expr) {
assert(body == null);
return body = expr;
}
bool get isSafeForElimination => false;
bool get isSafeForReordering => false;
}
/// Invoke a continuation in tail position.
@ -662,22 +663,19 @@ class Branch extends TailExpression {
}
/// Directly assigns to a field on a given object.
class SetField extends InteriorExpression {
class SetField extends Primitive {
final Reference<Primitive> object;
FieldElement field;
final Reference<Primitive> value;
Expression body;
SetField(Primitive object, this.field, Primitive value)
: this.object = new Reference<Primitive>(object),
this.value = new Reference<Primitive>(value);
Expression plug(Expression expr) {
assert(body == null);
return body = expr;
}
accept(Visitor visitor) => visitor.visitSetField(this);
bool get isSafeForElimination => false;
bool get isSafeForReordering => false;
}
/// Directly reads from a field on a given object.
@ -778,21 +776,18 @@ class GetStatic extends Primitive {
}
/// Sets the value of a static field.
class SetStatic extends InteriorExpression {
class SetStatic extends Primitive {
final FieldElement element;
final Reference<Primitive> value;
Expression body;
final SourceInformation sourceInformation;
SetStatic(this.element, Primitive value, [this.sourceInformation])
: this.value = new Reference<Primitive>(value);
Expression plug(Expression expr) {
assert(body == null);
return body = expr;
}
accept(Visitor visitor) => visitor.visitSetStatic(this);
bool get isSafeForElimination => false;
bool get isSafeForReordering => false;
}
/// Reads the value of a lazily initialized static field.
@ -1125,7 +1120,7 @@ abstract class Visitor<T> {
T visitRethrow(Rethrow node);
T visitBranch(Branch node);
T visitTypeCast(TypeCast node);
T visitSetMutableVariable(SetMutableVariable node);
T visitSetMutable(SetMutable node);
T visitSetStatic(SetStatic node);
T visitGetLazyStatic(GetLazyStatic node);
T visitSetField(SetField node);
@ -1136,7 +1131,7 @@ abstract class Visitor<T> {
T visitLiteralMap(LiteralMap node);
T visitConstant(Constant node);
T visitCreateFunction(CreateFunction node);
T visitGetMutableVariable(GetMutableVariable node);
T visitGetMutable(GetMutable node);
T visitParameter(Parameter node);
T visitContinuation(Continuation node);
T visitMutableVariable(MutableVariable node);
@ -1283,12 +1278,11 @@ class RecursiveVisitor implements Visitor {
node.typeArguments.forEach(processReference);
}
processSetMutableVariable(SetMutableVariable node) {}
visitSetMutableVariable(SetMutableVariable node) {
processSetMutableVariable(node);
processSetMutable(SetMutable node) {}
visitSetMutable(SetMutable node) {
processSetMutable(node);
processReference(node.variable);
processReference(node.value);
visit(node.body);
}
processGetLazyStatic(GetLazyStatic node) {}
@ -1328,9 +1322,9 @@ class RecursiveVisitor implements Visitor {
processMutableVariable(node);
}
processGetMutableVariable(GetMutableVariable node) {}
visitGetMutableVariable(GetMutableVariable node) {
processGetMutableVariable(node);
processGetMutable(GetMutable node) {}
visitGetMutable(GetMutable node) {
processGetMutable(node);
processReference(node.variable);
}
@ -1370,7 +1364,6 @@ class RecursiveVisitor implements Visitor {
processSetField(node);
processReference(node.object);
processReference(node.value);
visit(node.body);
}
processGetField(GetField node) {}
@ -1388,7 +1381,6 @@ class RecursiveVisitor implements Visitor {
visitSetStatic(SetStatic node) {
processSetStatic(node);
processReference(node.value);
visit(node.body);
}
processCreateBox(CreateBox node) {}

View file

@ -218,15 +218,13 @@ class SExpressionStringifier extends Indentation implements Visitor<String> {
return '(Unexpected Continuation)';
}
String visitGetMutableVariable(GetMutableVariable node) {
return '(GetMutableVariable ${access(node.variable)})';
String visitGetMutable(GetMutable node) {
return '(GetMutable ${access(node.variable)})';
}
String visitSetMutableVariable(SetMutableVariable node) {
String visitSetMutable(SetMutable node) {
String value = access(node.value);
String body = indentBlock(() => visit(node.body));
return '$indentation(SetMutableVariable ${access(node.variable)} '
'$value\n$body)';
return '(SetMutable ${access(node.variable)} $value)';
}
String visitTypeCast(TypeCast node) {
@ -262,8 +260,7 @@ class SExpressionStringifier extends Indentation implements Visitor<String> {
String object = access(node.object);
String field = node.field.name;
String value = access(node.value);
String body = indentBlock(() => visit(node.body));
return '$indentation(SetField $object $field $value)\n$body';
return '(SetField $object $field $value)';
}
String visitGetField(GetField node) {
@ -280,8 +277,7 @@ class SExpressionStringifier extends Indentation implements Visitor<String> {
String visitSetStatic(SetStatic node) {
String element = node.element.name;
String value = access(node.value);
String body = indentBlock(() => visit(node.body));
return '$indentation(SetStatic $element $value\n$body)';
return '(SetStatic $element $value)';
}
String visitGetLazyStatic(GetLazyStatic node) {
@ -335,7 +331,6 @@ class SExpressionStringifier extends Indentation implements Visitor<String> {
return '(ApplyBuiltinOperator $operator ($args))';
}
@override
String visitForeignCode(ForeignCode node) {
String arguments = node.arguments.map(access).join(' ');
String continuation = node.continuation == null ? ''
@ -343,20 +338,17 @@ class SExpressionStringifier extends Indentation implements Visitor<String> {
return '(JS ${node.type} ${node.codeTemplate} ($arguments)$continuation)';
}
@override
String visitGetLength(GetLength node) {
String object = access(node.object);
return '(GetLength $object)';
}
@override
String visitGetIndex(GetIndex node) {
String object = access(node.object);
String index = access(node.index);
return '(GetIndex $object $index)';
}
@override
String visitSetIndex(SetIndex node) {
String object = access(node.object);
String index = access(node.index);

View file

@ -227,12 +227,10 @@ class IRTracer extends TracerUtil implements cps_ir.Visitor {
printStmt(dummy, "Branch $condition ($trueCont, $falseCont)");
}
visitSetMutableVariable(cps_ir.SetMutableVariable node) {
String dummy = names.name(node);
visitSetMutable(cps_ir.SetMutable node) {
String variable = names.name(node.variable.definition);
String value = formatReference(node.value);
printStmt(dummy, 'SetMutableVariable $variable := $value');
visit(node.body);
return 'SetMutable $variable := $value';
}
String formatReference(cps_ir.Reference ref) {
@ -267,12 +265,10 @@ class IRTracer extends TracerUtil implements cps_ir.Visitor {
}
visitSetField(cps_ir.SetField node) {
String dummy = names.name(node);
String object = formatReference(node.object);
String field = node.field.name;
String value = formatReference(node.value);
printStmt(dummy, 'SetField $object.$field = $value');
visit(node.body);
return 'SetField $object.$field = $value';
}
visitGetField(cps_ir.GetField node) {
@ -287,11 +283,9 @@ class IRTracer extends TracerUtil implements cps_ir.Visitor {
}
visitSetStatic(cps_ir.SetStatic node) {
String dummy = names.name(node);
String element = node.element.name;
String value = formatReference(node.value);
printStmt(dummy, 'SetStatic $element = $value');
visit(node.body);
return 'SetStatic $element = $value';
}
visitGetLazyStatic(cps_ir.GetLazyStatic node) {
@ -320,9 +314,9 @@ class IRTracer extends TracerUtil implements cps_ir.Visitor {
return "CreateFunction ${node.definition.element.name}";
}
visitGetMutableVariable(cps_ir.GetMutableVariable node) {
visitGetMutable(cps_ir.GetMutable node) {
String variable = names.name(node.variable.definition);
return 'GetMutableVariable $variable';
return 'GetMutable $variable';
}
visitReadTypeVariable(cps_ir.ReadTypeVariable node) {
@ -523,18 +517,6 @@ class BlockCollector implements cps_ir.Visitor {
visitUnreachable(cps_ir.Unreachable node) {
}
visitSetMutableVariable(cps_ir.SetMutableVariable exp) {
visit(exp.body);
}
visitSetField(cps_ir.SetField exp) {
visit(exp.body);
}
visitSetStatic(cps_ir.SetStatic exp) {
visit(exp.body);
}
visitGetLazyStatic(cps_ir.GetLazyStatic exp) {
addEdgeToContinuation(exp.continuation);
}
@ -583,7 +565,7 @@ class BlockCollector implements cps_ir.Visitor {
unexpectedNode(node);
}
visitGetMutableVariable(cps_ir.GetMutableVariable node) {
visitGetMutable(cps_ir.GetMutable node) {
unexpectedNode(node);
}
@ -659,6 +641,18 @@ class BlockCollector implements cps_ir.Visitor {
unexpectedNode(node);
}
visitSetMutable(cps_ir.SetMutable node) {
unexpectedNode(node);
}
visitSetField(cps_ir.SetField node) {
unexpectedNode(node);
}
visitSetStatic(cps_ir.SetStatic node) {
unexpectedNode(node);
}
@override
visitForeignCode(cps_ir.ForeignCode node) {
if (node.continuation != null) {

View file

@ -37,7 +37,7 @@ class MutableVariablePreanalysis extends RecursiveVisitor {
variableDepth[node.variable] = currentDepth;
}
void processSetMutableVariable(SetMutableVariable node) {
void processSetMutable(SetMutable node) {
MutableVariable variable = node.variable.definition;
if (currentDepth > variableDepth[variable]) {
hasAssignmentInTry.add(variable);
@ -155,17 +155,19 @@ class MutableVariableEliminator implements Pass {
// Remove the mutable variable binding.
node.value.unlink();
removeNode(node);
} else if (node is SetMutableVariable &&
shouldRewrite(node.variable.definition)) {
// As above, update the environment, preserve variables and remove
// the mutable variable assignment.
MutableVariable variable = node.variable.definition;
environment[variable] = node.value.definition;
mergeHints(variable, node.value.definition);
node.value.unlink();
removeNode(node);
} else if (node is LetPrim && node.primitive is GetMutableVariable) {
GetMutableVariable getter = node.primitive;
} else if (node is LetPrim && node.primitive is SetMutable) {
SetMutable setter = node.primitive;
MutableVariable variable = setter.variable.definition;
if (shouldRewrite(variable)) {
// As above, update the environment, preserve variables and remove
// the mutable variable assignment.
environment[variable] = setter.value.definition;
mergeHints(variable, setter.value.definition);
setter.value.unlink();
removeNode(node);
}
} else if (node is LetPrim && node.primitive is GetMutable) {
GetMutable getter = node.primitive;
MutableVariable variable = getter.variable.definition;
if (shouldRewrite(variable)) {
// Replace with the reaching definition from the environment.

View file

@ -574,9 +574,8 @@ class ParentVisitor extends RecursiveVisitor {
node.value.parent = node;
}
processSetMutableVariable(SetMutableVariable node) {
processSetMutable(SetMutable node) {
node.variable.parent = node;
node.body.parent = node;
node.value.parent = node;
}
@ -623,7 +622,6 @@ class ParentVisitor extends RecursiveVisitor {
processSetField(SetField node) {
node.object.parent = node;
node.value.parent = node;
node.body.parent = node;
}
processGetField(GetField node) {
@ -635,10 +633,9 @@ class ParentVisitor extends RecursiveVisitor {
processSetStatic(SetStatic node) {
node.value.parent = node;
node.body.parent = node;
}
processGetMutableVariable(GetMutableVariable node) {
processGetMutable(GetMutable node) {
node.variable.parent = node;
}

View file

@ -832,12 +832,13 @@ class TransformingVisitor extends RecursiveVisitor {
if (target.isFinal) return false;
assert(cont.parameters.single.hasNoUses);
cont.parameters.clear();
SetField set = new SetField(getDartReceiver(node),
target,
getDartArgument(node, 0));
set.body = new InvokeContinuation(cont, <Primitive>[]);
replaceSubtree(node, set);
visitSetField(set);
CpsFragment cps = new CpsFragment(node.sourceInformation);
cps.letPrim(new SetField(getDartReceiver(node),
target,
getDartArgument(node, 0)));
cps.invokeContinuation(cont);
replaceSubtree(node, cps.result);
visit(cps.result);
return true;
}
}
@ -1052,8 +1053,7 @@ class TransformingVisitor extends RecursiveVisitor {
// that variable name for the mutable variable.
current.hint = result.hint;
}
LetPrim let =
makeLetPrimInvoke(new GetMutableVariable(current), useCont);
LetPrim let = makeLetPrimInvoke(new GetMutable(current), useCont);
replaceSubtree(use, let);
} else {
assert (use.selector == moveNextSelector);
@ -2006,9 +2006,8 @@ class TypePropagationVisitor implements Visitor {
}
}
void visitSetMutableVariable(SetMutableVariable node) {
void visitSetMutable(SetMutable node) {
setValue(node.variable.definition, getValue(node.value.definition));
setReachable(node.body);
}
void visitLiteralList(LiteralList node) {
@ -2040,7 +2039,7 @@ class TypePropagationVisitor implements Visitor {
setValue(node, constantValue(constant, typeSystem.functionType));
}
void visitGetMutableVariable(GetMutableVariable node) {
void visitGetMutable(GetMutable node) {
setValue(node, getValue(node.variable.definition));
}
@ -2096,9 +2095,7 @@ class TypePropagationVisitor implements Visitor {
}
}
void visitSetStatic(SetStatic node) {
setReachable(node.body);
}
void visitSetStatic(SetStatic node) {}
void visitGetLazyStatic(GetLazyStatic node) {
Continuation cont = node.continuation.definition;
@ -2126,9 +2123,7 @@ class TypePropagationVisitor implements Visitor {
setValue(node, nonConstant(typeSystem.getFieldType(node.field)));
}
void visitSetField(SetField node) {
setReachable(node.body);
}
void visitSetField(SetField node) {}
void visitCreateBox(CreateBox node) {
setValue(node, nonConstant(typeSystem.nonNullType));

View file

@ -258,12 +258,10 @@ class Builder implements cps_ir.Visitor<Node> {
internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node');
}
Statement visitSetField(cps_ir.SetField node) {
return new ExpressionStatement(
new SetField(getVariableUse(node.object),
node.field,
getVariableUse(node.value)),
visit(node.body));
Expression visitSetField(cps_ir.SetField node) {
return new SetField(getVariableUse(node.object),
node.field,
getVariableUse(node.value));
}
Expression visitInterceptor(cps_ir.Interceptor node) {
@ -300,12 +298,12 @@ class Builder implements cps_ir.Visitor<Node> {
Statement visitLetPrim(cps_ir.LetPrim node) {
Variable variable = getVariable(node.primitive);
// Don't translate unused primitives.
if (variable == null) return visit(node.body);
Expression value = visit(node.primitive);
return Assign.makeStatement(variable, value, visit(node.body));
if (node.primitive.hasAtLeastOneUse) {
return Assign.makeStatement(variable, value, visit(node.body));
} else {
return new ExpressionStatement(value, visit(node.body));
}
}
Statement visitLetCont(cps_ir.LetCont node) {
@ -412,14 +410,14 @@ class Builder implements cps_ir.Visitor<Node> {
return Assign.makeStatement(variable, value, body);
}
Expression visitGetMutableVariable(cps_ir.GetMutableVariable node) {
Expression visitGetMutable(cps_ir.GetMutable node) {
return getMutableVariableUse(node.variable);
}
Statement visitSetMutableVariable(cps_ir.SetMutableVariable node) {
Expression visitSetMutable(cps_ir.SetMutable node) {
Variable variable = getMutableVariable(node.variable.definition);
Expression value = getVariableUse(node.value);
return Assign.makeStatement(variable, value, visit(node.body));
return new Assign(variable, value);
}
Statement visitTypeCast(cps_ir.TypeCast node) {
@ -586,12 +584,11 @@ class Builder implements cps_ir.Visitor<Node> {
return continueWithExpression(node.continuation, value);
}
Statement visitSetStatic(cps_ir.SetStatic node) {
SetStatic setStatic = new SetStatic(
Expression visitSetStatic(cps_ir.SetStatic node) {
return new SetStatic(
node.element,
getVariableUse(node.value),
node.sourceInformation);
return new ExpressionStatement(setStatic, visit(node.body));
}
Expression visitApplyBuiltinOperator(cps_ir.ApplyBuiltinOperator node) {

View file

@ -134,25 +134,27 @@ class SExpressionUnstringifier {
static const String LET_PRIM = "LetPrim";
static const String LET_CONT = "LetCont";
static const String LET_MUTABLE = "LetMutable";
static const String SET_MUTABLE_VARIABLE = "SetMutableVariable";
static const String TYPE_CAST = "TypeCast";
static const String SET_STATIC = "SetStatic";
static const String GET_LAZY_STATIC = "GetLazyStatic";
static const String UNREACHABLE = "Unreachable";
// Primitives
static const String CONSTANT = "Constant";
static const String CREATE_FUNCTION = "CreateFunction";
static const String GET_MUTABLE_VARIABLE = "GetMutableVariable";
static const String GET_MUTABLE = "GetMutable";
static const String SET_MUTABLE = "SetMutable";
static const String LITERAL_LIST = "LiteralList";
static const String LITERAL_MAP = "LiteralMap";
static const String REIFY_TYPE_VAR = "ReifyTypeVar";
static const String GET_STATIC = "GetStatic";
static const String SET_STATIC = "SetStatic";
static const String TYPE_TEST = "TypeTest";
static const String APPLY_BUILTIN_OPERATOR = "ApplyBuiltinOperator";
static const String GET_LENGTH = "GetLength";
static const String GET_INDEX = "GetIndex";
static const String SET_INDEX = "SetIndex";
static const String GET_FIELD = "GetField";
static const String SET_FIELD = "SetField";
// Other
static const String FUNCTION_DEFINITION = "FunctionDefinition";
@ -251,12 +253,8 @@ class SExpressionUnstringifier {
return parseLetCont();
case LET_MUTABLE:
return parseLetMutable();
case SET_MUTABLE_VARIABLE:
return parseSetMutableVariable();
case TYPE_CAST:
return parseTypeCast();
case SET_STATIC:
return parseSetStatic();
case GET_LAZY_STATIC:
return parseGetLazyStatic();
case UNREACHABLE:
@ -546,19 +544,16 @@ class SExpressionUnstringifier {
return new LetMutable(local, value)..plug(body);
}
/// (SetMutableVariable name value body)
SetMutableVariable parseSetMutableVariable() {
tokens.consumeStart(SET_MUTABLE_VARIABLE);
/// (SetMutable name value)
SetMutable parseSetMutable() {
tokens.consumeStart(SET_MUTABLE);
MutableVariable local = name2variable[tokens.read()];
Primitive value = name2variable[tokens.read()];
assert(value != null);
Expression body = parseExpression();
tokens.consumeEnd();
return new SetMutableVariable(local, value)
..plug(body);
return new SetMutable(local, value);
}
/// (TypeCast value type args cont)
@ -640,17 +635,16 @@ class SExpressionUnstringifier {
return new SetIndex(object, index, value);
}
/// (SetStatic field value body)
/// (SetStatic field value)
SetStatic parseSetStatic() {
tokens.consumeStart(SET_STATIC);
Element fieldElement = new DummyElement(tokens.read());
Primitive value = name2variable[tokens.read()];
assert(value != null);
Expression body = parseExpression();
tokens.consumeEnd();
return new SetStatic(fieldElement, value, null)..plug(body);
return new SetStatic(fieldElement, value, null);
}
/// (GetLazyStatic field cont)
@ -700,8 +694,10 @@ class SExpressionUnstringifier {
return parseConstant();
case CREATE_FUNCTION:
return parseCreateFunction();
case GET_MUTABLE_VARIABLE:
return parseGetMutableVariable();
case GET_MUTABLE:
return parseGetMutable();
case SET_MUTABLE:
return parseSetMutable();
case LITERAL_LIST:
return parseLiteralList();
case LITERAL_MAP:
@ -710,6 +706,8 @@ class SExpressionUnstringifier {
return parseReifyTypeVar();
case GET_STATIC:
return parseGetStatic();
case SET_STATIC:
return parseSetStatic();
case TYPE_TEST:
return parseTypeTest();
case APPLY_BUILTIN_OPERATOR:
@ -720,6 +718,10 @@ class SExpressionUnstringifier {
return parseGetIndex();
case SET_INDEX:
return parseSetIndex();
case GET_FIELD:
return parseGetField();
case SET_FIELD:
return parseSetField();
default:
assert(false);
}
@ -803,13 +805,13 @@ class SExpressionUnstringifier {
return variable;
}
/// (GetMutableVariable name)
GetMutableVariable parseGetMutableVariable() {
tokens.consumeStart(GET_MUTABLE_VARIABLE);
/// (GetMutable name)
GetMutable parseGetMutable() {
tokens.consumeStart(GET_MUTABLE);
MutableVariable local = name2variable[tokens.read()];
tokens.consumeEnd();
return new GetMutableVariable(local);
return new GetMutable(local);
}
/// (LiteralList (values))
@ -855,4 +857,27 @@ class SExpressionUnstringifier {
tokens.consumeEnd();
return new GetStatic(field, null);
}
/// (GetField object field)
GetField parseGetField() {
tokens.consumeStart(GET_FIELD);
Primitive object = name2variable[tokens.read()];
Element field = new DummyElement(tokens.read());
tokens.consumeEnd();
return new GetField(object, field);
}
/// (SetField object field value)
SetField parseSetField() {
tokens.consumeStart(SET_FIELD);
Primitive object = name2variable[tokens.read()];
Element field = new DummyElement(tokens.read());
Primitive value = name2variable[tokens.read()];
tokens.consumeEnd();
return new SetField(object, field, value);
}
}