diff --git a/artiq/firmware/libproto_artiq/rpc_proto.rs b/artiq/firmware/libproto_artiq/rpc_proto.rs index 8c39251f7..dfd1a1dfa 100644 --- a/artiq/firmware/libproto_artiq/rpc_proto.rs +++ b/artiq/firmware/libproto_artiq/rpc_proto.rs @@ -151,11 +151,11 @@ unsafe fn send_value(writer: &mut W, tag: Tag, data: &mut *const ()) Ok(()) } Tag::Keyword(it) => { - struct Keyword<'a> { name: CSlice<'a, u8>, contents: () }; + struct Keyword<'a> { name: CSlice<'a, u8> }; consume_value!(Keyword, |ptr| { writer.write_string(str::from_utf8((*ptr).name.as_ref()).unwrap())?; let tag = it.clone().next().expect("truncated tag"); - let mut data = &(*ptr).contents as *const (); + let mut data = ptr.offset(1) as *const (); send_value(writer, tag, &mut data) }) // Tag::Keyword never appears in composite types, so we don't have diff --git a/artiq/test/coredevice/test_portability.py b/artiq/test/coredevice/test_portability.py index cd301d29b..2238ea805 100644 --- a/artiq/test/coredevice/test_portability.py +++ b/artiq/test/coredevice/test_portability.py @@ -202,6 +202,20 @@ class _RPCExceptions(EnvExperiment): self.success = True +class _Keywords(EnvExperiment): + def build(self, value, output): + self.setattr_device("core") + self.value = value + self.output = output + + def rpc(self, kw): + self.output.append(kw) + + @kernel + def run(self): + self.rpc(kw=self.value) + + class HostVsDeviceCase(ExperimentCase): def test_primes(self): l_device, l_host = [], [] @@ -245,3 +259,18 @@ class HostVsDeviceCase(ExperimentCase): f(_RPCExceptions, catch=False) uut = self.execute(_RPCExceptions, catch=True) self.assertTrue(uut.success) + + def test_keywords(self): + for f in self.execute, _run_on_host: + output = [] + f(_Keywords, value=0, output=output) + self.assertEqual(output, [0]) + output = [] + f(_Keywords, value=1, output=output) + self.assertEqual(output, [1]) + output = [] + f(_Keywords, value=False, output=output) + self.assertEqual(output, [False]) + output = [] + f(_Keywords, value=True, output=output) + self.assertEqual(output, [True])