github.com/enotodden/gopher-lua@v1.1.2/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_BITOR 764 opArith, // OP_MOD 765 opArith, // OP_POW 766 func(L *LState, inst uint32, baseframe *callFrame) int { // OP_UNM 767 reg := L.reg 768 cf := L.currentFrame 769 lbase := cf.LocalBase 770 A := int(inst>>18) & 0xff // GETA 771 RA := lbase + A 772 B := int(inst & 0x1ff) // GETB 773 unaryv := L.rkValue(B) 774 if nm, ok := unaryv.(LNumber); ok { 775 // this section is inlined by go-inline 776 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 777 { 778 rg := reg 779 regi := RA 780 vali := -nm 781 newSize := regi + 1 782 // this section is inlined by go-inline 783 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 784 { 785 requiredSize := newSize 786 if requiredSize > cap(rg.array) { 787 rg.resize(requiredSize) 788 } 789 } 790 rg.array[regi] = vali 791 if regi >= rg.top { 792 rg.top = regi + 1 793 } 794 } 795 } else { 796 op := L.metaOp1(unaryv, "__unm") 797 if op.Type() == LTFunction { 798 reg.Push(op) 799 reg.Push(unaryv) 800 L.Call(1, 1) 801 // this section is inlined by go-inline 802 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 803 { 804 rg := reg 805 regi := RA 806 vali := reg.Pop() 807 newSize := regi + 1 808 // this section is inlined by go-inline 809 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 810 { 811 requiredSize := newSize 812 if requiredSize > cap(rg.array) { 813 rg.resize(requiredSize) 814 } 815 } 816 rg.array[regi] = vali 817 if regi >= rg.top { 818 rg.top = regi + 1 819 } 820 } 821 } else if str, ok1 := unaryv.(LString); ok1 { 822 if num, err := parseNumber(string(str)); err == nil { 823 // this section is inlined by go-inline 824 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 825 { 826 rg := reg 827 regi := RA 828 vali := -num 829 newSize := regi + 1 830 // this section is inlined by go-inline 831 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 832 { 833 requiredSize := newSize 834 if requiredSize > cap(rg.array) { 835 rg.resize(requiredSize) 836 } 837 } 838 rg.array[regi] = vali 839 if regi >= rg.top { 840 rg.top = regi + 1 841 } 842 } 843 } else { 844 L.RaiseError("__unm undefined") 845 } 846 } else { 847 L.RaiseError("__unm undefined") 848 } 849 } 850 return 0 851 }, 852 func(L *LState, inst uint32, baseframe *callFrame) int { // OP_NOT 853 reg := L.reg 854 cf := L.currentFrame 855 lbase := cf.LocalBase 856 A := int(inst>>18) & 0xff // GETA 857 RA := lbase + A 858 B := int(inst & 0x1ff) // GETB 859 if LVIsFalse(reg.Get(lbase + B)) { 860 // this section is inlined by go-inline 861 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 862 { 863 rg := reg 864 regi := RA 865 vali := LTrue 866 newSize := regi + 1 867 // this section is inlined by go-inline 868 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 869 { 870 requiredSize := newSize 871 if requiredSize > cap(rg.array) { 872 rg.resize(requiredSize) 873 } 874 } 875 rg.array[regi] = vali 876 if regi >= rg.top { 877 rg.top = regi + 1 878 } 879 } 880 } else { 881 // this section is inlined by go-inline 882 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 883 { 884 rg := reg 885 regi := RA 886 vali := LFalse 887 newSize := regi + 1 888 // this section is inlined by go-inline 889 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 890 { 891 requiredSize := newSize 892 if requiredSize > cap(rg.array) { 893 rg.resize(requiredSize) 894 } 895 } 896 rg.array[regi] = vali 897 if regi >= rg.top { 898 rg.top = regi + 1 899 } 900 } 901 } 902 return 0 903 }, 904 func(L *LState, inst uint32, baseframe *callFrame) int { // OP_LEN 905 reg := L.reg 906 cf := L.currentFrame 907 lbase := cf.LocalBase 908 A := int(inst>>18) & 0xff // GETA 909 RA := lbase + A 910 B := int(inst & 0x1ff) // GETB 911 switch lv := L.rkValue(B).(type) { 912 case LString: 913 // this section is inlined by go-inline 914 // source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go' 915 { 916 rg := reg 917 regi := RA 918 vali := LNumber(len(lv)) 919 newSize := regi + 1 920 // this section is inlined by go-inline 921 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 922 { 923 requiredSize := newSize 924 if requiredSize > cap(rg.array) { 925 rg.resize(requiredSize) 926 } 927 } 928 rg.array[regi] = rg.alloc.LNumber2I(vali) 929 if regi >= rg.top { 930 rg.top = regi + 1 931 } 932 } 933 default: 934 op := L.metaOp1(lv, "__len") 935 if op.Type() == LTFunction { 936 reg.Push(op) 937 reg.Push(lv) 938 L.Call(1, 1) 939 ret := reg.Pop() 940 if ret.Type() == LTNumber { 941 v, _ := ret.(LNumber) 942 // this section is inlined by go-inline 943 // source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go' 944 { 945 rg := reg 946 regi := RA 947 vali := v 948 newSize := regi + 1 949 // this section is inlined by go-inline 950 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 951 { 952 requiredSize := newSize 953 if requiredSize > cap(rg.array) { 954 rg.resize(requiredSize) 955 } 956 } 957 rg.array[regi] = rg.alloc.LNumber2I(vali) 958 if regi >= rg.top { 959 rg.top = regi + 1 960 } 961 } 962 } else { 963 // this section is inlined by go-inline 964 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 965 { 966 rg := reg 967 regi := RA 968 vali := ret 969 newSize := regi + 1 970 // this section is inlined by go-inline 971 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 972 { 973 requiredSize := newSize 974 if requiredSize > cap(rg.array) { 975 rg.resize(requiredSize) 976 } 977 } 978 rg.array[regi] = vali 979 if regi >= rg.top { 980 rg.top = regi + 1 981 } 982 } 983 } 984 } else if lv.Type() == LTTable { 985 // this section is inlined by go-inline 986 // source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go' 987 { 988 rg := reg 989 regi := RA 990 vali := LNumber(lv.(*LTable).Len()) 991 newSize := regi + 1 992 // this section is inlined by go-inline 993 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 994 { 995 requiredSize := newSize 996 if requiredSize > cap(rg.array) { 997 rg.resize(requiredSize) 998 } 999 } 1000 rg.array[regi] = rg.alloc.LNumber2I(vali) 1001 if regi >= rg.top { 1002 rg.top = regi + 1 1003 } 1004 } 1005 } else { 1006 L.RaiseError("__len undefined") 1007 } 1008 } 1009 return 0 1010 }, 1011 func(L *LState, inst uint32, baseframe *callFrame) int { // OP_CONCAT 1012 reg := L.reg 1013 cf := L.currentFrame 1014 lbase := cf.LocalBase 1015 A := int(inst>>18) & 0xff // GETA 1016 RA := lbase + A 1017 B := int(inst & 0x1ff) // GETB 1018 C := int(inst>>9) & 0x1ff // GETC 1019 RC := lbase + C 1020 RB := lbase + B 1021 v := stringConcat(L, RC-RB+1, RC) 1022 // this section is inlined by go-inline 1023 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 1024 { 1025 rg := reg 1026 regi := RA 1027 vali := v 1028 newSize := regi + 1 1029 // this section is inlined by go-inline 1030 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1031 { 1032 requiredSize := newSize 1033 if requiredSize > cap(rg.array) { 1034 rg.resize(requiredSize) 1035 } 1036 } 1037 rg.array[regi] = vali 1038 if regi >= rg.top { 1039 rg.top = regi + 1 1040 } 1041 } 1042 return 0 1043 }, 1044 func(L *LState, inst uint32, baseframe *callFrame) int { // OP_JMP 1045 cf := L.currentFrame 1046 Sbx := int(inst&0x3ffff) - opMaxArgSbx // GETSBX 1047 cf.Pc += Sbx 1048 return 0 1049 }, 1050 func(L *LState, inst uint32, baseframe *callFrame) int { // OP_EQ 1051 cf := L.currentFrame 1052 A := int(inst>>18) & 0xff // GETA 1053 B := int(inst & 0x1ff) // GETB 1054 C := int(inst>>9) & 0x1ff // GETC 1055 ret := equals(L, L.rkValue(B), L.rkValue(C), false) 1056 v := 1 1057 if ret { 1058 v = 0 1059 } 1060 if v == A { 1061 cf.Pc++ 1062 } 1063 return 0 1064 }, 1065 func(L *LState, inst uint32, baseframe *callFrame) int { // OP_LT 1066 cf := L.currentFrame 1067 A := int(inst>>18) & 0xff // GETA 1068 B := int(inst & 0x1ff) // GETB 1069 C := int(inst>>9) & 0x1ff // GETC 1070 ret := lessThan(L, L.rkValue(B), L.rkValue(C)) 1071 v := 1 1072 if ret { 1073 v = 0 1074 } 1075 if v == A { 1076 cf.Pc++ 1077 } 1078 return 0 1079 }, 1080 func(L *LState, inst uint32, baseframe *callFrame) int { // OP_LE 1081 cf := L.currentFrame 1082 A := int(inst>>18) & 0xff // GETA 1083 B := int(inst & 0x1ff) // GETB 1084 C := int(inst>>9) & 0x1ff // GETC 1085 lhs := L.rkValue(B) 1086 rhs := L.rkValue(C) 1087 ret := false 1088 1089 if v1, ok1 := lhs.(LNumber); ok1 { 1090 if v2, ok2 := rhs.(LNumber); ok2 { 1091 ret = v1 <= v2 1092 } else { 1093 L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String()) 1094 } 1095 } else { 1096 if lhs.Type() != rhs.Type() { 1097 L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String()) 1098 } 1099 switch lhs.Type() { 1100 case LTString: 1101 ret = strCmp(string(lhs.(LString)), string(rhs.(LString))) <= 0 1102 default: 1103 switch objectRational(L, lhs, rhs, "__le") { 1104 case 1: 1105 ret = true 1106 case 0: 1107 ret = false 1108 default: 1109 ret = !objectRationalWithError(L, rhs, lhs, "__lt") 1110 } 1111 } 1112 } 1113 1114 v := 1 1115 if ret { 1116 v = 0 1117 } 1118 if v == A { 1119 cf.Pc++ 1120 } 1121 return 0 1122 }, 1123 func(L *LState, inst uint32, baseframe *callFrame) int { // OP_TEST 1124 reg := L.reg 1125 cf := L.currentFrame 1126 lbase := cf.LocalBase 1127 A := int(inst>>18) & 0xff // GETA 1128 RA := lbase + A 1129 C := int(inst>>9) & 0x1ff // GETC 1130 if LVAsBool(reg.Get(RA)) == (C == 0) { 1131 cf.Pc++ 1132 } 1133 return 0 1134 }, 1135 func(L *LState, inst uint32, baseframe *callFrame) int { // OP_TESTSET 1136 reg := L.reg 1137 cf := L.currentFrame 1138 lbase := cf.LocalBase 1139 A := int(inst>>18) & 0xff // GETA 1140 RA := lbase + A 1141 B := int(inst & 0x1ff) // GETB 1142 C := int(inst>>9) & 0x1ff // GETC 1143 if value := reg.Get(lbase + B); LVAsBool(value) != (C == 0) { 1144 // this section is inlined by go-inline 1145 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 1146 { 1147 rg := reg 1148 regi := RA 1149 vali := value 1150 newSize := regi + 1 1151 // this section is inlined by go-inline 1152 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1153 { 1154 requiredSize := newSize 1155 if requiredSize > cap(rg.array) { 1156 rg.resize(requiredSize) 1157 } 1158 } 1159 rg.array[regi] = vali 1160 if regi >= rg.top { 1161 rg.top = regi + 1 1162 } 1163 } 1164 } else { 1165 cf.Pc++ 1166 } 1167 return 0 1168 }, 1169 func(L *LState, inst uint32, baseframe *callFrame) int { // OP_CALL 1170 reg := L.reg 1171 cf := L.currentFrame 1172 lbase := cf.LocalBase 1173 A := int(inst>>18) & 0xff // GETA 1174 RA := lbase + A 1175 B := int(inst & 0x1ff) // GETB 1176 C := int(inst>>9) & 0x1ff // GETC 1177 nargs := B - 1 1178 if B == 0 { 1179 nargs = reg.Top() - (RA + 1) 1180 } 1181 lv := reg.Get(RA) 1182 nret := C - 1 1183 var callable *LFunction 1184 var meta bool 1185 if fn, ok := lv.(*LFunction); ok { 1186 callable = fn 1187 meta = false 1188 } else { 1189 callable, meta = L.metaCall(lv) 1190 } 1191 // this section is inlined by go-inline 1192 // source function is 'func (ls *LState) pushCallFrame(cf callFrame, fn LValue, meta bool) ' in '_state.go' 1193 { 1194 ls := L 1195 cf := callFrame{Fn: callable, Pc: 0, Base: RA, LocalBase: RA + 1, ReturnBase: RA, NArgs: nargs, NRet: nret, Parent: cf, TailCall: 0} 1196 fn := lv 1197 if meta { 1198 cf.NArgs++ 1199 ls.reg.Insert(fn, cf.LocalBase) 1200 } 1201 if cf.Fn == nil { 1202 ls.RaiseError("attempt to call a non-function object") 1203 } 1204 if ls.stack.IsFull() { 1205 ls.RaiseError("stack overflow") 1206 } 1207 ls.stack.Push(cf) 1208 newcf := ls.stack.Last() 1209 // this section is inlined by go-inline 1210 // source function is 'func (ls *LState) initCallFrame(cf *callFrame) ' in '_state.go' 1211 { 1212 cf := newcf 1213 if cf.Fn.IsG { 1214 ls.reg.SetTop(cf.LocalBase + cf.NArgs) 1215 } else { 1216 proto := cf.Fn.Proto 1217 nargs := cf.NArgs 1218 np := int(proto.NumParameters) 1219 if nargs < np { 1220 // default any missing arguments to nil 1221 newSize := cf.LocalBase + np 1222 // this section is inlined by go-inline 1223 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1224 { 1225 rg := ls.reg 1226 requiredSize := newSize 1227 if requiredSize > cap(rg.array) { 1228 rg.resize(requiredSize) 1229 } 1230 } 1231 for i := nargs; i < np; i++ { 1232 ls.reg.array[cf.LocalBase+i] = LNil 1233 } 1234 nargs = np 1235 ls.reg.top = newSize 1236 } 1237 1238 if (proto.IsVarArg & VarArgIsVarArg) == 0 { 1239 if nargs < int(proto.NumUsedRegisters) { 1240 nargs = int(proto.NumUsedRegisters) 1241 } 1242 newSize := cf.LocalBase + nargs 1243 // this section is inlined by go-inline 1244 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1245 { 1246 rg := ls.reg 1247 requiredSize := newSize 1248 if requiredSize > cap(rg.array) { 1249 rg.resize(requiredSize) 1250 } 1251 } 1252 for i := np; i < nargs; i++ { 1253 ls.reg.array[cf.LocalBase+i] = LNil 1254 } 1255 ls.reg.top = cf.LocalBase + int(proto.NumUsedRegisters) 1256 } else { 1257 /* swap vararg positions: 1258 closure 1259 namedparam1 <- lbase 1260 namedparam2 1261 vararg1 1262 vararg2 1263 1264 TO 1265 1266 closure 1267 nil 1268 nil 1269 vararg1 1270 vararg2 1271 namedparam1 <- lbase 1272 namedparam2 1273 */ 1274 nvarargs := nargs - np 1275 if nvarargs < 0 { 1276 nvarargs = 0 1277 } 1278 1279 ls.reg.SetTop(cf.LocalBase + nargs + np) 1280 for i := 0; i < np; i++ { 1281 // ls.reg.Set(cf.LocalBase+nargs+i, ls.reg.Get(cf.LocalBase+i)) 1282 ls.reg.array[cf.LocalBase+nargs+i] = ls.reg.array[cf.LocalBase+i] 1283 // ls.reg.Set(cf.LocalBase+i, LNil) 1284 ls.reg.array[cf.LocalBase+i] = LNil 1285 } 1286 1287 if CompatVarArg { 1288 ls.reg.SetTop(cf.LocalBase + nargs + np + 1) 1289 if (proto.IsVarArg & VarArgNeedsArg) != 0 { 1290 argtb := newLTable(nvarargs, 0) 1291 for i := 0; i < nvarargs; i++ { 1292 argtb.RawSetInt(i+1, ls.reg.Get(cf.LocalBase+np+i)) 1293 } 1294 argtb.RawSetString("n", LNumber(nvarargs)) 1295 // ls.reg.Set(cf.LocalBase+nargs+np, argtb) 1296 ls.reg.array[cf.LocalBase+nargs+np] = argtb 1297 } else { 1298 ls.reg.array[cf.LocalBase+nargs+np] = LNil 1299 } 1300 } 1301 cf.LocalBase += nargs 1302 maxreg := cf.LocalBase + int(proto.NumUsedRegisters) 1303 ls.reg.SetTop(maxreg) 1304 } 1305 } 1306 } 1307 ls.currentFrame = newcf 1308 } 1309 if callable.IsG && callGFunction(L, false) { 1310 return 1 1311 } 1312 return 0 1313 }, 1314 func(L *LState, inst uint32, baseframe *callFrame) int { // OP_TAILCALL 1315 reg := L.reg 1316 cf := L.currentFrame 1317 lbase := cf.LocalBase 1318 A := int(inst>>18) & 0xff // GETA 1319 RA := lbase + A 1320 B := int(inst & 0x1ff) // GETB 1321 nargs := B - 1 1322 if B == 0 { 1323 nargs = reg.Top() - (RA + 1) 1324 } 1325 lv := reg.Get(RA) 1326 var callable *LFunction 1327 var meta bool 1328 if fn, ok := lv.(*LFunction); ok { 1329 callable = fn 1330 meta = false 1331 } else { 1332 callable, meta = L.metaCall(lv) 1333 } 1334 if callable == nil { 1335 L.RaiseError("attempt to call a non-function object") 1336 } 1337 // this section is inlined by go-inline 1338 // source function is 'func (ls *LState) closeUpvalues(idx int) ' in '_state.go' 1339 { 1340 ls := L 1341 idx := lbase 1342 if ls.uvcache != nil { 1343 var prev *Upvalue 1344 for uv := ls.uvcache; uv != nil; uv = uv.next { 1345 if uv.index >= idx { 1346 if prev != nil { 1347 prev.next = nil 1348 } else { 1349 ls.uvcache = nil 1350 } 1351 uv.Close() 1352 } 1353 prev = uv 1354 } 1355 } 1356 } 1357 if callable.IsG { 1358 luaframe := cf 1359 L.pushCallFrame(callFrame{ 1360 Fn: callable, 1361 Pc: 0, 1362 Base: RA, 1363 LocalBase: RA + 1, 1364 ReturnBase: cf.ReturnBase, 1365 NArgs: nargs, 1366 NRet: cf.NRet, 1367 Parent: cf, 1368 TailCall: 0, 1369 }, lv, meta) 1370 if callGFunction(L, true) { 1371 return 1 1372 } 1373 if L.currentFrame == nil || L.currentFrame.Fn.IsG || luaframe == baseframe { 1374 return 1 1375 } 1376 } else { 1377 base := cf.Base 1378 cf.Fn = callable 1379 cf.Pc = 0 1380 cf.Base = RA 1381 cf.LocalBase = RA + 1 1382 cf.ReturnBase = cf.ReturnBase 1383 cf.NArgs = nargs 1384 cf.NRet = cf.NRet 1385 cf.TailCall++ 1386 lbase := cf.LocalBase 1387 if meta { 1388 cf.NArgs++ 1389 L.reg.Insert(lv, cf.LocalBase) 1390 } 1391 // this section is inlined by go-inline 1392 // source function is 'func (ls *LState) initCallFrame(cf *callFrame) ' in '_state.go' 1393 { 1394 ls := L 1395 if cf.Fn.IsG { 1396 ls.reg.SetTop(cf.LocalBase + cf.NArgs) 1397 } else { 1398 proto := cf.Fn.Proto 1399 nargs := cf.NArgs 1400 np := int(proto.NumParameters) 1401 if nargs < np { 1402 // default any missing arguments to nil 1403 newSize := cf.LocalBase + np 1404 // this section is inlined by go-inline 1405 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1406 { 1407 rg := ls.reg 1408 requiredSize := newSize 1409 if requiredSize > cap(rg.array) { 1410 rg.resize(requiredSize) 1411 } 1412 } 1413 for i := nargs; i < np; i++ { 1414 ls.reg.array[cf.LocalBase+i] = LNil 1415 } 1416 nargs = np 1417 ls.reg.top = newSize 1418 } 1419 1420 if (proto.IsVarArg & VarArgIsVarArg) == 0 { 1421 if nargs < int(proto.NumUsedRegisters) { 1422 nargs = int(proto.NumUsedRegisters) 1423 } 1424 newSize := cf.LocalBase + nargs 1425 // this section is inlined by go-inline 1426 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1427 { 1428 rg := ls.reg 1429 requiredSize := newSize 1430 if requiredSize > cap(rg.array) { 1431 rg.resize(requiredSize) 1432 } 1433 } 1434 for i := np; i < nargs; i++ { 1435 ls.reg.array[cf.LocalBase+i] = LNil 1436 } 1437 ls.reg.top = cf.LocalBase + int(proto.NumUsedRegisters) 1438 } else { 1439 /* swap vararg positions: 1440 closure 1441 namedparam1 <- lbase 1442 namedparam2 1443 vararg1 1444 vararg2 1445 1446 TO 1447 1448 closure 1449 nil 1450 nil 1451 vararg1 1452 vararg2 1453 namedparam1 <- lbase 1454 namedparam2 1455 */ 1456 nvarargs := nargs - np 1457 if nvarargs < 0 { 1458 nvarargs = 0 1459 } 1460 1461 ls.reg.SetTop(cf.LocalBase + nargs + np) 1462 for i := 0; i < np; i++ { 1463 // ls.reg.Set(cf.LocalBase+nargs+i, ls.reg.Get(cf.LocalBase+i)) 1464 ls.reg.array[cf.LocalBase+nargs+i] = ls.reg.array[cf.LocalBase+i] 1465 // ls.reg.Set(cf.LocalBase+i, LNil) 1466 ls.reg.array[cf.LocalBase+i] = LNil 1467 } 1468 1469 if CompatVarArg { 1470 ls.reg.SetTop(cf.LocalBase + nargs + np + 1) 1471 if (proto.IsVarArg & VarArgNeedsArg) != 0 { 1472 argtb := newLTable(nvarargs, 0) 1473 for i := 0; i < nvarargs; i++ { 1474 argtb.RawSetInt(i+1, ls.reg.Get(cf.LocalBase+np+i)) 1475 } 1476 argtb.RawSetString("n", LNumber(nvarargs)) 1477 // ls.reg.Set(cf.LocalBase+nargs+np, argtb) 1478 ls.reg.array[cf.LocalBase+nargs+np] = argtb 1479 } else { 1480 ls.reg.array[cf.LocalBase+nargs+np] = LNil 1481 } 1482 } 1483 cf.LocalBase += nargs 1484 maxreg := cf.LocalBase + int(proto.NumUsedRegisters) 1485 ls.reg.SetTop(maxreg) 1486 } 1487 } 1488 } 1489 // this section is inlined by go-inline 1490 // source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go' 1491 { 1492 rg := L.reg 1493 regv := base 1494 start := RA 1495 limit := -1 1496 n := reg.Top() - RA - 1 1497 newSize := regv + n 1498 // this section is inlined by go-inline 1499 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1500 { 1501 requiredSize := newSize 1502 if requiredSize > cap(rg.array) { 1503 rg.resize(requiredSize) 1504 } 1505 } 1506 if limit == -1 || limit > rg.top { 1507 limit = rg.top 1508 } 1509 for i := 0; i < n; i++ { 1510 srcIdx := start + i 1511 if srcIdx >= limit || srcIdx < 0 { 1512 rg.array[regv+i] = LNil 1513 } else { 1514 rg.array[regv+i] = rg.array[srcIdx] 1515 } 1516 } 1517 1518 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1519 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1520 oldtop := rg.top 1521 rg.top = regv + n 1522 if rg.top < oldtop { 1523 nilRange := rg.array[rg.top:oldtop] 1524 for i := range nilRange { 1525 nilRange[i] = nil 1526 } 1527 } 1528 } 1529 cf.Base = base 1530 cf.LocalBase = base + (cf.LocalBase - lbase + 1) 1531 } 1532 return 0 1533 }, 1534 func(L *LState, inst uint32, baseframe *callFrame) int { // OP_RETURN 1535 reg := L.reg 1536 cf := L.currentFrame 1537 lbase := cf.LocalBase 1538 A := int(inst>>18) & 0xff // GETA 1539 RA := lbase + A 1540 B := int(inst & 0x1ff) // GETB 1541 // this section is inlined by go-inline 1542 // source function is 'func (ls *LState) closeUpvalues(idx int) ' in '_state.go' 1543 { 1544 ls := L 1545 idx := lbase 1546 if ls.uvcache != nil { 1547 var prev *Upvalue 1548 for uv := ls.uvcache; uv != nil; uv = uv.next { 1549 if uv.index >= idx { 1550 if prev != nil { 1551 prev.next = nil 1552 } else { 1553 ls.uvcache = nil 1554 } 1555 uv.Close() 1556 } 1557 prev = uv 1558 } 1559 } 1560 } 1561 nret := B - 1 1562 if B == 0 { 1563 nret = reg.Top() - RA 1564 } 1565 n := cf.NRet 1566 if cf.NRet == MultRet { 1567 n = nret 1568 } 1569 1570 if L.Parent != nil && L.stack.Sp() == 1 { 1571 // this section is inlined by go-inline 1572 // source function is 'func copyReturnValues(L *LState, regv, start, n, b int) ' in '_vm.go' 1573 { 1574 regv := reg.Top() 1575 start := RA 1576 b := B 1577 if b == 1 { 1578 // this section is inlined by go-inline 1579 // source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go' 1580 { 1581 rg := L.reg 1582 regm := regv 1583 newSize := regm + n 1584 // this section is inlined by go-inline 1585 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1586 { 1587 requiredSize := newSize 1588 if requiredSize > cap(rg.array) { 1589 rg.resize(requiredSize) 1590 } 1591 } 1592 for i := 0; i < n; i++ { 1593 rg.array[regm+i] = LNil 1594 } 1595 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1596 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1597 oldtop := rg.top 1598 rg.top = regm + n 1599 if rg.top < oldtop { 1600 nilRange := rg.array[rg.top:oldtop] 1601 for i := range nilRange { 1602 nilRange[i] = nil 1603 } 1604 } 1605 } 1606 } else { 1607 // this section is inlined by go-inline 1608 // source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go' 1609 { 1610 rg := L.reg 1611 limit := -1 1612 newSize := regv + n 1613 // this section is inlined by go-inline 1614 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1615 { 1616 requiredSize := newSize 1617 if requiredSize > cap(rg.array) { 1618 rg.resize(requiredSize) 1619 } 1620 } 1621 if limit == -1 || limit > rg.top { 1622 limit = rg.top 1623 } 1624 for i := 0; i < n; i++ { 1625 srcIdx := start + i 1626 if srcIdx >= limit || srcIdx < 0 { 1627 rg.array[regv+i] = LNil 1628 } else { 1629 rg.array[regv+i] = rg.array[srcIdx] 1630 } 1631 } 1632 1633 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1634 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1635 oldtop := rg.top 1636 rg.top = regv + n 1637 if rg.top < oldtop { 1638 nilRange := rg.array[rg.top:oldtop] 1639 for i := range nilRange { 1640 nilRange[i] = nil 1641 } 1642 } 1643 } 1644 if b > 1 && n > (b-1) { 1645 // this section is inlined by go-inline 1646 // source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go' 1647 { 1648 rg := L.reg 1649 regm := regv + b - 1 1650 n := n - (b - 1) 1651 newSize := regm + n 1652 // this section is inlined by go-inline 1653 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1654 { 1655 requiredSize := newSize 1656 if requiredSize > cap(rg.array) { 1657 rg.resize(requiredSize) 1658 } 1659 } 1660 for i := 0; i < n; i++ { 1661 rg.array[regm+i] = LNil 1662 } 1663 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1664 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1665 oldtop := rg.top 1666 rg.top = regm + n 1667 if rg.top < oldtop { 1668 nilRange := rg.array[rg.top:oldtop] 1669 for i := range nilRange { 1670 nilRange[i] = nil 1671 } 1672 } 1673 } 1674 } 1675 } 1676 } 1677 switchToParentThread(L, n, false, true) 1678 return 1 1679 } 1680 islast := baseframe == L.stack.Pop() || L.stack.IsEmpty() 1681 // this section is inlined by go-inline 1682 // source function is 'func copyReturnValues(L *LState, regv, start, n, b int) ' in '_vm.go' 1683 { 1684 regv := cf.ReturnBase 1685 start := RA 1686 b := B 1687 if b == 1 { 1688 // this section is inlined by go-inline 1689 // source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go' 1690 { 1691 rg := L.reg 1692 regm := regv 1693 newSize := regm + n 1694 // this section is inlined by go-inline 1695 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1696 { 1697 requiredSize := newSize 1698 if requiredSize > cap(rg.array) { 1699 rg.resize(requiredSize) 1700 } 1701 } 1702 for i := 0; i < n; i++ { 1703 rg.array[regm+i] = LNil 1704 } 1705 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1706 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1707 oldtop := rg.top 1708 rg.top = regm + n 1709 if rg.top < oldtop { 1710 nilRange := rg.array[rg.top:oldtop] 1711 for i := range nilRange { 1712 nilRange[i] = nil 1713 } 1714 } 1715 } 1716 } else { 1717 // this section is inlined by go-inline 1718 // source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go' 1719 { 1720 rg := L.reg 1721 limit := -1 1722 newSize := regv + n 1723 // this section is inlined by go-inline 1724 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1725 { 1726 requiredSize := newSize 1727 if requiredSize > cap(rg.array) { 1728 rg.resize(requiredSize) 1729 } 1730 } 1731 if limit == -1 || limit > rg.top { 1732 limit = rg.top 1733 } 1734 for i := 0; i < n; i++ { 1735 srcIdx := start + i 1736 if srcIdx >= limit || srcIdx < 0 { 1737 rg.array[regv+i] = LNil 1738 } else { 1739 rg.array[regv+i] = rg.array[srcIdx] 1740 } 1741 } 1742 1743 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1744 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1745 oldtop := rg.top 1746 rg.top = regv + n 1747 if rg.top < oldtop { 1748 nilRange := rg.array[rg.top:oldtop] 1749 for i := range nilRange { 1750 nilRange[i] = nil 1751 } 1752 } 1753 } 1754 if b > 1 && n > (b-1) { 1755 // this section is inlined by go-inline 1756 // source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go' 1757 { 1758 rg := L.reg 1759 regm := regv + b - 1 1760 n := n - (b - 1) 1761 newSize := regm + n 1762 // this section is inlined by go-inline 1763 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1764 { 1765 requiredSize := newSize 1766 if requiredSize > cap(rg.array) { 1767 rg.resize(requiredSize) 1768 } 1769 } 1770 for i := 0; i < n; i++ { 1771 rg.array[regm+i] = LNil 1772 } 1773 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1774 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1775 oldtop := rg.top 1776 rg.top = regm + n 1777 if rg.top < oldtop { 1778 nilRange := rg.array[rg.top:oldtop] 1779 for i := range nilRange { 1780 nilRange[i] = nil 1781 } 1782 } 1783 } 1784 } 1785 } 1786 } 1787 L.currentFrame = L.stack.Last() 1788 if islast || L.currentFrame == nil || L.currentFrame.Fn.IsG { 1789 return 1 1790 } 1791 return 0 1792 }, 1793 func(L *LState, inst uint32, baseframe *callFrame) int { // OP_FORLOOP 1794 reg := L.reg 1795 cf := L.currentFrame 1796 lbase := cf.LocalBase 1797 A := int(inst>>18) & 0xff // GETA 1798 RA := lbase + A 1799 if init, ok1 := reg.Get(RA).(LNumber); ok1 { 1800 if limit, ok2 := reg.Get(RA + 1).(LNumber); ok2 { 1801 if step, ok3 := reg.Get(RA + 2).(LNumber); ok3 { 1802 init += step 1803 v := LNumber(init) 1804 // this section is inlined by go-inline 1805 // source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go' 1806 { 1807 rg := reg 1808 regi := RA 1809 vali := v 1810 newSize := regi + 1 1811 // this section is inlined by go-inline 1812 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1813 { 1814 requiredSize := newSize 1815 if requiredSize > cap(rg.array) { 1816 rg.resize(requiredSize) 1817 } 1818 } 1819 rg.array[regi] = rg.alloc.LNumber2I(vali) 1820 if regi >= rg.top { 1821 rg.top = regi + 1 1822 } 1823 } 1824 if (step > 0 && init <= limit) || (step <= 0 && init >= limit) { 1825 Sbx := int(inst&0x3ffff) - opMaxArgSbx // GETSBX 1826 cf.Pc += Sbx 1827 // this section is inlined by go-inline 1828 // source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go' 1829 { 1830 rg := reg 1831 regi := RA + 3 1832 vali := v 1833 newSize := regi + 1 1834 // this section is inlined by go-inline 1835 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1836 { 1837 requiredSize := newSize 1838 if requiredSize > cap(rg.array) { 1839 rg.resize(requiredSize) 1840 } 1841 } 1842 rg.array[regi] = rg.alloc.LNumber2I(vali) 1843 if regi >= rg.top { 1844 rg.top = regi + 1 1845 } 1846 } 1847 } else { 1848 // this section is inlined by go-inline 1849 // source function is 'func (rg *registry) SetTop(topi int) ' in '_state.go' 1850 { 1851 rg := reg 1852 topi := RA + 1 1853 // this section is inlined by go-inline 1854 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1855 { 1856 requiredSize := topi 1857 if requiredSize > cap(rg.array) { 1858 rg.resize(requiredSize) 1859 } 1860 } 1861 oldtopi := rg.top 1862 rg.top = topi 1863 for i := oldtopi; i < rg.top; i++ { 1864 rg.array[i] = LNil 1865 } 1866 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1867 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1868 if rg.top < oldtopi { 1869 nilRange := rg.array[rg.top:oldtopi] 1870 for i := range nilRange { 1871 nilRange[i] = nil 1872 } 1873 } 1874 //for i := rg.top; i < oldtop; i++ { 1875 // rg.array[i] = LNil 1876 //} 1877 } 1878 } 1879 } else { 1880 L.RaiseError("for statement step must be a number") 1881 } 1882 } else { 1883 L.RaiseError("for statement limit must be a number") 1884 } 1885 } else { 1886 L.RaiseError("for statement init must be a number") 1887 } 1888 return 0 1889 }, 1890 func(L *LState, inst uint32, baseframe *callFrame) int { // OP_FORPREP 1891 reg := L.reg 1892 cf := L.currentFrame 1893 lbase := cf.LocalBase 1894 A := int(inst>>18) & 0xff // GETA 1895 RA := lbase + A 1896 Sbx := int(inst&0x3ffff) - opMaxArgSbx // GETSBX 1897 if init, ok1 := reg.Get(RA).(LNumber); ok1 { 1898 if step, ok2 := reg.Get(RA + 2).(LNumber); ok2 { 1899 // this section is inlined by go-inline 1900 // source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go' 1901 { 1902 rg := reg 1903 regi := RA 1904 vali := LNumber(init - step) 1905 newSize := regi + 1 1906 // this section is inlined by go-inline 1907 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1908 { 1909 requiredSize := newSize 1910 if requiredSize > cap(rg.array) { 1911 rg.resize(requiredSize) 1912 } 1913 } 1914 rg.array[regi] = rg.alloc.LNumber2I(vali) 1915 if regi >= rg.top { 1916 rg.top = regi + 1 1917 } 1918 } 1919 } else { 1920 L.RaiseError("for statement step must be a number") 1921 } 1922 } else { 1923 L.RaiseError("for statement init must be a number") 1924 } 1925 cf.Pc += Sbx 1926 return 0 1927 }, 1928 func(L *LState, inst uint32, baseframe *callFrame) int { // OP_TFORLOOP 1929 reg := L.reg 1930 cf := L.currentFrame 1931 lbase := cf.LocalBase 1932 A := int(inst>>18) & 0xff // GETA 1933 RA := lbase + A 1934 C := int(inst>>9) & 0x1ff // GETC 1935 nret := C 1936 // this section is inlined by go-inline 1937 // source function is 'func (rg *registry) SetTop(topi int) ' in '_state.go' 1938 { 1939 rg := reg 1940 topi := RA + 3 + 2 1941 // this section is inlined by go-inline 1942 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1943 { 1944 requiredSize := topi 1945 if requiredSize > cap(rg.array) { 1946 rg.resize(requiredSize) 1947 } 1948 } 1949 oldtopi := rg.top 1950 rg.top = topi 1951 for i := oldtopi; i < rg.top; i++ { 1952 rg.array[i] = LNil 1953 } 1954 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1955 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1956 if rg.top < oldtopi { 1957 nilRange := rg.array[rg.top:oldtopi] 1958 for i := range nilRange { 1959 nilRange[i] = nil 1960 } 1961 } 1962 //for i := rg.top; i < oldtop; i++ { 1963 // rg.array[i] = LNil 1964 //} 1965 } 1966 // this section is inlined by go-inline 1967 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 1968 { 1969 rg := reg 1970 regi := RA + 3 + 2 1971 vali := reg.Get(RA + 2) 1972 newSize := regi + 1 1973 // this section is inlined by go-inline 1974 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1975 { 1976 requiredSize := newSize 1977 if requiredSize > cap(rg.array) { 1978 rg.resize(requiredSize) 1979 } 1980 } 1981 rg.array[regi] = vali 1982 if regi >= rg.top { 1983 rg.top = regi + 1 1984 } 1985 } 1986 // this section is inlined by go-inline 1987 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 1988 { 1989 rg := reg 1990 regi := RA + 3 + 1 1991 vali := reg.Get(RA + 1) 1992 newSize := regi + 1 1993 // this section is inlined by go-inline 1994 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1995 { 1996 requiredSize := newSize 1997 if requiredSize > cap(rg.array) { 1998 rg.resize(requiredSize) 1999 } 2000 } 2001 rg.array[regi] = vali 2002 if regi >= rg.top { 2003 rg.top = regi + 1 2004 } 2005 } 2006 // this section is inlined by go-inline 2007 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 2008 { 2009 rg := reg 2010 regi := RA + 3 2011 vali := reg.Get(RA) 2012 newSize := regi + 1 2013 // this section is inlined by go-inline 2014 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 2015 { 2016 requiredSize := newSize 2017 if requiredSize > cap(rg.array) { 2018 rg.resize(requiredSize) 2019 } 2020 } 2021 rg.array[regi] = vali 2022 if regi >= rg.top { 2023 rg.top = regi + 1 2024 } 2025 } 2026 L.callR(2, nret, RA+3) 2027 if value := reg.Get(RA + 3); value != LNil { 2028 // this section is inlined by go-inline 2029 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 2030 { 2031 rg := reg 2032 regi := RA + 2 2033 vali := value 2034 newSize := regi + 1 2035 // this section is inlined by go-inline 2036 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 2037 { 2038 requiredSize := newSize 2039 if requiredSize > cap(rg.array) { 2040 rg.resize(requiredSize) 2041 } 2042 } 2043 rg.array[regi] = vali 2044 if regi >= rg.top { 2045 rg.top = regi + 1 2046 } 2047 } 2048 pc := cf.Fn.Proto.Code[cf.Pc] 2049 cf.Pc += int(pc&0x3ffff) - opMaxArgSbx 2050 } 2051 cf.Pc++ 2052 return 0 2053 }, 2054 func(L *LState, inst uint32, baseframe *callFrame) int { // OP_SETLIST 2055 reg := L.reg 2056 cf := L.currentFrame 2057 lbase := cf.LocalBase 2058 A := int(inst>>18) & 0xff // GETA 2059 RA := lbase + A 2060 B := int(inst & 0x1ff) // GETB 2061 C := int(inst>>9) & 0x1ff // GETC 2062 if C == 0 { 2063 C = int(cf.Fn.Proto.Code[cf.Pc]) 2064 cf.Pc++ 2065 } 2066 offset := (C - 1) * FieldsPerFlush 2067 table := reg.Get(RA).(*LTable) 2068 nelem := B 2069 if B == 0 { 2070 nelem = reg.Top() - RA - 1 2071 } 2072 for i := 1; i <= nelem; i++ { 2073 table.RawSetInt(offset+i, reg.Get(RA+i)) 2074 } 2075 return 0 2076 }, 2077 func(L *LState, inst uint32, baseframe *callFrame) int { // OP_CLOSE 2078 cf := L.currentFrame 2079 lbase := cf.LocalBase 2080 A := int(inst>>18) & 0xff // GETA 2081 RA := lbase + A 2082 // this section is inlined by go-inline 2083 // source function is 'func (ls *LState) closeUpvalues(idx int) ' in '_state.go' 2084 { 2085 ls := L 2086 idx := RA 2087 if ls.uvcache != nil { 2088 var prev *Upvalue 2089 for uv := ls.uvcache; uv != nil; uv = uv.next { 2090 if uv.index >= idx { 2091 if prev != nil { 2092 prev.next = nil 2093 } else { 2094 ls.uvcache = nil 2095 } 2096 uv.Close() 2097 } 2098 prev = uv 2099 } 2100 } 2101 } 2102 return 0 2103 }, 2104 func(L *LState, inst uint32, baseframe *callFrame) int { // OP_CLOSURE 2105 reg := L.reg 2106 cf := L.currentFrame 2107 lbase := cf.LocalBase 2108 A := int(inst>>18) & 0xff // GETA 2109 RA := lbase + A 2110 Bx := int(inst & 0x3ffff) // GETBX 2111 proto := cf.Fn.Proto.FunctionPrototypes[Bx] 2112 closure := newLFunctionL(proto, cf.Fn.Env, int(proto.NumUpvalues)) 2113 // this section is inlined by go-inline 2114 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 2115 { 2116 rg := reg 2117 regi := RA 2118 vali := closure 2119 newSize := regi + 1 2120 // this section is inlined by go-inline 2121 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 2122 { 2123 requiredSize := newSize 2124 if requiredSize > cap(rg.array) { 2125 rg.resize(requiredSize) 2126 } 2127 } 2128 rg.array[regi] = vali 2129 if regi >= rg.top { 2130 rg.top = regi + 1 2131 } 2132 } 2133 for i := 0; i < int(proto.NumUpvalues); i++ { 2134 inst = cf.Fn.Proto.Code[cf.Pc] 2135 cf.Pc++ 2136 B := opGetArgB(inst) 2137 switch opGetOpCode(inst) { 2138 case OP_MOVE: 2139 closure.Upvalues[i] = L.findUpvalue(lbase + B) 2140 case OP_GETUPVAL: 2141 closure.Upvalues[i] = cf.Fn.Upvalues[B] 2142 } 2143 } 2144 return 0 2145 }, 2146 func(L *LState, inst uint32, baseframe *callFrame) int { // OP_VARARG 2147 reg := L.reg 2148 cf := L.currentFrame 2149 lbase := cf.LocalBase 2150 A := int(inst>>18) & 0xff // GETA 2151 RA := lbase + A 2152 B := int(inst & 0x1ff) // GETB 2153 nparams := int(cf.Fn.Proto.NumParameters) 2154 nvarargs := cf.NArgs - nparams 2155 if nvarargs < 0 { 2156 nvarargs = 0 2157 } 2158 nwant := B - 1 2159 if B == 0 { 2160 nwant = nvarargs 2161 } 2162 // this section is inlined by go-inline 2163 // source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go' 2164 { 2165 rg := reg 2166 regv := RA 2167 start := cf.Base + nparams + 1 2168 limit := cf.LocalBase 2169 n := nwant 2170 newSize := regv + n 2171 // this section is inlined by go-inline 2172 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 2173 { 2174 requiredSize := newSize 2175 if requiredSize > cap(rg.array) { 2176 rg.resize(requiredSize) 2177 } 2178 } 2179 if limit == -1 || limit > rg.top { 2180 limit = rg.top 2181 } 2182 for i := 0; i < n; i++ { 2183 srcIdx := start + i 2184 if srcIdx >= limit || srcIdx < 0 { 2185 rg.array[regv+i] = LNil 2186 } else { 2187 rg.array[regv+i] = rg.array[srcIdx] 2188 } 2189 } 2190 2191 // values beyond top don't need to be valid LValues, so setting them to nil is fine 2192 // setting them to nil rather than LNil lets us invoke the golang memclr opto 2193 oldtop := rg.top 2194 rg.top = regv + n 2195 if rg.top < oldtop { 2196 nilRange := rg.array[rg.top:oldtop] 2197 for i := range nilRange { 2198 nilRange[i] = nil 2199 } 2200 } 2201 } 2202 return 0 2203 }, 2204 func(L *LState, inst uint32, baseframe *callFrame) int { // OP_NOP 2205 return 0 2206 }, 2207 } 2208 } 2209 2210 func opArith(L *LState, inst uint32, baseframe *callFrame) int { // OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_BITOR, OP_MOD, OP_POW 2211 reg := L.reg 2212 cf := L.currentFrame 2213 lbase := cf.LocalBase 2214 A := int(inst>>18) & 0xff // GETA 2215 RA := lbase + A 2216 opcode := int(inst >> 26) // GETOPCODE 2217 B := int(inst & 0x1ff) // GETB 2218 C := int(inst>>9) & 0x1ff // GETC 2219 lhs := L.rkValue(B) 2220 rhs := L.rkValue(C) 2221 v1, ok1 := lhs.(LNumber) 2222 v2, ok2 := rhs.(LNumber) 2223 if ok1 && ok2 { 2224 v := numberArith(L, opcode, LNumber(v1), LNumber(v2)) 2225 // this section is inlined by go-inline 2226 // source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go' 2227 { 2228 rg := reg 2229 regi := RA 2230 vali := v 2231 newSize := regi + 1 2232 // this section is inlined by go-inline 2233 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 2234 { 2235 requiredSize := newSize 2236 if requiredSize > cap(rg.array) { 2237 rg.resize(requiredSize) 2238 } 2239 } 2240 rg.array[regi] = rg.alloc.LNumber2I(vali) 2241 if regi >= rg.top { 2242 rg.top = regi + 1 2243 } 2244 } 2245 } else { 2246 v := objectArith(L, opcode, lhs, rhs) 2247 // this section is inlined by go-inline 2248 // source function is 'func (rg *registry) Set(regi int, vali LValue) ' in '_state.go' 2249 { 2250 rg := reg 2251 regi := RA 2252 vali := v 2253 newSize := regi + 1 2254 // this section is inlined by go-inline 2255 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 2256 { 2257 requiredSize := newSize 2258 if requiredSize > cap(rg.array) { 2259 rg.resize(requiredSize) 2260 } 2261 } 2262 rg.array[regi] = vali 2263 if regi >= rg.top { 2264 rg.top = regi + 1 2265 } 2266 } 2267 } 2268 return 0 2269 } 2270 2271 func luaModulo(lhs, rhs LNumber) LNumber { 2272 flhs := float64(lhs) 2273 frhs := float64(rhs) 2274 v := math.Mod(flhs, frhs) 2275 if frhs > 0 && v < 0 || frhs < 0 && v > 0 { 2276 v += frhs 2277 } 2278 return LNumber(v) 2279 } 2280 2281 func numberArith(L *LState, opcode int, lhs, rhs LNumber) LNumber { 2282 switch opcode { 2283 case OP_ADD: 2284 return lhs + rhs 2285 case OP_SUB: 2286 return lhs - rhs 2287 case OP_MUL: 2288 return lhs * rhs 2289 case OP_DIV: 2290 return lhs / rhs 2291 case OP_BITOR: 2292 return lhs / rhs 2293 case OP_MOD: 2294 return luaModulo(lhs, rhs) 2295 case OP_POW: 2296 flhs := float64(lhs) 2297 frhs := float64(rhs) 2298 return LNumber(math.Pow(flhs, frhs)) 2299 } 2300 panic("should not reach here") 2301 return LNumber(0) 2302 } 2303 2304 func objectArith(L *LState, opcode int, lhs, rhs LValue) LValue { 2305 event := "" 2306 switch opcode { 2307 case OP_ADD: 2308 event = "__add" 2309 case OP_SUB: 2310 event = "__sub" 2311 case OP_MUL: 2312 event = "__mul" 2313 case OP_DIV: 2314 event = "__div" 2315 case OP_BITOR: 2316 event = "__bitor" 2317 case OP_MOD: 2318 event = "__mod" 2319 case OP_POW: 2320 event = "__pow" 2321 } 2322 op := L.metaOp2(lhs, rhs, event) 2323 if _, ok := op.(*LFunction); ok { 2324 L.reg.Push(op) 2325 L.reg.Push(lhs) 2326 L.reg.Push(rhs) 2327 L.Call(2, 1) 2328 return L.reg.Pop() 2329 } 2330 if str, ok := lhs.(LString); ok { 2331 if lnum, err := parseNumber(string(str)); err == nil { 2332 lhs = lnum 2333 } 2334 } 2335 if str, ok := rhs.(LString); ok { 2336 if rnum, err := parseNumber(string(str)); err == nil { 2337 rhs = rnum 2338 } 2339 } 2340 if v1, ok1 := lhs.(LNumber); ok1 { 2341 if v2, ok2 := rhs.(LNumber); ok2 { 2342 return numberArith(L, opcode, LNumber(v1), LNumber(v2)) 2343 } 2344 } 2345 L.RaiseError(fmt.Sprintf("cannot perform %v operation between %v and %v", 2346 strings.TrimLeft(event, "_"), lhs.Type().String(), rhs.Type().String())) 2347 2348 return LNil 2349 } 2350 2351 func stringConcat(L *LState, total, last int) LValue { 2352 rhs := L.reg.Get(last) 2353 total-- 2354 for i := last - 1; total > 0; { 2355 lhs := L.reg.Get(i) 2356 if !(LVCanConvToString(lhs) && LVCanConvToString(rhs)) { 2357 op := L.metaOp2(lhs, rhs, "__concat") 2358 if op.Type() == LTFunction { 2359 L.reg.Push(op) 2360 L.reg.Push(lhs) 2361 L.reg.Push(rhs) 2362 L.Call(2, 1) 2363 rhs = L.reg.Pop() 2364 total-- 2365 i-- 2366 } else { 2367 L.RaiseError("cannot perform concat operation between %v and %v", lhs.Type().String(), rhs.Type().String()) 2368 return LNil 2369 } 2370 } else { 2371 buf := make([]string, total+1) 2372 buf[total] = LVAsString(rhs) 2373 for total > 0 { 2374 lhs = L.reg.Get(i) 2375 if !LVCanConvToString(lhs) { 2376 break 2377 } 2378 buf[total-1] = LVAsString(lhs) 2379 i-- 2380 total-- 2381 } 2382 rhs = LString(strings.Join(buf, "")) 2383 } 2384 } 2385 return rhs 2386 } 2387 2388 func lessThan(L *LState, lhs, rhs LValue) bool { 2389 // optimization for numbers 2390 if v1, ok1 := lhs.(LNumber); ok1 { 2391 if v2, ok2 := rhs.(LNumber); ok2 { 2392 return v1 < v2 2393 } 2394 L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String()) 2395 } 2396 if lhs.Type() != rhs.Type() { 2397 L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String()) 2398 return false 2399 } 2400 ret := false 2401 switch lhs.Type() { 2402 case LTString: 2403 ret = strCmp(string(lhs.(LString)), string(rhs.(LString))) < 0 2404 default: 2405 ret = objectRationalWithError(L, lhs, rhs, "__lt") 2406 } 2407 return ret 2408 } 2409 2410 func equals(L *LState, lhs, rhs LValue, raw bool) bool { 2411 lt := lhs.Type() 2412 if lt != rhs.Type() { 2413 return false 2414 } 2415 2416 ret := false 2417 switch lt { 2418 case LTNil: 2419 ret = true 2420 case LTNumber: 2421 v1, _ := lhs.(LNumber) 2422 v2, _ := rhs.(LNumber) 2423 ret = v1 == v2 2424 case LTBool: 2425 ret = bool(lhs.(LBool)) == bool(rhs.(LBool)) 2426 case LTString: 2427 ret = string(lhs.(LString)) == string(rhs.(LString)) 2428 case LTUserData, LTTable: 2429 if lhs == rhs { 2430 ret = true 2431 } else if !raw { 2432 switch objectRational(L, lhs, rhs, "__eq") { 2433 case 1: 2434 ret = true 2435 default: 2436 ret = false 2437 } 2438 } 2439 default: 2440 ret = lhs == rhs 2441 } 2442 return ret 2443 } 2444 2445 func objectRationalWithError(L *LState, lhs, rhs LValue, event string) bool { 2446 switch objectRational(L, lhs, rhs, event) { 2447 case 1: 2448 return true 2449 case 0: 2450 return false 2451 } 2452 L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String()) 2453 return false 2454 } 2455 2456 func objectRational(L *LState, lhs, rhs LValue, event string) int { 2457 m1 := L.metaOp1(lhs, event) 2458 m2 := L.metaOp1(rhs, event) 2459 if m1.Type() == LTFunction && m1 == m2 { 2460 L.reg.Push(m1) 2461 L.reg.Push(lhs) 2462 L.reg.Push(rhs) 2463 L.Call(2, 1) 2464 if LVAsBool(L.reg.Pop()) { 2465 return 1 2466 } 2467 return 0 2468 } 2469 return -1 2470 }