From f1761c0c9c68d663df5df46a8e7bf0d3b70d68df Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sat, 27 Apr 2024 13:57:21 +0800 Subject: [PATCH] llgo/internal/runtime --- internal/runtime/iface.go | 5 +++++ internal/runtime/runtime2.go | 37 +++++++++++++++++++++++++++++++++ internal/runtime/type.go | 18 ++++++++++++++++ internal/runtime/z_iface.go | 40 ++++++++++++++++++++++++++++++++++++ ssa/package.go | 27 ++++++++++++++++++++++++ ssa/type.go | 7 +++++++ 6 files changed, 134 insertions(+) create mode 100644 internal/runtime/iface.go create mode 100644 internal/runtime/runtime2.go create mode 100644 internal/runtime/type.go create mode 100644 internal/runtime/z_iface.go diff --git a/internal/runtime/iface.go b/internal/runtime/iface.go new file mode 100644 index 00000000..47bf8fc2 --- /dev/null +++ b/internal/runtime/iface.go @@ -0,0 +1,5 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime diff --git a/internal/runtime/runtime2.go b/internal/runtime/runtime2.go new file mode 100644 index 00000000..d0d8bea7 --- /dev/null +++ b/internal/runtime/runtime2.go @@ -0,0 +1,37 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime + +import ( + "unsafe" +) + +type iface struct { + tab *itab + data unsafe.Pointer +} + +/* +type eface struct { + _type *_type + data unsafe.Pointer +} + +func efaceOf(ep *any) *eface { + return (*eface)(unsafe.Pointer(ep)) +} +*/ + +// layout of Itab known to compilers +// allocated in non-garbage-collected memory +// Needs to be in sync with +// ../cmd/compile/internal/reflectdata/reflect.go:/^func.WriteTabs. +type itab struct { + inter *interfacetype + _type *_type + hash uint32 // copy of _type.hash. Used for type switches. + _ [4]byte + fun [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter. +} diff --git a/internal/runtime/type.go b/internal/runtime/type.go new file mode 100644 index 00000000..a02e3b6c --- /dev/null +++ b/internal/runtime/type.go @@ -0,0 +1,18 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Runtime type representation. + +package runtime + +import ( + "github.com/goplus/llgo/internal/abi" +) + +// type nameOff = abi.NameOff +// type typeOff = abi.TypeOff + +type _type = abi.Type + +type interfacetype = abi.InterfaceType diff --git a/internal/runtime/z_iface.go b/internal/runtime/z_iface.go new file mode 100644 index 00000000..87689b2b --- /dev/null +++ b/internal/runtime/z_iface.go @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package runtime + +import ( + "unsafe" + + "github.com/goplus/llgo/internal/abi" +) + +type Interface = iface + +type InterfaceType = abi.InterfaceType + +type Type = abi.Type + +var ( + TyAny = &InterfaceType{} +) + +func MakeAny(typ *Type, data unsafe.Pointer) Interface { + return Interface{ + tab: &itab{inter: TyAny, _type: typ, hash: 0, fun: [1]uintptr{0}}, + data: data, + } +} diff --git a/ssa/package.go b/ssa/package.go index b6507c1f..85b7c9d2 100644 --- a/ssa/package.go +++ b/ssa/package.go @@ -90,10 +90,17 @@ func Initialize(flags InitFlags) { // ----------------------------------------------------------------------------- +type Runtime interface { + Runtime() *types.Package +} + type aProgram struct { ctx llvm.Context typs typeutil.Map + rt *types.Scope + rtget Runtime + target *Target td llvm.TargetData // tm llvm.TargetMachine @@ -107,6 +114,7 @@ type aProgram struct { voidType llvm.Type voidPtrTy llvm.Type + anyTy Type voidTy Type boolTy Type intTy Type @@ -128,6 +136,18 @@ func NewProgram(target *Target) Program { return &aProgram{ctx: ctx, target: target, td: td} } +// SetRuntime sets the runtime package. +func (p Program) SetRuntime(runtime Runtime) { + p.rtget = runtime +} + +func (p Program) runtime() *types.Scope { + if p.rt == nil { + p.rt = p.rtget.Runtime().Scope() + } + return p.rt +} + // NewPackage creates a new package. func (p Program) NewPackage(name, pkgPath string) Package { mod := p.ctx.NewModule(pkgPath) @@ -154,6 +174,13 @@ func (p Program) Bool() Type { return p.boolTy } +func (p Program) Any() Type { + if p.anyTy == nil { + p.anyTy = p.Type(tyAny) + } + return p.anyTy +} + // Int returns int type. func (p Program) Int() Type { if p.intTy == nil { diff --git a/ssa/type.go b/ssa/type.go index 0b26d7bb..21e438c9 100644 --- a/ssa/type.go +++ b/ssa/type.go @@ -23,6 +23,10 @@ import ( "github.com/goplus/llvm" ) +var ( + tyAny = types.NewInterfaceType(nil, nil) +) + // ----------------------------------------------------------------------------- type valueKind = int @@ -237,6 +241,9 @@ func (p Program) toLLVMType(typ types.Type) Type { case *types.Pointer: elem := p.Type(t.Elem()) return &aType{llvm.PointerType(elem.ll, 0), typ, vkInvalid} + case *types.Interface: + tyIface := p.runtime().Lookup("Interface").(*types.TypeName).Type().(*types.Named) + return p.toLLVMNamed(tyIface) case *types.Slice: case *types.Map: case *types.Struct: