ClamAV is an open source (GPLv2) anti-virus toolkit.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
clamav/libclamav/js/b_number.c

326 lines
6.8 KiB

/*
* The builtin Number object.
* Copyright (c) 1998 New Generation Software (NGS) Oy
*
* Author: Markku Rossi <mtr@ngs.fi>
*/
/*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA
*/
/*
* $Source: /tmp/cvsroot-15-2-2007/clamav-devel/libclamav/js/b_number.c,v $
* $Id: b_number.c,v 1.2 2006/10/28 11:27:44 njh Exp $
*/
/*
* Standard: ECMAScript-2.0.draft-22-Apr-98
*/
#if HAVE_CONFIG_H
#include "clamav-config.h"
#endif
#ifdef CL_EXPERIMENTAL
#include "jsint.h"
/*
* Types and definitions.
*/
/* Class context. */
struct number_ctx_st
{
JSSymbol s_MAX_VALUE;
JSSymbol s_MIN_VALUE;
JSSymbol s_NaN;
JSSymbol s_NEGATIVE_INFINITY;
JSSymbol s_POSITIVE_INFINITY;
};
typedef struct number_ctx_st NumberCtx;
/*
* Static functions.
*/
/* Global method proc. */
static void
global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
void *instance_context, JSNode *result_return,
JSNode *args)
{
if (args->u.vinteger == 0)
{
result_return->type = JS_INTEGER;
result_return->u.vinteger = 0;
}
else if (args->u.vinteger == 1)
{
js_vm_to_number (vm, &args[1], result_return);
}
else
{
sprintf (vm->error, "Number(): illegal amount of arguments");
js_vm_error (vm);
}
}
/* 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 2:
{
char buf2[256];
int i;
unsigned int bit = 1;
unsigned long ul = (unsigned long) n->u.vinteger;
for (i = 0; bit > 0; bit <<= 1, i++)
buf2[i] = (ul & bit) ? '1' : '0';
for (i--; i > 0 && buf2[i] == '0'; i--)
;
bit = i;
for (; i >= 0; i--)
buf[bit - i] = buf2[i];
buf[bit + 1] = '\0';
}
break;
case 8:
sprintf (buf, "%lo", (unsigned long) 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);
js_vm_error (vm);
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 if (method == vm->syms.s_valueOf)
{
if (n == NULL)
n = &vm->globals[js_vm_intern (vm, "Number")];
JS_COPY (result_return, n);
}
/* ********************************************************************** */
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;
}
/* 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;
JS_MAKE_NEGATIVE_INFINITY (node);
}
else if (property == ctx->s_POSITIVE_INFINITY)
{
if (set)
goto immutable;
JS_MAKE_POSITIVE_INFINITY (node);
}
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;
}
/* New proc. */
static void
new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, JSNode *args,
JSNode *result_return)
{
if (args->u.vinteger == 0)
{
result_return->type = JS_INTEGER;
result_return->u.vinteger = 0;
}
else if (args->u.vinteger == 1)
{
js_vm_to_number (vm, &args[1], result_return);
}
else
{
sprintf (vm->error, "new Number(): illegal amount of arguments");
js_vm_error (vm);
}
}
/*
* Global functions.
*/
void
js_builtin_Number (JSVirtualMachine *vm)
{
NumberCtx *ctx;
JSNode *n;
JSBuiltinInfo *info;
ctx = js_calloc (vm, 1, sizeof (*ctx));
ctx->s_MAX_VALUE = js_vm_intern (vm, "MAX_VALUE");
ctx->s_MIN_VALUE = js_vm_intern (vm, "MIN_VALUE");
ctx->s_NaN = js_vm_intern (vm, "NaN");
ctx->s_NEGATIVE_INFINITY = js_vm_intern (vm, "NEGATIVE_INFINITY");
ctx->s_POSITIVE_INFINITY = js_vm_intern (vm, "POSITIVE_INFINITY");
info = js_vm_builtin_info_create (vm);
vm->prim[JS_INTEGER] = info;
vm->prim[JS_FLOAT] = info;
vm->prim[JS_NAN] = info;
info->global_method_proc = global_method;
info->method_proc = method;
info->property_proc = property;
info->new_proc = new_proc;
info->obj_context = ctx;
info->obj_context_delete = js_free;
/* Define it. */
n = &vm->globals[js_vm_intern (vm, "Number")];
js_vm_builtin_create (vm, n, info, NULL);
}
#endif /*CL_EXPERIMENTAL*/