widl: Improve handling of offsets in the type format string.

This commit is contained in:
Dan Hipschman 2007-05-15 17:45:59 -07:00 committed by Alexandre Julliard
parent cde845fec5
commit 217fc9c0f3
5 changed files with 105 additions and 134 deletions

View File

@ -80,7 +80,7 @@ static void check_pointers(const func_t *func)
}
}
static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsigned int *type_offset)
static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
{
const func_t *func;
const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
@ -95,7 +95,6 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
{
const var_t *def = func->def;
const var_t* explicit_handle_var;
unsigned int type_offset_func;
/* check for a defined binding handle */
explicit_handle_var = get_explicit_handle_var(func);
@ -174,8 +173,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
fprintf(client, "\n");
}
type_offset_func = *type_offset;
write_remoting_arguments(client, indent, func, &type_offset_func, PASS_IN, PHASE_BUFFERSIZE);
write_remoting_arguments(client, indent, func, PASS_IN, PHASE_BUFFERSIZE);
print_client("NdrGetBuffer(\n");
indent++;
@ -188,12 +186,8 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
indent--;
fprintf(client, "\n");
/* make a copy so we don't increment the type offset twice */
type_offset_func = *type_offset;
/* marshal arguments */
write_remoting_arguments(client, indent, func, &type_offset_func, PASS_IN, PHASE_MARSHAL);
write_remoting_arguments(client, indent, func, PASS_IN, PHASE_MARSHAL);
/* send/receive message */
/* print_client("NdrNsSendReceive(\n"); */
@ -223,7 +217,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
/* unmarshall arguments */
fprintf(client, "\n");
write_remoting_arguments(client, indent, func, type_offset, PASS_OUT, PHASE_UNMARSHAL);
write_remoting_arguments(client, indent, func, PASS_OUT, PHASE_UNMARSHAL);
/* unmarshal return value */
if (!is_void(def->type))
@ -397,7 +391,6 @@ static void init_client(void)
void write_client(ifref_list_t *ifaces)
{
unsigned int proc_offset = 0;
unsigned int type_offset = 2;
ifref_t *iface;
if (!do_client)
@ -429,7 +422,7 @@ void write_client(ifref_list_t *ifaces)
write_clientinterfacedecl(iface->iface);
write_stubdescdecl(iface->iface);
write_function_stubs(iface->iface, &proc_offset, &type_offset);
write_function_stubs(iface->iface, &proc_offset);
print_client("#if !defined(__RPC_WIN32__)\n");
print_client("#error Invalid build platform for this stub.\n");

View File

@ -191,8 +191,9 @@ static void proxy_check_pointers( const var_list_t *args )
}
}
static void free_variable( const var_t *arg, unsigned int type_offset )
static void free_variable( const var_t *arg )
{
size_t type_offset = arg->type->typestring_offset;
var_t *constraint;
type_t *type;
expr_list_t *expr;
@ -240,33 +241,24 @@ static void free_variable( const var_t *arg, unsigned int type_offset )
}
}
static void proxy_free_variables( var_list_t *args, unsigned int type_offset )
static void proxy_free_variables( var_list_t *args )
{
const var_t *arg;
if (!args) return;
LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
{
size_t start_offset;
size_t size_type = get_size_typeformatstring_var(arg, &start_offset);
start_offset += type_offset;
if (is_attr(arg->attrs, ATTR_OUT))
{
free_variable( arg, type_offset );
free_variable( arg );
fprintf(proxy, "\n");
}
type_offset += size_type;
}
}
static void gen_proxy(type_t *iface, const func_t *cur, int idx,
unsigned int proc_offset, unsigned int *type_offset)
unsigned int proc_offset)
{
var_t *def = cur->def;
int has_ret = !is_void(def->type);
unsigned int offset;
indent = 0;
write_type(proxy, def->type);
@ -300,13 +292,11 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx,
print_proxy( "{\n" );
indent++;
offset = *type_offset;
write_remoting_arguments(proxy, indent, cur, &offset, PASS_IN, PHASE_BUFFERSIZE);
write_remoting_arguments(proxy, indent, cur, PASS_IN, PHASE_BUFFERSIZE);
print_proxy( "NdrProxyGetBuffer(This, &_StubMsg);\n" );
offset = *type_offset;
write_remoting_arguments(proxy, indent, cur, &offset, PASS_IN, PHASE_MARSHAL);
write_remoting_arguments(proxy, indent, cur, PASS_IN, PHASE_MARSHAL);
print_proxy( "NdrProxySendReceive(This, &_StubMsg);\n" );
fprintf(proxy, "\n");
@ -319,8 +309,7 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx,
indent--;
fprintf(proxy, "\n");
offset = *type_offset;
write_remoting_arguments(proxy, indent, cur, type_offset, PASS_OUT, PHASE_UNMARSHAL);
write_remoting_arguments(proxy, indent, cur, PASS_OUT, PHASE_UNMARSHAL);
if (has_ret)
print_phase_basetype(proxy, indent, PHASE_UNMARSHAL, PASS_RETURN, def, "_RetVal");
@ -340,7 +329,7 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx,
print_proxy( "{\n" );
if (has_ret) {
indent++;
proxy_free_variables( cur->args, offset );
proxy_free_variables( cur->args );
print_proxy( "_RetVal = NdrProxyErrorHandler(RpcExceptionCode());\n" );
indent--;
}
@ -356,12 +345,11 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx,
}
static void gen_stub(type_t *iface, const func_t *cur, const char *cas,
unsigned int proc_offset, unsigned int *type_offset)
unsigned int proc_offset)
{
var_t *def = cur->def;
const var_t *arg;
int has_ret = !is_void(def->type);
unsigned int offset;
indent = 0;
print_proxy( "void __RPC_STUB %s_", iface->name);
@ -398,8 +386,7 @@ static void gen_stub(type_t *iface, const func_t *cur, const char *cas,
indent--;
fprintf(proxy, "\n");
offset = *type_offset;
write_remoting_arguments(proxy, indent, cur, &offset, PASS_IN, PHASE_UNMARSHAL);
write_remoting_arguments(proxy, indent, cur, PASS_IN, PHASE_UNMARSHAL);
fprintf(proxy, "\n");
assign_stub_out_args( proxy, indent, cur );
@ -431,13 +418,11 @@ static void gen_stub(type_t *iface, const func_t *cur, const char *cas,
print_proxy("*_pdwStubPhase = STUB_MARSHAL;\n");
fprintf(proxy, "\n");
offset = *type_offset;
write_remoting_arguments(proxy, indent, cur, &offset, PASS_OUT, PHASE_BUFFERSIZE);
write_remoting_arguments(proxy, indent, cur, PASS_OUT, PHASE_BUFFERSIZE);
print_proxy("NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg);\n");
offset = *type_offset;
write_remoting_arguments(proxy, indent, cur, &offset, PASS_OUT, PHASE_MARSHAL);
write_remoting_arguments(proxy, indent, cur, PASS_OUT, PHASE_MARSHAL);
fprintf(proxy, "\n");
if (has_ret)
@ -448,8 +433,7 @@ static void gen_stub(type_t *iface, const func_t *cur, const char *cas,
print_proxy("RpcFinally\n");
print_proxy("{\n");
offset = *type_offset;
write_remoting_arguments(proxy, indent+1, cur, &offset, PASS_OUT, PHASE_FREE);
write_remoting_arguments(proxy, indent+1, cur, PASS_OUT, PHASE_FREE);
print_proxy("}\n");
print_proxy("RpcEndFinally\n");
@ -501,11 +485,10 @@ static int write_stub_methods(type_t *iface)
return i;
}
static void write_proxy(type_t *iface, unsigned int *proc_offset, unsigned int *type_offset)
static void write_proxy(type_t *iface, unsigned int *proc_offset)
{
int midx = -1, stubs;
const func_t *cur;
unsigned int offset;
if (!iface->funcs) return;
@ -530,9 +513,8 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset, unsigned int *
break;
}
}
offset = *type_offset;
gen_proxy(iface, cur, idx, *proc_offset, type_offset);
gen_stub(iface, cur, cname, *proc_offset, &offset);
gen_proxy(iface, cur, idx, *proc_offset);
gen_stub(iface, cur, cname, *proc_offset);
*proc_offset += get_size_procformatstring_func( cur );
if (midx == -1) midx = idx;
else if (midx != idx) parser_error("method index mismatch in write_proxy");
@ -594,7 +576,7 @@ void write_proxies(ifref_list_t *ifaces)
ifref_t *cur;
char *file_id = proxy_token;
int c;
unsigned int proc_offset = 0, type_offset = 0;
unsigned int proc_offset = 0;
if (!do_proxies) return;
if (do_everything && !ifaces) return;
@ -605,7 +587,7 @@ void write_proxies(ifref_list_t *ifaces)
if (ifaces)
LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry )
if (is_object(cur->iface->attrs) && !is_local(cur->iface->attrs))
write_proxy(cur->iface, &proc_offset, &type_offset);
write_proxy(cur->iface, &proc_offset);
write_stubdesc();

View File

@ -76,7 +76,7 @@ static void write_parameters_init(const func_t *func)
}
static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsigned int *type_offset)
static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
{
char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE);
@ -88,7 +88,6 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry )
{
const var_t *def = func->def;
unsigned int type_offset_func;
/* check for a defined binding handle */
explicit_handle_var = get_explicit_handle_var(func);
@ -164,11 +163,8 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
indent -= 2;
fprintf(server, "\n");
/* make a copy so we don't increment the type offset twice */
type_offset_func = *type_offset;
/* unmarshall arguments */
write_remoting_arguments(server, indent, func, &type_offset_func, PASS_IN, PHASE_UNMARSHAL);
write_remoting_arguments(server, indent, func, PASS_IN, PHASE_UNMARSHAL);
}
print_server("if (_StubMsg.Buffer > _StubMsg.BufferEnd)\n");
@ -225,8 +221,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
if (has_out_arg_or_return(func))
{
type_offset_func = *type_offset;
write_remoting_arguments(server, indent, func, &type_offset_func, PASS_OUT, PHASE_BUFFERSIZE);
write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_BUFFERSIZE);
print_server("_pRpcMessage->BufferLength = _StubMsg.BufferLength;\n");
fprintf(server, "\n");
@ -240,10 +235,8 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
fprintf(server, "\n");
}
type_offset_func = *type_offset;
/* marshall arguments */
write_remoting_arguments(server, indent, func, type_offset, PASS_OUT, PHASE_MARSHAL);
write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_MARSHAL);
/* marshall the return value */
if (!is_void(def->type))
@ -255,7 +248,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
print_server("{\n");
indent++;
write_remoting_arguments(server, indent, func, &type_offset_func, PASS_OUT, PHASE_FREE);
write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_FREE);
indent--;
print_server("}\n");
@ -419,7 +412,6 @@ static void init_server(void)
void write_server(ifref_list_t *ifaces)
{
unsigned int proc_offset = 0;
unsigned int type_offset = 2;
ifref_t *iface;
if (!do_server)
@ -450,7 +442,7 @@ void write_server(ifref_list_t *ifaces)
write_serverinterfacedecl(iface->iface);
write_stubdescdecl(iface->iface);
write_function_stubs(iface->iface, &proc_offset, &type_offset);
write_function_stubs(iface->iface, &proc_offset);
print_server("#if !defined(__RPC_WIN32__)\n");
print_server("#error Invalid build platform for this stub.\n");

View File

@ -232,7 +232,7 @@ static inline int is_base_type(unsigned char type)
}
static size_t write_procformatstring_var(FILE *file, int indent,
const var_t *var, int is_return, unsigned int *type_offset)
const var_t *var, int is_return)
{
size_t size;
const type_t *type = var->type;
@ -277,10 +277,9 @@ static size_t write_procformatstring_var(FILE *file, int indent,
print_file(file, indent, "0x4d, /* FC_IN_PARAM */\n");
print_file(file, indent, "0x01,\n");
print_file(file, indent, "NdrFcShort(0x%x),\n", *type_offset);
print_file(file, indent, "NdrFcShort(0x%x),\n", type->typestring_offset);
size = 4; /* includes param type prefix */
}
*type_offset += get_size_typeformatstring_var(var, NULL);
return size;
}
@ -289,7 +288,6 @@ void write_procformatstring(FILE *file, const ifref_list_t *ifaces, int for_obje
const ifref_t *iface;
int indent = 0;
const var_t *var;
unsigned int type_offset = 2;
print_file(file, indent, "static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");
print_file(file, indent, "{\n");
@ -313,7 +311,7 @@ void write_procformatstring(FILE *file, const ifref_list_t *ifaces, int for_obje
if (func->args)
{
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
write_procformatstring_var(file, indent, var, FALSE, &type_offset);
write_procformatstring_var(file, indent, var, FALSE);
}
/* emit return value data */
@ -324,8 +322,7 @@ void write_procformatstring(FILE *file, const ifref_list_t *ifaces, int for_obje
print_file(file, indent, "0x5c, /* FC_PAD */\n");
}
else
write_procformatstring_var(file, indent, var, TRUE,
&type_offset);
write_procformatstring_var(file, indent, var, TRUE);
}
}
}
@ -1530,22 +1527,50 @@ static size_t write_typeformatstring_var(FILE *file, int indent, const func_t *f
offset, typeformat_offset);
}
void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, int for_objects)
static void clear_tfsoff(type_t *type)
{
int indent = 0;
const var_t *var;
unsigned int typeformat_offset;
const ifref_t *iface;
for (;;)
{
type->typestring_offset = 0;
print_file(file, indent, "static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n");
print_file(file, indent, "{\n");
indent++;
print_file(file, indent, "0,\n");
print_file(file, indent, "{\n");
indent++;
print_file(file, indent, "NdrFcShort(0x0),\n");
typeformat_offset = 2;
if (type->kind == TKIND_ALIAS)
type = type->orig;
else if (is_ptr(type))
type = type->ref;
else
{
if (type->fields)
{
var_t *v;
LIST_FOR_EACH_ENTRY( v, type->fields, var_t, entry )
clear_tfsoff(v->type);
}
return;
}
}
}
static void clear_all_tfsoffs(const ifref_list_t *ifaces)
{
const ifref_t * iface;
const func_t *func;
const var_t *var;
if (ifaces)
LIST_FOR_EACH_ENTRY( iface, ifaces, const ifref_t, entry )
if (iface->iface->funcs)
LIST_FOR_EACH_ENTRY( func, iface->iface->funcs, const func_t, entry )
if (func->args)
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
clear_tfsoff(var->type);
}
static size_t process_tfs(FILE *file, const ifref_list_t *ifaces, int for_objects)
{
const var_t *var;
const ifref_t *iface;
size_t typeformat_offset = 2;
if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, const ifref_t, entry )
{
@ -1558,15 +1583,34 @@ void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, int for_obje
LIST_FOR_EACH_ENTRY( func, iface->iface->funcs, const func_t, entry )
{
if (is_local(func->def->attrs)) continue;
current_func = func;
if (func->args)
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
write_typeformatstring_var(file, indent, func, var->type, var,
&typeformat_offset);
var->type->typestring_offset
= write_typeformatstring_var(file, 2, func, var->type,
var, &typeformat_offset);
}
}
}
return typeformat_offset + 1;
}
void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, int for_objects)
{
int indent = 0;
print_file(file, indent, "static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n");
print_file(file, indent, "{\n");
indent++;
print_file(file, indent, "0,\n");
print_file(file, indent, "{\n");
indent++;
print_file(file, indent, "NdrFcShort(0x0),\n");
clear_all_tfsoffs(ifaces);
process_tfs(file, ifaces, for_objects);
print_file(file, indent, "0x0\n");
indent--;
print_file(file, indent, "}\n");
@ -1875,8 +1919,7 @@ static inline int is_size_needed_for_phase(enum remoting_phase phase)
}
void write_remoting_arguments(FILE *file, int indent, const func_t *func,
unsigned int *type_offset, enum pass pass,
enum remoting_phase phase)
enum pass pass, enum remoting_phase phase)
{
const expr_list_t *length_is;
const expr_list_t *size_is;
@ -1896,9 +1939,7 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
{
const type_t *type = var->type;
unsigned char rtype;
size_t start_offset;
size_t size_type = get_size_typeformatstring_var(var, &start_offset);
start_offset += *type_offset;
size_t start_offset = type->typestring_offset;
length_is = get_attrp(var->attrs, ATTR_LENGTHIS);
size_is = get_attrp(var->attrs, ATTR_SIZEIS);
@ -1917,10 +1958,10 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
switch (pass)
{
case PASS_IN:
if (!in_attr) goto next;
if (!in_attr) continue;
break;
case PASS_OUT:
if (!out_attr) goto next;
if (!out_attr) continue;
break;
case PASS_RETURN:
break;
@ -2084,16 +2125,13 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
}
}
fprintf(file, "\n");
next:
*type_offset += size_type;
}
}
size_t get_size_procformatstring_var(const var_t *var)
{
unsigned int type_offset = 2;
return write_procformatstring_var(NULL, 0, var, FALSE, &type_offset);
return write_procformatstring_var(NULL, 0, var, FALSE);
}
@ -2116,17 +2154,6 @@ size_t get_size_procformatstring_func(const func_t *func)
return size;
}
size_t get_size_typeformatstring_var(const var_t *var, size_t *pstart_offset)
{
unsigned int type_offset = 2; /* 0 is used as an invalid offset */
size_t start_offset = write_typeformatstring_var(NULL, 0, NULL, var->type,
var, &type_offset);
if (pstart_offset)
*pstart_offset = start_offset - 2;
return type_offset - 2;
}
size_t get_size_procformatstring(const ifref_list_t *ifaces, int for_objects)
{
const ifref_t *iface;
@ -2148,29 +2175,7 @@ size_t get_size_procformatstring(const ifref_list_t *ifaces, int for_objects)
size_t get_size_typeformatstring(const ifref_list_t *ifaces, int for_objects)
{
const ifref_t *iface;
size_t size = 3;
const func_t *func;
const var_t *var;
if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, const ifref_t, entry )
{
if (for_objects != is_object(iface->iface->attrs) || is_local(iface->iface->attrs))
continue;
if (iface->iface->funcs)
{
LIST_FOR_EACH_ENTRY( func, iface->iface->funcs, const func_t, entry )
{
if (is_local(func->def->attrs)) continue;
/* argument list size */
if (func->args)
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
size += get_size_typeformatstring_var(var, NULL);
}
}
}
return size;
return process_tfs(NULL, ifaces, for_objects);
}
static void write_struct_expr(FILE *h, const expr_t *e, int brackets,

View File

@ -39,10 +39,9 @@ void write_formatstringsdecl(FILE *f, int indent, ifref_list_t *ifaces, int for_
void write_procformatstring(FILE *file, const ifref_list_t *ifaces, int for_objects);
void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, int for_objects);
void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase, enum pass pass, const var_t *var, const char *varname);
void write_remoting_arguments(FILE *file, int indent, const func_t *func, unsigned int *type_offset, enum pass pass, enum remoting_phase phase);
void write_remoting_arguments(FILE *file, int indent, const func_t *func, enum pass pass, enum remoting_phase phase);
size_t get_size_procformatstring_var(const var_t *var);
size_t get_size_procformatstring_func(const func_t *func);
size_t get_size_typeformatstring_var(const var_t *var, size_t *start_offset);
size_t get_size_procformatstring(const ifref_list_t *ifaces, int for_objects);
size_t get_size_typeformatstring(const ifref_list_t *ifaces, int for_objects);
void assign_stub_out_args( FILE *file, int indent, const func_t *func );