From d06cf2caba523046b879b8e2ededef6f7e36b55a Mon Sep 17 00:00:00 2001 From: DQNEO Date: Mon, 21 Aug 2023 22:58:02 +0900 Subject: [PATCH 01/17] broken --- internal/codegen/codegen.go | 14 +++++ internal/ir/ir.go | 2 +- internal/sema/sema.go | 107 ++++++++++++++++++++++-------------- internal/types/types.go | 14 ++--- 4 files changed, 86 insertions(+), 51 deletions(-) diff --git a/internal/codegen/codegen.go b/internal/codegen/codegen.go index 9ee78a8a..e7deb690 100644 --- a/internal/codegen/codegen.go +++ b/internal/codegen/codegen.go @@ -6,6 +6,7 @@ import ( "github.com/DQNEO/babygo/internal/ir" "github.com/DQNEO/babygo/internal/sema" "github.com/DQNEO/babygo/internal/types" + "github.com/DQNEO/babygo/internal/util" "github.com/DQNEO/babygo/lib/fmt" "github.com/DQNEO/babygo/lib/strconv" "github.com/DQNEO/babygo/lib/token" @@ -2186,6 +2187,7 @@ func emitInterfaceTables(itab map[string]*sema.ITabEntry) { // sort map in order to assure the deterministic results for key, ent := range itab { entries[ent.Id] = key + } // skip id=0 @@ -2204,7 +2206,19 @@ func emitInterfaceTables(itab map[string]*sema.ITabEntry) { if len(methods) == 0 { printf(" # no methods\n") } + for mi, m := range methods { + rcvT := ent.Dtype + rcvPointerType, isPtr := rcvT.(*types.Pointer) + if isPtr { + rcvT = rcvPointerType.Elem() + } + namedRcvT := rcvT.(*types.Named) + if namedRcvT.String() == "Variable" && namedRcvT.PkgName == "" { + panic("No PkgName in Variable") + } + util.Logf(" # Dtype %s.%s \n", namedRcvT.PkgName, namedRcvT.String()) + printf(" # Dtype %s.%s \n", namedRcvT.PkgName, namedRcvT.String()) dmethod := sema.LookupMethod(ent.Dtype, m.Name) sym := sema.GetMethodSymbol(dmethod) printf(" .quad .method_name_%d_%d # %s \n", id, mi, m.Name) diff --git a/internal/ir/ir.go b/internal/ir/ir.go index 56cbcac5..783125f3 100644 --- a/internal/ir/ir.go +++ b/internal/ir/ir.go @@ -14,7 +14,7 @@ type IfcConversion struct { type MetaStructLiteralElement struct { Tpos token.Pos - Field *ast.Field + Field *types.Var Type types.Type Value MetaExpr } diff --git a/internal/sema/sema.go b/internal/sema/sema.go index 7ab309d6..a86cf8f5 100644 --- a/internal/sema/sema.go +++ b/internal/sema/sema.go @@ -6,6 +6,7 @@ import ( "github.com/DQNEO/babygo/internal/ir" "github.com/DQNEO/babygo/internal/types" "github.com/DQNEO/babygo/internal/universe" + "github.com/DQNEO/babygo/internal/util" "github.com/DQNEO/babygo/lib/ast" "github.com/DQNEO/babygo/lib/fmt" "github.com/DQNEO/babygo/lib/strconv" @@ -282,8 +283,10 @@ var inNamed string var inNamedType *types.Named func E2T(typeExpr ast.Expr) types.Type { + //util.Logf(" Compiling ast type %T\n", typeExpr) switch t := typeExpr.(type) { case *ast.Ident: + //util.Logf(" ident %s\n", t.Name) obj := t.Obj if obj == nil { panicPos("t.Obj should not be nil", typeExpr.Pos()) @@ -308,26 +311,23 @@ func E2T(typeExpr ast.Expr) types.Type { ut := E2T(dcl.Type) named := types.NewNamed(universe.Error.Name, ut) return named + } + ident := t + if ident.Name == inNamed { + return inNamedType + } + switch dcl := ident.Obj.Decl.(type) { + case *ast.TypeSpec: + typeSpec := dcl + ut := E2T(typeSpec.Type) + t2 := types.NewNamed(ident.Name, ut) + t2.PkgName = ident.Obj.Data.(string) + return t2 default: - switch dcl := t.Obj.Decl.(type) { - case *ast.TypeSpec: - typeSpec := dcl - gt := types.NewNamed(typeSpec.Name.Name, nil) - if typeSpec.Name.Obj.Data != nil { - gt.PkgName = typeSpec.Name.Obj.Data.(string) - } - inNamed = typeSpec.Name.Name - inNamedType = gt - ut := E2T(typeSpec.Type) - gt.UT = ut - inNamedType = nil - inNamed = "" - return gt - default: - panicPos(fmt.Sprintf("Unexpeced:%T ident=%s", t.Obj.Decl, t.Name), t.Pos()) - } - panic("Unexpected flow") + panicPos(fmt.Sprintf("Unexpeced:%T ident=%s", t.Obj.Decl, t.Name), t.Pos()) } + panic("Unexpected flow") + case *ast.ArrayType: if t.Len == nil { return types.NewSlice(E2T(t.Elt)) @@ -336,10 +336,8 @@ func E2T(typeExpr ast.Expr) types.Type { } case *ast.StructType: var fields []*types.Var - var astFields []*ast.Field if t.Fields != nil { for _, fld := range t.Fields.List { - astFields = append(astFields, fld) ft := E2T(fld.Type) v := &types.Var{ Name: fld.Names[0].Name, @@ -348,7 +346,7 @@ func E2T(typeExpr ast.Expr) types.Type { fields = append(fields, v) } } - return types.NewStruct(fields, astFields) + return types.NewStruct(fields) case *ast.StarExpr: if t.X == nil { panicPos("X should not be nil", t.Pos()) @@ -530,10 +528,10 @@ func getKeyTypeOfCollectionType(t types.Type) types.Type { return nil } -func LookupStructField(structType *types.Struct, selName string) *ast.Field { - for i, field := range structType.Fields { +func LookupStructField(structType *types.Struct, selName string) *types.Var { + for _, field := range structType.Fields { if field.Name == selName { - return structType.AstFields[i] + return field } } return nil // not found is OK. This indicates selName is a method name. @@ -666,6 +664,9 @@ func LookupMethod(rcvT types.Type, methodName string) *ir.Method { switch typ := rcvT.(type) { case *types.Named: + if typ.PkgName == "fmt" && typ.String() == "Type" { + panic("fmt.Type should not exist") + } if typ.PkgName == "" && typ.String() == "error" { namedTypeId = "error" return &ir.Method{ @@ -679,6 +680,9 @@ func LookupMethod(rcvT types.Type, methodName string) *ir.Method { } } else { pkgName := typ.PkgName + if pkgName == "" { + panic("No package name: " + typ.String()) + } namedTypeId = pkgName + "." + typ.String() } default: @@ -687,7 +691,10 @@ func LookupMethod(rcvT types.Type, methodName string) *ir.Method { namedType, ok := namedTypes[namedTypeId] if !ok { - panic("method not found: " + methodName + " in " + namedTypeId + " (no method set)") + for nid, _ := range namedTypes { + util.Logf("namedTypeId = %s\n", nid) + } + panic("NamedTypeId is not registered: " + methodName + " in " + namedTypeId + " (no method set)") } method, ok := namedType.MethodSet[methodName] if !ok { @@ -1401,6 +1408,17 @@ func walkSelectorExpr(e *ast.SelectorExpr, ctx *ir.EvalContext) *ir.MetaSelector } else { // expr.field meta.X = walkExpr(e.X, ctx) + + rcvT := meta.X.GetType() + rcvPointerType, isPtr := rcvT.(*types.Pointer) + if isPtr { + rcvT = rcvPointerType.Elem() + } + namedRcvT, isNamed := rcvT.(*types.Named) + if isNamed && namedRcvT.String() == "Variable" && namedRcvT.PkgName == "" { + panicPos("No PkgName in Variable", e.Pos()) + } + typ, isField, offset, needDeref := getTypeOfSelector(meta.X, e.Sel.Name) if typ == nil { panicPos("Selector type should not be nil", e.Pos()) @@ -1443,10 +1461,13 @@ func getTypeOfSelector(x ir.MetaExpr, selName string) (types.Type, bool, int, bo } if structTypeLiteral != nil { + if !structTypeLiteral.IsCalculated { + calcStructSizeAndSetFieldOffset(structTypeLiteral) + } field := LookupStructField(structTypeLiteral, selName) if field != nil { offset := GetStructFieldOffset(field) - return E2T(field.Type), true, offset, needDeref + return field.Type, true, offset, needDeref } } method := LookupMethod(typeOfX, selName) @@ -1762,7 +1783,7 @@ func walkCompositeLit(e *ast.CompositeLit, ctx *ir.EvalContext) *ir.MetaComposit strcctT := structType.Underlying().(*types.Struct) field := LookupStructField(strcctT, fieldName.Name) - fieldType := E2T(field.Type) + fieldType := field.Type ctx := &ir.EvalContext{Type: fieldType} // attach type to nil : STRUCT{Key:nil} valueMeta := walkExpr(kvExpr.Value, ctx) @@ -2097,17 +2118,18 @@ func Walk(pkg *ir.PkgContainer) *ir.AnalyzedPackage { } for _, typeSpec := range typeSpecs { - //@TODO check serializeType()'s *ast.Ident case typeSpec.Name.Obj.Data = pkg.Name // package the type belongs to - eType := &ast.Ident{ - Name: typeSpec.Name.Name, - NamePos: typeSpec.Pos(), - Obj: typeSpec.Name.Obj, - } - t := E2T(eType) - gt := t.(*types.Named) - gt.PkgName = pkg.Name - typs = append(typs, gt) + t := types.NewNamed(typeSpec.Name.Name, nil) + t.PkgName = pkg.Name + util.Logf("Created Pkg type: %s.%s\n", t.PkgName, t.String()) + inNamed = typeSpec.Name.Name + inNamedType = t + ut := E2T(typeSpec.Type) + inNamedType = nil + inNamed = "" + t.UT = ut + + typs = append(typs, t) switch Kind(t) { case types.T_STRUCT: //structType := GetUnderlyingType(t) @@ -2391,19 +2413,20 @@ func GetSizeOfType(t types.Type) int { func calcStructSizeAndSetFieldOffset(structType *types.Struct) int { var offset int = 0 - for i, field := range structType.Fields { - setStructFieldOffset(structType.AstFields[i], offset) + for _, field := range structType.Fields { + setStructFieldOffset(field, offset) size := GetSizeOfType(field.Type) offset += size } + structType.IsCalculated = true return offset } -func GetStructFieldOffset(field *ast.Field) int { +func GetStructFieldOffset(field *types.Var) int { return mapFieldOffset[unsafe.Pointer(field)] } -func setStructFieldOffset(field *ast.Field, offset int) { +func setStructFieldOffset(field *types.Var, offset int) { mapFieldOffset[unsafe.Pointer(field)] = offset } @@ -2592,6 +2615,7 @@ type ITabEntry struct { // "**[1][]*int" => ".dtype.8" func RegisterDtype(dtype types.Type, itype types.Type) { + ds := SerializeType(dtype, false, "") is := SerializeType(itype, false, "") @@ -2610,6 +2634,7 @@ func RegisterDtype(dtype types.Type, itype types.Type) { Dtype: dtype, Label: "." + "itab_" + strconv.Itoa(id), } + ITab[key] = e ITabID++ } diff --git a/internal/types/types.go b/internal/types/types.go index 2ede1547..10572378 100644 --- a/internal/types/types.go +++ b/internal/types/types.go @@ -1,9 +1,5 @@ package types -import ( - "github.com/DQNEO/babygo/lib/ast" -) - type TypeKind string const T_STRING TypeKind = "T_STRING" @@ -219,14 +215,14 @@ type Var struct { } type Struct struct { - Fields []*Var // Fields != nil indicates the struct is set up (possibly with len(Fields) == 0) - AstFields []*ast.Field // @TODO: Replace this by Fields + Fields []*Var // Fields != nil indicates the struct is set up (possibly with len(Fields) == 0) + //AstFields []*ast.Field // @TODO: Replace this by Fields + IsCalculated bool // the offsets are calculated ? } -func NewStruct(fields []*Var, astFields []*ast.Field) *Struct { +func NewStruct(fields []*Var) *Struct { return &Struct{ - Fields: fields, - AstFields: astFields, + Fields: fields, } } From 2a2c9f9d8604fc954f9d9a6c1350ad6728cbe0d8 Mon Sep 17 00:00:00 2001 From: DQNEO Date: Tue, 22 Aug 2023 01:09:23 +0900 Subject: [PATCH 02/17] Try to fix --- internal/codegen/codegen.go | 3 +- internal/ir/ir.go | 2 +- internal/sema/sema.go | 133 ++++++++++++++++++++---------------- 3 files changed, 77 insertions(+), 61 deletions(-) diff --git a/internal/codegen/codegen.go b/internal/codegen/codegen.go index e7deb690..9edaa832 100644 --- a/internal/codegen/codegen.go +++ b/internal/codegen/codegen.go @@ -2103,8 +2103,7 @@ func GenerateDecls(pkg *ir.AnalyzedPackage, declFilePath string) { for _, typ := range pkg.Types { ut := typ.Underlying() utAsString := sema.SerializeType(ut, true, pkg.Name) - named := typ.(*types.Named) - fmt.Fprintf(fout, "type %s %s\n", named.String(), utAsString) + fmt.Fprintf(fout, "type %s %s\n", typ.String(), utAsString) } for _, vr := range pkg.Vars { fmt.Fprintf(fout, "var %s %s\n", vr.Name.Name, sema.SerializeType(vr.Type, true, pkg.Name)) diff --git a/internal/ir/ir.go b/internal/ir/ir.go index 783125f3..ae23162e 100644 --- a/internal/ir/ir.go +++ b/internal/ir/ir.go @@ -498,7 +498,7 @@ type AnalyzedPackage struct { Path string Name string Imports []string - Types []types.Type + Types []*types.Named Consts []*PackageVarConst Funcs []*Func Vars []*PackageVarConst diff --git a/internal/sema/sema.go b/internal/sema/sema.go index a86cf8f5..6e8c8159 100644 --- a/internal/sema/sema.go +++ b/internal/sema/sema.go @@ -281,15 +281,18 @@ func GetTuple(rhsMeta ir.MetaExpr) *types.Tuple { var inNamed string var inNamedType *types.Named +var spaces string = "" func E2T(typeExpr ast.Expr) types.Type { - //util.Logf(" Compiling ast type %T\n", typeExpr) + spaces += " " + util.Logf(spaces+"E2T for %T\n", typeExpr) switch t := typeExpr.(type) { case *ast.Ident: //util.Logf(" ident %s\n", t.Name) + ident := t obj := t.Obj if obj == nil { - panicPos("t.Obj should not be nil", typeExpr.Pos()) + panicPos(ident.Name+" ident.Obj should not be nil", typeExpr.Pos()) } switch obj { case universe.Uintptr: @@ -312,22 +315,13 @@ func E2T(typeExpr ast.Expr) types.Type { named := types.NewNamed(universe.Error.Name, ut) return named } - ident := t - if ident.Name == inNamed { - return inNamedType - } - switch dcl := ident.Obj.Decl.(type) { - case *ast.TypeSpec: - typeSpec := dcl - ut := E2T(typeSpec.Type) - t2 := types.NewNamed(ident.Name, ut) - t2.PkgName = ident.Obj.Data.(string) - return t2 - default: - panicPos(fmt.Sprintf("Unexpeced:%T ident=%s", t.Obj.Decl, t.Name), t.Pos()) - } - panic("Unexpected flow") + for _, pkgType := range pkgTypes { + if pkgType.String() == ident.Name { + return pkgType + } + } + panicPos(fmt.Sprintf(" Cannot attach type : %T \n", ident.Name, ident.Obj), ident.Pos()) case *ast.ArrayType: if t.Len == nil { return types.NewSlice(E2T(t.Elt)) @@ -351,21 +345,8 @@ func E2T(typeExpr ast.Expr) types.Type { if t.X == nil { panicPos("X should not be nil", t.Pos()) } - - if inNamedType != nil { - ident, ok := t.X.(*ast.Ident) - if ok { - if ident.Name == inNamed { - p := types.NewPointer(inNamedType) - return p - } else { - return types.NewPointer(E2T(t.X)) - } - } else { - return types.NewPointer(E2T(t.X)) - } - } - return types.NewPointer(E2T(t.X)) + origT := E2T(t.X) + return types.NewPointer(origT) case *ast.Ellipsis: slc := types.NewSlice(E2T(t.Elt)) slc.IsElps = true @@ -464,7 +445,7 @@ func Kind(gType types.Type) types.TypeKind { case *types.Named: ut := gt.Underlying() if ut == nil { - panic(fmt.Sprintf("nil is not expected: NamedType %s\n", gt.String())) + panic(fmt.Sprintf("no underlying type for NamedType %s\n", gt.String())) } //t := &types.Type: ut} return Kind(ut) @@ -698,7 +679,10 @@ func LookupMethod(rcvT types.Type, methodName string) *ir.Method { } method, ok := namedType.MethodSet[methodName] if !ok { - panic("method not found: " + methodName + " in " + namedTypeId) + for mname, _ := range namedType.MethodSet { + util.Logf(" %s method = %s\n", namedTypeId, mname) + } + panic("method not found: '" + methodName + "' in " + namedTypeId) } return method } @@ -1419,6 +1403,7 @@ func walkSelectorExpr(e *ast.SelectorExpr, ctx *ir.EvalContext) *ir.MetaSelector panicPos("No PkgName in Variable", e.Pos()) } + util.Logf("trying getTypeOfSelector (%T).%s\n", meta.X, e.Sel.Name) typ, isField, offset, needDeref := getTypeOfSelector(meta.X, e.Sel.Name) if typ == nil { panicPos("Selector type should not be nil", e.Pos()) @@ -1440,6 +1425,8 @@ func getTypeOfSelector(x ir.MetaExpr, selName string) (types.Type, bool, int, bo var needDeref bool typeOfX := GetTypeOfExpr(x) utX := typeOfX.Underlying().Underlying() + util.Logf("utX = %T\n", utX) + var structTypeLiteral *types.Struct switch typ := utX.(type) { case *types.Struct: // strct.field | strct.method @@ -1454,21 +1441,30 @@ func getTypeOfSelector(x ir.MetaExpr, selName string) (types.Type, bool, int, bo structTypeLiteral, isStruct = ut.(*types.Struct) if !isStruct { typeOfX = origType + util.Logf("ut %T\n", ut) + panic("Bad type") + } else { + } } else { structTypeLiteral = origType.Underlying().(*types.Struct) } + + util.Logf("structTypeLiteral %T\n", structTypeLiteral) } if structTypeLiteral != nil { if !structTypeLiteral.IsCalculated { calcStructSizeAndSetFieldOffset(structTypeLiteral) } + util.Logf("Looking up struct field %T.%s\n", structTypeLiteral, selName) field := LookupStructField(structTypeLiteral, selName) if field != nil { offset := GetStructFieldOffset(field) return field.Type, true, offset, needDeref } + } else { + util.Logf("Not structTypeLiteral %T\n", x) } method := LookupMethod(typeOfX, selName) return E2T(method.FuncType), false, 0, needDeref @@ -2073,16 +2069,18 @@ func SetVariable(obj *ast.Object, vr *ir.Variable) { // - transmit ok syntax context // - (hope) attach type to untyped constants // - (hope) transmit the need of interface conversion + +var pkgTypes []*types.Named + func Walk(pkg *ir.PkgContainer) *ir.AnalyzedPackage { pkg.StringIndex = 0 pkg.StringLiterals = nil CurrentPkg = pkg - + pkgTypes = nil ITab = make(map[string]*ITabEntry) ITabID = 1 var hasInitFunc bool - var typs []types.Type var funcs []*ir.Func var consts []*ir.PackageVarConst var vars []*ir.PackageVarConst @@ -2118,22 +2116,50 @@ func Walk(pkg *ir.PkgContainer) *ir.AnalyzedPackage { } for _, typeSpec := range typeSpecs { - typeSpec.Name.Obj.Data = pkg.Name // package the type belongs to + // Register package types t := types.NewNamed(typeSpec.Name.Name, nil) t.PkgName = pkg.Name - util.Logf("Created Pkg type: %s.%s\n", t.PkgName, t.String()) - inNamed = typeSpec.Name.Name - inNamedType = t - ut := E2T(typeSpec.Type) - inNamedType = nil - inNamed = "" - t.UT = ut + util.Logf("NewNamed Pkg type: %s.%s\n", t.PkgName, t.String()) + pkgTypes = append(pkgTypes, t) - typs = append(typs, t) - switch Kind(t) { + // named type + ei := &ir.ExportedIdent{ + Name: typeSpec.Name.Name, + IsType: true, + Obj: typeSpec.Name.Obj, + Type: t, + PkgName: pkg.Name, + Pos: typeSpec.Pos(), + } + exportedIdents[string(NewQI(pkg.Name, typeSpec.Name.Name))] = ei + } + + for _, typeSpec := range typeSpecs { + util.Logf("typeSpec: %s\n", typeSpec.Name.Name) + spaces = "" + ut := E2T(typeSpec.Type) + if ut == nil { + panic("ut should not be nil") + } + var t *types.Named + for _, t = range pkgTypes { + if t.String() == typeSpec.Name.Name { + util.Logf(" attach t = %s\n", t.String()) + t.UT = ut + } + } + t = nil + if ut == nil { + panic("t should not be nil") + } + if ut.Underlying() == nil { + panic(ut.String() + " Underlying should not be nil") + } + spaces = "" + switch Kind(ut) { case types.T_STRUCT: //structType := GetUnderlyingType(t) - st := t.Underlying().Underlying() + st := ut.Underlying().Underlying() calcStructSizeAndSetFieldOffset(st.(*types.Struct)) // calcStructSizeAndSetFieldOffset(structType.E.(*ast.StructType)) case types.T_INTERFACE: @@ -2152,16 +2178,6 @@ func Walk(pkg *ir.PkgContainer) *ir.AnalyzedPackage { } } } - // named type - ei := &ir.ExportedIdent{ - Name: typeSpec.Name.Name, - IsType: true, - Obj: typeSpec.Name.Obj, - Type: t, - PkgName: pkg.Name, - Pos: typeSpec.Pos(), - } - exportedIdents[string(NewQI(pkg.Name, typeSpec.Name.Name))] = ei } for _, spec := range constSpecs { @@ -2342,6 +2358,7 @@ func Walk(pkg *ir.PkgContainer) *ir.AnalyzedPackage { fnc.HasBody = true var ms []ir.MetaStmt for _, stmt := range funcDecl.Body.List { + spaces = "" m := walkStmt(stmt) ms = append(ms, m) } @@ -2358,7 +2375,7 @@ func Walk(pkg *ir.PkgContainer) *ir.AnalyzedPackage { Path: pkg.Path, Name: pkg.Name, Imports: pkg.Imports, - Types: typs, + Types: pkgTypes, Funcs: funcs, Consts: consts, Vars: vars, From 13db4de4cc7f91745f07a40c266e281efdecf404 Mon Sep 17 00:00:00 2001 From: DQNEO Date: Tue, 22 Aug 2023 02:36:18 +0900 Subject: [PATCH 03/17] Broken --- internal/codegen/codegen.go | 6 +-- internal/ir/ir.go | 2 +- internal/sema/sema.go | 94 +++++++++++++++++++++-------------- internal/types/types.go | 11 ++-- internal/universe/universe.go | 2 +- 5 files changed, 70 insertions(+), 45 deletions(-) diff --git a/internal/codegen/codegen.go b/internal/codegen/codegen.go index 9edaa832..c57eaff1 100644 --- a/internal/codegen/codegen.go +++ b/internal/codegen/codegen.go @@ -521,7 +521,7 @@ func emitCall(fv *ir.FuncValue, args []ir.MetaExpr, paramTypes []types.Type, ret } func emitAllocReturnVarsAreaFF(ff *ir.Func) { - rtypes := (ff.Signature.ReturnTypes) + rtypes := (ff.FuncType.Typ.Results.Types) emitAllocReturnVarsArea(getTotalSizeOfType(rtypes)) } @@ -534,8 +534,8 @@ func getTotalSizeOfType(ts []types.Type) int { } func emitCallFF(ff *ir.Func) { - ptypes := (ff.Signature.ParamTypes) - rtypes := (ff.Signature.ReturnTypes) + ptypes := ff.FuncType.Typ.Params.Types + rtypes := ff.FuncType.Typ.Results.Types totalParamSize := getTotalSizeOfType(ptypes) symbol := ff.PkgName + "." + ff.Name emitCallQ(sema.NewFuncValueFromSymbol(symbol), totalParamSize, rtypes) diff --git a/internal/ir/ir.go b/internal/ir/ir.go index ae23162e..d1c8a085 100644 --- a/internal/ir/ir.go +++ b/internal/ir/ir.go @@ -441,7 +441,7 @@ type Func struct { Retvars []*Variable Method *Method Decl *ast.FuncDecl - Signature *Signature + FuncType *types.Func HasDefer bool DeferVar *Variable } diff --git a/internal/sema/sema.go b/internal/sema/sema.go index 6e8c8159..0e60e385 100644 --- a/internal/sema/sema.go +++ b/internal/sema/sema.go @@ -251,13 +251,15 @@ func FieldList2Tuple(fieldList *ast.FieldList) *types.Tuple { } var r = &types.Tuple{} for _, e2 := range fieldList.List { - ident, isIdent := e2.Type.(*ast.Ident) - var t types.Type - if isIdent && ident.Name == inNamed { - t = inNamedType - } else { - t = E2T(e2.Type) - } + util.Logf("[FieldList2Tuple] %T \n", e2) + t := E2T(e2.Type) + //ident, isIdent := e2.Type.(*ast.Ident) + //var t types.Type + //if isIdent && ident.Name == inNamed { + // util.Logf("[FieldList2Tuple] %s \n", ident.Name) + // t = inNamedType + //} else { + //} r.Types = append(r.Types, t) } @@ -279,13 +281,13 @@ func GetTuple(rhsMeta ir.MetaExpr) *types.Tuple { } } -var inNamed string -var inNamedType *types.Named +// var inNamed string +// var inNamedType *types.Named var spaces string = "" func E2T(typeExpr ast.Expr) types.Type { - spaces += " " - util.Logf(spaces+"E2T for %T\n", typeExpr) + //spaces += " " + util.Logf("[%s] E2T for %T\n", Fset.Position(typeExpr.Pos()).String(), typeExpr) switch t := typeExpr.(type) { case *ast.Ident: //util.Logf(" ident %s\n", t.Name) @@ -317,11 +319,12 @@ func E2T(typeExpr ast.Expr) types.Type { } for _, pkgType := range pkgTypes { + util.Logf(" ident %s <=> pkgType %s.%s\n", ident.Name, pkgType.PkgName, pkgType.String()) if pkgType.String() == ident.Name { return pkgType } } - panicPos(fmt.Sprintf(" Cannot attach type : %T \n", ident.Name, ident.Obj), ident.Pos()) + panicPos(fmt.Sprintf(" Cannot attach type : %s \n", ident.Name), ident.Pos()) case *ast.ArrayType: if t.Len == nil { return types.NewSlice(E2T(t.Elt)) @@ -360,7 +363,7 @@ func E2T(typeExpr ast.Expr) types.Type { methodName := m.Names[0].Name t := E2T(m.Type) f := &types.Func{ - Typ: t, + Typ: t.(*types.Func).Typ, Name: methodName, } methods = append(methods, f) @@ -368,6 +371,7 @@ func E2T(typeExpr ast.Expr) types.Type { } return types.NewInterfaceType(methods) case *ast.FuncType: + sig := &types.Signature{} if t.Params != nil { sig.Params = FieldList2Tuple(t.Params) @@ -381,7 +385,9 @@ func E2T(typeExpr ast.Expr) types.Type { return E2T(typeExpr) case *ast.SelectorExpr: if isQI(t) { // e.g. unsafe.Pointer + util.Logf(" type of selector %s\n", string(Selector2QI(t))) ei := LookupForeignIdent(Selector2QI(t), t.Pos()) + util.Logf(" type %T\n", ei.Type) return ei.Type } else { panic("@TBI") @@ -1384,7 +1390,7 @@ func walkSelectorExpr(e *ast.SelectorExpr, ctx *ir.EvalContext) *ir.MetaSelector QI: qi, } meta.ForeignValue = foreignMeta - meta.Type = E2T(ei.Func.Decl.Type) + meta.Type = ei.Func.FuncType } else { // var|con meta.ForeignValue = ei.MetaIdent meta.Type = ei.Type @@ -1403,7 +1409,6 @@ func walkSelectorExpr(e *ast.SelectorExpr, ctx *ir.EvalContext) *ir.MetaSelector panicPos("No PkgName in Variable", e.Pos()) } - util.Logf("trying getTypeOfSelector (%T).%s\n", meta.X, e.Sel.Name) typ, isField, offset, needDeref := getTypeOfSelector(meta.X, e.Sel.Name) if typ == nil { panicPos("Selector type should not be nil", e.Pos()) @@ -1422,10 +1427,11 @@ func walkSelectorExpr(e *ast.SelectorExpr, ctx *ir.EvalContext) *ir.MetaSelector func getTypeOfSelector(x ir.MetaExpr, selName string) (types.Type, bool, int, bool) { // (strct).field | (ptr).field | (obj).method + util.Logf("%s: trying getTypeOfSelector (%T).%s\n", Fset.Position(x.Pos()).String(), x, selName) var needDeref bool typeOfX := GetTypeOfExpr(x) utX := typeOfX.Underlying().Underlying() - util.Logf("utX = %T\n", utX) + //util.Logf("utX = %T\n", utX) var structTypeLiteral *types.Struct switch typ := utX.(type) { @@ -1450,21 +1456,21 @@ func getTypeOfSelector(x ir.MetaExpr, selName string) (types.Type, bool, int, bo structTypeLiteral = origType.Underlying().(*types.Struct) } - util.Logf("structTypeLiteral %T\n", structTypeLiteral) + //util.Logf("structTypeLiteral %T\n", structTypeLiteral) } if structTypeLiteral != nil { if !structTypeLiteral.IsCalculated { calcStructSizeAndSetFieldOffset(structTypeLiteral) } - util.Logf("Looking up struct field %T.%s\n", structTypeLiteral, selName) + //util.Logf("Looking up struct field %T.%s\n", structTypeLiteral, selName) field := LookupStructField(structTypeLiteral, selName) if field != nil { offset := GetStructFieldOffset(field) return field.Type, true, offset, needDeref } } else { - util.Logf("Not structTypeLiteral %T\n", x) + //util.Logf("Not structTypeLiteral %T\n", x) } method := LookupMethod(typeOfX, selName) return E2T(method.FuncType), false, 0, needDeref @@ -2134,6 +2140,7 @@ func Walk(pkg *ir.PkgContainer) *ir.AnalyzedPackage { exportedIdents[string(NewQI(pkg.Name, typeSpec.Name.Name))] = ei } + var structTypes []*types.Struct for _, typeSpec := range typeSpecs { util.Logf("typeSpec: %s\n", typeSpec.Name.Name) spaces = "" @@ -2159,8 +2166,8 @@ func Walk(pkg *ir.PkgContainer) *ir.AnalyzedPackage { switch Kind(ut) { case types.T_STRUCT: //structType := GetUnderlyingType(t) - st := ut.Underlying().Underlying() - calcStructSizeAndSetFieldOffset(st.(*types.Struct)) + st := ut.Underlying().Underlying().(*types.Struct) + structTypes = append(structTypes, st) // calcStructSizeAndSetFieldOffset(structType.E.(*ast.StructType)) case types.T_INTERFACE: // register ifc method @@ -2180,6 +2187,15 @@ func Walk(pkg *ir.PkgContainer) *ir.AnalyzedPackage { } } + for _, st := range structTypes { + calcStructSizeAndSetFieldOffset(st) + } + + for _, namedT := range pkgTypes { + if namedT.Underlying() == nil { + panic("named type " + namedT.String() + " Underlying() is nil") + } + } for _, spec := range constSpecs { assert(len(spec.Values) == 1, "only 1 value is supported", __func__) lhsIdent := spec.Names[0] @@ -2299,7 +2315,7 @@ func Walk(pkg *ir.PkgContainer) *ir.AnalyzedPackage { PkgName: CurrentPkg.Name, Name: funcDecl.Name.Name, Decl: funcDecl, - Signature: FuncTypeToSignature(funcDecl.Type), + FuncType: E2T(funcDecl.Type).(*types.Func), Localarea: 0, Argsarea: 16, // return address + previous rbp } @@ -2395,9 +2411,11 @@ const SizeOfPtr int = 8 const SizeOfInterface int = 16 func GetSizeOfType(t types.Type) int { - t = t.Underlying() - t = t.Underlying() - switch Kind(t) { + ut := t.Underlying() + if ut == nil { + panic(fmt.Sprintf("ut should not be nil: %T %s", t, t.(*types.Named).String())) + } + switch Kind(ut) { case types.T_SLICE: return SizeOfSlice case types.T_STRING: @@ -2415,11 +2433,11 @@ func GetSizeOfType(t types.Type) int { case types.T_INTERFACE: return SizeOfInterface case types.T_ARRAY: - arrayType := t.(*types.Array) + arrayType := ut.(*types.Array) elmSize := GetSizeOfType(arrayType.Elem()) return elmSize * arrayType.Len() case types.T_STRUCT: - return calcStructSizeAndSetFieldOffset(t.(*types.Struct)) + return calcStructSizeAndSetFieldOffset(ut.(*types.Struct)) case types.T_FUNC: return SizeOfPtr default: @@ -2530,11 +2548,11 @@ func FuncTypeToSignature(funcType *ast.FuncType) *ir.Signature { func RestoreMethodDecl(m *types.Func, showOnlyForeignPrefix bool, currentPkgName string) string { name := m.Name - fun, ok := m.Typ.(*types.Func) - if !ok { - panic(fmt.Sprintf("[SerializeType] Invalid type:%T\n", m.Typ)) - } - sig := fun.Typ.(*types.Signature) + //sig, ok := m.Typ.(*types.Signature) + //if !ok { + // panic(fmt.Sprintf("[SerializeType] Invalid type:%T\n", m.Typ)) + //} + sig := m.Typ var p string var r string if sig.Params != nil && len(sig.Params.Types) > 0 { @@ -2562,17 +2580,19 @@ func RestoreMethodDecl(m *types.Func, showOnlyForeignPrefix bool, currentPkgName func RestoreFuncDecl(fnc *ir.Func, showOnlyForeignPrefix bool, currentPkgName string) string { var p string var r string - for _, t := range fnc.Signature.ParamTypes { + for _, t := range fnc.FuncType.Typ.Params.Types { if p != "" { p += "," } p += SerializeType(t, showOnlyForeignPrefix, currentPkgName) } - for _, t := range fnc.Signature.ReturnTypes { - if r != "" { - r += "," + if fnc.FuncType.Typ.Results != nil { + for _, t := range fnc.FuncType.Typ.Results.Types { + if r != "" { + r += "," + } + r += SerializeType(t, showOnlyForeignPrefix, currentPkgName) } - r += SerializeType(t, showOnlyForeignPrefix, currentPkgName) } var m string var star string diff --git a/internal/types/types.go b/internal/types/types.go index 10572378..0a1c5530 100644 --- a/internal/types/types.go +++ b/internal/types/types.go @@ -181,7 +181,7 @@ func (t *Interface) Underlying() Type { return t } func (t *Interface) String() string { return "@TBI" } type Func struct { - Typ Type + Typ *Signature Name string } @@ -242,5 +242,10 @@ func NewNamed(name string, typ Type) *Named { } } -func (t *Named) Underlying() Type { return t.UT } -func (t *Named) String() string { return t.name } +func (t *Named) Underlying() Type { + if t.UT == nil { + panic("Named type " + t.PkgName + "." + t.name + ": Underlying is nil") + } + return t.UT +} +func (t *Named) String() string { return t.name } diff --git a/internal/universe/universe.go b/internal/universe/universe.go index 19d7ccba..86bbee04 100644 --- a/internal/universe/universe.go +++ b/internal/universe/universe.go @@ -124,7 +124,7 @@ func CreateUniverse() *ast.Scope { True, False, // types String, Uintptr, Bool, Int, Uint8, Uint16, Int32, Error, - // funcs + // funcs^ New, Make, Append, Len, Cap, Panic, Delete, } From 06b515f65014dceb549f1dd5e21663e98a51e9c7 Mon Sep 17 00:00:00 2001 From: DQNEO Date: Tue, 22 Aug 2023 02:55:27 +0900 Subject: [PATCH 04/17] it works! --- internal/ir/ir.go | 2 +- internal/sema/sema.go | 18 +++++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/internal/ir/ir.go b/internal/ir/ir.go index d1c8a085..3aac33f7 100644 --- a/internal/ir/ir.go +++ b/internal/ir/ir.go @@ -451,7 +451,7 @@ type Method struct { RcvNamedType *ast.Ident IsPtrMethod bool Name string - FuncType *ast.FuncType + FuncType types.Type } type Variable struct { diff --git a/internal/sema/sema.go b/internal/sema/sema.go index 0e60e385..c76debb8 100644 --- a/internal/sema/sema.go +++ b/internal/sema/sema.go @@ -371,7 +371,6 @@ func E2T(typeExpr ast.Expr) types.Type { } return types.NewInterfaceType(methods) case *ast.FuncType: - sig := &types.Signature{} if t.Params != nil { sig.Params = FieldList2Tuple(t.Params) @@ -622,7 +621,7 @@ func newMethod(pkgName string, funcDecl *ast.FuncDecl) *ir.Method { RcvNamedType: rcvNamedType, IsPtrMethod: isPtr, Name: funcDecl.Name.Name, - FuncType: funcDecl.Type, + FuncType: E2T(funcDecl.Type), } return method } @@ -663,7 +662,7 @@ func LookupMethod(rcvT types.Type, methodName string) *ir.Method { }, IsPtrMethod: false, Name: "Error", - FuncType: universe.ErrorMethodFuncType, + FuncType: E2T(universe.ErrorMethodFuncType), } } else { pkgName := typ.PkgName @@ -1446,17 +1445,13 @@ func getTypeOfSelector(x ir.MetaExpr, selName string) (types.Type, bool, int, bo var isStruct bool structTypeLiteral, isStruct = ut.(*types.Struct) if !isStruct { - typeOfX = origType - util.Logf("ut %T\n", ut) - panic("Bad type") - } else { - + structTypeLiteral = nil // not a field, but method + typeOfX = origType // var p *T ; p.method(); func(p *T) method() {...} } } else { structTypeLiteral = origType.Underlying().(*types.Struct) } - //util.Logf("structTypeLiteral %T\n", structTypeLiteral) } if structTypeLiteral != nil { @@ -1472,8 +1467,9 @@ func getTypeOfSelector(x ir.MetaExpr, selName string) (types.Type, bool, int, bo } else { //util.Logf("Not structTypeLiteral %T\n", x) } + method := LookupMethod(typeOfX, selName) - return E2T(method.FuncType), false, 0, needDeref + return method.FuncType, false, 0, needDeref } func walkConversion(pos token.Pos, toType types.Type, arg0 ir.MetaExpr) ir.MetaExpr { @@ -2174,7 +2170,7 @@ func Walk(pkg *ir.PkgContainer) *ir.AnalyzedPackage { it := typeSpec.Type.(*ast.InterfaceType) if it.Methods != nil { for _, m := range it.Methods.List { - funcType := m.Type.(*ast.FuncType) + funcType := E2T(m.Type) method := &ir.Method{ PkgName: pkg.Name, RcvNamedType: typeSpec.Name, From 09685bb39fe5fc28bb8528d38bb78b7737f43e3c Mon Sep 17 00:00:00 2001 From: DQNEO Date: Tue, 22 Aug 2023 03:05:20 +0900 Subject: [PATCH 05/17] Refactor --- internal/sema/sema.go | 46 +++++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/internal/sema/sema.go b/internal/sema/sema.go index c76debb8..143282a2 100644 --- a/internal/sema/sema.go +++ b/internal/sema/sema.go @@ -281,8 +281,6 @@ func GetTuple(rhsMeta ir.MetaExpr) *types.Tuple { } } -// var inNamed string -// var inNamedType *types.Named var spaces string = "" func E2T(typeExpr ast.Expr) types.Type { @@ -318,11 +316,9 @@ func E2T(typeExpr ast.Expr) types.Type { return named } - for _, pkgType := range pkgTypes { - util.Logf(" ident %s <=> pkgType %s.%s\n", ident.Name, pkgType.PkgName, pkgType.String()) - if pkgType.String() == ident.Name { - return pkgType - } + namedType, ok := pkgNamedTypesMap[ident.Name] + if ok { + return namedType } panicPos(fmt.Sprintf(" Cannot attach type : %s \n", ident.Name), ident.Pos()) case *ast.ArrayType: @@ -2072,13 +2068,14 @@ func SetVariable(obj *ast.Object, vr *ir.Variable) { // - (hope) attach type to untyped constants // - (hope) transmit the need of interface conversion -var pkgTypes []*types.Named +var pkgNamedTypesMap map[string]*types.Named func Walk(pkg *ir.PkgContainer) *ir.AnalyzedPackage { pkg.StringIndex = 0 pkg.StringLiterals = nil CurrentPkg = pkg - pkgTypes = nil + var pkgNamedTypes []*types.Named + pkgNamedTypesMap = make(map[string]*types.Named) ITab = make(map[string]*ITabEntry) ITabID = 1 @@ -2122,8 +2119,8 @@ func Walk(pkg *ir.PkgContainer) *ir.AnalyzedPackage { t := types.NewNamed(typeSpec.Name.Name, nil) t.PkgName = pkg.Name util.Logf("NewNamed Pkg type: %s.%s\n", t.PkgName, t.String()) - pkgTypes = append(pkgTypes, t) - + pkgNamedTypes = append(pkgNamedTypes, t) + pkgNamedTypesMap[typeSpec.Name.Name] = t // named type ei := &ir.ExportedIdent{ Name: typeSpec.Name.Name, @@ -2144,17 +2141,9 @@ func Walk(pkg *ir.PkgContainer) *ir.AnalyzedPackage { if ut == nil { panic("ut should not be nil") } - var t *types.Named - for _, t = range pkgTypes { - if t.String() == typeSpec.Name.Name { - util.Logf(" attach t = %s\n", t.String()) - t.UT = ut - } - } - t = nil - if ut == nil { - panic("t should not be nil") - } + namedType := pkgNamedTypesMap[typeSpec.Name.Name] + namedType.UT = ut + if ut.Underlying() == nil { panic(ut.String() + " Underlying should not be nil") } @@ -2183,15 +2172,16 @@ func Walk(pkg *ir.PkgContainer) *ir.AnalyzedPackage { } } - for _, st := range structTypes { - calcStructSizeAndSetFieldOffset(st) - } - - for _, namedT := range pkgTypes { + for _, namedT := range pkgNamedTypes { if namedT.Underlying() == nil { panic("named type " + namedT.String() + " Underlying() is nil") } } + + for _, st := range structTypes { + calcStructSizeAndSetFieldOffset(st) + } + for _, spec := range constSpecs { assert(len(spec.Values) == 1, "only 1 value is supported", __func__) lhsIdent := spec.Names[0] @@ -2387,7 +2377,7 @@ func Walk(pkg *ir.PkgContainer) *ir.AnalyzedPackage { Path: pkg.Path, Name: pkg.Name, Imports: pkg.Imports, - Types: pkgTypes, + Types: pkgNamedTypes, Funcs: funcs, Consts: consts, Vars: vars, From 786842508c05d34c03f6b986187ae60d37221bf2 Mon Sep 17 00:00:00 2001 From: DQNEO Date: Tue, 22 Aug 2023 03:09:48 +0900 Subject: [PATCH 06/17] Eliminate map to manage fields offset --- internal/codegen/codegen.go | 5 ++++- internal/sema/sema.go | 27 ++++++++------------------- internal/types/types.go | 5 +++-- 3 files changed, 15 insertions(+), 22 deletions(-) diff --git a/internal/codegen/codegen.go b/internal/codegen/codegen.go index c57eaff1..66e1765e 100644 --- a/internal/codegen/codegen.go +++ b/internal/codegen/codegen.go @@ -399,7 +399,10 @@ func emitStructLiteral(meta *ir.MetaCompositLit) { // push lhs address emitPushStackTop(types.Uintptr, 0, "address of struct heaad") - fieldOffset := sema.GetStructFieldOffset(metaElm.Field) + fieldOffset := metaElm.Field.Offset + if fieldOffset < 0 { + panic("field offset ist not set") + } emitAddConst(fieldOffset, "address of struct field") // push rhs value diff --git a/internal/sema/sema.go b/internal/sema/sema.go index 143282a2..a9f15126 100644 --- a/internal/sema/sema.go +++ b/internal/sema/sema.go @@ -1,8 +1,6 @@ package sema import ( - "unsafe" - "github.com/DQNEO/babygo/internal/ir" "github.com/DQNEO/babygo/internal/types" "github.com/DQNEO/babygo/internal/universe" @@ -20,7 +18,6 @@ var CurrentPkg *ir.PkgContainer var exportedIdents = make(map[string]*ir.ExportedIdent) var currentFor *ir.MetaForContainer var currentFunc *ir.Func -var mapFieldOffset = make(map[unsafe.Pointer]int) func Clear() { Fset = nil @@ -28,7 +25,6 @@ func Clear() { exportedIdents = nil currentFor = nil currentFunc = nil - mapFieldOffset = nil } func assert(bol bool, msg string, caller string) { @@ -333,8 +329,9 @@ func E2T(typeExpr ast.Expr) types.Type { for _, fld := range t.Fields.List { ft := E2T(fld.Type) v := &types.Var{ - Name: fld.Names[0].Name, - Type: ft, + Name: fld.Names[0].Name, + Type: ft, + Offset: -1, } fields = append(fields, v) } @@ -1457,11 +1454,11 @@ func getTypeOfSelector(x ir.MetaExpr, selName string) (types.Type, bool, int, bo //util.Logf("Looking up struct field %T.%s\n", structTypeLiteral, selName) field := LookupStructField(structTypeLiteral, selName) if field != nil { - offset := GetStructFieldOffset(field) - return field.Type, true, offset, needDeref + if field.Offset < 0 { + panic("field.Offset is not set") + } + return field.Type, true, field.Offset, needDeref } - } else { - //util.Logf("Not structTypeLiteral %T\n", x) } method := LookupMethod(typeOfX, selName) @@ -2435,7 +2432,7 @@ func GetSizeOfType(t types.Type) int { func calcStructSizeAndSetFieldOffset(structType *types.Struct) int { var offset int = 0 for _, field := range structType.Fields { - setStructFieldOffset(field, offset) + field.Offset = offset size := GetSizeOfType(field.Type) offset += size } @@ -2443,14 +2440,6 @@ func calcStructSizeAndSetFieldOffset(structType *types.Struct) int { return offset } -func GetStructFieldOffset(field *types.Var) int { - return mapFieldOffset[unsafe.Pointer(field)] -} - -func setStructFieldOffset(field *types.Var, offset int) { - mapFieldOffset[unsafe.Pointer(field)] = offset -} - func EvalInt(expr ast.Expr) int { if expr == nil { panic("EvanInt: nil is not expected") diff --git a/internal/types/types.go b/internal/types/types.go index 0a1c5530..953b35a6 100644 --- a/internal/types/types.go +++ b/internal/types/types.go @@ -210,8 +210,9 @@ func (t *Signature) Underlying() Type { return t } func (t *Signature) String() string { return "@TBI" } type Var struct { - Name string - Type Type + Name string + Type Type + Offset int } type Struct struct { From 318eec8b585d305923d42854bd8652b941fd31a5 Mon Sep 17 00:00:00 2001 From: DQNEO Date: Tue, 22 Aug 2023 03:14:34 +0900 Subject: [PATCH 07/17] gc --- internal/codegen/codegen.go | 2 -- internal/sema/sema.go | 32 +------------------------------- 2 files changed, 1 insertion(+), 33 deletions(-) diff --git a/internal/codegen/codegen.go b/internal/codegen/codegen.go index 66e1765e..fcb954ad 100644 --- a/internal/codegen/codegen.go +++ b/internal/codegen/codegen.go @@ -6,7 +6,6 @@ import ( "github.com/DQNEO/babygo/internal/ir" "github.com/DQNEO/babygo/internal/sema" "github.com/DQNEO/babygo/internal/types" - "github.com/DQNEO/babygo/internal/util" "github.com/DQNEO/babygo/lib/fmt" "github.com/DQNEO/babygo/lib/strconv" "github.com/DQNEO/babygo/lib/token" @@ -2219,7 +2218,6 @@ func emitInterfaceTables(itab map[string]*sema.ITabEntry) { if namedRcvT.String() == "Variable" && namedRcvT.PkgName == "" { panic("No PkgName in Variable") } - util.Logf(" # Dtype %s.%s \n", namedRcvT.PkgName, namedRcvT.String()) printf(" # Dtype %s.%s \n", namedRcvT.PkgName, namedRcvT.String()) dmethod := sema.LookupMethod(ent.Dtype, m.Name) sym := sema.GetMethodSymbol(dmethod) diff --git a/internal/sema/sema.go b/internal/sema/sema.go index a9f15126..2b250be9 100644 --- a/internal/sema/sema.go +++ b/internal/sema/sema.go @@ -4,7 +4,6 @@ import ( "github.com/DQNEO/babygo/internal/ir" "github.com/DQNEO/babygo/internal/types" "github.com/DQNEO/babygo/internal/universe" - "github.com/DQNEO/babygo/internal/util" "github.com/DQNEO/babygo/lib/ast" "github.com/DQNEO/babygo/lib/fmt" "github.com/DQNEO/babygo/lib/strconv" @@ -247,16 +246,7 @@ func FieldList2Tuple(fieldList *ast.FieldList) *types.Tuple { } var r = &types.Tuple{} for _, e2 := range fieldList.List { - util.Logf("[FieldList2Tuple] %T \n", e2) t := E2T(e2.Type) - //ident, isIdent := e2.Type.(*ast.Ident) - //var t types.Type - //if isIdent && ident.Name == inNamed { - // util.Logf("[FieldList2Tuple] %s \n", ident.Name) - // t = inNamedType - //} else { - //} - r.Types = append(r.Types, t) } return r @@ -277,14 +267,9 @@ func GetTuple(rhsMeta ir.MetaExpr) *types.Tuple { } } -var spaces string = "" - func E2T(typeExpr ast.Expr) types.Type { - //spaces += " " - util.Logf("[%s] E2T for %T\n", Fset.Position(typeExpr.Pos()).String(), typeExpr) switch t := typeExpr.(type) { case *ast.Ident: - //util.Logf(" ident %s\n", t.Name) ident := t obj := t.Obj if obj == nil { @@ -377,9 +362,7 @@ func E2T(typeExpr ast.Expr) types.Type { return E2T(typeExpr) case *ast.SelectorExpr: if isQI(t) { // e.g. unsafe.Pointer - util.Logf(" type of selector %s\n", string(Selector2QI(t))) ei := LookupForeignIdent(Selector2QI(t), t.Pos()) - util.Logf(" type %T\n", ei.Type) return ei.Type } else { panic("@TBI") @@ -670,16 +653,10 @@ func LookupMethod(rcvT types.Type, methodName string) *ir.Method { namedType, ok := namedTypes[namedTypeId] if !ok { - for nid, _ := range namedTypes { - util.Logf("namedTypeId = %s\n", nid) - } panic("NamedTypeId is not registered: " + methodName + " in " + namedTypeId + " (no method set)") } method, ok := namedType.MethodSet[methodName] if !ok { - for mname, _ := range namedType.MethodSet { - util.Logf(" %s method = %s\n", namedTypeId, mname) - } panic("method not found: '" + methodName + "' in " + namedTypeId) } return method @@ -1419,11 +1396,9 @@ func walkSelectorExpr(e *ast.SelectorExpr, ctx *ir.EvalContext) *ir.MetaSelector func getTypeOfSelector(x ir.MetaExpr, selName string) (types.Type, bool, int, bool) { // (strct).field | (ptr).field | (obj).method - util.Logf("%s: trying getTypeOfSelector (%T).%s\n", Fset.Position(x.Pos()).String(), x, selName) var needDeref bool typeOfX := GetTypeOfExpr(x) utX := typeOfX.Underlying().Underlying() - //util.Logf("utX = %T\n", utX) var structTypeLiteral *types.Struct switch typ := utX.(type) { @@ -2113,9 +2088,9 @@ func Walk(pkg *ir.PkgContainer) *ir.AnalyzedPackage { for _, typeSpec := range typeSpecs { // Register package types + // Underlying type will be attached later t := types.NewNamed(typeSpec.Name.Name, nil) t.PkgName = pkg.Name - util.Logf("NewNamed Pkg type: %s.%s\n", t.PkgName, t.String()) pkgNamedTypes = append(pkgNamedTypes, t) pkgNamedTypesMap[typeSpec.Name.Name] = t // named type @@ -2132,19 +2107,15 @@ func Walk(pkg *ir.PkgContainer) *ir.AnalyzedPackage { var structTypes []*types.Struct for _, typeSpec := range typeSpecs { - util.Logf("typeSpec: %s\n", typeSpec.Name.Name) - spaces = "" ut := E2T(typeSpec.Type) if ut == nil { panic("ut should not be nil") } namedType := pkgNamedTypesMap[typeSpec.Name.Name] namedType.UT = ut - if ut.Underlying() == nil { panic(ut.String() + " Underlying should not be nil") } - spaces = "" switch Kind(ut) { case types.T_STRUCT: //structType := GetUnderlyingType(t) @@ -2357,7 +2328,6 @@ func Walk(pkg *ir.PkgContainer) *ir.AnalyzedPackage { fnc.HasBody = true var ms []ir.MetaStmt for _, stmt := range funcDecl.Body.List { - spaces = "" m := walkStmt(stmt) ms = append(ms, m) } From 6dc8fd0034358d3d6c26bb16eae6377bf693b67d Mon Sep 17 00:00:00 2001 From: DQNEO Date: Tue, 22 Aug 2023 03:22:04 +0900 Subject: [PATCH 08/17] gc --- internal/codegen/codegen.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/codegen/codegen.go b/internal/codegen/codegen.go index fcb954ad..eeeba83d 100644 --- a/internal/codegen/codegen.go +++ b/internal/codegen/codegen.go @@ -523,7 +523,7 @@ func emitCall(fv *ir.FuncValue, args []ir.MetaExpr, paramTypes []types.Type, ret } func emitAllocReturnVarsAreaFF(ff *ir.Func) { - rtypes := (ff.FuncType.Typ.Results.Types) + rtypes := ff.FuncType.Typ.Results.Types emitAllocReturnVarsArea(getTotalSizeOfType(rtypes)) } From 3ed8248bbeb8480ef7f8e6025ecadd373170a53a Mon Sep 17 00:00:00 2001 From: DQNEO Date: Tue, 22 Aug 2023 03:26:30 +0900 Subject: [PATCH 09/17] gc --- internal/codegen/codegen.go | 3 --- internal/sema/sema.go | 11 ----------- 2 files changed, 14 deletions(-) diff --git a/internal/codegen/codegen.go b/internal/codegen/codegen.go index eeeba83d..d299a5f9 100644 --- a/internal/codegen/codegen.go +++ b/internal/codegen/codegen.go @@ -2215,9 +2215,6 @@ func emitInterfaceTables(itab map[string]*sema.ITabEntry) { rcvT = rcvPointerType.Elem() } namedRcvT := rcvT.(*types.Named) - if namedRcvT.String() == "Variable" && namedRcvT.PkgName == "" { - panic("No PkgName in Variable") - } printf(" # Dtype %s.%s \n", namedRcvT.PkgName, namedRcvT.String()) dmethod := sema.LookupMethod(ent.Dtype, m.Name) sym := sema.GetMethodSymbol(dmethod) diff --git a/internal/sema/sema.go b/internal/sema/sema.go index 2b250be9..a5f37926 100644 --- a/internal/sema/sema.go +++ b/internal/sema/sema.go @@ -1367,17 +1367,6 @@ func walkSelectorExpr(e *ast.SelectorExpr, ctx *ir.EvalContext) *ir.MetaSelector } else { // expr.field meta.X = walkExpr(e.X, ctx) - - rcvT := meta.X.GetType() - rcvPointerType, isPtr := rcvT.(*types.Pointer) - if isPtr { - rcvT = rcvPointerType.Elem() - } - namedRcvT, isNamed := rcvT.(*types.Named) - if isNamed && namedRcvT.String() == "Variable" && namedRcvT.PkgName == "" { - panicPos("No PkgName in Variable", e.Pos()) - } - typ, isField, offset, needDeref := getTypeOfSelector(meta.X, e.Sel.Name) if typ == nil { panicPos("Selector type should not be nil", e.Pos()) From 3b7b5e880f4cf2688fb4e464b9693f7752c5d97a Mon Sep 17 00:00:00 2001 From: DQNEO Date: Tue, 22 Aug 2023 03:35:46 +0900 Subject: [PATCH 10/17] Refactor --- internal/ir/ir.go | 2 +- internal/sema/sema.go | 26 +++++++++++++++----------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/internal/ir/ir.go b/internal/ir/ir.go index 3aac33f7..71c42766 100644 --- a/internal/ir/ir.go +++ b/internal/ir/ir.go @@ -451,7 +451,7 @@ type Method struct { RcvNamedType *ast.Ident IsPtrMethod bool Name string - FuncType types.Type + FuncType *types.Func } type Variable struct { diff --git a/internal/sema/sema.go b/internal/sema/sema.go index a5f37926..0c0d11cc 100644 --- a/internal/sema/sema.go +++ b/internal/sema/sema.go @@ -267,6 +267,17 @@ func GetTuple(rhsMeta ir.MetaExpr) *types.Tuple { } } +func CompileFuncType(e *ast.FuncType) *types.Func { + sig := &types.Signature{} + if e.Params != nil { + sig.Params = FieldList2Tuple(e.Params) + } + if e.Results != nil { + sig.Results = FieldList2Tuple(e.Results) + } + return types.NewFunc(sig) +} + func E2T(typeExpr ast.Expr) types.Type { switch t := typeExpr.(type) { case *ast.Ident: @@ -349,14 +360,7 @@ func E2T(typeExpr ast.Expr) types.Type { } return types.NewInterfaceType(methods) case *ast.FuncType: - sig := &types.Signature{} - if t.Params != nil { - sig.Params = FieldList2Tuple(t.Params) - } - if t.Results != nil { - sig.Results = FieldList2Tuple(t.Results) - } - return types.NewFunc(sig) + return CompileFuncType(t) case *ast.ParenExpr: typeExpr = t.X return E2T(typeExpr) @@ -597,7 +601,7 @@ func newMethod(pkgName string, funcDecl *ast.FuncDecl) *ir.Method { RcvNamedType: rcvNamedType, IsPtrMethod: isPtr, Name: funcDecl.Name.Name, - FuncType: E2T(funcDecl.Type), + FuncType: CompileFuncType(funcDecl.Type), } return method } @@ -638,7 +642,7 @@ func LookupMethod(rcvT types.Type, methodName string) *ir.Method { }, IsPtrMethod: false, Name: "Error", - FuncType: E2T(universe.ErrorMethodFuncType), + FuncType: CompileFuncType(universe.ErrorMethodFuncType), } } else { pkgName := typ.PkgName @@ -2116,7 +2120,7 @@ func Walk(pkg *ir.PkgContainer) *ir.AnalyzedPackage { it := typeSpec.Type.(*ast.InterfaceType) if it.Methods != nil { for _, m := range it.Methods.List { - funcType := E2T(m.Type) + funcType := CompileFuncType(m.Type.(*ast.FuncType)) method := &ir.Method{ PkgName: pkg.Name, RcvNamedType: typeSpec.Name, From 7c4241d43e887eff9eab66b85bb66725fe49676a Mon Sep 17 00:00:00 2001 From: DQNEO Date: Tue, 22 Aug 2023 03:44:11 +0900 Subject: [PATCH 11/17] Refactor --- internal/sema/sema.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/internal/sema/sema.go b/internal/sema/sema.go index 0c0d11cc..40fb2e65 100644 --- a/internal/sema/sema.go +++ b/internal/sema/sema.go @@ -350,12 +350,9 @@ func E2T(typeExpr ast.Expr) types.Type { if t.Methods != nil { for _, m := range t.Methods.List { methodName := m.Names[0].Name - t := E2T(m.Type) - f := &types.Func{ - Typ: t.(*types.Func).Typ, - Name: methodName, - } - methods = append(methods, f) + ft := CompileFuncType(m.Type.(*ast.FuncType)) + ft.Name = methodName + methods = append(methods, ft) } } return types.NewInterfaceType(methods) From 640a8158871dcb16233ce18de8ad6c71847262c8 Mon Sep 17 00:00:00 2001 From: DQNEO Date: Tue, 22 Aug 2023 03:46:02 +0900 Subject: [PATCH 12/17] gc --- internal/sema/sema.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/internal/sema/sema.go b/internal/sema/sema.go index 40fb2e65..8499f99d 100644 --- a/internal/sema/sema.go +++ b/internal/sema/sema.go @@ -627,9 +627,6 @@ func LookupMethod(rcvT types.Type, methodName string) *ir.Method { switch typ := rcvT.(type) { case *types.Named: - if typ.PkgName == "fmt" && typ.String() == "Type" { - panic("fmt.Type should not exist") - } if typ.PkgName == "" && typ.String() == "error" { namedTypeId = "error" return &ir.Method{ From 531bf8ade25a31365188821199a28ffff45931bb Mon Sep 17 00:00:00 2001 From: DQNEO Date: Tue, 22 Aug 2023 03:51:43 +0900 Subject: [PATCH 13/17] Refactor --- internal/sema/sema.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/sema/sema.go b/internal/sema/sema.go index 8499f99d..0bdc45c4 100644 --- a/internal/sema/sema.go +++ b/internal/sema/sema.go @@ -2256,7 +2256,7 @@ func Walk(pkg *ir.PkgContainer) *ir.AnalyzedPackage { PkgName: CurrentPkg.Name, Name: funcDecl.Name.Name, Decl: funcDecl, - FuncType: E2T(funcDecl.Type).(*types.Func), + FuncType: CompileFuncType(funcDecl.Type), Localarea: 0, Argsarea: 16, // return address + previous rbp } From 23a60c238ddc8d33349568450da169c76edea40f Mon Sep 17 00:00:00 2001 From: DQNEO Date: Tue, 22 Aug 2023 03:53:05 +0900 Subject: [PATCH 14/17] gc --- internal/sema/sema.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/sema/sema.go b/internal/sema/sema.go index 0bdc45c4..f33a2f23 100644 --- a/internal/sema/sema.go +++ b/internal/sema/sema.go @@ -1413,7 +1413,7 @@ func getTypeOfSelector(x ir.MetaExpr, selName string) (types.Type, bool, int, bo if !structTypeLiteral.IsCalculated { calcStructSizeAndSetFieldOffset(structTypeLiteral) } - //util.Logf("Looking up struct field %T.%s\n", structTypeLiteral, selName) + field := LookupStructField(structTypeLiteral, selName) if field != nil { if field.Offset < 0 { From f80f2fe4d3a2d30f484f537c32e9f3bcc3832809 Mon Sep 17 00:00:00 2001 From: DQNEO Date: Tue, 22 Aug 2023 03:55:03 +0900 Subject: [PATCH 15/17] gc --- internal/sema/sema.go | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/internal/sema/sema.go b/internal/sema/sema.go index f33a2f23..648b69d8 100644 --- a/internal/sema/sema.go +++ b/internal/sema/sema.go @@ -2469,21 +2469,8 @@ func SerializeType(goType types.Type, showOnlyForeignPrefix bool, currentPkgName return "" } -func FuncTypeToSignature(funcType *ast.FuncType) *ir.Signature { - p := FieldList2Types(funcType.Params) - r := FieldList2Types(funcType.Results) - return &ir.Signature{ - ParamTypes: p, - ReturnTypes: r, - } -} - func RestoreMethodDecl(m *types.Func, showOnlyForeignPrefix bool, currentPkgName string) string { name := m.Name - //sig, ok := m.Typ.(*types.Signature) - //if !ok { - // panic(fmt.Sprintf("[SerializeType] Invalid type:%T\n", m.Typ)) - //} sig := m.Typ var p string var r string From ab7d2e02dae8647cf3d6a1a08009bfc064d6e5d0 Mon Sep 17 00:00:00 2001 From: DQNEO Date: Tue, 22 Aug 2023 03:56:47 +0900 Subject: [PATCH 16/17] gc --- internal/types/types.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/internal/types/types.go b/internal/types/types.go index 953b35a6..574bb788 100644 --- a/internal/types/types.go +++ b/internal/types/types.go @@ -216,9 +216,8 @@ type Var struct { } type Struct struct { - Fields []*Var // Fields != nil indicates the struct is set up (possibly with len(Fields) == 0) - //AstFields []*ast.Field // @TODO: Replace this by Fields - IsCalculated bool // the offsets are calculated ? + Fields []*Var // Fields != nil indicates the struct is set up (possibly with len(Fields) == 0) + IsCalculated bool // the offsets of fields are calculated or not } func NewStruct(fields []*Var) *Struct { From 66121d79c64664cbc01be7432f4ae05a559cf2d2 Mon Sep 17 00:00:00 2001 From: DQNEO Date: Tue, 22 Aug 2023 03:57:37 +0900 Subject: [PATCH 17/17] gc --- internal/universe/universe.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/universe/universe.go b/internal/universe/universe.go index 86bbee04..19d7ccba 100644 --- a/internal/universe/universe.go +++ b/internal/universe/universe.go @@ -124,7 +124,7 @@ func CreateUniverse() *ast.Scope { True, False, // types String, Uintptr, Bool, Int, Uint8, Uint16, Int32, Error, - // funcs^ + // funcs New, Make, Append, Len, Cap, Panic, Delete, }