Merge pull request #318 from xushiwei/q
internal/abi.Map: IndirectKey/IndirectElem
This commit is contained in:
5
c/c.go
5
c/c.go
@@ -46,7 +46,7 @@ type integer interface {
|
||||
func Str(string) *Char
|
||||
|
||||
// llgo:link Advance llgo.advance
|
||||
func Advance[PtrT any](ptr PtrT, offset int) PtrT { return ptr }
|
||||
func Advance[PtrT any, I integer](ptr PtrT, offset I) PtrT { return ptr }
|
||||
|
||||
// llgo:link Index llgo.index
|
||||
func Index[T any, I integer](ptr *T, offset I) T { return *ptr }
|
||||
@@ -66,6 +66,9 @@ func Free(ptr Pointer)
|
||||
//go:linkname Memcpy C.memcpy
|
||||
func Memcpy(dst, src Pointer, n uintptr) Pointer
|
||||
|
||||
//go:linkname Memmove C.memmove
|
||||
func Memmove(dst, src Pointer, n uintptr) Pointer
|
||||
|
||||
//go:linkname Memset C.memset
|
||||
func Memset(s Pointer, c Int, n uintptr) Pointer
|
||||
|
||||
|
||||
@@ -170,6 +170,24 @@ type MapType struct {
|
||||
Flags uint32
|
||||
}
|
||||
|
||||
// Note: flag values must match those used in the TMAP case
|
||||
// in ../cmd/compile/internal/reflectdata/reflect.go:writeType.
|
||||
func (mt *MapType) IndirectKey() bool { // store ptr to key instead of key itself
|
||||
return mt.Flags&1 != 0
|
||||
}
|
||||
func (mt *MapType) IndirectElem() bool { // store ptr to elem instead of elem itself
|
||||
return mt.Flags&2 != 0
|
||||
}
|
||||
func (mt *MapType) ReflexiveKey() bool { // true if k==k for all keys
|
||||
return mt.Flags&4 != 0
|
||||
}
|
||||
func (mt *MapType) NeedKeyUpdate() bool { // true if we need to update key on an overwrite
|
||||
return mt.Flags&8 != 0
|
||||
}
|
||||
func (mt *MapType) HashMightPanic() bool { // true if hash function might panic
|
||||
return mt.Flags&16 != 0
|
||||
}
|
||||
|
||||
type PtrType struct {
|
||||
Type
|
||||
Elem *Type // pointer element (pointed at) type
|
||||
|
||||
@@ -19,10 +19,10 @@ To run the demos in directory `_demo`, you need to set the `LLGO_LIB_PYTHON` env
|
||||
export LLGO_LIB_PYTHON=/foo/bar/python3.12
|
||||
```
|
||||
|
||||
For example, `/opt/homebrew/Frameworks/Python.framework/Versions/3.12/libpython3.12.dylib` is a typical python lib location under macOS. So we should set it like this:
|
||||
For example, `/opt/homebrew/Frameworks/Python.framework/Versions/3.12/lib/libpython3.12.dylib` is a typical python lib location under macOS. So we should set it like this:
|
||||
|
||||
```sh
|
||||
export LLGO_LIB_PYTHON=/opt/homebrew/Frameworks/Python.framework/Versions/3.12/python3.12
|
||||
export LLGO_LIB_PYTHON=/opt/homebrew/Frameworks/Python.framework/Versions/3.12/lib/python3.12
|
||||
```
|
||||
|
||||
Then you can run the demos in directory `_demo`:
|
||||
|
||||
@@ -159,6 +159,10 @@ func (b *Builder) TypeName(t types.Type) (ret string, pub bool) {
|
||||
return "_llgo_any", true
|
||||
}
|
||||
return b.InterfaceName(t)
|
||||
case *types.Map:
|
||||
key, pub1 := b.TypeName(t.Key())
|
||||
elem, pub2 := b.TypeName(t.Elem())
|
||||
return fmt.Sprintf("map[%s]%s", key, elem), pub1 && pub2
|
||||
}
|
||||
log.Panicf("todo: %T\n", t)
|
||||
return
|
||||
|
||||
@@ -365,3 +365,50 @@ func (b Builder) MapUpdate(m, k, v Expr) {
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// The Range instruction yields an iterator over the domain and range
|
||||
// of X, which must be a string or map.
|
||||
//
|
||||
// Elements are accessed via Next.
|
||||
//
|
||||
// Type() returns an opaque and degenerate "rangeIter" type.
|
||||
//
|
||||
// Pos() returns the ast.RangeStmt.For.
|
||||
//
|
||||
// Example printed form:
|
||||
//
|
||||
// t0 = range "hello":string
|
||||
func (b Builder) Range(x Expr) Expr {
|
||||
switch x.kind {
|
||||
case vkString:
|
||||
return b.InlineCall(b.Pkg.rtFunc("NewStringIter"), x)
|
||||
}
|
||||
panic("todo")
|
||||
}
|
||||
|
||||
// The Next instruction reads and advances the (map or string)
|
||||
// iterator Iter and returns a 3-tuple value (ok, k, v). If the
|
||||
// iterator is not exhausted, ok is true and k and v are the next
|
||||
// elements of the domain and range, respectively. Otherwise ok is
|
||||
// false and k and v are undefined.
|
||||
//
|
||||
// Components of the tuple are accessed using Extract.
|
||||
//
|
||||
// The IsString field distinguishes iterators over strings from those
|
||||
// over maps, as the Type() alone is insufficient: consider
|
||||
// map[int]rune.
|
||||
//
|
||||
// Type() returns a *types.Tuple for the triple (ok, k, v).
|
||||
// The types of k and/or v may be types.Invalid.
|
||||
//
|
||||
// Example printed form:
|
||||
//
|
||||
// t1 = next t0
|
||||
func (b Builder) Next(iter Expr, isString bool) (ret Expr) {
|
||||
if isString {
|
||||
return b.InlineCall(b.Pkg.rtFunc("StringIterNext"), iter)
|
||||
}
|
||||
panic("todo")
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
47
ssa/expr.go
47
ssa/expr.go
@@ -742,53 +742,6 @@ func castPtr(b llvm.Builder, x llvm.Value, t llvm.Type) llvm.Value {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// The Range instruction yields an iterator over the domain and range
|
||||
// of X, which must be a string or map.
|
||||
//
|
||||
// Elements are accessed via Next.
|
||||
//
|
||||
// Type() returns an opaque and degenerate "rangeIter" type.
|
||||
//
|
||||
// Pos() returns the ast.RangeStmt.For.
|
||||
//
|
||||
// Example printed form:
|
||||
//
|
||||
// t0 = range "hello":string
|
||||
func (b Builder) Range(x Expr) Expr {
|
||||
switch x.kind {
|
||||
case vkString:
|
||||
return b.InlineCall(b.Pkg.rtFunc("NewStringIter"), x)
|
||||
}
|
||||
panic("todo")
|
||||
}
|
||||
|
||||
// The Next instruction reads and advances the (map or string)
|
||||
// iterator Iter and returns a 3-tuple value (ok, k, v). If the
|
||||
// iterator is not exhausted, ok is true and k and v are the next
|
||||
// elements of the domain and range, respectively. Otherwise ok is
|
||||
// false and k and v are undefined.
|
||||
//
|
||||
// Components of the tuple are accessed using Extract.
|
||||
//
|
||||
// The IsString field distinguishes iterators over strings from those
|
||||
// over maps, as the Type() alone is insufficient: consider
|
||||
// map[int]rune.
|
||||
//
|
||||
// Type() returns a *types.Tuple for the triple (ok, k, v).
|
||||
// The types of k and/or v may be types.Invalid.
|
||||
//
|
||||
// Example printed form:
|
||||
//
|
||||
// t1 = next t0
|
||||
func (b Builder) Next(iter Expr, isString bool) (ret Expr) {
|
||||
if isString {
|
||||
return b.InlineCall(b.Pkg.rtFunc("StringIterNext"), iter)
|
||||
}
|
||||
panic("todo")
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// The MakeClosure instruction yields a closure value whose code is
|
||||
// Fn and whose free variables' values are supplied by Bindings.
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user