Use proper string types with embedded length
Этот коммит содержится в:
родитель
0e99366568
коммит
e1b04abd46
3 изменённых файлов: 20 добавлений и 10 удалений
|
@ -4,8 +4,8 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
|
|
||||||
void __go_printstring(char *str) {
|
void __go_printstring(string_t *str) {
|
||||||
write(STDOUT_FILENO, str, strlen(str));
|
write(STDOUT_FILENO, str->buf, str->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __go_printspace() {
|
void __go_printspace() {
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t length; // TODO: size_t
|
uint32_t len; // TODO: size_t (or, let max string size depend on target/flag)
|
||||||
uint8_t *data;
|
uint8_t buf[]; // variable size
|
||||||
} string_t;
|
} string_t;
|
||||||
|
|
||||||
void __go_printstring(char *str);
|
void __go_printstring(string_t *str);
|
||||||
void __go_printnl();
|
void __go_printnl();
|
||||||
|
|
20
tgo.go
20
tgo.go
|
@ -27,6 +27,8 @@ type Compiler struct {
|
||||||
ctx llvm.Context
|
ctx llvm.Context
|
||||||
builder llvm.Builder
|
builder llvm.Builder
|
||||||
machine llvm.TargetMachine
|
machine llvm.TargetMachine
|
||||||
|
stringType llvm.Type
|
||||||
|
stringPtrType llvm.Type
|
||||||
printstringFunc llvm.Value
|
printstringFunc llvm.Value
|
||||||
printspaceFunc llvm.Value
|
printspaceFunc llvm.Value
|
||||||
printnlFunc llvm.Value
|
printnlFunc llvm.Value
|
||||||
|
@ -45,7 +47,11 @@ func NewCompiler(path, triple string) (*Compiler, error) {
|
||||||
c.ctx = c.mod.Context()
|
c.ctx = c.mod.Context()
|
||||||
c.builder = c.ctx.NewBuilder()
|
c.builder = c.ctx.NewBuilder()
|
||||||
|
|
||||||
printstringType := llvm.FunctionType(llvm.VoidType(), []llvm.Type{llvm.PointerType(llvm.Int8Type(), 0)}, false)
|
// Length-prefixed string.
|
||||||
|
c.stringType = llvm.StructType([]llvm.Type{llvm.Int32Type(), llvm.ArrayType(llvm.Int8Type(), 0)}, false)
|
||||||
|
c.stringPtrType = llvm.PointerType(c.stringType, 0)
|
||||||
|
|
||||||
|
printstringType := llvm.FunctionType(llvm.VoidType(), []llvm.Type{c.stringPtrType}, false)
|
||||||
c.printstringFunc = llvm.AddFunction(c.mod, "__go_printstring", printstringType)
|
c.printstringFunc = llvm.AddFunction(c.mod, "__go_printstring", printstringType)
|
||||||
printspaceType := llvm.FunctionType(llvm.VoidType(), nil, false)
|
printspaceType := llvm.FunctionType(llvm.VoidType(), nil, false)
|
||||||
c.printspaceFunc = llvm.AddFunction(c.mod, "__go_printspace", printspaceType)
|
c.printspaceFunc = llvm.AddFunction(c.mod, "__go_printspace", printspaceType)
|
||||||
|
@ -143,7 +149,6 @@ func (c *Compiler) parseStmt(stmt ast.Node) error {
|
||||||
func (c *Compiler) parseExpr(expr ast.Expr) error {
|
func (c *Compiler) parseExpr(expr ast.Expr) error {
|
||||||
switch v := expr.(type) {
|
switch v := expr.(type) {
|
||||||
case *ast.CallExpr:
|
case *ast.CallExpr:
|
||||||
zero := llvm.ConstInt(llvm.Int32Type(), 0, false)
|
|
||||||
name := v.Fun.(*ast.Ident).Name
|
name := v.Fun.(*ast.Ident).Name
|
||||||
fmt.Printf(" call: %s\n", name)
|
fmt.Printf(" call: %s\n", name)
|
||||||
|
|
||||||
|
@ -166,9 +171,14 @@ func (c *Compiler) parseExpr(expr ast.Expr) error {
|
||||||
switch arg.Kind {
|
switch arg.Kind {
|
||||||
case token.STRING:
|
case token.STRING:
|
||||||
str := constant.StringVal(val)
|
str := constant.StringVal(val)
|
||||||
strObj := c.builder.CreateGlobalString(str + "\x00", "")
|
strVal := c.ctx.ConstString(str, false)
|
||||||
msgCast := c.builder.CreateGEP(strObj, []llvm.Value{zero, zero}, "")
|
strLen := llvm.ConstInt(llvm.Int32Type(), uint64(len(str)), false)
|
||||||
c.builder.CreateCall(c.printstringFunc, []llvm.Value{msgCast}, "")
|
strObj := llvm.ConstStruct([]llvm.Value{strLen, strVal}, false)
|
||||||
|
ptr := llvm.AddGlobal(c.mod, strObj.Type(), ".str")
|
||||||
|
ptr.SetInitializer(strObj)
|
||||||
|
ptr.SetLinkage(llvm.InternalLinkage)
|
||||||
|
ptrCast := llvm.ConstPointerCast(ptr, c.stringPtrType)
|
||||||
|
c.builder.CreateCall(c.printstringFunc, []llvm.Value{ptrCast}, "")
|
||||||
default:
|
default:
|
||||||
return errors.New("todo: print anything other than strings")
|
return errors.New("todo: print anything other than strings")
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче