Skip to content

Commit 0f211c5

Browse files
committed
changed return type of zeroValue to ast.Expr
1 parent b8f692c commit 0f211c5

File tree

3 files changed

+53
-41
lines changed

3 files changed

+53
-41
lines changed

compiler/expressions.go

+31-12
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ func (c *funcContext) translateExpr(expr ast.Expr) *expression {
108108
collectIndexedElements := func(elementType types.Type) []string {
109109
var elements []string
110110
i := 0
111-
zero := c.zeroValue(elementType)
111+
zero := c.translateExpr(c.zeroValue(elementType)).String()
112112
for _, element := range e.Elts {
113113
if kve, isKve := element.(*ast.KeyValueExpr); isKve {
114114
key, ok := exact.Int64Val(c.p.Types[kve.Key].Value)
@@ -131,9 +131,9 @@ func (c *funcContext) translateExpr(expr ast.Expr) *expression {
131131
case *types.Array:
132132
elements := collectIndexedElements(t.Elem())
133133
if len(elements) == 0 {
134-
return c.formatExpr("%s", c.zeroValue(t))
134+
return c.formatExpr("%s.zero()", c.typeName(t))
135135
}
136-
zero := c.zeroValue(t.Elem())
136+
zero := c.translateExpr(c.zeroValue(t.Elem())).String()
137137
for len(elements) < int(t.Len()) {
138138
elements = append(elements, zero)
139139
}
@@ -162,7 +162,7 @@ func (c *funcContext) translateExpr(expr ast.Expr) *expression {
162162
}
163163
if isKeyValue {
164164
for i := range elements {
165-
elements[i] = c.zeroValue(t.Field(i).Type())
165+
elements[i] = c.translateExpr(c.zeroValue(t.Field(i).Type())).String()
166166
}
167167
for _, element := range e.Elts {
168168
kve := element.(*ast.KeyValueExpr)
@@ -462,9 +462,9 @@ func (c *funcContext) translateExpr(expr ast.Expr) *expression {
462462
}
463463
key := fmt.Sprintf("%s.keyFor(%s)", c.typeName(t.Key()), c.translateImplicitConversion(e.Index, t.Key()))
464464
if _, isTuple := exprType.(*types.Tuple); isTuple {
465-
return c.formatExpr(`(%1s = %2e[%3s], %1s !== undefined ? [%1s.v, true] : [%4s, false])`, c.newVariable("_entry"), e.X, key, c.zeroValue(t.Elem()))
465+
return c.formatExpr(`(%1s = %2e[%3s], %1s !== undefined ? [%1s.v, true] : [%4e, false])`, c.newVariable("_entry"), e.X, key, c.zeroValue(t.Elem()))
466466
}
467-
return c.formatExpr(`(%1s = %2e[%3s], %1s !== undefined ? %1s.v : %4s)`, c.newVariable("_entry"), e.X, key, c.zeroValue(t.Elem()))
467+
return c.formatExpr(`(%1s = %2e[%3s], %1s !== undefined ? %1s.v : %4e)`, c.newVariable("_entry"), e.X, key, c.zeroValue(t.Elem()))
468468
case *types.Basic:
469469
return c.formatExpr("%e.charCodeAt(%f)", e.X, e.Index)
470470
default:
@@ -728,7 +728,26 @@ func (c *funcContext) translateExpr(expr ast.Expr) *expression {
728728
case *types.TypeName:
729729
return c.formatExpr("%s", c.typeName(o.Type()))
730730
case *types.Nil:
731-
return c.formatExpr("%s", c.zeroValue(c.p.TypeOf(e)))
731+
if typesutil.IsJsObject(exprType) {
732+
return c.formatExpr("null")
733+
}
734+
switch t := exprType.Underlying().(type) {
735+
case *types.Basic:
736+
if t.Kind() != types.UnsafePointer {
737+
panic("unexpected basic type")
738+
}
739+
return c.formatExpr("0")
740+
case *types.Slice, *types.Pointer, *types.Chan:
741+
return c.formatExpr("%s.nil", c.typeName(exprType))
742+
case *types.Map:
743+
return c.formatExpr("false")
744+
case *types.Interface:
745+
return c.formatExpr("$ifaceNil")
746+
case *types.Signature:
747+
return c.formatExpr("$throwNilPointerError")
748+
default:
749+
panic(fmt.Sprintf("unexpected type: %T", t))
750+
}
732751
default:
733752
panic(fmt.Sprintf("Unhandled object: %T\n", o))
734753
}
@@ -808,9 +827,9 @@ func (c *funcContext) translateBuiltin(name string, sig *types.Signature, args [
808827
}
809828
switch t.Elem().Underlying().(type) {
810829
case *types.Struct, *types.Array:
811-
return c.formatExpr("%s", c.zeroValue(t.Elem()))
830+
return c.formatExpr("%e", c.zeroValue(t.Elem()))
812831
default:
813-
return c.formatExpr("$newDataPointer(%s, %s)", c.zeroValue(t.Elem()), c.typeName(t))
832+
return c.formatExpr("$newDataPointer(%e, %s)", c.zeroValue(t.Elem()), c.typeName(t))
814833
}
815834
case "make":
816835
switch argType := c.p.TypeOf(args[0]).Underlying().(type) {
@@ -1035,7 +1054,7 @@ func (c *funcContext) translateConversion(expr ast.Expr, desiredType types.Type)
10351054
if c.p.Pkg.Path() == "syscall" && types.Identical(exprType, types.Typ[types.UnsafePointer]) {
10361055
array := c.newVariable("_array")
10371056
target := c.newVariable("_struct")
1038-
return c.formatExpr("(%s = %e, %s = %s, %s, %s)", array, expr, target, c.zeroValue(t.Elem()), c.loadStruct(array, target, s), target)
1057+
return c.formatExpr("(%s = %e, %s = %e, %s, %s)", array, expr, target, c.zeroValue(t.Elem()), c.loadStruct(array, target, s), target)
10391058
}
10401059
return c.formatExpr("$pointerOfStructConversion(%e, %s)", expr, c.typeName(t))
10411060
}
@@ -1076,7 +1095,7 @@ func (c *funcContext) translateImplicitConversion(expr ast.Expr, desiredType typ
10761095
return c.translateExpr(expr)
10771096
}
10781097
if expr == nil {
1079-
return c.formatExpr("%s", c.zeroValue(desiredType))
1098+
return c.formatExpr("%e", c.zeroValue(desiredType))
10801099
}
10811100

10821101
exprType := c.p.TypeOf(expr)
@@ -1086,7 +1105,7 @@ func (c *funcContext) translateImplicitConversion(expr ast.Expr, desiredType typ
10861105

10871106
basicExprType, isBasicExpr := exprType.Underlying().(*types.Basic)
10881107
if isBasicExpr && basicExprType.Kind() == types.UntypedNil {
1089-
return c.formatExpr("%s", c.zeroValue(desiredType))
1108+
return c.formatExpr("%e", c.zeroValue(desiredType))
10901109
}
10911110

10921111
switch desiredType.Underlying().(type) {

compiler/package.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ func Compile(importPath string, files []*ast.File, fileSet *token.FileSet, impor
259259
}
260260
if _, ok := varsWithInit[o]; !ok {
261261
d.DceDeps = collectDependencies(func() {
262-
d.InitCode = []byte(fmt.Sprintf("\t\t%s = %s;\n", c.objectName(o), c.zeroValue(o.Type())))
262+
d.InitCode = []byte(fmt.Sprintf("\t\t%s = %s;\n", c.objectName(o), c.translateExpr(c.zeroValue(o.Type())).String()))
263263
})
264264
}
265265
d.DceObjectFilter = o.Name()
@@ -392,7 +392,7 @@ func Compile(importPath string, files []*ast.File, fileSet *token.FileSet, impor
392392
}
393393
constructor = fmt.Sprintf("function(%s) {\n\t\tthis.$val = this;\n\t\tif (arguments.length === 0) {\n", strings.Join(params, ", "))
394394
for i := 0; i < t.NumFields(); i++ {
395-
constructor += fmt.Sprintf("\t\t\tthis.%s = %s;\n", fieldName(t, i), c.zeroValue(t.Field(i).Type()))
395+
constructor += fmt.Sprintf("\t\t\tthis.%s = %s;\n", fieldName(t, i), c.translateExpr(c.zeroValue(t.Field(i).Type())).String())
396396
}
397397
constructor += "\t\t\treturn;\n\t\t}\n"
398398
for i := 0; i < t.NumFields(); i++ {
@@ -668,7 +668,7 @@ func translateFunction(typ *ast.FuncType, initStmts []ast.Stmt, body *ast.BlockS
668668
c.resultNames = make([]ast.Expr, c.sig.Results().Len())
669669
for i := 0; i < c.sig.Results().Len(); i++ {
670670
result := c.sig.Results().At(i)
671-
c.Printf("%s = %s;", c.objectName(result), c.zeroValue(result.Type()))
671+
c.Printf("%s = %s;", c.objectName(result), c.translateExpr(c.zeroValue(result.Type())).String())
672672
id := ast.NewIdent("")
673673
c.p.Uses[id] = result
674674
c.resultNames[i] = c.setType(id, result.Type())

compiler/utils.go

+19-26
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/gopherjs/gopherjs/compiler/analysis"
1414
"github.com/gopherjs/gopherjs/compiler/typesutil"
1515

16+
"golang.org/x/tools/go/exact"
1617
"golang.org/x/tools/go/types"
1718
)
1819

@@ -164,41 +165,33 @@ func (c *funcContext) translateSelection(sel *types.Selection, pos token.Pos) ([
164165
return fields, ""
165166
}
166167

167-
func (c *funcContext) zeroValue(ty types.Type) string {
168-
if typesutil.IsJsObject(ty) {
169-
return "null"
170-
}
168+
var nilObj = types.Universe.Lookup("nil")
169+
170+
func (c *funcContext) zeroValue(ty types.Type) ast.Expr {
171171
switch t := ty.Underlying().(type) {
172172
case *types.Basic:
173173
switch {
174-
case is64Bit(t) || isComplex(t):
175-
return fmt.Sprintf("new %s(0, 0)", c.typeName(ty))
176174
case isBoolean(t):
177-
return "false"
178-
case isNumeric(t), t.Kind() == types.UnsafePointer:
179-
return "0"
175+
return c.newConst(ty, exact.MakeBool(false))
176+
case isNumeric(t):
177+
return c.newConst(ty, exact.MakeInt64(0))
180178
case isString(t):
181-
return `""`
179+
return c.newConst(ty, exact.MakeString(""))
182180
case t.Kind() == types.UntypedNil:
183181
panic("Zero value for untyped nil.")
184-
default:
185-
panic("Unhandled type")
186182
}
187-
case *types.Array:
188-
return fmt.Sprintf("%s.zero()", c.typeName(ty))
189-
case *types.Signature:
190-
return "$throwNilPointerError"
191-
case *types.Slice, *types.Pointer, *types.Chan:
192-
return fmt.Sprintf("%s.nil", c.typeName(ty))
193-
case *types.Struct:
194-
return fmt.Sprintf("new %s.ptr()", c.typeName(ty))
195-
case *types.Map:
196-
return "false"
197-
case *types.Interface:
198-
return "$ifaceNil"
199-
default:
200-
panic(fmt.Sprintf("unexpected type: %T", t))
183+
case *types.Array, *types.Struct:
184+
return c.setType(&ast.CompositeLit{}, ty)
201185
}
186+
id := c.newIdent("nil", ty)
187+
c.p.Uses[id] = nilObj
188+
return id
189+
}
190+
191+
func (c *funcContext) newConst(t types.Type, value exact.Value) ast.Expr {
192+
id := &ast.Ident{}
193+
c.p.Types[id] = types.TypeAndValue{Type: t, Value: value}
194+
return id
202195
}
203196

204197
func (c *funcContext) newVariable(name string) string {

0 commit comments

Comments
 (0)