[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