11import { injectable } from "inversify" ;
22import { WasmBinary } from "./WasmBinary" ;
33import { BytesReader } from "./BytesReader" ;
4- import { WasmSection , WasmTypeSectionPayload , WasmSectionPayload , WasmExportSectionPayload , WasmCodeSectionPayload , WasmImportSectionPayload } from "./WasmSection" ;
4+ import { WasmSection , WasmTypeSectionPayload , WasmSectionPayload , WasmExportSectionPayload , WasmCodeSectionPayload , WasmImportSectionPayload , WasmFunctionSectionPayload , findSection } from "./WasmSection" ;
55import { WasmSectionType , WasmType , WasmValueType , getWasmValueType , getExternalType , WasmExternalKind } from "./wasmTypes" ;
6- import { FuncType } from "./FuncType" ;
6+ import { FuncType , printSignature } from "./FuncType" ;
77import { FunctionBody , FunctionLocal , formatOpcodes } from "./FunctionBody" ;
88import { WasmOpcode , WasmOpcodeDefinition , WasmOpcodes , Immediate } from "./WasmOpcodes" ;
99import { OpcodeImmediateType } from "./OpcodeImmediateType" ;
@@ -22,6 +22,7 @@ export class WasmBinaryParser {
2222 this . sectionParsers . set ( WasmSectionType . Export , this . parseExportSection )
2323 this . sectionParsers . set ( WasmSectionType . Code , this . parseCodeSection )
2424 this . sectionParsers . set ( WasmSectionType . Import , this . parseImportSection )
25+ this . sectionParsers . set ( WasmSectionType . Function , this . parseFunctionSection )
2526 }
2627
2728 parse ( binary : Buffer ) : WasmBinary {
@@ -30,7 +31,7 @@ export class WasmBinaryParser {
3031 const magicNumberRead : string = reader . readBytesToHex ( 4 )
3132
3233 if ( magicNumberRead !== this . WASM_MAGIC_NUMBER ) {
33- throw new Error ( `WASM Magic number not found` )
34+ throw new Error ( `WASM Magic number not found: ${ magicNumberRead } ` )
3435 }
3536 const version = reader . readBytesToHex ( 4 )
3637
@@ -53,24 +54,55 @@ export class WasmBinaryParser {
5354 } )
5455 }
5556
56- // removeme
57- const sec = sections . find ( section => {
58- return section . sectionType . toString ( ) == WasmSectionType [ WasmSectionType . Code . toString ( ) ]
59- } ) ;
60-
61- const imp = sections . find ( section => {
62- return section . sectionType . toString ( ) == WasmSectionType [ WasmSectionType . Import . toString ( ) ]
63- } ) ;
64- console . log ( JSON . stringify ( imp ) )
65- // const outp: WasmCodeSectionPayload = sec.payload as WasmCodeSectionPayload;
66- // console.log(JSON.stringify(outp.functions[1]))
67- // const mapp = outp.functions[3].opcodes.map(p => `[0x${p.opcode.code.toString(16)}] ${p.opcode.name} ${p.immediates}`)
68- // console.log(mapp)
69- // console.log(outp.functions[2].formattedOpcodes)
70- // console.log(JSON.stringify(wasmSections))
71- return {
57+ const wasmBinary : WasmBinary = {
7258 sections
59+ } ;
60+ const wasmPostProcessed = this . postProcess ( wasmBinary ) ;
61+ // console.log(JSON.stringify(wasmPostProcessed))
62+ return wasmPostProcessed
63+ }
64+
65+ postProcess ( wasmBinary : WasmBinary ) : WasmBinary {
66+ const functionSection = findSection ( wasmBinary . sections , WasmSectionType . Function )
67+ const functionSectionPayload : WasmFunctionSectionPayload = functionSection . payload as WasmFunctionSectionPayload
68+
69+ const typeSection = findSection ( wasmBinary . sections , WasmSectionType . Type )
70+ const typeSectionPayload : WasmTypeSectionPayload = typeSection . payload as WasmTypeSectionPayload
71+ const codeSection = findSection ( wasmBinary . sections , WasmSectionType . Code )
72+ const codeSectionPayload : WasmCodeSectionPayload = codeSection . payload as WasmCodeSectionPayload
73+ const exportSection = findSection ( wasmBinary . sections , WasmSectionType . Export )
74+ const exportSectionPayload : WasmExportSectionPayload = exportSection . payload as WasmExportSectionPayload
75+
76+ const importSection = findSection ( wasmBinary . sections , WasmSectionType . Import )
77+ const importSectionPayload : WasmImportSectionPayload = importSection . payload as WasmImportSectionPayload
78+
79+ // adding function signatures & name
80+ for ( let i = 0 ; i < functionSectionPayload . functionsTypes . length ; i ++ ) {
81+ const fun = functionSectionPayload . functionsTypes [ i ]
82+ const funCode = codeSectionPayload . functions [ i ]
83+ const typ = typeSectionPayload . functions [ fun ]
84+ const signature = printSignature ( i , typ )
85+ funCode . functionSignature = signature
86+ funCode . name = `func_${ i } `
87+ }
88+ const numOfImports = importSectionPayload . imports . length
89+ // adding export names to functions
90+ for ( const exp of exportSectionPayload . exports ) {
91+ if ( exp . kind !== getExternalType ( WasmExternalKind . Function . toString ( ) ) ) {
92+ continue
93+ }
94+ const index = exp . index - numOfImports
95+ const fun = codeSectionPayload . functions [ index ]
96+ fun . exportedName = exp . name
7397 }
98+ // formatting opcodes
99+ for ( const fun of codeSectionPayload . functions ) {
100+ const formattedOpcodes = formatOpcodes ( fun . opcodes , importSectionPayload , codeSectionPayload )
101+ fun . formattedOpcodes = formattedOpcodes
102+ // deleting opcodes for now, not really needed in the response, maybe in the future
103+ delete fun . opcodes
104+ }
105+ return wasmBinary
74106 }
75107
76108 parseSectionPayload ( payload : Buffer , sectionId : number ) : WasmSectionPayload {
@@ -91,7 +123,7 @@ export class WasmBinaryParser {
91123 const numberOfElements = reader . readVarUint32 ( )
92124 let index = 0 ;
93125 while ( index < numberOfElements ) {
94- const funcType : FuncType = self . parseFuncType ( reader , index )
126+ const funcType : FuncType = self . parseFuncType ( reader )
95127 sectionPayload . functions . push ( funcType )
96128 index ++
97129 }
@@ -185,13 +217,27 @@ export class WasmBinaryParser {
185217 return limits
186218 }
187219
220+ parseFunctionSection ( payload : Buffer , self : any ) : WasmFunctionSectionPayload {
221+ const reader = new BytesReader ( payload )
222+ const numberOfElements = reader . readVarUint32 ( )
223+ const functionSection : WasmFunctionSectionPayload = {
224+ functionsTypes : [ ]
225+ }
226+ let functionsCounter = 0
227+ while ( functionsCounter < numberOfElements ) {
228+ const functionTypeIndex = reader . readVarUint32 ( )
229+ functionSection . functionsTypes . push ( functionTypeIndex )
230+ functionsCounter ++
231+ }
232+ return functionSection
233+ }
234+
188235 parseCodeSection ( payload : Buffer , self : any ) : WasmCodeSectionPayload {
189236 const reader = new BytesReader ( payload )
190237 const numberOfElements = reader . readVarUint32 ( )
191238 const codeSection : WasmCodeSectionPayload = {
192239 functions : [ ]
193240 }
194- console . log ( `ParsingCodeSection, noElements=${ numberOfElements } ` )
195241 let bodiesCounter = 0
196242 while ( bodiesCounter < numberOfElements ) {
197243 const functionBody = self . parseFunctionCode ( reader )
@@ -226,12 +272,10 @@ export class WasmBinaryParser {
226272 const bytecodeBuffer : Buffer = reader . readBytes ( body . length - reader . getPointer ( ) )
227273 const opcodes : WasmOpcode [ ] = this . parseFunctionBytecode ( bytecodeBuffer )
228274 const bytecodeHex : string = bytecodeBuffer . toString ( 'hex' )
229- const formattedOpcodes = formatOpcodes ( opcodes )
230275 return {
231276 bytecodeHex,
232277 locals,
233- opcodes,
234- formattedOpcodes
278+ opcodes
235279 }
236280 }
237281
@@ -246,7 +290,7 @@ export class WasmBinaryParser {
246290 throw new Error ( `Opcode not implemented: ${ opcodeByte } [${ opcodeByte . toString ( 16 ) } ]` )
247291 }
248292 for ( const immediate of opcodeDefinition . immediates ) {
249- // TODO refactor
293+ // TODO refactor this shit
250294 if ( immediate . type === OpcodeImmediateType . U32 ) {
251295 const immediateValue = reader . readVarUint32 ( )
252296 const valueFormatted = immediateValue < 0 ? `-0x${ ( immediateValue * - 1 ) . toString ( 16 ) } ` : `0x${ immediateValue . toString ( 16 ) } `
@@ -263,6 +307,18 @@ export class WasmBinaryParser {
263307 const immediateValue = reader . readBytesToNumber ( 1 )
264308 const valueFormatted = immediateValue < 0 ? `-0x${ ( immediateValue * - 1 ) . toString ( 16 ) } ` : `0x${ immediateValue . toString ( 16 ) } `
265309 immediates . push ( valueFormatted )
310+ } else if ( immediate . type === OpcodeImmediateType . VECTOR_U32 ) {
311+ const vectorLength = reader . readVarUint32 ( )
312+ let vectorCounter = 0
313+ while ( vectorCounter < vectorLength ) {
314+ const immediateValue = reader . readVarUint32 ( )
315+ const valueFormatted = immediateValue < 0 ? `-0x${ ( immediateValue * - 1 ) . toString ( 16 ) } ` : `0x${ immediateValue . toString ( 16 ) } `
316+ immediates . push ( valueFormatted )
317+ vectorCounter ++
318+ }
319+ const defaultTarget = reader . readVarUint32 ( )
320+ const valueFormatted = defaultTarget < 0 ? `-0x${ ( defaultTarget * - 1 ) . toString ( 16 ) } ` : `0x${ defaultTarget . toString ( 16 ) } `
321+ immediates . push ( valueFormatted )
266322 }
267323 }
268324 opcodes . push ( {
@@ -273,7 +329,7 @@ export class WasmBinaryParser {
273329 return opcodes
274330 }
275331
276- parseFuncType ( reader : BytesReader , index : number ) : FuncType {
332+ parseFuncType ( reader : BytesReader ) : FuncType {
277333 const typeByte = reader . readBytesToNumber ( 1 )
278334 if ( typeByte !== WasmType . FunctionType ) {
279335 throw new Error ( `Error parsing FuncType - type=${ typeByte } not function ` )
@@ -297,7 +353,6 @@ export class WasmBinaryParser {
297353 resultsCounter ++
298354 }
299355 return {
300- index,
301356 params,
302357 results
303358 }
0 commit comments