-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace solc dependency with a thin solidity_compile wrapper #6073
base: robust-compiler-downloader
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
// This wrapper was created by extracting the parts of the solc-js package | ||
// (https://github.com/ethereum/solc-js) that we need to perform compilation. | ||
|
||
import * as semver from "semver"; | ||
|
||
interface Solc { | ||
cwrap<T>(ident: string, returnType: string | null, argTypes: string[]): T; | ||
|
||
// eslint-disable-next-line @typescript-eslint/naming-convention -- this is a C function | ||
_solidity_reset?: Reset | null; | ||
// eslint-disable-next-line @typescript-eslint/naming-convention -- this is a C function | ||
_solidity_version?: Version | null; | ||
// eslint-disable-next-line @typescript-eslint/naming-convention -- this is a C function | ||
_version?: Version | null; | ||
// eslint-disable-next-line @typescript-eslint/naming-convention -- this is a C function | ||
_compileStandard?: Compile | null; | ||
// eslint-disable-next-line @typescript-eslint/naming-convention -- this is a C function | ||
_solidity_compile?: Compile | null; | ||
} | ||
|
||
type Reset = () => string; | ||
type Version = () => string; | ||
type Compile = ( | ||
input: string, | ||
callbackPtr: number | null, | ||
callbackContextPtr?: null, | ||
) => string; | ||
|
||
export interface SolcWrapper { | ||
compile: CompileWrapper; | ||
} | ||
|
||
export type CompileWrapper = (input: string) => string; | ||
|
||
export default function wrapper(solc: Solc): SolcWrapper { | ||
const version = bindVersion(solc); | ||
const isVersion6OrNewer = semver.gte(versionToSemver(version()), "0.6.0"); | ||
galargh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const reset = bindReset(solc); | ||
const compile = bindCompile(solc, isVersion6OrNewer); | ||
|
||
if (compile === undefined) { | ||
// eslint-disable-next-line no-restricted-syntax -- should we use a HardhatError here? | ||
throw new Error( | ||
'Could not find the "compile" function in the solc library', | ||
); | ||
Comment on lines
+43
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm wondering if we should throw a |
||
} | ||
|
||
return { | ||
compile: compileWrapper(isVersion6OrNewer, compile, reset), | ||
}; | ||
} | ||
|
||
function compileWrapper( | ||
isVersion6OrNewer: boolean, | ||
compile: Compile, | ||
reset?: Reset, | ||
): CompileWrapper { | ||
return (input: string): string => { | ||
const output = isVersion6OrNewer | ||
? compile(input, null, null) | ||
: compile(input, null); | ||
Comment on lines
+60
to
+62
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The underlying compile functions expect explicit values as far as I understand. Also, their arguments differ depending on the version being used. |
||
|
||
if (reset !== undefined) { | ||
// Explicitly free memory. | ||
// | ||
// NOTE: cwrap() of "compile" will copy the returned pointer into a | ||
// Javascript string and it is not possible to call free() on it. | ||
// reset() however will clear up all allocations. | ||
reset(); | ||
} | ||
|
||
return output; | ||
}; | ||
} | ||
|
||
function bindVersion(solc: Solc): Version { | ||
if (solc._solidity_version === null || solc._solidity_version === undefined) { | ||
return solc.cwrap("version", "string", []); | ||
} | ||
|
||
return solc.cwrap("solidity_version", "string", []); | ||
} | ||
|
||
function bindReset(solc: Solc): Reset | undefined { | ||
if (solc._solidity_reset === null || solc._solidity_reset === undefined) { | ||
return undefined; | ||
} | ||
|
||
return solc.cwrap("solidity_reset", null, []); | ||
} | ||
|
||
function bindCompile( | ||
solc: Solc, | ||
isVersion6OrNewer: boolean, | ||
): CompileWrapper | undefined { | ||
if (isVersion6OrNewer) { | ||
if ( | ||
solc._solidity_compile !== null && | ||
solc._solidity_compile !== undefined | ||
) { | ||
return solc.cwrap("solidity_compile", "string", [ | ||
"string", | ||
"number", | ||
"number", | ||
]); | ||
} | ||
} else { | ||
if ( | ||
solc._solidity_compile !== null && | ||
solc._solidity_compile !== undefined | ||
) { | ||
return solc.cwrap("solidity_compile", "string", ["string", "number"]); | ||
} | ||
if (solc._compileStandard !== null && solc._compileStandard !== undefined) { | ||
return solc.cwrap("compileStandard", "string", ["string", "number"]); | ||
} | ||
} | ||
|
||
return undefined; | ||
} | ||
|
||
function versionToSemver(version: string): string { | ||
// FIXME: parse more detail, but this is a good start | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The implementation of this function is a direct copy from solc-js. |
||
const parsed = version.match( | ||
/^([0-9]+\.[0-9]+\.[0-9]+)-([0-9a-f]{8})[/*].*$/, | ||
); | ||
if (parsed !== null) { | ||
return parsed[1] + "+commit." + parsed[2]; | ||
} | ||
if (version.indexOf("0.1.3-0") !== -1) { | ||
return "0.1.3"; | ||
} | ||
if (version.indexOf("0.3.5-0") !== -1) { | ||
return "0.3.5"; | ||
} | ||
// assume it is already semver compatible | ||
return version; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an odd type, but we either want to skip this argument or provide an explicit null. That depends on the version of solc that we're going to be using.