Buckets:
| // Copyright 2023 The Emscripten Authors. All rights reserved. | |
| // Emscripten is available under two separate licenses, the MIT license and the | |
| // University of Illinois/NCSA Open Source License. Both these licenses can be | |
| // found in the LICENSE file. | |
| var LibraryEmbindShared = { | |
| $InternalError: "= class InternalError extends Error { constructor(message) { super(message); this.name = 'InternalError'; }}", | |
| $BindingError: "= class BindingError extends Error { constructor(message) { super(message); this.name = 'BindingError'; }}", | |
| $throwInternalError__deps: ['$InternalError'], | |
| $throwInternalError: (message) => { throw new InternalError(message); }, | |
| $throwBindingError__deps: ['$BindingError'], | |
| $throwBindingError: (message) => { throw new BindingError(message); }, | |
| // typeID -> { toWireType: ..., fromWireType: ... } | |
| $registeredTypes: {}, | |
| // typeID -> [callback] | |
| $awaitingDependencies: {}, | |
| // typeID -> [dependentTypes] | |
| $typeDependencies: {}, | |
| $tupleRegistrations: {}, | |
| $structRegistrations: {}, | |
| $sharedRegisterType__deps: [ | |
| '$awaitingDependencies', '$registeredTypes', | |
| '$typeDependencies', '$throwBindingError' ], | |
| $sharedRegisterType__docs: '/** @param {Object=} options */', | |
| $sharedRegisterType: function(rawType, registeredInstance, options = {}) { | |
| var name = registeredInstance.name; | |
| if (!rawType) { | |
| throwBindingError(`type "${name}" must have a positive integer typeid pointer`); | |
| } | |
| if (registeredTypes.hasOwnProperty(rawType)) { | |
| if (options.ignoreDuplicateRegistrations) { | |
| return; | |
| } else { | |
| throwBindingError(`Cannot register type '${name}' twice`); | |
| } | |
| } | |
| registeredTypes[rawType] = registeredInstance; | |
| delete typeDependencies[rawType]; | |
| if (awaitingDependencies.hasOwnProperty(rawType)) { | |
| var callbacks = awaitingDependencies[rawType]; | |
| delete awaitingDependencies[rawType]; | |
| callbacks.forEach((cb) => cb()); | |
| } | |
| }, | |
| $whenDependentTypesAreResolved__deps: [ | |
| '$awaitingDependencies', '$registeredTypes', | |
| '$typeDependencies', '$throwInternalError'], | |
| $whenDependentTypesAreResolved: (myTypes, dependentTypes, getTypeConverters) => { | |
| myTypes.forEach((type) => typeDependencies[type] = dependentTypes); | |
| function onComplete(typeConverters) { | |
| var myTypeConverters = getTypeConverters(typeConverters); | |
| if (myTypeConverters.length !== myTypes.length) { | |
| throwInternalError('Mismatched type converter count'); | |
| } | |
| for (var i = 0; i < myTypes.length; ++i) { | |
| registerType(myTypes[i], myTypeConverters[i]); | |
| } | |
| } | |
| var typeConverters = new Array(dependentTypes.length); | |
| var unregisteredTypes = []; | |
| var registered = 0; | |
| for (let [i, dt] of dependentTypes.entries()) { | |
| if (registeredTypes.hasOwnProperty(dt)) { | |
| typeConverters[i] = registeredTypes[dt]; | |
| } else { | |
| unregisteredTypes.push(dt); | |
| if (!awaitingDependencies.hasOwnProperty(dt)) { | |
| awaitingDependencies[dt] = []; | |
| } | |
| awaitingDependencies[dt].push(() => { | |
| typeConverters[i] = registeredTypes[dt]; | |
| ++registered; | |
| if (registered === unregisteredTypes.length) { | |
| onComplete(typeConverters); | |
| } | |
| }); | |
| } | |
| } | |
| if (0 === unregisteredTypes.length) { | |
| onComplete(typeConverters); | |
| } | |
| }, | |
| $getTypeName__deps: ['$AsciiToString', '__getTypeName', 'free'], | |
| $getTypeName: (type) => { | |
| var ptr = ___getTypeName(type); | |
| var rv = AsciiToString(ptr); | |
| _free(ptr); | |
| return rv; | |
| }, | |
| $getFunctionName__deps: [], | |
| $getFunctionName: (signature) => { | |
| signature = signature.trim(); | |
| const argsIndex = signature.indexOf("("); | |
| if (argsIndex === -1) return signature; | |
| #if ASSERTIONS | |
| assert(signature.endsWith(")"), "Parentheses for argument names should match."); | |
| #endif | |
| return signature.slice(0, argsIndex); | |
| }, | |
| $getFunctionArgsName__deps: [], | |
| $getFunctionArgsName: (signature) => { | |
| signature = signature.trim(); | |
| const argsIndex = signature.indexOf("("); | |
| if (argsIndex == -1) return; // Return undefined to mean we don't have any argument names | |
| #if ASSERTIONS | |
| assert(signature.endsWith(")"), "Parentheses for argument names should match."); | |
| #endif | |
| return signature.slice(argsIndex + 1, -1).replaceAll(" ", "").split(",").filter(n => n.length); | |
| }, | |
| $heap32VectorToArray: (count, firstElement) => { | |
| var array = []; | |
| for (var i = 0; i < count; i++) { | |
| // TODO(https://github.com/emscripten-core/emscripten/issues/17310): | |
| // Find a way to hoist the `>> 2` or `>> 3` out of this loop. | |
| array.push({{{ makeGetValue('firstElement', `i * ${POINTER_SIZE}`, '*') }}}); | |
| } | |
| return array; | |
| }, | |
| $requireRegisteredType__deps: [ | |
| '$registeredTypes', '$getTypeName', '$throwBindingError'], | |
| $requireRegisteredType: (rawType, humanName) => { | |
| var impl = registeredTypes[rawType]; | |
| if (undefined === impl) { | |
| throwBindingError(`${humanName} has unknown type ${getTypeName(rawType)}`); | |
| } | |
| return impl; | |
| }, | |
| $usesDestructorStack(argTypes) { | |
| // Skip return value at index 0 - it's not deleted here. | |
| for (var i = 1; i < argTypes.length; ++i) { | |
| // The type does not define a destructor function - must use dynamic stack | |
| if (argTypes[i] !== null && argTypes[i].destructorFunction === undefined) { | |
| return true; | |
| } | |
| } | |
| return false; | |
| }, | |
| // Many of the JS invoker functions are generic and can be reused for multiple | |
| // function bindings. This function needs to match createJsInvoker and create | |
| // a unique signature for any inputs that will create different invoker | |
| // function outputs. | |
| $createJsInvokerSignature(argTypes, isClassMethodFunc, returns, isAsync) { | |
| const signature = [ | |
| isClassMethodFunc ? 't' : 'f', | |
| returns ? 't' : 'f', | |
| isAsync ? 't' : 'f' | |
| ]; | |
| for (let i = isClassMethodFunc ? 1 : 2; i < argTypes.length; ++i) { | |
| const arg = argTypes[i]; | |
| let destructorSig = ''; | |
| if (arg.destructorFunction === undefined) { | |
| destructorSig = 'u'; | |
| } else if (arg.destructorFunction === null) { | |
| destructorSig = 'n'; | |
| } else { | |
| destructorSig = 't'; | |
| } | |
| signature.push(destructorSig); | |
| } | |
| return signature.join(''); | |
| }, | |
| $checkArgCount(numArgs, minArgs, maxArgs, humanName, throwBindingError) { | |
| if (numArgs < minArgs || numArgs > maxArgs) { | |
| var argCountMessage = minArgs == maxArgs ? minArgs : `${minArgs} to ${maxArgs}`; | |
| throwBindingError(`function ${humanName} called with ${numArgs} arguments, expected ${argCountMessage}`); | |
| } | |
| }, | |
| $getEnumValueType(rawValueType) { | |
| // This must match the values of enum_value_type in wire.h | |
| return rawValueType === 0 ? 'object' : (rawValueType === 1 ? 'number' : 'string'); | |
| }, | |
| $getRequiredArgCount(argTypes) { | |
| var requiredArgCount = argTypes.length - 2; | |
| for (var i = argTypes.length - 1; i >= 2; --i) { | |
| if (!argTypes[i].optional) { | |
| break; | |
| } | |
| requiredArgCount--; | |
| } | |
| return requiredArgCount; | |
| }, | |
| $createJsInvoker__deps: ['$usesDestructorStack', | |
| #if ASSERTIONS | |
| '$checkArgCount', | |
| #endif | |
| ], | |
| $createJsInvoker(argTypes, isClassMethodFunc, returns, isAsync) { | |
| var needsDestructorStack = usesDestructorStack(argTypes); | |
| var argCount = argTypes.length - 2; | |
| var argsList = []; | |
| var argsListWired = ['fn']; | |
| if (isClassMethodFunc) { | |
| argsListWired.push('thisWired'); | |
| } | |
| for (var i = 0; i < argCount; ++i) { | |
| argsList.push(`arg${i}`) | |
| argsListWired.push(`arg${i}Wired`) | |
| } | |
| argsList = argsList.join(',') | |
| argsListWired = argsListWired.join(',') | |
| var invokerFnBody = `return function (${argsList}) {\n`; | |
| #if ASSERTIONS | |
| invokerFnBody += "checkArgCount(arguments.length, minArgs, maxArgs, humanName, throwBindingError);\n"; | |
| #endif | |
| #if EMSCRIPTEN_TRACING | |
| invokerFnBody += `Module.emscripten_trace_enter_context('embind::' + humanName );\n`; | |
| #endif | |
| if (needsDestructorStack) { | |
| invokerFnBody += "var destructors = [];\n"; | |
| } | |
| var dtorStack = needsDestructorStack ? "destructors" : "null"; | |
| var args1 = ["humanName", "throwBindingError", "invoker", "fn", "runDestructors", "fromRetWire", "toClassParamWire"]; | |
| #if EMSCRIPTEN_TRACING | |
| args1.push("Module"); | |
| #endif | |
| if (isClassMethodFunc) { | |
| invokerFnBody += `var thisWired = toClassParamWire(${dtorStack}, this);\n`; | |
| } | |
| for (var i = 0; i < argCount; ++i) { | |
| var argName = `toArg${i}Wire`; | |
| invokerFnBody += `var arg${i}Wired = ${argName}(${dtorStack}, arg${i});\n`; | |
| args1.push(argName); | |
| } | |
| invokerFnBody += (returns || isAsync ? "var rv = ":"") + `invoker(${argsListWired});\n`; | |
| var returnVal = returns ? "rv" : ""; | |
| #if ASYNCIFY == 1 | |
| args1.push("Asyncify"); | |
| #endif | |
| #if ASYNCIFY | |
| invokerFnBody += `function onDone(${returnVal}) {\n`; | |
| #endif | |
| if (needsDestructorStack) { | |
| invokerFnBody += "runDestructors(destructors);\n"; | |
| } else { | |
| for (var i = isClassMethodFunc?1:2; i < argTypes.length; ++i) { // Skip return value at index 0 - it's not deleted here. Also skip class type if not a method. | |
| var paramName = (i === 1 ? "thisWired" : ("arg"+(i - 2)+"Wired")); | |
| if (argTypes[i].destructorFunction !== null) { | |
| invokerFnBody += `${paramName}_dtor(${paramName});\n`; | |
| args1.push(`${paramName}_dtor`); | |
| } | |
| } | |
| } | |
| if (returns) { | |
| invokerFnBody += "var ret = fromRetWire(rv);\n" + | |
| #if EMSCRIPTEN_TRACING | |
| "Module.emscripten_trace_exit_context();\n" + | |
| #endif | |
| "return ret;\n"; | |
| } else { | |
| #if EMSCRIPTEN_TRACING | |
| invokerFnBody += "Module.emscripten_trace_exit_context();\n"; | |
| #endif | |
| } | |
| #if ASYNCIFY == 1 | |
| invokerFnBody += "}\n"; | |
| invokerFnBody += `return Asyncify.currData ? Asyncify.whenDone().then(onDone) : onDone(${returnVal});\n` | |
| #elif ASYNCIFY == 2 | |
| invokerFnBody += "}\n"; | |
| invokerFnBody += "return " + (isAsync ? "rv.then(onDone)" : `onDone(${returnVal})`) + ";"; | |
| #endif | |
| invokerFnBody += "}\n"; | |
| #if ASSERTIONS | |
| args1.push('checkArgCount', 'minArgs', 'maxArgs'); | |
| invokerFnBody = `if (arguments.length !== ${args1.length}){ throw new Error(humanName + "Expected ${args1.length} closure arguments " + arguments.length + " given."); }\n${invokerFnBody}`; | |
| #endif | |
| return new Function(args1, invokerFnBody); | |
| } | |
| }; | |
| addToLibrary(LibraryEmbindShared); | |
Xet Storage Details
- Size:
- 10.5 kB
- Xet hash:
- 0e68f21a41eb73c02f8ce6c7c7ef809df55b28779e5d0a2192e7e159627b377c
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.