Skip to content

Commit

Permalink
fix(asm): use multi-line strings in FunC and add some e2e tests (#825)
Browse files Browse the repository at this point in the history
  • Loading branch information
novusnota authored Sep 15, 2024
1 parent 82fec48 commit a470488
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 3 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- The `toSlice` method for structs and messages: PR [#630](https://github.com/tact-lang/tact/pull/630)
- Wider range of serialization options for integers — `uint1` through `uint256` and `int1` through `int257`: PR [#558](https://github.com/tact-lang/tact/pull/558)
- The `deepEquals` method for the `Map` type: PR [#637](https://github.com/tact-lang/tact/pull/637)
- `asm` bodies for module-level functions: PR [#769](https://github.com/tact-lang/tact/pull/769)
- `asm` bodies for module-level functions: PR [#769](https://github.com/tact-lang/tact/pull/769), PR [#825](https://github.com/tact-lang/tact/pull/825)
- Corresponding stdlib functions for new TVM instructions from 2023.07 and 2024.04 upgrades: PR [#331](https://github.com/tact-lang/tact/pull/331)
- `slice`, `rawSlice`, `ascii` and `crc32` built-in functions: PR [#787](https://github.com/tact-lang/tact/pull/787), PR [#799](https://github.com/tact-lang/tact/pull/799)
- `Builder.storeMaybeRef`, `parseStdAddress` and `parseVarAddress` stdlib functions: PR [#793](https://github.com/tact-lang/tact/pull/793)
Expand Down
2 changes: 2 additions & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"decompiling",
"dentry",
"Descr",
"DEBUGSTR",
"disasm",
"divmod",
"dnsresolve",
Expand Down Expand Up @@ -64,6 +65,7 @@
"Korshakov",
"Laika",
"langle",
"LDDICT",
"LDIX",
"LDREF",
"LDSLICEX",
Expand Down
2 changes: 1 addition & 1 deletion src/generator/emitter/emit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export function emit(args: {
if (f.flags.has("impure")) {
sig = `${sig} impure`;
}
res += `${sig} asm${f.code.shuffle} "${f.code.code}";`;
res += `${sig} asm${f.code.shuffle} """${f.code.code}""";`;
} else {
throw new Error(`Unknown function body kind`);
}
Expand Down
26 changes: 25 additions & 1 deletion src/grammar/__snapshots__/grammar.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3358,7 +3358,7 @@ exports[`grammar should parse expr-with-var 1`] = `
exports[`grammar should parse items-asm-funs 1`] = `
{
"id": 46,
"id": 48,
"imports": [],
"items": [
{
Expand Down Expand Up @@ -3719,6 +3719,30 @@ exports[`grammar should parse items-asm-funs 1`] = `
"ret": [],
},
},
{
"attributes": [],
"id": 47,
"instructions": [
""Works!"",
"DEBUGSTR",
],
"kind": "asm_function_def",
"loc": asm fun debugStr() {
"Works!" DEBUGSTR
},
"name": {
"id": 46,
"kind": "id",
"loc": debugStr,
"text": "debugStr",
},
"params": [],
"return": null,
"shuffle": {
"args": [],
"ret": [],
},
},
],
"kind": "module",
}
Expand Down
4 changes: 4 additions & 0 deletions src/grammar/test/items-asm-funs.tact
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,7 @@ asm fun checkAndRemoveAddExtensionPrefix(self: Slice): Int {
asm fun checkAndRemoveAddExtensionPrefix() {
-ROT
}

asm fun debugStr() {
"Works!" DEBUGSTR
}
38 changes: 38 additions & 0 deletions src/test/e2e-emulated/asm-functions.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { toNano } from "@ton/core";
import { Blockchain, SandboxContract, TreasuryContract } from "@ton/sandbox";
import { AsmFunctionsTester as TestContract } from "./contracts/output/asm-functions_AsmFunctionsTester";
import "@ton/test-utils";

describe("asm functions", () => {
let blockchain: Blockchain;
let treasure: SandboxContract<TreasuryContract>;
let contract: SandboxContract<TestContract>;

beforeEach(async () => {
blockchain = await Blockchain.create();
blockchain.verbosity.print = false;
treasure = await blockchain.treasury("treasure");

contract = blockchain.openContract(await TestContract.fromInit());

const deployResult = await contract.send(
treasure.getSender(),
{ value: toNano("10") },
null,
);

expect(deployResult.transactions).toHaveTransaction({
from: treasure.address,
to: contract.address,
success: true,
deploy: true,
});
});

it("should implement asm functions correctly", async () => {
expect(await contract.getTestAsmStoreDict()).toEqual(true);
expect(await contract.getTestAsmLoadCoins()).toEqual(true);
expect(await contract.getTestAsmLoadInt()).toEqual(true);
expect(await contract.getTestAsmDebugStr()).toEqual(true);
});
});
59 changes: 59 additions & 0 deletions src/test/e2e-emulated/contracts/asm-functions.tact
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
contract AsmFunctionsTester {
/// To handle deployment
receive() {}

get fun testAsmStoreDict(): Bool {
let m: map<Int, Int> = emptyMap();
m.set(35, 34);
m.set(42, 27);

let s = beginCell().asmStoreDict(m.asCell()).asSlice();
let m2: map<Int, Int> = s.asmLoadMapIntInt().val;

return m2 == m;
}

get fun testAsmLoadCoins(): Bool {
let s = beginCell().storeCoins(42).asSlice();
return s.asmLoadCoins().val == 42;
}

get fun testAsmLoadInt(): Bool {
let s = beginCell().storeInt(42, 7).asSlice();
return s.asmLoadInt(7).val == 42;
}

get fun testAsmDebugStr(): Bool {
debugStr();
return true;
}
}

// Functions to test

asm(c self) extends fun asmStoreDict(self: Builder, c: Cell?): Builder { STDICT }

asm extends fun asmLoadMapIntInt(self: Slice): MapIntIntSlice { LDDICT }

asm extends fun asmLoadCoins(self: Slice): IntSlice { LDVARUINT16 }

asm(self len -> 1 0) extends fun asmLoadInt(self: Slice, len: Int): SliceInt { LDIX }

asm fun debugStr() { "Works!" DEBUGSTR }

// Helper Structs

struct MapIntIntSlice {
val: map<Int, Int>;
rem: Slice;
}

struct IntSlice {
val: Int;
rem: Slice;
}

struct SliceInt {
rem: Slice;
val: Int;
}
5 changes: 5 additions & 0 deletions tact.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,11 @@
"name": "contract-methods",
"path": "./src/test/e2e-emulated/contracts/contract-methods.tact",
"output": "./src/test/e2e-emulated/contracts/output"
},
{
"name": "asm-functions",
"path": "./src/test/e2e-emulated/contracts/asm-functions.tact",
"output": "./src/test/e2e-emulated/contracts/output"
}
]
}

0 comments on commit a470488

Please sign in to comment.