Buckets:
| /** | |
| * @license | |
| * Copyright 2022 The Emscripten Authors | |
| * SPDX-License-Identifier: MIT | |
| */ | |
| addToLibrary({ | |
| // Returns the C function with a specified identifier (for C++, you need to do manual name mangling) | |
| #if MODULARIZE == 'instance' && !INCLUDE_FULL_LIBRARY | |
| $getCFunc__deps: [() => error('ccall is not yet compatible with MODULARIZE=instance')], | |
| #endif | |
| $getCFunc__internal: true, | |
| $getCFunc: (ident) => { | |
| var func = Module['_' + ident]; // closure exported function | |
| #if ASSERTIONS | |
| assert(func, `Cannot call unknown function ${ident}, make sure it is exported`); | |
| #endif | |
| return func; | |
| }, | |
| // C calling interface. | |
| $ccall__deps: ['$getCFunc', '$writeArrayToMemory', '$stringToUTF8OnStack', '$stackSave', '$stackRestore', '$stackAlloc'], | |
| $ccall__docs: ` | |
| /** | |
| * @param {string|null=} returnType | |
| * @param {Array=} argTypes | |
| * @param {Array=} args | |
| * @param {Object=} opts | |
| */`, | |
| $ccall: (ident, returnType, argTypes, args, opts) => { | |
| // For fast lookup of conversion functions | |
| var toC = { | |
| #if MEMORY64 | |
| 'pointer': (p) => {{{ to64('p') }}}, | |
| #endif | |
| 'string': (str) => { | |
| var ret = 0; | |
| if (str !== null && str !== undefined && str !== 0) { // null string | |
| ret = stringToUTF8OnStack(str); | |
| } | |
| return {{{ to64('ret') }}}; | |
| }, | |
| 'array': (arr) => { | |
| var ret = stackAlloc(arr.length); | |
| writeArrayToMemory(arr, ret); | |
| return {{{ to64('ret') }}}; | |
| } | |
| }; | |
| function convertReturnValue(ret) { | |
| if (returnType === 'string') { | |
| return UTF8ToString({{{ from64Expr('ret') }}}); | |
| } | |
| #if MEMORY64 | |
| if (returnType === 'pointer') return Number(ret); | |
| #elif CAN_ADDRESS_2GB | |
| if (returnType === 'pointer') return ret >>> 0; | |
| #endif | |
| if (returnType === 'boolean') return Boolean(ret); | |
| return ret; | |
| } | |
| var func = getCFunc(ident); | |
| var cArgs = []; | |
| var stack = 0; | |
| #if ASSERTIONS | |
| assert(returnType !== 'array', 'return type should not be "array"'); | |
| #endif | |
| if (args) { | |
| for (var i = 0; i < args.length; i++) { | |
| var converter = toC[argTypes[i]]; | |
| if (converter) { | |
| if (stack === 0) stack = stackSave(); | |
| cArgs[i] = converter(args[i]); | |
| } else { | |
| cArgs[i] = args[i]; | |
| } | |
| } | |
| } | |
| #if ASYNCIFY == 1 | |
| // Data for a previous async operation that was in flight before us. | |
| var previousAsync = Asyncify.currData; | |
| #endif | |
| var ret = func(...cArgs); | |
| function onDone(ret) { | |
| #if ASYNCIFY == 1 | |
| runtimeKeepalivePop(); | |
| #endif | |
| if (stack !== 0) stackRestore(stack); | |
| return convertReturnValue(ret); | |
| } | |
| #if ASYNCIFY | |
| var asyncMode = opts?.async; | |
| #endif | |
| #if ASYNCIFY == 1 | |
| // Keep the runtime alive through all calls. Note that this call might not be | |
| // async, but for simplicity we push and pop in all calls. | |
| runtimeKeepalivePush(); | |
| if (Asyncify.currData != previousAsync) { | |
| #if ASSERTIONS | |
| // A change in async operation happened. If there was already an async | |
| // operation in flight before us, that is an error: we should not start | |
| // another async operation while one is active, and we should not stop one | |
| // either. The only valid combination is to have no change in the async | |
| // data (so we either had one in flight and left it alone, or we didn't have | |
| // one), or to have nothing in flight and to start one. | |
| assert(!(previousAsync && Asyncify.currData), 'We cannot start an async operation when one is already in flight'); | |
| assert(!(previousAsync && !Asyncify.currData), 'We cannot stop an async operation in flight'); | |
| #endif | |
| // This is a new async operation. The wasm is paused and has unwound its stack. | |
| // We need to return a Promise that resolves the return value | |
| // once the stack is rewound and execution finishes. | |
| #if ASSERTIONS | |
| assert(asyncMode, `The call to ${ident} is running asynchronously. If this was intended, add the async option to the ccall/cwrap call.`); | |
| #endif | |
| return Asyncify.whenDone().then(onDone); | |
| } | |
| #endif | |
| #if ASYNCIFY == 2 | |
| if (asyncMode) return ret.then(onDone); | |
| #endif | |
| ret = onDone(ret); | |
| #if ASYNCIFY == 1 | |
| // If this is an async ccall, ensure we return a promise | |
| if (asyncMode) return Promise.resolve(ret); | |
| #endif | |
| return ret; | |
| }, | |
| $cwrap__docs: ` | |
| /** | |
| * @param {string=} returnType | |
| * @param {Array=} argTypes | |
| * @param {Object=} opts | |
| */`, | |
| $cwrap__deps: [ '$ccall', | |
| #if !ASSERTIONS | |
| '$getCFunc', | |
| #endif | |
| ], | |
| $cwrap: (ident, returnType, argTypes, opts) => { | |
| #if !ASSERTIONS | |
| // When the function takes numbers and returns a number, we can just return | |
| // the original function | |
| var numericArgs = !argTypes || argTypes.every((type) => type === 'number' || type === 'boolean'); | |
| var numericRet = returnType !== 'string'; | |
| if (numericRet && numericArgs && !opts) { | |
| return getCFunc(ident); | |
| } | |
| #endif | |
| return (...args) => ccall(ident, returnType, argTypes, args, opts); | |
| }, | |
| }); | |
Xet Storage Details
- Size:
- 5.02 kB
- Xet hash:
- 9ef8c31f9cbc6f3a377355a5dc815d21121544321921019df47290a241e24adb
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.