Skip to content

Commit

Permalink
Do not modify sb for variadic calls as it breaks local variables reso…
Browse files Browse the repository at this point in the history
…lution. Instead place a marker on stack and use it to count the number of args. Fixes dop251#311.

Signed-off-by: Gabri <[email protected]>
  • Loading branch information
dop251 authored and Gabri3l committed Jan 24, 2022
1 parent b4db7b1 commit c6e1779
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 7 deletions.
11 changes: 11 additions & 0 deletions compiler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4020,6 +4020,17 @@ func TestVariadicNew(t *testing.T) {
testScript1(SCRIPT, asciiString("1,a,2"), t)
}

func TestVariadicUseStackVars(t *testing.T) {
const SCRIPT = `
function A(message) { return message; }
function B(...args){
return A(...args);
}
B("C");
`
testScript1(SCRIPT, asciiString("C"), t)
}

/*
func TestBabel(t *testing.T) {
src, err := ioutil.ReadFile("babel7.js")
Expand Down
25 changes: 18 additions & 7 deletions vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -2494,15 +2494,15 @@ type _callEvalVariadic struct{}
var callEvalVariadic _callEvalVariadic

func (_callEvalVariadic) exec(vm *vm) {
vm.callEval(vm.sp-vm.sb-2, false)
vm.callEval(vm.countVariadicArgs()-2, false)
}

type _callEvalVariadicStrict struct{}

var callEvalVariadicStrict _callEvalVariadicStrict

func (_callEvalVariadicStrict) exec(vm *vm) {
vm.callEval(vm.sp-vm.sb-2, true)
vm.callEval(vm.countVariadicArgs()-2, true)
}

type _boxThis struct{}
Expand All @@ -2519,22 +2519,34 @@ func (_boxThis) exec(vm *vm) {
vm.pc++
}

var variadicMarker Value = newSymbol(asciiString("[variadic marker]"))

type _startVariadic struct{}

var startVariadic _startVariadic

func (_startVariadic) exec(vm *vm) {
vm.push(valueInt(vm.sb))
vm.sb = vm.sp
vm.push(variadicMarker)
vm.pc++
}

type _callVariadic struct{}

var callVariadic _callVariadic

func (vm *vm) countVariadicArgs() int {
count := 0
for i := vm.sp - 1; i >= 0; i-- {
if vm.stack[i] == variadicMarker {
return count
}
count++
}
panic("Variadic marker was not found. Compiler bug.")
}

func (_callVariadic) exec(vm *vm) {
call(vm.sp - vm.sb - 2).exec(vm)
call(vm.countVariadicArgs() - 2).exec(vm)
}

type _endVariadic struct{}
Expand All @@ -2543,7 +2555,6 @@ var endVariadic _endVariadic

func (_endVariadic) exec(vm *vm) {
vm.sp--
vm.sb = int(vm.stack[vm.sp-1].(valueInt))
vm.stack[vm.sp-1] = vm.stack[vm.sp]
vm.pc++
}
Expand Down Expand Up @@ -3480,7 +3491,7 @@ type _newVariadic struct{}
var newVariadic _newVariadic

func (_newVariadic) exec(vm *vm) {
_new(vm.sp - vm.sb - 1).exec(vm)
_new(vm.countVariadicArgs() - 1).exec(vm)
}

type _new uint32
Expand Down

0 comments on commit c6e1779

Please sign in to comment.