From c05ca38903672f2ea8f975d3d470aa9db6abe115 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Fri, 17 Jul 2020 15:10:03 -0400 Subject: [PATCH] refactor getStackAt --- libs/remix-debug/src/Ethdebugger.js | 9 ++- libs/remix-debug/src/debugger/VmDebugger.js | 12 +-- .../src/debugger/solidityLocals.js | 10 ++- .../src/solidity-decoder/internalCallTree.js | 74 ++++++++++--------- libs/remix-debug/test/debugger.js | 18 +++-- .../test/decoder/localsTests/helper.js | 9 ++- libs/remix-lib/src/trace/traceManager.js | 15 ++-- libs/remix-lib/test/traceManager.js | 28 ++++--- 8 files changed, 98 insertions(+), 77 deletions(-) diff --git a/libs/remix-debug/src/Ethdebugger.js b/libs/remix-debug/src/Ethdebugger.js index 4c4f071e69..9203147dfe 100644 --- a/libs/remix-debug/src/Ethdebugger.js +++ b/libs/remix-debug/src/Ethdebugger.js @@ -90,7 +90,14 @@ Ethdebugger.prototype.extractLocalsAt = function (step, callback) { Ethdebugger.prototype.decodeLocalsAt = function (step, sourceLocation, callback) { const self = this this.traceManager.waterfall([ - this.traceManager.getStackAt, + function getStackAt (stepIndex, callback) { + try { + const result = self.traceManager.getStackAt(stepIndex) + callback(null, result) + } catch (error) { + callback(error) + } + }, this.traceManager.getMemoryAt, function getCurrentCalledAddressAt (stepIndex, next) { try { diff --git a/libs/remix-debug/src/debugger/VmDebugger.js b/libs/remix-debug/src/debugger/VmDebugger.js index 5b548b8a19..0cec534b75 100644 --- a/libs/remix-debug/src/debugger/VmDebugger.js +++ b/libs/remix-debug/src/debugger/VmDebugger.js @@ -87,14 +87,14 @@ class VmDebuggerLogic { this.event.trigger('traceManagerCallStackUpdate', [{}]) } - this._traceManager.getStackAt(index, (error, callstack) => { - if (error) { - // console.log(error) - this.event.trigger('traceManagerStackUpdate', [{}]) - } else if (this.stepManager.currentStepIndex === index) { + try { + const callstack = this._traceManager.getStackAt(index) + if (this.stepManager.currentStepIndex === index) { this.event.trigger('traceManagerStackUpdate', [callstack]) } - }) + } catch (error) { + this.event.trigger('traceManagerStackUpdate', [{}]) + } try { const address = this._traceManager.getCurrentCalledAddressAt(index) diff --git a/libs/remix-debug/src/debugger/solidityLocals.js b/libs/remix-debug/src/debugger/solidityLocals.js index 4e04af9e79..13f974692f 100644 --- a/libs/remix-debug/src/debugger/solidityLocals.js +++ b/libs/remix-debug/src/debugger/solidityLocals.js @@ -30,9 +30,17 @@ class DebuggerSolidityLocals { } decode (sourceLocation) { + const self = this this.event.trigger('solidityLocalsMessage', ['']) this.traceManager.waterfall([ - this.traceManager.getStackAt, + function getStackAt (stepIndex, callback) { + try { + const result = self.traceManager.getStackAt(stepIndex) + callback(null, result) + } catch (error) { + callback(error) + } + }, this.traceManager.getMemoryAt, function getCurrentCalledAddressAt (stepIndex, next) { try { diff --git a/libs/remix-debug/src/solidity-decoder/internalCallTree.js b/libs/remix-debug/src/solidity-decoder/internalCallTree.js index a1c9da1969..9b18a383d4 100644 --- a/libs/remix-debug/src/solidity-decoder/internalCallTree.js +++ b/libs/remix-debug/src/solidity-decoder/internalCallTree.js @@ -224,26 +224,26 @@ function includeVariableDeclaration (tree, step, sourceLocation, scopeId, newLoc // we check if the current vm trace step target a new ast node of type VariableDeclaration // that way we know that there is a new local variable from here. if (variableDeclaration && !tree.scopes[scopeId].locals[variableDeclaration.attributes.name]) { - tree.traceManager.getStackAt(step, (error, stack) => { + try { + const stack = tree.traceManager.getStackAt(step) // the stack length at this point is where the value of the new local variable will be stored. // so, either this is the direct value, or the offset in memory. That depends on the type. - if (!error) { - tree.solidityProxy.contractNameAt(step, (error, contractName) => { // cached - if (!error && variableDeclaration.attributes.name !== '') { - var states = tree.solidityProxy.extractStatesDefinitions() - var location = typesUtil.extractLocationFromAstVariable(variableDeclaration) - location = location === 'default' ? 'storage' : location + tree.solidityProxy.contractNameAt(step, (error, contractName) => { // cached + if (!error && variableDeclaration.attributes.name !== '') { + var states = tree.solidityProxy.extractStatesDefinitions() + var location = typesUtil.extractLocationFromAstVariable(variableDeclaration) + location = location === 'default' ? 'storage' : location // we push the new local variable in our tree - tree.scopes[scopeId].locals[variableDeclaration.attributes.name] = { - name: variableDeclaration.attributes.name, - type: decodeInfo.parseType(variableDeclaration.attributes.type, states, contractName, location), - stackDepth: stack.length, - sourceLocation: sourceLocation - } + tree.scopes[scopeId].locals[variableDeclaration.attributes.name] = { + name: variableDeclaration.attributes.name, + type: decodeInfo.parseType(variableDeclaration.attributes.type, states, contractName, location), + stackDepth: stack.length, + sourceLocation: sourceLocation } - }) - } - }) + } + }) + } catch (error) { + } } // we check here if we are at the beginning inside a new function. // if that is the case, we have to add to locals tree the inputs and output params @@ -253,34 +253,36 @@ function includeVariableDeclaration (tree, step, sourceLocation, scopeId, newLoc const functionDefinitionAndInputs = {functionDefinition, inputs: []} // means: the previous location was a function definition && JUMPDEST // => we are at the beginning of the function and input/output are setup + tree.solidityProxy.contractNameAt(step, (error, contractName) => { // cached if (!error) { - tree.traceManager.getStackAt(step, (error, stack) => { - if (!error) { - var states = tree.solidityProxy.extractStatesDefinitions() - if (functionDefinition.children && functionDefinition.children.length) { - let inputs - let outputs - for (const element of functionDefinition.children) { - if (element.name === 'ParameterList') { - if (!inputs) inputs = element - else { - outputs = element - break - } + try { + const stack = tree.traceManager.getStackAt(step) + var states = tree.solidityProxy.extractStatesDefinitions() + if (functionDefinition.children && functionDefinition.children.length) { + let inputs + let outputs + for (const element of functionDefinition.children) { + if (element.name === 'ParameterList') { + if (!inputs) inputs = element + else { + outputs = element + break } } - // input params - if (inputs) { - functionDefinitionAndInputs.inputs = addParams(inputs, tree, scopeId, states, contractName, previousSourceLocation, stack.length, inputs.children.length, -1) - } - // output params - if (outputs) addParams(outputs, tree, scopeId, states, contractName, previousSourceLocation, stack.length, 0, 1) } + // input params + if (inputs) { + functionDefinitionAndInputs.inputs = addParams(inputs, tree, scopeId, states, contractName, previousSourceLocation, stack.length, inputs.children.length, -1) + } + // output params + if (outputs) addParams(outputs, tree, scopeId, states, contractName, previousSourceLocation, stack.length, 0, 1) } - }) + } catch (error) { + } } }) + tree.functionDefinitionsByScope[scopeId] = functionDefinitionAndInputs } } diff --git a/libs/remix-debug/test/debugger.js b/libs/remix-debug/test/debugger.js index 946e21b43d..7d0a47c2dc 100644 --- a/libs/remix-debug/test/debugger.js +++ b/libs/remix-debug/test/debugger.js @@ -193,23 +193,27 @@ function testDebugging (debugManager) { // stack tape('traceManager.getStackAt 4', (t) => { t.plan(1) - debugManager.traceManager.getStackAt(4, (error, callstack) => { - if (error) return t.end(error) - t.equal(JSON.stringify(callstack), JSON.stringify([ '0x0000000000000000000000000000000000000000000000000000000000000000' ])) - }) + try { + const callstack = debugManager.traceManager.getStackAt(4) + t.equal(JSON.stringify(callstack), JSON.stringify(['0x0000000000000000000000000000000000000000000000000000000000000000'])) + } catch (error) { + return t.end(error) + } }) tape('traceManager.getStackAt 41', (t) => { t.plan(1) - debugManager.traceManager.getStackAt(41, (error, callstack) => { - if (error) return t.end(error) + try { + const callstack = debugManager.traceManager.getStackAt(41) t.equal(JSON.stringify(callstack), JSON.stringify([ '0x0000000000000000000000000000000000000000000000000000000000000080', '0x0000000000000000000000000000000000000000000000000000000000000020', '0x0000000000000000000000000000000000000000000000000000000000000080', '0x00000000000000000000000000000000000000000000000000000000000000e0', '0x00000000000000000000000000000000000000000000000000000000000000e0'])) - }) + } catch (error) { + return t.end(error) + } }) // storage diff --git a/libs/remix-debug/test/decoder/localsTests/helper.js b/libs/remix-debug/test/decoder/localsTests/helper.js index b30c39cb21..f2b3cce9f8 100644 --- a/libs/remix-debug/test/decoder/localsTests/helper.js +++ b/libs/remix-debug/test/decoder/localsTests/helper.js @@ -7,7 +7,14 @@ var localDecoder = require('../../../src/solidity-decoder/localDecoder') function decodeLocal (st, index, traceManager, callTree, verifier) { try { traceManager.waterfall([ - traceManager.getStackAt, + function getStackAt (stepIndex, callback) { + try { + const result = traceManager.getStackAt(stepIndex) + callback(null, result) + } catch (error) { + callback(error) + } + }, traceManager.getMemoryAt], index, function (error, result) { diff --git a/libs/remix-lib/src/trace/traceManager.js b/libs/remix-lib/src/trace/traceManager.js index 7065f76cf5..cddb116f60 100644 --- a/libs/remix-lib/src/trace/traceManager.js +++ b/libs/remix-lib/src/trace/traceManager.js @@ -124,19 +124,14 @@ TraceManager.prototype.getCallStackAt = function (stepIndex) { return call.callStack } -TraceManager.prototype.getStackAt = function (stepIndex, callback) { - try { - this.checkRequestedStep(stepIndex) - } catch (check) { - return callback(check, null) - } - let stack +TraceManager.prototype.getStackAt = function (stepIndex) { + this.checkRequestedStep(stepIndex) if (this.trace[stepIndex] && this.trace[stepIndex].stack) { // there's always a stack - stack = this.trace[stepIndex].stack.slice(0) + let stack = this.trace[stepIndex].stack.slice(0) stack.reverse() - callback(null, stack) + return stack } else { - callback('no stack found', null) + throw new Error('no stack found') } } diff --git a/libs/remix-lib/test/traceManager.js b/libs/remix-lib/test/traceManager.js index 818582761f..4a8a963faf 100644 --- a/libs/remix-lib/test/traceManager.js +++ b/libs/remix-lib/test/traceManager.js @@ -96,24 +96,22 @@ tape('TraceManager', function (t) { t.test('TraceManager.getStackAt', function (st) { st.plan(3) - traceManager.getStackAt(0, function (error, result) { + try { + const result = traceManager.getStackAt(0) console.log(result) - if (error) { - st.fail(error) - } else { - st.ok(result.length === 0) - } - }) + st.ok(result.length === 0) + } catch (error) { + st.fail(error) + } - traceManager.getStackAt(28, function (error, result) { + try { + const result = traceManager.getStackAt(28) console.log(result) - if (error) { - st.fail(error) - } else { - st.ok(result.length === 4) - st.ok(result[3] === '0x60fe47b1') - } - }) + st.ok(result.length === 4) + st.ok(result[3] === '0x60fe47b1') + } catch (error) { + st.fail(error) + } }) t.test('TraceManager.getLastCallChangeSince', function (st) {