Skip to content

Commit

Permalink
Change API of ConvertTypesAcrossModules to make it clearer that old v…
Browse files Browse the repository at this point in the history
…alue gets converted to new type
  • Loading branch information
Anonymous authored and eh-steve committed Jan 2, 2024
1 parent 67105cf commit 9344fa5
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 12 deletions.
15 changes: 7 additions & 8 deletions convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ import (
"unsafe"
)

func CanAttemptConversion(oldValue, newValue interface{}) bool {
func CanAttemptConversion(oldValue interface{}, newType reflect.Type) bool {
oldT := efaceOf(&oldValue)._type
newT := efaceOf(&newValue)._type
newT := fromRType(newType)
seen := map[_typePair]struct{}{}
return typesEqual(oldT, newT, seen)
}

func ConvertTypesAcrossModules(oldModule, newModule *CodeModule, oldValue, newValue interface{}) (res interface{}, err error) {
func ConvertTypesAcrossModules(oldModule, newModule *CodeModule, oldValue interface{}, newType reflect.Type) (res interface{}, err error) {
defer func() {
if v := recover(); v != nil {
err = fmt.Errorf("unexpected panic (this is a bug): %v\n stack trace: %s", v, debug.Stack())
Expand All @@ -35,25 +35,24 @@ func ConvertTypesAcrossModules(oldModule, newModule *CodeModule, oldValue, newVa
// So we need to recurse over the entire structure, and find any itabs and replace them with the equivalent from the new module

oldT := efaceOf(&oldValue)._type
newT := efaceOf(&newValue)._type
newT := fromRType(newType)
seen := map[_typePair]struct{}{}
if !typesEqual(oldT, newT, seen) {
return nil, fmt.Errorf("old type %T and new type %T are not equal", oldValue, newValue)
return nil, fmt.Errorf("old type %T and new type %s are not equal", oldValue, newType)
}

// Need to take data in old value and copy into new value one field at a time, but check that
// the type is either shared (first module) or translated from the old to the new modules
newV := Indirect(ValueOf(&newValue)).Elem()
oldV := Indirect(ValueOf(&oldValue)).Elem()

cycleDetector := map[uintptr]*Value{}
typeHash := make(map[uint32][]*_type, len(newModule.module.typelinks))
buildModuleTypeHash(activeModules()[0], typeHash)
buildModuleTypeHash(newModule.module, typeHash)

cvt(oldModule, newModule, Value{oldV}, newV.Type(), nil, cycleDetector, typeHash)
cvt(oldModule, newModule, Value{oldV}, AsType(newT), nil, cycleDetector, typeHash)

return oldV.ConvertWithInterface(newV.Type()).Interface(), err
return oldV.ConvertWithInterface(AsType(newT)).Interface(), err
}

func toType(t Type) *_type {
Expand Down
8 changes: 4 additions & 4 deletions jit/jit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1053,7 +1053,7 @@ func TestConvertOldAndNewTypes(t *testing.T) {
t.Fatalf("expected current to be the same as input: %d %d", current, input)
}

newThing2, err := goloader.ConvertTypesAcrossModules(module1, module2, thing1, thing2)
newThing2, err := goloader.ConvertTypesAcrossModules(module1, module2, thing1, reflect.TypeOf(thing2))
if err != nil {
t.Fatal(err)
}
Expand All @@ -1072,7 +1072,7 @@ func TestConvertOldAndNewTypes(t *testing.T) {
ifaceCurrentComplex12 := ifaceOut12.Val2["complex"].(map[interface{}]interface{})
_ = thingIface1.Method2(nil)

newThingIface2, err := goloader.ConvertTypesAcrossModules(module1, module2, thingIface1, thingIface2)
newThingIface2, err := goloader.ConvertTypesAcrossModules(module1, module2, thingIface1, reflect.TypeOf(thingIface2))
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -1192,7 +1192,7 @@ func TestStatefulHttpServer(t *testing.T) {
makeHandler2 := symbols2["MakeServer"].(func() http.Handler)
handler2 := makeHandler2()
newHandler, err := goloader.ConvertTypesAcrossModules(module, module2, handler, handler2)
newHandler, err := goloader.ConvertTypesAcrossModules(module, module2, handler, reflect.TypeOf(handler2))
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -1287,7 +1287,7 @@ func TestCloneConnection(t *testing.T) {
t.Fatal(err)
}

newDialer2, err := goloader.ConvertTypesAcrossModules(module1, module2, dialer1, dialer2)
newDialer2, err := goloader.ConvertTypesAcrossModules(module1, module2, dialer1, reflect.TypeOf(dialer2))
if err != nil {
t.Fatal(err)
}
Expand Down

0 comments on commit 9344fa5

Please sign in to comment.