]> rtime.felk.cvut.cz Git - frescor/forb.git/blobdiff - forb-idl/forb-idl-c-stubs.c
IDL compiler: Invoke methods directly only within the same executor
[frescor/forb.git] / forb-idl / forb-idl-c-stubs.c
index 392c3236ac2debfc1652fe1e5e03511717aee730..6405e32aa4b544b0bc0606b12c4361ca0c25b1d2 100644 (file)
@@ -38,14 +38,24 @@ cs_output_stub (IDL_tree     tree,
                fprintf (of, " " FORB_RETVAL_VAR_NAME ";\n");
        }
 
-       fprintf(of, "  if (_obj->type == %s_type) {\n"
-                   "    if (_obj->methods) {\n"
-                   "      /* in-proc object */\n"
-                   "      ", iface_id);
+/*     fprintf(of, "  if (_obj->type != %s_type) {\n" */
+/*                 "    ev->major = FORB_EX_BAD_OPERATION;\n", iface_id); */
+/*     if (has_retval) { */
+/*             fprintf(of, "    return "FORB_RETVAL_VAR_NAME";\n"); */
+/*     } */
+        fprintf(of, "  if (ev) ev->major = FORB_EX_NONE;\n");
+        fprintf(of, "  if (forb_object_is_local(_obj) &&\n"
+                          "forb_get_current_executor() == forb_object_get_executor(_obj)) {\n");
+        fprintf(of, "    if (!_obj->interface ||\n"
+                    "        strncmp(_obj->interface->name, \"%s\", %zd) != 0) {\n"
+                    "      ev->major = FORB_EX_BAD_OPERATION;\n"
+                    "      return %s;\n"
+                    "    }\n", iface_id, strlen(iface_id), has_retval ? FORB_RETVAL_VAR_NAME : "");
+       fprintf(of, "    ");
        if (has_retval) {
                fprintf(of, FORB_RETVAL_VAR_NAME " = ");
        }
