Updated dist files.
This commit is contained in:
parent
a6b696d8bd
commit
f9ab665b52
2
packages/abi/lib.esm/_version.d.ts
vendored
2
packages/abi/lib.esm/_version.d.ts
vendored
@ -1 +1 @@
|
|||||||
export declare const version = "abi/5.0.0-beta.144";
|
export declare const version = "abi/5.0.0-beta.145";
|
||||||
|
@ -1 +1 @@
|
|||||||
export const version = "abi/5.0.0-beta.144";
|
export const version = "abi/5.0.0-beta.145";
|
||||||
|
2
packages/abi/lib.esm/interface.d.ts
vendored
2
packages/abi/lib.esm/interface.d.ts
vendored
@ -41,7 +41,7 @@ export declare class Interface {
|
|||||||
};
|
};
|
||||||
readonly deploy: ConstructorFragment;
|
readonly deploy: ConstructorFragment;
|
||||||
readonly _abiCoder: AbiCoder;
|
readonly _abiCoder: AbiCoder;
|
||||||
static _isInterface: boolean;
|
readonly _isInterface: boolean;
|
||||||
constructor(fragments: string | Array<Fragment | JsonFragment | string>);
|
constructor(fragments: string | Array<Fragment | JsonFragment | string>);
|
||||||
format(format?: string): string | Array<string>;
|
format(format?: string): string | Array<string>;
|
||||||
static getAbiCoder(): AbiCoder;
|
static getAbiCoder(): AbiCoder;
|
||||||
|
2
packages/abi/lib/_version.d.ts
vendored
2
packages/abi/lib/_version.d.ts
vendored
@ -1 +1 @@
|
|||||||
export declare const version = "abi/5.0.0-beta.144";
|
export declare const version = "abi/5.0.0-beta.145";
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.version = "abi/5.0.0-beta.144";
|
exports.version = "abi/5.0.0-beta.145";
|
||||||
|
2
packages/abi/lib/interface.d.ts
vendored
2
packages/abi/lib/interface.d.ts
vendored
@ -41,7 +41,7 @@ export declare class Interface {
|
|||||||
};
|
};
|
||||||
readonly deploy: ConstructorFragment;
|
readonly deploy: ConstructorFragment;
|
||||||
readonly _abiCoder: AbiCoder;
|
readonly _abiCoder: AbiCoder;
|
||||||
static _isInterface: boolean;
|
readonly _isInterface: boolean;
|
||||||
constructor(fragments: string | Array<Fragment | JsonFragment | string>);
|
constructor(fragments: string | Array<Fragment | JsonFragment | string>);
|
||||||
format(format?: string): string | Array<string>;
|
format(format?: string): string | Array<string>;
|
||||||
static getAbiCoder(): AbiCoder;
|
static getAbiCoder(): AbiCoder;
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"tarballHash": "0x6f0200ce3170d8149ac6b5a736d2bd519bfa6648d0a60ff773aafa47a17b1e85",
|
"tarballHash": "0xea1c770d87b34f15239a3ddbc5813d90e7627b57b9afa633997dfb903ca51efd",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"version": "5.0.0-beta.144"
|
"version": "5.0.0-beta.145"
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
export const version = "abi/5.0.0-beta.144";
|
export const version = "abi/5.0.0-beta.145";
|
||||||
|
@ -1 +1 @@
|
|||||||
export declare const version = "abstract-signer/5.0.0-beta.139";
|
export declare const version = "abstract-signer/5.0.0-beta.140";
|
||||||
|
@ -1 +1 @@
|
|||||||
export const version = "abstract-signer/5.0.0-beta.139";
|
export const version = "abstract-signer/5.0.0-beta.140";
|
||||||
|
@ -122,25 +122,9 @@ export class Signer {
|
|||||||
if (tx.nonce == null) {
|
if (tx.nonce == null) {
|
||||||
tx.nonce = this.getTransactionCount("pending");
|
tx.nonce = this.getTransactionCount("pending");
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
// checkTransaction does this...
|
|
||||||
if (tx.from == null) {
|
|
||||||
tx.from = this.getAddress();
|
|
||||||
} else {
|
|
||||||
tx.from = Promise.all([
|
|
||||||
this.getAddress(),
|
|
||||||
this.provider.resolveName(tx.from)
|
|
||||||
]).then((results) => {
|
|
||||||
if (results[0] !== results[1]) {
|
|
||||||
logger.throwArgumentError("from address mismatch", "transaction", transaction);
|
|
||||||
}
|
|
||||||
return results[0];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if (tx.gasLimit == null) {
|
if (tx.gasLimit == null) {
|
||||||
tx.gasLimit = this.estimateGas(tx).catch((error) => {
|
tx.gasLimit = this.estimateGas(tx).catch((error) => {
|
||||||
logger.throwError("cannot estimate gas; transaction may fail or may require manual gas limit", Logger.errors.UNPREDICTABLE_GAS_LIMIT, {
|
return logger.throwError("cannot estimate gas; transaction may fail or may require manual gas limit", Logger.errors.UNPREDICTABLE_GAS_LIMIT, {
|
||||||
tx: tx
|
tx: tx
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
2
packages/abstract-signer/lib/_version.d.ts
vendored
2
packages/abstract-signer/lib/_version.d.ts
vendored
@ -1 +1 @@
|
|||||||
export declare const version = "abstract-signer/5.0.0-beta.139";
|
export declare const version = "abstract-signer/5.0.0-beta.140";
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.version = "abstract-signer/5.0.0-beta.139";
|
exports.version = "abstract-signer/5.0.0-beta.140";
|
||||||
|
@ -173,25 +173,9 @@ var Signer = /** @class */ (function () {
|
|||||||
if (tx.nonce == null) {
|
if (tx.nonce == null) {
|
||||||
tx.nonce = this.getTransactionCount("pending");
|
tx.nonce = this.getTransactionCount("pending");
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
// checkTransaction does this...
|
|
||||||
if (tx.from == null) {
|
|
||||||
tx.from = this.getAddress();
|
|
||||||
} else {
|
|
||||||
tx.from = Promise.all([
|
|
||||||
this.getAddress(),
|
|
||||||
this.provider.resolveName(tx.from)
|
|
||||||
]).then((results) => {
|
|
||||||
if (results[0] !== results[1]) {
|
|
||||||
logger.throwArgumentError("from address mismatch", "transaction", transaction);
|
|
||||||
}
|
|
||||||
return results[0];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if (tx.gasLimit == null) {
|
if (tx.gasLimit == null) {
|
||||||
tx.gasLimit = this.estimateGas(tx).catch(function (error) {
|
tx.gasLimit = this.estimateGas(tx).catch(function (error) {
|
||||||
logger.throwError("cannot estimate gas; transaction may fail or may require manual gas limit", logger_1.Logger.errors.UNPREDICTABLE_GAS_LIMIT, {
|
return logger.throwError("cannot estimate gas; transaction may fail or may require manual gas limit", logger_1.Logger.errors.UNPREDICTABLE_GAS_LIMIT, {
|
||||||
tx: tx
|
tx: tx
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"tarballHash": "0xe2e6e52bcdae724519b652bf02b2c3779db22c7da7ce7af404c5a6b152a56fb0",
|
"tarballHash": "0x45c10e64c71e99997884ff59d59e6e3829043a155d8109bc2ee644efc40c3c43",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"version": "5.0.0-beta.139"
|
"version": "5.0.0-beta.140"
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
export const version = "abstract-signer/5.0.0-beta.139";
|
export const version = "abstract-signer/5.0.0-beta.140";
|
||||||
|
@ -161,32 +161,15 @@ export abstract class Signer {
|
|||||||
// By default called from: (overriding these prevents it)
|
// By default called from: (overriding these prevents it)
|
||||||
// - sendTransaction
|
// - sendTransaction
|
||||||
async populateTransaction(transaction: TransactionRequest): Promise<TransactionRequest> {
|
async populateTransaction(transaction: TransactionRequest): Promise<TransactionRequest> {
|
||||||
const tx = await resolveProperties(this.checkTransaction(transaction))
|
const tx: TransactionRequest = await resolveProperties(this.checkTransaction(transaction))
|
||||||
|
|
||||||
if (tx.to != null) { tx.to = Promise.resolve(tx.to).then((to) => this.resolveName(to)); }
|
if (tx.to != null) { tx.to = Promise.resolve(tx.to).then((to) => this.resolveName(to)); }
|
||||||
if (tx.gasPrice == null) { tx.gasPrice = this.getGasPrice(); }
|
if (tx.gasPrice == null) { tx.gasPrice = this.getGasPrice(); }
|
||||||
if (tx.nonce == null) { tx.nonce = this.getTransactionCount("pending"); }
|
if (tx.nonce == null) { tx.nonce = this.getTransactionCount("pending"); }
|
||||||
|
|
||||||
/*
|
|
||||||
// checkTransaction does this...
|
|
||||||
if (tx.from == null) {
|
|
||||||
tx.from = this.getAddress();
|
|
||||||
} else {
|
|
||||||
tx.from = Promise.all([
|
|
||||||
this.getAddress(),
|
|
||||||
this.provider.resolveName(tx.from)
|
|
||||||
]).then((results) => {
|
|
||||||
if (results[0] !== results[1]) {
|
|
||||||
logger.throwArgumentError("from address mismatch", "transaction", transaction);
|
|
||||||
}
|
|
||||||
return results[0];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (tx.gasLimit == null) {
|
if (tx.gasLimit == null) {
|
||||||
tx.gasLimit = this.estimateGas(tx).catch((error) => {
|
tx.gasLimit = this.estimateGas(tx).catch((error) => {
|
||||||
logger.throwError("cannot estimate gas; transaction may fail or may require manual gas limit", Logger.errors.UNPREDICTABLE_GAS_LIMIT, {
|
return logger.throwError("cannot estimate gas; transaction may fail or may require manual gas limit", Logger.errors.UNPREDICTABLE_GAS_LIMIT, {
|
||||||
tx: tx
|
tx: tx
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
2
packages/asm/lib.esm/_version.d.ts
vendored
2
packages/asm/lib.esm/_version.d.ts
vendored
@ -1 +1 @@
|
|||||||
export declare const version = "asm/5.0.0-beta.148";
|
export declare const version = "asm/5.0.0-beta.149";
|
||||||
|
@ -1 +1 @@
|
|||||||
export const version = "asm/5.0.0-beta.148";
|
export const version = "asm/5.0.0-beta.149";
|
||||||
|
71
packages/asm/lib.esm/assembler.d.ts
vendored
71
packages/asm/lib.esm/assembler.d.ts
vendored
@ -1,15 +1,16 @@
|
|||||||
import { Opcode } from "./opcodes";
|
import { Opcode } from "./opcodes";
|
||||||
export declare type Location = {
|
export declare type Location = {
|
||||||
offset: number;
|
offset: number;
|
||||||
|
line: number;
|
||||||
length: number;
|
length: number;
|
||||||
source: string;
|
source: string;
|
||||||
|
statement: boolean;
|
||||||
};
|
};
|
||||||
export declare type AssembleVisitFunc = (node: Node, bytecode: string) => void;
|
export declare type AssembleVisitFunc = (node: Node, bytecode: string) => void;
|
||||||
export declare type VisitFunc = (node: Node) => void;
|
export declare type VisitFunc = (node: Node) => void;
|
||||||
export declare abstract class Node {
|
export declare abstract class Node {
|
||||||
readonly tag: string;
|
readonly tag: string;
|
||||||
readonly location: Location;
|
readonly location: Location;
|
||||||
readonly warnings: Array<string>;
|
|
||||||
constructor(guard: any, location: Location, options: {
|
constructor(guard: any, location: Location, options: {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
});
|
});
|
||||||
@ -30,6 +31,12 @@ export declare class LiteralNode extends ValueNode {
|
|||||||
assemble(assembler: Assembler, visit: AssembleVisitFunc): Promise<void>;
|
assemble(assembler: Assembler, visit: AssembleVisitFunc): Promise<void>;
|
||||||
static from(options: any): LiteralNode;
|
static from(options: any): LiteralNode;
|
||||||
}
|
}
|
||||||
|
export declare class PopNode extends ValueNode {
|
||||||
|
readonly index: number;
|
||||||
|
constructor(guard: any, location: Location, index: number);
|
||||||
|
readonly placeholder: string;
|
||||||
|
static from(options: any): PopNode;
|
||||||
|
}
|
||||||
export declare class LinkNode extends ValueNode {
|
export declare class LinkNode extends ValueNode {
|
||||||
readonly type: string;
|
readonly type: string;
|
||||||
readonly label: string;
|
readonly label: string;
|
||||||
@ -40,7 +47,8 @@ export declare class LinkNode extends ValueNode {
|
|||||||
export declare class OpcodeNode extends ValueNode {
|
export declare class OpcodeNode extends ValueNode {
|
||||||
readonly opcode: Opcode;
|
readonly opcode: Opcode;
|
||||||
readonly operands: Array<ValueNode>;
|
readonly operands: Array<ValueNode>;
|
||||||
constructor(guard: any, location: Location, opcode: Opcode, operands: Array<ValueNode>);
|
readonly instructional: boolean;
|
||||||
|
constructor(guard: any, location: Location, opcode: Opcode, operands: Array<ValueNode>, instructional: boolean);
|
||||||
assemble(assembler: Assembler, visit: AssembleVisitFunc): Promise<void>;
|
assemble(assembler: Assembler, visit: AssembleVisitFunc): Promise<void>;
|
||||||
children(): Array<Node>;
|
children(): Array<Node>;
|
||||||
visit(visit: VisitFunc): void;
|
visit(visit: VisitFunc): void;
|
||||||
@ -61,7 +69,6 @@ export declare class DataNode extends LabelledNode {
|
|||||||
constructor(guard: any, location: Location, name: string, data: string);
|
constructor(guard: any, location: Location, name: string, data: string);
|
||||||
assemble(assembler: Assembler, visit: AssembleVisitFunc): Promise<void>;
|
assemble(assembler: Assembler, visit: AssembleVisitFunc): Promise<void>;
|
||||||
children(): Array<Node>;
|
children(): Array<Node>;
|
||||||
visit(visit: VisitFunc): void;
|
|
||||||
static from(options: any): DataNode;
|
static from(options: any): DataNode;
|
||||||
}
|
}
|
||||||
export declare class EvaluationNode extends ValueNode {
|
export declare class EvaluationNode extends ValueNode {
|
||||||
@ -82,10 +89,8 @@ export declare class ScopeNode extends LabelledNode {
|
|||||||
constructor(guard: any, location: Location, name: string, statements: Array<Node>);
|
constructor(guard: any, location: Location, name: string, statements: Array<Node>);
|
||||||
assemble(assembler: Assembler, visit: AssembleVisitFunc): Promise<void>;
|
assemble(assembler: Assembler, visit: AssembleVisitFunc): Promise<void>;
|
||||||
children(): Array<Node>;
|
children(): Array<Node>;
|
||||||
visit(visit: VisitFunc): void;
|
|
||||||
static from(options: any): ScopeNode;
|
static from(options: any): ScopeNode;
|
||||||
}
|
}
|
||||||
export declare function parse(code: string): Node;
|
|
||||||
export declare type Operation = {
|
export declare type Operation = {
|
||||||
opcode: Opcode;
|
opcode: Opcode;
|
||||||
offset: number;
|
offset: number;
|
||||||
@ -96,15 +101,15 @@ export interface Bytecode extends Array<Operation> {
|
|||||||
}
|
}
|
||||||
export declare function disassemble(bytecode: string): Bytecode;
|
export declare function disassemble(bytecode: string): Bytecode;
|
||||||
export declare function formatBytecode(bytecode: Array<Operation>): string;
|
export declare function formatBytecode(bytecode: Array<Operation>): string;
|
||||||
interface DataSource extends Array<number> {
|
export interface DataSource extends Array<number> {
|
||||||
readonly offset: number;
|
offset: number;
|
||||||
|
ast: Node;
|
||||||
|
source: string;
|
||||||
}
|
}
|
||||||
declare type NodeState = {
|
export declare type NodeState = {
|
||||||
node: Node;
|
node: Node;
|
||||||
offset: number;
|
offset: number;
|
||||||
bytecode: string;
|
bytecode: string;
|
||||||
pending: string;
|
|
||||||
object?: number | DataSource;
|
|
||||||
};
|
};
|
||||||
export declare type AssemblerOptions = {
|
export declare type AssemblerOptions = {
|
||||||
filename?: string;
|
filename?: string;
|
||||||
@ -113,42 +118,46 @@ export declare type AssemblerOptions = {
|
|||||||
defines?: {
|
defines?: {
|
||||||
[name: string]: any;
|
[name: string]: any;
|
||||||
};
|
};
|
||||||
|
target?: string;
|
||||||
|
};
|
||||||
|
export declare type ParserOptions = {
|
||||||
|
ignoreWarnings?: boolean;
|
||||||
};
|
};
|
||||||
declare class Assembler {
|
declare class Assembler {
|
||||||
readonly root: Node;
|
readonly root: Node;
|
||||||
|
readonly positionIndependentCode: boolean;
|
||||||
readonly nodes: {
|
readonly nodes: {
|
||||||
[tag: string]: NodeState;
|
[tag: string]: NodeState;
|
||||||
};
|
};
|
||||||
readonly labels: {
|
readonly labels: {
|
||||||
[name: string]: LabelledNode;
|
[name: string]: LabelledNode;
|
||||||
};
|
};
|
||||||
readonly filename: string;
|
_parents: {
|
||||||
readonly positionIndependentCode: boolean;
|
[tag: string]: Node;
|
||||||
readonly retry: number;
|
|
||||||
readonly defines: {
|
|
||||||
[name: string]: any;
|
|
||||||
};
|
};
|
||||||
private _stack;
|
constructor(root: Node, positionIndependentCode?: boolean);
|
||||||
private _parents;
|
getTarget(label: string): LabelledNode;
|
||||||
private _script;
|
|
||||||
private _changed;
|
|
||||||
constructor(root: Node, options: AssemblerOptions);
|
|
||||||
readonly changed: boolean;
|
|
||||||
getTarget(name: string): LabelledNode;
|
|
||||||
reset(): void;
|
|
||||||
evaluate(script: string, source: Node): Promise<any>;
|
evaluate(script: string, source: Node): Promise<any>;
|
||||||
start(node: Node): void;
|
|
||||||
end(node: Node): void;
|
|
||||||
getPendingBytecode(node: Node): string;
|
|
||||||
_appendBytecode(bytecode: string): void;
|
|
||||||
getAncestor<T = Node>(node: Node, cls: {
|
getAncestor<T = Node>(node: Node, cls: {
|
||||||
new (...args: any[]): T;
|
new (...args: any[]): T;
|
||||||
}): T;
|
}): T;
|
||||||
|
getOffset(node: Node, source?: Node): number;
|
||||||
|
setOffset(node: Node, offset: number): void;
|
||||||
|
getBytecode(node: Node): string;
|
||||||
|
setBytecode(node: Node, bytecode: string): void;
|
||||||
getLinkValue(target: LabelledNode, source: Node): number | DataSource;
|
getLinkValue(target: LabelledNode, source: Node): number | DataSource;
|
||||||
get(name: string, source: Node): any;
|
start(node: Node): void;
|
||||||
_didChange(): void;
|
end(node: Node): void;
|
||||||
_assemble(): Promise<string>;
|
|
||||||
assemble(): Promise<string>;
|
|
||||||
}
|
}
|
||||||
|
export declare enum SemanticErrorSeverity {
|
||||||
|
error = "error",
|
||||||
|
warning = "warning"
|
||||||
|
}
|
||||||
|
export declare type SemanticError = {
|
||||||
|
readonly message: string;
|
||||||
|
readonly severity: SemanticErrorSeverity;
|
||||||
|
readonly node: Node;
|
||||||
|
};
|
||||||
|
export declare function parse(code: string, options?: ParserOptions): Node;
|
||||||
export declare function assemble(ast: Node, options?: AssemblerOptions): Promise<string>;
|
export declare function assemble(ast: Node, options?: AssemblerOptions): Promise<string>;
|
||||||
export {};
|
export {};
|
||||||
|
@ -9,10 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
// @TODO:
|
// @TODO:
|
||||||
// - PIC
|
|
||||||
// - warn on opcode non-function iff parameters
|
|
||||||
// - warn return/revert non-empty, comment ; !assert(+1 @extra)
|
// - warn return/revert non-empty, comment ; !assert(+1 @extra)
|
||||||
// - $$
|
|
||||||
// - In JS add config (positionIndependent)
|
// - In JS add config (positionIndependent)
|
||||||
// - When checking name collisions, verify no collision in javascript
|
// - When checking name collisions, verify no collision in javascript
|
||||||
import { dirname, resolve } from "path";
|
import { dirname, resolve } from "path";
|
||||||
@ -118,9 +115,8 @@ export class Node {
|
|||||||
throw new Error("cannot instantiate class");
|
throw new Error("cannot instantiate class");
|
||||||
}
|
}
|
||||||
logger.checkAbstract(new.target, Node);
|
logger.checkAbstract(new.target, Node);
|
||||||
ethers.utils.defineReadOnly(this, "location", location);
|
ethers.utils.defineReadOnly(this, "location", Object.freeze(location));
|
||||||
ethers.utils.defineReadOnly(this, "tag", `node-${nextTag++}-${this.constructor.name}`);
|
ethers.utils.defineReadOnly(this, "tag", `node-${nextTag++}-${this.constructor.name}`);
|
||||||
ethers.utils.defineReadOnly(this, "warnings", []);
|
|
||||||
for (const key in options) {
|
for (const key in options) {
|
||||||
ethers.utils.defineReadOnly(this, key, options[key]);
|
ethers.utils.defineReadOnly(this, key, options[key]);
|
||||||
}
|
}
|
||||||
@ -139,6 +135,9 @@ export class Node {
|
|||||||
}
|
}
|
||||||
visit(visit) {
|
visit(visit) {
|
||||||
visit(this);
|
visit(this);
|
||||||
|
this.children().forEach((child) => {
|
||||||
|
child.visit(visit);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
static from(options) {
|
static from(options) {
|
||||||
const Factories = {
|
const Factories = {
|
||||||
@ -151,6 +150,7 @@ export class Node {
|
|||||||
length: LinkNode,
|
length: LinkNode,
|
||||||
offset: LinkNode,
|
offset: LinkNode,
|
||||||
opcode: OpcodeNode,
|
opcode: OpcodeNode,
|
||||||
|
pop: PopNode,
|
||||||
scope: ScopeNode,
|
scope: ScopeNode,
|
||||||
};
|
};
|
||||||
const factory = Factories[options.type];
|
const factory = Factories[options.type];
|
||||||
@ -160,14 +160,6 @@ export class Node {
|
|||||||
return factory.from(options);
|
return factory.from(options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
export abstract class CodeNode extends Node {
|
|
||||||
constructor(guard: any, location: Location, options: { [ key: string ]: any }) {
|
|
||||||
logger.checkAbstract(new.target, CodeNode);
|
|
||||||
super(guard, location, options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
export class ValueNode extends Node {
|
export class ValueNode extends Node {
|
||||||
constructor(guard, location, options) {
|
constructor(guard, location, options) {
|
||||||
logger.checkAbstract(new.target, ValueNode);
|
logger.checkAbstract(new.target, ValueNode);
|
||||||
@ -215,6 +207,20 @@ export class LiteralNode extends ValueNode {
|
|||||||
return new LiteralNode(Guard, options.loc, options.value, !!options.verbatim);
|
return new LiteralNode(Guard, options.loc, options.value, !!options.verbatim);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
export class PopNode extends ValueNode {
|
||||||
|
constructor(guard, location, index) {
|
||||||
|
super(guard, location, { index });
|
||||||
|
}
|
||||||
|
get placeholder() {
|
||||||
|
if (this.index === 0) {
|
||||||
|
return "$$";
|
||||||
|
}
|
||||||
|
return "$" + String(this.index);
|
||||||
|
}
|
||||||
|
static from(options) {
|
||||||
|
return new PopNode(Guard, options.loc, options.index);
|
||||||
|
}
|
||||||
|
}
|
||||||
export class LinkNode extends ValueNode {
|
export class LinkNode extends ValueNode {
|
||||||
constructor(guard, location, type, label) {
|
constructor(guard, location, type, label) {
|
||||||
super(guard, location, { type, label });
|
super(guard, location, { type, label });
|
||||||
@ -223,28 +229,65 @@ export class LinkNode extends ValueNode {
|
|||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
assembler.start(this);
|
assembler.start(this);
|
||||||
let value = null;
|
let value = null;
|
||||||
|
let isOffset = false;
|
||||||
const target = assembler.getTarget(this.label);
|
const target = assembler.getTarget(this.label);
|
||||||
if (target instanceof LabelNode) {
|
if (target instanceof LabelNode) {
|
||||||
if (this.type === "offset") {
|
if (this.type === "offset") {
|
||||||
//value = assembler.getOffset(this.label);
|
|
||||||
value = (assembler.getLinkValue(target, this));
|
value = (assembler.getLinkValue(target, this));
|
||||||
|
isOffset = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const result = (assembler.getLinkValue(target, this));
|
const result = (assembler.getLinkValue(target, this));
|
||||||
if (this.type === "offset") {
|
if (this.type === "offset") {
|
||||||
//value = assembler.getOffset(this.label);
|
|
||||||
value = result.offset;
|
value = result.offset;
|
||||||
|
isOffset = true;
|
||||||
}
|
}
|
||||||
else if (this.type === "length") {
|
else if (this.type === "length") {
|
||||||
//value = assembler.getLength(this.label);
|
|
||||||
value = result.length;
|
value = result.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
throw new Error("labels can only be targetted as offsets");
|
throw new Error("labels can only be targetted as offsets");
|
||||||
}
|
}
|
||||||
|
if (isOffset && assembler.positionIndependentCode) {
|
||||||
|
const here = assembler.getOffset(this, this);
|
||||||
|
const opcodes = [];
|
||||||
|
if (here > value) {
|
||||||
|
// Jump backwards
|
||||||
|
// Find a literal with length the encodes its own length in the delta
|
||||||
|
let literal = "0x";
|
||||||
|
for (let w = 1; w <= 5; w++) {
|
||||||
|
if (w > 4) {
|
||||||
|
throw new Error("jump too large!");
|
||||||
|
}
|
||||||
|
literal = pushLiteral(here - value + w);
|
||||||
|
if (ethers.utils.hexDataLength(literal) <= w) {
|
||||||
|
literal = ethers.utils.hexZeroPad(literal, w);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
opcodes.push(literal);
|
||||||
|
opcodes.push(Opcode.from("PC"));
|
||||||
|
opcodes.push(Opcode.from("SUB"));
|
||||||
|
// This also works, in case the above literal thing doesn't work out...
|
||||||
|
//opcodes.push(Opcode.from("PC"));
|
||||||
|
//opcodes.push(pushLiteral(-delta));
|
||||||
|
//opcodes.push(Opcode.from("SWAP1"));
|
||||||
|
//opcodes.push(Opcode.from("SUB"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Jump forwards; this is easy to calculate since we can
|
||||||
|
// do PC firat.
|
||||||
|
opcodes.push(Opcode.from("PC"));
|
||||||
|
opcodes.push(pushLiteral(value - here));
|
||||||
|
opcodes.push(Opcode.from("ADD"));
|
||||||
|
}
|
||||||
|
visit(this, hexConcat(opcodes));
|
||||||
|
}
|
||||||
|
else {
|
||||||
visit(this, pushLiteral(value));
|
visit(this, pushLiteral(value));
|
||||||
|
}
|
||||||
assembler.end(this);
|
assembler.end(this);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -254,11 +297,8 @@ export class LinkNode extends ValueNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
export class OpcodeNode extends ValueNode {
|
export class OpcodeNode extends ValueNode {
|
||||||
constructor(guard, location, opcode, operands) {
|
constructor(guard, location, opcode, operands, instructional) {
|
||||||
super(guard, location, { opcode, operands });
|
super(guard, location, { instructional, opcode, operands });
|
||||||
if (opcode.isPush()) {
|
|
||||||
this.warnings.push("the PUSH opcode modifies program flow - use literals instead");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
assemble(assembler, visit) {
|
assemble(assembler, visit) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
@ -289,23 +329,14 @@ export class OpcodeNode extends ValueNode {
|
|||||||
if (!opcode) {
|
if (!opcode) {
|
||||||
throw new Error("unknown opcode: " + options.mnemonic);
|
throw new Error("unknown opcode: " + options.mnemonic);
|
||||||
}
|
}
|
||||||
// Using the function syntax will check the operand count
|
|
||||||
if (!options.bare) {
|
|
||||||
if (opcode.mnemonic === "POP" && options.operands.length === 0) {
|
|
||||||
// This is ok... Pop has a delta of 0, but without operands
|
|
||||||
}
|
|
||||||
else if (options.operands.length !== opcode.delta) {
|
|
||||||
throw new Error(`opcode ${opcode.mnemonic} expects ${opcode.delta} operands`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const operands = Object.freeze(options.operands.map((o) => {
|
const operands = Object.freeze(options.operands.map((o) => {
|
||||||
const operand = Node.from(o);
|
const operand = Node.from(o);
|
||||||
if (!(operand instanceof ValueNode)) {
|
if (!(operand instanceof ValueNode)) {
|
||||||
throw new Error("invalid operand");
|
throw new Error("bad grammar?!");
|
||||||
}
|
}
|
||||||
return operand;
|
return operand;
|
||||||
}));
|
}));
|
||||||
return new OpcodeNode(Guard, options.loc, opcode, operands);
|
return new OpcodeNode(Guard, options.loc, opcode, operands, !!options.bare);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export class LabelledNode extends Node {
|
export class LabelledNode extends Node {
|
||||||
@ -344,7 +375,7 @@ export class DataNode extends LabelledNode {
|
|||||||
// We pad data if is contains PUSH opcodes that would overrun
|
// We pad data if is contains PUSH opcodes that would overrun
|
||||||
// the data, which could eclipse valid operations (since the
|
// the data, which could eclipse valid operations (since the
|
||||||
// VM won't execute or jump within PUSH operations)
|
// VM won't execute or jump within PUSH operations)
|
||||||
const bytecode = ethers.utils.arrayify(assembler.getPendingBytecode(this));
|
const bytecode = ethers.utils.arrayify(assembler.getBytecode(this));
|
||||||
// Replay the data as bytecode, skipping PUSH data
|
// Replay the data as bytecode, skipping PUSH data
|
||||||
let i = 0;
|
let i = 0;
|
||||||
while (i < bytecode.length) {
|
while (i < bytecode.length) {
|
||||||
@ -365,12 +396,6 @@ export class DataNode extends LabelledNode {
|
|||||||
children() {
|
children() {
|
||||||
return this.data;
|
return this.data;
|
||||||
}
|
}
|
||||||
visit(visit) {
|
|
||||||
visit(this);
|
|
||||||
for (let i = 0; i < this.data.length; i++) {
|
|
||||||
this.data[i].visit(visit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static from(options) {
|
static from(options) {
|
||||||
if (options.type !== "data") {
|
if (options.type !== "data") {
|
||||||
throw new Error("expected data type");
|
throw new Error("expected data type");
|
||||||
@ -442,12 +467,6 @@ export class ScopeNode extends LabelledNode {
|
|||||||
children() {
|
children() {
|
||||||
return this.statements;
|
return this.statements;
|
||||||
}
|
}
|
||||||
visit(visit) {
|
|
||||||
visit(this);
|
|
||||||
for (let i = 0; i < this.statements.length; i++) {
|
|
||||||
this.statements[i].visit(visit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static from(options) {
|
static from(options) {
|
||||||
if (options.type !== "scope") {
|
if (options.type !== "scope") {
|
||||||
throw new Error("expected scope type");
|
throw new Error("expected scope type");
|
||||||
@ -455,56 +474,6 @@ export class ScopeNode extends LabelledNode {
|
|||||||
return new ScopeNode(Guard, options.loc, options.name, Object.freeze(options.statements.map((s) => Node.from(s))));
|
return new ScopeNode(Guard, options.loc, options.name, Object.freeze(options.statements.map((s) => Node.from(s))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export function parse(code) {
|
|
||||||
// Since jison allows \n, \r or \r\n line endings, we need some
|
|
||||||
// twekaing to get the correct position
|
|
||||||
const lines = [];
|
|
||||||
let offset = 0;
|
|
||||||
code.split(/(\r\n?|\n)/g).forEach((clump, index) => {
|
|
||||||
if (index % 2) {
|
|
||||||
lines[lines.length - 1].line += clump;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
lines.push({ line: clump, offset: offset });
|
|
||||||
}
|
|
||||||
offset += clump.length;
|
|
||||||
});
|
|
||||||
// Add a mock-EOF to the end of the file so we don't out-of-bounds
|
|
||||||
// on the last character
|
|
||||||
if (lines.length) {
|
|
||||||
lines[lines.length - 1].line += "\n";
|
|
||||||
}
|
|
||||||
// Givens a line (1 offset) and column (0 offset) return the byte offset
|
|
||||||
const getOffset = function (line, column) {
|
|
||||||
const info = lines[line - 1];
|
|
||||||
if (!info || column >= info.line.length) {
|
|
||||||
throw new Error("out of range");
|
|
||||||
}
|
|
||||||
return info.offset + column;
|
|
||||||
};
|
|
||||||
// We use this in the _parser to convert locations to source
|
|
||||||
_parser.yy._ethersLocation = function (loc) {
|
|
||||||
// The _ scope should call with null to get the full source
|
|
||||||
if (loc == null) {
|
|
||||||
return Object.freeze({
|
|
||||||
offset: 0,
|
|
||||||
length: code.length,
|
|
||||||
source: code
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const offset = getOffset(loc.first_line, loc.first_column);
|
|
||||||
const end = getOffset(loc.last_line, loc.last_column);
|
|
||||||
return Object.freeze({
|
|
||||||
offset: offset,
|
|
||||||
length: (end - offset),
|
|
||||||
source: code.substring(offset, end)
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const result = Node.from(_parse(code));
|
|
||||||
// Nuke the source code lookup callback
|
|
||||||
_parser.yy._ethersLocation = null;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
export function disassemble(bytecode) {
|
export function disassemble(bytecode) {
|
||||||
const ops = [];
|
const ops = [];
|
||||||
const offsets = {};
|
const offsets = {};
|
||||||
@ -568,14 +537,10 @@ export function formatBytecode(bytecode) {
|
|||||||
});
|
});
|
||||||
return lines.join("\n");
|
return lines.join("\n");
|
||||||
}
|
}
|
||||||
// @TODO: Rename to Assembler?
|
|
||||||
class Assembler {
|
class Assembler {
|
||||||
constructor(root, options) {
|
constructor(root, positionIndependentCode) {
|
||||||
ethers.utils.defineReadOnly(this, "positionIndependentCode", !!options.positionIndependentCode);
|
|
||||||
ethers.utils.defineReadOnly(this, "retry", ((options.retry != null) ? options.retry : 512));
|
|
||||||
ethers.utils.defineReadOnly(this, "filename", resolve(options.filename || "./contract.asm"));
|
|
||||||
ethers.utils.defineReadOnly(this, "defines", Object.freeze(options.defines || {}));
|
|
||||||
ethers.utils.defineReadOnly(this, "root", root);
|
ethers.utils.defineReadOnly(this, "root", root);
|
||||||
|
ethers.utils.defineReadOnly(this, "positionIndependentCode", !!positionIndependentCode);
|
||||||
const nodes = {};
|
const nodes = {};
|
||||||
const labels = {};
|
const labels = {};
|
||||||
const parents = {};
|
const parents = {};
|
||||||
@ -584,8 +549,7 @@ class Assembler {
|
|||||||
nodes[node.tag] = {
|
nodes[node.tag] = {
|
||||||
node: node,
|
node: node,
|
||||||
offset: 0x0,
|
offset: 0x0,
|
||||||
bytecode: "0x",
|
bytecode: "0x"
|
||||||
pending: "0x"
|
|
||||||
};
|
};
|
||||||
if (node instanceof LabelledNode) {
|
if (node instanceof LabelledNode) {
|
||||||
// Check for duplicate labels
|
// Check for duplicate labels
|
||||||
@ -611,52 +575,14 @@ class Assembler {
|
|||||||
ethers.utils.defineReadOnly(this, "labels", Object.freeze(labels));
|
ethers.utils.defineReadOnly(this, "labels", Object.freeze(labels));
|
||||||
ethers.utils.defineReadOnly(this, "nodes", Object.freeze(nodes));
|
ethers.utils.defineReadOnly(this, "nodes", Object.freeze(nodes));
|
||||||
ethers.utils.defineReadOnly(this, "_parents", Object.freeze(parents));
|
ethers.utils.defineReadOnly(this, "_parents", Object.freeze(parents));
|
||||||
ethers.utils.defineReadOnly(this, "_stack", []);
|
|
||||||
this.reset();
|
|
||||||
}
|
|
||||||
get changed() {
|
|
||||||
return this._changed;
|
|
||||||
}
|
}
|
||||||
// Link operations
|
// Link operations
|
||||||
getTarget(name) {
|
getTarget(label) {
|
||||||
return this.labels[name];
|
return this.labels[label];
|
||||||
}
|
|
||||||
// Reset the assmebler for another run with updated values
|
|
||||||
reset() {
|
|
||||||
this._changed = false;
|
|
||||||
for (const tag in this.nodes) {
|
|
||||||
delete this.nodes[tag].object;
|
|
||||||
}
|
|
||||||
this._script = new Script(this.filename, (name, context) => {
|
|
||||||
return this.get(name, context);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
// Evaluate script in the context of a {{! }} or {{= }}
|
||||||
evaluate(script, source) {
|
evaluate(script, source) {
|
||||||
return this._script.evaluate(script, source);
|
return Promise.resolve(new Uint8Array(0));
|
||||||
}
|
|
||||||
start(node) {
|
|
||||||
this._stack.push(node);
|
|
||||||
const info = this.nodes[node.tag];
|
|
||||||
info.pending = "0x";
|
|
||||||
}
|
|
||||||
end(node) {
|
|
||||||
if (this._stack.pop() !== node) {
|
|
||||||
throw new Error("missing push/pop pair");
|
|
||||||
}
|
|
||||||
const info = this.nodes[node.tag];
|
|
||||||
if (info.pending !== info.bytecode) {
|
|
||||||
this._didChange();
|
|
||||||
}
|
|
||||||
info.bytecode = info.pending;
|
|
||||||
}
|
|
||||||
getPendingBytecode(node) {
|
|
||||||
return this.nodes[node.tag].pending;
|
|
||||||
}
|
|
||||||
_appendBytecode(bytecode) {
|
|
||||||
this._stack.forEach((node) => {
|
|
||||||
const info = this.nodes[node.tag];
|
|
||||||
info.pending = hexConcat([info.pending, bytecode]);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
getAncestor(node, cls) {
|
getAncestor(node, cls) {
|
||||||
node = this._parents[node.tag];
|
node = this._parents[node.tag];
|
||||||
@ -668,6 +594,23 @@ class Assembler {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
getOffset(node, source) {
|
||||||
|
const offset = this.nodes[node.tag].offset;
|
||||||
|
if (source == null) {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
const sourceScope = ((source instanceof ScopeNode) ? source : this.getAncestor(source, ScopeNode));
|
||||||
|
return offset - this.nodes[sourceScope.tag].offset;
|
||||||
|
}
|
||||||
|
setOffset(node, offset) {
|
||||||
|
this.nodes[node.tag].offset = offset;
|
||||||
|
}
|
||||||
|
getBytecode(node) {
|
||||||
|
return this.nodes[node.tag].bytecode;
|
||||||
|
}
|
||||||
|
setBytecode(node, bytecode) {
|
||||||
|
this.nodes[node.tag].bytecode = bytecode;
|
||||||
|
}
|
||||||
getLinkValue(target, source) {
|
getLinkValue(target, source) {
|
||||||
const sourceScope = ((source instanceof ScopeNode) ? source : this.getAncestor(source, ScopeNode));
|
const sourceScope = ((source instanceof ScopeNode) ? source : this.getAncestor(source, ScopeNode));
|
||||||
const targetScope = ((target instanceof ScopeNode) ? target : this.getAncestor(target, ScopeNode));
|
const targetScope = ((target instanceof ScopeNode) ? target : this.getAncestor(target, ScopeNode));
|
||||||
@ -678,13 +621,7 @@ class Assembler {
|
|||||||
throw new Error(`cannot access ${target.name} from ${source.tag}`);
|
throw new Error(`cannot access ${target.name} from ${source.tag}`);
|
||||||
}
|
}
|
||||||
// Return the offset relative to its scope
|
// Return the offset relative to its scope
|
||||||
let offset = this.nodes[target.tag].offset - this.nodes[targetScope.tag].offset;
|
return this.nodes[target.tag].offset - this.nodes[targetScope.tag].offset;
|
||||||
// Offsets are wrong; but we should finish this run and then try again
|
|
||||||
if (offset < 0) {
|
|
||||||
offset = 0;
|
|
||||||
this._didChange();
|
|
||||||
}
|
|
||||||
return offset;
|
|
||||||
}
|
}
|
||||||
const info = this.nodes[target.tag];
|
const info = this.nodes[target.tag];
|
||||||
// Return the offset is relative to its scope
|
// Return the offset is relative to its scope
|
||||||
@ -713,14 +650,209 @@ class Assembler {
|
|||||||
// been marked as invalid, in which case accessing it will fail
|
// been marked as invalid, in which case accessing it will fail
|
||||||
if (safeOffset) {
|
if (safeOffset) {
|
||||||
bytes.offset = info.offset - this.nodes[sourceScope.tag].offset;
|
bytes.offset = info.offset - this.nodes[sourceScope.tag].offset;
|
||||||
// Offsets are wqrong; but we should finish this run and then try again
|
}
|
||||||
if (bytes.offset < 0) {
|
return bytes;
|
||||||
bytes.offset = 0;
|
}
|
||||||
|
start(node) { }
|
||||||
|
end(node) { }
|
||||||
|
}
|
||||||
|
export var SemanticErrorSeverity;
|
||||||
|
(function (SemanticErrorSeverity) {
|
||||||
|
SemanticErrorSeverity["error"] = "error";
|
||||||
|
SemanticErrorSeverity["warning"] = "warning";
|
||||||
|
})(SemanticErrorSeverity || (SemanticErrorSeverity = {}));
|
||||||
|
;
|
||||||
|
// This Assembler is designed to only check for errors and warnings
|
||||||
|
// Warnings
|
||||||
|
// - Bare PUSH opcodes
|
||||||
|
// - Instructional opcode that has parameters
|
||||||
|
// Errors
|
||||||
|
// - Using a $$ outside of RPN
|
||||||
|
// - Using a $$ when it is not adjacent to the stack
|
||||||
|
// - The operand count does not match the opcode
|
||||||
|
// - An opcode is used as an operand but does not return a value
|
||||||
|
class SemanticChecker extends Assembler {
|
||||||
|
check() {
|
||||||
|
const errors = [];
|
||||||
|
this.root.visit((node) => {
|
||||||
|
if (node instanceof OpcodeNode) {
|
||||||
|
const opcode = node.opcode;
|
||||||
|
if (node.instructional) {
|
||||||
|
if (opcode.delta) {
|
||||||
|
errors.push({
|
||||||
|
message: `${opcode.mnemonic} used as instructional`,
|
||||||
|
severity: SemanticErrorSeverity.warning,
|
||||||
|
node: node
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (opcode.mnemonic === "POP") {
|
||||||
|
if (node.operands.length !== 0) {
|
||||||
|
errors.push({
|
||||||
|
message: "POP expects 0 operands",
|
||||||
|
severity: SemanticErrorSeverity.error,
|
||||||
|
node: node
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (node.operands.length !== opcode.delta) {
|
||||||
|
errors.push({
|
||||||
|
message: `${opcode.mnemonic} expects ${opcode.delta} operands`,
|
||||||
|
severity: SemanticErrorSeverity.error,
|
||||||
|
node: node
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (opcode.isPush()) {
|
||||||
|
// A stray PUSH operation will gobble up the following code
|
||||||
|
// bytes which is bad. But this may be a disassembled program
|
||||||
|
// and that PUSH may actually be just some data (which is safe)
|
||||||
|
errors.push({
|
||||||
|
message: "PUSH opcode modifies program flow - use literals instead",
|
||||||
|
severity: SemanticErrorSeverity.warning,
|
||||||
|
node: node
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (!node.location.statement && opcode.alpha !== 1) {
|
||||||
|
// If an opcode does not push anything on the stack, it
|
||||||
|
// cannot be used as an operand
|
||||||
|
errors.push({
|
||||||
|
message: `${node.opcode.mnemonic} cannot be an operand`,
|
||||||
|
severity: SemanticErrorSeverity.error,
|
||||||
|
node: node
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node.location.statement) {
|
||||||
|
if (node instanceof PopNode) {
|
||||||
|
// $$ by istelf is useless and is intended to be an operand
|
||||||
|
errors.push({
|
||||||
|
message: `$$ must be an operand`,
|
||||||
|
severity: SemanticErrorSeverity.error,
|
||||||
|
node: node
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const scope = this.getAncestor(node, ScopeNode);
|
||||||
|
// Make sure any $$ is stack adjacent (within this scope)
|
||||||
|
const ordered = [];
|
||||||
|
node.visit((node) => {
|
||||||
|
if (scope !== this.getAncestor(node, ScopeNode)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ordered.push(node);
|
||||||
|
});
|
||||||
|
// Allow any number of stack adjacent $$
|
||||||
|
let foundZero = null;
|
||||||
|
let lastIndex = 0;
|
||||||
|
while (ordered.length && ordered[0] instanceof PopNode) {
|
||||||
|
const popNode = (ordered.shift());
|
||||||
|
const index = popNode.index;
|
||||||
|
if (index === 0) {
|
||||||
|
foundZero = popNode;
|
||||||
|
}
|
||||||
|
else if (index !== lastIndex + 1) {
|
||||||
|
errors.push({
|
||||||
|
message: `out-of-order stack placeholder ${popNode.placeholder}; expected $$${lastIndex + 1}`,
|
||||||
|
severity: SemanticErrorSeverity.error,
|
||||||
|
node: popNode
|
||||||
|
});
|
||||||
|
while (ordered.length && ordered[0] instanceof PopNode) {
|
||||||
|
ordered.shift();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lastIndex = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (foundZero && lastIndex > 0) {
|
||||||
|
errors.push({
|
||||||
|
message: "cannot mix $$ and $1 stack placeholder",
|
||||||
|
severity: SemanticErrorSeverity.error,
|
||||||
|
node: foundZero
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// If there are still any buried, we have a problem
|
||||||
|
const pops = ordered.filter((n) => (n instanceof PopNode));
|
||||||
|
if (pops.length) {
|
||||||
|
errors.push({
|
||||||
|
message: `stack placeholder ${(pops[0]).placeholder} must be stack adjacent`,
|
||||||
|
severity: SemanticErrorSeverity.error,
|
||||||
|
node: pops[0]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class CodeGenerationAssembler extends Assembler {
|
||||||
|
constructor(root, options) {
|
||||||
|
super(root, !!options.positionIndependentCode);
|
||||||
|
ethers.utils.defineReadOnly(this, "retry", ((options.retry != null) ? options.retry : 512));
|
||||||
|
ethers.utils.defineReadOnly(this, "filename", resolve(options.filename || "./contract.asm"));
|
||||||
|
ethers.utils.defineReadOnly(this, "defines", Object.freeze(options.defines || {}));
|
||||||
|
ethers.utils.defineReadOnly(this, "_stack", []);
|
||||||
|
this.reset();
|
||||||
|
}
|
||||||
|
_didChange() {
|
||||||
|
this._changed = true;
|
||||||
|
}
|
||||||
|
get changed() {
|
||||||
|
return this._changed;
|
||||||
|
}
|
||||||
|
// Reset the assmebler for another run with updated values
|
||||||
|
reset() {
|
||||||
|
this._changed = false;
|
||||||
|
this._oldBytecode = {};
|
||||||
|
this._objectCache = {};
|
||||||
|
this._script = new Script(this.filename, (name, context) => {
|
||||||
|
return this.get(name, context);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
evaluate(script, source) {
|
||||||
|
return this._script.evaluate(script, source);
|
||||||
|
}
|
||||||
|
getLinkValue(target, source) {
|
||||||
|
// Since we are iteratively generating code, offsets and lengths
|
||||||
|
// may not be stable at any given point in time, so if an offset
|
||||||
|
// is negative the code is obviously wrong, however we set it to
|
||||||
|
// 0 so we can proceed with generation to fill in as many blanks
|
||||||
|
// as possible; then we will try assembling again
|
||||||
|
const result = super.getLinkValue(target, source);
|
||||||
|
if (typeof (result) === "number") {
|
||||||
|
if (result < 0) {
|
||||||
|
this._didChange();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (result.offset < 0) {
|
||||||
|
result.offset = 0;
|
||||||
|
this._didChange();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
start(node) {
|
||||||
|
this._stack.push(node);
|
||||||
|
this._oldBytecode[node.tag] = this.getBytecode(node);
|
||||||
|
this.setBytecode(node, "0x");
|
||||||
|
}
|
||||||
|
end(node) {
|
||||||
|
if (this._stack.pop() !== node) {
|
||||||
|
throw new Error("missing push/pop pair");
|
||||||
|
}
|
||||||
|
if (this._oldBytecode[node.tag] !== this.getBytecode(node)) {
|
||||||
this._didChange();
|
this._didChange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Object.freeze(bytes);
|
// This is used by evaluate to access properties in JavaScript
|
||||||
}
|
// - "defines" allow meta-programming values to be used
|
||||||
|
// - jump destinations are available as numbers
|
||||||
|
// - bytecode and data are available as an immuatble DataSource
|
||||||
get(name, source) {
|
get(name, source) {
|
||||||
if (name === "defines") {
|
if (name === "defines") {
|
||||||
return this.defines;
|
return this.defines;
|
||||||
@ -729,67 +861,137 @@ class Assembler {
|
|||||||
if (!node) {
|
if (!node) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
const info = this.nodes[node.tag];
|
// We cache objects when they are generated so all nodes
|
||||||
if (info.object == null) {
|
// receive consistent data; if there is a change we will
|
||||||
info.object = this.getLinkValue(node, source);
|
// run the entire assembly process again with the updated
|
||||||
|
// values
|
||||||
|
if (this._objectCache[node.tag] == null) {
|
||||||
|
this._objectCache[node.tag] = Object.freeze(this.getLinkValue(node, source));
|
||||||
}
|
}
|
||||||
return info.object;
|
return this._objectCache[node.tag];
|
||||||
}
|
|
||||||
_didChange() {
|
|
||||||
this._changed = true;
|
|
||||||
}
|
}
|
||||||
_assemble() {
|
_assemble() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
const bytecodes = [];
|
|
||||||
yield this.root.assemble(this, (node, bytecode) => {
|
yield this.root.assemble(this, (node, bytecode) => {
|
||||||
const state = this.nodes[node.tag];
|
|
||||||
// Things have moved; we will need to try again
|
// Things have moved; we will need to try again
|
||||||
if (state.offset !== offset) {
|
if (this.getOffset(node) !== offset) {
|
||||||
state.offset = offset;
|
this.setOffset(node, offset);
|
||||||
this._didChange();
|
this._didChange();
|
||||||
}
|
}
|
||||||
this._appendBytecode(bytecode);
|
this._stack.forEach((node) => {
|
||||||
bytecodes.push(bytecode);
|
this.setBytecode(node, hexConcat([
|
||||||
// The bytecode has changed; we will need to try again
|
this.getBytecode(node),
|
||||||
//if (state.bytecode !== bytecode) {
|
bytecode
|
||||||
// state.bytecode = bytecode;
|
]));
|
||||||
// this._didChange();
|
});
|
||||||
//}
|
|
||||||
offset += ethers.utils.hexDataLength(bytecode);
|
offset += ethers.utils.hexDataLength(bytecode);
|
||||||
});
|
});
|
||||||
return hexConcat(bytecodes);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
assemble() {
|
assemble(label) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
if (label == null) {
|
||||||
|
label = "_";
|
||||||
|
}
|
||||||
|
const target = this.getTarget(label);
|
||||||
|
if (!target) {
|
||||||
|
logger.throwArgumentError(`unknown labelled target: ${label}`, "label", label);
|
||||||
|
}
|
||||||
|
else if (!(target instanceof ScopeNode || target instanceof DataNode)) {
|
||||||
|
logger.throwArgumentError(`cannot assemble a bodyless label: ${label}`, "label", label);
|
||||||
|
}
|
||||||
// Continue re-evaluating the bytecode until a stable set of
|
// Continue re-evaluating the bytecode until a stable set of
|
||||||
// offsets, length and values are reached.
|
// offsets, length and values are reached.
|
||||||
let bytecode = yield this._assemble();
|
yield this._assemble();
|
||||||
for (let i = 0; i < this.retry; i++) {
|
for (let i = 0; i < this.retry; i++) {
|
||||||
// Regenerate the code with the updated assembler values
|
// Regenerate the code with the updated assembler values
|
||||||
this.reset();
|
this.reset();
|
||||||
const adjusted = yield this._assemble();
|
yield this._assemble();
|
||||||
// Generated bytecode is stable!! :)
|
// Generated bytecode is stable!! :)
|
||||||
if (!this.changed) {
|
if (!this.changed) {
|
||||||
console.log(`Assembled in ${i} attempts`);
|
|
||||||
return bytecode;
|
|
||||||
}
|
|
||||||
// Try again...
|
|
||||||
bytecode = adjusted;
|
|
||||||
}
|
|
||||||
// This should not happen; something is wrong with the grammar
|
// This should not happen; something is wrong with the grammar
|
||||||
// or missing enter/exit call in assemble
|
// or missing enter/exit call in assemble
|
||||||
if (this._stack.length !== 0) {
|
if (this._stack.length !== 0) {
|
||||||
throw new Error("bad AST");
|
throw new Error("Bad AST! Bad grammar?!");
|
||||||
|
}
|
||||||
|
//console.log(`Assembled in ${ i } attempts`);
|
||||||
|
return this.getBytecode(target);
|
||||||
|
;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return logger.throwError(`unable to assemble; ${this.retry} attempts failed to generate stable bytecode`, ethers.utils.Logger.errors.UNKNOWN_ERROR, {});
|
return logger.throwError(`unable to assemble; ${this.retry} attempts failed to generate stable bytecode`, ethers.utils.Logger.errors.UNKNOWN_ERROR, {});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
export function parse(code, options) {
|
||||||
|
if (options == null) {
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
// Since jison allows \n, \r or \r\n line endings, we need some
|
||||||
|
// twekaing to get the correct position
|
||||||
|
const lines = [];
|
||||||
|
let offset = 0;
|
||||||
|
code.split(/(\r\n?|\n)/g).forEach((clump, index) => {
|
||||||
|
if (index % 2) {
|
||||||
|
lines[lines.length - 1].line += clump;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lines.push({ line: clump, offset: offset });
|
||||||
|
}
|
||||||
|
offset += clump.length;
|
||||||
|
});
|
||||||
|
// Add a mock-EOF to the end of the file so we don't out-of-bounds
|
||||||
|
// on the last character
|
||||||
|
if (lines.length) {
|
||||||
|
lines[lines.length - 1].line += "\n";
|
||||||
|
}
|
||||||
|
// Givens a line (1 offset) and column (0 offset) return the byte offset
|
||||||
|
const getOffset = function (line, column) {
|
||||||
|
const info = lines[line - 1];
|
||||||
|
if (!info || column >= info.line.length) {
|
||||||
|
throw new Error("out of range");
|
||||||
|
}
|
||||||
|
return info.offset + column;
|
||||||
|
};
|
||||||
|
// We use this in the _parser to convert locations to source
|
||||||
|
_parser.yy._ethersLocation = function (loc) {
|
||||||
|
// The _ scope should call with null to get the full source
|
||||||
|
if (loc == null) {
|
||||||
|
return {
|
||||||
|
offset: 0,
|
||||||
|
line: 0,
|
||||||
|
length: code.length,
|
||||||
|
source: code,
|
||||||
|
statement: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const offset = getOffset(loc.first_line, loc.first_column);
|
||||||
|
const end = getOffset(loc.last_line, loc.last_column);
|
||||||
|
return {
|
||||||
|
offset: offset,
|
||||||
|
line: loc.first_line - 1,
|
||||||
|
length: (end - offset),
|
||||||
|
source: code.substring(offset, end),
|
||||||
|
statement: (!!loc.statement)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
const result = Node.from(_parse(code));
|
||||||
|
// Nuke the source code lookup callback
|
||||||
|
_parser.yy._ethersLocation = null;
|
||||||
|
// Semantic Checks
|
||||||
|
const checker = new SemanticChecker(result);
|
||||||
|
const errors = checker.check();
|
||||||
|
if (errors.filter((e) => (e.severity === SemanticErrorSeverity.error)).length || (errors.length && !options.ignoreWarnings)) {
|
||||||
|
const error = new Error("semantic errors during parsing");
|
||||||
|
error.errors = errors;
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
export function assemble(ast, options) {
|
export function assemble(ast, options) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const assembler = new Assembler(ast, options || {});
|
const assembler = new CodeGenerationAssembler(ast, options || {});
|
||||||
return assembler.assemble();
|
return assembler.assemble(options.target || "_");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
6
packages/asm/lib.esm/index.d.ts
vendored
6
packages/asm/lib.esm/index.d.ts
vendored
@ -1,4 +1,4 @@
|
|||||||
import { assemble, DataNode, disassemble, EvaluationNode, ExecutionNode, formatBytecode, LabelNode, LabelledNode, LinkNode, LiteralNode, Node, OpcodeNode, parse, ScopeNode, ValueNode } from "./assembler";
|
import { assemble, DataNode, disassemble, EvaluationNode, ExecutionNode, formatBytecode, LabelNode, LabelledNode, LinkNode, LiteralNode, Node, OpcodeNode, parse, PopNode, ScopeNode, ValueNode } from "./assembler";
|
||||||
import { Opcode } from "./opcodes";
|
import { Opcode } from "./opcodes";
|
||||||
import { AssemblerOptions, AssembleVisitFunc, Bytecode, Location, Operation, VisitFunc } from "./assembler";
|
import { AssemblerOptions, AssembleVisitFunc, Bytecode, Location, Operation, ParserOptions, SemanticError, SemanticErrorSeverity, VisitFunc } from "./assembler";
|
||||||
export { Opcode, assemble, disassemble, formatBytecode, parse, DataNode, EvaluationNode, ExecutionNode, LabelNode, LabelledNode, LinkNode, LiteralNode, Node, OpcodeNode, ScopeNode, ValueNode, AssemblerOptions, AssembleVisitFunc, Bytecode, Location, Operation, VisitFunc, };
|
export { Opcode, assemble, disassemble, formatBytecode, parse, DataNode, EvaluationNode, ExecutionNode, LabelNode, LabelledNode, LinkNode, LiteralNode, Node, OpcodeNode, PopNode, ScopeNode, ValueNode, AssemblerOptions, AssembleVisitFunc, Bytecode, Location, Operation, SemanticError, SemanticErrorSeverity, ParserOptions, VisitFunc, };
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
import { assemble, DataNode, disassemble, EvaluationNode, ExecutionNode, formatBytecode, LabelNode, LabelledNode, LinkNode, LiteralNode, Node, OpcodeNode, parse, ScopeNode, ValueNode } from "./assembler";
|
import { assemble, DataNode, disassemble, EvaluationNode, ExecutionNode, formatBytecode, LabelNode, LabelledNode, LinkNode, LiteralNode, Node, OpcodeNode, parse, PopNode, ScopeNode, ValueNode } from "./assembler";
|
||||||
import { Opcode } from "./opcodes";
|
import { Opcode } from "./opcodes";
|
||||||
|
import { SemanticErrorSeverity } from "./assembler";
|
||||||
export {
|
export {
|
||||||
// Opcodes
|
// Opcodes
|
||||||
Opcode,
|
Opcode,
|
||||||
// Assembler functions
|
// Assembler functions
|
||||||
assemble, disassemble, formatBytecode, parse,
|
assemble, disassemble, formatBytecode, parse,
|
||||||
// Assembly AST Nodes
|
// Assembly AST Nodes
|
||||||
DataNode, EvaluationNode, ExecutionNode, LabelNode, LabelledNode, LinkNode, LiteralNode, Node, OpcodeNode, ScopeNode, ValueNode, };
|
DataNode, EvaluationNode, ExecutionNode, LabelNode, LabelledNode, LinkNode, LiteralNode, Node, OpcodeNode, PopNode, ScopeNode, ValueNode, SemanticErrorSeverity, };
|
||||||
|
7
packages/asm/lib.esm/opcodes.d.ts
vendored
7
packages/asm/lib.esm/opcodes.d.ts
vendored
@ -1,3 +1,8 @@
|
|||||||
|
export declare enum OpcodeMemoryAccess {
|
||||||
|
write = "write",
|
||||||
|
read = "read",
|
||||||
|
full = "full"
|
||||||
|
}
|
||||||
export declare class Opcode {
|
export declare class Opcode {
|
||||||
readonly value: number;
|
readonly value: number;
|
||||||
readonly mnemonic: string;
|
readonly mnemonic: string;
|
||||||
@ -8,7 +13,7 @@ export declare class Opcode {
|
|||||||
isJump(): boolean;
|
isJump(): boolean;
|
||||||
isValidJumpDest(): boolean;
|
isValidJumpDest(): boolean;
|
||||||
isPush(): number;
|
isPush(): number;
|
||||||
isMemory(readOrWrite?: boolean): boolean;
|
isMemoryAccess(readOrWrite?: boolean): OpcodeMemoryAccess;
|
||||||
isStatic(): boolean;
|
isStatic(): boolean;
|
||||||
static from(valueOrMnemonic: number | string): Opcode;
|
static from(valueOrMnemonic: number | string): Opcode;
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,13 @@
|
|||||||
// EXTCODEHASH
|
// EXTCODEHASH
|
||||||
// See: https://eips.ethereum.org/EIPS/eip-1052
|
// See: https://eips.ethereum.org/EIPS/eip-1052
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
|
export var OpcodeMemoryAccess;
|
||||||
|
(function (OpcodeMemoryAccess) {
|
||||||
|
OpcodeMemoryAccess["write"] = "write";
|
||||||
|
OpcodeMemoryAccess["read"] = "read";
|
||||||
|
OpcodeMemoryAccess["full"] = "full";
|
||||||
|
})(OpcodeMemoryAccess || (OpcodeMemoryAccess = {}));
|
||||||
|
;
|
||||||
export class Opcode {
|
export class Opcode {
|
||||||
constructor(mnemonic, value, delta, alpha, doc) {
|
constructor(mnemonic, value, delta, alpha, doc) {
|
||||||
ethers.utils.defineReadOnly(this, "mnemonic", mnemonic);
|
ethers.utils.defineReadOnly(this, "mnemonic", mnemonic);
|
||||||
@ -31,12 +38,19 @@ export class Opcode {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// Returns true if this operation writes to memory contents (or if readOrWrite, reads memory)
|
// Returns true if this operation writes to memory contents (or if readOrWrite, reads memory)
|
||||||
isMemory(readOrWrite) {
|
// Unknown opcodes return null
|
||||||
throw new Error("@TODO: return true if modifies memory");
|
isMemoryAccess(readOrWrite) {
|
||||||
|
switch ((_Opcodes[this.mnemonic.toLowerCase()] || { memory: null }).memory) {
|
||||||
|
case "read": return OpcodeMemoryAccess.read;
|
||||||
|
case "write": return OpcodeMemoryAccess.write;
|
||||||
|
case "full": return OpcodeMemoryAccess.full;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
// Returns true if this opcode does not affect state
|
// Returns true if this opcode does not affect state
|
||||||
|
// Unknown opcodes return false
|
||||||
isStatic() {
|
isStatic() {
|
||||||
throw new Error("@TODO: return true if certain non-state-changing");
|
return !(_Opcodes[this.mnemonic.toLowerCase()] || { nonStatic: true }).nonStatic;
|
||||||
}
|
}
|
||||||
static from(valueOrMnemonic) {
|
static from(valueOrMnemonic) {
|
||||||
if (typeof (valueOrMnemonic) === "string") {
|
if (typeof (valueOrMnemonic) === "string") {
|
||||||
@ -75,7 +89,7 @@ const _Opcodes = {
|
|||||||
shr: { value: 0x1c, delta: 2, alpha: 1, doc: "v = shr(shiftBits, value)" },
|
shr: { value: 0x1c, delta: 2, alpha: 1, doc: "v = shr(shiftBits, value)" },
|
||||||
sar: { value: 0x1d, delta: 2, alpha: 1, doc: "v = sar(shiftBits, value)" },
|
sar: { value: 0x1d, delta: 2, alpha: 1, doc: "v = sar(shiftBits, value)" },
|
||||||
// SHA3
|
// SHA3
|
||||||
sha3: { value: 0x20, delta: 2, alpha: 1, doc: "v = sha3(offset, length)" },
|
sha3: { value: 0x20, delta: 2, alpha: 1, doc: "v = sha3(offset, length)", memory: "read" },
|
||||||
// Environmental Information
|
// Environmental Information
|
||||||
address: { value: 0x30, delta: 0, alpha: 1, doc: "myAddr = address" },
|
address: { value: 0x30, delta: 0, alpha: 1, doc: "myAddr = address" },
|
||||||
balance: { value: 0x31, delta: 1, alpha: 1, doc: "wei = balance(address)" },
|
balance: { value: 0x31, delta: 1, alpha: 1, doc: "wei = balance(address)" },
|
||||||
@ -84,14 +98,14 @@ const _Opcodes = {
|
|||||||
callvalue: { value: 0x34, delta: 0, alpha: 1, doc: "msgValue = callvalue" },
|
callvalue: { value: 0x34, delta: 0, alpha: 1, doc: "msgValue = callvalue" },
|
||||||
calldataload: { value: 0x35, delta: 1, alpha: 1, doc: "calldataWordValue = calldataload(byteOffet)" },
|
calldataload: { value: 0x35, delta: 1, alpha: 1, doc: "calldataWordValue = calldataload(byteOffet)" },
|
||||||
calldatasize: { value: 0x36, delta: 0, alpha: 1, doc: "calldataLength = calldatasize" },
|
calldatasize: { value: 0x36, delta: 0, alpha: 1, doc: "calldataLength = calldatasize" },
|
||||||
calldatacopy: { value: 0x37, delta: 3, alpha: 0, doc: "calldatacopy(dstMemoryIndex, dataIndex, length)" },
|
calldatacopy: { value: 0x37, delta: 3, alpha: 0, doc: "calldatacopy(dstMemoryIndex, dataIndex, length)", memory: "write" },
|
||||||
codesize: { value: 0x38, delta: 0, alpha: 1, doc: "myCodeLength = codesize" },
|
codesize: { value: 0x38, delta: 0, alpha: 1, doc: "myCodeLength = codesize" },
|
||||||
codecopy: { value: 0x39, delta: 3, alpha: 0, doc: "codecopy(dstMemoryIndex, codeIndex, length)" },
|
codecopy: { value: 0x39, delta: 3, alpha: 0, doc: "codecopy(dstMemoryIndex, codeIndex, length)", memory: "write" },
|
||||||
gasprice: { value: 0x3a, delta: 0, alpha: 1, doc: "txGasPrice = gasprice" },
|
gasprice: { value: 0x3a, delta: 0, alpha: 1, doc: "txGasPrice = gasprice" },
|
||||||
extcodesize: { value: 0x3b, delta: 1, alpha: 1, doc: "otherCodeLength = extcodesize(address)" },
|
extcodesize: { value: 0x3b, delta: 1, alpha: 1, doc: "otherCodeLength = extcodesize(address)" },
|
||||||
extcodecopy: { value: 0x3c, delta: 4, alpha: 0, doc: "extcodecopy(address, dstMemoryIndex, extcodeIndex, length)" },
|
extcodecopy: { value: 0x3c, delta: 4, alpha: 0, doc: "extcodecopy(address, dstMemoryIndex, extcodeIndex, length)", memory: "write" },
|
||||||
returndatasize: { value: 0x3d, delta: 0, alpha: 1, doc: "v = returndatasize" },
|
returndatasize: { value: 0x3d, delta: 0, alpha: 1, doc: "v = returndatasize" },
|
||||||
returndatacopy: { value: 0x3e, delta: 3, alpha: 0, doc: "returndatacopy(dstMemoryOffset, returndataIndex, length)" },
|
returndatacopy: { value: 0x3e, delta: 3, alpha: 0, doc: "returndatacopy(dstMemoryOffset, returndataIndex, length)", memory: "write" },
|
||||||
extcodehash: { value: 0x3f, delta: 1, alpha: 1, doc: "hash = extcodehash(address)" },
|
extcodehash: { value: 0x3f, delta: 1, alpha: 1, doc: "hash = extcodehash(address)" },
|
||||||
// Block Information
|
// Block Information
|
||||||
blockhash: { value: 0x40, delta: 1, alpha: 1, doc: "hash = blockhash(blockNumber)" },
|
blockhash: { value: 0x40, delta: 1, alpha: 1, doc: "hash = blockhash(blockNumber)" },
|
||||||
@ -102,11 +116,11 @@ const _Opcodes = {
|
|||||||
gaslimit: { value: 0x45, delta: 0, alpha: 1, doc: "gas = gaslimit" },
|
gaslimit: { value: 0x45, delta: 0, alpha: 1, doc: "gas = gaslimit" },
|
||||||
// Stack, Memory, Storage and Flow Operations
|
// Stack, Memory, Storage and Flow Operations
|
||||||
pop: { value: 0x50, delta: 1, alpha: 0, doc: "stackTopValue = pop" },
|
pop: { value: 0x50, delta: 1, alpha: 0, doc: "stackTopValue = pop" },
|
||||||
mload: { value: 0x51, delta: 1, alpha: 1, doc: "memoryWordValue = mload(memoryByteIndex)" },
|
mload: { value: 0x51, delta: 1, alpha: 1, doc: "memoryWordValue = mload(memoryByteIndex)", memory: "read" },
|
||||||
mstore: { value: 0x52, delta: 2, alpha: 0, doc: "mstore(memoryByteIndex, valueOut)" },
|
mstore: { value: 0x52, delta: 2, alpha: 0, doc: "mstore(memoryByteIndex, valueOut)", memory: "write" },
|
||||||
mstore8: { value: 0x53, delta: 2, alpha: 0, doc: "mstore8(memoryByteIndex, valueOut [ & 0xff ])" },
|
mstore8: { value: 0x53, delta: 2, alpha: 0, doc: "mstore8(memoryByteIndex, valueOut [ & 0xff ])", memory: "write" },
|
||||||
sload: { value: 0x54, delta: 1, alpha: 1, doc: "storageWordValue = sload(storageWordIndex)" },
|
sload: { value: 0x54, delta: 1, alpha: 1, doc: "storageWordValue = sload(storageWordIndex)" },
|
||||||
sstore: { value: 0x55, delta: 2, alpha: 0, doc: "sstore(storageWordIndex, valueOut)" },
|
sstore: { value: 0x55, delta: 2, alpha: 0, doc: "sstore(storageWordIndex, valueOut)", nonStatic: true },
|
||||||
jump: { value: 0x56, delta: 1, alpha: 0, doc: "jump(target)" },
|
jump: { value: 0x56, delta: 1, alpha: 0, doc: "jump(target)" },
|
||||||
jumpi: { value: 0x57, delta: 2, alpha: 0, doc: "jumpi(target, notZero)" },
|
jumpi: { value: 0x57, delta: 2, alpha: 0, doc: "jumpi(target, notZero)" },
|
||||||
pc: { value: 0x58, delta: 0, alpha: 1, doc: "programCounter = pc" },
|
pc: { value: 0x58, delta: 0, alpha: 1, doc: "programCounter = pc" },
|
||||||
@ -181,22 +195,22 @@ const _Opcodes = {
|
|||||||
swap15: { value: 0x9e, delta: 0, alpha: 0 },
|
swap15: { value: 0x9e, delta: 0, alpha: 0 },
|
||||||
swap16: { value: 0x9f, delta: 0, alpha: 0 },
|
swap16: { value: 0x9f, delta: 0, alpha: 0 },
|
||||||
// Loggin Operations
|
// Loggin Operations
|
||||||
log0: { value: 0xa0, delta: 2, alpha: 0 },
|
log0: { value: 0xa0, delta: 2, alpha: 0, nonStatic: true, memory: "read" },
|
||||||
log1: { value: 0xa1, delta: 3, alpha: 0 },
|
log1: { value: 0xa1, delta: 3, alpha: 0, nonStatic: true, memory: "read" },
|
||||||
log2: { value: 0xa2, delta: 4, alpha: 0 },
|
log2: { value: 0xa2, delta: 4, alpha: 0, nonStatic: true, memory: "read" },
|
||||||
log3: { value: 0xa3, delta: 5, alpha: 0 },
|
log3: { value: 0xa3, delta: 5, alpha: 0, nonStatic: true, memory: "read" },
|
||||||
log4: { value: 0xa4, delta: 6, alpha: 0 },
|
log4: { value: 0xa4, delta: 6, alpha: 0, nonStatic: true, memory: "read" },
|
||||||
// System Operations
|
// System Operations
|
||||||
create: { value: 0xf0, delta: 3, alpha: 1, doc: "address = create(value, index, length)" },
|
create: { value: 0xf0, delta: 3, alpha: 1, doc: "address = create(value, index, length)", nonStatic: true, memory: "read" },
|
||||||
call: { value: 0xf1, delta: 7, alpha: 1, doc: "v = call(gasLimit, address, value, inputIndex, inputLength, outputIndex, outputLength)" },
|
call: { value: 0xf1, delta: 7, alpha: 1, doc: "v = call(gasLimit, address, value, inputIndex, inputLength, outputIndex, outputLength)", nonStatic: true, memory: "full" },
|
||||||
callcode: { value: 0xf2, delta: 7, alpha: 1, doc: "v = callcode(@TODO)" },
|
callcode: { value: 0xf2, delta: 7, alpha: 1, doc: "v = callcode(@TODO)", nonStatic: true, memory: "full" },
|
||||||
"return": { value: 0xf3, delta: 2, alpha: 0, doc: "return(index, length)" },
|
"return": { value: 0xf3, delta: 2, alpha: 0, doc: "return(index, length)", memory: "read" },
|
||||||
delegatecall: { value: 0xf4, delta: 6, alpha: 1, doc: "v = delegatecall(gasLimit, address, inputIndex, inputLength, outputIndex, outputLength)" },
|
delegatecall: { value: 0xf4, delta: 6, alpha: 1, doc: "v = delegatecall(gasLimit, address, inputIndex, inputLength, outputIndex, outputLength)", nonStatic: true, memory: "full" },
|
||||||
create2: { value: 0xf5, delta: 4, alpha: 1, doc: "address = create2(value, index, length, salt)" },
|
create2: { value: 0xf5, delta: 4, alpha: 1, doc: "address = create2(value, index, length, salt)", nonStatic: true, memory: "read" },
|
||||||
staticcall: { value: 0xfa, delta: 6, alpha: 1, doc: "v = staticcall(gasLimit, address, inputIndex, inputLength, outputIndex, outputLength)" },
|
staticcall: { value: 0xfa, delta: 6, alpha: 1, doc: "v = staticcall(gasLimit, address, inputIndex, inputLength, outputIndex, outputLength)", memory: "full" },
|
||||||
revert: { value: 0xfd, delta: 2, alpha: 0, doc: "revert(returnDataOffset, returnDataLength)" },
|
revert: { value: 0xfd, delta: 2, alpha: 0, doc: "revert(returnDataOffset, returnDataLength)", memory: "read" },
|
||||||
invalid: { value: 0xfe, delta: 0, alpha: 0, doc: "invalid" },
|
invalid: { value: 0xfe, delta: 0, alpha: 0, doc: "invalid" },
|
||||||
suicide: { value: 0xff, delta: 1, alpha: 0, doc: "suicide(targetAddress)" },
|
suicide: { value: 0xff, delta: 1, alpha: 0, doc: "suicide(targetAddress)", nonStatic: true },
|
||||||
};
|
};
|
||||||
const OpcodeMap = {};
|
const OpcodeMap = {};
|
||||||
const Opcodes = [];
|
const Opcodes = [];
|
||||||
|
@ -72,12 +72,12 @@
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
var parser = (function(){
|
var parser = (function(){
|
||||||
var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[2,19],$V1=[1,7],$V2=[1,8],$V3=[1,9],$V4=[1,10],$V5=[1,11],$V6=[1,12],$V7=[1,5],$V8=[1,6],$V9=[5,25],$Va=[5,11,14,15,16,17,18,22,25,28],$Vb=[2,2],$Vc=[1,19],$Vd=[5,10,11,13,14,15,16,17,18,22,25,28],$Ve=[1,25],$Vf=[1,26],$Vg=[1,27],$Vh=[2,14],$Vi=[5,10,11,13,14,15,16,17,18,22,25,27,28],$Vj=[16,17,18,27];
|
var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[2,21],$V1=[1,7],$V2=[1,8],$V3=[1,9],$V4=[1,10],$V5=[1,11],$V6=[1,12],$V7=[1,13],$V8=[1,14],$V9=[1,5],$Va=[1,6],$Vb=[5,27],$Vc=[5,11,14,15,16,17,18,19,20,24,27,30],$Vd=[2,2],$Ve=[1,21],$Vf=[5,10,11,13,14,15,16,17,18,19,20,24,27,30],$Vg=[1,27],$Vh=[1,28],$Vi=[1,29],$Vj=[2,16],$Vk=[5,10,11,13,14,15,16,17,18,19,20,24,27,29,30],$Vl=[16,17,20,29];
|
||||||
var parser = {trace: function trace () { },
|
var parser = {trace: function trace () { },
|
||||||
yy: {},
|
yy: {},
|
||||||
symbols_: {"error":2,"program":3,"statement_list":4,"EOF":5,"javascript":6,"SCRIPT_TOKEN":7,"opcode_list":8,"opcode":9,"COMMA":10,"ID":11,"OPEN_PAREN":12,"CLOSE_PAREN":13,"HASH_ID":14,"DOLLAR_ID":15,"HEX":16,"DECIMAL":17,"SCRIPT_EVAL":18,"hex_list":19,"hex":20,"statement":21,"AT_ID":22,"COLON":23,"OPEN_BRACE":24,"CLOSE_BRACE":25,"OPEN_BRACKET":26,"CLOSE_BRACKET":27,"SCRIPT_EXEC":28,"$accept":0,"$end":1},
|
symbols_: {"error":2,"program":3,"statement_list":4,"EOF":5,"javascript":6,"SCRIPT_TOKEN":7,"opcode_list":8,"opcode":9,"COMMA":10,"ID":11,"OPEN_PAREN":12,"CLOSE_PAREN":13,"HASH_ID":14,"DOLLAR_ID":15,"HEX":16,"DECIMAL":17,"DOLLAR_DOLLAR":18,"DOLLAR_INDEX":19,"SCRIPT_EVAL":20,"hex_list":21,"hex":22,"statement":23,"AT_ID":24,"COLON":25,"OPEN_BRACE":26,"CLOSE_BRACE":27,"OPEN_BRACKET":28,"CLOSE_BRACKET":29,"SCRIPT_EXEC":30,"$accept":0,"$end":1},
|
||||||
terminals_: {2:"error",5:"EOF",7:"SCRIPT_TOKEN",10:"COMMA",11:"ID",12:"OPEN_PAREN",13:"CLOSE_PAREN",14:"HASH_ID",15:"DOLLAR_ID",16:"HEX",17:"DECIMAL",18:"SCRIPT_EVAL",22:"AT_ID",23:"COLON",24:"OPEN_BRACE",25:"CLOSE_BRACE",26:"OPEN_BRACKET",27:"CLOSE_BRACKET",28:"SCRIPT_EXEC"},
|
terminals_: {2:"error",5:"EOF",7:"SCRIPT_TOKEN",10:"COMMA",11:"ID",12:"OPEN_PAREN",13:"CLOSE_PAREN",14:"HASH_ID",15:"DOLLAR_ID",16:"HEX",17:"DECIMAL",18:"DOLLAR_DOLLAR",19:"DOLLAR_INDEX",20:"SCRIPT_EVAL",24:"AT_ID",25:"COLON",26:"OPEN_BRACE",27:"CLOSE_BRACE",28:"OPEN_BRACKET",29:"CLOSE_BRACKET",30:"SCRIPT_EXEC"},
|
||||||
productions_: [0,[3,2],[6,0],[6,2],[8,1],[8,3],[9,1],[9,3],[9,4],[9,1],[9,1],[9,1],[9,1],[9,2],[19,0],[19,2],[20,1],[20,1],[20,2],[4,0],[4,2],[21,1],[21,2],[21,4],[21,4],[21,2]],
|
productions_: [0,[3,2],[6,0],[6,2],[8,1],[8,3],[9,1],[9,3],[9,4],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,2],[21,0],[21,2],[22,1],[22,1],[22,2],[4,0],[4,2],[23,1],[23,2],[23,4],[23,4],[23,2]],
|
||||||
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
|
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
|
||||||
/* this == yyval */
|
/* this == yyval */
|
||||||
|
|
||||||
@ -124,54 +124,69 @@ case 12:
|
|||||||
this.$ = { type: "decimal", value: $$[$0], loc: getLoc(yy, _$[$0]) };
|
this.$ = { type: "decimal", value: $$[$0], loc: getLoc(yy, _$[$0]) };
|
||||||
break;
|
break;
|
||||||
case 13:
|
case 13:
|
||||||
this.$ = { type: "eval", script: $$[$0], loc: getLoc(yy, _$[$0-1], _$[$0]) };
|
this.$ = { type: "pop", index: 0, loc: getLoc(yy, _$[$0]) };
|
||||||
break;
|
break;
|
||||||
case 14: case 19:
|
case 14:
|
||||||
this.$ = [ ];
|
this.$ = { type: "pop", index: parseInt(($$[$0]).substring(1)), loc: getLoc(yy, _$[$0]) };
|
||||||
break;
|
break;
|
||||||
case 15:
|
case 15:
|
||||||
|
this.$ = { type: "eval", script: $$[$0], loc: getLoc(yy, _$[$0-1], _$[$0]) };
|
||||||
|
break;
|
||||||
|
case 16: case 21:
|
||||||
|
this.$ = [ ];
|
||||||
|
break;
|
||||||
|
case 17:
|
||||||
{
|
{
|
||||||
const hexes = $$[$0].slice();;
|
const hexes = $$[$0].slice();;
|
||||||
hexes.unshift($$[$0-1]);
|
hexes.unshift($$[$0-1]);
|
||||||
this.$ = hexes;
|
this.$ = hexes;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 18:
|
||||||
this.$ = { type: "hex", verbatim: true, value: $$[$0], loc: getLoc(yy, _$[$0]) };
|
this.$ = { type: "hex", verbatim: true, value: $$[$0], loc: getLoc(yy, _$[$0]) };
|
||||||
break;
|
break;
|
||||||
case 17:
|
case 19:
|
||||||
{
|
{
|
||||||
const value = parseInt($$[$0]);
|
const value = parseInt($$[$0]);
|
||||||
if (value >= 256) { throw new Error("decimal data values must be single bytes"); }
|
if (value >= 256) { throw new Error("decimal data values must be single bytes"); }
|
||||||
this.$ = { type: "hex", verbatim: true, value: ("0x" + (value).toString(16)), loc: getLoc(yy, _$[$0]) };
|
let hex = (value).toString(16);
|
||||||
|
while (hex.length < 2) { hex = "0" + hex; }
|
||||||
|
this.$ = { type: "hex", verbatim: true, value: ("0x" + hex), loc: getLoc(yy, _$[$0]) };
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 18:
|
case 20:
|
||||||
this.$ = { type: "eval", verbatim: true, script: $$[$0], loc: getLoc(yy, _$[$0-1], _$[$0]) };
|
this.$ = { type: "eval", verbatim: true, script: $$[$0], loc: getLoc(yy, _$[$0-1], _$[$0]) };
|
||||||
break;
|
break;
|
||||||
case 20:
|
case 22:
|
||||||
{
|
{
|
||||||
const statements = $$[$0].slice();
|
const statements = $$[$0].slice();
|
||||||
statements.unshift($$[$0-1]);
|
statements.unshift($$[$0-1]);
|
||||||
this.$ = statements;
|
this.$ = statements;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 22:
|
|
||||||
this.$ = { type: "label", name: $$[$0-1].substring(1), loc: getLoc(yy, _$[$0-1], _$[$0]) };
|
|
||||||
break;
|
|
||||||
case 23:
|
case 23:
|
||||||
this.$ = { type: "scope", name: $$[$0-3].substring(1), statements: $$[$0-1], loc: getLoc(yy, _$[$0-3], _$[$0]) };
|
{
|
||||||
|
const statement = $$[$0];
|
||||||
|
statement.loc.statement = true;
|
||||||
|
this.$ = statement;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 24:
|
case 24:
|
||||||
this.$ = { type: "data", name: $$[$0-3].substring(1), data: $$[$0-1], loc: getLoc(yy, _$[$0-3], _$[$0]) };
|
this.$ = { type: "label", name: $$[$0-1].substring(1), loc: getLoc(yy, _$[$0-1], _$[$0], true) };
|
||||||
break;
|
break;
|
||||||
case 25:
|
case 25:
|
||||||
this.$ = { type: "exec", script: $$[$0], loc: getLoc(yy, _$[$0-1], _$[$0]) };
|
this.$ = { type: "scope", name: $$[$0-3].substring(1), statements: $$[$0-1], loc: getLoc(yy, _$[$0-3], _$[$0], true) };
|
||||||
|
break;
|
||||||
|
case 26:
|
||||||
|
this.$ = { type: "data", name: $$[$0-3].substring(1), data: $$[$0-1], loc: getLoc(yy, _$[$0-3], _$[$0], true) };
|
||||||
|
break;
|
||||||
|
case 27:
|
||||||
|
this.$ = { type: "exec", script: $$[$0], loc: getLoc(yy, _$[$0-1], _$[$0], true) };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
table: [{3:1,4:2,5:$V0,9:4,11:$V1,14:$V2,15:$V3,16:$V4,17:$V5,18:$V6,21:3,22:$V7,28:$V8},{1:[3]},{5:[1,13]},o($V9,$V0,{21:3,9:4,4:14,11:$V1,14:$V2,15:$V3,16:$V4,17:$V5,18:$V6,22:$V7,28:$V8}),o($Va,[2,21]),{23:[1,15],24:[1,16],26:[1,17]},o($Va,$Vb,{6:18,7:$Vc}),o($Vd,[2,6],{12:[1,20]}),o($Vd,[2,9]),o($Vd,[2,10]),o($Vd,[2,11]),o($Vd,[2,12]),o($Vd,$Vb,{6:21,7:$Vc}),{1:[2,1]},o($V9,[2,20]),o($Va,[2,22]),{4:22,9:4,11:$V1,14:$V2,15:$V3,16:$V4,17:$V5,18:$V6,21:3,22:$V7,25:$V0,28:$V8},{16:$Ve,17:$Vf,18:$Vg,19:23,20:24,27:$Vh},o($Va,[2,25]),o($Vi,$Vb,{6:28,7:$Vc}),{8:30,9:31,11:$V1,13:[1,29],14:$V2,15:$V3,16:$V4,17:$V5,18:$V6},o($Vd,[2,13]),{25:[1,32]},{27:[1,33]},{16:$Ve,17:$Vf,18:$Vg,19:34,20:24,27:$Vh},o($Vj,[2,16]),o($Vj,[2,17]),o($Vj,$Vb,{6:35,7:$Vc}),o($Vi,[2,3]),o($Vd,[2,7]),{13:[1,36]},{10:[1,37],13:[2,4]},o($Va,[2,23]),o($Va,[2,24]),{27:[2,15]},o($Vj,[2,18]),o($Vd,[2,8]),{8:38,9:31,11:$V1,14:$V2,15:$V3,16:$V4,17:$V5,18:$V6},{13:[2,5]}],
|
table: [{3:1,4:2,5:$V0,9:4,11:$V1,14:$V2,15:$V3,16:$V4,17:$V5,18:$V6,19:$V7,20:$V8,23:3,24:$V9,30:$Va},{1:[3]},{5:[1,15]},o($Vb,$V0,{23:3,9:4,4:16,11:$V1,14:$V2,15:$V3,16:$V4,17:$V5,18:$V6,19:$V7,20:$V8,24:$V9,30:$Va}),o($Vc,[2,23]),{25:[1,17],26:[1,18],28:[1,19]},o($Vc,$Vd,{6:20,7:$Ve}),o($Vf,[2,6],{12:[1,22]}),o($Vf,[2,9]),o($Vf,[2,10]),o($Vf,[2,11]),o($Vf,[2,12]),o($Vf,[2,13]),o($Vf,[2,14]),o($Vf,$Vd,{6:23,7:$Ve}),{1:[2,1]},o($Vb,[2,22]),o($Vc,[2,24]),{4:24,9:4,11:$V1,14:$V2,15:$V3,16:$V4,17:$V5,18:$V6,19:$V7,20:$V8,23:3,24:$V9,27:$V0,30:$Va},{16:$Vg,17:$Vh,20:$Vi,21:25,22:26,29:$Vj},o($Vc,[2,27]),o($Vk,$Vd,{6:30,7:$Ve}),{8:32,9:33,11:$V1,13:[1,31],14:$V2,15:$V3,16:$V4,17:$V5,18:$V6,19:$V7,20:$V8},o($Vf,[2,15]),{27:[1,34]},{29:[1,35]},{16:$Vg,17:$Vh,20:$Vi,21:36,22:26,29:$Vj},o($Vl,[2,18]),o($Vl,[2,19]),o($Vl,$Vd,{6:37,7:$Ve}),o($Vk,[2,3]),o($Vf,[2,7]),{13:[1,38]},{10:[1,39],13:[2,4]},o($Vc,[2,25]),o($Vc,[2,26]),{29:[2,17]},o($Vl,[2,20]),o($Vf,[2,8]),{8:40,9:33,11:$V1,14:$V2,15:$V3,16:$V4,17:$V5,18:$V6,19:$V7,20:$V8},{13:[2,5]}],
|
||||||
defaultActions: {13:[2,1],34:[2,15],38:[2,5]},
|
defaultActions: {15:[2,1],36:[2,17],40:[2,5]},
|
||||||
parseError: function parseError (str, hash) {
|
parseError: function parseError (str, hash) {
|
||||||
if (hash.recoverable) {
|
if (hash.recoverable) {
|
||||||
this.trace(str);
|
this.trace(str);
|
||||||
@ -320,7 +335,7 @@ parse: function parse(input) {
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
||||||
function getLoc(yy, start, end) {
|
function getLoc(yy, start, end, statement) {
|
||||||
if (end == null) { end = start; }
|
if (end == null) { end = start; }
|
||||||
|
|
||||||
let result = null;
|
let result = null;
|
||||||
@ -329,7 +344,8 @@ function getLoc(yy, start, end) {
|
|||||||
first_line: start.first_line,
|
first_line: start.first_line,
|
||||||
first_column: start.first_column,
|
first_column: start.first_column,
|
||||||
last_line: end.last_line,
|
last_line: end.last_line,
|
||||||
last_column: end.last_column
|
last_column: end.last_column,
|
||||||
|
statement: !!statement
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,7 +353,7 @@ function getLoc(yy, start, end) {
|
|||||||
return yy._ethersLocation(result);
|
return yy._ethersLocation(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Object.freeze(result);
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generated by jison-lex 0.3.4 */
|
/* generated by jison-lex 0.3.4 */
|
||||||
@ -690,9 +706,9 @@ case 9:return "COMMA"
|
|||||||
break;
|
break;
|
||||||
case 10:return "AT_ID"
|
case 10:return "AT_ID"
|
||||||
break;
|
break;
|
||||||
case 11:return "HASH_ID"
|
case 11:return "DOLLAR_ID"
|
||||||
break;
|
break;
|
||||||
case 12:return "DOLLAR_ID"
|
case 12:return "HASH_ID"
|
||||||
break;
|
break;
|
||||||
case 13:return "OPEN_BRACE"
|
case 13:return "OPEN_BRACE"
|
||||||
break;
|
break;
|
||||||
@ -708,14 +724,18 @@ case 18:return "HEX"
|
|||||||
break;
|
break;
|
||||||
case 19:return "DECIMAL"
|
case 19:return "DECIMAL"
|
||||||
break;
|
break;
|
||||||
case 20:return "EOF"
|
case 20:return "DOLLAR_DOLLAR"
|
||||||
break;
|
break;
|
||||||
case 21:return "INVALID"
|
case 21:return "DOLLAR_INDEX"
|
||||||
|
break;
|
||||||
|
case 22:return "EOF"
|
||||||
|
break;
|
||||||
|
case 23:return "INVALID"
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
rules: [/^(?:\{\{=)/,/^(?:\{\{!)/,/^(?:([^\}]|\n|\}[^}]))/,/^(?:\}\})/,/^(?:([;][^\n]*\n))/,/^(?:(\s+))/,/^(?:([A-Za-z][A-Za-z0-9]*))/,/^(?:\()/,/^(?:\))/,/^(?:,)/,/^(?:([@][A-Za-z][A-Za-z0-9]*))/,/^(?:([#][A-Za-z][A-Za-z0-9]*))/,/^(?:([$][A-Za-z][A-Za-z0-9]*))/,/^(?:\{)/,/^(?:\})/,/^(?::)/,/^(?:\[)/,/^(?:\])/,/^(?:(0x([0-9a-fA-F][0-9a-fA-F])*))/,/^(?:([1-9][0-9]*|0))/,/^(?:$)/,/^(?:)/],
|
rules: [/^(?:\{\{=)/,/^(?:\{\{!)/,/^(?:([^\}]|\n|\}[^}]))/,/^(?:\}\})/,/^(?:([;][^\n]*\n))/,/^(?:(\s+))/,/^(?:([A-Za-z][A-Za-z0-9]*))/,/^(?:\()/,/^(?:\))/,/^(?:,)/,/^(?:([@][A-Za-z][A-Za-z0-9]*))/,/^(?:([$](_|[A-Za-z][A-Za-z0-9]*)))/,/^(?:([#](_|[A-Za-z][A-Za-z0-9]*)))/,/^(?:\{)/,/^(?:\})/,/^(?::)/,/^(?:\[)/,/^(?:\])/,/^(?:(0x([0-9a-fA-F][0-9a-fA-F])*))/,/^(?:([1-9][0-9]*|0))/,/^(?:\$\$)/,/^(?:([$][1-9][0-9]*))/,/^(?:$)/,/^(?:)/],
|
||||||
conditions: {"script":{"rules":[2,3],"inclusive":false},"INITIAL":{"rules":[0,1,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21],"inclusive":true}}
|
conditions: {"script":{"rules":[2,3],"inclusive":false},"INITIAL":{"rules":[0,1,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23],"inclusive":true}}
|
||||||
});
|
});
|
||||||
return lexer;
|
return lexer;
|
||||||
})();
|
})();
|
||||||
|
2
packages/asm/lib/_version.d.ts
vendored
2
packages/asm/lib/_version.d.ts
vendored
@ -1 +1 @@
|
|||||||
export declare const version = "asm/5.0.0-beta.148";
|
export declare const version = "asm/5.0.0-beta.149";
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.version = "asm/5.0.0-beta.148";
|
exports.version = "asm/5.0.0-beta.149";
|
||||||
|
71
packages/asm/lib/assembler.d.ts
vendored
71
packages/asm/lib/assembler.d.ts
vendored
@ -1,15 +1,16 @@
|
|||||||
import { Opcode } from "./opcodes";
|
import { Opcode } from "./opcodes";
|
||||||
export declare type Location = {
|
export declare type Location = {
|
||||||
offset: number;
|
offset: number;
|
||||||
|
line: number;
|
||||||
length: number;
|
length: number;
|
||||||
source: string;
|
source: string;
|
||||||
|
statement: boolean;
|
||||||
};
|
};
|
||||||
export declare type AssembleVisitFunc = (node: Node, bytecode: string) => void;
|
export declare type AssembleVisitFunc = (node: Node, bytecode: string) => void;
|
||||||
export declare type VisitFunc = (node: Node) => void;
|
export declare type VisitFunc = (node: Node) => void;
|
||||||
export declare abstract class Node {
|
export declare abstract class Node {
|
||||||
readonly tag: string;
|
readonly tag: string;
|
||||||
readonly location: Location;
|
readonly location: Location;
|
||||||
readonly warnings: Array<string>;
|
|
||||||
constructor(guard: any, location: Location, options: {
|
constructor(guard: any, location: Location, options: {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
});
|
});
|
||||||
@ -30,6 +31,12 @@ export declare class LiteralNode extends ValueNode {
|
|||||||
assemble(assembler: Assembler, visit: AssembleVisitFunc): Promise<void>;
|
assemble(assembler: Assembler, visit: AssembleVisitFunc): Promise<void>;
|
||||||
static from(options: any): LiteralNode;
|
static from(options: any): LiteralNode;
|
||||||
}
|
}
|
||||||
|
export declare class PopNode extends ValueNode {
|
||||||
|
readonly index: number;
|
||||||
|
constructor(guard: any, location: Location, index: number);
|
||||||
|
readonly placeholder: string;
|
||||||
|
static from(options: any): PopNode;
|
||||||
|
}
|
||||||
export declare class LinkNode extends ValueNode {
|
export declare class LinkNode extends ValueNode {
|
||||||
readonly type: string;
|
readonly type: string;
|
||||||
readonly label: string;
|
readonly label: string;
|
||||||
@ -40,7 +47,8 @@ export declare class LinkNode extends ValueNode {
|
|||||||
export declare class OpcodeNode extends ValueNode {
|
export declare class OpcodeNode extends ValueNode {
|
||||||
readonly opcode: Opcode;
|
readonly opcode: Opcode;
|
||||||
readonly operands: Array<ValueNode>;
|
readonly operands: Array<ValueNode>;
|
||||||
constructor(guard: any, location: Location, opcode: Opcode, operands: Array<ValueNode>);
|
readonly instructional: boolean;
|
||||||
|
constructor(guard: any, location: Location, opcode: Opcode, operands: Array<ValueNode>, instructional: boolean);
|
||||||
assemble(assembler: Assembler, visit: AssembleVisitFunc): Promise<void>;
|
assemble(assembler: Assembler, visit: AssembleVisitFunc): Promise<void>;
|
||||||
children(): Array<Node>;
|
children(): Array<Node>;
|
||||||
visit(visit: VisitFunc): void;
|
visit(visit: VisitFunc): void;
|
||||||
@ -61,7 +69,6 @@ export declare class DataNode extends LabelledNode {
|
|||||||
constructor(guard: any, location: Location, name: string, data: string);
|
constructor(guard: any, location: Location, name: string, data: string);
|
||||||
assemble(assembler: Assembler, visit: AssembleVisitFunc): Promise<void>;
|
assemble(assembler: Assembler, visit: AssembleVisitFunc): Promise<void>;
|
||||||
children(): Array<Node>;
|
children(): Array<Node>;
|
||||||
visit(visit: VisitFunc): void;
|
|
||||||
static from(options: any): DataNode;
|
static from(options: any): DataNode;
|
||||||
}
|
}
|
||||||
export declare class EvaluationNode extends ValueNode {
|
export declare class EvaluationNode extends ValueNode {
|
||||||
@ -82,10 +89,8 @@ export declare class ScopeNode extends LabelledNode {
|
|||||||
constructor(guard: any, location: Location, name: string, statements: Array<Node>);
|
constructor(guard: any, location: Location, name: string, statements: Array<Node>);
|
||||||
assemble(assembler: Assembler, visit: AssembleVisitFunc): Promise<void>;
|
assemble(assembler: Assembler, visit: AssembleVisitFunc): Promise<void>;
|
||||||
children(): Array<Node>;
|
children(): Array<Node>;
|
||||||
visit(visit: VisitFunc): void;
|
|
||||||
static from(options: any): ScopeNode;
|
static from(options: any): ScopeNode;
|
||||||
}
|
}
|
||||||
export declare function parse(code: string): Node;
|
|
||||||
export declare type Operation = {
|
export declare type Operation = {
|
||||||
opcode: Opcode;
|
opcode: Opcode;
|
||||||
offset: number;
|
offset: number;
|
||||||
@ -96,15 +101,15 @@ export interface Bytecode extends Array<Operation> {
|
|||||||
}
|
}
|
||||||
export declare function disassemble(bytecode: string): Bytecode;
|
export declare function disassemble(bytecode: string): Bytecode;
|
||||||
export declare function formatBytecode(bytecode: Array<Operation>): string;
|
export declare function formatBytecode(bytecode: Array<Operation>): string;
|
||||||
interface DataSource extends Array<number> {
|
export interface DataSource extends Array<number> {
|
||||||
readonly offset: number;
|
offset: number;
|
||||||
|
ast: Node;
|
||||||
|
source: string;
|
||||||
}
|
}
|
||||||
declare type NodeState = {
|
export declare type NodeState = {
|
||||||
node: Node;
|
node: Node;
|
||||||
offset: number;
|
offset: number;
|
||||||
bytecode: string;
|
bytecode: string;
|
||||||
pending: string;
|
|
||||||
object?: number | DataSource;
|
|
||||||
};
|
};
|
||||||
export declare type AssemblerOptions = {
|
export declare type AssemblerOptions = {
|
||||||
filename?: string;
|
filename?: string;
|
||||||
@ -113,42 +118,46 @@ export declare type AssemblerOptions = {
|
|||||||
defines?: {
|
defines?: {
|
||||||
[name: string]: any;
|
[name: string]: any;
|
||||||
};
|
};
|
||||||
|
target?: string;
|
||||||
|
};
|
||||||
|
export declare type ParserOptions = {
|
||||||
|
ignoreWarnings?: boolean;
|
||||||
};
|
};
|
||||||
declare class Assembler {
|
declare class Assembler {
|
||||||
readonly root: Node;
|
readonly root: Node;
|
||||||
|
readonly positionIndependentCode: boolean;
|
||||||
readonly nodes: {
|
readonly nodes: {
|
||||||
[tag: string]: NodeState;
|
[tag: string]: NodeState;
|
||||||
};
|
};
|
||||||
readonly labels: {
|
readonly labels: {
|
||||||
[name: string]: LabelledNode;
|
[name: string]: LabelledNode;
|
||||||
};
|
};
|
||||||
readonly filename: string;
|
_parents: {
|
||||||
readonly positionIndependentCode: boolean;
|
[tag: string]: Node;
|
||||||
readonly retry: number;
|
|
||||||
readonly defines: {
|
|
||||||
[name: string]: any;
|
|
||||||
};
|
};
|
||||||
private _stack;
|
constructor(root: Node, positionIndependentCode?: boolean);
|
||||||
private _parents;
|
getTarget(label: string): LabelledNode;
|
||||||
private _script;
|
|
||||||
private _changed;
|
|
||||||
constructor(root: Node, options: AssemblerOptions);
|
|
||||||
readonly changed: boolean;
|
|
||||||
getTarget(name: string): LabelledNode;
|
|
||||||
reset(): void;
|
|
||||||
evaluate(script: string, source: Node): Promise<any>;
|
evaluate(script: string, source: Node): Promise<any>;
|
||||||
start(node: Node): void;
|
|
||||||
end(node: Node): void;
|
|
||||||
getPendingBytecode(node: Node): string;
|
|
||||||
_appendBytecode(bytecode: string): void;
|
|
||||||
getAncestor<T = Node>(node: Node, cls: {
|
getAncestor<T = Node>(node: Node, cls: {
|
||||||
new (...args: any[]): T;
|
new (...args: any[]): T;
|
||||||
}): T;
|
}): T;
|
||||||
|
getOffset(node: Node, source?: Node): number;
|
||||||
|
setOffset(node: Node, offset: number): void;
|
||||||
|
getBytecode(node: Node): string;
|
||||||
|
setBytecode(node: Node, bytecode: string): void;
|
||||||
getLinkValue(target: LabelledNode, source: Node): number | DataSource;
|
getLinkValue(target: LabelledNode, source: Node): number | DataSource;
|
||||||
get(name: string, source: Node): any;
|
start(node: Node): void;
|
||||||
_didChange(): void;
|
end(node: Node): void;
|
||||||
_assemble(): Promise<string>;
|
|
||||||
assemble(): Promise<string>;
|
|
||||||
}
|
}
|
||||||
|
export declare enum SemanticErrorSeverity {
|
||||||
|
error = "error",
|
||||||
|
warning = "warning"
|
||||||
|
}
|
||||||
|
export declare type SemanticError = {
|
||||||
|
readonly message: string;
|
||||||
|
readonly severity: SemanticErrorSeverity;
|
||||||
|
readonly node: Node;
|
||||||
|
};
|
||||||
|
export declare function parse(code: string, options?: ParserOptions): Node;
|
||||||
export declare function assemble(ast: Node, options?: AssemblerOptions): Promise<string>;
|
export declare function assemble(ast: Node, options?: AssemblerOptions): Promise<string>;
|
||||||
export {};
|
export {};
|
||||||
|
@ -53,10 +53,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
// @TODO:
|
// @TODO:
|
||||||
// - PIC
|
|
||||||
// - warn on opcode non-function iff parameters
|
|
||||||
// - warn return/revert non-empty, comment ; !assert(+1 @extra)
|
// - warn return/revert non-empty, comment ; !assert(+1 @extra)
|
||||||
// - $$
|
|
||||||
// - In JS add config (positionIndependent)
|
// - In JS add config (positionIndependent)
|
||||||
// - When checking name collisions, verify no collision in javascript
|
// - When checking name collisions, verify no collision in javascript
|
||||||
var path_1 = require("path");
|
var path_1 = require("path");
|
||||||
@ -174,9 +171,8 @@ var Node = /** @class */ (function () {
|
|||||||
throw new Error("cannot instantiate class");
|
throw new Error("cannot instantiate class");
|
||||||
}
|
}
|
||||||
logger.checkAbstract(_newTarget, Node);
|
logger.checkAbstract(_newTarget, Node);
|
||||||
ethers_1.ethers.utils.defineReadOnly(this, "location", location);
|
ethers_1.ethers.utils.defineReadOnly(this, "location", Object.freeze(location));
|
||||||
ethers_1.ethers.utils.defineReadOnly(this, "tag", "node-" + nextTag++ + "-" + this.constructor.name);
|
ethers_1.ethers.utils.defineReadOnly(this, "tag", "node-" + nextTag++ + "-" + this.constructor.name);
|
||||||
ethers_1.ethers.utils.defineReadOnly(this, "warnings", []);
|
|
||||||
for (var key in options) {
|
for (var key in options) {
|
||||||
ethers_1.ethers.utils.defineReadOnly(this, key, options[key]);
|
ethers_1.ethers.utils.defineReadOnly(this, key, options[key]);
|
||||||
}
|
}
|
||||||
@ -198,6 +194,9 @@ var Node = /** @class */ (function () {
|
|||||||
};
|
};
|
||||||
Node.prototype.visit = function (visit) {
|
Node.prototype.visit = function (visit) {
|
||||||
visit(this);
|
visit(this);
|
||||||
|
this.children().forEach(function (child) {
|
||||||
|
child.visit(visit);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
Node.from = function (options) {
|
Node.from = function (options) {
|
||||||
var Factories = {
|
var Factories = {
|
||||||
@ -210,6 +209,7 @@ var Node = /** @class */ (function () {
|
|||||||
length: LinkNode,
|
length: LinkNode,
|
||||||
offset: LinkNode,
|
offset: LinkNode,
|
||||||
opcode: OpcodeNode,
|
opcode: OpcodeNode,
|
||||||
|
pop: PopNode,
|
||||||
scope: ScopeNode,
|
scope: ScopeNode,
|
||||||
};
|
};
|
||||||
var factory = Factories[options.type];
|
var factory = Factories[options.type];
|
||||||
@ -221,14 +221,6 @@ var Node = /** @class */ (function () {
|
|||||||
return Node;
|
return Node;
|
||||||
}());
|
}());
|
||||||
exports.Node = Node;
|
exports.Node = Node;
|
||||||
/*
|
|
||||||
export abstract class CodeNode extends Node {
|
|
||||||
constructor(guard: any, location: Location, options: { [ key: string ]: any }) {
|
|
||||||
logger.checkAbstract(new.target, CodeNode);
|
|
||||||
super(guard, location, options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
var ValueNode = /** @class */ (function (_super) {
|
var ValueNode = /** @class */ (function (_super) {
|
||||||
__extends(ValueNode, _super);
|
__extends(ValueNode, _super);
|
||||||
function ValueNode(guard, location, options) {
|
function ValueNode(guard, location, options) {
|
||||||
@ -288,6 +280,27 @@ var LiteralNode = /** @class */ (function (_super) {
|
|||||||
return LiteralNode;
|
return LiteralNode;
|
||||||
}(ValueNode));
|
}(ValueNode));
|
||||||
exports.LiteralNode = LiteralNode;
|
exports.LiteralNode = LiteralNode;
|
||||||
|
var PopNode = /** @class */ (function (_super) {
|
||||||
|
__extends(PopNode, _super);
|
||||||
|
function PopNode(guard, location, index) {
|
||||||
|
return _super.call(this, guard, location, { index: index }) || this;
|
||||||
|
}
|
||||||
|
Object.defineProperty(PopNode.prototype, "placeholder", {
|
||||||
|
get: function () {
|
||||||
|
if (this.index === 0) {
|
||||||
|
return "$$";
|
||||||
|
}
|
||||||
|
return "$" + String(this.index);
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true
|
||||||
|
});
|
||||||
|
PopNode.from = function (options) {
|
||||||
|
return new PopNode(Guard, options.loc, options.index);
|
||||||
|
};
|
||||||
|
return PopNode;
|
||||||
|
}(ValueNode));
|
||||||
|
exports.PopNode = PopNode;
|
||||||
var LinkNode = /** @class */ (function (_super) {
|
var LinkNode = /** @class */ (function (_super) {
|
||||||
__extends(LinkNode, _super);
|
__extends(LinkNode, _super);
|
||||||
function LinkNode(guard, location, type, label) {
|
function LinkNode(guard, location, type, label) {
|
||||||
@ -295,32 +308,67 @@ var LinkNode = /** @class */ (function (_super) {
|
|||||||
}
|
}
|
||||||
LinkNode.prototype.assemble = function (assembler, visit) {
|
LinkNode.prototype.assemble = function (assembler, visit) {
|
||||||
return __awaiter(this, void 0, void 0, function () {
|
return __awaiter(this, void 0, void 0, function () {
|
||||||
var value, target, result;
|
var value, isOffset, target, result, here, opcodes, literal, w;
|
||||||
return __generator(this, function (_a) {
|
return __generator(this, function (_a) {
|
||||||
assembler.start(this);
|
assembler.start(this);
|
||||||
value = null;
|
value = null;
|
||||||
|
isOffset = false;
|
||||||
target = assembler.getTarget(this.label);
|
target = assembler.getTarget(this.label);
|
||||||
if (target instanceof LabelNode) {
|
if (target instanceof LabelNode) {
|
||||||
if (this.type === "offset") {
|
if (this.type === "offset") {
|
||||||
//value = assembler.getOffset(this.label);
|
|
||||||
value = (assembler.getLinkValue(target, this));
|
value = (assembler.getLinkValue(target, this));
|
||||||
|
isOffset = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = (assembler.getLinkValue(target, this));
|
result = (assembler.getLinkValue(target, this));
|
||||||
if (this.type === "offset") {
|
if (this.type === "offset") {
|
||||||
//value = assembler.getOffset(this.label);
|
|
||||||
value = result.offset;
|
value = result.offset;
|
||||||
|
isOffset = true;
|
||||||
}
|
}
|
||||||
else if (this.type === "length") {
|
else if (this.type === "length") {
|
||||||
//value = assembler.getLength(this.label);
|
|
||||||
value = result.length;
|
value = result.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
throw new Error("labels can only be targetted as offsets");
|
throw new Error("labels can only be targetted as offsets");
|
||||||
}
|
}
|
||||||
|
if (isOffset && assembler.positionIndependentCode) {
|
||||||
|
here = assembler.getOffset(this, this);
|
||||||
|
opcodes = [];
|
||||||
|
if (here > value) {
|
||||||
|
literal = "0x";
|
||||||
|
for (w = 1; w <= 5; w++) {
|
||||||
|
if (w > 4) {
|
||||||
|
throw new Error("jump too large!");
|
||||||
|
}
|
||||||
|
literal = pushLiteral(here - value + w);
|
||||||
|
if (ethers_1.ethers.utils.hexDataLength(literal) <= w) {
|
||||||
|
literal = ethers_1.ethers.utils.hexZeroPad(literal, w);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
opcodes.push(literal);
|
||||||
|
opcodes.push(opcodes_1.Opcode.from("PC"));
|
||||||
|
opcodes.push(opcodes_1.Opcode.from("SUB"));
|
||||||
|
// This also works, in case the above literal thing doesn't work out...
|
||||||
|
//opcodes.push(Opcode.from("PC"));
|
||||||
|
//opcodes.push(pushLiteral(-delta));
|
||||||
|
//opcodes.push(Opcode.from("SWAP1"));
|
||||||
|
//opcodes.push(Opcode.from("SUB"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Jump forwards; this is easy to calculate since we can
|
||||||
|
// do PC firat.
|
||||||
|
opcodes.push(opcodes_1.Opcode.from("PC"));
|
||||||
|
opcodes.push(pushLiteral(value - here));
|
||||||
|
opcodes.push(opcodes_1.Opcode.from("ADD"));
|
||||||
|
}
|
||||||
|
visit(this, hexConcat(opcodes));
|
||||||
|
}
|
||||||
|
else {
|
||||||
visit(this, pushLiteral(value));
|
visit(this, pushLiteral(value));
|
||||||
|
}
|
||||||
assembler.end(this);
|
assembler.end(this);
|
||||||
return [2 /*return*/];
|
return [2 /*return*/];
|
||||||
});
|
});
|
||||||
@ -335,12 +383,8 @@ var LinkNode = /** @class */ (function (_super) {
|
|||||||
exports.LinkNode = LinkNode;
|
exports.LinkNode = LinkNode;
|
||||||
var OpcodeNode = /** @class */ (function (_super) {
|
var OpcodeNode = /** @class */ (function (_super) {
|
||||||
__extends(OpcodeNode, _super);
|
__extends(OpcodeNode, _super);
|
||||||
function OpcodeNode(guard, location, opcode, operands) {
|
function OpcodeNode(guard, location, opcode, operands, instructional) {
|
||||||
var _this = _super.call(this, guard, location, { opcode: opcode, operands: operands }) || this;
|
return _super.call(this, guard, location, { instructional: instructional, opcode: opcode, operands: operands }) || this;
|
||||||
if (opcode.isPush()) {
|
|
||||||
_this.warnings.push("the PUSH opcode modifies program flow - use literals instead");
|
|
||||||
}
|
|
||||||
return _this;
|
|
||||||
}
|
}
|
||||||
OpcodeNode.prototype.assemble = function (assembler, visit) {
|
OpcodeNode.prototype.assemble = function (assembler, visit) {
|
||||||
return __awaiter(this, void 0, void 0, function () {
|
return __awaiter(this, void 0, void 0, function () {
|
||||||
@ -386,23 +430,14 @@ var OpcodeNode = /** @class */ (function (_super) {
|
|||||||
if (!opcode) {
|
if (!opcode) {
|
||||||
throw new Error("unknown opcode: " + options.mnemonic);
|
throw new Error("unknown opcode: " + options.mnemonic);
|
||||||
}
|
}
|
||||||
// Using the function syntax will check the operand count
|
|
||||||
if (!options.bare) {
|
|
||||||
if (opcode.mnemonic === "POP" && options.operands.length === 0) {
|
|
||||||
// This is ok... Pop has a delta of 0, but without operands
|
|
||||||
}
|
|
||||||
else if (options.operands.length !== opcode.delta) {
|
|
||||||
throw new Error("opcode " + opcode.mnemonic + " expects " + opcode.delta + " operands");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var operands = Object.freeze(options.operands.map(function (o) {
|
var operands = Object.freeze(options.operands.map(function (o) {
|
||||||
var operand = Node.from(o);
|
var operand = Node.from(o);
|
||||||
if (!(operand instanceof ValueNode)) {
|
if (!(operand instanceof ValueNode)) {
|
||||||
throw new Error("invalid operand");
|
throw new Error("bad grammar?!");
|
||||||
}
|
}
|
||||||
return operand;
|
return operand;
|
||||||
}));
|
}));
|
||||||
return new OpcodeNode(Guard, options.loc, opcode, operands);
|
return new OpcodeNode(Guard, options.loc, opcode, operands, !!options.bare);
|
||||||
};
|
};
|
||||||
return OpcodeNode;
|
return OpcodeNode;
|
||||||
}(ValueNode));
|
}(ValueNode));
|
||||||
@ -469,7 +504,7 @@ var DataNode = /** @class */ (function (_super) {
|
|||||||
i_1++;
|
i_1++;
|
||||||
return [3 /*break*/, 1];
|
return [3 /*break*/, 1];
|
||||||
case 4:
|
case 4:
|
||||||
bytecode = ethers_1.ethers.utils.arrayify(assembler.getPendingBytecode(this));
|
bytecode = ethers_1.ethers.utils.arrayify(assembler.getBytecode(this));
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < bytecode.length) {
|
while (i < bytecode.length) {
|
||||||
opcode = opcodes_1.Opcode.from(bytecode[i++]);
|
opcode = opcodes_1.Opcode.from(bytecode[i++]);
|
||||||
@ -491,12 +526,6 @@ var DataNode = /** @class */ (function (_super) {
|
|||||||
DataNode.prototype.children = function () {
|
DataNode.prototype.children = function () {
|
||||||
return this.data;
|
return this.data;
|
||||||
};
|
};
|
||||||
DataNode.prototype.visit = function (visit) {
|
|
||||||
visit(this);
|
|
||||||
for (var i = 0; i < this.data.length; i++) {
|
|
||||||
this.data[i].visit(visit);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
DataNode.from = function (options) {
|
DataNode.from = function (options) {
|
||||||
if (options.type !== "data") {
|
if (options.type !== "data") {
|
||||||
throw new Error("expected data type");
|
throw new Error("expected data type");
|
||||||
@ -610,12 +639,6 @@ var ScopeNode = /** @class */ (function (_super) {
|
|||||||
ScopeNode.prototype.children = function () {
|
ScopeNode.prototype.children = function () {
|
||||||
return this.statements;
|
return this.statements;
|
||||||
};
|
};
|
||||||
ScopeNode.prototype.visit = function (visit) {
|
|
||||||
visit(this);
|
|
||||||
for (var i = 0; i < this.statements.length; i++) {
|
|
||||||
this.statements[i].visit(visit);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ScopeNode.from = function (options) {
|
ScopeNode.from = function (options) {
|
||||||
if (options.type !== "scope") {
|
if (options.type !== "scope") {
|
||||||
throw new Error("expected scope type");
|
throw new Error("expected scope type");
|
||||||
@ -625,57 +648,6 @@ var ScopeNode = /** @class */ (function (_super) {
|
|||||||
return ScopeNode;
|
return ScopeNode;
|
||||||
}(LabelledNode));
|
}(LabelledNode));
|
||||||
exports.ScopeNode = ScopeNode;
|
exports.ScopeNode = ScopeNode;
|
||||||
function parse(code) {
|
|
||||||
// Since jison allows \n, \r or \r\n line endings, we need some
|
|
||||||
// twekaing to get the correct position
|
|
||||||
var lines = [];
|
|
||||||
var offset = 0;
|
|
||||||
code.split(/(\r\n?|\n)/g).forEach(function (clump, index) {
|
|
||||||
if (index % 2) {
|
|
||||||
lines[lines.length - 1].line += clump;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
lines.push({ line: clump, offset: offset });
|
|
||||||
}
|
|
||||||
offset += clump.length;
|
|
||||||
});
|
|
||||||
// Add a mock-EOF to the end of the file so we don't out-of-bounds
|
|
||||||
// on the last character
|
|
||||||
if (lines.length) {
|
|
||||||
lines[lines.length - 1].line += "\n";
|
|
||||||
}
|
|
||||||
// Givens a line (1 offset) and column (0 offset) return the byte offset
|
|
||||||
var getOffset = function (line, column) {
|
|
||||||
var info = lines[line - 1];
|
|
||||||
if (!info || column >= info.line.length) {
|
|
||||||
throw new Error("out of range");
|
|
||||||
}
|
|
||||||
return info.offset + column;
|
|
||||||
};
|
|
||||||
// We use this in the _parser to convert locations to source
|
|
||||||
_parser_1.parser.yy._ethersLocation = function (loc) {
|
|
||||||
// The _ scope should call with null to get the full source
|
|
||||||
if (loc == null) {
|
|
||||||
return Object.freeze({
|
|
||||||
offset: 0,
|
|
||||||
length: code.length,
|
|
||||||
source: code
|
|
||||||
});
|
|
||||||
}
|
|
||||||
var offset = getOffset(loc.first_line, loc.first_column);
|
|
||||||
var end = getOffset(loc.last_line, loc.last_column);
|
|
||||||
return Object.freeze({
|
|
||||||
offset: offset,
|
|
||||||
length: (end - offset),
|
|
||||||
source: code.substring(offset, end)
|
|
||||||
});
|
|
||||||
};
|
|
||||||
var result = Node.from(_parser_1.parse(code));
|
|
||||||
// Nuke the source code lookup callback
|
|
||||||
_parser_1.parser.yy._ethersLocation = null;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
exports.parse = parse;
|
|
||||||
function disassemble(bytecode) {
|
function disassemble(bytecode) {
|
||||||
var ops = [];
|
var ops = [];
|
||||||
var offsets = {};
|
var offsets = {};
|
||||||
@ -741,14 +713,10 @@ function formatBytecode(bytecode) {
|
|||||||
return lines.join("\n");
|
return lines.join("\n");
|
||||||
}
|
}
|
||||||
exports.formatBytecode = formatBytecode;
|
exports.formatBytecode = formatBytecode;
|
||||||
// @TODO: Rename to Assembler?
|
|
||||||
var Assembler = /** @class */ (function () {
|
var Assembler = /** @class */ (function () {
|
||||||
function Assembler(root, options) {
|
function Assembler(root, positionIndependentCode) {
|
||||||
ethers_1.ethers.utils.defineReadOnly(this, "positionIndependentCode", !!options.positionIndependentCode);
|
|
||||||
ethers_1.ethers.utils.defineReadOnly(this, "retry", ((options.retry != null) ? options.retry : 512));
|
|
||||||
ethers_1.ethers.utils.defineReadOnly(this, "filename", path_1.resolve(options.filename || "./contract.asm"));
|
|
||||||
ethers_1.ethers.utils.defineReadOnly(this, "defines", Object.freeze(options.defines || {}));
|
|
||||||
ethers_1.ethers.utils.defineReadOnly(this, "root", root);
|
ethers_1.ethers.utils.defineReadOnly(this, "root", root);
|
||||||
|
ethers_1.ethers.utils.defineReadOnly(this, "positionIndependentCode", !!positionIndependentCode);
|
||||||
var nodes = {};
|
var nodes = {};
|
||||||
var labels = {};
|
var labels = {};
|
||||||
var parents = {};
|
var parents = {};
|
||||||
@ -757,8 +725,7 @@ var Assembler = /** @class */ (function () {
|
|||||||
nodes[node.tag] = {
|
nodes[node.tag] = {
|
||||||
node: node,
|
node: node,
|
||||||
offset: 0x0,
|
offset: 0x0,
|
||||||
bytecode: "0x",
|
bytecode: "0x"
|
||||||
pending: "0x"
|
|
||||||
};
|
};
|
||||||
if (node instanceof LabelledNode) {
|
if (node instanceof LabelledNode) {
|
||||||
// Check for duplicate labels
|
// Check for duplicate labels
|
||||||
@ -784,58 +751,14 @@ var Assembler = /** @class */ (function () {
|
|||||||
ethers_1.ethers.utils.defineReadOnly(this, "labels", Object.freeze(labels));
|
ethers_1.ethers.utils.defineReadOnly(this, "labels", Object.freeze(labels));
|
||||||
ethers_1.ethers.utils.defineReadOnly(this, "nodes", Object.freeze(nodes));
|
ethers_1.ethers.utils.defineReadOnly(this, "nodes", Object.freeze(nodes));
|
||||||
ethers_1.ethers.utils.defineReadOnly(this, "_parents", Object.freeze(parents));
|
ethers_1.ethers.utils.defineReadOnly(this, "_parents", Object.freeze(parents));
|
||||||
ethers_1.ethers.utils.defineReadOnly(this, "_stack", []);
|
|
||||||
this.reset();
|
|
||||||
}
|
}
|
||||||
Object.defineProperty(Assembler.prototype, "changed", {
|
|
||||||
get: function () {
|
|
||||||
return this._changed;
|
|
||||||
},
|
|
||||||
enumerable: true,
|
|
||||||
configurable: true
|
|
||||||
});
|
|
||||||
// Link operations
|
// Link operations
|
||||||
Assembler.prototype.getTarget = function (name) {
|
Assembler.prototype.getTarget = function (label) {
|
||||||
return this.labels[name];
|
return this.labels[label];
|
||||||
};
|
|
||||||
// Reset the assmebler for another run with updated values
|
|
||||||
Assembler.prototype.reset = function () {
|
|
||||||
var _this = this;
|
|
||||||
this._changed = false;
|
|
||||||
for (var tag in this.nodes) {
|
|
||||||
delete this.nodes[tag].object;
|
|
||||||
}
|
|
||||||
this._script = new Script(this.filename, function (name, context) {
|
|
||||||
return _this.get(name, context);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
// Evaluate script in the context of a {{! }} or {{= }}
|
||||||
Assembler.prototype.evaluate = function (script, source) {
|
Assembler.prototype.evaluate = function (script, source) {
|
||||||
return this._script.evaluate(script, source);
|
return Promise.resolve(new Uint8Array(0));
|
||||||
};
|
|
||||||
Assembler.prototype.start = function (node) {
|
|
||||||
this._stack.push(node);
|
|
||||||
var info = this.nodes[node.tag];
|
|
||||||
info.pending = "0x";
|
|
||||||
};
|
|
||||||
Assembler.prototype.end = function (node) {
|
|
||||||
if (this._stack.pop() !== node) {
|
|
||||||
throw new Error("missing push/pop pair");
|
|
||||||
}
|
|
||||||
var info = this.nodes[node.tag];
|
|
||||||
if (info.pending !== info.bytecode) {
|
|
||||||
this._didChange();
|
|
||||||
}
|
|
||||||
info.bytecode = info.pending;
|
|
||||||
};
|
|
||||||
Assembler.prototype.getPendingBytecode = function (node) {
|
|
||||||
return this.nodes[node.tag].pending;
|
|
||||||
};
|
|
||||||
Assembler.prototype._appendBytecode = function (bytecode) {
|
|
||||||
var _this = this;
|
|
||||||
this._stack.forEach(function (node) {
|
|
||||||
var info = _this.nodes[node.tag];
|
|
||||||
info.pending = hexConcat([info.pending, bytecode]);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
Assembler.prototype.getAncestor = function (node, cls) {
|
Assembler.prototype.getAncestor = function (node, cls) {
|
||||||
node = this._parents[node.tag];
|
node = this._parents[node.tag];
|
||||||
@ -847,6 +770,23 @@ var Assembler = /** @class */ (function () {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
Assembler.prototype.getOffset = function (node, source) {
|
||||||
|
var offset = this.nodes[node.tag].offset;
|
||||||
|
if (source == null) {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
var sourceScope = ((source instanceof ScopeNode) ? source : this.getAncestor(source, ScopeNode));
|
||||||
|
return offset - this.nodes[sourceScope.tag].offset;
|
||||||
|
};
|
||||||
|
Assembler.prototype.setOffset = function (node, offset) {
|
||||||
|
this.nodes[node.tag].offset = offset;
|
||||||
|
};
|
||||||
|
Assembler.prototype.getBytecode = function (node) {
|
||||||
|
return this.nodes[node.tag].bytecode;
|
||||||
|
};
|
||||||
|
Assembler.prototype.setBytecode = function (node, bytecode) {
|
||||||
|
this.nodes[node.tag].bytecode = bytecode;
|
||||||
|
};
|
||||||
Assembler.prototype.getLinkValue = function (target, source) {
|
Assembler.prototype.getLinkValue = function (target, source) {
|
||||||
var sourceScope = ((source instanceof ScopeNode) ? source : this.getAncestor(source, ScopeNode));
|
var sourceScope = ((source instanceof ScopeNode) ? source : this.getAncestor(source, ScopeNode));
|
||||||
var targetScope = ((target instanceof ScopeNode) ? target : this.getAncestor(target, ScopeNode));
|
var targetScope = ((target instanceof ScopeNode) ? target : this.getAncestor(target, ScopeNode));
|
||||||
@ -857,13 +797,7 @@ var Assembler = /** @class */ (function () {
|
|||||||
throw new Error("cannot access " + target.name + " from " + source.tag);
|
throw new Error("cannot access " + target.name + " from " + source.tag);
|
||||||
}
|
}
|
||||||
// Return the offset relative to its scope
|
// Return the offset relative to its scope
|
||||||
var offset = this.nodes[target.tag].offset - this.nodes[targetScope.tag].offset;
|
return this.nodes[target.tag].offset - this.nodes[targetScope.tag].offset;
|
||||||
// Offsets are wrong; but we should finish this run and then try again
|
|
||||||
if (offset < 0) {
|
|
||||||
offset = 0;
|
|
||||||
this._didChange();
|
|
||||||
}
|
|
||||||
return offset;
|
|
||||||
}
|
}
|
||||||
var info = this.nodes[target.tag];
|
var info = this.nodes[target.tag];
|
||||||
// Return the offset is relative to its scope
|
// Return the offset is relative to its scope
|
||||||
@ -892,15 +826,224 @@ var Assembler = /** @class */ (function () {
|
|||||||
// been marked as invalid, in which case accessing it will fail
|
// been marked as invalid, in which case accessing it will fail
|
||||||
if (safeOffset) {
|
if (safeOffset) {
|
||||||
bytes.offset = info.offset - this.nodes[sourceScope.tag].offset;
|
bytes.offset = info.offset - this.nodes[sourceScope.tag].offset;
|
||||||
// Offsets are wqrong; but we should finish this run and then try again
|
}
|
||||||
if (bytes.offset < 0) {
|
return bytes;
|
||||||
bytes.offset = 0;
|
};
|
||||||
|
Assembler.prototype.start = function (node) { };
|
||||||
|
Assembler.prototype.end = function (node) { };
|
||||||
|
return Assembler;
|
||||||
|
}());
|
||||||
|
var SemanticErrorSeverity;
|
||||||
|
(function (SemanticErrorSeverity) {
|
||||||
|
SemanticErrorSeverity["error"] = "error";
|
||||||
|
SemanticErrorSeverity["warning"] = "warning";
|
||||||
|
})(SemanticErrorSeverity = exports.SemanticErrorSeverity || (exports.SemanticErrorSeverity = {}));
|
||||||
|
;
|
||||||
|
// This Assembler is designed to only check for errors and warnings
|
||||||
|
// Warnings
|
||||||
|
// - Bare PUSH opcodes
|
||||||
|
// - Instructional opcode that has parameters
|
||||||
|
// Errors
|
||||||
|
// - Using a $$ outside of RPN
|
||||||
|
// - Using a $$ when it is not adjacent to the stack
|
||||||
|
// - The operand count does not match the opcode
|
||||||
|
// - An opcode is used as an operand but does not return a value
|
||||||
|
var SemanticChecker = /** @class */ (function (_super) {
|
||||||
|
__extends(SemanticChecker, _super);
|
||||||
|
function SemanticChecker() {
|
||||||
|
return _super !== null && _super.apply(this, arguments) || this;
|
||||||
|
}
|
||||||
|
SemanticChecker.prototype.check = function () {
|
||||||
|
var _this = this;
|
||||||
|
var errors = [];
|
||||||
|
this.root.visit(function (node) {
|
||||||
|
if (node instanceof OpcodeNode) {
|
||||||
|
var opcode = node.opcode;
|
||||||
|
if (node.instructional) {
|
||||||
|
if (opcode.delta) {
|
||||||
|
errors.push({
|
||||||
|
message: opcode.mnemonic + " used as instructional",
|
||||||
|
severity: SemanticErrorSeverity.warning,
|
||||||
|
node: node
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (opcode.mnemonic === "POP") {
|
||||||
|
if (node.operands.length !== 0) {
|
||||||
|
errors.push({
|
||||||
|
message: "POP expects 0 operands",
|
||||||
|
severity: SemanticErrorSeverity.error,
|
||||||
|
node: node
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (node.operands.length !== opcode.delta) {
|
||||||
|
errors.push({
|
||||||
|
message: opcode.mnemonic + " expects " + opcode.delta + " operands",
|
||||||
|
severity: SemanticErrorSeverity.error,
|
||||||
|
node: node
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (opcode.isPush()) {
|
||||||
|
// A stray PUSH operation will gobble up the following code
|
||||||
|
// bytes which is bad. But this may be a disassembled program
|
||||||
|
// and that PUSH may actually be just some data (which is safe)
|
||||||
|
errors.push({
|
||||||
|
message: "PUSH opcode modifies program flow - use literals instead",
|
||||||
|
severity: SemanticErrorSeverity.warning,
|
||||||
|
node: node
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (!node.location.statement && opcode.alpha !== 1) {
|
||||||
|
// If an opcode does not push anything on the stack, it
|
||||||
|
// cannot be used as an operand
|
||||||
|
errors.push({
|
||||||
|
message: node.opcode.mnemonic + " cannot be an operand",
|
||||||
|
severity: SemanticErrorSeverity.error,
|
||||||
|
node: node
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node.location.statement) {
|
||||||
|
if (node instanceof PopNode) {
|
||||||
|
// $$ by istelf is useless and is intended to be an operand
|
||||||
|
errors.push({
|
||||||
|
message: "$$ must be an operand",
|
||||||
|
severity: SemanticErrorSeverity.error,
|
||||||
|
node: node
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var scope_1 = _this.getAncestor(node, ScopeNode);
|
||||||
|
// Make sure any $$ is stack adjacent (within this scope)
|
||||||
|
var ordered_1 = [];
|
||||||
|
node.visit(function (node) {
|
||||||
|
if (scope_1 !== _this.getAncestor(node, ScopeNode)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ordered_1.push(node);
|
||||||
|
});
|
||||||
|
// Allow any number of stack adjacent $$
|
||||||
|
var foundZero = null;
|
||||||
|
var lastIndex = 0;
|
||||||
|
while (ordered_1.length && ordered_1[0] instanceof PopNode) {
|
||||||
|
var popNode = (ordered_1.shift());
|
||||||
|
var index = popNode.index;
|
||||||
|
if (index === 0) {
|
||||||
|
foundZero = popNode;
|
||||||
|
}
|
||||||
|
else if (index !== lastIndex + 1) {
|
||||||
|
errors.push({
|
||||||
|
message: "out-of-order stack placeholder " + popNode.placeholder + "; expected $$" + (lastIndex + 1),
|
||||||
|
severity: SemanticErrorSeverity.error,
|
||||||
|
node: popNode
|
||||||
|
});
|
||||||
|
while (ordered_1.length && ordered_1[0] instanceof PopNode) {
|
||||||
|
ordered_1.shift();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lastIndex = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (foundZero && lastIndex > 0) {
|
||||||
|
errors.push({
|
||||||
|
message: "cannot mix $$ and $1 stack placeholder",
|
||||||
|
severity: SemanticErrorSeverity.error,
|
||||||
|
node: foundZero
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// If there are still any buried, we have a problem
|
||||||
|
var pops = ordered_1.filter(function (n) { return (n instanceof PopNode); });
|
||||||
|
if (pops.length) {
|
||||||
|
errors.push({
|
||||||
|
message: "stack placeholder " + (pops[0]).placeholder + " must be stack adjacent",
|
||||||
|
severity: SemanticErrorSeverity.error,
|
||||||
|
node: pops[0]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return errors;
|
||||||
|
};
|
||||||
|
return SemanticChecker;
|
||||||
|
}(Assembler));
|
||||||
|
var CodeGenerationAssembler = /** @class */ (function (_super) {
|
||||||
|
__extends(CodeGenerationAssembler, _super);
|
||||||
|
function CodeGenerationAssembler(root, options) {
|
||||||
|
var _this = _super.call(this, root, !!options.positionIndependentCode) || this;
|
||||||
|
ethers_1.ethers.utils.defineReadOnly(_this, "retry", ((options.retry != null) ? options.retry : 512));
|
||||||
|
ethers_1.ethers.utils.defineReadOnly(_this, "filename", path_1.resolve(options.filename || "./contract.asm"));
|
||||||
|
ethers_1.ethers.utils.defineReadOnly(_this, "defines", Object.freeze(options.defines || {}));
|
||||||
|
ethers_1.ethers.utils.defineReadOnly(_this, "_stack", []);
|
||||||
|
_this.reset();
|
||||||
|
return _this;
|
||||||
|
}
|
||||||
|
CodeGenerationAssembler.prototype._didChange = function () {
|
||||||
|
this._changed = true;
|
||||||
|
};
|
||||||
|
Object.defineProperty(CodeGenerationAssembler.prototype, "changed", {
|
||||||
|
get: function () {
|
||||||
|
return this._changed;
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true
|
||||||
|
});
|
||||||
|
// Reset the assmebler for another run with updated values
|
||||||
|
CodeGenerationAssembler.prototype.reset = function () {
|
||||||
|
var _this = this;
|
||||||
|
this._changed = false;
|
||||||
|
this._oldBytecode = {};
|
||||||
|
this._objectCache = {};
|
||||||
|
this._script = new Script(this.filename, function (name, context) {
|
||||||
|
return _this.get(name, context);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
CodeGenerationAssembler.prototype.evaluate = function (script, source) {
|
||||||
|
return this._script.evaluate(script, source);
|
||||||
|
};
|
||||||
|
CodeGenerationAssembler.prototype.getLinkValue = function (target, source) {
|
||||||
|
// Since we are iteratively generating code, offsets and lengths
|
||||||
|
// may not be stable at any given point in time, so if an offset
|
||||||
|
// is negative the code is obviously wrong, however we set it to
|
||||||
|
// 0 so we can proceed with generation to fill in as many blanks
|
||||||
|
// as possible; then we will try assembling again
|
||||||
|
var result = _super.prototype.getLinkValue.call(this, target, source);
|
||||||
|
if (typeof (result) === "number") {
|
||||||
|
if (result < 0) {
|
||||||
|
this._didChange();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (result.offset < 0) {
|
||||||
|
result.offset = 0;
|
||||||
this._didChange();
|
this._didChange();
|
||||||
}
|
}
|
||||||
}
|
return result;
|
||||||
return Object.freeze(bytes);
|
|
||||||
};
|
};
|
||||||
Assembler.prototype.get = function (name, source) {
|
CodeGenerationAssembler.prototype.start = function (node) {
|
||||||
|
this._stack.push(node);
|
||||||
|
this._oldBytecode[node.tag] = this.getBytecode(node);
|
||||||
|
this.setBytecode(node, "0x");
|
||||||
|
};
|
||||||
|
CodeGenerationAssembler.prototype.end = function (node) {
|
||||||
|
if (this._stack.pop() !== node) {
|
||||||
|
throw new Error("missing push/pop pair");
|
||||||
|
}
|
||||||
|
if (this._oldBytecode[node.tag] !== this.getBytecode(node)) {
|
||||||
|
this._didChange();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// This is used by evaluate to access properties in JavaScript
|
||||||
|
// - "defines" allow meta-programming values to be used
|
||||||
|
// - jump destinations are available as numbers
|
||||||
|
// - bytecode and data are available as an immuatble DataSource
|
||||||
|
CodeGenerationAssembler.prototype.get = function (name, source) {
|
||||||
if (name === "defines") {
|
if (name === "defines") {
|
||||||
return this.defines;
|
return this.defines;
|
||||||
}
|
}
|
||||||
@ -908,55 +1051,67 @@ var Assembler = /** @class */ (function () {
|
|||||||
if (!node) {
|
if (!node) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
var info = this.nodes[node.tag];
|
// We cache objects when they are generated so all nodes
|
||||||
if (info.object == null) {
|
// receive consistent data; if there is a change we will
|
||||||
info.object = this.getLinkValue(node, source);
|
// run the entire assembly process again with the updated
|
||||||
|
// values
|
||||||
|
if (this._objectCache[node.tag] == null) {
|
||||||
|
this._objectCache[node.tag] = Object.freeze(this.getLinkValue(node, source));
|
||||||
}
|
}
|
||||||
return info.object;
|
return this._objectCache[node.tag];
|
||||||
};
|
};
|
||||||
Assembler.prototype._didChange = function () {
|
CodeGenerationAssembler.prototype._assemble = function () {
|
||||||
this._changed = true;
|
|
||||||
};
|
|
||||||
Assembler.prototype._assemble = function () {
|
|
||||||
return __awaiter(this, void 0, void 0, function () {
|
return __awaiter(this, void 0, void 0, function () {
|
||||||
var offset, bytecodes;
|
var offset;
|
||||||
var _this = this;
|
var _this = this;
|
||||||
return __generator(this, function (_a) {
|
return __generator(this, function (_a) {
|
||||||
switch (_a.label) {
|
switch (_a.label) {
|
||||||
case 0:
|
case 0:
|
||||||
offset = 0;
|
offset = 0;
|
||||||
bytecodes = [];
|
|
||||||
return [4 /*yield*/, this.root.assemble(this, function (node, bytecode) {
|
return [4 /*yield*/, this.root.assemble(this, function (node, bytecode) {
|
||||||
var state = _this.nodes[node.tag];
|
|
||||||
// Things have moved; we will need to try again
|
// Things have moved; we will need to try again
|
||||||
if (state.offset !== offset) {
|
if (_this.getOffset(node) !== offset) {
|
||||||
state.offset = offset;
|
_this.setOffset(node, offset);
|
||||||
_this._didChange();
|
_this._didChange();
|
||||||
}
|
}
|
||||||
_this._appendBytecode(bytecode);
|
_this._stack.forEach(function (node) {
|
||||||
bytecodes.push(bytecode);
|
_this.setBytecode(node, hexConcat([
|
||||||
// The bytecode has changed; we will need to try again
|
_this.getBytecode(node),
|
||||||
//if (state.bytecode !== bytecode) {
|
bytecode
|
||||||
// state.bytecode = bytecode;
|
]));
|
||||||
// this._didChange();
|
});
|
||||||
//}
|
|
||||||
offset += ethers_1.ethers.utils.hexDataLength(bytecode);
|
offset += ethers_1.ethers.utils.hexDataLength(bytecode);
|
||||||
})];
|
})];
|
||||||
case 1:
|
case 1:
|
||||||
_a.sent();
|
_a.sent();
|
||||||
return [2 /*return*/, hexConcat(bytecodes)];
|
return [2 /*return*/];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
Assembler.prototype.assemble = function () {
|
CodeGenerationAssembler.prototype.assemble = function (label) {
|
||||||
return __awaiter(this, void 0, void 0, function () {
|
return __awaiter(this, void 0, void 0, function () {
|
||||||
var bytecode, i, adjusted;
|
var target, i;
|
||||||
return __generator(this, function (_a) {
|
return __generator(this, function (_a) {
|
||||||
switch (_a.label) {
|
switch (_a.label) {
|
||||||
case 0: return [4 /*yield*/, this._assemble()];
|
case 0:
|
||||||
|
if (label == null) {
|
||||||
|
label = "_";
|
||||||
|
}
|
||||||
|
target = this.getTarget(label);
|
||||||
|
if (!target) {
|
||||||
|
logger.throwArgumentError("unknown labelled target: " + label, "label", label);
|
||||||
|
}
|
||||||
|
else if (!(target instanceof ScopeNode || target instanceof DataNode)) {
|
||||||
|
logger.throwArgumentError("cannot assemble a bodyless label: " + label, "label", label);
|
||||||
|
}
|
||||||
|
// Continue re-evaluating the bytecode until a stable set of
|
||||||
|
// offsets, length and values are reached.
|
||||||
|
return [4 /*yield*/, this._assemble()];
|
||||||
case 1:
|
case 1:
|
||||||
bytecode = _a.sent();
|
// Continue re-evaluating the bytecode until a stable set of
|
||||||
|
// offsets, length and values are reached.
|
||||||
|
_a.sent();
|
||||||
i = 0;
|
i = 0;
|
||||||
_a.label = 2;
|
_a.label = 2;
|
||||||
case 2:
|
case 2:
|
||||||
@ -965,37 +1120,101 @@ var Assembler = /** @class */ (function () {
|
|||||||
this.reset();
|
this.reset();
|
||||||
return [4 /*yield*/, this._assemble()];
|
return [4 /*yield*/, this._assemble()];
|
||||||
case 3:
|
case 3:
|
||||||
adjusted = _a.sent();
|
_a.sent();
|
||||||
// Generated bytecode is stable!! :)
|
// Generated bytecode is stable!! :)
|
||||||
if (!this.changed) {
|
if (!this.changed) {
|
||||||
console.log("Assembled in " + i + " attempts");
|
// This should not happen; something is wrong with the grammar
|
||||||
return [2 /*return*/, bytecode];
|
// or missing enter/exit call in assemble
|
||||||
|
if (this._stack.length !== 0) {
|
||||||
|
throw new Error("Bad AST! Bad grammar?!");
|
||||||
|
}
|
||||||
|
//console.log(`Assembled in ${ i } attempts`);
|
||||||
|
return [2 /*return*/, this.getBytecode(target)];
|
||||||
|
;
|
||||||
}
|
}
|
||||||
// Try again...
|
|
||||||
bytecode = adjusted;
|
|
||||||
_a.label = 4;
|
_a.label = 4;
|
||||||
case 4:
|
case 4:
|
||||||
i++;
|
i++;
|
||||||
return [3 /*break*/, 2];
|
return [3 /*break*/, 2];
|
||||||
case 5:
|
case 5: return [2 /*return*/, logger.throwError("unable to assemble; " + this.retry + " attempts failed to generate stable bytecode", ethers_1.ethers.utils.Logger.errors.UNKNOWN_ERROR, {})];
|
||||||
// This should not happen; something is wrong with the grammar
|
|
||||||
// or missing enter/exit call in assemble
|
|
||||||
if (this._stack.length !== 0) {
|
|
||||||
throw new Error("bad AST");
|
|
||||||
}
|
|
||||||
return [2 /*return*/, logger.throwError("unable to assemble; " + this.retry + " attempts failed to generate stable bytecode", ethers_1.ethers.utils.Logger.errors.UNKNOWN_ERROR, {})];
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
return Assembler;
|
return CodeGenerationAssembler;
|
||||||
}());
|
}(Assembler));
|
||||||
|
function parse(code, options) {
|
||||||
|
if (options == null) {
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
// Since jison allows \n, \r or \r\n line endings, we need some
|
||||||
|
// twekaing to get the correct position
|
||||||
|
var lines = [];
|
||||||
|
var offset = 0;
|
||||||
|
code.split(/(\r\n?|\n)/g).forEach(function (clump, index) {
|
||||||
|
if (index % 2) {
|
||||||
|
lines[lines.length - 1].line += clump;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lines.push({ line: clump, offset: offset });
|
||||||
|
}
|
||||||
|
offset += clump.length;
|
||||||
|
});
|
||||||
|
// Add a mock-EOF to the end of the file so we don't out-of-bounds
|
||||||
|
// on the last character
|
||||||
|
if (lines.length) {
|
||||||
|
lines[lines.length - 1].line += "\n";
|
||||||
|
}
|
||||||
|
// Givens a line (1 offset) and column (0 offset) return the byte offset
|
||||||
|
var getOffset = function (line, column) {
|
||||||
|
var info = lines[line - 1];
|
||||||
|
if (!info || column >= info.line.length) {
|
||||||
|
throw new Error("out of range");
|
||||||
|
}
|
||||||
|
return info.offset + column;
|
||||||
|
};
|
||||||
|
// We use this in the _parser to convert locations to source
|
||||||
|
_parser_1.parser.yy._ethersLocation = function (loc) {
|
||||||
|
// The _ scope should call with null to get the full source
|
||||||
|
if (loc == null) {
|
||||||
|
return {
|
||||||
|
offset: 0,
|
||||||
|
line: 0,
|
||||||
|
length: code.length,
|
||||||
|
source: code,
|
||||||
|
statement: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var offset = getOffset(loc.first_line, loc.first_column);
|
||||||
|
var end = getOffset(loc.last_line, loc.last_column);
|
||||||
|
return {
|
||||||
|
offset: offset,
|
||||||
|
line: loc.first_line - 1,
|
||||||
|
length: (end - offset),
|
||||||
|
source: code.substring(offset, end),
|
||||||
|
statement: (!!loc.statement)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
var result = Node.from(_parser_1.parse(code));
|
||||||
|
// Nuke the source code lookup callback
|
||||||
|
_parser_1.parser.yy._ethersLocation = null;
|
||||||
|
// Semantic Checks
|
||||||
|
var checker = new SemanticChecker(result);
|
||||||
|
var errors = checker.check();
|
||||||
|
if (errors.filter(function (e) { return (e.severity === SemanticErrorSeverity.error); }).length || (errors.length && !options.ignoreWarnings)) {
|
||||||
|
var error = new Error("semantic errors during parsing");
|
||||||
|
error.errors = errors;
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
exports.parse = parse;
|
||||||
function assemble(ast, options) {
|
function assemble(ast, options) {
|
||||||
return __awaiter(this, void 0, void 0, function () {
|
return __awaiter(this, void 0, void 0, function () {
|
||||||
var assembler;
|
var assembler;
|
||||||
return __generator(this, function (_a) {
|
return __generator(this, function (_a) {
|
||||||
assembler = new Assembler(ast, options || {});
|
assembler = new CodeGenerationAssembler(ast, options || {});
|
||||||
return [2 /*return*/, assembler.assemble()];
|
return [2 /*return*/, assembler.assemble(options.target || "_")];
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
6
packages/asm/lib/index.d.ts
vendored
6
packages/asm/lib/index.d.ts
vendored
@ -1,4 +1,4 @@
|
|||||||
import { assemble, DataNode, disassemble, EvaluationNode, ExecutionNode, formatBytecode, LabelNode, LabelledNode, LinkNode, LiteralNode, Node, OpcodeNode, parse, ScopeNode, ValueNode } from "./assembler";
|
import { assemble, DataNode, disassemble, EvaluationNode, ExecutionNode, formatBytecode, LabelNode, LabelledNode, LinkNode, LiteralNode, Node, OpcodeNode, parse, PopNode, ScopeNode, ValueNode } from "./assembler";
|
||||||
import { Opcode } from "./opcodes";
|
import { Opcode } from "./opcodes";
|
||||||
import { AssemblerOptions, AssembleVisitFunc, Bytecode, Location, Operation, VisitFunc } from "./assembler";
|
import { AssemblerOptions, AssembleVisitFunc, Bytecode, Location, Operation, ParserOptions, SemanticError, SemanticErrorSeverity, VisitFunc } from "./assembler";
|
||||||
export { Opcode, assemble, disassemble, formatBytecode, parse, DataNode, EvaluationNode, ExecutionNode, LabelNode, LabelledNode, LinkNode, LiteralNode, Node, OpcodeNode, ScopeNode, ValueNode, AssemblerOptions, AssembleVisitFunc, Bytecode, Location, Operation, VisitFunc, };
|
export { Opcode, assemble, disassemble, formatBytecode, parse, DataNode, EvaluationNode, ExecutionNode, LabelNode, LabelledNode, LinkNode, LiteralNode, Node, OpcodeNode, PopNode, ScopeNode, ValueNode, AssemblerOptions, AssembleVisitFunc, Bytecode, Location, Operation, SemanticError, SemanticErrorSeverity, ParserOptions, VisitFunc, };
|
||||||
|
@ -14,7 +14,10 @@ exports.LiteralNode = assembler_1.LiteralNode;
|
|||||||
exports.Node = assembler_1.Node;
|
exports.Node = assembler_1.Node;
|
||||||
exports.OpcodeNode = assembler_1.OpcodeNode;
|
exports.OpcodeNode = assembler_1.OpcodeNode;
|
||||||
exports.parse = assembler_1.parse;
|
exports.parse = assembler_1.parse;
|
||||||
|
exports.PopNode = assembler_1.PopNode;
|
||||||
exports.ScopeNode = assembler_1.ScopeNode;
|
exports.ScopeNode = assembler_1.ScopeNode;
|
||||||
exports.ValueNode = assembler_1.ValueNode;
|
exports.ValueNode = assembler_1.ValueNode;
|
||||||
var opcodes_1 = require("./opcodes");
|
var opcodes_1 = require("./opcodes");
|
||||||
exports.Opcode = opcodes_1.Opcode;
|
exports.Opcode = opcodes_1.Opcode;
|
||||||
|
var assembler_2 = require("./assembler");
|
||||||
|
exports.SemanticErrorSeverity = assembler_2.SemanticErrorSeverity;
|
||||||
|
7
packages/asm/lib/opcodes.d.ts
vendored
7
packages/asm/lib/opcodes.d.ts
vendored
@ -1,3 +1,8 @@
|
|||||||
|
export declare enum OpcodeMemoryAccess {
|
||||||
|
write = "write",
|
||||||
|
read = "read",
|
||||||
|
full = "full"
|
||||||
|
}
|
||||||
export declare class Opcode {
|
export declare class Opcode {
|
||||||
readonly value: number;
|
readonly value: number;
|
||||||
readonly mnemonic: string;
|
readonly mnemonic: string;
|
||||||
@ -8,7 +13,7 @@ export declare class Opcode {
|
|||||||
isJump(): boolean;
|
isJump(): boolean;
|
||||||
isValidJumpDest(): boolean;
|
isValidJumpDest(): boolean;
|
||||||
isPush(): number;
|
isPush(): number;
|
||||||
isMemory(readOrWrite?: boolean): boolean;
|
isMemoryAccess(readOrWrite?: boolean): OpcodeMemoryAccess;
|
||||||
isStatic(): boolean;
|
isStatic(): boolean;
|
||||||
static from(valueOrMnemonic: number | string): Opcode;
|
static from(valueOrMnemonic: number | string): Opcode;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|||||||
// EXTCODEHASH
|
// EXTCODEHASH
|
||||||
// See: https://eips.ethereum.org/EIPS/eip-1052
|
// See: https://eips.ethereum.org/EIPS/eip-1052
|
||||||
var ethers_1 = require("ethers");
|
var ethers_1 = require("ethers");
|
||||||
|
var OpcodeMemoryAccess;
|
||||||
|
(function (OpcodeMemoryAccess) {
|
||||||
|
OpcodeMemoryAccess["write"] = "write";
|
||||||
|
OpcodeMemoryAccess["read"] = "read";
|
||||||
|
OpcodeMemoryAccess["full"] = "full";
|
||||||
|
})(OpcodeMemoryAccess = exports.OpcodeMemoryAccess || (exports.OpcodeMemoryAccess = {}));
|
||||||
|
;
|
||||||
var Opcode = /** @class */ (function () {
|
var Opcode = /** @class */ (function () {
|
||||||
function Opcode(mnemonic, value, delta, alpha, doc) {
|
function Opcode(mnemonic, value, delta, alpha, doc) {
|
||||||
ethers_1.ethers.utils.defineReadOnly(this, "mnemonic", mnemonic);
|
ethers_1.ethers.utils.defineReadOnly(this, "mnemonic", mnemonic);
|
||||||
@ -32,12 +39,19 @@ var Opcode = /** @class */ (function () {
|
|||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
// Returns true if this operation writes to memory contents (or if readOrWrite, reads memory)
|
// Returns true if this operation writes to memory contents (or if readOrWrite, reads memory)
|
||||||
Opcode.prototype.isMemory = function (readOrWrite) {
|
// Unknown opcodes return null
|
||||||
throw new Error("@TODO: return true if modifies memory");
|
Opcode.prototype.isMemoryAccess = function (readOrWrite) {
|
||||||
|
switch ((_Opcodes[this.mnemonic.toLowerCase()] || { memory: null }).memory) {
|
||||||
|
case "read": return OpcodeMemoryAccess.read;
|
||||||
|
case "write": return OpcodeMemoryAccess.write;
|
||||||
|
case "full": return OpcodeMemoryAccess.full;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
};
|
};
|
||||||
// Returns true if this opcode does not affect state
|
// Returns true if this opcode does not affect state
|
||||||
|
// Unknown opcodes return false
|
||||||
Opcode.prototype.isStatic = function () {
|
Opcode.prototype.isStatic = function () {
|
||||||
throw new Error("@TODO: return true if certain non-state-changing");
|
return !(_Opcodes[this.mnemonic.toLowerCase()] || { nonStatic: true }).nonStatic;
|
||||||
};
|
};
|
||||||
Opcode.from = function (valueOrMnemonic) {
|
Opcode.from = function (valueOrMnemonic) {
|
||||||
if (typeof (valueOrMnemonic) === "string") {
|
if (typeof (valueOrMnemonic) === "string") {
|
||||||
@ -78,7 +92,7 @@ var _Opcodes = {
|
|||||||
shr: { value: 0x1c, delta: 2, alpha: 1, doc: "v = shr(shiftBits, value)" },
|
shr: { value: 0x1c, delta: 2, alpha: 1, doc: "v = shr(shiftBits, value)" },
|
||||||
sar: { value: 0x1d, delta: 2, alpha: 1, doc: "v = sar(shiftBits, value)" },
|
sar: { value: 0x1d, delta: 2, alpha: 1, doc: "v = sar(shiftBits, value)" },
|
||||||
// SHA3
|
// SHA3
|
||||||
sha3: { value: 0x20, delta: 2, alpha: 1, doc: "v = sha3(offset, length)" },
|
sha3: { value: 0x20, delta: 2, alpha: 1, doc: "v = sha3(offset, length)", memory: "read" },
|
||||||
// Environmental Information
|
// Environmental Information
|
||||||
address: { value: 0x30, delta: 0, alpha: 1, doc: "myAddr = address" },
|
address: { value: 0x30, delta: 0, alpha: 1, doc: "myAddr = address" },
|
||||||
balance: { value: 0x31, delta: 1, alpha: 1, doc: "wei = balance(address)" },
|
balance: { value: 0x31, delta: 1, alpha: 1, doc: "wei = balance(address)" },
|
||||||
@ -87,14 +101,14 @@ var _Opcodes = {
|
|||||||
callvalue: { value: 0x34, delta: 0, alpha: 1, doc: "msgValue = callvalue" },
|
callvalue: { value: 0x34, delta: 0, alpha: 1, doc: "msgValue = callvalue" },
|
||||||
calldataload: { value: 0x35, delta: 1, alpha: 1, doc: "calldataWordValue = calldataload(byteOffet)" },
|
calldataload: { value: 0x35, delta: 1, alpha: 1, doc: "calldataWordValue = calldataload(byteOffet)" },
|
||||||
calldatasize: { value: 0x36, delta: 0, alpha: 1, doc: "calldataLength = calldatasize" },
|
calldatasize: { value: 0x36, delta: 0, alpha: 1, doc: "calldataLength = calldatasize" },
|
||||||
calldatacopy: { value: 0x37, delta: 3, alpha: 0, doc: "calldatacopy(dstMemoryIndex, dataIndex, length)" },
|
calldatacopy: { value: 0x37, delta: 3, alpha: 0, doc: "calldatacopy(dstMemoryIndex, dataIndex, length)", memory: "write" },
|
||||||
codesize: { value: 0x38, delta: 0, alpha: 1, doc: "myCodeLength = codesize" },
|
codesize: { value: 0x38, delta: 0, alpha: 1, doc: "myCodeLength = codesize" },
|
||||||
codecopy: { value: 0x39, delta: 3, alpha: 0, doc: "codecopy(dstMemoryIndex, codeIndex, length)" },
|
codecopy: { value: 0x39, delta: 3, alpha: 0, doc: "codecopy(dstMemoryIndex, codeIndex, length)", memory: "write" },
|
||||||
gasprice: { value: 0x3a, delta: 0, alpha: 1, doc: "txGasPrice = gasprice" },
|
gasprice: { value: 0x3a, delta: 0, alpha: 1, doc: "txGasPrice = gasprice" },
|
||||||
extcodesize: { value: 0x3b, delta: 1, alpha: 1, doc: "otherCodeLength = extcodesize(address)" },
|
extcodesize: { value: 0x3b, delta: 1, alpha: 1, doc: "otherCodeLength = extcodesize(address)" },
|
||||||
extcodecopy: { value: 0x3c, delta: 4, alpha: 0, doc: "extcodecopy(address, dstMemoryIndex, extcodeIndex, length)" },
|
extcodecopy: { value: 0x3c, delta: 4, alpha: 0, doc: "extcodecopy(address, dstMemoryIndex, extcodeIndex, length)", memory: "write" },
|
||||||
returndatasize: { value: 0x3d, delta: 0, alpha: 1, doc: "v = returndatasize" },
|
returndatasize: { value: 0x3d, delta: 0, alpha: 1, doc: "v = returndatasize" },
|
||||||
returndatacopy: { value: 0x3e, delta: 3, alpha: 0, doc: "returndatacopy(dstMemoryOffset, returndataIndex, length)" },
|
returndatacopy: { value: 0x3e, delta: 3, alpha: 0, doc: "returndatacopy(dstMemoryOffset, returndataIndex, length)", memory: "write" },
|
||||||
extcodehash: { value: 0x3f, delta: 1, alpha: 1, doc: "hash = extcodehash(address)" },
|
extcodehash: { value: 0x3f, delta: 1, alpha: 1, doc: "hash = extcodehash(address)" },
|
||||||
// Block Information
|
// Block Information
|
||||||
blockhash: { value: 0x40, delta: 1, alpha: 1, doc: "hash = blockhash(blockNumber)" },
|
blockhash: { value: 0x40, delta: 1, alpha: 1, doc: "hash = blockhash(blockNumber)" },
|
||||||
@ -105,11 +119,11 @@ var _Opcodes = {
|
|||||||
gaslimit: { value: 0x45, delta: 0, alpha: 1, doc: "gas = gaslimit" },
|
gaslimit: { value: 0x45, delta: 0, alpha: 1, doc: "gas = gaslimit" },
|
||||||
// Stack, Memory, Storage and Flow Operations
|
// Stack, Memory, Storage and Flow Operations
|
||||||
pop: { value: 0x50, delta: 1, alpha: 0, doc: "stackTopValue = pop" },
|
pop: { value: 0x50, delta: 1, alpha: 0, doc: "stackTopValue = pop" },
|
||||||
mload: { value: 0x51, delta: 1, alpha: 1, doc: "memoryWordValue = mload(memoryByteIndex)" },
|
mload: { value: 0x51, delta: 1, alpha: 1, doc: "memoryWordValue = mload(memoryByteIndex)", memory: "read" },
|
||||||
mstore: { value: 0x52, delta: 2, alpha: 0, doc: "mstore(memoryByteIndex, valueOut)" },
|
mstore: { value: 0x52, delta: 2, alpha: 0, doc: "mstore(memoryByteIndex, valueOut)", memory: "write" },
|
||||||
mstore8: { value: 0x53, delta: 2, alpha: 0, doc: "mstore8(memoryByteIndex, valueOut [ & 0xff ])" },
|
mstore8: { value: 0x53, delta: 2, alpha: 0, doc: "mstore8(memoryByteIndex, valueOut [ & 0xff ])", memory: "write" },
|
||||||
sload: { value: 0x54, delta: 1, alpha: 1, doc: "storageWordValue = sload(storageWordIndex)" },
|
sload: { value: 0x54, delta: 1, alpha: 1, doc: "storageWordValue = sload(storageWordIndex)" },
|
||||||
sstore: { value: 0x55, delta: 2, alpha: 0, doc: "sstore(storageWordIndex, valueOut)" },
|
sstore: { value: 0x55, delta: 2, alpha: 0, doc: "sstore(storageWordIndex, valueOut)", nonStatic: true },
|
||||||
jump: { value: 0x56, delta: 1, alpha: 0, doc: "jump(target)" },
|
jump: { value: 0x56, delta: 1, alpha: 0, doc: "jump(target)" },
|
||||||
jumpi: { value: 0x57, delta: 2, alpha: 0, doc: "jumpi(target, notZero)" },
|
jumpi: { value: 0x57, delta: 2, alpha: 0, doc: "jumpi(target, notZero)" },
|
||||||
pc: { value: 0x58, delta: 0, alpha: 1, doc: "programCounter = pc" },
|
pc: { value: 0x58, delta: 0, alpha: 1, doc: "programCounter = pc" },
|
||||||
@ -184,22 +198,22 @@ var _Opcodes = {
|
|||||||
swap15: { value: 0x9e, delta: 0, alpha: 0 },
|
swap15: { value: 0x9e, delta: 0, alpha: 0 },
|
||||||
swap16: { value: 0x9f, delta: 0, alpha: 0 },
|
swap16: { value: 0x9f, delta: 0, alpha: 0 },
|
||||||
// Loggin Operations
|
// Loggin Operations
|
||||||
log0: { value: 0xa0, delta: 2, alpha: 0 },
|
log0: { value: 0xa0, delta: 2, alpha: 0, nonStatic: true, memory: "read" },
|
||||||
log1: { value: 0xa1, delta: 3, alpha: 0 },
|
log1: { value: 0xa1, delta: 3, alpha: 0, nonStatic: true, memory: "read" },
|
||||||
log2: { value: 0xa2, delta: 4, alpha: 0 },
|
log2: { value: 0xa2, delta: 4, alpha: 0, nonStatic: true, memory: "read" },
|
||||||
log3: { value: 0xa3, delta: 5, alpha: 0 },
|
log3: { value: 0xa3, delta: 5, alpha: 0, nonStatic: true, memory: "read" },
|
||||||
log4: { value: 0xa4, delta: 6, alpha: 0 },
|
log4: { value: 0xa4, delta: 6, alpha: 0, nonStatic: true, memory: "read" },
|
||||||
// System Operations
|
// System Operations
|
||||||
create: { value: 0xf0, delta: 3, alpha: 1, doc: "address = create(value, index, length)" },
|
create: { value: 0xf0, delta: 3, alpha: 1, doc: "address = create(value, index, length)", nonStatic: true, memory: "read" },
|
||||||
call: { value: 0xf1, delta: 7, alpha: 1, doc: "v = call(gasLimit, address, value, inputIndex, inputLength, outputIndex, outputLength)" },
|
call: { value: 0xf1, delta: 7, alpha: 1, doc: "v = call(gasLimit, address, value, inputIndex, inputLength, outputIndex, outputLength)", nonStatic: true, memory: "full" },
|
||||||
callcode: { value: 0xf2, delta: 7, alpha: 1, doc: "v = callcode(@TODO)" },
|
callcode: { value: 0xf2, delta: 7, alpha: 1, doc: "v = callcode(@TODO)", nonStatic: true, memory: "full" },
|
||||||
"return": { value: 0xf3, delta: 2, alpha: 0, doc: "return(index, length)" },
|
"return": { value: 0xf3, delta: 2, alpha: 0, doc: "return(index, length)", memory: "read" },
|
||||||
delegatecall: { value: 0xf4, delta: 6, alpha: 1, doc: "v = delegatecall(gasLimit, address, inputIndex, inputLength, outputIndex, outputLength)" },
|
delegatecall: { value: 0xf4, delta: 6, alpha: 1, doc: "v = delegatecall(gasLimit, address, inputIndex, inputLength, outputIndex, outputLength)", nonStatic: true, memory: "full" },
|
||||||
create2: { value: 0xf5, delta: 4, alpha: 1, doc: "address = create2(value, index, length, salt)" },
|
create2: { value: 0xf5, delta: 4, alpha: 1, doc: "address = create2(value, index, length, salt)", nonStatic: true, memory: "read" },
|
||||||
staticcall: { value: 0xfa, delta: 6, alpha: 1, doc: "v = staticcall(gasLimit, address, inputIndex, inputLength, outputIndex, outputLength)" },
|
staticcall: { value: 0xfa, delta: 6, alpha: 1, doc: "v = staticcall(gasLimit, address, inputIndex, inputLength, outputIndex, outputLength)", memory: "full" },
|
||||||
revert: { value: 0xfd, delta: 2, alpha: 0, doc: "revert(returnDataOffset, returnDataLength)" },
|
revert: { value: 0xfd, delta: 2, alpha: 0, doc: "revert(returnDataOffset, returnDataLength)", memory: "read" },
|
||||||
invalid: { value: 0xfe, delta: 0, alpha: 0, doc: "invalid" },
|
invalid: { value: 0xfe, delta: 0, alpha: 0, doc: "invalid" },
|
||||||
suicide: { value: 0xff, delta: 1, alpha: 0, doc: "suicide(targetAddress)" },
|
suicide: { value: 0xff, delta: 1, alpha: 0, doc: "suicide(targetAddress)", nonStatic: true },
|
||||||
};
|
};
|
||||||
var OpcodeMap = {};
|
var OpcodeMap = {};
|
||||||
var Opcodes = [];
|
var Opcodes = [];
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
"generate": "node ./generate.js",
|
"generate": "node ./generate.js",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"tarballHash": "0xff54a87fe1756a7bc92d6d3b007dd65d85713495eabf6186a44f687098b67aa1",
|
"tarballHash": "0x6a57190906839e057c493a8ffaf2c5e57b4ac513d882bddc115884bc5092649b",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"version": "5.0.0-beta.148"
|
"version": "5.0.0-beta.149"
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
export const version = "asm/5.0.0-beta.148";
|
export const version = "asm/5.0.0-beta.149";
|
||||||
|
2
packages/basex/lib.esm/_version.d.ts
vendored
2
packages/basex/lib.esm/_version.d.ts
vendored
@ -1 +1 @@
|
|||||||
export declare const version = "basex/5.0.0-beta.131";
|
export declare const version = "basex/5.0.0-beta.132";
|
||||||
|
@ -1 +1 @@
|
|||||||
export const version = "basex/5.0.0-beta.131";
|
export const version = "basex/5.0.0-beta.132";
|
||||||
|
6
packages/basex/lib.esm/index.d.ts
vendored
6
packages/basex/lib.esm/index.d.ts
vendored
@ -41,8 +41,10 @@ import { BytesLike } from "@ethersproject/bytes";
|
|||||||
export declare class BaseX {
|
export declare class BaseX {
|
||||||
readonly alphabet: string;
|
readonly alphabet: string;
|
||||||
readonly base: number;
|
readonly base: number;
|
||||||
private _alphabetMap;
|
_alphabetMap: {
|
||||||
private _leader;
|
[character: string]: number;
|
||||||
|
};
|
||||||
|
_leader: string;
|
||||||
constructor(alphabet: string);
|
constructor(alphabet: string);
|
||||||
encode(value: BytesLike): string;
|
encode(value: BytesLike): string;
|
||||||
decode(value: string): Uint8Array;
|
decode(value: string): Uint8Array;
|
||||||
|
2
packages/basex/lib/_version.d.ts
vendored
2
packages/basex/lib/_version.d.ts
vendored
@ -1 +1 @@
|
|||||||
export declare const version = "basex/5.0.0-beta.131";
|
export declare const version = "basex/5.0.0-beta.132";
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.version = "basex/5.0.0-beta.131";
|
exports.version = "basex/5.0.0-beta.132";
|
||||||
|
6
packages/basex/lib/index.d.ts
vendored
6
packages/basex/lib/index.d.ts
vendored
@ -41,8 +41,10 @@ import { BytesLike } from "@ethersproject/bytes";
|
|||||||
export declare class BaseX {
|
export declare class BaseX {
|
||||||
readonly alphabet: string;
|
readonly alphabet: string;
|
||||||
readonly base: number;
|
readonly base: number;
|
||||||
private _alphabetMap;
|
_alphabetMap: {
|
||||||
private _leader;
|
[character: string]: number;
|
||||||
|
};
|
||||||
|
_leader: string;
|
||||||
constructor(alphabet: string);
|
constructor(alphabet: string);
|
||||||
encode(value: BytesLike): string;
|
encode(value: BytesLike): string;
|
||||||
decode(value: string): Uint8Array;
|
decode(value: string): Uint8Array;
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"tarballHash": "0xb05390e395a38be994749f03651ccc3c7d744517c9437e0fe1d1a7679266a33f",
|
"tarballHash": "0x4f195cbe70a4657e86326d67c58dc6e244b4c816eafc232c5a8f82bb43d3dba3",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"version": "5.0.0-beta.131"
|
"version": "5.0.0-beta.132"
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
export const version = "basex/5.0.0-beta.131";
|
export const version = "basex/5.0.0-beta.132";
|
||||||
|
2
packages/cli/lib.esm/_version.d.ts
vendored
2
packages/cli/lib.esm/_version.d.ts
vendored
@ -1 +1 @@
|
|||||||
export declare const version = "cli/5.0.0-beta.150";
|
export declare const version = "cli/5.0.0-beta.151";
|
||||||
|
@ -1 +1 @@
|
|||||||
export const version = "cli/5.0.0-beta.150";
|
export const version = "cli/5.0.0-beta.151";
|
||||||
|
@ -11,7 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||||||
};
|
};
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import { resolve } from "path";
|
import { resolve } from "path";
|
||||||
import { assemble, disassemble, formatBytecode, parse } from "@ethersproject/asm";
|
import { assemble, disassemble, formatBytecode, parse, SemanticErrorSeverity } from "@ethersproject/asm";
|
||||||
import { CLI, Plugin } from "../cli";
|
import { CLI, Plugin } from "../cli";
|
||||||
function repeat(text, length) {
|
function repeat(text, length) {
|
||||||
if (text.length === 0) {
|
if (text.length === 0) {
|
||||||
@ -37,14 +37,26 @@ class AssemblePlugin extends Plugin {
|
|||||||
}
|
}
|
||||||
static getOptionHelp() {
|
static getOptionHelp() {
|
||||||
return [
|
return [
|
||||||
|
{
|
||||||
|
name: "--define KEY=VALUE",
|
||||||
|
help: "provide assembler defines"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "--disassemble",
|
name: "--disassemble",
|
||||||
help: "Disassemble input bytecode"
|
help: "Disassemble input bytecode"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "--define KEY=VALUE",
|
name: "--ignore-warnings",
|
||||||
help: "provide assembler defines"
|
help: "Ignore warnings"
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
name: "--pic",
|
||||||
|
help: "generate position independent code"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "--target LABEL",
|
||||||
|
help: "output LABEL bytecode (default: _)"
|
||||||
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
prepareOptions(argParser) {
|
prepareOptions(argParser) {
|
||||||
@ -64,6 +76,9 @@ class AssemblePlugin extends Plugin {
|
|||||||
});
|
});
|
||||||
// We are disassembling...
|
// We are disassembling...
|
||||||
this.disassemble = argParser.consumeFlag("disassemble");
|
this.disassemble = argParser.consumeFlag("disassemble");
|
||||||
|
this.ignoreWarnings = argParser.consumeFlag("ignore-warnings");
|
||||||
|
this.pic = argParser.consumeFlag("pic");
|
||||||
|
this.target = argParser.consumeOption("target");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
prepareArgs(args) {
|
prepareArgs(args) {
|
||||||
@ -126,11 +141,37 @@ class AssemblePlugin extends Plugin {
|
|||||||
console.log(formatBytecode(disassemble(this.content)));
|
console.log(formatBytecode(disassemble(this.content)));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
console.log(yield assemble(parse(this.content), {
|
try {
|
||||||
|
const ast = parse(this.content, {
|
||||||
|
ignoreWarnings: !!this.ignoreWarnings
|
||||||
|
});
|
||||||
|
console.log(yield assemble(ast, {
|
||||||
defines: this.defines,
|
defines: this.defines,
|
||||||
filename: this.filename,
|
filename: this.filename,
|
||||||
|
positionIndependentCode: this.pic,
|
||||||
|
target: (this.target || "_")
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
catch (error) {
|
||||||
|
if (error.errors) {
|
||||||
|
(error.errors).forEach((error) => {
|
||||||
|
if (error.severity === SemanticErrorSeverity.error) {
|
||||||
|
console.log(`Error: ${error.message} (line: ${error.node.location.line + 1})`);
|
||||||
|
}
|
||||||
|
else if (error.severity === SemanticErrorSeverity.warning) {
|
||||||
|
console.log(`Warning: ${error.message} (line: ${error.node.location.line + 1})`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,15 +238,6 @@ class AccountPlugin extends EnsPlugin {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
prepareOptions(argParser) {
|
|
||||||
const _super = Object.create(null, {
|
|
||||||
prepareOptions: { get: () => super.prepareOptions }
|
|
||||||
});
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
yield _super.prepareOptions.call(this, argParser);
|
|
||||||
ethers.utils.defineReadOnly(this, "_wait", argParser.consumeFlag("wait"));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
prepareArgs(args) {
|
prepareArgs(args) {
|
||||||
const _super = Object.create(null, {
|
const _super = Object.create(null, {
|
||||||
prepareArgs: { get: () => super.prepareArgs }
|
prepareArgs: { get: () => super.prepareArgs }
|
||||||
|
@ -12,12 +12,22 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import { dirname, resolve } from "path";
|
import { dirname, resolve } from "path";
|
||||||
import REPL from "repl";
|
import REPL from "repl";
|
||||||
import util from "util";
|
|
||||||
import vm from "vm";
|
import vm from "vm";
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
|
import { parseExpression as babelParseExpression } from "@babel/parser";
|
||||||
import { CLI, dump, Plugin } from "../cli";
|
import { CLI, dump, Plugin } from "../cli";
|
||||||
import { getPassword, getProgressBar } from "../prompt";
|
import { getPassword, getProgressBar } from "../prompt";
|
||||||
import { compile, customRequire } from "../solc";
|
import { compile, customRequire } from "../solc";
|
||||||
|
function repeat(c, length) {
|
||||||
|
if (c.length === 0) {
|
||||||
|
throw new Error("too short");
|
||||||
|
}
|
||||||
|
let result = c;
|
||||||
|
while (result.length < length) {
|
||||||
|
result += result;
|
||||||
|
}
|
||||||
|
return result.substring(0, length);
|
||||||
|
}
|
||||||
function setupContext(path, context, plugin) {
|
function setupContext(path, context, plugin) {
|
||||||
context.provider = plugin.provider;
|
context.provider = plugin.provider;
|
||||||
context.accounts = plugin.accounts;
|
context.accounts = plugin.accounts;
|
||||||
@ -31,7 +41,6 @@ function setupContext(path, context, plugin) {
|
|||||||
context.console = console;
|
context.console = console;
|
||||||
}
|
}
|
||||||
if (!context.require) {
|
if (!context.require) {
|
||||||
//context.require = _module.createRequireFromPath(path);
|
|
||||||
context.require = customRequire(path);
|
context.require = customRequire(path);
|
||||||
}
|
}
|
||||||
if (!context.process) {
|
if (!context.process) {
|
||||||
@ -52,7 +61,9 @@ function setupContext(path, context, plugin) {
|
|||||||
context.getContractAddress = ethers.utils.getContractAddress;
|
context.getContractAddress = ethers.utils.getContractAddress;
|
||||||
context.getIcapAddress = ethers.utils.getIcapAddress;
|
context.getIcapAddress = ethers.utils.getIcapAddress;
|
||||||
context.arrayify = ethers.utils.arrayify;
|
context.arrayify = ethers.utils.arrayify;
|
||||||
|
context.concat = ethers.utils.concat;
|
||||||
context.hexlify = ethers.utils.hexlify;
|
context.hexlify = ethers.utils.hexlify;
|
||||||
|
context.zeroPad = ethers.utils.zeroPad;
|
||||||
context.joinSignature = ethers.utils.joinSignature;
|
context.joinSignature = ethers.utils.joinSignature;
|
||||||
context.splitSignature = ethers.utils.splitSignature;
|
context.splitSignature = ethers.utils.splitSignature;
|
||||||
context.id = ethers.utils.id;
|
context.id = ethers.utils.id;
|
||||||
@ -71,6 +82,37 @@ function setupContext(path, context, plugin) {
|
|||||||
context.toUtf8String = ethers.utils.toUtf8String;
|
context.toUtf8String = ethers.utils.toUtf8String;
|
||||||
}
|
}
|
||||||
const cli = new CLI("sandbox");
|
const cli = new CLI("sandbox");
|
||||||
|
function prepareCode(code) {
|
||||||
|
let ast = babelParseExpression(code, {
|
||||||
|
createParenthesizedExpressions: true
|
||||||
|
});
|
||||||
|
// Crawl the AST, to compute needed source code manipulations
|
||||||
|
const insert = [];
|
||||||
|
const descend = function (node) {
|
||||||
|
if (node == null || typeof (node) !== "object") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Array.isArray(node)) {
|
||||||
|
return node.forEach(descend);
|
||||||
|
}
|
||||||
|
// We will add parenthesis around ObjectExpressions, which
|
||||||
|
// otherwise look like blocks
|
||||||
|
if (node.type === "ObjectExpression") {
|
||||||
|
insert.push({ char: "(", offset: node.start });
|
||||||
|
insert.push({ char: ")", offset: node.end });
|
||||||
|
}
|
||||||
|
Object.keys(node).forEach((key) => descend(key));
|
||||||
|
};
|
||||||
|
descend(ast);
|
||||||
|
// We make modifications from back to front, so we don't need
|
||||||
|
// to adjust offsets
|
||||||
|
insert.sort((a, b) => (b.offset - a.offset));
|
||||||
|
// Modify the code for REPL
|
||||||
|
insert.forEach((mod) => {
|
||||||
|
code = code.substring(0, mod.offset) + mod.char + code.substring(mod.offset);
|
||||||
|
});
|
||||||
|
return code;
|
||||||
|
}
|
||||||
class SandboxPlugin extends Plugin {
|
class SandboxPlugin extends Plugin {
|
||||||
static getHelp() {
|
static getHelp() {
|
||||||
return {
|
return {
|
||||||
@ -101,33 +143,59 @@ class SandboxPlugin extends Plugin {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
run() {
|
run() {
|
||||||
console.log("network: " + this.network.name + " (chainId: " + this.network.chainId + ")");
|
console.log(`version: ${ethers.version}`);
|
||||||
let nextPromiseId = 0;
|
console.log(`network: ${this.network.name} (chainId: ${this.network.chainId})`);
|
||||||
function promiseWriter(output) {
|
const filename = resolve(process.cwd(), "./sandbox.js");
|
||||||
if (output instanceof Promise) {
|
const prompt = (this.provider ? this.network.name : "no-network") + "> ";
|
||||||
repl.context._p = output;
|
const evaluate = function (code, context, file, _callback) {
|
||||||
let promiseId = nextPromiseId++;
|
// Pausing the stdin (which prompt does when it leaves), causes
|
||||||
output.then((result) => {
|
// readline to end us. So, we always re-enable stdin on a result
|
||||||
console.log(`\n<Promise id=${promiseId} resolved>`);
|
const callback = (error, result) => {
|
||||||
console.log(util.inspect(result));
|
_callback(error, result);
|
||||||
repl.context._r = result;
|
process.stdin.resume();
|
||||||
repl.displayPrompt(true);
|
};
|
||||||
|
try {
|
||||||
|
code = prepareCode(code);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
if (error instanceof SyntaxError) {
|
||||||
|
const leftover = code.substring(error.pos);
|
||||||
|
const loc = error.loc;
|
||||||
|
if (leftover.trim()) {
|
||||||
|
// After the first line, the prompt is "... "
|
||||||
|
console.log(repeat("-", ((loc.line === 1) ? prompt.length : 4) + loc.column - 1) + "^");
|
||||||
|
console.log(`Syntax Error! ${error.message}`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error = new REPL.Recoverable(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return callback(error);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const result = vm.runInContext(code, context, {
|
||||||
|
filename: filename
|
||||||
|
});
|
||||||
|
if (result instanceof Promise) {
|
||||||
|
result.then((result) => {
|
||||||
|
callback(null, result);
|
||||||
}, (error) => {
|
}, (error) => {
|
||||||
console.log(`\n<Promise id=${promiseId} rejected>`);
|
callback(error);
|
||||||
console.log(util.inspect(error));
|
|
||||||
repl.displayPrompt(true);
|
|
||||||
});
|
});
|
||||||
return `<Promise id=${promiseId} pending>`;
|
|
||||||
}
|
}
|
||||||
return util.inspect(output);
|
else {
|
||||||
|
callback(null, result);
|
||||||
}
|
}
|
||||||
let repl = REPL.start({
|
}
|
||||||
input: process.stdin,
|
catch (error) {
|
||||||
output: process.stdout,
|
callback(error);
|
||||||
prompt: (this.provider ? this.network.name : "no-network") + "> ",
|
}
|
||||||
writer: promiseWriter
|
};
|
||||||
|
const repl = REPL.start({
|
||||||
|
prompt: prompt,
|
||||||
|
eval: evaluate
|
||||||
});
|
});
|
||||||
setupContext(resolve(process.cwd(), "./sandbox.js"), repl.context, this);
|
setupContext(filename, repl.context, this);
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
repl.on("exit", function () {
|
repl.on("exit", function () {
|
||||||
console.log("");
|
console.log("");
|
||||||
|
2
packages/cli/lib.esm/cli.d.ts
vendored
2
packages/cli/lib.esm/cli.d.ts
vendored
@ -39,7 +39,7 @@ export interface PluginType {
|
|||||||
export declare abstract class Plugin {
|
export declare abstract class Plugin {
|
||||||
network: ethers.providers.Network;
|
network: ethers.providers.Network;
|
||||||
provider: ethers.providers.Provider;
|
provider: ethers.providers.Provider;
|
||||||
accounts: Array<WrappedSigner>;
|
accounts: ReadonlyArray<WrappedSigner>;
|
||||||
mnemonicPassword: boolean;
|
mnemonicPassword: boolean;
|
||||||
_xxxMnemonicPasswordHard: boolean;
|
_xxxMnemonicPasswordHard: boolean;
|
||||||
gasLimit: ethers.BigNumber;
|
gasLimit: ethers.BigNumber;
|
||||||
|
2
packages/cli/lib/_version.d.ts
vendored
2
packages/cli/lib/_version.d.ts
vendored
@ -1 +1 @@
|
|||||||
export declare const version = "cli/5.0.0-beta.150";
|
export declare const version = "cli/5.0.0-beta.151";
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.version = "cli/5.0.0-beta.150";
|
exports.version = "cli/5.0.0-beta.151";
|
||||||
|
57
packages/cli/lib/bin/ethers-asm.js
Normal file → Executable file
57
packages/cli/lib/bin/ethers-asm.js
Normal file → Executable file
@ -85,14 +85,26 @@ var AssemblePlugin = /** @class */ (function (_super) {
|
|||||||
};
|
};
|
||||||
AssemblePlugin.getOptionHelp = function () {
|
AssemblePlugin.getOptionHelp = function () {
|
||||||
return [
|
return [
|
||||||
|
{
|
||||||
|
name: "--define KEY=VALUE",
|
||||||
|
help: "provide assembler defines"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "--disassemble",
|
name: "--disassemble",
|
||||||
help: "Disassemble input bytecode"
|
help: "Disassemble input bytecode"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "--define KEY=VALUE",
|
name: "--ignore-warnings",
|
||||||
help: "provide assembler defines"
|
help: "Ignore warnings"
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
name: "--pic",
|
||||||
|
help: "generate position independent code"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "--target LABEL",
|
||||||
|
help: "output LABEL bytecode (default: _)"
|
||||||
|
},
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
AssemblePlugin.prototype.prepareOptions = function (argParser) {
|
AssemblePlugin.prototype.prepareOptions = function (argParser) {
|
||||||
@ -114,6 +126,9 @@ var AssemblePlugin = /** @class */ (function (_super) {
|
|||||||
});
|
});
|
||||||
// We are disassembling...
|
// We are disassembling...
|
||||||
this.disassemble = argParser.consumeFlag("disassemble");
|
this.disassemble = argParser.consumeFlag("disassemble");
|
||||||
|
this.ignoreWarnings = argParser.consumeFlag("ignore-warnings");
|
||||||
|
this.pic = argParser.consumeFlag("pic");
|
||||||
|
this.target = argParser.consumeOption("target");
|
||||||
return [2 /*return*/];
|
return [2 /*return*/];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -181,23 +196,49 @@ var AssemblePlugin = /** @class */ (function (_super) {
|
|||||||
};
|
};
|
||||||
AssemblePlugin.prototype.run = function () {
|
AssemblePlugin.prototype.run = function () {
|
||||||
return __awaiter(this, void 0, void 0, function () {
|
return __awaiter(this, void 0, void 0, function () {
|
||||||
var _a, _b;
|
var ast, _a, _b, error_1;
|
||||||
return __generator(this, function (_c) {
|
return __generator(this, function (_c) {
|
||||||
switch (_c.label) {
|
switch (_c.label) {
|
||||||
case 0:
|
case 0:
|
||||||
if (!this.disassemble) return [3 /*break*/, 1];
|
if (!this.disassemble) return [3 /*break*/, 1];
|
||||||
console.log(asm_1.formatBytecode(asm_1.disassemble(this.content)));
|
console.log(asm_1.formatBytecode(asm_1.disassemble(this.content)));
|
||||||
return [3 /*break*/, 3];
|
return [3 /*break*/, 4];
|
||||||
case 1:
|
case 1:
|
||||||
|
_c.trys.push([1, 3, , 4]);
|
||||||
|
ast = asm_1.parse(this.content, {
|
||||||
|
ignoreWarnings: !!this.ignoreWarnings
|
||||||
|
});
|
||||||
_b = (_a = console).log;
|
_b = (_a = console).log;
|
||||||
return [4 /*yield*/, asm_1.assemble(asm_1.parse(this.content), {
|
return [4 /*yield*/, asm_1.assemble(ast, {
|
||||||
defines: this.defines,
|
defines: this.defines,
|
||||||
filename: this.filename,
|
filename: this.filename,
|
||||||
|
positionIndependentCode: this.pic,
|
||||||
|
target: (this.target || "_")
|
||||||
})];
|
})];
|
||||||
case 2:
|
case 2:
|
||||||
_b.apply(_a, [_c.sent()]);
|
_b.apply(_a, [_c.sent()]);
|
||||||
_c.label = 3;
|
return [3 /*break*/, 4];
|
||||||
case 3: return [2 /*return*/];
|
case 3:
|
||||||
|
error_1 = _c.sent();
|
||||||
|
if (error_1.errors) {
|
||||||
|
(error_1.errors).forEach(function (error) {
|
||||||
|
if (error.severity === asm_1.SemanticErrorSeverity.error) {
|
||||||
|
console.log("Error: " + error.message + " (line: " + (error.node.location.line + 1) + ")");
|
||||||
|
}
|
||||||
|
else if (error.severity === asm_1.SemanticErrorSeverity.warning) {
|
||||||
|
console.log("Warning: " + error.message + " (line: " + (error.node.location.line + 1) + ")");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw error_1;
|
||||||
|
}
|
||||||
|
return [3 /*break*/, 4];
|
||||||
|
case 4: return [2 /*return*/];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -404,19 +404,6 @@ var AccountPlugin = /** @class */ (function (_super) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
AccountPlugin.prototype.prepareOptions = function (argParser) {
|
|
||||||
return __awaiter(this, void 0, void 0, function () {
|
|
||||||
return __generator(this, function (_a) {
|
|
||||||
switch (_a.label) {
|
|
||||||
case 0: return [4 /*yield*/, _super.prototype.prepareOptions.call(this, argParser)];
|
|
||||||
case 1:
|
|
||||||
_a.sent();
|
|
||||||
ethers_1.ethers.utils.defineReadOnly(this, "_wait", argParser.consumeFlag("wait"));
|
|
||||||
return [2 /*return*/];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
AccountPlugin.prototype.prepareArgs = function (args) {
|
AccountPlugin.prototype.prepareArgs = function (args) {
|
||||||
return __awaiter(this, void 0, void 0, function () {
|
return __awaiter(this, void 0, void 0, function () {
|
||||||
var helpLine, params, command, i;
|
var helpLine, params, command, i;
|
||||||
|
@ -56,12 +56,22 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|||||||
var fs_1 = __importDefault(require("fs"));
|
var fs_1 = __importDefault(require("fs"));
|
||||||
var path_1 = require("path");
|
var path_1 = require("path");
|
||||||
var repl_1 = __importDefault(require("repl"));
|
var repl_1 = __importDefault(require("repl"));
|
||||||
var util_1 = __importDefault(require("util"));
|
|
||||||
var vm_1 = __importDefault(require("vm"));
|
var vm_1 = __importDefault(require("vm"));
|
||||||
var ethers_1 = require("ethers");
|
var ethers_1 = require("ethers");
|
||||||
|
var parser_1 = require("@babel/parser");
|
||||||
var cli_1 = require("../cli");
|
var cli_1 = require("../cli");
|
||||||
var prompt_1 = require("../prompt");
|
var prompt_1 = require("../prompt");
|
||||||
var solc_1 = require("../solc");
|
var solc_1 = require("../solc");
|
||||||
|
function repeat(c, length) {
|
||||||
|
if (c.length === 0) {
|
||||||
|
throw new Error("too short");
|
||||||
|
}
|
||||||
|
var result = c;
|
||||||
|
while (result.length < length) {
|
||||||
|
result += result;
|
||||||
|
}
|
||||||
|
return result.substring(0, length);
|
||||||
|
}
|
||||||
function setupContext(path, context, plugin) {
|
function setupContext(path, context, plugin) {
|
||||||
context.provider = plugin.provider;
|
context.provider = plugin.provider;
|
||||||
context.accounts = plugin.accounts;
|
context.accounts = plugin.accounts;
|
||||||
@ -75,7 +85,6 @@ function setupContext(path, context, plugin) {
|
|||||||
context.console = console;
|
context.console = console;
|
||||||
}
|
}
|
||||||
if (!context.require) {
|
if (!context.require) {
|
||||||
//context.require = _module.createRequireFromPath(path);
|
|
||||||
context.require = solc_1.customRequire(path);
|
context.require = solc_1.customRequire(path);
|
||||||
}
|
}
|
||||||
if (!context.process) {
|
if (!context.process) {
|
||||||
@ -96,7 +105,9 @@ function setupContext(path, context, plugin) {
|
|||||||
context.getContractAddress = ethers_1.ethers.utils.getContractAddress;
|
context.getContractAddress = ethers_1.ethers.utils.getContractAddress;
|
||||||
context.getIcapAddress = ethers_1.ethers.utils.getIcapAddress;
|
context.getIcapAddress = ethers_1.ethers.utils.getIcapAddress;
|
||||||
context.arrayify = ethers_1.ethers.utils.arrayify;
|
context.arrayify = ethers_1.ethers.utils.arrayify;
|
||||||
|
context.concat = ethers_1.ethers.utils.concat;
|
||||||
context.hexlify = ethers_1.ethers.utils.hexlify;
|
context.hexlify = ethers_1.ethers.utils.hexlify;
|
||||||
|
context.zeroPad = ethers_1.ethers.utils.zeroPad;
|
||||||
context.joinSignature = ethers_1.ethers.utils.joinSignature;
|
context.joinSignature = ethers_1.ethers.utils.joinSignature;
|
||||||
context.splitSignature = ethers_1.ethers.utils.splitSignature;
|
context.splitSignature = ethers_1.ethers.utils.splitSignature;
|
||||||
context.id = ethers_1.ethers.utils.id;
|
context.id = ethers_1.ethers.utils.id;
|
||||||
@ -115,6 +126,37 @@ function setupContext(path, context, plugin) {
|
|||||||
context.toUtf8String = ethers_1.ethers.utils.toUtf8String;
|
context.toUtf8String = ethers_1.ethers.utils.toUtf8String;
|
||||||
}
|
}
|
||||||
var cli = new cli_1.CLI("sandbox");
|
var cli = new cli_1.CLI("sandbox");
|
||||||
|
function prepareCode(code) {
|
||||||
|
var ast = parser_1.parseExpression(code, {
|
||||||
|
createParenthesizedExpressions: true
|
||||||
|
});
|
||||||
|
// Crawl the AST, to compute needed source code manipulations
|
||||||
|
var insert = [];
|
||||||
|
var descend = function (node) {
|
||||||
|
if (node == null || typeof (node) !== "object") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Array.isArray(node)) {
|
||||||
|
return node.forEach(descend);
|
||||||
|
}
|
||||||
|
// We will add parenthesis around ObjectExpressions, which
|
||||||
|
// otherwise look like blocks
|
||||||
|
if (node.type === "ObjectExpression") {
|
||||||
|
insert.push({ char: "(", offset: node.start });
|
||||||
|
insert.push({ char: ")", offset: node.end });
|
||||||
|
}
|
||||||
|
Object.keys(node).forEach(function (key) { return descend(key); });
|
||||||
|
};
|
||||||
|
descend(ast);
|
||||||
|
// We make modifications from back to front, so we don't need
|
||||||
|
// to adjust offsets
|
||||||
|
insert.sort(function (a, b) { return (b.offset - a.offset); });
|
||||||
|
// Modify the code for REPL
|
||||||
|
insert.forEach(function (mod) {
|
||||||
|
code = code.substring(0, mod.offset) + mod.char + code.substring(mod.offset);
|
||||||
|
});
|
||||||
|
return code;
|
||||||
|
}
|
||||||
var SandboxPlugin = /** @class */ (function (_super) {
|
var SandboxPlugin = /** @class */ (function (_super) {
|
||||||
__extends(SandboxPlugin, _super);
|
__extends(SandboxPlugin, _super);
|
||||||
function SandboxPlugin() {
|
function SandboxPlugin() {
|
||||||
@ -166,33 +208,59 @@ var SandboxPlugin = /** @class */ (function (_super) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
SandboxPlugin.prototype.run = function () {
|
SandboxPlugin.prototype.run = function () {
|
||||||
|
console.log("version: " + ethers_1.ethers.version);
|
||||||
console.log("network: " + this.network.name + " (chainId: " + this.network.chainId + ")");
|
console.log("network: " + this.network.name + " (chainId: " + this.network.chainId + ")");
|
||||||
var nextPromiseId = 0;
|
var filename = path_1.resolve(process.cwd(), "./sandbox.js");
|
||||||
function promiseWriter(output) {
|
var prompt = (this.provider ? this.network.name : "no-network") + "> ";
|
||||||
if (output instanceof Promise) {
|
var evaluate = function (code, context, file, _callback) {
|
||||||
repl.context._p = output;
|
// Pausing the stdin (which prompt does when it leaves), causes
|
||||||
var promiseId_1 = nextPromiseId++;
|
// readline to end us. So, we always re-enable stdin on a result
|
||||||
output.then(function (result) {
|
var callback = function (error, result) {
|
||||||
console.log("\n<Promise id=" + promiseId_1 + " resolved>");
|
_callback(error, result);
|
||||||
console.log(util_1.default.inspect(result));
|
process.stdin.resume();
|
||||||
repl.context._r = result;
|
};
|
||||||
repl.displayPrompt(true);
|
try {
|
||||||
|
code = prepareCode(code);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
if (error instanceof SyntaxError) {
|
||||||
|
var leftover = code.substring(error.pos);
|
||||||
|
var loc = error.loc;
|
||||||
|
if (leftover.trim()) {
|
||||||
|
// After the first line, the prompt is "... "
|
||||||
|
console.log(repeat("-", ((loc.line === 1) ? prompt.length : 4) + loc.column - 1) + "^");
|
||||||
|
console.log("Syntax Error! " + error.message);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error = new repl_1.default.Recoverable(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return callback(error);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var result = vm_1.default.runInContext(code, context, {
|
||||||
|
filename: filename
|
||||||
|
});
|
||||||
|
if (result instanceof Promise) {
|
||||||
|
result.then(function (result) {
|
||||||
|
callback(null, result);
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
console.log("\n<Promise id=" + promiseId_1 + " rejected>");
|
callback(error);
|
||||||
console.log(util_1.default.inspect(error));
|
|
||||||
repl.displayPrompt(true);
|
|
||||||
});
|
});
|
||||||
return "<Promise id=" + promiseId_1 + " pending>";
|
|
||||||
}
|
}
|
||||||
return util_1.default.inspect(output);
|
else {
|
||||||
|
callback(null, result);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
callback(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
var repl = repl_1.default.start({
|
var repl = repl_1.default.start({
|
||||||
input: process.stdin,
|
prompt: prompt,
|
||||||
output: process.stdout,
|
eval: evaluate
|
||||||
prompt: (this.provider ? this.network.name : "no-network") + "> ",
|
|
||||||
writer: promiseWriter
|
|
||||||
});
|
});
|
||||||
setupContext(path_1.resolve(process.cwd(), "./sandbox.js"), repl.context, this);
|
setupContext(filename, repl.context, this);
|
||||||
return new Promise(function (resolve) {
|
return new Promise(function (resolve) {
|
||||||
repl.on("exit", function () {
|
repl.on("exit", function () {
|
||||||
console.log("");
|
console.log("");
|
||||||
|
2
packages/cli/lib/cli.d.ts
vendored
2
packages/cli/lib/cli.d.ts
vendored
@ -39,7 +39,7 @@ export interface PluginType {
|
|||||||
export declare abstract class Plugin {
|
export declare abstract class Plugin {
|
||||||
network: ethers.providers.Network;
|
network: ethers.providers.Network;
|
||||||
provider: ethers.providers.Provider;
|
provider: ethers.providers.Provider;
|
||||||
accounts: Array<WrappedSigner>;
|
accounts: ReadonlyArray<WrappedSigner>;
|
||||||
mnemonicPassword: boolean;
|
mnemonicPassword: boolean;
|
||||||
_xxxMnemonicPasswordHard: boolean;
|
_xxxMnemonicPasswordHard: boolean;
|
||||||
gasLimit: ethers.BigNumber;
|
gasLimit: ethers.BigNumber;
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "7.8.4",
|
"@babel/parser": "7.8.4",
|
||||||
|
"@babel/types": "7.8.3",
|
||||||
"@ethersproject/asm": ">=5.0.0-beta.148",
|
"@ethersproject/asm": ">=5.0.0-beta.148",
|
||||||
"@ethersproject/basex": ">=5.0.0-beta.127",
|
"@ethersproject/basex": ">=5.0.0-beta.127",
|
||||||
"ethers": ">=5.0.0-beta.156",
|
"ethers": ">=5.0.0-beta.156",
|
||||||
@ -40,7 +41,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "exit 1"
|
"test": "exit 1"
|
||||||
},
|
},
|
||||||
"tarballHash": "0xf20ecfe28643c5e68c573b3204e4a03e02494722929d2fa2467d800ef0ff6edb",
|
"tarballHash": "0xf7cdf17b34ec310a5d6e2f93116a70787764532f9c9a11d7dcb5484ed44d731d",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"version": "5.0.0-beta.150"
|
"version": "5.0.0-beta.151"
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
export const version = "cli/5.0.0-beta.150";
|
export const version = "cli/5.0.0-beta.151";
|
||||||
|
@ -180,6 +180,8 @@ class AssemblePlugin extends Plugin {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,9 @@ function setupContext(path: string, context: any, plugin: Plugin) {
|
|||||||
context.getIcapAddress = ethers.utils.getIcapAddress;
|
context.getIcapAddress = ethers.utils.getIcapAddress;
|
||||||
|
|
||||||
context.arrayify = ethers.utils.arrayify;
|
context.arrayify = ethers.utils.arrayify;
|
||||||
|
context.concat = ethers.utils.concat;
|
||||||
context.hexlify = ethers.utils.hexlify;
|
context.hexlify = ethers.utils.hexlify;
|
||||||
|
context.zeroPad = ethers.utils.zeroPad;
|
||||||
|
|
||||||
context.joinSignature = ethers.utils.joinSignature;
|
context.joinSignature = ethers.utils.joinSignature;
|
||||||
context.splitSignature = ethers.utils.splitSignature;
|
context.splitSignature = ethers.utils.splitSignature;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
import { EventFragment, Fragment, Indexed, Interface, JsonFragment, ParamType, Result } from "@ethersproject/abi";
|
import { EventFragment, Fragment, Indexed, Interface, JsonFragment, ParamType, Result } from "@ethersproject/abi";
|
||||||
import { Block, BlockTag, Listener, Log, Provider, TransactionReceipt, TransactionRequest, TransactionResponse } from "@ethersproject/abstract-provider";
|
import { Block, BlockTag, Filter, FilterByBlockHash, Listener, Log, Provider, TransactionReceipt, TransactionRequest, TransactionResponse } from "@ethersproject/abstract-provider";
|
||||||
import { Signer, VoidSigner } from "@ethersproject/abstract-signer";
|
import { Signer, VoidSigner } from "@ethersproject/abstract-signer";
|
||||||
import { getContractAddress } from "@ethersproject/address";
|
import { getContractAddress } from "@ethersproject/address";
|
||||||
import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
|
import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
|
||||||
@ -780,10 +780,10 @@ export class Contract {
|
|||||||
if (toBlock != null) {
|
if (toBlock != null) {
|
||||||
logger.throwArgumentError("cannot specify toBlock with blockhash", "toBlock", toBlock);
|
logger.throwArgumentError("cannot specify toBlock with blockhash", "toBlock", toBlock);
|
||||||
}
|
}
|
||||||
filter.blockhash = fromBlockOrBlockhash;
|
(<FilterByBlockHash>filter).blockhash = fromBlockOrBlockhash;
|
||||||
} else {
|
} else {
|
||||||
filter.fromBlock = ((fromBlockOrBlockhash != null) ? fromBlockOrBlockhash: 0);
|
(<Filter>filter).fromBlock = ((fromBlockOrBlockhash != null) ? fromBlockOrBlockhash: 0);
|
||||||
filter.toBlock = ((toBlock != null) ? toBlock: "latest");
|
(<Filter>filter).toBlock = ((toBlock != null) ? toBlock: "latest");
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.provider.getLogs(filter).then((logs) => {
|
return this.provider.getLogs(filter).then((logs) => {
|
||||||
|
4
packages/ethers/dist/ethers-all.esm.min.js
vendored
4
packages/ethers/dist/ethers-all.esm.min.js
vendored
File diff suppressed because one or more lines are too long
4
packages/ethers/dist/ethers-all.umd.min.js
vendored
4
packages/ethers/dist/ethers-all.umd.min.js
vendored
File diff suppressed because one or more lines are too long
43
packages/ethers/dist/ethers.esm.js
vendored
43
packages/ethers/dist/ethers.esm.js
vendored
@ -4629,7 +4629,7 @@ class FixedNumber {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const version$3 = "properties/5.0.0-beta.136";
|
const version$3 = "properties/5.0.0-beta.137";
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
const logger$3 = new Logger(version$3);
|
const logger$3 = new Logger(version$3);
|
||||||
@ -4665,10 +4665,10 @@ function resolveProperties(object) {
|
|||||||
});
|
});
|
||||||
return Promise.all(promises).then((results) => {
|
return Promise.all(promises).then((results) => {
|
||||||
const result = {};
|
const result = {};
|
||||||
return results.reduce((accum, result) => {
|
return (results.reduce((accum, result) => {
|
||||||
accum[result.key] = result.value;
|
accum[result.key] = result.value;
|
||||||
return accum;
|
return accum;
|
||||||
}, result);
|
}, result));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function checkProperties(object, properties) {
|
function checkProperties(object, properties) {
|
||||||
@ -4691,7 +4691,7 @@ function shallowCopy(object) {
|
|||||||
const opaque = { bigint: true, boolean: true, number: true, string: true };
|
const opaque = { bigint: true, boolean: true, number: true, string: true };
|
||||||
// Returns a new copy of object, such that no properties may be replaced.
|
// Returns a new copy of object, such that no properties may be replaced.
|
||||||
// New properties may be added only to objects.
|
// New properties may be added only to objects.
|
||||||
function deepCopy(object) {
|
function _deepCopy(object) {
|
||||||
// Opaque objects are not mutable, so safe to copy by assignment
|
// Opaque objects are not mutable, so safe to copy by assignment
|
||||||
if (object === undefined || object === null || opaque[typeof (object)]) {
|
if (object === undefined || object === null || opaque[typeof (object)]) {
|
||||||
return object;
|
return object;
|
||||||
@ -4719,7 +4719,10 @@ function deepCopy(object) {
|
|||||||
if (typeof (object) === "function") {
|
if (typeof (object) === "function") {
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
throw new Error("Cannot deepCopy " + typeof (object));
|
logger$3.throwArgumentError(`Cannot deepCopy ${typeof (object)}`, "object", object);
|
||||||
|
}
|
||||||
|
function deepCopy(object) {
|
||||||
|
return _deepCopy(object);
|
||||||
}
|
}
|
||||||
class Description {
|
class Description {
|
||||||
constructor(info) {
|
constructor(info) {
|
||||||
@ -4739,7 +4742,7 @@ var lib_esm$2 = /*#__PURE__*/Object.freeze({
|
|||||||
Description: Description
|
Description: Description
|
||||||
});
|
});
|
||||||
|
|
||||||
const version$4 = "abi/5.0.0-beta.144";
|
const version$4 = "abi/5.0.0-beta.145";
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
const logger$4 = new Logger(version$4);
|
const logger$4 = new Logger(version$4);
|
||||||
@ -7715,7 +7718,7 @@ class Provider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const version$9 = "abstract-signer/5.0.0-beta.139";
|
const version$9 = "abstract-signer/5.0.0-beta.140";
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
var __awaiter = (window && window.__awaiter) || function (thisArg, _arguments, P, generator) {
|
var __awaiter = (window && window.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
@ -7838,25 +7841,9 @@ class Signer {
|
|||||||
if (tx.nonce == null) {
|
if (tx.nonce == null) {
|
||||||
tx.nonce = this.getTransactionCount("pending");
|
tx.nonce = this.getTransactionCount("pending");
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
// checkTransaction does this...
|
|
||||||
if (tx.from == null) {
|
|
||||||
tx.from = this.getAddress();
|
|
||||||
} else {
|
|
||||||
tx.from = Promise.all([
|
|
||||||
this.getAddress(),
|
|
||||||
this.provider.resolveName(tx.from)
|
|
||||||
]).then((results) => {
|
|
||||||
if (results[0] !== results[1]) {
|
|
||||||
logger.throwArgumentError("from address mismatch", "transaction", transaction);
|
|
||||||
}
|
|
||||||
return results[0];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if (tx.gasLimit == null) {
|
if (tx.gasLimit == null) {
|
||||||
tx.gasLimit = this.estimateGas(tx).catch((error) => {
|
tx.gasLimit = this.estimateGas(tx).catch((error) => {
|
||||||
logger$d.throwError("cannot estimate gas; transaction may fail or may require manual gas limit", Logger.errors.UNPREDICTABLE_GAS_LIMIT, {
|
return logger$d.throwError("cannot estimate gas; transaction may fail or may require manual gas limit", Logger.errors.UNPREDICTABLE_GAS_LIMIT, {
|
||||||
tx: tx
|
tx: tx
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -15111,7 +15098,7 @@ function decryptJsonWallet(json, password, progressCallback) {
|
|||||||
return Promise.reject(new Error("invalid JSON wallet"));
|
return Promise.reject(new Error("invalid JSON wallet"));
|
||||||
}
|
}
|
||||||
|
|
||||||
const version$g = "wallet/5.0.0-beta.136";
|
const version$g = "wallet/5.0.0-beta.137";
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
const logger$k = new Logger(version$g);
|
const logger$k = new Logger(version$g);
|
||||||
@ -15148,7 +15135,6 @@ class Wallet extends Signer {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
defineReadOnly(this, "_mnemonic", () => null);
|
defineReadOnly(this, "_mnemonic", () => null);
|
||||||
defineReadOnly(this, "path", null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -15163,7 +15149,6 @@ class Wallet extends Signer {
|
|||||||
defineReadOnly(this, "_signingKey", () => signingKey);
|
defineReadOnly(this, "_signingKey", () => signingKey);
|
||||||
}
|
}
|
||||||
defineReadOnly(this, "_mnemonic", () => null);
|
defineReadOnly(this, "_mnemonic", () => null);
|
||||||
defineReadOnly(this, "path", null);
|
|
||||||
defineReadOnly(this, "address", computeAddress(this.publicKey));
|
defineReadOnly(this, "address", computeAddress(this.publicKey));
|
||||||
}
|
}
|
||||||
if (provider && !Provider.isProvider(provider)) {
|
if (provider && !Provider.isProvider(provider)) {
|
||||||
@ -16265,7 +16250,7 @@ function poll(func, options) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const version$j = "providers/5.0.0-beta.152";
|
const version$j = "providers/5.0.0-beta.153";
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
const logger$n = new Logger(version$j);
|
const logger$n = new Logger(version$j);
|
||||||
@ -19362,7 +19347,7 @@ var utils$1 = /*#__PURE__*/Object.freeze({
|
|||||||
Indexed: Indexed
|
Indexed: Indexed
|
||||||
});
|
});
|
||||||
|
|
||||||
const version$l = "ethers/5.0.0-beta.172";
|
const version$l = "ethers/5.0.0-beta.173";
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
const errors = Logger.errors;
|
const errors = Logger.errors;
|
||||||
|
4
packages/ethers/dist/ethers.esm.min.js
vendored
4
packages/ethers/dist/ethers.esm.min.js
vendored
File diff suppressed because one or more lines are too long
43
packages/ethers/dist/ethers.umd.js
vendored
43
packages/ethers/dist/ethers.umd.js
vendored
@ -4757,7 +4757,7 @@
|
|||||||
var _version$6 = createCommonjsModule(function (module, exports) {
|
var _version$6 = createCommonjsModule(function (module, exports) {
|
||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.version = "properties/5.0.0-beta.136";
|
exports.version = "properties/5.0.0-beta.137";
|
||||||
});
|
});
|
||||||
|
|
||||||
var _version$7 = unwrapExports(_version$6);
|
var _version$7 = unwrapExports(_version$6);
|
||||||
@ -4803,10 +4803,10 @@
|
|||||||
});
|
});
|
||||||
return Promise.all(promises).then(function (results) {
|
return Promise.all(promises).then(function (results) {
|
||||||
var result = {};
|
var result = {};
|
||||||
return results.reduce(function (accum, result) {
|
return (results.reduce(function (accum, result) {
|
||||||
accum[result.key] = result.value;
|
accum[result.key] = result.value;
|
||||||
return accum;
|
return accum;
|
||||||
}, result);
|
}, result));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.resolveProperties = resolveProperties;
|
exports.resolveProperties = resolveProperties;
|
||||||
@ -4832,7 +4832,7 @@
|
|||||||
var opaque = { bigint: true, boolean: true, number: true, string: true };
|
var opaque = { bigint: true, boolean: true, number: true, string: true };
|
||||||
// Returns a new copy of object, such that no properties may be replaced.
|
// Returns a new copy of object, such that no properties may be replaced.
|
||||||
// New properties may be added only to objects.
|
// New properties may be added only to objects.
|
||||||
function deepCopy(object) {
|
function _deepCopy(object) {
|
||||||
// Opaque objects are not mutable, so safe to copy by assignment
|
// Opaque objects are not mutable, so safe to copy by assignment
|
||||||
if (object === undefined || object === null || opaque[typeof (object)]) {
|
if (object === undefined || object === null || opaque[typeof (object)]) {
|
||||||
return object;
|
return object;
|
||||||
@ -4860,7 +4860,10 @@
|
|||||||
if (typeof (object) === "function") {
|
if (typeof (object) === "function") {
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
throw new Error("Cannot deepCopy " + typeof (object));
|
logger.throwArgumentError("Cannot deepCopy " + typeof (object), "object", object);
|
||||||
|
}
|
||||||
|
function deepCopy(object) {
|
||||||
|
return _deepCopy(object);
|
||||||
}
|
}
|
||||||
exports.deepCopy = deepCopy;
|
exports.deepCopy = deepCopy;
|
||||||
var Description = /** @class */ (function () {
|
var Description = /** @class */ (function () {
|
||||||
@ -4886,7 +4889,7 @@
|
|||||||
var _version$8 = createCommonjsModule(function (module, exports) {
|
var _version$8 = createCommonjsModule(function (module, exports) {
|
||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.version = "abi/5.0.0-beta.144";
|
exports.version = "abi/5.0.0-beta.145";
|
||||||
});
|
});
|
||||||
|
|
||||||
var _version$9 = unwrapExports(_version$8);
|
var _version$9 = unwrapExports(_version$8);
|
||||||
@ -8545,7 +8548,7 @@
|
|||||||
var _version$i = createCommonjsModule(function (module, exports) {
|
var _version$i = createCommonjsModule(function (module, exports) {
|
||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.version = "abstract-signer/5.0.0-beta.139";
|
exports.version = "abstract-signer/5.0.0-beta.140";
|
||||||
});
|
});
|
||||||
|
|
||||||
var _version$j = unwrapExports(_version$i);
|
var _version$j = unwrapExports(_version$i);
|
||||||
@ -8727,25 +8730,9 @@
|
|||||||
if (tx.nonce == null) {
|
if (tx.nonce == null) {
|
||||||
tx.nonce = this.getTransactionCount("pending");
|
tx.nonce = this.getTransactionCount("pending");
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
// checkTransaction does this...
|
|
||||||
if (tx.from == null) {
|
|
||||||
tx.from = this.getAddress();
|
|
||||||
} else {
|
|
||||||
tx.from = Promise.all([
|
|
||||||
this.getAddress(),
|
|
||||||
this.provider.resolveName(tx.from)
|
|
||||||
]).then((results) => {
|
|
||||||
if (results[0] !== results[1]) {
|
|
||||||
logger.throwArgumentError("from address mismatch", "transaction", transaction);
|
|
||||||
}
|
|
||||||
return results[0];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if (tx.gasLimit == null) {
|
if (tx.gasLimit == null) {
|
||||||
tx.gasLimit = this.estimateGas(tx).catch(function (error) {
|
tx.gasLimit = this.estimateGas(tx).catch(function (error) {
|
||||||
logger.throwError("cannot estimate gas; transaction may fail or may require manual gas limit", lib.Logger.errors.UNPREDICTABLE_GAS_LIMIT, {
|
return logger.throwError("cannot estimate gas; transaction may fail or may require manual gas limit", lib.Logger.errors.UNPREDICTABLE_GAS_LIMIT, {
|
||||||
tx: tx
|
tx: tx
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -16414,7 +16401,7 @@
|
|||||||
var _version$A = createCommonjsModule(function (module, exports) {
|
var _version$A = createCommonjsModule(function (module, exports) {
|
||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.version = "wallet/5.0.0-beta.136";
|
exports.version = "wallet/5.0.0-beta.137";
|
||||||
});
|
});
|
||||||
|
|
||||||
var _version$B = unwrapExports(_version$A);
|
var _version$B = unwrapExports(_version$A);
|
||||||
@ -16487,7 +16474,6 @@
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lib$3.defineReadOnly(_this, "_mnemonic", function () { return null; });
|
lib$3.defineReadOnly(_this, "_mnemonic", function () { return null; });
|
||||||
lib$3.defineReadOnly(_this, "path", null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -16502,7 +16488,6 @@
|
|||||||
lib$3.defineReadOnly(_this, "_signingKey", function () { return signingKey_2; });
|
lib$3.defineReadOnly(_this, "_signingKey", function () { return signingKey_2; });
|
||||||
}
|
}
|
||||||
lib$3.defineReadOnly(_this, "_mnemonic", function () { return null; });
|
lib$3.defineReadOnly(_this, "_mnemonic", function () { return null; });
|
||||||
lib$3.defineReadOnly(_this, "path", null);
|
|
||||||
lib$3.defineReadOnly(_this, "address", lib$g.computeAddress(_this.publicKey));
|
lib$3.defineReadOnly(_this, "address", lib$g.computeAddress(_this.publicKey));
|
||||||
}
|
}
|
||||||
if (provider && !lib$b.Provider.isProvider(provider)) {
|
if (provider && !lib$b.Provider.isProvider(provider)) {
|
||||||
@ -17710,7 +17695,7 @@
|
|||||||
var _version$G = createCommonjsModule(function (module, exports) {
|
var _version$G = createCommonjsModule(function (module, exports) {
|
||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.version = "providers/5.0.0-beta.152";
|
exports.version = "providers/5.0.0-beta.153";
|
||||||
});
|
});
|
||||||
|
|
||||||
var _version$H = unwrapExports(_version$G);
|
var _version$H = unwrapExports(_version$G);
|
||||||
@ -21875,7 +21860,7 @@
|
|||||||
var _version$K = createCommonjsModule(function (module, exports) {
|
var _version$K = createCommonjsModule(function (module, exports) {
|
||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.version = "ethers/5.0.0-beta.172";
|
exports.version = "ethers/5.0.0-beta.173";
|
||||||
});
|
});
|
||||||
|
|
||||||
var _version$L = unwrapExports(_version$K);
|
var _version$L = unwrapExports(_version$K);
|
||||||
|
4
packages/ethers/dist/ethers.umd.min.js
vendored
4
packages/ethers/dist/ethers.umd.min.js
vendored
File diff suppressed because one or more lines are too long
2
packages/ethers/lib.esm/_version.d.ts
vendored
2
packages/ethers/lib.esm/_version.d.ts
vendored
@ -1 +1 @@
|
|||||||
export declare const version = "ethers/5.0.0-beta.172";
|
export declare const version = "ethers/5.0.0-beta.173";
|
||||||
|
@ -1 +1 @@
|
|||||||
export const version = "ethers/5.0.0-beta.172";
|
export const version = "ethers/5.0.0-beta.173";
|
||||||
|
3
packages/ethers/lib.esm/utils.d.ts
vendored
3
packages/ethers/lib.esm/utils.d.ts
vendored
@ -20,10 +20,11 @@ import { verifyMessage } from "@ethersproject/wallet";
|
|||||||
import { fetchJson, poll } from "@ethersproject/web";
|
import { fetchJson, poll } from "@ethersproject/web";
|
||||||
import { SupportedAlgorithm } from "@ethersproject/sha2";
|
import { SupportedAlgorithm } from "@ethersproject/sha2";
|
||||||
import { UnicodeNormalizationForm, Utf8ErrorReason } from "@ethersproject/strings";
|
import { UnicodeNormalizationForm, Utf8ErrorReason } from "@ethersproject/strings";
|
||||||
|
import { UnsignedTransaction } from "@ethersproject/transactions";
|
||||||
import { CoerceFunc } from "@ethersproject/abi";
|
import { CoerceFunc } from "@ethersproject/abi";
|
||||||
import { Bytes, BytesLike, Hexable } from "@ethersproject/bytes";
|
import { Bytes, BytesLike, Hexable } from "@ethersproject/bytes";
|
||||||
import { Mnemonic } from "@ethersproject/hdnode";
|
import { Mnemonic } from "@ethersproject/hdnode";
|
||||||
import { EncryptOptions, ProgressCallback } from "@ethersproject/json-wallets";
|
import { EncryptOptions, ProgressCallback } from "@ethersproject/json-wallets";
|
||||||
import { Utf8ErrorFunc } from "@ethersproject/strings";
|
import { Utf8ErrorFunc } from "@ethersproject/strings";
|
||||||
import { ConnectionInfo, FetchJsonResponse, OnceBlockable, PollOptions } from "@ethersproject/web";
|
import { ConnectionInfo, FetchJsonResponse, OnceBlockable, PollOptions } from "@ethersproject/web";
|
||||||
export { AbiCoder, defaultAbiCoder, Fragment, EventFragment, FunctionFragment, ParamType, FormatTypes, Logger, RLP, fetchJson, poll, checkProperties, deepCopy, defineReadOnly, getStatic, resolveProperties, shallowCopy, arrayify, concat, stripZeros, zeroPad, isBytes, isBytesLike, defaultPath, HDNode, SigningKey, Interface, base64, hexlify, isHexString, hexStripZeros, hexValue, hexZeroPad, hexDataLength, hexDataSlice, nameprep, _toEscapedUtf8String, toUtf8Bytes, toUtf8CodePoints, toUtf8String, Utf8ErrorFuncs, formatBytes32String, parseBytes32String, hashMessage, namehash, isValidName, id, getAddress, getIcapAddress, getContractAddress, getCreate2Address, isAddress, formatEther, parseEther, formatUnits, parseUnits, commify, keccak256, sha256, randomBytes, solidityPack, solidityKeccak256, soliditySha256, splitSignature, joinSignature, parseTransaction, serializeTransaction, getJsonWalletAddress, computeAddress, recoverAddress, computePublicKey, recoverPublicKey, verifyMessage, mnemonicToEntropy, entropyToMnemonic, isValidMnemonic, mnemonicToSeed, SupportedAlgorithm, UnicodeNormalizationForm, Utf8ErrorReason, Bytes, BytesLike, Hexable, CoerceFunc, Indexed, Mnemonic, Utf8ErrorFunc, ConnectionInfo, OnceBlockable, PollOptions, FetchJsonResponse, EncryptOptions, ProgressCallback };
|
export { AbiCoder, defaultAbiCoder, Fragment, EventFragment, FunctionFragment, ParamType, FormatTypes, Logger, RLP, fetchJson, poll, checkProperties, deepCopy, defineReadOnly, getStatic, resolveProperties, shallowCopy, arrayify, concat, stripZeros, zeroPad, isBytes, isBytesLike, defaultPath, HDNode, SigningKey, Interface, base64, hexlify, isHexString, hexStripZeros, hexValue, hexZeroPad, hexDataLength, hexDataSlice, nameprep, _toEscapedUtf8String, toUtf8Bytes, toUtf8CodePoints, toUtf8String, Utf8ErrorFuncs, formatBytes32String, parseBytes32String, hashMessage, namehash, isValidName, id, getAddress, getIcapAddress, getContractAddress, getCreate2Address, isAddress, formatEther, parseEther, formatUnits, parseUnits, commify, keccak256, sha256, randomBytes, solidityPack, solidityKeccak256, soliditySha256, splitSignature, joinSignature, parseTransaction, serializeTransaction, getJsonWalletAddress, computeAddress, recoverAddress, computePublicKey, recoverPublicKey, verifyMessage, mnemonicToEntropy, entropyToMnemonic, isValidMnemonic, mnemonicToSeed, SupportedAlgorithm, UnicodeNormalizationForm, Utf8ErrorReason, Bytes, BytesLike, Hexable, UnsignedTransaction, CoerceFunc, Indexed, Mnemonic, Utf8ErrorFunc, ConnectionInfo, OnceBlockable, PollOptions, FetchJsonResponse, EncryptOptions, ProgressCallback };
|
||||||
|
2
packages/ethers/lib/_version.d.ts
vendored
2
packages/ethers/lib/_version.d.ts
vendored
@ -1 +1 @@
|
|||||||
export declare const version = "ethers/5.0.0-beta.172";
|
export declare const version = "ethers/5.0.0-beta.173";
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.version = "ethers/5.0.0-beta.172";
|
exports.version = "ethers/5.0.0-beta.173";
|
||||||
|
3
packages/ethers/lib/utils.d.ts
vendored
3
packages/ethers/lib/utils.d.ts
vendored
@ -20,10 +20,11 @@ import { verifyMessage } from "@ethersproject/wallet";
|
|||||||
import { fetchJson, poll } from "@ethersproject/web";
|
import { fetchJson, poll } from "@ethersproject/web";
|
||||||
import { SupportedAlgorithm } from "@ethersproject/sha2";
|
import { SupportedAlgorithm } from "@ethersproject/sha2";
|
||||||
import { UnicodeNormalizationForm, Utf8ErrorReason } from "@ethersproject/strings";
|
import { UnicodeNormalizationForm, Utf8ErrorReason } from "@ethersproject/strings";
|
||||||
|
import { UnsignedTransaction } from "@ethersproject/transactions";
|
||||||
import { CoerceFunc } from "@ethersproject/abi";
|
import { CoerceFunc } from "@ethersproject/abi";
|
||||||
import { Bytes, BytesLike, Hexable } from "@ethersproject/bytes";
|
import { Bytes, BytesLike, Hexable } from "@ethersproject/bytes";
|
||||||
import { Mnemonic } from "@ethersproject/hdnode";
|
import { Mnemonic } from "@ethersproject/hdnode";
|
||||||
import { EncryptOptions, ProgressCallback } from "@ethersproject/json-wallets";
|
import { EncryptOptions, ProgressCallback } from "@ethersproject/json-wallets";
|
||||||
import { Utf8ErrorFunc } from "@ethersproject/strings";
|
import { Utf8ErrorFunc } from "@ethersproject/strings";
|
||||||
import { ConnectionInfo, FetchJsonResponse, OnceBlockable, PollOptions } from "@ethersproject/web";
|
import { ConnectionInfo, FetchJsonResponse, OnceBlockable, PollOptions } from "@ethersproject/web";
|
||||||
export { AbiCoder, defaultAbiCoder, Fragment, EventFragment, FunctionFragment, ParamType, FormatTypes, Logger, RLP, fetchJson, poll, checkProperties, deepCopy, defineReadOnly, getStatic, resolveProperties, shallowCopy, arrayify, concat, stripZeros, zeroPad, isBytes, isBytesLike, defaultPath, HDNode, SigningKey, Interface, base64, hexlify, isHexString, hexStripZeros, hexValue, hexZeroPad, hexDataLength, hexDataSlice, nameprep, _toEscapedUtf8String, toUtf8Bytes, toUtf8CodePoints, toUtf8String, Utf8ErrorFuncs, formatBytes32String, parseBytes32String, hashMessage, namehash, isValidName, id, getAddress, getIcapAddress, getContractAddress, getCreate2Address, isAddress, formatEther, parseEther, formatUnits, parseUnits, commify, keccak256, sha256, randomBytes, solidityPack, solidityKeccak256, soliditySha256, splitSignature, joinSignature, parseTransaction, serializeTransaction, getJsonWalletAddress, computeAddress, recoverAddress, computePublicKey, recoverPublicKey, verifyMessage, mnemonicToEntropy, entropyToMnemonic, isValidMnemonic, mnemonicToSeed, SupportedAlgorithm, UnicodeNormalizationForm, Utf8ErrorReason, Bytes, BytesLike, Hexable, CoerceFunc, Indexed, Mnemonic, Utf8ErrorFunc, ConnectionInfo, OnceBlockable, PollOptions, FetchJsonResponse, EncryptOptions, ProgressCallback };
|
export { AbiCoder, defaultAbiCoder, Fragment, EventFragment, FunctionFragment, ParamType, FormatTypes, Logger, RLP, fetchJson, poll, checkProperties, deepCopy, defineReadOnly, getStatic, resolveProperties, shallowCopy, arrayify, concat, stripZeros, zeroPad, isBytes, isBytesLike, defaultPath, HDNode, SigningKey, Interface, base64, hexlify, isHexString, hexStripZeros, hexValue, hexZeroPad, hexDataLength, hexDataSlice, nameprep, _toEscapedUtf8String, toUtf8Bytes, toUtf8CodePoints, toUtf8String, Utf8ErrorFuncs, formatBytes32String, parseBytes32String, hashMessage, namehash, isValidName, id, getAddress, getIcapAddress, getContractAddress, getCreate2Address, isAddress, formatEther, parseEther, formatUnits, parseUnits, commify, keccak256, sha256, randomBytes, solidityPack, solidityKeccak256, soliditySha256, splitSignature, joinSignature, parseTransaction, serializeTransaction, getJsonWalletAddress, computeAddress, recoverAddress, computePublicKey, recoverPublicKey, verifyMessage, mnemonicToEntropy, entropyToMnemonic, isValidMnemonic, mnemonicToSeed, SupportedAlgorithm, UnicodeNormalizationForm, Utf8ErrorReason, Bytes, BytesLike, Hexable, UnsignedTransaction, CoerceFunc, Indexed, Mnemonic, Utf8ErrorFunc, ConnectionInfo, OnceBlockable, PollOptions, FetchJsonResponse, EncryptOptions, ProgressCallback };
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"tarballHash": "0x8bf3df33da732d3a07a569560633f98fd9b7826cfc306fb4f3c159f98873b29c",
|
"tarballHash": "0x6eba00cc347e154a1bacd6b073af290f2da00b3e1e0b06e4ea342d94940832be",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"version": "5.0.0-beta.172"
|
"version": "5.0.0-beta.173"
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
export const version = "ethers/5.0.0-beta.172";
|
export const version = "ethers/5.0.0-beta.173";
|
||||||
|
@ -26,7 +26,7 @@ import { fetchJson, poll } from "@ethersproject/web";
|
|||||||
|
|
||||||
import { SupportedAlgorithm } from "@ethersproject/sha2";
|
import { SupportedAlgorithm } from "@ethersproject/sha2";
|
||||||
import { UnicodeNormalizationForm, Utf8ErrorReason } from "@ethersproject/strings";
|
import { UnicodeNormalizationForm, Utf8ErrorReason } from "@ethersproject/strings";
|
||||||
|
import { UnsignedTransaction } from "@ethersproject/transactions";
|
||||||
|
|
||||||
////////////////////////
|
////////////////////////
|
||||||
// Types and Interfaces
|
// Types and Interfaces
|
||||||
@ -165,6 +165,8 @@ export {
|
|||||||
BytesLike,
|
BytesLike,
|
||||||
Hexable,
|
Hexable,
|
||||||
|
|
||||||
|
UnsignedTransaction,
|
||||||
|
|
||||||
CoerceFunc,
|
CoerceFunc,
|
||||||
|
|
||||||
Indexed,
|
Indexed,
|
||||||
|
@ -95,11 +95,11 @@ export class LedgerSigner extends ethers.Signer {
|
|||||||
|
|
||||||
async signTransaction(transaction: ethers.providers.TransactionRequest): Promise<string> {
|
async signTransaction(transaction: ethers.providers.TransactionRequest): Promise<string> {
|
||||||
const tx = transaction = await ethers.utils.resolveProperties(transaction);
|
const tx = transaction = await ethers.utils.resolveProperties(transaction);
|
||||||
const unsignedTx = ethers.utils.serializeTransaction(tx).substring(2);
|
const unsignedTx = ethers.utils.serializeTransaction(<ethers.utils.UnsignedTransaction>tx).substring(2);
|
||||||
|
|
||||||
const sig = await this._retry((eth) => eth.signTransaction(this.path, unsignedTx));
|
const sig = await this._retry((eth) => eth.signTransaction(this.path, unsignedTx));
|
||||||
|
|
||||||
return ethers.utils.serializeTransaction(tx, {
|
return ethers.utils.serializeTransaction(<ethers.utils.UnsignedTransaction>tx, {
|
||||||
v: sig.v,
|
v: sig.v,
|
||||||
r: ("0x" + sig.r),
|
r: ("0x" + sig.r),
|
||||||
s: ("0x" + sig.s),
|
s: ("0x" + sig.s),
|
||||||
|
2
packages/properties/lib.esm/_version.d.ts
vendored
2
packages/properties/lib.esm/_version.d.ts
vendored
@ -1 +1 @@
|
|||||||
export declare const version = "properties/5.0.0-beta.136";
|
export declare const version = "properties/5.0.0-beta.137";
|
||||||
|
@ -1 +1 @@
|
|||||||
export const version = "properties/5.0.0-beta.136";
|
export const version = "properties/5.0.0-beta.137";
|
||||||
|
14
packages/properties/lib.esm/index.d.ts
vendored
14
packages/properties/lib.esm/index.d.ts
vendored
@ -1,11 +1,17 @@
|
|||||||
export declare function defineReadOnly(object: any, name: string, value: any): void;
|
export declare function defineReadOnly<T, K extends keyof T>(object: T, name: K, value: T[K]): void;
|
||||||
export declare function getStatic<T>(ctor: any, key: string): T;
|
export declare function getStatic<T>(ctor: any, key: string): T;
|
||||||
export declare function resolveProperties(object: any): Promise<any>;
|
export declare type Similar<T> = {
|
||||||
|
[P in keyof T]: T[P];
|
||||||
|
};
|
||||||
|
export declare type Resolvable<T> = {
|
||||||
|
[P in keyof T]: T[P] | Promise<T[P]>;
|
||||||
|
};
|
||||||
|
export declare function resolveProperties<T>(object: Resolvable<T>): Promise<Similar<T>>;
|
||||||
export declare function checkProperties(object: any, properties: {
|
export declare function checkProperties(object: any, properties: {
|
||||||
[name: string]: boolean;
|
[name: string]: boolean;
|
||||||
}): void;
|
}): void;
|
||||||
export declare function shallowCopy(object: any): any;
|
export declare function shallowCopy<T>(object: T): Similar<T>;
|
||||||
export declare function deepCopy(object: any): any;
|
export declare function deepCopy<T>(object: T): Similar<T>;
|
||||||
export declare class Description<T = any> {
|
export declare class Description<T = any> {
|
||||||
constructor(info: T);
|
constructor(info: T);
|
||||||
}
|
}
|
||||||
|
@ -34,10 +34,10 @@ export function resolveProperties(object) {
|
|||||||
});
|
});
|
||||||
return Promise.all(promises).then((results) => {
|
return Promise.all(promises).then((results) => {
|
||||||
const result = {};
|
const result = {};
|
||||||
return results.reduce((accum, result) => {
|
return (results.reduce((accum, result) => {
|
||||||
accum[result.key] = result.value;
|
accum[result.key] = result.value;
|
||||||
return accum;
|
return accum;
|
||||||
}, result);
|
}, result));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
export function checkProperties(object, properties) {
|
export function checkProperties(object, properties) {
|
||||||
@ -60,7 +60,7 @@ export function shallowCopy(object) {
|
|||||||
const opaque = { bigint: true, boolean: true, number: true, string: true };
|
const opaque = { bigint: true, boolean: true, number: true, string: true };
|
||||||
// Returns a new copy of object, such that no properties may be replaced.
|
// Returns a new copy of object, such that no properties may be replaced.
|
||||||
// New properties may be added only to objects.
|
// New properties may be added only to objects.
|
||||||
export function deepCopy(object) {
|
function _deepCopy(object) {
|
||||||
// Opaque objects are not mutable, so safe to copy by assignment
|
// Opaque objects are not mutable, so safe to copy by assignment
|
||||||
if (object === undefined || object === null || opaque[typeof (object)]) {
|
if (object === undefined || object === null || opaque[typeof (object)]) {
|
||||||
return object;
|
return object;
|
||||||
@ -88,7 +88,10 @@ export function deepCopy(object) {
|
|||||||
if (typeof (object) === "function") {
|
if (typeof (object) === "function") {
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
throw new Error("Cannot deepCopy " + typeof (object));
|
logger.throwArgumentError(`Cannot deepCopy ${typeof (object)}`, "object", object);
|
||||||
|
}
|
||||||
|
export function deepCopy(object) {
|
||||||
|
return _deepCopy(object);
|
||||||
}
|
}
|
||||||
export class Description {
|
export class Description {
|
||||||
constructor(info) {
|
constructor(info) {
|
||||||
|
2
packages/properties/lib/_version.d.ts
vendored
2
packages/properties/lib/_version.d.ts
vendored
@ -1 +1 @@
|
|||||||
export declare const version = "properties/5.0.0-beta.136";
|
export declare const version = "properties/5.0.0-beta.137";
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.version = "properties/5.0.0-beta.136";
|
exports.version = "properties/5.0.0-beta.137";
|
||||||
|
14
packages/properties/lib/index.d.ts
vendored
14
packages/properties/lib/index.d.ts
vendored
@ -1,11 +1,17 @@
|
|||||||
export declare function defineReadOnly(object: any, name: string, value: any): void;
|
export declare function defineReadOnly<T, K extends keyof T>(object: T, name: K, value: T[K]): void;
|
||||||
export declare function getStatic<T>(ctor: any, key: string): T;
|
export declare function getStatic<T>(ctor: any, key: string): T;
|
||||||
export declare function resolveProperties(object: any): Promise<any>;
|
export declare type Similar<T> = {
|
||||||
|
[P in keyof T]: T[P];
|
||||||
|
};
|
||||||
|
export declare type Resolvable<T> = {
|
||||||
|
[P in keyof T]: T[P] | Promise<T[P]>;
|
||||||
|
};
|
||||||
|
export declare function resolveProperties<T>(object: Resolvable<T>): Promise<Similar<T>>;
|
||||||
export declare function checkProperties(object: any, properties: {
|
export declare function checkProperties(object: any, properties: {
|
||||||
[name: string]: boolean;
|
[name: string]: boolean;
|
||||||
}): void;
|
}): void;
|
||||||
export declare function shallowCopy(object: any): any;
|
export declare function shallowCopy<T>(object: T): Similar<T>;
|
||||||
export declare function deepCopy(object: any): any;
|
export declare function deepCopy<T>(object: T): Similar<T>;
|
||||||
export declare class Description<T = any> {
|
export declare class Description<T = any> {
|
||||||
constructor(info: T);
|
constructor(info: T);
|
||||||
}
|
}
|
||||||
|
@ -37,10 +37,10 @@ function resolveProperties(object) {
|
|||||||
});
|
});
|
||||||
return Promise.all(promises).then(function (results) {
|
return Promise.all(promises).then(function (results) {
|
||||||
var result = {};
|
var result = {};
|
||||||
return results.reduce(function (accum, result) {
|
return (results.reduce(function (accum, result) {
|
||||||
accum[result.key] = result.value;
|
accum[result.key] = result.value;
|
||||||
return accum;
|
return accum;
|
||||||
}, result);
|
}, result));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.resolveProperties = resolveProperties;
|
exports.resolveProperties = resolveProperties;
|
||||||
@ -66,7 +66,7 @@ exports.shallowCopy = shallowCopy;
|
|||||||
var opaque = { bigint: true, boolean: true, number: true, string: true };
|
var opaque = { bigint: true, boolean: true, number: true, string: true };
|
||||||
// Returns a new copy of object, such that no properties may be replaced.
|
// Returns a new copy of object, such that no properties may be replaced.
|
||||||
// New properties may be added only to objects.
|
// New properties may be added only to objects.
|
||||||
function deepCopy(object) {
|
function _deepCopy(object) {
|
||||||
// Opaque objects are not mutable, so safe to copy by assignment
|
// Opaque objects are not mutable, so safe to copy by assignment
|
||||||
if (object === undefined || object === null || opaque[typeof (object)]) {
|
if (object === undefined || object === null || opaque[typeof (object)]) {
|
||||||
return object;
|
return object;
|
||||||
@ -94,7 +94,10 @@ function deepCopy(object) {
|
|||||||
if (typeof (object) === "function") {
|
if (typeof (object) === "function") {
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
throw new Error("Cannot deepCopy " + typeof (object));
|
logger.throwArgumentError("Cannot deepCopy " + typeof (object), "object", object);
|
||||||
|
}
|
||||||
|
function deepCopy(object) {
|
||||||
|
return _deepCopy(object);
|
||||||
}
|
}
|
||||||
exports.deepCopy = deepCopy;
|
exports.deepCopy = deepCopy;
|
||||||
var Description = /** @class */ (function () {
|
var Description = /** @class */ (function () {
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
"build": "tsc -p ./tsconfig.json",
|
"build": "tsc -p ./tsconfig.json",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"tarballHash": "0x6a1817252456f7b6cbd2edd780d3b2585fcb477da55f7e7282869c0a5a7f5184",
|
"tarballHash": "0xfbf63fe67dfb09b4e1d9cf19010f61f540f63105cc006a148d91ab9bbf016c61",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"version": "5.0.0-beta.136"
|
"version": "5.0.0-beta.137"
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
export const version = "properties/5.0.0-beta.136";
|
export const version = "properties/5.0.0-beta.137";
|
||||||
|
@ -22,11 +22,19 @@ export function getStatic<T>(ctor: any, key: string): T {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type Similar<T> = {
|
||||||
|
[P in keyof T]: T[P];
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Resolvable<T> = {
|
||||||
|
[P in keyof T]: T[P] | Promise<T[P]>;
|
||||||
|
}
|
||||||
|
|
||||||
type Result = { key: string, value: any};
|
type Result = { key: string, value: any};
|
||||||
export function resolveProperties(object: any): Promise<any> {
|
export function resolveProperties<T>(object: Resolvable<T>): Promise<Similar<T>> {
|
||||||
|
|
||||||
const promises: Array<Promise<Result>> = Object.keys(object).map((key) => {
|
const promises: Array<Promise<Result>> = Object.keys(object).map((key) => {
|
||||||
const value = object[key];
|
const value = (<any>object)[key];
|
||||||
|
|
||||||
if (!(value instanceof Promise)) {
|
if (!(value instanceof Promise)) {
|
||||||
return Promise.resolve({ key: key, value: value });
|
return Promise.resolve({ key: key, value: value });
|
||||||
@ -39,10 +47,10 @@ export function resolveProperties(object: any): Promise<any> {
|
|||||||
|
|
||||||
return Promise.all(promises).then((results) => {
|
return Promise.all(promises).then((results) => {
|
||||||
const result: any = { };
|
const result: any = { };
|
||||||
return results.reduce((accum, result) => {
|
return (<Similar<T>>(results.reduce((accum, result) => {
|
||||||
accum[result.key] = result.value;
|
accum[result.key] = result.value;
|
||||||
return accum;
|
return accum;
|
||||||
}, result);
|
}, result)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +66,7 @@ export function checkProperties(object: any, properties: { [ name: string ]: boo
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function shallowCopy(object: any): any {
|
export function shallowCopy<T>(object: T): Similar<T> {
|
||||||
const result: any = {};
|
const result: any = {};
|
||||||
for (const key in object) { result[key] = object[key]; }
|
for (const key in object) { result[key] = object[key]; }
|
||||||
return result;
|
return result;
|
||||||
@ -68,7 +76,7 @@ const opaque: { [key: string]: boolean } = { bigint: true, boolean: true, number
|
|||||||
|
|
||||||
// Returns a new copy of object, such that no properties may be replaced.
|
// Returns a new copy of object, such that no properties may be replaced.
|
||||||
// New properties may be added only to objects.
|
// New properties may be added only to objects.
|
||||||
export function deepCopy(object: any): any {
|
function _deepCopy(object: any): any {
|
||||||
|
|
||||||
// Opaque objects are not mutable, so safe to copy by assignment
|
// Opaque objects are not mutable, so safe to copy by assignment
|
||||||
if (object === undefined || object === null || opaque[typeof(object)]) { return object; }
|
if (object === undefined || object === null || opaque[typeof(object)]) { return object; }
|
||||||
@ -98,7 +106,11 @@ export function deepCopy(object: any): any {
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error("Cannot deepCopy " + typeof(object));
|
logger.throwArgumentError(`Cannot deepCopy ${ typeof(object) }`, "object", object);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deepCopy<T>(object: T): Similar<T> {
|
||||||
|
return _deepCopy(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Description<T = any> {
|
export class Description<T = any> {
|
||||||
|
2
packages/providers/lib.esm/_version.d.ts
vendored
2
packages/providers/lib.esm/_version.d.ts
vendored
@ -1 +1 @@
|
|||||||
export declare const version = "providers/5.0.0-beta.152";
|
export declare const version = "providers/5.0.0-beta.153";
|
||||||
|
@ -1 +1 @@
|
|||||||
export const version = "providers/5.0.0-beta.152";
|
export const version = "providers/5.0.0-beta.153";
|
||||||
|
@ -7,7 +7,7 @@ export interface FallbackProviderConfig {
|
|||||||
weight?: number;
|
weight?: number;
|
||||||
}
|
}
|
||||||
export declare class FallbackProvider extends BaseProvider {
|
export declare class FallbackProvider extends BaseProvider {
|
||||||
readonly providerConfigs: Array<FallbackProviderConfig>;
|
readonly providerConfigs: ReadonlyArray<FallbackProviderConfig>;
|
||||||
readonly quorum: number;
|
readonly quorum: number;
|
||||||
_highestBlockNumber: number;
|
_highestBlockNumber: number;
|
||||||
constructor(providers: Array<Provider | FallbackProviderConfig>, quorum?: number);
|
constructor(providers: Array<Provider | FallbackProviderConfig>, quorum?: number);
|
||||||
|
2
packages/providers/lib/_version.d.ts
vendored
2
packages/providers/lib/_version.d.ts
vendored
@ -1 +1 @@
|
|||||||
export declare const version = "providers/5.0.0-beta.152";
|
export declare const version = "providers/5.0.0-beta.153";
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.version = "providers/5.0.0-beta.152";
|
exports.version = "providers/5.0.0-beta.153";
|
||||||
|
@ -7,7 +7,7 @@ export interface FallbackProviderConfig {
|
|||||||
weight?: number;
|
weight?: number;
|
||||||
}
|
}
|
||||||
export declare class FallbackProvider extends BaseProvider {
|
export declare class FallbackProvider extends BaseProvider {
|
||||||
readonly providerConfigs: Array<FallbackProviderConfig>;
|
readonly providerConfigs: ReadonlyArray<FallbackProviderConfig>;
|
||||||
readonly quorum: number;
|
readonly quorum: number;
|
||||||
_highestBlockNumber: number;
|
_highestBlockNumber: number;
|
||||||
constructor(providers: Array<Provider | FallbackProviderConfig>, quorum?: number);
|
constructor(providers: Array<Provider | FallbackProviderConfig>, quorum?: number);
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"tarballHash": "0xce9a626d62434fe628a5ab60fd3a05198eda8d7cf7ff7d54b63096e5b95d918c",
|
"tarballHash": "0x54990412c71ac1e81ce962062a2bbcc0127a32b1243f1db28fbb2af511b3e749",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"version": "5.0.0-beta.152"
|
"version": "5.0.0-beta.153"
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
export const version = "providers/5.0.0-beta.152";
|
export const version = "providers/5.0.0-beta.153";
|
||||||
|
2
packages/wallet/lib.esm/_version.d.ts
vendored
2
packages/wallet/lib.esm/_version.d.ts
vendored
@ -1 +1 @@
|
|||||||
export declare const version = "wallet/5.0.0-beta.136";
|
export declare const version = "wallet/5.0.0-beta.137";
|
||||||
|
@ -1 +1 @@
|
|||||||
export const version = "wallet/5.0.0-beta.136";
|
export const version = "wallet/5.0.0-beta.137";
|
||||||
|
@ -47,7 +47,6 @@ export class Wallet extends Signer {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
defineReadOnly(this, "_mnemonic", () => null);
|
defineReadOnly(this, "_mnemonic", () => null);
|
||||||
defineReadOnly(this, "path", null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -62,7 +61,6 @@ export class Wallet extends Signer {
|
|||||||
defineReadOnly(this, "_signingKey", () => signingKey);
|
defineReadOnly(this, "_signingKey", () => signingKey);
|
||||||
}
|
}
|
||||||
defineReadOnly(this, "_mnemonic", () => null);
|
defineReadOnly(this, "_mnemonic", () => null);
|
||||||
defineReadOnly(this, "path", null);
|
|
||||||
defineReadOnly(this, "address", computeAddress(this.publicKey));
|
defineReadOnly(this, "address", computeAddress(this.publicKey));
|
||||||
}
|
}
|
||||||
if (provider && !Provider.isProvider(provider)) {
|
if (provider && !Provider.isProvider(provider)) {
|
||||||
|
2
packages/wallet/lib/_version.d.ts
vendored
2
packages/wallet/lib/_version.d.ts
vendored
@ -1 +1 @@
|
|||||||
export declare const version = "wallet/5.0.0-beta.136";
|
export declare const version = "wallet/5.0.0-beta.137";
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user