mirror of
https://github.com/dart-lang/sdk
synced 2024-09-04 16:03:44 +00:00
[dart2wasm] Implement noSuchMethod on null receivers
New passing tests: - language/closure/tearoff_dynamic_test - language/no_such_method/native_test Change-Id: I42449f3e238ab5ecd02504d65ff1a696a76bb7a3 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/307800 Reviewed-by: Aske Simon Christensen <askesc@google.com> Commit-Queue: Ömer Ağacan <omersa@google.com>
This commit is contained in:
parent
46c0a9d43b
commit
e8f370ca4e
|
@ -1527,31 +1527,46 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
|
|||
w.ValueType? intrinsicResult = intrinsifier.generateInstanceIntrinsic(node);
|
||||
if (intrinsicResult != null) return intrinsicResult;
|
||||
|
||||
Procedure target = node.interfaceTarget;
|
||||
w.ValueType callWithNullCheck(
|
||||
Procedure target, void Function(w.ValueType) onNull) {
|
||||
late w.Label done;
|
||||
final w.ValueType resultType =
|
||||
_virtualCall(node, target, _VirtualCallKind.Call, (signature) {
|
||||
done = b.block(const [], signature.outputs);
|
||||
final w.Label nullReceiver = b.block();
|
||||
wrap(node.receiver, translator.topInfo.nullableType);
|
||||
b.br_on_null(nullReceiver);
|
||||
}, (_) {
|
||||
_visitArguments(node.arguments, node.interfaceTargetReference, 1);
|
||||
});
|
||||
b.br(done);
|
||||
b.end(); // end nullReceiver
|
||||
onNull(resultType);
|
||||
b.end();
|
||||
return resultType;
|
||||
}
|
||||
|
||||
final Procedure target = node.interfaceTarget;
|
||||
if (node.kind == InstanceAccessKind.Object) {
|
||||
switch (target.name.text) {
|
||||
case "toString":
|
||||
late w.Label done;
|
||||
w.ValueType resultType =
|
||||
_virtualCall(node, target, _VirtualCallKind.Call, (signature) {
|
||||
done = b.block(const [], signature.outputs);
|
||||
w.Label nullString = b.block();
|
||||
wrap(node.receiver, translator.topInfo.nullableType);
|
||||
b.br_on_null(nullString);
|
||||
}, (_) {
|
||||
return callWithNullCheck(
|
||||
target, (resultType) => wrap(StringLiteral("null"), resultType));
|
||||
case "noSuchMethod":
|
||||
return callWithNullCheck(target, (resultType) {
|
||||
// Object? receiver
|
||||
b.ref_null(translator.topInfo.struct);
|
||||
// Invocation invocation
|
||||
_visitArguments(node.arguments, node.interfaceTargetReference, 1);
|
||||
call(translator.noSuchMethodErrorThrowWithInvocation.reference);
|
||||
});
|
||||
b.br(done);
|
||||
b.end();
|
||||
wrap(StringLiteral("null"), resultType);
|
||||
b.end();
|
||||
return resultType;
|
||||
default:
|
||||
unimplemented(node, "Nullable invocation of ${target.name.text}",
|
||||
[if (expectedType != voidMarker) expectedType]);
|
||||
return expectedType;
|
||||
}
|
||||
}
|
||||
|
||||
Member? singleTarget = translator.singleTarget(node);
|
||||
if (singleTarget != null) {
|
||||
w.BaseFunction targetFunction =
|
||||
|
|
Loading…
Reference in a new issue