@cashscript/utils 0.13.0 → 0.13.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/dist/bitauth-script.js +17 -0
- package/dist/script.js +20 -2
- package/dist/types.d.ts +3 -1
- package/dist/types.js +2 -0
- package/package.json +2 -2
package/dist/bitauth-script.js
CHANGED
|
@@ -48,6 +48,11 @@ const PROLOGUE_KINDS = [
|
|
|
48
48
|
SourceTagKind.LOCKTIME_GUARD,
|
|
49
49
|
SourceTagKind.PARAMETER_VALIDATION,
|
|
50
50
|
];
|
|
51
|
+
// Compiler-injected epilogue checks: emitted after the function/loop body
|
|
52
|
+
const EPILOGUE_KINDS = [
|
|
53
|
+
SourceTagKind.SCOPE_CLEANUP,
|
|
54
|
+
SourceTagKind.LOOP_CONDITION,
|
|
55
|
+
];
|
|
51
56
|
function buildInsertions(locationData, sourceLines, sourceTags) {
|
|
52
57
|
const tags = (sourceTags ? parseSourceTags(sourceTags) : []);
|
|
53
58
|
return tags.map((tag) => {
|
|
@@ -70,6 +75,14 @@ function deriveAnchor(tag, tags, locationData, sourceLines) {
|
|
|
70
75
|
indent: lineIndent(sourceLines, firstBodyLine),
|
|
71
76
|
};
|
|
72
77
|
}
|
|
78
|
+
// Scope cleanup and loop-back condition tags always get inserted right before the scope's closing brace.
|
|
79
|
+
if (EPILOGUE_KINDS.includes(tag.kind)) {
|
|
80
|
+
const braceLine = getDisplayLine(locationData[tag.startIndex]);
|
|
81
|
+
return {
|
|
82
|
+
insertAfterLine: braceLine - 1,
|
|
83
|
+
indent: deriveIndent(locationData[tag.startIndex].location.start.line, sourceLines),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
73
86
|
return {
|
|
74
87
|
insertAfterLine: getDisplayLine(locationData[Math.max(tag.startIndex - 1, 0)]),
|
|
75
88
|
indent: deriveIndent(getDisplayLine(locationData[tag.startIndex]), sourceLines),
|
|
@@ -113,6 +126,10 @@ function tagDescription(tag, locationData, sourceLines) {
|
|
|
113
126
|
const parameter = deriveSourceText(tag, locationData, sourceLines);
|
|
114
127
|
return `>>> parameter type check${parameter ? ` (${parameter})` : ''}`;
|
|
115
128
|
}
|
|
129
|
+
case SourceTagKind.SCOPE_CLEANUP:
|
|
130
|
+
return '>>> scope cleanup';
|
|
131
|
+
case SourceTagKind.LOOP_CONDITION:
|
|
132
|
+
return '>>> loop condition check';
|
|
116
133
|
case SourceTagKind.FOR_UPDATE:
|
|
117
134
|
default:
|
|
118
135
|
return `>>> for-loop update (${deriveSourceText(tag, locationData, sourceLines)})`;
|
package/dist/script.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { encodeDataPush, hexToBin, disassembleBytecodeBch, flattenBinArray, encodeAuthenticationInstructions, decodeAuthenticationInstructions, OpcodesBch, } from '@bitauth/libauth';
|
|
2
2
|
import OptimisationsEquivFile from './cashproof-optimisations.js';
|
|
3
3
|
import { optimisationReplacements } from './optimisations.js';
|
|
4
|
-
import {
|
|
4
|
+
import { range } from './data.js';
|
|
5
|
+
import { PositionHint, SourceTagKind } from './types.js';
|
|
5
6
|
export const Op = OpcodesBch;
|
|
6
7
|
export function scriptToAsm(script) {
|
|
7
8
|
return bytecodeToAsm(scriptToBytecode(script));
|
|
@@ -120,7 +121,24 @@ export function optimiseBytecode(script, locationData, logs, requires, sourceTag
|
|
|
120
121
|
requires = newRequires;
|
|
121
122
|
sourceTags = newSourceTags;
|
|
122
123
|
}
|
|
123
|
-
return { script, locationData, logs, requires, sourceTags };
|
|
124
|
+
return { script, locationData, logs, requires, sourceTags: reconcileScopeCleanupTags(script, sourceTags) };
|
|
125
|
+
}
|
|
126
|
+
const SCOPE_CLEANUP_OPCODES = [Op.OP_DROP, Op.OP_NIP, Op.OP_2DROP];
|
|
127
|
+
// Make sure that scope cleanup tags are only displayed if they did not merge with other tags or drift
|
|
128
|
+
// due to compiler optimisations.
|
|
129
|
+
function reconcileScopeCleanupTags(script, sourceTags) {
|
|
130
|
+
const otherTags = sourceTags.filter((tag) => tag.kind !== SourceTagKind.SCOPE_CLEANUP);
|
|
131
|
+
return sourceTags.filter((tag) => {
|
|
132
|
+
if (tag.kind !== SourceTagKind.SCOPE_CLEANUP)
|
|
133
|
+
return true;
|
|
134
|
+
const isOnlyCleanupOpcodes = range(tag.startIndex, tag.endIndex)
|
|
135
|
+
.every((index) => SCOPE_CLEANUP_OPCODES.includes(script[index]));
|
|
136
|
+
if (!isOnlyCleanupOpcodes)
|
|
137
|
+
return false;
|
|
138
|
+
const overlapsOtherTag = otherTags
|
|
139
|
+
.some((other) => tag.startIndex <= other.endIndex && other.startIndex <= tag.endIndex);
|
|
140
|
+
return !overlapsOtherTag;
|
|
141
|
+
});
|
|
124
142
|
}
|
|
125
143
|
export function optimiseBytecodeOld(script, runs = 1000) {
|
|
126
144
|
const optimisations = OptimisationsEquivFile
|
package/dist/types.d.ts
CHANGED
|
@@ -54,7 +54,9 @@ export declare enum PositionHint {
|
|
|
54
54
|
export declare enum SourceTagKind {
|
|
55
55
|
FOR_UPDATE = "fu",
|
|
56
56
|
LOCKTIME_GUARD = "lg",
|
|
57
|
-
PARAMETER_VALIDATION = "pv"
|
|
57
|
+
PARAMETER_VALIDATION = "pv",
|
|
58
|
+
SCOPE_CLEANUP = "sc",
|
|
59
|
+
LOOP_CONDITION = "lc"
|
|
58
60
|
}
|
|
59
61
|
export interface SourceTagEntry {
|
|
60
62
|
startIndex: number;
|
package/dist/types.js
CHANGED
|
@@ -197,5 +197,7 @@ export var SourceTagKind;
|
|
|
197
197
|
SourceTagKind["FOR_UPDATE"] = "fu";
|
|
198
198
|
SourceTagKind["LOCKTIME_GUARD"] = "lg";
|
|
199
199
|
SourceTagKind["PARAMETER_VALIDATION"] = "pv";
|
|
200
|
+
SourceTagKind["SCOPE_CLEANUP"] = "sc";
|
|
201
|
+
SourceTagKind["LOOP_CONDITION"] = "lc";
|
|
200
202
|
})(SourceTagKind || (SourceTagKind = {}));
|
|
201
203
|
//# sourceMappingURL=types.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cashscript/utils",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.2",
|
|
4
4
|
"description": "CashScript utilities and types",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bitcoin cash",
|
|
@@ -48,5 +48,5 @@
|
|
|
48
48
|
"typescript": "^5.9.2",
|
|
49
49
|
"vitest": "^4.0.15"
|
|
50
50
|
},
|
|
51
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "a4f112abb0d035ecf018ebc694e2b081f25b3409"
|
|
52
52
|
}
|