Re: PMC Methods, Inheritance, and User-visible Classes

2006-08-30 Thread Luke Palmer

On 8/30/06, chromatic [EMAIL PROTECTED] wrote:

On Wednesday 30 August 2006 04:12, Watson Ladd wrote:

 Seriously, what's so bad about adding functionality into
 a language?

I once saw an overfilled waterbed that was almost as tall as I am.  I would
have called it PHP, but it didn't explode and throw cold water all over the
house.


Tons of people use PHP.  Why?  Because it gets the job done, and it
has tons of functionality.  The problem with PHP is not that it has
too much functionality, but that it is organized extremely poorly.

Luke


Re: Perl6

2005-12-27 Thread Luke Palmer
On 12/28/05, Sastry [EMAIL PROTECTED] wrote:
 I am looking for the latest Perl6 source code. Could somebody give me
 a link to the same?
 Do we need to install parrot before we install perl6?

You can check out the latest code at:

http://svn.openfoundry.org/pugs

You'll need ghc-6.4 or later installed.

Come to irc.freenode.net #perl6 if you need help building.

Luke


Re: Secure execution of Remote Code

2005-12-11 Thread Luke Palmer
On 12/11/05, Bryan Burgers [EMAIL PROTECTED] wrote:
 I was wondering... Are there plans to have parrot securely execute
 remote code, similar to JVM, so a person can have a parrot plug-in in
 their browser (for example), and run parrot 'applets' with the
 confidence that they are safe?
 Or is this not really part of the plan?
 If there's information about this already, you can just point me to
 it, but I couldn't find any.  Thanks for the help,

Well, the best place to ask this would actually be on
[EMAIL PROTECTED]  This list is not really concerned with
parrot, at least at the moment (but that looks like it will change
pretty soon).

And, I don't know much about it, but I do believe that this is part of
the plan.  When Dan Sugalski was our grand architect, he mentioned it
a fair amount.  I think that we use a different runcore for code that
needs to be safe; i.e. no JIT allowed.

Luke


Re: punie's demo uses *a lot* of memory on win32

2005-12-02 Thread Luke Palmer
On 12/2/05, jerry gay [EMAIL PROTECTED] wrote:
 i'm afraid adding tracing info will bring either system to its knees.
 perhaps there's some other way for me to help debug?

Okay, I haven't looked into the source at all, but I have one theory:

If Punie now uses Allison's attribute grammar implementation, that may
be the culprit (and even if it's not, this is still an issue in the
large scheme of things).  She ported my
Language::AttributeGrammar-0.05 from Perl 5.  That version of the
module suffered an algorithmic problem (i.e. not just a detail) that
would cause it not to free any memory until the whole tree was
traversed and all attributes were found.  So it's likely that the port
suffers the same problem.  If there are a lot of attributes, or if
those attributes carry large data structures, or just if the tree is
big, an attribute grammar traversal could use a heck of a lot of
memory.

If you're going to dive in debugging, that may be a place to start.

Luke


Re: parrot directory reorganization

2005-11-28 Thread Luke Palmer
Hi Jerry,

I'm just curious, I don't mean to criticize your ideas.  Just, give
some whys for the shoulds.

