(L *LState)
| 524 | var loopdetection = &LUserData{} |
| 525 | |
| 526 | func loRequire(L *LState) int { |
| 527 | name := L.CheckString(1) |
| 528 | loaded := L.GetField(L.Get(RegistryIndex), "_LOADED") |
| 529 | lv := L.GetField(loaded, name) |
| 530 | if LVAsBool(lv) { |
| 531 | if lv == loopdetection { |
| 532 | L.RaiseError("loop or previous error loading module: %s", name) |
| 533 | } |
| 534 | L.Push(lv) |
| 535 | return 1 |
| 536 | } |
| 537 | loaders, ok := L.GetField(L.Get(RegistryIndex), "_LOADERS").(*LTable) |
| 538 | if !ok { |
| 539 | L.RaiseError("package.loaders must be a table") |
| 540 | } |
| 541 | messages := []string{} |
| 542 | var modasfunc LValue |
| 543 | for i := 1; ; i++ { |
| 544 | loader := L.RawGetInt(loaders, i) |
| 545 | if loader == LNil { |
| 546 | L.RaiseError("module %s not found:\n\t%s, ", name, strings.Join(messages, "\n\t")) |
| 547 | } |
| 548 | L.Push(loader) |
| 549 | L.Push(LString(name)) |
| 550 | L.Call(1, 1) |
| 551 | ret := L.reg.Pop() |
| 552 | switch retv := ret.(type) { |
| 553 | case *LFunction: |
| 554 | modasfunc = retv |
| 555 | goto loopbreak |
| 556 | case LString: |
| 557 | messages = append(messages, string(retv)) |
| 558 | } |
| 559 | } |
| 560 | loopbreak: |
| 561 | L.SetField(loaded, name, loopdetection) |
| 562 | L.Push(modasfunc) |
| 563 | L.Push(LString(name)) |
| 564 | L.Call(1, 1) |
| 565 | ret := L.reg.Pop() |
| 566 | modv := L.GetField(loaded, name) |
| 567 | if ret != LNil && modv == loopdetection { |
| 568 | L.SetField(loaded, name, ret) |
| 569 | L.Push(ret) |
| 570 | } else if modv == loopdetection { |
| 571 | L.SetField(loaded, name, LTrue) |
| 572 | L.Push(LTrue) |
| 573 | } else { |
| 574 | L.Push(modv) |
| 575 | } |
| 576 | return 1 |
| 577 | } |
| 578 | |
| 579 | /* }}} */ |
| 580 |
nothing calls this directly
no test coverage detected
searching dependent graphs…