[PATCH] Fix MANIFEST
Adds rx.t, removes duplicated rx.c and puts everything back in alphabetical order. Simon --- MANIFEST.oldThu Jan 10 13:41:59 2002 +++ MANIFESTThu Jan 10 13:42:38 2002 @@ -187,10 +187,9 @@ pmc_pm.pl register.c resources.c -rx.c -rx.ops runops_cores.c rx.c +rx.ops stacks.c string.c t/harness @@ -206,6 +205,7 @@ t/op/pmc_perlarray.t t/op/pmc_perlhash.t t/op/pmc_perlstring.t +t/op/rx.t t/op/stacks.t t/op/string.t t/op/time.t
[PATCH] Minor fixes to rx.c
This fixes a couple of nits in rx.c: 1. There's no newline at the end, which makes gcc unhappy. 2. We should use NULL, not 0 or , for creating null pointers. Simon --- rx.c.oldWed Jan 9 22:35:14 2002 +++ rx.cThu Jan 10 14:14:36 2002 @@ -76,9 +76,9 @@ /*printf(rxP_get_substr(%p, %p(%d), %d, %d), interpreter, source, -1, startindex, length);*/ - ret=string_make(interpreter, , 0, 0, 0, 0); + ret=string_make(interpreter, NULL, 0, NULL, 0, NULL); string_substr(interpreter, source, startindex, length, ret); return ret; -} \ No newline at end of file +}
Re: [PATCH] Minor fixes to rx.c
On Thu, 10 Jan 2002, Simon Glover wrote: This fixes a couple of nits in rx.c: patch seems fine, but got me thinking... 2. We should use NULL, not 0 or , for creating null pointers. isn't a NULL pointer although at present there isn't any difference in the result of string_make(INTERP, ...) and string_make(INTERP, NULL, ...) I think this makes sense, but could do with being documented, also will the various string_* functions that take interpreters as args continue to do so, as if so I'll update the string docs. Also, I'm a bit concerned that our null termination games: s-bufstart = mem_sys_allocate(buflen+1); ... memset((char *)s-bufstart+s-bufused,0,1); Are going to lead to an eternity of OBO errors. Also if our encoding or output does not require termination, this is a waste of time. Also I don't think all the string functions update the termination when they add characters beyond bufused but below buflen, which means that any output function that needs null termination will have to check for this itself anyway. All in all, I think it would make more sense to keep the code that cares about termination away from the general string code as it's being a bit obscuring at present. Alex Gough
[PATCH] Skip tests, don't comment them out
As the subject line says. Simon --- macro.t.old Tue Nov 13 02:00:01 2001 +++ macro.t Thu Jan 10 15:52:28 2002 @@ -1,6 +1,6 @@ #! perl -w -use Parrot::Test tests = 8; +use Parrot::Test tests = 9; output_is( 'CODE', OUTPUT, macro, zero parameters ); answer macro @@ -47,19 +47,19 @@ 42 OUTPUT -# -# Can't test because I can't capture errors -# -#output_is( 'CODE', OUTPUT, macro, one parameter in call, not in def ); -#answermacro -# print A -#endm -# answer 42 -# print \n -#end -#CODE -#42 -#OUTPUT +SKIP: { skip(Await exceptions, 1); + +output_is( 'CODE', OUTPUT, macro, one parameter in call, not in def ); +answer macro + print A +endm + answer 42 + print \n +end +CODE +42 +OUTPUT +} output_is( 'CODE', OUTPUT, macro, one used parameter, register ); answer macro A
[PATCH] Fix return statement that breaks the build
This patch fixes parrotpointer.pmc, which tries to return 0 from a void function. Index: classes/parrotpointer.pmc === RCS file: /home/perlcvs/parrot/classes/parrotpointer.pmc,v retrieving revision 1.1 diff -u -r1.1 parrotpointer.pmc --- classes/parrotpointer.pmc 9 Jan 2002 21:22:14 - 1.1 +++ classes/parrotpointer.pmc 10 Jan 2002 16:37:09 - @@ -11,7 +11,7 @@ */ #include parrot/parrot.h -#define ERROR fprintf(stderr, An illegal operation was performed on a ParrotPointer (vtable function at %s line %d).\n, __FILE__, __LINE__); exit(1); return 0; +#define ERROR fprintf(stderr, An illegal operation was performed on a ParrotPointer +(vtable function at %s line %d).\n, __FILE__, __LINE__); exit(1); return; pmclass ParrotPointer { INTVAL type () { - D [EMAIL PROTECTED]
[PATCH] string_destroy in string.c
Hello, I'm not sure if this behavior was intended or not, but just in case I'm submitting this patch. The read op would segfault if you gave a string register as the first argument that didn't previously have a string value in it. --- will_fail.pasm --- read S0, 0, 1 end -- --- wont_fail.pasm --- set S0, read S0, 0, 1 end -- This patch might be futile since work is probably still being done on string support. =/ --Josh --- string.c.orig Thu Jan 10 11:26:39 2002 +++ string.cThu Jan 10 11:27:12 2002 @@ -71,7 +71,9 @@ */ void string_destroy(STRING *s) { -free_string(s); +if(s) { +free_string(s); +} } /* Ordinary user-visible string operations */
[APPLIED] (sort of) string_destroy in string.c
On Thu, 10 Jan 2002, Joshua Nye wrote: The read op would segfault if you gave a string register as the first argument that didn't previously have a string value in it. --- string.c.orig Thu Jan 10 11:26:39 2002 +++ string.cThu Jan 10 11:27:12 2002 @@ -71,7 +71,9 @@ */ void string_destroy(STRING *s) { -free_string(s); +if(s) { +free_string(s); +} } Thanks for spotting this one. I think it makes more sense to have the test in resources.c:free_string itself, then other functions cannot possibly make the same mistake themselves. I've made the needed changes. Alex Gough
Re: [PATCH] Minor fixes to rx.c
On Thu, Jan 10, 2002 at 03:06:38PM +, Alex Gough wrote: Also, I'm a bit concerned that our null termination games: s-bufstart = mem_sys_allocate(buflen+1); ... memset((char *)s-bufstart+s-bufused,0,1); Are going to lead to an eternity of OBO errors. Also if our encoding or output does not require termination, this is a waste of time. Also I don't think all the string functions update the termination when they add characters beyond bufused but below buflen, which means that any output function that needs null termination will have to check for this itself anyway. All in all, I think it would make more sense to keep the code that cares about termination away from the general string code as it's being a bit obscuring at present. I would strongly recommend that perl6 mandates that buffers are not nul terminated. Anything that needs a nul should arrange for one to be appended. [eg by ensuring that the buffer is writable, extending it by one byte if needs be, and writing that nul, or by copying out the contents.] If there are no explicit nul bytes, and none needed to be added then as you say 0: Avoids lots of off by one errors. 1: Saves time adding a nul byte. [1 call to memcpy to set a buffer, rather than (a call of given length an explicit write of nul) or (add one to length call memcpy) if you know source has a nul byte] 2: It's more robust. If your code knows that it needs a nul byte, you don't need to ponder whether you can trust everyone else (eg the string functions) not to shaft you by buggily forgetting nul bytes and also 3: substrings can point into the buffers of other things. The last one lets you mmap a file (or however VMS does it faster still) and then make your scalars point into the mmap buffer, flagged copy on write. And if your grep-as-perl doesn't actually modify the buffer there's no copying. This assumes that the housekeeping of copy-on-write is less than the time spent copying. Nicholas Clark -- ENOJOB http://www.ccl4.org/~nick/CV.html
Re: [PATCH] Fix MANIFEST [APPLIED]
At 01:46 PM 1/10/2002 +, Simon Glover wrote: Adds rx.t, removes duplicated rx.c and puts everything back in alphabetical order. This was my bad. Applied, and thanks. Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: [PATCH] Skip tests, don't comment them out [APPLIED]
At 03:56 PM 1/10/2002 +, Simon Glover wrote: As the subject line says. Applied, thanks. Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
[PATCH] if (PerlArray)
The enclosed patch allows one to use the if op with a PerlArray, as in: new P0, PerlArray if P0, TRUE print false\n end TRUE: print true\n end Currently, this works the same way that if(@array) does in Perl, ie it's false if and only if the array has a length of zero. Patch also includes the appropriate regression test. It should be straightforward to add this to PerlHash as well, but my attempt to do so seems to have brought some bugs to light - currently investigating this. Simon --- default.pmc.old Sat Jan 5 08:00:01 2002 +++ default.pmc Thu Jan 10 15:39:11 2002 @@ -69,10 +69,10 @@ } BOOLVAL get_bool () { - /* Everything has to be true */ + /* Everything has to be false */ if ( SELF-vtable-get_integer(INTERP, SELF) == 0 SELF-vtable-get_number(INTERP, SELF) == 0.0 - string_bool(SELF-vtable-get_string(INTERP, SELF)) + string_bool(SELF-vtable-get_string(INTERP, SELF)) == 0 ) { return 0; --- perlarray.pmc.old Thu Jan 10 02:00:02 2002 +++ perlarray.pmc Thu Jan 10 15:38:08 2002 @@ -86,8 +86,7 @@ return key_pair-cache.struct_val; } -BOOLVAL get_bool () { -} +BOOLVAL get_bool () = default; void* get_value () { return SELF-cache; --- pmc_perlarray.t.old Thu Jan 10 15:41:40 2002 +++ pmc_perlarray.t Thu Jan 10 16:06:30 2002 @@ -1,6 +1,6 @@ #! perl -w -use Parrot::Test tests = 3; +use Parrot::Test tests = 4; output_is('CODE', 'OUTPUT', size of the array); new P0,PerlArray @@ -76,5 +76,38 @@ hey OUTPUT +output_is('CODE', 'OUTPUT', If P); +new P0, PerlArray +if P0, TR +print false\n +branch NEXT +TR: print true\n + +NEXT: set P0, 1, 0 +if P0, TR2 +print false\n +branch NEXT2 +TR2:print true\n + +NEXT2: new P1, PerlArray +set P1, 1 +if P1, TR3 +print false\n +branch NEXT3 +TR3:print true\n + +NEXT3: set P1, 0 +if P1, TR4 +print false\n +end +TR4:print true\n +end + +CODE +false +true +true +false +OUTPUT 1;
Re: Some random design notes
At 12:15 AM 1/10/2002 +, Tim Bunce wrote: On Wed, Jan 09, 2002 at 04:42:51PM +, Graham Barr wrote: On Tue, Jan 08, 2002 at 06:38:02PM -0500, Dan Sugalski wrote: # Attributes are done as a hash of hashes. Each interpreter has a # pointer to an attribute hash, whose keys are the attribute names. The # values will be hash pointers. Those hashes will each have a key which # is a PMC pointer (hashed up somehow) and the value is the attribute # value. If you're talking about 'is'-style attributes, why not have them be attached to the PMCs themselves? D'you want an attribute pointer for each PMC? (I've considered it, but for the moment I think it'll be too expensive. Might be wrong) This sounds rather like perl5's optional list of arbitrary 'magic'. Can't PMC's be 'upgraded' so only carry the overhead if needed? Not easily. PMC structs are fixed size, unlike perl's variable-size SVs. I was hoping to keep attributes as OOB data, since I'm not sure it'll be used enough to be worth being in-band. However... On the other hand when a variable is garbage collected you have to walk the hash of hashes to clear out the attributes. Also what happens when you move the PMC during garbage collection, will the key in the hash change ? Good points. This is a darned good point. Good enough to dump my OOB argument, I think. A PMC may have a flag to show if it has any entries in the global table, but it is probably just a trade off between space and performance. Tim [who's not really been paying attention, so ignore me if I'm being daft]. Nah, you're making sense. Besides, vtables are all your fault in the first place, so I ought to be listening... :) Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
[PATCH] Hash bug
Well, actually two bugs. The first is an off-by-one error in key.c than can cause parrot to segfault if hash % NUM_BUCKETS happens to be zero. The other is a bug in the PerlHash init() code that causes new PerlHash PMCs to start with the wrong size. Both fixed below; also tests to prevent them recurring. Simon --- key.c.old Wed Jan 9 20:00:01 2002 +++ key.c Thu Jan 10 17:41:01 2002 @@ -327,7 +327,7 @@ if(bucket != NULL) { hash = hash % NUM_BUCKETS; /* Resize the hash here rather than set an initial size. */ - if(hash key-size) { + if(hash = key-size) { key_set_size(interpreter,key,hash+1); } if(key-keys[hash].type != enum_key_undef) { --- perlhash.pmc.oldThu Jan 10 15:40:08 2002 +++ perlhash.pmcThu Jan 10 17:40:32 2002 @@ -24,7 +24,7 @@ void init () { SELF-cache.struct_val = key_new(INTERP); - key_set_size(INTERP,SELF-cache.struct_val,1); + key_set_size(INTERP,SELF-cache.struct_val,0); } void clone (PMC* dest) { --- pmc_perlhash.t.old Thu Jan 10 15:41:47 2002 +++ pmc_perlhash.t Thu Jan 10 17:56:55 2002 @@ -1,6 +1,6 @@ #! perl -use Parrot::Test tests = 5; +use Parrot::Test tests = 7; output_is('CODE', OUTPUT, simple set / get); new P0, PerlHash @@ -23,6 +23,28 @@ 2 OUTPUT +output_is('CODE', OUTPUT, more than one PerlHash); + new P0, PerlHash + set S0, key + set P0, 1, S0 + +new P1, PerlHash +set S1, another_key +set P1, 2, S1 + + set I0, P0, S0 + set I1, P1, S1 + + print I0 + print \n + print I1 + print \n +end +CODE +1 +2 +OUTPUT + output_is('CODE', OUTPUT, hash keys with nulls in them); new P0, PerlHash set S0, parp\0me @@ -112,5 +134,23 @@ 2 2 OUTPUT + + +# NB Next test depends on key2 hashing to zero, which it does with +# the current algorithm; if the algorithm changes, change the test! + +output_is('CODE', OUTPUT, key that hashes to zero); +new P0, PerlHash +set S0, key2 +set P0, 1, S0 +set I0, P0, S0 + print I0 + print \n + end +CODE +1 +OUTPUT + + 1;
Re: [PATCH] Minor fixes to rx.c
I would strongly recommend that perl6 mandates that buffers are not nul terminated. Anything that needs a nul should arrange for one to be appended. [eg by ensuring that the buffer is writable, extending it by one byte if needs be, and writing that nul, or by copying out the contents.] If this recommendation is to be implemented, it probably needs to be done sooner rather than later, before too much code appears that needs to be changed. I would suggest implementing a function to supply a terminated string if required, something like string_nt() below; this returns a char* rather than a STRING* because terminated strings should only be used for passing outside parrot. s-buflen has been changed to be the true allocated length; the extra byte could be removed along with the actual null-termination once nobody relies on it; however, if memory allocation will be happening on fixed boundaries, it may make sense to round the buffer length up to match. -- Peter Gibbs EmKel Systems Index: include/parrot/string.h === RCS file: /home/perlcvs/parrot/include/parrot/string.h,v retrieving revision 1.20 diff -c -r1.20 string.h *** include/parrot/string.h 7 Jan 2002 22:09:15 - 1.20 --- include/parrot/string.h 10 Jan 2002 18:18:23 - *** *** 67,72 --- 67,74 STRING* string_transcode(struct Parrot_Interp *interpreter, const STRING *src, const ENCODING *encoding, const CHARTYPE *type, STRING **d); + char* + string_nt(struct Parrot_Interp *interpreter, const STRING *s); void string_init(void); INTVAL Index: string.c === RCS file: /home/perlcvs/parrot/string.c,v retrieving revision 1.38 diff -c -r1.38 string.c *** string.c 9 Jan 2002 22:35:14 - 1.38 --- string.c 10 Jan 2002 18:18:33 - *** *** 49,55 s-encoding = encoding; s-flags = flags; s-type = type; ! s-buflen = buflen; if (buffer) { mem_sys_memcopy(s-bufstart, buffer, buflen); --- 49,55 s-encoding = encoding; s-flags = flags; s-type = type; ! s-buflen = buflen+1; if (buffer) { mem_sys_memcopy(s-bufstart, buffer, buflen); *** *** 201,206 --- 201,221 } return dest; + } + + /*=for api string string_nt + * return pointer to null-terminated character string + * this may be the original string's buffer or a copy thereof + */ + char* + string_nt(struct Parrot_Interp *interpreter, const STRING *s) { + + if (s-buflen s-bufused+1) { + s = string_make(interpreter, s-bufstart, s-bufused+1, + s-encoding, s-flags, s-type); + } + memset((char *)s-bufstart+s-bufused,0,1); + return s-bufstart; } /* vtable despatch functions */
Proposal: Naming conventions
The naming of things is getting a bit messy. I'd like to propose a convention that I use in my work. It's compatible with the last draft of PDD 7 that I could find: http://www.mail-archive.com/perl6-internals%40perl.org/msg03422.html By example: struct somename_t { ... }; typedef struct somename_t { ... }* Somename; The non-typedef'd name of a struct type ends in _t. (If you don't mind typing the 'struct', then surely you won't mind typing the _t.) Typedef'd names are always capitalized (as in PDD 7). If a particular type is almost always used as a pointer (eg Parrot_Interp), then the capitalized name refers to a pointer type. (Think of a Foo as a reference to a struct foo_t). This is the case for nearly all struct typedefs. Some things are *never* used without going through a pointer, in which case the _t version is unnecessary. I usually only use _t names for recursive data structures like linked lists and trees. But maybe some compilers don't like Foo foo = (Foo) malloc(sizeof(*foo)); ? Does ANSI allow using sizeof on a variable declared on the same line? The current struct Parrot_Interp { ... }; would become typedef struct Parrot_interp_t { ... }* Parrot_Interp; or if you like splitting things up struct Parrot_interp_t { ... }; typedef struct Parrot_interp_t* Parrot_Interp; and in the gazillion places where 'struct Parrot_Interp *' is used, we'd use 'Parrot_Interp' instead. Imagine, we'll save 8 bytes * 1 gazillion occurrences! More function declarations will fit on a line! World peace will ensue and the moon will become habitable again! If people have visceral objections to typedef'ing pointers, I'm fine with dropping that part of the proposal. I'd just like to see struct Stack_Entry *push_generic_entry(struct Parrot_Interp *, struct Stack_Entry **top, void *thing, INTVAL type, void (*cleanup)(struct Stack_Entry *)); become more like Stack_Entry push_generic_entry(Parrot_Interp, Stack_Entry *top, void *thing, INTVAL type, void (*cleanup)(Stack_Entry)); Oops. Except PDD 7 says that it's Stack_Entry push_generic_entry(Parrot_Interp, Stack_Entry *top, void *thing, INTVAL type, void (*cleanup)(Stack_Entry)); (someday I'll figure out why our stacks are obsessed with passing back their tops all the time.)
Re: Proposal: Naming conventions
Foo foo = (Foo) malloc(sizeof(*foo)); ? Does ANSI allow using sizeof on a variable declared on the same line? Wouldn't sizeof(Foo) be safer here? At the logical time of the call *foo points to undefined. Technically its not a deref but still looks scary. In C++ it might be confusing if you were to cast it as: // If it were really C++ we would probably be using new() Foo foo = (FooBar) malloc(sizeof(*foo)); What type is *foo then? Should be Foo, but what if FooBar was of different size, it might not be an obvious bug to someone that just came along and tweaked your code. Not sure if I made any point here but it seemed interesting. :) and in the gazillion places where 'struct Parrot_Interp *' is used, we'd use 'Parrot_Interp' instead. Imagine, we'll save 8 bytes * 1 gazillion occurrences! More function declarations will fit on a line! World peace will ensue and the moon will become habitable again! Agreed, in my code I defined a macro theINTERP for that whole aggravation which sort of hides the type in the macro but as we only have 1 interp type... If people have visceral objections to typedef'ing pointers, I'm fine with dropping that part of the proposal. I'd just like to see I've always been uncomfortable with that practice, its one part of the whole Win32 world I hate. If you stick with the practice then you either end up making a new typedef for every level of indirection or you drop to using * (some typedef), etc. Now if it were C++ and we were using a smart pointer class I don't mind the practice. Anyway I'm one opinion in a haystack. -Melvin Smith IBM :: Atlanta Innovation Center [EMAIL PROTECTED] :: 770-835-6984
Re: Proposal: Naming conventions
Eep, to answer the original subject of your mail, I think its a good idea to start with the _t typedef standard. -Melvin Smith IBM :: Atlanta Innovation Center [EMAIL PROTECTED] :: 770-835-6984
Re: Proposal: Naming conventions
On Thu, 10 Jan 2002, Steve Fink wrote: The naming of things is getting a bit messy. I'd like to propose a convention that I use in my work. It's compatible with the last draft of PDD 7 that I could find: http://www.mail-archive.com/perl6-internals%40perl.org/msg03422.html I agree, we should definitly be sticking to a standard. I think, though, that putting the * in the typedefs for structs might be a little confusing; at least, on all the systems I've worked on that do this, I've been confused. But that might just be me. :-) My question is (again, I suppose): What about INTVAL, NUMVAL, STRING, and friends? I have the distinct impression that they were uppercased somewhat in veneration of our old perl5 frieds IV, SV, PV, NV, etc. I think they should adhere to the same standard as everything else... whatever that may be. After looking through PDD 7, I wonder: were we planning on doing any of this stuff? If so, maybe we should step back for a moment and do it. :-) If developers are expected to follow these guidelines (not that I've done any developing, but hey), then everyone should take the time to read this file (and probably the other PDDs), and maybe think about fixing up either the code to follow the PDD, or the PDD to follow the code. - D [EMAIL PROTECTED]
Re: Proposal: Naming conventions
On Thu, Jan 10, 2002 at 02:31:24PM -0600, David M. Lloyd wrote: After looking through PDD 7, I wonder: were we planning on doing any of this stuff? If so, maybe we should step back for a moment and do it. :-) If developers are expected to follow these guidelines (not that I've done any developing, but hey), then everyone should take the time to read this file (and probably the other PDDs), and maybe think about fixing up either the code to follow the PDD, or the PDD to follow the code. A first step might be posting PDD 7, or the last known version if David Mitchell can't be found, on dev.perl.org.
[PATCH] Fix 'basic' test 1 for sizeof(opcode_t) != sizeof(INTVAL)
Just as the subject says. Index: core.ops === RCS file: /home/perlcvs/parrot/core.ops,v retrieving revision 1.72 diff -u -r1.72 core.ops --- core.ops9 Jan 2002 17:24:11 - 1.72 +++ core.ops10 Jan 2002 21:47:29 - @@ -253,7 +253,7 @@ =cut inline op print(in INT) { - printf(INTVAL_FMT, $1); + printf(INTVAL_FMT, (INTVAL)$1); goto NEXT(); } @@ -301,7 +301,7 @@ break; default: file = (FILE *)$1; } - fprintf(file, INTVAL_FMT, $2); + fprintf(file, INTVAL_FMT, (INTVAL)$2); goto NEXT(); } - D [EMAIL PROTECTED]
stacks.[ch] modification
I needed to use a generic stack, and the API in stacks.[ch] really bothered me: - it relied on the caller to maintain a pointer to the top of the stack, rather than having a stack ADT that knows its own top. That meant that anyone including a stack in its structure had to keep around two variables and be sure to pass them together to many routines. - It used funky pointer masking to jump between the above two variables behind your back. - The main type exported was 'struct Stack_Chunk', which sounds to me like an internal implementation detail. I changed its internal data structure from a doubly-linked list to a circular, doubly-linked list (so the Stack could quickly find its own top by looking in the its chunk-prev chunk). The API changed quite a bit. For example: void new_stack(struct Parrot_Interp *, struct StackChunk **, struct Stack_Entry **); struct Stack_Entry *push_generic_entry(struct Parrot_Interp *, struct Stack_Entry **top, void *thing, INTVAL type, void (*cleanup)(struct Stack_Entry *)); are now Stack new_stack(struct Parrot_Interp *); void stack_push(struct Parrot_Interp *, Stack, void *thing, INTVAL type, void (*cleanup)(Stack_Entry)); That means that interpreter-user_stack_top and -user_stack_base have been collapsed to -user_stack, and likewise for -control_stack. And to forestall any objections based on speed, on my machine the new version is slightly faster. All tests pass. Well, they all pass for non-JIT runs, anyway. I noticed that if I change test_prog in Parrot/Config.pm from 'test_parrot' to 'test_parrot -j' and do a 'make test', quite a few things fail with or without my change. Is that bad? Index: core.ops === RCS file: /home/perlcvs/parrot/core.ops,v retrieving revision 1.72 diff -a -u -r1.72 core.ops --- core.ops9 Jan 2002 17:24:11 - 1.72 +++ core.ops10 Jan 2002 21:51:55 - @@ -2266,13 +2266,13 @@ op entrytype(out INT, in INT) { INTVAL depth; - struct Stack_Entry *entry; - depth = stack_depth(interpreter, interpreter-user_stack_base); + Stack_Entry entry; + depth = stack_depth(interpreter, interpreter-user_stack); if (depth = $2) { INTERNAL_EXCEPTION(99, Stack Depth wrong); } - entry = stack_entry(interpreter, interpreter-user_stack_base, $2); + entry = stack_entry(interpreter, interpreter-user_stack, $2); $1 = get_entry_type(interpreter, entry); goto NEXT(); } @@ -2292,22 +2292,22 @@ =cut inline op save(in INT) { - push_generic_entry(interpreter, interpreter-user_stack_top, ($1), STACK_ENTRY_INT, NULL); + stack_push(interpreter, interpreter-user_stack, ($1), STACK_ENTRY_INT, NULL); goto NEXT(); } inline op save(in NUM) { - push_generic_entry(interpreter, interpreter-user_stack_top, ($1), STACK_ENTRY_FLOAT, NULL); + stack_push(interpreter, interpreter-user_stack, ($1), STACK_ENTRY_FLOAT, NULL); goto NEXT(); } inline op save(in PMC) { - push_generic_entry(interpreter, interpreter-user_stack_top, $1, STACK_ENTRY_PMC, NULL); + stack_push(interpreter, interpreter-user_stack, $1, STACK_ENTRY_PMC, NULL); goto NEXT(); } inline op save(in STR) { - push_generic_entry(interpreter, interpreter-user_stack_top, $1, STACK_ENTRY_STRING, NULL); + stack_push(interpreter, interpreter-user_stack, $1, STACK_ENTRY_STRING, NULL); goto NEXT(); } @@ -2327,22 +2327,22 @@ =cut inline op restore(out INT) { - pop_generic_entry(interpreter, interpreter-user_stack_top, ($1), STACK_ENTRY_INT); + stack_pop(interpreter, interpreter-user_stack, ($1), STACK_ENTRY_INT); goto NEXT(); } inline op restore(out NUM) { - pop_generic_entry(interpreter, interpreter-user_stack_top, ($1), STACK_ENTRY_FLOAT); + stack_pop(interpreter, interpreter-user_stack, ($1), STACK_ENTRY_FLOAT); goto NEXT(); } inline op restore(out PMC) { - pop_generic_entry(interpreter, interpreter-user_stack_top, ($1), STACK_ENTRY_PMC); + stack_pop(interpreter, interpreter-user_stack, ($1), STACK_ENTRY_PMC); goto NEXT(); } inline op restore(out STR) { - pop_generic_entry(interpreter, interpreter-user_stack_top, ($1), STACK_ENTRY_STRING); + stack_pop(interpreter, interpreter-user_stack, ($1), STACK_ENTRY_STRING); goto NEXT(); } @@ -2357,7 +2357,7 @@ =cut inline op rotate_up(in INT) { - rotate_entries(interpreter, interpreter-user_stack_base, interpreter-user_stack_top, $1); + rotate_entries(interpreter, interpreter-user_stack, $1); goto NEXT(); } @@ -2400,7 +2400,7 @@ =cut inline op bsr (in INT) { - push_generic_entry(interpreter, interpreter-control_stack_top, CUR_OPCODE + 2, STACK_ENTRY_DESTINATION, NULL); + stack_push(interpreter, interpreter-control_stack, CUR_OPCODE + 2, +STACK_ENTRY_DESTINATION, NULL); goto OFFSET($1); } Index: interpreter.c === RCS file: /home/perlcvs/parrot/interpreter.c,v retrieving
New benchmark
Okay, I've abused examples/assembly/life.pasm to be a benchmark program. It now will time generations/sec, and does rather more than mops.pasm does. Something for testing as we go along. (The numbers are rather smaller, but it does do a lot more than mops does) Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
[PATCH] Make save work for sizeof(opcode_t) != sizeof(INTVAL) (caveat)
This patch will clash with Steve Fink's stacks patch, but you get the idea. Also, there's gonna be a small speed hit that I don't know how to get around. The problem is that when you save an int constant on the stack in a mixed 32/64-bit system, the int type is 8 bytes but the pointer points to four bytes of int constant and four bytes of... something else. So it has to be copied out into a temp variable before being referenced. I'll leave it to greater minds to find a way around this. :-) Index: core.ops === RCS file: /home/perlcvs/parrot/core.ops,v retrieving revision 1.72 diff -u -r1.72 core.ops --- core.ops9 Jan 2002 17:24:11 - 1.72 +++ core.ops10 Jan 2002 22:00:30 - @@ -2292,7 +2292,8 @@ =cut inline op save(in INT) { - push_generic_entry(interpreter, interpreter-user_stack_top, ($1), STACK_ENTRY_INT, NULL); + INTVAL val = $1; + push_generic_entry(interpreter, interpreter-user_stack_top, val, +STACK_ENTRY_INT, NULL); goto NEXT(); } - D [EMAIL PROTECTED]
Re: [PATCH] if (PerlArray) [APPLIED]
At 05:20 PM 1/10/2002 +, Simon Glover wrote: The enclosed patch allows one to use the if op with a PerlArray, Applied, thanks. Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Proposal: Naming conventions
On Thu, Jan 10, 2002 at 02:31:24PM -0600, David M. Lloyd wrote: On Thu, 10 Jan 2002, Steve Fink wrote: The naming of things is getting a bit messy. I'd like to propose a convention that I use in my work. It's compatible with the last draft of PDD 7 that I could find: http://www.mail-archive.com/perl6-internals%40perl.org/msg03422.html I agree, we should definitly be sticking to a standard. I think, though, that putting the * in the typedefs for structs might be a little confusing; at least, on all the systems I've worked on that do this, I've been confused. But that might just be me. :-) Well, I'm not doing it to avoid typing the '*'. I'm doing it to mark the type as referring to an abstract data type called a 'Stack', gosh darn it, and if I pass a Stack into a subroutine then I don't want the receiver to get a member-wise copy of my Stack's guts -- that wouldn't be *my* Stack. It would be a new gibbering beast that happened to share pointers and other internal organs with my Stack in ways that would doom them both to half-lives of pain, discomfort, and arguments over whose turn it was to use the liver that night and who got stuck with the spleen. cough Or at least that's the way I think of it. Gotta go now.
Re: [PATCH] Hash bug [APPLIED]
At 05:57 PM 1/10/2002 +, Simon Glover wrote: Well, actually two bugs. The first is an off-by-one error in key.c than can cause parrot to segfault if hash % NUM_BUCKETS happens to be zero. The other is a bug in the PerlHash init() code that causes new PerlHash PMCs to start with the wrong size. Both fixed below; also tests to prevent them recurring. Applied, thanks. Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Some random design notes
At 10:43 PM 1/10/2002 +, Tim Bunce wrote: On Thu, Jan 10, 2002 at 12:37:23PM -0500, Dan Sugalski wrote: Tim [who's not really been paying attention, so ignore me if I'm being daft]. Nah, you're making sense. Besides, vtables are all your fault in the first place, so I ought to be listening... :) Why do I have the feeling that'll come back to haunt me? I don't think so. Things appear to be performing rather well so far. Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: [PATCH] Fix 'basic' test 1 for sizeof(opcode_t) != sizeof(INTVAL) [APPLIED]
At 03:47 PM 1/10/2002 -0600, David M. Lloyd wrote: Just as the subject says. Applied, thanks. Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Some random design notes
At 10:43 PM 1/10/2002 +, Tim Bunce wrote: On Thu, Jan 10, 2002 at 12:37:23PM -0500, Dan Sugalski wrote: Tim [who's not really been paying attention, so ignore me if I'm being daft]. Nah, you're making sense. Besides, vtables are all your fault in the first place, so I ought to be listening... :) Why do I have the feeling that'll come back to haunt me? And, FWIW, my policy's to accept the blame and distribute the credit. Seems an appropriate thing to do . Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
[PATCH] jumps with pbc2c.pl
Here is a patch that makes pbc2c generated code work with the bsr opcode. It creates a new opcode 'enternative', and uses this to support a mixed model of interpretation and execution of compiled C code. Initially, an interpreter is created and started in order to execute a modified copy of the bytecode. At certain known branch target addresses, the original opcode is replaced by an 'enternative' opcode, which switches to execution of the compiled C code. If a branch to a target address not identified by pbc2c occurs, the compiled C code returns control to the interpreter which executes the original bytecode until another 'enternative' opcode is encountered. I'm also including a version of mops.pasm that includes a bsr opcode to test the changes to pbc2c. -- Jason Index: core.ops === RCS file: /home/perlcvs/parrot/core.ops,v retrieving revision 1.72 diff -u -r1.72 core.ops --- core.ops9 Jan 2002 17:24:11 - 1.72 +++ core.ops10 Jan 2002 22:56:19 - @@ -2475,6 +2475,10 @@ goto NEXT(); } +op enternative() { + goto ADDRESS(run_native(interpreter, CUR_OPCODE, (opcode_t +*)interpreter-code-byte_code)); +} + =item Bnew(out PMC, in INT) Index: pbc2c.pl === RCS file: /home/perlcvs/parrot/pbc2c.pl,v retrieving revision 1.11 diff -u -r1.11 pbc2c.pl --- pbc2c.pl3 Jan 2002 19:41:46 - 1.11 +++ pbc2c.pl10 Jan 2002 22:56:19 - @@ -18,6 +18,7 @@ use Parrot::PackFile::ConstTable; use Parrot::OpsFile; use Parrot::OpTrans::CGoto; +use Parrot::OpLib::core; my $trans = Parrot::OpTrans::CGoto-new; @@ -67,88 +68,46 @@ # compile_byte_code() # -my $pc; -my $new_pc = 1; my @args = (); sub compile_byte_code { -my ($pf) = @_; - -my $nconst = $pf-const_table-const_count; +my ($pf, $file_name) = @_; +my ($byte_code); +my $pc; +my $new_pc = 0; +my $offset=0; +my $op_code; +my $op; +my %leaders; +my @pc_list; +my @blocks; +my %opcodes; print END_C; #include parrot/parrot.h #include parrot/string.h END_C +print $trans-defines; print $ops-preamble; -print END_C; - -int -main(int argc, char **argv) { -inti; -struct Parrot_Interp * interpreter; -struct PackFile_Constant * c; -struct PackFile * pf; - -init_world(); - -interpreter = make_interpreter(0); -pf = PackFile_new(); - -interpreter-code = pf; - -END_C - -for(my $i = 0; $i $nconst; $i++) { - my $const = $pf-const_table-constant($i); - my $value = $const-value; - - if ($const-type eq Parrot::PackFile::Constant::type_code('PFC_INTEGER')) { # TODO: Don't hardocde these codes. -print END_C; -c = PackFile_Constant_new_integer($value); -END_C - } elsif ($const-type eq Parrot::PackFile::Constant::type_code('PFC_NUMBER')) { # TODO: Don't hardocde these codes. -print END_C; -c = PackFile_Constant_new_number($value); -END_C - } elsif ($const-type eq Parrot::PackFile::Constant::type_code('PFC_STRING')) { # TODO: Don't hardocde these codes. -my $type = $value-type; -my $encoding = $value-encoding; -my $size = $value-size; -my $flags= $value-flags; -my $data = Dumper($value-data); - -$data = '' . $data . '' unless $data =~ m/^/; - -print END_C; -c = PackFile_Constant_new_string(interpreter, string_make(interpreter, - $data, $size, $encoding, $flags, $type)); -END_C - } else { -die; - } - - print END_C; -PackFile_ConstTable_push_constant(pf-const_table, c); - -END_C -} - -my $cursor = 0; my $length = length($pf-byte_code); -my $offset=0; - -my $op_code; -my $op; +# First instruction in bytecode must be the leader of a block +$leaders{$new_pc} = 1; +# This loop tries to identify instructions that may be the target +# of control flow changing opcodes including the possible targets of ret +# opcodes while ($offset + sizeof('op') = $length) { + my ($src, $is_branch); + $pc = $new_pc; $op_code = unpack x$offset l, $pf-byte_code; $op = $ops-op($op_code) || die Can't find an op for opcode $op_code\n; $offset += sizeof('op'); + push @pc_list, $pc; + $opcodes{$pc}-{op} = $op; $new_pc = $pc + $op-size; @args = (); @@ -160,24 +119,154 @@ $offset += sizeof('op'); push @args, $arg; } + push @{$opcodes{$pc}-{args}}, @args; + +$src = $op-full_body(); + + # The regexes here correspond to the rewriting rules for the various + # forms of goto recognized by Parrot/OpsFile.pm and Parrot/Op.pm + + # absolute address goto + while($src =~
Re: Proposal: Naming conventions
On Thu, Jan 10, 2002 at 03:18:33PM -0500, Melvin Smith wrote: Eep, to answer the original subject of your mail, I think its a good idea to start with the _t typedef standard. except that POSIX (IIRC, but it's either them or ANSI) reserves all names ending in _t for themselves. So any other name except _t would avoid non conformance. (do we want to avoid non conformance that much?) Nicholas Clark -- ENOJOB http://www.ccl4.org/~nick/CV.html
Re: stacks.[ch] modification [APPLIED]
At 01:56 PM 1/10/2002 -0800, Steve Fink wrote: I needed to use a generic stack, and the API in stacks.[ch] really bothered me: You forgot because it sucked :) Patch applied. Thanks. Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: [PATCH] Minor fixes to rx.c
On Thu, 10 Jan 2002, Nicholas Clark wrote: On Thu, Jan 10, 2002 at 03:06:38PM +, Alex Gough wrote: Also, I'm a bit concerned that our null termination games: I would strongly recommend that perl6 mandates that buffers are not nul terminated. Anything that needs a nul should arrange for one to be appended. I've ripped out all the nul termination stuff, and noted in strings.pod that nul termination isn't The Way To Do It. Alex Gough
Re: [PATCH] Skip tests, don't comment them out
On Thu, Jan 10, 2002 at 03:56:57PM +, Simon Glover wrote: As the subject line says. Technically that should be a TODO. -- Michael G. Schwern [EMAIL PROTECTED]http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One come sing my fun song my bologna has a first name p a s t e -- Fmh
[PATCH] Remove evilness in regex engine
Patch below removes some evil mucking around in string internals that was in the regular expression engine. All (expected) tests pass on Windows native and Cygwin. (PerlArrays and PerlHashes are still causing segfaults on Windows native.) --Brent Dax [EMAIL PROTECTED] Configure pumpking for Perl 6 obra . hawt sysadmin chx0rs lathos This is sad. I know of *a* hawt sysamin chx0r. obra I know more than a few. lathos obra: There are two? Are you sure it's not the same one? diff -ur /parrot-cvs/include/parrot/rx.h /parrot/include/parrot/rx.h --- /parrot-cvs/include/parrot/rx.h Thu Jan 10 16:04:56 2002 +++ /parrot/include/parrot/rx.h Thu Jan 10 16:10:24 2002 @@ -59,8 +59,7 @@ STRING *rxP_get_substr(struct Parrot_Interp *, STRING *, INTVAL, INTVAL); #define RX_dUNPACK(pmc)rxinfo *rx=(rxinfo *)pmc-data -/* this one is really quite evil */ -#define RxCurChar(rx) ((char *)rx-string-bufstart)[rx-index] +#define RxCurChar(rx) (char)string_ord(rx-string, rx-index) #define RxCurCharS(rx) rxP_get_substr(interpreter, rx-string, rx-index, 1) #define RxAdvance(rx) RxAdvanceX(rx, 1) diff -ur /parrot-cvs/rx.ops /parrot/rx.ops --- /parrot-cvs/rx.ops Thu Jan 10 16:04:54 2002 +++ /parrot/rx.ops Thu Jan 10 16:12:02 2002 @@ -549,7 +549,7 @@ rx-minlength=$3; for(i=0; i string_length($2); i++) { - switch(((char *)$2-bufstart)[i]) { + switch((char)string_ord($2, i)) { case 'i': RxCaseInsensitive_on(rx); break; @@ -564,7 +564,7 @@ rx-index=rx-startindex=string_length(rx-string); break; default: - fprintf(stderr, Unknown regular expression option '%c'., ((char*)$2-bufstart)[i]); + fprintf(stderr, Unknown regular expression option +'%c'., (char)string_ord($2, i)); HALT(); } }
Removing SunWorkshop 6 Solaris 2.8 (32-bit) from Tinderbox
I'm removing this more common configuration because of the increased time it takes to build Parrot these days. If someone else wants to pick it up, cool, but until then I'm figuring that if the other two (mixed 32/64-bit and pure 64-bit) work, 32-bit probably does too. - D [EMAIL PROTECTED]
Re: [PATCH] Make save work for sizeof(opcode_t) != sizeof(INTVAL)(caveat)
On Thu, 10 Jan 2002, David M. Lloyd wrote: The problem is that when you save an int constant on the stack in a mixed 32/64-bit system, the int type is 8 bytes but the pointer points to four bytes of int constant and four bytes of... something else. So it has to be copied out into a temp variable before being referenced. I'll leave it to greater minds to find a way around this. :-) This is the post-stack-API-change version of this patch. Index: core.ops === RCS file: /home/perlcvs/parrot/core.ops,v retrieving revision 1.74 diff -a -u -r1.74 core.ops --- core.ops10 Jan 2002 23:14:56 - 1.74 +++ core.ops11 Jan 2002 00:50:04 - @@ -2292,7 +2292,8 @@ =cut inline op save(in INT) { - stack_push(interpreter, interpreter-user_stack, ($1), STACK_ENTRY_INT, NULL); + INTVAL i = $1; + stack_push(interpreter, interpreter-user_stack, i, STACK_ENTRY_INT, NULL); goto NEXT(); } - D [EMAIL PROTECTED]
[PATCH] life benchmark
New benchmark. Yummy. Index: Makefile.in === RCS file: /home/perlcvs/parrot/Makefile.in,v retrieving revision 1.112 diff -a -u -r1.112 Makefile.in --- Makefile.in 9 Jan 2002 22:35:14 - 1.112 +++ Makefile.in 11 Jan 2002 01:58:44 - @@ -233,6 +233,8 @@ examples/assembly/mops${exe}: examples/assembly/mops$(O) $(O_FILES) $(LD) $(LDFLAGS) ${ld_out}examples/assembly/mops${exe} examples/assembly/mops$(O) $(O_FILES) $(C_LIBS) +examples/assembly/life.pbc: examples/assembly/life.pasm assemble.pl + cd examples cd assembly $(MAKE) life.pbc PERL=$(PERL) cd .. cd .. ### # @@ -345,6 +347,9 @@ mopstest: $(TEST_PROG) examples/assembly/mops.pbc $(TEST_PROG) examples/assembly/mops.pbc + +lifetest: $(TEST_PROG) examples/assembly/life.pbc + $(TEST_PROG) examples/assembly/life.pbc ### Index: examples/assembly/life.pasm === RCS file: /home/perlcvs/parrot/examples/assembly/life.pasm,v retrieving revision 1.2 diff -a -u -r1.2 life.pasm --- examples/assembly/life.pasm 10 Jan 2002 21:31:30 - 1.2 +++ examples/assembly/life.pasm 11 Jan 2002 01:58:44 - @@ -60,7 +60,7 @@ set N8, I2 div N1, N8, N7 print N1 - print generations/sec + print generations/sec\n end
Re: [PATCH] life benchmark [APPLIED]
At 05:58 PM 1/10/2002 -0800, Steve Fink wrote: New benchmark. Yummy. And committed. Thanks. Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Regex benchmarks
Could someone construct a few regexes in both parrot and perl, and run some benchmarks to see how we're doing with speed here? Nothing final, certainly, but something to give us an idea of performance. Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Proposal: Naming conventions
At 11:34 PM 1/10/2002 +, Tom Hughes wrote: In message 20020110201559$[EMAIL PROTECTED] Melvin Smith [EMAIL PROTECTED] wrote: Well sizeof(Foo) and sizeof(*foo) are not actually the same thing at all there because Foo is presumably a typedef for a pointer type so sizeof(Foo) will be the size of a pointer and sizeof(*foo) will be the size of the thing it points to. Right, I misread the code snippet in my infinite confusion. In general it is safer to sizeof() on the variable you are working with than on it's type, as that way the sizeof() will still work if somebody changes the type of the variable. Well even after misreading the snippet the point I was getting at was emulating virtual pointers in C++ where the allocator might create an object regardless of what type of pointer it was using or assigning to. For example in the case where an allocator had in it a switch statement of subclasses. In the end this is more the exception than the rule and I see I was just on a tangent. :) The type of *foo is whatever Foo as been typedefed as a pointer to, and FooBar is a red herring. Grin, I'll read more carefully before arguing next time. ;) -Melvin
Re: New benchmark
Dan Sugalski wrote: Okay, I've abused examples/assembly/life.pasm to be a benchmark program. It now will time generations/sec, and does rather more than mops.pasm does. Where can I find implementations of this algorithm in other languages, for instance for Perl 5, Python, Ruby, ..? -- Sebastian Bergmann http://sebastian-bergmann.de/ http://phpOpenTracker.de/ Did I help you? Consider a gift: http://wishlist.sebastian-bergmann.de/