func ArgumentError(l *State, argCount int, extraMessage string) {
	f, ok := Stack(l, 0)
	if !ok {  
		Errorf(l, "bad argument #%d (%s)", argCount, extraMessage)
		return
	}
	d, _ := Info(l, "n", f)
	if d.NameKind == "method" {
		argCount--          
		if argCount == 0 {  
			Errorf(l, "calling '%s' on bad self (%s)", d.Name, extraMessage)
			return
		}
	}
	if d.Name == "" {
		if pushGlobalFunctionName(l, f) {
			d.Name, _ = l.ToString(-1)
		} else {
			d.Name = "?"
		}
	}
	Errorf(l, "bad argument #%d to '%s' (%s)", argCount, d.Name, extraMessage)
}
ArgumentError raises an error with a standard message that includes extraMessage as a comment.

This function never returns. It is an idiom to use it in Go functions as
lua.ArgumentError(l, args, "message")
panic("unreachable")
package lua
import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strings"
)
func functionName(l *State, d Debug) string {
	switch {
	case d.NameKind != "":
		return fmt.Sprintf("function '%s'", d.Name)
	case d.What == "main":
		return "main chunk"
	case d.What == "Go":
		if pushGlobalFunctionName(l, d.callInfo) {
			s, _ := l.ToString(-1)
			l.Pop(1)
			return fmt.Sprintf("function '%s'", s)
		} else {
			return "?"
		}
	}
	return fmt.Sprintf("function <%s:%d>", d.ShortSource, d.LineDefined)
}
func countLevels(l *State) int {
	li, le := 1, 1
	for _, ok := Stack(l, le); ok; _, ok = Stack(l, le) {
		li = le
		le *= 2
	}
	for li < le {
		m := (li + le) / 2
		if _, ok := Stack(l, m); ok {
			li = m + 1
		} else {
			le = m
		}
	}
	return le - 1
}
func Traceback(l, l1 *State, message string, level int) {
	const levels1, levels2 = 12, 10
	levels := countLevels(l1)
	mark := 0
	if levels > levels1+levels2 {
		mark = levels1
	}
	buf := message
	if buf != "" {
		buf += "\n"
	}
	buf += "stack traceback:"
	for f, ok := Stack(l1, level); ok; f, ok = Stack(l1, level) {
		if level++; level == mark {
			buf += "\n\t..."
			level = levels - levels2
		} else {
			d, _ := Info(l1, "Slnt", f)
			buf += "\n\t" + d.ShortSource + ":"
			if d.CurrentLine > 0 {
				buf += fmt.Sprintf("%d:", d.CurrentLine)
			}
			buf += " in " + functionName(l, d)
			if d.IsTailCall {
				buf += "\n\t(...tail calls...)"
			}
		}
	}
	l.PushString(buf)
}
func MetaField(l *State, index int, event string) bool {
	if !l.MetaTable(index) {
		return false
	}
	l.PushString(event)
	l.RawGet(-2)
	if l.IsNil(-1) {
		l.Pop(2)  
		return false
	}
	l.Remove(-2)  
	return true
}
func CallMeta(l *State, index int, event string) bool {
	index = l.AbsIndex(index)
	if !MetaField(l, index, event) {
		return false
	}
	l.PushValue(index)
	l.Call(1, 1)
	return true
}