On Fri, Nov 8, 2019 at 10:06 AM André Eriksson <ean...@gmail.com> wrote: > > Interesting. Do you have a reference to where that happens?
The method (*Package).rewriteCall in cmd/cgo/gcc.go. But more useful might be to experiment with some cgo code and build with `go build -work` and look in the $WORK directory to see the generated files. > If i understand you correctly, however, it doesn't appear to solve the case > where the called function fn lives in a different package, and takes an > argument which is a private type. That is: > > -- a/a.go -- > package a > > type myString string > > func Fn(str myString) { } > > -- b/b.go -- > package b > > import "a" > > func rewrite() { > go a.Fn("some string") > } > > In this example knowing the desired type from the function signature does not > help, I would think? That is correct. Fortunately for a case like that you don't need to use a temporary variable at all, since the argument is a constant. Ian > On Friday, November 8, 2019 at 6:58:02 PM UTC+1, Ian Lance Taylor wrote: >> >> On Fri, Nov 8, 2019 at 9:08 AM André Eriksson <ean...@gmail.com> wrote: >> > >> > That works in simple cases, but does not work when the expression is an >> > untyped constant, like 1 or nil. In the case of 1 the variable will get a >> > concrete type of int, while fn may accept a float32, or even a private >> > type that cannot be named in the current package. >> >> You might want to look at the rewriting that cmd/cgo does, as it >> handles this exact kind of case. Basically, for untyped constants, >> you know the desired type, because it's in the function signature. So >> use that. >> >> It does get kind of complicated, though. >> >> Ian >> >> >> > On Friday, November 8, 2019 at 5:51:10 PM UTC+1, Michael Jones wrote: >> >> >> >> If expr was evaluable in the original code then why not rewrite in place >> >> after assigning temporaries? >> >> >> >> go fn(e1,e2) >> >> >> >> { >> >> t1,t2 := e1,e2 >> >> go func() { >> >> defer instrument() >> >> fn(t1,t2) >> >> } >> >> >> >> >> >> On Fri, Nov 8, 2019 at 8:38 AM André Eriksson <ean...@gmail.com> wrote: >> >>> >> >>> I am working on a type of Go preprocessor that rewrites source code to >> >>> add additional instrumentation to certain types of statements. >> >>> >> >>> One such statement is the go statement. I would like to instrument the >> >>> newly created goroutine, injecting some instrumentation code at the >> >>> start and finish of the goroutine. >> >>> >> >>> In the simple case, the rewrite is straightforward: >> >>> >> >>> go fn() >> >>> >> >>> becomes >> >>> >> >>> go func() { >> >>> defer instrument()() >> >>> fn() >> >>> }() >> >>> >> >>> However this approach does not work when fn takes parameters. >> >>> If we were to rewrite go fn(expr) into the equivalent form above: >> >>> >> >>> go func() { >> >>> defer instrument()() >> >>> fn(expr) >> >>> }() >> >>> >> >>> >> >>> the semantics change, since in the rewrite expr gets evaluated inside >> >>> the newly created goroutine, which can change the behavior and introduce >> >>> data races. >> >>> >> >>> My attempts to address this have not been particularly fruitful. >> >>> >> >>> One cannot pass in expr as an argument to the closure, because the type >> >>> of the expression may not have a valid name in the current package (for >> >>> example if expr evaluates to a private type in some other package). >> >>> >> >>> Similarly, if expr is a constant expression (like 1 or nil) the type may >> >>> depend on the corresponding parameter in fn’s signature. >> >>> >> >>> The only semantics-preserving rewrite I can think of revolves around >> >>> using package reflect, and rewriting like so: >> >>> >> >>> go func(fn reflect.Value, vals …reflect.Value) { >> >>> defer instrument() >> >>> fn.Call(vals) >> >>> }(reflect.ValueOf(fn), reflect.ValueOf(expr)) >> >>> >> >>> As far as I understand, this should be semantics-preserving, although >> >>> with a slight performance cost. (Though I imagine the cost of a >> >>> reflection-based call is dwarfed by the cost of spawning a goroutine.) >> >>> >> >>> Unfortunately this also comes with a major downside: the rewritten code >> >>> does not typecheck identically to the original code. Ideally I would >> >>> like the rewritten form to cause identical typechecking failures to the >> >>> old code, so that these errors are caught at compile time without >> >>> requiring a separate typechecking pass for the original code. >> >>> >> >>> Am I correct in the above reasoning? Can anyone think of a way to do >> >>> this sort of rewrite in a semantics-preserving and >> >>> typechecking-preserving way? >> >>> >> >>> -- >> >>> You received this message because you are subscribed to the Google >> >>> Groups "golang-nuts" group. >> >>> To unsubscribe from this group and stop receiving emails from it, send >> >>> an email to golan...@googlegroups.com. >> >>> To view this discussion on the web visit >> >>> https://groups.google.com/d/msgid/golang-nuts/a92641f3-2eda-4d4a-ab02-d2b40e3bde75%40googlegroups.com. >> >> >> >> >> >> >> >> -- >> >> Michael T. Jones >> >> michae...@gmail.com >> > >> > -- >> > You received this message because you are subscribed to the Google Groups >> > "golang-nuts" group. >> > To unsubscribe from this group and stop receiving emails from it, send an >> > email to golan...@googlegroups.com. >> > To view this discussion on the web visit >> > https://groups.google.com/d/msgid/golang-nuts/ec41a345-163f-4a8a-a24f-b868def081a0%40googlegroups.com. > > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/golang-nuts/0ff39043-4699-4f0b-a1c0-6c4ebc5eb208%40googlegroups.com. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAOyqgcVdafpA%2Bp3WPxGGaUF%2BAu%2B0HPQm1Qrw1z3PCwv3FmJ1xg%40mail.gmail.com.