[modular_aot] Code generation for NullCheck

Issue: https://github.com/dart-lang/sdk/issues/61635
Change-Id: I0a3ba9dae62514ed9330366e9e4e33b38f44e4c8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/504760
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
Alexander Markov
2026-05-20 11:42:54 -07:00
committed by dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent 25a757da3e
commit c0902a81a0
4 changed files with 36 additions and 2 deletions
@@ -818,6 +818,11 @@ final class Arm64Assembler extends Assembler with Uint32OutputBuffer {
callRuntime(RuntimeEntry.FatalError, 1);
}
@override
void breakpoint() {
brk(0);
}
/// Generate code for inline object allocation.
void inlineAllocation(
Register resultReg,
@@ -1898,6 +1903,11 @@ final class Arm64Assembler extends Assembler with Uint32OutputBuffer {
);
}
void brk(int imm) {
assert(_isUint(16, imm));
emit(B31 | B30 | B28 | B26 | B21 | (imm << 5));
}
void scvtf(
FPRegister rd,
Register rn, [
@@ -901,7 +901,17 @@ final class Arm64CodeGenerator extends CodeGenerator {
@override
void visitNullCheck(NullCheck instr) {
_asm.unimplemented('Unimplemented: code generation for NullCheck');
final operandReg = inputReg(instr, 0);
final resultReg = outputReg(instr);
if (operandReg != resultReg) {
_asm.mov(resultReg, operandReg);
}
final Label slowPath = addSlowPath(() {
_asm.callRuntime(RuntimeEntry.NullCastError, 0);
_asm.breakpoint();
});
_asm.cmp(resultReg, nullReg);
_asm.b(slowPath, .equal);
}
int _getNumberOfInputsForSubtypeTestCache(
@@ -202,6 +202,7 @@ abstract base class Assembler {
void callStub(Code stub);
void unimplemented(String message);
void breakpoint();
}
/// Assembler output buffer holding 32-bit instructions.
@@ -398,6 +398,10 @@ void main() {
'blr lr\n',
);
});
test('breakpoint', () {
asm.breakpoint();
expectDisassembly('brk #0x0\n');
});
test('inlineAllocation - object size 16', () {
final slowPath = Label();
asm.inlineAllocation(
@@ -1637,7 +1641,16 @@ void main() {
'ret r1\n',
);
});
test('brk', () {
asm.brk(0x1234);
expectDisassembly('brk #0x1234\n');
expectThrows(() {
asm.brk(-1);
});
expectThrows(() {
asm.brk(0x10000);
});
});
test('scvtf', () {
asm.scvtf(V0, R0);
asm.scvtf(V1, R2, .s32);