@@ -1193,108 +1193,221 @@ mlir.BytecodeReader = class {
1193
1193
1194
1194
constructor ( context ) {
1195
1195
this . _reader = new mlir . BinaryReader ( context ) ;
1196
- this . _decoder = new TextDecoder ( 'utf-8' ) ;
1197
1196
}
1198
1197
1199
1198
read ( ) {
1200
1199
const reader = this . _reader ;
1201
1200
reader . read ( 4 ) ; // signature 'ML\xEFR'
1202
1201
this . version = reader . varint ( ) . toNumber ( ) ;
1203
1202
this . producer = reader . string ( ) ;
1204
- this . sections = [ ] ;
1203
+ this . sections = new Map ( ) ;
1205
1204
while ( reader . position < reader . length ) {
1206
1205
// https://mlir.llvm.org/docs/BytecodeFormat/
1207
- const code = reader . byte ( ) ;
1208
- const identifier = code & 0x7F ;
1206
+ // https://github.com/llvm/llvm-project/blob/main/mlir/lib/Bytecode/Reader/BytecodeReader.cpp
1207
+ const sectionIDAndHasAlignment = reader . byte ( ) ;
1208
+ const sectionID = sectionIDAndHasAlignment & 0x7F ;
1209
1209
const length = reader . varint ( ) . toNumber ( ) ;
1210
- if ( code >> 7 ) {
1210
+ const hasAlignment = sectionIDAndHasAlignment & 0x80 ;
1211
+ if ( sectionID >= 9 ) {
1212
+ throw new mlir . Error ( `Unsupported section identifier '${ sectionID } '.` ) ;
1213
+ }
1214
+ if ( hasAlignment ) {
1211
1215
const alignment = reader . varint ( ) ;
1212
1216
reader . skip ( alignment ) ;
1213
1217
}
1214
- const next = reader . position + length ;
1215
- switch ( identifier ) {
1216
- case 0 : { // string
1217
- const lengths = new Array ( reader . varint ( ) . toNumber ( ) ) ;
1218
- for ( let i = 0 ; i < lengths . length ; i ++ ) {
1219
- lengths [ i ] = reader . varint ( ) . toNumber ( ) ;
1220
- }
1221
- this . strings = new Array ( lengths . length ) ;
1222
- for ( let i = 0 ; i < this . strings . length ; i ++ ) {
1223
- const size = lengths [ lengths . length - i - 1 ] ;
1224
- const buffer = reader . read ( size ) ;
1225
- this . strings [ i ] = this . _decoder . decode ( buffer ) ;
1226
- }
1227
- break ;
1228
- }
1229
- case 1 : { // dialect
1230
- const numDialects = reader . varint ( ) . toNumber ( ) ;
1231
- this . dialectNames = new Array ( numDialects ) ;
1232
- this . opNames = new Array ( numDialects ) ;
1233
- for ( let i = 0 ; i < this . dialectNames . length ; i ++ ) {
1234
- const group = { } ;
1235
- const nameAndIsVersioned = reader . varint ( ) ;
1236
- group . name = ( nameAndIsVersioned >> 1n ) . toNumber ( ) ;
1237
- if ( nameAndIsVersioned & 1n ) {
1238
- const size = reader . varint ( ) . toNumber ( ) ;
1239
- group . version = reader . read ( size ) ;
1240
- }
1241
- this . dialectNames [ i ] = group ;
1242
- }
1243
- for ( let i = 0 ; i < this . opNames . length ; i ++ ) {
1244
- const dialect_ops_group = { } ;
1245
- dialect_ops_group . dialect = reader . varint ( ) ;
1246
- dialect_ops_group . opNames = new Array ( reader . varint ( ) . toNumber ( ) ) ;
1247
- for ( let j = 0 ; j < dialect_ops_group . opNames . length ; j ++ ) {
1248
- const op_name_group = { } ;
1249
- const nameAndIsRegistered = reader . varint ( ) ;
1250
- op_name_group . isRegistered = ( nameAndIsRegistered & 1n ) === 1n ;
1251
- op_name_group . name = ( nameAndIsRegistered >> 1n ) . toNumber ( ) ;
1252
- dialect_ops_group . opNames [ j ] = op_name_group ;
1253
- }
1254
- this . opNames [ i ] = dialect_ops_group ;
1255
- }
1256
- break ;
1257
- }
1258
- case 2 : // attrType
1259
- case 3 : { // attrTypeOffset
1260
- /*
1261
- const numAttrs = reader.varint().toNumber();
1262
- const numTypes = reader.varint().toNumber();
1263
- for (let i = 0; i < (numAttrs + numTypes); i++) {
1218
+ const offset = reader . position ;
1219
+ reader . skip ( length ) ;
1220
+ this . sections . set ( sectionID , { start : offset , end : reader . position } ) ;
1221
+ }
1222
+ if ( ! this . sections . has ( 0 ) || ! this . sections . has ( 1 ) ||
1223
+ ! this . sections . has ( 2 ) || ! this . sections . has ( 3 ) ||
1224
+ ! this . sections . has ( 4 ) || ( this . version >= 5 && ! this . sections . has ( 8 ) ) ) {
1225
+ throw new mlir . Error ( 'Missing required section.' ) ;
1226
+ }
1227
+ this . _parseStringSection ( ) ;
1228
+ if ( this . sections . has ( 8 ) ) {
1229
+ this . _parsePropertiesSection ( ) ;
1230
+ }
1231
+ this . _parseDialectSection ( ) ;
1232
+ this . _parseResourceSection ( ) ;
1233
+ this . _parseAttrTypeSection ( ) ;
1234
+ }
1264
1235
1265
- }
1266
- break;
1267
- */
1268
- this . attrType = reader . stream ( length ) ;
1269
- break ;
1270
- }
1271
- case 4 : { // IR
1272
- reader . skip ( length ) ;
1273
- break ;
1274
- }
1275
- case 5 : { // resource
1276
- this . resource = reader . stream ( length ) ;
1277
- break ;
1278
- }
1279
- case 6 : { // resourceOffset
1280
- reader . skip ( length ) ;
1281
- break ;
1282
- }
1283
- case 7 : { // dialectVersions
1284
- reader . skip ( length ) ;
1285
- break ;
1236
+ _parseStringSection ( ) {
1237
+ const section = this . sections . get ( 0 ) ;
1238
+ const reader = this . _reader ;
1239
+ reader . seek ( section . start ) ;
1240
+ const lengths = new Array ( reader . varint ( ) . toNumber ( ) ) ;
1241
+ for ( let i = 0 ; i < lengths . length ; i ++ ) {
1242
+ lengths [ i ] = reader . varint ( ) . toNumber ( ) ;
1243
+ }
1244
+ const decoder = new TextDecoder ( 'utf-8' ) ;
1245
+ this . strings = new Array ( lengths . length ) ;
1246
+ for ( let i = 0 ; i < this . strings . length ; i ++ ) {
1247
+ const size = lengths [ lengths . length - 1 - i ] ;
1248
+ const buffer = reader . read ( size ) ;
1249
+ this . strings [ i ] = decoder . decode ( buffer ) ;
1250
+ }
1251
+ if ( reader . position !== section . end ) {
1252
+ throw new mlir . Error ( `Invalid string section size.` ) ;
1253
+ }
1254
+ }
1255
+
1256
+ _parseDialectSection ( ) {
1257
+ const section = this . sections . get ( 1 ) ;
1258
+ const reader = this . _reader ;
1259
+ reader . seek ( section . start ) ;
1260
+ const numDialects = reader . varint ( ) . toNumber ( ) ;
1261
+ this . dialects = new Array ( numDialects ) ;
1262
+ for ( let i = 0 ; i < this . dialects . length ; i ++ ) {
1263
+ this . dialects [ i ] = { } ;
1264
+ if ( this . version < 1 ) { // kDialectVersioning
1265
+ const entryIdx = reader . varint ( ) . toNumber ( ) ;
1266
+ this . dialects [ i ] . name = this . strings [ entryIdx ] ;
1267
+ continue ;
1268
+ }
1269
+ const nameAndIsVersioned = reader . varint ( ) ;
1270
+ const dialectNameIdx = ( nameAndIsVersioned >> 1n ) . toNumber ( ) ;
1271
+ this . dialects [ i ] . name = this . strings [ dialectNameIdx ] ;
1272
+ if ( nameAndIsVersioned & 1n ) {
1273
+ const size = reader . varint ( ) . toNumber ( ) ;
1274
+ this . dialects [ i ] . version = reader . read ( size ) ;
1275
+ }
1276
+ }
1277
+ let numOps = - 1 ;
1278
+ this . opNames = [ ] ;
1279
+ if ( this . version > 4 ) { // kElideUnknownBlockArgLocation
1280
+ numOps = reader . varint ( ) . toNumber ( ) ;
1281
+ this . opNames = new Array ( numOps ) ;
1282
+ }
1283
+ let i = 0 ;
1284
+ while ( reader . position < section . end ) {
1285
+ const dialect = this . dialects [ reader . varint ( ) . toNumber ( ) ] ;
1286
+ const numEntries = reader . varint ( ) . toNumber ( ) ;
1287
+ for ( let j = 0 ; j < numEntries ; j ++ ) {
1288
+ const opName = { } ;
1289
+ if ( this . version < 5 ) { // kNativePropertiesEncoding
1290
+ opName . name = this . strings [ reader . varint ( ) . toNumber ( ) ] ;
1291
+ opName . dialect = dialect ;
1292
+ } else {
1293
+ const nameAndIsRegistered = reader . varint ( ) ;
1294
+ opName . name = this . strings [ ( nameAndIsRegistered >> 1n ) . toNumber ( ) ] ;
1295
+ opName . dialect = dialect ;
1296
+ opName . isRegistered = ( nameAndIsRegistered & 1n ) === 1n ;
1286
1297
}
1287
- case 8 : { // properties
1288
- reader . skip ( length ) ;
1289
- break ;
1298
+ if ( numOps < 0 ) {
1299
+ this . opNames . push ( opName ) ;
1300
+ } else {
1301
+ this . opNames [ i ++ ] = opName ;
1290
1302
}
1291
- default : {
1292
- throw new mlir . Error ( `Unsupported section identifier '${ identifier } '.` ) ;
1303
+ }
1304
+ }
1305
+ if ( reader . position !== section . end ) {
1306
+ throw new mlir . Error ( `Invalid dialect section size.` ) ;
1307
+ }
1308
+ }
1309
+
1310
+ _parseResourceSection ( ) {
1311
+ const section = this . sections . get ( 6 ) ;
1312
+ const reader = this . _reader ;
1313
+ reader . seek ( section . start ) ;
1314
+ const numExternalResourceGroups = reader . varint ( ) . toNumber ( ) ;
1315
+ if ( numExternalResourceGroups > 0 ) {
1316
+ throw new mlir . Error ( `Unsupported resource section.` ) ;
1317
+ }
1318
+ /*
1319
+ for (let i = 0; i < numExternalResourceGroups; i++) {
1320
+ const numResources = reader.varint().toNumber();
1321
+ for (let j = 0; j < numResources; j++) {
1322
+ const resource = {};
1323
+ resource.key = this.strings[reader.varint().toNumber()];
1324
+ resource.offset = reader.varint().toNumber();
1325
+ resource.kind = reader.byte();
1326
+ }
1327
+ }
1328
+ */
1329
+ if ( reader . position !== section . end ) {
1330
+ throw new mlir . Error ( `Invalid dialect section size.` ) ;
1331
+ }
1332
+ }
1333
+
1334
+ _parseAttrTypeSection ( ) {
1335
+ const section = this . sections . get ( 3 ) ;
1336
+ const reader = this . _reader ;
1337
+ reader . seek ( section . start ) ;
1338
+ this . attributes = new Array ( reader . varint ( ) . toNumber ( ) ) ;
1339
+ this . types = new Array ( reader . varint ( ) . toNumber ( ) ) ;
1340
+ let offset = 0 ;
1341
+ const parseEntries = ( range ) => {
1342
+ for ( let i = 0 ; i < range . length ; ) {
1343
+ const dialect = this . dialects [ reader . varint ( ) . toNumber ( ) ] ;
1344
+ const numEntries = reader . varint ( ) . toNumber ( ) ;
1345
+ for ( let j = 0 ; j < numEntries ; j ++ ) {
1346
+ const entry = { } ;
1347
+ const entrySizeWithFlag = reader . varint ( ) ;
1348
+ entry . hasCustomEncoding = ( entrySizeWithFlag & 1n ) === 1n ;
1349
+ entry . size = ( entrySizeWithFlag >> 1n ) . toNumber ( ) ;
1350
+ entry . offset = offset ;
1351
+ entry . dialect = dialect ;
1352
+ offset += entry . size ;
1353
+ range [ i ++ ] = entry ;
1293
1354
}
1294
1355
}
1295
- if ( reader . position !== next ) {
1296
- throw new mlir . Error ( 'Invalid section length.' ) ;
1356
+ } ;
1357
+ parseEntries ( this . attributes ) ;
1358
+ parseEntries ( this . types ) ;
1359
+ if ( reader . position !== section . end ) {
1360
+ throw new mlir . Error ( `Invalid dialect section size.` ) ;
1361
+ }
1362
+ offset = this . sections . get ( 2 ) . start ;
1363
+ const parseCustomEntry = ( entry , reader , entryType ) => {
1364
+ // throw new mlir.Error(`Unsupported custom encoding.`);
1365
+ if ( entryType === 'type' ) {
1366
+ // debugger;
1367
+ } else {
1368
+ // debugger;
1297
1369
}
1370
+ } ;
1371
+ const parseAsmEntry = ( entry , reader , entryType ) => {
1372
+ if ( entryType === 'type' ) {
1373
+ // debugger;
1374
+ } else {
1375
+ // debugger;
1376
+ }
1377
+ } ;
1378
+ const resolveEntries = ( range , entryType ) => {
1379
+ for ( const entry of this . attributes ) {
1380
+ reader . seek ( offset + entry . offset ) ;
1381
+ if ( entry . hasCustomEncoding ) {
1382
+ parseCustomEntry ( entry , reader ) ;
1383
+ } else {
1384
+ parseAsmEntry ( entry , reader , entryType ) ;
1385
+ }
1386
+ // if (reader.position !== (offset + entry.offset + entry.size)) {
1387
+ // throw new mlir.Error(`Invalid '${entryType}' section size.`);
1388
+ // }
1389
+ // delete entry.offset;
1390
+ // delete entry.size;
1391
+ }
1392
+ } ;
1393
+ resolveEntries ( this . attributes , 'attribute' ) ;
1394
+ resolveEntries ( this . types , 'type' ) ;
1395
+ }
1396
+
1397
+ _parsePropertiesSection ( ) {
1398
+ const section = this . sections . get ( 8 ) ;
1399
+ const reader = this . _reader ;
1400
+ reader . seek ( section . start ) ;
1401
+ const count = reader . varint ( ) . toNumber ( ) ;
1402
+ const offsetTable = new Array ( count ) ;
1403
+ for ( let i = 0 ; i < offsetTable . length ; i ++ ) {
1404
+ const offset = reader . position ;
1405
+ const size = reader . varint ( ) . toNumber ( ) ;
1406
+ const data = reader . read ( size ) ;
1407
+ offsetTable [ i ] = { offset, data } ;
1408
+ }
1409
+ if ( reader . position !== section . end ) {
1410
+ throw new mlir . Error ( `Invalid properties section size.` ) ;
1298
1411
}
1299
1412
}
1300
1413
} ;
@@ -1317,6 +1430,10 @@ mlir.BinaryReader = class {
1317
1430
this . _reader . skip ( length ) ;
1318
1431
}
1319
1432
1433
+ seek ( offset ) {
1434
+ this . _reader . seek ( offset ) ;
1435
+ }
1436
+
1320
1437
read ( length ) {
1321
1438
return this . _reader . read ( length ) ;
1322
1439
}
@@ -1330,17 +1447,25 @@ mlir.BinaryReader = class {
1330
1447
}
1331
1448
1332
1449
varint ( ) {
1333
- let value = 0n ;
1334
- let shift = 0n ;
1335
- for ( let i = 0 ; i < 10 && this . _reader . position < this . _reader . length ; i ++ ) {
1336
- const byte = this . _reader . byte ( ) ;
1337
- value |= BigInt ( byte >> 1 ) << shift ;
1338
- if ( ( byte & 1 ) === 1 ) {
1339
- return value ;
1340
- }
1341
- shift += 7n ;
1342
- }
1343
- throw new mlir . Error ( 'Invalid varint value.' ) ;
1450
+ let result = this . _reader . byte ( ) ;
1451
+ if ( result & 1 ) {
1452
+ return BigInt ( result >> 1 ) ;
1453
+ }
1454
+ if ( result === 0 ) {
1455
+ return this . _reader . uint64 ( ) ;
1456
+ }
1457
+ result = BigInt ( result ) ;
1458
+ let mask = 1n ;
1459
+ let numBytes = 0n ;
1460
+ let shift = 8n ;
1461
+ while ( result > 0n && ( result & mask ) === 0n ) {
1462
+ result |= ( BigInt ( this . _reader . byte ( ) ) << shift ) ;
1463
+ mask <<= 1n ;
1464
+ shift += 8n ;
1465
+ numBytes ++ ;
1466
+ }
1467
+ result >>= BigInt ( numBytes + 1n ) ;
1468
+ return result ;
1344
1469
}
1345
1470
1346
1471
string ( ) {
0 commit comments