@@ -815,16 +815,21 @@ opswitch:
815
815
case OCONVIFACE :
816
816
n .Left = walkexpr (n .Left , init )
817
817
818
- // Optimize convT2E or convT2I as a two-word copy when T is pointer-shaped.
819
- if isdirectiface ( n . Left . Type ) {
820
- var t * Node
821
- if n . Type . IsEmptyInterface () {
822
- t = typename ( n . Left . Type )
823
- } else {
824
- t = itabname ( n . Left . Type , n . Type )
818
+ fromType := n . Left . Type
819
+ toType := n . Type
820
+
821
+ // typeword generates the type word of the interface value.
822
+ typeword := func () * Node {
823
+ if toType . IsEmptyInterface () {
824
+ return typename ( fromType )
825
825
}
826
- l := nod (OEFACE , t , n .Left )
827
- l .Type = n .Type
826
+ return itabname (fromType , toType )
827
+ }
828
+
829
+ // Optimize convT2E or convT2I as a two-word copy when T is pointer-shaped.
830
+ if isdirectiface (fromType ) {
831
+ l := nod (OEFACE , typeword (), n .Left )
832
+ l .Type = toType
828
833
l .SetTypecheck (n .Typecheck ())
829
834
n = l
830
835
break
@@ -844,35 +849,29 @@ opswitch:
844
849
// or creating one on the stack.
845
850
var value * Node
846
851
switch {
847
- case n . Left . Type .Size () == 0 :
852
+ case fromType .Size () == 0 :
848
853
// n.Left is zero-sized. Use zerobase.
849
854
cheapexpr (n .Left , init ) // Evaluate n.Left for side-effects. See issue 19246.
850
855
value = zerobase
851
- case n . Left . Type . IsBoolean () || (n . Left . Type . Size () == 1 && n . Left . Type .IsInteger ()):
856
+ case fromType . IsBoolean () || (fromType . Size () == 1 && fromType .IsInteger ()):
852
857
// n.Left is a bool/byte. Use staticbytes[n.Left].
853
858
n .Left = cheapexpr (n .Left , init )
854
859
value = nod (OINDEX , staticbytes , byteindex (n .Left ))
855
860
value .SetBounded (true )
856
861
case n .Left .Class () == PEXTERN && n .Left .Name != nil && n .Left .Name .Readonly ():
857
862
// n.Left is a readonly global; use it directly.
858
863
value = n .Left
859
- case ! n . Left . Type . IsInterface () && n .Esc == EscNone && n . Left . Type .Width <= 1024 :
864
+ case ! fromType . IsInterface () && n .Esc == EscNone && fromType .Width <= 1024 :
860
865
// n.Left does not escape. Use a stack temporary initialized to n.Left.
861
- value = temp (n . Left . Type )
866
+ value = temp (fromType )
862
867
init .Append (typecheck (nod (OAS , value , n .Left ), Etop ))
863
868
}
864
869
865
870
if value != nil {
866
871
// Value is identical to n.Left.
867
872
// Construct the interface directly: {type/itab, &value}.
868
- var t * Node
869
- if n .Type .IsEmptyInterface () {
870
- t = typename (n .Left .Type )
871
- } else {
872
- t = itabname (n .Left .Type , n .Type )
873
- }
874
- l := nod (OEFACE , t , typecheck (nod (OADDR , value , nil ), Erv ))
875
- l .Type = n .Type
873
+ l := nod (OEFACE , typeword (), typecheck (nod (OADDR , value , nil ), Erv ))
874
+ l .Type = toType
876
875
l .SetTypecheck (n .Typecheck ())
877
876
n = l
878
877
break
@@ -884,9 +883,9 @@ opswitch:
884
883
// tmp = tmp.type
885
884
// }
886
885
// e = iface{tmp, i.data}
887
- if n . Type . IsEmptyInterface () && n . Left . Type . IsInterface () && ! n . Left . Type .IsEmptyInterface () {
886
+ if toType . IsEmptyInterface () && fromType . IsInterface () && ! fromType .IsEmptyInterface () {
888
887
// Evaluate the input interface.
889
- c := temp (n . Left . Type )
888
+ c := temp (fromType )
890
889
init .Append (nod (OAS , c , n .Left ))
891
890
892
891
// Get the itab out of the interface.
@@ -900,51 +899,41 @@ opswitch:
900
899
901
900
// Build the result.
902
901
e := nod (OEFACE , tmp , ifaceData (c , types .NewPtr (types .Types [TUINT8 ])))
903
- e .Type = n . Type // assign type manually, typecheck doesn't understand OEFACE.
902
+ e .Type = toType // assign type manually, typecheck doesn't understand OEFACE.
904
903
e .SetTypecheck (1 )
905
904
n = e
906
905
break
907
906
}
908
907
909
- fnname , needsaddr := convFuncName (n . Left . Type , n . Type )
908
+ fnname , needsaddr := convFuncName (fromType , toType )
910
909
911
- if ! needsaddr && ! n . Left . Type .IsInterface () {
910
+ if ! needsaddr && ! fromType .IsInterface () {
912
911
// Use a specialized conversion routine that only returns a data pointer.
913
912
// ptr = convT2X(val)
914
913
// e = iface{typ/tab, ptr}
915
914
fn := syslook (fnname )
916
- dowidth (n . Left . Type )
917
- fn = substArgTypes (fn , n . Left . Type )
915
+ dowidth (fromType )
916
+ fn = substArgTypes (fn , fromType )
918
917
dowidth (fn .Type )
919
918
call := nod (OCALL , fn , nil )
920
919
call .List .Set1 (n .Left )
921
920
call = typecheck (call , Erv )
922
921
call = walkexpr (call , init )
923
922
call = safeexpr (call , init )
924
- var tab * Node
925
- if n .Type .IsEmptyInterface () {
926
- tab = typename (n .Left .Type )
927
- } else {
928
- tab = itabname (n .Left .Type , n .Type )
929
- }
930
- e := nod (OEFACE , tab , call )
931
- e .Type = n .Type
923
+ e := nod (OEFACE , typeword (), call )
924
+ e .Type = toType
932
925
e .SetTypecheck (1 )
933
926
n = e
934
927
break
935
928
}
936
929
937
- var ll []* Node
938
- if n .Type .IsEmptyInterface () {
939
- if ! n .Left .Type .IsInterface () {
940
- ll = append (ll , typename (n .Left .Type ))
941
- }
930
+ var tab * Node
931
+ if fromType .IsInterface () {
932
+ // convI2I
933
+ tab = typename (toType )
942
934
} else {
943
- if n .Left .Type .IsInterface () {
944
- ll = append (ll , typename (n .Type ))
945
- } else {
946
- ll = append (ll , itabname (n .Left .Type , n .Type ))
947
- }
935
+ // convT2x
936
+ tab = typeword ()
948
937
}
949
938
950
939
v := n .Left
@@ -960,14 +949,13 @@ opswitch:
960
949
}
961
950
v = nod (OADDR , v , nil )
962
951
}
963
- ll = append (ll , v )
964
952
965
- dowidth (n . Left . Type )
953
+ dowidth (fromType )
966
954
fn := syslook (fnname )
967
- fn = substArgTypes (fn , n . Left . Type , n . Type )
955
+ fn = substArgTypes (fn , fromType , toType )
968
956
dowidth (fn .Type )
969
957
n = nod (OCALL , fn , nil )
970
- n .List .Set ( ll )
958
+ n .List .Set2 ( tab , v )
971
959
n = typecheck (n , Erv )
972
960
n = walkexpr (n , init )
973
961
0 commit comments