diff --git a/.gitignore b/.gitignore index 6422124..a8a0c39 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ tmp package-lock.json /*.html /build +soljson.js diff --git a/Makefile b/Makefile index 2b08368..9f1491d 100644 --- a/Makefile +++ b/Makefile @@ -1,18 +1,21 @@ .PHONY: install format test test-solidity test-cli test-integration test-workspace clean docs docs-build RUSTFLAGS_EMSCRIPTEN := \ - -Clink-arg=-sEXPORTED_FUNCTIONS=_main,_free,_malloc \ - -Clink-arg=-sNO_INVOKE_RUN \ - -Clink-arg=-sEXIT_RUNTIME \ - -Clink-arg=-sINITIAL_MEMORY=64MB \ - -Clink-arg=-sTOTAL_MEMORY=3GB \ - -Clink-arg=-sALLOW_MEMORY_GROWTH \ - -Clink-arg=-sEXPORTED_RUNTIME_METHODS=FS,callMain,stringToNewUTF8,cwrap \ - -Clink-arg=-sMODULARIZE \ - -Clink-arg=-sEXPORT_NAME=createRevive \ - -Clink-arg=-sWASM_ASYNC_COMPILATION=0 \ - -Clink-arg=--js-library=js/embed/soljson_interface.js \ - -Clink-arg=--pre-js=js/embed/pre.js + -C link-arg=-sEXPORTED_FUNCTIONS=_main,_free,_malloc \ + -C link-arg=-sNO_INVOKE_RUN=1 \ + -C link-arg=-sEXIT_RUNTIME=1 \ + -C link-arg=-sALLOW_MEMORY_GROWTH=1 \ + -C link-arg=-sEXPORTED_RUNTIME_METHODS=FS,callMain,stringToNewUTF8 \ + -C link-arg=-sMODULARIZE=1 \ + -C link-arg=-sEXPORT_NAME=createRevive \ + -C link-arg=-sWASM_ASYNC_COMPILATION=0 \ + -C link-arg=-sDYNAMIC_EXECUTION=0 \ + -C link-arg=-sALLOW_TABLE_GROWTH=1 \ + -C link-arg=--js-library=js/embed/soljson_interface.js \ + -C link-arg=--pre-js=js/embed/pre.js \ + -C link-arg=-sNODEJS_CATCH_EXIT=0 \ + -C link-arg=-sDISABLE_EXCEPTION_CATCHING=0 \ + -C opt-level=3 install: install-bin install-npm diff --git a/RELEASE.md b/RELEASE.md index 4316fd6..8d8547d 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -8,4 +8,5 @@ To create a new pre-release: 2. Push a release tag to `main` 3. Manually trigger the `Build revive-debian` action 4. Create a __pre-release__ from the tag and manually upload the build artifact generated by the action -5. Update the [contract-docs](https://github.com/paritytech/contract-docs/) accordingly +5. Manually upload `resolc.js` and `resolc.wasm` from the `build-revive-wasm` action artifacts. +6. Update the [contract-docs](https://github.com/paritytech/contract-docs/) accordingly diff --git a/js/embed/pre.js b/js/embed/pre.js index 745723c..5ab4e3d 100644 --- a/js/embed/pre.js +++ b/js/embed/pre.js @@ -1,47 +1,52 @@ var Module = { - stdinData: "", - stdoutCallback: null, - stderrCallback: null, + stdinData: null, + stdinDataPosition: 0, + stdoutData: [], + stderrData: [], - // Function to set a callback for stdout - setStdoutCallback: function(callback) { - this.stdoutCallback = callback; + // Function to read and return all collected stdout data as a string + readFromStdout: function() { + if (!this.stdoutData.length) return ""; + const decoder = new TextDecoder('utf-8'); + const data = decoder.decode(new Uint8Array(this.stdoutData)); + this.stdoutData = []; + return data; }, - // Function to set a callback for stderr - setStderrCallback: function(callback) { - this.stderrCallback = callback; + // Function to read and return all collected stderr data as a string + readFromStderr: function() { + if (!this.stderrData.length) return ""; + const decoder = new TextDecoder('utf-8'); + const data = decoder.decode(new Uint8Array(this.stderrData)); + this.stderrData = []; + return data; }, // Function to set input data for stdin - setStdinData: function(data) { - this.stdinData = data; + writeToStdin: function(data) { + const encoder = new TextEncoder(); + this.stdinData = encoder.encode(data); + this.stdinDataPosition = 0; }, // `preRun` is called before the program starts running preRun: function() { // Define a custom stdin function function customStdin() { - if (Module.stdinData.length === 0) { + if (!Module.stdinData || Module.stdinDataPosition >= Module.stdinData.length) { return null; // End of input (EOF) } - const char = Module.stdinData.charCodeAt(0); - Module.stdinData = Module.stdinData.slice(1); // Remove the character from input - return char; + return Module.stdinData[Module.stdinDataPosition++]; } // Define a custom stdout function function customStdout(char) { - if (Module.stdoutCallback) { - Module.stdoutCallback(String.fromCharCode(char)); - } + Module.stdoutData.push(char); } // Define a custom stderr function function customStderr(char) { - if (Module.stderrCallback) { - Module.stderrCallback(String.fromCharCode(char)); - } + Module.stderrData.push(char); } FS.init(customStdin, customStdout, customStderr); diff --git a/js/embed/soljson_interface.js b/js/embed/soljson_interface.js index cefff55..f9ee68d 100644 --- a/js/embed/soljson_interface.js +++ b/js/embed/soljson_interface.js @@ -24,28 +24,17 @@ mergeInto(LibraryManager.library, { } else { throw new Error('Unknown environment: Unable to load resolc.js'); } - revive.setStdinData(inputJson); - - let stdoutString = ""; - revive.setStdoutCallback(function(char) { - if (char.charCodeAt(0) === '\n') { - exit; - } - stdoutString += char; - }); - - let stderrString = ""; - revive.setStderrCallback(function(char) { - stderrString += char; - }); + revive.writeToStdin(inputJson); // Call main on the new instance const result = revive.callMain(['--recursive-process']); if (result) { + const stderrString = revive.readFromStderr(); const error = JSON.stringify({ type: 'error', message: stderrString || "Unknown error" }); return stringToNewUTF8(error); } else { + const stdoutString = revive.readFromStdout(); const json = JSON.stringify({ type: 'success', data: stdoutString }); return stringToNewUTF8(json); } diff --git a/js/examples/node/run_revive.js b/js/examples/node/run_revive.js index bd6b10c..dec99ac 100644 --- a/js/examples/node/run_revive.js +++ b/js/examples/node/run_revive.js @@ -34,26 +34,12 @@ async function runCompiler() { m.soljson = soljson; // Set input data for stdin - m.setStdinData(JSON.stringify(compilerStandardJsonInput)); - - var stdoutString = ""; - m.setStdoutCallback(function(char) { - if (char.charCodeAt(0) === '\n') { - console.log("new line") - exit - } - stdoutString += char; - }); - - var stderrString = ""; - m.setStderrCallback(function(char) { - stderrString += char; - }); + m.writeToStdin(JSON.stringify(compilerStandardJsonInput)); // Compile the Solidity source code let x = m.callMain(['--standard-json']); - console.log("Stdout: " + stdoutString); - console.error("Stderr: " + stderrString); + console.log("Stdout: " + m.readFromStdout()); + console.error("Stderr: " + m.readFromStderr()); } runCompiler().catch(err => { diff --git a/js/examples/web/worker.js b/js/examples/web/worker.js index 68cd0b7..5ed8dd1 100644 --- a/js/examples/web/worker.js +++ b/js/examples/web/worker.js @@ -29,24 +29,10 @@ onmessage = async function (e) { m.soljson = Module; // Set input data for stdin - m.setStdinData(JSON.stringify(sourceCode)); - - var stdoutString = ""; - m.setStdoutCallback(function(char) { - if (char.charCodeAt(0) === '\n') { - console.log("new line") - exit - } - stdoutString += char; - }); - - var stderrString = ""; - m.setStderrCallback(function(char) { - stderrString += char; - }); + m.writeToStdin(JSON.stringify(sourceCode)); // Compile the Solidity source code m.callMain(['--standard-json']); - postMessage({output: stdoutString || stderrString}); + postMessage({output: m.readFromStdout() || m.readFromStderr()}); };