2
0
mirror of synced 2025-02-20 13:38:20 +00:00

bind/objc: fixes miscalculation of string length.

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.

Fixes golang/go#11842.

Change-Id: I21798be2ec7adfb68cc2897bb46a924f05f3478c
Reviewed-on: https://go-review.googlesource.com/12577
Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
Hyang-Ah (Hana) Kim 2015-07-23 13:06:27 -04:00 committed by Hyang-Ah Hana Kim
parent c039090cf1
commit 4755f4ad8f
8 changed files with 383 additions and 22 deletions

View File

@ -60,7 +60,8 @@ void testStruct() {
double y = [s Y];
double sum = [s Sum];
if (x != 10.0 || y != 100.0 || sum != 110.0) {
ERROR(@"GoTestpkgS(10.0, 100.0).X=%f Y=%f SUM=%f; want 10, 100, 110", x, y, sum);
ERROR(@"GoTestpkgS(10.0, 100.0).X=%f Y=%f SUM=%f; want 10, 100, 110", x, y,
sum);
}
double sum2 = GoTestpkgCallSSum(s);
@ -76,6 +77,15 @@ void testStruct() {
if (x != 7 || y != 70 || sum != 77) {
ERROR(@"GoTestpkgS(7, 70).X=%f Y=%f SUM=%f; want 7, 70, 77", x, y, sum);
}
NSString *first = @"trytwotested";
NSString *second = @"test";
NSString *got = [s TryTwoStrings:first second:second];
NSString *want = [first stringByAppendingString:second];
if (![got isEqualToString:want]) {
ERROR(@"GoTestpkgS_TryTwoStrings(%@, %@)= %@; want %@", first, second, got,
want);
}
}
// Invokes functions and object methods defined in Testpkg.h.
@ -103,9 +113,12 @@ int main(void) {
testBytesAppend(@"Foo", @"Bar");
testStruct();
int numS = GoTestpkgCollectS(1, 10); // within 10 seconds, collect the S used in testStruct.
int numS = GoTestpkgCollectS(
1, 10); // within 10 seconds, collect the S used in testStruct.
if (numS != 1) {
ERROR(@"%d S objects were collected; S used in testStruct is supposed to be collected.", numS);
ERROR(@"%d S objects were collected; S used in testStruct is supposed to "
@"be collected.",
numS);
}
}

View File

@ -25,14 +25,24 @@
// mem_ensure ensures that m has at least size bytes free.
// If m is NULL, it is created.
static void mem_ensure(GoSeq *m, uint32_t size) {
if (m->cap > m->off + size) {
size_t cap = m->cap;
if (cap > m->off + size) {
return;
}
m->buf = (uint8_t *)realloc((void *)m->buf, m->off + size);
if (cap == 0) {
cap = 64;
}
while (cap < m->off + size) {
cap *= 2;
}
m->buf = (uint8_t *)realloc((void *)m->buf, cap);
if (m->buf == NULL) {
LOG_FATAL(@"mem_ensure realloc failed, off=%zu, size=%u", m->off, size);
}
m->cap = m->off + size;
m->cap = cap;
}
static uint32_t align(uint32_t offset, uint32_t alignment) {
@ -66,14 +76,7 @@ static uint8_t *mem_write(GoSeq *m, uint32_t size, uint32_t alignment) {
m->off, m->len, size);
}
uint32_t offset = align(m->off, alignment);
uint32_t cap = m->cap;
if (cap == 0) {
cap = 64;
}
while (offset + size > cap) {
cap *= 2;
}
mem_ensure(m, cap);
mem_ensure(m, offset - m->off + size);
uint8_t *res = m->buf + offset;
m->off = offset + size;
m->len = offset + size;
@ -160,7 +163,7 @@ void go_seq_writeUTF8(GoSeq *seq, NSString *s) {
return;
}
char *buf = (char *)mem_write(seq, len + 1, 1);
char *buf = (char *)mem_write(seq, len, 1);
NSUInteger used;
[s getBytes:buf
maxLength:len

View File

@ -65,12 +65,13 @@ func proxy_ReturnsError(out, in *seq.Buffer) {
}
const (
proxyS_Descriptor = "go.testpkg.S"
proxyS_X_Get_Code = 0x00f
proxyS_X_Set_Code = 0x01f
proxyS_Y_Get_Code = 0x10f
proxyS_Y_Set_Code = 0x11f
proxyS_Sum_Code = 0x00c
proxyS_Descriptor = "go.testpkg.S"
proxyS_X_Get_Code = 0x00f
proxyS_X_Set_Code = 0x01f
proxyS_Y_Get_Code = 0x10f
proxyS_Y_Set_Code = 0x11f
proxyS_Sum_Code = 0x00c
proxyS_TryTwoStrings_Code = 0x10c
)
type proxyS seq.Ref
@ -106,12 +107,22 @@ func proxyS_Sum(out, in *seq.Buffer) {
out.WriteFloat64(res)
}
func proxyS_TryTwoStrings(out, in *seq.Buffer) {
ref := in.ReadRef()
v := ref.Get().(*testpkg.S)
param_first := in.ReadString()
param_second := in.ReadString()
res := v.TryTwoStrings(param_first, param_second)
out.WriteString(res)
}
func init() {
seq.Register(proxyS_Descriptor, proxyS_X_Set_Code, proxyS_X_Set)
seq.Register(proxyS_Descriptor, proxyS_X_Get_Code, proxyS_X_Get)
seq.Register(proxyS_Descriptor, proxyS_Y_Set_Code, proxyS_Y_Set)
seq.Register(proxyS_Descriptor, proxyS_Y_Get_Code, proxyS_Y_Get)
seq.Register(proxyS_Descriptor, proxyS_Sum_Code, proxyS_Sum)
seq.Register(proxyS_Descriptor, proxyS_TryTwoStrings_Code, proxyS_TryTwoStrings)
}
func proxy_Sum(out, in *seq.Buffer) {

View File

@ -20,6 +20,7 @@
- (double)Y;
- (void)setY:(double)v;
- (double)Sum;
- (NSString*)TryTwoStrings:(NSString*)first second:(NSString*)second;
@end
FOUNDATION_EXPORT NSData* GoTestpkgBytesAppend(NSData* a, NSData* b);

View File

@ -9,6 +9,10 @@
static NSString *errDomain = @"go.golang.org/x/mobile/bind/objc/testpkg";
@protocol goSeqRefInterface
-(GoSeqRef*) ref;
@end
#define _DESCRIPTOR_ "testpkg"
#define _CALL_BytesAppend_ 1
@ -27,6 +31,7 @@ static NSString *errDomain = @"go.golang.org/x/mobile/bind/objc/testpkg";
#define _GO_testpkg_S_FIELD_Y_GET_ (0x10f)
#define _GO_testpkg_S_FIELD_Y_SET_ (0x11f)
#define _GO_testpkg_S_Sum_ (0x00c)
#define _GO_testpkg_S_TryTwoStrings_ (0x10c)
@implementation GoTestpkgS {
}
@ -90,6 +95,19 @@ static NSString *errDomain = @"go.golang.org/x/mobile/bind/objc/testpkg";
return ret0_;
}
- (NSString*)TryTwoStrings:(NSString*)first second:(NSString*)second {
GoSeq in_ = {};
GoSeq out_ = {};
go_seq_writeRef(&in_, self.ref);
go_seq_writeUTF8(&in_, first);
go_seq_writeUTF8(&in_, second);
go_seq_send(_GO_testpkg_S_DESCRIPTOR_, _GO_testpkg_S_TryTwoStrings_, &in_, &out_);
NSString* ret0_ = go_seq_readUTF8(&out_);
go_seq_free(&in_);
go_seq_free(&out_);
return ret0_;
}
@end
NSData* GoTestpkgBytesAppend(NSData* a, NSData* b) {
@ -107,7 +125,12 @@ NSData* GoTestpkgBytesAppend(NSData* a, NSData* b) {
double GoTestpkgCallSSum(GoTestpkgS* s) {
GoSeq in_ = {};
GoSeq out_ = {};
go_seq_writeRef(&in_, s.ref);
if (![s respondsToSelector:@selector(ref)]) {
@throw [NSException exceptionWithName:@"InvalidGoSeqRef"
reason:@"not a subclass of GoTestpkgSStub"
userInfo:nil];
}
go_seq_writeRef(&in_, [(id<goSeqRefInterface>)s ref]);
go_seq_send(_DESCRIPTOR_, _CALL_CallSSum_, &in_, &out_);
double ret0_ = go_seq_readFloat64(&out_);
go_seq_free(&in_);

View File

@ -0,0 +1,57 @@
// Objective-C API for talking to golang.org/x/mobile/bind/objc/testpkg Go package.
// gobind -lang=objc golang.org/x/mobile/bind/objc/testpkg
//
// File is generated by gobind. Do not edit.
#ifndef __GoTestpkg_H__
#define __GoTestpkg_H__
#include <Foundation/Foundation.h>
@protocol GoTestpkgI
- (void)Fn:(int32_t)v;
@end
@interface GoTestpkgI : NSObject {
}
@property (strong, readonly) id ref;
@property (weak, readonly, nonatomic) id delegate;
- (void)call:(int)code in:(void *)in out:(void *)out;
@end
@class GoTestpkgS;
@interface GoTestpkgS : NSObject {
}
@property(strong, readonly) id ref;
- (id)initWithRef:(id)ref;
- (double)X;
- (void)setX:(double)v;
- (double)Y;
- (void)setY:(double)v;
- (double)Sum;
@end
FOUNDATION_EXPORT NSData* GoTestpkgBytesAppend(NSData* a, NSData* b);
FOUNDATION_EXPORT void GoTestpkgCallI(GoTestpkgI* i, int32_t v);
FOUNDATION_EXPORT double GoTestpkgCallSSum(GoTestpkgS* s);
FOUNDATION_EXPORT int GoTestpkgCollectS(int want, int timeoutSec);
FOUNDATION_EXPORT NSString* GoTestpkgHello(NSString* s);
FOUNDATION_EXPORT void GoTestpkgHi();
FOUNDATION_EXPORT void GoTestpkgInt(int32_t x);
FOUNDATION_EXPORT GoTestpkgS* GoTestpkgNewS(double x, double y);
FOUNDATION_EXPORT BOOL GoTestpkgReturnsError(BOOL b, NSString** ret0_, NSError** error);
FOUNDATION_EXPORT int64_t GoTestpkgSum(int64_t x, int64_t y);
#endif

View File

@ -0,0 +1,249 @@
// Objective-C API for talking to golang.org/x/mobile/bind/objc/testpkg Go package.
// gobind -lang=objc golang.org/x/mobile/bind/objc/testpkg
//
// File is generated by gobind. Do not edit.
#include "GoTestpkg.h"
#include <Foundation/Foundation.h>
#include "seq.h"
static NSString *errDomain = @"go.golang.org/x/mobile/bind/objc/testpkg";
#define _DESCRIPTOR_ "testpkg"
#define _CALL_BytesAppend_ 1
#define _CALL_CallI_ 2
#define _CALL_CallSSum_ 3
#define _CALL_CollectS_ 4
#define _CALL_Hello_ 5
#define _CALL_Hi_ 6
#define _CALL_Int_ 7
#define _CALL_NewS_ 8
#define _CALL_ReturnsError_ 9
#define _CALL_Sum_ 10
#define _GO_testpkg_S_DESCRIPTOR_ "go.testpkg.S"
#define _GO_testpkg_S_FIELD_X_GET_ (0x00f)
#define _GO_testpkg_S_FIELD_X_SET_ (0x01f)
#define _GO_testpkg_S_FIELD_Y_GET_ (0x10f)
#define _GO_testpkg_S_FIELD_Y_SET_ (0x11f)
#define _GO_testpkg_S_Sum_ (0x00c)
#define _GO_testpkg_I_DESCRIPTOR_ "go.testpkg.I"
#define _GO_testpkg_I_Fn_ 0x10a
@implementation GoTestpkgI {
}
@synthesize delegate = _delegate;
@synthesize ref = _ref;
- (id)init {
self = [super init];
if (self) {
_delegate = self;
_ref = [GoSeqRef newForObject:self];
}
return self;
}
- (void)call:(int)code in:(void *)in out:(void *)out {
GoSeq* inseq = (GoSeq*)in;
GoSeq* outseq = (GoSeq*)out;
switch (code) {
case _GO_testpkg_I_Fn_:
{
int32_t v = go_seq_readInt32(inseq);
[_delegate Fn:v];
return;
}
default:
NSLog(@"unknown code %s:%d", _GO_testpkg_I_DESCRIPTOR_, code);
}
}
@end
@implementation GoTestpkgS {
}
- (id)initWithRef:(id)ref {
self = [super init];
if (self) { _ref = ref; }
return self;
}
- (double)X {
GoSeq in_ = {};
GoSeq out_ = {};
go_seq_writeRef(&in_, self.ref);
go_seq_send(_GO_testpkg_S_DESCRIPTOR_, _GO_testpkg_S_FIELD_X_GET_, &in_, &out_);
double ret_ = go_seq_readFloat64(&out_);
go_seq_free(&in_);
go_seq_free(&out_);
return ret_;
}
- (void)setX:(double)v {
GoSeq in_ = {};
GoSeq out_ = {};
go_seq_writeRef(&in_, self.ref);
go_seq_writeFloat64(&in_, v);
go_seq_send(_GO_testpkg_S_DESCRIPTOR_, _GO_testpkg_S_FIELD_X_SET_, &in_, &out_);
go_seq_free(&in_);
go_seq_free(&out_);
}
- (double)Y {
GoSeq in_ = {};
GoSeq out_ = {};
go_seq_writeRef(&in_, self.ref);
go_seq_send(_GO_testpkg_S_DESCRIPTOR_, _GO_testpkg_S_FIELD_Y_GET_, &in_, &out_);
double ret_ = go_seq_readFloat64(&out_);
go_seq_free(&in_);
go_seq_free(&out_);
return ret_;
}
- (void)setY:(double)v {
GoSeq in_ = {};
GoSeq out_ = {};
go_seq_writeRef(&in_, self.ref);
go_seq_writeFloat64(&in_, v);
go_seq_send(_GO_testpkg_S_DESCRIPTOR_, _GO_testpkg_S_FIELD_Y_SET_, &in_, &out_);
go_seq_free(&in_);
go_seq_free(&out_);
}
- (double)Sum {
GoSeq in_ = {};
GoSeq out_ = {};
go_seq_writeRef(&in_, self.ref);
go_seq_send(_GO_testpkg_S_DESCRIPTOR_, _GO_testpkg_S_Sum_, &in_, &out_);
double ret0_ = go_seq_readFloat64(&out_);
go_seq_free(&in_);
go_seq_free(&out_);
return ret0_;
}
@end
NSData* GoTestpkgBytesAppend(NSData* a, NSData* b) {
GoSeq in_ = {};
GoSeq out_ = {};
go_seq_writeByteArray(&in_, a);
go_seq_writeByteArray(&in_, b);
go_seq_send(_DESCRIPTOR_, _CALL_BytesAppend_, &in_, &out_);
NSData* ret0_ = go_seq_readByteArray(&out_);
go_seq_free(&in_);
go_seq_free(&out_);
return ret0_;
}
void GoTestpkgCallI(GoTestpkgI* i, int32_t v) {
GoSeq in_ = {};
GoSeq out_ = {};
go_seq_writeRef(&in_, i.ref);
go_seq_writeInt32(&in_, v);
go_seq_send(_DESCRIPTOR_, _CALL_CallI_, &in_, &out_);
return;
}
double GoTestpkgCallSSum(GoTestpkgS* s) {
GoSeq in_ = {};
GoSeq out_ = {};
go_seq_writeRef(&in_, s.ref);
go_seq_send(_DESCRIPTOR_, _CALL_CallSSum_, &in_, &out_);
double ret0_ = go_seq_readFloat64(&out_);
go_seq_free(&in_);
go_seq_free(&out_);
return ret0_;
}
int GoTestpkgCollectS(int want, int timeoutSec) {
GoSeq in_ = {};
GoSeq out_ = {};
go_seq_writeInt(&in_, want);
go_seq_writeInt(&in_, timeoutSec);
go_seq_send(_DESCRIPTOR_, _CALL_CollectS_, &in_, &out_);
int ret0_ = go_seq_readInt(&out_);
go_seq_free(&in_);
go_seq_free(&out_);
return ret0_;
}
NSString* GoTestpkgHello(NSString* s) {
GoSeq in_ = {};
GoSeq out_ = {};
go_seq_writeUTF8(&in_, s);
go_seq_send(_DESCRIPTOR_, _CALL_Hello_, &in_, &out_);
NSString* ret0_ = go_seq_readUTF8(&out_);
go_seq_free(&in_);
go_seq_free(&out_);
return ret0_;
}
void GoTestpkgHi() {
GoSeq in_ = {};
GoSeq out_ = {};
go_seq_send(_DESCRIPTOR_, _CALL_Hi_, &in_, &out_);
go_seq_free(&in_);
go_seq_free(&out_);
}
void GoTestpkgInt(int32_t x) {
GoSeq in_ = {};
GoSeq out_ = {};
go_seq_writeInt32(&in_, x);
go_seq_send(_DESCRIPTOR_, _CALL_Int_, &in_, &out_);
go_seq_free(&in_);
go_seq_free(&out_);
}
GoTestpkgS* GoTestpkgNewS(double x, double y) {
GoSeq in_ = {};
GoSeq out_ = {};
go_seq_writeFloat64(&in_, x);
go_seq_writeFloat64(&in_, y);
go_seq_send(_DESCRIPTOR_, _CALL_NewS_, &in_, &out_);
GoSeqRef* ret0__ref = go_seq_readRef(&out_);
GoTestpkgS* ret0_ = ret0__ref.obj;
if (ret0_ == NULL) {
ret0_ = [[GoTestpkgS alloc] initWithRef:ret0__ref];
}
go_seq_free(&in_);
go_seq_free(&out_);
return ret0_;
}
BOOL GoTestpkgReturnsError(BOOL b, NSString** ret0_, NSError** error) {
GoSeq in_ = {};
GoSeq out_ = {};
go_seq_writeBool(&in_, b);
go_seq_send(_DESCRIPTOR_, _CALL_ReturnsError_, &in_, &out_);
NSString* ret0__val = go_seq_readUTF8(&out_);
if (ret0_ != NULL) {
*ret0_ = ret0__val;
}
NSString* _error = go_seq_readUTF8(&out_);
if ([_error length] != 0 && error != nil) {
NSMutableDictionary *details = [NSMutableDictionary dictionary];
[details setValue:_error forKey:NSLocalizedDescriptionKey];
*error = [NSError errorWithDomain:errDomain code:1 userInfo:details];
}
go_seq_free(&in_);
go_seq_free(&out_);
return ([_error length] == 0);
}
int64_t GoTestpkgSum(int64_t x, int64_t y) {
GoSeq in_ = {};
GoSeq out_ = {};
go_seq_writeInt64(&in_, x);
go_seq_writeInt64(&in_, y);
go_seq_send(_DESCRIPTOR_, _CALL_Sum_, &in_, &out_);
int64_t ret0_ = go_seq_readInt64(&out_);
go_seq_free(&in_);
go_seq_free(&out_);
return ret0_;
}

View File

@ -75,6 +75,10 @@ func NewS(x, y float64) *S {
return s
}
func (s *S) TryTwoStrings(first, second string) string {
return first + second
}
func (s *S) Sum() float64 {
return s.X + s.Y
}