skaller | 1 Aug 2006 04:41
Picon

varray semantics

What are the desired semantics of a variable length array?

My vague thoughts are:

(1) initially empty, with push_back/pop_back functions
to add and remove elements from the end

(2) reserve_memory(n), reserve_addresses(n), bound(n)

(3) lock(n)

reserve_memory allocates, or promises to allocate,
enough memory for n slots.

reserve_addresses reserves address space (using mmap
or equivalent) without necessarily promising to
reserve storage.

bound just sets the maximum possible size of the array,
if exceeded the program aborts.

lock hints that pages should be locked into memory.

When reserved address space is exceeded, one of two
things happens:

(a) the program aborts
(b) the array is reallocated.

Reallocation leads to some problems. First, we need
(Continue reading)

skaller | 1 Aug 2006 19:13
Picon

Re: varray semantics

On Tue, 2006-08-01 at 12:41 +1000, skaller wrote:
> What are the desired semantics of a variable length array?

(What, no comments? Hmm)

This problem turns out to be deeper. At the moment, the collector
shape object provides one polymorphic method for objects:
a destructor.

The collector also supports mobility: some objects can be moved,
if they're allocated in an arena. The requires 

(a) physically copying the object from address A to B
(b) adjusting every pointer to A to point to B

The collector can manage these steps by itself ..
ON THE ASSUMPTION objects can be moved (the client has
to flag them immobile if they can't be: the RTS supports
this, but there's no language feature to state it because
Felix objects are intrinsically mobile, provided their
contained primitives are.

The simplest way to move a C++ object is to copy it,
then destroy the source location.

A diversion: C++ supports default initialisation,
copy assignment, copy construction, and destruction.
These are core polymorphic operations: in traditional
FPL's pointers are used, and so a single set of these
operations on pointers suffices for all objects:
(Continue reading)

skaller | 4 Aug 2006 08:08
Picon

New experimental feature

I'm playing with (it's in CVS now!) something which makes 
this work .. because I'm  writing some documentation (!) 
which specifies it:

-------------------------------
#include <flx.flxh>

var v = 1;

fun x => v;
fun y : int => 1;

print$ x; endl;
v = 2;
print$ x; endl;
-------------------------------

The notation 

fun x => v;

is short for

(a) fun x() => v;
(b) replace every x in scope with x().

In other words, it's *enforced* lazy evaluation.
At present, this notation:

var x = v;
(Continue reading)

skaller | 5 Aug 2006 13:28
Picon

Felix 1.1.2 production release uploaded

Test please!

--

-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
skaller | 12 Aug 2006 08:29
Picon

Exceptions in pthreads

At present, an exception could be thrown in a pthread and
fail to be caught, in which case, behaviour is undefined.

This can be fixed as follows: given the client init
procedure cp, and client data pointer cd, instead of
calling pthread.init(cp,fp) [pseudo code!] we instead
do this:

struct cpd_wrapper {
  pthread_init_proc_t *cp;
  void *cd;
}

pthread.init(fixed_routine, new cpd_wrapper(cp,cd));

void fixed_routine(void *vcpd) {
  cpd_wrapper *cpd = (cpd_wrapper*)vcpd;
  pthread_init_proc_t *cp = cpd->cp;
  void *cd = cpd->cd;
  delete cpd;  
  try { cp(cd); }
  catch (...) { abort(); }
}

This is completely transparent, but ensures that an uncaught
exception will be detected.

--

-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net
(Continue reading)

skaller | 12 Aug 2006 10:42
Picon

Re: Exceptions in pthreads

On Sat, 2006-08-12 at 16:29 +1000, skaller wrote:
> At present, an exception could be thrown in a pthread and
> fail to be caught, in which case, behaviour is undefined.

There's one issue here: the return value. Windows returns
an int, whereas Posix returns a void*.

For Felix threads, this is nonsense. We have better ways
to return data from a thread (channels), and all our threads are
detached anyhow.

So I propose Felix thread start routines all be:

	void (*)(void*)

since now, this routine is called from a wrapper,
and the LPSTART_THREAD_PROC crud is all hidden.

--

-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
Erick Tryzelaar | 12 Aug 2006 18:15
Picon

Re: Exceptions in pthreads

skaller wrote:
> There's one issue here: the return value. Windows returns
> an int, whereas Posix returns a void*.
>
> For Felix threads, this is nonsense. We have better ways
> to return data from a thread (channels), and all our threads are
> detached anyhow.
>
> So I propose Felix thread start routines all be:
>
> 	void (*)(void*)
>
> since now, this routine is called from a wrapper,
> and the LPSTART_THREAD_PROC crud is all hidden.
>
>
>   
I'm all for that. I was thinking about trying to hide a little more of 
the private OS interface in a couple packages. Haven't done much.

(and we'll see if sf will drop this email, as that still is occasionally 
happening to me)

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
skaller | 15 Aug 2006 16:51
Picon

Parameters, evaluation, and semantics

There is now a significant change committed to CVS which 
improves and extends function and procedure call performance
and semantics. You can now write:

fun f(var x:int, val y:int):int {
  ++x; 
  return x + y;
}

The default is val.

This is equivalent to the hack required before:

fun f(x:int, y:int):int {
  var x' = x;
  ++x';
  return x' + y;
}

The effect is also to ensure var arguments are evaluated
eagerly. For val arguments may be evaluated
either eagerly or lazily. This is correct for functions
but not procedures.

The semantics of inline and noinline functions should now
be the same, and well defined, provided the val argument
is convergent (that is, it terminates with a value, as opposed
to throwing an exception, core dumping, going into an infinite
loop, or otherwise being nasty).

(Continue reading)

skaller | 15 Aug 2006 20:05
Picon

Re: Parameters, evaluation, and semantics

On Wed, 2006-08-16 at 00:51 +1000, skaller wrote:

Interesting quirk with refs. At the moment this works:
----------------------------
#include <flx.flxh>

var x = 1;
ref px <- x;
print px; endl;
x = 2;
print px; endl;
----------------------------

Well, the parameter case isn't harder, but I have
discovered an interesting limitation.

Felix cannot take the address of an arbitrary lvalue:
it can ONLY take the address of a variable.

It can ASSIGN to any lvalue .. it can't address one.

It isn't even allowed to do this:

struct X { a: int; };
var x = X(1);
var pa = &x.a;

Of course .. you can certainly get the "C" address of
any lvalue.. but that's not a Felix pointer, its 
a C pointer .. and the function for doing that is
(Continue reading)

skaller | 18 Aug 2006 06:19
Picon

dynamic typing

As you know, most scripting languages are dynamically typed.
Felix is different, because it is statically typed.

Nevertheless, run time typing is not just useful,
it is essential for the proper operation of the garbage
collector, which needs at least two things:

(a) it needs to know how to destroy an object
(b) it needs to know where all the pointers are

The current system has a way to handle this: the
shape object records the offsets of pointers,
and it records the finaliser (destructor) if one
is required (pod don't require finalisation).

However the arena allocator requires more: it moves
objects using memcpy, and adjusts pointers everywhere
to account for the move. This works for many data types,
but not all. For example a C++ doubly linked list doesn't
contain Felix pointers, and memcpy of one node will
trash the system -- the pointers to that node in the
next and previous objects (if they exist) must be
adjusted.

To allow this for arbitrary C++ objects, we need to
provide a slot for a move function.

However this isn't enough in general. For example,
realloc() may move objects. In this case, we can't
call the move function, because the source is already
(Continue reading)


Gmane