On 11/29/05, jerry gay [EMAIL PROTECTED] wrote:
 the parrot directory structure is large and a bit disorganized.
 let me give you some examples:
 * build_tools/, util/, and tools/*/ each contain utility perl
   scripts. these should be grouped together under tools/, which
   already contains subdirectories

Why must all perl scripts be grouped under one directory?

 * there are multiple dirs containing C source code (charset,
   classes, io, etc.) these should be grouped together under src/

Why must all C files be grouped under one directory?

 * the editor/ directory contains files for text editors and has
   a generated makefile. there is no reason for this to be a make
   target. a perl script should be created to replace makefile,
   and the dir moved with the other tool  utility scripts.

Why can't we use make for this?  Make handles modification times and
rebuilds on demand based on dependencies.  imc.vim (and a few others
IIRC) are built from dependencies, and if the dependencies haven't
been changed, they don't need to be rebuilt. That sounds like make's
job to me.

Luke


Re: shr bug when shifting by a multiple of the int size?

2005-11-03 Thread Luke Palmer
On 11/3/05, Leopold Toetsch [EMAIL PROTECTED] wrote:
 On Nov 3, 2005, at 20:49, Joshua Isom wrote:

  I was trying to use bit shifting for division by multiples of two, but
  if the shift amount is a multiple of the int size, it seems to fail to
  shift the bits.  Here's some example code demonstrating it.
 
  .sub _main @MAIN
  .local int a, b, c
  print a\tb\tc\n
  a = 24
  b = 32
  c = a  b

 Shifting anything by = the bits of the int isn't portable nor
 specified.

Why isn't it specified?  It seems to me that it should be zero.

The result being zero is also portable.  Right-shifting only ever
makes the number smaller.

Luke


Re: [perl #36437] [BUG] PGE recursion, bus error

2005-07-01 Thread Luke Palmer
 Attempting to come up with a simplistic math grammar that has one possible
 operand (A) and one possible operator (*) - so that things like A, A*A, and
 A*A*A*A*A are all parsed. This simplistic example (thanks to spinclad on
 #perl6) cause PGE to explode.
 
 $ cat ta.p6r
 grammar f;
 rule atom  { A }
 rule binary { expr \* atom }
 rule expr { binary }

That probably shouldn't die so horribly, but it should die.  We don't
support left-recursive grammars, and this is one.  A
non-left-recursive grammar that matches the same language is:

grammar f;
rule atom { A }
rule binary { atom \* binary }

Luke


Re: ./method defunct

2005-06-21 Thread Luke Palmer
On 6/21/05, Matthew Zimmerman [EMAIL PROTECTED] wrote:
 Could we revisit the idea of using a shorter keyword for $?SELF, like
 'o'? I know that $Larry said the idea was probably not going to work:
 
http://tinyurl.com/7baz6
 
 but I'm curious if the reasoning that killed it then still holds now,
 now that './' has emerged as a replacement.

./ bugs me a little bit since there is no $foo./bar .  Emphasis on a
little bit.  I rather enjoyed the o. proposal, but a few people are
horribly opposed to it, because o is a terrible name for a variable.
 I like to think of o. not as a varaible and a method call, but more
as just some syntax.  For instance:

while $count -- 0 {...}

You could oppose that by saying you should never put space between an
operand and a postfix operator, because it makes it look infix, or
you could look beyond that and see the arrow.  I do the same with
o.foo, not thinking of o as the letter o, but more as an open dot.

Anyway, I'm just happy that there's something to do the job.  Forcing
an explicit invocant was the only thing I didn't want, and making the
invocant the topic by default was the thing I especially didn't want.

Luke


[PATCH] make PIO_fdopen return NULL on incorrect flags

2005-05-05 Thread Luke Palmer
This patch makes PIO_fdopen return NULL when you give it flags it
doesn't understand.  I gathered that this was the correct behavior
from the test that I untodid.

Luke
Index: t/src/io.t
===
--- t/src/io.t	(revision 7981)
+++ t/src/io.t	(working copy)
@@ -585,8 +585,6 @@
 
 ###
 
-SKIP: {
-skip (fdopen does not handle illegal modes correct, 1);
 c_output_is($main . 'CODE', 'OUTPUT', PIO_fdopen);
 static opcode_t*
 the_test(Interp *interpreter,
@@ -620,7 +618,6 @@
 CODE
 done
 OUTPUT
-}
 
 ###
 
Index: io/io.c
===
--- io/io.c	(revision 7981)
+++ io/io.c	(working copy)
@@ -730,6 +730,8 @@
 }
 
 flags = PIO_parse_open_flags(sflags);
+if (!flags) return NULL;
+
 io = PIO_fdopen_down(interpreter, layer, fd, flags);
 /* io could be null here but we still have to
  * to create a PMC for the caller, no PMCNULL here


Re: parrot and refcounting semantics

2005-05-01 Thread Luke Palmer
Robin Redeker writes:
 On Sat, Apr 30, 2005 at 05:02:54PM -0400, Dan Sugalski wrote:
  destroy. There's a vtable method that's called by the GC system when 
  an object is no longer reachable from the root set.
 
 Actually, not when, but some (indefinite) time after that has happened,
 right?
 
   And if so, what
  would the purpose of them be?
 
 First, let me define destructor as something that runs very soon after
 an object is no longer reachable (perl5 sense), and a finalizer as
 somethign that gets called before the memory of an object gets reused
 (java sense).

Just so you don't talk past each other, I'll point out that this is
backwards from how we usually talk about these.

Luke


Re: parrot and refcounting semantics

2005-04-28 Thread Luke Palmer
Dan Sugalski writes:
 Also, with all this stuff, people are going to find timely destruction
 is less useful than they might want, what with threads and
 continuations, which'll screw *everything* up, as they are wont to do.
 I know I've been making heavy use of continuations myself, and this is
 for a compiler for a language that doesn't even have subroutines in
 it. Continuations screw everything up, which is always fun, for
 unusual values of 'fun'.

When I programmed in C++ with proper use of the STL and other such
abstractions, almost the only time I needed destructors were for
block-exit actions.  Perl 6 has block-exit hooks, so you don't need to
use destructors to fudge those anymore.  And there's a lot less explicit
memory management in languages with GC (that's the point), so
destructors become even less useful.

I agree with Dan completely here.  People make such a big fuss over
timely destruction when they don't realize that they don't really need
it.  (But they want it).   I think, more importantly, they don't
understand what they're getting in return for giving it up.

Luke


Re: parrot and refcounting semantics

2005-04-28 Thread Luke Palmer
Robin Redeker writes:
 On Wed, Apr 27, 2005 at 12:33:30PM -0600, Luke Palmer wrote:
  I think, more importantly, they don't understand what they're
  getting in return for giving [refcounting] up.
 
 Could you point out what i get?
 
 I use TD is to handle resources: filehandles, database handles, gui
 windows and all that. Refcounting does this with a little overhead, but
 in a fast and deterministic O(1) way.

If it's deterministic behavior that you want, you probably ought to be
doing things explicitly.  What you get as a Perl programmer is, well,
the ability to use circular data structure.  Big deal, right?  But if
you're an extention writer, you get relief from days of refcount
debugging and a nice fast throughput (though the former is what
convinces me).  Hacking on parrot is such a joy, because I can just
forget that I need to free memory. 

 And how do you want to implement glib objects with parrot?  They are
 refcounted.

How do you do it in Perl 5?  Glib doesn't use Perl's refcounts, it uses
its own right?  (I don't actually know).  But if the behavior of your
program depends on where things are destoryed, and caching a reference
somewhere can keep your window from closing, I'm under the impression
that you should be doing it explicitly.  Perl 6 in particular provides
so many hooks that pure destruction-based program behavior is probably
already too obfuscated.

At least, that's my experience writing the ODE module.  I initially had
the destroy_body calls inside the destructor.  But I found that bodies
would magically disappear under my nose, and others would never go away.
I ended up switching to an explicit destroy call, and now my life is
much less painful.

But that's my opinion.  :-)

Luke


Re: parrot and refcounting semantics

2005-04-28 Thread Luke Palmer
Robin Redeker writes:
 This should actually be, to prevent the resource from leaking:
 
 {
   my $s = new CoolClass;
   eval {
 ... do stuff that may throws ...
   };
   destroy $s;
 }

Or, with the block hooks that I keep claiming makes timely destruction
almost never needed, it is:

{
my $s = new CoolClass;
# ... do stuff that may throw ...
LEAVE { destroy $s }
}

This destroys properly and even propagates the exception.

Luke


Re: Again the infix ops

2005-03-31 Thread Luke Palmer
Leopold Toetsch writes:
 But with one more indirection a PIC-like scheme can work with
 read-only bytecode too (probably). E.g. the assembler emits instead
 of the proposed:
 
   infix __add, Pd, Pl, Pr
 
 this opcode:
 
   infix (.MMD_ADD  24) | n, Pd, Pl, Pr

Just 256?  Why don't you add another argument to the infix opcode?

Luke


Re: operator

2005-01-30 Thread Luke Palmer
Markus Laire writes:
 [EMAIL PROTECTED] kirjoitti:
 Please,
 I have a question if exists in Perl somethink like keyword
 'operator' in C++ ?
 
 That will exist in perl6.

And to quite a larger extent.  Not only can you overload existing
operators, you can make up whatever operator name you like.

 for example we can write in C++ :
 class A {
 A() { printf(Constructor of object class A\n); }
 ~A() { printf(Destructor of object class A\n); }
 };
 A operator + (A a1, A a2) { printf(Addition\n); }
 A operator * (A a1, A a2) { printf(Multiplication\n); }
 
  int main() {
  A a,b,c;
  c = (a+b*a);
  }
 
 Using these as reference:
 
 http://dev.perl.org/perl6/synopsis/S06.html
 http://dev.perl.org/perl6/synopsis/S12.html
 
 (I don't understand how to create constructor  destructor)
 I think equivalent perl6-code would be:
 
 class A {
   # place constructor here

submethod BUILD() {
say Constructor of class A;
}

   # place destructor here
submethod DESTROY() {
say Destructor of class A;
}
 }
 
 sub infix:+ (A $a1, A $a2) { print(Addition\n); }
 sub infix:* (A $a1, A $a2) { print(Multiplication\n); }

I expect you need multi on those subs, to avoid redefining the
existing operators (not without it yelling at you a bit, though).

multi sub infix:+ (A $a1, A $a2) { say Addition }
multi sub infix:* (A $a1, A $a2) { say Multiplication }

 my A $a; # note, I'm not sure how to write this on one line
 my A $b;
 my A $c;

Just:

my A ($a, $b, $c);

Luke

 $c = ($a + $b * $a);


Re: Calling conventions, invocations, and suchlike things

2005-01-28 Thread Luke Palmer
Sam Ruby writes:
 Mmm, syntax! :) Luckily it makes no difference to us at the parrot 
 level. What that should translate to is something like:
 
 $P0 = find_method Parrot_string, find
  # Elided check for failed lookup and fallback to attribute fetch
 $P1 = make_bound_method(Parrot_string, $P0)
 $P1(r)
 
 This will be a recurring theme in my replies.  Any thing which presumes 
 a bit of knowledge at compile time will ultimately not work.
 
 Consider the following:
 
   class c:
 find = 7
 
   def f(x):
 return x.find
 
   print f(c())
   print f(Parrot)(r)
 
 Now, what should the code for function f look like?  The only reasonable 
 answer is something along the lines of:
 
   getattribute $P0, P5, 'find'

I doubt that.  All languages have different semantics, and we can't
implement them all, because they are conflicting.  You, as a compiler
designer, have the opportunity to design things so that they work.  And
you definitely have to be clever if you're looking for language features
that Parrot doesn't natively support.

My first tendency here is to echo all attributes as methods (like Perl 6
does), and then always call the method when you see a dot.  ParrotString
has a find method, and it knows how to curry itself.  Instances of c
also have a find method, and that method always returns 7.

Although I agree that we should come up with a general, bare-bones
object model that allows all of our current target languages to operate
smoothly.  Parrot's current model makes far too many assumptions.  But
that doesn't mean that anything you're trying to do is impossible; it
just means it's harder.

Luke


Re: Scope exit and timely destruction

2005-01-14 Thread Luke Palmer
Dave Mitchell writes:
 On Fri, Jan 14, 2005 at 02:40:43PM -0700, Luke Palmer wrote:
  What I'd most like is to convince Larry to waive the timely destruction
  requirement.  However, that doesn't really solve the problem for other
  languages that need timely destruction.  Are there any?
 
 Perl 5 springs to mind !!!

Well it didn't spring to my mind.  I seemed more to mosey in.

I wonder about Ponie though.  I don't think Parrot plans to support Perl
5 without help from perl5.  However, I don't know enough about Ponie to
know whether it will keep its refcounting around to help us out in that
case.

Luke


Re: Scope exit and timely destruction

2005-01-14 Thread Luke Palmer
Unknown writes:
 On Fri, 2005-01-14 at 17:57 -0500, Michael Walter wrote:
  You could change the GC scheme (*cough*) to use one similar to
  Python's (ref-counting + additional GC for cyclic references
  *double-cough*).
 
 You could adapt Java's last-generation GC scheme to do a really fast GC
 on scope-exit, only of objects created within that scope. However, this
 may require a relocating or treadmill GC to do efficiently. Otherwise, I
 seem to remember a zone-based GC strategy which allocated 'zones' to
 frames and GC'd by zone... will have to find a reference. It was very
 fast, since generally everything from a zone except the return value was
 garbage. Vague memories are also coming back to me about only being able
 to point from lower to higher numbered zones, except through gates ...
 
 I suspect the algorithm described at
 
 http://www-106.ibm.com/developerworks/java/library/j-jtp11253/
 
 with card-marking on arenas would be applicable. PMCs could be relocated
 between arenas (promotion to an older generation?) could then store a
 redirect bit in the arena header of the old arena, and update all
 pointers on the next full GC (about 1 in 10 in the 1.4 hotspot JVM,
 except when thrashing). I note that in practice [and this is
 mis-documented] the hotspot JVM keeps separate permanent store, and
 appears to thrash on the object heap when permanent store is full,
 although this permanent store ought to be treated as a strictly older
 generation.

There are a lot of partial solutions.  I get the impression that when
they say timely destruction they want a full solution.  Here's an
example of a case that most partial solutions won't catch:

my %data;
sub a {
open my $fh, somefile;
$data{fh} = $fh;
}
sub b {
%data = ();
}

a();
# ...
b();

 I thought C++ only guaranteed destruction (on return or exception) for
 objects which were directly on the stack. 

That's true, you have to explicitly delete most memory.  I was actually
referring to the template refcounting classes that I use all the time:

void foo() {
refImage image = new Image(somefile.jpg);
image-draw();

// image will be cleaned up automatically
}

Here, C++ manages only to refcount objects (or rather, pointers) that
are declared using ref instead of *.  In a dynamically typed VM this
isn't possible.

Luke


Re: Scope exit and timely destruction

2005-01-14 Thread Luke Palmer
Shevek writes:
 On Fri, 2005-01-14 at 16:56 -0700, Luke Palmer wrote:
 
   I thought C++ only guaranteed destruction (on return or exception) for
   objects which were directly on the stack. 
  
  That's true, you have to explicitly delete most memory.  I was actually
  referring to the template refcounting classes that I use all the time:
  
  void foo() {
  refImage image = new Image(somefile.jpg);
  image-draw();
  
  // image will be cleaned up automatically
  }
  
  Here, C++ manages only to refcount objects (or rather, pointers) that
  are declared using ref instead of *.  In a dynamically typed VM this
  isn't possible.
 
 Yeah, but the ref object is directly on the stack, and destruction of
 that, and thus decrement of the refcount, is guaranteed. Um.

Yes, I understand that.  So, moving on...

 The example you described destroyed a ref within a sub, and then assumed
 that the object refed would be destroyed at scope exit.

I'm assuming you're referring to my Perl example, which you tactfully
omitted in order to lose the casual reader.  Very cunning.  :-)

Here it is again:

my %data;
sub a {
open my $fh,  somefile;
$data{fh} = $fh;
}
sub b {
%data = ();
}
a();
# ...
b();

And what I mean is that most approximate solutions won't destroy $fh in
time.  One example of such a proposal is keeping tabs on objects in the
current scope which need timely destruction and then do a sweep whenever
we lose a reference to one.  Another is using generational schemes.
Generational schemes are good for finding *enough* dead objects quickly
when we run out of memory, but they're not good for finding whether a
particular object is dead.

However, Perl 5, since it uses refcounting everywhere, has no problem
with this.  Parrot has decided not to use refcounting at all (a decision
that I think I agree with), and so we have this problem.

 This is incorrect: the object refed should be destroyed when the ref is
 destroyed in a general refcounting GC system.

And I don't understand what you mean here.

 Anyway, this led me to the (useful?) thought that you could delink the
 concept of timely GC and destruction at scope exit by registering
 atexit() or atleave() code on a scope (like finally{}) which explicitly
 undef'd registered PMCs. That way you would be able to guarantee
 destruction even if the PMC was still ref'd, which is probably more use
 for things like critical section locks than just relying on a
 side-effect of the GC, and is certainly easier to implement since it's
 just a flag on the lexical in the pad.

Precisely!  But if we have to support this area of Perl 5 (I'm not
certain that we do yet), we have to implement its semantics
backward-compatibly.  The programmer of Perl 5 relied on the side
effects because they worked then.  So we're not allowed to break them.

And because of Perl 6's many lexical scope hooks, I hope that we can get
rid of any timely destruction policy, to encourage the use of lexical
hooks instead of destruction rules.

No matter how we slice it, it would royally suck to add a sweep at the
end of every lexical scope.

Luke


Re: Native data structure for parrot?

2005-01-03 Thread Luke Palmer
Bernhard Schmalhofer writes:
 This sounds somewhat like a Piddle, which is the data structure of the 
 Perl Data Language, http://pdl.perl.org/. AFAIK there is already a hook, 
 that allows you to use your own data lying somewhere in your memory.
 
 It might be worthwile to create a Piddle PMC, that brings this 
 functionality to all Parrot languages.

Which of course would entail bringing the functionality that comes with
Piddles to Parrot.  Which is like writing a library.

 You can also get at a C-level struct using the ManagedStruct and
 UnManagedStruct PMCs, though access is a bit clumsy IIRC.
 
 With NCI it should be possible to create a Piddle PMC, that hooks into 
 the shared library
 of PDL for Perl5. Of course, one could also just steal the code or roll 
 your own code.

Well, we could do that temporarily, I suppose.  It would be a pain
considering all the wrappers and such that we'd have to do, since we
don't have ponie at our disposal yet.

However, both Parrot and Perl 6 are offering many new possibilities to
PDL.  I think it would be wise to rethink the overall architecture
before making any hooks or trying to write another PDL.

If there's anyone interested in working on PDL for Parrot, drop me a
line.  I've had my eye on this task for a while now, and it would be
neat to get started.

Luke


Re: Native data structure for parrot?

2004-12-29 Thread Luke Palmer
Graciliano M. P. writes:
 Will be nice to can write this directly on Perl6:
 
   int the_matrix[10][10] ;

Or rather:

my int @matrix is dim(10,10);

Perl 6 has been planning support for such naive data structures for a
long time.  

I'm not sure about hashes.  They have enough internal structure that
they're going to be pretty big no matter what the return type is
declared to be.

Problems like this are what the CPAN is adept at solving anyway.  Just
find a module that does it. 

Luke


Re: MMD and VTABLE_find_method

2004-12-23 Thread Luke Palmer
Sam Ruby writes:
 In the general case, a call to a subroutine with three arguments can 
 have four possibilities: anywhere from zero to three arguments may be 
 involved in the dispatch.
 
 I also read this to say that whatever code is generated by a subroutine 
 call is independent of the number of arguments involved in the dispatch. 
  If you read this differently, perhaps we can get a ruling from the 
 Perl6 language folks.  If I am correct, this will have the nice side 
 benefit that any such methods can be invoked transparently by all languages.

A ruling: The caller might not know that it's calling a multimethod at
all at compile time, much less how many invocants it has.

A PMC that hides the fact that we're doing a multimethod seems like the
best way to allow multiple language semantics.  If we were OO designers,
I doubt we would have thought of any other way.

Luke


Re: auxiliary variables

2004-12-19 Thread Luke Palmer
[EMAIL PROTECTED] writes:
 Please
 Lets have two scalars variables in Perl and some operation under 
 them like an adding. 
 x = a + b
 I would like know, witch auxiliary variables are creating 
 on the in-line code like a Parrot 
 
 somethink like T = a + b
  x = T ???
 
 and on witch circumstances depends it. 
 Can I keep clear of creating this auxiliary variables anywise ?

We have no idea when they'll come up, because we haven't even layed out
the groundwork for the code generator yet.

However, such auxilliary variables show up in a lot of places.  For
instance, when you add two PMCs, you need an Undef in which to put the
result.  I don't entirely agree with this semantic: I think the result
PMC should be created by the add function itself.

This is how it works now:

$P0 = new PerlInt
$P0 = 3
$P1 = new PerlInt
$P1 = 4
$P2 = new Undef
$P2 = $P0 + $P1

If that counts as an auxilliary variable, you'll see them all over the
place.  And there's not really a way you can avoid it.

In fact, I don't think you could avoid it if you wrote in bare PIR
without going through a compiler.

Luke


Re: [perl #33092] IMCC sub/opcode invocation conflict

2004-12-17 Thread Luke Palmer
Dave Brondsema writes:
 # New Ticket Created by  Dave Brondsema 
 # Please include the string:  [perl #33092]
 # in the subject line of all future correspondence about this issue. 
 # URL: http://rt.perl.org:80/rt3/Ticket/Display.html?id=33092 
 
 
 
 If I define a sub as:
 
 .sub print
 .param string arg
 print arg
 .end
 
 
 Then I cannot invoke it using the IMCC short way:
   print(hello)
 because I get this error:
   error:imcc:op not found 'print' (print0)

You can invoke it the almost short way:

print(hello)

You can also define the sub like this:

.sub print
.param string arg
print arg
.end

Which is quite nice for compiler writers.

Luke


Re: overloaded operator calling conventions

2004-12-15 Thread Luke Palmer
Leopold Toetsch writes:
 Why do we have the special notion of current_object in the first place?
 Why not just pass all in as P5, P6, ...?

I agree that this is the way to go.  Especially if we have some marker
somewhere that tells us that we were called as a method.

Luke


Re: [CVS ci] class refactoring 1 - Integer

2004-12-10 Thread Luke Palmer
Sam Ruby writes:
 Mike Guy wrote:
 
 Perl5 Cxor always returns a standard boolean value, i.e.
 dualvar(0, '') or dualvar(1, '1').Perl6/Parrot should do the same
 thing.
 
 Try:
 
 perl -le print 'day' xor 'night'
 
 On the version of Perl I have installed, I get day as the result.

Odd, since xoring two true values should give a false one.

Remember the precedence of xor.  This is parsed:

perl -le print('day') xor 'night'

Luke


Re: [CVS ci] class refactoring 1 - Integer

2004-12-10 Thread Luke Palmer
[ From p6i ]

Patrick R. Michaud writes:
 On Fri, Dec 10, 2004 at 08:50:46PM +0100, Leopold Toetsch wrote:
  Not quite. It gives one value if one is true or 0 (false). This is more
  information then the perl5 implementation returns. The returned value (if
  any) is still true but usable, if I just want one of both. Well that's
  logical xor - not binary xor.
 
 Agreed.   At some point this probably belongs on perl6-languages (and
 apologies if this posting to p6i is therefore inappropriate).  But if
 the following hold (Perl 5):
 
 print (0 and hello);# outputs 0
 print ( and hello);   # outputs 
 print (0 or hello); # outputs hello
 print ( or hello);# outputs hello
 print ( or 0);  # outputs 0
 print (0 or );  # outputs 
 print (not( or 0)); # outputs 1
 print (not(a and b)); # outputs 
 
 it seems like one should be able to do:
 
 print (0 xor hello);# outputs hello
 print ( xor hello);   # outputs hello
 print (hello xor 0);# outputs hello
 print (hello xor );   # outputs hello
 print (world xor hello);  # outputs 
 print (0 xor ); # outputs 1
 print ( xor 0); # outputs 1
 
 Just as Cor returns its first non-false argument, the interpretation
 of Cxor would be that it returns its single non-false argument, or 1 if
 both (all?) arguments logically evaluate to false.

Well, IAAL. :-)

In particular, xor is analogous, operatorwise, to the junctive one().
one() represents its single true value when it evaluates to true in
conditionals:

my $smin = one(3,6,9,12)  5;

So it seems logical that xor do the same.  I don't see any loss of
generality in doing so, and you're keeping around more information.

For the PMC variant, it seems like returning *the* true PMC is the
correct thing to do, because the definiton of the canonical true
differs from language to language.  Parrot has a canonical false.

Luke


Re: Premature pessimization

2004-12-06 Thread Luke Palmer
Leopold Toetsch writes:
 citing Luke Palmer
 On a semi-related note, can I get a classoffset without doing a hash
 lookup?  That is, can I store the class number I get assigned somewhere
 for quick fetching?

Hey now, you're citing the Luke Palmer that writes code.  Don't confuse
him with the Luke Palmer who does software design.  They really don't
get along so well...

Luke


Re: Premature pessimization

2004-12-05 Thread Luke Palmer
Leopold Toetsch writes:
 This term came up in a recent discussion[1]. But I'd like to give this
 term a second meaning.

Except what you're talking about here is premature *optimzation*.
You're expecting certain forms of the opcodes to be slow (that's the
pessimization part), but then you're acutally using opcodes that you
think can be made faster.  This is a classic Knuth example.

If I were Dan, here's what I'd say (though perhaps I'd say it in
somewhat a different tone :-):  don't worry about it.  Inline caching is
just another optimization.  We need to be feature complete.

Leo, speed is never off your mind, so we can be fairly certain that we
won't be making any decisions that are going to bite us speed-wise.
Plus, at this point, we can change interfaces (when we go past feature
complete into real-life benchmarked optimization).  Yeah, the compilers
will have to change, but really that's not a big issue.  I've been
writing compilers for parrot for a while, and stuff is always changing,
and it usually means one or two lines of code for me if I designed well.

And if you really feel like you need to optimize something, look into
the lexicals-as-registers idea you had to fix continuation semantics.
Then you can work under the guise of fixing something broken.

Luke

 
 During design considerations we (including me of course too) tend to 
 discard or pessimize ideas early, because they look inefficient. Recent 
 examples are e.g.
 - spilling
 - lexical (re-)fetching
 - method calls
 
 We have even some opcodes that work around the estimated bad effect of 
 the operation. E.g. for attribute access:
 
   classoffset Ix, Pobj, attr
   getattribute Pattr, Pobj, Ix
 
 instead a plain and clear, single opcode:
 
   gettatribute Pattr, Pobj, attr
 
 We are thinking that the former is more efficient because we can cache 
 the expensive hash lookup in the index CIx and do just integer math to 
 access other attributes. (This is BTW problematic anyay, as the side 
 effect of a getattribute could be a change to the class structure).
 
 Anyway, a second example is the indexed access of lexicals additionally 
 to the named access. Again a premature pessimization with opcode support.
 
 Another one is the newsub opcode, invented to be able to create the 
 subroutine object (and possibly the return continuation) outside of a 
 loop, where the function is called.
 
 All of these pessimized operations have one common part: one or several 
  costy lookups with a constant key.
 
 One possible solution is inline caching.
 
 A cache is of course kind of an optimization. OTOH when we know that we 
 don't have to pay any runtime penalty for certain operations, possible 
 solutions are again thinkable that would otherwise just be discarded as 
 they seem to be expensive.
 
 I'll comment on inline caching in a second mail.
 
 leo
 
 [1] Michael Walter in Re: [CVS ci] opcode cleanup 1 . minus 177 opcodes
 I'm fully behind Dan's answer - first fix broken stuff, then optimize. 
 OTOH when compilers already are choking on the source it seems that this 
 kind of pessimization isn't really premature ;)
 


Re: continuation enhanced arcs

2004-12-05 Thread Luke Palmer
Piers Cawley writes:
 I'd submit that, in the vast majority of cases you're not going to be
 dealing with full continuations, and on the occasions when you are the
 programmer using them will be aware of the cost and will be willing to
 pay it.

Yeah probably.  Except the problem isn't the cost.  The problem is the
semantics.  If you copy the registers, then when you invoke the
continuation, their *values* restore to what they were when you made the
continuation.  These are not proper semantics, and would result in
subtle, incorrect infinite loops.

Luke


Re: Parrot Strong typing

2004-12-03 Thread Luke Palmer
Timm Murray writes:
 I've always thought of Perl5 having two basic types: Scalar and List, with 
 Hash and Array being subtypes of List.  The reason is that arrays and hashes 
 can be easily converted into each other, because of Perl5's list-flatening 
 nature:
 
 @array = %hash;
 %hash = @array;

I wouldn't say that:

my $array = [1, 2, 3, 4];
print $array-{1};   # error!

Perl doesn't automatically convert between them; however, you're allowed
to assign them to each other.  That is, a hash isn't a list, but in list
context, it turns into one.

Luke


Re: continuation enhanced arcs

2004-12-03 Thread Luke Palmer
Leopold Toetsch writes:
  I think we have basically 3 choices: support continuations such that
  they work correctly in all HLL situations and accept likely poor
  performance, or support only escape continuations, or devise a strategy
  whereby Parrot itself doesn't provide continuations, but allows them to
  exist at the HLL level somehow.
 
 These choices are not really desirable, IMHO. Number 3 doesn't work for
 technical reasons anyway.
 
 Frankly I think, I've presented a way to make continuations work
 correctly. I did *not* hear any technical or otherwise reasonable
 argument that it wouldn't work or that it's untenable, nothing, nada.

Well, since I (and I'm sure many others) have been skipping over a lot
of messages in this thread, could you either restate your solution or
give a pointer to your proposal message?

Thanks,
Luke


Re: continuation enhanced arcs

2004-12-03 Thread Luke Palmer
I looked through google groups and couldn't find leo's solution
(putting lexicals in registers, and I can't figure out what that
means; couldn't you have a loop counter that isn't a lexical?).

I think we all agree that this is a major problem, and that to ignore it
would be a fatal mistake in Parrot's support of continuations.  And
parrot not supporting continuations means parrot not supporting
coroutines.  And that means parrot not supporting Perl 6 :-/

We would like a solution that allows optimization, keeps JIT around, and
behaves correctly.  The main problem with Dan's solution (which I also
couldn't find, but I'm inferring by talk about it) is that it restores
things values when they may have already changed.

So--here's the naive proposal.  Naive because I'm not very good at
foreseeing performance issues, etc.  Keep in mind that this is a
major architecture change (which we're not doing, right?), but can be
made opaque with proper support from IMCC.

No more value semantics.

That's it.  All values on the bytecode level are pointers.  I's are
pointers to ints (that's still a win since you don't need to keep going
through a vtable), etc.  P's are just as they used to be.

Then to use an int, you have to allocate it first.  Perhaps this can be
made efficient with a specialized small-object pool attached onto the
register frame for cache locality (which I don't really understand).

Anyway, I'm expecting you smart guys to shoot this down.  But
something's got to be done about this problem.  Proposals have to
happen.

Luke


Re: continuation enhanced arcs

2004-12-03 Thread Luke Palmer
And because of a message that came up very recently, I infer that leo's
solution involves a variable-sized register frame.  

This sounds like a much better solution than the one I've just proposed.
No saving/restoring, the register frame size is known at compile time
(so the double-indirection can be reduced to single), JIT still works.

So, scrap my proposal.  Seriously consider his.  My comments about this
is a real problem and needs a real solution still hold.

Luke

Luke Palmer writes:
 I looked through google groups and couldn't find leo's solution
 (putting lexicals in registers, and I can't figure out what that
 means; couldn't you have a loop counter that isn't a lexical?).
 
 I think we all agree that this is a major problem, and that to ignore it
 would be a fatal mistake in Parrot's support of continuations.  And
 parrot not supporting continuations means parrot not supporting
 coroutines.  And that means parrot not supporting Perl 6 :-/
 
 We would like a solution that allows optimization, keeps JIT around, and
 behaves correctly.  The main problem with Dan's solution (which I also
 couldn't find, but I'm inferring by talk about it) is that it restores
 things values when they may have already changed.
 
 So--here's the naive proposal.  Naive because I'm not very good at
 foreseeing performance issues, etc.  Keep in mind that this is a
 major architecture change (which we're not doing, right?), but can be
 made opaque with proper support from IMCC.
 
 No more value semantics.
 
 That's it.  All values on the bytecode level are pointers.  I's are
 pointers to ints (that's still a win since you don't need to keep going
 through a vtable), etc.  P's are just as they used to be.
 
 Then to use an int, you have to allocate it first.  Perhaps this can be
 made efficient with a specialized small-object pool attached onto the
 register frame for cache locality (which I don't really understand).
 
 Anyway, I'm expecting you smart guys to shoot this down.  But
 something's got to be done about this problem.  Proposals have to
 happen.
 
 Luke
 


Re: continuation enhanced arcs

2004-12-01 Thread Luke Palmer
Bill Coffman writes:
 I can see that there is true magic in the power of using references in
 this way.  Nonetheless, how can the compiler figure out that it can't
 use an integer here?  The compiler should use integers when it can,
 but it sounds like you are saying that when a variable crosses a sub
 call (which might invoke a continuation) it will then have to be a PMC
 or String to do the right thing.

Yep.  And that's something that the compiler will just have to know (or
give IMCC enough information to do something about it).

And, IIRC, an S register wouldn't work either, since strings are value
types at the bytecode level. 

Luke

  Remember the PMC and string registers
  hold pointers to pmc/string structures, which is all we're preserving
  -- the *pointer* to the structure, not the contents of the structure.
  (Though that's an interesting thing to do for other reasons, like,
  say, transactions, we're not going to be doing that) The contents can
  change over and over without the register itself ever changing.
  
  
  
  # these two lines are main
  outer()
  $saved.call
  
 
 Bill
 
  JEff
  
  --
  Dan
 


Re: continuation enhanced arcs

2004-11-29 Thread Luke Palmer
It seems to me that there is no good solution to this problem without
annotating the register set or killing the register allocator.  So
perhaps we should keep the non-pmc registers at value semantics; that
is, continuations simply restore their value when the continuation was
taken.  

Yes, I know it's not technically correct, but it is consistent, useful,
and doesn't kill our optimizations.  If the compilers know about these
semantics, then there is no loss of functionality or interoperability.
Functions that aren't prepared to deal with continuations won't be able
to anyway (and in fact, these semantics may work better in those cases).

Luke


Re: [perl #32676] testj hangs on string_102

2004-11-29 Thread Luke Palmer
Parrot Assembler via RT writes:
 make testj hangs on string_102.pasm.  Here's the gdb backtrace. 

It looks like a really subtle, nasty problem.  If I add a noop anywhere
in the top section of code (before MAIN) it works.  It works even if I
change the filename from string_102.pasm to test.pasm!  It works if I
add a non-jit op (like print or find_type) right after MAIN.

Luke

 
 % gdb parrot
 GNU gdb Red Hat Linux (6.0post-0.20040223.19rh)
 Copyright 2004 Free Software Foundation, Inc.
 GDB is free software, covered by the GNU General Public License, and you are
 welcome to change it and/or distribute copies of it under certain conditions.
 Type show copying to see the conditions.
 There is absolutely no warranty for GDB.  Type show warranty for details.
 This GDB was configured as i386-redhat-linux-gnu...Using host libthread_db 
 library /lib/tls/libthread_db.so.1.
   
  
 (gdb) run -j t/op/string_102.pasm
 Starting program: /home/fibonaci/devel/parrot/parrot -j t/op/string_102.pasm
 Error while mapping shared library sections:
 : Success.
 Error while reading shared library symbols:
 : No such file or directory.
 [Thread debugging using libthread_db enabled]
 [New Thread -150292160 (LWP 10828)]
 Error while reading shared library symbols:
 : No such file or directory.
 Error while reading shared library symbols:
 : No such file or directory.
 [New Thread -159155280 (LWP 10831)]
 [New Thread -169645136 (LWP 10832)]
   
  
 Program received signal SIGINT, Interrupt.
 [Switching to Thread -150292160 (LWP 10828)]
 0x00880d34 in _int_malloc () from /lib/tls/libc.so.6
 (gdb) bt
 #0  0x00880d34 in _int_malloc () from /lib/tls/libc.so.6
 #1  0x00881bbd in _int_memalign () from /lib/tls/libc.so.6
 #2  0x00880467 in memalign () from /lib/tls/libc.so.6
 #3  0x008826a6 in posix_memalign () from /lib/tls/libc.so.6
 #4  0x080ab600 in mem_realloc_executable (old=0x9f13000, newsize=4720) at 
 memexec.c:47
 #5  0x080ad3d2 in build_asm (interpreter=0x9d21008, pc=0x9f1b1c0, 
 code_start=0x9f1b1c0, code_end=0x9f1b56c, objfile=0x0)
 at src/jit.c:1402
 #6  0x08160068 in init_jit (interpreter=0x9d21008, pc=0x9f1b1c0) at 
 src/interpreter.c:461
 #7  0x08160124 in runops_jit (interpreter=0x9d21008, pc=0x9f1b1c0) at 
 src/interpreter.c:528
 #8  0x08160495 in runops_int (interpreter=0x9d21008, offset=0) at 
 src/interpreter.c:744
 #9  0x081612d2 in runops (interpreter=0x9d21008, offs=0) at src/inter_run.c:81
 #10 0x080d6308 in Parrot_runcode (interpreter=0x9d21008, argc=1, 
 argv=0xfef6856c) at src/embed.c:762
 #11 0x080d614f in Parrot_runcode (interpreter=0x9d21008, argc=1, 
 argv=0xfef6856c) at src/embed.c:694
 #12 0x0809b4fb in main (argc=1, argv=0xfef6856c) at imcc/main.c:581
 
 % uname -a
 Linux jabberwock 2.6.5-1.358custom #2 Mon Aug 16 05:15:44 MDT 2004 i686 
 athlon i386 GNU/Linux
 
 % cat myconfig
 Summary of my parrot 0.1.1 configuration:
   configdate='Mon Nov 29 03:39:43 2004'
   Platform:
 osname=linux, archname=i386-linux-thread-multi
 jitcapable=1, jitarchname=i386-linux,
 jitosname=LINUX, jitcpuarch=i386
 execcapable=1
 perl=/usr/bin/perl
   Compiler:
 cc='gcc', ccflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS 
 -DDEBUGGING  -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 
 -I/usr/include/gdbm',
   Linker and Libraries:
 ld='gcc', ldflags=' -L/usr/local/lib',
 cc_ldflags='',
 libs='-lnsl -ldl -lm -lcrypt -lutil -lpthread -lrt -lgmp'
   Dynamic Linking:
 share_ext='.so', ld_share_flags='-shared -L/usr/local/lib -fPIC',
 load_ext='.so', ld_load_flags='-shared -L/usr/local/lib -fPIC'
   Types:
 iv=long, intvalsize=4, intsize=4, opcode_t=long, opcode_t_size=4,
 ptrsize=4, ptr_alignment=1 byteorder=1234,
 nv=double, numvalsize=8, doublesize=8
 


Re: [CVS ci] @ANON sub pragma

2004-11-28 Thread Luke Palmer
Leopold Toetsch wrote:
I've checked in intial support for anonymous subroutines.

  .sub foo @ANON

creates an anonymous subroutine.

On a semi-related note, can I get a classoffset without doing a hash
lookup?  That is, can I store the class number I get assigned somewhere
for quick fetching?

Thanks,
Luke



Re: PGE issues

2004-11-28 Thread Luke Palmer
Nicholas Clark writes:
 The appended patch makes it compile and pass tests. The change which caused
 the problem appears to be this one, which added pge_parseglob.c:
 
 http://www.nntp.perl.org/group/perl.cvs.parrot/7849
 
 I infer that dylib is not as forgiving of multiply defined symbols as ELF.

Thanks, applied.

Luke


Re: EcmaScript

2004-11-27 Thread Luke Palmer
Sam Ruby writes:
 Overall, JavaScript would be a good match for Parrot.  One place where 
 it would significantly diverge at the moment is in the concept of a 
 class.  Objects in JavaScript are little more than bundles of 
 properites, some of which may be functions.  And classes are essentially 
 templates for such objects.

That's why there's the find_method vtable.  I don't see how it would be
difficult to do in any way.

Luke


Reserved Word Heartburn

2004-11-24 Thread Luke Palmer
IMCC yells at me when I say:

.namespace [ Foo ]

.sub new
...
.end

While it's tolerable for local symbols, subs really have to be
named according to the interface.  Is it possible to allow:

.sub new
...
.end

?

Thanks,
Luke


Namespace-sub invocation syntax?

2004-11-24 Thread Luke Palmer
Since there is a syntax for invoking subs:

.sub foo
# ...
.end

.sub bar
foo()
.end

Should there be one for invoking a sub out of a namespace, say:

.namespace [ Foo ]

.sub bar
# ...
.end

.namespace [ Baz ]

.sub quux
[ Foo, bar ]()
.end

?

On a related note, are we supposed to name our namespaces [ Foo, Bar ] 
or [ Foo::Bar ] nowadays?  If the former, how do we name our classes?
Do we have to mangle those ourselves, or is there a way to put a class
in a namespace?

Luke


Re: p6ge compiler's namespace...

2004-11-22 Thread Luke Palmer
William Coleda writes:
 Should the compilation sub for p6g3 be in the root namespace as it is 
 currently, or moved to, say, a p6ge namespace?

I doubt we should be taking up the users' precious namespace with things
that aren't standardly prefixed.

It's likely that the p6ge_compile should be in P6GE, and that P6GEMatch
should be P6GE::Match (that is, [ P6GE, Match ]).

Anyone disagree?

Luke


Bug in method calling with nonconst keys

2004-11-22 Thread Luke Palmer
There's a pretty bad problem with calling the vtable proxy methods with
keys that aren't constant.  Best illustrated by example:

.sub _main
newclass $P0, Foo

find_type $I0, Foo
new $P1, $I0

$I1 = $P1[foo]

$S0 = foo
$I1 = $P1[$S0]

end
.end

.namespace [Foo]

.sub __get_integer_keyed
.param pmc key
print Key = 
print key
print \n
.return(0)
.end

The output is:

Key = foo
Key = 

Thanks,
Luke


Underscores on subs

2004-11-22 Thread Luke Palmer
Are we still supposed to put underscores before sub names?  Since they
don't get converted into PASM labels, there doesn't seem much need for
that restriction anymore.

Luke


[PATCH] Re: cvs commit: parrot/t/pmc object-meths.t

2004-11-22 Thread Luke Palmer
Leopold Toetsch writes:
   +if (arg-vtable-base_type == enum_class_Key) {
   +while (arg) {
   +UINTVAL flags = PObj_get_FLAGS(arg);
   +if (flags  KEY_register_FLAG) {
   +INTVAL n = PMC_int_val(arg);
   +if (flags  KEY_integer_FLAG)
   +REG_INT(n) = BP_REG_INT(bp, n);
   +else if (flags  KEY_pmc_FLAG)
   +REG_PMC(n) = BP_REG_PMC(bp, n);
   +else if (flags  KEY_string_FLAG)
   +REG_STR(n) = BP_REG_STR(bp, n);
   +}
   +arg = key_next(interpreter, arg);
   +}
   +}

Ack!  I don't think that's going to do it.  What if the
get_integer_keyed method were:

.namespace [Foo]

.sub __get_integer_keyed
.param pmc key
$S0 = bar
print Key = 
print key
print \n
.return(0)
.end

The first line overwrites the register that was there before, and you
get:

Key = foo
Key = bar

(Assuming that $S0 was coincidentally mapped to the same register...
which it was)

Even more subtle and no less wrong.

This patch solves the problem completely, but I'm wary of putting it in
because it's so evil ugly.  Is it safe to do this?

Index: src/inter_run.c
===
RCS file: /cvs/public/parrot/src/inter_run.c,v
retrieving revision 1.20
diff -u -u -r1.20 inter_run.c
--- src/inter_run.c 22 Nov 2004 12:07:22 -  1.20
+++ src/inter_run.c 22 Nov 2004 12:51:02 -
@@ -202,7 +202,7 @@
 STRING *meth, const char* sig, va_list ap)
 {
 opcode_t offset, *dest;
-struct parrot_regs_t *bp;
+struct parrot_regs_t *bp, *old_bp;
 int next[4], count[4];
 int i;
 PMC *ret_c;
@@ -284,30 +284,21 @@
 break;
 case 'P':   /* REG_PMC */
 arg = va_arg(ap, PMC*);
+
+/* Deal with key arguments, which might reference registers */
+if (arg-vtable-base_type == enum_class_Key) {
+/* XXX EVIL!  Making this work in a non-evil way requires
+ * a major rethinking in how this function operates... */
+old_bp = interpreter-ctx.bp;
+interpreter-ctx.bp = bp;
+arg = VTABLE_clone(interpreter, arg);
+interpreter-ctx.bp = old_bp;
+}
+
 if (next[2] == 16)
 VTABLE_set_pmc_keyed_int(interpreter, p3, i++, arg);
 else
 REG_PMC(next[2]++) = arg;
-/*
- * if this is a Key PMC with registers, pass on these
- * registers.
- * XXX make a distinct 'K' signature ?
- */
-if (arg-vtable-base_type == enum_class_Key) {
-while (arg) {
-UINTVAL flags = PObj_get_FLAGS(arg);
-if (flags  KEY_register_FLAG) {
-INTVAL n = PMC_int_val(arg);
-if (flags  KEY_integer_FLAG)
-REG_INT(n) = BP_REG_INT(bp, n);
-else if (flags  KEY_pmc_FLAG)
-REG_PMC(n) = BP_REG_PMC(bp, n);
-else if (flags  KEY_string_FLAG)
-REG_STR(n) = BP_REG_STR(bp, n);
-}
-arg = key_next(interpreter, arg);
-}
-}
 break;
 case 'N':   /* REG_NUM */
 if (next[3] == 16)


Re: p6ge compiler's namespace...

2004-11-22 Thread Luke Palmer
Jerome Quelin writes:
 On 04/11/22 07:14 -0700, Patrick R. Michaud wrote:
  Looks great to me -- I'll switch things around to (pardon the pun) match.
  They'll become P6GE::compile (compiler sub) and P6GE::Match, with
  a note that P6GE::compile is still subject to change.
 
 Well, since we're nitpicking conventions and consistency, what about:
 PGE::compile
 and PGE::match  (instead of Match)
 

Probably because PGE::compile is a sub and PGE::Match is a class :-)

Luke


Re: Continuations, basic blocks, loops and register allocation

2004-11-15 Thread Luke Palmer
Jeff Clites writes:
 On Nov 14, 2004, at 3:03 AM, Leopold Toetsch wrote:
 
 Matt Fowles [EMAIL PROTECTED] wrote:
 
 Yes, but in the case of the continuation resuming after foo, the
 continuation should restore the frame to the point where it was taken.
  Thus all of the registers will be exactly as they were when the
 continuation was taken (i.e. in the correct place).
 
 Yes, but Jeff's example wasn't really reflecting the problem.
 
 How come? (Not quibbling--just afraid I'm missing something.) It seems 
 that even this function body shows the problem:
 
   a = 1
   foo()
   print a
   b = 10
   return b
 
 It would seem (w/o continuations) that b should be able to re-use a's 
 register, but if it does then we'll print 10 instead of 1 the second 
 time.

It can.  You can't reuse the same PMC (if you're using PMCs), but you
can reuse the register. 

It all comes down to how the code is generated.  I've done this in a
project of mine, and it takes a little thought, but it works.  When you
take a continuation, you have to saveall before you take it, and
restoreall at the point where the continuation is to resume.

This is the trick I used (modulo brain code rot--I haven't written PIR
in a really long time):

saveall
$P0 = new Continuation
set_addr $P0, RESUME
save $P0
restoreall
restore $P0
# ... $P0 is your continuation

RESUME:
restoreall
# ...

On the other hand, this may be completely irrelavent, since I haven't
been following the discussion.

Luke


[PATCH] A little more Configure info

2004-11-14 Thread Luke Palmer
This adds information about the result of a test if the information is
terse enough.  i.e. changes:

Determining whether your cc is actually gcc...done.

Into:

Determining whether your cc is actually gccyes.

Enjoy,
Luke
Index: config/auto/aio.pl
===
RCS file: /cvs/public/parrot/config/auto/aio.pl,v
retrieving revision 1.1
diff -u -u -r1.1 aio.pl
--- config/auto/aio.pl  31 May 2004 11:54:46 -  1.1
+++ config/auto/aio.pl  14 Nov 2004 11:47:12 -
@@ -37,6 +37,7 @@
INFO=42\n
ok/x) {
print  (yes)  if $verbose;
+$Configure::Step::result = 'yes';
 
Configure::Data-set(
aio = 'define',
@@ -50,5 +51,6 @@
 else {
Configure::Data-set('libs', $libs);
print  (no)  if $verbose;
+$Configure::Step::result = 'no';
 }
 }
Index: config/auto/byteorder.pl
===
RCS file: /cvs/public/parrot/config/auto/byteorder.pl,v
retrieving revision 1.2
diff -u -u -r1.2 byteorder.pl
--- config/auto/byteorder.pl26 Feb 2004 00:43:02 -  1.2
+++ config/auto/byteorder.pl14 Nov 2004 11:47:12 -
@@ -34,16 +34,18 @@
   byteorder = $byteorder,
   bigendian = 0
 );
+$Configure::Step::result = 'little-endian';
   }
   elsif($byteorder =~ /^(8765|4321)/) {
 Configure::Data-set(
   byteorder = $byteorder,
   bigendian = 1
 );
+$Configure::Step::result = 'big-endian';
   }
   else {
 die Unsupported byte-order [$byteorder]!;
   }
 }
 
-1;
\ No newline at end of file
+1;
Index: config/auto/cgoto.pl
===
RCS file: /cvs/public/parrot/config/auto/cgoto.pl,v
retrieving revision 1.17
diff -u -u -r1.17 cgoto.pl
--- config/auto/cgoto.pl25 Mar 2004 16:52:53 -  1.17
+++ config/auto/cgoto.pl14 Nov 2004 11:47:12 -
@@ -56,9 +56,11 @@
   cg_flag   = '-DHAVE_COMPUTED_GOTO'
 );
 print  (yes)  if $verbose;
+$Configure::Step::result = 'yes';
   }
   else {
 print  (no)  if $verbose;
+$Configure::Step::result = 'no';
 Configure::Data-set(
   TEMP_cg_h= '',
   TEMP_cg_c= '',
Index: config/auto/env.pl
===
RCS file: /cvs/public/parrot/config/auto/env.pl,v
retrieving revision 1.4
diff -u -u -r1.4 env.pl
--- config/auto/env.pl  6 Mar 2004 22:24:30 -   1.4
+++ config/auto/env.pl  14 Nov 2004 11:47:13 -
@@ -50,15 +50,19 @@
 
 if ($setenv  $unsetenv) {
print  (both)  if $_[0];
+$Configure::Step::result = 'both';
 }
 elsif ($setenv) {
print  (setenv)  if $_[0];
+$Configure::Step::result = 'setenv';
 }
 elsif ($unsetenv) {
print  (unsetenv)  if $_[0];
+$Configure::Step::result = 'unsetenv';
 }
 else {
print  (no)  if $_[0];
+$Configure::Step::result = 'no';
 }
 }
 
Index: config/auto/funcptr.pl
===
RCS file: /cvs/public/parrot/config/auto/funcptr.pl,v
retrieving revision 1.4
diff -u -u -r1.4 funcptr.pl
--- config/auto/funcptr.pl  6 Mar 2004 22:24:30 -   1.4
+++ config/auto/funcptr.pl  14 Nov 2004 11:47:13 -
@@ -46,6 +46,7 @@
 }
 cc_clean();
 print  (yes)  if $_[0];
+$Configure::Step::result = 'yes';
   }
 }
 
Index: config/auto/gcc.pl
===
RCS file: /cvs/public/parrot/config/auto/gcc.pl,v
retrieving revision 1.20
diff -u -u -r1.20 gcc.pl
--- config/auto/gcc.pl  10 Nov 2004 00:29:26 -  1.20
+++ config/auto/gcc.pl  14 Nov 2004 11:47:13 -
@@ -42,6 +42,7 @@
   my $minor = $gnuc{__GNUC_MINOR__};
   unless (defined $major) {
 print  (no)  if $_[1];
+$Configure::Step::result = 'no';
 return;
   }
   if ($major =~ tr/0-9//c) {
@@ -55,6 +56,7 @@
 $gccversion .= .$minor if defined $minor;
   }
   print  (yep: $gccversion ) if $_[1];
