Patchwork Go patch committed: More steps toward 64-bit int

login
register
mail settings
Submitter Ian Taylor
Date Nov. 1, 2012, 3:02 a.m.
Message ID <mcr7gq6nhzc.fsf@google.com>
Download mbox | patch
Permalink /patch/196075/
State New
Headers show

Comments

Ian Taylor - Nov. 1, 2012, 3:02 a.m.
This patch to the Go compiler and to libgo take some more steps toward
changing the type of int to be 64 bits on x86_64.  This patch changes
the runtime function RFT_INT argument to be the Go type int rather than
the C type int.  At the moment they are the same type but this will
change in the future.  This also changes the string and slice structures
to use the Go type int (known as intgo in the runtime library).  Doing
that required moving the string structure from go-string.h to runtime.h,
and while doing that I also changed the name and field names to match
those of the gc compiler, to make simplify future library merges.

The result is a large but mechanical patch.  Bootstrapped and ran Go
testsuite on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian

Patch

diff -r c4af1cde4722 go/expressions.cc
--- a/go/expressions.cc	Wed Oct 31 13:48:25 2012 -0700
+++ b/go/expressions.cc	Wed Oct 31 19:54:39 2012 -0700
@@ -1832,11 +1832,9 @@ 
       // some reason.  Use a type which will fit the value.  We use <,
       // not <=, because we need an extra bit for the sign bit.
       int bits = mpz_sizeinbase(this->val_, 2);
-      if (bits < INT_TYPE_SIZE)
-	{
-	  Type* t = Type::lookup_integer_type("int");
-	  type = type_to_tree(t->get_backend(gogo));
-	}
+      Type* int_type = Type::lookup_integer_type("int");
+      if (bits < int_type->integer_type()->bits())
+	type = type_to_tree(int_type->get_backend(gogo));
       else if (bits < 64)
 	{
 	  Type* t = Type::lookup_integer_type("int64");
@@ -3146,7 +3144,10 @@ 
   else if (type->is_string_type()
 	   && expr_type->integer_type() != NULL)
     {
-      expr_tree = fold_convert(integer_type_node, expr_tree);
+      Type* int_type = Type::lookup_integer_type("int");
+      tree int_type_tree = type_to_tree(int_type->get_backend(gogo));
+
+      expr_tree = fold_convert(int_type_tree, expr_tree);
       if (host_integerp(expr_tree, 0))
 	{
 	  HOST_WIDE_INT intval = tree_low_cst(expr_tree, 0);
@@ -3162,20 +3163,24 @@ 
 			       "__go_int_to_string",
 			       1,
 			       type_tree,
-			       integer_type_node,
-			       fold_convert(integer_type_node, expr_tree));
+			       int_type_tree,
+			       expr_tree);
     }
   else if (type->is_string_type() && expr_type->is_slice_type())
     {
       if (!DECL_P(expr_tree))
 	expr_tree = save_expr(expr_tree);
+
+      Type* int_type = Type::lookup_integer_type("int");
+      tree int_type_tree = type_to_tree(int_type->get_backend(gogo));
+
       Array_type* a = expr_type->array_type();
       Type* e = a->element_type()->forwarded();
       go_assert(e->integer_type() != NULL);
       tree valptr = fold_convert(const_ptr_type_node,
 				 a->value_pointer_tree(gogo, expr_tree));
       tree len = a->length_tree(gogo, expr_tree);
-      len = fold_convert_loc(this->location().gcc_location(), integer_type_node,
+      len = fold_convert_loc(this->location().gcc_location(), int_type_tree,
                              len);
       if (e->integer_type()->is_byte())
 	{
@@ -3187,7 +3192,7 @@ 
 				   type_tree,
 				   const_ptr_type_node,
 				   valptr,
-				   integer_type_node,
+				   int_type_tree,
 				   len);
 	}
       else
@@ -3201,7 +3206,7 @@ 
 				   type_tree,
 				   const_ptr_type_node,
 				   valptr,
-				   integer_type_node,
+				   int_type_tree,
 				   len);
 	}
     }
@@ -3939,6 +3944,7 @@ 
 tree
 Unary_expression::do_get_tree(Translate_context* context)
 {
+  Gogo* gogo = context->gogo();
   Location loc = this->location();
 
   // Taking the address of a set-and-use-temporary expression requires
@@ -4103,7 +4109,7 @@ 
 					       expr,
 					       fold_convert(TREE_TYPE(expr),
 							    null_pointer_node));
-		tree crash = Gogo::runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE,
+		tree crash = gogo->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE,
 						 loc);
 		expr = fold_build2_loc(loc.gcc_location(), COMPOUND_EXPR,
 				       TREE_TYPE(expr), build3(COND_EXPR,
@@ -4119,7 +4125,7 @@ 
 	if (VOID_TYPE_P(target_type_tree))
 	  {
 	    Type* pt = this->expr_->type()->points_to();
-	    tree ind = type_to_tree(pt->get_backend(context->gogo()));
+	    tree ind = type_to_tree(pt->get_backend(gogo));
 	    expr = fold_convert_loc(loc.gcc_location(),
                                     build_pointer_type(ind), expr);
 	  }
@@ -5668,6 +5674,8 @@ 
 tree
 Binary_expression::do_get_tree(Translate_context* context)
 {
+  Gogo* gogo = context->gogo();
+
   tree left = this->left_->get_tree(context);
   tree right = this->right_->get_tree(context);
 
@@ -5756,7 +5764,7 @@ 
     {
       go_assert(this->op_ == OPERATOR_PLUS);
       Type* st = Type::make_string_type();
-      tree string_type = type_to_tree(st->get_backend(context->gogo()));
+      tree string_type = type_to_tree(st->get_backend(gogo));
       static tree string_plus_decl;
       return Gogo::call_builtin(&string_plus_decl,
 				this->location(),
@@ -5859,7 +5867,7 @@ 
 	  // __go_runtime_error(RUNTIME_ERROR_DIVISION_BY_ZERO), 0
 	  int errcode = RUNTIME_ERROR_DIVISION_BY_ZERO;
 	  tree panic = fold_build2_loc(gccloc, COMPOUND_EXPR, TREE_TYPE(ret),
-				       Gogo::runtime_error(errcode,
+				       gogo->runtime_error(errcode,
 							   this->location()),
 				       fold_convert_loc(gccloc, TREE_TYPE(ret),
 							integer_zero_node));
@@ -6152,6 +6160,9 @@ 
 			    Type* right_type, tree right_tree,
 			    Location location)
 {
+  Type* int_type = Type::lookup_integer_type("int");
+  tree int_type_tree = type_to_tree(int_type->get_backend(context->gogo()));
+
   enum tree_code code;
   switch (op)
     {
@@ -6186,12 +6197,12 @@ 
 				     location,
 				     "__go_strcmp",
 				     2,
-				     integer_type_node,
+				     int_type_tree,
 				     string_type,
 				     left_tree,
 				     string_type,
 				     right_tree);
-      right_tree = build_int_cst_type(integer_type_node, 0);
+      right_tree = build_int_cst_type(int_type_tree, 0);
     }
   else if ((left_type->interface_type() != NULL
 	    && right_type->interface_type() == NULL
@@ -6248,7 +6259,7 @@ 
 					 location,
 					 "__go_empty_interface_value_compare",
 					 3,
-					 integer_type_node,
+					 int_type_tree,
 					 TREE_TYPE(left_tree),
 					 left_tree,
 					 TREE_TYPE(descriptor),
@@ -6267,7 +6278,7 @@ 
 					 location,
 					 "__go_interface_value_compare",
 					 3,
-					 integer_type_node,
+					 int_type_tree,
 					 TREE_TYPE(left_tree),
 					 left_tree,
 					 TREE_TYPE(descriptor),
@@ -6279,7 +6290,7 @@ 
 	  // This can panic if the type is not comparable.
 	  TREE_NOTHROW(interface_value_compare_decl) = 0;
 	}
-      right_tree = build_int_cst_type(integer_type_node, 0);
+      right_tree = build_int_cst_type(int_type_tree, 0);
 
       if (make_tmp != NULL_TREE)
 	left_tree = build2(COMPOUND_EXPR, TREE_TYPE(left_tree), make_tmp,
@@ -6296,7 +6307,7 @@ 
 					 location,
 					 "__go_empty_interface_compare",
 					 2,
-					 integer_type_node,
+					 int_type_tree,
 					 TREE_TYPE(left_tree),
 					 left_tree,
 					 TREE_TYPE(right_tree),
@@ -6314,7 +6325,7 @@ 
 					 location,
 					 "__go_interface_compare",
 					 2,
-					 integer_type_node,
+					 int_type_tree,
 					 TREE_TYPE(left_tree),
 					 left_tree,
 					 TREE_TYPE(right_tree),
@@ -6339,7 +6350,7 @@ 
 					 location,
 					 "__go_interface_empty_compare",
 					 2,
-					 integer_type_node,
+					 int_type_tree,
 					 TREE_TYPE(left_tree),
 					 left_tree,
 					 TREE_TYPE(right_tree),
@@ -6350,7 +6361,7 @@ 
 	  TREE_NOTHROW(interface_empty_compare_decl) = 0;
 	}
 
-      right_tree = build_int_cst_type(integer_type_node, 0);
+      right_tree = build_int_cst_type(int_type_tree, 0);
     }
 
   if (left_type->is_nil_type()
@@ -7869,6 +7880,9 @@ 
 	    arg_tree = build_fold_indirect_ref(arg_tree);
 	  }
 
+	Type* int_type = Type::lookup_integer_type("int");
+	tree int_type_tree = type_to_tree(int_type->get_backend(gogo));
+
 	tree val_tree;
 	if (this->code_ == BUILTIN_LEN)
 	  {
@@ -7893,7 +7907,7 @@ 
 					      location,
 					      "__go_map_len",
 					      1,
-					      integer_type_node,
+					      int_type_tree,
 					      arg_type_tree,
 					      arg_tree);
 	      }
@@ -7905,7 +7919,7 @@ 
 					      location,
 					      "__go_chan_len",
 					      1,
-					      integer_type_node,
+					      int_type_tree,
 					      arg_type_tree,
 					      arg_tree);
 	      }
@@ -7934,7 +7948,7 @@ 
 					      location,
 					      "__go_chan_cap",
 					      1,
-					      integer_type_node,
+					      int_type_tree,
 					      arg_type_tree,
 					      arg_tree);
 	      }
