Created
August 14, 2021 09:12
-
-
Save elct9620/2fa11b672c8bb185e4b48160acd2ccbf to your computer and use it in GitHub Desktop.
RubyKaigi 2021 Takeout - mruby VM demo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdint.h> | |
#include <stdio.h> | |
static inline uint32_t | |
bin_to_uint32(const uint8_t *bin) | |
{ | |
return (uint32_t)bin[0] << 24 | | |
(uint32_t)bin[1] << 16 | | |
(uint32_t)bin[2] << 8 | | |
(uint32_t)bin[3]; | |
} | |
static inline uint16_t | |
bin_to_uint16(const uint8_t *bin) | |
{ | |
return (uint16_t)bin[0] << 8 | | |
(uint16_t)bin[1]; | |
} | |
static size_t skip_padding(const uint8_t* buf) { | |
const size_t align = sizeof(uint32_t); | |
return -(intptr_t)buf & (align - 1); | |
} | |
enum { | |
OP_NOP, | |
OP_LOADI__1 = 5, | |
OP_LOADI_0, | |
OP_LOADI_1, | |
OP_LOADI_2, | |
OP_LOADI_3, | |
OP_LOADI_4, | |
OP_LOADI_5, | |
OP_LOADI_6, | |
OP_LOADI_7, | |
OP_RETURN = 55, | |
OP_ADD = 59, | |
OP_ADDI, | |
}; | |
int main(int argc, char** argv) { | |
printf("Read: %s\n", argv[1]); | |
FILE *fp = fopen(argv[1], "r"); | |
fseek(fp, 0, SEEK_END); | |
size_t size = ftell(fp); | |
fseek(fp, 0, SEEK_SET); | |
uint8_t binary[size]; | |
fread(binary, sizeof(uint8_t), size, fp); | |
const uint8_t* bin = binary; | |
// RITE | |
bin += 34; | |
// Record Size | |
bin += 4; | |
// Local Variables | |
uint16_t nlocals = bin_to_uint16(bin); | |
bin += 2; | |
uint16_t nregs = bin_to_uint16(bin); | |
bin += 2; | |
uint16_t nirep = bin_to_uint16(bin); | |
bin += 2; | |
uint32_t niseq = bin_to_uint32(bin); | |
bin += 4; | |
bin += skip_padding(bin); | |
printf("nregs=%d nlocals=%d iseq=%d\n", nregs, nlocals, niseq); | |
// Create Register | |
intptr_t reg[nregs - 1]; | |
// Temp Variable | |
int32_t a = 0; | |
int32_t b = 0; | |
int32_t c = 0; | |
for(;;) { | |
uint8_t opcode = *bin++; | |
switch(opcode) { | |
case OP_NOP: | |
break; | |
case OP_LOADI_0: | |
case OP_LOADI_1: | |
case OP_LOADI_2: | |
case OP_LOADI_3: | |
case OP_LOADI_4: | |
case OP_LOADI_5: | |
case OP_LOADI_6: | |
case OP_LOADI_7: | |
a = *bin++; | |
reg[a] = opcode - OP_LOADI_0; | |
break; | |
case OP_ADDI: | |
a = *bin++; b = *bin++; | |
reg[a] += b; | |
break; | |
case OP_RETURN: | |
a = *bin++; | |
printf("Result: %ld\n", reg[a]); | |
return 0; | |
default: | |
printf("Unsuport OPCODE = %d\n", opcode); | |
return 1; | |
} | |
} | |
fclose(fp); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment