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