This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Go patch committed: Update to current Go library


I have committed a patch to update libgo to the current version of the
Go library.  This patch includes some minor changes to the Go frontend
and to the testsuite.  The patch is too large to include here, but most
of it is simply a copy of the changes to the master Go library.  I have
appended the changes to the files which are not in the master library.
Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.

Ian

Index: gcc/go/gofrontend/types.h
===================================================================
--- gcc/go/gofrontend/types.h	(revision 173742)
+++ gcc/go/gofrontend/types.h	(working copy)
@@ -1044,7 +1044,7 @@ class Type
   // Build a composite literal for one method.
   Expression*
   method_constructor(Gogo*, Type* method_type, const std::string& name,
-		     const Method*) const;
+		     const Method*, bool only_value_methods) const;
 
   static tree
   build_receive_return_type(tree type);
Index: gcc/go/gofrontend/types.cc
===================================================================
--- gcc/go/gofrontend/types.cc	(revision 173742)
+++ gcc/go/gofrontend/types.cc	(working copy)
@@ -1432,7 +1432,7 @@ Type::methods_constructor(Gogo* gogo, Ty
        p != smethods.end();
        ++p)
     vals->push_back(this->method_constructor(gogo, method_type, p->first,
-					     p->second));
+					     p->second, only_value_methods));
 
   return Expression::make_slice_composite_literal(methods_type, vals, bloc);
 }
