show line number in the opcodes list

pull/5370/head
yann300 2 years ago
parent 8d88218d21
commit 41702522c8
  1. 30
      libs/remix-debug/src/debugger/debugger.ts
  2. 8
      libs/remix-debug/src/solidity-decoder/internalCallTree.ts
  3. 4
      libs/remix-debug/test/decoder/localsTests/int.ts
  4. 10
      libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx
  5. 24
      libs/remix-ui/debugger-ui/src/reducers/assembly-items.ts

@ -14,6 +14,8 @@ export class Debugger {
breakPointManager
step_manager // eslint-disable-line camelcase
vmDebuggerLogic
currentFile = -1
currentLine = -1
constructor (options) {
this.event = new EventManager()
@ -74,6 +76,9 @@ export class Debugger {
const compilationResultForAddress = await this.compilationResult(address)
if (!compilationResultForAddress) {
this.event.trigger('newSourceLocation', [null])
this.currentFile = -1
this.currentLine = -1
this.vmDebuggerLogic.event.trigger('lineGasCostChanged', [null])
return
}
@ -92,26 +97,43 @@ export class Debugger {
}
const lineColumnPos = await this.offsetToLineColumnConverter.offsetToLineColumn(rawLocation, rawLocation.file, sources, astSources)
let lineGasCost = -1
let lineGasCostObj = null
try {
lineGasCost = await this.debugger.callTree.getGasCostPerLine(rawLocation.file, lineColumnPos.start.line)
lineGasCostObj = await this.debugger.callTree.getGasCostPerLine(rawLocation.file, lineColumnPos.start.line)
} catch (e) {
console.log(e)
}
this.event.trigger('newSourceLocation', [lineColumnPos, rawLocation, generatedSources, address, stepDetail, lineGasCost])
this.event.trigger('newSourceLocation', [lineColumnPos, rawLocation, generatedSources, address, stepDetail, (lineGasCostObj && lineGasCostObj.gasCost) || -1])
this.vmDebuggerLogic.event.trigger('sourceLocationChanged', [rawLocation])
if (this.currentFile !== rawLocation.file || this.currentLine !== lineColumnPos.start.line) {
const instructionIndexes = lineGasCostObj.indexes.map((index) => { // translate from vmtrace index to instruction index
return this.debugger.codeManager.getInstructionIndex(address, index)
})
this.vmDebuggerLogic.event.trigger('lineGasCostChanged', [instructionIndexes, lineColumnPos.start.line ])
this.currentFile = rawLocation.file
this.currentLine = lineColumnPos.start.line
}
} else {
this.event.trigger('newSourceLocation', [null])
this.vmDebuggerLogic.event.trigger('sourceLocationChanged', [null])
this.vmDebuggerLogic.event.trigger('lineGasCostChanged', [null])
this.currentFile = -1
this.currentLine = -1
this.vmDebuggerLogic.event.trigger('lineGasCostChanged', [null])
}
}).catch((_error) => {
this.event.trigger('newSourceLocation', [null])
this.vmDebuggerLogic.event.trigger('sourceLocationChanged', [null])
this.currentFile = -1
this.currentLine = -1
this.vmDebuggerLogic.event.trigger('lineGasCostChanged', [null])
})
// })
} catch (error) {
this.event.trigger('newSourceLocation', [null])
this.vmDebuggerLogic.event.trigger('sourceLocationChanged', [null])
this.currentFile = -1
this.currentLine = -1
this.vmDebuggerLogic.event.trigger('lineGasCostChanged', [null])
return console.log(error)
}
}

@ -259,9 +259,13 @@ async function buildTree (tree, step, scopeId, isExternalCall, isCreation, funct
const lineColumnPos = await tree.offsetToLineColumnConverter.offsetToLineColumn(validSourceLocation, validSourceLocation.file, tree.solidityProxy.sourcesCode, tree.solidityProxy.sources)
if (!tree.gasCostPerLine[validSourceLocation.file]) tree.gasCostPerLine[validSourceLocation.file] = {}
if (!tree.gasCostPerLine[validSourceLocation.file][lineColumnPos.start.line]) {
tree.gasCostPerLine[validSourceLocation.file][lineColumnPos.start.line] = 0
tree.gasCostPerLine[validSourceLocation.file][lineColumnPos.start.line] = {
gasCost: 0,
indexes: []
}
}
tree.gasCostPerLine[validSourceLocation.file][lineColumnPos.start.line] += stepDetail.gasCost
tree.gasCostPerLine[validSourceLocation.file][lineColumnPos.start.line].gasCost += stepDetail.gasCost
tree.gasCostPerLine[validSourceLocation.file][lineColumnPos.start.line].indexes.push(step)
} catch (e) {
console.log(e)
}