-       fprintf(of, "forb_%s_methods(obj)->%s(_obj, ",
+       fprintf(of, "_%s_impl(_obj)->%s(_obj, ",
                iface_id, opname_plain);
        for (sub = IDL_OP_DCL (tree).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
                IDL_tree parm = IDL_LIST (sub).data;
@@ -53,28 +63,36 @@ cs_output_stub (IDL_tree     tree,
        }
        fprintf(of, "ev);\n");
        
-       fprintf(of, "    } else {\n");
-       fprintf(of, "      /* remote object */\n"
-                   "      CDR_Codec codec;\n"
-                   "      CDR_codec_init_static(&codec);\n");
-       fprintf(of, "      forb_prepare_request(&codec, _obj, FORB_METHOD_INDEX(%s));\n",
-               opname);
+       fprintf(of, "  } else {\n");
+       fprintf(of, "    /* remote object */\n"
+                   "    forb_request_t req;\n");
+       fprintf(of, "    ex_on_fail(forb_request_init(&req, _obj) == 0, FORB_EX_INTERNAL);\n");
+       fprintf(of, "    forb_iop_prepare_request(&req, \"%s\", FORB_METHOD_INDEX(%s), ev);\n",
+               iface_id, opname);
+       fprintf(of, "    if (forb_exception_occurred(ev)) goto exception;\n");
        for (sub = IDL_OP_DCL (tree).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
                IDL_tree        parm = IDL_LIST (sub).data;
                IDL_ParamRole   role;
                role = oidl_attr_to_paramrole(IDL_PARAM_DCL(parm).attr);
                if (role == DATA_IN || role == DATA_INOUT) {
-                 char *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
-                 fprintf(of, "      ");
+                 char      *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
+                 gboolean  isSlice;
+                 IDL_tree  ts = forb_cbe_get_typespec(parm);
+                 int       n = oidl_param_info (ts, role, &isSlice);
+                 fprintf(of, "    ex_on_fail(");
                  forb_cbe_write_typespec(of, IDL_PARAM_DCL(parm).param_type_spec);
-                 fprintf(of, "_serialize(&codec, %s);\n", name);
+                 fprintf(of, "_serialize(&req.cdr_request, %s%s), FORB_EX_IMP_LIMIT);\n",
+                         n == 0 ? "&":"", name);
                }
        }
-       fprintf(of, "      /* TODO: Send request */\n");
+       fprintf(of, "    forb_request_send(&req, ev);\n");
+       fprintf(of, "    if (forb_exception_occurred(ev)) goto exception;\n");
+       fprintf(of, "    forb_request_wait_for_reply(&req);\n");
+       fprintf(of, "    if (forb_exception_occurred(ev)) goto exception;\n");
        if (has_retval) {
-         fprintf(of, "      ");
+         fprintf(of, "    ");
          forb_cbe_write_typespec(of, IDL_OP_DCL(tree).op_type_spec);
-         fprintf(of, "_deserialize(&codec, &"FORB_RETVAL_VAR_NAME");\n");
+         fprintf(of, "_deserialize(req.cdr_reply, &"FORB_RETVAL_VAR_NAME");\n");
        }
        for (sub = IDL_OP_DCL (tree).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
                IDL_tree        parm = IDL_LIST (sub).data;
@@ -82,14 +100,25 @@ cs_output_stub (IDL_tree     tree,
                role = oidl_attr_to_paramrole(IDL_PARAM_DCL(parm).attr);
                if (role == DATA_OUT || role == DATA_INOUT) {
                  char *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
-                 fprintf(of, "      ");
+                 gboolean  isSlice;
+                 IDL_tree  ts = forb_cbe_get_typespec(parm);
+                 int       n = oidl_param_info (ts, role, &isSlice);
+                 if (IDL_NODE_TYPE(forb_cbe_get_typespec(parm)) == IDLN_TYPE_SEQUENCE &&
+                     role == DATA_OUT) { /* Allocate out sequence */
+                         fprintf(ci->fh, "    *%s = forb_malloc(sizeof(**%s));\n", name, name);
+                         fprintf(ci->fh, "    if (!*%s) { ev->major = FORB_EX_NO_MEMORY; goto exception; }\n", name);
+                         fprintf(ci->fh, "    memset(*%s, 0, sizeof(**%s));\n", name, name);
+                         fprintf(ci->fh, "    CORBA_sequence_set_release(*%s, CORBA_TRUE);\n", name);
+                         /* TODO: Free previously allocated parameters on no memory error. */
+                 }
+                 fprintf(of, "    ");
                  forb_cbe_write_typespec(of, IDL_PARAM_DCL(parm).param_type_spec);
-                 fprintf(of, "_deserialize(&codec, %s);\n", name);
+                 fprintf(ci->fh, "_deserialize(req.cdr_reply, %s%s);\n", n==2?"*":"", name);
                }
        }
-       fprintf(of, "    }\n");
-       fprintf(of, "  } else {\n");
-       fprintf(of, "    ev->major = FORB_EX_BAD_OPERATION;\n");
+       fprintf(of, "    forb_request_signal_processed(&req);\n"
+                   "exception:\n"
+                   "    forb_request_destroy(&req);\n");
        fprintf(of, "  }\n");
        if (has_retval) {
                fprintf(of, "  return " FORB_RETVAL_VAR_NAME ";\n");
@@ -139,8 +168,15 @@ cs_output_stubs (IDL_tree     tree,
                }
        case IDLN_INTERFACE: {
                int real_idx = 0;
-
-               cs_output_stubs (IDL_INTERFACE (tree).body, ci, &real_idx);
+               char *id;
+               /* Do not output skeletons for PIDL interfaces */
+               if ((tree->declspec & IDLF_DECLSPEC_PIDL) == 0) {
+                 id = IDL_ns_ident_to_qstring (IDL_INTERFACE (tree).ident, "_", 0);
+                 fprintf(ci->fh, "#define _%s_impl(obj) ((struct forb_%s_impl*)(obj)->implementation)\n\n",
+                         id, id);
+                 g_free(id);
+                 cs_output_stubs (IDL_INTERFACE (tree).body, ci, &real_idx);
+               }
                break;
                }
        case IDLN_OP_DCL:
@@ -157,9 +193,17 @@ forb_idl_output_c_stubs (IDL_tree       tree,
                          OIDL_C_Info   *ci)
 {
        fprintf (ci->fh, OIDL_C_WARNING);
-/*     fprintf (ci->fh, "#include <string.h>\n"); */
+       fprintf (ci->fh, "#include <string.h>\n");
 /*     fprintf (ci->fh, "#define FORB2_STUBS_API\n"); */
+       fprintf (ci->fh, "#include <forb/forb-internal.h>\n");
+       fprintf (ci->fh, "#include <forb/request.h>\n");
+       fprintf (ci->fh, "#include <forb/iop.h>\n");
+       fprintf (ci->fh, "#include <forb/cdr.h>\n");
+       fprintf (ci->fh, "#include <forb/object.h>\n\n");
        fprintf (ci->fh, "#include \"%s.h\"\n\n", ci->base_name);
 
+       fprintf (ci->fh, "#define ex_on_fail(command, ex) if (!(command)) do { ev->major = (ex); goto exception; } while(0)\n");
+       fprintf (ci->fh, "#define FORB_REQEST_HDR_SIZE (forb_iop_MESSAGE_HEADER_SIZE + forb_iop_REQUEST_HEADER_SIZE)\n\n");
+
        cs_output_stubs (tree, ci, NULL);
 }