[svn:parrot] r39645 - in branches/pmc_pct/compilers/pmcc/src: . emitter parser

cotto at svn.parrot.org cotto at svn.parrot.org
Thu Jun 18 07:55:17 UTC 2009


Author: cotto
Date: Thu Jun 18 07:55:16 2009
New Revision: 39645
URL: https://trac.parrot.org/parrot/changeset/39645

Log:
[pmcc] generate the first part of the first pass of class_init

Modified:
   branches/pmc_pct/compilers/pmcc/src/builtins.pir
   branches/pmc_pct/compilers/pmcc/src/emitter/pmc.pm
   branches/pmc_pct/compilers/pmcc/src/nodes.pir
   branches/pmc_pct/compilers/pmcc/src/parser/actions.pm

Modified: branches/pmc_pct/compilers/pmcc/src/builtins.pir
==============================================================================
--- branches/pmc_pct/compilers/pmcc/src/builtins.pir	Thu Jun 18 07:51:40 2009	(r39644)
+++ branches/pmc_pct/compilers/pmcc/src/builtins.pir	Thu Jun 18 07:55:16 2009	(r39645)
@@ -43,6 +43,70 @@
     .return ($P0)
 .end
 
+
+=item deep_clone
+
+Create a deep clone of C<what>.  Note: This sub assumes that any element of
+C<what> which doesn't provide scalar is an aggregate PMC.  It also assumes that
+any nested aggregates work correctly with iterators and can be resized.  This
+is not intended to be a general-use sub.
+
+=cut
+
+.include 'iterator.pasm'
+
+.sub 'deep_clone'
+    .param pmc what
+
+    .local int does_scalar, does_hash, does_array
+    does_scalar = does what, 'scalar'
+    does_hash   = does what, 'hash'
+    does_array  = does what, 'array'
+    if does_scalar == 1 goto clone_scalar
+  
+  clone_aggregate:
+    .local pmc it, key, val, cloned, cloned_val
+    .local int i
+
+    cloned = clone what
+    it = iter what
+    if does_hash goto hash_iter_loop
+    unless does_array goto idk
+
+    i = 0
+  array_iter_loop:
+    unless it goto array_iter_end
+    val = shift it
+    (cloned_val) = 'deep_clone'(val)
+    cloned[i] = cloned_val
+    i += 1
+    goto array_iter_loop
+  array_iter_end:
+    .return (cloned)
+
+  hash_iter_loop:
+    unless it goto hash_iter_end
+    key = shift it
+    $S0 = typeof key
+    val = what[key]
+    (cloned_val) = 'deep_clone'(val)
+    cloned[key] = cloned_val
+    goto hash_iter_loop
+  hash_iter_end:
+    .return (cloned)
+
+  clone_scalar:
+    $P0 = clone what
+    .return ($P0)
+
+  idk:
+    $P0 = new ['Exception']
+    $S0 = typeof what
+    $S0 = concat "don't know how to clone ", $S0
+    $P0['message'] = $S0
+    throw $P0
+.end
+
 .sub 'substr'
     .param string orig
     .param int    from
@@ -51,6 +115,17 @@
     .return ($S0)
 .end
 
+.sub 'chars'
+    .param string s
+    $I0 = length s
+    .return ($I0)
+.end
+
+.sub 'elements'
+    .param pmc p
+    $I0 = elements p
+    .return ($I0)
+.end
 
 # Extend various Parrot's PMCs to play nicely with NQP.
 .namespace ['Hash']

Modified: branches/pmc_pct/compilers/pmcc/src/emitter/pmc.pm
==============================================================================
--- branches/pmc_pct/compilers/pmcc/src/emitter/pmc.pm	Thu Jun 18 07:51:40 2009	(r39644)
+++ branches/pmc_pct/compilers/pmcc/src/emitter/pmc.pm	Thu Jun 18 07:55:16 2009	(r39645)
@@ -455,7 +455,53 @@
 
 method generate_passes() {
     my @res;
+    my $enum_name;
+    my $name := self.name;
+    my $provides := join(' ', self.past.provides);
+
+    #not sure if this is the best place for such code
+    if elements(self.past.provides) == 0 {
+        self.past.provides.push('scalar');
+    }
+
+    if self.past.traits{'dynpmc'} {
+        $enum_name := '-1';
+    }
+    else {
+        $enum_name := 'enum_class_'~ self.name;
+    }
+
+
+    #first pass
+
+    @res.push('    if (pass == 0) {');
+    @res.push('        Hash    *isa_hash  = NULL;');
+    @res.push('        VTABLE * const vt  = Parrot_'~ self.name ~'_get_vtable(interp);');
+    @res.push('        vt->base_type      = '~ $enum_name ~';');
+    @res.push('        vt->flags          = '~ self.vtable_flags ~';');
+    @res.push('        vt->attribute_defs = attr_defs;');
+    @res.push('        interp->vtables[entry] = vt;');
+
+    if self.past.traits{'dynpmc'} {
+        my $name_length := chars(self.name);
+        my $provides_length := chars($provides);
+
+        @res.push('        vt->base_type    = entry;');
+        @res.push('        vt->whoami       = string_make(interp, "'~ self.name ~'", '~ $name_length ~',');
+        @res.push('            "ascii", PObj_constant_FLAG|PObj_external_FLAG);');
+        @res.push('        vt->provides_str = Parrot_str_append(interp, vt->provides_str,');
+        @res.push('            string_make(interp, "'~ $provides ~'", '~ $provides_length  ~', "ascii",');
+        @res.push('            PObj_constant_FLAG|PObj_external_FLAG));');
+
+    }
+    else {
+        @res.push('         vt->whoami       = CONST_STRING_GEN(interp, "'~ self.name ~'");');
+        @res.push('         vt->provides_str = CONST_STRING_GEN(interp, "' ~$provides ~'");');
+    }
 
+
+
+    #second pass
 ## Cotto, this is last bit of second pass.
 ##        {
 ## #define N_MULTI_LIST (sizeof(_temp_multi_func_list)/sizeof(_temp_multi_func_list[0]))
@@ -463,10 +509,12 @@
 ##                _temp_multi_func_list, N_MULTI_LIST);
 ##        }
 
-    "";
+    join("\n", @res);
 }
 
 
