widl: Fix top-level and callback conformances.

This commit is contained in:
Dan Hipschman 2007-09-04 09:33:23 -07:00 committed by Alexandre Julliard
parent 69025bafe7
commit 3d036da6d3
3 changed files with 117 additions and 102 deletions

View File

@ -225,6 +225,16 @@ s_sum_cps(cps_t *cps)
return sum;
}
int
s_sum_cpsc(cpsc_t *cpsc)
{
int sum = 0;
int i;
for (i = 0; i < (cpsc->c ? cpsc->a : cpsc->b); ++i)
sum += cpsc->ca[i];
return sum;
}
int
s_square_puint(puint_t p)
{
@ -298,6 +308,27 @@ s_square_encue(encue_t *eue)
}
}
int
s_sum_toplev_conf_2n(int *x, int n)
{
int sum = 0;
int i;
for (i = 0; i < 2 * n; ++i)
sum += x[i];
return sum;
}
int
s_sum_toplev_conf_cond(int *x, int a, int b, int c)
{
int sum = 0;
int n = c ? a : b;
int i;
for (i = 0; i < n; ++i)
sum += x[i];
return sum;
}
void
s_stop(void)
{
@ -584,6 +615,7 @@ array_tests(void)
static int c[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
static vector_t vs[2] = {{1, -2, 3}, {4, -5, -6}};
cps_t cps;
cpsc_t cpsc;
cs_t *cs;
int n;
@ -616,6 +648,21 @@ array_tests(void)
cps.n = 3;
cps.ca2 = &c[3];
ok(sum_cps(&cps) == 53, "RPC sum_cps\n");
cpsc.a = 4;
cpsc.b = 5;
cpsc.c = 1;
cpsc.ca = c;
ok(sum_cpsc(&cpsc) == 6, "RPC sum_cpsc\n");
cpsc.a = 4;
cpsc.b = 5;
cpsc.c = 0;
cpsc.ca = c;
ok(sum_cpsc(&cpsc) == 10, "RPC sum_cpsc\n");
ok(sum_toplev_conf_2n(c, 3) == 15, "RPC sum_toplev_conf_2n\n");
ok(sum_toplev_conf_cond(c, 5, 6, 1) == 10, "RPC sum_toplev_conf_cond\n");
ok(sum_toplev_conf_cond(c, 5, 6, 0) == 15, "RPC sum_toplev_conf_cond\n");
}
static void

View File

@ -127,8 +127,17 @@ interface IServer
int n;
} cps_t;
typedef struct
{
[size_is(c ? a : b)] int *ca;
int a;
int b;
int c;
} cpsc_t;
int sum_cs(cs_t *cs);
int sum_cps(cps_t *cps);
int sum_cpsc(cpsc_t *cpsc);
typedef [wire_marshal(int)] void *puint_t;
int square_puint(puint_t p);
@ -176,5 +185,9 @@ interface IServer
int sum_pcarr([size_is(n)] int *a[], int n);
int enum_ord(e_t e);
double square_encue(encue_t *eue);
int sum_toplev_conf_2n([size_is(n * 2)] int *x, int n);
int sum_toplev_conf_cond([size_is(c ? a : b)] int *x, int a, int b, int c);
void stop(void);
}

View File

