Commit 1234a0d5 authored by yann300's avatar yann300

sourceLocationTracker

parent 6af21774
...@@ -25,39 +25,45 @@ CodeManager.prototype.resolveStep = function (stepIndex, tx) { ...@@ -25,39 +25,45 @@ CodeManager.prototype.resolveStep = function (stepIndex, tx) {
this.trigger('resolvingStep') this.trigger('resolvingStep')
var self = this var self = this
if (stepIndex === 0) { if (stepIndex === 0) {
self.getCode(tx.to, stepIndex, tx) self.retrieveCodeAndTrigger(tx.to, stepIndex, tx)
} else { } else {
this.traceManager.getCurrentCalledAddressAt(stepIndex, function (error, address) { this.traceManager.getCurrentCalledAddressAt(stepIndex, function (error, address) {
if (error) { if (error) {
console.log(error) console.log(error)
} else { } else {
self.getCode(address, stepIndex, tx) self.retrieveCodeAndTrigger(address, stepIndex, tx)
} }
}) })
} }
} }
CodeManager.prototype.getCode = function (address, currentStep, tx) { CodeManager.prototype.retrieveCodeAndTrigger = function (address, stepIndex, tx) {
var self = this var self = this
this.getCode(address, function (error, result) {
if (!error) {
self.retrieveIndexAndTrigger(address, stepIndex, result.instructions)
} else {
console.log(error)
}
})
}
CodeManager.prototype.getCode = function (address, cb) {
if (traceHelper.isContractCreation(address)) { if (traceHelper.isContractCreation(address)) {
var codes = codeResolver.getExecutingCodeFromCache(address) var codes = codeResolver.getExecutingCodeFromCache(address)
if (!codes) { if (!codes) {
this.traceManager.getContractCreationCode(address, function (error, hexCode) { this.traceManager.getContractCreationCode(address, function (error, hexCode) {
// contract creation if (!error) {
if (error) {
console.log(error)
} else {
codes = codeResolver.cacheExecutingCode(address, hexCode) codes = codeResolver.cacheExecutingCode(address, hexCode)
self.retrieveIndexAndTrigger(address, currentStep, codes.code) cb(null, codes)
} }
}) })
} else { } else {
self.retrieveIndexAndTrigger(address, currentStep, codes.code) cb(null, codes)
} }
} else { } else {
codeResolver.resolveCode(address, function (address, code) { codeResolver.resolveCode(address, function (address, code) {
// resoling code from stack cb(null, code)
self.retrieveIndexAndTrigger(address, currentStep, code)
}) })
} }
} }
......
...@@ -3,19 +3,20 @@ var codeUtils = require('./codeUtils') ...@@ -3,19 +3,20 @@ var codeUtils = require('./codeUtils')
var util = require('../helpers/global') var util = require('../helpers/global')
module.exports = { module.exports = {
codes: {}, // assembly items instructions list by contract addesses bytecodeByAddress: {}, // bytes code by contract addesses
instructionsByAddress: {}, // assembly items instructions list by contract addesses
instructionsIndexByBytesOffset: {}, // mapping between bytes offset and instructions index. instructionsIndexByBytesOffset: {}, // mapping between bytes offset and instructions index.
resolveCode: function (address, callBack) { resolveCode: function (address, callBack) {
var cache = this.getExecutingCodeFromCache(address) var cache = this.getExecutingCodeFromCache(address)
if (cache) { if (cache) {
callBack(address, cache.code) callBack(address, cache)
return return
} }
var self = this var self = this
this.loadCode(address, function (code) { this.loadCode(address, function (code) {
callBack(address, self.cacheExecutingCode(address, code).code) callBack(address, self.cacheExecutingCode(address, code))
}) })
}, },
...@@ -32,9 +33,10 @@ module.exports = { ...@@ -32,9 +33,10 @@ module.exports = {
cacheExecutingCode: function (address, hexCode) { cacheExecutingCode: function (address, hexCode) {
var codes = this.formatCode(hexCode) var codes = this.formatCode(hexCode)
this.codes[address] = codes.code this.bytecodeByAddress[address] = hexCode
this.instructionsByAddress[address] = codes.code
this.instructionsIndexByBytesOffset[address] = codes.instructionsIndexByBytesOffset this.instructionsIndexByBytesOffset[address] = codes.instructionsIndexByBytesOffset
return codes return this.getExecutingCodeFromCache(address)
}, },
formatCode: function (hexCode) { formatCode: function (hexCode) {
...@@ -46,10 +48,11 @@ module.exports = { ...@@ -46,10 +48,11 @@ module.exports = {
}, },
getExecutingCodeFromCache: function (address) { getExecutingCodeFromCache: function (address) {
if (this.codes[address]) { if (this.instructionsByAddress[address]) {
return { return {
code: this.codes[address], instructions: this.instructionsByAddress[address],
instructionsIndexByBytesOffset: this.instructionsIndexByBytesOffset[address] instructionsIndexByBytesOffset: this.instructionsIndexByBytesOffset[address],
bytecode: this.bytecodeByAddress[address]
} }
} else { } else {
return null return null
......
'use strict'
var EventManager = require('../lib/eventManager')
var util = require('../helpers/global')
var helper = require('../helpers/traceHelper')
var SourceMappingDecoder = require('../util/sourceMappingDecoder')
/**
* Process the source code location for the current executing bytecode
*/
function SourceLocationTracker (_codeManager) {
this.codeManager = _codeManager
util.extend(this, new EventManager())
this.sourceMappingDecoder = new SourceMappingDecoder()
}
/**
* Return the source location associated with the given @arg index
*
* @param {String} address - contract address from which the source location is retrieved
* @param {Int} index - index in the instruction list from where the source location is retrieved
* @param {Object} contractDetails - AST of compiled contracts
* @param {Function} cb - callback function
*/
SourceLocationTracker.prototype.getSourceLocation = function (address, index, contractsDetails, cb) {
var self = this
this.codeManager.getCode(address, function (error, result) {
if (!error) {
var sourceMap = getSourceMap(address, result.bytecode, contractsDetails)
if (sourceMap) {
cb(null, self.sourceMappingDecoder.atIndex(index, sourceMap))
} else {
cb('no srcmap associated with the code ' + address)
}
} else {
cb(error)
}
})
}
/**
* backwards compatibility - attribute name will certainly be changed
*/
function srcmapRuntime (contract) {
return contract.srcmapRuntime ? contract.srcmapRuntime : contract['srcmap-runtime']
}
function getSourceMap (address, code, contractsDetails) {
var isCreation = helper.isContractCreation(address)
var byteProp = isCreation ? 'bytecode' : 'runtimeBytecode'
for (var k in contractsDetails) {
if ('0x' + contractsDetails[k][byteProp] === code) {
return isCreation ? contractsDetails[k].srcmap : srcmapRuntime(contractsDetails[k])
}
}
return null
}
module.exports = SourceLocationTracker
...@@ -12,6 +12,7 @@ var ui = require('../helpers/ui') ...@@ -12,6 +12,7 @@ var ui = require('../helpers/ui')
var Web3Providers = require('../web3Provider/web3Providers') var Web3Providers = require('../web3Provider/web3Providers')
var DummyProvider = require('../web3Provider/dummyProvider') var DummyProvider = require('../web3Provider/dummyProvider')
var CodeManager = require('../code/codeManager') var CodeManager = require('../code/codeManager')
var SourceLocationTracker = require('../code/sourceLocationTracker')
function Ethdebugger () { function Ethdebugger () {
util.extend(this, new EventManager()) util.extend(this, new EventManager())
...@@ -26,6 +27,7 @@ function Ethdebugger () { ...@@ -26,6 +27,7 @@ function Ethdebugger () {
this.switchProvider('DUMMYWEB3') this.switchProvider('DUMMYWEB3')
this.traceManager = new TraceManager() this.traceManager = new TraceManager()
this.codeManager = new CodeManager(this.traceManager) this.codeManager = new CodeManager(this.traceManager)
this.sourceLocationTracker = new SourceLocationTracker(this.codeManager)
var self = this var self = this
this.register('indexChanged', this, function (index) { this.register('indexChanged', this, function (index) {
...@@ -72,7 +74,11 @@ Ethdebugger.prototype.switchProvider = function (type) { ...@@ -72,7 +74,11 @@ Ethdebugger.prototype.switchProvider = function (type) {
} }
Ethdebugger.prototype.debug = function (tx) { Ethdebugger.prototype.debug = function (tx) {
this.txBrowser.load(tx.hash) if (tx instanceof Object) {
this.txBrowser.load(tx.hash)
} else if (tx instanceof String) {
this.txBrowser.load(tx)
}
} }
Ethdebugger.prototype.render = function () { Ethdebugger.prototype.render = function () {
......
...@@ -9,19 +9,16 @@ Web3Providers.prototype.addProvider = function (type, obj) { ...@@ -9,19 +9,16 @@ Web3Providers.prototype.addProvider = function (type, obj) {
if (type === 'INTERNAL') { if (type === 'INTERNAL') {
var web3 = init.loadWeb3() var web3 = init.loadWeb3()
this.addWeb3(type, web3) this.addWeb3(type, web3)
} else if (type === 'EXTERNAL') { } else if (type === 'vm') {
init.extendWeb3(obj)
this.addWeb3(type, obj)
} else if (type === 'VM') {
this.addVM(obj) this.addVM(obj)
} else { } else {
init.extendWeb3(obj)
this.addWeb3(type, obj) this.addWeb3(type, obj)
} }
} }
Web3Providers.prototype.get = function (type, cb) { Web3Providers.prototype.get = function (type, cb) {
if (this.modes[type]) { if (this.modes[type]) {
this.currentMode = type
cb(null, this.modes[type]) cb(null, this.modes[type])
} else { } else {
cb('error: this provider has not been setup (' + type + ')', null) cb('error: this provider has not been setup (' + type + ')', null)
......
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