Skip to content

Commit 4441032

Browse files
lforg37Ferdinand LemaireJessica Paquette
authored andcommitted
[mlir][wasm] Add code section parsing in Wasm Binary importer
--------- Co-authored-by: Ferdinand Lemaire <[email protected]> Co-authored-by: Jessica Paquette <[email protected]>
1 parent 32188fd commit 4441032

File tree

5 files changed

+251
-1
lines changed

5 files changed

+251
-1
lines changed

mlir/lib/Target/Wasm/TranslateFromWasm.cpp

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ class ExpressionParser {
289289
private:
290290
std::optional<Location> currentOpLoc;
291291
ParserHead &parser;
292-
[[maybe_unused]] WasmModuleSymbolTables const &symbols;
292+
WasmModuleSymbolTables const &symbols;
293293
locals_t locals;
294294
ValueStack valueStack;
295295
};
@@ -510,6 +510,60 @@ class ParserHead {
510510
return eParser.parse(builder);
511511
}
512512

513+
llvm::LogicalResult parseCodeFor(FuncOp func,
514+
WasmModuleSymbolTables const &symbols) {
515+
llvm::SmallVector<local_val_t> locals{};
516+
// Populating locals with function argument
517+
auto &block = func.getBody().front();
518+
// Delete temporary return argument which was only created for IR validity
519+
assert(func.getBody().getBlocks().size() == 1 &&
520+
"Function should only have its default created block at this point");
521+
assert(block.getOperations().size() == 1 &&
522+
"Only the placeholder return op should be present at this point");
523+
auto returnOp = cast<ReturnOp>(&block.back());
524+
assert(returnOp);
525+
526+
auto codeSizeInBytes = parseUI32();
527+
if (failed(codeSizeInBytes))
528+
return failure();
529+
auto codeContent = consumeNBytes(*codeSizeInBytes);
530+
if (failed(codeContent))
531+
return failure();
532+
auto name = StringAttr::get(func->getContext(),
533+
locName.str() + "::" + func.getSymName());
534+
auto cParser = ParserHead{*codeContent, name};
535+
auto localVecSize = cParser.parseVectorSize();
536+
if (failed(localVecSize))
537+
return failure();
538+
OpBuilder builder{&func.getBody().front().back()};
539+
for (auto arg : block.getArguments())
540+
locals.push_back(cast<TypedValue<LocalRefType>>(arg));
541+
// Declare the local ops
542+
auto nVarVec = *localVecSize;
543+
for (size_t i = 0; i < nVarVec; ++i) {
544+
auto varLoc = cParser.getLocation();
545+
auto nSubVar = cParser.parseUI32();
546+
if (failed(nSubVar))
547+
return failure();
548+
auto varT = cParser.parseValueType(func->getContext());
549+
if (failed(varT))
550+
return failure();
551+
for (size_t j = 0; j < *nSubVar; ++j) {
552+
auto local = builder.create<LocalOp>(varLoc, *varT);
553+
locals.push_back(local.getResult());
554+
}
555+
}
556+
auto res = cParser.parseExpression(builder, symbols, locals);
557+
if (failed(res))
558+
return failure();
559+
if (!cParser.end())
560+
return emitError(cParser.getLocation(),
561+
"Unparsed garbage remaining at end of code block");
562+
builder.create<ReturnOp>(func->getLoc(), *res);
563+
returnOp->erase();
564+
return success();
565+
}
566+
513567
bool end() const { return curHead().empty(); }
514568