@@ -7942,15 +7956,8 @@ 
 	      go_unreachable();
 	  }
 
-	if (val_tree == error_mark_node)
-	  return error_mark_node;
-
-	Type* int_type = Type::lookup_integer_type("int");
-	tree type_tree = type_to_tree(int_type->get_backend(gogo));
-	if (type_tree == TREE_TYPE(val_tree))
-	  return val_tree;
-	else
-	  return fold(convert_to_integer(type_tree, val_tree));
+	return fold_convert_loc(location.gcc_location(), int_type_tree,
+				val_tree);
       }
 
     case BUILTIN_PRINT:
@@ -9872,7 +9879,7 @@ 
 	      : (this->end_ == NULL
 		 ? RUNTIME_ERROR_SLICE_INDEX_OUT_OF_BOUNDS
 		 : RUNTIME_ERROR_SLICE_SLICE_OUT_OF_BOUNDS));
-  tree crash = Gogo::runtime_error(code, loc);
+  tree crash = gogo->runtime_error(code, loc);
 
   if (this->end_ == NULL)
     {
@@ -10185,7 +10192,9 @@ 
 
   tree length_tree = String_type::length_tree(context->gogo(), string_tree);
   length_tree = save_expr(length_tree);
-  tree length_type = TREE_TYPE(length_tree);
+
+  Type* int_type = Type::lookup_integer_type("int");
+  tree length_type = type_to_tree(int_type->get_backend(context->gogo()));
 
   tree bad_index = boolean_false_node;
 
@@ -10205,7 +10214,7 @@ 
   int code = (this->end_ == NULL
 	      ? RUNTIME_ERROR_STRING_INDEX_OUT_OF_BOUNDS
 	      : RUNTIME_ERROR_STRING_SLICE_OUT_OF_BOUNDS);
-  tree crash = Gogo::runtime_error(code, loc);
+  tree crash = context->gogo()->runtime_error(code, loc);
 
   if (this->end_ == NULL)
     {
diff -r c4af1cde4722 go/gogo-tree.cc
--- a/go/gogo-tree.cc	Wed Oct 31 13:48:25 2012 -0700
+++ b/go/gogo-tree.cc	Wed Oct 31 19:54:39 2012 -0700
@@ -2331,14 +2331,17 @@ 
 tree
 Gogo::runtime_error(int code, Location location)
 {
+  Type* int32_type = Type::lookup_integer_type("int32");
+  tree int32_type_tree = type_to_tree(int32_type->get_backend(this));
+
   static tree runtime_error_fndecl;
   tree ret = Gogo::call_builtin(&runtime_error_fndecl,
 				location,
 				"__go_runtime_error",
 				1,
 				void_type_node,
-				integer_type_node,
-				build_int_cst(integer_type_node, code));
+				int32_type_tree,
+				build_int_cst(int32_type_tree, code));
   if (ret == error_mark_node)
     return error_mark_node;
   // The runtime error function panics and does not return.
diff -r c4af1cde4722 go/gogo.h
--- a/go/gogo.h	Wed Oct 31 13:48:25 2012 -0700
+++ b/go/gogo.h	Wed Oct 31 19:54:39 2012 -0700
@@ -558,7 +558,7 @@ 
 	       tree rettype, ...);
 
   // Build a call to the runtime error function.
-  static tree
+  tree
   runtime_error(int code, Location);
 
   // Build a builtin struct with a list of fields.
diff -r c4af1cde4722 go/runtime.cc
--- a/go/runtime.cc	Wed Oct 31 13:48:25 2012 -0700
+++ b/go/runtime.cc	Wed Oct 31 19:54:39 2012 -0700
@@ -30,7 +30,7 @@ 
   RFT_BOOL,
   // Go type *bool, C type _Bool*.
   RFT_BOOLPTR,
-  // Go type int, C type int.
+  // Go type int, C type intgo.
   RFT_INT,
   // Go type int32, C type int32_t.
   RFT_INT32,
diff -r c4af1cde4722 go/runtime.def
--- a/go/runtime.def	Wed Oct 31 13:48:25 2012 -0700
+++ b/go/runtime.def	Wed Oct 31 19:54:39 2012 -0700
@@ -198,7 +198,7 @@ 
 DEF_GO_RUNTIME(UNDEFER, "__go_undefer", P1(BOOLPTR), R0())
 
 // Panic with a runtime error.
-DEF_GO_RUNTIME(RUNTIME_ERROR, "__go_runtime_error", P1(INT), R0())
+DEF_GO_RUNTIME(RUNTIME_ERROR, "__go_runtime_error", P1(INT32), R0())
 
 
 // Close.
diff -r c4af1cde4722 go/types.cc
--- a/go/types.cc	Wed Oct 31 13:48:25 2012 -0700
+++ b/go/types.cc	Wed Oct 31 19:54:39 2012 -0700
@@ -2985,7 +2985,7 @@ 
   tree length_field = DECL_CHAIN(TYPE_FIELDS(string_type));
   go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(length_field)),
 		    "__length") == 0);
-  return fold_build3(COMPONENT_REF, integer_type_node, string,
+  return fold_build3(COMPONENT_REF, TREE_TYPE(length_field), string,
 		     length_field, NULL_TREE);
 }
 
@@ -5524,7 +5524,9 @@ 
 	  tree len = this->length_->get_tree(&context);
 	  if (len != error_mark_node)
 	    {
-	      len = convert_to_integer(integer_type_node, len);
+	      Type* int_type = Type::lookup_integer_type("int");
+	      tree int_type_tree = type_to_tree(int_type->get_backend(gogo));
+	      len = convert_to_integer(int_type_tree, len);
 	      len = save_expr(len);
 	    }
 	  this->length_tree_ = len;
@@ -5663,10 +5665,12 @@ 
   if (this->length_ != NULL)
     {
       if (TREE_CODE(array) == SAVE_EXPR)
-	return fold_convert(integer_type_node, this->get_length_tree(gogo));
+	return this->get_length_tree(gogo);
       else
-	return omit_one_operand(integer_type_node,
-				this->get_length_tree(gogo), array);
+	{
+	  tree len = this->get_length_tree(gogo);
+	  return omit_one_operand(TREE_TYPE(len), len, array);
+	}
     }
 
   // This is an open array.  We need to read the length field.
