more c++ migration for ast/ir/code; reached a working condition here

This commit is contained in:
Wolfgang Bumiller 2015-01-20 20:25:56 +01:00
parent f09c6a5d63
commit 566e761546
10 changed files with 252 additions and 189 deletions

18
algo.h Normal file
View file

@ -0,0 +1,18 @@
#ifndef GMQCC_ALGO_HDR
#define GMQCC_ALGO_HDR
namespace algo {
template<typename ITER>
void shiftback(ITER element, ITER end) {
//typename ITER::value_type backup(move(*element)); // hold the element
typename std::remove_reference<decltype(*element)>::type backup(move(*element)); // hold the element
ITER p = element++;
for (; element != end; p = element++)
*p = move(*element);
*p = move(backup);
}
} // ::algo
#endif

42
ast.cpp
View file

@ -8,6 +8,8 @@
#include "fold.h" #include "fold.h"
//#include "parser.h" //#include "parser.h"
#include "algo.h"
#define ast_instantiate(T, ctx, destroyfn) \ #define ast_instantiate(T, ctx, destroyfn) \
T* self = (T*)mem_a(sizeof(T)); \ T* self = (T*)mem_a(sizeof(T)); \
if (!self) { \ if (!self) { \
@ -387,6 +389,7 @@ void ast_value_delete(ast_value* self)
} }
ast_expression_delete((ast_expression*)self); ast_expression_delete((ast_expression*)self);
self->~ast_value();
mem_d(self); mem_d(self);
} }
@ -1211,8 +1214,9 @@ void ast_function_delete(ast_function *self)
} }
for (auto &it : self->static_names) for (auto &it : self->static_names)
mem_d(it); mem_d(it);
for (auto &it : self->blocks) // FIXME::DELME:: unique_ptr used on ast_block
ast_delete(it); //for (auto &it : self->blocks)
// ast_delete(it);
if (self->varargs) if (self->varargs)
ast_delete(self->varargs); ast_delete(self->varargs);
if (self->argc) if (self->argc)
@ -1844,7 +1848,7 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir)
for (auto &it : self->blocks) { for (auto &it : self->blocks) {
cgen = it->codegen; cgen = it->codegen;
if (!(*cgen)((ast_expression*)it, self, false, &dummy)) if (!(*cgen)(it.get(), self, false, &dummy))
return false; return false;
} }
@ -2105,8 +2109,12 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va
if (!ir_block_create_jump(func->curblock, ast_ctx(self), merge)) if (!ir_block_create_jump(func->curblock, ast_ctx(self), merge))
return false; return false;
func->ir_func->blocks.erase(func->ir_func->blocks.begin() + merge_id); algo::shiftback(func->ir_func->blocks.begin() + merge_id,
func->ir_func->blocks.emplace_back(merge); func->ir_func->blocks.end());
// FIXME::DELME::
//func->ir_func->blocks[merge_id].release();
//func->ir_func->blocks.erase(func->ir_func->blocks.begin() + merge_id);
//func->ir_func->blocks.emplace_back(merge);
func->curblock = merge; func->curblock = merge;
phi = ir_block_create_phi(func->curblock, ast_ctx(self), phi = ir_block_create_phi(func->curblock, ast_ctx(self),
@ -3011,8 +3019,12 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value
} }
/* Move 'bout' to the end */ /* Move 'bout' to the end */
func->ir_func->blocks.erase(func->ir_func->blocks.begin() + bout_id); algo::shiftback(func->ir_func->blocks.begin() + bout_id,
func->ir_func->blocks.emplace_back(bout); func->ir_func->blocks.end());
// FIXME::DELME::
//func->ir_func->blocks[bout_id].release(); // it's a vector<unique_ptr<>>
//func->ir_func->blocks.erase(func->ir_func->blocks.begin() + bout_id);
//func->ir_func->blocks.emplace_back(bout);
return true; return true;
} }
@ -3151,8 +3163,12 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va
/* enter the else and move it down */ /* enter the else and move it down */
func->curblock = bnot; func->curblock = bnot;
func->ir_func->blocks.erase(func->ir_func->blocks.begin() + bnot_id); algo::shiftback(func->ir_func->blocks.begin() + bnot_id,
func->ir_func->blocks.emplace_back(bnot); func->ir_func->blocks.end());
// FIXME::DELME::
//func->ir_func->blocks[bnot_id].release();
//func->ir_func->blocks.erase(func->ir_func->blocks.begin() + bnot_id);
//func->ir_func->blocks.emplace_back(bnot);
} else { } else {
/* The default case */ /* The default case */
/* Remember where to fall through from: */ /* Remember where to fall through from: */
@ -3209,8 +3225,12 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va
func->breakblocks.pop_back(); func->breakblocks.pop_back();
/* Move 'bout' to the end, it's nicer */ /* Move 'bout' to the end, it's nicer */
func->ir_func->blocks.erase(func->ir_func->blocks.begin() + bout_id); algo::shiftback(func->ir_func->blocks.begin() + bout_id,
func->ir_func->blocks.emplace_back(bout); func->ir_func->blocks.end());
// FIXME::DELME::
//func->ir_func->blocks[bout_id].release();
//func->ir_func->blocks.erase(func->ir_func->blocks.begin() + bout_id);
//func->ir_func->blocks.emplace_back(bout);
return true; return true;
} }

2
ast.h
View file

@ -626,7 +626,7 @@ struct ast_function
* here to use in ast_function_label. * here to use in ast_function_label.
*/ */
char labelbuf[64]; char labelbuf[64];
std::vector<ast_block*> blocks; std::vector<std::unique_ptr<ast_block>> blocks;
ast_value *varargs; ast_value *varargs;
ast_value *argc; ast_value *argc;
ast_value *fixedparams; ast_value *fixedparams;

View file

