Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / TAO / TAO_IDL / be / be_visitor_operation / amh_ss.cpp
blobded343c68364e70fd6c40400e7fbdfed1b7e864c
1 //=============================================================================
2 /**
3 * @file amh_ss.cpp
5 * Creates code for AMH operations.
7 * @author Darrell Brunsch <brunsch@cs.wustl.edu>
8 */
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 ()
24 int
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 ())
30 return 0;
33 /// These are not for the server side.
34 if (node->is_sendc_ami ())
36 return 0;
39 TAO_OutStream *os = this->ctx_->stream ();
40 this->ctx_->node (node);
42 if (this->generate_shared_prologue (node, os, "") == -1)
44 return -1;
47 int argument_count =
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);
61 !si.is_done ();
62 si.next ())
64 be_argument *argument =
65 dynamic_cast<be_argument*> (si.item ());
67 if (argument == nullptr
68 || argument->direction () == AST_Argument::dir_OUT)
70 continue;
73 if (vardecl_visitor.visit_argument (argument) == -1)
75 ACE_ERROR_RETURN ((LM_ERROR,
76 "(%N:%l) be_visitor_amh_operation_ss::"
77 "visit_operation - "
78 "codegen for return var decl failed\n"),
79 -1);
83 *os << be_nl
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);
95 int i = 0;
97 for (UTL_ScopeActiveIterator sj (node, UTL_Scope::IK_decls);
98 !sj.is_done ();
99 sj.next ())
101 be_argument *argument =
102 dynamic_cast<be_argument*> (sj.item ());
104 if (argument == nullptr
105 || argument->direction () == AST_Argument::dir_OUT)
107 continue;
110 if (i++ != 0)
112 *os << " &&";
115 if (marshal_visitor.visit_argument (argument) == -1)
117 ACE_ERROR_RETURN ((LM_ERROR,
118 "(%N:%l) be_visitor_operation_ss::"
119 "visit_operation - "
120 "codegen for demarshal failed\n"),
121 -1);
125 *os << be_uidt_nl << "))" << be_nl;
127 // If marshaling fails, raise exception.
128 if (this->gen_raise_exception ("::CORBA::MARSHAL",
129 "") == -1)
131 ACE_ERROR_RETURN ((LM_ERROR,
132 "(%N:%l) gen_raise_exception failed\n"),
133 -1);
136 *os << be_uidt_nl;
139 if (this->generate_shared_section (node, os) == -1)
141 return -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);
151 !i.is_done ();)
153 be_argument *argument =
154 dynamic_cast<be_argument*> (i.item ());
156 i.next ();
158 if (argument == nullptr
159 || argument->direction () == AST_Argument::dir_OUT)
161 continue;
164 *os << ",";
166 if (argument->accept (&visitor) == -1)
168 ACE_ERROR_RETURN ((LM_ERROR,
169 "(%N:%l) be_visitor_amh_operation_ss::"
170 "visit_operation - "
171 "codegen for upcall args failed\n"),
172 -1);
177 if (this->generate_shared_epilogue (os) == -1)
179 return -1;
182 return 0;
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)
193 return -1;
196 if (this->generate_shared_section (node, os) == -1)
198 return -1;
201 if (this->generate_shared_epilogue (os) == -1)
203 return -1;
206 if (node->readonly ())
208 return 0;
211 if (this->generate_shared_prologue (node, os, "_set_") == -1)
213 return -1;
216 be_argument the_argument (AST_Argument::dir_IN,
217 node->field_type (),
218 node->name ());
220 int status = 0;
223 be_visitor_context ctx (*this->ctx_);
224 be_visitor_args_vardecl_ss vardecl_visitor (&ctx);
226 status = vardecl_visitor.visit_argument (&the_argument);
228 if (-1 == status)
230 the_argument.destroy ();
231 return -1;
235 *os << be_nl
236 << "TAO_InputCDR & _tao_in ="
237 << " *_tao_server_request.incoming ();"
238 << be_nl_2
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);
249 if (-1 == status)
251 the_argument.destroy ();
252 return -1;
256 *os << be_uidt_nl << "))" << be_nl
257 << "{" << be_idt_nl;
259 // If marshaling fails, raise exception.
260 status = this->gen_raise_exception ("::CORBA::MARSHAL",
261 "");
262 if (-1 == status)
264 ACE_ERROR_RETURN ((LM_ERROR,
265 "(%N:%l) gen_raise_exception failed\n"),
266 -1);
269 *os << be_uidt_nl
270 << "}" << be_uidt_nl;
272 if (-1 == this->generate_shared_section (node, os))
274 return -1;
277 *os << ",";
280 be_visitor_args_upcall_ss upcall_visitor (this->ctx_);
281 status = upcall_visitor.visit_argument (&the_argument);
282 the_argument.destroy ();
284 if (-1 == status)
286 return -1;
290 if (-1 == this->generate_shared_epilogue (os))
292 return -1;
295 return 0;
299 be_visitor_amh_operation_ss::generate_shared_prologue (be_decl *node,
300 TAO_OutStream *os,
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
308 be_interface *intf =
309 dynamic_cast<be_interface*> (node->defined_in ());
311 if (intf == nullptr)
313 ACE_ERROR_RETURN ((LM_ERROR,
314 "(%N:%l) be_visitor_operation_ss::"
315 "visit_operation - "
316 "bad interface scope\n"),
317 -1);
321 char *buf;
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
326 // of delete.
327 ACE_OS::free (buf);
328 buf = nullptr;
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
338 << be_uidt_nl;
340 // Generate the actual code for the skeleton.
341 // last argument
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;
352 return 0;
356 be_visitor_amh_operation_ss::generate_shared_section (be_decl *node,
357 TAO_OutStream *os)
359 be_interface *intf =
360 dynamic_cast<be_interface*> (node->defined_in ());
362 if (!intf)
364 ACE_ERROR_RETURN ((LM_ERROR,
365 "(%N:%l) generate_shared_section - "
366 "bad interface scope\n"),
367 -1);
370 // Create the response handler
371 char *buf;
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
376 // of delete.
377 ACE_OS::free (buf);
378 buf = nullptr;
380 *os << be_nl
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 = "
393 << be_idt_nl
394 << "buffer_allocator.allocate();"
395 << be_uidt_nl << be_nl
396 << "if (!_tao_rh_ptr) " << be_idt_nl << "throw ::CORBA::NO_MEMORY ();"
397 << be_uidt_nl;
399 // Initialize amh rh
400 *os << be_nl << "_tao_rh_ptr->init (_tao_server_request, amh_allocator);" << be_nl
401 << 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);"
406 << be_nl;
408 // Make the upcall.
409 *os << be_nl << "_tao_impl->"
410 << node->local_name () << " (" << be_idt << be_idt_nl
411 << "safe_rd_.get ()";
413 return 0;
417 be_visitor_amh_operation_ss::generate_shared_epilogue (TAO_OutStream *os)
419 *os << be_uidt_nl << ");"
420 << be_uidt << be_uidt_nl
421 << "}";
423 return 0;