@@ -20,7 +20,7 @@ var $needsExternalization = function(t) {
20
20
}
21
21
} ;
22
22
23
- var $externalize = function ( v , t ) {
23
+ var $externalize = function ( v , t , makeWrapper ) {
24
24
if ( t === $jsObjectPtr ) {
25
25
return v ;
26
26
}
@@ -44,37 +44,37 @@ var $externalize = function(v, t) {
44
44
case $kindArray :
45
45
if ( $needsExternalization ( t . elem ) ) {
46
46
return $mapArray ( v , function ( e ) {
47
- return $externalize ( e , t . elem ) ;
47
+ return $externalize ( e , t . elem , makeWrapper ) ;
48
48
} ) ;
49
49
}
50
50
return v ;
51
51
case $kindFunc :
52
- return $externalizeFunction ( v , t , false ) ;
52
+ return $externalizeFunction ( v , t , false , makeWrapper ) ;
53
53
case $kindInterface :
54
54
if ( v === $ifaceNil ) {
55
55
return null ;
56
56
}
57
57
if ( v . constructor === $jsObjectPtr ) {
58
58
return v . $val . object ;
59
59
}
60
- return $externalize ( v . $val , v . constructor ) ;
60
+ return $externalize ( v . $val , v . constructor , makeWrapper ) ;
61
61
case $kindMap :
62
62
var m = { } ;
63
63
var keys = $keys ( v ) ;
64
64
for ( var i = 0 ; i < keys . length ; i ++ ) {
65
65
var entry = v [ keys [ i ] ] ;
66
- m [ $externalize ( entry . k , t . key ) ] = $externalize ( entry . v , t . elem ) ;
66
+ m [ $externalize ( entry . k , t . key , makeWrapper ) ] = $externalize ( entry . v , t . elem , makeWrapper ) ;
67
67
}
68
68
return m ;
69
69
case $kindPtr :
70
70
if ( v === t . nil ) {
71
71
return null ;
72
72
}
73
- return $externalize ( v . $get ( ) , t . elem ) ;
73
+ return $externalize ( v . $get ( ) , t . elem , makeWrapper ) ;
74
74
case $kindSlice :
75
75
if ( $needsExternalization ( t . elem ) ) {
76
76
return $mapArray ( $sliceToArray ( v ) , function ( e ) {
77
- return $externalize ( e , t . elem ) ;
77
+ return $externalize ( e , t . elem , makeWrapper ) ;
78
78
} ) ;
79
79
}
80
80
return $sliceToArray ( v ) ;
@@ -128,20 +128,24 @@ var $externalize = function(v, t) {
128
128
return o ;
129
129
}
130
130
131
+ if ( makeWrapper !== undefined ) {
132
+ return makeWrapper ( v ) ;
133
+ }
134
+
131
135
o = { } ;
132
136
for ( var i = 0 ; i < t . fields . length ; i ++ ) {
133
137
var f = t . fields [ i ] ;
134
138
if ( ! f . exported ) {
135
139
continue ;
136
140
}
137
- o [ f . name ] = $externalize ( v [ f . prop ] , f . typ ) ;
141
+ o [ f . name ] = $externalize ( v [ f . prop ] , f . typ , makeWrapper ) ;
138
142
}
139
143
return o ;
140
144
}
141
145
$throwRuntimeError ( "cannot externalize " + t . string ) ;
142
146
} ;
143
147
144
- var $externalizeFunction = function ( v , t , passThis ) {
148
+ var $externalizeFunction = function ( v , t , passThis , makeWrapper ) {
145
149
if ( v === $throwNilPointerError ) {
146
150
return null ;
147
151
}
@@ -154,22 +158,22 @@ var $externalizeFunction = function(v, t, passThis) {
154
158
var vt = t . params [ i ] . elem ,
155
159
varargs = [ ] ;
156
160
for ( var j = i ; j < arguments . length ; j ++ ) {
157
- varargs . push ( $internalize ( arguments [ j ] , vt ) ) ;
161
+ varargs . push ( $internalize ( arguments [ j ] , vt , makeWrapper ) ) ;
158
162
}
159
163
args . push ( new t . params [ i ] ( varargs ) ) ;
160
164
break ;
161
165
}
162
- args . push ( $internalize ( arguments [ i ] , t . params [ i ] ) ) ;
166
+ args . push ( $internalize ( arguments [ i ] , t . params [ i ] , makeWrapper ) ) ;
163
167
}
164
168
var result = v . apply ( passThis ? this : undefined , args ) ;
165
169
switch ( t . results . length ) {
166
170
case 0 :
167
171
return ;
168
172
case 1 :
169
- return $externalize ( result , t . results [ 0 ] ) ;
173
+ return $externalize ( $copyIfRequired ( result , t . results [ 0 ] ) , t . results [ 0 ] , makeWrapper ) ;
170
174
default :
171
175
for ( var i = 0 ; i < t . results . length ; i ++ ) {
172
- result [ i ] = $externalize ( result [ i ] , t . results [ i ] ) ;
176
+ result [ i ] = $externalize ( $copyIfRequired ( result [ i ] , t . results [ i ] ) , t . results [ i ] , makeWrapper ) ;
173
177
}
174
178
return result ;
175
179
}
@@ -178,7 +182,7 @@ var $externalizeFunction = function(v, t, passThis) {
178
182
return v . $externalizeWrapper ;
179
183
} ;
180
184
181
- var $internalize = function ( v , t , recv ) {
185
+ var $internalize = function ( v , t , recv , makeWrapper ) {
182
186
if ( t === $jsObjectPtr ) {
183
187
return v ;
184
188
}
@@ -226,7 +230,7 @@ var $internalize = function(v, t, recv) {
226
230
$throwRuntimeError ( "got array with wrong size from JavaScript native" ) ;
227
231
}
228
232
return $mapArray ( v , function ( e ) {
229
- return $internalize ( e , t . elem ) ;
233
+ return $internalize ( e , t . elem , makeWrapper ) ;
230
234
} ) ;
231
235
case $kindFunc :
232
236
return function ( ) {
@@ -236,21 +240,21 @@ var $internalize = function(v, t, recv) {
236
240
var vt = t . params [ i ] . elem ,
237
241
varargs = arguments [ i ] ;
238
242
for ( var j = 0 ; j < varargs . $length ; j ++ ) {
239
- args . push ( $externalize ( varargs . $array [ varargs . $offset + j ] , vt ) ) ;
243
+ args . push ( $externalize ( varargs . $array [ varargs . $offset + j ] , vt , makeWrapper ) ) ;
240
244
}
241
245
break ;
242
246
}
243
- args . push ( $externalize ( arguments [ i ] , t . params [ i ] ) ) ;
247
+ args . push ( $externalize ( arguments [ i ] , t . params [ i ] , makeWrapper ) ) ;
244
248
}
245
249
var result = v . apply ( recv , args ) ;
246
250
switch ( t . results . length ) {
247
251
case 0 :
248
252
return ;
249
253
case 1 :
250
- return $internalize ( result , t . results [ 0 ] ) ;
254
+ return $internalize ( result , t . results [ 0 ] , makeWrapper ) ;
251
255
default :
252
256
for ( var i = 0 ; i < t . results . length ; i ++ ) {
253
- result [ i ] = $internalize ( result [ i ] , t . results [ i ] ) ;
257
+ result [ i ] = $internalize ( result [ i ] , t . results [ i ] , makeWrapper ) ;
254
258
}
255
259
return result ;
256
260
}
@@ -283,45 +287,45 @@ var $internalize = function(v, t, recv) {
283
287
case Float64Array :
284
288
return new ( $sliceType ( $Float64 ) ) ( v ) ;
285
289
case Array :
286
- return $internalize ( v , $sliceType ( $emptyInterface ) ) ;
290
+ return $internalize ( v , $sliceType ( $emptyInterface ) , makeWrapper ) ;
287
291
case Boolean :
288
292
return new $Bool ( ! ! v ) ;
289
293
case Date :
290
294
if ( timePkg === undefined ) {
291
295
/* time package is not present, internalize as &js.Object{Date} so it can be externalized into original Date. */
292
296
return new $jsObjectPtr ( v ) ;
293
297
}
294
- return new timePkg . Time ( $internalize ( v , timePkg . Time ) ) ;
298
+ return new timePkg . Time ( $internalize ( v , timePkg . Time , makeWrapper ) ) ;
295
299
case Function :
296
300
var funcType = $funcType ( [ $sliceType ( $emptyInterface ) ] , [ $jsObjectPtr ] , true ) ;
297
- return new funcType ( $internalize ( v , funcType ) ) ;
301
+ return new funcType ( $internalize ( v , funcType , makeWrapper ) ) ;
298
302
case Number :
299
303
return new $Float64 ( parseFloat ( v ) ) ;
300
304
case String :
301
- return new $String ( $internalize ( v , $String ) ) ;
305
+ return new $String ( $internalize ( v , $String , makeWrapper ) ) ;
302
306
default :
303
307
if ( $global . Node && v instanceof $global . Node ) {
304
308
return new $jsObjectPtr ( v ) ;
305
309
}
306
310
var mapType = $mapType ( $String , $emptyInterface ) ;
307
- return new mapType ( $internalize ( v , mapType ) ) ;
311
+ return new mapType ( $internalize ( v , mapType , makeWrapper ) ) ;
308
312
}
309
313
case $kindMap :
310
314
var m = { } ;
311
315
var keys = $keys ( v ) ;
312
316
for ( var i = 0 ; i < keys . length ; i ++ ) {
313
- var k = $internalize ( keys [ i ] , t . key ) ;
314
- m [ t . key . keyFor ( k ) ] = { k : k , v : $internalize ( v [ keys [ i ] ] , t . elem ) } ;
317
+ var k = $internalize ( keys [ i ] , t . key , makeWrapper ) ;
318
+ m [ t . key . keyFor ( k ) ] = { k : k , v : $internalize ( v [ keys [ i ] ] , t . elem , makeWrapper ) } ;
315
319
}
316
320
return m ;
317
321
case $kindPtr :
318
322
if ( t . elem . kind === $kindStruct ) {
319
- return $internalize ( v , t . elem ) ;
323
+ return $internalize ( v , t . elem , makeWrapper ) ;
320
324
}
321
325
case $kindSlice :
322
326
return new t (
323
327
$mapArray ( v , function ( e ) {
324
- return $internalize ( e , t . elem ) ;
328
+ return $internalize ( e , t . elem , makeWrapper ) ;
325
329
} )
326
330
) ;
327
331
case $kindString :
@@ -386,3 +390,17 @@ var $isASCII = function(s) {
386
390
}
387
391
return true ;
388
392
} ;
393
+
394
+ var $copyIfRequired = function ( v , typ ) {
395
+ // interface values
396
+ if ( v . constructor . copy ) {
397
+ return new v . constructor ( $clone ( v . $val , v . constructor ) ) ;
398
+ }
399
+ // array and struct values
400
+ if ( typ . copy ) {
401
+ var clone = typ . zero ( ) ;
402
+ typ . copy ( clone , v ) ;
403
+ return clone ;
404
+ }
405
+ return v ;
406
+ } ;
0 commit comments