INSTR(RegPushBase3);
INSTR(RegPushBase4);
INSTR(RegPushPtr);
-INSTR(RegPushCode);
INSTR(RegDup);
INSTR(RegAddRef);
return push_func_code(emit, f);
}
-ANN static m_bool emit_exp_call1_code(const Emitter emit, const Func f) {
- if(GET_FLAG(f, template) && emit->env->func != f)
- return emit_template_code(emit, f);
- emit_add_instr(emit, RegPushCode);
- return 1;
-}
-
ANN static Instr emit_call(const Emitter emit, const Func f) {
MEMOIZE_CALL
const Type t = actual_type(f->value_ref->type);
return emit_add_instr(emit, exec);
}
-ANN m_bool emit_exp_call1(const Emitter emit, const Func func) { GWDEBUG_EXE
- if(!func->code || (GET_FLAG(func, ref) && !GET_FLAG(func, builtin)))
- CHECK_BB(emit_exp_call1_code(emit, func))
- else
- push_func_code(emit, func);
+ANN m_bool emit_exp_call1(const Emitter emit, const Func f) { GWDEBUG_EXE
+ if(!f->code || (GET_FLAG(f, ref) && !GET_FLAG(f, builtin))) {
+ if(GET_FLAG(f, template) && emit->env->func != f)
+ CHECK_BB(emit_template_code(emit, f))
+ } else
+ push_func_code(emit, f);
const Instr offset = emit_add_instr(emit, RegPushImm);
offset->m_val = emit_code_offset(emit);
- const Instr instr = emit_call(emit, func);
- const m_uint size = instr->m_val = func->def->ret_type->size;
+ const Instr instr = emit_call(emit, f);
+ const m_uint size = instr->m_val = f->def->ret_type->size;
return (m_bool)(instr->m_val2 = kindof(size, !size));
}
ANN static m_bool emit_dot_static_func(const Emitter emit, const Func func) { GWDEBUG_EXE
const Instr func_i = emit_add_instr(emit, RegPushImm);
- func_i->m_val = (m_uint)func;
+ func_i->m_val = (m_uint)func->code;
return GW_OK;
}
ANN static inline void emit_func_def_global(const Emitter emit, const Value value) { GWDEBUG_EXE
const Instr set_mem = emit_add_instr(emit, MemSetImm);
- set_mem->m_val = value->offset = emit_local(emit, value->type->size, 0);
- set_mem->m_val2 = (m_uint)value->d.func_ref;
+ set_mem->m_val = value->offset = emit_local(emit, value->type->size, 0); // size -> SZ_INT ?
+ set_mem->m_val2 = (m_uint)value->d.func_ref->code;
}
ANN static void emit_func_def_init(const Emitter emit, const Func func) { GWDEBUG_EXE
UNSET_FLAG(func_def, template);;
return GW_OK;
}
- if(!emit->env->class_def)
- emit_func_def_global(emit, func->value_ref);
- else if(GET_FLAG(emit->env->class_def, builtin) && GET_FLAG(emit->env->class_def, template))
+ if(SAFE_FLAG(emit->env->class_def, builtin) && GET_FLAG(emit->env->class_def, template))
return GW_OK;
emit_func_def_init(emit, func);
if(GET_FLAG(func, member))
emit_func_def_code(emit, func);
emit->env->func = former;
emit_pop_code(emit);
+ if(!emit->env->class_def)
+ emit_func_def_global(emit, func->value_ref);
MEMOIZE_INI
return GW_OK;
}
#include "vm.h"
#include "env.h"
#include "type.h"
+#include "func.h"
#include "object.h"
#include "instr.h"
-/* static */ void print_type(const Type type) {
+static void print_type(const Type type) {
const m_bool is_func = isa(type, t_function) > 0 && isa(type, t_fptr) < 0;
const m_str name = is_func ? strdup("@function") : strdup(type->name);
gw_out("(%s) ", name);
}
}
-/* static inline */ void print_int(const m_int i) {
+static inline void print_int(const m_int i) {
gw_out("%" INT_F "", i);
}
-/* static inline */void print_float(const m_float f) {
+static inline void print_float(const m_float f) {
gw_out("%.4f", f);
}
-/* static inline */void print_complex(const m_complex c) {
+static inline void print_complex(const m_complex c) {
gw_out("#(");
print_float(creal(c));
gw_out(", ");
gw_out(")");
}
-/*static inline */void print_polar(const m_complex c) {
+static inline void print_polar(const m_complex c) {
gw_out("%%(");
print_float(creal(c));
gw_out(", ");
gw_out("*pi)");
}
-/* static inline */ void print_vec(const m_bit* f, const m_uint size) {
+static inline void print_vec(const m_bit* f, const m_uint size) {
gw_out("@(");
for(m_uint i = 0; i < size; i++) {
print_float(creal(*(m_float*)(f + i * SZ_FLOAT)));
gw_out(")");
}
-/* static inline */void print_string1(const m_str str) {
+static inline void print_string1(const m_str str) {
gw_out("%s", str);
}
-/*static inline */void print_string(const M_Object obj) {
+static inline void print_string(const M_Object obj) {
print_string1(obj ? STRING(obj) : "(null string)");
}
-/*static inline */void print_object(const Type type, const M_Object obj) {
+static inline void print_object(const Type type, const M_Object obj) {
if(isa(type, t_string) > 0)
print_string(obj);
else
gw_out("%p", (void*)obj);
}
-/* static inline */ void print_func(const Type type, const m_bit* stack) {
- const Func func = isa(type, t_fptr) > 0 ?
- *(Func*)stack : type->d.func;
- gw_out("%s %p", type->name, (void*)func);
+static inline void print_func(const Type type, const m_bit* stack) {
+ const VM_Code code = isa(type, t_fptr) > 0 ?
+ *(VM_Code*)stack : type->d.func->code;
+ gw_out("%s %p", type->name, (void*)code);
}
-/*static */void print_prim(const Type type, const m_bit* stack) {
+static void print_prim(const Type type, const m_bit* stack) {
if(isa(type, t_int) > 0)
print_int(*(m_int*)stack);
else if(isa(type, t_complex) > 0)
PUSH_REG(shred, SZ_INT);
}
-
#define describe_regpushbase(name, type, size) \
INSTR(RegPush##name) { GWDEBUG_EXE \
*(type*)REG(0) = *(type*)(shred->base + instr->m_val); \
*(m_uint*)REG(-SZ_INT) = instr->m_val;
}
-INSTR(RegPushCode) { GWDEBUG_EXE
- const Func f = *(Func*)REG(-SZ_INT);
- if(!f)
- Except(shred, "NullFuncPtrException");
- *(VM_Code*)REG(-SZ_INT) = f->code;
-}
-
INSTR(RegDup) { GWDEBUG_EXE
*(M_Object*)REG(0) = *(M_Object*)REG(-SZ_INT);
PUSH_REG(shred, SZ_INT);
ANN static void shred_func_prepare(const VM_Shred shred) {
POP_REG(shred, SZ_INT * 2);
- const VM_Code code = *(VM_Code*)REG(0);
-
- const m_uint local_depth = *(m_uint*)REG(SZ_INT);
- const m_uint prev_stack = *(m_uint*)MEM(-SZ_INT);
- const m_uint push = prev_stack + local_depth;
-
- PUSH_MEM(shred, push + SZ_INT*4);
- *(m_uint*) MEM(-SZ_INT*4) = push;
- *(VM_Code*) MEM(-SZ_INT*3) = shred->code;
- *(m_uint*) MEM(-SZ_INT*2) = shred->pc;
- *(m_uint*) MEM(-SZ_INT) = (m_uint)code->stack_depth;
+ // local depth + previous stack
+ const m_uint push = *(m_uint*)REG(SZ_INT) + *(m_uint*)MEM(-SZ_INT);
+ PUSH_MEM(shred, push + SZ_INT*3);
+ *(m_uint*) MEM(-SZ_INT*3) = push;
+ *(VM_Code*) MEM(-SZ_INT*2) = shred->code;
+ *(m_uint*) MEM(-SZ_INT) = shred->pc;
shred->pc = 0;
- shred->code = code;
- shred->instr = code->instr;
+ shred->code = *(VM_Code*)REG(0);
+ shred->instr = shred->code->instr;
}
ANN static inline void shred_func_need_this(const VM_Shred shred) {
INSTR(FuncPtr) { GWDEBUG_EXE
const VM_Code code = *(VM_Code*)REG(-SZ_INT*2);
+ if(!code)
+ Except(shred, "NullFuncPtrException");
if(!GET_FLAG(code, builtin))
FuncUsr(shred, instr);
else if(GET_FLAG(code, member))
const M_Object obj = *(M_Object*)REG(-SZ_INT);
if(!obj)
Except(shred, "NullPtrException");
- *(Func*)REG(-SZ_INT) = (Func)vector_at(&obj->type_ref->nspc->vtable, instr->m_val);
+ *(VM_Code*)REG(-SZ_INT) = ((Func)vector_at(&obj->type_ref->nspc->vtable, instr->m_val))->code;
}
INSTR(FuncStatic) { GWDEBUG_EXE
}
INSTR(FuncReturn) { GWDEBUG_EXE
- shred->pc = *(m_uint*)MEM(-SZ_INT*2);
- shred->code = *(VM_Code*)MEM(-SZ_INT*3);
+ shred->pc = *(m_uint*)MEM(-SZ_INT);
+ shred->code = *(VM_Code*)MEM(-SZ_INT*2);
shred->instr = shred->code->instr;
- POP_MEM(shred, *(m_uint*)MEM(-SZ_INT*4) + SZ_INT*4);
+ POP_MEM(shred, *(m_uint*)MEM(-SZ_INT*3) + SZ_INT*3);
}
INSTR(PreCtor) { GWDEBUG_EXE