Chromium Code Reviews| Index: frog/leg/ssa/codegen.dart |
| =================================================================== |
| --- frog/leg/ssa/codegen.dart (revision 5830) |
| +++ frog/leg/ssa/codegen.dart (working copy) |
| @@ -1127,12 +1127,42 @@ |
| } |
| void checkType(HInstruction input, Element element) { |
| - buffer.add('!!'); |
| + bool requiresNativeIsCheck = |
| + compiler.emitter.nativeEmitter.requiresNativeIsCheck(element); |
| + if (!requiresNativeIsCheck) buffer.add('!!'); |
| use(input, JSPrecedence.MEMBER_PRECEDENCE); |
| buffer.add('.'); |
| buffer.add(compiler.namer.operatorIs(element)); |
| + if (requiresNativeIsCheck) buffer.add('()'); |
| } |
| + void handleStringSupertypeCheck(HInstruction input, Element element) { |
| + assert(element !== compiler.listClass |
| + && Elements.isListSupertype(element, compiler)); |
|
floitsch
2012/03/26 20:32:59
I don't understand this assert.
ngeoffray
2012/03/27 10:48:53
It's to make sure List and String don't share supe
floitsch
2012/03/28 21:19:01
You also added a "!" ;)
ngeoffray
2012/03/29 08:27:16
Busted :)
|
| + beginExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE); |
| + checkString(input, '==='); |
| + buffer.add(' || '); |
| + beginExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE); |
| + checkObject(input, '==='); |
| + buffer.add(' && '); |
| + checkType(input, element); |
| + endExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE); |
| + endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE); |
| + } |
| + |
| + void handleListOrSupertypeCheck(HInstruction input, Element element) { |
| + beginExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE); |
| + checkObject(input, '==='); |
| + buffer.add(' && ('); |
| + beginExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE); |
| + checkArray(input, '==='); |
| + buffer.add(' || '); |
| + checkType(input, element); |
| + buffer.add(')'); |
| + endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE); |
| + endExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE); |
| + } |
| + |
| void visitIs(HIs node) { |
| Element element = node.typeExpression; |
| if (element.kind === ElementKind.TYPE_VARIABLE) { |
| @@ -1147,6 +1177,7 @@ |
| checkNull(input); |
| buffer.add(' || '); |
| } |
| + |
| if (element === objectClass || element === compiler.dynamicClass) { |
| // The constant folder also does this optimization, but we make |
| // it safe by assuming it may have not run. |
| @@ -1167,77 +1198,23 @@ |
| buffer.add(' && '); |
| checkInt(input, '==='); |
| endExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE); |
| + } else if (Elements.isStringSupertype(element, compiler)) { |
| + handleStringSupertypeCheck(input, element); |
| + } else if (element === compiler.listClass |
| + || Elements.isListSupertype(element, compiler)) { |
| + handleListOrSupertypeCheck(input, element); |
| } else { |
| beginExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE); |
| - if (Elements.isStringSupertype(element, compiler)) { |
| - checkString(input, '==='); |
| - buffer.add(' || '); |
| - } |
| checkObject(input, '==='); |
| buffer.add(' && '); |
| - int precedence = JSPrecedence.PREFIX_PRECEDENCE; |
| - bool endParen = false; |
| - if (element === compiler.listClass |
| - || Elements.isListSupertype(element, compiler)) { |
| - buffer.add("("); |
| - endParen = true; |
| - beginExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE); |
| - checkArray(input, '==='); |
| - buffer.add(' || '); |
| - precedence = JSPrecedence.LOGICAL_OR_PRECEDENCE; |
| - } else if (element.isClass() && (element.dynamic.isNative() |
| - || isSupertypeOfNativeClass(element))) { |
| - buffer.add("("); |
| - endParen = true; |
| - } else { |
| - beginExpression(precedence); |
| - } |
| - checkType(input, node.typeExpression); |
| - if (element.isClass() && (element.dynamic.isNative() |
| - || isSupertypeOfNativeClass(element))) { |
| - buffer.add(' || '); |
| - beginExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE); |
| - // First check if the object is not a Dart object. If the |
| - // object is a Dart object, we know the property check was |
| - // sufficient. |
| - compiler.registerIsCheck(objectClass); |
| - buffer.add('!'); |
| - use(input, JSPrecedence.MEMBER_PRECEDENCE); |
| - buffer.add('.'); |
| - buffer.add(compiler.namer.operatorIs(objectClass)); |
| - buffer.add(' && '); |
| - buffer.add(compiler.emitter.nativeEmitter.dynamicIsCheckName); |
| - buffer.add('('); |
| - use(input, JSPrecedence.MEMBER_PRECEDENCE); |
| - buffer.add(", '${compiler.namer.operatorIs(node.typeExpression)}')"); |
| - endExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE); |
| - } |
| - endExpression(precedence); |
| - if (endParen) buffer.add(')'); |
| + checkType(input, element); |
| endExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE); |
| } |
| + |
| if (node.nullOk) { |
| endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE); |
| } |
| } |
| - |
| - bool isSupertypeOfNativeClass(Element element) { |
| - if (element.isTypeVariable()) { |
| - compiler.cancel("Is check for type variable", element: work.element); |
| - return false; |
| - } |
| - if (element.computeType(compiler) is FunctionType) return false; |
| - |
| - if (!element.isClass()) { |
| - compiler.cancel("Is check does not handle element", element: element); |
| - return false; |
| - } |
| - |
| - List<ClassElement> subtypes = |
| - compiler.emitter.nativeEmitter.subtypes[element]; |
| - if (subtypes === null) return false; |
| - return true; |
| - } |
| } |
| class SsaOptimizedCodeGenerator extends SsaCodeGenerator { |