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