github.com/jslyzt/glua@v0.0.0-20210819023911-4030c8e0234a/_state.go (about) 1 package glua 2 3 import ( 4 "context" 5 "fmt" 6 "io" 7 "math" 8 "os" 9 "runtime" 10 "strings" 11 "sync" 12 "sync/atomic" 13 "time" 14 15 "github.com/jslyzt/glua/parse" 16 ) 17 18 // 常量定义 19 const ( 20 MultRet = -1 21 RegistryIndex = -10000 22 EnvironIndex = -10001 23 GlobalsIndex = -10002 24 ) 25 26 // APIError api错误 27 type APIError struct { 28 Type APIErrorType 29 Object LValue 30 StackTrace string 31 // Underlying error. This attribute is set only if the Type is ApiErrorFile or ApiErrorSyntax 32 Cause error 33 } 34 35 func newAPIError(code APIErrorType, object LValue) *APIError { 36 return &APIError{code, object, "", nil} 37 } 38 39 func newAPIErrorS(code APIErrorType, message string) *APIError { 40 return newAPIError(code, LString(message)) 41 } 42 43 func newAPIErrorE(code APIErrorType, err error) *APIError { 44 return &APIError{code, LString(err.Error()), "", err} 45 } 46 47 // Error 错误 48 func (e *APIError) Error() string { 49 if len(e.StackTrace) > 0 { 50 return fmt.Sprintf("%s\n%s", e.Object.String(), e.StackTrace) 51 } 52 return e.Object.String() 53 } 54 55 // APIErrorType api错误类型 56 type APIErrorType int 57 58 // api错误枚举 59 const ( 60 APIErrorSyntax APIErrorType = iota 61 APIErrorFile 62 APIErrorRun 63 APIErrorError 64 APIErrorPanic 65 ) 66 67 // ResumeState 重启状态 68 type ResumeState int 69 70 // 重启状态枚举 71 const ( 72 ResumeOK ResumeState = iota 73 ResumeYield 74 ResumeError 75 ) 76 77 // P p 78 type P struct { 79 Fn LValue 80 NRet int 81 Protect bool 82 Handler *LFunction 83 } 84 85 // Options is a configuration that is used to create a new LState. 86 type Options struct { 87 // Call stack size. This defaults to `lua.CallStackSize`. 88 CallStackSize int 89 // Data stack size. This defaults to `lua.RegistrySize`. 90 RegistrySize int 91 // Allow the registry to grow from the registry size specified up to a value of RegistryMaxSize. A value of 0 92 // indicates no growth is permitted. The registry will not shrink again after any growth. 93 RegistryMaxSize int 94 // If growth is enabled, step up by an additional `RegistryGrowStep` each time to avoid having to resize too often. 95 // This defaults to `lua.RegistryGrowStep` 96 RegistryGrowStep int 97 // Controls whether or not libraries are opened by default 98 SkipOpenLibs bool 99 // Tells whether a Go stacktrace should be included in a Lua stacktrace when panics occur. 100 IncludeGoStackTrace bool 101 // If `MinimizeStackMemory` is set, the call stack will be automatically grown or shrank up to a limit of 102 // `CallStackSize` in order to minimize memory usage. This does incur a slight performance penalty. 103 MinimizeStackMemory bool 104 } 105 106 // Debug 调试信息 107 type Debug struct { 108 frame *CallFrame 109 Name string 110 What string 111 Source string 112 CurrentLine int 113 NUpvalues int 114 LineDefined int 115 LastLineDefined int 116 } 117 118 // CallFrame 调用层 119 type CallFrame struct { 120 Idx int 121 Fn *LFunction 122 Parent *CallFrame 123 Pc int 124 Base int 125 LocalBase int 126 ReturnBase int 127 NArgs int 128 NRet int 129 TailCall int 130 } 131 132 // CallFrameStack 调用堆栈 133 type CallFrameStack interface { 134 Push(v CallFrame) 135 Pop() *CallFrame 136 Last() *CallFrame 137 138 SetSp(sp int) 139 Sp() int 140 At(sp int) *CallFrame 141 142 IsFull() bool 143 IsEmpty() bool 144 145 FreeAll() 146 } 147 148 type fixedCallFrameStack struct { 149 array []CallFrame 150 sp int 151 } 152 153 func newFixedCallFrameStack(size int) CallFrameStack { 154 return &fixedCallFrameStack{ 155 array: make([]CallFrame, size), 156 sp: 0, 157 } 158 } 159 160 func (cs *fixedCallFrameStack) IsEmpty() bool { 161 return cs.sp == 0 162 } 163 164 func (cs *fixedCallFrameStack) IsFull() bool { 165 return cs.sp == len(cs.array) 166 } 167 168 func (cs *fixedCallFrameStack) Clear() { 169 cs.sp = 0 170 } 171 172 func (cs *fixedCallFrameStack) Push(v CallFrame) { 173 cs.array[cs.sp] = v 174 cs.array[cs.sp].Idx = cs.sp 175 cs.sp++ 176 } 177 178 func (cs *fixedCallFrameStack) Sp() int { 179 return cs.sp 180 } 181 182 func (cs *fixedCallFrameStack) SetSp(sp int) { 183 cs.sp = sp 184 } 185 186 func (cs *fixedCallFrameStack) Last() *CallFrame { 187 if cs.sp == 0 { 188 return nil 189 } 190 return &cs.array[cs.sp-1] 191 } 192 193 func (cs *fixedCallFrameStack) At(sp int) *CallFrame { 194 return &cs.array[sp] 195 } 196 197 func (cs *fixedCallFrameStack) Pop() *CallFrame { 198 cs.sp-- 199 return &cs.array[cs.sp] 200 } 201 202 func (cs *fixedCallFrameStack) FreeAll() { 203 // nothing to do for fixed callframestack 204 } 205 206 // FramesPerSegment should be a power of 2 constant for performance reasons. It will allow the go compiler to change 207 // the divs and mods into bitshifts. Max is 256 due to current use of uint8 to count how many frames in a segment are 208 // used. 209 const FramesPerSegment = 8 210 211 type callFrameStackSegment struct { 212 array [FramesPerSegment]CallFrame 213 } 214 type segIdx uint16 215 type autoGrowingCallFrameStack struct { 216 segments []*callFrameStackSegment 217 segIdx segIdx 218 // segSp is the number of frames in the current segment which are used. Full 'sp' value is segIdx * FramesPerSegment + segSp. 219 // It points to the next stack slot to use, so 0 means to use the 0th element in the segment, and a value of 220 // FramesPerSegment indicates that the segment is full and cannot accommodate another frame. 221 segSp uint8 222 } 223 224 var segmentPool sync.Pool 225 226 func newCallFrameStackSegment() *callFrameStackSegment { 227 seg := segmentPool.Get() 228 if seg == nil { 229 return &callFrameStackSegment{} 230 } 231 return seg.(*callFrameStackSegment) 232 } 233 234 func freeCallFrameStackSegment(seg *callFrameStackSegment) { 235 segmentPool.Put(seg) 236 } 237 238 // newCallFrameStack allocates a new stack for a lua state, which will auto grow up to a max size of at least maxSize. 239 // it will actually grow up to the next segment size multiple after maxSize, where the segment size is dictated by 240 // FramesPerSegment. 241 func newAutoGrowingCallFrameStack(maxSize int) CallFrameStack { 242 cs := &autoGrowingCallFrameStack{ 243 segments: make([]*callFrameStackSegment, (maxSize+(FramesPerSegment-1))/FramesPerSegment), 244 segIdx: 0, 245 } 246 cs.segments[0] = newCallFrameStackSegment() 247 return cs 248 } 249 250 func (cs *autoGrowingCallFrameStack) IsEmpty() bool { 251 return cs.segIdx == 0 && cs.segSp == 0 252 } 253 254 // IsFull returns true if the stack cannot receive any more stack pushes without overflowing 255 func (cs *autoGrowingCallFrameStack) IsFull() bool { 256 return int(cs.segIdx) == len(cs.segments) && cs.segSp >= FramesPerSegment 257 } 258 259 func (cs *autoGrowingCallFrameStack) Clear() { 260 for i := segIdx(1); i <= cs.segIdx; i++ { 261 freeCallFrameStackSegment(cs.segments[i]) 262 cs.segments[i] = nil 263 } 264 cs.segIdx = 0 265 cs.segSp = 0 266 } 267 268 func (cs *autoGrowingCallFrameStack) FreeAll() { 269 for i := segIdx(0); i <= cs.segIdx; i++ { 270 freeCallFrameStackSegment(cs.segments[i]) 271 cs.segments[i] = nil 272 } 273 } 274 275 // Push pushes the passed callFrame onto the stack. it panics if the stack is full, caller should call IsFull() before 276 // invoking this to avoid this. 277 func (cs *autoGrowingCallFrameStack) Push(v CallFrame) { 278 curSeg := cs.segments[cs.segIdx] 279 if cs.segSp >= FramesPerSegment { 280 // segment full, push new segment if allowed 281 if cs.segIdx < segIdx(len(cs.segments)-1) { 282 curSeg = newCallFrameStackSegment() 283 cs.segIdx++ 284 cs.segments[cs.segIdx] = curSeg 285 cs.segSp = 0 286 } else { 287 panic("lua callstack overflow") 288 } 289 } 290 curSeg.array[cs.segSp] = v 291 curSeg.array[cs.segSp].Idx = int(cs.segSp) + FramesPerSegment*int(cs.segIdx) 292 cs.segSp++ 293 } 294 295 // Sp retrieves the current stack depth, which is the number of frames currently pushed on the stack. 296 func (cs *autoGrowingCallFrameStack) Sp() int { 297 return int(cs.segSp) + int(cs.segIdx)*FramesPerSegment 298 } 299 300 // SetSp can be used to rapidly unwind the stack, freeing all stack frames on the way. It should not be used to 301 // allocate new stack space, use Push() for that. 302 func (cs *autoGrowingCallFrameStack) SetSp(sp int) { 303 desiredSegIdx := segIdx(sp / FramesPerSegment) 304 desiredFramesInLastSeg := uint8(sp % FramesPerSegment) 305 for { 306 if cs.segIdx <= desiredSegIdx { 307 break 308 } 309 freeCallFrameStackSegment(cs.segments[cs.segIdx]) 310 cs.segments[cs.segIdx] = nil 311 cs.segIdx-- 312 } 313 cs.segSp = desiredFramesInLastSeg 314 } 315 316 func (cs *autoGrowingCallFrameStack) Last() *CallFrame { 317 curSeg := cs.segments[cs.segIdx] 318 segSp := cs.segSp 319 if segSp == 0 { 320 if cs.segIdx == 0 { 321 return nil 322 } 323 curSeg = cs.segments[cs.segIdx-1] 324 segSp = FramesPerSegment 325 } 326 return &curSeg.array[segSp-1] 327 } 328 329 func (cs *autoGrowingCallFrameStack) At(sp int) *CallFrame { 330 segIdx := segIdx(sp / FramesPerSegment) 331 frameIdx := uint8(sp % FramesPerSegment) 332 return &cs.segments[segIdx].array[frameIdx] 333 } 334 335 // Pop pops off the most recent stack frame and returns it 336 func (cs *autoGrowingCallFrameStack) Pop() *CallFrame { 337 curSeg := cs.segments[cs.segIdx] 338 if cs.segSp == 0 { 339 if cs.segIdx == 0 { 340 // stack empty 341 return nil 342 } 343 freeCallFrameStackSegment(curSeg) 344 cs.segments[cs.segIdx] = nil 345 cs.segIdx-- 346 cs.segSp = FramesPerSegment 347 curSeg = cs.segments[cs.segIdx] 348 } 349 cs.segSp-- 350 return &curSeg.array[cs.segSp] 351 } 352 353 type registryHandler interface { 354 registryOverflow() 355 } 356 type registry struct { 357 array []LValue 358 top int 359 growBy int 360 maxSize int 361 alloc *allocator 362 handler registryHandler 363 } 364 365 func newRegistry(handler registryHandler, initialSize int, growBy int, maxSize int, alloc *allocator) *registry { 366 return ®istry{make([]LValue, initialSize), 0, growBy, maxSize, alloc, handler} 367 } 368 369 func (rg *registry) checkSize(requiredSize int) { // +inline-start 370 if requiredSize > cap(rg.array) { 371 rg.resize(requiredSize) 372 } 373 } // +inline-end 374 375 func (rg *registry) resize(requiredSize int) { // +inline-start 376 newSize := requiredSize + rg.growBy // give some padding 377 if newSize > rg.maxSize { 378 newSize = rg.maxSize 379 } 380 if newSize < requiredSize { 381 rg.handler.registryOverflow() 382 return 383 } 384 rg.forceResize(newSize) 385 } // +inline-end 386 387 func (rg *registry) forceResize(newSize int) { 388 newSlice := make([]LValue, newSize) 389 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. 390 rg.array = newSlice 391 } 392 func (rg *registry) SetTop(top int) { 393 // +inline-call rg.checkSize top 394 oldtop := rg.top 395 rg.top = top 396 for i := oldtop; i < rg.top; i++ { 397 rg.array[i] = LNil 398 } 399 // values beyond top don't need to be valid LValues, so setting them to nil is fine 400 // setting them to nil rather than LNil lets us invoke the golang memclr opto 401 if rg.top < oldtop { 402 nilRange := rg.array[rg.top:oldtop] 403 for i := range nilRange { 404 nilRange[i] = nil 405 } 406 } 407 //for i := rg.top; i < oldtop; i++ { 408 // rg.array[i] = LNil 409 //} 410 } 411 412 func (rg *registry) Top() int { 413 return rg.top 414 } 415 416 func (rg *registry) Push(v LValue) { 417 newSize := rg.top + 1 418 // +inline-call rg.checkSize newSize 419 rg.array[rg.top] = v 420 rg.top++ 421 } 422 423 func (rg *registry) Pop() LValue { 424 v := rg.array[rg.top-1] 425 rg.array[rg.top-1] = LNil 426 rg.top-- 427 return v 428 } 429 430 func (rg *registry) Get(reg int) LValue { 431 return rg.array[reg] 432 } 433 434 // CopyRange will move a section of values from index `start` to index `regv` 435 // It will move `n` values. 436 // `limit` specifies the maximum end range that can be copied from. If it's set to -1, then it defaults to stopping at 437 // the top of the registry (values beyond the top are not initialized, so if specifying an alternative `limit` you should 438 // pass a value <= rg.top. 439 // If start+n is beyond the limit, then nil values will be copied to the destination slots. 440 // After the copy, the registry is truncated to be at the end of the copied range, ie the original of the copied values 441 // are nilled out. (So top will be regv+n) 442 // CopyRange should ideally be renamed to MoveRange. 443 func (rg *registry) CopyRange(regv, start, limit, n int) { // +inline-start 444 newSize := regv + n 445 // +inline-call rg.checkSize newSize 446 if limit == -1 || limit > rg.top { 447 limit = rg.top 448 } 449 for i := 0; i < n; i++ { 450 srcIdx := start + i 451 if srcIdx >= limit || srcIdx < 0 { 452 rg.array[regv+i] = LNil 453 } else { 454 rg.array[regv+i] = rg.array[srcIdx] 455 } 456 } 457 458 // values beyond top don't need to be valid LValues, so setting them to nil is fine 459 // setting them to nil rather than LNil lets us invoke the golang memclr opto 460 oldtop := rg.top 461 rg.top = regv + n 462 if rg.top < oldtop { 463 nilRange := rg.array[rg.top:oldtop] 464 for i := range nilRange { 465 nilRange[i] = nil 466 } 467 } 468 } // +inline-end 469 470 // FillNil fills the registry with nil values from regm to regm+n and then sets the registry top to regm+n 471 func (rg *registry) FillNil(regm, n int) { // +inline-start 472 newSize := regm + n 473 // +inline-call rg.checkSize newSize 474 for i := 0; i < n; i++ { 475 rg.array[regm+i] = LNil 476 } 477 // values beyond top don't need to be valid LValues, so setting them to nil is fine 478 // setting them to nil rather than LNil lets us invoke the golang memclr opto 479 oldtop := rg.top 480 rg.top = regm + n 481 if rg.top < oldtop { 482 nilRange := rg.array[rg.top:oldtop] 483 for i := range nilRange { 484 nilRange[i] = nil 485 } 486 } 487 } // +inline-end 488 489 func (rg *registry) Insert(value LValue, reg int) { 490 top := rg.Top() 491 if reg >= top { 492 rg.Set(reg, value) 493 return 494 } 495 top-- 496 for ; top >= reg; top-- { 497 // FIXME consider using copy() here if Insert() is called enough 498 rg.Set(top+1, rg.Get(top)) 499 } 500 rg.Set(reg, value) 501 } 502 503 func (rg *registry) Set(reg int, val LValue) { 504 newSize := reg + 1 505 // +inline-call rg.checkSize newSize 506 rg.array[reg] = val 507 if reg >= rg.top { 508 rg.top = reg + 1 509 } 510 } 511 512 func (rg *registry) SetNumber(reg int, val LNumber) { 513 newSize := reg + 1 514 // +inline-call rg.checkSize newSize 515 rg.array[reg] = rg.alloc.LNumber2I(val) 516 if reg >= rg.top { 517 rg.top = reg + 1 518 } 519 } 520 521 func (rg *registry) IsFull() bool { 522 return rg.top >= cap(rg.array) 523 } 524 525 func newGlobal() *Global { 526 return &Global{ 527 MainThread: nil, 528 Registry: newLTable(0, 32), 529 Global: newLTable(0, 64), 530 builtinMts: make(map[int]LValue), 531 tempFiles: make([]*os.File, 0, 10), 532 } 533 } 534 535 func panicWithTraceback(L *LState) { 536 err := newAPIError(APIErrorRun, L.Get(-1)) 537 err.StackTrace = L.stackTrace(0) 538 panic(err) 539 } 540 541 func panicWithoutTraceback(L *LState) { 542 err := newAPIError(APIErrorRun, L.Get(-1)) 543 panic(err) 544 } 545 546 func newLState(options Options) *LState { 547 al := newAllocator(32) 548 ls := &LState{ 549 G: newGlobal(), 550 Parent: nil, 551 Panic: panicWithTraceback, 552 Dead: false, 553 Options: options, 554 555 stop: 0, 556 alloc: al, 557 currentFrame: nil, 558 wrapped: false, 559 uvcache: nil, 560 hasErrorFunc: false, 561 mainLoop: mainLoop, 562 ctx: nil, 563 } 564 if options.MinimizeStackMemory { 565 ls.stack = newAutoGrowingCallFrameStack(options.CallStackSize) 566 } else { 567 ls.stack = newFixedCallFrameStack(options.CallStackSize) 568 } 569 ls.reg = newRegistry(ls, options.RegistrySize, options.RegistryGrowStep, options.RegistryMaxSize, al) 570 ls.Env = ls.G.Global 571 return ls 572 } 573 574 func (ls *LState) PrintReg() { 575 println("-------------------------") 576 println("thread:", ls) 577 println("top:", ls.reg.Top()) 578 if ls.currentFrame != nil { 579 println("function base:", ls.currentFrame.Base) 580 println("return base:", ls.currentFrame.ReturnBase) 581 } else { 582 println("(vm not started)") 583 } 584 println("local base:", ls.currentLocalBase()) 585 for i := 0; i < ls.reg.Top(); i++ { 586 println(i, ls.reg.Get(i).String()) 587 } 588 println("-------------------------") 589 } 590 591 func (ls *LState) PrintCallStack() { 592 println("-------------------------") 593 for i := 0; i < ls.stack.Sp(); i++ { 594 print(i) 595 print(" ") 596 frame := ls.stack.At(i) 597 if frame == nil { 598 break 599 } 600 if frame.Fn.IsG { 601 println("IsG:", true, "Frame:", frame, "Fn:", frame.Fn) 602 } else { 603 println("IsG:", false, "Frame:", frame, "Fn:", frame.Fn, "pc:", frame.Pc) 604 } 605 } 606 println("-------------------------") 607 } 608 609 func (ls *LState) closeAllUpvalues() { // +inline-start 610 for cf := ls.currentFrame; cf != nil; cf = cf.Parent { 611 if !cf.Fn.IsG { 612 ls.closeUpvalues(cf.LocalBase) 613 } 614 } 615 } // +inline-end 616 617 func (ls *LState) raiseError(level int, format string, args ...interface{}) { 618 if !ls.hasErrorFunc { 619 ls.closeAllUpvalues() 620 } 621 message := format 622 if len(args) > 0 { 623 message = fmt.Sprintf(format, args...) 624 } 625 if level > 0 { 626 message = fmt.Sprintf("%v %v", ls.where(level-1, true), message) 627 } 628 if ls.reg.IsFull() { 629 // if the registry is full then it won't be possible to push a value, in this case, force a larger size 630 ls.reg.forceResize(ls.reg.Top() + 1) 631 } 632 ls.reg.Push(LString(message)) 633 ls.Panic(ls) 634 } 635 636 func (ls *LState) findLocal(frame *CallFrame, no int) string { 637 fn := frame.Fn 638 if !fn.IsG { 639 if name, ok := fn.LocalName(no, frame.Pc-1); ok { 640 return name 641 } 642 } 643 var top int 644 if ls.currentFrame == frame { 645 top = ls.reg.Top() 646 } else if frame.Idx+1 < ls.stack.Sp() { 647 top = ls.stack.At(frame.Idx + 1).Base 648 } else { 649 return "" 650 } 651 if top-frame.LocalBase >= no { 652 return "(*temporary)" 653 } 654 return "" 655 } 656 657 func (ls *LState) where(level int, skipg bool) string { 658 dbg, ok := ls.GetStack(level) 659 if !ok { 660 return "" 661 } 662 cf := dbg.frame 663 proto := cf.Fn.Proto 664 sourcename := "[G]" 665 if proto != nil { 666 sourcename = proto.SourceName 667 } else if skipg { 668 return ls.where(level+1, skipg) 669 } 670 line := "" 671 if proto != nil { 672 line = fmt.Sprintf("%v:", proto.DbgSourcePositions[cf.Pc-1]) 673 } 674 return fmt.Sprintf("%v:%v", sourcename, line) 675 } 676 677 func (ls *LState) stackTrace(level int) string { 678 buf := []string{} 679 header := "stack traceback:" 680 if ls.currentFrame != nil { 681 i := 0 682 for dbg, ok := ls.GetStack(i); ok; dbg, ok = ls.GetStack(i) { 683 cf := dbg.frame 684 buf = append(buf, fmt.Sprintf("\t%v in %v", ls.Where(i), ls.formattedFrameFuncName(cf))) 685 if !cf.Fn.IsG && cf.TailCall > 0 { 686 for tc := cf.TailCall; tc > 0; tc-- { 687 buf = append(buf, "\t(tailcall): ?") 688 i++ 689 } 690 } 691 i++ 692 } 693 } 694 buf = append(buf, fmt.Sprintf("\t%v: %v", "[G]", "?")) 695 buf = buf[intMax(0, intMin(level, len(buf))):] 696 if len(buf) > 20 { 697 newbuf := make([]string, 0, 20) 698 newbuf = append(newbuf, buf[0:7]...) 699 newbuf = append(newbuf, "\t...") 700 newbuf = append(newbuf, buf[len(buf)-7:]...) 701 buf = newbuf 702 } 703 return fmt.Sprintf("%s\n%s", header, strings.Join(buf, "\n")) 704 } 705 706 func (ls *LState) formattedFrameFuncName(fr *CallFrame) string { 707 name, ischunk := ls.frameFuncName(fr) 708 if ischunk { 709 return name 710 } 711 if name[0] != '(' && name[0] != '<' { 712 return fmt.Sprintf("function '%s'", name) 713 } 714 return fmt.Sprintf("function %s", name) 715 } 716 717 func (ls *LState) rawFrameFuncName(fr *CallFrame) string { 718 name, _ := ls.frameFuncName(fr) 719 return name 720 } 721 722 func (ls *LState) frameFuncName(fr *CallFrame) (string, bool) { 723 frame := fr.Parent 724 if frame == nil { 725 if ls.Parent == nil { 726 return "main chunk", true 727 } 728 return "corountine", true 729 } 730 if !frame.Fn.IsG { 731 pc := frame.Pc - 1 732 for _, call := range frame.Fn.Proto.DbgCalls { 733 if call.Pc == pc { 734 name := call.Name 735 if (name == "?" || fr.TailCall > 0) && !fr.Fn.IsG { 736 name = fmt.Sprintf("<%v:%v>", fr.Fn.Proto.SourceName, fr.Fn.Proto.LineDefined) 737 } 738 return name, false 739 } 740 } 741 } 742 if !fr.Fn.IsG { 743 return fmt.Sprintf("<%v:%v>", fr.Fn.Proto.SourceName, fr.Fn.Proto.LineDefined), false 744 } 745 return "(anonymous)", false 746 } 747 748 func (ls *LState) isStarted() bool { 749 return ls.currentFrame != nil 750 } 751 752 func (ls *LState) kill() { 753 ls.Dead = true 754 } 755 756 func (ls *LState) indexToReg(idx int) int { 757 base := ls.currentLocalBase() 758 if idx > 0 { 759 return base + idx - 1 760 } else if idx == 0 { 761 return -1 762 } else { 763 tidx := ls.reg.Top() + idx 764 if tidx < base { 765 return -1 766 } 767 return tidx 768 } 769 } 770 771 func (ls *LState) currentLocalBase() int { 772 base := 0 773 if ls.currentFrame != nil { 774 base = ls.currentFrame.LocalBase 775 } 776 return base 777 } 778 779 func (ls *LState) currentEnv() *LTable { 780 return ls.Env 781 /* 782 if ls.currentFrame == nil { 783 return ls.Env 784 } 785 return ls.currentFrame.Fn.Env 786 */ 787 } 788 789 func (ls *LState) rkValue(idx int) LValue { 790 /* 791 if OpIsK(idx) { 792 return ls.currentFrame.Fn.Proto.Constants[opIndexK(idx)] 793 } 794 return ls.reg.Get(ls.currentFrame.LocalBase + idx) 795 */ 796 if (idx & opBitRk) != 0 { 797 return ls.currentFrame.Fn.Proto.Constants[idx & ^opBitRk] 798 } 799 return ls.reg.array[ls.currentFrame.LocalBase+idx] 800 } 801 802 func (ls *LState) rkString(idx int) string { 803 if (idx & opBitRk) != 0 { 804 return ls.currentFrame.Fn.Proto.stringConstants[idx & ^opBitRk] 805 } 806 return string(ls.reg.array[ls.currentFrame.LocalBase+idx].(LString)) 807 } 808 809 func (ls *LState) closeUpvalues(idx int) { // +inline-start 810 if ls.uvcache != nil { 811 var prev *Upvalue 812 for uv := ls.uvcache; uv != nil; uv = uv.next { 813 if uv.index >= idx { 814 if prev != nil { 815 prev.next = nil 816 } else { 817 ls.uvcache = nil 818 } 819 uv.Close() 820 } 821 prev = uv 822 } 823 } 824 } // +inline-end 825 826 func (ls *LState) findUpvalue(idx int) *Upvalue { 827 var prev *Upvalue 828 var next *Upvalue 829 if ls.uvcache != nil { 830 for uv := ls.uvcache; uv != nil; uv = uv.next { 831 if uv.index == idx { 832 return uv 833 } 834 if uv.index > idx { 835 next = uv 836 break 837 } 838 prev = uv 839 } 840 } 841 uv := &Upvalue{reg: ls.reg, index: idx, closed: false} 842 if prev != nil { 843 prev.next = uv 844 } else { 845 ls.uvcache = uv 846 } 847 if next != nil { 848 uv.next = next 849 } 850 return uv 851 } 852 853 func (ls *LState) metatable(lvalue LValue, rawget bool) LValue { 854 var metatable LValue = LNil 855 switch obj := lvalue.(type) { 856 case *LTable: 857 metatable = obj.Metatable 858 case *LUserData: 859 metatable = obj.Metatable 860 default: 861 if table, ok := ls.G.builtinMts[int(obj.Type())]; ok { 862 metatable = table 863 } 864 } 865 866 if !rawget && metatable != LNil { 867 oldmt := metatable 868 if tb, ok := metatable.(*LTable); ok { 869 metatable = tb.RawGetString("__metatable") 870 if metatable == LNil { 871 metatable = oldmt 872 } 873 } 874 } 875 876 return metatable 877 } 878 879 func (ls *LState) metaOp1(lvalue LValue, event string) LValue { 880 if mt := ls.metatable(lvalue, true); mt != LNil { 881 if tb, ok := mt.(*LTable); ok { 882 return tb.RawGetString(event) 883 } 884 } 885 return LNil 886 } 887 888 func (ls *LState) metaOp2(value1, value2 LValue, event string) LValue { 889 if mt := ls.metatable(value1, true); mt != LNil { 890 if tb, ok := mt.(*LTable); ok { 891 if ret := tb.RawGetString(event); ret != LNil { 892 return ret 893 } 894 } 895 } 896 if mt := ls.metatable(value2, true); mt != LNil { 897 if tb, ok := mt.(*LTable); ok { 898 return tb.RawGetString(event) 899 } 900 } 901 return LNil 902 } 903 904 func (ls *LState) metaCall(lvalue LValue) (*LFunction, bool) { 905 if fn, ok := lvalue.(*LFunction); ok { 906 return fn, false 907 } 908 if fn, ok := ls.metaOp1(lvalue, "__call").(*LFunction); ok { 909 return fn, true 910 } 911 return nil, false 912 } 913 914 func (ls *LState) initCallFrame(cf *CallFrame) { // +inline-start 915 if cf.Fn.IsG { 916 ls.reg.SetTop(cf.LocalBase + cf.NArgs) 917 } else { 918 proto := cf.Fn.Proto 919 nargs := cf.NArgs 920 np := int(proto.NumParameters) 921 922 if nargs < np { 923 // default any missing arguments to nil 924 newSize := cf.LocalBase + np 925 // +inline-call ls.reg.checkSize newSize 926 for i := nargs; i < np; i++ { 927 ls.reg.array[cf.LocalBase+i] = LNil 928 } 929 nargs = np 930 ls.reg.top = newSize 931 } 932 933 if (proto.IsVarArg & VarArgIsVarArg) == 0 { 934 if nargs < int(proto.NumUsedRegisters) { 935 nargs = int(proto.NumUsedRegisters) 936 } 937 newSize := cf.LocalBase + nargs 938 // +inline-call ls.reg.checkSize newSize 939 for i := np; i < nargs; i++ { 940 ls.reg.array[cf.LocalBase+i] = LNil 941 } 942 ls.reg.top = cf.LocalBase + int(proto.NumUsedRegisters) 943 } else { 944 /* swap vararg positions: 945 closure 946 namedparam1 <- lbase 947 namedparam2 948 vararg1 949 vararg2 950 951 TO 952 953 closure 954 nil 955 nil 956 vararg1 957 vararg2 958 namedparam1 <- lbase 959 namedparam2 960 */ 961 nvarargs := nargs - np 962 if nvarargs < 0 { 963 nvarargs = 0 964 } 965 966 ls.reg.SetTop(cf.LocalBase + nargs + np) 967 for i := 0; i < np; i++ { 968 //ls.reg.Set(cf.LocalBase+nargs+i, ls.reg.Get(cf.LocalBase+i)) 969 ls.reg.array[cf.LocalBase+nargs+i] = ls.reg.array[cf.LocalBase+i] 970 //ls.reg.Set(cf.LocalBase+i, LNil) 971 ls.reg.array[cf.LocalBase+i] = LNil 972 } 973 974 if CompatVarArg { 975 ls.reg.SetTop(cf.LocalBase + nargs + np + 1) 976 if (proto.IsVarArg & VarArgNeedsArg) != 0 { 977 argtb := newLTable(nvarargs, 0) 978 for i := 0; i < nvarargs; i++ { 979 argtb.RawSetInt(i+1, ls.reg.Get(cf.LocalBase+np+i)) 980 } 981 argtb.RawSetString("n", LNumber(nvarargs)) 982 //ls.reg.Set(cf.LocalBase+nargs+np, argtb) 983 ls.reg.array[cf.LocalBase+nargs+np] = argtb 984 } else { 985 ls.reg.array[cf.LocalBase+nargs+np] = LNil 986 } 987 } 988 cf.LocalBase += nargs 989 maxreg := cf.LocalBase + int(proto.NumUsedRegisters) 990 ls.reg.SetTop(maxreg) 991 } 992 } 993 } // +inline-end 994 995 func (ls *LState) pushCallFrame(cf CallFrame, fn LValue, meta bool) { // +inline-start 996 if meta { 997 cf.NArgs++ 998 ls.reg.Insert(fn, cf.LocalBase) 999 } 1000 if cf.Fn == nil { 1001 ls.RaiseError("attempt to call a non-function object") 1002 } 1003 if ls.stack.IsFull() { 1004 ls.RaiseError("stack overflow") 1005 } 1006 ls.stack.Push(cf) 1007 newcf := ls.stack.Last() 1008 // +inline-call ls.initCallFrame newcf 1009 ls.currentFrame = newcf 1010 } // +inline-end 1011 1012 func (ls *LState) callR(nargs, nret, rbase int) { 1013 base := ls.reg.Top() - nargs - 1 1014 if rbase < 0 { 1015 rbase = base 1016 } 1017 lv := ls.reg.Get(base) 1018 fn, meta := ls.metaCall(lv) 1019 ls.pushCallFrame(CallFrame{ 1020 Fn: fn, 1021 Pc: 0, 1022 Base: base, 1023 LocalBase: base + 1, 1024 ReturnBase: rbase, 1025 NArgs: nargs, 1026 NRet: nret, 1027 Parent: ls.currentFrame, 1028 TailCall: 0, 1029 }, lv, meta) 1030 if ls.G.MainThread == nil { 1031 ls.G.MainThread = ls 1032 ls.G.CurrentThread = ls 1033 ls.mainLoop(ls, nil) 1034 } else { 1035 ls.mainLoop(ls, ls.currentFrame) 1036 } 1037 if nret != MultRet { 1038 ls.reg.SetTop(rbase + nret) 1039 } 1040 } 1041 1042 func (ls *LState) getField(obj LValue, key LValue) LValue { 1043 curobj := obj 1044 for i := 0; i < MaxTableGetLoop; i++ { 1045 tb, istable := curobj.(*LTable) 1046 if istable { 1047 ret := tb.RawGet(key) 1048 if ret != LNil { 1049 return ret 1050 } 1051 } 1052 metaindex := ls.metaOp1(curobj, "__index") 1053 if metaindex == LNil { 1054 if !istable { 1055 ls.RaiseError("attempt to index a non-table object(%v) with key '%s'", curobj.Type().String(), key.String()) 1056 } 1057 return LNil 1058 } 1059 if metaindex.Type() == LTFunction { 1060 ls.reg.Push(metaindex) 1061 ls.reg.Push(curobj) 1062 ls.reg.Push(key) 1063 ls.Call(2, 1) 1064 return ls.reg.Pop() 1065 } 1066 curobj = metaindex 1067 } 1068 ls.RaiseError("too many recursions in gettable") 1069 return nil 1070 } 1071 1072 func (ls *LState) getFieldString(obj LValue, key string) LValue { 1073 curobj := obj 1074 for i := 0; i < MaxTableGetLoop; i++ { 1075 tb, istable := curobj.(*LTable) 1076 if istable { 1077 ret := tb.RawGetString(key) 1078 if ret != LNil { 1079 return ret 1080 } 1081 } 1082 metaindex := ls.metaOp1(curobj, "__index") 1083 if metaindex == LNil { 1084 if !istable { 1085 ls.RaiseError("attempt to index a non-table object(%v) with key '%s'", curobj.Type().String(), key) 1086 } 1087 return LNil 1088 } 1089 if metaindex.Type() == LTFunction { 1090 ls.reg.Push(metaindex) 1091 ls.reg.Push(curobj) 1092 ls.reg.Push(LString(key)) 1093 ls.Call(2, 1) 1094 return ls.reg.Pop() 1095 } 1096 curobj = metaindex 1097 } 1098 ls.RaiseError("too many recursions in gettable") 1099 return nil 1100 } 1101 1102 func (ls *LState) setField(obj LValue, key LValue, value LValue) { 1103 curobj := obj 1104 for i := 0; i < MaxTableGetLoop; i++ { 1105 tb, istable := curobj.(*LTable) 1106 if istable { 1107 if tb.RawGet(key) != LNil { 1108 ls.RawSet(tb, key, value) 1109 return 1110 } 1111 } 1112 metaindex := ls.metaOp1(curobj, "__newindex") 1113 if metaindex == LNil { 1114 if !istable { 1115 ls.RaiseError("attempt to index a non-table object(%v) with key '%s'", curobj.Type().String(), key.String()) 1116 } 1117 ls.RawSet(tb, key, value) 1118 return 1119 } 1120 if metaindex.Type() == LTFunction { 1121 ls.reg.Push(metaindex) 1122 ls.reg.Push(curobj) 1123 ls.reg.Push(key) 1124 ls.reg.Push(value) 1125 ls.Call(3, 0) 1126 return 1127 } 1128 curobj = metaindex 1129 } 1130 ls.RaiseError("too many recursions in settable") 1131 } 1132 1133 func (ls *LState) setFieldString(obj LValue, key string, value LValue) { 1134 curobj := obj 1135 for i := 0; i < MaxTableGetLoop; i++ { 1136 tb, istable := curobj.(*LTable) 1137 if istable { 1138 if tb.RawGetString(key) != LNil { 1139 tb.RawSetString(key, value) 1140 return 1141 } 1142 } 1143 metaindex := ls.metaOp1(curobj, "__newindex") 1144 if metaindex == LNil { 1145 if !istable { 1146 ls.RaiseError("attempt to index a non-table object(%v) with key '%s'", curobj.Type().String(), key) 1147 } 1148 tb.RawSetString(key, value) 1149 return 1150 } 1151 if metaindex.Type() == LTFunction { 1152 ls.reg.Push(metaindex) 1153 ls.reg.Push(curobj) 1154 ls.reg.Push(LString(key)) 1155 ls.reg.Push(value) 1156 ls.Call(3, 0) 1157 return 1158 } 1159 curobj = metaindex 1160 } 1161 ls.RaiseError("too many recursions in settable") 1162 } 1163 1164 // NewState new state 1165 func NewState(opts ...Options) *LState { 1166 var ls *LState 1167 if len(opts) == 0 { 1168 ls = newLState(Options{ 1169 CallStackSize: CallStackSize, 1170 RegistrySize: RegistrySize, 1171 }) 1172 ls.OpenLibs() 1173 } else { 1174 if opts[0].CallStackSize < 1 { 1175 opts[0].CallStackSize = CallStackSize 1176 } 1177 if opts[0].RegistrySize < 128 { 1178 opts[0].RegistrySize = RegistrySize 1179 } 1180 if opts[0].RegistryMaxSize < opts[0].RegistrySize { 1181 opts[0].RegistryMaxSize = 0 // disable growth if max size is smaller than initial size 1182 } else { 1183 // if growth enabled, grow step is set 1184 if opts[0].RegistryGrowStep < 1 { 1185 opts[0].RegistryGrowStep = RegistryGrowStep 1186 } 1187 } 1188 ls = newLState(opts[0]) 1189 if !opts[0].SkipOpenLibs { 1190 ls.OpenLibs() 1191 } 1192 } 1193 return ls 1194 } 1195 1196 // IsClosed 是否关闭 1197 func (ls *LState) IsClosed() bool { 1198 return ls.stack == nil 1199 } 1200 1201 // Close 关闭 1202 func (ls *LState) Close() { 1203 atomic.AddInt32(&ls.stop, 1) 1204 for _, file := range ls.G.tempFiles { 1205 // ignore errors in these operations 1206 file.Close() 1207 os.Remove(file.Name()) 1208 } 1209 ls.stack.FreeAll() 1210 ls.stack = nil 1211 } 1212 1213 // GetTop 获取 top 1214 func (ls *LState) GetTop() int { 1215 return ls.reg.Top() - ls.currentLocalBase() 1216 } 1217 1218 // SetTop 设置 top 1219 func (ls *LState) SetTop(idx int) { 1220 base := ls.currentLocalBase() 1221 newtop := ls.indexToReg(idx) + 1 1222 if newtop < base { 1223 ls.reg.SetTop(base) 1224 } else { 1225 ls.reg.SetTop(newtop) 1226 } 1227 } 1228 1229 // Replace 替换 1230 func (ls *LState) Replace(idx int, value LValue) { 1231 base := ls.currentLocalBase() 1232 if idx > 0 { 1233 reg := base + idx - 1 1234 if reg < ls.reg.Top() { 1235 ls.reg.Set(reg, value) 1236 } 1237 } else if idx == 0 { 1238 } else if idx > RegistryIndex { 1239 if tidx := ls.reg.Top() + idx; tidx >= base { 1240 ls.reg.Set(tidx, value) 1241 } 1242 } else { 1243 switch idx { 1244 case RegistryIndex: 1245 if tb, ok := value.(*LTable); ok { 1246 ls.G.Registry = tb 1247 } else { 1248 ls.RaiseError("registry must be a table(%v)", value.Type().String()) 1249 } 1250 case EnvironIndex: 1251 if ls.currentFrame == nil { 1252 ls.RaiseError("no calling environment") 1253 } 1254 if tb, ok := value.(*LTable); ok { 1255 ls.currentFrame.Fn.Env = tb 1256 } else { 1257 ls.RaiseError("environment must be a table(%v)", value.Type().String()) 1258 } 1259 case GlobalsIndex: 1260 if tb, ok := value.(*LTable); ok { 1261 ls.G.Global = tb 1262 } else { 1263 ls.RaiseError("_G must be a table(%v)", value.Type().String()) 1264 } 1265 default: 1266 fn := ls.currentFrame.Fn 1267 index := GlobalsIndex - idx - 1 1268 if index < len(fn.Upvalues) { 1269 fn.Upvalues[index].SetValue(value) 1270 } 1271 } 1272 } 1273 } 1274 1275 // Get 获取 1276 func (ls *LState) Get(idx int) LValue { 1277 base := ls.currentLocalBase() 1278 if idx > 0 { 1279 reg := base + idx - 1 1280 if reg < ls.reg.Top() { 1281 return ls.reg.Get(reg) 1282 } 1283 return LNil 1284 } else if idx == 0 { 1285 return LNil 1286 } else if idx > RegistryIndex { 1287 tidx := ls.reg.Top() + idx 1288 if tidx < base { 1289 return LNil 1290 } 1291 return ls.reg.Get(tidx) 1292 } else { 1293 switch idx { 1294 case RegistryIndex: 1295 return ls.G.Registry 1296 case EnvironIndex: 1297 if ls.currentFrame == nil { 1298 return ls.Env 1299 } 1300 return ls.currentFrame.Fn.Env 1301 case GlobalsIndex: 1302 return ls.G.Global 1303 default: 1304 fn := ls.currentFrame.Fn 1305 index := GlobalsIndex - idx - 1 1306 if index < len(fn.Upvalues) { 1307 return fn.Upvalues[index].Value() 1308 } 1309 return LNil 1310 } 1311 } 1312 //return LNil 1313 } 1314 1315 // Push 推入 1316 func (ls *LState) Push(value LValue) { 1317 ls.reg.Push(value) 1318 } 1319 1320 // Pop 推出 1321 func (ls *LState) Pop(n int) { 1322 for i := 0; i < n; i++ { 1323 if ls.GetTop() == 0 { 1324 ls.RaiseError("register underflow") 1325 } 1326 ls.reg.Pop() 1327 } 1328 } 1329 1330 // Insert 插入 1331 func (ls *LState) Insert(value LValue, index int) { 1332 reg := ls.indexToReg(index) 1333 top := ls.reg.Top() 1334 if reg >= top { 1335 ls.reg.Set(reg, value) 1336 return 1337 } 1338 if reg <= ls.currentLocalBase() { 1339 reg = ls.currentLocalBase() 1340 } 1341 top-- 1342 for ; top >= reg; top-- { 1343 ls.reg.Set(top+1, ls.reg.Get(top)) 1344 } 1345 ls.reg.Set(reg, value) 1346 } 1347 1348 // Remove 删除 1349 func (ls *LState) Remove(index int) { 1350 reg := ls.indexToReg(index) 1351 top := ls.reg.Top() 1352 switch { 1353 case reg >= top: 1354 return 1355 case reg < ls.currentLocalBase(): 1356 return 1357 case reg == top-1: 1358 ls.Pop(1) 1359 return 1360 } 1361 for i := reg; i < top-1; i++ { 1362 ls.reg.Set(i, ls.reg.Get(i+1)) 1363 } 1364 ls.reg.SetTop(top - 1) 1365 } 1366 1367 // NewTable new table 1368 func (ls *LState) NewTable() *LTable { 1369 return newLTable(defaultArrayCap, defaultHashCap) 1370 } 1371 1372 // CreateTable create table 1373 func (ls *LState) CreateTable(acap, hcap int) *LTable { 1374 return newLTable(acap, hcap) 1375 } 1376 1377 // NewThread returns a new LState that shares with the original state all global objects. 1378 // 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. 1379 func (ls *LState) NewThread() (*LState, context.CancelFunc) { 1380 thread := newLState(ls.Options) 1381 thread.G = ls.G 1382 thread.Env = ls.Env 1383 var f context.CancelFunc = nil 1384 if ls.ctx != nil { 1385 thread.mainLoop = mainLoopWithContext 1386 thread.ctx, f = context.WithCancel(ls.ctx) 1387 } 1388 return thread, f 1389 } 1390 1391 // NewFunctionFromProto new func 1392 func (ls *LState) NewFunctionFromProto(proto *FunctionProto) *LFunction { 1393 return newLFunctionL(proto, ls.Env, int(proto.NumUpvalues)) 1394 } 1395 1396 // NewUserData new user data 1397 func (ls *LState) NewUserData() *LUserData { 1398 return &LUserData{ 1399 Env: ls.currentEnv(), 1400 Metatable: LNil, 1401 } 1402 } 1403 1404 // NewFunction new func 1405 func (ls *LState) NewFunction(fn LGFunction) *LFunction { 1406 return newLFunctionG(fn, ls.currentEnv(), 0) 1407 } 1408 1409 // NewClosure new closure 1410 func (ls *LState) NewClosure(fn LGFunction, upvalues ...LValue) *LFunction { 1411 cl := newLFunctionG(fn, ls.currentEnv(), len(upvalues)) 1412 for i, lv := range upvalues { 1413 cl.Upvalues[i] = &Upvalue{} 1414 cl.Upvalues[i].Close() 1415 cl.Upvalues[i].SetValue(lv) 1416 } 1417 return cl 1418 } 1419 1420 // ToBool to bool 1421 func (ls *LState) ToBool(n int) bool { 1422 return LVAsBool(ls.Get(n)) 1423 } 1424 1425 // ToInt to int 1426 func (ls *LState) ToInt(n int) int { 1427 if lv, ok := ls.Get(n).(LNumber); ok { 1428 return int(lv) 1429 } 1430 if lv, ok := ls.Get(n).(LString); ok { 1431 if num, err := parseNumber(string(lv)); err == nil { 1432 return int(num) 1433 } 1434 } 1435 return 0 1436 } 1437 1438 // ToInt64 to int64 1439 func (ls *LState) ToInt64(n int) int64 { 1440 if lv, ok := ls.Get(n).(LNumber); ok { 1441 return int64(lv) 1442 } 1443 if lv, ok := ls.Get(n).(LString); ok { 1444 if num, err := parseNumber(string(lv)); err == nil { 1445 return int64(num) 1446 } 1447 } 1448 return 0 1449 } 1450 1451 // ToNumber to number 1452 func (ls *LState) ToNumber(n int) LNumber { 1453 return LVAsNumber(ls.Get(n)) 1454 } 1455 1456 // ToString to string 1457 func (ls *LState) ToString(n int) string { 1458 return LVAsString(ls.Get(n)) 1459 } 1460 1461 // ToTable to table 1462 func (ls *LState) ToTable(n int) *LTable { 1463 if lv, ok := ls.Get(n).(*LTable); ok { 1464 return lv 1465 } 1466 return nil 1467 } 1468 1469 // ToFunction to func 1470 func (ls *LState) ToFunction(n int) *LFunction { 1471 if lv, ok := ls.Get(n).(*LFunction); ok { 1472 return lv 1473 } 1474 return nil 1475 } 1476 1477 // ToUserData to user data 1478 func (ls *LState) ToUserData(n int) *LUserData { 1479 if lv, ok := ls.Get(n).(*LUserData); ok { 1480 return lv 1481 } 1482 return nil 1483 } 1484 1485 // ToThread to thread 1486 func (ls *LState) ToThread(n int) *LState { 1487 if lv, ok := ls.Get(n).(*LState); ok { 1488 return lv 1489 } 1490 return nil 1491 } 1492 1493 func (ls *LState) registryOverflow() { 1494 ls.RaiseError("registry overflow") 1495 } 1496 1497 // RaiseError This function is equivalent to luaL_error( http://www.lua.org/manual/5.1/manual.html#luaL_error ). 1498 func (ls *LState) RaiseError(format string, args ...interface{}) { 1499 ls.raiseError(1, format, args...) 1500 } 1501 1502 // Error This function is equivalent to lua_error( http://www.lua.org/manual/5.1/manual.html#lua_error ). 1503 func (ls *LState) Error(lv LValue, level int) { 1504 if str, ok := lv.(LString); ok { 1505 ls.raiseError(level, string(str)) 1506 } else { 1507 if !ls.hasErrorFunc { 1508 ls.closeAllUpvalues() 1509 } 1510 ls.Push(lv) 1511 ls.Panic(ls) 1512 } 1513 } 1514 1515 // GetInfo 获取信息 1516 func (ls *LState) GetInfo(what string, dbg *Debug, fn LValue) (LValue, error) { 1517 if !strings.HasPrefix(what, ">") { 1518 fn = dbg.frame.Fn 1519 } else { 1520 what = what[1:] 1521 } 1522 f, ok := fn.(*LFunction) 1523 if !ok { 1524 return LNil, newAPIErrorS(APIErrorRun, "can not get debug info(an object in not a function)") 1525 } 1526 1527 retfn := false 1528 for _, c := range what { 1529 switch c { 1530 case 'f': 1531 retfn = true 1532 case 'S': 1533 if dbg.frame != nil && dbg.frame.Parent == nil { 1534 dbg.What = "main" 1535 } else if f.IsG { 1536 dbg.What = "G" 1537 } else if dbg.frame != nil && dbg.frame.TailCall > 0 { 1538 dbg.What = "tail" 1539 } else { 1540 dbg.What = "Lua" 1541 } 1542 if !f.IsG { 1543 dbg.Source = f.Proto.SourceName 1544 dbg.LineDefined = f.Proto.LineDefined 1545 dbg.LastLineDefined = f.Proto.LastLineDefined 1546 } 1547 case 'l': 1548 if !f.IsG && dbg.frame != nil { 1549 if dbg.frame.Pc > 0 { 1550 dbg.CurrentLine = f.Proto.DbgSourcePositions[dbg.frame.Pc-1] 1551 } 1552 } else { 1553 dbg.CurrentLine = -1 1554 } 1555 case 'u': 1556 dbg.NUpvalues = len(f.Upvalues) 1557 case 'n': 1558 if dbg.frame != nil { 1559 dbg.Name = ls.rawFrameFuncName(dbg.frame) 1560 } 1561 default: 1562 return LNil, newAPIErrorS(APIErrorRun, "invalid what: "+string(c)) 1563 } 1564 } 1565 1566 if retfn { 1567 return f, nil 1568 } 1569 return LNil, nil 1570 1571 } 1572 1573 // GetStack 获取栈 1574 func (ls *LState) GetStack(level int) (*Debug, bool) { 1575 frame := ls.currentFrame 1576 for ; level > 0 && frame != nil; frame = frame.Parent { 1577 level-- 1578 if !frame.Fn.IsG { 1579 level -= frame.TailCall 1580 } 1581 } 1582 1583 if level == 0 && frame != nil { 1584 return &Debug{frame: frame}, true 1585 } else if level < 0 && ls.stack.Sp() > 0 { 1586 return &Debug{frame: ls.stack.At(0)}, true 1587 } 1588 return &Debug{}, false 1589 } 1590 1591 // GetLocal get local 1592 func (ls *LState) GetLocal(dbg *Debug, no int) (string, LValue) { 1593 frame := dbg.frame 1594 if name := ls.findLocal(frame, no); len(name) > 0 { 1595 return name, ls.reg.Get(frame.LocalBase + no - 1) 1596 } 1597 return "", LNil 1598 } 1599 1600 // SetLocal set local 1601 func (ls *LState) SetLocal(dbg *Debug, no int, lv LValue) string { 1602 frame := dbg.frame 1603 if name := ls.findLocal(frame, no); len(name) > 0 { 1604 ls.reg.Set(frame.LocalBase+no-1, lv) 1605 return name 1606 } 1607 return "" 1608 } 1609 1610 // GetUpvalue get upvalue 1611 func (ls *LState) GetUpvalue(fn *LFunction, no int) (string, LValue) { 1612 if fn.IsG { 1613 return "", LNil 1614 } 1615 1616 no-- 1617 if no >= 0 && no < len(fn.Upvalues) { 1618 return fn.Proto.DbgUpvalues[no], fn.Upvalues[no].Value() 1619 } 1620 return "", LNil 1621 } 1622 1623 // SetUpvalue set upvalue 1624 func (ls *LState) SetUpvalue(fn *LFunction, no int, lv LValue) string { 1625 if fn.IsG { 1626 return "" 1627 } 1628 1629 no-- 1630 if no >= 0 && no < len(fn.Upvalues) { 1631 fn.Upvalues[no].SetValue(lv) 1632 return fn.Proto.DbgUpvalues[no] 1633 } 1634 return "" 1635 } 1636 1637 // GetFEnv get fenv 1638 func (ls *LState) GetFEnv(obj LValue) LValue { 1639 switch lv := obj.(type) { 1640 case *LFunction: 1641 return lv.Env 1642 case *LUserData: 1643 return lv.Env 1644 case *LState: 1645 return lv.Env 1646 } 1647 return LNil 1648 } 1649 1650 // SetFEnv set fenv 1651 func (ls *LState) SetFEnv(obj LValue, env LValue) { 1652 tb, ok := env.(*LTable) 1653 if !ok { 1654 ls.RaiseError("cannot use %v as an environment", env.Type().String()) 1655 } 1656 1657 switch lv := obj.(type) { 1658 case *LFunction: 1659 lv.Env = tb 1660 case *LUserData: 1661 lv.Env = tb 1662 case *LState: 1663 lv.Env = tb 1664 } 1665 /* do nothing */ 1666 } 1667 1668 // RawGet raw get 1669 func (ls *LState) RawGet(tb *LTable, key LValue) LValue { 1670 return tb.RawGet(key) 1671 } 1672 1673 // RawGetInt raw get int 1674 func (ls *LState) RawGetInt(tb *LTable, key int) LValue { 1675 return tb.RawGetInt(key) 1676 } 1677 1678 // GetField get field 1679 func (ls *LState) GetField(obj LValue, skey string) LValue { 1680 return ls.getFieldString(obj, skey) 1681 } 1682 1683 // GetTable get table 1684 func (ls *LState) GetTable(obj LValue, key LValue) LValue { 1685 return ls.getField(obj, key) 1686 } 1687 1688 // RawSet raw set 1689 func (ls *LState) RawSet(tb *LTable, key LValue, value LValue) { 1690 if n, ok := key.(LNumber); ok && math.IsNaN(float64(n)) { 1691 ls.RaiseError("table index is NaN") 1692 } else if key == LNil { 1693 ls.RaiseError("table index is nil") 1694 } 1695 tb.RawSet(key, value) 1696 } 1697 1698 // RawSetInt raw set int 1699 func (ls *LState) RawSetInt(tb *LTable, key int, value LValue) { 1700 tb.RawSetInt(key, value) 1701 } 1702 1703 // SetField set field 1704 func (ls *LState) SetField(obj LValue, key string, value LValue) { 1705 ls.setFieldString(obj, key, value) 1706 } 1707 1708 // SetTable set table 1709 func (ls *LState) SetTable(obj LValue, key LValue, value LValue) { 1710 ls.setField(obj, key, value) 1711 } 1712 1713 // ForEach for each 1714 func (ls *LState) ForEach(tb *LTable, cb func(LValue, LValue)) { 1715 tb.ForEach(cb) 1716 } 1717 1718 // GetGlobal get global 1719 func (ls *LState) GetGlobal(name string) LValue { 1720 return ls.GetField(ls.Get(GlobalsIndex), name) 1721 } 1722 1723 // SetGlobal set global 1724 func (ls *LState) SetGlobal(name string, value LValue) { 1725 ls.SetField(ls.Get(GlobalsIndex), name, value) 1726 } 1727 1728 // Next next 1729 func (ls *LState) Next(tb *LTable, key LValue) (LValue, LValue) { 1730 return tb.Next(key) 1731 } 1732 1733 // ObjLen obj len 1734 func (ls *LState) ObjLen(v1 LValue) int { 1735 if v1.Type() == LTString { 1736 return len(string(v1.(LString))) 1737 } 1738 op := ls.metaOp1(v1, "__len") 1739 if op.Type() == LTFunction { 1740 ls.Push(op) 1741 ls.Push(v1) 1742 ls.Call(1, 1) 1743 ret := ls.reg.Pop() 1744 if ret.Type() == LTNumber { 1745 return int(ret.(LNumber)) 1746 } 1747 } else if v1.Type() == LTTable { 1748 return v1.(*LTable).Len() 1749 } 1750 return 0 1751 } 1752 1753 // Concat 连接 1754 func (ls *LState) Concat(values ...LValue) string { 1755 top := ls.reg.Top() 1756 for _, value := range values { 1757 ls.reg.Push(value) 1758 } 1759 ret := stringConcat(ls, len(values), ls.reg.Top()-1) 1760 ls.reg.SetTop(top) 1761 return LVAsString(ret) 1762 } 1763 1764 // LessThan less than 1765 func (ls *LState) LessThan(lhs, rhs LValue) bool { 1766 return lessThan(ls, lhs, rhs) 1767 } 1768 1769 // Equal equal 1770 func (ls *LState) Equal(lhs, rhs LValue) bool { 1771 return equals(ls, lhs, rhs, false) 1772 } 1773 1774 // RawEqual raw equal 1775 func (ls *LState) RawEqual(lhs, rhs LValue) bool { 1776 return equals(ls, lhs, rhs, true) 1777 } 1778 1779 // Register ragister 1780 func (ls *LState) Register(name string, fn LGFunction) { 1781 ls.SetGlobal(name, ls.NewFunction(fn)) 1782 } 1783 1784 // Load load 1785 func (ls *LState) Load(reader io.Reader, name string) (*LFunction, error) { 1786 chunk, err := parse.Parse(reader, name) 1787 if err != nil { 1788 return nil, newAPIErrorE(APIErrorSyntax, err) 1789 } 1790 proto, err := Compile(chunk, name) 1791 if err != nil { 1792 return nil, newAPIErrorE(APIErrorSyntax, err) 1793 } 1794 return newLFunctionL(proto, ls.currentEnv(), 0), nil 1795 } 1796 1797 // Call call 1798 func (ls *LState) Call(nargs, nret int) { 1799 ls.callR(nargs, nret, -1) 1800 } 1801 1802 // PCall pcall 1803 func (ls *LState) PCall(nargs, nret int, errfunc *LFunction) (err error) { 1804 err = nil 1805 sp := ls.stack.Sp() 1806 base := ls.reg.Top() - nargs - 1 1807 oldpanic := ls.Panic 1808 ls.Panic = panicWithoutTraceback 1809 if errfunc != nil { 1810 ls.hasErrorFunc = true 1811 } 1812 defer func() { 1813 ls.Panic = oldpanic 1814 ls.hasErrorFunc = false 1815 rcv := recover() 1816 if rcv != nil { 1817 if _, ok := rcv.(*APIError); !ok { 1818 err = newAPIErrorS(APIErrorPanic, fmt.Sprint(rcv)) 1819 if ls.Options.IncludeGoStackTrace { 1820 buf := make([]byte, 4096) 1821 runtime.Stack(buf, false) 1822 err.(*APIError).StackTrace = strings.Trim(string(buf), "\000") + "\n" + ls.stackTrace(0) 1823 } 1824 } else { 1825 err = rcv.(*APIError) 1826 } 1827 if errfunc != nil { 1828 ls.Push(errfunc) 1829 ls.Push(err.(*APIError).Object) 1830 ls.Panic = panicWithoutTraceback 1831 defer func() { 1832 ls.Panic = oldpanic 1833 rcv := recover() 1834 if rcv != nil { 1835 if _, ok := rcv.(*APIError); !ok { 1836 err = newAPIErrorS(APIErrorPanic, fmt.Sprint(rcv)) 1837 if ls.Options.IncludeGoStackTrace { 1838 buf := make([]byte, 4096) 1839 runtime.Stack(buf, false) 1840 err.(*APIError).StackTrace = strings.Trim(string(buf), "\000") + ls.stackTrace(0) 1841 } 1842 } else { 1843 err = rcv.(*APIError) 1844 err.(*APIError).StackTrace = ls.stackTrace(0) 1845 } 1846 } 1847 }() 1848 ls.Call(1, 1) 1849 err = newAPIError(APIErrorError, ls.Get(-1)) 1850 } else if len(err.(*APIError).StackTrace) == 0 { 1851 err.(*APIError).StackTrace = ls.stackTrace(0) 1852 } 1853 ls.stack.SetSp(sp) 1854 ls.currentFrame = ls.stack.Last() 1855 ls.reg.SetTop(base) 1856 } 1857 ls.stack.SetSp(sp) 1858 if sp == 0 { 1859 ls.currentFrame = nil 1860 } 1861 }() 1862 1863 ls.Call(nargs, nret) 1864 1865 return 1866 } 1867 1868 // GPCall gpcall 1869 func (ls *LState) GPCall(fn LGFunction, data LValue) error { 1870 ls.Push(newLFunctionG(fn, ls.currentEnv(), 0)) 1871 ls.Push(data) 1872 return ls.PCall(1, MultRet, nil) 1873 } 1874 1875 // CallByParam call by param 1876 func (ls *LState) CallByParam(cp P, args ...LValue) error { 1877 ls.Push(cp.Fn) 1878 for _, arg := range args { 1879 ls.Push(arg) 1880 } 1881 1882 if cp.Protect { 1883 return ls.PCall(len(args), cp.NRet, cp.Handler) 1884 } 1885 ls.Call(len(args), cp.NRet) 1886 return nil 1887 } 1888 1889 // GetMetatable 获取元组 1890 func (ls *LState) GetMetatable(obj LValue) LValue { 1891 return ls.metatable(obj, false) 1892 } 1893 1894 // SetMetatable 设置元组 1895 func (ls *LState) SetMetatable(obj LValue, mt LValue) { 1896 switch mt.(type) { 1897 case *LNilType, *LTable: 1898 default: 1899 ls.RaiseError("metatable must be a table or nil, but got %v", mt.Type().String()) 1900 } 1901 1902 switch v := obj.(type) { 1903 case *LTable: 1904 v.Metatable = mt 1905 case *LUserData: 1906 v.Metatable = mt 1907 default: 1908 ls.G.builtinMts[int(obj.Type())] = mt 1909 } 1910 } 1911 1912 // Status 状态 1913 func (ls *LState) Status(th *LState) string { 1914 status := "suspended" 1915 if th.Dead { 1916 status = "dead" 1917 } else if ls.G.CurrentThread == th { 1918 status = "running" 1919 } else if ls.Parent == th { 1920 status = "normal" 1921 } 1922 return status 1923 } 1924 1925 // Resume 重新开始 1926 func (ls *LState) Resume(th *LState, fn *LFunction, args ...LValue) (ResumeState, []LValue, error) { 1927 isstarted := th.isStarted() 1928 if !isstarted { 1929 base := 0 1930 th.stack.Push(CallFrame{ 1931 Fn: fn, 1932 Pc: 0, 1933 Base: base, 1934 LocalBase: base + 1, 1935 ReturnBase: base, 1936 NArgs: 0, 1937 NRet: MultRet, 1938 Parent: nil, 1939 TailCall: 0, 1940 }) 1941 } 1942 1943 if ls.G.CurrentThread == th { 1944 return ResumeError, nil, newAPIErrorS(APIErrorRun, "can not resume a running thread") 1945 } 1946 if th.Dead { 1947 return ResumeError, nil, newAPIErrorS(APIErrorRun, "can not resume a dead thread") 1948 } 1949 th.Parent = ls 1950 ls.G.CurrentThread = th 1951 if !isstarted { 1952 cf := th.stack.Last() 1953 th.currentFrame = cf 1954 th.SetTop(0) 1955 for _, arg := range args { 1956 th.Push(arg) 1957 } 1958 cf.NArgs = len(args) 1959 th.initCallFrame(cf) 1960 th.Panic = panicWithoutTraceback 1961 } else { 1962 for _, arg := range args { 1963 th.Push(arg) 1964 } 1965 } 1966 top := ls.GetTop() 1967 threadRun(th) 1968 haserror := LVIsFalse(ls.Get(top + 1)) 1969 ret := make([]LValue, 0, ls.GetTop()) 1970 for idx := top + 2; idx <= ls.GetTop(); idx++ { 1971 ret = append(ret, ls.Get(idx)) 1972 } 1973 if len(ret) == 0 { 1974 ret = append(ret, LNil) 1975 } 1976 ls.SetTop(top) 1977 1978 if haserror { 1979 return ResumeError, nil, newAPIError(APIErrorRun, ret[0]) 1980 } else if th.stack.IsEmpty() { 1981 return ResumeOK, ret, nil 1982 } 1983 return ResumeYield, ret, nil 1984 } 1985 1986 // Yield 暂停 1987 func (ls *LState) Yield(values ...LValue) int { 1988 ls.SetTop(0) 1989 for _, lv := range values { 1990 ls.Push(lv) 1991 } 1992 return -1 1993 } 1994 1995 // XMoveTo move to 1996 func (ls *LState) XMoveTo(other *LState, n int) { 1997 if ls == other { 1998 return 1999 } 2000 top := ls.GetTop() 2001 n = intMin(n, top) 2002 for i := n; i > 0; i-- { 2003 other.Push(ls.Get(top - i + 1)) 2004 } 2005 ls.SetTop(top - n) 2006 } 2007 2008 // SetMx Set maximum memory size. This function can only be called from the main thread. 2009 func (ls *LState) SetMx(mx int) { 2010 if ls.Parent != nil { 2011 ls.RaiseError("sub threads are not allowed to set a memory limit") 2012 } 2013 go func() { 2014 limit := uint64(mx * 1024 * 1024) //MB 2015 var s runtime.MemStats 2016 for atomic.LoadInt32(&ls.stop) == 0 { 2017 runtime.ReadMemStats(&s) 2018 if s.Alloc >= limit { 2019 fmt.Println("out of memory") 2020 os.Exit(3) 2021 } 2022 time.Sleep(100 * time.Millisecond) 2023 } 2024 }() 2025 } 2026 2027 // SetContext set a context ctx to this LState. The provided ctx must be non-nil. 2028 func (ls *LState) SetContext(ctx context.Context) { 2029 ls.mainLoop = mainLoopWithContext 2030 ls.ctx = ctx 2031 } 2032 2033 // Context returns the LState's context. To change the context, use WithContext. 2034 func (ls *LState) Context() context.Context { 2035 return ls.ctx 2036 } 2037 2038 // RemoveContext removes the context associated with this LState and returns this context. 2039 func (ls *LState) RemoveContext() context.Context { 2040 oldctx := ls.ctx 2041 ls.mainLoop = mainLoop 2042 ls.ctx = nil 2043 return oldctx 2044 } 2045 2046 // ToChannel Converts the Lua value at the given acceptable index to the chan LValue. 2047 func (ls *LState) ToChannel(n int) chan LValue { 2048 if lv, ok := ls.Get(n).(LChannel); ok { 2049 return (chan LValue)(lv) 2050 } 2051 return nil 2052 } 2053 2054 // RemoveCallerFrame removes the stack frame above the current stack frame. This is useful in tail calls. It returns 2055 // the new current frame. 2056 func (ls *LState) RemoveCallerFrame() *CallFrame { 2057 cs := ls.stack 2058 sp := cs.Sp() 2059 parentFrame := cs.At(sp - 2) 2060 currentFrame := cs.At(sp - 1) 2061 parentsParentFrame := parentFrame.Parent 2062 *parentFrame = *currentFrame 2063 parentFrame.Parent = parentsParentFrame 2064 parentFrame.Idx = sp - 2 2065 cs.Pop() 2066 return parentFrame 2067 }