@@ -5690,8 +5694,10 @@ 
 Array_type::capacity_tree(Gogo* gogo, tree array)
 {
   if (this->length_ != NULL)
-    return omit_one_operand(integer_type_node, this->get_length_tree(gogo),
-			    array);
+    {
+      tree len = this->get_length_tree(gogo);
+      return omit_one_operand(TREE_TYPE(len), len, array);
+    }
 
   // This is an open array.  We need to read the capacity field.
 
diff -r c4af1cde4722 libgo/go/bytes/indexbyte.c
--- a/libgo/go/bytes/indexbyte.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/go/bytes/indexbyte.c	Wed Oct 31 19:54:39 2012 -0700
@@ -6,6 +6,7 @@ 
 
 #include <stddef.h>
 
+#include "runtime.h"
 #include "array.h"
 
 /* This is in C so that the compiler can optimize it appropriately.
diff -r c4af1cde4722 libgo/go/syscall/signame.c
--- a/libgo/go/syscall/signame.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/go/syscall/signame.c	Wed Oct 31 19:54:39 2012 -0700
@@ -6,7 +6,6 @@ 
 
 #include <string.h>
 
-#include "config.h"
 #include "runtime.h"
 #include "arch.h"
 #include "malloc.h"
@@ -19,7 +18,7 @@ 
   const char* s = NULL;
   char buf[100];
   size_t len;
-  unsigned char *data;
+  byte *data;
   String ret;
 
 #if defined(HAVE_STRSIGNAL)
@@ -34,7 +33,7 @@ 
   len = __builtin_strlen (s);
   data = runtime_mallocgc (len, FlagNoPointers, 0, 0);
   __builtin_memcpy (data, s, len);
-  ret.__data = data;
-  ret.__length = len;
+  ret.str = data;
+  ret.len = len;
   return ret;
 }
diff -r c4af1cde4722 libgo/runtime/array.h
--- a/libgo/runtime/array.h	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/array.h	Wed Oct 31 19:54:39 2012 -0700
@@ -19,10 +19,10 @@ 
      enough to hold the size of any allocated object.  Using "int"
      saves 8 bytes per slice header on a 64-bit system with 32-bit
      ints.  */
-  int __count;
+  intgo __count;
   /* The capacity of the array--the number of elements that can fit in
      the __VALUES field.  */
-  int __capacity;
+  intgo __capacity;
 };
 
 #endif /* !defined(LIBGO_ARRAY_H) */
diff -r c4af1cde4722 libgo/runtime/go-append.c
--- a/libgo/runtime/go-append.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-append.c	Wed Oct 31 19:54:39 2012 -0700
@@ -4,10 +4,10 @@ 
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
+#include "runtime.h"
+#include "go-panic.h"
 #include "go-type.h"
-#include "go-panic.h"
 #include "array.h"
-#include "runtime.h"
 #include "arch.h"
 #include "malloc.h"
 
diff -r c4af1cde4722 libgo/runtime/go-assert-interface.c
--- a/libgo/runtime/go-assert-interface.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-assert-interface.c	Wed Oct 31 19:54:39 2012 -0700
@@ -4,11 +4,12 @@ 
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
+#include "runtime.h"
 #include "go-alloc.h"
 #include "go-assert.h"
 #include "go-panic.h"
+#include "go-type.h"
 #include "interface.h"
-#include "runtime.h"
 
 /* This is called by the compiler to implement a type assertion from
    one interface type to another.  This returns the value that should
diff -r c4af1cde4722 libgo/runtime/go-byte-array-to-string.c
--- a/libgo/runtime/go-byte-array-to-string.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-byte-array-to-string.c	Wed Oct 31 19:54:39 2012 -0700
@@ -4,22 +4,21 @@ 
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
-#include "go-string.h"
 #include "runtime.h"
 #include "arch.h"
 #include "malloc.h"
 
-struct __go_string
-__go_byte_array_to_string (const void* p, int len)
+String
+__go_byte_array_to_string (const void* p, intgo len)
 {
   const unsigned char *bytes;
   unsigned char *retdata;
-  struct __go_string ret;
+  String ret;
 
   bytes = (const unsigned char *) p;
-  retdata = runtime_mallocgc (len, FlagNoPointers, 1, 0);
+  retdata = runtime_mallocgc ((uintptr) len, FlagNoPointers, 1, 0);
   __builtin_memcpy (retdata, bytes, len);
-  ret.__data = retdata;
-  ret.__length = len;
+  ret.str = retdata;
+  ret.len = len;
   return ret;
 }
diff -r c4af1cde4722 libgo/runtime/go-caller.c
--- a/libgo/runtime/go-caller.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-caller.c	Wed Oct 31 19:54:39 2012 -0700
@@ -11,7 +11,6 @@ 
 #include "backtrace.h"
 
 #include "runtime.h"
-#include "go-string.h"
 
 /* Get the function name, file name, and line number for a PC value.
    We use the backtrace library to get this.  */
@@ -20,9 +19,9 @@ 
 
 struct caller
 {
-  struct __go_string fn;
-  struct __go_string file;
-  int line;
+  String fn;
+  String file;
+  intgo line;
 };
 
 /* Collect file/line information for a PC value.  If this is called
@@ -37,32 +36,32 @@ 
 
   if (function == NULL)
     {
-      c->fn.__data = NULL;
-      c->fn.__length = 0;
+      c->fn.str = NULL;
+      c->fn.len = 0;
     }
   else
     {
-      char *s;
+      byte *s;
 
-      c->fn.__length = __builtin_strlen (function);
-      s = runtime_malloc (c->fn.__length);
-      __builtin_memcpy (s, function, c->fn.__length);
-      c->fn.__data = (unsigned char *) s;
+      c->fn.len = __builtin_strlen (function);
+      s = runtime_malloc (c->fn.len);
+      __builtin_memcpy (s, function, c->fn.len);
+      c->fn.str = s;
     }
 
   if (filename == NULL)
     {
-      c->file.__data = NULL;
-      c->file.__length = 0;
+      c->file.str = NULL;
+      c->file.len = 0;
     }
   else
     {
-      char *s;
+      byte *s;
 
-      c->file.__length = __builtin_strlen (filename);
-      s = runtime_malloc (c->file.__length);
-      __builtin_memcpy (s, filename, c->file.__length);
-      c->file.__data = (unsigned char *) s;
+      c->file.len = __builtin_strlen (filename);
+      s = runtime_malloc (c->file.len);
+      __builtin_memcpy (s, filename, c->file.len);
+      c->file.str = s;
     }
 
   c->line = lineno;
@@ -111,8 +110,7 @@ 
 /* Return function/file/line information for PC.  */
 
 _Bool
-__go_file_line (uintptr pc, struct __go_string *fn, struct __go_string *file,
-		int *line)
+__go_file_line (uintptr pc, String *fn, String *file, intgo *line)
 {
   struct caller c;
 
@@ -122,7 +120,7 @@ 
   *fn = c.fn;
   *file = c.file;
   *line = c.line;
-  return c.file.__length > 0;
+  return c.file.len > 0;
 }
 
 /* Collect symbol information.  */
@@ -153,8 +151,8 @@ 
 struct caller_ret
 {
   uintptr_t pc;
-  struct __go_string file;
-  int line;
+  String file;
+  intgo line;
   _Bool ok;
 };
 
@@ -170,7 +168,7 @@ 
   struct caller_ret ret;
   uintptr pc;
   int32 n;
-  struct __go_string fn;
+  String fn;
 
   runtime_memclr (&ret, sizeof ret);
   n = runtime_callers (skip + 1, &pc, 1);
