BadVPN – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /** |
2 | * @file call2.c |
||
3 | * @author Ambroz Bizjak <ambrop7@gmail.com> |
||
4 | * |
||
5 | * @section LICENSE |
||
6 | * |
||
7 | * Redistribution and use in source and binary forms, with or without |
||
8 | * modification, are permitted provided that the following conditions are met: |
||
9 | * 1. Redistributions of source code must retain the above copyright |
||
10 | * notice, this list of conditions and the following disclaimer. |
||
11 | * 2. Redistributions in binary form must reproduce the above copyright |
||
12 | * notice, this list of conditions and the following disclaimer in the |
||
13 | * documentation and/or other materials provided with the distribution. |
||
14 | * 3. Neither the name of the author nor the |
||
15 | * names of its contributors may be used to endorse or promote products |
||
16 | * derived from this software without specific prior written permission. |
||
17 | * |
||
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
||
19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
||
20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
||
21 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
||
22 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||
23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||
24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||
25 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||
27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||
28 | * |
||
29 | * @section DESCRIPTION |
||
30 | * |
||
31 | * |
||
32 | * Synopsis: |
||
33 | * call(string template, list args) |
||
34 | * |
||
35 | * Description: |
||
36 | * Calls a process template. The 'template' argument is the name of the process |
||
37 | * template to call, and the 'list' argument is a list of arguments for the |
||
38 | * process template. Calling a process template is roughly equivalent to placing |
||
39 | * the statements within that template into the place of call(), except for the |
||
40 | * points presented next. The 'template' argument can be a special value "<none>", |
||
41 | * which makes call() a no-op. |
||
42 | * |
||
43 | * The process created from the called template will be able to access the arguments |
||
44 | * that were given in the 'args' argument to call() via the '_argN' predefined\ |
||
45 | * objects (e.g. _arg0 for the first argumens), and also via '_args' for the entire |
||
46 | * argument list. |
||
47 | * |
||
48 | * The called process also will be able to access objects within the calling |
||
49 | * process as seen by the call() statement. However such any access needs to happen |
||
50 | * via a special '_caller' predefined object. For example, if there is a statement |
||
51 | * 'var("a") x;' somewhere above the call() statement, the called process can access |
||
52 | * it as '_caller.x'. |
||
53 | * |
||
54 | * Note that call() preserves backtracking semantics, i.e. when a statement within |
||
55 | * the called process goes down after having gone up, the behaviour really is as |
||
56 | * if the call() statement was replaced with the statements in the called template, |
||
57 | * (disregarding variable resolution). |
||
58 | * |
||
59 | * Because the template name is an argument, call() can be used for branching. |
||
60 | * For example, if we have an object 'x' with the value "true" or "false", a |
||
61 | * branch can be performed by defining two process templates, 'branch_true' |
||
62 | * and 'branch_false', and branching with the following code: |
||
63 | * |
||
64 | * concat("branch_", x) name; |
||
65 | * call(name, {}); |
||
66 | * |
||
67 | * |
||
68 | * Synopsis: |
||
69 | * call_with_caller_target(string template, list args, string caller_target) |
||
70 | * |
||
71 | * Description: |
||
72 | * Like call(), except that the target of the '_caller' predefined object is |
||
73 | * specified by the 'caller_target' argument. This is indented to be used from |
||
74 | * generic code for user-specified callbacks, allowing the user to easily refer to |
||
75 | * his own objects from inside the callback. |
||
76 | * |
||
77 | * The 'caller_target' must be a non-empty string referring to an actual object; |
||
78 | * there is no choice of 'caller_target' that would make call_with_caller_target() |
||
79 | * equivalent to call(). |
||
80 | * |
||
81 | * |
||
82 | * Synopsis: |
||
83 | * embcall(string template) |
||
84 | * |
||
85 | * Description: |
||
86 | * Like call, but makes its own scope directly available in the called |
||
87 | * template process, instead of via _caller. Also, doesn not provide any |
||
88 | * arguments to the template process. |
||
89 | * |
||
90 | * |
||
91 | * Synopsis: |
||
92 | * inline_code(string template) |
||
93 | * inline_code::call(list args) |
||
94 | * |
||
95 | * Description: |
||
96 | * The inline_code() acts as a proxy object for calling the specified template. |
||
97 | * The inline_code::call calls the template of the corresponding inline_code |
||
98 | * instance, in a manner similar to a simple "call". The called template will |
||
99 | * have access to the following resources: |
||
100 | * - The arguments will be available in the usual fashion. |
||
101 | * - The scope of the inline_code::call instance will be available as "_caller". |
||
102 | * - The scope of the inline_code instance will be directly available. |
||
103 | * - The scope of the inline_code instance will also be available as "_scope". |
||
104 | * This is useful to access shadowed names, e.g. "_caller" and the arguments |
||
105 | * stuff (_argN, _args). |
||
106 | */ |
||
107 | |||
108 | #include <stdlib.h> |
||
109 | #include <string.h> |
||
110 | |||
111 | #include <misc/debug.h> |
||
112 | #include <misc/offset.h> |
||
113 | #include <structure/LinkedList0.h> |
||
114 | #include <ncd/extra/NCDFastNames.h> |
||
115 | |||
116 | #include <ncd/module_common.h> |
||
117 | |||
118 | #include <generated/blog_channel_ncd_call2.h> |
||
119 | |||
120 | #define STATE_WORKING 1 |
||
121 | #define STATE_UP 2 |
||
122 | #define STATE_WAITING 3 |
||
123 | #define STATE_TERMINATING 4 |
||
124 | #define STATE_NONE 5 |
||
125 | |||
126 | struct instance; |
||
127 | |||
128 | typedef void (*call_extra_free_cb) (struct instance *o); |
||
129 | |||
130 | struct instance { |
||
131 | NCDModuleInst *i; |
||
132 | call_extra_free_cb extra_free_cb; |
||
133 | NCDModuleProcess process; |
||
134 | int state; |
||
135 | }; |
||
136 | |||
137 | struct instance_with_caller_target { |
||
138 | struct instance base; |
||
139 | NCDFastNames names; |
||
140 | }; |
||
141 | |||
142 | struct inline_code { |
||
143 | NCDModuleInst *i; |
||
144 | NCDValRef template_name; |
||
145 | LinkedList0 calls_list; |
||
146 | }; |
||
147 | |||
148 | struct inline_code_call { |
||
149 | struct instance base; |
||
150 | struct inline_code *ic; |
||
151 | LinkedList0Node ic_node; |
||
152 | }; |
||
153 | |||
154 | static void process_handler_event (NCDModuleProcess *process, int event); |
||
155 | static int process_func_getspecialobj_embed (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object); |
||
156 | static int process_func_getspecialobj_noembed (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object); |
||
157 | static int process_func_getspecialobj_with_caller_target (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object); |
||
158 | static int caller_obj_func_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object); |
||
159 | static int caller_obj_func_getobj_with_caller_target (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object); |
||
160 | static void func_new_templ (void *vo, NCDModuleInst *i, NCDValRef template_name, NCDValRef args, NCDModuleProcess_func_getspecialobj func_getspecialobj, call_extra_free_cb extra_free_cb); |
||
161 | static void instance_free (struct instance *o); |
||
162 | static void call_with_caller_target_extra_free (struct instance *bo); |
||
163 | static void inline_code_extra_free (struct instance *bo); |
||
164 | static int inline_code_call_process_getspecialobj (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object); |
||
165 | static int inline_code_scope_obj_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object); |
||
166 | |||
167 | static void process_handler_event (NCDModuleProcess *process, int event) |
||
168 | { |
||
169 | struct instance *o = UPPER_OBJECT(process, struct instance, process); |
||
170 | |||
171 | switch (event) { |
||
172 | case NCDMODULEPROCESS_EVENT_UP: { |
||
173 | ASSERT(o->state == STATE_WORKING) |
||
174 | |||
175 | // signal up |
||
176 | NCDModuleInst_Backend_Up(o->i); |
||
177 | |||
178 | // set state up |
||
179 | o->state = STATE_UP; |
||
180 | } break; |
||
181 | |||
182 | case NCDMODULEPROCESS_EVENT_DOWN: { |
||
183 | ASSERT(o->state == STATE_UP) |
||
184 | |||
185 | // signal down |
||
186 | NCDModuleInst_Backend_Down(o->i); |
||
187 | |||
188 | // set state waiting |
||
189 | o->state = STATE_WAITING; |
||
190 | } break; |
||
191 | |||
192 | case NCDMODULEPROCESS_EVENT_TERMINATED: { |
||
193 | ASSERT(o->state == STATE_TERMINATING) |
||
194 | |||
195 | // die finally |
||
196 | instance_free(o); |
||
197 | return; |
||
198 | } break; |
||
199 | |||
200 | default: ASSERT(0); |
||
201 | } |
||
202 | } |
||
203 | |||
204 | static int process_func_getspecialobj_embed (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object) |
||
205 | { |
||
206 | struct instance *o = UPPER_OBJECT(process, struct instance, process); |
||
207 | |||
208 | return NCDModuleInst_Backend_GetObj(o->i, name, out_object); |
||
209 | } |
||
210 | |||
211 | static int process_func_getspecialobj_noembed (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object) |
||
212 | { |
||
213 | struct instance *o = UPPER_OBJECT(process, struct instance, process); |
||
214 | |||
215 | if (name == NCD_STRING_CALLER) { |
||
216 | *out_object = NCDObject_Build(-1, o, NCDObject_no_getvar, caller_obj_func_getobj); |
||
217 | return 1; |
||
218 | } |
||
219 | |||
220 | return 0; |
||
221 | } |
||
222 | |||
223 | static int process_func_getspecialobj_with_caller_target (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object) |
||
224 | { |
||
225 | struct instance *o = UPPER_OBJECT(process, struct instance, process); |
||
226 | |||
227 | if (name == NCD_STRING_CALLER) { |
||
228 | *out_object = NCDObject_Build(-1, o, NCDObject_no_getvar, caller_obj_func_getobj_with_caller_target); |
||
229 | return 1; |
||
230 | } |
||
231 | |||
232 | return 0; |
||
233 | } |
||
234 | |||
235 | static int caller_obj_func_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object) |
||
236 | { |
||
237 | struct instance *o = NCDObject_DataPtr(obj); |
||
238 | |||
239 | return NCDModuleInst_Backend_GetObj(o->i, name, out_object); |
||
240 | } |
||
241 | |||
242 | static int caller_obj_func_getobj_with_caller_target (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object) |
||
243 | { |
||
244 | struct instance_with_caller_target *o_ch = NCDObject_DataPtr(obj); |
||
245 | |||
246 | NCD_string_id_t *names = NCDFastNames_GetNames(&o_ch->names); |
||
247 | |||
248 | NCDObject object; |
||
249 | if (!NCDModuleInst_Backend_GetObj(o_ch->base.i, names[0], &object)) { |
||
250 | return 0; |
||
251 | } |
||
252 | |||
253 | NCDObject obj2; |
||
254 | if (!NCDObject_ResolveObjExprCompact(&object, names + 1, NCDFastNames_GetNumNames(&o_ch->names) - 1, &obj2)) { |
||
255 | return 0; |
||
256 | } |
||
257 | |||
258 | if (name == NCD_STRING_EMPTY) { |
||
259 | *out_object = obj2; |
||
260 | return 1; |
||
261 | } |
||
262 | |||
263 | return NCDObject_GetObj(&obj2, name, out_object); |
||
264 | } |
||
265 | |||
266 | static void func_new_templ (void *vo, NCDModuleInst *i, NCDValRef template_name, NCDValRef args, NCDModuleProcess_func_getspecialobj func_getspecialobj, call_extra_free_cb extra_free_cb) |
||
267 | { |
||
268 | ASSERT(NCDVal_IsInvalid(template_name) || NCDVal_IsString(template_name)) |
||
269 | ASSERT(NCDVal_IsInvalid(args) || NCDVal_IsList(args)) |
||
270 | ASSERT(func_getspecialobj) |
||
271 | |||
272 | struct instance *o = vo; |
||
273 | o->i = i; |
||
274 | o->extra_free_cb = extra_free_cb; |
||
275 | |||
276 | if (NCDVal_IsInvalid(template_name) || ncd_is_none(template_name)) { |
||
277 | // signal up |
||
278 | NCDModuleInst_Backend_Up(o->i); |
||
279 | |||
280 | // set state none |
||
281 | o->state = STATE_NONE; |
||
282 | } else { |
||
283 | // create process |
||
284 | if (!NCDModuleProcess_InitValue(&o->process, o->i, template_name, args, process_handler_event)) { |
||
285 | ModuleLog(o->i, BLOG_ERROR, "NCDModuleProcess_Init failed"); |
||
286 | goto fail1; |
||
287 | } |
||
288 | |||
289 | // set special functions |
||
290 | NCDModuleProcess_SetSpecialFuncs(&o->process, func_getspecialobj); |
||
291 | |||
292 | // set state working |
||
293 | o->state = STATE_WORKING; |
||
294 | } |
||
295 | |||
296 | return; |
||
297 | |||
298 | fail1: |
||
299 | if (o->extra_free_cb) { |
||
300 | o->extra_free_cb(o); |
||
301 | } |
||
302 | NCDModuleInst_Backend_DeadError(i); |
||
303 | } |
||
304 | |||
305 | static void instance_free (struct instance *o) |
||
306 | { |
||
307 | if (o->extra_free_cb) { |
||
308 | o->extra_free_cb(o); |
||
309 | } |
||
310 | |||
311 | // free process |
||
312 | if (o->state != STATE_NONE) { |
||
313 | NCDModuleProcess_Free(&o->process); |
||
314 | } |
||
315 | |||
316 | NCDModuleInst_Backend_Dead(o->i); |
||
317 | } |
||
318 | |||
319 | static void func_new_call (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) |
||
320 | { |
||
321 | NCDValRef template_arg; |
||
322 | NCDValRef args_arg; |
||
323 | if (!NCDVal_ListRead(params->args, 2, &template_arg, &args_arg)) { |
||
324 | ModuleLog(i, BLOG_ERROR, "wrong arity"); |
||
325 | goto fail0; |
||
326 | } |
||
327 | if (!NCDVal_IsString(template_arg) || !NCDVal_IsList(args_arg)) { |
||
328 | ModuleLog(i, BLOG_ERROR, "wrong type"); |
||
329 | goto fail0; |
||
330 | } |
||
331 | |||
332 | func_new_templ(vo, i, template_arg, args_arg, process_func_getspecialobj_noembed, NULL); |
||
333 | return; |
||
334 | |||
335 | fail0: |
||
336 | NCDModuleInst_Backend_DeadError(i); |
||
337 | } |
||
338 | |||
339 | static void func_new_call_with_caller_target (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) |
||
340 | { |
||
341 | NCDValRef template_arg; |
||
342 | NCDValRef args_arg; |
||
343 | NCDValRef caller_target_arg; |
||
344 | if (!NCDVal_ListRead(params->args, 3, &template_arg, &args_arg, &caller_target_arg)) { |
||
345 | ModuleLog(i, BLOG_ERROR, "wrong arity"); |
||
346 | goto fail0; |
||
347 | } |
||
348 | if (!NCDVal_IsString(template_arg) || !NCDVal_IsList(args_arg) || !NCDVal_IsString(caller_target_arg)) { |
||
349 | ModuleLog(i, BLOG_ERROR, "wrong type"); |
||
350 | goto fail0; |
||
351 | } |
||
352 | |||
353 | struct instance_with_caller_target *o = vo; |
||
354 | |||
355 | int res = NCDFastNames_Init(&o->names, i->params->iparams->string_index, NCDVal_StringMemRef(caller_target_arg)); |
||
356 | if (!res) { |
||
357 | ModuleLog(i, BLOG_ERROR, "NCDFastNames_Init failed"); |
||
358 | goto fail0; |
||
359 | } |
||
360 | |||
361 | func_new_templ(vo, i, template_arg, args_arg, process_func_getspecialobj_with_caller_target, call_with_caller_target_extra_free); |
||
362 | return; |
||
363 | |||
364 | fail0: |
||
365 | NCDModuleInst_Backend_DeadError(i); |
||
366 | } |
||
367 | |||
368 | static void call_with_caller_target_extra_free (struct instance *bo) |
||
369 | { |
||
370 | struct instance_with_caller_target *o = (void *)bo; |
||
371 | |||
372 | NCDFastNames_Free(&o->names); |
||
373 | } |
||
374 | |||
375 | static void func_new_embcall (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) |
||
376 | { |
||
377 | NCDValRef template_arg; |
||
378 | if (!NCDVal_ListRead(params->args, 1, &template_arg)) { |
||
379 | ModuleLog(i, BLOG_ERROR, "wrong arity"); |
||
380 | goto fail0; |
||
381 | } |
||
382 | if (!NCDVal_IsString(template_arg)) { |
||
383 | ModuleLog(i, BLOG_ERROR, "wrong type"); |
||
384 | goto fail0; |
||
385 | } |
||
386 | |||
387 | func_new_templ(vo, i, template_arg, NCDVal_NewInvalid(), process_func_getspecialobj_embed, NULL); |
||
388 | return; |
||
389 | |||
390 | fail0: |
||
391 | NCDModuleInst_Backend_DeadError(i); |
||
392 | } |
||
393 | |||
394 | static void func_die (void *vo) |
||
395 | { |
||
396 | struct instance *o = vo; |
||
397 | ASSERT(o->state != STATE_TERMINATING) |
||
398 | |||
399 | // if none, die now |
||
400 | if (o->state == STATE_NONE) { |
||
401 | instance_free(o); |
||
402 | return; |
||
403 | } |
||
404 | |||
405 | // request process to terminate |
||
406 | NCDModuleProcess_Terminate(&o->process); |
||
407 | |||
408 | // set state terminating |
||
409 | o->state = STATE_TERMINATING; |
||
410 | } |
||
411 | |||
412 | static void func_clean (void *vo) |
||
413 | { |
||
414 | struct instance *o = vo; |
||
415 | if (o->state != STATE_WAITING) { |
||
416 | return; |
||
417 | } |
||
418 | |||
419 | // allow process to continue |
||
420 | NCDModuleProcess_Continue(&o->process); |
||
421 | |||
422 | // set state working |
||
423 | o->state = STATE_WORKING; |
||
424 | } |
||
425 | |||
426 | static int func_getobj (void *vo, NCD_string_id_t name, NCDObject *out_object) |
||
427 | { |
||
428 | struct instance *o = vo; |
||
429 | |||
430 | if (o->state == STATE_NONE) { |
||
431 | return 0; |
||
432 | } |
||
433 | |||
434 | return NCDModuleProcess_GetObj(&o->process, name, out_object); |
||
435 | } |
||
436 | |||
437 | static void inline_code_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) |
||
438 | { |
||
439 | NCDValRef template_arg; |
||
440 | if (!NCDVal_ListRead(params->args, 1, &template_arg)) { |
||
441 | ModuleLog(i, BLOG_ERROR, "wrong arity"); |
||
442 | goto fail0; |
||
443 | } |
||
444 | if (!NCDVal_IsString(template_arg)) { |
||
445 | ModuleLog(i, BLOG_ERROR, "wrong type"); |
||
446 | goto fail0; |
||
447 | } |
||
448 | |||
449 | struct inline_code *o = vo; |
||
450 | o->i = i; |
||
451 | o->template_name = template_arg; |
||
452 | LinkedList0_Init(&o->calls_list); |
||
453 | |||
454 | NCDModuleInst_Backend_Up(i); |
||
455 | return; |
||
456 | |||
457 | fail0: |
||
458 | NCDModuleInst_Backend_DeadError(i); |
||
459 | } |
||
460 | |||
461 | static void inline_code_die (void *vo) |
||
462 | { |
||
463 | struct inline_code *o = vo; |
||
464 | |||
465 | for (LinkedList0Node *ln = LinkedList0_GetFirst(&o->calls_list); ln; ln = LinkedList0Node_Next(ln)) { |
||
466 | struct inline_code_call *call = UPPER_OBJECT(ln, struct inline_code_call, ic_node); |
||
467 | ASSERT(call->ic == o) |
||
468 | call->ic = NULL; |
||
469 | } |
||
470 | |||
471 | NCDModuleInst_Backend_Dead(o->i); |
||
472 | } |
||
473 | |||
474 | static void inline_code_call_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) |
||
475 | { |
||
476 | struct inline_code_call *o = vo; |
||
477 | |||
478 | o->ic = NCDModuleInst_Backend_GetUser((NCDModuleInst *)params->method_user); |
||
479 | LinkedList0_Prepend(&o->ic->calls_list, &o->ic_node); |
||
480 | |||
481 | func_new_templ(vo, i, o->ic->template_name, params->args, inline_code_call_process_getspecialobj, inline_code_extra_free); |
||
482 | } |
||
483 | |||
484 | static void inline_code_extra_free (struct instance *bo) |
||
485 | { |
||
486 | struct inline_code_call *o = (void *)bo; |
||
487 | |||
488 | if (o->ic) { |
||
489 | LinkedList0_Remove(&o->ic->calls_list, &o->ic_node); |
||
490 | } |
||
491 | } |
||
492 | |||
493 | static int inline_code_call_process_getspecialobj (NCDModuleProcess *process, NCD_string_id_t name, NCDObject *out_object) |
||
494 | { |
||
495 | struct inline_code_call *o = UPPER_OBJECT(process, struct inline_code_call, base.process); |
||
496 | |||
497 | if (name == NCD_STRING_CALLER) { |
||
498 | *out_object = NCDObject_Build(-1, o, NCDObject_no_getvar, caller_obj_func_getobj); |
||
499 | return 1; |
||
500 | } |
||
501 | |||
502 | if (!o->ic) { |
||
503 | ModuleLog(o->base.i, BLOG_ERROR, "inline_code object is gone"); |
||
504 | return 0; |
||
505 | } |
||
506 | |||
507 | if (name == NCD_STRING_SCOPE) { |
||
508 | *out_object = NCDObject_Build(-1, o->ic, NCDObject_no_getvar, inline_code_scope_obj_getobj); |
||
509 | return 1; |
||
510 | } |
||
511 | |||
512 | return NCDModuleInst_Backend_GetObj(o->ic->i, name, out_object); |
||
513 | } |
||
514 | |||
515 | static int inline_code_scope_obj_getobj (const NCDObject *obj, NCD_string_id_t name, NCDObject *out_object) |
||
516 | { |
||
517 | struct inline_code *ic = NCDObject_DataPtr(obj); |
||
518 | |||
519 | return NCDModuleInst_Backend_GetObj(ic->i, name, out_object); |
||
520 | } |
||
521 | |||
522 | static struct NCDModule modules[] = { |
||
523 | { |
||
524 | .type = "call", |
||
525 | .func_new2 = func_new_call, |
||
526 | .func_die = func_die, |
||
527 | .func_clean = func_clean, |
||
528 | .func_getobj = func_getobj, |
||
529 | .flags = NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN, |
||
530 | .alloc_size = sizeof(struct instance) |
||
531 | }, { |
||
532 | .type = "call_with_caller_target", |
||
533 | .func_new2 = func_new_call_with_caller_target, |
||
534 | .func_die = func_die, |
||
535 | .func_clean = func_clean, |
||
536 | .func_getobj = func_getobj, |
||
537 | .flags = NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN, |
||
538 | .alloc_size = sizeof(struct instance_with_caller_target) |
||
539 | }, { |
||
540 | .type = "embcall", |
||
541 | .func_new2 = func_new_embcall, |
||
542 | .func_die = func_die, |
||
543 | .func_clean = func_clean, |
||
544 | .func_getobj = func_getobj, |
||
545 | .flags = NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN, |
||
546 | .alloc_size = sizeof(struct instance) |
||
547 | }, { |
||
548 | .type = "inline_code", |
||
549 | .func_new2 = inline_code_new, |
||
550 | .func_die = inline_code_die, |
||
551 | .alloc_size = sizeof(struct inline_code) |
||
552 | }, { |
||
553 | .type = "inline_code::call", |
||
554 | .func_new2 = inline_code_call_new, |
||
555 | .func_die = func_die, |
||
556 | .func_clean = func_clean, |
||
557 | .func_getobj = func_getobj, |
||
558 | .flags = NCDMODULE_FLAG_CAN_RESOLVE_WHEN_DOWN, |
||
559 | .alloc_size = sizeof(struct inline_code_call) |
||
560 | }, { |
||
561 | .type = NULL |
||
562 | } |
||
563 | }; |
||
564 | |||
565 | const struct NCDModuleGroup ncdmodule_call2 = { |
||
566 | .modules = modules |
||
567 | }; |