@theqrl/hypc 0.0.2
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/LICENSE +0 -0
- package/README.md +361 -0
- package/abi.js +80 -0
- package/bindings/compile.js +157 -0
- package/bindings/core.js +116 -0
- package/bindings/helpers.js +35 -0
- package/bindings/index.js +16 -0
- package/build/clean.js +6 -0
- package/build/pack-publish-block.js +10 -0
- package/build/postbuild.js +3 -0
- package/common/helpers.js +24 -0
- package/common/types.js +2 -0
- package/contractA_hyp_A.bin +1 -0
- package/contractB_hyp_B.bin +1 -0
- package/downloadCurrentVersion.js +93 -0
- package/formatters.js +17 -0
- package/hypc.js +259 -0
- package/hypjson.js +1733 -0
- package/importA_hyp_C.bin +1 -0
- package/importB_hyp_D.bin +1 -0
- package/index.js +7 -0
- package/libX_hyp_X.bin +1 -0
- package/libY_hyp_Y.bin +1 -0
- package/libZ_hyp_Z.bin +1 -0
- package/linker.js +156 -0
- package/package.json +74 -0
- package/smtchecker.js +39 -0
- package/smtsolver.js +89 -0
- package/test/abi.js +77 -0
- package/test/cli.js +245 -0
- package/test/compiler.js +791 -0
- package/test/index.js +36 -0
- package/test/linker.js +132 -0
- package/test/resources/fixtureAsmJson.hyp +8 -0
- package/test/resources/fixtureAsmJson.json +528 -0
- package/test/resources/fixtureAsmJson.output +101 -0
- package/test/resources/fixtureIncorrectSource.hyp +1 -0
- package/test/resources/fixtureSmoke.hyp +5 -0
- package/test/resources/importA.hyp +7 -0
- package/test/resources/importB.hyp +5 -0
- package/test/resources/importCallback/base/contractA.hyp +8 -0
- package/test/resources/importCallback/base/contractB.hyp +6 -0
- package/test/resources/importCallback/contractC.hyp +4 -0
- package/test/resources/importCallback/includeA/libX.hyp +4 -0
- package/test/resources/importCallback/includeA/libY.hyp +6 -0
- package/test/resources/importCallback/includeA/utils.hyp +4 -0
- package/test/resources/importCallback/includeB/libZ.hyp +4 -0
- package/test/resources/smtChecker/loop.hyp +8 -0
- package/test/resources/smtChecker/smoke.hyp +5 -0
- package/test/resources/smtChecker/smoke_with_engine.hyp +6 -0
- package/test/resources/smtChecker/smoke_with_multi_engine.hyp +8 -0
- package/test/smtcallback.js +221 -0
- package/test/smtchecker.js +83 -0
- package/test/translate.js +83 -0
- package/test_resources_fixtureSmoke_hyp_C.abi +1 -0
- package/test_resources_fixtureSmoke_hyp_C.bin +1 -0
- package/test_resources_importA_hyp_C.bin +1 -0
- package/test_resources_importB_hyp_D.bin +1 -0
- package/translate.js +186 -0
- package/tsconfig.json +25 -0
- package/utils_hyp_Utils.bin +1 -0
- package/verifyVersion.js +43 -0
- package/wrapper.js +143 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
const assert_1 = __importDefault(require("assert"));
|
|
30
|
+
const tape_1 = __importDefault(require("tape"));
|
|
31
|
+
const fs = __importStar(require("fs"));
|
|
32
|
+
const path = __importStar(require("path"));
|
|
33
|
+
const __1 = __importDefault(require("../"));
|
|
34
|
+
const smtchecker_1 = __importDefault(require("../smtchecker"));
|
|
35
|
+
const smtsolver_1 = __importDefault(require("../smtsolver"));
|
|
36
|
+
const preamble = 'pragma hyperion >=0.0.1;\n// SPDX-License-Identifier: GPL-3.0\n';
|
|
37
|
+
function collectErrors(hypOutput) {
|
|
38
|
+
if (hypOutput === undefined) {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
const errors = [];
|
|
42
|
+
for (const i in hypOutput.errors) {
|
|
43
|
+
const error = hypOutput.errors[i];
|
|
44
|
+
if (error.message.includes('This is a pre-release compiler version')) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
errors.push(error.message);
|
|
48
|
+
}
|
|
49
|
+
return errors;
|
|
50
|
+
}
|
|
51
|
+
function expectErrors(expectations, errors, ignoreCex) {
|
|
52
|
+
if (errors.length !== expectations.length) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
for (const i in errors) {
|
|
56
|
+
if (errors[i].includes('Error trying to invoke SMT solver') || expectations[i].includes('Error trying to invoke SMT solver')) {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
// Expectations containing counterexamples might have many '\n' in a single line.
|
|
60
|
+
// These are stored escaped in the test format (as '\\n'), whereas the actual error from the compiler has '\n'.
|
|
61
|
+
// Therefore we need to replace '\\n' by '\n' in the expectations.
|
|
62
|
+
// Function `replace` only replaces the first occurrence, and `replaceAll` is not standard yet.
|
|
63
|
+
// Replace all '\\n' by '\n' via split & join.
|
|
64
|
+
expectations[i] = expectations[i].split('\\n').join('\n');
|
|
65
|
+
if (ignoreCex) {
|
|
66
|
+
expectations[i] = expectations[i].split('\nCounterexample')[0];
|
|
67
|
+
errors[i] = errors[i].split('\nCounterexample')[0];
|
|
68
|
+
}
|
|
69
|
+
// `expectations` have "// Warning ... " before the actual message,
|
|
70
|
+
// whereas `errors` have only the message.
|
|
71
|
+
if (!expectations[i].includes(errors[i])) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
(0, tape_1.default)('SMTCheckerCallback', function (t) {
|
|
78
|
+
t.test('Interface via callback', function (st) {
|
|
79
|
+
const satCallback = function (query) {
|
|
80
|
+
return { contents: 'sat\n' };
|
|
81
|
+
};
|
|
82
|
+
const unsatCallback = function (query) {
|
|
83
|
+
return { contents: 'unsat\n' };
|
|
84
|
+
};
|
|
85
|
+
const errorCallback = function (query) {
|
|
86
|
+
return { error: 'Fake SMT solver error.' };
|
|
87
|
+
};
|
|
88
|
+
const settings = { modelChecker: { engine: 'all' } };
|
|
89
|
+
const input = { a: { content: preamble + 'contract C { function f(uint x) public pure { assert(x > 0); } }' } };
|
|
90
|
+
const inputJSON = JSON.stringify({
|
|
91
|
+
language: 'Hyperion',
|
|
92
|
+
sources: input,
|
|
93
|
+
settings: settings
|
|
94
|
+
});
|
|
95
|
+
const tests = [
|
|
96
|
+
{ cb: satCallback, expectations: ['Assertion violation happens here'] },
|
|
97
|
+
{ cb: unsatCallback, expectations: ['Assertion violation happens here'] },
|
|
98
|
+
{ cb: errorCallback, expectations: ['Assertion violation happens here'] }
|
|
99
|
+
];
|
|
100
|
+
for (const i in tests) {
|
|
101
|
+
const test = tests[i];
|
|
102
|
+
const output = JSON.parse(__1.default.compile(inputJSON, { smtSolver: test.cb }));
|
|
103
|
+
const errors = collectErrors(output);
|
|
104
|
+
st.ok(expectErrors(errors, test.expectations, false));
|
|
105
|
+
}
|
|
106
|
+
st.end();
|
|
107
|
+
});
|
|
108
|
+
t.test('Hyperion smtCheckerTests', function (st) {
|
|
109
|
+
const testdir = path.resolve(__dirname, 'resources/smtChecker/');
|
|
110
|
+
if (!fs.existsSync(testdir)) {
|
|
111
|
+
st.skip('SMT checker tests not present.');
|
|
112
|
+
st.end();
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
// For these tests we actually need z3/Spacer.
|
|
116
|
+
const z3HornSolvers = smtsolver_1.default.availableSolvers.filter(solver => solver.command === 'z3');
|
|
117
|
+
if (z3HornSolvers.length === 0) {
|
|
118
|
+
st.skip('z3/Spacer not available.');
|
|
119
|
+
st.end();
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const sources = [];
|
|
123
|
+
// BFS to get all test files
|
|
124
|
+
const dirs = [testdir];
|
|
125
|
+
let i;
|
|
126
|
+
while (dirs.length > 0) {
|
|
127
|
+
const dir = dirs.shift();
|
|
128
|
+
const files = fs.readdirSync(dir);
|
|
129
|
+
for (i in files) {
|
|
130
|
+
const file = path.join(dir, files[i]);
|
|
131
|
+
if (fs.statSync(file).isDirectory()) {
|
|
132
|
+
dirs.push(file);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
sources.push(file);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Read tests and collect expectations
|
|
140
|
+
const tests = [];
|
|
141
|
+
for (i in sources) {
|
|
142
|
+
st.comment('Collecting ' + sources[i] + '...');
|
|
143
|
+
const source = fs.readFileSync(sources[i], 'utf8');
|
|
144
|
+
let engine;
|
|
145
|
+
const option = '// SMTEngine: ';
|
|
146
|
+
if (source.includes(option)) {
|
|
147
|
+
const idx = source.indexOf(option);
|
|
148
|
+
if (source.indexOf(option, idx + 1) !== -1) {
|
|
149
|
+
st.comment('SMTEngine option given multiple times.');
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const re = new RegExp(option + '(\\w+)');
|
|
153
|
+
const m = source.match(re);
|
|
154
|
+
(0, assert_1.default)(m !== undefined);
|
|
155
|
+
(0, assert_1.default)(m.length >= 2);
|
|
156
|
+
engine = m[1];
|
|
157
|
+
}
|
|
158
|
+
let expected = [];
|
|
159
|
+
const delimiter = '// ----';
|
|
160
|
+
if (source.includes(delimiter)) {
|
|
161
|
+
expected = source.substring(source.indexOf('// ----') + 8, source.length).split('\n');
|
|
162
|
+
// Sometimes the last expectation line ends with a '\n'
|
|
163
|
+
if (expected.length > 0 && expected[expected.length - 1] === '') {
|
|
164
|
+
expected.pop();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
tests[sources[i]] = {
|
|
168
|
+
expectations: expected,
|
|
169
|
+
hyperion: { test: { content: preamble + source } },
|
|
170
|
+
ignoreCex: source.includes('// SMTIgnoreCex: yes'),
|
|
171
|
+
engine: engine
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
// Run all tests
|
|
175
|
+
for (i in tests) {
|
|
176
|
+
const test = tests[i];
|
|
177
|
+
// Z3's nondeterminism sometimes causes a test to timeout in one context but not in the other,
|
|
178
|
+
// so if we see timeout we skip a potentially misleading run.
|
|
179
|
+
const findError = (errorMsg) => { return errorMsg.includes('Error trying to invoke SMT solver'); };
|
|
180
|
+
if (test.expectations.find(findError) !== undefined) {
|
|
181
|
+
st.skip('Test contains timeout which may have been caused by nondeterminism.');
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
let settings = {};
|
|
185
|
+
const engine = test.engine !== undefined ? test.engine : 'all';
|
|
186
|
+
settings = {
|
|
187
|
+
modelChecker: {
|
|
188
|
+
engine: engine,
|
|
189
|
+
solvers: [
|
|
190
|
+
'smtlib2'
|
|
191
|
+
]
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
const output = JSON.parse(__1.default.compile(JSON.stringify({
|
|
195
|
+
language: 'Hyperion',
|
|
196
|
+
sources: test.hyperion,
|
|
197
|
+
settings: settings
|
|
198
|
+
}),
|
|
199
|
+
// This test needs z3 specifically.
|
|
200
|
+
{ smtSolver: smtchecker_1.default.smtCallback(smtsolver_1.default.smtSolver, z3HornSolvers[0]) }));
|
|
201
|
+
st.ok(output);
|
|
202
|
+
// Collect obtained error messages
|
|
203
|
+
test.errors = collectErrors(output);
|
|
204
|
+
// These are errors in the SMTLib2Interface encoding.
|
|
205
|
+
if (test.errors.length > 0 && test.errors[test.errors.length - 1].includes('BMC analysis was not possible')) {
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
// These are due to CHC not being supported via SMTLib2Interface yet.
|
|
209
|
+
if (test.expectations.length !== test.errors.length) {
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
if (test.errors.find(findError) !== undefined) {
|
|
213
|
+
st.skip('Test contains timeout which may have been caused by nondeterminism.');
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
// Compare expected vs obtained errors
|
|
217
|
+
st.ok(expectErrors(test.expectations, test.errors, test.ignoreCex));
|
|
218
|
+
}
|
|
219
|
+
st.end();
|
|
220
|
+
});
|
|
221
|
+
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const tape_1 = __importDefault(require("tape"));
|
|
7
|
+
const __1 = __importDefault(require("../"));
|
|
8
|
+
const smtchecker_1 = __importDefault(require("../smtchecker"));
|
|
9
|
+
const smtsolver_1 = __importDefault(require("../smtsolver"));
|
|
10
|
+
const preamble = 'pragma hyperion >=0.0.1;\n// SPDX-License-Identifier: GPL-3.0\n';
|
|
11
|
+
//
|
|
12
|
+
(0, tape_1.default)('SMTChecker', function (t) {
|
|
13
|
+
// We use null for `solverFunction` and `solver` when calling `handleSMTQueries`
|
|
14
|
+
// because these tests do not call a solver.
|
|
15
|
+
t.test('smoke test with no axuiliaryInputRequested', function (st) {
|
|
16
|
+
const input = {};
|
|
17
|
+
const output = {};
|
|
18
|
+
st.equal(smtchecker_1.default.handleSMTQueries(input, output, null, null), null);
|
|
19
|
+
st.end();
|
|
20
|
+
});
|
|
21
|
+
t.test('smoke test with no smtlib2queries', function (st) {
|
|
22
|
+
const input = {};
|
|
23
|
+
const output = { auxiliaryInputRequested: {} };
|
|
24
|
+
st.equal(smtchecker_1.default.handleSMTQueries(input, output, null, null), null);
|
|
25
|
+
st.end();
|
|
26
|
+
});
|
|
27
|
+
t.test('smoke test with empty smtlib2queries', function (st) {
|
|
28
|
+
const input = {};
|
|
29
|
+
const output = { auxiliaryInputRequested: { smtlib2queries: {} } };
|
|
30
|
+
st.equal(smtchecker_1.default.handleSMTQueries(input, output, null, null), null);
|
|
31
|
+
st.end();
|
|
32
|
+
});
|
|
33
|
+
t.test('smtCallback should return type function', (st) => {
|
|
34
|
+
const response = smtchecker_1.default.smtCallback(() => { });
|
|
35
|
+
st.equal(typeof response, 'function');
|
|
36
|
+
st.end();
|
|
37
|
+
});
|
|
38
|
+
t.test('smtCallback should error when passed parser fails', (st) => {
|
|
39
|
+
const cbFun = smtchecker_1.default.smtCallback((content) => { throw new Error(content); });
|
|
40
|
+
const response = cbFun('expected-error-message');
|
|
41
|
+
st.deepEqual(response, { error: new Error('expected-error-message') });
|
|
42
|
+
st.end();
|
|
43
|
+
});
|
|
44
|
+
t.test('smtCallback should return content when passed parser does not fail', (st) => {
|
|
45
|
+
const cbFun = smtchecker_1.default.smtCallback((content) => { return content; });
|
|
46
|
+
const response = cbFun('expected-content-message');
|
|
47
|
+
st.deepEqual(response, { contents: 'expected-content-message' });
|
|
48
|
+
st.end();
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
(0, tape_1.default)('SMTCheckerWithSolver', function (t) {
|
|
52
|
+
// In these tests we require z3 to actually run the solver.
|
|
53
|
+
// This uses the SMT double run mechanism instead of the callback.
|
|
54
|
+
t.test('Simple test with axuiliaryInputRequested', function (st) {
|
|
55
|
+
const z3 = smtsolver_1.default.availableSolvers.filter(solver => solver.command === 'z3');
|
|
56
|
+
if (z3.length === 0) {
|
|
57
|
+
st.skip('Test requires z3.');
|
|
58
|
+
st.end();
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const settings = {
|
|
62
|
+
modelChecker: {
|
|
63
|
+
engine: 'chc',
|
|
64
|
+
solvers: ['smtlib2']
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
const source = { a: { content: preamble + '\ncontract C { function f(uint x) public pure { assert(x > 0); } }' } };
|
|
68
|
+
const input = {
|
|
69
|
+
language: 'Hyperion',
|
|
70
|
+
sources: source,
|
|
71
|
+
settings: settings
|
|
72
|
+
};
|
|
73
|
+
const output = JSON.parse(__1.default.compile(JSON.stringify(input)));
|
|
74
|
+
st.ok(output);
|
|
75
|
+
const newInput = smtchecker_1.default.handleSMTQueries(input, output, smtsolver_1.default.smtSolver, z3[0]);
|
|
76
|
+
st.notEqual(newInput, null);
|
|
77
|
+
const newOutput = JSON.parse(__1.default.compile(JSON.stringify(newInput)));
|
|
78
|
+
st.ok(newOutput);
|
|
79
|
+
const smtErrors = newOutput.errors.filter(e => e.errorCode === '6328');
|
|
80
|
+
st.equal(smtErrors.length, 1);
|
|
81
|
+
st.end();
|
|
82
|
+
});
|
|
83
|
+
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
const fs = __importStar(require("fs"));
|
|
30
|
+
const path = __importStar(require("path"));
|
|
31
|
+
const tape_1 = __importDefault(require("tape"));
|
|
32
|
+
const translate_1 = __importDefault(require("../translate"));
|
|
33
|
+
const versionToSemver = translate_1.default.versionToSemver;
|
|
34
|
+
(0, tape_1.default)('Version string to Semver translator', function (t) {
|
|
35
|
+
t.test('Only numbers', function (st) {
|
|
36
|
+
st.equal(versionToSemver('0.1.0'), '0.1.0');
|
|
37
|
+
st.end();
|
|
38
|
+
});
|
|
39
|
+
t.test('New style release (semver)', function (st) {
|
|
40
|
+
st.equal(versionToSemver('0.4.5+commit.b318366e.Emscripten.clang'), '0.4.5+commit.b318366e.Emscripten.clang');
|
|
41
|
+
st.end();
|
|
42
|
+
});
|
|
43
|
+
t.test('New style nightly (semver)', function (st) {
|
|
44
|
+
st.equal(versionToSemver('0.4.20-nightly.2018.2.13+commit.27ef9794.Emscripten.clang'), '0.4.20-nightly.2018.2.13+commit.27ef9794.Emscripten.clang');
|
|
45
|
+
st.end();
|
|
46
|
+
});
|
|
47
|
+
t.test('Old style 0.1.1', function (st) {
|
|
48
|
+
st.equal(versionToSemver('0.1.1-6ff4cd6b/RelWithDebInfo-Emscripten/clang/int'), '0.1.1+commit.6ff4cd6b');
|
|
49
|
+
st.end();
|
|
50
|
+
});
|
|
51
|
+
t.test('Old style 0.1.2', function (st) {
|
|
52
|
+
st.equal(versionToSemver('0.1.2-5c3bfd4b*/.-/clang/int'), '0.1.2+commit.5c3bfd4b');
|
|
53
|
+
st.end();
|
|
54
|
+
});
|
|
55
|
+
t.test('Broken 0.1.3', function (st) {
|
|
56
|
+
st.equal(versionToSemver('0.1.3-0/.-/clang/int linked to libzond-0.9.92-0/.-/clang/int'), '0.1.3');
|
|
57
|
+
st.end();
|
|
58
|
+
});
|
|
59
|
+
t.test('Old style 0.2.0', function (st) {
|
|
60
|
+
st.equal(versionToSemver('0.2.0-e7098958/.-Emscripten/clang/int linked to libzond-1.1.1-bbb80ab0/.-Emscripten/clang/int'), '0.2.0+commit.e7098958');
|
|
61
|
+
st.end();
|
|
62
|
+
});
|
|
63
|
+
t.test('Old style 0.3.5', function (st) {
|
|
64
|
+
// The one in the hypc-bin list
|
|
65
|
+
st.equal(versionToSemver('0.3.5-371690f0/Release-Emscripten/clang/Interpreter'), '0.3.5+commit.371690f0');
|
|
66
|
+
// The actual one reported by the compiler
|
|
67
|
+
st.equal(versionToSemver('0.3.5-0/Release-Emscripten/clang/Interpreter'), '0.3.5');
|
|
68
|
+
st.end();
|
|
69
|
+
});
|
|
70
|
+
t.test('Old style 0.3.6', function (st) {
|
|
71
|
+
st.equal(versionToSemver('0.3.6-3fc68da5/Release-Emscripten/clang'), '0.3.6+commit.3fc68da5');
|
|
72
|
+
st.end();
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
(0, tape_1.default)('prettyPrintLegacyAssemblyJSON', function (t) {
|
|
76
|
+
t.test('Works properly', function (st) {
|
|
77
|
+
const fixtureAsmJson = JSON.parse(fs.readFileSync(path.resolve(__dirname, 'resources/fixtureAsmJson.json')).toString());
|
|
78
|
+
const fixtureAsmJsonSource = fs.readFileSync(path.resolve(__dirname, 'resources/fixtureAsmJson.hyp')).toString();
|
|
79
|
+
const fixtureAsmJsonOutput = fs.readFileSync(path.resolve(__dirname, 'resources/fixtureAsmJson.output')).toString();
|
|
80
|
+
st.equal(translate_1.default.prettyPrintLegacyAssemblyJSON(fixtureAsmJson, fixtureAsmJsonSource), fixtureAsmJsonOutput);
|
|
81
|
+
st.end();
|
|
82
|
+
});
|
|
83
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[{"inputs":[],"name":"f","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
6080604052348015600e575f80fd5b5060ab8061001b5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c806326121ff014602a575b5f80fd5b60306044565b604051603b9190605e565b60405180910390f35b5f90565b5f819050919050565b6058816048565b82525050565b5f602082019050606f5f8301846051565b9291505056fea2646970667358221220a64bffebed1b5ea46c9e55283bb4753bda96a1f1cc64c005260afedb8a70c40a6468797063430000020033
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
6080604052348015600e575f80fd5b5060ab8061001b5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c806326121ff014602a575b5f80fd5b60306044565b604051603b9190605e565b60405180910390f35b5f90565b5f819050919050565b6058816048565b82525050565b5f602082019050606f5f8301846051565b9291505056fea26469706673582212203cd9e1982d54d4d890bf8e70885702652542c82b6abb83e7c15acee85073406c6468797063430000020033
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
6080604052348015600e575f80fd5b5060ab8061001b5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c806326121ff014602a575b5f80fd5b60306044565b604051603b9190605e565b60405180910390f35b5f90565b5f819050919050565b6058816048565b82525050565b5f602082019050606f5f8301846051565b9291505056fea26469706673582212207037e01e24ae6d283b7725b9545b7c4376d40d1a1186404fcfd6d3b064b2ca786468797063430000020033
|
package/translate.js
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
const linker_1 = __importDefault(require("./linker"));
|
|
6
|
+
/// Translate old style version numbers to semver.
|
|
7
|
+
/// Old style: 0.3.6-3fc68da5/Release-Emscripten/clang
|
|
8
|
+
/// 0.3.5-371690f0/Release-Emscripten/clang/Interpreter
|
|
9
|
+
/// 0.3.5-0/Release-Emscripten/clang/Interpreter
|
|
10
|
+
/// 0.2.0-e7098958/.-Emscripten/clang/int linked to libzond-1.1.1-bbb80ab0/.-Emscripten/clang/int
|
|
11
|
+
/// 0.1.3-0/.-/clang/int linked to libzond-0.9.92-0/.-/clang/int
|
|
12
|
+
/// 0.1.2-5c3bfd4b*/.-/clang/int
|
|
13
|
+
/// 0.1.1-6ff4cd6b/RelWithDebInfo-Emscripten/clang/int
|
|
14
|
+
/// New style: 0.4.5+commit.b318366e.Emscripten.clang
|
|
15
|
+
function versionToSemver(version) {
|
|
16
|
+
// FIXME: parse more detail, but this is a good start
|
|
17
|
+
const parsed = version.match(/^([0-9]+\.[0-9]+\.[0-9]+)-([0-9a-f]{8})[/*].*$/);
|
|
18
|
+
if (parsed) {
|
|
19
|
+
return parsed[1] + '+commit.' + parsed[2];
|
|
20
|
+
}
|
|
21
|
+
if (version.indexOf('0.1.3-0') !== -1) {
|
|
22
|
+
return '0.1.3';
|
|
23
|
+
}
|
|
24
|
+
if (version.indexOf('0.3.5-0') !== -1) {
|
|
25
|
+
return '0.3.5';
|
|
26
|
+
}
|
|
27
|
+
// assume it is already semver compatible
|
|
28
|
+
return version;
|
|
29
|
+
}
|
|
30
|
+
function translateErrors(ret, errors) {
|
|
31
|
+
for (const error in errors) {
|
|
32
|
+
let type = 'error';
|
|
33
|
+
let extractType = /^(.*):(\d+):(\d+):(.*):/;
|
|
34
|
+
extractType = extractType.exec(errors[error]);
|
|
35
|
+
if (extractType) {
|
|
36
|
+
type = extractType[4].trim();
|
|
37
|
+
}
|
|
38
|
+
else if (errors[error].indexOf(': Warning:')) {
|
|
39
|
+
type = 'Warning';
|
|
40
|
+
}
|
|
41
|
+
else if (errors[error].indexOf(': Error:')) {
|
|
42
|
+
type = 'Error';
|
|
43
|
+
}
|
|
44
|
+
ret.push({
|
|
45
|
+
type: type,
|
|
46
|
+
component: 'general',
|
|
47
|
+
severity: (type === 'Warning') ? 'warning' : 'error',
|
|
48
|
+
message: errors[error],
|
|
49
|
+
formattedMessage: errors[error]
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function translateGasEstimates(gasEstimates) {
|
|
54
|
+
if (gasEstimates === null) {
|
|
55
|
+
return 'infinite';
|
|
56
|
+
}
|
|
57
|
+
if (typeof gasEstimates === 'number') {
|
|
58
|
+
return gasEstimates.toString();
|
|
59
|
+
}
|
|
60
|
+
const gasEstimatesTranslated = {};
|
|
61
|
+
for (const func in gasEstimates) {
|
|
62
|
+
gasEstimatesTranslated[func] = translateGasEstimates(gasEstimates[func]);
|
|
63
|
+
}
|
|
64
|
+
return gasEstimatesTranslated;
|
|
65
|
+
}
|
|
66
|
+
function translateJsonCompilerOutput(output, libraries) {
|
|
67
|
+
const ret = {};
|
|
68
|
+
ret.errors = [];
|
|
69
|
+
let errors;
|
|
70
|
+
if (output.error) {
|
|
71
|
+
errors = [output.error];
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
errors = output.errors;
|
|
75
|
+
}
|
|
76
|
+
translateErrors(ret.errors, errors);
|
|
77
|
+
ret.contracts = {};
|
|
78
|
+
for (const contract in output.contracts) {
|
|
79
|
+
// Split name first, can be `contract`, `:contract` or `filename:contract`
|
|
80
|
+
const tmp = contract.match(/^((.*):)?([^:]+)$/);
|
|
81
|
+
if (tmp.length !== 4) {
|
|
82
|
+
// Force abort
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
let fileName = tmp[2];
|
|
86
|
+
if (fileName === undefined) {
|
|
87
|
+
// this is the case of `contract`
|
|
88
|
+
fileName = '';
|
|
89
|
+
}
|
|
90
|
+
const contractName = tmp[3];
|
|
91
|
+
const contractInput = output.contracts[contract];
|
|
92
|
+
const gasEstimates = contractInput.gasEstimates;
|
|
93
|
+
const translatedGasEstimates = {};
|
|
94
|
+
if (gasEstimates.creation) {
|
|
95
|
+
translatedGasEstimates.creation = {
|
|
96
|
+
codeDepositCost: translateGasEstimates(gasEstimates.creation[1]),
|
|
97
|
+
executionCost: translateGasEstimates(gasEstimates.creation[0])
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
if (gasEstimates.internal) {
|
|
101
|
+
translatedGasEstimates.internal = translateGasEstimates(gasEstimates.internal);
|
|
102
|
+
}
|
|
103
|
+
if (gasEstimates.external) {
|
|
104
|
+
translatedGasEstimates.external = translateGasEstimates(gasEstimates.external);
|
|
105
|
+
}
|
|
106
|
+
const contractOutput = {
|
|
107
|
+
abi: JSON.parse(contractInput.interface),
|
|
108
|
+
metadata: contractInput.metadata,
|
|
109
|
+
zvm: {
|
|
110
|
+
legacyAssembly: contractInput.assembly,
|
|
111
|
+
bytecode: {
|
|
112
|
+
object: contractInput.bytecode && linker_1.default.linkBytecode(contractInput.bytecode, libraries || {}),
|
|
113
|
+
opcodes: contractInput.opcodes,
|
|
114
|
+
sourceMap: contractInput.srcmap,
|
|
115
|
+
linkReferences: contractInput.bytecode && linker_1.default.findLinkReferences(contractInput.bytecode)
|
|
116
|
+
},
|
|
117
|
+
deployedBytecode: {
|
|
118
|
+
object: contractInput.runtimeBytecode && linker_1.default.linkBytecode(contractInput.runtimeBytecode, libraries || {}),
|
|
119
|
+
sourceMap: contractInput.srcmapRuntime,
|
|
120
|
+
linkReferences: contractInput.runtimeBytecode && linker_1.default.findLinkReferences(contractInput.runtimeBytecode)
|
|
121
|
+
},
|
|
122
|
+
methodIdentifiers: contractInput.functionHashes,
|
|
123
|
+
gasEstimates: translatedGasEstimates
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
if (!ret.contracts[fileName]) {
|
|
127
|
+
ret.contracts[fileName] = {};
|
|
128
|
+
}
|
|
129
|
+
ret.contracts[fileName][contractName] = contractOutput;
|
|
130
|
+
}
|
|
131
|
+
const sourceMap = {};
|
|
132
|
+
for (const sourceId in output.sourceList) {
|
|
133
|
+
sourceMap[output.sourceList[sourceId]] = sourceId;
|
|
134
|
+
}
|
|
135
|
+
ret.sources = {};
|
|
136
|
+
for (const source in output.sources) {
|
|
137
|
+
ret.sources[source] = {
|
|
138
|
+
id: sourceMap[source],
|
|
139
|
+
legacyAST: output.sources[source].AST
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
return ret;
|
|
143
|
+
}
|
|
144
|
+
function escapeString(text) {
|
|
145
|
+
return text
|
|
146
|
+
.replace(/\n/g, '\\n')
|
|
147
|
+
.replace(/\r/g, '\\r')
|
|
148
|
+
.replace(/\t/g, '\\t');
|
|
149
|
+
}
|
|
150
|
+
// 'asm' can be an object or a string
|
|
151
|
+
function formatAssemblyText(asm, prefix, source) {
|
|
152
|
+
if (typeof asm === 'string' || asm === null || asm === undefined) {
|
|
153
|
+
return prefix + (asm || '') + '\n';
|
|
154
|
+
}
|
|
155
|
+
let text = prefix + '.code\n';
|
|
156
|
+
asm['.code'].forEach(function (item, i) {
|
|
157
|
+
const v = item.value === undefined ? '' : item.value;
|
|
158
|
+
let src = '';
|
|
159
|
+
if (source !== undefined && item.begin !== undefined && item.end !== undefined) {
|
|
160
|
+
src = escapeString(source.slice(item.begin, item.end));
|
|
161
|
+
}
|
|
162
|
+
if (src.length > 30) {
|
|
163
|
+
src = src.slice(0, 30) + '...';
|
|
164
|
+
}
|
|
165
|
+
if (item.name !== 'tag') {
|
|
166
|
+
text += ' ';
|
|
167
|
+
}
|
|
168
|
+
text += prefix + item.name + ' ' + v + '\t\t\t' + src + '\n';
|
|
169
|
+
});
|
|
170
|
+
text += prefix + '.data\n';
|
|
171
|
+
const asmData = asm['.data'] || [];
|
|
172
|
+
for (const i in asmData) {
|
|
173
|
+
const item = asmData[i];
|
|
174
|
+
text += ' ' + prefix + '' + i + ':\n';
|
|
175
|
+
text += formatAssemblyText(item, prefix + ' ', source);
|
|
176
|
+
}
|
|
177
|
+
return text;
|
|
178
|
+
}
|
|
179
|
+
function prettyPrintLegacyAssemblyJSON(assembly, source) {
|
|
180
|
+
return formatAssemblyText(assembly, '', source);
|
|
181
|
+
}
|
|
182
|
+
module.exports = {
|
|
183
|
+
versionToSemver,
|
|
184
|
+
translateJsonCompilerOutput,
|
|
185
|
+
prettyPrintLegacyAssemblyJSON
|
|
186
|
+
};
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "esnext",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"resolveJsonModule": true,
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"outDir": "./dist",
|
|
8
|
+
"forceConsistentCasingInFileNames": true,
|
|
9
|
+
"allowJs": true,
|
|
10
|
+
"strict": false,
|
|
11
|
+
"noImplicitAny": false
|
|
12
|
+
},
|
|
13
|
+
"include": [
|
|
14
|
+
"**/*.js",
|
|
15
|
+
"**/*.ts",
|
|
16
|
+
"**/*.json"
|
|
17
|
+
],
|
|
18
|
+
"exclude": [
|
|
19
|
+
"coverage",
|
|
20
|
+
"dist"
|
|
21
|
+
],
|
|
22
|
+
"ts-node": {
|
|
23
|
+
"transpileOnly": true
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
6055604b600b8282823980515f1a607314603f577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe730000000000000000000000000000000000000000301460806040525f80fdfea2646970667358221220c6f7f973579a348b89e77c0e22d1800927ba997a07148e7c7b4d9cff3451b45c6468797063430000020033
|