This is the ObjC equiivalent to CL 30276. It expands support for
implicit `self` parameters to every exported method.
Change-Id: Iff8a956b38448213866a93dc02ca59cac592feef
Reviewed-on: https://go-review.googlesource.com/30277
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>
Using the new ObjC type analyzer API, scan the bound packages for
references to ObjC classes and protocols and generate Go wrappers for them.
This is the second part of the implementation of proposal golang/go#17102.
For golang/go#17102
Change-Id: I773db7b0362a7ff526d0a0fd6da5b2fa33301144
Reviewed-on: https://go-review.googlesource.com/29174
Reviewed-by: David Crawshaw <crawshaw@golang.org>
CL 24800 changed the error representation from strings to objects.
However, since native errors types are not immediately compatible
across languages, wrapper types were introduced to bridge the gap.
This CL remove those wrappers and instead special case the error
proxy types to conform to their language error protocol.
Specifically:
- The ObjC proxy for Go errors now extends NSError and calls
initWithDomain to store the error message.
- The Go proxy for ObjC NSError return the localizedDescription
property for calls to Error.
- The Java proxy for Go errors ow extends Exception and
overrides getMessage() to return the error message.
- The Go proxy for Java Exceptions returns getMessage whenever
Error is called.
The end result is that error values behave more like normal objects
across the language boundary. In particular, instance identity is
now preserved: an error passed across the boundary and back will
result in the same instance.
There are two semantic changes that followed this change:
- The domain for wrapped Go errors is now always "go".
The domain wasn't useful before this CL: the domains were set to
the package name of function or method where the error happened
to cross the language boundary.
- If a Go method that returns an error is implemented in ObjC, the
implementation must now both return NO _and_ set the error result
for the calling Go code to receive a non-nil error.
Before this CL, because errors were always wrapped, a nil ObjC
could be represented with a non-nil wrapper.
Change-Id: Idb415b6b13ecf79ccceb60f675059942bfc48fec
Reviewed-on: https://go-review.googlesource.com/29298
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Errors was recently converted to use objects as representation instead
of strings. Issue golang/go#17073 exposed a few places that wasn't properly
updated. Fix them and add the test case from the the issue.
Fixesgolang/go#17073
Change-Id: I0191993a8427d930540716407fc09032f282fc66
Reviewed-on: https://go-review.googlesource.com/29176
Reviewed-by: David Crawshaw <crawshaw@golang.org>
CL 24792 changed Go's int type to be represented in ObjC as long.
Change SeqTest.m accordingly.
Change-Id: Ifd34787db713444fc729b497ed72b62688384bc8
Reviewed-on: https://go-review.googlesource.com/28591
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>
Warnings used to be invisible when running SeqTest.m through
go test. Treat warnings as errors and fix a bug that surfaced.
Change-Id: I81e7291635824cdb4a898c91db740f7aa10f3611
Reviewed-on: https://go-review.googlesource.com/21133
Reviewed-by: David Crawshaw <crawshaw@golang.org>
The objc reference handling has bug on assigning different refnum
to the same ios object. The reason for this is that the
RefTracker _refs is not properly initialized thus incorrect
reference check in assignRefnumAndIncRefcount.
Change-Id: Id86423dcf378d11e9056bf7c7ecb646333a94a04
Reviewed-on: https://go-review.googlesource.com/21120
Reviewed-by: Elias Naur <elias.naur@gmail.com>
An extra struct initializer was left over from an earlier version
of the direct call conversion. Remove it.
Change-Id: I19c3eb3be7bf78378af47ea182931b0c24cdd34d
Reviewed-on: https://go-review.googlesource.com/21104
Reviewed-by: David Crawshaw <crawshaw@golang.org>
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>
It was generated once per bound package before, but since it is
constant it belongs in seq.h.
Change-Id: I7d920e8e87ce11cc9ae5e5e410dd935bc6e53480
Reviewed-on: https://go-review.googlesource.com/20657
Reviewed-by: David Crawshaw <crawshaw@golang.org>
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>
Also, upgrade the android plugin version used for java/seq_test
from 1.2.3 to 1.5.0
For golang/go#9603
Change-Id: I7b465ff0e607319a08150c4405675832d91edc1e
Reviewed-on: https://go-review.googlesource.com/20411
Reviewed-by: Elias Naur <elias.naur@gmail.com>
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Currently there is a Go test package for each platform, iOS and
Android. This CL merges them into a single, shared package. Apart
from the reduced code duplication, the merger stops the tests
diverging further. Most importantly, one shared package clarifies
that the intent of gobind is that the same Go package can be
reused across platforms.
This CL only merges the obvious test duplicates. The rest have been
copied from the ObjC package into the Android test under different
names.
While we're here, demote the long string test to the basictypes
bind test; the test never had a runtime part.
Change-Id: I7838b16999968fae7b012016a5b5f6bb80f94023
Reviewed-on: https://go-review.googlesource.com/20300
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Add a XCTestCase based ObjC driver, SeqTest.m, to run the benchmarks
package on iOS.
While we're here, replace "Java" with "Foreign" in test names to
reflect that benchmarks run on both platforms now.
Change-Id: I38a38f3093b4b97961107b5ea66f03cff8e395c3
Reviewed-on: https://go-review.googlesource.com/20259
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Replace test.bash with go test that builds and run the bind tests
through the XCode testing framework.
Running on the iOS emulator unmasked a bug where autorelease pools
were not in place for Go calls into ObjC, leaking autoreleased
objects. Fix that by adding autoreleasepool blocks to the tracker
finalizer callback and to every generated ObjC proxy.
Will not run on the emulator without CL 19206.
Change-Id: I6a775f9995f3b8ea50272982069d033e41ddcb7b
Reviewed-on: https://go-review.googlesource.com/20255
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
LOG_FATAL already throws an exception on iOS. Make it abort() on
Android, so that any fatal error will hopefully end up with a useful
log instead of an easily missed message in logcat.
Also, remove return statements after LOG_FATAL on both platforms.
They're unnecessary and confusing and they weren't used consistently
anyway.
Change-Id: I2a8e2e0ac064e95f52ca130de17265c9741cefe4
Reviewed-on: https://go-review.googlesource.com/20257
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
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>
for example,
package testpkg
var AnInt int64
will be mapped to
@interface GoTestpkg: NSObject
+ (int64_t) AnInt;
+ (void) setAnInt:(int64_t)v;
@end
Followup of cl/15340
Update golang/go#12475
Change-Id: Ie26c92af977fc3dd62dcad2b10c6a5c1c1b8941b
Reviewed-on: https://go-review.googlesource.com/15770
Reviewed-by: David Crawshaw <crawshaw@golang.org>
A framework generated with gomobile bind -target=ios has two global
constructors: one initializing a data structure and another using it.
These constructors are defined in different translation units, which
(I believe, reasoning from C++ global constructors) means their order
of initialization is undefined.
A capturing block is stack allocated. Its memory is invalid after the
function returns. Make a copy of the interface initializer blocks so
they can be saved to the heap.
Block implementation background:
http://www.cocoawithlove.com/2009/10/how-blocks-are-implemented-and.html
Updates golang/go#12590
Change-Id: Ia7ae9f4bbd8df6e6e79949de54b3e6c48148c700
Reviewed-on: https://go-review.googlesource.com/14549
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Given a Go package defining an interface,
package testpkg
type I interface {
Fn()
}
I is mapped to an objective-c protocol and a proxy interface
that implements the routing of method calls from Go.
@protocol GoTestpkgI
-(void)Fn;
@end
Users implement a class conforming the generated protocol. For example,
@interface MyI <GoTestpkgI> {
}
@end
@implementation MyI {
}
- (void)Fn { .... }
@end
Gobind will also create a proxy interface to handle Go objects
implementing the interface and passed to Objective-C, but that will
be hidden from users.
@interface GoTestpkgI : NSObject <GoTestpkgI> {
...
-(void)Fn;
@end
The gobind code to generate the objective-c binding is in a separate CL.
Change-Id: I6a72d34fe3a5b8d2774d2d53913229c1e71f2d60
Reviewed-on: https://go-review.googlesource.com/12389
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
Also, fixes the memory allocation bug - misuse of mem_ensure that caused
to allocate 72 bytes of memory to carry 16 bytes of data for instance.
Fixesgolang/go#11842.
Change-Id: I21798be2ec7adfb68cc2897bb46a924f05f3478c
Reviewed-on: https://go-review.googlesource.com/12577
Reviewed-by: David Crawshaw <crawshaw@golang.org>
This allows gomobile bind to stop copying seq.h to the destination.
Change-Id: I4a23613fe0407500ad483ae9d8f6bb823d82f082
Reviewed-on: https://go-review.googlesource.com/12300
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Before this change, func Hello() of mypkg package generated a function
GoMypkg_Hello to distinguish the prefix from the function name.
It seems the use of '_' is very rare in Objective-C though.
After this change, it generates GoMypkgHello.
Change-Id: Ic7aa2b667363a447a5ff3500262502d3137d6853
Reviewed-on: https://go-review.googlesource.com/11893
Reviewed-by: Damien Neil <dneil@google.com>
The existing implementation generates uncompilable objc code for
functions returning two results.
Change-Id: I13f7329596d8fa6103c4b7827c26c5461e16a925
Reviewed-on: https://go-review.googlesource.com/11364
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
With https://go-review.googlesource.com/10638, the reference counting
of Go objects can be simplified. Everytime a Go object is passed into
Objective-C side, a new proxy object with GoSeqRef is created.
Deallocation of a GoSeqRef decrements the reference counter of the
corresponding Go object.
Test the Go object is collected.
Note: It's possible to reduce the number of GoSeqRef
allocations by maintaining a map of weak references to the existing
GoSeqRef, but for now, we allocate a new GoSeqRef instance.
Change-Id: I57a5a4b249c5800d9eba95d128a2cdf74bbef566
Reviewed-on: https://go-review.googlesource.com/10639
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
test.bash is a simple script that builds the c-shared library from
test_main.go, compiles SeqTest.m and the objective-c bindings of testpkg
(testpkg/objc_testpkg/GoTestpkg.*), and runs the output. Eventually this
will be replaced with coed that runs gomobile bind & xcodebuild.
The code under testpkg/go_testpkg and testpkg/objc_testpkg is the output
of gobind (now manually-generated). I am adding it to repo now in order
to get the testpkg/objc_tstpkg reviewed. Eventually, this will be
removed from the repo.
Change-Id: I8d6af3732337992af922cb4615a63f385e19d489
Reviewed-on: https://go-review.googlesource.com/9826
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
duplicate code from bind/java/seq_android.c to use for obj-c/go binding.
Change-Id: Iefd5d4171cca3a30c5d56f9b37647463e6fd0c5a
Reviewed-on: https://go-review.googlesource.com/9409
Reviewed-by: David Crawshaw <crawshaw@golang.org>