@ -106,35 +106,39 @@ void code_pop_statement(code_t *code)
code->columnnums.pop_back(); code->columnnums.pop_back();
} }
code_t *code_init() { void *code_t::operator new(std::size_t bytes) {
return mem_a(bytes);
}
void code_t::operator delete(void *ptr) {
mem_d(ptr);
}
code_t::code_t()
{
static lex_ctx_t empty_ctx = {0, 0, 0}; static lex_ctx_t empty_ctx = {0, 0, 0};
static prog_section_function_t empty_function = {0,0,0,0,0,0,0,{0,0,0,0,0,0,0,0}}; static prog_section_function_t empty_function = {0,0,0,0,0,0,0,{0,0,0,0,0,0,0,0}};
static prog_section_statement_t empty_statement = {0,{0},{0},{0}}; static prog_section_statement_t empty_statement = {0,{0},{0},{0}};
static prog_section_def_t empty_def = {0, 0, 0}; static prog_section_def_t empty_def = {0, 0, 0};
code_t *code = (code_t*)mem_a(sizeof(code_t)); string_cache = util_htnew(OPTS_OPTIMIZATION(OPTIM_OVERLAP_STRINGS) ? 0x100 : 1024);
int i = 0;
memset(code, 0, sizeof(code_t)); // The way progs.dat is suppose to work is odd, there needs to be
code->entfields = 0; // some null (empty) statements, functions, and 28 globals
code->string_cache = util_htnew(OPTS_OPTIMIZATION(OPTIM_OVERLAP_STRINGS) ? 0x100 : 1024); globals.insert(globals.begin(), 28, 0);
/* chars.push_back('\0');
* The way progs.dat is suppose to work is odd, there needs to be functions.push_back(empty_function);
* some null (empty) statements, functions, and 28 globals
*/
for(; i < 28; i++)
code->globals.push_back(0);
code->chars.push_back('\0'); code_push_statement(this, &empty_statement, empty_ctx);
code->functions.push_back(empty_function);
code_push_statement(code, &empty_statement, empty_ctx); defs.push_back(empty_def);
fields.push_back(empty_def);
}
code->defs.push_back(empty_def); code_t::~code_t()
code->fields.push_back(empty_def); {
util_htdel(string_cache);
return code;
} }
void *code_util_str_htgeth(hash_table_t *ht, const char *key, size_t bin); void *code_util_str_htgeth(hash_table_t *ht, const char *key, size_t bin);
@ -342,8 +346,3 @@ bool code_write(code_t *code, const char *filename, const char *lnofile) {
code_stats(filename, lnofile, code, &code_header); code_stats(filename, lnofile, code, &code_header);
return true; return true;
} }
void code_cleanup(code_t *code) {
util_htdel(code->string_cache);
mem_d(code);
}

10
gmqcc.h
View file

@ -502,6 +502,10 @@ typedef int32_t qcint_t;
typedef uint32_t qcuint_t; typedef uint32_t qcuint_t;
struct code_t { struct code_t {
void* operator new(std::size_t);
void operator delete(void*);
code_t();
~code_t();
std::vector<prog_section_statement_t> statements; std::vector<prog_section_statement_t> statements;
std::vector<int> linenums; std::vector<int> linenums;
std::vector<int> columnnums; std::vector<int> columnnums;
@ -510,10 +514,10 @@ struct code_t {
std::vector<prog_section_function_t> functions; std::vector<prog_section_function_t> functions;
std::vector<int> globals; std::vector<int> globals;
std::vector<char> chars; std::vector<char> chars;
uint16_t crc; uint16_t crc = 0;
uint32_t entfields; uint32_t entfields = 0;
ht string_cache; ht string_cache;
qcint_t string_cached_empty; qcint_t string_cached_empty = 0;
}; };
/* /*

View file

@ -80,7 +80,7 @@ ast_expression *intrin::isfinite_() {
) )
); );
func->blocks.push_back(block); func->blocks.emplace_back(block);
reg(val, func); reg(val, func);
return (ast_expression*)val;; return (ast_expression*)val;;
@ -125,7 +125,7 @@ ast_expression *intrin::isinf_() {
); );
val->type_params.push_back(x); val->type_params.push_back(x);
func->blocks.push_back(body); func->blocks.emplace_back(body);
reg(val, func); reg(val, func);
@ -170,7 +170,7 @@ ast_expression *intrin::isnan_() {
); );
val->type_params.push_back(arg1); val->type_params.push_back(arg1);
func->blocks.push_back(body); func->blocks.emplace_back(body);
reg(val, func); reg(val, func);
@ -200,7 +200,7 @@ ast_expression *intrin::isnormal_() {
) )
); );
func->blocks.push_back(body); func->blocks.emplace_back(body);
reg(val, func); reg(val, func);
return (ast_expression*)val; return (ast_expression*)val;
} }
@ -236,7 +236,7 @@ ast_expression *intrin::signbit_() {
) )
); );
func->blocks.push_back(body); func->blocks.emplace_back(body);
reg(val, func); reg(val, func);
return (ast_expression*)val; return (ast_expression*)val;
} }
@ -289,7 +289,7 @@ ast_expression *intrin::acosh_() {
) )
); );
func->blocks.push_back(body); func->blocks.emplace_back(body);
reg(val, func); reg(val, func);
return (ast_expression*)val; return (ast_expression*)val;
} }
@ -342,7 +342,7 @@ ast_expression *intrin::asinh_() {
) )
); );
func->blocks.push_back(body); func->blocks.emplace_back(body);
reg(val, func); reg(val, func);
return (ast_expression*)val; return (ast_expression*)val;
} }
@ -391,7 +391,7 @@ ast_expression *intrin::atanh_() {
) )
); );
func->blocks.push_back(body); func->blocks.emplace_back(body);
reg(val, func); reg(val, func);
return (ast_expression*)val; return (ast_expression*)val;
} }
@ -504,7 +504,7 @@ ast_expression *intrin::exp_() {
) )
); );
func->blocks.push_back(body); func->blocks.emplace_back(body);
reg(val, func); reg(val, func);
return (ast_expression*)val; return (ast_expression*)val;
} }
@ -534,7 +534,7 @@ ast_expression *intrin::exp2_() {
) )
); );
func->blocks.push_back(body); func->blocks.emplace_back(body);
reg(val, func); reg(val, func);
return (ast_expression*)val; return (ast_expression*)val;
} }
@ -569,7 +569,7 @@ ast_expression *intrin::expm1_() {
) )
); );
func->blocks.push_back(body); func->blocks.emplace_back(body);
reg(val, func); reg(val, func);
return (ast_expression*)val; return (ast_expression*)val;
} }
@ -1014,7 +1014,7 @@ ast_expression *intrin::pow_() {
); );
/* } */ /* } */
func->blocks.push_back(body); func->blocks.emplace_back(body);
reg(val, func); reg(val, func);
return (ast_expression*)val; return (ast_expression*)val;
} }
@ -1110,7 +1110,7 @@ ast_expression *intrin::mod_() {
) )
); );
func->blocks.push_back(body); func->blocks.emplace_back(body);
reg(val, func); reg(val, func);
return (ast_expression*)val; return (ast_expression*)val;
} }
@ -1149,7 +1149,7 @@ ast_expression *intrin::fabs_() {
val->type_params.push_back(arg1); val->type_params.push_back(arg1);
func->blocks.push_back(body); func->blocks.emplace_back(body);
reg(val, func); reg(val, func);
return (ast_expression*)val; return (ast_expression*)val;
} }
@ -1221,7 +1221,7 @@ ast_expression *intrin::epsilon_() {
) )
); );
func->blocks.push_back(body); func->blocks.emplace_back(body);
reg(val, func); reg(val, func);
return (ast_expression*)val; return (ast_expression*)val;
} }
@ -1261,7 +1261,7 @@ ast_expression *intrin::nan_() {
) )
); );
func->blocks.push_back(block); func->blocks.emplace_back(block);
reg(val, func); reg(val, func);
return (ast_expression*)val; return (ast_expression*)val;
} }
@ -1308,7 +1308,7 @@ ast_expression *intrin::inf_() {
) )
); );
func->blocks.push_back(block); func->blocks.emplace_back(block);
reg(val, func); reg(val, func);
return (ast_expression*)val; return (ast_expression*)val;
} }
@ -1852,7 +1852,7 @@ ast_expression *intrin::ln_() {
) )
); );
func->blocks.push_back(block); func->blocks.emplace_back(block);
reg(val, func); reg(val, func);
return (ast_expression*)val; return (ast_expression*)val;
} }
@ -1876,7 +1876,7 @@ ast_expression *intrin::log_variant(const char *name, float base) {
) )
); );
func->blocks.push_back(body); func->blocks.emplace_back(body);
reg(val, func); reg(val, func);
return (ast_expression*)val; return (ast_expression*)val;
} }
@ -1933,7 +1933,7 @@ ast_expression *intrin::shift_variant(const char *name, size_t instr) {
) )
); );
func->blocks.push_back(body); func->blocks.emplace_back(body);
reg(val, func); reg(val, func);
return (ast_expression*)val; return (ast_expression*)val;
} }

