Skip to content

Commit

Permalink
feat: split decompilation to AST and Writer (#26)
Browse files Browse the repository at this point in the history
* feat: split decompilation to AST and Writer

Most of the code taken from: https://github.com/scaleton-labs/tvm-disassembler

* add attribution for files from https://github.com/scaleton-labs/tvm-disassembler and to README.md

* add 2 new opcodes for the new code
  • Loading branch information
i582 authored Jan 16, 2025
1 parent fe1c09b commit 3948087
Show file tree
Hide file tree
Showing 15 changed files with 852 additions and 448 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ const decompiledCode = decompileAll({ src: sourceCode });

```

## Authors

- [Steve Korshakov](https://github.com/ex3ndr)
- [Nick Nekilov](https://github.com/NickNekilov)

## License

MIT
MIT
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tact-lang/opcode",
"version": "0.0.18",
"version": "0.0.19",
"main": "dist/index.js",
"repository": "https://github.com/tact-lang/ton-opcode.git",
"author": "Steve Korshakov <[email protected]>",
Expand All @@ -25,7 +25,8 @@
"ts-jest": "^29.0.5",
"ts-node": "^10.9.1",
"typescript": "^5.0.2",
"tvm-disassembler": "^3.0.0"
"tvm-disassembler": "^3.0.0",
"@scaleton/func-debug-symbols": "^0.1.4"
},
"peerDependencies": {
"@ton/core": ">=0.49.2",
Expand Down
4 changes: 3 additions & 1 deletion reference/opcodes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,8 @@ opcodes:
SAMEALTSAVE:

# A.8.7. Dictionary subroutine calls and jumps.
CALLDICT: ["int"]
INLINECALLDICT: ["int"]
CALL: ["int"]
JMP: ["int"]
PREPARE: ["int"]
Expand Down Expand Up @@ -804,4 +806,4 @@ opcodes:
CHASHI: ["int"]
CDEPTHI: ["int"]
CHASHIX:
CDEPTHIX:
CDEPTHIX:
126 changes: 126 additions & 0 deletions src/ast/AST.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// This file is based on code from https://github.com/scaleton-labs/tvm-disassembler

import {
BlockNode,
InstructionNode,
MethodNode,
ProcedureNode,
ProgramNode,
ReferenceNode,
ScalarNode,
NodeType,
ControlRegisterNode,
StackEntryNode,
GlobalVariableNode,
MethodReferenceNode,
} from './nodes';

export class AST {
static program(
methods: MethodNode[],
procedures: ProcedureNode[],
): ProgramNode {
return {
type: NodeType.PROGRAM,
methods,
procedures,
};
}

static method(
id: number,
body: BlockNode,
sourceHash: string,
sourceOffset: number,
): MethodNode {
return {
type: NodeType.METHOD,
id,
body,
hash: sourceHash,
offset: sourceOffset,
};
}

static procedure(hash: string, body: BlockNode): ProcedureNode {
return {
type: NodeType.PROCEDURE,
hash,
body,
};
}

static block(
instructions: InstructionNode[],
hash: string,
offset: number,
length: number,
): BlockNode {
return {
type: NodeType.BLOCK,
instructions,
hash,
offset,
length,
};
}

static instruction(
opcode: InstructionNode['opcode'],
args: InstructionNode['arguments'],
offset: number,
length: number,
hash: string,
): InstructionNode {
return {
type: NodeType.INSTRUCTION,
opcode,
arguments: args,
offset,
length,
hash,
};
}

static scalar(value: string | number | bigint): ScalarNode {
return {
type: NodeType.SCALAR,
value,
};
}

static reference(hash: string): ReferenceNode {
return {
type: NodeType.REFERENCE,
hash,
};
}

static controlRegister(index: number): ControlRegisterNode {
return {
type: NodeType.CONTROL_REGISTER,
value: index,
};
}

static stackEntry(index: number): StackEntryNode {
return {
type: NodeType.STACK_ENTRY,
value: index,
};
}

static globalVariable(index: number): GlobalVariableNode {
return {
type: NodeType.GLOBAL_VARIABLE,
value: index,
};
}

static methodReference(method: number): MethodReferenceNode {
return {
type: NodeType.METHOD_REFERENCE,
methodId: method,
};
}
}
2 changes: 2 additions & 0 deletions src/ast/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './nodes';
export * from './AST';
93 changes: 93 additions & 0 deletions src/ast/nodes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// This file is based on code from https://github.com/scaleton-labs/tvm-disassembler

import {Cell} from '@ton/core';
import {OpCode} from '../codepage/opcodes.gen';

export enum NodeType {
PROGRAM,
METHOD,
BLOCK,
INSTRUCTION,
SCALAR,
REFERENCE,
PROCEDURE,
CONTROL_REGISTER,
STACK_ENTRY,
GLOBAL_VARIABLE,
METHOD_REFERENCE,
}

export type ControlRegisterNode = {
type: NodeType.CONTROL_REGISTER;
value: number;
};

export type StackEntryNode = {
type: NodeType.STACK_ENTRY;
value: number;
};

export type GlobalVariableNode = {
type: NodeType.GLOBAL_VARIABLE;
value: number;
};

export type ScalarNode = {
type: NodeType.SCALAR;
value: number | string | bigint | Cell;
};

export type ReferenceNode = {
type: NodeType.REFERENCE;
hash: string;
};

export type MethodReferenceNode = {
type: NodeType.METHOD_REFERENCE;
methodId: number;
};

export type InstructionNode = {
type: NodeType.INSTRUCTION;
opcode: OpCode['code'];
arguments: (
| ScalarNode
| BlockNode
| ReferenceNode
| StackEntryNode
| ControlRegisterNode
| GlobalVariableNode
| MethodReferenceNode
)[];
offset: number;
length: number;
hash: string;
};

export type BlockNode = {
type: NodeType.BLOCK;
instructions: InstructionNode[];
hash: string;
offset: number;
length: number;
};

export type MethodNode = {
type: NodeType.METHOD;
id: number;
body: BlockNode;
hash: string;
offset: number;
};

export type ProcedureNode = {
type: NodeType.PROCEDURE;
hash: string;
body: BlockNode;
};

export type ProgramNode = {
type: NodeType.PROGRAM;
methods: MethodNode[];
procedures: ProcedureNode[];
};
2 changes: 2 additions & 0 deletions src/codepage/opcodes.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ export type OpCodeWithArgs =
| { code: 'SAVE', args: [number] }
| { code: 'SAVEALT', args: [number] }
| { code: 'SAVEBOTH', args: [number] }
| { code: 'CALLDICT', args: [number] }
| { code: 'INLINECALLDICT', args: [number] }
| { code: 'CALL', args: [number] }
| { code: 'JMP', args: [number] }
| { code: 'PREPARE', args: [number] }
Expand Down
Loading

0 comments on commit 3948087

Please sign in to comment.