Skip to content

Commit

Permalink
fix: 表达式(0||0)+1引起栈失衡崩溃的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
fy0 committed Sep 17, 2023
1 parent b66705d commit 46a8c8b
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 4 deletions.
2 changes: 1 addition & 1 deletion roll.peg
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ exprTernary <- exprLogicOr sp '?' sp { p.AddOp(TypeJne); p.OffsetPush() } exprLo
// 注: 越靠下的算符优先级越高

// 逻辑运算
exprLogicOr <- exprLogicAnd sp (logicOr {p.AddOp(TypeJeDup); p.OffsetPush()} exprLogicAnd { p.AddOp(TypeJeDup); p.OffsetPush()} { p.AddOp(TypePushLast); p.WriteCode(TypeJmp, int64(1)); p.OffsetPopAndSet(); p.OffsetPopAndSet(); } )*
exprLogicOr <- exprLogicAnd sp (logicOr {p.AddOp(TypeJeDup); p.OffsetPush()} exprLogicAnd { p.AddOp(TypeJeDup); p.OffsetPush()} { p.AddOp(TypePushLast); p.OffsetPopAndSet(); p.OffsetPopAndSet(); } )*
exprLogicAnd <- exprBitwiseOr sp (logicAnd exprBitwiseOr { p.AddOp(TypeLogicAnd) } )*

// 位运算
Expand Down
3 changes: 1 addition & 2 deletions roll.peg.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions rollvm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1370,3 +1370,17 @@ func TestNameDetailBug(t *testing.T) {
assert.Equal(t, "a = 1;1[a=1] ", vm.Detail)
}
}

func TestLogicOrBug(t *testing.T) {
// (0||0)+1 报错,原因是生成的代码里最后有一个jmp 1,跳过了1的push,导致栈里只有一个值
vm := NewVM()
err := vm.Run(`(0||0)+1`)
if assert.NoError(t, err) {
assert.True(t, valueEqual(vm.Ret, ni(1)))
}

err = vm.Run(`(0||1)+1`)
if assert.NoError(t, err) {
assert.True(t, valueEqual(vm.Ret, ni(2)))
}
}
10 changes: 9 additions & 1 deletion types.go
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ func (v *VMValue) toReprRaw(ri *recursionInfo) string {
case VMTypeString:
// TODO: 检测其中是否有"
return "'" + v.toStringRaw(ri) + "'"
case VMTypeInt, VMTypeFloat, VMTypeUndefined, VMTypeNull, VMTypeArray, VMTypeComputedValue, VMTypeDict, VMTypeFunction, VMTypeNativeFunction:
case VMTypeInt, VMTypeFloat, VMTypeUndefined, VMTypeNull, VMTypeArray, VMTypeComputedValue, VMTypeDict, VMTypeFunction, VMTypeNativeFunction, VMTypeNativeObject:
return v.toStringRaw(ri)
default:
return "<a value>"
Expand Down Expand Up @@ -703,10 +703,18 @@ func (v *VMValue) OpDivide(ctx *Context, v2 *VMValue) *VMValue {
}

func (v *VMValue) OpModulus(ctx *Context, v2 *VMValue) *VMValue {
setDivideZero := func() {
ctx.Error = errors.New("被除数被0")
}

switch v.TypeId {
case VMTypeInt:
switch v2.TypeId {
case VMTypeInt:
if v2.Value.(int64) == 0 {
setDivideZero()
return nil
}
val := v.Value.(int64) % v2.Value.(int64)
return VMValueNewInt(val)
}
Expand Down

0 comments on commit 46a8c8b

Please sign in to comment.