diff --git a/build.bat b/build.bat new file mode 100644 index 0000000..1d52bfc --- /dev/null +++ b/build.bat @@ -0,0 +1,2 @@ +call "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" x64 +cl /O2 src\coparun\runmem.c src\coparun\coparun.c src\coparun\mem_man.c /Fe:bin\coparun.exe \ No newline at end of file diff --git a/src/copapy/__init__.py b/src/copapy/__init__.py index dbb7ce2..457a01f 100644 --- a/src/copapy/__init__.py +++ b/src/copapy/__init__.py @@ -354,6 +354,7 @@ def compile_to_instruction_list(node_list: Iterable[Node], sdb: stencil_database for variable in variable_list: lengths = sdb.var_size['dummy_' + variable.dtype] + print('variable_mem_layout', variable.dtype, lengths) object_list.append((variable, offset, lengths)) offset += (lengths + 3) // 4 * 4 @@ -460,6 +461,7 @@ class Target(): def read_value(self, net: Net) -> float | int: assert net in self._variables, f"Variable {net} not found" addr, lengths, var_type = self._variables[net] + print('read_value', addr, lengths) data = read_data_mem(addr, lengths) assert data is not None and len(data) == lengths, f"Failed to read variable {net}" en = {'little': '<', 'big': '>'}[self.sdb.byteorder] @@ -481,12 +483,17 @@ class Target(): raise ValueError(f"Unsupported int length: {lengths} bytes") else: raise ValueError(f"Unsupported variable type: {var_type}") + def read_variable_remote(self, net: Net) -> None: - assert net in self._variables, f"Variable {net} not found in data writer variables" - addr, lengths, _ = self._variables[net] dw = binw.data_writer(self.sdb.byteorder) - dw.write_com(binw.Command.READ_DATA) - dw.write_int(addr) - dw.write_int(lengths) + add_read_command(dw, self._variables, net) assert coparun(dw.get_data()) > 0 + +def add_read_command(dw: binw.data_writer, variables: dict[Net, tuple[int, int, str]], net: Net) -> None: + assert net in variables, f"Variable {net} not found in data writer variables" + addr, lengths, _ = variables[net] + dw.write_com(binw.Command.READ_DATA) + dw.write_int(addr) + dw.write_int(lengths) + diff --git a/src/coparun/runmem.c b/src/coparun/runmem.c index 27f8d7d..197b7ae 100644 --- a/src/coparun/runmem.c +++ b/src/coparun/runmem.c @@ -38,7 +38,7 @@ int parse_commands(uint8_t *bytes) { uint32_t command; uint32_t reloc_type; uint32_t offs; - int data_offs; + ptrdiff_t data_offs; uint32_t size; int err_flag = 0; uint32_t rel_entr_point; @@ -89,7 +89,7 @@ int parse_commands(uint8_t *bytes) { offs = *(uint32_t*)bytes; bytes += 4; reloc_type = *(uint32_t*)bytes; bytes += 4; value = *(int32_t*)bytes; bytes += 4; - data_offs = (int32_t)(data_memory - executable_memory); + data_offs = data_memory - executable_memory; printf("PATCH_OBJECT patch_offs=%i reloc_type=%i value=%i data_offs=%i\n", offs, reloc_type, value, data_offs); if (abs(data_offs) > 0x7FFFFFFF) { diff --git a/tests/test_coparun_module.py b/tests/test_coparun_module.py index 58142e0..9df01a1 100644 --- a/tests/test_coparun_module.py +++ b/tests/test_coparun_module.py @@ -1,6 +1,6 @@ from copapy import const, Target from pytest import approx - +import time def function(c1, c2): i1 = c1 * 3.3 + 5 @@ -19,14 +19,17 @@ def test_compile(): ret = function(c1, c2) tg = Target() + print('* compile and copy ...') tg.compile(ret) - tg.run() + #time.sleep(5) + print('* run and copy ...') + #tg.run() + #print('* finished') ret_ref = function(4, 2) - print() - for test, ref, name in zip(ret, ret_ref, ['i1', 'i2', 'r1', 'r2']): + print('+', name) assert tg.read_value(test) == approx(ref, 1e-5), name diff --git a/tests/test_crash_win.py b/tests/test_crash_win.py new file mode 100644 index 0000000..070287b --- /dev/null +++ b/tests/test_crash_win.py @@ -0,0 +1,56 @@ +from copapy import Write, const +import copapy +import subprocess +import struct +from copapy import binwrite + + +def run_command(command: list[str], encoding: str = 'utf8') -> str: + process = subprocess.Popen(command, stdout=subprocess.PIPE) + output, error = process.communicate() + + assert error is None, f"Error occurred: {error.decode(encoding)}" + return output.decode(encoding) + + +def function(c1, c2): + i1 = c1 * 3.3 + 5 + i2 = c2 * 5 + c1 + r1 = i1 + i2 * 55 / 4 + r2 = 4 * i2 + 5 + + return i1, i2, r1, r2 + + +def test_compile(): + + c1 = const(4) + c2 = const(2) + + ret = function(c1, c2) + + dw, variable_list = copapy.compile_to_instruction_list([Write(net) for net in ret], copapy.generic_sdb) + + # run program command + dw.write_com(binwrite.Command.RUN_PROG) + dw.write_int(0) + + dw.write_com(binwrite.Command.READ_DATA) + dw.write_int(0) + dw.write_int(36) + + for net, name in zip(ret, ['i1', 'i2', 'r1', 'r2']): + print('+', name) + copapy.add_read_command(dw, variable_list, net) + + dw.write_com(binwrite.Command.END_PROG) + + dw.to_file('bin/test.copapy') + result = run_command(['bin/coparun', 'bin/test.copapy']) + print('* Output from runner:') + print(result) + assert 'Return value: 1' in result + +if __name__ == "__main__": + #test_example() + test_compile()