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