@theqrl/hypc 0.0.2 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -15
- package/abi.js +17 -7
- package/bindings/compile.js +158 -31
- package/bindings/core.js +22 -6
- package/bindings/helpers.js +3 -4
- package/bindings/index.js +13 -6
- package/common/helpers.js +17 -3
- package/downloadCurrentVersion.js +20 -14
- package/formatters.js +2 -3
- package/hypc.js +91 -35
- package/hypjson.js +110 -1732
- package/linker.js +63 -32
- package/package.json +28 -28
- package/smtchecker.js +3 -1
- package/smtsolver.js +44 -17
- package/translate.js +4 -4
- package/verifyVersion.js +17 -7
- package/wrapper.js +305 -30
- package/build/clean.js +0 -6
- package/build/pack-publish-block.js +0 -10
- package/build/postbuild.js +0 -3
- package/contractA_hyp_A.bin +0 -1
- package/contractB_hyp_B.bin +0 -1
- package/importA_hyp_C.bin +0 -1
- package/importB_hyp_D.bin +0 -1
- package/libX_hyp_X.bin +0 -1
- package/libY_hyp_Y.bin +0 -1
- package/libZ_hyp_Z.bin +0 -1
- package/test/abi.js +0 -77
- package/test/cli.js +0 -245
- package/test/compiler.js +0 -791
- package/test/index.js +0 -36
- package/test/linker.js +0 -132
- package/test/resources/fixtureAsmJson.hyp +0 -8
- package/test/resources/fixtureAsmJson.json +0 -528
- package/test/resources/fixtureAsmJson.output +0 -101
- package/test/resources/fixtureIncorrectSource.hyp +0 -1
- package/test/resources/fixtureSmoke.hyp +0 -5
- package/test/resources/importA.hyp +0 -7
- package/test/resources/importB.hyp +0 -5
- package/test/resources/importCallback/base/contractA.hyp +0 -8
- package/test/resources/importCallback/base/contractB.hyp +0 -6
- package/test/resources/importCallback/contractC.hyp +0 -4
- package/test/resources/importCallback/includeA/libX.hyp +0 -4
- package/test/resources/importCallback/includeA/libY.hyp +0 -6
- package/test/resources/importCallback/includeA/utils.hyp +0 -4
- package/test/resources/importCallback/includeB/libZ.hyp +0 -4
- package/test/resources/smtChecker/loop.hyp +0 -8
- package/test/resources/smtChecker/smoke.hyp +0 -5
- package/test/resources/smtChecker/smoke_with_engine.hyp +0 -6
- package/test/resources/smtChecker/smoke_with_multi_engine.hyp +0 -8
- package/test/smtcallback.js +0 -221
- package/test/smtchecker.js +0 -83
- package/test/translate.js +0 -83
- package/test_resources_fixtureSmoke_hyp_C.abi +0 -1
- package/test_resources_fixtureSmoke_hyp_C.bin +0 -1
- package/test_resources_importA_hyp_C.bin +0 -1
- package/test_resources_importB_hyp_D.bin +0 -1
- package/tsconfig.json +0 -25
- package/utils_hyp_Utils.bin +0 -1
package/linker.js
CHANGED
|
@@ -5,6 +5,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
const assert_1 = __importDefault(require("assert"));
|
|
6
6
|
const js_sha3_1 = require("js-sha3");
|
|
7
7
|
const helpers_1 = require("./common/helpers");
|
|
8
|
+
const ADDRESS_HEX_LENGTH = 128;
|
|
9
|
+
const ADDRESS_PREFIX = 'Q';
|
|
10
|
+
const PREFIXED_ADDRESS_LENGTH = ADDRESS_HEX_LENGTH + ADDRESS_PREFIX.length;
|
|
11
|
+
const PLACEHOLDER_MARKER_LENGTH = 4;
|
|
12
|
+
const HASH_PLACEHOLDER_MARKER_LENGTH = 6;
|
|
13
|
+
const PLACEHOLDER_BODY_LENGTH = ADDRESS_HEX_LENGTH - PLACEHOLDER_MARKER_LENGTH;
|
|
14
|
+
const HASH_PLACEHOLDER_BODY_LENGTH = ADDRESS_HEX_LENGTH - HASH_PLACEHOLDER_MARKER_LENGTH;
|
|
8
15
|
/**
|
|
9
16
|
* Generates a new-style library placeholder from a fully-qualified library name.
|
|
10
17
|
*
|
|
@@ -13,8 +20,32 @@ const helpers_1 = require("./common/helpers");
|
|
|
13
20
|
*
|
|
14
21
|
* @param fullyQualifiedLibraryName Fully qualified library name.
|
|
15
22
|
*/
|
|
23
|
+
function libraryHash(fullyQualifiedLibraryName, length) {
|
|
24
|
+
let hash = (0, js_sha3_1.keccak256)(fullyQualifiedLibraryName);
|
|
25
|
+
while (hash.length < length) {
|
|
26
|
+
hash += (0, js_sha3_1.keccak256)(hash);
|
|
27
|
+
}
|
|
28
|
+
return hash.slice(0, length);
|
|
29
|
+
}
|
|
16
30
|
function libraryHashPlaceholder(fullyQualifiedLibraryName) {
|
|
17
|
-
return `$${(
|
|
31
|
+
return `$${libraryHash(fullyQualifiedLibraryName, HASH_PLACEHOLDER_BODY_LENGTH)}$`;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Applies the compiler's address checksum to a hex address body: a letter is upper case when
|
|
35
|
+
* the matching nibble of SHAKE-256 (64 bytes) of the lower-case body is 8 or more.
|
|
36
|
+
* Mirrors `checksummedAddressBody` in hyperion's libhyputil/CommonData.cpp.
|
|
37
|
+
*/
|
|
38
|
+
function checksummedAddressBody(body) {
|
|
39
|
+
const lower = body.toLowerCase();
|
|
40
|
+
const hash = (0, js_sha3_1.shake256)(lower, ADDRESS_HEX_LENGTH * 4);
|
|
41
|
+
return [...lower].map((c, i) => (c >= 'a' && c <= 'f' && parseInt(hash[i], 16) >= 8 ? c.toUpperCase() : c)).join('');
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Accepts an all-lower-case or all-upper-case body, or a mixed-case body with a valid checksum,
|
|
45
|
+
* as the compiler does for `settings.libraries`.
|
|
46
|
+
*/
|
|
47
|
+
function passesAddressChecksum(body) {
|
|
48
|
+
return body === body.toLowerCase() || body === body.toUpperCase() || body === checksummedAddressBody(body);
|
|
18
49
|
}
|
|
19
50
|
/**
|
|
20
51
|
* Finds all placeholders corresponding to the specified library label and replaces them
|
|
@@ -30,9 +61,8 @@ function libraryHashPlaceholder(fullyQualifiedLibraryName) {
|
|
|
30
61
|
* It will **not** be padded with zeros if too short.
|
|
31
62
|
*/
|
|
32
63
|
function replacePlaceholder(bytecode, label, address) {
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
const libLabel = `__${truncatedName.padEnd(36, '_')}__`;
|
|
64
|
+
const truncatedName = label.slice(0, PLACEHOLDER_BODY_LENGTH);
|
|
65
|
+
const libLabel = `__${truncatedName.padEnd(PLACEHOLDER_BODY_LENGTH, '_')}__`;
|
|
36
66
|
while (bytecode.indexOf(libLabel) >= 0) {
|
|
37
67
|
bytecode = bytecode.replace(libLabel, address);
|
|
38
68
|
}
|
|
@@ -44,14 +74,14 @@ function replacePlaceholder(bytecode, label, address) {
|
|
|
44
74
|
* See [Library Linking](https://docs.soliditylang.org/en/latest/using-the-compiler.html#library-linking)
|
|
45
75
|
* for a full explanation of the linking process.
|
|
46
76
|
*
|
|
47
|
-
* Example of
|
|
48
|
-
* Example of a new-style placeholder: `__
|
|
77
|
+
* Example of an old-style placeholder: `__lib.hyp:L...__` padded to 64 bytes.
|
|
78
|
+
* Example of a new-style placeholder: `__$<122 hex characters>$__`
|
|
49
79
|
*
|
|
50
|
-
* @param bytecode Hex-encoded bytecode string. All
|
|
80
|
+
* @param bytecode Hex-encoded bytecode string. All 64-byte substrings starting and ending with
|
|
51
81
|
* `__` will be interpreted as placeholders.
|
|
52
82
|
*
|
|
53
83
|
* @param libraries Mapping between fully qualified library names and the hex-encoded
|
|
54
|
-
* addresses they should be replaced with.
|
|
84
|
+
* addresses they should be replaced with.
|
|
55
85
|
*
|
|
56
86
|
* @returns bytecode Hex-encoded bytecode string with placeholders replaced with addresses.
|
|
57
87
|
* Note that some placeholders may remain in the bytecode if `libraries` does not provide addresses for all of them.
|
|
@@ -66,7 +96,7 @@ function linkBytecode(bytecode, libraries) {
|
|
|
66
96
|
throw new Error(`No address provided for library ${fullyQualifiedLibraryName}`);
|
|
67
97
|
}
|
|
68
98
|
// API compatible with the standard JSON i/o
|
|
69
|
-
// {"lib.hyp": {"L": "
|
|
99
|
+
// {"lib.hyp": {"L": "Q..."}}
|
|
70
100
|
if ((0, helpers_1.isObject)(libraryObjectOrAddress)) {
|
|
71
101
|
for (const [unqualifiedLibraryName, address] of Object.entries(libraryObjectOrAddress)) {
|
|
72
102
|
librariesComplete[unqualifiedLibraryName] = address;
|
|
@@ -85,11 +115,16 @@ function linkBytecode(bytecode, libraries) {
|
|
|
85
115
|
}
|
|
86
116
|
for (const libraryName in librariesComplete) {
|
|
87
117
|
let hexAddress = librariesComplete[libraryName];
|
|
88
|
-
if (!hexAddress.startsWith(
|
|
118
|
+
if (!hexAddress.startsWith(ADDRESS_PREFIX) ||
|
|
119
|
+
hexAddress.length !== PREFIXED_ADDRESS_LENGTH ||
|
|
120
|
+
!/^[0-9a-fA-F]+$/.test(hexAddress.slice(ADDRESS_PREFIX.length))) {
|
|
89
121
|
throw new Error(`Invalid address specified for ${libraryName}`);
|
|
90
122
|
}
|
|
91
|
-
// remove
|
|
92
|
-
hexAddress = hexAddress.slice(
|
|
123
|
+
// remove address prefix
|
|
124
|
+
hexAddress = hexAddress.slice(ADDRESS_PREFIX.length);
|
|
125
|
+
if (!passesAddressChecksum(hexAddress)) {
|
|
126
|
+
throw new Error(`Invalid address checksum specified for ${libraryName}`);
|
|
127
|
+
}
|
|
93
128
|
bytecode = replacePlaceholder(bytecode, libraryName, hexAddress);
|
|
94
129
|
bytecode = replacePlaceholder(bytecode, libraryHashPlaceholder(libraryName), hexAddress);
|
|
95
130
|
}
|
|
@@ -97,17 +132,17 @@ function linkBytecode(bytecode, libraries) {
|
|
|
97
132
|
}
|
|
98
133
|
/**
|
|
99
134
|
* Finds locations of all library address placeholders in the hex-encoded bytecode.
|
|
100
|
-
* Returns information in a format matching `
|
|
135
|
+
* Returns information in a format matching `qrvm.bytecode.linkReferences` output
|
|
101
136
|
* in Standard JSON.
|
|
102
137
|
*
|
|
103
138
|
* See [Library Linking](https://docs.soliditylang.org/en/latest/using-the-compiler.html#library-linking)
|
|
104
139
|
* for a full explanation of library placeholders and linking process.
|
|
105
140
|
*
|
|
106
|
-
* WARNING: The output matches `
|
|
141
|
+
* WARNING: The output matches `qrvm.bytecode.linkReferences` exactly only in
|
|
107
142
|
* case of old-style placeholders created from fully qualified library names
|
|
108
143
|
* of no more than 36 characters, and even then only if the name does not start
|
|
109
144
|
* or end with an underscore. This is different from
|
|
110
|
-
* `
|
|
145
|
+
* `qrvm.bytecode.linkReferences`, which uses fully qualified library names.
|
|
111
146
|
* This is a limitation of the placeholder format - the fully qualified names
|
|
112
147
|
* are not preserved in the compiled bytecode and cannot be reconstructed
|
|
113
148
|
* without external information.
|
|
@@ -116,37 +151,33 @@ function linkBytecode(bytecode, libraries) {
|
|
|
116
151
|
*
|
|
117
152
|
* @returns linkReferences A mapping between library labels and their locations
|
|
118
153
|
* in the bytecode. In case of old-style placeholders the label is a fully
|
|
119
|
-
* qualified library name truncated to
|
|
120
|
-
* it's the
|
|
121
|
-
*
|
|
154
|
+
* qualified library name truncated to 124 characters. For new-style placeholders
|
|
155
|
+
* it's the address-width hash label of the fully qualified library name, with a leading
|
|
156
|
+
* and trailing $ character added. Note that the
|
|
122
157
|
* offsets and lengths refer to the *binary* (not hex-encoded) bytecode, just
|
|
123
|
-
* like in `
|
|
158
|
+
* like in `qrvm.bytecode.linkReferences`.
|
|
124
159
|
*/
|
|
125
160
|
function findLinkReferences(bytecode) {
|
|
126
161
|
(0, assert_1.default)(typeof bytecode === 'string');
|
|
127
|
-
// find
|
|
128
|
-
// e.g. __Lib.hyp:L_____________________________
|
|
162
|
+
// find 64-byte placeholders in the pattern of __...__
|
|
163
|
+
// e.g. __Lib.hyp:L_____________________________ or __$<122 hex digits>$__
|
|
129
164
|
const linkReferences = {};
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
if (!found) {
|
|
134
|
-
break;
|
|
135
|
-
}
|
|
165
|
+
const placeholderPattern = /__(.{124})__/g;
|
|
166
|
+
let found;
|
|
167
|
+
while ((found = placeholderPattern.exec(bytecode)) !== null) {
|
|
136
168
|
const start = found.index;
|
|
169
|
+
const placeholder = found[1];
|
|
137
170
|
// trim trailing underscores
|
|
138
171
|
// NOTE: this has no way of knowing if the trailing underscore was part of the name
|
|
139
|
-
const libraryName =
|
|
172
|
+
const libraryName = placeholder.replace(/_+$/gm, '');
|
|
140
173
|
if (!linkReferences[libraryName]) {
|
|
141
174
|
linkReferences[libraryName] = [];
|
|
142
175
|
}
|
|
143
176
|
// offsets are in bytes in binary representation (and not hex)
|
|
144
177
|
linkReferences[libraryName].push({
|
|
145
|
-
start:
|
|
146
|
-
length:
|
|
178
|
+
start: start / 2,
|
|
179
|
+
length: ADDRESS_HEX_LENGTH / 2
|
|
147
180
|
});
|
|
148
|
-
offset += start + 20;
|
|
149
|
-
bytecode = bytecode.slice(start + 20);
|
|
150
181
|
}
|
|
151
182
|
return linkReferences;
|
|
152
183
|
}
|
package/package.json
CHANGED
|
@@ -1,33 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theqrl/hypc",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Hyperion compiler",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"hypcjs": "hypc.js"
|
|
8
8
|
},
|
|
9
|
+
"files": [
|
|
10
|
+
"*.js",
|
|
11
|
+
"bindings/*.js",
|
|
12
|
+
"common/*.js"
|
|
13
|
+
],
|
|
9
14
|
"scripts": {
|
|
10
15
|
"build": "tsc",
|
|
11
16
|
"postbuild": "node build/postbuild.js && cp README.md LICENSE dist/",
|
|
12
|
-
"lint": "eslint
|
|
13
|
-
"lint:fix": "eslint --fix
|
|
17
|
+
"lint": "eslint .",
|
|
18
|
+
"lint:fix": "eslint --fix .",
|
|
14
19
|
"updateBinary": "node build/clean.js && ts-node ./downloadCurrentVersion.ts && ts-node ./verifyVersion.ts",
|
|
15
20
|
"prepack": "node build/pack-publish-block.js",
|
|
16
21
|
"build:tarball": "npm run updateBinary && npm run build && BYPASS_SAFETY_CHECK=true npm pack ./dist",
|
|
17
22
|
"publish:tarball": "tarball=$(npm run --silent tarballName) && ls \"$tarball\" && BYPASS_SAFETY_CHECK=true npm publish --access public \"$tarball\"",
|
|
18
|
-
"tarballName": "jq --raw-output '.name + \"-\" + .version + \".tgz\"' package.json",
|
|
23
|
+
"tarballName": "jq --raw-output '(.name | sub(\"@\"; \"\") | gsub(\"/\"; \"-\")) + \"-\" + .version + \".tgz\"' package.json",
|
|
19
24
|
"copyTestFiles": "cp -r ./test/resources ./dist/test/",
|
|
20
25
|
"pretest": "npm run lint && npm run build && npm run copyTestFiles",
|
|
21
|
-
"test": "cd dist && tape ./test/index.js",
|
|
22
|
-
"coverage": "nyc npm run test"
|
|
23
|
-
"coveralls": "npm run coverage && coveralls <coverage/lcov.info"
|
|
26
|
+
"test": "cd dist && tape ./test/index.js --no-remote-versions",
|
|
27
|
+
"coverage": "nyc npm run test"
|
|
24
28
|
},
|
|
25
29
|
"repository": {
|
|
26
30
|
"type": "git",
|
|
27
31
|
"url": "git+https://github.com/theQRL/hypc-js.git"
|
|
28
32
|
},
|
|
29
33
|
"keywords": [
|
|
30
|
-
"
|
|
34
|
+
"qrl",
|
|
31
35
|
"hyperion",
|
|
32
36
|
"compiler"
|
|
33
37
|
],
|
|
@@ -37,33 +41,29 @@
|
|
|
37
41
|
"url": "https://github.com/theQRL/hypc-js/issues"
|
|
38
42
|
},
|
|
39
43
|
"homepage": "https://github.com/theQRL/hypc-js#readme",
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=22.12.0"
|
|
46
|
+
},
|
|
40
47
|
"dependencies": {
|
|
41
48
|
"command-exists": "^1.2.8",
|
|
42
|
-
"commander": "^
|
|
43
|
-
"follow-redirects": "^1.
|
|
44
|
-
"js-sha3": "0.
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"tmp": "0.0.33"
|
|
49
|
+
"commander": "^15.0.0",
|
|
50
|
+
"follow-redirects": "^1.16.2",
|
|
51
|
+
"js-sha3": "0.13.0",
|
|
52
|
+
"semver": "^7.8.5",
|
|
53
|
+
"tmp": "0.2.7"
|
|
48
54
|
},
|
|
49
55
|
"devDependencies": {
|
|
50
|
-
"@types/node": "^
|
|
51
|
-
"@types/semver": "^7.
|
|
52
|
-
"@types/tape": "^
|
|
56
|
+
"@types/node": "^22.12.0",
|
|
57
|
+
"@types/semver": "^7.8.0",
|
|
58
|
+
"@types/tape": "^5.8.1",
|
|
53
59
|
"@types/tmp": "^0.2.3",
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"eslint-config-standard": "^16.0.3",
|
|
59
|
-
"eslint-plugin-import": "^2.25.3",
|
|
60
|
-
"eslint-plugin-node": "^11.1.0",
|
|
61
|
-
"eslint-plugin-promise": "^5.1.1",
|
|
62
|
-
"nyc": "^15.1.0",
|
|
63
|
-
"tape": "^4.11.0",
|
|
60
|
+
"eslint": "^10.13.0",
|
|
61
|
+
"neostandard": "^0.14.1",
|
|
62
|
+
"nyc": "^18.0.0",
|
|
63
|
+
"tape": "^5.10.3",
|
|
64
64
|
"tape-spawn": "^1.4.2",
|
|
65
65
|
"ts-node": "^10.4.0",
|
|
66
|
-
"typescript": "
|
|
66
|
+
"typescript": "~6.0.2"
|
|
67
67
|
},
|
|
68
68
|
"nyc": {
|
|
69
69
|
"exclude": [
|
package/smtchecker.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
const helpers_1 = require("./common/helpers");
|
|
2
3
|
// This function checks the standard JSON output for auxiliaryInputRequested,
|
|
3
4
|
// where smtlib2queries represent the queries created by the SMTChecker.
|
|
4
5
|
// The function runs an SMT solver on each query and adjusts the input for
|
|
@@ -29,7 +30,8 @@ function smtCallback(solverFunction, solver) {
|
|
|
29
30
|
return { contents: result };
|
|
30
31
|
}
|
|
31
32
|
catch (err) {
|
|
32
|
-
|
|
33
|
+
// The compiler takes the error as a string, like the contents.
|
|
34
|
+
return { error: (0, helpers_1.describeException)(err) };
|
|
33
35
|
}
|
|
34
36
|
};
|
|
35
37
|
}
|
package/smtsolver.js
CHANGED
|
@@ -15,34 +15,51 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
const command_exists_1 = require("command-exists");
|
|
26
36
|
const child_process_1 = require("child_process");
|
|
27
37
|
const fs = __importStar(require("fs"));
|
|
28
38
|
const tmp = __importStar(require("tmp"));
|
|
29
39
|
// Timeout in ms.
|
|
30
40
|
const timeout = 10000;
|
|
41
|
+
// Solver answers are short; this only bounds a runaway solver.
|
|
42
|
+
const maxBuffer = 64 * 1024 * 1024;
|
|
31
43
|
const potentialSolvers = [
|
|
32
44
|
{
|
|
33
45
|
name: 'z3',
|
|
34
46
|
command: 'z3',
|
|
35
|
-
params: '-smt2 rlimit=20000000 rewriter.pull_cheap_ite=true fp.spacer.q3.use_qgen=true fp.spacer.mbqi=false fp.spacer.ground_pobs=false'
|
|
47
|
+
params: ['-smt2', 'rlimit=20000000', 'rewriter.pull_cheap_ite=true', 'fp.spacer.q3.use_qgen=true', 'fp.spacer.mbqi=false', 'fp.spacer.ground_pobs=false']
|
|
36
48
|
},
|
|
37
49
|
{
|
|
38
50
|
name: 'Eldarica',
|
|
39
51
|
command: 'eld',
|
|
40
|
-
params: '-horn -t:' + (timeout / 1000) // Eldarica takes timeout in seconds.
|
|
52
|
+
params: ['-horn', '-t:' + (timeout / 1000)] // Eldarica takes timeout in seconds.
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'cvc5',
|
|
56
|
+
command: 'cvc5',
|
|
57
|
+
params: ['--lang=smt2', '--tlimit=' + timeout]
|
|
41
58
|
},
|
|
42
59
|
{
|
|
43
60
|
name: 'cvc4',
|
|
44
61
|
command: 'cvc4',
|
|
45
|
-
params: '--lang=smt2 --tlimit=' + timeout
|
|
62
|
+
params: ['--lang=smt2', '--tlimit=' + timeout]
|
|
46
63
|
}
|
|
47
64
|
];
|
|
48
65
|
const solvers = potentialSolvers.filter(solver => (0, command_exists_1.sync)(solver.command));
|
|
@@ -59,18 +76,26 @@ function solve(query, solver) {
|
|
|
59
76
|
fs.writeFileSync(tmpFile.name, query);
|
|
60
77
|
let solverOutput;
|
|
61
78
|
try {
|
|
62
|
-
|
|
79
|
+
// No shell: the solver gets its arguments as an array. A caller's solver configuration may
|
|
80
|
+
// still give params as one string, as before; it is split on whitespace.
|
|
81
|
+
const params = typeof solver.params === 'string' ? solver.params.split(/\s+/).filter(Boolean) : solver.params;
|
|
82
|
+
solverOutput = (0, child_process_1.execFileSync)(solver.command, [...params, tmpFile.name], {
|
|
63
83
|
encoding: 'utf8',
|
|
64
|
-
maxBuffer
|
|
84
|
+
maxBuffer,
|
|
65
85
|
stdio: 'pipe',
|
|
66
|
-
timeout
|
|
86
|
+
timeout, // Enforce timeout on the process, since solvers can sometimes go around it.
|
|
87
|
+
killSignal: 'SIGKILL' // A solver can ignore SIGTERM.
|
|
67
88
|
}).toString();
|
|
68
89
|
}
|
|
69
90
|
catch (e) {
|
|
70
|
-
//
|
|
91
|
+
// The output was cut off at maxBuffer, so even an answer at its start cannot be trusted.
|
|
92
|
+
if (e.code === 'ENOBUFS') {
|
|
93
|
+
throw new Error(`Failed to solve SMT query. The solver wrote more than ${maxBuffer} bytes.`);
|
|
94
|
+
}
|
|
95
|
+
// execFileSync throws if the process times out or returns != 0.
|
|
71
96
|
// The latter might happen with z3 if the query asks for a model
|
|
72
97
|
// for an UNSAT formula. We can still use stdout.
|
|
73
|
-
solverOutput = e.stdout.toString();
|
|
98
|
+
solverOutput = (e.stdout || '').toString();
|
|
74
99
|
if (!solverOutput.startsWith('sat') &&
|
|
75
100
|
!solverOutput.startsWith('unsat') &&
|
|
76
101
|
!solverOutput.startsWith('unknown') &&
|
|
@@ -79,8 +104,10 @@ function solve(query, solver) {
|
|
|
79
104
|
throw new Error('Failed to solve SMT query. ' + e.toString());
|
|
80
105
|
}
|
|
81
106
|
}
|
|
82
|
-
|
|
83
|
-
|
|
107
|
+
finally {
|
|
108
|
+
// Trigger early manual cleanup
|
|
109
|
+
tmpFile.removeCallback();
|
|
110
|
+
}
|
|
84
111
|
return solverOutput;
|
|
85
112
|
}
|
|
86
113
|
module.exports = {
|
package/translate.js
CHANGED
|
@@ -7,8 +7,8 @@ const linker_1 = __importDefault(require("./linker"));
|
|
|
7
7
|
/// Old style: 0.3.6-3fc68da5/Release-Emscripten/clang
|
|
8
8
|
/// 0.3.5-371690f0/Release-Emscripten/clang/Interpreter
|
|
9
9
|
/// 0.3.5-0/Release-Emscripten/clang/Interpreter
|
|
10
|
-
/// 0.2.0-e7098958/.-Emscripten/clang/int linked to
|
|
11
|
-
/// 0.1.3-0/.-/clang/int linked to
|
|
10
|
+
/// 0.2.0-e7098958/.-Emscripten/clang/int linked to libqrl-1.1.1-bbb80ab0/.-Emscripten/clang/int
|
|
11
|
+
/// 0.1.3-0/.-/clang/int linked to libqrl-0.9.92-0/.-/clang/int
|
|
12
12
|
/// 0.1.2-5c3bfd4b*/.-/clang/int
|
|
13
13
|
/// 0.1.1-6ff4cd6b/RelWithDebInfo-Emscripten/clang/int
|
|
14
14
|
/// New style: 0.4.5+commit.b318366e.Emscripten.clang
|
|
@@ -42,7 +42,7 @@ function translateErrors(ret, errors) {
|
|
|
42
42
|
type = 'Error';
|
|
43
43
|
}
|
|
44
44
|
ret.push({
|
|
45
|
-
type
|
|
45
|
+
type,
|
|
46
46
|
component: 'general',
|
|
47
47
|
severity: (type === 'Warning') ? 'warning' : 'error',
|
|
48
48
|
message: errors[error],
|
|
@@ -106,7 +106,7 @@ function translateJsonCompilerOutput(output, libraries) {
|
|
|
106
106
|
const contractOutput = {
|
|
107
107
|
abi: JSON.parse(contractInput.interface),
|
|
108
108
|
metadata: contractInput.metadata,
|
|
109
|
-
|
|
109
|
+
qrvm: {
|
|
110
110
|
legacyAssembly: contractInput.assembly,
|
|
111
111
|
bytecode: {
|
|
112
112
|
object: contractInput.bytecode && linker_1.default.linkBytecode(contractInput.bytecode, libraries || {}),
|
package/verifyVersion.js
CHANGED
|
@@ -16,13 +16,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
16
16
|
}) : function(o, v) {
|
|
17
17
|
o["default"] = v;
|
|
18
18
|
});
|
|
19
|
-
var __importStar = (this && this.__importStar) || function (
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
};
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
26
36
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
27
37
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
28
38
|
};
|