[svn:parrot-pdd] r26309 - in trunk: . compilers/bcg/src/pmc compilers/imcc config/auto config/init/hints docs docs/dev docs/pdds docs/pdds/draft include/parrot languages/APL/src/pmc languages/WMLScrip

Author: allison
Date: Tue Mar 11 02:50:21 2008
New Revision: 26309

Modified:
   trunk/docs/pdds/draft/pdd04_datatypes.pod
   trunk/docs/pdds/pdd17_pmc.pod

Changes in other areas also in this revision:
Added:
   trunk/lib/Parrot/Pmc2c/Attribute.pm
      - copied unchanged from r26307, /branches/pdd17pmc/lib/Parrot/Pmc2c/Attribute.pm
   trunk/tools/dev/vtablize.pl
      - copied unchanged from r26307, /branches/pdd17pmc/tools/dev/vtablize.pl
Modified:
   trunk/MANIFEST
   trunk/compilers/bcg/src/pmc/bcg.pmc
   trunk/compilers/imcc/pbc.c
   trunk/config/auto/pmc.pm
   trunk/config/init/hints/darwin.pm
   trunk/docs/dev/pccmethods.pod
   trunk/docs/pmc2c.pod
   trunk/docs/strings.pod
   trunk/include/parrot/events.h
   trunk/include/parrot/global.h
   trunk/include/parrot/misc.h
   trunk/include/parrot/oo_private.h
   trunk/include/parrot/pobj.h
   trunk/include/parrot/scheduler_private.h
   trunk/include/parrot/stacks.h
   trunk/languages/APL/src/pmc/aplvector.pmc
   trunk/languages/WMLScript/config/makefiles/root.in
   trunk/languages/WMLScript/pmc/wmlsboolean.pmc
   trunk/languages/WMLScript/pmc/wmlsfloat.pmc
   trunk/languages/WMLScript/pmc/wmlsinteger.pmc
   trunk/languages/WMLScript/pmc/wmlsinvalid.pmc
   trunk/languages/WMLScript/pmc/wmlsstring.pmc
   trunk/languages/amber/lib/kernel/pmc/amber_integer.pmc
   trunk/languages/lua/pmc/lua.pmc
   trunk/languages/lua/pmc/luaany.pmc
   trunk/languages/lua/pmc/luaboolean.pmc
   trunk/languages/lua/pmc/luaclosure.pmc
   trunk/languages/lua/pmc/luafunction.pmc
   trunk/languages/lua/pmc/luanil.pmc
   trunk/languages/lua/pmc/luanumber.pmc
   trunk/languages/lua/pmc/luastring.pmc
   trunk/languages/lua/pmc/luatable.pmc
   trunk/languages/lua/pmc/luathread.pmc
   trunk/languages/lua/pmc/luauserdata.pmc
   trunk/languages/lua/t/boolean.t
   trunk/languages/lua/t/functions.t
   trunk/languages/lua/t/nil.t
   trunk/languages/lua/t/number.t
   trunk/languages/lua/t/threads.t
   trunk/languages/lua/t/userdata.t
   trunk/languages/perl6/src/pmc/perl6bool.pmc
   trunk/languages/perl6/src/pmc/perl6str.pmc
   trunk/languages/perl6/src/pmc/perl6undef.pmc
   trunk/languages/pugs/pmc/pugscapture.pmc
   trunk/languages/regex/pmc/matchrange.pmc
   trunk/languages/tcl/runtime/builtin/dict.pir
   trunk/languages/tcl/runtime/builtin/open.pir
   trunk/languages/tcl/runtime/conversions.pir
   trunk/languages/tcl/src/pmc/tclarray.pmc
   trunk/languages/tcl/src/pmc/tcldict.pmc
   trunk/languages/tcl/src/pmc/tclint.pmc
   trunk/languages/tcl/src/pmc/tcllist.pmc
   trunk/languages/tcl/src/pmc/tclobject.pmc
   trunk/languages/tcl/src/pmc/tclstring.pmc
   trunk/lib/Parrot/Pmc2c/Dumper.pm
   trunk/lib/Parrot/Pmc2c/Method.pm
   trunk/lib/Parrot/Pmc2c/MethodEmitter.pm
   trunk/lib/Parrot/Pmc2c/Object.pm
   trunk/lib/Parrot/Pmc2c/PCCMETHOD.pm
   trunk/lib/Parrot/Pmc2c/PMC.pm
   trunk/lib/Parrot/Pmc2c/PMCEmitter.pm
   trunk/lib/Parrot/Pmc2c/Parser.pm
   trunk/lib/Parrot/Pmc2c/UtilFunctions.pm
   trunk/lib/Parrot/Pmc2c/VTable.pm
   trunk/lib/Parrot/Vtable.pm
   trunk/src/dynext.c
   trunk/src/dynpmc/dynlexpad.pmc
   trunk/src/dynpmc/foo.pmc
   trunk/src/dynpmc/gdbmhash.pmc
   trunk/src/dynpmc/rational.pmc
   trunk/src/dynpmc/rotest.pmc
   trunk/src/dynpmc/subproxy.pmc
   trunk/src/global.c
   trunk/src/inter_misc.c
   trunk/src/jit/i386/jit_emit.h
   trunk/src/jit_debug.c
   trunk/src/jit_debug_xcoff.c
   trunk/src/mmd.c
   trunk/src/oo.c
   trunk/src/ops/experimental.ops
   trunk/src/pmc/addrregistry.pmc
   trunk/src/pmc/array.pmc
   trunk/src/pmc/bigint.pmc
   trunk/src/pmc/boolean.pmc
   trunk/src/pmc/bound_nci.pmc
   trunk/src/pmc/capture.pmc
   trunk/src/pmc/class.pmc
   trunk/src/pmc/closure.pmc
   trunk/src/pmc/codestring.pmc
   trunk/src/pmc/complex.pmc
   trunk/src/pmc/continuation.pmc
   trunk/src/pmc/coroutine.pmc
   trunk/src/pmc/default.pmc
   trunk/src/pmc/deleg_pmc.pmc
   trunk/src/pmc/delegate.pmc
   trunk/src/pmc/enumerate.pmc
   trunk/src/pmc/env.pmc
   trunk/src/pmc/eval.pmc
   trunk/src/pmc/eventhandler.pmc
   trunk/src/pmc/exception.pmc
   trunk/src/pmc/exception_handler.pmc
   trunk/src/pmc/exporter.pmc
   trunk/src/pmc/file.pmc
   trunk/src/pmc/fixedbooleanarray.pmc
   trunk/src/pmc/fixedfloatarray.pmc
   trunk/src/pmc/fixedintegerarray.pmc
   trunk/src/pmc/fixedpmcarray.pmc
   trunk/src/pmc/fixedstringarray.pmc
   trunk/src/pmc/float.pmc
   trunk/src/pmc/hash.pmc
   trunk/src/pmc/integer.pmc
   trunk/src/pmc/intlist.pmc
   trunk/src/pmc/iterator.pmc
   trunk/src/pmc/key.pmc
   trunk/src/pmc/lexinfo.pmc
   trunk/src/pmc/lexpad.pmc
   trunk/src/pmc/managedstruct.pmc
   trunk/src/pmc/multiarray.pmc
   trunk/src/pmc/multisub.pmc
   trunk/src/pmc/namespace.pmc
   trunk/src/pmc/nci.pmc
   trunk/src/pmc/null.pmc
   trunk/src/pmc/object.pmc
   trunk/src/pmc/orderedhash.pmc
   trunk/src/pmc/os.pmc
   trunk/src/pmc/pair.pmc
   trunk/src/pmc/parrotinterpreter.pmc
   trunk/src/pmc/parrotio.pmc
   trunk/src/pmc/parrotlibrary.pmc
   trunk/src/pmc/parrotrunningthread.pmc
   trunk/src/pmc/parrotthread.pmc
   trunk/src/pmc/pccmethod_test.pmc
   trunk/src/pmc/pmcproxy.pmc
   trunk/src/pmc/pointer.pmc
   trunk/src/pmc/random.pmc
   trunk/src/pmc/ref.pmc
   trunk/src/pmc/resizablebooleanarray.pmc
   trunk/src/pmc/resizablefloatarray.pmc
   trunk/src/pmc/resizableintegerarray.pmc
   trunk/src/pmc/resizablepmcarray.pmc
   trunk/src/pmc/resizablestringarray.pmc
   trunk/src/pmc/retcontinuation.pmc
   trunk/src/pmc/role.pmc
   trunk/src/pmc/sarray.pmc
   trunk/src/pmc/scalar.pmc
   trunk/src/pmc/scheduler.pmc
   trunk/src/pmc/schedulermessage.pmc
   trunk/src/pmc/sharedref.pmc
   trunk/src/pmc/slice.pmc
   trunk/src/pmc/stmlog.pmc
   trunk/src/pmc/stmref.pmc
   trunk/src/pmc/stmvar.pmc
   trunk/src/pmc/string.pmc
   trunk/src/pmc/sub.pmc
   trunk/src/pmc/super.pmc
   trunk/src/pmc/task.pmc
   trunk/src/pmc/timer.pmc
   trunk/src/pmc/tqueue.pmc
   trunk/src/pmc/undef.pmc
   trunk/src/pmc/unmanagedstruct.pmc
   trunk/src/pmc/vtablecache.pmc
   trunk/src/scheduler.c
   trunk/src/sub.c
   trunk/src/utils.c
   trunk/src/vtables.c
   trunk/t/codingstd/pccmethod_deps.t
   trunk/t/oo/subclass.t
   trunk/t/op/calling.t
   trunk/t/pmc/builtin.t
   trunk/t/pmc/pmcproxy.t
   trunk/t/pmc/ro.t
   trunk/t/tools/pmc2c.t
   trunk/tools/build/vtable_extend.pl

