Module-Objekt

Module ist ein globales JavaScript-Objekt mit Attributen, die von Emscripten-generiertem Code an verschiedenen Punkten seiner Ausführung aufgerufen werden.

Entwickler können eine Implementierung von Module bereitstellen, um die Ausführung des Codes zu steuern. Um beispielsweise zu definieren, wie Benachrichtigungen von Emscripten angezeigt werden, implementieren Entwickler das Attribut Module.print.

Wenn eine Emscripten-Anwendung startet, prüft sie die Werte im Module-Objekt und wendet diese an. Beachten Sie, dass das Ändern der Werte nach dem Start im Allgemeinen nicht funktioniert; in einem Build mit aktivierten ASSERTIONS erhalten Sie in diesem Fall einen Fehler.

Hinweis

Module wird auch verwendet, um den Zugriff auf Emscripten-API-Funktionen (zum Beispiel ccall()) auf sichere Weise zu ermöglichen. Jede exportierte Funktion oder Laufzeitmethode (mittels EXPORTED_FUNCTIONS für kompilierte Funktionen oder EXPORTED_RUNTIME_METHODS für Laufzeitmethoden wie ccall) wird über das Module-Objekt zugänglich sein, ohne dass die Minifizierung den Namen ändert, und der Optimierer wird sicherstellen, dass die Funktion vorhanden bleibt (und nicht als unbenutzt entfernt wird). Siehe den relevanten FAQ-Eintrag.

Erstellen des Module-Objekts

Verwenden Sie die pre-js Option von emcc, um JavaScript-Code hinzuzufügen, der das Module-Objekt mit dem gewünschten Verhalten definiert (oder erweitert).

Wenn nur JavaScript generiert wird (im Gegensatz zu HTML), wird standardmäßig kein Module-Objekt erstellt, und das Verhalten wird vollständig vom Entwickler definiert. Das Erstellen eines Module-Objekts mit dem folgenden Code führt beispielsweise dazu, dass alle Benachrichtigungen vom Programm Aufrufe an alert() sind.

var Module = {
  'print': function(text) { alert('stdout: ' + text) },
  'printErr': function(text) { alert('stderr: ' + text) }
};

Wichtig

Wenn Sie den Closure Compiler für Ihren Code ausführen (was optional ist und mit --closure 1 erfolgen kann), benötigen Sie Anführungszeichen um die Eigenschaften von Module, wie im obigen Beispiel. Zusätzlich müssen Sie Closure für den kompilierten Code zusammen mit der Deklaration von Module ausführen – dies geschieht automatisch für eine --pre-js-Datei.

Beim Generieren von HTML erstellt Emscripten ein Module-Objekt mit Standardmethoden (siehe src/shell.html). In diesem Fall sollten Sie wiederum --pre-js verwenden, aber diesmal fügen Sie Eigenschaften zum bestehenden Module-Objekt hinzu, zum Beispiel

Module['print'] = function(text) { alert('stdout: ' + text) };

Beachten Sie, dass sobald das Module-Objekt von der Haupt-JavaScript-Datei empfangen wird, es zu diesem Zeitpunkt nach Module['print'] und so weiter sucht und diese entsprechend verwendet. Eine spätere Änderung ihrer Werte wird möglicherweise nicht bemerkt.

Kompilierungseinstellungen

Die Compiler-Einstellung INCOMING_MODULE_JS_API steuert, welche Module-Attribute im generierten JS unterstützt werden. Diese Liste enthält standardmäßig häufig verwendete Dinge.

Wenn Sie diese Liste für Ihre Anwendung auf die kleinstmögliche Größe setzen, sparen Sie JS-Code-Größe. Wenn Sie beispielsweise keine Module-Attribute verwenden, können Sie mit -sINCOMING_MODULE_JS_API=[] bauen. Oder, wenn Sie nur wenige verwenden, können Sie diese auflisten, wie folgt: -sINCOMING_MODULE_JS_API=print,printErr.

Beeinflussung der Ausführung

Die folgenden Module-Attribute beeinflussen die Codeausführung. Legen Sie sie fest, um das Verhalten anzupassen.

