Repository: goplus/gop
Pull request #432 (2020-07-10 05:52:33)

builtin delete: use GoBuiltin instead of new instr


Patch:
diff --git a/cl/goinstr.go b/cl/goinstr.go
index 6262b467..a0053c80 100644
--- a/cl/goinstr.go
+++ b/cl/goinstr.go
@@ -128,7 +128,7 @@ func igoCopy(ctx *blockCtx, v *ast.CallExpr) func() {
 			log.Panicln("second argument to copy should be slice or string; have", srcTy.Kind())
 		}
 		ctx.infer.Pop()
-		ctx.out.GoBuiltin(nil, exec.GobCopy)
+		ctx.out.GoBuiltin(dstTy, exec.GobCopy)
 	}
 }
 
@@ -155,7 +155,7 @@ func igoDelete(ctx *blockCtx, v *ast.CallExpr) func() {
 		elem := mapType.Key()
 		checkType(elem, args[0], ctx.out)
 		ctx.infer.PopN(n1)
-		ctx.out.Delete()
+		ctx.out.GoBuiltin(mapType, exec.GobDelete)
 	}
 }
 
diff --git a/exec.spec/interface.go b/exec.spec/interface.go
index f9b45aeb..ab42c12f 100644
--- a/exec.spec/interface.go
+++ b/exec.spec/interface.go
@@ -304,9 +304,6 @@ type Builder interface {
 	// SetMapIndex instr
 	SetMapIndex() Builder
 
-	// Delete instr
-	Delete() Builder
-
 	// Index instr
 	Index(idx int) Builder
 
diff --git a/exec/bytecode/code.go b/exec/bytecode/code.go
index 5ddadc14..a994f19f 100644
--- a/exec/bytecode/code.go
+++ b/exec/bytecode/code.go
@@ -110,7 +110,7 @@ const (
 	opTypeCast      = 37 // type(26)
 	opSlice         = 38 // i(13) j(13)
 	opSlice3        = 39 // i(13) j(13)
-	opMapIndex      = 40 // reserved(24) set(2)
+	opMapIndex      = 40 // reserved(25) set(1)
 	opGoBuiltin     = 41 // op(26)
 	opErrWrap       = 42 // idx(26)
 	opWrapIfErr     = 43 // reserved(2) offset(24)
@@ -192,7 +192,7 @@ var instrInfos = []InstrInfo{
 	opTypeCast:      {"typeCast", "", "type", 26},                         // type(26)
 	opSlice:         {"slice", "i", "j", (13 << 8) | 13},                  // i(13) j(13)
 	opSlice3:        {"slice3", "i", "j", (13 << 8) | 13},                 // i(13) j(13)
-	opMapIndex:      {"mapIndex", "", "set", 26},                          // reserved(24) set(2)
+	opMapIndex:      {"mapIndex", "", "set", 26},                          // reserved(25) set(1)
 	opGoBuiltin:     {"goBuiltin", "", "op", 26},                          // op(26)
 	opErrWrap:       {"errWrap", "", "idx", 26},                           // idx(26)
 	opWrapIfErr:     {"wrapIfErr", "", "offset", 26},                      // reserved(2) offset(24)
diff --git a/exec/bytecode/goinstr.go b/exec/bytecode/goinstr.go
index 07010bf6..57ac6557 100644
--- a/exec/bytecode/goinstr.go
+++ b/exec/bytecode/goinstr.go
@@ -243,10 +243,7 @@ func execMapIndex(i Instr, p *Context) {
 	key := reflect.ValueOf(p.data[n-1])
 	v := reflect.ValueOf(p.data[n-2])
 	switch i & bitsOperand {
-	case mapDeleteOperand: // delete(mapData $key)
-		v.SetMapIndex(key, reflect.Value{})
-		p.PopN(2)
-	case setMapIndexOperand: // value mapData $key $setMapIndex
+	case 1: // value mapData $key $setMapIndex
 		v.SetMapIndex(key, reflect.ValueOf(p.data[n-3]))
 		p.PopN(3)
 	default: // mapData $key $mapIndex
@@ -448,13 +445,7 @@ func (p *Builder) MapIndex() *Builder {
 
 // SetMapIndex instr
 func (p *Builder) SetMapIndex() *Builder {
-	p.code.data = append(p.code.data, (opMapIndex<<bitsOpShift)|setMapIndexOperand)
-	return p
-}
-
-// Delete instr
-func (p *Builder) Delete() *Builder {
-	p.code.data = append(p.code.data, (opMapIndex<<bitsOpShift)|mapDeleteOperand)
+	p.code.data = append(p.code.data, (opMapIndex<<bitsOpShift)|1)
 	return p
 }
 
@@ -481,11 +472,9 @@ func (p *Builder) SetIndex(idx int) *Builder {
 }
 
 const (
-	mapDeleteOperand   = 2
-	setMapIndexOperand = 3
-	setIndexFlag       = (1 << 25)
-	setIndexOperand    = setIndexFlag - 1
-	sliceIndexMask     = (1 << 13) - 1
+	setIndexFlag    = (1 << 25)
+	setIndexOperand = setIndexFlag - 1
+	sliceIndexMask  = (1 << 13) - 1
 	// SliceConstIndexLast - slice const index max
 	SliceConstIndexLast = exec.SliceConstIndexLast
 	// SliceDefaultIndex - unspecified index
diff --git a/exec/bytecode/interface.go b/exec/bytecode/interface.go
index 9b3aeec6..f6a9baf0 100644
--- a/exec/bytecode/interface.go
+++ b/exec/bytecode/interface.go
@@ -355,12 +355,6 @@ func (p *iBuilder) SetMapIndex() exec.Builder {
 	return p
 }
 
-// Delete instr
-func (p *iBuilder) Delete() exec.Builder {
-	((*Builder)(p)).Delete()
-	return p
-}
-
 // Index instr
 func (p *iBuilder) Index(idx int) exec.Builder {
 	((*Builder)(p)).Index(idx)
diff --git a/exec/bytecode/var.go b/exec/bytecode/var.go
index 60e2f13c..ed7fd5cc 100644
--- a/exec/bytecode/var.go
+++ b/exec/bytecode/var.go
@@ -134,6 +134,11 @@ func execGoBuiltin(i Instr, p *Context) {
 		src := reflect.ValueOf(p.data[n-1])
 		dst := reflect.ValueOf(p.data[n-2])
 		p.Ret(2, reflect.Copy(dst, src))
+	case GobDelete:
+		key := reflect.ValueOf(p.data[n-1])
+		v := reflect.ValueOf(p.data[n-2])
+		v.SetMapIndex(key, reflect.Value{})
+		p.PopN(2)
 	default:
 		log.Panicln("execGoBuiltin: todo -", i)
 	}
diff --git a/exec/golang/builder.go b/exec/golang/builder.go
index 356fe1b5..eb91b534 100644
--- a/exec/golang/builder.go
+++ b/exec/golang/builder.go
@@ -130,7 +130,6 @@ var (
 	makeIdent   = Ident("make")
 	newIdent    = Ident("new")
 	nilIdent    = Ident("nil")
-	deleteIdent = Ident("delete")
 )
 
 // Resolve resolves all unresolved labels/functions/consts/etc.
diff --git a/exec/golang/expr.go b/exec/golang/expr.go
index 927ac158..3e807190 100644
--- a/exec/golang/expr.go
+++ b/exec/golang/expr.go
@@ -492,13 +492,6 @@ func (p *Builder) SetMapIndex() *Builder {
 	return p
 }
 
-// Delete instr
-func (p *Builder) Delete() *Builder {
-	p.rhs.Push(deleteIdent)
-	p.Call(2, false)
-	return p
-}
-
 // Index instr
 func (p *Builder) Index(idx int) *Builder {
 	p.rhs.Push(IndexWith(p, idx))
diff --git a/exec/golang/interface.go b/exec/golang/interface.go
index 62dc179c..bbe2643b 100644
--- a/exec/golang/interface.go
+++ b/exec/golang/interface.go
@@ -370,12 +370,6 @@ func (p *iBuilder) SetMapIndex() exec.Builder {
 	return p
 }
 
-// Delete instr
-func (p *iBuilder) Delete() exec.Builder {
-	((*Builder)(p)).Delete()
-	return p
-}
-
 // Index instr
 func (p *iBuilder) Index(idx int) exec.Builder {
 	((*Builder)(p)).Index(idx)


Test patch:
diff --git a/exec/bytecode/goinstr_test.go b/exec/bytecode/goinstr_test.go
index c96c6870..f6d3ea97 100644
--- a/exec/bytecode/goinstr_test.go
+++ b/exec/bytecode/goinstr_test.go
@@ -616,18 +616,19 @@ func TestTypeCast(t *testing.T) {
 }
 
 func TestDelete(t *testing.T) {
-	m := NewVar(reflect.MapOf(TyString, TyInt), "")
+	tyMap := reflect.MapOf(TyString, TyInt)
+	m := NewVar(tyMap, "")
 	code := newBuilder().
 		DefineVar(m).
 		Push("Hello").
 		Push(1).
 		Push("Go+").
 		Push(2).
-		MakeMap(reflect.MapOf(TyString, TyInt), 2).
+		MakeMap(tyMap, 2).
 		StoreVar(m).
 		LoadVar(m).
 		Push("Hello").
-		Delete().
+		GoBuiltin(tyMap, GobDelete).
 		LoadVar(m).
 		Resolve()