github.com/yuin/gopher-lua@v1.1.2-0.20231212122839-2348fd042596/vm.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 "math" 10 "strings" 11 ) 12 13 func mainLoop(L *LState, baseframe *callFrame) { 14 var inst uint32 15 var cf *callFrame 16 17 if L.stack.IsEmpty() { 18 return 19 } 20 21 L.currentFrame = L.stack.Last() 22 if L.currentFrame.Fn.IsG { 23 callGFunction(L, false) 24 return 25 } 26 27 for { 28 cf = L.currentFrame 29 inst = cf.Fn.Proto.Code[cf.Pc] 30 cf.Pc++ 31 if jumpTable[int(inst>>26)](L, inst, baseframe) == 1 { 32 return 33 } 34 } 35 } 36 37 func mainLoopWithContext(L *LState, baseframe *callFrame) { 38 var inst uint32 39 var cf *callFrame 40 41 if L.stack.IsEmpty() { 42 return 43 } 44 45 L.currentFrame = L.stack.Last() 46 if L.currentFrame.Fn.IsG { 47 callGFunction(L, false) 48 return 49 } 50 51 for { 52 cf = L.currentFrame 53 inst = cf.Fn.Proto.Code[cf.Pc] 54 cf.Pc++ 55 select { 56 case <-L.ctx.Done(): 57 L.RaiseError(L.ctx.Err().Error()) 58 return 59 default: 60 if jumpTable[int(inst>>26)](L, inst, baseframe) == 1 { 61 return 62 } 63 } 64 } 65 } 66 67 // regv is the first target register to copy the return values to. 68 // It can be reg.top, indicating that the copied values are going into new registers, or it can be below reg.top 69 // Indicating that the values should be within the existing registers. 70 // b is the available number of return values + 1. 71 // n is the desired number of return values. 72 // If n more than the available return values then the extra values are set to nil. 73 // When this function returns the top of the registry will be set to regv+n. 74 func copyReturnValues(L *LState, regv, start, n, b int) { // +inline-start 75 if b == 1 { 76 // this section is inlined by go-inline 77 // source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go' 78 { 79 rg := L.reg 80 regm := regv 81 newSize := regm + n 82 // this section is inlined by go-inline 83 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 84 { 85 requiredSize := newSize 86 if requiredSize > cap(rg.array) { 87 rg.resize(requiredSize) 88 } 89 } 90 for i := 0; i < n; i++ { 91 rg.array[regm+i] = LNil 92 } 93 // values beyond top don't need to be valid LValues, so setting them to nil is fine 94 // setting them to nil rather than LNil lets us invoke the golang memclr opto 95 oldtop := rg.top 96 rg.top = regm + n 97 if rg.top < oldtop { 98 nilRange := rg.array[rg.top:oldtop] 99 for i := range nilRange { 100 nilRange[i] = nil 101 } 102 } 103 } 104 } else { 105 // this section is inlined by go-inline 106 // source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go' 107 { 108 rg := L.reg 109 limit := -1 110 newSize := regv + n 111 // this section is inlined by go-inline 112 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 113 { 114 requiredSize := newSize 115 if requiredSize > cap(rg.array) { 116 rg.resize(requiredSize) 117 } 118 } 119 if limit == -1 || limit > rg.top { 120 limit = rg.top 121 } 122 for i := 0; i < n; i++ { 123 srcIdx := start + i 124 if srcIdx >= limit || srcIdx < 0 { 125 rg.array[regv+i] = LNil 126 } else { 127 rg.array[regv+i] = rg.array[srcIdx] 128 } 129 } 130 131 // values beyond top don't need to be valid LValues, so setting them to nil is fine 132 // setting them to nil rather than LNil lets us invoke the golang memclr opto 133 oldtop := rg.top 134 rg.top = regv + n 135 if rg.top < oldtop { 136 nilRange := rg.array[rg.top:oldtop] 137 for i := range nilRange { 138 nilRange[i] = nil 139 } 140 } 141 } 142 if b > 1 && n > (b-1) { 143 // this section is inlined by go-inline 144 // source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go' 145 { 146 rg := L.reg 147 regm := regv + b - 1 148 n := n - (b - 1) 149 newSize := regm + n 150 // this section is inlined by go-inline 151 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 152 { 153 requiredSize := newSize 154 if requiredSize > cap(rg.array) { 155 rg.resize(requiredSize) 156 } 157 } 158 for i := 0; i < n; i++ { 159 rg.array[regm+i] = LNil 160 } 161 // values beyond top don't need to be valid LValues, so setting them to nil is fine 162 // setting them to nil rather than LNil lets us invoke the golang memclr opto 163 oldtop := rg.top 164 rg.top = regm + n 165 if rg.top < oldtop { 166 nilRange := rg.array[rg.top:oldtop] 167 for i := range nilRange { 168 nilRange[i] = nil 169 } 170 } 171 } 172 } 173 } 174 } // +inline-end 175 176 func switchToParentThread(L *LState, nargs int, haserror bool, kill bool) { 177 parent := L.Parent 178 if parent == nil { 179 L.RaiseError("can not yield from outside of a coroutine") 180 } 181 L.G.CurrentThread = parent 182 L.Parent = nil 183 if !L.wrapped { 184 if haserror { 185 parent.Push(LFalse) 186 } else { 187 parent.Push(LTrue) 188 } 189 } 190 L.XMoveTo(parent, nargs) 191 L.stack.Pop() 192 offset := L.currentFrame.LocalBase - L.currentFrame.ReturnBase 193 L.currentFrame = L.stack.Last() 194 L.reg.SetTop(L.reg.Top() - offset) // remove 'yield' function(including tailcalled functions) 195 if kill { 196 L.kill() 197 } 198 } 199 200 func callGFunction(L *LState, tailcall bool) bool { 201 frame := L.currentFrame 202 gfnret := frame.Fn.GFunction(L) 203 if tailcall { 204 L.currentFrame = L.RemoveCallerFrame() 205 } 206 207 if gfnret < 0 { 208 switchToParentThread(L, L.GetTop(), false, false) 209 return true 210 } 211 212 wantret := frame.NRet 213 if wantret == MultRet { 214 wantret = gfnret 215 } 216 217 if tailcall && L.Parent != nil && L.stack.Sp() == 1 { 218 switchToParentThread(L, wantret, false, true) 219 return true 220 } 221 222 // this section is inlined by go-inline 223 // source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go' 224 { 225 rg := L.reg 226 regv := frame.ReturnBase 227 start := L.reg.Top() - gfnret 228 limit := -1 229 n := wantret 230 newSize := regv + n 231 // this section is inlined by go-inline 232 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 233 { 234 requiredSize := newSize 235 if requiredSize > cap(rg.array) { 236 rg.resize(requiredSize) 237 } 238 } 239 if limit == -1 || limit > rg.top { 240 limit = rg.top 241 } 242 for i := 0; i < n; i++ { 243 srcIdx := start + i 244 if srcIdx >= limit || srcIdx < 0 { 245 rg.array[regv+i] = LNil 246 } else { 247 rg.array[regv+i] = rg.array[srcIdx] 248 } 249 } 250 251 // values beyond top don't need to be valid LValues, so setting them to nil is fine 252 // setting them to nil rather than LNil lets us invoke the golang memclr opto 253 oldtop := rg.top 254 rg.top = regv + n 255 if rg.top < oldtop { 256 nilRange := rg.array[rg.top:oldtop] 257 for i := range nilRange { 258 nilRange[i] = nil 259 } 260 } 261 } 262 L.stack.Pop() 263 L.currentFrame = L.stack.Last() 264 return false 265 } 266 267 func threadRun(L *LState) { 268 if L.stack.IsEmpty() { 269 return 270 } 271 272 defer func() { 273 if rcv := recover(); rcv != nil { 274 var lv LValue 275 if v, ok := rcv.(*ApiError); ok { 276 lv = v.Object 277 } else { 278 lv = LString(fmt.Sprint(rcv)) 279 } 280 if parent := L.Parent; parent != nil { 281 if L.wrapped { 282 L.Push(lv) 283 parent.Panic(L) 284 } else { 285 L.SetTop(0) 286 L.Push(lv) 287 switchToParentThread(L, 1, true, true) 288 } 289 } else { 290 panic(rcv) 291 } 292 } 293 }() 294 L.mainLoop(L, nil) 295 } 296 297 type instFunc func(*LState, uint32, *callFrame) int 298 299 var jumpTable [opCodeMax + 1]instFunc 300 301 func init() { 302 jumpTable = [opCodeMax + 1]instFunc{ 303 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_MOVE 304 reg := L.reg 305 cf := L.currentFrame 306 lbase := cf.LocalBase 307 A := int(inst>>18) & 0xff //GETA 308 RA := lbase + A 309 B := int(inst & 0x1ff) //GETB 310 v := reg.Get(lbase + B) 311 // this section is inlined by go-inline 312 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 313 { 314 rg := reg 315 regi := RA 316 vali := v 317 newSize := regi + 1 318 // this section is inlined by go-inline 319 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 320 { 321 requiredSize := newSize 322 if requiredSize > cap(rg.array) { 323 rg.resize(requiredSize) 324 } 325 } 326 rg.array[regi] = vali 327 if regi >= rg.top { 328 rg.top = regi + 1 329 } 330 } 331 return 0 332 }, 333 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_MOVEN 334 reg := L.reg 335 cf := L.currentFrame 336 lbase := cf.LocalBase 337 A := int(inst>>18) & 0xff //GETA 338 B := int(inst & 0x1ff) //GETB 339 C := int(inst>>9) & 0x1ff //GETC 340 v := reg.Get(lbase + B) 341 // this section is inlined by go-inline 342 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 343 { 344 rg := reg 345 regi := lbase + A 346 vali := v 347 newSize := regi + 1 348 // this section is inlined by go-inline 349 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 350 { 351 requiredSize := newSize 352 if requiredSize > cap(rg.array) { 353 rg.resize(requiredSize) 354 } 355 } 356 rg.array[regi] = vali 357 if regi >= rg.top { 358 rg.top = regi + 1 359 } 360 } 361 code := cf.Fn.Proto.Code 362 pc := cf.Pc 363 for i := 0; i < C; i++ { 364 inst = code[pc] 365 pc++ 366 A = int(inst>>18) & 0xff //GETA 367 B = int(inst & 0x1ff) //GETB 368 v := reg.Get(lbase + B) 369 // this section is inlined by go-inline 370 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 371 { 372 rg := reg 373 regi := lbase + A 374 vali := v 375 newSize := regi + 1 376 // this section is inlined by go-inline 377 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 378 { 379 requiredSize := newSize 380 if requiredSize > cap(rg.array) { 381 rg.resize(requiredSize) 382 } 383 } 384 rg.array[regi] = vali 385 if regi >= rg.top { 386 rg.top = regi + 1 387 } 388 } 389 } 390 cf.Pc = pc 391 return 0 392 }, 393 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_LOADK 394 reg := L.reg 395 cf := L.currentFrame 396 lbase := cf.LocalBase 397 A := int(inst>>18) & 0xff //GETA 398 RA := lbase + A 399 Bx := int(inst & 0x3ffff) //GETBX 400 v := cf.Fn.Proto.Constants[Bx] 401 // this section is inlined by go-inline 402 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 403 { 404 rg := reg 405 regi := RA 406 vali := v 407 newSize := regi + 1 408 // this section is inlined by go-inline 409 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 410 { 411 requiredSize := newSize 412 if requiredSize > cap(rg.array) { 413 rg.resize(requiredSize) 414 } 415 } 416 rg.array[regi] = vali 417 if regi >= rg.top { 418 rg.top = regi + 1 419 } 420 } 421 return 0 422 }, 423 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_LOADBOOL 424 reg := L.reg 425 cf := L.currentFrame 426 lbase := cf.LocalBase 427 A := int(inst>>18) & 0xff //GETA 428 RA := lbase + A 429 B := int(inst & 0x1ff) //GETB 430 C := int(inst>>9) & 0x1ff //GETC 431 if B != 0 { 432 // this section is inlined by go-inline 433 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 434 { 435 rg := reg 436 regi := RA 437 vali := LTrue 438 newSize := regi + 1 439 // this section is inlined by go-inline 440 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 441 { 442 requiredSize := newSize 443 if requiredSize > cap(rg.array) { 444 rg.resize(requiredSize) 445 } 446 } 447 rg.array[regi] = vali 448 if regi >= rg.top { 449 rg.top = regi + 1 450 } 451 } 452 } else { 453 // this section is inlined by go-inline 454 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 455 { 456 rg := reg 457 regi := RA 458 vali := LFalse 459 newSize := regi + 1 460 // this section is inlined by go-inline 461 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 462 { 463 requiredSize := newSize 464 if requiredSize > cap(rg.array) { 465 rg.resize(requiredSize) 466 } 467 } 468 rg.array[regi] = vali 469 if regi >= rg.top { 470 rg.top = regi + 1 471 } 472 } 473 } 474 if C != 0 { 475 cf.Pc++ 476 } 477 return 0 478 }, 479 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_LOADNIL 480 reg := L.reg 481 cf := L.currentFrame 482 lbase := cf.LocalBase 483 A := int(inst>>18) & 0xff //GETA 484 RA := lbase + A 485 B := int(inst & 0x1ff) //GETB 486 for i := RA; i <= lbase+B; i++ { 487 // this section is inlined by go-inline 488 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 489 { 490 rg := reg 491 regi := i 492 vali := LNil 493 newSize := regi + 1 494 // this section is inlined by go-inline 495 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 496 { 497 requiredSize := newSize 498 if requiredSize > cap(rg.array) { 499 rg.resize(requiredSize) 500 } 501 } 502 rg.array[regi] = vali 503 if regi >= rg.top { 504 rg.top = regi + 1 505 } 506 } 507 } 508 return 0 509 }, 510 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_GETUPVAL 511 reg := L.reg 512 cf := L.currentFrame 513 lbase := cf.LocalBase 514 A := int(inst>>18) & 0xff //GETA 515 RA := lbase + A 516 B := int(inst & 0x1ff) //GETB 517 v := cf.Fn.Upvalues[B].Value() 518 // this section is inlined by go-inline 519 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 520 { 521 rg := reg 522 regi := RA 523 vali := v 524 newSize := regi + 1 525 // this section is inlined by go-inline 526 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 527 { 528 requiredSize := newSize 529 if requiredSize > cap(rg.array) { 530 rg.resize(requiredSize) 531 } 532 } 533 rg.array[regi] = vali 534 if regi >= rg.top { 535 rg.top = regi + 1 536 } 537 } 538 return 0 539 }, 540 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_GETGLOBAL 541 reg := L.reg 542 cf := L.currentFrame 543 lbase := cf.LocalBase 544 A := int(inst>>18) & 0xff //GETA 545 RA := lbase + A 546 Bx := int(inst & 0x3ffff) //GETBX 547 //reg.Set(RA, L.getField(cf.Fn.Env, cf.Fn.Proto.Constants[Bx])) 548 v := L.getFieldString(cf.Fn.Env, cf.Fn.Proto.stringConstants[Bx]) 549 // this section is inlined by go-inline 550 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 551 { 552 rg := reg 553 regi := RA 554 vali := v 555 newSize := regi + 1 556 // this section is inlined by go-inline 557 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 558 { 559 requiredSize := newSize 560 if requiredSize > cap(rg.array) { 561 rg.resize(requiredSize) 562 } 563 } 564 rg.array[regi] = vali 565 if regi >= rg.top { 566 rg.top = regi + 1 567 } 568 } 569 return 0 570 }, 571 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_GETTABLE 572 reg := L.reg 573 cf := L.currentFrame 574 lbase := cf.LocalBase 575 A := int(inst>>18) & 0xff //GETA 576 RA := lbase + A 577 B := int(inst & 0x1ff) //GETB 578 C := int(inst>>9) & 0x1ff //GETC 579 v := L.getField(reg.Get(lbase+B), L.rkValue(C)) 580 // this section is inlined by go-inline 581 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 582 { 583 rg := reg 584 regi := RA 585 vali := v 586 newSize := regi + 1 587 // this section is inlined by go-inline 588 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 589 { 590 requiredSize := newSize 591 if requiredSize > cap(rg.array) { 592 rg.resize(requiredSize) 593 } 594 } 595 rg.array[regi] = vali 596 if regi >= rg.top { 597 rg.top = regi + 1 598 } 599 } 600 return 0 601 }, 602 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_GETTABLEKS 603 reg := L.reg 604 cf := L.currentFrame 605 lbase := cf.LocalBase 606 A := int(inst>>18) & 0xff //GETA 607 RA := lbase + A 608 B := int(inst & 0x1ff) //GETB 609 C := int(inst>>9) & 0x1ff //GETC 610 v := L.getFieldString(reg.Get(lbase+B), L.rkString(C)) 611 // this section is inlined by go-inline 612 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 613 { 614 rg := reg 615 regi := RA 616 vali := v 617 newSize := regi + 1 618 // this section is inlined by go-inline 619 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 620 { 621 requiredSize := newSize 622 if requiredSize > cap(rg.array) { 623 rg.resize(requiredSize) 624 } 625 } 626 rg.array[regi] = vali 627 if regi >= rg.top { 628 rg.top = regi + 1 629 } 630 } 631 return 0 632 }, 633 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SETGLOBAL 634 reg := L.reg 635 cf := L.currentFrame 636 lbase := cf.LocalBase 637 A := int(inst>>18) & 0xff //GETA 638 RA := lbase + A 639 Bx := int(inst & 0x3ffff) //GETBX 640 //L.setField(cf.Fn.Env, cf.Fn.Proto.Constants[Bx], reg.Get(RA)) 641 L.setFieldString(cf.Fn.Env, cf.Fn.Proto.stringConstants[Bx], reg.Get(RA)) 642 return 0 643 }, 644 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SETUPVAL 645 reg := L.reg 646 cf := L.currentFrame 647 lbase := cf.LocalBase 648 A := int(inst>>18) & 0xff //GETA 649 RA := lbase + A 650 B := int(inst & 0x1ff) //GETB 651 cf.Fn.Upvalues[B].SetValue(reg.Get(RA)) 652 return 0 653 }, 654 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SETTABLE 655 reg := L.reg 656 cf := L.currentFrame 657 lbase := cf.LocalBase 658 A := int(inst>>18) & 0xff //GETA 659 RA := lbase + A 660 B := int(inst & 0x1ff) //GETB 661 C := int(inst>>9) & 0x1ff //GETC 662 L.setField(reg.Get(RA), L.rkValue(B), L.rkValue(C)) 663 return 0 664 }, 665 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SETTABLEKS 666 reg := L.reg 667 cf := L.currentFrame 668 lbase := cf.LocalBase 669 A := int(inst>>18) & 0xff //GETA 670 RA := lbase + A 671 B := int(inst & 0x1ff) //GETB 672 C := int(inst>>9) & 0x1ff //GETC 673 L.setFieldString(reg.Get(RA), L.rkString(B), L.rkValue(C)) 674 return 0 675 }, 676 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_NEWTABLE 677 reg := L.reg 678 cf := L.currentFrame 679 lbase := cf.LocalBase 680 A := int(inst>>18) & 0xff //GETA 681 RA := lbase + A 682 B := int(inst & 0x1ff) //GETB 683 C := int(inst>>9) & 0x1ff //GETC 684 v := newLTable(B, C) 685 // this section is inlined by go-inline 686 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 687 { 688 rg := reg 689 regi := RA 690 vali := v 691 newSize := regi + 1 692 // this section is inlined by go-inline 693 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 694 { 695 requiredSize := newSize 696 if requiredSize > cap(rg.array) { 697 rg.resize(requiredSize) 698 } 699 } 700 rg.array[regi] = vali 701 if regi >= rg.top { 702 rg.top = regi + 1 703 } 704 } 705 return 0 706 }, 707 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SELF 708 reg := L.reg 709 cf := L.currentFrame 710 lbase := cf.LocalBase 711 A := int(inst>>18) & 0xff //GETA 712 RA := lbase + A 713 B := int(inst & 0x1ff) //GETB 714 C := int(inst>>9) & 0x1ff //GETC 715 selfobj := reg.Get(lbase + B) 716 v := L.getFieldString(selfobj, L.rkString(C)) 717 // this section is inlined by go-inline 718 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 719 { 720 rg := reg 721 regi := RA 722 vali := v 723 newSize := regi + 1 724 // this section is inlined by go-inline 725 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 726 { 727 requiredSize := newSize 728 if requiredSize > cap(rg.array) { 729 rg.resize(requiredSize) 730 } 731 } 732 rg.array[regi] = vali 733 if regi >= rg.top { 734 rg.top = regi + 1 735 } 736 } 737 // this section is inlined by go-inline 738 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 739 { 740 rg := reg 741 regi := RA + 1 742 vali := selfobj 743 newSize := regi + 1 744 // this section is inlined by go-inline 745 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 746 { 747 requiredSize := newSize 748 if requiredSize > cap(rg.array) { 749 rg.resize(requiredSize) 750 } 751 } 752 rg.array[regi] = vali 753 if regi >= rg.top { 754 rg.top = regi + 1 755 } 756 } 757 return 0 758 }, 759 opArith, // OP_ADD 760 opArith, // OP_SUB 761 opArith, // OP_MUL 762 opArith, // OP_DIV 763 opArith, // OP_MOD 764 opArith, // OP_POW 765 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_UNM 766 reg := L.reg 767 cf := L.currentFrame 768 lbase := cf.LocalBase 769 A := int(inst>>18) & 0xff //GETA 770 RA := lbase + A 771 B := int(inst & 0x1ff) //GETB 772 unaryv := L.rkValue(B) 773 if nm, ok := unaryv.(LNumber); ok { 774 // this section is inlined by go-inline 775 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 776 { 777 rg := reg 778 regi := RA 779 vali := -nm 780 newSize := regi + 1 781 // this section is inlined by go-inline 782 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 783 { 784 requiredSize := newSize 785 if requiredSize > cap(rg.array) { 786 rg.resize(requiredSize) 787 } 788 } 789 rg.array[regi] = vali 790 if regi >= rg.top { 791 rg.top = regi + 1 792 } 793 } 794 } else { 795 op := L.metaOp1(unaryv, "__unm") 796 if op.Type() == LTFunction { 797 reg.Push(op) 798 reg.Push(unaryv) 799 L.Call(1, 1) 800 // this section is inlined by go-inline 801 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 802 { 803 rg := reg 804 regi := RA 805 vali := reg.Pop() 806 newSize := regi + 1 807 // this section is inlined by go-inline 808 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 809 { 810 requiredSize := newSize 811 if requiredSize > cap(rg.array) { 812 rg.resize(requiredSize) 813 } 814 } 815 rg.array[regi] = vali 816 if regi >= rg.top { 817 rg.top = regi + 1 818 } 819 } 820 } else if str, ok1 := unaryv.(LString); ok1 { 821 if num, err := parseNumber(string(str)); err == nil { 822 // this section is inlined by go-inline 823 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 824 { 825 rg := reg 826 regi := RA 827 vali := -num 828 newSize := regi + 1 829 // this section is inlined by go-inline 830 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 831 { 832 requiredSize := newSize 833 if requiredSize > cap(rg.array) { 834 rg.resize(requiredSize) 835 } 836 } 837 rg.array[regi] = vali 838 if regi >= rg.top { 839 rg.top = regi + 1 840 } 841 } 842 } else { 843 L.RaiseError("__unm undefined") 844 } 845 } else { 846 L.RaiseError("__unm undefined") 847 } 848 } 849 return 0 850 }, 851 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_NOT 852 reg := L.reg 853 cf := L.currentFrame 854 lbase := cf.LocalBase 855 A := int(inst>>18) & 0xff //GETA 856 RA := lbase + A 857 B := int(inst & 0x1ff) //GETB 858 if LVIsFalse(reg.Get(lbase + B)) { 859 // this section is inlined by go-inline 860 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 861 { 862 rg := reg 863 regi := RA 864 vali := LTrue 865 newSize := regi + 1 866 // this section is inlined by go-inline 867 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 868 { 869 requiredSize := newSize 870 if requiredSize > cap(rg.array) { 871 rg.resize(requiredSize) 872 } 873 } 874 rg.array[regi] = vali 875 if regi >= rg.top { 876 rg.top = regi + 1 877 } 878 } 879 } else { 880 // this section is inlined by go-inline 881 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 882 { 883 rg := reg 884 regi := RA 885 vali := LFalse 886 newSize := regi + 1 887 // this section is inlined by go-inline 888 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 889 { 890 requiredSize := newSize 891 if requiredSize > cap(rg.array) { 892 rg.resize(requiredSize) 893 } 894 } 895 rg.array[regi] = vali 896 if regi >= rg.top { 897 rg.top = regi + 1 898 } 899 } 900 } 901 return 0 902 }, 903 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_LEN 904 reg := L.reg 905 cf := L.currentFrame 906 lbase := cf.LocalBase 907 A := int(inst>>18) & 0xff //GETA 908 RA := lbase + A 909 B := int(inst & 0x1ff) //GETB 910 switch lv := L.rkValue(B).(type) { 911 case LString: 912 // this section is inlined by go-inline 913 // source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go' 914 { 915 rg := reg 916 regi := RA 917 vali := LNumber(len(lv)) 918 newSize := regi + 1 919 // this section is inlined by go-inline 920 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 921 { 922 requiredSize := newSize 923 if requiredSize > cap(rg.array) { 924 rg.resize(requiredSize) 925 } 926 } 927 rg.array[regi] = rg.alloc.LNumber2I(vali) 928 if regi >= rg.top { 929 rg.top = regi + 1 930 } 931 } 932 default: 933 op := L.metaOp1(lv, "__len") 934 if op.Type() == LTFunction { 935 reg.Push(op) 936 reg.Push(lv) 937 L.Call(1, 1) 938 ret := reg.Pop() 939 if ret.Type() == LTNumber { 940 v, _ := ret.(LNumber) 941 // this section is inlined by go-inline 942 // source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go' 943 { 944 rg := reg 945 regi := RA 946 vali := v 947 newSize := regi + 1 948 // this section is inlined by go-inline 949 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 950 { 951 requiredSize := newSize 952 if requiredSize > cap(rg.array) { 953 rg.resize(requiredSize) 954 } 955 } 956 rg.array[regi] = rg.alloc.LNumber2I(vali) 957 if regi >= rg.top { 958 rg.top = regi + 1 959 } 960 } 961 } else { 962 // this section is inlined by go-inline 963 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 964 { 965 rg := reg 966 regi := RA 967 vali := ret 968 newSize := regi + 1 969 // this section is inlined by go-inline 970 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 971 { 972 requiredSize := newSize 973 if requiredSize > cap(rg.array) { 974 rg.resize(requiredSize) 975 } 976 } 977 rg.array[regi] = vali 978 if regi >= rg.top { 979 rg.top = regi + 1 980 } 981 } 982 } 983 } else if lv.Type() == LTTable { 984 // this section is inlined by go-inline 985 // source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go' 986 { 987 rg := reg 988 regi := RA 989 vali := LNumber(lv.(*LTable).Len()) 990 newSize := regi + 1 991 // this section is inlined by go-inline 992 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 993 { 994 requiredSize := newSize 995 if requiredSize > cap(rg.array) { 996 rg.resize(requiredSize) 997 } 998 } 999 rg.array[regi] = rg.alloc.LNumber2I(vali) 1000 if regi >= rg.top { 1001 rg.top = regi + 1 1002 } 1003 } 1004 } else { 1005 L.RaiseError("__len undefined") 1006 } 1007 } 1008 return 0 1009 }, 1010 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_CONCAT 1011 reg := L.reg 1012 cf := L.currentFrame 1013 lbase := cf.LocalBase 1014 A := int(inst>>18) & 0xff //GETA 1015 RA := lbase + A 1016 B := int(inst & 0x1ff) //GETB 1017 C := int(inst>>9) & 0x1ff //GETC 1018 RC := lbase + C 1019 RB := lbase + B 1020 v := stringConcat(L, RC-RB+1, RC) 1021 // this section is inlined by go-inline 1022 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 1023 { 1024 rg := reg 1025 regi := RA 1026 vali := v 1027 newSize := regi + 1 1028 // this section is inlined by go-inline 1029 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1030 { 1031 requiredSize := newSize 1032 if requiredSize > cap(rg.array) { 1033 rg.resize(requiredSize) 1034 } 1035 } 1036 rg.array[regi] = vali 1037 if regi >= rg.top { 1038 rg.top = regi + 1 1039 } 1040 } 1041 return 0 1042 }, 1043 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_JMP 1044 cf := L.currentFrame 1045 Sbx := int(inst&0x3ffff) - opMaxArgSbx //GETSBX 1046 cf.Pc += Sbx 1047 return 0 1048 }, 1049 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_EQ 1050 cf := L.currentFrame 1051 A := int(inst>>18) & 0xff //GETA 1052 B := int(inst & 0x1ff) //GETB 1053 C := int(inst>>9) & 0x1ff //GETC 1054 ret := equals(L, L.rkValue(B), L.rkValue(C), false) 1055 v := 1 1056 if ret { 1057 v = 0 1058 } 1059 if v == A { 1060 cf.Pc++ 1061 } 1062 return 0 1063 }, 1064 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_LT 1065 cf := L.currentFrame 1066 A := int(inst>>18) & 0xff //GETA 1067 B := int(inst & 0x1ff) //GETB 1068 C := int(inst>>9) & 0x1ff //GETC 1069 ret := lessThan(L, L.rkValue(B), L.rkValue(C)) 1070 v := 1 1071 if ret { 1072 v = 0 1073 } 1074 if v == A { 1075 cf.Pc++ 1076 } 1077 return 0 1078 }, 1079 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_LE 1080 cf := L.currentFrame 1081 A := int(inst>>18) & 0xff //GETA 1082 B := int(inst & 0x1ff) //GETB 1083 C := int(inst>>9) & 0x1ff //GETC 1084 lhs := L.rkValue(B) 1085 rhs := L.rkValue(C) 1086 ret := false 1087 1088 if v1, ok1 := lhs.(LNumber); ok1 { 1089 if v2, ok2 := rhs.(LNumber); ok2 { 1090 ret = v1 <= v2 1091 } else { 1092 L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String()) 1093 } 1094 } else { 1095 if lhs.Type() != rhs.Type() { 1096 L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String()) 1097 } 1098 switch lhs.Type() { 1099 case LTString: 1100 ret = strCmp(string(lhs.(LString)), string(rhs.(LString))) <= 0 1101 default: 1102 switch objectRational(L, lhs, rhs, "__le") { 1103 case 1: 1104 ret = true 1105 case 0: 1106 ret = false 1107 default: 1108 ret = !objectRationalWithError(L, rhs, lhs, "__lt") 1109 } 1110 } 1111 } 1112 1113 v := 1 1114 if ret { 1115 v = 0 1116 } 1117 if v == A { 1118 cf.Pc++ 1119 } 1120 return 0 1121 }, 1122 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_TEST 1123 reg := L.reg 1124 cf := L.currentFrame 1125 lbase := cf.LocalBase 1126 A := int(inst>>18) & 0xff //GETA 1127 RA := lbase + A 1128 C := int(inst>>9) & 0x1ff //GETC 1129 if LVAsBool(reg.Get(RA)) == (C == 0) { 1130 cf.Pc++ 1131 } 1132 return 0 1133 }, 1134 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_TESTSET 1135 reg := L.reg 1136 cf := L.currentFrame 1137 lbase := cf.LocalBase 1138 A := int(inst>>18) & 0xff //GETA 1139 RA := lbase + A 1140 B := int(inst & 0x1ff) //GETB 1141 C := int(inst>>9) & 0x1ff //GETC 1142 if value := reg.Get(lbase + B); LVAsBool(value) != (C == 0) { 1143 // this section is inlined by go-inline 1144 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 1145 { 1146 rg := reg 1147 regi := RA 1148 vali := value 1149 newSize := regi + 1 1150 // this section is inlined by go-inline 1151 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1152 { 1153 requiredSize := newSize 1154 if requiredSize > cap(rg.array) { 1155 rg.resize(requiredSize) 1156 } 1157 } 1158 rg.array[regi] = vali 1159 if regi >= rg.top { 1160 rg.top = regi + 1 1161 } 1162 } 1163 } else { 1164 cf.Pc++ 1165 } 1166 return 0 1167 }, 1168 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_CALL 1169 reg := L.reg 1170 cf := L.currentFrame 1171 lbase := cf.LocalBase 1172 A := int(inst>>18) & 0xff //GETA 1173 RA := lbase + A 1174 B := int(inst & 0x1ff) //GETB 1175 C := int(inst>>9) & 0x1ff //GETC 1176 nargs := B - 1 1177 if B == 0 { 1178 nargs = reg.Top() - (RA + 1) 1179 } 1180 lv := reg.Get(RA) 1181 nret := C - 1 1182 var callable *LFunction 1183 var meta bool 1184 if fn, ok := lv.(*LFunction); ok { 1185 callable = fn 1186 meta = false 1187 } else { 1188 callable, meta = L.metaCall(lv) 1189 } 1190 // this section is inlined by go-inline 1191 // source function is 'func (ls *LState) pushCallFrame(cf callFrame, fn LValue, meta bool) ' in '_state.go' 1192 { 1193 ls := L 1194 cf := callFrame{Fn: callable, Pc: 0, Base: RA, LocalBase: RA + 1, ReturnBase: RA, NArgs: nargs, NRet: nret, Parent: cf, TailCall: 0} 1195 fn := lv 1196 if meta { 1197 cf.NArgs++ 1198 ls.reg.Insert(fn, cf.LocalBase) 1199 } 1200 if cf.Fn == nil { 1201 ls.RaiseError("attempt to call a non-function object") 1202 } 1203 if ls.stack.IsFull() { 1204 ls.RaiseError("stack overflow") 1205 } 1206 ls.stack.Push(cf) 1207 newcf := ls.stack.Last() 1208 // this section is inlined by go-inline 1209 // source function is 'func (ls *LState) initCallFrame(cf *callFrame) ' in '_state.go' 1210 { 1211 cf := newcf 1212 if cf.Fn.IsG { 1213 ls.reg.SetTop(cf.LocalBase + cf.NArgs) 1214 } else { 1215 proto := cf.Fn.Proto 1216 nargs := cf.NArgs 1217 np := int(proto.NumParameters) 1218 if nargs < np { 1219 // default any missing arguments to nil 1220 newSize := cf.LocalBase + np 1221 // this section is inlined by go-inline 1222 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1223 { 1224 rg := ls.reg 1225 requiredSize := newSize 1226 if requiredSize > cap(rg.array) { 1227 rg.resize(requiredSize) 1228 } 1229 } 1230 for i := nargs; i < np; i++ { 1231 ls.reg.array[cf.LocalBase+i] = LNil 1232 } 1233 nargs = np 1234 ls.reg.top = newSize 1235 } 1236 1237 if (proto.IsVarArg & VarArgIsVarArg) == 0 { 1238 if nargs < int(proto.NumUsedRegisters) { 1239 nargs = int(proto.NumUsedRegisters) 1240 } 1241 newSize := cf.LocalBase + nargs 1242 // this section is inlined by go-inline 1243 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1244 { 1245 rg := ls.reg 1246 requiredSize := newSize 1247 if requiredSize > cap(rg.array) { 1248 rg.resize(requiredSize) 1249 } 1250 } 1251 for i := np; i < nargs; i++ { 1252 ls.reg.array[cf.LocalBase+i] = LNil 1253 } 1254 ls.reg.top = cf.LocalBase + int(proto.NumUsedRegisters) 1255 } else { 1256 /* swap vararg positions: 1257 closure 1258 namedparam1 <- lbase 1259 namedparam2 1260 vararg1 1261 vararg2 1262 1263 TO 1264 1265 closure 1266 nil 1267 nil 1268 vararg1 1269 vararg2 1270 namedparam1 <- lbase 1271 namedparam2 1272 */ 1273 nvarargs := nargs - np 1274 if nvarargs < 0 { 1275 nvarargs = 0 1276 } 1277 1278 ls.reg.SetTop(cf.LocalBase + nargs + np) 1279 for i := 0; i < np; i++ { 1280 //ls.reg.Set(cf.LocalBase+nargs+i, ls.reg.Get(cf.LocalBase+i)) 1281 ls.reg.array[cf.LocalBase+nargs+i] = ls.reg.array[cf.LocalBase+i] 1282 //ls.reg.Set(cf.LocalBase+i, LNil) 1283 ls.reg.array[cf.LocalBase+i] = LNil 1284 } 1285 1286 if CompatVarArg { 1287 ls.reg.SetTop(cf.LocalBase + nargs + np + 1) 1288 if (proto.IsVarArg & VarArgNeedsArg) != 0 { 1289 argtb := newLTable(nvarargs, 0) 1290 for i := 0; i < nvarargs; i++ { 1291 argtb.RawSetInt(i+1, ls.reg.Get(cf.LocalBase+np+i)) 1292 } 1293 argtb.RawSetString("n", LNumber(nvarargs)) 1294 //ls.reg.Set(cf.LocalBase+nargs+np, argtb) 1295 ls.reg.array[cf.LocalBase+nargs+np] = argtb 1296 } else { 1297 ls.reg.array[cf.LocalBase+nargs+np] = LNil 1298 } 1299 } 1300 cf.LocalBase += nargs 1301 maxreg := cf.LocalBase + int(proto.NumUsedRegisters) 1302 ls.reg.SetTop(maxreg) 1303 } 1304 } 1305 } 1306 ls.currentFrame = newcf 1307 } 1308 if callable.IsG && callGFunction(L, false) { 1309 return 1 1310 } 1311 return 0 1312 }, 1313 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_TAILCALL 1314 reg := L.reg 1315 cf := L.currentFrame 1316 lbase := cf.LocalBase 1317 A := int(inst>>18) & 0xff //GETA 1318 RA := lbase + A 1319 B := int(inst & 0x1ff) //GETB 1320 nargs := B - 1 1321 if B == 0 { 1322 nargs = reg.Top() - (RA + 1) 1323 } 1324 lv := reg.Get(RA) 1325 var callable *LFunction 1326 var meta bool 1327 if fn, ok := lv.(*LFunction); ok { 1328 callable = fn 1329 meta = false 1330 } else { 1331 callable, meta = L.metaCall(lv) 1332 } 1333 if callable == nil { 1334 L.RaiseError("attempt to call a non-function object") 1335 } 1336 // this section is inlined by go-inline 1337 // source function is 'func (ls *LState) closeUpvalues(idx int) ' in '_state.go' 1338 { 1339 ls := L 1340 idx := lbase 1341 if ls.uvcache != nil { 1342 var prev *Upvalue 1343 for uv := ls.uvcache; uv != nil; uv = uv.next { 1344 if uv.index >= idx { 1345 if prev != nil { 1346 prev.next = nil 1347 } else { 1348 ls.uvcache = nil 1349 } 1350 uv.Close() 1351 } 1352 prev = uv 1353 } 1354 } 1355 } 1356 if callable.IsG { 1357 luaframe := cf 1358 L.pushCallFrame(callFrame{ 1359 Fn: callable, 1360 Pc: 0, 1361 Base: RA, 1362 LocalBase: RA + 1, 1363 ReturnBase: cf.ReturnBase, 1364 NArgs: nargs, 1365 NRet: cf.NRet, 1366 Parent: cf, 1367 TailCall: 0, 1368 }, lv, meta) 1369 if callGFunction(L, true) { 1370 return 1 1371 } 1372 if L.currentFrame == nil || L.currentFrame.Fn.IsG || luaframe == baseframe { 1373 return 1 1374 } 1375 } else { 1376 base := cf.Base 1377 cf.Fn = callable 1378 cf.Pc = 0 1379 cf.Base = RA 1380 cf.LocalBase = RA + 1 1381 cf.ReturnBase = cf.ReturnBase 1382 cf.NArgs = nargs 1383 cf.NRet = cf.NRet 1384 cf.TailCall++ 1385 lbase := cf.LocalBase 1386 if meta { 1387 cf.NArgs++ 1388 L.reg.Insert(lv, cf.LocalBase) 1389 } 1390 // this section is inlined by go-inline 1391 // source function is 'func (ls *LState) initCallFrame(cf *callFrame) ' in '_state.go' 1392 { 1393 ls := L 1394 if cf.Fn.IsG { 1395 ls.reg.SetTop(cf.LocalBase + cf.NArgs) 1396 } else { 1397 proto := cf.Fn.Proto 1398 nargs := cf.NArgs 1399 np := int(proto.NumParameters) 1400 if nargs < np { 1401 // default any missing arguments to nil 1402 newSize := cf.LocalBase + np 1403 // this section is inlined by go-inline 1404 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1405 { 1406 rg := ls.reg 1407 requiredSize := newSize 1408 if requiredSize > cap(rg.array) { 1409 rg.resize(requiredSize) 1410 } 1411 } 1412 for i := nargs; i < np; i++ { 1413 ls.reg.array[cf.LocalBase+i] = LNil 1414 } 1415 nargs = np 1416 ls.reg.top = newSize 1417 } 1418 1419 if (proto.IsVarArg & VarArgIsVarArg) == 0 { 1420 if nargs < int(proto.NumUsedRegisters) { 1421 nargs = int(proto.NumUsedRegisters) 1422 } 1423 newSize := cf.LocalBase + nargs 1424 // this section is inlined by go-inline 1425 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1426 { 1427 rg := ls.reg 1428 requiredSize := newSize 1429 if requiredSize > cap(rg.array) { 1430 rg.resize(requiredSize) 1431 } 1432 } 1433 for i := np; i < nargs; i++ { 1434 ls.reg.array[cf.LocalBase+i] = LNil 1435 } 1436 ls.reg.top = cf.LocalBase + int(proto.NumUsedRegisters) 1437 } else { 1438 /* swap vararg positions: 1439 closure 1440 namedparam1 <- lbase 1441 namedparam2 1442 vararg1 1443 vararg2 1444 1445 TO 1446 1447 closure 1448 nil 1449 nil 1450 vararg1 1451 vararg2 1452 namedparam1 <- lbase 1453 namedparam2 1454 */ 1455 nvarargs := nargs - np 1456 if nvarargs < 0 { 1457 nvarargs = 0 1458 } 1459 1460 ls.reg.SetTop(cf.LocalBase + nargs + np) 1461 for i := 0; i < np; i++ { 1462 //ls.reg.Set(cf.LocalBase+nargs+i, ls.reg.Get(cf.LocalBase+i)) 1463 ls.reg.array[cf.LocalBase+nargs+i] = ls.reg.array[cf.LocalBase+i] 1464 //ls.reg.Set(cf.LocalBase+i, LNil) 1465 ls.reg.array[cf.LocalBase+i] = LNil 1466 } 1467 1468 if CompatVarArg { 1469 ls.reg.SetTop(cf.LocalBase + nargs + np + 1) 1470 if (proto.IsVarArg & VarArgNeedsArg) != 0 { 1471 argtb := newLTable(nvarargs, 0) 1472 for i := 0; i < nvarargs; i++ { 1473 argtb.RawSetInt(i+1, ls.reg.Get(cf.LocalBase+np+i)) 1474 } 1475 argtb.RawSetString("n", LNumber(nvarargs)) 1476 //ls.reg.Set(cf.LocalBase+nargs+np, argtb) 1477 ls.reg.array[cf.LocalBase+nargs+np] = argtb 1478 } else { 1479 ls.reg.array[cf.LocalBase+nargs+np] = LNil 1480 } 1481 } 1482 cf.LocalBase += nargs 1483 maxreg := cf.LocalBase + int(proto.NumUsedRegisters) 1484 ls.reg.SetTop(maxreg) 1485 } 1486 } 1487 } 1488 // this section is inlined by go-inline 1489 // source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go' 1490 { 1491 rg := L.reg 1492 regv := base 1493 start := RA 1494 limit := -1 1495 n := reg.Top() - RA - 1 1496 newSize := regv + n 1497 // this section is inlined by go-inline 1498 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1499 { 1500 requiredSize := newSize 1501 if requiredSize > cap(rg.array) { 1502 rg.resize(requiredSize) 1503 } 1504 } 1505 if limit == -1 || limit > rg.top { 1506 limit = rg.top 1507 } 1508 for i := 0; i < n; i++ { 1509 srcIdx := start + i 1510 if srcIdx >= limit || srcIdx < 0 { 1511 rg.array[regv+i] = LNil 1512 } else { 1513 rg.array[regv+i] = rg.array[srcIdx] 1514 } 1515 } 1516 1517 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1518 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1519 oldtop := rg.top 1520 rg.top = regv + n 1521 if rg.top < oldtop { 1522 nilRange := rg.array[rg.top:oldtop] 1523 for i := range nilRange { 1524 nilRange[i] = nil 1525 } 1526 } 1527 } 1528 cf.Base = base 1529 cf.LocalBase = base + (cf.LocalBase - lbase + 1) 1530 } 1531 return 0 1532 }, 1533 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_RETURN 1534 reg := L.reg 1535 cf := L.currentFrame 1536 lbase := cf.LocalBase 1537 A := int(inst>>18) & 0xff //GETA 1538 RA := lbase + A 1539 B := int(inst & 0x1ff) //GETB 1540 // this section is inlined by go-inline 1541 // source function is 'func (ls *LState) closeUpvalues(idx int) ' in '_state.go' 1542 { 1543 ls := L 1544 idx := lbase 1545 if ls.uvcache != nil { 1546 var prev *Upvalue 1547 for uv := ls.uvcache; uv != nil; uv = uv.next { 1548 if uv.index >= idx { 1549 if prev != nil { 1550 prev.next = nil 1551 } else { 1552 ls.uvcache = nil 1553 } 1554 uv.Close() 1555 } 1556 prev = uv 1557 } 1558 } 1559 } 1560 nret := B - 1 1561 if B == 0 { 1562 nret = reg.Top() - RA 1563 } 1564 n := cf.NRet 1565 if cf.NRet == MultRet { 1566 n = nret 1567 } 1568 1569 if L.Parent != nil && L.stack.Sp() == 1 { 1570 // this section is inlined by go-inline 1571 // source function is 'func copyReturnValues(L *LState, regv, start, n, b int) ' in '_vm.go' 1572 { 1573 regv := reg.Top() 1574 start := RA 1575 b := B 1576 if b == 1 { 1577 // this section is inlined by go-inline 1578 // source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go' 1579 { 1580 rg := L.reg 1581 regm := regv 1582 newSize := regm + n 1583 // this section is inlined by go-inline 1584 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1585 { 1586 requiredSize := newSize 1587 if requiredSize > cap(rg.array) { 1588 rg.resize(requiredSize) 1589 } 1590 } 1591 for i := 0; i < n; i++ { 1592 rg.array[regm+i] = LNil 1593 } 1594 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1595 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1596 oldtop := rg.top 1597 rg.top = regm + n 1598 if rg.top < oldtop { 1599 nilRange := rg.array[rg.top:oldtop] 1600 for i := range nilRange { 1601 nilRange[i] = nil 1602 } 1603 } 1604 } 1605 } else { 1606 // this section is inlined by go-inline 1607 // source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go' 1608 { 1609 rg := L.reg 1610 limit := -1 1611 newSize := regv + n 1612 // this section is inlined by go-inline 1613 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1614 { 1615 requiredSize := newSize 1616 if requiredSize > cap(rg.array) { 1617 rg.resize(requiredSize) 1618 } 1619 } 1620 if limit == -1 || limit > rg.top { 1621 limit = rg.top 1622 } 1623 for i := 0; i < n; i++ { 1624 srcIdx := start + i 1625 if srcIdx >= limit || srcIdx < 0 { 1626 rg.array[regv+i] = LNil 1627 } else { 1628 rg.array[regv+i] = rg.array[srcIdx] 1629 } 1630 } 1631 1632 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1633 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1634 oldtop := rg.top 1635 rg.top = regv + n 1636 if rg.top < oldtop { 1637 nilRange := rg.array[rg.top:oldtop] 1638 for i := range nilRange { 1639 nilRange[i] = nil 1640 } 1641 } 1642 } 1643 if b > 1 && n > (b-1) { 1644 // this section is inlined by go-inline 1645 // source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go' 1646 { 1647 rg := L.reg 1648 regm := regv + b - 1 1649 n := n - (b - 1) 1650 newSize := regm + n 1651 // this section is inlined by go-inline 1652 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1653 { 1654 requiredSize := newSize 1655 if requiredSize > cap(rg.array) { 1656 rg.resize(requiredSize) 1657 } 1658 } 1659 for i := 0; i < n; i++ { 1660 rg.array[regm+i] = LNil 1661 } 1662 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1663 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1664 oldtop := rg.top 1665 rg.top = regm + n 1666 if rg.top < oldtop { 1667 nilRange := rg.array[rg.top:oldtop] 1668 for i := range nilRange { 1669 nilRange[i] = nil 1670 } 1671 } 1672 } 1673 } 1674 } 1675 } 1676 switchToParentThread(L, n, false, true) 1677 return 1 1678 } 1679 islast := baseframe == L.stack.Pop() || L.stack.IsEmpty() 1680 // this section is inlined by go-inline 1681 // source function is 'func copyReturnValues(L *LState, regv, start, n, b int) ' in '_vm.go' 1682 { 1683 regv := cf.ReturnBase 1684 start := RA 1685 b := B 1686 if b == 1 { 1687 // this section is inlined by go-inline 1688 // source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go' 1689 { 1690 rg := L.reg 1691 regm := regv 1692 newSize := regm + n 1693 // this section is inlined by go-inline 1694 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1695 { 1696 requiredSize := newSize 1697 if requiredSize > cap(rg.array) { 1698 rg.resize(requiredSize) 1699 } 1700 } 1701 for i := 0; i < n; i++ { 1702 rg.array[regm+i] = LNil 1703 } 1704 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1705 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1706 oldtop := rg.top 1707 rg.top = regm + n 1708 if rg.top < oldtop { 1709 nilRange := rg.array[rg.top:oldtop] 1710 for i := range nilRange { 1711 nilRange[i] = nil 1712 } 1713 } 1714 } 1715 } else { 1716 // this section is inlined by go-inline 1717 // source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go' 1718 { 1719 rg := L.reg 1720 limit := -1 1721 newSize := regv + n 1722 // this section is inlined by go-inline 1723 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1724 { 1725 requiredSize := newSize 1726 if requiredSize > cap(rg.array) { 1727 rg.resize(requiredSize) 1728 } 1729 } 1730 if limit == -1 || limit > rg.top { 1731 limit = rg.top 1732 } 1733 for i := 0; i < n; i++ { 1734 srcIdx := start + i 1735 if srcIdx >= limit || srcIdx < 0 { 1736 rg.array[regv+i] = LNil 1737 } else { 1738 rg.array[regv+i] = rg.array[srcIdx] 1739 } 1740 } 1741 1742 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1743 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1744 oldtop := rg.top 1745 rg.top = regv + n 1746 if rg.top < oldtop { 1747 nilRange := rg.array[rg.top:oldtop] 1748 for i := range nilRange { 1749 nilRange[i] = nil 1750 } 1751 } 1752 } 1753 if b > 1 && n > (b-1) { 1754 // this section is inlined by go-inline 1755 // source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go' 1756 { 1757 rg := L.reg 1758 regm := regv + b - 1 1759 n := n - (b - 1) 1760 newSize := regm + n 1761 // this section is inlined by go-inline 1762 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1763 { 1764 requiredSize := newSize 1765 if requiredSize > cap(rg.array) { 1766 rg.resize(requiredSize) 1767 } 1768 } 1769 for i := 0; i < n; i++ { 1770 rg.array[regm+i] = LNil 1771 } 1772 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1773 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1774 oldtop := rg.top 1775 rg.top = regm + n 1776 if rg.top < oldtop { 1777 nilRange := rg.array[rg.top:oldtop] 1778 for i := range nilRange { 1779 nilRange[i] = nil 1780 } 1781 } 1782 } 1783 } 1784 } 1785 } 1786 L.currentFrame = L.stack.Last() 1787 if islast || L.currentFrame == nil || L.currentFrame.Fn.IsG { 1788 return 1 1789 } 1790 return 0 1791 }, 1792 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_FORLOOP 1793 reg := L.reg 1794 cf := L.currentFrame 1795 lbase := cf.LocalBase 1796 A := int(inst>>18) & 0xff //GETA 1797 RA := lbase + A 1798 if init, ok1 := reg.Get(RA).(LNumber); ok1 { 1799 if limit, ok2 := reg.Get(RA + 1).(LNumber); ok2 { 1800 if step, ok3 := reg.Get(RA + 2).(LNumber); ok3 { 1801 init += step 1802 v := LNumber(init) 1803 // this section is inlined by go-inline 1804 // source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go' 1805 { 1806 rg := reg 1807 regi := RA 1808 vali := v 1809 newSize := regi + 1 1810 // this section is inlined by go-inline 1811 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1812 { 1813 requiredSize := newSize 1814 if requiredSize > cap(rg.array) { 1815 rg.resize(requiredSize) 1816 } 1817 } 1818 rg.array[regi] = rg.alloc.LNumber2I(vali) 1819 if regi >= rg.top { 1820 rg.top = regi + 1 1821 } 1822 } 1823 if (step > 0 && init <= limit) || (step <= 0 && init >= limit) { 1824 Sbx := int(inst&0x3ffff) - opMaxArgSbx //GETSBX 1825 cf.Pc += Sbx 1826 // this section is inlined by go-inline 1827 // source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go' 1828 { 1829 rg := reg 1830 regi := RA + 3 1831 vali := v 1832 newSize := regi + 1 1833 // this section is inlined by go-inline 1834 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1835 { 1836 requiredSize := newSize 1837 if requiredSize > cap(rg.array) { 1838 rg.resize(requiredSize) 1839 } 1840 } 1841 rg.array[regi] = rg.alloc.LNumber2I(vali) 1842 if regi >= rg.top { 1843 rg.top = regi + 1 1844 } 1845 } 1846 } else { 1847 // this section is inlined by go-inline 1848 // source function is 'func (rg *registry) SetTop(topi int) ' in '_state.go' 1849 { 1850 rg := reg 1851 topi := RA + 1 1852 // this section is inlined by go-inline 1853 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1854 { 1855 requiredSize := topi 1856 if requiredSize > cap(rg.array) { 1857 rg.resize(requiredSize) 1858 } 1859 } 1860 oldtopi := rg.top 1861 rg.top = topi 1862 for i := oldtopi; i < rg.top; i++ { 1863 rg.array[i] = LNil 1864 } 1865 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1866 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1867 if rg.top < oldtopi { 1868 nilRange := rg.array[rg.top:oldtopi] 1869 for i := range nilRange { 1870 nilRange[i] = nil 1871 } 1872 } 1873 //for i := rg.top; i < oldtop; i++ { 1874 // rg.array[i] = LNil 1875 //} 1876 } 1877 } 1878 } else { 1879 L.RaiseError("for statement step must be a number") 1880 } 1881 } else { 1882 L.RaiseError("for statement limit must be a number") 1883 } 1884 } else { 1885 L.RaiseError("for statement init must be a number") 1886 } 1887 return 0 1888 }, 1889 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_FORPREP 1890 reg := L.reg 1891 cf := L.currentFrame 1892 lbase := cf.LocalBase 1893 A := int(inst>>18) & 0xff //GETA 1894 RA := lbase + A 1895 Sbx := int(inst&0x3ffff) - opMaxArgSbx //GETSBX 1896 if init, ok1 := reg.Get(RA).(LNumber); ok1 { 1897 if step, ok2 := reg.Get(RA + 2).(LNumber); ok2 { 1898 // this section is inlined by go-inline 1899 // source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go' 1900 { 1901 rg := reg 1902 regi := RA 1903 vali := LNumber(init - step) 1904 newSize := regi + 1 1905 // this section is inlined by go-inline 1906 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1907 { 1908 requiredSize := newSize 1909 if requiredSize > cap(rg.array) { 1910 rg.resize(requiredSize) 1911 } 1912 } 1913 rg.array[regi] = rg.alloc.LNumber2I(vali) 1914 if regi >= rg.top { 1915 rg.top = regi + 1 1916 } 1917 } 1918 } else { 1919 L.RaiseError("for statement step must be a number") 1920 } 1921 } else { 1922 L.RaiseError("for statement init must be a number") 1923 } 1924 cf.Pc += Sbx 1925 return 0 1926 }, 1927 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_TFORLOOP 1928 reg := L.reg 1929 cf := L.currentFrame 1930 lbase := cf.LocalBase 1931 A := int(inst>>18) & 0xff //GETA 1932 RA := lbase + A 1933 C := int(inst>>9) & 0x1ff //GETC 1934 nret := C 1935 // this section is inlined by go-inline 1936 // source function is 'func (rg *registry) SetTop(topi int) ' in '_state.go' 1937 { 1938 rg := reg 1939 topi := RA + 3 + 2 1940 // this section is inlined by go-inline 1941 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1942 { 1943 requiredSize := topi 1944 if requiredSize > cap(rg.array) { 1945 rg.resize(requiredSize) 1946 } 1947 } 1948 oldtopi := rg.top 1949 rg.top = topi 1950 for i := oldtopi; i < rg.top; i++ { 1951 rg.array[i] = LNil 1952 } 1953 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1954 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1955 if rg.top < oldtopi { 1956 nilRange := rg.array[rg.top:oldtopi] 1957 for i := range nilRange { 1958 nilRange[i] = nil 1959 } 1960 } 1961 //for i := rg.top; i < oldtop; i++ { 1962 // rg.array[i] = LNil 1963 //} 1964 } 1965 // this section is inlined by go-inline 1966 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 1967 { 1968 rg := reg 1969 regi := RA + 3 + 2 1970 vali := reg.Get(RA + 2) 1971 newSize := regi + 1 1972 // this section is inlined by go-inline 1973 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1974 { 1975 requiredSize := newSize 1976 if requiredSize > cap(rg.array) { 1977 rg.resize(requiredSize) 1978 } 1979 } 1980 rg.array[regi] = vali 1981 if regi >= rg.top { 1982 rg.top = regi + 1 1983 } 1984 } 1985 // this section is inlined by go-inline 1986 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 1987 { 1988 rg := reg 1989 regi := RA + 3 + 1 1990 vali := reg.Get(RA + 1) 1991 newSize := regi + 1 1992 // this section is inlined by go-inline 1993 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1994 { 1995 requiredSize := newSize 1996 if requiredSize > cap(rg.array) { 1997 rg.resize(requiredSize) 1998 } 1999 } 2000 rg.array[regi] = vali 2001 if regi >= rg.top { 2002 rg.top = regi + 1 2003 } 2004 } 2005 // this section is inlined by go-inline 2006 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 2007 { 2008 rg := reg 2009 regi := RA + 3 2010 vali := reg.Get(RA) 2011 newSize := regi + 1 2012 // this section is inlined by go-inline 2013 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 2014 { 2015 requiredSize := newSize 2016 if requiredSize > cap(rg.array) { 2017 rg.resize(requiredSize) 2018 } 2019 } 2020 rg.array[regi] = vali 2021 if regi >= rg.top { 2022 rg.top = regi + 1 2023 } 2024 } 2025 L.callR(2, nret, RA+3) 2026 if value := reg.Get(RA + 3); value != LNil { 2027 // this section is inlined by go-inline 2028 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 2029 { 2030 rg := reg 2031 regi := RA + 2 2032 vali := value 2033 newSize := regi + 1 2034 // this section is inlined by go-inline 2035 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 2036 { 2037 requiredSize := newSize 2038 if requiredSize > cap(rg.array) { 2039 rg.resize(requiredSize) 2040 } 2041 } 2042 rg.array[regi] = vali 2043 if regi >= rg.top { 2044 rg.top = regi + 1 2045 } 2046 } 2047 pc := cf.Fn.Proto.Code[cf.Pc] 2048 cf.Pc += int(pc&0x3ffff) - opMaxArgSbx 2049 } 2050 cf.Pc++ 2051 return 0 2052 }, 2053 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SETLIST 2054 reg := L.reg 2055 cf := L.currentFrame 2056 lbase := cf.LocalBase 2057 A := int(inst>>18) & 0xff //GETA 2058 RA := lbase + A 2059 B := int(inst & 0x1ff) //GETB 2060 C := int(inst>>9) & 0x1ff //GETC 2061 if C == 0 { 2062 C = int(cf.Fn.Proto.Code[cf.Pc]) 2063 cf.Pc++ 2064 } 2065 offset := (C - 1) * FieldsPerFlush 2066 table := reg.Get(RA).(*LTable) 2067 nelem := B 2068 if B == 0 { 2069 nelem = reg.Top() - RA - 1 2070 } 2071 for i := 1; i <= nelem; i++ { 2072 table.RawSetInt(offset+i, reg.Get(RA+i)) 2073 } 2074 return 0 2075 }, 2076 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_CLOSE 2077 cf := L.currentFrame 2078 lbase := cf.LocalBase 2079 A := int(inst>>18) & 0xff //GETA 2080 RA := lbase + A 2081 // this section is inlined by go-inline 2082 // source function is 'func (ls *LState) closeUpvalues(idx int) ' in '_state.go' 2083 { 2084 ls := L 2085 idx := RA 2086 if ls.uvcache != nil { 2087 var prev *Upvalue 2088 for uv := ls.uvcache; uv != nil; uv = uv.next { 2089 if uv.index >= idx { 2090 if prev != nil { 2091 prev.next = nil 2092 } else { 2093 ls.uvcache = nil 2094 } 2095 uv.Close() 2096 } 2097 prev = uv 2098 } 2099 } 2100 } 2101 return 0 2102 }, 2103 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_CLOSURE 2104 reg := L.reg 2105 cf := L.currentFrame 2106 lbase := cf.LocalBase 2107 A := int(inst>>18) & 0xff //GETA 2108 RA := lbase + A 2109 Bx := int(inst & 0x3ffff) //GETBX 2110 proto := cf.Fn.Proto.FunctionPrototypes[Bx] 2111 closure := newLFunctionL(proto, cf.Fn.Env, int(proto.NumUpvalues)) 2112 // this section is inlined by go-inline 2113 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 2114 { 2115 rg := reg 2116 regi := RA 2117 vali := closure 2118 newSize := regi + 1 2119 // this section is inlined by go-inline 2120 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 2121 { 2122 requiredSize := newSize 2123 if requiredSize > cap(rg.array) { 2124 rg.resize(requiredSize) 2125 } 2126 } 2127 rg.array[regi] = vali 2128 if regi >= rg.top { 2129 rg.top = regi + 1 2130 } 2131 } 2132 for i := 0; i < int(proto.NumUpvalues); i++ { 2133 inst = cf.Fn.Proto.Code[cf.Pc] 2134 cf.Pc++ 2135 B := opGetArgB(inst) 2136 switch opGetOpCode(inst) { 2137 case OP_MOVE: 2138 closure.Upvalues[i] = L.findUpvalue(lbase + B) 2139 case OP_GETUPVAL: 2140 closure.Upvalues[i] = cf.Fn.Upvalues[B] 2141 } 2142 } 2143 return 0 2144 }, 2145 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_VARARG 2146 reg := L.reg 2147 cf := L.currentFrame 2148 lbase := cf.LocalBase 2149 A := int(inst>>18) & 0xff //GETA 2150 RA := lbase + A 2151 B := int(inst & 0x1ff) //GETB 2152 nparams := int(cf.Fn.Proto.NumParameters) 2153 nvarargs := cf.NArgs - nparams 2154 if nvarargs < 0 { 2155 nvarargs = 0 2156 } 2157 nwant := B - 1 2158 if B == 0 { 2159 nwant = nvarargs 2160 } 2161 // this section is inlined by go-inline 2162 // source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go' 2163 { 2164 rg := reg 2165 regv := RA 2166 start := cf.Base + nparams + 1 2167 limit := cf.LocalBase 2168 n := nwant 2169 newSize := regv + n 2170 // this section is inlined by go-inline 2171 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 2172 { 2173 requiredSize := newSize 2174 if requiredSize > cap(rg.array) { 2175 rg.resize(requiredSize) 2176 } 2177 } 2178 if limit == -1 || limit > rg.top { 2179 limit = rg.top 2180 } 2181 for i := 0; i < n; i++ { 2182 srcIdx := start + i 2183 if srcIdx >= limit || srcIdx < 0 { 2184 rg.array[regv+i] = LNil 2185 } else { 2186 rg.array[regv+i] = rg.array[srcIdx] 2187 } 2188 } 2189 2190 // values beyond top don't need to be valid LValues, so setting them to nil is fine 2191 // setting them to nil rather than LNil lets us invoke the golang memclr opto 2192 oldtop := rg.top 2193 rg.top = regv + n 2194 if rg.top < oldtop { 2195 nilRange := rg.array[rg.top:oldtop] 2196 for i := range nilRange { 2197 nilRange[i] = nil 2198 } 2199 } 2200 } 2201 return 0 2202 }, 2203 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_NOP 2204 return 0 2205 }, 2206 } 2207 } 2208 2209 func opArith(L *LState, inst uint32, baseframe *callFrame) int { //OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_MOD, OP_POW 2210 reg := L.reg 2211 cf := L.currentFrame 2212 lbase := cf.LocalBase 2213 A := int(inst>>18) & 0xff //GETA 2214 RA := lbase + A 2215 opcode := int(inst >> 26) //GETOPCODE 2216 B := int(inst & 0x1ff) //GETB 2217 C := int(inst>>9) & 0x1ff //GETC 2218 lhs := L.rkValue(B) 2219 rhs := L.rkValue(C) 2220 v1, ok1 := lhs.(LNumber) 2221 v2, ok2 := rhs.(LNumber) 2222 if ok1 && ok2 { 2223 v := numberArith(L, opcode, LNumber(v1), LNumber(v2)) 2224 // this section is inlined by go-inline 2225 // source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go' 2226 { 2227 rg := reg 2228 regi := RA 2229 vali := v 2230 newSize := regi + 1 2231 // this section is inlined by go-inline 2232 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 2233 { 2234 requiredSize := newSize 2235 if requiredSize > cap(rg.array) { 2236 rg.resize(requiredSize) 2237 } 2238 } 2239 rg.array[regi] = rg.alloc.LNumber2I(vali) 2240 if regi >= rg.top { 2241 rg.top = regi + 1 2242 } 2243 } 2244 } else { 2245 v := objectArith(L, opcode, lhs, rhs) 2246 // this section is inlined by go-inline 2247 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 2248 { 2249 rg := reg 2250 regi := RA 2251 vali := v 2252 newSize := regi + 1 2253 // this section is inlined by go-inline 2254 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 2255 { 2256 requiredSize := newSize 2257 if requiredSize > cap(rg.array) { 2258 rg.resize(requiredSize) 2259 } 2260 } 2261 rg.array[regi] = vali 2262 if regi >= rg.top { 2263 rg.top = regi + 1 2264 } 2265 } 2266 } 2267 return 0 2268 } 2269 2270 func luaModulo(lhs, rhs LNumber) LNumber { 2271 flhs := float64(lhs) 2272 frhs := float64(rhs) 2273 v := math.Mod(flhs, frhs) 2274 if frhs > 0 && v < 0 || frhs < 0 && v > 0 { 2275 v += frhs 2276 } 2277 return LNumber(v) 2278 } 2279 2280 func numberArith(L *LState, opcode int, lhs, rhs LNumber) LNumber { 2281 switch opcode { 2282 case OP_ADD: 2283 return lhs + rhs 2284 case OP_SUB: 2285 return lhs - rhs 2286 case OP_MUL: 2287 return lhs * rhs 2288 case OP_DIV: 2289 return lhs / rhs 2290 case OP_MOD: 2291 return luaModulo(lhs, rhs) 2292 case OP_POW: 2293 flhs := float64(lhs) 2294 frhs := float64(rhs) 2295 return LNumber(math.Pow(flhs, frhs)) 2296 } 2297 panic("should not reach here") 2298 return LNumber(0) 2299 } 2300 2301 func objectArith(L *LState, opcode int, lhs, rhs LValue) LValue { 2302 event := "" 2303 switch opcode { 2304 case OP_ADD: 2305 event = "__add" 2306 case OP_SUB: 2307 event = "__sub" 2308 case OP_MUL: 2309 event = "__mul" 2310 case OP_DIV: 2311 event = "__div" 2312 case OP_MOD: 2313 event = "__mod" 2314 case OP_POW: 2315 event = "__pow" 2316 } 2317 op := L.metaOp2(lhs, rhs, event) 2318 if _, ok := op.(*LFunction); ok { 2319 L.reg.Push(op) 2320 L.reg.Push(lhs) 2321 L.reg.Push(rhs) 2322 L.Call(2, 1) 2323 return L.reg.Pop() 2324 } 2325 if str, ok := lhs.(LString); ok { 2326 if lnum, err := parseNumber(string(str)); err == nil { 2327 lhs = lnum 2328 } 2329 } 2330 if str, ok := rhs.(LString); ok { 2331 if rnum, err := parseNumber(string(str)); err == nil { 2332 rhs = rnum 2333 } 2334 } 2335 if v1, ok1 := lhs.(LNumber); ok1 { 2336 if v2, ok2 := rhs.(LNumber); ok2 { 2337 return numberArith(L, opcode, LNumber(v1), LNumber(v2)) 2338 } 2339 } 2340 L.RaiseError(fmt.Sprintf("cannot perform %v operation between %v and %v", 2341 strings.TrimLeft(event, "_"), lhs.Type().String(), rhs.Type().String())) 2342 2343 return LNil 2344 } 2345 2346 func stringConcat(L *LState, total, last int) LValue { 2347 rhs := L.reg.Get(last) 2348 total-- 2349 for i := last - 1; total > 0; { 2350 lhs := L.reg.Get(i) 2351 if !(LVCanConvToString(lhs) && LVCanConvToString(rhs)) { 2352 op := L.metaOp2(lhs, rhs, "__concat") 2353 if op.Type() == LTFunction { 2354 L.reg.Push(op) 2355 L.reg.Push(lhs) 2356 L.reg.Push(rhs) 2357 L.Call(2, 1) 2358 rhs = L.reg.Pop() 2359 total-- 2360 i-- 2361 } else { 2362 L.RaiseError("cannot perform concat operation between %v and %v", lhs.Type().String(), rhs.Type().String()) 2363 return LNil 2364 } 2365 } else { 2366 buf := make([]string, total+1) 2367 buf[total] = LVAsString(rhs) 2368 for total > 0 { 2369 lhs = L.reg.Get(i) 2370 if !LVCanConvToString(lhs) { 2371 break 2372 } 2373 buf[total-1] = LVAsString(lhs) 2374 i-- 2375 total-- 2376 } 2377 rhs = LString(strings.Join(buf, "")) 2378 } 2379 } 2380 return rhs 2381 } 2382 2383 func lessThan(L *LState, lhs, rhs LValue) bool { 2384 // optimization for numbers 2385 if v1, ok1 := lhs.(LNumber); ok1 { 2386 if v2, ok2 := rhs.(LNumber); ok2 { 2387 return v1 < v2 2388 } 2389 L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String()) 2390 } 2391 if lhs.Type() != rhs.Type() { 2392 L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String()) 2393 return false 2394 } 2395 ret := false 2396 switch lhs.Type() { 2397 case LTString: 2398 ret = strCmp(string(lhs.(LString)), string(rhs.(LString))) < 0 2399 default: 2400 ret = objectRationalWithError(L, lhs, rhs, "__lt") 2401 } 2402 return ret 2403 } 2404 2405 func equals(L *LState, lhs, rhs LValue, raw bool) bool { 2406 lt := lhs.Type() 2407 if lt != rhs.Type() { 2408 return false 2409 } 2410 2411 ret := false 2412 switch lt { 2413 case LTNil: 2414 ret = true 2415 case LTNumber: 2416 v1, _ := lhs.(LNumber) 2417 v2, _ := rhs.(LNumber) 2418 ret = v1 == v2 2419 case LTBool: 2420 ret = bool(lhs.(LBool)) == bool(rhs.(LBool)) 2421 case LTString: 2422 ret = string(lhs.(LString)) == string(rhs.(LString)) 2423 case LTUserData, LTTable: 2424 if lhs == rhs { 2425 ret = true 2426 } else if !raw { 2427 switch objectRational(L, lhs, rhs, "__eq") { 2428 case 1: 2429 ret = true 2430 default: 2431 ret = false 2432 } 2433 } 2434 default: 2435 ret = lhs == rhs 2436 } 2437 return ret 2438 } 2439 2440 func objectRationalWithError(L *LState, lhs, rhs LValue, event string) bool { 2441 switch objectRational(L, lhs, rhs, event) { 2442 case 1: 2443 return true 2444 case 0: 2445 return false 2446 } 2447 L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String()) 2448 return false 2449 } 2450 2451 func objectRational(L *LState, lhs, rhs LValue, event string) int { 2452 m1 := L.metaOp1(lhs, event) 2453 m2 := L.metaOp1(rhs, event) 2454 if m1.Type() == LTFunction && m1 == m2 { 2455 L.reg.Push(m1) 2456 L.reg.Push(lhs) 2457 L.reg.Push(rhs) 2458 L.Call(2, 1) 2459 if LVAsBool(L.reg.Pop()) { 2460 return 1 2461 } 2462 return 0 2463 } 2464 return -1 2465 }