diff --git a/go.mod b/go.mod index e5d9eb8b848..4f4b1f0ebd7 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/PuerkitoBio/goquery v1.6.1 github.com/Soontao/goHttpDigestClient v0.0.0-20170320082612-6d28bb1415c5 github.com/andybalholm/brotli v1.0.3 - github.com/dop251/goja v0.0.0-20211211112501-fb27c91c26ed + github.com/dop251/goja v0.0.0-20220104154337-b93494d0c5d9 github.com/fatih/color v1.12.0 github.com/golang/protobuf v1.4.3 github.com/gorilla/websocket v1.4.2 diff --git a/go.sum b/go.sum index e4c1c848ef1..bfb1bff28d1 100644 --- a/go.sum +++ b/go.sum @@ -57,8 +57,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= 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/dop251/goja v0.0.0-20211211112501-fb27c91c26ed h1:93Xt1lY7ReTv+7uDM6UHe818CEvLLn5HE1gpB7d3MS8= -github.com/dop251/goja v0.0.0-20211211112501-fb27c91c26ed/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja v0.0.0-20220104154337-b93494d0c5d9 h1:QYh60R7QllMj/JKMtE2hCrwRqDbQq8vsUD63SDdVpHw= +github.com/dop251/goja v0.0.0-20220104154337-b93494d0c5d9/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= diff --git a/vendor/github.com/dop251/goja/ast/node.go b/vendor/github.com/dop251/goja/ast/node.go index e9a5389a8a4..c0a1691983b 100644 --- a/vendor/github.com/dop251/goja/ast/node.go +++ b/vendor/github.com/dop251/goja/ast/node.go @@ -118,6 +118,14 @@ type ( Identifier Identifier } + OptionalChain struct { + Expression + } + + Optional struct { + Expression + } + FunctionLiteral struct { Function file.Idx Name *Identifier diff --git a/vendor/github.com/dop251/goja/compiler.go b/vendor/github.com/dop251/goja/compiler.go index 12359ed8438..863310df529 100644 --- a/vendor/github.com/dop251/goja/compiler.go +++ b/vendor/github.com/dop251/goja/compiler.go @@ -21,6 +21,7 @@ const ( blockWith blockScope blockIterScope + blockOptChain ) const ( @@ -384,6 +385,13 @@ func (p *Program) sourceOffset(pc int) int { return 0 } +func (p *Program) addSrcMap(srcPos int) { + if len(p.srcMap) > 0 && p.srcMap[len(p.srcMap)-1].srcPos == srcPos { + return + } + p.srcMap = append(p.srcMap, srcMapItem{pc: len(p.code), srcPos: srcPos}) +} + func (s *scope) lookupName(name unistring.String) (binding *binding, noDynamics bool) { noDynamics = true toStash := false diff --git a/vendor/github.com/dop251/goja/compiler_expr.go b/vendor/github.com/dop251/goja/compiler_expr.go index 5bfeb8dba8c..85344d44195 100644 --- a/vendor/github.com/dop251/goja/compiler_expr.go +++ b/vendor/github.com/dop251/goja/compiler_expr.go @@ -188,6 +188,16 @@ type compiledSpreadCallArgument struct { expr compiledExpr } +type compiledOptionalChain struct { + baseCompiledExpr + expr compiledExpr +} + +type compiledOptional struct { + baseCompiledExpr + expr compiledExpr +} + func (e *defaultDeleteExpr) emitGetter(putOnStack bool) { e.expr.emitGetter(false) if putOnStack { @@ -264,6 +274,18 @@ func (c *compiler) compileExpression(v ast.Expression) compiledExpr { return c.compileObjectAssignmentPattern(v) case *ast.ArrayPattern: return c.compileArrayAssignmentPattern(v) + case *ast.OptionalChain: + r := &compiledOptionalChain{ + expr: c.compileExpression(v.Expression), + } + r.init(c, v.Idx0()) + return r + case *ast.Optional: + r := &compiledOptional{ + expr: c.compileExpression(v.Expression), + } + r.init(c, v.Idx0()) + return r default: panic(fmt.Errorf("Unknown expression type: %T", v)) } @@ -300,7 +322,7 @@ func (e *baseCompiledExpr) emitUnary(func(), func(), bool, bool) { func (e *baseCompiledExpr) addSrcMap() { if e.offset >= 0 { - e.c.p.srcMap = append(e.c.p.srcMap, srcMapItem{pc: len(e.c.p.code), srcPos: e.offset}) + e.c.p.addSrcMap(e.offset) } } @@ -1948,6 +1970,12 @@ func (c *compiler) emitCallee(callee compiledExpr) (calleeName unistring.String) case *compiledIdentifierExpr: calleeName = callee.name callee.emitGetterAndCallee() + case *compiledOptionalChain: + c.startOptChain() + c.emitCallee(callee.expr) + c.endOptChain() + case *compiledOptional: + c.emitCallee(callee.expr) default: c.emit(loadUndef) callee.emitGetter(true) @@ -2362,3 +2390,35 @@ func (e *compiledSpreadCallArgument) emitGetter(putOnStack bool) { e.c.emit(pushSpread) } } + +func (c *compiler) startOptChain() { + c.block = &block{ + typ: blockOptChain, + outer: c.block, + } +} + +func (c *compiler) endOptChain() { + lbl := len(c.p.code) + for _, item := range c.block.breaks { + c.p.code[item] = jopt(lbl - item) + } + c.block = c.block.outer +} + +func (e *compiledOptionalChain) emitGetter(putOnStack bool) { + e.c.startOptChain() + e.expr.emitGetter(true) + e.c.endOptChain() + if !putOnStack { + e.c.emit(pop) + } +} + +func (e *compiledOptional) emitGetter(putOnStack bool) { + e.expr.emitGetter(putOnStack) + if putOnStack { + e.c.block.breaks = append(e.c.block.breaks, len(e.c.p.code)) + e.c.emit(nil) + } +} diff --git a/vendor/github.com/dop251/goja/compiler_stmt.go b/vendor/github.com/dop251/goja/compiler_stmt.go index 05d3b875ce7..e658997d7d4 100644 --- a/vendor/github.com/dop251/goja/compiler_stmt.go +++ b/vendor/github.com/dop251/goja/compiler_stmt.go @@ -202,9 +202,13 @@ func (c *compiler) compileTryStatement(v *ast.TryStatement, needResult bool) { c.leaveBlock() } +func (c *compiler) addSrcMap(node ast.Node) { + c.p.addSrcMap(int(node.Idx0()) - 1) +} + func (c *compiler) compileThrowStatement(v *ast.ThrowStatement) { - //c.p.srcMap = append(c.p.srcMap, srcMapItem{pc: len(c.p.code), srcPos: int(v.Throw) - 1}) c.compileExpression(v.Argument).emitGetter(true) + c.addSrcMap(v) c.emit(throw) } @@ -752,6 +756,7 @@ func (c *compiler) emitVarAssign(name unistring.String, offset int, init compile if init != nil { c.emitVarRef(name, offset) c.emitNamed(init, name) + c.p.addSrcMap(offset) c.emit(initValueP) } } @@ -775,6 +780,7 @@ func (c *compiler) emitLexicalAssign(name unistring.String, offset int, init com } if init != nil { c.emitNamed(init, name) + c.p.addSrcMap(offset) } else { if isConst { c.throwSyntaxError(offset, "Missing initializer in const declaration") diff --git a/vendor/github.com/dop251/goja/parser/expression.go b/vendor/github.com/dop251/goja/parser/expression.go index 7491e25c3be..568f89113a8 100644 --- a/vendor/github.com/dop251/goja/parser/expression.go +++ b/vendor/github.com/dop251/goja/parser/expression.go @@ -544,7 +544,8 @@ func (self *_parser) parseCallExpression(left ast.Expression) ast.Expression { } func (self *_parser) parseDotMember(left ast.Expression) ast.Expression { - period := self.expect(token.PERIOD) + period := self.idx + self.next() literal := self.parsedLiteral idx := self.idx @@ -653,11 +654,14 @@ func (self *_parser) parseLeftHandSideExpressionAllowCall() ast.Expression { }() var left ast.Expression + start := self.idx if self.token == token.NEW { left = self.parseNewExpression() } else { left = self.parsePrimaryExpression() } + + optionalChain := false L: for { switch self.token { @@ -668,12 +672,30 @@ L: case token.LEFT_PARENTHESIS: left = self.parseCallExpression(left) case token.BACKTICK: + if optionalChain { + self.error(self.idx, "Invalid template literal on optional chain") + self.nextStatement() + return &ast.BadExpression{From: start, To: self.idx} + } left = self.parseTaggedTemplateLiteral(left) + case token.QUESTION_DOT: + optionalChain = true + left = &ast.Optional{Expression: left} + + switch self.peek() { + case token.LEFT_BRACKET, token.LEFT_PARENTHESIS, token.BACKTICK: + self.next() + default: + left = self.parseDotMember(left) + } default: break L } } + if optionalChain { + left = &ast.OptionalChain{Expression: left} + } return left } diff --git a/vendor/github.com/dop251/goja/parser/lexer.go b/vendor/github.com/dop251/goja/parser/lexer.go index 37e1aacb2f2..b7cfa1b3ca8 100644 --- a/vendor/github.com/dop251/goja/parser/lexer.go +++ b/vendor/github.com/dop251/goja/parser/lexer.go @@ -405,7 +405,12 @@ func (self *_parser) scan() (tkn token.Token, literal string, parsedLiteral unis case '~': tkn = token.BITWISE_NOT case '?': - tkn = token.QUESTION_MARK + if self.chr == '.' && !isDecimalDigit(self._peek()) { + self.read() + tkn = token.QUESTION_DOT + } else { + tkn = token.QUESTION_MARK + } case '"', '\'': insertSemicolon = true tkn = token.STRING diff --git a/vendor/github.com/dop251/goja/parser/statement.go b/vendor/github.com/dop251/goja/parser/statement.go index 580d0440645..8c5320c5939 100644 --- a/vendor/github.com/dop251/goja/parser/statement.go +++ b/vendor/github.com/dop251/goja/parser/statement.go @@ -269,6 +269,7 @@ func (self *_parser) parseThrowStatement() ast.Statement { } node := &ast.ThrowStatement{ + Throw: idx, Argument: self.parseExpression(), } diff --git a/vendor/github.com/dop251/goja/runtime.go b/vendor/github.com/dop251/goja/runtime.go index 01edbb7c3b3..914497240b2 100644 --- a/vendor/github.com/dop251/goja/runtime.go +++ b/vendor/github.com/dop251/goja/runtime.go @@ -294,11 +294,22 @@ type uncatchableException struct { err error } +func (ue *uncatchableException) Unwrap() error { + return ue.err +} + type InterruptedError struct { Exception iface interface{} } +func (e *InterruptedError) Unwrap() error { + if err, ok := e.iface.(error); ok { + return err + } + return nil +} + type StackOverflowError struct { Exception } diff --git a/vendor/github.com/dop251/goja/token/token_const.go b/vendor/github.com/dop251/goja/token/token_const.go index f3b8a404ccd..61e2f12f04c 100644 --- a/vendor/github.com/dop251/goja/token/token_const.go +++ b/vendor/github.com/dop251/goja/token/token_const.go @@ -67,6 +67,7 @@ const ( SEMICOLON // ; COLON // : QUESTION_MARK // ? + QUESTION_DOT // ?. ARROW // => ELLIPSIS // ... BACKTICK // ` @@ -174,6 +175,7 @@ var token2string = [...]string{ SEMICOLON: ";", COLON: ":", QUESTION_MARK: "?", + QUESTION_DOT: "?.", ARROW: "=>", ELLIPSIS: "...", BACKTICK: "`", diff --git a/vendor/github.com/dop251/goja/vm.go b/vendor/github.com/dop251/goja/vm.go index cc987b1dbe6..46c755acef5 100644 --- a/vendor/github.com/dop251/goja/vm.go +++ b/vendor/github.com/dop251/goja/vm.go @@ -3340,6 +3340,20 @@ func (j jdefP) exec(vm *vm) { vm.sp-- } +type jopt int32 + +func (j jopt) exec(vm *vm) { + switch vm.stack[vm.sp-1] { + case _null: + vm.stack[vm.sp-1] = _undefined + fallthrough + case _undefined: + vm.pc += int(j) + default: + vm.pc++ + } +} + type _not struct{} var not _not diff --git a/vendor/modules.txt b/vendor/modules.txt index 9b44def9b4d..de3b85b1a18 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -23,7 +23,7 @@ github.com/davecgh/go-spew/spew ## explicit github.com/dlclark/regexp2 github.com/dlclark/regexp2/syntax -# github.com/dop251/goja v0.0.0-20211211112501-fb27c91c26ed +# github.com/dop251/goja v0.0.0-20220104154337-b93494d0c5d9 ## explicit; go 1.14 github.com/dop251/goja github.com/dop251/goja/ast