Commit 9f99d531 authored by Russ Cox's avatar Russ Cox

[dev.cc] runtime/cgo: convert from C to Go

The conversion was done with an automated tool and then
modified only as necessary to make it compile and run.

[This CL is part of the removal of C code from package runtime.
See golang.org/s/dev.cc for an overview.]

LGTM=r
R=r
CC=austin, dvyukov, golang-codereviews, iant, khr
https://golang.org/cl/168500043
parent fee9e475
// Copyright 2014 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.
package runtime
import "unsafe"
//go:cgo_export_static main
// Filled in by runtime/cgo when linked into binary.
//go:linkname _cgo_init _cgo_init
//go:linkname _cgo_malloc _cgo_malloc
//go:linkname _cgo_free _cgo_free
//go:linkname _cgo_thread_start _cgo_thread_start
var (
_cgo_init unsafe.Pointer
_cgo_malloc unsafe.Pointer
_cgo_free unsafe.Pointer
_cgo_thread_start unsafe.Pointer
)
...@@ -2,21 +2,25 @@ ...@@ -2,21 +2,25 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
#include "../runtime.h" package cgo
#include "../cgocall.h"
#include "textflag.h" import "unsafe"
// These utility functions are available to be called from code // These utility functions are available to be called from code
// compiled with gcc via crosscall2. // compiled with gcc via crosscall2.
// cgocallback is defined in runtime
//go:linkname _runtime_cgocallback runtime.cgocallback
func _runtime_cgocallback(unsafe.Pointer, unsafe.Pointer, uintptr)
// The declaration of crosscall2 is: // The declaration of crosscall2 is:
// void crosscall2(void (*fn)(void *, int), void *, int); // void crosscall2(void (*fn)(void *, int), void *, int);
// //
// We need to export the symbol crosscall2 in order to support // We need to export the symbol crosscall2 in order to support
// callbacks from shared libraries. This applies regardless of // callbacks from shared libraries. This applies regardless of
// linking mode. // linking mode.
#pragma cgo_export_static crosscall2 //go:cgo_export_static crosscall2
#pragma cgo_export_dynamic crosscall2 //go:cgo_export_dynamic crosscall2
// Allocate memory. This allocates the requested number of bytes in // Allocate memory. This allocates the requested number of bytes in
// memory controlled by the Go runtime. The allocated memory will be // memory controlled by the Go runtime. The allocated memory will be
...@@ -33,15 +37,15 @@ ...@@ -33,15 +37,15 @@
// crosscall2(_cgo_allocate, &a, sizeof a); // crosscall2(_cgo_allocate, &a, sizeof a);
// /* Here a.ret is a pointer to the allocated memory. */ // /* Here a.ret is a pointer to the allocated memory. */
void runtime·_cgo_allocate_internal(void); //go:linkname _runtime_cgo_allocate_internal runtime._cgo_allocate_internal
var _runtime_cgo_allocate_internal byte
#pragma cgo_export_static _cgo_allocate //go:linkname _cgo_allocate _cgo_allocate
#pragma cgo_export_dynamic _cgo_allocate //go:cgo_export_static _cgo_allocate
#pragma textflag NOSPLIT //go:cgo_export_dynamic _cgo_allocate
void //go:nosplit
_cgo_allocate(void *a, int32 n) func _cgo_allocate(a unsafe.Pointer, n int32) {
{ _runtime_cgocallback(unsafe.Pointer(&_runtime_cgo_allocate_internal), a, uintptr(n))
runtime·cgocallback((void(*)(void))runtime·_cgo_allocate_internal, a, n);
} }
// Panic. The argument is converted into a Go string. // Panic. The argument is converted into a Go string.
...@@ -52,32 +56,40 @@ _cgo_allocate(void *a, int32 n) ...@@ -52,32 +56,40 @@ _cgo_allocate(void *a, int32 n)
// crosscall2(_cgo_panic, &a, sizeof a); // crosscall2(_cgo_panic, &a, sizeof a);
// /* The function call will not return. */ // /* The function call will not return. */
void runtime·_cgo_panic_internal(void); //go:linkname _runtime_cgo_panic_internal runtime._cgo_panic_internal
var _runtime_cgo_panic_internal byte
#pragma cgo_export_static _cgo_panic //go:linkname _cgo_panic _cgo_panic
#pragma cgo_export_dynamic _cgo_panic //go:cgo_export_static _cgo_panic
#pragma textflag NOSPLIT //go:cgo_export_dynamic _cgo_panic
void //go:nosplit
_cgo_panic(void *a, int32 n) func _cgo_panic(a unsafe.Pointer, n int32) {
{ _runtime_cgocallback(unsafe.Pointer(&_runtime_cgo_panic_internal), a, uintptr(n))
runtime·cgocallback((void(*)(void))runtime·_cgo_panic_internal, a, n);
} }
#pragma cgo_import_static x_cgo_init //go:cgo_import_static x_cgo_init
extern void x_cgo_init(G*); //go:linkname x_cgo_init x_cgo_init
void (*_cgo_init)(G*) = x_cgo_init; //go:linkname _cgo_init _cgo_init
var x_cgo_init byte
#pragma cgo_import_static x_cgo_malloc var _cgo_init = &x_cgo_init
extern void x_cgo_malloc(void*);
void (*_cgo_malloc)(void*) = x_cgo_malloc; //go:cgo_import_static x_cgo_malloc
//go:linkname x_cgo_malloc x_cgo_malloc
#pragma cgo_import_static x_cgo_free //go:linkname _cgo_malloc _cgo_malloc
extern void x_cgo_free(void*); var x_cgo_malloc byte
void (*_cgo_free)(void*) = x_cgo_free; var _cgo_malloc = &x_cgo_malloc
#pragma cgo_import_static x_cgo_thread_start //go:cgo_import_static x_cgo_free
extern void x_cgo_thread_start(void*); //go:linkname x_cgo_free x_cgo_free
void (*_cgo_thread_start)(void*) = x_cgo_thread_start; //go:linkname _cgo_free _cgo_free
var x_cgo_free byte
#pragma cgo_export_static _cgo_topofstack var _cgo_free = &x_cgo_free
#pragma cgo_export_dynamic _cgo_topofstack
//go:cgo_import_static x_cgo_thread_start
//go:linkname x_cgo_thread_start x_cgo_thread_start
//go:linkname _cgo_thread_start _cgo_thread_start
var x_cgo_thread_start byte
var _cgo_thread_start = &x_cgo_thread_start
//go:cgo_export_static _cgo_topofstack
//go:cgo_export_dynamic _cgo_topofstack
...@@ -4,16 +4,16 @@ ...@@ -4,16 +4,16 @@
// +build dragonfly // +build dragonfly
#include "textflag.h" package cgo
import _ "unsafe"
// Supply environ and __progname, because we don't // Supply environ and __progname, because we don't
// link against the standard DragonFly crt0.o and the // link against the standard DragonFly crt0.o and the
// libc dynamic library needs them. // libc dynamic library needs them.
#pragma dataflag NOPTR //go:linkname _environ environ
char *environ[1]; //go:linkname _progname __progname
#pragma dataflag NOPTR
char *__progname;
#pragma dynexport environ environ var _environ uintptr
#pragma dynexport __progname __progname var _progname uintptr
...@@ -4,16 +4,14 @@ ...@@ -4,16 +4,14 @@
// +build freebsd // +build freebsd
#include "textflag.h" package cgo
// Supply environ and __progname, because we don't // Supply environ and __progname, because we don't
// link against the standard FreeBSD crt0.o and the // link against the standard FreeBSD crt0.o and the
// libc dynamic library needs them. // libc dynamic library needs them.
#pragma dataflag NOPTR //go:linkname _environ environ
char *environ[1]; //go:linkname _progname __progname
#pragma dataflag NOPTR
char *__progname;
#pragma dynexport environ environ var _environ uintptr
#pragma dynexport __progname __progname var _progname uintptr
...@@ -9,7 +9,12 @@ ...@@ -9,7 +9,12 @@
// correctly, and sometimes they break. This variable is a // correctly, and sometimes they break. This variable is a
// backup: it depends only on old C style static linking rules. // backup: it depends only on old C style static linking rules.
#include "../runtime.h" package cgo
bool runtime·iscgo = 1; import _ "unsafe"
uint32 runtime·needextram = 1; // create an extra M on first cgo call
//go:linkname _iscgo runtime.iscgo
var _iscgo bool = true
//go:linkname _needextram runtime.needextram
var _needextram uint32 = 1 // create an extra M on first cgo call
...@@ -4,16 +4,14 @@ ...@@ -4,16 +4,14 @@
// +build netbsd // +build netbsd
#include "textflag.h" package cgo
// Supply environ and __progname, because we don't // Supply environ and __progname, because we don't
// link against the standard NetBSD crt0.o and the // link against the standard NetBSD crt0.o and the
// libc dynamic library needs them. // libc dynamic library needs them.
#pragma dataflag NOPTR //go:linkname _environ environ
char *environ[1]; //go:linkname _progname __progname
#pragma dataflag NOPTR
char *__progname;
#pragma dynexport environ environ var _environ uintptr
#pragma dynexport __progname __progname var _progname uintptr
...@@ -4,24 +4,26 @@ ...@@ -4,24 +4,26 @@
// +build openbsd // +build openbsd
#include "textflag.h" package cgo
// Supply environ, __progname and __guard_local, because // Supply environ, __progname and __guard_local, because
// we don't link against the standard OpenBSD crt0.o and // we don't link against the standard OpenBSD crt0.o and
// the libc dynamic library needs them. // the libc dynamic library needs them.
#pragma dataflag NOPTR //go:linkname _environ environ
char *environ[1]; //go:linkname _progname __progname
#pragma dataflag NOPTR //go:linkname _guard_local __guard_local
char *__progname;
long __guard_local;
#pragma dynexport environ environ var _environ uintptr
#pragma dynexport __progname __progname var _progname uintptr
var _guard_local uintptr
//go:cgo_export_dynamic environ environ
//go:cgo_export_dynamic __progname __progname
// This is normally marked as hidden and placed in the // This is normally marked as hidden and placed in the
// .openbsd.randomdata section. // .openbsd.randomdata section.
#pragma dynexport __guard_local __guard_local //go:cgo_export_dynamic __guard_local __guard_local
// We override pthread_create to support PT_TLS. // We override pthread_create to support PT_TLS.
#pragma dynexport pthread_create pthread_create //go:cgo_export_dynamic pthread_create pthread_create
...@@ -4,10 +4,18 @@ ...@@ -4,10 +4,18 @@
// +build darwin dragonfly freebsd linux netbsd openbsd // +build darwin dragonfly freebsd linux netbsd openbsd
#pragma cgo_import_static x_cgo_setenv package cgo
#pragma cgo_import_static x_cgo_unsetenv
void x_cgo_setenv(char**); import _ "unsafe"
void (*runtime·_cgo_setenv)(char**) = x_cgo_setenv;
void x_cgo_unsetenv(char**); //go:cgo_import_static x_cgo_setenv
void (*runtime·_cgo_unsetenv)(char**) = x_cgo_unsetenv; //go:linkname x_cgo_setenv x_cgo_setenv
//go:linkname _cgo_setenv runtime._cgo_setenv
var x_cgo_setenv byte
var _cgo_setenv = &x_cgo_setenv
//go:cgo_import_static x_cgo_unsetenv
//go:linkname x_cgo_unsetenv x_cgo_unsetenv
//go:linkname _cgo_unsetenv runtime._cgo_unsetenv
var x_cgo_unsetenv byte
var _cgo_unsetenv = &x_cgo_unsetenv
...@@ -127,9 +127,9 @@ func cgocall_errno(fn, arg unsafe.Pointer) int32 { ...@@ -127,9 +127,9 @@ func cgocall_errno(fn, arg unsafe.Pointer) int32 {
* so it is safe to call while "in a system call", outside * so it is safe to call while "in a system call", outside
* the $GOMAXPROCS accounting. * the $GOMAXPROCS accounting.
*/ */
entersyscall() entersyscall(0)
errno := asmcgocall_errno(fn, arg) errno := asmcgocall_errno(fn, arg)
exitsyscall() exitsyscall(0)
return errno return errno
} }
...@@ -153,17 +153,13 @@ func endcgo(mp *m) { ...@@ -153,17 +153,13 @@ func endcgo(mp *m) {
// Helper functions for cgo code. // Helper functions for cgo code.
// Filled by schedinit from corresponding C variables,
// which are in turn filled in by dynamic linker when Cgo is available.
var cgoMalloc, cgoFree unsafe.Pointer
func cmalloc(n uintptr) unsafe.Pointer { func cmalloc(n uintptr) unsafe.Pointer {
var args struct { var args struct {
n uint64 n uint64
ret unsafe.Pointer ret unsafe.Pointer
} }
args.n = uint64(n) args.n = uint64(n)
cgocall(cgoMalloc, unsafe.Pointer(&args)) cgocall(_cgo_malloc, unsafe.Pointer(&args))
if args.ret == nil { if args.ret == nil {
gothrow("C malloc failed") gothrow("C malloc failed")
} }
...@@ -171,7 +167,7 @@ func cmalloc(n uintptr) unsafe.Pointer { ...@@ -171,7 +167,7 @@ func cmalloc(n uintptr) unsafe.Pointer {
} }
func cfree(p unsafe.Pointer) { func cfree(p unsafe.Pointer) {
cgocall(cgoFree, p) cgocall(_cgo_free, p)
} }
// Call from C back to Go. // Call from C back to Go.
...@@ -189,10 +185,10 @@ func cgocallbackg() { ...@@ -189,10 +185,10 @@ func cgocallbackg() {
// save syscall* and let reentersyscall restore them. // save syscall* and let reentersyscall restore them.
savedsp := unsafe.Pointer(gp.syscallsp) savedsp := unsafe.Pointer(gp.syscallsp)
savedpc := gp.syscallpc savedpc := gp.syscallpc
exitsyscall() // coming out of cgo call exitsyscall(0) // coming out of cgo call
cgocallbackg1() cgocallbackg1()
// going back to cgo call // going back to cgo call
reentersyscall(savedpc, savedsp) reentersyscall(savedpc, uintptr(savedsp))
} }
func cgocallbackg1() { func cgocallbackg1() {
......
...@@ -8,8 +8,6 @@ package runtime ...@@ -8,8 +8,6 @@ package runtime
import "unsafe" import "unsafe"
func environ() []string
func getenv(s *byte) *byte { func getenv(s *byte) *byte {
val := gogetenv(gostringnocopy(s)) val := gogetenv(gostringnocopy(s))
if val == "" { if val == "" {
...@@ -32,13 +30,13 @@ func gogetenv(key string) string { ...@@ -32,13 +30,13 @@ func gogetenv(key string) string {
return "" return ""
} }
var _cgo_setenv uintptr // pointer to C function var _cgo_setenv unsafe.Pointer // pointer to C function
var _cgo_unsetenv uintptr // pointer to C function var _cgo_unsetenv unsafe.Pointer // pointer to C function
// Update the C environment if cgo is loaded. // Update the C environment if cgo is loaded.
// Called from syscall.Setenv. // Called from syscall.Setenv.
func syscall_setenv_c(k string, v string) { func syscall_setenv_c(k string, v string) {
if _cgo_setenv == 0 { if _cgo_setenv == nil {
return return
} }
arg := [2]unsafe.Pointer{cstring(k), cstring(v)} arg := [2]unsafe.Pointer{cstring(k), cstring(v)}
...@@ -48,7 +46,7 @@ func syscall_setenv_c(k string, v string) { ...@@ -48,7 +46,7 @@ func syscall_setenv_c(k string, v string) {
// Update the C environment if cgo is loaded. // Update the C environment if cgo is loaded.
// Called from syscall.unsetenv. // Called from syscall.unsetenv.
func syscall_unsetenv_c(k string) { func syscall_unsetenv_c(k string) {
if _cgo_unsetenv == 0 { if _cgo_unsetenv == nil {
return return
} }
arg := [1]unsafe.Pointer{cstring(k)} arg := [1]unsafe.Pointer{cstring(k)}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment