2
0
mirror of synced 2025-02-23 23:08:14 +00:00

13 Commits

Author SHA1 Message Date
Elias Naur
89b8360218 bind: remove error wrappers to preserve error instance identity
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>
2016-10-04 09:11:42 +00:00
Elias Naur
a3e0621280 mobile/bind: use objects to pass errors across the language barrier
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>
2016-06-23 18:55:48 +00:00
Elias Naur
07a529f836 mobile/bind: fix a reference count race with the garbage collectors
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>
2016-03-30 18:24:55 +00:00
Elias Naur
51fe33c7bf mobile/bind: don't generate goSeqRefInterface
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>
2016-03-14 13:45:40 +00:00
Elias Naur
6fca37c69e mobile/bind: replace seq serialization with direct calls
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%

Fixes golang/go#12619
Fixes golang/go#12113
Fixes golang/go#13033

Change-Id: I2b45e9e98a1248e3c23a5137f775f7364908bec7
Reviewed-on: https://go-review.googlesource.com/19821
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
2016-03-03 15:03:45 +00:00
Hyang-Ah (Hana) Kim
926122382b bind/objc: Interface binding support
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>
2015-07-31 20:12:03 +00:00
Hyang-Ah (Hana) Kim
343eae7dd2 bind/objc: simplify reference counting of Go objects.
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>
2015-06-04 23:02:01 +00:00
Hyang-Ah (Hana) Kim
b24fa8f869 bind/objc: add read/write Int and BOOL values.
Change-Id: I9e1d0c62acfa43cfc1b0dd79ff25b89b43a891cb
Reviewed-on: https://go-review.googlesource.com/10710
Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-06-04 20:31:20 +00:00
Hyang-Ah (Hana) Kim
a7e5f659df bind/objc: allow passing Go objects to objective-C.
Change-Id: I2aa3971cd8800485f2934d5efb89cea8042e7d88
Reviewed-on: https://go-review.googlesource.com/10632
Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-06-02 16:03:04 +00:00
Hyang-Ah (Hana) Kim
6e800237e4 bind/objc: simplify GoSeq.
Change-Id: I86e5409d5e09794108cdf5ef1b4c80155d8874cf
Reviewed-on: https://go-review.googlesource.com/10049
Reviewed-by: Damien Neil <dneil@google.com>
2015-05-14 22:26:19 +00:00
Hyang-Ah (Hana) Kim
fd342d15ab bind/objc: implement byte array read/write support.
Change-Id: I01ff7369c653bc7d57a3357c8f936d30ca5c0beb
Reviewed-on: https://go-review.googlesource.com/9922
Reviewed-by: Damien Neil <dneil@google.com>
2015-05-13 22:32:52 +00:00
Hyang-Ah (Hana) Kim
5c3e18f08f bind/objc: obj-c binding for functions using numeric, string types.
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>
2015-05-13 22:28:22 +00:00
Hyang-Ah (Hana) Kim
812950cfd1 bind/objc: GoSeq for obj-c and go communication.
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>
2015-05-01 19:28:10 +00:00