github.com/assemblaj/gopher-lua@v0.0.0-20221116224352-d57295a0d9e8/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 reg.Set(RA, reg.Get(lbase+B)) 311 return 0 312 }, 313 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_MOVEN 314 reg := L.reg 315 cf := L.currentFrame 316 lbase := cf.LocalBase 317 A := int(inst>>18) & 0xff //GETA 318 B := int(inst & 0x1ff) //GETB 319 C := int(inst>>9) & 0x1ff //GETC 320 reg.Set(lbase+A, reg.Get(lbase+B)) 321 code := cf.Fn.Proto.Code 322 pc := cf.Pc 323 for i := 0; i < C; i++ { 324 inst = code[pc] 325 pc++ 326 A = int(inst>>18) & 0xff //GETA 327 B = int(inst & 0x1ff) //GETB 328 reg.Set(lbase+A, reg.Get(lbase+B)) 329 } 330 cf.Pc = pc 331 return 0 332 }, 333 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_LOADK 334 reg := L.reg 335 cf := L.currentFrame 336 lbase := cf.LocalBase 337 A := int(inst>>18) & 0xff //GETA 338 RA := lbase + A 339 Bx := int(inst & 0x3ffff) //GETBX 340 reg.Set(RA, cf.Fn.Proto.Constants[Bx]) 341 return 0 342 }, 343 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_LOADBOOL 344 reg := L.reg 345 cf := L.currentFrame 346 lbase := cf.LocalBase 347 A := int(inst>>18) & 0xff //GETA 348 RA := lbase + A 349 B := int(inst & 0x1ff) //GETB 350 C := int(inst>>9) & 0x1ff //GETC 351 if B != 0 { 352 reg.Set(RA, LTrue) 353 } else { 354 reg.Set(RA, LFalse) 355 } 356 if C != 0 { 357 cf.Pc++ 358 } 359 return 0 360 }, 361 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_LOADNIL 362 reg := L.reg 363 cf := L.currentFrame 364 lbase := cf.LocalBase 365 A := int(inst>>18) & 0xff //GETA 366 RA := lbase + A 367 B := int(inst & 0x1ff) //GETB 368 for i := RA; i <= lbase+B; i++ { 369 reg.Set(i, LNil) 370 } 371 return 0 372 }, 373 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_GETUPVAL 374 reg := L.reg 375 cf := L.currentFrame 376 lbase := cf.LocalBase 377 A := int(inst>>18) & 0xff //GETA 378 RA := lbase + A 379 B := int(inst & 0x1ff) //GETB 380 reg.Set(RA, cf.Fn.Upvalues[B].Value()) 381 return 0 382 }, 383 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_GETGLOBAL 384 reg := L.reg 385 cf := L.currentFrame 386 lbase := cf.LocalBase 387 A := int(inst>>18) & 0xff //GETA 388 RA := lbase + A 389 Bx := int(inst & 0x3ffff) //GETBX 390 //reg.Set(RA, L.getField(cf.Fn.Env, cf.Fn.Proto.Constants[Bx])) 391 reg.Set(RA, L.getFieldString(cf.Fn.Env, cf.Fn.Proto.stringConstants[Bx])) 392 return 0 393 }, 394 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_GETTABLE 395 reg := L.reg 396 cf := L.currentFrame 397 lbase := cf.LocalBase 398 A := int(inst>>18) & 0xff //GETA 399 RA := lbase + A 400 B := int(inst & 0x1ff) //GETB 401 C := int(inst>>9) & 0x1ff //GETC 402 reg.Set(RA, L.getField(reg.Get(lbase+B), L.rkValue(C))) 403 return 0 404 }, 405 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_GETTABLEKS 406 reg := L.reg 407 cf := L.currentFrame 408 lbase := cf.LocalBase 409 A := int(inst>>18) & 0xff //GETA 410 RA := lbase + A 411 B := int(inst & 0x1ff) //GETB 412 C := int(inst>>9) & 0x1ff //GETC 413 reg.Set(RA, L.getFieldString(reg.Get(lbase+B), L.rkString(C))) 414 return 0 415 }, 416 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SETGLOBAL 417 reg := L.reg 418 cf := L.currentFrame 419 lbase := cf.LocalBase 420 A := int(inst>>18) & 0xff //GETA 421 RA := lbase + A 422 Bx := int(inst & 0x3ffff) //GETBX 423 //L.setField(cf.Fn.Env, cf.Fn.Proto.Constants[Bx], reg.Get(RA)) 424 L.setFieldString(cf.Fn.Env, cf.Fn.Proto.stringConstants[Bx], reg.Get(RA)) 425 return 0 426 }, 427 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SETUPVAL 428 reg := L.reg 429 cf := L.currentFrame 430 lbase := cf.LocalBase 431 A := int(inst>>18) & 0xff //GETA 432 RA := lbase + A 433 B := int(inst & 0x1ff) //GETB 434 cf.Fn.Upvalues[B].SetValue(reg.Get(RA)) 435 return 0 436 }, 437 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SETTABLE 438 reg := L.reg 439 cf := L.currentFrame 440 lbase := cf.LocalBase 441 A := int(inst>>18) & 0xff //GETA 442 RA := lbase + A 443 B := int(inst & 0x1ff) //GETB 444 C := int(inst>>9) & 0x1ff //GETC 445 L.setField(reg.Get(RA), L.rkValue(B), L.rkValue(C)) 446 return 0 447 }, 448 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SETTABLEKS 449 reg := L.reg 450 cf := L.currentFrame 451 lbase := cf.LocalBase 452 A := int(inst>>18) & 0xff //GETA 453 RA := lbase + A 454 B := int(inst & 0x1ff) //GETB 455 C := int(inst>>9) & 0x1ff //GETC 456 L.setFieldString(reg.Get(RA), L.rkString(B), L.rkValue(C)) 457 return 0 458 }, 459 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_NEWTABLE 460 reg := L.reg 461 cf := L.currentFrame 462 lbase := cf.LocalBase 463 A := int(inst>>18) & 0xff //GETA 464 RA := lbase + A 465 B := int(inst & 0x1ff) //GETB 466 C := int(inst>>9) & 0x1ff //GETC 467 reg.Set(RA, newLTable(B, C)) 468 return 0 469 }, 470 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SELF 471 reg := L.reg 472 cf := L.currentFrame 473 lbase := cf.LocalBase 474 A := int(inst>>18) & 0xff //GETA 475 RA := lbase + A 476 B := int(inst & 0x1ff) //GETB 477 C := int(inst>>9) & 0x1ff //GETC 478 selfobj := reg.Get(lbase + B) 479 reg.Set(RA, L.getFieldString(selfobj, L.rkString(C))) 480 reg.Set(RA+1, selfobj) 481 return 0 482 }, 483 opArith, // OP_ADD 484 opArith, // OP_SUB 485 opArith, // OP_MUL 486 opArith, // OP_DIV 487 opArith, // OP_MOD 488 opArith, // OP_POW 489 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_UNM 490 reg := L.reg 491 cf := L.currentFrame 492 lbase := cf.LocalBase 493 A := int(inst>>18) & 0xff //GETA 494 RA := lbase + A 495 B := int(inst & 0x1ff) //GETB 496 unaryv := L.rkValue(B) 497 if nm, ok := unaryv.(LNumber); ok { 498 reg.SetNumber(RA, -nm) 499 } else { 500 op := L.metaOp1(unaryv, "__unm") 501 if op.Type() == LTFunction { 502 reg.Push(op) 503 reg.Push(unaryv) 504 L.Call(1, 1) 505 reg.Set(RA, reg.Pop()) 506 } else if str, ok1 := unaryv.(LString); ok1 { 507 if num, err := parseNumber(string(str)); err == nil { 508 reg.Set(RA, -num) 509 } else { 510 L.RaiseError("__unm undefined") 511 } 512 } else { 513 L.RaiseError("__unm undefined") 514 } 515 } 516 return 0 517 }, 518 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_NOT 519 reg := L.reg 520 cf := L.currentFrame 521 lbase := cf.LocalBase 522 A := int(inst>>18) & 0xff //GETA 523 RA := lbase + A 524 B := int(inst & 0x1ff) //GETB 525 if LVIsFalse(reg.Get(lbase + B)) { 526 reg.Set(RA, LTrue) 527 } else { 528 reg.Set(RA, LFalse) 529 } 530 return 0 531 }, 532 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_LEN 533 reg := L.reg 534 cf := L.currentFrame 535 lbase := cf.LocalBase 536 A := int(inst>>18) & 0xff //GETA 537 RA := lbase + A 538 B := int(inst & 0x1ff) //GETB 539 switch lv := L.rkValue(B).(type) { 540 case LString: 541 reg.SetNumber(RA, LNumber(len(lv))) 542 default: 543 op := L.metaOp1(lv, "__len") 544 if op.Type() == LTFunction { 545 reg.Push(op) 546 reg.Push(lv) 547 L.Call(1, 1) 548 ret := reg.Pop() 549 if ret.Type() == LTNumber { 550 reg.SetNumber(RA, ret.(LNumber)) 551 } else { 552 reg.Set(RA, ret) 553 } 554 } else if lv.Type() == LTTable { 555 reg.SetNumber(RA, LNumber(lv.(*LTable).Len())) 556 } else { 557 L.RaiseError("__len undefined") 558 } 559 } 560 return 0 561 }, 562 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_CONCAT 563 reg := L.reg 564 cf := L.currentFrame 565 lbase := cf.LocalBase 566 A := int(inst>>18) & 0xff //GETA 567 RA := lbase + A 568 B := int(inst & 0x1ff) //GETB 569 C := int(inst>>9) & 0x1ff //GETC 570 RC := lbase + C 571 RB := lbase + B 572 reg.Set(RA, stringConcat(L, RC-RB+1, RC)) 573 return 0 574 }, 575 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_JMP 576 cf := L.currentFrame 577 Sbx := int(inst&0x3ffff) - opMaxArgSbx //GETSBX 578 cf.Pc += Sbx 579 return 0 580 }, 581 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_EQ 582 cf := L.currentFrame 583 A := int(inst>>18) & 0xff //GETA 584 B := int(inst & 0x1ff) //GETB 585 C := int(inst>>9) & 0x1ff //GETC 586 ret := equals(L, L.rkValue(B), L.rkValue(C), false) 587 v := 1 588 if ret { 589 v = 0 590 } 591 if v == A { 592 cf.Pc++ 593 } 594 return 0 595 }, 596 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_LT 597 cf := L.currentFrame 598 A := int(inst>>18) & 0xff //GETA 599 B := int(inst & 0x1ff) //GETB 600 C := int(inst>>9) & 0x1ff //GETC 601 ret := lessThan(L, L.rkValue(B), L.rkValue(C)) 602 v := 1 603 if ret { 604 v = 0 605 } 606 if v == A { 607 cf.Pc++ 608 } 609 return 0 610 }, 611 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_LE 612 cf := L.currentFrame 613 A := int(inst>>18) & 0xff //GETA 614 B := int(inst & 0x1ff) //GETB 615 C := int(inst>>9) & 0x1ff //GETC 616 lhs := L.rkValue(B) 617 rhs := L.rkValue(C) 618 ret := false 619 620 if v1, ok1 := lhs.assertFloat64(); ok1 { 621 if v2, ok2 := rhs.assertFloat64(); ok2 { 622 ret = v1 <= v2 623 } else { 624 L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String()) 625 } 626 } else { 627 if lhs.Type() != rhs.Type() { 628 L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String()) 629 } 630 switch lhs.Type() { 631 case LTString: 632 ret = strCmp(string(lhs.(LString)), string(rhs.(LString))) <= 0 633 default: 634 switch objectRational(L, lhs, rhs, "__le") { 635 case 1: 636 ret = true 637 case 0: 638 ret = false 639 default: 640 ret = !objectRationalWithError(L, rhs, lhs, "__lt") 641 } 642 } 643 } 644 645 v := 1 646 if ret { 647 v = 0 648 } 649 if v == A { 650 cf.Pc++ 651 } 652 return 0 653 }, 654 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_TEST 655 reg := L.reg 656 cf := L.currentFrame 657 lbase := cf.LocalBase 658 A := int(inst>>18) & 0xff //GETA 659 RA := lbase + A 660 C := int(inst>>9) & 0x1ff //GETC 661 if LVAsBool(reg.Get(RA)) == (C == 0) { 662 cf.Pc++ 663 } 664 return 0 665 }, 666 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_TESTSET 667 reg := L.reg 668 cf := L.currentFrame 669 lbase := cf.LocalBase 670 A := int(inst>>18) & 0xff //GETA 671 RA := lbase + A 672 B := int(inst & 0x1ff) //GETB 673 C := int(inst>>9) & 0x1ff //GETC 674 if value := reg.Get(lbase + B); LVAsBool(value) != (C == 0) { 675 reg.Set(RA, value) 676 } else { 677 cf.Pc++ 678 } 679 return 0 680 }, 681 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_CALL 682 reg := L.reg 683 cf := L.currentFrame 684 lbase := cf.LocalBase 685 A := int(inst>>18) & 0xff //GETA 686 RA := lbase + A 687 B := int(inst & 0x1ff) //GETB 688 C := int(inst>>9) & 0x1ff //GETC 689 nargs := B - 1 690 if B == 0 { 691 nargs = reg.Top() - (RA + 1) 692 } 693 lv := reg.Get(RA) 694 nret := C - 1 695 var callable *LFunction 696 var meta bool 697 if fn, ok := lv.assertFunction(); ok { 698 callable = fn 699 meta = false 700 } else { 701 callable, meta = L.metaCall(lv) 702 } 703 // this section is inlined by go-inline 704 // source function is 'func (ls *LState) pushCallFrame(cf callFrame, fn LValue, meta bool) ' in '_state.go' 705 { 706 ls := L 707 cf := callFrame{Fn: callable, Pc: 0, Base: RA, LocalBase: RA + 1, ReturnBase: RA, NArgs: nargs, NRet: nret, Parent: cf, TailCall: 0} 708 fn := lv 709 if meta { 710 cf.NArgs++ 711 ls.reg.Insert(fn, cf.LocalBase) 712 } 713 if cf.Fn == nil { 714 ls.RaiseError("attempt to call a non-function object") 715 } 716 if ls.stack.IsFull() { 717 ls.RaiseError("stack overflow") 718 } 719 ls.stack.Push(cf) 720 newcf := ls.stack.Last() 721 // this section is inlined by go-inline 722 // source function is 'func (ls *LState) initCallFrame(cf *callFrame) ' in '_state.go' 723 { 724 cf := newcf 725 if cf.Fn.IsG { 726 ls.reg.SetTop(cf.LocalBase + cf.NArgs) 727 } else { 728 proto := cf.Fn.Proto 729 nargs := cf.NArgs 730 np := int(proto.NumParameters) 731 if nargs < np { 732 // default any missing arguments to nil 733 newSize := cf.LocalBase + np 734 // this section is inlined by go-inline 735 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 736 { 737 rg := ls.reg 738 requiredSize := newSize 739 if requiredSize > cap(rg.array) { 740 rg.resize(requiredSize) 741 } 742 } 743 for i := nargs; i < np; i++ { 744 ls.reg.array[cf.LocalBase+i] = LNil 745 } 746 nargs = np 747 ls.reg.top = newSize 748 } 749 750 if (proto.IsVarArg & VarArgIsVarArg) == 0 { 751 if nargs < int(proto.NumUsedRegisters) { 752 nargs = int(proto.NumUsedRegisters) 753 } 754 newSize := cf.LocalBase + nargs 755 // this section is inlined by go-inline 756 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 757 { 758 rg := ls.reg 759 requiredSize := newSize 760 if requiredSize > cap(rg.array) { 761 rg.resize(requiredSize) 762 } 763 } 764 for i := np; i < nargs; i++ { 765 ls.reg.array[cf.LocalBase+i] = LNil 766 } 767 ls.reg.top = cf.LocalBase + int(proto.NumUsedRegisters) 768 } else { 769 /* swap vararg positions: 770 closure 771 namedparam1 <- lbase 772 namedparam2 773 vararg1 774 vararg2 775 776 TO 777 778 closure 779 nil 780 nil 781 vararg1 782 vararg2 783 namedparam1 <- lbase 784 namedparam2 785 */ 786 nvarargs := nargs - np 787 if nvarargs < 0 { 788 nvarargs = 0 789 } 790 791 ls.reg.SetTop(cf.LocalBase + nargs + np) 792 for i := 0; i < np; i++ { 793 //ls.reg.Set(cf.LocalBase+nargs+i, ls.reg.Get(cf.LocalBase+i)) 794 ls.reg.array[cf.LocalBase+nargs+i] = ls.reg.array[cf.LocalBase+i] 795 //ls.reg.Set(cf.LocalBase+i, LNil) 796 ls.reg.array[cf.LocalBase+i] = LNil 797 } 798 799 if CompatVarArg { 800 ls.reg.SetTop(cf.LocalBase + nargs + np + 1) 801 if (proto.IsVarArg & VarArgNeedsArg) != 0 { 802 argtb := newLTable(nvarargs, 0) 803 for i := 0; i < nvarargs; i++ { 804 argtb.RawSetInt(i+1, ls.reg.Get(cf.LocalBase+np+i)) 805 } 806 argtb.RawSetString("n", LNumber(nvarargs)) 807 //ls.reg.Set(cf.LocalBase+nargs+np, argtb) 808 ls.reg.array[cf.LocalBase+nargs+np] = argtb 809 } else { 810 ls.reg.array[cf.LocalBase+nargs+np] = LNil 811 } 812 } 813 cf.LocalBase += nargs 814 maxreg := cf.LocalBase + int(proto.NumUsedRegisters) 815 ls.reg.SetTop(maxreg) 816 } 817 } 818 } 819 ls.currentFrame = newcf 820 } 821 if callable.IsG && callGFunction(L, false) { 822 return 1 823 } 824 return 0 825 }, 826 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_TAILCALL 827 reg := L.reg 828 cf := L.currentFrame 829 lbase := cf.LocalBase 830 A := int(inst>>18) & 0xff //GETA 831 RA := lbase + A 832 B := int(inst & 0x1ff) //GETB 833 nargs := B - 1 834 if B == 0 { 835 nargs = reg.Top() - (RA + 1) 836 } 837 lv := reg.Get(RA) 838 var callable *LFunction 839 var meta bool 840 if fn, ok := lv.assertFunction(); ok { 841 callable = fn 842 meta = false 843 } else { 844 callable, meta = L.metaCall(lv) 845 } 846 if callable == nil { 847 L.RaiseError("attempt to call a non-function object") 848 } 849 // this section is inlined by go-inline 850 // source function is 'func (ls *LState) closeUpvalues(idx int) ' in '_state.go' 851 { 852 ls := L 853 idx := lbase 854 if ls.uvcache != nil { 855 var prev *Upvalue 856 for uv := ls.uvcache; uv != nil; uv = uv.next { 857 if uv.index >= idx { 858 if prev != nil { 859 prev.next = nil 860 } else { 861 ls.uvcache = nil 862 } 863 uv.Close() 864 } 865 prev = uv 866 } 867 } 868 } 869 if callable.IsG { 870 luaframe := cf 871 L.pushCallFrame(callFrame{ 872 Fn: callable, 873 Pc: 0, 874 Base: RA, 875 LocalBase: RA + 1, 876 ReturnBase: cf.ReturnBase, 877 NArgs: nargs, 878 NRet: cf.NRet, 879 Parent: cf, 880 TailCall: 0, 881 }, lv, meta) 882 if callGFunction(L, true) { 883 return 1 884 } 885 if L.currentFrame == nil || L.currentFrame.Fn.IsG || luaframe == baseframe { 886 return 1 887 } 888 } else { 889 base := cf.Base 890 cf.Fn = callable 891 cf.Pc = 0 892 cf.Base = RA 893 cf.LocalBase = RA + 1 894 cf.ReturnBase = cf.ReturnBase 895 cf.NArgs = nargs 896 cf.NRet = cf.NRet 897 cf.TailCall++ 898 lbase := cf.LocalBase 899 if meta { 900 cf.NArgs++ 901 L.reg.Insert(lv, cf.LocalBase) 902 } 903 // this section is inlined by go-inline 904 // source function is 'func (ls *LState) initCallFrame(cf *callFrame) ' in '_state.go' 905 { 906 ls := L 907 if cf.Fn.IsG { 908 ls.reg.SetTop(cf.LocalBase + cf.NArgs) 909 } else { 910 proto := cf.Fn.Proto 911 nargs := cf.NArgs 912 np := int(proto.NumParameters) 913 if nargs < np { 914 // default any missing arguments to nil 915 newSize := cf.LocalBase + np 916 // this section is inlined by go-inline 917 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 918 { 919 rg := ls.reg 920 requiredSize := newSize 921 if requiredSize > cap(rg.array) { 922 rg.resize(requiredSize) 923 } 924 } 925 for i := nargs; i < np; i++ { 926 ls.reg.array[cf.LocalBase+i] = LNil 927 } 928 nargs = np 929 ls.reg.top = newSize 930 } 931 932 if (proto.IsVarArg & VarArgIsVarArg) == 0 { 933 if nargs < int(proto.NumUsedRegisters) { 934 nargs = int(proto.NumUsedRegisters) 935 } 936 newSize := cf.LocalBase + nargs 937 // this section is inlined by go-inline 938 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 939 { 940 rg := ls.reg 941 requiredSize := newSize 942 if requiredSize > cap(rg.array) { 943 rg.resize(requiredSize) 944 } 945 } 946 for i := np; i < nargs; i++ { 947 ls.reg.array[cf.LocalBase+i] = LNil 948 } 949 ls.reg.top = cf.LocalBase + int(proto.NumUsedRegisters) 950 } else { 951 /* swap vararg positions: 952 closure 953 namedparam1 <- lbase 954 namedparam2 955 vararg1 956 vararg2 957 958 TO 959 960 closure 961 nil 962 nil 963 vararg1 964 vararg2 965 namedparam1 <- lbase 966 namedparam2 967 */ 968 nvarargs := nargs - np 969 if nvarargs < 0 { 970 nvarargs = 0 971 } 972 973 ls.reg.SetTop(cf.LocalBase + nargs + np) 974 for i := 0; i < np; i++ { 975 //ls.reg.Set(cf.LocalBase+nargs+i, ls.reg.Get(cf.LocalBase+i)) 976 ls.reg.array[cf.LocalBase+nargs+i] = ls.reg.array[cf.LocalBase+i] 977 //ls.reg.Set(cf.LocalBase+i, LNil) 978 ls.reg.array[cf.LocalBase+i] = LNil 979 } 980 981 if CompatVarArg { 982 ls.reg.SetTop(cf.LocalBase + nargs + np + 1) 983 if (proto.IsVarArg & VarArgNeedsArg) != 0 { 984 argtb := newLTable(nvarargs, 0) 985 for i := 0; i < nvarargs; i++ { 986 argtb.RawSetInt(i+1, ls.reg.Get(cf.LocalBase+np+i)) 987 } 988 argtb.RawSetString("n", LNumber(nvarargs)) 989 //ls.reg.Set(cf.LocalBase+nargs+np, argtb) 990 ls.reg.array[cf.LocalBase+nargs+np] = argtb 991 } else { 992 ls.reg.array[cf.LocalBase+nargs+np] = LNil 993 } 994 } 995 cf.LocalBase += nargs 996 maxreg := cf.LocalBase + int(proto.NumUsedRegisters) 997 ls.reg.SetTop(maxreg) 998 } 999 } 1000 } 1001 // this section is inlined by go-inline 1002 // source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go' 1003 { 1004 rg := L.reg 1005 regv := base 1006 start := RA 1007 limit := -1 1008 n := reg.Top() - RA - 1 1009 newSize := regv + n 1010 // this section is inlined by go-inline 1011 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1012 { 1013 requiredSize := newSize 1014 if requiredSize > cap(rg.array) { 1015 rg.resize(requiredSize) 1016 } 1017 } 1018 if limit == -1 || limit > rg.top { 1019 limit = rg.top 1020 } 1021 for i := 0; i < n; i++ { 1022 srcIdx := start + i 1023 if srcIdx >= limit || srcIdx < 0 { 1024 rg.array[regv+i] = LNil 1025 } else { 1026 rg.array[regv+i] = rg.array[srcIdx] 1027 } 1028 } 1029 1030 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1031 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1032 oldtop := rg.top 1033 rg.top = regv + n 1034 if rg.top < oldtop { 1035 nilRange := rg.array[rg.top:oldtop] 1036 for i := range nilRange { 1037 nilRange[i] = nil 1038 } 1039 } 1040 } 1041 cf.Base = base 1042 cf.LocalBase = base + (cf.LocalBase - lbase + 1) 1043 } 1044 return 0 1045 }, 1046 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_RETURN 1047 reg := L.reg 1048 cf := L.currentFrame 1049 lbase := cf.LocalBase 1050 A := int(inst>>18) & 0xff //GETA 1051 RA := lbase + A 1052 B := int(inst & 0x1ff) //GETB 1053 // this section is inlined by go-inline 1054 // source function is 'func (ls *LState) closeUpvalues(idx int) ' in '_state.go' 1055 { 1056 ls := L 1057 idx := lbase 1058 if ls.uvcache != nil { 1059 var prev *Upvalue 1060 for uv := ls.uvcache; uv != nil; uv = uv.next { 1061 if uv.index >= idx { 1062 if prev != nil { 1063 prev.next = nil 1064 } else { 1065 ls.uvcache = nil 1066 } 1067 uv.Close() 1068 } 1069 prev = uv 1070 } 1071 } 1072 } 1073 nret := B - 1 1074 if B == 0 { 1075 nret = reg.Top() - RA 1076 } 1077 n := cf.NRet 1078 if cf.NRet == MultRet { 1079 n = nret 1080 } 1081 1082 if L.Parent != nil && L.stack.Sp() == 1 { 1083 // this section is inlined by go-inline 1084 // source function is 'func copyReturnValues(L *LState, regv, start, n, b int) ' in '_vm.go' 1085 { 1086 regv := reg.Top() 1087 start := RA 1088 b := B 1089 if b == 1 { 1090 // this section is inlined by go-inline 1091 // source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go' 1092 { 1093 rg := L.reg 1094 regm := regv 1095 newSize := regm + n 1096 // this section is inlined by go-inline 1097 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1098 { 1099 requiredSize := newSize 1100 if requiredSize > cap(rg.array) { 1101 rg.resize(requiredSize) 1102 } 1103 } 1104 for i := 0; i < n; i++ { 1105 rg.array[regm+i] = LNil 1106 } 1107 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1108 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1109 oldtop := rg.top 1110 rg.top = regm + n 1111 if rg.top < oldtop { 1112 nilRange := rg.array[rg.top:oldtop] 1113 for i := range nilRange { 1114 nilRange[i] = nil 1115 } 1116 } 1117 } 1118 } else { 1119 // this section is inlined by go-inline 1120 // source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go' 1121 { 1122 rg := L.reg 1123 limit := -1 1124 newSize := regv + n 1125 // this section is inlined by go-inline 1126 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1127 { 1128 requiredSize := newSize 1129 if requiredSize > cap(rg.array) { 1130 rg.resize(requiredSize) 1131 } 1132 } 1133 if limit == -1 || limit > rg.top { 1134 limit = rg.top 1135 } 1136 for i := 0; i < n; i++ { 1137 srcIdx := start + i 1138 if srcIdx >= limit || srcIdx < 0 { 1139 rg.array[regv+i] = LNil 1140 } else { 1141 rg.array[regv+i] = rg.array[srcIdx] 1142 } 1143 } 1144 1145 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1146 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1147 oldtop := rg.top 1148 rg.top = regv + n 1149 if rg.top < oldtop { 1150 nilRange := rg.array[rg.top:oldtop] 1151 for i := range nilRange { 1152 nilRange[i] = nil 1153 } 1154 } 1155 } 1156 if b > 1 && n > (b-1) { 1157 // this section is inlined by go-inline 1158 // source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go' 1159 { 1160 rg := L.reg 1161 regm := regv + b - 1 1162 n := n - (b - 1) 1163 newSize := regm + n 1164 // this section is inlined by go-inline 1165 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1166 { 1167 requiredSize := newSize 1168 if requiredSize > cap(rg.array) { 1169 rg.resize(requiredSize) 1170 } 1171 } 1172 for i := 0; i < n; i++ { 1173 rg.array[regm+i] = LNil 1174 } 1175 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1176 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1177 oldtop := rg.top 1178 rg.top = regm + n 1179 if rg.top < oldtop { 1180 nilRange := rg.array[rg.top:oldtop] 1181 for i := range nilRange { 1182 nilRange[i] = nil 1183 } 1184 } 1185 } 1186 } 1187 } 1188 } 1189 switchToParentThread(L, n, false, true) 1190 return 1 1191 } 1192 islast := baseframe == L.stack.Pop() || L.stack.IsEmpty() 1193 // this section is inlined by go-inline 1194 // source function is 'func copyReturnValues(L *LState, regv, start, n, b int) ' in '_vm.go' 1195 { 1196 regv := cf.ReturnBase 1197 start := RA 1198 b := B 1199 if b == 1 { 1200 // this section is inlined by go-inline 1201 // source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go' 1202 { 1203 rg := L.reg 1204 regm := regv 1205 newSize := regm + n 1206 // this section is inlined by go-inline 1207 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1208 { 1209 requiredSize := newSize 1210 if requiredSize > cap(rg.array) { 1211 rg.resize(requiredSize) 1212 } 1213 } 1214 for i := 0; i < n; i++ { 1215 rg.array[regm+i] = LNil 1216 } 1217 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1218 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1219 oldtop := rg.top 1220 rg.top = regm + n 1221 if rg.top < oldtop { 1222 nilRange := rg.array[rg.top:oldtop] 1223 for i := range nilRange { 1224 nilRange[i] = nil 1225 } 1226 } 1227 } 1228 } else { 1229 // this section is inlined by go-inline 1230 // source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go' 1231 { 1232 rg := L.reg 1233 limit := -1 1234 newSize := regv + n 1235 // this section is inlined by go-inline 1236 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1237 { 1238 requiredSize := newSize 1239 if requiredSize > cap(rg.array) { 1240 rg.resize(requiredSize) 1241 } 1242 } 1243 if limit == -1 || limit > rg.top { 1244 limit = rg.top 1245 } 1246 for i := 0; i < n; i++ { 1247 srcIdx := start + i 1248 if srcIdx >= limit || srcIdx < 0 { 1249 rg.array[regv+i] = LNil 1250 } else { 1251 rg.array[regv+i] = rg.array[srcIdx] 1252 } 1253 } 1254 1255 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1256 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1257 oldtop := rg.top 1258 rg.top = regv + n 1259 if rg.top < oldtop { 1260 nilRange := rg.array[rg.top:oldtop] 1261 for i := range nilRange { 1262 nilRange[i] = nil 1263 } 1264 } 1265 } 1266 if b > 1 && n > (b-1) { 1267 // this section is inlined by go-inline 1268 // source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go' 1269 { 1270 rg := L.reg 1271 regm := regv + b - 1 1272 n := n - (b - 1) 1273 newSize := regm + n 1274 // this section is inlined by go-inline 1275 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1276 { 1277 requiredSize := newSize 1278 if requiredSize > cap(rg.array) { 1279 rg.resize(requiredSize) 1280 } 1281 } 1282 for i := 0; i < n; i++ { 1283 rg.array[regm+i] = LNil 1284 } 1285 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1286 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1287 oldtop := rg.top 1288 rg.top = regm + n 1289 if rg.top < oldtop { 1290 nilRange := rg.array[rg.top:oldtop] 1291 for i := range nilRange { 1292 nilRange[i] = nil 1293 } 1294 } 1295 } 1296 } 1297 } 1298 } 1299 L.currentFrame = L.stack.Last() 1300 if islast || L.currentFrame == nil || L.currentFrame.Fn.IsG { 1301 return 1 1302 } 1303 return 0 1304 }, 1305 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_FORLOOP 1306 reg := L.reg 1307 cf := L.currentFrame 1308 lbase := cf.LocalBase 1309 A := int(inst>>18) & 0xff //GETA 1310 RA := lbase + A 1311 if init, ok1 := reg.Get(RA).assertFloat64(); ok1 { 1312 if limit, ok2 := reg.Get(RA + 1).assertFloat64(); ok2 { 1313 if step, ok3 := reg.Get(RA + 2).assertFloat64(); ok3 { 1314 init += step 1315 reg.SetNumber(RA, LNumber(init)) 1316 if (step > 0 && init <= limit) || (step <= 0 && init >= limit) { 1317 Sbx := int(inst&0x3ffff) - opMaxArgSbx //GETSBX 1318 cf.Pc += Sbx 1319 reg.SetNumber(RA+3, LNumber(init)) 1320 } else { 1321 reg.SetTop(RA + 1) 1322 } 1323 } else { 1324 L.RaiseError("for statement step must be a number") 1325 } 1326 } else { 1327 L.RaiseError("for statement limit must be a number") 1328 } 1329 } else { 1330 L.RaiseError("for statement init must be a number") 1331 } 1332 return 0 1333 }, 1334 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_FORPREP 1335 reg := L.reg 1336 cf := L.currentFrame 1337 lbase := cf.LocalBase 1338 A := int(inst>>18) & 0xff //GETA 1339 RA := lbase + A 1340 Sbx := int(inst&0x3ffff) - opMaxArgSbx //GETSBX 1341 if init, ok1 := reg.Get(RA).assertFloat64(); ok1 { 1342 if step, ok2 := reg.Get(RA + 2).assertFloat64(); ok2 { 1343 reg.SetNumber(RA, LNumber(init-step)) 1344 } else { 1345 L.RaiseError("for statement step must be a number") 1346 } 1347 } else { 1348 L.RaiseError("for statement init must be a number") 1349 } 1350 cf.Pc += Sbx 1351 return 0 1352 }, 1353 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_TFORLOOP 1354 reg := L.reg 1355 cf := L.currentFrame 1356 lbase := cf.LocalBase 1357 A := int(inst>>18) & 0xff //GETA 1358 RA := lbase + A 1359 C := int(inst>>9) & 0x1ff //GETC 1360 nret := C 1361 reg.SetTop(RA + 3 + 2) 1362 reg.Set(RA+3+2, reg.Get(RA+2)) 1363 reg.Set(RA+3+1, reg.Get(RA+1)) 1364 reg.Set(RA+3, reg.Get(RA)) 1365 L.callR(2, nret, RA+3) 1366 if value := reg.Get(RA + 3); value != LNil { 1367 reg.Set(RA+2, value) 1368 pc := cf.Fn.Proto.Code[cf.Pc] 1369 cf.Pc += int(pc&0x3ffff) - opMaxArgSbx 1370 } 1371 cf.Pc++ 1372 return 0 1373 }, 1374 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SETLIST 1375 reg := L.reg 1376 cf := L.currentFrame 1377 lbase := cf.LocalBase 1378 A := int(inst>>18) & 0xff //GETA 1379 RA := lbase + A 1380 B := int(inst & 0x1ff) //GETB 1381 C := int(inst>>9) & 0x1ff //GETC 1382 if C == 0 { 1383 C = int(cf.Fn.Proto.Code[cf.Pc]) 1384 cf.Pc++ 1385 } 1386 offset := (C - 1) * FieldsPerFlush 1387 table := reg.Get(RA).(*LTable) 1388 nelem := B 1389 if B == 0 { 1390 nelem = reg.Top() - RA - 1 1391 } 1392 for i := 1; i <= nelem; i++ { 1393 table.RawSetInt(offset+i, reg.Get(RA+i)) 1394 } 1395 return 0 1396 }, 1397 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_CLOSE 1398 cf := L.currentFrame 1399 lbase := cf.LocalBase 1400 A := int(inst>>18) & 0xff //GETA 1401 RA := lbase + A 1402 // this section is inlined by go-inline 1403 // source function is 'func (ls *LState) closeUpvalues(idx int) ' in '_state.go' 1404 { 1405 ls := L 1406 idx := RA 1407 if ls.uvcache != nil { 1408 var prev *Upvalue 1409 for uv := ls.uvcache; uv != nil; uv = uv.next { 1410 if uv.index >= idx { 1411 if prev != nil { 1412 prev.next = nil 1413 } else { 1414 ls.uvcache = nil 1415 } 1416 uv.Close() 1417 } 1418 prev = uv 1419 } 1420 } 1421 } 1422 return 0 1423 }, 1424 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_CLOSURE 1425 reg := L.reg 1426 cf := L.currentFrame 1427 lbase := cf.LocalBase 1428 A := int(inst>>18) & 0xff //GETA 1429 RA := lbase + A 1430 Bx := int(inst & 0x3ffff) //GETBX 1431 proto := cf.Fn.Proto.FunctionPrototypes[Bx] 1432 closure := newLFunctionL(proto, cf.Fn.Env, int(proto.NumUpvalues)) 1433 reg.Set(RA, closure) 1434 for i := 0; i < int(proto.NumUpvalues); i++ { 1435 inst = cf.Fn.Proto.Code[cf.Pc] 1436 cf.Pc++ 1437 B := opGetArgB(inst) 1438 switch opGetOpCode(inst) { 1439 case OP_MOVE: 1440 closure.Upvalues[i] = L.findUpvalue(lbase + B) 1441 case OP_GETUPVAL: 1442 closure.Upvalues[i] = cf.Fn.Upvalues[B] 1443 } 1444 } 1445 return 0 1446 }, 1447 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_VARARG 1448 reg := L.reg 1449 cf := L.currentFrame 1450 lbase := cf.LocalBase 1451 A := int(inst>>18) & 0xff //GETA 1452 RA := lbase + A 1453 B := int(inst & 0x1ff) //GETB 1454 nparams := int(cf.Fn.Proto.NumParameters) 1455 nvarargs := cf.NArgs - nparams 1456 if nvarargs < 0 { 1457 nvarargs = 0 1458 } 1459 nwant := B - 1 1460 if B == 0 { 1461 nwant = nvarargs 1462 } 1463 // this section is inlined by go-inline 1464 // source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go' 1465 { 1466 rg := reg 1467 regv := RA 1468 start := cf.Base + nparams + 1 1469 limit := cf.LocalBase 1470 n := nwant 1471 newSize := regv + n 1472 // this section is inlined by go-inline 1473 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1474 { 1475 requiredSize := newSize 1476 if requiredSize > cap(rg.array) { 1477 rg.resize(requiredSize) 1478 } 1479 } 1480 if limit == -1 || limit > rg.top { 1481 limit = rg.top 1482 } 1483 for i := 0; i < n; i++ { 1484 srcIdx := start + i 1485 if srcIdx >= limit || srcIdx < 0 { 1486 rg.array[regv+i] = LNil 1487 } else { 1488 rg.array[regv+i] = rg.array[srcIdx] 1489 } 1490 } 1491 1492 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1493 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1494 oldtop := rg.top 1495 rg.top = regv + n 1496 if rg.top < oldtop { 1497 nilRange := rg.array[rg.top:oldtop] 1498 for i := range nilRange { 1499 nilRange[i] = nil 1500 } 1501 } 1502 } 1503 return 0 1504 }, 1505 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_NOP 1506 return 0 1507 }, 1508 } 1509 } 1510 1511 func opArith(L *LState, inst uint32, baseframe *callFrame) int { //OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_MOD, OP_POW 1512 reg := L.reg 1513 cf := L.currentFrame 1514 lbase := cf.LocalBase 1515 A := int(inst>>18) & 0xff //GETA 1516 RA := lbase + A 1517 opcode := int(inst >> 26) //GETOPCODE 1518 B := int(inst & 0x1ff) //GETB 1519 C := int(inst>>9) & 0x1ff //GETC 1520 lhs := L.rkValue(B) 1521 rhs := L.rkValue(C) 1522 v1, ok1 := lhs.assertFloat64() 1523 v2, ok2 := rhs.assertFloat64() 1524 if ok1 && ok2 { 1525 reg.SetNumber(RA, numberArith(L, opcode, LNumber(v1), LNumber(v2))) 1526 } else { 1527 reg.Set(RA, objectArith(L, opcode, lhs, rhs)) 1528 } 1529 return 0 1530 } 1531 1532 func luaModulo(lhs, rhs LNumber) LNumber { 1533 flhs := float64(lhs) 1534 frhs := float64(rhs) 1535 v := math.Mod(flhs, frhs) 1536 if flhs < 0 || frhs < 0 && !(flhs < 0 && frhs < 0) { 1537 v += frhs 1538 } 1539 return LNumber(v) 1540 } 1541 1542 func numberArith(L *LState, opcode int, lhs, rhs LNumber) LNumber { 1543 switch opcode { 1544 case OP_ADD: 1545 return lhs + rhs 1546 case OP_SUB: 1547 return lhs - rhs 1548 case OP_MUL: 1549 return lhs * rhs 1550 case OP_DIV: 1551 return lhs / rhs 1552 case OP_MOD: 1553 return luaModulo(lhs, rhs) 1554 case OP_POW: 1555 flhs := float64(lhs) 1556 frhs := float64(rhs) 1557 return LNumber(math.Pow(flhs, frhs)) 1558 } 1559 panic("should not reach here") 1560 return LNumber(0) 1561 } 1562 1563 func objectArith(L *LState, opcode int, lhs, rhs LValue) LValue { 1564 event := "" 1565 switch opcode { 1566 case OP_ADD: 1567 event = "__add" 1568 case OP_SUB: 1569 event = "__sub" 1570 case OP_MUL: 1571 event = "__mul" 1572 case OP_DIV: 1573 event = "__div" 1574 case OP_MOD: 1575 event = "__mod" 1576 case OP_POW: 1577 event = "__pow" 1578 } 1579 op := L.metaOp2(lhs, rhs, event) 1580 if op.Type() == LTFunction { 1581 L.reg.Push(op) 1582 L.reg.Push(lhs) 1583 L.reg.Push(rhs) 1584 L.Call(2, 1) 1585 return L.reg.Pop() 1586 } 1587 if str, ok := lhs.(LString); ok { 1588 if lnum, err := parseNumber(string(str)); err == nil { 1589 lhs = lnum 1590 } 1591 } 1592 if str, ok := rhs.(LString); ok { 1593 if rnum, err := parseNumber(string(str)); err == nil { 1594 rhs = rnum 1595 } 1596 } 1597 if v1, ok1 := lhs.assertFloat64(); ok1 { 1598 if v2, ok2 := rhs.assertFloat64(); ok2 { 1599 return numberArith(L, opcode, LNumber(v1), LNumber(v2)) 1600 } 1601 } 1602 L.RaiseError(fmt.Sprintf("cannot perform %v operation between %v and %v", 1603 strings.TrimLeft(event, "_"), lhs.Type().String(), rhs.Type().String())) 1604 1605 return LNil 1606 } 1607 1608 func stringConcat(L *LState, total, last int) LValue { 1609 rhs := L.reg.Get(last) 1610 total-- 1611 for i := last - 1; total > 0; { 1612 lhs := L.reg.Get(i) 1613 if !(LVCanConvToString(lhs) && LVCanConvToString(rhs)) { 1614 op := L.metaOp2(lhs, rhs, "__concat") 1615 if op.Type() == LTFunction { 1616 L.reg.Push(op) 1617 L.reg.Push(lhs) 1618 L.reg.Push(rhs) 1619 L.Call(2, 1) 1620 rhs = L.reg.Pop() 1621 total-- 1622 i-- 1623 } else { 1624 L.RaiseError("cannot perform concat operation between %v and %v", lhs.Type().String(), rhs.Type().String()) 1625 return LNil 1626 } 1627 } else { 1628 buf := make([]string, total+1) 1629 buf[total] = LVAsString(rhs) 1630 for total > 0 { 1631 lhs = L.reg.Get(i) 1632 if !LVCanConvToString(lhs) { 1633 break 1634 } 1635 buf[total-1] = LVAsString(lhs) 1636 i-- 1637 total-- 1638 } 1639 rhs = LString(strings.Join(buf, "")) 1640 } 1641 } 1642 return rhs 1643 } 1644 1645 func lessThan(L *LState, lhs, rhs LValue) bool { 1646 // optimization for numbers 1647 if v1, ok1 := lhs.assertFloat64(); ok1 { 1648 if v2, ok2 := rhs.assertFloat64(); ok2 { 1649 return v1 < v2 1650 } 1651 L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String()) 1652 } 1653 if lhs.Type() != rhs.Type() { 1654 L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String()) 1655 return false 1656 } 1657 ret := false 1658 switch lhs.Type() { 1659 case LTString: 1660 ret = strCmp(string(lhs.(LString)), string(rhs.(LString))) < 0 1661 default: 1662 ret = objectRationalWithError(L, lhs, rhs, "__lt") 1663 } 1664 return ret 1665 } 1666 1667 func equals(L *LState, lhs, rhs LValue, raw bool) bool { 1668 if lhs.Type() != rhs.Type() { 1669 return false 1670 } 1671 1672 ret := false 1673 switch lhs.Type() { 1674 case LTNil: 1675 ret = true 1676 case LTNumber: 1677 v1, _ := lhs.assertFloat64() 1678 v2, _ := rhs.assertFloat64() 1679 ret = v1 == v2 1680 case LTBool: 1681 ret = bool(lhs.(LBool)) == bool(rhs.(LBool)) 1682 case LTString: 1683 ret = string(lhs.(LString)) == string(rhs.(LString)) 1684 case LTUserData, LTTable: 1685 if lhs == rhs { 1686 ret = true 1687 } else if !raw { 1688 switch objectRational(L, lhs, rhs, "__eq") { 1689 case 1: 1690 ret = true 1691 default: 1692 ret = false 1693 } 1694 } 1695 default: 1696 ret = lhs == rhs 1697 } 1698 return ret 1699 } 1700 1701 func objectRationalWithError(L *LState, lhs, rhs LValue, event string) bool { 1702 switch objectRational(L, lhs, rhs, event) { 1703 case 1: 1704 return true 1705 case 0: 1706 return false 1707 } 1708 L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String()) 1709 return false 1710 } 1711 1712 func objectRational(L *LState, lhs, rhs LValue, event string) int { 1713 m1 := L.metaOp1(lhs, event) 1714 m2 := L.metaOp1(rhs, event) 1715 if m1.Type() == LTFunction && m1 == m2 { 1716 L.reg.Push(m1) 1717 L.reg.Push(lhs) 1718 L.reg.Push(rhs) 1719 L.Call(2, 1) 1720 if LVAsBool(L.reg.Pop()) { 1721 return 1 1722 } 1723 return 0 1724 } 1725 return -1 1726 }