[dart2wasm] Implement as check.

Change-Id: Iadf187ccc4d243a1b46491fbf99c2f740db9c6fa
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/239920
Reviewed-by: Aske Simon Christensen <askesc@google.com>
Commit-Queue: Joshua Litt <joshualitt@google.com>
This commit is contained in:
Joshua Litt 2022-04-04 19:17:52 +00:00 committed by Commit Bot
parent 434aac2fb5
commit df512fefe9
3 changed files with 29 additions and 2 deletions

View file

@ -2092,8 +2092,23 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
@override
w.ValueType visitAsExpression(AsExpression node, w.ValueType expectedType) {
// TODO(joshualitt): Emit type test and throw exception on failure
return wrap(node.operand, expectedType);
w.Label asCheckBlock = b.block();
wrap(node.operand, translator.topInfo.nullableType);
w.Local operand = addLocal(translator.topInfo.nullableType);
b.local_tee(operand);
// We lower an `as` expression to a type test, throwing a [TypeError] if
// the type test fails.
emitTypeTest(node.type, dartTypeOf(node.operand), node);
b.br_if(asCheckBlock);
b.local_get(operand);
_makeType(node.type, node);
_call(translator.stackTraceCurrent.reference);
_call(translator.throwAsCheckError.reference);
b.unreachable();
b.end();
b.local_get(operand);
return operand.type;
}
}

View file

@ -95,6 +95,7 @@ class Translator {
late final Procedure stringEquals;
late final Procedure stringInterpolate;
late final Procedure throwNullCheckError;
late final Procedure throwAsCheckError;
late final Procedure mapFactory;
late final Procedure mapPut;
late final Procedure immutableMapIndexNullable;
@ -192,6 +193,8 @@ class Translator {
.firstWhere((p) => p.name.text == "_interpolate");
throwNullCheckError = typeErrorClass.procedures
.firstWhere((p) => p.name.text == "_throwNullCheckError");
throwAsCheckError = typeErrorClass.procedures
.firstWhere((p) => p.name.text == "_throwAsCheckError");
mapFactory = lookupCollection("LinkedHashMap").procedures.firstWhere(
(p) => p.kind == ProcedureKind.Factory && p.name.text == "_default");
mapPut = lookupCollection("_CompactLinkedCustomHashMap")

View file

@ -56,4 +56,13 @@ class _TypeError extends _Error implements TypeError {
"Null check operator used on a null value", stackTrace);
return _throwObjectWithStackTrace(typeError, stackTrace);
}
@pragma("wasm:entry-point")
static Never _throwAsCheckError(
Object? operand, Type? type, StackTrace stackTrace) {
final typeError = _TypeError.fromMessageAndStackTrace(
"Type '${operand.runtimeType}' is not a subtype of type '$type' in type cast",
stackTrace);
return _throwObjectWithStackTrace(typeError, stackTrace);
}
}