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