func (l *State) SetField(index int, key string) {
	l.checkElementCount(1)
	t := l.indexToValue(index)
	l.push(key)
	l.setTableAt(t, key, l.stack[l.top-2])
	l.top -= 2
}
SetField does the equivalent of table[key]=v where table is the value at
index and v is the value on top of the stack.

This function pops the value from the stack. As in Lua, this function may
trigger a metamethod for the __newindex event.

http://www.lua.org/manual/5.2/manual.html#lua_setfield
package lua
import (
	"errors"
	"fmt"
	"io"
	"math"
	"strings"
)
const MultipleReturns = -1
const (
	HookCall, MaskCall = iota, 1 << iota
	HookReturn, MaskReturn
	HookLine, MaskLine
	HookCount, MaskCount
	HookTailCall, MaskTailCall
)
var (
	SyntaxError = errors.New("syntax error")
	MemoryError = errors.New("memory error")
	ErrorError  = errors.New("error within the error handler")
	FileError   = errors.New("file error")
)
type RuntimeError string
func (r RuntimeError) Error() string { return "runtime error: " + string(r) }
type Type int
const (
	TypeNil Type = iota
	TypeBoolean
	TypeLightUserData
	TypeNumber
	TypeString
	TypeTable
	TypeFunction
	TypeUserData
	TypeThread
	TypeCount
	TypeNone = TypeNil - 1
)
type Operator int
const (
	OpAdd        Operator = iota  
	OpSub                         
	OpMul                         
	OpDiv                         
	OpMod                         
	OpPow                         
	OpUnaryMinus                  
)
type ComparisonOperator int
const (
	OpEq ComparisonOperator = iota  
	OpLT                            
	OpLE                            
)
const (
	RegistryIndex = firstPseudoIndex
	RegistryIndexMainThread = iota
	RegistryIndexGlobals
)
const Signature = "\033Lua"
const MinStack = 20
const (
	VersionMajor  = 5
	VersionMinor  = 2
	VersionNumber = 502
	VersionString = "Lua " + string('0'+VersionMajor) + "." + string('0'+VersionMinor)
)
type RegistryFunction struct {
	Name     string
	Function Function
}
type Debug struct {
	Event int
	Name string
	NameKind string
	What string
	Source string
	ShortSource string
	CurrentLine int
	LineDefined int
	LastLineDefined int
	UpValueCount int
	ParameterCount int
	IsVarArg bool
	IsTailCall bool
	callInfo *callInfo
}
type Hook func(state *State, activationRecord Debug)
type Function func(state *State) int
type pc int
type callStatus byte
const (
	callStatusLua                callStatus = 1 << iota  
	callStatusHooked                                     
	callStatusReentry                                    
	callStatusYielded                                    
	callStatusYieldableProtected                         
	callStatusError                                      
	callStatusTail                                       
	callStatusHookYielded                                
)
type State struct {
	error                 error
	shouldYield           bool
	top                   int  
	global                *globalState
	callInfo              *callInfo  
	oldPC                 pc         
	stackLast             int        
	stack                 []value
	nonYieldableCallCount int
	nestedGoCallCount     int
	hookMask              byte
	allowHook             bool
	internalHook          bool
	baseHookCount         int
	hookCount             int
	hooker                Hook
	upValues              *openUpValue
	errorFunction         int       
	baseCallInfo          callInfo  
	protectFunction       func()
}
type globalState struct {
	mainThread         *State
	tagMethodNames     [tmCount]string
	metaTables         [TypeCount]*table  
	registry           *table
	panicFunction      Function  
	version            *float64  
	memoryErrorMessage string
}
func (g *globalState) metaTable(o value) *table {
	var t Type
	switch o.(type) {
	case nil:
		t = TypeNil
	case bool:
		t = TypeBoolean
	case float64:
		t = TypeNumber
	case string:
		t = TypeString
	case *table:
		t = TypeTable
	case *goFunction:
		t = TypeFunction
	case closure:
		t = TypeFunction
	case *userData:
		t = TypeUserData
	case *State:
		t = TypeThread
	default:
		return nil
	}
	return g.metaTables[t]
}
func (l *State) adjustResults(resultCount int) {
	if resultCount == MultipleReturns && l.callInfo.top < l.top {
		l.callInfo.setTop(l.top)
	}
}
func (l *State) apiIncrementTop() {
	l.top++
	if apiCheck && l.top > l.callInfo.top {
		panic("stack overflow")
	}
}
func (l *State) apiPush(v value) {
	l.push(v)
	if apiCheck && l.top > l.callInfo.top {
		panic("stack overflow")
	}
}
func (l *State) checkElementCount(n int) {
	if apiCheck && n >= l.top-l.callInfo.function {
		panic("not enough elements in the stack")
	}
}
func (l *State) checkResults(argCount, resultCount int) {
	if apiCheck && resultCount != MultipleReturns && l.callInfo.top-l.top < resultCount-argCount {
		panic("results from function overflow current stack size")
	}
}
func (l *State) Context() (int, bool, error) {
	if l.callInfo.isCallStatus(callStatusYielded) {
		return l.callInfo.context, l.callInfo.shouldYield, l.callInfo.error
	}
	return 0, false, nil
}
func (l *State) CallWithContinuation(argCount, resultCount, context int, continuation Function) {
	if apiCheck && continuation != nil && l.callInfo.isLua() {
		panic("cannot use continuations inside hooks")
	}
	l.checkElementCount(argCount + 1)
	if apiCheck && l.shouldYield {
		panic("cannot do calls on non-normal thread")
	}
	l.checkResults(argCount, resultCount)
	f := l.top - (argCount + 1)
	if continuation != nil && l.nonYieldableCallCount == 0 {  
		l.callInfo.continuation = continuation
		l.callInfo.context = context
		l.call(f, resultCount, true)  
	} else {  
		l.call(f, resultCount, false)  
	}
	l.adjustResults(resultCount)
}
func (l *State) ProtectedCall(argCount, resultCount, errorFunction int) error {
	return l.ProtectedCallWithContinuation(argCount, resultCount, errorFunction, 0, nil)
}
func (l *State) ProtectedCallWithContinuation(argCount, resultCount, errorFunction, context int, continuation Function) (err error) {
	if apiCheck && continuation != nil && l.callInfo.isLua() {
		panic("cannot use continuations inside hooks")
	}
	l.checkElementCount(argCount + 1)
	if apiCheck && l.shouldYield {
		panic("cannot do calls on non-normal thread")
	}
	l.checkResults(argCount, resultCount)
	if errorFunction != 0 {
		apiCheckStackIndex(errorFunction, l.indexToValue(errorFunction))
		errorFunction = l.AbsIndex(errorFunction)
	}
	f := l.top - (argCount + 1)
	if continuation == nil || l.nonYieldableCallCount > 0 {
		err = l.protectedCall(func() { l.call(f, resultCount, false) }, f, errorFunction)
	} else {
		c := l.callInfo
		c.continuation, c.context, c.extra, c.oldAllowHook, c.oldErrorFunction = continuation, context, f, l.allowHook, l.errorFunction
		l.errorFunction = errorFunction
		l.callInfo.setCallStatus(callStatusYieldableProtected)
		l.call(f, resultCount, true)
		l.callInfo.clearCallStatus(callStatusYieldableProtected)
		l.errorFunction = c.oldErrorFunction
	}
	l.adjustResults(resultCount)
	return
}
func (l *State) Load(r io.Reader, chunkName string, mode string) error {
	if chunkName == "" {
		chunkName = "?"
	}
	if err := protectedParser(l, r, chunkName, mode); err != nil {
		return err
	}
	if f := l.stack[l.top-1].(*luaClosure); f.upValueCount() == 1 {
		f.setUpValue(0, l.global.registry.atInt(RegistryIndexGlobals))
	}
	return nil
}
func NewState() *State {
	v := float64(VersionNumber)
	l := &State{allowHook: true, error: nil, nonYieldableCallCount: 1}
	g := &globalState{mainThread: l, registry: newTable(), version: &v, memoryErrorMessage: "not enough memory"}
	l.global = g
	l.initializeStack()
	g.registry.putAtInt(RegistryIndexMainThread, l)
	g.registry.putAtInt(RegistryIndexGlobals, newTable())
	copy(g.tagMethodNames[:], eventNames)
	return l
}
func apiCheckStackIndex(index int, v value) {
	if apiCheck && (v == none || isPseudoIndex(index)) {
		panic(fmt.Sprintf("index %d not in the stack", index))
	}
}