Index: pkg/compiler/lib/src/js_backend/codegen/type_test_emitter.dart |
diff --git a/pkg/compiler/lib/src/js_backend/codegen/type_test_emitter.dart b/pkg/compiler/lib/src/js_backend/codegen/type_test_emitter.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..49b28e6caa8a505879994f44c4f38aa0a1b46939 |
--- /dev/null |
+++ b/pkg/compiler/lib/src/js_backend/codegen/type_test_emitter.dart |
@@ -0,0 +1,63 @@ |
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+part of code_generator; |
+ |
+abstract class TypeTestEmitter { |
+ giveup(node, reason); |
+ Glue get glue; |
+ |
+ js.Expression emitSubtypeTest(tree_ir.Node node, |
+ js.Expression value, |
+ DartType type) { |
+ return glue.isNativePrimitiveType(type) |
+ ? emitNativeSubtypeTest(node, value, type.element) |
+ : emitGeneralSubtypeTest(node, value, type); |
+ } |
+ |
+ js.Expression emitNativeSubtypeTest(tree_ir.Node node, |
+ js.Expression value, |
+ ClassElement cls) { |
+ if (glue.isIntClass(cls)) { |
+ return _emitIntCheck(value); |
+ } else if (glue.isStringClass(cls)) { |
+ return _emitTypeofCheck(value, 'string'); |
+ } else if (glue.isBoolClass(cls)) { |
+ return _emitTypeofCheck(value, 'boolean'); |
+ } else if (glue.isNumClass(cls) || glue.isDoubleClass(cls)) { |
+ return _emitNumCheck(value); |
+ } else { |
+ return giveup(value, 'type check unimplemented for ${cls.name}.'); |
+ } |
+ } |
+ |
+ js.Expression emitGeneralSubtypeTest(tree_ir.Node node, |
+ js.Expression value, |
+ InterfaceType type) { |
+ return new js.Binary('&&', |
+ new js.Prefix('!!', value), |
+ new js.Prefix('!!', |
+ new js.PropertyAccess.field(value, glue.getTypeTestTag(type)))); |
+ } |
+ |
+ js.Expression _emitNumCheck(js.Expression value) { |
+ return _emitTypeofCheck(value, 'number'); |
+ } |
+ |
+ js.Expression _emitBigIntCheck(js.Expression value) { |
+ return js.js('Math.floor(#) === #', [value, value]); |
+ } |
+ |
+ js.Expression _emitIntCheck(js.Expression value) { |
+ return new js.Binary('&&', |
+ _emitNumCheck(value), |
+ _emitBigIntCheck(value)); |
+ } |
+ |
+ js.Expression _emitTypeofCheck(js.Expression value, String type) { |
+ return new js.Binary('===', |
+ new js.Prefix("typeof", value), |
+ js.string(type)); |
+ } |
+} |