+ for (uint i = 0; i < spib->objlist_len; i++) {
+ Object *obj = ids->lookup(spib->objlist[i]);
+
+ if (!obj)
+ throw_idl(InvalidReference, i, nullarray);
+
+ dpib->objlist[i] = reinterpret_cast<uintptr_t>(obj);
+ }
+ }
+
+ void invoke_method(ParamInfoBlock *user_pib, uintptr_t &stack)
+ {
+ printf("invoke_method: pib %p\n", user_pib);
+
+ ParamInfoBlock pib = Arch::copyin(user_pib);
+ printf("objlist len %u\n", pib.objlist_len);
+
+ if (pib.objlist_len == 0)
+ throw_idl(InvalidArgument, 0, countarray("no objects"));
+
+ // FIXME: declare constants somewhere
+ if (pib.num_segments > 64)
+ throw_idl(InvalidArgument, 0, countarray("too many segments"));
+ if (pib.objlist_len > 4096)
+ throw_idl(InvalidArgument, 0, countarray("too many objects"));
+
+ printf("&pib.objlist[0] %p\n", &pib.objlist[0]);
+
+ IDSpace *ids = &curthread->aspace->idspace;
+ ID objid = Arch::copyin(&pib.objlist[0]);
+ Object *obj = ids->lookup(objid);
+
+ if (!obj) {
+ printf("no obj %d\n", objid);
+ throw_idl(InvalidReference, 0, nullarray);
+ }
+
+ printf("obj %p\n", obj);
+
+ if (obj->aspace == Arch::init_thread->aspace) {
+ KernObject *ko = static_cast<KernObject *>(obj);
+ int datalen = round_up(pib.buffer_size, 8);
+ int buflen = datalen + pib.objlist_len * sizeof(void *);
+ int piboff = datalen;
+ buflen += sizeof(ParamInfoBlock);
+ buflen += pib.num_segments * sizeof(ParamInfoBlock::Segment);
+
+ u8 *args = new(orbmm) u8[buflen];
+ u8 *copy = new(orbmm) u8[pib.copy_size];
+ ParamInfoBlock *dpib = reinterpret_cast<ParamInfoBlock *>
+ (args + piboff);
+ dpib->objlist = reinterpret_cast<ID *>(args + datalen);
+
+ copy_ids_to_kern(dpib, &pib, ids);
+ copy_data(args, args, pib.buffer_size, dpib, &pib, ~0U, Segment::In);
+ copy_data(copy, copy, pib.copy_size, dpib, &pib, ~0U,
+ Segment::In | Segment::Copy);
+
+ ko->entry(dpib);
+
+ // FIXME: Copy return data
+ return;
+ }
+
+ CallFrame *frame = new_frame(curthread);
+ frame->caller_user_pib = user_pib;
+ frame->ret_stack = stack;
+
+ printf("invoke_method: frame %p pib %p ret_stack %lx obj %p\n",
+ frame, frame->caller_user_pib,
+ frame->ret_stack, obj);
+ }