226
ir.cpp
View file

@ -203,7 +203,6 @@ static bool GMQCC_WARN ir_block_create_store(ir_block*, lex_ctx_t, ir_value *tar
static void ir_block_dump(ir_block*, char *ind, int (*oprintf)(const char*,...)); static void ir_block_dump(ir_block*, char *ind, int (*oprintf)(const char*,...));
static bool ir_instr_op(ir_instr*, int op, ir_value *value, bool writing); static bool ir_instr_op(ir_instr*, int op, ir_value *value, bool writing);
static void ir_instr_delete(ir_instr*);
static void ir_instr_dump(ir_instr* in, char *ind, int (*oprintf)(const char*,...)); static void ir_instr_dump(ir_instr* in, char *ind, int (*oprintf)(const char*,...));
/* error functions */ /* error functions */
@ -285,7 +284,8 @@ void ir_builder::operator delete(void *ptr)
} }
ir_builder::ir_builder(const std::string& modulename) ir_builder::ir_builder(const std::string& modulename)
: name(modulename) : name(modulename),
code(new code_t)
{ {
htglobals = util_htnew(IR_HT_SIZE); htglobals = util_htnew(IR_HT_SIZE);
htfields = util_htnew(IR_HT_SIZE); htfields = util_htnew(IR_HT_SIZE);
@ -302,8 +302,6 @@ ir_builder::ir_builder(const std::string& modulename)
vinstr_temp[i] = new ir_value("vinstr_temp", store_value, TYPE_NOEXPR); vinstr_temp[i] = new ir_value("vinstr_temp", store_value, TYPE_NOEXPR);
vinstr_temp[i]->cvq = CV_CONST; vinstr_temp[i]->cvq = CV_CONST;
} }
code = code_init();
} }
ir_builder::~ir_builder() ir_builder::~ir_builder()
@ -321,7 +319,8 @@ ir_builder::~ir_builder()
delete vinstr_temp[i]; delete vinstr_temp[i];
} }
code_cleanup(code); extparams.clear();
extparam_protos.clear();
} }
static ir_function* ir_builder_get_function(ir_builder *self, const char *name) static ir_function* ir_builder_get_function(ir_builder *self, const char *name)
@ -527,7 +526,7 @@ static bool ir_function_pass_peephole(ir_function *self)
(void)!ir_instr_op(oper, 0, store->_ops[0], true); (void)!ir_instr_op(oper, 0, store->_ops[0], true);
vec_remove(block->instr, i, 1); vec_remove(block->instr, i, 1);
ir_instr_delete(store); delete store;
} }
else if (inst->opcode == VINSTR_COND) else if (inst->opcode == VINSTR_COND)
{ {
@ -569,7 +568,7 @@ static bool ir_function_pass_peephole(ir_function *self)
return false; return false;
} }
vec_remove(tmp->instr, inotid, 1); vec_remove(tmp->instr, inotid, 1);
ir_instr_delete(inot); delete inot;
/* swap ontrue/onfalse */ /* swap ontrue/onfalse */
tmp = inst->bops[0]; tmp = inst->bops[0];
inst->bops[0] = inst->bops[1]; inst->bops[0] = inst->bops[1];
@ -627,7 +626,7 @@ static bool ir_function_pass_tailrecursion(ir_function *self)
++opts_optimizationcount[OPTIM_PEEPHOLE]; ++opts_optimizationcount[OPTIM_PEEPHOLE];
call->_ops[0] = store->_ops[0]; call->_ops[0] = store->_ops[0];
vec_remove(block->instr, vec_size(block->instr) - 2, 1); vec_remove(block->instr, vec_size(block->instr) - 2, 1);
ir_instr_delete(store); delete store;
} }
else else
continue; continue;
@ -664,8 +663,8 @@ static bool ir_function_pass_tailrecursion(ir_function *self)
return false; return false;
} }
ir_instr_delete(call); delete call;
ir_instr_delete(ret); delete ret;
} }
return true; return true;
@ -767,7 +766,7 @@ ir_block::ir_block(ir_function* owner, const std::string& name)
ir_block::~ir_block() ir_block::~ir_block()
{ {
for (size_t i = 0; i != vec_size(instr); ++i) for (size_t i = 0; i != vec_size(instr); ++i)
ir_instr_delete(instr[i]); delete instr[i];
vec_free(instr); vec_free(instr);
vec_free(entries); vec_free(entries);
vec_free(exits); vec_free(exits);
@ -786,55 +785,54 @@ static void ir_block_delete_quick(ir_block* self)
*IR Instructions *IR Instructions
*/ */
static ir_instr* ir_instr_new(lex_ctx_t ctx, ir_block* owner, int op) void* ir_instr::operator new(std::size_t bytes) {
return mem_a(bytes);
}
void ir_instr::operator delete(void *data) {
mem_d(data);
}
ir_instr::ir_instr(lex_ctx_t ctx, ir_block* owner_, int op)
: opcode(op),
context(ctx),
owner(owner_)
{ {
ir_instr *self = new ir_instr; }
self->owner = owner;
self->context = ctx; ir_instr::~ir_instr()
self->opcode = op; {
self->_ops[0] = nullptr; // The following calls can only delete from
self->_ops[1] = nullptr; // vectors, we still want to delete this instruction
self->_ops[2] = nullptr; // so ignore the return value. Since with the warn_unused_result attribute
self->bops[0] = nullptr; // gcc doesn't care about an explicit: (void)foo(); to ignore the result,
self->bops[1] = nullptr; // I have to improvise here and use if(foo());
self->eid = 0; for (auto &it : phi) {
self->likely = true; size_t idx;
return self; if (vec_ir_instr_find(it.value->writes, this, &idx))
it.value->writes.erase(it.value->writes.begin() + idx);
if (vec_ir_instr_find(it.value->reads, this, &idx))
it.value->reads.erase(it.value->reads.begin() + idx);
}
for (auto &it : params) {
size_t idx;
if (vec_ir_instr_find(it->writes, this, &idx))
it->writes.erase(it->writes.begin() + idx);
if (vec_ir_instr_find(it->reads, this, &idx))
it->reads.erase(it->reads.begin() + idx);
}
(void)!ir_instr_op(this, 0, nullptr, false);
(void)!ir_instr_op(this, 1, nullptr, false);
(void)!ir_instr_op(this, 2, nullptr, false);
} }
static void ir_instr_delete_quick(ir_instr *self) static void ir_instr_delete_quick(ir_instr *self)
{ {
self->phi.clear();
self->params.clear();
delete self; delete self;
} }
static void ir_instr_delete(ir_instr *self)
{
/* The following calls can only delete from
* vectors, we still want to delete this instruction
* so ignore the return value. Since with the warn_unused_result attribute
* gcc doesn't care about an explicit: (void)foo(); to ignore the result,
* I have to improvise here and use if(foo());
*/
for (auto &it : self->phi) {
size_t idx;
if (vec_ir_instr_find(it.value->writes, self, &idx))
it.value->writes.erase(it.value->writes.begin() + idx);
if (vec_ir_instr_find(it.value->reads, self, &idx))
it.value->reads.erase(it.value->reads.begin() + idx);
}
for (auto &it : self->params) {
size_t idx;
if (vec_ir_instr_find(it->writes, self, &idx))
it->writes.erase(it->writes.begin() + idx);
if (vec_ir_instr_find(it->reads, self, &idx))
it->reads.erase(it->reads.begin() + idx);
}
(void)!ir_instr_op(self, 0, nullptr, false);
(void)!ir_instr_op(self, 1, nullptr, false);
(void)!ir_instr_op(self, 2, nullptr, false);
mem_d(self);
}
static bool ir_instr_op(ir_instr *self, int op, ir_value *v, bool writing) static bool ir_instr_op(ir_instr *self, int op, ir_value *v, bool writing)
{ {
if (v && v->vtype == TYPE_NOEXPR) { if (v && v->vtype == TYPE_NOEXPR) {
@ -1119,7 +1117,7 @@ static bool ir_value_life_merge(ir_value *self, size_t s)
{ {
/* merge */ /* merge */
before->end = life_found->end; before->end = life_found->end;
self->life.erase(self->life.begin()+1); self->life.erase(self->life.begin()+i);
return true; return true;
} }
if (before->end + 1 == s) if (before->end + 1 == s)
@ -1297,14 +1295,14 @@ bool ir_block_create_store_op(ir_block *self, lex_ctx_t ctx, int op, ir_value *t
return false; return false;
} }
in = ir_instr_new(ctx, self, op); in = new ir_instr(ctx, self, op);
if (!in) if (!in)
return false; return false;
if (!ir_instr_op(in, 0, target, (op < INSTR_STOREP_F || op > INSTR_STOREP_FNC)) || if (!ir_instr_op(in, 0, target, (op < INSTR_STOREP_F || op > INSTR_STOREP_FNC)) ||
!ir_instr_op(in, 1, what, false)) !ir_instr_op(in, 1, what, false))
{ {
ir_instr_delete(in); delete in;
return false; return false;
} }
vec_push(self->instr, in); vec_push(self->instr, in);
@ -1317,14 +1315,14 @@ bool ir_block_create_state_op(ir_block *self, lex_ctx_t ctx, ir_value *frame, ir
if (!ir_check_unreachable(self)) if (!ir_check_unreachable(self))
return false; return false;
in = ir_instr_new(ctx, self, INSTR_STATE); in = new ir_instr(ctx, self, INSTR_STATE);
if (!in) if (!in)
return false; return false;
if (!ir_instr_op(in, 0, frame, false) || if (!ir_instr_op(in, 0, frame, false) ||
!ir_instr_op(in, 1, think, false)) !ir_instr_op(in, 1, think, false))
{ {
ir_instr_delete(in); delete in;
return false; return false;
} }
vec_push(self->instr, in); vec_push(self->instr, in);
@ -1387,12 +1385,12 @@ bool ir_block_create_return(ir_block *self, lex_ctx_t ctx, ir_value *v)
self->final = true; self->final = true;
self->is_return = true; self->is_return = true;
in = ir_instr_new(ctx, self, INSTR_RETURN); in = new ir_instr(ctx, self, INSTR_RETURN);
if (!in) if (!in)
return false; return false;
if (v && !ir_instr_op(in, 0, v, false)) { if (v && !ir_instr_op(in, 0, v, false)) {
ir_instr_delete(in); delete in;
return false; return false;
} }
@ -1407,13 +1405,13 @@ bool ir_block_create_if(ir_block *self, lex_ctx_t ctx, ir_value *v,
if (!ir_check_unreachable(self)) if (!ir_check_unreachable(self))
return false; return false;
self->final = true; self->final = true;
/*in = ir_instr_new(ctx, self, (v->vtype == TYPE_STRING ? INSTR_IF_S : INSTR_IF_F));*/ /*in = new ir_instr(ctx, self, (v->vtype == TYPE_STRING ? INSTR_IF_S : INSTR_IF_F));*/
in = ir_instr_new(ctx, self, VINSTR_COND); in = new ir_instr(ctx, self, VINSTR_COND);
if (!in) if (!in)
return false; return false;
if (!ir_instr_op(in, 0, v, false)) { if (!ir_instr_op(in, 0, v, false)) {
ir_instr_delete(in); delete in;
return false; return false;
} }
@ -1435,7 +1433,7 @@ bool ir_block_create_jump(ir_block *self, lex_ctx_t ctx, ir_block *to)
if (!ir_check_unreachable(self)) if (!ir_check_unreachable(self))
return false; return false;
self->final = true; self->final = true;
in = ir_instr_new(ctx, self, VINSTR_JUMP); in = new ir_instr(ctx, self, VINSTR_JUMP);
if (!in) if (!in)
return false; return false;
@ -1459,16 +1457,16 @@ ir_instr* ir_block_create_phi(ir_block *self, lex_ctx_t ctx, const char *label,
ir_instr *in; ir_instr *in;
if (!ir_check_unreachable(self)) if (!ir_check_unreachable(self))
return nullptr; return nullptr;
in = ir_instr_new(ctx, self, VINSTR_PHI); in = new ir_instr(ctx, self, VINSTR_PHI);
if (!in) if (!in)
return nullptr; return nullptr;
out = ir_value_out(self->owner, label, store_value, ot); out = ir_value_out(self->owner, label, store_value, ot);
if (!out) { if (!out) {
ir_instr_delete(in); delete in;
return nullptr; return nullptr;
} }
if (!ir_instr_op(in, 0, out, true)) { if (!ir_instr_op(in, 0, out, true)) {
ir_instr_delete(in); delete in;
return nullptr; return nullptr;
} }
vec_push(self->instr, in); vec_push(self->instr, in);
@ -1485,9 +1483,8 @@ void ir_phi_add(ir_instr* self, ir_block *b, ir_value *v)
ir_phi_entry_t pe; ir_phi_entry_t pe;
if (!vec_ir_block_find(self->owner->entries, b, nullptr)) { if (!vec_ir_block_find(self->owner->entries, b, nullptr)) {
/* Must not be possible to cause this, otherwise the AST // Must not be possible to cause this, otherwise the AST
* is doing something wrong. // is doing something wrong.
*/
irerror(self->context, "Invalid entry block for PHI"); irerror(self->context, "Invalid entry block for PHI");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -1505,7 +1502,7 @@ ir_instr* ir_block_create_call(ir_block *self, lex_ctx_t ctx, const char *label,
ir_instr *in; ir_instr *in;
if (!ir_check_unreachable(self)) if (!ir_check_unreachable(self))
return nullptr; return nullptr;
in = ir_instr_new(ctx, self, (noreturn ? VINSTR_NRCALL : INSTR_CALL0)); in = new ir_instr(ctx, self, (noreturn ? VINSTR_NRCALL : INSTR_CALL0));
if (!in) if (!in)
return nullptr; return nullptr;
if (noreturn) { if (noreturn) {
@ -1514,13 +1511,13 @@ ir_instr* ir_block_create_call(ir_block *self, lex_ctx_t ctx, const char *label,
} }
out = ir_value_out(self->owner, label, (func->outtype == TYPE_VOID) ? store_return : store_value, func->outtype); out = ir_value_out(self->owner, label, (func->outtype == TYPE_VOID) ? store_return : store_value, func->outtype);
if (!out) { if (!out) {
ir_instr_delete(in); delete in;
return nullptr; return nullptr;
} }
if (!ir_instr_op(in, 0, out, true) || if (!ir_instr_op(in, 0, out, true) ||
!ir_instr_op(in, 1, func, false)) !ir_instr_op(in, 1, func, false))
{ {
ir_instr_delete(in); delete in;
return nullptr; return nullptr;
} }
vec_push(self->instr, in); vec_push(self->instr, in);
@ -1528,7 +1525,7 @@ ir_instr* ir_block_create_call(ir_block *self, lex_ctx_t ctx, const char *label,
if (noreturn) { if (noreturn) {
if (!ir_block_create_return(self, ctx, nullptr)) { if (!ir_block_create_return(self, ctx, nullptr)) {
compile_error(ctx, "internal error: failed to generate dummy-return instruction"); compile_error(ctx, "internal error: failed to generate dummy-return instruction");
ir_instr_delete(in); delete in;
return nullptr; return nullptr;
} }
} }
@ -1715,7 +1712,7 @@ static ir_value* ir_block_create_general_instr(ir_block *self, lex_ctx_t ctx, co
if (!out) if (!out)
return nullptr; return nullptr;
instr = ir_instr_new(ctx, self, op); instr = new ir_instr(ctx, self, op);
if (!instr) { if (!instr) {
return nullptr; return nullptr;
} }
@ -1731,7 +1728,7 @@ static ir_value* ir_block_create_general_instr(ir_block *self, lex_ctx_t ctx, co
return out; return out;
on_error: on_error:
ir_instr_delete(instr); delete instr;
return nullptr; return nullptr;
} }
@ -1830,7 +1827,7 @@ static bool ir_block_naive_phi(ir_block *self)
b->final = true; b->final = true;
} }
} }
ir_instr_delete(instr); delete instr;
} }
return true; return true;
} }
@ -2190,12 +2187,8 @@ static bool ir_block_life_propagate(ir_block *self, bool *changed)
ir_instr *instr; ir_instr *instr;
ir_value *value; ir_value *value;
size_t i, o, p, mem; size_t i, o, p, mem;
/* bitmasks which operands are read from or written to */ // bitmasks which operands are read from or written to
size_t read, write; size_t read, write;
char dbg_ind[16];
dbg_ind[0] = '#';
dbg_ind[1] = '0';
(void)dbg_ind;
self->living.clear(); self->living.clear();
@ -2397,21 +2390,17 @@ static bool ir_block_life_propagate(ir_block *self, bool *changed)
bool ir_function_calculate_liferanges(ir_function *self) bool ir_function_calculate_liferanges(ir_function *self)
{ {
size_t i, s;
bool changed;
/* parameters live at 0 */ /* parameters live at 0 */
for (i = 0; i < vec_size(self->params); ++i) for (size_t i = 0; i < vec_size(self->params); ++i)
if (!ir_value_life_merge(self->locals[i].get(), 0)) if (!ir_value_life_merge(self->locals[i].get(), 0))
compile_error(self->context, "internal error: failed value-life merging"); compile_error(self->context, "internal error: failed value-life merging");
bool changed;
do { do {
self->run_id++; self->run_id++;
changed = false; changed = false;
i = self->blocks.size(); for (auto i = self->blocks.rbegin(); i != self->blocks.rend(); ++i)
while (i--) { ir_block_life_propagate(i->get(), &changed);
ir_block_life_propagate(self->blocks[i].get(), &changed);
}
} while (changed); } while (changed);
if (self->blocks.size()) { if (self->blocks.size()) {
@ -2424,7 +2413,8 @@ bool ir_function_calculate_liferanges(ir_function *self)
continue; continue;
self->flags |= IR_FLAG_HAS_UNINITIALIZED; self->flags |= IR_FLAG_HAS_UNINITIALIZED;
/* find the instruction reading from it */ /* find the instruction reading from it */
for (s = 0; s < v->reads.size(); ++s) { size_t s = 0;
for (; s < v->reads.size(); ++s) {
if (v->reads[s]->eid == v->life[0].end) if (v->reads[s]->eid == v->life[0].end)
break; break;
} }
@ -2902,7 +2892,7 @@ static bool gen_blocks_recursive(code_t *code, ir_function *func, ir_block *bloc
if (p-8 >= ir->extparams.size()) if (p-8 >= ir->extparams.size())
ir_gen_extparam(ir); ir_gen_extparam(ir);
targetparam = ir->extparams[p-8].get(); targetparam = ir->extparams[p-8];
stmt.opcode = INSTR_STORE_F; stmt.opcode = INSTR_STORE_F;
stmt.o3.u1 = 0; stmt.o3.u1 = 0;
@ -3069,7 +3059,7 @@ static qcint_t ir_builder_filestring(ir_builder *ir, const char *filename)
return i; return i;
} }
str = code_genstring(ir->code, filename); str = code_genstring(ir->code.get(), filename);
ir->filenames.push_back(filename); ir->filenames.push_back(filename);
ir->filestrings.push_back(str); ir->filestrings.push_back(str);
return str; return str;
@ -3137,7 +3127,7 @@ static void ir_gen_extparam(ir_builder *ir)
else else
global = ir->extparam_protos[ir->extparams.size()].get(); global = ir->extparam_protos[ir->extparams.size()].get();
def.name = code_genstring(ir->code, global->name.c_str()); def.name = code_genstring(ir->code.get(), global->name.c_str());
def.type = TYPE_VECTOR; def.type = TYPE_VECTOR;
def.offset = ir->code->globals.size(); def.offset = ir->code->globals.size();
@ -3168,7 +3158,7 @@ static bool gen_function_extparam_copy(code_t *code, ir_function *self)
if (ext >= ir->extparams.size()) if (ext >= ir->extparams.size())
ir_gen_extparam(ir); ir_gen_extparam(ir);
ir_value *ep = ir->extparams[ext].get(); ir_value *ep = ir->extparams[ext];
stmt.opcode = type_store_instr[self->locals[i]->vtype]; stmt.opcode = type_store_instr[self->locals[i]->vtype];
if (self->locals[i]->vtype == TYPE_FIELD && if (self->locals[i]->vtype == TYPE_FIELD &&
@ -3210,7 +3200,7 @@ static bool gen_function_varargs_copy(code_t *code, ir_function *self)
while (ext >= ir->extparams.size()) while (ext >= ir->extparams.size())
ir_gen_extparam(ir); ir_gen_extparam(ir);
ep = ir->extparams[ext].get(); ep = ir->extparams[ext];
stmt.o1.u1 = ir_value_code_addr(ep); stmt.o1.u1 = ir_value_code_addr(ep);
stmt.o2.u1 = ir_value_code_addr(self->locals[i].get()); stmt.o2.u1 = ir_value_code_addr(self->locals[i].get());
@ -3315,15 +3305,15 @@ static bool gen_global_function_code(ir_builder *ir, ir_value *global)
irerror(irfun->context, "Failed to generate locals for function %s", irfun->name.c_str()); irerror(irfun->context, "Failed to generate locals for function %s", irfun->name.c_str());
return false; return false;
} }
if (!gen_function_extparam_copy(ir->code, irfun)) { if (!gen_function_extparam_copy(ir->code.get(), irfun)) {
irerror(irfun->context, "Failed to generate extparam-copy code for function %s", irfun->name.c_str()); irerror(irfun->context, "Failed to generate extparam-copy code for function %s", irfun->name.c_str());
return false; return false;
} }
if (irfun->max_varargs && !gen_function_varargs_copy(ir->code, irfun)) { if (irfun->max_varargs && !gen_function_varargs_copy(ir->code.get(), irfun)) {
irerror(irfun->context, "Failed to generate vararg-copy code for function %s", irfun->name.c_str()); irerror(irfun->context, "Failed to generate vararg-copy code for function %s", irfun->name.c_str());
return false; return false;
} }
if (!gen_function_code(ir->code, irfun)) { if (!gen_function_code(ir->code.get(), irfun)) {
irerror(irfun->context, "Failed to generate code for function %s", irfun->name.c_str()); irerror(irfun->context, "Failed to generate code for function %s", irfun->name.c_str());
return false; return false;
} }
@ -3426,11 +3416,11 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
if (pushdef) { if (pushdef) {
if (global->name[0] == '#') { if (global->name[0] == '#') {
if (!self->str_immediate) if (!self->str_immediate)
self->str_immediate = code_genstring(self->code, "IMMEDIATE"); self->str_immediate = code_genstring(self->code.get(), "IMMEDIATE");
def.name = global->code.name = self->str_immediate; def.name = global->code.name = self->str_immediate;
} }
else else
def.name = global->code.name = code_genstring(self->code, global->name.c_str()); def.name = global->code.name = code_genstring(self->code.get(), global->name.c_str());
} }
else else
def.name = 0; def.name = 0;
@ -3438,9 +3428,9 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
def.offset = ir_value_code_addr(global); def.offset = ir_value_code_addr(global);
self->code->defs.push_back(def); self->code->defs.push_back(def);
if (global->vtype == TYPE_VECTOR) if (global->vtype == TYPE_VECTOR)
gen_vector_defs(self->code, def, global->name.c_str()); gen_vector_defs(self->code.get(), def, global->name.c_str());
else if (global->vtype == TYPE_FIELD && global->fieldtype == TYPE_VECTOR) else if (global->vtype == TYPE_FIELD && global->fieldtype == TYPE_VECTOR)
gen_vector_defs(self->code, def, global->name.c_str()); gen_vector_defs(self->code.get(), def, global->name.c_str());
return true; return true;
} }
} }
@ -3475,14 +3465,14 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
return true; return true;
case TYPE_POINTER: case TYPE_POINTER:
if (pushdef) self->code->defs.push_back(def); if (pushdef) self->code->defs.push_back(def);
return gen_global_pointer(self->code, global); return gen_global_pointer(self->code.get(), global);
case TYPE_FIELD: case TYPE_FIELD:
if (pushdef) { if (pushdef) {
self->code->defs.push_back(def); self->code->defs.push_back(def);
if (global->fieldtype == TYPE_VECTOR) if (global->fieldtype == TYPE_VECTOR)
gen_vector_defs(self->code, def, global->name.c_str()); gen_vector_defs(self->code.get(), def, global->name.c_str());
} }
return gen_global_field(self->code, global); return gen_global_field(self->code.get(), global);
case TYPE_ENTITY: case TYPE_ENTITY:
/* fall through */ /* fall through */
case TYPE_FLOAT: case TYPE_FLOAT:
@ -3504,7 +3494,7 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
{ {
ir_value_code_setaddr(global, self->code->globals.size()); ir_value_code_setaddr(global, self->code->globals.size());
if (global->hasvalue) { if (global->hasvalue) {
uint32_t load = code_genstring(self->code, global->constval.vstring); uint32_t load = code_genstring(self->code.get(), global->constval.vstring);
self->code->globals.push_back(load); self->code->globals.push_back(load);
} else { } else {
self->code->globals.push_back(0); self->code->globals.push_back(0);
@ -3540,7 +3530,7 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
if (pushdef) { if (pushdef) {
self->code->defs.push_back(def); self->code->defs.push_back(def);
def.type &= ~DEF_SAVEGLOBAL; def.type &= ~DEF_SAVEGLOBAL;
gen_vector_defs(self->code, def, global->name.c_str()); gen_vector_defs(self->code.get(), def, global->name.c_str());
} }
return global->code.globaladdr >= 0; return global->code.globaladdr >= 0;
} }
@ -3607,7 +3597,7 @@ static bool ir_builder_gen_field(ir_builder *self, ir_value *field)
memcpy(name+1, field->name.c_str(), len); // no strncpy - we used strlen above memcpy(name+1, field->name.c_str(), len); // no strncpy - we used strlen above
name[len+1] = 0; name[len+1] = 0;
def.name = code_genstring(self->code, name); def.name = code_genstring(self->code.get(), name);
fld.name = def.name + 1; /* we reuse that string table entry */ fld.name = def.name + 1; /* we reuse that string table entry */
} else { } else {
/* in plain QC, there cannot be a global with the same name, /* in plain QC, there cannot be a global with the same name,
@ -3615,7 +3605,7 @@ static bool ir_builder_gen_field(ir_builder *self, ir_value *field)
* FIXME: fteqcc should create a global as well * FIXME: fteqcc should create a global as well
* check if it actually uses the same name. Probably does * check if it actually uses the same name. Probably does
*/ */
def.name = code_genstring(self->code, field->name.c_str()); def.name = code_genstring(self->code.get(), field->name.c_str());
fld.name = def.name; fld.name = def.name;
} }
@ -3642,8 +3632,8 @@ static bool ir_builder_gen_field(ir_builder *self, ir_value *field)
} }
if (field->fieldtype == TYPE_VECTOR) { if (field->fieldtype == TYPE_VECTOR) {
gen_vector_defs (self->code, def, field->name.c_str()); gen_vector_defs (self->code.get(), def, field->name.c_str());
gen_vector_fields(self->code, fld, field->name.c_str()); gen_vector_fields(self->code.get(), fld, field->name.c_str());
} }
return field->code.globaladdr >= 0; return field->code.globaladdr >= 0;
@ -3729,8 +3719,12 @@ static void ir_builder_split_vector(ir_builder *self, ir_value *vec) {
} }
static void ir_builder_split_vectors(ir_builder *self) { static void ir_builder_split_vectors(ir_builder *self) {
for (auto& gp : self->globals) { // member values may be added to self->globals during this operation, but
ir_value *v = gp.get(); // no new vectors will be added, we need to iterate via an index as
// c++ iterators would be invalidated
const size_t count = self->globals.size();
for (size_t i = 0; i != count; ++i) {
ir_value *v = self->globals[i].get();
if (v->vtype != TYPE_VECTOR || !v->name.length() || v->name[0] != '#') if (v->vtype != TYPE_VECTOR || !v->name.length() || v->name[0] != '#')
continue; continue;
ir_builder_split_vector(self, v); ir_builder_split_vector(self, v);
@ -3749,7 +3743,7 @@ bool ir_builder_generate(ir_builder *self, const char *filename)
} }
for (auto& fp : self->fields) for (auto& fp : self->fields)
ir_builder_prepare_field(self->code, fp.get()); ir_builder_prepare_field(self->code.get(), fp.get());
for (auto& gp : self->globals) { for (auto& gp : self->globals) {
ir_value *global = gp.get(); ir_value *global = gp.get();
@ -3832,7 +3826,7 @@ bool ir_builder_generate(ir_builder *self, const char *filename)
last.line = self->code->linenums.back(); last.line = self->code->linenums.back();
last.column = self->code->columnnums.back(); last.column = self->code->columnnums.back();
code_push_statement(self->code, &stmt, last); code_push_statement(self->code.get(), &stmt, last);
} }
if (OPTS_OPTION_BOOL(OPTION_PP_ONLY)) if (OPTS_OPTION_BOOL(OPTION_PP_ONLY))
@ -3856,7 +3850,7 @@ bool ir_builder_generate(ir_builder *self, const char *filename)
memcpy(vec_add(lnofile, 5), ".lno", 5); memcpy(vec_add(lnofile, 5), ".lno", 5);
} }
if (!code_write(self->code, filename, lnofile)) { if (!code_write(self->code.get(), filename, lnofile)) {
vec_free(lnofile); vec_free(lnofile);
return false; return false;
} }

19
ir.h
View file

@ -108,19 +108,25 @@ struct ir_phi_entry_t {
/* instruction */ /* instruction */
struct ir_instr { struct ir_instr {
void* operator new(std::size_t);
void operator delete(void*);
ir_instr(lex_ctx_t, ir_block *owner, int opcode);
~ir_instr();
int opcode; int opcode;
lex_ctx_t context; lex_ctx_t context;
ir_value *(_ops[3]); ir_value *(_ops[3]) = { nullptr, nullptr, nullptr };
ir_block *(bops[2]); ir_block *(bops[2]) = { nullptr, nullptr };
std::vector<ir_phi_entry_t> phi; std::vector<ir_phi_entry_t> phi;
std::vector<ir_value *> params; std::vector<ir_value *> params;
// For the temp-allocation // For the temp-allocation
size_t eid; size_t eid = 0;
// For IFs // For IFs
bool likely; bool likely = true;
ir_block *owner; ir_block *owner;
}; };
@ -262,8 +268,9 @@ struct ir_builder {
ht htglobals; ht htglobals;
ht htfields; ht htfields;
std::vector<std::unique_ptr<ir_value>> extparams; // extparams' ir_values reference the ones from extparam_protos
std::vector<std::unique_ptr<ir_value>> extparam_protos; std::vector<std::unique_ptr<ir_value>> extparam_protos;
std::vector<ir_value*> extparams;
// the highest func->allocated_locals // the highest func->allocated_locals
size_t max_locals = 0; size_t max_locals = 0;
@ -288,7 +295,7 @@ struct ir_builder {
ir_value *vinstr_temp[IR_MAX_VINSTR_TEMPS]; ir_value *vinstr_temp[IR_MAX_VINSTR_TEMPS];
/* code generator */ /* code generator */
code_t *code; std::unique_ptr<code_t> code;
}; };
ir_function* ir_builder_create_function(ir_builder*, const std::string& name, qc_type outtype); ir_function* ir_builder_create_function(ir_builder*, const std::string& name, qc_type outtype);

View file

@ -4088,7 +4088,7 @@ static bool parse_function_body(parser_t *parser, ast_value *var)
goto enderrfn; goto enderrfn;
} }
func->blocks.push_back(block); func->blocks.emplace_back(block);
parser->function = old; parser->function = old;
if (!parser_leaveblock(parser)) if (!parser_leaveblock(parser))
@ -4348,7 +4348,7 @@ static bool parser_create_array_accessor(parser_t *parser, ast_value *array, con
return false; return false;
} }
func->blocks.push_back(body); func->blocks.emplace_back(body);
*out = fval; *out = fval;
parser->accessors.push_back(fval); parser->accessors.push_back(fval);
@ -4405,7 +4405,7 @@ static bool parser_create_array_setter_impl(parser_t *parser, ast_value *array)
parseerror(parser, "failed to build accessor search tree"); parseerror(parser, "failed to build accessor search tree");
return false; return false;
} }
if (!ast_block_add_expr(array->setter->constval.vfunc->blocks[0], root)) { if (!ast_block_add_expr(array->setter->constval.vfunc->blocks[0].get(), root)) {
ast_delete(root); ast_delete(root);
return false; return false;
} }
@ -4457,7 +4457,7 @@ static bool parser_create_array_field_setter(parser_t *parser, ast_value *array,
} }
array->setter = fval; array->setter = fval;
return ast_block_add_expr(func->blocks[0], root); return ast_block_add_expr(func->blocks[0].get(), root);
cleanup: cleanup:
if (entity) ast_delete(entity); if (entity) ast_delete(entity);
if (index) ast_delete(index); if (index) ast_delete(index);
@ -4513,7 +4513,7 @@ static bool parser_create_array_getter_impl(parser_t *parser, ast_value *array)
parseerror(parser, "failed to build accessor search tree"); parseerror(parser, "failed to build accessor search tree");
return false; return false;
} }
if (!ast_block_add_expr(array->getter->constval.vfunc->blocks[0], root)) { if (!ast_block_add_expr(array->getter->constval.vfunc->blocks[0].get(), root)) {
ast_delete(root); ast_delete(root);
return false; return false;
} }
@ -6123,6 +6123,7 @@ static void parser_remove_ast(parser_t *parser)
void parser_cleanup(parser_t *parser) void parser_cleanup(parser_t *parser)
{ {
parser_remove_ast(parser); parser_remove_ast(parser);
parser->~parser_t();
mem_d(parser); mem_d(parser);
} }

