From: Jürg Billeter Date: Sun, 8 Aug 2010 09:03:07 +0000 (+0200) Subject: codegen: Add EmitContext class X-Git-Tag: 0.9.6~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f37c74e4277da477825b20b3db92706ea77e61dd;p=thirdparty%2Fvala.git codegen: Add EmitContext class --- diff --git a/codegen/valaccodearraymodule.vala b/codegen/valaccodearraymodule.vala index cf364798b..d0966e6d9 100644 --- a/codegen/valaccodearraymodule.vala +++ b/codegen/valaccodearraymodule.vala @@ -769,10 +769,7 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule { 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 (); + push_context (new EmitContext ()); var cdecl = new CCodeDeclaration (array_type.get_cname ()); var cvardecl = new CCodeVariableDeclarator ("result"); @@ -807,8 +804,8 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule { 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")); @@ -851,10 +848,7 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule { 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 (); + push_context (new EmitContext ()); var idx_decl = new CCodeDeclaration ("int"); idx_decl.add_declarator (new CCodeVariableDeclarator ("i")); @@ -871,8 +865,8 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule { 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"); diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 95a190c5e..5524e5da9 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -27,11 +27,46 @@ * Code visitor generating C Code. */ public class Vala.CCodeBaseModule : CodeGenerator { + public class EmitContext { + public Symbol? current_symbol; + public ArrayList symbol_stack = new ArrayList (); + public TryStatement current_try; + public CCodeSwitchStatement state_switch_statement; + public ArrayList temp_vars = new ArrayList (); + public ArrayList temp_ref_vars = new ArrayList (); + public int next_temp_var_id; + public bool current_method_inner_error; + public Map variable_name_map = new HashMap (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 emit_context_stack = new ArrayList (); + + 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 { @@ -135,13 +170,17 @@ public class Vala.CCodeBaseModule : CodeGenerator { // 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 temp_vars = new ArrayList (); + public ArrayList temp_vars { get { return emit_context.temp_vars; } } /* temporary variables that own their content */ - public ArrayList temp_ref_vars = new ArrayList (); + public ArrayList temp_ref_vars { get { return emit_context.temp_ref_vars; } } /* cache to check whether a certain marshaller has been created yet */ public Set user_marshal_set; /* (constant) hash table with all predefined marshallers */ @@ -149,12 +188,21 @@ public class Vala.CCodeBaseModule : CodeGenerator { /* (constant) hash table with all reserved identifiers in the generated code */ Set 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_map = new HashMap (); @@ -214,7 +262,7 @@ public class Vala.CCodeBaseModule : CodeGenerator { public Set wrappers; Set generated_external_symbols; - public Map variable_name_map = new HashMap (str_hash, str_equal); + public Map variable_name_map { get { return emit_context.variable_name_map; } } public CCodeBaseModule () { predefined_marshal_set = new HashSet (str_hash, str_equal); @@ -475,6 +523,23 @@ public class Vala.CCodeBaseModule : CodeGenerator { } } + 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) { @@ -566,9 +631,7 @@ public class Vala.CCodeBaseModule : CodeGenerator { user_marshal_set = new HashSet (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; @@ -1224,21 +1287,7 @@ public class Vala.CCodeBaseModule : CodeGenerator { 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 (); - temp_ref_vars = new ArrayList (); - variable_name_map = new HashMap (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) { @@ -1353,10 +1402,7 @@ public class Vala.CCodeBaseModule : CodeGenerator { } 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; @@ -1610,8 +1656,7 @@ public class Vala.CCodeBaseModule : CodeGenerator { 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) { @@ -5004,16 +5049,8 @@ public class Vala.CCodeBaseModule : CodeGenerator { 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 (); - temp_ref_vars = new ArrayList (); - l.accept_children (this); - temp_vars = old_temp_vars; - temp_ref_vars = old_temp_ref_vars; - l.ccodenode = new CCodeIdentifier (l.method.get_cname ()); } @@ -5650,14 +5687,7 @@ public class Vala.CCodeBaseModule : CodeGenerator { 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 (); - temp_ref_vars = new ArrayList (); - variable_name_map = new HashMap (str_hash, str_equal); + push_context (new EmitContext ()); var cblock = new CCodeBlock (); var cfrag = new CCodeFragment (); @@ -5707,10 +5737,7 @@ public class Vala.CCodeBaseModule : CodeGenerator { 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; diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala index 8df7ca421..1bad76374 100644 --- a/codegen/valaccodemethodmodule.vala +++ b/codegen/valaccodemethodmodule.vala @@ -261,22 +261,7 @@ public class Vala.CCodeMethodModule : CCodeStructModule { } 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 (); - temp_ref_vars = new ArrayList (); - variable_name_map = new HashMap (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; @@ -354,14 +339,7 @@ public class Vala.CCodeMethodModule : CCodeStructModule { 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 diff --git a/codegen/valaccodestructmodule.vala b/codegen/valaccodestructmodule.vala index fc0810b23..84697a563 100644 --- a/codegen/valaccodestructmodule.vala +++ b/codegen/valaccodestructmodule.vala @@ -140,9 +140,9 @@ public class Vala.CCodeStructModule : CCodeBaseModule { } 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); @@ -166,8 +166,9 @@ public class Vala.CCodeStructModule : CCodeBaseModule { 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) { diff --git a/codegen/valadovabasemodule.vala b/codegen/valadovabasemodule.vala index 31499b5e0..2a45d2840 100644 --- a/codegen/valadovabasemodule.vala +++ b/codegen/valadovabasemodule.vala @@ -26,11 +26,44 @@ * Code visitor generating C Code. */ public class Vala.DovaBaseModule : CodeGenerator { + public class EmitContext { + public Symbol? current_symbol; + public ArrayList symbol_stack = new ArrayList (); + public TryStatement current_try; + public ArrayList temp_vars = new ArrayList (); + public ArrayList temp_ref_vars = new ArrayList (); + public int next_temp_var_id; + public Map variable_name_map = new HashMap (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 emit_context_stack = new ArrayList (); + + 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 { @@ -127,13 +160,17 @@ public class Vala.DovaBaseModule : CodeGenerator { public CCodeFragment pre_statement_fragment; /* all temporary variables */ - public ArrayList temp_vars = new ArrayList (); + public ArrayList temp_vars { get { return emit_context.temp_vars; } } /* temporary variables that own their content */ - public ArrayList temp_ref_vars = new ArrayList (); + public ArrayList temp_ref_vars { get { return emit_context.temp_ref_vars; } } /* (constant) hash table with all reserved identifiers in the generated code */ Set 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; @@ -161,7 +198,7 @@ public class Vala.DovaBaseModule : CodeGenerator { Set generated_external_symbols; - public Map variable_name_map = new HashMap (str_hash, str_equal); + public Map variable_name_map { get { return emit_context.variable_name_map; } } public DovaBaseModule () { reserved_identifiers = new HashSet (str_hash, str_equal); @@ -250,9 +287,6 @@ public class Vala.DovaBaseModule : CodeGenerator { source_declarations.add_include ("dova-base.h"); } - next_temp_var_id = 0; - variable_name_map.clear (); - generated_external_symbols = new HashSet (); @@ -324,6 +358,23 @@ public class Vala.DovaBaseModule : CodeGenerator { } } + 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 (); @@ -594,21 +645,7 @@ public class Vala.DovaBaseModule : CodeGenerator { } 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 (); - temp_ref_vars = new ArrayList (); - variable_name_map = new HashMap (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) { @@ -2166,16 +2203,8 @@ public class Vala.DovaBaseModule : CodeGenerator { 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 (); - temp_ref_vars = new ArrayList (); - l.accept_children (this); - temp_vars = old_temp_vars; - temp_ref_vars = old_temp_ref_vars; - l.ccodenode = new CCodeIdentifier (l.method.get_cname ()); } diff --git a/codegen/valadovaobjectmodule.vala b/codegen/valadovaobjectmodule.vala index e944a0cb4..51b2778c0 100644 --- a/codegen/valadovaobjectmodule.vala +++ b/codegen/valadovaobjectmodule.vala @@ -791,9 +791,9 @@ public class Vala.DovaObjectModule : DovaArrayModule { } 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); @@ -969,13 +969,13 @@ public class Vala.DovaObjectModule : DovaArrayModule { 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); @@ -1072,7 +1072,7 @@ public class Vala.DovaObjectModule : DovaArrayModule { iface.accept_children (this); - current_symbol = old_symbol; + pop_context (); } public override void generate_property_accessor_declaration (PropertyAccessor acc, CCodeDeclarationSpace decl_space) { @@ -1135,8 +1135,7 @@ public class Vala.DovaObjectModule : DovaArrayModule { } 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; @@ -1261,7 +1260,7 @@ public class Vala.DovaObjectModule : DovaArrayModule { source_type_member_definition.append (function); } - current_symbol = old_symbol; + pop_context (); } public override void generate_interface_declaration (Interface iface, CCodeDeclarationSpace decl_space) { @@ -1372,19 +1371,7 @@ public class Vala.DovaObjectModule : DovaArrayModule { } 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 (); - temp_ref_vars = new ArrayList (); - variable_name_map = new HashMap (str_hash, str_equal); - current_try = null; - + push_context (new EmitContext (m)); foreach (FormalParameter param in m.get_parameters ()) { param.accept (this); @@ -1407,12 +1394,7 @@ public class Vala.DovaObjectModule : DovaArrayModule { } - 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); diff --git a/codegen/valadovastructmodule.vala b/codegen/valadovastructmodule.vala index ddab46ae6..e934e8071 100644 --- a/codegen/valadovastructmodule.vala +++ b/codegen/valadovastructmodule.vala @@ -70,9 +70,9 @@ public class Vala.DovaStructModule : DovaBaseModule { } 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); @@ -83,8 +83,9 @@ public class Vala.DovaStructModule : DovaBaseModule { st.accept_children (this); - current_symbol = old_symbol; instance_finalize_fragment = old_instance_finalize_fragment; + + pop_context (); } } diff --git a/codegen/valagasyncmodule.vala b/codegen/valagasyncmodule.vala index c55461214..c8fb945b7 100644 --- a/codegen/valagasyncmodule.vala +++ b/codegen/valagasyncmodule.vala @@ -92,8 +92,7 @@ public class Vala.GAsyncModule : GSignalModule { 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) { @@ -129,7 +128,7 @@ public class Vala.GAsyncModule : GSignalModule { } } - current_symbol = old_symbol; + pop_context (); var freecall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_free")); freecall.add_argument (new CCodeIdentifier (dataname)); diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala index 2480f0bbb..c989a3923 100644 --- a/codegen/valagtypemodule.vala +++ b/codegen/valagtypemodule.vala @@ -492,7 +492,8 @@ public class Vala.GTypeModule : GErrorModule { } 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; @@ -501,7 +502,6 @@ public class Vala.GTypeModule : GErrorModule { 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; @@ -679,7 +679,6 @@ public class Vala.GTypeModule : GErrorModule { } } - current_symbol = old_symbol; param_spec_struct = old_param_spec_struct; prop_enum = old_prop_enum; class_init_fragment = old_class_init_fragment; @@ -688,6 +687,8 @@ public class Vala.GTypeModule : GErrorModule { 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) { @@ -1914,8 +1915,7 @@ public class Vala.GTypeModule : GErrorModule { } 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; @@ -1944,7 +1944,7 @@ public class Vala.GTypeModule : GErrorModule { 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) {