Module.arguments

Die Kommandozeilenargumente. Der Wert von arguments enthält die Werte, die zurückgegeben werden, wenn kompilierter Code argc und argv überprüft.

Module.buffer

Ermöglicht es Ihnen, einen eigenen ArrayBuffer oder SharedArrayBuffer als Speicher bereitzustellen.

Hinweis

Dies wird nur unterstützt, wenn -sWASM=0. Siehe Module.wasmMemory für WebAssembly-Unterstützung.

Module.wasmMemory

Ermöglicht es Ihnen, einen eigenen WebAssembly.Memory als Speicher bereitzustellen. Die zum Initialisieren des Speichers verwendeten Eigenschaften sollten mit den Compiler-Optionen übereinstimmen.

Wenn Sie beispielsweise INITIAL_MEMORY auf 8 MB ohne Speicherwachstum einstellen, sollte das von Ihnen bereitgestellte wasmMemory (falls vorhanden) sowohl 'initial' als auch 'maximum' auf 128 setzen (aufgrund der WASM-Seitengrößen von 64 KB).

Module.locateFile

Wenn gesetzt, wird diese Methode aufgerufen, wenn die Laufzeit eine Datei laden muss, z. B. eine .wasm WebAssembly-Datei, eine .mem Speicherinitialisierungsdatei oder eine vom Datei-Packer generierte Datei. Die Funktion erhält den relativen Pfad zur Datei, wie im Build-Prozess konfiguriert, und ein prefix (Pfad zum Verzeichnis der Haupt-JavaScript-Datei) und sollte die tatsächliche URL zurückgeben. Dies ermöglicht es Ihnen, Dateipakete oder die .mem-Datei usw. an einem anderen Ort als dem Verzeichnis der JavaScript-Datei (was die Standarderwartung ist) zu hosten, z. B. wenn Sie diese auf einem CDN hosten möchten.

Hinweis

prefix kann ein leerer String sein, wenn locateFile aufgerufen wird, bevor wir das Haupt-JavaScript laden. Dies kann zum Beispiel passieren, wenn ein Dateipaket oder eine Speicherinitialisierungsdatei zuvor geladen wird (vielleicht aus dem HTML, bevor es das Haupt-JavaScript lädt).

Hinweis

Mehrere Module.*PrefixURL-Optionen wurden zugunsten von locateFile veraltet, darunter memoryInitializerPrefixURL, pthreadMainPrefixURL, cdInitializerPrefixURL, filePackagePrefixURL. Um Ihren Code zu aktualisieren, können Sie beispielsweise, wenn Sie Module.memoryInitializerPrefixURL gleich "https://mycdn.com/memory-init-dir/" verwendet haben, dies durch etwas Ähnliches ersetzen

Module['locateFile'] = function(path, prefix) {
  // if it's a mem init file, use a custom dir
  if (path.endsWith(".mem")) return "https://mycdn.com/memory-init-dir/" + path;
  // otherwise, use the default, the prefix (JS file's dir) + the path
  return prefix + path;
}
Module.logReadFiles

Wenn gesetzt, protokolliert stderr, wenn eine Datei gelesen wird.

Module.printWithColors

Steuert, ob Emscripten-Laufzeitbibliotheken versuchen, mit Farben zu drucken. Derzeit betrifft dies nur Sanitizer.

Wenn nicht gesetzt, werden Farben aktiviert, wenn in einem Terminal mit node gedruckt wird.

Wenn auf true gesetzt, werden Farben immer verwendet, wenn möglich. Wenn auf false gesetzt, werden Farben niemals verwendet.

Module.onAbort

Wenn gesetzt, wird diese Funktion aufgerufen, wenn eine abnormale Programmbeendigung auftritt. Dies kann passieren, wenn die C-Methode abort() direkt oder von JavaScript aus aufgerufen wird, oder aufgrund eines schwerwiegenden Problems, z. B. wenn eine notwendige Datei während des Starts nicht abgerufen werden kann (z. B. das Wasm-Binary) usw. Nach dem Aufruf dieser Funktion erfolgt die Programmbeendigung (d.h. Sie können dies nicht verwenden, um stattdessen etwas anderes zu versuchen; eine Wiederherstellung ist hier nicht möglich).

