ssa: closure use specific struct field name { $f ftype, $data unsafe.pointer }

This commit is contained in:
visualfc
2024-12-21 21:37:46 +08:00
parent 070d64f365
commit a6a3c09c05
14 changed files with 238 additions and 190 deletions

View File

@@ -129,14 +129,12 @@ func makeMethodValue(op string, v Value) Value {
// v.Type returns the actual type of the method value.
ftyp := (*funcType)(unsafe.Pointer(v.Type().(*rtype)))
ptyp := rtypeOf(unsafe.Pointer(uintptr(0)))
typ := runtime.Struct(v.typ().Uncommon().PkgPath_, 2*unsafe.Sizeof(0), abi.StructField{
Name_: "f",
typ := runtime.Struct("", 2*unsafe.Sizeof(0), abi.StructField{
Name_: "$f",
Typ: &ftyp.Type,
}, abi.StructField{
Name_: "data",
Typ: ptyp,
Offset: unsafe.Sizeof(0),
Name_: "$data",
Typ: unsafePointerType,
})
typ.TFlag |= abi.TFlagClosure
_, _, fn := methodReceiver(op, rcvr, int(v.flag)>>flagMethodShift)
@@ -150,6 +148,8 @@ func makeMethodValue(op string, v Value) Value {
return Value{typ, unsafe.Pointer(fv), v.flag&flagRO | flagIndir | flag(Func)}
}
var unsafePointerType = rtypeOf(unsafe.Pointer(nil))
/*
func methodValueCallCodePtr() uintptr {
return abi.FuncPCABI0(methodValueCall)

View File

@@ -486,10 +486,6 @@ func isDirectIface(t *_type) bool {
return t.Kind_&abi.KindDirectIface != 0
}
func SetClosure(t *abi.Type) {
t.TFlag |= abi.TFlagClosure
}
func interfaceStr(ft *abi.InterfaceType) string {
repr := make([]byte, 0, 64)
repr = append(repr, "interface {"...)

View File

@@ -197,6 +197,10 @@ func Struct(pkgPath string, size uintptr, fields ...abi.StructField) *Type {
if len(fields) == 1 && isDirectIface(fields[0].Typ) {
ret.Kind_ |= abi.KindDirectIface
}
if len(fields) == 2 && fields[0].Name_ == "$f" && fields[0].Typ.Kind() == abi.Func &&
fields[1].Name_ == "$data" && fields[1].Typ.Kind() == abi.UnsafePointer {
ret.TFlag |= abi.TFlagClosure
}
rtypeList.addType(&ret.Type)
return &ret.Type
}
@@ -504,7 +508,7 @@ func eqFields(s1, s2 []abi.StructField) bool {
func (r *rtypes) findStruct(pkgPath string, size uintptr, fields []abi.StructField) *Type {
for _, typ := range r.types {
if typ.Kind() == abi.Struct && typ.Size() == size {
if st := typ.StructType(); st.PkgPath_ == pkgPath && eqFields(st.Fields, fields) {
if st := typ.StructType(); (st.IsClosure() || st.PkgPath_ == pkgPath) && eqFields(st.Fields, fields) {
return typ
}
}