mirror of https://github.com/Cisco-Talos/clamav
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.
451 lines
11 KiB
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*/
|
|
|