@ -47,8 +47,8 @@ module.exports = function (st, privateKey, contractBytecode, compilationResult,
try {
// test gas cost per line
st.equals(await callTree.getGasCostPerLine(0, 16), 11)
st.equals(await callTree.getGasCostPerLine(0, 32), 60)
st.equals((await callTree.getGasCostPerLine(0, 16)).gasCost, 11)
st.equals((await callTree.getGasCostPerLine(0, 32)).gasCost, 60)
let functions1 = callTree.retrieveFunctionsStack(102)
let functions2 = callTree.retrieveFunctionsStack(115)

@ -1,3 +1,4 @@
import { stateDecoder } from 'dist/libs/remix-debug/src/solidity-decoder'
import React, { useState, useRef, useEffect, useReducer } from 'react' // eslint-disable-line
import { initialState, reducer } from '../../reducers/assembly-items'
import './styles/assembly-items.css'
@ -9,6 +10,7 @@ export const AssemblyItems = ({ registerEvent }) => {
const [nextSelectedItems, setNextSelectedItems] = useState([1])
const [returnInstructionIndexes, setReturnInstructionIndexes] = useState([])
const [outOfGasInstructionIndexes, setOutOfGasInstructionIndexes] = useState([])
const [opcodeTooltipText, setOpcodeTooltipText] = useState('')
const refs = useRef({})
const asmItemsRef = useRef(null)
@ -16,6 +18,10 @@ export const AssemblyItems = ({ registerEvent }) => {
registerEvent && registerEvent('codeManagerChanged', (code, address, index, nextIndexes, returnInstructionIndexes, outOfGasInstructionIndexes) => {
dispatch({ type: 'FETCH_OPCODES_SUCCESS', payload: { code, address, index, nextIndexes, returnInstructionIndexes, outOfGasInstructionIndexes } })
})
registerEvent && registerEvent('lineGasCostChanged', (instructionsIndexes: number[], line: []) => {
dispatch({ type: 'FETCH_INDEXES_FOR_NEW_LINE', payload: { currentLineIndexes: instructionsIndexes || [], line } })
})
}, [])
useEffect(() => {
@ -129,7 +135,9 @@ export const AssemblyItems = ({ registerEvent }) => {
<div className="pl-2 my-1 small instructions" data-id="asmitems" id='asmitems' ref={asmItemsRef}>
{
assemblyItems.display.map((item, i) => {
return <div className="px-1" key={i} ref={ref => { refs.current[i] = ref }}><span>{item}</span></div>
return <div className="px-1" key={i} ref={ref => { refs.current[i] = ref }}>
<span>{item}</span>{assemblyItems.currentLineIndexes.includes(i) ? <span><i><b> - LINE {assemblyItems.line + 1}</b></i></span> : ' - '}
</div>
})
}
</div>

@ -13,6 +13,7 @@ export const initialState = {
},
display: [],
index: 0,
initialIndex: 0,
nextIndexes: [-1],
returnInstructionIndexes: [],
outOfGasInstructionIndexes: [],
@ -20,7 +21,10 @@ export const initialState = {
bottom: 0,
isRequesting: false,
isSuccessful: false,
hasError: null
hasError: null,
absoluteCurrentLineIndexes: [],
currentLineIndexes: [],
line: -1
}
const reducedOpcode = (opCodes, payload) => {
@ -31,6 +35,7 @@ const reducedOpcode = (opCodes, payload) => {
return {
index: opCodes.index - bottom,
nextIndexes: opCodes.nextIndexes.map(index => index - bottom),
currentLineIndexes: (opCodes.absoluteCurrentLineIndexes && opCodes.absoluteCurrentLineIndexes.map(index => index - bottom)) || [],
display: opCodes.code.slice(bottom, top),
returnInstructionIndexes: payload.returnInstructionIndexes.map((index) => index.instructionIndex - bottom),
outOfGasInstructionIndexes: payload.outOfGasInstructionIndexes.map((index) => index.instructionIndex - bottom)
@ -49,20 +54,23 @@ export const reducer = (state = initialState, action: Action) => {
}
case 'FETCH_OPCODES_SUCCESS': {
const opCodes = action.payload.address === state.opCodes.address ? {
...state.opCodes, index: action.payload.index, nextIndexes: action.payload.nextIndexes
...state.opCodes, index: action.payload.index, nextIndexes: action.payload.nextIndexes, absoluteCurrentLineIndexes: state.absoluteCurrentLineIndexes
} : deepEqual(action.payload.code, state.opCodes.code) ? state.opCodes : action.payload
const reduced = reducedOpcode(opCodes, action.payload)
return {
...state,
opCodes,
display: reduced.display,
initialIndex: action.payload.index,
index: reduced.index,
nextIndexes: reduced.nextIndexes,
isRequesting: false,
isSuccessful: true,
hasError: null,
returnInstructionIndexes: reduced.returnInstructionIndexes,
outOfGasInstructionIndexes: reduced.outOfGasInstructionIndexes
outOfGasInstructionIndexes: reduced.outOfGasInstructionIndexes,
currentLineIndexes: reduced.currentLineIndexes
}
}
case 'FETCH_OPCODES_ERROR': {
@ -73,6 +81,16 @@ export const reducer = (state = initialState, action: Action) => {
hasError: action.payload
}
}
case 'FETCH_INDEXES_FOR_NEW_LINE': {
let bottom = state.initialIndex - 10
bottom = bottom < 0 ? 0 : bottom
return {
...state,
absoluteCurrentLineIndexes: action.payload.currentLineIndexes,
currentLineIndexes: action.payload.currentLineIndexes.map(index => index - bottom),
line: action.payload.line
}
}
default:
throw new Error()
}

Loading…
Cancel
Save