Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
a6ba5ec5
Commit
a6ba5ec5
authored
May 07, 2009
by
Russ Cox
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
6g: new interface rules (code got simpler!)
R=ken OCL=28374 CL=28378
parent
d76f0957
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
121 additions
and
178 deletions
+121
-178
dcl.c
src/cmd/gc/dcl.c
+1
-2
go.h
src/cmd/gc/go.h
+1
-6
obj.c
src/cmd/gc/obj.c
+38
-43
subr.c
src/cmd/gc/subr.c
+73
-119
walk.c
src/cmd/gc/walk.c
+8
-8
No files found.
src/cmd/gc/dcl.c
View file @
a6ba5ec5
...
@@ -129,7 +129,6 @@ updatetype(Type *n, Type *t)
...
@@ -129,7 +129,6 @@ updatetype(Type *n, Type *t)
n
->
sym
=
s
;
n
->
sym
=
s
;
n
->
local
=
local
;
n
->
local
=
local
;
n
->
siggen
=
0
;
n
->
siggen
=
0
;
n
->
methptr
=
0
;
n
->
printed
=
0
;
n
->
printed
=
0
;
n
->
method
=
nil
;
n
->
method
=
nil
;
n
->
vargen
=
0
;
n
->
vargen
=
0
;
...
@@ -293,7 +292,7 @@ addmethod(Node *n, Type *t, int local)
...
@@ -293,7 +292,7 @@ addmethod(Node *n, Type *t, int local)
if
(
pa
==
T
)
if
(
pa
==
T
)
goto
bad
;
goto
bad
;
f
=
dclmethod
(
pa
);
f
=
methtype
(
pa
);
if
(
f
==
T
)
if
(
f
==
T
)
goto
bad
;
goto
bad
;
...
...
src/cmd/gc/go.h
View file @
a6ba5ec5
...
@@ -137,7 +137,6 @@ struct Type
...
@@ -137,7 +137,6 @@ struct Type
uchar
chan
;
uchar
chan
;
uchar
recur
;
// to detect loops
uchar
recur
;
// to detect loops
uchar
trecur
;
// to detect loops
uchar
trecur
;
// to detect loops
uchar
methptr
;
// 1=direct 2=pointer
uchar
printed
;
uchar
printed
;
uchar
embedded
;
// TFIELD embedded type
uchar
embedded
;
// TFIELD embedded type
uchar
siggen
;
uchar
siggen
;
...
@@ -725,9 +724,7 @@ int isinter(Type*);
...
@@ -725,9 +724,7 @@ int isinter(Type*);
int
isnilinter
(
Type
*
);
int
isnilinter
(
Type
*
);
int
isddd
(
Type
*
);
int
isddd
(
Type
*
);
Type
*
maptype
(
Type
*
,
Type
*
);
Type
*
maptype
(
Type
*
,
Type
*
);
Type
*
dclmethod
(
Type
*
);
Type
*
methtype
(
Type
*
);
Type
*
methtype
(
Type
*
);
int
methconv
(
Type
*
);
Sym
*
signame
(
Type
*
);
Sym
*
signame
(
Type
*
);
int
eqtype
(
Type
*
,
Type
*
,
int
);
int
eqtype
(
Type
*
,
Type
*
,
int
);
int
eqtypenoname
(
Type
*
,
Type
*
);
int
eqtypenoname
(
Type
*
,
Type
*
);
...
@@ -787,10 +784,8 @@ int lookdot0(Sym*, Type*, Type**);
...
@@ -787,10 +784,8 @@ int lookdot0(Sym*, Type*, Type**);
Type
*
lookdot1
(
Sym
*
,
Type
*
,
Type
*
);
Type
*
lookdot1
(
Sym
*
,
Type
*
,
Type
*
);
int
adddot1
(
Sym
*
,
Type
*
,
int
,
Type
**
);
int
adddot1
(
Sym
*
,
Type
*
,
int
,
Type
**
);
Node
*
adddot
(
Node
*
);
Node
*
adddot
(
Node
*
);
void
expand0
(
Type
*
);
void
expand1
(
Type
*
,
int
);
void
expandmeth
(
Sym
*
,
Type
*
);
void
expandmeth
(
Sym
*
,
Type
*
);
void
gen
ptrtramp
(
Sym
*
,
Sym
*
,
Type
*
,
Type
*
,
Sym
*
,
Type
*
);
void
gen
wrapper
(
Type
*
,
Type
*
,
Sym
*
);
/*
/*
* dcl.c
* dcl.c
...
...
src/cmd/gc/obj.c
View file @
a6ba5ec5
...
@@ -140,6 +140,12 @@ ieeedtod(uint64 *ieee, double native)
...
@@ -140,6 +140,12 @@ ieeedtod(uint64 *ieee, double native)
*
ieee
=
((
uint64
)
h
<<
32
)
|
l
;
*
ieee
=
((
uint64
)
h
<<
32
)
|
l
;
}
}
static
int
sigcmp
(
Sig
*
a
,
Sig
*
b
)
{
return
strcmp
(
a
->
name
,
b
->
name
);
}
/*
/*
* Add DATA for signature s.
* Add DATA for signature s.
* progt - type in program
* progt - type in program
...
@@ -165,13 +171,6 @@ ieeedtod(uint64 *ieee, double native)
...
@@ -165,13 +171,6 @@ ieeedtod(uint64 *ieee, double native)
* } meth[1]; // one or more - last name is nil
* } meth[1]; // one or more - last name is nil
* };
* };
*/
*/
static
int
sigcmp
(
Sig
*
a
,
Sig
*
b
)
{
return
strcmp
(
a
->
name
,
b
->
name
);
}
void
void
dumpsigt
(
Type
*
progt
,
Type
*
ifacet
,
Type
*
rcvrt
,
Type
*
methodt
,
Sym
*
s
)
dumpsigt
(
Type
*
progt
,
Type
*
ifacet
,
Type
*
rcvrt
,
Type
*
methodt
,
Sym
*
s
)
{
{
...
@@ -180,12 +179,16 @@ dumpsigt(Type *progt, Type *ifacet, Type *rcvrt, Type *methodt, Sym *s)
...
@@ -180,12 +179,16 @@ dumpsigt(Type *progt, Type *ifacet, Type *rcvrt, Type *methodt, Sym *s)
Sig
*
a
,
*
b
;
Sig
*
a
,
*
b
;
char
buf
[
NSYMB
];
char
buf
[
NSYMB
];
Type
*
this
;
Type
*
this
;
Iter
savet
;
Prog
*
oldlist
;
Prog
*
oldlist
;
Sym
*
method
;
Sym
*
method
;
uint32
sighash
;
uint32
sighash
;
int
ot
;
int
ot
;
if
(
debug
[
'r'
])
{
print
(
"dumpsigt progt=%T ifacet=%T rcvrt=%T methodt=%T s=%S
\n
"
,
progt
,
ifacet
,
rcvrt
,
methodt
,
s
);
}
a
=
nil
;
a
=
nil
;
o
=
0
;
o
=
0
;
oldlist
=
nil
;
oldlist
=
nil
;
...
@@ -201,6 +204,16 @@ dumpsigt(Type *progt, Type *ifacet, Type *rcvrt, Type *methodt, Sym *s)
...
@@ -201,6 +204,16 @@ dumpsigt(Type *progt, Type *ifacet, Type *rcvrt, Type *methodt, Sym *s)
if
(
method
==
nil
)
if
(
method
==
nil
)
continue
;
continue
;
// get receiver type for this particular method.
this
=
getthisx
(
f
->
type
)
->
type
->
type
;
if
(
f
->
embedded
!=
2
&&
isptr
[
this
->
etype
]
&&
!
isptr
[
progt
->
etype
])
{
// pointer receiver method but value method set.
// ignore.
if
(
debug
[
'r'
])
print
(
"ignore %T for %T
\n
"
,
f
,
progt
);
continue
;
}
b
=
mal
(
sizeof
(
*
b
));
b
=
mal
(
sizeof
(
*
b
));
b
->
link
=
a
;
b
->
link
=
a
;
a
=
b
;
a
=
b
;
...
@@ -216,31 +229,19 @@ dumpsigt(Type *progt, Type *ifacet, Type *rcvrt, Type *methodt, Sym *s)
...
@@ -216,31 +229,19 @@ dumpsigt(Type *progt, Type *ifacet, Type *rcvrt, Type *methodt, Sym *s)
if
(
!
a
->
sym
->
siggen
)
{
if
(
!
a
->
sym
->
siggen
)
{
a
->
sym
->
siggen
=
1
;
a
->
sym
->
siggen
=
1
;
// TODO(rsc): This test is still not quite right.
this
=
structfirst
(
&
savet
,
getthis
(
f
->
type
))
->
type
;
if
(
!
eqtype
(
this
,
ifacet
,
0
))
{
if
(
isptr
[
this
->
etype
]
!=
isptr
[
ifacet
->
etype
])
{
if
(
oldlist
==
nil
)
if
(
oldlist
==
nil
)
oldlist
=
pc
;
oldlist
=
pc
;
// indirect vs direct mismatch
// It would be okay to call genwrapper here always,
Sym
*
oldname
,
*
newname
;
// but we can generate more efficient code
Type
*
oldthis
,
*
newthis
;
// using genembedtramp if all that is necessary
// is a pointer adjustment and a JMP.
newthis
=
ifacet
;
if
(
f
->
embedded
&&
isptr
[
ifacet
->
etype
])
if
(
isptr
[
newthis
->
etype
])
oldthis
=
ifacet
->
type
;
else
oldthis
=
ptrto
(
ifacet
);
newname
=
a
->
sym
;
oldname
=
methodsym
(
method
,
oldthis
);
genptrtramp
(
method
,
oldname
,
oldthis
,
f
->
type
,
newname
,
newthis
);
}
else
if
(
f
->
embedded
)
{
// TODO(rsc): only works for pointer receivers
if
(
oldlist
==
nil
)
oldlist
=
pc
;
genembedtramp
(
ifacet
,
a
);
genembedtramp
(
ifacet
,
a
);
else
genwrapper
(
ifacet
,
f
,
a
->
sym
);
}
}
}
}
o
++
;
o
++
;
...
@@ -449,23 +450,17 @@ dumpsignatures(void)
...
@@ -449,23 +450,17 @@ dumpsignatures(void)
rcvrt
=
t
;
rcvrt
=
t
;
// if there's a pointer, methods are on base.
// if there's a pointer, methods are on base.
if
(
isptr
[
methodt
->
etype
]
&&
methodt
->
type
->
sym
!=
S
)
{
methodt
=
methtype
(
progt
);
methodt
=
methodt
->
type
;
if
(
methodt
==
T
)
{
// if that failed, go back to progt,
// assuming we're writing out a signature
// for a type with no methods
methodt
=
progt
;
}
else
{
expandmeth
(
methodt
->
sym
,
methodt
);
expandmeth
(
methodt
->
sym
,
methodt
);
// if methodt had a name, we don't want to see
// it in the method names that go into the sigt.
// e.g., if
// type item *rat
// then item needs its own sigt distinct from *rat,
// but it needs to have all of *rat's methods, using
// the *rat (not item) in the method names.
if
(
rcvrt
->
sym
!=
S
)
rcvrt
=
ptrto
(
methodt
);
}
}
// and if ifacet is too wide, the methods
// if ifacet is too wide, the methods will see a pointer.
// will see a pointer anyway.
if
(
ifacet
->
width
>
8
)
{
if
(
ifacet
->
width
>
8
)
{
ifacet
=
ptrto
(
progt
);
ifacet
=
ptrto
(
progt
);
rcvrt
=
ptrto
(
progt
);
rcvrt
=
ptrto
(
progt
);
...
@@ -473,7 +468,7 @@ dumpsignatures(void)
...
@@ -473,7 +468,7 @@ dumpsignatures(void)
// don't emit non-trivial signatures for types defined outside this file.
// don't emit non-trivial signatures for types defined outside this file.
// non-trivial signatures might also drag in generated trampolines,
// non-trivial signatures might also drag in generated trampolines,
// and ar can't handle duplicate
s of the trampoline
s.
// and ar can't handle duplicate
function
s.
// only pay attention to types with symbols, because
// only pay attention to types with symbols, because
// the ... structs and maybe other internal structs
// the ... structs and maybe other internal structs
// don't get marked as local.
// don't get marked as local.
...
...
src/cmd/gc/subr.c
View file @
a6ba5ec5
...
@@ -1495,7 +1495,7 @@ isddd(Type *t)
...
@@ -1495,7 +1495,7 @@ isddd(Type *t)
* return type to hang methods off (r).
* return type to hang methods off (r).
*/
*/
Type
*
Type
*
dclmethod
(
Type
*
t
)
methtype
(
Type
*
t
)
{
{
int
ptr
;
int
ptr
;
...
@@ -1517,15 +1517,6 @@ dclmethod(Type *t)
...
@@ -1517,15 +1517,6 @@ dclmethod(Type *t)
if
(
t
->
sym
==
S
)
if
(
t
->
sym
==
S
)
return
T
;
return
T
;
// check that all method receivers are consistent
if
(
t
->
methptr
!=
0
&&
t
->
methptr
!=
(
1
<<
ptr
))
{
if
(
t
->
methptr
!=
3
)
{
t
->
methptr
=
3
;
yyerror
(
"methods on both %T and *%T"
,
t
,
t
);
}
}
t
->
methptr
|=
1
<<
ptr
;
// check types
// check types
if
(
!
issimple
[
t
->
etype
])
if
(
!
issimple
[
t
->
etype
])
switch
(
t
->
etype
)
{
switch
(
t
->
etype
)
{
...
@@ -1543,50 +1534,6 @@ dclmethod(Type *t)
...
@@ -1543,50 +1534,6 @@ dclmethod(Type *t)
return
t
;
return
t
;
}
}
/*
* this is dclmethod() without side effects.
*/
Type
*
methtype
(
Type
*
t
)
{
if
(
t
==
T
)
return
T
;
if
(
isptr
[
t
->
etype
])
{
if
(
t
->
sym
!=
S
)
return
T
;
t
=
t
->
type
;
}
if
(
t
==
T
||
t
->
etype
==
TINTER
||
t
->
sym
==
S
)
return
T
;
return
t
;
}
/*
* given type t in a method call, returns op
* to convert t into appropriate receiver.
* returns OADDR if t==x and method takes *x
* returns OIND if t==*x and method takes x
*/
int
methconv
(
Type
*
t
)
{
Type
*
m
;
m
=
methtype
(
t
);
if
(
m
==
T
)
return
0
;
if
(
m
->
methptr
&
2
)
{
// want pointer
if
(
t
==
m
)
return
OADDR
;
return
0
;
}
// want non-pointer
if
(
t
!=
m
)
return
OIND
;
return
0
;
}
int
int
iscomposite
(
Type
*
t
)
iscomposite
(
Type
*
t
)
{
{
...
@@ -2604,19 +2551,22 @@ struct Symlink
...
@@ -2604,19 +2551,22 @@ struct Symlink
{
{
Type
*
field
;
Type
*
field
;
uchar
good
;
uchar
good
;
uchar
followptr
;
Symlink
*
link
;
Symlink
*
link
;
};
};
static
Symlink
*
slist
;
static
Symlink
*
slist
;
void
static
void
expand0
(
Type
*
t
)
expand0
(
Type
*
t
,
int
followptr
)
{
{
Type
*
f
,
*
u
;
Type
*
f
,
*
u
;
Symlink
*
sl
;
Symlink
*
sl
;
u
=
t
;
u
=
t
;
if
(
isptr
[
u
->
etype
])
if
(
isptr
[
u
->
etype
])
{
followptr
=
1
;
u
=
u
->
type
;
u
=
u
->
type
;
}
u
=
methtype
(
t
);
u
=
methtype
(
t
);
if
(
u
!=
T
)
{
if
(
u
!=
T
)
{
...
@@ -2629,13 +2579,14 @@ expand0(Type *t)
...
@@ -2629,13 +2579,14 @@ expand0(Type *t)
sl
=
mal
(
sizeof
(
*
sl
));
sl
=
mal
(
sizeof
(
*
sl
));
sl
->
field
=
f
;
sl
->
field
=
f
;
sl
->
link
=
slist
;
sl
->
link
=
slist
;
sl
->
followptr
=
followptr
;
slist
=
sl
;
slist
=
sl
;
}
}
}
}
}
}
void
static
void
expand1
(
Type
*
t
,
int
d
)
expand1
(
Type
*
t
,
int
d
,
int
followptr
)
{
{
Type
*
f
,
*
u
;
Type
*
f
,
*
u
;
...
@@ -2646,11 +2597,13 @@ expand1(Type *t, int d)
...
@@ -2646,11 +2597,13 @@ expand1(Type *t, int d)
t
->
trecur
=
1
;
t
->
trecur
=
1
;
if
(
d
!=
nelem
(
dotlist
)
-
1
)
if
(
d
!=
nelem
(
dotlist
)
-
1
)
expand0
(
t
);
expand0
(
t
,
followptr
);
u
=
t
;
u
=
t
;
if
(
isptr
[
u
->
etype
])
if
(
isptr
[
u
->
etype
])
{
followptr
=
1
;
u
=
u
->
type
;
u
=
u
->
type
;
}
if
(
u
->
etype
!=
TSTRUCT
&&
u
->
etype
!=
TINTER
)
if
(
u
->
etype
!=
TSTRUCT
&&
u
->
etype
!=
TINTER
)
goto
out
;
goto
out
;
...
@@ -2659,7 +2612,7 @@ expand1(Type *t, int d)
...
@@ -2659,7 +2612,7 @@ expand1(Type *t, int d)
continue
;
continue
;
if
(
f
->
sym
==
S
)
if
(
f
->
sym
==
S
)
continue
;
continue
;
expand1
(
f
->
type
,
d
-
1
);
expand1
(
f
->
type
,
d
-
1
,
followptr
);
}
}
out:
out:
...
@@ -2682,7 +2635,7 @@ expandmeth(Sym *s, Type *t)
...
@@ -2682,7 +2635,7 @@ expandmeth(Sym *s, Type *t)
// generate all reachable methods
// generate all reachable methods
slist
=
nil
;
slist
=
nil
;
expand1
(
t
,
nelem
(
dotlist
)
-
1
);
expand1
(
t
,
nelem
(
dotlist
)
-
1
,
0
);
// check each method to be uniquely reachable
// check each method to be uniquely reachable
for
(
sl
=
slist
;
sl
!=
nil
;
sl
=
sl
->
link
)
{
for
(
sl
=
slist
;
sl
!=
nil
;
sl
=
sl
->
link
)
{
...
@@ -2704,7 +2657,8 @@ expandmeth(Sym *s, Type *t)
...
@@ -2704,7 +2657,8 @@ expandmeth(Sym *s, Type *t)
f
=
typ
(
TFIELD
);
f
=
typ
(
TFIELD
);
*
f
=
*
sl
->
field
;
*
f
=
*
sl
->
field
;
f
->
embedded
=
1
;
// needs a trampoline
f
->
embedded
=
1
;
// needs a trampoline
if
(
sl
->
followptr
)
f
->
embedded
=
2
;
f
->
down
=
t
->
method
;
f
->
down
=
t
->
method
;
t
->
method
=
f
;
t
->
method
=
f
;
...
@@ -2742,43 +2696,46 @@ structargs(Type **tl, int mustname)
...
@@ -2742,43 +2696,46 @@ structargs(Type **tl, int mustname)
}
}
/*
/*
* Generate a trampoline to convert
* Generate a wrapper function to convert from
* from an indirect receiver to a direct receiver
* a receiver of type T to a receiver of type U.
* or vice versa.
* That is,
*
* func (t T) M() {
* ...
* }
*
* already exists; this function generates
*
* func (u U) M() {
* u.M()
* }
*
*
* method - short name of method (Len)
* where the types T and U are such that u.M() is valid
* oldname - old mangled method name (x·y·Len)
* and calls the T.M method.
* oldthis - old this type (y)
* The resulting function is for use in method tables.
* oldtype - type of method being called;
*
* only in and out params are known okay,
* rcvrtype - U
* receiver might be != oldthis.
* method - M func (t T)(), a TFIELD type struct
* newnam [sic] - new mangled method name (x·*y·Len)
* newnam - the eventual mangled name of this function
* newthis - new this type (*y)
*/
*/
void
void
gen
ptrtramp
(
Sym
*
method
,
Sym
*
oldname
,
Type
*
oldthis
,
Type
*
oldtype
,
Sym
*
newnam
,
Type
*
newthis
)
gen
wrapper
(
Type
*
rcvrtype
,
Type
*
method
,
Sym
*
newnam
)
{
{
Node
*
fn
,
*
args
,
*
l
,
*
in
,
*
call
,
*
out
,
*
this
,
*
rcvr
,
*
meth
;
Node
*
this
,
*
in
,
*
out
,
*
fn
,
*
args
,
*
call
;
Node
*
l
;
Iter
savel
;
Iter
savel
;
if
(
debug
[
'r'
])
{
if
(
debug
[
'r'
])
{
print
(
"
\n
genptrtramp method=%S oldname=%S oldthis=%T
\n
"
,
print
(
"genwrapper rcvrtype=%T method=%T newnam=%S
\n
"
,
method
,
oldname
,
oldthis
);
rcvrtype
,
method
,
newnam
);
print
(
"
\t
oldtype=%T newnam=%S newthis=%T
\n
"
,
oldtype
,
newnam
,
newthis
);
}
}
dclcontext
=
PEXTERN
;
dclcontext
=
PEXTERN
;
markdcl
();
markdcl
();
this
=
nametodcl
(
newname
(
lookup
(
".this"
)),
newthis
);
this
=
nametodcl
(
newname
(
lookup
(
".this"
)),
rcvrtype
);
in
=
structargs
(
getinarg
(
oldtype
),
1
);
in
=
structargs
(
getinarg
(
method
->
type
),
1
);
out
=
structargs
(
getoutarg
(
oldtype
),
0
);
out
=
structargs
(
getoutarg
(
method
->
type
),
0
);
// fix up oldtype
markdcl
();
oldtype
=
functype
(
nametodcl
(
newname
(
lookup
(
".this"
)),
oldthis
),
in
,
out
);
popdcl
();
fn
=
nod
(
ODCLFUNC
,
N
,
N
);
fn
=
nod
(
ODCLFUNC
,
N
,
N
);
fn
->
nname
=
newname
(
newnam
);
fn
->
nname
=
newname
(
newnam
);
...
@@ -2791,19 +2748,10 @@ genptrtramp(Sym *method, Sym *oldname, Type *oldthis, Type *oldtype, Sym *newnam
...
@@ -2791,19 +2748,10 @@ genptrtramp(Sym *method, Sym *oldname, Type *oldthis, Type *oldtype, Sym *newnam
args
=
list
(
args
,
l
->
left
);
args
=
list
(
args
,
l
->
left
);
args
=
rev
(
args
);
args
=
rev
(
args
);
// method to call
// generate call
if
(
isptr
[
oldthis
->
etype
])
call
=
nod
(
OCALL
,
adddot
(
nod
(
ODOT
,
this
->
left
,
newname
(
method
->
sym
))),
args
);
rcvr
=
nod
(
OADDR
,
this
->
left
,
N
);
else
rcvr
=
nod
(
OIND
,
this
->
left
,
N
);
gettype
(
rcvr
,
N
);
meth
=
nod
(
ODOTMETH
,
rcvr
,
newname
(
oldname
));
meth
->
xoffset
=
BADWIDTH
;
// TODO(rsc): necessary?
meth
->
type
=
oldtype
;
call
=
nod
(
OCALL
,
meth
,
args
);
fn
->
nbody
=
call
;
fn
->
nbody
=
call
;
if
(
old
type
->
outtuple
>
0
)
if
(
method
->
type
->
outtuple
>
0
)
fn
->
nbody
=
nod
(
ORETURN
,
call
,
N
);
fn
->
nbody
=
nod
(
ORETURN
,
call
,
N
);
if
(
debug
[
'r'
])
if
(
debug
[
'r'
])
...
@@ -2850,11 +2798,13 @@ ifacecheck(Type *dst, Type *src, int lineno, int explicit)
...
@@ -2850,11 +2798,13 @@ ifacecheck(Type *dst, Type *src, int lineno, int explicit)
}
}
Type
*
Type
*
ifacelookdot
(
Sym
*
s
,
Type
*
t
)
ifacelookdot
(
Sym
*
s
,
Type
*
t
,
int
*
followptr
)
{
{
int
c
,
d
;
int
i
,
c
,
d
;
Type
*
m
;
Type
*
m
;
*
followptr
=
0
;
if
(
t
==
T
)
if
(
t
==
T
)
return
T
;
return
T
;
...
@@ -2864,9 +2814,16 @@ ifacelookdot(Sym *s, Type *t)
...
@@ -2864,9 +2814,16 @@ ifacelookdot(Sym *s, Type *t)
yyerror
(
"%T.%S is ambiguous"
,
t
,
s
);
yyerror
(
"%T.%S is ambiguous"
,
t
,
s
);
return
T
;
return
T
;
}
}
if
(
c
==
1
)
if
(
c
==
1
)
{
for
(
i
=
0
;
i
<
d
;
i
++
)
{
if
(
isptr
[
dotlist
[
i
].
field
->
type
->
etype
])
{
*
followptr
=
1
;
break
;
}
}
return
m
;
return
m
;
}
}
}
return
T
;
return
T
;
}
}
...
@@ -2875,23 +2832,11 @@ ifacelookdot(Sym *s, Type *t)
...
@@ -2875,23 +2832,11 @@ ifacelookdot(Sym *s, Type *t)
int
int
ifaceokT2I
(
Type
*
t0
,
Type
*
iface
,
Type
**
m
)
ifaceokT2I
(
Type
*
t0
,
Type
*
iface
,
Type
**
m
)
{
{
Type
*
t
,
*
im
,
*
tm
;
Type
*
t
,
*
im
,
*
tm
,
*
rcvr
;
int
imhash
;
int
imhash
,
followptr
;
t
=
methtype
(
t0
);
t
=
methtype
(
t0
);
// stopgap: check for
// non-pointer type in T2I, methods want pointers.
// supposed to do something better eventually
// but this will catch errors while we decide the
// details of the "better" solution.
// only warn if iface is not interface{}.
if
(
t
==
t0
&&
t
->
methptr
==
2
&&
iface
->
type
!=
T
)
{
yyerror
(
"probably wanted *%T not %T"
,
t
,
t
);
*
m
=
iface
->
type
;
return
0
;
}
// if this is too slow,
// if this is too slow,
// could sort these first
// could sort these first
// and then do one loop.
// and then do one loop.
...
@@ -2905,11 +2850,20 @@ ifaceokT2I(Type *t0, Type *iface, Type **m)
...
@@ -2905,11 +2850,20 @@ ifaceokT2I(Type *t0, Type *iface, Type **m)
for
(
im
=
iface
->
type
;
im
;
im
=
im
->
down
)
{
for
(
im
=
iface
->
type
;
im
;
im
=
im
->
down
)
{
imhash
=
typehash
(
im
,
0
,
0
);
imhash
=
typehash
(
im
,
0
,
0
);
tm
=
ifacelookdot
(
im
->
sym
,
t
);
tm
=
ifacelookdot
(
im
->
sym
,
t
,
&
followptr
);
if
(
tm
==
T
||
typehash
(
tm
,
0
,
0
)
!=
imhash
)
{
if
(
tm
==
T
||
typehash
(
tm
,
0
,
0
)
!=
imhash
)
{
*
m
=
im
;
*
m
=
im
;
return
0
;
return
0
;
}
}
// if pointer receiver in method,
// the method does not exist for value types.
rcvr
=
getthisx
(
tm
->
type
)
->
type
->
type
;
if
(
isptr
[
rcvr
->
etype
]
&&
!
isptr
[
t0
->
etype
]
&&
!
followptr
)
{
if
(
debug
[
'r'
])
yyerror
(
"interface pointer mismatch"
);
*
m
=
im
;
return
0
;
}
}
}
return
1
;
return
1
;
}
}
...
...
src/cmd/gc/walk.c
View file @
a6ba5ec5
...
@@ -1590,8 +1590,7 @@ lookdot1(Sym *s, Type *t, Type *f)
...
@@ -1590,8 +1590,7 @@ lookdot1(Sym *s, Type *t, Type *f)
int
int
lookdot
(
Node
*
n
,
Type
*
t
)
lookdot
(
Node
*
n
,
Type
*
t
)
{
{
Type
*
f1
,
*
f2
,
*
tt
;
Type
*
f1
,
*
f2
,
*
tt
,
*
rcvr
;
int
op
;
Sym
*
s
;
Sym
*
s
;
s
=
n
->
right
->
sym
;
s
=
n
->
right
->
sym
;
...
@@ -1618,18 +1617,19 @@ lookdot(Node *n, Type *t)
...
@@ -1618,18 +1617,19 @@ lookdot(Node *n, Type *t)
if
(
f2
!=
T
)
{
if
(
f2
!=
T
)
{
tt
=
n
->
left
->
type
;
tt
=
n
->
left
->
type
;
if
((
op
=
methconv
(
tt
))
!=
0
)
{
rcvr
=
getthisx
(
f2
->
type
)
->
type
->
type
;
switch
(
op
)
{
if
(
!
eqtype
(
rcvr
,
tt
,
0
)
)
{
case
OADDR
:
if
(
rcvr
->
etype
==
tptr
&&
eqtype
(
rcvr
->
type
,
tt
,
0
))
{
walktype
(
n
->
left
,
Elv
);
walktype
(
n
->
left
,
Elv
);
addrescapes
(
n
->
left
);
addrescapes
(
n
->
left
);
n
->
left
=
nod
(
OADDR
,
n
->
left
,
N
);
n
->
left
=
nod
(
OADDR
,
n
->
left
,
N
);
n
->
left
->
type
=
ptrto
(
tt
);
n
->
left
->
type
=
ptrto
(
tt
);
break
;
}
else
if
(
tt
->
etype
==
tptr
&&
eqtype
(
tt
->
type
,
rcvr
,
0
))
{
case
OIND
:
n
->
left
=
nod
(
OIND
,
n
->
left
,
N
);
n
->
left
=
nod
(
OIND
,
n
->
left
,
N
);
n
->
left
->
type
=
tt
->
type
;
n
->
left
->
type
=
tt
->
type
;
break
;
}
else
{
// method is attached to wrong type?
fatal
(
"method mismatch: %T for %T"
,
rcvr
,
tt
);
}
}
}
}
n
->
right
=
methodname
(
n
->
right
,
n
->
left
->
type
);
n
->
right
=
methodname
(
n
->
right
,
n
->
left
->
type
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment