if (!self->vtype->expression.next ||
self->vtype->expression.next->expression.vtype == TYPE_VOID)
{
- return ir_block_create_return(self->curblock, NULL);
+ return ir_block_create_return(self->curblock, ast_ctx(self), NULL);
}
else if (vec_size(self->curblock->entries))
{
{
return false;
}
- return ir_block_create_return(self->curblock, NULL);
+ return ir_block_create_return(self->curblock, ast_ctx(self), NULL);
}
}
return true;
ai = (ast_array_index*)self->dest;
idx = (ast_value*)ai->index;
- if (ast_istype(ai->index, ast_value) && idx->hasvalue)
+ if (ast_istype(ai->index, ast_value) && idx->hasvalue && idx->cvq == CV_CONST)
ai = NULL;
}
if (!(*cgen)((ast_expression*)(self->source), func, false, &right))
return false;
- call = ir_block_create_call(func->curblock, ast_function_label(func, "store"), funval);
+ call = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "store"), funval);
if (!call)
return false;
ir_call_param(call, iridx);
if (!(*cgen)((ast_expression*)(self->source), func, false, &right))
return false;
- if (!ir_block_create_store_op(func->curblock, self->op, left, right))
+ if (!ir_block_create_store_op(func->curblock, ast_ctx(self), self->op, left, right))
return false;
self->expression.outr = right;
}
compile_error(ast_ctx(self), "don't know how to cast to bool...");
return false;
}
- left = ir_block_create_unary(func->curblock,
+ left = ir_block_create_unary(func->curblock, ast_ctx(self),
ast_function_label(func, "sce_not"),
notop,
left);
other = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "sce_other"));
if ( !(self->op == INSTR_OR) != !OPTS_FLAG(PERL_LOGIC) ) {
- if (!ir_block_create_if(func->curblock, left, other, merge))
+ if (!ir_block_create_if(func->curblock, ast_ctx(self), left, other, merge))
return false;
} else {
- if (!ir_block_create_if(func->curblock, left, merge, other))
+ if (!ir_block_create_if(func->curblock, ast_ctx(self), left, merge, other))
return false;
}
/* use the likely flag */
compile_error(ast_ctx(self), "don't know how to cast to bool...");
return false;
}
- right = ir_block_create_unary(func->curblock,
+ right = ir_block_create_unary(func->curblock, ast_ctx(self),
ast_function_label(func, "sce_not"),
notop,
right);
}
from_right = func->curblock;
- if (!ir_block_create_jump(func->curblock, merge))
+ if (!ir_block_create_jump(func->curblock, ast_ctx(self), merge))
return false;
vec_remove(func->ir_func->blocks, merge_id, 1);
vec_push(func->ir_func->blocks, merge);
func->curblock = merge;
- phi = ir_block_create_phi(func->curblock, ast_function_label(func, "sce_value"), TYPE_FLOAT);
+ phi = ir_block_create_phi(func->curblock, ast_ctx(self), ast_function_label(func, "sce_value"), TYPE_FLOAT);
ir_phi_add(phi, from_left, left);
ir_phi_add(phi, from_right, right);
*out = ir_phi_value(phi);
compile_error(ast_ctx(self), "don't know how to cast to bool...");
return false;
}
- *out = ir_block_create_unary(func->curblock,
+ *out = ir_block_create_unary(func->curblock, ast_ctx(self),
ast_function_label(func, "sce_final_not"),
notop,
*out);
if (!(*cgen)((ast_expression*)(self->right), func, false, &right))
return false;
- *out = ir_block_create_binop(func->curblock, ast_function_label(func, "bin"),
+ *out = ir_block_create_binop(func->curblock, ast_ctx(self), ast_function_label(func, "bin"),
self->op, left, right);
if (!*out)
return false;
ai = (ast_array_index*)self->dest;
idx = (ast_value*)ai->index;
- if (ast_istype(ai->index, ast_value) && idx->hasvalue)
+ if (ast_istype(ai->index, ast_value) && idx->hasvalue && idx->cvq == CV_CONST)
ai = NULL;
}
return false;
/* now the binary */
- bin = ir_block_create_binop(func->curblock, ast_function_label(func, "binst"),
+ bin = ir_block_create_binop(func->curblock, ast_ctx(self), ast_function_label(func, "binst"),
self->opbin, leftr, right);
self->expression.outr = bin;
if (!(*cgen)((ast_expression*)(arr->setter), func, true, &funval))
return false;
- call = ir_block_create_call(func->curblock, ast_function_label(func, "store"), funval);
+ call = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "store"), funval);
if (!call)
return false;
ir_call_param(call, iridx);
return false;
self->expression.outl = leftl;
- if (!ir_block_create_store_op(func->curblock, self->opstore, leftl, bin))
+ if (!ir_block_create_store_op(func->curblock, ast_ctx(self), self->opstore, leftl, bin))
return false;
self->expression.outr = bin;
}
if (!(*cgen)((ast_expression*)(self->operand), func, false, &operand))
return false;
- *out = ir_block_create_unary(func->curblock, ast_function_label(func, "unary"),
+ *out = ir_block_create_unary(func->curblock, ast_ctx(self), ast_function_label(func, "unary"),
self->op, operand);
if (!*out)
return false;
if (!(*cgen)((ast_expression*)(self->operand), func, false, &operand))
return false;
- if (!ir_block_create_return(func->curblock, operand))
+ if (!ir_block_create_return(func->curblock, ast_ctx(self), operand))
return false;
} else {
- if (!ir_block_create_return(func->curblock, NULL))
+ if (!ir_block_create_return(func->curblock, ast_ctx(self), NULL))
return false;
}
if (lvalue) {
/* address! */
- *out = ir_block_create_fieldaddress(func->curblock, ast_function_label(func, "efa"),
+ *out = ir_block_create_fieldaddress(func->curblock, ast_ctx(self), ast_function_label(func, "efa"),
ent, field);
} else {
- *out = ir_block_create_load_from_ent(func->curblock, ast_function_label(func, "efv"),
+ *out = ir_block_create_load_from_ent(func->curblock, ast_ctx(self), ast_function_label(func, "efv"),
ent, field, self->expression.vtype);
}
if (!*out) {
arr = (ast_value*)self->array;
idx = (ast_value*)self->index;
- if (!ast_istype(self->index, ast_value) || !idx->hasvalue) {
+ if (!ast_istype(self->index, ast_value) || !idx->hasvalue || idx->cvq != CV_CONST) {
/* Time to use accessor functions */
ast_expression_codegen *cgen;
ir_value *iridx, *funval;
if (!(*cgen)((ast_expression*)(arr->getter), func, true, &funval))
return false;
- call = ir_block_create_call(func->curblock, ast_function_label(func, "fetch"), funval);
+ call = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "fetch"), funval);
if (!call)
return false;
ir_call_param(call, iridx);
return true;
}
- if (idx->expression.vtype == TYPE_FLOAT)
- *out = arr->ir_values[(int)idx->constval.vfloat];
- else if (idx->expression.vtype == TYPE_INTEGER)
- *out = arr->ir_values[idx->constval.vint];
+ if (idx->expression.vtype == TYPE_FLOAT) {
+ unsigned int arridx = idx->constval.vfloat;
+ if (arridx >= self->array->expression.count)
+ {
+ compile_error(ast_ctx(self), "array index out of bounds: %i", arridx);
+ return false;
+ }
+ *out = arr->ir_values[arridx];
+ }
+ else if (idx->expression.vtype == TYPE_INTEGER) {
+ unsigned int arridx = idx->constval.vint;
+ if (arridx >= self->array->expression.count)
+ {
+ compile_error(ast_ctx(self), "array index out of bounds: %i", arridx);
+ return false;
+ }
+ *out = arr->ir_values[arridx];
+ }
else {
compile_error(ast_ctx(self), "array indexing here needs an integer constant");
return false;
if (!merge)
return false;
/* add jumps ot the merge block */
- if (ontrue && !ontrue_endblock->final && !ir_block_create_jump(ontrue_endblock, merge))
+ if (ontrue && !ontrue_endblock->final && !ir_block_create_jump(ontrue_endblock, ast_ctx(self), merge))
return false;
- if (onfalse && !onfalse_endblock->final && !ir_block_create_jump(onfalse_endblock, merge))
+ if (onfalse && !onfalse_endblock->final && !ir_block_create_jump(onfalse_endblock, ast_ctx(self), merge))
return false;
/* Now enter the merge block */
/* we create the if here, that way all blocks are ordered :)
*/
- if (!ir_block_create_if(cond, condval,
+ if (!ir_block_create_if(cond, ast_ctx(self), condval,
(ontrue ? ontrue : merge),
(onfalse ? onfalse : merge)))
{
if (!merge)
return false;
/* jump to merge block */
- if (!ir_block_create_jump(ontrue_out, merge))
+ if (!ir_block_create_jump(ontrue_out, ast_ctx(self), merge))
return false;
- if (!ir_block_create_jump(onfalse_out, merge))
+ if (!ir_block_create_jump(onfalse_out, ast_ctx(self), merge))
return false;
/* create if instruction */
- if (!ir_block_create_if(cond_out, condval, ontrue, onfalse))
+ if (!ir_block_create_if(cond_out, ast_ctx(self), condval, ontrue, onfalse))
return false;
/* Now enter the merge block */
}
/* create PHI */
- phi = ir_block_create_phi(merge, ast_function_label(func, "phi"), trueval->vtype);
+ phi = ir_block_create_phi(merge, ast_ctx(self), ast_function_label(func, "phi"), trueval->vtype);
if (!phi)
return false;
ir_phi_add(phi, ontrue_out, trueval);
else if (bbody) tmpblock = bbody;
else if (bpostcond) tmpblock = bpostcond;
else tmpblock = bout;
- if (!ir_block_create_jump(bin, tmpblock))
+ if (!ir_block_create_jump(bin, ast_ctx(self), tmpblock))
return false;
/* From precond */
else if (bpostcond) ontrue = bpostcond;
else ontrue = bprecond;
onfalse = bout;
- if (!ir_block_create_if(end_bprecond, precond, ontrue, onfalse))
+ if (!ir_block_create_if(end_bprecond, ast_ctx(self), precond, ontrue, onfalse))
return false;
}
else if (bpostcond) tmpblock = bpostcond;
else if (bprecond) tmpblock = bprecond;
else tmpblock = bbody;
- if (!end_bbody->final && !ir_block_create_jump(end_bbody, tmpblock))
+ if (!end_bbody->final && !ir_block_create_jump(end_bbody, ast_ctx(self), tmpblock))
return false;
}
else if (bprecond) tmpblock = bprecond;
else if (bbody) tmpblock = bbody;
else tmpblock = bout;
- if (!ir_block_create_jump(end_bincrement, tmpblock))
+ if (!ir_block_create_jump(end_bincrement, ast_ctx(self), tmpblock))
return false;
}
else if (bincrement) ontrue = bincrement;
else ontrue = bpostcond;
onfalse = bout;
- if (!ir_block_create_if(end_bpostcond, postcond, ontrue, onfalse))
+ if (!ir_block_create_if(end_bpostcond, ast_ctx(self), postcond, ontrue, onfalse))
return false;
}
return false;
}
- if (!ir_block_create_jump(func->curblock, target))
+ if (!ir_block_create_jump(func->curblock, ast_ctx(self), target))
return false;
return true;
}
if (!(*cgen)((ast_expression*)(swcase->value), func, false, &val))
return false;
/* generate the condition */
- cond = ir_block_create_binop(func->curblock, ast_function_label(func, "switch_eq"), cmpinstr, irop, val);
+ cond = ir_block_create_binop(func->curblock, ast_ctx(self), ast_function_label(func, "switch_eq"), cmpinstr, irop, val);
if (!cond)
return false;
bnot = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "not_case"));
if (!bcase || !bnot)
return false;
- if (!ir_block_create_if(func->curblock, cond, bcase, bnot))
+ if (!ir_block_create_if(func->curblock, ast_ctx(self), cond, bcase, bnot))
return false;
/* Make the previous case-end fall through */
if (bfall && !bfall->final) {
- if (!ir_block_create_jump(bfall, bcase))
+ if (!ir_block_create_jump(bfall, ast_ctx(self), bcase))
return false;
}
}
/* Jump from the last bnot to bout */
- if (bfall && !bfall->final && !ir_block_create_jump(bfall, bout)) {
+ if (bfall && !bfall->final && !ir_block_create_jump(bfall, ast_ctx(self), bout)) {
/*
astwarning(ast_ctx(bfall), WARN_???, "missing break after last case");
*/
/* Insert the fallthrough jump */
if (def_bfall && !def_bfall->final) {
- if (!ir_block_create_jump(def_bfall, bcase))
+ if (!ir_block_create_jump(def_bfall, ast_ctx(self), bcase))
return false;
}
}
/* Jump from the last bnot to bout */
- if (!func->curblock->final && !ir_block_create_jump(func->curblock, bout))
+ if (!func->curblock->final && !ir_block_create_jump(func->curblock, ast_ctx(self), bout))
return false;
/* enter the outgoing block */
func->curblock = bout;
return false;
}
if (!func->curblock->final) {
- if (!ir_block_create_jump(func->curblock, self->irblock))
+ if (!ir_block_create_jump(func->curblock, ast_ctx(self), self->irblock))
return false;
}
if (self->irblock_from) {
/* we already tried once, this is the callback */
self->irblock_from->final = false;
- if (!ir_block_create_jump(self->irblock_from, self->target->irblock)) {
+ if (!ir_block_create_jump(self->irblock_from, ast_ctx(self), self->target->irblock)) {
compile_error(ast_ctx(self), "failed to generate goto to `%s`", self->name);
return false;
}
}
else
{
- if (!ir_block_create_jump(func->curblock, self->target->irblock)) {
+ if (!ir_block_create_jump(func->curblock, ast_ctx(self), self->target->irblock)) {
compile_error(ast_ctx(self), "failed to generate goto to `%s`", self->name);
return false;
}
vec_push(params, param);
}
- callinstr = ir_block_create_call(func->curblock, ast_function_label(func, "call"), funval);
+ callinstr = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "call"), funval);
if (!callinstr)
goto error;