Skip to content

Commit

Permalink
Merge branch 'master' into es6
Browse files Browse the repository at this point in the history
# Conflicts:
#	compiler_test.go
  • Loading branch information
dop251 committed Apr 14, 2020
2 parents 60b86f2 + 77e84ff commit 00c4500
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 11 deletions.
3 changes: 2 additions & 1 deletion compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

const (
blockLoop = iota
blockLoopEnum
blockTry
blockBranch
blockSwitch
Expand Down Expand Up @@ -87,7 +88,7 @@ func (c *compiler) leaveBlock() {
for _, item := range c.block.breaks {
c.p.code[item] = jump(lbl - item)
}
if c.block.typ == blockLoop {
if t := c.block.typ; t == blockLoop || t == blockLoopEnum {
for _, item := range c.block.conts {
c.p.code[item] = jump(c.block.cont - item)
}
Expand Down
27 changes: 17 additions & 10 deletions compiler_stmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ func (c *compiler) compileForInStatement(v *ast.ForInStatement, needResult bool)

func (c *compiler) compileLabeledForInStatement(v *ast.ForInStatement, needResult bool, label unistring.String) {
c.block = &block{
typ: blockLoop,
typ: blockLoopEnum,
outer: c.block,
label: label,
needResult: needResult,
Expand Down Expand Up @@ -463,15 +463,15 @@ func (c *compiler) findBranchBlock(st *ast.BranchStatement) *block {
func (c *compiler) findContinueBlock(label *ast.Identifier) (block *block) {
if label != nil {
for b := c.block; b != nil; b = b.outer {
if b.typ == blockLoop && b.label == label.Name {
if (b.typ == blockLoop || b.typ == blockLoopEnum) && b.label == label.Name {
block = b
break
}
}
} else {
// find the nearest loop
for b := c.block; b != nil; b = b.outer {
if b.typ == blockLoop {
if b.typ == blockLoop || b.typ == blockLoopEnum {
block = b
break
}
Expand All @@ -494,7 +494,7 @@ func (c *compiler) findBreakBlock(label *ast.Identifier) (block *block) {
L:
for b := c.block; b != nil; b = b.outer {
switch b.typ {
case blockLoop, blockSwitch:
case blockLoop, blockLoopEnum, blockSwitch:
block = b
break L
}
Expand Down Expand Up @@ -532,7 +532,7 @@ func (c *compiler) compileBreak(label *ast.Identifier, idx file.Idx) {
c.emit(halt)
case blockWith:
c.emit(leaveWith)
case blockLoop, blockSwitch:
case blockLoop, blockLoopEnum, blockSwitch:
block = b
break L
}
Expand All @@ -556,7 +556,7 @@ func (c *compiler) compileContinue(label *ast.Identifier, idx file.Idx) {
for b := c.block; b != nil; b = b.outer {
if b.typ == blockTry {
c.emit(halt)
} else if b.typ == blockLoop && b.label == label.Name {
} else if (b.typ == blockLoop || b.typ == blockLoopEnum) && b.label == label.Name {
block = b
break
}
Expand All @@ -570,7 +570,7 @@ func (c *compiler) compileContinue(label *ast.Identifier, idx file.Idx) {
for b := c.block; b != nil; b = b.outer {
if b.typ == blockTry {
c.emit(halt)
} else if b.typ == blockLoop {
} else if b.typ == blockLoop || b.typ == blockLoopEnum {
block = b
break
}
Expand Down Expand Up @@ -637,10 +637,14 @@ func (c *compiler) compileIfStatement(v *ast.IfStatement, needResult bool) {
c.p.code[jmp1] = jump(len(c.p.code) - jmp1)
c.markBlockStart()
} else {
c.p.code[jmp] = jne(len(c.p.code) - jmp)
c.markBlockStart()
if needResult {
c.emit(jump(2))
c.p.code[jmp] = jne(len(c.p.code) - jmp)
c.emit(loadUndef)
c.markBlockStart()
} else {
c.p.code[jmp] = jne(len(c.p.code) - jmp)
c.markBlockStart()
}
}
}
Expand All @@ -653,8 +657,11 @@ func (c *compiler) compileReturnStatement(v *ast.ReturnStatement) {
c.emit(loadUndef)
}
for b := c.block; b != nil; b = b.outer {
if b.typ == blockTry {
switch b.typ {
case blockTry:
c.emit(halt)
case blockLoopEnum:
c.emit(enumPop)
}
}
c.emit(ret)
Expand Down
25 changes: 25 additions & 0 deletions compiler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ func testScript1(script string, expectedResult Value, t *testing.T) {
if vm.sp != 0 {
t.Fatalf("sp: %d", vm.sp)
}

if l := len(vm.iterStack); l > 0 {
t.Fatalf("iter stack is not empty: %d", l)
}
}

func TestEmptyProgram(t *testing.T) {
Expand Down Expand Up @@ -2017,6 +2021,27 @@ func TestForOfReturn(t *testing.T) {
testScript1(TESTLIB+SCRIPT, _undefined, t)
}

func TestReturnFromForInLoop(t *testing.T) {
const SCRIPT = `
(function f() {
for (var i in {a: 1}) {
return true;
}
})();
`
testScript1(SCRIPT, valueTrue, t)
}

func TestIfStackLeaks(t *testing.T) {
const SCRIPT = `
var t = 0;
if (t === 0) {
t;
}
`
testScript1(SCRIPT, _positiveZero, t)
}

// FIXME
/*
func TestDummyCompile(t *testing.T) {
Expand Down
8 changes: 8 additions & 0 deletions tc39_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,14 @@ func (ctx *tc39TestCtx) runTC39Test(name, src string, meta *tc39Meta, t testing.
t.Fatalf("%s: Expected error: %v", name, err)
}
}

if vm.vm.sp != 0 {
t.Fatalf("sp: %d", vm.vm.sp)
}

if l := len(vm.vm.iterStack); l > 0 {
t.Fatalf("iter stack is not empty: %d", l)
}
}

func (ctx *tc39TestCtx) runTC39File(name string, t testing.TB) {
Expand Down

0 comments on commit 00c4500

Please sign in to comment.