View file

@ -76,7 +76,7 @@ static FILE **task_popen(const char *command, const char *mode) {
dup2(errhandle[1], 2); dup2(errhandle[1], 2);
execvp(argv[0], &argv[0]); execvp(argv[0], &argv[0]);
exit(EXIT_FAILURE); exit(95);
} else { } else {
/* fork failed */ /* fork failed */
goto task_popen_error_3; goto task_popen_error_3;
@ -98,11 +98,17 @@ static int task_pclose(FILE **handles) {
close(data->pipes[1]); /* stdout */ close(data->pipes[1]); /* stdout */
close(data->pipes[2]); /* stderr */ close(data->pipes[2]); /* stderr */
waitpid(data->pid, &status, 0); if (data->pid != waitpid(data->pid, &status, 0)) {
abort();
}
if (!WIFEXITED(status))
return -1;
if (WIFSIGNALED(status))
con_out("got signaled!\n");
mem_d(data); mem_d(data);
return status; return status ? 1 : 0;
} }
#define TASK_COMPILE 0 #define TASK_COMPILE 0
@ -997,6 +1003,10 @@ static size_t task_schedualize(size_t *pad) {
util_snprintf(space[1], sizeof(space[1]), "%d", (int)(i)); util_snprintf(space[1], sizeof(space[1]), "%d", (int)(i));
con_out("test #%u %*s", i, strlen(space[0]) - strlen(space[1]), ""); con_out("test #%u %*s", i, strlen(space[0]) - strlen(space[1]), "");
//con_out("[[%*s]]",
// (pad[0] + pad[1] - strlen(it.tmpl->description)) + (strlen(it.tmpl->rulesfile) - pad[1]),
// it.tmpl->rulesfile);
//fflush(stdout);
/* /*
* Generate a task from thin air if it requires execution in * Generate a task from thin air if it requires execution in
@ -1057,6 +1067,16 @@ static size_t task_schedualize(size_t *pad) {
} }
status = task_pclose(it.runhandles); status = task_pclose(it.runhandles);
if (status != 0 && status != 1) {
con_out("compiler failure (returned: %i): `%s` %*s\n",
status,
it.tmpl->description,
(pad[0] + pad[1] - strlen(it.tmpl->description)) + (strlen(it.tmpl->rulesfile) - pad[1]),
it.tmpl->rulesfile
);
failed++;
continue;
}
if ((!strcmp(it.tmpl->proceduretype, "-fail") && status == EXIT_SUCCESS) if ((!strcmp(it.tmpl->proceduretype, "-fail") && status == EXIT_SUCCESS)
|| ( strcmp(it.tmpl->proceduretype, "-fail") && status == EXIT_FAILURE)) { || ( strcmp(it.tmpl->proceduretype, "-fail") && status == EXIT_FAILURE)) {
con_out("failure: `%s` %*s %*s\n", con_out("failure: `%s` %*s %*s\n",