@ -46,16 +46,11 @@
static const func_t *current_func;
static const type_t *current_structure;
/* name of the structure variable for structure callbacks */
#define STRUCT_EXPR_EVAL_VAR "pS"
static struct list expr_eval_routines = LIST_INIT(expr_eval_routines);
struct expr_eval_routine
{
struct list entry;
const type_t *structure;
size_t structure_size;
const expr_t *expr;
};
@ -496,9 +491,16 @@ static size_t write_conf_or_var_desc(FILE *file, const func_t *func, const type_
unsigned char operator_type = 0;
const char *operator_string = "no operators";
const expr_t *subexpr;
unsigned char correlation_type;
if (!file) return 4; /* optimisation for sizing pass */
if (!structure)
{
/* Top-level conformance calculations are done inline. */
print_file (file, 2, "0x%x,\t/* Corr desc: parameter */\n",
RPC_FC_TOP_LEVEL_CONFORMANCE);
print_file (file, 2, "0x0,\n");
print_file (file, 2, "NdrFcShort(0x0),\n");
return 4;
}
if (expr->is_const)
{
@ -565,53 +567,25 @@ static size_t write_conf_or_var_desc(FILE *file, const func_t *func, const type_
unsigned char correlation_variable_type;
unsigned char param_type = 0;
const char *param_type_string = NULL;
size_t offset;
size_t offset = 0;
const var_t *var;
if (structure)
if (structure->fields) LIST_FOR_EACH_ENTRY( var, structure->fields, const var_t, entry )
{
const var_t *var;
offset = 0;
if (structure->fields) LIST_FOR_EACH_ENTRY( var, structure->fields, const var_t, entry )
unsigned int align = 0;
/* FIXME: take alignment into account */
if (var->name && !strcmp(var->name, subexpr->u.sval))
{
unsigned int align = 0;
/* FIXME: take alignment into account */
if (var->name && !strcmp(var->name, subexpr->u.sval))
{
correlation_variable = var->type;
break;
}
offset += type_memsize(var->type, &align);
correlation_variable = var->type;
break;
}
if (!correlation_variable)
error("write_conf_or_var_desc: couldn't find variable %s in structure\n",
subexpr->u.sval);
offset -= baseoff;
correlation_type = RPC_FC_NORMAL_CONFORMANCE;
}
else
{
const var_t *var;
offset = sizeof(void *);
if (func->args) LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
{
if (!strcmp(var->name, subexpr->u.sval))
{
correlation_variable = var->type;
break;
}
/* FIXME: not all stack variables are sizeof(void *) */
offset += sizeof(void *);
}
if (!correlation_variable)
error("write_conf_or_var_desc: couldn't find variable %s in function\n",
subexpr->u.sval);
correlation_type = RPC_FC_TOP_LEVEL_CONFORMANCE;
offset += type_memsize(var->type, &align);
}
if (!correlation_variable)
error("write_conf_or_var_desc: couldn't find variable %s in structure\n",
subexpr->u.sval);
offset -= baseoff;
correlation_variable_type = correlation_variable->type;
switch (correlation_variable_type)
@ -665,60 +639,41 @@ static size_t write_conf_or_var_desc(FILE *file, const func_t *func, const type_
correlation_variable_type);
}
print_file(file, 2, "0x%x, /* Corr desc: %s%s */\n",
correlation_type | param_type,
correlation_type == RPC_FC_TOP_LEVEL_CONFORMANCE ? "parameter, " : "",
param_type_string);
print_file(file, 2, "0x%x, /* Corr desc: %s */\n",
RPC_FC_NORMAL_CONFORMANCE | param_type, param_type_string);
print_file(file, 2, "0x%x, /* %s */\n", operator_type, operator_string);
print_file(file, 2, "NdrFcShort(0x%x), /* %soffset = %d */\n",
offset,
correlation_type == RPC_FC_TOP_LEVEL_CONFORMANCE ? "x86 stack size / " : "",
offset);
print_file(file, 2, "NdrFcShort(0x%x), /* offset = %d */\n",
offset, offset);
}
else
{
unsigned int callback_offset = 0;
struct expr_eval_routine *eval;
int found = 0;
if (structure)
LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry)
{
struct expr_eval_routine *eval;
int found = 0;
LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry)
if (!strcmp (eval->structure->name, structure->name)
&& !compare_expr (eval->expr, expr))
{
if (!strcmp(eval->structure->name, structure->name) &&
!compare_expr(eval->expr, expr))
{
found = 1;
break;
}
callback_offset++;
found = 1;
break;
}
if (!found)
{
unsigned int align = 0;
eval = xmalloc(sizeof(*eval));
eval->structure = structure;
eval->structure_size = fields_memsize(structure->fields, &align);
eval->expr = expr;
list_add_tail(&expr_eval_routines, &eval->entry);
}
correlation_type = RPC_FC_NORMAL_CONFORMANCE;
callback_offset++;
}
else
if (!found)
{
error("write_conf_or_var_desc: top-level callback conformance unimplemented\n");
correlation_type = RPC_FC_TOP_LEVEL_CONFORMANCE;
eval = xmalloc (sizeof(*eval));
eval->structure = structure;
eval->expr = expr;
list_add_tail (&expr_eval_routines, &eval->entry);
}
if (callback_offset > USHRT_MAX)
error("Maximum number of callback routines reached\n");
print_file(file, 2, "0x%x, /* Corr desc: %s */\n",
correlation_type,
correlation_type == RPC_FC_TOP_LEVEL_CONFORMANCE ? "parameter" : "");
print_file(file, 2, "0x%x, /* Corr desc: */\n", RPC_FC_NORMAL_CONFORMANCE);
print_file(file, 2, "0x%x, /* %s */\n", RPC_FC_CALLBACK, "FC_CALLBACK");
print_file(file, 2, "NdrFcShort(0x%x), /* %u */\n", callback_offset, callback_offset);
}
@ -2881,27 +2836,28 @@ void assign_stub_out_args( FILE *file, int indent, const func_t *func )
int write_expr_eval_routines(FILE *file, const char *iface)
{
static const char *var_name = "pS";
int result = 0;
struct expr_eval_routine *eval;
unsigned short callback_offset = 0;
LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry)
{
int indent = 0;
const char *name = eval->structure->name;
const var_list_t *fields = eval->structure->fields;
unsigned align = 0;
result = 1;
print_file(file, indent, "static void __RPC_USER %s_%sExprEval_%04u(PMIDL_STUB_MESSAGE pStubMsg)\n",
iface, eval->structure->name, callback_offset);
print_file(file, indent, "{\n");
indent++;
print_file(file, indent, "struct %s *" STRUCT_EXPR_EVAL_VAR " = (struct %s *)(pStubMsg->StackTop - %u);\n",
eval->structure->name, eval->structure->name, eval->structure_size);
fprintf(file, "\n");
print_file(file, indent, "pStubMsg->Offset = 0;\n"); /* FIXME */
print_file(file, indent, "pStubMsg->MaxCount = (unsigned long)");
write_struct_expr(file, eval->expr, 1, eval->structure->fields, STRUCT_EXPR_EVAL_VAR);
print_file(file, 0, "static void __RPC_USER %s_%sExprEval_%04u(PMIDL_STUB_MESSAGE pStubMsg)\n",
iface, name, callback_offset);
print_file(file, 0, "{\n");
print_file (file, 1, "%s *%s = (%s *)(pStubMsg->StackTop - %u);\n",
name, var_name, name, type_memsize (eval->structure, &align));
print_file(file, 1, "pStubMsg->Offset = 0;\n"); /* FIXME */
print_file(file, 1, "pStubMsg->MaxCount = (unsigned long)");
write_struct_expr(file, eval->expr, 1, fields, var_name);
fprintf(file, ";\n");
indent--;
print_file(file, indent, "}\n\n");
print_file(file, 0, "}\n\n");
callback_offset++;
}
return result;
@ -2918,9 +2874,8 @@ void write_expr_eval_routine_list(FILE *file, const char *iface)
LIST_FOR_EACH_ENTRY_SAFE(eval, cursor, &expr_eval_routines, struct expr_eval_routine, entry)
{
print_file(file, 1, "%s_%sExprEval_%04u,\n",
iface, eval->structure->name, callback_offset);
const char *name = eval->structure->name;
print_file(file, 1, "%s_%sExprEval_%04u,\n", iface, name, callback_offset);
callback_offset++;
list_remove(&eval->entry);
free(eval);