@@ -1444,7 +1444,8 @@ Type::methods_constructor(Gogo* gogo, Ty
 Expression*
 Type::method_constructor(Gogo*, Type* method_type,
 			 const std::string& method_name,
-			 const Method* m) const
+			 const Method* m,
+			 bool only_value_methods) const
 {
   source_location bloc = BUILTINS_LOCATION;
 
@@ -1487,6 +1488,25 @@ Type::method_constructor(Gogo*, Type* me
 
   ++p;
   go_assert(p->field_name() == "typ");
+  if (!only_value_methods && m->is_value_method())
+    {
+      // This is a value method on a pointer type.  Change the type of
+      // the method to use a pointer receiver.  The implementation
+      // always uses a pointer receiver anyhow.
+      Type* rtype = mtype->receiver()->type();
+      Type* prtype = Type::make_pointer_type(rtype);
+      Typed_identifier* receiver =
+	new Typed_identifier(mtype->receiver()->name(), prtype,
+			     mtype->receiver()->location());
+      mtype = Type::make_function_type(receiver,
+				       (mtype->parameters() == NULL
+					? NULL
+					: mtype->parameters()->copy()),
+				       (mtype->results() == NULL
+					? NULL
+					: mtype->results()->copy()),
+				       mtype->location());
+    }
   vals->push_back(Expression::make_type_descriptor(mtype, bloc));
 
   ++p;
@@ -2779,14 +2799,7 @@ Function_type::type_descriptor_params(Ty
 		+ (receiver != NULL ? 1 : 0));
 
   if (receiver != NULL)
-    {
-      Type* rtype = receiver->type();
-      // The receiver is always passed as a pointer.  FIXME: Is this
-      // right?  Should that fact affect the type descriptor?
-      if (rtype->points_to() == NULL)
-	rtype = Type::make_pointer_type(rtype);
-      vals->push_back(Expression::make_type_descriptor(rtype, bloc));
-    }
+    vals->push_back(Expression::make_type_descriptor(receiver->type(), bloc));
 
   if (params != NULL)
     {
@@ -4822,9 +4835,10 @@ Array_type::make_array_type_descriptor_t
       Type* uintptr_type = Type::lookup_integer_type("uintptr");
 
       Struct_type* sf =
-	Type::make_builtin_struct_type(3,
+	Type::make_builtin_struct_type(4,
 				       "", tdt,
 				       "elem", ptdt,
+				       "slice", ptdt,
 				       "len", uintptr_type);
 
       ret = Type::make_builtin_named_type("ArrayType", sf);
@@ -4891,6 +4905,11 @@ Array_type::array_type_descriptor(Gogo* 
   vals->push_back(Expression::make_type_descriptor(this->element_type_, bloc));
 
   ++p;
+  go_assert(p->field_name() == "slice");
+  Type* slice_type = Type::make_array_type(this->element_type_, NULL);
+  vals->push_back(Expression::make_type_descriptor(slice_type, bloc));
+
+  ++p;
   go_assert(p->field_name() == "len");
   vals->push_back(Expression::make_cast(p->type(), this->length_, bloc));
 
@@ -5375,8 +5394,9 @@ Channel_type::do_make_expression_tree(Tr
   Gogo* gogo = context->gogo();
   tree channel_type = type_to_tree(this->get_backend(gogo));
 
-  tree element_tree = type_to_tree(this->element_type_->get_backend(gogo));
-  tree element_size_tree = size_in_bytes(element_tree);
+  Type* ptdt = Type::make_type_descriptor_ptr_type();
+  tree element_type_descriptor =
+    this->element_type_->type_descriptor_pointer(gogo);
 
   tree bad_index = NULL_TREE;
 
@@ -5402,8 +5422,8 @@ Channel_type::do_make_expression_tree(Tr
 				"__go_new_channel",
 				2,
 				channel_type,
-				sizetype,
-				element_size_tree,
+				type_to_tree(ptdt->get_backend(gogo)),
+				element_type_descriptor,
 				sizetype,
 				expr_tree);
   if (ret == error_mark_node)
@@ -6242,7 +6262,16 @@ Interface_type::do_reflection(Gogo* gogo
 	  if (p != this->methods_->begin())
 	    ret->append(";");
 	  ret->push_back(' ');
-	  ret->append(Gogo::unpack_hidden_name(p->name()));
+	  if (!Gogo::is_hidden_name(p->name()))
+	    ret->append(p->name());
+	  else
+	    {
+	      // This matches what the gc compiler does.
+	      std::string prefix = Gogo::hidden_name_prefix(p->name());
+	      ret->append(prefix.substr(prefix.find('.') + 1));
+	      ret->push_back('.');
+	      ret->append(Gogo::unpack_hidden_name(p->name()));
+	    }
 	  std::string sub = p->type()->reflection(gogo);
 	  go_assert(sub.compare(0, 4, "func") == 0);
 	  sub = sub.substr(4);
Index: libgo/Makefile.am
===================================================================
--- libgo/Makefile.am	(revision 173685)
+++ libgo/Makefile.am	(working copy)
@@ -248,7 +248,8 @@ toolexeclibgogo_DATA = \
 	go/printer.gox \
 	go/scanner.gox \
 	go/token.gox \
-	go/typechecker.gox
+	go/typechecker.gox \
+	go/types.gox
 
 toolexeclibgohashdir = $(toolexeclibgodir)/hash
 
@@ -262,14 +263,19 @@ toolexeclibgohttpdir = $(toolexeclibgodi
 
 toolexeclibgohttp_DATA = \
 	http/cgi.gox \
+	http/fcgi.gox \
 	http/httptest.gox \
-	http/pprof.gox
+	http/pprof.gox \
+	http/spdy.gox
 
 toolexeclibgoimagedir = $(toolexeclibgodir)/image
 
 toolexeclibgoimage_DATA = \
+	image/gif.gox \
 	image/jpeg.gox \
-	image/png.gox
+	image/png.gox \
+	image/tiff.gox \
+	image/ycbcr.gox
 
 toolexeclibgoindexdir = $(toolexeclibgodir)/index
 
@@ -303,6 +309,7 @@ endif
 
 toolexeclibgoos_DATA = \
 	$(os_inotify_gox) \
+	os/user.gox \
 	os/signal.gox
 
 toolexeclibgopathdir = $(toolexeclibgodir)/path
@@ -404,6 +411,7 @@ runtime_files = \
 	runtime/go-send-nb-big.c \
 	runtime/go-send-nb-small.c \
 	runtime/go-send-small.c \
+	runtime/go-setenv.c \
 	runtime/go-signal.c \
 	runtime/go-strcmp.c \
 	runtime/go-string-to-byte-array.c \
@@ -560,6 +568,7 @@ go_http_files = \
 	go/http/persist.go \
 	go/http/request.go \
 	go/http/response.go \
+	go/http/reverseproxy.go \
 	go/http/server.go \
 	go/http/status.go \
 	go/http/transfer.go \
@@ -656,8 +665,17 @@ go_net_newpollserver_file = go/net/newpo
 endif # !LIBGO_IS_LINUX
 endif # !LIBGO_IS_RTEMS
 
+if LIBGO_IS_LINUX
+go_net_cgo_file = go/net/cgo_linux.go
+go_net_sock_file = go/net/sock_linux.go
+else
+go_net_cgo_file = go/net/cgo_bsd.go
+go_net_sock_file = go/net/sock_bsd.go
+endif
+
 go_net_files = \
-	go/net/cgo_stub.go \
+	go/net/cgo_unix.go \
+	$(go_net_cgo_file) \
 	go/net/dial.go \
 	go/net/dnsclient.go \
 	go/net/dnsconfig.go \
@@ -676,6 +694,7 @@ go_net_files = \
 	go/net/pipe.go \
 	go/net/port.go \
 	go/net/sock.go \
+	$(go_net_sock_file) \
 	go/net/tcpsock.go \
 	go/net/udpsock.go \
 	go/net/unixsock.go
@@ -1002,7 +1021,6 @@ go_crypto_subtle_files = \
 	go/crypto/subtle/constant_time.go
 go_crypto_tls_files = \
 	go/crypto/tls/alert.go \
-	go/crypto/tls/ca_set.go \
 	go/crypto/tls/cipher_suites.go \
 	go/crypto/tls/common.go \
 	go/crypto/tls/conn.go \
@@ -1015,6 +1033,8 @@ go_crypto_tls_files = \
 go_crypto_twofish_files = \
 	go/crypto/twofish/twofish.go
 go_crypto_x509_files = \
+	go/crypto/x509/cert_pool.go \
+	go/crypto/x509/verify.go \
 	go/crypto/x509/x509.go
 go_crypto_xtea_files = \
 	go/crypto/xtea/block.go \
@@ -1130,6 +1150,12 @@ go_go_typechecker_files = \
 	go/go/typechecker/type.go \
 	go/go/typechecker/typechecker.go \
 	go/go/typechecker/universe.go
+go_go_types_files = \
+	go/go/types/const.go \
+	go/go/types/exportdata.go \
+	go/go/types/gcimporter.go \
+	go/go/types/types.go \
+	go/go/types/universe.go
 
 go_hash_adler32_files = \
 	go/hash/adler32/adler32.go
@@ -1143,21 +1169,39 @@ go_hash_fnv_files = \
 go_http_cgi_files = \
 	go/http/cgi/child.go \
 	go/http/cgi/host.go
+go_http_fcgi_files = \
+	go/http/fcgi/child.go \
+	go/http/fcgi/fcgi.go
 go_http_httptest_files = \
 	go/http/httptest/recorder.go \
 	go/http/httptest/server.go
 go_http_pprof_files = \
 	go/http/pprof/pprof.go
+go_http_spdy_files = \
+	go/http/spdy/protocol.go
+
+go_image_gif_files = \
+	go/image/gif/reader.go
 
 go_image_jpeg_files = \
+	go/image/jpeg/fdct.go \
 	go/image/jpeg/huffman.go \
 	go/image/jpeg/idct.go \
-	go/image/jpeg/reader.go
+	go/image/jpeg/reader.go \
+	go/image/jpeg/writer.go
 
 go_image_png_files = \
 	go/image/png/reader.go \
 	go/image/png/writer.go
 
+go_image_tiff_files = \
+	go/image/tiff/buffer.go \
+	go/image/tiff/consts.go \
+	go/image/tiff/reader.go
+
+go_image_ycbcr_files = \
+	go/image/ycbcr/ycbcr.go
+
 go_index_suffixarray_files = \
 	go/index/suffixarray/qsufsort.go \
 	go/index/suffixarray/suffixarray.go
@@ -1167,6 +1211,7 @@ go_io_ioutil_files = \
 	go/io/ioutil/tempfile.go
 
 go_mime_multipart_files = \
+	go/mime/multipart/formdata.go \
 	go/mime/multipart/multipart.go
 
 go_net_dict_files = \
@@ -1182,6 +1227,10 @@ go_net_textproto_files = \
 go_os_inotify_files = \
 	go/os/inotify/inotify_linux.go
 
+go_os_user_files = \
+	go/os/user/user.go \
+	go/os/user/lookup_unix.go
+
 go_os_signal_files = \
 	go/os/signal/signal.go \
 	unix.go
@@ -1485,21 +1534,28 @@ libgo_go_objs = \
 	go/scanner.lo \
 	go/token.lo \
 	go/typechecker.lo \
+	go/types.lo \
 	hash/adler32.lo \
 	hash/crc32.lo \
 	hash/crc64.lo \
 	hash/fnv.lo \
 	http/cgi.lo \
+	http/fcgi.lo \
 	http/httptest.lo \
 	http/pprof.lo \
+	http/spdy.lo \
+	image/gif.lo \
 	image/jpeg.lo \
 	image/png.lo \
+	image/tiff.lo \
+	image/ycbcr.lo \
 	index/suffixarray.lo \
 	io/ioutil.lo \
 	mime/multipart.lo \
 	net/dict.lo \
 	net/textproto.lo \
 	$(os_lib_inotify_lo) \
+	os/user.lo \
 	os/signal.lo \
 	path/filepath.lo \
 	rpc/jsonrpc.lo \
@@ -1711,11 +1767,12 @@ html/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: html/check
 
-http/http.lo: $(go_http_files) bufio.gox bytes.gox container/vector.gox \
-		crypto/rand.gox crypto/tls.gox encoding/base64.gox fmt.gox \
-		io.gox io/ioutil.gox log.gox mime.gox mime/multipart.gox \
-		net.gox net/textproto.gox os.gox path.gox path/filepath.gox \
-		sort.gox strconv.gox strings.gox sync.gox time.gox utf8.gox
+http/http.lo: $(go_http_files) bufio.gox bytes.gox compress/gzip.gox \
+		container/vector.gox crypto/rand.gox crypto/tls.gox \
+		encoding/base64.gox fmt.gox io.gox io/ioutil.gox log.gox \
+		mime.gox mime/multipart.gox net.gox net/textproto.gox os.gox \
+		path.gox path/filepath.gox sort.gox strconv.gox strings.gox \
+		sync.gox time.gox utf8.gox
 	$(BUILDPACKAGE)
 http/check: $(CHECK_DEPS)
 	@$(CHECK)
@@ -1755,7 +1812,7 @@ math/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: math/check
 
-mime/mime.lo: $(go_mime_files) bufio.gox bytes.gox os.gox strings.gox \
+mime/mime.lo: $(go_mime_files) bufio.gox bytes.gox fmt.gox os.gox strings.gox \
 		sync.gox unicode.gox
 	$(BUILDPACKAGE)
 mime/check: $(CHECK_DEPS)
@@ -1763,8 +1820,8 @@ mime/check: $(CHECK_DEPS)
 .PHONY: mime/check
 
 net/net.lo: $(go_net_files) bytes.gox fmt.gox io.gox os.gox rand.gox \
-		reflect.gox strconv.gox strings.gox sync.gox syscall.gox \
-		time.gox
+		reflect.gox sort.gox strconv.gox strings.gox sync.gox \
+		syscall.gox time.gox
 	$(BUILDPACKAGE)
 net/check: $(CHECK_DEPS)
 	@$(CHECK_ON_REQUEST)
@@ -1945,8 +2002,8 @@ xml/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: xml/check
 
-archive/tar.lo: $(go_archive_tar_files) bytes.gox io.gox os.gox strconv.gox \
-		strings.gox
+archive/tar.lo: $(go_archive_tar_files) bytes.gox io.gox io/ioutil.gox os.gox \
+		strconv.gox strings.gox
 	$(BUILDPACKAGE)
 archive/tar/check: $(CHECK_DEPS)
 	@$(MKDIR_P) archive/tar
@@ -2148,8 +2205,7 @@ crypto/ripemd160/check: $(CHECK_DEPS)
 .PHONY: crypto/ripemd160/check
 
 crypto/rsa.lo: $(go_crypto_rsa_files) big.gox crypto.gox crypto/sha1.gox \
-		crypto/subtle.gox encoding/hex.gox hash.gox io.gox os.gox \
-		sync.gox
+		crypto/subtle.gox encoding/hex.gox hash.gox io.gox os.gox
 	$(BUILDPACKAGE)
 crypto/rsa/check: $(CHECK_DEPS)
 	@$(MKDIR_P) crypto/rsa
@@ -2184,13 +2240,13 @@ crypto/subtle/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: crypto/subtle/check
 
-crypto/tls.lo: $(go_crypto_tls_files) big.gox bufio.gox bytes.gox \
-		container/list.gox crypto.gox crypto/aes.gox crypto/cipher.gox \
-		crypto/elliptic.gox crypto/hmac.gox crypto/md5.gox \
-		crypto/rc4.gox crypto/rand.gox crypto/rsa.gox crypto/sha1.gox \
-		crypto/subtle.gox crypto/rsa.gox crypto/sha1.gox \
-		crypto/x509.gox encoding/pem.gox fmt.gox hash.gox io.gox \
-		io/ioutil.gox net.gox os.gox strings.gox sync.gox time.gox
+crypto/tls.lo: $(go_crypto_tls_files) big.gox bytes.gox crypto.gox \
+		crypto/aes.gox crypto/cipher.gox crypto/elliptic.gox \
+		crypto/hmac.gox crypto/md5.gox crypto/rand.gox crypto/rc4.gox \
+		crypto/rsa.gox crypto/sha1.gox crypto/subtle.gox \
+		crypto/x509.gox encoding/pem.gox hash.gox io.gox \
+		io/ioutil.gox net.gox os.gox strconv.gox strings.gox sync.gox \
+		time.gox
 	$(BUILDPACKAGE)
 crypto/tls/check: $(CHECK_DEPS)
 	@$(MKDIR_P) crypto/tls
@@ -2204,9 +2260,10 @@ crypto/twofish/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: crypto/twofish/check
 
-crypto/x509.lo: $(go_crypto_x509_files) asn1.gox big.gox container/vector.gox \
-		crypto.gox crypto/rsa.gox crypto/sha1.gox hash.gox os.gox \
-		strings.gox time.gox
+crypto/x509.lo: $(go_crypto_x509_files) asn1.gox big.gox bytes.gox \
+		container/vector.gox crypto.gox crypto/rsa.gox \
+		crypto/sha1.gox encoding/pem.gox hash.gox os.gox strings.gox \
+		time.gox
 	$(BUILDPACKAGE)
 crypto/x509/check: $(CHECK_DEPS)
 	@$(MKDIR_P) crypto/x509
@@ -2220,9 +2277,8 @@ crypto/xtea/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: crypto/xtea/check
 
-crypto/openpgp/armor.lo: $(go_crypto_openpgp_armor_files) bytes.gox \
-		crypto/openpgp/error.gox encoding/base64.gox \
-		encoding/line.gox io.gox os.gox
+crypto/openpgp/armor.lo: $(go_crypto_openpgp_armor_files) bufio.gox bytes.gox \
+		crypto/openpgp/error.gox encoding/base64.gox io.gox os.gox
 	$(BUILDPACKAGE)
 crypto/openpgp/armor/check: $(CHECK_DEPS)
 	@$(MKDIR_P) crypto/openpgp/armor
@@ -2374,7 +2430,7 @@ exp/datafmt/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: exp/datafmt/check
 
-exp/draw.lo: $(go_exp_draw_files) image.gox os.gox
+exp/draw.lo: $(go_exp_draw_files) image.gox image/ycbcr.gox os.gox
 	$(BUILDPACKAGE)
 exp/draw/check: $(CHECK_DEPS)
 	@$(MKDIR_P) exp/draw
@@ -2448,6 +2504,15 @@ go/typechecker/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: go/typechecker/check
 
+go/types.lo: $(go_go_types_files) big.gox bufio.gox fmt.gox go/ast.gox \
+		go/token.gox io.gox os.gox path/filepath.gox runtime.gox \
+		scanner.gox strconv.gox strings.gox
+	$(BUILDPACKAGE)
+go/types/check: $(CHECK_DEPS)
+	@$(MKDIR_P) go/types
+	@$(CHECK)
+.PHONY: go/types/check
+
 hash/adler32.lo: $(go_hash_adler32_files) hash.gox os.gox
 	$(BUILDPACKAGE)
 hash/adler32/check: $(CHECK_DEPS)
@@ -2476,15 +2541,25 @@ hash/fnv/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: hash/fnv/check
 
-http/cgi.lo: $(go_http_cgi_files) bufio.gox bytes.gox encoding/line.gox \
-		exec.gox fmt.gox http.gox io.gox io/ioutil.gox log.gox \
-		os.gox path/filepath.gox regexp.gox strconv.gox strings.gox
+http/cgi.lo: $(go_http_cgi_files) bufio.gox bytes.gox crypto/tls.gox \
+		exec.gox fmt.gox http.gox net.gox io.gox io/ioutil.gox \
+		log.gox os.gox path/filepath.gox regexp.gox strconv.gox \
+		strings.gox
 	$(BUILDPACKAGE)
 http/cgi/check: $(CHECK_DEPS)
 	@$(MKDIR_P) http/cgi
 	@$(CHECK)
 .PHONY: http/cgi/check
 
+http/fcgi.lo: $(go_http_fcgi_files) bufio.gox bytes.gox encoding/binary.gox \
+		fmt.gox http.gox http/cgi.gox io.gox net.gox os.gox sync.gox \
+		time.gox
+	$(BUILDPACKAGE)
+http/fcgi/check: $(CHECK_DEPS)
+	@$(MKDIR_P) http/fcgi
+	@$(CHECK)
+.PHONY: http/fcgi/check
+
 http/httptest.lo: $(go_http_httptest_files) bytes.gox crypto/rand.gox \
 		crypto/tls.gox fmt.gox http.gox net.gox os.gox time.gox
 	$(BUILDPACKAGE)
@@ -2493,15 +2568,33 @@ http/httptest/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: http/httptest/check
 
-http/pprof.lo: $(go_http_pprof_files) bufio.gox fmt.gox http.gox os.gox \
-		runtime.gox runtime/pprof.gox strconv.gox strings.gox
+http/pprof.lo: $(go_http_pprof_files) bufio.gox bytes.gox fmt.gox http.gox \
+		os.gox runtime.gox runtime/pprof.gox strconv.gox strings.gox
 	$(BUILDPACKAGE)
 http/pprof/check: $(CHECK_DEPS)
 	@$(MKDIR_P) http/pprof
 	@$(CHECK)
 .PHONY: http/pprof/check
 
-image/jpeg.lo: $(go_image_jpeg_files) bufio.gox image.gox io.gox os.gox
+http/spdy.lo: $(go_http_spdy_files) bytes.gox compress/zlib.gox \
+		encoding/binary.gox http.gox io.gox os.gox strconv.gox \
+		strings.gox sync.gox
+	$(BUILDPACKAGE)
+http/spdy/check: $(CHECK_DEPS)
+	@$(MKDIR_P) http/spdy
+	@$(CHECK)
+.PHONY: http/spdy/check
+
+image/gif.lo: $(go_image_gif_files) bufio.gox compress/lzw.gox fmt.gox \
+		image.gox io.gox os.gox
+	$(BUILDPACKAGE)
+image/gif/check: $(CHECK_DEPS)
+	@$(MKDIR_P) image/gif
+	@$(CHECK)
+.PHONY: image/gif/check
+
+image/jpeg.lo: $(go_image_jpeg_files) bufio.gox image.gox image/ycbcr.gox \
+		io.gox os.gox
 	$(BUILDPACKAGE)
 image/jpeg/check: $(CHECK_DEPS)
 	@$(MKDIR_P) image/jpeg
@@ -2516,6 +2609,21 @@ image/png/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: image/png/check
 
+image/tiff.lo: $(go_image_tiff_files) compress/lzw.gox compress/zlib.gox \
+		encoding/binary.gox image.gox io.gox io/ioutil.gox os.gox
+	$(BUILDPACKAGE)
+image/tiff/check: $(CHECK_DEPS)
+	@$(MKDIR_P) image/tiff
+	@$(CHECK)
+.PHONY: image/tiff/check
+
+image/ycbcr.lo: $(go_image_ycbcr_files) image.gox
+	$(BUILDPACKAGE)
+image/ycbcr/check: $(CHECK_DEPS)
+	@$(MKDIR_P) image/ycbcr
+	@$(CHECK)
+.PHONY: image/ycbcr/check
+
 index/suffixarray.lo: $(go_index_suffixarray_files) bytes.gox regexp.gox \
 		sort.gox
 	$(BUILDPACKAGE)
@@ -2532,8 +2640,9 @@ io/ioutil/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: io/ioutil/check
 
-mime/multipart.lo: $(go_mime_multipart_files) bufio.gox bytes.gox io.gox \
-		mime.gox net/textproto.gox os.gox regexp.gox strings.gox
+mime/multipart.lo: $(go_mime_multipart_files) bufio.gox bytes.gox fmt.gox \
+		io.gox io/ioutil.gox mime.gox net/textproto.gox os.gox \
+		regexp.gox
 	$(BUILDPACKAGE)
 mime/multipart/check: $(CHECK_DEPS)
 	@$(MKDIR_P) mime/multipart
@@ -2560,6 +2669,14 @@ os/inotify/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: os/inotify/check
 
+os/user.lo: $(go_os_user_files) fmt.gox os.gox runtime.gox strconv.gox \
+		strings.gox syscall.gox
+	$(BUILDPACKAGE)
+os/user/check: $(CHECK_DEPS)
+	@$(MKDIR_P) os/user
+	@$(CHECK)
+.PHONY: os/user/check
+
 os/signal.lo: $(go_os_signal_files) runtime.gox strconv.gox
 	$(BUILDPACKAGE)
 os/signal/check: $(CHECK_DEPS)
@@ -2886,6 +3003,8 @@ go/token.gox: go/token.lo
 	$(BUILDGOX)
 go/typechecker.gox: go/typechecker.lo
 	$(BUILDGOX)
+go/types.gox: go/types.lo
+	$(BUILDGOX)
 
 hash/adler32.gox: hash/adler32.lo
 	$(BUILDGOX)
@@ -2898,15 +3017,25 @@ hash/fnv.gox: hash/fnv.lo
 
 http/cgi.gox: http/cgi.lo
 	$(BUILDGOX)
+http/fcgi.gox: http/fcgi.lo
+	$(BUILDGOX)
 http/httptest.gox: http/httptest.lo
 	$(BUILDGOX)
 http/pprof.gox: http/pprof.lo
 	$(BUILDGOX)
+http/spdy.gox: http/spdy.lo
+	$(BUILDGOX)
 
+image/gif.gox: image/gif.lo
+	$(BUILDGOX)
 image/jpeg.gox: image/jpeg.lo
 	$(BUILDGOX)
 image/png.gox: image/png.lo
 	$(BUILDGOX)
+image/tiff.gox: image/tiff.lo
+	$(BUILDGOX)
+image/ycbcr.gox: image/ycbcr.lo
+	$(BUILDGOX)
 
 index/suffixarray.gox: index/suffixarray.lo
 	$(BUILDGOX)
@@ -2924,6 +3053,8 @@ net/textproto.gox: net/textproto.lo
 
 os/inotify.gox: os/inotify.lo
 	$(BUILDGOX)
+os/user.gox: os/user.lo
+	$(BUILDGOX)
 os/signal.gox: os/signal.lo
 	$(BUILDGOX)
 
@@ -3054,22 +3185,30 @@ TEST_PACKAGES = \
 	exp/datafmt/check \
 	exp/draw/check \
 	exp/eval/check \
+	go/ast/check \
 	go/parser/check \
 	go/printer/check \
 	go/scanner/check \
 	go/token/check \
 	go/typechecker/check \
+	$(go_types_check_omitted_since_it_calls_6g) \
 	hash/adler32/check \
 	hash/crc32/check \
 	hash/crc64/check \
 	hash/fnv/check \
 	http/cgi/check \
+	http/fcgi/check \
+	http/spdy/check \
+	image/jpeg/check \
 	image/png/check \
+	image/tiff/check \
+	image/ycbcr/check \
 	index/suffixarray/check \
 	io/ioutil/check \
 	mime/multipart/check \
 	net/textproto/check \
 	$(os_inotify_check) \
+	os/user/check \
 	os/signal/check \
 	path/filepath/check \
 	rpc/jsonrpc/check \
Index: libgo/MERGE
===================================================================
--- libgo/MERGE	(revision 173685)
+++ libgo/MERGE	(working copy)
@@ -1,4 +1,4 @@
-f618e5e0991d
+aea0ba6e5935
 
 The first line of this file holds the Mercurial revision number of the
 last merge done from the master library sources.
Index: libgo/mksysinfo.sh
===================================================================
--- libgo/mksysinfo.sh	(revision 173685)
+++ libgo/mksysinfo.sh	(working copy)
@@ -74,6 +74,8 @@ cat > sysinfo.c <<EOF
 #include <sys/select.h>
 #endif
 #include <unistd.h>
+#include <netdb.h>
+#include <pwd.h>
 EOF
 
 ${CC} -fdump-go-spec=gen-sysinfo.go -std=gnu99 -S -o sysinfo.s sysinfo.c
@@ -403,6 +405,10 @@ else
   echo "type Rusage struct {}" >> ${OUT}
 fi
 
+# The RUSAGE constants.
+grep '^const _RUSAGE_' gen-sysinfo.go | \
+  sed -e 's/^\(const \)_\(RUSAGE_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+
 # The utsname struct.
 grep '^type _utsname ' gen-sysinfo.go | \
     sed -e 's/_utsname/Utsname/' \
@@ -456,4 +462,20 @@ if test "$fd_set" != ""; then
 fi
 echo "type fds_bits_type $fds_bits_type" >> ${OUT}
 
+# The addrinfo struct.
+grep '^type _addrinfo ' gen-sysinfo.go | \
+    sed -e 's/_addrinfo/Addrinfo/g' \
+      -e 's/ ai_/ Ai_/g' \
+    >> ${OUT}
+
+# The addrinfo flags.
+grep '^const _AI_' gen-sysinfo.go | \
+  sed -e 's/^\(const \)_\(AI_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+
+# The passwd struct.
+grep '^type _passwd ' gen-sysinfo.go | \
+    sed -e 's/_passwd/Passwd/' \
+      -e 's/ pw_/ Pw_/g' \
+    >> ${OUT}
+
 exit $?
Index: libgo/runtime/go-reflect-chan.c
===================================================================
--- libgo/runtime/go-reflect-chan.c	(revision 173685)
+++ libgo/runtime/go-reflect-chan.c	(working copy)
@@ -8,30 +8,54 @@
 #include <stdint.h>
 
 #include "config.h"
+#include "go-alloc.h"
+#include "go-assert.h"
+#include "go-panic.h"
 #include "go-type.h"
 #include "channel.h"
 
 /* This file implements support for reflection on channels.  These
    functions are called from reflect/value.go.  */
 
-extern unsigned char *makechan (const struct __go_type_descriptor *, uint32_t)
+extern uintptr_t makechan (const struct __go_type_descriptor *, uint32_t)
   asm ("libgo_reflect.reflect.makechan");
 
-unsigned char *
+uintptr_t
 makechan (const struct __go_type_descriptor *typ, uint32_t size)
 {
-  return (unsigned char *) __go_new_channel (typ->__size, size);
+  struct __go_channel *channel;
+  void *ret;
+
+  __go_assert (typ->__code == GO_CHAN);
+  typ = ((const struct __go_channel_type *) typ)->__element_type;
+
+  channel = __go_new_channel (typ, size);
+
+  ret = __go_alloc (sizeof (void *));
+  __builtin_memcpy (ret, &channel, sizeof (void *));
+  return (uintptr_t) ret;
 }
 
-extern void chansend (unsigned char *, unsigned char *, _Bool *)
+extern _Bool chansend (uintptr_t, uintptr_t, _Bool)
   asm ("libgo_reflect.reflect.chansend");
 
-void
-chansend (unsigned char *ch, unsigned char *val, _Bool *selected)
+_Bool
+chansend (uintptr_t ch, uintptr_t val_i, _Bool nb)
 {
   struct __go_channel *channel = (struct __go_channel *) ch;
+  uintptr_t element_size;
+  void *pv;
+
+  if (channel == NULL)
+    __go_panic_msg ("send to nil channel");
+
+  if (__go_is_pointer_type (channel->element_type))
+    pv = &val_i;
+  else
+    pv = (void *) val_i;
 
-  if (channel->element_size <= sizeof (uint64_t))
+  element_size = channel->element_type->__size;
+  if (element_size <= sizeof (uint64_t))
     {
       union
       {
@@ -41,35 +65,60 @@ chansend (unsigned char *ch, unsigned ch
 
       __builtin_memset (u.b, 0, sizeof (uint64_t));
 #ifndef WORDS_BIGENDIAN
-      __builtin_memcpy (u.b, val, channel->element_size);
+      __builtin_memcpy (u.b, pv, element_size);
 #else
-      __builtin_memcpy (u.b + sizeof (uint64_t) - channel->element_size, val,
-			channel->element_size);
+      __builtin_memcpy (u.b + sizeof (uint64_t) - element_size, pv,
+			element_size);
 #endif
-      if (selected == NULL)
-	__go_send_small (channel, u.v, 0);
+      if (nb)
+	return __go_send_nonblocking_small (channel, u.v);
       else
-	*selected = __go_send_nonblocking_small (channel, u.v);
+	{
+	  __go_send_small (channel, u.v, 0);
+	  return 1;
+	}
     }
   else
     {
-      if (selected == NULL)
-	__go_send_big (channel, val, 0);
+      if (nb)
+	return __go_send_nonblocking_big (channel, pv);
       else
-	*selected = __go_send_nonblocking_big (channel, val);
+	{
+	  __go_send_big (channel, pv, 0);
+	  return 1;
+	}
     }
 }
 
-extern void chanrecv (unsigned char *, unsigned char *, _Bool *, _Bool *)
+struct chanrecv_ret
+{
+  uintptr_t val;
+  _Bool selected;
+  _Bool received;
+};
+
+extern struct chanrecv_ret chanrecv (uintptr_t, _Bool)
   asm ("libgo_reflect.reflect.chanrecv");
 
-void
-chanrecv (unsigned char *ch, unsigned char *val, _Bool *selected,
-	  _Bool *received)
+struct chanrecv_ret
+chanrecv (uintptr_t ch, _Bool nb)
 {
   struct __go_channel *channel = (struct __go_channel *) ch;
+  void *pv;
+  uintptr_t element_size;
+  struct chanrecv_ret ret;
+
+  element_size = channel->element_type->__size;
 
-  if (channel->element_size <= sizeof (uint64_t))
+  if (__go_is_pointer_type (channel->element_type))
+    pv = &ret.val;
+  else
+    {
+      pv = __go_alloc (element_size);
+      ret.val = (uintptr_t) pv;
+    }
+
+  if (element_size <= sizeof (uint64_t))
     {
       union
       {
@@ -77,74 +126,73 @@ chanrecv (unsigned char *ch, unsigned ch
 	uint64_t v;
       } u;
 
-      if (selected == NULL)
-	u.v = __go_receive_small_closed (channel, 0, received);
+      if (!nb)
+	{
+	  u.v = __go_receive_small_closed (channel, 0, &ret.received);
+	  ret.selected = 1;
+	}
       else
 	{
 	  struct __go_receive_nonblocking_small s;
 
 	  s = __go_receive_nonblocking_small (channel);
-	  *selected = s.__success || s.__closed;
-	  if (received != NULL)
-	    *received = s.__success;
+	  ret.selected = s.__success || s.__closed;
+	  ret.received = s.__success;
 	  u.v = s.__val;
 	}
 
 #ifndef WORDS_BIGENDIAN
-      __builtin_memcpy (val, u.b, channel->element_size);
+      __builtin_memcpy (pv, u.b, element_size);
 #else
-      __builtin_memcpy (val, u.b + sizeof (uint64_t) - channel->element_size,
-			channel->element_size);
+      __builtin_memcpy (pv, u.b + sizeof (uint64_t) - element_size,
+			element_size);
 #endif
     }
   else
     {
-      if (selected == NULL)
+      if (!nb)
 	{
-	  _Bool success;
-
-	  success = __go_receive_big (channel, val, 0);
-	  if (received != NULL)
-	    *received = success;
+	  ret.received = __go_receive_big (channel, pv, 0);
+	  ret.selected = 1;
 	}
       else
 	{
 	  _Bool got;
 	  _Bool closed;
 
-	  got = __go_receive_nonblocking_big (channel, val, &closed);
-	  *selected = got || closed;
-	  if (received != NULL)
-	    *received = got;
+	  got = __go_receive_nonblocking_big (channel, pv, &closed);
+	  ret.selected = got || closed;
+	  ret.received = got;
 	}
     }
+
+  return ret;
 }
 
-extern void chanclose (unsigned char *)
-  asm ("libgo_reflect.reflect.chanclose");
+extern void chanclose (uintptr_t) asm ("libgo_reflect.reflect.chanclose");
 
 void
-chanclose (unsigned char *ch)
+chanclose (uintptr_t ch)
 {
   struct __go_channel *channel = (struct __go_channel *) ch;
 
   __go_builtin_close (channel);
 }
 
-extern int32_t chanlen (unsigned char *) asm ("libgo_reflect.reflect.chanlen");
+extern int32_t chanlen (uintptr_t) asm ("libgo_reflect.reflect.chanlen");
 
 int32_t
-chanlen (unsigned char *ch)
+chanlen (uintptr_t ch)
 {
   struct __go_channel *channel = (struct __go_channel *) ch;
 
   return (int32_t) __go_chan_len (channel);
 }
 
-extern int32_t chancap (unsigned char *) asm ("libgo_reflect.reflect.chancap");
+extern int32_t chancap (uintptr_t) asm ("libgo_reflect.reflect.chancap");
 
 int32_t
-chancap (unsigned char *ch)
+chancap (uintptr_t ch)
 {
   struct __go_channel *channel = (struct __go_channel *) ch;
 
Index: libgo/runtime/channel.h
===================================================================
--- libgo/runtime/channel.h	(revision 173685)
+++ libgo/runtime/channel.h	(working copy)
@@ -7,6 +7,8 @@
 #include <stdint.h>
 #include <pthread.h>
 
+#include "go-type.h"
+
 /* This structure is used when a select is waiting for a synchronous
    channel.  */
 
@@ -34,8 +36,8 @@ struct __go_channel
   /* A condition variable.  This is signalled when data is added to
      the channel and when data is removed from the channel.  */
   pthread_cond_t cond;
-  /* The size of elements on this channel.  */
-  size_t element_size;
+  /* The type of elements on this channel.  */
+  const struct __go_type_descriptor *element_type;
   /* True if a goroutine is waiting to send on a synchronous
      channel.  */
   _Bool waiting_to_send;
@@ -82,7 +84,8 @@ typedef struct __go_channel __go_channel
    acquired while this mutex is held.  */
 extern pthread_mutex_t __go_select_data_mutex;
 
-extern struct __go_channel *__go_new_channel (uintptr_t, uintptr_t);
+extern struct __go_channel *
+__go_new_channel (const struct __go_type_descriptor *, uintptr_t);
 
 extern _Bool __go_synch_with_select (struct __go_channel *, _Bool);
 
Index: libgo/runtime/go-signal.c
===================================================================
--- libgo/runtime/go-signal.c	(revision 173685)
+++ libgo/runtime/go-signal.c	(working copy)
@@ -245,3 +245,26 @@ runtime_resetcpuprofiler(int32 hz)
 
   m->profilehz = hz;
 }
+
+/* Used by the os package to raise SIGPIPE.  */
+
+void os_sigpipe (void) __asm__ ("libgo_os.os.sigpipe");
+
+void
+os_sigpipe (void)
+{
+  struct sigaction sa;
+  int i;
+
+  memset (&sa, 0, sizeof sa);
+
+  sa.sa_handler = SIG_DFL;
+
+  i = sigemptyset (&sa.sa_mask);
+  __go_assert (i == 0);
+
+  if (sigaction (SIGPIPE, &sa, NULL) != 0)
+    abort ();
+
+  raise (SIGPIPE);
+}
Index: libgo/runtime/go-send-big.c
===================================================================
--- libgo/runtime/go-send-big.c	(revision 173685)
+++ libgo/runtime/go-send-big.c	(working copy)
@@ -12,19 +12,20 @@
 void
 __go_send_big (struct __go_channel* channel, const void *val, _Bool for_select)
 {
+  uintptr_t element_size;
   size_t alloc_size;
   size_t offset;
 
   if (channel == NULL)
     __go_panic_msg ("send to nil channel");
 
-  alloc_size = ((channel->element_size + sizeof (uint64_t) - 1)
-		/ sizeof (uint64_t));
+  element_size = channel->element_type->__size;
+  alloc_size = (element_size + sizeof (uint64_t) - 1) / sizeof (uint64_t);
 
   __go_send_acquire (channel, for_select);
 
   offset = channel->next_store * alloc_size;
-  __builtin_memcpy (&channel->data[offset], val, channel->element_size);
+  __builtin_memcpy (&channel->data[offset], val, element_size);
 
   __go_send_release (channel);
 }
Index: libgo/runtime/iface.goc
===================================================================
--- libgo/runtime/iface.goc	(revision 173685)
+++ libgo/runtime/iface.goc	(working copy)
@@ -3,6 +3,7 @@
 // license that can be found in the LICENSE file.
 
 package runtime
+#include "go-panic.h"
 #include "go-type.h"
 #include "interface.h"
 #define nil NULL
@@ -33,6 +34,8 @@ func ifacetype(i interface) (d *const_de
 
 // Convert an empty interface to an empty interface.
 func ifaceE2E2(e empty_interface) (ret empty_interface, ok bool) {
+	if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
+		__go_panic_msg("invalid interface value");
 	ret = e;
 	ok = ret.__type_descriptor != nil;
 }
@@ -52,6 +55,8 @@ func ifaceI2E2(i interface) (ret empty_i
 
 // Convert an empty interface to a non-empty interface.
 func ifaceE2I2(inter *descriptor, e empty_interface) (ret interface, ok bool) {
+	if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
+		__go_panic_msg("invalid interface value");
 	if (e.__type_descriptor == nil) {
 		ret.__methods = nil;
 		ret.__object = nil;
@@ -81,6 +86,8 @@ func ifaceI2I2(inter *descriptor, i inte
 
 // Convert an empty interface to a pointer type.
 func ifaceE2T2P(inter *descriptor, e empty_interface) (ret *void, ok bool) {
+	if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
+		__go_panic_msg("invalid interface value");
 	if (!__go_type_descriptors_equal(inter, e.__type_descriptor)) {
 		ret = nil;
 		ok = 0;
@@ -104,6 +111,8 @@ func ifaceI2T2P(inter *descriptor, i int
 
 // Convert an empty interface to a non-pointer type.
 func ifaceE2T2(inter *descriptor, e empty_interface, ret *void) (ok bool) {
+	if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
+		__go_panic_msg("invalid interface value");
 	if (!__go_type_descriptors_equal(inter, e.__type_descriptor)) {
 		__builtin_memset(ret, 0, inter->__size);
 		ok = 0;
Index: libgo/runtime/go-send-nb-small.c
===================================================================
--- libgo/runtime/go-send-nb-small.c	(revision 173685)
+++ libgo/runtime/go-send-nb-small.c	(working copy)
@@ -93,7 +93,7 @@ __go_send_nonblocking_acquire (struct __
 _Bool
 __go_send_nonblocking_small (struct __go_channel *channel, uint64_t val)
 {
-  __go_assert (channel->element_size <= sizeof (uint64_t));
+  __go_assert (channel->element_type->__size <= sizeof (uint64_t));
 
   if (!__go_send_nonblocking_acquire (channel))
     return 0;
Index: libgo/runtime/chan.goc
===================================================================
--- libgo/runtime/chan.goc	(revision 173685)
+++ libgo/runtime/chan.goc	(working copy)
@@ -13,7 +13,8 @@ typedef struct __go_channel chan;
 /* Do a channel receive with closed status.  */
 
 func chanrecv2(c *chan, val *byte) (received bool) {
-	if (c->element_size > 8) {
+	uintptr_t element_size = c->element_type->__size;
+	if (element_size > 8) {
 		return __go_receive_big(c, val, 0);
 	} else {
 		union {
@@ -23,10 +24,9 @@ func chanrecv2(c *chan, val *byte) (rece
 
 		u.v = __go_receive_small_closed(c, 0, &received);
 #ifndef WORDS_BIGENDIAN
-		__builtin_memcpy(val, u.b, c->element_size);
+		__builtin_memcpy(val, u.b, element_size);
 #else
-		__builtin_memcpy(val, u.b + 8 - c->element_size,
-				 c->element_size);
+		__builtin_memcpy(val, u.b + 8 - element_size, element_size);
 #endif
 		return received;
 	}
@@ -35,7 +35,8 @@ func chanrecv2(c *chan, val *byte) (rece
 /* Do a channel receive with closed status for a select statement.  */
 
 func chanrecv3(c *chan, val *byte) (received bool) {
-	if (c->element_size > 8) {
+	uintptr_t element_size = c->element_type->__size;
+	if (element_size > 8) {
 		return __go_receive_big(c, val, 1);
 	} else {
 		union {
@@ -45,10 +46,9 @@ func chanrecv3(c *chan, val *byte) (rece
 
 		u.v = __go_receive_small_closed(c, 1, &received);
 #ifndef WORDS_BIGENDIAN
-		__builtin_memcpy(val, u.b, c->element_size);
+		__builtin_memcpy(val, u.b, element_size);
 #else
-		__builtin_memcpy(val, u.b + 8 - c->element_size,
-				 c->element_size);
+		__builtin_memcpy(val, u.b + 8 - element_size, element_size);
 #endif
 		return received;
 	}
Index: libgo/runtime/go-reflect-call.c
===================================================================
--- libgo/runtime/go-reflect-call.c	(revision 173685)
+++ libgo/runtime/go-reflect-call.c	(working copy)
@@ -14,9 +14,32 @@
 #include "go-type.h"
 #include "runtime.h"
 
-/* Forward declaration.  */
-
-static ffi_type *go_type_to_ffi (const struct __go_type_descriptor *);
+/* The functions in this file are only called from reflect_call.  As
+   reflect_call calls a libffi function, which will be compiled
+   without -fsplit-stack, it will always run with a large stack.  */
+
+static ffi_type *go_array_to_ffi (const struct __go_array_type *)
+  __attribute__ ((no_split_stack));
+static ffi_type *go_slice_to_ffi (const struct __go_slice_type *)
+  __attribute__ ((no_split_stack));
+static ffi_type *go_struct_to_ffi (const struct __go_struct_type *)
+  __attribute__ ((no_split_stack));
+static ffi_type *go_string_to_ffi (void) __attribute__ ((no_split_stack));
+static ffi_type *go_interface_to_ffi (void) __attribute__ ((no_split_stack));
+static ffi_type *go_complex_to_ffi (ffi_type *)
+  __attribute__ ((no_split_stack));
+static ffi_type *go_type_to_ffi (const struct __go_type_descriptor *)
+  __attribute__ ((no_split_stack));
+static ffi_type *go_func_return_ffi (const struct __go_func_type *)
+  __attribute__ ((no_split_stack));
+static void go_func_to_cif (const struct __go_func_type *, _Bool, _Bool,
+			    ffi_cif *)
+  __attribute__ ((no_split_stack));
+static size_t go_results_size (const struct __go_func_type *)
+  __attribute__ ((no_split_stack));
+static void go_set_results (const struct __go_func_type *, unsigned char *,
+			    void **)
+  __attribute__ ((no_split_stack));
 
 /* Return an ffi_type for a Go array type.  The libffi library does
    not have any builtin support for passing arrays as values.  We work
@@ -31,7 +54,6 @@ go_array_to_ffi (const struct __go_array
   uintptr_t i;
 
   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
-  __builtin_memset (ret, 0, sizeof (ffi_type));
   ret->type = FFI_TYPE_STRUCT;
   len = descriptor->__len;
   ret->elements = (ffi_type **) __go_alloc ((len + 1) * sizeof (ffi_type *));
@@ -52,7 +74,6 @@ go_slice_to_ffi (
   ffi_type *ret;
 
   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
-  __builtin_memset (ret, 0, sizeof (ffi_type));
   ret->type = FFI_TYPE_STRUCT;
   ret->elements = (ffi_type **) __go_alloc (4 * sizeof (ffi_type *));
   ret->elements[0] = &ffi_type_pointer;
@@ -73,7 +94,6 @@ go_struct_to_ffi (const struct __go_stru
   int i;
 
   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
-  __builtin_memset (ret, 0, sizeof (ffi_type));
   ret->type = FFI_TYPE_STRUCT;
   field_count = descriptor->__fields.__count;
   fields = (const struct __go_struct_field *) descriptor->__fields.__values;
@@ -237,7 +257,6 @@ go_func_return_ffi (const struct __go_fu
     return go_type_to_ffi (types[0]);
 
   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
-  __builtin_memset (ret, 0, sizeof (ffi_type));
   ret->type = FFI_TYPE_STRUCT;
   ret->elements = (ffi_type **) __go_alloc ((count + 1) * sizeof (ffi_type *));
   for (i = 0; i < count; ++i)
@@ -251,7 +270,7 @@ go_func_return_ffi (const struct __go_fu
 
 static void
 go_func_to_cif (const struct __go_func_type *func, _Bool is_interface,
-		ffi_cif *cif)
+		_Bool is_method, ffi_cif *cif)
 {
   int num_params;
   const struct __go_type_descriptor **in_types;
@@ -268,10 +287,19 @@ go_func_to_cif (const struct __go_func_t
 
   num_args = num_params + (is_interface ? 1 : 0);
   args = (ffi_type **) __go_alloc (num_args * sizeof (ffi_type *));
+  i = 0;
+  off = 0;
   if (is_interface)
-    args[0] = &ffi_type_pointer;
-  off = is_interface ? 1 : 0;
-  for (i = 0; i < num_params; ++i)
+    {
+      args[0] = &ffi_type_pointer;
+      off = 1;
+    }
+  else if (is_method)
+    {
+      args[0] = &ffi_type_pointer;
+      i = 1;
+    }
+  for (; i < num_params; ++i)
     args[i + off] = go_type_to_ffi (in_types[i]);
 
   rettype = go_func_return_ffi (func);
@@ -354,13 +382,14 @@ go_set_results (const struct __go_func_t
 
 void
 reflect_call (const struct __go_func_type *func_type, const void *func_addr,
-	      _Bool is_interface, void **params, void **results)
+	      _Bool is_interface, _Bool is_method, void **params,
+	      void **results)
 {
   ffi_cif cif;
   unsigned char *call_result;
 
   __go_assert (func_type->__common.__code == GO_FUNC);
-  go_func_to_cif (func_type, is_interface, &cif);
+  go_func_to_cif (func_type, is_interface, is_method, &cif);
 
   call_result = (unsigned char *) malloc (go_results_size (func_type));
 
Index: libgo/runtime/go-reflect-map.c
===================================================================
--- libgo/runtime/go-reflect-map.c	(revision 173685)
+++ libgo/runtime/go-reflect-map.c	(working copy)
@@ -8,69 +8,125 @@
 #include <stdint.h>
 
 #include "go-alloc.h"
+#include "go-panic.h"
 #include "go-type.h"
 #include "map.h"
 
 /* This file implements support for reflection on maps.  These
    functions are called from reflect/value.go.  */
 
-extern _Bool mapaccess (unsigned char *, unsigned char *, unsigned char *)
+struct mapaccess_ret
+{
+  uintptr_t val;
+  _Bool pres;
+};
+
+extern struct mapaccess_ret mapaccess (uintptr_t, uintptr_t)
   asm ("libgo_reflect.reflect.mapaccess");
 
-_Bool
-mapaccess (unsigned char *m, unsigned char *key, unsigned char *val)
+struct mapaccess_ret
+mapaccess (uintptr_t m, uintptr_t key_i)
 {
   struct __go_map *map = (struct __go_map *) m;
+  void *key;
+  const struct __go_type_descriptor *key_descriptor;
   void *p;
   const struct __go_type_descriptor *val_descriptor;
+  struct mapaccess_ret ret;
+  void *val;
+  void *pv;
+
+  if (map == NULL)
+    __go_panic_msg ("lookup in nil map");
+
+  key_descriptor = map->__descriptor->__map_descriptor->__key_type;
+  if (__go_is_pointer_type (key_descriptor))
+    key = &key_i;
+  else
+    key = (void *) key_i;
 
   p = __go_map_index (map, key, 0);
+
+  val_descriptor = map->__descriptor->__map_descriptor->__val_type;
+  if (__go_is_pointer_type (val_descriptor))
+    {
+      val = NULL;
+      pv = &val;
+    }
+  else
+    {
+      val = __go_alloc (val_descriptor->__size);
+      pv = val;
+    }
+
   if (p == NULL)
-    return 0;
+    ret.pres = 0;
   else
     {
-      val_descriptor = map->__descriptor->__map_descriptor->__val_type;
-      __builtin_memcpy (val, p, val_descriptor->__size);
-      return 1;
+      __builtin_memcpy (pv, p, val_descriptor->__size);
+      ret.pres = 1;
     }
+
+  ret.val = (uintptr_t) val;
+  return ret;
 }
 
-extern void mapassign (unsigned char *, unsigned char *, unsigned char *)
+extern void mapassign (uintptr_t, uintptr_t, uintptr_t, _Bool)
   asm ("libgo_reflect.reflect.mapassign");
 
 void
-mapassign (unsigned char *m, unsigned char *key, unsigned char *val)
+mapassign (uintptr_t m, uintptr_t key_i, uintptr_t val_i, _Bool pres)
 {
   struct __go_map *map = (struct __go_map *) m;
+  const struct __go_type_descriptor *key_descriptor;
+  void *key;
+
+  if (map == NULL)
+    __go_panic_msg ("lookup in nil map");
 
-  if (val == NULL)
+  key_descriptor = map->__descriptor->__map_descriptor->__key_type;
+  if (__go_is_pointer_type (key_descriptor))
+    key = &key_i;
+  else
+    key = (void *) key_i;
+
+  if (!pres)
     __go_map_delete (map, key);
   else
     {
       void *p;
       const struct __go_type_descriptor *val_descriptor;
+      void *pv;
 
       p = __go_map_index (map, key, 1);
+
       val_descriptor = map->__descriptor->__map_descriptor->__val_type;
-      __builtin_memcpy (p, val, val_descriptor->__size);
+      if (__go_is_pointer_type (val_descriptor))
+	pv = &val_i;
+      else
+	pv = (void *) val_i;
+      __builtin_memcpy (p, pv, val_descriptor->__size);
     }
 }
 
-extern int32_t maplen (unsigned char *)
+extern int32_t maplen (uintptr_t)
   asm ("libgo_reflect.reflect.maplen");
 
 int32_t
-maplen (unsigned char *m __attribute__ ((unused)))
+maplen (uintptr_t m)
 {
   struct __go_map *map = (struct __go_map *) m;
+
+  if (map == NULL)
+    return 0;
   return (int32_t) map->__element_count;
 }
 
-extern unsigned char *mapiterinit (unsigned char *)
+extern unsigned char *mapiterinit (uintptr_t)
   asm ("libgo_reflect.reflect.mapiterinit");
 
 unsigned char *
-mapiterinit (unsigned char *m)
+mapiterinit (uintptr_t m)
 {
   struct __go_hash_iter *it;
 
@@ -88,35 +144,67 @@ mapiternext (unsigned char *it)
   __go_mapiternext ((struct __go_hash_iter *) it);
 }
 
-extern _Bool mapiterkey (unsigned char *, unsigned char *)
+struct mapiterkey_ret
+{
+  uintptr_t key;
+  _Bool ok;
+};
+
+extern struct mapiterkey_ret mapiterkey (unsigned char *)
   asm ("libgo_reflect.reflect.mapiterkey");
 
-_Bool
-mapiterkey (unsigned char *ita, unsigned char *key)
+struct mapiterkey_ret
+mapiterkey (unsigned char *ita)
 {
   struct __go_hash_iter *it = (struct __go_hash_iter *) ita;
+  struct mapiterkey_ret ret;
 
   if (it->entry == NULL)
-    return 0;
+    {
+      ret.key = 0;
+      ret.ok = 0;
+    }
   else
     {
-      __go_mapiter1 (it, key);
-      return 1;
+      const struct __go_type_descriptor *key_descriptor;
+      void *key;
+      void *pk;
+
+      key_descriptor = it->map->__descriptor->__map_descriptor->__key_type;
+      if (__go_is_pointer_type (key_descriptor))
+	{
+	  key = NULL;
+	  pk = &key;
+	}
+      else
+	{
+	  key = __go_alloc (key_descriptor->__size);
+	  pk = key;
+	}
+
+      __go_mapiter1 (it, pk);
+
+      ret.key = (uintptr_t) key;
+      ret.ok = 1;
     }
+
+  return ret;
 }
 
 /* Make a new map.  We have to build our own map descriptor.  */
 
-extern unsigned char *makemap (const struct __go_map_type *)
+extern uintptr_t makemap (const struct __go_map_type *)
   asm ("libgo_reflect.reflect.makemap");
 
-unsigned char *
+uintptr_t
 makemap (const struct __go_map_type *t)
 {
   struct __go_map_descriptor *md;
   unsigned int o;
   const struct __go_type_descriptor *kt;
   const struct __go_type_descriptor *vt;
+  struct __go_map* map;
+  void *ret;
 
   /* FIXME: Reference count.  */
   md = (struct __go_map_descriptor *) __go_alloc (sizeof (*md));
@@ -135,5 +223,9 @@ makemap (const struct __go_map_type *t)
   o = (o + vt->__field_align - 1) & ~ (vt->__field_align - 1);
   md->__entry_size = o;
 
-  return (unsigned char *) __go_new_map (md, 0);
+  map = __go_new_map (md, 0);
+
+  ret = __go_alloc (sizeof (void *));
+  __builtin_memcpy (ret, &map, sizeof (void *));
+  return (uintptr_t) ret;
 }
Index: libgo/runtime/go-setenv.c
===================================================================
--- libgo/runtime/go-setenv.c	(revision 0)
+++ libgo/runtime/go-setenv.c	(revision 0)
@@ -0,0 +1,50 @@
+/* go-setenv.c -- set the C environment from Go.
+
+   Copyright 2011 The Go Authors. All rights reserved.
+   Use of this source code is governed by a BSD-style
+   license that can be found in the LICENSE file.  */
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "go-alloc.h"
+#include "go-string.h"
+
+/* Set the C environment from Go.  This is called by os.Setenv.  */
+
+void setenv_c (struct __go_string, struct __go_string)
+  __asm__ ("libgo_os.os.setenv_c");
+
+void
+setenv_c (struct __go_string k, struct __go_string v)
+{
+  const unsigned char *ks;
+  unsigned char *kn;
+  const unsigned char *vs;
+  unsigned char *vn;
+
+  ks = k.__data;
+  kn = NULL;
+  if (ks[k.__length] != 0)
+    {
+      kn = __go_alloc (k.__length + 1);
+      __builtin_memcpy (kn, k.__data, k.__length);
+      ks = kn;
+    }
+
+  vs = v.__data;
+  vn = NULL;
+  if (vs[v.__length] != 0)
+    {
+      vn = __go_alloc (v.__length + 1);
+      __builtin_memcpy (vn, v.__data, v.__length);
+      vs = vn;
+    }
+
+  setenv ((const char *) ks, (const char *) vs, 1);
+
+  if (kn != NULL)
+    __go_free (kn);
+  if (vn != NULL)
+    __go_free (vn);
+}
Index: libgo/runtime/go-unsafe-newarray.c
===================================================================
--- libgo/runtime/go-unsafe-newarray.c	(revision 173685)
+++ libgo/runtime/go-unsafe-newarray.c	(working copy)
@@ -5,6 +5,7 @@
    license that can be found in the LICENSE file.  */
 
 #include "go-alloc.h"
+#include "go-panic.h"
 #include "go-type.h"
 #include "interface.h"
 
@@ -21,6 +22,9 @@ NewArray (struct __go_empty_interface ty
 {
   const struct __go_type_descriptor *descriptor;
 
+  if (((uintptr_t) type.__type_descriptor & reflectFlags) != 0)
+    __go_panic_msg ("invalid interface value");
+
   /* FIXME: We should check __type_descriptor to verify that this is
      really a type descriptor.  */
   descriptor = (const struct __go_type_descriptor *) type.__object;
Index: libgo/runtime/mcache.c
===================================================================
--- libgo/runtime/mcache.c	(revision 173685)
+++ libgo/runtime/mcache.c	(working copy)
@@ -22,6 +22,8 @@ runtime_MCache_Alloc(MCache *c, int32 si
 		// Replenish using central lists.
 		n = runtime_MCentral_AllocList(&runtime_mheap.central[sizeclass],
 			runtime_class_to_transfercount[sizeclass], &first);
+		if(n == 0)
+			runtime_throw("out of memory");
 		l->list = first;
 		l->nlist = n;
 		c->size += n*size;
Index: libgo/runtime/go-reflect.c
===================================================================
--- libgo/runtime/go-reflect.c	(revision 173685)
+++ libgo/runtime/go-reflect.c	(working copy)
@@ -121,6 +121,9 @@ Reflect (struct __go_empty_interface e)
 {
   struct reflect_ret ret;
 
+  if (((uintptr_t) e.__type_descriptor & reflectFlags) != 0)
+    __go_panic_msg ("invalid interface value");
+
   if (e.__type_descriptor == NULL)
     {
       ret.rettype.__type_descriptor = NULL;
@@ -166,6 +169,9 @@ Typeof (const struct __go_empty_interfac
 {
   struct __go_empty_interface ret;
 
+  if (((uintptr_t) e.__type_descriptor & reflectFlags) != 0)
+    __go_panic_msg ("invalid interface value");
+
   if (e.__type_descriptor == NULL)
     {
       ret.__type_descriptor = NULL;
Index: libgo/runtime/go-interface-eface-compare.c
===================================================================
--- libgo/runtime/go-interface-eface-compare.c	(revision 173685)
+++ libgo/runtime/go-interface-eface-compare.c	(working copy)
@@ -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 "go-panic.h"
 #include "interface.h"
 
 /* Compare a non-empty interface value with an empty interface value.
@@ -16,6 +17,8 @@ __go_interface_empty_compare (struct __g
 {
   const struct __go_type_descriptor *left_descriptor;
 
+  if (((uintptr_t) right.__type_descriptor & reflectFlags) != 0)
+    __go_panic_msg ("invalid interface value");
   if (left.__methods == NULL && right.__type_descriptor == NULL)
     return 0;
   if (left.__methods == NULL || right.__type_descriptor == NULL)
Index: libgo/runtime/go-send-nb-big.c
===================================================================
--- libgo/runtime/go-send-nb-big.c	(revision 173685)
+++ libgo/runtime/go-send-nb-big.c	(working copy)
@@ -11,17 +11,18 @@
 _Bool
 __go_send_nonblocking_big (struct __go_channel* channel, const void *val)
 {
+  uintptr_t element_size;
   size_t alloc_size;
   size_t offset;
 
-  alloc_size = ((channel->element_size + sizeof (uint64_t) - 1)
-		/ sizeof (uint64_t));
+  element_size = channel->element_type->__size;
+  alloc_size = (element_size + sizeof (uint64_t) - 1) / sizeof (uint64_t);
 
   if (!__go_send_nonblocking_acquire (channel))
     return 0;
 
   offset = channel->next_store * alloc_size;
-  __builtin_memcpy (&channel->data[offset], val, channel->element_size);
+  __builtin_memcpy (&channel->data[offset], val, element_size);
 
   __go_send_release (channel);
 
Index: libgo/runtime/go-type.h
===================================================================
--- libgo/runtime/go-type.h	(revision 173685)
+++ libgo/runtime/go-type.h	(working copy)
@@ -149,6 +149,9 @@ struct __go_array_type
   /* The element type.  */
   struct __go_type_descriptor *__element_type;
 
+  /* The type of a slice of the same element type.  */
+  struct __go_type_descriptor *__slice_type;
+
   /* The length of the array.  */
   uintptr_t __len;
 };
@@ -289,6 +292,15 @@ struct __go_struct_type
   struct __go_open_array __fields;
 };
 
+/* If an empty interface has these bits set in its type pointer, it
+   was copied from a reflect.Value and is not a valid empty
+   interface.  */
+
+enum 
+{
+  reflectFlags = 3,
+};
+
 /* Whether a type descriptor is a pointer.  */
 
 static inline _Bool
Index: libgo/runtime/malloc.goc
===================================================================
--- libgo/runtime/malloc.goc	(revision 173685)
+++ libgo/runtime/malloc.goc	(working copy)
@@ -386,7 +386,7 @@ runtime_MHeap_SysAlloc(MHeap *h, uintptr
 		return nil;
 
 	if(p < h->arena_start || (uintptr)(p+n - h->arena_start) >= MaxArena32) {
-		runtime_printf("runtime: memory allocated by OS not in usable range");
+		runtime_printf("runtime: memory allocated by OS not in usable range\n");
 		runtime_SysFree(p, n);
 		return nil;
 	}
Index: libgo/runtime/go-send-small.c
===================================================================
--- libgo/runtime/go-send-small.c	(revision 173685)
+++ libgo/runtime/go-send-small.c	(working copy)
@@ -147,7 +147,7 @@ __go_send_small (struct __go_channel *ch
   if (channel == NULL)
     __go_panic_msg ("send to nil channel");
 
-  __go_assert (channel->element_size <= sizeof (uint64_t));
+  __go_assert (channel->element_type->__size <= sizeof (uint64_t));
 
   __go_send_acquire (channel, for_select);
 
Index: libgo/runtime/go-new-channel.c
===================================================================
--- libgo/runtime/go-new-channel.c	(revision 173685)
+++ libgo/runtime/go-new-channel.c	(working copy)
@@ -13,12 +13,16 @@
 #include "channel.h"
 
 struct __go_channel*
-__go_new_channel (uintptr_t element_size, uintptr_t entries)
+__go_new_channel (const struct __go_type_descriptor *element_type,
+		  uintptr_t entries)
 {
+  uintptr_t element_size;
   struct __go_channel* ret;
   size_t alloc_size;
   int i;
 
+  element_size = element_type->__size;
+
   if ((uintptr_t) (int) entries != entries
       || entries > (uintptr_t) -1 / element_size)
     __go_panic_msg ("chan size out of range");
@@ -40,7 +44,7 @@ __go_new_channel (uintptr_t element_size
   __go_assert (i == 0);
   i = pthread_cond_init (&ret->cond, NULL);
   __go_assert (i == 0);
-  ret->element_size = element_size;
+  ret->element_type = element_type;
   ret->waiting_to_send = 0;
   ret->waiting_to_receive = 0;
   ret->selected_for_send = 0;
Index: libgo/runtime/go-rec-big.c
===================================================================
--- libgo/runtime/go-rec-big.c	(revision 173685)
+++ libgo/runtime/go-rec-big.c	(working copy)
@@ -15,23 +15,24 @@
 _Bool
 __go_receive_big (struct __go_channel *channel, void *val, _Bool for_select)
 {
+  uintptr_t element_size;
   size_t alloc_size;
   size_t offset;
 
   if (channel == NULL)
     __go_panic_msg ("receive from nil channel");
 
-  alloc_size = ((channel->element_size + sizeof (uint64_t) - 1)
-		/ sizeof (uint64_t));
+  element_size = channel->element_type->__size;
+  alloc_size = (element_size + sizeof (uint64_t) - 1) / sizeof (uint64_t);
 
   if (!__go_receive_acquire (channel, for_select))
     {
-      __builtin_memset (val, 0, channel->element_size);
+      __builtin_memset (val, 0, element_size);
       return 0;
     }
 
   offset = channel->next_fetch * alloc_size;
-  __builtin_memcpy (val, &channel->data[offset], channel->element_size);
+  __builtin_memcpy (val, &channel->data[offset], element_size);
 
   __go_receive_release (channel);
 
Index: libgo/runtime/go-rec-nb-small.c
===================================================================
--- libgo/runtime/go-rec-nb-small.c	(revision 173685)
+++ libgo/runtime/go-rec-nb-small.c	(working copy)
@@ -94,9 +94,11 @@ __go_receive_nonblocking_acquire (struct
 struct __go_receive_nonblocking_small
 __go_receive_nonblocking_small (struct __go_channel *channel)
 {
+  uintptr_t element_size;
   struct __go_receive_nonblocking_small ret;
 
-  __go_assert (channel->element_size <= sizeof (uint64_t));
+  element_size = channel->element_type->__size;
+  __go_assert (element_size <= sizeof (uint64_t));
 
   int data = __go_receive_nonblocking_acquire (channel);
   if (data != RECEIVE_NONBLOCKING_ACQUIRE_DATA)
Index: libgo/runtime/go-type-eface.c
===================================================================
--- libgo/runtime/go-type-eface.c	(revision 173685)
+++ libgo/runtime/go-type-eface.c	(working copy)
@@ -5,6 +5,7 @@
    license that can be found in the LICENSE file.  */
 
 #include "interface.h"
+#include "go-panic.h"
 #include "go-type.h"
 
 /* A hash function for an empty interface.  */
@@ -43,6 +44,9 @@ __go_type_equal_empty_interface (const v
   v2 = (const struct __go_empty_interface *) vv2;
   v1_descriptor = v1->__type_descriptor;
   v2_descriptor = v2->__type_descriptor;
+  if (((uintptr_t) v1_descriptor & reflectFlags) != 0
+      || ((uintptr_t) v2_descriptor & reflectFlags) != 0)
+    __go_panic_msg ("invalid interface value");
   if (v1_descriptor == NULL || v2_descriptor == NULL)
     return v1_descriptor == v2_descriptor;
   if (!__go_type_descriptors_equal (v1_descriptor, v2_descriptor))
Index: libgo/runtime/runtime.h
===================================================================
--- libgo/runtime/runtime.h	(revision 173685)
+++ libgo/runtime/runtime.h	(working copy)
@@ -194,8 +194,8 @@ void	runtime_resetcpuprofiler(int32);
 void	runtime_setcpuprofilerate(void(*)(uintptr*, int32), int32);
 
 struct __go_func_type;
-void reflect_call(const struct __go_func_type *, const void *, _Bool, void **,
-		  void **)
+void reflect_call(const struct __go_func_type *, const void *, _Bool, _Bool,
+		  void **, void **)
   asm ("libgo_reflect.reflect.call");
 
 #ifdef __rtems__
Index: libgo/runtime/go-unreflect.c
===================================================================
--- libgo/runtime/go-unreflect.c	(revision 173685)
+++ libgo/runtime/go-unreflect.c	(working copy)
@@ -5,6 +5,7 @@
    license that can be found in the LICENSE file.  */
 
 #include "go-alloc.h"
+#include "go-panic.h"
 #include "go-type.h"
 #include "interface.h"
 
@@ -19,6 +20,9 @@ Unreflect (struct __go_empty_interface t
 {
   struct __go_empty_interface ret;
 
+  if (((uintptr_t) type.__type_descriptor & reflectFlags) != 0)
+    __go_panic_msg ("invalid interface value");
+
   /* FIXME: We should check __type_descriptor to verify that this is
      really a type descriptor.  */
   ret.__type_descriptor = type.__object;
Index: libgo/runtime/go-rec-nb-big.c
===================================================================
--- libgo/runtime/go-rec-nb-big.c	(revision 173685)
+++ libgo/runtime/go-rec-nb-big.c	(working copy)
@@ -14,23 +14,24 @@ _Bool
 __go_receive_nonblocking_big (struct __go_channel* channel, void *val,
 			      _Bool *closed)
 {
+  uintptr_t element_size;
   size_t alloc_size;
   size_t offset;
 
-  alloc_size = ((channel->element_size + sizeof (uint64_t) - 1)
-		/ sizeof (uint64_t));
+  element_size = channel->element_type->__size;
+  alloc_size = (element_size + sizeof (uint64_t) - 1) / sizeof (uint64_t);
 
   int data = __go_receive_nonblocking_acquire (channel);
   if (data != RECEIVE_NONBLOCKING_ACQUIRE_DATA)
     {
-      __builtin_memset (val, 0, channel->element_size);
+      __builtin_memset (val, 0, element_size);
       if (closed != NULL)
 	*closed = data == RECEIVE_NONBLOCKING_ACQUIRE_CLOSED;
       return 0;
     }
 
   offset = channel->next_fetch * alloc_size;
-  __builtin_memcpy (val, &channel->data[offset], channel->element_size);
+  __builtin_memcpy (val, &channel->data[offset], element_size);
 
   __go_receive_release (channel);
 
Index: libgo/runtime/go-eface-val-compare.c
===================================================================
--- libgo/runtime/go-eface-val-compare.c	(revision 173685)
+++ libgo/runtime/go-eface-val-compare.c	(working copy)
@@ -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 "go-panic.h"
 #include "go-type.h"
 #include "interface.h"
 
@@ -19,6 +20,8 @@ __go_empty_interface_value_compare (
   const struct __go_type_descriptor *left_descriptor;
 
   left_descriptor = left.__type_descriptor;
+  if (((uintptr_t) left_descriptor & reflectFlags) != 0)
+    __go_panic_msg ("invalid interface value");
   if (left_descriptor == NULL)
     return 1;
   if (!__go_type_descriptors_equal (left_descriptor, right_descriptor))
Index: libgo/runtime/reflect.goc
===================================================================
--- libgo/runtime/reflect.goc	(revision 173685)
+++ libgo/runtime/reflect.goc	(working copy)
@@ -5,31 +5,27 @@
 package reflect
 #include "go-type.h"
 #include "interface.h"
-#define nil NULL
-typedef unsigned char byte;
+#include "runtime.h"
+#include "go-panic.h"
 
+typedef struct __go_type_descriptor Type;
 typedef struct __go_interface Iface;
 typedef struct __go_empty_interface Eface;
 
-func setiface(typ *byte, x *byte, ret *byte) {
-	struct __go_interface_type *t;
-	const struct __go_type_descriptor* xt;
+func ifaceE2I(inter *Type, e Eface, ret *Iface) {
+	const Type *t;
+	Eface err;
 
-	/* FIXME: We should check __type_descriptor to verify that
-	   this is really a type descriptor.  */
-	t = (struct __go_interface_type *)typ;
-	if(t->__methods.__count == 0) {
-		// already an empty interface
-		*(Eface*)ret = *(Eface*)x;
-		return;
+	if(((uintptr)e.__type_descriptor&reflectFlags) != 0)
+		runtime_throw("invalid interface value");
+	t = e.__type_descriptor;
+	if(t == nil) {
+		// explicit conversions require non-nil interface value.
+		newTypeAssertionError(nil, nil, inter,
+			nil, nil, inter->__reflection,
+			nil, &err);
+		__go_panic(err);
 	}
-	xt = ((Eface*)x)->__type_descriptor;
-	if(xt == nil) {
-		// can assign nil to any interface
-		((Iface*)ret)->__methods = nil;
-		((Iface*)ret)->__object = nil;
-		return;
-	}
-	((Iface*)ret)->__methods = __go_convert_interface(&t->__common, xt);
-	((Iface*)ret)->__object = ((Eface*)x)->__object;
+	ret->__object = e.__object;
+	ret->__methods = __go_convert_interface(inter, t);
 }
Index: libgo/runtime/go-unsafe-new.c
===================================================================
--- libgo/runtime/go-unsafe-new.c	(revision 173685)
+++ libgo/runtime/go-unsafe-new.c	(working copy)
@@ -5,6 +5,7 @@
    license that can be found in the LICENSE file.  */
 
 #include "go-alloc.h"
+#include "go-panic.h"
 #include "go-type.h"
 #include "interface.h"
 
@@ -20,6 +21,9 @@ New (struct __go_empty_interface type)
 {
   const struct __go_type_descriptor *descriptor;
 
+  if (((uintptr_t) type.__type_descriptor & reflectFlags) != 0)
+    __go_panic_msg ("invalid interface value");
+
   /* FIXME: We should check __type_descriptor to verify that this is
      really a type descriptor.  */
   descriptor = (const struct __go_type_descriptor *) type.__object;
Index: libgo/runtime/go-rec-small.c
===================================================================
--- libgo/runtime/go-rec-small.c	(revision 173685)
+++ libgo/runtime/go-rec-small.c	(working copy)
@@ -266,12 +266,14 @@ uint64_t
 __go_receive_small_closed (struct __go_channel *channel, _Bool for_select,
 			   _Bool *received)
 {
+  uintptr_t element_size;
   uint64_t ret;
 
   if (channel == NULL)
     __go_panic_msg ("receive from nil channel");
 
-  __go_assert (channel->element_size <= sizeof (uint64_t));
+  element_size = channel->element_type->__size;
+  __go_assert (element_size <= sizeof (uint64_t));
 
   if (!__go_receive_acquire (channel, for_select))
     {
Index: libgo/runtime/mgc0.c
===================================================================
--- libgo/runtime/mgc0.c	(revision 173685)
+++ libgo/runtime/mgc0.c	(working copy)
@@ -90,6 +90,11 @@ scanblock(byte *b, int64 n)
 	void **bw, **w, **ew;
 	Workbuf *wbuf;
 
+	if((int64)(uintptr)n != n || n < 0) {
+		// runtime_printf("scanblock %p %lld\n", b, (long long)n);
+		runtime_throw("scanblock");
+	}
+
 	// Memory arena parameters.
 	arena_start = runtime_mheap.arena_start;
 	
@@ -602,7 +607,7 @@ runfinq(void* dummy)
 
 			next = f->next;
 			params[0] = &f->arg;
-			reflect_call(f->ft, (void*)f->fn, 0, params, nil);
+			reflect_call(f->ft, (void*)f->fn, 0, 0, params, nil);
 			f->fn = nil;
 			f->arg = nil;
 			f->next = nil;
Index: libgo/runtime/go-eface-compare.c
===================================================================
--- libgo/runtime/go-eface-compare.c	(revision 173685)
+++ libgo/runtime/go-eface-compare.c	(working copy)
@@ -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 "go-panic.h"
 #include "interface.h"
 
 /* Compare two interface values.  Return 0 for equal, not zero for not
@@ -16,6 +17,11 @@ __go_empty_interface_compare (struct __g
   const struct __go_type_descriptor *left_descriptor;
 
   left_descriptor = left.__type_descriptor;
+
+  if (((uintptr_t) left_descriptor & reflectFlags) != 0
+      || ((uintptr_t) right.__type_descriptor & reflectFlags) != 0)
+    __go_panic_msg ("invalid interface value");
+
   if (left_descriptor == NULL && right.__type_descriptor == NULL)
     return 0;
   if (left_descriptor == NULL || right.__type_descriptor == NULL)
Index: libgo/runtime/mheap.c
===================================================================
--- libgo/runtime/mheap.c	(revision 173685)
+++ libgo/runtime/mheap.c	(working copy)
@@ -181,9 +181,7 @@ MHeap_Grow(MHeap *h, uintptr npage)
 	// Allocate a multiple of 64kB (16 pages).
 	npage = (npage+15)&~15;
 	ask = npage<<PageShift;
-	if(ask > (uintptr)(h->arena_end - h->arena_used))
-		return false;
-	if(ask < HeapAllocChunk && HeapAllocChunk <= h->arena_end - h->arena_used)
+	if(ask < HeapAllocChunk)
 		ask = HeapAllocChunk;
 
 	v = runtime_MHeap_SysAlloc(h, ask);
@@ -192,8 +190,10 @@ MHeap_Grow(MHeap *h, uintptr npage)
 			ask = npage<<PageShift;
 			v = runtime_MHeap_SysAlloc(h, ask);
 		}
-		if(v == nil)
+		if(v == nil) {
+			runtime_printf("runtime: out of memory: cannot allocate %llu-byte block (%llu in use)\n", (unsigned long long)ask, (unsigned long long)mstats.heap_sys);
 			return false;
+		}
 	}
 	mstats.heap_sys += ask;
 
Index: libgo/syscalls/syscall_unix.go
===================================================================
--- libgo/syscalls/syscall_unix.go	(revision 173685)
+++ libgo/syscalls/syscall_unix.go	(working copy)
@@ -56,3 +56,12 @@ func munmap(addr uintptr, length uintptr
 	}
 	return
 }
+
+func libc_getrusage(who int, rusage *Rusage) int __asm__ ("getrusage")
+
+func Getrusage(who int, rusage *Rusage) (errno int) {
+	if libc_getrusage(who, rusage) < 0 {
+		errno = GetErrno()
+	}
+	return
+}
Index: libgo/syscalls/stringbyte.go
===================================================================
--- libgo/syscalls/stringbyte.go	(revision 173685)
+++ libgo/syscalls/stringbyte.go	(working copy)
@@ -6,6 +6,8 @@
 
 package syscall
 
+import "unsafe"
+
 // StringByteSlice returns a NUL-terminated slice of bytes
 // containing the text of s.
 func StringByteSlice(s string) []byte {
@@ -22,3 +24,14 @@ func StringBytePtr(s string) *byte {
 	p := StringByteSlice(s);
 	return &p[0];
 }
+
+// BytePtrToString takes a NUL-terminated array of bytes and convert
+// it to a Go string.
+func BytePtrToString(p *byte) string {
+	a := (*[10000]byte)(unsafe.Pointer(p))
+	i := 0
+	for a[i] != 0 {
+		i++
+	}
+	return string(a[:i])
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]