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