Skip to content

Commit ccf040e

Browse files
committed
arm64 implementation that segfaults
1 parent b364df7 commit ccf040e

File tree

2 files changed

+136
-9
lines changed

2 files changed

+136
-9
lines changed

examples/exceptions.cal

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
include "cores/select.cal"
22
include "std/io.cal"
33

4-
func __uxn_exception begin
4+
func __arm64_exception begin
55
&_cal_exception Exception.msg + Array.length + @ printdec new_line
66
&_cal_exception Exception.msg + Array.memberSize + @ printdec new_line
77
&_cal_exception Exception.msg + Array.elements + @ printdec new_line
@@ -16,9 +16,9 @@ func error foo begin
1616
c"hi im an exception" throw
1717
end
1818

19-
#try foo
20-
#catch
21-
# exception_msg printstr new_line
22-
#end
19+
try foo
20+
catch
21+
exception_msg printstr new_line
22+
end
2323

2424
foo

source/backends/arm64.d

Lines changed: 131 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ private struct Word {
2424
WordType type;
2525
bool inline;
2626
Node[] inlineNodes;
27+
bool error;
2728

2829
// for C words
2930
Type[] params;
@@ -135,6 +136,8 @@ class BackendARM64 : CompilerBackend {
135136
NewConst("Exception.msg", 8);
136137
NewConst("Exception.sizeof", 24 + 8);
137138

139+
globals["_cal_exception"] = Global(GetType("Exception"), false, 0);
140+
138141
foreach (ref type ; types) {
139142
NewConst(format("%s.sizeof", type.name), cast(long) type.size);
140143
}
@@ -466,6 +469,32 @@ class BackendARM64 : CompilerBackend {
466469
output ~= format("bl __func__%s\n", node.name.Sanitise());
467470
}
468471
}
472+
473+
if (word.error) {
474+
if ("__arm64_exception" in words) {
475+
bool crash;
476+
477+
if (inScope) {
478+
crash = !words[thisFunc].error;
479+
}
480+
else {
481+
crash = true;
482+
}
483+
484+
if (crash) {
485+
output ~= format("ldr x9, =__global_%s\n", Sanitise("_cal_exception"));
486+
output ~= "ldr x9, [x9]\n";
487+
output ~= "cmp x9, #0\n";
488+
output ~= format("bne __func__%s\n", Sanitise("__arm64_exception"));
489+
}
490+
else {
491+
CompileReturn(node);
492+
}
493+
}
494+
else {
495+
Warn(node.error, "No exception handler");
496+
}
497+
}
469498
}
470499
else if (VariableExists(node.name)) {
471500
auto var = GetVariable(node.name);
@@ -531,13 +560,23 @@ class BackendARM64 : CompilerBackend {
531560
thisFunc = node.name;
532561

533562
if (node.inline) {
534-
words[node.name] = Word(WordType.Callisto, true, node.nodes);
563+
if (node.errors) {
564+
output ~= format("ldr x9, =__global_%s\n", Sanitise("_cal_exception"));
565+
output ~= "ldr x10, #0\n";
566+
output ~= "str x10, [x9]\n";
567+
}
568+
569+
words[node.name] = Word(
570+
WordType.Callisto, true, node.nodes
571+
);
535572
}
536573
else {
537574
assert(!inScope);
538575
inScope = true;
539576

540-
words[node.name] = Word(node.raw? WordType.Raw : WordType.Callisto , false, []);
577+
words[node.name] = Word(
578+
node.raw? WordType.Raw : WordType.Callisto , false, [], node.errors
579+
);
541580

542581
string symbol =
543582
node.raw? node.name : format("__func__%s", node.name.Sanitise());
@@ -549,6 +588,12 @@ class BackendARM64 : CompilerBackend {
549588
output ~= format("%s:\n", symbol);
550589
output ~= "str lr, [x20, #-8]!\n";
551590

591+
if (node.errors) {
592+
output ~= format("ldr x9, =__global_%s\n", Sanitise("_cal_exception"));
593+
output ~= "ldr x10, #0\n";
594+
output ~= "str x10, [x9]\n";
595+
}
596+
552597
// allocate parameters
553598
size_t paramSize = node.params.length * 8;
554599
foreach (ref type ; node.paramTypes) {
@@ -1215,6 +1260,88 @@ class BackendARM64 : CompilerBackend {
12151260
}
12161261

12171262

1218-
override void CompileTryCatch(TryCatchNode node) {}
1219-
override void CompileThrow(WordNode node) {}
1263+
override void CompileTryCatch(TryCatchNode node) {
1264+
if (node.func !in words) {
1265+
Error(node.error, "Function '%s' doesn't exist", node.func);
1266+
}
1267+
1268+
auto word = words[node.func];
1269+
1270+
if (!word.error) {
1271+
Error(node.error, "Function '%s' doesn't throw", node.func);
1272+
}
1273+
if (word.type != WordType.Callisto) {
1274+
Error(node.error, "Non-callisto functions can't throw");
1275+
}
1276+
1277+
if (word.inline) {
1278+
foreach (inode ; word.inlineNodes) {
1279+
compiler.CompileNode(inode);
1280+
}
1281+
}
1282+
else {
1283+
output ~= format("bl __func__%s\n", node.func.Sanitise());
1284+
}
1285+
1286+
++ blockCounter;
1287+
1288+
output ~= format("ldr x9, =__global_%s\n", Sanitise("_cal_exception"));
1289+
output ~= "ldr x9, [x9]\n";
1290+
output ~= "cmp x9, #0\n";
1291+
output ~= format("beq __catch_%d_end\n", blockCounter);
1292+
1293+
// create scope
1294+
auto oldVars = variables.dup;
1295+
auto oldSize = GetStackSize();
1296+
1297+
foreach (inode ; node.catchBlock) {
1298+
compiler.CompileNode(inode);
1299+
}
1300+
1301+
// remove scope
1302+
foreach (ref var ; variables) {
1303+
if (oldVars.canFind(var)) continue;
1304+
if (!var.type.hasDeinit) continue;
1305+
1306+
output ~= format("add x9, x20, #%d\n", var.offset);
1307+
output ~= "str x9, [x19], #8\n";
1308+
output ~= format("bl __type_deinit_%s\n", var.type.name.Sanitise());
1309+
}
1310+
if (GetStackSize() - oldSize > 0) {
1311+
OffsetLocalsStack(GetStackSize() - oldSize, false);
1312+
}
1313+
variables = oldVars;
1314+
1315+
output ~= format("__catch_%d_end:\n", blockCounter);
1316+
}
1317+
1318+
override void CompileThrow(WordNode node) {
1319+
if (!inScope || (!words[thisFunc].error)) {
1320+
Error(node.error, "Not in a function that can throw");
1321+
}
1322+
if (words[thisFunc].inline) {
1323+
Error(node.error, "Can't use throw in an inline function");
1324+
}
1325+
1326+
// set exception error
1327+
output ~= format("ldr x9, =__global_%s\n", Sanitise("_cal_exception"));
1328+
output ~= "mov x10, 0xFFFFFFFFFFFFFFFF\n";
1329+
output ~= "str x10, [x9]\n";
1330+
1331+
// copy exception message
1332+
output ~= "sub x19, x19, #8\n";
1333+
output ~= "mov x10, x19\n";
1334+
output ~= "add x11, x9, #8\n";
1335+
output ~= "mov x12, #3\n";
1336+
// copy x10 to x11, x12 times
1337+
output ~= "1:\n";
1338+
output ~= "ldr x13, [x10]\n";
1339+
output ~= "str x13, [x11]\n";
1340+
output ~= "add x10, x10, #8\n";
1341+
output ~= "add x11, x11, #8\n";
1342+
output ~= "sub x12, x12, #1\n";
1343+
output ~= "bne 1b\n";
1344+
1345+
CompileReturn(node);
1346+
}
12201347
}

0 commit comments

Comments
 (0)