Module.onRuntimeInitialized

Wenn gesetzt, wird diese Funktion aufgerufen, wenn die Laufzeit vollständig initialisiert ist, d.h. wenn kompilierter Code sicher ausgeführt werden kann, was nach Abschluss aller asynchronen Startvorgänge (wie asynchrone WebAssembly-Kompilierung, Dateivorladen usw.) der Fall ist. (Eine Alternative zum Warten auf den Aufruf dieser Funktion ist das Warten auf den Aufruf von main().)

Module.noExitRuntime

Wenn noExitRuntime auf true gesetzt ist, wird die Laufzeit nach Abschluss von run nicht heruntergefahren. Das Herunterfahren der Laufzeit ruft Shutdown-Callbacks auf, z. B. atexit-Aufrufe. Wenn Sie den Code nach dem Abschluss von run() weiter verwenden möchten, ist es notwendig, dies festzulegen. Dies wird automatisch für Sie festgelegt, wenn Sie einen API-Befehl verwenden, der impliziert, dass die Laufzeit nicht heruntergefahren werden soll, z. B. emscripten_set_main_loop.

Module.noInitialRun

Wenn noInitialRun auf true gesetzt ist, wird main() nicht automatisch aufgerufen (Sie können dies später selbst tun). Das Programm ruft weiterhin globale Initialisierungen auf, richtet die Speicherinitialisierung ein und so weiter.

Module.preInit

Eine Funktion (oder ein Array von Funktionen), die vor der Ausführung globaler Initialisierungen, aber nach der grundlegenden Initialisierung der JavaScript-Laufzeit aufgerufen werden muss. Dies wird typischerweise für Dateisystemoperationen verwendet.

Module.preinitializedWebGLContext

Wenn Sie mit gesetztem -sGL_PREINITIALIZED_CONTEXT bauen, können Sie Module.preinitializedWebGLContext auf eine bereits erstellte Instanz eines WebGL-Kontexts setzen, die später bei der Initialisierung von WebGL auf C/C++-Seite verwendet wird. Das Vorerstellen des GL-Kontexts ist nützlich, wenn GL-Side-Loading (Shader-Kompilierung, Texturladen usw.) parallel zu anderen Seitenstartaktionen durchgeführt wird und/oder zur Erkennung der WebGL-Feature-Unterstützung, wie z.B. GL-Version oder komprimierte Texturunterstützung, im Voraus auf einer Seite vor oder parallel zum Laden von kompiliertem Code.

Module.preRun

Ein Array von Funktionen, die direkt vor dem Aufruf von run() aufgerufen werden sollen, aber nach der Definition und Einrichtung der Umgebung, einschließlich globaler Initialisierungen. Dies ist nützlich, um beispielsweise Verzeichnisse und Dateien mit der File System API einzurichten – da dies nach dem Laden der FileSystem API, aber vor dem Start des Programms geschehen muss.

Hinweis

Wenn Code globale Initialisierungen beeinflussen muss, sollte er stattdessen mit preInit ausgeführt werden.

Module.print

Wird aufgerufen, wenn etwas auf die Standardausgabe (stdout) gedruckt wird.

Module.printErr

Wird aufgerufen, wenn etwas auf die Standardfehlerausgabe (stderr) gedruckt wird.

Module.mainScriptUrlOrBlob

Ermöglicht pthread-Worker oder WASM-Worker, die JavaScript-Hauptanwendungsmoduldatei (z. B. main.js) unabhängig von einer URL oder einem Blob zu laden. Die Erstellung von pthread-Worker oder WASM-Worker erfordert das Laden der JavaScript-Hauptanwendungsmoduldatei (z. B. main.js). Standardmäßig laden sie den Inhalt von main.js von der URL von main.js. Wenn die Datei main.js jedoch von einem Blob geladen wurde, ist es nicht möglich, auf die URL von main.js zuzugreifen. Auch wenn main.js von einem Node.JS-Modul-Bundler (z. B. Webpack) gebündelt wird, kann die URL dieses Skripts falsch sein, die URL nach dem Webpack-Bundler führt zu einer falschen URL wie main.chunk.js.