+  $Configure::Step::result = 'yes';
 
   if ($gccversion) {
 # If using gcc, crank up its warnings as much as possible and make it
Index: config/auto/gmp.pl
===
RCS file: /cvs/public/parrot/config/auto/gmp.pl,v
retrieving revision 1.3
diff -u -u -r1.3 gmp.pl
--- config/auto/gmp.pl  12 Oct 2004 09:00:15 -  1.3
+++ config/auto/gmp.pl  14 Nov 2004 11:47:13 -
@@ -52,6 +52,7 @@
$test = cc_run();
if ($test eq 4950\n) {
print  (yes)  if $verbose;
+$Configure::Step::result = 'yes';
 
Configure::Data-set(
gmp = 'define',
@@ -65,6 +66,7 @@
 Configure::Data-set('ccflags', $ccflags);
 Configure::Data-set('linkflags', $linkflags);
 print  (no)  if $verbose;
+

Re: Does Parrot have True coroutines?

2004-11-05 Thread Luke Palmer
Klaas-Jan Stol writes:
 Hello,
 
 I spoke (through email) with Roberto Ierusalimschy, one of the creators of 
 the Lua programming language, and I said that Parrot has good support for 
 implementing coroutines and closures (heck, they are explicitly there).
 
 However, in a reply, Roberto asked:
 
 Are you sure Parrot support true coroutines? Does it integrate
 coroutines and closures correctly? (For instance, a single closure may
 refer to variables in several different coroutines.)

I have no idea what he means by that, but I'm sure parrot does it.
Parrot supports full contintuations, and coroutines can be implemented
using continuations.  I can't fathom anything you'd want to do with
coroutines that parrot's continuations wouldn't allow you to do.

 M, I wouldn't know.  In Lua, one can create a coroutine explicitly 
 (through a kind of package coroutine, an example is included:
 
 co = coroutine.create(function ()
   for i=1,10 do
 print(co, i)
 coroutine.yield()
   end
 end)

That one's easy.  Is that what he means by true coroutine?  What's a
fake coroutine?

Luke


Re: Please, Help on I/O

2004-11-05 Thread Luke Palmer
Christian Aperghis-Tramoni writes:
 I have the folowing program :
 
   print   Give me an integer number : n
   getstdinP0
   readline S1,P0
 
 Its execution gives :
 
 10
 Give me an integer number :
 
 How is it possible to flush stdout before reading the number.
 
 It means the equivalent of the $| in Perl.

No, it doesn't quite.  As in C++'s iostreams, streams ought to have the
ability to be tied.  That is, a call on one automatically flushes the
other.  stdout should be tied to stdin this way.

Luke


Re: No Cpow op with PMC arguments?

2004-11-05 Thread Luke Palmer
Jeff Clites writes:
 On Nov 4, 2004, at 8:29 PM, Brent 'Dax' Royal-Gordon wrote:
 This is true.  But how do you define a number?  Do you include
 floating-point?  Fixed-point?  Bignum?  Bigrat?  Complex?  Surreal?
 Matrix?  N registers don't even begin to encompass all the numbers
 out there.
 
 Floating point, and possibly integer. Those are the numeric primitives 
 of processors. Other aggregate mathematical types are always defined in 
 terms of those (in a computing context), one way or another.

The question is, though, how do compilers think of it?  That is, does
the compiler have the liberty, given the code:

$x ** $y

To emit:

pow $P0, x, y

Or must it use a named multimethod?

This is just the age-old question, is this operation fundamental
according to Parrot?

Luke


Re: Closures and subs

2004-11-04 Thread Luke Palmer
I haven't written PIR in a while, and I'm not terribly familiar with the
new changes, but I'll make some guesses.

Klaas-Jan Stol writes:
 function main()
   
local p = 123;   
local q = 345;
 
foo(q);
foo(q);
 
function foo(a) # nested function, it does have access to p in main
   print(p);
   p = p + p;
 
   print(typeof(a));
   print(a);
end
 end
 
 I would translate this to this PIR code:
 
 .sub _main
new_pad 0
 
# local p = 123
.local pmc p
p = new .PerlInt
p = 123
store_lex 0, p, p

If I recall, store_lex 0 is meaningless, and you ought to be using
either store_lex 1 or store_lex -1.  Not too sure about this one though.

 
# local q = 345
.local pmc q
q = new .PerlInt
q = 345
store_lex 0, q, q
 
newsub $P0, .Closure, _foo
 
# foo(q)
.arg q  
$P0()

Shouldn't this be:

$P0(q)

?  And likewise below?

 
# foo(q)
.arg q
$P0()
 
end
 .end
 
 .sub _foo
.param pmc a
   
# print(p);
find_lex $P0, p
print $P0
 
# p = p + p;
$P0 = $P0 + $P0

I feel a little uneasy about this line.  I'm not sure how PIR interprets
this.

store_lex p, $P0
 
# print(typeof(a));
$S0 = typeof a   
print $S0  # 
   
# print(a);
print a # ERROR!
 .end
 
 My problem with the last 2 statements is:
 - the statement print(typeof(a)); print SArray, which I don't understand.

I'm going to guess that that's due to your use of .arg above.

Luke


Re: pmc_type

2004-10-28 Thread Luke Palmer
Stphane Payrard writes:
 That would allow to implement typechecking in imcc.
 
   .sym Scalar a
   a = new .PerlInt  # ok.  Perlint is derived from Scalar

Ugh, yeah, but what does that buy you?  In dynamic languages pure
derivational typechecking is very close to useless.  The reason C++[1]
has pure derivational semantics is because of implementation.  The
vtable functions have the same relative address, so you can use a
derived object interchangably.  In a language where methods are looked
up by name, such strictures are more often over-restrictive than
helpful.

Anyway, that's just my rant.  If such a thing is to be in imcc, it
_must_ be optional without loss of feature.  I have quibble with the
automatic typechecking of .param variables for the same reason.

Luke

[1] And the reason Java has it is because C++ did.  Great design work,
guys.


Re: towards a new call scheme

2004-09-23 Thread Luke Palmer
Dan Sugalski writes:
 At 4:15 PM +0200 9/23/04, Leopold Toetsch wrote:
   return_cc() # 2) return via current continuation
 
 1) is only needed for special porposes, like passing the 
 continuation on to a different place. The normal way to return from 
 a sub will be 2)
 
 If that's in, access to CP1 as a return continuation will be deprecated.
 
 Well... should we? We're still passing the return continuation *in* 
 in P1, unless you want to move it out and unconditionally make it a 
 parameter to invoke. Which is OK, but we should be up front.

What we'd really like is to get the call chain.  That is, given a
continuation, can we query it to see what the previous continuation was?

Luke


Re: Namespaces

2004-09-13 Thread Luke Palmer
Jeff Clites writes:
 On Sep 12, 2004, at 8:43 PM, Luke Palmer wrote:
 
 Jeff Clites writes:
 On Sep 7, 2004, at 6:26 AM, Dan Sugalski wrote:
 
 *) Namespaces are hierarchical
 
 So we can have [foo; bar; baz] for a namespace. Woo hoo and all
 that. It'd map to the equivalent perl namespace of foo::bar::baz.
 
 How does this hierarchical nature manifest? I ask because I don't know
 of any languages which actually have nested namespaces,
 
 Other than, um, well, Perl.
 
 As an implementation detail yes, but I can't think of any Perl code 
 (except for explicit introspection) which reveals this. 

Does:

print ${$Foo::{Bar::}{baz}}

Count as explicit introspection?

 No, the lookup is not cascading downwards.  It is cascading upwards,
 however, so that in:
 
 [ foo; bar; baz ]
 
 The [ foo; bar ] part can be implemented differently.  This means
 that Python's namespaces and Perl's namespaces can have different
 semantics.  Picture a PythonStash and PerlStash pmc.
 
 Now it's true that if you think it's really important to tie
 namespaces such that you can take over the name resolution for
 [Foo], then you'd want the former. But I don't see that as really
 terribly useful

A debugger.

No, let me restate.

A DEBUGGER!

 --in the examples I've heard of (e.g., turning the namespace lookup
 into an Oracle fetch) have seemed to not provide much that a tied hash
 doesn't.  And there are currently a ton of, for instance, Text::Blah
 modules on CPAN--but that doesn't actually mean that they have
 anything to do with a Text namespace--that's not the intention, and
 most of these modules have nothing to do with each other. That naming
 is to keep them conceptually organized, not functionally.

Sure.  That's not the idea behind the heirarchical namespaces either.  A
lot of power comes out of being able to treat namespaces as a tree-like
data structure (I can actually attest to this: see Class::Closure), as
was pointed out before, being able to treat namespaces as a filesystem.

Also, Perl 6's classes will behave more heirarchically:

module Foo;

class Bar {...}
my $x = Bar.new;   # Actually works, while Bar is Foo::Bar.

I don't know how much that says for my argument though.

Luke


Re: Namespaces

2004-09-12 Thread Luke Palmer
Jeff Clites writes:
 On Sep 7, 2004, at 6:26 AM, Dan Sugalski wrote:
 
 *) Namespaces are hierarchical
 
 So we can have [foo; bar; baz] for a namespace. Woo hoo and all 
 that. It'd map to the equivalent perl namespace of foo::bar::baz.
 
 How does this hierarchical nature manifest? I ask because I don't know 
 of any languages which actually have nested namespaces,

Other than, um, well, Perl.

 so I'm not sure what this is meant to imply. In particular, if this
 implies cascading lookup (meaning that a symbol looked up in [foo;
 bar; baz] would fall back to looking in [foo; bar] if it
 didn't find it), than that's not how Perl5 packages work.

No, the lookup is not cascading downwards.  It is cascading upwards,
however, so that in:

[ foo; bar; baz ]

The [ foo; bar ] part can be implemented differently.  This means
that Python's namespaces and Perl's namespaces can have different
semantics.  Picture a PythonStash and PerlStash pmc.

Luke


Re: Namespaces

2004-09-07 Thread Luke Palmer
Dan Sugalski writes:
 Time to nail this.
 
 We need namespaces. Duh. We talked about this in the past.
 
 So, here's what I'm proposing. It'll be formalized into a PDD once we 
 hash things out.
 
 *) Namespaces are hierarchical
 
 So we can have [foo; bar; baz] for a namespace. Woo hoo and all 
 that. It'd map to the equivalent perl namespace of foo::bar::baz.
 
 *) Namespaces and sub-spaces can be overlaid or aliased

Can you say, in [foo; bar; baz], toss in a different namespace
implementation for [foo; bar] and have that call some function with
baz?  Will this work if it's [foo; bar; baz; quux]?

Luke



t/pmc/perlhash.t#20 failed

2004-08-22 Thread Luke Palmer
And as I look at the code for that test:

output_is( 'CODE',  'OUTPUT', Getting PMCs from string;int compound keys);
new P0, .PerlHash
new P1, .PerlHash
new P2, .PerlInt
set P2, 4
set P1[9], P2
set I0, P1[9]
print I0
print \n
set P0[a], P1
set I0, P0[a;9]
print Four is 
print I0
print \n
end
CODE
4
Four is 4
OUTPUT

It looks bogus.  Is a PerlHash supposed to accept an integer as a key?
The test output to this one is:

4
Four is 0

Here's my config:

Summary of my parrot 0.1.0 configuration:
  configdate='Sun Aug 22 12:48:16 2004'
  Platform:
osname=linux, archname=i386-linux-thread-multi
jitcapable=1, jitarchname=i386-linux,
jitosname=LINUX, jitcpuarch=i386
execcapable=1
perl=/usr/bin/perl
  Compiler:
cc='gcc', ccflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBUGGING  
-I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm',
  Linker and Libraries:
ld='gcc', ldflags=' -L/usr/local/lib',
cc_ldflags='',
libs='-lnsl -ldl -lm -lcrypt -lutil -lpthread -lrt -lgmp'
  Dynamic Linking:
so='.so', ld_shared='-shared -L/usr/local/lib -fPIC',
ld_shared_flags=''
  Types:
iv=long, intvalsize=4, intsize=4, opcode_t=long, opcode_t_size=4,
ptrsize=4, ptr_alignment=1 byteorder=1234,
nv=double, numvalsize=8, doublesize=8

Luke


Re: incremental garbage collection 1/2

2004-08-20 Thread Luke Palmer
Andr Pang writes:
 On 21/08/2004, at 5:48 AM, Leopold Toetsch wrote:
 
 3) The copying collector isn't integrated yet. But that should be easy.
 After finishing sweep and if there is some possible wastage in the
 memory pools, these get compacted.
 
 I thought Parrot wasn't using copying collectors, since you're exposing 
 PMC addresses to C?

It does.  Headers don't get copied, but buffers do, which is a pretty
elegant way to make a copying collector since you can keep the headers
in fixed-size object pools.  You will get in trouble if you try to copy
a header into a buffer somewhere and use that.  But you deserve to get
in trouble for being naughty.

Luke


Re: Proof of concept - hack_42 (was: the whole and everything)

2004-07-27 Thread Luke Palmer
Leopold Toetsch writes:
 $ time parrot -j -Oc c.imc
 in main
 20
 
 real0m1.069s
 user0m0.910s
 sys 0m0.020s
 
 $ time parrot -C ch.imc
 in main
 20
 
 real0m0.356s
 user0m0.250s
 sys 0m0.000s
 
 I think that a factor 3 improvement in function call speed (and a factor 
 of ~4 for overloaded vtables) is an argument to have a closer look at 
 this scheme. Here are again the key ideas:
 
 * the interpreter structure is the context, and the continuation
 * instead of pushing registers onto the register frame stacks an
   interpreter structure gets attached to each sub, and the
   subsequent code is running with that interpreter

Yes, this scheme is definitely worth a look.  I'm currently battling
Perl 5's function call speed in my own projects; i.e.:

for (1..4000) {
# OpenGL calls
}
# Fast enough (30 FPS)

-

sub draw {
# OpenGL calls
}
for (1..4000) {
draw()
}
# Not fast enough (18 FPS)

This isn't something I want to have to battle.  When a language severely
limits my ability to abstract, I consider not using that language in
favor of something that doesn't punish me.  I really don't want to give
C++ preference to Perl 6.

Luke


Re: Perl script to .so file

2004-07-14 Thread Luke Palmer
RaghavendraK 70574 writes:
 Hi,
 
 Am a hardcore C++ guy and don;t know much abt the Perl. But one of my
 friend has proved that the fastest way to RAD is Perl. I need to know
 if we can convert a Perl script to a dynamic link library under unix
 only.

I don't know what RAD is, but I know you're asking the wrong place.
Send your question to [EMAIL PROTECTED]

This is a list for discussing the design and implementation of the
Parrot virtual machine (parrotcode.org).

Luke


Re: Regexp::Parser v0.02 on CPAN (and Perl 6 regex question)

2004-07-01 Thread Luke Palmer
Jeff 'japhy' Pinyan writes:
 It'll appear shortly at your local mirror.  You can get it from my web
 site as well.
 
 I'll be writing an extension module tomorrow, and starting next week, I'll
 get started on Regexp::Perl6.

Cool.

 Which leads me to a question about Perl 6 regexes.  I'm writing an article
 on (?{ ... }) and (??{ ... }) for TPJ, and my conclusion translates some
 of the regexes I use to Perl 6.  I have a question about the backtrack
 control assertions : :: and :::.
 
 Do any of them cause the regex to fail entirely?  That is, not fail and
 try again from a different position in the string, but fail utterly?  My
 understanding is they don't, which is why there's commit, but I just
 wanted to be sure of this.

Yeah, that's right.  It's hard to do a commit in a Perl 5 regex, and
perhaps impossible generically.  

Luke

 Thanks for your time.
 
 -- 
 Jeff japhy Pinyan  [EMAIL PROTECTED]  http://www.pobox.com/~japhy/
 RPI Acacia brother #734   http://www.perlmonks.org/   http://www.cpan.org/
 CPAN ID: PINYAN[Need a programmer?  If you like my work, let me know.]
 stu what does y/// stand for?  tenderpuss why, yansliterate of course.
 


Re: Perl 6 regex parser

2004-06-27 Thread Luke Palmer
Jeff 'japhy' Pinyan writes:
 I am currently completing work on an extensible regex-specific parsing
 module, Regexp::Parser.  It should appear on CPAN by early July
 (hopefully under my *new* CPAN ID JAPHY).
 
 Once it is completed, I will be starting work on writing a subclass
 that matches Perl 6 regexes, Regexp::Perl6 (or Perl6::Regexp, or
 Perl6::Regexp::Parser).

