Skip to content

Commit

Permalink
add GETTABLEKS, SETTABLEKS opecodes
Browse files Browse the repository at this point in the history
  • Loading branch information
yuin committed May 15, 2015
1 parent 55dbb60 commit b3cc50f
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 9 deletions.
20 changes: 18 additions & 2 deletions compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,7 @@ func compileAssignStmt(context *funcContext, stmt *ast.AssignStmt) { // {{{
code.AddABC(OP_SETUPVAL, reg, context.Upvalues.RegisterUnique(ex.(*ast.IdentExpr).Value), 0, sline(ex))
reg -= 1
case ecTable:
// TODO: OP_SETTABLEKS
code.AddABC(OP_SETTABLE, acs[i].ec.reg, acs[i].keyrk, acs[i].valuerk, sline(ex))
if !opIsK(acs[i].valuerk) {
reg -= 1
Expand Down Expand Up @@ -988,7 +989,11 @@ func compileExpr(context *funcContext, reg int, expr ast.Expr, ec *expcontext) i
compileExprWithMVPropagation(context, ex.Object, &reg, &b)
c := reg
compileExprWithKMVPropagation(context, ex.Key, &reg, &c)
code.AddABC(OP_GETTABLE, a, b, c, sline(ex))
opcode := OP_GETTABLE
if _, ok := ex.Key.(*ast.StringExpr); ok {
opcode = OP_GETTABLEKS
}
code.AddABC(opcode, a, b, c, sline(ex))
return sused
case *ast.TableExpr:
compileTableExpr(context, reg, ex, ec)
Expand Down Expand Up @@ -1129,6 +1134,13 @@ func compileFunctionExpr(context *funcContext, funcexpr *ast.FunctionExpr, ec *e
context.Proto.DbgSourcePositions = context.Code.PosList()
context.Proto.DbgUpvalues = context.Upvalues.Names()
context.Proto.NumUpvalues = uint8(len(context.Proto.DbgUpvalues))
for _, clv := range context.Proto.Constants {
sv := ""
if slv, ok := clv.(LString); ok {
sv = string(slv)
}
context.Proto.stringConstants = append(context.Proto.stringConstants, sv)
}
patchCode(context)
} // }}}

Expand Down Expand Up @@ -1164,7 +1176,11 @@ func compileTableExpr(context *funcContext, reg int, ex *ast.TableExpr, ec *expc
compileExprWithKMVPropagation(context, field.Key, &reg, &b)
c := reg
compileExprWithKMVPropagation(context, field.Value, &reg, &c)
code.AddABC(OP_SETTABLE, tablereg, b, c, sline(ex))
opcode := OP_SETTABLE
if _, ok := field.Key.(*ast.StringExpr); ok {
opcode = OP_SETTABLEKS
}
code.AddABC(opcode, tablereg, b, c, sline(ex))
reg = regorg
}
flush := arraycount % FieldsPerFlush
Expand Down
4 changes: 4 additions & 0 deletions function.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ type FunctionProto struct {
DbgLocals []*DbgLocalInfo
DbgCalls []DbgCall
DbgUpvalues []string

stringConstants []string
}

/* Upvalue {{{ */
Expand Down Expand Up @@ -102,6 +104,8 @@ func newFunctionProto(name string) *FunctionProto {
DbgLocals: make([]*DbgLocalInfo, 0, 16),
DbgCalls: make([]DbgCall, 0, 128),
DbgUpvalues: make([]string, 0, 16),

stringConstants: make([]string, 0, 32),
}
}

Expand Down
18 changes: 13 additions & 5 deletions opcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,14 @@ const (
OP_LOADNIL /* A B R(A) := ... := R(B) := nil */
OP_GETUPVAL /* A B R(A) := UpValue[B] */

OP_GETGLOBAL /* A Bx R(A) := Gbl[Kst(Bx)] */
OP_GETTABLE /* A B C R(A) := R(B)[RK(C)] */
OP_GETGLOBAL /* A Bx R(A) := Gbl[Kst(Bx)] */
OP_GETTABLE /* A B C R(A) := R(B)[RK(C)] */
OP_GETTABLEKS /* A B C R(A) := R(B)[RK(C)] ; RK(C) is constant string */

OP_SETGLOBAL /* A Bx Gbl[Kst(Bx)] := R(A) */
OP_SETUPVAL /* A B UpValue[B] := R(A) */
OP_SETTABLE /* A B C R(A)[RK(B)] := RK(C) */
OP_SETGLOBAL /* A Bx Gbl[Kst(Bx)] := R(A) */
OP_SETUPVAL /* A B UpValue[B] := R(A) */
OP_SETTABLE /* A B C R(A)[RK(B)] := RK(C) */
OP_SETTABLEKS /* A B C R(A)[RK(B)] := RK(C) ; RK(B) is constant string */

OP_NEWTABLE /* A B C R(A) := {} (size = BC) */

Expand Down Expand Up @@ -130,9 +132,11 @@ var opProps = []opProp{
opProp{"GETUPVAL", false, true, opArgModeU, opArgModeN, opTypeABC},
opProp{"GETGLOBAL", false, true, opArgModeK, opArgModeN, opTypeABx},
opProp{"GETTABLE", false, true, opArgModeR, opArgModeK, opTypeABC},
opProp{"GETTABLEKS", false, true, opArgModeR, opArgModeK, opTypeABC},
opProp{"SETGLOBAL", false, false, opArgModeK, opArgModeN, opTypeABx},
opProp{"SETUPVAL", false, false, opArgModeU, opArgModeN, opTypeABC},
opProp{"SETTABLE", false, false, opArgModeK, opArgModeK, opTypeABC},
opProp{"SETTABLEKS", false, false, opArgModeK, opArgModeK, opTypeABC},
opProp{"NEWTABLE", false, true, opArgModeU, opArgModeU, opTypeABC},
opProp{"SELF", false, true, opArgModeR, opArgModeK, opTypeABC},
opProp{"ADD", false, true, opArgModeK, opArgModeK, opTypeABC},
Expand Down Expand Up @@ -290,12 +294,16 @@ func opToString(inst uint32) string {
buf += fmt.Sprintf("; R(%v) := Gbl[Kst(%v)]", arga, argbx)
case OP_GETTABLE:
buf += fmt.Sprintf("; R(%v) := R(%v)[RK(%v)]", arga, argb, argc)
case OP_GETTABLEKS:
buf += fmt.Sprintf("; R(%v) := R(%v)[RK(%v)] ; RK(%v) is constant string", arga, argb, argc, argc)
case OP_SETGLOBAL:
buf += fmt.Sprintf("; Gbl[Kst(%v)] := R(%v)", argbx, arga)
case OP_SETUPVAL:
buf += fmt.Sprintf("; UpValue[%v] := R(%v)", argb, arga)
case OP_SETTABLE:
buf += fmt.Sprintf("; R(%v)[RK(%v)] := RK(%v)", arga, argb, argc)
case OP_SETTABLEKS:
buf += fmt.Sprintf("; R(%v)[RK(%v)] := RK(%v) ; RK(%v) is constant string", arga, argb, argc, argb)
case OP_NEWTABLE:
buf += fmt.Sprintf("; R(%v) := {} (size = BC)", arga)
case OP_SELF:
Expand Down
7 changes: 7 additions & 0 deletions state.go
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,13 @@ func (ls *LState) rkValue(idx int) LValue {
return ls.reg.array[ls.currentFrame.LocalBase+idx]
}

func (ls *LState) rkString(idx int) string {
if (idx & opBitRk) != 0 {
return ls.currentFrame.Fn.Proto.stringConstants[idx & ^opBitRk]
}
return string(ls.reg.array[ls.currentFrame.LocalBase+idx].(LString))
}

func (ls *LState) closeUpvalues(idx int) {
if ls.uvcache == nil {
return
Expand Down
28 changes: 26 additions & 2 deletions vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ func init() {
A := int(inst>>18) & 0xff //GETA
RA := lbase + A
Bx := int(inst & 0x3ffff) //GETBX
reg.Set(RA, L.getField(cf.Fn.Env, cf.Fn.Proto.Constants[Bx]))
//reg.Set(RA, L.getField(cf.Fn.Env, cf.Fn.Proto.Constants[Bx]))
reg.Set(RA, L.getFieldString(cf.Fn.Env, cf.Fn.Proto.stringConstants[Bx]))
return 0
},
func(L *LState, inst uint32, baseframe *callFrame) int { //OP_GETTABLE
Expand All @@ -208,14 +209,26 @@ func init() {
reg.Set(RA, L.getField(reg.Get(lbase+B), L.rkValue(C)))
return 0
},
func(L *LState, inst uint32, baseframe *callFrame) int { //OP_GETTABLEKS
reg := L.reg
cf := L.currentFrame
lbase := cf.LocalBase
A := int(inst>>18) & 0xff //GETA
RA := lbase + A
B := int(inst & 0x1ff) //GETB
C := int(inst>>9) & 0x1ff //GETC
reg.Set(RA, L.getFieldString(reg.Get(lbase+B), L.rkString(C)))
return 0
},
func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SETGLOBAL
reg := L.reg
cf := L.currentFrame
lbase := cf.LocalBase
A := int(inst>>18) & 0xff //GETA
RA := lbase + A
Bx := int(inst & 0x3ffff) //GETBX
L.setField(cf.Fn.Env, cf.Fn.Proto.Constants[Bx], reg.Get(RA))
//L.setField(cf.Fn.Env, cf.Fn.Proto.Constants[Bx], reg.Get(RA))
L.setFieldString(cf.Fn.Env, cf.Fn.Proto.stringConstants[Bx], reg.Get(RA))
return 0
},
func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SETUPVAL
Expand All @@ -239,6 +252,17 @@ func init() {
L.setField(reg.Get(RA), L.rkValue(B), L.rkValue(C))
return 0
},
func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SETTABLEKS
reg := L.reg
cf := L.currentFrame
lbase := cf.LocalBase
A := int(inst>>18) & 0xff //GETA
RA := lbase + A
B := int(inst & 0x1ff) //GETB
C := int(inst>>9) & 0x1ff //GETC
L.setFieldString(reg.Get(RA), L.rkString(B), L.rkValue(C))
return 0
},
func(L *LState, inst uint32, baseframe *callFrame) int { //OP_NEWTABLE
reg := L.reg
cf := L.currentFrame
Expand Down

0 comments on commit b3cc50f

Please sign in to comment.