515569
ParserHead copy() const { return *this; }
@@ -1039,6 +1093,11 @@ class WasmBinaryParser {
10391093
auto parsingGlobals = parseSection<WasmSectionType::GLOBAL>();
10401094
if (failed(parsingGlobals))
10411095
return;
1096+
1097+
auto parsingCode = parseSection<WasmSectionType::CODE>();
1098+
if (failed(parsingCode))
1099+
return;
1100+
10421101
LogicalResult parsingExports = parseSection<WasmSectionType::EXPORT>();
10431102
if (failed(parsingExports))
10441103
return;
@@ -1264,6 +1323,19 @@ WasmBinaryParser::parseSectionItem<WasmSectionType::GLOBAL>(ParserHead &ph,
12641323
builder.restoreInsertionPoint(ip);
12651324
return success();
12661325
}
1326+
1327+
template <>
1328+
LogicalResult WasmBinaryParser::parseSectionItem<WasmSectionType::CODE>(
1329+
ParserHead &ph, size_t innerFunctionId) {
1330+
auto funcId = innerFunctionId + firstInternalFuncID;
1331+
auto symRef = symbols.funcSymbols[funcId];
1332+
auto funcOp =
1333+
llvm::dyn_cast<FuncOp>(SymbolTable::lookupSymbolIn(mOp, symRef.symbol));
1334+
assert(funcOp);
1335+
if (failed(ph.parseCodeFor(funcOp, symbols)))
1336+
return failure();
1337+
return success();
1338+
}
12671339
} // namespace
12681340