Andere Methoden

Module.destroy(obj)

Diese Methode sollte aufgerufen werden, um C++-Objekte zu zerstören, die in JavaScript mit WebIDL-Bindungen erstellt wurden. Wenn diese Methode nicht aufgerufen wird, kann ein Objekt vom Garbage Collector erfasst werden, aber sein Destruktor wird nicht aufgerufen.

Argumente
  • obj – Das JavaScript-gekapselte C++-Objekt, das zerstört werden soll.

Module.getPreloadedPackage()

Wenn Sie den Download von .data-Dateipaketen für benutzerdefiniertes Caching, Fortschrittsberichterstattung und Fehlerbehandlung manuell verwalten möchten, können Sie den Callback Module.getPreloadedPackage = function(remotePackageName, remotePackageSize) implementieren, um den Inhalt der Datendateien an die Dateiladeskripte zurückzugeben. Der Rückgabewert dieses Callbacks sollte ein Arraybuffer mit dem Inhalt der heruntergeladenen Dateidaten sein. Siehe die Datei test/manual_download_data.html und den Test browser.test_preload_file_with_manual_data_download für ein Beispiel.

Module.instantiateWasm()

Wenn WebAssembly als Ziel dient, ist Module.instantiateWasm eine optionale, vom Benutzer implementierte Callback-Funktion, die von der Emscripten-Laufzeit aufgerufen wird, um die WebAssembly-Instanziierungsaktion durchzuführen. Die Callback-Funktion wird mit zwei Parametern aufgerufen: imports und successCallback. imports ist ein JS-Objekt, das alle Funktionimporten enthält, die an das WebAssembly-Modul bei der Instanziierung übergeben werden müssen, und sobald instanziiert, sollte diese Callback-Funktion successCallback() mit dem generierten WebAssembly-Instanzobjekt aufrufen.

Die Instanziierung kann entweder synchron oder asynchron durchgeführt werden. Der Rückgabewert dieser Funktion sollte das exports-Objekt des instanziierten WebAssembly-Moduls enthalten oder ein leeres Dictionary-Objekt {}, wenn die Instanziierung asynchron durchgeführt wird, oder false, wenn die Instanziierung fehlgeschlagen ist.

Das Überschreiben des WebAssembly-Instanziierungsprozesses über diese Funktion ist nützlich, wenn Sie andere benutzerdefinierte asynchrone Startaktionen oder Downloads haben, die parallel zur WebAssembly-Kompilierung durchgeführt werden können. Die Implementierung dieses Callbacks ermöglicht die parallele Ausführung all dieser Aktionen. Siehe die Datei test/manual_wasm_instantiate.html und den Test browser.test_manual_wasm_instantiate für ein Beispiel, wie diese Konstruktion in der Praxis funktioniert.

Hinweis

Sanitizer oder Quellzuordnung werden derzeit nicht unterstützt, wenn die WebAssembly-Instanziierung mit Module.instantiateWasm überschrieben wird. Die Bereitstellung von Module.instantiateWasm, wenn Quellzuordnung oder Sanitizer aktiviert sind, kann verhindern, dass die WebAssembly-Instanziierung abgeschlossen wird.

Module.onCustomMessage()

Beim Kompilieren mit PROXY_TO_WORKER = 1 (siehe settings.js) ermöglicht dieser Callback (der sowohl auf dem Module-Objekt des Clients als auch des Workers implementiert werden sollte) das Senden benutzerdefinierter Nachrichten und Daten zwischen dem Web-Worker und dem Haupt-Thread (mithilfe der in proxyClient.js und proxyWorker.js definierten Funktion postCustomMessage).

Module.fetchSettings()

Überschreiben Sie das Standardeinstellungsobjekt, das beim Abrufen des Wasm-Moduls aus dem Netzwerk verwendet wird. Dieses Attribut wird als Zeichenfolge erwartet und ist standardmäßig auf { credentials: 'same-origin' } gesetzt.