[ 
  The listserver does not like my attachments
  ezmlm-send: fatal: Sorry, after removing unacceptable MIME parts from your message I 
was left with nothing (#5.7.0)
  ezmlm-gate: fatal: fatal error from child

  Here is the resend with code inline
]

Leopold Toetsch <[EMAIL PROTECTED]> writes:

> We currently have constant Key and Sub PMCs both created from the
> packfile at load time. They live in the constant_table pointing to a
> constant PMC pool. But we need more.
> 
> 
> We have allover the core code like this:
> 
>    string_from_cstring(interpreter, "pIt", 0)
>    key = key_new_cstring(interpreter, "_message");
> 
> to create some STRINGs or entries in hashes. The keys should be
> constant PMCs and they should be shared as well as the STRINGs.
> 
> We need this in objects.c ("\0\0anonymous"), for setting standard
> property names internally and for the current hash based
> implementation of Exceptions.

[...]

Some time ago I did some experiments with initialising strings at
compile time. With some preprocessor magic and a perl program scanning
the c-file I got it running.

The changes to an existing c-file are minimal: At the beginning add a
#include "FILE.str" and replace all these string_form_cstring with
_S("text"). The _S macros are replaced by static string_structures
with static initialisers. These string structures are in the ro-data
segement of the executable and should load really fast. No calls to
any functions.

===== c2str.pl
#! perl

use Text::Balanced qw(extract_bracketed);
use Data::Dumper;

die "$0: Usage $0 FILE.c" unless $#ARGV == 0;

my $file = shift @ARGV;

$file =~ s/\.c$//;

my $infile = $file . '.c';
my $outfile = $file . '.str';

die "$0: $infile: $!" unless -e $infile;

print <<'HEADER';
/*
 * !!!!!!!   DO NOT EDIT THIS FILE   !!!!!!!
 *
 * This file is generated automatically from '$infile'
 * by $0.
 *
 * Any changes made here will be lost!
 *
 */

#define CONCAT(a,b) a##b
#define _S(name) (__PARROT_STATIC_STR(__LINE__))
#define __PARROT_STATIC_STR(line) CONCAT(&static_string_, line)
#include <parrot/pobj.h>

#if ! DISABLE_GC_DEBUG
#  define GC_DEBUG_VERSION ,0
#else
#  define GC_DEBUG_VERSION
#endif

HEADER

my %known_strings = ();

sub output_string {
  my ($text, $line) = @_;

  if (exists $known_strings{$text}) {
    <<"DATA";
#define static_string_${line} static_string_$known_strings{$text}

DATA
  }
  else {
    $known_strings{$text} = $line;
    <<"DATA";
static const char static_string_${line}_data\[\] = $text;
static const struct parrot_string_t static_string_${line} = {
  { /* pobj_t */
    {{ 
      (void*)static_string_${line}_data, 
      sizeof(static_string_${line}_data) 
    }},
    PObj_constant_FLAG
    GC_DEBUG_VERSION
  },
  sizeof(static_string_${line}_data),
  (void*)static_string_${line}_data,
  sizeof(static_string_${line}_data) - 1,
  NULL,
  NULL,
  0
};

DATA
  }
}

open IN, $infile;

my $line = 0;
while (<IN>) {
  $line++;
  next if m/^\s*\#/; # ignore preprocessor
  next unless s/.*\b_S\b//;

  my $str = extract_bracketed $_, '(")';

  print output_string (substr($str,1,-1), $line);
}
===== example.c
/*
 * example.c
 *
 * demonstrating static allocation of string
 *
 * to compile:
 * perl c2str.pl example.c > example.str
 * gcc -o example -Iinclude example.c blib/lib/libparrot.a -lm -ldl
 */

#include <parrot/parrot.h>

#include "example.str"

int 
main(int argc, char* argv[]) {
    struct Parrot_Interp * interpreter;

    interpreter = Parrot_new();
    Parrot_init(interpreter, &interpreter);

    PIO_putps(interpreter, PIO_STDOUT(interpreter), _S("foo\n"));
    PIO_putps(interpreter, PIO_STDOUT(interpreter), _S("bar\n"));
    PIO_putps(interpreter, PIO_STDOUT(interpreter), _S("foo\n"));

    return 0;
}
=====

Issues with this are:
* My macro vodoo is base on __LINE__ so only one _S directive per line
* the strings are local to one compilation unit (but that is not
  diffrent from the c-string constants)
* It exposes the internal structure of PObj (this does not bother us at
  the moment, nearly every file includes <parrot/parrot.h>)
* The encoding/chartype must be set to 0 or we get a many relocations,
  the string functions have to deal with this case.

May a scheme like this can be used for keys too.

> Comments welcome
> leo

Same here
boe
-- 
Juergen Boemmels                        [EMAIL PROTECTED]
Fachbereich Physik                      Tel: ++49-(0)631-205-2817
Universitaet Kaiserslautern             Fax: ++49-(0)631-205-3906
PGP Key fingerprint = 9F 56 54 3D 45 C1 32 6F  23 F6 C7 2F 85 93 DD 47

Reply via email to