cl: _testpy/gcd
This commit is contained in:
4
c/c.go
4
c/c.go
@@ -28,6 +28,10 @@ type (
|
|||||||
Char = int8
|
Char = int8
|
||||||
Int = C.int
|
Int = C.int
|
||||||
Uint = C.uint
|
Uint = C.uint
|
||||||
|
Long = int32
|
||||||
|
Ulong = uint32
|
||||||
|
LongLong = int64
|
||||||
|
UlongLong = uint64
|
||||||
Float = float32
|
Float = float32
|
||||||
Pointer = unsafe.Pointer
|
Pointer = unsafe.Pointer
|
||||||
FilePtr = unsafe.Pointer
|
FilePtr = unsafe.Pointer
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/goplus/gogen"
|
"github.com/goplus/gogen"
|
||||||
|
"github.com/goplus/llgo/ssa"
|
||||||
)
|
)
|
||||||
|
|
||||||
type symbol struct {
|
type symbol struct {
|
||||||
@@ -146,7 +147,7 @@ func (ctx *context) genParams(pkg *gogen.Package, sig string) (*types.Tuple, boo
|
|||||||
}
|
}
|
||||||
if strings.HasPrefix(part, "*") {
|
if strings.HasPrefix(part, "*") {
|
||||||
if part[1] != '*' {
|
if part[1] != '*' {
|
||||||
list = append(list, pkg.NewParam(0, genName(part[1:], 0), types.NewSlice(objPtr)))
|
list = append(list, ssa.VArg())
|
||||||
return types.NewTuple(list...), true, false
|
return types.NewTuple(list...), true, false
|
||||||
}
|
}
|
||||||
return types.NewTuple(list...), false, false
|
return types.NewTuple(list...), false, false
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ source_filename = "main"
|
|||||||
@__llgo_argc = global ptr null
|
@__llgo_argc = global ptr null
|
||||||
@__llgo_argv = global ptr null
|
@__llgo_argv = global ptr null
|
||||||
|
|
||||||
|
|
||||||
define void @main.init() {
|
define void @main.init() {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
%0 = load i1, ptr @"main.init$guard", align 1
|
%0 = load i1, ptr @"main.init$guard", align 1
|
||||||
|
|||||||
12
cl/_testpy/gcd/in.go
Normal file
12
cl/_testpy/gcd/in.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
"github.com/goplus/llgo/py/math"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
x := math.Gcd(py.Long(60), py.Long(20), py.Long(25))
|
||||||
|
c.Printf(c.Str("gcd(60, 20, 25) = %d\n"), x.Long())
|
||||||
|
}
|
||||||
59
cl/_testpy/gcd/out.ll
Normal file
59
cl/_testpy/gcd/out.ll
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
; ModuleID = 'main'
|
||||||
|
source_filename = "main"
|
||||||
|
|
||||||
|
@"main.init$guard" = global ptr null
|
||||||
|
@__llgo_argc = global ptr null
|
||||||
|
@__llgo_argv = global ptr null
|
||||||
|
@__llgo_py.math.gcd = linkonce global ptr null
|
||||||
|
@0 = private unnamed_addr constant [22 x i8] c"gcd(60, 20, 25) = %d\0A\00", align 1
|
||||||
|
@__llgo_py.math = external global ptr
|
||||||
|
@1 = private unnamed_addr constant [4 x i8] c"gcd\00", align 1
|
||||||
|
|
||||||
|
define void @main.init() {
|
||||||
|
_llgo_0:
|
||||||
|
%0 = load i1, ptr @"main.init$guard", align 1
|
||||||
|
br i1 %0, label %_llgo_2, label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_1: ; preds = %_llgo_0
|
||||||
|
store i1 true, ptr @"main.init$guard", align 1
|
||||||
|
call void @"github.com/goplus/llgo/py/math.init"()
|
||||||
|
%1 = load ptr, ptr @__llgo_py.math, align 8
|
||||||
|
call void (ptr, ...) @llgoLoadPyModSyms(ptr %1, ptr @1, ptr @__llgo_py.math.gcd, ptr null)
|
||||||
|
br label %_llgo_2
|
||||||
|
|
||||||
|
_llgo_2: ; preds = %_llgo_1, %_llgo_0
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @main(i32 %0, ptr %1) {
|
||||||
|
_llgo_0:
|
||||||
|
call void @Py_Initialize()
|
||||||
|
store i32 %0, ptr @__llgo_argc, align 4
|
||||||
|
store ptr %1, ptr @__llgo_argv, align 8
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
call void @main.init()
|
||||||
|
%2 = call ptr @PyLong_FromLong(i32 60)
|
||||||
|
%3 = call ptr @PyLong_FromLong(i32 20)
|
||||||
|
%4 = call ptr @PyLong_FromLong(i32 25)
|
||||||
|
%5 = load ptr, ptr @__llgo_py.math.gcd, align 8
|
||||||
|
%6 = call ptr (ptr, ...) @PyObject_CallFunctionObjArgs(ptr %5, ptr %2, ptr %3, ptr %4, ptr null)
|
||||||
|
%7 = call i32 @PyLong_AsLong(ptr %6)
|
||||||
|
%8 = call i32 (ptr, ...) @printf(ptr @0, i32 %7)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/py/math.init"()
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
|
||||||
|
declare ptr @PyLong_FromLong(i32)
|
||||||
|
|
||||||
|
declare ptr @PyObject_CallFunctionObjArgs(ptr, ...)
|
||||||
|
|
||||||
|
declare i32 @PyLong_AsLong(ptr)
|
||||||
|
|
||||||
|
declare i32 @printf(ptr, ...)
|
||||||
|
|
||||||
|
declare void @llgoLoadPyModSyms(ptr, ...)
|
||||||
|
|
||||||
|
declare void @Py_Initialize()
|
||||||
73
py/long.go
Normal file
73
py/long.go
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* 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 py
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://docs.python.org/3/c-api/long.html
|
||||||
|
|
||||||
|
//go:linkname Long C.PyLong_FromLong
|
||||||
|
func Long(v c.Long) *Object
|
||||||
|
|
||||||
|
//go:linkname LongLong C.PyLong_FromLongLong
|
||||||
|
func LongLong(v c.LongLong) *Object
|
||||||
|
|
||||||
|
//go:linkname Ulong C.PyLong_FromUnsignedLong
|
||||||
|
func Ulong(v c.Ulong) *Object
|
||||||
|
|
||||||
|
//go:linkname UlongLong C.PyLong_FromUnsignedLongLong
|
||||||
|
func UlongLong(v c.UlongLong) *Object
|
||||||
|
|
||||||
|
//go:linkname Uintptr C.PyLong_FromSize_t
|
||||||
|
func Uintptr(v uintptr) *Object
|
||||||
|
|
||||||
|
//go:linkname LongFromFloat64 C.PyLong_FromDouble
|
||||||
|
func LongFromFloat64(v float64) *Object
|
||||||
|
|
||||||
|
//go:linkname LongFromVoidPtr C.PyLong_FromVoidPtr
|
||||||
|
func LongFromVoidPtr(v c.Pointer) *Object
|
||||||
|
|
||||||
|
//go:linkname LongFromCStr C.PyLong_FromString
|
||||||
|
func LongFromCStr(v *c.Char, pend **c.Char, base c.Int) *Object
|
||||||
|
|
||||||
|
//go:linkname LongFromUnicode C.PyLong_FromUnicodeObject
|
||||||
|
func LongFromUnicode(v *Object, base c.Int) *Object
|
||||||
|
|
||||||
|
// llgo:link (*Object).Long C.PyLong_AsLong
|
||||||
|
func (l *Object) Long() c.Long { return 0 }
|
||||||
|
|
||||||
|
// llgo:link (*Object).LongLong C.PyLong_AsLongLong
|
||||||
|
func (l *Object) LongLong() c.LongLong { return 0 }
|
||||||
|
|
||||||
|
// llgo:link (*Object).Ulong C.PyLong_AsUnsignedLong
|
||||||
|
func (l *Object) Ulong() c.Ulong { return 0 }
|
||||||
|
|
||||||
|
// llgo:link (*Object).UlongLong C.PyLong_AsUnsignedLongLong
|
||||||
|
func (l *Object) UlongLong() c.UlongLong { return 0 }
|
||||||
|
|
||||||
|
// llgo:link (*Object).Uintptr C.PyLong_AsSize_t
|
||||||
|
func (l *Object) Uintptr() uintptr { return 0 }
|
||||||
|
|
||||||
|
// llgo:link (*Object).LongAsFloat64 C.PyLong_AsDouble
|
||||||
|
func (l *Object) LongAsFloat64() float64 { return 0 }
|
||||||
|
|
||||||
|
// llgo:link (*Object).LongAsVoidPtr C.PyLong_AsVoidPtr
|
||||||
|
func (l *Object) LongAsVoidPtr() c.Pointer { return nil }
|
||||||
31
py/math/doc.txt
Normal file
31
py/math/doc.txt
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
// Unlike the built-in ** operator, math.pow() converts both its arguments to type
|
||||||
|
// float. Use ** or the built-in pow() function for computing exact integer powers.
|
||||||
|
//
|
||||||
|
//go:linkname Pow py.pow
|
||||||
|
func Pow(x, y *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the sine of x radians.
|
||||||
|
//
|
||||||
|
//go:linkname Sin py.sin
|
||||||
|
func Sin(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the hyperbolic sine of x.
|
||||||
|
//
|
||||||
|
//go:linkname Sinh py.sinh
|
||||||
|
func Sinh(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the base-2 logarithm of x. This is usually more accurate than log(x, 2).
|
||||||
|
//
|
||||||
|
//go:linkname Log2 py.log2
|
||||||
|
func Log2(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the base-10 logarithm of x. This is usually more accurate than log(x, 10).
|
||||||
|
//
|
||||||
|
//go:linkname Log10 py.log10
|
||||||
|
func Log10(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the fractional and integer parts of x. Both results carry the sign of
|
||||||
|
// x and are floats.
|
||||||
|
//
|
||||||
|
//go:linkname Modf py.modf
|
||||||
|
func Modf(x *py.Object) *py.Object
|
||||||
@@ -174,7 +174,90 @@ func Gamma(x *py.Object) *py.Object
|
|||||||
// Greatest Common Divisor.
|
// Greatest Common Divisor.
|
||||||
//
|
//
|
||||||
//go:linkname Gcd py.gcd
|
//go:linkname Gcd py.gcd
|
||||||
func Gcd(integers ...*py.Object) *py.Object
|
func Gcd(__llgo_va_list ...interface{}) *py.Object
|
||||||
|
|
||||||
|
// Return True if x is neither an infinity nor a NaN, and False otherwise.
|
||||||
|
//
|
||||||
|
//go:linkname Isfinite py.isfinite
|
||||||
|
func Isfinite(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return True if x is a positive or negative infinity, and False otherwise.
|
||||||
|
//
|
||||||
|
//go:linkname Isinf py.isinf
|
||||||
|
func Isinf(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return True if x is a NaN (not a number), and False otherwise.
|
||||||
|
//
|
||||||
|
//go:linkname Isnan py.isnan
|
||||||
|
func Isnan(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the integer part of the square root of the input.
|
||||||
|
//
|
||||||
|
//go:linkname Isqrt py.isqrt
|
||||||
|
func Isqrt(n *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Least Common Multiple.
|
||||||
|
//
|
||||||
|
//go:linkname Lcm py.lcm
|
||||||
|
func Lcm(__llgo_va_list ...interface{}) *py.Object
|
||||||
|
|
||||||
|
// Return x * (2**i).
|
||||||
|
//
|
||||||
|
// This is essentially the inverse of frexp().
|
||||||
|
//
|
||||||
|
//go:linkname Ldexp py.ldexp
|
||||||
|
func Ldexp(x *py.Object, i *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Natural logarithm of absolute value of Gamma function at x.
|
||||||
|
//
|
||||||
|
//go:linkname Lgamma py.lgamma
|
||||||
|
func Lgamma(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the base 10 logarithm of x.
|
||||||
|
//
|
||||||
|
//go:linkname Log10 py.log10
|
||||||
|
func Log10(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the base 2 logarithm of x.
|
||||||
|
//
|
||||||
|
//go:linkname Log2 py.log2
|
||||||
|
func Log2(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the fractional and integer parts of x.
|
||||||
|
//
|
||||||
|
// Both results carry the sign of x and are floats.
|
||||||
|
//
|
||||||
|
//go:linkname Modf py.modf
|
||||||
|
func Modf(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return x**y (x to the power of y).
|
||||||
|
//
|
||||||
|
//go:linkname Pow py.pow
|
||||||
|
func Pow(x *py.Object, y *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Convert angle x from degrees to radians.
|
||||||
|
//
|
||||||
|
//go:linkname Radians py.radians
|
||||||
|
func Radians(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Difference between x and the closest integer multiple of y.
|
||||||
|
//
|
||||||
|
// Return x - n*y where n*y is the closest integer multiple of y.
|
||||||
|
// In the case where x is exactly halfway between two multiples of
|
||||||
|
// y, the nearest even value of n is used. The result is always exact.
|
||||||
|
//
|
||||||
|
//go:linkname Remainder py.remainder
|
||||||
|
func Remainder(x *py.Object, y *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the sine of x (measured in radians).
|
||||||
|
//
|
||||||
|
//go:linkname Sin py.sin
|
||||||
|
func Sin(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the hyperbolic sine of x.
|
||||||
|
//
|
||||||
|
//go:linkname Sinh py.sinh
|
||||||
|
func Sinh(x *py.Object) *py.Object
|
||||||
|
|
||||||
// Return the square root of x.
|
// Return the square root of x.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -27,22 +27,6 @@ import (
|
|||||||
//go:linkname Pi py.pi
|
//go:linkname Pi py.pi
|
||||||
var Pi *py.Object
|
var Pi *py.Object
|
||||||
|
|
||||||
// Unlike the built-in ** operator, math.pow() converts both its arguments to type
|
|
||||||
// float. Use ** or the built-in pow() function for computing exact integer powers.
|
|
||||||
//
|
|
||||||
//go:linkname Pow py.pow
|
|
||||||
func Pow(x, y *py.Object) *py.Object
|
|
||||||
|
|
||||||
// Return the sine of x radians.
|
|
||||||
//
|
|
||||||
//go:linkname Sin py.sin
|
|
||||||
func Sin(x *py.Object) *py.Object
|
|
||||||
|
|
||||||
// Return the hyperbolic sine of x.
|
|
||||||
//
|
|
||||||
//go:linkname Sinh py.sinh
|
|
||||||
func Sinh(x *py.Object) *py.Object
|
|
||||||
|
|
||||||
// With one argument, return the natural logarithm of x (to base e).
|
// With one argument, return the natural logarithm of x (to base e).
|
||||||
//
|
//
|
||||||
//go:linkname Log py.log
|
//go:linkname Log py.log
|
||||||
@@ -60,22 +44,6 @@ func LogOf(x, base *py.Object) *py.Object
|
|||||||
//go:linkname Log1p py.log1p
|
//go:linkname Log1p py.log1p
|
||||||
func Log1p(x *py.Object) *py.Object
|
func Log1p(x *py.Object) *py.Object
|
||||||
|
|
||||||
// Return the base-2 logarithm of x. This is usually more accurate than log(x, 2).
|
|
||||||
//
|
|
||||||
//go:linkname Log2 py.log2
|
|
||||||
func Log2(x *py.Object) *py.Object
|
|
||||||
|
|
||||||
// Return the base-10 logarithm of x. This is usually more accurate than log(x, 10).
|
|
||||||
//
|
|
||||||
//go:linkname Log10 py.log10
|
|
||||||
func Log10(x *py.Object) *py.Object
|
|
||||||
|
|
||||||
// Return the fractional and integer parts of x. Both results carry the sign of
|
|
||||||
// x and are floats.
|
|
||||||
//
|
|
||||||
//go:linkname Modf py.modf
|
|
||||||
func Modf(x *py.Object) *py.Object
|
|
||||||
|
|
||||||
// Return the Euclidean norm, sqrt(sum(x**2 for x in coordinates)). This is the
|
// Return the Euclidean norm, sqrt(sum(x**2 for x in coordinates)). This is the
|
||||||
// length of the vector from the origin to the point given by the coordinates.
|
// length of the vector from the origin to the point given by the coordinates.
|
||||||
//
|
//
|
||||||
|
|||||||
12
ssa/decl.go
12
ssa/decl.go
@@ -33,15 +33,19 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func VArg() *types.Var {
|
func VArg() *types.Var {
|
||||||
return types.NewParam(0, nil, NameValist, types.Typ[types.Invalid])
|
return types.NewParam(0, nil, NameValist, types.NewSlice(tyAny))
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsVArg(arg *types.Var) bool {
|
func IsVArg(arg *types.Var) bool {
|
||||||
return arg.Name() == NameValist
|
return arg.Name() == NameValist
|
||||||
}
|
}
|
||||||
|
|
||||||
func HasVArg(t *types.Tuple, n int) bool {
|
func HasVArg(t *types.Tuple, n int, sig *types.Signature) bool {
|
||||||
return n > 0 && IsVArg(t.At(n-1))
|
has := n > 0 && IsVArg(t.At(n-1))
|
||||||
|
if has && !sig.Variadic() { // TODO(xsw): remove this check
|
||||||
|
panic("HasVArg: varg must mark as variadic in signature")
|
||||||
|
}
|
||||||
|
return has
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@@ -196,7 +200,7 @@ func newParams(fn Type, prog Program) (params []Type, hasVArg bool) {
|
|||||||
sig := fn.raw.Type.(*types.Signature)
|
sig := fn.raw.Type.(*types.Signature)
|
||||||
in := sig.Params()
|
in := sig.Params()
|
||||||
if n := in.Len(); n > 0 {
|
if n := in.Len(); n > 0 {
|
||||||
if hasVArg = HasVArg(in, n); hasVArg {
|
if hasVArg = HasVArg(in, n, sig); hasVArg {
|
||||||
n--
|
n--
|
||||||
}
|
}
|
||||||
params = make([]Type, n)
|
params = make([]Type, n)
|
||||||
|
|||||||
@@ -532,7 +532,7 @@ func (p Program) tyCallFunctionObjArgs() *types.Signature {
|
|||||||
paramObjPtr := p.paramObjPtr()
|
paramObjPtr := p.paramObjPtr()
|
||||||
params := types.NewTuple(paramObjPtr, VArg())
|
params := types.NewTuple(paramObjPtr, VArg())
|
||||||
results := types.NewTuple(paramObjPtr)
|
results := types.NewTuple(paramObjPtr)
|
||||||
p.callFOArgs = types.NewSignatureType(nil, nil, nil, params, results, false)
|
p.callFOArgs = types.NewSignatureType(nil, nil, nil, params, results, true)
|
||||||
}
|
}
|
||||||
return p.callFOArgs
|
return p.callFOArgs
|
||||||
}
|
}
|
||||||
@@ -576,7 +576,7 @@ func (p Program) tyLoadPyModSyms() *types.Signature {
|
|||||||
objPtr := p.PyObjectPtr().raw.Type
|
objPtr := p.PyObjectPtr().raw.Type
|
||||||
paramObjPtr := types.NewParam(token.NoPos, nil, "mod", objPtr)
|
paramObjPtr := types.NewParam(token.NoPos, nil, "mod", objPtr)
|
||||||
params := types.NewTuple(paramObjPtr, VArg())
|
params := types.NewTuple(paramObjPtr, VArg())
|
||||||
p.loadPyModS = types.NewSignatureType(nil, nil, nil, params, nil, false)
|
p.loadPyModS = types.NewSignatureType(nil, nil, nil, params, nil, true)
|
||||||
}
|
}
|
||||||
return p.loadPyModS
|
return p.loadPyModS
|
||||||
}
|
}
|
||||||
@@ -647,8 +647,11 @@ func (b Builder) pyCall(fn Expr, args []Expr) (ret Expr) {
|
|||||||
call := pkg.pyFunc("PyObject_CallNoArgs", prog.tyCallNoArgs())
|
call := pkg.pyFunc("PyObject_CallNoArgs", prog.tyCallNoArgs())
|
||||||
ret = b.Call(call, fn)
|
ret = b.Call(call, fn)
|
||||||
case 1:
|
case 1:
|
||||||
|
if !sig.Variadic() {
|
||||||
call := pkg.pyFunc("PyObject_CallOneArg", prog.tyCallOneArg())
|
call := pkg.pyFunc("PyObject_CallOneArg", prog.tyCallOneArg())
|
||||||
ret = b.Call(call, fn, args[0])
|
return b.Call(call, fn, args[0])
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
default:
|
default:
|
||||||
call := pkg.pyFunc("PyObject_CallFunctionObjArgs", prog.tyCallFunctionObjArgs())
|
call := pkg.pyFunc("PyObject_CallFunctionObjArgs", prog.tyCallFunctionObjArgs())
|
||||||
n = len(args)
|
n = len(args)
|
||||||
|
|||||||
@@ -399,7 +399,7 @@ func TestPrintf(t *testing.T) {
|
|||||||
pchar := types.NewPointer(types.Typ[types.Int8])
|
pchar := types.NewPointer(types.Typ[types.Int8])
|
||||||
params := types.NewTuple(types.NewVar(0, nil, "format", pchar), VArg())
|
params := types.NewTuple(types.NewVar(0, nil, "format", pchar), VArg())
|
||||||
rets := types.NewTuple(types.NewVar(0, nil, "", types.Typ[types.Int32]))
|
rets := types.NewTuple(types.NewVar(0, nil, "", types.Typ[types.Int32]))
|
||||||
sig := types.NewSignatureType(nil, nil, nil, params, rets, false)
|
sig := types.NewSignatureType(nil, nil, nil, params, rets, true)
|
||||||
pkg.NewFunc("printf", sig, InGo)
|
pkg.NewFunc("printf", sig, InGo)
|
||||||
assertPkg(t, pkg, `; ModuleID = 'foo/bar'
|
assertPkg(t, pkg, `; ModuleID = 'foo/bar'
|
||||||
source_filename = "foo/bar"
|
source_filename = "foo/bar"
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ func (p Program) toLLVMTypes(t *types.Tuple, n int) (ret []llvm.Type) {
|
|||||||
func (p Program) toLLVMFunc(sig *types.Signature) llvm.Type {
|
func (p Program) toLLVMFunc(sig *types.Signature) llvm.Type {
|
||||||
tParams := sig.Params()
|
tParams := sig.Params()
|
||||||
n := tParams.Len()
|
n := tParams.Len()
|
||||||
hasVArg := HasVArg(tParams, n)
|
hasVArg := HasVArg(tParams, n, sig)
|
||||||
if hasVArg {
|
if hasVArg {
|
||||||
n--
|
n--
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,6 +66,27 @@ func (p Program) FuncDecl(sig *types.Signature, bg Background) Type {
|
|||||||
return &aType{p.toLLVMFunc(sig), rawType{sig}, vkFuncDecl}
|
return &aType{p.toLLVMFunc(sig), rawType{sig}, vkFuncDecl}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// cvtCxFunc converts a C extended function type into raw type.
|
||||||
|
func cvtCxFunc(sig *types.Signature, recv *types.Var) *types.Signature {
|
||||||
|
if sig.Variadic() {
|
||||||
|
// convert printf-like function type
|
||||||
|
tParams := sig.Params()
|
||||||
|
n := tParams.Len()
|
||||||
|
params := make([]*types.Var, n)
|
||||||
|
n--
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
params[i] = tParams.At(i)
|
||||||
|
}
|
||||||
|
params[n] = VArg()
|
||||||
|
sig = types.NewSignatureType(nil, nil, nil, types.NewTuple(params...), sig.Results(), true)
|
||||||
|
panic("todo")
|
||||||
|
}
|
||||||
|
sig = FuncAddCtx(recv, sig)
|
||||||
|
return sig
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// Closure creates a closture type for a function.
|
// Closure creates a closture type for a function.
|
||||||
func (p Program) Closure(fn Type) Type {
|
func (p Program) Closure(fn Type) Type {
|
||||||
sig := fn.raw.Type.(*types.Signature)
|
sig := fn.raw.Type.(*types.Signature)
|
||||||
@@ -152,7 +173,7 @@ func (p goTypes) cvtFunc(sig *types.Signature, recv *types.Var) (raw *types.Sign
|
|||||||
params, cvt1 := p.cvtTuple(sig.Params())
|
params, cvt1 := p.cvtTuple(sig.Params())
|
||||||
results, cvt2 := p.cvtTuple(sig.Results())
|
results, cvt2 := p.cvtTuple(sig.Results())
|
||||||
if cvt1 || cvt2 {
|
if cvt1 || cvt2 {
|
||||||
return types.NewSignatureType(nil, nil, nil, params, results, sig.Variadic())
|
return types.NewSignatureType(nil, nil, nil, params, results, false)
|
||||||
}
|
}
|
||||||
return sig
|
return sig
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user