codeResolver and codeUtils updated

pull/697/head
aniket-engg 4 years ago committed by Aniket
parent 137b6a7ce1
commit 9381d5713b
  1. 91
      libs/remix-debug/src/code/codeResolver.ts
  2. 103
      libs/remix-debug/src/code/codeUtils.ts

@ -1,56 +1,61 @@
'use strict'
const codeUtils = require('./codeUtils')
function CodeResolver ({getCode}) {
this.getCode = getCode
this.bytecodeByAddress = {} // bytes code by contract addesses
this.instructionsByAddress = {} // assembly items instructions list by contract addesses
this.instructionsIndexByBytesOffset = {} // mapping between bytes offset and instructions index.
}
CodeResolver.prototype.clear = function () {
this.bytecodeByAddress = {}
this.instructionsByAddress = {}
this.instructionsIndexByBytesOffset = {}
}
export class CodeResolver {
getCode
bytecodeByAddress
instructionsByAddress
instructionsIndexByBytesOffset
constructor({getCode}) {
this.getCode = getCode
this.bytecodeByAddress = {} // bytes code by contract addesses
this.instructionsByAddress = {} // assembly items instructions list by contract addesses
this.instructionsIndexByBytesOffset = {} // mapping between bytes offset and instructions index.
}
CodeResolver.prototype.resolveCode = async function (address) {
const cache = this.getExecutingCodeFromCache(address)
if (cache) {
return cache
clear () {
this.bytecodeByAddress = {}
this.instructionsByAddress = {}
this.instructionsIndexByBytesOffset = {}
}
const code = await this.getCode(address)
return this.cacheExecutingCode(address, code)
}
async resolveCode (address) {
const cache = this.getExecutingCodeFromCache(address)
if (cache) {
return cache
}
CodeResolver.prototype.cacheExecutingCode = function (address, hexCode) {
const codes = this.formatCode(hexCode)
this.bytecodeByAddress[address] = hexCode
this.instructionsByAddress[address] = codes.code
this.instructionsIndexByBytesOffset[address] = codes.instructionsIndexByBytesOffset
return this.getExecutingCodeFromCache(address)
}
const code = await this.getCode(address)
return this.cacheExecutingCode(address, code)
}
CodeResolver.prototype.formatCode = function (hexCode) {
const [code, instructionsIndexByBytesOffset] = codeUtils.nameOpCodes(Buffer.from(hexCode.substring(2), 'hex'))
return {code, instructionsIndexByBytesOffset}
}
cacheExecutingCode (address, hexCode) {
const codes = this.formatCode(hexCode)
this.bytecodeByAddress[address] = hexCode
this.instructionsByAddress[address] = codes.code
this.instructionsIndexByBytesOffset[address] = codes.instructionsIndexByBytesOffset
return this.getExecutingCodeFromCache(address)
}
CodeResolver.prototype.getExecutingCodeFromCache = function (address) {
if (!this.instructionsByAddress[address]) {
return null
formatCode (hexCode) {
const [code, instructionsIndexByBytesOffset] = codeUtils.nameOpCodes(Buffer.from(hexCode.substring(2), 'hex'))
return {code, instructionsIndexByBytesOffset}
}
return {
instructions: this.instructionsByAddress[address],
instructionsIndexByBytesOffset: this.instructionsIndexByBytesOffset[address],
bytecode: this.bytecodeByAddress[address]
getExecutingCodeFromCache (address) {
if (!this.instructionsByAddress[address]) {
return null
}
return {
instructions: this.instructionsByAddress[address],
instructionsIndexByBytesOffset: this.instructionsIndexByBytesOffset[address],
bytecode: this.bytecodeByAddress[address]
}
}
}
CodeResolver.prototype.getInstructionIndex = function (address, pc) {
return this.getExecutingCodeFromCache(address).instructionsIndexByBytesOffset[pc]
getInstructionIndex (address, pc) {
return this.getExecutingCodeFromCache(address).instructionsIndexByBytesOffset[pc]
}
}
module.exports = CodeResolver

@ -1,66 +1,65 @@
'use strict'
const opcodes = require('./opcodes')
module.exports = {
nameOpCodes: function (raw) {
let pushData = ''
const codeMap = {}
const code = []
export function nameOpCodes (raw) {
let pushData = ''
const codeMap = {}
const code = []
for (let i = 0; i < raw.length; i++) {
const pc = i
const curOpCode = opcodes(raw[pc], false).name
codeMap[i] = code.length
// no destinations into the middle of PUSH
if (curOpCode.slice(0, 4) === 'PUSH') {
const jumpNum = raw[pc] - 0x5f
pushData = raw.slice(pc + 1, pc + jumpNum + 1)
i += jumpNum
}
for (let i = 0; i < raw.length; i++) {
const pc = i
const curOpCode = opcodes(raw[pc], false).name
codeMap[i] = code.length
// no destinations into the middle of PUSH
if (curOpCode.slice(0, 4) === 'PUSH') {
const jumpNum = raw[pc] - 0x5f
pushData = raw.slice(pc + 1, pc + jumpNum + 1)
i += jumpNum
}
const data = pushData.toString('hex') !== '' ? ' ' + pushData.toString('hex') : ''
const data = pushData.toString() !== '' ? ' ' + pushData.toString() : ''
code.push(this.pad(pc, this.roundLog(raw.length, 10)) + ' ' + curOpCode + data)
pushData = ''
}
return [ code, codeMap ]
},
code.push(this.pad(pc, this.roundLog(raw.length, 10)) + ' ' + curOpCode + data)
pushData = ''
}
return [ code, codeMap ]
}
/**
* Parses code as a list of integers into a list of objects containing
* information about the opcode.
*/
parseCode: function (raw) {
const code = []
for (let i = 0; i < raw.length; i++) {
const opcode = opcodes(raw[i], true)
if (opcode.name.slice(0, 4) === 'PUSH') {
const length = raw[i] - 0x5f
opcode.pushData = raw.slice(i + 1, i + length + 1)
// in case pushdata extends beyond code
if (i + 1 + length > raw.length) {
for (let j = opcode.pushData.length; j < length; j++) {
opcode.pushData.push(0)
}
/**
* Parses code as a list of integers into a list of objects containing
* information about the opcode.
*/
export function parseCode (raw) {
const code = []
for (let i = 0; i < raw.length; i++) {
const opcode = opcodes(raw[i], true)
if (opcode.name.slice(0, 4) === 'PUSH') {
const length = raw[i] - 0x5f
opcode.pushData = raw.slice(i + 1, i + length + 1)
// in case pushdata extends beyond code
if (i + 1 + length > raw.length) {
for (let j = opcode.pushData.length; j < length; j++) {
opcode.pushData.push(0)
}
i += length
}
code.push(opcode)
i += length
}
return code
},
code.push(opcode)
}
return code
}
pad: function (num, size) {
let s = num + ''
while (s.length < size) s = '0' + s
return s
},
export function pad (num, size) {
let s = num + ''
while (s.length < size) s = '0' + s
return s
}
log: function (num, base) {
return Math.log(num) / Math.log(base)
},
export function log (num, base) {
return Math.log(num) / Math.log(base)
}
roundLog: function (num, base) {
return Math.ceil(this.log(num, base))
}
export function roundLog (num, base) {
return Math.ceil(this.log(num, base))
}

Loading…
Cancel
Save