-
Notifications
You must be signed in to change notification settings - Fork 358
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
interp: improve handling of methods defined on interfaces
For methods defined on interfaces (vs concrete methods), the resolution of the method is necessarily delayed at the run time and can not be completed at compile time. The selectorExpr processing has been changed to correctly identify calls on interface methods which were confused as fields rather than methods (due to the fact that in a interface definition, methods are fields of the interface). Then at runtime, method lookup has been fixed to correctly recurse in nested valueInterface wrappers and to find embedded interface fields in case of struct or pointer to struct. Finally, remove receiver processing in `call()`.The receiver is already processed at method resolution and in genFunctionWrapper. Removing redundant processing in call fixes handling of variadic method, simplifies the code and makes it faster. With those fixes, it is now possible to load and run `go.uber.org/zap` in yaegi. In turn, it makes possible for yaegi to run plugins dependent on zap, such as coraza-waf. Fixes #1515, Fixes #1172, Fixes #1275, Fixes #1485.
- Loading branch information
Showing
5 changed files
with
276 additions
and
186 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package main | ||
|
||
type I1 interface { | ||
I2 | ||
Wrap() *S3 | ||
} | ||
|
||
type I2 interface { | ||
F() | ||
} | ||
|
||
type S2 struct { | ||
I2 | ||
} | ||
|
||
func newS2(i2 I2) I1 { | ||
return &S2{i2} | ||
} | ||
|
||
type S3 struct { | ||
base *S2 | ||
} | ||
|
||
func (s *S2) Wrap() *S3 { | ||
i2 := s | ||
return &S3{i2} | ||
} | ||
|
||
type T struct { | ||
name string | ||
} | ||
|
||
func (t *T) F() { println("in F", t.name) } | ||
|
||
func main() { | ||
t := &T{"test"} | ||
s2 := newS2(t) | ||
s3 := s2.Wrap() | ||
s3.base.F() | ||
} | ||
|
||
// Output: | ||
// in F test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.