diff --git a/artiq/firmware/runtime/session.rs b/artiq/firmware/runtime/session.rs index 4947fe17c..23760e038 100644 --- a/artiq/firmware/runtime/session.rs +++ b/artiq/firmware/runtime/session.rs @@ -277,6 +277,11 @@ fn process_host_message(io: &Io, } })?; rpc::recv_return(stream, &tag, slot, &|size| -> Result<_, Error> { + if size == 0 { + // Don't try to allocate zero-length values, as RpcRecvReply(0) is + // used to terminate the kernel-side receive loop. + return Ok(0 as *mut ()) + } kern_send(io, &kern::RpcRecvReply(Ok(size)))?; Ok(kern_recv(io, |reply| { match reply { diff --git a/artiq/test/coredevice/test_embedding.py b/artiq/test/coredevice/test_embedding.py index d9757b733..38e1a3d07 100644 --- a/artiq/test/coredevice/test_embedding.py +++ b/artiq/test/coredevice/test_embedding.py @@ -363,9 +363,27 @@ class _NestedTupleList(EnvExperiment): if a != self.data: raise ValueError + +class _EmptyList(EnvExperiment): + def build(self): + self.setattr_device("core") + + def get_empty(self) -> TList(TInt32): + return [] + + @kernel + def run(self): + a = self.get_empty() + if a != []: + raise ValueError + + class ListTupleTest(ExperimentCase): def test_list_tuple(self): self.create(_ListTuple).run() def test_nested_tuple_list(self): self.create(_NestedTupleList).run() + + def test_empty_list(self): + self.create(_EmptyList).run()