about summary refs log tree commit diff
path: root/pkg/lang/vm
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2022-08-22 23:41:49 +0000
committerMel <einebeere@gmail.com>2022-08-22 23:41:49 +0000
commite22df631c4428f8dea4d5784a8a7840d2f84c6be (patch)
tree084c233741374cdabde8d70b49988b3dca686719 /pkg/lang/vm
parent24183cd5363b96d83292df17d44fa79d8b47a89f (diff)
downloadjinx-e22df631c4428f8dea4d5784a8a7840d2f84c6be.tar.zst
jinx-e22df631c4428f8dea4d5784a8a7840d2f84c6be.zip
Generate runtime debug info with source locations
Diffstat (limited to 'pkg/lang/vm')
-rw-r--r--pkg/lang/vm/code/builder.go6
-rw-r--r--pkg/lang/vm/code/debug.go29
-rw-r--r--pkg/lang/vm/vm.go8
3 files changed, 33 insertions, 10 deletions
diff --git a/pkg/lang/vm/code/builder.go b/pkg/lang/vm/code/builder.go
index f413ba1..618608a 100644
--- a/pkg/lang/vm/code/builder.go
+++ b/pkg/lang/vm/code/builder.go
@@ -2,6 +2,7 @@ package code
 
 import (
 	"encoding/binary"
+	"jinx/pkg/libs/source"
 	"math"
 )
 
@@ -76,6 +77,7 @@ func (b *Builder) AppendBuilder(other Builder) error {
 	}
 
 	b.AppendRaw(other.code)
+	b.debugInfo.AppendOther(other.debugInfo)
 
 	return nil
 }
@@ -114,6 +116,10 @@ func (b *Builder) EndLine() {
 	b.debugInfo.AppendLine(b.Len()-1, b.currentLine)
 }
 
+func (b *Builder) AddDebugInfo(fromPc, toPc int, loc source.Loc) {
+	b.debugInfo.FillInfo(fromPc, toPc, loc)
+}
+
 func (b *Builder) SetInt(at int, x int64) {
 	binary.LittleEndian.PutUint64(b.code[at:], uint64(x))
 }
diff --git a/pkg/lang/vm/code/debug.go b/pkg/lang/vm/code/debug.go
index ebf0ea1..efb788c 100644
--- a/pkg/lang/vm/code/debug.go
+++ b/pkg/lang/vm/code/debug.go
@@ -1,16 +1,19 @@
 package code
 
-import "jinx/pkg/libs/rangemap"
+import (
+	"jinx/pkg/libs/rangemap"
+	"jinx/pkg/libs/source"
+)
 
 type DebugInfo struct {
 	file     string
-	pcToLine rangemap.RangeMap[int]
+	pcToLine rangemap.RangeMap[source.Loc]
 }
 
 func NewDebugInfo(file string) DebugInfo {
 	return DebugInfo{
 		file:     file,
-		pcToLine: rangemap.New[int](),
+		pcToLine: rangemap.New[source.Loc](),
 	}
 }
 
@@ -18,14 +21,22 @@ func (di *DebugInfo) File() string {
 	return di.file
 }
 
-func (di *DebugInfo) PCToLine(pc int) int {
-	line := di.pcToLine.Get(pc)
-	if line == nil {
-		return -1
+func (di *DebugInfo) PCToLoc(pc int) (source.Loc, bool) {
+	loc := di.pcToLine.Get(pc)
+	if loc == nil {
+		return source.Loc{}, false
 	}
-	return *line
+	return *loc, true
 }
 
 func (di *DebugInfo) AppendLine(uptoPc, line int) {
-	di.pcToLine.AppendToLast(uptoPc, line)
+	di.pcToLine.AppendToLast(uptoPc, source.Loc{Row: line, Col: 0})
+}
+
+func (di *DebugInfo) FillInfo(from, to int, loc source.Loc) {
+	di.pcToLine.Fill(from, to, loc)
+}
+
+func (di *DebugInfo) AppendOther(other DebugInfo) {
+	di.pcToLine.AppendRanges(other.pcToLine)
 }
diff --git a/pkg/lang/vm/vm.go b/pkg/lang/vm/vm.go
index 4d4d5ca..b18e7cb 100644
--- a/pkg/lang/vm/vm.go
+++ b/pkg/lang/vm/vm.go
@@ -121,10 +121,16 @@ func (vm *VM) executeModule(moduleID int) error {
 		vm.advancePC(advance)
 
 		if decision, err := vm.step(code, op); err != nil {
+			loc, ok := code.Debug().PCToLoc(vm.pc())
+			line := loc.Row
+			if !ok {
+				line = -1
+			}
+
 			return Error{
 				Pos:    vm.pos,
 				Module: module.Name(),
-				Line:   code.Debug().PCToLine(vm.pc()),
+				Line:   line,
 				Err:    err,
 			}
 		} else if decision == stepDecisionHalt {