| Index: sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
|
| ===================================================================
|
| --- sdk/lib/_internal/compiler/implementation/ssa/nodes.dart (revision 16030)
|
| +++ sdk/lib/_internal/compiler/implementation/ssa/nodes.dart (working copy)
|
| @@ -289,7 +289,7 @@
|
| visitGreaterEqual(HGreaterEqual node) => visitRelational(node);
|
| visitIdentity(HIdentity node) => visitRelational(node);
|
| visitIf(HIf node) => visitConditionalBranch(node);
|
| - visitIndex(HIndex node) => visitInvokeStatic(node);
|
| + visitIndex(HIndex node) => visitInstruction(node);
|
| visitIndexAssign(HIndexAssign node) => visitInvokeStatic(node);
|
| visitIntegerCheck(HIntegerCheck node) => visitCheck(node);
|
| visitInterceptor(HInterceptor node) => visitInstruction(node);
|
| @@ -1320,8 +1320,34 @@
|
| class HInvokeDynamicMethod extends HInvokeDynamic {
|
| HInvokeDynamicMethod(Selector selector, List<HInstruction> inputs)
|
| : super(selector, null, inputs);
|
| - toString() => 'invoke dynamic method: $selector';
|
| + String toString() => 'invoke dynamic method: $selector';
|
| accept(HVisitor visitor) => visitor.visitInvokeDynamicMethod(this);
|
| +
|
| + bool isIndexOperatorOnIndexablePrimitive(HTypeMap types) {
|
| + return isInterceptorCall
|
| + && selector.kind == SelectorKind.INDEX
|
| + && inputs[1].isIndexablePrimitive(types);
|
| + }
|
| +
|
| + HType computeDesiredTypeForInput(HInstruction input,
|
| + HTypeMap types,
|
| + Compiler compiler) {
|
| + // TODO(ngeoffray): Move this logic into a different class that
|
| + // will know what type it wants for a given selector.
|
| + if (selector.kind != SelectorKind.INDEX) return HType.UNKNOWN;
|
| + if (!isInterceptorCall) return HType.UNKNOWN;
|
| +
|
| + HInstruction index = inputs[2];
|
| + if (input == inputs[1] &&
|
| + (index.isTypeUnknown(types) || index.isNumber(types))) {
|
| + return HType.INDEXABLE_PRIMITIVE;
|
| + }
|
| + // The index should be an int when the receiver is a string or array.
|
| + // However it turns out that inserting an integer check in the optimized
|
| + // version is cheaper than having another bailout case. This is true,
|
| + // because the integer check will simply throw if it fails.
|
| + return HType.UNKNOWN;
|
| + }
|
| }
|
|
|
| abstract class HInvokeDynamicField extends HInvokeDynamic {
|
| @@ -2439,42 +2465,21 @@
|
| }
|
| }
|
|
|
| -class HIndex extends HInvokeStatic {
|
| - HIndex(HStatic target, HInstruction receiver, HInstruction index)
|
| - : super(<HInstruction>[target, receiver, index]);
|
| - toString() => 'index operator';
|
| +class HIndex extends HInstruction {
|
| + HIndex(HInstruction receiver, HInstruction index)
|
| + : super(<HInstruction>[receiver, index]);
|
| + String toString() => 'index operator';
|
| accept(HVisitor visitor) => visitor.visitIndex(this);
|
|
|
| void prepareGvn(HTypeMap types) {
|
| clearAllSideEffects();
|
| - if (isBuiltin(types)) {
|
| - setDependsOnIndexStore();
|
| - setUseGvn();
|
| - } else {
|
| - setAllSideEffects();
|
| - }
|
| + setDependsOnIndexStore();
|
| + setUseGvn();
|
| }
|
|
|
| - HInstruction get receiver => inputs[1];
|
| - HInstruction get index => inputs[2];
|
| + HInstruction get receiver => inputs[0];
|
| + HInstruction get index => inputs[1];
|
|
|
| - HType computeDesiredTypeForNonTargetInput(HInstruction input,
|
| - HTypeMap types,
|
| - Compiler compiler) {
|
| - if (input == receiver &&
|
| - (index.isTypeUnknown(types) || index.isNumber(types))) {
|
| - return HType.INDEXABLE_PRIMITIVE;
|
| - }
|
| - // The index should be an int when the receiver is a string or array.
|
| - // However it turns out that inserting an integer check in the optimized
|
| - // version is cheaper than having another bailout case. This is true,
|
| - // because the integer check will simply throw if it fails.
|
| - return HType.UNKNOWN;
|
| - }
|
| -
|
| - bool isBuiltin(HTypeMap types)
|
| - => receiver.isIndexablePrimitive(types) && index.isInteger(types);
|
| -
|
| int typeCode() => HInstruction.INDEX_TYPECODE;
|
| bool typeEquals(HInstruction other) => other is HIndex;
|
| bool dataEquals(HIndex other) => true;
|
|
|