14:02 < whiteknight> would like to add a new VTABLE_init_int, which would allow initialization from an integer 14:03 < whiteknight> Would allow preallocation of things like Fixed*Array, Integer, CallContext, etc 14:04 < whiteknight> Coke: you would have to create a throwaway Integer PMC to do the same thing
14:07 < Coke> NotFound: new $P1, ['Array'],  5
14:07 < allison> I am in favor or ways to avoid creating intermediate throw-away PMCs
14:07 < whiteknight> $P0 = new ['FixedIntegerArray'], 10


diff --git a/include/parrot/pmc.h b/include/parrot/pmc.h
index 3589358..a708185 100644
--- a/include/parrot/pmc.h
+++ b/include/parrot/pmc.h
@@ -89,6 +89,13 @@ PMC * Parrot_pmc_new_init(PARROT_INTERP,
 
 PARROT_EXPORT
 PARROT_CANNOT_RETURN_NULL
+PMC * Parrot_pmc_new_init_int(PARROT_INTERP,
+    INTVAL base_type,
+    INTVAL init)
+        __attribute__nonnull__(1);
+
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
 PMC * Parrot_pmc_new_noinit(PARROT_INTERP, INTVAL base_type)
         __attribute__nonnull__(1);
 
diff --git a/src/ops/experimental.ops b/src/ops/experimental.ops
index ce0fb2e..861ee23 100644
--- a/src/ops/experimental.ops
+++ b/src/ops/experimental.ops
@@ -235,6 +235,62 @@ inline op vivify(out PMC, in PMC, in STR, in PMC) :base_core {
     }
 }
 
+=over 4
+
+=item B<new>(out PMC, in STR, in INT)
+
+=item B<new>(out PMC, in PMC, in INT)
+
+=back
+
+=cut
+
+
+op new(out PMC, in STR, in INT) {
+    STRING * const name   = $2;
+    PMC    * const _class = Parrot_pcc_get_HLL(interp, CURRENT_CONTEXT(interp))
+                          ? Parrot_oo_get_class_str(interp, name)
+                          : PMCNULL;
+
+    if (!PMC_IS_NULL(_class)) {
+        PMC *initial = Parrot_pmc_new(interp, Parrot_get_ctx_HLL_type(interp, enum_class_Integer));
+        VTABLE_set_integer_native(interp, initial, $3);
+        $1 = VTABLE_instantiate(interp, _class, initial);
+    }
+    else {
+        const INTVAL type = Parrot_pmc_get_type_str(interp, name);
+        if (type <= 0) {
+            opcode_t *dest = Parrot_ex_throw_from_op_args(interp, expr NEXT(),
+                EXCEPTION_NO_CLASS,
+                "Class '%Ss' not found", name);
+            goto ADDRESS(dest);
+        }
+        $1 = Parrot_pmc_new_init_int(interp, type, $3);
+    }
+}
+
+
+op new(out PMC, in PMC, in INT) {
+    PMC * const name_key = $2;
+    PMC * const _class   = Parrot_oo_get_class(interp, name_key);
+
+    if (!PMC_IS_NULL(_class)) {
+        PMC *initial = Parrot_pmc_new(interp, Parrot_get_ctx_HLL_type(interp, enum_class_Integer));
+        VTABLE_set_integer_native(interp, initial, $3);
+        $1 = VTABLE_instantiate(interp, _class, initial);
+    }
+    else {
+        const INTVAL type = Parrot_pmc_get_type(interp, name_key);
+        if (type <= 0) {
+            opcode_t *dest = Parrot_ex_throw_from_op_args(interp, expr NEXT(),
+                EXCEPTION_NO_CLASS,
+                "Class '%Ss' not found", VTABLE_get_repr(interp, name_key));
+            goto ADDRESS(dest);
+        }
+        $1 = Parrot_pmc_new_init_int(interp, type, $3);
+    }
+}
+
 =head1 COPYRIGHT
 
 Copyright (C) 2001-2009, Parrot Foundation.
diff --git a/src/pmc.c b/src/pmc.c
index 76167b9..78383e2 100644
--- a/src/pmc.c
+++ b/src/pmc.c
@@ -564,6 +564,35 @@ Parrot_pmc_new_init(PARROT_INTERP, INTVAL base_type, ARGOUT(PMC *init))
 
 /*
 
+=item C<PMC * Parrot_pmc_new_init(PARROT_INTERP, INTVAL base_type, INTVAL init)>
+
+As C<Parrot_pmc_new()>, but passes C<init> to the PMC's C<init_int()> vtable entry.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+PMC *
+Parrot_pmc_new_init_int(PARROT_INTERP, INTVAL base_type, INTVAL init)
+{
+    ASSERT_ARGS(Parrot_pmc_new_init)
+    PMC *const classobj = interp->vtables[base_type]->pmc_class;
+
+    if (!PMC_IS_NULL(classobj) && PObj_is_class_TEST(classobj))
+        return VTABLE_instantiate(interp, classobj, init);
+    else {
+        PMC * const pmc = get_new_pmc_header(interp, base_type, 0);
+        VTABLE_init_int(interp, pmc, init);
+        return pmc;
+    }
+}
+
+
+
+/*
+
 =item C<PMC * Parrot_pmc_new_constant_init(PARROT_INTERP, INTVAL base_type, PMC
 *init)>
 
diff --git a/src/vtable.tbl b/src/vtable.tbl
index 70eafab..0aa80ec 100644
--- a/src/vtable.tbl
+++ b/src/vtable.tbl
@@ -281,3 +281,5 @@ void visit (PMC* info)
 void share()
 
 PMC* share_ro()
+
+void init_int(INTVAL initializer)
_______________________________________________
http://lists.parrot.org/mailman/listinfo/parrot-dev

Reply via email to