Commit 39efcc85 authored by yann300's avatar yann300 Committed by Iuri Matias

function stack trace

parent 29c4f59c
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
"scripts": { "scripts": {
"diff": "lerna diff", "diff": "lerna diff",
"updated": "lerna updated", "updated": "lerna updated",
"bootstrap": "npm run build-ts-packages; lerna bootstrap", "bootstrap": "lerna bootstrap; npm run build-ts-packages",
"build-ts-packages": "lerna run --scope 'remix-analyzer' --scope 'remix-astwalker' --scope 'remix-solidity' --scope 'remix-tests' --scope 'remix-url-resolver' build", "build-ts-packages": "lerna run --scope 'remix-analyzer' --scope 'remix-astwalker' --scope 'remix-solidity' --scope 'remix-tests' --scope 'remix-url-resolver' build",
"publish": "npm run build-ts-packages; lerna publish", "publish": "npm run build-ts-packages; lerna publish",
"release": "lerna bootstrap; lerna publish;", "release": "lerna bootstrap; lerna publish;",
......
...@@ -58,6 +58,8 @@ class VmDebuggerLogic { ...@@ -58,6 +58,8 @@ class VmDebuggerLogic {
this.event.trigger('indexUpdate', [index]) this.event.trigger('indexUpdate', [index])
this.event.trigger('functionsStackUpdate', [this._callTree.retrieveFunctionsStack(index)])
this._traceManager.getCallDataAt(index, (error, calldata) => { this._traceManager.getCallDataAt(index, (error, calldata) => {
if (error) { if (error) {
// console.log(error) // console.log(error)
......
...@@ -66,6 +66,7 @@ class InternalCallTree { ...@@ -66,6 +66,7 @@ class InternalCallTree {
*/ */
this.sourceLocationTracker.clearCache() this.sourceLocationTracker.clearCache()
this.functionCallStack = [] this.functionCallStack = []
this.functionDefinitionsByScope = {}
this.scopeStarts = {} this.scopeStarts = {}
this.variableDeclarationByFile = {} this.variableDeclarationByFile = {}
this.functionDefinitionByFile = {} this.functionDefinitionByFile = {}
...@@ -79,21 +80,43 @@ class InternalCallTree { ...@@ -79,21 +80,43 @@ class InternalCallTree {
* @param {Int} vmtraceIndex - index on the vm trace * @param {Int} vmtraceIndex - index on the vm trace
*/ */
findScope (vmtraceIndex) { findScope (vmtraceIndex) {
const scopes = Object.keys(this.scopeStarts) let scopeId = this.findScopeId(vmtraceIndex)
if (!scopes.length) { if (!scopeId) return null
return null
}
let scopeId = util.findLowerBoundValue(vmtraceIndex, scopes)
scopeId = this.scopeStarts[scopeId]
let scope = this.scopes[scopeId] let scope = this.scopes[scopeId]
while (scope.lastStep && scope.lastStep < vmtraceIndex && scope.firstStep > 0) { while (scope.lastStep && scope.lastStep < vmtraceIndex && scope.firstStep > 0) {
const matched = scopeId.match(/(.\d|\d)$/) scopeId = this.parentScope(scopeId)
scopeId = scopeId.replace(matched[1], '')
scope = this.scopes[scopeId] scope = this.scopes[scopeId]
} }
return scope return scope
} }
parentScope (scopeId) {
const matched = scopeId.match(/(.\d|\d)$/)
return scopeId.replace(matched[1], '')
}
findScopeId (vmtraceIndex) {
const scopes = Object.keys(this.scopeStarts)
if (!scopes.length) return null
const scopeStart = util.findLowerBoundValue(vmtraceIndex, scopes)
return this.scopeStarts[scopeStart]
}
retrieveFunctionsStack (vmtraceIndex) {
let scope = this.findScope(vmtraceIndex)
if (!scope) return []
let scopeId = this.scopeStarts[scope.firstStep]
let functions = []
if (!scopeId) return functions
while (true) {
functions.push(this.functionDefinitionsByScope[scopeId])
let parent = this.parentScope(scopeId)
if (!parent) break
else scopeId = parent
}
return functions
}
extractSourceLocation (step) { extractSourceLocation (step) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.traceManager.getCurrentCalledAddressAt(step, (error, address) => { this.traceManager.getCurrentCalledAddressAt(step, (error, address) => {
...@@ -220,6 +243,7 @@ function includeVariableDeclaration (tree, step, sourceLocation, scopeId, newLoc ...@@ -220,6 +243,7 @@ function includeVariableDeclaration (tree, step, sourceLocation, scopeId, newLoc
const functionDefinition = resolveFunctionDefinition(tree, step, previousSourceLocation) const functionDefinition = resolveFunctionDefinition(tree, step, previousSourceLocation)
if (functionDefinition && (newLocation && traceHelper.isJumpDestInstruction(tree.traceManager.trace[step - 1]) || functionDefinition.attributes.isConstructor)) { if (functionDefinition && (newLocation && traceHelper.isJumpDestInstruction(tree.traceManager.trace[step - 1]) || functionDefinition.attributes.isConstructor)) {
tree.functionCallStack.push(step) tree.functionCallStack.push(step)
const functionDefinitionAndInputs = {functionDefinition, inputs: []}
// means: the previous location was a function definition && JUMPDEST // means: the previous location was a function definition && JUMPDEST
// => we are at the beginning of the function and input/output are setup // => we are at the beginning of the function and input/output are setup
tree.solidityProxy.contractNameAt(step, (error, contractName) => { // cached tree.solidityProxy.contractNameAt(step, (error, contractName) => { // cached
...@@ -240,7 +264,9 @@ function includeVariableDeclaration (tree, step, sourceLocation, scopeId, newLoc ...@@ -240,7 +264,9 @@ function includeVariableDeclaration (tree, step, sourceLocation, scopeId, newLoc
} }
} }
// input params // input params
if (inputs) addParams(inputs, tree, scopeId, states, contractName, previousSourceLocation, stack.length, inputs.children.length, -1) if (inputs) {
functionDefinitionAndInputs.inputs.push(addParams(inputs, tree, scopeId, states, contractName, previousSourceLocation, stack.length, inputs.children.length, -1))
}
// output params // output params
if (outputs) addParams(outputs, tree, scopeId, states, contractName, previousSourceLocation, stack.length, 0, 1) if (outputs) addParams(outputs, tree, scopeId, states, contractName, previousSourceLocation, stack.length, 0, 1)
} }
...@@ -248,6 +274,7 @@ function includeVariableDeclaration (tree, step, sourceLocation, scopeId, newLoc ...@@ -248,6 +274,7 @@ function includeVariableDeclaration (tree, step, sourceLocation, scopeId, newLoc
}) })
} }
}) })
tree.functionDefinitionsByScope[scopeId] = functionDefinitionAndInputs
} }
} }
...@@ -304,6 +331,7 @@ function extractFunctionDefinitions (ast, astWalker) { ...@@ -304,6 +331,7 @@ function extractFunctionDefinitions (ast, astWalker) {
} }
function addParams (parameterList, tree, scopeId, states, contractName, sourceLocation, stackLength, stackPosition, dir) { function addParams (parameterList, tree, scopeId, states, contractName, sourceLocation, stackLength, stackPosition, dir) {
let params = []
for (let inputParam in parameterList.children) { for (let inputParam in parameterList.children) {
const param = parameterList.children[inputParam] const param = parameterList.children[inputParam]
const stackDepth = stackLength + (dir * stackPosition) const stackDepth = stackLength + (dir * stackPosition)
...@@ -317,9 +345,11 @@ function addParams (parameterList, tree, scopeId, states, contractName, sourceLo ...@@ -317,9 +345,11 @@ function addParams (parameterList, tree, scopeId, states, contractName, sourceLo
stackDepth: stackDepth, stackDepth: stackDepth,
sourceLocation: sourceLocation sourceLocation: sourceLocation
} }
params.push(attributesName)
} }
stackPosition += dir stackPosition += dir
} }
return params
} }
module.exports = InternalCallTree module.exports = InternalCallTree
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment