Skip to content

Commit 1388221

Browse files
committed
Remove LValue.assert* functions.
GopherLua is a relatively old project. Old Go runtime had slow interface type assertions, but now Go runtime better its performance.
1 parent 1e3d646 commit 1388221

File tree

5 files changed

+57
-92
lines changed

5 files changed

+57
-92
lines changed

_vm.go

+20-20
Original file line numberDiff line numberDiff line change
@@ -495,8 +495,8 @@ func init() {
495495
rhs := L.rkValue(C)
496496
ret := false
497497

498-
if v1, ok1 := lhs.assertFloat64(); ok1 {
499-
if v2, ok2 := rhs.assertFloat64(); ok2 {
498+
if v1, ok1 := lhs.(LNumber); ok1 {
499+
if v2, ok2 := rhs.(LNumber); ok2 {
500500
ret = v1 <= v2
501501
} else {
502502
L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String())
@@ -572,7 +572,7 @@ func init() {
572572
nret := C - 1
573573
var callable *LFunction
574574
var meta bool
575-
if fn, ok := lv.assertFunction(); ok {
575+
if fn, ok := lv.(*LFunction); ok {
576576
callable = fn
577577
meta = false
578578
} else {
@@ -598,7 +598,7 @@ func init() {
598598
lv := reg.Get(RA)
599599
var callable *LFunction
600600
var meta bool
601-
if fn, ok := lv.assertFunction(); ok {
601+
if fn, ok := lv.(*LFunction); ok {
602602
callable = fn
603603
meta = false
604604
} else {
@@ -685,9 +685,9 @@ func init() {
685685
lbase := cf.LocalBase
686686
A := int(inst>>18) & 0xff //GETA
687687
RA := lbase + A
688-
if init, ok1 := reg.Get(RA).assertFloat64(); ok1 {
689-
if limit, ok2 := reg.Get(RA + 1).assertFloat64(); ok2 {
690-
if step, ok3 := reg.Get(RA + 2).assertFloat64(); ok3 {
688+
if init, ok1 := reg.Get(RA).(LNumber); ok1 {
689+
if limit, ok2 := reg.Get(RA + 1).(LNumber); ok2 {
690+
if step, ok3 := reg.Get(RA + 2).(LNumber); ok3 {
691691
init += step
692692
v := LNumber(init)
693693
// +inline-call reg.SetNumber RA v
@@ -716,8 +716,8 @@ func init() {
716716
A := int(inst>>18) & 0xff //GETA
717717
RA := lbase + A
718718
Sbx := int(inst&0x3ffff) - opMaxArgSbx //GETSBX
719-
if init, ok1 := reg.Get(RA).assertFloat64(); ok1 {
720-
if step, ok2 := reg.Get(RA + 2).assertFloat64(); ok2 {
719+
if init, ok1 := reg.Get(RA).(LNumber); ok1 {
720+
if step, ok2 := reg.Get(RA + 2).(LNumber); ok2 {
721721
// +inline-call reg.SetNumber RA LNumber(init-step)
722722
} else {
723723
L.RaiseError("for statement step must be a number")
@@ -839,8 +839,8 @@ func opArith(L *LState, inst uint32, baseframe *callFrame) int { //OP_ADD, OP_SU
839839
C := int(inst>>9) & 0x1ff //GETC
840840
lhs := L.rkValue(B)
841841
rhs := L.rkValue(C)
842-
v1, ok1 := lhs.assertFloat64()
843-
v2, ok2 := rhs.assertFloat64()
842+
v1, ok1 := lhs.(LNumber)
843+
v2, ok2 := rhs.(LNumber)
844844
if ok1 && ok2 {
845845
v := numberArith(L, opcode, LNumber(v1), LNumber(v2))
846846
// +inline-call reg.SetNumber RA v
@@ -899,25 +899,25 @@ func objectArith(L *LState, opcode int, lhs, rhs LValue) LValue {
899899
event = "__pow"
900900
}
901901
op := L.metaOp2(lhs, rhs, event)
902-
if _, ok := op.assertFunction(); ok {
902+
if _, ok := op.(*LFunction); ok {
903903
L.reg.Push(op)
904904
L.reg.Push(lhs)
905905
L.reg.Push(rhs)
906906
L.Call(2, 1)
907907
return L.reg.Pop()
908908
}
909-
if str, ok := lhs.assertString(); ok {
909+
if str, ok := lhs.(LString); ok {
910910
if lnum, err := parseNumber(string(str)); err == nil {
911911
lhs = lnum
912912
}
913913
}
914-
if str, ok := rhs.assertString(); ok {
914+
if str, ok := rhs.(LString); ok {
915915
if rnum, err := parseNumber(string(str)); err == nil {
916916
rhs = rnum
917917
}
918918
}
919-
if v1, ok1 := lhs.assertFloat64(); ok1 {
920-
if v2, ok2 := rhs.assertFloat64(); ok2 {
919+
if v1, ok1 := lhs.(LNumber); ok1 {
920+
if v2, ok2 := rhs.(LNumber); ok2 {
921921
return numberArith(L, opcode, LNumber(v1), LNumber(v2))
922922
}
923923
}
@@ -966,8 +966,8 @@ func stringConcat(L *LState, total, last int) LValue {
966966

967967
func lessThan(L *LState, lhs, rhs LValue) bool {
968968
// optimization for numbers
969-
if v1, ok1 := lhs.assertFloat64(); ok1 {
970-
if v2, ok2 := rhs.assertFloat64(); ok2 {
969+
if v1, ok1 := lhs.(LNumber); ok1 {
970+
if v2, ok2 := rhs.(LNumber); ok2 {
971971
return v1 < v2
972972
}
973973
L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String())
@@ -997,8 +997,8 @@ func equals(L *LState, lhs, rhs LValue, raw bool) bool {
997997
case LTNil:
998998
ret = true
999999
case LTNumber:
1000-
v1, _ := lhs.assertFloat64()
1001-
v2, _ := rhs.assertFloat64()
1000+
v1, _ := lhs.(LNumber)
1001+
v2, _ := rhs.(LNumber)
10021002
ret = v1 == v2
10031003
case LTBool:
10041004
ret = bool(lhs.(LBool)) == bool(rhs.(LBool))

auxlib.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ func (ls *LState) DoString(source string) error {
418418
// ToStringMeta returns string representation of given LValue.
419419
// This method calls the `__tostring` meta method if defined.
420420
func (ls *LState) ToStringMeta(lv LValue) LValue {
421-
if fn, ok := ls.metaOp1(lv, "__tostring").assertFunction(); ok {
421+
if fn, ok := ls.metaOp1(lv, "__tostring").(*LFunction); ok {
422422
ls.Push(fn)
423423
ls.Push(lv)
424424
ls.Call(1, 1)

debuglib.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,8 @@ func debugTraceback(L *LState) int {
155155
level := L.OptInt(2, 1)
156156
ls := L
157157
if L.GetTop() > 0 {
158-
if s, ok := L.Get(1).assertString(); ok {
159-
msg = s
158+
if s, ok := L.Get(1).(LString); ok {
159+
msg = string(s)
160160
}
161161
if l, ok := L.Get(1).(*LState); ok {
162162
ls = l

value.go

+16-49
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,6 @@ func (vt LValueType) String() string {
2929
type LValue interface {
3030
String() string
3131
Type() LValueType
32-
// to reduce `runtime.assertI2T2` costs, this method should be used instead of the type assertion in heavy paths(typically inside the VM).
33-
assertFloat64() (float64, bool)
34-
// to reduce `runtime.assertI2T2` costs, this method should be used instead of the type assertion in heavy paths(typically inside the VM).
35-
assertString() (string, bool)
36-
// to reduce `runtime.assertI2T2` costs, this method should be used instead of the type assertion in heavy paths(typically inside the VM).
37-
assertFunction() (*LFunction, bool)
3832
}
3933

4034
// LVIsFalse returns true if a given LValue is a nil or false otherwise false.
@@ -80,11 +74,8 @@ func LVAsNumber(v LValue) LNumber {
8074

8175
type LNilType struct{}
8276

83-
func (nl *LNilType) String() string { return "nil" }
84-
func (nl *LNilType) Type() LValueType { return LTNil }
85-
func (nl *LNilType) assertFloat64() (float64, bool) { return 0, false }
86-
func (nl *LNilType) assertString() (string, bool) { return "", false }
87-
func (nl *LNilType) assertFunction() (*LFunction, bool) { return nil, false }
77+
func (nl *LNilType) String() string { return "nil" }
78+
func (nl *LNilType) Type() LValueType { return LTNil }
8879

8980
var LNil = LValue(&LNilType{})
9081

@@ -96,21 +87,15 @@ func (bl LBool) String() string {
9687
}
9788
return "false"
9889
}
99-
func (bl LBool) Type() LValueType { return LTBool }
100-
func (bl LBool) assertFloat64() (float64, bool) { return 0, false }
101-
func (bl LBool) assertString() (string, bool) { return "", false }
102-
func (bl LBool) assertFunction() (*LFunction, bool) { return nil, false }
90+
func (bl LBool) Type() LValueType { return LTBool }
10391

10492
var LTrue = LBool(true)
10593
var LFalse = LBool(false)
10694

10795
type LString string
10896

109-
func (st LString) String() string { return string(st) }
110-
func (st LString) Type() LValueType { return LTString }
111-
func (st LString) assertFloat64() (float64, bool) { return 0, false }
112-
func (st LString) assertString() (string, bool) { return string(st), true }
113-
func (st LString) assertFunction() (*LFunction, bool) { return nil, false }
97+
func (st LString) String() string { return string(st) }
98+
func (st LString) Type() LValueType { return LTString }
11499

115100
// fmt.Formatter interface
116101
func (st LString) Format(f fmt.State, c rune) {
@@ -133,10 +118,7 @@ func (nm LNumber) String() string {
133118
return fmt.Sprint(float64(nm))
134119
}
135120

136-
func (nm LNumber) Type() LValueType { return LTNumber }
137-
func (nm LNumber) assertFloat64() (float64, bool) { return float64(nm), true }
138-
func (nm LNumber) assertString() (string, bool) { return "", false }
139-
func (nm LNumber) assertFunction() (*LFunction, bool) { return nil, false }
121+
func (nm LNumber) Type() LValueType { return LTNumber }
140122

141123
// fmt.Formatter interface
142124
func (nm LNumber) Format(f fmt.State, c rune) {
@@ -168,11 +150,8 @@ type LTable struct {
168150
k2i map[LValue]int
169151
}
170152

171-
func (tb *LTable) String() string { return fmt.Sprintf("table: %p", tb) }
172-
func (tb *LTable) Type() LValueType { return LTTable }
173-
func (tb *LTable) assertFloat64() (float64, bool) { return 0, false }
174-
func (tb *LTable) assertString() (string, bool) { return "", false }
175-
func (tb *LTable) assertFunction() (*LFunction, bool) { return nil, false }
153+
func (tb *LTable) String() string { return fmt.Sprintf("table: %p", tb) }
154+
func (tb *LTable) Type() LValueType { return LTTable }
176155

177156
type LFunction struct {
178157
IsG bool
@@ -183,11 +162,8 @@ type LFunction struct {
183162
}
184163
type LGFunction func(*LState) int
185164

186-
func (fn *LFunction) String() string { return fmt.Sprintf("function: %p", fn) }
187-
func (fn *LFunction) Type() LValueType { return LTFunction }
188-
func (fn *LFunction) assertFloat64() (float64, bool) { return 0, false }
189-
func (fn *LFunction) assertString() (string, bool) { return "", false }
190-
func (fn *LFunction) assertFunction() (*LFunction, bool) { return fn, true }
165+
func (fn *LFunction) String() string { return fmt.Sprintf("function: %p", fn) }
166+
func (fn *LFunction) Type() LValueType { return LTFunction }
191167

192168
type Global struct {
193169
MainThread *LState
@@ -221,28 +197,19 @@ type LState struct {
221197
ctxCancelFn context.CancelFunc
222198
}
223199

224-
func (ls *LState) String() string { return fmt.Sprintf("thread: %p", ls) }
225-
func (ls *LState) Type() LValueType { return LTThread }
226-
func (ls *LState) assertFloat64() (float64, bool) { return 0, false }
227-
func (ls *LState) assertString() (string, bool) { return "", false }
228-
func (ls *LState) assertFunction() (*LFunction, bool) { return nil, false }
200+
func (ls *LState) String() string { return fmt.Sprintf("thread: %p", ls) }
201+
func (ls *LState) Type() LValueType { return LTThread }
229202

230203
type LUserData struct {
231204
Value interface{}
232205
Env *LTable
233206
Metatable LValue
234207
}
235208

236-
func (ud *LUserData) String() string { return fmt.Sprintf("userdata: %p", ud) }
237-
func (ud *LUserData) Type() LValueType { return LTUserData }
238-
func (ud *LUserData) assertFloat64() (float64, bool) { return 0, false }
239-
func (ud *LUserData) assertString() (string, bool) { return "", false }
240-
func (ud *LUserData) assertFunction() (*LFunction, bool) { return nil, false }
209+
func (ud *LUserData) String() string { return fmt.Sprintf("userdata: %p", ud) }
210+
func (ud *LUserData) Type() LValueType { return LTUserData }
241211

242212
type LChannel chan LValue
243213

244-
func (ch LChannel) String() string { return fmt.Sprintf("channel: %p", ch) }
245-
func (ch LChannel) Type() LValueType { return LTChannel }
246-
func (ch LChannel) assertFloat64() (float64, bool) { return 0, false }
247-
func (ch LChannel) assertString() (string, bool) { return "", false }
248-
func (ch LChannel) assertFunction() (*LFunction, bool) { return nil, false }
214+
func (ch LChannel) String() string { return fmt.Sprintf("channel: %p", ch) }
215+
func (ch LChannel) Type() LValueType { return LTChannel }

vm.go

+18-20
Original file line numberDiff line numberDiff line change
@@ -1085,8 +1085,8 @@ func init() {
10851085
rhs := L.rkValue(C)
10861086
ret := false
10871087

1088-
if v1, ok1 := lhs.assertFloat64(); ok1 {
1089-
if v2, ok2 := rhs.assertFloat64(); ok2 {
1088+
if v1, ok1 := lhs.(LNumber); ok1 {
1089+
if v2, ok2 := rhs.(LNumber); ok2 {
10901090
ret = v1 <= v2
10911091
} else {
10921092
L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String())
@@ -1181,7 +1181,7 @@ func init() {
11811181
nret := C - 1
11821182
var callable *LFunction
11831183
var meta bool
1184-
if fn, ok := lv.assertFunction(); ok {
1184+
if fn, ok := lv.(*LFunction); ok {
11851185
callable = fn
11861186
meta = false
11871187
} else {
@@ -1324,7 +1324,7 @@ func init() {
13241324
lv := reg.Get(RA)
13251325
var callable *LFunction
13261326
var meta bool
1327-
if fn, ok := lv.assertFunction(); ok {
1327+
if fn, ok := lv.(*LFunction); ok {
13281328
callable = fn
13291329
meta = false
13301330
} else {
@@ -1795,9 +1795,9 @@ func init() {
17951795
lbase := cf.LocalBase
17961796
A := int(inst>>18) & 0xff //GETA
17971797
RA := lbase + A
1798-
if init, ok1 := reg.Get(RA).assertFloat64(); ok1 {
1799-
if limit, ok2 := reg.Get(RA + 1).assertFloat64(); ok2 {
1800-
if step, ok3 := reg.Get(RA + 2).assertFloat64(); ok3 {
1798+
if init, ok1 := reg.Get(RA).(LNumber); ok1 {
1799+
if limit, ok2 := reg.Get(RA + 1).(LNumber); ok2 {
1800+
if step, ok3 := reg.Get(RA + 2).(LNumber); ok3 {
18011801
init += step
18021802
v := LNumber(init)
18031803
// this section is inlined by go-inline
@@ -1893,8 +1893,8 @@ func init() {
18931893
A := int(inst>>18) & 0xff //GETA
18941894
RA := lbase + A
18951895
Sbx := int(inst&0x3ffff) - opMaxArgSbx //GETSBX
1896-
if init, ok1 := reg.Get(RA).assertFloat64(); ok1 {
1897-
if step, ok2 := reg.Get(RA + 2).assertFloat64(); ok2 {
1896+
if init, ok1 := reg.Get(RA).(LNumber); ok1 {
1897+
if step, ok2 := reg.Get(RA + 2).(LNumber); ok2 {
18981898
// this section is inlined by go-inline
18991899
// source function is 'func (rg *registry) SetNumber(regi int, vali LNumber) ' in '_state.go'
19001900
{
@@ -2217,8 +2217,6 @@ func opArith(L *LState, inst uint32, baseframe *callFrame) int { //OP_ADD, OP_SU
22172217
C := int(inst>>9) & 0x1ff //GETC
22182218
lhs := L.rkValue(B)
22192219
rhs := L.rkValue(C)
2220-
// v1, ok1 := lhs.assertFloat64()
2221-
// v2, ok2 := rhs.assertFloat64()
22222220
v1, ok1 := lhs.(LNumber)
22232221
v2, ok2 := rhs.(LNumber)
22242222
if ok1 && ok2 {
@@ -2317,25 +2315,25 @@ func objectArith(L *LState, opcode int, lhs, rhs LValue) LValue {
23172315
event = "__pow"
23182316
}
23192317
op := L.metaOp2(lhs, rhs, event)
2320-
if _, ok := op.assertFunction(); ok {
2318+
if _, ok := op.(*LFunction); ok {
23212319
L.reg.Push(op)
23222320
L.reg.Push(lhs)
23232321
L.reg.Push(rhs)
23242322
L.Call(2, 1)
23252323
return L.reg.Pop()
23262324
}
2327-
if str, ok := lhs.assertString(); ok {
2325+
if str, ok := lhs.(LString); ok {
23282326
if lnum, err := parseNumber(string(str)); err == nil {
23292327
lhs = lnum
23302328
}
23312329
}
2332-
if str, ok := rhs.assertString(); ok {
2330+
if str, ok := rhs.(LString); ok {
23332331
if rnum, err := parseNumber(string(str)); err == nil {
23342332
rhs = rnum
23352333
}
23362334
}
2337-
if v1, ok1 := lhs.assertFloat64(); ok1 {
2338-
if v2, ok2 := rhs.assertFloat64(); ok2 {
2335+
if v1, ok1 := lhs.(LNumber); ok1 {
2336+
if v2, ok2 := rhs.(LNumber); ok2 {
23392337
return numberArith(L, opcode, LNumber(v1), LNumber(v2))
23402338
}
23412339
}
@@ -2384,8 +2382,8 @@ func stringConcat(L *LState, total, last int) LValue {
23842382

23852383
func lessThan(L *LState, lhs, rhs LValue) bool {
23862384
// optimization for numbers
2387-
if v1, ok1 := lhs.assertFloat64(); ok1 {
2388-
if v2, ok2 := rhs.assertFloat64(); ok2 {
2385+
if v1, ok1 := lhs.(LNumber); ok1 {
2386+
if v2, ok2 := rhs.(LNumber); ok2 {
23892387
return v1 < v2
23902388
}
23912389
L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String())
@@ -2415,8 +2413,8 @@ func equals(L *LState, lhs, rhs LValue, raw bool) bool {
24152413
case LTNil:
24162414
ret = true
24172415
case LTNumber:
2418-
v1, _ := lhs.assertFloat64()
2419-
v2, _ := rhs.assertFloat64()
2416+
v1, _ := lhs.(LNumber)
2417+
v2, _ := rhs.(LNumber)
24202418
ret = v1 == v2
24212419
case LTBool:
24222420
ret = bool(lhs.(LBool)) == bool(rhs.(LBool))

0 commit comments

Comments
 (0)