Exemplo n.º 1
0
static void
error_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
		     void *instance_context,
		     JSNode *result_return, JSNode *args)
{
  unsigned int len;

  if (args->u.vinteger != 1)
    {
      sprintf (vm->error, "eval: illegal amount of arguments");
      js_vm_error (vm);
    }
  if (args[1].type != JS_STRING)
    {
      sprintf (vm->error, "eval: illegal argument");
      js_vm_error (vm);
    }

  len = args[1].u.vstring->len;
  if (len > sizeof (vm->error) - 1)
    len = sizeof (vm->error) - 1;

  memcpy (vm->error, args[1].u.vstring->data, len);
  vm->error[len] = '\0';

  /* Here we go... */
  js_vm_error (vm);

  /* NOTREACHED */
}
Exemplo n.º 2
0
static int
sort_js_cmp_func (const void *aptr, const void *bptr, void *context)
{
  ArraySortCtx *ctx = context;
  const JSNode *a = aptr;
  const JSNode *b = bptr;

  /*
   * Finalize the argument array.  The argumnet count has already been set.
   * when the context were initialized.
   */
  JS_COPY (&ctx->argv[1], a);
  JS_COPY (&ctx->argv[2], b);

  /* Call the function. */
  if (!js_vm_apply (ctx->vm, NULL, ctx->func, 3, ctx->argv))
    /* Raise an error. */
    js_vm_error (ctx->vm);

  /* Fetch the return value. */
  if (ctx->vm->exec_result.type != JS_INTEGER)
    {
      sprintf (ctx->vm->error,
	       "Array.sort(): comparison function didn't return integer");
      js_vm_error (ctx->vm);
    }

  return ctx->vm->exec_result.u.vinteger;
}
Exemplo n.º 3
0
static void
eval_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
		    void *instance_context, JSNode *result_return,
		    JSNode *args)
{
  JSInterpPtr interp = instance_context;

  if (args->u.vinteger != 1)
    {
      sprintf (vm->error, "eval: illegal amount of arguments");
      js_vm_error (vm);
    }
  if (args[1].type != JS_STRING)
    {
      sprintf (vm->error, "eval: illegal argument");
      js_vm_error (vm);
    }

  /*
   * Ok, we'r ready to eval it.  The source strings is our argument, so,
   * it is in the stack and therefore, protected for gc.
   */
  if (!js_eval_source (interp, &args[1], "JSC$compile_string"))
    {
      /* The evaluation failed. */
      fprintf (stderr, "eval: evaluation failed: %s\n", vm->error);
      result_return->type = JS_UNDEFINED;
    }
  else
    /* Pass the return value to our caller. */
    JS_COPY (result_return, &vm->exec_result);
}
Exemplo n.º 4
0
static void
isNaN_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
		     void *instance_context, JSNode *result_return,
		     JSNode *args)
{
  JSNode cvt;
  int result;

  if (args->u.vinteger != 1)
    {
      sprintf (vm->error, b_core_string_4);
      js_vm_error (vm);
    }

  switch (args[1].type)
    {
    case JS_NAN:
      result = 1;
      break;

    case JS_INTEGER:
    case JS_FLOAT:
      result = 0;
      break;

    default:
      js_vm_to_number (vm, &args[1], &cvt);
      result = cvt.type == JS_NAN;
      break;
    }

  result_return->type = JS_BOOLEAN;
  result_return->u.vboolean = result;
}
Exemplo n.º 5
0
void
js_vm_object_load_array (JSVirtualMachine *vm, JSObject *obj, JSNode *sel,
			 JSNode *value_return)
{
  if (sel->type == JS_INTEGER)
    {
      if (sel->u.vinteger < 0 || sel->u.vinteger >= obj->num_props)
	value_return->type = JS_UNDEFINED;
      else
	JS_COPY (value_return, &obj->props[sel->u.vinteger].value);
    }
  else if (sel->type == JS_STRING)
    {
      int pos;

      if (obj->hash == NULL)
	hash_create (vm, obj);

      pos = hash_lookup (obj, (char *) sel->u.vstring->data,
			 sel->u.vstring->len);
      if (pos < 0)
	value_return->type = JS_UNDEFINED;
      else
	JS_COPY (value_return, &obj->props[pos].value);
    }
  else
    {
      sprintf (vm->error, "load_property: illegal array index");
      js_vm_error (vm);
    }
}
Exemplo n.º 6
0
static void
parseFloat_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
			  void *instance_context, JSNode *result_return,
			  JSNode *args)
{
  char *cp, *end;

  result_return->type = JS_FLOAT;

  if (args->u.vinteger != 1)
    {
      sprintf_P (vm->error, b_core_string_1);
      js_vm_error (vm);
    }
  if (args[1].type == JS_STRING)
    cp = js_string_to_c_string (vm, &args[1]);
  else
    {
      JSNode input;

      /* Convert the input to string. */
      js_vm_to_string (vm, &args[1], &input);
      cp = js_string_to_c_string (vm, &input);
    }

  result_return->u.vfloat = strtod (cp, &end);
  js_free (cp);

  if (cp == end)
    /* Couldn't parse, return NaN. */
    result_return->type = JS_NAN;
}
Exemplo n.º 7
0
static void
unescape_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
			void *instance_context, JSNode *result_return,
			JSNode *args)
{
  unsigned char *dp;
  unsigned int n, i;
  JSNode *source;
  JSNode source_n;

  if (args->u.vinteger != 1)
    {
      sprintf_P (vm->error, b_core_string_3);
      js_vm_error (vm);
    }
  if (args[1].type == JS_STRING)
    source = &args[1];
  else
    {
      js_vm_to_string (vm, &args[1], &source_n);
      source = &source_n;
    }

  /*
   * Allocate the result string, Let's guess that we need at least
   * <source->u.vstring->len> bytes of data.
   */
  n = source->u.vstring->len;
  dp = source->u.vstring->data;
  js_vm_make_string (vm, result_return, NULL, n);
  result_return->u.vstring->len = 0;

  /*
   * Scan for escapes requiring characters.
   */
  for (i = 0; i < n;)
    {
      unsigned int c = dp[i];

      if (c != '%')
	i += 1;
      else if (i <= n - 6 && dp[i + 1] == 'u'
	       && scanhexdigits (dp + i + 2, 4, &c))
	i += 6;
      else if (i <= n - 3 && scanhexdigits (dp + i + 1, 2, &c))
	i += 3;
      else
	{
	  c = dp[i];
	  i += 1;
	}
      EMIT_TO_RESULT (c);
    }
}
Exemplo n.º 8
0
static void
isFinite_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
			void *instance_context, JSNode *result_return,
			JSNode *args)
{
  JSNode *source;
  JSNode cvt;
  int result;

  if (args->u.vinteger != 1)
    {
      sprintf_P (vm->error, b_core_string_5);
      js_vm_error (vm);
    }

  if (args[1].type == JS_NAN || args[1].type == JS_INTEGER
      || args[1].type == JS_FLOAT)
    source = &args[1];
  else
    {
      js_vm_to_number (vm, &args[1], &cvt);
      source = &cvt;
    }

  switch (source->type)
    {
    case JS_NAN:
      result = 0;
      break;

    case JS_INTEGER:
      result = 1;
      break;

    case JS_FLOAT:
      if (JS_IS_POSITIVE_INFINITY (&args[1])
	  || JS_IS_NEGATIVE_INFINITY (&args[1]))
	result = 0;
      else
	result = 1;
      break;

    default:
      /* NOTREACHED */
      result = 0;
      break;
    }

  result_return->type = JS_BOOLEAN;
  result_return->u.vboolean = result;
}
Exemplo n.º 9
0
static void
load_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
		    void *instance_context,
		    JSNode *result_return, JSNode *args)
{
  JSInterpPtr interp = instance_context;
  int i;
  int result;

  if (args->u.vinteger == 0)
    {
      sprintf (vm->error, "load: no arguments given");
      js_vm_error (vm);
    }

  for (i = 1; i <= args->u.vinteger; i++)
    {
      char *cp;

      if (args[i].type != JS_STRING)
	{
	  sprintf (vm->error, "load: illegal argument");
	  js_vm_error (vm);
	}

      cp = js_string_to_c_string (vm, &args[i]);
      result = js_eval_file (interp, cp);
      js_free (cp);

      if (!result)
	js_vm_error (vm);
    }

  result_return->type = JS_BOOLEAN;
  result_return->u.vboolean = 1;
}
Exemplo n.º 10
0
void
js_vm_object_delete_array (JSVirtualMachine *vm, JSObject *obj, JSNode *sel)
{
  if (sel->type == JS_INTEGER)
    {
      if (0 <= sel->u.vinteger && sel->u.vinteger < obj->num_props)
	{
	  JSSymbol sym;

	  sym = obj->props[sel->u.vinteger].name;
	  obj->props[sel->u.vinteger].name = JS_SYMBOL_NULL;
	  obj->props[sel->u.vinteger].value.type = JS_UNDEFINED;

	  /* Remove its name from the hash (if present and it is not NULL). */
	  if (sym != JS_SYMBOL_NULL && obj->hash)
	    {
	      const char *name = js_vm_symname (vm, sym);
	      hash_delete (vm, obj, name, strlen (name));
	    }
	}
    }
  else if (sel->type == JS_STRING)
    {
      int pos;

      if (obj->hash == NULL)
	hash_create (vm, obj);

      pos = hash_lookup (obj, (char *) sel->u.vstring->data,
			 sel->u.vstring->len);
      if (pos >= 0)
	{
	  /* Found it. */
	  obj->props[pos].name = JS_SYMBOL_NULL;
	  obj->props[pos].value.type = JS_UNDEFINED;

	  /* And, delete its name from the hash. */
	  hash_delete (vm, obj, (char *) sel->u.vstring->data,
		       sel->u.vstring->len);
	}
    }
  else
    {
      sprintf (vm->error, "delete_array: illegal array index");
      js_vm_error (vm);
    }
}
Exemplo n.º 11
0
/* Property proc. */
static int
property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
	  void *instance_context, JSSymbol property, int set,
	  JSNode *node)
{
  CursesCtx *ctx = builtin_info->obj_context;

  if (property == ctx->s_LINES)
    {
      if (set)
	goto immutable;

      node->type = JS_INTEGER;
      node->u.vinteger = LINES;
    }
  else if (property == ctx->s_COLS)
    {
      if (set)
	goto immutable;

      node->type = JS_INTEGER;
      node->u.vinteger = COLS;
    }
  else
    {
      if (!set)
	node->type = JS_UNDEFINED;

      return JS_PROPERTY_UNKNOWN;
    }

  return JS_PROPERTY_FOUND;


  /*
   * Error handling.
   */

 immutable:
  sprintf (vm->error, "Curses.%s: immutable property",
	   js_vm_symname (vm, property));
  js_vm_error (vm);

  /* NOTREACHED. */
  return 0;
}
Exemplo n.º 12
0
static void
js_global_method_stub (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
		       void *instance_context, JSNode *result_return,
		       JSNode *args)
{
  JSMethodResult result;
  JSGlobalMethodContext *ctx = instance_context;

  /* Set the default result. */
  result_return->type = JS_UNDEFINED;

  /* Call the user supplied function. */
  result = (*ctx->proc) (ctx->context, ctx->interp, args->u.vinteger,
			 (JSType *) &args[1], (JSType *) result_return,
			 vm->error);
  if (result != JS_OK)
    js_vm_error (ctx->interp->vm);
}
Exemplo n.º 13
0
/* New proc. */
static void
new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, JSNode *args,
	  JSNode *result_return)
{
  XJSInstanceCtx *instance;
  JSInterpOptions options;

  if (args->u.vinteger != 0)
    {
      sprintf (vm->error, "new JS(): illegal amount of arguments");
      js_vm_error (vm);
    }

  instance = js_calloc (vm, 1, sizeof (*instance));

  js_init_default_options (&options);
  instance->interp = js_create_interp (&options);

  js_vm_builtin_create (vm, result_return, builtin_info, instance);
}
Exemplo n.º 14
0
/* Property proc. */
static int
property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
	  void *instance_context, JSSymbol method, int set, JSNode *node)
{
  XJSCtx *ctx = builtin_info->obj_context;
  XJSInstanceCtx *instance = instance_context;

  if (method == ctx->s_errorMessage)
    {
      char *cp = instance->interp->vm->error;

      if (set)
	goto immutable;

      js_vm_make_string (vm, node, cp, strlen (cp));
    }
  else
    {
      if (!set)
	node->type = JS_UNDEFINED;

      return JS_PROPERTY_UNKNOWN;
    }

  return JS_PROPERTY_FOUND;


  /*
   * Error handling.
   */

 immutable:
  sprintf (vm->error, "JS.%s: immutable property",
	   js_vm_symname (vm, method));
  js_vm_error (vm);

  /* NOTREACHED. */
  return 0;
}
Exemplo n.º 15
0
static void
parseInt_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
			void *instance_context, JSNode *result_return,
			JSNode *args)
{
  JSInt32 base = 0;
  char *cp, *end;

  result_return->type = JS_INTEGER;

  if (args->u.vinteger != 1 && args->u.vinteger != 2)
    {
      sprintf_P (vm->error, b_core_string_0);
      js_vm_error (vm);
    }
  if (args[1].type == JS_STRING)
    cp = js_string_to_c_string (vm, &args[1]);
  else
    {
      JSNode input;

      /* Convert the input to string. */
      js_vm_to_string (vm, &args[1], &input);
      cp = js_string_to_c_string (vm, &input);
    }
  if (args->u.vinteger == 2)
    {
      if (args[2].type == JS_INTEGER)
	base = args[2].u.vinteger;
      else
	base = js_vm_to_int32 (vm, &args[2]);
    }

  result_return->u.vinteger = strtol (cp, &end, base);
  js_free (cp);

  if (cp == end)
    result_return->type = JS_NAN;
}
Exemplo n.º 16
0
/* Property proc. */
static int
property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
          void *instance_context, JSSymbol property, int set, JSNode *node)
{
    NumberCtx *ctx = builtin_info->obj_context;

    /* The default result type. */
    node->type = JS_FLOAT;

    if (property == ctx->s_MAX_VALUE)
    {
        if (set)
            goto immutable;

        node->u.vfloat = DBL_MAX;
    }
    else if (property == ctx->s_MIN_VALUE)
    {
        if (set)
            goto immutable;

        node->u.vfloat = DBL_MIN;
    }
    else if (property == ctx->s_NaN)
    {
        if (set)
            goto immutable;

        node->type = JS_NAN;
    }
    else if (property == ctx->s_NEGATIVE_INFINITY)
    {
        if (set)
            goto immutable;

        node->u.vfloat = -HUGE_VAL;
    }
    else if (property == ctx->s_POSITIVE_INFINITY)
    {
        if (set)
            goto immutable;

        node->u.vfloat = HUGE_VAL;
    }
    else
    {
        if (!set)
            node->type = JS_UNDEFINED;

        return JS_PROPERTY_UNKNOWN;
    }

    return JS_PROPERTY_FOUND;


    /*
     * Error handling.
     */

immutable:
    sprintf (vm->error, "Number.%s: immutable property",
             js_vm_symname (vm, property));
    js_vm_error (vm);

    /* NOTREACHED */
    return 0;
}
Exemplo n.º 17
0
/* Method proc. */
static int
method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
        void *instance_context, JSSymbol method, JSNode *result_return,
        JSNode *args)
{
    JSNode *n = instance_context;
    char buf[256];

    if (method == vm->syms.s_toString)
    {
        if (n)
        {
            int radix = 10;

            if (args->u.vinteger == 0)
                ;
            else if (args->u.vinteger == 1)
            {
                if (args[1].type != JS_INTEGER)
                    goto argument_type_error;

                radix = args[1].u.vinteger;
            }
            else
                goto argument_error;

            if (n->type == JS_INTEGER)
            {
                switch (radix)
                {
                case 8:
                    sprintf (buf, "%o", (unsigned int) n->u.vinteger);
                    break;

                case 10:
                    sprintf (buf, "%ld", n->u.vinteger);
                    break;

                case 16:
                    sprintf (buf, "%lx", (unsigned long) n->u.vinteger);
                    break;

                default:
                    sprintf (vm->error, "Number.%s(): illegal radix %d",
                             js_vm_symname (vm, method), radix);
                    break;
                }
            }
            else if (n->type == JS_FLOAT)
                sprintf (buf, "%g", n->u.vfloat);
            else
                sprintf (buf, "NaN");

            js_vm_make_string (vm, result_return, buf, strlen (buf));
        }
        else
        {
            if (args->u.vinteger != 0)
                goto argument_error;
            js_vm_make_static_string (vm, result_return, "Number", 6);
        }
    }
    /* ********************************************************************** */
    else
        return JS_PROPERTY_UNKNOWN;

    return JS_PROPERTY_FOUND;


    /*
     * Error handling.
     */

argument_error:
    sprintf (vm->error, "Number.%s(): illegal amount of arguments",
             js_vm_symname (vm, method));
    js_vm_error (vm);

argument_type_error:
    sprintf (vm->error, "Number.%s(): illegal argument",
             js_vm_symname (vm, method));
    js_vm_error (vm);

    /* NOTREACHED */
    return 0;
}
Exemplo n.º 18
0
/* Method proc. */
static int
method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
	void *instance_context, JSSymbol method,
	JSNode *result_return, JSNode *args)
{
  CursesCtx *ctx = builtin_info->obj_context;
  char *cp;

  /* The default result. */
  result_return->type = JS_BOOLEAN;
  result_return->u.vboolean = 1;

  if (method == ctx->s_addstr)
    {
      if (args->u.vinteger != 1)
	goto argument_error;
      if (args[1].type != JS_STRING)
	goto argument_type_error;

      cp = js_string_to_c_string (vm, &args[1]);
      addstr (cp);
      js_free (cp);
    }
  /* ********************************************************************** */
  else if (method == ctx->s_attron)
    {
      if (args->u.vinteger != 1)
	goto argument_error;
      if (args[1].type != JS_INTEGER)
	goto argument_type_error;

      attron (args[1].u.vinteger);
    }
  /* ********************************************************************** */
  else if (method == ctx->s_attroff)
    {
      if (args->u.vinteger != 1)
	goto argument_error;
      if (args[1].type != JS_INTEGER)
	goto argument_type_error;

      attroff (args[1].u.vinteger);
    }
  /* ********************************************************************** */
  else if (method == ctx->s_beep)
    {
      if (args->u.vinteger != 0)
	goto argument_error;

      beep ();
    }
  /* ********************************************************************** */
  else if (method == ctx->s_cbreak)
    {
      if (args->u.vinteger != 0)
	goto argument_error;

      cbreak ();
    }
  /* ********************************************************************** */
  else if (method == ctx->s_clear)
    {
      if (args->u.vinteger != 0)
	goto argument_error;

      clear ();
    }
  /* ********************************************************************** */
  else if (method == ctx->s_clrtobot)
    {
      if (args->u.vinteger != 0)
	goto argument_error;

      clrtobot ();
    }
  /* ********************************************************************** */
  else if (method == ctx->s_clrtoeol)
    {
      if (args->u.vinteger != 0)
	goto argument_error;

      clrtoeol ();
    }
  /* ********************************************************************** */
  else if (method == ctx->s_echo)
    {
      if (args->u.vinteger != 0)
	goto argument_error;

      echo ();
    }
  /* ********************************************************************** */
  else if (method == ctx->s_endwin)
    {
      if (args->u.vinteger != 0)
	goto argument_error;

      endwin ();
    }
  /* ********************************************************************** */
  else if (method == ctx->s_getch)
    {
      if (args->u.vinteger != 0)
	goto argument_error;

      result_return->type = JS_INTEGER;
      result_return->u.vinteger = getch ();
    }
  /* ********************************************************************** */
  else if (method == ctx->s_initscr)
    {
      if (args->u.vinteger != 0)
	goto argument_error;

      if (initscr () == (WINDOW *) ERR)
	result_return->u.vboolean = 0;
    }
  /* ********************************************************************** */
  else if (method == ctx->s_keypad)
    {
      if (args->u.vinteger != 1)
	goto argument_error;
      if (args[1].type != JS_BOOLEAN)
	goto argument_type_error;

      keypad (stdscr, args->u.vboolean);
    }
  /* ********************************************************************** */
  else if (method == ctx->s_move)
    {
      if (args->u.vinteger != 2)
	goto argument_error;
      if (args[1].type != JS_INTEGER || args[2].type != JS_INTEGER)
	goto argument_type_error;

      move (args[1].u.vinteger, args[2].u.vinteger);
    }
  /* ********************************************************************** */
  else if (method == ctx->s_mvaddstr)
    {
      if (args->u.vinteger != 3)
	goto argument_error;
      if (args[1].type != JS_INTEGER || args[2].type != JS_INTEGER
	  || args[3].type != JS_STRING)
	goto argument_type_error;

      cp = js_string_to_c_string (vm, &args[3]);
      mvaddstr (args[1].u.vinteger, args[2].u.vinteger, cp);
      js_free (cp);
    }
  /* ********************************************************************** */
  else if (method == ctx->s_mvaddsubstr)
    {
      int start, length;

      if (args->u.vinteger != 4 && args->u.vinteger != 5)
	goto argument_error;
      if (args[1].type != JS_INTEGER || args[2].type != JS_INTEGER
	  || args[3].type != JS_STRING
	  || args[4].type != JS_INTEGER)
	goto argument_type_error;

      start = args[4].u.vinteger;

      if (args->u.vinteger == 5)
	{
	  if (args[5].type != JS_INTEGER)
	    goto argument_type_error;

	  length = args[5].u.vinteger;
	  if (length < 0)
	    length = 0;
	}
      else
	length = args[3].u.vstring->len;

      if (start < 0)
	start += args[3].u.vstring->len;
      if (start < 0)
	start = 0;
      if (start > args[3].u.vstring->len)
	start = args[3].u.vstring->len;

      if (start + length > args[3].u.vstring->len)
	length = args[3].u.vstring->len - start;

      cp = js_malloc (vm, length + 1);
      memcpy (cp, args[3].u.vstring->data + start, length);
      cp[length] = '\0';
      mvaddstr (args[1].u.vinteger, args[2].u.vinteger, cp);
      js_free (cp);
    }
  /* ********************************************************************** */
  else if (method == ctx->s_mvgetch)
    {
      if (args->u.vinteger != 2)
	goto argument_error;
      if (args[1].type != JS_INTEGER || args[2].type != JS_INTEGER)
	goto argument_type_error;

      result_return->type = JS_INTEGER;
      result_return->u.vinteger = mvgetch (args[1].u.vinteger,
					   args[2].u.vinteger);
    }
  /* ********************************************************************** */
  else if (method == ctx->s_nocbreak)
    {
      if (args->u.vinteger != 0)
	goto argument_error;

      nocbreak ();
    }
  /* ********************************************************************** */
  else if (method == ctx->s_noecho)
    {
      if (args->u.vinteger != 0)
	goto argument_error;

      noecho ();
    }
  /* ********************************************************************** */
  else if (method == ctx->s_refresh)
    {
      if (args->u.vinteger != 0)
	goto argument_error;

      refresh ();
    }
  /* ********************************************************************** */
  else if (method == ctx->s_standend)
    {
      if (args->u.vinteger != 0)
	goto argument_error;

      standend ();
    }
  /* ********************************************************************** */
  else if (method == ctx->s_standout)
    {
      if (args->u.vinteger != 0)
	goto argument_error;

      standout ();
    }
  /* ********************************************************************** */
  else if (method == vm->syms.s_toString)
    {
      if (args->u.vinteger != 0)
	goto argument_error;

      js_vm_make_static_string (vm, result_return, "Curses", 6);
    }
  /* ********************************************************************** */
  else
    return JS_PROPERTY_UNKNOWN;

  return JS_PROPERTY_FOUND;


  /*
   * Error handling.
   */

 argument_error:
  sprintf (vm->error, "Curses.%s(): illegal amount of arguments",
	   js_vm_symname (vm, method));
  js_vm_error (vm);

 argument_type_error:
  sprintf (vm->error, "Curses.%s(): illegal argument",
	   js_vm_symname (vm, method));
  js_vm_error (vm);

  /* NOTREACHED. */
  return 0;
}
Exemplo n.º 19
0
/* Method proc. */
static int
method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
	void *instance_context, JSSymbol method, JSNode *result_return,
	JSNode *args)
{
  ArrayCtx *ctx = builtin_info->obj_context;
  JSNode *n = instance_context;
  int i;

  /* Set the default result type. */
  result_return->type = JS_UNDEFINED;

  if (method == ctx->s_concat)
    {
      if (args->u.vinteger != 1)
	goto argument_error;
      if (args[1].type != JS_ARRAY)
	goto argument_type_error;

      js_vm_make_array (vm, result_return,
			n->u.varray->length + args[1].u.varray->length);

      memcpy (result_return->u.varray->data, n->u.varray->data,
	      n->u.varray->length * sizeof (JSNode));

      memcpy (&result_return->u.varray->data[n->u.varray->length],
	      args[1].u.varray->data,
	      args[1].u.varray->length * sizeof (JSNode));
    }
  /* ********************************************************************** */
  else if (method == ctx->s_join || method == vm->syms.s_toString)
    {
      char *glue = NULL;

      if (method == vm->syms.s_toString)
	{
	  if (args->u.vinteger != 0)
	    goto argument_error;
	}
      else
	{
	  if (args->u.vinteger == 0)
	    ;
	  else if (args->u.vinteger == 1)
	    {
	      JSNode glue_result;

	      js_vm_to_string (vm, &args[1], &glue_result);
	      glue = js_string_to_c_string (vm, &glue_result);
	    }
	  else
	    goto argument_error;
	}

      /* Ok, ready to run. */
      if (n->u.varray->length == 0)
	js_vm_make_static_string (vm, result_return, "", 0);
      else
	{
	  int len;
	  int glue_len = glue ? strlen (glue) : 1;

	  /* Estimate the result length. */
	  len = (n->u.varray->length * 5
		 + (n->u.varray->length - 1) * glue_len);

	  js_vm_make_string (vm, result_return, NULL, len);
	  result_return->u.vstring->len = 0;

	  /* Do the join. */
	  for (i = 0; i < n->u.varray->length; i++)
	    {
	      JSNode sitem;
	      int delta;

	      js_vm_to_string (vm, &n->u.varray->data[i], &sitem);
	      delta = sitem.u.vstring->len;

	      if (i + 1 < n->u.varray->length)
		delta += glue_len;

	      result_return->u.vstring->data
		= js_vm_realloc (vm, result_return->u.vstring->data,
				 result_return->u.vstring->len + delta);

	      memcpy (result_return->u.vstring->data
		      + result_return->u.vstring->len,
		      sitem.u.vstring->data,
		      sitem.u.vstring->len);
	      result_return->u.vstring->len += sitem.u.vstring->len;

	      if (i + 1 < n->u.varray->length)
		{
		  if (glue)
		    {
		      memcpy (result_return->u.vstring->data
			      + result_return->u.vstring->len,
			      glue, glue_len);
		      result_return->u.vstring->len += glue_len;
		    }
		  else
		    result_return->u.vstring->data
		      [result_return->u.vstring->len++] = ',';
		}
	    }
	}

      if (glue)
	js_free (glue);
    }
  /* ********************************************************************** */
  else if (method == ctx->s_pop)
    {
      if (args->u.vinteger != 0)
	goto argument_error;

      if (n->u.varray->length == 0)
	result_return->type = JS_UNDEFINED;
      else
	{
	  JS_COPY (result_return, &n->u.varray->data[n->u.varray->length - 1]);
	  n->u.varray->length--;
	}
    }
  /* ********************************************************************** */
  else if (method == ctx->s_push)
    {
      int old_len;

      if (args->u.vinteger == 0)
	goto argument_error;

      old_len = n->u.varray->length;
      js_vm_expand_array (vm, n, n->u.varray->length + args->u.vinteger);

      for (i = 0; i < args->u.vinteger; i++)
	JS_COPY (&n->u.varray->data[old_len + i], &args[i + 1]);

      JS_COPY (result_return, &args[i]);
    }
  /* ********************************************************************** */
  else if (method == ctx->s_reverse)
    {
      if (args->u.vinteger != 0)
	goto argument_error;

      for (i = 0; i < n->u.varray->length / 2; i++)
	{
	  JSNode tmp;

	  JS_COPY (&tmp, &n->u.varray->data[i]);
	  JS_COPY (&n->u.varray->data[i],
		   &n->u.varray->data[n->u.varray->length - i - 1]);
	  JS_COPY (&n->u.varray->data[n->u.varray->length - i - 1], &tmp);
	}
    }
  /* ********************************************************************** */
  else if (method == ctx->s_shift)
    {
      if (args->u.vinteger != 0)
	goto argument_error;

      if (n->u.varray->length == 0)
	result_return->type = JS_UNDEFINED;
      else
	{
	  JS_COPY (result_return, &n->u.varray->data[0]);
	  memmove (&n->u.varray->data[0], &n->u.varray->data[1],
		   (n->u.varray->length - 1) * sizeof (JSNode));
	  n->u.varray->length--;
	}
    }
  /* ********************************************************************** */
  else if (method == ctx->s_slice)
    {
      int start, end;

      if (args->u.vinteger < 1 || args->u.vinteger > 2)
	goto argument_error;

      if (args[1].type != JS_INTEGER)
	goto argument_type_error;

      start = args[1].u.vinteger;

      if (args->u.vinteger == 2)
	{
	  if (args[2].type != JS_INTEGER)
	    goto argument_type_error;

	  end = args[2].u.vinteger;
	}
      else
	end = n->u.varray->length;

      if (end < 0)
	end += n->u.varray->length;
      if (end < 0)
	end = start;

      js_vm_make_array (vm, result_return, end - start);

      /* Copy items. */
      for (i = 0; i < end - start; i++)
	JS_COPY (&result_return->u.varray->data[i],
		 &n->u.varray->data[start + i]);
    }
  /* ********************************************************************** */
  else if (method == ctx->s_splice)
    {
      unsigned int new_length;
      unsigned int old_length;
      int delta;

      if (args->u.vinteger < 2)
	goto argument_error;
      if (args[1].type != JS_INTEGER || args[2].type != JS_INTEGER)
	goto argument_type_error;

      if (args[2].u.vinteger == 0 && args->u.vinteger == 2)
	/* No deletions: must specify at least one item to insert. */
	goto argument_error;

      old_length = new_length = n->u.varray->length;
      if (args[1].u.vinteger < new_length)
	{
	  if (args[2].u.vinteger > new_length - args[1].u.vinteger)
	    {
	      args[2].u.vinteger = new_length - args[1].u.vinteger;
	      new_length = args[1].u.vinteger;
	    }
	  else
	    new_length -= args[2].u.vinteger;
	}
      else
	{
	  new_length = args[1].u.vinteger;
	  args[2].u.vinteger = 0;
	}

      new_length += args->u.vinteger - 2;

      if (new_length > n->u.varray->length)
	js_vm_expand_array (vm, n, new_length);
      else
	/* Cut the array. */
	n->u.varray->length = new_length;

      /* Do the stuffs we must do. */

      /* Create the result array. */
      if (args[2].u.vinteger == 0)
	result_return->type = JS_UNDEFINED;
      else
	{
	  js_vm_make_array (vm, result_return, args[2].u.vinteger);
	  for (i = 0; i < args[2].u.vinteger; i++)
	    JS_COPY (&result_return->u.varray->data[i],
		     &n->u.varray->data[args[1].u.vinteger + i]);
	}

      /* Delete and move. */
      delta = args->u.vinteger - 2 - args[2].u.vinteger;
      memmove (&n->u.varray->data[args[1].u.vinteger + args[2].u.vinteger
				 + delta],
	       &n->u.varray->data[args[1].u.vinteger + args[2].u.vinteger],
	       (old_length - (args[1].u.vinteger + args[2].u.vinteger))
	       * sizeof (JSNode));

      /* Insert. */
      for (i = 0; i < args->u.vinteger - 2; i++)
	JS_COPY (&n->u.varray->data[args[1].u.vinteger + i], &args[i + 3]);
    }
  /* ********************************************************************** */
  else if (method == ctx->s_sort)
    {
      MergesortCompFunc func;
      ArraySortCtx array_sort_ctx;
      void *func_ctx = NULL;	/* Initialized to keep compiler quiet. */

      if (args->u.vinteger == 0)
	{
	  func = sort_default_cmp_func;
	  func_ctx = vm;
	}
      else if (args->u.vinteger == 1)
	{
	  if (args[1].type != JS_FUNC && args[1].type != JS_BUILTIN)
	    goto argument_type_error;

	  func = sort_js_cmp_func;

	  /* Init context. */
	  array_sort_ctx.vm = vm;
	  array_sort_ctx.func = &args[1];

	  /* Init the argc part of the argument vector here. */
	  array_sort_ctx.argv[0].type = JS_INTEGER;
	  array_sort_ctx.argv[0].u.vinteger = 3;

	  func_ctx = &array_sort_ctx;
	}
      else
	goto argument_error;

      mergesort_r (n->u.varray->data, n->u.varray->length, sizeof (JSNode),
		   func, func_ctx);
    }
  /* ********************************************************************** */
  else if (method == ctx->s_unshift)
    {
      int old_len;

      if (args->u.vinteger == 0)
	goto argument_error;

      old_len = n->u.varray->length;
      js_vm_expand_array (vm, n, n->u.varray->length + args->u.vinteger);

      memmove (&n->u.varray->data[args->u.vinteger], n->u.varray->data,
	       old_len * sizeof (JSNode));

      for (i = 0; i < args->u.vinteger; i++)
	JS_COPY (&n->u.varray->data[i], &args[args->u.vinteger - i]);

      result_return->type = JS_INTEGER;
      result_return->u.vinteger = n->u.varray->length;
    }
  /* ********************************************************************** */
  else
    return JS_PROPERTY_UNKNOWN;

  return JS_PROPERTY_FOUND;


  /*
   * Error handling.
   */

 argument_error:
  sprintf (vm->error, "Array.%s(): illegal amount of arguments",
	   js_vm_symname (vm, method));
  js_vm_error (vm);

 argument_type_error:
  sprintf (vm->error, "Array.%s(): illegal argument",
	   js_vm_symname (vm, method));
  js_vm_error (vm);

  /* NOTREACHED */
  return 0;
}
Exemplo n.º 20
0
static void
escape_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
		      void *instance_context, JSNode *result_return,
		      JSNode *args)
{
  unsigned char *dp;
  unsigned int n, i;
  JSNode *source;
  JSNode source_n;
  static const prog_char charset[] PROGMEM =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_+-./";

  if (args->u.vinteger != 1)
    {
      sprintf (vm->error, b_core_string_2);
      js_vm_error (vm);
    }
  if (args[1].type == JS_STRING)
    source = &args[1];
  else
    {
      /* Convert the argument to string. */
      js_vm_to_string (vm, &args[1], &source_n);
      source = &source_n;
    }

  /*
   * Allocate the result string, Let's guess that we need at least
   * <source->u.vstring->len> bytes of data.
   */
  n = source->u.vstring->len;
  dp = source->u.vstring->data;
  js_vm_make_string (vm, result_return, NULL, n);
  result_return->u.vstring->len = 0;

  /*
   * Scan for characters requiring escapes.
   */
  for (i = 0; i < n; i += 1)
    {
      unsigned int c = dp[i];

      if (strchr_P (charset, c))
	EMIT_TO_RESULT (c);
      else if (c > 0xFF)
	{
	  unsigned char buf[6];

	  sprintf (buf, "%04x", c);
	  EMIT_TO_RESULT ('%');
	  EMIT_TO_RESULT ('u');
	  EMIT_TO_RESULT (buf[0]);
	  EMIT_TO_RESULT (buf[1]);
	  EMIT_TO_RESULT (buf[2]);
	  EMIT_TO_RESULT (buf[3]);
      }
    else
      {
	unsigned char buf[4];
	sprintf (buf, "%02x", c);

	EMIT_TO_RESULT ('%');
	EMIT_TO_RESULT (buf[0]);
	EMIT_TO_RESULT (buf[1]);
      }
    }
}
Exemplo n.º 21
0
void
js_vm_object_store_array (JSVirtualMachine *vm, JSObject *obj, JSNode *sel,
			  JSNode *value)
{
  if (sel->type == JS_INTEGER)
    {
      if (sel->u.vinteger < 0)
	{
	  sprintf (vm->error, "store_array: array index can't be nagative");
	  js_vm_error (vm);
	}
      if (sel->u.vinteger >= obj->num_props)
	{
	  /* Expand properties. */
	  obj->props = js_vm_realloc (vm, obj->props,
				      (sel->u.vinteger + 1)
				      * sizeof (JSProperty));

	  /* Init the possible gap. */
	  for (; obj->num_props <= sel->u.vinteger; obj->num_props++)
	    {
	      obj->props[obj->num_props].name = 0;
	      obj->props[obj->num_props].attributes = 0;
	      obj->props[obj->num_props].value.type = JS_UNDEFINED;
	    }
	}

      JS_COPY (&obj->props[sel->u.vinteger].value, value);
    }
  else if (sel->type == JS_STRING)
    {
      int pos;

      if (obj->hash == NULL)
	hash_create (vm, obj);

      pos = hash_lookup (obj, (char *) sel->u.vstring->data,
			 sel->u.vstring->len);
      if (pos < 0)
	{
	  /* It is undefined, define it. */
	  obj->props = js_vm_realloc (vm, obj->props,
				      (obj->num_props + 1)
				      * sizeof (JSProperty));

	  /*
	   * XXX if <sel> is a valid symbol, intern it and set symbol's
	   * name below.
	   */
	  obj->props[obj->num_props].name = JS_SYMBOL_NULL;
	  obj->props[obj->num_props].attributes = 0;
	  JS_COPY (&obj->props[obj->num_props].value, value);

	  hash_insert (vm, obj, (char *) sel->u.vstring->data,
		       sel->u.vstring->len, obj->num_props);

	  obj->num_props++;
	}
      else
	JS_COPY (&obj->props[pos].value, value);
    }
}
Exemplo n.º 22
0
/* Method proc. */
static int
method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
	void *instance_context, JSSymbol method, JSNode *result_return,
	JSNode *args)
{
  XJSCtx *ctx = builtin_info->obj_context;
  XJSInstanceCtx *instance = instance_context;

  /* The default result is false. */
  result_return->type = JS_BOOLEAN;
  result_return->u.vboolean = 0;

  /*
   * Static methods.
   */
  if (method == vm->syms.s_toString)
    {
      if (args->u.vinteger != 0)
	goto argument_error;

      if (instance)
	js_vm_make_static_string (vm, result_return, "JSInterp", 8);
      else
	js_vm_make_static_string (vm, result_return, "JS", 2);
    }
  /* ********************************************************************** */
  else if (instance)
    {
      /*
       * Instance methods.
       */

      if (method == ctx->s_compile)
	{
	  if (args->u.vinteger != 3)
	    goto argument_error;

	  if (args[1].type != JS_STRING
	      || (args[2].type != JS_NULL && args[2].type != JS_STRING)
	      || (args[3].type != JS_NULL && args[3].type != JS_STRING))
	    goto argument_type_error;
	}
      /* ***************************************************************** */
      else if (method == ctx->s_eval)
	{
	  if (args->u.vinteger != 1)
	    goto argument_error;

	  if (args[1].type != JS_STRING)
	    goto argument_type_error;

	  result_return->type = JS_BOOLEAN;
	  result_return->u.vboolean
	    = (js_eval_data (instance->interp, args[1].u.vstring->data,
			     args[1].u.vstring->len) != 0);
	}
      /* ***************************************************************** */
      else if (method == ctx->s_evalFile)
	{
	  char *path;

	  if (args->u.vinteger != 1)
	    goto argument_error;

	  if (args[1].type != JS_STRING)
	    goto argument_type_error;

	  path = js_string_to_c_string (vm, &args[1]);

	  result_return->type = JS_BOOLEAN;
	  result_return->u.vboolean = (js_eval_file (instance->interp, path)
				       != 0);

	  js_free (path);
	}
      /* ***************************************************************** */
      else if (method == ctx->s_evalJavaScriptFile)
	{
	  char *path;

	  if (args->u.vinteger != 1)
	    goto argument_error;

	  if (args[1].type != JS_STRING)
	    goto argument_type_error;

	  path = js_string_to_c_string (vm, &args[1]);

	  result_return->type = JS_BOOLEAN;
	  result_return->u.vboolean
	    = (js_eval_javascript_file (instance->interp, path) != 0);

	  js_free (path);
	}
      /* ***************************************************************** */
      else if (method == ctx->s_executeByteCodeFile)
	{
	  char *path;

	  if (args->u.vinteger != 1)
	    goto argument_error;

	  if (args[1].type != JS_STRING)
	    goto argument_type_error;

	  path = js_string_to_c_string (vm, &args[1]);

	  result_return->type = JS_BOOLEAN;
	  result_return->u.vboolean
	    = (js_execute_byte_code_file (instance->interp, path) != 0);

	  js_free (path);
	}
      /* ***************************************************************** */
      else if (method == ctx->s_getVar)
	{
	  char *cp;
	  JSType value;

	  if (args->u.vinteger != 1)
	    goto argument_error;

	  if (args[1].type != JS_STRING)
	    goto argument_type_error;

	  cp = js_string_to_c_string (vm, &args[1]);
	  js_get_var (instance->interp, cp, &value);
	  js_free (cp);

	  copy_from_type_to_node (vm, result_return, &value);
	}
      /* ***************************************************************** */
      else if (method == ctx->s_setVar)
	{
	  char *cp;
	  JSType value;

	  if (args->u.vinteger != 2)
	    goto argument_error;

	  if (args[1].type != JS_STRING)
	    goto argument_type_error;

	  copy_from_node_to_type (instance->interp, &value, &args[2]);

	  cp = js_string_to_c_string (vm, &args[1]);
	  js_set_var (instance->interp, cp, &value);
	  js_free (cp);

	  result_return->type = JS_UNDEFINED;
	}
      /* ***************************************************************** */
      else
	return JS_PROPERTY_UNKNOWN;
    }
  /* ********************************************************************** */
  else
    return JS_PROPERTY_UNKNOWN;

  return JS_PROPERTY_FOUND;


  /*
   * Error handling.
   */

 argument_error:
  sprintf (vm->error, "JS.%s(): illegal amount of arguments",
	   js_vm_symname (vm, method));
  js_vm_error (vm);

 argument_type_error:
  sprintf (vm->error, "JS.%s(): illegal argument",
	   js_vm_symname (vm, method));
  js_vm_error (vm);

  /* NOTREACHED */
  return 0;
}