mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-06-09 20:01:05 +00:00
Initial wasm support
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { fileURLToPath } from 'url';
|
||||
import path from 'path';
|
||||
import vm from 'vm';
|
||||
import { createRequire } from 'module';
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
// Import the Emscripten module
|
||||
import ModuleFactory from './resolc.mjs';
|
||||
|
||||
async function initializeSolc() {
|
||||
// Load soljson.js
|
||||
const soljsonPath = path.join('./', 'soljson.js');
|
||||
const soljsonCode = readFileSync(soljsonPath, 'utf8');
|
||||
|
||||
// Create a new VM context and run soljson.js in it
|
||||
const soljsonContext = { Module: {} };
|
||||
vm.createContext(soljsonContext); // Create a new context
|
||||
vm.runInContext(soljsonCode, soljsonContext); // Execute soljson.js in the new context
|
||||
|
||||
// Return the initialized soljson module
|
||||
return soljsonContext.Module;
|
||||
}
|
||||
|
||||
async function runCompiler() {
|
||||
const soljson = await initializeSolc();
|
||||
const Module = await ModuleFactory();
|
||||
|
||||
// Expose soljson in the Module context
|
||||
Module.soljson = soljson;
|
||||
|
||||
// Create input Solidity source code
|
||||
const input = `
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8;
|
||||
contract Baseline {
|
||||
function baseline() public payable {}
|
||||
}`;
|
||||
|
||||
// Write the input Solidity code to the Emscripten file system
|
||||
Module.FS.writeFile('./input.sol', input);
|
||||
|
||||
// Compile the Solidity source code
|
||||
Module.callMain(['./input.sol', '-O3','--bin']);
|
||||
}
|
||||
|
||||
runCompiler().catch(err => {
|
||||
console.error('Error:', err);
|
||||
});
|
||||
+111
File diff suppressed because one or more lines are too long
@@ -0,0 +1,58 @@
|
||||
mergeInto(LibraryManager.library, {
|
||||
soljson_compile: function(inputPtr, inputLen) {
|
||||
var inputJson = UTF8ToString(inputPtr, inputLen);
|
||||
var output = Module.soljson.cwrap('solidity_compile', 'string', ['string'])(inputJson);
|
||||
return stringToNewUTF8(output)
|
||||
},
|
||||
soljson_version: function() {
|
||||
var version = Module.soljson.cwrap("solidity_version", "string", [])();
|
||||
return stringToNewUTF8(version)
|
||||
},
|
||||
resolc_compile: function(inputPtr, inputLen) {
|
||||
const { Worker } = require('worker_threads');
|
||||
const deasync = require('deasync');
|
||||
|
||||
var inputJson = UTF8ToString(inputPtr, inputLen);
|
||||
function compileWithWorker(inputJson, callback) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Create a new Worker
|
||||
const worker = new Worker('./worker.js');
|
||||
|
||||
// Listen for messages from the worker
|
||||
worker.on('message', (message) => {
|
||||
resolve(message.output); // Resolve the promise with the output
|
||||
callback(null, message.output);
|
||||
worker.terminate(); // Terminate the worker after processing
|
||||
});
|
||||
|
||||
// Listen for errors from the worker
|
||||
worker.on('error', (error) => {
|
||||
reject(error);
|
||||
callback(error);
|
||||
worker.terminate();
|
||||
});
|
||||
|
||||
// Send the input JSON to the worker
|
||||
worker.postMessage(inputJson);
|
||||
});
|
||||
}
|
||||
let result = null;
|
||||
let error = null;
|
||||
|
||||
// Use deasync to block until promise resolves
|
||||
compileWithWorker(inputJson, function (err, res) {
|
||||
error = err;
|
||||
result = res;
|
||||
});
|
||||
// TODO: deasync is not present in browsers, another solution needs to be implemented
|
||||
deasync.loopWhile(() => result === null && error === null);
|
||||
|
||||
if (error) {
|
||||
const errorJson = JSON.stringify({ type: 'error', message: error.message || "Unknown error" });
|
||||
return stringToNewUTF8(errorJson)
|
||||
}
|
||||
|
||||
const resultJson = JSON.stringify({ type: 'success', data: result });
|
||||
return stringToNewUTF8(resultJson);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
// worker.js
|
||||
// nodejs version
|
||||
const { parentPort } = require('worker_threads');
|
||||
|
||||
parentPort.on('message', async (inputJson) => {
|
||||
const { default: ModuleFactory } = await import('./resolc.mjs');
|
||||
const newModule = await ModuleFactory();
|
||||
|
||||
// Create a virtual file for stdin
|
||||
newModule.FS.writeFile('/in', inputJson);
|
||||
|
||||
// Call main on the new instance
|
||||
const output = newModule.callMain(['--recursive-process']);
|
||||
|
||||
// Check the /err file content
|
||||
const errorMessage = newModule.FS.readFile('/err', { encoding: 'utf8' });
|
||||
|
||||
if (errorMessage.length > 0) {
|
||||
// If /err is not empty, throw an error with its content
|
||||
throw new Error(errorMessage);
|
||||
} else {
|
||||
// If no error, read the output file
|
||||
let outputFile = newModule.FS.readFile('/out', { encoding: 'utf8' });
|
||||
parentPort.postMessage({ output: outputFile });
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user