diff options
Diffstat (limited to 'libgo')
-rw-r--r-- | libgo/Makefile.am | 1 | ||||
-rw-r--r-- | libgo/Makefile.in | 11 | ||||
-rwxr-xr-x | libgo/configure | 2 | ||||
-rw-r--r-- | libgo/configure.ac | 2 | ||||
-rw-r--r-- | libgo/go/reflect/all_test.go | 3 | ||||
-rw-r--r-- | libgo/go/reflect/type.go | 6 | ||||
-rw-r--r-- | libgo/go/reflect/value.go | 39 | ||||
-rw-r--r-- | libgo/go/runtime/extern.go | 3 | ||||
-rw-r--r-- | libgo/go/runtime/parfor_test.go | 9 | ||||
-rw-r--r-- | libgo/runtime/go-reflect-call.c | 33 | ||||
-rw-r--r-- | libgo/runtime/malloc.h | 3 | ||||
-rw-r--r-- | libgo/runtime/mfinal.c | 8 | ||||
-rw-r--r-- | libgo/runtime/mgc0.c | 10 | ||||
-rw-r--r-- | libgo/runtime/parfor.c | 2 | ||||
-rw-r--r-- | libgo/runtime/runtime.h | 12 | ||||
-rw-r--r-- | libgo/runtime/time.goc | 13 |
16 files changed, 104 insertions, 53 deletions
diff --git a/libgo/Makefile.am b/libgo/Makefile.am index ea90318..d54448c 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -487,7 +487,6 @@ runtime_files = \ runtime/go-strplus.c \ runtime/go-strslice.c \ runtime/go-traceback.c \ - runtime/go-trampoline.c \ runtime/go-type-complex.c \ runtime/go-type-eface.c \ runtime/go-type-error.c \ diff --git a/libgo/Makefile.in b/libgo/Makefile.in index 2ec60d3..08eae57 100644 --- a/libgo/Makefile.in +++ b/libgo/Makefile.in @@ -208,7 +208,7 @@ am__objects_5 = go-append.lo go-assert.lo go-assert-interface.lo \ go-reflect-call.lo go-reflect-map.lo go-rune.lo \ go-runtime-error.lo go-setenv.lo go-signal.lo go-strcmp.lo \ go-string-to-byte-array.lo go-string-to-int-array.lo \ - go-strplus.lo go-strslice.lo go-traceback.lo go-trampoline.lo \ + go-strplus.lo go-strslice.lo go-traceback.lo \ go-type-complex.lo go-type-eface.lo go-type-error.lo \ go-type-float.lo go-type-identity.lo go-type-interface.lo \ go-type-string.lo go-typedesc-equal.lo go-typestring.lo \ @@ -822,7 +822,6 @@ runtime_files = \ runtime/go-strplus.c \ runtime/go-strslice.c \ runtime/go-traceback.c \ - runtime/go-trampoline.c \ runtime/go-type-complex.c \ runtime/go-type-eface.c \ runtime/go-type-error.c \ @@ -2519,7 +2518,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-strplus.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-strslice.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-traceback.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-trampoline.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-type-complex.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-type-eface.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-type-error.Plo@am__quote@ @@ -2959,13 +2957,6 @@ go-traceback.lo: runtime/go-traceback.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-traceback.lo `test -f 'runtime/go-traceback.c' || echo '$(srcdir)/'`runtime/go-traceback.c -go-trampoline.lo: runtime/go-trampoline.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-trampoline.lo -MD -MP -MF $(DEPDIR)/go-trampoline.Tpo -c -o go-trampoline.lo `test -f 'runtime/go-trampoline.c' || echo '$(srcdir)/'`runtime/go-trampoline.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-trampoline.Tpo $(DEPDIR)/go-trampoline.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-trampoline.c' object='go-trampoline.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-trampoline.lo `test -f 'runtime/go-trampoline.c' || echo '$(srcdir)/'`runtime/go-trampoline.c - go-type-complex.lo: runtime/go-type-complex.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-type-complex.lo -MD -MP -MF $(DEPDIR)/go-type-complex.Tpo -c -o go-type-complex.lo `test -f 'runtime/go-type-complex.c' || echo '$(srcdir)/'`runtime/go-type-complex.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-type-complex.Tpo $(DEPDIR)/go-type-complex.Plo diff --git a/libgo/configure b/libgo/configure index e1d37dc..5c943ff 100755 --- a/libgo/configure +++ b/libgo/configure @@ -2496,7 +2496,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" -libtool_VERSION=3:1:0 +libtool_VERSION=5:0:0 # Default to --enable-multilib diff --git a/libgo/configure.ac b/libgo/configure.ac index 58cc045..002aa88 100644 --- a/libgo/configure.ac +++ b/libgo/configure.ac @@ -11,7 +11,7 @@ AC_INIT(package-unused, version-unused,, libgo) AC_CONFIG_SRCDIR(Makefile.am) AC_CONFIG_HEADER(config.h) -libtool_VERSION=3:1:0 +libtool_VERSION=5:0:0 AC_SUBST(libtool_VERSION) AM_ENABLE_MULTILIB(, ..) diff --git a/libgo/go/reflect/all_test.go b/libgo/go/reflect/all_test.go index 8a36023..5a2ae2e 100644 --- a/libgo/go/reflect/all_test.go +++ b/libgo/go/reflect/all_test.go @@ -1891,6 +1891,7 @@ func (*inner) m() {} func (*outer) m() {} func TestNestedMethods(t *testing.T) { + t.Skip("fails on gccgo due to function wrappers") typ := TypeOf((*outer)(nil)) if typ.NumMethod() != 1 || typ.Method(0).Func.Pointer() != ValueOf((*outer).m).Pointer() { t.Errorf("Wrong method table for outer: (m=%p)", (*outer).m) @@ -1915,6 +1916,7 @@ func (i *InnerInt) M() int { } func TestEmbeddedMethods(t *testing.T) { + /* This part of the test fails on gccgo due to function wrappers. typ := TypeOf((*OuterInt)(nil)) if typ.NumMethod() != 1 || typ.Method(0).Func.Pointer() != ValueOf((*OuterInt).M).Pointer() { t.Errorf("Wrong method table for OuterInt: (m=%p)", (*OuterInt).M) @@ -1923,6 +1925,7 @@ func TestEmbeddedMethods(t *testing.T) { t.Errorf("\t%d: %s %#x\n", i, m.Name, m.Func.Pointer()) } } + */ i := &InnerInt{3} if v := ValueOf(i).Method(0).Call(nil)[0].Int(); v != 3 { diff --git a/libgo/go/reflect/type.go b/libgo/go/reflect/type.go index 9e65870..b909177 100644 --- a/libgo/go/reflect/type.go +++ b/libgo/go/reflect/type.go @@ -243,8 +243,8 @@ type rtype struct { size uintptr // size in bytes hash uint32 // hash of type; avoids computation in hash tables - hashfn func(unsafe.Pointer, uintptr) // hash function - equalfn func(unsafe.Pointer, unsafe.Pointer, uintptr) // equality function + hashfn uintptr // hash function code + equalfn uintptr // equality function code string *string // string form; unnecessary but undeniably useful *uncommonType // (relatively) uncommon fields @@ -485,7 +485,7 @@ func (t *uncommonType) Method(i int) (m Method) { mt := p.typ m.Type = toType(mt) x := new(unsafe.Pointer) - *x = p.tfn + *x = unsafe.Pointer(&p.tfn) m.Func = Value{mt, unsafe.Pointer(x), fl | flagIndir} m.Index = i return diff --git a/libgo/go/reflect/value.go b/libgo/go/reflect/value.go index 15f5715..f8126e6 100644 --- a/libgo/go/reflect/value.go +++ b/libgo/go/reflect/value.go @@ -377,7 +377,7 @@ func (v Value) call(method string, in []Value) []Value { if iface.itab == nil { panic(method + " of method on nil interface value") } - fn = iface.itab.fun[i] + fn = unsafe.Pointer(&iface.itab.fun[i]) rcvr = iface.word } else { ut := v.typ.uncommon() @@ -388,7 +388,7 @@ func (v Value) call(method string, in []Value) []Value { if m.pkgPath != nil { panic(method + " of unexported method") } - fn = m.tfn + fn = unsafe.Pointer(&m.tfn) t = m.mtyp rcvr = v.iword() } @@ -462,6 +462,10 @@ func (v Value) call(method string, in []Value) []Value { if v.flag&flagMethod != 0 { nin++ } + firstPointer := len(in) > 0 && Kind(t.In(0).(*rtype).kind) != Ptr && v.flag&flagMethod == 0 && isMethod(v.typ) + if v.flag&flagMethod == 0 && !firstPointer { + nin++ + } params := make([]unsafe.Pointer, nin) off := 0 if v.flag&flagMethod != 0 { @@ -471,7 +475,6 @@ func (v Value) call(method string, in []Value) []Value { params[0] = unsafe.Pointer(p) off = 1 } - first_pointer := false for i, pv := range in { pv.mustBeExported() targ := t.In(i).(*rtype) @@ -483,14 +486,17 @@ func (v Value) call(method string, in []Value) []Value { } else { params[off] = pv.val } - if i == 0 && Kind(targ.kind) != Ptr && v.flag&flagMethod == 0 && isMethod(v.typ) { + if i == 0 && firstPointer { p := new(unsafe.Pointer) *p = params[off] params[off] = unsafe.Pointer(p) - first_pointer = true } off++ } + if v.flag&flagMethod == 0 && !firstPointer { + // Closure argument. + params[off] = unsafe.Pointer(&fn) + } ret := make([]Value, nout) results := make([]unsafe.Pointer, nout) @@ -509,7 +515,7 @@ func (v Value) call(method string, in []Value) []Value { pr = &results[0] } - call(t, fn, v.flag&flagMethod != 0, first_pointer, pp, pr) + call(t, fn, v.flag&flagMethod != 0, firstPointer, pp, pr) return ret } @@ -1209,18 +1215,35 @@ func (v Value) OverflowUint(x uint64) bool { // code using reflect cannot obtain unsafe.Pointers // without importing the unsafe package explicitly. // It panics if v's Kind is not Chan, Func, Map, Ptr, Slice, or UnsafePointer. +// +// If v's Kind is Func, the returned pointer is an underlying +// code pointer, but not necessarily enough to identify a +// single function uniquely. The only guarantee is that the +// result is zero if and only if v is a nil func Value. func (v Value) Pointer() uintptr { k := v.kind() switch k { - case Chan, Func, Map, Ptr, UnsafePointer: - if k == Func && v.flag&flagMethod != 0 { + case Chan, Map, Ptr, UnsafePointer: + p := v.val + if v.flag&flagIndir != 0 { + p = *(*unsafe.Pointer)(p) + } + return uintptr(p) + case Func: + if v.flag&flagMethod != 0 { panic("reflect.Value.Pointer of method Value") } p := v.val if v.flag&flagIndir != 0 { p = *(*unsafe.Pointer)(p) } + // Non-nil func value points at data block. + // First word of data block is actual code. + if p != nil { + p = *(*unsafe.Pointer)(p) + } return uintptr(p) + case Slice: return (*SliceHeader)(v.val).Data } diff --git a/libgo/go/runtime/extern.go b/libgo/go/runtime/extern.go index 2a90113..6e91ef5 100644 --- a/libgo/go/runtime/extern.go +++ b/libgo/go/runtime/extern.go @@ -59,9 +59,6 @@ func (f *Func) FileLine(pc uintptr) (file string, line int) { // implemented in symtab.c func funcline_go(*Func, uintptr) (string, int) -// mid returns the current OS thread (m) id. -func mid() uint32 - // SetFinalizer sets the finalizer associated with x to f. // When the garbage collector finds an unreachable block // with an associated finalizer, it clears the association and runs diff --git a/libgo/go/runtime/parfor_test.go b/libgo/go/runtime/parfor_test.go index b382b76..4c69a68 100644 --- a/libgo/go/runtime/parfor_test.go +++ b/libgo/go/runtime/parfor_test.go @@ -13,6 +13,8 @@ import ( "unsafe" ) +var gdata []uint64 + // Simple serial sanity test for parallelfor. func TestParFor(t *testing.T) { const P = 1 @@ -22,7 +24,12 @@ func TestParFor(t *testing.T) { data[i] = i } desc := NewParFor(P) + // Avoid making func a closure: parfor cannot invoke them. + // Since it doesn't happen in the C code, it's not worth doing + // just for the test. + gdata = data ParForSetup(desc, P, N, nil, true, func(desc *ParFor, i uint32) { + data := gdata data[i] = data[i]*data[i] + 1 }) ParForDo(desc) @@ -111,7 +118,9 @@ func TestParForParallel(t *testing.T) { P := GOMAXPROCS(-1) c := make(chan bool, P) desc := NewParFor(uint32(P)) + gdata = data ParForSetup(desc, uint32(P), uint32(N), nil, false, func(desc *ParFor, i uint32) { + data := gdata data[i] = data[i]*data[i] + 1 }) for p := 1; p < P; p++ { diff --git a/libgo/runtime/go-reflect-call.c b/libgo/runtime/go-reflect-call.c index a66f928..83b9eba 100644 --- a/libgo/runtime/go-reflect-call.c +++ b/libgo/runtime/go-reflect-call.c @@ -302,7 +302,9 @@ go_func_to_cif (const struct __go_func_type *func, _Bool is_interface, in_types = ((const struct __go_type_descriptor **) func->__in.__values); - num_args = num_params + (is_interface ? 1 : 0); + num_args = (num_params + + (is_interface ? 1 : 0) + + (!is_interface && !is_method ? 1 : 0)); args = (ffi_type **) __go_alloc (num_args * sizeof (ffi_type *)); i = 0; off = 0; @@ -319,6 +321,12 @@ go_func_to_cif (const struct __go_func_type *func, _Bool is_interface, for (; i < num_params; ++i) args[i + off] = go_type_to_ffi (in_types[i]); + if (!is_interface && !is_method) + { + // There is a closure argument, a pointer. + args[i + off] = &ffi_type_pointer; + } + rettype = go_func_return_ffi (func); status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, num_args, rettype, args); @@ -491,11 +499,24 @@ go_set_results (const struct __go_func_type *func, unsigned char *call_result, } /* Call a function. The type of the function is FUNC_TYPE, and the - address is FUNC_ADDR. PARAMS is an array of parameter addresses. - RESULTS is an array of result addresses. */ + closure is FUNC_VAL. PARAMS is an array of parameter addresses. + RESULTS is an array of result addresses. + + If IS_INTERFACE is true this is a call to an interface method and + the first argument is the receiver, which is always a pointer. + This argument, the receiver, is not described in FUNC_TYPE. + + If IS_METHOD is true this is a call to a method expression. The + first argument is the receiver. It is described in FUNC_TYPE, but + regardless of FUNC_TYPE, it is passed as a pointer. + + If neither IS_INTERFACE nor IS_METHOD is true then we are calling a + function indirectly, and the caller is responsible for passing a + trailing closure argument, a pointer, which is not described in + FUNC_TYPE. */ void -reflect_call (const struct __go_func_type *func_type, const void *func_addr, +reflect_call (const struct __go_func_type *func_type, FuncVal *func_val, _Bool is_interface, _Bool is_method, void **params, void **results) { @@ -507,7 +528,7 @@ reflect_call (const struct __go_func_type *func_type, const void *func_addr, call_result = (unsigned char *) malloc (go_results_size (func_type)); - ffi_call (&cif, func_addr, call_result, params); + ffi_call (&cif, func_val->fn, call_result, params); /* Some day we may need to free result values if RESULTS is NULL. */ @@ -521,7 +542,7 @@ reflect_call (const struct __go_func_type *func_type, const void *func_addr, void reflect_call (const struct __go_func_type *func_type __attribute__ ((unused)), - const void *func_addr __attribute__ ((unused)), + FuncVal *func_val __attribute__ ((unused)), _Bool is_interface __attribute__ ((unused)), _Bool is_method __attribute__ ((unused)), void **params __attribute__ ((unused)), diff --git a/libgo/runtime/malloc.h b/libgo/runtime/malloc.h index a820774..7ebb762 100644 --- a/libgo/runtime/malloc.h +++ b/libgo/runtime/malloc.h @@ -485,7 +485,7 @@ void runtime_helpgc(int32 nproc); void runtime_gchelper(void); struct __go_func_type; -bool runtime_getfinalizer(void *p, bool del, void (**fn)(void*), const struct __go_func_type **ft); +bool runtime_getfinalizer(void *p, bool del, FuncVal **fn, const struct __go_func_type **ft); void runtime_walkfintab(void (*fn)(void*), void (*scan)(Obj)); enum @@ -505,4 +505,3 @@ void runtime_gc_itab_ptr(Eface*); void runtime_memorydump(void); void runtime_time_scan(void (*)(Obj)); -void runtime_trampoline_scan(void (*)(Obj)); diff --git a/libgo/runtime/mfinal.c b/libgo/runtime/mfinal.c index 7c906da..407092b 100644 --- a/libgo/runtime/mfinal.c +++ b/libgo/runtime/mfinal.c @@ -11,7 +11,7 @@ enum { debug = 0 }; typedef struct Fin Fin; struct Fin { - void (*fn)(void*); + FuncVal *fn; const struct __go_func_type *ft; }; @@ -42,7 +42,7 @@ static struct { } fintab[TABSZ]; static void -addfintab(Fintab *t, void *k, void (*fn)(void*), const struct __go_func_type *ft) +addfintab(Fintab *t, void *k, FuncVal *fn, const struct __go_func_type *ft) { int32 i, j; @@ -137,7 +137,7 @@ resizefintab(Fintab *tab) } bool -runtime_addfinalizer(void *p, void (*f)(void*), const struct __go_func_type *ft) +runtime_addfinalizer(void *p, FuncVal *f, const struct __go_func_type *ft) { Fintab *tab; byte *base; @@ -175,7 +175,7 @@ runtime_addfinalizer(void *p, void (*f)(void*), const struct __go_func_type *ft) // get finalizer; if del, delete finalizer. // caller is responsible for updating RefHasFinalizer (special) bit. bool -runtime_getfinalizer(void *p, bool del, void (**fn)(void*), const struct __go_func_type **ft) +runtime_getfinalizer(void *p, bool del, FuncVal **fn, const struct __go_func_type **ft) { Fintab *tab; bool res; diff --git a/libgo/runtime/mgc0.c b/libgo/runtime/mgc0.c index ffbe2ce..88283cc 100644 --- a/libgo/runtime/mgc0.c +++ b/libgo/runtime/mgc0.c @@ -120,7 +120,7 @@ struct Workbuf typedef struct Finalizer Finalizer; struct Finalizer { - void (*fn)(void*); + FuncVal *fn; void *arg; const struct __go_func_type *ft; }; @@ -1130,7 +1130,6 @@ addroots(void) addroot((Obj){(byte*)&runtime_allm, sizeof runtime_allm, 0}); runtime_MProf_Mark(addroot); runtime_time_scan(addroot); - runtime_trampoline_scan(addroot); // MSpan.types allspans = runtime_mheap.allspans; @@ -1182,7 +1181,7 @@ addroots(void) static bool handlespecial(byte *p, uintptr size) { - void (*fn)(void*); + FuncVal *fn; const struct __go_func_type *ft; FinBlock *block; Finalizer *f; @@ -1731,11 +1730,12 @@ runfinq(void* dummy __attribute__ ((unused))) for(; fb; fb=next) { next = fb->next; for(i=0; i<(uint32)fb->cnt; i++) { - void *params[1]; + void *params[2]; f = &fb->fin[i]; params[0] = &f->arg; - reflect_call(f->ft, (void*)f->fn, 0, 0, params, nil); + params[1] = f; + reflect_call(f->ft, f->fn, 0, 0, params, nil); f->fn = nil; f->arg = nil; } diff --git a/libgo/runtime/parfor.c b/libgo/runtime/parfor.c index 591b968..65ca586 100644 --- a/libgo/runtime/parfor.c +++ b/libgo/runtime/parfor.c @@ -83,7 +83,7 @@ void runtime_parforsetup2(ParFor *, uint32, uint32, void *, bool, void *) void runtime_parforsetup2(ParFor *desc, uint32 nthr, uint32 n, void *ctx, bool wait, void *body) { - runtime_parforsetup(desc, nthr, n, ctx, wait, (void(*)(ParFor*, uint32))body); + runtime_parforsetup(desc, nthr, n, ctx, wait, *(void(**)(ParFor*, uint32))body); } void diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h index 9392df1..959220d 100644 --- a/libgo/runtime/runtime.h +++ b/libgo/runtime/runtime.h @@ -57,6 +57,7 @@ typedef struct G G; typedef union Lock Lock; typedef struct M M; typedef union Note Note; +typedef struct FuncVal FuncVal; typedef struct SigTab SigTab; typedef struct MCache MCache; typedef struct FixAlloc FixAlloc; @@ -147,6 +148,11 @@ struct String const byte* str; intgo len; }; +struct FuncVal +{ + void (*fn)(void); + // variable-size, fn-specific data here +}; struct GCStats { // the struct must consist of only uint64's, @@ -313,7 +319,7 @@ struct Timer // a well-behaved function and not block. int64 when; int64 period; - void (*f)(int64, Eface); + FuncVal *fv; Eface arg; }; @@ -540,7 +546,7 @@ void runtime_printslice(Slice); void runtime_printcomplex(__complex double); struct __go_func_type; -void reflect_call(const struct __go_func_type *, const void *, _Bool, _Bool, +void reflect_call(const struct __go_func_type *, FuncVal *, _Bool, _Bool, void **, void **) __asm__ (GOSYM_PREFIX "reflect.call"); @@ -570,7 +576,7 @@ void free(void *v); #define PREFETCH(p) __builtin_prefetch(p) struct __go_func_type; -bool runtime_addfinalizer(void*, void(*fn)(void*), const struct __go_func_type *); +bool runtime_addfinalizer(void*, FuncVal *fn, const struct __go_func_type *); #define runtime_getcallersp(p) __builtin_frame_address(1) int32 runtime_mcount(void); int32 runtime_gcount(void); diff --git a/libgo/runtime/time.goc b/libgo/runtime/time.goc index 9a5cbdf..e9f087a 100644 --- a/libgo/runtime/time.goc +++ b/libgo/runtime/time.goc @@ -49,13 +49,16 @@ static void siftdown(int32); // Ready the goroutine e.data. static void -ready(int64 now, Eface e) +ready(int64 now, Eface e, void *closure) { USED(now); + USED(closure); runtime_ready(e.__object); } +static FuncVal readyv = {(void(*)(void))ready}; + // Put the current goroutine to sleep for ns nanoseconds. void runtime_tsleep(int64 ns, const char *reason) @@ -70,7 +73,7 @@ runtime_tsleep(int64 ns, const char *reason) t.when = runtime_nanotime() + ns; t.period = 0; - t.f = ready; + t.fv = &readyv; t.arg.__object = g; runtime_lock(&timers); addtimer(&t); @@ -158,7 +161,7 @@ timerproc(void* dummy __attribute__ ((unused))) { int64 delta, now; Timer *t; - void (*f)(int64, Eface); + void (*f)(int64, Eface, void *); Eface arg; for(;;) { @@ -184,12 +187,12 @@ timerproc(void* dummy __attribute__ ((unused))) siftdown(0); t->i = -1; // mark as removed } - f = t->f; + f = (void*)t->fv->fn; arg = t->arg; runtime_unlock(&timers); if(raceenabled) runtime_raceacquire(t); - f(now, arg); + f(now, arg, &t->fv); runtime_lock(&timers); } if(delta < 0) { |