| 27 | } |
| 28 | |
| 29 | ValueRefList InterpreterTransformation::apply_op( |
| 30 | const ApplyOp& apply_op, Span<ValueRef> inputs) { |
| 31 | SmallVector<Handle> input_handles; |
| 32 | SmallVector<Handle> output_handles; |
| 33 | CleanupGuard _{[&] { |
| 34 | for (auto handle : output_handles) { |
| 35 | if (handle) { |
| 36 | m_channel->del(handle); |
| 37 | } |
| 38 | } |
| 39 | }}; |
| 40 | for (auto input : inputs) { |
| 41 | input_handles.push_back(input.cast(m_value_type).handle()->handle()); |
| 42 | } |
| 43 | m_channel->set_backtrace(Transformation::get_context().bt); |
| 44 | output_handles = |
| 45 | m_channel->apply_op(apply_op.op().shared_from_this(), input_handles); |
| 46 | ValueRefList outputs(output_handles.size()); |
| 47 | for (size_t i = 0; i < output_handles.size(); ++i) { |
| 48 | outputs[i] = m_value_type.make(share_handle(output_handles[i])); |
| 49 | output_handles[i] = nullptr; |
| 50 | } |
| 51 | output_handles.clear(); |
| 52 | m_channel->clear_backtrace(); |
| 53 | return outputs; |
| 54 | } |
| 55 | |
| 56 | ValueRefList InterpreterTransformation::apply_get_attr( |
| 57 | const GetAttr& get_attr, Span<ValueRef> inputs) { |