feat: optimize VM using dispatch table
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
#include <vm/fzl_vm.h>
|
||||
#include <vm/internals/opcode.h>
|
||||
|
||||
// Pop two numbers and push sum result
|
||||
int op_add(fzl_vm_t *vm)
|
||||
{
|
||||
if (vm->dtop < 2)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err),
|
||||
"runtime error - expected 2 values in stack");
|
||||
print_err_data(vm);
|
||||
return -1;
|
||||
}
|
||||
fzl_value_t add1 = vm->dstack[--vm->dtop];
|
||||
fzl_value_t add2 = vm->dstack[--vm->dtop];
|
||||
vm->dstack[vm->dtop++] =
|
||||
(fzl_value_t){.type = add1.type, .as.u = add1.as.u + add2.as.u};
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Pop two numbers and push sum result
|
||||
int op_sub(fzl_vm_t *vm)
|
||||
{
|
||||
if (vm->dtop < 2)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err),
|
||||
"runtime error - expected 2 values in stack");
|
||||
print_err_data(vm);
|
||||
return -1;
|
||||
}
|
||||
fzl_value_t sub2 = vm->dstack[--vm->dtop];
|
||||
fzl_value_t sub1 = vm->dstack[--vm->dtop];
|
||||
vm->dstack[vm->dtop++] =
|
||||
(fzl_value_t){.type = sub1.type, .as.u = sub1.as.u - sub2.as.u};
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Pop two numbers and push sum result
|
||||
int op_mul(fzl_vm_t *vm)
|
||||
{
|
||||
if (vm->dtop < 2)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err),
|
||||
"runtime error - expected 2 values in stack");
|
||||
print_err_data(vm);
|
||||
return -1;
|
||||
}
|
||||
fzl_value_t mul1 = vm->dstack[--vm->dtop];
|
||||
fzl_value_t mul2 = vm->dstack[--vm->dtop];
|
||||
vm->dstack[vm->dtop++] =
|
||||
(fzl_value_t){.type = mul1.type, .as.u = mul1.as.u * mul2.as.u};
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Pop two numbers and push sum result
|
||||
int op_div(fzl_vm_t *vm)
|
||||
{
|
||||
if (vm->dtop < 2)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err),
|
||||
"runtime error - expected 2 values in stack");
|
||||
print_err_data(vm);
|
||||
return -1;
|
||||
}
|
||||
fzl_value_t div1 = vm->dstack[--vm->dtop];
|
||||
fzl_value_t div2 = vm->dstack[--vm->dtop];
|
||||
vm->dstack[vm->dtop++] =
|
||||
(fzl_value_t){.type = div1.type, .as.u = div2.as.u / div1.as.u};
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Pop two numbers and push sum result
|
||||
int op_pow(fzl_vm_t *vm)
|
||||
{
|
||||
if (vm->dtop < 2)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err),
|
||||
"runtime error - expected 2 values in stack");
|
||||
print_err_data(vm);
|
||||
return -1;
|
||||
}
|
||||
fzl_value_t pow2 = vm->dstack[--vm->dtop];
|
||||
fzl_value_t pow1 = vm->dstack[--vm->dtop];
|
||||
|
||||
uint64_t pow_n = pow1.as.u;
|
||||
uint64_t pow_res = pow_n;
|
||||
uint64_t pow_times = pow2.as.u;
|
||||
for (size_t i = 1; i < pow_times; i++)
|
||||
pow_res *= pow_n;
|
||||
|
||||
vm->dstack[vm->dtop++] = (fzl_value_t){.type = pow1.type, .as.u = pow_res};
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Pop two numbers and push sum result
|
||||
int op_mod(fzl_vm_t *vm)
|
||||
{
|
||||
if (vm->dtop < 2)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err),
|
||||
"runtime error - expected 2 values in stack");
|
||||
print_err_data(vm);
|
||||
return -1;
|
||||
}
|
||||
fzl_value_t mod1 = vm->dstack[--vm->dtop];
|
||||
fzl_value_t mod2 = vm->dstack[--vm->dtop];
|
||||
vm->dstack[vm->dtop++] =
|
||||
(fzl_value_t){.type = mod1.type, .as.u = mod2.as.u % mod1.as.u};
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Pop two numbers and push sum result
|
||||
int op_neg(fzl_vm_t *vm)
|
||||
{
|
||||
if (vm->dtop < 1)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err),
|
||||
"runtime error - expected value in stack");
|
||||
print_err_data(vm);
|
||||
return -1;
|
||||
}
|
||||
fzl_value_t neg_n = vm->dstack[--vm->dtop];
|
||||
vm->dstack[vm->dtop++] =
|
||||
(fzl_value_t){.type = neg_n.type, .as.u = -neg_n.as.u};
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user