Sync to wine-1.1.0:
authorEric Kohl <eric.kohl@reactos.org>
Sat, 15 Nov 2008 21:17:09 +0000 (21:17 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Sat, 15 Nov 2008 21:17:09 +0000 (21:17 +0000)
- Simon Richter <Simon.Richter@hogyros.de> Tue, 17 Jun 2008
widl: Write string lengths in host endianness.
Type libraries are currently parsed in host endianness, so byte arrays that are going to be interpreted as integers need to be written in the appropriate byte order.

- Rob Shearman <robertshearman@gmail.com> Fri, 20 Jun 2008
widl: Fix generation of the type format string for conformant-varying structures.
The conformance needs to be added on to the offset in the buffer so set this before calling each the writer of each class of pointer description in write_pointer_description. Pass the passed in offsets to buffer and memory to write_pointer_description_offsets in write_varying_array_pointer_descriptions.

- Rob Shearman <robertshearman@gmail.com> Mon, 23 Jun 2008
widl: Replace code to round up values and calculate padding with macros to improve readability.

- Rob Shearman <robertshearman@gmail.com> Mon, 23 Jun 2008
widl: Fix the embedded pointer offsets in generated code when the containing structure has padding.
Do so by calculating the alignment of members when iterating through the structures and adding it onto the buffer and memory offsets. Only call type_memsize once elsewhere in the embedded pointer processing functions since the return value will be the same from the second call.

- Rob Shearman <robertshearman@gmail.com> Mon, 23 Jun 2008
widl: Factor out the finding of a registered type to reduce code duplication.

- Rob Shearman <robertshearman@gmail.com> Mon, 23 Jun 2008
widl: Set the type of the type_t node constructured for dispinterfaces to RPC_FC_IP, like we do for interfaces.

- Rob Shearman <robertshearman@gmail.com> Mon, 23 Jun 2008
widl: Fix crash in find_array_or_string_in_struct if the structure or union has no fields or cases.
(Aleksey already applied this patch in rev37378)

- Rob Shearman <robertshearman@gmail.com> Mon, 23 Jun 2008
widl: Fix the types of enums with the v1_enum attribute applied.

- Rob Shearman <robertshearman@gmail.com> Mon, 23 Jun 2008
widl: Fix type_memsize to follow aliases so that the correct size is calculated.

- Rob Shearman <robertshearman@gmail.com> Mon, 23 Jun 2008
widl: Fix check_remoting_fields to enumerate the correct list of fields.

svn path=/trunk/; revision=37381

reactos/media/doc/README.WINE
reactos/tools/widl/parser.tab.c
reactos/tools/widl/parser.y
reactos/tools/widl/typegen.c
reactos/tools/widl/write_msft.c

index ec09a3e..607fbd1 100644 (file)
@@ -26,7 +26,7 @@ reactos/tools/wpp                 # Synced to Wine-20081105 (~Wine-1.1.7)
 reactos/tools/winebuild           # Synced to Wine-20081105 (~Wine-1.1.7)
 reactos/tools/wmc                 # Synced to Wine-20081105 (~Wine-1.1.7)
 reactos/tools/wrc                 # Synced to Wine-20081105 (~Wine-1.1.7)
-reactos/tools/widl                # Synced to Wine-1_0-rc1
+reactos/tools/widl                # Synced to Wine-1_1_0
 
 The following libraries are shared with Wine.
 
index c350d55..99423d7 100644 (file)
@@ -3744,12 +3744,12 @@ yyreduce:
 
   case 242:
 #line 877 "parser.y"
-    { (yyval.type) = get_type(0, (yyvsp[0].str), 0); (yyval.type)->kind = TKIND_DISPATCH; ;}
+    { (yyval.type) = get_type(RPC_FC_IP, (yyvsp[0].str), 0); (yyval.type)->kind = TKIND_DISPATCH; ;}
     break;
 
   case 243:
 #line 878 "parser.y"
-    { (yyval.type) = get_type(0, (yyvsp[0].str), 0); (yyval.type)->kind = TKIND_DISPATCH; ;}
+    { (yyval.type) = get_type(RPC_FC_IP, (yyvsp[0].str), 0); (yyval.type)->kind = TKIND_DISPATCH; ;}
     break;
 
   case 244:
@@ -4792,6 +4792,14 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
     error_loc("'%s': [string] attribute applied to non-pointer, non-array type\n",
               v->name);
 
+  if (is_attr(v->attrs, ATTR_V1ENUM))
+  {
+    if (v->type->type == RPC_FC_ENUM16)
+      v->type->type = RPC_FC_ENUM32;
+    else
+      error_loc("'%s': [v1_enum] attribute applied to non-enum type\n", v->name);
+  }
+
   sizeless = FALSE;
   if (arr) LIST_FOR_EACH_ENTRY_REV(dim, arr, expr_t, entry)
   {
@@ -5213,16 +5221,22 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
   return type;
 }
 
-type_t *find_type(const char *name, int t)
+static type_t *find_type_helper(const char *name, int t)
 {
   struct rtype *cur = type_hash[hash_ident(name)];
   while (cur && (cur->t != t || strcmp(cur->name, name)))
     cur = cur->next;
-  if (!cur) {
+  return cur ? cur->type : NULL;
+}
+
+type_t *find_type(const char *name, int t)
+{
+  type_t *type = find_type_helper(name, t);
+  if (!type) {
     error_loc("type '%s' not found\n", name);
     return NULL;
   }
-  return cur->type;
+  return type;
 }
 
 static type_t *find_type2(char *name, int t)
@@ -5234,25 +5248,18 @@ static type_t *find_type2(char *name, int t)
 
 int is_type(const char *name)
 {
-  struct rtype *cur = type_hash[hash_ident(name)];
-  while (cur && (cur->t || strcmp(cur->name, name)))
-    cur = cur->next;
-  if (cur) return TRUE;
-  return FALSE;
+  return find_type_helper(name, 0) != NULL;
 }
 
 static type_t *get_type(unsigned char type, char *name, int t)
 {
-  struct rtype *cur = NULL;
   type_t *tp;
   if (name) {
-    cur = type_hash[hash_ident(name)];
-    while (cur && (cur->t != t || strcmp(cur->name, name)))
-      cur = cur->next;
-  }
-  if (cur) {
-    free(name);
-    return cur->type;
+    tp = find_type_helper(name, t);
+    if (tp) {
+      free(name);
+      return tp;
+    }
   }
   tp = make_type(type, NULL);
   tp->name = name;
@@ -5929,7 +5936,7 @@ static void check_remoting_fields(const var_t *var, type_t *type)
             fields = type->fields_or_args;
     }
 
-    if (fields) LIST_FOR_EACH_ENTRY( field, type->fields_or_args, const var_t, entry )
+    if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
         if (field->type) check_field_common(type, type->name, field);
 }
 
index c337aa6..3c0a5fe 100644 (file)
@@ -874,8 +874,8 @@ coclass_int:
          m_attributes interfacedec             { $$ = make_ifref($2); $$->attrs = $1; }
        ;
 
-dispinterface: tDISPINTERFACE aIDENTIFIER      { $$ = get_type(0, $2, 0); $$->kind = TKIND_DISPATCH; }
-       |      tDISPINTERFACE aKNOWNTYPE        { $$ = get_type(0, $2, 0); $$->kind = TKIND_DISPATCH; }
+dispinterface: tDISPINTERFACE aIDENTIFIER      { $$ = get_type(RPC_FC_IP, $2, 0); $$->kind = TKIND_DISPATCH; }
+       |      tDISPINTERFACE aKNOWNTYPE        { $$ = get_type(RPC_FC_IP, $2, 0); $$->kind = TKIND_DISPATCH; }
        ;
 
 dispinterfacehdr: attributes dispinterface     { attr_t *attrs;
@@ -1479,6 +1479,14 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
     error_loc("'%s': [string] attribute applied to non-pointer, non-array type\n",
               v->name);
 
+  if (is_attr(v->attrs, ATTR_V1ENUM))
+  {
+    if (v->type->type == RPC_FC_ENUM16)
+      v->type->type = RPC_FC_ENUM32;
+    else
+      error_loc("'%s': [v1_enum] attribute applied to non-enum type\n", v->name);
+  }
+
   sizeless = FALSE;
   if (arr) LIST_FOR_EACH_ENTRY_REV(dim, arr, expr_t, entry)
   {
@@ -1900,16 +1908,22 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
   return type;
 }
 
-type_t *find_type(const char *name, int t)
+static type_t *find_type_helper(const char *name, int t)
 {
   struct rtype *cur = type_hash[hash_ident(name)];
   while (cur && (cur->t != t || strcmp(cur->name, name)))
     cur = cur->next;
-  if (!cur) {
+  return cur ? cur->type : NULL;
+}
+
+type_t *find_type(const char *name, int t)
+{
+  type_t *type = find_type_helper(name, t);
+  if (!type) {
     error_loc("type '%s' not found\n", name);
     return NULL;
   }
-  return cur->type;
+  return type;
 }
 
 static type_t *find_type2(char *name, int t)
@@ -1921,25 +1935,18 @@ static type_t *find_type2(char *name, int t)
 
 int is_type(const char *name)
 {
-  struct rtype *cur = type_hash[hash_ident(name)];
-  while (cur && (cur->t || strcmp(cur->name, name)))
-    cur = cur->next;
-  if (cur) return TRUE;
-  return FALSE;
+  return find_type_helper(name, 0) != NULL;
 }
 
 static type_t *get_type(unsigned char type, char *name, int t)
 {
-  struct rtype *cur = NULL;
   type_t *tp;
   if (name) {
-    cur = type_hash[hash_ident(name)];
-    while (cur && (cur->t != t || strcmp(cur->name, name)))
-      cur = cur->next;
-  }
-  if (cur) {
-    free(name);
-    return cur->type;
+    tp = find_type_helper(name, t);
+    if (tp) {
+      free(name);
+      return tp;
+    }
   }
   tp = make_type(type, NULL);
   tp->name = name;
@@ -2616,7 +2623,7 @@ static void check_remoting_fields(const var_t *var, type_t *type)
             fields = type->fields_or_args;
     }
 
-    if (fields) LIST_FOR_EACH_ENTRY( field, type->fields_or_args, const var_t, entry )
+    if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
         if (field->type) check_field_common(type, type->name, field);
 }
 
index 35a94c9..f89f13f 100644 (file)
 #include "typegen.h"
 #include "expr.h"
 
+/* round size up to multiple of alignment */
+#define ROUND_SIZE(size, alignment) (((size) + ((alignment) - 1)) & ~((alignment) - 1))
+/* value to add on to round size up to a multiple of alignment */
+#define ROUNDING(size, alignment) (((alignment) - 1) - (((size) + ((alignment) - 1)) & ((alignment) - 1)))
+
 static const func_t *current_func;
 static const type_t *current_structure;
 static const type_t *current_iface;
@@ -754,11 +759,11 @@ static size_t fields_memsize(const var_list_t *fields, unsigned int *align)
             *align = falign;
             have_align = TRUE;
         }
-        size = (size + (falign - 1)) & ~(falign - 1);
+        size = ROUND_SIZE(size, falign);
         size += fsize;
     }
 
