Bump github.com/yuin/gopher-lua

Bumps [github.com/yuin/gopher-lua](https://github.com/yuin/gopher-lua) from 0.0.0-20200603152657-dc2b0ca8b37e to 1.1.1.
- [Release notes](https://github.com/yuin/gopher-lua/releases)
- [Commits](https://github.com/yuin/gopher-lua/commits/v1.1.1)

---
updated-dependencies:
- dependency-name: github.com/yuin/gopher-lua
  dependency-type: indirect
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot] 2024-05-28 08:01:17 +00:00 committed by GitHub
parent 39d374f4fa
commit c288cb88ef
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
28 changed files with 2249 additions and 909 deletions

2
go.mod
View file

@ -41,6 +41,6 @@ require (
github.com/gomodule/redigo v2.0.0+incompatible // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/stretchr/testify v1.9.0 // indirect
github.com/yuin/gopher-lua v0.0.0-20200603152657-dc2b0ca8b37e // indirect
github.com/yuin/gopher-lua v1.1.1 // indirect
google.golang.org/protobuf v1.34.1 // indirect
)

8
go.sum
View file

@ -62,9 +62,6 @@ github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -134,8 +131,8 @@ github.com/tj/go-buffer v1.1.0/go.mod h1:iyiJpfFcR2B9sXu7KvjbT9fpM4mOelRSDTbntVj
github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0=
github.com/tj/go-kinesis v0.0.0-20171128231115-08b17f58cb1b/go.mod h1:/yhzCV0xPfx6jb1bBgRFjl5lytqVqZXEaeqWP8lTEao=
github.com/tj/go-spin v1.1.0/go.mod h1:Mg1mzmePZm4dva8Qz60H2lHwmJ2loum4VIrLgVnKwh4=
github.com/yuin/gopher-lua v0.0.0-20200603152657-dc2b0ca8b37e h1:oIpIX9VKxSCFrfjsKpluGbNPBGq9iNnT9crH781j9wY=
github.com/yuin/gopher-lua v0.0.0-20200603152657-dc2b0ca8b37e/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -143,7 +140,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

1
vendor/github.com/yuin/gopher-lua/.gitignore generated vendored Normal file
View file

@ -0,0 +1 @@
.idea

View file

@ -1,18 +0,0 @@
language: go
go:
- "1.9.x"
- "1.10.x"
- "1.11.x"
env:
global:
GO111MODULE=off
before_install:
- go get github.com/axw/gocov/gocov
- go get github.com/mattn/goveralls
- if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi
install:
- go get -u -v $(go list -f '{{join .Imports "\n"}}{{"\n"}}{{join .TestImports "\n"}}' ./... | sort | uniq | grep '\.' | grep -v gopher-lua)
script:
- $HOME/gopath/bin/goveralls -service=travis-ci

View file

@ -3,14 +3,14 @@
GopherLua: VM and compiler for Lua in Go.
===============================================================================
.. image:: https://godoc.org/github.com/yuin/gopher-lua?status.svg
:target: http://godoc.org/github.com/yuin/gopher-lua
.. image:: https://pkg.go.dev/badge/github.com/yuin/gopher-lua.svg
:target: https://pkg.go.dev/github.com/yuin/gopher-lua
.. image:: https://travis-ci.org/yuin/gopher-lua.svg
:target: https://travis-ci.org/yuin/gopher-lua
.. image:: https://github.com/yuin/gopher-lua/workflows/test/badge.svg?branch=master&event=push
:target: https://github.com/yuin/gopher-lua/actions?query=workflow:test
.. image:: https://coveralls.io/repos/yuin/gopher-lua/badge.svg
:target: https://coveralls.io/r/yuin/gopher-lua
.. image:: https://coveralls.io/repos/github/yuin/gopher-lua/badge.svg?branch=master
:target: https://coveralls.io/github/yuin/gopher-lua
.. image:: https://badges.gitter.im/Join%20Chat.svg
:alt: Join the chat at https://gitter.im/yuin/gopher-lua
@ -19,7 +19,7 @@ GopherLua: VM and compiler for Lua in Go.
|
GopherLua is a Lua5.1 VM and compiler written in Go. GopherLua has a same goal
GopherLua is a Lua5.1(+ `goto` statement in Lua5.2) VM and compiler written in Go. GopherLua has a same goal
with Lua: **Be a scripting language with extensible semantics** . It provides
Go APIs that allow you to easily embed a scripting language to your Go host
programs.
@ -830,6 +830,8 @@ Miscellaneous notes
- ``file:setvbuf`` does not support a line buffering.
- Daylight saving time is not supported.
- GopherLua has a function to set an environment variable : ``os.setenv(name, value)``
- GopherLua support ``goto`` and ``::label::`` statement in Lua5.2.
- `goto` is a keyword and not a valid variable name.
----------------------------------------------------------------
Standalone interpreter
@ -870,6 +872,7 @@ Libraries for GopherLua
- `gluaperiphery <https://github.com/BixData/gluaperiphery>`_ : A periphery library for the GopherLua VM (GPIO, SPI, I2C, MMIO, and Serial peripheral I/O for Linux).
- `glua-async <https://github.com/CuberL/glua-async>`_ : An async/await implement for gopher-lua.
- `gopherlua-debugger <https://github.com/edolphin-ydf/gopherlua-debugger>`_ : A debugger for gopher-lua
- `gluamahonia <https://github.com/super1207/gluamahonia>`_ : An encoding converter for gopher-lua
----------------------------------------------------------------
Donation
----------------------------------------------------------------

View file

@ -3,7 +3,6 @@ package lua
import (
"context"
"fmt"
"github.com/yuin/gopher-lua/parse"
"io"
"math"
"os"
@ -12,6 +11,8 @@ import (
"sync"
"sync/atomic"
"time"
"github.com/yuin/gopher-lua/parse"
)
const MultRet = -1
@ -397,17 +398,18 @@ func (rg *registry) forceResize(newSize int) {
copy(newSlice, rg.array[:rg.top]) // should we copy the area beyond top? there shouldn't be any valid values there so it shouldn't be necessary.
rg.array = newSlice
}
func (rg *registry) SetTop(top int) {
// +inline-call rg.checkSize top
oldtop := rg.top
rg.top = top
for i := oldtop; i < rg.top; i++ {
func (rg *registry) SetTop(topi int) { // +inline-start
// +inline-call rg.checkSize topi
oldtopi := rg.top
rg.top = topi
for i := oldtopi; i < rg.top; i++ {
rg.array[i] = LNil
}
// values beyond top don't need to be valid LValues, so setting them to nil is fine
// setting them to nil rather than LNil lets us invoke the golang memclr opto
if rg.top < oldtop {
nilRange := rg.array[rg.top:oldtop]
if rg.top < oldtopi {
nilRange := rg.array[rg.top:oldtopi]
for i := range nilRange {
nilRange[i] = nil
}
@ -415,7 +417,7 @@ func (rg *registry) SetTop(top int) {
//for i := rg.top; i < oldtop; i++ {
// rg.array[i] = LNil
//}
}
} // +inline-end
func (rg *registry) Top() int {
return rg.top
@ -497,34 +499,34 @@ func (rg *registry) FillNil(regm, n int) { // +inline-start
func (rg *registry) Insert(value LValue, reg int) {
top := rg.Top()
if reg >= top {
rg.Set(reg, value)
// +inline-call rg.Set reg value
return
}
top--
for ; top >= reg; top-- {
// FIXME consider using copy() here if Insert() is called enough
rg.Set(top+1, rg.Get(top))
// +inline-call rg.Set top+1 rg.Get(top)
}
rg.Set(reg, value)
// +inline-call rg.Set reg value
}
func (rg *registry) Set(reg int, val LValue) {
newSize := reg + 1
func (rg *registry) Set(regi int, vali LValue) { // +inline-start
newSize := regi + 1
// +inline-call rg.checkSize newSize
rg.array[reg] = val
if reg >= rg.top {
rg.top = reg + 1
rg.array[regi] = vali
if regi >= rg.top {
rg.top = regi + 1
}
}
} // +inline-end
func (rg *registry) SetNumber(reg int, val LNumber) {
newSize := reg + 1
func (rg *registry) SetNumber(regi int, vali LNumber) { // +inline-start
newSize := regi + 1
// +inline-call rg.checkSize newSize
rg.array[reg] = rg.alloc.LNumber2I(val)
if reg >= rg.top {
rg.top = reg + 1
rg.array[regi] = rg.alloc.LNumber2I(vali)
if regi >= rg.top {
rg.top = regi + 1
}
}
} // +inline-end
func (rg *registry) IsFull() bool {
return rg.top >= cap(rg.array)
@ -768,6 +770,9 @@ func (ls *LState) isStarted() bool {
func (ls *LState) kill() {
ls.Dead = true
if ls.ctxCancelFn != nil {
ls.ctxCancelFn()
}
}
func (ls *LState) indexToReg(idx int) int {
@ -935,18 +940,22 @@ func (ls *LState) initCallFrame(cf *callFrame) { // +inline-start
proto := cf.Fn.Proto
nargs := cf.NArgs
np := int(proto.NumParameters)
if nargs < np {
// default any missing arguments to nil
newSize := cf.LocalBase + np
// +inline-call ls.reg.checkSize newSize
for i := nargs; i < np; i++ {
ls.reg.array[cf.LocalBase+i] = LNil
}
nargs = np
ls.reg.top = newSize
}
if (proto.IsVarArg & VarArgIsVarArg) == 0 {
if nargs < int(proto.NumUsedRegisters) {
nargs = int(proto.NumUsedRegisters)
}
newSize = cf.LocalBase + nargs
newSize := cf.LocalBase + nargs
// +inline-call ls.reg.checkSize newSize
for i := np; i < nargs; i++ {
ls.reg.array[cf.LocalBase+i] = LNil
@ -1212,6 +1221,10 @@ func NewState(opts ...Options) *LState {
return ls
}
func (ls *LState) IsClosed() bool {
return ls.stack == nil
}
func (ls *LState) Close() {
atomic.AddInt32(&ls.stop, 1)
for _, file := range ls.G.tempFiles {
@ -1393,6 +1406,7 @@ func (ls *LState) NewThread() (*LState, context.CancelFunc) {
if ls.ctx != nil {
thread.mainLoop = mainLoopWithContext
thread.ctx, f = context.WithCancel(ls.ctx)
thread.ctxCancelFn = f
}
return thread, f
}
@ -1842,6 +1856,9 @@ func (ls *LState) PCall(nargs, nret int, errfunc *LFunction) (err error) {
err = rcv.(*ApiError)
err.(*ApiError).StackTrace = ls.stackTrace(0)
}
ls.stack.SetSp(sp)
ls.currentFrame = ls.stack.Last()
ls.reg.SetTop(base)
}
}()
ls.Call(1, 1)
@ -2016,7 +2033,7 @@ func (ls *LState) SetMx(mx int) {
go func() {
limit := uint64(mx * 1024 * 1024) //MB
var s runtime.MemStats
for ls.stop == 0 {
for atomic.LoadInt32(&ls.stop) == 0 {
runtime.ReadMemStats(&s)
if s.Alloc >= limit {
fmt.Println("out of memory")

View file

@ -173,7 +173,8 @@ func init() {
A := int(inst>>18) & 0xff //GETA
RA := lbase + A
B := int(inst & 0x1ff) //GETB
reg.Set(RA, reg.Get(lbase+B))
v := reg.Get(lbase + B)
// +inline-call reg.Set RA v
return 0
},
func(L *LState, inst uint32, baseframe *callFrame) int { //OP_MOVEN
@ -183,7 +184,8 @@ func init() {
A := int(inst>>18) & 0xff //GETA
B := int(inst & 0x1ff) //GETB
C := int(inst>>9) & 0x1ff //GETC
reg.Set(lbase+A, reg.Get(lbase+B))
v := reg.Get(lbase + B)
// +inline-call reg.Set lbase+A v
code := cf.Fn.Proto.Code
pc := cf.Pc
for i := 0; i < C; i++ {
@ -191,7 +193,8 @@ func init() {
pc++
A = int(inst>>18) & 0xff //GETA
B = int(inst & 0x1ff) //GETB
reg.Set(lbase+A, reg.Get(lbase+B))
v := reg.Get(lbase + B)
// +inline-call reg.Set lbase+A v
}
cf.Pc = pc
return 0
@ -203,7 +206,8 @@ func init() {
A := int(inst>>18) & 0xff //GETA
RA := lbase + A
Bx := int(inst & 0x3ffff) //GETBX
reg.Set(RA, cf.Fn.Proto.Constants[Bx])
v := cf.Fn.Proto.Constants[Bx]
// +inline-call reg.Set RA v
return 0
},
func(L *LState, inst uint32, baseframe *callFrame) int { //OP_LOADBOOL
@ -215,9 +219,9 @@ func init() {
B := int(inst & 0x1ff) //GETB
C := int(inst>>9) & 0x1ff //GETC
if B != 0 {
reg.Set(RA, LTrue)
// +inline-call reg.Set RA LTrue
} else {
reg.Set(RA, LFalse)
// +inline-call reg.Set RA LFalse
}
if C != 0 {
cf.Pc++
@ -232,7 +236,7 @@ func init() {
RA := lbase + A
B := int(inst & 0x1ff) //GETB
for i := RA; i <= lbase+B; i++ {
reg.Set(i, LNil)
// +inline-call reg.Set i LNil
}
return 0
},
@ -243,7 +247,8 @@ func init() {
A := int(inst>>18) & 0xff //GETA
RA := lbase + A
B := int(inst & 0x1ff) //GETB
reg.Set(RA, cf.Fn.Upvalues[B].Value())
v := cf.Fn.Upvalues[B].Value()
// +inline-call reg.Set RA v
return 0
},
func(L *LState, inst uint32, baseframe *callFrame) int { //OP_GETGLOBAL
@ -254,7 +259,8 @@ func init() {
RA := lbase + A
Bx := int(inst & 0x3ffff) //GETBX
//reg.Set(RA, L.getField(cf.Fn.Env, cf.Fn.Proto.Constants[Bx]))
reg.Set(RA, L.getFieldString(cf.Fn.Env, cf.Fn.Proto.stringConstants[Bx]))
v := L.getFieldString(cf.Fn.Env, cf.Fn.Proto.stringConstants[Bx])
// +inline-call reg.Set RA v
return 0
},
func(L *LState, inst uint32, baseframe *callFrame) int { //OP_GETTABLE
@ -265,7 +271,8 @@ func init() {
RA := lbase + A
B := int(inst & 0x1ff) //GETB
C := int(inst>>9) & 0x1ff //GETC
reg.Set(RA, L.getField(reg.Get(lbase+B), L.rkValue(C)))
v := L.getField(reg.Get(lbase+B), L.rkValue(C))
// +inline-call reg.Set RA v
return 0
},
func(L *LState, inst uint32, baseframe *callFrame) int { //OP_GETTABLEKS
@ -276,7 +283,8 @@ func init() {
RA := lbase + A
B := int(inst & 0x1ff) //GETB
C := int(inst>>9) & 0x1ff //GETC
reg.Set(RA, L.getFieldString(reg.Get(lbase+B), L.rkString(C)))
v := L.getFieldString(reg.Get(lbase+B), L.rkString(C))
// +inline-call reg.Set RA v
return 0
},
func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SETGLOBAL
@ -330,7 +338,8 @@ func init() {
RA := lbase + A
B := int(inst & 0x1ff) //GETB
C := int(inst>>9) & 0x1ff //GETC
reg.Set(RA, newLTable(B, C))
v := newLTable(B, C)
// +inline-call reg.Set RA v
return 0
},
func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SELF
@ -342,8 +351,9 @@ func init() {
B := int(inst & 0x1ff) //GETB
C := int(inst>>9) & 0x1ff //GETC
selfobj := reg.Get(lbase + B)
reg.Set(RA, L.getFieldString(selfobj, L.rkString(C)))
reg.Set(RA+1, selfobj)
v := L.getFieldString(selfobj, L.rkString(C))
// +inline-call reg.Set RA v
// +inline-call reg.Set RA+1 selfobj
return 0
},
opArith, // OP_ADD
@ -361,17 +371,17 @@ func init() {
B := int(inst & 0x1ff) //GETB
unaryv := L.rkValue(B)
if nm, ok := unaryv.(LNumber); ok {
reg.SetNumber(RA, -nm)
// +inline-call reg.Set RA -nm
} else {
op := L.metaOp1(unaryv, "__unm")
if op.Type() == LTFunction {
reg.Push(op)
reg.Push(unaryv)
L.Call(1, 1)
reg.Set(RA, reg.Pop())
// +inline-call reg.Set RA reg.Pop()
} else if str, ok1 := unaryv.(LString); ok1 {
if num, err := parseNumber(string(str)); err == nil {
reg.Set(RA, -num)
// +inline-call reg.Set RA -num
} else {
L.RaiseError("__unm undefined")
}
@ -389,9 +399,9 @@ func init() {
RA := lbase + A
B := int(inst & 0x1ff) //GETB
if LVIsFalse(reg.Get(lbase + B)) {
reg.Set(RA, LTrue)
// +inline-call reg.Set RA LTrue
} else {
reg.Set(RA, LFalse)
// +inline-call reg.Set RA LFalse
}
return 0
},
@ -404,7 +414,7 @@ func init() {
B := int(inst & 0x1ff) //GETB
switch lv := L.rkValue(B).(type) {
case LString:
reg.SetNumber(RA, LNumber(len(lv)))
// +inline-call reg.SetNumber RA LNumber(len(lv))
default:
op := L.metaOp1(lv, "__len")
if op.Type() == LTFunction {
@ -413,12 +423,13 @@ func init() {
L.Call(1, 1)
ret := reg.Pop()
if ret.Type() == LTNumber {
reg.SetNumber(RA, ret.(LNumber))
v, _ := ret.(LNumber)
// +inline-call reg.SetNumber RA v
} else {
reg.SetNumber(RA, LNumber(0))
// +inline-call reg.Set RA ret
}
} else if lv.Type() == LTTable {
reg.SetNumber(RA, LNumber(lv.(*LTable).Len()))
// +inline-call reg.SetNumber RA LNumber(lv.(*LTable).Len())
} else {
L.RaiseError("__len undefined")
}
@ -435,7 +446,8 @@ func init() {
C := int(inst>>9) & 0x1ff //GETC
RC := lbase + C
RB := lbase + B
reg.Set(RA, stringConcat(L, RC-RB+1, RC))
v := stringConcat(L, RC-RB+1, RC)
// +inline-call reg.Set RA v
return 0
},
func(L *LState, inst uint32, baseframe *callFrame) int { //OP_JMP
@ -483,8 +495,8 @@ func init() {
rhs := L.rkValue(C)
ret := false
if v1, ok1 := lhs.assertFloat64(); ok1 {
if v2, ok2 := rhs.assertFloat64(); ok2 {
if v1, ok1 := lhs.(LNumber); ok1 {
if v2, ok2 := rhs.(LNumber); ok2 {
ret = v1 <= v2
} else {
L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String())
@ -538,7 +550,7 @@ func init() {
B := int(inst & 0x1ff) //GETB
C := int(inst>>9) & 0x1ff //GETC
if value := reg.Get(lbase + B); LVAsBool(value) != (C == 0) {
reg.Set(RA, value)
// +inline-call reg.Set RA value
} else {
cf.Pc++
}
@ -560,7 +572,7 @@ func init() {
nret := C - 1
var callable *LFunction
var meta bool
if fn, ok := lv.assertFunction(); ok {
if fn, ok := lv.(*LFunction); ok {
callable = fn
meta = false
} else {
@ -586,7 +598,7 @@ func init() {
lv := reg.Get(RA)
var callable *LFunction
var meta bool
if fn, ok := lv.assertFunction(); ok {
if fn, ok := lv.(*LFunction); ok {
callable = fn
meta = false
} else {
@ -673,17 +685,18 @@ func init() {
lbase := cf.LocalBase
A := int(inst>>18) & 0xff //GETA
RA := lbase + A
if init, ok1 := reg.Get(RA).assertFloat64(); ok1 {
if limit, ok2 := reg.Get(RA + 1).assertFloat64(); ok2 {
if step, ok3 := reg.Get(RA + 2).assertFloat64(); ok3 {
if init, ok1 := reg.Get(RA).(LNumber); ok1 {
if limit, ok2 := reg.Get(RA + 1).(LNumber); ok2 {
if step, ok3 := reg.Get(RA + 2).(LNumber); ok3 {
init += step
reg.SetNumber(RA, LNumber(init))
v := LNumber(init)
// +inline-call reg.SetNumber RA v
if (step > 0 && init <= limit) || (step <= 0 && init >= limit) {
Sbx := int(inst&0x3ffff) - opMaxArgSbx //GETSBX
cf.Pc += Sbx
reg.SetNumber(RA+3, LNumber(init))
// +inline-call reg.SetNumber RA+3 v
} else {
reg.SetTop(RA + 1)
// +inline-call reg.SetTop RA+1
}
} else {
L.RaiseError("for statement step must be a number")
@ -703,9 +716,9 @@ func init() {
A := int(inst>>18) & 0xff //GETA
RA := lbase + A
Sbx := int(inst&0x3ffff) - opMaxArgSbx //GETSBX
if init, ok1 := reg.Get(RA).assertFloat64(); ok1 {
if step, ok2 := reg.Get(RA + 2).assertFloat64(); ok2 {
reg.SetNumber(RA, LNumber(init-step))
if init, ok1 := reg.Get(RA).(LNumber); ok1 {
if step, ok2 := reg.Get(RA + 2).(LNumber); ok2 {
// +inline-call reg.SetNumber RA LNumber(init-step)
} else {
L.RaiseError("for statement step must be a number")
}
@ -723,13 +736,13 @@ func init() {
RA := lbase + A
C := int(inst>>9) & 0x1ff //GETC
nret := C
reg.SetTop(RA + 3 + 2)
reg.Set(RA+3+2, reg.Get(RA+2))
reg.Set(RA+3+1, reg.Get(RA+1))
reg.Set(RA+3, reg.Get(RA))
// +inline-call reg.SetTop RA+3+2
// +inline-call reg.Set RA+3+2 reg.Get(RA+2)
// +inline-call reg.Set RA+3+1 reg.Get(RA+1)
// +inline-call reg.Set RA+3 reg.Get(RA)
L.callR(2, nret, RA+3)
if value := reg.Get(RA + 3); value != LNil {
reg.Set(RA+2, value)
// +inline-call reg.Set RA+2 value
pc := cf.Fn.Proto.Code[cf.Pc]
cf.Pc += int(pc&0x3ffff) - opMaxArgSbx
}
@ -776,7 +789,7 @@ func init() {
Bx := int(inst & 0x3ffff) //GETBX
proto := cf.Fn.Proto.FunctionPrototypes[Bx]
closure := newLFunctionL(proto, cf.Fn.Env, int(proto.NumUpvalues))
reg.Set(RA, closure)
// +inline-call reg.Set RA closure
for i := 0; i < int(proto.NumUpvalues); i++ {
inst = cf.Fn.Proto.Code[cf.Pc]
cf.Pc++
@ -826,12 +839,14 @@ func opArith(L *LState, inst uint32, baseframe *callFrame) int { //OP_ADD, OP_SU
C := int(inst>>9) & 0x1ff //GETC
lhs := L.rkValue(B)
rhs := L.rkValue(C)
v1, ok1 := lhs.assertFloat64()
v2, ok2 := rhs.assertFloat64()
v1, ok1 := lhs.(LNumber)
v2, ok2 := rhs.(LNumber)
if ok1 && ok2 {
reg.SetNumber(RA, numberArith(L, opcode, LNumber(v1), LNumber(v2)))
v := numberArith(L, opcode, LNumber(v1), LNumber(v2))
// +inline-call reg.SetNumber RA v
} else {
reg.Set(RA, objectArith(L, opcode, lhs, rhs))
v := objectArith(L, opcode, lhs, rhs)
// +inline-call reg.Set RA v
}
return 0
}
@ -840,7 +855,7 @@ func luaModulo(lhs, rhs LNumber) LNumber {
flhs := float64(lhs)
frhs := float64(rhs)
v := math.Mod(flhs, frhs)
if flhs < 0 || frhs < 0 && !(flhs < 0 && frhs < 0) {
if frhs > 0 && v < 0 || frhs < 0 && v > 0 {
v += frhs
}
return LNumber(v)
@ -884,7 +899,7 @@ func objectArith(L *LState, opcode int, lhs, rhs LValue) LValue {
event = "__pow"
}
op := L.metaOp2(lhs, rhs, event)
if op.Type() == LTFunction {
if _, ok := op.(*LFunction); ok {
L.reg.Push(op)
L.reg.Push(lhs)
L.reg.Push(rhs)
@ -901,8 +916,8 @@ func objectArith(L *LState, opcode int, lhs, rhs LValue) LValue {
rhs = rnum
}
}
if v1, ok1 := lhs.assertFloat64(); ok1 {
if v2, ok2 := rhs.assertFloat64(); ok2 {
if v1, ok1 := lhs.(LNumber); ok1 {
if v2, ok2 := rhs.(LNumber); ok2 {
return numberArith(L, opcode, LNumber(v1), LNumber(v2))
}
}
@ -951,8 +966,8 @@ func stringConcat(L *LState, total, last int) LValue {
func lessThan(L *LState, lhs, rhs LValue) bool {
// optimization for numbers
if v1, ok1 := lhs.assertFloat64(); ok1 {
if v2, ok2 := rhs.assertFloat64(); ok2 {
if v1, ok1 := lhs.(LNumber); ok1 {
if v2, ok2 := rhs.(LNumber); ok2 {
return v1 < v2
}
L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String())
@ -972,17 +987,18 @@ func lessThan(L *LState, lhs, rhs LValue) bool {
}
func equals(L *LState, lhs, rhs LValue, raw bool) bool {
if lhs.Type() != rhs.Type() {
lt := lhs.Type()
if lt != rhs.Type() {
return false
}
ret := false
switch lhs.Type() {
switch lt {
case LTNil:
ret = true
case LTNumber:
v1, _ := lhs.assertFloat64()
v2, _ := rhs.assertFloat64()
v1, _ := lhs.(LNumber)
v2, _ := rhs.(LNumber)
ret = v1 == v2
case LTBool:
ret = bool(lhs.(LBool)) == bool(rhs.(LBool))

View file

@ -52,6 +52,7 @@ type StringExpr struct {
type Comma3Expr struct {
ExprBase
AdjustRet bool
}
type IdentExpr struct {

View file

@ -93,3 +93,15 @@ type ReturnStmt struct {
type BreakStmt struct {
StmtBase
}
type LabelStmt struct {
StmtBase
Name string
}
type GotoStmt struct {
StmtBase
Label string
}

View file

@ -40,6 +40,11 @@ func (ls *LState) CheckNumber(n int) LNumber {
if lv, ok := v.(LNumber); ok {
return lv
}
if lv, ok := v.(LString); ok {
if num, err := parseNumber(string(lv)); err == nil {
return num
}
}
ls.TypeError(n, LTNumber)
return 0
}
@ -413,7 +418,7 @@ func (ls *LState) DoString(source string) error {
// ToStringMeta returns string representation of given LValue.
// This method calls the `__tostring` meta method if defined.
func (ls *LState) ToStringMeta(lv LValue) LValue {
if fn, ok := ls.metaOp1(lv, "__tostring").assertFunction(); ok {
if fn, ok := ls.metaOp1(lv, "__tostring").(*LFunction); ok {
ls.Push(fn)
ls.Push(lv)
ls.Call(1, 1)

View file

@ -260,7 +260,7 @@ func basePairs(L *LState) int {
func basePCall(L *LState) int {
L.CheckAny(1)
v := L.Get(1)
if v.Type() != LTFunction {
if v.Type() != LTFunction && L.GetMetaField(v, "__call").Type() != LTFunction {
L.Push(LFalse)
L.Push(LString("attempt to call a " + v.Type().String() + " value"))
return 2
@ -321,11 +321,16 @@ func baseSelect(L *LState) int {
switch lv := L.Get(1).(type) {
case LNumber:
idx := int(lv)
num := L.reg.Top() - L.indexToReg(int(lv)) - 1
num := L.GetTop()
if idx < 0 {
num++
idx = num + idx
} else if idx > num {
idx = num
}
return num
if 1 > idx {
L.ArgError(1, "index out of range")
}
return num - idx
case LString:
if string(lv) != "#" {
L.ArgError(1, "invalid string '"+string(lv)+"'")

View file

@ -2,9 +2,10 @@ package lua
import (
"fmt"
"github.com/yuin/gopher-lua/ast"
"math"
"reflect"
"github.com/yuin/gopher-lua/ast"
)
/* internal constants & structs {{{ */
@ -94,7 +95,11 @@ func sline(pos ast.PositionHolder) int {
}
func eline(pos ast.PositionHolder) int {
return pos.LastLine()
line := pos.LastLine()
if line == 0 {
return pos.Line()
}
return line
}
func savereg(ec *expcontext, reg int) int {
@ -114,7 +119,7 @@ func isVarArgReturnExpr(expr ast.Expr) bool {
case *ast.FuncCallExpr:
return !ex.AdjustRet
case *ast.Comma3Expr:
return true
return !ex.AdjustRet
}
return false
}
@ -134,6 +139,28 @@ func lnumberValue(expr ast.Expr) (LNumber, bool) {
/* utilities }}} */
type gotoLabelDesc struct { // {{{
Id int
Name string
Pc int
Line int
NumActiveLocalVars int
}
func newLabelDesc(id int, name string, pc, line, n int) *gotoLabelDesc {
return &gotoLabelDesc{
Id: id,
Name: name,
Pc: pc,
Line: line,
NumActiveLocalVars: n,
}
}
func (l *gotoLabelDesc) SetNumActiveLocalVars(n int) {
l.NumActiveLocalVars = n
} // }}}
type CompileError struct { // {{{
context *funcContext
Line int
@ -334,10 +361,12 @@ type codeBlock struct {
RefUpvalue bool
LineStart int
LastLine int
labels map[string]*gotoLabelDesc
firstGotoIndex int
}
func newCodeBlock(localvars *varNamePool, blabel int, parent *codeBlock, pos ast.PositionHolder) *codeBlock {
bl := &codeBlock{localvars, blabel, parent, false, 0, 0}
func newCodeBlock(localvars *varNamePool, blabel int, parent *codeBlock, pos ast.PositionHolder, firstGotoIndex int) *codeBlock {
bl := &codeBlock{localvars, blabel, parent, false, 0, 0, map[string]*gotoLabelDesc{}, firstGotoIndex}
if pos != nil {
bl.LineStart = pos.Line()
bl.LastLine = pos.LastLine()
@ -345,6 +374,29 @@ func newCodeBlock(localvars *varNamePool, blabel int, parent *codeBlock, pos ast
return bl
}
func (b *codeBlock) AddLabel(label *gotoLabelDesc) *gotoLabelDesc {
if old, ok := b.labels[label.Name]; ok {
return old
}
b.labels[label.Name] = label
return nil
}
func (b *codeBlock) GetLabel(label string) *gotoLabelDesc {
if v, ok := b.labels[label]; ok {
return v
}
return nil
}
func (b *codeBlock) LocalVarsCount() int {
count := 0
for block := b; block != nil; block = block.Parent {
count += len(block.LocalVars.Names())
}
return count
}
type funcContext struct {
Proto *FunctionProto
Code *codeStore
@ -355,6 +407,8 @@ type funcContext struct {
regTop int
labelId int
labelPc map[int]int
gotosCount int
unresolvedGotos map[int]*gotoLabelDesc
}
func newFuncContext(sourcename string, parent *funcContext) *funcContext {
@ -363,15 +417,93 @@ func newFuncContext(sourcename string, parent *funcContext) *funcContext {
Code: &codeStore{make([]uint32, 0, 1024), make([]int, 0, 1024), 0},
Parent: parent,
Upvalues: newVarNamePool(0),
Block: newCodeBlock(newVarNamePool(0), labelNoJump, nil, nil),
Block: newCodeBlock(newVarNamePool(0), labelNoJump, nil, nil, 0),
regTop: 0,
labelId: 1,
labelPc: map[int]int{},
gotosCount: 0,
unresolvedGotos: map[int]*gotoLabelDesc{},
}
fc.Blocks = []*codeBlock{fc.Block}
return fc
}
func (fc *funcContext) CheckUnresolvedGoto() {
for i := fc.Block.firstGotoIndex; i < fc.gotosCount; i++ {
gotoLabel, ok := fc.unresolvedGotos[i]
if !ok {
continue
}
raiseCompileError(fc, fc.Proto.LastLineDefined, "no visible label '%s' for <goto> at line %d", gotoLabel.Name, gotoLabel.Line)
}
}
func (fc *funcContext) AddUnresolvedGoto(label *gotoLabelDesc) {
fc.unresolvedGotos[fc.gotosCount] = label
fc.gotosCount++
}
func (fc *funcContext) AddNamedLabel(label *gotoLabelDesc) {
if old := fc.Block.AddLabel(label); old != nil {
raiseCompileError(fc, label.Line+1, "label '%s' already defined on line %d", label.Name, old.Line)
}
fc.SetLabelPc(label.Id, label.Pc)
}
func (fc *funcContext) GetNamedLabel(name string) *gotoLabelDesc {
return fc.Block.GetLabel(name)
}
func (fc *funcContext) ResolveGoto(from, to *gotoLabelDesc, index int) {
if from.NumActiveLocalVars < to.NumActiveLocalVars {
varName := fc.Block.LocalVars.Names()[len(fc.Block.LocalVars.Names())-1]
raiseCompileError(fc, to.Line+1, "<goto %s> at line %d jumps into the scope of local '%s'", to.Name, from.Line, varName)
}
fc.Code.SetSbx(from.Pc, to.Id)
delete(fc.unresolvedGotos, index)
}
func (fc *funcContext) FindLabel(block *codeBlock, gotoLabel *gotoLabelDesc, i int) bool {
target := block.GetLabel(gotoLabel.Name)
if target != nil {
if gotoLabel.NumActiveLocalVars > target.NumActiveLocalVars && block.RefUpvalue {
fc.Code.SetA(gotoLabel.Pc-1, target.NumActiveLocalVars)
}
fc.ResolveGoto(gotoLabel, target, i)
return true
}
return false
}
func (fc *funcContext) ResolveCurrentBlockGotosWithParentBlock() {
blockActiveLocalVars := fc.Block.Parent.LocalVarsCount()
for i := fc.Block.firstGotoIndex; i < fc.gotosCount; i++ {
gotoLabel, ok := fc.unresolvedGotos[i]
if !ok {
continue
}
if gotoLabel.NumActiveLocalVars > blockActiveLocalVars {
if fc.Block.RefUpvalue {
fc.Code.SetA(gotoLabel.Pc-1, blockActiveLocalVars)
}
gotoLabel.SetNumActiveLocalVars(blockActiveLocalVars)
}
fc.FindLabel(fc.Block.Parent, gotoLabel, i)
}
}
func (fc *funcContext) ResolveForwardGoto(target *gotoLabelDesc) {
for i := fc.Block.firstGotoIndex; i <= fc.gotosCount; i++ {
gotoLabel, ok := fc.unresolvedGotos[i]
if !ok {
continue
}
if gotoLabel.Name == target.Name {
fc.ResolveGoto(gotoLabel, target, i)
}
}
}
func (fc *funcContext) NewLabel() int {
ret := fc.labelId
fc.labelId++
@ -400,6 +532,13 @@ func (fc *funcContext) ConstIndex(value LValue) int {
}
return v
}
func (fc *funcContext) BlockLocalVarsCount() int {
count := 0
for block := fc.Block; block != nil; block = block.Parent {
count += len(block.LocalVars.Names())
}
return count
}
func (fc *funcContext) RegisterLocalVar(name string) int {
ret := fc.Block.LocalVars.Register(name)
@ -431,7 +570,7 @@ func (fc *funcContext) LocalVars() []varNamePoolValue {
}
func (fc *funcContext) EnterBlock(blabel int, pos ast.PositionHolder) {
fc.Block = newCodeBlock(newVarNamePool(fc.RegTop()), blabel, fc.Block, pos)
fc.Block = newCodeBlock(newVarNamePool(fc.RegTop()), blabel, fc.Block, pos, fc.gotosCount)
fc.Blocks = append(fc.Blocks, fc.Block)
}
@ -447,6 +586,10 @@ func (fc *funcContext) CloseUpvalues() int {
func (fc *funcContext) LeaveBlock() int {
closed := fc.CloseUpvalues()
fc.EndScope()
if fc.Block.Parent != nil {
fc.ResolveCurrentBlockGotosWithParentBlock()
}
fc.Block = fc.Block.Parent
fc.SetRegTop(fc.Block.LocalVars.LastIndex())
return closed
@ -471,9 +614,17 @@ func (fc *funcContext) RegTop() int {
/* FuncContext }}} */
func compileChunk(context *funcContext, chunk []ast.Stmt) { // {{{
for _, stmt := range chunk {
compileStmt(context, stmt)
func compileChunk(context *funcContext, chunk []ast.Stmt, untilFollows bool) { // {{{
for i, stmt := range chunk {
lastStmt := true
for j := i + 1; j < len(chunk); j++ {
_, ok := chunk[j].(*ast.LabelStmt)
if !ok {
lastStmt = false
break
}
}
compileStmt(context, stmt, lastStmt && !untilFollows)
}
} // }}}
@ -485,13 +636,21 @@ func compileBlock(context *funcContext, chunk []ast.Stmt) { // {{{
ph.SetLine(sline(chunk[0]))
ph.SetLastLine(eline(chunk[len(chunk)-1]))
context.EnterBlock(labelNoJump, ph)
for _, stmt := range chunk {
compileStmt(context, stmt)
for i, stmt := range chunk {
lastStmt := true
for j := i + 1; j < len(chunk); j++ {
_, ok := chunk[j].(*ast.LabelStmt)
if !ok {
lastStmt = false
break
}
}
compileStmt(context, stmt, lastStmt)
}
context.LeaveBlock()
} // }}}
func compileStmt(context *funcContext, stmt ast.Stmt) { // {{{
func compileStmt(context *funcContext, stmt ast.Stmt, isLastStmt bool) { // {{{
switch st := stmt.(type) {
case *ast.AssignStmt:
compileAssignStmt(context, st)
@ -501,7 +660,7 @@ func compileStmt(context *funcContext, stmt ast.Stmt) { // {{{
compileFuncCallExpr(context, context.RegTop(), st.Expr.(*ast.FuncCallExpr), ecnone(-1))
case *ast.DoBlockStmt:
context.EnterBlock(labelNoJump, st)
compileChunk(context, st.Stmts)
compileChunk(context, st.Stmts, false)
context.LeaveBlock()
case *ast.WhileStmt:
compileWhileStmt(context, st)
@ -519,14 +678,17 @@ func compileStmt(context *funcContext, stmt ast.Stmt) { // {{{
compileNumberForStmt(context, st)
case *ast.GenericForStmt:
compileGenericForStmt(context, st)
case *ast.LabelStmt:
compileLabelStmt(context, st, isLastStmt)
case *ast.GotoStmt:
compileGotoStmt(context, st)
}
} // }}}
func compileAssignStmtLeft(context *funcContext, stmt *ast.AssignStmt) (int, []*assigncontext) { // {{{
reg := context.RegTop()
acs := make([]*assigncontext, 0, len(stmt.Lhs))
for i, lhs := range stmt.Lhs {
islast := i == len(stmt.Lhs)-1
for _, lhs := range stmt.Lhs {
switch st := lhs.(type) {
case *ast.IdentExpr:
identtype := getIdentRefType(context, context, st)
@ -537,10 +699,8 @@ func compileAssignStmtLeft(context *funcContext, stmt *ast.AssignStmt) (int, []*
case ecUpvalue:
context.Upvalues.RegisterUnique(st.Value)
case ecLocal:
if islast {
ec.reg = context.FindLocalVar(st.Value)
}
}
acs = append(acs, &assigncontext{ec, 0, 0, false, false})
case *ast.AttrGetExpr:
ac := &assigncontext{&expcontext{ecTable, regNotDefined, 0}, 0, 0, false, false}
@ -723,8 +883,12 @@ func compileReturnStmt(context *funcContext, stmt *ast.ReturnStmt) { // {{{
return
}
case *ast.FuncCallExpr:
if ex.AdjustRet { // return (func())
reg += compileExpr(context, reg, ex, ecnone(0))
} else {
reg += compileExpr(context, reg, ex, ecnone(-2))
code.SetOpCode(code.LastPC(), OP_TAILCALL)
}
code.AddABC(OP_RETURN, a, 0, 0, sline(stmt))
return
}
@ -821,7 +985,7 @@ func compileWhileStmt(context *funcContext, stmt *ast.WhileStmt) { // {{{
compileBranchCondition(context, context.RegTop(), stmt.Condition, thenlabel, elselabel, false)
context.SetLabelPc(thenlabel, context.Code.LastPC())
context.EnterBlock(elselabel, stmt)
compileChunk(context, stmt.Stmts)
compileChunk(context, stmt.Stmts, false)
context.CloseUpvalues()
context.Code.AddASbx(OP_JMP, 0, condlabel, eline(stmt))
context.LeaveBlock()
@ -836,7 +1000,7 @@ func compileRepeatStmt(context *funcContext, stmt *ast.RepeatStmt) { // {{{
context.SetLabelPc(initlabel, context.Code.LastPC())
context.SetLabelPc(elselabel, context.Code.LastPC())
context.EnterBlock(thenlabel, stmt)
compileChunk(context, stmt.Stmts)
compileChunk(context, stmt.Stmts, true)
compileBranchCondition(context, context.RegTop(), stmt.Condition, thenlabel, elselabel, false)
context.SetLabelPc(thenlabel, context.Code.LastPC())
@ -912,7 +1076,7 @@ func compileNumberForStmt(context *funcContext, stmt *ast.NumberForStmt) { // {{
context.RegisterLocalVar(stmt.Name)
bodypc := code.LastPC()
compileChunk(context, stmt.Stmts)
compileChunk(context, stmt.Stmts, false)
context.LeaveBlock()
@ -945,7 +1109,7 @@ func compileGenericForStmt(context *funcContext, stmt *ast.GenericForStmt) { //
}
context.SetLabelPc(bodylabel, code.LastPC())
compileChunk(context, stmt.Stmts)
compileChunk(context, stmt.Stmts, false)
context.LeaveBlock()
@ -956,6 +1120,24 @@ func compileGenericForStmt(context *funcContext, stmt *ast.GenericForStmt) { //
context.SetLabelPc(endlabel, code.LastPC())
} // }}}
func compileLabelStmt(context *funcContext, stmt *ast.LabelStmt, isLastStmt bool) { // {{{
labelId := context.NewLabel()
label := newLabelDesc(labelId, stmt.Name, context.Code.LastPC(), sline(stmt), context.BlockLocalVarsCount())
context.AddNamedLabel(label)
if isLastStmt {
label.SetNumActiveLocalVars(context.Block.Parent.LocalVarsCount())
}
context.ResolveForwardGoto(label)
} // }}}
func compileGotoStmt(context *funcContext, stmt *ast.GotoStmt) { // {{{
context.Code.AddABC(OP_CLOSE, 0, 0, 0, sline(stmt))
context.Code.AddASbx(OP_JMP, 0, labelNoJump, sline(stmt))
label := newLabelDesc(-1, stmt.Label, context.Code.LastPC(), sline(stmt), context.BlockLocalVarsCount())
context.AddUnresolvedGoto(label)
context.FindLabel(context.Block, label, context.gotosCount-1)
} // }}}
func compileExpr(context *funcContext, reg int, expr ast.Expr, ec *expcontext) int { // {{{
code := context.Code
sreg := savereg(ec, reg)
@ -1145,10 +1327,11 @@ func compileFunctionExpr(context *funcContext, funcexpr *ast.FunctionExpr, ec *e
context.Proto.IsVarArg |= VarArgIsVarArg
}
compileChunk(context, funcexpr.Stmts)
compileChunk(context, funcexpr.Stmts, false)
context.Code.AddABC(OP_RETURN, 0, 1, 0, eline(funcexpr))
context.EndScope()
context.CheckUnresolvedGoto()
context.Proto.Code = context.Code.List()
context.Proto.DbgSourcePositions = context.Code.PosList()
context.Proto.DbgUpvalues = context.Upvalues.Names()
@ -1464,7 +1647,17 @@ func compileLogicalOpExprAux(context *funcContext, reg int, expr ast.Expr, ec *e
a := reg
sreg := savereg(ec, a)
if !hasnextcond && thenlabel == elselabel {
isLastAnd := elselabel == lb.e && thenlabel != elselabel
isLastOr := thenlabel == lb.e && hasnextcond
if ident, ok := expr.(*ast.IdentExpr); ok && (isLastAnd || isLastOr) && getIdentRefType(context, context, ident) == ecLocal {
b := context.FindLocalVar(ident.Value)
op := OP_TESTSET
if sreg == b {
op = OP_TEST
}
code.AddABC(op, sreg, b, 0^flip, sline(expr))
} else if !hasnextcond && thenlabel == elselabel {
reg += compileExpr(context, reg, expr, &expcontext{ec.ctype, intMax(a, sreg), ec.varargopt})
last := context.Code.Last()
if opGetOpCode(last) == OP_MOVE && opGetArgA(last) == a {
@ -1474,7 +1667,7 @@ func compileLogicalOpExprAux(context *funcContext, reg int, expr ast.Expr, ec *e
}
} else {
reg += compileExpr(context, reg, expr, ecnone(0))
if sreg == a {
if !hasnextcond {
code.AddABC(OP_TEST, a, 0, 0^flip, sline(expr))
} else {
code.AddABC(OP_TESTSET, sreg, a, 0^flip, sline(expr))
@ -1665,6 +1858,10 @@ func Compile(chunk []ast.Stmt, name string) (proto *FunctionProto, err error) {
err = nil
parlist := &ast.ParList{HasVargs: true, Names: []string{}}
funcexpr := &ast.FunctionExpr{ParList: parlist, Stmts: chunk}
if len(chunk) > 0 {
funcexpr.SetLastLine(sline(chunk[0]))
funcexpr.SetLastLine(eline(chunk[len(chunk)-1]) + 1)
}
context := newFuncContext(name, nil)
compileFunctionExpr(context, funcexpr, ecnone(0))
proto = context.Proto

View file

@ -22,15 +22,22 @@ var LuaPath = "LUA_PATH"
var LuaLDir string
var LuaPathDefault string
var LuaOS string
var LuaDirSep string
var LuaPathSep = ";"
var LuaPathMark = "?"
var LuaExecDir = "!"
var LuaIgMark = "-"
func init() {
if os.PathSeparator == '/' { // unix-like
LuaOS = "unix"
LuaLDir = "/usr/local/share/lua/5.1"
LuaDirSep = "/"
LuaPathDefault = "./?.lua;" + LuaLDir + "/?.lua;" + LuaLDir + "/?/init.lua"
} else { // windows
LuaOS = "windows"
LuaLDir = "!\\lua"
LuaDirSep = "\\"
LuaPathDefault = ".\\?.lua;" + LuaLDir + "\\?.lua;" + LuaLDir + "\\?\\init.lua"
}
}

View file

@ -155,8 +155,8 @@ func debugTraceback(L *LState) int {
level := L.OptInt(2, 1)
ls := L
if L.GetTop() > 0 {
if s, ok := L.Get(1).assertString(); ok {
msg = s
if s, ok := L.Get(1).(LString); ok {
msg = string(s)
}
if l, ok := L.Get(1).(*LState); ok {
ls = l

View file

@ -629,7 +629,7 @@ func ioOpenFile(L *LState) int {
mode = os.O_RDONLY
writable = false
case "w", "wb":
mode = os.O_WRONLY | os.O_CREATE
mode = os.O_WRONLY | os.O_TRUNC | os.O_CREATE
readable = false
case "a", "ab":
mode = os.O_WRONLY | os.O_APPEND | os.O_CREATE
@ -658,6 +658,9 @@ func ioPopen(L *LState) int {
cmd := L.CheckString(1)
if L.GetTop() == 1 {
L.Push(LString("r"))
} else if L.GetTop() > 1 && (L.Get(2)).Type() == LTNil {
L.SetTop(1)
L.Push(LString("r"))
}
var file *LUserData
var err error

View file

@ -65,6 +65,9 @@ func OpenPackage(L *LState) int {
L.SetField(packagemod, "path", LString(loGetPath(LuaPath, LuaPathDefault)))
L.SetField(packagemod, "cpath", emptyLString)
L.SetField(packagemod, "config", LString(LuaDirSep+"\n"+LuaPathSep+
"\n"+LuaPathMark+"\n"+LuaExecDir+"\n"+LuaIgMark+"\n"))
L.Push(packagemod)
return 1
}

View file

@ -15,9 +15,27 @@ func init() {
func getIntField(L *LState, tb *LTable, key string, v int) int {
ret := tb.RawGetString(key)
if ln, ok := ret.(LNumber); ok {
return int(ln)
switch lv := ret.(type) {
case LNumber:
return int(lv)
case LString:
slv := string(lv)
slv = strings.TrimLeft(slv, " ")
if strings.HasPrefix(slv, "0") && !strings.HasPrefix(slv, "0x") && !strings.HasPrefix(slv, "0X") {
// Standard lua interpreter only support decimal and hexadecimal
slv = strings.TrimLeft(slv, "0")
if slv == "" {
return 0
}
}
if num, err := parseNumber(slv); err == nil {
return int(num)
}
default:
return v
}
return v
}
@ -88,16 +106,20 @@ func osExit(L *LState) int {
func osDate(L *LState) int {
t := time.Now()
isUTC := false
cfmt := "%c"
if L.GetTop() >= 1 {
cfmt = L.CheckString(1)
if strings.HasPrefix(cfmt, "!") {
t = time.Now().UTC()
cfmt = strings.TrimLeft(cfmt, "!")
isUTC = true
}
if L.GetTop() >= 2 {
t = time.Unix(L.CheckInt64(2), 0)
}
if isUTC {
t = t.UTC()
}
if strings.HasPrefix(cfmt, "*t") {
ret := L.NewTable()
ret.RawSetString("year", LNumber(t.Year()))
@ -174,7 +196,14 @@ func osTime(L *LState) int {
if L.GetTop() == 0 {
L.Push(LNumber(time.Now().Unix()))
} else {
tbl := L.CheckTable(1)
lv := L.CheckAny(1)
if lv == LNil {
L.Push(LNumber(time.Now().Unix()))
} else {
tbl, ok := lv.(*LTable)
if !ok {
L.TypeError(1, LTTable)
}
sec := getIntField(L, tbl, "sec", 0)
min := getIntField(L, tbl, "min", 0)
hour := getIntField(L, tbl, "hour", 12)
@ -189,6 +218,7 @@ func osTime(L *LState) int {
}
L.Push(LNumber(t.Unix()))
}
}
return 1
}

View file

@ -2,3 +2,6 @@ all : parser.go
parser.go : parser.go.y
goyacc -o $@ parser.go.y; [ -f y.output ] && ( rm -f y.output )
clean:
rm -f parser.go

View file

@ -4,11 +4,12 @@ import (
"bufio"
"bytes"
"fmt"
"github.com/yuin/gopher-lua/ast"
"io"
"reflect"
"strconv"
"strings"
"github.com/yuin/gopher-lua/ast"
)
const EOF = -1
@ -255,7 +256,7 @@ func (sc *Scanner) scanMultilineString(ch int, buf *bytes.Buffer) error {
var count1, count2 int
count1, ch = sc.countSep(ch)
if ch != '[' {
return sc.Error(string(ch), "invalid multiline string")
return sc.Error(string(rune(ch)), "invalid multiline string")
}
ch = sc.Next()
if ch == '\n' || ch == '\r' {
@ -286,7 +287,7 @@ var reservedWords = map[string]int{
"end": TEnd, "false": TFalse, "for": TFor, "function": TFunction,
"if": TIf, "in": TIn, "local": TLocal, "nil": TNil, "not": TNot, "or": TOr,
"return": TReturn, "repeat": TRepeat, "then": TThen, "true": TTrue,
"until": TUntil, "while": TWhile}
"until": TUntil, "while": TWhile, "goto": TGoto}
func (sc *Scanner) Scan(lexer *Lexer) (ast.Token, error) {
redo:
@ -338,7 +339,7 @@ redo:
goto redo
} else {
tok.Type = ch
tok.Str = string(ch)
tok.Str = string(rune(ch))
}
case '"', '\'':
tok.Type = TString
@ -351,7 +352,7 @@ redo:
tok.Str = buf.String()
} else {
tok.Type = ch
tok.Str = string(ch)
tok.Str = string(rune(ch))
}
case '=':
if sc.Peek() == '=' {
@ -360,7 +361,7 @@ redo:
sc.Next()
} else {
tok.Type = ch
tok.Str = string(ch)
tok.Str = string(rune(ch))
}
case '~':
if sc.Peek() == '=' {
@ -377,7 +378,7 @@ redo:
sc.Next()
} else {
tok.Type = ch
tok.Str = string(ch)
tok.Str = string(rune(ch))
}
case '>':
if sc.Peek() == '=' {
@ -386,7 +387,7 @@ redo:
sc.Next()
} else {
tok.Type = ch
tok.Str = string(ch)
tok.Str = string(rune(ch))
}
case '.':
ch2 := sc.Peek()
@ -408,9 +409,18 @@ redo:
tok.Type = '.'
}
tok.Str = buf.String()
case '+', '*', '/', '%', '^', '#', '(', ')', '{', '}', ']', ';', ':', ',':
case ':':
if sc.Peek() == ':' {
tok.Type = T2Colon
tok.Str = "::"
sc.Next()
} else {
tok.Type = ch
tok.Str = string(ch)
tok.Str = string(rune(ch))
}
case '+', '*', '/', '%', '^', '#', '(', ')', '{', '}', ']', ';', ',':
tok.Type = ch
tok.Str = string(rune(ch))
default:
writeChar(buf, ch)
err = sc.Error(buf.String(), "Invalid token")

File diff suppressed because it is too large Load diff

View file

@ -52,10 +52,10 @@ import (
}
/* Reserved words */
%token<token> TAnd TBreak TDo TElse TElseIf TEnd TFalse TFor TFunction TIf TIn TLocal TNil TNot TOr TReturn TRepeat TThen TTrue TUntil TWhile
%token<token> TAnd TBreak TDo TElse TElseIf TEnd TFalse TFor TFunction TIf TIn TLocal TNil TNot TOr TReturn TRepeat TThen TTrue TUntil TWhile TGoto
/* Literals */
%token<token> TEqeq TNeq TLte TGte T2Comma T3Comma TIdent TNumber TString '{' '('
%token<token> TEqeq TNeq TLte TGte T2Comma T3Comma T2Colon TIdent TNumber TString '{' '('
/* Operators */
%left TOr
@ -187,6 +187,14 @@ stat:
TLocal namelist {
$$ = &ast.LocalAssignStmt{Names: $2, Exprs:[]ast.Expr{}}
$$.SetLine($1.Pos.Line)
} |
T2Colon TIdent T2Colon {
$$ = &ast.LabelStmt{Name: $2.Str}
$$.SetLine($1.Pos.Line)
} |
TGoto TIdent {
$$ = &ast.GotoStmt{Label: $2.Str}
$$.SetLine($1.Pos.Line)
}
elseifs:
@ -396,6 +404,9 @@ prefixexp:
$$ = $1
} |
'(' expr ')' {
if ex, ok := $2.(*ast.Comma3Expr); ok {
ex.AdjustRet = true
}
$$ = $2
$$.SetLine($1.Pos.Line)
}

View file

@ -210,7 +210,7 @@ func (pn *singleClass) Matches(ch int) bool {
case 'l', 'L':
ret = 'a' <= ch && ch <= 'z'
case 'p', 'P':
ret = (0x21 <= ch && ch <= 0x2f) || (0x30 <= ch && ch <= 0x40) || (0x5b <= ch && ch <= 0x60) || (0x7b <= ch && ch <= 0x7e)
ret = (0x21 <= ch && ch <= 0x2f) || (0x3a <= ch && ch <= 0x40) || (0x5b <= ch && ch <= 0x60) || (0x7b <= ch && ch <= 0x7e)
case 's', 'S':
switch ch {
case ' ', '\f', '\n', '\r', '\t', '\v':

View file

@ -7,7 +7,6 @@ package lua
import (
"context"
"fmt"
"github.com/yuin/gopher-lua/parse"
"io"
"math"
"os"
@ -16,6 +15,8 @@ import (
"sync"
"sync/atomic"
"time"
"github.com/yuin/gopher-lua/parse"
)
const MultRet = -1
@ -401,24 +402,25 @@ func (rg *registry) forceResize(newSize int) {
copy(newSlice, rg.array[:rg.top]) // should we copy the area beyond top? there shouldn't be any valid values there so it shouldn't be necessary.
rg.array = newSlice
}
func (rg *registry) SetTop(top int) {
func (rg *registry) SetTop(topi int) { // +inline-start
// this section is inlined by go-inline
// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
{
requiredSize := top
requiredSize := topi
if requiredSize > cap(rg.array) {
rg.resize(requiredSize)
}
}
oldtop := rg.top
rg.top = top
for i := oldtop; i < rg.top; i++ {
oldtopi := rg.top
rg.top = topi
for i := oldtopi; i < rg.top; i++ {
rg.array[i] = LNil
}
// values beyond top don't need to be valid LValues, so setting them to nil is fine
// setting them to nil rather than LNil lets us invoke the golang memclr opto
if rg.top < oldtop {
nilRange := rg.array[rg.top:oldtop]
if rg.top < oldtopi {
nilRange := rg.array[rg.top:oldtopi]
for i := range nilRange {
nilRange[i] = nil
}
@ -426,7 +428,7 @@ func (rg *registry) SetTop(top int) {
//for i := rg.top; i < oldtop; i++ {
// rg.array[i] = LNil
//}
}
} // +inline-end
func (rg *registry) Top() int {
return rg.top
@ -529,19 +531,36 @@ func (rg *registry) FillNil(regm, n int) { // +inline-start
func (rg *registry) Insert(value LValue, reg int) {
top := rg.Top()
if reg >= top {
rg.Set(reg, value)
// this section is inlined by go-inline
// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
{
regi := reg
vali := value
newSize := regi + 1
// this section is inlined by go-inline
// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
{
requiredSize := newSize
if requiredSize > cap(rg.array) {
rg.resize(requiredSize)
}
}
rg.array[regi] = vali
if regi >= rg.top {
rg.top = regi + 1
}
}
return
}
top--
for ; top >= reg; top-- {
// FIXME consider using copy() here if Insert() is called enough
rg.Set(top+1, rg.Get(top))
}
rg.Set(reg, value)
}
func (rg *registry) Set(reg int, val LValue) {
newSize := reg + 1
// this section is inlined by go-inline
// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
{
regi := top + 1
vali := rg.Get(top)
newSize := regi + 1
// this section is inlined by go-inline
// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
{
@ -550,14 +569,18 @@ func (rg *registry) Set(reg int, val LValue) {
rg.resize(requiredSize)
}
}
rg.array[reg] = val
if reg >= rg.top {
rg.top = reg + 1
rg.array[regi] = vali
if regi >= rg.top {
rg.top = regi + 1
}
}
func (rg *registry) SetNumber(reg int, val LNumber) {
newSize := reg + 1
}
}
// this section is inlined by go-inline
// source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go'
{
regi := reg
vali := value
newSize := regi + 1
// this section is inlined by go-inline
// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
{
@ -566,12 +589,45 @@ func (rg *registry) SetNumber(reg int, val LNumber) {
rg.resize(requiredSize)
}
}
rg.array[reg] = rg.alloc.LNumber2I(val)
if reg >= rg.top {
rg.top = reg + 1
rg.array[regi] = vali
if regi >= rg.top {
rg.top = regi + 1
}
}
}
func (rg *registry) Set(regi int, vali LValue) { // +inline-start
newSize := regi + 1
// this section is inlined by go-inline
// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
{
requiredSize := newSize
if requiredSize > cap(rg.array) {
rg.resize(requiredSize)
}
}
rg.array[regi] = vali
if regi >= rg.top {
rg.top = regi + 1
}
} // +inline-end
func (rg *registry) SetNumber(regi int, vali LNumber) { // +inline-start
newSize := regi + 1
// this section is inlined by go-inline
// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
{
requiredSize := newSize
if requiredSize > cap(rg.array) {
rg.resize(requiredSize)
}
}
rg.array[regi] = rg.alloc.LNumber2I(vali)
if regi >= rg.top {
rg.top = regi + 1
}
} // +inline-end
func (rg *registry) IsFull() bool {
return rg.top >= cap(rg.array)
}
@ -814,6 +870,9 @@ func (ls *LState) isStarted() bool {
func (ls *LState) kill() {
ls.Dead = true
if ls.ctxCancelFn != nil {
ls.ctxCancelFn()
}
}
func (ls *LState) indexToReg(idx int) int {
@ -981,6 +1040,8 @@ func (ls *LState) initCallFrame(cf *callFrame) { // +inline-start
proto := cf.Fn.Proto
nargs := cf.NArgs
np := int(proto.NumParameters)
if nargs < np {
// default any missing arguments to nil
newSize := cf.LocalBase + np
// this section is inlined by go-inline
// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
@ -993,14 +1054,16 @@ func (ls *LState) initCallFrame(cf *callFrame) { // +inline-start
}
for i := nargs; i < np; i++ {
ls.reg.array[cf.LocalBase+i] = LNil
}
nargs = np
ls.reg.top = newSize
}
if (proto.IsVarArg & VarArgIsVarArg) == 0 {
if nargs < int(proto.NumUsedRegisters) {
nargs = int(proto.NumUsedRegisters)
}
newSize = cf.LocalBase + nargs
newSize := cf.LocalBase + nargs
// this section is inlined by go-inline
// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
{
@ -1089,6 +1152,8 @@ func (ls *LState) pushCallFrame(cf callFrame, fn LValue, meta bool) { // +inline
proto := cf.Fn.Proto
nargs := cf.NArgs
np := int(proto.NumParameters)
if nargs < np {
// default any missing arguments to nil
newSize := cf.LocalBase + np
// this section is inlined by go-inline
// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
@ -1101,14 +1166,16 @@ func (ls *LState) pushCallFrame(cf callFrame, fn LValue, meta bool) { // +inline
}
for i := nargs; i < np; i++ {
ls.reg.array[cf.LocalBase+i] = LNil
}
nargs = np
ls.reg.top = newSize
}
if (proto.IsVarArg & VarArgIsVarArg) == 0 {
if nargs < int(proto.NumUsedRegisters) {
nargs = int(proto.NumUsedRegisters)
}
newSize = cf.LocalBase + nargs
newSize := cf.LocalBase + nargs
// this section is inlined by go-inline
// source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go'
{
@ -1367,6 +1434,10 @@ func NewState(opts ...Options) *LState {
return ls
}
func (ls *LState) IsClosed() bool {
return ls.stack == nil
}
func (ls *LState) Close() {
atomic.AddInt32(&ls.stop, 1)
for _, file := range ls.G.tempFiles {
@ -1548,6 +1619,7 @@ func (ls *LState) NewThread() (*LState, context.CancelFunc) {
if ls.ctx != nil {
thread.mainLoop = mainLoopWithContext
thread.ctx, f = context.WithCancel(ls.ctx)
thread.ctxCancelFn = f
}
return thread, f
}
@ -1997,6 +2069,9 @@ func (ls *LState) PCall(nargs, nret int, errfunc *LFunction) (err error) {
err = rcv.(*ApiError)
err.(*ApiError).StackTrace = ls.stackTrace(0)
}
ls.stack.SetSp(sp)
ls.currentFrame = ls.stack.Last()
ls.reg.SetTop(base)
}
}()
ls.Call(1, 1)
@ -2171,7 +2246,7 @@ func (ls *LState) SetMx(mx int) {
go func() {
limit := uint64(mx * 1024 * 1024) //MB
var s runtime.MemStats
for ls.stop == 0 {
for atomic.LoadInt32(&ls.stop) == 0 {
runtime.ReadMemStats(&s)
if s.Alloc >= limit {
fmt.Println("out of memory")

View file

@ -46,7 +46,7 @@ func newLTable(acap int, hcap int) *LTable {
return tb
}
// Len returns length of this LTable.
// Len returns length of this LTable without using __len.
func (tb *LTable) Len() int {
if tb.array == nil {
return 0

View file

@ -32,7 +32,7 @@ func defaultFormat(v interface{}, f fmt.State, c rune) {
buf = append(buf, "%")
for i := 0; i < 128; i++ {
if f.Flag(i) {
buf = append(buf, string(i))
buf = append(buf, string(rune(i)))
}
}

View file

@ -29,12 +29,6 @@ func (vt LValueType) String() string {
type LValue interface {
String() string
Type() LValueType
// to reduce `runtime.assertI2T2` costs, this method should be used instead of the type assertion in heavy paths(typically inside the VM).
assertFloat64() (float64, bool)
// to reduce `runtime.assertI2T2` costs, this method should be used instead of the type assertion in heavy paths(typically inside the VM).
assertString() (string, bool)
// to reduce `runtime.assertI2T2` costs, this method should be used instead of the type assertion in heavy paths(typically inside the VM).
assertFunction() (*LFunction, bool)
}
// LVIsFalse returns true if a given LValue is a nil or false otherwise false.
@ -82,9 +76,6 @@ type LNilType struct{}
func (nl *LNilType) String() string { return "nil" }
func (nl *LNilType) Type() LValueType { return LTNil }
func (nl *LNilType) assertFloat64() (float64, bool) { return 0, false }
func (nl *LNilType) assertString() (string, bool) { return "", false }
func (nl *LNilType) assertFunction() (*LFunction, bool) { return nil, false }
var LNil = LValue(&LNilType{})
@ -97,9 +88,6 @@ func (bl LBool) String() string {
return "false"
}
func (bl LBool) Type() LValueType { return LTBool }
func (bl LBool) assertFloat64() (float64, bool) { return 0, false }
func (bl LBool) assertString() (string, bool) { return "", false }
func (bl LBool) assertFunction() (*LFunction, bool) { return nil, false }
var LTrue = LBool(true)
var LFalse = LBool(false)
@ -108,9 +96,6 @@ type LString string
func (st LString) String() string { return string(st) }
func (st LString) Type() LValueType { return LTString }
func (st LString) assertFloat64() (float64, bool) { return 0, false }
func (st LString) assertString() (string, bool) { return string(st), true }
func (st LString) assertFunction() (*LFunction, bool) { return nil, false }
// fmt.Formatter interface
func (st LString) Format(f fmt.State, c rune) {
@ -134,9 +119,6 @@ func (nm LNumber) String() string {
}
func (nm LNumber) Type() LValueType { return LTNumber }
func (nm LNumber) assertFloat64() (float64, bool) { return float64(nm), true }
func (nm LNumber) assertString() (string, bool) { return "", false }
func (nm LNumber) assertFunction() (*LFunction, bool) { return nil, false }
// fmt.Formatter interface
func (nm LNumber) Format(f fmt.State, c rune) {
@ -170,9 +152,6 @@ type LTable struct {
func (tb *LTable) String() string { return fmt.Sprintf("table: %p", tb) }
func (tb *LTable) Type() LValueType { return LTTable }
func (tb *LTable) assertFloat64() (float64, bool) { return 0, false }
func (tb *LTable) assertString() (string, bool) { return "", false }
func (tb *LTable) assertFunction() (*LFunction, bool) { return nil, false }
type LFunction struct {
IsG bool
@ -185,9 +164,6 @@ type LGFunction func(*LState) int
func (fn *LFunction) String() string { return fmt.Sprintf("function: %p", fn) }
func (fn *LFunction) Type() LValueType { return LTFunction }
func (fn *LFunction) assertFloat64() (float64, bool) { return 0, false }
func (fn *LFunction) assertString() (string, bool) { return "", false }
func (fn *LFunction) assertFunction() (*LFunction, bool) { return fn, true }
type Global struct {
MainThread *LState
@ -218,13 +194,11 @@ type LState struct {
hasErrorFunc bool
mainLoop func(*LState, *callFrame)
ctx context.Context
ctxCancelFn context.CancelFunc
}
func (ls *LState) String() string { return fmt.Sprintf("thread: %p", ls) }
func (ls *LState) Type() LValueType { return LTThread }
func (ls *LState) assertFloat64() (float64, bool) { return 0, false }
func (ls *LState) assertString() (string, bool) { return "", false }
func (ls *LState) assertFunction() (*LFunction, bool) { return nil, false }
type LUserData struct {
Value interface{}
@ -234,14 +208,8 @@ type LUserData struct {
func (ud *LUserData) String() string { return fmt.Sprintf("userdata: %p", ud) }
func (ud *LUserData) Type() LValueType { return LTUserData }
func (ud *LUserData) assertFloat64() (float64, bool) { return 0, false }
func (ud *LUserData) assertString() (string, bool) { return "", false }
func (ud *LUserData) assertFunction() (*LFunction, bool) { return nil, false }
type LChannel chan LValue
func (ch LChannel) String() string { return fmt.Sprintf("channel: %p", ch) }
func (ch LChannel) Type() LValueType { return LTChannel }
func (ch LChannel) assertFloat64() (float64, bool) { return 0, false }
func (ch LChannel) assertString() (string, bool) { return "", false }
func (ch LChannel) assertFunction() (*LFunction, bool) { return nil, false }

File diff suppressed because it is too large Load diff

4
vendor/modules.txt vendored
View file

@ -181,8 +181,8 @@ github.com/redis/go-redis/v9/internal/rand
github.com/redis/go-redis/v9/internal/util
# github.com/stretchr/testify v1.9.0
## explicit; go 1.17
# github.com/yuin/gopher-lua v0.0.0-20200603152657-dc2b0ca8b37e
## explicit
# github.com/yuin/gopher-lua v1.1.1
## explicit; go 1.17
github.com/yuin/gopher-lua
github.com/yuin/gopher-lua/ast
github.com/yuin/gopher-lua/parse