mirror of
https://github.com/dart-lang/sdk
synced 2024-09-19 14:51:30 +00:00
[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:
parent
434aac2fb5
commit
df512fefe9
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue