GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — cppjit/python/cppjit/_cpython_cppjit.py at main · compiler-research/cppjit

Expand file tree

/

_cpython_cppjit.py

Copy path
More file actions
More file actions

Latest commit

 

History

History
History
230 lines (181 loc) · 7.29 KB
/

_cpython_cppjit.py

Copy path

File metadata and controls

230 lines (181 loc) · 7.29 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
"""CPython-specific touch-ups"""
import ctypes
import importlib.util
from . import _stdcpp_fix # noqa: F401
__all__ = [
"gbl",
"load_reflection_info",
"addressof",
"bind_object",
"nullptr",
"default",
"_backend",
"_begin_capture_stderr",
"_end_capture_stderr",
]
def _preload_backend_library():
# preload the merged extension with ctypes and run LoadCppInterOp() first,
# so the interpreter is ready before the extension module initializes
spec = importlib.util.find_spec("cppjit.libcppjit")
if spec is None or not spec.origin:
raise ImportError("cannot locate the cppjit.libcppjit extension module")
lib = ctypes.CDLL(spec.origin, ctypes.RTLD_GLOBAL)
if not lib.LoadCppInterOp():
raise RuntimeError(
"cppjit could not initialize its C++ interpreter, see the diagnostic "
"above (LoadCppInterOp failed)"
)
return lib
_w = _preload_backend_library()
from . import libcppjit as _backend # noqa: E402
### template support ---------------------------------------------------------
class Template(object): # expected/used by ProxyWrappers.cxx in cpyrt
stl_sequence_types = ["std::vector", "std::list", "std::set", "std::deque"]
stl_unrolled_types = ["std::pair"]
stl_fixed_size_types = ["std::array"]
stl_mapping_types = ["std::map", "std::unordered_map"]
def __init__(self, name, scope):
self.__name__ = name
self.__cpp_name__ = name
self._instantiations = dict()
self.__scope__ = scope
def __repr__(self):
return "<cppjit.Template '%s' object at %s>" % (self.__name__, hex(id(self)))
def __getitem__(self, *args):
# multi-argument to [] becomes a single tuple argument
if args and isinstance(args[0], tuple):
args = args[0]
# if already instantiated, return the existing class
try:
return self._instantiations[args]
except KeyError:
pass
# construct the type name from the types or their string representation
newargs = [self.__scope__]
for arg in args:
if isinstance(arg, str):
arg = ",".join(map(lambda x: x.strip(), arg.split(",")))
newargs.append(arg)
pyclass = _backend.MakeCppTemplateClass(*newargs)
# memoize the class to prevent spurious lookups/re-pythonizations
self._instantiations[args] = pyclass
# special case pythonization (builtin_map is not available from the C-API)
if "push_back" in pyclass.__dict__ and "__iadd__" not in pyclass.__dict__:
if "reserve" in pyclass.__dict__:
def iadd(self, ll):
self.reserve(len(ll))
for x in ll:
self.push_back(x)
return self
else:
def iadd(self, ll):
for x in ll:
self.push_back(x)
return self
pyclass.__iadd__ = iadd
# back-pointer for reflection
pyclass.__cpp_template__ = self
return pyclass
def __call__(self, *args):
# for C++17, we're required to derive the type when using initializer syntax
# (i.e. a tuple or list); not sure how to do that in general, but below the
# most common cases are covered
if args:
args0 = args[0]
if args0 and isinstance(args0, (tuple, list)):
t = type(args0[0])
if t is float:
t = "double"
if self.__name__ in self.stl_sequence_types:
return self[t](*args)
if self.__name__ in self.stl_fixed_size_types:
return self[t, len(args0)](*args)
if self.__name__ in self.stl_unrolled_types:
return self[tuple(type(a) for a in args0)](*args0)
if args0 and isinstance(args0, dict):
if self.__name__ in self.stl_mapping_types:
try:
pair = args0.items().__iter__().__next__()
except AttributeError:
pair = args0.items()[0]
t1 = type(pair[0])
if t1 is float:
t1 = "double"
t2 = type(pair[1])
if t2 is float:
t2 = "double"
return self[t1, t2](*args)
return self.__getitem__(*(type(a) for a in args0))(*args)
# old 'metaclass-style' template instantiations
return self.__getitem__(*args)
_backend.Template = Template
# - :: and std:: namespaces ---------------------------------------------------
gbl = _backend.CreateScopeProxy("")
gbl.__class__.__repr__ = lambda cls: "<namespace cppjit.gbl at 0x%x>" % id(cls)
gbl.std = _backend.CreateScopeProxy("std")
# for move, we want our "pythonized" one, not the C++ template
gbl.std.move = _backend.move
# CppInterOp proxy object to access its API
Cpp = gbl.Cpp
# - add to the dynamic path as needed -----------------------------------------
import os # noqa: E402
def _add_default_paths():
if os.getenv("CONDA_PREFIX"):
# MacOS, Linux
lib_path = os.path.join(os.getenv("CONDA_PREFIX"), "lib")
if os.path.exists(lib_path):
Cpp.AddSearchPath(lib_path, True, False)
# Windows
lib_path = os.path.join(os.getenv("CONDA_PREFIX"), "Library", "lib")
if os.path.exists(lib_path):
Cpp.AddSearchPath(lib_path, True, False)
# assuming that we are in PREFIX/lib/python/site-packages/cppjit, add PREFIX/lib to the search path
lib_path = os.path.abspath(
os.path.join(
os.path.dirname(__file__), os.path.pardir, os.path.pardir, os.path.pardir
)
)
if os.path.exists(lib_path):
Cpp.AddSearchPath(lib_path, True, False)
try:
with open("/etc/ld.so.conf") as ldconf:
for line in ldconf:
f = line.strip()
if os.path.exists(f):
Cpp.AddSearchPath(f, True, False)
except IOError:
pass
_add_default_paths()
# - exports -------------------------------------------------------------------
addressof = _backend.addressof
bind_object = _backend.bind_object
nullptr = _backend.nullptr
default = _backend.default
def load_reflection_info(name):
# with _stderr_capture() as err:
# FIXME: Remove the .so and add logic in libcppinterop
name = name + ".so"
result = Cpp.LoadLibrary(name, True)
if name.endswith("Dict.so"):
header = name[:-7] + ".h"
Cpp.Declare('#include "' + header + '"', False)
if result == False: # noqa: E712
raise RuntimeError('Could not load library "%s"' % (name))
return True
def _begin_capture_stderr():
_backend._begin_capture_stderr()
def _end_capture_stderr():
err = _backend._end_capture_stderr()
if err:
try:
return "\n%s" % err
except UnicodeDecodeError as e:
original_error = e
try:
return "\n%s" % err.decode("gbk") # not guaranteed, but common
except UnicodeDecodeError:
pass
return "C++ issued an error message that could not be decoded (%s)" % str(
original_error
)
return ""
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.