blob: 49b28e6caa8a505879994f44c4f38aa0a1b46939 [file] [log] [blame]
// 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));
}
}