mirror of
https://git.sfja.dk/Mikkel/slige.git
synced 2025-01-18 09:46:30 +00:00
59 lines
1.4 KiB
TypeScript
59 lines
1.4 KiB
TypeScript
import { VType } from "../vtype.ts";
|
|
import { Fn, Local, Mir, replaceBlockSrcs, RValue } from "./mir.ts";
|
|
|
|
export function makeMoveCopyExplicit(mir: Mir) {
|
|
for (const fn of mir.fns) {
|
|
for (const local of fn.locals) {
|
|
new LocalExpliciter(fn, local).pass();
|
|
}
|
|
}
|
|
}
|
|
|
|
class LocalExpliciter {
|
|
private copyable: boolean;
|
|
|
|
public constructor(private fn: Fn, private local: Local) {
|
|
this.copyable = copyableIsType(local.vtype);
|
|
}
|
|
|
|
public pass() {
|
|
for (const block of this.fn.blocks) {
|
|
replaceBlockSrcs(block, (src) => this.explicitSrc(src));
|
|
}
|
|
}
|
|
|
|
private explicitSrc(src: RValue): RValue {
|
|
if (src.type !== "local") {
|
|
return src;
|
|
}
|
|
return this.copyable
|
|
? { type: "copy", id: src.id }
|
|
: { type: "move", id: src.id };
|
|
}
|
|
}
|
|
|
|
function copyableIsType(vtype: VType): boolean {
|
|
switch (vtype.type) {
|
|
case "error":
|
|
case "unknown":
|
|
throw new Error();
|
|
case "null":
|
|
case "int":
|
|
case "bool":
|
|
case "string":
|
|
case "ref":
|
|
case "ref_mut":
|
|
case "ptr":
|
|
case "ptr_mut":
|
|
return true;
|
|
case "array":
|
|
case "struct":
|
|
case "fn":
|
|
return false;
|
|
case "generic":
|
|
return false;
|
|
case "generic_spec":
|
|
throw new Error();
|
|
}
|
|
}
|