22## Patched to:
33## - add integer pointers (IntPtr)
44## - implement ByteString type
5+ ## - add [Owner] Extended attribute for Pointer Ownership transfer
56## From https://github.com/emscripten-core/emscripten/blob/f36f9fcaf83db93e6a6d0f0cdc47ab6379ade139/tools/webidl_binder.py
67
78# Copyright 2014 The Emscripten Authors. All rights reserved.
@@ -174,6 +175,7 @@ def build_constructor(name):
174175 size: 0, // the size of buffer
175176 pos: 0, // the next free offset in buffer
176177 temps: [], // extra allocations
178+ owned: [], // Owned allocations
177179 needed: 0, // the total size we need next time
178180
179181 prepare: function() {
@@ -197,22 +199,29 @@ def build_constructor(name):
197199 }
198200 ensureCache.pos = 0;
199201 },
200- alloc: function(array, view) {
202+ alloc: function(array, view, owner ) {
201203 assert(ensureCache.buffer);
202204 var bytes = view.BYTES_PER_ELEMENT;
203205 var len = array.length * bytes;
204206 len = (len + 7) & -8; // keep things aligned to 8 byte boundaries
205207 var ret;
206- if (ensureCache.pos + len >= ensureCache.size) {
207- // we failed to allocate in the buffer, ensureCache time around :(
208+ if (owner) {
208209 assert(len > 0); // null terminator, at least
209210 ensureCache.needed += len;
210211 ret = Module['_malloc'](len);
211- ensureCache.temps .push(ret);
212+ ensureCache.owned .push(ret);
212213 } else {
213- // we can allocate in the buffer
214- ret = ensureCache.buffer + ensureCache.pos;
215- ensureCache.pos += len;
214+ if (ensureCache.pos + len >= ensureCache.size) {
215+ // we failed to allocate in the buffer, ensureCache time around :(
216+ assert(len > 0); // null terminator, at least
217+ ensureCache.needed += len;
218+ ret = Module['_malloc'](len);
219+ ensureCache.temps.push(ret);
220+ } else {
221+ // we can allocate in the buffer
222+ ret = ensureCache.buffer + ensureCache.pos;
223+ ensureCache.pos += len;
224+ }
216225 }
217226 return ret;
218227 },
@@ -228,58 +237,73 @@ def build_constructor(name):
228237 view[offset + i] = array[i];
229238 }
230239 },
240+ clear: function(clearOwned) {
241+ for (var i = 0; i < ensureCache.temps.length; i++) {
242+ Module['_free'](ensureCache.temps[i]);
243+ }
244+ if (clearOwned) {
245+ for (var i = 0; i < ensureCache.owned.length; i++) {
246+ Module['_free'](ensureCache.owned[i]);
247+ }
248+ }
249+ ensureCache.temps.length = 0;
250+ Module['_free'](ensureCache.buffer);
251+ ensureCache.buffer = 0;
252+ ensureCache.size = 0;
253+ ensureCache.needed = 0;
254+ }
231255};
232256
233257/** @suppress {duplicate} (TODO: avoid emitting this multiple times, it is redundant) */
234- function ensureString(value) {
258+ function ensureString(value, owner ) {
235259 if (typeof value === 'string') {
236260 var intArray = intArrayFromString(value);
237- var offset = ensureCache.alloc(intArray, HEAP8);
261+ var offset = ensureCache.alloc(intArray, HEAP8, owner );
238262 ensureCache.copy(intArray, HEAP8, offset);
239263 return offset;
240264 }
241265 return value;
242266}
243267/** @suppress {duplicate} (TODO: avoid emitting this multiple times, it is redundant) */
244- function ensureInt8(value) {
268+ function ensureInt8(value, owner ) {
245269 if (typeof value === 'object') {
246- var offset = ensureCache.alloc(value, HEAP8);
270+ var offset = ensureCache.alloc(value, HEAP8, owner );
247271 ensureCache.copy(value, HEAP8, offset);
248272 return offset;
249273 }
250274 return value;
251275}
252276/** @suppress {duplicate} (TODO: avoid emitting this multiple times, it is redundant) */
253- function ensureInt16(value) {
277+ function ensureInt16(value, owner ) {
254278 if (typeof value === 'object') {
255- var offset = ensureCache.alloc(value, HEAP16);
279+ var offset = ensureCache.alloc(value, HEAP16, owner );
256280 ensureCache.copy(value, HEAP16, offset);
257281 return offset;
258282 }
259283 return value;
260284}
261285/** @suppress {duplicate} (TODO: avoid emitting this multiple times, it is redundant) */
262- function ensureInt32(value) {
286+ function ensureInt32(value, owner ) {
263287 if (typeof value === 'object') {
264- var offset = ensureCache.alloc(value, HEAP32);
288+ var offset = ensureCache.alloc(value, HEAP32, owner );
265289 ensureCache.copy(value, HEAP32, offset);
266290 return offset;
267291 }
268292 return value;
269293}
270294/** @suppress {duplicate} (TODO: avoid emitting this multiple times, it is redundant) */
271- function ensureFloat32(value) {
295+ function ensureFloat32(value, owner ) {
272296 if (typeof value === 'object') {
273- var offset = ensureCache.alloc(value, HEAPF32);
297+ var offset = ensureCache.alloc(value, HEAPF32, owner );
274298 ensureCache.copy(value, HEAPF32, offset);
275299 return offset;
276300 }
277301 return value;
278302}
279303/** @suppress {duplicate} (TODO: avoid emitting this multiple times, it is redundant) */
280- function ensureFloat64(value) {
304+ function ensureFloat64(value, owner ) {
281305 if (typeof value === 'object') {
282- var offset = ensureCache.alloc(value, HEAPF64);
306+ var offset = ensureCache.alloc(value, HEAPF64, owner );
283307 ensureCache.copy(value, HEAPF64, offset);
284308 return offset;
285309 }
@@ -390,7 +414,7 @@ def type_to_cdec(raw):
390414
391415def render_function (class_name , func_name , sigs , return_type , non_pointer ,
392416 copy , operator , constructor , func_scope ,
393- call_content = None , const = False , array_attribute = False ):
417+ call_content = None , const = False , owned = False , array_attribute = False ):
394418 legacy_mode = CHECKS not in ['ALL' , 'FAST' ]
395419 all_checks = CHECKS == 'ALL'
396420
@@ -505,20 +529,20 @@ def render_function(class_name, func_name, sigs, return_type, non_pointer,
505529 if not (arg .type .isArray () and not array_attribute ):
506530 body += " if ({0} && typeof {0} === 'object') {0} = {0}.ptr;\n " .format (js_arg )
507531 if arg .type .isString ():
508- body += " else {0} = ensureString({0});\n " .format (js_arg )
532+ body += " else {0} = ensureString({0}, {1} );\n " .format (js_arg , "true" if ( owned ) else "false" )
509533 else :
510534 # an array can be received here
511535 arg_type = arg .type .name
512536 if arg_type in ['Byte' , 'Octet' ]:
513- body += " if (typeof {0} == 'object') {{ {0} = ensureInt8({0}); }}\n " .format (js_arg )
537+ body += " if (typeof {0} == 'object') {{ {0} = ensureInt8({0}, {1} ); }}\n " .format (js_arg , "true" if ( owned ) else "false" )
514538 elif arg_type in ['Short' , 'UnsignedShort' ]:
515- body += " if (typeof {0} == 'object') {{ {0} = ensureInt16({0}); }}\n " .format (js_arg )
539+ body += " if (typeof {0} == 'object') {{ {0} = ensureInt16({0}, {1} ); }}\n " .format (js_arg , "true" if ( owned ) else "false" )
516540 elif arg_type in ['Long' , 'UnsignedLong' ]:
517- body += " if (typeof {0} == 'object') {{ {0} = ensureInt32({0}); }}\n " .format (js_arg )
541+ body += " if (typeof {0} == 'object') {{ {0} = ensureInt32({0}, {1} ); }}\n " .format (js_arg , "true" if ( owned ) else "false" )
518542 elif arg_type == 'Float' :
519- body += " if (typeof {0} == 'object') {{ {0} = ensureFloat32({0}); }}\n " .format (js_arg )
543+ body += " if (typeof {0} == 'object') {{ {0} = ensureFloat32({0}, {1} ); }}\n " .format (js_arg , "true" if ( owned ) else "false" )
520544 elif arg_type == 'Double' :
521- body += " if (typeof {0} == 'object') {{ {0} = ensureFloat64({0}); }}\n " .format (js_arg )
545+ body += " if (typeof {0} == 'object') {{ {0} = ensureFloat64({0}, {1} ); }}\n " .format (js_arg , "true" if ( owned ) else "false" )
522546
523547 c_names = {}
524548 for i in range (min_args , max_args ):
@@ -737,6 +761,7 @@ def render_function(class_name, func_name, sigs, return_type, non_pointer,
737761 func_scope = interface ,
738762 call_content = get_call_content ,
739763 const = m .getExtendedAttribute ('Const' ),
764+ owned = m .getExtendedAttribute ('Owner' ),
740765 array_attribute = m .type .isArray ())
741766
742767 if m .readonly :
@@ -755,6 +780,7 @@ def render_function(class_name, func_name, sigs, return_type, non_pointer,
755780 func_scope = interface ,
756781 call_content = set_call_content ,
757782 const = m .getExtendedAttribute ('Const' ),
783+ owned = m .getExtendedAttribute ('Owner' ),
758784 array_attribute = m .type .isArray ())
759785 mid_js += [r'''
760786 Object.defineProperty(%s.prototype, '%s', { get: %s.prototype.%s, set: %s.prototype.%s });''' % (name , attr , name , get_name , name , set_name )]
0 commit comments