All pastes #30709 Raw Edit

Something

public text v1 · immutable
#30709 ·published 2005-11-23 21:26 UTC
rendered paste body
Index: mini.c
===================================================================
--- mini.c      (revision 53280)
+++ mini.c      (working copy)
@@ -2568,13 +2568,54 @@

        return mono_emit_jit_icall (cfg, bblock, alloc_ftn, iargs, ip);
 }
+
+/** is klass Nullable<T>? */
+static gboolean
+type_is_nullable (MonoClass* klass)
+{
+       return klass->generic_class != NULL &&
+               klass->generic_class->container_class == mono_defaults.generic_nullable_class;
+}
+
+/** if klass is T? return T */
+static MonoClass*
+type_get_nullable_param (MonoClass* klass)
+{
+       g_assert (type_is_nullable (klass));
+
+       return klass->generic_class->inst->type_argv [0];
+}
+
+
+
+/**
+ * Handles unbox of a Nullable<T>, returning a temp variable
+ * where the result is stored
+ */
+static int
+handle_unbox_nullable (MonoCompile* cfg, MonoBasicBlock* bblock, MonoInst* val, const guchar *ip, MonoClass* klass)
+{
+       MonoMethod* method = mono_class_get_method_from_name (klass, "Unbox", 1);
+       return mono_emit_method_call_spilled (cfg, bblock, method, mono_method_signature (method), &val, ip, NULL);

+}
+
+
+
 static MonoInst *
 handle_box (MonoCompile *cfg, MonoBasicBlock *bblock, MonoInst *val, const guchar *ip, MonoClass *klass)
 {
        MonoInst *dest, *vtoffset, *add, *vstore;
        int temp;

+       if (type_is_nullable (klass)) {
+               MonoMethod* method = mono_class_get_method_from_name (klass, "Box", 1);
+               temp = mono_emit_method_call_spilled (cfg, bblock, method, mono_method_signature (method), &val, ip, NULL);
+               NEW_TEMPLOAD (cfg, dest, temp);
+               return dest;
+       }
+
+
        temp = handle_alloc (cfg, bblock, klass, TRUE, ip);
        NEW_TEMPLOAD (cfg, dest, temp);
        NEW_ICONST (cfg, vtoffset, sizeof (MonoObject));
@@ -5039,6 +5080,15 @@
                                break;
                        }

+                       if (type_is_nullable (klass)) {
+                               int v = handle_unbox_nullable (cfg, bblock, *sp, ip, klass);
+                               NEW_TEMPLOAD (cfg, *sp, v);
+                               sp ++;
+                               ip += 5;
+                               break;
+
+                       }
+
                        MONO_INST_NEW (cfg, ins, OP_UNBOXCAST);
                        ins->type = STACK_OBJ;
                        ins->inst_left = *sp;
@@ -5089,6 +5139,15 @@
                        if (!klass)
                                goto load_error;

+                       if (type_is_nullable (klass)) {
+                               int v = handle_unbox_nullable (cfg, bblock, *sp, ip, klass);
+                               NEW_TEMPLOADA (cfg, *sp, v);
+                               sp ++;
+                               ip += 5;
+                               break;
+                       }
+
+
                        /* Needed by the code generated in inssel.brg */
                        mono_get_got_var (cfg);