Skip to content

Commit

Permalink
fix: correctly load locals from parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
zskamljic committed Dec 1, 2024
1 parent cfbebb5 commit 4e14df7
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/main/java/zskamljic/wjvern/llir/FunctionBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ private void generateCode(IrMethodGenerator generator) {
var stack = new VarStack(generator, types);
var exceptionState = new ExceptionState();
var labelGenerator = new LabelGenerator();
var locals = new Locals(generator, types, labelGenerator, generator::hasParameter);
var locals = new Locals(generator, types, labelGenerator, generator::getParameter);
String currentLabel = null;
for (var element : code) {
if (debug && !(element instanceof Label)) {
Expand Down
21 changes: 19 additions & 2 deletions src/main/java/zskamljic/wjvern/llir/IrMethodGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.OptionalInt;
import java.util.function.Predicate;
import java.util.stream.Collectors;

Expand All @@ -32,8 +33,24 @@ void addParameter(String name, LlvmType type) {
parameters.add(new Parameter(name, type));
}

boolean hasParameter(String name) {
return parameters.stream().anyMatch(e -> e.name().equals(name));
OptionalInt getParameter(int slot) {
var realParameters = parameters.stream()
.filter(Predicate.not(Parameter::isReturn))
.toList();

int currentIndex = 0;
for (int i = 0; i < realParameters.size(); i++) {
var parameter = realParameters.get(i);
var nextIndex = currentIndex + switch (parameter.type()) {
case LlvmType.Primitive.LONG, LlvmType.Primitive.DOUBLE -> 2;
default -> 1;
};
if (slot == currentIndex) return OptionalInt.of(i);

currentIndex = nextIndex;
}

return OptionalInt.empty();
}

public String alloca(LlvmType type) {
Expand Down
21 changes: 13 additions & 8 deletions src/main/java/zskamljic/wjvern/llir/Locals.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.OptionalInt;
import java.util.function.Function;

public class Locals {
public static final String LOCAL_PREFIX = "%local.";
Expand All @@ -18,9 +19,11 @@ public class Locals {
private final IrMethodGenerator generator;
private final Map<String, LlvmType> types;
private final LabelGenerator labelGenerator;
private final Predicate<String> parameterChecker;
private final Function<Integer, OptionalInt> parameterChecker;

public Locals(IrMethodGenerator generator, Map<String, LlvmType> types, LabelGenerator labelGenerator, Predicate<String> parameterChecker) {
public Locals(
IrMethodGenerator generator, Map<String, LlvmType> types, LabelGenerator labelGenerator, Function<Integer, OptionalInt> parameterChecker
) {
this.generator = generator;
this.types = types;
this.labelGenerator = labelGenerator;
Expand All @@ -32,11 +35,12 @@ public Local get(int slot) {
var name = LOCAL_PREFIX + s;
var local = new Local(name, LlvmType.Primitive.POINTER, s, null, null);
if (!types.containsKey(name)) {
if (parameterChecker.test("param." + slot)) {
var paramType = types.get(PARAM_PREFIX + slot);
var parameter = parameterChecker.apply(slot);
if (parameter.isPresent()) {
var paramType = types.get(PARAM_PREFIX + parameter.getAsInt());
var type = new LlvmType.Pointer(paramType);
generator.alloca(name, type);
generator.store(paramType, PARAM_PREFIX + slot, type, name);
generator.store(paramType, PARAM_PREFIX + parameter.getAsInt(), type, name);
types.put(name, type);
} else {
generator.alloca(name, LlvmType.Primitive.POINTER);
Expand All @@ -56,9 +60,10 @@ public void register(LocalVariable variable) {
type = new LlvmType.Pointer(type);
}

if (parameterChecker.test("param." + variable.slot())) {
var parameter = parameterChecker.apply(variable.slot());
if (parameter.isPresent()) {
generator.alloca(LOCAL_PREFIX + variable.slot(), new LlvmType.Pointer(type));
generator.store(type, PARAM_PREFIX + variable.slot(), new LlvmType.Pointer(type), LOCAL_PREFIX + variable.slot());
generator.store(type, PARAM_PREFIX + parameter.getAsInt(), new LlvmType.Pointer(type), LOCAL_PREFIX + variable.slot());
}
type = new LlvmType.Pointer(type);

Expand Down
1 change: 0 additions & 1 deletion src/main/resources/unsupported_functions.json
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@
"rotateRight",
"parseLong",
"parseUnsignedLong",
"sum",
"toHexString",
"toOctalString",
"toBinaryString",
Expand Down

0 comments on commit 4e14df7

Please sign in to comment.