Before this change, binding unsupported basic types such as
uint failed with an error. Instead, add them to the list of
ignored types so that no error is generated and a comment is
generated explaining why the offending function, constant or
variable was skipped.
Unsigned integers are probably easy to support in ObjC, but
leave them unsupported for now.
While here, improve the printing of the ignored types in the
explaining comments.
Fixesgolang/go#24762
Change-Id: I0d9ab471b2245728270f6ee588f554d4a105d500
Reviewed-on: https://go-review.googlesource.com/105377
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
The gobind and gomobile bind tools have historically overlapped:
gobind outputs generated bindings, and gomobile bind will generate
bindings before building them. However, the gobind bindings were
never used for building and thus allowed to not be complete.
To simplify version control, debugging, instrumentation and build
system flexibility, this CL upgrades the gobind tool to be the
canonical binding generator and change gomobile bind to use gobind
instead of its own generator code.
This greatly simplifies gomobile bind, but also paves the way to skip
gomobile bind entirely. For example:
$ gobind -outdir=$GOPATH golang.org/x/mobile/example/bind/hello
$ GOOS=android GOARCH=arm64 CC=<ndk-toolchain>/bin/clang go build -buildmode=c-shared -o libgobind.so gobind
$ ls libgobind.*
libgobind.h libgobind.so
The same applies to iOS, although the go build command line is more
involved.
By skipping gomobile it is possible to freely customize the Android
or iOS SDK level or any other flags not supported by gomobile bind.
By checking in the generated source code, the cost of supporting
gomobile in a custom build system is also decreased.
Change-Id: I59c14a77d625ac1377c23b3213672e0d83a48c85
Reviewed-on: https://go-review.googlesource.com/99316
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Currently the generated bindings assume that any object
passed to Go as a method argument is actually a valid one
originating from Go. The `null` object is however a corner
case to this assumption, which should be accepted for Go
pointer types, since they can cleanly convert into `nil`.
This CL modifies the generated wrapper code so any `nil`
reference is permitted for Go pointer types, which until
now produced a nil pointer dereference error.
Fixesgolang/go#20330
Change-Id: If1ab9cf9df7ac3808486d23ccf2db8d32fb89426
Reviewed-on: https://go-review.googlesource.com/43253
Reviewed-by: Elias Naur <elias.naur@gmail.com>
Before this CL, using the reverse bindings to access two Java packages
with the same last component would fail with a duplicate package import
error. This CL renames generated import statements to use unique
aliases.
Change-Id: I94696281e58f011f45811445cf81aea02af69c4f
Reviewed-on: https://go-review.googlesource.com/34774
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Accept ObjC API wrapper types as arguments and return values from
bound Go package functions and methods. Also, allow Go structs
to extend ObjC classes and implement ObjC protocols as well as override
and implement methods.
This is the third and final part of the implementation of the golang/go#17102
proposal.
Fixesgolang/go#17102
Change-Id: I601d90fb6d22b8d6f8b7d5fe0130daa1a4dd4734
Reviewed-on: https://go-review.googlesource.com/29175
Reviewed-by: David Crawshaw <crawshaw@golang.org>
The are three generators that currently call this method:
A -> B
(1) go -> java
(2) go -> objective-c
(3) go -> go
As discussed below, we only substitute for invalid unicode characters
in case (1).
**Case 1**
Go:
From golang.org/ref/spec:
Identifiers name program entities such as variables and types.
An identifier is a sequence of one or more letters and digits(unicode_digit).
The first character in an identifier must be a letter(unicode_letter | "_" ).
Java:
From https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.8
`The "Java letters" include uppercase and lowercase ASCII Latin letters
A-Z (\u0041-\u005a), and a-z (\u0061-\u007a), and, for historical reasons,
the ASCII underscore (_, or \u005f) and dollar sign ($, or \u0024). The $
character should be used only in mechanically generated source code or,
rarely, to access pre-existing names on legacy systems.`
Therefore, Go's identifiers are checked in case they break these Java rules.
**Case 2**
There is no objective-c standard specification for valid identifiers.
From some testing it seems that Go and objective-c have identical
valid identifier rules.
**Case 3**
Requires no checking.
Change-Id: I881810eb9355af6a418727ace32cb6ce4266b2a0
Reviewed-on: https://go-review.googlesource.com/14044
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Accept Java API interface types as arguments and return values from
bound Go package functions and methods. Also, allow Go structs
to extend Java classes and implement Java interfaces as well as override
and implement methods.
This is the third and final part of the implementation of the golang/go#16876
proposal.
Fixesgolang/go#16876
Change-Id: I6951dd87235553ce09abe5117a39a503466163c0
Reviewed-on: https://go-review.googlesource.com/28597
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Before this CL, generated Java classes or interfaces were inner
classes to the top package class. That is both unnecessary and creates
ugly class names. Instead, move every generated class and interface to its
own package level class.
NOTE: This is a backwards incompatible change and requires every client
of gomobile APIs to be updated to leave out the package class in the
type names. For example, the Go type
package pkg
type S struct {
}
now generates (with the default java package name go) a Java class named
go.pkg.S. The name before this CL was go.pkg.Pkg.S.
Also, change the custom java package to specify the package prefix and
not the full package as before. This is an unfortunate change needed
to avoid name clashes between two bound packages. On the plus side,
the change brings the custom package case closer to the default behaviour,
which is a commen prefix, "go.", and a distinct java package for every
Go package bound.
Change-Id: Iadfaad56e101d1caf7e2a05006f4d384859a20fe
Reviewed-on: https://go-review.googlesource.com/27436
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Gobind uses strings for passing errors across the language barrier.
However, since Gobind doesn't have a concept of a nil string, it
can't separate an empty native string from a nil string.
In turn, that means that empty errors, exceptions or NSError * with
an empty description are treated as no error. With ObjC, empty errors
are replaced with a default string to workaround the issue, while
with Java empty errors are silently ignored.
Fix this by replacing strings with actual error objects, wrapping
the Go error, Java Throwable or ObjC NSError *, and letting the
existing bind machinery take care of passing the references across.
It's a large change for a small corner case, but I believe objects
are a better fit for exception that strings. Error objects also
naturally leads to future additions, for example accessing the
exception class name or chained exception.
Change-Id: Ie03b47cafcb231ad1e12a80195693fa7459c6265
Reviewed-on: https://go-review.googlesource.com/24100
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Each side of the language barrier maintains a map of reference numbers
to objects. Each entry has a reference count that exactly matches
the number of active proxy objects on the other side. When a reference
crosses the barrier, the count is incremented and when a proxy finalizer
is run, the count is decremented. If the count reaches 0, the reference
number and its object are removed from the map.
There is a possibility that a reference number is passed to the other
side, and the last proxy is then immediately garbage collected and
finalized. The reference counter then reaches 0 before the other side has
converted the reference number to its object, crashing the program.
This is possible in both Go/Java/ObjC but is most likely to happen in
ObjC because its own automatic reference count runtime frees objects
as soon as they are statically never referenced again.
Fix the race by always incrementing the reference count before sending
a reference across the barrier. When converting the reference back into
an object on the other side, decrement the counter again.
Only the new ObjC test fails without this fix, but I left the Java
counterpart in for good measure.
Change-Id: I92743aabec275b4a5b82b952052e7e284872ce02
Reviewed-on: https://go-review.googlesource.com/21311
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
If a method or function refers to a type from an unbound package,
ignore it instead of reporting an error.
Change-Id: I689da63c1a0d1a3aa09220311d871c1f6f66208f
Reviewed-on: https://go-review.googlesource.com/20985
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Rename the refnum field, Num, to something much less likely to clash
with an interface method set.
Change-Id: If334966b2430f38118baded44461bd39298bafb0
Reviewed-on: https://go-review.googlesource.com/20983
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Bind attempts to generate bindings for everything a package exports,
generating an error for what it cannot handle.
For multiple bound packages, unexporting what should not be bound
is sometimes awkward or outright impossible.
Lacking the equivalent of Cgo's //export directory, this CL change
the behaviour of bind to simply ignore everything it can't generate
bindings for, even if otherwise exported. For every declaration it
ignores, a comment is generated instead, to help any confusion as
to why a particular export was not included.
Change-Id: I2c7a5bee0f19a58009293b4e5ac2c95687e62e80
Reviewed-on: https://go-review.googlesource.com/20651
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
ToRefNum only handles Go objects, but it can be passed foreign object
proxies as well. Add a check whether the object is a proxy, and if so,
simply return its refnum and don't track it.
Change-Id: Ib17bd11b48e472c3bec0e5fb06661b201c3dfa97
Reviewed-on: https://go-review.googlesource.com/20681
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Multiple packages are already supported, but only as if each packages
were bound in isolation. This CL lets a bound package refer to other
bound packages in its exported functions, types and fields.
In Java, the JNI class jclass and constructor jmethodID are exported
so other packages can construct proxies of other packages' interfaces.
In ObjC, the class @interface declarations are moved from the package
.m file to its .h file to allow other packages to constructs its
interface proxies.
Add a supporting test package, secondpkg, and add Java and ObjC tests
for the new cross package functionality. Also add simplepkg for
testing corner cases where the generated Go file must not include its
bound package.
While we're here, stop generating Go proxy types for struct types;
only Go interfaces can be implemented in the foreign language.
Change-Id: Icbfa739c893703867d38a9100ed0928fbd7a660d
Reviewed-on: https://go-review.googlesource.com/20575
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Converting a Go string to a string suitable use a specialized function,
UTF16Encode, that can encode the string directly to a malloc'ed buffer. That
way, only two copies are made when strings are passed from Go to Java; once
for UTF-8 to UTF-16 encoding and once for the creation of the Java String.
This CL implements the same optimization in the other direction, with a
UTF-16 to UTF-8 decoder implemented in C. Unfortunately, while calling into a
Go decoder also saves the extra copy, the Cgo overhead makes the calls much
slower for short strings.
To alleviate the risk of introducing decoding bugs, I've added the tests from
the encoding/utf16 package to SeqTest.
As a sideeffect, both Java and ObjC now always copy strings, regardless of
the argument mode. The cpy argument can therefore be removed from the string
conversion functions. Furthermore, the modeRetained and modeReturned modes
can be collapsed into just one.
While we're here, delete a leftover function from seq/strings.go that
wasn't removed when the old seq buffers went away.
Benchmarks, as compared with benchstat over 5 runs:
name old time/op new time/op delta
JavaStringShort 11.4µs ±13% 11.6µs ± 4% ~ (p=0.859 n=10+5)
JavaStringShortDirect 19.5µs ± 9% 20.3µs ± 2% +3.68% (p=0.019 n=9+5)
JavaStringLong 103µs ± 8% 24µs ± 4% -77.13% (p=0.001 n=9+5)
JavaStringLongDirect 113µs ± 9% 32µs ± 7% -71.63% (p=0.001 n=9+5)
JavaStringShortUnicode 11.1µs ±16% 10.7µs ± 5% ~ (p=0.190 n=9+5)
JavaStringShortUnicodeDirect 19.6µs ± 7% 20.2µs ± 1% +2.78% (p=0.029 n=9+5)
JavaStringLongUnicode 97.1µs ± 9% 28.0µs ± 5% -71.17% (p=0.001 n=9+5)
JavaStringLongUnicodeDirect 105µs ±10% 34µs ± 5% -67.23% (p=0.002 n=8+5)
JavaStringRetShort 14.2µs ± 2% 13.9µs ± 1% -2.15% (p=0.006 n=8+5)
JavaStringRetShortDirect 20.8µs ± 2% 20.4µs ± 2% ~ (p=0.065 n=8+5)
JavaStringRetLong 42.2µs ± 9% 42.4µs ± 3% ~ (p=0.190 n=9+5)
JavaStringRetLongDirect 51.2µs ±21% 50.8µs ± 8% ~ (p=0.518 n=9+5)
GoStringShort 23.4µs ± 7% 22.5µs ± 3% -3.55% (p=0.019 n=9+5)
GoStringLong 51.9µs ± 9% 53.1µs ± 3% ~ (p=0.240 n=9+5)
GoStringShortUnicode 24.2µs ± 6% 22.8µs ± 1% -5.54% (p=0.002 n=9+5)
GoStringLongUnicode 58.6µs ± 8% 57.6µs ± 3% ~ (p=0.518 n=9+5)
GoStringRetShort 27.6µs ± 1% 23.2µs ± 2% -15.87% (p=0.003 n=7+5)
GoStringRetLong 129µs ±12% 33µs ± 2% -74.03% (p=0.001 n=10+5)
Change-Id: Icb9481981493ffca8defed9fb80a9433d6048937
Reviewed-on: https://go-review.googlesource.com/20250
Reviewed-by: David Crawshaw <crawshaw@golang.org>
The seq serialization machinery is a historic artifact from when Go
mobile code had to run in a separate process. Now that Go code is running
in-process, replace the explicit serialization with direct calls and pass
arguments on the stack.
The benefits are a much smaller bind runtime, much less garbage (and, in
Java, fewer objects with finalizers), less argument copying, and faster
cross-language calls.
The cost is a more complex generator, because some of the work from the
bind runtime is moved to generated code. Generated code now handles
conversion between Go and Java/ObjC types, multiple return values and memory
management of byte slice and string arguments.
To overcome the lack of calling C code between Go packages, all bound
packages now end up in the same (fake) package, "gomobile_bind", instead of
separate packages (go_<pkgname>). To avoid name clashes, the package name is
added as a prefix to generated functions and types.
Also, don't copy byte arrays passed to Go, saving call time and
allowing read([]byte)-style interfaces to foreign callers (#12113).
Finally, add support for nil interfaces and struct pointers to objc.
This is a large CL, but most of the changes stem from changing testdata.
The full benchcmp output on the CL/20095 benchmarks on my Nexus 5 is
reproduced below. Note that the savings for the JavaSlice* benchmarks are
skewed because byte slices are no longer copied before passing them to Go.
benchmark old ns/op new ns/op delta
BenchmarkJavaEmpty 26.0 19.0 -26.92%
BenchmarkJavaEmptyDirect 23.0 22.0 -4.35%
BenchmarkJavaNoargs 7685 2339 -69.56%
BenchmarkJavaNoargsDirect 17405 8041 -53.80%
BenchmarkJavaOnearg 26887 2366 -91.20%
BenchmarkJavaOneargDirect 34266 7910 -76.92%
BenchmarkJavaOneret 38325 2245 -94.14%
BenchmarkJavaOneretDirect 46265 7708 -83.34%
BenchmarkJavaManyargs 41720 2535 -93.92%
BenchmarkJavaManyargsDirect 51026 8373 -83.59%
BenchmarkJavaRefjava 38139 21260 -44.26%
BenchmarkJavaRefjavaDirect 42706 28150 -34.08%
BenchmarkJavaRefgo 34403 6843 -80.11%
BenchmarkJavaRefgoDirect 40193 16582 -58.74%
BenchmarkJavaStringShort 32366 9323 -71.20%
BenchmarkJavaStringShortDirect 41973 19118 -54.45%
BenchmarkJavaStringLong 127879 94420 -26.16%
BenchmarkJavaStringLongDirect 133776 114760 -14.21%
BenchmarkJavaStringShortUnicode 32562 9221 -71.68%
BenchmarkJavaStringShortUnicodeDirect 41464 19094 -53.95%
BenchmarkJavaStringLongUnicode 131015 89401 -31.76%
BenchmarkJavaStringLongUnicodeDirect 134130 90786 -32.31%
BenchmarkJavaSliceShort 42462 7538 -82.25%
BenchmarkJavaSliceShortDirect 52940 17017 -67.86%
BenchmarkJavaSliceLong 138391 8466 -93.88%
BenchmarkJavaSliceLongDirect 205804 15666 -92.39%
BenchmarkGoEmpty 3.00 3.00 +0.00%
BenchmarkGoEmptyDirect 3.00 3.00 +0.00%
BenchmarkGoNoarg 40342 13716 -66.00%
BenchmarkGoNoargDirect 46691 13569 -70.94%
BenchmarkGoOnearg 43529 13757 -68.40%
BenchmarkGoOneargDirect 44867 14078 -68.62%
BenchmarkGoOneret 45456 13559 -70.17%
BenchmarkGoOneretDirect 44694 13442 -69.92%
BenchmarkGoRefjava 55111 28071 -49.06%
BenchmarkGoRefjavaDirect 60883 26872 -55.86%
BenchmarkGoRefgo 57038 29223 -48.77%
BenchmarkGoRefgoDirect 56153 27812 -50.47%
BenchmarkGoManyargs 67967 17398 -74.40%
BenchmarkGoManyargsDirect 60617 16998 -71.96%
BenchmarkGoStringShort 57538 22600 -60.72%
BenchmarkGoStringShortDirect 52627 22704 -56.86%
BenchmarkGoStringLong 128485 52530 -59.12%
BenchmarkGoStringLongDirect 138377 52079 -62.36%
BenchmarkGoStringShortUnicode 57062 22994 -59.70%
BenchmarkGoStringShortUnicodeDirect 62563 22938 -63.34%
BenchmarkGoStringLongUnicode 139913 55553 -60.29%
BenchmarkGoStringLongUnicodeDirect 150863 57791 -61.69%
BenchmarkGoSliceShort 59279 20215 -65.90%
BenchmarkGoSliceShortDirect 60160 21136 -64.87%
BenchmarkGoSliceLong 411225 301870 -26.59%
BenchmarkGoSliceLongDirect 399029 298915 -25.09%
Fixesgolang/go#12619Fixesgolang/go#12113Fixesgolang/go#13033
Change-Id: I2b45e9e98a1248e3c23a5137f775f7364908bec7
Reviewed-on: https://go-review.googlesource.com/19821
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Avoid taking a good name (seq) away from users.
Fixesgolang/go#14168
Change-Id: I88e90cb74b479e348c642a1caa27096ed4a6d68e
Reviewed-on: https://go-review.googlesource.com/19601
Reviewed-by: David Crawshaw <crawshaw@golang.org>
The Seq Java class has a special case for null references. Expand
the special case to Go so that null references from Java are properly
translated to nil.
Fixesgolang/go#14228
Change-Id: I915d1f843c9db299d6910480f6d10dae0121a3b4
Reviewed-on: https://go-review.googlesource.com/19460
Reviewed-by: David Crawshaw <crawshaw@golang.org>
error message example:
gomobile: unsupported named type github.com/sridharv/bugreports/typealiasmissing.Alias
Objective-C and Java generation code currently panics, which need to be
fixed separately. (See TODO in bind/seq.go)
Fixesgolang/go#13190
Change-Id: Ie46dc58ea800522b8ab7cb8ac662ad561e0ca82e
Reviewed-on: https://go-review.googlesource.com/16780
Reviewed-by: Burcu Dogan <jbd@google.com>
This breaks our dependency on the x/tools repository, which has a
tendency to change in unexpected ways. It also means we can use the
version of go/types that ships with Go 1.5.
Along the way, it appears that cgo processing has changed slightly.
The old check for cgo files apparently wasn't working, so I removed
it.
Change-Id: I14378e9df9cd65c5ab61b47728ba0d56f31cdf76
Reviewed-on: https://go-review.googlesource.com/12680
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
seq.Transact is called when Go calls a method of a foreign object
that implements a Go interface. Currently, we assume that the foreign
object has an instance method that can conduct the message routing,
so the object id and the method code is sufficient for transact.
Passing the interface descriptor (e.g. go.testpkg.I) however allows
the bind internal to use non-instance methods to implement the routing.
Change-Id: I1f61a04f919fbd09117ea332d678cd50e4861e46
Reviewed-on: https://go-review.googlesource.com/12685
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Also fixes a parameter name handling problem when processing a
function signature that omits parameter names.
Fixesgolang/go#10788.
Change-Id: I65273d330bbf3a836ec9e4ffb691927970d795d8
Reviewed-on: https://go-review.googlesource.com/9926
Reviewed-by: Alan Donovan <adonovan@google.com>
This is to enable more flexible encoding/decoding of Go string.
For Java, we use UTF16 to be compatible with java string.
For other languages, we will want other way to represent a string.
Change-Id: Iccd53e2eea18d37636c3c619d06cb473facef0cd
Reviewed-on: https://go-review.googlesource.com/8628
Reviewed-by: David Crawshaw <crawshaw@golang.org>
This change makes gobind to generate proper Go-side proxy code to
handle interface methods that have parameters and return values.
It allows gobind to accept struct pointer types as parameters
or a return value of a method.
Fixesgolang/go#9487, golang/go#9488.
Change-Id: Id243c42ee0701d40e3871e392140368c2f8f9bc6
Reviewed-on: https://go-review.googlesource.com/2348
Reviewed-by: David Crawshaw <crawshaw@golang.org>