@@ -4,7 +4,9 @@ import { BytesReader } from "./BytesReader";
44import { WasmSection , WasmTypeSectionPayload , WasmSectionPayload , WasmExportSectionPayload , WasmCodeSectionPayload } from "./WasmSection" ;
55import { WasmSectionType , WasmType , WasmValueType , getWasmValueType , getExternalType } from "./wasmTypes" ;
66import { FuncType } from "./FuncType" ;
7- import { FunctionBody , FunctionLocal } from "./FunctionBody" ;
7+ import { FunctionBody , FunctionLocal , formatOpcodes } from "./FunctionBody" ;
8+ import { WasmOpcode , WasmOpcodeDefinition , WasmOpcodes , Immediate } from "./WasmOpcodes" ;
9+ import { OpcodeImmediateType } from "./OpcodeImmediateType" ;
810
911
1012@injectable ( )
@@ -35,24 +37,34 @@ export class WasmBinaryParser {
3537 throw new Error ( `WASM binary version=${ version } , supported=${ this . WASM_V1 } ` )
3638 }
3739
38- const wasmSections : WasmSection [ ] = [ ]
40+ const sections : WasmSection [ ] = [ ]
3941 while ( ! reader . finished ( ) ) {
4042 const sectionId = reader . readBytesToNumber ( 1 )
4143 const sectionType = WasmSectionType [ sectionId . toString ( ) ]
4244 const payloadLength = reader . readVarUint32 ( )
4345 const payloadData = reader . readBytes ( payloadLength )
4446 const payloadHex = payloadData . toString ( 'hex' )
4547 const payload = this . parseSectionPayload ( payloadData , sectionId )
46- wasmSections . push ( {
48+ sections . push ( {
4749 sectionType,
48- payloadLength,
49- payloadData,
5050 payloadHex,
5151 payload
5252 } )
5353 }
54- console . log ( JSON . stringify ( wasmSections ) )
55- return
54+
55+ // removeme
56+ const sec = sections . find ( section => {
57+ return section . sectionType . toString ( ) == WasmSectionType [ WasmSectionType . Code . toString ( ) ]
58+ } ) ;
59+ const outp : WasmCodeSectionPayload = sec . payload as WasmCodeSectionPayload ;
60+ // console.log(JSON.stringify(outp.functions[1]))
61+ const mapp = outp . functions [ 3 ] . opcodes . map ( p => `[0x${ p . opcode . code . toString ( 16 ) } ] ${ p . opcode . name } ${ p . immediates } ` )
62+ // console.log(mapp)
63+ console . log ( outp . functions [ 2 ] . formattedOpcodes )
64+ // console.log(JSON.stringify(wasmSections))
65+ return {
66+ sections
67+ }
5668 }
5769
5870 parseSectionPayload ( payload : Buffer , sectionId : number ) : WasmSectionPayload {
@@ -142,12 +154,54 @@ export class WasmBinaryParser {
142154 } )
143155 localsCounter ++
144156 }
145- const functionInstructions = reader . readBytes ( body . length - reader . getPointer ( ) )
146- const bytecodeHex = functionInstructions . toString ( 'hex' )
157+ const bytecodeBuffer : Buffer = reader . readBytes ( body . length - reader . getPointer ( ) )
158+ const opcodes : WasmOpcode [ ] = this . parseFunctionBytecode ( bytecodeBuffer )
159+ const bytecodeHex : string = bytecodeBuffer . toString ( 'hex' )
160+ const formattedOpcodes = formatOpcodes ( opcodes )
147161 return {
148162 bytecodeHex,
149- locals
163+ locals,
164+ opcodes,
165+ formattedOpcodes
166+ }
167+ }
168+
169+ parseFunctionBytecode ( bytecode : Buffer ) : WasmOpcode [ ] {
170+ const reader = new BytesReader ( bytecode )
171+ const opcodes : WasmOpcode [ ] = [ ]
172+ while ( ! reader . finished ( ) ) {
173+ const opcodeByte = reader . readBytesToNumber ( 1 )
174+ const immediates : string [ ] = [ ]
175+ const opcodeDefinition : WasmOpcodeDefinition = WasmOpcodes . getDefinition ( opcodeByte )
176+ if ( ! opcodeDefinition ) {
177+ throw new Error ( `Opcode not implemented: ${ opcodeByte } [${ opcodeByte . toString ( 16 ) } ]` )
178+ }
179+ for ( const immediate of opcodeDefinition . immediates ) {
180+ // TODO refactor
181+ if ( immediate . type === OpcodeImmediateType . U32 ) {
182+ const immediateValue = reader . readVarUint32 ( )
183+ const valueFormatted = immediateValue < 0 ? `-0x${ ( immediateValue * - 1 ) . toString ( 16 ) } ` : `0x${ immediateValue . toString ( 16 ) } `
184+ immediates . push ( valueFormatted )
185+ } else if ( immediate . type === OpcodeImmediateType . I32 ) {
186+ const immediateValue = reader . readVarInt32 ( )
187+ const valueFormatted = immediateValue < 0 ? `-0x${ ( immediateValue * - 1 ) . toString ( 16 ) } ` : `0x${ immediateValue . toString ( 16 ) } `
188+ immediates . push ( valueFormatted )
189+ } else if ( immediate . type === OpcodeImmediateType . I64 ) {
190+ const immediateValue = reader . readVarInt64 ( )
191+ const valueFormatted = immediateValue < 0 ? `-0x${ ( immediateValue * - 1 ) . toString ( 16 ) } ` : `0x${ immediateValue . toString ( 16 ) } `
192+ immediates . push ( valueFormatted )
193+ } else if ( immediate . type === OpcodeImmediateType . BYTE ) {
194+ const immediateValue = reader . readBytesToNumber ( 1 )
195+ const valueFormatted = immediateValue < 0 ? `-0x${ ( immediateValue * - 1 ) . toString ( 16 ) } ` : `0x${ immediateValue . toString ( 16 ) } `
196+ immediates . push ( valueFormatted )
197+ }
198+ }
199+ opcodes . push ( {
200+ opcode : opcodeDefinition ,
201+ immediates
202+ } )
150203 }
204+ return opcodes
151205 }
152206
153207 parseFuncType ( reader : BytesReader , index : number ) : FuncType {
0 commit comments