12691341
namespace mlir::wasm {

mlir/test/Target/Wasm/const.mlir

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: yaml2obj %S/inputs/const.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
2+
/* Source code used to create this test:
3+
(module
4+
(func(result i32)
5+
i32.const 1
6+
)
7+
(func (result i64)
8+
i64.const 3
9+
)
10+
(func (result f32)
11+
f32.const 4.0
12+
)
13+
(func (result f64)
14+
f64.const 9.0
15+
)
16+
)
17+
*/
18+
19+
// CHECK-LABEL: wasmssa.func nested @func_0() -> i32 {
20+
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1 : i32
21+
// CHECK: wasmssa.return %[[VAL_0]] : i32
22+
// CHECK: }
23+
24+
// CHECK-LABEL: wasmssa.func nested @func_1() -> i64 {
25+
// CHECK: %[[VAL_0:.*]] = wasmssa.const 3 : i64
26+
// CHECK: wasmssa.return %[[VAL_0]] : i64
27+
// CHECK: }
28+
29+
// CHECK-LABEL: wasmssa.func nested @func_2() -> f32 {
30+
// CHECK: %[[VAL_0:.*]] = wasmssa.const 4.000000e+00 : f32
31+
// CHECK: wasmssa.return %[[VAL_0]] : f32
32+
// CHECK: }
33+
34+
// CHECK-LABEL: wasmssa.func nested @func_3() -> f64 {
35+
// CHECK: %[[VAL_0:.*]] = wasmssa.const 9.000000e+00 : f64
36+
// CHECK: wasmssa.return %[[VAL_0]] : f64
37+
// CHECK: }

mlir/test/Target/Wasm/global.mlir

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// RUN: yaml2obj %S/inputs/global.yaml.wasm -o - | mlir-translate --import-wasm | FileCheck %s
2+
/* Source code used to create this test:
3+
(module
4+
5+
;; import a global variable from js
6+
(global $imported_glob (import "env" "from_js") i32)
7+
8+
;; create a global variable
9+
(global $normal_glob i32(i32.const 10))
10+
(global $glob_mut (mut i32) (i32.const 10))
11+
(global $glob_mut_ext (mut i32) (i32.const 10))
12+
13+
(global $normal_glob_i64 i64(i64.const 11))
14+
(global $normal_glob_f32 f32(f32.const 12))
15+
(global $normal_glob_f64 f64(f64.const 13))
16+
)
17+
*/
18+
19+
// CHECK-LABEL: wasmssa.import_global "from_js" from "env" as @global_0 nested : i32
20+
21+
22+
// CHECK-LABEL: wasmssa.global @global_1 i32 nested : {
23+
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i32
24+
// CHECK: wasmssa.return %[[VAL_0]] : i32
25+
26+
// CHECK-LABEL: wasmssa.global @global_2 i32 mutable nested : {
27+
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i32
28+
// CHECK: wasmssa.return %[[VAL_0]] : i32
29+
30+
// CHECK-LABEL: wasmssa.global @global_3 i32 mutable nested : {
31+
// CHECK: %[[VAL_0:.*]] = wasmssa.const 10 : i32
32+
// CHECK: wasmssa.return %[[VAL_0]] : i32
33+
34+
// CHECK-LABEL: wasmssa.global @global_4 i64 nested : {
35+
// CHECK: %[[VAL_0:.*]] = wasmssa.const 11 : i64
36+
// CHECK: wasmssa.return %[[VAL_0]] : i64
37+
38+
// CHECK-LABEL: wasmssa.global @global_5 f32 nested : {
39+
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.200000e+01 : f32
40+
// CHECK: wasmssa.return %[[VAL_0]] : f32
41+
42+
// CHECK-LABEL: wasmssa.global @global_6 f64 nested : {
43+
// CHECK: %[[VAL_0:.*]] = wasmssa.const 1.300000e+01 : f64
44+
// CHECK: wasmssa.return %[[VAL_0]] : f64
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
--- !WASM
2+
FileHeader:
3+
Version: 0x1
4+
Sections:
5+
- Type: TYPE
6+
Signatures:
7+
- Index: 0
8+
ParamTypes: []
9+
ReturnTypes:
10+
- I32
11+
- Index: 1
12+
ParamTypes: []
13+
ReturnTypes:
14+
- I64
15+
- Index: 2
16+
ParamTypes: []
17+
ReturnTypes:
18+
- F32
19+
- Index: 3
20+
ParamTypes: []
21+
ReturnTypes:
22+
- F64
23+
- Type: FUNCTION
24+
FunctionTypes: [ 0, 1, 2, 3 ]
25+
- Type: CODE
26+
Functions:
27+
- Index: 0
28+
Locals: []
29+
Body: 41010B
30+
- Index: 1
31+
Locals: []
32+
Body: 42030B
33+
- Index: 2
34+
Locals: []
35+
Body: 43000080400B
36+
- Index: 3
37+
Locals: []
38+
Body: 4400000000000022400B
39+
...
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
--- !WASM
2+
FileHeader:
3+
Version: 0x1
4+
Sections:
5+
- Type: TYPE
6+
Signatures:
7+
- Index: 0
8+
ParamTypes: []
9+
ReturnTypes:
10+
- I32
11+
- Type: IMPORT
12+
Imports:
13+
- Module: env
14+
Field: from_js
15+
Kind: GLOBAL
16+
GlobalType: I32
17+
GlobalMutable: false
18+
- Type: FUNCTION
19+
FunctionTypes: [ 0 ]
20+
- Type: GLOBAL
21+
Globals:
22+
- Index: 1
23+
Type: I32
24+
Mutable: false
25+
InitExpr:
26+
Opcode: I32_CONST
27+
Value: 10
28+
- Index: 2
29+
Type: I32
30+
Mutable: true
31+
InitExpr:
32+
Opcode: I32_CONST
33+
Value: 10
34+
- Index: 3
35+
Type: I32
36+
Mutable: true
37+
InitExpr:
38+
Opcode: I32_CONST
39+
Value: 10
40+
- Index: 4
41+
Type: I64
42+
Mutable: false
43+
InitExpr:
44+
Opcode: I64_CONST
45+
Value: 11
46+
- Index: 5
47+
Type: F32
48+
Mutable: false
49+
InitExpr:
50+
Opcode: F32_CONST
51+
Value: 1094713344
52+
- Index: 6
53+
Type: F64
54+
Mutable: false
55+
InitExpr:
56+
Opcode: F64_CONST
57+
Value: 4623507967449235456
58+
...

0 commit comments

Comments
 (0)