var block = new CCodeBlock ();
if (requires_copy (array_type.element_type)) {
- var old_symbol = current_symbol;
- var old_temp_vars = temp_vars;
- current_symbol = null;
- temp_vars = new ArrayList<LocalVariable> ();
+ push_context (new EmitContext ());
var cdecl = new CCodeDeclaration (array_type.get_cname ());
var cvardecl = new CCodeVariableDeclarator ("result");
var cfrag = new CCodeFragment ();
append_temp_decl (cfrag, temp_vars);
block.add_statement (cfrag);
- current_symbol = old_symbol;
- temp_vars = old_temp_vars;
+
+ pop_context ();
} else {
var dup_call = new CCodeFunctionCall (new CCodeIdentifier ("g_memdup"));
dup_call.add_argument (new CCodeIdentifier ("self"));
var block = new CCodeBlock ();
if (requires_copy (array_type.element_type)) {
- var old_symbol = current_symbol;
- var old_temp_vars = temp_vars;
- current_symbol = null;
- temp_vars = new ArrayList<LocalVariable> ();
+ push_context (new EmitContext ());
var idx_decl = new CCodeDeclaration ("int");
idx_decl.add_declarator (new CCodeVariableDeclarator ("i"));
var cfrag = new CCodeFragment ();
append_temp_decl (cfrag, temp_vars);
block.add_statement (cfrag);
- current_symbol = old_symbol;
- temp_vars = old_temp_vars;
+
+ pop_context ();
} else {
source_declarations.add_include ("string.h");
* Code visitor generating C Code.
*/
public class Vala.CCodeBaseModule : CodeGenerator {
+ public class EmitContext {
+ public Symbol? current_symbol;
+ public ArrayList<Symbol> symbol_stack = new ArrayList<Symbol> ();
+ public TryStatement current_try;
+ public CCodeSwitchStatement state_switch_statement;
+ public ArrayList<LocalVariable> temp_vars = new ArrayList<LocalVariable> ();
+ public ArrayList<LocalVariable> temp_ref_vars = new ArrayList<LocalVariable> ();
+ public int next_temp_var_id;
+ public bool current_method_inner_error;
+ public Map<string,string> variable_name_map = new HashMap<string,string> (str_hash, str_equal);
+
+ public EmitContext (Symbol? symbol = null) {
+ current_symbol = symbol;
+ }
+
+ public void push_symbol (Symbol symbol) {
+ symbol_stack.add (current_symbol);
+ current_symbol = symbol;
+ }
+
+ public void pop_symbol () {
+ current_symbol = symbol_stack[symbol_stack.size - 1];
+ symbol_stack.remove_at (symbol_stack.size - 1);
+ }
+ }
+
public CodeContext context { get; set; }
public Symbol root_symbol;
- public Symbol current_symbol;
- public TryStatement current_try;
+
+ public EmitContext emit_context = new EmitContext ();
+
+ List<EmitContext> emit_context_stack = new ArrayList<EmitContext> ();
+
+ public Symbol current_symbol { get { return emit_context.current_symbol; } }
+
+ public TryStatement current_try {
+ get { return emit_context.current_try; }
+ set { emit_context.current_try = value; }
+ }
public TypeSymbol? current_type_symbol {
get {
// code nodes to be inserted before the current statement
// used by async method calls in coroutines
public CCodeFragment pre_statement_fragment;
+
// case statements to be inserted for the couroutine state
- public CCodeSwitchStatement state_switch_statement;
+ public CCodeSwitchStatement state_switch_statement {
+ get { return emit_context.state_switch_statement; }
+ set { emit_context.state_switch_statement = value; }
+ }
/* all temporary variables */
- public ArrayList<LocalVariable> temp_vars = new ArrayList<LocalVariable> ();
+ public ArrayList<LocalVariable> temp_vars { get { return emit_context.temp_vars; } }
/* temporary variables that own their content */
- public ArrayList<LocalVariable> temp_ref_vars = new ArrayList<LocalVariable> ();
+ public ArrayList<LocalVariable> temp_ref_vars { get { return emit_context.temp_ref_vars; } }
/* cache to check whether a certain marshaller has been created yet */
public Set<string> user_marshal_set;
/* (constant) hash table with all predefined marshallers */
/* (constant) hash table with all reserved identifiers in the generated code */
Set<string> reserved_identifiers;
- public int next_temp_var_id = 0;
+ public int next_temp_var_id {
+ get { return emit_context.next_temp_var_id; }
+ set { emit_context.next_temp_var_id = value; }
+ }
+
public int next_regex_id = 0;
public bool in_creation_method { get { return current_method is CreationMethod; } }
public bool in_constructor = false;
public bool in_static_or_class_context = false;
- public bool current_method_inner_error = false;
+
+ public bool current_method_inner_error {
+ get { return emit_context.current_method_inner_error; }
+ set { emit_context.current_method_inner_error = value; }
+ }
+
public int next_coroutine_state = 1;
int next_block_id = 0;
Map<Block,int> block_map = new HashMap<Block,int> ();
public Set<string> wrappers;
Set<Symbol> generated_external_symbols;
- public Map<string,string> variable_name_map = new HashMap<string,string> (str_hash, str_equal);
+ public Map<string,string> variable_name_map { get { return emit_context.variable_name_map; } }
public CCodeBaseModule () {
predefined_marshal_set = new HashSet<string> (str_hash, str_equal);
}
}
+ public void push_context (EmitContext emit_context) {
+ if (this.emit_context != null) {
+ emit_context_stack.add (this.emit_context);
+ }
+
+ this.emit_context = emit_context;
+ }
+
+ public void pop_context () {
+ if (emit_context_stack.size > 0) {
+ this.emit_context = emit_context_stack[emit_context_stack.size - 1];
+ emit_context_stack.remove_at (emit_context_stack.size - 1);
+ } else {
+ this.emit_context = null;
+ }
+ }
+
public CCodeIdentifier get_value_setter_function (DataType type_reference) {
var array_type = type_reference as ArrayType;
if (type_reference.data_type != null) {
user_marshal_set = new HashSet<string> (str_hash, str_equal);
- next_temp_var_id = 0;
next_regex_id = 0;
- variable_name_map.clear ();
gvaluecollector_h_needed = false;
requires_array_free = false;
check_type (prop.property_type);
- int old_next_temp_var_id = next_temp_var_id;
- var old_temp_vars = temp_vars;
- var old_temp_ref_vars = temp_ref_vars;
- var old_variable_name_map = variable_name_map;
- next_temp_var_id = 0;
- temp_vars = new ArrayList<LocalVariable> ();
- temp_ref_vars = new ArrayList<LocalVariable> ();
- variable_name_map = new HashMap<string,string> (str_hash, str_equal);
-
prop.accept_children (this);
-
- next_temp_var_id = old_next_temp_var_id;
- temp_vars = old_temp_vars;
- temp_ref_vars = old_temp_ref_vars;
- variable_name_map = old_variable_name_map;
}
public void generate_type_declaration (DataType type, CCodeDeclarationSpace decl_space) {
}
public override void visit_property_accessor (PropertyAccessor acc) {
- var old_symbol = current_symbol;
- bool old_method_inner_error = current_method_inner_error;
- current_symbol = acc;
- current_method_inner_error = false;
+ push_context (new EmitContext (acc));
var prop = (Property) acc.prop;
source_type_member_definition.append (function);
}
- current_symbol = old_symbol;
- current_method_inner_error = old_method_inner_error;
+ pop_context ();
}
public override void visit_destructor (Destructor d) {
var dt = (DelegateType) l.target_type;
l.method.cinstance_parameter_position = dt.delegate_symbol.cinstance_parameter_position;
- var old_temp_vars = temp_vars;
- var old_temp_ref_vars = temp_ref_vars;
- temp_vars = new ArrayList<LocalVariable> ();
- temp_ref_vars = new ArrayList<LocalVariable> ();
-
l.accept_children (this);
- temp_vars = old_temp_vars;
- temp_ref_vars = old_temp_ref_vars;
-
l.ccodenode = new CCodeIdentifier (l.method.get_cname ());
}
function.add_parameter (new CCodeFormalParameter ("self", "const " + st.get_cname () + "*"));
function.add_parameter (new CCodeFormalParameter ("dest", st.get_cname () + "*"));
- int old_next_temp_var_id = next_temp_var_id;
- var old_temp_vars = temp_vars;
- var old_temp_ref_vars = temp_ref_vars;
- var old_variable_name_map = variable_name_map;
- next_temp_var_id = 0;
- temp_vars = new ArrayList<LocalVariable> ();
- temp_ref_vars = new ArrayList<LocalVariable> ();
- variable_name_map = new HashMap<string,string> (str_hash, str_equal);
+ push_context (new EmitContext ());
var cblock = new CCodeBlock ();
var cfrag = new CCodeFragment ();
append_temp_decl (cfrag, temp_vars);
temp_vars.clear ();
- next_temp_var_id = old_next_temp_var_id;
- temp_vars = old_temp_vars;
- temp_ref_vars = old_temp_ref_vars;
- variable_name_map = old_variable_name_map;
+ pop_context ();
source_declarations.add_type_member_declaration (function.copy ());
function.block = cblock;
}
public override void visit_method (Method m) {
- var old_symbol = current_symbol;
- bool old_method_inner_error = current_method_inner_error;
- int old_next_temp_var_id = next_temp_var_id;
- var old_temp_vars = temp_vars;
- var old_temp_ref_vars = temp_ref_vars;
- var old_variable_name_map = variable_name_map;
- var old_try = current_try;
- var old_state_switch_statement = state_switch_statement;
- current_symbol = m;
- current_method_inner_error = false;
- next_temp_var_id = 0;
- temp_vars = new ArrayList<LocalVariable> ();
- temp_ref_vars = new ArrayList<LocalVariable> ();
- variable_name_map = new HashMap<string,string> (str_hash, str_equal);
- current_try = null;
- state_switch_statement = null;
+ push_context (new EmitContext (m));
bool in_gobject_creation_method = false;
bool in_fundamental_creation_method = false;
bool inner_error = current_method_inner_error;
- current_symbol = old_symbol;
- current_method_inner_error = old_method_inner_error;
- next_temp_var_id = old_next_temp_var_id;
- temp_vars = old_temp_vars;
- temp_ref_vars = old_temp_ref_vars;
- variable_name_map = old_variable_name_map;
- current_try = old_try;
- state_switch_statement = old_state_switch_statement;
+ pop_context ();
// do not declare overriding methods and interface implementations
if (m.is_abstract || m.is_virtual
}
public override void visit_struct (Struct st) {
- var old_symbol = current_symbol;
+ push_context (new EmitContext (st));
+
var old_instance_finalize_fragment = instance_finalize_fragment;
- current_symbol = st;
instance_finalize_fragment = new CCodeFragment ();
generate_struct_declaration (st, source_declarations);
add_struct_free_function (st);
}
- current_symbol = old_symbol;
instance_finalize_fragment = old_instance_finalize_fragment;
+
+ pop_context ();
}
void add_struct_dup_function (Struct st) {
* Code visitor generating C Code.
*/
public class Vala.DovaBaseModule : CodeGenerator {
+ public class EmitContext {
+ public Symbol? current_symbol;
+ public ArrayList<Symbol> symbol_stack = new ArrayList<Symbol> ();
+ public TryStatement current_try;
+ public ArrayList<LocalVariable> temp_vars = new ArrayList<LocalVariable> ();
+ public ArrayList<LocalVariable> temp_ref_vars = new ArrayList<LocalVariable> ();
+ public int next_temp_var_id;
+ public Map<string,string> variable_name_map = new HashMap<string,string> (str_hash, str_equal);
+
+ public EmitContext (Symbol? symbol = null) {
+ current_symbol = symbol;
+ }
+
+ public void push_symbol (Symbol symbol) {
+ symbol_stack.add (current_symbol);
+ current_symbol = symbol;
+ }
+
+ public void pop_symbol () {
+ current_symbol = symbol_stack[symbol_stack.size - 1];
+ symbol_stack.remove_at (symbol_stack.size - 1);
+ }
+ }
+
public CodeContext context { get; set; }
public Symbol root_symbol;
- public Symbol current_symbol;
- public TryStatement current_try;
+
+ public EmitContext emit_context = new EmitContext ();
+
+ List<EmitContext> emit_context_stack = new ArrayList<EmitContext> ();
+
+ public Symbol current_symbol { get { return emit_context.current_symbol; } }
+
+ public TryStatement current_try {
+ get { return emit_context.current_try; }
+ set { emit_context.current_try = value; }
+ }
public TypeSymbol? current_type_symbol {
get {
public CCodeFragment pre_statement_fragment;
/* all temporary variables */
- public ArrayList<LocalVariable> temp_vars = new ArrayList<LocalVariable> ();
+ public ArrayList<LocalVariable> temp_vars { get { return emit_context.temp_vars; } }
/* temporary variables that own their content */
- public ArrayList<LocalVariable> temp_ref_vars = new ArrayList<LocalVariable> ();
+ public ArrayList<LocalVariable> temp_ref_vars { get { return emit_context.temp_ref_vars; } }
/* (constant) hash table with all reserved identifiers in the generated code */
Set<string> reserved_identifiers;
- public int next_temp_var_id = 0;
+ public int next_temp_var_id {
+ get { return emit_context.next_temp_var_id; }
+ set { emit_context.next_temp_var_id = value; }
+ }
+
public int next_wrapper_id = 0;
public bool in_creation_method { get { return current_method is CreationMethod; } }
int next_block_id = 0;
Set<Symbol> generated_external_symbols;
- public Map<string,string> variable_name_map = new HashMap<string,string> (str_hash, str_equal);
+ public Map<string,string> variable_name_map { get { return emit_context.variable_name_map; } }
public DovaBaseModule () {
reserved_identifiers = new HashSet<string> (str_hash, str_equal);
source_declarations.add_include ("dova-base.h");
}
- next_temp_var_id = 0;
- variable_name_map.clear ();
-
generated_external_symbols = new HashSet<Symbol> ();
}
}
+ public void push_context (EmitContext emit_context) {
+ if (this.emit_context != null) {
+ emit_context_stack.add (this.emit_context);
+ }
+
+ this.emit_context = emit_context;
+ }
+
+ public void pop_context () {
+ if (emit_context_stack.size > 0) {
+ this.emit_context = emit_context_stack[emit_context_stack.size - 1];
+ emit_context_stack.remove_at (emit_context_stack.size - 1);
+ } else {
+ this.emit_context = null;
+ }
+ }
+
public override void visit_source_file (SourceFile source_file) {
if (csource_filename == null) {
csource_filename = source_file.get_csource_filename ();
}
public override void visit_property (Property prop) {
- int old_next_temp_var_id = next_temp_var_id;
- var old_temp_vars = temp_vars;
- var old_temp_ref_vars = temp_ref_vars;
- var old_variable_name_map = variable_name_map;
- next_temp_var_id = 0;
- temp_vars = new ArrayList<LocalVariable> ();
- temp_ref_vars = new ArrayList<LocalVariable> ();
- variable_name_map = new HashMap<string,string> (str_hash, str_equal);
-
prop.accept_children (this);
-
- next_temp_var_id = old_next_temp_var_id;
- temp_vars = old_temp_vars;
- temp_ref_vars = old_temp_ref_vars;
- variable_name_map = old_variable_name_map;
}
public void generate_type_declaration (DataType type, CCodeDeclarationSpace decl_space) {
var dt = (DelegateType) l.target_type;
l.method.cinstance_parameter_position = dt.delegate_symbol.cinstance_parameter_position;
- var old_temp_vars = temp_vars;
- var old_temp_ref_vars = temp_ref_vars;
- temp_vars = new ArrayList<LocalVariable> ();
- temp_ref_vars = new ArrayList<LocalVariable> ();
-
l.accept_children (this);
- temp_vars = old_temp_vars;
- temp_ref_vars = old_temp_ref_vars;
-
l.ccodenode = new CCodeIdentifier (l.method.get_cname ());
}
}
public override void visit_class (Class cl) {
- var old_symbol = current_symbol;
+ push_context (new EmitContext (cl));
+
var old_instance_finalize_fragment = instance_finalize_fragment;
- current_symbol = cl;
instance_finalize_fragment = new CCodeFragment ();
generate_class_declaration (cl, source_declarations);
source_type_member_definition.append (create_set_value_from_any_function ());
}
- current_symbol = old_symbol;
instance_finalize_fragment = old_instance_finalize_fragment;
+
+ pop_context ();
}
public override void visit_interface (Interface iface) {
- var old_symbol = current_symbol;
- current_symbol = iface;
+ push_context (new EmitContext (iface));
generate_interface_declaration (iface, source_declarations);
iface.accept_children (this);
- current_symbol = old_symbol;
+ pop_context ();
}
public override void generate_property_accessor_declaration (PropertyAccessor acc, CCodeDeclarationSpace decl_space) {
}
public override void visit_property_accessor (PropertyAccessor acc) {
- var old_symbol = current_symbol;
- current_symbol = acc;
+ push_context (new EmitContext (acc));
var prop = (Property) acc.prop;
source_type_member_definition.append (function);
}
- current_symbol = old_symbol;
+ pop_context ();
}
public override void generate_interface_declaration (Interface iface, CCodeDeclarationSpace decl_space) {
}
public override void visit_method (Method m) {
- var old_symbol = current_symbol;
- int old_next_temp_var_id = next_temp_var_id;
- var old_temp_vars = temp_vars;
- var old_temp_ref_vars = temp_ref_vars;
- var old_variable_name_map = variable_name_map;
- var old_try = current_try;
- current_symbol = m;
- next_temp_var_id = 0;
- temp_vars = new ArrayList<LocalVariable> ();
- temp_ref_vars = new ArrayList<LocalVariable> ();
- variable_name_map = new HashMap<string,string> (str_hash, str_equal);
- current_try = null;
-
+ push_context (new EmitContext (m));
foreach (FormalParameter param in m.get_parameters ()) {
param.accept (this);
}
- current_symbol = old_symbol;
- next_temp_var_id = old_next_temp_var_id;
- temp_vars = old_temp_vars;
- temp_ref_vars = old_temp_ref_vars;
- variable_name_map = old_variable_name_map;
- current_try = old_try;
+ pop_context ();
generate_method_declaration (m, source_declarations);
}
public override void visit_struct (Struct st) {
- var old_symbol = current_symbol;
+ push_context (new EmitContext (st));
+
var old_instance_finalize_fragment = instance_finalize_fragment;
- current_symbol = st;
instance_finalize_fragment = new CCodeFragment ();
generate_struct_declaration (st, source_declarations);
st.accept_children (this);
- current_symbol = old_symbol;
instance_finalize_fragment = old_instance_finalize_fragment;
+
+ pop_context ();
}
}
datadecl.add_declarator (new CCodeVariableDeclarator ("data", new CCodeIdentifier ("_data")));
freeblock.add_statement (datadecl);
- var old_symbol = current_symbol;
- current_symbol = m;
+ push_context (new EmitContext (m));
foreach (FormalParameter param in m.get_parameters ()) {
if (param.direction != ParameterDirection.OUT) {
}
}
- current_symbol = old_symbol;
+ pop_context ();
var freecall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_free"));
freecall.add_argument (new CCodeIdentifier (dataname));
}
public override void visit_class (Class cl) {
- var old_symbol = current_symbol;
+ push_context (new EmitContext (cl));
+
var old_param_spec_struct = param_spec_struct;
var old_prop_enum = prop_enum;
var old_class_init_fragment = class_init_fragment;
var old_base_finalize_fragment = base_finalize_fragment;
var old_instance_init_fragment = instance_init_fragment;
var old_instance_finalize_fragment = instance_finalize_fragment;
- current_symbol = cl;
bool is_gtypeinstance = !cl.is_compact;
bool is_fundamental = is_gtypeinstance && cl.base_class == null;
}
}
- current_symbol = old_symbol;
param_spec_struct = old_param_spec_struct;
prop_enum = old_prop_enum;
class_init_fragment = old_class_init_fragment;
base_finalize_fragment = old_base_finalize_fragment;
instance_init_fragment = old_instance_init_fragment;
instance_finalize_fragment = old_instance_finalize_fragment;
+
+ pop_context ();
}
private void add_type_value_table_init_function (Class cl) {
}
public override void visit_interface (Interface iface) {
- var old_symbol = current_symbol;
- current_symbol = iface;
+ push_context (new EmitContext (iface));
if (iface.get_cname().len () < 3) {
iface.error = true;
source_declarations.add_type_member_declaration (type_fun.get_source_declaration ());
source_type_member_definition.append (type_fun.get_definition ());
- current_symbol = old_symbol;
+ pop_context ();
}
public virtual TypeRegisterFunction create_interface_register_function (Interface iface) {