123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926 |
- package lua
- ////////////////////////////////////////////////////////
- // This file was generated by go-inline. DO NOT EDIT. //
- ////////////////////////////////////////////////////////
- import (
- "bufio"
- "fmt"
- "github.com/vmihailenco/msgpack"
- "github.com/yuin/gopher-lua/parse"
- "golang.org/x/net/context"
- "io"
- "io/ioutil"
- "math"
- "os"
- "runtime"
- "strings"
- "sync/atomic"
- "time"
- )
- const MultRet = -1
- const RegistryIndex = -10000
- const EnvironIndex = -10001
- const GlobalsIndex = -10002
- /* ApiError {{{ */
- type ApiError struct {
- Type ApiErrorType
- Object LValue
- StackTrace string
- // Underlying error. This attribute is set only if the Type is ApiErrorFile or ApiErrorSyntax
- Cause error
- }
- func newApiError(code ApiErrorType, object LValue) *ApiError {
- return &ApiError{code, object, "", nil}
- }
- func newApiErrorS(code ApiErrorType, message string) *ApiError {
- return newApiError(code, LString(message))
- }
- func newApiErrorE(code ApiErrorType, err error) *ApiError {
- return &ApiError{code, LString(err.Error()), "", err}
- }
- func (e *ApiError) Error() string {
- if len(e.StackTrace) > 0 {
- return fmt.Sprintf("%s\n%s", e.Object.String(), e.StackTrace)
- }
- return e.Object.String()
- }
- type ApiErrorType int
- const (
- ApiErrorSyntax ApiErrorType = iota
- ApiErrorFile
- ApiErrorRun
- ApiErrorError
- ApiErrorPanic
- )
- /* }}} */
- /* ResumeState {{{ */
- type ResumeState int
- const (
- ResumeOK ResumeState = iota
- ResumeYield
- ResumeError
- )
- /* }}} */
- /* P {{{ */
- type P struct {
- Fn LValue
- NRet int
- Protect bool
- Handler *LFunction
- }
- /* }}} */
- /* Options {{{ */
- // Options is a configuration that is used to create a new LState.
- type Options struct {
- // Call stack size. This defaults to `lua.CallStackSize`.
- CallStackSize int
- // Data stack size. This defaults to `lua.RegistrySize`.
- RegistrySize int
- // Controls whether or not libraries are opened by default
- SkipOpenLibs bool
- // Tells whether a Go stacktrace should be included in a Lua stacktrace when panics occur.
- IncludeGoStackTrace bool
- }
- /* }}} */
- /* Debug {{{ */
- type Debug struct {
- frame *callFrame
- Name string
- What string
- Source string
- CurrentLine int
- NUpvalues int
- LineDefined int
- LastLineDefined int
- }
- /* }}} */
- /* callFrame {{{ */
- type callFrame struct {
- Idx int
- Fn *LFunction
- Parent *callFrame
- Pc int
- Base int
- LocalBase int
- ReturnBase int
- NArgs int
- NRet int
- TailCall int
- }
- type callFrameStack struct {
- array []callFrame
- sp int
- }
- func newCallFrameStack(size int) *callFrameStack {
- return &callFrameStack{
- array: make([]callFrame, size),
- sp: 0,
- }
- }
- func (cs *callFrameStack) IsEmpty() bool { return cs.sp == 0 }
- func (cs *callFrameStack) Clear() {
- cs.sp = 0
- }
- func (cs *callFrameStack) Push(v callFrame) { // +inline-start
- cs.array[cs.sp] = v
- cs.array[cs.sp].Idx = cs.sp
- cs.sp++
- } // +inline-end
- func (cs *callFrameStack) Remove(sp int) {
- psp := sp - 1
- nsp := sp + 1
- var pre *callFrame
- var next *callFrame
- if psp > 0 {
- pre = &cs.array[psp]
- }
- if nsp < cs.sp {
- next = &cs.array[nsp]
- }
- if next != nil {
- next.Parent = pre
- }
- for i := sp; i+1 < cs.sp; i++ {
- cs.array[i] = cs.array[i+1]
- cs.array[i].Idx = i
- cs.sp = i
- }
- cs.sp++
- }
- func (cs *callFrameStack) Sp() int {
- return cs.sp
- }
- func (cs *callFrameStack) SetSp(sp int) {
- cs.sp = sp
- }
- func (cs *callFrameStack) Last() *callFrame {
- if cs.sp == 0 {
- return nil
- }
- return &cs.array[cs.sp-1]
- }
- func (cs *callFrameStack) At(sp int) *callFrame {
- return &cs.array[sp]
- }
- func (cs *callFrameStack) Pop() *callFrame {
- cs.sp--
- return &cs.array[cs.sp]
- }
- /* }}} */
- /* registry {{{ */
- type registry struct {
- array []LValue
- top int
- alloc *allocator
- }
- func newRegistry(size int, alloc *allocator) *registry {
- return ®istry{make([]LValue, size), 0, alloc}
- }
- func (rg *registry) SetTop(top int) {
- oldtop := rg.top
- rg.top = top
- for i := oldtop; i < rg.top; i++ {
- rg.array[i] = LNil
- }
- for i := rg.top; i < oldtop; i++ {
- rg.array[i] = LNil
- }
- }
- func (rg *registry) Top() int {
- return rg.top
- }
- func (rg *registry) Push(v LValue) {
- rg.array[rg.top] = v
- rg.top++
- }
- func (rg *registry) Pop() LValue {
- v := rg.array[rg.top-1]
- rg.array[rg.top-1] = LNil
- rg.top--
- return v
- }
- func (rg *registry) Get(reg int) LValue {
- return rg.array[reg]
- }
- func (rg *registry) CopyRange(regv, start, limit, n int) { // +inline-start
- for i := 0; i < n; i++ {
- if tidx := start + i; tidx >= rg.top || limit > -1 && tidx >= limit || tidx < 0 {
- rg.array[regv+i] = LNil
- } else {
- rg.array[regv+i] = rg.array[tidx]
- }
- }
- rg.top = regv + n
- } // +inline-end
- func (rg *registry) FillNil(regm, n int) { // +inline-start
- for i := 0; i < n; i++ {
- rg.array[regm+i] = LNil
- }
- rg.top = regm + n
- } // +inline-end
- func (rg *registry) Insert(value LValue, reg int) {
- top := rg.Top()
- if reg >= top {
- rg.Set(reg, value)
- return
- }
- top--
- for ; top >= reg; top-- {
- rg.Set(top+1, rg.Get(top))
- }
- rg.Set(reg, value)
- }
- func (rg *registry) Set(reg int, val LValue) {
- rg.array[reg] = val
- if reg >= rg.top {
- rg.top = reg + 1
- }
- }
- func (rg *registry) SetNumber(reg int, val LNumber) {
- rg.array[reg] = rg.alloc.LNumber2I(val)
- if reg >= rg.top {
- rg.top = reg + 1
- }
- } /* }}} */
- /* Global {{{ */
- func newGlobal() *Global {
- return &Global{
- MainThread: nil,
- Registry: newLTable(0, 32),
- Global: newLTable(0, 64),
- builtinMts: make(map[int]LValue),
- tempFiles: make([]*os.File, 0, 10),
- }
- }
- /* }}} */
- /* package local methods {{{ */
- func panicWithTraceback(L *LState) {
- err := newApiError(ApiErrorRun, L.Get(-1))
- err.StackTrace = L.stackTrace(0)
- panic(err)
- }
- func panicWithoutTraceback(L *LState) {
- err := newApiError(ApiErrorRun, L.Get(-1))
- panic(err)
- }
- func newLState(options Options) *LState {
- al := newAllocator(32)
- ls := &LState{
- G: newGlobal(),
- Parent: nil,
- Panic: panicWithTraceback,
- Dead: false,
- Options: options,
- stop: 0,
- reg: newRegistry(options.RegistrySize, al),
- stack: newCallFrameStack(options.CallStackSize),
- alloc: al,
- currentFrame: nil,
- wrapped: false,
- uvcache: nil,
- hasErrorFunc: false,
- mainLoop: mainLoop,
- ctx: nil,
- }
- ls.Env = ls.G.Global
- return ls
- }
- func (ls *LState) printReg() {
- println("-------------------------")
- println("thread:", ls)
- println("top:", ls.reg.Top())
- if ls.currentFrame != nil {
- println("function base:", ls.currentFrame.Base)
- println("return base:", ls.currentFrame.ReturnBase)
- } else {
- println("(vm not started)")
- }
- println("local base:", ls.currentLocalBase())
- for i := 0; i < ls.reg.Top(); i++ {
- println(i, ls.reg.Get(i).String())
- }
- println("-------------------------")
- }
- func (ls *LState) printCallStack() {
- println("-------------------------")
- for i := 0; i < ls.stack.Sp(); i++ {
- print(i)
- print(" ")
- frame := ls.stack.At(i)
- if frame == nil {
- break
- }
- if frame.Fn.IsG {
- println("IsG:", true, "Frame:", frame, "Fn:", frame.Fn)
- } else {
- println("IsG:", false, "Frame:", frame, "Fn:", frame.Fn, "pc:", frame.Pc)
- }
- }
- println("-------------------------")
- }
- func (ls *LState) closeAllUpvalues() { // +inline-start
- for cf := ls.currentFrame; cf != nil; cf = cf.Parent {
- if !cf.Fn.IsG {
- ls.closeUpvalues(cf.LocalBase)
- }
- }
- } // +inline-end
- func (ls *LState) raiseError(level int, format string, args ...interface{}) {
- if !ls.hasErrorFunc {
- ls.closeAllUpvalues()
- }
- message := format
- if len(args) > 0 {
- message = fmt.Sprintf(format, args...)
- }
- if level > 0 {
- message = fmt.Sprintf("%v %v", ls.where(level-1, true), message)
- }
- ls.reg.Push(LString(message))
- ls.Panic(ls)
- }
- func (ls *LState) findLocal(frame *callFrame, no int) string {
- fn := frame.Fn
- if !fn.IsG {
- if name, ok := fn.LocalName(no, frame.Pc-1); ok {
- return name
- }
- }
- var top int
- if ls.currentFrame == frame {
- top = ls.reg.Top()
- } else if frame.Idx+1 < ls.stack.Sp() {
- top = ls.stack.At(frame.Idx + 1).Base
- } else {
- return ""
- }
- if top-frame.LocalBase >= no {
- return "(*temporary)"
- }
- return ""
- }
- func (ls *LState) where(level int, skipg bool) string {
- dbg, ok := ls.GetStack(level)
- if !ok {
- return ""
- }
- cf := dbg.frame
- proto := cf.Fn.Proto
- sourcename := "[G]"
- if proto != nil {
- sourcename = proto.SourceName
- } else if skipg {
- return ls.where(level+1, skipg)
- }
- line := ""
- if proto != nil {
- line = fmt.Sprintf("%v:", proto.DbgSourcePositions[cf.Pc-1])
- }
- return fmt.Sprintf("%v:%v", sourcename, line)
- }
- func (ls *LState) stackTrace(level int) string {
- buf := []string{}
- header := "stack traceback:"
- if ls.currentFrame != nil {
- i := 0
- for dbg, ok := ls.GetStack(i); ok; dbg, ok = ls.GetStack(i) {
- cf := dbg.frame
- buf = append(buf, fmt.Sprintf("\t%v in %v", ls.Where(i), ls.formattedFrameFuncName(cf)))
- if !cf.Fn.IsG && cf.TailCall > 0 {
- for tc := cf.TailCall; tc > 0; tc-- {
- buf = append(buf, "\t(tailcall): ?")
- i++
- }
- }
- i++
- }
- }
- buf = append(buf, fmt.Sprintf("\t%v: %v", "[G]", "?"))
- buf = buf[intMax(0, intMin(level, len(buf))):len(buf)]
- if len(buf) > 20 {
- newbuf := make([]string, 0, 20)
- newbuf = append(newbuf, buf[0:7]...)
- newbuf = append(newbuf, "\t...")
- newbuf = append(newbuf, buf[len(buf)-7:len(buf)]...)
- buf = newbuf
- }
- return fmt.Sprintf("%s\n%s", header, strings.Join(buf, "\n"))
- }
- func (ls *LState) formattedFrameFuncName(fr *callFrame) string {
- name, ischunk := ls.frameFuncName(fr)
- if ischunk {
- return name
- }
- if name[0] != '(' && name[0] != '<' {
- return fmt.Sprintf("function '%s'", name)
- }
- return fmt.Sprintf("function %s", name)
- }
- func (ls *LState) rawFrameFuncName(fr *callFrame) string {
- name, _ := ls.frameFuncName(fr)
- return name
- }
- func (ls *LState) frameFuncName(fr *callFrame) (string, bool) {
- frame := fr.Parent
- if frame == nil {
- if ls.Parent == nil {
- return "main chunk", true
- } else {
- return "corountine", true
- }
- }
- if !frame.Fn.IsG {
- pc := frame.Pc - 1
- for _, call := range frame.Fn.Proto.DbgCalls {
- if call.Pc == pc {
- name := call.Name
- if (name == "?" || fr.TailCall > 0) && !fr.Fn.IsG {
- name = fmt.Sprintf("<%v:%v>", fr.Fn.Proto.SourceName, fr.Fn.Proto.LineDefined)
- }
- return name, false
- }
- }
- }
- if !fr.Fn.IsG {
- return fmt.Sprintf("<%v:%v>", fr.Fn.Proto.SourceName, fr.Fn.Proto.LineDefined), false
- }
- return "(anonymous)", false
- }
- func (ls *LState) isStarted() bool {
- return ls.currentFrame != nil
- }
- func (ls *LState) kill() {
- ls.Dead = true
- }
- func (ls *LState) indexToReg(idx int) int {
- base := ls.currentLocalBase()
- if idx > 0 {
- return base + idx - 1
- } else if idx == 0 {
- return -1
- } else {
- tidx := ls.reg.Top() + idx
- if tidx < base {
- return -1
- }
- return tidx
- }
- }
- func (ls *LState) currentLocalBase() int {
- base := 0
- if ls.currentFrame != nil {
- base = ls.currentFrame.LocalBase
- }
- return base
- }
- func (ls *LState) currentEnv() *LTable {
- return ls.Env
- /*
- if ls.currentFrame == nil {
- return ls.Env
- }
- return ls.currentFrame.Fn.Env
- */
- }
- func (ls *LState) rkValue(idx int) LValue {
- /*
- if OpIsK(idx) {
- return ls.currentFrame.Fn.Proto.Constants[opIndexK(idx)]
- }
- return ls.reg.Get(ls.currentFrame.LocalBase + idx)
- */
- if (idx & opBitRk) != 0 {
- return ls.currentFrame.Fn.Proto.Constants[idx & ^opBitRk]
- }
- return ls.reg.array[ls.currentFrame.LocalBase+idx]
- }
- func (ls *LState) rkString(idx int) string {
- if (idx & opBitRk) != 0 {
- return ls.currentFrame.Fn.Proto.stringConstants[idx & ^opBitRk]
- }
- return string(ls.reg.array[ls.currentFrame.LocalBase+idx].(LString))
- }
- func (ls *LState) closeUpvalues(idx int) { // +inline-start
- if ls.uvcache != nil {
- var prev *Upvalue
- for uv := ls.uvcache; uv != nil; uv = uv.next {
- if uv.index >= idx {
- if prev != nil {
- prev.next = nil
- } else {
- ls.uvcache = nil
- }
- uv.Close()
- }
- prev = uv
- }
- }
- } // +inline-end
- func (ls *LState) findUpvalue(idx int) *Upvalue {
- var prev *Upvalue
- var next *Upvalue
- if ls.uvcache != nil {
- for uv := ls.uvcache; uv != nil; uv = uv.next {
- if uv.index == idx {
- return uv
- }
- if uv.index > idx {
- next = uv
- break
- }
- prev = uv
- }
- }
- uv := &Upvalue{reg: ls.reg, index: idx, closed: false}
- if prev != nil {
- prev.next = uv
- } else {
- ls.uvcache = uv
- }
- if next != nil {
- uv.next = next
- }
- return uv
- }
- func (ls *LState) metatable(lvalue LValue, rawget bool) LValue {
- var metatable LValue = LNil
- switch obj := lvalue.(type) {
- case *LTable:
- metatable = obj.Metatable
- case *LUserData:
- metatable = obj.Metatable
- default:
- if table, ok := ls.G.builtinMts[int(obj.Type())]; ok {
- metatable = table
- }
- }
- if !rawget && metatable != LNil {
- oldmt := metatable
- if tb, ok := metatable.(*LTable); ok {
- metatable = tb.RawGetString("__metatable")
- if metatable == LNil {
- metatable = oldmt
- }
- }
- }
- return metatable
- }
- func (ls *LState) metaOp1(lvalue LValue, event string) LValue {
- if mt := ls.metatable(lvalue, true); mt != LNil {
- if tb, ok := mt.(*LTable); ok {
- return tb.RawGetString(event)
- }
- }
- return LNil
- }
- func (ls *LState) metaOp2(value1, value2 LValue, event string) LValue {
- if mt := ls.metatable(value1, true); mt != LNil {
- if tb, ok := mt.(*LTable); ok {
- if ret := tb.RawGetString(event); ret != LNil {
- return ret
- }
- }
- }
- if mt := ls.metatable(value2, true); mt != LNil {
- if tb, ok := mt.(*LTable); ok {
- return tb.RawGetString(event)
- }
- }
- return LNil
- }
- func (ls *LState) metaCall(lvalue LValue) (*LFunction, bool) {
- if fn, ok := lvalue.(*LFunction); ok {
- return fn, false
- }
- if fn, ok := ls.metaOp1(lvalue, "__call").(*LFunction); ok {
- return fn, true
- }
- return nil, false
- }
- func (ls *LState) initCallFrame(cf *callFrame) { // +inline-start
- if cf.Fn.IsG {
- ls.reg.SetTop(cf.LocalBase + cf.NArgs)
- } else {
- proto := cf.Fn.Proto
- nargs := cf.NArgs
- np := int(proto.NumParameters)
- for i := nargs; i < np; i++ {
- ls.reg.array[cf.LocalBase+i] = LNil
- nargs = np
- }
- if (proto.IsVarArg & VarArgIsVarArg) == 0 {
- if nargs < int(proto.NumUsedRegisters) {
- nargs = int(proto.NumUsedRegisters)
- }
- for i := np; i < nargs; i++ {
- ls.reg.array[cf.LocalBase+i] = LNil
- }
- ls.reg.top = cf.LocalBase + int(proto.NumUsedRegisters)
- } else {
- /* swap vararg positions:
- closure
- namedparam1 <- lbase
- namedparam2
- vararg1
- vararg2
- TO
- closure
- nil
- nil
- vararg1
- vararg2
- namedparam1 <- lbase
- namedparam2
- */
- nvarargs := nargs - np
- if nvarargs < 0 {
- nvarargs = 0
- }
- ls.reg.SetTop(cf.LocalBase + nargs + np)
- for i := 0; i < np; i++ {
- //ls.reg.Set(cf.LocalBase+nargs+i, ls.reg.Get(cf.LocalBase+i))
- ls.reg.array[cf.LocalBase+nargs+i] = ls.reg.array[cf.LocalBase+i]
- //ls.reg.Set(cf.LocalBase+i, LNil)
- ls.reg.array[cf.LocalBase+i] = LNil
- }
- if CompatVarArg {
- ls.reg.SetTop(cf.LocalBase + nargs + np + 1)
- if (proto.IsVarArg & VarArgNeedsArg) != 0 {
- argtb := newLTable(nvarargs, 0)
- for i := 0; i < nvarargs; i++ {
- argtb.RawSetInt(i+1, ls.reg.Get(cf.LocalBase+np+i))
- }
- argtb.RawSetString("n", LNumber(nvarargs))
- //ls.reg.Set(cf.LocalBase+nargs+np, argtb)
- ls.reg.array[cf.LocalBase+nargs+np] = argtb
- } else {
- ls.reg.array[cf.LocalBase+nargs+np] = LNil
- }
- }
- cf.LocalBase += nargs
- maxreg := cf.LocalBase + int(proto.NumUsedRegisters)
- ls.reg.SetTop(maxreg)
- }
- }
- } // +inline-end
- func (ls *LState) pushCallFrame(cf callFrame, fn LValue, meta bool) { // +inline-start
- if meta {
- cf.NArgs++
- ls.reg.Insert(fn, cf.LocalBase)
- }
- if cf.Fn == nil {
- ls.RaiseError("attempt to call a non-function object")
- }
- if ls.stack.sp == ls.Options.CallStackSize {
- ls.RaiseError("stack overflow")
- }
- // this section is inlined by go-inline
- // source function is 'func (cs *callFrameStack) Push(v callFrame) ' in '_state.go'
- {
- cs := ls.stack
- v := cf
- cs.array[cs.sp] = v
- cs.array[cs.sp].Idx = cs.sp
- cs.sp++
- }
- newcf := ls.stack.Last()
- // this section is inlined by go-inline
- // source function is 'func (ls *LState) initCallFrame(cf *callFrame) ' in '_state.go'
- {
- cf := newcf
- if cf.Fn.IsG {
- ls.reg.SetTop(cf.LocalBase + cf.NArgs)
- } else {
- proto := cf.Fn.Proto
- nargs := cf.NArgs
- np := int(proto.NumParameters)
- for i := nargs; i < np; i++ {
- ls.reg.array[cf.LocalBase+i] = LNil
- nargs = np
- }
- if (proto.IsVarArg & VarArgIsVarArg) == 0 {
- if nargs < int(proto.NumUsedRegisters) {
- nargs = int(proto.NumUsedRegisters)
- }
- for i := np; i < nargs; i++ {
- ls.reg.array[cf.LocalBase+i] = LNil
- }
- ls.reg.top = cf.LocalBase + int(proto.NumUsedRegisters)
- } else {
- /* swap vararg positions:
- closure
- namedparam1 <- lbase
- namedparam2
- vararg1
- vararg2
- TO
- closure
- nil
- nil
- vararg1
- vararg2
- namedparam1 <- lbase
- namedparam2
- */
- nvarargs := nargs - np
- if nvarargs < 0 {
- nvarargs = 0
- }
- ls.reg.SetTop(cf.LocalBase + nargs + np)
- for i := 0; i < np; i++ {
- //ls.reg.Set(cf.LocalBase+nargs+i, ls.reg.Get(cf.LocalBase+i))
- ls.reg.array[cf.LocalBase+nargs+i] = ls.reg.array[cf.LocalBase+i]
- //ls.reg.Set(cf.LocalBase+i, LNil)
- ls.reg.array[cf.LocalBase+i] = LNil
- }
- if CompatVarArg {
- ls.reg.SetTop(cf.LocalBase + nargs + np + 1)
- if (proto.IsVarArg & VarArgNeedsArg) != 0 {
- argtb := newLTable(nvarargs, 0)
- for i := 0; i < nvarargs; i++ {
- argtb.RawSetInt(i+1, ls.reg.Get(cf.LocalBase+np+i))
- }
- argtb.RawSetString("n", LNumber(nvarargs))
- //ls.reg.Set(cf.LocalBase+nargs+np, argtb)
- ls.reg.array[cf.LocalBase+nargs+np] = argtb
- } else {
- ls.reg.array[cf.LocalBase+nargs+np] = LNil
- }
- }
- cf.LocalBase += nargs
- maxreg := cf.LocalBase + int(proto.NumUsedRegisters)
- ls.reg.SetTop(maxreg)
- }
- }
- }
- ls.currentFrame = newcf
- } // +inline-end
- func (ls *LState) callR(nargs, nret, rbase int) {
- base := ls.reg.Top() - nargs - 1
- if rbase < 0 {
- rbase = base
- }
- lv := ls.reg.Get(base)
- fn, meta := ls.metaCall(lv)
- ls.pushCallFrame(callFrame{
- Fn: fn,
- Pc: 0,
- Base: base,
- LocalBase: base + 1,
- ReturnBase: rbase,
- NArgs: nargs,
- NRet: nret,
- Parent: ls.currentFrame,
- TailCall: 0,
- }, lv, meta)
- if ls.G.MainThread == nil {
- ls.G.MainThread = ls
- ls.G.CurrentThread = ls
- ls.mainLoop(ls, nil)
- } else {
- ls.mainLoop(ls, ls.currentFrame)
- }
- if nret != MultRet {
- ls.reg.SetTop(rbase + nret)
- }
- }
- func (ls *LState) getField(obj LValue, key LValue) LValue {
- curobj := obj
- for i := 0; i < MaxTableGetLoop; i++ {
- tb, istable := curobj.(*LTable)
- if istable {
- ret := tb.RawGet(key)
- if ret != LNil {
- return ret
- }
- }
- metaindex := ls.metaOp1(curobj, "__index")
- if metaindex == LNil {
- if !istable {
- ls.RaiseError("attempt to index a non-table object(%v)", curobj.Type().String())
- }
- return LNil
- }
- if metaindex.Type() == LTFunction {
- ls.reg.Push(metaindex)
- ls.reg.Push(curobj)
- ls.reg.Push(key)
- ls.Call(2, 1)
- return ls.reg.Pop()
- } else {
- curobj = metaindex
- }
- }
- ls.RaiseError("too many recursions in gettable")
- return nil
- }
- func (ls *LState) getFieldString(obj LValue, key string) LValue {
- curobj := obj
- for i := 0; i < MaxTableGetLoop; i++ {
- tb, istable := curobj.(*LTable)
- if istable {
- ret := tb.RawGetString(key)
- if ret != LNil {
- return ret
- }
- }
- metaindex := ls.metaOp1(curobj, "__index")
- if metaindex == LNil {
- if !istable {
- ls.RaiseError("attempt to index a non-table object(%v)", curobj.Type().String())
- }
- return LNil
- }
- if metaindex.Type() == LTFunction {
- ls.reg.Push(metaindex)
- ls.reg.Push(curobj)
- ls.reg.Push(LString(key))
- ls.Call(2, 1)
- return ls.reg.Pop()
- } else {
- curobj = metaindex
- }
- }
- ls.RaiseError("too many recursions in gettable")
- return nil
- }
- func (ls *LState) setField(obj LValue, key LValue, value LValue) {
- curobj := obj
- for i := 0; i < MaxTableGetLoop; i++ {
- tb, istable := curobj.(*LTable)
- if istable {
- if tb.RawGet(key) != LNil {
- ls.RawSet(tb, key, value)
- return
- }
- }
- metaindex := ls.metaOp1(curobj, "__newindex")
- if metaindex == LNil {
- if !istable {
- ls.RaiseError("attempt to index a non-table object(%v)", curobj.Type().String())
- }
- ls.RawSet(tb, key, value)
- return
- }
- if metaindex.Type() == LTFunction {
- ls.reg.Push(metaindex)
- ls.reg.Push(curobj)
- ls.reg.Push(key)
- ls.reg.Push(value)
- ls.Call(3, 0)
- return
- } else {
- curobj = metaindex
- }
- }
- ls.RaiseError("too many recursions in settable")
- }
- func (ls *LState) setFieldString(obj LValue, key string, value LValue) {
- curobj := obj
- for i := 0; i < MaxTableGetLoop; i++ {
- tb, istable := curobj.(*LTable)
- if istable {
- if tb.RawGetString(key) != LNil {
- tb.RawSetString(key, value)
- return
- }
- }
- metaindex := ls.metaOp1(curobj, "__newindex")
- if metaindex == LNil {
- if !istable {
- ls.RaiseError("attempt to index a non-table object(%v)", curobj.Type().String())
- }
- tb.RawSetString(key, value)
- return
- }
- if metaindex.Type() == LTFunction {
- ls.reg.Push(metaindex)
- ls.reg.Push(curobj)
- ls.reg.Push(LString(key))
- ls.reg.Push(value)
- ls.Call(3, 0)
- return
- } else {
- curobj = metaindex
- }
- }
- ls.RaiseError("too many recursions in settable")
- }
- /* }}} */
- /* api methods {{{ */
- func NewState(opts ...Options) *LState {
- var ls *LState
- if len(opts) == 0 {
- ls = newLState(Options{
- CallStackSize: CallStackSize,
- RegistrySize: RegistrySize,
- })
- ls.OpenLibs()
- } else {
- if opts[0].CallStackSize < 1 {
- opts[0].CallStackSize = CallStackSize
- }
- if opts[0].RegistrySize < 128 {
- opts[0].RegistrySize = RegistrySize
- }
- ls = newLState(opts[0])
- if !opts[0].SkipOpenLibs {
- ls.OpenLibs()
- }
- }
- return ls
- }
- func (ls *LState) Close() {
- atomic.AddInt32(&ls.stop, 1)
- for _, file := range ls.G.tempFiles {
- // ignore errors in these operations
- file.Close()
- os.Remove(file.Name())
- }
- }
- /* registry operations {{{ */
- func (ls *LState) GetTop() int {
- return ls.reg.Top() - ls.currentLocalBase()
- }
- func (ls *LState) SetTop(idx int) {
- base := ls.currentLocalBase()
- newtop := ls.indexToReg(idx) + 1
- if newtop < base {
- ls.reg.SetTop(base)
- } else {
- ls.reg.SetTop(newtop)
- }
- }
- func (ls *LState) Replace(idx int, value LValue) {
- base := ls.currentLocalBase()
- if idx > 0 {
- reg := base + idx - 1
- if reg < ls.reg.Top() {
- ls.reg.Set(reg, value)
- }
- } else if idx == 0 {
- } else if idx > RegistryIndex {
- if tidx := ls.reg.Top() + idx; tidx >= base {
- ls.reg.Set(tidx, value)
- }
- } else {
- switch idx {
- case RegistryIndex:
- if tb, ok := value.(*LTable); ok {
- ls.G.Registry = tb
- } else {
- ls.RaiseError("registry must be a table(%v)", value.Type().String())
- }
- case EnvironIndex:
- if ls.currentFrame == nil {
- ls.RaiseError("no calling environment")
- }
- if tb, ok := value.(*LTable); ok {
- ls.currentFrame.Fn.Env = tb
- } else {
- ls.RaiseError("environment must be a table(%v)", value.Type().String())
- }
- case GlobalsIndex:
- if tb, ok := value.(*LTable); ok {
- ls.G.Global = tb
- } else {
- ls.RaiseError("_G must be a table(%v)", value.Type().String())
- }
- default:
- fn := ls.currentFrame.Fn
- index := GlobalsIndex - idx - 1
- if index < len(fn.Upvalues) {
- fn.Upvalues[index].SetValue(value)
- }
- }
- }
- }
- func (ls *LState) Get(idx int) LValue {
- base := ls.currentLocalBase()
- if idx > 0 {
- reg := base + idx - 1
- if reg < ls.reg.Top() {
- return ls.reg.Get(reg)
- }
- return LNil
- } else if idx == 0 {
- return LNil
- } else if idx > RegistryIndex {
- tidx := ls.reg.Top() + idx
- if tidx < base {
- return LNil
- }
- return ls.reg.Get(tidx)
- } else {
- switch idx {
- case RegistryIndex:
- return ls.G.Registry
- case EnvironIndex:
- if ls.currentFrame == nil {
- return ls.Env
- }
- return ls.currentFrame.Fn.Env
- case GlobalsIndex:
- return ls.G.Global
- default:
- fn := ls.currentFrame.Fn
- index := GlobalsIndex - idx - 1
- if index < len(fn.Upvalues) {
- return fn.Upvalues[index].Value()
- }
- return LNil
- }
- }
- return LNil
- }
- func (ls *LState) Push(value LValue) {
- ls.reg.Push(value)
- }
- func (ls *LState) Pop(n int) {
- for i := 0; i < n; i++ {
- if ls.GetTop() == 0 {
- ls.RaiseError("register underflow")
- }
- ls.reg.Pop()
- }
- }
- func (ls *LState) Insert(value LValue, index int) {
- reg := ls.indexToReg(index)
- top := ls.reg.Top()
- if reg >= top {
- ls.reg.Set(reg, value)
- return
- }
- if reg <= ls.currentLocalBase() {
- reg = ls.currentLocalBase()
- }
- top--
- for ; top >= reg; top-- {
- ls.reg.Set(top+1, ls.reg.Get(top))
- }
- ls.reg.Set(reg, value)
- }
- func (ls *LState) Remove(index int) {
- reg := ls.indexToReg(index)
- top := ls.reg.Top()
- switch {
- case reg >= top:
- return
- case reg < ls.currentLocalBase():
- return
- case reg == top-1:
- ls.Pop(1)
- return
- }
- for i := reg; i < top-1; i++ {
- ls.reg.Set(i, ls.reg.Get(i+1))
- }
- ls.reg.SetTop(top - 1)
- }
- /* }}} */
- /* object allocation {{{ */
- func (ls *LState) NewTable() *LTable {
- return newLTable(defaultArrayCap, defaultHashCap)
- }
- func (ls *LState) CreateTable(acap, hcap int) *LTable {
- return newLTable(acap, hcap)
- }
- // NewThread returns a new LState that shares with the original state all global objects.
- // If the original state has context.Context, the new state has a new child context of the original state and this function returns its cancel function.
- func (ls *LState) NewThread() (*LState, context.CancelFunc) {
- thread := newLState(ls.Options)
- thread.G = ls.G
- thread.Env = ls.Env
- var f context.CancelFunc = nil
- if ls.ctx != nil {
- thread.mainLoop = mainLoopWithContext
- thread.ctx, f = context.WithCancel(ls.ctx)
- }
- return thread, f
- }
- func (ls *LState) NewUserData() *LUserData {
- return &LUserData{
- Env: ls.currentEnv(),
- Metatable: LNil,
- }
- }
- func (ls *LState) NewFunction(fn LGFunction) *LFunction {
- return newLFunctionG(fn, ls.currentEnv(), 0)
- }
- func (ls *LState) NewClosure(fn LGFunction, upvalues ...LValue) *LFunction {
- cl := newLFunctionG(fn, ls.currentEnv(), len(upvalues))
- for i, lv := range upvalues {
- cl.Upvalues[i] = &Upvalue{}
- cl.Upvalues[i].Close()
- cl.Upvalues[i].SetValue(lv)
- }
- return cl
- }
- /* }}} */
- /* toType {{{ */
- func (ls *LState) ToBool(n int) bool {
- return LVAsBool(ls.Get(n))
- }
- func (ls *LState) ToInt(n int) int {
- if lv, ok := ls.Get(n).(LNumber); ok {
- return int(lv)
- }
- if lv, ok := ls.Get(n).(LString); ok {
- if num, err := parseNumber(string(lv)); err == nil {
- return int(num)
- }
- }
- return 0
- }
- func (ls *LState) ToInt64(n int) int64 {
- if lv, ok := ls.Get(n).(LNumber); ok {
- return int64(lv)
- }
- if lv, ok := ls.Get(n).(LString); ok {
- if num, err := parseNumber(string(lv)); err == nil {
- return int64(num)
- }
- }
- return 0
- }
- func (ls *LState) ToNumber(n int) LNumber {
- return LVAsNumber(ls.Get(n))
- }
- func (ls *LState) ToString(n int) string {
- return LVAsString(ls.Get(n))
- }
- func (ls *LState) ToTable(n int) *LTable {
- if lv, ok := ls.Get(n).(*LTable); ok {
- return lv
- }
- return nil
- }
- func (ls *LState) ToFunction(n int) *LFunction {
- if lv, ok := ls.Get(n).(*LFunction); ok {
- return lv
- }
- return nil
- }
- func (ls *LState) ToUserData(n int) *LUserData {
- if lv, ok := ls.Get(n).(*LUserData); ok {
- return lv
- }
- return nil
- }
- func (ls *LState) ToThread(n int) *LState {
- if lv, ok := ls.Get(n).(*LState); ok {
- return lv
- }
- return nil
- }
- /* }}} */
- /* error & debug operations {{{ */
- // This function is equivalent to luaL_error( http://www.lua.org/manual/5.1/manual.html#luaL_error ).
- func (ls *LState) RaiseError(format string, args ...interface{}) {
- ls.raiseError(1, format, args...)
- }
- // This function is equivalent to lua_error( http://www.lua.org/manual/5.1/manual.html#lua_error ).
- func (ls *LState) Error(lv LValue, level int) {
- if str, ok := lv.(LString); ok {
- ls.raiseError(level, string(str))
- } else {
- if !ls.hasErrorFunc {
- ls.closeAllUpvalues()
- }
- ls.Push(lv)
- ls.Panic(ls)
- }
- }
- func (ls *LState) GetInfo(what string, dbg *Debug, fn LValue) (LValue, error) {
- if !strings.HasPrefix(what, ">") {
- fn = dbg.frame.Fn
- } else {
- what = what[1:]
- }
- f, ok := fn.(*LFunction)
- if !ok {
- return LNil, newApiErrorS(ApiErrorRun, "can not get debug info(an object in not a function)")
- }
- retfn := false
- for _, c := range what {
- switch c {
- case 'f':
- retfn = true
- case 'S':
- if dbg.frame != nil && dbg.frame.Parent == nil {
- dbg.What = "main"
- } else if f.IsG {
- dbg.What = "G"
- } else if dbg.frame != nil && dbg.frame.TailCall > 0 {
- dbg.What = "tail"
- } else {
- dbg.What = "Lua"
- }
- if !f.IsG {
- dbg.Source = f.Proto.SourceName
- dbg.LineDefined = f.Proto.LineDefined
- dbg.LastLineDefined = f.Proto.LastLineDefined
- }
- case 'l':
- if !f.IsG && dbg.frame != nil {
- if dbg.frame.Pc > 0 {
- dbg.CurrentLine = f.Proto.DbgSourcePositions[dbg.frame.Pc-1]
- }
- } else {
- dbg.CurrentLine = -1
- }
- case 'u':
- dbg.NUpvalues = len(f.Upvalues)
- case 'n':
- if dbg.frame != nil {
- dbg.Name = ls.rawFrameFuncName(dbg.frame)
- }
- default:
- return LNil, newApiErrorS(ApiErrorRun, "invalid what: "+string(c))
- }
- }
- if retfn {
- return f, nil
- }
- return LNil, nil
- }
- func (ls *LState) GetStack(level int) (*Debug, bool) {
- frame := ls.currentFrame
- for ; level > 0 && frame != nil; frame = frame.Parent {
- level--
- if !frame.Fn.IsG {
- level -= frame.TailCall
- }
- }
- if level == 0 && frame != nil {
- return &Debug{frame: frame}, true
- } else if level < 0 && ls.stack.Sp() > 0 {
- return &Debug{frame: ls.stack.At(0)}, true
- }
- return &Debug{}, false
- }
- func (ls *LState) GetLocal(dbg *Debug, no int) (string, LValue) {
- frame := dbg.frame
- if name := ls.findLocal(frame, no); len(name) > 0 {
- return name, ls.reg.Get(frame.LocalBase + no - 1)
- }
- return "", LNil
- }
- func (ls *LState) SetLocal(dbg *Debug, no int, lv LValue) string {
- frame := dbg.frame
- if name := ls.findLocal(frame, no); len(name) > 0 {
- ls.reg.Set(frame.LocalBase+no-1, lv)
- return name
- }
- return ""
- }
- func (ls *LState) GetUpvalue(fn *LFunction, no int) (string, LValue) {
- if fn.IsG {
- return "", LNil
- }
- no--
- if no >= 0 && no < len(fn.Upvalues) {
- return fn.Proto.DbgUpvalues[no], fn.Upvalues[no].Value()
- }
- return "", LNil
- }
- func (ls *LState) SetUpvalue(fn *LFunction, no int, lv LValue) string {
- if fn.IsG {
- return ""
- }
- no--
- if no >= 0 && no < len(fn.Upvalues) {
- fn.Upvalues[no].SetValue(lv)
- return fn.Proto.DbgUpvalues[no]
- }
- return ""
- }
- /* }}} */
- /* env operations {{{ */
- func (ls *LState) GetFEnv(obj LValue) LValue {
- switch lv := obj.(type) {
- case *LFunction:
- return lv.Env
- case *LUserData:
- return lv.Env
- case *LState:
- return lv.Env
- }
- return LNil
- }
- func (ls *LState) SetFEnv(obj LValue, env LValue) {
- tb, ok := env.(*LTable)
- if !ok {
- ls.RaiseError("cannot use %v as an environment", env.Type().String())
- }
- switch lv := obj.(type) {
- case *LFunction:
- lv.Env = tb
- case *LUserData:
- lv.Env = tb
- case *LState:
- lv.Env = tb
- }
- /* do nothing */
- }
- /* }}} */
- /* table operations {{{ */
- func (ls *LState) RawGet(tb *LTable, key LValue) LValue {
- return tb.RawGet(key)
- }
- func (ls *LState) RawGetInt(tb *LTable, key int) LValue {
- return tb.RawGetInt(key)
- }
- func (ls *LState) GetField(obj LValue, skey string) LValue {
- return ls.getFieldString(obj, skey)
- }
- func (ls *LState) GetTable(obj LValue, key LValue) LValue {
- return ls.getField(obj, key)
- }
- func (ls *LState) RawSet(tb *LTable, key LValue, value LValue) {
- if n, ok := key.(LNumber); ok && math.IsNaN(float64(n)) {
- ls.RaiseError("table index is NaN")
- } else if key == LNil {
- ls.RaiseError("table index is nil")
- }
- tb.RawSet(key, value)
- }
- func (ls *LState) RawSetInt(tb *LTable, key int, value LValue) {
- tb.RawSetInt(key, value)
- }
- func (ls *LState) SetField(obj LValue, key string, value LValue) {
- ls.setFieldString(obj, key, value)
- }
- func (ls *LState) SetTable(obj LValue, key LValue, value LValue) {
- ls.setField(obj, key, value)
- }
- func (ls *LState) ForEach(tb *LTable, cb func(LValue, LValue)) {
- tb.ForEach(cb)
- }
- func (ls *LState) GetGlobal(name string) LValue {
- return ls.GetField(ls.Get(GlobalsIndex), name)
- }
- func (ls *LState) SetGlobal(name string, value LValue) {
- ls.SetField(ls.Get(GlobalsIndex), name, value)
- }
- func (ls *LState) Next(tb *LTable, key LValue) (LValue, LValue) {
- return tb.Next(key)
- }
- /* }}} */
- /* unary operations {{{ */
- func (ls *LState) ObjLen(v1 LValue) int {
- if v1.Type() == LTString {
- return len(string(v1.(LString)))
- }
- op := ls.metaOp1(v1, "__len")
- if op.Type() == LTFunction {
- ls.Push(op)
- ls.Push(v1)
- ls.Call(1, 1)
- ret := ls.reg.Pop()
- if ret.Type() == LTNumber {
- return int(ret.(LNumber))
- }
- } else if v1.Type() == LTTable {
- return v1.(*LTable).Len()
- }
- return 0
- }
- /* }}} */
- /* binary operations {{{ */
- func (ls *LState) Concat(values ...LValue) string {
- top := ls.reg.Top()
- for _, value := range values {
- ls.reg.Push(value)
- }
- ret := stringConcat(ls, len(values), ls.reg.Top()-1)
- ls.reg.SetTop(top)
- return LVAsString(ret)
- }
- func (ls *LState) LessThan(lhs, rhs LValue) bool {
- return lessThan(ls, lhs, rhs)
- }
- func (ls *LState) Equal(lhs, rhs LValue) bool {
- return equals(ls, lhs, rhs, false)
- }
- func (ls *LState) RawEqual(lhs, rhs LValue) bool {
- return equals(ls, lhs, rhs, true)
- }
- /* }}} */
- /* register operations {{{ */
- func (ls *LState) Register(name string, fn LGFunction) {
- ls.SetGlobal(name, ls.NewFunction(fn))
- }
- /* }}} */
- /* load and function call operations {{{ */
- func container2proto(container *functionProtoContainer) *FunctionProto {
- protos := []*FunctionProto{}
- for _, c := range container.FunctionPrototypes {
- protos = append(protos, container2proto(c))
- }
- constants := []LValue{}
- stringConstants := []string{}
- for _, c := range container.Constants {
- if s, ok := c.(string); ok {
- constants = append(constants, LString(s))
- stringConstants = append(stringConstants, s)
- } else {
- constants = append(constants, LNumber(c.(float64)))
- }
- }
- return &FunctionProto{
- SourceName: container.SourceName,
- LineDefined: container.LineDefined,
- LastLineDefined: container.LastLineDefined,
- NumUpvalues: container.NumUpvalues,
- NumParameters: container.NumParameters,
- IsVarArg: container.IsVarArg,
- NumUsedRegisters: container.NumUsedRegisters,
- Code: container.Code,
- Constants: constants,
- FunctionPrototypes: protos,
- DbgSourcePositions: container.DbgSourcePositions,
- DbgLocals: container.DbgLocals,
- DbgCalls: container.DbgCalls,
- DbgUpvalues: container.DbgUpvalues,
- stringConstants: stringConstants,
- }
- }
- func (ls *LState) Load(reader io.Reader, name string) (*LFunction, error) {
- b := bufio.NewReader(reader)
- if sbuf, err := b.Peek(4); err == nil {
- if string(sbuf) == dumpSignature {
- b.Discard(4)
- buf, err := ioutil.ReadAll(b)
- if err != nil {
- ls.RaiseError(err.Error())
- }
- var container functionProtoContainer
- if err := msgpack.Unmarshal(buf, &container); err != nil {
- ls.RaiseError(err.Error())
- }
- return newLFunctionL(container2proto(&container), ls.currentEnv(), 0), nil
- }
- }
- chunk, err := parse.Parse(b, name)
- if err != nil {
- return nil, newApiErrorE(ApiErrorSyntax, err)
- }
- proto, err := Compile(chunk, name)
- if err != nil {
- return nil, newApiErrorE(ApiErrorSyntax, err)
- }
- return newLFunctionL(proto, ls.currentEnv(), 0), nil
- }
- func (ls *LState) Call(nargs, nret int) {
- ls.callR(nargs, nret, -1)
- }
- func (ls *LState) PCall(nargs, nret int, errfunc *LFunction) (err error) {
- err = nil
- sp := ls.stack.Sp()
- base := ls.reg.Top() - nargs - 1
- oldpanic := ls.Panic
- ls.Panic = panicWithoutTraceback
- if errfunc != nil {
- ls.hasErrorFunc = true
- }
- defer func() {
- ls.Panic = oldpanic
- ls.hasErrorFunc = false
- rcv := recover()
- if rcv != nil {
- if _, ok := rcv.(*ApiError); !ok {
- err = newApiErrorS(ApiErrorPanic, fmt.Sprint(rcv))
- if ls.Options.IncludeGoStackTrace {
- buf := make([]byte, 4096)
- runtime.Stack(buf, false)
- err.(*ApiError).StackTrace = strings.Trim(string(buf), "\000") + "\n" + ls.stackTrace(0)
- }
- } else {
- err = rcv.(*ApiError)
- }
- if errfunc != nil {
- ls.Push(errfunc)
- ls.Push(err.(*ApiError).Object)
- ls.Panic = panicWithoutTraceback
- defer func() {
- ls.Panic = oldpanic
- rcv := recover()
- if rcv != nil {
- if _, ok := rcv.(*ApiError); !ok {
- err = newApiErrorS(ApiErrorPanic, fmt.Sprint(rcv))
- if ls.Options.IncludeGoStackTrace {
- buf := make([]byte, 4096)
- runtime.Stack(buf, false)
- err.(*ApiError).StackTrace = strings.Trim(string(buf), "\000") + ls.stackTrace(0)
- }
- } else {
- err = rcv.(*ApiError)
- err.(*ApiError).StackTrace = ls.stackTrace(0)
- }
- }
- }()
- ls.Call(1, 1)
- err = newApiError(ApiErrorError, ls.Get(-1))
- } else if len(err.(*ApiError).StackTrace) == 0 {
- err.(*ApiError).StackTrace = ls.stackTrace(0)
- }
- ls.reg.SetTop(base)
- }
- ls.stack.SetSp(sp)
- if sp == 0 {
- ls.currentFrame = nil
- }
- }()
- ls.Call(nargs, nret)
- return
- }
- func (ls *LState) GPCall(fn LGFunction, data LValue) error {
- ls.Push(newLFunctionG(fn, ls.currentEnv(), 0))
- ls.Push(data)
- return ls.PCall(1, MultRet, nil)
- }
- func (ls *LState) CallByParam(cp P, args ...LValue) error {
- ls.Push(cp.Fn)
- for _, arg := range args {
- ls.Push(arg)
- }
- if cp.Protect {
- return ls.PCall(len(args), cp.NRet, cp.Handler)
- }
- ls.Call(len(args), cp.NRet)
- return nil
- }
- /* }}} */
- /* metatable operations {{{ */
- func (ls *LState) GetMetatable(obj LValue) LValue {
- return ls.metatable(obj, false)
- }
- func (ls *LState) SetMetatable(obj LValue, mt LValue) {
- switch mt.(type) {
- case *LNilType, *LTable:
- default:
- ls.RaiseError("metatable must be a table or nil, but got %v", mt.Type().String())
- }
- switch v := obj.(type) {
- case *LTable:
- v.Metatable = mt
- case *LUserData:
- v.Metatable = mt
- default:
- ls.G.builtinMts[int(obj.Type())] = mt
- }
- }
- /* }}} */
- /* coroutine operations {{{ */
- func (ls *LState) Status(th *LState) string {
- status := "suspended"
- if th.Dead {
- status = "dead"
- } else if ls.G.CurrentThread == th {
- status = "running"
- } else if ls.Parent == th {
- status = "normal"
- }
- return status
- }
- func (ls *LState) Resume(th *LState, fn *LFunction, args ...LValue) (ResumeState, error, []LValue) {
- isstarted := th.isStarted()
- if !isstarted {
- base := 0
- th.stack.Push(callFrame{
- Fn: fn,
- Pc: 0,
- Base: base,
- LocalBase: base + 1,
- ReturnBase: base,
- NArgs: 0,
- NRet: MultRet,
- Parent: nil,
- TailCall: 0,
- })
- }
- if ls.G.CurrentThread == th {
- return ResumeError, newApiErrorS(ApiErrorRun, "can not resume a running thread"), nil
- }
- if th.Dead {
- return ResumeError, newApiErrorS(ApiErrorRun, "can not resume a dead thread"), nil
- }
- th.Parent = ls
- ls.G.CurrentThread = th
- if !isstarted {
- cf := th.stack.Last()
- th.currentFrame = cf
- th.SetTop(0)
- for _, arg := range args {
- th.Push(arg)
- }
- cf.NArgs = len(args)
- th.initCallFrame(cf)
- th.Panic = panicWithoutTraceback
- } else {
- for _, arg := range args {
- th.Push(arg)
- }
- }
- top := ls.GetTop()
- threadRun(th)
- haserror := LVIsFalse(ls.Get(top + 1))
- ret := make([]LValue, 0, ls.GetTop())
- for idx := top + 2; idx <= ls.GetTop(); idx++ {
- ret = append(ret, ls.Get(idx))
- }
- if len(ret) == 0 {
- ret = append(ret, LNil)
- }
- ls.SetTop(top)
- if haserror {
- return ResumeError, newApiError(ApiErrorRun, ret[0]), nil
- } else if th.stack.IsEmpty() {
- return ResumeOK, nil, ret
- }
- return ResumeYield, nil, ret
- }
- func (ls *LState) Yield(values ...LValue) int {
- ls.SetTop(0)
- for _, lv := range values {
- ls.Push(lv)
- }
- return -1
- }
- func (ls *LState) XMoveTo(other *LState, n int) {
- if ls == other {
- return
- }
- top := ls.GetTop()
- n = intMin(n, top)
- for i := n; i > 0; i-- {
- other.Push(ls.Get(top - i + 1))
- }
- ls.SetTop(top - n)
- }
- /* }}} */
- /* GopherLua original APIs {{{ */
- // Set maximum memory size. This function can only be called from the main thread.
- func (ls *LState) SetMx(mx int) {
- if ls.Parent != nil {
- ls.RaiseError("sub threads are not allowed to set a memory limit")
- }
- go func() {
- limit := uint64(mx * 1024 * 1024) //MB
- var s runtime.MemStats
- for ls.stop == 0 {
- runtime.ReadMemStats(&s)
- if s.Alloc >= limit {
- fmt.Println("out of memory")
- os.Exit(3)
- }
- time.Sleep(100 * time.Millisecond)
- }
- }()
- }
- // SetContext set a context ctx to this LState. The provided ctx must be non-nil.
- func (ls *LState) SetContext(ctx context.Context) {
- ls.mainLoop = mainLoopWithContext
- ls.ctx = ctx
- }
- // Context returns the LState's context. To change the context, use WithContext.
- func (ls *LState) Context() context.Context {
- return ls.ctx
- }
- // RemoveContext removes the context associated with this LState and returns this context.
- func (ls *LState) RemoveContext() context.Context {
- oldctx := ls.ctx
- ls.mainLoop = mainLoop
- ls.ctx = nil
- return oldctx
- }
- // Converts the Lua value at the given acceptable index to the chan LValue.
- func (ls *LState) ToChannel(n int) chan LValue {
- if lv, ok := ls.Get(n).(LChannel); ok {
- return (chan LValue)(lv)
- }
- return nil
- }
- /* }}} */
- /* }}} */
- //
|