diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index e239b54a..ae6699ea 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,12 +1,12 @@ -FROM mcr.microsoft.com/vscode/devcontainers/base:jammy +FROM mcr.microsoft.com/devcontainers/base:dev-ubuntu-22.04 # These dependencies are required by Nix. RUN apt update -y -RUN apt -y install --no-install-recommends curl xz-utils cmake libreadline-dev libncurses-dev llvm-12 llvm-12-dev ack +RUN apt -y install --no-install-recommends curl xz-utils cmake libreadline-dev libncurses-dev llvm-12 llvm-12-dev RUN [ -e /usr/bin/gmake ] || sudo ln -s /usr/bin/make /usr/bin/gmake -# Install Nix -ARG NIX_INSTALL_SCRIPT=https://github.com/nix-community/nix-unstable-installer/releases/download/nix-2.23.0pre20240603_da92ad7/install +# Install Nix +ARG NIX_INSTALL_SCRIPT=https://nixos.org/nix/install RUN curl -L ${NIX_INSTALL_SCRIPT} | sudo -u vscode NIX_INSTALLER_NO_MODIFY_PROFILE=1 sh # Configuration for Nix from the repository shared amongst developers. diff --git a/.devcontainer/podman/devcontainer.json b/.devcontainer/podman/devcontainer.json index a52dd69c..3ffca5be 100644 --- a/.devcontainer/podman/devcontainer.json +++ b/.devcontainer/podman/devcontainer.json @@ -31,6 +31,9 @@ "containerEnv": { "HOME": "/home/vscode" }, + "mounts": [ + "type=bind,readonly,source=/etc/localtime,target=/etc/localtime" + ], "customizations": { "vscode": { "extensions": [ diff --git a/.gitignore b/.gitignore index a886c192..3d0c5ca6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *.sw? /build/ -scripts/*.pyc +__pycache__/ +*.py[cod] CMakeCache.txt CMakeFiles/ /doc/en/_build/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 4bf088ce..da0eef4e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,12 +31,17 @@ elseif(${LLVM_PACKAGE_VERSION} VERSION_LESS "11.0") else() set(jit_lib mcjit orcjit) endif() +IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + set(llvm_arch_lib x86) +ELSEIF(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") + set(llvm_arch_lib aarch64) +ENDIF() find_program(llvm-config llvm-config PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH) find_program(llvm-config llvm-config) message(STATUS "Using LLVM config: ${llvm-config}") if (${LLVM_PACKAGE_VERSION} VERSION_LESS "4.0") - execute_process(COMMAND ${llvm-config} --libs x86 ipo ${jit_lib} + execute_process(COMMAND ${llvm-config} --libs ipo ${llvm_arch_lib} ${jit_lib} OUTPUT_VARIABLE llvm_libs OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process(COMMAND ${llvm-config} --ldflags @@ -46,7 +51,7 @@ if (${LLVM_PACKAGE_VERSION} VERSION_LESS "4.0") OUTPUT_VARIABLE sys_libs OUTPUT_STRIP_TRAILING_WHITESPACE) else() - execute_process(COMMAND ${llvm-config} --libs x86 ipo ${jit_lib} --link-static + execute_process(COMMAND ${llvm-config} --libs ipo ${llvm_arch_lib} ${jit_lib} --link-static OUTPUT_VARIABLE llvm_libs OUTPUT_STRIP_TRAILING_WHITESPACE COMMAND_ERROR_IS_FATAL ANY) diff --git a/include/hobbes/storage.H b/include/hobbes/storage.H index 84864b60..c52dfc7b 100644 --- a/include/hobbes/storage.H +++ b/include/hobbes/storage.H @@ -262,6 +262,57 @@ static inline unsigned spin(unsigned count) { return (count << 1); } +#if defined(__aarch64__) +//https://docs.huihoo.com/doxygen/linux/kernel/3.7/arch_2arm64_2include_2asm_2cmpxchg_8h_source.html +#define uxchg(ptr,x) \ + __xchg((x),(ptr),sizeof(*(ptr))) + +static inline void __xchg(volatile unsigned long x, volatile void *ptr, std::size_t size) +{ + unsigned long ret, tmp; + + switch (size) { + case 1: + asm volatile("// __xchg1\n" + "1: ldaxrb %w0, [%3]\n" + " stlxrb %w1, %w2, [%3]\n" + " cbnz %w1, 1b\n" + : "=&r" (ret), "=&r" (tmp) + : "r" (x), "r" (ptr) + : "memory", "cc"); + break; + case 2: + asm volatile("// __xchg2\n" + "1: ldaxrh %w0, [%3]\n" + " stlxrh %w1, %w2, [%3]\n" + " cbnz %w1, 1b\n" + : "=&r" (ret), "=&r" (tmp) + : "r" (x), "r" (ptr) + : "memory", "cc"); + break; + case 4: + asm volatile("// __xchg4\n" + "1: ldaxr %w0, [%3]\n" + " stlxr %w1, %w2, [%3]\n" + " cbnz %w1, 1b\n" + : "=&r" (ret), "=&r" (tmp) + : "r" (x), "r" (ptr) + : "memory", "cc"); + break; + case 8: + asm volatile("// __xchg8\n" + "1: ldaxr %0, [%3]\n" + " stlxr %w1, %2, [%3]\n" + " cbnz %w1, 1b\n" + : "=&r" (ret), "=&r" (tmp) + : "r" (x), "r" (ptr) + : "memory", "cc"); + break; + default: + assert(0); + } +} +#else static inline void uxchg(volatile uint32_t* px, uint32_t nx) { __asm__ __volatile__( "xchgl %0,%1" @@ -270,6 +321,8 @@ static inline void uxchg(volatile uint32_t* px, uint32_t nx) { :"memory" ); } +#endif + #define xchg __sync_lock_test_and_set // define a local socket for registering new storage queues diff --git a/nix/overlays.nix b/nix/overlays.nix index 0061ae02..9bf3f009 100644 --- a/nix/overlays.nix +++ b/nix/overlays.nix @@ -4,9 +4,9 @@ with final; let dbg = if debug == true then enableDebugging else (x: x); - nativeBuildInputs = [ cmake ninja python27 ]; + nativeBuildInputs = [ cmake ninja python310 ]; - buildInputs = [ ncurses readline zlib python27 ]; + buildInputs = [ ncurses readline zlib python310 ]; doCheck = true; diff --git a/scripts/fregion.py b/scripts/fregion.py index 674e3b60..9d18a03e 100755 --- a/scripts/fregion.py +++ b/scripts/fregion.py @@ -84,7 +84,7 @@ def __str__(self): return "{}".format(self.fn(*self.args, **self.kw)) def reader(self): - return self.fn.im_self + return self.fn.__self__ def LazyRead(enable): """ @@ -302,7 +302,7 @@ def freeVars(ty): return m def dictFreeVars(m): lm={} - for n, ty in m.items(): + for n, ty in list(m.items()): freeVarsInto(lm,ty) return lm def freeName(m): @@ -358,7 +358,7 @@ def substituteInAbs(m,a): def substitute(m,ty): tyDisp = { "prim": lambda p: Prim(p.name,substitute(m,p.rep)) if (p.rep != None) else p, - "var": lambda v: m[v.name] if (v.name in m.keys()) else v, + "var": lambda v: m[v.name] if (v.name in list(m.keys())) else v, "farr": lambda fa: FixedArr(substitute(m,fa.ty), substitute(m,fa.tlen)), "arr": lambda a: Arr(substitute(m,a.ty)), "variant": lambda v: substituteInVariant(m,v), @@ -532,7 +532,7 @@ def decodeLong(d, p): def decodeStr(d, p): n = decodeLong(d,p) - s = str(d[p.pos:p.pos+n]) + s = (d[p.pos:p.pos+n]).decode("utf-8") p.pos += n return s @@ -670,7 +670,7 @@ def __init__(self, fpath): # if reading the old format, we need to reinterpret recorded types if (self.version == 1): - for vn, b in self.env.items(): + for vn, b in list(self.env.items()): b.ty = V1toV2Type(b.ty) # read page data entries into the 'pages' argument @@ -710,7 +710,7 @@ def readEnvRecord(self, env, offset): vnlen = struct.unpack('Q', self.m[offset:offset+8])[0] offset += 8 - vn = str(self.m[offset:offset+vnlen]) + vn = (self.m[offset:offset+vnlen]).decode("utf-8") offset += vnlen tylen = struct.unpack('Q', self.m[offset:offset+8])[0] @@ -821,7 +821,8 @@ def read(self,m,offset): if (t == 0): return None else: - return self.jr.read(m,offset+self.poff) + x = self.jr.read(m,offset+self.poff) + return x class EnumView: def __init__(self, ns, t): @@ -879,7 +880,7 @@ def __init__(self): self.nr = UnpackReader('Q',8) def read(self,m,offset): n=self.nr.read(m,offset) - return m[offset+8:offset+8+n] + return m[offset+8:offset+8+n].decode("utf-8") class ArrReaderGenerator: def __init__(self, m, reader, size, offset): @@ -894,13 +895,13 @@ def __len__(self): def __call__(self): o = self.offset - for i in xrange(0, self.size): + for i in range(0, self.size): tv = self.get(i) o += self.vlen yield(tv) def __getitem__(self, i): - if not isinstance(i, (int,long)): + if not isinstance(i, int): raise StopIteration return self.get(i) @@ -969,7 +970,7 @@ def makeArrReader(renv,a): def makeVariantReader(renv,v): if (len(v.ctors)==2 and v.ctors[0][0] == ".f0" and v.ctors[0][1] == 0 and isinstance(v.ctors[0][2],Prim) and v.ctors[0][2].name == "unit"): return MaybeReader(renv,v.ctors[1][2]) - elif (all(map(lambda c: isinstance(c[2],Prim) and c[2].name=="unit", v.ctors))): + elif (all([isinstance(c[2],Prim) and c[2].name=="unit" for c in v.ctors])): return EnumReader(v.ctors) else: return VariantReader(renv,v.ctors) @@ -978,9 +979,9 @@ def makeStructReader(renv,s): if (len(s.fields) == 0): return UnitReader() elif (s.fields[0][0][0] == '.'): # should we read this as a tuple? - return TupleReader(renv, map(lambda f:f[2], s.fields)) + return TupleReader(renv, [f[2] for f in s.fields]) else: - return StructReader(renv, map(lambda f:f[0], s.fields), map(lambda f:f[2], s.fields)) + return StructReader(renv, [f[0] for f in s.fields], [f[2] for f in s.fields]) def makeAppReader(renv,app): if (isinstance(app.f,Prim)): @@ -1064,7 +1065,7 @@ class FRegion: def __init__(self, fpath): self.rep = FREnvelope(fpath) - for vn, bind in self.rep.env.items(): + for vn, bind in list(self.rep.env.items()): bind.reader = makeReader({}, bind.ty) @staticmethod @@ -1077,10 +1078,10 @@ def __repr__(self): vns = [] hts = [] tds = [] - for vn, bind in self.rep.env.items(): + for vn, bind in list(self.rep.env.items()): vns.append(vn) hts.append(' :: ') - tds.append(str(bind.ty)) + tds.append((bind.ty).decode("utf-8")) return tableFormat([vns, hts, tds]) def __getattr__(self, attr): @@ -1133,7 +1134,8 @@ def read(self,m,offset): if (o==0): return None else: - return self.r.read(m,o) + x = self.r.read(m,o) + return x # carrays (variable-length arrays stored with a static capacity) FRegion.addType("carray", lambda renv, ty, repty: makeArrReader(renv, Arr(ty.args[0]))) @@ -1178,7 +1180,7 @@ def __contains__(self,k): if (self.sl.count==0): return False else: - n=SLView.findNextGLEB(self.sl.root, len(self.sl.root.next)-1, k) + n=SLView.findNextGLEB(self.sl.root, len(self.sl.root.__next__)-1, k) return (not(n==None) and n.key==k) def __iter__(self): n=self.sl.root.next[0] @@ -1193,9 +1195,9 @@ def __repr__(self): vs=[] n=self.sl.root().next[0] while (not(n == None)): - ks.append(str(n.key)) + ks.append(n.key.decode("utf-8")) eqs.append(' = ') - vs.append(str(n.value)) + vs.append(n.value.decode("utf-8")) n=n.next[0] return tableFormat([ks,eqs,vs]) diff --git a/test/Python.C b/test/Python.C index 34fac67f..45d009dd 100644 --- a/test/Python.C +++ b/test/Python.C @@ -21,8 +21,9 @@ public: PythonProc(const std::string& py, const std::string& moddir, const std::string& script, const std::string& db) : py(py), moddir(moddir), script(script), db(db) { if(this->py.empty()) - this->py = "/usr/bin/python"; // Give a default python execute path + this->py = "/usr/bin/env"; // Nix can provide python3 or the OS this->argv.push_back(this->py.c_str()); + this->argv.push_back("python3"); this->argv.push_back(this->script.c_str()); this->argv.push_back(this->db.c_str()); this->argv.push_back(nullptr); // end @@ -246,8 +247,11 @@ def explode(s): r.append(s[i]) return r -expectCB=explode('chickens') -if (f.cbuffer[0:len(expectCB)] != expectCB): +expectCB='chickens' +if (b''.join(f.cbuffer[0:len(expectCB)]).decode('utf-8') != expectCB): + from pprint import pprint + pprint(f.cbuffer[0:len(expectCB)]) + pprint(expectCB) print("Expected 'cbuffer' to equal 'chickens': " + str(f.cbuffer)) sys.exit(-1)