diff --git a/newbinding/binding.py b/newbinding/binding.py index 1f980d1..69267dc 100644 --- a/newbinding/binding.py +++ b/newbinding/binding.py @@ -185,6 +185,11 @@ class Class(_Type): writer.die_if_false(casted) return casted + def wrap(self, writer, val): + copy = 'new %s(%s)' % (self.fullname, val) + return writer.pycapsule_new(copy, self.capsule_name, self.fullname) + + class Enum(object): format = 'O' @@ -466,13 +471,17 @@ class ref(_Type): def __init__(self, element): assert isinstance(element, Class), type(element) self.element = element + self.const = False def __str__(self): return self.fullname @property def fullname(self): - return '%s&' % self.element.fullname + if self.const: + return 'const %s&' % self.element.fullname + else: + return '%s&' % self.element.fullname @property def capsule_name(self): @@ -483,7 +492,7 @@ class ref(_Type): return self.element.format def wrap(self, writer, val): - p = writer.declare(ptr(self.element).fullname, '&%s' % val) + p = writer.declare(const(ptr(self.element)).fullname, '&%s' % val) return writer.pycapsule_new(p, self.capsule_name, self.element.fullname) def unwrap(self, writer, val): @@ -522,9 +531,9 @@ class ptr(_Type): class ownedptr(ptr): pass -def const(ptr): - ptr.const = True - return ptr +def const(ptr_or_ref): + ptr_or_ref.const = True + return ptr_or_ref class cast(_Type): format = 'O' diff --git a/newbinding/include/llvm_binding/extra.h b/newbinding/include/llvm_binding/extra.h index 10a4361..46dd42a 100644 --- a/newbinding/include/llvm_binding/extra.h +++ b/newbinding/include/llvm_binding/extra.h @@ -368,9 +368,9 @@ PyObject* EngineBuilder_setMAttrs(llvm::EngineBuilder* eb, return NULL; } std::vector tmp; - const int N = PyList_Size(strlist); + const Py_ssize_t N = PyList_Size(strlist); tmp.reserve(N); - for (int i = 0; i < N; ++i) { + for (Py_ssize_t i = 0; i < N; ++i) { const char * elem = PyString_AsString(PyList_GetItem(strlist, i)); if (!elem) { return NULL; @@ -381,3 +381,27 @@ PyObject* EngineBuilder_setMAttrs(llvm::EngineBuilder* eb, return pycapsule_new(eb, "llvm::EngineBuilder"); } +static +PyObject* EngineBuilder_selectTarget(llvm::EngineBuilder* eb, + const llvm::Triple& TargetTriple, + llvm::StringRef MArch, + llvm::StringRef MCPU, + PyObject* strlist) +{ + const Py_ssize_t N = PySequence_Size(strlist); + llvm::SmallVector MAttrs; + MAttrs.reserve(N); + for (Py_ssize_t i = 0; i < N; ++i) { + PyObject* str = PySequence_GetItem(strlist, i); + const char * cp = PyString_AsString(str); + if (!cp) { + Py_DECREF(str); + return NULL; + } + MAttrs.push_back(cp); + Py_DECREF(str); + } + eb->selectTarget(TargetTriple, MArch, MCPU, MAttrs); + return pycapsule_new(eb, "llvm::EngineBuilder"); +} + diff --git a/newbinding/src/CodeGen.py b/newbinding/src/CodeGen.py index 06821aa..7afcd49 100644 --- a/newbinding/src/CodeGen.py +++ b/newbinding/src/CodeGen.py @@ -17,3 +17,4 @@ class TLSModel: class CodeGenOpt: 'Actually a namespace' Level = Enum('None', 'Less', 'Default', 'Aggressive') + diff --git a/newbinding/src/EngineBuilder.py b/newbinding/src/EngineBuilder.py index 0e8388e..07ffcc0 100644 --- a/newbinding/src/EngineBuilder.py +++ b/newbinding/src/EngineBuilder.py @@ -6,6 +6,7 @@ from CodeGen import CodeGenOpt, Reloc, CodeModel from StringRef import StringRef from ExecutionEngine import ExecutionEngine from TargetMachine import TargetMachine +from Triple import Triple EngineBuilder = llvm.Class() @@ -45,5 +46,17 @@ class EngineBuilder: create = Method(ptr(ExecutionEngine), ownedptr(TargetMachine)).require_only(0) - selectTarget = Method(ptr(TargetMachine)) + _selectTarget0 = Method(ptr(TargetMachine)) + _selectTarget0.realname = 'selectTarget' + + _selectTarget1 = CustomMethod('EngineBuilder_selectTarget', + const(ref(Triple)), cast(str, StringRef), + cast(str, StringRef), PyObjectPtr), + + @CustomPythonMethod + def selectTarget(self, *args): + if not args: + return self._selectTarget0() + else: + return self._selectTarget1(*args) diff --git a/newbinding/src/Target.py b/newbinding/src/Target.py new file mode 100644 index 0000000..3c2a0e1 --- /dev/null +++ b/newbinding/src/Target.py @@ -0,0 +1,27 @@ +from binding import * +from namespace import llvm +from StringRef import StringRef +Target = llvm.Class() + +@Target +class Target: + _include_ = 'llvm/Support/TargetRegistry.h' + + getNext = Method(const(ptr(Target))) + + getName = Method(cast(StringRef, str)) + getShortDescription = Method(cast(StringRef, str)) + + def _has(): + return Method(cast(Bool, bool)) + + hasJIT = _has() + hasTargetMachine = _has() + hasMCAsmBackend = _has() + hasMCAsmParser = _has() + hasAsmPrinter = _has() + hasMCDisassembler = _has() + hasMCInstPrinter = _has() + hasMCCodeEmitter = _has() + hasMCObjectStreamer = _has() + hasAsmStreamer = _has() diff --git a/newbinding/src/TargetMachine.py b/newbinding/src/TargetMachine.py index e53cd33..5910585 100644 --- a/newbinding/src/TargetMachine.py +++ b/newbinding/src/TargetMachine.py @@ -1,5 +1,12 @@ from binding import * from namespace import llvm +from StringRef import StringRef +from CodeGen import CodeModel, TLSModel, CodeGenOpt, Reloc +from GlobalValue import GlobalValue +from Target import Target +from DataLayout import DataLayout +from TargetTransformInfo import (ScalarTargetTransformInfo, + VectorTargetTransformInfo) TargetMachine = llvm.Class() @@ -8,4 +15,22 @@ class TargetMachine: _include_ = 'llvm/Target/TargetMachine.h' delete = Destructor() + getTarget = Method(const(ref(Target))) + getTargetTriple = Method(cast(StringRef, str)) + getTargetCPU = Method(cast(StringRef, str)) + getTargetFeatureString = Method(cast(StringRef, str)) + + getRelocationModel = Method(Reloc.Model) + getCodeModel = Method(CodeModel.Model) + getTLSModel = Method(TLSModel.Model, ptr(GlobalValue)) + getOptLevel = Method(CodeGenOpt.Level) + + hasMCUseDwarfDirectory = Method(cast(Bool, bool)) + setMCUseDwarfDirectory = Method(Void, cast(bool, Bool)) + + getDataLayout = Method(const(ownedptr(DataLayout))) + getScalarTargetTransformInfo = Method(const( + ownedptr(ScalarTargetTransformInfo))) + getVectorTargetTransformInfo = Method(const( + ownedptr(VectorTargetTransformInfo))) diff --git a/newbinding/src/TargetTransformInfo.py b/newbinding/src/TargetTransformInfo.py new file mode 100644 index 0000000..8e3c17e --- /dev/null +++ b/newbinding/src/TargetTransformInfo.py @@ -0,0 +1,14 @@ +from binding import * +from namespace import llvm + +ScalarTargetTransformInfo = llvm.Class() +VectorTargetTransformInfo = llvm.Class() + +@ScalarTargetTransformInfo +class ScalarTargetTransformInfo: + delete = Destructor() + +@VectorTargetTransformInfo +class VectorTargetTransformInfo: + delete = Destructor() + diff --git a/newbinding/src/Triple.py b/newbinding/src/Triple.py new file mode 100644 index 0000000..0fd894e --- /dev/null +++ b/newbinding/src/Triple.py @@ -0,0 +1,55 @@ +from binding import * +from namespace import llvm +from StringRef import StringRef + +Triple = llvm.Class() + +@Triple +class Triple: + _include_ = 'llvm/ADT/Triple.h' + + new = Constructor() + new |= Constructor(cast(str, StringRef)) + new |= Constructor(cast(str, StringRef), + cast(str, StringRef), cast(str, StringRef)) + + def _return_str(): + return Method(cast(StringRef, str)) + + getTriple = _return_str() + getArchName = _return_str() + getVendorName = _return_str() + getOSName = _return_str() + getEnvironmentName = _return_str() + getOSAndEnvironmentName = _return_str() + + @CustomPythonMethod + def __str__(self): + return self.getTriple() + + def _return_bool(*args): + return Method(cast(bool, Bool), *args) + + isArch64Bit = _return_bool() + isArch32Bit = _return_bool() + isArch16Bit = _return_bool() + isOSVersionLT = _return_bool(cast(int, Unsigned), + cast(int, Unsigned), + cast(int, Unsigned)).require_only(1) + + isMacOSXVersionLT = _return_bool(cast(int, Unsigned), + cast(int, Unsigned), + cast(int, Unsigned)).require_only(1) + + isMacOSX = _return_bool() + isOSDarwin = _return_bool() + isOSCygMing = _return_bool() + isOSWindows = _return_bool() + # isOSNaCl = _return_bool() + isOSBinFormatELF = _return_bool() + isOSBinFormatCOFF = _return_bool() + isEnvironmentMachO = _return_bool() + + get32BitArchVariant = Method(Triple) + get64BitArchVariant = Method(Triple) + diff --git a/newbinding/test2.py b/newbinding/test2.py index a304426..93fccb8 100644 --- a/newbinding/test2.py +++ b/newbinding/test2.py @@ -124,8 +124,31 @@ def test_engine_builder(): eb.setOptLevel(api.CodeGenOpt.Level.Aggressive).setUseMCJIT(False) tm = eb.selectTarget() + + print 'target triple:', tm.getTargetTriple() + print 'target cpu:', tm.getTargetCPU() + print 'target feature string:', tm.getTargetFeatureString() + + target = tm.getTarget() + print 'target name:', target.getName() + print 'target short description:', target.getShortDescription() + + assert target.hasJIT() + assert target.hasTargetMachine() + ee = eb.create(tm) + triple = api.Triple.new('x86_64-unknown-linux') + assert triple.getArchName() == 'x86_64' + assert triple.getVendorName() == 'unknown' + assert triple.getOSName() == 'linux' + assert triple.isArch64Bit() + assert not triple.isArch32Bit() + triple_32variant = triple.get32BitArchVariant() + assert triple_32variant.isArch32Bit() + + print tm.getDataLayout() + def main(): for name, value in globals().items():