1 //=============================================================================
5 * Creates code for AMH operations.
7 * @author Darrell Brunsch <brunsch@cs.wustl.edu>
9 //=============================================================================
11 #include "operation.h"
12 #include "ace/SString.h"
14 be_visitor_amh_operation_ss::be_visitor_amh_operation_ss (
15 be_visitor_context
*ctx
)
16 : be_visitor_operation (ctx
)
20 be_visitor_amh_operation_ss::~be_visitor_amh_operation_ss ()
25 be_visitor_amh_operation_ss::visit_operation (be_operation
*node
)
27 // If there is an argument of type "native", return immediately.
28 if (node
->has_native ())
33 /// These are not for the server side.
34 if (node
->is_sendc_ami ())
39 TAO_OutStream
*os
= this->ctx_
->stream ();
40 this->ctx_
->node (node
);
42 if (this->generate_shared_prologue (node
, os
, "") == -1)
48 node
->count_arguments_with_direction (AST_Argument::dir_IN
49 | AST_Argument::dir_INOUT
);
51 if (argument_count
!= 0)
53 // Declare variables for arguments.
54 be_visitor_context vardecl_ctx
= *this->ctx_
;
55 vardecl_ctx
.state (TAO_CodeGen::TAO_OPERATION_ARG_DECL_SS
);
57 be_visitor_args_vardecl_ss
vardecl_visitor (&vardecl_ctx
);
58 vardecl_visitor
.set_fixed_direction (AST_Argument::dir_IN
);
60 for (UTL_ScopeActiveIterator
si (node
, UTL_Scope::IK_decls
);
64 be_argument
*argument
=
65 dynamic_cast<be_argument
*> (si
.item ());
67 if (argument
== nullptr
68 || argument
->direction () == AST_Argument::dir_OUT
)
73 if (vardecl_visitor
.visit_argument (argument
) == -1)
75 ACE_ERROR_RETURN ((LM_ERROR
,
76 "(%N:%l) be_visitor_amh_operation_ss::"
78 "codegen for return var decl failed\n"),
84 << "TAO_InputCDR & _tao_in ="
85 << " *_tao_server_request.incoming ();" << be_nl_2
86 << "if (!(" << be_idt
<< be_idt
;
88 // Marshal each in and inout argument.
89 be_visitor_context marshal_ctx
= *this->ctx_
;
90 marshal_ctx
.state (TAO_CodeGen::TAO_OPERATION_ARG_DEMARSHAL_SS
);
91 marshal_ctx
.sub_state (TAO_CodeGen::TAO_CDR_INPUT
);
93 be_visitor_args_marshal_ss
marshal_visitor (&marshal_ctx
);
94 marshal_visitor
.set_fixed_direction (AST_Argument::dir_IN
);
97 for (UTL_ScopeActiveIterator
sj (node
, UTL_Scope::IK_decls
);
101 be_argument
*argument
=
102 dynamic_cast<be_argument
*> (sj
.item ());
104 if (argument
== nullptr
105 || argument
->direction () == AST_Argument::dir_OUT
)
115 if (marshal_visitor
.visit_argument (argument
) == -1)
117 ACE_ERROR_RETURN ((LM_ERROR
,
118 "(%N:%l) be_visitor_operation_ss::"
120 "codegen for demarshal failed\n"),
125 *os
<< be_uidt_nl
<< "))" << be_nl
;
127 // If marshaling fails, raise exception.
128 if (this->gen_raise_exception ("::CORBA::MARSHAL",
131 ACE_ERROR_RETURN ((LM_ERROR
,
132 "(%N:%l) gen_raise_exception failed\n"),
139 if (this->generate_shared_section (node
, os
) == -1)
145 be_visitor_context
ctx (*this->ctx_
);
146 ctx
.state (TAO_CodeGen::TAO_OPERATION_ARG_UPCALL_SS
);
147 be_visitor_args_upcall_ss
visitor (&ctx
);
148 visitor
.set_fixed_direction (AST_Argument::dir_IN
);
150 for (UTL_ScopeActiveIterator
i (node
, UTL_Scope::IK_decls
);
153 be_argument
*argument
=
154 dynamic_cast<be_argument
*> (i
.item ());
158 if (argument
== nullptr
159 || argument
->direction () == AST_Argument::dir_OUT
)
166 if (argument
->accept (&visitor
) == -1)
168 ACE_ERROR_RETURN ((LM_ERROR
,
169 "(%N:%l) be_visitor_amh_operation_ss::"
171 "codegen for upcall args failed\n"),
177 if (this->generate_shared_epilogue (os
) == -1)
186 be_visitor_amh_operation_ss::visit_attribute (be_attribute
*node
)
188 TAO_OutStream
*os
= this->ctx_
->stream ();
189 this->ctx_
->node (node
);
191 if (this->generate_shared_prologue (node
, os
, "_get_") == -1)
196 if (this->generate_shared_section (node
, os
) == -1)
201 if (this->generate_shared_epilogue (os
) == -1)
206 if (node
->readonly ())
211 if (this->generate_shared_prologue (node
, os
, "_set_") == -1)
216 be_argument
the_argument (AST_Argument::dir_IN
,
223 be_visitor_context
ctx (*this->ctx_
);
224 be_visitor_args_vardecl_ss
vardecl_visitor (&ctx
);
226 status
= vardecl_visitor
.visit_argument (&the_argument
);
230 the_argument
.destroy ();
236 << "TAO_InputCDR & _tao_in ="
237 << " *_tao_server_request.incoming ();"
239 << "if (!(" << be_idt
<< be_idt
;
242 be_visitor_context
ctx (*this->ctx_
);
243 ctx
.state (TAO_CodeGen::TAO_OPERATION_ARG_DEMARSHAL_SS
);
244 ctx
.sub_state (TAO_CodeGen::TAO_CDR_INPUT
);
245 be_visitor_args_marshal_ss
marshal_visitor (&ctx
);
247 status
= marshal_visitor
.visit_argument (&the_argument
);
251 the_argument
.destroy ();
256 *os
<< be_uidt_nl
<< "))" << be_nl
259 // If marshaling fails, raise exception.
260 status
= this->gen_raise_exception ("::CORBA::MARSHAL",
264 ACE_ERROR_RETURN ((LM_ERROR
,
265 "(%N:%l) gen_raise_exception failed\n"),
270 << "}" << be_uidt_nl
;
272 if (-1 == this->generate_shared_section (node
, os
))
280 be_visitor_args_upcall_ss
upcall_visitor (this->ctx_
);
281 status
= upcall_visitor
.visit_argument (&the_argument
);
282 the_argument
.destroy ();
290 if (-1 == this->generate_shared_epilogue (os
))
299 be_visitor_amh_operation_ss::generate_shared_prologue (be_decl
*node
,
301 const char *skel_prefix
)
303 TAO_INSERT_COMMENT (os
);
305 // We need the interface node in which this operation was defined. However,
306 // if this operation node was an attribute node in disguise, we get this
307 // information from the context
309 dynamic_cast<be_interface
*> (node
->defined_in ());
313 ACE_ERROR_RETURN ((LM_ERROR
,
314 "(%N:%l) be_visitor_operation_ss::"
316 "bad interface scope\n"),
322 intf
->compute_full_name ("AMH_", "", buf
);
323 ACE_CString
amh_skel_name ("POA_");
324 amh_skel_name
+= buf
;
325 // buf was allocated by ACE_OS::strdup, so we need to use free instead
330 *os
<< "void" << be_nl
331 << amh_skel_name
.c_str () << "::"
332 << skel_prefix
<< this->ctx_
->port_prefix ().c_str ()
333 << node
->local_name ()
334 << "_skel (" << be_idt
<< be_idt_nl
335 << "TAO_ServerRequest & _tao_server_request," << be_nl
336 << "TAO::Portable_Server::Servant_Upcall * /* context */," << be_nl
337 << "TAO_ServantBase * _tao_servant)" << be_uidt
340 // Generate the actual code for the skeleton.
342 *os
<< "{" << be_idt_nl
;
344 // Get the right object implementation.
345 *os
<< amh_skel_name
.c_str () << " * const _tao_impl =" << be_idt_nl
346 << "dynamic_cast<" << amh_skel_name
.c_str () << " *> ("
347 << "_tao_servant" << ");" << be_uidt_nl
;
349 *os
<< "if (!_tao_impl)" << be_idt_nl
350 << "throw ::CORBA::INTERNAL ();" << be_uidt_nl
;
356 be_visitor_amh_operation_ss::generate_shared_section (be_decl
*node
,
360 dynamic_cast<be_interface
*> (node
->defined_in ());
364 ACE_ERROR_RETURN ((LM_ERROR
,
365 "(%N:%l) generate_shared_section - "
366 "bad interface scope\n"),
370 // Create the response handler
372 intf
->compute_full_name ("TAO_AMH_", "ResponseHandler", buf
);
373 ACE_CString
response_handler_implementation_name ("POA_");
374 response_handler_implementation_name
+= buf
;
375 // buf was allocated by ACE_OS::strdup, so we need to use free instead
381 << "TAO_ORB_Core *orb_core =" << be_idt_nl
382 << "_tao_server_request.orb ()->orb_core ();" << be_uidt_nl
<< be_nl
383 << "TAO_AMH_BUFFER_ALLOCATOR* amh_allocator =" << be_idt_nl
384 << "orb_core->lane_resources ().amh_response_handler_allocator ();"
385 << be_uidt_nl
<< be_nl
386 << "TAO::TAO_Buffer_Allocator<" << be_idt
<< be_idt_nl
387 << response_handler_implementation_name
.c_str () << "," << be_nl
388 << "TAO_AMH_BUFFER_ALLOCATOR" << be_uidt_nl
389 << "> buffer_allocator (amh_allocator);"
390 << be_uidt_nl
<< be_nl
391 << response_handler_implementation_name
.c_str ()
392 << "_ptr _tao_rh_ptr = "
394 << "buffer_allocator.allocate();"
395 << be_uidt_nl
<< be_nl
396 << "if (!_tao_rh_ptr) " << be_idt_nl
<< "throw ::CORBA::NO_MEMORY ();"
400 *os
<< be_nl
<< "_tao_rh_ptr->init (_tao_server_request, amh_allocator);" << be_nl
403 *os
<< "ACE_Utils::Auto_Functor <"
404 << response_handler_implementation_name
.c_str ()
405 << ", TAO::ARH_Refcount_Functor> safe_rd_(_tao_rh_ptr);"
409 *os
<< be_nl
<< "_tao_impl->"
410 << node
->local_name () << " (" << be_idt
<< be_idt_nl
411 << "safe_rd_.get ()";
417 be_visitor_amh_operation_ss::generate_shared_epilogue (TAO_OutStream
*os
)
419 *os
<< be_uidt_nl
<< ");"
420 << be_uidt
<< be_uidt_nl