Log:
[pdd17pmc] Merging the pdd17pmc branch into trunk (r24435 to r26307).


Modified: trunk/docs/pdds/draft/pdd04_datatypes.pod
==============================================================================
--- trunk/docs/pdds/draft/pdd04_datatypes.pod	(original)
+++ trunk/docs/pdds/draft/pdd04_datatypes.pod	Tue Mar 11 02:50:21 2008
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2007, The Perl Foundation.
+# Copyright (C) 2001-2008, The Perl Foundation.
 # $Id$
 
 =head1 NAME
@@ -46,7 +46,8 @@
 Parrot has a single internal string form:
 
     struct parrot_string_t {
-        pobj_t obj;
+        UnionVal cache;
+        Parrot_UInt flags;
         UINTVAL bufused;
         void *strstart;
         UINTVAL strlen;
@@ -115,24 +116,14 @@
 All PMCs have the form:
 
     struct PMC {
-        pobj_t obj;
+        UnionVal cache;
+        Parrot_UInt flags;
         VTABLE *vtable;
- #if ! PMC_DATA_IN_EXT
         DPOINTER *data;
- #endif
         struct PMC_EXT *pmc_ext;
+        PMC *real_self;
     };
 
-where C<obj> is a pointer to an C<pobj_t> structure:
-
-    typedef struct pobj_t {
-        UnionVal u;
-        Parrot_UInt flags;
- #if ! DISABLE_GC_DEBUG
-        UINTVAL _pobj_version;
- #endif
-    } pobj_t;
-
 and where:
 
     typedef union UnionVal {

Modified: trunk/docs/pdds/pdd17_pmc.pod
==============================================================================
--- trunk/docs/pdds/pdd17_pmc.pod	(original)
+++ trunk/docs/pdds/pdd17_pmc.pod	Tue Mar 11 02:50:21 2008
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2007, The Perl Foundation.
+# Copyright (C) 2001-2008, The Perl Foundation.
 # $Id$
 
 =head1 NAME
@@ -12,7 +12,7 @@
 =head1 ABSTRACT
 
 This PDD describes the internal structure and behavior of the Parrot Magic
-Cookie (PMC) data type. 
+Cookie (PMC) data type.
 
 =head1 DESCRIPTION
 
@@ -81,7 +81,7 @@
 C<PerlInts>).
 
 C<flags> holds a set of flags associated with the PMC; these are documented  in
-F<include/parrot/pobj.h>, and are generally only used within the Parrot 
+F<include/parrot/pobj.h>, and are generally only used within the Parrot
 internals.
 
 C<vtable> holds a pointer to the B<vtable> associated with the PMC. This points
@@ -90,7 +90,7 @@
 (i.e. how it behaves under addition, subtraction, cloning etc.)
 
 C<data> holds a pointer to the core data associated with the PMC. This
-may be NULL.
+may be null.
 
 C<pmc_ext> points to an extended PMC structure. This has the form:
 
@@ -105,7 +105,7 @@
 
 C<_synchronize> is for access synchronization between shared PMCs.
 
-C<_next_for_GC> determines the next PMC in the 'used' list during dead object 
+C<_next_for_GC> determines the next PMC in the 'used' list during dead object
 detection in the GC.
 
 PMCs are not required to have a C<PMC_EXT> structure (i.e. C<pmc_ext> can be
@@ -230,19 +230,34 @@
 
   ATTR <type> <name> [ :<modifier> ... ];
 
-This declaration is used to generate the data struct for the PMC
-(named "Parrot_<pmcname>_Data"). The data struct incorporates any
-attributes declared in a composed role. The declaration is also used to
-generate accessor macros for the class, in the form of
-GET_ATTR_<attrname> and SET_ATTR_<attrname>, and to set up helper
-information for the C<inspect> vtable function, and to provide attribue
-access throught the default C<get_attr> and C<set_attr> vtable functions.
+This declaration is used to generate the data struct for the PMC (named
+"Parrot_<pmcname>_Data"). The data struct incorporates any attributes declared
+in a composed role or inherited class. Composed attributes are inserted at the
+end of the generated struct. Inherited attributes are inserted at the top of
+the generated struct, so the struct members shared by the parent and child are
+in the same position, and code compiled for direct struct access to the parent
+can also perform the same direct struct access on the child.
+
+The declaration is also used to generate accessor macros, C<GET_ATTR_attrname>
+and C<SET_ATTR_attrname>, to set up helper information for the C<inspect>
+vtable function, and to provide attribute access through the default
+C<get_attr> and C<set_attr> vtable functions.
 
 It's also possible to define and store the PMC's data struct manually,
 but the standard declaration syntax must be used in roles, in PMCs that
 compose roles, and in PMCs that will be subclassed by high-level classes
 (this means all core PMCs, and most non-core PMCs).
 
+Low-level PMCs that use multiple inheritance (C<pmclass> declarations with more
+than one C<extends> entry) have to be careful with the contents of their
+structs. There's no problem if the two parents have identical data struct
+members. But, if the two parents have different data struct members, any vtable
+functions inherited from the parents will not be able to directly access the
+parents' struct members or use the accessor macros. The solution is to either
+override those vtable functions that directly access data struct members in the
+child PMC, define the parents as roles instead of classes, or declare the
+multiply inheriting child in PIR or an HLL.
+
 =head3 Defining vtable functions
 
 Vtable functions are defined as C functions within the body of the C<pmclass>
@@ -261,22 +276,20 @@
 
 =item SELF
 
-The current static invocant.
+The current invocant by dynamic type.
 
-=item DYNSELF
+=item STATICSELF
 
-The current dynamic invocant. [NOTE: it seems that this is actually what
-most people mean when they say C<SELF>.]
+The current invocant by static type.
 
 =item SUPER
 
-Calls the current method in the nearest superclass, using the static
-type of C<SELF>. [NOTE: again, seems that this should be the dynamic
-type, not static type.]
+Calls the current method in the nearest superclass, using the dynamic
+type of C<SELF>.
 
-=item DYNSUPER
+=item STATICSUPER
 
-Calls the current method in the nearest superclass, using the dynamic
+Calls the current method in the nearest superclass, using the static
 type of C<SELF>.
 
 =back
@@ -288,9 +301,6 @@
 
   METHOD inspect(STRING *what :optional, int got_what :opt_flag) {...}
 
-[NOTE: There is an older C<METHOD> keyword, which is deprecated. The
-current C<PCCMETHOD> will be renamed to C<METHOD>. See: RT#48565]
-
 =head2 PMCs and Namespaces
 
 Like high-level classes, low-level PMCs are tied to a corresponding
@@ -324,7 +334,7 @@
 state that can be used within the composing PMC. As such, roles are never
 instantiated directly, and are never translated to C directly. They have no
 core structs, though they define attributes to be added to the PMC they are
-composed into. 
+composed into.
 
 When a PMC that uses a role is translated to C, the role provides vtable
 functions, methods, and attributes that will be added to the generated C
@@ -336,7 +346,7 @@
 composed feature overrides the inherited feature, just as it would if
 defined in the composing PMC.
 
-Roles are defined using the C<prole> keyword. 
+Roles are defined using the C<prole> keyword.
 
   prole <name> <modifiers> {
   }
@@ -417,11 +427,6 @@
 This allows the PDD 15 object to intelligently handle method and vtable
 overrides within multiple parents and itself.
 
-(This will likely require changing the C<SELF> shortcut to be equivalent
-to C<DYNSELF>, which is what it probably should have been in the first
-place. We can create an alternative C<STATICSELF> for the rare cases
-when we really need it.)
-
 If a low-level PMC expects to be overridden by high-level classes (which
 means all the core low-level PMC types), it must respect the standard
 interface.
@@ -431,7 +436,7 @@
 
 =head2 Vtable Functions
 
-Vtables decouple the interface and implementation of various object functions. 
+Vtables decouple the interface and implementation of various object functions.
 The actual vtable structure contains pointers to functions that implement the
 methods for that particular PMC.  All pointers must point to valid functions
 with appropriate prototypes.
@@ -460,7 +465,7 @@
 Alternative entry point called when a PMC is first instantiated.  Accepts a PMC
 parameter used to initialize the given object.  Interpretation of the PMC
 initializer is left open, each PMC is free to choose its own implemention. A
-NULL value passed as the initializer parameter is allowed.
+null value passed as the initializer parameter is allowed.
 
 NOTE: It is strongly suggested that init_pmc(PMCNULL) be equivalent to
 init(), though there will of necessity be exceptions.
@@ -624,21 +629,21 @@
   PMC* getprop(INTERP, PMC* self, STRING* key)
 
 Return the value from the property hash of I<self> keyed by I<key>. The key
-should not be NULL.
+should not be null.
 
 =item setprop
 
   void setprop(INTERP, PMC* self, STRING* key, PMC* value)
 
 Set the value in the property hash of I<self> that is keyed by I<key> to the
-value of I<value>. The key should not be NULL.
+value of I<value>. The key should not be null.
 
 =item delprop
 
   void delprop(INTERP, PMC* self, STRING* key)
 
 Delete the value from the property hash of I<self> keyed by I<key>. The key
-should not be NULL.
+should not be null.
 
 =item getprops
 
@@ -652,7 +657,7 @@
 
 Return the type of the PMC. Type is a unique number associated with the PMC when
 the PMC's class is loaded. Negative numbers are considered
-interpreter-specific, non-public types. 
+interpreter-specific, non-public types.
 
 =item subtype [deprecated: See RT #48569]
 
@@ -824,13 +829,13 @@
 
 Many of the following functions have a *_keyed form, a *_keyed_int form, and a
 *_keyed_str form. The keyed forms take a PMC*, INTVAL, or STRING* key as a
-parameter. The PMC* parameter is NULL if there is no key for that
+parameter. The PMC* parameter is null (PMCNULL) if there is no key for that
 PMC; this means that that argument is unkeyed.
 
-In some cases, the caller must provide a non-NULL key.  Those cases are
+In some cases, the caller must provide a non-null key.  Those cases are
 explicitly stated below.  In the other cases, you may have to implement the
-keyed vtable functions and check for a NULL I<self> key even if you are
-implementing a non-aggregate type.  If the I<self> key is non-NULL and the PMC
+keyed vtable functions and check for a null I<self> key even if you are
+implementing a non-aggregate type.  If the I<self> key is non-null and the PMC
 class is a non-aggregate type, the _keyed_* methods should throw an exception.
 
 If you do not implement the *_keyed_int and *_keyed_str functions, the default
@@ -852,7 +857,7 @@
   INTVAL get_integer_keyed_str(INTERP, PMC* self, STRING* key)
 
 Return the integer value for the element indexed by a PMC, integer, or string
-key. The key is guaranteed not to be NULL for this function.
+key. The key is guaranteed not to be null for this function.
 
 =item get_number_keyed
 
@@ -861,7 +866,7 @@
   FLOATVAL get_number_keyed_str(INTERP, PMC* self, STRING* key)
 
 Return the native floating-point value for the element indexed by a PMC,
-integer, or string key. The key is guaranteed not to be NULL for this
+integer, or string key. The key is guaranteed not to be null for this
 function.
 
 =item get_string_keyed
@@ -871,7 +876,7 @@
   STRING* get_string_keyed_str(INTERP, PMC* self, STRING* key)
 
 Return the string value for the element indexed by a PMC, integer, or string
-key. The key is guaranteed not to be NULL for this function.
+key. The key is guaranteed not to be null for this function.
 
 =item get_bool_keyed [deprecated: See RT #48571]
 
@@ -892,7 +897,7 @@
   PMC* get_pmc_keyed_str(INTERP, PMC* self, STRING* key)
 
 Return the PMC value for the element indexed by a PMC, integer, or
-string key. The key is guaranteed not to be NULL for this function.
+string key. The key is guaranteed not to be null for this function.
 
 =item get_pointer_keyed
 
@@ -911,7 +916,7 @@
   void set_integer_keyed_str(INTERP, PMC* self, STRING* key, INTVAL value)
 
 Set the integer value of the element indexed by a PMC, integer, or
-string key. The key is guaranteed not to be NULL for this function.
+string key. The key is guaranteed not to be null for this function.
 
 =item set_number_keyed
 
@@ -920,7 +925,7 @@
   void set_number_keyed_str(INTERP, PMC* self, STRING* key, FLOATVAL value)
 
 Set the floating-point value of the element indexed by a PMC, integer,
-or string key. The key is guaranteed not to be NULL for this function.
+or string key. The key is guaranteed not to be null for this function.
 
 =item set_string_keyed
 
@@ -929,7 +934,7 @@
   void set_string_keyed_str(INTERP, PMC* self, STRING* key, STRING* value)
 
 Set the string value of the element indexed by a PMC, integer, or string
-key. The key is guaranteed not to be NULL for this function.
+key. The key is guaranteed not to be null for this function.
 
 =item set_pmc_keyed
 
@@ -955,7 +960,7 @@
   INTVAL type_keyed_str(INTERP, PMC* self, STRING* key) [RT #48581]
 
 Return the type number of the PMC indexed by a PMC, integer, or string key.
-The I<key> parameter is guaranteed not to be NULL for this method.
+The I<key> parameter is guaranteed not to be null for this method.
 
 =item pop_integer
 
@@ -1129,7 +1134,7 @@
   void i_subtract_float(INTERP, PMC* self, FLOATVAL value)
 
 Subtract the value of a PMC, native integer, or native floating-point number
-from a PMC and store the result in I<dest>. If I<dest> is NULL create a result
+from a PMC and store the result in I<dest>. If I<dest> is null create a result
 PMC of an appropriate type.  Note that I<dest> may be the same PMC as I<self>;
 in that case optimizations may be made. The C<i_> variants perform an
 inplace operation, modifying the value of I<self>.
@@ -1686,10 +1691,6 @@
 integer or float, empty string for false and '1' for true when fetched
 as a string.
 
-{{ IMPLEMENTATION NOTE: move the definitions of the Python constants
-"True" and "False" out of src/pmc/boolean.pmc. They belong in
-HLL-specific code, not in the core boolean type. }}
-
 =item BigInt
 
 An arbitrary precision integer.
@@ -1707,7 +1708,7 @@
 
 =item Class
 
-The PMC for Parrot's class. 
+The PMC for Parrot's class.
 
 =item Object
 
@@ -1721,8 +1722,8 @@
 =item AggregateElementRef
 
 This PMC represents a reference to an element contained in an aggregate PMC
-type, such as an array or hash. It is initialized with the key being 
-referenced and the aggregate PMC containing that key. 
+type, such as an array or hash. It is initialized with the key being
+referenced and the aggregate PMC containing that key.
 
 Note that assigning to the reference PMC will be equivalent to a keyed set on
 the referenced aggregate PMC - that is, it modifies the element rather than
@@ -1775,7 +1776,7 @@
 The base class for all array types (a statically sized array for any
 arbitrary type). New array types can be derived from the base Array.
 In user code it is recommended to use one of the specific array types
-below, rather than the base type. 
+below, rather than the base type.
 
 =item FixedBooleanArray
 
@@ -1907,7 +1908,7 @@
 
 =item Bound_NCI
 
-An internal NCI method call bound to a particular call instance. 
+An internal NCI method call bound to a particular call instance.
 
 =item Compiler
 
0
allison
3/11/2008 9:50:26 AM
perl.perl6.internals 7376 articles. 0 followers. Follow

0 Replies
856 Views

Similar Articles

[PageSpeed] 39

Reply: