Marc,

So what we get to then is that that Scheme object allocation could fail. In that case, would the mature way of dealing with it for the code return a special error, and then have a Scheme-side exception handler?

Also just to understand - is the only thin that would allocating objects in the C world to fail, would be that malloc() failed, or are there other more local things that could make the object allocation fail?


(define uint32_tag
  (lambda (a)
  (let* ((r ((c-lambda
   (TIFF* ttag_t)
   scheme-object
   "
    ___U32 val;
    if (TIFFGetField(___arg1, ___arg2, &val) == 1) {
      if ((___err = ___U32_to_SCMOBJ (___PSTATE, val, &___result, ___RETURN_POS)) == ___FIX(___NO_ERR)) {
        ___release_scmobj (___result);
      } else {
        ___result = [             SOME ERROR CODE        ]; ?
      }
    } else {
      ___result = ___FAL;
    }
   ") a)))
    (if (eq? a   some-error-code) (##raise-heap-overflow-exception)       a))


2016-01-06 23:02 GMT+08:00 Marc Feeley <feeley@iro.umontreal.ca>:
On a 64 bit machine all uint32 values fit in a fixnum so there is no allocation possible.  On a 32 bit machine, converting a large uint32 will cause a heap allocation of a bignum.  However the code is written so that it detects heap overflows and raises a Scheme exception in that case (the Scheme exception can be handled in Scheme because the GC will have prereserved some room in the heap to do further processing in Scheme).

A Scheme heap overflow exception could be raised by a malloc failure or if the Scheme heap size limit is reached (see -:h runtime option).

Try

% gsi -:h1000 -e "(let loop ((x 0)) (loop (list x)))"
*** ERROR IN (string)@1.1 -- Heap overflow

% gsi -:h1000 -e "(with-exception-catcher (lambda (e) (pp (list 'caught e))) (lambda () (let loop ((x 0)) (loop (list x)))))"
(caught #<heap-overflow-exception #2>)

Marc

> On Jan 6, 2016, at 9:48 AM, Adam <adam.mlmb@gmail.com> wrote:
>
>
>
> 2016-01-06 22:37 GMT+08:00 Marc Feeley <feeley@iro.umontreal.ca>:
> Of course one way would be to return a double (which has 53 bits of precision) and use NaN to encode “missing tag”.  I’m not kidding!
>
> If you don’t like this approach, and I can understand why you wouldn’t, then you have to do the conversion to ___SCMOBJ by directly calling the conversion macros.  Something like this:
>
> (define uint32_tag
>   (c-lambda
>    (TIFF* ttag_t)
>    scheme-object
>    "
>     ___U32 val;
>     if (TIFFGetField(___arg1, ___arg2, &val) == 1) {
>       if ((___err = ___U32_to_SCMOBJ (___PSTATE, val, &___result, ___RETURN_POS)) == ___FIX(___NO_ERR)) {
>         ___release_scmobj (___result);
>       }
>     } else {
>       ___result = ___FAL;
>     }
>    "))
>
> Neat! What is the risk involved with this one - I mean, the Scheme object allocation on the Gambit heap could fail under certain circumstances. But would that only be on malloc() failure?