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_vm.c

451 lines
11 KiB

/*
* The builtin VM object.
* Copyright (c) 1998-1999 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_vm.c,v $
* $Id: b_vm.c,v 1.2 2006/10/28 11:27:44 njh Exp $
*/
/*
* Class:
*
* - static methods:
*
* VM.garbageCollect ()
* VM.stackTrace ()
*
* - properties: type mutable
*
* VM.dispatchMethod string
* VM.fdCount integer
* VM.gcCount integer
* VM.gcTrigger integer yes
* VM.heapAllocated integer
* VM.heapFree integer
* VM.heapSize integer
* VM.numConstants integer
* VM.numGlobals integer
* VM.stackSize integer
* VM.stacktraceOnError boolean yes
* VM.verbose integer yes
* VM.verboseStacktrace boolean yes
* VM.version string
* VM.versionMajor integer
* VM.versionMinor integer
* VM.versionPatch integer
* VM.warnUndef boolean yes
*/
#if HAVE_CONFIG_H
#include "clamav-config.h"
#endif
#ifdef CL_EXPERIMENTAL
#include "jsint.h"
/*
* Types and definitions.
*/
struct vm_ctx_st
{
JSSymbol s_garbageCollect;
JSSymbol s_stackTrace;
JSSymbol s_dispatchMethod;
JSSymbol s_fdCount;
JSSymbol s_gcCount;
JSSymbol s_gcTrigger;
JSSymbol s_heapAllocated;
JSSymbol s_heapFree;
JSSymbol s_heapSize;
JSSymbol s_numConstants;
JSSymbol s_numGlobals;
JSSymbol s_stackSize;
JSSymbol s_stacktraceOnError;
JSSymbol s_verbose;
JSSymbol s_verboseStacktrace;
JSSymbol s_version;
JSSymbol s_versionMajor;
JSSymbol s_versionMinor;
JSSymbol s_versionPatch;
JSSymbol s_warnUndef;
};
typedef struct vm_ctx_st VMCtx;
/*
* Static functions.
*/
/* Method proc */
static int
method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
void *instance_context, JSSymbol method, JSNode *result_return,
JSNode *args)
{
VMCtx *ctx = builtin_info->obj_context;
/* The default return value is undefined. */
result_return->type = JS_UNDEFINED;
if (method == ctx->s_garbageCollect)
{
if (args->u.vinteger != 0)
goto argument_error;
/* Ok, let's trigger a garbage collection. */
vm->gc.bytes_allocated = vm->gc.trigger + 1;
}
/* ********************************************************************** */
else if (method == ctx->s_stackTrace)
{
unsigned int limit;
if (args->u.vinteger == 0)
limit = -1;
else if (args->u.vinteger == 1)
{
if (args[1].type != JS_INTEGER)
goto argument_type_error;
limit = args[1].u.vinteger;
}
else
goto argument_error;
js_vm_stacktrace (vm, limit);
}
/* ********************************************************************** */
else if (method == vm->syms.s_toString)
{
if (args->u.vinteger != 0)
goto argument_error;
js_vm_make_static_string (vm, result_return, "VM", 2);
}
/* ********************************************************************** */
else
return JS_PROPERTY_UNKNOWN;
return JS_PROPERTY_FOUND;
/*
* Error handling.
*/
argument_error:
sprintf (vm->error, "VM.%s(): illegal amout of arguments",
js_vm_symname (vm, method));
js_vm_error (vm);
argument_type_error:
sprintf (vm->error, "VM.%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)
{
VMCtx *ctx = builtin_info->obj_context;
if (property == ctx->s_dispatchMethod)
{
if (set)
goto immutable;
js_vm_make_static_string (vm, node,
vm->dispatch_method_name,
strlen (vm->dispatch_method_name));
}
/* ***************************************************************** */
else if (property == ctx->s_fdCount)
{
if (set)
goto immutable;
node->type = JS_INTEGER;
node->u.vinteger = vm->fd_count;
}
/* ***************************************************************** */
else if (property == ctx->s_gcCount)
{
if (set)
goto immutable;
node->type = JS_INTEGER;
node->u.vinteger = vm->gc.count;
}
/* ***************************************************************** */
else if (property == ctx->s_gcTrigger)
{
if (set)
{
if (node->type != JS_INTEGER)
goto value_error;
vm->gc.trigger = node->u.vinteger;
}
else
{
node->type = JS_INTEGER;
node->u.vinteger = vm->gc.trigger;
}
}
/* ***************************************************************** */
else if (property == ctx->s_heapAllocated)
{
if (set)
goto immutable;
node->type = JS_INTEGER;
node->u.vinteger = vm->gc.bytes_allocated;
}
/* ***************************************************************** */
else if (property == ctx->s_heapFree)
{
if (set)
goto immutable;
node->type = JS_INTEGER;
node->u.vinteger = vm->gc.bytes_free;
}
/* ***************************************************************** */
else if (property == ctx->s_heapSize)
{
if (set)
goto immutable;
node->type = JS_INTEGER;
node->u.vinteger = vm->heap_size;
}
/* ***************************************************************** */
else if (property == ctx->s_numConstants)
{
if (set)
goto immutable;
node->type = JS_INTEGER;
node->u.vinteger = vm->num_consts;
}
/* ***************************************************************** */
else if (property == ctx->s_numGlobals)
{
if (set)
goto immutable;
node->type = JS_INTEGER;
node->u.vinteger = vm->num_globals;
}
/* ***************************************************************** */
else if (property == ctx->s_stackSize)
{
if (set)
goto immutable;
node->type = JS_INTEGER;
node->u.vinteger = vm->stack_size;
}
/* ***************************************************************** */
else if (property == ctx->s_stacktraceOnError)
{
if (set)
{
if (node->type != JS_BOOLEAN)
goto value_error;
vm->stacktrace_on_error = node->u.vboolean;
}
else
{
node->type = JS_BOOLEAN;
node->u.vboolean = vm->stacktrace_on_error;
}
}
/* ***************************************************************** */
else if (property == ctx->s_verbose)
{
if (set)
{
if (node->type != JS_INTEGER)
goto value_error;
vm->verbose = node->u.vinteger;
}
else
{
node->type = JS_INTEGER;
node->u.vinteger = vm->verbose;
}
}
/* ***************************************************************** */
else if (property == ctx->s_verboseStacktrace)
{
if (set)
{
if (node->type != JS_BOOLEAN)
goto value_error;
vm->verbose_stacktrace = node->u.vboolean;
}
else
{
node->type = JS_BOOLEAN;
node->u.vboolean = vm->verbose_stacktrace;
}
}
/* ***************************************************************** */
else if (property == ctx->s_version)
{
if (set)
goto immutable;
js_vm_make_static_string (vm, node, VERSION, strlen (VERSION));
}
/* ***************************************************************** */
else if (property == ctx->s_versionMajor)
{
if (set)
goto immutable;
node->type = JS_INTEGER;
node->u.vinteger = atoi (VERSION);
}
/* ***************************************************************** */
else if (property == ctx->s_versionMinor)
{
if (set)
goto immutable;
node->type = JS_INTEGER;
node->u.vinteger = atoi (VERSION + 2);
}
/* ***************************************************************** */
else if (property == ctx->s_versionPatch)
{
if (set)
goto immutable;
node->type = JS_INTEGER;
node->u.vinteger = atoi (VERSION + 4);
}
/* ***************************************************************** */
else if (property == ctx->s_warnUndef)
{
if (set)
{
if (node->type != JS_INTEGER)
goto value_error;
vm->warn_undef = node->u.vinteger != 0;
}
else
{
node->type = JS_INTEGER;
node->u.vinteger = vm->warn_undef;
}
}
/* ***************************************************************** */
else
{
if (!set)
node->type = JS_UNDEFINED;
return JS_PROPERTY_UNKNOWN;
}
return JS_PROPERTY_FOUND;
/*
* Error handling.
*/
value_error:
sprintf (vm->error, "VM.%s: illegal value",
js_vm_symname (vm, property));
js_vm_error (vm);
immutable:
sprintf (vm->error, "VM.%s: immutable property",
js_vm_symname (vm, property));
js_vm_error (vm);
/* NOTREACHED. */
return 0;
}
/*
* Global functions.
*/
void
js_builtin_VM (JSVirtualMachine *vm)
{
JSNode *n;
JSBuiltinInfo *info;
VMCtx *ctx;
ctx = js_calloc (vm, 1, sizeof (*ctx));
ctx->s_garbageCollect = js_vm_intern (vm, "garbageCollect");
ctx->s_stackTrace = js_vm_intern (vm, "stackTrace");
ctx->s_dispatchMethod = js_vm_intern (vm, "dispatchMethod");
ctx->s_fdCount = js_vm_intern (vm, "fdCount");
ctx->s_gcCount = js_vm_intern (vm, "gcCount");
ctx->s_gcTrigger = js_vm_intern (vm, "gcTrigger");
ctx->s_heapAllocated = js_vm_intern (vm, "heapAllocated");
ctx->s_heapFree = js_vm_intern (vm, "heapFree");
ctx->s_heapSize = js_vm_intern (vm, "heapSize");
ctx->s_numConstants = js_vm_intern (vm, "numConstants");
ctx->s_numGlobals = js_vm_intern (vm, "numGlobals");
ctx->s_stackSize = js_vm_intern (vm, "stackSize");
ctx->s_stacktraceOnError = js_vm_intern (vm, "stacktraceOnError");
ctx->s_verbose = js_vm_intern (vm, "verbose");
ctx->s_verboseStacktrace = js_vm_intern (vm, "verboseStacktrace");
ctx->s_version = js_vm_intern (vm, "version");
ctx->s_versionMajor = js_vm_intern (vm, "versionMajor");
ctx->s_versionMinor = js_vm_intern (vm, "versionMinor");
ctx->s_versionPatch = js_vm_intern (vm, "versionPatch");
ctx->s_warnUndef = js_vm_intern (vm, "warnUndef");
/* Object information. */
info = js_vm_builtin_info_create (vm);
info->method_proc = method;
info->property_proc = property;
info->obj_context = ctx;
info->obj_context_delete = js_free;
/* Define it. */
n = &vm->globals[js_vm_intern (vm, "VM")];
js_vm_builtin_create (vm, n, info, NULL);
}
#endif /*CL_EXPERIMENTAL*/