示例#1
0
/* xlthrow - throw to a catch */
void xlthrow(LVAL tag, LVAL val)
{
    XLCONTEXT *cptr;

    /* find a catch context */
    for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext)
        if ((cptr->c_flags & CF_THROW) && cptr->c_expr == tag)
            xljump(cptr,CF_THROW,val);
    xlfail("no target for THROW");
}
示例#2
0
/* xlreturn - return from a block */
void xlreturn(LVAL name, LVAL val)
{
    XLCONTEXT *cptr;

    /* find a block context */
    for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext)
        if (cptr->c_flags & CF_RETURN && cptr->c_expr == name)
            xljump(cptr,CF_RETURN,val);
    xlfail("no target for RETURN");
}
示例#3
0
/* findandjump - find a target context frame and jump to it */
LOCAL void findandjump(int mask, const char *error)
{
    XLCONTEXT *cptr;

    /* find a block context */
    for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext)
        if (cptr->c_flags & mask)
            xljump(cptr,mask,NIL);
    xlabort(error);
}
示例#4
0
/* xlsignal - signal an error */
void xlsignal(const char *emsg, LVAL arg)
{
    XLCONTEXT *cptr;

    /* find an error catcher */
    for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext)
        if (cptr->c_flags & CF_ERROR) {
            if (cptr->c_expr && emsg)
                xlerrprint("error",NULL,emsg,arg);
            xljump(cptr,CF_ERROR,NIL);
        }
}
示例#5
0
/* xlgo - go to a label */
void xlgo(LVAL label)
{
    XLCONTEXT *cptr;
    LVAL *argv;
    int argc;

    /* find a tagbody context */
    for (cptr = xlcontext; cptr; cptr = cptr->c_xlcontext)
        if (cptr->c_flags & CF_GO) {
            argc = cptr->c_xlargc;
            argv = cptr->c_xlargv;
            while (--argc >= 0)
                if (*argv++ == label) {
                    cptr->c_xlargc = argc;
                    cptr->c_xlargv = argv;
                    xljump(cptr,CF_GO,NIL);
                }
        }
    xlfail("no target for GO");
}
示例#6
0
int nyx_get_audio(nyx_audio_callback callback, void *userdata)
{
   float *buffer = NULL;
   sound_type *snds = NULL;
   long *totals = NULL;
   long *lens = NULL;
   sound_type snd;
   int result = 0;
   int num_channels;
   int ch;

   // Any variable whose value is set between the setjmp() and the "finish" label
   // and that is used after the "finish" label, must be marked volatile since
   // any routine outside of the current one that calls longjmp() will cause values
   // cached in registers to be lost.
   volatile int success = FALSE;

   if (nyx_get_type(nyx_result) != nyx_audio) {
      return FALSE;
   }

#if defined(NYX_MEMORY_STATS) && NYX_MEMORY_STATS
   printf("\nnyx_get_audio before\n");
   xmem();
#endif

   num_channels = nyx_get_audio_num_channels();

   buffer = (sample_type *) malloc(max_sample_block_len * sizeof(sample_type));
   if (buffer == NULL) {
      goto finish;
   }

   snds = (sound_type *) malloc(num_channels * sizeof(sound_type));
   if (snds == NULL) {
      goto finish;
   }

   totals = (long *) malloc(num_channels * sizeof(long));
   if (totals == NULL) {
      goto finish;
   }

   lens = (long *) malloc(num_channels * sizeof(long));
   if (lens == NULL) {
      goto finish;
   }

   // Setup a new context
   xlbegin(&nyx_cntxt, CF_TOPLEVEL|CF_CLEANUP|CF_BRKLEVEL|CF_ERROR, s_true);

   // Set the context jump destination
   if (setjmp(nyx_cntxt.c_jmpbuf)) {
      // If the script is cancelled or some other condition occurs that causes
      // the script to exit and return to this level, then we don't need to
      // restore the previous context.
      goto finish;
   }

   for (ch = 0; ch < num_channels; ch++) {
      if (num_channels == 1) {
         snd = getsound(nyx_result);
      }
      else {
         snd = getsound(getelement(nyx_result, ch));
      }
      snds[ch] = snd;
      totals[ch] = 0;
      lens[ch] = snd_length(snd, snd->stop);
   }

   while (result == 0) {
      for (ch =0 ; ch < num_channels; ch++) {
         sample_block_type block;
         long cnt;
         int i;

         snd = snds[ch];

         cnt = 0;
         block = sound_get_next(snd, &cnt);
         if (block == zero_block || cnt == 0) {
            success = TRUE;
            result = -1;
            break;
         }

         // Copy and scale the samples
         for (i = 0; i < cnt; i++) {
            buffer[i] = block->samples[i] * snd->scale;
         }

         result = callback((float *)buffer, ch,
                           totals[ch], cnt, lens[ch], userdata);

         if (result != 0) {
            result = -1;
            break;
         }

         totals[ch] += cnt;
      }
   }

   // This will unwind the xlisp context and restore internals to a point just
   // before we issued our xlbegin() above.  This is important since the internal
   // xlisp stacks will contain pointers to invalid objects otherwise.
   //
   // Also note that execution will jump back up to the statement following the
   // setjmp() above.
   xljump(&nyx_cntxt, CF_TOPLEVEL, NIL);
   // Never reached

 finish:

   if (buffer) {
      free(buffer);
   }

   if (lens) {
      free(lens);
   }

   if (totals) {
      free(totals);
   }

   if (snds) {
      free(snds);
   }

   gc();

#if defined(NYX_MEMORY_STATS) && NYX_MEMORY_STATS
   printf("\nnyx_get_audio after\n");
   xmem();
#endif

   return success;
}
示例#7
0
nyx_rval nyx_eval_expression(const char *expr_string)
{
   LVAL expr = NULL;

#if defined(NYX_MEMORY_STATS) && NYX_MEMORY_STATS
   printf("\nnyx_eval_expression before\n");
   xmem();
#endif

   nyx_result = NULL;
   nyx_result_type = nyx_error;

   // Check argument
   if (!expr_string || !strlen(expr_string)) {
      return nyx_get_type(nyx_result);
   }

   nyx_expr_string = expr_string;
   nyx_expr_len = strlen(nyx_expr_string);
   nyx_expr_pos = 0;

   // Protect the expression from being garbage collected
   xlprot1(expr);

   // Setup a new context
   xlbegin(&nyx_cntxt, CF_TOPLEVEL|CF_CLEANUP|CF_BRKLEVEL|CF_ERROR, s_true);

   // Set the context jump destination
   if (setjmp(nyx_cntxt.c_jmpbuf)) {
      // If the script is cancelled or some other condition occurs that causes
      // the script to exit and return to this level, then we don't need to
      // restore the previous context.
      goto finish;
   }

   while (nyx_expr_pos < nyx_expr_len) {
      expr = NULL;

      // Read an expression
      if (!xlread(getvalue(s_stdin), &expr, FALSE)) {
         break;
      }

      #if 0
      /* save the input expression (so the user can refer to it
         as +, ++, or +++) */
      xlrdsave(expr);
      #endif

      // Evaluate the expression
      nyx_result = xleval(expr);
   }

   // This will unwind the xlisp context and restore internals to a point just
   // before we issued our xlbegin() above.  This is important since the internal
   // xlisp stacks will contain pointers to invalid objects otherwise.
   //
   // Also note that execution will jump back up to the statement following the
   // setjmp() above.
   xljump(&nyx_cntxt, CF_TOPLEVEL, NIL);
   // Never reached

 finish:

   xlflush();

   xlpop(); // unprotect expr

   gc();

#if defined(NYX_MEMORY_STATS) && NYX_MEMORY_STATS
   printf("\nnyx_eval_expression after\n");
   xmem();
#endif

   return nyx_get_type(nyx_result);
}