Skip to content

Commit

Permalink
Support get/set locals
Browse files Browse the repository at this point in the history
  • Loading branch information
danielperano committed Dec 22, 2024
1 parent cb6265d commit 6b98997
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 1 deletion.
6 changes: 6 additions & 0 deletions Lang/src/main/java/chipmunk/compiler/assembler/Operands.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ public Operand pop(){
return new Operand(calculateRegister(), types.pop());
}

public Operand dup(){
var type = types.peek();
types.push(type);
return new Operand(calculateRegister(), type);
}

private int calculateRegister(){
return reserved + types.size() - 1;
}
Expand Down
43 changes: 42 additions & 1 deletion Lang/src/main/java/chipmunk/vm/hvm/HvmCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ public ChipmunkModule compileModule(BinaryModule module){
var code = method.getCode();

var operands = new Operands(method.getArgCount() + method.getLocalCount());
var registerStates = new RegisterStates();

var ip = 0;
while(ip < code.length){
switch (code[ip]){
// Arithmetic
case PUSH -> ip = push(builder, constants, operands, code, ip);
case ADD -> ip = add(builder, operands, ip);
case MUL -> ip = mul(builder, operands, ip);
case DIV -> ip = div(builder, operands, ip);
Expand All @@ -74,6 +74,16 @@ public ChipmunkModule compileModule(BinaryModule module){
case RSHIFT -> ip = rshift(builder, operands, ip);
case URSHIFT -> ip = urshift(builder, operands, ip);

// Stack
// Note: swap not implemented since it is currently unused by the assembler
case POP -> operands.pop();
case DUP -> operands.dup();
case PUSH -> ip = push(builder, constants, operands, code, ip);

// Locals
case GETLOCAL -> ip = getlocal(builder, operands, registerStates, code, ip);
case SETLOCAL -> ip = setlocal(builder, operands, registerStates, code, ip);

// Flow control
case RETURN -> ip = _return(builder, operands, ip);
default -> {
Expand Down Expand Up @@ -364,6 +374,33 @@ private int urshift(Executable.Builder builder, Operands operands, int ip){
return ip + 1;
}

private int getlocal(Executable.Builder builder, Operands operands, RegisterStates registerStates, byte[] code, int ip){
var index = fetchInt(code, ip);

var type = registerStates.getLocal(index);
if(type == null){
// Default locals to long if they're not initialized, though in theory this should never happen,
// and we probably should throw here instead
type = LONG;
}

var target = operands.push(type);
builder.appendOpcode(Opcodes.COPY(target.register(), index));

return ip + 5;
}

private int setlocal(Executable.Builder builder, Operands operands, RegisterStates registerStates, byte[] code, int ip){
var index = fetchInt(code, ip);

var source = operands.pop();
registerStates.setLocal(index, source.type());

builder.appendOpcode(Opcodes.COPY(index, source.register()));

return ip + 5;
}

private int _return(Executable.Builder builder, Operands operands, int ip){
var op = operands.pop();
builder.appendOpcode(Opcodes.RETURN(op.register()));
Expand Down Expand Up @@ -399,6 +436,10 @@ protected HVMType wider(Operand a, Operand b){
return LONG;
}

protected int calculateLocalRegister(int argCount, int localIndex){
return argCount + localIndex;
}

private int fetchInt(byte[] instructions, int ip) {
int b1 = instructions[ip] & 0xFF;
int b2 = instructions[ip + 1] & 0xFF;
Expand Down
40 changes: 40 additions & 0 deletions Lang/src/main/java/chipmunk/vm/hvm/RegisterStates.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (C) 2024 MyWorld, LLC
* All rights reserved.
*
* This file is part of Chipmunk.
*
* Chipmunk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Chipmunk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Chipmunk. If not, see <https://www.gnu.org/licenses/>.
*/

package chipmunk.vm.hvm;

import chipmunk.compiler.assembler.HVMType;

import java.util.HashMap;
import java.util.Map;

public class RegisterStates {

private final Map<Integer, HVMType> states = new HashMap<>();

public HVMType setLocal(int localIndex, HVMType type){
return states.put(localIndex, type);
}

public HVMType getLocal(int localIndex){
return states.get(localIndex);
}

}

0 comments on commit 6b98997

Please sign in to comment.