-Subproject commit 971a79a2f613db01129d7e52b4f738640bee00a9
+Subproject commit bf27a9f9f37420e80cfeca031f465a338ebbe63b
INSTR(ComplexReal);
INSTR(ComplexImag);
+struct FastExceptInfo {
+ m_str file;
+ loc_t loc;
+ m_str file2;
+ loc_t loc2;
+};
INSTR(fast_except);
/* function */
instr->m_val = (m_uint)&v->d.ptr;
// prevent invalid access to global variables
if(!exp_getvar(exp_self(prim_self(data))) &&
- isa(v->type, emit->gwion->type[et_object]) > 0) {
-// const Instr instr = emit_add_instr(emit, GWOP_EXCEPT);
- const Instr instr = emit_add_instr(emit, fast_except);
- instr->m_val = -SZ_INT;
- // use m_val2 to set some info?
- }
+ isa(v->type, emit->gwion->type[et_object]) > 0)
+ emit_fast_except(emit, v->from, prim_pos(data));
} else {
const m_uint size = v->type->size;
const Instr instr = emit_regpushimm(emit, size, exp_getvar(prim_exp(data)));
instr->m_val = v->from->offset;
if (GET_FLAG(v, late) && !exp_getvar(prim_exp(data)) &&
(isa(v->type, emit->gwion->type[et_object]) > 0 ||
- is_fptr(emit->gwion, v->type))) {
-// const Instr instr = emit_add_instr(emit, GWOP_EXCEPT);
- const Instr instr = emit_add_instr(emit, fast_except);
- instr->m_val = -SZ_INT;
- }
+ is_fptr(emit->gwion, v->type)))
+ emit_fast_except(emit, v->from, prim_pos(data));
return GW_OK;
}
.rhs = info->array.type,
.data = (uintptr_t)info};
if (!info->is_var &&
- (GET_FLAG(info->array.type, abstract) || type_ref(info->array.type))) {
-// const Instr instr = emit_add_instr(emit, GWOP_EXCEPT);
- const Instr instr = emit_add_instr(emit, fast_except);
- instr->m_val = -SZ_INT;
- }
+ (GET_FLAG(info->array.type, abstract) || type_ref(info->array.type)))
+ emit_fast_except(emit, NULL, info->array.exp->pos);
return op_emit(emit, &opi);
}
(e->cast_to ? isa(e->cast_to, emit->gwion->type[et_object]) > 0 : 1) &&
e->exp_type == ae_exp_decl && GET_FLAG(e->d.exp_decl.td, late) &&
exp_getuse(e) && !exp_getvar(e) &&
- GET_FLAG(mp_vector_at(e->d.exp_decl.list, struct Var_Decl_, 0)->value, late)) {
-// GET_FLAG(e->d.exp_decl.list->self->value, late)) {
- // e->exp_type == ae_exp_decl && !exp_getvar(e)) {
-// const Instr instr = emit_add_instr(emit, GWOP_EXCEPT);
- const Instr instr = emit_add_instr(emit, fast_except);
- instr->m_val = -SZ_INT;
- }
+ GET_FLAG(mp_vector_at(e->d.exp_decl.list, struct Var_Decl_, 0)->value, late))
+ emit_fast_except(emit, mp_vector_at(e->d.exp_decl.list, struct Var_Decl_, 0)->value->from, e->pos);
} while ((exp = exp->next));
return GW_OK;
}
vector_add(&emit->code->instr, (vtype)instr);
return instr;
}
+
+ANN2(1) void emit_fast_except(const Emitter emit, const struct ValueFrom_ *vf, const loc_t loc) {
+ const Instr instr = emit_add_instr(emit, fast_except);
+ if(vf) {
+ struct FastExceptInfo *info = mp_malloc2(emit->gwion->mp, sizeof(struct FastExceptInfo));
+ info->file = emit->env->name;
+ info->loc = loc;
+ info->file2 = vf->filename;
+ info->loc2 = vf->loc;
+ instr->m_val2 = (m_uint)info;
+ }
+}
ANN Type check_array_access(const Env env, const Array_Sub array);
+ANN static inline Type get_array_type(const Type type) {
+ const Type t = !tflag(type, tflag_ref) ? type : (Type)vector_front(&type->info->tuple->contains);
+ return t->array_depth ? t : typedef_base(t);
+}
+
static OP_CHECK(opck_array) {
const Array_Sub array = (Array_Sub)data;
const Type t_int = env->gwion->type[et_int];
Exp e = array->exp;
do CHECK_BN(check_implicit(env, e, t_int));
while ((e = e->next));
- const Type t =
- array->type->array_depth ? array->type : typedef_base(array->type);
+ const Type t = get_array_type(array->type);
if (t->array_depth >= array->depth)
return array_type(env, array_base(t), t->array_depth - array->depth);
const Exp curr = take_exp(array->exp, t->array_depth);
return ret > 0 ? next : NULL;
}
+ANN static Type emit_get_array_type(const Emitter emit, const Type t) {
+ if(!tflag(t, tflag_ref)) return t;
+ const Instr instr = emit_add_instr(emit, Reg2RegDeref);
+ instr->m_val = -SZ_INT;
+ instr->m_val2 = -SZ_INT;
+ return (Type)vector_front(&t->info->tuple->contains);
+
+}
+
static OP_EMIT(opem_array_access) {
struct ArrayAccessInfo *const info = (struct ArrayAccessInfo *)data;
- if (info->array.type->array_depth >= info->array.depth) {
+ const Type t = emit_get_array_type(emit, info->array.type);
+ if (t->array_depth >= info->array.depth) {
struct Array_Sub_ next = {
.exp = info->array.exp, .type = info->type, .depth = info->array.depth};
return array_do(emit, &next, info->is_var);
}
- struct Array_Sub_ partial = {info->array.exp, info->array.type,
- info->array.type->array_depth};
- struct Array_Sub_ next = {info->array.exp, array_base(info->array.type),
- info->array.depth - info->array.type->array_depth};
+ struct Array_Sub_ partial = {info->array.exp, t,
+ t->array_depth};
+ struct Array_Sub_ next = {info->array.exp, array_base(t),
+ info->array.depth - t->array_depth};
info->array = partial;
const Exp exp = emit_n_exp(emit, info);
next.exp = exp;
}
INSTR(fast_except) {
- if(*(m_uint*)REG((m_int)instr->m_val)) {
-// BYTE(eNoOp)
- m_bit *byte = shred->code->bytecode + (shred->pc - 1) * BYTECODE_SZ; \
- *(m_uint *)byte = instr->opcode;
- instr->opcode = eNoOp;
- } else
- handle(shred, "NullPtrException");
+ struct FastExceptInfo *info = (struct FastExceptInfo *)instr->m_val2;
+ if(*(m_uint*)REG(-SZ_INT)) {
+ m_bit *byte = shred->code->bytecode + (shred->pc - 1) * BYTECODE_SZ; \
+ *(m_uint *)byte = instr->opcode;
+ VAL = -SZ_INT;
+ instr->opcode = eNoOp;
+ if(info) mp_free2(shred->info->mp, sizeof(struct FastExceptInfo), info);
+ return;
+ } else if(info) {
+ if(info->file)
+ gwerr_basic("Object not instantiated", NULL, NULL, info->file, info->loc, 0);
+ if(info->file2)
+ gwerr_warn("declared here", NULL, NULL, info->file2, info->loc2);
+ mp_free2(shred->info->mp, sizeof(struct FastExceptInfo), info);
+ }
+ handle(shred, "NullPtrException");
}
}
if((isa(value->type, emit->gwion->type[et_object]) > 0 || is_fptr(emit->gwion, value->type)) &&
!exp_getvar(exp_self(member)) &&
- (GET_FLAG(value, static) || GET_FLAG(value, late))) {
-// const Instr instr = emit_add_instr(emit, GWOP_EXCEPT);
- const Instr instr = emit_add_instr(emit, fast_except);
- instr->m_val = -SZ_INT;
- }
+ (GET_FLAG(value, static) || GET_FLAG(value, late)))
+ emit_fast_except(emit, value->from, exp_self(member)->pos);
return GW_OK;
}