Skip to content

Commit

Permalink
fix default release repo, and loading solc
Browse files Browse the repository at this point in the history
  • Loading branch information
iostat committed Sep 8, 2023
1 parent 81cd992 commit 56f401b
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 14 deletions.
61 changes: 50 additions & 11 deletions src/Language/Solidity/Compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,56 @@ export const version = function(solc) {
return solc.version();
}

export const useCompiler = function(source) {
const requireFromString = function(str) {
const filename = "__solc_useCompiler";
const Module = module.constructor;
var m = new Module(filename, module);
m.filename = filename
m.paths = module.paths;
m._compile(source, "__solc_useCompiler");
return m.exports;
// Because PureScript 0.15+ converted modules to use ESM, we can't just
// require() in a CJS module -- even import()ing from a data URI will make
// node's loader assume we're trying to load an ES module. This is unfortunate
// since solc is shipped as an ES. To get around this, we create a loader hook
// that forces Node to treat certain URLs as CommonJS.
//
// This unfortunately requires Node v20.6+
//
// Because we are a PureScript package and can't assume anything about where any relative
// "pure" JS files will be, but we do know our own module's URL, we keep this function here
// and in _useCompiler, we register this file as a node loader.
const __DATA_JS_BASE64 = "data:text/javascript;base64,";
const __SOLC_CJS_MARKER = "/solc_cjs";
export function load(spec, context, next) {
if (typeof spec === 'string' && spec.startsWith(__DATA_JS_BASE64) && spec.endsWith(__SOLC_CJS_MARKER)) {
const cleanedSpec = spec.substring(__DATA_JS_BASE64.length, spec.length - __SOLC_CJS_MARKER.length);
return {
format: 'commonjs',
shortCircuit: true,
source: atob(cleanedSpec),
};
} else {
return next(spec, context);
}
return solcMod.setupMethods(requireFromString(source));
}

export const _useCompiler = function(source) {
return function (onError, onSuccess) {
const mkMod = async () => {
try {
const url = __DATA_JS_BASE64 + btoa(source) + __SOLC_CJS_MARKER;
const NodeModule = await import("node:module");
NodeModule.register(import.meta.url);
const mod = await import(url);
return mod.default;
} catch(e) {
console.error(e);
throw e;
}
};

const cancel = mkMod().then(m => onSuccess(solcMod.setupMethods(m)), e => {
onError(e);
});

return function(cancelError, onCancelerError, onCancelerSuccess) {
cancel();
onCancelerSuccess();
};
};
}

export const callbackSuccess = function (contents) {
Expand Down Expand Up @@ -156,4 +195,4 @@ export const _compile = function (solc, input, readCallback) {
return readCallback(requestedFile)();
}));
}
};
};
9 changes: 8 additions & 1 deletion src/Language/Solidity/Compiler.purs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ foreign import callbackSuccess :: String -> SolcReadFileCallbackResult
foreign import callbackFailure :: String -> SolcReadFileCallbackResult
foreign import defaultCompiler :: SolidityCompiler
foreign import version :: SolidityCompiler -> String
foreign import useCompiler :: String -> SolidityCompiler
foreign import _useCompiler :: String -> EffectFnAff SolidityCompiler
foreign import _loadRemoteVersion :: String -> EffectFnAff SolidityCompiler
foreign import _compile :: Fn3 SolidityCompiler Json (FilePath -> Effect SolcReadFileCallbackResult) (Effect Json)

Expand All @@ -51,3 +51,10 @@ loadRemoteVersion
=> String
-> m SolidityCompiler
loadRemoteVersion = liftAff <<< fromEffectFnAff <<< _loadRemoteVersion

useCompiler
:: forall m
. MonadAff m
=> String
-> m SolidityCompiler
useCompiler = liftAff <<< fromEffectFnAff <<< _useCompiler
2 changes: 1 addition & 1 deletion src/Language/Solidity/Compiler/Releases.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const _getURL = function(url) {
var cancel = httpImpl.get(url, function (res) {
var error;
if (res.statusCode != 200) {
error = new Error("Request failed, status code " + statusCode);
error = new Error("Request failed to " + url + " status code " + res.statusCode);
}

if (error) {
Expand Down
11 changes: 10 additions & 1 deletion src/Language/Solidity/Compiler/Releases.purs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, encodeJson
import Data.Argonaut.Decode.Error (printJsonDecodeError)
import Data.Bifunctor (lmap)
import Data.Either (Either(..), note)
import Data.Generic.Rep (class Generic)
import Data.Maybe (Maybe(..))
import Data.Show.Generic (genericShow)
import Data.String (toLower)
import Effect.Aff.Class (class MonadAff, liftAff)
import Effect.Aff.Compat (EffectFnAff, fromEffectFnAff)
Expand All @@ -37,6 +39,10 @@ data Build
= Stable (BuildR ())
| Prerelease (BuildR (prerelease :: String))

derive instance genericBuild :: Generic Build _
instance showBuild :: Show Build where
show = genericShow

instance decodeJsonBuild :: DecodeJson Build where
decodeJson j = Prerelease <$> decodeJson j <|> Stable <$> decodeJson j

Expand All @@ -51,8 +57,11 @@ newtype ReleaseList =
, latestRelease :: String
}

derive instance genericReleaseList :: Generic ReleaseList _
derive newtype instance decodeJsonReleaseList :: DecodeJson ReleaseList
derive newtype instance encodeJsonReleaseList :: EncodeJson ReleaseList
instance showReleaseList :: Show ReleaseList where
show = genericShow

newtype ReleaseRepo =
ReleaseRepo
Expand All @@ -71,7 +80,7 @@ getURL u = liftAff $ (map Right <<< fromEffectFnAff $ _getURL u) `catchError` (p

defaultReleaseRepo :: ReleaseRepo
defaultReleaseRepo = ReleaseRepo
{ base: "https://ethereum.github.io/solc-bin/bin"
{ base: "https://binaries.soliditylang.org/bin"
, listFile: "list.json"
}

Expand Down

0 comments on commit 56f401b

Please sign in to comment.