Pārlūkot izejas kodu

Only use vm.funcName and context.funcName when prg is nil. Closes #339

Dmitry Panov 3 gadi atpakaļ
vecāks
revīzija
ba346f1c40
3 mainītis faili ar 29 papildinājumiem un 14 dzēšanām
  1. 1 0
      runtime.go
  2. 10 3
      runtime_test.go
  3. 18 11
      vm.go

+ 1 - 0
runtime.go

@@ -1287,6 +1287,7 @@ func (r *Runtime) RunProgram(p *Program) (result Value, err error) {
 	} else {
 		vm.stack = nil
 		vm.prg = nil
+		vm.funcName = ""
 		r.leave()
 	}
 	return

+ 10 - 3
runtime_test.go

@@ -2082,6 +2082,10 @@ func TestStacktraceLocationThrowFromGo(t *testing.T) {
 	vm.Set("f", f)
 	_, err := vm.RunString(`
 	function main() {
+		(function noop() {})();
+		return callee();
+	}
+	function callee() {
 		return f();
 	}
 	main();
@@ -2090,18 +2094,21 @@ func TestStacktraceLocationThrowFromGo(t *testing.T) {
 		t.Fatal("Expected error")
 	}
 	stack := err.(*Exception).stack
-	if len(stack) != 3 {
+	if len(stack) != 4 {
 		t.Fatalf("Unexpected stack len: %v", stack)
 	}
 	if frame := stack[0]; !strings.HasSuffix(frame.funcName.String(), "TestStacktraceLocationThrowFromGo.func1") {
 		t.Fatalf("Unexpected stack frame 0: %#v", frame)
 	}
-	if frame := stack[1]; frame.funcName != "main" || frame.pc != 1 {
+	if frame := stack[1]; frame.funcName != "callee" || frame.pc != 1 {
 		t.Fatalf("Unexpected stack frame 1: %#v", frame)
 	}
-	if frame := stack[2]; frame.funcName != "" || frame.pc != 3 {
+	if frame := stack[2]; frame.funcName != "main" || frame.pc != 6 {
 		t.Fatalf("Unexpected stack frame 2: %#v", frame)
 	}
+	if frame := stack[3]; frame.funcName != "" || frame.pc != 4 {
+		t.Fatalf("Unexpected stack frame 3: %#v", frame)
+	}
 }
 
 func TestStrToInt64(t *testing.T) {

+ 18 - 11
vm.go

@@ -33,7 +33,7 @@ type stash struct {
 
 type context struct {
 	prg       *Program
-	funcName  unistring.String
+	funcName  unistring.String // only valid when prg is nil
 	stash     *stash
 	newTarget Value
 	result    Value
@@ -141,7 +141,7 @@ func (r *unresolvedRef) refname() unistring.String {
 type vm struct {
 	r            *Runtime
 	prg          *Program
-	funcName     unistring.String
+	funcName     unistring.String // only valid when prg == nil
 	pc           int
 	stack        valueStack
 	sp, sb, args int
@@ -436,11 +436,23 @@ func (vm *vm) ClearInterrupt() {
 func (vm *vm) captureStack(stack []StackFrame, ctxOffset int) []StackFrame {
 	// Unroll the context stack
 	if vm.pc != -1 {
-		stack = append(stack, StackFrame{prg: vm.prg, pc: vm.pc, funcName: vm.funcName})
+		var funcName unistring.String
+		if vm.prg != nil {
+			funcName = vm.prg.funcName
+		} else {
+			funcName = vm.funcName
+		}
+		stack = append(stack, StackFrame{prg: vm.prg, pc: vm.pc, funcName: funcName})
 	}
 	for i := len(vm.callStack) - 1; i > ctxOffset-1; i-- {
 		if vm.callStack[i].pc != -1 {
-			stack = append(stack, StackFrame{prg: vm.callStack[i].prg, pc: vm.callStack[i].pc - 1, funcName: vm.callStack[i].funcName})
+			var funcName unistring.String
+			if prg := vm.callStack[i].prg; prg != nil {
+				funcName = prg.funcName
+			} else {
+				funcName = vm.callStack[i].funcName
+			}
+			stack = append(stack, StackFrame{prg: vm.callStack[i].prg, pc: vm.callStack[i].pc - 1, funcName: funcName})
 		}
 	}
 	return stack
@@ -539,13 +551,8 @@ func (vm *vm) peek() Value {
 }
 
 func (vm *vm) saveCtx(ctx *context) {
-	ctx.prg, ctx.stash, ctx.newTarget, ctx.result, ctx.pc, ctx.sb, ctx.args =
-		vm.prg, vm.stash, vm.newTarget, vm.result, vm.pc, vm.sb, vm.args
-	if vm.funcName != "" {
-		ctx.funcName = vm.funcName
-	} else if ctx.prg != nil && ctx.prg.funcName != "" {
-		ctx.funcName = ctx.prg.funcName
-	}
+	ctx.prg, ctx.stash, ctx.newTarget, ctx.result, ctx.pc, ctx.sb, ctx.args, ctx.funcName =
+		vm.prg, vm.stash, vm.newTarget, vm.result, vm.pc, vm.sb, vm.args, vm.funcName
 }
 
 func (vm *vm) pushCtx() {