2015-05-05 15:57:36 -04:00
|
|
|
// Copyright 2015 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
// +build ignore
|
|
|
|
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
#import "GoTestpkg.h"
|
|
|
|
|
|
|
|
#define ERROR(...) \
|
|
|
|
do { \
|
|
|
|
NSLog(__VA_ARGS__); \
|
|
|
|
err = 1; \
|
|
|
|
} while (0);
|
|
|
|
|
|
|
|
static int err = 0;
|
|
|
|
|
2015-09-28 15:08:01 -04:00
|
|
|
void testConst() {
|
|
|
|
if (![GoTestpkgAString isEqualToString:@"a string"]) {
|
|
|
|
ERROR(@"GoTestpkgAString = %@, want 'a string'", GoTestpkgAString);
|
|
|
|
}
|
|
|
|
if (GoTestpkgAnInt != 7) {
|
|
|
|
ERROR(@"GoTestpkgAnInt = %lld, want 7", GoTestpkgAnInt);
|
|
|
|
}
|
|
|
|
if (ABS(GoTestpkgAFloat - 0.12345) > 0.0001) {
|
|
|
|
ERROR(@"GoTestpkgAFloat = %f, want 0.12345", GoTestpkgAFloat);
|
|
|
|
}
|
|
|
|
if (GoTestpkgABool != YES) {
|
|
|
|
ERROR(@"GoTestpkgABool = %@, want YES", GoTestpkgAFloat ? @"YES" : @"NO");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GoTestpkgMinInt32 != INT32_MIN) {
|
|
|
|
ERROR(@"GoTestpkgMinInt32 = %d, want %d", GoTestpkgMinInt32, INT32_MIN);
|
|
|
|
}
|
|
|
|
if (GoTestpkgMaxInt32 != INT32_MAX) {
|
|
|
|
ERROR(@"GoTestpkgMaxInt32 = %d, want %d", GoTestpkgMaxInt32, INT32_MAX);
|
|
|
|
}
|
|
|
|
if (GoTestpkgMinInt64 != INT64_MIN) {
|
|
|
|
ERROR(@"GoTestpkgMinInt64 = %lld, want %lld", GoTestpkgMinInt64, INT64_MIN);
|
|
|
|
}
|
|
|
|
if (GoTestpkgMaxInt64 != INT64_MAX) {
|
|
|
|
ERROR(@"GoTestpkgMaxInt64 = %lld, want %lld", GoTestpkgMaxInt64, INT64_MAX);
|
|
|
|
}
|
|
|
|
if (ABS(GoTestpkgSmallestNonzeroFloat64 -
|
|
|
|
4.940656458412465441765687928682213723651e-324) > 1e-323) {
|
|
|
|
ERROR(@"GoTestpkgSmallestNonzeroFloat64 = %f, want %f",
|
|
|
|
GoTestpkgSmallestNonzeroFloat64,
|
|
|
|
4.940656458412465441765687928682213723651e-324);
|
|
|
|
}
|
|
|
|
if (ABS(GoTestpkgMaxFloat64 -
|
|
|
|
1.797693134862315708145274237317043567981e+308) > 0.0001) {
|
|
|
|
ERROR(@"GoTestpkgMaxFloat64 = %f, want %f", GoTestpkgMaxFloat64,
|
|
|
|
1.797693134862315708145274237317043567981e+308);
|
|
|
|
}
|
|
|
|
if (ABS(GoTestpkgSmallestNonzeroFloat32 -
|
|
|
|
1.401298464324817070923729583289916131280e-45) > 1e-44) {
|
|
|
|
ERROR(@"GoTestpkgSmallestNonzeroFloat32 = %f, want %f",
|
|
|
|
GoTestpkgSmallestNonzeroFloat32,
|
|
|
|
1.401298464324817070923729583289916131280e-45);
|
|
|
|
}
|
|
|
|
if (ABS(GoTestpkgMaxFloat32 - 3.40282346638528859811704183484516925440e+38) >
|
|
|
|
0.0001) {
|
|
|
|
ERROR(@"GoTestpkgMaxFloat32 = %f, want %f", GoTestpkgMaxFloat32,
|
|
|
|
3.40282346638528859811704183484516925440e+38);
|
|
|
|
}
|
|
|
|
if (ABS(GoTestpkgLog2E -
|
|
|
|
1 / 0.693147180559945309417232121458176568075500134360255254120680009) >
|
|
|
|
0.0001) {
|
|
|
|
ERROR(
|
|
|
|
@"GoTestpkgLog2E = %f, want %f", GoTestpkgLog2E,
|
|
|
|
1 / 0.693147180559945309417232121458176568075500134360255254120680009);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-05 15:57:36 -04:00
|
|
|
void testHello(NSString *input) {
|
2015-07-06 11:55:50 -04:00
|
|
|
NSString *got = GoTestpkgHello(input);
|
2015-05-05 15:57:36 -04:00
|
|
|
NSString *want = [NSString stringWithFormat:@"Hello, %@!", input];
|
|
|
|
if (!got) {
|
2015-07-06 11:55:50 -04:00
|
|
|
ERROR(@"GoTestpkgHello(%@)= NULL, want %@", input, want);
|
2015-05-05 15:57:36 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (![got isEqualToString:want]) {
|
2015-07-06 11:55:50 -04:00
|
|
|
ERROR(@"want %@\nGoTestpkgHello(%@)= %@", want, input, got);
|
2015-05-05 15:57:36 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-28 15:14:06 -04:00
|
|
|
void testString() {
|
|
|
|
NSString *input = @"";
|
|
|
|
NSString *got = GoTestpkgEcho(input);
|
|
|
|
if (!got || ![got isEqualToString:input]) {
|
|
|
|
ERROR(@"want %@\nGoTestpkgEcho(%@)= %@", input, input, got);
|
|
|
|
}
|
|
|
|
|
|
|
|
input = @"FOO";
|
|
|
|
got = GoTestpkgEcho(input);
|
|
|
|
if (!got || ![got isEqualToString:input]) {
|
|
|
|
ERROR(@"want %@\nGoTestpkgEcho(%@)= %@", input, input, got);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-11 16:25:42 -04:00
|
|
|
void testBytesAppend(NSString *a, NSString *b) {
|
|
|
|
NSData *data_a = [a dataUsingEncoding:NSUTF8StringEncoding];
|
|
|
|
NSData *data_b = [b dataUsingEncoding:NSUTF8StringEncoding];
|
2015-07-06 11:55:50 -04:00
|
|
|
NSData *gotData = GoTestpkgBytesAppend(data_a, data_b);
|
2015-05-11 16:25:42 -04:00
|
|
|
NSString *got =
|
|
|
|
[[NSString alloc] initWithData:gotData encoding:NSUTF8StringEncoding];
|
|
|
|
NSString *want = [a stringByAppendingString:b];
|
|
|
|
if (![got isEqualToString:want]) {
|
2015-07-06 11:55:50 -04:00
|
|
|
ERROR(@"want %@\nGoTestpkgBytesAppend(%@, %@) = %@", want, a, b, got);
|
2015-05-11 16:25:42 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-23 15:11:37 -04:00
|
|
|
void testReturnsError() {
|
|
|
|
NSString *value;
|
|
|
|
NSError *error;
|
2015-07-06 11:55:50 -04:00
|
|
|
GoTestpkgReturnsError(TRUE, &value, &error);
|
2015-06-23 15:11:37 -04:00
|
|
|
NSString *got = [error.userInfo valueForKey:NSLocalizedDescriptionKey];
|
|
|
|
NSString *want = @"Error";
|
|
|
|
if (![got isEqualToString:want]) {
|
2015-07-06 11:55:50 -04:00
|
|
|
ERROR(@"want %@\nGoTestpkgReturnsError(TRUE) = (%@, %@)", want, value, got);
|
2015-06-23 15:11:37 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-02 09:36:44 -04:00
|
|
|
void testStruct() {
|
2015-07-06 11:55:50 -04:00
|
|
|
GoTestpkgS *s = GoTestpkgNewS(10.0, 100.0);
|
2015-06-02 09:36:44 -04:00
|
|
|
if (!s) {
|
2015-07-06 11:55:50 -04:00
|
|
|
ERROR(@"GoTestpkgNewS returned NULL");
|
2015-06-02 09:36:44 -04:00
|
|
|
}
|
2015-06-04 14:56:48 -04:00
|
|
|
|
2015-10-12 15:50:24 -04:00
|
|
|
double x = [s x];
|
|
|
|
double y = [s y];
|
|
|
|
double sum = [s sum];
|
2015-06-02 09:36:44 -04:00
|
|
|
if (x != 10.0 || y != 100.0 || sum != 110.0) {
|
2015-07-23 13:06:27 -04:00
|
|
|
ERROR(@"GoTestpkgS(10.0, 100.0).X=%f Y=%f SUM=%f; want 10, 100, 110", x, y,
|
|
|
|
sum);
|
2015-06-02 09:36:44 -04:00
|
|
|
}
|
2015-06-04 14:56:48 -04:00
|
|
|
|
2015-07-06 11:55:50 -04:00
|
|
|
double sum2 = GoTestpkgCallSSum(s);
|
2015-06-04 14:56:48 -04:00
|
|
|
if (sum != sum2) {
|
2015-07-06 11:55:50 -04:00
|
|
|
ERROR(@"GoTestpkgCallSSum(s)=%f; want %f as returned by s.Sum", sum2, sum);
|
2015-06-04 14:56:48 -04:00
|
|
|
}
|
|
|
|
|
2015-06-02 09:36:44 -04:00
|
|
|
[s setX:7];
|
|
|
|
[s setY:70];
|
2015-10-12 15:50:24 -04:00
|
|
|
x = [s x];
|
|
|
|
y = [s y];
|
|
|
|
sum = [s sum];
|
2015-06-02 09:36:44 -04:00
|
|
|
if (x != 7 || y != 70 || sum != 77) {
|
2015-07-06 11:55:50 -04:00
|
|
|
ERROR(@"GoTestpkgS(7, 70).X=%f Y=%f SUM=%f; want 7, 70, 77", x, y, sum);
|
2015-06-02 09:36:44 -04:00
|
|
|
}
|
2015-07-23 13:06:27 -04:00
|
|
|
|
|
|
|
NSString *first = @"trytwotested";
|
|
|
|
NSString *second = @"test";
|
2015-10-12 15:50:24 -04:00
|
|
|
NSString *got = [s tryTwoStrings:first second:second];
|
2015-07-23 13:06:27 -04:00
|
|
|
NSString *want = [first stringByAppendingString:second];
|
|
|
|
if (![got isEqualToString:want]) {
|
|
|
|
ERROR(@"GoTestpkgS_TryTwoStrings(%@, %@)= %@; want %@", first, second, got,
|
|
|
|
want);
|
|
|
|
}
|
2015-07-16 08:37:45 -04:00
|
|
|
|
|
|
|
GoTestpkgGC();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Objective-C implementation of testpkg.I.
|
|
|
|
@interface Number : NSObject <GoTestpkgI> {
|
|
|
|
}
|
|
|
|
@property int32_t value;
|
|
|
|
|
2015-10-12 15:50:24 -04:00
|
|
|
// TODO(hyangah): error:error is not good.
|
|
|
|
- (BOOL)error:(BOOL)e error:(NSError **)error;
|
|
|
|
- (int64_t)times:(int32_t)v;
|
2015-07-16 08:37:45 -04:00
|
|
|
@end
|
|
|
|
|
|
|
|
// numI is incremented when the first numI objective-C implementation is
|
|
|
|
// deallocated.
|
|
|
|
static int numI = 0;
|
|
|
|
|
|
|
|
@implementation Number {
|
|
|
|
}
|
|
|
|
@synthesize value;
|
|
|
|
|
2015-10-12 15:50:24 -04:00
|
|
|
- (BOOL)stringError:(NSString *)s
|
2015-08-31 01:06:30 -04:00
|
|
|
ret0_:(NSString **)ret0_
|
|
|
|
error:(NSError **)error {
|
|
|
|
if ([s isEqualTo:@"number"]) {
|
|
|
|
if (ret0_ != NULL) {
|
|
|
|
*ret0_ = @"OK";
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-10-12 15:50:24 -04:00
|
|
|
- (BOOL)error:(BOOL)triggerError error:(NSError **)error {
|
2015-08-25 00:26:23 -04:00
|
|
|
if (!triggerError) {
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
if (error != NULL) {
|
|
|
|
*error = [NSError errorWithDomain:@"SeqTest" code:1 userInfo:NULL];
|
|
|
|
}
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
2015-10-12 15:50:24 -04:00
|
|
|
- (int64_t)times:(int32_t)v {
|
2015-07-16 08:37:45 -04:00
|
|
|
return v * value;
|
|
|
|
}
|
2015-08-31 01:06:30 -04:00
|
|
|
|
2015-07-16 08:37:45 -04:00
|
|
|
- (void)dealloc {
|
|
|
|
if (self.value == 0) {
|
|
|
|
numI++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
|
|
void testInterface() {
|
|
|
|
// Test Go object implementing testpkg.I is handled correctly.
|
|
|
|
id<GoTestpkgI> goObj = GoTestpkgNewI();
|
2015-10-12 15:50:24 -04:00
|
|
|
int64_t got = [goObj times:10];
|
2015-07-16 08:37:45 -04:00
|
|
|
if (got != 100) {
|
2015-10-12 15:50:24 -04:00
|
|
|
ERROR(@"GoTestpkgNewI().times(10) = %lld; want %d", got, 100);
|
2015-07-16 08:37:45 -04:00
|
|
|
}
|
|
|
|
int32_t key = -1;
|
|
|
|
GoTestpkgRegisterI(key, goObj);
|
|
|
|
int64_t got2 = GoTestpkgMultiply(key, 10);
|
|
|
|
if (got != got2) {
|
|
|
|
ERROR(@"GoTestpkgMultiply(10 * 10) = %lld; want %lld", got2, got);
|
|
|
|
}
|
|
|
|
GoTestpkgUnregisterI(key);
|
|
|
|
|
|
|
|
// Test Objective-C objects implementing testpkg.I is handled correctly.
|
|
|
|
@autoreleasepool {
|
|
|
|
for (int32_t i = 0; i < 10; i++) {
|
|
|
|
Number *num = [[Number alloc] init];
|
|
|
|
num.value = i;
|
|
|
|
GoTestpkgRegisterI(i, num);
|
|
|
|
}
|
|
|
|
GoTestpkgGC();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Registered Objective-C objects are pinned on Go side which must
|
|
|
|
// prevent deallocation from Objective-C.
|
|
|
|
for (int32_t i = 0; i < 10; i++) {
|
|
|
|
int64_t got = GoTestpkgMultiply(i, 2);
|
|
|
|
if (got != i * 2) {
|
|
|
|
ERROR(@"GoTestpkgMultiply(%d, 2) = %lld; want %d", i, got, i * 2);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
GoTestpkgUnregisterI(i);
|
|
|
|
GoTestpkgGC();
|
|
|
|
}
|
|
|
|
// Unregistered all Objective-C objects.
|
2015-06-02 09:36:44 -04:00
|
|
|
}
|
|
|
|
|
2015-08-25 00:26:23 -04:00
|
|
|
void testIssue12307() {
|
|
|
|
Number *num = [[Number alloc] init];
|
|
|
|
num.value = 1024;
|
|
|
|
NSError *error;
|
|
|
|
if (GoTestpkgCallIError(num, YES, &error) == YES) {
|
|
|
|
ERROR(@"GoTestpkgCallIError(Number, YES) succeeded; want error");
|
|
|
|
}
|
|
|
|
NSError *error2;
|
|
|
|
if (GoTestpkgCallIError(num, NO, &error2) == NO) {
|
|
|
|
ERROR(@"GoTestpkgCallIError(Number, NO) failed(%@); want success", error2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-31 01:06:30 -04:00
|
|
|
void testIssue12403() {
|
|
|
|
Number *num = [[Number alloc] init];
|
|
|
|
num.value = 1024;
|
|
|
|
|
|
|
|
NSString *ret;
|
|
|
|
NSError *error;
|
|
|
|
if (GoTestpkgCallIStringError(num, @"alphabet", &ret, &error) == YES) {
|
|
|
|
ERROR(
|
|
|
|
@"GoTestpkgCallIStringError(Number, 'alphabet') succeeded; want error");
|
|
|
|
}
|
|
|
|
NSError *error2;
|
|
|
|
if (GoTestpkgCallIStringError(num, @"number", &ret, &error2) == NO) {
|
|
|
|
ERROR(
|
|
|
|
@"GoTestpkgCallIStringError(Number, 'number') failed(%@); want success",
|
|
|
|
error2);
|
|
|
|
} else if (![ret isEqualTo:@"OK"]) {
|
|
|
|
ERROR(@"GoTestpkgCallIStringError(Number, 'number') returned unexpected "
|
|
|
|
@"results %@",
|
|
|
|
ret);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-01 22:04:03 -04:00
|
|
|
void testVar() {
|
2015-10-12 15:50:24 -04:00
|
|
|
NSString *s = GoTestpkg.stringVar;
|
2015-10-01 22:04:03 -04:00
|
|
|
if (![s isEqualToString:@"a string var"]) {
|
2015-10-12 12:27:29 -04:00
|
|
|
ERROR(@"GoTestpkg.StringVar = %@, want 'a string var'", s);
|
2015-10-01 22:04:03 -04:00
|
|
|
}
|
|
|
|
s = @"a new string var";
|
2015-10-12 15:50:24 -04:00
|
|
|
GoTestpkg.stringVar = s;
|
|
|
|
NSString *s2 = GoTestpkg.stringVar;
|
2015-10-01 22:04:03 -04:00
|
|
|
if (![s2 isEqualToString:s]) {
|
2015-10-12 15:50:24 -04:00
|
|
|
ERROR(@"GoTestpkg.stringVar = %@, want %@", s2, s);
|
2015-10-01 22:04:03 -04:00
|
|
|
}
|
|
|
|
|
2015-10-12 15:50:24 -04:00
|
|
|
int64_t i = GoTestpkg.intVar;
|
2015-10-01 22:04:03 -04:00
|
|
|
if (i != 77) {
|
2015-10-12 15:50:24 -04:00
|
|
|
ERROR(@"GoTestpkg.intVar = %lld, want 77", i);
|
2015-10-01 22:04:03 -04:00
|
|
|
}
|
2015-10-12 15:50:24 -04:00
|
|
|
GoTestpkg.intVar = 777;
|
|
|
|
i = GoTestpkg.intVar;
|
2015-10-01 22:04:03 -04:00
|
|
|
if (i != 777) {
|
2015-10-12 15:50:24 -04:00
|
|
|
ERROR(@"GoTestpkg.intVar = %lld, want 777", i);
|
2015-10-12 12:27:29 -04:00
|
|
|
}
|
|
|
|
[GoTestpkg setIntVar:7777];
|
2015-10-12 15:50:24 -04:00
|
|
|
i = [GoTestpkg intVar];
|
2015-10-12 12:27:29 -04:00
|
|
|
if (i != 7777) {
|
2015-10-12 15:50:24 -04:00
|
|
|
ERROR(@"GoTestpkg.intVar = %lld, want 7777", i);
|
2015-10-01 22:04:03 -04:00
|
|
|
}
|
|
|
|
|
2015-10-12 15:50:24 -04:00
|
|
|
GoTestpkgNode *n0 = GoTestpkg.structVar;
|
|
|
|
if (![n0.v isEqualToString:@"a struct var"]) {
|
|
|
|
ERROR(@"GoTestpkg.structVar = %@, want 'a struct var'", n0.v);
|
2015-10-01 22:04:03 -04:00
|
|
|
}
|
|
|
|
GoTestpkgNode *n1 = GoTestpkgNewNode(@"a new struct var");
|
2015-10-12 15:50:24 -04:00
|
|
|
GoTestpkg.structVar = n1;
|
|
|
|
GoTestpkgNode *n2 = GoTestpkg.structVar;
|
|
|
|
if (![n2.v isEqualToString:@"a new struct var"]) {
|
|
|
|
ERROR(@"GoTestpkg.StructVar = %@, want 'a new struct var'", n2.v);
|
2015-10-01 22:04:03 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
Number *num = [[Number alloc] init];
|
|
|
|
num.value = 12345;
|
2015-10-12 15:50:24 -04:00
|
|
|
GoTestpkg.interfaceVar = num;
|
|
|
|
id<GoTestpkgI> iface = GoTestpkg.interfaceVar;
|
|
|
|
int64_t x = [iface times:10];
|
|
|
|
int64_t y = [num times:10];
|
2015-10-01 22:04:03 -04:00
|
|
|
if (x != y) {
|
2015-10-12 12:27:29 -04:00
|
|
|
ERROR(@"GoTestpkg.InterfaceVar Times 10 = %lld, want %lld", x, y);
|
2015-10-01 22:04:03 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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-02-12 18:50:33 +01:00
|
|
|
// Objective-C implementation of testpkg.NullTest.
|
|
|
|
@interface NullTest : NSObject <GoTestpkgNullTest> {
|
|
|
|
}
|
|
|
|
|
|
|
|
- (GoTestpkgNullTest *)null;
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation NullTest {
|
|
|
|
}
|
|
|
|
|
|
|
|
- (GoTestpkgNullTest *)null {
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
|
|
void testNullReferences() {
|
|
|
|
NullTest *t = [[NullTest alloc] init];
|
|
|
|
BOOL res = GoTestpkgCallWithNull(nil, t);
|
|
|
|
if (!res) {
|
|
|
|
ERROR(@"GoTestpkg.CallWithNull failed");
|
|
|
|
}
|
|
|
|
id<GoTestpkgI> i = GoTestpkgNewNullInterface();
|
|
|
|
if (i != nil) {
|
|
|
|
ERROR(@"NewNullInterface() returned %p; expected nil", i);
|
|
|
|
}
|
|
|
|
GoTestpkgS *s = GoTestpkgNewNullStruct();
|
|
|
|
if (s != nil) {
|
|
|
|
ERROR(@"NewNullStruct() returned %p; expected nil", s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void testByteArrayRead() {
|
|
|
|
NSData *arr = [NSMutableData dataWithLength:8];
|
|
|
|
int n;
|
|
|
|
BOOL success = GoTestpkgReadIntoByteArray(arr, &n, nil);
|
|
|
|
if (!success) {
|
|
|
|
ERROR(@"ReadIntoByteArray failed");
|
|
|
|
}
|
|
|
|
if (n != 8) {
|
|
|
|
ERROR(@"ReadIntoByteArray wrote %d bytes, expected %d", n, 8);
|
|
|
|
}
|
|
|
|
const uint8_t *b = [arr bytes];
|
|
|
|
for (int i = 0; i < [arr length]; i++) {
|
|
|
|
if (b[i] != i) {
|
|
|
|
ERROR(@"ReadIntoByteArray wrote %d at %d; expected %d", b[i], i, i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Test that immutable data cannot be changed from Go
|
|
|
|
const uint8_t buf[] = {42};
|
|
|
|
arr = [NSData dataWithBytes:buf length:1];
|
|
|
|
success = GoTestpkgReadIntoByteArray(arr, &n, nil);
|
|
|
|
if (!success) {
|
|
|
|
ERROR(@"ReadIntoByteArray failed");
|
|
|
|
}
|
|
|
|
if (n != 1) {
|
|
|
|
ERROR(@"ReadIntoByteArray wrote %d bytes, expected %d", n, 8);
|
|
|
|
}
|
|
|
|
b = [arr bytes];
|
|
|
|
if (b[0] != 42) {
|
|
|
|
ERROR(@"ReadIntoByteArray wrote to an immutable NSData; expected no change");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void testNilField() {
|
|
|
|
GoTestpkgNullFieldStruct *s = GoTestpkgNewNullFieldStruct();
|
|
|
|
if ([s f] != nil) {
|
|
|
|
ERROR(@"NullFieldStruct has non-nil field; expected nil");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void testStringDup(NSString *want) {
|
|
|
|
NSString *got = GoTestpkgStringDup(want);
|
|
|
|
if (![want isEqualToString:got]) {
|
|
|
|
ERROR(@"StringDup returned %@; expected %@", got, want)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void testUnicodeStrings() {
|
|
|
|
testStringDup(@"abcxyz09{}");
|
|
|
|
testStringDup(@"Hello, 世界");
|
|
|
|
testStringDup(@"\uffff\U00010000\U00010001\U00012345\U0010ffff");
|
|
|
|
}
|
|
|
|
|
2015-05-05 15:57:36 -04:00
|
|
|
// Invokes functions and object methods defined in Testpkg.h.
|
|
|
|
//
|
|
|
|
// TODO(hyangah): apply testing framework (e.g. XCTestCase)
|
|
|
|
// and test through xcodebuild.
|
|
|
|
int main(void) {
|
|
|
|
@autoreleasepool {
|
2015-07-06 11:55:50 -04:00
|
|
|
GoTestpkgHi();
|
2015-05-05 15:57:36 -04:00
|
|
|
|
2015-07-06 11:55:50 -04:00
|
|
|
GoTestpkgInt(42);
|
2015-05-05 15:57:36 -04:00
|
|
|
|
2015-07-06 11:55:50 -04:00
|
|
|
int64_t sum = GoTestpkgSum(31, 21);
|
2015-05-05 15:57:36 -04:00
|
|
|
if (sum != 52) {
|
2015-07-06 11:55:50 -04:00
|
|
|
ERROR(@"GoTestpkgSum(31, 21) = %lld, want 52\n", sum);
|
2015-05-05 15:57:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
testHello(@"세계"); // korean, utf-8, world.
|
|
|
|
|
2015-10-28 15:14:06 -04:00
|
|
|
testString();
|
|
|
|
|
2015-05-05 15:57:36 -04:00
|
|
|
unichar t[] = {
|
|
|
|
0xD83D, 0xDCA9,
|
|
|
|
}; // utf-16, pile of poo.
|
|
|
|
testHello([NSString stringWithCharacters:t length:2]);
|
2015-05-11 16:25:42 -04:00
|
|
|
|
|
|
|
testBytesAppend(@"Foo", @"Bar");
|
2015-06-02 09:36:44 -04:00
|
|
|
|
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-02-12 18:50:33 +01:00
|
|
|
@autoreleasepool {
|
|
|
|
testStruct();
|
|
|
|
}
|
2015-07-23 13:06:27 -04:00
|
|
|
int numS = GoTestpkgCollectS(
|
|
|
|
1, 10); // within 10 seconds, collect the S used in testStruct.
|
2015-06-04 14:56:48 -04:00
|
|
|
if (numS != 1) {
|
2015-07-23 13:06:27 -04:00
|
|
|
ERROR(@"%d S objects were collected; S used in testStruct is supposed to "
|
|
|
|
@"be collected.",
|
|
|
|
numS);
|
2015-06-04 14:56:48 -04:00
|
|
|
}
|
2015-07-16 08:37:45 -04:00
|
|
|
|
|
|
|
@autoreleasepool {
|
|
|
|
testInterface();
|
|
|
|
}
|
|
|
|
if (numI != 1) {
|
|
|
|
ERROR(@"%d I objects were collected; I used in testInterface is supposed "
|
|
|
|
@"to be collected.",
|
|
|
|
numI);
|
|
|
|
}
|
2015-08-25 00:26:23 -04:00
|
|
|
|
2015-10-01 22:04:03 -04:00
|
|
|
testConst();
|
|
|
|
|
2015-08-25 00:26:23 -04:00
|
|
|
testIssue12307();
|
2015-10-01 22:04:03 -04:00
|
|
|
|
|
|
|
testVar();
|
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-02-12 18:50:33 +01:00
|
|
|
|
|
|
|
testNullReferences();
|
|
|
|
|
|
|
|
testByteArrayRead();
|
|
|
|
|
|
|
|
testNilField();
|
|
|
|
|
|
|
|
testUnicodeStrings();
|
2015-05-05 15:57:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(stderr, "%s\n", err ? "FAIL" : "PASS");
|
|
|
|
return err;
|
|
|
|
}
|