summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Worth <cworth@cworth.org>2010-06-23 18:11:51 -0700
committerCarl Worth <cworth@cworth.org>2010-06-23 18:59:35 -0700
commit1660a2954797e056caba319c5d6c70b0d4be22fe (patch)
tree172af2dd8effb58c89828b917cae850058312edd
parent8f52c9b5fcbc73ed12b23253caa44c28fd4452e2 (diff)
exec_node: Add new talloc-based new()
And fix all callers to use the tallbac-based new for exec_node construction. We make ready use of talloc_parent in order to get valid, (and appropriate) talloc owners for everything we construct without having to add new 'ctx' parameters up and down all the call trees. This closes the majority of the memory leaks in the glsl-orangebook-ch06-bump.frag test: total heap usage: 55,623 allocs, 42,672 frees (was 14,533 frees) Now 76.7% leak-free. Woo-hoo!
-rw-r--r--ast_function.cpp53
-rw-r--r--ast_to_hir.cpp181
-rw-r--r--glsl_types.cpp128
-rw-r--r--hir_field_selection.cpp5
-rw-r--r--ir.cpp25
-rw-r--r--ir_clone.cpp47
-rw-r--r--ir_constant_expression.cpp11
-rw-r--r--ir_copy_propagation.cpp3
-rw-r--r--ir_dead_code.cpp3
-rw-r--r--ir_dead_code_local.cpp3
-rw-r--r--ir_expression_flattening.cpp11
-rw-r--r--ir_function_inlining.cpp15
-rw-r--r--ir_reader.cpp50
-rw-r--r--ir_variable.cpp2
-rw-r--r--ir_vec_index_to_swizzle.cpp4
-rw-r--r--list.h25
-rw-r--r--s_expression.cpp16
-rw-r--r--s_expression.h4
18 files changed, 351 insertions, 235 deletions
diff --git a/ast_function.cpp b/ast_function.cpp
index ff2dfa5..866cbc4 100644
--- a/ast_function.cpp
+++ b/ast_function.cpp
@@ -54,6 +54,8 @@ process_call(exec_list *instructions, ir_function *f,
YYLTYPE *loc, exec_list *actual_parameters,
struct _mesa_glsl_parse_state *state)
{
+ void *ctx = talloc_parent(state);
+
const ir_function_signature *sig =
f->matching_signature(actual_parameters);
@@ -93,7 +95,7 @@ process_call(exec_list *instructions, ir_function *f,
/* FINISHME: The list of actual parameters needs to be modified to
* FINISHME: include any necessary conversions.
*/
- return new ir_call(sig, actual_parameters);
+ return new(ctx) ir_call(sig, actual_parameters);
} else {
/* FINISHME: Log a better error message here. G++ will show the types
* FINISHME: of the actual parameters and the set of candidate
@@ -132,6 +134,7 @@ match_function_by_name(exec_list *instructions, const char *name,
static ir_rvalue *
convert_component(ir_rvalue *src, const glsl_type *desired_type)
{
+ void *ctx = talloc_parent(src);
const unsigned a = desired_type->base_type;
const unsigned b = src->type->base_type;
ir_expression *result = NULL;
@@ -149,22 +152,22 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type)
case GLSL_TYPE_UINT:
case GLSL_TYPE_INT:
if (b == GLSL_TYPE_FLOAT)
- result = new ir_expression(ir_unop_f2i, desired_type, src, NULL);
+ result = new(ctx) ir_expression(ir_unop_f2i, desired_type, src, NULL);
else {
assert(b == GLSL_TYPE_BOOL);
- result = new ir_expression(ir_unop_b2i, desired_type, src, NULL);
+ result = new(ctx) ir_expression(ir_unop_b2i, desired_type, src, NULL);
}
break;
case GLSL_TYPE_FLOAT:
switch (b) {
case GLSL_TYPE_UINT:
- result = new ir_expression(ir_unop_u2f, desired_type, src, NULL);
+ result = new(ctx) ir_expression(ir_unop_u2f, desired_type, src, NULL);
break;
case GLSL_TYPE_INT:
- result = new ir_expression(ir_unop_i2f, desired_type, src, NULL);
+ result = new(ctx) ir_expression(ir_unop_i2f, desired_type, src, NULL);
break;
case GLSL_TYPE_BOOL:
- result = new ir_expression(ir_unop_b2f, desired_type, src, NULL);
+ result = new(ctx) ir_expression(ir_unop_b2f, desired_type, src, NULL);
break;
}
break;
@@ -172,12 +175,12 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type)
ir_constant *zero = NULL;
switch (b) {
- case GLSL_TYPE_UINT: zero = new ir_constant(unsigned(0)); break;
- case GLSL_TYPE_INT: zero = new ir_constant(int(0)); break;
- case GLSL_TYPE_FLOAT: zero = new ir_constant(0.0f); break;
+ case GLSL_TYPE_UINT: zero = new(ctx) ir_constant(unsigned(0)); break;
+ case GLSL_TYPE_INT: zero = new(ctx) ir_constant(int(0)); break;
+ case GLSL_TYPE_FLOAT: zero = new(ctx) ir_constant(0.0f); break;
}
- result = new ir_expression(ir_binop_nequal, desired_type, src, zero);
+ result = new(ctx) ir_expression(ir_binop_nequal, desired_type, src, zero);
}
}
@@ -194,6 +197,7 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type)
static ir_rvalue *
dereference_component(ir_rvalue *src, unsigned component)
{
+ void *ctx = talloc_parent(src);
assert(component < src->type->components());
/* If the source is a constant, just create a new constant instead of a
@@ -201,12 +205,12 @@ dereference_component(ir_rvalue *src, unsigned component)
*/
ir_constant *constant = src->as_constant();
if (constant)
- return new ir_constant(constant, component);
+ return new(ctx) ir_constant(constant, component);
if (src->type->is_scalar()) {
return src;
} else if (src->type->is_vector()) {
- return new ir_swizzle(src, component, 0, 0, 0, 1);
+ return new(ctx) ir_swizzle(src, component, 0, 0, 0, 1);
} else {
assert(src->type->is_matrix());
@@ -215,8 +219,8 @@ dereference_component(ir_rvalue *src, unsigned component)
*/
const int c = component / src->type->column_type()->vector_elements;
const int r = component % src->type->column_type()->vector_elements;
- ir_constant *const col_index = new ir_constant(c);
- ir_dereference *const col = new ir_dereference_array(src, col_index);
+ ir_constant *const col_index = new(ctx) ir_constant(c);
+ ir_dereference *const col = new(ctx) ir_dereference_array(src, col_index);
col->type = src->type->column_type();
@@ -306,6 +310,7 @@ constant_record_constructor(const glsl_type *constructor_type,
YYLTYPE *loc, exec_list *parameters,
struct _mesa_glsl_parse_state *state)
{
+ void *ctx = talloc_parent(state);
bool all_parameters_are_constant = true;
exec_node *node = parameters->head;
@@ -338,7 +343,7 @@ constant_record_constructor(const glsl_type *constructor_type,
if (!all_parameters_are_constant)
return NULL;
- return new ir_constant(constructor_type, parameters);
+ return new(ctx) ir_constant(constructor_type, parameters);
}
@@ -440,6 +445,7 @@ ir_rvalue *
ast_function_expression::hir(exec_list *instructions,
struct _mesa_glsl_parse_state *state)
{
+ void *ctx = talloc_parent(state);
/* There are three sorts of function calls.
*
* 1. contstructors - The first subexpression is an ast_type_specifier.
@@ -574,11 +580,13 @@ ast_function_expression::hir(exec_list *instructions,
* glsl-vs-constructor-call.shader_test.
*/
if (result->type->components() >= 1 && !result->as_constant()) {
- result_var = new ir_variable(result->type, "constructor_tmp");
+ result_var = new(ctx) ir_variable(result->type,
+ "constructor_tmp");
ir_dereference_variable *lhs;
- lhs = new ir_dereference_variable(result_var);
- instructions->push_tail(new ir_assignment(lhs, result, NULL));
+ lhs = new(ctx) ir_dereference_variable(result_var);
+ instructions->push_tail(new(ctx) ir_assignment(lhs,
+ result, NULL));
}
/* Process each of the components of the parameter. Dereference
@@ -592,7 +600,7 @@ ast_function_expression::hir(exec_list *instructions,
ir_rvalue *component;
if (result_var) {
- ir_dereference *d = new ir_dereference_variable(result_var);
+ ir_dereference *d = new(ctx) ir_dereference_variable(result_var);
component = dereference_component(d, i);
} else {
component = dereference_component(result, i);
@@ -674,7 +682,8 @@ ast_function_expression::hir(exec_list *instructions,
*/
if (all_parameters_are_constant) {
if (components_used >= type_components)
- return new ir_constant(sig->return_type, & actual_parameters);
+ return new(ctx) ir_constant(sig->return_type,
+ & actual_parameters);
assert(sig->return_type->is_vector()
|| sig->return_type->is_matrix());
@@ -695,9 +704,9 @@ ast_function_expression::hir(exec_list *instructions,
generate_constructor_vector(sig->return_type, initializer,
&data);
- return new ir_constant(sig->return_type, &data);
+ return new(ctx) ir_constant(sig->return_type, &data);
} else
- return new ir_call(sig, & actual_parameters);
+ return new(ctx) ir_call(sig, & actual_parameters);
} else {
/* FINISHME: Log a better error message here. G++ will show the
* FINSIHME: types of the actual parameters and the set of
diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp
index c70f0f9..eafc9e8 100644
--- a/ast_to_hir.cpp
+++ b/ast_to_hir.cpp
@@ -87,6 +87,7 @@ static bool
apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from,
struct _mesa_glsl_parse_state *state)
{
+ void *ctx = talloc_parent(state);
if (to->base_type == from->type->base_type)
return true;
@@ -111,13 +112,13 @@ apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from,
switch (from->type->base_type) {
case GLSL_TYPE_INT:
- from = new ir_expression(ir_unop_i2f, to, from, NULL);
+ from = new(ctx) ir_expression(ir_unop_i2f, to, from, NULL);
break;
case GLSL_TYPE_UINT:
- from = new ir_expression(ir_unop_u2f, to, from, NULL);
+ from = new(ctx) ir_expression(ir_unop_u2f, to, from, NULL);
break;
case GLSL_TYPE_BOOL:
- from = new ir_expression(ir_unop_b2f, to, from, NULL);
+ from = new(ctx) ir_expression(ir_unop_b2f, to, from, NULL);
break;
default:
assert(0);
@@ -467,6 +468,7 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
ir_rvalue *lhs, ir_rvalue *rhs,
YYLTYPE lhs_loc)
{
+ void *ctx = talloc_parent(state);
bool error_emitted = (lhs->type->is_error() || rhs->type->is_error());
if (!error_emitted) {
@@ -519,16 +521,16 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
* temporary and return a deref of that temporary. If the rvalue
* ends up not being used, the temp will get copy-propagated out.
*/
- ir_variable *var = new ir_variable(rhs->type, "assignment_tmp");
- instructions->push_tail(new ir_assignment(new ir_dereference_variable(var),
- rhs,
- NULL));
+ ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp");
+ instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var),
+ rhs,
+ NULL));
- instructions->push_tail(new ir_assignment(lhs,
- new ir_dereference_variable(var),
- NULL));
+ instructions->push_tail(new(ctx) ir_assignment(lhs,
+ new(ctx) ir_dereference_variable(var),
+ NULL));
- return new ir_dereference_variable(var);
+ return new(ctx) ir_dereference_variable(var);
}
@@ -539,12 +541,13 @@ static ir_variable *
generate_temporary(const glsl_type *type, exec_list *instructions,
struct _mesa_glsl_parse_state *state)
{
+ void *ctx = talloc_parent(state);
char *name = (char *) malloc(sizeof(char) * 13);
snprintf(name, 13, "tmp_%08X", state->temp_index);
state->temp_index++;
- ir_variable *const var = new ir_variable(type, name);
+ ir_variable *const var = new(ctx) ir_variable(type, name);
instructions->push_tail(var);
return var;
@@ -554,21 +557,22 @@ generate_temporary(const glsl_type *type, exec_list *instructions,
static ir_rvalue *
get_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue)
{
+ void *ctx = talloc_parent(lvalue);
ir_variable *var;
/* FINISHME: Give unique names to the temporaries. */
- var = new ir_variable(lvalue->type, "_post_incdec_tmp");
+ var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp");
var->mode = ir_var_auto;
- instructions->push_tail(new ir_assignment(new ir_dereference_variable(var),
- lvalue, NULL));
+ instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var),
+ lvalue, NULL));
/* Once we've created this temporary, mark it read only so it's no
* longer considered an lvalue.
*/
var->read_only = true;
- return new ir_dereference_variable(var);
+ return new(ctx) ir_dereference_variable(var);
}
@@ -587,6 +591,7 @@ ir_rvalue *
ast_expression::hir(exec_list *instructions,
struct _mesa_glsl_parse_state *state)
{
+ void *ctx = talloc_parent(state);
static const int operations[AST_NUM_OPERATORS] = {
-1, /* ast_assign doesn't convert to ir_expression. */
-1, /* ast_plus doesn't convert to ir_expression. */
@@ -679,8 +684,8 @@ ast_expression::hir(exec_list *instructions,
error_emitted = type->is_error();
- result = new ir_expression(operations[this->oper], type,
- op[0], NULL);
+ result = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], NULL);
break;
case ast_add:
@@ -695,8 +700,8 @@ ast_expression::hir(exec_list *instructions,
state, & loc);
error_emitted = type->is_error();
- result = new ir_expression(operations[this->oper], type,
- op[0], op[1]);
+ result = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
break;
case ast_mod:
@@ -707,8 +712,8 @@ ast_expression::hir(exec_list *instructions,
assert(operations[this->oper] == ir_binop_mod);
- result = new ir_expression(operations[this->oper], type,
- op[0], op[1]);
+ result = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
error_emitted = type->is_error();
break;
@@ -734,8 +739,8 @@ ast_expression::hir(exec_list *instructions,
|| ((type->base_type == GLSL_TYPE_BOOL)
&& type->is_scalar()));
- result = new ir_expression(operations[this->oper], type,
- op[0], op[1]);
+ result = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
error_emitted = type->is_error();
break;
@@ -766,8 +771,8 @@ ast_expression::hir(exec_list *instructions,
error_emitted = true;
}
- result = new ir_expression(operations[this->oper], glsl_type::bool_type,
- op[0], op[1]);
+ result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
+ op[0], op[1]);
type = glsl_type::bool_type;
assert(result->type == glsl_type::bool_type);
@@ -811,7 +816,7 @@ ast_expression::hir(exec_list *instructions,
}
type = glsl_type::bool_type;
} else {
- ir_if *const stmt = new ir_if(op[0]);
+ ir_if *const stmt = new(ctx) ir_if(op[0]);
instructions->push_tail(stmt);
op[1] = this->subexpressions[1]->hir(&stmt->then_instructions, state);
@@ -828,17 +833,17 @@ ast_expression::hir(exec_list *instructions,
ir_variable *const tmp = generate_temporary(glsl_type::bool_type,
instructions, state);
- ir_dereference *const then_deref = new ir_dereference_variable(tmp);
+ ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp);
ir_assignment *const then_assign =
- new ir_assignment(then_deref, op[1], NULL);
+ new(ctx) ir_assignment(then_deref, op[1], NULL);
stmt->then_instructions.push_tail(then_assign);
- ir_dereference *const else_deref = new ir_dereference_variable(tmp);
+ ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp);
ir_assignment *const else_assign =
- new ir_assignment(else_deref, new ir_constant(false), NULL);
+ new(ctx) ir_assignment(else_deref, new(ctx) ir_constant(false), NULL);
stmt->else_instructions.push_tail(else_assign);
- result = new ir_dereference_variable(tmp);
+ result = new(ctx) ir_dereference_variable(tmp);
type = tmp->type;
}
break;
@@ -874,7 +879,7 @@ ast_expression::hir(exec_list *instructions,
}
type = glsl_type::bool_type;
} else {
- ir_if *const stmt = new ir_if(op[0]);
+ ir_if *const stmt = new(ctx) ir_if(op[0]);
instructions->push_tail(stmt);
ir_variable *const tmp = generate_temporary(glsl_type::bool_type,
@@ -890,17 +895,17 @@ ast_expression::hir(exec_list *instructions,
error_emitted = true;
}
- ir_dereference *const then_deref = new ir_dereference_variable(tmp);
+ ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp);
ir_assignment *const then_assign =
- new ir_assignment(then_deref, new ir_constant(true), NULL);
+ new(ctx) ir_assignment(then_deref, new(ctx) ir_constant(true), NULL);
stmt->then_instructions.push_tail(then_assign);
- ir_dereference *const else_deref = new ir_dereference_variable(tmp);
+ ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp);
ir_assignment *const else_assign =
- new ir_assignment(else_deref, op[1], NULL);
+ new(ctx) ir_assignment(else_deref, op[1], NULL);
stmt->else_instructions.push_tail(else_assign);
- result = new ir_dereference_variable(tmp);
+ result = new(ctx) ir_dereference_variable(tmp);
type = tmp->type;
}
break;
@@ -911,8 +916,8 @@ ast_expression::hir(exec_list *instructions,
op[1] = this->subexpressions[1]->hir(instructions, state);
- result = new ir_expression(operations[this->oper], glsl_type::bool_type,
- op[0], op[1]);
+ result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
+ op[0], op[1]);
type = glsl_type::bool_type;
break;
@@ -927,8 +932,8 @@ ast_expression::hir(exec_list *instructions,
error_emitted = true;
}
- result = new ir_expression(operations[this->oper], glsl_type::bool_type,
- op[0], NULL);
+ result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
+ op[0], NULL);
type = glsl_type::bool_type;
break;
@@ -943,8 +948,8 @@ ast_expression::hir(exec_list *instructions,
(this->oper == ast_mul_assign),
state, & loc);
- ir_rvalue *temp_rhs = new ir_expression(operations[this->oper], type,
- op[0], op[1]);
+ ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
result = do_assignment(instructions, state,
(ir_rvalue *)op[0]->clone(NULL), temp_rhs,
@@ -969,8 +974,8 @@ ast_expression::hir(exec_list *instructions,
assert(operations[this->oper] == ir_binop_mod);
struct ir_rvalue *temp_rhs;
- temp_rhs = new ir_expression(operations[this->oper], type,
- op[0], op[1]);
+ temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
result = do_assignment(instructions, state,
(ir_rvalue *)op[0]->clone(NULL), temp_rhs,
@@ -1056,22 +1061,24 @@ ast_expression::hir(exec_list *instructions,
ir_variable *const tmp = generate_temporary(type,
instructions, state);
- ir_if *const stmt = new ir_if(op[0]);
+ ir_if *const stmt = new(ctx) ir_if(op[0]);
instructions->push_tail(stmt);
then_instructions.move_nodes_to(& stmt->then_instructions);
- ir_dereference *const then_deref = new ir_dereference_variable(tmp);
+ ir_dereference *const then_deref =
+ new(ctx) ir_dereference_variable(tmp);
ir_assignment *const then_assign =
- new ir_assignment(then_deref, op[1], NULL);
+ new(ctx) ir_assignment(then_deref, op[1], NULL);
stmt->then_instructions.push_tail(then_assign);
else_instructions.move_nodes_to(& stmt->else_instructions);
- ir_dereference *const else_deref = new ir_dereference_variable(tmp);
+ ir_dereference *const else_deref =
+ new(ctx) ir_dereference_variable(tmp);
ir_assignment *const else_assign =
- new ir_assignment(else_deref, op[2], NULL);
+ new(ctx) ir_assignment(else_deref, op[2], NULL);
stmt->else_instructions.push_tail(else_assign);
- result = new ir_dereference_variable(tmp);
+ result = new(ctx) ir_dereference_variable(tmp);
}
break;
}
@@ -1080,15 +1087,15 @@ ast_expression::hir(exec_list *instructions,
case ast_pre_dec: {
op[0] = this->subexpressions[0]->hir(instructions, state);
if (op[0]->type->base_type == GLSL_TYPE_FLOAT)
- op[1] = new ir_constant(1.0f);
+ op[1] = new(ctx) ir_constant(1.0f);
else
- op[1] = new ir_constant(1);
+ op[1] = new(ctx) ir_constant(1);
type = arithmetic_result_type(op[0], op[1], false, state, & loc);
struct ir_rvalue *temp_rhs;
- temp_rhs = new ir_expression(operations[this->oper], type,
- op[0], op[1]);
+ temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
result = do_assignment(instructions, state,
(ir_rvalue *)op[0]->clone(NULL), temp_rhs,
@@ -1102,17 +1109,17 @@ ast_expression::hir(exec_list *instructions,
case ast_post_dec: {
op[0] = this->subexpressions[0]->hir(instructions, state);
if (op[0]->type->base_type == GLSL_TYPE_FLOAT)
- op[1] = new ir_constant(1.0f);
+ op[1] = new(ctx) ir_constant(1.0f);
else
- op[1] = new ir_constant(1);
+ op[1] = new(ctx) ir_constant(1);
error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
type = arithmetic_result_type(op[0], op[1], false, state, & loc);
struct ir_rvalue *temp_rhs;
- temp_rhs = new ir_expression(operations[this->oper], type,
- op[0], op[1]);
+ temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
/* Get a temporary of a copy of the lvalue before it's modified.
* This may get thrown away later.
@@ -1143,7 +1150,7 @@ ast_expression::hir(exec_list *instructions,
ir_rvalue *const array = op[0];
- result = new ir_dereference_array(op[0], op[1]);
+ result = new(ctx) ir_dereference_array(op[0], op[1]);
/* Do not use op[0] after this point. Use array.
*/
@@ -1259,7 +1266,7 @@ ast_expression::hir(exec_list *instructions,
ir_variable *var =
state->symbols->get_variable(this->primary_expression.identifier);
- result = new ir_dereference_variable(var);
+ result = new(ctx) ir_dereference_variable(var);
if (var != NULL) {
type = result->type;
@@ -1274,22 +1281,22 @@ ast_expression::hir(exec_list *instructions,
case ast_int_constant:
type = glsl_type::int_type;
- result = new ir_constant(this->primary_expression.int_constant);
+ result = new(ctx) ir_constant(this->primary_expression.int_constant);
break;
case ast_uint_constant:
type = glsl_type::uint_type;
- result = new ir_constant(this->primary_expression.uint_constant);
+ result = new(ctx) ir_constant(this->primary_expression.uint_constant);
break;
case ast_float_constant:
type = glsl_type::float_type;
- result = new ir_constant(this->primary_expression.float_constant);
+ result = new(ctx) ir_constant(this->primary_expression.float_constant);
break;
case ast_bool_constant:
type = glsl_type::bool_type;
- result = new ir_constant(bool(this->primary_expression.bool_constant));
+ result = new(ctx) ir_constant(bool(this->primary_expression.bool_constant));
break;
case ast_sequence: {
@@ -1528,6 +1535,7 @@ ir_rvalue *
ast_declarator_list::hir(exec_list *instructions,
struct _mesa_glsl_parse_state *state)
{
+ void *ctx = talloc_parent(state);
const struct glsl_type *decl_type;
const char *type_name = NULL;
ir_rvalue *result = NULL;
@@ -1588,7 +1596,7 @@ ast_declarator_list::hir(exec_list *instructions,
var_type = decl_type;
}
- var = new ir_variable(var_type, decl->identifier);
+ var = new(ctx) ir_variable(var_type, decl->identifier);
/* From page 22 (page 28 of the PDF) of the GLSL 1.10 specification;
*
@@ -1788,7 +1796,7 @@ ast_declarator_list::hir(exec_list *instructions,
? "attribute" : "varying");
}
- ir_dereference *const lhs = new ir_dereference_variable(var);
+ ir_dereference *const lhs = new(ctx) ir_dereference_variable(var);
ir_rvalue *rhs = decl->initializer->hir(instructions, state);
/* Calculate the constant value if this is a const or uniform
@@ -1866,6 +1874,7 @@ ir_rvalue *
ast_parameter_declarator::hir(exec_list *instructions,
struct _mesa_glsl_parse_state *state)
{
+ void *ctx = talloc_parent(state);
const struct glsl_type *type;
const char *name = NULL;
YYLTYPE loc = this->get_location();
@@ -1913,7 +1922,7 @@ ast_parameter_declarator::hir(exec_list *instructions,
}
is_void = false;
- ir_variable *var = new ir_variable(type, this->identifier);
+ ir_variable *var = new(ctx) ir_variable(type, this->identifier);
/* FINISHME: Handle array declarations. Note that this requires
* FINISHME: complete handling of constant expressions.
@@ -1966,6 +1975,7 @@ ir_rvalue *
ast_function::hir(exec_list *instructions,
struct _mesa_glsl_parse_state *state)
{
+ void *ctx = talloc_parent(state);
ir_function *f = NULL;
ir_function_signature *sig = NULL;
exec_list hir_parameters;
@@ -2025,7 +2035,7 @@ ast_function::hir(exec_list *instructions,
"non-function", name);
sig = NULL;
} else {
- f = new ir_function(name);
+ f = new(ctx) ir_function(name);
state->symbols->add_function(f->name, f);
/* Emit the new function header */
@@ -2050,7 +2060,7 @@ ast_function::hir(exec_list *instructions,
/* Finish storing the information about this new function in its signature.
*/
if (sig == NULL) {
- sig = new ir_function_signature(return_type);
+ sig = new(ctx) ir_function_signature(return_type);
f->add_signature(sig);
}
@@ -2115,6 +2125,7 @@ ir_rvalue *
ast_jump_statement::hir(exec_list *instructions,
struct _mesa_glsl_parse_state *state)
{
+ void *ctx = talloc_parent(state);
switch (mode) {
case ast_return: {
@@ -2140,7 +2151,7 @@ ast_jump_statement::hir(exec_list *instructions,
* FINISHME: type of the enclosing function.
*/
- inst = new ir_return(ret);
+ inst = new(ctx) ir_return(ret);
} else {
if (state->current_function->return_type->base_type !=
GLSL_TYPE_VOID) {
@@ -2151,7 +2162,7 @@ ast_jump_statement::hir(exec_list *instructions,
"non-void",
state->current_function->function_name());
}
- inst = new ir_return;
+ inst = new(ctx) ir_return;
}
instructions->push_tail(inst);
@@ -2188,9 +2199,9 @@ ast_jump_statement::hir(exec_list *instructions,
if (loop != NULL) {
ir_loop_jump *const jump =
- new ir_loop_jump((mode == ast_break)
- ? ir_loop_jump::jump_break
- : ir_loop_jump::jump_continue);
+ new(ctx) ir_loop_jump((mode == ast_break)
+ ? ir_loop_jump::jump_break
+ : ir_loop_jump::jump_continue);
instructions->push_tail(jump);
}
}
@@ -2208,6 +2219,8 @@ ir_rvalue *
ast_selection_statement::hir(exec_list *instructions,
struct _mesa_glsl_parse_state *state)
{
+ void *ctx = talloc_parent(state);
+
ir_rvalue *const condition = this->condition->hir(instructions, state);
/* From page 66 (page 72 of the PDF) of the GLSL 1.50 spec:
@@ -2226,7 +2239,7 @@ ast_selection_statement::hir(exec_list *instructions,
"boolean");
}
- ir_if *const stmt = new ir_if(condition);
+ ir_if *const stmt = new(ctx) ir_if(condition);
if (then_statement != NULL)
then_statement->hir(& stmt->then_instructions, state);
@@ -2246,6 +2259,8 @@ void
ast_iteration_statement::condition_to_hir(ir_loop *stmt,
struct _mesa_glsl_parse_state *state)
{
+ void *ctx = talloc_parent(state);
+
if (condition != NULL) {
ir_rvalue *const cond =
condition->hir(& stmt->body_instructions, state);
@@ -2261,13 +2276,13 @@ ast_iteration_statement::condition_to_hir(ir_loop *stmt,
* like 'if (!condition) break;' as the loop termination condition.
*/
ir_rvalue *const not_cond =
- new ir_expression(ir_unop_logic_not, glsl_type::bool_type, cond,
- NULL);
+ new(ctx) ir_expression(ir_unop_logic_not, glsl_type::bool_type, cond,
+ NULL);
- ir_if *const if_stmt = new ir_if(not_cond);
+ ir_if *const if_stmt = new(ctx) ir_if(not_cond);
ir_jump *const break_stmt =
- new ir_loop_jump(ir_loop_jump::jump_break);
+ new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
if_stmt->then_instructions.push_tail(break_stmt);
stmt->body_instructions.push_tail(if_stmt);
@@ -2280,6 +2295,8 @@ ir_rvalue *
ast_iteration_statement::hir(exec_list *instructions,
struct _mesa_glsl_parse_state *state)
{
+ void *ctx = talloc_parent(state);
+
/* For-loops and while-loops start a new scope, but do-while loops do not.
*/
if (mode != ast_do_while)
@@ -2288,7 +2305,7 @@ ast_iteration_statement::hir(exec_list *instructions,
if (init_statement != NULL)
init_statement->hir(instructions, state);
- ir_loop *const stmt = new ir_loop();
+ ir_loop *const stmt = new(ctx) ir_loop();
instructions->push_tail(stmt);
/* Track the current loop and / or switch-statement nesting.
diff --git a/glsl_types.cpp b/glsl_types.cpp
index ca19de6..fcc7745 100644
--- a/glsl_types.cpp
+++ b/glsl_types.cpp
@@ -150,14 +150,16 @@ const glsl_type *glsl_type::get_base_type() const
ir_function *
glsl_type::generate_constructor(glsl_symbol_table *symtab) const
{
+ void *ctx = symtab;
+
/* Generate the function name and add it to the symbol table.
*/
- ir_function *const f = new ir_function(name);
+ ir_function *const f = new(ctx) ir_function(name);
bool added = symtab->add_function(name, f);
assert(added);
- ir_function_signature *const sig = new ir_function_signature(this);
+ ir_function_signature *const sig = new(ctx) ir_function_signature(this);
f->add_signature(sig);
ir_variable **declarations =
@@ -168,8 +170,8 @@ glsl_type::generate_constructor(glsl_symbol_table *symtab) const
snprintf(param_name, 10, "p%08X", i);
ir_variable *var = (this->base_type == GLSL_TYPE_ARRAY)
- ? new ir_variable(fields.array, param_name)
- : new ir_variable(fields.structure[i].type, param_name);
+ ? new(ctx) ir_variable(fields.array, param_name)
+ : new(ctx) ir_variable(fields.structure[i].type, param_name);
var->mode = ir_var_in;
declarations[i] = var;
@@ -181,24 +183,26 @@ glsl_type::generate_constructor(glsl_symbol_table *symtab) const
* the same type as the constructor. After initializing __retval,
* __retval is returned.
*/
- ir_variable *retval = new ir_variable(this, "__retval");
+ ir_variable *retval = new(ctx) ir_variable(this, "__retval");
sig->body.push_tail(retval);
for (unsigned i = 0; i < length; i++) {
ir_dereference *const lhs = (this->base_type == GLSL_TYPE_ARRAY)
- ? (ir_dereference *) new ir_dereference_array(retval, new ir_constant(i))
- : (ir_dereference *) new ir_dereference_record(retval, fields.structure[i].name);
+ ? (ir_dereference *) new(ctx) ir_dereference_array(retval,
+ new(ctx) ir_constant(i))
+ : (ir_dereference *) new(ctx) ir_dereference_record(retval,
+ fields.structure[i].name);
- ir_dereference *const rhs = new ir_dereference_variable(declarations[i]);
- ir_instruction *const assign = new ir_assignment(lhs, rhs, NULL);
+ ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[i]);
+ ir_instruction *const assign = new(ctx) ir_assignment(lhs, rhs, NULL);
sig->body.push_tail(assign);
}
free(declarations);
- ir_dereference *const retref = new ir_dereference_variable(retval);
- ir_instruction *const inst = new ir_return(retref);
+ ir_dereference *const retref = new(ctx) ir_dereference_variable(retval);
+ ir_instruction *const inst = new(ctx) ir_return(retref);
sig->body.push_tail(inst);
return f;
@@ -223,6 +227,8 @@ static ir_function_signature *
generate_constructor_intro(const glsl_type *type, unsigned parameter_count,
ir_variable **declarations)
{
+ /* NULL is wrong here and leaks. */
+ void *ctx = NULL;
/* Names of parameters used in vector and matrix constructors
*/
static const char *const names[] = {
@@ -234,10 +240,10 @@ generate_constructor_intro(const glsl_type *type, unsigned parameter_count,
const glsl_type *const parameter_type = type->get_base_type();
- ir_function_signature *const signature = new ir_function_signature(type);
+ ir_function_signature *const signature = new(ctx) ir_function_signature(type);
for (unsigned i = 0; i < parameter_count; i++) {
- ir_variable *var = new ir_variable(parameter_type, names[i]);
+ ir_variable *var = new(ctx) ir_variable(parameter_type, names[i]);
var->mode = ir_var_in;
signature->parameters.push_tail(var);
@@ -245,7 +251,7 @@ generate_constructor_intro(const glsl_type *type, unsigned parameter_count,
declarations[i] = var;
}
- ir_variable *retval = new ir_variable(type, "__retval");
+ ir_variable *retval = new(ctx) ir_variable(type, "__retval");
signature->body.push_tail(retval);
declarations[16] = retval;
@@ -260,26 +266,28 @@ static void
generate_vec_body_from_scalar(exec_list *instructions,
ir_variable **declarations)
{
+ /* NULL is wrong here and leaks. */
+ void *ctx = NULL;
ir_instruction *inst;
/* Generate a single assignment of the parameter to __retval.x and return
* __retval.xxxx for however many vector components there are.
*/
ir_dereference *const lhs_ref =
- new ir_dereference_variable(declarations[16]);
- ir_dereference *const rhs = new ir_dereference_variable(declarations[0]);
+ new(ctx) ir_dereference_variable(declarations[16]);
+ ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[0]);
- ir_swizzle *lhs = new ir_swizzle(lhs_ref, 0, 0, 0, 0, 1);
+ ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, 0, 0, 0, 0, 1);
- inst = new ir_assignment(lhs, rhs, NULL);
+ inst = new(ctx) ir_assignment(lhs, rhs, NULL);
instructions->push_tail(inst);
- ir_dereference *const retref = new ir_dereference_variable(declarations[16]);
+ ir_dereference *const retref = new(ctx) ir_dereference_variable(declarations[16]);
- ir_swizzle *retval = new ir_swizzle(retref, 0, 0, 0, 0,
- declarations[16]->type->vector_elements);
+ ir_swizzle *retval = new(ctx) ir_swizzle(retref, 0, 0, 0, 0,
+ declarations[16]->type->vector_elements);
- inst = new ir_return(retval);
+ inst = new(ctx) ir_return(retval);
instructions->push_tail(inst);
}
@@ -291,27 +299,28 @@ static void
generate_vec_body_from_N_scalars(exec_list *instructions,
ir_variable **declarations)
{
+ /* NULL is wrong here and leaks. */
+ void *ctx = NULL;
ir_instruction *inst;
const glsl_type *const vec_type = declarations[16]->type;
-
/* Generate an assignment of each parameter to a single component of
* __retval.x and return __retval.
*/
for (unsigned i = 0; i < vec_type->vector_elements; i++) {
ir_dereference *const lhs_ref =
- new ir_dereference_variable(declarations[16]);
- ir_dereference *const rhs = new ir_dereference_variable(declarations[i]);
+ new(ctx) ir_dereference_variable(declarations[16]);
+ ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[i]);
- ir_swizzle *lhs = new ir_swizzle(lhs_ref, i, 0, 0, 0, 1);
+ ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, i, 0, 0, 0, 1);
- inst = new ir_assignment(lhs, rhs, NULL);
+ inst = new(ctx) ir_assignment(lhs, rhs, NULL);
instructions->push_tail(inst);
}
- ir_dereference *retval = new ir_dereference_variable(declarations[16]);
+ ir_dereference *retval = new(ctx) ir_dereference_variable(declarations[16]);
- inst = new ir_return(retval);
+ inst = new(ctx) ir_return(retval);
instructions->push_tail(inst);
}
@@ -323,6 +332,8 @@ static void
generate_mat_body_from_scalar(exec_list *instructions,
ir_variable **declarations)
{
+ /* NULL is wrong here and leaks. */
+ void *ctx = NULL;
ir_instruction *inst;
/* Generate an assignment of the parameter to the X component of a
@@ -347,49 +358,50 @@ generate_mat_body_from_scalar(exec_list *instructions,
*/
const glsl_type *const column_type = declarations[16]->type->column_type();
const glsl_type *const row_type = declarations[16]->type->row_type();
- ir_variable *const column = new ir_variable(column_type, "v");
+
+ ir_variable *const column = new(ctx) ir_variable(column_type, "v");
instructions->push_tail(column);
- ir_dereference *const lhs_ref = new ir_dereference_variable(column);
- ir_dereference *const rhs = new ir_dereference_variable(declarations[0]);
+ ir_dereference *const lhs_ref = new(ctx) ir_dereference_variable(column);
+ ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[0]);
- ir_swizzle *lhs = new ir_swizzle(lhs_ref, 0, 0, 0, 0, 1);
+ ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, 0, 0, 0, 0, 1);
- inst = new ir_assignment(lhs, rhs, NULL);
+ inst = new(ctx) ir_assignment(lhs, rhs, NULL);
instructions->push_tail(inst);
for (unsigned i = 1; i < column_type->vector_elements; i++) {
- ir_dereference *const lhs_ref = new ir_dereference_variable(column);
- ir_constant *const zero = new ir_constant(0.0f);
+ ir_dereference *const lhs_ref = new(ctx) ir_dereference_variable(column);
+ ir_constant *const zero = new(ctx) ir_constant(0.0f);
- ir_swizzle *lhs = new ir_swizzle(lhs_ref, i, 0, 0, 0, 1);
+ ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, i, 0, 0, 0, 1);
- inst = new ir_assignment(lhs, zero, NULL);
+ inst = new(ctx) ir_assignment(lhs, zero, NULL);
instructions->push_tail(inst);
}
for (unsigned i = 0; i < row_type->vector_elements; i++) {
static const unsigned swiz[] = { 1, 1, 1, 0, 1, 1, 1 };
- ir_dereference *const rhs_ref = new ir_dereference_variable(column);
+ ir_dereference *const rhs_ref = new(ctx) ir_dereference_variable(column);
/* This will be .xyyy when i=0, .yxyy when i=1, etc.
*/
- ir_swizzle *rhs = new ir_swizzle(rhs_ref, swiz[3 - i], swiz[4 - i],
- swiz[5 - i], swiz[6 - i],
- column_type->vector_elements);
+ ir_swizzle *rhs = new(ctx) ir_swizzle(rhs_ref, swiz[3 - i], swiz[4 - i],
+ swiz[5 - i], swiz[6 - i],
+ column_type->vector_elements);
- ir_constant *const idx = new ir_constant(int(i));
+ ir_constant *const idx = new(ctx) ir_constant(int(i));
ir_dereference *const lhs =
- new ir_dereference_array(declarations[16], idx);
+ new(ctx) ir_dereference_array(declarations[16], idx);
- inst = new ir_assignment(lhs, rhs, NULL);
+ inst = new(ctx) ir_assignment(lhs, rhs, NULL);
instructions->push_tail(inst);
}
- ir_dereference *const retval = new ir_dereference_variable(declarations[16]);
- inst = new ir_return(retval);
+ ir_dereference *const retval = new(ctx) ir_dereference_variable(declarations[16]);
+ inst = new(ctx) ir_return(retval);
instructions->push_tail(inst);
}
@@ -401,35 +413,36 @@ static void
generate_mat_body_from_N_scalars(exec_list *instructions,
ir_variable **declarations)
{
+ /* NULL is wrong here and leaks. */
+ void *ctx = NULL;
ir_instruction *inst;
const glsl_type *const row_type = declarations[16]->type->row_type();
const glsl_type *const column_type = declarations[16]->type->column_type();
-
/* Generate an assignment of each parameter to a single component of
* of a particular column of __retval and return __retval.
*/
for (unsigned i = 0; i < column_type->vector_elements; i++) {
for (unsigned j = 0; j < row_type->vector_elements; j++) {
- ir_constant *row_index = new ir_constant(int(i));
+ ir_constant *row_index = new(ctx) ir_constant(int(i));
ir_dereference *const row_access =
- new ir_dereference_array(declarations[16], row_index);
+ new(ctx) ir_dereference_array(declarations[16], row_index);
- ir_swizzle *component_access = new ir_swizzle(row_access,
- j, 0, 0, 0, 1);
+ ir_swizzle *component_access = new(ctx) ir_swizzle(row_access,
+ j, 0, 0, 0, 1);
const unsigned param = (i * row_type->vector_elements) + j;
ir_dereference *const rhs =
- new ir_dereference_variable(declarations[param]);
+ new(ctx) ir_dereference_variable(declarations[param]);
- inst = new ir_assignment(component_access, rhs, NULL);
+ inst = new(ctx) ir_assignment(component_access, rhs, NULL);
instructions->push_tail(inst);
}
}
- ir_dereference *retval = new ir_dereference_variable(declarations[16]);
+ ir_dereference *retval = new(ctx) ir_dereference_variable(declarations[16]);
- inst = new ir_return(retval);
+ inst = new(ctx) ir_return(retval);
instructions->push_tail(inst);
}
@@ -444,6 +457,7 @@ static void
generate_constructor(glsl_symbol_table *symtab, const struct glsl_type *types,
unsigned num_types, exec_list *instructions)
{
+ void *ctx = symtab;
ir_variable *declarations[17];
for (unsigned i = 0; i < num_types; i++) {
@@ -459,7 +473,7 @@ generate_constructor(glsl_symbol_table *symtab, const struct glsl_type *types,
/* Generate the function block, add it to the symbol table, and emit it.
*/
- ir_function *const f = new ir_function(types[i].name);
+ ir_function *const f = new(ctx) ir_function(types[i].name);
bool added = symtab->add_function(types[i].name, f);
assert(added);
diff --git a/hir_field_selection.cpp b/hir_field_selection.cpp
index e60ea30..6da1492 100644
--- a/hir_field_selection.cpp
+++ b/hir_field_selection.cpp
@@ -33,6 +33,7 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr,
exec_list *instructions,
struct _mesa_glsl_parse_state *state)
{
+ void *ctx = talloc_parent(state);
ir_rvalue *result = NULL;
ir_rvalue *op;
@@ -62,8 +63,8 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr,
expr->primary_expression.identifier);
}
} else if (op->type->base_type == GLSL_TYPE_STRUCT) {
- result = new ir_dereference_record(op,
- expr->primary_expression.identifier);
+ result = new(ctx) ir_dereference_record(op,
+ expr->primary_expression.identifier);
if (result->type->is_error()) {
_mesa_glsl_error(& loc, state, "Cannot access field `%s' of "
diff --git a/ir.cpp b/ir.cpp
index 98b085e..26cd475 100644
--- a/ir.cpp
+++ b/ir.cpp
@@ -300,15 +300,17 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
ir_instruction *
ir_constant::clone(struct hash_table *ht) const
{
+ void *ctx = talloc_parent(this);
+
switch (this->type->base_type) {
case GLSL_TYPE_UINT:
case GLSL_TYPE_INT:
case GLSL_TYPE_FLOAT:
case GLSL_TYPE_BOOL:
- return new ir_constant(this->type, &this->value);
+ return new(ctx) ir_constant(this->type, &this->value);
case GLSL_TYPE_STRUCT: {
- ir_constant *c = new ir_constant;
+ ir_constant *c = new(ctx)ir_constant;
c->type = this->type;
for (exec_node *node = this->components.head
@@ -497,8 +499,10 @@ ir_dereference_array::ir_dereference_array(ir_rvalue *value,
ir_dereference_array::ir_dereference_array(ir_variable *var,
ir_rvalue *array_index)
{
+ void *ctx = talloc_parent(var);
+
this->array_index = array_index;
- this->set_array(new ir_dereference_variable(var));
+ this->set_array(new(ctx) ir_dereference_variable(var));
}
@@ -535,7 +539,9 @@ ir_dereference_record::ir_dereference_record(ir_rvalue *value,
ir_dereference_record::ir_dereference_record(ir_variable *var,
const char *field)
{
- this->record = new ir_dereference_variable(var);
+ void *ctx = talloc_parent(var);
+
+ this->record = new(ctx) ir_dereference_variable(var);
this->field = field;
this->type = (this->record != NULL)
? this->record->type->field_type(field) : glsl_type::error_type;
@@ -646,6 +652,8 @@ ir_swizzle::ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask)
ir_swizzle *
ir_swizzle::create(ir_rvalue *val, const char *str, unsigned vector_length)
{
+ void *ctx = talloc_parent(val);
+
/* For each possible swizzle character, this table encodes the value in
* \c idx_map that represents the 0th element of the vector. For invalid
* swizzle characters (e.g., 'k'), a special value is used that will allow
@@ -710,8 +718,8 @@ ir_swizzle::create(ir_rvalue *val, const char *str, unsigned vector_length)
if (str[i] != '\0')
return NULL;
- return new ir_swizzle(val, swiz_idx[0], swiz_idx[1], swiz_idx[2],
- swiz_idx[3], i);
+ return new(ctx) ir_swizzle(val, swiz_idx[0], swiz_idx[1], swiz_idx[2],
+ swiz_idx[3], i);
}
#undef X
@@ -811,7 +819,6 @@ ir_function_signature::replace_parameters(exec_list *new_params)
assert(((ir_instruction *) iter.get())->as_variable() != NULL);
iter.remove();
- delete (ir_instruction*) iter.get();
}
new_params->move_nodes_to(&parameters);
@@ -828,7 +835,9 @@ ir_function::ir_function(const char *name)
ir_call *
ir_call::get_error_instruction()
{
- ir_call *call = new ir_call;
+ /* NULL is wrong and leaks */
+ void *ctx = NULL;
+ ir_call *call = new(ctx) ir_call;
call->type = glsl_type::error_type;
return call;
diff --git a/ir_clone.cpp b/ir_clone.cpp
index c810fe8..5ffd3fc 100644
--- a/ir_clone.cpp
+++ b/ir_clone.cpp
@@ -36,7 +36,8 @@
ir_instruction *
ir_variable::clone(struct hash_table *ht) const
{
- ir_variable *var = new ir_variable(type, name);
+ void *ctx = talloc_parent(this);
+ ir_variable *var = new(ctx) ir_variable(type, name);
var->max_array_access = this->max_array_access;
var->read_only = this->read_only;
@@ -55,32 +56,36 @@ ir_variable::clone(struct hash_table *ht) const
ir_instruction *
ir_swizzle::clone(struct hash_table *ht) const
{
- return new ir_swizzle((ir_rvalue *)this->val->clone(ht), this->mask);
+ void *ctx = talloc_parent(this);
+ return new(ctx) ir_swizzle((ir_rvalue *)this->val->clone(ht), this->mask);
}
ir_instruction *
ir_return::clone(struct hash_table *ht) const
{
+ void *ctx = talloc_parent(this);
ir_rvalue *new_value = NULL;
if (this->value)
new_value = (ir_rvalue *)this->value->clone(ht);
- return new ir_return(new_value);
+ return new(ctx) ir_return(new_value);
}
ir_instruction *
ir_loop_jump::clone(struct hash_table *ht) const
{
+ void *ctx = talloc_parent(this);
(void)ht;
- return new ir_loop_jump(this->mode);
+ return new(ctx) ir_loop_jump(this->mode);
}
ir_instruction *
ir_if::clone(struct hash_table *ht) const
{
- ir_if *new_if = new ir_if((ir_rvalue *)this->condition->clone(ht));
+ void *ctx = talloc_parent(this);
+ ir_if *new_if = new(ctx) ir_if((ir_rvalue *)this->condition->clone(ht));
foreach_iter(exec_list_iterator, iter, this->then_instructions) {
ir_instruction *ir = (ir_instruction *)iter.get();
@@ -98,7 +103,8 @@ ir_if::clone(struct hash_table *ht) const
ir_instruction *
ir_loop::clone(struct hash_table *ht) const
{
- ir_loop *new_loop = new ir_loop();
+ void *ctx = talloc_parent(this);
+ ir_loop *new_loop = new(ctx) ir_loop();
if (this->from)
new_loop->from = (ir_rvalue *)this->from->clone(ht);
@@ -119,6 +125,7 @@ ir_loop::clone(struct hash_table *ht) const
ir_instruction *
ir_call::clone(struct hash_table *ht) const
{
+ void *ctx = talloc_parent(this);
exec_list new_parameters;
foreach_iter(exec_list_iterator, iter, this->actual_parameters) {
@@ -126,12 +133,13 @@ ir_call::clone(struct hash_table *ht) const
new_parameters.push_tail(ir->clone(ht));
}
- return new ir_call(this->callee, &new_parameters);
+ return new(ctx) ir_call(this->callee, &new_parameters);
}
ir_instruction *
ir_expression::clone(struct hash_table *ht) const
{
+ void *ctx = talloc_parent(this);
ir_rvalue *op[2] = {NULL, NULL};
unsigned int i;
@@ -139,12 +147,13 @@ ir_expression::clone(struct hash_table *ht) const
op[i] = (ir_rvalue *)this->operands[i]->clone(ht);
}
- return new ir_expression(this->operation, this->type, op[0], op[1]);
+ return new(ctx) ir_expression(this->operation, this->type, op[0], op[1]);
}
ir_instruction *
ir_dereference_variable::clone(struct hash_table *ht) const
{
+ void *ctx = talloc_parent(this);
ir_variable *new_var;
if (ht) {
@@ -155,27 +164,30 @@ ir_dereference_variable::clone(struct hash_table *ht) const
new_var = this->var;
}
- return new ir_dereference_variable(new_var);
+ return new(ctx) ir_dereference_variable(new_var);
}
ir_instruction *
ir_dereference_array::clone(struct hash_table *ht) const
{
- return new ir_dereference_array((ir_rvalue *)this->array->clone(ht),
- (ir_rvalue *)this->array_index->clone(ht));
+ void *ctx = talloc_parent(this);
+ return new(ctx) ir_dereference_array((ir_rvalue *)this->array->clone(ht),
+ (ir_rvalue *)this->array_index->clone(ht));
}
ir_instruction *
ir_dereference_record::clone(struct hash_table *ht) const
{
- return new ir_dereference_record((ir_rvalue *)this->record->clone(ht),
- this->field);
+ void *ctx = talloc_parent(this);
+ return new(ctx) ir_dereference_record((ir_rvalue *)this->record->clone(ht),
+ this->field);
}
ir_instruction *
ir_texture::clone(struct hash_table *ht) const
{
- ir_texture *new_tex = new ir_texture(this->op);
+ void *ctx = talloc_parent(this);
+ ir_texture *new_tex = new(ctx) ir_texture(this->op);
new_tex->sampler = (ir_dereference *)this->sampler->clone(ht);
new_tex->coordinate = (ir_rvalue *)this->coordinate->clone(ht);
@@ -218,9 +230,10 @@ ir_assignment::clone(struct hash_table *ht) const
if (this->condition)
new_condition = (ir_rvalue *)this->condition->clone(ht);
- return new ir_assignment((ir_rvalue *)this->lhs->clone(ht),
- (ir_rvalue *)this->rhs->clone(ht),
- new_condition);
+ void *ctx = talloc_parent(this);
+ return new(ctx) ir_assignment((ir_rvalue *)this->lhs->clone(ht),
+ (ir_rvalue *)this->rhs->clone(ht),
+ new_condition);
}
ir_instruction *
diff --git a/ir_constant_expression.cpp b/ir_constant_expression.cpp
index effb888..4010e46 100644
--- a/ir_constant_expression.cpp
+++ b/ir_constant_expression.cpp
@@ -127,6 +127,7 @@ ir_constant_visitor::visit(ir_function *ir)
void
ir_constant_visitor::visit(ir_expression *ir)
{
+ void *ctx = talloc_parent(ir);
value = NULL;
ir_constant *op[2];
unsigned int operand, c;
@@ -497,7 +498,7 @@ ir_constant_visitor::visit(ir_expression *ir)
return;
}
- this->value = new ir_constant(ir->type, &data);
+ this->value = new(ctx) ir_constant(ir->type, &data);
}
@@ -513,6 +514,7 @@ ir_constant_visitor::visit(ir_texture *ir)
void
ir_constant_visitor::visit(ir_swizzle *ir)
{
+ void *ctx = talloc_parent(ir);
ir_constant *v = ir->val->constant_expression_value();
this->value = NULL;
@@ -534,7 +536,7 @@ ir_constant_visitor::visit(ir_swizzle *ir)
}
}
- this->value = new ir_constant(ir->type, &data);
+ this->value = new(ctx) ir_constant(ir->type, &data);
}
}
@@ -553,6 +555,7 @@ ir_constant_visitor::visit(ir_dereference_variable *ir)
void
ir_constant_visitor::visit(ir_dereference_array *ir)
{
+ void *ctx = talloc_parent(ir);
ir_constant *array = ir->array->constant_expression_value();
ir_constant *idx = ir->array_index->constant_expression_value();
@@ -592,11 +595,11 @@ ir_constant_visitor::visit(ir_dereference_array *ir)
break;
}
- this->value = new ir_constant(column_type, &data);
+ this->value = new(ctx) ir_constant(column_type, &data);
} else if (array->type->is_vector()) {
const unsigned component = idx->value.u[0];
- this->value = new ir_constant(array, component);
+ this->value = new(ctx) ir_constant(array, component);
} else {
/* FINISHME: Handle access of constant arrays. */
}
diff --git a/ir_copy_propagation.cpp b/ir_copy_propagation.cpp
index 16a2ba7..46ef667 100644
--- a/ir_copy_propagation.cpp
+++ b/ir_copy_propagation.cpp
@@ -197,6 +197,7 @@ kill_invalidated_copies(ir_assignment *ir, exec_list *acp)
static void
add_copy(ir_assignment *ir, exec_list *acp)
{
+ void *ctx = talloc_parent(ir);
acp_entry *entry;
if (ir->condition) {
@@ -209,7 +210,7 @@ add_copy(ir_assignment *ir, exec_list *acp)
ir_variable *rhs_var = ir->rhs->whole_variable_referenced();
if ((lhs_var != NULL) && (rhs_var != NULL)) {
- entry = new acp_entry(lhs_var, rhs_var);
+ entry = new(ctx) acp_entry(lhs_var, rhs_var);
acp->push_tail(entry);
}
}
diff --git a/ir_dead_code.cpp b/ir_dead_code.cpp
index 8465d86..01b7d2d 100644
--- a/ir_dead_code.cpp
+++ b/ir_dead_code.cpp
@@ -77,6 +77,7 @@ public:
variable_entry *
ir_dead_code_visitor::get_variable_entry(ir_variable *var)
{
+ void *ctx = talloc_parent(var);
assert(var);
foreach_iter(exec_list_iterator, iter, this->variable_list) {
variable_entry *entry = (variable_entry *)iter.get();
@@ -84,7 +85,7 @@ ir_dead_code_visitor::get_variable_entry(ir_variable *var)
return entry;
}
- variable_entry *entry = new variable_entry(var);
+ variable_entry *entry = new(ctx) variable_entry(var);
this->variable_list.push_tail(entry);
return entry;
}
diff --git a/ir_dead_code_local.cpp b/ir_dead_code_local.cpp
index d3b3858..e018770 100644
--- a/ir_dead_code_local.cpp
+++ b/ir_dead_code_local.cpp
@@ -113,6 +113,7 @@ public:
static bool
process_assignment(ir_assignment *ir, exec_list *assignments)
{
+ void *ctx = talloc_parent(ir);
ir_variable *var = NULL;
bool progress = false;
kill_for_derefs_visitor v(assignments);
@@ -157,7 +158,7 @@ process_assignment(ir_assignment *ir, exec_list *assignments)
}
/* Add this instruction to the assignment list. */
- assignment_entry *entry = new assignment_entry(var, ir);
+ assignment_entry *entry = new(ctx) assignment_entry(var, ir);
assignments->push_tail(entry);
if (debug) {
diff --git a/ir_expression_flattening.cpp b/ir_expression_flattening.cpp
index 3089f17..5ba24e3 100644
--- a/ir_expression_flattening.cpp
+++ b/ir_expression_flattening.cpp
@@ -80,18 +80,19 @@ do_expression_flattening(exec_list *instructions,
static ir_rvalue *
operand_to_temp(ir_instruction *base_ir, ir_rvalue *ir)
{
+ void *ctx = talloc_parent(base_ir);
ir_variable *var;
ir_assignment *assign;
- var = new ir_variable(ir->type, "flattening_tmp");
+ var = new(ctx) ir_variable(ir->type, "flattening_tmp");
base_ir->insert_before(var);
- assign = new ir_assignment(new ir_dereference_variable(var),
- ir,
- NULL);
+ assign = new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var),
+ ir,
+ NULL);
base_ir->insert_before(assign);
- return new ir_dereference_variable(var);
+ return new(ctx) ir_dereference_variable(var);
}
ir_visitor_status
diff --git a/ir_function_inlining.cpp b/ir_function_inlining.cpp
index effb01c..8a1cf4f 100644
--- a/ir_function_inlining.cpp
+++ b/ir_function_inlining.cpp
@@ -94,6 +94,7 @@ do_function_inlining(exec_list *instructions)
ir_rvalue *
ir_call::generate_inline(ir_instruction *next_ir)
{
+ void *ctx = talloc_parent(this);
ir_variable **parameters;
int num_parameters;
int i;
@@ -110,7 +111,7 @@ ir_call::generate_inline(ir_instruction *next_ir)
/* Generate storage for the return value. */
if (this->callee->return_type) {
- retval = new ir_variable(this->callee->return_type, "__retval");
+ retval = new(ctx) ir_variable(this->callee->return_type, "__retval");
next_ir->insert_before(retval);
}
@@ -133,8 +134,8 @@ ir_call::generate_inline(ir_instruction *next_ir)
parameters[i]->mode == ir_var_inout) {
ir_assignment *assign;
- assign = new ir_assignment(new ir_dereference_variable(parameters[i]),
- param, NULL);
+ assign = new(ctx) ir_assignment(new(ctx) ir_dereference_variable(parameters[i]),
+ param, NULL);
next_ir->insert_before(assign);
}
@@ -162,9 +163,9 @@ ir_call::generate_inline(ir_instruction *next_ir)
parameters[i]->mode == ir_var_inout) {
ir_assignment *assign;
- assign = new ir_assignment(param->as_rvalue(),
- new ir_dereference_variable(parameters[i]),
- NULL);
+ assign = new(ctx) ir_assignment(param->as_rvalue(),
+ new(ctx) ir_dereference_variable(parameters[i]),
+ NULL);
next_ir->insert_before(assign);
}
@@ -176,7 +177,7 @@ ir_call::generate_inline(ir_instruction *next_ir)
hash_table_dtor(ht);
if (retval)
- return new ir_dereference_variable(retval);
+ return new(ctx) ir_dereference_variable(retval);
else
return NULL;
}
diff --git a/ir_reader.cpp b/ir_reader.cpp
index ee320dd..d6985c4 100644
--- a/ir_reader.cpp
+++ b/ir_reader.cpp
@@ -70,7 +70,8 @@ void
_mesa_glsl_read_ir(_mesa_glsl_parse_state *state, exec_list *instructions,
const char *src)
{
- s_expression *expr = s_expression::read_expression(src);
+ void *ctx = talloc_parent(state);
+ s_expression *expr = s_expression::read_expression(ctx, src);
if (expr == NULL) {
ir_read_error(state, NULL, "couldn't parse S-Expression.");
return;
@@ -190,6 +191,7 @@ scan_for_prototypes(_mesa_glsl_parse_state *st, exec_list *instructions,
static ir_function *
read_function(_mesa_glsl_parse_state *st, s_list *list, bool skip_body)
{
+ void *ctx = talloc_parent(st);
if (list->length() < 3) {
ir_read_error(st, list, "Expected (function <name> (signature ...) ...)");
return NULL;
@@ -203,7 +205,7 @@ read_function(_mesa_glsl_parse_state *st, s_list *list, bool skip_body)
ir_function *f = st->symbols->get_function(name->value());
if (f == NULL) {
- f = new ir_function(name->value());
+ f = new(ctx) ir_function(name->value());
bool added = st->symbols->add_function(name->value(), f);
assert(added);
}
@@ -233,6 +235,7 @@ static void
read_function_sig(_mesa_glsl_parse_state *st, ir_function *f, s_list *list,
bool skip_body)
{
+ void *ctx = talloc_parent(st);
if (list->length() != 4) {
ir_read_error(st, list, "Expected (signature <type> (parameters ...) "
"(<instruction> ...))");
@@ -286,7 +289,7 @@ read_function_sig(_mesa_glsl_parse_state *st, ir_function *f, s_list *list,
return;
}
} else {
- sig = new ir_function_signature(return_type);
+ sig = new(ctx) ir_function_signature(return_type);
f->add_signature(sig);
}
@@ -331,12 +334,13 @@ static ir_instruction *
read_instruction(_mesa_glsl_parse_state *st, s_expression *expr,
ir_loop *loop_ctx)
{
+ void *ctx = talloc_parent(st);
s_symbol *symbol = SX_AS_SYMBOL(expr);
if (symbol != NULL) {
if (strcmp(symbol->value(), "break") == 0 && loop_ctx != NULL)
- return new ir_loop_jump(ir_loop_jump::jump_break);
+ return new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
if (strcmp(symbol->value(), "continue") == 0 && loop_ctx != NULL)
- return new ir_loop_jump(ir_loop_jump::jump_continue);
+ return new(ctx) ir_loop_jump(ir_loop_jump::jump_continue);
}
s_list *list = SX_AS_LIST(expr);
@@ -372,6 +376,7 @@ read_instruction(_mesa_glsl_parse_state *st, s_expression *expr,
static ir_variable *
read_declaration(_mesa_glsl_parse_state *st, s_list *list)
{
+ void *ctx = talloc_parent(st);
if (list->length() != 4) {
ir_read_error(st, list, "expected (declare (<qualifiers>) <type> "
"<name>)");
@@ -395,7 +400,7 @@ read_declaration(_mesa_glsl_parse_state *st, s_list *list)
return NULL;
}
- ir_variable *var = new ir_variable(type, var_name->value());
+ ir_variable *var = new(ctx) ir_variable(type, var_name->value());
foreach_iter(exec_list_iterator, it, quals->subexpressions) {
s_symbol *qualifier = SX_AS_SYMBOL(it.get());
@@ -443,6 +448,7 @@ read_declaration(_mesa_glsl_parse_state *st, s_list *list)
static ir_if *
read_if(_mesa_glsl_parse_state *st, s_list *list, ir_loop *loop_ctx)
{
+ void *ctx = talloc_parent(st);
if (list->length() != 4) {
ir_read_error(st, list, "expected (if <condition> (<then> ...) "
"(<else> ...))");
@@ -459,7 +465,7 @@ read_if(_mesa_glsl_parse_state *st, s_list *list, ir_loop *loop_ctx)
s_expression *then_expr = (s_expression*) cond_expr->next;
s_expression *else_expr = (s_expression*) then_expr->next;
- ir_if *iff = new ir_if(condition);
+ ir_if *iff = new(ctx) ir_if(condition);
read_instructions(st, &iff->then_instructions, then_expr, loop_ctx);
read_instructions(st, &iff->else_instructions, else_expr, loop_ctx);
@@ -474,6 +480,7 @@ read_if(_mesa_glsl_parse_state *st, s_list *list, ir_loop *loop_ctx)
static ir_loop *
read_loop(_mesa_glsl_parse_state *st, s_list *list)
{
+ void *ctx = talloc_parent(st);
if (list->length() != 6) {
ir_read_error(st, list, "expected (loop <counter> <from> <to> "
"<increment> <body>)");
@@ -488,7 +495,7 @@ read_loop(_mesa_glsl_parse_state *st, s_list *list)
// FINISHME: actually read the count/from/to fields.
- ir_loop *loop = new ir_loop;
+ ir_loop *loop = new(ctx) ir_loop;
read_instructions(st, &loop->body_instructions, body_expr, loop);
if (st->error) {
delete loop;
@@ -501,6 +508,7 @@ read_loop(_mesa_glsl_parse_state *st, s_list *list)
static ir_return *
read_return(_mesa_glsl_parse_state *st, s_list *list)
{
+ void *ctx = talloc_parent(st);
if (list->length() != 2) {
ir_read_error(st, list, "expected (return <rvalue>)");
return NULL;
@@ -514,7 +522,7 @@ read_return(_mesa_glsl_parse_state *st, s_list *list)
return NULL;
}
- return new ir_return(retval);
+ return new(ctx) ir_return(retval);
}
@@ -556,6 +564,7 @@ read_rvalue(_mesa_glsl_parse_state *st, s_expression *expr)
static ir_assignment *
read_assignment(_mesa_glsl_parse_state *st, s_list *list)
{
+ void *ctx = talloc_parent(st);
if (list->length() != 4) {
ir_read_error(st, list, "expected (assign <condition> <lhs> <rhs>)");
return NULL;
@@ -584,12 +593,13 @@ read_assignment(_mesa_glsl_parse_state *st, s_list *list)
return NULL;
}
- return new ir_assignment(lhs, rhs, condition);
+ return new(ctx) ir_assignment(lhs, rhs, condition);
}
static ir_call *
read_call(_mesa_glsl_parse_state *st, s_list *list)
{
+ void *ctx = talloc_parent(st);
if (list->length() != 3) {
ir_read_error(st, list, "expected (call <name> (<param> ...))");
return NULL;
@@ -628,12 +638,13 @@ read_call(_mesa_glsl_parse_state *st, s_list *list)
return NULL;
}
- return new ir_call(callee, &parameters);
+ return new(ctx) ir_call(callee, &parameters);
}
static ir_expression *
read_expression(_mesa_glsl_parse_state *st, s_list *list)
{
+ void *ctx = talloc_parent(st);
const unsigned list_length = list->length();
if (list_length < 4) {
ir_read_error(st, list, "expected (expression <type> <operator> "
@@ -693,7 +704,7 @@ read_expression(_mesa_glsl_parse_state *st, s_list *list)
}
}
- return new ir_expression(op, type, arg1, arg2);
+ return new(ctx) ir_expression(op, type, arg1, arg2);
}
static ir_swizzle *
@@ -738,6 +749,7 @@ read_swizzle(_mesa_glsl_parse_state *st, s_list *list)
static ir_constant *
read_constant(_mesa_glsl_parse_state *st, s_list *list)
{
+ void *ctx = talloc_parent(st);
if (list->length() != 3) {
ir_read_error(st, list, "expected (constant <type> (<num> ... <num>))");
return NULL;
@@ -803,7 +815,7 @@ read_constant(_mesa_glsl_parse_state *st, s_list *list)
++k;
}
- return new ir_constant(type, &data);
+ return new(ctx) ir_constant(type, &data);
}
static ir_dereference *
@@ -828,6 +840,7 @@ read_dereference(_mesa_glsl_parse_state *st, s_expression *expr)
static ir_dereference *
read_var_ref(_mesa_glsl_parse_state *st, s_list *list)
{
+ void *ctx = talloc_parent(st);
if (list->length() != 2) {
ir_read_error(st, list, "expected (var_ref <variable name>)");
return NULL;
@@ -844,12 +857,13 @@ read_var_ref(_mesa_glsl_parse_state *st, s_list *list)
return NULL;
}
- return new ir_dereference_variable(var);
+ return new(ctx) ir_dereference_variable(var);
}
static ir_dereference *
read_array_ref(_mesa_glsl_parse_state *st, s_list *list)
{
+ void *ctx = talloc_parent(st);
if (list->length() != 3) {
ir_read_error(st, list, "expected (array_ref <rvalue> <index>)");
return NULL;
@@ -864,12 +878,13 @@ read_array_ref(_mesa_glsl_parse_state *st, s_list *list)
s_expression *idx_expr = (s_expression*) subj_expr->next;
ir_rvalue *idx = read_rvalue(st, idx_expr);
- return new ir_dereference_array(subject, idx);
+ return new(ctx) ir_dereference_array(subject, idx);
}
static ir_dereference *
read_record_ref(_mesa_glsl_parse_state *st, s_list *list)
{
+ void *ctx = talloc_parent(st);
if (list->length() != 3) {
ir_read_error(st, list, "expected (record_ref <rvalue> <field>)");
return NULL;
@@ -887,7 +902,7 @@ read_record_ref(_mesa_glsl_parse_state *st, s_list *list)
ir_read_error(st, list, "expected (record_ref ... <field name>)");
return NULL;
}
- return new ir_dereference_record(subject, field->value());
+ return new(ctx) ir_dereference_record(subject, field->value());
}
static bool
@@ -905,6 +920,7 @@ valid_texture_list_length(ir_texture_opcode op, s_list *list)
static ir_texture *
read_texture(_mesa_glsl_parse_state *st, s_list *list)
{
+ void *ctx = talloc_parent(st);
s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.head);
assert(tag != NULL);
@@ -917,7 +933,7 @@ read_texture(_mesa_glsl_parse_state *st, s_list *list)
return NULL;
}
- ir_texture *tex = new ir_texture(op);
+ ir_texture *tex = new(ctx) ir_texture(op);
// Read sampler (must be a deref)
s_expression *sampler_expr = (s_expression *) tag->next;
diff --git a/ir_variable.cpp b/ir_variable.cpp
index efebe91..fabd856 100644
--- a/ir_variable.cpp
+++ b/ir_variable.cpp
@@ -35,7 +35,7 @@ add_variable(const char *name, enum ir_variable_mode mode, int slot,
const glsl_type *type, exec_list *instructions,
glsl_symbol_table *symtab)
{
- ir_variable *var = new ir_variable(type, name);
+ ir_variable *var = new(symtab) ir_variable(type, name);
var->mode = mode;
switch (var->mode) {
diff --git a/ir_vec_index_to_swizzle.cpp b/ir_vec_index_to_swizzle.cpp
index eb0e556..bbd8737 100644
--- a/ir_vec_index_to_swizzle.cpp
+++ b/ir_vec_index_to_swizzle.cpp
@@ -60,6 +60,7 @@ public:
ir_rvalue *
ir_vec_index_to_swizzle_visitor::convert_vec_index_to_swizzle(ir_rvalue *ir)
{
+ void *ctx = talloc_parent(ir);
ir_dereference_array *deref = ir->as_dereference_array();
ir_constant *ir_constant;
@@ -75,7 +76,8 @@ ir_vec_index_to_swizzle_visitor::convert_vec_index_to_swizzle(ir_rvalue *ir)
return ir;
this->progress = true;
- return new ir_swizzle(deref->array, ir_constant->value.i[0], 0, 0, 0, 1);
+ return new(ctx) ir_swizzle(deref->array,
+ ir_constant->value.i[0], 0, 0, 0, 1);
}
ir_visitor_status
diff --git a/list.h b/list.h
index 0b91647..7732d66 100644
--- a/list.h
+++ b/list.h
@@ -66,7 +66,13 @@
#ifndef __cplusplus
#include <stddef.h>
+#include <talloc.h>
+#else
+extern "C" {
+#include <talloc.h>
+}
#endif
+
#include <assert.h>
struct exec_node {
@@ -74,6 +80,25 @@ struct exec_node {
struct exec_node *prev;
#ifdef __cplusplus
+ /* Callers of this talloc-based new need not call delete. It's
+ * easier to just talloc_free 'ctx' (or any of its ancestors). */
+ static void* operator new(size_t size, void *ctx)
+ {
+ void *node;
+
+ node = talloc_size(ctx, size);
+ assert(node != NULL);
+
+ return node;
+ }
+
+ /* If the user *does* call delete, that's OK, we will just
+ * talloc_free in that case. */
+ static void operator delete(void *node)
+ {
+ talloc_free(node);
+ }
+
exec_node() : next(NULL), prev(NULL)
{
/* empty */
diff --git a/s_expression.cpp b/s_expression.cpp
index 0fb296e..875d739 100644
--- a/s_expression.cpp
+++ b/s_expression.cpp
@@ -49,7 +49,7 @@ s_list::length() const
}
static s_expression *
-read_atom(const char *& src)
+read_atom(void *ctx, const char *& src)
{
char buf[101];
int n;
@@ -65,20 +65,20 @@ read_atom(const char *& src)
int i = strtol(buf, &int_end, 10);
// If strtod matched more characters, it must have a decimal part
if (float_end > int_end)
- return new s_float(f);
+ return new(ctx) s_float(f);
- return new s_int(i);
+ return new(ctx) s_int(i);
}
// Not a number; return a symbol.
- return new s_symbol(buf);
+ return new(ctx) s_symbol(buf);
}
s_expression *
-s_expression::read_expression(const char *&src)
+s_expression::read_expression(void *ctx, const char *&src)
{
assert(src != NULL);
- s_expression *atom = read_atom(src);
+ s_expression *atom = read_atom(ctx, src);
if (atom != NULL)
return atom;
@@ -87,10 +87,10 @@ s_expression::read_expression(const char *&src)
if (sscanf(src, " %c%n", &c, &n) == 1 && c == '(') {
src += n;
- s_list *list = new s_list;
+ s_list *list = new(ctx) s_list;
s_expression *expr;
- while ((expr = read_expression(src)) != NULL) {
+ while ((expr = read_expression(ctx, src)) != NULL) {
list->subexpressions.push_tail(expr);
}
if (sscanf(src, " %c%n", &c, &n) != 1 || c != ')') {
diff --git a/s_expression.h b/s_expression.h
index 8a4eda2..1a0c03c 100644
--- a/s_expression.h
+++ b/s_expression.h
@@ -49,8 +49,10 @@ public:
/**
* Read an S-Expression from the given string.
* Advances the supplied pointer to just after the expression read.
+ *
+ * Any allocation will be performed with 'ctx' as the talloc owner.
*/
- static s_expression *read_expression(const char *&src);
+ static s_expression *read_expression(void *ctx, const char *&src);
/**
* Print out an S-Expression. Useful for debugging.