@@ -174,6 +174,7 @@ def build_constructor(name):
174
174
size: 0, // the size of buffer
175
175
pos: 0, // the next free offset in buffer
176
176
temps: [], // extra allocations
177
+ owned: [], // Owned allocations
177
178
needed: 0, // the total size we need next time
178
179
179
180
prepare: function() {
@@ -197,22 +198,29 @@ def build_constructor(name):
197
198
}
198
199
ensureCache.pos = 0;
199
200
},
200
- alloc: function(array, view) {
201
+ alloc: function(array, view, owner ) {
201
202
assert(ensureCache.buffer);
202
203
var bytes = view.BYTES_PER_ELEMENT;
203
204
var len = array.length * bytes;
204
205
len = (len + 7) & -8; // keep things aligned to 8 byte boundaries
205
206
var ret;
206
- if (ensureCache.pos + len >= ensureCache.size) {
207
- // we failed to allocate in the buffer, ensureCache time around :(
207
+ if (owner) {
208
208
assert(len > 0); // null terminator, at least
209
209
ensureCache.needed += len;
210
210
ret = Module['_malloc'](len);
211
- ensureCache.temps .push(ret);
211
+ ensureCache.owned .push(ret);
212
212
} else {
213
- // we can allocate in the buffer
214
- ret = ensureCache.buffer + ensureCache.pos;
215
- ensureCache.pos += len;
213
+ if (ensureCache.pos + len >= ensureCache.size) {
214
+ // we failed to allocate in the buffer, ensureCache time around :(
215
+ assert(len > 0); // null terminator, at least
216
+ ensureCache.needed += len;
217
+ ret = Module['_malloc'](len);
218
+ ensureCache.temps.push(ret);
219
+ } else {
220
+ // we can allocate in the buffer
221
+ ret = ensureCache.buffer + ensureCache.pos;
222
+ ensureCache.pos += len;
223
+ }
216
224
}
217
225
return ret;
218
226
},
@@ -228,58 +236,73 @@ def build_constructor(name):
228
236
view[offset + i] = array[i];
229
237
}
230
238
},
239
+ clear: function(clearOwned) {
240
+ for (var i = 0; i < ensureCache.temps.length; i++) {
241
+ Module['_free'](ensureCache.temps[i]);
242
+ }
243
+ if (clearOwned) {
244
+ for (var i = 0; i < ensureCache.owned.length; i++) {
245
+ Module['_free'](ensureCache.owned[i]);
246
+ }
247
+ }
248
+ ensureCache.temps.length = 0;
249
+ Module['_free'](ensureCache.buffer);
250
+ ensureCache.buffer = 0;
251
+ ensureCache.size = 0;
252
+ ensureCache.needed = 0;
253
+ }
231
254
};
232
255
233
256
/** @suppress {duplicate} (TODO: avoid emitting this multiple times, it is redundant) */
234
- function ensureString(value) {
257
+ function ensureString(value, owner ) {
235
258
if (typeof value === 'string') {
236
259
var intArray = intArrayFromString(value);
237
- var offset = ensureCache.alloc(intArray, HEAP8);
260
+ var offset = ensureCache.alloc(intArray, HEAP8, owner );
238
261
ensureCache.copy(intArray, HEAP8, offset);
239
262
return offset;
240
263
}
241
264
return value;
242
265
}
243
266
/** @suppress {duplicate} (TODO: avoid emitting this multiple times, it is redundant) */
244
- function ensureInt8(value) {
267
+ function ensureInt8(value, owner ) {
245
268
if (typeof value === 'object') {
246
- var offset = ensureCache.alloc(value, HEAP8);
269
+ var offset = ensureCache.alloc(value, HEAP8, owner );
247
270
ensureCache.copy(value, HEAP8, offset);
248
271
return offset;
249
272
}
250
273
return value;
251
274
}
252
275
/** @suppress {duplicate} (TODO: avoid emitting this multiple times, it is redundant) */
253
- function ensureInt16(value) {
276
+ function ensureInt16(value, owner ) {
254
277
if (typeof value === 'object') {
255
- var offset = ensureCache.alloc(value, HEAP16);
278
+ var offset = ensureCache.alloc(value, HEAP16, owner );
256
279
ensureCache.copy(value, HEAP16, offset);
257
280
return offset;
258
281
}
259
282
return value;
260
283
}
261
284
/** @suppress {duplicate} (TODO: avoid emitting this multiple times, it is redundant) */
262
- function ensureInt32(value) {
285
+ function ensureInt32(value, owner ) {
263
286
if (typeof value === 'object') {
264
- var offset = ensureCache.alloc(value, HEAP32);
287
+ var offset = ensureCache.alloc(value, HEAP32, owner );
265
288
ensureCache.copy(value, HEAP32, offset);
266
289
return offset;
267
290
}
268
291
return value;
269
292
}
270
293
/** @suppress {duplicate} (TODO: avoid emitting this multiple times, it is redundant) */
271
- function ensureFloat32(value) {
294
+ function ensureFloat32(value, owner ) {
272
295
if (typeof value === 'object') {
273
- var offset = ensureCache.alloc(value, HEAPF32);
296
+ var offset = ensureCache.alloc(value, HEAPF32, owner );
274
297
ensureCache.copy(value, HEAPF32, offset);
275
298
return offset;
276
299
}
277
300
return value;
278
301
}
279
302
/** @suppress {duplicate} (TODO: avoid emitting this multiple times, it is redundant) */
280
- function ensureFloat64(value) {
303
+ function ensureFloat64(value, owner ) {
281
304
if (typeof value === 'object') {
282
- var offset = ensureCache.alloc(value, HEAPF64);
305
+ var offset = ensureCache.alloc(value, HEAPF64, owner );
283
306
ensureCache.copy(value, HEAPF64, offset);
284
307
return offset;
285
308
}
@@ -390,7 +413,7 @@ def type_to_cdec(raw):
390
413
391
414
def render_function (class_name , func_name , sigs , return_type , non_pointer ,
392
415
copy , operator , constructor , func_scope ,
393
- call_content = None , const = False , array_attribute = False ):
416
+ call_content = None , const = False , owned = False , array_attribute = False ):
394
417
legacy_mode = CHECKS not in ['ALL' , 'FAST' ]
395
418
all_checks = CHECKS == 'ALL'
396
419
@@ -505,20 +528,20 @@ def render_function(class_name, func_name, sigs, return_type, non_pointer,
505
528
if not (arg .type .isArray () and not array_attribute ):
506
529
body += " if ({0} && typeof {0} === 'object') {0} = {0}.ptr;\n " .format (js_arg )
507
530
if arg .type .isString ():
508
- body += " else {0} = ensureString({0});\n " .format (js_arg )
531
+ body += " else {0} = ensureString({0}, {1} );\n " .format (js_arg , "true" if ( owned ) else "false" )
509
532
else :
510
533
# an array can be received here
511
534
arg_type = arg .type .name
512
535
if arg_type in ['Byte' , 'Octet' ]:
513
- body += " if (typeof {0} == 'object') {{ {0} = ensureInt8({0}); }}\n " .format (js_arg )
536
+ body += " if (typeof {0} == 'object') {{ {0} = ensureInt8({0}, {1} ); }}\n " .format (js_arg , "true" if ( owned ) else "false" )
514
537
elif arg_type in ['Short' , 'UnsignedShort' ]:
515
- body += " if (typeof {0} == 'object') {{ {0} = ensureInt16({0}); }}\n " .format (js_arg )
538
+ body += " if (typeof {0} == 'object') {{ {0} = ensureInt16({0}, {1} ); }}\n " .format (js_arg , "true" if ( owned ) else "false" )
516
539
elif arg_type in ['Long' , 'UnsignedLong' ]:
517
- body += " if (typeof {0} == 'object') {{ {0} = ensureInt32({0}); }}\n " .format (js_arg )
540
+ body += " if (typeof {0} == 'object') {{ {0} = ensureInt32({0}, {1} ); }}\n " .format (js_arg , "true" if ( owned ) else "false" )
518
541
elif arg_type == 'Float' :
519
- body += " if (typeof {0} == 'object') {{ {0} = ensureFloat32({0}); }}\n " .format (js_arg )
542
+ body += " if (typeof {0} == 'object') {{ {0} = ensureFloat32({0}, {1} ); }}\n " .format (js_arg , "true" if ( owned ) else "false" )
520
543
elif arg_type == 'Double' :
521
- body += " if (typeof {0} == 'object') {{ {0} = ensureFloat64({0}); }}\n " .format (js_arg )
544
+ body += " if (typeof {0} == 'object') {{ {0} = ensureFloat64({0}, {1} ); }}\n " .format (js_arg , "true" if ( owned ) else "false" )
522
545
523
546
c_names = {}
524
547
for i in range (min_args , max_args ):
@@ -737,6 +760,7 @@ def render_function(class_name, func_name, sigs, return_type, non_pointer,
737
760
func_scope = interface ,
738
761
call_content = get_call_content ,
739
762
const = m .getExtendedAttribute ('Const' ),
763
+ owned = m .getExtendedAttribute ('Owner' ),
740
764
array_attribute = m .type .isArray ())
741
765
742
766
if m .readonly :
@@ -755,6 +779,7 @@ def render_function(class_name, func_name, sigs, return_type, non_pointer,
755
779
func_scope = interface ,
756
780
call_content = set_call_content ,
757
781
const = m .getExtendedAttribute ('Const' ),
782
+ owned = m .getExtendedAttribute ('Owner' ),
758
783
array_attribute = m .type .isArray ())
759
784
mid_js += [r'''
760
785
Object.defineProperty(%s.prototype, '%s', { get: %s.prototype.%s, set: %s.prototype.%s });''' % (name , attr , name , get_name , name , set_name )]
0 commit comments