From 3be567ba3ef193bfea60b32055da1dd79c8d26e4 Mon Sep 17 00:00:00 2001 From: visualfc Date: Mon, 15 Jun 2026 16:16:18 +0800 Subject: [PATCH 1/8] llgo: support setMethodSet --- internal/abi/type_llgo.go | 48 ++++++++---- rtype_llgo.go | 160 +++++++++++++++++++++++++++++++++----- 2 files changed, 173 insertions(+), 35 deletions(-) diff --git a/internal/abi/type_llgo.go b/internal/abi/type_llgo.go index b45bd29..4ecf65f 100644 --- a/internal/abi/type_llgo.go +++ b/internal/abi/type_llgo.go @@ -348,29 +348,43 @@ func (t *UncommonType) Methods() []Method { if t.Mcount == 0 { return nil } - methodsPtr := addChecked(unsafe.Pointer(t), uintptr(t.Moff), "t.mcount > 0") - methods := make([]Method, t.Mcount) - for i := 0; i < int(t.Mcount); i++ { - elemPtr := addChecked(methodsPtr, uintptr(i)*unsafe.Sizeof(Method{}), "accessing method element") - elem := (*Method)(elemPtr) - methods[i] = *elem - } - return methods + return (*[1 << 16]Method)(addChecked(unsafe.Pointer(t), uintptr(t.Moff), "t.mcount > 0"))[:t.Mcount:t.Mcount] } func (t *UncommonType) ExportedMethods() []Method { if t.Xcount == 0 { return nil } - mthdsPtr := addChecked(unsafe.Pointer(t), uintptr(t.Moff), "t.xcount > 0") - mthds := make([]Method, t.Xcount) - for i := 0; i < int(t.Xcount); i++ { - elemPtr := addChecked(mthdsPtr, uintptr(i)*unsafe.Sizeof(Method{}), "accessing method element") - elem := (*Method)(elemPtr) - mthds[i] = *elem - } - return mthds -} + return (*[1 << 16]Method)(addChecked(unsafe.Pointer(t), uintptr(t.Moff), "t.xcount > 0"))[:t.Xcount:t.Xcount] +} + +// func (t *UncommonType) Methods() []Method { +// if t.Mcount == 0 { +// return nil +// } +// methodsPtr := addChecked(unsafe.Pointer(t), uintptr(t.Moff), "t.mcount > 0") +// methods := make([]Method, t.Mcount) +// for i := 0; i < int(t.Mcount); i++ { +// elemPtr := addChecked(methodsPtr, uintptr(i)*unsafe.Sizeof(Method{}), "accessing method element") +// elem := (*Method)(elemPtr) +// methods[i] = *elem +// } +// return methods +// } + +// func (t *UncommonType) ExportedMethods() []Method { +// if t.Xcount == 0 { +// return nil +// } +// mthdsPtr := addChecked(unsafe.Pointer(t), uintptr(t.Moff), "t.xcount > 0") +// mthds := make([]Method, t.Xcount) +// for i := 0; i < int(t.Xcount); i++ { +// elemPtr := addChecked(mthdsPtr, uintptr(i)*unsafe.Sizeof(Method{}), "accessing method element") +// elem := (*Method)(elemPtr) +// mthds[i] = *elem +// } +// return mthds +// } // Imethod represents a method on an interface type type Imethod struct { diff --git a/rtype_llgo.go b/rtype_llgo.go index ab461bd..c43b863 100644 --- a/rtype_llgo.go +++ b/rtype_llgo.go @@ -10,6 +10,8 @@ import ( "strconv" "strings" "unsafe" + + "github.com/goplus/reflectx/internal/abi" ) func NamedTypeOf(pkgpath string, name string, from reflect.Type) reflect.Type { @@ -146,6 +148,9 @@ func closureOf(ftyp *funcType) *rtype //go:linkname toFuncType reflect.toFuncType func toFuncType(ftyp *structType) *funcType +//go:linkname makeFunc reflect.makeFunc +func makeFunc(typ reflect.Type, method bool, fn func(args []reflect.Value) (results []reflect.Value)) reflect.Value + func rtypeMethodX(t *rtype, i int) (m reflect.Method) { if reflect.Kind(t.Kind()) == reflect.Interface { return toType(t).Method(i) @@ -293,17 +298,9 @@ func newType(pkg string, name string, styp reflect.Type, mcount int, xcount int) return rt, nil } else if skind == reflect.Func { ut.Moff += fnoff - //return rt, tt.Elem().Field(3).Slice(0, mcount).Interface().([]method) - data := toWord(tt.Elem().Field(3).Slice(0, mcount).Interface()) - return rt, *(*[]method)(data) + return rt, tt.Elem().Field(3).Slice(0, mcount).Interface().([]method) } - //return rt, tt.Elem().Field(2).Slice(0, mcount).Interface().([]method) - data := toWord(tt.Elem().Field(2).Slice(0, mcount).Interface()) - return rt, *(*[]method)(data) -} - -func toWord(i interface{}) unsafe.Pointer { - return (*emptyInterface)(unsafe.Pointer(&i)).word + return rt, tt.Elem().Field(2).Slice(0, mcount).Interface().([]method) } func (ctx *Context) Reset() { @@ -313,17 +310,75 @@ func resetAll() { } func newMethodSet(styp reflect.Type, maxmfunc, maxpfunc int) reflect.Type { - // rt, _ := newType("", "", styp, maxmfunc, 0) - // prt, _ := newType("", "", PtrTo(styp), maxpfunc, 0) - // rt.PtrToThis = resolveReflectType(prt) - // (*ptrType)(unsafe.Pointer(prt)).Elem = rt - // setTypeName(rt, styp.PkgPath(), styp.Name()) - // prt.Uncommon().PkgPath = resolveReflectName(newName(styp.PkgPath(), "", false)) - // return toType(rt) - panic("TODO newMethodSet") + rt, _ := newType("", "", styp, maxmfunc, 0) + prt, _ := newType("", "", reflect.PtrTo(styp), maxpfunc, 0) + rt.PtrToThis_ = prt + (*ptrType)(unsafe.Pointer(prt)).Elem = rt + setTypeName(rt, styp.PkgPath(), styp.Name()) + prt.Uncommon().PkgPath_ = styp.PkgPath() + return toType(rt) +} + +func resizeMethod(typ reflect.Type, mcount int, xcount int) error { + rt := totype(typ) + ut := rt.Uncommon() + if ut == nil { + return fmt.Errorf("not found uncommonType of %v", typ) + } + if uint16(mcount) > ut.Mcount { + return fmt.Errorf("too many methods of %v", typ) + } + ut.Xcount = uint16(xcount) return nil } +type textOff = abi.Text + +var globalMethodCache = make(map[int]*ifnValue) + +type ifnValue struct { + method method + pmethod method +} + +func createMethod(typ reflect.Type, ptyp reflect.Type, m Method, index int) (mtyp *abi.Type, tfn, ptfn reflect.Value, mfn, pmfn reflect.Value) { + var in []reflect.Type + var out []reflect.Type + var ntyp reflect.Type + in, out, ntyp, _, _ = parserMethodType(m.Type, nil) + mtyp = totype(ntyp) + var ftyp reflect.Type + if m.Pointer { + ftyp = reflect.FuncOf(append([]reflect.Type{ptyp}, in...), out, m.Type.IsVariadic()) + } else { + ftyp = reflect.FuncOf(append([]reflect.Type{typ}, in...), out, m.Type.IsVariadic()) + } + if m.Pointer { + ptfn = makeFunc(ftyp, false, m.Func) + pmfn = makeFunc(ftyp, true, m.Func) + } else { + tfn = makeFunc(ftyp, false, m.Func) + ftyp = reflect.FuncOf(append([]reflect.Type{ptyp}, in...), out, m.Type.IsVariadic()) + ptfn = makeFunc(ftyp, false, func(args []reflect.Value) []reflect.Value { + args[0] = args[0].Elem() + return m.Func(args) + }) + mfn = makeFunc(ftyp, true, func(args []reflect.Value) []reflect.Value { + args[0] = args[0].Elem() + return m.Func(args) + }) + pmfn = mfn + } + return +} + +func (ctx *Context) hasImethod(typ reflect.Type, method Method) bool { + if ctx.fnHasImethod != nil { + return ctx.fnHasImethod(typ, method) + } + return true +} + func (ctx *Context) setMethodSet(typ reflect.Type, methods []Method, sortMethods bool) error { if sortMethods { sort.Slice(methods, func(i, j int) bool { @@ -334,6 +389,75 @@ func (ctx *Context) setMethodSet(typ reflect.Type, methods []Method, sortMethods return n < 0 }) } + var mcount, pcount int + var xcount, pxcount int + pcount = len(methods) + var mlist []string + for _, m := range methods { + isexport := methodIsExported(m.Name) + if isexport { + pxcount++ + } + if !m.Pointer { + if isexport { + xcount++ + } + mlist = append(mlist, m.Name) + mcount++ + } + } + ptyp := PtrTo(typ) + if err := resizeMethod(typ, mcount, xcount); err != nil { + return err + } + if err := resizeMethod(ptyp, pcount, pxcount); err != nil { + return err + } + rt := totype(typ) + prt := totype(ptyp) + + ms := rtypeMethods(rt) + pms := rtypeMethods(prt) + + var onePtr bool + switch typ.Kind() { + case reflect.Func, reflect.Chan, reflect.Map: + onePtr = true + case reflect.Struct: + onePtr = typ.NumField() == 1 && typ.Field(0).Type.Kind() == reflect.Ptr + } + _ = onePtr + var index int + for i, m := range methods { + if m.FuncId > 0 { + if pv, ok := globalMethodCache[m.FuncId]; ok { + pms[i] = pv.pmethod + if !m.Pointer { + ms[index] = pv.method + index++ + } + continue + } + } + var mname string + if !methodIsExported(m.Name) { + mname = m.PkgPath + "." + m.Name + } else { + mname = m.Name + } + mtyp, tfn, ptfn, mfn, pmfn := createMethod(typ, ptyp, m, index) + pms[i].Name_ = mname + pms[i].Mtyp_ = mtyp.FuncType() + pms[i].Tfn_ = textOff(ptfn.Pointer()) + pms[i].Ifn_ = textOff(pmfn.Pointer()) + if !m.Pointer { + ms[index].Name_ = mname + ms[index].Mtyp_ = mtyp.FuncType() + ms[index].Tfn_ = textOff(tfn.Pointer()) + ms[index].Ifn_ = textOff(mfn.Pointer()) + index++ + } + } return nil } From 5799f19d7bedd73c730fafd7dc8abbc396da82fb Mon Sep 17 00:00:00 2001 From: visualfc Date: Mon, 15 Jun 2026 17:11:02 +0800 Subject: [PATCH 2/8] llgo: update method cache --- rtype_llgo.go | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/rtype_llgo.go b/rtype_llgo.go index c43b863..3ae7f75 100644 --- a/rtype_llgo.go +++ b/rtype_llgo.go @@ -392,7 +392,6 @@ func (ctx *Context) setMethodSet(typ reflect.Type, methods []Method, sortMethods var mcount, pcount int var xcount, pxcount int pcount = len(methods) - var mlist []string for _, m := range methods { isexport := methodIsExported(m.Name) if isexport { @@ -402,7 +401,6 @@ func (ctx *Context) setMethodSet(typ reflect.Type, methods []Method, sortMethods if isexport { xcount++ } - mlist = append(mlist, m.Name) mcount++ } } @@ -419,14 +417,6 @@ func (ctx *Context) setMethodSet(typ reflect.Type, methods []Method, sortMethods ms := rtypeMethods(rt) pms := rtypeMethods(prt) - var onePtr bool - switch typ.Kind() { - case reflect.Func, reflect.Chan, reflect.Map: - onePtr = true - case reflect.Struct: - onePtr = typ.NumField() == 1 && typ.Field(0).Type.Kind() == reflect.Ptr - } - _ = onePtr var index int for i, m := range methods { if m.FuncId > 0 { @@ -450,11 +440,18 @@ func (ctx *Context) setMethodSet(typ reflect.Type, methods []Method, sortMethods pms[i].Mtyp_ = mtyp.FuncType() pms[i].Tfn_ = textOff(ptfn.Pointer()) pms[i].Ifn_ = textOff(pmfn.Pointer()) + + if m.FuncId > 0 { + globalMethodCache[m.FuncId] = &ifnValue{pmethod: pms[i]} + } if !m.Pointer { ms[index].Name_ = mname ms[index].Mtyp_ = mtyp.FuncType() ms[index].Tfn_ = textOff(tfn.Pointer()) ms[index].Ifn_ = textOff(mfn.Pointer()) + if m.FuncId > 0 { + globalMethodCache[m.FuncId].method = ms[index] + } index++ } } From c4dc6b93b8761eb7d96dd6936e479688c8ffa34b Mon Sep 17 00:00:00 2001 From: visualfc Date: Wed, 17 Jun 2026 15:57:23 +0800 Subject: [PATCH 3/8] llgo: SetUnderlying --- reflectx.go | 4 +++ rtype.go | 4 --- rtype_llgo.go | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 4 deletions(-) diff --git a/reflectx.go b/reflectx.go index 7c36a8a..5ba3f24 100644 --- a/reflectx.go +++ b/reflectx.go @@ -179,3 +179,7 @@ func MethodByName(typ reflect.Type, name string) (m reflect.Method, ok bool) { m, ok = rtypeMethodByNameX(totype(typ), name) return } + +func MethodX(typ reflect.Type, i int) reflect.Method { + return rtypeMethodX(totype(typ), i) +} diff --git a/rtype.go b/rtype.go index c2f9c03..1de5459 100644 --- a/rtype.go +++ b/rtype.go @@ -304,10 +304,6 @@ func DumpType(w io.Writer, typ reflect.Type) { } } -func MethodX(typ reflect.Type, i int) reflect.Method { - return rtypeMethodX(totype(typ), i) -} - func rtypeMethodX(t *rtype, i int) (m reflect.Method) { if reflect.Kind(t.Kind()) == reflect.Interface { return toType(t).Method(i) diff --git a/rtype_llgo.go b/rtype_llgo.go index 3ae7f75..94ad274 100644 --- a/rtype_llgo.go +++ b/rtype_llgo.go @@ -519,3 +519,72 @@ func (ctx *Context) newInterface(methods []reflect.Method) reflect.Type { ctx.interfceLookupCache[str] = typ return typ } + +func SetUnderlying(typ reflect.Type, styp reflect.Type) { + rt := totype(typ) + ort := totype(styp) + switch styp.Kind() { + case reflect.Struct: + st := (*structType)(unsafe.Pointer(rt)) + ost := (*structType)(unsafe.Pointer(ort)) + st.Fields = ost.Fields + case reflect.Ptr: + st := (*ptrType)(unsafe.Pointer(rt)) + ost := (*ptrType)(unsafe.Pointer(ort)) + st.Elem = ost.Elem + case reflect.Slice: + st := (*sliceType)(unsafe.Pointer(rt)) + ost := (*sliceType)(unsafe.Pointer(ort)) + st.Elem = ost.Elem + case reflect.Array: + st := (*arrayType)(unsafe.Pointer(rt)) + ost := (*arrayType)(unsafe.Pointer(ort)) + st.Elem = ost.Elem + st.Slice = ost.Slice + st.Len = ost.Len + case reflect.Chan: + st := (*chanType)(unsafe.Pointer(rt)) + ost := (*chanType)(unsafe.Pointer(ort)) + st.Elem = ost.Elem + st.Dir = ost.Dir + case reflect.Interface: + st := (*interfaceType)(unsafe.Pointer(rt)) + ost := (*interfaceType)(unsafe.Pointer(ort)) + st.Methods = ost.Methods + case reflect.Map: + st := (*mapType)(unsafe.Pointer(rt)) + ost := (*mapType)(unsafe.Pointer(ort)) + cloneMap(st, ost) + case reflect.Func: + st := (*funcType)(unsafe.Pointer(rt)) + ost := (*funcType)(unsafe.Pointer(ort)) + st.In = ost.In + st.Out = ost.Out + } + rt.Size_ = ort.Size_ + rt.TFlag |= tflagUncommon | tflagExtraStar | tflagNamed + rt.Kind_ = ort.Kind_ + rt.Align_ = ort.Align_ + rt.FieldAlign_ = ort.FieldAlign_ + rt.GCData = ort.GCData + rt.PtrBytes = ort.PtrBytes + rt.Equal = ort.Equal + //rt.Str = resolveReflectName(rtype_nameOff(ort, ort.Str)) + if isRegularMemory(typ) { + rt.TFlag |= tflagRegularMemory + } +} + +// icall stat +func IcallStat() (capacity int, allocate int, aviable int) { + return +} + +// icall global cached +func IcallCached() int { + return 0 +} + +func (ctx *Context) IcallAlloc() int { + return 0 +} From bf72f70f6983ddc789c7197f06f0bc5cc7aecd2f Mon Sep 17 00:00:00 2001 From: visualfc Date: Thu, 18 Jun 2026 14:47:39 +0800 Subject: [PATCH 4/8] llgo: fix newType for func --- rtype_llgo.go | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/rtype_llgo.go b/rtype_llgo.go index 94ad274..f3e4766 100644 --- a/rtype_llgo.go +++ b/rtype_llgo.go @@ -186,7 +186,6 @@ func rtypeMethodX(t *rtype, i int) (m reflect.Method) { func newType(pkg string, name string, styp reflect.Type, mcount int, xcount int) (*rtype, []method) { var rt *rtype - var fnoff uint32 var tt reflect.Value ort := totype(styp) skind := styp.Kind() @@ -251,13 +250,9 @@ func newType(pkg string, name string, styp reflect.Type, mcount int, xcount int) st.Elem = ost.Elem st.Dir = ost.Dir case reflect.Func: - numIn := styp.NumIn() - numOut := styp.NumOut() - narg := numIn + numOut tt = reflect.New(reflect.StructOf([]reflect.StructField{ {Name: "S", Type: reflect.TypeOf(funcType{})}, {Name: "U", Type: reflect.TypeOf(uncommonType{})}, - {Name: "N", Type: reflect.ArrayOf(narg, reflect.TypeOf((*rtype)(nil)))}, {Name: "M", Type: reflect.ArrayOf(mcount, reflect.TypeOf(method{}))}, })) st := (*funcType)(unsafe.Pointer(tt.Elem().Field(0).UnsafeAddr())) @@ -280,6 +275,7 @@ func newType(pkg string, name string, styp reflect.Type, mcount int, xcount int) {Name: "M", Type: reflect.ArrayOf(mcount, reflect.TypeOf(method{}))}, })) } + rt = (*rtype)(unsafe.Pointer(tt.Elem().Field(0).UnsafeAddr())) rt.Size_ = ort.Size_ rt.TFlag = ort.TFlag | tflagUncommon @@ -296,9 +292,6 @@ func newType(pkg string, name string, styp reflect.Type, mcount int, xcount int) ut.Moff = uint32(unsafe.Sizeof(uncommonType{})) if skind == reflect.Interface { return rt, nil - } else if skind == reflect.Func { - ut.Moff += fnoff - return rt, tt.Elem().Field(3).Slice(0, mcount).Interface().([]method) } return rt, tt.Elem().Field(2).Slice(0, mcount).Interface().([]method) } From 8d30f952fa3f7f34a953a2c7a49408987e184075 Mon Sep 17 00:00:00 2001 From: visualfc Date: Mon, 22 Jun 2026 14:56:06 +0800 Subject: [PATCH 5/8] llgo: gcDisable/gcEnable for setMethodSet --- rtype_llgo.go | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/rtype_llgo.go b/rtype_llgo.go index f3e4766..1bb8a5c 100644 --- a/rtype_llgo.go +++ b/rtype_llgo.go @@ -346,6 +346,7 @@ func createMethod(typ reflect.Type, ptyp reflect.Type, m Method, index int) (mty } else { ftyp = reflect.FuncOf(append([]reflect.Type{typ}, in...), out, m.Type.IsVariadic()) } + if m.Pointer { ptfn = makeFunc(ftyp, false, m.Func) pmfn = makeFunc(ftyp, true, m.Func) @@ -372,6 +373,12 @@ func (ctx *Context) hasImethod(typ reflect.Type, method Method) bool { return true } +//go:linkname gcEnable C.GC_enable +func gcEnable() + +//go:linkname gcDisable C.GC_disable +func gcDisable() + func (ctx *Context) setMethodSet(typ reflect.Type, methods []Method, sortMethods bool) error { if sortMethods { sort.Slice(methods, func(i, j int) bool { @@ -410,6 +417,9 @@ func (ctx *Context) setMethodSet(typ reflect.Type, methods []Method, sortMethods ms := rtypeMethods(rt) pms := rtypeMethods(prt) + gcDisable() + defer gcEnable() + var index int for i, m := range methods { if m.FuncId > 0 { @@ -431,17 +441,16 @@ func (ctx *Context) setMethodSet(typ reflect.Type, methods []Method, sortMethods mtyp, tfn, ptfn, mfn, pmfn := createMethod(typ, ptyp, m, index) pms[i].Name_ = mname pms[i].Mtyp_ = mtyp.FuncType() - pms[i].Tfn_ = textOff(ptfn.Pointer()) - pms[i].Ifn_ = textOff(pmfn.Pointer()) - + pms[i].Tfn_ = textOff(ptfn.UnsafePointer()) + pms[i].Ifn_ = textOff(pmfn.UnsafePointer()) if m.FuncId > 0 { globalMethodCache[m.FuncId] = &ifnValue{pmethod: pms[i]} } if !m.Pointer { ms[index].Name_ = mname ms[index].Mtyp_ = mtyp.FuncType() - ms[index].Tfn_ = textOff(tfn.Pointer()) - ms[index].Ifn_ = textOff(mfn.Pointer()) + ms[index].Tfn_ = textOff(tfn.UnsafePointer()) + ms[index].Ifn_ = textOff(mfn.UnsafePointer()) if m.FuncId > 0 { globalMethodCache[m.FuncId].method = ms[index] } From d27ecccd158fb75426f345b9731e543a854cf399 Mon Sep 17 00:00:00 2001 From: visualfc Date: Mon, 22 Jun 2026 15:03:26 +0800 Subject: [PATCH 6/8] llgo: clean abi --- internal/abi/type_llgo.go | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/internal/abi/type_llgo.go b/internal/abi/type_llgo.go index 4ecf65f..47e27dd 100644 --- a/internal/abi/type_llgo.go +++ b/internal/abi/type_llgo.go @@ -358,34 +358,6 @@ func (t *UncommonType) ExportedMethods() []Method { return (*[1 << 16]Method)(addChecked(unsafe.Pointer(t), uintptr(t.Moff), "t.xcount > 0"))[:t.Xcount:t.Xcount] } -// func (t *UncommonType) Methods() []Method { -// if t.Mcount == 0 { -// return nil -// } -// methodsPtr := addChecked(unsafe.Pointer(t), uintptr(t.Moff), "t.mcount > 0") -// methods := make([]Method, t.Mcount) -// for i := 0; i < int(t.Mcount); i++ { -// elemPtr := addChecked(methodsPtr, uintptr(i)*unsafe.Sizeof(Method{}), "accessing method element") -// elem := (*Method)(elemPtr) -// methods[i] = *elem -// } -// return methods -// } - -// func (t *UncommonType) ExportedMethods() []Method { -// if t.Xcount == 0 { -// return nil -// } -// mthdsPtr := addChecked(unsafe.Pointer(t), uintptr(t.Moff), "t.xcount > 0") -// mthds := make([]Method, t.Xcount) -// for i := 0; i < int(t.Xcount); i++ { -// elemPtr := addChecked(mthdsPtr, uintptr(i)*unsafe.Sizeof(Method{}), "accessing method element") -// elem := (*Method)(elemPtr) -// mthds[i] = *elem -// } -// return mthds -// } - // Imethod represents a method on an interface type type Imethod struct { Name_ string // name of method From a0966cb412d66cda6a4ddbfbd482de5c403c1514 Mon Sep 17 00:00:00 2001 From: visualfc Date: Mon, 22 Jun 2026 15:09:01 +0800 Subject: [PATCH 7/8] llgo: reset --- rtype_llgo.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/rtype_llgo.go b/rtype_llgo.go index 1bb8a5c..3d5c620 100644 --- a/rtype_llgo.go +++ b/rtype_llgo.go @@ -297,9 +297,16 @@ func newType(pkg string, name string, styp reflect.Type, mcount int, xcount int) } func (ctx *Context) Reset() { + ctx.nAllocateError = 0 + ctx.embedLookupCache = make(map[reflect.Type]reflect.Type) + ctx.structLookupCache = make(map[string][]reflect.Type) + ctx.interfceLookupCache = make(map[string]reflect.Type) + ctx.methodIndexList = make(map[int][]int) + ctx.fnHasImethod = nil } func resetAll() { + globalMethodCache = make(map[int]*ifnValue) } func newMethodSet(styp reflect.Type, maxmfunc, maxpfunc int) reflect.Type { From bf15b58224a365b53136756908ac303c109f4cb6 Mon Sep 17 00:00:00 2001 From: visualfc Date: Mon, 22 Jun 2026 15:12:23 +0800 Subject: [PATCH 8/8] x --- methodof.go | 1 + rtype_llgo.go | 1 + 2 files changed, 2 insertions(+) diff --git a/methodof.go b/methodof.go index 379b99c..bf94903 100644 --- a/methodof.go +++ b/methodof.go @@ -124,6 +124,7 @@ func resizeMethod(typ reflect.Type, mcount int, xcount int) error { return fmt.Errorf("too many methods of %v", typ) } ut.Xcount = uint16(xcount) + ut.Mcount = uint16(mcount) return nil } diff --git a/rtype_llgo.go b/rtype_llgo.go index 3d5c620..2afa82f 100644 --- a/rtype_llgo.go +++ b/rtype_llgo.go @@ -329,6 +329,7 @@ func resizeMethod(typ reflect.Type, mcount int, xcount int) error { return fmt.Errorf("too many methods of %v", typ) } ut.Xcount = uint16(xcount) + ut.Mcount = uint16(mcount) return nil }