+
+
 =item C<get_vtable_func>
 
 Generate C-code for get_vtable_func
@@ -501,6 +549,10 @@
     self.past.vtables;
 }
 
+method attr() {
+    self.past.attr;
+}
+
 method generate_signature($entry, $name, $prefix) {
     my @res;
 
@@ -531,6 +583,7 @@
 Method for generating PMC-specific VTABLE functions. E.g. C<default> and C<null> implementations.
 
 =cut
+
 method pre_method_gen() {
 }
 
@@ -539,6 +592,7 @@
 Generate code for register MULTIs.
 
 =cut
+
 method generate_multis() {
     # Result holder.
     my @res;
@@ -609,6 +663,40 @@
     join('', @res);
 }
 
+
+=item C<get_vtable_flags()>
+
+Returns C code to produce a PMC's flags.
+
+=cut
+
+method vtable_flags() {
+
+    my @flags;
+
+    if self.past.traits{'need_ext'} {
+        @flags.push('VTABLE_PMC_NEEDS_EXT');
+    }
+    if self.past.traits{'singleton'} {
+        @flags.push('VTABLE_PMC_IS_SINGLETON');
+    }
+    if self.past.traits{'is_shared'} {
+        @flags.push('VTABLE_IS_SHARED_FLAG');
+    }
+    if self.past.traits{'is_ro'} {
+        @flags.push('VTABLE_IS_READONLY_FLAG');
+    }
+    if self.past.traits{'has_ro'} {
+        @flags.push('VTABLE_HAS_READONLY_FLAG');
+    }
+    if !@flags {
+        @flags.push('0');
+    }
+
+    join('|', at flags);
+}
+
+
 method past() {
     self<past>;
 }

Modified: branches/pmc_pct/compilers/pmcc/src/nodes.pir
==============================================================================
--- branches/pmc_pct/compilers/pmcc/src/nodes.pir	Thu Jun 18 07:51:40 2009	(r39644)
+++ branches/pmc_pct/compilers/pmcc/src/nodes.pir	Thu Jun 18 07:55:16 2009	(r39645)
@@ -60,6 +60,9 @@
     $P1 = new 'ResizableStringArray'
     res.'attr'('provides', $P1, 1)
 
+    $P1 = new 'Hash'
+    res.'attr'('traits', $P1, 1)
+
     .return (res)
 .end
 
@@ -133,6 +136,16 @@
     .tailcall self.'attr'('attrs',0,0)
 .end
 
+=item C<traits>
+
+Get PMC traits.
+
+=cut
+
+.sub 'traits' :method
+    .tailcall self.'attr'('traits',0,0)
+.end
+
 
 =item C<unfreeze_attrs>
 
@@ -211,19 +224,6 @@
 .end
 
 
-=item C<set_trait>
-
-Set boolean trait
-
-=cut
-
-.sub 'trait' :method
-    .param string name
-    .param int value        :optional
-    .param int has_value    :opt_flag
-    .tailcall self.'attr'(name, value, has_value)
-.end
-
 =item C<add_class_init>
 
 Add a class_init function to PMC.

Modified: branches/pmc_pct/compilers/pmcc/src/parser/actions.pm
==============================================================================
--- branches/pmc_pct/compilers/pmcc/src/parser/actions.pm	Thu Jun 18 07:51:40 2009	(r39644)
+++ branches/pmc_pct/compilers/pmcc/src/parser/actions.pm	Thu Jun 18 07:55:16 2009	(r39645)
@@ -47,13 +47,14 @@
         $?PMC.unfreeze_pmc_attrs(~$<identifier>);
     }
     elsif $key eq 'provides' {
+        $?PMC.provides().push(~$<identifier>);
     }
     elsif $key eq 'group' {
     }
     elsif $key eq 'lib' {
     }
     else {
-        $?PMC.trait(~$/, 1);
+        $?PMC.traits{$key} := 1;
     }
 }
 


More information about the parrot-commits mailing list