-    size = (size + (*align - 1)) & ~(*align - 1);
+    size = ROUND_SIZE(size, *align);
     return size;
 }
 
@@ -798,18 +803,20 @@ int get_padding(const var_list_t *fields)
         size_t size = type_memsize(ft, &align);
         if (salign == -1)
             salign = align;
-        offset = (offset + (align - 1)) & ~(align - 1);
+        offset = ROUND_SIZE(offset, align);
         offset += size;
     }
 
-    return ((offset + (salign - 1)) & ~(salign - 1)) - offset;
+    return ROUNDING(offset, salign);
 }
 
 size_t type_memsize(const type_t *t, unsigned int *align)
 {
     size_t size = 0;
 
-    if (t->declarray && is_conformant_array(t))
+    if (t->kind == TKIND_ALIAS)
+        size = type_memsize(t->orig, align);
+    else if (t->declarray && is_conformant_array(t))
     {
         type_memsize(t->ref, align);
         size = 0;
@@ -1112,6 +1119,8 @@ static int write_no_repeat_pointer_descriptions(
 
     if (is_ptr(type) || (!type->declarray && is_conformant_array(type)))
     {
+        size_t memsize;
+
         print_file(file, 2, "0x%02x, /* FC_NO_REPEAT */\n", RPC_FC_NO_REPEAT);
         print_file(file, 2, "0x%02x, /* FC_PAD */\n", RPC_FC_PAD);
 
@@ -1139,10 +1148,11 @@ static int write_no_repeat_pointer_descriptions(
         }
 
         align = 0;
-        *offset_in_memory += type_memsize(type, &align);
-        /* FIXME: is there a case where these two are different? */
-        align = 0;
-        *offset_in_buffer += type_memsize(type, &align);
+        memsize = type_memsize(type, &align);
+        *offset_in_memory += memsize;
+        /* increment these separately as in the case of conformant (varying)
+         * structures these start at different values */
+        *offset_in_buffer += memsize;
 
         return 1;
     }
@@ -1151,17 +1161,30 @@ static int write_no_repeat_pointer_descriptions(
     {
         const var_t *v;
         LIST_FOR_EACH_ENTRY( v, type->fields_or_args, const var_t, entry )
+        {
+            if (offset_in_memory && offset_in_buffer)
+            {
+                size_t padding;
+                align = 0;
+                type_memsize(v->type, &align);
+                padding = ROUNDING(*offset_in_memory, align);
+                *offset_in_memory += padding;
+                *offset_in_buffer += padding;
+            }
             written += write_no_repeat_pointer_descriptions(
                 file, v->type,
                 offset_in_memory, offset_in_buffer, typestring_offset);
+        }
     }
     else
     {
+        size_t memsize;
         align = 0;
-        *offset_in_memory += type_memsize(type, &align);
-        /* FIXME: is there a case where these two are different? */
-        align = 0;
-        *offset_in_buffer += type_memsize(type, &align);
+        memsize = type_memsize(type, &align);
+        *offset_in_memory += memsize;
+        /* increment these separately as in the case of conformant (varying)
+         * structures these start at different values */
+        *offset_in_buffer += memsize;
     }
 
     return written;
@@ -1179,16 +1202,19 @@ static int write_pointer_description_offsets(
     {
         if (offset_in_memory && offset_in_buffer)
         {
+            size_t memsize;
+
             /* pointer instance */
             /* FIXME: sometimes from end of structure, sometimes from beginning */
             print_file(file, 2, "NdrFcShort(0x%x), /* Memory offset = %d */\n", *offset_in_memory, *offset_in_memory);
             print_file(file, 2, "NdrFcShort(0x%x), /* Buffer offset = %d */\n", *offset_in_buffer, *offset_in_buffer);
 
             align = 0;
-            *offset_in_memory += type_memsize(type, &align);
-            /* FIXME: is there a case where these two are different? */
-            align = 0;
-            *offset_in_buffer += type_memsize(type, &align);
+            memsize = type_memsize(type, &align);
+            *offset_in_memory += memsize;
+            /* increment these separately as in the case of conformant (varying)
+             * structures these start at different values */
+            *offset_in_buffer += memsize;
         }
         *typestring_offset += 4;
 
@@ -1206,7 +1232,7 @@ static int write_pointer_description_offsets(
     {
         return write_pointer_description_offsets(
             file, attrs, type->ref, offset_in_memory, offset_in_buffer,
-                                                 typestring_offset);
+            typestring_offset);
     }
     else if (is_non_complex_struct(type))
     {
@@ -1214,6 +1240,15 @@ static int write_pointer_description_offsets(
         const var_t *v;
         LIST_FOR_EACH_ENTRY( v, type->fields_or_args, const var_t, entry )
         {
+            if (offset_in_memory && offset_in_buffer)
+            {
+                size_t padding;
+                align = 0;
+                type_memsize(v->type, &align);
+                padding = ROUNDING(*offset_in_memory, align);
+                *offset_in_memory += padding;
+                *offset_in_buffer += padding;
+            }
             written += write_pointer_description_offsets(
                 file, v->attrs, v->type, offset_in_memory, offset_in_buffer,
                 typestring_offset);
@@ -1221,13 +1256,16 @@ static int write_pointer_description_offsets(
     }
     else
     {
-        align = 0;
-        if (offset_in_memory)
-            *offset_in_memory += type_memsize(type, &align);
-        /* FIXME: is there a case where these two are different? */
-        align = 0;
-        if (offset_in_buffer)
-            *offset_in_buffer += type_memsize(type, &align);
+        if (offset_in_memory && offset_in_buffer)
+        {
+            size_t memsize;
+            align = 0;
+            memsize = type_memsize(type, &align);
+            *offset_in_memory += memsize;
+            /* increment these separately as in the case of conformant (varying)
+             * structures these start at different values */
+            *offset_in_buffer += memsize;
+        }
     }
 
     return written;
@@ -1277,6 +1315,15 @@ static int write_fixed_array_pointer_descriptions(
         const var_t *v;
         LIST_FOR_EACH_ENTRY( v, type->fields_or_args, const var_t, entry )
         {
+            if (offset_in_memory && offset_in_buffer)
+            {
+                size_t padding;
+                align = 0;
+                type_memsize(v->type, &align);
+                padding = ROUNDING(*offset_in_memory, align);
+                *offset_in_memory += padding;
+                *offset_in_buffer += padding;
+            }
             pointer_count += write_fixed_array_pointer_descriptions(
                 file, v->attrs, v->type, offset_in_memory, offset_in_buffer,
                 typestring_offset);
@@ -1284,13 +1331,16 @@ static int write_fixed_array_pointer_descriptions(
     }
     else
     {
-        align = 0;
-        if (offset_in_memory)
-            *offset_in_memory += type_memsize(type, &align);
-        /* FIXME: is there a case where these two are different? */
-        align = 0;
-        if (offset_in_buffer)
-            *offset_in_buffer += type_memsize(type, &align);
+        if (offset_in_memory && offset_in_buffer)
+        {
+            size_t memsize;
+            align = 0;
+            memsize = type_memsize(type, &align);
+            *offset_in_memory += memsize;
+            /* increment these separately as in the case of conformant (varying)
+             * structures these start at different values */
+            *offset_in_buffer += memsize;
+        }
     }
 
     return pointer_count;
@@ -1350,8 +1400,6 @@ static int write_varying_array_pointer_descriptions(
     unsigned int align;
     int pointer_count = 0;
 
-    /* FIXME: do varying array searching here, but pointer searching in write_pointer_description_offsets */
-
     if (is_array(type) && type->length_is)
     {
         unsigned int temp = 0;
@@ -1362,8 +1410,6 @@ static int write_varying_array_pointer_descriptions(
         if (pointer_count > 0)
         {
             unsigned int increment_size;
-            size_t offset_of_array_pointer_mem = 0;
-            size_t offset_of_array_pointer_buf = 0;
 
             align = 0;
             increment_size = type_memsize(type->ref, &align);
@@ -1379,8 +1425,8 @@ static int write_varying_array_pointer_descriptions(
             *typestring_offset += 8;
 
             pointer_count = write_pointer_description_offsets(
-                file, attrs, type, &offset_of_array_pointer_mem,
-                &offset_of_array_pointer_buf, typestring_offset);
+                file, attrs, type, offset_in_memory,
+                offset_in_buffer, typestring_offset);
         }
     }
     else if (is_struct(type->type))
@@ -1388,6 +1434,15 @@ static int write_varying_array_pointer_descriptions(
         const var_t *v;
         LIST_FOR_EACH_ENTRY( v, type->fields_or_args, const var_t, entry )
         {
+            if (offset_in_memory && offset_in_buffer)
+            {
+                size_t padding;
+                align = 0;
+                type_memsize(v->type, &align);
+                padding = ROUNDING(*offset_in_memory, align);
+                *offset_in_memory += padding;
+                *offset_in_buffer += padding;
+            }
             pointer_count += write_varying_array_pointer_descriptions(
                 file, v->attrs, v->type, offset_in_memory, offset_in_buffer,
                 typestring_offset);
@@ -1395,13 +1450,16 @@ static int write_varying_array_pointer_descriptions(
     }
     else
     {
-        align = 0;
-        if (offset_in_memory)
-            *offset_in_memory += type_memsize(type, &align);
-        /* FIXME: is there a case where these two are different? */
-        align = 0;
-        if (offset_in_buffer)
-            *offset_in_buffer += type_memsize(type, &align);
+        if (offset_in_memory && offset_in_buffer)
+        {
+            size_t memsize;
+            align = 0;
+            memsize = type_memsize(type, &align);
+            *offset_in_memory += memsize;
+            /* increment these separately as in the case of conformant (varying)
+             * structures these start at different values */
+            *offset_in_buffer += memsize;
+        }
     }
 
     return pointer_count;
@@ -1412,13 +1470,19 @@ static void write_pointer_description(FILE *file, type_t *type,
 {
     size_t offset_in_buffer;
     size_t offset_in_memory;
+    size_t conformance = 0;
+
+    if (type->type == RPC_FC_CVSTRUCT)
+        conformance = 8;
+    else if (type->type == RPC_FC_CSTRUCT || type->type == RPC_FC_CPSTRUCT)
+        conformance = 4;
 
     /* pass 1: search for single instance of a pointer (i.e. don't descend
      * into arrays) */
     if (!is_array(type))
     {
         offset_in_memory = 0;
-        offset_in_buffer = 0;
+        offset_in_buffer = conformance;
         write_no_repeat_pointer_descriptions(
             file, type,
             &offset_in_memory, &offset_in_buffer, typestring_offset);
@@ -1426,7 +1490,7 @@ static void write_pointer_description(FILE *file, type_t *type,
 
     /* pass 2: search for pointers in fixed arrays */
     offset_in_memory = 0;
-    offset_in_buffer = 0;
+    offset_in_buffer = conformance;
     write_fixed_array_pointer_descriptions(
         file, NULL, type,
         &offset_in_memory, &offset_in_buffer, typestring_offset);
@@ -1446,9 +1510,9 @@ static void write_pointer_description(FILE *file, type_t *type,
             typestring_offset);
     }
 
-   /* pass 4: search for pointers in varying arrays */
+    /* pass 4: search for pointers in varying arrays */
     offset_in_memory = 0;
-    offset_in_buffer = 0;
+    offset_in_buffer = conformance;
     write_varying_array_pointer_descriptions(
             file, NULL, type,
             &offset_in_memory, &offset_in_buffer, typestring_offset);
@@ -1709,7 +1773,7 @@ static void write_struct_members(FILE *file, const type_t *type,
                     error("write_struct_members: cannot align type %d\n", ft->type);
                 }
                 print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc));
-                offset = (offset + (align - 1)) & ~(align - 1);
+                offset = ROUND_SIZE(offset, align);
                 *typestring_offset += 1;
             }
             write_member_type(file, type, field->attrs, field->type, corroff,
@@ -1718,7 +1782,7 @@ static void write_struct_members(FILE *file, const type_t *type,
         }
     }
 
-    padding = ((offset + (salign - 1)) & ~(salign - 1)) - offset;
+    padding = ROUNDING(offset, salign);
     if (padding)
     {
         print_file(file, 2, "0x%x,\t/* FC_STRUCTPAD%d */\n",
index 4b67a5f..66a4fd5 100644 (file)
@@ -294,16 +294,23 @@ static int ctl2_encode_name(
 
     length = strlen(name);
     memcpy(converted_name + 4, name, length);
-    converted_name[0] = length & 0xff;
 
     converted_name[length + 4] = 0;
 
-    converted_name[1] = 0x00;
 
     value = lhash_val_of_name_sys(typelib->typelib_header.varflags & 0x0f, typelib->typelib_header.lcid, converted_name + 4);
 
+#ifdef WORDS_BIGENDIAN
+    converted_name[3] = length & 0xff;
+    converted_name[2] = 0x00;
+    converted_name[1] = value;
+    converted_name[0] = value >> 8;
+#else
+    converted_name[0] = length & 0xff;
+    converted_name[1] = 0x00;
     converted_name[2] = value;
     converted_name[3] = value >> 8;
+#endif
 
     for (offset = (4 - length) & 3; offset; offset--) converted_name[length + offset + 3] = 0x57;
 
@@ -337,8 +344,14 @@ static int ctl2_encode_string(
 
     length = strlen(string);
     memcpy(converted_string + 2, string, length);
+
+#ifdef WORDS_BIGENDIAN
+    converted_string[1] = length & 0xff;
+    converted_string[0] = (length >> 8) & 0xff;
+#else
     converted_string[0] = length & 0xff;
     converted_string[1] = (length >> 8) & 0xff;
+#endif
 
     if(length < 3) { /* strings of this length are padded with up to 8 bytes incl the 2 byte length */
         for(offset = 0; offset < 4; offset++)