1 /* valadovadelegatemodule.vala
3 * Copyright (C) 2006-2010 Jürg Billeter
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 * Jürg Billeter <j@bitron.ch>
21 * Raffaele Sandrini <raffaele@sandrini.ch>
25 * The link between a delegate and generated code.
27 public class Vala
.DovaDelegateModule
: DovaValueModule
{
28 public override void generate_delegate_declaration (Delegate d
, CCodeFile decl_space
) {
29 if (add_symbol_declaration (decl_space
, d
, d
.get_cname ())) {
33 decl_space
.add_type_declaration (new
CCodeTypeDefinition ("struct _%s".printf (d
.get_cname ()), new
CCodeVariableDeclarator (d
.get_cname ())));
35 generate_class_declaration (type_class
, decl_space
);
36 generate_method_declaration ((Method
) object_class
.scope
.lookup ("ref"), decl_space
);
37 generate_method_declaration ((Method
) object_class
.scope
.lookup ("unref"), decl_space
);
39 var type_fun
= new
CCodeFunction ("%s_type_get".printf (d
.get_lower_case_cname ()), "DovaType *");
40 if (d
.is_internal_symbol ()) {
41 type_fun
.modifiers
= CCodeModifiers
.STATIC
;
43 decl_space
.add_function_declaration (type_fun
);
45 var type_init_fun
= new
CCodeFunction ("%s_type_init".printf (d
.get_lower_case_cname ()));
46 if (d
.is_internal_symbol ()) {
47 type_init_fun
.modifiers
= CCodeModifiers
.STATIC
;
49 type_init_fun
.add_parameter (new
CCodeParameter ("type", "DovaType *"));
50 decl_space
.add_function_declaration (type_init_fun
);
52 generate_type_declaration (d
.return_type
, decl_space
);
54 var function
= generate_new_function (d
, decl_space
);
55 function
.block
= null;
56 decl_space
.add_function_declaration (function
);
58 function
= generate_invoke_function (d
, decl_space
);
59 function
.block
= null;
60 decl_space
.add_function_declaration (function
);
63 CCodeFunction
generate_new_function (Delegate d
, CCodeFile decl_space
) {
64 var function
= new
CCodeFunction ("%s_new".printf (d
.get_lower_case_cname ()), "%s*".printf (d
.get_cname ()));
65 if (d
.is_internal_symbol ()) {
66 function
.modifiers
|= CCodeModifiers
.STATIC
;
69 function
.add_parameter (new
CCodeParameter ("target", "DovaObject *"));
70 function
.add_parameter (new
CCodeParameter ("(*method) (void)", "void"));
72 function
.block
= new
CCodeBlock ();
74 var alloc_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_object_alloc"));
75 alloc_call
.add_argument (new
CCodeFunctionCall (new
CCodeIdentifier ("%s_type_get".printf (d
.get_lower_case_cname ()))));
77 var cdecl
= new
CCodeDeclaration ("%s*".printf (d
.get_cname ()));
78 cdecl
.add_declarator (new
CCodeVariableDeclarator ("this", alloc_call
));
79 function
.block
.add_statement (cdecl
);
81 var init_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_delegate_init"));
82 init_call
.add_argument (new
CCodeIdentifier ("this"));
83 init_call
.add_argument (new
CCodeIdentifier ("target"));
84 function
.block
.add_statement (new
CCodeExpressionStatement (init_call
));
86 var priv
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_GET_PRIVATE".printf (d
.get_upper_case_cname ())));
87 priv
.add_argument (new
CCodeIdentifier ("this"));
88 var assignment
= new
CCodeAssignment (new CCodeMemberAccess
.pointer (priv
, "method"), new
CCodeIdentifier ("method"));
89 function
.block
.add_statement (new
CCodeExpressionStatement (assignment
));
91 function
.block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("this")));
96 CCodeFunction
generate_invoke_function (Delegate d
, CCodeFile decl_space
) {
97 var function
= new
CCodeFunction ("%s_invoke".printf (d
.get_lower_case_cname ()));
99 if (d
.is_internal_symbol ()) {
100 function
.modifiers
|= CCodeModifiers
.STATIC
;
103 function
.add_parameter (new
CCodeParameter ("this", "%s*".printf (d
.get_cname ())));
105 string param_list
= "";
107 foreach (Parameter param
in d
.get_parameters ()) {
108 generate_type_declaration (param
.variable_type
, decl_space
);
110 function
.add_parameter (new
CCodeParameter (param
.name
, param
.variable_type
.get_cname ()));
112 if (param_list
!= "") {
115 param_list
+= param
.variable_type
.get_cname ();
118 if (d
.return_type is GenericType
) {
119 function
.add_parameter (new
CCodeParameter ("result", "void *"));
121 if (param_list
!= "") {
124 param_list
+= "void *";
126 function
.return_type
= d
.return_type
.get_cname ();
129 function
.block
= new
CCodeBlock ();
131 var get_target
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_delegate_get_target"));
132 get_target
.add_argument (new
CCodeIdentifier ("this"));
134 var cdecl
= new
CCodeDeclaration ("DovaObject*");
135 cdecl
.add_declarator (new
CCodeVariableDeclarator ("target", get_target
));
136 function
.block
.add_statement (cdecl
);
138 var priv
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_GET_PRIVATE".printf (d
.get_upper_case_cname ())));
139 priv
.add_argument (new
CCodeIdentifier ("this"));
141 string instance_param_list
= "(DovaObject *";
142 if (param_list
!= "") {
143 instance_param_list
+= ",";
144 instance_param_list
+= param_list
;
146 instance_param_list
+= ")";
148 var instance_block
= new
CCodeBlock ();
149 var instance_call
= new
CCodeFunctionCall (new
CCodeCastExpression (new CCodeMemberAccess
.pointer (priv
, "method"), "%s (*) %s".printf (function
.return_type
, instance_param_list
)));
151 instance_call
.add_argument (new
CCodeIdentifier ("target"));
153 string static_param_list
= "(";
154 if (param_list
!= "") {
155 static_param_list
+= param_list
;
157 static_param_list
+= "void";
159 static_param_list
+= ")";
161 var static_block
= new
CCodeBlock ();
162 var static_call
= new
CCodeFunctionCall (new
CCodeCastExpression (new CCodeMemberAccess
.pointer (priv
, "method"), "%s (*) %s".printf (function
.return_type
, static_param_list
)));
164 foreach (Parameter param
in d
.get_parameters ()) {
165 instance_call
.add_argument (new
CCodeIdentifier (param
.name
));
166 static_call
.add_argument (new
CCodeIdentifier (param
.name
));
169 if (d
.return_type is VoidType
) {
170 instance_block
.add_statement (new
CCodeExpressionStatement (instance_call
));
171 static_block
.add_statement (new
CCodeExpressionStatement (static_call
));
172 } else if (d
.return_type is GenericType
) {
173 instance_call
.add_argument (new
CCodeIdentifier ("result"));
174 static_call
.add_argument (new
CCodeIdentifier ("result"));
175 instance_block
.add_statement (new
CCodeExpressionStatement (instance_call
));
176 static_block
.add_statement (new
CCodeExpressionStatement (static_call
));
178 instance_block
.add_statement (new
CCodeReturnStatement (instance_call
));
179 static_block
.add_statement (new
CCodeReturnStatement (static_call
));
182 function
.block
.add_statement (new
CCodeIfStatement (new
CCodeIdentifier ("target"), instance_block
, static_block
));
187 public override void visit_delegate (Delegate d
) {
188 d
.accept_children (this
);
190 generate_delegate_declaration (d
, cfile
);
192 if (!d
.is_internal_symbol ()) {
193 generate_delegate_declaration (d
, header_file
);
196 generate_type_get_function (d
, delegate_class
);
198 var instance_priv_struct
= new
CCodeStruct ("_%sPrivate".printf (d
.get_cname ()));
200 instance_priv_struct
.add_field ("void", "(*method) (void)");
202 cfile
.add_type_declaration (new
CCodeTypeDefinition ("struct %s".printf (instance_priv_struct
.name
), new
CCodeVariableDeclarator ("%sPrivate".printf (d
.get_cname ()))));
203 cfile
.add_type_definition (instance_priv_struct
);
205 string macro
= "((%sPrivate *) (((char *) o) + _%s_object_offset))".printf (d
.get_cname (), d
.get_lower_case_cname ());
206 cfile
.add_type_member_declaration (new
CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (d
.get_upper_case_cname (null)), macro
));
208 var cdecl
= new
CCodeDeclaration ("intptr_t");
209 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_%s_object_offset".printf (d
.get_lower_case_cname ()), new
CCodeConstant ("0")));
210 cdecl
.modifiers
= CCodeModifiers
.STATIC
;
211 cfile
.add_type_member_declaration (cdecl
);
213 cdecl
= new
CCodeDeclaration ("intptr_t");
214 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_%s_type_offset".printf (d
.get_lower_case_cname ()), new
CCodeConstant ("0")));
215 cdecl
.modifiers
= CCodeModifiers
.STATIC
;
216 cfile
.add_type_member_declaration (cdecl
);
218 cfile
.add_function (generate_new_function (d
, cfile
));
219 cfile
.add_function (generate_invoke_function (d
, cfile
));