github.com/guardangely/gopher-lua@v0.0.0-20200324075529-f92e6f279f59/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.SetNumber(RA, LNumber(0)) 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 newSize := cf.LocalBase + np 732 // this section is inlined by go-inline 733 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 734 { 735 rg := ls.reg 736 requiredSize := newSize 737 if requiredSize > cap(rg.array) { 738 rg.resize(requiredSize) 739 } 740 } 741 for i := nargs; i < np; i++ { 742 ls.reg.array[cf.LocalBase+i] = LNil 743 nargs = np 744 } 745 746 if (proto.IsVarArg & VarArgIsVarArg) == 0 { 747 if nargs < int(proto.NumUsedRegisters) { 748 nargs = int(proto.NumUsedRegisters) 749 } 750 newSize = cf.LocalBase + nargs 751 // this section is inlined by go-inline 752 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 753 { 754 rg := ls.reg 755 requiredSize := newSize 756 if requiredSize > cap(rg.array) { 757 rg.resize(requiredSize) 758 } 759 } 760 for i := np; i < nargs; i++ { 761 ls.reg.array[cf.LocalBase+i] = LNil 762 } 763 ls.reg.top = cf.LocalBase + int(proto.NumUsedRegisters) 764 } else { 765 /* swap vararg positions: 766 closure 767 namedparam1 <- lbase 768 namedparam2 769 vararg1 770 vararg2 771 772 TO 773 774 closure 775 nil 776 nil 777 vararg1 778 vararg2 779 namedparam1 <- lbase 780 namedparam2 781 */ 782 nvarargs := nargs - np 783 if nvarargs < 0 { 784 nvarargs = 0 785 } 786 787 ls.reg.SetTop(cf.LocalBase + nargs + np) 788 for i := 0; i < np; i++ { 789 //ls.reg.Set(cf.LocalBase+nargs+i, ls.reg.Get(cf.LocalBase+i)) 790 ls.reg.array[cf.LocalBase+nargs+i] = ls.reg.array[cf.LocalBase+i] 791 //ls.reg.Set(cf.LocalBase+i, LNil) 792 ls.reg.array[cf.LocalBase+i] = LNil 793 } 794 795 if CompatVarArg { 796 ls.reg.SetTop(cf.LocalBase + nargs + np + 1) 797 if (proto.IsVarArg & VarArgNeedsArg) != 0 { 798 argtb := newLTable(nvarargs, 0) 799 for i := 0; i < nvarargs; i++ { 800 argtb.RawSetInt(i+1, ls.reg.Get(cf.LocalBase+np+i)) 801 } 802 argtb.RawSetString("n", LNumber(nvarargs)) 803 //ls.reg.Set(cf.LocalBase+nargs+np, argtb) 804 ls.reg.array[cf.LocalBase+nargs+np] = argtb 805 } else { 806 ls.reg.array[cf.LocalBase+nargs+np] = LNil 807 } 808 } 809 cf.LocalBase += nargs 810 maxreg := cf.LocalBase + int(proto.NumUsedRegisters) 811 ls.reg.SetTop(maxreg) 812 } 813 } 814 } 815 ls.currentFrame = newcf 816 } 817 if callable.IsG && callGFunction(L, false) { 818 return 1 819 } 820 return 0 821 }, 822 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_TAILCALL 823 reg := L.reg 824 cf := L.currentFrame 825 lbase := cf.LocalBase 826 A := int(inst>>18) & 0xff //GETA 827 RA := lbase + A 828 B := int(inst & 0x1ff) //GETB 829 nargs := B - 1 830 if B == 0 { 831 nargs = reg.Top() - (RA + 1) 832 } 833 lv := reg.Get(RA) 834 var callable *LFunction 835 var meta bool 836 if fn, ok := lv.assertFunction(); ok { 837 callable = fn 838 meta = false 839 } else { 840 callable, meta = L.metaCall(lv) 841 } 842 if callable == nil { 843 L.RaiseError("attempt to call a non-function object") 844 } 845 // this section is inlined by go-inline 846 // source function is 'func (ls *LState) closeUpvalues(idx int) ' in '_state.go' 847 { 848 ls := L 849 idx := lbase 850 if ls.uvcache != nil { 851 var prev *Upvalue 852 for uv := ls.uvcache; uv != nil; uv = uv.next { 853 if uv.index >= idx { 854 if prev != nil { 855 prev.next = nil 856 } else { 857 ls.uvcache = nil 858 } 859 uv.Close() 860 } 861 prev = uv 862 } 863 } 864 } 865 if callable.IsG { 866 luaframe := cf 867 L.pushCallFrame(callFrame{ 868 Fn: callable, 869 Pc: 0, 870 Base: RA, 871 LocalBase: RA + 1, 872 ReturnBase: cf.ReturnBase, 873 NArgs: nargs, 874 NRet: cf.NRet, 875 Parent: cf, 876 TailCall: 0, 877 }, lv, meta) 878 if callGFunction(L, true) { 879 return 1 880 } 881 if L.currentFrame == nil || L.currentFrame.Fn.IsG || luaframe == baseframe { 882 return 1 883 } 884 } else { 885 base := cf.Base 886 cf.Fn = callable 887 cf.Pc = 0 888 cf.Base = RA 889 cf.LocalBase = RA + 1 890 cf.ReturnBase = cf.ReturnBase 891 cf.NArgs = nargs 892 cf.NRet = cf.NRet 893 cf.TailCall++ 894 lbase := cf.LocalBase 895 if meta { 896 cf.NArgs++ 897 L.reg.Insert(lv, cf.LocalBase) 898 } 899 // this section is inlined by go-inline 900 // source function is 'func (ls *LState) initCallFrame(cf *callFrame) ' in '_state.go' 901 { 902 ls := L 903 if cf.Fn.IsG { 904 ls.reg.SetTop(cf.LocalBase + cf.NArgs) 905 } else { 906 proto := cf.Fn.Proto 907 nargs := cf.NArgs 908 np := int(proto.NumParameters) 909 newSize := cf.LocalBase + np 910 // this section is inlined by go-inline 911 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 912 { 913 rg := ls.reg 914 requiredSize := newSize 915 if requiredSize > cap(rg.array) { 916 rg.resize(requiredSize) 917 } 918 } 919 for i := nargs; i < np; i++ { 920 ls.reg.array[cf.LocalBase+i] = LNil 921 nargs = np 922 } 923 924 if (proto.IsVarArg & VarArgIsVarArg) == 0 { 925 if nargs < int(proto.NumUsedRegisters) { 926 nargs = int(proto.NumUsedRegisters) 927 } 928 newSize = cf.LocalBase + nargs 929 // this section is inlined by go-inline 930 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 931 { 932 rg := ls.reg 933 requiredSize := newSize 934 if requiredSize > cap(rg.array) { 935 rg.resize(requiredSize) 936 } 937 } 938 for i := np; i < nargs; i++ { 939 ls.reg.array[cf.LocalBase+i] = LNil 940 } 941 ls.reg.top = cf.LocalBase + int(proto.NumUsedRegisters) 942 } else { 943 /* swap vararg positions: 944 closure 945 namedparam1 <- lbase 946 namedparam2 947 vararg1 948 vararg2 949 950 TO 951 952 closure 953 nil 954 nil 955 vararg1 956 vararg2 957 namedparam1 <- lbase 958 namedparam2 959 */ 960 nvarargs := nargs - np 961 if nvarargs < 0 { 962 nvarargs = 0 963 } 964 965 ls.reg.SetTop(cf.LocalBase + nargs + np) 966 for i := 0; i < np; i++ { 967 //ls.reg.Set(cf.LocalBase+nargs+i, ls.reg.Get(cf.LocalBase+i)) 968 ls.reg.array[cf.LocalBase+nargs+i] = ls.reg.array[cf.LocalBase+i] 969 //ls.reg.Set(cf.LocalBase+i, LNil) 970 ls.reg.array[cf.LocalBase+i] = LNil 971 } 972 973 if CompatVarArg { 974 ls.reg.SetTop(cf.LocalBase + nargs + np + 1) 975 if (proto.IsVarArg & VarArgNeedsArg) != 0 { 976 argtb := newLTable(nvarargs, 0) 977 for i := 0; i < nvarargs; i++ { 978 argtb.RawSetInt(i+1, ls.reg.Get(cf.LocalBase+np+i)) 979 } 980 argtb.RawSetString("n", LNumber(nvarargs)) 981 //ls.reg.Set(cf.LocalBase+nargs+np, argtb) 982 ls.reg.array[cf.LocalBase+nargs+np] = argtb 983 } else { 984 ls.reg.array[cf.LocalBase+nargs+np] = LNil 985 } 986 } 987 cf.LocalBase += nargs 988 maxreg := cf.LocalBase + int(proto.NumUsedRegisters) 989 ls.reg.SetTop(maxreg) 990 } 991 } 992 } 993 // this section is inlined by go-inline 994 // source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go' 995 { 996 rg := L.reg 997 regv := base 998 start := RA 999 limit := -1 1000 n := reg.Top() - RA - 1 1001 newSize := regv + n 1002 // this section is inlined by go-inline 1003 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1004 { 1005 requiredSize := newSize 1006 if requiredSize > cap(rg.array) { 1007 rg.resize(requiredSize) 1008 } 1009 } 1010 if limit == -1 || limit > rg.top { 1011 limit = rg.top 1012 } 1013 for i := 0; i < n; i++ { 1014 srcIdx := start + i 1015 if srcIdx >= limit || srcIdx < 0 { 1016 rg.array[regv+i] = LNil 1017 } else { 1018 rg.array[regv+i] = rg.array[srcIdx] 1019 } 1020 } 1021 1022 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1023 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1024 oldtop := rg.top 1025 rg.top = regv + n 1026 if rg.top < oldtop { 1027 nilRange := rg.array[rg.top:oldtop] 1028 for i := range nilRange { 1029 nilRange[i] = nil 1030 } 1031 } 1032 } 1033 cf.Base = base 1034 cf.LocalBase = base + (cf.LocalBase - lbase + 1) 1035 } 1036 return 0 1037 }, 1038 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_RETURN 1039 reg := L.reg 1040 cf := L.currentFrame 1041 lbase := cf.LocalBase 1042 A := int(inst>>18) & 0xff //GETA 1043 RA := lbase + A 1044 B := int(inst & 0x1ff) //GETB 1045 // this section is inlined by go-inline 1046 // source function is 'func (ls *LState) closeUpvalues(idx int) ' in '_state.go' 1047 { 1048 ls := L 1049 idx := lbase 1050 if ls.uvcache != nil { 1051 var prev *Upvalue 1052 for uv := ls.uvcache; uv != nil; uv = uv.next { 1053 if uv.index >= idx { 1054 if prev != nil { 1055 prev.next = nil 1056 } else { 1057 ls.uvcache = nil 1058 } 1059 uv.Close() 1060 } 1061 prev = uv 1062 } 1063 } 1064 } 1065 nret := B - 1 1066 if B == 0 { 1067 nret = reg.Top() - RA 1068 } 1069 n := cf.NRet 1070 if cf.NRet == MultRet { 1071 n = nret 1072 } 1073 1074 if L.Parent != nil && L.stack.Sp() == 1 { 1075 // this section is inlined by go-inline 1076 // source function is 'func copyReturnValues(L *LState, regv, start, n, b int) ' in '_vm.go' 1077 { 1078 regv := reg.Top() 1079 start := RA 1080 b := B 1081 if b == 1 { 1082 // this section is inlined by go-inline 1083 // source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go' 1084 { 1085 rg := L.reg 1086 regm := regv 1087 newSize := regm + n 1088 // this section is inlined by go-inline 1089 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1090 { 1091 requiredSize := newSize 1092 if requiredSize > cap(rg.array) { 1093 rg.resize(requiredSize) 1094 } 1095 } 1096 for i := 0; i < n; i++ { 1097 rg.array[regm+i] = LNil 1098 } 1099 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1100 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1101 oldtop := rg.top 1102 rg.top = regm + n 1103 if rg.top < oldtop { 1104 nilRange := rg.array[rg.top:oldtop] 1105 for i := range nilRange { 1106 nilRange[i] = nil 1107 } 1108 } 1109 } 1110 } else { 1111 // this section is inlined by go-inline 1112 // source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go' 1113 { 1114 rg := L.reg 1115 limit := -1 1116 newSize := regv + n 1117 // this section is inlined by go-inline 1118 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1119 { 1120 requiredSize := newSize 1121 if requiredSize > cap(rg.array) { 1122 rg.resize(requiredSize) 1123 } 1124 } 1125 if limit == -1 || limit > rg.top { 1126 limit = rg.top 1127 } 1128 for i := 0; i < n; i++ { 1129 srcIdx := start + i 1130 if srcIdx >= limit || srcIdx < 0 { 1131 rg.array[regv+i] = LNil 1132 } else { 1133 rg.array[regv+i] = rg.array[srcIdx] 1134 } 1135 } 1136 1137 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1138 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1139 oldtop := rg.top 1140 rg.top = regv + n 1141 if rg.top < oldtop { 1142 nilRange := rg.array[rg.top:oldtop] 1143 for i := range nilRange { 1144 nilRange[i] = nil 1145 } 1146 } 1147 } 1148 if b > 1 && n > (b-1) { 1149 // this section is inlined by go-inline 1150 // source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go' 1151 { 1152 rg := L.reg 1153 regm := regv + b - 1 1154 n := n - (b - 1) 1155 newSize := regm + n 1156 // this section is inlined by go-inline 1157 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1158 { 1159 requiredSize := newSize 1160 if requiredSize > cap(rg.array) { 1161 rg.resize(requiredSize) 1162 } 1163 } 1164 for i := 0; i < n; i++ { 1165 rg.array[regm+i] = LNil 1166 } 1167 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1168 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1169 oldtop := rg.top 1170 rg.top = regm + n 1171 if rg.top < oldtop { 1172 nilRange := rg.array[rg.top:oldtop] 1173 for i := range nilRange { 1174 nilRange[i] = nil 1175 } 1176 } 1177 } 1178 } 1179 } 1180 } 1181 switchToParentThread(L, n, false, true) 1182 return 1 1183 } 1184 islast := baseframe == L.stack.Pop() || L.stack.IsEmpty() 1185 // this section is inlined by go-inline 1186 // source function is 'func copyReturnValues(L *LState, regv, start, n, b int) ' in '_vm.go' 1187 { 1188 regv := cf.ReturnBase 1189 start := RA 1190 b := B 1191 if b == 1 { 1192 // this section is inlined by go-inline 1193 // source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go' 1194 { 1195 rg := L.reg 1196 regm := regv 1197 newSize := regm + n 1198 // this section is inlined by go-inline 1199 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1200 { 1201 requiredSize := newSize 1202 if requiredSize > cap(rg.array) { 1203 rg.resize(requiredSize) 1204 } 1205 } 1206 for i := 0; i < n; i++ { 1207 rg.array[regm+i] = LNil 1208 } 1209 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1210 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1211 oldtop := rg.top 1212 rg.top = regm + n 1213 if rg.top < oldtop { 1214 nilRange := rg.array[rg.top:oldtop] 1215 for i := range nilRange { 1216 nilRange[i] = nil 1217 } 1218 } 1219 } 1220 } else { 1221 // this section is inlined by go-inline 1222 // source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go' 1223 { 1224 rg := L.reg 1225 limit := -1 1226 newSize := regv + n 1227 // this section is inlined by go-inline 1228 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1229 { 1230 requiredSize := newSize 1231 if requiredSize > cap(rg.array) { 1232 rg.resize(requiredSize) 1233 } 1234 } 1235 if limit == -1 || limit > rg.top { 1236 limit = rg.top 1237 } 1238 for i := 0; i < n; i++ { 1239 srcIdx := start + i 1240 if srcIdx >= limit || srcIdx < 0 { 1241 rg.array[regv+i] = LNil 1242 } else { 1243 rg.array[regv+i] = rg.array[srcIdx] 1244 } 1245 } 1246 1247 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1248 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1249 oldtop := rg.top 1250 rg.top = regv + n 1251 if rg.top < oldtop { 1252 nilRange := rg.array[rg.top:oldtop] 1253 for i := range nilRange { 1254 nilRange[i] = nil 1255 } 1256 } 1257 } 1258 if b > 1 && n > (b-1) { 1259 // this section is inlined by go-inline 1260 // source function is 'func (rg *registry) FillNil(regm, n int) ' in '_state.go' 1261 { 1262 rg := L.reg 1263 regm := regv + b - 1 1264 n := n - (b - 1) 1265 newSize := regm + n 1266 // this section is inlined by go-inline 1267 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1268 { 1269 requiredSize := newSize 1270 if requiredSize > cap(rg.array) { 1271 rg.resize(requiredSize) 1272 } 1273 } 1274 for i := 0; i < n; i++ { 1275 rg.array[regm+i] = LNil 1276 } 1277 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1278 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1279 oldtop := rg.top 1280 rg.top = regm + n 1281 if rg.top < oldtop { 1282 nilRange := rg.array[rg.top:oldtop] 1283 for i := range nilRange { 1284 nilRange[i] = nil 1285 } 1286 } 1287 } 1288 } 1289 } 1290 } 1291 L.currentFrame = L.stack.Last() 1292 if islast || L.currentFrame == nil || L.currentFrame.Fn.IsG { 1293 return 1 1294 } 1295 return 0 1296 }, 1297 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_FORLOOP 1298 reg := L.reg 1299 cf := L.currentFrame 1300 lbase := cf.LocalBase 1301 A := int(inst>>18) & 0xff //GETA 1302 RA := lbase + A 1303 if init, ok1 := reg.Get(RA).assertFloat64(); ok1 { 1304 if limit, ok2 := reg.Get(RA + 1).assertFloat64(); ok2 { 1305 if step, ok3 := reg.Get(RA + 2).assertFloat64(); ok3 { 1306 init += step 1307 reg.SetNumber(RA, LNumber(init)) 1308 if (step > 0 && init <= limit) || (step <= 0 && init >= limit) { 1309 Sbx := int(inst&0x3ffff) - opMaxArgSbx //GETSBX 1310 cf.Pc += Sbx 1311 reg.SetNumber(RA+3, LNumber(init)) 1312 } else { 1313 reg.SetTop(RA + 1) 1314 } 1315 } else { 1316 L.RaiseError("for statement step must be a number") 1317 } 1318 } else { 1319 L.RaiseError("for statement limit must be a number") 1320 } 1321 } else { 1322 L.RaiseError("for statement init must be a number") 1323 } 1324 return 0 1325 }, 1326 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_FORPREP 1327 reg := L.reg 1328 cf := L.currentFrame 1329 lbase := cf.LocalBase 1330 A := int(inst>>18) & 0xff //GETA 1331 RA := lbase + A 1332 Sbx := int(inst&0x3ffff) - opMaxArgSbx //GETSBX 1333 if init, ok1 := reg.Get(RA).assertFloat64(); ok1 { 1334 if step, ok2 := reg.Get(RA + 2).assertFloat64(); ok2 { 1335 reg.SetNumber(RA, LNumber(init-step)) 1336 } else { 1337 L.RaiseError("for statement step must be a number") 1338 } 1339 } else { 1340 L.RaiseError("for statement init must be a number") 1341 } 1342 cf.Pc += Sbx 1343 return 0 1344 }, 1345 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_TFORLOOP 1346 reg := L.reg 1347 cf := L.currentFrame 1348 lbase := cf.LocalBase 1349 A := int(inst>>18) & 0xff //GETA 1350 RA := lbase + A 1351 C := int(inst>>9) & 0x1ff //GETC 1352 nret := C 1353 reg.SetTop(RA + 3 + 2) 1354 reg.Set(RA+3+2, reg.Get(RA+2)) 1355 reg.Set(RA+3+1, reg.Get(RA+1)) 1356 reg.Set(RA+3, reg.Get(RA)) 1357 L.callR(2, nret, RA+3) 1358 if value := reg.Get(RA + 3); value != LNil { 1359 reg.Set(RA+2, value) 1360 pc := cf.Fn.Proto.Code[cf.Pc] 1361 cf.Pc += int(pc&0x3ffff) - opMaxArgSbx 1362 } 1363 cf.Pc++ 1364 return 0 1365 }, 1366 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SETLIST 1367 reg := L.reg 1368 cf := L.currentFrame 1369 lbase := cf.LocalBase 1370 A := int(inst>>18) & 0xff //GETA 1371 RA := lbase + A 1372 B := int(inst & 0x1ff) //GETB 1373 C := int(inst>>9) & 0x1ff //GETC 1374 if C == 0 { 1375 C = int(cf.Fn.Proto.Code[cf.Pc]) 1376 cf.Pc++ 1377 } 1378 offset := (C - 1) * FieldsPerFlush 1379 table := reg.Get(RA).(*LTable) 1380 nelem := B 1381 if B == 0 { 1382 nelem = reg.Top() - RA - 1 1383 } 1384 for i := 1; i <= nelem; i++ { 1385 table.RawSetInt(offset+i, reg.Get(RA+i)) 1386 } 1387 return 0 1388 }, 1389 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_CLOSE 1390 cf := L.currentFrame 1391 lbase := cf.LocalBase 1392 A := int(inst>>18) & 0xff //GETA 1393 RA := lbase + A 1394 // this section is inlined by go-inline 1395 // source function is 'func (ls *LState) closeUpvalues(idx int) ' in '_state.go' 1396 { 1397 ls := L 1398 idx := RA 1399 if ls.uvcache != nil { 1400 var prev *Upvalue 1401 for uv := ls.uvcache; uv != nil; uv = uv.next { 1402 if uv.index >= idx { 1403 if prev != nil { 1404 prev.next = nil 1405 } else { 1406 ls.uvcache = nil 1407 } 1408 uv.Close() 1409 } 1410 prev = uv 1411 } 1412 } 1413 } 1414 return 0 1415 }, 1416 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_CLOSURE 1417 reg := L.reg 1418 cf := L.currentFrame 1419 lbase := cf.LocalBase 1420 A := int(inst>>18) & 0xff //GETA 1421 RA := lbase + A 1422 Bx := int(inst & 0x3ffff) //GETBX 1423 proto := cf.Fn.Proto.FunctionPrototypes[Bx] 1424 closure := newLFunctionL(proto, cf.Fn.Env, int(proto.NumUpvalues)) 1425 reg.Set(RA, closure) 1426 for i := 0; i < int(proto.NumUpvalues); i++ { 1427 inst = cf.Fn.Proto.Code[cf.Pc] 1428 cf.Pc++ 1429 B := opGetArgB(inst) 1430 switch opGetOpCode(inst) { 1431 case OP_MOVE: 1432 closure.Upvalues[i] = L.findUpvalue(lbase + B) 1433 case OP_GETUPVAL: 1434 closure.Upvalues[i] = cf.Fn.Upvalues[B] 1435 } 1436 } 1437 return 0 1438 }, 1439 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_VARARG 1440 reg := L.reg 1441 cf := L.currentFrame 1442 lbase := cf.LocalBase 1443 A := int(inst>>18) & 0xff //GETA 1444 RA := lbase + A 1445 B := int(inst & 0x1ff) //GETB 1446 nparams := int(cf.Fn.Proto.NumParameters) 1447 nvarargs := cf.NArgs - nparams 1448 if nvarargs < 0 { 1449 nvarargs = 0 1450 } 1451 nwant := B - 1 1452 if B == 0 { 1453 nwant = nvarargs 1454 } 1455 // this section is inlined by go-inline 1456 // source function is 'func (rg *registry) CopyRange(regv, start, limit, n int) ' in '_state.go' 1457 { 1458 rg := reg 1459 regv := RA 1460 start := cf.Base + nparams + 1 1461 limit := cf.LocalBase 1462 n := nwant 1463 newSize := regv + n 1464 // this section is inlined by go-inline 1465 // source function is 'func (rg *registry) checkSize(requiredSize int) ' in '_state.go' 1466 { 1467 requiredSize := newSize 1468 if requiredSize > cap(rg.array) { 1469 rg.resize(requiredSize) 1470 } 1471 } 1472 if limit == -1 || limit > rg.top { 1473 limit = rg.top 1474 } 1475 for i := 0; i < n; i++ { 1476 srcIdx := start + i 1477 if srcIdx >= limit || srcIdx < 0 { 1478 rg.array[regv+i] = LNil 1479 } else { 1480 rg.array[regv+i] = rg.array[srcIdx] 1481 } 1482 } 1483 1484 // values beyond top don't need to be valid LValues, so setting them to nil is fine 1485 // setting them to nil rather than LNil lets us invoke the golang memclr opto 1486 oldtop := rg.top 1487 rg.top = regv + n 1488 if rg.top < oldtop { 1489 nilRange := rg.array[rg.top:oldtop] 1490 for i := range nilRange { 1491 nilRange[i] = nil 1492 } 1493 } 1494 } 1495 return 0 1496 }, 1497 func(L *LState, inst uint32, baseframe *callFrame) int { //OP_NOP 1498 return 0 1499 }, 1500 } 1501 } 1502 1503 func opArith(L *LState, inst uint32, baseframe *callFrame) int { //OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_MOD, OP_POW 1504 reg := L.reg 1505 cf := L.currentFrame 1506 lbase := cf.LocalBase 1507 A := int(inst>>18) & 0xff //GETA 1508 RA := lbase + A 1509 opcode := int(inst >> 26) //GETOPCODE 1510 B := int(inst & 0x1ff) //GETB 1511 C := int(inst>>9) & 0x1ff //GETC 1512 lhs := L.rkValue(B) 1513 rhs := L.rkValue(C) 1514 v1, ok1 := lhs.assertFloat64() 1515 v2, ok2 := rhs.assertFloat64() 1516 if ok1 && ok2 { 1517 reg.SetNumber(RA, numberArith(L, opcode, LNumber(v1), LNumber(v2))) 1518 } else { 1519 reg.Set(RA, objectArith(L, opcode, lhs, rhs)) 1520 } 1521 return 0 1522 } 1523 1524 func luaModulo(lhs, rhs LNumber) LNumber { 1525 flhs := float64(lhs) 1526 frhs := float64(rhs) 1527 v := math.Mod(flhs, frhs) 1528 if flhs < 0 || frhs < 0 && !(flhs < 0 && frhs < 0) { 1529 v += frhs 1530 } 1531 return LNumber(v) 1532 } 1533 1534 func numberArith(L *LState, opcode int, lhs, rhs LNumber) LNumber { 1535 switch opcode { 1536 case OP_ADD: 1537 return lhs + rhs 1538 case OP_SUB: 1539 return lhs - rhs 1540 case OP_MUL: 1541 return lhs * rhs 1542 case OP_DIV: 1543 return lhs / rhs 1544 case OP_MOD: 1545 return luaModulo(lhs, rhs) 1546 case OP_POW: 1547 flhs := float64(lhs) 1548 frhs := float64(rhs) 1549 return LNumber(math.Pow(flhs, frhs)) 1550 } 1551 panic("should not reach here") 1552 return LNumber(0) 1553 } 1554 1555 func objectArith(L *LState, opcode int, lhs, rhs LValue) LValue { 1556 event := "" 1557 switch opcode { 1558 case OP_ADD: 1559 event = "__add" 1560 case OP_SUB: 1561 event = "__sub" 1562 case OP_MUL: 1563 event = "__mul" 1564 case OP_DIV: 1565 event = "__div" 1566 case OP_MOD: 1567 event = "__mod" 1568 case OP_POW: 1569 event = "__pow" 1570 } 1571 op := L.metaOp2(lhs, rhs, event) 1572 if op.Type() == LTFunction { 1573 L.reg.Push(op) 1574 L.reg.Push(lhs) 1575 L.reg.Push(rhs) 1576 L.Call(2, 1) 1577 return L.reg.Pop() 1578 } 1579 if str, ok := lhs.(LString); ok { 1580 if lnum, err := parseNumber(string(str)); err == nil { 1581 lhs = lnum 1582 } 1583 } 1584 if str, ok := rhs.(LString); ok { 1585 if rnum, err := parseNumber(string(str)); err == nil { 1586 rhs = rnum 1587 } 1588 } 1589 if v1, ok1 := lhs.assertFloat64(); ok1 { 1590 if v2, ok2 := rhs.assertFloat64(); ok2 { 1591 return numberArith(L, opcode, LNumber(v1), LNumber(v2)) 1592 } 1593 } 1594 L.RaiseError(fmt.Sprintf("cannot perform %v operation between %v and %v", 1595 strings.TrimLeft(event, "_"), lhs.Type().String(), rhs.Type().String())) 1596 1597 return LNil 1598 } 1599 1600 func stringConcat(L *LState, total, last int) LValue { 1601 rhs := L.reg.Get(last) 1602 total-- 1603 for i := last - 1; total > 0; { 1604 lhs := L.reg.Get(i) 1605 if !(LVCanConvToString(lhs) && LVCanConvToString(rhs)) { 1606 op := L.metaOp2(lhs, rhs, "__concat") 1607 if op.Type() == LTFunction { 1608 L.reg.Push(op) 1609 L.reg.Push(lhs) 1610 L.reg.Push(rhs) 1611 L.Call(2, 1) 1612 rhs = L.reg.Pop() 1613 total-- 1614 i-- 1615 } else { 1616 L.RaiseError("cannot perform concat operation between %v and %v", lhs.Type().String(), rhs.Type().String()) 1617 return LNil 1618 } 1619 } else { 1620 buf := make([]string, total+1) 1621 buf[total] = LVAsString(rhs) 1622 for total > 0 { 1623 lhs = L.reg.Get(i) 1624 if !LVCanConvToString(lhs) { 1625 break 1626 } 1627 buf[total-1] = LVAsString(lhs) 1628 i-- 1629 total-- 1630 } 1631 rhs = LString(strings.Join(buf, "")) 1632 } 1633 } 1634 return rhs 1635 } 1636 1637 func lessThan(L *LState, lhs, rhs LValue) bool { 1638 // optimization for numbers 1639 if v1, ok1 := lhs.assertFloat64(); ok1 { 1640 if v2, ok2 := rhs.assertFloat64(); ok2 { 1641 return v1 < v2 1642 } 1643 L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String()) 1644 } 1645 if lhs.Type() != rhs.Type() { 1646 L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String()) 1647 return false 1648 } 1649 ret := false 1650 switch lhs.Type() { 1651 case LTString: 1652 ret = strCmp(string(lhs.(LString)), string(rhs.(LString))) < 0 1653 default: 1654 ret = objectRationalWithError(L, lhs, rhs, "__lt") 1655 } 1656 return ret 1657 } 1658 1659 func equals(L *LState, lhs, rhs LValue, raw bool) bool { 1660 if lhs.Type() != rhs.Type() { 1661 return false 1662 } 1663 1664 ret := false 1665 switch lhs.Type() { 1666 case LTNil: 1667 ret = true 1668 case LTNumber: 1669 v1, _ := lhs.assertFloat64() 1670 v2, _ := rhs.assertFloat64() 1671 ret = v1 == v2 1672 case LTBool: 1673 ret = bool(lhs.(LBool)) == bool(rhs.(LBool)) 1674 case LTString: 1675 ret = string(lhs.(LString)) == string(rhs.(LString)) 1676 case LTUserData, LTTable: 1677 if lhs == rhs { 1678 ret = true 1679 } else if !raw { 1680 switch objectRational(L, lhs, rhs, "__eq") { 1681 case 1: 1682 ret = true 1683 default: 1684 ret = false 1685 } 1686 } 1687 default: 1688 ret = lhs == rhs 1689 } 1690 return ret 1691 } 1692 1693 func objectRationalWithError(L *LState, lhs, rhs LValue, event string) bool { 1694 switch objectRational(L, lhs, rhs, event) { 1695 case 1: 1696 return true 1697 case 0: 1698 return false 1699 } 1700 L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String()) 1701 return false 1702 } 1703 1704 func objectRational(L *LState, lhs, rhs LValue, event string) int { 1705 m1 := L.metaOp1(lhs, event) 1706 m2 := L.metaOp1(rhs, event) 1707 if m1.Type() == LTFunction && m1 == m2 { 1708 L.reg.Push(m1) 1709 L.reg.Push(lhs) 1710 L.reg.Push(rhs) 1711 L.Call(2, 1) 1712 if LVAsBool(L.reg.Pop()) { 1713 return 1 1714 } 1715 return 0 1716 } 1717 return -1 1718 }