+
+uintptr_t
+mono_array_handle_length (MonoArrayHandle arr)
+{
+ MONO_REQ_GC_UNSAFE_MODE;
+
+ return MONO_HANDLE_RAW (arr)->max_length;
+}
+
+uint32_t
+mono_gchandle_from_handle (MonoObjectHandle handle, mono_bool pinned)
+{
+ /* FIXME: chunk_element_to_chunk_idx does a linear search through the
+ * chunks and we only need it for the assert */
+ MonoThreadInfo *info = mono_thread_info_current ();
+ HandleStack *stack = (HandleStack*) info->handle_stack;
+ HandleChunkElem* elem = handle_to_chunk_element (handle);
+ int elem_idx = 0;
+ HandleChunk *chunk = chunk_element_to_chunk_idx (stack, elem, &elem_idx);
+ /* gchandles cannot deal with interior pointers */
+ g_assert (chunk != NULL);
+ return mono_gchandle_new (MONO_HANDLE_RAW (handle), pinned);
+}
+
+MonoObjectHandle
+mono_gchandle_get_target_handle (uint32_t gchandle)
+{
+ return MONO_HANDLE_NEW (MonoObject, mono_gchandle_get_target (gchandle));
+}
+
+gpointer
+mono_array_handle_pin_with_size (MonoArrayHandle handle, int size, uintptr_t idx, uint32_t *gchandle)
+{
+ g_assert (gchandle != NULL);
+ *gchandle = mono_gchandle_from_handle (MONO_HANDLE_CAST(MonoObject,handle), TRUE);
+ MonoArray *raw = MONO_HANDLE_RAW (handle);
+ return mono_array_addr_with_size (raw, size, idx);
+}
+
+gunichar2*
+mono_string_handle_pin_chars (MonoStringHandle handle, uint32_t *gchandle)
+{
+ g_assert (gchandle != NULL);
+ *gchandle = mono_gchandle_from_handle (MONO_HANDLE_CAST (MonoObject, handle), TRUE);
+ MonoString *raw = MONO_HANDLE_RAW (handle);
+ return mono_string_chars (raw);
+}
+
+gpointer
+mono_object_handle_pin_unbox (MonoObjectHandle obj, uint32_t *gchandle)
+{
+ g_assert (!MONO_HANDLE_IS_NULL (obj));
+ MonoClass *klass = mono_handle_class (obj);
+ g_assert (klass->valuetype);
+ *gchandle = mono_gchandle_from_handle (obj, TRUE);
+ return mono_object_unbox (MONO_HANDLE_RAW (obj));
+}
+
+void
+mono_array_handle_memcpy_refs (MonoArrayHandle dest, uintptr_t dest_idx, MonoArrayHandle src, uintptr_t src_idx, uintptr_t len)
+{
+ mono_array_memcpy_refs (MONO_HANDLE_RAW (dest), dest_idx, MONO_HANDLE_RAW (src), src_idx, len);
+}
+
+gboolean
+mono_handle_stack_is_empty (HandleStack *stack)
+{
+ return (stack->top == stack->bottom && stack->top->size == 0);
+}