diff --git a/internal/runtime/z_string.go b/internal/runtime/z_string.go index d968d0d8..1ee8109a 100644 --- a/internal/runtime/z_string.go +++ b/internal/runtime/z_string.go @@ -40,6 +40,11 @@ func EmptyString() String { return String{nil, 0} } +// NewString creates a new string. +func NewString(data unsafe.Pointer, len int) String { + return String{data, len} +} + // StringLen returns the length of a string. func StringLen(s Slice) int { return s.len @@ -50,6 +55,8 @@ func StringData(s String) unsafe.Pointer { return s.data } +// ----------------------------------------------------------------------------- + // CStrCopy copies a Go string to a C string buffer and returns it. func CStrCopy(dest unsafe.Pointer, s String) *int8 { n := s.len diff --git a/ssa/expr.go b/ssa/expr.go index 79651d0f..e5c585e8 100644 --- a/ssa/expr.go +++ b/ssa/expr.go @@ -77,14 +77,6 @@ func (p Program) Null(t Type) Expr { return Expr{llvm.ConstNull(t.ll), t} } -// StringVal returns string constant expression. -func (p Program) StringVal(v string) Expr { - t := p.String() - cstr := llvm.ConstString(v, true) - // TODO(xsw): cstr => gostring - return Expr{cstr, t} -} - // BoolVal returns a boolean constant expression. func (p Program) BoolVal(v bool) Expr { t := p.Bool() @@ -149,7 +141,7 @@ func (b Builder) Const(v constant.Value, typ Type) Expr { return prog.FloatVal(v, typ) } case kind == types.String: - return prog.StringVal(constant.StringVal(v)) + return b.Str(constant.StringVal(v)) } } panic(fmt.Sprintf("unsupported Const: %v, %v", v, typ.t)) @@ -160,6 +152,12 @@ func (b Builder) CStr(v string) Expr { return Expr{llvm.CreateGlobalStringPtr(b.impl, v), b.Prog.CStr()} } +// Str returns a Go string constant expression. +func (b Builder) Str(v string) Expr { + cstr := b.CStr(v) + return b.InlineCall(b.fn.pkg.rtFunc("NewString"), cstr, b.Prog.Val(len(v))) +} + // ----------------------------------------------------------------------------- const (