@@ -1257,9 +1257,47 @@ struct ParseImplicitTypeDefsCtx : TypeParserCtx<ParseImplicitTypeDefsCtx> {
1257
1257
}
1258
1258
};
1259
1259
1260
+ struct AnnotationParserCtx {
1261
+ // Return the inline hint for a call instruction, if there is one.
1262
+ std::optional<std::uint8_t >
1263
+ getInlineHint (const std::vector<Annotation>& annotations) {
1264
+ // Find and apply (the last) inline hint.
1265
+ const Annotation* hint = nullptr ;
1266
+ for (auto & a : annotations) {
1267
+ if (a.kind == Annotations::InlineHint) {
1268
+ hint = &a;
1269
+ }
1270
+ }
1271
+ if (!hint) {
1272
+ return std::nullopt ;
1273
+ }
1274
+
1275
+ Lexer lexer (hint->contents );
1276
+ if (lexer.empty ()) {
1277
+ std::cerr << " warning: empty InlineHint\n " ;
1278
+ return std::nullopt ;
1279
+ }
1280
+
1281
+ auto str = lexer.takeString ();
1282
+ if (!str || str->size () != 1 ) {
1283
+ std::cerr << " warning: invalid InlineHint string\n " ;
1284
+ return std::nullopt ;
1285
+ }
1286
+
1287
+ uint8_t value = (*str)[0 ];
1288
+ if (value > 127 ) {
1289
+ std::cerr << " warning: invalid InlineHint value\n " ;
1290
+ return std::nullopt ;
1291
+ }
1292
+
1293
+ return value;
1294
+ }
1295
+ };
1296
+
1260
1297
// Phase 4: Parse and set the types of module elements.
1261
1298
struct ParseModuleTypesCtx : TypeParserCtx<ParseModuleTypesCtx>,
1262
- NullInstrParserCtx {
1299
+ NullInstrParserCtx,
1300
+ AnnotationParserCtx {
1263
1301
// In this phase we have constructed all the types, so we can materialize and
1264
1302
// validate them when they are used.
1265
1303
@@ -1367,6 +1405,13 @@ struct ParseModuleTypesCtx : TypeParserCtx<ParseModuleTypesCtx>,
1367
1405
Builder::addVar (f.get (), l.name , l.type );
1368
1406
}
1369
1407
}
1408
+ // TODO: Add function-level annotations (stored using the nullptr key, as
1409
+ // they are tied to no instruction in particular), but this should wait on
1410
+ // figuring out
1411
+ // https://github.com/WebAssembly/tool-conventions/issues/251
1412
+ // if (auto inline_ = getInlineHint(annotations)) {
1413
+ // f->codeAnnotations[nullptr].inline_ = inline_;
1414
+ // }
1370
1415
return Ok{};
1371
1416
}
1372
1417
@@ -1427,7 +1472,7 @@ struct ParseModuleTypesCtx : TypeParserCtx<ParseModuleTypesCtx>,
1427
1472
};
1428
1473
1429
1474
// Phase 5: Parse module element definitions, including instructions.
1430
- struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
1475
+ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx>, AnnotationParserCtx {
1431
1476
using GlobalTypeT = Ok;
1432
1477
using TableTypeT = Ok;
1433
1478
using TypeUseT = HeapType;
@@ -2329,7 +2374,8 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
2329
2374
const std::vector<Annotation>& annotations,
2330
2375
Name func,
2331
2376
bool isReturn) {
2332
- return withLoc (pos, irBuilder.makeCall (func, isReturn));
2377
+ auto inline_ = getInlineHint (annotations);
2378
+ return withLoc (pos, irBuilder.makeCall (func, isReturn, inline_));
2333
2379
}
2334
2380
2335
2381
Result<> makeCallIndirect (Index pos,
0 commit comments