Skip to content

Instantly share code, notes, and snippets.

@elct9620
Created August 14, 2021 09:12
Show Gist options
  • Save elct9620/2fa11b672c8bb185e4b48160acd2ccbf to your computer and use it in GitHub Desktop.
Save elct9620/2fa11b672c8bb185e4b48160acd2ccbf to your computer and use it in GitHub Desktop.
RubyKaigi 2021 Takeout - mruby VM demo
#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