1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 1999-2016. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20%% 21 22 23-module(ic_jbe). 24 25 26-export([do_gen/3, gen/3, emit_type_function/4]). 27 28 29 30-include("icforms.hrl"). 31-include("ic.hrl"). 32-include("ic_debug.hrl"). 33-include_lib("stdlib/include/erl_compile.hrl"). 34 35 36 37%%------------------------------------------------------------ 38%% 39%% Entry point 40%% 41%%------------------------------------------------------------ 42 43do_gen(G, _File, Form) -> 44 gen(G, [], Form). 45 46 47%%------------------------------------------------------------ 48%% 49%% Generate the client side C stubs. 50%% 51%% Each module is generated to a separate file. 52%% 53%% Each function needs to generate a function head and 54%% a body. IDL parameters must be converted into C parameters. 55%% 56%%------------------------------------------------------------ 57 58gen(G, N, [X|Xs]) when is_record(X, preproc) -> 59 NewG = handle_preproc(G, N, X#preproc.cat, X), 60 gen(NewG, N, Xs); 61 62gen(G, N, [X|Xs]) when is_record(X, module) -> 63 gen_module(G, N, X), 64 gen(G, N, Xs); 65 66gen(G, N, [X|Xs]) when is_record(X, interface) -> 67 gen_interface(G, N, X), 68 gen(G, N, Xs); 69 70gen(G, N, [X|Xs]) when is_record(X, const) -> 71 ic_constant_java:gen(G, N, X), 72 gen(G, N, Xs); 73 74gen(G, N, [X|Xs]) when is_record(X, op) -> 75 gen(G, N, Xs); 76 77gen(G, N, [X|Xs]) when is_record(X, attr) -> 78 gen(G, N, Xs); 79 80gen(G, N, [X|Xs]) when is_record(X, except) -> 81 gen_exception(G, N, X), 82 gen(G, N, Xs); 83 84gen(G, N, [X|Xs]) when is_record(X, enum) -> 85 ic_enum_java:gen(G, N, X), 86 gen(G, N, Xs); 87 88gen(G, N, [X|Xs]) when is_record(X, struct) -> 89 ic_struct_java:gen(G, N, X), 90 gen(G, N, Xs); 91 92gen(G, N, [X|Xs]) when is_record(X, union) -> 93 ic_union_java:gen(G, N, X), 94 gen(G, N, Xs); 95 96gen(G, N, [X|Xs]) when is_record(X, typedef) -> 97 gen_typedef(G, N, X), 98 gen(G, N, Xs); 99 100gen(G, N, [X|Xs]) when is_record(X, member) -> 101 %%?PRINTDEBUG2("gen member: ~p\n",[ic_forms:get_type(X)]), 102 gen_member(G, N, X), 103 gen(G, N, Xs); 104 105gen(G, N, [X|Xs]) when is_record(X, case_dcl) -> 106 %%?PRINTDEBUG2("gen case decl: ~p\n",[ic_forms:get_type(X)]), 107 gen(G, N, [ic_forms:get_type(X)]), 108 gen(G, N, Xs); 109 110gen(G, N, [_|Xs]) -> 111 gen(G, N, Xs); 112 113gen(_G, _N, []) -> 114 ok. 115 116 117%%%-------------------------------------------- 118%%% 119%%% Just generates the directory to host 120%%% the module files 121%%% 122%%%-------------------------------------------- 123 124gen_module(G, N, X) -> 125 case ic_genobj:do_gen(G) of 126 127 true -> %% Generate & register 128 N1 = [ic_forms:get_id2(X) | N], 129 %% Create directory 130 ic_file:createJavaDirectory(G, N1), 131 gen(G, N1, ic_forms:get_body(X)); 132 133 false -> %% Register only 134 N1 = [ic_forms:get_id2(X) | N], 135 reg(G, N1, ic_forms:get_body(X)) 136 end. 137 138reg(G, N, [X|_Xs]) when is_record(X, module) -> 139 reg(G, [ic_forms:get_id2(X) | N], ic_forms:get_body(X)); 140 141reg(G, N, [X|_Xs]) when is_record(X, interface) -> 142 reg(G, [ic_forms:get_id2(X) | N], ic_forms:get_body(X)); 143 144reg(G, N, [X|Xs]) when is_record(X, typedef) -> 145 Name = ic_util:to_dot(G,[ic_forms:get_java_id(X) | N]), 146 case X#typedef.type of 147 {scoped_id,_,_,_} -> 148 {FullScopedName, _, _, _} = 149 ic_symtab:get_full_scoped_name(G, N, X#typedef.type), 150 Type = ic_code:get_basetype(G, ic_util:to_dot(G,FullScopedName)), 151 ic_code:insert_typedef(G, Name, Type); 152 _ -> 153 ok 154 end, 155 reg(G, N, Xs); 156 157reg(G, N, [_|Xs]) -> 158 reg(G, N, Xs); 159 160reg(_G, _N, []) -> 161 ok. 162 163 164 165 166%%%---------------------------------------------- 167%%% 168%%% Generates the interface code 169%%% 170%%%---------------------------------------------- 171 172gen_interface(G, N, X) -> 173 case ic_genobj:do_gen(G) of 174 true -> 175 G1 = ic_file:javaInterfaceFilePush(G, N, X), 176 177 %% Generate Interface file 178 InterfaceFd = ic_genobj:interfacefiled(G1), 179 emit_interface(G1, N, X, InterfaceFd), 180 181 %% Generate Helper file 182 HelperFd = ic_genobj:helperfiled(G1), 183 emit_helper(G1, N, X, HelperFd), 184 185 %% Generate Holder file 186 HolderFd = ic_genobj:holderfiled(G1), 187 emit_holder(G1, N, X, HolderFd), 188 189 %% Generate Stub file 190 StubFd = ic_genobj:stubfiled(G1), 191 emit_stub(G1,N,X,StubFd), %<--------------------------------------------------- 1 192 193 %% Generate Skeleton file 194 SkelFd = ic_genobj:skelfiled(G1), 195 emit_skel(G1, N, X, SkelFd), 196 197 ic_file:javaInterfaceFilePop(G1); 198 false -> 199 ok 200 end. 201 202 203 204 205%%%-------------------------------------------- 206%%% 207%%% Typedef redirection 208%%% 209%%%-------------------------------------------- 210 211gen_typedef(G, N, X) -> 212 Name = ic_util:to_dot(G,[ic_forms:get_java_id(X) | N]), 213 case X#typedef.type of 214 {scoped_id,_,_,_} -> 215 {FullScopedName, _, _, _} = 216 ic_symtab:get_full_scoped_name(G, N, X#typedef.type), 217 Type = ic_code:get_basetype(G, ic_util:to_dot(G,FullScopedName)), 218 ic_code:insert_typedef(G, Name, Type); 219 _ -> 220 ok 221 end, 222 gen_typedef_1(G, N, X, ic_forms:get_body(X)). 223 224gen_typedef_1(G, N, X, Type) when is_record(Type, sequence) -> 225 ic_sequence_java:gen(G, N, Type, ic_forms:get_java_id(X)); 226gen_typedef_1(G, N, X, Type) when is_record(Type, array) -> 227 ic_array_java:gen(G, N, X, Type); 228gen_typedef_1(G, N, X, _Type) -> 229 gen_typedef_2(G, N, X, X#typedef.id), 230 ok. 231 232gen_typedef_2(G, N, X, Type) when is_record(Type, array) -> 233 gen_typedef_1(G, N, X, Type); 234gen_typedef_2(G, N, X, Type) when is_list(Type) -> 235 case Type of 236 [] -> 237 ok; 238 _ -> 239 gen_typedef_2(G, N, X, hd(Type)), 240 gen_typedef_2(G, N, X, tl(Type)) 241 end; 242%gen_typedef_2(G, N, X, Type) -> %% Generating Helpers for typedef 243% %% Stoped due to compatibility problems 244% %% with erl_genserv backend 245% case ic_java_type:isBasicType(G,N,X#typedef.type) of 246% true -> 247% ok; 248% false -> 249% case ic_forms:get_type_code(G,N,X#typedef.type) of 250% {'tk_struct', _, _, _} -> 251% ic_struct_java:gen(G, N, X); 252% {'tk_sequence',_,_} -> 253% ic_sequence_java:gen(G, N, X, ic_forms:get_java_id(X)), 254% ok; 255% _ -> 256% ok 257% end 258% end; 259gen_typedef_2(_G, _N, _X, _Type) -> 260 ok. 261 262 263 264%%%-------------------------------------------- 265%%% 266%%% Member redirection 267%%% 268%%%-------------------------------------------- 269 270gen_member(G, N, X) -> 271 gen_member_1(G, N, X, [X#member.type]), 272 gen_member_2(G, N, X, X#member.id). 273 274 275gen_member_1(_G, _N, _X, []) -> 276 ok; 277 278gen_member_1(G, N, X, [T|Ts]) when is_record(T, sequence) -> 279 ic_sequence_java:gen(G, N, T, ic_forms:get_java_id(X)), 280 gen_member_1(G, N, X, Ts); 281 282gen_member_1(G, N, X, [T|Ts]) -> 283 gen(G,N,[T]), 284 gen_member_1(G,N,X,Ts). 285 286 287gen_member_2(_G, _N, _X, []) -> 288 ok; 289 290gen_member_2(G, N, X, [T|Ts]) when is_record(T, array) -> %% BUG ! 291 ic_array_java:gen(G, N, X, T), 292 gen_member_2(G, N, X, Ts); 293 294gen_member_2(G, N, X, [_T|Ts]) -> 295 gen_member_2(G, N, X, Ts). 296 297 298 299gen_exception(_G, N, X) -> 300 io:format("Warning : Exceptions not supported for java mapping, ~p ignored\n", 301 [ic_util:to_colon([ic_forms:get_java_id(X)|N])]), 302 ok. 303 304 305 306%%%----------------------------------------------------- 307%%% 308%%% Interface file generation 309%%% 310%%%----------------------------------------------------- 311 312emit_interface(G, N, X, Fd) -> 313 Interface = ic_forms:get_java_id(X), %% Java Interface Name 314 IFCName = ic_forms:get_id2(X), %% Internal Interface Name 315 316 ic_codegen:emit(Fd, "public interface ~s {\n\n",[Interface]), 317 Body = ic_forms:get_body(X), 318 319 %% Generate type declarations inside interface 320 gen(G, [IFCName |N], Body), 321 322 lists:foreach(fun({_Name, Body1}) -> 323 emit_interface_prototypes(G, [IFCName|N], Body1, Fd) end, 324 [{x, Body} | X#interface.inherit_body]), 325 326 ic_codegen:emit(Fd, "}\n\n"). 327 328 329emit_interface_prototypes(G, N, [X |Xs], Fd) when is_record(X, op) -> 330 331 {_, ArgNames, TypeList} = extract_info(G, N, X), 332 {R, ParameterTypes, _} = TypeList, 333 334 OpName = ic_forms:get_java_id(X), 335 RT = ic_java_type:getParamType(G,N,R,ret), 336 PL = ic_util:mk_list(gen_par_list(G, N, X, ParameterTypes,ArgNames)), 337 338 ic_codegen:emit(Fd, "/*\n"), 339 ic_codegen:emit(Fd, " * Operation ~p interface functions \n", [ic_util:to_colon([OpName|N])]), 340 ic_codegen:emit(Fd, " */\n\n"), 341 342 ic_codegen:emit(Fd, "~s ~s(~s)\n",[RT, OpName, PL]), 343 ic_codegen:emit(Fd, " throws java.lang.Exception;\n\n\n"), 344 345 emit_interface_prototypes(G, N, Xs, Fd); 346emit_interface_prototypes(G, N, [X |Xs], Fd) when is_record(X, attr) -> 347 ic_attribute_java:emit_attribute_prototype(G, N, X, Fd), 348 emit_interface_prototypes(G, N, Xs, Fd); 349emit_interface_prototypes(G, N, [_X|Xs], Fd) -> 350 emit_interface_prototypes(G, N, Xs, Fd); 351emit_interface_prototypes(_G, _N, [], _Fd) -> ok. 352 353 354 355 356%%%----------------------------------------------------- 357%%% 358%%% Holder file generation 359%%% 360%%%----------------------------------------------------- 361 362emit_holder(_G, N, X, Fd) -> 363 InterfaceName = ic_forms:get_java_id(X), 364 FullInterfaceName = ic_util:to_dot([InterfaceName|N]), 365 366 ic_codegen:emit(Fd, "public final class ~sHolder {\n\n",[InterfaceName]), 367 368 ic_codegen:emit(Fd, " // Instance variable\n"), 369 ic_codegen:emit(Fd, " public ~s value;\n\n",[FullInterfaceName]), 370 371 ic_codegen:emit(Fd, " // Constructors\n"), 372 ic_codegen:emit(Fd, " public ~sHolder() {\n",[InterfaceName]), 373 ic_codegen:emit(Fd, " this(null);\n"), 374 ic_codegen:emit(Fd, " }\n\n"), 375 376 ic_codegen:emit(Fd, " public ~sHolder(~s _arg) {\n",[InterfaceName, FullInterfaceName]), 377 ic_codegen:emit(Fd, " value = _arg;\n"), 378 ic_codegen:emit(Fd, " }\n\n"), 379 380 ic_codegen:emit(Fd, " public void _marshal() {\n"), 381 ic_codegen:emit(Fd, " }\n\n"), 382 383 ic_codegen:emit(Fd, " public void _unmarshal() {\n"), 384 ic_codegen:emit(Fd, " }\n\n"), 385 386 ic_codegen:emit(Fd, "}\n\n"). 387 388 389 390 391%%%----------------------------------------------------- 392%%% 393%%% Helper file generation 394%%% 395%%%----------------------------------------------------- 396emit_helper(G, N, X, Fd) -> 397 InterfaceName = ic_forms:get_java_id(X), 398 FullInterfaceName = ic_util:to_dot([InterfaceName|N]), 399 400 ic_codegen:emit(Fd, "public final class ~sHelper {\n\n",[InterfaceName]), 401 402 ic_codegen:emit(Fd, " // Constructor\n"), 403 ic_codegen:emit(Fd, " public ~sHelper() {\n",[InterfaceName]), 404 ic_codegen:emit(Fd, " }\n\n"), 405 406 ic_codegen:emit(Fd, " public static void _marshal() {\n"), 407 ic_codegen:emit(Fd, " // Writing the object to the message\n"), 408 ic_codegen:emit(Fd, " }\n\n"), 409 410 ic_codegen:emit(Fd, " public static ~s _unmarshal() {\n",[FullInterfaceName]), 411 ic_codegen:emit(Fd, " // Reading the object from the message\n"), 412 ic_codegen:emit(Fd, " return null;\n"), 413 ic_codegen:emit(Fd, " }\n\n"), 414 415 ic_codegen:emit(Fd, " public static java.lang.String id() {\n"), 416 ic_codegen:emit(Fd, " return ~p;\n",[ictk:get_IR_ID(G, N, X)]), 417 ic_codegen:emit(Fd, " }\n\n"), 418 419 ic_codegen:emit(Fd, "}\n\n"). 420 421 422 423 424%%%----------------------------------------------------- 425%%% 426%%% Stub file generation 427%%% 428%%%----------------------------------------------------- 429 430emit_stub(G, N, X, Fd) -> 431 InterfaceName = ic_forms:get_java_id(X), %% Java Interface Name 432 IFCName = ic_forms:get_id2(X), %% Internal Interface Name 433 434 FullInterfaceName = ic_util:to_dot([InterfaceName|N]), 435 Body = ic_forms:get_body(X), 436 437 ic_codegen:emit(Fd, "public class _~sStub implements ~s {\n\n", 438 [InterfaceName,FullInterfaceName]), 439 440 ic_codegen:emit(Fd, " // Client data\n"), 441 ic_codegen:emit(Fd, " public ~sEnvironment _env;\n\n",[?ICPACKAGE]), 442 443 ic_codegen:emit(Fd, " // Constructors\n"), 444 ic_codegen:emit(Fd, " public _~sStub(~sOtpSelf _self,\n",[InterfaceName,?ERLANGPACKAGE]), 445 ic_codegen:emit(Fd, " ~sOtpPeer _peer,\n",[?ERLANGPACKAGE]), 446 ic_codegen:emit(Fd, " java.lang.Object _server) throws java.lang.Exception {\n\n"), 447 448 ic_codegen:emit(Fd, " _env =\n"), 449 ic_codegen:emit(Fd, " new ~sEnvironment(_self, _peer, _server);\n",[?ICPACKAGE]), 450 ic_codegen:emit(Fd, " _env.connect();\n"), 451 ic_codegen:emit(Fd, " }\n\n"), 452 453 ic_codegen:emit(Fd, " public _~sStub(java.lang.String _selfN,\n",[InterfaceName]), 454 ic_codegen:emit(Fd, " java.lang.String _peerN,\n"), 455 ic_codegen:emit(Fd, " java.lang.String _cookie,\n"), 456 ic_codegen:emit(Fd, " java.lang.Object _server) throws java.lang.Exception {\n\n"), 457 ic_codegen:emit(Fd, " _env =\n"), 458 ic_codegen:emit(Fd, " new ~sEnvironment(_selfN, _peerN, _cookie, _server);\n",[?ICPACKAGE]), 459 ic_codegen:emit(Fd, " _env.connect();\n"), 460 ic_codegen:emit(Fd, " }\n\n"), 461 462 ic_codegen:emit(Fd, " public _~sStub(~sOtpConnection _connection,\n",[InterfaceName, ?ERLANGPACKAGE]), 463 ic_codegen:emit(Fd, " java.lang.Object _server) throws java.lang.Exception {\n\n"), 464 ic_codegen:emit(Fd, " _env =\n"), 465 ic_codegen:emit(Fd, " new ~sEnvironment(_connection, _server);\n",[?ICPACKAGE]), 466 ic_codegen:emit(Fd, " _env.connect();\n"), 467 ic_codegen:emit(Fd, " }\n\n"), 468 469 emit_message_reference_extraction(Fd), 470 471 emit_servers_object_access(Fd), 472 473 emit_client_connection_close(Fd), 474 475 emit_client_connection_reconnect(Fd), 476 477 emit_client_destroy(Fd), 478 479 lists:foreach(fun({_Name, Body1}) -> 480 emit_op_implementation(G, [IFCName|N], Body1, Fd) end, 481 [{x, Body} | X#interface.inherit_body]), 482 483 ic_codegen:emit(Fd, "}\n\n"). 484 485 486emit_op_implementation(G, N, [X |Xs], Fd) when is_record(X, op) -> 487 488 WireOpName = ic_forms:get_id2(X), 489 OpName = ic_forms:get_java_id(WireOpName), 490 {_, ArgNames, TypeList} = extract_info(G, N, X), 491 {R, ParamTypes, _} = TypeList, 492 493 RT = ic_java_type:getParamType(G,N,R,ret), 494 PL = ic_util:mk_list(gen_par_list(G, N, X, ParamTypes, ArgNames)), 495 CMCPL = ic_util:mk_list(gen_client_marshal_call_par_list(ArgNames)), 496 497 ic_codegen:emit(Fd, " // Operation ~p implementation\n", [ic_util:to_colon([WireOpName|N])]), 498 ic_codegen:emit(Fd, " public ~s ~s(~s)\n", [RT, OpName, PL]), 499 ic_codegen:emit(Fd, " throws java.lang.Exception {\n\n"), 500 501 %% Function marshal call 502 ic_codegen:emit(Fd, " // Calling the marshal function\n"), 503 504 case CMCPL of 505 "" -> 506 ic_codegen:emit(Fd, " _~s_marshal(_env);\n\n",[OpName]); 507 _ -> 508 ic_codegen:emit(Fd, " _~s_marshal(_env, ~s);\n\n",[OpName, CMCPL]) 509 end, 510 511 %% Sending call 512 ic_codegen:emit(Fd, " // Message send\n"), 513 ic_codegen:emit(Fd, " _env.send();\n\n"), 514 515 case ic_forms:is_oneway(X) of 516 true -> 517 ok; 518 false -> 519 %% Receiving return values 520 ic_codegen:emit(Fd, " // Message receive\n"), 521 ic_codegen:emit(Fd, " _env.receive();\n\n"), 522 523 %% Function unmarshal call 524 case RT of 525 "void" -> 526 case ic_util:mk_list(gen_client_unmarshal_call_par_list(ArgNames)) of 527 "" -> 528 ic_codegen:emit(Fd, " // Calling the unmarshal function\n"), 529 ic_codegen:emit(Fd, " _~s_unmarshal(_env);\n", 530 [OpName]); 531 UMCPL -> 532 ic_codegen:emit(Fd, " // Calling the unmarshal function\n"), 533 ic_codegen:emit(Fd, " _~s_unmarshal(_env, ~s);\n", 534 [OpName,UMCPL]) 535 end; 536 _ -> 537 ic_codegen:emit(Fd, " // Calling the unmarshal function\n"), 538 case ic_util:mk_list(gen_client_unmarshal_call_par_list(ArgNames)) of 539 "" -> 540 ic_codegen:emit(Fd, " return _~s_unmarshal(_env);\n", 541 [OpName]); 542 UMCPL -> 543 ic_codegen:emit(Fd, " return _~s_unmarshal(_env, ~s);\n", 544 [OpName,UMCPL]) 545 end 546 end 547 end, 548 ic_codegen:emit(Fd, " }\n\n"), 549 550 %% Marshalling 551 emit_op_marshal(G, N, X, Fd), 552 553 %% UnMarshalling 554 emit_op_unmarshal(G, N, X, Fd), 555 ic_codegen:emit(Fd, "\n"), 556 557 emit_op_implementation(G, N, Xs, Fd); 558emit_op_implementation(G, N, [X |Xs], Fd) when is_record(X, attr) -> 559 ic_attribute_java:emit_attribute_stub_code(G, N, X, Fd), 560 emit_op_implementation(G, N, Xs, Fd); 561emit_op_implementation(G, N, [_X|Xs], Fd) -> 562 emit_op_implementation(G, N, Xs, Fd); 563emit_op_implementation(_G, _N, [], _Fd) -> ok. 564 565 566 567 568 569%%--------------------------------------- 570%% 571%% Marshal operation generation 572%% 573%%--------------------------------------- 574 575emit_op_marshal(G, N, X, Fd) -> 576 WireOpName = ic_forms:get_id2(X), 577 OpName = ic_forms:get_java_id(WireOpName), 578 {_, ArgNames, TypeList} = extract_info(G, N, X), 579 {_R, ParamTypes, _} = TypeList, 580 581 PL = ic_util:mk_list(gen_marshal_par_list(G, N, X, ParamTypes, ArgNames)), 582 583 ic_codegen:emit(Fd, " // Marshal operation for ~p\n", [OpName]), 584 case PL of 585 "" -> 586 ic_codegen:emit(Fd, " public static void _~s_marshal(~sEnvironment __env)\n", 587 [OpName, ?ICPACKAGE]), 588 ic_codegen:emit(Fd, " throws java.lang.Exception {\n\n"); 589 _ -> 590 ic_codegen:emit(Fd, " public static void _~s_marshal(~sEnvironment __env, ~s)\n", 591 [OpName, ?ICPACKAGE, PL]), 592 ic_codegen:emit(Fd, " throws java.lang.Exception {\n\n") 593 end, 594 %% Message encoding 595 emit_op_encode(G, N, X, OpName, WireOpName, ParamTypes, ArgNames, Fd), 596 597 ic_codegen:emit(Fd, " }\n\n"). 598 599 600emit_op_encode(G, N, X, _OpN, WOpN, ParamTypes, ArgNames, Fd) -> 601 602 OpCallName = case ic_options:get_opt(G, scoped_op_calls) of 603 true -> 604 ic_util:to_undersc([WOpN|N]); 605 false -> 606 WOpN 607 end, 608 609 SendParamNr = count_client_send(ArgNames), 610 611 ic_codegen:emit(Fd, " ~sOtpOutputStream __os = __env.getOs();\n\n", 612 [?ERLANGPACKAGE]), 613 614 case ic_forms:is_oneway(X) of 615 true -> 616 %% Initiating call tuple 617 ic_codegen:emit(Fd, " // Message header assembly\n"), 618 ic_codegen:emit(Fd, " __os.reset();\n"), 619 ic_codegen:emit(Fd, " __os.write_tuple_head(2);\n"), 620 ic_codegen:emit(Fd, " __os.write_atom(\"$gen_cast\");\n\n"); 621 false -> 622 %% Initiating call tuple 623 ic_codegen:emit(Fd, " // Message header assembly\n"), 624 ic_codegen:emit(Fd, " __os.reset();\n"), 625 ic_codegen:emit(Fd, " __os.write_tuple_head(3);\n"), 626 ic_codegen:emit(Fd, " __os.write_atom(\"$gen_call\");\n\n"), 627 628 %% Initiating call identity tuple 629 ic_codegen:emit(Fd, " // Message identity part creation\n"), 630 ic_codegen:emit(Fd, " __os.write_tuple_head(2);\n"), 631 ic_codegen:emit(Fd, " __env.write_client_pid();\n"), 632 ic_codegen:emit(Fd, " __env.write_client_ref();\n\n") 633 end, 634 635 %% Operation part initializations 636 case SendParamNr > 0 of 637 true -> 638 ic_codegen:emit(Fd, " // Operation attribute creation\n"), 639 ic_codegen:emit(Fd, " __os.write_tuple_head(~p);\n", [SendParamNr+1]), 640 ic_codegen:emit(Fd, " __os.write_atom(~p);\n", [OpCallName]), 641 emit_op_encode_loop(G, N, X, ParamTypes, ArgNames, 1, Fd); 642 false -> %% No in/inout paramaters 643 ic_codegen:emit(Fd, " __os.write_atom(~p);\n", [OpCallName]) 644 end. 645 646 647 648emit_op_encode_loop(_,_,_,_,[],_,_Fd) -> 649 ok; 650emit_op_encode_loop(G, N, X, [_Type|Types],[{out, _Arg}|Args], Counter, Fd) -> 651 emit_op_encode_loop(G, N, X, Types, Args, Counter, Fd); 652emit_op_encode_loop(G, N, X, [Type|Types], [{inout, Arg}|Args], Counter, Fd) -> 653 case ic_java_type:isBasicType(G, N, Type) of 654 true -> 655 ic_codegen:emit(Fd, " __os~s(~s.value);\n", 656 [ic_java_type:marshalFun(G, N, X, Type),Arg]); 657 false -> 658 ic_codegen:emit(Fd, " ~s(__os, ~s.value);\n", 659 [ic_java_type:marshalFun(G, N, X, Type),Arg]) 660 end, 661 emit_op_encode_loop(G, N, X, Types, Args, Counter+1, Fd); 662emit_op_encode_loop(G, N, X, [Type|Types], [{in, Arg}|Args], Counter, Fd) -> 663 case ic_java_type:isBasicType(G, N, Type) of 664 true -> 665 ic_codegen:emit(Fd, " __os~s(~s);\n", 666 [ic_java_type:marshalFun(G, N, X, Type),Arg]); 667 false -> 668 ic_codegen:emit(Fd, " ~s(__os, ~s);\n", 669 [ic_java_type:marshalFun(G, N, X, Type),Arg]) 670 end, 671 emit_op_encode_loop(G, N, X, Types, Args, Counter+1, Fd). 672 673 674 675 676 677 678%%------------------------------------- 679%% 680%% UnMarshal operation generation 681%% 682%%------------------------------------- 683 684emit_op_unmarshal(G, N, X, Fd) -> 685 case ic_forms:is_oneway(X) of 686 true -> 687 ok; 688 false -> 689 OpName = ic_forms:get_java_id(X), 690 {_, ArgNames, TypeList} = extract_info(G, N, X), 691 {R, ParamTypes, _} = TypeList, 692 693 RT = ic_java_type:getParamType(G,N,R,ret), 694 PL = ic_util:mk_list(gen_unmarshal_par_list(G, N, X, ParamTypes, ArgNames)), 695 696 case PL of 697 "" -> 698 case RT of 699 "void" -> 700 ic_codegen:emit(Fd, " // Unmarshal operation for ~p\n", [OpName]), 701 ic_codegen:emit(Fd, " public static void _~s_unmarshal(~sEnvironment __env)\n", 702 [OpName, ?ICPACKAGE]), 703 ic_codegen:emit(Fd, " throws java.lang.Exception {\n\n"), 704 ic_codegen:emit(Fd, " __env.getIs().read_atom();\n"), 705 ic_codegen:emit(Fd, " }\n\n"); 706 _ -> 707 ic_codegen:emit(Fd, " // Unmarshal operation for ~p\n", [OpName]), 708 ic_codegen:emit(Fd, " public static ~s _~s_unmarshal(~sEnvironment __env)\n", 709 [RT, OpName, ?ICPACKAGE]), 710 ic_codegen:emit(Fd, " throws java.lang.Exception {\n\n"), 711 712 ic_codegen:emit(Fd, " // Get input stream\n"), 713 ic_codegen:emit(Fd, " ~sOtpInputStream __is = __env.getIs();\n\n", 714 [?ERLANGPACKAGE]), 715 716 emit_op_decode(G, N, X, R, RT, ParamTypes, ArgNames, Fd), 717 ic_codegen:emit(Fd, " }\n\n") 718 end; 719 _ -> 720 ic_codegen:emit(Fd, " // Unmarshal operation for ~p\n", [OpName]), 721 ic_codegen:emit(Fd, " public static ~s _~s_unmarshal(~sEnvironment __env, ~s)\n", 722 [RT, OpName, ?ICPACKAGE, PL]), 723 ic_codegen:emit(Fd, " throws java.lang.Exception {\n\n"), 724 725 ic_codegen:emit(Fd, " // Get input stream\n"), 726 ic_codegen:emit(Fd, " ~sOtpInputStream __is = __env.getIs();\n\n", 727 [?ERLANGPACKAGE]), 728 729 emit_op_decode(G, N, X, R, RT, ParamTypes, ArgNames, Fd), 730 ic_codegen:emit(Fd, " }\n\n") 731 end 732 end. 733 734 735emit_op_decode(G, N, X, R, RT, ParamTypes, ArgNames, Fd) -> 736 ReceiveNr = count_client_receive(ArgNames), 737 738 case RT of 739 "void" -> 740 case ReceiveNr > 0 of 741 true -> 742 ic_codegen:emit(Fd, " // Extracting output values\n"), 743 ic_codegen:emit(Fd, " __is.read_tuple_head();\n"), 744 ic_codegen:emit(Fd, " __is.read_atom();\n"), 745 emit_op_decode_loop(G, N, X, ParamTypes, ArgNames, 1, Fd); 746 false -> 747 ic_codegen:emit(Fd, " __is.read_atom();\n") 748 end; 749 _ -> 750 case ReceiveNr > 0 of 751 true -> 752 ic_codegen:emit(Fd, " // Extracting return/output values\n"), 753 ic_codegen:emit(Fd, " __is.read_tuple_head();\n"), 754 case ic_java_type:isBasicType(G,N,R) of 755 true -> 756 ic_codegen:emit(Fd, " ~s _result = __is~s;\n", 757 [RT,ic_java_type:unMarshalFun(G, N, X, R)]); 758 false -> 759 ic_codegen:emit(Fd, " ~s _result = ~s.unmarshal(__is);\n", 760 [RT, ic_java_type:getUnmarshalType(G,N,X,R)]) 761 end, 762 emit_op_decode_loop(G, N, X, ParamTypes, ArgNames, 1, Fd), 763 764 ic_codegen:nl(Fd), 765 ic_codegen:emit(Fd, " return _result;\n"); 766 false -> 767 ic_codegen:emit(Fd, " // Extracting return value\n"), 768 case ic_java_type:isBasicType(G,N,R) of 769 true -> 770 ic_codegen:emit(Fd, " return __is~s;\n", 771 [ic_java_type:unMarshalFun(G, N, X, R)]); 772 false -> 773 ic_codegen:emit(Fd, " return ~s.unmarshal(__is);\n", 774 [ic_java_type:getUnmarshalType(G,N,X,R)]) 775 end 776 end 777 end. 778 779emit_op_decode_loop(_,_,_,_,[],_,_Fd) -> 780 ok; 781emit_op_decode_loop(G, N, X, [_Type|Types], [{in, _Arg}|Args], Counter, Fd) -> 782 emit_op_decode_loop(G, N, X, Types, Args, Counter, Fd); 783emit_op_decode_loop(G, N, X, [Type|Types], [{_, Arg}|Args], Counter, Fd) -> 784 case ic_java_type:isBasicType(G,N,Type) of 785 true -> 786 ic_codegen:emit(Fd, " ~s.value = __is~s;\n", 787 [Arg, 788 ic_java_type:unMarshalFun(G, N, X, Type)]); 789 false -> 790 ic_codegen:emit(Fd, " ~s.value = ~s.unmarshal(__is);\n", 791 [Arg, 792 ic_java_type:getUnmarshalType(G, N, X, Type)]) 793 end, 794 emit_op_decode_loop(G, N, X, Types, Args, Counter+1, Fd). 795 796 797 798emit_message_reference_extraction(Fd) -> 799 ic_codegen:emit(Fd, " // Returns call reference\n"), 800 ic_codegen:emit(Fd, " public ~sOtpErlangRef __getRef()\n", 801 [?ERLANGPACKAGE]), 802 ic_codegen:emit(Fd, " throws java.lang.Exception {\n"), 803 ic_codegen:emit(Fd, " return _env.received_ref();\n"), 804 ic_codegen:emit(Fd, " }\n\n"). 805 806emit_servers_object_access(Fd) -> 807 ic_codegen:emit(Fd, " // Returns the server\n"), 808 ic_codegen:emit(Fd, " public java.lang.Object __server() {\n"), 809 ic_codegen:emit(Fd, " return _env.server();\n"), 810 ic_codegen:emit(Fd, " }\n\n"). 811 812emit_client_connection_close(Fd) -> 813 ic_codegen:emit(Fd, " // Closes connection\n"), 814 ic_codegen:emit(Fd, " public void __disconnect() {\n"), 815 ic_codegen:emit(Fd, " _env.disconnect();\n"), 816 ic_codegen:emit(Fd, " }\n\n"). 817 818emit_client_connection_reconnect(Fd) -> 819 ic_codegen:emit(Fd, " // Reconnects client\n"), 820 ic_codegen:emit(Fd, " public void __reconnect()\n"), 821 ic_codegen:emit(Fd, " throws java.lang.Exception {\n"), 822 ic_codegen:emit(Fd, " _env.reconnect();\n"), 823 ic_codegen:emit(Fd, " }\n\n"). 824 825emit_client_destroy(Fd) -> 826 ic_codegen:emit(Fd, " // Destroy server\n"), 827 ic_codegen:emit(Fd, " public void __stop()\n"), 828 ic_codegen:emit(Fd, " throws java.lang.Exception {\n"), 829 ic_codegen:emit(Fd, " _env.client_stop_server();\n"), 830 ic_codegen:emit(Fd, " }\n\n"). 831 832 833 834%%%---------------------------------------------------- 835%%% 836%%% Generates the server code 837%%% 838%%%---------------------------------------------------- 839 840emit_skel(G, N, X, Fd) -> 841 InterfaceName = ic_forms:get_java_id(X), 842 FullInterfaceName = ic_util:to_dot([InterfaceName|N]), 843 844 ic_codegen:emit(Fd, "public abstract class _~sImplBase implements ~s {\n\n", 845 [InterfaceName,FullInterfaceName]), 846 847 ic_codegen:emit(Fd, " // Server data\n"), 848 ic_codegen:emit(Fd, " protected ~sEnvironment _env = null;\n\n",[?ICPACKAGE]), 849 850 ic_codegen:emit(Fd, " // Constructors\n"), 851 ic_codegen:emit(Fd, " public _~sImplBase() {\n",[InterfaceName]), 852 ic_codegen:emit(Fd, " }\n\n"), 853 854 emit_caller_pid(G, N, X, Fd), 855 856 %% Emit operation dictionary 857 emit_dictionary(G, N, X, Fd), 858 859 %% Emit server switch 860 emit_server_switch(G, N, X, Fd), 861 862 ic_codegen:emit(Fd, "}\n"). 863 864 865emit_server_switch(G, N, X, Fd) -> 866 867 IFCName = ic_forms:get_id2(X), %% Internal Interface Name 868 Body = ic_forms:get_body(X), 869 Counter = 0, 870 871 ic_codegen:emit(Fd, " // Operation invokation\n"), 872 ic_codegen:emit(Fd, " public ~sOtpOutputStream invoke(~sOtpInputStream _in)\n", 873 [?ERLANGPACKAGE,?ERLANGPACKAGE]), 874 ic_codegen:emit(Fd, " throws java.lang.Exception {\n\n"), 875 876 ic_codegen:emit(Fd, " // Create a new environment if needed\n"), 877 ic_codegen:emit(Fd, " if (_env == null)\n"), 878 ic_codegen:emit(Fd, " _env = new com.ericsson.otp.ic.Environment();\n\n"), 879 880 ic_codegen:emit(Fd, " // Unmarshal head\n"), 881 ic_codegen:emit(Fd, " _env.uHead(_in);\n\n"), 882 883 ic_codegen:emit(Fd, " // Switch over operation\n"), 884 ic_codegen:emit(Fd, " return __switch(_env);\n"), 885 886 ic_codegen:emit(Fd, " }\n\n"), 887 888 889 ic_codegen:emit(Fd, " // Operation switch\n"), 890 ic_codegen:emit(Fd, " public ~sOtpOutputStream __switch(~sEnvironment __env)\n", [?ERLANGPACKAGE,?ICPACKAGE]), 891 ic_codegen:emit(Fd, " throws java.lang.Exception {\n\n"), 892 893 ic_codegen:emit(Fd, " // Setup streams and operation label\n"), 894 ic_codegen:emit(Fd, " ~sOtpOutputStream __os = __env.getOs();\n",[?ERLANGPACKAGE]), 895 ic_codegen:emit(Fd, " __os.reset();\n"), 896 ic_codegen:emit(Fd, " int __label = __env.uLabel(__operations);\n\n"), 897 898 ic_codegen:emit(Fd, " // Switch over operation\n"), 899 ic_codegen:emit(Fd, " switch(__label) {\n\n"), 900 901 OpNr = emit_server_op_switch_loop(G, 902 [IFCName|N], 903 [{x, Body} | X#interface.inherit_body], 904 Counter, 905 Fd), 906 907 ic_codegen:emit(Fd, " case ~p: { // Standard stop operation\n\n",[OpNr]), 908 ic_codegen:emit(Fd, " __env.server_stop_server();\n\n"), 909 ic_codegen:emit(Fd, " } break;\n\n"), 910 911 ic_codegen:emit(Fd, " default: // It will never come down here \n"), 912 ic_codegen:emit(Fd, " throw new java.lang.Exception(\"BAD OPERATION\");\n\n", []), 913 914 ic_codegen:emit(Fd, " }\n\n"), 915 916 ic_codegen:emit(Fd, " if(__os.count() > 0)\n"), 917 ic_codegen:emit(Fd, " return __os;\n\n"), 918 919 ic_codegen:emit(Fd, " return null;\n"), 920 ic_codegen:emit(Fd, " }\n\n"). 921 922 923 924emit_server_op_switch_loop(_G, _N, [], C, _Fd) -> 925 C; 926emit_server_op_switch_loop(G, N, [{_,X}|Xs], C, Fd) -> 927 C1 = emit_server_op_switch(G, N, X, C, Fd), 928 emit_server_op_switch_loop(G, N, Xs, C1, Fd). 929 930 931emit_server_op_switch(G, N, [X|Xs], C, Fd) when is_record(X, op) -> 932 933 OpName = ic_forms:get_java_id(X), 934 935 ic_codegen:emit(Fd, " case ~p: { // Operation ~s\n\n",[C,ic_util:to_dot([OpName|N])]), 936 937 emit_invoke(G, N, X, Fd), 938 939 ic_codegen:emit(Fd, " } break;\n\n"), 940 941 emit_server_op_switch(G, N, Xs, C+1, Fd); 942emit_server_op_switch(G, N, [X |Xs], C, Fd) when is_record(X, attr) -> 943 C1 = ic_attribute_java:emit_attribute_switch_case(G,N,X,Fd,C), 944 emit_server_op_switch(G, N, Xs, C1, Fd); 945emit_server_op_switch(G, N, [_X|Xs], C, Fd) -> 946 emit_server_op_switch(G, N, Xs, C, Fd); 947emit_server_op_switch(_G, _N, [], C, _Fd) -> 948 C. 949 950 951emit_caller_pid(_G, _N, _X, Fd) -> 952 ic_codegen:emit(Fd, " // Extracts caller identity\n"), 953 ic_codegen:emit(Fd, " public ~sOtpErlangPid __getCallerPid() {\n", [?ERLANGPACKAGE]), 954 ic_codegen:emit(Fd, " return _env.getScaller();\n"), 955 ic_codegen:emit(Fd, " }\n\n"), 956 957 ic_codegen:emit(Fd, " public ~sOtpErlangPid __getCallerPid(~sEnvironment __env) {\n", 958 [?ERLANGPACKAGE, ?ICPACKAGE]), 959 ic_codegen:emit(Fd, " return __env.getScaller();\n"), 960 ic_codegen:emit(Fd, " }\n\n"), 961 962 ic_codegen:emit(Fd, " public boolean __isStopped() {\n"), 963 ic_codegen:emit(Fd, " return _env.isStopped();\n"), 964 ic_codegen:emit(Fd, " }\n\n"), 965 966 ic_codegen:emit(Fd, " public boolean __isStopped(~sEnvironment __env) {\n", 967 [?ICPACKAGE]), 968 ic_codegen:emit(Fd, " return __env.isStopped();\n"), 969 ic_codegen:emit(Fd, " }\n\n"). 970 971 972 973%% Creates an operation dictionary 974emit_dictionary(G, N, X, Fd) -> 975 976 Counter = 0, 977 Body = ic_forms:get_body(X), 978 979 ic_codegen:emit(Fd, " // Operation dictionary\n"), 980 ic_codegen:emit(Fd, " private static java.util.Dictionary __operations = new java.util.Hashtable();\n"), 981 ic_codegen:emit(Fd, " static {\n"), 982 983 emit_dictionary_loop(G, 984 [ic_forms:get_id2(X)|N], 985 [{x, Body} | X#interface.inherit_body], 986 Counter, 987 Fd), 988 989 ic_codegen:emit(Fd, " }\n\n"), 990 991 ic_codegen:emit(Fd, " // Operation dictionary access\n"), 992 ic_codegen:emit(Fd, " public static java.util.Dictionary __operations() {\n"), 993 ic_codegen:emit(Fd, " return __operations;\n"), 994 ic_codegen:emit(Fd, " }\n\n"). 995 996 997 998 999emit_dictionary_loop(_G, _N, [], C, Fd) -> 1000 ic_codegen:emit(Fd, " __operations.put(~p, new java.lang.Integer(~p));\n", 1001 ["stop",C]); 1002emit_dictionary_loop(G, N, [{_,X}|Xs], C, Fd) -> 1003 C1 = emit_dictionary(G, N, X, C, Fd), 1004 emit_dictionary_loop(G, N, Xs, C1, Fd). 1005 1006 1007emit_dictionary(G, N, [X|Xs], C, Fd) when is_record(X, op) -> 1008 1009 OpName = case ic_options:get_opt(G, scoped_op_calls) of 1010 true -> 1011 ic_util:to_undersc([ic_forms:get_id2(X)|N]); 1012 false -> 1013 ic_forms:get_id2(X) 1014 end, 1015 1016 ic_codegen:emit(Fd, " __operations.put(~p, new java.lang.Integer(~p));\n", 1017 [OpName,C]), 1018 emit_dictionary(G, N, Xs, C+1, Fd); 1019 1020emit_dictionary(G, N, [X |Xs], C, Fd) when is_record(X, attr) -> 1021 C1 = ic_attribute_java:emit_atrribute_on_dictionary(G, N, X, Fd, C), 1022 emit_dictionary(G, N, Xs, C1, Fd); 1023 1024emit_dictionary(G, N, [_X|Xs], C, Fd) -> 1025 emit_dictionary(G, N, Xs, C, Fd); 1026 1027emit_dictionary(_G, _N, [], C, _Fd) -> 1028 C. 1029 1030 1031 1032emit_invoke(G, N, X, Fd) -> 1033 1034 {_, ArgNames, TypeList} = extract_info(G, N, X), 1035 {R, ParamTypes, _} = TypeList, 1036 OpName = ic_forms:get_java_id(X), 1037 RT = ic_java_type:getParamType(G,N,R,ret), 1038 PL = ic_util:mk_list(gen_cb_arg_list(ArgNames)), 1039 OutParamNr = count_server_send(ArgNames), 1040 1041 case count_server_receive(ArgNames) of 1042 0 -> 1043 ok; 1044 _C -> 1045 ic_codegen:emit(Fd, " // Preparing input\n"), 1046 ic_codegen:emit(Fd, " ~sOtpInputStream __is = __env.getIs();\n", 1047 [?ERLANGPACKAGE]), 1048 emit_server_unmarshal_loop(G, N, X, ParamTypes, ArgNames, 1, Fd) 1049 end, 1050 1051 ic_codegen:emit(Fd, " // Calling implementation function\n"), 1052 case RT of 1053 "void" -> 1054 ic_codegen:emit(Fd, " this.~s(~s);\n\n", 1055 [OpName,PL]); 1056 _ -> 1057 ic_codegen:emit(Fd, " ~s _result = this.~s(~s);\n\n", 1058 [RT, OpName, PL]) 1059 end, 1060 1061 case ic_forms:is_oneway(X) of 1062 true -> 1063 ok; 1064 false -> 1065 ic_codegen:emit(Fd, " // Marshaling output\n"), 1066 ic_codegen:emit(Fd, " ~sOtpErlangRef __ref = __env.getSref();\n",[?ERLANGPACKAGE]), 1067 1068 case RT of 1069 "void" -> 1070 case OutParamNr > 0 of 1071 true -> 1072 ic_codegen:emit(Fd, " __os.write_tuple_head(2);\n"), 1073 ic_codegen:emit(Fd, " __os.write_ref(__ref.node(),__ref.ids(),__ref.creation()); // Call reference\n"), 1074 ic_codegen:emit(Fd, " __os.write_tuple_head(~p);\n",[OutParamNr+1]), 1075 ic_codegen:emit(Fd, " __os.write_atom(\"ok\");\n"), 1076 emit_server_marshal_loop(G, N, X, ParamTypes,ArgNames,1,Fd); 1077 false -> 1078 ic_codegen:emit(Fd, " __os.write_tuple_head(2);\n"), 1079 ic_codegen:emit(Fd, " __os.write_ref(__ref.node(),__ref.ids(),__ref.creation()); // Call reference\n"), 1080 ic_codegen:emit(Fd, " __os.write_atom(\"ok\");\n\n") 1081 end; 1082 _ -> 1083 case OutParamNr > 0 of 1084 true -> 1085 ic_codegen:emit(Fd, " __os.write_tuple_head(2);\n"), 1086 ic_codegen:emit(Fd, " __os.write_ref(__ref.node(),__ref.ids(),__ref.creation()); // Call reference\n"), 1087 ic_codegen:emit(Fd, " __os.write_tuple_head(~p);\n",[OutParamNr+1]), 1088 1089 case ic_java_type:isBasicType(G,N,R) of 1090 true -> 1091 ic_codegen:emit(Fd, " __os~s(_result); // Return value\n", 1092 [ic_java_type:marshalFun(G,N,X,R)]); 1093 false -> 1094 ic_codegen:emit(Fd, " ~s(__os,_result); // Return value\n", 1095 [ic_java_type:marshalFun(G,N,X,R)]) 1096 end, 1097 emit_server_marshal_loop(G, N, X, ParamTypes,ArgNames,1,Fd); 1098 false -> 1099 ic_codegen:emit(Fd, " __os.write_tuple_head(2);\n"), 1100 ic_codegen:emit(Fd, " __os.write_ref(__ref.node(),__ref.ids(),__ref.creation()); // Call reference\n"), 1101 1102 case ic_java_type:isBasicType(G,N,R) of 1103 true -> 1104 ic_codegen:emit(Fd, " __os~s(_result); // Return value\n\n", 1105 [ic_java_type:marshalFun(G,N,X,R)]); 1106 false -> 1107 ic_codegen:emit(Fd, " ~s(__os,_result); // Return value\n\n", 1108 [ic_java_type:marshalFun(G,N,X,R)]) 1109 end 1110 end 1111 end, 1112 ic_codegen:nl(Fd) 1113 end. 1114 1115 1116emit_server_unmarshal_loop(_,_,_,_,[],_,Fd) -> 1117 ic_codegen:nl(Fd); 1118emit_server_unmarshal_loop(G, N, X, [Type|Types], [{in, Arg}|Args], Counter, Fd) -> 1119 case ic_java_type:isBasicType(G,N,Type) of 1120 true -> 1121 ic_codegen:emit(Fd, " ~s ~s = __is~s; // In value\n", 1122 [ic_java_type:getType(G,N,Type), 1123 Arg, 1124 ic_java_type:unMarshalFun(G,N,X,Type)]); 1125 false -> 1126 ic_codegen:emit(Fd, " ~s ~s = ~s.unmarshal(__is); // In value\n", 1127 [ic_java_type:getType(G,N,Type), 1128 Arg, 1129 ic_java_type:getUnmarshalType(G,N,X,Type)]) 1130 end, 1131 emit_server_unmarshal_loop(G, N, X, Types, Args, Counter+1, Fd); 1132emit_server_unmarshal_loop(G, N, X, [Type|Types],[{inout, Arg}|Args], Counter, Fd) -> 1133 Holder = ic_java_type:getHolderType(G,N,Type), 1134 case ic_java_type:isBasicType(G,N,Type) of 1135 true -> 1136% OtpEncVar = ic_java_type:getUnmarshalType(G,N,X,Type), 1137 ic_codegen:emit(Fd, " ~s _~s = __is~s;\n", 1138 [ic_java_type:getType(G,N,Type), 1139 Arg, 1140 ic_java_type:unMarshalFun(G,N,X,Type)]), 1141 ic_codegen:emit(Fd, " ~s ~s = new ~s(_~s); // InOut value\n", 1142 [Holder, 1143 Arg, 1144 Holder, 1145 Arg]); 1146 false -> 1147 ic_codegen:emit(Fd, " ~s ~s = new ~s(); // InOut value\n", 1148 [Holder, 1149 Arg, 1150 Holder]), 1151 ic_codegen:emit(Fd, " ~s._unmarshal(__is);\n", 1152 [Arg]) 1153 end, 1154 emit_server_unmarshal_loop(G, N, X, Types, Args, Counter+1, Fd); 1155emit_server_unmarshal_loop(G, N, X, [Type|Types],[{out, Arg}|Args], Counter, Fd) -> 1156 Holder = ic_java_type:getHolderType(G,N,Type), 1157 ic_codegen:emit(Fd, " ~s ~s = new ~s(); // Out value\n", [Holder, Arg, Holder]), 1158 emit_server_unmarshal_loop(G, N, X, Types, Args, Counter, Fd). 1159 1160 1161emit_server_marshal_loop(_,_,_,_,[],_,_Fd) -> 1162 ok; 1163emit_server_marshal_loop(G, N, X, [_Type|Types],[{in, _Arg}|Args], Counter, Fd) -> 1164 emit_server_marshal_loop(G, N, X, Types, Args, Counter, Fd); 1165emit_server_marshal_loop(G, N, X, [Type|Types],[{_, Arg}|Args], Counter, Fd) -> 1166% Holder = ic_java_type:getHolderType(G,N,Type), 1167 case ic_java_type:isBasicType(G,N,Type) of 1168 true -> 1169 ic_codegen:emit(Fd, " __os~s(~s.value); // Out/InOut value\n", 1170 [ic_java_type:marshalFun(G,N,X,Type),Arg]); 1171 false -> 1172 ic_codegen:emit(Fd, " ~s._marshal(__os); // Out/InOut value\n", 1173 [Arg]) 1174 end, 1175 emit_server_marshal_loop(G, N, X, Types, Args, Counter+1, Fd). 1176 1177 1178 1179 1180 1181%%%---------------------------------------------------- 1182%%% 1183%%% Utilities 1184%%% 1185%%%---------------------------------------------------- 1186 1187extract_info(_G, N, X) when is_record(X, op) -> 1188 Name = ic_util:to_undersc([ic_forms:get_id2(X) | N]), 1189 Args = X#op.params, 1190 ArgNames = mk_c_vars(Args), 1191 TypeList = {ic_forms:get_type(X), 1192 lists:map(fun(Y) -> ic_forms:get_type(Y) end, Args), 1193 [] 1194 }, 1195 {Name, ArgNames, TypeList}; 1196extract_info(_G, N, X) -> 1197 Name = ic_util:to_undersc([ic_forms:get_id2(X) | N]), 1198 {Name, [], []}. 1199 1200%% Input is a list of parameters (in parse form) and output is a list 1201%% of parameter attribute and variable names. 1202mk_c_vars(Params) -> 1203 lists:map(fun(P) -> {A, _} = P#param.inout, 1204 {A, ic_forms:get_id(P#param.id)} 1205 end, 1206 Params). 1207 1208%% 1209handle_preproc(G, _N, line_nr, X) -> 1210 Id = ic_forms:get_java_id(X), 1211 Flags = X#preproc.aux, 1212 case Flags of 1213 [] -> ic_genobj:push_file(G, Id); 1214 _ -> 1215 lists:foldr(fun({_, _, "1"}, Gprim) -> ic_genobj:push_file(Gprim, Id); 1216 ({_, _, "2"}, Gprim) -> ic_genobj:pop_file(Gprim, Id); 1217 ({_, _, "3"}, Gprim) -> ic_genobj:sys_file(Gprim, Id) end, 1218 G, Flags) 1219 end; 1220handle_preproc(G, _N, _Other, _X) -> 1221 G. 1222 1223 1224%% 1225gen_par_list(_, _, _, [], []) -> 1226 []; 1227gen_par_list(G, N, X, [Type |Types], [{Attr, Arg}|Args]) -> 1228 JType = ic_java_type:getParamType(G, N, Type, Attr), 1229 [JType ++ " " ++ Arg | 1230 gen_par_list(G, N, X, Types, Args)]. 1231 1232 1233gen_marshal_par_list(_, _, _, [], []) -> 1234 []; 1235gen_marshal_par_list(G, N, X, [_Type |Types], [{out, _Arg}|Args]) -> 1236 gen_marshal_par_list(G, N, X, Types, Args); 1237gen_marshal_par_list(G, N, X, [Type |Types], [{Attr, Arg}|Args]) -> 1238 JType = ic_java_type:getParamType(G, N, Type, Attr), 1239 [JType ++ " " ++ Arg | 1240 gen_marshal_par_list(G, N, X, Types, Args)]. 1241 1242 1243gen_unmarshal_par_list(_, _, _, [], []) -> 1244 []; 1245gen_unmarshal_par_list(G, N, X, [_Type |Types], [{in, _Arg}|Args]) -> 1246 gen_unmarshal_par_list(G, N, X, Types, Args); 1247gen_unmarshal_par_list(G, N, X, [Type |Types], [{Attr, Arg}|Args]) -> 1248 JType = ic_java_type:getParamType(G, N, Type, Attr), 1249 [JType ++ " " ++ Arg | 1250 gen_unmarshal_par_list(G, N, X, Types, Args)]. 1251 1252 1253%% 1254gen_client_marshal_call_par_list([]) -> 1255 []; 1256gen_client_marshal_call_par_list([{out, _Arg}|Args]) -> 1257 gen_client_marshal_call_par_list(Args); 1258gen_client_marshal_call_par_list([{_Attr, Arg}|Args]) -> 1259 [Arg | gen_client_marshal_call_par_list(Args)]. 1260 1261 1262gen_client_unmarshal_call_par_list([]) -> 1263 []; 1264gen_client_unmarshal_call_par_list([{in, _Arg}|Args]) -> 1265 gen_client_unmarshal_call_par_list(Args); 1266gen_client_unmarshal_call_par_list([{_Attr, Arg}|Args]) -> 1267 [Arg | gen_client_unmarshal_call_par_list(Args)]. 1268 1269 1270 1271count_client_receive(ArgNames) -> 1272 count_client_receive(ArgNames,0). 1273 1274count_client_receive([],C) -> 1275 C; 1276count_client_receive([{in, _Arg}|Args],C) -> 1277 count_client_receive(Args,C); 1278count_client_receive([_|Args],C) -> 1279 count_client_receive(Args,C+1). 1280 1281 1282 1283count_client_send(ArgNames) -> 1284 count_client_send(ArgNames,0). 1285 1286count_client_send([],C) -> 1287 C; 1288count_client_send([{out, _Arg}|Args],C) -> 1289 count_client_send(Args,C); 1290count_client_send([_|Args],C) -> 1291 count_client_send(Args,C+1). 1292 1293 1294gen_cb_arg_list([]) -> 1295 []; 1296gen_cb_arg_list([{_Attr, Arg}|Args]) -> 1297 [Arg | gen_cb_arg_list(Args)]. 1298 1299 1300count_server_receive(ArgNames) -> 1301 count_server_receive(ArgNames,0). 1302 1303count_server_receive([],C) -> 1304 C; 1305count_server_receive([_|Args],C) -> 1306 count_server_receive(Args,C+1). 1307 1308 1309count_server_send(ArgNames) -> 1310 count_server_send(ArgNames,0). 1311 1312count_server_send([],C) -> 1313 C; 1314count_server_send([{in, _Arg}|Args],C) -> 1315 count_server_send(Args,C); 1316count_server_send([_|Args],C) -> 1317 count_server_send(Args,C+1). 1318 1319 1320 1321 1322 1323%%%------------------------------------------------------- 1324 1325 1326emit_type_function(G, N, X, Fd) -> 1327 1328 TC = ic_forms:get_type_code(G, N, X), 1329 1330 %%io:format("X = ~p\nTC = ~p\n",[X,TC]), 1331 1332 ic_codegen:emit(Fd, " private static ~sTypeCode _tc;\n",[?ICPACKAGE]), 1333 ic_codegen:emit(Fd, " synchronized public static ~sTypeCode type() {\n\n",[?ICPACKAGE]), 1334 1335 ic_codegen:emit(Fd, " if (_tc != null)\n"), 1336 ic_codegen:emit(Fd, " return _tc;\n\n"), 1337 1338 emit_type_function(TC, 0, Fd), 1339 1340 ic_codegen:emit(Fd, "\n _tc = _tc0;\n"), 1341 1342 ic_codegen:emit(Fd, "\n return _tc0;\n"), 1343 ic_codegen:emit(Fd, " }\n\n"). 1344 1345 1346 1347emit_type_function({tk_struct, ID, Name, ML}, C, Fd) -> %% struct 1348 ic_codegen:emit(Fd, " ~sTypeCode _tc~p =\n",[?ICPACKAGE,C]), 1349 ic_codegen:emit(Fd, " new ~sTypeCode();\n", [?ICPACKAGE]), 1350 ic_codegen:emit(Fd, " _tc~p.kind(~sTCKind.tk_struct);\n", [C,?ICPACKAGE]), 1351 ic_codegen:emit(Fd, " _tc~p.id(~p);\n", [C,ID]), 1352 ic_codegen:emit(Fd, " _tc~p.name(~p);\n", [C,Name]), 1353 ic_codegen:emit(Fd, " _tc~p.member_count(~p);\n", [C,length(ML)]), 1354 emit_struct_members(ML, C, C+1, 0, Fd); 1355 1356emit_type_function({tk_enum, ID, Name, MNames}, C, Fd) -> %% enum 1357 ic_codegen:emit(Fd, " ~sTypeCode _tc~p =\n",[?ICPACKAGE,C]), 1358 ic_codegen:emit(Fd, " new ~sTypeCode();\n", [?ICPACKAGE]), 1359 ic_codegen:emit(Fd, " _tc~p.kind(~sTCKind.tk_enum);\n", [C,?ICPACKAGE]), 1360 ic_codegen:emit(Fd, " _tc~p.id(~p);\n", [C,ID]), 1361 ic_codegen:emit(Fd, " _tc~p.name(~p);\n", [C,Name]), 1362 ic_codegen:emit(Fd, " _tc~p.member_count(~p);\n", [C,length(MNames)]), 1363 emit_enum_members(MNames, C, 0, Fd), 1364 C+1; 1365 1366emit_type_function({tk_array, ET, L}, C, Fd) -> %% array 1367 ic_codegen:emit(Fd, " ~sTypeCode _tc~p =\n",[?ICPACKAGE,C]), 1368 ic_codegen:emit(Fd, " new ~sTypeCode();\n", [?ICPACKAGE]), 1369 ic_codegen:emit(Fd, " _tc~p.kind(~sTCKind.tk_array);\n", [C,?ICPACKAGE]), 1370 ic_codegen:emit(Fd, " _tc~p.id(id());\n",[C]), 1371 ic_codegen:emit(Fd, " _tc~p.length(~p);\n", [C,L]), 1372 C1 = C+1, 1373 C2 = emit_type_function(ET, C1, Fd), 1374 ic_codegen:emit(Fd, " _tc~p.content_type(_tc~p);\n", [C,C1]), 1375 C2; 1376 1377emit_type_function({tk_sequence, ET, L}, C, Fd) -> %% sequence 1378 ic_codegen:emit(Fd, " ~sTypeCode _tc~p =\n",[?ICPACKAGE,C]), 1379 ic_codegen:emit(Fd, " new ~sTypeCode();\n", [?ICPACKAGE]), 1380 ic_codegen:emit(Fd, " _tc~p.kind(~sTCKind.tk_sequence);\n", [C,?ICPACKAGE]), 1381 ic_codegen:emit(Fd, " _tc~p.id(id());\n",[C]), 1382 ic_codegen:emit(Fd, " _tc~p.length(~p);\n", [C,L]), 1383 C1 = C+1, 1384 C2 = emit_type_function(ET, C1, Fd), 1385 ic_codegen:emit(Fd, " _tc~p.content_type(_tc~p);\n", [C,C1]), 1386 C2; 1387 1388emit_type_function({tk_string, L}, C, Fd) -> %% string 1389 ic_codegen:emit(Fd, " ~sTypeCode _tc~p =\n",[?ICPACKAGE,C]), 1390 ic_codegen:emit(Fd, " new ~sTypeCode();\n", [?ICPACKAGE]), 1391 ic_codegen:emit(Fd, " _tc~p.kind(~sTCKind.tk_string);\n", [C,?ICPACKAGE]), 1392 ic_codegen:emit(Fd, " _tc~p.length(~p);\n", [C,L]), 1393 C+1; 1394 1395emit_type_function({tk_union, ID, Name, DT, DI, LL}, C, Fd) -> %% union 1396 1397 ic_codegen:emit(Fd, " ~sTypeCode _tc~p =\n",[?ICPACKAGE,C]), 1398 ic_codegen:emit(Fd, " new ~sTypeCode();\n", [?ICPACKAGE]), 1399 ic_codegen:emit(Fd, " _tc~p.kind(~sTCKind.tk_union);\n", [C,?ICPACKAGE]), 1400 ic_codegen:emit(Fd, " _tc~p.id(~p);\n", [C,ID]), 1401 ic_codegen:emit(Fd, " _tc~p.name(~p);\n", [C,Name]), 1402 1403 C1 = C+1, 1404 C2 = emit_type_function(DT, C1, Fd), 1405 1406 ic_codegen:emit(Fd, " _tc~p.discriminator_type(_tc~p);\n", [C,C1]), 1407 ic_codegen:emit(Fd, " _tc~p.default_index(~p);\n", [C,DI]), 1408 ic_codegen:emit(Fd, " _tc~p.member_count(~p);\n", [C,length(LL)]), 1409 1410 emit_union_labels(LL, C, DT, C2, 0, Fd); 1411 1412emit_type_function(tk_term, C, Fd) -> %% term, must change it to tk_any 1413 ic_codegen:emit(Fd, " ~sTypeCode _tc~p =\n",[?ICPACKAGE,C]), 1414 ic_codegen:emit(Fd, " new ~sTypeCode();\n", [?ICPACKAGE]), 1415 ic_codegen:emit(Fd, " _tc~p.kind(~sTCKind.tk_any);\n", [C,?ICPACKAGE]), 1416 C+1; 1417 1418emit_type_function(TC, C, Fd) -> %% other 1419 ic_codegen:emit(Fd, " ~sTypeCode _tc~p =\n",[?ICPACKAGE,C]), 1420 ic_codegen:emit(Fd, " new ~sTypeCode();\n", [?ICPACKAGE]), 1421 ic_codegen:emit(Fd, " _tc~p.kind(~sTCKind.~p);\n", [C,?ICPACKAGE,TC]), 1422 C+1. 1423 1424 1425 1426emit_struct_members([], _, TCtr, _, _Fd) -> 1427 TCtr; 1428emit_struct_members([{Name,MT}|Rest], BTCtr, TCtr, I, Fd) -> 1429 ic_codegen:emit(Fd, " _tc~p.member_name(~p,~p);\n", [BTCtr,I,Name]), 1430 TCtr2 = emit_type_function(MT, TCtr, Fd), 1431 ic_codegen:emit(Fd, " _tc~p.member_type(~p,_tc~p);\n", [BTCtr,I,TCtr]), 1432 emit_struct_members(Rest, BTCtr, TCtr2, I+1, Fd). 1433 1434emit_enum_members([], _, _, _Fd) -> 1435 ok; 1436emit_enum_members([Name|Names], BTCtr, I, Fd) -> 1437 ic_codegen:emit(Fd, " _tc~p.member_name(~p,~p);\n", [BTCtr,I,Name]), 1438 emit_enum_members(Names, BTCtr, I+1, Fd). 1439 1440 1441emit_union_labels([], _, _, TCtr, _, _) -> 1442 TCtr; 1443emit_union_labels([{L, LN, LT}|Rest], BTCtr, DT, TCtr, I, Fd) -> 1444 ic_codegen:emit(Fd, " ~sAny _any~p =\n",[?ICPACKAGE,TCtr]), 1445 ic_codegen:emit(Fd, " new ~sAny();\n", [?ICPACKAGE]), 1446 TCtr1 = TCtr+1, 1447 TCtr2 = emit_type_function(LT, TCtr1,Fd), 1448 ic_codegen:emit(Fd, " _any~p.type(_tc~p);\n",[TCtr,TCtr1]), 1449 1450 case L of 1451 default -> 1452 ic_codegen:emit(Fd, " _any~p.insert_atom(\"default\");\n", [TCtr]); 1453 _ -> 1454 case DT of 1455 tk_boolean -> 1456 ic_codegen:emit(Fd, " _any~p.insert_boolean(~p);\n",[TCtr,L]); 1457 tk_char -> 1458 Default = if is_integer(L) -> 1459 [L]; 1460 true -> 1461 L 1462 end, 1463 ic_codegen:emit(Fd, " _any~p.insert_char('~s');\n",[TCtr,Default]); 1464 tk_ushort -> 1465 ic_codegen:emit(Fd, " _any~p.insert_ushort(~p);\n",[TCtr,L]); 1466 tk_ulong -> 1467 ic_codegen:emit(Fd, " _any~p.insert_ulong(~p);\n",[TCtr,L]); 1468 tk_short -> 1469 ic_codegen:emit(Fd, " _any~p.insert_short(~p);\n",[TCtr,L]); 1470 tk_long -> 1471 ic_codegen:emit(Fd, " _any~p.insert_long(~p);\n",[TCtr,L]); 1472 _ -> 1473 ic_codegen:emit(Fd, " _any~p.insert_string(~p);\n", [TCtr,L]) 1474 end 1475 end, 1476 ic_codegen:emit(Fd, " _tc~p.member_label(~p,_any~p);\n", [BTCtr,I,TCtr]), 1477 ic_codegen:emit(Fd, " _tc~p.member_name(~p,~p);\n", [BTCtr,I,LN]), 1478 TCtr3 = emit_type_function(LT, TCtr2, Fd), 1479 ic_codegen:emit(Fd, " _tc~p.member_type(~p,_tc~p);\n", [BTCtr,I,TCtr2]), 1480 emit_union_labels(Rest, BTCtr, DT, TCtr3, I+1, Fd). 1481 1482 1483 1484 1485 1486 1487 1488 1489