Or Regexp::Parser::Perl6 :-)

 I think this might be of some use to the Perl 6 dev crew, but I'm not
 sure how.

It surely would.

The grammar for Perl 6 is going to be specified with Perl 6 patterns.
That presents us a little bootstrapping problem.  So the original goal
of Damian's Perl6::Rules was to transform this grammar back into Perl 5
patterns so they can parse the simplified Perl 6 code for Perl 6 and
compile a bootstrap.

But Perl6::Rules failed.  Due to serious bugs in the Perl 5 regex engine
having to do with executing code within regexes, Perl6::Rules couldn't
do its job properly.  So, for the bootstrap, we need something else, and
you're giving us an in.

My personal, nondivine plan would be to use your module to create a
driver-based parser.  That could then be used for the bootstrap instead.

A driver-based parser has a couple of advantages over regexes and even
Parse::RecDescent.  First, the parsing algorithm can be easily
customized, so we can play with hybrid models and see how the time
complexity works out.  Also, you can suspend the parsing in the middle
of execution, go somewhere else, and continue, which the Perl 6 parser
might just want to do (something like simulated coroutines).

In any case, such a parser would be really, really useful.

Luke


Re: The behaviour of iterators

2004-06-14 Thread Luke Palmer
Dan Sugalski writes:
 Once we decide how to *get* these things (see the previous e-mail) we 
 need to decide how they should work. We can fiddle around, but 
 honestly the scheme:
 
 1) They act as arrays--if you want the 18th element in the iterator, 
 access it directly
 2) They have 'next', 'previous', 'first', 'last', and 'reset' methods 
 to get the next, previous, first, or last element in the iterator, or 
 to reset the iterator to the beginning. Next, last, and reset change 
 the internal current element pointer, first and last don't.

Why not take a page from C++ and call previous and next Cinc and
Cdec, and then Cderef to get what it points to.  The ops are already
there.  Not sure about reset though.

Luke


Re: Slices and iterators

2004-06-14 Thread Luke Palmer
Dan Sugalski writes:
 The slice vtable entry should take as its parameter a slice pmc. This 
 should be an array of typed from/to values, so we can do something 
 like:
 
 @foo[0..2,4..8,12..];
 
 with three entries in the slice array--one with a from/to of 0/2, one 
 with 4/8, and one with 12/inf. 

Perl also has:

@foo[0..12 :by(3)]# 0,3,6,9,12

PDL has affine slices.

To me, it seems like the best thing to do is to give slice an iterator,
and slice would return an iterator that maps keys to values.  So, doing
C@bar = @foo[0..2,4..8,12...] would look something like:

Construct iterator for 0..2, 4..8, 12...
Call @foo-VTABLE_slice(iterator)
Initialize @bar from returned iterator

Iterators have the advantage over arrays since they can be infinite.
With arrays, how do you represent:

@foo[12... :by(3)]

Do we still have multidimensional keys? 

Luke



Re: Slices and iterators

2004-06-14 Thread Luke Palmer
Dan Sugalski writes:
 At 1:21 PM -0600 6/14/04, Luke Palmer wrote:
 Dan Sugalski writes:
  The slice vtable entry should take as its parameter a slice pmc. This
  should be an array of typed from/to values, so we can do something
  like:
 
  @foo[0..2,4..8,12..];
 
  with three entries in the slice array--one with a from/to of 0/2, one
  with 4/8, and one with 12/inf.
 
 Perl also has:
 
 @foo[0..12 :by(3)]# 0,3,6,9,12
 
 PDL has affine slices.
 
 Yeah, but at some point you have to draw the line and say This is as 
 far as we're going at the low level.
 
 Iterators have the advantage over arrays since they can be infinite.
 With arrays, how do you represent:
 
 @foo[12... :by(3)]
 
 And that is probably well past it. :)
 
 Do we still have multidimensional keys?
 
 Yes, we do.

Then these are both clear arguments for giving an iterator to slice
rather than an array.  We have no way to represent @foo[12... :by(3)],
so how do we represent it?  We have multidimensional keys but no way to
slice by them.

The former is solved by constructing the lazy iterator for C12... :by(3) 
and giving it to @foo's slice.  The latter is solved by creating an
iterator that yields multidimensional keys.

What advantage does the simple array case give, other than the one fewer
opcode from extracting the iterator?

Luke


Re: The behaviour of iterators

2004-06-14 Thread Luke Palmer
Dan Sugalski writes:
 At 1:08 PM -0600 6/14/04, Luke Palmer wrote:
 Dan Sugalski writes:
  Once we decide how to *get* these things (see the previous e-mail) we
  need to decide how they should work. We can fiddle around, but
  honestly the scheme:
 
  1) They act as arrays--if you want the 18th element in the iterator,
  access it directly
  2) They have 'next', 'previous', 'first', 'last', and 'reset' methods
  to get the next, previous, first, or last element in the iterator, or
  to reset the iterator to the beginning. Next, last, and reset change
  the internal current element pointer, first and last don't.
 
 Why not take a page from C++ and call previous and next Cinc and
 Cdec, and then Cderef to get what it points to.
 
 Because ++ and -- affect the value not the container. (There are days 
 when I think C++ does it like... is the near-perfect argument 
 against doing it one particular way... :) 

Heh, yeah.

 Next and previous are actions on the container.

Then how, if we have an array of iterators, do we increment an internal
iterator from an external one.  That is:

@foo = (1..5);
@bar = map { @foo.iter($_) } reverse 0..4;  # make an array of iterators

for @bar  0... - $x, $c {
if something($x) {
@bar[$c].next;
}
}

Without that awful reference of $c (awful not in a stylistic way, but in
a I-have-to-keep-the-index-around-too-wtf kind of way).

I'm arguing for an iterator to be an Iexplicit pointer, one that you
have to dereference, for this reason.

Luke


Re: Non-flow-control logical tests

2004-05-20 Thread Luke Palmer
Dan Sugalski writes:
 Right now the only good way to find out if a value is true or not is 
 to do something like:
 
  $I0 = 1
  if $P0, done
  $I0 = 0
  done:
 
 and look in $I0 for the result.

[snip]

 Anyway, because of it I'm pondering non-flowcontrol logical ops. That
 is, something like:
 
istrue I0, P5# I0 = 1 if P5 is true
isgt I0, P5, P6  # I0 = i if P5  P6

Definitely!  When I was writing my compiler to parrot I ran into that
awkward idiom over and over.  Something like this would be great.

Luke



Re: P6C: Parser Weirdness

2004-05-13 Thread Luke Palmer
Dan Sugalski writes:
 And personally I'd be happy to do violence to the dragon book. (Not 
 that it's *entirely* horrible, as I occasionally need to prop doors 
 open or shim a broken table leg temporarily...)
 
 But, anyway, snipping out the rest of this stuff...
 
 The big problem is that I don't know *how* to implement a mixed-type 
 parser generator. I'm not big on parsers in general, so I'm mostly 
 stuck with the literature if I need to write one from scratch.
 
 Since you've been itching to get into the internals anyway, this'd be 
 a good place to start, y'know. :-P

I'd be happy to draft out a model and do a first run implementation in
a little while.  I'm definitely a parsophile.

I've actually been pondering a Perl 5 alternative to P::RD that doesn't
become painfully slow once things get complex enough.  Pushing that in
Parrot would be even better though.

Luke


Re: Register stacks again

2004-05-08 Thread Luke Palmer
Leopold Toetsch writes:
 [1] yes I'm thinking of just one frame pointer :) Well, the whole scheme 
 makes a stack machine out of Parrot:
 
 I0,...In, In+1Ik, Ik+1...Il
 ^
 |
 frame
 pointer
 
 I0..In are the incoming function arguments
 In+1..Ik are the working registers of the function
 Ik+1...Il are outgoing args for a function call
 Calling a function is just a move of the frame pointer to Ik.
 The working register file size is adjusted to the actual needs of the 
 function.
 
 Actually registers would be arranged (I0,S0,P0,N0,I1,S1...)
 
 Is this scheme just crazy?

I love it.  Very clever, and certainly much less copying than we're
currently doing.

Luke


Re: assertion in headers.c breaks OS X

2004-05-07 Thread Luke Palmer
Nicholas Clark writes:
 Thanks. Everything compiles again now, and all tests pass
 (after I do the little .so - .dylib dance)

I'm new to OS X.  Might you describe said dance?

Luke


Re: A12: The dynamic nature of a class

2004-04-26 Thread Luke Palmer
Jeff Clites writes:
 I don't (right off) know of any other language which has something in 
 between variables and objects. That is, containers. They're feeling a 
 bit artificial.

Well... Perl 5.

Luke



Re: A12: The dynamic nature of a class

2004-04-22 Thread Luke Palmer
Aaron Sherman writes:
 But according to A12 as I understand it, the part BEFORE that, which
 looked innocently like a definition:
 
   class Joe { my $.a; method b {...} }
 
 would actually get turned into a BEGIN block that executes the body of
 the class definition as a closure in class MetaClass and stores the
 result into a new object (named Joe) of class Class.
 
 Perl 6's compiler does not (by default, at least) know how to run code.

There's where you're wrong.  In the static languages world, they like to
make the target architicture independent of the compiler's architecture.
C++ does this (and runs into rather a problem doing so, because of the
treatment of templates).

But Perl 6 is tightly coupled with Parrot.  Perl 6 will be a Parrot
program (even if it calls out to C a lot), and can therefore use the
compreg opcodes.  That means that any code executing in Parrot can call
back out to the Perl 6 compiler, and obviously the Perl 6 compiler can
call out to parrot.

So:

  eval eval 'eval 1';
#(a(b(c )) )

Goes through this process:

Perl 6 compiles (a)
Perl 6 tells Parrot to run (a)
Parrot calls out to Perl 6 to compile (b)
Perl 6 tells Parrot to run (b)
Parrot call out to Perl 6 to compile (c)
Perl 6 tells Parrot to run (c)
The result is 1
The result is 1
The result is 1
...

Luke



Hyper op summary

2004-04-21 Thread Luke Palmer
I was asked to post a small summary of hyper ops for you guys.  Here it
is:

Of course to hyperize an operator you surround it with , or just one
of them for a unary operator.

@a + @b
@a++

You can't necessarily override their semantics without chaning how Perl
6 interprets the syntax (i.e. grammar munge).  So for an operator ` :

@a ` @b

Always means:

map - $i { $a[$i] ` $b[$i] } 0..max([EMAIL PROTECTED], [EMAIL PROTECTED]);

Except that, if I recall, when one list runs out it uses a suitable,
operator-specific default.  That is, 0 for +, 1 for *, who-knows-what
for %.  I'm not certain on the details there.

When a binary op has one array and one scalar argument, the scalar side
is repeated:

@a + 1;

Means:

map { $_ + 1 } @a;

If you need to treat one side as scalar, you give it an explicit
context:

@a + [EMAIL PROTECTED]; # add the length of @b to @a

Of course to Parrot that means nothing.

And hyperization can be used on any operator declared with inifx:
prefix: or postfix:  (so not things that just *look* like operators,
like ,).

@a.[4]  # Slice the fifth column of a matrix

Is legal because a subscript is a postfix operator.

Luke


Re: Fun with nondeterministic searches

2004-04-06 Thread Luke Palmer
Dan Sugalski writes:
 I'm OK with moving the return continuation out of P1 and into 
 somewhere else--I can even see throwing it on the control stack. (Or 
 a special register, I can live with that as well)

I'd like to express my vote of confidence for an RC register, which is
put in the context structure.  Piers has made it clear that P1 needs
special handling, and I'd rather have special handling in a special
register.

IMCC would probably like it, too.

Luke



Re: Ulterior Reference Counting for DoD?

2004-03-24 Thread Luke Palmer
[EMAIL PROTECTED] writes:
 Hi guys,
 
 I know approximately zero about the DoD and GC mechanisms which are 
 currently used by Parrot, but I did attend a talk a few weeks ago about 
 a promising new method of garbage collection called Ulterior Reference 
 Counting:
 
 http://www.cs.purdue.edu/homes/hosking/690M/urc-oopsla-2003.pdf
 
 Two-line summary:
 
 * gives as good performance as the best generational garbage 
 collectors today, with
 * even better latencies than the best reference counting mechanisms 
 today
 
 In a nutshell, it combines the RC and generational techniques so that 
 generational collection is used for young objects in the nursery, and 
 RC is used for old objects.

It looks promising.   I'm not sure if Parrot needs it, though.  The DOD 
phase is relatively low latency (as compared to, eg. Sun Java).  But
parrot hasn't seen the likes of big, memory hungry projects yet.

I say it's worth looking into, and if not now, keeping it in mind if we
do run into problems.

Luke



Re: Optimizations for Objects

2004-03-21 Thread Luke Palmer
Piers Cawley writes:
  You seem to be mixing up different issues with that statement. Using
  plain Continuation PMCs for returning just from subroutines was dead
  slow, w or w/o COWed stacks.
 
 But when a Continuation is simply a collection of pointers to the tops
 of the various stacks (and I really do think it should include P1 in
 that list...) will it really be that slow? I'm surprised.

I implemented this in the register stacks, but I didn't spend any time
on optimization (and who knows, I may have even been marking the stacks
COW unnecessarily).  Continuation creation, call, and return had great
performance.  But the problem was that pushtop, etc. were much slower
than with the current scheme.  

I would love to see RetContinuation leave, honestly.  One of the
greatest things about CPS is that you can grab anybody's continuation
that they passed you and store it somewhere.  RetContinuation is just a
computed goto.

But more than I want to see RetContinuation leave, I want to see sub
calls fast.  

Maybe when I get some time again I'll implement single frame linked
stacks for a benchmark.

Luke


Re: imcc concat and method syntax

2004-03-13 Thread Luke Palmer
luka frelih writes:
 But how should the two interpretations of x.x be resolved? Is that
 concatenation or method calling?
 
 currently, the  pir line
   S5 = S5 . 'foo'
 produces
   error:imcc:object isn't a PMC
 
 concatenation with . seems to be gone
 i cannot think of a good replacement for it

Well, Perl 6 uses ~ .  I think that would be a fair replacement:

S5 = S5 ~ 'foo'

Luke


[PATCH] Prettifying parrotbench output

2004-03-09 Thread Luke Palmer
Here's a patch that prettifies parrotbench's output.  It also redirects
errors to /dev/null, and replaces them with !!! in the output.  The
benchmarking program is not the correct place to debug errors.

Luke

Index: tools/dev/parrotbench.pl
===
RCS file: /cvs/public/parrot/tools/dev/parrotbench.pl,v
retrieving revision 1.2
diff -u -r1.2 parrotbench.pl
--- tools/dev/parrotbench.pl9 Mar 2004 12:03:09 -   1.2
+++ tools/dev/parrotbench.pl9 Mar 2004 13:13:17 -
@@ -54,6 +54,8 @@
 my $help= 0;
 my $list= 0;
 my $time= 0;
+my $sep = ;
+my $initialsp   = 0;
 
 GetOptions
   'benchmarks=s'  = \$benchmarks,
@@ -70,7 +72,7 @@
 die Configuration file \$conf\ does not exist unless -e $conf;
 my $file = new IO::File( $conf)
   or die Unable to open configuration file \$conf\;
-my ( @names, %pathes, %suffixes, @suffixes );
+my ( @names, %pathes, %suffixes, @suffixes, @columns );
 my $i = 0;
 while ($file) {
 if (/^\s*(.*):\s*(.*):\s*(.*)$/) {
@@ -98,6 +100,7 @@
 my $benchmark = $1;
 if ( $benchmark =~ /$benchmarks/ ) {
 $list{$benchmark}++;
+$initialsp = length $benchmark if length $benchmark  $initialsp;
 foreach my $name ( @{ $suffixes{$suffix} } ) {
 $tree{$name}{$suffix}{$benchmark}++;
 }
@@ -121,36 +124,45 @@
 }
 
 # Benchmark
+$initialsp++;
+print   x ($initialsp - length $sep);
 foreach my $i ( 0 .. $#names ) {
 foreach my $j ( 0 .. $#{ $suffixes[$i] } ) {
-print \t$names[$i]($suffixes[$i][$j]);
+my $str = $names[$i]($suffixes[$i][$j]);
+push @columns, length($str) - 1;
+print $sep$str;
 }
 }
 print \n;
 foreach my $benchmark ( sort keys %list ) {
-print $benchmark;
+printf %-${initialsp}s, $benchmark;
 my $base = 0;
+my $count = 0;
 foreach my $i ( 0 .. $#names ) {
 foreach my $j ( 0 .. $#{ $suffixes[$i] } ) {
 if (   $tree{ $names[$i] }{ $suffixes[$i][$j] }{$benchmark}
  $pathes{ $names[$i] } )
 {
 my ( $scuser, $scsys ) = (times)[ 2, 3 ];
-system $pathes{$names[$i]} $directory/
-  . $benchmark.$suffixes[$i][$j]
-  . '/dev/null';
+my $retcode = system $pathes{$names[$i]} $directory/
+   . $benchmark.$suffixes[$i][$j]
+   . ' /dev/null';
+if ($retcode) {
+printf  %$columns[$count++]s$sep, !!!;
+next;
+}
 my ( $ecuser, $ecsys ) = (times)[ 2, 3 ];
 my $used = ( $ecuser - $scuser ) + ( $ecsys - $scsys );
 $base ||= $used;
 if ($time) {
-printf \t%.3fs, $used;
+printf %$columns[$count++].3fs$sep, $used;
 }
 else {
-printf \t%d%%, $used / ( $base / 100 );
+printf %$columns[$count++]d%%$sep, $used / ( $base / 100 );
 }
 }
 else {
-print \t-;
+printf  %$columns[$count++]s$sep, '-';
 }
 }
 }


Re: [PATCH] Prettifying parrotbench output

2004-03-09 Thread Luke Palmer
Leopold Toetsch writes:
 Luke Palmer [EMAIL PROTECTED] wrote:
  Here's a patch that prettifies parrotbench's output.  It also redirects
  errors to /dev/null, and replaces them with !!! in the output.  The
  benchmarking program is not the correct place to debug errors.
 
 Must be soemthing wrong here. Output is now totally messed up.

It's possible that your terminal isn't wide enough.  The change fits all
interpreters on one line without regard for the terminal width.   In
order to keep it readable, it makes the columns much wider.

Try running it against only one interpreter.

Indeed, something needs to be modified to keep the output to 72 columns,
somehow.

Luke

  Luke
 
 leo


Re: Another object bug

2004-02-26 Thread Luke Palmer
Dan Sugalski writes:
 At 2:38 PM +0100 2/26/04, Leopold Toetsch wrote:
 Simplifies compilers:
 
 newclass P1, Foo
 addattribute P1, i
 findclass I1, Foo
 new P2, I1
 
 classoffset I2, P2
 
 In static cases, where P2 is known to be a CFoo, attrib #0 (i) would
 be always 0. That is, the Cclassoffset opcode can be omitted in that
 case.
 
 That's a very rare case, honestly, and since arguably every object is 
 a subclass of the base object class and people will end up sticking 
 attributes and methods into the base object class it's going to 
 happen anyway.

And how do we deal with an object already in existence when the base
object gets an attribute added?

Luke



Re: Another object bug

2004-02-25 Thread Luke Palmer
Leopold Toetsch writes:
 Dan Sugalski [EMAIL PROTECTED] wrote:
  At 4:54 PM -0500 2/25/04, Simon Glover wrote:
   If I'm understanding the docs correctly, this should print '0'.
   Instead, it prints 'Array index out of bounds!'
 
  Another bug, though the offset ought to be 2 right now. (Attributes 0
  and 1 are taken by other things so they're valid)
 
 *Please* don't. Cclassoffset (and attribute access) should by all
 means start with 0.
 
 - Let's hide the internals
 - If that offset is ever changed, existing code will break
 - Its ugly
 
 We can afford one more instruction ( offset += POD_FIRST_ATTRIB; )
 that's just one CPU cycle.

Agreed.  Though I do like the ability to replace the class name PMC
currently in slot 0.  But then there are a lot of PMCs in a lot of
places that I'd like to replace, and the eventual Parrot::B should do
that for me.  So I vote Yes on offset 0.

Luke


Re: [perl #25960] [PATCH] COWed stack bug (was IMCC - PerlArray getting trounced)

2004-02-23 Thread Luke Palmer
Leopold Toetsch writes:
 Matt Fowles [EMAIL PROTECTED] wrote:
 
  This patch make the problem case submitted by Jeff Clites work.  All
  tests pass, and his sample has been added to the tests.
 
   struct RegisterChunkBuf* top = stack-top;
   if (top-used  1) {
  +top-used--;
 
 Thanks for the patch *but*:
 
 That's changing the COWed copy. It does the right thing for the test
 case but is still wrong.
 
 As already stated:
 - COWed buffers need distinct buffer headers pointing to the same
   buffer memory
 - unCOWing (regstack_copy_chunk) allocates new buffer memory and
   resets the COW flag

I headed in to fix this when I saw some new stuff in there.   Has this
been fixed?

Luke



Re: Rules for method resolution?

2004-02-14 Thread Luke Palmer
Michal Wallace writes:
 On Fri, 13 Feb 2004, Dan Sugalski wrote:
 
  We also have to have a way to fetch the method PMC for a named method
  for later use, which is where the interesting bits come in.
 
  This is required for a number of reasons, including Python, so we
  have to have it. The question is... *When* is the name resolved? That
  is, if we do:
 
  findmethod P4, Pobject, methodname
 
  does the method PMC that gets stuck in P4 represent the method
  methodname for the object *at that point in time* or does it
  represent the method *at the time it is invoked*? That is, do we
  defer actual lookup until invocation, or do we resolve at method find
  time?
 
 
 For python, you want P4 to contain the method as
 it is when this op is run.
 
 But the whole idea of a findmethod seems very
 unpythonic to me. In python, a method is just another
 attribute... One that happens to be callable and also
 happens to know what instance it's bound to.

As with Perl 6.  A sub object has a Cdo trait which specifies what to
do when it's called.

But I think findmethod is a good idea, cross-language-wise.  Each
language has a different idea of what a method is, and they can store it
that way.  As long as findmethod is vtableable, you can hook it up to
whatever system your language uses.

Luke


Re: [RFD] Symbol naming and imcc2

2004-02-11 Thread Luke Palmer
Jonathan Worthington writes:
 I would go with the idea of having a sigil that is placed before all local
 variables, and another (different!) sigil for registers (of the IMCC-handled
 type).  Anything without one of those is a direct register access.  Or a
 syntax error.  Clean, simple rules.  What the sigils are is relatively
 immaterial if what is placed after them (for locals, not registers) can
 contains non-alphanumeric stuff.  And whatever sigils a language wants can
 be put there.  This way, name mangling can be avoided - though arguably
 we're defining a syntax that auto-mangles.  :-)

Hooray!  That is precisely what sigils are for.  No use in making a
variable sigil that shares its name with a register sigil.

On the other hand, we could define four sigils and do away with the
$S358 syntax, like so:

?foo   # I register
+foo   # N register
~foo   # S register
$foo   # P register

(I took the most Perl6ish representitave sigils I could think of...
doesn't matter what they are, really)

 Jonathan
 
 [1] (C|S)hould we potentially provide a quoting mechanism, e.g. for
 languages that want variable names containing characters that are not
 allowed due to IMCC syntax rules?  Or is it up to the compiler to emit
 compliant names?  And I'm too scared of unicode to mention unicode
 variable names.

I can envisage something like:

$'%foo' = new PerlHash

But is that all that more readable than:

$Hfoo = new PerlHash

I would say we should definitely go with something like this if
registers held more permanent values.  But in writing my own compilers,
I've found that most of my register naming comes from prefixing a
constant string to an incremented counter.  Lexical pads already let
you do this, and those are the ones that need to.

Bascially, I think the current system works fine, but it would be nice
to namespace locals somehow.

Luke


Re: OO inheritance in a hacker style

2004-02-04 Thread Luke Palmer
Joseph Ryan writes:
 It's surely possible by modifying that class's DISPATCH.  
 
 Whether it should actually be in the language is up for debate.  I'd say
 that if you need to do this with any frequency whatsoever, you're not
 thinking about roles right.  A good example might be in order... :-)
  
 
 
 Well, what if the two classes you want to inherit from weren't
 designed with roles in mind?  For instance, there might be two
 CPAN modules that each have a dozen methods that you want to
 inherit, but they each have 1 that overlap whose conflict you
 want to easily resolve.

Cforget doesn't help you there.  That would presumably forget Iboth
methods, leaving you with none.  That doesn't sound too useful.  If you
could add a SomeClass:: on the front of the method, like:

class Foo is Bar is Baz {
forget Bar::frobnicate;
}

That looks backwards.  It would certainly make more sense to specify
which method you want to use, as opposed to specifying all the methods
but the one you want to use.

A syntax that is the opposite of forget -- one that lets you specify
which method to use without typing that parameter list twice -- might be
useful, but it's trivial enough to, er, forget for now.  I wonder
whether it's possible to say:

class Foo is Bar is Baz {
method frobnicate := Baz::frobnicate;
}

I know my syntax there isn't right quite. :-)

 Besides, the user is not thinking about XXX right sounds like we
 need to give a ++ to the pythonometer ;)

Let's say someone came on here and asked how to use regexes to make a
socket connection.  Surely the user is not thinking about regexes
right...  or sockets.

Luke


Re: Some minor decisions and timetables

2004-02-04 Thread Luke Palmer
Leopold Toetsch writes:
 I'd add some syntax additions and some notes:
 
 - Pn above is a NameSpace PMC, derived from Hash
 - an interpreter has a current namespace
 - located in the context, so that its restored after sub calls
 
getinterp P2
find_global Pn, P2[.]   # get current NS
find_global Pz, P2[..]  # get parent NS
set Pz, Pn[..]  # same
find_global Py, P2[/]   # get root of namespaces
find_global Px, Pn[Foo; Bar] # NS of Module Foo::Bar
find_global Pv, Pn[Foo; Bar], baz  # $Foo::Bar::baz var
find_global Pv, Pn[Foo; Bar; baz ] # same
set P2[.], Px   # switch current NS to Foo::Bar
find_global Pv, Pn[/; java; some; glob ] # /java.some.glob

Me gusta mucho!

This system allows neato things like anonymous namespaces, too.

I was thinking of something similar for classes.  An object holds a
reference to a class PMC which is used to fetch its methods.  This
allows different metaclasses (which are, again, required for Perl 6[1]).  
Maybe said class PMC is, by default, just an anonymous namespace PMC.

Luke



Re: Some namespace notes

2004-01-29 Thread Luke Palmer
Jeff Clites writes:
 We could certainly do some sort of language-specific prefixing, as Tim 
 suggested, but it seems that we are then going to trouble to unify, 
 only to immediately de-unify. Certainly, a random Java programmer 
 shouldn't have to worry about naming a class so that it doesn't 
 conflict with any class in any other language in the world--that's 
 silly, especially since this Java programmer may not even know about 
 parrot. (But it matters, if later someone wants to run his code on top 
 of parrot.) If we use per-language prefixing, then I'm certainly going 
 to have to be aware of what language is hosting a given class, and so 
 it seems natural to instead just use that class name as I would expect 
 it to be written--java.lang.String for Java, for example.
 
 And again, one of my basic points here is that although namespace 
 nesting could be useful for some things (maybe), it isn't what's going 
 on in most languages anyway. For instance, Java does not have nested 
 namespaces--it just happens to have a convention for namespace naming 
 which involves dots, and also uses a dot as the separator between a 
 namespace name and the variable or class name. (Though I suppose 
 there's really 2 separate, but related, issues--how namespace names are 
 represented internally, and whether these names imply namespace 
 nesting.)

But in fact, one of Perl 6's key features depends on heirarchical
namespaces: namespace aliasing.  And then if the Java programmer
accidentally named a class the same a some perl module (unlikely,
because you probably won't see Perl with a org::bazbar::Foo module),
Perl is able to move that namespace somewhere else to make room for
another conflicting module.

Luke


Re: Security problems with UnManagedStruct

2004-01-28 Thread Luke Palmer
Leopold Toetsch writes:
 This is unlimited self-inspection and self-modification :) With little 
 additions (nested structs) one could read/write all Parrot_Interp 
 internals (including possible security bits) and not only registers like 
 above. But current state is already sufficient to seriously damage the 
 interpreter ($P2 above is a struct representing the current interpreter)

Uh huh.  I saw this coming when we first started rediscussing
UnmanagedStruct.  I see it not as a security hole, but as serious
internal-hacking power without C code.

I don't think it's fair to say that if you do something like this that
the interpreter won't crash.  You're being truly, ungodly evil, and you
deserve what you get.  But I also think it's important that this stay
possible.

When we're worried about security, we don't allow dlfunc (except in
certain places) anyway.

Luke


Re: IMCC - PerlArray getting trounced

2004-01-25 Thread Luke Palmer
Will Coleda writes:
 I'm trying to track down a problem with a PerlArray that is getting 
 modified on me.
 
 I have a snippet of code like:
 
   typeof $S12, tcl_words
   $I12 = tcl_words
   print TYPEOF: 
   print $S12
   print \n
   print SIZEOF: 
   print $I12
   print \n
   (var_start_at,var_length,var_replace_str) = 
 __var_subst(var_current_word)
   typeof $S12, tcl_words
   $I12 = tcl_words
   print TYPEOF: 
   print $S12
   print \n
   print SIZEOF: 
   print $I12
   print \n
 
 Which is displaying:
 
 TYPEOF: PerlArray
 SIZEOF: 7
 TYPEOF: PerlArray
 SIZEOF: 1
 
 if I do a saveall/restoreall around the call to __var_subst, then I get 
 the expected:
 
 TYPEOF: PerlArray
 SIZEOF: 7
 TYPEOF: PerlArray
 SIZEOF: 7
 
 But then my return values are trounced.
 
 Is this a bug, or just a misunderstanding on my part?

It looks okay to me, but that depends on what __var_subst actually does.
Any continuation magic could make this choke.  What if you try a
savetop/restoretop instead?  I'm not sure if that works, because I'm not
sure whether IMCC moves return values into high registers after a call.
Or you could use the user stack to save your return values.

Of course these are temporary fixes.  I'd like to see the code of
__var_subst, and perhaps a few functions that it in turn calls, if any. 

Luke



Re: Benchmark Suite

2004-01-25 Thread Luke Palmer
Matt Fowles writes:
 All~
 
 Of late it seems that everybody has been throwing around their own 
 little homegrown benchmarks to support their points.  But many people 
 frequently point out that these benchmarks are flawed on one way or another.
 
 I suggest that we add a benchmark/ subdirectory and create a canonical 
 suite of benchmarks that exercise things well (and hopefully fully). 
 Then we can all post relative times for runs on this benchmark suite, 
 and we will know exactly what is being tested and how valid it is.

Like, for example, examples/benchmarks ?

It's quite difficult to create benchmarks that test *everything*.  But
any time someone posts a good benchmark, it really should go in here.
Hopefully with some documentation describing what it tests.

Luke


Re: Q: Sub vs Closure lexical pads

2004-01-21 Thread Luke Palmer
Leopold Toetsch writes:
 While trying to generate a small example that shows the memory 
 corruption problem reported by Steve, I came along these issues:
 
 a) [1] is .Sub, [2] is turned off
The subroutine prints main's $m - very likely wrong.

Well, Subs don't do anything with pads, so I'd say this is correct.

 Q: Should the Sub get a NULL scratch pad, or a new empty scratch pad stack?

Or just keep the existing one like current subs do.  A top-level sub
should be a closure under an empty pad stack.

The following correspond to Perl code (approximately):

 b) [1] is .Closure, [2] is turned off
The closure prints main - probably ok

eval 'my $m = main\n; ' . 'print $m';

 c) [1] is .Closure, [2] is newpad 0
Lexical '$m' not found

sub foo { print $m }
{ my $m = main\n; foo() }

 d) [1] is .Closure, [2] is newpad 1
prints main

my $m = main\n; sub { print $m }-();

 Q: What is correct?

It looks to me as though they all are.

Luke

 .sub _main
   new_pad 0
   new $P0, .PerlString
   set $P0, main\n
   store_lex -1, $m, $P0
   .sym pmc foo
   newsub foo, .Sub, _foo # [1]
   .pcc_begin prototyped
   .pcc_call foo
   .pcc_end
   pop_pad
   end
 .end
 .sub _foo prototyped
   # new_pad 1# [2]
   find_lex $P0, $m
   print $P0
   # pop_pad
   .pcc_begin_return
   .pcc_end_return
 .end
 
 leo
 


Re: [RESEND] Q: Array vs SArray

2004-01-21 Thread Luke Palmer
Dan Sugalski writes:
 At 9:38 AM +0100 1/21/04, Leopold Toetsch wrote:
 Dan Sugalski [EMAIL PROTECTED] wrote:
 
  Okay, at this point we've a pile of different array classes
 
  Before we go any further we need to figure out what we want.
 
 1) Unify setting/getting element count
- the elements() vtable is unused (not accessible by opcode)
- we use get_integer()
- push for Array is unusabale currently
- reserve array store size before filling can have performance
  benefits by avoiding reallocation
 
 Okay. So, let's do the following:
 
 *) Expose elements as an op. Two, actually, as we should have a get 
 and set version.

I'd like it to be possible to return infinity here.  If that means
setting a PMC or returning a PMC, I think that's fine.  As long as there
are also Ireg variants.

Luke


Re: Start of thread proposal

2004-01-19 Thread Luke Palmer
Dan's thread proposal mentions:
 =item Automatic PMC sharing will be provided
 
 When a PMC is placed into a container which is shared (including
 lexical pads and global namespaces) then that PMC will automatically
 be marked as shared. It is acceptable for this to trigger an
 exception if for some reason a PMC should not be shared between
 interpreters.
 
 PMCs are, by default, not shared. This avoids sharing overhead for
 PMCs which are only used as temporaries and not shared. (Note that
 this is dangerous, and may end up not being done, due to the sharing
 of continuations)

I don't know why this is dangerous.  A continuation is a data structure
just like an array or a hash.  When you share it, everything inside it
gets shared, too.  For a continuation, this could be an awful lot of
stuff, but it's the safe way.

Luke


Re: Calling conventions, IMC

2004-01-19 Thread Luke Palmer
Will Coleda writes:
 I didn't expect the code to be very usable, merely compilable. =-)
 
 If I want to call myself from myself, how do I do that then?
 
 For anything else, I do:
 
   .local Sub foo_sub
   newsub foo_sub, .Sub, __foo
 
   .pcc_begin prototyped
   .arg $S1
   .pcc_call foo_sub
   tellmeagainwhyineedthislabel:
   .result $S1
   .pcc_end
 
 
 If I can't explicitly create foo_sub if I'm in the middle of __foo, how 
 do I recurse using calling conventions

You could use P0, which holds the subroutine object.  Like using _ in
Perl 6.

Luke



[PATCH] Re: Register stacks organization

2004-01-18 Thread Luke Palmer
Leopold Toetsch writes:
 Luke Palmer clearly should, that optimizations WRT register frame stacks 
 are possible.
 The follwing numbers seem to second that:
 
 FRAMES_PER_CHUNK   time real  user
  4  1.2s  0.9
  8  1.6
 16  2.3 1.4
 
 These are runs of
  parrot -j -Oc examples/benchmarks/fib.imc
 on an unoptimized built parrot on Athlon 800.
 
 The main problem seems to be, that we are copying around a lot of memory:
 16 chunks * 32 regs * 4/8 bytes

I think it would be a good idea to reduce FRAMES_PER_CHUNK anyway.  The
more continuations are used, the more a high value hurts us.

I'm working on yet another scheme at the moment, with a special op that
pushes and clears simultaneously, to see if I can avoid copying
altogether!  It costs another indirection in the core registers, so I'm
worried that it will slow things down too much in general to be useful.
But we'll see what the benchmarks say.

 More fields for optimizations:
 - regstack_copy_chunk alwyas copies a full chunk (despite of used)
 - memory is allocated zeroed

Fixed in included patch.

 - the COW flags is only reset on one user of 2 provocing even
   more unneeded ocpies.

Again, I don't think this is hurting us.  If there's another copy, it's
in a continuation.  And unless continuations destroy themselves when
they're invoked, the stack they hold on to should stay COW.

 Comments welcome,
 leo

Luke


Index: include/parrot/register.h
===
RCS file: /cvs/public/parrot/include/parrot/register.h,v
retrieving revision 1.18
diff -u -r1.18 register.h
--- include/parrot/register.h   12 Jan 2004 09:50:24 -  1.18
+++ include/parrot/register.h   18 Jan 2004 18:28:54 -
@@ -50,7 +50,7 @@
 
 struct RegStack {
 struct RegisterChunkBuf* top;
-size_t chunk_size;
+size_t frame_size;
 };
 
 /* Base class for the RegChunk types */
Index: src/register.c
===
RCS file: /cvs/public/parrot/src/register.c,v
retrieving revision 1.38
diff -u -r1.38 register.c
--- src/register.c  17 Jan 2004 11:40:03 -  1.38
+++ src/register.c  18 Jan 2004 18:28:54 -
@@ -23,22 +23,22 @@
 buf = new_bufferlike_header(interpreter, sizeof(struct RegisterChunkBuf));
 Parrot_allocate_zeroed(interpreter, buf, sizeof(struct IRegChunkBuf));
 interpreter-ctx.int_reg_stack.top = buf;
-interpreter-ctx.int_reg_stack.chunk_size = sizeof(struct IRegChunkBuf);
+interpreter-ctx.int_reg_stack.frame_size = sizeof(struct IRegFrame);
 
 buf = new_bufferlike_header(interpreter, sizeof(struct RegisterChunkBuf));
 Parrot_allocate_zeroed(interpreter, buf, sizeof(struct SRegChunkBuf));
 interpreter-ctx.string_reg_stack.top = buf;
-interpreter-ctx.string_reg_stack.chunk_size = sizeof(struct SRegChunkBuf);
+interpreter-ctx.string_reg_stack.frame_size = sizeof(struct SRegFrame);
 
 buf = new_bufferlike_header(interpreter, sizeof(struct RegisterChunkBuf));
 Parrot_allocate_zeroed(interpreter, buf, sizeof(struct NRegChunkBuf));
 interpreter-ctx.num_reg_stack.top = buf;
-interpreter-ctx.num_reg_stack.chunk_size = sizeof(struct NRegChunkBuf);
+interpreter-ctx.num_reg_stack.frame_size = sizeof(struct NRegFrame);
 
 buf = new_bufferlike_header(interpreter, sizeof(struct RegisterChunkBuf));
 Parrot_allocate_zeroed(interpreter, buf, sizeof(struct PRegChunkBuf));
 interpreter-ctx.pmc_reg_stack.top = buf;
-interpreter-ctx.pmc_reg_stack.chunk_size = sizeof(struct PRegChunkBuf);
+interpreter-ctx.pmc_reg_stack.frame_size = sizeof(struct PRegFrame);
 
 Parrot_unblock_DOD(interpreter);
 }
@@ -112,10 +112,11 @@
 PObj_COW_CLEAR((PObj*) buf);
 
 Parrot_block_DOD(interpreter);
-Parrot_allocate(interpreter, buf, stack-chunk_size);
+Parrot_allocate(interpreter, buf, stack-frame_size * FRAMES_PER_CHUNK);
 Parrot_unblock_DOD(interpreter);
 
-memcpy(buf-data.bufstart, chunk-data.bufstart, stack-chunk_size);
+memcpy(buf-data.bufstart, chunk-data.bufstart, 
+stack-frame_size * FRAMES_PER_CHUNK);
 return buf;
 }
 
@@ -136,7 +137,8 @@
 sizeof(struct RegisterChunkBuf));
 
 Parrot_block_DOD(interpreter);
-Parrot_allocate_zeroed(interpreter, (PObj*)buf, stack-chunk_size);
+Parrot_allocate(interpreter, (PObj*)buf, 
+stack-frame_size * FRAMES_PER_CHUNK);
 Parrot_unblock_DOD(interpreter);
 
 buf-used = 1;


Re: [PATCH] Re: Register stacks organization

2004-01-18 Thread Luke Palmer
Luke Palmer writes:
  
 -memcpy(buf-data.bufstart, chunk-data.bufstart, stack-chunk_size);
 +memcpy(buf-data.bufstart, chunk-data.bufstart, 
 +stack-frame_size * FRAMES_PER_CHUNK);

Silly me -- left over from benchmarks.  Of course I mean:

+   memcpy(buf-data.bufstart, chunk-data.bufstart,
+   stack-frame_size * chunk-used);

Luke



Re: Vtables organization

2004-01-18 Thread Luke Palmer
Benjamin K. Stuhl writes:
 Other than the special case of :readonly, can you give me an example
 of when you'd need to, rather than simply writing a PMC class that
 inherits from some base? I'm having trouble thinking of an example of
 when you'd want to be able to do that... After all, since operator
 overloading and tying effectively _replace_ the builtin operations,
 what more does one need?

Well, other than Constant, we need to be able to put locking on shared
PMCs.  We'd like to add a debug trace to a PMC.  We could even make any
kind of PMC sync itself with an external source on access, though that's
a bit of a pathological case.

Indeed, all of this can be done, however, by subclassing Ref.  I think
the reason this isn't sufficient is that we want to change the actual
PMC into this new variant when it is possibly already in existence.
Like my Csupplant was evilly trying to do.  Perhaps there's a way to
get that working safely...

Luke

 -- BKS


Re: Some namespace notes

2004-01-16 Thread Luke Palmer
Jeff Clites writes:
 On Jan 15, 2004, at 8:26 PM, Benjamin K. Stuhl wrote:
 
 Thus wrate Dan Sugalski:
 At 10:13 AM -0800 1/13/04, Jeff Clites wrote:
 Short version: I was originally going to argue for fully 
 hierarchical namespaces, identified as above, but after turning this 
 over in my head for a while, I came to the conclusion that 
 namespaces are not conceptually hierarchical (especially as used in 
 languages such as Perl5 and Java, at least), so I'm going to argue 
 for a single string (rather than an array) as a namespace 
 identifier.
 ...
 Performance-wise, I would guesstimate that it's more-or-less a
 wash between parsing strings and parsing multidimensional keys,
 so as long as we precreate the keys (keep thm in a constant
 table or something), I see no performance issues.
 
 It turns out that it makes a big difference in lookup times--doing one 
 hash lookup v. several. I did this experiment using Perl5 (5.8.0): 
 Create a structure holding 1296 entries, each logically 12 characters 
 long--either one level of 12 character strings, or 2 levels of 6 
 character strings, or 3 levels of 4 character strings, or 4 levels of 3 
 character strings, and look up the same item 10 million times. Here is 
 the time it takes for the lookups:
 
 1-level: 14 sec.
 2-level: 20 sec.
 3-level: 25 sec.
 4-level: 32 sec.
 
 Conclusion: It's faster to do one lookup of a single, longer string 
 than several lookups of shorter strings.
 
 Of course, as Uri pointed out, even if we go with hierarchical 
 namespaces, we could implement these internally as a single-level hash, 
 behind the scenes, as an implementation detail and optimization.

My two cents:  I don't care as long as we can toss symbol tables around
as PMCs, and replace symbol tables with different (alternately
implemented) PMCs.   I think it's possible to do this using a clever
ordered hash scheme even if we go one level, but it's something to keep
in mind.

Luke

 JEff
 


  1   2   3   >