ANN Code* emit_class_code(const Emitter, const m_str);
ANN m_bool emit_array_extend(const Emitter, const Type, const Exp);
ANN void emit_class_finish(const Emitter, const Nspc);
-ANN void emit_ext_ctor(const Emitter, const VM_Code);
ANN void emit_union_offset(Decl_List, const m_uint);
ANN2(1,2) m_bool emit_instantiate_object(const Emitter, const Type, const Array_Sub, const m_bool);
ANN m_uint emit_code_offset(const Emitter emit);
--- /dev/null
+#ifndef __MODIFY_INSTR
+#define __MODIFY_INSTR
+typedef void (*instr_modifier)(m_bit *bytecode, m_bit *reg);
+
+ANN void emit_mod_recurs(const Emitter);
+ANN void emit_mod_func(const Emitter, const Func);
+ANN void emit_mod_ctor(const Emitter, const Type);
+#endif
#include "parser.h"
#include "specialid.h"
#include "vararg.h"
+#include "modify_instr.h"
#undef insert_symbol
#define insert_symbol(a) insert_symbol(emit->gwion->st, (a))
return frame_local(emit->gwion->mp, emit->code->frame, t);
}
-ANN static inline void maybe_ctor(const Emitter emit, const Type type) {
- if(type->nspc && type->nspc->pre_ctor && !GET_FLAG(type, nonnull))
- emit_ext_ctor(emit, type->nspc->pre_ctor);
+ANN void emit_ext_ctor(const Emitter emit, const Type t);
+
+ANN static inline void maybe_ctor(const Emitter emit, const Type t) {
+ if(!GET_FLAG(t, nonnull) && GET_FLAG(t, ctor))
+ emit_ext_ctor(emit, t);
}
ANN static void emit_pre_ctor(const Emitter emit, const Type type) {
return info;
}
-ANN void emit_ext_ctor(const Emitter emit, const VM_Code code) {
+ANN void emit_ext_ctor(const Emitter emit, const Type t) {
const Instr cpy = emit_add_instr(emit, Reg2Reg);
cpy->m_val2 = -SZ_INT;
- const Instr set_code = regseti(emit, (m_uint)code);
- set_code->m_val2 = SZ_INT;
+ if(t->nspc->pre_ctor) {
+ const Instr set_code = regseti(emit, (m_uint)t->nspc->pre_ctor);
+ set_code->m_val2 = SZ_INT;
+ } else
+ emit_mod_ctor(emit, t);
const m_uint offset = emit_code_offset(emit);
const Instr regset = regseti(emit, offset);
regset->m_val2 = SZ_INT *2;
ANN static void emit_struct_decl_finish(const Emitter emit, const Type t, const uint emit_addr) {
emit->code->frame->curr_offset += t->size + SZ_INT;
- emit_ext_ctor(emit, t->nspc->pre_ctor);
+ emit_ext_ctor(emit, t);
if(!emit_addr)
decl_expand(emit, t);
emit->code->frame->curr_offset -= t->size + SZ_INT;
if(GET_FLAG(f, template) && !is_fptr(emit->gwion, f->value_ref->type)) {
if(emit->env->func != f)
CHECK_BO(emit_template_code(emit, f))
- else {
+ else { // recursive function. (maybe should be used only for global funcs)
const Instr back = (Instr) vector_size(&emit->code->instr) ?
(Instr)vector_back(&emit->code->instr) : emit_add_instr(emit, RegPushImm);
back->opcode = ePushStaticCode;
const Instr instr = emit_add_instr(emit, (f_instr)(m_uint)exec);
instr->m_val = val;
instr->m_val2 = val2;
- } else if(f != emit->env->func && !f->code&& ! is_fptr(emit->gwion, f->value_ref->type)){
+ } else if(f != emit->env->func && !f->code && !is_fptr(emit->gwion, f->value_ref->type)){
/* not yet emitted static func */
if(f->value_ref->from->owner_class) {
const Instr instr = vector_size(&emit->code->instr) ?
(Instr)vector_back(&emit->code->instr) : emit_add_instr(emit, PushStaticCode);
assert(instr->opcode == ePushStaticCode);
instr->opcode = eRegPushImm;
- } else {
- const Instr pushcode = emit_add_instr(emit, PushStaticCode);
- pushcode->m_val = (m_uint)f;
- }
+ } else
+ emit_mod_func(emit, f);
}
const m_uint offset = emit_code_offset(emit);
regseti(emit, offset);
const Type t = cdef->base.type;
if(GET_FLAG(t, emit))
return GW_OK;
+ SET_FLAG(t, emit);
if(cdef->base.ext && t->e->parent->e->def && !GET_FLAG(t->e->parent, emit))
CHECK_BB(cdef_parent(emit, cdef))
- SET_FLAG(t, emit);
nspc_allocdata(emit->gwion->mp, t->nspc);
if(cdef->body) {
emit_class_code(emit, t->name);
--- /dev/null
+#include "gwion_util.h"
+#include "gwion_ast.h"
+#include "gwion_env.h"
+#include "vm.h"
+#include "gwion.h"
+#include "instr.h"
+#include "emit.h"
+
+// should be in vm.h
+#define VAL (*(m_uint*)(byte + SZ_INT))
+#define FVAL (*(m_float*)(byte + SZ_INT))
+#define VAL2 (*(m_uint*)(byte + SZ_INT*2))
+/*
+ANN static void set_recurs(m_bit *byte, m_bit **reg) {
+ *(m_bit*)byte = eRegPushImm;
+ VAL = (*(m_uint*)(*reg-SZ_INT) = );
+ VAL2 = -SZ_INT;
+// copy from vm_code
+}
+*/
+
+ANN static void set_func(m_bit *byte, m_bit **reg) {
+ *(m_bit*)byte = eRegSetImm;
+ VAL = (*(m_uint*)(*reg-SZ_INT) = (m_uint)((Func)VAL)->code);
+ VAL2 = -SZ_INT;
+// copy from vm_code
+}
+
+ANN static void set_ctor(m_bit *byte, m_bit *reg) {
+ *(m_bit*)byte = eRegSetImm;
+ VAL = (*(m_uint*)(reg+SZ_INT) = (m_uint)((Type)VAL)->nspc->pre_ctor);
+ VAL2 = SZ_INT;
+}
+
+ANN void emit_mod_recurs(const Emitter emit) {
+ const Instr instr = vector_size(&emit->code->instr) ?
+ (Instr)vector_back(&emit->code->instr) : emit_add_instr(emit, RegPushImm);
+ instr->opcode = ePushStaticCode;
+ instr->m_val = 0;
+}
+
+ANN void emit_mod_func(const Emitter emit, const Func f) {
+ const Instr instr = emit_add_instr(emit, PushStaticCode);
+ instr->m_val = (m_uint)f;
+ instr->m_val2 = (m_uint)set_func;
+}
+
+ANN void emit_mod_ctor(const Emitter emit, const Type t) {
+ const Instr instr = emit_add_instr(emit, PushStaticCode);
+ instr->m_val = (m_uint)t;
+ instr->m_val2 = (m_uint)set_ctor;
+}
CHECK_BO(emit_exp(emit, member->base))
emit_struct_data(emit, value, exp_getvar(exp_self(member)));
}
- }
- else if(GET_FLAG(value, static))
+ } else if(GET_FLAG(value, static))
emit_dot_static_import_data(emit, value, exp_getvar(exp_self(member)));
+ else { // member type
+ const Instr instr = emit_add_instr(emit, RegPushImm);
+ instr->m_val = (m_uint)value->type;
+ }
return (Instr)GW_OK;
}
CHECK_BB(cdef_parent(env, cdef))
if(!GET_FLAG(cdef, struct))
inherit(t);
- if(cdef->body)
+ if(cdef->body) {
CHECK_BB(env_body(env, cdef, check_section))
+ SET_FLAG(t, ctor);
+ }
SET_FLAG(t, valid);
return GW_OK;
}
return envset_run(&es, t);
}
-ANN static m_bool type_recursive(const Env env, const Type_Decl *td, const Type t) {
- const Type base = get_type(t);
- if(!GET_FLAG(td, ref) && env->class_def && !env->scope->depth &&
- base == env->class_def) {
- ERR_B(td_pos(td), _("%s declared inside %s\n. (make it a ref ?)"),
- t->name, t == env->class_def ? "itself" : env->class_def->name);
- }
- return GW_OK;
-}
-
ANN static Type scan1_type(const Env env, Type_Decl* td) {
DECL_OO(const Type, type, = known_type(env, td))
const Type t = get_type(type);
- if(!env->func && env->class_def)
+ if(!env->func && env->class_def && !GET_FLAG(td, ref))
CHECK_BO(type_cyclic(env, t, td))
if(!GET_FLAG(t, scan1) && t->e->def)
CHECK_BO(ensure_scan1(env, t))
ANN static Type void_type(const Env env, Type_Decl* td) {
DECL_OO(const Type, type, = scan1_type(env, td))
- if(isa(type, env->gwion->type[et_compound]) > 0)
- CHECK_BO(type_recursive(env, td, type))
if(type->size)
return type;
ERR_O(td_pos(td), _("cannot declare variables of size '0' (i.e. 'void')..."))
#include "map_private.h"
#include "gack.h"
#include "array.h"
-
+#include "modify_instr.h"
static inline uint64_t splitmix64_stateless(uint64_t index) {
uint64_t z = (index + UINT64_C(0x9E3779B97F4A7C15));
*(VM_Code*)(reg-SZ_INT) = ((Func)vector_at(a.obj->vtable, VAL))->code;
PRAGMA_POP()
DISPATCH()
-pushstaticcode:
- *(m_bit*)byte = eRegSetImm;
- VAL = (*(m_uint*)(reg-SZ_INT) = (m_uint)((Func)VAL)->code);
- VAL2 = -SZ_INT;
+pushstaticcode: // TODO: use external instr
+ ((instr_modifier)VAL2)(byte, reg);
DISPATCH()
gcini:
vector_add(&shred->gc, 0);