Browse Source

Removed erroneous stacktrace frame when exception is thrown from a catch clause.

Dmitry Panov 4 years ago
parent
commit
96fa0aa6d9
4 changed files with 78 additions and 6 deletions
  1. 1 1
      go.mod
  2. 2 4
      go.sum
  3. 71 0
      runtime_test.go
  4. 4 1
      vm.go

+ 1 - 1
go.mod

@@ -7,7 +7,7 @@ require (
 	github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7
 	github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7
 	github.com/go-sourcemap/sourcemap v2.1.3+incompatible
 	github.com/go-sourcemap/sourcemap v2.1.3+incompatible
 	github.com/kr/text v0.2.0 // indirect
 	github.com/kr/text v0.2.0 // indirect
-	golang.org/x/text v0.3.5
+	golang.org/x/text v0.3.6
 	gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
 	gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
 	gopkg.in/yaml.v2 v2.4.0
 	gopkg.in/yaml.v2 v2.4.0
 )
 )

+ 2 - 4
go.sum

@@ -1,6 +1,4 @@
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
-github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
-github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
 github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 h1:Izz0+t1Z5nI16/II7vuEo/nHjodOg0p7+OiDpjX5t1E=
 github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 h1:Izz0+t1Z5nI16/II7vuEo/nHjodOg0p7+OiDpjX5t1E=
 github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
 github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
 github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7 h1:tYwu/z8Y0NkkzGEh3z21mSWggMg4LwLRFucLS7TjARg=
 github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7 h1:tYwu/z8Y0NkkzGEh3z21mSWggMg4LwLRFucLS7TjARg=
@@ -14,8 +12,8 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
-golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
-golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

+ 71 - 0
runtime_test.go

@@ -7,6 +7,7 @@ import (
 	"reflect"
 	"reflect"
 	"runtime"
 	"runtime"
 	"strconv"
 	"strconv"
+	"strings"
 	"testing"
 	"testing"
 	"time"
 	"time"
 
 
@@ -1985,6 +1986,76 @@ func TestStackOverflowError(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func TestStacktraceLocationThrowFromCatch(t *testing.T) {
+	vm := New()
+	_, err := vm.RunString(`
+	function main(arg) {
+		try {
+			if (arg === 1) {
+				return f1();
+			}
+			if (arg === 2) {
+				return f2();
+			}
+			if (arg === 3) {
+				return f3();
+			}
+		} catch (e) {
+			throw e;
+		}
+	}
+	function f1() {}
+	function f2() {
+		throw new Error();
+	}
+	function f3() {}
+	main(2);
+	`)
+	if err == nil {
+		t.Fatal("Expected error")
+	}
+	stack := err.(*Exception).stack
+	if len(stack) != 2 {
+		t.Fatalf("Unexpected stack len: %v", stack)
+	}
+	if frame := stack[0]; frame.funcName != "main" || frame.pc != 30 {
+		t.Fatalf("Unexpected stack frame 0: %#v", frame)
+	}
+	if frame := stack[1]; frame.funcName != "" || frame.pc != 7 {
+		t.Fatalf("Unexpected stack frame 1: %#v", frame)
+	}
+}
+
+func TestStacktraceLocationThrowFromGo(t *testing.T) {
+	vm := New()
+	f := func() {
+		panic(vm.ToValue("Test"))
+	}
+	vm.Set("f", f)
+	_, err := vm.RunString(`
+	function main() {
+		return f();
+	}
+	main();
+	`)
+	if err == nil {
+		t.Fatal("Expected error")
+	}
+	stack := err.(*Exception).stack
+	if len(stack) != 3 {
+		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 {
+		t.Fatalf("Unexpected stack frame 1: %#v", frame)
+	}
+	if frame := stack[2]; frame.funcName != "" || frame.pc != 3 {
+		t.Fatalf("Unexpected stack frame 2: %#v", frame)
+	}
+}
+
 /*
 /*
 func TestArrayConcatSparse(t *testing.T) {
 func TestArrayConcatSparse(t *testing.T) {
 function foo(a,b,c)
 function foo(a,b,c)

+ 4 - 1
vm.go

@@ -428,7 +428,9 @@ func (vm *vm) ClearInterrupt() {
 
 
 func (vm *vm) captureStack(stack []StackFrame, ctxOffset int) []StackFrame {
 func (vm *vm) captureStack(stack []StackFrame, ctxOffset int) []StackFrame {
 	// Unroll the context stack
 	// Unroll the context stack
-	stack = append(stack, StackFrame{prg: vm.prg, pc: vm.pc, funcName: vm.funcName})
+	if vm.pc != -1 {
+		stack = append(stack, StackFrame{prg: vm.prg, pc: vm.pc, funcName: vm.funcName})
+	}
 	for i := len(vm.callStack) - 1; i > ctxOffset-1; i-- {
 	for i := len(vm.callStack) - 1; i > ctxOffset-1; i-- {
 		if vm.callStack[i].pc != -1 {
 		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})
 			stack = append(stack, StackFrame{prg: vm.callStack[i].prg, pc: vm.callStack[i].pc - 1, funcName: vm.callStack[i].funcName})
@@ -3093,6 +3095,7 @@ func (t try) exec(vm *vm) {
 	vm.halt = false
 	vm.halt = false
 
 
 	if ex != nil {
 	if ex != nil {
+		vm.pc = -1 // to prevent the current position from being captured in the stacktrace
 		panic(ex)
 		panic(ex)
 	}
 	}
 }
 }