@@ -188,9 +186,9 @@ 
 FuncForPC (uintptr_t pc)
 {
   Func *ret;
-  struct __go_string fn;
-  struct __go_string file;
-  int line;
+  String fn;
+  String file;
+  intgo line;
   uintptr_t val;
 
   if (!__go_file_line (pc, &fn, &file, &line))
@@ -212,8 +210,8 @@ 
 
 struct funcline_go_return
 {
-  struct __go_string retfile;
-  int retline;
+  String retfile;
+  intgo retline;
 };
 
 struct funcline_go_return
@@ -224,7 +222,7 @@ 
 runtime_funcline_go (Func *f __attribute__((unused)), uintptr targetpc)
 {
   struct funcline_go_return ret;
-  struct __go_string fn;
+  String fn;
 
   if (!__go_file_line (targetpc, &fn, &ret.retfile,  &ret.retline))
     runtime_memclr (&ret, sizeof ret);
diff -r c4af1cde4722 libgo/runtime/go-callers.c
--- a/libgo/runtime/go-callers.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-callers.c	Wed Oct 31 19:54:39 2012 -0700
@@ -9,6 +9,7 @@ 
 #include "backtrace.h"
 
 #include "runtime.h"
+#include "array.h"
 
 /* Argument passed to callback function.  */
 
diff -r c4af1cde4722 libgo/runtime/go-can-convert-interface.c
--- a/libgo/runtime/go-can-convert-interface.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-can-convert-interface.c	Wed Oct 31 19:54:39 2012 -0700
@@ -4,7 +4,9 @@ 
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
+#include "runtime.h"
 #include "go-assert.h"
+#include "go-string.h"
 #include "go-type.h"
 #include "interface.h"
 
diff -r c4af1cde4722 libgo/runtime/go-cgo.c
--- a/libgo/runtime/go-cgo.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-cgo.c	Wed Oct 31 19:54:39 2012 -0700
@@ -8,7 +8,6 @@ 
 #include "go-alloc.h"
 #include "interface.h"
 #include "go-panic.h"
-#include "go-string.h"
 
 /* Go memory allocated by code not written in Go.  We keep a linked
    list of these allocations so that the garbage collector can see
@@ -135,9 +134,9 @@ 
 void
 _cgo_panic (const char *p)
 {
-  int len;
+  intgo len;
   unsigned char *data;
-  struct __go_string *ps;
+  String *ps;
   struct __go_empty_interface e;
 
   runtime_exitsyscall ();
@@ -145,8 +144,8 @@ 
   data = alloc_saved (len);
   __builtin_memcpy (data, p, len);
   ps = alloc_saved (sizeof *ps);
-  ps->__data = data;
-  ps->__length = len;
+  ps->str = data;
+  ps->len = len;
   e.__type_descriptor = &string_type_descriptor;
   e.__object = ps;
 
diff -r c4af1cde4722 libgo/runtime/go-check-interface.c
--- a/libgo/runtime/go-check-interface.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-check-interface.c	Wed Oct 31 19:54:39 2012 -0700
@@ -4,9 +4,10 @@ 
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
+#include "runtime.h"
 #include "go-panic.h"
+#include "go-type.h"
 #include "interface.h"
-#include "runtime.h"
 
 /* Check that an interface type matches for a conversion to a
    non-interface type.  This panics if the types are bad.  The actual
diff -r c4af1cde4722 libgo/runtime/go-construct-map.c
--- a/libgo/runtime/go-construct-map.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-construct-map.c	Wed Oct 31 19:54:39 2012 -0700
@@ -8,6 +8,7 @@ 
 #include <stdint.h>
 #include <stdlib.h>
 
+#include "runtime.h"
 #include "map.h"
 
 struct __go_map *
diff -r c4af1cde4722 libgo/runtime/go-convert-interface.c
--- a/libgo/runtime/go-convert-interface.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-convert-interface.c	Wed Oct 31 19:54:39 2012 -0700
@@ -4,11 +4,13 @@ 
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
+#include "runtime.h"
 #include "go-alloc.h"
 #include "go-assert.h"
 #include "go-panic.h"
+#include "go-string.h"
+#include "go-type.h"
 #include "interface.h"
-#include "runtime.h"
 
 /* This is called when converting one interface type into another
    interface type.  LHS_DESCRIPTOR is the type descriptor of the
diff -r c4af1cde4722 libgo/runtime/go-eface-compare.c
--- a/libgo/runtime/go-eface-compare.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-eface-compare.c	Wed Oct 31 19:54:39 2012 -0700
@@ -5,12 +5,13 @@ 
    license that can be found in the LICENSE file.  */
 
 #include "runtime.h"
+#include "go-type.h"
 #include "interface.h"
 
 /* Compare two interface values.  Return 0 for equal, not zero for not
    equal (return value is like strcmp).  */
 
-int
+intgo
 __go_empty_interface_compare (struct __go_empty_interface left,
 			      struct __go_empty_interface right)
 {
diff -r c4af1cde4722 libgo/runtime/go-eface-val-compare.c
--- a/libgo/runtime/go-eface-val-compare.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-eface-val-compare.c	Wed Oct 31 19:54:39 2012 -0700
@@ -11,7 +11,7 @@ 
 /* Compare an empty interface with a value.  Return 0 for equal, not
    zero for not equal (return value is like strcmp).  */
 
-int
+intgo
 __go_empty_interface_value_compare (
     struct __go_empty_interface left,
     const struct __go_type_descriptor *right_descriptor,
diff -r c4af1cde4722 libgo/runtime/go-getgoroot.c
--- a/libgo/runtime/go-getgoroot.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-getgoroot.c	Wed Oct 31 19:54:39 2012 -0700
@@ -6,21 +6,21 @@ 
 
 #include <stdlib.h>
 
-#include "go-string.h"
+#include "runtime.h"
 
-struct __go_string getgoroot (void) asm ("runtime.getgoroot");
+String getgoroot (void) asm ("runtime.getgoroot");
 
-struct __go_string
+String
 getgoroot ()
 {
   const char *p;
-  struct __go_string ret;
+  String ret;
 
   p = getenv ("GOROOT");
-  ret.__data = (const unsigned char *) p;
-  if (ret.__data == NULL)
-    ret.__length = 0;
+  ret.str = (const byte *) p;
+  if (ret.str == NULL)
+    ret.len = 0;
   else
-    ret.__length = __builtin_strlen (p);
+    ret.len = __builtin_strlen (p);
   return ret;
 }
diff -r c4af1cde4722 libgo/runtime/go-int-array-to-string.c
--- a/libgo/runtime/go-int-array-to-string.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-int-array-to-string.c	Wed Oct 31 19:54:39 2012 -0700
@@ -5,31 +5,30 @@ 
    license that can be found in the LICENSE file.  */
 
 #include "go-assert.h"
-#include "go-string.h"
 #include "runtime.h"
 #include "arch.h"
 #include "malloc.h"
 
-struct __go_string
-__go_int_array_to_string (const void* p, int len)
+String
+__go_int_array_to_string (const void* p, intgo len)
 {
-  const int *ints;
-  int slen;
-  int i;
+  const int32 *ints;
+  intgo slen;
+  intgo i;
   unsigned char *retdata;
-  struct __go_string ret;
+  String ret;
   unsigned char *s;
 
-  ints = (const int *) p;
+  ints = (const int32 *) p;
 
   slen = 0;
   for (i = 0; i < len; ++i)
     {
-      int v;
+      int32 v;
 
       v = ints[i];
 
-      if (v > 0x10ffff)
+      if (v < 0 || v > 0x10ffff)
 	v = 0xfffd;
 
       if (v <= 0x7f)
@@ -42,20 +41,20 @@ 
 	slen += 4;
     }
 
-  retdata = runtime_mallocgc (slen, FlagNoPointers, 1, 0);
-  ret.__data = retdata;
-  ret.__length = slen;
+  retdata = runtime_mallocgc ((uintptr) slen, FlagNoPointers, 1, 0);
+  ret.str = retdata;
+  ret.len = slen;
 
   s = retdata;
   for (i = 0; i < len; ++i)
     {
-      int v;
+      int32 v;
 
       v = ints[i];
 
       /* If V is out of range for UTF-8, substitute the replacement
 	 character.  */
-      if (v > 0x10ffff)
+      if (v < 0 || v > 0x10ffff)
 	v = 0xfffd;
 
       if (v <= 0x7f)
diff -r c4af1cde4722 libgo/runtime/go-int-to-string.c
--- a/libgo/runtime/go-int-to-string.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-int-to-string.c	Wed Oct 31 19:54:39 2012 -0700
@@ -4,18 +4,17 @@ 
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
-#include "go-string.h"
 #include "runtime.h"
 #include "arch.h"
 #include "malloc.h"
 
-struct __go_string
-__go_int_to_string (int v)
+String
+__go_int_to_string (intgo v)
 {
   char buf[4];
   int len;
   unsigned char *retdata;
-  struct __go_string ret;
+  String ret;
 
   /* A negative value is not valid UTF-8; turn it into the replacement
      character.  */
@@ -63,8 +62,8 @@ 
 
   retdata = runtime_mallocgc (len, FlagNoPointers, 1, 0);
   __builtin_memcpy (retdata, buf, len);
-  ret.__data = retdata;
-  ret.__length = len;
+  ret.str = retdata;
+  ret.len = len;
 
   return ret;
 }
diff -r c4af1cde4722 libgo/runtime/go-interface-compare.c
--- a/libgo/runtime/go-interface-compare.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-interface-compare.c	Wed Oct 31 19:54:39 2012 -0700
@@ -4,6 +4,10 @@ 
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
+#include <stddef.h>
+
+#include "runtime.h"
+#include "go-type.h"
 #include "interface.h"
 
 /* Compare two interface values.  Return 0 for equal, not zero for not
diff -r c4af1cde4722 libgo/runtime/go-interface-eface-compare.c
--- a/libgo/runtime/go-interface-eface-compare.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-interface-eface-compare.c	Wed Oct 31 19:54:39 2012 -0700
@@ -5,13 +5,14 @@ 
    license that can be found in the LICENSE file.  */
 
 #include "runtime.h"
+#include "go-type.h"
 #include "interface.h"
 
 /* Compare a non-empty interface value with an empty interface value.
    Return 0 for equal, not zero for not equal (return value is like
    strcmp).  */
 
-int
+intgo
 __go_interface_empty_compare (struct __go_interface left,
 			      struct __go_empty_interface right)
 {
diff -r c4af1cde4722 libgo/runtime/go-interface-val-compare.c
--- a/libgo/runtime/go-interface-val-compare.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-interface-val-compare.c	Wed Oct 31 19:54:39 2012 -0700
@@ -4,13 +4,14 @@ 
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
+#include "runtime.h"
 #include "go-type.h"
 #include "interface.h"
 
 /* Compare two interface values.  Return 0 for equal, not zero for not
    equal (return value is like strcmp).  */
 
-int
+intgo
 __go_interface_value_compare (
     struct __go_interface left,
     const struct __go_type_descriptor *right_descriptor,
diff -r c4af1cde4722 libgo/runtime/go-main.c
--- a/libgo/runtime/go-main.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-main.c	Wed Oct 31 19:54:39 2012 -0700
@@ -14,11 +14,9 @@ 
 #include <fpu_control.h>
 #endif
 
+#include "runtime.h"
 #include "go-alloc.h"
 #include "array.h"
-#include "go-string.h"
-
-#include "runtime.h"
 #include "arch.h"
 #include "malloc.h"
 
diff -r c4af1cde4722 libgo/runtime/go-make-slice.c
--- a/libgo/runtime/go-make-slice.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-make-slice.c	Wed Oct 31 19:54:39 2012 -0700
@@ -6,12 +6,12 @@ 
 
 #include <stdint.h>
 
+#include "runtime.h"
 #include "go-alloc.h"
 #include "go-assert.h"
 #include "go-panic.h"
 #include "go-type.h"
 #include "array.h"
-#include "runtime.h"
 #include "arch.h"
 #include "malloc.h"
 
@@ -20,8 +20,8 @@ 
 		  uintptr_t cap)
 {
   const struct __go_slice_type* std;
-  int ilen;
-  int icap;
+  intgo ilen;
+  intgo icap;
   uintptr_t size;
   struct __go_open_array ret;
   unsigned int flag;
@@ -29,11 +29,11 @@ 
   __go_assert (td->__code == GO_SLICE);
   std = (const struct __go_slice_type *) td;
 
-  ilen = (int) len;
+  ilen = (intgo) len;
   if (ilen < 0 || (uintptr_t) ilen != len)
     runtime_panicstring ("makeslice: len out of range");
 
-  icap = (int) cap;
+  icap = (intgo) cap;
   if (cap < len
       || (uintptr_t) icap != cap
       || (std->__element_type->__size > 0
diff -r c4af1cde4722 libgo/runtime/go-map-len.c
--- a/libgo/runtime/go-map-len.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-map-len.c	Wed Oct 31 19:54:39 2012 -0700
@@ -6,6 +6,7 @@ 
 
 #include <stddef.h>
 
+#include "runtime.h"
 #include "go-assert.h"
 #include "map.h"
 
@@ -13,11 +14,12 @@ 
    but I'm doing it as a function for now to make it easy to change
    the map structure.  */
 
-int
+intgo
 __go_map_len (struct __go_map *map)
 {
   if (map == NULL)
     return 0;
-  __go_assert (map->__element_count == (uintptr_t) (int) map->__element_count);
+  __go_assert (map->__element_count
+	       == (uintptr_t) (intgo) map->__element_count);
   return map->__element_count;
 }
diff -r c4af1cde4722 libgo/runtime/go-map-range.c
--- a/libgo/runtime/go-map-range.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-map-range.c	Wed Oct 31 19:54:39 2012 -0700
@@ -4,6 +4,7 @@ 
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
+#include "runtime.h"
 #include "go-assert.h"
 #include "map.h"
 
diff -r c4af1cde4722 libgo/runtime/go-new-map.c
--- a/libgo/runtime/go-new-map.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-new-map.c	Wed Oct 31 19:54:39 2012 -0700
@@ -106,10 +106,10 @@ 
 struct __go_map *
 __go_new_map (const struct __go_map_descriptor *descriptor, uintptr_t entries)
 {
-  int ientries;
+  intgo ientries;
   struct __go_map *ret;
 
-  ientries = (int) entries;
+  ientries = (intgo) entries;
   if (ientries < 0 || (uintptr_t) ientries != entries)
     runtime_panicstring ("map size out of range");
 
diff -r c4af1cde4722 libgo/runtime/go-panic.c
--- a/libgo/runtime/go-panic.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-panic.c	Wed Oct 31 19:54:39 2012 -0700
@@ -13,7 +13,6 @@ 
 #include "go-alloc.h"
 #include "go-defer.h"
 #include "go-panic.h"
-#include "go-string.h"
 #include "interface.h"
 
 /* Print the panic stack.  This is used when there is no recover.  */
diff -r c4af1cde4722 libgo/runtime/go-panic.h
--- a/libgo/runtime/go-panic.h	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-panic.h	Wed Oct 31 19:54:39 2012 -0700
@@ -9,7 +9,7 @@ 
 
 #include "interface.h"
 
-struct __go_string;
+struct String;
 struct __go_type_descriptor;
 struct __go_defer_stack;
 
@@ -34,7 +34,7 @@ 
 extern void __go_panic (struct __go_empty_interface)
   __attribute__ ((noreturn));
 
-extern void __go_print_string (struct __go_string);
+extern void __go_print_string (struct String);
 
 extern struct __go_empty_interface __go_recover (void);
 
diff -r c4af1cde4722 libgo/runtime/go-print.c
--- a/libgo/runtime/go-print.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-print.c	Wed Oct 31 19:54:39 2012 -0700
@@ -11,7 +11,6 @@ 
 #include "runtime.h"
 #include "array.h"
 #include "go-panic.h"
-#include "go-string.h"
 #include "interface.h"
 
 /* This implements the various little functions which are called by
diff -r c4af1cde4722 libgo/runtime/go-reflect-call.c
--- a/libgo/runtime/go-reflect-call.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-reflect-call.c	Wed Oct 31 19:54:39 2012 -0700
@@ -8,12 +8,10 @@ 
 #include <stdint.h>
 #include <stdlib.h>
 
-#include "config.h"
-
+#include "runtime.h"
 #include "go-alloc.h"
 #include "go-assert.h"
 #include "go-type.h"
-#include "runtime.h"
 
 #ifdef USE_LIBFFI
 
@@ -77,13 +75,15 @@ 
     const struct __go_slice_type *descriptor __attribute__ ((unused)))
 {
   ffi_type *ret;
+  ffi_type *intgo;
 
   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
   ret->type = FFI_TYPE_STRUCT;
   ret->elements = (ffi_type **) __go_alloc (4 * sizeof (ffi_type *));
   ret->elements[0] = &ffi_type_pointer;
-  ret->elements[1] = &ffi_type_sint;
-  ret->elements[2] = &ffi_type_sint;
+  intgo = sizeof (intgo) == 4 ? &ffi_type_sint32 : &ffi_type_sint64;
+  ret->elements[1] = intgo;
+  ret->elements[2] = intgo;
   ret->elements[3] = NULL;
   return ret;
 }
@@ -110,19 +110,21 @@ 
   return ret;
 }
 
-/* Return an ffi_type for a Go string type.  This describes the
-   __go_string struct.  */
+/* Return an ffi_type for a Go string type.  This describes the String
+   struct.  */
 
 static ffi_type *
 go_string_to_ffi (void)
 {
   ffi_type *ret;
+  ffi_type *intgo;
 
   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
   ret->type = FFI_TYPE_STRUCT;
   ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
   ret->elements[0] = &ffi_type_pointer;
-  ret->elements[1] = &ffi_type_sint;
+  intgo = sizeof (intgo) == 4 ? &ffi_type_sint32 : &ffi_type_sint64;
+  ret->elements[1] = intgo;
   ret->elements[2] = NULL;
   return ret;
 }
@@ -199,7 +201,7 @@ 
     case GO_INT8:
       return &ffi_type_sint8;
     case GO_INT:
-      return &ffi_type_sint;
+      return sizeof (intgo) == 4 ? &ffi_type_sint32 : &ffi_type_sint64;
     case GO_UINT16:
       return &ffi_type_uint16;
     case GO_UINT32:
@@ -209,7 +211,7 @@ 
     case GO_UINT8:
       return &ffi_type_uint8;
     case GO_UINT:
-      return &ffi_type_uint;
+      return sizeof (uintgo) == 4 ? &ffi_type_uint32 : &ffi_type_uint64;
     case GO_UINTPTR:
       if (sizeof (void *) == 2)
 	return &ffi_type_uint16;
diff -r c4af1cde4722 libgo/runtime/go-rune.c
--- a/libgo/runtime/go-rune.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-rune.c	Wed Oct 31 19:54:39 2012 -0700
@@ -6,6 +6,7 @@ 
 
 #include <stddef.h>
 
+#include "runtime.h"
 #include "go-string.h"
 
 /* Get a character from the UTF-8 string STR, of length LEN.  Store
diff -r c4af1cde4722 libgo/runtime/go-runtime-error.c
--- a/libgo/runtime/go-runtime-error.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-runtime-error.c	Wed Oct 31 19:54:39 2012 -0700
@@ -55,7 +55,7 @@ 
 extern void __go_runtime_error () __attribute__ ((noreturn));
 
 void
-__go_runtime_error (int i)
+__go_runtime_error (int32 i)
 {
   switch (i)
     {
diff -r c4af1cde4722 libgo/runtime/go-setenv.c
--- a/libgo/runtime/go-setenv.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-setenv.c	Wed Oct 31 19:54:39 2012 -0700
@@ -10,39 +10,38 @@ 
 #include <stdlib.h>
 
 #include "go-alloc.h"
-#include "go-string.h"
+#include "runtime.h"
 
 /* Set the C environment from Go.  This is called by syscall.Setenv.  */
 
-void setenv_c (struct __go_string, struct __go_string)
-  __asm__ ("syscall.setenv_c");
+void setenv_c (String, String) __asm__ ("syscall.setenv_c");
 
 void
-setenv_c (struct __go_string k, struct __go_string v)
+setenv_c (String k, String v)
 {
-  const unsigned char *ks;
+  const byte *ks;
   unsigned char *kn;
-  const unsigned char *vs;
+  const byte *vs;
   unsigned char *vn;
 
-  ks = k.__data;
+  ks = k.str;
   kn = NULL;
-  vs = v.__data;
+  vs = v.str;
   vn = NULL;
 
 #ifdef HAVE_SETENV
 
-  if (ks[k.__length] != 0)
+  if (ks[k.len] != 0)
     {
-      kn = __go_alloc (k.__length + 1);
-      __builtin_memcpy (kn, ks, k.__length);
+      kn = __go_alloc (k.len + 1);
+      __builtin_memcpy (kn, ks, k.len);
       ks = kn;
     }
 
-  if (vs[v.__length] != 0)
+  if (vs[v.len] != 0)
     {
-      vn = __go_alloc (v.__length + 1);
-      __builtin_memcpy (vn, vs, v.__length);
+      vn = __go_alloc (v.len + 1);
+      __builtin_memcpy (vn, vs, v.len);
       vs = vn;
     }
 
@@ -50,11 +49,11 @@ 
 
 #else /* !defined(HAVE_SETENV) */
 
-  kn = __go_alloc (k.__length + v.__length + 2);
-  __builtin_memcpy (kn, ks, k.__length);
-  kn[k.__length] = '=';
-  __builtin_memcpy (kn + k.__length + 1, vs, v.__length);
-  kn[k.__length + v.__length + 1] = '\0';
+  kn = __go_alloc (k.len + v.len + 2);
+  __builtin_memcpy (kn, ks, k.len);
+  kn[k.len] = '=';
+  __builtin_memcpy (kn + k.len + 1, vs, v.len);
+  kn[k.len + v.len + 1] = '\0';
   putenv ((char *) kn);
 
 #endif /* !defined(HAVE_SETENV) */
diff -r c4af1cde4722 libgo/runtime/go-strcmp.c
--- a/libgo/runtime/go-strcmp.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-strcmp.c	Wed Oct 31 19:54:39 2012 -0700
@@ -4,23 +4,21 @@ 
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
-#include "go-string.h"
+#include "runtime.h"
 
-int
-__go_strcmp(struct __go_string s1, struct __go_string s2)
+intgo
+__go_strcmp(String s1, String s2)
 {
   int i;
 
-  i = __builtin_memcmp(s1.__data, s2.__data,
-		       (s1.__length < s2.__length
-			? s1.__length
-			: s2.__length));
+  i = __builtin_memcmp(s1.str, s2.str,
+		       (s1.len < s2.len ? s1.len : s2.len));
   if (i != 0)
     return i;
 
-  if (s1.__length < s2.__length)
+  if (s1.len < s2.len)
     return -1;
-  else if (s1.__length > s2.__length)
+  else if (s1.len > s2.len)
     return 1;
   else
     return 0;
diff -r c4af1cde4722 libgo/runtime/go-string-to-byte-array.c
--- a/libgo/runtime/go-string-to-byte-array.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-string-to-byte-array.c	Wed Oct 31 19:54:39 2012 -0700
@@ -4,22 +4,21 @@ 
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
-#include "go-string.h"
+#include "runtime.h"
 #include "array.h"
-#include "runtime.h"
 #include "arch.h"
 #include "malloc.h"
 
 struct __go_open_array
-__go_string_to_byte_array (struct __go_string str)
+__go_string_to_byte_array (String str)
 {
   unsigned char *data;
   struct __go_open_array ret;
 
-  data = (unsigned char *) runtime_mallocgc (str.__length, FlagNoPointers, 1, 0);
-  __builtin_memcpy (data, str.__data, str.__length);
+  data = (unsigned char *) runtime_mallocgc (str.len, FlagNoPointers, 1, 0);
+  __builtin_memcpy (data, str.str, str.len);
   ret.__values = (void *) data;
-  ret.__count = str.__length;
-  ret.__capacity = str.__length;
+  ret.__count = str.len;
+  ret.__capacity = str.len;
   return ret;
 }
diff -r c4af1cde4722 libgo/runtime/go-string-to-int-array.c
--- a/libgo/runtime/go-string-to-int-array.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-string-to-int-array.c	Wed Oct 31 19:54:39 2012 -0700
@@ -4,15 +4,15 @@ 
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
+#include "runtime.h"
 #include "go-alloc.h"
 #include "go-string.h"
 #include "array.h"
-#include "runtime.h"
 #include "arch.h"
 #include "malloc.h"
 
 struct __go_open_array
-__go_string_to_int_array (struct __go_string str)
+__go_string_to_int_array (String str)
 {
   size_t c;
   const unsigned char *p;
@@ -22,8 +22,8 @@ 
   struct __go_open_array ret;
 
   c = 0;
-  p = str.__data;
-  pend = p + str.__length;
+  p = str.str;
+  pend = p + str.len;
   while (p < pend)
     {
       int rune;
@@ -34,7 +34,7 @@ 
 
   data = (uint32_t *) runtime_mallocgc (c * sizeof (uint32_t), FlagNoPointers,
 					1, 0);
-  p = str.__data;
+  p = str.str;
   pd = data;
   while (p < pend)
     {
diff -r c4af1cde4722 libgo/runtime/go-string.h
--- a/libgo/runtime/go-string.h	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-string.h	Wed Oct 31 19:54:39 2012 -0700
@@ -9,26 +9,15 @@ 
 
 #include <stddef.h>
 
-/* A string is an instance of this structure.  */
-
-struct __go_string
+static inline _Bool
+__go_strings_equal (String s1, String s2)
 {
-  /* The bytes.  */
-  const unsigned char *__data;
-  /* The length.  */
-  int __length;
-};
-
-static inline _Bool
-__go_strings_equal (struct __go_string s1, struct __go_string s2)
-{
-  return (s1.__length == s2.__length
-	  && __builtin_memcmp (s1.__data, s2.__data, s1.__length) == 0);
+  return (s1.len == s2.len
+	  && __builtin_memcmp (s1.str, s2.str, s1.len) == 0);
 }
 
 static inline _Bool
-__go_ptr_strings_equal (const struct __go_string *ps1,
-			const struct __go_string *ps2)
+__go_ptr_strings_equal (const String *ps1, const String *ps2)
 {
   if (ps1 == NULL)
     return ps2 == NULL;
diff -r c4af1cde4722 libgo/runtime/go-strplus.c
--- a/libgo/runtime/go-strplus.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-strplus.c	Wed Oct 31 19:54:39 2012 -0700
@@ -4,28 +4,27 @@ 
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
-#include "go-string.h"
 #include "runtime.h"
 #include "arch.h"
 #include "malloc.h"
 
-struct __go_string
-__go_string_plus (struct __go_string s1, struct __go_string s2)
+String
+__go_string_plus (String s1, String s2)
 {
   int len;
-  unsigned char *retdata;
-  struct __go_string ret;
+  byte *retdata;
+  String ret;
 
-  if (s1.__length == 0)
+  if (s1.len == 0)
     return s2;
-  else if (s2.__length == 0)
+  else if (s2.len == 0)
     return s1;
 
-  len = s1.__length + s2.__length;
+  len = s1.len + s2.len;
   retdata = runtime_mallocgc (len, FlagNoPointers, 1, 0);
-  __builtin_memcpy (retdata, s1.__data, s1.__length);
-  __builtin_memcpy (retdata + s1.__length, s2.__data, s2.__length);
-  ret.__data = retdata;
-  ret.__length = len;
+  __builtin_memcpy (retdata, s1.str, s1.len);
+  __builtin_memcpy (retdata + s1.len, s2.str, s2.len);
+  ret.str = retdata;
+  ret.len = len;
   return ret;
 }
diff -r c4af1cde4722 libgo/runtime/go-strslice.c
--- a/libgo/runtime/go-strslice.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-strslice.c	Wed Oct 31 19:54:39 2012 -0700
@@ -4,24 +4,23 @@ 
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
-#include "go-string.h"
 #include "go-panic.h"
 #include "runtime.h"
 #include "arch.h"
 #include "malloc.h"
 
-struct __go_string
-__go_string_slice (struct __go_string s, int start, int end)
+String
+__go_string_slice (String s, intgo start, intgo end)
 {
-  int len;
-  struct __go_string ret;
+  intgo len;
+  String ret;
 
-  len = s.__length;
+  len = s.len;
   if (end == -1)
     end = len;
   if (start > len || end < start || end > len)
     runtime_panicstring ("string index out of bounds");
-  ret.__data = s.__data + start;
-  ret.__length = end - start;
+  ret.str = s.str + start;
+  ret.len = end - start;
   return ret;
 }
diff -r c4af1cde4722 libgo/runtime/go-traceback.c
--- a/libgo/runtime/go-traceback.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-traceback.c	Wed Oct 31 19:54:39 2012 -0700
@@ -7,7 +7,6 @@ 
 #include "config.h"
 
 #include "runtime.h"
-#include "go-string.h"
 
 /* Print a stack trace for the current goroutine.  */
 
@@ -28,12 +27,12 @@ 
 
   for (i = 0; i < c; ++i)
     {
-      struct __go_string fn;
-      struct __go_string file;
+      String fn;
+      String file;
       int line;
 
       if (__go_file_line (pcbuf[i], &fn, &file, &line)
-	  && runtime_showframe (fn.__data))
+	  && runtime_showframe (fn.str))
 	{
 	  runtime_printf ("%S\n", fn);
 	  runtime_printf ("\t%S:%d\n", file, line);
diff -r c4af1cde4722 libgo/runtime/go-type-identity.c
--- a/libgo/runtime/go-type-identity.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-type-identity.c	Wed Oct 31 19:54:39 2012 -0700
@@ -6,13 +6,9 @@ 
 
 #include <stddef.h>
 
-#include "config.h"
+#include "runtime.h"
 #include "go-type.h"
 
-/* The 64-bit type.  */
-
-typedef unsigned int DItype __attribute__ ((mode (DI)));
-
 /* An identity hash function for a type.  This is used for types where
    we can simply use the type value itself as a hash code.  This is
    true of, e.g., integers and pointers.  */
@@ -28,7 +24,7 @@ 
     {
       union
       {
-	DItype v;
+	uint64 v;
 	unsigned char a[8];
       } u;
       u.v = 0;
diff -r c4af1cde4722 libgo/runtime/go-type-interface.c
--- a/libgo/runtime/go-type-interface.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-type-interface.c	Wed Oct 31 19:54:39 2012 -0700
@@ -4,6 +4,7 @@ 
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
+#include "runtime.h"
 #include "interface.h"
 #include "go-type.h"
 
diff -r c4af1cde4722 libgo/runtime/go-type-string.c
--- a/libgo/runtime/go-type-string.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-type-string.c	Wed Oct 31 19:54:39 2012 -0700
@@ -4,10 +4,9 @@ 
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
-#include <stddef.h>
-
+#include "runtime.h"
+#include "go-type.h"
 #include "go-string.h"
-#include "go-type.h"
 
 /* A string hash function for a map.  */
 
@@ -16,15 +15,15 @@ 
 		       uintptr_t key_size __attribute__ ((unused)))
 {
   uintptr_t ret;
-  const struct __go_string *key;
-  int len;
-  int i;
-  const unsigned char *p;
+  const String *key;
+  intgo len;
+  intgo i;
+  const byte *p;
 
   ret = 5381;
-  key = (const struct __go_string *) vkey;
-  len = key->__length;
-  for (i = 0, p = key->__data; i < len; i++, p++)
+  key = (const String *) vkey;
+  len = key->len;
+  for (i = 0, p = key->str; i < len; i++, p++)
     ret = ret * 33 + *p;
   return ret;
 }
@@ -35,11 +34,10 @@ 
 __go_type_equal_string (const void *vk1, const void *vk2,
 			uintptr_t key_size __attribute__ ((unused)))
 {
-  const struct __go_string *k1;
-  const struct __go_string *k2;
+  const String *k1;
+  const String *k2;
 
-  k1 = (const struct __go_string *) vk1;
-  k2 = (const struct __go_string *) vk2;
-  return (k1->__length == k2->__length
-	  && __builtin_memcmp (k1->__data, k2->__data, k1->__length) == 0);
+  k1 = (const String *) vk1;
+  k2 = (const String *) vk2;
+  return __go_ptr_strings_equal (k1, k2);
 }
diff -r c4af1cde4722 libgo/runtime/go-type.h
--- a/libgo/runtime/go-type.h	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-type.h	Wed Oct 31 19:54:39 2012 -0700
@@ -10,9 +10,10 @@ 
 #include <stddef.h>
 #include <stdint.h>
 
-#include "go-string.h"
 #include "array.h"
 
+struct String;
+
 /* Many of the types in this file must match the data structures
    generated by the compiler, and must also match the Go types which
    appear in go/runtime/type.go and go/reflect/type.go.  */
@@ -94,7 +95,7 @@ 
 
   /* A string describing this type.  This is only used for
      debugging.  */
-  const struct __go_string *__reflection;
+  const struct String *__reflection;
 
   /* A pointer to fields which are only used for some types.  */
   const struct __go_uncommon_type *__uncommon;
@@ -109,11 +110,11 @@ 
 struct __go_method
 {
   /* The name of the method.  */
-  const struct __go_string *__name;
+  const struct String *__name;
 
   /* This is NULL for an exported method, or the name of the package
      where it lives.  */
-  const struct __go_string *__pkg_path;
+  const struct String *__pkg_path;
 
   /* The type of the method, without the receiver.  This will be a
      function type.  */
@@ -134,10 +135,10 @@ 
 struct __go_uncommon_type
 {
   /* The name of the type.  */
-  const struct __go_string *__name;
+  const struct String *__name;
 
   /* The type's package.  This is NULL for builtin types.  */
-  const struct __go_string *__pkg_path;
+  const struct String *__pkg_path;
 
   /* The type's methods.  This is an array of struct __go_method.  */
   struct __go_open_array __methods;
@@ -216,11 +217,11 @@ 
 struct __go_interface_method
 {
   /* The name of the method.  */
-  const struct __go_string *__name;
+  const struct String *__name;
 
   /* This is NULL for an exported method, or the name of the package
      where it lives.  */
-  const struct __go_string *__pkg_path;
+  const struct String *__pkg_path;
 
   /* The real type of the method.  */
   struct __go_type_descriptor *__type;
@@ -269,17 +270,17 @@ 
 struct __go_struct_field
 {
   /* The name of the field--NULL for an anonymous field.  */
-  const struct __go_string *__name;
+  const struct String *__name;
 
   /* This is NULL for an exported method, or the name of the package
      where it lives.  */
-  const struct __go_string *__pkg_path;
+  const struct String *__pkg_path;
 
   /* The type of the field.  */
   const struct __go_type_descriptor *__type;
 
   /* The field tag, or NULL.  */
-  const struct __go_string *__tag;
+  const struct String *__tag;
 
   /* The offset of the field in the struct.  */
   uintptr_t __offset;
diff -r c4af1cde4722 libgo/runtime/go-typedesc-equal.c
--- a/libgo/runtime/go-typedesc-equal.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-typedesc-equal.c	Wed Oct 31 19:54:39 2012 -0700
@@ -4,6 +4,7 @@ 
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
+#include "runtime.h"
 #include "go-string.h"
 #include "go-type.h"
 
diff -r c4af1cde4722 libgo/runtime/go-typestring.c
--- a/libgo/runtime/go-typestring.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-typestring.c	Wed Oct 31 19:54:39 2012 -0700
@@ -4,14 +4,13 @@ 
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
+#include "runtime.h"
 #include "interface.h"
 #include "go-type.h"
-#include "go-string.h"
 
-struct __go_string typestring(struct __go_empty_interface)
-  asm ("runtime.typestring");
+String typestring(struct __go_empty_interface) asm ("runtime.typestring");
 
-struct __go_string
+String
 typestring (struct __go_empty_interface e)
 {
   return *e.__type_descriptor->__reflection;
diff -r c4af1cde4722 libgo/runtime/go-unsafe-pointer.c
--- a/libgo/runtime/go-unsafe-pointer.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/go-unsafe-pointer.c	Wed Oct 31 19:54:39 2012 -0700
@@ -6,7 +6,7 @@ 
 
 #include <stddef.h>
 
-#include "go-string.h"
+#include "runtime.h"
 #include "go-type.h"
 
 /* This file provides the type descriptor for the unsafe.Pointer type.
@@ -26,9 +26,9 @@ 
 
 /* The reflection string.  */
 #define REFLECTION "unsafe.Pointer"
-static const struct __go_string reflection_string =
+static const String reflection_string =
 {
-  (const unsigned char *) REFLECTION,
+  (const byte *) REFLECTION,
   sizeof REFLECTION - 1
 };
 
@@ -65,9 +65,9 @@ 
 
 /* The reflection string.  */
 #define PREFLECTION "*unsafe.Pointer"
-static const struct __go_string preflection_string =
+static const String preflection_string =
 {
-  (const unsigned char *) PREFLECTION,
+  (const byte *) PREFLECTION,
   sizeof PREFLECTION - 1,
 };
 
diff -r c4af1cde4722 libgo/runtime/interface.h
--- a/libgo/runtime/interface.h	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/interface.h	Wed Oct 31 19:54:39 2012 -0700
@@ -7,7 +7,7 @@ 
 #ifndef LIBGO_INTERFACE_H
 #define LIBGO_INTERFACE_H
 
-#include "go-type.h"
+struct __go_type_descriptor;
 
 /* A variable of interface type is an instance of this struct, if the
    interface has any methods.  */
diff -r c4af1cde4722 libgo/runtime/malloc.goc
--- a/libgo/runtime/malloc.goc	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/malloc.goc	Wed Oct 31 19:54:39 2012 -0700
@@ -14,7 +14,6 @@ 
 #include "runtime.h"
 #include "arch.h"
 #include "malloc.h"
-#include "go-string.h"
 #include "interface.h"
 #include "go-type.h"
 #include "race.h"
diff -r c4af1cde4722 libgo/runtime/panic.c
--- a/libgo/runtime/panic.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/panic.c	Wed Oct 31 19:54:39 2012 -0700
@@ -4,6 +4,7 @@ 
 
 #include "runtime.h"
 #include "go-defer.h"
+#include "go-panic.h"
 
 // Code related to defer, panic and recover.
 
diff -r c4af1cde4722 libgo/runtime/print.c
--- a/libgo/runtime/print.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/print.c	Wed Oct 31 19:54:39 2012 -0700
@@ -4,6 +4,7 @@ 
 
 #include <stdarg.h>
 #include "runtime.h"
+#include "array.h"
 
 //static Lock debuglock;
 
@@ -294,8 +295,8 @@ 
 	//	gwrite("[string too long]", 17);
 	//	return;
 	// }
-	if(v.__length > 0)
-		gwrite(v.__data, v.__length);
+	if(v.len > 0)
+		gwrite(v.str, v.len);
 }
 
 void
diff -r c4af1cde4722 libgo/runtime/proc.c
--- a/libgo/runtime/proc.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/proc.c	Wed Oct 31 19:54:39 2012 -0700
@@ -586,13 +586,13 @@ 
 runtime_goroutinetrailer(G *g)
 {
 	if(g != nil && g->gopc != 0 && g->goid != 1) {
-		struct __go_string fn;
-		struct __go_string file;
+		String fn;
+		String file;
 		int line;
 
 		if(__go_file_line(g->gopc - 1, &fn, &file, &line)) {
-			runtime_printf("created by %s\n", fn.__data);
-			runtime_printf("\t%s:%d\n", file.__data, line);
+			runtime_printf("created by %S\n", fn);
+			runtime_printf("\t%S:%d\n", file, line);
 		}
 	}
 }
diff -r c4af1cde4722 libgo/runtime/reflect.goc
--- a/libgo/runtime/reflect.goc	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/reflect.goc	Wed Oct 31 19:54:39 2012 -0700
@@ -3,9 +3,9 @@ 
 // license that can be found in the LICENSE file.
 
 package reflect
+#include "runtime.h"
 #include "go-type.h"
 #include "interface.h"
-#include "runtime.h"
 #include "go-panic.h"
 
 func ifaceE2I(inter *Type, e Eface, ret *Iface) {
diff -r c4af1cde4722 libgo/runtime/runtime.c
--- a/libgo/runtime/runtime.c	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/runtime.c	Wed Oct 31 19:54:39 2012 -0700
@@ -9,7 +9,6 @@ 
 #include "runtime.h"
 #include "array.h"
 #include "go-panic.h"
-#include "go-string.h"
 
 int32
 runtime_gotraceback(void)
@@ -93,9 +92,9 @@ 
 	envv = (String*)syscall_Envs.__values;
 	envc = syscall_Envs.__count;
 	for(i=0; i<envc; i++){
-		if(envv[i].__length <= len)
+		if(envv[i].len <= len)
 			continue;
-		v = (const byte*)envv[i].__data;
+		v = (const byte*)envv[i].str;
 		for(j=0; j<len; j++)
 			if(bs[j] != v[j])
 				goto nomatch;
diff -r c4af1cde4722 libgo/runtime/runtime.h
--- a/libgo/runtime/runtime.h	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/runtime.h	Wed Oct 31 19:54:39 2012 -0700
@@ -21,10 +21,8 @@ 
 #include <sys/mman.h>
 #endif
 
-#include "array.h"
+#include "interface.h"
 #include "go-alloc.h"
-#include "go-panic.h"
-#include "go-string.h"
 
 /* This file supports C files copied from the 6g runtime library.
    This is a version of the 6g runtime.h rewritten for gccgo's version
@@ -67,7 +65,7 @@ 
 typedef struct	ParForThread	ParForThread;
 
 typedef	struct	__go_open_array		Slice;
-typedef	struct	__go_string		String;
+typedef	struct	String			String;
 typedef struct	__go_interface		Iface;
 typedef	struct	__go_empty_interface	Eface;
 typedef	struct	__go_type_descriptor	Type;
@@ -129,6 +127,11 @@ 
 	uint32	key;	// futex-based impl
 	M*	waitm;	// waiting M (sema-based impl)
 };
+struct String
+{
+	const byte*	str;
+	intgo		len;
+};
 struct	GCStats
 {
 	// the struct must consist of only uint64's,
diff -r c4af1cde4722 libgo/runtime/string.goc
--- a/libgo/runtime/string.goc	Wed Oct 31 13:48:25 2012 -0700
+++ b/libgo/runtime/string.goc	Wed Oct 31 19:54:39 2012 -0700
@@ -6,10 +6,11 @@ 
 #include "runtime.h"
 #include "arch.h"
 #include "malloc.h"
+#include "go-string.h"
 
 #define charntorune(pv, str, len) __go_get_rune(str, len, pv)
 
-int32
+intgo
 runtime_findnull(const byte *s)
 {
 	if(s == nil)
@@ -22,8 +23,8 @@ 
 {
 	String s;
 	
-	s.__data = (const unsigned char *) str;
-	s.__length = runtime_findnull(str);
+	s.str = str;
+	s.len = runtime_findnull(str);
 	return s;
 }
 
@@ -35,40 +36,40 @@ 
 func stringiter(s String, k int) (retk int) {
 	int32 l;
 
-	if(k >= s.__length) {
+	if(k >= s.len) {
 		// retk=0 is end of iteration
 		retk = 0;
 		goto out;
 	}
 
-	l = s.__data[k];
+	l = s.str[k];
 	if(l < Runeself) {
 		retk = k+1;
 		goto out;
 	}
 
 	// multi-char rune
-	retk = k + charntorune(&l, s.__data+k, s.__length-k);
+	retk = k + charntorune(&l, s.str+k, s.len-k);
 
 out:
 }
 
 func stringiter2(s String, k int) (retk int, retv int) {
-	if(k >= s.__length) {
+	if(k >= s.len) {
 		// retk=0 is end of iteration
 		retk = 0;
 		retv = 0;
 		goto out;
 	}
 
-	retv = s.__data[k];
+	retv = s.str[k];
 	if(retv < Runeself) {
 		retk = k+1;
 		goto out;
 	}
 
 	// multi-char rune
-	retk = k + charntorune(&retv, s.__data+k, s.__length-k);
+	retk = k + charntorune(&retv, s.str+k, s.len-k);
 
 out:
 }