diff --git a/package.json b/package.json index a65469a329..c0140c500a 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "js-base64": "^2.1.9", "nightwatch": "^0.9.3", "semistandard": "^7.0.0", + "solc": "https://github.com/ethereum/solc-js", "tape": "^4.5.1", "web3": "^0.16.0", "webworkify": "^1.2.1" diff --git a/src/app/compiler-worker.js b/src/app/compiler-worker.js index 6a4cd404be..2cdde94cb2 100644 --- a/src/app/compiler-worker.js +++ b/src/app/compiler-worker.js @@ -1,4 +1,5 @@ -var version = function () { return '(loading)'; }; +var solc = require('solc/wrapper'); + var compileJSON = function () { return ''; }; var missingInputs = []; @@ -8,30 +9,23 @@ module.exports = function (self) { switch (data.cmd) { case 'loadVersion': delete self.Module; - version = null; compileJSON = null; self.importScripts(data.data); - var Module = self.Module; - version = Module.cwrap('version', 'string', []); - if ('_compileJSONCallback' in Module) { - var compileJSONInternal = Module.cwrap('compileJSONCallback', 'string', ['string', 'number', 'number']); - var missingInputCallback = Module.Runtime.addFunction(function (path) { - missingInputs.push(Module.Pointer_stringify(path)); - }); - compileJSON = function (input, optimize) { - return compileJSONInternal(input, optimize, missingInputCallback); - }; - } else if ('_compileJSONMulti' in Module) { - compileJSON = Module.cwrap('compileJSONMulti', 'string', ['string', 'number']); - } else { - compileJSON = Module.cwrap('compileJSON', 'string', ['string', 'number']); - } + var compiler = solc(self.Module); + + compileJSON = function (input, optimize) { + return JSON.stringify(compiler.compile(JSON.parse(input), optimize, function (path) { + missingInputs.push(path); + return { 'error': 'Deferred import' }; + })); + }; + self.postMessage({ cmd: 'versionLoaded', - data: version(), - acceptsMultipleFiles: ('_compileJSONMulti' in Module) + data: compiler.version(), + acceptsMultipleFiles: compiler.supportsMulti }); break; case 'compile': diff --git a/src/app/compiler.js b/src/app/compiler.js index 966e0fb717..c3de62713c 100644 --- a/src/app/compiler.js +++ b/src/app/compiler.js @@ -1,3 +1,5 @@ +var solc = require('solc/wrapper'); + var webworkify = require('webworkify'); var utils = require('./utils'); @@ -65,49 +67,34 @@ function Compiler (editor, renderer, queryParams, handleGithubCall, outputField, function onInternalCompilerLoaded (setVersionText) { if (worker === null) { - var compile; - var missingInputs = []; - var Module = window.Module; - if ('_compileJSONCallback' in Module) { - compilerAcceptsMultipleFiles = true; - var missingInputsCallback = Module.Runtime.addFunction(function (path, contents, error) { - missingInputs.push(Module.Pointer_stringify(path)); - }); - var compileInternal = Module.cwrap('compileJSONCallback', 'string', [ 'string', 'number', 'number' ]); - compile = function (input, optimize) { - missingInputs.length = 0; - return compileInternal(input, optimize, missingInputsCallback); + var compiler = solc(window.Module); + + compilerAcceptsMultipleFiles = compiler.supportsMulti; + + compileJSON = function (source, optimize, cb) { + var missingInputs = []; + var missingInputsCallback = function (path) { + missingInputs.push(path); + return { error: 'Deferred import' }; }; - } else if ('_compileJSONMulti' in Module) { - compilerAcceptsMultipleFiles = true; - compile = Module.cwrap('compileJSONMulti', 'string', [ 'string', 'number' ]); - } else { - compilerAcceptsMultipleFiles = false; - compile = Module.cwrap('compileJSON', 'string', [ 'string', 'number' ]); - } - setCompileJSON(function (source, optimize, cb) { + + var result; try { - var result = compile(source, optimize); + result = compiler.compile(source, optimize, missingInputsCallback); } catch (exception) { - result = JSON.stringify({ error: 'Uncaught JavaScript exception:\n' + exception }); + result = { error: 'Uncaught JavaScript exception:\n' + exception }; } + compilationFinished(result, missingInputs); - }); - onCompilerLoaded(setVersionText, Module.cwrap('version', 'string', [])()); + }; + + onCompilerLoaded(setVersionText, compiler.version()); } } - function compilationFinished (result, missingInputs) { - var data; + function compilationFinished (data, missingInputs) { var noFatalErrors = true; // ie warnings are ok - try { - data = JSON.parse(result); - } catch (exception) { - renderer.error('Invalid JSON output from the compiler: ' + exception); - return; - } - if (data['error'] !== undefined) { renderer.error(data['error']); if (utils.errortype(data['error']) !== 'warning') { @@ -132,6 +119,7 @@ function Compiler (editor, renderer, queryParams, handleGithubCall, outputField, this.loadVersion = function (usingWorker, version, setVersionText) { var url = 'https://ethereum.github.io/solc-bin/bin/' + version; + console.log('Loading ' + url + ' ' + (usingWorker ? 'with worker' : 'without worker')); if (usingWorker) { loadWorker(url, setVersionText); @@ -171,15 +159,21 @@ function Compiler (editor, renderer, queryParams, handleGithubCall, outputField, onCompilerLoaded(setVersionText, data.data); break; case 'compiled': - compilationFinished(data.data, data.missingInputs); + var result; + try { + result = JSON.parse(data.data); + } catch (exception) { + result = { 'error': 'Invalid JSON output from the compiler: ' + exception }; + } + compilationFinished(result, data.missingInputs); break; } }); worker.onerror = function (msg) { console.log(msg.data); }; worker.addEventListener('error', function (msg) { console.log(msg.data); }); - setCompileJSON(function (source, optimize) { - worker.postMessage({cmd: 'compile', source: source, optimize: optimize}); - }); + compileJSON = function (source, optimize) { + worker.postMessage({cmd: 'compile', source: JSON.stringify(source), optimize: optimize}); + }; worker.postMessage({cmd: 'loadVersion', data: url}); } @@ -235,7 +229,7 @@ function Compiler (editor, renderer, queryParams, handleGithubCall, outputField, } } } while (reloop); - cb(JSON.stringify({ 'sources': files })); + cb({ 'sources': files }); } }