migrate substitution keywords to SVN
[reactos.git] / reactos / lib / kjs / src / b_vm.c
1 /*
2 * The builtin VM object.
3 * Copyright (c) 1998-1999 New Generation Software (NGS) Oy
4 *
5 * Author: Markku Rossi <mtr@ngs.fi>
6 */
7
8 /*
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the Free
21 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
22 * MA 02111-1307, USA
23 */
24
25 /*
26 * $Source: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/b_vm.c,v $
27 * $Id$
28 */
29
30 /*
31 * Class:
32 *
33 * - static methods:
34 *
35 * VM.garbageCollect ()
36 * VM.stackTrace ()
37 *
38 * - properties: type mutable
39 *
40 * VM.dispatchMethod string
41 * VM.fdCount integer
42 * VM.gcCount integer
43 * VM.gcTrigger integer yes
44 * VM.heapAllocated integer
45 * VM.heapFree integer
46 * VM.heapSize integer
47 * VM.numConstants integer
48 * VM.numGlobals integer
49 * VM.stackSize integer
50 * VM.stacktraceOnError boolean yes
51 * VM.verbose integer yes
52 * VM.verboseStacktrace boolean yes
53 * VM.version string
54 * VM.versionMajor integer
55 * VM.versionMinor integer
56 * VM.versionPatch integer
57 * VM.warnUndef boolean yes
58 */
59
60 #include "jsint.h"
61
62 /*
63 * Types and definitions.
64 */
65
66 struct vm_ctx_st
67 {
68 JSSymbol s_garbageCollect;
69 JSSymbol s_stackTrace;
70
71 JSSymbol s_dispatchMethod;
72 JSSymbol s_fdCount;
73 JSSymbol s_gcCount;
74 JSSymbol s_gcTrigger;
75 JSSymbol s_heapAllocated;
76 JSSymbol s_heapFree;
77 JSSymbol s_heapSize;
78 JSSymbol s_numConstants;
79 JSSymbol s_numGlobals;
80 JSSymbol s_stackSize;
81 JSSymbol s_stacktraceOnError;
82 JSSymbol s_verbose;
83 JSSymbol s_verboseStacktrace;
84 JSSymbol s_version;
85 JSSymbol s_versionMajor;
86 JSSymbol s_versionMinor;
87 JSSymbol s_versionPatch;
88 JSSymbol s_warnUndef;
89 };
90
91 typedef struct vm_ctx_st VMCtx;
92
93
94 /*
95 * Static functions.
96 */
97
98 /* Method proc */
99 static int
100 method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
101 void *instance_context, JSSymbol method, JSNode *result_return,
102 JSNode *args)
103 {
104 VMCtx *ctx = builtin_info->obj_context;
105
106 /* The default return value is undefined. */
107 result_return->type = JS_UNDEFINED;
108
109 if (method == ctx->s_garbageCollect)
110 {
111 if (args->u.vinteger != 0)
112 goto argument_error;
113
114 /* Ok, let's trigger a garbage collection. */
115 vm->gc.bytes_allocated = vm->gc.trigger + 1;
116 }
117 /* ********************************************************************** */
118 else if (method == ctx->s_stackTrace)
119 {
120 unsigned int limit;
121
122 if (args->u.vinteger == 0)
123 limit = -1;
124 else if (args->u.vinteger == 1)
125 {
126 if (args[1].type != JS_INTEGER)
127 goto argument_type_error;
128
129 limit = args[1].u.vinteger;
130 }
131 else
132 goto argument_error;
133
134 js_vm_stacktrace (vm, limit);
135 }
136 /* ********************************************************************** */
137 else if (method == vm->syms.s_toString)
138 {
139 if (args->u.vinteger != 0)
140 goto argument_error;
141
142 js_vm_make_static_string (vm, result_return, "VM", 2);
143 }
144 /* ********************************************************************** */
145 else
146 return JS_PROPERTY_UNKNOWN;
147
148 return JS_PROPERTY_FOUND;
149
150
151 /*
152 * Error handling.
153 */
154
155 argument_error:
156 sprintf (vm->error, "VM.%s(): illegal amout of arguments",
157 js_vm_symname (vm, method));
158 js_vm_error (vm);
159
160 argument_type_error:
161 sprintf (vm->error, "VM.%s(): illegal argument",
162 js_vm_symname (vm, method));
163 js_vm_error (vm);
164
165 /* NOTREACHED */
166 return 0;
167 }
168
169 /* Property proc. */
170 static int
171 property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
172 void *instance_context, JSSymbol property, int set, JSNode *node)
173 {
174 VMCtx *ctx = builtin_info->obj_context;
175
176 if (property == ctx->s_dispatchMethod)
177 {
178 if (set)
179 goto immutable;
180
181 js_vm_make_static_string (vm, node,
182 vm->dispatch_method_name,
183 strlen (vm->dispatch_method_name));
184 }
185 /* ***************************************************************** */
186 else if (property == ctx->s_fdCount)
187 {
188 if (set)
189 goto immutable;
190
191 node->type = JS_INTEGER;
192 node->u.vinteger = vm->fd_count;
193 }
194 /* ***************************************************************** */
195 else if (property == ctx->s_gcCount)
196 {
197 if (set)
198 goto immutable;
199
200 node->type = JS_INTEGER;
201 node->u.vinteger = vm->gc.count;
202 }
203 /* ***************************************************************** */
204 else if (property == ctx->s_gcTrigger)
205 {
206 if (set)
207 {
208 if (node->type != JS_INTEGER)
209 goto value_error;
210 vm->gc.trigger = node->u.vinteger;
211 }
212 else
213 {
214 node->type = JS_INTEGER;
215 node->u.vinteger = vm->gc.trigger;
216 }
217 }
218 /* ***************************************************************** */
219 else if (property == ctx->s_heapAllocated)
220 {
221 if (set)
222 goto immutable;
223
224 node->type = JS_INTEGER;
225 node->u.vinteger = vm->gc.bytes_allocated;
226 }
227 /* ***************************************************************** */
228 else if (property == ctx->s_heapFree)
229 {
230 if (set)
231 goto immutable;
232
233 node->type = JS_INTEGER;
234 node->u.vinteger = vm->gc.bytes_free;
235 }
236 /* ***************************************************************** */
237 else if (property == ctx->s_heapSize)
238 {
239 if (set)
240 goto immutable;
241
242 node->type = JS_INTEGER;
243 node->u.vinteger = vm->heap_size;
244 }
245 /* ***************************************************************** */
246 else if (property == ctx->s_numConstants)
247 {
248 if (set)
249 goto immutable;
250
251 node->type = JS_INTEGER;
252 node->u.vinteger = vm->num_consts;
253 }
254 /* ***************************************************************** */
255 else if (property == ctx->s_numGlobals)
256 {
257 if (set)
258 goto immutable;
259
260 node->type = JS_INTEGER;
261 node->u.vinteger = vm->num_globals;
262 }
263 /* ***************************************************************** */
264 else if (property == ctx->s_stackSize)
265 {
266 if (set)
267 goto immutable;
268
269 node->type = JS_INTEGER;
270 node->u.vinteger = vm->stack_size;
271 }
272 /* ***************************************************************** */
273 else if (property == ctx->s_stacktraceOnError)
274 {
275 if (set)
276 {
277 if (node->type != JS_BOOLEAN)
278 goto value_error;
279 vm->stacktrace_on_error = node->u.vboolean;
280 }
281 else
282 {
283 node->type = JS_BOOLEAN;
284 node->u.vboolean = vm->stacktrace_on_error;
285 }
286 }
287 /* ***************************************************************** */
288 else if (property == ctx->s_verbose)
289 {
290 if (set)
291 {
292 if (node->type != JS_INTEGER)
293 goto value_error;
294 vm->verbose = node->u.vinteger;
295 }
296 else
297 {
298 node->type = JS_INTEGER;
299 node->u.vinteger = vm->verbose;
300 }
301 }
302 /* ***************************************************************** */
303 else if (property == ctx->s_verboseStacktrace)
304 {
305 if (set)
306 {
307 if (node->type != JS_BOOLEAN)
308 goto value_error;
309 vm->verbose_stacktrace = node->u.vboolean;
310 }
311 else
312 {
313 node->type = JS_BOOLEAN;
314 node->u.vboolean = vm->verbose_stacktrace;
315 }
316 }
317 /* ***************************************************************** */
318 else if (property == ctx->s_version)
319 {
320 if (set)
321 goto immutable;
322
323 js_vm_make_static_string (vm, node, VERSION, strlen (VERSION));
324 }
325 /* ***************************************************************** */
326 else if (property == ctx->s_versionMajor)
327 {
328 if (set)
329 goto immutable;
330
331 node->type = JS_INTEGER;
332 node->u.vinteger = atoi (VERSION);
333 }
334 /* ***************************************************************** */
335 else if (property == ctx->s_versionMinor)
336 {
337 if (set)
338 goto immutable;
339
340 node->type = JS_INTEGER;
341 node->u.vinteger = atoi (VERSION + 2);
342 }
343 /* ***************************************************************** */
344 else if (property == ctx->s_versionPatch)
345 {
346 if (set)
347 goto immutable;
348
349 node->type = JS_INTEGER;
350 node->u.vinteger = atoi (VERSION + 4);
351 }
352 /* ***************************************************************** */
353 else if (property == ctx->s_warnUndef)
354 {
355 if (set)
356 {
357 if (node->type != JS_INTEGER)
358 goto value_error;
359 vm->warn_undef = node->u.vinteger != 0;
360 }
361 else
362 {
363 node->type = JS_INTEGER;
364 node->u.vinteger = vm->warn_undef;
365 }
366 }
367 /* ***************************************************************** */
368 else
369 {
370 if (!set)
371 node->type = JS_UNDEFINED;
372
373 return JS_PROPERTY_UNKNOWN;
374 }
375
376 return JS_PROPERTY_FOUND;
377
378
379 /*
380 * Error handling.
381 */
382
383 value_error:
384 sprintf (vm->error, "VM.%s: illegal value",
385 js_vm_symname (vm, property));
386 js_vm_error (vm);
387
388 immutable:
389 sprintf (vm->error, "VM.%s: immutable property",
390 js_vm_symname (vm, property));
391 js_vm_error (vm);
392
393 /* NOTREACHED. */
394 return 0;
395 }
396
397
398 /*
399 * Global functions.
400 */
401
402 void
403 js_builtin_VM (JSVirtualMachine *vm)
404 {
405 JSNode *n;
406 JSBuiltinInfo *info;
407 VMCtx *ctx;
408
409 ctx = js_calloc (vm, 1, sizeof (*ctx));
410
411 ctx->s_garbageCollect = js_vm_intern (vm, "garbageCollect");
412 ctx->s_stackTrace = js_vm_intern (vm, "stackTrace");
413
414 ctx->s_dispatchMethod = js_vm_intern (vm, "dispatchMethod");
415 ctx->s_fdCount = js_vm_intern (vm, "fdCount");
416 ctx->s_gcCount = js_vm_intern (vm, "gcCount");
417 ctx->s_gcTrigger = js_vm_intern (vm, "gcTrigger");
418 ctx->s_heapAllocated = js_vm_intern (vm, "heapAllocated");
419 ctx->s_heapFree = js_vm_intern (vm, "heapFree");
420 ctx->s_heapSize = js_vm_intern (vm, "heapSize");
421 ctx->s_numConstants = js_vm_intern (vm, "numConstants");
422 ctx->s_numGlobals = js_vm_intern (vm, "numGlobals");
423 ctx->s_stackSize = js_vm_intern (vm, "stackSize");
424 ctx->s_stacktraceOnError = js_vm_intern (vm, "stacktraceOnError");
425 ctx->s_verbose = js_vm_intern (vm, "verbose");
426 ctx->s_verboseStacktrace = js_vm_intern (vm, "verboseStacktrace");
427 ctx->s_version = js_vm_intern (vm, "version");
428 ctx->s_versionMajor = js_vm_intern (vm, "versionMajor");
429 ctx->s_versionMinor = js_vm_intern (vm, "versionMinor");
430 ctx->s_versionPatch = js_vm_intern (vm, "versionPatch");
431 ctx->s_warnUndef = js_vm_intern (vm, "warnUndef");
432
433 /* Object information. */
434
435 info = js_vm_builtin_info_create (vm);
436
437 info->method_proc = method;
438 info->property_proc = property;
439 info->obj_context = ctx;
440 info->obj_context_delete = js_free;
441
442 /* Define it. */
443 n = &vm->globals[js_vm_intern (vm, "VM")];
444 js_vm_builtin_create (vm, n, info, NULL);
445 }