Skip to content

Commit b88ccc4

Browse files
committed
rm86
1 parent a8bff2a commit b88ccc4

File tree

4 files changed

+117
-8
lines changed

4 files changed

+117
-8
lines changed

examples/exceptions.cal

Lines changed: 1 addition & 1 deletion
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 __x86_64_exception begin
4+
func __rm86_exception begin
55
&_cal_exception Exception.msg + "Unhandled exception: %s" printf new_line
66
1 exit
77
end

examples/test/multithreading.cal

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func new_thread addr function begin
4646
dup printdec new_line
4747

4848
if 0 = then
49-
# stinky winky callisto runtime just to get stuff working
49+
# stinky callisto runtime just to get stuff working
5050
asm
5151
"sub rsp, 4096"
5252
"mov r15, rsp"

source/backends/rm86.d

Lines changed: 114 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ private struct Word {
1515
bool raw;
1616
bool inline;
1717
Node[] inlineNodes;
18+
bool error;
1819
}
1920

2021
private struct StructEntry {
@@ -121,6 +122,8 @@ class BackendRM86 : CompilerBackend {
121122
globals["__rm86_argv"] = Global(GetType("addr"), false, 0);
122123
globals["__rm86_arglen"] = Global(GetType("cell"), false, 0);
123124
}
125+
126+
globals["_cal_exception"] = Global(GetType("Exception"), false, 0);
124127
}
125128

126129
override void NewConst(string name, long value, ErrorInfo error = ErrorInfo.init) {
@@ -179,7 +182,7 @@ class BackendRM86 : CompilerBackend {
179182
"RM86", "LittleEndian", "16Bit",
180183
// features
181184
"IO"
182-
] ~ (os == "dos"? ["DOS", "Args"] : os == "bare-metal"? ["BareMetal"] : []);
185+
] ~ (os == "dos"? ["DOS", "Args", "Exit"] : os == "bare-metal"? ["BareMetal"] : []);
183186

184187
override string[] FinalCommands() => [
185188
format("mv %s %s.asm", compiler.outFile, compiler.outFile),
@@ -330,6 +333,32 @@ class BackendRM86 : CompilerBackend {
330333
output ~= format("call __func__%s\n", node.name.Sanitise());
331334
}
332335
}
336+
337+
if (word.error) {
338+
if ("__rm86_exception" in words) {
339+
bool crash;
340+
341+
if (inScope) {
342+
crash = !words[thisFunc].error;
343+
}
344+
else {
345+
crash = true;
346+
}
347+
348+
if (crash) {
349+
output ~= format("mov bx, __global_%s\n", Sanitise("_cal_exception"));
350+
output ~= "mov ax, [bx]\n";
351+
output ~= "cmp ax, 0\n";
352+
output ~= format("jne __func__%s\n", Sanitise("__rm86_exception"));
353+
}
354+
else {
355+
CompileReturn(node);
356+
}
357+
}
358+
else {
359+
Warn(node.error, "No exception handler");
360+
}
361+
}
333362
}
334363
else if (VariableExists(node.name)) {
335364
auto var = GetVariable(node.name);
@@ -405,19 +434,27 @@ class BackendRM86 : CompilerBackend {
405434
thisFunc = node.name;
406435

407436
if (node.inline) {
408-
words[node.name] = Word(false, true, node.nodes);
437+
if (node.errors) {
438+
output ~= format("mov word [__global_%s], 0\n", Sanitise("_cal_exception"));
439+
}
440+
441+
words[node.name] = Word(false, true, node.nodes, node.errors);
409442
}
410443
else {
411444
assert(!inScope);
412445
inScope = true;
413446

414-
words[node.name] = Word(node.raw, false, []);
447+
words[node.name] = Word(node.raw, false, [], node.errors);
415448

416449
string symbol =
417450
node.raw? node.name : format("__func__%s", node.name.Sanitise());
418451

419452
output ~= format("%s:\n", symbol);
420453

454+
if (node.errors) {
455+
output ~= format("mov word [__global_%s], 0\n", Sanitise("_cal_exception"));
456+
}
457+
421458
// allocate parameters
422459
size_t paramSize = node.params.length * 2;
423460
foreach (ref type ; node.paramTypes) {
@@ -1073,6 +1110,78 @@ class BackendRM86 : CompilerBackend {
10731110
}
10741111
}
10751112

1076-
override void CompileTryCatch(TryCatchNode node) {}
1077-
override void CompileThrow(WordNode node) {}
1113+
override void CompileTryCatch(TryCatchNode node) {
1114+
if (node.func !in words) {
1115+
Error(node.error, "Function '%s' doesn't exist", node.func);
1116+
}
1117+
1118+
auto word = words[node.func];
1119+
1120+
if (!word.error) {
1121+
Error(node.error, "Function '%s' doesn't throw", node.func);
1122+
}
1123+
if (word.raw) {
1124+
Error(node.error, "Non-callisto functions can't throw");
1125+
}
1126+
1127+
if (word.inline) {
1128+
foreach (inode ; word.inlineNodes) {
1129+
compiler.CompileNode(inode);
1130+
}
1131+
}
1132+
else {
1133+
output ~= format("call __func__%s\n", node.func.Sanitise());
1134+
}
1135+
1136+
++ blockCounter;
1137+
1138+
output ~= format("mov ax, [__global_%s]\n", Sanitise("_cal_exception"));
1139+
output ~= "cmp ax, 0\n";
1140+
output ~= format("je __catch_%d_end\n", blockCounter);
1141+
1142+
// create scope
1143+
auto oldVars = variables.dup;
1144+
auto oldSize = GetStackSize();
1145+
1146+
foreach (inode ; node.catchBlock) {
1147+
compiler.CompileNode(inode);
1148+
}
1149+
1150+
// remove scope
1151+
foreach (ref var ; variables) {
1152+
if (oldVars.canFind(var)) continue;
1153+
if (!var.type.hasDeinit) continue;
1154+
1155+
output ~= format("lea ax, [sp + %d\n]", var.offset);
1156+
output ~= "mov [si], ax\n";
1157+
output ~= "add si, 2\n";
1158+
output ~= format("call __type_deinit_%s\n", Sanitise(var.type.name));
1159+
}
1160+
if (GetStackSize() - oldSize > 0) {
1161+
output ~= format("add sp, %d\n", GetStackSize() - oldSize);
1162+
}
1163+
variables = oldVars;
1164+
1165+
output ~= format("__catch_%d_end:\n", blockCounter);
1166+
}
1167+
1168+
override void CompileThrow(WordNode node) {
1169+
if (!inScope || (!words[thisFunc].error)) {
1170+
Error(node.error, "Not in a function that can throw");
1171+
}
1172+
1173+
// set exception error
1174+
output ~= format("mov word [__global_%s], 0xFFFF\n", Sanitise("_cal_exception"));
1175+
1176+
// copy exception message
1177+
output ~= "sub si, 2\n";
1178+
output ~= "mov bx, si\n";
1179+
output ~= "mov si, [bx]\n";
1180+
output ~= format("lea di, [__global_%s + 2]\n", Sanitise("_cal_exception"));
1181+
output ~= "mov cx, 3\n";
1182+
output ~= "rep movsw\n";
1183+
output ~= "mov si, bx\n";
1184+
1185+
CompileReturn(node);
1186+
}
10781187
}

0 commit comments

Comments
 (0)