Updated debugger

* Compile on the go. Continues compilation in order to update the ASM
  view
* Short cuts commands
This commit is contained in:
obscuren 2014-07-04 13:04:25 +02:00
parent 24ff81d14e
commit ca395306e3
2 changed files with 91 additions and 18 deletions

View File

@ -7,6 +7,7 @@ import QtQuick.Controls.Styles 1.1
import Ethereum 1.0 import Ethereum 1.0
ApplicationWindow { ApplicationWindow {
id: win
visible: false visible: false
title: "IceCREAM" title: "IceCREAM"
minimumWidth: 1280 minimumWidth: 1280
@ -17,6 +18,10 @@ ApplicationWindow {
property alias codeText: codeEditor.text property alias codeText: codeEditor.text
property alias dataText: rawDataField.text property alias dataText: rawDataField.text
onClosing: {
compileTimer.stop()
}
MenuBar { MenuBar {
Menu { Menu {
title: "Debugger" title: "Debugger"
@ -34,12 +39,44 @@ ApplicationWindow {
MenuItem { MenuItem {
text: "Continue" text: "Continue"
shortcut: "Ctrl+c" shortcut: "Ctrl+g"
onTriggered: dbg.continue() onTriggered: dbg.continue()
} }
MenuItem {
text: "Command"
shortcut: "Ctrl+l"
onTriggered: {
dbgCommand.focus = true
}
}
MenuItem {
text: "Focus code"
shortcut: "Ctrl+1"
onTriggered: {
codeEditor.focus = true
}
}
MenuItem {
text: "Focus data"
shortcut: "Ctrl+2"
onTriggered: {
rawDataField.focus = true
}
}
/*
MenuItem {
text: "Close window"
shortcut: "Ctrl+w"
onTriggered: {
win.close()
}
}
*/
} }
} }
SplitView { SplitView {
anchors.fill: parent anchors.fill: parent
property var asmModel: ListModel { property var asmModel: ListModel {
@ -73,6 +110,15 @@ ApplicationWindow {
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.left: parent.left anchors.left: parent.left
anchors.right: settings.left anchors.right: settings.left
focus: true
Timer {
id: compileTimer
interval: 500 ; running: true ; repeat: true
onTriggered: {
dbg.compile(codeEditor.text)
}
}
} }
Column { Column {
@ -185,7 +231,7 @@ ApplicationWindow {
} }
height: parent.height height: parent.height
width: parent.width width: parent.width
TableViewColumn{ id: message ; role: "message" ; title: "log" ; width: logTableView.width } TableViewColumn{ id: message ; role: "message" ; title: "log" ; width: logTableView.width -1 }
model: logModel model: logModel
} }
} }
@ -207,7 +253,7 @@ ApplicationWindow {
y: 1 y: 1
x: asmTableView.width x: asmTableView.width
width: 500 width: 500
placeholderText: "Debugger command (help for help)" placeholderText: "Debugger (type 'help')"
Keys.onReturnPressed: { Keys.onReturnPressed: {
exec() exec()
} }
@ -225,6 +271,7 @@ ApplicationWindow {
} }
toolBar: ToolBar { toolBar: ToolBar {
height: 30
RowLayout { RowLayout {
spacing: 5 spacing: 5
@ -254,6 +301,23 @@ ApplicationWindow {
text: "Continue" text: "Continue"
} }
} }
ComboBox {
id: snippets
anchors.right: parent.right
model: ListModel {
ListElement { text: "Snippets" ; value: "" }
ListElement { text: "Call Contract" ; value: "var[2] in;\nvar ret;\n\nin[0] = \"arg1\"\nin[1] = 0xdeadbeef\n\nvar success = call(0x0c542ddea93dae0c2fcb2cf175f03ad80d6be9a0, 0, 7000, in, ret)\n\nreturn ret" }
}
onCurrentIndexChanged: {
if(currentIndex != 0) {
var code = snippets.model.get(currentIndex).value;
codeEditor.insert(codeEditor.cursorPosition, code)
}
}
}
} }
function debugCurrent() { function debugCurrent() {

View File

@ -52,13 +52,27 @@ func (self *DebuggerWindow) SetCode(code string) {
func (self *DebuggerWindow) SetData(data string) { func (self *DebuggerWindow) SetData(data string) {
self.win.Set("dataText", data) self.win.Set("dataText", data)
} }
func (self *DebuggerWindow) SetAsm(data string) { func (self *DebuggerWindow) SetAsm(data []byte) {
dis := ethchain.Disassemble(ethutil.Hex2Bytes(data)) self.win.Root().Call("clearAsm")
dis := ethchain.Disassemble(data)
for _, str := range dis { for _, str := range dis {
self.win.Root().Call("setAsm", str) self.win.Root().Call("setAsm", str)
} }
} }
func (self *DebuggerWindow) Compile(code string) {
var err error
script := ethutil.StringToByteFunc(code, func(s string) (ret []byte) {
ret, err = ethutil.Compile(s)
return
})
if err == nil {
self.SetAsm(script)
}
}
func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, scriptStr, dataStr string) { func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, scriptStr, dataStr string) {
if !self.Db.done { if !self.Db.done {
self.Db.Q <- true self.Db.Q <- true
@ -91,27 +105,21 @@ func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, scriptStr, data
return return
} }
dis := ethchain.Disassemble(script) self.SetAsm(script)
self.win.Root().Call("clearAsm")
for _, str := range dis {
self.win.Root().Call("setAsm", str)
}
var ( var (
gas = ethutil.Big(gasStr) gas = ethutil.Big(gasStr)
gasPrice = ethutil.Big(gasPriceStr) gasPrice = ethutil.Big(gasPriceStr)
value = ethutil.Big(valueStr) value = ethutil.Big(valueStr)
// Contract addr as test address // Contract addr as test address
keyPair = self.lib.eth.KeyManager().KeyPair() keyPair = self.lib.eth.KeyManager().KeyPair()
callerTx = ethchain.NewContractCreationTx(ethutil.Big(valueStr), gas, gasPrice, script)
) )
callerTx.Sign(keyPair.PrivateKey)
state := self.lib.eth.BlockChain().CurrentBlock.State() state := self.lib.eth.StateManager().TransState()
account := self.lib.eth.StateManager().TransState().GetAccount(keyPair.Address()) account := self.lib.eth.StateManager().TransState().GetAccount(keyPair.Address())
contract := ethchain.MakeContract(callerTx, state) contract := ethchain.NewStateObject([]byte{0})
contract.Amount = value contract.Amount = value
callerClosure := ethchain.NewClosure(account, contract, script, state, gas, gasPrice) callerClosure := ethchain.NewClosure(account, contract, script, state, gas, gasPrice)
block := self.lib.eth.BlockChain().CurrentBlock block := self.lib.eth.BlockChain().CurrentBlock
@ -179,8 +187,9 @@ func (self *DebuggerWindow) ExecCommand(command string) {
cmd := strings.Split(command, " ") cmd := strings.Split(command, " ")
switch cmd[0] { switch cmd[0] {
case "help": case "help":
self.Logln("Debgger commands:") self.Logln("Debugger commands:")
self.Logln("break, bp Set breakpoint") self.Logln("break, bp Set breakpoint on instruction")
self.Logln("clear [break, bp] Clears previous set sub-command(s)")
case "break", "bp": case "break", "bp":
if len(cmd) > 1 { if len(cmd) > 1 {
lineNo, err := strconv.Atoi(cmd[1]) lineNo, err := strconv.Atoi(cmd[1])