implement lookupswitch

This commit is contained in:
Zack Buhman 2024-12-27 02:07:51 -06:00
parent de4d8761f1
commit f10429927b
8 changed files with 46 additions and 8 deletions

View File

@ -7,7 +7,7 @@ CC ?= gcc
ARCH = -m32
CFLAGS += -Wall -Werror -Wfatal-errors -Wno-error=unused-variable -fstack-protector -std=c2x -g
CFLAGS += -DDEBUG
#CFLAGS += -DDEBUG_PRINT
CFLAGS += -DDEBUG_PRINT
OPT ?= -O0
DEPFLAGS = -MMD -MP

View File

@ -82,11 +82,22 @@ static inline int32_t aligned_s4(const void * buf)
#define TABLESWITCH_NEXT_PC \
(args + (3 * 4) + ((highbyte - lowbyte + 1) * 4))
#define LOOKUPSWITCH_ARGS assert(false);
#define LOOKUPSWITCH_ARGS \
uint32_t args = ((pc + 1) + 3) & (~3); \
int32_t defaultbyte = aligned_s4(&code[args + 0]); \
int32_t npairs = aligned_s4(&code[args + 4]); \
const int32_t * table = (const int32_t *)&code[args + 8];
#define LOOKUPSWITCH_PRINT_ARGS()
#define LOOKUPSWITCH_PRINT_ARGS() \
do { \
for (int i = 0; i < npairs; i++) { \
debugf(" %d: %d\n", aligned_s4(&table[i * 2]), aligned_s4(&table[i * 2 + 1])); \
} \
debugf("default: %d\n", defaultbyte); \
} while (0);
#define LOOKUPSWITCH_NEXT_PC 0
#define LOOKUPSWITCH_NEXT_PC \
(args + (2 * 4) + (npairs * 2 * 4))
#define WIDE_ARGS assert(false);

View File

@ -2165,7 +2165,7 @@ void decode_execute_instruction(struct vm * vm, const uint8_t * code, uint32_t p
{
LOOKUPSWITCH_ARGS;
vm->current_frame->next_pc = LOOKUPSWITCH_NEXT_PC;
op_lookupswitch(vm);
op_lookupswitch(vm, defaultbyte, npairs, table);
break;
}
case 172: // ireturn

View File

@ -1467,9 +1467,18 @@ void op_lneg(struct vm * vm)
operand_stack_push_u64(vm->current_frame, result);
}
void op_lookupswitch(struct vm * vm)
void op_lookupswitch(struct vm * vm, int32_t defaultbyte, int32_t npairs, const int32_t * table)
{
assert(!"op_lookupswitch");
int32_t key = operand_stack_pop_u32(vm->current_frame);
for (int i = 0; i < npairs; i++) {
int32_t match = BE_BSWAP32(table[i * 2]);
if (key == match) {
int32_t offset = BE_BSWAP32(table[i * 2 + 1]);
vm->current_frame->pc = vm->current_frame->pc + offset;
return;
}
}
vm->current_frame->pc = vm->current_frame->pc + defaultbyte;
}
void op_lor(struct vm * vm)

View File

@ -177,7 +177,7 @@ void op_lload_2(struct vm * vm);
void op_lload_3(struct vm * vm);
void op_lmul(struct vm * vm);
void op_lneg(struct vm * vm);
void op_lookupswitch(struct vm * vm);
void op_lookupswitch(struct vm * vm, int32_t defaultbyte, int32_t npairs, const int32_t * table);
void op_lor(struct vm * vm);
void op_lrem(struct vm * vm);
void op_lreturn(struct vm * vm);

BIN
main.bin

Binary file not shown.

Binary file not shown.

18
p/LookupSwitch.java Normal file
View File

@ -0,0 +1,18 @@
package p;
class LookupSwitch {
static int foo(int a) {
switch (a) {
case 1: return 5;
case 10: return 42;
case 100: return 432;
case 1000: return 999;
case 10000: return 9999;
default: return 123;
}
}
public static void main() {
foo(10);
}
}