From f48739f395261773d24cb88fb08fc75b989637fb Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sat, 10 Jan 2004 20:38:18 +0000 Subject: [PATCH] Added kjs -- The kernel javascript system. This system allows the kernel debugger to be scripted with the new js command. Functions for reading and writing memory, as well as reading the module list, the registry, and the trap frame registers are provided. A simple mechanism is provided for reading javascript initialization from the registry so that the user may provide custom functions for use during debugging sessions. I have already used it to find a bug in kdb itself; as well as to list sections in modules and perform various other tedious tasks often required while debugging linked lists, etc. This is a static library that will be built when KDBG=1, and linked with ntoskrnl. svn path=/trunk/; revision=7554 --- reactos/lib/kjs/AUTHORS | 4 + reactos/lib/kjs/COPYING | 482 + reactos/lib/kjs/ChangeLog | 112 + reactos/lib/kjs/INSTALL | 183 + reactos/lib/kjs/MODIFICATIONS | 6 + reactos/lib/kjs/Makefile.am | 35 + reactos/lib/kjs/Makefile.in | 384 + reactos/lib/kjs/Makefile.orig | 384 + reactos/lib/kjs/NEWS | 131 + reactos/lib/kjs/README | 69 + reactos/lib/kjs/THANKS | 7 + reactos/lib/kjs/TODO | 13 + reactos/lib/kjs/acconfig.h | 76 + reactos/lib/kjs/aclocal.m4 | 664 ++ reactos/lib/kjs/am.opt/libtool.m4 | 259 + reactos/lib/kjs/am/pthreads.m4 | 179 + reactos/lib/kjs/config.cache | 48 + reactos/lib/kjs/config.log | 53 + reactos/lib/kjs/configure.in | 275 + reactos/lib/kjs/docs/Makefile | 343 + reactos/lib/kjs/docs/Makefile.am | 27 + reactos/lib/kjs/docs/Makefile.in | 343 + reactos/lib/kjs/docs/design.texi | 112 + reactos/lib/kjs/docs/js.info | 145 + reactos/lib/kjs/docs/js.info-1 | 1886 ++++ reactos/lib/kjs/docs/js.info-2 | 1635 +++ reactos/lib/kjs/docs/js.info-3 | 1145 ++ reactos/lib/kjs/docs/js.info-4 | 383 + reactos/lib/kjs/docs/js.texi | 4885 +++++++++ reactos/lib/kjs/docs/lgpl.texinfo | 548 + reactos/lib/kjs/docs/mdate-sh | 92 + reactos/lib/kjs/docs/stamp-vti | 3 + reactos/lib/kjs/docs/texinfo.tex | 4935 +++++++++ reactos/lib/kjs/docs/version.texi | 3 + reactos/lib/kjs/examples/Makefile | 320 + reactos/lib/kjs/examples/Makefile.am | 40 + reactos/lib/kjs/examples/Makefile.in | 320 + reactos/lib/kjs/examples/add.js | 14 + reactos/lib/kjs/examples/dload.c | 60 + reactos/lib/kjs/examples/hello.js | 48 + reactos/lib/kjs/examples/ieval.c | 100 + reactos/lib/kjs/examples/obtype.js | 18 + reactos/lib/kjs/examples/simple.c | 338 + reactos/lib/kjs/include/js.h | 503 + reactos/lib/kjs/include/jsconfig.h | 190 + reactos/lib/kjs/include/jsint.h | 1783 ++++ reactos/lib/kjs/include/kjs.h | 24 + reactos/lib/kjs/include/kjs_structs.h | 44 + reactos/lib/kjs/jsas/ChangeLog | 35 + reactos/lib/kjs/jsas/Makefile | 244 + reactos/lib/kjs/jsas/Makefile.am | 51 + reactos/lib/kjs/jsas/Makefile.in | 244 + reactos/lib/kjs/jsas/jsas.js | 980 ++ reactos/lib/kjs/jsas/main.js | 212 + reactos/lib/kjs/jsas/operands.js | 472 + reactos/lib/kjs/jsas/process.js | 296 + reactos/lib/kjs/jsc/ChangeLog | 652 ++ reactos/lib/kjs/jsc/Makefile | 318 + reactos/lib/kjs/jsc/Makefile.am | 60 + reactos/lib/kjs/jsc/Makefile.in | 318 + reactos/lib/kjs/jsc/TODO | 24 + reactos/lib/kjs/jsc/asm.js | 2287 ++++ reactos/lib/kjs/jsc/bs.js | 65 + reactos/lib/kjs/jsc/compiler.js | 8221 ++++++++++++++ reactos/lib/kjs/jsc/defs.js | 178 + reactos/lib/kjs/jsc/entry.js | 206 + reactos/lib/kjs/jsc/gram.js | 2697 +++++ reactos/lib/kjs/jsc/lexer.js | 824 ++ reactos/lib/kjs/jsc/namespace.js | 161 + reactos/lib/kjs/jsc/parser.js | 1695 +++ reactos/lib/kjs/jsc/streams.js | 173 + reactos/lib/kjs/jsc/tests/ChangeLog | 11 + reactos/lib/kjs/jsc/tests/Makefile | 223 + reactos/lib/kjs/jsc/tests/Makefile.am | 28 + reactos/lib/kjs/jsc/tests/Makefile.in | 223 + reactos/lib/kjs/jsc/tests/asci.js | 44 + reactos/lib/kjs/jsc/tests/asci.test | 32 + reactos/lib/kjs/jsc/tests/compile.test | 50 + reactos/lib/kjs/jsc/tests/defs | 15 + reactos/lib/kjs/jsconfig.h.in | 167 + reactos/lib/kjs/jsdas/ChangeLog | 61 + reactos/lib/kjs/jsdas/Makefile | 290 + reactos/lib/kjs/jsdas/Makefile.am | 53 + reactos/lib/kjs/jsdas/Makefile.in | 290 + reactos/lib/kjs/jsdas/TODO | 5 + reactos/lib/kjs/jsdas/bc.js | 619 ++ reactos/lib/kjs/jsdas/extract-op-names.js | 117 + reactos/lib/kjs/jsdas/jsdas.1 | 83 + reactos/lib/kjs/jsdas/jsdas.js | 1253 +++ reactos/lib/kjs/jsdas/main.js | 398 + reactos/lib/kjs/jsdas/operands.js | 236 + reactos/lib/kjs/jswrap/ChangeLog | 13 + reactos/lib/kjs/jswrap/Makefile | 244 + reactos/lib/kjs/jswrap/Makefile.am | 51 + reactos/lib/kjs/jswrap/Makefile.in | 244 + reactos/lib/kjs/jswrap/TODO | 13 + reactos/lib/kjs/jswrap/jswrap.js | 1138 ++ reactos/lib/kjs/jswrap/main.js | 248 + reactos/lib/kjs/jswrap/process.js | 890 ++ reactos/lib/kjs/kjs.def | 11 + reactos/lib/kjs/kjs.edf | 11 + reactos/lib/kjs/kjs.rc | 37 + reactos/lib/kjs/kjsinit.js | 41 + reactos/lib/kjs/ksrc/alloc.c | 342 + reactos/lib/kjs/ksrc/b_core.c | 658 ++ reactos/lib/kjs/ksrc/b_file.c | 1024 ++ reactos/lib/kjs/ksrc/b_func.c | 78 + reactos/lib/kjs/ksrc/b_regexp.c | 1136 ++ reactos/lib/kjs/ksrc/b_system.c | 394 + reactos/lib/kjs/ksrc/bc.c | 137 + reactos/lib/kjs/ksrc/compat.c | 67 + reactos/lib/kjs/ksrc/debug.c | 171 + reactos/lib/kjs/ksrc/ejumps.h | 2244 ++++ reactos/lib/kjs/ksrc/eswitch.h | 2171 ++++ reactos/lib/kjs/ksrc/eswt0.h | 2169 ++++ reactos/lib/kjs/ksrc/iostream.c | 216 + reactos/lib/kjs/ksrc/js.c | 1472 +++ reactos/lib/kjs/ksrc/kjs.c | 53 + reactos/lib/kjs/ksrc/longjmp.S | 72 + reactos/lib/kjs/ksrc/main.c | 798 ++ reactos/lib/kjs/ksrc/mrgsort.c | 120 + reactos/lib/kjs/ksrc/object.c | 537 + reactos/lib/kjs/ksrc/regex.c | 5870 ++++++++++ reactos/lib/kjs/ksrc/setjmp.S | 59 + reactos/lib/kjs/ksrc/vm.c | 968 ++ reactos/lib/kjs/ksrc/vmjumps.c | 581 + reactos/lib/kjs/ksrc/vmswitch.c | 554 + reactos/lib/kjs/ksrc/vmswt0.c | 351 + reactos/lib/kjs/ltmain.sh | 2453 +++++ reactos/lib/kjs/makefile | 96 + reactos/lib/kjs/micros/ChangeLog | 31 + reactos/lib/kjs/micros/Makefile | 196 + reactos/lib/kjs/micros/Makefile.am | 26 + reactos/lib/kjs/micros/Makefile.in | 196 + reactos/lib/kjs/micros/README.OS2 | 6 + reactos/lib/kjs/micros/ccprops.c | 78 + reactos/lib/kjs/micros/jsconfig.os2 | 80 + reactos/lib/kjs/micros/jsconfig.w32 | 118 + reactos/lib/kjs/micros/makefile.os2 | 43 + reactos/lib/kjs/micros/makefile.w32 | 50 + reactos/lib/kjs/micros/os2.c | 55 + reactos/lib/kjs/micros/w32.c | 150 + reactos/lib/kjs/micros/w32.h | 90 + reactos/lib/kjs/projects/ChangeLog | 4 + reactos/lib/kjs/projects/Makefile | 201 + reactos/lib/kjs/projects/Makefile.am | 30 + reactos/lib/kjs/projects/Makefile.in | 201 + reactos/lib/kjs/src/ChangeLog | 1183 +++ reactos/lib/kjs/src/Makefile | 542 + reactos/lib/kjs/src/Makefile.am | 79 + reactos/lib/kjs/src/Makefile.in | 542 + reactos/lib/kjs/src/TODO | 104 + reactos/lib/kjs/src/alloc.c | 311 + reactos/lib/kjs/src/b_array.c | 650 ++ reactos/lib/kjs/src/b_bool.c | 153 + reactos/lib/kjs/src/b_core.c | 659 ++ reactos/lib/kjs/src/b_date.c | 792 ++ reactos/lib/kjs/src/b_dir.c | 319 + reactos/lib/kjs/src/b_file.c | 1012 ++ reactos/lib/kjs/src/b_func.c | 78 + reactos/lib/kjs/src/b_math.c | 511 + reactos/lib/kjs/src/b_number.c | 320 + reactos/lib/kjs/src/b_object.c | 195 + reactos/lib/kjs/src/b_regexp.c | 1136 ++ reactos/lib/kjs/src/b_string.c | 937 ++ reactos/lib/kjs/src/b_system.c | 521 + reactos/lib/kjs/src/b_vm.c | 445 + reactos/lib/kjs/src/bc.c | 224 + reactos/lib/kjs/src/c1jumps.h | 521 + reactos/lib/kjs/src/c1switch.h | 521 + reactos/lib/kjs/src/c1swt0.h | 410 + reactos/lib/kjs/src/c2jumps.h | 447 + reactos/lib/kjs/src/c2switch.h | 447 + reactos/lib/kjs/src/compiler.c | 11198 ++++++++++++++++++++ reactos/lib/kjs/src/crc32.c | 112 + reactos/lib/kjs/src/debug.c | 171 + reactos/lib/kjs/src/dl_dummy.c | 77 + reactos/lib/kjs/src/dl_open.c | 80 + reactos/lib/kjs/src/ejumps.h | 2239 ++++ reactos/lib/kjs/src/eswitch.h | 2164 ++++ reactos/lib/kjs/src/eswt0.h | 2164 ++++ reactos/lib/kjs/src/getopt.c | 1000 ++ reactos/lib/kjs/src/getopt.h | 133 + reactos/lib/kjs/src/getopt1.c | 189 + reactos/lib/kjs/src/heap.c | 586 + reactos/lib/kjs/src/iostream.c | 471 + reactos/lib/kjs/src/js.1 | 234 + reactos/lib/kjs/src/js.c | 1684 +++ reactos/lib/kjs/src/main.c | 831 ++ reactos/lib/kjs/src/make-data.c | 90 + reactos/lib/kjs/src/make-jumps.pl | 155 + reactos/lib/kjs/src/make-op-def.pl | 43 + reactos/lib/kjs/src/make-switch.pl | 150 + reactos/lib/kjs/src/make-swt0.pl | 95 + reactos/lib/kjs/src/md5.h | 96 + reactos/lib/kjs/src/md5c.c | 335 + reactos/lib/kjs/src/mrgsort.c | 119 + reactos/lib/kjs/src/mrgsort.h | 49 + reactos/lib/kjs/src/object.c | 535 + reactos/lib/kjs/src/operands.def | 2117 ++++ reactos/lib/kjs/src/r_pthrs.c | 129 + reactos/lib/kjs/src/r_std.c | 100 + reactos/lib/kjs/src/regex.c | 5862 ++++++++++ reactos/lib/kjs/src/regex.h | 572 + reactos/lib/kjs/src/rentrant.h | 52 + reactos/lib/kjs/src/utils.c | 439 + reactos/lib/kjs/src/vm.c | 968 ++ reactos/lib/kjs/src/vmjumps.c | 583 + reactos/lib/kjs/src/vmswitch.c | 554 + reactos/lib/kjs/src/vmswt0.c | 351 + reactos/lib/kjs/src/xcurses.c | 450 + reactos/lib/kjs/src/xjs.c | 460 + reactos/lib/kjs/src/xmd5.c | 222 + reactos/lib/kjs/stamp-h | 1 + reactos/lib/kjs/stamp-h.in | 1 + 215 files changed, 128469 insertions(+) create mode 100644 reactos/lib/kjs/AUTHORS create mode 100644 reactos/lib/kjs/COPYING create mode 100644 reactos/lib/kjs/ChangeLog create mode 100644 reactos/lib/kjs/INSTALL create mode 100644 reactos/lib/kjs/MODIFICATIONS create mode 100644 reactos/lib/kjs/Makefile.am create mode 100644 reactos/lib/kjs/Makefile.in create mode 100644 reactos/lib/kjs/Makefile.orig create mode 100644 reactos/lib/kjs/NEWS create mode 100644 reactos/lib/kjs/README create mode 100644 reactos/lib/kjs/THANKS create mode 100644 reactos/lib/kjs/TODO create mode 100644 reactos/lib/kjs/acconfig.h create mode 100644 reactos/lib/kjs/aclocal.m4 create mode 100644 reactos/lib/kjs/am.opt/libtool.m4 create mode 100644 reactos/lib/kjs/am/pthreads.m4 create mode 100644 reactos/lib/kjs/config.cache create mode 100644 reactos/lib/kjs/config.log create mode 100644 reactos/lib/kjs/configure.in create mode 100644 reactos/lib/kjs/docs/Makefile create mode 100644 reactos/lib/kjs/docs/Makefile.am create mode 100644 reactos/lib/kjs/docs/Makefile.in create mode 100644 reactos/lib/kjs/docs/design.texi create mode 100644 reactos/lib/kjs/docs/js.info create mode 100644 reactos/lib/kjs/docs/js.info-1 create mode 100644 reactos/lib/kjs/docs/js.info-2 create mode 100644 reactos/lib/kjs/docs/js.info-3 create mode 100644 reactos/lib/kjs/docs/js.info-4 create mode 100644 reactos/lib/kjs/docs/js.texi create mode 100644 reactos/lib/kjs/docs/lgpl.texinfo create mode 100755 reactos/lib/kjs/docs/mdate-sh create mode 100644 reactos/lib/kjs/docs/stamp-vti create mode 100644 reactos/lib/kjs/docs/texinfo.tex create mode 100644 reactos/lib/kjs/docs/version.texi create mode 100644 reactos/lib/kjs/examples/Makefile create mode 100644 reactos/lib/kjs/examples/Makefile.am create mode 100644 reactos/lib/kjs/examples/Makefile.in create mode 100644 reactos/lib/kjs/examples/add.js create mode 100644 reactos/lib/kjs/examples/dload.c create mode 100644 reactos/lib/kjs/examples/hello.js create mode 100644 reactos/lib/kjs/examples/ieval.c create mode 100644 reactos/lib/kjs/examples/obtype.js create mode 100644 reactos/lib/kjs/examples/simple.c create mode 100644 reactos/lib/kjs/include/js.h create mode 100644 reactos/lib/kjs/include/jsconfig.h create mode 100644 reactos/lib/kjs/include/jsint.h create mode 100644 reactos/lib/kjs/include/kjs.h create mode 100644 reactos/lib/kjs/include/kjs_structs.h create mode 100644 reactos/lib/kjs/jsas/ChangeLog create mode 100644 reactos/lib/kjs/jsas/Makefile create mode 100644 reactos/lib/kjs/jsas/Makefile.am create mode 100644 reactos/lib/kjs/jsas/Makefile.in create mode 100644 reactos/lib/kjs/jsas/jsas.js create mode 100644 reactos/lib/kjs/jsas/main.js create mode 100644 reactos/lib/kjs/jsas/operands.js create mode 100644 reactos/lib/kjs/jsas/process.js create mode 100644 reactos/lib/kjs/jsc/ChangeLog create mode 100644 reactos/lib/kjs/jsc/Makefile create mode 100644 reactos/lib/kjs/jsc/Makefile.am create mode 100644 reactos/lib/kjs/jsc/Makefile.in create mode 100644 reactos/lib/kjs/jsc/TODO create mode 100644 reactos/lib/kjs/jsc/asm.js create mode 100644 reactos/lib/kjs/jsc/bs.js create mode 100644 reactos/lib/kjs/jsc/compiler.js create mode 100644 reactos/lib/kjs/jsc/defs.js create mode 100644 reactos/lib/kjs/jsc/entry.js create mode 100644 reactos/lib/kjs/jsc/gram.js create mode 100644 reactos/lib/kjs/jsc/lexer.js create mode 100644 reactos/lib/kjs/jsc/namespace.js create mode 100644 reactos/lib/kjs/jsc/parser.js create mode 100644 reactos/lib/kjs/jsc/streams.js create mode 100644 reactos/lib/kjs/jsc/tests/ChangeLog create mode 100644 reactos/lib/kjs/jsc/tests/Makefile create mode 100644 reactos/lib/kjs/jsc/tests/Makefile.am create mode 100644 reactos/lib/kjs/jsc/tests/Makefile.in create mode 100644 reactos/lib/kjs/jsc/tests/asci.js create mode 100755 reactos/lib/kjs/jsc/tests/asci.test create mode 100755 reactos/lib/kjs/jsc/tests/compile.test create mode 100755 reactos/lib/kjs/jsc/tests/defs create mode 100644 reactos/lib/kjs/jsconfig.h.in create mode 100644 reactos/lib/kjs/jsdas/ChangeLog create mode 100644 reactos/lib/kjs/jsdas/Makefile create mode 100644 reactos/lib/kjs/jsdas/Makefile.am create mode 100644 reactos/lib/kjs/jsdas/Makefile.in create mode 100644 reactos/lib/kjs/jsdas/TODO create mode 100644 reactos/lib/kjs/jsdas/bc.js create mode 100755 reactos/lib/kjs/jsdas/extract-op-names.js create mode 100644 reactos/lib/kjs/jsdas/jsdas.1 create mode 100644 reactos/lib/kjs/jsdas/jsdas.js create mode 100644 reactos/lib/kjs/jsdas/main.js create mode 100644 reactos/lib/kjs/jsdas/operands.js create mode 100644 reactos/lib/kjs/jswrap/ChangeLog create mode 100644 reactos/lib/kjs/jswrap/Makefile create mode 100644 reactos/lib/kjs/jswrap/Makefile.am create mode 100644 reactos/lib/kjs/jswrap/Makefile.in create mode 100644 reactos/lib/kjs/jswrap/TODO create mode 100644 reactos/lib/kjs/jswrap/jswrap.js create mode 100644 reactos/lib/kjs/jswrap/main.js create mode 100644 reactos/lib/kjs/jswrap/process.js create mode 100644 reactos/lib/kjs/kjs.def create mode 100644 reactos/lib/kjs/kjs.edf create mode 100644 reactos/lib/kjs/kjs.rc create mode 100644 reactos/lib/kjs/kjsinit.js create mode 100644 reactos/lib/kjs/ksrc/alloc.c create mode 100644 reactos/lib/kjs/ksrc/b_core.c create mode 100644 reactos/lib/kjs/ksrc/b_file.c create mode 100644 reactos/lib/kjs/ksrc/b_func.c create mode 100644 reactos/lib/kjs/ksrc/b_regexp.c create mode 100644 reactos/lib/kjs/ksrc/b_system.c create mode 100644 reactos/lib/kjs/ksrc/bc.c create mode 100644 reactos/lib/kjs/ksrc/compat.c create mode 100644 reactos/lib/kjs/ksrc/debug.c create mode 100644 reactos/lib/kjs/ksrc/ejumps.h create mode 100644 reactos/lib/kjs/ksrc/eswitch.h create mode 100644 reactos/lib/kjs/ksrc/eswt0.h create mode 100644 reactos/lib/kjs/ksrc/iostream.c create mode 100644 reactos/lib/kjs/ksrc/js.c create mode 100644 reactos/lib/kjs/ksrc/kjs.c create mode 100644 reactos/lib/kjs/ksrc/longjmp.S create mode 100644 reactos/lib/kjs/ksrc/main.c create mode 100644 reactos/lib/kjs/ksrc/mrgsort.c create mode 100644 reactos/lib/kjs/ksrc/object.c create mode 100644 reactos/lib/kjs/ksrc/regex.c create mode 100644 reactos/lib/kjs/ksrc/setjmp.S create mode 100644 reactos/lib/kjs/ksrc/vm.c create mode 100644 reactos/lib/kjs/ksrc/vmjumps.c create mode 100644 reactos/lib/kjs/ksrc/vmswitch.c create mode 100644 reactos/lib/kjs/ksrc/vmswt0.c create mode 100644 reactos/lib/kjs/ltmain.sh create mode 100644 reactos/lib/kjs/makefile create mode 100644 reactos/lib/kjs/micros/ChangeLog create mode 100644 reactos/lib/kjs/micros/Makefile create mode 100644 reactos/lib/kjs/micros/Makefile.am create mode 100644 reactos/lib/kjs/micros/Makefile.in create mode 100644 reactos/lib/kjs/micros/README.OS2 create mode 100644 reactos/lib/kjs/micros/ccprops.c create mode 100644 reactos/lib/kjs/micros/jsconfig.os2 create mode 100644 reactos/lib/kjs/micros/jsconfig.w32 create mode 100644 reactos/lib/kjs/micros/makefile.os2 create mode 100644 reactos/lib/kjs/micros/makefile.w32 create mode 100644 reactos/lib/kjs/micros/os2.c create mode 100644 reactos/lib/kjs/micros/w32.c create mode 100644 reactos/lib/kjs/micros/w32.h create mode 100644 reactos/lib/kjs/projects/ChangeLog create mode 100644 reactos/lib/kjs/projects/Makefile create mode 100644 reactos/lib/kjs/projects/Makefile.am create mode 100644 reactos/lib/kjs/projects/Makefile.in create mode 100644 reactos/lib/kjs/src/ChangeLog create mode 100644 reactos/lib/kjs/src/Makefile create mode 100644 reactos/lib/kjs/src/Makefile.am create mode 100644 reactos/lib/kjs/src/Makefile.in create mode 100644 reactos/lib/kjs/src/TODO create mode 100644 reactos/lib/kjs/src/alloc.c create mode 100644 reactos/lib/kjs/src/b_array.c create mode 100644 reactos/lib/kjs/src/b_bool.c create mode 100644 reactos/lib/kjs/src/b_core.c create mode 100644 reactos/lib/kjs/src/b_date.c create mode 100644 reactos/lib/kjs/src/b_dir.c create mode 100644 reactos/lib/kjs/src/b_file.c create mode 100644 reactos/lib/kjs/src/b_func.c create mode 100644 reactos/lib/kjs/src/b_math.c create mode 100644 reactos/lib/kjs/src/b_number.c create mode 100644 reactos/lib/kjs/src/b_object.c create mode 100644 reactos/lib/kjs/src/b_regexp.c create mode 100644 reactos/lib/kjs/src/b_string.c create mode 100644 reactos/lib/kjs/src/b_system.c create mode 100644 reactos/lib/kjs/src/b_vm.c create mode 100644 reactos/lib/kjs/src/bc.c create mode 100644 reactos/lib/kjs/src/c1jumps.h create mode 100644 reactos/lib/kjs/src/c1switch.h create mode 100644 reactos/lib/kjs/src/c1swt0.h create mode 100644 reactos/lib/kjs/src/c2jumps.h create mode 100644 reactos/lib/kjs/src/c2switch.h create mode 100644 reactos/lib/kjs/src/compiler.c create mode 100644 reactos/lib/kjs/src/crc32.c create mode 100644 reactos/lib/kjs/src/debug.c create mode 100644 reactos/lib/kjs/src/dl_dummy.c create mode 100644 reactos/lib/kjs/src/dl_open.c create mode 100644 reactos/lib/kjs/src/ejumps.h create mode 100644 reactos/lib/kjs/src/eswitch.h create mode 100644 reactos/lib/kjs/src/eswt0.h create mode 100644 reactos/lib/kjs/src/getopt.c create mode 100644 reactos/lib/kjs/src/getopt.h create mode 100644 reactos/lib/kjs/src/getopt1.c create mode 100644 reactos/lib/kjs/src/heap.c create mode 100644 reactos/lib/kjs/src/iostream.c create mode 100644 reactos/lib/kjs/src/js.1 create mode 100644 reactos/lib/kjs/src/js.c create mode 100644 reactos/lib/kjs/src/main.c create mode 100644 reactos/lib/kjs/src/make-data.c create mode 100755 reactos/lib/kjs/src/make-jumps.pl create mode 100755 reactos/lib/kjs/src/make-op-def.pl create mode 100755 reactos/lib/kjs/src/make-switch.pl create mode 100755 reactos/lib/kjs/src/make-swt0.pl create mode 100644 reactos/lib/kjs/src/md5.h create mode 100644 reactos/lib/kjs/src/md5c.c create mode 100644 reactos/lib/kjs/src/mrgsort.c create mode 100644 reactos/lib/kjs/src/mrgsort.h create mode 100644 reactos/lib/kjs/src/object.c create mode 100644 reactos/lib/kjs/src/operands.def create mode 100644 reactos/lib/kjs/src/r_pthrs.c create mode 100644 reactos/lib/kjs/src/r_std.c create mode 100644 reactos/lib/kjs/src/regex.c create mode 100644 reactos/lib/kjs/src/regex.h create mode 100644 reactos/lib/kjs/src/rentrant.h create mode 100644 reactos/lib/kjs/src/utils.c create mode 100644 reactos/lib/kjs/src/vm.c create mode 100644 reactos/lib/kjs/src/vmjumps.c create mode 100644 reactos/lib/kjs/src/vmswitch.c create mode 100644 reactos/lib/kjs/src/vmswt0.c create mode 100644 reactos/lib/kjs/src/xcurses.c create mode 100644 reactos/lib/kjs/src/xjs.c create mode 100644 reactos/lib/kjs/src/xmd5.c create mode 100644 reactos/lib/kjs/stamp-h create mode 100644 reactos/lib/kjs/stamp-h.in diff --git a/reactos/lib/kjs/AUTHORS b/reactos/lib/kjs/AUTHORS new file mode 100644 index 00000000000..5ce46ebe1e7 --- /dev/null +++ b/reactos/lib/kjs/AUTHORS @@ -0,0 +1,4 @@ + + Authors of the NGS JavaScript Interpreter + +Markku Rossi diff --git a/reactos/lib/kjs/COPYING b/reactos/lib/kjs/COPYING new file mode 100644 index 00000000000..161a3d1d47b --- /dev/null +++ b/reactos/lib/kjs/COPYING @@ -0,0 +1,482 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/reactos/lib/kjs/ChangeLog b/reactos/lib/kjs/ChangeLog new file mode 100644 index 00000000000..c297bae70aa --- /dev/null +++ b/reactos/lib/kjs/ChangeLog @@ -0,0 +1,112 @@ +1999-01-15 Markku Rossi + + * configure.in: Added AC_FUNC_ALLOCA. + +1999-01-12 Markku Rossi + + * configure.in (with_dload_val): Added check for the dlfcn.h + header file. + +1998-10-20 Markku Rossi + + * Version 0.2.4 released. + +1998-10-02 Markku Rossi + + * configure.in: New configure option --enable-operand-hooks to + enable the byte-code operand hooks. + +1998-09-17 Markku Rossi + + * configure.in: Fixed the --with-pthreads to resolve the compiler + and its options which are needed when compiling thread + applications. The thread checks are defined in `am/pthreads.m4' + file. + +1998-09-07 Markku Rossi + + * Version 0.2.2 released. + +1998-08-24 Markku Rossi + + * Version 0.2.1 released. + +1998-08-17 Markku Rossi + + * configure.in: Added check for struct_st.st_blksize. + +1998-08-12 Markku Rossi + + * configure.in: New option --disable-jumps to unconditionally + disable the `jumps' byte-code instruction dispatch method. + +1998-08-10 Markku Rossi + + * configure.in: Changed to use libtool for libraries. Now the + libjs can be built to a shared library. + +1998-08-04 Markku Rossi + + * Added `projects' subdirectory to hold JS related work and + contributions. + +1998-07-06 Markku Rossi + + * Changed the license to GNU Library General Public License LGPL. + + * Version 0.2.0 released. + +1998-06-26 Markku Rossi + + * configure.in: New option --enable-profiling to enable byte-code + operand profiling. + Renamed --with-all-dispatchers to --enable-all-dispatchers. + +1998-06-25 Markku Rossi + + * Added jsas directory for the JavaScript assembler. + +1998-06-09 Markku Rossi + + * Version 0.1.2 released. + +1998-06-02 Markku Rossi + + * configure.in: New options --without-js and --without-md5 to + undefine the JS and MD5 extensions. + Added check for the lstat() function that is not present on + djgpp/Windows 95. + Added check for struct stat's st_blocks member. That is not + present on djgpp/windows 95. + Thanks to Dave Pearson for the + djgpp/Window95 notes. + Added checks for some pthread differences. + +1998-05-29 Markku Rossi + + * Version 0.1.1 released. + +1998-05-25 Markku Rossi + + * Version 0.1.0 released. + +1998-04-07 Markku Rossi + + * Version 0.0.2 frozen. + +1998-04-02 Markku Rossi + + * configure.in: New option --with-all-dispatchers to enable all + byte-code instruction dispatchers. + +1998-03-30 Markku Rossi + + * Added micros directory for micro ports. + +1998-02-27 Markku Rossi + + * Added dasm and docs directories to the project. + +1998-02-23 Markku Rossi + + * Started to use auto{make,conf} in the project. diff --git a/reactos/lib/kjs/INSTALL b/reactos/lib/kjs/INSTALL new file mode 100644 index 00000000000..50dbe439d09 --- /dev/null +++ b/reactos/lib/kjs/INSTALL @@ -0,0 +1,183 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. + diff --git a/reactos/lib/kjs/MODIFICATIONS b/reactos/lib/kjs/MODIFICATIONS new file mode 100644 index 00000000000..6d0cb86843f --- /dev/null +++ b/reactos/lib/kjs/MODIFICATIONS @@ -0,0 +1,6 @@ +This interpreter has been modified for use in the ReactOS kernel as a +debugging aid. The original files are available in the src directory, +and modified files are in the ksrc directory. + +The file jsconfig.h which is normally automatically generated has been +hand generated here. \ No newline at end of file diff --git a/reactos/lib/kjs/Makefile.am b/reactos/lib/kjs/Makefile.am new file mode 100644 index 00000000000..7679bfac800 --- /dev/null +++ b/reactos/lib/kjs/Makefile.am @@ -0,0 +1,35 @@ +# +# Automakefile for JS interpreter. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + +SUBDIRS = src jsc jsas jsdas jswrap docs micros examples projects + +include_HEADERS = jsconfig.h + +ACLOCAL_AMFLAGS = -I $(srcdir)/am @ACLOCAL_FLAGS_FOR_LIBTOOL@ + +dist-hook: + mkdir $(distdir)/am + cp -p $(srcdir)/am/pthreads.m4 $(distdir)/am/pthreads.m4 + mkdir $(distdir)/am.opt + cp -p $(srcdir)/am.opt/libtool.m4 $(distdir)/am.opt/libtool.m4 diff --git a/reactos/lib/kjs/Makefile.in b/reactos/lib/kjs/Makefile.in new file mode 100644 index 00000000000..1ebdc788379 --- /dev/null +++ b/reactos/lib/kjs/Makefile.in @@ -0,0 +1,384 @@ +# Makefile.in generated automatically by automake 1.3 from Makefile.am + +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Automakefile for JS interpreter. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + + +SHELL = /bin/sh + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DISTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = . + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_FLAGS_FOR_LIBTOOL = @ACLOCAL_FLAGS_FOR_LIBTOOL@ +CC = @CC@ +CPP = @CPP@ +EXTENSIONS = @EXTENSIONS@ +EXTENSIONS_LIBS = @EXTENSIONS_LIBS@ +INTERPRETER_FEATURES = @INTERPRETER_FEATURES@ +LD = @LD@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +NM = @NM@ +PACKAGE = @PACKAGE@ +PGCC_BY_PROVENZANO = @PGCC_BY_PROVENZANO@ +RANLIB = @RANLIB@ +U = @U@ +VERSION = @VERSION@ +XLC_R_AIX = @XLC_R_AIX@ + +SUBDIRS = src jsc jsas jsdas jswrap docs micros examples projects + +include_HEADERS = jsconfig.h + +ACLOCAL_AMFLAGS = -I $(srcdir)/am @ACLOCAL_FLAGS_FOR_LIBTOOL@ +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = jsconfig.h +CONFIG_CLEAN_FILES = +HEADERS = $(include_HEADERS) + +DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \ +Makefile.in NEWS THANKS TODO acconfig.h aclocal.m4 config.guess \ +config.sub configure configure.in install-sh jsconfig.h.in ltconfig \ +ltmain.sh missing mkinstalldirs stamp-h.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP = --best +all: all-recursive-am all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +$(ACLOCAL_M4): configure.in + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) + +config.status: $(srcdir)/configure + $(SHELL) ./config.status --recheck +$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +jsconfig.h: stamp-h + @: +stamp-h: $(srcdir)/jsconfig.h.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES= CONFIG_HEADERS=jsconfig.h \ + $(SHELL) ./config.status + @echo timestamp > stamp-h +$(srcdir)/jsconfig.h.in: $(srcdir)/stamp-h.in +$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h + cd $(top_srcdir) && $(AUTOHEADER) + @echo timestamp > $(srcdir)/stamp-h.in + +mostlyclean-hdr: + +clean-hdr: + +distclean-hdr: + -rm -f jsconfig.h + +maintainer-clean-hdr: + +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(includedir) + @list='$(include_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + list='$(include_HEADERS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(includedir)/$$p; \ + done + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. + +@SET_MAKE@ + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + target=`echo $@ | sed s/-recursive//`; \ + echo "Making $$target in $$subdir"; \ + (cd $$subdir && $(MAKE) $$target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + done; \ + for subdir in $$rev; do \ + target=`echo $@ | sed s/-recursive//`; \ + echo "Making $$target in $$subdir"; \ + (cd $$subdir && $(MAKE) $$target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + (cd $$subdir && $(MAKE) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) jsconfig.h.in $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)jsconfig.h.in$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags jsconfig.h.in $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + -rm -rf $(distdir) + GZIP=$(GZIP) $(TAR) zxf $(distdir).tar.gz + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + dc_install_base=`cd $(distdir)/=inst && pwd`; \ + cd $(distdir)/=build \ + && ../configure --srcdir=.. --prefix=$$dc_install_base \ + && $(MAKE) \ + && $(MAKE) dvi \ + && $(MAKE) check \ + && $(MAKE) install \ + && $(MAKE) installcheck \ + && $(MAKE) dist + -rm -rf $(distdir) + @echo "========================"; \ + echo "$(distdir).tar.gz is ready for distribution"; \ + echo "========================" +dist: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +dist-all: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +distdir: $(DISTFILES) + -rm -rf $(distdir) + mkdir $(distdir) + -chmod 777 $(distdir) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done + for subdir in $(SUBDIRS); do \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + done + $(MAKE) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook +info: info-recursive +dvi: dvi-recursive +check: all-am + $(MAKE) check-recursive +installcheck: installcheck-recursive +all-recursive-am: jsconfig.h + $(MAKE) all-recursive + +all-am: Makefile $(HEADERS) jsconfig.h + +install-data-am: install-includeHEADERS + +uninstall-am: uninstall-includeHEADERS + +install-exec: install-exec-recursive + @$(NORMAL_INSTALL) + +install-data: install-data-recursive install-data-am + @$(NORMAL_INSTALL) + +install: install-recursive install-data-am + @: + +uninstall: uninstall-recursive uninstall-am + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: installdirs-recursive + $(mkinstalldirs) $(DATADIR)$(includedir) + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean-am: mostlyclean-hdr mostlyclean-tags mostlyclean-generic + +clean-am: clean-hdr clean-tags clean-generic mostlyclean-am + +distclean-am: distclean-hdr distclean-tags distclean-generic clean-am + +maintainer-clean-am: maintainer-clean-hdr maintainer-clean-tags \ + maintainer-clean-generic distclean-am + +mostlyclean: mostlyclean-recursive mostlyclean-am + +clean: clean-recursive clean-am + +distclean: distclean-recursive distclean-am + -rm -f config.status + -rm -f libtool + +maintainer-clean: maintainer-clean-recursive maintainer-clean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + -rm -f config.status + +.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \ +uninstall-includeHEADERS install-includeHEADERS install-data-recursive \ +uninstall-data-recursive install-exec-recursive \ +uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \ +all-recursive check-recursive installcheck-recursive info-recursive \ +dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info dvi \ +installcheck all-recursive-am all-am install-data-am uninstall-am \ +install-exec install-data install uninstall all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +dist-hook: + mkdir $(distdir)/am + cp -p $(srcdir)/am/pthreads.m4 $(distdir)/am/pthreads.m4 + mkdir $(distdir)/am.opt + cp -p $(srcdir)/am.opt/libtool.m4 $(distdir)/am.opt/libtool.m4 + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/reactos/lib/kjs/Makefile.orig b/reactos/lib/kjs/Makefile.orig new file mode 100644 index 00000000000..2aa684c87a0 --- /dev/null +++ b/reactos/lib/kjs/Makefile.orig @@ -0,0 +1,384 @@ +# Generated automatically from Makefile.in by configure. +# Makefile.in generated automatically by automake 1.3 from Makefile.am + +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Automakefile for JS interpreter. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + + +SHELL = /bin/sh + +srcdir = . +top_srcdir = . +prefix = /usr/local/js-0.2.5 +exec_prefix = ${prefix} + +bindir = ${exec_prefix}/bin +sbindir = ${exec_prefix}/sbin +libexecdir = ${exec_prefix}/libexec +datadir = ${prefix}/share +sysconfdir = ${prefix}/etc +sharedstatedir = ${prefix}/com +localstatedir = ${prefix}/var +libdir = ${exec_prefix}/lib +infodir = ${prefix}/info +mandir = ${prefix}/man +includedir = ${prefix}/include +oldincludedir = /usr/include + +DISTDIR = + +pkgdatadir = $(datadir)/js +pkglibdir = $(libdir)/js +pkgincludedir = $(includedir)/js + +top_builddir = . + +ACLOCAL = aclocal +AUTOCONF = autoconf +AUTOMAKE = automake +AUTOHEADER = autoheader + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} +transform = s,x,x, + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = i686-pc-linux-gnu +host_triplet = i686-pc-linux-gnu +ACLOCAL_FLAGS_FOR_LIBTOOL = +CC = gcc +CPP = gcc -E +EXTENSIONS = dl_open.lo xjs.lo xmd5.lo md5c.lo +EXTENSIONS_LIBS = -ldl +INTERPRETER_FEATURES = r_std.lo +LD = /usr/bin/ld +LIBTOOL = $(SHELL) $(top_builddir)/libtool +LN_S = ln -s +MAKEINFO = makeinfo +NM = /usr/bin/nm -B +PACKAGE = js +PGCC_BY_PROVENZANO = +RANLIB = ranlib +U = +VERSION = 0.2.5 +XLC_R_AIX = + +SUBDIRS = src jsc jsas jsdas jswrap docs micros examples projects + +include_HEADERS = jsconfig.h + +ACLOCAL_AMFLAGS = -I $(srcdir)/am +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = jsconfig.h +CONFIG_CLEAN_FILES = +HEADERS = $(include_HEADERS) + +DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \ +Makefile.in NEWS THANKS TODO acconfig.h aclocal.m4 config.guess \ +config.sub configure configure.in install-sh jsconfig.h.in ltconfig \ +ltmain.sh missing mkinstalldirs stamp-h.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP = --best +all: all-recursive-am all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +$(ACLOCAL_M4): configure.in + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) + +config.status: $(srcdir)/configure + $(SHELL) ./config.status --recheck +$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +jsconfig.h: stamp-h + @: +stamp-h: $(srcdir)/jsconfig.h.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES= CONFIG_HEADERS=jsconfig.h \ + $(SHELL) ./config.status + @echo timestamp > stamp-h +$(srcdir)/jsconfig.h.in: $(srcdir)/stamp-h.in +$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h + cd $(top_srcdir) && $(AUTOHEADER) + @echo timestamp > $(srcdir)/stamp-h.in + +mostlyclean-hdr: + +clean-hdr: + +distclean-hdr: + -rm -f jsconfig.h + +maintainer-clean-hdr: + +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(includedir) + @list='$(include_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + list='$(include_HEADERS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(includedir)/$$p; \ + done + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. + + + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + target=`echo $@ | sed s/-recursive//`; \ + echo "Making $$target in $$subdir"; \ + (cd $$subdir && $(MAKE) $$target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + done; \ + for subdir in $$rev; do \ + target=`echo $@ | sed s/-recursive//`; \ + echo "Making $$target in $$subdir"; \ + (cd $$subdir && $(MAKE) $$target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + (cd $$subdir && $(MAKE) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) jsconfig.h.in $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)jsconfig.h.in$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags jsconfig.h.in $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + -rm -rf $(distdir) + GZIP=$(GZIP) $(TAR) zxf $(distdir).tar.gz + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + dc_install_base=`cd $(distdir)/=inst && pwd`; \ + cd $(distdir)/=build \ + && ../configure --srcdir=.. --prefix=$$dc_install_base \ + && $(MAKE) \ + && $(MAKE) dvi \ + && $(MAKE) check \ + && $(MAKE) install \ + && $(MAKE) installcheck \ + && $(MAKE) dist + -rm -rf $(distdir) + @echo "========================"; \ + echo "$(distdir).tar.gz is ready for distribution"; \ + echo "========================" +dist: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +dist-all: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +distdir: $(DISTFILES) + -rm -rf $(distdir) + mkdir $(distdir) + -chmod 777 $(distdir) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done + for subdir in $(SUBDIRS); do \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + done + $(MAKE) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook +info: info-recursive +dvi: dvi-recursive +check: all-am + $(MAKE) check-recursive +installcheck: installcheck-recursive +all-recursive-am: jsconfig.h + $(MAKE) all-recursive + +all-am: Makefile $(HEADERS) jsconfig.h + +install-data-am: install-includeHEADERS + +uninstall-am: uninstall-includeHEADERS + +install-exec: install-exec-recursive + @$(NORMAL_INSTALL) + +install-data: install-data-recursive install-data-am + @$(NORMAL_INSTALL) + +install: install-recursive install-data-am + @: + +uninstall: uninstall-recursive uninstall-am + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: installdirs-recursive + $(mkinstalldirs) $(DATADIR)$(includedir) + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean-am: mostlyclean-hdr mostlyclean-tags mostlyclean-generic + +clean-am: clean-hdr clean-tags clean-generic mostlyclean-am + +distclean-am: distclean-hdr distclean-tags distclean-generic clean-am + +maintainer-clean-am: maintainer-clean-hdr maintainer-clean-tags \ + maintainer-clean-generic distclean-am + +mostlyclean: mostlyclean-recursive mostlyclean-am + +clean: clean-recursive clean-am + +distclean: distclean-recursive distclean-am + -rm -f config.status + -rm -f libtool + +maintainer-clean: maintainer-clean-recursive maintainer-clean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + -rm -f config.status + +.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \ +uninstall-includeHEADERS install-includeHEADERS install-data-recursive \ +uninstall-data-recursive install-exec-recursive \ +uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \ +all-recursive check-recursive installcheck-recursive info-recursive \ +dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info dvi \ +installcheck all-recursive-am all-am install-data-am uninstall-am \ +install-exec install-data install uninstall all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +dist-hook: + mkdir $(distdir)/am + cp -p $(srcdir)/am/pthreads.m4 $(distdir)/am/pthreads.m4 + mkdir $(distdir)/am.opt + cp -p $(srcdir)/am.opt/libtool.m4 $(distdir)/am.opt/libtool.m4 + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/reactos/lib/kjs/NEWS b/reactos/lib/kjs/NEWS new file mode 100644 index 00000000000..6b07a105172 --- /dev/null +++ b/reactos/lib/kjs/NEWS @@ -0,0 +1,131 @@ + + What's new in the NGS JavaScript Interpreter + ============================================ + +Noteworthy changes in js-0.2.5: + + - Implemented nested function declarations, e.g. function + declarations as statements. + - Ported to 64 bit Alpha chip. + + +Noteworthy changes in js-0.2.4: + + - Security options for the virtual machine to disable insecure + methods from the File and System built-in objects. + - New global method `print()' that prints its arguments to the + system's standard output stream. + - User-definable event hooks. + - New built-in object `Directory' to access directories. + - ECMAScript compatibility fixes in: built-in objects, byte-code + operands, compiler + - Optimizations in the memory usage. + - Simple constant folding optimization for additive expressions. + - JavaScript assembler `jsas'. + - Many bug fixes. + + +Noteworthy changes in js-0.2.3: + +* Misc + + - ECMAScript compatibility fixes in: built-in objects, byte-code + operands, compiler + - fixed the configure option `--with-pthreads' to resolve the system + features + + +Noteworthy changes in js-0.2.2: + +* Misc + + - js.h API changes + - better ECMAScript support + +* JSC + + - do Statement while (Expression); + - switch (Expression) CaseBlock + - try statement (ECMAScript compatible) + - labeled statements + - the continue and break statements now support the labeled + statements + - local variable declarations in for statements + - \xHH and \uHHHH escape sequences in string and regular expression + literals + - strict equals and does-not-equal operators + - the `arguments' property of function instance + - optimizations and code cleanups + + +Noteworthy changes in js-0.2.1: + +* New methods: + +** global methods + + - callMethod() to call methods from objects with given array of + arguments. + - loadClass() extend the interpreter by calling extension entry + functions from shared libraries. + +** File + + - chmod() change permissions of a file + +** Number + + - constructor `new Number()' + - global method `Number()' invocation + +* The `js' program + + - new option -x, --executable to add execute permissions to the + generated byte-code files + - new warning options: -Wmissing-semicolon, -Wstrict-ecma, -Wpedantic + +* js.h API changes + +* Misc + + - Uses libtool for libraries. Now the libjs can be built to a + shared library. + - New utility program `jswrap' to create C functions that are + implemented in JavaScript. + - Automatic semicolon insertion. + - Support for regular expression literals. + - Support for array initializers. + - updates in the byte-code operands + - new configure option `--disable-jumps' to uncoditionally disable + the `jumps' byte-code instruction dispatch method + - ported to Windows 9x/NT + + +Noteworthy changes in js-0.2.0: + +* The license was changed to GNU Library General Public License LGPL. + +* JSC + + - Implemented 'foo'-strings. The character constants are now + written as #'a'. + - Implemented the mod operand. + +* Implemented the prototype properties for objects. + +* Implemented the prototype properties for built-in objects. Now you + can define your own properties for built-in objects. + +* Major cleanups in the memory management: + + - The interpreter will not exit if memory allocations fail. + - Fixed all known memory leaks. + - Optimized the heap freelist handling. This reduces the memory + consumption noticeably. + +* Namespace cleanups. + +* Documentation updates. + +* Bug fixes and feature updates. Please, see the ChangeLogs for the + details. diff --git a/reactos/lib/kjs/README b/reactos/lib/kjs/README new file mode 100644 index 00000000000..faecf0878fd --- /dev/null +++ b/reactos/lib/kjs/README @@ -0,0 +1,69 @@ + + NGS JavaScript Interpreter + ========================== + +Welcome to the NGS JavaScript interpreter. The NGS JavaScript is a +GPL free interpreter for the JavaScript language. The JavaScript +language is an interpreted C-like language, developed by Netscape et +al. + +The NGS JavaScript interpreter 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 + + +* Design Goals + +This implementation is not 100% compatible with the JavaScript +language, found from the Netscape's WWW browsers and servers. To +achieve the following design goals, some shortcuts have been taken in +the implementation, as compared to the Netscape's implementation. + +This implementation is designed to be: + +- re-entrant + + the interpreter can be safely used in multi-threaded environments + +- extendible + + the interpreter API allows user-defined commands and classes, and it + allows reading and setting language's global variables + +- fast + + the JavaScript code is compiled to byte-code that is executed by a + virtual machine + +- programmable + + it should be easy to implement large projects with the language + + +* WWW Home Page and Additional Information + +The WWW home page of the NGS JavaScript interpreter is at URL: + + http://www.ngs.fi/js/ + +The home page contains up-to-date information about the interpreter, +its development, releases, documentation, etc. + +Please note that the current version, js-0.2.0 is a work in progress. +It contains bugs and many features are still unimplemented. + +Comments, suggestions, bug reports and fixes, feature wishes, etc. are +welcome. + + Markku Rossi diff --git a/reactos/lib/kjs/THANKS b/reactos/lib/kjs/THANKS new file mode 100644 index 00000000000..19231296bb8 --- /dev/null +++ b/reactos/lib/kjs/THANKS @@ -0,0 +1,7 @@ +Roger E Critchlow Jr +Dmitry M. Golubovsky +Stephan Kulow +Torben Weis +Eric W. Sink +Paul Rohr +Indrek Mandre diff --git a/reactos/lib/kjs/TODO b/reactos/lib/kjs/TODO new file mode 100644 index 00000000000..d63c6b51d06 --- /dev/null +++ b/reactos/lib/kjs/TODO @@ -0,0 +1,13 @@ + + TODO JavaScript + +* Debugger + +* Package builder that would ease the pain of creating stubs for + extensions. Something similar that perl has for its extensions. As + an initial application, implement GTK package. + + ... or try SWIG: www.swig.org + +* Implement a JSTokenized in C. That would speed up the parsing + noticeably. \ No newline at end of file diff --git a/reactos/lib/kjs/acconfig.h b/reactos/lib/kjs/acconfig.h new file mode 100644 index 00000000000..44aa250a3b8 --- /dev/null +++ b/reactos/lib/kjs/acconfig.h @@ -0,0 +1,76 @@ +/* + * Define the PACKAGE and VERSION only if they are undefined. This means + * that we do not redefine them, when the library is used in another + * GNU like package that defines PACKAGE and VERSION. + */ + +/* Package name. */ +#ifndef PACKAGE +#undef PACKAGE +#endif /* no PACKAGE */ + +/* Version number. */ +#ifndef VERSION +#undef VERSION +#endif /* no VERSION */ + +/* Are C prototypes supported. */ +#undef PROTOTYPES + +/* Canonical host name and its parts. */ +#undef CANONICAL_HOST +#undef CANONICAL_HOST_CPU +#undef CANONICAL_HOST_VENDOR +#undef CANONICAL_HOST_OS + +/* Do we want to build all instruction dispatchers? */ +#undef ALL_DISPATCHERS + +/* Do we want to profile byte-code operands. */ +#undef PROFILING + +/* Do we want the byte-code operand hooks. */ +#undef BC_OPERAND_HOOKS + +/* + * Unconditionall disable the jumps byte-code instruction dispatch + * method. + */ +#undef DISABLE_JUMPS + +/* Does the struct stat has st_blksize member? */ +#undef HAVE_STAT_ST_ST_BLKSIZE + +/* Does the struct stat has st_blocks member? */ +#undef HAVE_STAT_ST_ST_BLOCKS + + +/* + * Posix threads features. + */ + +/* Does the asctime_r() function take three arguments. */ +#undef ASCTIME_R_WITH_THREE_ARGS + +/* Does the drand48_r() work with DRAND48D data. */ +#undef DRAND48_R_WITH_DRAND48D + +/* How the attribute structures are passed to the init functions. */ +#undef CONDATTR_BY_VALUE +#undef MUTEXATTR_BY_VALUE +#undef THREADATTR_BY_VALUE + +/* + * Extensions. + */ + +/* JS */ +#undef WITH_JS + +/* Curses. */ +#undef WITH_CURSES +#undef HAVE_CURSES_H +#undef HAVE_NCURSES_H + +/* MD5 */ +#undef WITH_MD5 diff --git a/reactos/lib/kjs/aclocal.m4 b/reactos/lib/kjs/aclocal.m4 new file mode 100644 index 00000000000..258c310b88a --- /dev/null +++ b/reactos/lib/kjs/aclocal.m4 @@ -0,0 +1,664 @@ +dnl aclocal.m4 generated automatically by aclocal 1.3 + +dnl Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +dnl This Makefile.in is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + +# Do all the work for Automake. This macro actually does too much -- +# some checks are only needed if your package does certain things. +# But this isn't really a big deal. + +# serial 1 + +dnl Usage: +dnl AM_INIT_AUTOMAKE(package,version, [no-define]) + +AC_DEFUN(AM_INIT_AUTOMAKE, +[AC_REQUIRE([AM_PROG_INSTALL]) +PACKAGE=[$1] +AC_SUBST(PACKAGE) +VERSION=[$2] +AC_SUBST(VERSION) +dnl test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi +ifelse([$3],, +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE") +AC_DEFINE_UNQUOTED(VERSION, "$VERSION")) +AC_REQUIRE([AM_SANITY_CHECK]) +AC_REQUIRE([AC_ARG_PROGRAM]) +dnl FIXME This is truly gross. +missing_dir=`cd $ac_aux_dir && pwd` +AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) +AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) +AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) +AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) +AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) +AC_REQUIRE([AC_PROG_MAKE_SET])]) + + +# serial 1 + +AC_DEFUN(AM_PROG_INSTALL, +[AC_REQUIRE([AC_PROG_INSTALL]) +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' +AC_SUBST(INSTALL_SCRIPT)dnl +]) + +# +# Check to make sure that the build environment is sane. +# + +AC_DEFUN(AM_SANITY_CHECK, +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "[$]*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "[$]*" != "X $srcdir/configure conftestfile" \ + && test "[$]*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "[$]2" = conftestfile + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +rm -f conftest* +AC_MSG_RESULT(yes)]) + +dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) +dnl The program must properly implement --version. +AC_DEFUN(AM_MISSING_PROG, +[AC_MSG_CHECKING(for working $2) +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if ($2 --version) < /dev/null > /dev/null 2>&1; then + $1=$2 + AC_MSG_RESULT(found) +else + $1="$3/missing $2" + AC_MSG_RESULT(missing) +fi +AC_SUBST($1)]) + +# Like AC_CONFIG_HEADER, but automatically create stamp file. + +AC_DEFUN(AM_CONFIG_HEADER, +[AC_PREREQ([2.12]) +AC_CONFIG_HEADER([$1]) +dnl When config.status generates a header, we must update the stamp-h file. +dnl This file resides in the same directory as the config header +dnl that is generated. We must strip everything past the first ":", +dnl and everything past the last "/". +AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl +ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>, +<>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>, +<>; do + case " <<$>>CONFIG_HEADERS " in + *" <<$>>am_file "*<<)>> + echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx + ;; + esac + am_indx=`expr "<<$>>am_indx" + 1` +done<<>>dnl>>) +changequote([,]))]) + +# +# Resolve how to compile Posix thread programs. +# + +# serial 1 + +AC_DEFUN(AM_POSIX_THREADS, +[ +# +# First, check the easily recognizable compilers. +# +AC_CANONICAL_HOST + +# pgcc, pthreads gcc by Chris Provenzano +AC_CHECK_PROG(PGCC_BY_PROVENZANO, pgcc, yes, no) + +if test "$PGCC_BY_PROVENZANO" = "yes"; then + CC='pgcc' + CFLAGS="$CFLAGS -g -Wall -Wno-unused" + LDFLAGS="$LDFLAGS -g" +fi + +if test "X$CC" = "X"; then + # xlc_r, thread safe C compiler for AIX + AC_CHECK_PROG(XLC_R_AIX, xlc_r, yes, no) + + if test "$XLC_R_AIX" = "yes"; then + CC='xlc_r' + CFLAGS='-I/usr/local/include -g' + LDFLAGS="$LDFLAGS -L/usr/local/lib -g" + fi +fi + +AC_ARG_WITH(cc, +[ --with-cc(=CC) use system's native compiler or compiler CC], + if test "X$withval" != "Xno"; then + if test "X$withval" = "Xyes"; then + CC='cc' + else + CC=$withval + fi + CFLAGS='-I/usr/local/include' + LDFLAGS="$LDFLAGS -L/usr/local/lib" + echo "using compiler CC=$CC" + fi +) + +if test "X$CC" = "X"; then + # Ok, not an easy compiler, let's try our knowledge-base + AC_PROG_CC + case "$host" in + *solaris2.5* ) + if test -n "$GCC"; then + CFLAGS="$CFLAGS -D_REENTRANT" + else + CFLAGS="$CFLAGS -threads" + fi + ;; + *osf* ) + if test -n "$GCC"; then + AC_WARN(don't know how to make gcc thread-aware, using cc) + CC='cc' + CFLAGS="$CFLAGS -threads" + else + CFLAGS=="$CFLAGS -threads" + fi + ;; + *aix4* ) + if test -n "$GCC"; then + CFLAGS="$CFLAGS -D_REENTRANT" + LDFLAGS="$LDFLAGS -L/usr/lib/threads -nostartfiles /lib/crt0_r.o -lc_r -lpthreads" + else + AC_WARN(don't know how to make $CC thread-aware) + fi + ;; + *-*-linux-gnu ) + CFLAGS="$CFLAGS -D_REENTRANT" + LDFLAGS="-lpthread" + ;; + * ) + AC_WARN(don't know how to make compiler thread-aware) + ;; + esac +fi +# Check pthread functions. +AC_CHECK_FUNCS(pthread_attr_setscope \ + pthread_attr_setstacksize \ + pthread_mutexattr_create \ + pthread_condattr_create \ + pthread_condattr_init \ + pthread_attr_create) + +# Check if pthread_mutex_init() takes attributes by value. +AC_MSG_CHECKING([if pthread_mutex_init() takes attributes by value]) +AC_TRY_COMPILE([ +#include +#include +], [ + pthread_mutex_t m; + + pthread_mutex_init (&m, NULL); +], [ + AC_MSG_RESULT(no) +], [ + AC_MSG_RESULT(yes) + AC_DEFINE(MUTEXATTR_BY_VALUE) +]) + +# Check if pthread_cond_init() takes attributes by value. +AC_MSG_CHECKING([if pthread_cond_init() takes attributes by value]) +AC_TRY_COMPILE([ +#include +#include +], [ + pthread_cond_t c; + + pthread_cond_init (&c, NULL); +], [ + AC_MSG_RESULT(no) +], [ + AC_MSG_RESULT(yes) + AC_DEFINE(CONDATTR_BY_VALUE) +]) + +# Check if pthread_create() takes attributes by value. +AC_MSG_CHECKING([if pthread_create() takes attributes by value]) +AC_TRY_COMPILE([ +#include +#include +], [ + pthread_t th; + pthread_attr_t th_attr; + + pthread_create (&th, &th_attr, NULL, NULL); +], [ + AC_MSG_RESULT(no) +], [ + AC_MSG_RESULT(yes) + AC_DEFINE(THREADATTR_BY_VALUE) +]) + +# Check if asctime_r() takes three arguments. +AC_MSG_CHECKING([if asctime_r() takes three arguments]) +AC_TRY_COMPILE([ +#include +#include +], [ + struct tm tm; + char buf[256]; + + asctime_r (&tm, buf, sizeof (buf)); +], [ + AC_DEFINE(ASCTIME_R_WITH_THREE_ARGS) + AC_MSG_RESULT(yes) +], [ + AC_MSG_RESULT(no) +]) + +# Check if drand48_r() is available and it works with DRAND48D data. +AC_MSG_CHECKING([if drand48_r() works with DRAND48D]) +AC_TRY_COMPILE([ +#include +], [ + DRAND48D data; + double r; + + srand48_r (42, &data); + drand48_r (&data, &r); +], [ + AC_DEFINE(DRAND48_R_WITH_DRAND48D) + AC_MSG_RESULT(yes) +], [ + AC_MSG_RESULT(no) + AC_MSG_WARN(assuming that the drand48() function is thread-safe) +]) + + +# End of AM_POSIX_THREADS macro. +]) + + +# serial 24 AM_PROG_LIBTOOL +AC_DEFUN(AM_PROG_LIBTOOL, +[AC_REQUIRE([AM_ENABLE_SHARED])dnl +AC_REQUIRE([AM_ENABLE_STATIC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_RANLIB])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AM_PROG_LD])dnl +AC_REQUIRE([AM_PROG_NM])dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +dnl +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Check for any special flags to pass to ltconfig. +libtool_flags= +test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared" +test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static" +test "$silent" = yes && libtool_flags="$libtool_flags --silent" +test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc" +test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case "$host" in +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case "`/usr/bin/file conftest.o`" in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + CFLAGS="$CFLAGS -belf" + ;; +esac + +# Actually configure libtool. ac_aux_dir is where install-sh is found. +CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \ +LD="$LD" NM="$NM" RANLIB="$RANLIB" LN_S="$LN_S" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig \ +$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \ +|| AC_MSG_ERROR([libtool configure failed]) +]) + +# AM_ENABLE_SHARED - implement the --enable-shared flag +# Usage: AM_ENABLE_SHARED[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN(AM_ENABLE_SHARED, +[define([AM_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(shared, +changequote(<<, >>)dnl +<< --enable-shared build shared libraries [default=>>AM_ENABLE_SHARED_DEFAULT] +changequote([, ])dnl +[ --enable-shared=PKGS only build shared libraries if the current package + appears as an element in the PKGS list], +[p=${PACKAGE-default} +case "$enableval" in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_shared=AM_ENABLE_SHARED_DEFAULT)dnl +]) + +# AM_DISABLE_SHARED - set the default shared flag to --disable-shared +AC_DEFUN(AM_DISABLE_SHARED, +[AM_ENABLE_SHARED(no)]) + +# AM_DISABLE_STATIC - set the default static flag to --disable-static +AC_DEFUN(AM_DISABLE_STATIC, +[AM_ENABLE_STATIC(no)]) + +# AM_ENABLE_STATIC - implement the --enable-static flag +# Usage: AM_ENABLE_STATIC[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN(AM_ENABLE_STATIC, +[define([AM_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(static, +changequote(<<, >>)dnl +<< --enable-static build static libraries [default=>>AM_ENABLE_STATIC_DEFAULT] +changequote([, ])dnl +[ --enable-static=PKGS only build shared libraries if the current package + appears as an element in the PKGS list], +[p=${PACKAGE-default} +case "$enableval" in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_static=AM_ENABLE_STATIC_DEFAULT)dnl +]) + + +# AM_PROG_LD - find the path to the GNU or non-GNU linker +AC_DEFUN(AM_PROG_LD, +[AC_ARG_WITH(gnu-ld, +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC]) +ac_prog=ld +if test "$ac_cv_prog_gcc" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + ac_prog=`($CC -print-prog-name=ld) 2>&5` + case "$ac_prog" in + # Accept absolute paths. + /* | [A-Za-z]:\\*) + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(ac_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog"; then + ac_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + ac_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$ac_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_SUBST(LD) +AM_PROG_LD_GNU +]) + +AC_DEFUN(AM_PROG_LD_GNU, +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + ac_cv_prog_gnu_ld=yes +else + ac_cv_prog_gnu_ld=no +fi]) +]) + +# AM_PROG_NM - find the path to a BSD-compatible name lister +AC_DEFUN(AM_PROG_NM, +[AC_MSG_CHECKING([for BSD-compatible nm]) +AC_CACHE_VAL(ac_cv_path_NM, +[case "$NM" in +/* | [A-Za-z]:\\*) + ac_cv_path_NM="$NM" # Let the user override the test with a path. + ;; +*) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in /usr/ucb /usr/ccs/bin $PATH /bin; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/nm; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -B" + elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -p" + else + ac_cv_path_NM="$ac_dir/nm" + fi + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm + ;; +esac]) +NM="$ac_cv_path_NM" +AC_MSG_RESULT([$NM]) +AC_SUBST(NM) +]) + + +# serial 1 + +# @defmac AC_PROG_CC_STDC +# @maindex PROG_CC_STDC +# @ovindex CC +# If the C compiler in not in ANSI C mode by default, try to add an option +# to output variable @code{CC} to make it so. This macro tries various +# options that select ANSI C on some system or another. It considers the +# compiler to be in ANSI C mode if it handles function prototypes correctly. +# +# If you use this macro, you should check after calling it whether the C +# compiler has been set to accept ANSI C; if not, the shell variable +# @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source +# code in ANSI C, you can make an un-ANSIfied copy of it by using the +# program @code{ansi2knr}, which comes with Ghostscript. +# @end defmac + +AC_DEFUN(AM_PROG_CC_STDC, +[AC_REQUIRE([AC_PROG_CC]) +AC_BEFORE([$0], [AC_C_INLINE]) +AC_BEFORE([$0], [AC_C_CONST]) +dnl Force this before AC_PROG_CPP. Some cpp's, eg on HPUX, require +dnl a magic option to avoid problems with ANSI preprocessor commands +dnl like #elif. +dnl FIXME: can't do this because then AC_AIX won't work due to a +dnl circular dependency. +dnl AC_BEFORE([$0], [AC_PROG_CPP]) +AC_MSG_CHECKING(for ${CC-cc} option to accept ANSI C) +AC_CACHE_VAL(am_cv_prog_cc_stdc, +[am_cv_prog_cc_stdc=no +ac_save_CC="$CC" +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + AC_TRY_COMPILE( +[#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +], [ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; +], +[am_cv_prog_cc_stdc="$ac_arg"; break]) +done +CC="$ac_save_CC" +]) +if test -z "$am_cv_prog_cc_stdc"; then + AC_MSG_RESULT([none needed]) +else + AC_MSG_RESULT($am_cv_prog_cc_stdc) +fi +case "x$am_cv_prog_cc_stdc" in + x|xno) ;; + *) CC="$CC $am_cv_prog_cc_stdc" ;; +esac +]) + + +# serial 1 + +AC_DEFUN(AM_C_PROTOTYPES, +[AC_REQUIRE([AM_PROG_CC_STDC]) +AC_REQUIRE([AC_PROG_CPP]) +AC_MSG_CHECKING([for function prototypes]) +if test "$am_cv_prog_cc_stdc" != no; then + AC_MSG_RESULT(yes) + AC_DEFINE(PROTOTYPES) + U= ANSI2KNR= +else + AC_MSG_RESULT(no) + U=_ ANSI2KNR=./ansi2knr + # Ensure some checks needed by ansi2knr itself. + AC_HEADER_STDC + AC_CHECK_HEADERS(string.h) +fi +AC_SUBST(U)dnl +AC_SUBST(ANSI2KNR)dnl +]) + diff --git a/reactos/lib/kjs/am.opt/libtool.m4 b/reactos/lib/kjs/am.opt/libtool.m4 new file mode 100644 index 00000000000..07c2046eb06 --- /dev/null +++ b/reactos/lib/kjs/am.opt/libtool.m4 @@ -0,0 +1,259 @@ +## libtool.m4 - Configure libtool for the target system. -*-Shell-script-*- +## Copyright (C) 1996-1998 Free Software Foundation, Inc. +## Gordon Matzigkeit , 1996 +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program 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 +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## As a special exception to the GNU General Public License, if you +## distribute this file as part of a program that contains a +## configuration script generated by Autoconf, you may include it under +## the same distribution terms that you use for the rest of that program. + +# serial 24 AM_PROG_LIBTOOL +AC_DEFUN(AM_PROG_LIBTOOL, +[AC_REQUIRE([AM_ENABLE_SHARED])dnl +AC_REQUIRE([AM_ENABLE_STATIC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_RANLIB])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AM_PROG_LD])dnl +AC_REQUIRE([AM_PROG_NM])dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +dnl +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Check for any special flags to pass to ltconfig. +libtool_flags= +test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared" +test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static" +test "$silent" = yes && libtool_flags="$libtool_flags --silent" +test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc" +test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case "$host" in +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case "`/usr/bin/file conftest.o`" in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + CFLAGS="$CFLAGS -belf" + ;; +esac + +# Actually configure libtool. ac_aux_dir is where install-sh is found. +CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \ +LD="$LD" NM="$NM" RANLIB="$RANLIB" LN_S="$LN_S" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig \ +$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \ +|| AC_MSG_ERROR([libtool configure failed]) +]) + +# AM_ENABLE_SHARED - implement the --enable-shared flag +# Usage: AM_ENABLE_SHARED[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN(AM_ENABLE_SHARED, +[define([AM_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(shared, +changequote(<<, >>)dnl +<< --enable-shared build shared libraries [default=>>AM_ENABLE_SHARED_DEFAULT] +changequote([, ])dnl +[ --enable-shared=PKGS only build shared libraries if the current package + appears as an element in the PKGS list], +[p=${PACKAGE-default} +case "$enableval" in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_shared=AM_ENABLE_SHARED_DEFAULT)dnl +]) + +# AM_DISABLE_SHARED - set the default shared flag to --disable-shared +AC_DEFUN(AM_DISABLE_SHARED, +[AM_ENABLE_SHARED(no)]) + +# AM_DISABLE_STATIC - set the default static flag to --disable-static +AC_DEFUN(AM_DISABLE_STATIC, +[AM_ENABLE_STATIC(no)]) + +# AM_ENABLE_STATIC - implement the --enable-static flag +# Usage: AM_ENABLE_STATIC[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN(AM_ENABLE_STATIC, +[define([AM_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(static, +changequote(<<, >>)dnl +<< --enable-static build static libraries [default=>>AM_ENABLE_STATIC_DEFAULT] +changequote([, ])dnl +[ --enable-static=PKGS only build shared libraries if the current package + appears as an element in the PKGS list], +[p=${PACKAGE-default} +case "$enableval" in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_static=AM_ENABLE_STATIC_DEFAULT)dnl +]) + + +# AM_PROG_LD - find the path to the GNU or non-GNU linker +AC_DEFUN(AM_PROG_LD, +[AC_ARG_WITH(gnu-ld, +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC]) +ac_prog=ld +if test "$ac_cv_prog_gcc" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + ac_prog=`($CC -print-prog-name=ld) 2>&5` + case "$ac_prog" in + # Accept absolute paths. + /* | [A-Za-z]:\\*) + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(ac_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog"; then + ac_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + ac_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$ac_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_SUBST(LD) +AM_PROG_LD_GNU +]) + +AC_DEFUN(AM_PROG_LD_GNU, +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + ac_cv_prog_gnu_ld=yes +else + ac_cv_prog_gnu_ld=no +fi]) +]) + +# AM_PROG_NM - find the path to a BSD-compatible name lister +AC_DEFUN(AM_PROG_NM, +[AC_MSG_CHECKING([for BSD-compatible nm]) +AC_CACHE_VAL(ac_cv_path_NM, +[case "$NM" in +/* | [A-Za-z]:\\*) + ac_cv_path_NM="$NM" # Let the user override the test with a path. + ;; +*) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in /usr/ucb /usr/ccs/bin $PATH /bin; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/nm; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -B" + elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -p" + else + ac_cv_path_NM="$ac_dir/nm" + fi + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm + ;; +esac]) +NM="$ac_cv_path_NM" +AC_MSG_RESULT([$NM]) +AC_SUBST(NM) +]) diff --git a/reactos/lib/kjs/am/pthreads.m4 b/reactos/lib/kjs/am/pthreads.m4 new file mode 100644 index 00000000000..70b2444c0f3 --- /dev/null +++ b/reactos/lib/kjs/am/pthreads.m4 @@ -0,0 +1,179 @@ +# +# Resolve how to compile Posix thread programs. +# + +# serial 1 + +AC_DEFUN(AM_POSIX_THREADS, +[ +# +# First, check the easily recognizable compilers. +# +AC_CANONICAL_HOST + +# pgcc, pthreads gcc by Chris Provenzano +AC_CHECK_PROG(PGCC_BY_PROVENZANO, pgcc, yes, no) + +if test "$PGCC_BY_PROVENZANO" = "yes"; then + CC='pgcc' + CFLAGS="$CFLAGS -g -Wall -Wno-unused" + LDFLAGS="$LDFLAGS -g" +fi + +if test "X$CC" = "X"; then + # xlc_r, thread safe C compiler for AIX + AC_CHECK_PROG(XLC_R_AIX, xlc_r, yes, no) + + if test "$XLC_R_AIX" = "yes"; then + CC='xlc_r' + CFLAGS='-I/usr/local/include -g' + LDFLAGS="$LDFLAGS -L/usr/local/lib -g" + fi +fi + +AC_ARG_WITH(cc, +[ --with-cc(=CC) use system's native compiler or compiler CC], + if test "X$withval" != "Xno"; then + if test "X$withval" = "Xyes"; then + CC='cc' + else + CC=$withval + fi + CFLAGS='-I/usr/local/include' + LDFLAGS="$LDFLAGS -L/usr/local/lib" + echo "using compiler CC=$CC" + fi +) + +if test "X$CC" = "X"; then + # Ok, not an easy compiler, let's try our knowledge-base + AC_PROG_CC + case "$host" in + *solaris2.5* ) + if test -n "$GCC"; then + CFLAGS="$CFLAGS -D_REENTRANT" + else + CFLAGS="$CFLAGS -threads" + fi + ;; + *osf* ) + if test -n "$GCC"; then + AC_WARN(don't know how to make gcc thread-aware, using cc) + CC='cc' + CFLAGS="$CFLAGS -threads" + else + CFLAGS=="$CFLAGS -threads" + fi + ;; + *aix4* ) + if test -n "$GCC"; then + CFLAGS="$CFLAGS -D_REENTRANT" + LDFLAGS="$LDFLAGS -L/usr/lib/threads -nostartfiles /lib/crt0_r.o -lc_r -lpthreads" + else + AC_WARN(don't know how to make $CC thread-aware) + fi + ;; + *-*-linux-gnu ) + CFLAGS="$CFLAGS -D_REENTRANT" + LDFLAGS="-lpthread" + ;; + * ) + AC_WARN(don't know how to make compiler thread-aware) + ;; + esac +fi +# Check pthread functions. +AC_CHECK_FUNCS(pthread_attr_setscope \ + pthread_attr_setstacksize \ + pthread_mutexattr_create \ + pthread_condattr_create \ + pthread_condattr_init \ + pthread_attr_create) + +# Check if pthread_mutex_init() takes attributes by value. +AC_MSG_CHECKING([if pthread_mutex_init() takes attributes by value]) +AC_TRY_COMPILE([ +#include +#include +], [ + pthread_mutex_t m; + + pthread_mutex_init (&m, NULL); +], [ + AC_MSG_RESULT(no) +], [ + AC_MSG_RESULT(yes) + AC_DEFINE(MUTEXATTR_BY_VALUE) +]) + +# Check if pthread_cond_init() takes attributes by value. +AC_MSG_CHECKING([if pthread_cond_init() takes attributes by value]) +AC_TRY_COMPILE([ +#include +#include +], [ + pthread_cond_t c; + + pthread_cond_init (&c, NULL); +], [ + AC_MSG_RESULT(no) +], [ + AC_MSG_RESULT(yes) + AC_DEFINE(CONDATTR_BY_VALUE) +]) + +# Check if pthread_create() takes attributes by value. +AC_MSG_CHECKING([if pthread_create() takes attributes by value]) +AC_TRY_COMPILE([ +#include +#include +], [ + pthread_t th; + pthread_attr_t th_attr; + + pthread_create (&th, &th_attr, NULL, NULL); +], [ + AC_MSG_RESULT(no) +], [ + AC_MSG_RESULT(yes) + AC_DEFINE(THREADATTR_BY_VALUE) +]) + +# Check if asctime_r() takes three arguments. +AC_MSG_CHECKING([if asctime_r() takes three arguments]) +AC_TRY_COMPILE([ +#include +#include +], [ + struct tm tm; + char buf[256]; + + asctime_r (&tm, buf, sizeof (buf)); +], [ + AC_DEFINE(ASCTIME_R_WITH_THREE_ARGS) + AC_MSG_RESULT(yes) +], [ + AC_MSG_RESULT(no) +]) + +# Check if drand48_r() is available and it works with DRAND48D data. +AC_MSG_CHECKING([if drand48_r() works with DRAND48D]) +AC_TRY_COMPILE([ +#include +], [ + DRAND48D data; + double r; + + srand48_r (42, &data); + drand48_r (&data, &r); +], [ + AC_DEFINE(DRAND48_R_WITH_DRAND48D) + AC_MSG_RESULT(yes) +], [ + AC_MSG_RESULT(no) + AC_MSG_WARN(assuming that the drand48() function is thread-safe) +]) + + +# End of AM_POSIX_THREADS macro. +]) diff --git a/reactos/lib/kjs/config.cache b/reactos/lib/kjs/config.cache new file mode 100644 index 00000000000..e9db5ddd7fe --- /dev/null +++ b/reactos/lib/kjs/config.cache @@ -0,0 +1,48 @@ +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +ac_cv_c_const=${ac_cv_c_const=yes} +ac_cv_func_alloca_works=${ac_cv_func_alloca_works=yes} +ac_cv_func_drand48=${ac_cv_func_drand48=yes} +ac_cv_func_lstat=${ac_cv_func_lstat=yes} +ac_cv_func_sleep=${ac_cv_func_sleep=yes} +ac_cv_func_srand48=${ac_cv_func_srand48=yes} +ac_cv_func_usleep=${ac_cv_func_usleep=yes} +ac_cv_header_alloca_h=${ac_cv_header_alloca_h=yes} +ac_cv_header_dlfcn_h=${ac_cv_header_dlfcn_h=yes} +ac_cv_header_errno_h=${ac_cv_header_errno_h=yes} +ac_cv_header_float_h=${ac_cv_header_float_h=yes} +ac_cv_header_limits_h=${ac_cv_header_limits_h=yes} +ac_cv_header_stdc=${ac_cv_header_stdc=yes} +ac_cv_header_stdlib_h=${ac_cv_header_stdlib_h=yes} +ac_cv_header_string_h=${ac_cv_header_string_h=yes} +ac_cv_header_unistd_h=${ac_cv_header_unistd_h=yes} +ac_cv_lib_dl_dlopen=${ac_cv_lib_dl_dlopen=yes} +ac_cv_path_LD=${ac_cv_path_LD=/usr/bin/ld} +ac_cv_path_NM=${ac_cv_path_NM='/usr/bin/nm -B'} +ac_cv_path_install=${ac_cv_path_install='/usr/bin/install -c'} +ac_cv_prog_ACLOCAL_FLAGS_FOR_LIBTOOL=${ac_cv_prog_ACLOCAL_FLAGS_FOR_LIBTOOL=found} +ac_cv_prog_CC=${ac_cv_prog_CC=gcc} +ac_cv_prog_CPP=${ac_cv_prog_CPP='gcc -E'} +ac_cv_prog_LN_S=${ac_cv_prog_LN_S='ln -s'} +ac_cv_prog_RANLIB=${ac_cv_prog_RANLIB=ranlib} +ac_cv_prog_cc_cross=${ac_cv_prog_cc_cross=no} +ac_cv_prog_cc_g=${ac_cv_prog_cc_g=yes} +ac_cv_prog_cc_works=${ac_cv_prog_cc_works=yes} +ac_cv_prog_gcc=${ac_cv_prog_gcc=yes} +ac_cv_prog_gnu_ld=${ac_cv_prog_gnu_ld=yes} +ac_cv_prog_make_make_set=${ac_cv_prog_make_make_set=yes} +ac_cv_sizeof_int=${ac_cv_sizeof_int=4} +ac_cv_sizeof_long=${ac_cv_sizeof_long=4} +am_cv_prog_cc_stdc=${am_cv_prog_cc_stdc=} diff --git a/reactos/lib/kjs/config.log b/reactos/lib/kjs/config.log new file mode 100644 index 00000000000..59b9d13b91b --- /dev/null +++ b/reactos/lib/kjs/config.log @@ -0,0 +1,53 @@ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +configure:582: checking for a BSD compatible install +configure:635: checking whether build environment is sane +configure:692: checking whether make sets ${MAKE} +configure:738: checking for working aclocal +configure:751: checking for working autoconf +configure:764: checking for working automake +configure:777: checking for working autoheader +configure:790: checking for working makeinfo +configure:813: checking for libtool +configure:851: checking for ranlib +configure:885: checking host system type +configure:1537: checking for gcc +configure:1614: checking whether the C compiler (gcc ) works +configure:1628: gcc -o conftest conftest.c 1>&5 +configure:1648: checking whether the C compiler (gcc ) is a cross-compiler +configure:1653: checking whether we are using GNU C +configure:1677: checking whether gcc accepts -g +configure:1765: checking for ld used by GCC +configure:1822: checking if the linker (/usr/bin/ld) is GNU ld +configure:1838: checking for BSD-compatible nm +configure:1875: checking whether ln -s works +configure:1943: checking how to run the C preprocessor +configure:2004: checking for AIX +configure:2032: checking for gcc option to accept ANSI C +configure:2110: checking for working const +configure:2187: checking for function prototypes +configure:2348: checking for working alloca.h +configure:2381: checking for alloca +configure:2576: checking for ANSI C header files +configure:2683: checking for string.h +configure:2683: checking for stdlib.h +configure:2683: checking for unistd.h +configure:2683: checking for errno.h +configure:2683: checking for float.h +configure:2683: checking for limits.h +configure:2721: checking size of int +configure:2760: checking size of long +configure:2802: checking for srand48 +configure:2802: checking for drand48 +configure:2802: checking for sleep +configure:2802: checking for usleep +configure:2802: checking for lstat +configure:2856: checking if inline works +configure:2872: gcc -c -g -O2 conftest.c 1>&5 +configure:2892: checking if struct stat has st_blksize +configure:2907: gcc -c -g -O2 conftest.c 1>&5 +configure:2927: checking if struct stat has st_blocks +configure:2942: gcc -c -g -O2 conftest.c 1>&5 +configure:3147: checking for dlfcn.h +configure:3184: checking for dlopen in -ldl diff --git a/reactos/lib/kjs/configure.in b/reactos/lib/kjs/configure.in new file mode 100644 index 00000000000..519f7fa40f6 --- /dev/null +++ b/reactos/lib/kjs/configure.in @@ -0,0 +1,275 @@ +dnl Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.12) + +AC_INIT(src/jsint.h) +AM_INIT_AUTOMAKE(js, 0.2.5) +AM_CONFIG_HEADER(jsconfig.h) + +AC_REVISION($Revision: 1.1 $) + +dnl Check if we have `libtool'. + +AC_CHECK_PROG(ACLOCAL_FLAGS_FOR_LIBTOOL, libtool, found, -I $(srcdir)/am.opt) + +if test "X$ACLOCAL_FLAGS_FOR_LIBTOOL" = "Xfound"; then + ACLOCAL_FLAGS_FOR_LIBTOOL="" +fi + + +AM_PROG_INSTALL +AC_PROG_RANLIB + +AC_CANONICAL_HOST +AC_DEFINE_UNQUOTED(CANONICAL_HOST, "$host") +AC_DEFINE_UNQUOTED(CANONICAL_HOST_CPU, "$host_cpu") +AC_DEFINE_UNQUOTED(CANONICAL_HOST_VENDOR, "$host_vendor") +AC_DEFINE_UNQUOTED(CANONICAL_HOST_OS, "$host_os") + +dnl System / C-compiler properties. + +please_posix_threads=0 +AC_ARG_WITH(pthreads, +[ --with-pthreads use Posix threads for the re-entrant functions], + if test "X$withval" = "Xyes"; then + please_posix_threads=1 + + echo "fetching re-entrant functions from the Posix threads library" + RE_ENTRANT_SOURCE="r_pthrs.lo" + fi +) + +if test "X$please_posix_threads" = "X1"; then + dnl Check if we know anything about the Posix threads. + AM_POSIX_THREADS +fi + +dnl ... other re-entrancy back-ends + +if test "X$RE_ENTRANT_SOURCE" = "X"; then + echo "fetching re-entrant functions from the C-library" + AC_MSG_WARN(the interpreter is not re-entrant) + RE_ENTRANT_SOURCE="r_std.lo" +fi + +INTERPRETER_FEATURES="$INTERPRETER_FEATURES $RE_ENTRANT_SOURCE" + +dnl Now we definitely need the cc. +AC_PROG_CC + + +AM_ENABLE_SHARED(no) +AM_ENABLE_STATIC(yes) +AM_PROG_LIBTOOL + +AC_AIX + +AM_PROG_CC_STDC + +AC_C_CONST +AM_C_PROTOTYPES +AC_FUNC_ALLOCA + +AC_STDC_HEADERS +AC_HAVE_HEADERS(string.h stdlib.h unistd.h errno.h float.h limits.h) + +AC_CHECK_SIZEOF(int) +AC_CHECK_SIZEOF(long) + +AC_CHECK_FUNCS(srand48 drand48 sleep usleep lstat) + +dnl Can we use inline? +AC_MSG_CHECKING([if inline works]) +AC_TRY_COMPILE([ +static inline int foo () +{ + return 0; +} +], [ + foo (); +], [ + AC_MSG_RESULT(yes) +], [ + AC_MSG_RESULT(no) + AC_DEFINE(inline,) +]) + +dnl Does the struct stat have st_blksize? +AC_MSG_CHECKING([if struct stat has st_blksize]) +AC_TRY_COMPILE([ +#include +#include +], [ + struct stat stat_st; + stat_st.st_blksize = 0; +], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_STAT_ST_ST_BLKSIZE, 1) +], [ + AC_MSG_RESULT(no) +]) + +dnl Does the struct stat have st_blocks? +AC_MSG_CHECKING([if struct stat has st_blocks]) +AC_TRY_COMPILE([ +#include +#include +], [ + struct stat stat_st; + stat_st.st_blocks = 0; +], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_STAT_ST_ST_BLOCKS, 1) +], [ + AC_MSG_RESULT(no) +]) + +dnl +dnl Interpreter features. +dnl + +AC_ARG_ENABLE(all-dispatchers, +[ --enable-all-dispatchers build all byte-code instruction dispatchers], + if test "X$enableval" = "Xyes"; then + echo "building all byte-code instruction dispatchers" + AC_DEFINE(ALL_DISPATCHERS) + INTERPRETER_FEATURES="$INTERPRETER_FEATURES vmswt0.lo" + fi +) + +AC_ARG_ENABLE(profiling, +[ --enable-profiling enable byte-code operand profiling], + if test "X$enableval" = "Xyes"; then + echo "enabling byte-code operand profiling" + AC_DEFINE(PROFILING) + fi +) + +AC_ARG_ENABLE(operand-hooks, +[ --enable-operand-hooks turn on byte-code operand hooks], + if test "X$enableval" = "Xyes"; then + echo "enabling byte-code operand hooks" + AC_DEFINE(BC_OPERAND_HOOKS) + fi +) + +AC_ARG_ENABLE(jumps, +[ --disable-jumps disable the jumps instruction dispatch method], + if test "X$enableval" = "Xno"; then + echo "disabling the jumps byte-code instruction dispatch method" + AC_DEFINE(DISABLE_JUMPS) + fi +) + + +dnl +dnl Extensions. +dnl + +EXTENSIONS="" +EXTENSIONS_LIBS="" + +with_curses_val=0 +AC_ARG_WITH(curses, +[ --with-curses build curses entension], + if test "X$withval" = "Xyes"; then + echo "building curses extension" + with_curses_val=1 + + dnl Check which curses package to use. + AC_CHECK_HEADER(ncurses.h, [ + AC_DEFINE(HAVE_NCURSES_H) + curses_lib='-lncurses' + ], [ + AC_CHECK_HEADER(curses.h, [ + AC_DEFINE(HAVE_CURSES_H) + curses_lib='-lcurses' + ], [ + AC_MSG_ERROR([couldn't determine which curses library I should use]) + ]) + ]) + fi +) +if test "X$with_curses_val" = "X1"; then + AC_DEFINE(WITH_CURSES) + EXTENSIONS="$EXTENSIONS xcurses.lo" + EXTENSIONS_LIBS="$EXTENSIONS_LIBS $curses_lib -ltermcap" +fi + +with_dload_val=1 +AC_ARG_WITH(dload, +[ --without-dload disable dynamic loading], + if test "X$withval" = "Xno"; then + echo "disabling the dynamic loading" + with_dload_val=0 + fi +) +if test "X$with_dload_val" = "X1"; then + # Check what dload method we should use, and from which library. + + # The dl{open,close,cym}() interface. + AC_HAVE_HEADERS(dlfcn.h) + AC_CHECK_LIB(dl, dlopen, [ + EXTENSIONS="$EXTENSIONS dl_open.lo" + EXTENSIONS_LIBS="$EXTENSIONS_LIBS -ldl" + ], [ + # Ok, can't do dynamic loading. + with_dload_val=0 + ]) +fi +if test "X$with_dload_val" = "X1"; then + # Everything ok so far. Let's set the final link flags the + # environment might require. + case "$host" in + *linux* ) + LDFLAGS="$LDFLAGS -rdynamic" + ;; + esac +else + # Sorry, no luck. Dynamic loading do not work on your system. + EXTENSIONS="dl_dummy.lo" +fi + +with_js_val=1 +AC_ARG_WITH(js, +[ --without-js do not built the JS extension], + if text "X$withval" = "Xno"; then + echo "disabling the JS extension" + with_js_val=0 + fi +) +if test "X$with_js_val" = "X1"; then + AC_DEFINE(WITH_JS) + EXTENSIONS="$EXTENSIONS xjs.lo" +fi + +with_md5_val=1 +AC_ARG_WITH(md5, +[ --without-md5 do not built the MD5 extension], + if text "X$withval" = "Xno"; then + echo "disabling the MD5 extension" + with_md5_val=0 + fi +) +if test "X$with_md5_val" = "X1"; then + AC_DEFINE(WITH_MD5) + EXTENSIONS="$EXTENSIONS xmd5.lo md5c.lo" +fi + +AC_SUBST(EXTENSIONS) +AC_SUBST(EXTENSIONS_LIBS) + +AC_SUBST(INTERPRETER_FEATURES) + +AC_OUTPUT([Makefile \ + src/Makefile \ + src/tests/Makefile \ + examples/Makefile \ + jsc/Makefile \ + jsc/tests/Makefile \ + jsas/Makefile \ + jsdas/Makefile \ + jswrap/Makefile \ + docs/Makefile \ + projects/Makefile \ + micros/Makefile]) diff --git a/reactos/lib/kjs/docs/Makefile b/reactos/lib/kjs/docs/Makefile new file mode 100644 index 00000000000..a216f54219a --- /dev/null +++ b/reactos/lib/kjs/docs/Makefile @@ -0,0 +1,343 @@ +# Generated automatically from Makefile.in by configure. +# Makefile.in generated automatically by automake 1.3 from Makefile.am + +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Automakefile for the documents. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + + +SHELL = /bin/sh + +srcdir = . +top_srcdir = .. +prefix = /usr/local/js-0.2.5 +exec_prefix = ${prefix} + +bindir = ${exec_prefix}/bin +sbindir = ${exec_prefix}/sbin +libexecdir = ${exec_prefix}/libexec +datadir = ${prefix}/share +sysconfdir = ${prefix}/etc +sharedstatedir = ${prefix}/com +localstatedir = ${prefix}/var +libdir = ${exec_prefix}/lib +infodir = ${prefix}/info +mandir = ${prefix}/man +includedir = ${prefix}/include +oldincludedir = /usr/include + +DISTDIR = + +pkgdatadir = $(datadir)/js +pkglibdir = $(libdir)/js +pkgincludedir = $(includedir)/js + +top_builddir = .. + +ACLOCAL = aclocal +AUTOCONF = autoconf +AUTOMAKE = automake +AUTOHEADER = autoheader + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} +transform = s,x,x, + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = i686-pc-linux-gnu +host_triplet = i686-pc-linux-gnu +ACLOCAL_FLAGS_FOR_LIBTOOL = +CC = gcc +CPP = gcc -E +EXTENSIONS = dl_open.lo xjs.lo xmd5.lo md5c.lo +EXTENSIONS_LIBS = -ldl +INTERPRETER_FEATURES = r_std.lo +LD = /usr/bin/ld +LIBTOOL = $(SHELL) $(top_builddir)/libtool +LN_S = ln -s +MAKEINFO = makeinfo +NM = /usr/bin/nm -B +PACKAGE = js +PGCC_BY_PROVENZANO = +RANLIB = ranlib +U = +VERSION = 0.2.5 +XLC_R_AIX = + +info_TEXINFOS = js.texi + +EXTRA_DIST = design.texi lgpl.texinfo +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../jsconfig.h +CONFIG_CLEAN_FILES = +TEXI2DVI = texi2dvi +TEXINFO_TEX = $(srcdir)/texinfo.tex +INFO_DEPS = js.info +DVIS = js.dvi +TEXINFOS = js.texi +DIST_COMMON = Makefile.am Makefile.in mdate-sh stamp-vti texinfo.tex \ +version.texi + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP = --best +all: Makefile $(INFO_DEPS) + +.SUFFIXES: +.SUFFIXES: .dvi .info .ps .texi .texinfo .txi +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps docs/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +version.texi: stamp-vti + cp $(srcdir)/stamp-vti $(srcdir)/version.texi + +stamp-vti: js.texi $(top_srcdir)/configure.in + @echo "@set UPDATED `cd $(srcdir) \ + && $(SHELL) ./mdate-sh js.texi`" > vti.tmp + @echo "@set EDITION $(VERSION)" >> vti.tmp + @echo "@set VERSION $(VERSION)" >> vti.tmp + @cmp -s vti.tmp $(srcdir)/stamp-vti \ + || (echo "Updating $(srcdir)/stamp-vti"; \ + cp vti.tmp $(srcdir)/stamp-vti) + -@rm -f vti.tmp + +mostlyclean-vti: + -rm -f vti.tmp + +clean-vti: + +distclean-vti: + +maintainer-clean-vti: + -rm -f stamp-vti version.texi + +js.info: js.texi version.texi +js.dvi: js.texi version.texi + + +DVIPS = dvips + +.texi.info: + @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] + cd $(srcdir) \ + && $(MAKEINFO) `echo $< | sed 's,.*/,,'` + +.texi.dvi: + TEXINPUTS=$(srcdir):$$TEXINPUTS \ + MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< + +.texi: + @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] + cd $(srcdir) \ + && $(MAKEINFO) `echo $< | sed 's,.*/,,'` + +.texinfo.info: + @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] + cd $(srcdir) \ + && $(MAKEINFO) `echo $< | sed 's,.*/,,'` + +.texinfo: + @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] + cd $(srcdir) \ + && $(MAKEINFO) `echo $< | sed 's,.*/,,'` + +.texinfo.dvi: + TEXINPUTS=$(srcdir):$$TEXINPUTS \ + MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< + +.txi.info: + @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] + cd $(srcdir) \ + && $(MAKEINFO) `echo $< | sed 's,.*/,,'` + +.txi.dvi: + TEXINPUTS=$(srcdir):$$TEXINPUTS \ + MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< + +.txi: + @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] + cd $(srcdir) \ + && $(MAKEINFO) `echo $< | sed 's,.*/,,'` +.dvi.ps: + $(DVIPS) $< -o $@ + +install-info-am: $(INFO_DEPS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(infodir) + @for file in $(INFO_DEPS); do \ + d=$(srcdir); \ + for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9]`; do \ + if test -f $$d/$$ifile; then \ + echo " $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile"; \ + $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile; \ + else : ; fi; \ + done; \ + done + @$(POST_INSTALL) + @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \ + for file in $(INFO_DEPS); do \ + echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file";\ + install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file || :;\ + done; \ + else : ; fi + +uninstall-info: + $(PRE_UNINSTALL) + @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \ + ii=yes; \ + else ii=; fi; \ + for file in $(INFO_DEPS); do \ + test -z "$ii" \ + || install-info --info-dir=$(DESTDIR)$(infodir) --remove $$file; \ + done + @$(NORMAL_UNINSTALL) + for file in $(INFO_DEPS); do \ + (cd $(DESTDIR)$(infodir) && rm -f $$file $$file-[0-9] $$file-[0-9][0-9]); \ + done + +dist-info: $(INFO_DEPS) + for base in $(INFO_DEPS); do \ + d=$(srcdir); \ + for file in `cd $$d && eval echo $$base*`; do \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done; \ + done + +mostlyclean-aminfo: + -rm -f js.aux js.cp js.cps js.dvi js.fn js.fns js.ky js.kys js.ps \ + js.log js.pg js.toc js.tp js.tps js.vr js.vrs js.op js.tr \ + js.cv js.cn + +clean-aminfo: + +distclean-aminfo: + +maintainer-clean-aminfo: + for i in $(INFO_DEPS); do \ + rm -f $$i; \ + if test "`echo $$i-[0-9]*`" != "$$i-[0-9]*"; then \ + rm -f $$i-[0-9]*; \ + fi; \ + done +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = docs + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done + $(MAKE) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-info +info: $(INFO_DEPS) +dvi: $(DVIS) +check: all + $(MAKE) +installcheck: +install-exec: + @$(NORMAL_INSTALL) + +install-data: install-info-am + @$(NORMAL_INSTALL) + +install: install-exec install-data all + @: + +uninstall: uninstall-info + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(infodir) + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean: mostlyclean-vti mostlyclean-aminfo mostlyclean-generic + +clean: clean-vti clean-aminfo clean-generic mostlyclean + +distclean: distclean-vti distclean-aminfo distclean-generic clean + -rm -f config.status + -rm -f libtool + +maintainer-clean: maintainer-clean-vti maintainer-clean-aminfo \ + maintainer-clean-generic distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +.PHONY: mostlyclean-vti distclean-vti clean-vti maintainer-clean-vti \ +install-info-am uninstall-info mostlyclean-aminfo distclean-aminfo \ +clean-aminfo maintainer-clean-aminfo tags distdir info dvi installcheck \ +install-exec install-data install uninstall all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/reactos/lib/kjs/docs/Makefile.am b/reactos/lib/kjs/docs/Makefile.am new file mode 100644 index 00000000000..28b945ae331 --- /dev/null +++ b/reactos/lib/kjs/docs/Makefile.am @@ -0,0 +1,27 @@ +# +# Automakefile for the documents. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + +info_TEXINFOS = js.texi + +EXTRA_DIST = design.texi lgpl.texinfo diff --git a/reactos/lib/kjs/docs/Makefile.in b/reactos/lib/kjs/docs/Makefile.in new file mode 100644 index 00000000000..2ffb6388a12 --- /dev/null +++ b/reactos/lib/kjs/docs/Makefile.in @@ -0,0 +1,343 @@ +# Makefile.in generated automatically by automake 1.3 from Makefile.am + +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Automakefile for the documents. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + + +SHELL = /bin/sh + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DISTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_FLAGS_FOR_LIBTOOL = @ACLOCAL_FLAGS_FOR_LIBTOOL@ +CC = @CC@ +CPP = @CPP@ +EXTENSIONS = @EXTENSIONS@ +EXTENSIONS_LIBS = @EXTENSIONS_LIBS@ +INTERPRETER_FEATURES = @INTERPRETER_FEATURES@ +LD = @LD@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +NM = @NM@ +PACKAGE = @PACKAGE@ +PGCC_BY_PROVENZANO = @PGCC_BY_PROVENZANO@ +RANLIB = @RANLIB@ +U = @U@ +VERSION = @VERSION@ +XLC_R_AIX = @XLC_R_AIX@ + +info_TEXINFOS = js.texi + +EXTRA_DIST = design.texi lgpl.texinfo +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../jsconfig.h +CONFIG_CLEAN_FILES = +TEXI2DVI = texi2dvi +TEXINFO_TEX = $(srcdir)/texinfo.tex +INFO_DEPS = js.info +DVIS = js.dvi +TEXINFOS = js.texi +DIST_COMMON = Makefile.am Makefile.in mdate-sh stamp-vti texinfo.tex \ +version.texi + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP = --best +all: Makefile $(INFO_DEPS) + +.SUFFIXES: +.SUFFIXES: .dvi .info .ps .texi .texinfo .txi +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps docs/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +version.texi: stamp-vti + cp $(srcdir)/stamp-vti $(srcdir)/version.texi + +stamp-vti: js.texi $(top_srcdir)/configure.in + @echo "@set UPDATED `cd $(srcdir) \ + && $(SHELL) ./mdate-sh js.texi`" > vti.tmp + @echo "@set EDITION $(VERSION)" >> vti.tmp + @echo "@set VERSION $(VERSION)" >> vti.tmp + @cmp -s vti.tmp $(srcdir)/stamp-vti \ + || (echo "Updating $(srcdir)/stamp-vti"; \ + cp vti.tmp $(srcdir)/stamp-vti) + -@rm -f vti.tmp + +mostlyclean-vti: + -rm -f vti.tmp + +clean-vti: + +distclean-vti: + +maintainer-clean-vti: + -rm -f stamp-vti version.texi + +js.info: js.texi version.texi +js.dvi: js.texi version.texi + + +DVIPS = dvips + +.texi.info: + @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] + cd $(srcdir) \ + && $(MAKEINFO) `echo $< | sed 's,.*/,,'` + +.texi.dvi: + TEXINPUTS=$(srcdir):$$TEXINPUTS \ + MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< + +.texi: + @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] + cd $(srcdir) \ + && $(MAKEINFO) `echo $< | sed 's,.*/,,'` + +.texinfo.info: + @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] + cd $(srcdir) \ + && $(MAKEINFO) `echo $< | sed 's,.*/,,'` + +.texinfo: + @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] + cd $(srcdir) \ + && $(MAKEINFO) `echo $< | sed 's,.*/,,'` + +.texinfo.dvi: + TEXINPUTS=$(srcdir):$$TEXINPUTS \ + MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< + +.txi.info: + @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] + cd $(srcdir) \ + && $(MAKEINFO) `echo $< | sed 's,.*/,,'` + +.txi.dvi: + TEXINPUTS=$(srcdir):$$TEXINPUTS \ + MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< + +.txi: + @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] + cd $(srcdir) \ + && $(MAKEINFO) `echo $< | sed 's,.*/,,'` +.dvi.ps: + $(DVIPS) $< -o $@ + +install-info-am: $(INFO_DEPS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(infodir) + @for file in $(INFO_DEPS); do \ + d=$(srcdir); \ + for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9]`; do \ + if test -f $$d/$$ifile; then \ + echo " $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile"; \ + $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile; \ + else : ; fi; \ + done; \ + done + @$(POST_INSTALL) + @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \ + for file in $(INFO_DEPS); do \ + echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file";\ + install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file || :;\ + done; \ + else : ; fi + +uninstall-info: + $(PRE_UNINSTALL) + @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \ + ii=yes; \ + else ii=; fi; \ + for file in $(INFO_DEPS); do \ + test -z "$ii" \ + || install-info --info-dir=$(DESTDIR)$(infodir) --remove $$file; \ + done + @$(NORMAL_UNINSTALL) + for file in $(INFO_DEPS); do \ + (cd $(DESTDIR)$(infodir) && rm -f $$file $$file-[0-9] $$file-[0-9][0-9]); \ + done + +dist-info: $(INFO_DEPS) + for base in $(INFO_DEPS); do \ + d=$(srcdir); \ + for file in `cd $$d && eval echo $$base*`; do \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done; \ + done + +mostlyclean-aminfo: + -rm -f js.aux js.cp js.cps js.dvi js.fn js.fns js.ky js.kys js.ps \ + js.log js.pg js.toc js.tp js.tps js.vr js.vrs js.op js.tr \ + js.cv js.cn + +clean-aminfo: + +distclean-aminfo: + +maintainer-clean-aminfo: + for i in $(INFO_DEPS); do \ + rm -f $$i; \ + if test "`echo $$i-[0-9]*`" != "$$i-[0-9]*"; then \ + rm -f $$i-[0-9]*; \ + fi; \ + done +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = docs + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done + $(MAKE) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-info +info: $(INFO_DEPS) +dvi: $(DVIS) +check: all + $(MAKE) +installcheck: +install-exec: + @$(NORMAL_INSTALL) + +install-data: install-info-am + @$(NORMAL_INSTALL) + +install: install-exec install-data all + @: + +uninstall: uninstall-info + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(infodir) + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean: mostlyclean-vti mostlyclean-aminfo mostlyclean-generic + +clean: clean-vti clean-aminfo clean-generic mostlyclean + +distclean: distclean-vti distclean-aminfo distclean-generic clean + -rm -f config.status + -rm -f libtool + +maintainer-clean: maintainer-clean-vti maintainer-clean-aminfo \ + maintainer-clean-generic distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +.PHONY: mostlyclean-vti distclean-vti clean-vti maintainer-clean-vti \ +install-info-am uninstall-info mostlyclean-aminfo distclean-aminfo \ +clean-aminfo maintainer-clean-aminfo tags distdir info dvi installcheck \ +install-exec install-data install uninstall all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/reactos/lib/kjs/docs/design.texi b/reactos/lib/kjs/docs/design.texi new file mode 100644 index 00000000000..bcd82acaa7d --- /dev/null +++ b/reactos/lib/kjs/docs/design.texi @@ -0,0 +1,112 @@ +\input texinfo @c -*-texinfo-*- +@c %**start of header +@setfilename jsdesign.info +@settitle jsdesign +@setchapternewpage on +@c %**end of header + +@ifinfo +Copyright (C) 1998 New Generation Software (NGS) Oy + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +@ignore +Permission is granted to process this file through TeX and print the +results, provided the printed document carries copying permission +notice identical to this one except for the removal of this paragraph + + +@end ignore +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the entire +resulting derived work is distributed under the terms of a permission +notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that this permission notice may be stated in a translation approved +by the Foundation. +@end ifinfo + + +@titlepage +@title NGS JavaScript Interpreter +@subtitle Design Goals +@author Markku Rossi + +@page +@vskip 0pt plus 1filll +Copyright @copyright{} 1998 New Generation Software (NGS) Oy +@sp 2 + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the entire +resulting derived work is distributed under the terms of a permission +notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that this permission notice may be stated in a translation +approved by the Free Software Foundation. +@end titlepage + +@ifinfo +@node Top, Introduction, (dir), (dir) +@comment node-name, next, previous, up +@top The Design Goals of the NGS JavaScript Interpreter + +The Design Goals of the NGS JavaScript Interpreter. + +@end ifinfo + +@strong{This document is very much under construction.} + +@menu +* Introduction:: +* Re-Entrant:: +* Extendible:: +* Fast:: +* Programmable:: +* The *Java* Hype:: +@end menu + +@node Introduction, Re-Entrant, Top, Top +@chapter Introduction + +The NGS JavaScript interpreter is "yet another extension language". +Although the world is full of extensions languages, none of the +currently available languages didn't meet all the requirements we had +for the extension language. So, as a trivial solution, we decided to +implement one that would satisfy our needs. + +The following chapters describe the goals that were set for the project. +The chapters are in priority order, starting from the most important +feature. + +@node Re-Entrant, Extendible, Introduction, Top +@chapter Re-Entrant + +One of the original reasons for the JS project was the lack of +thread-safe interpreters. + +@node Extendible, Fast, Re-Entrant, Top +@chapter Extendible + +@node Fast, Programmable, Extendible, Top +@chapter Fast + +@node Programmable, The *Java* Hype, Fast, Top +@chapter Programmable + +@node The *Java* Hype, , Programmable, Top +@chapter The *Java* Hype + +@contents + +@bye diff --git a/reactos/lib/kjs/docs/js.info b/reactos/lib/kjs/docs/js.info new file mode 100644 index 00000000000..19cb00d61cd --- /dev/null +++ b/reactos/lib/kjs/docs/js.info @@ -0,0 +1,145 @@ +This is Info file js.info, produced by Makeinfo version 1.68 from the +input file js.texi. + +INFO-DIR-SECTION NGS JavaScript Interpreter +START-INFO-DIR-ENTRY +* libjs: (js). The JavaScript interpreter library. +* js: (js)The js Program. JavaScript interpreter. +END-INFO-DIR-ENTRY + + This file documents NGS JavaScript interpreter 0.2.5 + + Copyright (C) 1998 New Generation Software (NGS) Oy + + Permission is granted to make and distribute verbatim copies of this +manual provided the copyright notice and this permission notice are +preserved on all copies. + + Permission is granted to copy and distribute modified versions of +this manual under the conditions for verbatim copying, provided that +the entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + + Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that this permission notice may be stated in a +translation approved by the Foundation. + + +Indirect: +js.info-1: 1052 +js.info-2: 50497 +js.info-3: 100456 +js.info-4: 147894 + +Tag Table: +(Indirect) +Node: Top1052 +Node: Introduction1530 +Node: NGS JavaScript Language1730 +Node: Language1973 +Node: Lexical Conventions2215 +Node: White Space2498 +Node: Comments2631 +Node: Reserved Words2753 +Node: Identifiers2887 +Node: Punctuators3018 +Node: Literals3143 +Node: Automatic Semicolon Insertion3280 +Node: Function Definition4268 +Node: Statements4416 +Node: Block4917 +Node: Variable Statement5024 +Node: Empty Statement5162 +Node: The if Statement5305 +Node: The do...while Statement5460 +Node: The while Statement5639 +Node: The for Statement5805 +Node: The for...in Statement5965 +Node: The continue Statement6142 +Node: The break Statement6317 +Node: The return Statement6484 +Node: The with Statement6649 +Node: The switch Statement6975 +Node: Labeled Statements7139 +Node: The throw Statement7296 +Node: The try Statement7456 +Node: Expressions7585 +Node: Primary Expressions8045 +Node: Left-Hand-Side Expressions8204 +Node: Postfix Expressions8385 +Node: Unary Operators8548 +Node: Multiplicative Operators8701 +Node: Additive Operators8871 +Node: Bitwise Shift Operators9037 +Node: Relational Operators9209 +Node: Equality Operators9375 +Node: Binary Bitwise Operators9538 +Node: Binary Logical Operators9717 +Node: Conditional Operator9898 +Node: Assignment Operators10067 +Node: Comma Operator10226 +Node: Global Methods and Properties10344 +Node: Native Objects13372 +Node: Array13678 +Node: Boolean20867 +Node: Date21974 +Node: File23572 +Node: Directory27924 +Node: Function28319 +Node: Math28424 +Node: Number29593 +Node: Object31030 +Node: RegExp31585 +Node: String37819 +Node: System42434 +Node: VM46388 +Node: Extensions49830 +Node: Curses49978 +Node: JS50072 +Node: MD550497 +Node: The js Program52029 +Node: Invoking The js Program52486 +Node: Evaluating and Executing Code62627 +Node: Compiling JavaScript Code62830 +Node: Warning Messages63490 +Node: Optimization68445 +Node: Debugging Information68597 +Node: Assembler Listings70615 +Node: The jsas Program73003 +Node: Invoking The jsas Program73319 +Node: The jsdas Program74216 +Node: Invoking The jsdas Program74642 +Node: Viewing Byte-Code Files76034 +Node: Manipulating Byte-Code Files79458 +Node: The jswrap Program80445 +Node: Invoking The jswrap Program80827 +Node: Definition File Format82356 +Node: The Type Specifiers83870 +Node: The Pass-Type Specifiers85357 +Node: The Life Scope Specifiers86752 +Node: Re-Entrant Functions87454 +Node: Calling the Functions from C87636 +Node: Sample Project87826 +Node: JavaScript API88972 +Node: Interpreter Handling89240 +Node: Evaluation and Compilation91564 +Node: Type Handling95182 +Node: Defining Global Methods95764 +Node: Classes96069 +Node: Modules99295 +Node: Virtual Machine99476 +Node: Byte-Code File Format99686 +Node: File Header99953 +Node: Code Section100317 +Node: Constants Section100456 +Node: Symtab Section101224 +Node: Debug Section101371 +Node: Byte-Code Operands101490 +Node: Stack Frame113444 +Node: JavaScript Compiler114261 +Node: Public Entry Points115800 +Node: GNU Library General Public License120892 +Node: Index147894 + +End Tag Table diff --git a/reactos/lib/kjs/docs/js.info-1 b/reactos/lib/kjs/docs/js.info-1 new file mode 100644 index 00000000000..165316e9fc4 --- /dev/null +++ b/reactos/lib/kjs/docs/js.info-1 @@ -0,0 +1,1886 @@ +This is Info file js.info, produced by Makeinfo version 1.68 from the +input file js.texi. + +INFO-DIR-SECTION NGS JavaScript Interpreter +START-INFO-DIR-ENTRY +* libjs: (js). The JavaScript interpreter library. +* js: (js)The js Program. JavaScript interpreter. +END-INFO-DIR-ENTRY + + This file documents NGS JavaScript interpreter 0.2.5 + + Copyright (C) 1998 New Generation Software (NGS) Oy + + Permission is granted to make and distribute verbatim copies of this +manual provided the copyright notice and this permission notice are +preserved on all copies. + + Permission is granted to copy and distribute modified versions of +this manual under the conditions for verbatim copying, provided that +the entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + + Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that this permission notice may be stated in a +translation approved by the Foundation. + + +File: js.info, Node: Top, Next: Introduction, Prev: (dir), Up: (dir) + +NGS JavaScript Interpreter +************************** + + This file documents the NGS JavaScript interpreter. This edition +documents version 0.2.5. + +* Menu: + +* Introduction:: +* NGS JavaScript Language:: +* The js Program:: +* The jsas Program:: +* The jsdas Program:: +* The jswrap Program:: +* JavaScript API:: +* Virtual Machine:: +* JavaScript Compiler:: +* GNU Library General Public License:: +* Index:: + + +File: js.info, Node: Introduction, Next: NGS JavaScript Language, Prev: Top, Up: Top + +Introduction +************ + + * overall + + * design goals + + * structure: virtual machine, JSC$, JS glue + + +File: js.info, Node: NGS JavaScript Language, Next: The js Program, Prev: Introduction, Up: Top + +NGS JavaScript Language +*********************** + +* Menu: + +* Language:: +* Global Methods and Properties:: +* Native Objects:: +* Extensions:: + + +File: js.info, Node: Language, Next: Global Methods and Properties, Prev: NGS JavaScript Language, Up: NGS JavaScript Language + +Language +======== + +* Menu: + +* Lexical Conventions:: +* Function Definition:: +* Statements:: +* Expressions:: + + +File: js.info, Node: Lexical Conventions, Next: Function Definition, Prev: Language, Up: Language + +Lexical Conventions +------------------- + +* Menu: + +* White Space:: +* Comments:: +* Reserved Words:: +* Identifiers:: +* Punctuators:: +* Literals:: +* Automatic Semicolon Insertion:: + + +File: js.info, Node: White Space, Next: Comments, Prev: Lexical Conventions, Up: Lexical Conventions + +White Space +........... + + +File: js.info, Node: Comments, Next: Reserved Words, Prev: White Space, Up: Lexical Conventions + +Comments +........ + + +File: js.info, Node: Reserved Words, Next: Identifiers, Prev: Comments, Up: Lexical Conventions + +Reserved Words +.............. + + +File: js.info, Node: Identifiers, Next: Punctuators, Prev: Reserved Words, Up: Lexical Conventions + +Identifiers +........... + + +File: js.info, Node: Punctuators, Next: Literals, Prev: Identifiers, Up: Lexical Conventions + +Punctuators +........... + + +File: js.info, Node: Literals, Next: Automatic Semicolon Insertion, Prev: Punctuators, Up: Lexical Conventions + +Literals +........ + + +File: js.info, Node: Automatic Semicolon Insertion, Prev: Literals, Up: Lexical Conventions + +Automatic Semicolon Insertion +............................. + + Certain ECMAScript statements must be terminated with a semicolon. +Such a semicolon may always appear explicitly in the source text. For +pain of the compiler implementator, however, such semicolons may be +omitted from the source text in certain situations. These situations +are described in details in the ECMA-262 Version 2 draft 22-Apr-98 +standard. Here is 's interpretation of the rules: + + Insert semicolons as you would do in the C language. Now, you can +omit them: + + 1. before '`}'' character + + 2. from the end of the line + + 3. from the end of the file + +The automatic semicolon insertion sets some restrictions how you can +insert whitespace to you code. You can't insert line breaks: + + 1. between LEFTHANDSIDEEXPRESSION and `++' or `--' operator + + 2. between `return' and the returned EXPRESSION + + +File: js.info, Node: Function Definition, Next: Statements, Prev: Lexical Conventions, Up: Language + +Function Definition +------------------- + + +File: js.info, Node: Statements, Next: Expressions, Prev: Function Definition, Up: Language + +Statements +---------- + +* Menu: + +* Block:: +* Variable Statement:: +* Empty Statement:: +* The if Statement:: +* The do...while Statement:: +* The while Statement:: +* The for Statement:: +* The for...in Statement:: +* The continue Statement:: +* The break Statement:: +* The return Statement:: +* The with Statement:: +* The switch Statement:: +* Labeled Statements:: +* The throw Statement:: +* The try Statement:: + + +File: js.info, Node: Block, Next: Variable Statement, Prev: Statements, Up: Statements + +Block +..... + + +File: js.info, Node: Variable Statement, Next: Empty Statement, Prev: Block, Up: Statements + +Variable Statement +.................. + + +File: js.info, Node: Empty Statement, Next: The if Statement, Prev: Variable Statement, Up: Statements + +Empty Statement +............... + + +File: js.info, Node: The if Statement, Next: The do...while Statement, Prev: Empty Statement, Up: Statements + +The `if' Statement +.................. + + +File: js.info, Node: The do...while Statement, Next: The while Statement, Prev: The if Statement, Up: Statements + +The `do'...`while' Statement +............................ + + +File: js.info, Node: The while Statement, Next: The for Statement, Prev: The do...while Statement, Up: Statements + +The `while' Statement +..................... + + +File: js.info, Node: The for Statement, Next: The for...in Statement, Prev: The while Statement, Up: Statements + +The `for' Statement +................... + + +File: js.info, Node: The for...in Statement, Next: The continue Statement, Prev: The for Statement, Up: Statements + +The `for'...`in' Statement +.......................... + + +File: js.info, Node: The continue Statement, Next: The break Statement, Prev: The for...in Statement, Up: Statements + +The `continue' Statement +........................ + + +File: js.info, Node: The break Statement, Next: The return Statement, Prev: The continue Statement, Up: Statements + +The `break' Statement +..................... + + +File: js.info, Node: The return Statement, Next: The with Statement, Prev: The break Statement, Up: Statements + +The `return' Statement +...................... + + +File: js.info, Node: The with Statement, Next: The switch Statement, Prev: The return Statement, Up: Statements + +The `with' Statement +.................... + + The syntax of the `with'-statement is: + + with (EXPR) STATEMENT + + with (Math) + { + result = sin (PI); + result -= tan (45); + } + + +File: js.info, Node: The switch Statement, Next: Labeled Statements, Prev: The with Statement, Up: Statements + +The `switch' Statement +...................... + + +File: js.info, Node: Labeled Statements, Next: The throw Statement, Prev: The switch Statement, Up: Statements + +Labeled Statements +.................. + + +File: js.info, Node: The throw Statement, Next: The try Statement, Prev: Labeled Statements, Up: Statements + +The `throw' Statement +..................... + + +File: js.info, Node: The try Statement, Prev: The throw Statement, Up: Statements + +The `try' Statement +................... + + +File: js.info, Node: Expressions, Prev: Statements, Up: Language + +Expressions +----------- + +* Menu: + +* Primary Expressions:: +* Left-Hand-Side Expressions:: +* Postfix Expressions:: +* Unary Operators:: +* Multiplicative Operators:: +* Additive Operators:: +* Bitwise Shift Operators:: +* Relational Operators:: +* Equality Operators:: +* Binary Bitwise Operators:: +* Binary Logical Operators:: +* Conditional Operator:: +* Assignment Operators:: +* Comma Operator:: + + +File: js.info, Node: Primary Expressions, Next: Left-Hand-Side Expressions, Prev: Expressions, Up: Expressions + +Primary Expressions +................... + + +File: js.info, Node: Left-Hand-Side Expressions, Next: Postfix Expressions, Prev: Primary Expressions, Up: Expressions + +Left-Hand-Side Expressions +.......................... + + +File: js.info, Node: Postfix Expressions, Next: Unary Operators, Prev: Left-Hand-Side Expressions, Up: Expressions + +Postfix Expressions +................... + + +File: js.info, Node: Unary Operators, Next: Multiplicative Operators, Prev: Postfix Expressions, Up: Expressions + +Unary Operators +............... + + +File: js.info, Node: Multiplicative Operators, Next: Additive Operators, Prev: Unary Operators, Up: Expressions + +Multiplicative Operators +........................ + + +File: js.info, Node: Additive Operators, Next: Bitwise Shift Operators, Prev: Multiplicative Operators, Up: Expressions + +Additive Operators +.................. + + +File: js.info, Node: Bitwise Shift Operators, Next: Relational Operators, Prev: Additive Operators, Up: Expressions + +Bitwise Shift Operators +....................... + + +File: js.info, Node: Relational Operators, Next: Equality Operators, Prev: Bitwise Shift Operators, Up: Expressions + +Relational Operators +.................... + + +File: js.info, Node: Equality Operators, Next: Binary Bitwise Operators, Prev: Relational Operators, Up: Expressions + +Equality Operators +.................. + + +File: js.info, Node: Binary Bitwise Operators, Next: Binary Logical Operators, Prev: Equality Operators, Up: Expressions + +Binary Bitwise Operators +........................ + + +File: js.info, Node: Binary Logical Operators, Next: Conditional Operator, Prev: Binary Bitwise Operators, Up: Expressions + +Binary Logical Operators +........................ + + +File: js.info, Node: Conditional Operator, Next: Assignment Operators, Prev: Binary Logical Operators, Up: Expressions + +Conditional Operator +.................... + + +File: js.info, Node: Assignment Operators, Next: Comma Operator, Prev: Conditional Operator, Up: Expressions + +Assignment Operators +.................... + + +File: js.info, Node: Comma Operator, Prev: Assignment Operators, Up: Expressions + +Comma Operator +.............. + + +File: js.info, Node: Global Methods and Properties, Next: Native Objects, Prev: Language, Up: NGS JavaScript Language + +Global Methods and Properties +============================= + +*Standard* + ECMA-262 Version 2 draft 22-Apr-98 + + - Property of Global: NaN + The *not a number* value. + + - Property of Global: Infinity + The *positive infinity* value. + + - Function: eval (ANY) + + - Function: parseInt (STRING, RADIX) + + - Function: parseFloat (STRING) + + - Function: escape (STRING) + + - Function: unescape (STRING) + + - Function: isNaN (ANY) + + - Function: isFinite (ANY) + + - Function: debug (ANY) + *Standard* + Netscape JavaScript Reference 12-Dec-97 + + + - Function: print (ANY[,...]) + *Standard* + Netscape JavaScript Reference 12-Dec-97 ??? + + + - Function: error (MESSAGE) + *Standard* + Netscape JavaScript Reference 12-Dec-97 ??? + + + - Function: float (ANY) + *Standard* + NGS JavaScript Interpreter 0.2.5 + + + - Function: int (ANY) + *Standard* + NGS JavaScript Interpreter 0.2.5 + + + - Function: isFloat (ANY) + *Standard* + NGS JavaScript Interpreter 0.2.5 + + + - Function: isInt (ANY) + *Standard* + NGS JavaScript Interpreter 0.2.5 + + + - Function: load (FILE...) + *Standard* + NGS JavaScript Interpreter 0.2.5 + + + - Function: loadClass (CLASS_SPEC...) + *Standard* + NGS JavaScript Interpreter 0.2.5 + + Extend interpreter by calling an initialization function from + shared library CLASS_SPEC. The argument CLASS_SPEC can be given in + the following formats: + + `LIBRARY:FUNCTION' + The argument LIBRARY specifies the shared library from which + function FUNCTION is called. The library specification can be + given in absolute or relative formats. + + `LIBRARY' + The argument LIBRARY specifies both the shared library, and + the name of the entry function. The name of the entry + function is the name of the library, without the possible + leading directory path and any suffixes. + + loadClass ("libexts.so:init_all"); + => CALL FUNCTION `INIT_ALL' FROM LIBRARY `LIBEXTS.SO' + + loadClass ("/usr/local/lib/libexts.so:init_all"); + => CALL FUNCTION `INIT_ALL' FROM LIBRARY `/USR/LOCAL/LIB/LIBEXTS.SO' + + loadClass ("/usr/local/lib/libdbexts.so"); + => CALL FUNCTION `DBEXTS' FROM LIBRARY `/USR/LOCAL/LIB/LIBEXTS.SO' + + The initialization function must be a void function that takes one + argument that is a pointer to the interpreter. + + void + entry (JSInterpPtr interp) + { + INITIALIZE EXTENSIONS USING NORMAL `JS.H' AND `JSINT.H' + INTERFACES. + } + + - Function: callMethod (OBJECT, METHOD, ARGUMENTS) + *Standard* + NGS JavaScript Interpreter 0.2.5 + + Call method METHOD from object OBJECT with arguments ARGUMENTS. + + callMethod (System.stdout, "writeln", ["Hello, world!"]); + -| Hello, world! + + +File: js.info, Node: Native Objects, Next: Extensions, Prev: Global Methods and Properties, Up: NGS JavaScript Language + +Native Objects +============== + +* Menu: + +* Array:: +* Boolean:: +* Date:: +* File:: +* Directory:: +* Function:: +* Math:: +* Number:: +* Object:: +* RegExp:: +* String:: +* System:: +* VM:: + + +File: js.info, Node: Array, Next: Boolean, Prev: Native Objects, Up: Native Objects + +Array +----- + +*Standard* + ECMA-262 Version 2 draft 22-Apr-98 + +*Incompatibilities* + * The `toSource()' method is missing. + + * The constructor doesn't set the [[Prototype]] and [[Class]] + properties. + + - Function: Array (COUNT) + - Function: Array (ITEM...) + Do exactly the same as the expression `new Array()' called with the + same arguments. + + - Constructor: Array (COUNT) + - Constructor: Array (ITEM...) + Create a new array object. The first form creates a new array + which length is COUNT. All items are set to value `undefined'. + The second form creates an array that contains the given items as + its values. + + var a = new Array (5); + a.length; + => 5 + a.toString (); + => undefined,undefined,undefined,undefined,undefined + + a = new Array (1, 2, "hello"); + a.length; + => 3 + a.toString (); + => 1,2,hello + + - Method on Array: concat (ARRAY[, ...]) + Create a new array object from the items of the called array + object and the argument arrays ARRAY, .... The contents of the + argument arrays are not modified. + + var a = new Array (1, 2, 3); + var b = a.concat (new Array (4, 5)); + b.length; + => 5; + b.toString (); + => 1,2,3,4,5 + + - Method on Array: join ([GLUE]) + Convert the array to a string. Individual items of the array are + combined with the string GLUE. If the argument GLUE is omitted, + string `","' is used. + + var a = new Array (1, 2, "three"); + a.join (); + => "1,2,three" + + a.join ("-"); + => "1-2-three" + + - Method on Array: pop () + Remove the last item of the array. The method returns the item + removed. If the array is empty, value `undefined' is returned. + + a = new Array (1, 2, 3); + a.pop (); + => 3 + a.length; + => 2 + + - Method on Array: push (ANY...) + Insert items to the end of the array. The method returns the last + item pushed. + + a = new Array (1, 2); + a.push (7); + => 7 + a.push (7, 8, 9); + => 9 + System.print (a.join (", "), "\n"); + -| 1, 2, 7, 7, 8, 9 + + - Method on Array: reverse () + Reverse the array. + + a = new Array (1, 2, 3); + a.reverse (); + System.print (a.join (""), "\n"); + -| 321 + + - Method on Array: shift () + Remove item from the beginning of the array. The method returns + the item removed, or value `undefined' if the array was empty. + + a = new Array (1, 2, 3); + a.shift (); + => 1 + + - Method on Array: slice (START[, END]) + Return a new array containing items between START (inclusively) + and END (exclusively) in the array. If the argument END is + negative, it is counted from the end of the array. If the argument + END is omitted, the method extract items from the position START + to the end of the array. + + a = new Array (1, 2, 3, 4, 5); + b = a.slice (1, 4); + System.print (b.join (", "), "\n"); + -| 2, 3, 4 + b = a.slice (1, -2); + System.print (b.join (", "), "\n"); + -| 2, 3 + b = a.slice (2); + System.print (b.join (", "), "\n"); + -| 3, 4, 5 + + - Method on Array: splice (INDEX, REMOVE[, ANY...]) + Modify array by removing old items and by inserting new ones. The + argument INDEX specifies the index from which the array is + modified. The argument REMOVE specifies how many old items are + removed. If the argument REMOVE is 0, no old items are removed + and at least one new item must have been given. After the items + are removed, all remaining arguments are inserted after the + position INDEX. + + var a = new Array (1, 2, 3); + a.splice (1, 1); + => 1, 3 + a.splice (1, 0, "new item"); + => 1, "new item", 2, 3 + + var a = new Array (1, 2, 3, 4); + a.splice (1, 2, "new item"); + => 1, "new item", 4 + + - Method on Array: sort ([SORT_FUNCTION]) + Sort the array to the order specified by the argument function + SORT_FUNCTION. The comparison function SORT_FUNCTION takes two + arguments and it must return one of the following codes: + + `-1' + the first argument items is smaller than the second item + (must come before the second item) + + `0' + the items are equal + + `1' + the first argument item is bigger than the second item (it + must come after the second item) + + If the argument SORT_FUNCTION is omitted, the items are sorted to + an alphabetical (lexicographical) order. + + a = new Array ("Jukka-Pekka", "Jukka", "Kari", "Markku"); + a.sort (); + System.print (a, "\n"); + -| Jukka,Jukka-Pekka,Kari,Markku + a = new Array (1, 2, 10, 20, 100, 200); + a.sort (); + System.stdout.writeln (a.toString ()); + -| 1,10,100,2,20,200 + + The sort method is stable in that sense that, if the comparison + function returns 0 for two items, their original order in the + array is preserved. For example, if a list of person objects is + sorted first by their names, and second by their ages, all persons + with the same age will remain sorted in an alphabetical order. + + function by_age (a, b) + { + return a.age - b.age; + } + + function by_name (a, b) + { + if (a.name < b.name) + return -1; + if (a.name > b.name) + return 1; + return 0; + } + + function Person (name, age) + { + this.name = name; + this.age = age; + } + + a = new Array (new Person ("Smith", 30), + new Person ("Jones", 31), + new Person ("Bob", 30), + new Person ("Chris", 29)); + + a.sort (by_name); + a.sort (by_age); + + for (i in a) + System.print (i.name, ", ", i.age, "\n"); + -| Chris, 29 + -| Bob, 30 + -| Smith, 30 + -| Jones, 31 + + - Method on Array: toSource () + + - Method on Array: toString () + Convert the array to a string. The method converts each item of + the array to string and combines them with the string `","'. + + var a = new Array (1, "foo", 2, new Array (7, 8)); + a.toString (); + => 1,foo,2,7,8 + + - Method on Array: unshift (ANY...) + Insert items ANY... to the beginning of the array. The method + returns the new length of the array. + + a = new Array (1, 2, 3); + System.print (a.unshift (7, 8, 9), "\n"); + -| 6 + + - Property of Array: length + The length of the array. + + var a = new Array (1, 2); + a.length; + => 2 + a.push (3, 4, 5); + a.length; + => 5 + + +File: js.info, Node: Boolean, Next: Date, Prev: Array, Up: Native Objects + +Boolean +------- + +*Standard* + ECMA-262 Version 2 draft 22-Apr-98 + +*Incompatibilities* + * The constructor doesn't set the [[Prototype]] and [[Class]] + properties. + + - Function: Boolean () + Return `false'. + + - Function: Boolean (VALUE) + + - Constructor: Boolean () + - Constructor: Boolean (VALUE) + Create a new boolean object. If no arguments are given, the + returned object will have value `false'. If the argument VALUE is + given, the initial value of the object is determined by the type + of the argument and its value. If the argument VALUE is + `undefined', `null', `false', `""' (an empty string), or `0', the + value of the object will be `false'. All other values for the + argument VALUE will set the initial value of the object to `true'. + + - Method on Boolean: toString () + Return a string presentation of the boolean object. The method + will return string `"true"' or `"false"' according to the value of + the object. + + - Method on Boolean: valueOf () + + +File: js.info, Node: Date, Next: File, Prev: Boolean, Up: Native Objects + +Date +---- + +*Standard* + ECMA-262 Version 2 draft 22-Apr-98 + +*Incompatibilities* + XXX Check all methods and properties. + + - Function: MakeTime (HOUR, MIN, SEC, MS) + + - Function: MakeDay (YEAR, MONTH, DATE) + + - Function: MakeDate (DAY, TIME) + + - Function: TimeClip (TIME) + + - Function: Date ([A1[, A2[, A3[, A4[, A5[, A6[, A7]]]]]]]) + When the `Date' constructor is called as a function, it ignores + arguments A1...A7 and returns the result of expression: + + new Date ().toString() + + - Constructor: Date () + - Constructor: Date ("MONTH DAY, YEAR HOURS:MINUTES:SECONDS") + - Constructor: Date (YR_NUM, MO_NUM, DAY_NUM) + - Constructor: Date (YR_NUM, MO_NUM, DAY_NUM, HR_NUM, MIN_NUM, SEC_NUM) + + - Static Method on Date: UTC (YEAR, MONTH, DAY, HRS, MIN, SEC) + + - Method on Date: format (FORMAT) + + - Method on Date: formatGMT (FORMAT) + + - Method on Date: getDate () + + - Method on Date: getDay () + + - Method on Date: getHours () + + - Method on Date: getMinutes () + + - Method on Date: getMonth () + + - Method on Date: getSeconds () + + - Method on Date: getTime () + + - Method on Date: getTimezoneOffset () + + - Method on Date: getYear () + + - Method on Date: parse (STRING) + + - Method on Date: setDate (DAY) + + - Method on Date: setHours (HOURS) + + - Method on Date: setMinutes (MINUTES) + + - Method on Date: setMonths (MONTHS) + + - Method on Date: setSeconds (SECONDS) + + - Method on Date: setTime (TIME) + + - Method on Date: setYear (YEAR) + + - Method on Date: toGMTString () + + - Method on Date: toLocaleString () + + +File: js.info, Node: File, Next: Directory, Prev: Date, Up: Native Objects + +File +---- + +*Standard* + Netscape JavaScript Reference 12-Dec-97 + +*Incompatibilities* + XXX Check all methods and properties. + + - Constructor: File (PATH) + + - Static Method on File: byteToString (BYTE) + + - Static Method on File: chmod (PATH, MODE) + *Standard* + NGS JavaScript Interpreter 0.2.5 + + Change permissions of file PATH to MODE. The modes are specifeid + by or'ing the following values: + + `04000' + set user ID on execution + + `02000' + set group ID on execution + + `01000' + sticky bit + + `00400' + read by owner + + `00200' + write by owner + + `00100' + execute / search by owner + + `00040' + read by group + + `00020' + write by group + + `00010' + execute / search by group + + `00004' + read by others + + `00002' + write by others + + `00001' + execute / search by others + + - Static Method on File: lstat (PATH) + *Standard* + NGS JavaScript Interpreter 0.2.5 + + + - Static Method on File: remove (PATH) + *Standard* + NGS JavaScript Interpreter 0.2.5 + + + - Static Method on File: rename (PATH) + *Standard* + NGS JavaScript Interpreter 0.2.5 + + + - Static Method on File: stat (PATH) + *Standard* + NGS JavaScript Interpreter 0.2.5 + + Return statistics about the file FILE. The method returns a 13 + element array containing the statistics, or `false' if the file + couldn't be inspected. + + The returned array contains the following items: + + `dev' + Device that contains a directory entry for this file. + + `ino' + Index of this file on its device. A file is uniquely + identified by specifying its `dev' and `ino'. + + `mode' + The mode of the file. + + `nlink' + The number of hard links to the file. + + `uid' + The ID of the file owner. + + `gid' + The ID of the file group. + + `rdev' + The ID of the device. + + `size' + The size of the file. + + `atime' + The time when the data was last accessed. + + `mtime' + The time when the data was last modified. + + `ctime' + The time when the file status was last changed. + + `blksize' + Preferred blocksize for file system I/O. + + `blocks' + The number of blocks the file actually uses. + + fields = new Array ("dev", "ino", "mode", "nlink", "uid", + "gid", "rdev", "size", "atime", + "mtime", "ctime", "blksize", "blocks"); + + var a = File.stat ("js"); + if (a) + { + var i; + for (i = 0; i < a.length; i++) + System.print (fields[i], "=", a[i], " "); + System.print ("\n"); + } + + -| dev=655368 ino=370741 mode=33261 nlink=1 uid=201 gid=200 + -| rdev=2979328 size=731370 atime=893159080 mtime=893158537 + -| ctime=893158537 blksize=4096 blocks=1432 + + - Static Method on File: stringToByte (STRING) + + - Method on File: open (MODE) + The argument MODE must have one of the following values: + + `r'[`b'] + + `w'[`b'] + + `a'[`b'] + + `r+'[`b'] + + `w+'[`b'] + + `a+'[`b'] + + - Method on File: close () + + - Method on File: setPosition (POSITION[, WHENCE]) + + - Method on File: getPosition () + + - Method on File: eof () + + - Method on File: read (SIZE) + + - Method on File: readln () + + - Method on File: readByte () + + - Method on File: toString () + + - Method on File: write (STRING) + + - Method on File: writeln (STRING) + + - Method on File: writeByte (BYTE) + + - Method on File: ungetByte (BYTE) + *Standard* + NGS JavaScript Interpreter 0.2.5 + + + - Method on File: flush () + + - Method on File: getLength () + + - Method on File: exists () + + - Method on File: error () + + - Method on File: clearError () + + - Property of File: autoFlush + *Standard* + NGS JavaScript Interpreter 0.2.5 + + Flag that specifies whether the stream should automatically flush + its buffers after a write. + + - Property of File: bufferSize + *Standard* + NGS JavaScript Interpreter 0.2.5 + + The I/O buffer size of the stream. The buffer size can be changed + at the runtime. + + +File: js.info, Node: Directory, Next: Function, Prev: File, Up: Native Objects + +Directory +--------- + +*Standard* + NGS JavaScript Interpreter 0.2.5 + + - Constructor: Directory (PATH) + + - Method on Directory: close () + + - Method on Directory: open () + + - Method on Directory: read () + + - Method on Directory: rewind () + + - Method on Directory: seek (POS) + + - Method on Directory: tell () + + +File: js.info, Node: Function, Next: Math, Prev: Directory, Up: Native Objects + +Function +-------- + + +File: js.info, Node: Math, Next: Number, Prev: Function, Up: Native Objects + +Math +---- + +*Standard* + ECMA-262 Version 2 draft 22-Apr-98 + + - Static Method on Math: abs (X) + + - Static Method on Math: acos (X) + + - Static Method on Math: asin (X) + + - Static Method on Math: atan (X) + + - Static Method on Math: atan2 (Y, X) + + - Static Method on Math: ceil (X) + + - Static Method on Math: cos (X) + + - Static Method on Math: exp (X) + + - Static Method on Math: floor (X) + + - Static Method on Math: log (X) + + - Static Method on Math: max (X, Y) + + - Static Method on Math: min (X, Y) + + - Static Method on Math: pow (X, Y) + + - Static Method on Math: random () + + - Static Method on Math: round (X) + + - Static Method on Math: seed (X) + *Standard* + NGS JavaScript Interpreter 0.2.5 + + + - Static Method on Math: sin (X) + + - Static Method on Math: sqrt (X) + + - Static Method on Math: tan (X) + + - Static Property of Math: E + + - Static Property of Math: LN10 + + - Static Property of Math: LN2 + + - Static Property of Math: LOG10E + + - Static Property of Math: LOG2E + + - Static Property of Math: PI + + - Static Property of Math: SQRT1_2 + + - Static Property of Math: SQRT2 + + +File: js.info, Node: Number, Next: Object, Prev: Math, Up: Native Objects + +Number +------ + +*Standard* + ECMA-262 Version 2 draft 22-Apr-98 + + - Function: Number() + Return value `0'. + + - Function: Number (VALUE) + + - Constructor: Number () + - Constructor: Number (VALUE) + Create a new number object. If no argument is given, the + constructor returns value `+0'. If the argument VALUE is given, + the constructor returns `ToNumber(VALUE)'. + + new Number (); + => 0 + new Number (3.1415); + => 3.1415 + new Number (true); + => 1 + + + - Method on Number: toString ([RADIX]) + Convert the number to its textual presentation. If the argument + RADIX is given, it specifies the radix to which the number is + formatted. If the argument RADIX is not given, it defaults to + `10'. + + System.stdout.writeln ((193).toString ()); + -| 193 + System.stdout.writeln ((193).toString (8)); + -| 301 + System.stdout.writeln ((193).toString (16)); + -| c1 + System.stdout.writeln ((193).toString (2)); + -| 11000001 + + - Method on Number: valueOf () + Return the value of the number object. + + - Static Property of Number: MAX_VALUE + + - Static Property of Number: MIN_VALUE + + - Static Property of Number: NaN + + - Static Property of Number: NEGATIVE_INFINITY + + - Static Property of Number: POSITIVE_INFINITY + + +File: js.info, Node: Object, Next: RegExp, Prev: Number, Up: Native Objects + +Object +------ + +*Standard* + ECMA-262 Version 2 draft 22-Apr-98 + +*Incompatibilities* + * The `toString()' and `toSource()' methods are missing. + + * The constructor doesn't set the [[Prototype]] and [[Class]] + properties. + + - Function: Object ([VALUE]) + + - Constructor: Object ([VALUE]) + Create a new object. + + var o = new Object (); + + - Method on Object: toString () + + - Method on Object: toSource () + + - Method on Object: valueOf () + + +File: js.info, Node: RegExp, Next: String, Prev: Object, Up: Native Objects + +RegExp +------ + +*Standard* + ECMA-262 Version 2 draft 22-Apr-98 + +*Incompatibilities* + * The regular expression engine - taken from the GNU Emacs - + might not support all features that are required. + + * XXX Check all methods and properties. + + - Constructor: RegExp (PATTERN[, FLAGS]) + Create a new regular expression from string PATTERN. The optional + argument string FLAGS can contain the following options: + + `i' + Ignore case; the matching is case-insensitive. + + `g' + Global search. This allows you to iterate over all matches + of the expression by executing the `exec' method multiple + times against the string. + + - Method on RegExp: compile (PATTERN[, FLAGS]) + Create a new regular expression from string PATTERN using optional + options FLAGS. The method can be used to change the regular + expression pattern or its flags in the regular expression object. + The method returns an error if the string PATTERN do not specify a + well-formed regular expression. + + *Note!* All regular expressions are always compiled in this + implementation. This holds also for the expressions, created with + the `RegExp()' constructor. + + var re = new RegExp ("ab*"); + re.compile ("ab*", "i"); + + - Method on RegExp: exec ([STRING]) + Match the expression against the string STRING. If the argument + STRING is omitted, the regular expression is matched against the + `RegExp.input' string. The method returns an array that holds the + matched portions of the expression. + + var re = new RegExp ("d(b+)(d)", "ig"); + var a = re.exec ("cdbBdbsbz"); + a.toString (); + => "dbBd,bB,d" + + In the previous example, the result array `a' has the following +items: + +`dbBd' + The substring that matched the regular expression. This string + can also be retrieved as `RegExp.lastMatch'. + +`bB' + The matched substring for the first parenthesized subexpression + `(b+)'. This match can also be found as `RegExp.$1'. + +`d' + The matched substring for the second parentsized subexpression + `(d)'. This match can also be found as `RegExp.$2'. + + The option `g' of the regular expression can be used to iterate over +multiple matches of the expression on at a time. For example, the +following code fragment searches for the expression `a(b*)' from the +string `str'. In the inial state - when the expression is create with +the constructor - the object's `lastIndex' property is set to 0. When +the expression is matched against the string, the `lastIndex' property +is updated to point to the next index from which the matching should be +continued. Therefore, the following example iterates over all matches +in the string `str'. + + var re = new RegExp ("a(b*)", "g"); + var str = "abbcdefabh"; + while (a = re.exec (str)) + System.print ("Found ", a, ". Next match starts at ", re.lastIndex, + ".\n"); + -| Found abb. Next match starts at 3. + -| Found ab. Next match starts at 9. + + The property `REGEXP.lastIndex' can also be set explicitly to start +the matching from a pre-defined position. + + - Method on RegExp: test ([STRING]) + Test whether the regular expression matches for the string STRING. + If the argument STRING is omitted, the regular expression is + tested against the `RegExp.input' string. + + var re = new RegExp ("fo*bar"); + re.test ("fbar"); + => true + re.test ("fooBar"); + => false + + re = new RegExp ("fo*bar", "i"); + re.test ("FOObAR"); + => true + + RegExp.input = "#include "; + re = new RegExp ("^#"); + re.test (); + => true + + - Static Property of RegExp: $1 + - Static Property of RegExp: $2 + - Static Property of RegExp: $3 + - Static Property of RegExp: $4 + - Static Property of RegExp: $5 + - Static Property of RegExp: $6 + - Static Property of RegExp: $7 + - Static Property of RegExp: $8 + - Static Property of RegExp: $9 + The matching substring for the n:th parenthesized subexpression. + If the latest regular expression didn't have that many + parenthesized subexpressions, the property has value `undefined'. + + - Static Property of RegExp: $_ + - Static Property of RegExp: input + The string against which the expression was tested. The `input' + property is also used, if no string argument was given for the + `test()' or `exec()' methods. + + var str = file.readln (); + re.test (str); + RegExp.input; + => THE STRING RETURNED BY THE `FILE.READLN()' METHOD. + + - Static Property of RegExp: lastMatch + The substring that matched the whole expression in the last regular + expression matching. + + - Static Property of RegExp: lastParen + The last parenthesized subexpression of the last regular expression + matching. + + - Static Property of RegExp: leftContext + The substring from the beginning of the input string to the + beginning of the matching substring of the last regular expression. + + var re = new RegExp ("foo"); + var str = "garbage foo tail garbage"; + re.exec (str); + RegExp.leftContext; + => "garbage " + + - Static Property of RegExp: multiline + + - Static Property of RegExp: rightContext + The substring from the end of the matching substring to the end the + input string. + + var re = new RegExp ("foo"); + var str = "garbage foo tail garbage"; + re.exec (str); + RegExp.rightContext; + => " tail garbage" + + - Property of RegExp: global + Flag that tells if the option `g' was given for the constructor or + for the `compile' method. + + - Property of RegExp: ignoreCase + Flat that tells if the option `i' was given for the construtor or + for the `compile' method. + + - Property of RegExp: lastIndex + The index from which the matching is continued with the global + (`g') expressions. + + - Property of RegExp: source + The source string from which the regular expression object was + created. + + +File: js.info, Node: String, Next: System, Prev: RegExp, Up: Native Objects + +String +------ + +*Standard* + ECMA-262 Version 2 draft 22-Apr-98 + +*Incompatibilities* + * The constructor doesn't set the [[Prototype]] and [[Class]] + properties. + + - Constructor: String (STRING) + Create a new string object and set its data to STRING. + + var str = new String ("Hello, world"); + => "Hello, world!" + + - Static Method on String: fromCharCode (CODE...) + Create a new string object from the character codes CODE.... + + var str = String.fromCharCode (72, 101, 108, 108, 111, 33); + => "Hello!" + + - Static Method on String: pack (FORMAT, ARG[, ...]) + *Standard* + NGS JavaScript Interpreter 0.2.5 + + Create a new string by packing values ARG... to a string according + to the format string FORMAT. + + The format is a sequence of characters that specify the type of + values as follows: + + `C' + an unsigned char value + + `n' + a short in "network" (big-endian) order + + `N' + a long in "network" (big-endian) order + + `d' + a double-precision float in the native format + + - Method on String: append (STRING) + *Standard* + NGS JavaScript Interpreter 0.2.5 + + Append string STRING to the end of the string object. The string + object must be a dynamic string, not a constant string literal. + + var str = new String (""); + str.append ("foo"); + str.append ("-"); + str.append ("bar"); + => "foo-bar" + + - Method on String: charAt (POSITION) + Create a new string that constains the character from position + POSITION of the the string object. + + "foobar".charAt (3); + => "b" + + - Method on String: charCodeAt (POSITION) + Return the code of the character at position POSITION in the + string object. + + "foobar".charCodeAt (3); + => 98 + + - Method on String: concat (STRING[, ...]) + Create a new string by appending the argument strings STRING, ... + to the end of the string object. + + "foo".concat ("bar"); + => "foobar" + + - Method on String: crc32 () + *Standard* + NGS JavaScript Interpreter 0.2.5 + + Count a 32-bit CRC of the string. + + var str = "Hello, world!"; + System.print ("CRC32 of \"", str, "\" is ", + str.crc32 ().toString (16), ".\n"); + -| CRC32 of "Hello, world!" is e4928064. + + - Method on String: indexOf (STRING[, START_INDEX]) + Return the index of the first substring of STRING within the + string object, or -1 if the string didn't contain the substring. + The optional argument START_INDEX can be used to specify the index + from which the searching is started. + + var str = "foobar foo bar foo"; + str.indexOf ("foo"); + => 0 + str.indexOf (" foo"); + => 6 + str.indexOf ("foo", 1); + => 7 + str.indexOf ("Foo"); + => -1 + + - Method on String: lastIndexOf (STRING[, START_INDEX]) + Return the the index of the last substring of STRING within the + string object, or -1 if the string didn't contain the substring. + The optional argument START_INDEX can be used to specify the index + from which the searching is started. + + var str = "foobar foo bar foo"; + str.lastIndexOf ("foo"); + => 15 + str.lastIndexOf ("bar"); + => 11 + str.lastIndexOf ("foo", 14); + => 7 + str.lastIndexOf ("Foo"); + => -1 + + - Method on String: match (REGEXP) + + - Method on String: replace (REGEXP, SUBSTITUTION) + + - Method on String: search (REGEXP) + + - Method on String: slice (START[, END]) + + - Method on String: split (SEPARTOR[, LIMIT]) + + - Method on String: substr (START[, LENGTH]) + + - Method on String: substring (START[, END]) + + - Method on String: toLowerCase () + Create a new string which contents is the data of the string + object, converted to the lower case. + + "FoObAr".toLowerCase (); + => "foobar" + + - Method on String: toUpperCase () + Create a new string which contents is the data of the string + object, converted to the upper case. + + "FoObAr".toUpperCase (); + => "FOOBAR" + + - Method on String: unpack (FORMAT) + *Standard* + NGS JavaScript Interpreter 0.2.5 + + + - Property of String: length + The length of the string. + + "foobar".length; + => 6 + var str = new String ("foo"); + str.append ("bar"); + str.length; + => 6 + + +File: js.info, Node: System, Next: VM, Prev: String, Up: Native Objects + +System +------ + +*Standard* + NGS JavaScript Interpreter 0.2.5 + + - Static Method on System: chdir (DIRECTORY) + Change the process' current working directory to DIRECTORY. The + function returns a boolean success status. + + - Static Method on System: error (ANY[, ...]) + Convert arguments ANY... to string and print the resulting string + to the standard error stream of the system. + + - Static Method on System: exit (CODE) + Terminate the program execution and return the value CODE to the + operating system as the return value of the running program. + Effectively the method performs C-code `exit (CODE)'. + + - Static Method on System: getcwd () + Get the current working directory of the process. The function + returns a strings presenting the directory or `false' if errors + were encountered. + + - Static Method on System: getenv (VARIABLE) + Return the value of the environment variable VARIABLE. The method + returns the value as a string or `undefined' if the variable was + not defined in the environment. + + - Static Method on System: popen (COMMAND, MODE) + + - Static Method on System: print (ANY[, ...]) + Convert arguments ANY... to string and print the resulting string + to the standard output stream of the system. + + - Static Method on System: sleep (SECONDS) + Stop the interpreter for SECONDS seconds. + + - Static Method on System: strerror (ERRNO) + Return a string that describes the system error code ERRNO. + + - Static Method on System: system (COMMAND) + + - Static Method on System: usleep (MICRO_SECONDS) + Stop the interpreter for MICRO_SECONDS micro seconds. + + - Static Property of System: bits + Return a value that describes the "bitness" of the underlying + system. Possible values might be `16', `32', `64', or even `128'. + Normally this is the size of a host system pointer in bits. + + - Static Property of System: canonicalHost + The canonical host name of the system where the interpreter was + compiled. + + System.stdout.writeln (System.canonicalHost); + -| powerpc-ibm-aix4.2.1.0 + + - Static Property of System: canonicalHostCPU + The CPU part of the canonical host name. + + System.stdout.writeln (System.canonicalHostCPU); + -| powerpc + + - Static Property of System: canonicalHostVendor + The Vendor part of the canonical host name. + + System.stdout.writeln (System.canonicalHostVendor); + -| ibm + + - Static Property of System: canonicalHostOS + The OS part of the canonical host name. + + System.stdout.writeln (System.canonicalHostOS); + -| aix4.2.1.0 + + - Static Property of System: errno + The system's error number. The error number can be converted to a + string with the `strerror()' method of the System object. + + var fp = new File ("output.txt"); + if (!fp.open ("w")) + System.error ("couldn't create output file `", fp, "': ", + System.strerror (System.errno), "\n"); + -| couldn't create output file `output.txt': Permission denied + + - Static Property of System: lineBreakSequence + The line break sequence that is used in the underlying system. For + example, the outputs from the following lines are identical: + + System.stdout.writeln ("Hello!"); + -| Hello! + System.stdout.write ("Hello!" + System.lineBreakSequence); + -| Hello! + + + - Static Property of System: stderr + The system's standard error stream. This is a normal JavaScript + file and all methods of the File object can be called for it. + + System.stderr.writeln ("panic: must exit"); + System.exit (1); + -| panic: must exit + + - Static Property of System: stdin + The system's standard input stream. + + - Static Property of System: stdout + The system's standard output stream. + + +File: js.info, Node: VM, Prev: System, Up: Native Objects + +VM +-- + +*Standard* + NGS JavaScript Interpreter 0.2.5 + + - Static Method on VM: garbageCollect () + Perform a garbage collection for the virtual machine heap. + Normally, the garbage collection is triggered automatically, but + the `garbageCollect()' method can be used to trigger the collection + explicitly. + + - Static Method on VM: stackTrace ([LIMIT]) + Print the contents of the virtual machine stack. Optional argument + LIMIT specifies how many stack frames are printed. If no + arguments are given, the whole virtual machine stack is printed. + + function recursive (n) + { + if (n > 5) + VM.stackTrace (); + else + recursive (n + 1); + } + + recursive (0); + -|VM: stacktrace: stacksize=2048, used=78 + -|#0 recursive(): builtin 0 + -|#1 recursive(): null 1 6 + -|#2 recursive(): null 1 5 + -|#3 recursive(): null 1 4 + -|#4 recursive(): null 1 3 + -|#5 recursive(): null 1 2 + -|#6 recursive(): null 1 1 + -|#7 .global(): null 1 0 + + - Static Property of VM: dispatchMethod + The name of the dispatch method, currently used in the virtual + machine. The method returns a string that describes the method. + The possible return values are `switch-basic', `switch', and + `jumps'. + + - Static Property of VM: gcCount + How many times the garbage collection has been performed for the + heap. + + - Static Property of VM: gcTrigger + The garbage collection trigger. When the virtual machine heap has + allocated more than `gcTrigger' number of bytes of memory, the + virtual machine will perform a garbage collection. + + - Static Property of VM: heapAllocated + The number of bytes of memory the system has allocated from the + heap. + + - Static Property of VM: heapFree + The number of bytes of memory the heap freelist contains. + + - Static Property of VM: heapSize + The size of the heap in bytes. + + - Static Property of VM: numConstants + The number of constants defined in the virtual machine. + + - Static Property of VM: numGlobals + The number of global symbols defined in the virtual machine. This + value equals to the number of global variables and functions, + defined in the system. + + - Static Property of VM: stackSize + The size of the virtual machine stack. + + - Static Property of VM: stacktraceOnError + A boolean flag that tells whether the virtual machine stack trace + is printed if an error occurs in the program execution. + + - Static Property of VM: verbose + The verbosity level of the virtual machine. + + - Static Property of VM: verboseStacktrace + A boolean flag that tells whether the virtual machine prints the + normal or verbose stacktrace. + + - Static Property of VM: version + The version string of the interpreter virtual machine. + + - Static Property of VM: versionMajor + The major version number of the virtual machine. + + - Static Property of VM: versionMinor + The minor version number of the virtual machine. + + - Static Property of VM: versionPatch + The patch level number of the virtual machine. + + - Static Property of VM: warnUndef + A boolean flag that tells whether the virtual machine should print + a warning message if an undefined variable is used. + + +File: js.info, Node: Extensions, Prev: Native Objects, Up: NGS JavaScript Language + +Extensions +========== + +* Menu: + +* Curses:: +* JS:: +* MD5:: + + +File: js.info, Node: Curses, Next: JS, Prev: Extensions, Up: Extensions + +Curses +------ + + +File: js.info, Node: JS, Next: MD5, Prev: Curses, Up: Extensions + +JS +-- + + - Constructor: JS () + + - Method on JS: compile (FILE, ASM_FILE, BC_FILE) + + - Method on JS: eval (STRING) + + - Method on JS: evalFile (FILENAME) + + - Method on JS: evalJavaScriptFile (FILENAME) + + - Method on JS: executeByteCodeFile (FILENAME) + + - Method on JS: getVar (NAME) + + - Method on JS: setVar (NAME, VALUE) + + - Property of JS: errorMessage + diff --git a/reactos/lib/kjs/docs/js.info-2 b/reactos/lib/kjs/docs/js.info-2 new file mode 100644 index 00000000000..27e2263436f --- /dev/null +++ b/reactos/lib/kjs/docs/js.info-2 @@ -0,0 +1,1635 @@ +This is Info file js.info, produced by Makeinfo version 1.68 from the +input file js.texi. + +INFO-DIR-SECTION NGS JavaScript Interpreter +START-INFO-DIR-ENTRY +* libjs: (js). The JavaScript interpreter library. +* js: (js)The js Program. JavaScript interpreter. +END-INFO-DIR-ENTRY + + This file documents NGS JavaScript interpreter 0.2.5 + + Copyright (C) 1998 New Generation Software (NGS) Oy + + Permission is granted to make and distribute verbatim copies of this +manual provided the copyright notice and this permission notice are +preserved on all copies. + + Permission is granted to copy and distribute modified versions of +this manual under the conditions for verbatim copying, provided that +the entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + + Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that this permission notice may be stated in a +translation approved by the Foundation. + + +File: js.info, Node: MD5, Prev: JS, Up: Extensions + +MD5 +--- + + - Constructor: MD5 () + Create a new MD5 message digest object. + + var md5 = new MD5 (); + + - Method on MD5: final () + Return the MD5 value of the data, set to the object with the + `update()' method. The method returns a 32 bytes long string that + holds the MD5 value as a hexadecimal number. + + function print_md5 (str) + { + var md5 = new MD5 (); + md5.update (str); + System.print ("MD5 of \"", str, "\" is ", + md5.final (), ".\n"); + } + print_md5 ("Hello, world!"); + -| MD5 of "Hello, world!" is 6CD3556DEB0DA54BCA060B4C39479839. + + - Method on MD5: finalBinary () + Return the MD5 value of the data. The method returns a 128 bits + long MD5 value. + + - Method on MD5: init () + Initalize the object to the initial state. The method can be used + to reset the object after some data has been set to it with the + `update()' method. + + - Method on MD5: update (STR) + Append data to the object. The method can be called multiple + times, so that the MD5 message digest can be counted one block at + a time. + + function count_md5_for_file (stream) + { + var md5 = new MD5 (); + + while (!stream.eof ()) + { + var data = stream.read (1024); + md5.update (data); + } + + return md5.final (); + } + + +File: js.info, Node: The js Program, Next: The jsas Program, Prev: NGS JavaScript Language, Up: Top + +The `js' Program +**************** + + The `js' program is the JavaScript interpreter command. It can be +used to execute JavaScript and JavaScript byte-code files. The progam +can also be used to compile JavaScript files into the byte-code files. + +* Menu: + +* Invoking The js Program:: +* Evaluating and Executing Code:: +* Compiling JavaScript Code:: + + +File: js.info, Node: Invoking The js Program, Next: Evaluating and Executing Code, Prev: The js Program, Up: The js Program + +Invoking The `js' Program +========================= + + The `js' program is invoked as: + + `js' OPTION... FILE [ARGUMENT...] + +The `js' program processes the command line options and when the first +non-option argument, or the option `--file', is encountered, it is +assumed to contain JavaScript or byte-code that should be evaluated. +The interpreter will pass all remaining arguments to the script +throught the `ARGS' array. The items in the array are strings +containing the arguments ARGUMENT.... The first item of the array is +always the name of the script FILE. + + The options can be one or more of the following command line options: + +`-a' +`--annotate-assembler' + Annotate the created assembler listing with the original JavaScript + source code. The option can be used only with the `--assembler' + option. + +`-c' +`--compile' + Compile JavaScript files to byte-code. The generated byte-code is + saved to file which name is created from the name of the input + file by replacing the suffix `.js' with the suffix `.jsc'. The + compilation can be controlled with options `--debug', + `--optimize', and `--compiler-option'. + +`-d TYPE' +`--dispatch=TYPE' + Use the byte-code instruction dispatch method TYPE. The current + implementation supports the following dispatch methods: + + `switch-basic' + The basic switch-method using a big switch-case table to + dispatch the instruction. This method is available only if + the interpreter has been configured with the option + `--with-all-dispatchers'. + + `switch' + An optimized version of the switch-method. This method is + supported on all environments. + + `jumps' + The fastest dispatch method that uses the `computed goto' + statement of the GNU C-compiler. This method is available if + the interpreter has been compiler with the GNU C-compiler. + + The default dispatch method, for environments that has the GNU + C-compiler, is `jumps'. For all other environments, the default + method is `switch'. + +`-e CODE' +`--eval=CODE' + Evaluate JavaScript code CODE. + + $ js --eval='System.print ("Hello, world!\n");' + -| Hello, world! + +`-E' +`--events' + Print the interpreter events to the standard error. + + $ js -E -c test.js + [js: garbage collect] + [js: garbage collect] + [js: garbage collect] + [js: garbage collect] + +`-f' +`--file' + Stop processing options and use the next argument as the name of + the JavaScript (or byte-code) file. All the remaining arguments + are passed to the interpreter through the `ARGS' array. The first + item of the array will be the name of the script, i.e. the + argument that follows the option `--file'. + + $ cat hello.js + -| var i; + -| for (i = 0; i < ARGS.length; i++) + -| System.print (i, ": ", ARGS[i], "\n"); + $ js --file hello.js a b c d + -| 0: hello.js + -| 1: a + -| 2: b + -| 3: c + -| 4: d + + The option can also be used with the option `--load' to indicate + the last file to load. Also in that case, the remaining arguments + will be passed to the script through the `ARGS' array. + +`-g' +`--debug' + Make the compiler to generate debugging information to the + generated byte-code files. This option can be used with the option + `--compile'. + +`-h' +`--help' + Print a short help message that describes the options that can be + given to the `js' program. + +`-l' +`--load' + Load multiple JavaScript and JavaScript byte-code files to the + interpreter. Normally, the first non-option argument is evaluated + and all remaining arguments are passed to the script as arguments. + With the option `--load', multiple files can be loaded the to the + interpreter. The loading can be stopped with option `--file' that + specifies the last file to load. + + For example, if we have files `a.js': + + function do_a () + { + System.print ("do_a()\n"); + } + + `b.js': + + function do_b () + { + System.print ("do_b()\n"); + } + + and `main.js': + + do_a (); + do_b (); + + the whole application can be run as: + + $ js --load a.js b.js --file main.js ARGUMENTS... + -| do_a() + -| do_b() + +`-N' +`--no-compiler' + Do not define the compiler to the virtual machine. This option + makes the interpreter smaller, but the interpreter can only execute + pre-compiled byte-code files. The option disables the `eval' + global method. + +`-O [LEVEL]' +`--optimize[=LEVEL]' + Set the compiler optimization level to LEVEL. The compiler has + three different optimization levels: + + `0' + Do not optimize. + + `1' + Perform all cheap optimizations which do not required heavy + assembler instruction analyzing. + + `2' + Perform all optimizations, supported by the compiler. + + The default optimization level is 1. + +`-r OPTION' +`--secure=OPTION' + Turn on virtual machine security option OPTION. The following + security options are available: + + `file' + Disable insecure methods from the buit-in File object. + + `system' + Disable insecure methods from the buit-in System object. + +`-s SIZE' +`--stack-size=SIZE' + Set the size of the virtual machine operand stack to SIZE. The + size of the virtual machine operand stack is set at the + startup-time and it can't be enlarged dynamically at the runtime. + +`-S' +`--assembler' + Compile JavaScript files to JavaScript assembler. The generated + assembler listing is saved to file which name is created from the + name of the input file by replacing the suffix `.js' with the + suffix `.jas'. The compilation can be controlled with options + `--optimize', and `--compiler-option'. + +`-t' +`--stacktrace' + Print a stack trace on error. When an error occurs during the + evaluation of a script, the virtual machine will halt and the `js' + program terminates. If the option `--stacktrace' was given to the + interpreter, the virtual machine will print a stack trace that + shows the call stack at the point of the error. + + The following listing showns an program that raises an error at the + specified recursion level. + + function recursive (level) + { + if (level <= 0) + error ("recursion limit exceeded"); + else + recursive (level - 1); + } + + recursive (5); + + If the program is executed without the `--stacktrace' option, the + following result is shown: + + $ js hello.js + js: evaluation of file `hello.js' failed: + hello.js:6: recursion limit exceeded + + With the `--stacktrace' option, the `js' program will print the + following error message: + + $ js --stacktrace hello.js + -| VM: error: hello.js:6: recursion limit exceeded + -| VM: stacktrace: stacksize=2048, used=44 + -| #0 recursive(): null 1 "recursion limit exceeded" + -| #1 recursive(): null 1 0 + -| #2 recursive(): null 1 1 + -| #3 recursive(): null 1 2 + -| #4 recursive(): null 1 3 + -| #5 recursive(): null 1 4 + -| #6 .global(): null 1 5 + -| js: evaluation of file `hello.js' failed: + -| hello.js:6: recursion limit exceeded + +`-v' +`--verbose' + Increase the verbosity of the interpreter. The option can be given + multiple times to increase the amount of messages the interpreter + prints. + +`-V' +`--version' + Print the version number of the `js' program. + +`-W OPTION' +`--compiler-option=OPTION' + Set JavaScript compiler options according to the option + specification OPTION. The specification OPTION can be given in + two forms. In the normal form, the option specifies a compiler + option that should be set on. If the specification OPTION starts + with the prefix ``no-'', the specified option will be turn off. + The following option specifications are currently implemented: + + `all' + match most of the compile time options + + `pedantic' + match all compile time options. This option generates as + much warnings as possible. It will also complain about some + things that are allowed by the ECMAScript standard, but which + are consired to show bad programming style, for example, + missing semicolons. + + `runtime' + match all runtime options + + `shadow' + warn if a variable declaration shadows a parameter + + `undefined' + runtime check for undefined global variables + + `unused-argument' + warn about unused arguments + + `unused-variable' + warn about unused local variables + + `with-clobber' + warn if the with-lookup of a symbol is clobbered because the + symbol is defined to be a local variable or a function + argument + + `missing-semicolon' + warn about missing semicolons that are fixed by the missing + semicolon inserting during the compilation + + `strict-ecma' + warn about things that are supported by this implementation, + but are not allowed by the ECMAScript standard. These + features are: + + * line terminators in string and regular expression + constants + + `deprecated' + warn if deprecated features has been used in the source code + +`-x' +`--executable' + Add execute permissions to the generated byte-code files. This + option is useful on Linux environments where JavaScript byte-code + files can be executed natively with the `binfmt_js' module. + + $ cat hello.js + -| System.stdout.writeln ("Hello, world!"); + $ js -cx hello.js + $ ./hello.jsc + -| Hello, world! + + +File: js.info, Node: Evaluating and Executing Code, Next: Compiling JavaScript Code, Prev: Invoking The js Program, Up: The js Program + +Evaluating and Executing Code +============================= + + +File: js.info, Node: Compiling JavaScript Code, Prev: Evaluating and Executing Code, Up: The js Program + +Compiling JavaScript Code +========================= + + The compilation of JavaScript code is carried out with the following +command: + + `js' [OPTIONS] `-c' FILE... + +where FILE is a JavaScript source file to compile and OPTIONS specify +additional compiler options. + + In the simplest form, the compilation goes as follows: + + $ js -c hello.js + +This example compiles file `hello.js' to byte-code file `hello.jsc' +with the default compiler options. + +* Menu: + +* Warning Messages:: +* Optimization:: +* Debugging Information:: +* Assembler Listings:: + + +File: js.info, Node: Warning Messages, Next: Optimization, Prev: Compiling JavaScript Code, Up: Compiling JavaScript Code + +Warning Messages +---------------- + + It is nice to get as many error messages as possible at the +compilation time. However, sometimes some error messages are false and +it is annoying to see them every time you compile your project. The +option `--compiler-option' can be used to adjust the level of warning +messages the compiler generates. + + Normally we want to get all possible compiler time warnings. They +can be enable with the `-Wall' option. To set the warnings +individually, the following options can be given for the +`--compiler-option' option. The option names can be prefixed with +string `no-' to turn them off instead of setting them. For example, +let's assume that we want to get as much warnings as possible, but we +do not care about unused function arguments: + + $ js -Wall -Wno-unused-arguments -c hello.js + +In this example, we turn on all warnings `-Wall', but we turn off +warnings about unused arguments `-Wno-unused-arguments'. + + The `js' program knows the following warning options: + +`shadow' + Warn if a variable declaration shadows a parameter. For example, + when compiling file `test.js' containing code: + + function foo (a, b) + { + var a = 1; + return a + b; + } + + the following warning is generated: + + $ js -Wshadow -c test.js + -| test.js:3: warning: declaration of `a' shadows a parameter + +`unused-argument' + Warn if an argument is not used in the function body. For + example, when compiling file `test.js' containing code: + + function foo (a, b) + { + return a + 5; + } + + the following warning is generated: + + $ js -Wunused-argument -c test.js + -| test.js:1: warning: unused argument `b' + +`unused-variable' + Warn if a local variable is not used in the function body. For + example, when compiling file `test.js' containing code: + + function foo (a, b) + { + var c; + return a + b; + } + + the following warning is generated: + + $ js -Wunused-variable -c test.js + -| test.js:3: warning: unused variable `c' + +`with-clobber' + Warn if the with-lookup of a symbol is clobbered because the + symbol is defined to be a local variable or a function argument. + For example, when compiling file `test.js' containing code: + + function foo (PI) + { + with (Math) + System.print ("PI=", PI, "\n"); + } + + the following warning is generated: + + $ js -Wwith-clobber -c test.js + -| test.js:4: warning: the with-lookup of symbol `PI' is + -| clobbered by the argument definition + +`missing-semicolon' + Warn if a semicolon is missing from the input. The missing + semicolons are inserted during the parsing by the automatic + semicolon inserting. However, since the missing semicolons show + bad programming style, this option will warn about them. For + example, when compiling file `test.js' containing code: + + function foo () + { + return 1 + } + + foo () + + the following warnings are generated: + + $ js -Wmissing-semicolon -c test.js + test.js:3: warning: missing semicolon + test.js:6: warning: missing semicolon + +`strict-ecma' + warn about things that are supported by this implementation, but + are not allowed by the ECMAScript standard. For example, when + compiling file `test.js' containing code: + + function foo () + { + System.stdout.writeln ("Hello, world! + "); + } + + the following warning is generated: + + $ js -Wstrict-ecma -c test.js + test.js:3: warning: ECMAScript don't allow line terminators in + string constants + +`deprecated' + warn if deprecated features has been used in the source code. For + example, when compiling file `test.js' containing code: + + function foo () + { + for (var i in arguments) + System.stdout.writeln (i); + } + + the following warning is generated: + + $ js -Wdeprecated -c test.js + test.js:1: warning: the `arguments' property of Function instance + is deprecated + + Besides the compiler time checks, the virtual machine can also +perform some checks at the runtime. These checks can be set and unset +with the `-Wruntime' option. + + The following runtime warnings are supported: + +`undefined' + Warn if the value of an undefined global variable is used. For + example, when running file `test.js' containing code: + + foo = an_undefined_variable; + + the following warning is generated: + + $ js test.js + -| VM: warning: using undefined global `an_undefined_variable' + + +File: js.info, Node: Optimization, Next: Debugging Information, Prev: Warning Messages, Up: Compiling JavaScript Code + +Optimization +------------ + + +File: js.info, Node: Debugging Information, Next: Assembler Listings, Prev: Optimization, Up: Compiling JavaScript Code + +Debugging Information +--------------------- + + As a default, the JavaScript compiler do not include symbolic +debugging information to the generated byte-code files. The debugging +information can be generated by giving the compiler `-g' option. The +debugging information is also generated for the internal byte-code +files that are created when the interpreter evaluates plain JavaScript +source code. + + In the current implementation, the debugging information contains +only the names of the source files, and mappings from the virtual +machine program counter offsets to the source file locations. In the +future, it will contain information about local variables and function +arguments, so that the symbolic debugger can print their values. + + The presence of the debugging information shows in the error messages +the interpreter shows. For example, let's consider the following +JavaScript source code file `test.js': + + function foo (a) + { + a += 1; + if (a > 50) + error ("a overflow"); + + return 1; + } + + foo (50); + + When this file is compiled to the byte-code without debugging +information, the following error message is raised: + + $ js -c test.js + $ js test.jsc + -| js: evaluation of file `test.jsc' failed: + -| a overflow + + If we recompile the file with the debugging information, we will get +a more precise error message from the interpreter: + + $ js -g -c test.js + $ js test.jsc + -| js: evaluation of file `test.js' failed: + -| test.js:5: a overflow + +Now we see the exact source code location where the error occurred. + + The debugging information can be removed from the byte-code files +after the compilation with the `jsdas' program. + + $ jsdas --strip test.jsc + test.jsc: + jsdas: removing section 3 + $ js test.jsc + js: evaluation of file `test.jsc' failed: + a overflow + + +File: js.info, Node: Assembler Listings, Prev: Debugging Information, Up: Compiling JavaScript Code + +Assembler Listings +------------------ + + The JavaScript compiler can generate assembler listings from the +JavaScript source files. The assembler listings are generated just +before the resulting byte-code data would be generated. So the resulting +assembler listing is exactly the same that will be in the resulting +byte-code data. The assembler listing is generated with the +`--assembler' option. For example, if we have a source file `hello.js' +with the following contents: + + function hello () + { + System.stdout.writeln ("Hello, world!"); + return true; + } + + hello (); + +it can be compiled to assembler with command + + $ js -S hello.js + +The command will save the assembler listing in file `hello.jas': + + hello: + load_arg 1 + add_2_i + min_args 2 + const "Hello, world!" + const_i1 + load_global System + load_property stdout + call_method writeln + pop_n 4 + const_true + return + + .global: + const_i0 + const_null + jsr hello + apop 2 + + The option `--annotate-assembler' can be used with the `--assembler' +option. It mixes the original source code to the generated assembler +listing. In this format, it is easy to see how different JavaScript +constructs are compiled in the assembler. Our example file can be +compiled to the annotated assembler with the following command: + + $ js -a -S hello.js + +The result listing is saved to file `hello.jas': + + ; -*- asm -*- + ; function hello () + + hello: + ; { + load_arg 1 + add_2_i + min_args 2 + ; System.stdout.writeln ("Hello, world!"); + const "Hello, world!" + const_i1 + load_global System + load_property stdout + call_method writeln + pop_n 4 + ; return true; + const_true + return + ; } + ; + ; hello (); + + .global: + const_i0 + const_null + jsr hello + apop 2 + + +File: js.info, Node: The jsas Program, Next: The jsdas Program, Prev: The js Program, Up: Top + +The `jsas' Program +****************** + + The `jsas' program is a assembler for the JavaScript assembler. The +program can be used to compile assembler files into byte-code. + +* Menu: + +* Invoking The jsas Program:: + + +File: js.info, Node: Invoking The jsas Program, Prev: The jsas Program, Up: The jsas Program + +Invoking The `jsas' Program +=========================== + + The `jsas' program is invoked as: + + `jsas' OPTION... FILE... + + The program reads the options and processes the assembler files +FILE... according to the options. The options can be one of more of the +following command line options: + +`-g' +`--debug' + Make the assembler to generate debugging information to the + generated byte-code files. + +`-h' +`--help' + Print a short help message that describes the options that can be + given to the `jsas' program. + +`-O' +`--optimize' + Optimize the assembler instructions. + +`-v' +`--verbose' + Turn on verbose diagnostic messages. When this options is given, + the `jsas' program tells what it is doing. + +`-V' +`--version' + Print the version number of the `jsas' program. + + +File: js.info, Node: The jsdas Program, Next: The jswrap Program, Prev: The jsas Program, Up: Top + +The `jsdas' Program +******************* + + The `jsdas' program is a disassembler and a manipulator for the +JavaScript byte-code files. The program can be used to view, +disassemble and manipulate the byte-code files. + +* Menu: + +* Invoking The jsdas Program:: +* Viewing Byte-Code Files:: +* Manipulating Byte-Code Files:: + + +File: js.info, Node: Invoking The jsdas Program, Next: Viewing Byte-Code Files, Prev: The jsdas Program, Up: The jsdas Program + +Invoking The `jsdas' Program +============================ + + The `jsdas' program is invoked as: + + `jsdas' OPTION... FILE... + + The program reads the options and processes the byte-code files +FILE... according to the options. The options can be one or more of +the following command line options: + +`-c' +`--code' + Print the code section of the byte-code files. This is the default + action that is preformed if no options are given for the `jsdas' + program. + +`-C' +`--constants' + Print the constants section of the byte-code file. + +`-d' +`--debug' + Print the debug section of the byte-code file. + +`-h' +`--help' + Print a short help message that describes the options that can be + given to the `jsdas' program. + +`-i' +`--info' + Print the byte-code file information. + +`-l TYPE DATA' +`--link TYPE DATA' + Link a new section to the byte-code file. The section's type is + TYPE and its contents is read from file DATA. + +`-r TYPE' +`--remove TYPE' + Remove section of type TYPE from the byte-code files. + +`-s' +`--symtab' + Print the symbol table section of the byte-code file. + +`-S' +`--strip' + Remove the debug section from the byte-code files. + +`-V' +`--version' + Print the version number of the `jsdas' program. + + +File: js.info, Node: Viewing Byte-Code Files, Next: Manipulating Byte-Code Files, Prev: Invoking The jsdas Program, Up: The jsdas Program + +Viewing Byte-Code Files +======================= + + In this section we assume that we have a source file `hello.js' with +the following contents: + + function main () + { + System.print ("Hello, world!\n"); + } + + main (); + + The file has been compiled to byte-code file `hello.jsc' with the +following command: + + $ js -Wall -g -c hello.js + + The option `--info' is used to view the contents of the byte-code +file. For example, our example file contains the following information: + + $ jsdas --info hello.jsc + hello.jsc: + + * byte-code file information + + section 0: type=0 (code), length=34 + section 1: type=1 (constants), length=40 + section 2: type=2 (symtab), length=25 + section 3: type=3 (debug), length=40 + +We see that the byte-code file has four sections: code, constants, +symtab and debug. The listing shows also their lengths. The sections +are: + +`code' + the byte-code instructions of the file + +`constants' + the constant values of the file + +`symtab' + the symbol table + +`debug' + the debugging information + + Next, we would like to see a assembler listing of the byte-code, +defined in the `code' section of the file. This can be viewed with the +option `--code' that is the `jsdas''s default option (so no options for +the following example). + + $ jsdas hello.jsc + hello.jsc: + + * section `Code' + + main: + 0 load_arg 1 + 2 add_2_i + 3 min_args 2 + 5 const "Hello, world!\n" + 10 const_i1 + 11 load_global System + 16 call_method print + 21 pop_n 4 + 23 const_undefined + 24 return + + .global: + 25 const_i0 + 26 const_null + 27 jsr main + 32 apop 2 + + The constants section holds the constant data the byte-code +instructions need. These constants are pushed to the stack with the +`const' byte-code operand, or they are used to name a symbol in method +invocation or in subroutine call. + + The constant section can be viewed with the `--constants' option. + + $ jsdas --constants hello.jsc + hello.jsc: + + * section `Constants' + + 0: "Hello, world!\n" + 1: System + 2: print + 3: main + + Our example file defines four constants. A string `Hello, world!\n' +and three symbols `System', `print', and `main'. + + The debugging information holds line number information about the +source file from which the file was compiled. The debugging section +can be viewed with the option `--debug': + + $ jsdas --debug hello.jsc + hello.jsc: + + * section `Debug' + + 2 hello.js:2 + 10 hello.js:3 + 26 hello.js:6 + + The symbol table hold the information about the global symbols the +byte-code file defines. For each symbol, the symbol table has an offset +that points to the appropriate location in the byte-code instruction +stream. + + The symbol table information can be viewed with the `--symtab' +option: + + $ jsdas --symtab hello.jsc + hello.jsc: + + * section `Symtab' + + main 0 + .global 25 + + +File: js.info, Node: Manipulating Byte-Code Files, Prev: Viewing Byte-Code Files, Up: The jsdas Program + +Manipulating Byte-Code Files +============================ + + $ jsdas --link 7001 hello.js hello.jsc + hello.jsc: + jsdas: linking 67 bytes of data to section 7001 + $ jsdas --info hello.jsc + hello.jsc: + + * byte-code file information + + section 0: type=0 (code), length=34 + section 1: type=1 (constants), length=40 + section 2: type=2 (symtab), length=25 + section 3: type=3 (debug), length=40 + section 4: type=7001, length=67 + + $ jsdas --remove 3 hello.jsc + hello.jsc: + jsdas: removing section 3 + $ jsdas --remove 7001 hello.jsc + hello.jsc: + jsdas: removing section 7001 + $ jsdas -i hello.jsc + hello.jsc: + + * byte-code file information + + section 0: type=0 (code), length=34 + section 1: type=1 (constants), length=40 + section 2: type=2 (symtab), length=25 + + +File: js.info, Node: The jswrap Program, Next: JavaScript API, Prev: The jsdas Program, Up: Top + +The ``jswrap'' Program +********************** + + The `jswrap' program is a tool that helps implementing C functions +in JavaScript. + +* Menu: + +* Invoking The jswrap Program:: +* Definition File Format:: +* Re-Entrant Functions:: +* Calling the Functions from C:: +* Sample Project:: + + +File: js.info, Node: Invoking The jswrap Program, Next: Definition File Format, Prev: The jswrap Program, Up: The jswrap Program + +Invoking The `jswrap' Program +============================= + + The `jswrap' program is invoked as: + + `jswrap' OPTIONS... FILE + +The `jswrap' program processes the command line options and according +to them and the default values, it converts the input file FILE to the +corresponding `.h' and `.c' files. The options can be one of more of +the following command line options: + +`-g' +`--debug' + Generate debugging information to the generated JavaScript + byte-code. + +`-h FILE' +`--header FILE' + Generate the C header file to file FILE. The default C header + file name is constructed from the input file name by replacing the + suffix `.jsw' with suffix `.h'. + +`-n' +`--no-error-handler' + Do not generate the default error handler to the generated C + files. If this option is specified, then the error handler must + be defined in your code. + +`-o' +`--output FILE' + Generate the C output to file FILE. The default output file name + is constructed from the input file name by replacing the suffix + `.jsw' with suffix `.c'. + +`-r' +`--reentrant' + Generate re-entrant C functions. The option adds a ``JSInterpPtr'' + argument to all C functions it generates. + +`-V' +`--version' + Print the version number of the `jswrap' program. + +`--help' + Print a short help message that describes the options that can be + given to the `jswrap' program. + + +File: js.info, Node: Definition File Format, Next: Re-Entrant Functions, Prev: Invoking The jswrap Program, Up: The jswrap Program + +Definition File Format +====================== + + The definition file contains the function definitions and their +implementation in JavaScript. The function definitions are normal +JavaScript function definitions but they are extended with the type +information. The type information is used to generate the C header +files and the glue code that is used in the function call. The +definition file can also contain normal JavaScript comments. The +comments are ignored and they are not copied to the generated C header +and implementation files. + + The syntax of the function definition is: + + function [RETURN_TYPE] FUNCTION_NAME `('ARGUMENT_TYPE... ARGUMENT[, ...]`)' + { + JAVASCRIPT CODE IMPLEMENTING THE FUNCTION. + } + +Where: + +RETURN_TYPE + specifies the return type of the function. If the return type + specification is omitted, the function is a `void' function + returning no value. + +FUNCTION_NAME + is the name of the function. The name must be a valid C identifier + matching regular expression ``^[A-Za-z_][A-Za-z_0-9]*''. + +ARGUMENT_TYPE + specifies the type of the argument, its passing type, and the life + scope of the value of the argument. + +ARGUMENT + is the name of the argument. The name must be a valid C + identifier. + +* Menu: + +* The Type Specifiers:: +* The Pass-Type Specifiers:: +* The Life Scope Specifiers:: + + +File: js.info, Node: The Type Specifiers, Next: The Pass-Type Specifiers, Prev: Definition File Format, Up: Definition File Format + +The Type Specifiers +------------------- + + The type specifiers specify the native C and JavaScript type that is +used for the argument or for the return value. The following type are +supported: + +`cstring' + A `'\0'' terminated C-string. In the C, this is presented as + ``char *''. In the JavaScript, this is a normal string. + +`double' + A floating point number. In the C, this is a ``double'' floating + point number. + +`int' + An integer Number. In the C, this is a ``long'' integer. + +`string' + An arbitrary data block. In the C, this is presented as ``unsigned + char *', `unsigned int'' pair. In the JavaScript, this is a normal + string. *Note!* Because the type's presentation in C is two + types, this value can't be used as a return value of a function. + + The following example shows how the types are converted to the +corresponding C header file. The input file `types.jsw' is as follows: + + function types (cstring vcstring, double vdouble, int vint, + string vstring) + { + } + + The resulting C header file `types.h' contains the following +definitions for the function `types': + + void types ( + char *vcstring, + double vdouble, + long vint, + unsigned char *vstring, + unsigned int vstring_len + ); + + +File: js.info, Node: The Pass-Type Specifiers, Next: The Life Scope Specifiers, Prev: The Type Specifiers, Up: Definition File Format + +The Pass-Type Specifiers +------------------------ + + The passing type specifiers specify how the argument is passed to the +function. The following specifies are supported: + +`in' + An input argument. This is the default pass-type for arguments. + +`out' + An output argument. In the JavaScript, the initial value of the + argument is `undefined'. When the control returns from the + implementation of the function, the argument's current value is + returned to the calling C function. + + In the C, the output and input-output arguments are presented as + pointers to the variables, containing the values. + +`inout' + An input-output argument. + + The following example shows show the output and input-output +arguments are presented in the C header file. The input file +`pass.jsw' is as follows: + + function pass (out cstring vcstring, out double vdouble, inout int vint, + inout string vstring) + { + } + + The resulting C header file `pass.h' contains the following +definitions for the function `pass': + + void pass ( + char **vcstring, + double *vdouble, + long *vint, + unsigned char **vstring, + unsigned int *vstring_len + ); + + +File: js.info, Node: The Life Scope Specifiers, Prev: The Pass-Type Specifiers, Up: Definition File Format + +The Life Scope Specifiers +------------------------- + + The life scope specifiers specify the liveness of the value, passed +in an argument. The following specifiers are supported: + +`static' + The argument points to static data that can't change while the + execution is in the JavaScript code. This means that the + JavaScript can use the same data that is given to it; it don't + have to make a private copy of the data. The specifier can only + be used with `cstring' and `string' types. + + The specifier don't have any affect for the generated C header + file. + + +File: js.info, Node: Re-Entrant Functions, Next: Calling the Functions from C, Prev: Definition File Format, Up: The jswrap Program + +Re-Entrant Functions +==================== + + +File: js.info, Node: Calling the Functions from C, Next: Sample Project, Prev: Re-Entrant Functions, Up: The jswrap Program + +Calling the Functions from C +============================ + + +File: js.info, Node: Sample Project, Prev: Calling the Functions from C, Up: The jswrap Program + +Sample Project +============== + + function hello (cstring user) + { + System.stdout.writeln ("Hello, " + user + "!"); + } + + function int max_sum (int a, int b, int out sum) + { + sum = a + b; + + return a > b ? a : b; + } + + $ jswrap sample.jsw + + /* This file is automatically generated from `hello.jsw' by jswrap. */ + + #ifndef HELLO_H + #define HELLO_H + + void hello ( + char *user + ); + + int max_sum ( + int a, + int b, + int *sum + ); + + #endif /* not HELLO_H */ + + #include + #include "hello.h" + + JSInterpPtr jswrap_interp; + + int + main (int argc, char *argv[]) + { + int a, b, max, sum; + + jswrap_interp = js_create_interp (NULL); + + hello ("World"); + + a = 5; + b = 7; + max = max_sum (a, b, &sum); + printf ("%d + %d = %d, max(%d, %d) = %d\n", a, b, sum, a, b, max); + + return 0; + } + + +File: js.info, Node: JavaScript API, Next: Virtual Machine, Prev: The jswrap Program, Up: Top + +JavaScript API +************** + +* Menu: + +* Interpreter Handling:: +* Evaluation and Compilation:: +* Type Handling:: +* Defining Global Methods:: +* Classes:: +* Modules:: + + +File: js.info, Node: Interpreter Handling, Next: Evaluation and Compilation, Prev: JavaScript API, Up: JavaScript API + +Interpreter Handling +==================== + + - Function: const char * js_version () + Return a string that describes the JavaScript interpreter version + number. The returned string is in format `"MAJOR.MINOR.PATCH"', + where MAJOR, MINOR, and PATCH are integer numbers. + + - Function: void js_init_default_options (JSInterpOptions *OPTIONS) + Initialize the interpreter options OPTIONS to the default values. + These are the same values that are used in the interpreter + creation, if the argument OPTIONS of `js_create_interp()' is + `NULL'. + + - Function: JSInterpPtr js_create_interp (JSInterpOptions *OPTIONS) + Create a new JavaScript interpreter. The function returns an + interpreter handle that must be passed to all other interpreter API + functions. The argument OPTIONS specify additional options for + the interpreter. If the argument is NULL, the default values are + used. If the interpreter creation fails - due insufficient memory + resources - the function return value `NULL'. + + - Function: void js_destroy_interp (JSInterpPtr INTERP) + Destroy interpreter INTERP and free all resources the interpreter + has allocated. The handle INTERP must not be used after this + function. + + - Function: const char * js_error_message (JSInterpPtr INTERP) + Return an error message of the latest error in interpreter INTERP. + + - Function: void js_result (JSInterpPtr INTERP, JSType *RESULT_RETURN) + Get the result of the latest evaluation or execution in interpreter + INTERP. The result is returned in RESULT_RETURN. All data, + returned in RESULT_RETURN, belongs to the interpreter. The caller + must not modify or changed it in any ways. + + - Function: void js_set_var (JSInterpPtr INTERP, char *NAME, JSType + *VALUE) + + - Function: void js_get_var (JSInterpPtr INTERP, char *NAME, JSType + *VALUE) + + - Function: void js_get_options (JSInterpPtr INTERP, JSInterpOptions + *OPTIONS) + Get the options of interpreter INTERP to OPTIONS. + + - Function: void js_set_options (JSInterpPtr INTERP, JSInterpOptions + *OPTIONS) + Modify the options of interpreter INTERP according to OPTIONS. + + +File: js.info, Node: Evaluation and Compilation, Next: Type Handling, Prev: Interpreter Handling, Up: JavaScript API + +Evaluation and Compilation +========================== + + - Function: int js_eval (JSInterpPtr INTERP, char *CODE) + Evaluate JavaScript code CODE with interpreter INTERP. The + argument CODE is NUL-terminated a C-string holding the JavaScript + code. The function returns 1 if the operation was successful or 0 + otherwise. If the evaluation failed, the error message can be + retrieved with function `js_error_message()'. + + - Function: int js_eval_data (JSInterpPtr INTERP, char *DATA, unsigned + int DATALEN) + Evaluate JavaScript code DATA, DATALEN with interpreter INTERP. + + - Function: int js_eval_file (JSInterpPtr INTERP, char *FILENAME) + Evaluate file FILENAME with interpreter INTERP. The file FILENAME + can contain JavaScript or byte-code. + + - Function: int js_eval_javascript_file (JSInterpPtr INTERP, char + *FILENAME) + Evaluate JavaScript code file FILENAME with interpreter INTERP. + + - Function: int js_execute_byte_code_file (JSInterpPtr INTERP, char + *FILENAME) + Execute a byte-code file FILENAME with interpreter INTERP. + + - Function: int js_apply (JSInterpPtr INTERP, char *NAME, unsigned int + ARGC, JSType *ARGV) + Call function NAME with arguments ARGC, ARGV. The return value of + the function NAME can be retrieved with the `js_result()' function. + + - Function: int js_compile (JSInterpPtr INTERP, char *INPUT_FILE, char + *ASSEMBLER_FILE, char *BYTE_CODE_FILE) + Compile JavaScript input file INPUT_FILE. If the argument + ASSEMBLER_FILE is not `NULL', the generated assembler code is + saved to the file, specified by the argument. If the argument + BYTE_CODE_FILE is not `NULL', the generated byte-code data is + svaed to the file, specified by the argument. + + - Function: int js_compile_to_byte_code (JSInterpPtr INTERP, char + *INPUT_FILE, unsigned char **BC_RETURN, unsigned int + *BC_LEN_RETURN); + Compile JavaScript file INPUT_FILE to byte-code and return the + resulting byte-code data in BC_RETURN, BC_LEN_RETURN. The + returned byte-code data BC_RETURN belongs to the interpreter and + it must be saved by the caller *before* any other JS functions is + called. If the data is not saved, its contents will be + invalidated at the next garbage collection. + + - Function: int js_compile_data_to_byte_code (JSInterpPtr INTERP, char + *DATA, unsigned int DATALEN, unsigned char **BC_RETURN, + unsigned int *BC_LEN_RETURN); + Compile JavaScript code DATA, DATALEN to byte-code and return the + resulting byte-code data in BC_RETURN, BC_LEN_RETURN. + + - Function: int js_execute_byte_code (JSInterpPtr INTERP, unsigned + char *BC, unsigned int BC_LEN); + Execute byte-code data BC, BC_LEN. The byte-code data is the + contents of a byte-code file, or a copy of the data returned by the + `js_compile_to_byte_code()' or `js_compile_data_to_byte_code()' + functions. + + *Note!* You can't use the data from the + `js_compile_to_byte_code()', `js_compile_data_to_byte_code()' + functions as an input for this function. You must take a private + copy of the data and pass that copy to the function: + + if (js_compile_to_byte_code (interp, file, &bc, &bclen)) + { + char *bc_copy = xmalloc (bclen); + memcpy (bc_copy, bc, bclen); + js_execute_byte_code (interp, bc_copy, bclen); + xfree (bc_copy); + } + + +File: js.info, Node: Type Handling, Next: Defining Global Methods, Prev: Evaluation and Compilation, Up: JavaScript API + +Type Handling +============= + + - Function: void js_type_make_string (JSInterpPtr INTERP, JSType + *TYPE, unsigned char *DATA, unsigned int LENGTH) + Create a new string type from LENGTH bytes of data DATA. The + result string is created to TYPE. + + - Function: void js_type_make_array (JSInterpPtr INTERP, JSType *TYPE, + unsigned int LENGTH) + Create a new array type of length LENGTH. The result array is + created to TYPE. + + +File: js.info, Node: Defining Global Methods, Next: Classes, Prev: Type Handling, Up: JavaScript API + +Global Methods +============== + + - Function: void js_create_global_method (JSInterpPtr INTERP, char + *NAME, JSGlobalMethodProc PROC, void *CONTEXT, JSFreeProc + CONTEXT_FREE_PROC) + + +File: js.info, Node: Classes, Next: Modules, Prev: Defining Global Methods, Up: JavaScript API + +Classes +======= + + - Function: JSClassPtr js_class_create (void *CLASS_CONTEXT, + JSFreeProc CLASS_CONTEXT_DESTRUCTOR, int NO_AUTO_DESTROY, + JSConstructor CONSTRUCTOR) + Create a new class with class context data CLASS_CONTEXT. The + context data is destroyed with CLASS_CONTEXT_DESTRUCTOR. If the + argument NO_AUTO_DESTROY is not 0, the JavaScript interpreter will + *not* destroy the class when the interpreter is destroyed. In + that case, it is the caller's responsibility to call + `js_class_destroy()' for the returned class handle, after the + interpreter has been destroyed. If the argument CONSTRUCTOR is + not `NULL', it is used to instantiate the class when a ``new + 'CLASS` ('ARGS[...]`);'' expression is evaluated in the JavaScript + code. + + - Function: void js_class_destroy (JSClassPtr CLS) + Destroy class handle CLS. The class handle must be created by the + `js_class_create()' function, so that value `1' was given for the + NO_AUTO_DESTROY argument. + + - Function: JSVoidPtr js_class_context (JSClassPtr CLS) + Return the class context of class CLS. The returned value is the + same that was given for the CLASS_CONTEXT argument in call of + function `js_class_create()'. + + - Function: int js_class_define_method (JSClassPtr CLS, char *NAME, + unsigned int FLAGS, JSMethodProc METHOD) + Define a new method for the class CLS. The name of the new method + is NAME and its implementation is METHOD. The argument FLAGS can + have the following flags: + + `JS_CF_STATIC' + The created method is a static method. + + - Function: int js_class_define_property (JSClassPtr CLS, char *NAME, + unsigned int FLAGS, JSPropertyProc PROPERTY) + Define a new property for the class CLS. The name of the property + is NAME and its setter and getter function is PROPERTY. The + argument FLAGS can have the following flags: + + `JS_CF_STATIC' + The property is a static property. + + `JS_CF_IMMUTABLE' + The property is immutable. An error to try to set the + property. + + - Function: int js_define_class (JSInterpPtr INTERP, JSClassPtr CLS, + char *NAME) + Define the class CLS to the interpreter INTERP with name NAME. If + the value `0' was given for the argument NO_AUTO_DESTROY of the + function `js_class_create()', the handle CLS must not be used + after this call. + + - Function: int js_instantiate_class (JSInterpPtr INTERP, JSClassPtr + CLS, void *INSTANCE_CTX, JSFreeProc INSTANCE_CTX_DESTRUCTOR, + JSType *RESULT_RETURN) + + - Function: const JSClassPtr js_lookup_class (JSInterpPtr INTERP, char + *NAME) + Lookup the class context by name from the interpreter INTERP. + + - Function: int js_isa (JSInterpPtr INTERP, JSType *OBJECT, JSClassPtr + CLS, void **INSTANCE_CONTEXT_RETURN) + Check if object OBJECT is an instance of class CLS. The function + returns a boolean success status. If the argument + INSTANCE_CONTEXT_RETURN is not `NULL', it will be set to the + instance context of object OBJECT. + + +File: js.info, Node: Modules, Prev: Classes, Up: JavaScript API + +Modules +======= + + - Function: int js_define_module (JSInterpPtr INTERP, JSModuleInitProc + INIT_PROC) + + +File: js.info, Node: Virtual Machine, Next: JavaScript Compiler, Prev: JavaScript API, Up: Top + +Virtual Machine +*************** + +* Menu: + +* Byte-Code File Format:: +* Byte-Code Operands:: +* Stack Frame:: + + +File: js.info, Node: Byte-Code File Format, Next: Byte-Code Operands, Prev: Virtual Machine, Up: Virtual Machine + +Byte-Code File Format +===================== + +* Menu: + +* File Header:: +* Code Section:: +* Constants Section:: +* Symtab Section:: +* Debug Section:: + + +File: js.info, Node: File Header, Next: Code Section, Prev: Byte-Code File Format, Up: Byte-Code File Format + +File Header +----------- + +`magic' + An `UInt32' number containing the JavaScript byte-code file magic. + The value of the magic is `0xc0014a53'. + +`nsects' + An `UInt32' number containing the number of sections in this + byte-code file. + + +File: js.info, Node: Code Section, Next: Constants Section, Prev: File Header, Up: Byte-Code File Format + +Code Section +------------ + diff --git a/reactos/lib/kjs/docs/js.info-3 b/reactos/lib/kjs/docs/js.info-3 new file mode 100644 index 00000000000..8e18ab3bcc3 --- /dev/null +++ b/reactos/lib/kjs/docs/js.info-3 @@ -0,0 +1,1145 @@ +This is Info file js.info, produced by Makeinfo version 1.68 from the +input file js.texi. + +INFO-DIR-SECTION NGS JavaScript Interpreter +START-INFO-DIR-ENTRY +* libjs: (js). The JavaScript interpreter library. +* js: (js)The js Program. JavaScript interpreter. +END-INFO-DIR-ENTRY + + This file documents NGS JavaScript interpreter 0.2.5 + + Copyright (C) 1998 New Generation Software (NGS) Oy + + Permission is granted to make and distribute verbatim copies of this +manual provided the copyright notice and this permission notice are +preserved on all copies. + + Permission is granted to copy and distribute modified versions of +this manual under the conditions for verbatim copying, provided that +the entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + + Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that this permission notice may be stated in a +translation approved by the Foundation. + + +File: js.info, Node: Constants Section, Next: Symtab Section, Prev: Code Section, Up: Byte-Code File Format + +Constants Section +----------------- + + The constants section contains the constant values of the byte-code. +The different constant types are stored as follows: + +integer + (UInt8)`3', (Int32)VALUE + +string + (UInt8)`4', (UInt32)LENGTH, LENGTH BYTES OF DATA + +float + (UInt8)`5', (double)VALUE + +symbol + (UInt8)`10', SYMBOL NAME, (UInt8)`0' + +NaN + (UInt8)`13' + +regular expression + (UInt8)`100', (UInt8)FLAGS, (UInt32)LENGTH, LENGTH BYTES OF REGEXP + SOURCE + + The item FLAGS holds the regular expression flags. It is a + combination of the following flags: + + `0x01' + global match + + `0x02' + ignore case + + +File: js.info, Node: Symtab Section, Next: Debug Section, Prev: Constants Section, Up: Byte-Code File Format + +Symtab Section +-------------- + + +File: js.info, Node: Debug Section, Prev: Symtab Section, Up: Byte-Code File Format + +Debug Section +------------- + + +File: js.info, Node: Byte-Code Operands, Next: Stack Frame, Prev: Byte-Code File Format, Up: Virtual Machine + +Byte-Code Operands +================== + + The virtual machine knows the following byte-code operands. Each +operand is identified by a 8 bit long unsigned integer number. The +first operand `halt' has code 0, the next operand `done' has code 1, +and so on. Some operand take arguments that are shown after the +operand name in the following listing. The meanings of the arguments +are: + +`Int8' + The code of the operand is followed by a 8 bit long integer number + argument. + +`Int16' + The code of the operand is followed by a 16 bit long integer number + argument. + +`Int32' + The code of the operand is followed by a 32 bit long integer number + argument. + +`Symbol' + The code of the operand is followed by a 32 bit long integer number + argument. The number is an offset to the constant section and the + specified constant is a symbol that is the argument of the operand. + + The notation + + BEFORE => AFTER + +desribes how the operand modifies the virtual machine stack. For +example, the notation: + + -- => `undefined' + +means that the operand takes no items from the stack and it pushes +value `undefined' to the stack. The notation: + + ANY ANY => `boolean' + +means that the operand takes two items from the stack and it pushes a +boolean result to the stack. + + The virtual machine knows the following byte-code operands. + + - Operand: halt -- => -- + Halt the virtual machine. The program execution stops immediately + and the virtual machine starts execute the following C-code: + + while (1) + sleep (5); + + This "sleep forever" loop is implemented for debugging purposes. + + - Operand: done -- => -- + The execution of the byte-code is finished and the control returns + to the calling C-function. + + - Operand: nop -- => -- + Do nothing; no operation. + + - Operand: dup ANY => ANY ANY + Duplicate the item at the top of the stack. + + - Operand: pop ANY => -- + Remove one item from the top of the stack. + + - Operand: pop_n `Int8' ANY ... ANY => -- + Remove INT8 items from the top of the stack. + + - Operand: apop `Int8' ANY_N ... ANY_0 => ANY_0 + Remove INT8 items from the top of the stack, leaving the topmost + item on the top of the stack. This operand is used to remove + arguments of a function call, leaving the function's return value + to the top of the stack. + + - Operand: swap ANY_1 ANY_2 => ANY_2 ANY_1 + Swap the two topmost items in the stack. + + - Operand: roll `Int8' ANY_N ... ANY_1 ANY_0 => ANY_0 ANY_N ... ANY_1 + + - Operand: const `Int32' -- => CONST + Push a constant from the constant section to the stack. The + constant is specified by the value INT32. + + - Operand: const_null -- => `null' + Push value `null' to the stack. + + - Operand: const_true -- => `true' + Push value `true' to the stack. + + - Operand: const_false -- => `false' + Push value `false' to the stack. + + - Operand: const_undefined -- => `undefined' + Push value `undefined' to the stack. + + - Operand: const_i0 -- => `0' + Push integer number `0' to the stack. + + - Operand: const_i1 -- => `1' + Push integer number `1' to the stack. + + - Operand: const_i2 -- => `2' + Push integer number `2' to the stack. + + - Operand: const_i3 -- => `3' + Push integer number `3' to the stack. + + - Operand: const_i `Int32' -- => `Int32' + Push integer number `Int32' to the stack. + + - Operand: load_global `Symbol' -- => VALUE + Push the value of the global variable SYMBOL to the stack. The + operand will *not* lookup the variable SYMBOL from the with-chain. + + - Operand: store_global `Symbol' VALUE => -- + Store the topmost item of the stack to the global variable SYMBOL. + + - Operand: load_arg `Int8' -- => VALUE + Push the value of the argument INT8 to the stack. + + - Operand: store_arg `Int8' VALUE => -- + Store the topmost item of the stack to the argument INT8. + + - Operand: load_local `Int16' -- => VALUE + Push the value of the local variable INT16 to the stack. + + - Operand: store_local `Int16' VALUE => -- + Store the topmost item of the stack to the local variable INT16. + + - Operand: load_property `Symbol' OBJECT => VALUE + Push the value of the property SYMBOL of object OBJECT to the + stack. + + - Operand: store_property `Symbol' OBJECT VALUE => -- + Save the value VALUE to the property SYMBOL of object OBJECT. + + - Operand: load_array OBJECT INDEX => VALUE + Push the INDEX:th item of object OBJECT to the stack. + + - Operand: store_array VALUE OBJECT INDEX => -- + Store the value VALUE to the INDEX:th position of object OBJECT. + + - Operand: nth ANY INTEGER => ITEM BOOLEAN + Push the INTEGER:th item of object ANY to the stack. Push a + boolean success status that tells whether the object ANY did + contain INTEGER:th item. + + - Operand: cmp_eq ANY1 ANY2 => BOOLEAN + Compare the two objects ANY1, ANY2 for equality and push a boolean + result code to the stack. + + - Operand: cmp_ne ANY ANY => BOOLEAN + Compare the two objects ANY1, ANY2 for inequality and push a + boolean result code to the stack. + + - Operand: cmp_lt ANY1 ANY2 => BOOLEAN + Compare whether object ANY1 is smaller than object ANY2. Push a + boolean result code to the stack. + + - Operand: cmp_gt ANY1 ANY2 => BOOLEAN + Compare whether object ANY1 is greater than object ANY2. Push a + boolean result code to the stack. + + - Operand: cmp_le ANY1 ANY2 => BOOLEAN + Compare whether object ANY1 is smaller than, or equal to object + ANY2. Push a boolean result code to the stack. + + - Operand: cmp_ge ANY1 ANY2 => BOOLEAN + Compare whether object ANY1 is greater than, or equal to object + ANY2. Push a boolean result code to the stack. + + - Operand: cmp_seq ANY1 ANY2 => BOOLEAN + Compare the two objects ANY1, ANY2 for strict equality and push a + boolean result code to the stack. + + - Operand: cmp_sne ANY ANY => BOOLEAN + Compare the two objects ANY1, ANY2 for strict inequality and push + a boolean result code to the stack. + + - Operand: sub ANY1 ANY2 => RESULT + Substract object ANY2 from object ANY1 and push the result to the + stack. + + - Operand: add ANY1 ANY2 => RESULT + Add object ANY2 to object ANY1 and push the result to the stack. + + - Operand: mul ANY1 ANY2 => RESULT + Multiply object ANY1 with object ANY2 and push the result to the + stack. + + - Operand: div ANY1 ANY2 => RESULT + Divide object ANY1 with object ANY2 and push the result to the + stack. + + - Operand: mod INTEGER1 INTEGER2 => RESULT + Count object INTEGER1 modulo object INTEGER2 and push the result + to the stack. + + - Operand: neg ANY => RESULT + Negate object ANY and push the result to the stack. + + - Operand: and ANY1 ANY2 => RESULT + Perform a bitwise and operation between objects ANY1 and ANY2 and + push the result to the stack. + + - Operand: not ANY1 ANY2 => RESULT + Perform a bitwise not operation between objects ANY1 and ANY2 and + push the result to the stack. + + - Operand: or ANY1 ANY2 => RESULT + Perform a bitwise or operation between objects ANY1 and ANY2 and + push the result to the stack. + + - Operand: xor ANY1 ANY2 => RESULT + Perform a bitwise xor operation between objects ANY1 and ANY2 and + push the result to the stack. + + - Operand: shift_left INTEGER1 INTEGER2 => INTEGER + Shift integer number INTEGER1 left INTEGER2 bits. Push the result + value to the stack. + + - Operand: shift_right INTEGER1 INTEGER2 => INTEGER + Shift integer number INTEGER1 right INTEGER2 bits. Push the + result value to the stack. + + - Operand: shift_rright INTEGER1 INTEGER2 => INTEGER + + - Operand: iffalse `Int32' ANY => -- + If the topmost item in the stack has boolean value `false', adjust + the program counter with relative offset INT32. + + - Operand: iftrue `Int32' ANY => -- + If the topmost item in the stack has boolean value `true', adjust + the program counter with relative offset INT32. + + - Operand: call_method `Symbol' OBJECT => RESULT + Call method SYMBOL in the object OBJECT. Push the result of the + method call to the stack. + + - Operand: jmp `Int32' -- => -- + Adjust program counter with relative offset INT32, e.g. jump to + relative position PC + INT32. + + - Operand: jsr FUNCTION => RESULT + Jump to subroutine FUNCTION and push the result of the subroutine + call to the stack. The operand will *not* process the with-chain. + + - Operand: return RESULT => RESULT + Return from a subroutine with value RESULT. + + - Operand: typeof ANY => STRING + Push the type name of object ANY to the stack. + + - Operand: new OBJECT => RESULT OBJECT + Create an instance of object OBJECT and call its constructor + function. Push the result from the constructor and the new + instance to the stack. The return value of the constructor is + discarded. + + - Operand: delete_property `Symbol' OBJECT => UNDEFINED + Delete property SYMBOL from object OBJECT. Push value `undefined' + to the stack. + + - Operand: delete_array OBJECT INDEX => UNDEFINED + Delete the INDEX:th property of object OBJECT. Push value + `undefined' to the stack. + + - Operand: locals `Int16' -- => UNDEFINED ... UNDEFINED + Allocate INT16 local variables from the stack frame. The operand + `locals' must be called in the beginning of the function code. The + operand will push INT16 `undefined' values to the stack. The + values will be the place-holders for the local variables. + + - Operand: min_args `Int8' INTEGER => -- + If the number of the arguments for the function INTEGER is smaller + than `Int8', expand the stack frame so that the function gets + `Int8' arguments. The created arguments will have value + `undefined'. + + - Operand: load_nth_arg INTEGER => ARGUMENT + Push the INTEGER'th argument of function to the top of the stack. + The index INTEGER must be an integer number. + + - Operand: with_push OBJECT => -- + Push object OBJECT to the function's with-lookup chain. + + - Operand: with_pop `Int8' -- => -- + Pop INT8 objects from the function's with-lookup chain. + + - Operand: try_push `Int32' -- => -- + Push a try-frame with a catch block offset INT32 to the virtual + machine's try-chain. + + - Operand: try_pop `Int8' -- => -- + Pop INT8 frames from the virtual machine's try-chain. + + - Operand: throw ANY => -- + Throw an exception with value ANY. + + - Operand: iffalse_b `Int32' BOOLEAN => -- + If the topmost item in the stack is `false', adjust the program + counter with relative offset INT32. The operand assumes that the + topmost item is a boolean value. + + - Operand: iftrue_b `Int32' BOOLEAN => -- + If the topmost item in the stack is `true', adjust the program + counter with relative offset INT32. The operand assumes that the + topmost item is a boolean value. + + - Operand: add_1_i INTEGER => INTEGER + Add integer number one to the top most item in the stack. The + operand assumes that the topmost item is an integer number. + + - Operand: add_2_i INTEGER => INTEGER + Add integer number two to the top most item in the stack. The + operand assumes that the topmost item is an integer number. + + - Operand: load_global_w `Symbol' -- => VALUE + Push the value of the global variable SYMBOL to the stack. The + operand will lookup the property SYMBOL from the currently active + with-chain. + + - Operand: jsr_w `Symbol' FUNCTION => RESULT + Jump to subroutine FUNCTION and push the result of the subroutine + call to the stack. The operand will lookup the method SYMBOL from + the currently active with-chain. If the method is not found, the + argument FUNCTION is used. + + +File: js.info, Node: Stack Frame, Prev: Byte-Code Operands, Up: Virtual Machine + +Stack Frame +=========== + + JS_SP0 sp => + JS_SP1 local_var_N + JS_SP2 ... + JS_SP(N) local_var_1 + JS_LOCAL(0) local_var_0 + return_addr + JS_WITHPTR with_ptr + JS_ARGS_FIXP args_fix + fp => old_fp + JS_ARG(0) this + JS_ARG(1) arg_count + JS_ARG(2) argument_1 + argument_2 + ... + JS_ARG(N) argument_N + local_var_N + ... + local_var_0 + args_fix + return_addr + with_ptr + old_fp + this + ... + + +File: js.info, Node: JavaScript Compiler, Next: GNU Library General Public License, Prev: Virtual Machine, Up: Top + +JavaScript Compiler +******************* + + The JavaScript compiler is implemented in the JavaScript language. +Because the JavaScript language does not have namespaces, the compiler +has been coded to a fixed part of the global namespace. All global +symbols the compiler uses, start with the prefix ``JSC$''. This prefix +is reserved for the interpreter and users must not define any symbols +or functions starting with that prefix. + + The compiler compiles JavaScript source code to byte-code and it +returns a fixed byte-code file as the result. This result file (or +data block) can be passed to the virtual machine for execution. + + The compiler has three stages. The first stage parse the input +stream and create a syntax tree for the input. The second stage +transforms the syntax tree to a list of assembler operations. The +third stage converts the symbolic assembler instructions to byte-code +operands. + + Depending on the compilation options, the compiler performs different +optimizations during the compilation. The basic optimizations include +constant folding, peephole optimization, and optimization of jumps to +jump instructions. During the batch-compilation (when compiling a +JavaScript source file `.js' to byte-code file `.jsc') the compiler +performns heavier optimizations to minimize the size of the generated +byte-code file, and to speed up some operations. + +* Menu: + +* Public Entry Points:: + + +File: js.info, Node: Public Entry Points, Prev: JavaScript Compiler, Up: JavaScript Compiler + +Public Entry Points +=================== + + - Function: JSC$compile_file (NAME, FLAGS, ASM_FILE, BC_FILE) + Compile JavaScript source file NAME according to FLAGS. If + argument ASM_FILE is not `null', symbolic assembler output is + saved to that file. If argument BC_FILE is not `null', the + byte-code output is saved to that file. + + The function returns a string that holds the byte-code output for + the source file. + + - Function: JSC$compile_string (STRING, FLAGS, ASM_FILE, BC_FILE) + Compile JavaScript source code STRING according to FLAGS. If + argument ASM_FILE is not `null', symbolic assembler output is + saved to that file. If argument BC_FILE is not `null', the + byte-code output is saved to that file. + + The function returns a string that holds the byte-code output for + the source code. + + In both functions, the argument FLAGS specify the verbosity, +warning, and optimization levels of the compilation. The following +values can be given to flags: + +`JSC$FLAG_VERBOSE' + turns on diagnostic messages + +`JSC$FLAG_ANNOTATE_ASSEMBLER' + add original JavaScript source lines to the generated assembler + listing + +`JSC$FLAG_GENERATE_DEBUG_INFO' + generate debugging information to the byte-code file + +`JSC$FLAG_GENERATE_EXECUTABLE_BC_FILES' + add execute permissions to the generated byte-code files + +`JSC$FLAG_OPTIMIZE_PEEPHOLE' + perform peephole optimization + +`JSC$FLAG_OPTIMIZE_JUMPS' + perform optimization for jumps to jump instructions + +`JSC$FLAG_OPTIMIZE_BC_SIZE' + optimize the size of the genated byte-code file + +`JSC$FLAG_OPTIMIZE_HEAVY' + perform optimizations which require liveness analyzing of the + variables + +`JSC$FLAG_OPTIMIZE_MASK' + mask to turn on all optimizations + +`JSC$FLAG_WARN_UNUSED_ARGUMENT' + warn if an argument of a function is unused in the function body + +`JSC$FLAG_WARN_UNUSED_VARIABLE' + warn in a variable is defined but it is not used in the function + body + +`JSC$FLAG_WARN_SHADOW' + warn if a variable declaration shadows a parameter of a function + +`JSC$FLAG_WARN_WITH_CLOBBER' + warn if a symbol with-lookup is clobbered because the symbol is + defined to be a local variable or a function argument + +`JSC$FLAG_WARN_MISSING_SEMICOLON' + warn if a semicolon is missing from the input. The missing + semicolons are inserted during the parsing by the automatic + semicolon inserting. However, since the missing semicolons show + bad programming style, this option will warn about them. + +`JSC$FLAG_WARN_STRICT_ECMA' + warn about things that are supported by this implementation, but + are not allowed by the ECMAScript standard + +`JSC$FLAG_WARN_DEPRECATED' + warn if deprecated features has been used in the source code + +`JSC$FLAG_WARN_MASK' + mask to turn on all warnings + + The compiler entry points can be called from JavaScript and C +programs. For example, they are used extensively to implement the +JavaScript API, described in the `js.h' file. The following example +shows how a C-string, containing JavaScript code, can be compiled and +executed. Similar function can be found from the JavaScript API +implementing the `js_eval()' function. + + int + eval_code (JSInterpPtr interp, char *code); + { + JSNode argv[5]; + int i = 0; + int result; + ByteCode *bc; + + /* Compile the code. */ + + /* Argument count. */ + argv[i].type = JS_INTEGER; + argv[i].u.vinteger = 4; + i++; + + /* Source for the compiler. */ + js_make_static_string (interp->vm, &argv[i], code, strlen (code)); + i++; + + /* Flags. */ + argv[i].type = JS_INTEGER; + argv[i].u.vinteger = JSC_FLAG_VERBOSE; + argv[i].u.vinteger |= JSC_FLAG_OPTIMIZE_MASK; + argv[i].u.vinteger |= JSC_FLAG_WARN_MASK; + i++; + + /* Assembler file. */ + argv[i].type = JS_NULL; + i++; + + /* Byte-code file. */ + argv[i].type = JS_NULL; + i++; + + /* Call the compiler entry point. */ + result = js_vm_apply (interp->vm, "JSC$compile_string", i, argv); + if (result == 0) + return 0; + + bc = js_bc_read_data (interp->vm->exec_result.u.vstring->data, + interp->vm->exec_result.u.vstring->len); + + /* And finally, execute it. */ + result = js_vm_execute (interp->vm, bc); + + /* Free the byte-code. */ + js_bc_free (bc); + + return result; + } + + The following example shows how the compiler entry point can be +called from JavaScript code. The example code compiles a JavaScript +source code file `input.js' into byte-code and stores the result to file +`ouput.jsc'. + + try + { + JSC$compile_file ("input.js", + JSC$FLAG_OPTIMIZE_MASK | JSC$FLAG_WARN_MASK, + null, "output.jsc"); + } + catch (e) + { + System.stdout.writeln ("compilation failed: " + e); + } + + +File: js.info, Node: GNU Library General Public License, Next: Index, Prev: JavaScript Compiler, Up: Top + +GNU Library General Public License +********************************** + +GNU LIBRARY GENERAL PUBLIC LICENSE +********************************** + + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + [This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + +Preamble +======== + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it in +new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License, which was designed for utility +programs. This license, the GNU Library General Public License, +applies to certain designated libraries. This license is quite +different from the ordinary one; be sure to read it in full, and don't +assume that anything in it is the same as in the ordinary license. + + The reason we have a separate public license for some libraries is +that they blur the distinction we usually make between modifying or +adding to a program and simply using it. Linking a program with a +library, without changing the library, is in some sense simply using +the library, and is analogous to running a utility program or +application program. However, in a textual and legal sense, the linked +executable is a combined work, a derivative of the original library, +and the ordinary General Public License treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended +to permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to +achieve this as regards changes in header files, but we have achieved +it as regards changes in the actual functions of the Library.) The +hope is that this will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which + contains a notice placed by the copyright holder or other + authorized party saying it may be distributed under the terms of + this Library General Public License (also called "this License"). + Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data + prepared so as to be conveniently linked with application programs + (which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work + which has been distributed under these terms. A "work based on the + Library" means either the Library or any derivative work under + copyright law: that is to say, a work containing the Library or a + portion of it, either verbatim or with modifications and/or + translated straightforwardly into another language. (Hereinafter, + translation is included without limitation in the term + "modification".) + + "Source code" for a work means the preferred form of the work for + making modifications to it. For a library, complete source code + means all the source code for all modules it contains, plus any + associated interface definition files, plus the scripts used to + control compilation and installation of the library. + + Activities other than copying, distribution and modification are + not covered by this License; they are outside its scope. The act + of running a program using the Library is not restricted, and + output from such a program is covered only if its contents + constitute a work based on the Library (independent of the use of + the Library in a tool for writing it). Whether that is true + depends on what the Library does and what the program that uses + the Library does. + + 1. You may copy and distribute verbatim copies of the Library's + complete source code as you receive it, in any medium, provided + that you conspicuously and appropriately publish on each copy an + appropriate copyright notice and disclaimer of warranty; keep + intact all the notices that refer to this License and to the + absence of any warranty; and distribute a copy of this License + along with the Library. + + You may charge a fee for the physical act of transferring a copy, + and you may at your option offer warranty protection in exchange + for a fee. + + 2. You may modify your copy or copies of the Library or any portion + of it, thus forming a work based on the Library, and copy and + distribute such modifications or work under the terms of Section 1 + above, provided that you also meet all of these conditions: + + a. The modified work must itself be a software library. + + b. You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c. You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d. If a facility in the modified Library refers to a function or + a table of data to be supplied by an application program that + uses the facility, other than as an argument passed when the + facility is invoked, then you must make a good faith effort + to ensure that, in the event an application does not supply + such function or table, the facility still operates, and + performs whatever part of its purpose remains meaningful. + + (For example, a function in a library to compute square roots + has a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function + must be optional: if the application does not supply it, the + square root function must still compute square roots.) + + These requirements apply to the modified work as a whole. If + identifiable sections of that work are not derived from the + Library, and can be reasonably considered independent and separate + works in themselves, then this License, and its terms, do not + apply to those sections when you distribute them as separate + works. But when you distribute the same sections as part of a + whole which is a work based on the Library, the distribution of + the whole must be on the terms of this License, whose permissions + for other licensees extend to the entire whole, and thus to each + and every part regardless of who wrote it. + + Thus, it is not the intent of this section to claim rights or + contest your rights to work written entirely by you; rather, the + intent is to exercise the right to control the distribution of + derivative or collective works based on the Library. + + In addition, mere aggregation of another work not based on the + Library with the Library (or with a work based on the Library) on + a volume of a storage or distribution medium does not bring the + other work under the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public + License instead of this License to a given copy of the Library. + To do this, you must alter all the notices that refer to this + License, so that they refer to the ordinary GNU General Public + License, version 2, instead of to this License. (If a newer + version than version 2 of the ordinary GNU General Public License + has appeared, then you can specify that version instead if you + wish.) Do not make any other change in these notices. + + Once this change is made in a given copy, it is irreversible for + that copy, so the ordinary GNU General Public License applies to + all subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of + the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or + derivative of it, under Section 2) in object code or executable + form under the terms of Sections 1 and 2 above provided that you + accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software + interchange. + + If distribution of object code is made by offering access to copy + from a designated place, then offering equivalent access to copy + the source code from the same place satisfies the requirement to + distribute the source code, even though third parties are not + compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the + Library, but is designed to work with the Library by being + compiled or linked with it, is called a "work that uses the + Library". Such a work, in isolation, is not a derivative work of + the Library, and therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library + creates an executable that is a derivative of the Library (because + it contains portions of the Library), rather than a "work that + uses the library". The executable is therefore covered by this + License. Section 6 states terms for distribution of such + executables. + + When a "work that uses the Library" uses material from a header + file that is part of the Library, the object code for the work may + be a derivative work of the Library even though the source code is + not. Whether this is true is especially significant if the work + can be linked without the Library, or if the work is itself a + library. The threshold for this to be true is not precisely + defined by law. + + If such an object file uses only numerical parameters, data + structure layouts and accessors, and small macros and small inline + functions (ten lines or less in length), then the use of the object + file is unrestricted, regardless of whether it is legally a + derivative work. (Executables containing this object code plus + portions of the Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may + distribute the object code for the work under the terms of Section + 6. Any executables containing that work also fall under Section 6, + whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or + link a "work that uses the Library" with the Library to produce a + work containing portions of the Library, and distribute that work + under terms of your choice, provided that the terms permit + modification of the work for the customer's own use and reverse + engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the + Library is used in it and that the Library and its use are covered + by this License. You must supply a copy of this License. If the + work during execution displays copyright notices, you must include + the copyright notice for the Library among them, as well as a + reference directing the user to the copy of this License. Also, + you must do one of these things: + + a. Accompany the work with the complete corresponding + machine-readable source code for the Library including + whatever changes were used in the work (which must be + distributed under Sections 1 and 2 above); and, if the work + is an executable linked with the Library, with the complete + machine-readable "work that uses the Library", as object code + and/or source code, so that the user can modify the Library + and then relink to produce a modified executable containing + the modified Library. (It is understood that the user who + changes the contents of definitions files in the Library will + not necessarily be able to recompile the application to use + the modified definitions.) + + b. Accompany the work with a written offer, valid for at least + three years, to give the same user the materials specified in + Subsection 6a, above, for a charge no more than the cost of + performing this distribution. + + c. If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the + above specified materials from the same place. + + d. Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the + Library" must include any data and utility programs needed for + reproducing the executable from it. However, as a special + exception, the source code distributed need not include anything + that is normally distributed (in either source or binary form) + with the major components (compiler, kernel, and so on) of the + operating system on which the executable runs, unless that + component itself accompanies the executable. + + It may happen that this requirement contradicts the license + restrictions of other proprietary libraries that do not normally + accompany the operating system. Such a contradiction means you + cannot use both them and the Library together in an executable + that you distribute. + + 7. You may place library facilities that are a work based on the + Library side-by-side in a single library together with other + library facilities not covered by this License, and distribute + such a combined library, provided that the separate distribution + of the work based on the Library and of the other library + facilities is otherwise permitted, and provided that you do these + two things: + + a. Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b. Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same + work. + + 8. You may not copy, modify, sublicense, link with, or distribute the + Library except as expressly provided under this License. Any + attempt otherwise to copy, modify, sublicense, link with, or + distribute the Library is void, and will automatically terminate + your rights under this License. However, parties who have + received copies, or rights, from you under this License will not + have their licenses terminated so long as such parties remain in + full compliance. + + 9. You are not required to accept this License, since you have not + signed it. However, nothing else grants you permission to modify + or distribute the Library or its derivative works. These actions + are prohibited by law if you do not accept this License. + Therefore, by modifying or distributing the Library (or any work + based on the Library), you indicate your acceptance of this + License to do so, and all its terms and conditions for copying, + distributing or modifying the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the + Library), the recipient automatically receives a license from the + original licensor to copy, distribute, link with or modify the + Library subject to these terms and conditions. You may not impose + any further restrictions on the recipients' exercise of the rights + granted herein. You are not responsible for enforcing compliance + by third parties to this License. + + 11. If, as a consequence of a court judgment or allegation of patent + infringement or for any other reason (not limited to patent + issues), conditions are imposed on you (whether by court order, + agreement or otherwise) that contradict the conditions of this + License, they do not excuse you from the conditions of this + License. If you cannot distribute so as to satisfy simultaneously + your obligations under this License and any other pertinent + obligations, then as a consequence you may not distribute the + Library at all. For example, if a patent license would not permit + royalty-free redistribution of the Library by all those who + receive copies directly or indirectly through you, then the only + way you could satisfy both it and this License would be to refrain + entirely from distribution of the Library. + + If any portion of this section is held invalid or unenforceable + under any particular circumstance, the balance of the section is + intended to apply, and the section as a whole is intended to apply + in other circumstances. + + It is not the purpose of this section to induce you to infringe any + patents or other property right claims or to contest validity of + any such claims; this section has the sole purpose of protecting + the integrity of the free software distribution system which is + implemented by public license practices. Many people have made + generous contributions to the wide range of software distributed + through that system in reliance on consistent application of that + system; it is up to the author/donor to decide if he or she is + willing to distribute software through any other system and a + licensee cannot impose that choice. + + This section is intended to make thoroughly clear what is believed + to be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in + certain countries either by patents or by copyrighted interfaces, + the original copyright holder who places the Library under this + License may add an explicit geographical distribution limitation + excluding those countries, so that distribution is permitted only + in or among countries not thus excluded. In such case, this + License incorporates the limitation as if written in the body of + this License. + + 13. The Free Software Foundation may publish revised and/or new + versions of the Library General Public License from time to time. + Such new versions will be similar in spirit to the present version, + but may differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the + Library specifies a version number of this License which applies + to it and "any later version", you have the option of following + the terms and conditions either of that version or of any later + version published by the Free Software Foundation. If the Library + does not specify a license version number, you may choose any + version ever published by the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free + programs whose distribution conditions are incompatible with these, + write to the author to ask for permission. For software which is + copyrighted by the Free Software Foundation, write to the Free + Software Foundation; we sometimes make exceptions for this. Our + decision will be guided by the two goals of preserving the free + status of all derivatives of our free software and of promoting + the sharing and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO + WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE + LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT + HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT + WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT + NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE + QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE + LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY + SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN + WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY + MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE + LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, + INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR + INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF + DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU + OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY + OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Libraries +============================================== + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of +the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +It is safest to attach them to the start of each source file to most +effectively convey the exclusion of warranty; and each file should have +at least the "copyright" line and a pointer to where the full notice is +found. + + ONE LINE TO GIVE THE LIBRARY'S NAME AND AN IDEA OF WHAT IT DOES. + Copyright (C) YEAR NAME OF AUTHOR + + 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, Cambridge, + MA 02139, USA. + + Also add information on how to contact you by electronic and paper +mail. + + You should also get your employer (if you work as a programmer) or +your school, if any, to sign a "copyright disclaimer" for the library, +if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in + the library `Frob' (a library for tweaking knobs) written + by James Random Hacker. + + SIGNATURE OF TY COON, 1 April 1990 + Ty Coon, President of Vice + + That's all there is to it! + diff --git a/reactos/lib/kjs/docs/js.info-4 b/reactos/lib/kjs/docs/js.info-4 new file mode 100644 index 00000000000..114120b7df2 --- /dev/null +++ b/reactos/lib/kjs/docs/js.info-4 @@ -0,0 +1,383 @@ +This is Info file js.info, produced by Makeinfo version 1.68 from the +input file js.texi. + +INFO-DIR-SECTION NGS JavaScript Interpreter +START-INFO-DIR-ENTRY +* libjs: (js). The JavaScript interpreter library. +* js: (js)The js Program. JavaScript interpreter. +END-INFO-DIR-ENTRY + + This file documents NGS JavaScript interpreter 0.2.5 + + Copyright (C) 1998 New Generation Software (NGS) Oy + + Permission is granted to make and distribute verbatim copies of this +manual provided the copyright notice and this permission notice are +preserved on all copies. + + Permission is granted to copy and distribute modified versions of +this manual under the conditions for verbatim copying, provided that +the entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + + Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that this permission notice may be stated in a +translation approved by the Foundation. + + +File: js.info, Node: Index, Prev: GNU Library General Public License, Up: Top + +Index +***** + +* Menu: + +* $1: RegExp. +* $2: RegExp. +* $3: RegExp. +* $4: RegExp. +* $5: RegExp. +* $6: RegExp. +* $7: RegExp. +* $8: RegExp. +* $9: RegExp. +* $_: RegExp. +* abs on Math: Math. +* acos on Math: Math. +* add: Byte-Code Operands. +* add_1_i: Byte-Code Operands. +* add_2_i: Byte-Code Operands. +* and: Byte-Code Operands. +* apop: Byte-Code Operands. +* append on String: String. +* Array: Array. +* asin on Math: Math. +* atan on Math: Math. +* atan2 on Math: Math. +* autoFlush: File. +* bits: System. +* Boolean: Boolean. +* bufferSize: File. +* byteToString on File: File. +* call_method: Byte-Code Operands. +* callMethod: Global Methods and Properties. +* canonicalHost: System. +* canonicalHostCPU: System. +* canonicalHostOS: System. +* canonicalHostVendor: System. +* ceil on Math: Math. +* charAt on String: String. +* charCodeAt on String: String. +* chdir on System: System. +* chmod on File: File. +* clearError on File: File. +* close on Directory: Directory. +* close on File: File. +* cmp_eq: Byte-Code Operands. +* cmp_ge: Byte-Code Operands. +* cmp_gt: Byte-Code Operands. +* cmp_le: Byte-Code Operands. +* cmp_lt: Byte-Code Operands. +* cmp_ne: Byte-Code Operands. +* cmp_seq: Byte-Code Operands. +* cmp_sne: Byte-Code Operands. +* compile on JS: JS. +* compile on RegExp: RegExp. +* concat on Array: Array. +* concat on String: String. +* const: Byte-Code Operands. +* const_false: Byte-Code Operands. +* const_i: Byte-Code Operands. +* const_i0: Byte-Code Operands. +* const_i1: Byte-Code Operands. +* const_i2: Byte-Code Operands. +* const_i3: Byte-Code Operands. +* const_null: Byte-Code Operands. +* const_true: Byte-Code Operands. +* const_undefined: Byte-Code Operands. +* cos on Math: Math. +* crc32 on String: String. +* Date: Date. +* debug: Global Methods and Properties. +* delete_array: Byte-Code Operands. +* delete_property: Byte-Code Operands. +* Directory: Directory. +* dispatchMethod: VM. +* div: Byte-Code Operands. +* done: Byte-Code Operands. +* dup: Byte-Code Operands. +* E: Math. +* eof on File: File. +* errno: System. +* error: Global Methods and Properties. +* error on File: File. +* error on System: System. +* errorMessage: JS. +* escape: Global Methods and Properties. +* eval: Global Methods and Properties. +* eval on JS: JS. +* evalFile on JS: JS. +* evalJavaScriptFile on JS: JS. +* exec on RegExp: RegExp. +* executeByteCodeFile on JS: JS. +* exists on File: File. +* exit on System: System. +* exp on Math: Math. +* File: File. +* final on MD5: MD5. +* finalBinary on MD5: MD5. +* float: Global Methods and Properties. +* floor on Math: Math. +* flush on File: File. +* format on Date: Date. +* formatGMT on Date: Date. +* fromCharCode on String: String. +* garbageCollect on VM: VM. +* gcCount: VM. +* gcTrigger: VM. +* getcwd on System: System. +* getDate on Date: Date. +* getDay on Date: Date. +* getenv on System: System. +* getHours on Date: Date. +* getLength on File: File. +* getMinutes on Date: Date. +* getMonth on Date: Date. +* getPosition on File: File. +* getSeconds on Date: Date. +* getTime on Date: Date. +* getTimezoneOffset on Date: Date. +* getVar on JS: JS. +* getYear on Date: Date. +* global: RegExp. +* halt: Byte-Code Operands. +* heapAllocated: VM. +* heapFree: VM. +* heapSize: VM. +* iffalse: Byte-Code Operands. +* iffalse_b: Byte-Code Operands. +* iftrue: Byte-Code Operands. +* iftrue_b: Byte-Code Operands. +* ignoreCase: RegExp. +* indexOf on String: String. +* Infinity: Global Methods and Properties. +* init on MD5: MD5. +* input: RegExp. +* int: Global Methods and Properties. +* isFinite: Global Methods and Properties. +* isFloat: Global Methods and Properties. +* isInt: Global Methods and Properties. +* isNaN: Global Methods and Properties. +* jmp: Byte-Code Operands. +* join on Array: Array. +* JS: JS. +* js_apply: Evaluation and Compilation. +* js_class_context: Classes. +* js_class_create: Classes. +* js_class_define_method: Classes. +* js_class_define_property: Classes. +* js_class_destroy: Classes. +* js_compile: Evaluation and Compilation. +* js_compile_data_to_byte_code: Evaluation and Compilation. +* js_compile_to_byte_code: Evaluation and Compilation. +* js_create_global_method: Defining Global Methods. +* js_create_interp: Interpreter Handling. +* js_define_class: Classes. +* js_define_module: Modules. +* js_destroy_interp: Interpreter Handling. +* js_error_message: Interpreter Handling. +* js_eval: Evaluation and Compilation. +* js_eval_data: Evaluation and Compilation. +* js_eval_file: Evaluation and Compilation. +* js_eval_javascript_file: Evaluation and Compilation. +* js_execute_byte_code: Evaluation and Compilation. +* js_execute_byte_code_file: Evaluation and Compilation. +* js_get_options: Interpreter Handling. +* js_get_var: Interpreter Handling. +* js_init_default_options: Interpreter Handling. +* js_instantiate_class: Classes. +* js_isa: Classes. +* js_lookup_class: Classes. +* js_result: Interpreter Handling. +* js_set_options: Interpreter Handling. +* js_set_var: Interpreter Handling. +* js_type_make_array: Type Handling. +* js_type_make_string: Type Handling. +* js_version: Interpreter Handling. +* JSC$compile_file: Public Entry Points. +* JSC$compile_string: Public Entry Points. +* jsr: Byte-Code Operands. +* jsr_w: Byte-Code Operands. +* lastIndex: RegExp. +* lastIndexOf on String: String. +* lastMatch: RegExp. +* lastParen: RegExp. +* leftContext: RegExp. +* length <1>: String. +* length: Array. +* lineBreakSequence: System. +* LN10: Math. +* LN2: Math. +* load: Global Methods and Properties. +* load_arg: Byte-Code Operands. +* load_array: Byte-Code Operands. +* load_global: Byte-Code Operands. +* load_global_w: Byte-Code Operands. +* load_local: Byte-Code Operands. +* load_nth_arg: Byte-Code Operands. +* load_property: Byte-Code Operands. +* loadClass: Global Methods and Properties. +* locals: Byte-Code Operands. +* log on Math: Math. +* LOG10E: Math. +* LOG2E: Math. +* lstat on File: File. +* MakeDate: Date. +* MakeDay: Date. +* MakeTime: Date. +* match on String: String. +* max on Math: Math. +* MAX_VALUE: Number. +* MD5: MD5. +* min on Math: Math. +* min_args: Byte-Code Operands. +* MIN_VALUE: Number. +* mod: Byte-Code Operands. +* mul: Byte-Code Operands. +* multiline: RegExp. +* NaN <1>: Global Methods and Properties. +* NaN: Number. +* neg: Byte-Code Operands. +* NEGATIVE_INFINITY: Number. +* new: Byte-Code Operands. +* nop: Byte-Code Operands. +* not: Byte-Code Operands. +* nth: Byte-Code Operands. +* Number: Number. +* numConstants: VM. +* numGlobals: VM. +* Object: Object. +* open on Directory: Directory. +* open on File: File. +* or: Byte-Code Operands. +* pack on String: String. +* parse on Date: Date. +* parseFloat: Global Methods and Properties. +* parseInt: Global Methods and Properties. +* PI: Math. +* pop: Byte-Code Operands. +* pop on Array: Array. +* pop_n: Byte-Code Operands. +* popen on System: System. +* POSITIVE_INFINITY: Number. +* pow on Math: Math. +* print: Global Methods and Properties. +* print on System: System. +* push on Array: Array. +* random on Math: Math. +* read on Directory: Directory. +* read on File: File. +* readByte on File: File. +* readln on File: File. +* RegExp: RegExp. +* remove on File: File. +* rename on File: File. +* replace on String: String. +* return: Byte-Code Operands. +* reverse on Array: Array. +* rewind on Directory: Directory. +* rightContext: RegExp. +* roll: Byte-Code Operands. +* round on Math: Math. +* search on String: String. +* seed on Math: Math. +* seek on Directory: Directory. +* setDate on Date: Date. +* setHours on Date: Date. +* setMinutes on Date: Date. +* setMonths on Date: Date. +* setPosition on File: File. +* setSeconds on Date: Date. +* setTime on Date: Date. +* setVar on JS: JS. +* setYear on Date: Date. +* shift on Array: Array. +* shift_left: Byte-Code Operands. +* shift_right: Byte-Code Operands. +* shift_rright: Byte-Code Operands. +* sin on Math: Math. +* sleep on System: System. +* slice on Array: Array. +* slice on String: String. +* sort on Array: Array. +* source: RegExp. +* splice on Array: Array. +* split on String: String. +* sqrt on Math: Math. +* SQRT1_2: Math. +* SQRT2: Math. +* stackSize: VM. +* stackTrace on VM: VM. +* stacktraceOnError: VM. +* stat on File: File. +* stderr: System. +* stdin: System. +* stdout: System. +* store_arg: Byte-Code Operands. +* store_array: Byte-Code Operands. +* store_global: Byte-Code Operands. +* store_local: Byte-Code Operands. +* store_property: Byte-Code Operands. +* strerror on System: System. +* String: String. +* stringToByte on File: File. +* sub: Byte-Code Operands. +* substr on String: String. +* substring on String: String. +* swap: Byte-Code Operands. +* system on System: System. +* tan on Math: Math. +* tell on Directory: Directory. +* test on RegExp: RegExp. +* throw: Byte-Code Operands. +* TimeClip: Date. +* toGMTString on Date: Date. +* toLocaleString on Date: Date. +* toLowerCase on String: String. +* toSource on Array: Array. +* toSource on Object: Object. +* toString on Array: Array. +* toString on Boolean: Boolean. +* toString on File: File. +* toString on Number: Number. +* toString on Object: Object. +* toUpperCase on String: String. +* try_pop: Byte-Code Operands. +* try_push: Byte-Code Operands. +* typeof: Byte-Code Operands. +* unescape: Global Methods and Properties. +* ungetByte on File: File. +* unpack on String: String. +* unshift on Array: Array. +* update on MD5: MD5. +* usleep on System: System. +* UTC on Date: Date. +* valueOf on Boolean: Boolean. +* valueOf on Number: Number. +* valueOf on Object: Object. +* verbose: VM. +* verboseStacktrace: VM. +* version: VM. +* versionMajor: VM. +* versionMinor: VM. +* versionPatch: VM. +* warnUndef: VM. +* with_pop: Byte-Code Operands. +* with_push: Byte-Code Operands. +* write on File: File. +* writeByte on File: File. +* writeln on File: File. +* xor: Byte-Code Operands. + + diff --git a/reactos/lib/kjs/docs/js.texi b/reactos/lib/kjs/docs/js.texi new file mode 100644 index 00000000000..74f4e893a96 --- /dev/null +++ b/reactos/lib/kjs/docs/js.texi @@ -0,0 +1,4885 @@ +\input texinfo @c -*-texinfo-*- +@c %**start of header +@setfilename js.info +@settitle js +@setchapternewpage on +@c %**end of header + +@c (save-excursion (replace-regexp "^@\\(end \\)?cartouche" "@c \\&")) +@c (save-excursion (replace-regexp "^@c \\(@\\(end \\)?cartouche\\)" "\\1")) + +@include version.texi + +@set ECMA ECMA-262 Version 2 draft 22-Apr-98 +@set JSREF Netscape JavaScript Reference 12-Dec-97 +@set NGS NGS JavaScript Interpreter @value{VERSION} + +@dircategory NGS JavaScript Interpreter +@direntry +* libjs: (js). The JavaScript interpreter library. +* js: (js)The js Program. JavaScript interpreter. +@end direntry + +@c Combine function and variable indexes to the Concept index. +@synindex fn cp +@synindex vr cp + +@ifinfo +This file documents NGS JavaScript interpreter @value{VERSION} + +Copyright (C) 1998 New Generation Software (NGS) Oy + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +@ignore +Permission is granted to process this file through TeX and print the +results, provided the printed document carries copying permission +notice identical to this one except for the removal of this paragraph + + +@end ignore +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the entire +resulting derived work is distributed under the terms of a permission +notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that this permission notice may be stated in a translation approved +by the Foundation. +@end ifinfo + + +@titlepage +@title NGS JavaScript Interpreter +@subtitle For version @value{VERSION}, @value{UPDATED} +@author Markku Rossi + +@page +@vskip 0pt plus 1filll +Copyright @copyright{} 1998 New Generation Software (NGS) Oy +@sp 2 +This is the first edition of the NGS JavaScript documentation,@* +and is consistent with NGS JavaScript Interpreter @value{VERSION}.@* + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the entire +resulting derived work is distributed under the terms of a permission +notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that this permission notice may be stated in a translation +approved by the Free Software Foundation. +@end titlepage + +@ifinfo +@node Top, Introduction, (dir), (dir) +@comment node-name, next, previous, up +@top NGS JavaScript Interpreter + +This file documents the NGS JavaScript interpreter. This edition +documents version @value{VERSION}. + +@menu +* Introduction:: +* NGS JavaScript Language:: +* The js Program:: +* The jsas Program:: +* The jsdas Program:: +* The jswrap Program:: +* JavaScript API:: +* Virtual Machine:: +* JavaScript Compiler:: +* GNU Library General Public License:: +* Index:: +@end menu + +@end ifinfo + +@c ---------------------------------------------------------------------- +@node Introduction, NGS JavaScript Language, Top, Top +@chapter Introduction + +@itemize @bullet +@item overall +@item design goals +@item structure: virtual machine, JSC$, JS glue +@end itemize + +@c ---------------------------------------------------------------------- +@node NGS JavaScript Language, The js Program, Introduction, Top +@chapter NGS JavaScript Language + +@menu +* Language:: +* Global Methods and Properties:: +* Native Objects:: +* Extensions:: +@end menu + +@c ---------------------------------------------------------------------- +@node Language, Global Methods and Properties, NGS JavaScript Language, NGS JavaScript Language +@section Language + +@menu +* Lexical Conventions:: +* Function Definition:: +* Statements:: +* Expressions:: +@end menu + +@node Lexical Conventions, Function Definition, Language, Language +@subsection Lexical Conventions + +@menu +* White Space:: +* Comments:: +* Reserved Words:: +* Identifiers:: +* Punctuators:: +* Literals:: +* Automatic Semicolon Insertion:: +@end menu + +@node White Space, Comments, Lexical Conventions, Lexical Conventions +@subsubsection White Space + +@node Comments, Reserved Words, White Space, Lexical Conventions +@subsubsection Comments + +@node Reserved Words, Identifiers, Comments, Lexical Conventions +@subsubsection Reserved Words + +@node Identifiers, Punctuators, Reserved Words, Lexical Conventions +@subsubsection Identifiers + +@node Punctuators, Literals, Identifiers, Lexical Conventions +@subsubsection Punctuators + +@node Literals, Automatic Semicolon Insertion, Punctuators, Lexical Conventions +@subsubsection Literals + +@node Automatic Semicolon Insertion, , Literals, Lexical Conventions +@subsubsection Automatic Semicolon Insertion + +Certain ECMAScript statements must be terminated with a semicolon. Such +a semicolon may always appear explicitly in the source text. For pain +of the compiler implementator, however, such semicolons may be omitted +from the source text in certain situations. These situations are +described in details in the @value{ECMA} standard. Here is +@email{mtr@@ngs.fi}'s interpretation of the rules: + +Insert semicolons as you would do in the C language. Now, you can omit +them: + +@enumerate +@item before '@code{@}}' character +@item from the end of the line +@item from the end of the file +@end enumerate + +@noindent The automatic semicolon insertion sets some restrictions how +you can insert whitespace to you code. You can't insert line breaks: + +@enumerate +@item between @var{LeftHandSideExpression} and @code{++} or @code{--} +operator +@item between @code{return} and the returned @var{Expression} +@end enumerate + + +@node Function Definition, Statements, Lexical Conventions, Language +@subsection Function Definition + + +@node Statements, Expressions, Function Definition, Language +@subsection Statements + +@menu +* Block:: +* Variable Statement:: +* Empty Statement:: +* The if Statement:: +* The do...while Statement:: +* The while Statement:: +* The for Statement:: +* The for...in Statement:: +* The continue Statement:: +* The break Statement:: +* The return Statement:: +* The with Statement:: +* The switch Statement:: +* Labeled Statements:: +* The throw Statement:: +* The try Statement:: +@end menu + +@node Block, Variable Statement, Statements, Statements +@subsubsection Block + +@node Variable Statement, Empty Statement, Block, Statements +@subsubsection Variable Statement + +@node Empty Statement, The if Statement, Variable Statement, Statements +@subsubsection Empty Statement + +@node The if Statement, The do...while Statement, Empty Statement, Statements +@subsubsection The @code{if} Statement + +@node The do...while Statement, The while Statement, The if Statement, Statements +@subsubsection The @code{do}@dots{}@code{while} Statement + +@node The while Statement, The for Statement, The do...while Statement, Statements +@subsubsection The @code{while} Statement + +@node The for Statement, The for...in Statement, The while Statement, Statements +@subsubsection The @code{for} Statement + +@node The for...in Statement, The continue Statement, The for Statement, Statements +@subsubsection The @code{for}@dots{}@code{in} Statement + +@node The continue Statement, The break Statement, The for...in Statement, Statements +@subsubsection The @code{continue} Statement + +@node The break Statement, The return Statement, The continue Statement, Statements +@subsubsection The @code{break} Statement + +@node The return Statement, The with Statement, The break Statement, Statements +@subsubsection The @code{return} Statement + +@node The with Statement, The switch Statement, The return Statement, Statements +@subsubsection The @code{with} Statement + +The syntax of the @code{with}-statement is: + +@example +with (@var{expr}) @var{statement} +@end example + +@c @cartouche +@example +with (Math) + @{ + result = sin (PI); + result -= tan (45); + @} +@end example +@c @end cartouche + +@node The switch Statement, Labeled Statements, The with Statement, Statements +@subsubsection The @code{switch} Statement + +@node Labeled Statements, The throw Statement, The switch Statement, Statements +@subsubsection Labeled Statements + +@node The throw Statement, The try Statement, Labeled Statements, Statements +@subsubsection The @code{throw} Statement + +@node The try Statement, , The throw Statement, Statements +@subsubsection The @code{try} Statement + + + +@node Expressions, , Statements, Language +@subsection Expressions + +@menu +* Primary Expressions:: +* Left-Hand-Side Expressions:: +* Postfix Expressions:: +* Unary Operators:: +* Multiplicative Operators:: +* Additive Operators:: +* Bitwise Shift Operators:: +* Relational Operators:: +* Equality Operators:: +* Binary Bitwise Operators:: +* Binary Logical Operators:: +* Conditional Operator:: +* Assignment Operators:: +* Comma Operator:: +@end menu + +@node Primary Expressions, Left-Hand-Side Expressions, Expressions, Expressions +@subsubsection Primary Expressions + +@node Left-Hand-Side Expressions, Postfix Expressions, Primary Expressions, Expressions +@subsubsection Left-Hand-Side Expressions + +@node Postfix Expressions, Unary Operators, Left-Hand-Side Expressions, Expressions +@subsubsection Postfix Expressions + +@node Unary Operators, Multiplicative Operators, Postfix Expressions, Expressions +@subsubsection Unary Operators + +@node Multiplicative Operators, Additive Operators, Unary Operators, Expressions +@subsubsection Multiplicative Operators + +@node Additive Operators, Bitwise Shift Operators, Multiplicative Operators, Expressions +@subsubsection Additive Operators + +@node Bitwise Shift Operators, Relational Operators, Additive Operators, Expressions +@subsubsection Bitwise Shift Operators + +@node Relational Operators, Equality Operators, Bitwise Shift Operators, Expressions +@subsubsection Relational Operators + +@node Equality Operators, Binary Bitwise Operators, Relational Operators, Expressions +@subsubsection Equality Operators + +@node Binary Bitwise Operators, Binary Logical Operators, Equality Operators, Expressions +@subsubsection Binary Bitwise Operators + +@node Binary Logical Operators, Conditional Operator, Binary Bitwise Operators, Expressions +@subsubsection Binary Logical Operators + +@node Conditional Operator, Assignment Operators, Binary Logical Operators, Expressions +@subsubsection Conditional Operator + +@node Assignment Operators, Comma Operator, Conditional Operator, Expressions +@subsubsection Assignment Operators + +@node Comma Operator, , Assignment Operators, Expressions +@subsubsection Comma Operator + + +@c ---------------------------------------------------------------------- +@node Global Methods and Properties, Native Objects, Language, NGS JavaScript Language +@section Global Methods and Properties + +@table @strong +@item Standard +@value{ECMA} +@end table + +@c --- Properties ------------------------------------------------------- + +@defcv Property Global NaN +The @emph{not a number} value. +@end defcv + +@defcv Property Global Infinity +The @emph{positive infinity} value. +@end defcv + +@c --- Methods ---------------------------------------------------------- + +@defun eval (any) +@end defun + +@defun parseInt (string, radix) +@end defun + +@defun parseFloat (string) +@end defun + +@defun escape (string) +@end defun + +@defun unescape (string) +@end defun + +@defun isNaN (any) +@end defun + +@defun isFinite (any) +@end defun + + +@defun debug (any) + +@table @strong +@item Standard +@value{JSREF} +@end table + +@end defun + + +@defun print (any[,@dots{}]) + +@table @strong +@item Standard +@value{JSREF} ??? +@end table + +@end defun + + +@defun error (message) + +@table @strong +@item Standard +@value{JSREF} ??? +@end table + +@end defun + + +@defun float (any) + +@table @strong +@item Standard +@value{NGS} +@end table + +@end defun + + +@defun int (any) + +@table @strong +@item Standard +@value{NGS} +@end table + +@end defun + + +@defun isFloat (any) + +@table @strong +@item Standard +@value{NGS} +@end table + +@end defun + + +@defun isInt (any) + +@table @strong +@item Standard +@value{NGS} +@end table + +@end defun + +@defun load (file@dots{}) + +@table @strong +@item Standard +@value{NGS} +@end table + +@end defun + + +@defun loadClass (class_spec@dots{}) + +@table @strong +@item Standard +@value{NGS} +@end table + +Extend interpreter by calling an initialization function from shared +library @var{class_spec}. The argument @var{class_spec} can be given in +the following formats: + +@table @code +@item @var{library}:@var{function} + +The argument @var{library} specifies the shared library from which +function @var{function} is called. The library specification can be +given in absolute or relative formats. + +@item @var{library} +The argument @var{library} specifies both the shared library, and the +name of the entry function. The name of the entry function is the name +of the library, without the possible leading directory path and any +suffixes. +@end table + +@c @cartouche +@example +loadClass ("libexts.so:init_all"); +@result{} @var{call function @code{init_all} from library @file{libexts.so}} + +loadClass ("/usr/local/lib/libexts.so:init_all"); +@result{} @var{call function @code{init_all} from library @file{/usr/local/lib/libexts.so}} + +loadClass ("/usr/local/lib/libdbexts.so"); +@result{} @var{call function @code{dbexts} from library @file{/usr/local/lib/libexts.so}} +@end example +@c @end cartouche + +The initialization function must be a void function that takes one +argument that is a pointer to the interpreter. + +@c @cartouche +@example +void +entry (JSInterpPtr interp) +@{ + @var{Initialize extensions using normal @file{js.h} and @file{jsint.h}} + @var{interfaces.} +@} +@end example +@c @end cartouche +@end defun + + +@defun callMethod (object, method, arguments) + +@table @strong +@item Standard +@value{NGS} +@end table + +Call method @var{method} from object @var{object} with arguments +@var{arguments}. + +@c @cartouche +@example +callMethod (System.stdout, "writeln", ["Hello, world!"]); +@print{} Hello, world! +@end example +@c @end cartouche +@end defun + + + + +@c ---------------------------------------------------------------------- +@node Native Objects, Extensions, Global Methods and Properties, NGS JavaScript Language +@section Native Objects + +@menu +* Array:: +* Boolean:: +* Date:: +* File:: +* Directory:: +* Function:: +* Math:: +* Number:: +* Object:: +* RegExp:: +* String:: +* System:: +* VM:: +@end menu + +@c ---------------------------------------------------------------------- +@node Array, Boolean, Native Objects, Native Objects +@subsection Array + +@table @strong +@item Standard +@value{ECMA} +@item Incompatibilities +@itemize @bullet +@item The @code{toSource()} method is missing. +@item The constructor doesn't set the [[Prototype]] and [[Class]] +properties. +@end itemize +@end table + +@defun Array (count) +@defunx Array (item@dots{}) +Do exactly the same as the expression @code{new Array()} called with the +same arguments. +@end defun + +@c --- Constructors ----------------------------------------------------- + +@deffn Constructor Array (count) +@deffnx Constructor Array (item@dots{}) + +Create a new array object. The first form creates a new array which +length is @var{count}. All items are set to value @samp{undefined}. +The second form creates an array that contains the given items as its +values. + +@c @cartouche +@example +var a = new Array (5); +a.length; +@result{} 5 +a.toString (); +@result{} undefined,undefined,undefined,undefined,undefined + +a = new Array (1, 2, "hello"); +a.length; +@result{} 3 +a.toString (); +@result{} 1,2,hello +@end example +@c @end cartouche +@end deffn + +@c --- Methods ---------------------------------------------------------- + +@defmethod Array concat (array[, @dots{}]) +Create a new array object from the items of the called array object and +the argument arrays @var{array}, @dots{}. The contents of the argument +arrays are not modified. + +@c @cartouche +@example +var a = new Array (1, 2, 3); +var b = a.concat (new Array (4, 5)); +b.length; +@result{} 5; +b.toString (); +@result{} 1,2,3,4,5 +@end example +@c @end cartouche +@end defmethod + +@defmethod Array join ([glue]) +Convert the array to a string. Individual items of the array are +combined with the string @var{glue}. If the argument @var{glue} is +omitted, string @code{","} is used. + +@c @cartouche +@example +var a = new Array (1, 2, "three"); +a.join (); +@result{} "1,2,three" + +a.join ("-"); +@result{} "1-2-three" +@end example +@c @end cartouche +@end defmethod + +@defmethod Array pop () +Remove the last item of the array. The method returns the item removed. +If the array is empty, value @code{undefined} is returned. + +@c @cartouche +@example +a = new Array (1, 2, 3); +a.pop (); +@result{} 3 +a.length; +@result{} 2 +@end example +@c @end cartouche +@end defmethod + +@defmethod Array push (any@dots{}) +Insert items to the end of the array. The method returns the last item +pushed. + +@c @cartouche +@example +a = new Array (1, 2); +a.push (7); +@result{} 7 +a.push (7, 8, 9); +@result{} 9 +System.print (a.join (", "), "\n"); +@print{} 1, 2, 7, 7, 8, 9 +@end example +@c @end cartouche +@end defmethod + +@defmethod Array reverse () +Reverse the array. + +@c @cartouche +@example +a = new Array (1, 2, 3); +a.reverse (); +System.print (a.join (""), "\n"); +@print{} 321 +@end example +@c @end cartouche +@end defmethod + +@defmethod Array shift () +Remove item from the beginning of the array. The method returns the +item removed, or value @samp{undefined} if the array was empty. + +@c @cartouche +@example +a = new Array (1, 2, 3); +a.shift (); +@result{} 1 +@end example +@c @end cartouche +@end defmethod + +@defmethod Array slice (start[, end]) +Return a new array containing items between @var{start} (inclusively) +and @var{end} (exclusively) in the array. If the argument @var{end} is +negative, it is counted from the end of the array. If the argument +@var{end} is omitted, the method extract items from the position +@var{start} to the end of the array. + +@c @cartouche +@example +a = new Array (1, 2, 3, 4, 5); +b = a.slice (1, 4); +System.print (b.join (", "), "\n"); +@print{} 2, 3, 4 +b = a.slice (1, -2); +System.print (b.join (", "), "\n"); +@print{} 2, 3 +b = a.slice (2); +System.print (b.join (", "), "\n"); +@print{} 3, 4, 5 +@end example +@c @end cartouche +@end defmethod + +@defmethod Array splice (index, remove[, any@dots{}]) +Modify array by removing old items and by inserting new ones. The +argument @var{index} specifies the index from which the array is +modified. The argument @var{remove} specifies how many old items are +removed. If the argument @var{remove} is 0, no old items are removed +and at least one new item must have been given. After the items are +removed, all remaining arguments are inserted after the position +@var{index}. + +@c @cartouche +@example +var a = new Array (1, 2, 3); +a.splice (1, 1); +@result{} 1, 3 +a.splice (1, 0, "new item"); +@result{} 1, "new item", 2, 3 + +var a = new Array (1, 2, 3, 4); +a.splice (1, 2, "new item"); +@result{} 1, "new item", 4 +@end example +@c @end cartouche +@end defmethod + +@defmethod Array sort ([sort_function]) +Sort the array to the order specified by the argument function +@var{sort_function}. The comparison function @var{sort_function} takes +two arguments and it must return one of the following codes: + +@table @code +@item -1 +the first argument items is smaller than the second item (must come +before the second item) +@item 0 +the items are equal +@item 1 +the first argument item is bigger than the second item (it must come +after the second item) +@end table + +@noindent If the argument @var{sort_function} is omitted, the items are +sorted to an alphabetical (lexicographical) order. + +@c @cartouche +@example +a = new Array ("Jukka-Pekka", "Jukka", "Kari", "Markku"); +a.sort (); +System.print (a, "\n"); +@print{} Jukka,Jukka-Pekka,Kari,Markku +a = new Array (1, 2, 10, 20, 100, 200); +a.sort (); +System.stdout.writeln (a.toString ()); +@print{} 1,10,100,2,20,200 +@end example +@c @end cartouche + +The sort method is stable in that sense that, if the comparison function +returns 0 for two items, their original order in the array is preserved. +For example, if a list of person objects is sorted first by their names, +and second by their ages, all persons with the same age will remain +sorted in an alphabetical order. + +@c @cartouche +@example +function by_age (a, b) +@{ + return a.age - b.age; +@} + +function by_name (a, b) +@{ + if (a.name < b.name) + return -1; + if (a.name > b.name) + return 1; + return 0; +@} + +function Person (name, age) +@{ + this.name = name; + this.age = age; +@} + +a = new Array (new Person ("Smith", 30), + new Person ("Jones", 31), + new Person ("Bob", 30), + new Person ("Chris", 29)); + +a.sort (by_name); +a.sort (by_age); + +for (i in a) + System.print (i.name, ", ", i.age, "\n"); +@print{} Chris, 29 +@print{} Bob, 30 +@print{} Smith, 30 +@print{} Jones, 31 +@end example +@c @end cartouche +@end defmethod + +@defmethod Array toSource () +@end defmethod + +@defmethod Array toString () +Convert the array to a string. The method converts each item of the +array to string and combines them with the string @code{","}. + +@c @cartouche +@example +var a = new Array (1, "foo", 2, new Array (7, 8)); +a.toString (); +@result{} 1,foo,2,7,8 +@end example +@c @end cartouche +@end defmethod + +@defmethod Array unshift (any@dots{}) +Insert items @var{any}@dots{} to the beginning of the array. The method +returns the new length of the array. + +@c @cartouche +@example +a = new Array (1, 2, 3); +System.print (a.unshift (7, 8, 9), "\n"); +@print{} 6 +@end example +@c @end cartouche +@end defmethod + +@defcv Property Array length +The length of the array. + +@c @cartouche +@example +var a = new Array (1, 2); +a.length; +@result{} 2 +a.push (3, 4, 5); +a.length; +@result{} 5 +@end example +@c @end cartouche +@end defcv + +@c ---------------------------------------------------------------------- +@node Boolean, Date, Array, Native Objects +@subsection Boolean + +@table @strong +@item Standard +@value{ECMA} +@item Incompatibilities +@itemize @bullet +@item The constructor doesn't set the [[Prototype]] and [[Class]] +properties. +@end itemize +@end table + +@defun Boolean () +Return @code{false}. +@end defun + +@defun Boolean (value) +@end defun + +@c --- Constructors ----------------------------------------------------- + +@deffn Constructor Boolean () +@deffnx Constructor Boolean (value) +Create a new boolean object. If no arguments are given, the returned +object will have value @samp{false}. If the argument @var{value} is +given, the initial value of the object is determined by the type of the +argument and its value. If the argument @var{value} is +@code{undefined}, @code{null}, @code{false}, @code{""} (an empty +string), or @code{0}, the value of the object will be @samp{false}. All +other values for the argument @var{value} will set the initial value of +the object to @samp{true}. +@end deffn + +@defmethod Boolean toString () +Return a string presentation of the boolean object. The method will +return string @code{"true"} or @code{"false"} according to the value of +the object. +@end defmethod + +@defmethod Boolean valueOf () +@end defmethod + + +@c ---------------------------------------------------------------------- +@node Date, File, Boolean, Native Objects +@subsection Date + +@table @strong +@item Standard +@value{ECMA} +@item Incompatibilities +XXX Check all methods and properties. +@end table + +@defun MakeTime (hour, min, sec, ms) +@end defun + +@defun MakeDay (year, month, date) +@end defun + +@defun MakeDate (day, time) +@end defun + +@defun TimeClip (time) +@end defun + +@defun Date ([a1[, a2[, a3[, a4[, a5[, a6[, a7]]]]]]]) +When the @code{Date} constructor is called as a function, it ignores +arguments @var{a1}@dots{}@var{a7} and returns the result of expression: + +@example +new Date ().toString() +@end example +@end defun + +@deffn Constructor Date () +@deffnx Constructor Date ("@var{month} @var{day}, @var{year} @var{hours}:@var{minutes}:@var{seconds}") +@deffnx Constructor Date (@var{yr_num}, @var{mo_num}, @var{day_num}) +@deffnx Constructor Date (@var{yr_num}, @var{mo_num}, @var{day_num}, @var{hr_num}, @var{min_num}, @var{sec_num}) +@end deffn + +@defop {Static Method} Date UTC (@var{year}, @var{month}, @var{day}, @var{hrs}, @var{min}, @var{sec}) +@end defop + +@defmethod Date format (format) +@end defmethod + +@defmethod Date formatGMT (format) +@end defmethod + +@defmethod Date getDate () +@end defmethod + +@defmethod Date getDay () +@end defmethod + +@defmethod Date getHours () +@end defmethod + +@defmethod Date getMinutes () +@end defmethod + +@defmethod Date getMonth () +@end defmethod + +@defmethod Date getSeconds () +@end defmethod + +@defmethod Date getTime () +@end defmethod + +@defmethod Date getTimezoneOffset () +@end defmethod + +@defmethod Date getYear () +@end defmethod + +@defmethod Date parse (string) +@end defmethod + +@defmethod Date setDate (day) +@end defmethod + +@defmethod Date setHours (hours) +@end defmethod + +@defmethod Date setMinutes (minutes) +@end defmethod + +@defmethod Date setMonths (months) +@end defmethod + +@defmethod Date setSeconds (seconds) +@end defmethod + +@defmethod Date setTime (time) +@end defmethod + +@defmethod Date setYear (year) +@end defmethod + +@defmethod Date toGMTString () +@end defmethod + +@defmethod Date toLocaleString () +@end defmethod + +@c ---------------------------------------------------------------------- +@node File, Directory, Date, Native Objects +@subsection File + +@table @strong +@item Standard +@value{JSREF} +@item Incompatibilities +XXX Check all methods and properties. +@end table + + +@deffn Constructor File (path) +@end deffn + + +@defop {Static Method} File byteToString (byte) +@end defop + +@defop {Static Method} File chmod (path, mode) + +@table @strong +@item Standard +@value{NGS} +@end table + +Change permissions of file @var{path} to @var{mode}. The modes are +specifeid by or'ing the following values: + +@table @code +@item 04000 +set user ID on execution +@item 02000 +set group ID on execution +@item 01000 +sticky bit + +@item 00400 +read by owner +@item 00200 +write by owner +@item 00100 +execute / search by owner + +@item 00040 +read by group +@item 00020 +write by group +@item 00010 +execute / search by group + +@item 00004 +read by others +@item 00002 +write by others +@item 00001 +execute / search by others +@end table +@end defop + +@defop {Static Method} File lstat (path) + +@table @strong +@item Standard +@value{NGS} +@end table + +@end defop + +@defop {Static Method} File remove (path) + +@table @strong +@item Standard +@value{NGS} +@end table + +@end defop + +@defop {Static Method} File rename (path) + +@table @strong +@item Standard +@value{NGS} +@end table + +@end defop + +@defop {Static Method} File stat (path) + +@table @strong +@item Standard +@value{NGS} +@end table + +Return statistics about the file @var{file}. The method returns a 13 +element array containing the statistics, or @samp{false} if the file +couldn't be inspected. + +The returned array contains the following items: + +@table @code +@item dev +Device that contains a directory entry for this file. + +@item ino +Index of this file on its device. A file is uniquely identified by +specifying its @code{dev} and @code{ino}. + +@item mode +The mode of the file. + +@item nlink +The number of hard links to the file. + +@item uid +The ID of the file owner. + +@item gid +The ID of the file group. + +@item rdev +The ID of the device. + +@item size +The size of the file. + +@item atime +The time when the data was last accessed. + +@item mtime +The time when the data was last modified. + +@item ctime +The time when the file status was last changed. + +@item blksize +Preferred blocksize for file system I/O. + +@item blocks +The number of blocks the file actually uses. +@end table + +@c @cartouche +@example +fields = new Array ("dev", "ino", "mode", "nlink", "uid", + "gid", "rdev", "size", "atime", + "mtime", "ctime", "blksize", "blocks"); + +var a = File.stat ("js"); +if (a) + @{ + var i; + for (i = 0; i < a.length; i++) + System.print (fields[i], "=", a[i], " "); + System.print ("\n"); + @} + +@print{} dev=655368 ino=370741 mode=33261 nlink=1 uid=201 gid=200 +@print{} rdev=2979328 size=731370 atime=893159080 mtime=893158537 +@print{} ctime=893158537 blksize=4096 blocks=1432 +@end example +@c @end cartouche +@end defop + + +@defop {Static Method} File stringToByte (string) +@end defop + + + +@defmethod File open (mode) + +The argument @var{mode} must have one of the following values: + +@table @r +@item @code{r}[@code{b}] +@item @code{w}[@code{b}] +@item @code{a}[@code{b}] +@item @code{r+}[@code{b}] +@item @code{w+}[@code{b}] +@item @code{a+}[@code{b}] +@end table + +@end defmethod + +@defmethod File close () +@end defmethod + +@defmethod File setPosition (position[, whence]) +@end defmethod + +@defmethod File getPosition () +@end defmethod + +@defmethod File eof () +@end defmethod + +@defmethod File read (size) +@end defmethod + +@defmethod File readln () +@end defmethod + +@defmethod File readByte () +@end defmethod + +@defmethod File toString () +@end defmethod + +@defmethod File write (string) +@end defmethod + +@defmethod File writeln (string) +@end defmethod + +@defmethod File writeByte (byte) +@end defmethod + +@defmethod File ungetByte (byte) + +@table @strong +@item Standard +@value{NGS} +@end table + +@end defmethod + +@defmethod File flush () +@end defmethod + +@defmethod File getLength () +@end defmethod + +@defmethod File exists () +@end defmethod + +@defmethod File error () +@end defmethod + +@defmethod File clearError () +@end defmethod + +@defcv Property File autoFlush + +@table @strong +@item Standard +@value{NGS} +@end table + +Flag that specifies whether the stream should automatically flush its +buffers after a write. +@end defcv + +@defcv Property File bufferSize + +@table @strong +@item Standard +@value{NGS} +@end table + +The I/O buffer size of the stream. The buffer size can be changed at +the runtime. +@end defcv + +@c ---------------------------------------------------------------------- +@node Directory, Function, File, Native Objects +@subsection Directory + +@table @strong +@item Standard +@value{NGS} +@end table + +@deffn Constructor Directory (path) +@end deffn + +@defmethod Directory close () +@end defmethod + +@defmethod Directory open () +@end defmethod + +@defmethod Directory read () +@end defmethod + +@defmethod Directory rewind () +@end defmethod + +@defmethod Directory seek (pos) +@end defmethod + +@defmethod Directory tell () +@end defmethod + + +@c ---------------------------------------------------------------------- +@node Function, Math, Directory, Native Objects +@subsection Function + +@c ---------------------------------------------------------------------- +@node Math, Number, Function, Native Objects +@subsection Math + +@table @strong +@item Standard +@value{ECMA} +@end table + +@defop {Static Method} Math abs (@var{x}) +@end defop + +@defop {Static Method} Math acos (@var{x}) +@end defop + +@defop {Static Method} Math asin (@var{x}) +@end defop + +@defop {Static Method} Math atan (@var{x}) +@end defop + +@defop {Static Method} Math atan2 (@var{y}, @var{x}) +@end defop + +@defop {Static Method} Math ceil (@var{x}) +@end defop + +@defop {Static Method} Math cos (@var{x}) +@end defop + +@defop {Static Method} Math exp (@var{x}) +@end defop + +@defop {Static Method} Math floor (@var{x}) +@end defop + +@defop {Static Method} Math log (@var{x}) +@end defop + +@defop {Static Method} Math max (@var{x}, @var{y}) +@end defop + +@defop {Static Method} Math min (@var{x}, @var{y}) +@end defop + +@defop {Static Method} Math pow (@var{x}, @var{y}) +@end defop + +@defop {Static Method} Math random () +@end defop + +@defop {Static Method} Math round (@var{x}) +@end defop + +@defop {Static Method} Math seed (@var{x}) + +@table @strong +@item Standard +@value{NGS} +@end table + +@end defop + +@defop {Static Method} Math sin (@var{x}) +@end defop + +@defop {Static Method} Math sqrt (@var{x}) +@end defop + +@defop {Static Method} Math tan (@var{x}) +@end defop + + + +@defcv {Static Property} Math E +@end defcv + +@defcv {Static Property} Math LN10 +@end defcv + +@defcv {Static Property} Math LN2 +@end defcv + +@defcv {Static Property} Math LOG10E +@end defcv + +@defcv {Static Property} Math LOG2E +@end defcv + +@defcv {Static Property} Math PI +@end defcv + +@defcv {Static Property} Math SQRT1_2 +@end defcv + +@defcv {Static Property} Math SQRT2 +@end defcv + +@c ---------------------------------------------------------------------- +@node Number, Object, Math, Native Objects +@subsection Number + +@table @strong +@item Standard +@value{ECMA} +@end table + +@defun Number() +Return value @code{0}. +@end defun + +@defun Number (value) +@end defun + +@c --- Constructors ----------------------------------------------------- + +@deffn Constructor Number () +@deffnx Constructor Number (@var{value}) +Create a new number object. If no argument is given, the constructor +returns value @code{+0}. If the argument @var{value} is given, the +constructor returns @code{ToNumber(@var{value})}. + +@example +new Number (); +@result{} 0 +new Number (3.1415); +@result{} 3.1415 +new Number (true); +@result{} 1 +@end example + +@end deffn + +@defmethod Number toString ([@var{radix}]) +Convert the number to its textual presentation. If the argument +@var{radix} is given, it specifies the radix to which the number is +formatted. If the argument @var{radix} is not given, it defaults to +@code{10}. + +@example +System.stdout.writeln ((193).toString ()); +@print{} 193 +System.stdout.writeln ((193).toString (8)); +@print{} 301 +System.stdout.writeln ((193).toString (16)); +@print{} c1 +System.stdout.writeln ((193).toString (2)); +@print{} 11000001 +@end example +@end defmethod + +@defmethod Number valueOf () +Return the value of the number object. +@end defmethod + + +@defcv {Static Property} Number MAX_VALUE +@end defcv + +@defcv {Static Property} Number MIN_VALUE +@end defcv + +@defcv {Static Property} Number NaN +@end defcv + +@defcv {Static Property} Number NEGATIVE_INFINITY +@end defcv + +@defcv {Static Property} Number POSITIVE_INFINITY +@end defcv + + +@c ---------------------------------------------------------------------- +@node Object, RegExp, Number, Native Objects +@subsection Object + +@table @strong +@item Standard +@value{ECMA} +@item Incompatibilities +@itemize @bullet +@item The @code{toString()} and @code{toSource()} methods are missing. +@item The constructor doesn't set the [[Prototype]] and [[Class]] +properties. +@end itemize +@end table + + +@defun Object ([@var{value}]) +@end defun + +@c --- Constructors ----------------------------------------------------- + +@deffn Constructor Object ([@var{value}]) +Create a new object. + +@example +var o = new Object (); +@end example +@end deffn + +@c --- Methods ---------------------------------------------------------- + +@defmethod Object toString () +@end defmethod + +@defmethod Object toSource () +@end defmethod + +@defmethod Object valueOf () +@end defmethod + + +@c ---------------------------------------------------------------------- +@node RegExp, String, Object, Native Objects +@subsection RegExp + +@table @strong +@item Standard +@value{ECMA} + +@item Incompatibilities +@itemize @bullet +@item The regular expression engine -- taken from the GNU Emacs -- might +not support all features that are required. +@item XXX Check all methods and properties. +@end itemize +@end table + +@deffn Constructor RegExp (pattern[, flags]) + +Create a new regular expression from string @var{pattern}. The optional +argument string @var{flags} can contain the following options: + +@table @code +@item i +Ignore case; the matching is case-insensitive. + +@item g +Global search. This allows you to iterate over all matches of the +expression by executing the @code{exec} method multiple times against +the string. +@end table +@end deffn + +@defmethod RegExp compile (@var{pattern}[, @var{flags}]) +Create a new regular expression from string @var{pattern} using optional +options @var{flags}. The method can be used to change the regular +expression pattern or its flags in the regular expression object. +The method returns an error if the string @var{pattern} do not specify a +well-formed regular expression. + +@strong{Note!} All regular expressions are always compiled in this +implementation. This holds also for the expressions, created with the +@code{RegExp()} constructor. + +@c @cartouche +@example +var re = new RegExp ("ab*"); +re.compile ("ab*", "i"); +@end example +@c @end cartouche +@end defmethod + +@defmethod RegExp exec ([string]) +Match the expression against the string @var{string}. If the argument +@var{string} is omitted, the regular expression is matched against the +@code{RegExp.input} string. The method returns an array that holds the +matched portions of the expression. + +@c @cartouche +@example +var re = new RegExp ("d(b+)(d)", "ig"); +var a = re.exec ("cdbBdbsbz"); +a.toString (); +@result{} "dbBd,bB,d" +@end example +@c @end cartouche +@end defmethod + +In the previous example, the result array @samp{a} has the following +items: + +@table @code +@item dbBd +The substring that matched the regular expression. This string can also +be retrieved as @samp{RegExp.lastMatch}. + +@item bB +The matched substring for the first parenthesized subexpression +@samp{(b+)}. This match can also be found as @samp{RegExp.$1}. + +@item d +The matched substring for the second parentsized subexpression +@samp{(d)}. This match can also be found as @samp{RegExp.$2}. +@end table + +The option @samp{g} of the regular expression can be used to iterate +over multiple matches of the expression on at a time. For example, the +following code fragment searches for the expression @samp{a(b*)} from +the string @samp{str}. In the inial state -- when the expression is +create with the constructor -- the object's @samp{lastIndex} property is +set to 0. When the expression is matched against the string, the +@samp{lastIndex} property is updated to point to the next index from +which the matching should be continued. Therefore, the following +example iterates over all matches in the string @samp{str}. + +@c @cartouche +@example +var re = new RegExp ("a(b*)", "g"); +var str = "abbcdefabh"; +while (a = re.exec (str)) + System.print ("Found ", a, ". Next match starts at ", re.lastIndex, + ".\n"); +@print{} Found abb. Next match starts at 3. +@print{} Found ab. Next match starts at 9. +@end example +@c @end cartouche + +The property @samp{@var{regexp}.lastIndex} can also be set explicitly to +start the matching from a pre-defined position. + + +@defmethod RegExp test ([string]) +Test whether the regular expression matches for the string @var{string}. +If the argument @var{string} is omitted, the regular expression is +tested against the @code{RegExp.input} string. + +@c @cartouche +@example +var re = new RegExp ("fo*bar"); +re.test ("fbar"); +@result{} true +re.test ("fooBar"); +@result{} false + +re = new RegExp ("fo*bar", "i"); +re.test ("FOObAR"); +@result{} true + +RegExp.input = "#include "; +re = new RegExp ("^#"); +re.test (); +@result{} true +@end example +@c @end cartouche +@end defmethod + +@defcv {Static Property} RegExp {$1} +@defcvx {Static Property} RegExp {$2} +@defcvx {Static Property} RegExp {$3} +@defcvx {Static Property} RegExp {$4} +@defcvx {Static Property} RegExp {$5} +@defcvx {Static Property} RegExp {$6} +@defcvx {Static Property} RegExp {$7} +@defcvx {Static Property} RegExp {$8} +@defcvx {Static Property} RegExp {$9} +The matching substring for the @i{n}:th parenthesized subexpression. If +the latest regular expression didn't have that many parenthesized +subexpressions, the property has value @samp{undefined}. +@end defcv + +@defcv {Static Property} RegExp {$_} +@defcvx {Static Property} RegExp {input} +The string against which the expression was tested. The @samp{input} +property is also used, if no string argument was given for the +@samp{test()} or @samp{exec()} methods. + +@c @cartouche +@example +var str = file.readln (); +re.test (str); +RegExp.input; +@result{} @var{The string returned by the @samp{file.readln()} method.} +@end example +@c @end cartouche +@end defcv + +@defcv {Static Property} RegExp lastMatch +The substring that matched the whole expression in the last regular +expression matching. +@end defcv + +@defcv {Static Property} RegExp lastParen +The last parenthesized subexpression of the last regular expression +matching. +@end defcv + +@defcv {Static Property} RegExp leftContext +The substring from the beginning of the input string to the beginning of +the matching substring of the last regular expression. + +@c @cartouche +@example +var re = new RegExp ("foo"); +var str = "garbage foo tail garbage"; +re.exec (str); +RegExp.leftContext; +@result{} "garbage " +@end example +@c @end cartouche +@end defcv + +@defcv {Static Property} RegExp multiline +@end defcv + +@defcv {Static Property} RegExp rightContext +The substring from the end of the matching substring to the end the +input string. + +@c @cartouche +@example +var re = new RegExp ("foo"); +var str = "garbage foo tail garbage"; +re.exec (str); +RegExp.rightContext; +@result{} " tail garbage" +@end example +@c @end cartouche +@end defcv + +@defcv Property RegExp global +Flag that tells if the option @samp{g} was given for the constructor or +for the @code{compile} method. +@end defcv + +@defcv Property RegExp ignoreCase +Flat that tells if the option @samp{i} was given for the construtor or +for the @code{compile} method. +@end defcv + +@defcv Property RegExp lastIndex +The index from which the matching is continued with the global +(@samp{g}) expressions. +@end defcv + +@defcv Property RegExp source +The source string from which the regular expression object was created. +@end defcv + + + +@c ---------------------------------------------------------------------- +@node String, System, RegExp, Native Objects +@subsection String + +@table @strong +@item Standard +@value{ECMA} +@item Incompatibilities +@itemize @bullet +@item The constructor doesn't set the [[Prototype]] and [[Class]] +properties. +@end itemize +@end table + +@deffn Constructor String (string) +Create a new string object and set its data to @var{string}. + +@c @cartouche +@example +var str = new String ("Hello, world"); +@result{} "Hello, world!" +@end example +@c @end cartouche +@end deffn + + +@defop {Static Method} String fromCharCode (code@dots{}) +Create a new string object from the character codes @var{code}@dots{}. + +@c @cartouche +@example +var str = String.fromCharCode (72, 101, 108, 108, 111, 33); +@result{} "Hello!" +@end example +@c @end cartouche +@end defop + +@defop {Static Method} String pack (format, arg[, @dots{}]) + +@table @strong +@item Standard +@value{NGS} +@end table + +Create a new string by packing values @var{arg}@dots{} to a string +according to the format string @var{format}. + +The format is a sequence of characters that specify the type of values +as follows: + +@table @code +@item C +an unsigned char value + +@item n +a short in "network" (big-endian) order + +@item N +a long in "network" (big-endian) order + +@item d +a double-precision float in the native format +@end table +@end defop + + +@defmethod String append (string) + +@table @strong +@item Standard +@value{NGS} +@end table + +Append string @var{string} to the end of the string object. The string +object must be a dynamic string, not a constant string literal. + +@c @cartouche +@example +var str = new String (""); +str.append ("foo"); +str.append ("-"); +str.append ("bar"); +@result{} "foo-bar" +@end example +@c @end cartouche +@end defmethod + +@defmethod String charAt (position) +Create a new string that constains the character from position +@var{position} of the the string object. + +@c @cartouche +@example +"foobar".charAt (3); +@result{} "b" +@end example +@c @end cartouche +@end defmethod + +@defmethod String charCodeAt (position) +Return the code of the character at position @var{position} in the +string object. + +@c @cartouche +@example +"foobar".charCodeAt (3); +@result{} 98 +@end example +@c @end cartouche +@end defmethod + +@defmethod String concat (@var{string}[, @dots{}]) +Create a new string by appending the argument strings @var{string}, +@dots{} to the end of the string object. + +@c @cartouche +@example +"foo".concat ("bar"); +@result{} "foobar" +@end example +@c @end cartouche +@end defmethod + +@defmethod String crc32 () + +@table @strong +@item Standard +@value{NGS} +@end table + +Count a 32-bit CRC of the string. + +@c @cartouche +@example +var str = "Hello, world!"; +System.print ("CRC32 of \"", str, "\" is ", + str.crc32 ().toString (16), ".\n"); +@print{} CRC32 of "Hello, world!" is e4928064. +@end example +@c @end cartouche +@end defmethod + +@defmethod String indexOf (string[, start_index]) +Return the index of the first substring of @var{string} within the +string object, or -1 if the string didn't contain the substring. The +optional argument @var{start_index} can be used to specify the index +from which the searching is started. + +@c @cartouche +@example +var str = "foobar foo bar foo"; +str.indexOf ("foo"); +@result{} 0 +str.indexOf (" foo"); +@result{} 6 +str.indexOf ("foo", 1); +@result{} 7 +str.indexOf ("Foo"); +@result{} -1 +@end example +@c @end cartouche +@end defmethod + +@defmethod String lastIndexOf (string[, start_index]) +Return the the index of the last substring of @var{string} within the +string object, or -1 if the string didn't contain the substring. The +optional argument @var{start_index} can be used to specify the index +from which the searching is started. + +@c @cartouche +@example +var str = "foobar foo bar foo"; +str.lastIndexOf ("foo"); +@result{} 15 +str.lastIndexOf ("bar"); +@result{} 11 +str.lastIndexOf ("foo", 14); +@result{} 7 +str.lastIndexOf ("Foo"); +@result{} -1 +@end example +@c @end cartouche +@end defmethod + +@defmethod String match (regexp) +@end defmethod + +@defmethod String replace (regexp, substitution) +@end defmethod + +@defmethod String search (regexp) +@end defmethod + +@defmethod String slice (start[, end]) +@end defmethod + +@defmethod String split (separtor[, limit]) +@end defmethod + +@defmethod String substr (start[, length]) +@end defmethod + +@defmethod String substring (start[, end]) +@end defmethod + +@defmethod String toLowerCase () +Create a new string which contents is the data of the string object, +converted to the lower case. + +@c @cartouche +@example +"FoObAr".toLowerCase (); +@result{} "foobar" +@end example +@c @end cartouche +@end defmethod + +@defmethod String toUpperCase () +Create a new string which contents is the data of the string object, +converted to the upper case. + +@c @cartouche +@example +"FoObAr".toUpperCase (); +@result{} "FOOBAR" +@end example +@c @end cartouche +@end defmethod + +@defmethod String unpack (format) + +@table @strong +@item Standard +@value{NGS} +@end table + +@end defmethod + + +@defcv Property String length +The length of the string. + +@c @cartouche +@example +"foobar".length; +@result{} 6 +var str = new String ("foo"); +str.append ("bar"); +str.length; +@result{} 6 +@end example +@c @end cartouche +@end defcv + + +@node System, VM, String, Native Objects +@subsection System + +@table @strong +@item Standard +@value{NGS} +@end table + + +@defop {Static Method} System chdir (directory) +Change the process' current working directory to @var{directory}. The +function returns a boolean success status. +@end defop + +@defop {Static Method} System error (any[, @dots{}]) +Convert arguments @var{any}@dots{} to string and print the resulting +string to the standard error stream of the system. +@end defop + +@defop {Static Method} System exit (code) +Terminate the program execution and return the value @var{code} to the +operating system as the return value of the running program. +Effectively the method performs C-code @samp{exit (@var{code})}. +@end defop + +@defop {Static Method} System getcwd () +Get the current working directory of the process. The function returns +a strings presenting the directory or @code{false} if errors were +encountered. +@end defop + +@defop {Static Method} System getenv (variable) +Return the value of the environment variable @var{variable}. The method +returns the value as a string or @samp{undefined} if the variable was +not defined in the environment. +@end defop + +@defop {Static Method} System popen (command, mode) +@end defop + +@defop {Static Method} System print (any[, @dots{}]) +Convert arguments @var{any}@dots{} to string and print the resulting +string to the standard output stream of the system. +@end defop + +@defop {Static Method} System sleep (seconds) +Stop the interpreter for @var{seconds} seconds. +@end defop + +@defop {Static Method} System strerror (errno) +Return a string that describes the system error code @var{errno}. +@end defop + +@defop {Static Method} System system (command) +@end defop + +@defop {Static Method} System usleep (micro_seconds) +Stop the interpreter for @var{micro_seconds} micro seconds. +@end defop + +@defcv {Static Property} System bits +Return a value that describes the "bitness" of the underlying system. +Possible values might be @samp{16}, @samp{32}, @samp{64}, or even +@samp{128}. Normally this is the size of a host system pointer in bits. +@end defcv + +@defcv {Static Property} System canonicalHost +The canonical host name of the system where the interpreter was +compiled. + +@example +System.stdout.writeln (System.canonicalHost); +@print{} powerpc-ibm-aix4.2.1.0 +@end example +@end defcv + +@defcv {Static Property} System canonicalHostCPU +The CPU part of the canonical host name. + +@example +System.stdout.writeln (System.canonicalHostCPU); +@print{} powerpc +@end example +@end defcv + +@defcv {Static Property} System canonicalHostVendor +The Vendor part of the canonical host name. + +@example +System.stdout.writeln (System.canonicalHostVendor); +@print{} ibm +@end example +@end defcv + +@defcv {Static Property} System canonicalHostOS +The OS part of the canonical host name. + +@example +System.stdout.writeln (System.canonicalHostOS); +@print{} aix4.2.1.0 +@end example +@end defcv + +@defcv {Static Property} System errno +The system's error number. The error number can be converted to a +string with the @code{strerror()} method of the System object. + +@example +var fp = new File ("output.txt"); +if (!fp.open ("w")) + System.error ("couldn't create output file `", fp, "': ", + System.strerror (System.errno), "\n"); +@print{} couldn't create output file `output.txt': Permission denied +@end example +@end defcv + +@defcv {Static Property} System lineBreakSequence +The line break sequence that is used in the underlying system. For +example, the outputs from the following lines are identical: + +@example +System.stdout.writeln ("Hello!"); +@print{} Hello! +System.stdout.write ("Hello!" + System.lineBreakSequence); +@print{} Hello! +@end example + +@end defcv + +@defcv {Static Property} System stderr +The system's standard error stream. This is a normal JavaScript file +and all methods of the File object can be called for it. + +@example +System.stderr.writeln ("panic: must exit"); +System.exit (1); +@print{} panic: must exit +@end example +@end defcv + +@defcv {Static Property} System stdin +The system's standard input stream. +@end defcv + +@defcv {Static Property} System stdout +The system's standard output stream. +@end defcv + + +@node VM, , System, Native Objects +@subsection VM + +@table @strong +@item Standard +@value{NGS} +@end table + + +@defop {Static Method} VM garbageCollect () +Perform a garbage collection for the virtual machine heap. Normally, +the garbage collection is triggered automatically, but the +@code{garbageCollect()} method can be used to trigger the collection +explicitly. +@end defop + +@defop {Static Method} VM stackTrace ([@var{limit}]) +Print the contents of the virtual machine stack. Optional argument +@var{limit} specifies how many stack frames are printed. If no +arguments are given, the whole virtual machine stack is printed. + +@c @cartouche +@example +function recursive (n) +@{ + if (n > 5) + VM.stackTrace (); + else + recursive (n + 1); +@} + +recursive (0); +@print{}VM: stacktrace: stacksize=2048, used=78 +@print{}#0 recursive(): builtin 0 +@print{}#1 recursive(): null 1 6 +@print{}#2 recursive(): null 1 5 +@print{}#3 recursive(): null 1 4 +@print{}#4 recursive(): null 1 3 +@print{}#5 recursive(): null 1 2 +@print{}#6 recursive(): null 1 1 +@print{}#7 .global(): null 1 0 +@end example +@c @end cartouche +@end defop + +@defcv {Static Property} VM dispatchMethod +The name of the dispatch method, currently used in the virtual machine. +The method returns a string that describes the method. The possible +return values are @samp{switch-basic}, @samp{switch}, and @samp{jumps}. +@end defcv + +@defcv {Static Property} VM gcCount +How many times the garbage collection has been performed for the heap. +@end defcv + +@defcv {Static Property} VM gcTrigger +The garbage collection trigger. When the virtual machine heap has +allocated more than @code{gcTrigger} number of bytes of memory, the +virtual machine will perform a garbage collection. +@end defcv + +@defcv {Static Property} VM heapAllocated +The number of bytes of memory the system has allocated from the heap. +@end defcv + +@defcv {Static Property} VM heapFree +The number of bytes of memory the heap freelist contains. +@end defcv + +@defcv {Static Property} VM heapSize +The size of the heap in bytes. +@end defcv + +@defcv {Static Property} VM numConstants +The number of constants defined in the virtual machine. +@end defcv + +@defcv {Static Property} VM numGlobals +The number of global symbols defined in the virtual machine. This value +equals to the number of global variables and functions, defined in the +system. +@end defcv + +@defcv {Static Property} VM stackSize +The size of the virtual machine stack. +@end defcv + +@defcv {Static Property} VM stacktraceOnError +A boolean flag that tells whether the virtual machine stack trace is +printed if an error occurs in the program execution. +@end defcv + +@defcv {Static Property} VM verbose +The verbosity level of the virtual machine. +@end defcv + +@defcv {Static Property} VM verboseStacktrace +A boolean flag that tells whether the virtual machine prints the normal +or verbose stacktrace. +@end defcv + +@defcv {Static Property} VM version +The version string of the interpreter virtual machine. +@end defcv + +@defcv {Static Property} VM versionMajor +The major version number of the virtual machine. +@end defcv + +@defcv {Static Property} VM versionMinor +The minor version number of the virtual machine. +@end defcv + +@defcv {Static Property} VM versionPatch +The patch level number of the virtual machine. +@end defcv + +@defcv {Static Property} VM warnUndef +A boolean flag that tells whether the virtual machine should print a +warning message if an undefined variable is used. +@end defcv + + + +@node Extensions, , Native Objects, NGS JavaScript Language +@section Extensions + +@menu +* Curses:: +* JS:: +* MD5:: +@end menu + +@node Curses, JS, Extensions, Extensions +@subsection Curses + + +@node JS, MD5, Curses, Extensions +@subsection JS + +@deffn Constructor JS () +@end deffn + +@defmethod JS compile (file, asm_file, bc_file) +@end defmethod + +@defmethod JS eval (string) +@end defmethod + +@defmethod JS evalFile (filename) +@end defmethod + +@defmethod JS evalJavaScriptFile (filename) +@end defmethod + +@defmethod JS executeByteCodeFile (filename) +@end defmethod + +@defmethod JS getVar (name) +@end defmethod + +@defmethod JS setVar (name, value) +@end defmethod + +@defcv Property JS errorMessage +@end defcv + +@c ---------------------------------------------------------------------- +@node MD5, , JS, Extensions +@subsection MD5 + +@deffn Constructor MD5 () +Create a new MD5 message digest object. + +@c @cartouche +@example +var md5 = new MD5 (); +@end example +@c @end cartouche +@end deffn + +@defmethod MD5 final () +Return the MD5 value of the data, set to the object with the +@code{update()} method. The method returns a 32 bytes long string that +holds the MD5 value as a hexadecimal number. + +@c @cartouche +@example +function print_md5 (str) +@{ + var md5 = new MD5 (); + md5.update (str); + System.print ("MD5 of \"", str, "\" is ", + md5.final (), ".\n"); +@} +print_md5 ("Hello, world!"); +@print{} MD5 of "Hello, world!" is 6CD3556DEB0DA54BCA060B4C39479839. +@end example +@c @end cartouche +@end defmethod + +@defmethod MD5 finalBinary () +Return the MD5 value of the data. The method returns a 128 bits long +MD5 value. +@end defmethod + +@defmethod MD5 init () +Initalize the object to the initial state. The method can be used to +reset the object after some data has been set to it with the +@code{update()} method. +@end defmethod + +@defmethod MD5 update (str) +Append data to the object. The method can be called multiple times, so +that the MD5 message digest can be counted one block at a time. + +@c @cartouche +@example +function count_md5_for_file (stream) +@{ + var md5 = new MD5 (); + + while (!stream.eof ()) + @{ + var data = stream.read (1024); + md5.update (data); + @} + + return md5.final (); +@} +@end example +@c @end cartouche +@end defmethod + + +@c ---------------------------------------------------------------------- +@node The js Program, The jsas Program, NGS JavaScript Language, Top +@chapter The @file{js} Program + +The @samp{js} program is the JavaScript interpreter command. It can be +used to execute JavaScript and JavaScript byte-code files. The progam +can also be used to compile JavaScript files into the byte-code files. + +@menu +* Invoking The js Program:: +* Evaluating and Executing Code:: +* Compiling JavaScript Code:: +@end menu + +@node Invoking The js Program, Evaluating and Executing Code, The js Program, The js Program +@section Invoking The @samp{js} Program + +The @code{js} program is invoked as: + +@code{js} @var{option}@dots{} @var{file} [@var{argument}@dots{}] + +@noindent The @code{js} program processes the command line options and +when the first non-option argument, or the option @samp{--file}, is +encountered, it is assumed to contain JavaScript or byte-code that +should be evaluated. The interpreter will pass all remaining arguments +to the script throught the @samp{ARGS} array. The items in the array +are strings containing the arguments @var{argument}@dots{}. The first +item of the array is always the name of the script @var{file}. + +The options can be one or more of the following command line options: + +@table @code +@item -a +@itemx --annotate-assembler + +Annotate the created assembler listing with the original JavaScript +source code. The option can be used only with the @samp{--assembler} +option. + +@item -c +@itemx --compile + +Compile JavaScript files to byte-code. The generated byte-code is saved +to file which name is created from the name of the input file by +replacing the suffix @samp{.js} with the suffix @samp{.jsc}. The +compilation can be controlled with options @samp{--debug}, +@samp{--optimize}, and @samp{--compiler-option}. + +@item -d @var{type} +@itemx --dispatch=@var{type} + +Use the byte-code instruction dispatch method @var{type}. The current +implementation supports the following dispatch methods: + +@table @code +@item switch-basic + +The basic switch-method using a big switch-case table to dispatch the +instruction. This method is available only if the interpreter has been +configured with the option @samp{--with-all-dispatchers}. + +@item switch + +An optimized version of the switch-method. This method is supported on +all environments. + +@item jumps + +The fastest dispatch method that uses the `computed goto' statement of +the GNU C-compiler. This method is available if the interpreter has +been compiler with the GNU C-compiler. +@end table + +The default dispatch method, for environments that has the GNU +C-compiler, is @samp{jumps}. For all other environments, the default +method is @samp{switch}. + + +@item -e @var{code} +@itemx --eval=@var{code} + +Evaluate JavaScript code @var{code}. + +@cartouche +@example +$ js --eval='System.print ("Hello, world!\n");' +@print{} Hello, world! +@end example +@end cartouche + + +@item -E +@itemx --events + +Print the interpreter events to the standard error. + +@cartouche +@example +$ js -E -c test.js +[js: garbage collect] +[js: garbage collect] +[js: garbage collect] +[js: garbage collect] +@end example +@end cartouche + + +@item -f +@itemx --file + +Stop processing options and use the next argument as the name of the +JavaScript (or byte-code) file. All the remaining arguments are passed +to the interpreter through the @code{ARGS} array. The first item of the +array will be the name of the script, i.e. the argument that follows the +option @samp{--file}. + +@cartouche +@example +$ cat hello.js +@print{} var i; +@print{} for (i = 0; i < ARGS.length; i++) +@print{} System.print (i, ": ", ARGS[i], "\n"); +$ js --file hello.js a b c d +@print{} 0: hello.js +@print{} 1: a +@print{} 2: b +@print{} 3: c +@print{} 4: d +@end example +@end cartouche + +The option can also be used with the option @samp{--load} to indicate +the last file to load. Also in that case, the remaining arguments will +be passed to the script through the @code{ARGS} array. + +@item -g +@itemx --debug + +Make the compiler to generate debugging information to the generated +byte-code files. This option can be used with the option +@samp{--compile}. + +@item -h +@itemx --help + +Print a short help message that describes the options that can be given +to the @samp{js} program. + +@item -l +@itemx --load + +Load multiple JavaScript and JavaScript byte-code files to the +interpreter. Normally, the first non-option argument is evaluated and +all remaining arguments are passed to the script as arguments. With the +option @code{--load}, multiple files can be loaded the to the +interpreter. The loading can be stopped with option @code{--file} that +specifies the last file to load. + +For example, if we have files @file{a.js}: + +@example +function do_a () +@{ + System.print ("do_a()\n"); +@} +@end example + +@noindent @file{b.js}: + +@example +function do_b () +@{ + System.print ("do_b()\n"); +@} +@end example + +@noindent and @file{main.js}: + +@example +do_a (); +do_b (); +@end example + +@noindent the whole application can be run as: + +@cartouche +@example +$ js --load a.js b.js --file main.js @var{arguments}@dots{} +@print{} do_a() +@print{} do_b() +@end example +@end cartouche + +@item -N +@itemx --no-compiler + +Do not define the compiler to the virtual machine. This option makes +the interpreter smaller, but the interpreter can only execute +pre-compiled byte-code files. The option disables the @samp{eval} +global method. + +@item -O [@var{level}] +@itemx --optimize[=@var{level}] + +Set the compiler optimization level to @var{level}. The compiler has +three different optimization levels: + +@table @code +@item 0 +Do not optimize. + +@item 1 +Perform all cheap optimizations which do not required heavy assembler +instruction analyzing. + +@item 2 +Perform all optimizations, supported by the compiler. +@end table + +The default optimization level is 1. + +@item -r @var{option} +@itemx --secure=@var{option} + +Turn on virtual machine security option @var{option}. The following +security options are available: + +@table @code +@item file +Disable insecure methods from the buit-in File object. + +@item system +Disable insecure methods from the buit-in System object. +@end table + + +@item -s @var{size} +@itemx --stack-size=@var{size} + +Set the size of the virtual machine operand stack to @var{size}. The +size of the virtual machine operand stack is set at the startup-time and +it can't be enlarged dynamically at the runtime. + +@item -S +@itemx --assembler + +Compile JavaScript files to JavaScript assembler. The generated +assembler listing is saved to file which name is created from the name +of the input file by replacing the suffix @samp{.js} with the suffix +@samp{.jas}. The compilation can be controlled with options +@samp{--optimize}, and @samp{--compiler-option}. + +@item -t +@itemx --stacktrace + +Print a stack trace on error. When an error occurs during the +evaluation of a script, the virtual machine will halt and the @samp{js} +program terminates. If the option @samp{--stacktrace} was given to the +interpreter, the virtual machine will print a stack trace that shows the +call stack at the point of the error. + +The following listing showns an program that raises an error at the +specified recursion level. + +@example +function recursive (level) +@{ + if (level <= 0) + error ("recursion limit exceeded"); + else + recursive (level - 1); +@} + +recursive (5); +@end example + +@noindent If the program is executed without the @samp{--stacktrace} +option, the following result is shown: + +@example +$ js hello.js +js: evaluation of file `hello.js' failed: +hello.js:6: recursion limit exceeded +@end example + +@noindent With the @samp{--stacktrace} option, the @samp{js} program +will print the following error message: + +@cartouche +@example +$ js --stacktrace hello.js +@print{} VM: error: hello.js:6: recursion limit exceeded +@print{} VM: stacktrace: stacksize=2048, used=44 +@print{} #0 recursive(): null 1 "recursion limit exceeded" +@print{} #1 recursive(): null 1 0 +@print{} #2 recursive(): null 1 1 +@print{} #3 recursive(): null 1 2 +@print{} #4 recursive(): null 1 3 +@print{} #5 recursive(): null 1 4 +@print{} #6 .global(): null 1 5 +@print{} js: evaluation of file `hello.js' failed: +@print{} hello.js:6: recursion limit exceeded +@end example +@end cartouche + +@item -v +@itemx --verbose + +Increase the verbosity of the interpreter. The option can be given +multiple times to increase the amount of messages the interpreter +prints. + +@item -V +@itemx --version + +Print the version number of the @code{js} program. + +@item -W @var{option} +@itemx --compiler-option=@var{option} + +Set JavaScript compiler options according to the option specification +@var{option}. The specification @var{option} can be given in two forms. +In the normal form, the option specifies a compiler option that should +be set on. If the specification @var{option} starts with the prefix +`@code{no-}', the specified option will be turn off. The following +option specifications are currently implemented: + +@table @code +@item all +match most of the compile time options + +@item pedantic +match all compile time options. This option generates as much warnings +as possible. It will also complain about some things that are allowed +by the ECMAScript standard, but which are consired to show bad +programming style, for example, missing semicolons. + +@item runtime +match all runtime options + +@item shadow +warn if a variable declaration shadows a parameter + +@item undefined +runtime check for undefined global variables + +@item unused-argument +warn about unused arguments + +@item unused-variable +warn about unused local variables + +@item with-clobber +warn if the with-lookup of a symbol is clobbered because the symbol is +defined to be a local variable or a function argument + +@item missing-semicolon +warn about missing semicolons that are fixed by the missing semicolon +inserting during the compilation + +@item strict-ecma +warn about things that are supported by this implementation, but are not +allowed by the ECMAScript standard. These features are: + +@itemize @bullet +@item line terminators in string and regular expression constants +@end itemize + + +@item deprecated +warn if deprecated features has been used in the source code + +@end table + +@item -x +@itemx --executable +Add execute permissions to the generated byte-code files. This option +is useful on Linux environments where JavaScript byte-code files can be +executed natively with the `binfmt_js' module. + +@cartouche +@example +$ cat hello.js +@print{} System.stdout.writeln ("Hello, world!"); +$ js -cx hello.js +$ ./hello.jsc +@print{} Hello, world! +@end example +@end cartouche + +@end table + + +@node Evaluating and Executing Code, Compiling JavaScript Code, Invoking The js Program, The js Program +@section Evaluating and Executing Code + +@node Compiling JavaScript Code, , Evaluating and Executing Code, The js Program +@section Compiling JavaScript Code + +The compilation of JavaScript code is carried out with the following +command: + +@code{js} [@var{options}] @code{-c} @var{file}@dots{} + +@noindent where @var{file} is a JavaScript source file to compile and +@var{options} specify additional compiler options. + +In the simplest form, the compilation goes as follows: + +@cartouche +@example +$ js -c hello.js +@end example +@end cartouche + +@noindent This example compiles file @file{hello.js} to byte-code file +@file{hello.jsc} with the default compiler options. + +@menu +* Warning Messages:: +* Optimization:: +* Debugging Information:: +* Assembler Listings:: +@end menu + +@node Warning Messages, Optimization, Compiling JavaScript Code, Compiling JavaScript Code +@subsection Warning Messages + +It is nice to get as many error messages as possible at the compilation +time. However, sometimes some error messages are false and it is +annoying to see them every time you compile your project. The option +@code{--compiler-option} can be used to adjust the level of warning +messages the compiler generates. + +Normally we want to get all possible compiler time warnings. They can +be enable with the @code{-Wall} option. To set the warnings +individually, the following options can be given for the +@code{--compiler-option} option. The option names can be prefixed with +string @samp{no-} to turn them off instead of setting them. For +example, let's assume that we want to get as much warnings as possible, +but we do not care about unused function arguments: + +@cartouche +@example +$ js -Wall -Wno-unused-arguments -c hello.js +@end example +@end cartouche + +@noindent In this example, we turn on all warnings @samp{-Wall}, but we +turn off warnings about unused arguments @samp{-Wno-unused-arguments}. + +The @code{js} program knows the following warning options: + +@table @code +@item shadow +Warn if a variable declaration shadows a parameter. For example, when +compiling file @file{test.js} containing code: + +@example +function foo (a, b) +@{ + var a = 1; + return a + b; +@} +@end example + +@noindent the following warning is generated: + +@cartouche +@example +$ js -Wshadow -c test.js +@print{} test.js:3: warning: declaration of `a' shadows a parameter +@end example +@end cartouche + +@item unused-argument +Warn if an argument is not used in the function body. For example, when +compiling file @file{test.js} containing code: + +@example +function foo (a, b) +@{ + return a + 5; +@} +@end example + +@noindent the following warning is generated: + +@cartouche +@example +$ js -Wunused-argument -c test.js +@print{} test.js:1: warning: unused argument `b' +@end example +@end cartouche + +@item unused-variable +Warn if a local variable is not used in the function body. For example, +when compiling file @file{test.js} containing code: + +@example +function foo (a, b) +@{ + var c; + return a + b; +@} +@end example + +@noindent the following warning is generated: + +@cartouche +@example +$ js -Wunused-variable -c test.js +@print{} test.js:3: warning: unused variable `c' +@end example +@end cartouche + +@item with-clobber +Warn if the with-lookup of a symbol is clobbered because the symbol is +defined to be a local variable or a function argument. For example, +when compiling file @file{test.js} containing code: + +@example +function foo (PI) +@{ + with (Math) + System.print ("PI=", PI, "\n"); +@} +@end example + +@noindent the following warning is generated: + +@cartouche +@example +$ js -Wwith-clobber -c test.js +@print{} test.js:4: warning: the with-lookup of symbol `PI' is +@print{} clobbered by the argument definition +@end example +@end cartouche + +@item missing-semicolon +Warn if a semicolon is missing from the input. The missing semicolons +are inserted during the parsing by the automatic semicolon inserting. +However, since the missing semicolons show bad programming style, this +option will warn about them. For example, when compiling file +@file{test.js} containing code: + +@example +function foo () +@{ + return 1 +@} + +foo () +@end example + +@noindent the following warnings are generated: + +@cartouche +@example +$ js -Wmissing-semicolon -c test.js +test.js:3: warning: missing semicolon +test.js:6: warning: missing semicolon +@end example +@end cartouche + +@item strict-ecma +warn about things that are supported by this implementation, but are not +allowed by the ECMAScript standard. For example, when compiling file +@file{test.js} containing code: + +@example +function foo () +@{ + System.stdout.writeln ("Hello, world! +"); +@} +@end example + +@noindent the following warning is generated: + +@cartouche +@example +$ js -Wstrict-ecma -c test.js +test.js:3: warning: ECMAScript don't allow line terminators in +string constants +@end example +@end cartouche + + +@item deprecated +warn if deprecated features has been used in the source code. For +example, when compiling file @file{test.js} containing code: + +@example +function foo () +@{ + for (var i in arguments) + System.stdout.writeln (i); +@} +@end example + +@noindent the following warning is generated: + +@cartouche +@example +$ js -Wdeprecated -c test.js +test.js:1: warning: the `arguments' property of Function instance +is deprecated +@end example +@end cartouche + +@end table + +Besides the compiler time checks, the virtual machine can also perform +some checks at the runtime. These checks can be set and unset with the +@samp{-Wruntime} option. + +The following runtime warnings are supported: + +@table @code +@item undefined +Warn if the value of an undefined global variable is used. For example, +when running file @file{test.js} containing code: + +@example +foo = an_undefined_variable; +@end example + +@noindent the following warning is generated: + +@cartouche +@example +$ js test.js +@print{} VM: warning: using undefined global `an_undefined_variable' +@end example +@end cartouche + +@end table + + +@node Optimization, Debugging Information, Warning Messages, Compiling JavaScript Code +@subsection Optimization + +@node Debugging Information, Assembler Listings, Optimization, Compiling JavaScript Code +@subsection Debugging Information + +As a default, the JavaScript compiler do not include symbolic debugging +information to the generated byte-code files. The debugging information +can be generated by giving the compiler @code{-g} option. The debugging +information is also generated for the internal byte-code files that are +created when the interpreter evaluates plain JavaScript source code. + +In the current implementation, the debugging information contains only +the names of the source files, and mappings from the virtual machine +program counter offsets to the source file locations. In the future, it +will contain information about local variables and function arguments, +so that the symbolic debugger can print their values. + +The presence of the debugging information shows in the error messages +the interpreter shows. For example, let's consider the following +JavaScript source code file @file{test.js}: + +@example +function foo (a) +@{ + a += 1; + if (a > 50) + error ("a overflow"); + + return 1; +@} + +foo (50); +@end example + +When this file is compiled to the byte-code without debugging +information, the following error message is raised: + +@cartouche +@example +$ js -c test.js +$ js test.jsc +@print{} js: evaluation of file `test.jsc' failed: +@print{} a overflow +@end example +@end cartouche + +If we recompile the file with the debugging information, we will get a +more precise error message from the interpreter: + +@cartouche +@example +$ js -g -c test.js +$ js test.jsc +@print{} js: evaluation of file `test.js' failed: +@print{} test.js:5: a overflow +@end example +@end cartouche + +@noindent Now we see the exact source code location where the error +occurred. + +The debugging information can be removed from the byte-code files after +the compilation with the @code{jsdas} program. + +@cartouche +@example +$ jsdas --strip test.jsc +test.jsc: +jsdas: removing section 3 +$ js test.jsc +js: evaluation of file `test.jsc' failed: +a overflow +@end example +@end cartouche + +@node Assembler Listings, , Debugging Information, Compiling JavaScript Code +@subsection Assembler Listings + +The JavaScript compiler can generate assembler listings from the +JavaScript source files. The assembler listings are generated just +before the resulting byte-code data would be generated. So the resulting +assembler listing is exactly the same that will be in the resulting +byte-code data. The assembler listing is generated with the +@code{--assembler} option. For example, if we have a source file +@file{hello.js} with the following contents: + +@example +function hello () +@{ + System.stdout.writeln ("Hello, world!"); + return true; +@} + +hello (); +@end example + +@noindent it can be compiled to assembler with command + +@cartouche +@example +$ js -S hello.js +@end example +@end cartouche + +@noindent The command will save the assembler listing in file +@file{hello.jas}: + +@example +hello: + load_arg 1 + add_2_i + min_args 2 + const "Hello, world!" + const_i1 + load_global System + load_property stdout + call_method writeln + pop_n 4 + const_true + return + +.global: + const_i0 + const_null + jsr hello + apop 2 +@end example + +The option @code{--annotate-assembler} can be used with the +@code{--assembler} option. It mixes the original source code to the +generated assembler listing. In this format, it is easy to see how +different JavaScript constructs are compiled in the assembler. Our +example file can be compiled to the annotated assembler with the +following command: + +@cartouche +@example +$ js -a -S hello.js +@end example +@end cartouche + +@noindent The result listing is saved to file @file{hello.jas}: + +@example +; -*- asm -*- +; function hello () + +hello: +; @{ + load_arg 1 + add_2_i + min_args 2 +; System.stdout.writeln ("Hello, world!"); + const "Hello, world!" + const_i1 + load_global System + load_property stdout + call_method writeln + pop_n 4 +; return true; + const_true + return +; @} +; +; hello (); + +.global: + const_i0 + const_null + jsr hello + apop 2 +@end example + + +@c ---------------------------------------------------------------------- +@node The jsas Program, The jsdas Program, The js Program, Top +@chapter The @samp{jsas} Program + +The @samp{jsas} program is a assembler for the JavaScript assembler. +The program can be used to compile assembler files into byte-code. + +@menu +* Invoking The jsas Program:: +@end menu + +@node Invoking The jsas Program, , The jsas Program, The jsas Program +@section Invoking The @samp{jsas} Program + +The @code{jsas} program is invoked as: + +@code{jsas} @var{option}@dots{} @var{file}@dots{} + +The program reads the options and processes the assembler files +@var{file}@dots{} according to the options. The options can be one of +more of the following command line options: + +@table @code +@item -g +@itemx --debug + +Make the assembler to generate debugging information to the generated +byte-code files. + +@item -h +@itemx --help + +Print a short help message that describes the options that can be given +to the @samp{jsas} program. + +@item -O +@itemx --optimize + +Optimize the assembler instructions. + +@item -v +@itemx --verbose + +Turn on verbose diagnostic messages. When this options is given, the +@code{jsas} program tells what it is doing. + +@item -V +@itemx --version + +Print the version number of the @code{jsas} program. + +@end table + +@c ---------------------------------------------------------------------- +@node The jsdas Program, The jswrap Program, The jsas Program, Top +@chapter The @samp{jsdas} Program + +The @samp{jsdas} program is a disassembler and a manipulator for the +JavaScript byte-code files. The program can be used to view, +disassemble and manipulate the byte-code files. + +@menu +* Invoking The jsdas Program:: +* Viewing Byte-Code Files:: +* Manipulating Byte-Code Files:: +@end menu + +@node Invoking The jsdas Program, Viewing Byte-Code Files, The jsdas Program, The jsdas Program +@section Invoking The @samp{jsdas} Program + +The @code{jsdas} program is invoked as: + +@code{jsdas} @var{option}@dots{} @var{file}@dots{} + +The program reads the options and processes the byte-code files +@var{file}@dots{} according to the options. The options can be one or +more of the following command line options: + +@table @code +@item -c +@itemx --code + +Print the code section of the byte-code files. This is the default +action that is preformed if no options are given for the @code{jsdas} +program. + +@item -C +@itemx --constants + +Print the constants section of the byte-code file. + +@item -d +@itemx --debug + +Print the debug section of the byte-code file. + +@item -h +@itemx --help + +Print a short help message that describes the options that can be given +to the @code{jsdas} program. + +@item -i +@itemx --info + +Print the byte-code file information. + +@item -l @var{type} @var{data} +@itemx --link @var{type} @var{data} + +Link a new section to the byte-code file. The section's type is +@var{type} and its contents is read from file @var{data}. + +@item -r @var{type} +@itemx --remove @var{type} + +Remove section of type @var{type} from the byte-code files. + +@item -s +@itemx --symtab + +Print the symbol table section of the byte-code file. + +@item -S +@itemx --strip + +Remove the debug section from the byte-code files. + +@item -V +@itemx --version + +Print the version number of the @code{jsdas} program. +@end table + +@node Viewing Byte-Code Files, Manipulating Byte-Code Files, Invoking The jsdas Program, The jsdas Program +@section Viewing Byte-Code Files + +In this section we assume that we have a source file @file{hello.js} +with the following contents: + +@c @cartouche +@example +function main () +@{ + System.print ("Hello, world!\n"); +@} + +main (); +@end example +@c @end cartouche + +The file has been compiled to byte-code file @file{hello.jsc} with the +following command: + +@cartouche +@example +$ js -Wall -g -c hello.js +@end example +@end cartouche + +The option @samp{--info} is used to view the contents of the byte-code +file. For example, our example file contains the following information: + +@cartouche +@example +$ jsdas --info hello.jsc +hello.jsc: + +* byte-code file information + + section 0: type=0 (code), length=34 + section 1: type=1 (constants), length=40 + section 2: type=2 (symtab), length=25 + section 3: type=3 (debug), length=40 +@end example +@end cartouche + +@noindent We see that the byte-code file has four sections: code, +constants, symtab and debug. The listing shows also their lengths. The +sections are: + +@table @code +@item code +the byte-code instructions of the file + +@item constants +the constant values of the file + +@item symtab +the symbol table + +@item debug +the debugging information +@end table + +Next, we would like to see a assembler listing of the byte-code, defined +in the @code{code} section of the file. This can be viewed with the +option @samp{--code} that is the @code{jsdas}'s default option (so no +options for the following example). + +@cartouche +@example +$ jsdas hello.jsc +hello.jsc: + +* section `Code' + +main: + 0 load_arg 1 + 2 add_2_i + 3 min_args 2 + 5 const "Hello, world!\n" + 10 const_i1 + 11 load_global System + 16 call_method print + 21 pop_n 4 + 23 const_undefined + 24 return + +.global: + 25 const_i0 + 26 const_null + 27 jsr main + 32 apop 2 +@end example +@end cartouche + +The constants section holds the constant data the byte-code instructions +need. These constants are pushed to the stack with the @code{const} +byte-code operand, or they are used to name a symbol in method +invocation or in subroutine call. + +The constant section can be viewed with the @samp{--constants} option. + +@cartouche +@example +$ jsdas --constants hello.jsc +hello.jsc: + +* section `Constants' + + 0: "Hello, world!\n" + 1: System + 2: print + 3: main +@end example +@end cartouche + +Our example file defines four constants. A string @samp{Hello, +world!\n} and three symbols @samp{System}, @samp{print}, and +@samp{main}. + +The debugging information holds line number information about the source +file from which the file was compiled. The debugging section can be +viewed with the option @samp{--debug}: + +@cartouche +@example +$ jsdas --debug hello.jsc +hello.jsc: + +* section `Debug' + + 2 hello.js:2 + 10 hello.js:3 + 26 hello.js:6 +@end example +@end cartouche + +The symbol table hold the information about the global symbols the +byte-code file defines. For each symbol, the symbol table has an offset +that points to the appropriate location in the byte-code instruction +stream. + +The symbol table information can be viewed with the @samp{--symtab} +option: + +@cartouche +@example +$ jsdas --symtab hello.jsc +hello.jsc: + +* section `Symtab' + + main 0 + .global 25 +@end example +@end cartouche + +@node Manipulating Byte-Code Files, , Viewing Byte-Code Files, The jsdas Program +@section Manipulating Byte-Code Files + +@cartouche +@example +$ jsdas --link 7001 hello.js hello.jsc +hello.jsc: +jsdas: linking 67 bytes of data to section 7001 +$ jsdas --info hello.jsc +hello.jsc: + +* byte-code file information + + section 0: type=0 (code), length=34 + section 1: type=1 (constants), length=40 + section 2: type=2 (symtab), length=25 + section 3: type=3 (debug), length=40 + section 4: type=7001, length=67 +@end example +@end cartouche + +@cartouche +@example +$ jsdas --remove 3 hello.jsc +hello.jsc: +jsdas: removing section 3 +$ jsdas --remove 7001 hello.jsc +hello.jsc: +jsdas: removing section 7001 +$ jsdas -i hello.jsc +hello.jsc: + +* byte-code file information + + section 0: type=0 (code), length=34 + section 1: type=1 (constants), length=40 + section 2: type=2 (symtab), length=25 +@end example +@end cartouche + +@c ---------------------------------------------------------------------- +@node The jswrap Program, JavaScript API, The jsdas Program, Top +@chapter The `@code{jswrap}' Program + +The @code{jswrap} program is a tool that helps implementing C functions +in JavaScript. + +@menu +* Invoking The jswrap Program:: +* Definition File Format:: +* Re-Entrant Functions:: +* Calling the Functions from C:: +* Sample Project:: +@end menu + +@node Invoking The jswrap Program, Definition File Format, The jswrap Program, The jswrap Program +@section Invoking The @code{jswrap} Program + +The @code{jswrap} program is invoked as: + +@code{jswrap} @var{options}@dots{} @var{file} + +@noindent The @code{jswrap} program processes the command line options +and according to them and the default values, it converts the input file +@var{file} to the corresponding @file{.h} and @file{.c} files. The +options can be one of more of the following command line options: + +@table @code +@item -g +@itemx --debug + +Generate debugging information to the generated JavaScript byte-code. + +@item -h @var{file} +@itemx --header @var{file} + +Generate the C header file to file @var{file}. The default C header +file name is constructed from the input file name by replacing the +suffix @file{.jsw} with suffix @file{.h}. + +@item -n +@itemx --no-error-handler + +Do not generate the default error handler to the generated C files. If +this option is specified, then the error handler must be defined in your +code. + +@item -o +@itemx --output @var{file} + +Generate the C output to file @var{file}. The default output file name +is constructed from the input file name by replacing the suffix +@file{.jsw} with suffix @file{.c}. + +@item -r +@itemx --reentrant + +Generate re-entrant C functions. The option adds a `@code{JSInterpPtr}' +argument to all C functions it generates. + +@item -V +@itemx --version +Print the version number of the @code{jswrap} program. + +@item --help +Print a short help message that describes the options that can be given +to the @code{jswrap} program. +@end table + + +@node Definition File Format, Re-Entrant Functions, Invoking The jswrap Program, The jswrap Program +@section Definition File Format + +The definition file contains the function definitions and their +implementation in JavaScript. The function definitions are normal +JavaScript function definitions but they are extended with the type +information. The type information is used to generate the C header +files and the glue code that is used in the function call. The +definition file can also contain normal JavaScript comments. The +comments are ignored and they are not copied to the generated C header +and implementation files. + +The syntax of the function definition is: + +@example +function [@var{return_type}] @var{function_name} @code{(}@var{argument_type}@dots{} @var{argument}[, @dots{}]@code{)} +@{ + @var{JavaScript code implementing the function.} +@} +@end example + +@noindent Where: + +@table @var +@item return_type + +specifies the return type of the function. If the return type +specification is omitted, the function is a @code{void} function +returning no value. + +@item function_name + +is the name of the function. The name must be a valid C identifier +matching regular expression `@code{^[A-Za-z_][A-Za-z_0-9]*}'. + +@item argument_type + +specifies the type of the argument, its passing type, and the life scope +of the value of the argument. + +@item argument + +is the name of the argument. The name must be a valid C identifier. +@end table + + +@menu +* The Type Specifiers:: +* The Pass-Type Specifiers:: +* The Life Scope Specifiers:: +@end menu + +@node The Type Specifiers, The Pass-Type Specifiers, Definition File Format, Definition File Format +@subsection The Type Specifiers + +The type specifiers specify the native C and JavaScript type that is +used for the argument or for the return value. The following type are +supported: + +@table @code +@item cstring + +A @code{'\0'} terminated C-string. In the C, this is presented as +`@code{char *}'. In the JavaScript, this is a normal string. + +@item double + +A floating point number. In the C, this is a `@code{double}' floating +point number. + +@item int + +An integer Number. In the C, this is a `@code{long}' integer. + +@item string + +An arbitrary data block. In the C, this is presented as `@code{unsigned +char *}, @code{unsigned int}' pair. In the JavaScript, this is a normal +string. @strong{Note!} Because the type's presentation in C is two +types, this value can't be used as a return value of a function. +@end table + +The following example shows how the types are converted to the +corresponding C header file. The input file @file{types.jsw} is as +follows: + +@example +function types (cstring vcstring, double vdouble, int vint, + string vstring) +@{ +@} +@end example + +The resulting C header file @file{types.h} contains the following +definitions for the function @code{types}: + +@example +void types ( + char *vcstring, + double vdouble, + long vint, + unsigned char *vstring, + unsigned int vstring_len + ); +@end example + + +@node The Pass-Type Specifiers, The Life Scope Specifiers, The Type Specifiers, Definition File Format +@subsection The Pass-Type Specifiers + +The passing type specifiers specify how the argument is passed to the +function. The following specifies are supported: + +@table @code +@item in + +An input argument. This is the default pass-type for arguments. + +@item out + +An output argument. In the JavaScript, the initial value of the +argument is @code{undefined}. When the control returns from the +implementation of the function, the argument's current value is returned +to the calling C function. + +In the C, the output and input-output arguments are presented as +pointers to the variables, containing the values. + +@item inout + +An input-output argument. +@end table + +The following example shows show the output and input-output arguments +are presented in the C header file. The input file @file{pass.jsw} is +as follows: + +@example +function pass (out cstring vcstring, out double vdouble, inout int vint, + inout string vstring) +@{ +@} +@end example + +The resulting C header file @file{pass.h} contains the following +definitions for the function @code{pass}: + +@example +void pass ( + char **vcstring, + double *vdouble, + long *vint, + unsigned char **vstring, + unsigned int *vstring_len + ); +@end example + + +@node The Life Scope Specifiers, , The Pass-Type Specifiers, Definition File Format +@subsection The Life Scope Specifiers + +The life scope specifiers specify the liveness of the value, passed in +an argument. The following specifiers are supported: + +@table @code +@item static + +The argument points to static data that can't change while the execution +is in the JavaScript code. This means that the JavaScript can use the +same data that is given to it; it don't have to make a private copy of +the data. The specifier can only be used with @code{cstring} and +@code{string} types. + +The specifier don't have any affect for the generated C header file. +@end table + + +@node Re-Entrant Functions, Calling the Functions from C, Definition File Format, The jswrap Program +@section Re-Entrant Functions + + + +@node Calling the Functions from C, Sample Project, Re-Entrant Functions, The jswrap Program +@section Calling the Functions from C + + +@node Sample Project, , Calling the Functions from C, The jswrap Program +@section Sample Project + +@example +function hello (cstring user) +@{ + System.stdout.writeln ("Hello, " + user + "!"); +@} + +function int max_sum (int a, int b, int out sum) +@{ + sum = a + b; + + return a > b ? a : b; +@} +@end example + +@cartouche +@example +$ jswrap sample.jsw +@end example +@end cartouche + +@example +/* This file is automatically generated from `hello.jsw' by jswrap. */ + +#ifndef HELLO_H +#define HELLO_H + +void hello ( + char *user + ); + +int max_sum ( + int a, + int b, + int *sum + ); + +#endif /* not HELLO_H */ +@end example + +@example +#include +#include "hello.h" + +JSInterpPtr jswrap_interp; + +int +main (int argc, char *argv[]) +@{ + int a, b, max, sum; + + jswrap_interp = js_create_interp (NULL); + + hello ("World"); + + a = 5; + b = 7; + max = max_sum (a, b, &sum); + printf ("%d + %d = %d, max(%d, %d) = %d\n", a, b, sum, a, b, max); + + return 0; +@} +@end example + +@c ---------------------------------------------------------------------- +@node JavaScript API, Virtual Machine, The jswrap Program, Top +@chapter JavaScript API + +@menu +* Interpreter Handling:: +* Evaluation and Compilation:: +* Type Handling:: +* Defining Global Methods:: +* Classes:: +* Modules:: +@end menu + +@node Interpreter Handling, Evaluation and Compilation, JavaScript API, JavaScript API +@section Interpreter Handling + +@deftypefun {const char *} js_version () +Return a string that describes the JavaScript interpreter version +number. The returned string is in format +@code{"@var{major}.@var{minor}.@var{patch}"}, where @var{major}, +@var{minor}, and @var{patch} are integer numbers. +@end deftypefun + +@deftypefun void js_init_default_options (JSInterpOptions *@var{options}) +Initialize the interpreter options @var{options} to the default values. +These are the same values that are used in the interpreter creation, if +the argument @var{options} of @code{js_create_interp()} is @code{NULL}. +@end deftypefun + +@deftypefun JSInterpPtr js_create_interp (JSInterpOptions *@var{options}) +Create a new JavaScript interpreter. The function returns an +interpreter handle that must be passed to all other interpreter API +functions. The argument @var{options} specify additional options for +the interpreter. If the argument is NULL, the default values are used. +If the interpreter creation fails -- due insufficient memory resources +-- the function return value @code{NULL}. +@end deftypefun + +@deftypefun void js_destroy_interp (JSInterpPtr @var{interp}) +Destroy interpreter @var{interp} and free all resources the interpreter +has allocated. The handle @var{interp} must not be used after this +function. +@end deftypefun + +@deftypefun {const char *} js_error_message (JSInterpPtr @var{interp}) +Return an error message of the latest error in interpreter @var{interp}. +@end deftypefun + +@deftypefun void js_result (JSInterpPtr @var{interp}, JSType *@var{result_return}) +Get the result of the latest evaluation or execution in interpreter +@var{interp}. The result is returned in @var{result_return}. All data, +returned in @var{result_return}, belongs to the interpreter. The caller +must not modify or changed it in any ways. +@end deftypefun + +@deftypefun void js_set_var (JSInterpPtr @var{interp}, char *@var{name}, JSType *@var{value}) +@end deftypefun + +@deftypefun void js_get_var (JSInterpPtr @var{interp}, char *@var{name}, JSType *@var{value}) +@end deftypefun + +@deftypefun void js_get_options (JSInterpPtr @var{interp}, JSInterpOptions *@var{options}) +Get the options of interpreter @var{interp} to @var{options}. +@end deftypefun + +@deftypefun void js_set_options (JSInterpPtr @var{interp}, JSInterpOptions *@var{options}) +Modify the options of interpreter @var{interp} according to +@var{options}. +@end deftypefun + + + +@node Evaluation and Compilation, Type Handling, Interpreter Handling, JavaScript API +@section Evaluation and Compilation + +@deftypefun int js_eval (JSInterpPtr @var{interp}, char *@var{code}) +Evaluate JavaScript code @var{code} with interpreter @var{interp}. The +argument @var{code} is NUL-terminated a C-string holding the JavaScript +code. The function returns 1 if the operation was successful or 0 +otherwise. If the evaluation failed, the error message can be retrieved +with function @code{js_error_message()}. +@end deftypefun + +@deftypefun int js_eval_data (JSInterpPtr @var{interp}, char *@var{data}, unsigned int @var{datalen}) +Evaluate JavaScript code @var{data}, @var{datalen} with interpreter +@var{interp}. +@end deftypefun + +@deftypefun int js_eval_file (JSInterpPtr @var{interp}, char *@var{filename}) +Evaluate file @var{filename} with interpreter @var{interp}. The file +@var{filename} can contain JavaScript or byte-code. +@end deftypefun + +@deftypefun int js_eval_javascript_file (JSInterpPtr @var{interp}, char *@var{filename}) +Evaluate JavaScript code file @var{filename} with interpreter +@var{interp}. +@end deftypefun + +@deftypefun int js_execute_byte_code_file (JSInterpPtr @var{interp}, char *@var{filename}) +Execute a byte-code file @var{filename} with interpreter @var{interp}. +@end deftypefun + +@deftypefun int js_apply (JSInterpPtr @var{interp}, char *@var{name}, unsigned int @var{argc}, JSType *@var{argv}) +Call function @var{name} with arguments @var{argc}, @var{argv}. The +return value of the function @var{name} can be retrieved with the +@code{js_result()} function. +@end deftypefun + +@deftypefun int js_compile (JSInterpPtr @var{interp}, char *@var{input_file}, char *@var{assembler_file}, char *@var{byte_code_file}) +Compile JavaScript input file @var{input_file}. If the argument +@var{assembler_file} is not @code{NULL}, the generated assembler code is +saved to the file, specified by the argument. If the argument +@var{byte_code_file} is not @code{NULL}, the generated byte-code data is +svaed to the file, specified by the argument. +@end deftypefun + +@deftypefun int js_compile_to_byte_code (JSInterpPtr @var{interp}, char *@var{input_file}, unsigned char **@var{bc_return}, unsigned int *@var{bc_len_return}); +Compile JavaScript file @var{input_file} to byte-code and return the +resulting byte-code data in @var{bc_return}, @var{bc_len_return}. The +returned byte-code data @var{bc_return} belongs to the interpreter and +it must be saved by the caller @strong{before} any other JS functions is +called. If the data is not saved, its contents will be invalidated at +the next garbage collection. +@end deftypefun + +@deftypefun int js_compile_data_to_byte_code (JSInterpPtr @var{interp}, char *@var{data}, unsigned int @var{datalen}, unsigned char **@var{bc_return}, unsigned int *@var{bc_len_return}); + +Compile JavaScript code @var{data}, @var{datalen} to byte-code and +return the resulting byte-code data in @var{bc_return}, +@var{bc_len_return}. +@end deftypefun + +@deftypefun int js_execute_byte_code (JSInterpPtr @var{interp}, unsigned char *@var{bc}, unsigned int @var{bc_len}); + +Execute byte-code data @var{bc}, @var{bc_len}. The byte-code data is +the contents of a byte-code file, or a copy of the data returned by the +@code{js_compile_to_byte_code()} or +@code{js_compile_data_to_byte_code()} functions. + +@strong{Note!} You can't use the data from the +@code{js_compile_to_byte_code()}, @code{js_compile_data_to_byte_code()} +functions as an input for this function. You must take a private copy +of the data and pass that copy to the function: + +@example +if (js_compile_to_byte_code (interp, file, &bc, &bclen)) + @{ + char *bc_copy = xmalloc (bclen); + memcpy (bc_copy, bc, bclen); + js_execute_byte_code (interp, bc_copy, bclen); + xfree (bc_copy); + @} +@end example +@end deftypefun + + +@node Type Handling, Defining Global Methods, Evaluation and Compilation, JavaScript API +@section Type Handling + +@deftypefun void js_type_make_string (JSInterpPtr @var{interp}, JSType *@var{type}, unsigned char *@var{data}, unsigned int @var{length}) +Create a new string type from @var{length} bytes of data @var{data}. +The result string is created to @var{type}. +@end deftypefun + +@deftypefun void js_type_make_array (JSInterpPtr @var{interp}, JSType *@var{type}, unsigned int @var{length}) +Create a new array type of length @var{length}. The result array is +created to @var{type}. +@end deftypefun + + + +@node Defining Global Methods, Classes, Type Handling, JavaScript API +@section Global Methods + +@deftypefun void js_create_global_method (JSInterpPtr @var{interp}, char *@var{name}, JSGlobalMethodProc @var{proc}, void *@var{context}, JSFreeProc @var{context_free_proc}) +@end deftypefun + + + +@node Classes, Modules, Defining Global Methods, JavaScript API +@section Classes + +@deftypefun JSClassPtr js_class_create (void *@var{class_context}, JSFreeProc @var{class_context_destructor}, int @var{no_auto_destroy}, JSConstructor @var{constructor}) + +Create a new class with class context data @var{class_context}. The +context data is destroyed with @var{class_context_destructor}. If the +argument @var{no_auto_destroy} is not 0, the JavaScript interpreter will +@strong{not} destroy the class when the interpreter is destroyed. In +that case, it is the caller's responsibility to call +@code{js_class_destroy()} for the returned class handle, after the +interpreter has been destroyed. If the argument @var{constructor} is +not @code{NULL}, it is used to instantiate the class when a `@code{new +}@var{class}@code{ (}@var{args}[@dots{}]@code{);}' expression is +evaluated in the JavaScript code. +@end deftypefun + +@deftypefun void js_class_destroy (JSClassPtr @var{cls}) +Destroy class handle @var{cls}. The class handle must be created by the +@code{js_class_create()} function, so that value @code{1} was given for +the @var{no_auto_destroy} argument. +@end deftypefun + +@deftypefun JSVoidPtr js_class_context (JSClassPtr @var{cls}) +Return the class context of class @var{cls}. The returned value is the +same that was given for the @var{class_context} argument in call of +function @code{js_class_create()}. +@end deftypefun + +@deftypefun int js_class_define_method (JSClassPtr @var{cls}, char *@var{name}, unsigned int @var{flags}, JSMethodProc @var{method}) +Define a new method for the class @var{cls}. The name of the new method +is @var{name} and its implementation is @var{method}. The argument +@var{flags} can have the following flags: + +@table @code +@item JS_CF_STATIC +The created method is a static method. +@end table +@end deftypefun + +@deftypefun int js_class_define_property (JSClassPtr @var{cls}, char *@var{name}, unsigned int @var{flags}, JSPropertyProc @var{property}) +Define a new property for the class @var{cls}. The name of the property +is @var{name} and its setter and getter function is @var{property}. The +argument @var{flags} can have the following flags: + +@table @code +@item JS_CF_STATIC +The property is a static property. + +@item JS_CF_IMMUTABLE +The property is immutable. An error to try to set the property. +@end table +@end deftypefun + +@deftypefun int js_define_class (JSInterpPtr @var{interp}, JSClassPtr @var{cls}, char *@var{name}) +Define the class @var{cls} to the interpreter @var{interp} with name +@var{name}. If the value @code{0} was given for the argument +@var{no_auto_destroy} of the function @code{js_class_create()}, the +handle @var{cls} must not be used after this call. +@end deftypefun + +@deftypefun int js_instantiate_class (JSInterpPtr @var{interp}, JSClassPtr @var{cls}, void *@var{instance_ctx}, JSFreeProc @var{instance_ctx_destructor}, JSType *@var{result_return}) +@end deftypefun + +@deftypefun {const JSClassPtr} js_lookup_class (JSInterpPtr @var{interp}, char *@var{name}) +Lookup the class context by name from the interpreter @var{interp}. +@end deftypefun + +@deftypefun int js_isa (JSInterpPtr @var{interp}, JSType *@var{object}, JSClassPtr @var{cls}, void **@var{instance_context_return}) + +Check if object @var{object} is an instance of class @var{cls}. The +function returns a boolean success status. If the argument +@var{instance_context_return} is not @code{NULL}, it will be set to the +instance context of object @var{object}. +@end deftypefun + +@node Modules, , Classes, JavaScript API +@section Modules + +@deftypefun int js_define_module (JSInterpPtr @var{interp}, JSModuleInitProc @var{init_proc}) +@end deftypefun + +@c ---------------------------------------------------------------------- +@node Virtual Machine, JavaScript Compiler, JavaScript API, Top +@chapter Virtual Machine + +@menu +* Byte-Code File Format:: +* Byte-Code Operands:: +* Stack Frame:: +@end menu + +@node Byte-Code File Format, Byte-Code Operands, Virtual Machine, Virtual Machine +@section Byte-Code File Format + +@menu +* File Header:: +* Code Section:: +* Constants Section:: +* Symtab Section:: +* Debug Section:: +@end menu + +@node File Header, Code Section, Byte-Code File Format, Byte-Code File Format +@subsection File Header + +@table @code +@item magic +An @code{UInt32} number containing the JavaScript byte-code file magic. +The value of the magic is @code{0xc0014a53}. + +@item nsects +An @code{UInt32} number containing the number of sections in this +byte-code file. +@end table + +@node Code Section, Constants Section, File Header, Byte-Code File Format +@subsection Code Section + +@node Constants Section, Symtab Section, Code Section, Byte-Code File Format +@subsection Constants Section + +The constants section contains the constant values of the byte-code. +The different constant types are stored as follows: + +@table @r +@item integer + +(UInt8)@code{3}, (Int32)@var{value} + +@item string + +(UInt8)@code{4}, (UInt32)@var{length}, @var{length bytes of data} + +@item float + +(UInt8)@code{5}, (double)@var{value} + +@item symbol + +(UInt8)@code{10}, @var{symbol name}, (UInt8)@code{0} + +@item NaN + +(UInt8)@code{13} + +@item regular expression + +(UInt8)@code{100}, (UInt8)@var{flags}, (UInt32)@var{length}, @var{length +bytes of regexp source} + +The item @var{flags} holds the regular expression flags. It is a +combination of the following flags: + +@table @code +@item 0x01 +global match +@item 0x02 +ignore case +@end table + +@end table + +@node Symtab Section, Debug Section, Constants Section, Byte-Code File Format +@subsection Symtab Section + +@node Debug Section, , Symtab Section, Byte-Code File Format +@subsection Debug Section + + +@node Byte-Code Operands, Stack Frame, Byte-Code File Format, Virtual Machine +@section Byte-Code Operands + +The virtual machine knows the following byte-code operands. Each +operand is identified by a 8 bit long unsigned integer number. The +first operand @code{halt} has code 0, the next operand @code{done} has +code 1, and so on. Some operand take arguments that are shown after the +operand name in the following listing. The meanings of the arguments +are: + +@table @code +@item Int8 +The code of the operand is followed by a 8 bit long integer number +argument. + +@item Int16 +The code of the operand is followed by a 16 bit long integer number +argument. + +@item Int32 +The code of the operand is followed by a 32 bit long integer number +argument. + +@item Symbol +The code of the operand is followed by a 32 bit long integer number +argument. The number is an offset to the constant section and the +specified constant is a symbol that is the argument of the operand. +@end table + +The notation + +@var{before} @result{} @var{after} + +@noindent desribes how the operand modifies the virtual machine stack. +For example, the notation: + +--- @result{} @code{undefined} + +@noindent means that the operand takes no items from the stack and it +pushes value @code{undefined} to the stack. The notation: + +@var{any} @var{any} @result{} @code{boolean} + +@noindent means that the operand takes two items from the stack and it +pushes a boolean result to the stack. + +The virtual machine knows the following byte-code operands. + +@deffn Operand halt @ @ --- @result{} --- +Halt the virtual machine. The program execution stops immediately and +the virtual machine starts execute the following C-code: + +@example +while (1) + sleep (5); +@end example + +@noindent This "sleep forever" loop is implemented for debugging +purposes. +@end deffn + +@deffn Operand done @ @ --- @result{} --- +The execution of the byte-code is finished and the control returns to +the calling C-function. +@end deffn + +@deffn Operand nop @ @ --- @result{} --- +Do nothing; no operation. +@end deffn + +@deffn Operand dup @ @ any @result{} any any +Duplicate the item at the top of the stack. +@end deffn + +@deffn Operand pop @ @ any @result{} --- +Remove one item from the top of the stack. +@end deffn + +@deffn Operand pop_n @code{Int8} @ @ any @dots{} any @result{} --- +Remove @var{Int8} items from the top of the stack. +@end deffn + +@deffn Operand apop @code{Int8} @ @ any_n @dots{} any_0 @result{} any_0 +Remove @var{Int8} items from the top of the stack, leaving the topmost +item on the top of the stack. This operand is used to remove arguments +of a function call, leaving the function's return value to the top of +the stack. +@end deffn + +@deffn Operand swap @ @ any_1 any_2 @result{} any_2 any_1 +Swap the two topmost items in the stack. +@end deffn + +@deffn Operand roll @code{Int8} @ @ any_n @dots{} any_1 any_0 @result{} any_0 any_n @dots{} any_1 +@end deffn + +@deffn Operand const @code{Int32} @ @ --- @result{} const +Push a constant from the constant section to the stack. The constant is +specified by the value @var{Int32}. +@end deffn + +@deffn Operand const_null @ @ --- @result{} @code{null} +Push value @code{null} to the stack. +@end deffn + +@deffn Operand const_true @ @ --- @result{} @code{true} +Push value @code{true} to the stack. +@end deffn + +@deffn Operand const_false @ @ --- @result{} @code{false} +Push value @code{false} to the stack. +@end deffn + +@deffn Operand const_undefined @ @ --- @result{} @code{undefined} +Push value @code{undefined} to the stack. +@end deffn + +@deffn Operand const_i0 @ @ --- @result{} @code{0} +Push integer number @code{0} to the stack. +@end deffn + +@deffn Operand const_i1 @ @ --- @result{} @code{1} +Push integer number @code{1} to the stack. +@end deffn + +@deffn Operand const_i2 @ @ --- @result{} @code{2} +Push integer number @code{2} to the stack. +@end deffn + +@deffn Operand const_i3 @ @ --- @result{} @code{3} +Push integer number @code{3} to the stack. +@end deffn + +@deffn Operand const_i @code{Int32} @ @ --- @result{} @code{Int32} +Push integer number @code{Int32} to the stack. +@end deffn + +@deffn Operand load_global @code{Symbol} @ @ --- @result{} value +Push the value of the global variable @var{Symbol} to the stack. The +operand will @strong{not} lookup the variable @var{Symbol} from the +with-chain. +@end deffn + +@deffn Operand store_global @code{Symbol} @ @ value @result{} --- +Store the topmost item of the stack to the global variable @var{Symbol}. +@end deffn + +@deffn Operand load_arg @code{Int8} @ @ --- @result{} value +Push the value of the argument @var{Int8} to the stack. +@end deffn + +@deffn Operand store_arg @code{Int8} @ @ value @result{} --- +Store the topmost item of the stack to the argument @var{Int8}. +@end deffn + +@deffn Operand load_local @code{Int16} @ @ --- @result{} value +Push the value of the local variable @var{Int16} to the stack. +@end deffn + +@deffn Operand store_local @code{Int16} @ @ value @result{} --- +Store the topmost item of the stack to the local variable @var{Int16}. +@end deffn + +@deffn Operand load_property @code{Symbol} @ @ object @result{} value +Push the value of the property @var{Symbol} of object @var{object} to +the stack. +@end deffn + +@deffn Operand store_property @code{Symbol} @ @ object value @result{} --- +Save the value @var{value} to the property @var{Symbol} of object +@var{object}. +@end deffn + +@deffn Operand load_array @ @ object index @result{} value +Push the @var{index}:th item of object @var{object} to the stack. +@end deffn + +@deffn Operand store_array @ @ value object index @result{} --- +Store the value @var{value} to the @var{index}:th position of object +@var{object}. +@end deffn + +@deffn Operand nth @ @ any integer @result{} item boolean +Push the @var{integer}:th item of object @var{any} to the stack. Push a +boolean success status that tells whether the object @var{any} did +contain @var{integer}:th item. +@end deffn + +@deffn Operand cmp_eq @ @ any1 any2 @result{} boolean +Compare the two objects @var{any1}, @var{any2} for equality and push a +boolean result code to the stack. +@end deffn + +@deffn Operand cmp_ne @ @ any any @result{} boolean +Compare the two objects @var{any1}, @var{any2} for inequality and push a +boolean result code to the stack. +@end deffn + +@deffn Operand cmp_lt @ @ any1 any2 @result{} boolean +Compare whether object @var{any1} is smaller than object @var{any2}. +Push a boolean result code to the stack. +@end deffn + +@deffn Operand cmp_gt @ @ any1 any2 @result{} boolean +Compare whether object @var{any1} is greater than object @var{any2}. +Push a boolean result code to the stack. +@end deffn + +@deffn Operand cmp_le @ @ any1 any2 @result{} boolean +Compare whether object @var{any1} is smaller than, or equal to object +@var{any2}. Push a boolean result code to the stack. +@end deffn + +@deffn Operand cmp_ge @ @ any1 any2 @result{} boolean +Compare whether object @var{any1} is greater than, or equal to object +@var{any2}. Push a boolean result code to the stack. +@end deffn + +@deffn Operand cmp_seq @ @ any1 any2 @result{} boolean +Compare the two objects @var{any1}, @var{any2} for strict equality and +push a boolean result code to the stack. +@end deffn + +@deffn Operand cmp_sne @ @ any any @result{} boolean +Compare the two objects @var{any1}, @var{any2} for strict inequality and +push a boolean result code to the stack. +@end deffn + +@deffn Operand sub @ @ any1 any2 @result{} result +Substract object @var{any2} from object @var{any1} and push the +result to the stack. +@end deffn + +@deffn Operand add @ @ any1 any2 @result{} result +Add object @var{any2} to object @var{any1} and push the result to +the stack. +@end deffn + +@deffn Operand mul @ @ any1 any2 @result{} result +Multiply object @var{any1} with object @var{any2} and push the result to +the stack. +@end deffn + +@deffn Operand div @ @ any1 any2 @result{} result +Divide object @var{any1} with object @var{any2} and push the result to +the stack. +@end deffn + +@deffn Operand mod @ @ integer1 integer2 @result{} result +Count object @var{integer1} modulo object @var{integer2} and push the +result to the stack. +@end deffn + +@deffn Operand neg @ @ any @result{} result +Negate object @var{any} and push the result to the stack. +@end deffn + +@deffn Operand and @ @ any1 any2 @result{} result +Perform a bitwise and operation between objects @var{any1} and +@var{any2} and push the result to the stack. +@end deffn + +@deffn Operand not @ @ any1 any2 @result{} result +Perform a bitwise not operation between objects @var{any1} and +@var{any2} and push the result to the stack. +@end deffn + +@deffn Operand or @ @ any1 any2 @result{} result +Perform a bitwise or operation between objects @var{any1} and @var{any2} +and push the result to the stack. +@end deffn + +@deffn Operand xor @ @ any1 any2 @result{} result +Perform a bitwise xor operation between objects @var{any1} and @var{any2} +and push the result to the stack. +@end deffn + +@deffn Operand shift_left @ @ integer1 integer2 @result{} integer +Shift integer number @var{integer1} left @var{integer2} bits. Push the +result value to the stack. +@end deffn + +@deffn Operand shift_right @ @ integer1 integer2 @result{} integer +Shift integer number @var{integer1} right @var{integer2} bits. Push the +result value to the stack. +@end deffn + +@deffn Operand shift_rright @ @ integer1 integer2 @result{} integer +@end deffn + +@deffn Operand iffalse @code{Int32} @ @ any @result{} --- +If the topmost item in the stack has boolean value `false', adjust the +program counter with relative offset @var{Int32}. +@end deffn + +@deffn Operand iftrue @code{Int32} @ @ any @result{} --- +If the topmost item in the stack has boolean value `true', adjust the +program counter with relative offset @var{Int32}. +@end deffn + +@deffn Operand call_method @code{Symbol} @ @ object @result{} result +Call method @var{Symbol} in the object @var{object}. Push the result of +the method call to the stack. +@end deffn + +@deffn Operand jmp @code{Int32} @ @ --- @result{} --- +Adjust program counter with relative offset @var{Int32}, e.g. jump to +relative position @var{pc} + @var{Int32}. +@end deffn + +@deffn Operand jsr @ @ function @result{} result +Jump to subroutine @var{function} and push the result of the subroutine +call to the stack. The operand will @strong{not} process the +with-chain. +@end deffn + +@deffn Operand return @ @ result @result{} result +Return from a subroutine with value @var{result}. +@end deffn + +@deffn Operand typeof @ @ any @result{} string +Push the type name of object @var{any} to the stack. +@end deffn + +@deffn Operand new @ @ object @result{} result object +Create an instance of object @var{object} and call its constructor +function. Push the result from the constructor and the new instance to +the stack. The return value of the constructor is discarded. +@end deffn + +@deffn Operand delete_property @code{Symbol} @ @ object @result{} undefined +Delete property @var{Symbol} from object @var{object}. Push value +@code{undefined} to the stack. +@end deffn + +@deffn Operand delete_array @ @ object index @result{} undefined +Delete the @var{index}:th property of object @var{object}. Push value +@code{undefined} to the stack. +@end deffn + +@deffn Operand locals @code{Int16} @ @ --- @result{} undefined @dots{} undefined +Allocate @var{Int16} local variables from the stack frame. The operand +@code{locals} must be called in the beginning of the function code. The +operand will push @var{Int16} @samp{undefined} values to the stack. The +values will be the place-holders for the local variables. +@end deffn + +@deffn Operand min_args @code{Int8} @ @ integer @result{} --- +If the number of the arguments for the function @var{integer} is smaller +than @code{Int8}, expand the stack frame so that the function gets +@code{Int8} arguments. The created arguments will have value +@code{undefined}. +@end deffn + +@deffn Operand load_nth_arg @ @ integer @result{} argument +Push the @var{integer}'th argument of function to the top of the stack. +The index @var{integer} must be an integer number. +@end deffn + +@deffn Operand with_push @ @ object @result{} --- +Push object @var{object} to the function's with-lookup chain. +@end deffn + +@deffn Operand with_pop @code{Int8} @ @ --- @result{} --- +Pop @var{Int8} objects from the function's with-lookup chain. +@end deffn + +@deffn Operand try_push @code{Int32} @ @ --- @result{} --- +Push a try-frame with a catch block offset @var{Int32} to the virtual +machine's try-chain. +@end deffn + +@deffn Operand try_pop @code{Int8} @ @ --- @result{} --- +Pop @var{Int8} frames from the virtual machine's try-chain. +@end deffn + +@deffn Operand throw @ @ any @result{} --- +Throw an exception with value @var{any}. +@end deffn + +@deffn Operand iffalse_b @code{Int32} @ @ boolean @result{} --- +If the topmost item in the stack is @code{false}, adjust the program +counter with relative offset @var{Int32}. The operand assumes that the +topmost item is a boolean value. +@end deffn + +@deffn Operand iftrue_b @code{Int32} @ @ boolean @result{} --- +If the topmost item in the stack is @code{true}, adjust the program +counter with relative offset @var{Int32}. The operand assumes that the +topmost item is a boolean value. +@end deffn + +@deffn Operand add_1_i @ @ integer @result{} integer +Add integer number one to the top most item in the stack. The operand +assumes that the topmost item is an integer number. +@end deffn + +@deffn Operand add_2_i @ @ integer @result{} integer +Add integer number two to the top most item in the stack. The operand +assumes that the topmost item is an integer number. +@end deffn + +@deffn Operand load_global_w @code{Symbol} @ @ --- @result{} value +Push the value of the global variable @var{Symbol} to the stack. The +operand will lookup the property @var{symbol} from the currently active +with-chain. +@end deffn + +@deffn Operand jsr_w @code{Symbol} @ @ function @result{} result +Jump to subroutine @var{function} and push the result of the subroutine +call to the stack. The operand will lookup the method @var{Symbol} from +the currently active with-chain. If the method is not found, the +argument @var{function} is used. +@end deffn + +@c ---------------------------------------------------------------------- +@node Stack Frame, , Byte-Code Operands, Virtual Machine +@section Stack Frame + +@example +JS_SP0 sp @result{} +JS_SP1 local_var_@var{n} +JS_SP2 @dots{} +JS_SP(@var{n}) local_var_1 +JS_LOCAL(0) local_var_0 + return_addr +JS_WITHPTR with_ptr +JS_ARGS_FIXP args_fix + fp @result{} old_fp +JS_ARG(0) this +JS_ARG(1) arg_count +JS_ARG(2) argument_1 + argument_2 + @dots{} +JS_ARG(@var{n}) argument_@var{n} + local_var_@var{n} + @dots{} + local_var_0 + args_fix + return_addr + with_ptr + old_fp + this + @dots{} +@end example + +@c ---------------------------------------------------------------------- +@node JavaScript Compiler, GNU Library General Public License, Virtual Machine, Top +@chapter JavaScript Compiler + +The JavaScript compiler is implemented in the JavaScript language. +Because the JavaScript language does not have namespaces, the compiler +has been coded to a fixed part of the global namespace. All global +symbols the compiler uses, start with the prefix `@code{JSC$}'. This +prefix is reserved for the interpreter and users must not define any +symbols or functions starting with that prefix. + +The compiler compiles JavaScript source code to byte-code and it returns +a fixed byte-code file as the result. This result file (or data block) +can be passed to the virtual machine for execution. + +The compiler has three stages. The first stage parse the input stream +and create a syntax tree for the input. The second stage transforms the +syntax tree to a list of assembler operations. The third stage converts +the symbolic assembler instructions to byte-code operands. + +Depending on the compilation options, the compiler performs different +optimizations during the compilation. The basic optimizations include +constant folding, peephole optimization, and optimization of jumps to +jump instructions. During the batch-compilation (when compiling a +JavaScript source file @file{.js} to byte-code file @file{.jsc}) the +compiler performns heavier optimizations to minimize the size of the +generated byte-code file, and to speed up some operations. + + +@menu +* Public Entry Points:: +@end menu + +@node Public Entry Points, , JavaScript Compiler, JavaScript Compiler +@section Public Entry Points + +@defun JSC$compile_file (@var{name}, @var{flags}, @var{asm_file}, @var{bc_file}) +Compile JavaScript source file @var{name} according to @var{flags}. If +argument @var{asm_file} is not @code{null}, symbolic assembler output is +saved to that file. If argument @var{bc_file} is not @code{null}, the +byte-code output is saved to that file. + +The function returns a string that holds the byte-code output for the +source file. +@end defun + +@defun JSC$compile_string (@var{string}, @var{flags}, @var{asm_file}, @var{bc_file}) +Compile JavaScript source code @var{string} according to @var{flags}. If +argument @var{asm_file} is not @code{null}, symbolic assembler output is +saved to that file. If argument @var{bc_file} is not @code{null}, the +byte-code output is saved to that file. + +The function returns a string that holds the byte-code output for the +source code. +@end defun + +In both functions, the argument @var{flags} specify the verbosity, +warning, and optimization levels of the compilation. The following +values can be given to flags: + +@table @code +@item JSC$FLAG_VERBOSE +turns on diagnostic messages + +@item JSC$FLAG_ANNOTATE_ASSEMBLER +add original JavaScript source lines to the generated assembler listing + +@item JSC$FLAG_GENERATE_DEBUG_INFO +generate debugging information to the byte-code file + +@item JSC$FLAG_GENERATE_EXECUTABLE_BC_FILES +add execute permissions to the generated byte-code files + +@item JSC$FLAG_OPTIMIZE_PEEPHOLE +perform peephole optimization + +@item JSC$FLAG_OPTIMIZE_JUMPS +perform optimization for jumps to jump instructions + +@item JSC$FLAG_OPTIMIZE_BC_SIZE +optimize the size of the genated byte-code file + +@item JSC$FLAG_OPTIMIZE_HEAVY +perform optimizations which require liveness analyzing of the +variables + +@item JSC$FLAG_OPTIMIZE_MASK +mask to turn on all optimizations + +@item JSC$FLAG_WARN_UNUSED_ARGUMENT +warn if an argument of a function is unused in the function body + +@item JSC$FLAG_WARN_UNUSED_VARIABLE +warn in a variable is defined but it is not used in the function body + +@item JSC$FLAG_WARN_SHADOW +warn if a variable declaration shadows a parameter of a function + +@item JSC$FLAG_WARN_WITH_CLOBBER +warn if a symbol with-lookup is clobbered because the symbol is defined +to be a local variable or a function argument + +@item JSC$FLAG_WARN_MISSING_SEMICOLON +warn if a semicolon is missing from the input. The missing semicolons +are inserted during the parsing by the automatic semicolon inserting. +However, since the missing semicolons show bad programming style, this +option will warn about them. + +@item JSC$FLAG_WARN_STRICT_ECMA +warn about things that are supported by this implementation, but are not +allowed by the ECMAScript standard + +@item JSC$FLAG_WARN_DEPRECATED +warn if deprecated features has been used in the source code + +@item JSC$FLAG_WARN_MASK +mask to turn on all warnings +@end table + +The compiler entry points can be called from JavaScript and C programs. +For example, they are used extensively to implement the JavaScript API, +described in the @file{js.h} file. The following example shows how a +C-string, containing JavaScript code, can be compiled and executed. +Similar function can be found from the JavaScript API implementing the +@code{js_eval()} function. + +@example +int +eval_code (JSInterpPtr interp, char *code); +@{ + JSNode argv[5]; + int i = 0; + int result; + ByteCode *bc; + + /* Compile the code. */ + + /* Argument count. */ + argv[i].type = JS_INTEGER; + argv[i].u.vinteger = 4; + i++; + + /* Source for the compiler. */ + js_make_static_string (interp->vm, &argv[i], code, strlen (code)); + i++; + + /* Flags. */ + argv[i].type = JS_INTEGER; + argv[i].u.vinteger = JSC_FLAG_VERBOSE; + argv[i].u.vinteger |= JSC_FLAG_OPTIMIZE_MASK; + argv[i].u.vinteger |= JSC_FLAG_WARN_MASK; + i++; + + /* Assembler file. */ + argv[i].type = JS_NULL; + i++; + + /* Byte-code file. */ + argv[i].type = JS_NULL; + i++; + + /* Call the compiler entry point. */ + result = js_vm_apply (interp->vm, "JSC$compile_string", i, argv); + if (result == 0) + return 0; + + bc = js_bc_read_data (interp->vm->exec_result.u.vstring->data, + interp->vm->exec_result.u.vstring->len); + + /* And finally, execute it. */ + result = js_vm_execute (interp->vm, bc); + + /* Free the byte-code. */ + js_bc_free (bc); + + return result; +@} +@end example + +The following example shows how the compiler entry point can be called +from JavaScript code. The example code compiles a JavaScript source +code file @file{input.js} into byte-code and stores the result to file +@file{ouput.jsc}. + +@example +try + @{ + JSC$compile_file ("input.js", + JSC$FLAG_OPTIMIZE_MASK | JSC$FLAG_WARN_MASK, + null, "output.jsc"); + @} +catch (e) + @{ + System.stdout.writeln ("compilation failed: " + e); + @} +@end example + +@c ---------------------------------------------------------------------- +@node GNU Library General Public License, Index, JavaScript Compiler, Top +@ifinfo +@appendix GNU Library General Public License +@end ifinfo + +@set lgpl-appendix 1 +@include lgpl.texinfo + +@c ---------------------------------------------------------------------- +@page +@node Index, , GNU Library General Public License, Top +@unnumbered Index + +@printindex cp + +@contents +@bye diff --git a/reactos/lib/kjs/docs/lgpl.texinfo b/reactos/lib/kjs/docs/lgpl.texinfo new file mode 100644 index 00000000000..5a57ff9620a --- /dev/null +++ b/reactos/lib/kjs/docs/lgpl.texinfo @@ -0,0 +1,548 @@ +@c This LGPL is meant to be included from other files. +@c To format a standalone LGPL, use liblic.texi. + +@ifset lgpl-appendix +@appendix GNU LIBRARY GENERAL PUBLIC LICENSE +@end ifset + +@ifclear lgpl-appendix +@unnumbered GNU LIBRARY GENERAL PUBLIC LICENSE +@end ifclear +@center Version 2, June 1991 + +@display +Copyright @copyright{} 1991 Free Software Foundation, Inc. +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] +@end display + +@unnumberedsec Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software---to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +``work based on the library'' and a ``work that uses the library''. The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + +@iftex +@unnumberedsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +@end iftex +@ifinfo +@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +@end ifinfo + +@enumerate 0 +@item +This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called ``this License''). Each licensee is +addressed as ``you''. + + A ``library'' means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The ``Library'', below, refers to any such software library or work +which has been distributed under these terms. A ``work based on the +Library'' means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term ``modification''.) + + ``Source code'' for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + +@item +You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + +@item +You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + +@enumerate a +@item +The modified work must itself be a software library. + +@item +You must cause the files modified to carry prominent notices +stating that you changed the files and the date of any change. + +@item +You must cause the whole of the work to be licensed at no +charge to all third parties under the terms of this License. + +@item +If a facility in the modified Library refers to a function or a +table of data to be supplied by an application program that uses +the facility, other than as an argument passed when the facility +is invoked, then you must make a good faith effort to ensure that, +in the event an application does not supply such function or +table, the facility still operates, and performs whatever part of +its purpose remains meaningful. + +(For example, a function in a library to compute square roots has +a purpose that is entirely well-defined independent of the +application. Therefore, Subsection 2d requires that any +application-supplied function or table used by this function must +be optional: if the application does not supply it, the square +root function must still compute square roots.) +@end enumerate + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + +@item +You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + +@item +You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + +@item +A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a ``work that uses the Library''. Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a ``work that uses the Library'' with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a ``work that uses the +library''. The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a ``work that uses the Library'' uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + +@item +As an exception to the Sections above, you may also compile or +link a ``work that uses the Library'' with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + +@enumerate a +@item +Accompany the work with the complete corresponding +machine-readable source code for the Library including whatever +changes were used in the work (which must be distributed under +Sections 1 and 2 above); and, if the work is an executable linked +with the Library, with the complete machine-readable ``work that +uses the Library'', as object code and/or source code, so that the +user can modify the Library and then relink to produce a modified +executable containing the modified Library. (It is understood +that the user who changes the contents of definitions files in the +Library will not necessarily be able to recompile the application +to use the modified definitions.) + +@item +Accompany the work with a written offer, valid for at +least three years, to give the same user the materials +specified in Subsection 6a, above, for a charge no more +than the cost of performing this distribution. + +@item +If distribution of the work is made by offering access to copy +from a designated place, offer equivalent access to copy the above +specified materials from the same place. + +@item +Verify that the user has already received a copy of these +materials or that you have already sent this user a copy. +@end enumerate + + For an executable, the required form of the ``work that uses the +Library'' must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + +@item +You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + +@enumerate a +@item +Accompany the combined library with a copy of the same work +based on the Library, uncombined with any other library +facilities. This must be distributed under the terms of the +Sections above. + +@item +Give prominent notice with the combined library of the fact +that part of it is a work based on the Library, and explaining +where to find the accompanying uncombined form of the same work. +@end enumerate + +@item +You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + +@item +You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + +@item +Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + +@item +If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + +@item +If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + +@item +The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +``any later version'', you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + +@item +If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + +@iftex +@heading NO WARRANTY +@end iftex +@ifinfo +@center NO WARRANTY +@end ifinfo + +@item +BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY ``AS IS'' WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +@item +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. +@end enumerate + +@iftex +@heading END OF TERMS AND CONDITIONS +@end iftex +@ifinfo +@center END OF TERMS AND CONDITIONS +@end ifinfo + +@page +@unnumberedsec How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +``copyright'' line and a pointer to where the full notice is found. + +@smallexample +@var{one line to give the library's name and an idea of what it does.} +Copyright (C) @var{year} @var{name of author} + +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, Cambridge, +MA 02139, USA. +@end smallexample + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a ``copyright disclaimer'' for the library, if +necessary. Here is a sample; alter the names: + +@example +Yoyodyne, Inc., hereby disclaims all copyright interest in +the library `Frob' (a library for tweaking knobs) written +by James Random Hacker. + +@var{signature of Ty Coon}, 1 April 1990 +Ty Coon, President of Vice +@end example + +That's all there is to it! diff --git a/reactos/lib/kjs/docs/mdate-sh b/reactos/lib/kjs/docs/mdate-sh new file mode 100755 index 00000000000..37171f21fbd --- /dev/null +++ b/reactos/lib/kjs/docs/mdate-sh @@ -0,0 +1,92 @@ +#!/bin/sh +# Get modification time of a file or directory and pretty-print it. +# Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. +# written by Ulrich Drepper , June 1995 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Prevent date giving response in another language. +LANG=C +export LANG +LC_ALL=C +export LC_ALL +LC_TIME=C +export LC_TIME + +# Get the extended ls output of the file or directory. +# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below. +if ls -L /dev/null 1>/dev/null 2>&1; then + set - x`ls -L -l -d $1` +else + set - x`ls -l -d $1` +fi +# The month is at least the fourth argument +# (3 shifts here, the next inside the loop). +shift +shift +shift + +# Find the month. Next argument is day, followed by the year or time. +month= +until test $month +do + shift + case $1 in + Jan) month=January; nummonth=1;; + Feb) month=February; nummonth=2;; + Mar) month=March; nummonth=3;; + Apr) month=April; nummonth=4;; + May) month=May; nummonth=5;; + Jun) month=June; nummonth=6;; + Jul) month=July; nummonth=7;; + Aug) month=August; nummonth=8;; + Sep) month=September; nummonth=9;; + Oct) month=October; nummonth=10;; + Nov) month=November; nummonth=11;; + Dec) month=December; nummonth=12;; + esac +done + +day=$2 + +# Here we have to deal with the problem that the ls output gives either +# the time of day or the year. +case $3 in + *:*) set `date`; eval year=\$$# + case $2 in + Jan) nummonthtod=1;; + Feb) nummonthtod=2;; + Mar) nummonthtod=3;; + Apr) nummonthtod=4;; + May) nummonthtod=5;; + Jun) nummonthtod=6;; + Jul) nummonthtod=7;; + Aug) nummonthtod=8;; + Sep) nummonthtod=9;; + Oct) nummonthtod=10;; + Nov) nummonthtod=11;; + Dec) nummonthtod=12;; + esac + # For the first six month of the year the time notation can also + # be used for files modified in the last year. + if (expr $nummonth \> $nummonthtod) > /dev/null; + then + year=`expr $year - 1` + fi;; + *) year=$3;; +esac + +# The result. +echo $day $month $year diff --git a/reactos/lib/kjs/docs/stamp-vti b/reactos/lib/kjs/docs/stamp-vti new file mode 100644 index 00000000000..bdd8ee12d38 --- /dev/null +++ b/reactos/lib/kjs/docs/stamp-vti @@ -0,0 +1,3 @@ +@set UPDATED 25 November 1998 +@set EDITION 0.2.5 +@set VERSION 0.2.5 diff --git a/reactos/lib/kjs/docs/texinfo.tex b/reactos/lib/kjs/docs/texinfo.tex new file mode 100644 index 00000000000..ef926af1295 --- /dev/null +++ b/reactos/lib/kjs/docs/texinfo.tex @@ -0,0 +1,4935 @@ +%% TeX macros to handle Texinfo files. +%% $Id: texinfo.tex,v 1.1 2004/01/10 20:38:17 arty Exp $ + +% Copyright (C) 1985, 86, 88, 90, 91, 92, 93, +% 94, 95, 96, 97 Free Software Foundation, Inc. + +%This texinfo.tex file is free software; you can redistribute it and/or +%modify it under the terms of the GNU General Public License as +%published by the Free Software Foundation; either version 2, or (at +%your option) any later version. + +%This texinfo.tex file 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 +%General Public License for more details. + +%You should have received a copy of the GNU General Public License +%along with this texinfo.tex file; see the file COPYING. If not, write +%to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +%Boston, MA 02111-1307, USA. + + +%In other words, you are welcome to use, share and improve this program. +%You are forbidden to forbid anyone else to use, share and improve +%what you give them. Help stamp out software-hoarding! + + +% Send bug reports to bug-texinfo@prep.ai.mit.edu. +% Please include a *precise* test case in each bug report. + + +% Make it possible to create a .fmt file just by loading this file: +% if the underlying format is not loaded, start by loading it now. +% Added by gildea November 1993. +\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi + +% This automatically updates the version number based on RCS. +\def\deftexinfoversion$#1: #2 ${\def\texinfoversion{#2}} +\deftexinfoversion$Revision: 1.1 $ +\message{Loading texinfo package [Version \texinfoversion]:} + +% If in a .fmt file, print the version number +% and turn on active characters that we couldn't do earlier because +% they might have appeared in the input file name. +\everyjob{\message{[Texinfo version \texinfoversion]}\message{} + \catcode`+=\active \catcode`\_=\active} + +% Save some parts of plain tex whose names we will redefine. + +\let\ptexb=\b +\let\ptexbullet=\bullet +\let\ptexc=\c +\let\ptexcomma=\, +\let\ptexdot=\. +\let\ptexdots=\dots +\let\ptexend=\end +\let\ptexequiv = \equiv +\let\ptexi=\i +\let\ptexlbrace=\{ +\let\ptexrbrace=\} +\let\ptexstar=\* +\let\ptext=\t + +% Be sure we're in horizontal mode when doing a tie, since we make space +% equivalent to this in @example-like environments. Otherwise, a space +% at the beginning of a line will start with \penalty -- and +% since \penalty is valid in vertical mode, we'd end up putting the +% penalty on the vertical list instead of in the new paragraph. +{\catcode`@ = 11 + % Avoid using \@M directly, because that causes trouble + % if the definition is written into an index file. + \global\let\tiepenalty = \@M + \gdef\tie{\leavevmode\penalty\tiepenalty\ } +} + + +\message{Basics,} +\chardef\other=12 + +% If this character appears in an error message or help string, it +% starts a new line in the output. +\newlinechar = `^^J + +% Set up fixed words for English. +\ifx\putwordChapter\undefined{\gdef\putwordChapter{Chapter}}\fi% +\def\putwordInfo{Info}% +\ifx\putwordSee\undefined{\gdef\putwordSee{See}}\fi% +\ifx\putwordsee\undefined{\gdef\putwordsee{see}}\fi% +\ifx\putwordfile\undefined{\gdef\putwordfile{file}}\fi% +\ifx\putwordpage\undefined{\gdef\putwordpage{page}}\fi% +\ifx\putwordsection\undefined{\gdef\putwordsection{section}}\fi% +\ifx\putwordSection\undefined{\gdef\putwordSection{Section}}\fi% +\ifx\putwordTableofContents\undefined{\gdef\putwordTableofContents{Table of Contents}}\fi% +\ifx\putwordShortContents\undefined{\gdef\putwordShortContents{Short Contents}}\fi% +\ifx\putwordAppendix\undefined{\gdef\putwordAppendix{Appendix}}\fi% + +% Ignore a token. +% +\def\gobble#1{} + +\hyphenation{ap-pen-dix} +\hyphenation{mini-buf-fer mini-buf-fers} +\hyphenation{eshell} +\hyphenation{white-space} + +% Margin to add to right of even pages, to left of odd pages. +\newdimen \bindingoffset +\newdimen \normaloffset +\newdimen\pagewidth \newdimen\pageheight + +% Sometimes it is convenient to have everything in the transcript file +% and nothing on the terminal. We don't just call \tracingall here, +% since that produces some useless output on the terminal. +% +\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% +\def\loggingall{\tracingcommands2 \tracingstats2 + \tracingpages1 \tracingoutput1 \tracinglostchars1 + \tracingmacros2 \tracingparagraphs1 \tracingrestores1 + \showboxbreadth\maxdimen\showboxdepth\maxdimen +}% + +% For @cropmarks command. +% Do @cropmarks to get crop marks. +% +\newif\ifcropmarks +\let\cropmarks = \cropmarkstrue +% +% Dimensions to add cropmarks at corners. +% Added by P. A. MacKay, 12 Nov. 1986 +% +\newdimen\cornerlong \newdimen\cornerthick +\newdimen\topandbottommargin +\newdimen\outerhsize \newdimen\outervsize +\cornerlong=1pc\cornerthick=.3pt % These set size of cropmarks +\outerhsize=7in +%\outervsize=9.5in +% Alternative @smallbook page size is 9.25in +\outervsize=9.25in +\topandbottommargin=.75in + +% Main output routine. +\chardef\PAGE = 255 +\output = {\onepageout{\pagecontents\PAGE}} + +\newbox\headlinebox +\newbox\footlinebox + +% \onepageout takes a vbox as an argument. Note that \pagecontents +% does insertions, but you have to call it yourself. +\def\onepageout#1{% + \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi + % + \ifodd\pageno \advance\hoffset by \bindingoffset + \else \advance\hoffset by -\bindingoffset\fi + % + % Do this outside of the \shipout so @code etc. will be expanded in + % the headline as they should be, not taken literally (outputting ''code). + \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% + \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% + % + {% + % Have to do this stuff outside the \shipout because we want it to + % take effect in \write's, yet the group defined by the \vbox ends + % before the \shipout runs. + % + \escapechar = `\\ % use backslash in output files. + \indexdummies % don't expand commands in the output. + \normalturnoffactive % \ in index entries must not stay \, e.g., if + % the page break happens to be in the middle of an example. + \shipout\vbox{% + \ifcropmarks \vbox to \outervsize\bgroup + \hsize = \outerhsize + \line{\ewtop\hfil\ewtop}% + \nointerlineskip + \line{% + \vbox{\moveleft\cornerthick\nstop}% + \hfill + \vbox{\moveright\cornerthick\nstop}% + }% + \vskip\topandbottommargin + \line\bgroup + \hfil % center the page within the outer (page) hsize. + \ifodd\pageno\hskip\bindingoffset\fi + \vbox\bgroup + \fi + % + \unvbox\headlinebox + \pagebody{#1}% + \ifdim\ht\footlinebox > 0pt + % Only leave this space if the footline is nonempty. + % (We lessened \vsize for it in \oddfootingxxx.) + % The \baselineskip=24pt in plain's \makefootline has no effect. + \vskip 2\baselineskip + \unvbox\footlinebox + \fi + % + \ifcropmarks + \egroup % end of \vbox\bgroup + \hfil\egroup % end of (centering) \line\bgroup + \vskip\topandbottommargin plus1fill minus1fill + \boxmaxdepth = \cornerthick + \line{% + \vbox{\moveleft\cornerthick\nsbot}% + \hfill + \vbox{\moveright\cornerthick\nsbot}% + }% + \nointerlineskip + \line{\ewbot\hfil\ewbot}% + \egroup % \vbox from first cropmarks clause + \fi + }% end of \shipout\vbox + }% end of group with \turnoffactive + \advancepageno + \ifnum\outputpenalty>-20000 \else\dosupereject\fi +} + +\newinsert\margin \dimen\margin=\maxdimen + +\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} +{\catcode`\@ =11 +\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi +% marginal hacks, juha@viisa.uucp (Juha Takala) +\ifvoid\margin\else % marginal info is present + \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi +\dimen@=\dp#1 \unvbox#1 +\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi +\ifr@ggedbottom \kern-\dimen@ \vfil \fi} +} + +% Here are the rules for the cropmarks. Note that they are +% offset so that the space between them is truly \outerhsize or \outervsize +% (P. A. MacKay, 12 November, 1986) +% +\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} +\def\nstop{\vbox + {\hrule height\cornerthick depth\cornerlong width\cornerthick}} +\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} +\def\nsbot{\vbox + {\hrule height\cornerlong depth\cornerthick width\cornerthick}} + +% Parse an argument, then pass it to #1. The argument is the rest of +% the input line (except we remove a trailing comment). #1 should be a +% macro which expects an ordinary undelimited TeX argument. +% +\def\parsearg#1{% + \let\next = #1% + \begingroup + \obeylines + \futurelet\temp\parseargx +} + +% If the next token is an obeyed space (from an @example environment or +% the like), remove it and recurse. Otherwise, we're done. +\def\parseargx{% + % \obeyedspace is defined far below, after the definition of \sepspaces. + \ifx\obeyedspace\temp + \expandafter\parseargdiscardspace + \else + \expandafter\parseargline + \fi +} + +% Remove a single space (as the delimiter token to the macro call). +{\obeyspaces % + \gdef\parseargdiscardspace {\futurelet\temp\parseargx}} + +{\obeylines % + \gdef\parseargline#1^^M{% + \endgroup % End of the group started in \parsearg. + % + % First remove any @c comment, then any @comment. + % Result of each macro is put in \toks0. + \argremovec #1\c\relax % + \expandafter\argremovecomment \the\toks0 \comment\relax % + % + % Call the caller's macro, saved as \next in \parsearg. + \expandafter\next\expandafter{\the\toks0}% + }% +} + +% Since all \c{,omment} does is throw away the argument, we can let TeX +% do that for us. The \relax here is matched by the \relax in the call +% in \parseargline; it could be more or less anything, its purpose is +% just to delimit the argument to the \c. +\def\argremovec#1\c#2\relax{\toks0 = {#1}} +\def\argremovecomment#1\comment#2\relax{\toks0 = {#1}} + +% \argremovec{,omment} might leave us with trailing spaces, though; e.g., +% @end itemize @c foo +% will have two active spaces as part of the argument with the +% `itemize'. Here we remove all active spaces from #1, and assign the +% result to \toks0. +% +% This loses if there are any *other* active characters besides spaces +% in the argument -- _ ^ +, for example -- since they get expanded. +% Fortunately, Texinfo does not define any such commands. (If it ever +% does, the catcode of the characters in questionwill have to be changed +% here.) But this means we cannot call \removeactivespaces as part of +% \argremovec{,omment}, since @c uses \parsearg, and thus the argument +% that \parsearg gets might well have any character at all in it. +% +\def\removeactivespaces#1{% + \begingroup + \ignoreactivespaces + \edef\temp{#1}% + \global\toks0 = \expandafter{\temp}% + \endgroup +} + +% Change the active space to expand to nothing. +% +\begingroup + \obeyspaces + \gdef\ignoreactivespaces{\obeyspaces\let =\empty} +\endgroup + + +\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} + +%% These are used to keep @begin/@end levels from running away +%% Call \inENV within environments (after a \begingroup) +\newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi} +\def\ENVcheck{% +\ifENV\errmessage{Still within an environment. Type Return to continue.} +\endgroup\fi} % This is not perfect, but it should reduce lossage + +% @begin foo is the same as @foo, for now. +\newhelp\EMsimple{Type to continue.} + +\outer\def\begin{\parsearg\beginxxx} + +\def\beginxxx #1{% +\expandafter\ifx\csname #1\endcsname\relax +{\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else +\csname #1\endcsname\fi} + +% @end foo executes the definition of \Efoo. +% +\def\end{\parsearg\endxxx} +\def\endxxx #1{% + \removeactivespaces{#1}% + \edef\endthing{\the\toks0}% + % + \expandafter\ifx\csname E\endthing\endcsname\relax + \expandafter\ifx\csname \endthing\endcsname\relax + % There's no \foo, i.e., no ``environment'' foo. + \errhelp = \EMsimple + \errmessage{Undefined command `@end \endthing'}% + \else + \unmatchedenderror\endthing + \fi + \else + % Everything's ok; the right environment has been started. + \csname E\endthing\endcsname + \fi +} + +% There is an environment #1, but it hasn't been started. Give an error. +% +\def\unmatchedenderror#1{% + \errhelp = \EMsimple + \errmessage{This `@end #1' doesn't have a matching `@#1'}% +} + +% Define the control sequence \E#1 to give an unmatched @end error. +% +\def\defineunmatchedend#1{% + \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}% +} + + +% Single-spacing is done by various environments (specifically, in +% \nonfillstart and \quotations). +\newskip\singlespaceskip \singlespaceskip = 12.5pt +\def\singlespace{% + % Why was this kern here? It messes up equalizing space above and below + % environments. --karl, 6may93 + %{\advance \baselineskip by -\singlespaceskip + %\kern \baselineskip}% + \setleading \singlespaceskip +} + +%% Simple single-character @ commands + +% @@ prints an @ +% Kludge this until the fonts are right (grr). +\def\@{{\tt \char '100}} + +% This is turned off because it was never documented +% and you can use @w{...} around a quote to suppress ligatures. +%% Define @` and @' to be the same as ` and ' +%% but suppressing ligatures. +%\def\`{{`}} +%\def\'{{'}} + +% Used to generate quoted braces. +\def\mylbrace {{\tt \char '173}} +\def\myrbrace {{\tt \char '175}} +\let\{=\mylbrace +\let\}=\myrbrace +\begingroup + % Definitions to produce actual \{ & \} command in an index. + \catcode`\{ = 12 \catcode`\} = 12 + \catcode`\[ = 1 \catcode`\] = 2 + \catcode`\@ = 0 \catcode`\\ = 12 + @gdef@lbracecmd[\{]% + @gdef@rbracecmd[\}]% +@endgroup + +% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent +% Others are defined by plain TeX: @` @' @" @^ @~ @= @v @H. +\let\, = \c +\let\dotaccent = \. +\def\ringaccent#1{{\accent23 #1}} +\let\tieaccent = \t +\let\ubaraccent = \b +\let\udotaccent = \d + +% Other special characters: @questiondown @exclamdown +% Plain TeX defines: @AA @AE @O @OE @L (and lowercase versions) @ss. +\def\questiondown{?`} +\def\exclamdown{!`} + +% Dotless i and dotless j, used for accents. +\def\imacro{i} +\def\jmacro{j} +\def\dotless#1{% + \def\temp{#1}% + \ifx\temp\imacro \ptexi + \else\ifx\temp\jmacro \j + \else \errmessage{@dotless can be used only with i or j}% + \fi\fi +} + +% @: forces normal size whitespace following. +\def\:{\spacefactor=1000 } + +% @* forces a line break. +\def\*{\hfil\break\hbox{}\ignorespaces} + +% @. is an end-of-sentence period. +\def\.{.\spacefactor=3000 } + +% @enddots{} is an end-of-sentence ellipsis. +\gdef\enddots{$\mathinner{\ldotp\ldotp\ldotp\ldotp}$\spacefactor=3000} + +% @! is an end-of-sentence bang. +\gdef\!{!\spacefactor=3000 } + +% @? is an end-of-sentence query. +\gdef\?{?\spacefactor=3000 } + +% @w prevents a word break. Without the \leavevmode, @w at the +% beginning of a paragraph, when TeX is still in vertical mode, would +% produce a whole line of output instead of starting the paragraph. +\def\w#1{\leavevmode\hbox{#1}} + +% @group ... @end group forces ... to be all on one page, by enclosing +% it in a TeX vbox. We use \vtop instead of \vbox to construct the box +% to keep its height that of a normal line. According to the rules for +% \topskip (p.114 of the TeXbook), the glue inserted is +% max (\topskip - \ht (first item), 0). If that height is large, +% therefore, no glue is inserted, and the space between the headline and +% the text is small, which looks bad. +% +\def\group{\begingroup + \ifnum\catcode13=\active \else + \errhelp = \groupinvalidhelp + \errmessage{@group invalid in context where filling is enabled}% + \fi + % + % The \vtop we start below produces a box with normal height and large + % depth; thus, TeX puts \baselineskip glue before it, and (when the + % next line of text is done) \lineskip glue after it. (See p.82 of + % the TeXbook.) Thus, space below is not quite equal to space + % above. But it's pretty close. + \def\Egroup{% + \egroup % End the \vtop. + \endgroup % End the \group. + }% + % + \vtop\bgroup + % We have to put a strut on the last line in case the @group is in + % the midst of an example, rather than completely enclosing it. + % Otherwise, the interline space between the last line of the group + % and the first line afterwards is too small. But we can't put the + % strut in \Egroup, since there it would be on a line by itself. + % Hence this just inserts a strut at the beginning of each line. + \everypar = {\strut}% + % + % Since we have a strut on every line, we don't need any of TeX's + % normal interline spacing. + \offinterlineskip + % + % OK, but now we have to do something about blank + % lines in the input in @example-like environments, which normally + % just turn into \lisppar, which will insert no space now that we've + % turned off the interline space. Simplest is to make them be an + % empty paragraph. + \ifx\par\lisppar + \edef\par{\leavevmode \par}% + % + % Reset ^^M's definition to new definition of \par. + \obeylines + \fi + % + % Do @comment since we are called inside an environment such as + % @example, where each end-of-line in the input causes an + % end-of-line in the output. We don't want the end-of-line after + % the `@group' to put extra space in the output. Since @group + % should appear on a line by itself (according to the Texinfo + % manual), we don't worry about eating any user text. + \comment +} +% +% TeX puts in an \escapechar (i.e., `@') at the beginning of the help +% message, so this ends up printing `@group can only ...'. +% +\newhelp\groupinvalidhelp{% +group can only be used in environments such as @example,^^J% +where each line of input produces a line of output.} + +% @need space-in-mils +% forces a page break if there is not space-in-mils remaining. + +\newdimen\mil \mil=0.001in + +\def\need{\parsearg\needx} + +% Old definition--didn't work. +%\def\needx #1{\par % +%% This method tries to make TeX break the page naturally +%% if the depth of the box does not fit. +%{\baselineskip=0pt% +%\vtop to #1\mil{\vfil}\kern -#1\mil\penalty 10000 +%\prevdepth=-1000pt +%}} + +\def\needx#1{% + % Go into vertical mode, so we don't make a big box in the middle of a + % paragraph. + \par + % + % Don't add any leading before our big empty box, but allow a page + % break, since the best break might be right here. + \allowbreak + \nointerlineskip + \vtop to #1\mil{\vfil}% + % + % TeX does not even consider page breaks if a penalty added to the + % main vertical list is 10000 or more. But in order to see if the + % empty box we just added fits on the page, we must make it consider + % page breaks. On the other hand, we don't want to actually break the + % page after the empty box. So we use a penalty of 9999. + % + % There is an extremely small chance that TeX will actually break the + % page at this \penalty, if there are no other feasible breakpoints in + % sight. (If the user is using lots of big @group commands, which + % almost-but-not-quite fill up a page, TeX will have a hard time doing + % good page breaking, for example.) However, I could not construct an + % example where a page broke at this \penalty; if it happens in a real + % document, then we can reconsider our strategy. + \penalty9999 + % + % Back up by the size of the box, whether we did a page break or not. + \kern -#1\mil + % + % Do not allow a page break right after this kern. + \nobreak +} + +% @br forces paragraph break + +\let\br = \par + +% @dots{} output some dots + +\def\dots{$\ldots$} + +% @page forces the start of a new page + +\def\page{\par\vfill\supereject} + +% @exdent text.... +% outputs text on separate line in roman font, starting at standard page margin + +% This records the amount of indent in the innermost environment. +% That's how much \exdent should take out. +\newskip\exdentamount + +% This defn is used inside fill environments such as @defun. +\def\exdent{\parsearg\exdentyyy} +\def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}} + +% This defn is used inside nofill environments such as @example. +\def\nofillexdent{\parsearg\nofillexdentyyy} +\def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount +\leftline{\hskip\leftskip{\rm#1}}}} + +% @inmargin{TEXT} puts TEXT in the margin next to the current paragraph. + +\def\inmargin#1{% +\strut\vadjust{\nobreak\kern-\strutdepth + \vtop to \strutdepth{\baselineskip\strutdepth\vss + \llap{\rightskip=\inmarginspacing \vbox{\noindent #1}}\null}}} +\newskip\inmarginspacing \inmarginspacing=1cm +\def\strutdepth{\dp\strutbox} + +%\hbox{{\rm#1}}\hfil\break}} + +% @include file insert text of that file as input. +% Allow normal characters that we make active in the argument (a file name). +\def\include{\begingroup + \catcode`\\=12 + \catcode`~=12 + \catcode`^=12 + \catcode`_=12 + \catcode`|=12 + \catcode`<=12 + \catcode`>=12 + \catcode`+=12 + \parsearg\includezzz} +% Restore active chars for included file. +\def\includezzz#1{\endgroup\begingroup + % Read the included file in a group so nested @include's work. + \def\thisfile{#1}% + \input\thisfile +\endgroup} + +\def\thisfile{} + +% @center line outputs that line, centered + +\def\center{\parsearg\centerzzz} +\def\centerzzz #1{{\advance\hsize by -\leftskip +\advance\hsize by -\rightskip +\centerline{#1}}} + +% @sp n outputs n lines of vertical space + +\def\sp{\parsearg\spxxx} +\def\spxxx #1{\vskip #1\baselineskip} + +% @comment ...line which is ignored... +% @c is the same as @comment +% @ignore ... @end ignore is another way to write a comment + +\def\comment{\catcode 64=\other \catcode 123=\other \catcode 125=\other% +\parsearg \commentxxx} + +\def\commentxxx #1{\catcode 64=0 \catcode 123=1 \catcode 125=2 } + +\let\c=\comment + +% @paragraphindent is defined for the Info formatting commands only. +\let\paragraphindent=\comment + +% Prevent errors for section commands. +% Used in @ignore and in failing conditionals. +\def\ignoresections{% +\let\chapter=\relax +\let\unnumbered=\relax +\let\top=\relax +\let\unnumberedsec=\relax +\let\unnumberedsection=\relax +\let\unnumberedsubsec=\relax +\let\unnumberedsubsection=\relax +\let\unnumberedsubsubsec=\relax +\let\unnumberedsubsubsection=\relax +\let\section=\relax +\let\subsec=\relax +\let\subsubsec=\relax +\let\subsection=\relax +\let\subsubsection=\relax +\let\appendix=\relax +\let\appendixsec=\relax +\let\appendixsection=\relax +\let\appendixsubsec=\relax +\let\appendixsubsection=\relax +\let\appendixsubsubsec=\relax +\let\appendixsubsubsection=\relax +\let\contents=\relax +\let\smallbook=\relax +\let\titlepage=\relax +} + +% Used in nested conditionals, where we have to parse the Texinfo source +% and so want to turn off most commands, in case they are used +% incorrectly. +% +\def\ignoremorecommands{% + \let\defcodeindex = \relax + \let\defcv = \relax + \let\deffn = \relax + \let\deffnx = \relax + \let\defindex = \relax + \let\defivar = \relax + \let\defmac = \relax + \let\defmethod = \relax + \let\defop = \relax + \let\defopt = \relax + \let\defspec = \relax + \let\deftp = \relax + \let\deftypefn = \relax + \let\deftypefun = \relax + \let\deftypevar = \relax + \let\deftypevr = \relax + \let\defun = \relax + \let\defvar = \relax + \let\defvr = \relax + \let\ref = \relax + \let\xref = \relax + \let\printindex = \relax + \let\pxref = \relax + \let\settitle = \relax + \let\setchapternewpage = \relax + \let\setchapterstyle = \relax + \let\everyheading = \relax + \let\evenheading = \relax + \let\oddheading = \relax + \let\everyfooting = \relax + \let\evenfooting = \relax + \let\oddfooting = \relax + \let\headings = \relax + \let\include = \relax + \let\lowersections = \relax + \let\down = \relax + \let\raisesections = \relax + \let\up = \relax + \let\set = \relax + \let\clear = \relax + \let\item = \relax +} + +% Ignore @ignore ... @end ignore. +% +\def\ignore{\doignore{ignore}} + +% Ignore @ifinfo, @ifhtml, @ifnottex, @html, @menu, and @direntry text. +% +\def\ifinfo{\doignore{ifinfo}} +\def\ifhtml{\doignore{ifhtml}} +\def\ifnottex{\doignore{ifnottex}} +\def\html{\doignore{html}} +\def\menu{\doignore{menu}} +\def\direntry{\doignore{direntry}} + +% Also ignore @macro ... @end macro. The user must run texi2dvi, +% which runs makeinfo to do macro expansion. Ignore @unmacro, too. +\def\macro{\doignore{macro}} +\let\unmacro = \comment + + +% @dircategory CATEGORY -- specify a category of the dir file +% which this file should belong to. Ignore this in TeX. +\let\dircategory = \comment + +% Ignore text until a line `@end #1'. +% +\def\doignore#1{\begingroup + % Don't complain about control sequences we have declared \outer. + \ignoresections + % + % Define a command to swallow text until we reach `@end #1'. + \long\def\doignoretext##1\end #1{\enddoignore}% + % + % Make sure that spaces turn into tokens that match what \doignoretext wants. + \catcode32 = 10 + % + % Ignore braces, too, so mismatched braces don't cause trouble. + \catcode`\{ = 9 + \catcode`\} = 9 + % + % And now expand that command. + \doignoretext +} + +% What we do to finish off ignored text. +% +\def\enddoignore{\endgroup\ignorespaces}% + +\newif\ifwarnedobs\warnedobsfalse +\def\obstexwarn{% + \ifwarnedobs\relax\else + % We need to warn folks that they may have trouble with TeX 3.0. + % This uses \immediate\write16 rather than \message to get newlines. + \immediate\write16{} + \immediate\write16{***WARNING*** for users of Unix TeX 3.0!} + \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).} + \immediate\write16{If you are running another version of TeX, relax.} + \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.} + \immediate\write16{ Then upgrade your TeX installation if you can.} + \immediate\write16{ (See ftp://ftp.gnu.ai.mit.edu/pub/gnu/TeX.README.)} + \immediate\write16{If you are stuck with version 3.0, run the} + \immediate\write16{ script ``tex3patch'' from the Texinfo distribution} + \immediate\write16{ to use a workaround.} + \immediate\write16{} + \global\warnedobstrue + \fi +} + +% **In TeX 3.0, setting text in \nullfont hangs tex. For a +% workaround (which requires the file ``dummy.tfm'' to be installed), +% uncomment the following line: +%%%%%\font\nullfont=dummy\let\obstexwarn=\relax + +% Ignore text, except that we keep track of conditional commands for +% purposes of nesting, up to an `@end #1' command. +% +\def\nestedignore#1{% + \obstexwarn + % We must actually expand the ignored text to look for the @end + % command, so that nested ignore constructs work. Thus, we put the + % text into a \vbox and then do nothing with the result. To minimize + % the change of memory overflow, we follow the approach outlined on + % page 401 of the TeXbook: make the current font be a dummy font. + % + \setbox0 = \vbox\bgroup + % Don't complain about control sequences we have declared \outer. + \ignoresections + % + % Define `@end #1' to end the box, which will in turn undefine the + % @end command again. + \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}% + % + % We are going to be parsing Texinfo commands. Most cause no + % trouble when they are used incorrectly, but some commands do + % complicated argument parsing or otherwise get confused, so we + % undefine them. + % + % We can't do anything about stray @-signs, unfortunately; + % they'll produce `undefined control sequence' errors. + \ignoremorecommands + % + % Set the current font to be \nullfont, a TeX primitive, and define + % all the font commands to also use \nullfont. We don't use + % dummy.tfm, as suggested in the TeXbook, because not all sites + % might have that installed. Therefore, math mode will still + % produce output, but that should be an extremely small amount of + % stuff compared to the main input. + % + \nullfont + \let\tenrm = \nullfont \let\tenit = \nullfont \let\tensl = \nullfont + \let\tenbf = \nullfont \let\tentt = \nullfont \let\smallcaps = \nullfont + \let\tensf = \nullfont + % Similarly for index fonts (mostly for their use in + % smallexample) + \let\indrm = \nullfont \let\indit = \nullfont \let\indsl = \nullfont + \let\indbf = \nullfont \let\indtt = \nullfont \let\indsc = \nullfont + \let\indsf = \nullfont + % + % Don't complain when characters are missing from the fonts. + \tracinglostchars = 0 + % + % Don't bother to do space factor calculations. + \frenchspacing + % + % Don't report underfull hboxes. + \hbadness = 10000 + % + % Do minimal line-breaking. + \pretolerance = 10000 + % + % Do not execute instructions in @tex + \def\tex{\doignore{tex}}% +} + +% @set VAR sets the variable VAR to an empty value. +% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. +% +% Since we want to separate VAR from REST-OF-LINE (which might be +% empty), we can't just use \parsearg; we have to insert a space of our +% own to delimit the rest of the line, and then take it out again if we +% didn't need it. Make sure the catcode of space is correct to avoid +% losing inside @example, for instance. +% +\def\set{\begingroup\catcode` =10 + \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR. + \parsearg\setxxx} +\def\setxxx#1{\setyyy#1 \endsetyyy} +\def\setyyy#1 #2\endsetyyy{% + \def\temp{#2}% + \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty + \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted. + \fi + \endgroup +} +% Can't use \xdef to pre-expand #2 and save some time, since \temp or +% \next or other control sequences that we've defined might get us into +% an infinite loop. Consider `@set foo @cite{bar}'. +\def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}} + +% @clear VAR clears (i.e., unsets) the variable VAR. +% +\def\clear{\parsearg\clearxxx} +\def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax} + +% @value{foo} gets the text saved in variable foo. +% +\def\value{\begingroup + \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR. + \valuexxx} +\def\valuexxx#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + {\{No value for ``#1''\}}% + \else + \csname SET#1\endcsname + \fi +\endgroup} + +% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined +% with @set. +% +\def\ifset{\parsearg\ifsetxxx} +\def\ifsetxxx #1{% + \expandafter\ifx\csname SET#1\endcsname\relax + \expandafter\ifsetfail + \else + \expandafter\ifsetsucceed + \fi +} +\def\ifsetsucceed{\conditionalsucceed{ifset}} +\def\ifsetfail{\nestedignore{ifset}} +\defineunmatchedend{ifset} + +% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been +% defined with @set, or has been undefined with @clear. +% +\def\ifclear{\parsearg\ifclearxxx} +\def\ifclearxxx #1{% + \expandafter\ifx\csname SET#1\endcsname\relax + \expandafter\ifclearsucceed + \else + \expandafter\ifclearfail + \fi +} +\def\ifclearsucceed{\conditionalsucceed{ifclear}} +\def\ifclearfail{\nestedignore{ifclear}} +\defineunmatchedend{ifclear} + +% @iftex, @ifnothtml, @ifnotinfo always succeed; we read the text +% following, through the first @end iftex (etc.). Make `@end iftex' +% (etc.) valid only after an @iftex. +% +\def\iftex{\conditionalsucceed{iftex}} +\def\ifnothtml{\conditionalsucceed{ifnothtml}} +\def\ifnotinfo{\conditionalsucceed{ifnotinfo}} +\defineunmatchedend{iftex} +\defineunmatchedend{ifnothtml} +\defineunmatchedend{ifnotinfo} + +% We can't just want to start a group at @iftex (for example) and end it +% at @end iftex, since then @set commands inside the conditional have no +% effect (they'd get reverted at the end of the group). So we must +% define \Eiftex to redefine itself to be its previous value. (We can't +% just define it to fail again with an ``unmatched end'' error, since +% the @ifset might be nested.) +% +\def\conditionalsucceed#1{% + \edef\temp{% + % Remember the current value of \E#1. + \let\nece{prevE#1} = \nece{E#1}% + % + % At the `@end #1', redefine \E#1 to be its previous value. + \def\nece{E#1}{\let\nece{E#1} = \nece{prevE#1}}% + }% + \temp +} + +% We need to expand lots of \csname's, but we don't want to expand the +% control sequences after we've constructed them. +% +\def\nece#1{\expandafter\noexpand\csname#1\endcsname} + +% @asis just yields its argument. Used with @table, for example. +% +\def\asis#1{#1} + +% @math means output in math mode. +% We don't use $'s directly in the definition of \math because control +% sequences like \math are expanded when the toc file is written. Then, +% we read the toc file back, the $'s will be normal characters (as they +% should be, according to the definition of Texinfo). So we must use a +% control sequence to switch into and out of math mode. +% +% This isn't quite enough for @math to work properly in indices, but it +% seems unlikely it will ever be needed there. +% +\let\implicitmath = $ +\def\math#1{\implicitmath #1\implicitmath} + +% @bullet and @minus need the same treatment as @math, just above. +\def\bullet{\implicitmath\ptexbullet\implicitmath} +\def\minus{\implicitmath-\implicitmath} + +\def\node{\ENVcheck\parsearg\nodezzz} +\def\nodezzz#1{\nodexxx [#1,]} +\def\nodexxx[#1,#2]{\gdef\lastnode{#1}} +\let\nwnode=\node +\let\lastnode=\relax + +\def\donoderef{\ifx\lastnode\relax\else +\expandafter\expandafter\expandafter\setref{\lastnode}\fi +\global\let\lastnode=\relax} + +\def\unnumbnoderef{\ifx\lastnode\relax\else +\expandafter\expandafter\expandafter\unnumbsetref{\lastnode}\fi +\global\let\lastnode=\relax} + +\def\appendixnoderef{\ifx\lastnode\relax\else +\expandafter\expandafter\expandafter\appendixsetref{\lastnode}\fi +\global\let\lastnode=\relax} + +% @refill is a no-op. +\let\refill=\relax + +% @setfilename is done at the beginning of every texinfo file. +% So open here the files we need to have open while reading the input. +% This makes it possible to make a .fmt file for texinfo. +\def\setfilename{% + \readauxfile + \opencontents + \openindices + \fixbackslash % Turn off hack to swallow `\input texinfo'. + \global\let\setfilename=\comment % Ignore extra @setfilename cmds. + % + % If texinfo.cnf is present on the system, read it. + % Useful for site-wide @afourpaper, etc. + % Just to be on the safe side, close the input stream before the \input. + \openin 1 texinfo.cnf + \ifeof1 \let\temp=\relax \else \def\temp{\input texinfo.cnf }\fi + \closein1 + \temp + % + \comment % Ignore the actual filename. +} + +% @bye. +\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} + +% \def\macro#1{\begingroup\ignoresections\catcode`\#=6\def\macrotemp{#1}\parsearg\macroxxx} +% \def\macroxxx#1#2 \end macro{% +% \expandafter\gdef\macrotemp#1{#2}% +% \endgroup} + +%\def\linemacro#1{\begingroup\ignoresections\catcode`\#=6\def\macrotemp{#1}\parsearg\linemacroxxx} +%\def\linemacroxxx#1#2 \end linemacro{% +%\let\parsearg=\relax +%\edef\macrotempx{\csname M\butfirst\expandafter\string\macrotemp\endcsname}% +%\expandafter\xdef\macrotemp{\parsearg\macrotempx}% +%\expandafter\gdef\macrotempx#1{#2}% +%\endgroup} + +%\def\butfirst#1{} + + +\message{fonts,} + +% Font-change commands. + +% Texinfo supports the sans serif font style, which plain TeX does not. +% So we set up a \sf analogous to plain's \rm, etc. +\newfam\sffam +\def\sf{\fam=\sffam \tensf} +\let\li = \sf % Sometimes we call it \li, not \sf. + +% We don't need math for this one. +\def\ttsl{\tenttsl} + +% Use Computer Modern fonts at \magstephalf (11pt). +\newcount\mainmagstep +\mainmagstep=\magstephalf + +% Set the font macro #1 to the font named #2, adding on the +% specified font prefix (normally `cm'). +% #3 is the font's design size, #4 is a scale factor +\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4} + +% Use cm as the default font prefix. +% To specify the font prefix, you must define \fontprefix +% before you read in texinfo.tex. +\ifx\fontprefix\undefined +\def\fontprefix{cm} +\fi +% Support font families that don't use the same naming scheme as CM. +\def\rmshape{r} +\def\rmbshape{bx} %where the normal face is bold +\def\bfshape{b} +\def\bxshape{bx} +\def\ttshape{tt} +\def\ttbshape{tt} +\def\ttslshape{sltt} +\def\itshape{ti} +\def\itbshape{bxti} +\def\slshape{sl} +\def\slbshape{bxsl} +\def\sfshape{ss} +\def\sfbshape{ss} +\def\scshape{csc} +\def\scbshape{csc} + +\ifx\bigger\relax +\let\mainmagstep=\magstep1 +\setfont\textrm\rmshape{12}{1000} +\setfont\texttt\ttshape{12}{1000} +\else +\setfont\textrm\rmshape{10}{\mainmagstep} +\setfont\texttt\ttshape{10}{\mainmagstep} +\fi +% Instead of cmb10, you many want to use cmbx10. +% cmbx10 is a prettier font on its own, but cmb10 +% looks better when embedded in a line with cmr10. +\setfont\textbf\bfshape{10}{\mainmagstep} +\setfont\textit\itshape{10}{\mainmagstep} +\setfont\textsl\slshape{10}{\mainmagstep} +\setfont\textsf\sfshape{10}{\mainmagstep} +\setfont\textsc\scshape{10}{\mainmagstep} +\setfont\textttsl\ttslshape{10}{\mainmagstep} +\font\texti=cmmi10 scaled \mainmagstep +\font\textsy=cmsy10 scaled \mainmagstep + +% A few fonts for @defun, etc. +\setfont\defbf\bxshape{10}{\magstep1} %was 1314 +\setfont\deftt\ttshape{10}{\magstep1} +\def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf} + +% Fonts for indices and small examples (9pt). +% We actually use the slanted font rather than the italic, +% because texinfo normally uses the slanted fonts for that. +% Do not make many font distinctions in general in the index, since they +% aren't very useful. +\setfont\ninett\ttshape{9}{1000} +\setfont\indrm\rmshape{9}{1000} +\setfont\indit\slshape{9}{1000} +\let\indsl=\indit +\let\indtt=\ninett +\let\indttsl=\ninett +\let\indsf=\indrm +\let\indbf=\indrm +\setfont\indsc\scshape{10}{900} +\font\indi=cmmi9 +\font\indsy=cmsy9 + +% Fonts for title page: +\setfont\titlerm\rmbshape{12}{\magstep3} +\setfont\titleit\itbshape{10}{\magstep4} +\setfont\titlesl\slbshape{10}{\magstep4} +\setfont\titlett\ttbshape{12}{\magstep3} +\setfont\titlettsl\ttslshape{10}{\magstep4} +\setfont\titlesf\sfbshape{17}{\magstep1} +\let\titlebf=\titlerm +\setfont\titlesc\scbshape{10}{\magstep4} +\font\titlei=cmmi12 scaled \magstep3 +\font\titlesy=cmsy10 scaled \magstep4 +\def\authorrm{\secrm} + +% Chapter (and unnumbered) fonts (17.28pt). +\setfont\chaprm\rmbshape{12}{\magstep2} +\setfont\chapit\itbshape{10}{\magstep3} +\setfont\chapsl\slbshape{10}{\magstep3} +\setfont\chaptt\ttbshape{12}{\magstep2} +\setfont\chapttsl\ttslshape{10}{\magstep3} +\setfont\chapsf\sfbshape{17}{1000} +\let\chapbf=\chaprm +\setfont\chapsc\scbshape{10}{\magstep3} +\font\chapi=cmmi12 scaled \magstep2 +\font\chapsy=cmsy10 scaled \magstep3 + +% Section fonts (14.4pt). +\setfont\secrm\rmbshape{12}{\magstep1} +\setfont\secit\itbshape{10}{\magstep2} +\setfont\secsl\slbshape{10}{\magstep2} +\setfont\sectt\ttbshape{12}{\magstep1} +\setfont\secttsl\ttslshape{10}{\magstep2} +\setfont\secsf\sfbshape{12}{\magstep1} +\let\secbf\secrm +\setfont\secsc\scbshape{10}{\magstep2} +\font\seci=cmmi12 scaled \magstep1 +\font\secsy=cmsy10 scaled \magstep2 + +% \setfont\ssecrm\bxshape{10}{\magstep1} % This size an font looked bad. +% \setfont\ssecit\itshape{10}{\magstep1} % The letters were too crowded. +% \setfont\ssecsl\slshape{10}{\magstep1} +% \setfont\ssectt\ttshape{10}{\magstep1} +% \setfont\ssecsf\sfshape{10}{\magstep1} + +%\setfont\ssecrm\bfshape{10}{1315} % Note the use of cmb rather than cmbx. +%\setfont\ssecit\itshape{10}{1315} % Also, the size is a little larger than +%\setfont\ssecsl\slshape{10}{1315} % being scaled magstep1. +%\setfont\ssectt\ttshape{10}{1315} +%\setfont\ssecsf\sfshape{10}{1315} + +%\let\ssecbf=\ssecrm + +% Subsection fonts (13.15pt). +\setfont\ssecrm\rmbshape{12}{\magstephalf} +\setfont\ssecit\itbshape{10}{1315} +\setfont\ssecsl\slbshape{10}{1315} +\setfont\ssectt\ttbshape{12}{\magstephalf} +\setfont\ssecttsl\ttslshape{10}{1315} +\setfont\ssecsf\sfbshape{12}{\magstephalf} +\let\ssecbf\ssecrm +\setfont\ssecsc\scbshape{10}{\magstep1} +\font\sseci=cmmi12 scaled \magstephalf +\font\ssecsy=cmsy10 scaled 1315 +% The smallcaps and symbol fonts should actually be scaled \magstep1.5, +% but that is not a standard magnification. + +% In order for the font changes to affect most math symbols and letters, +% we have to define the \textfont of the standard families. Since +% texinfo doesn't allow for producing subscripts and superscripts, we +% don't bother to reset \scriptfont and \scriptscriptfont (which would +% also require loading a lot more fonts). +% +\def\resetmathfonts{% + \textfont0 = \tenrm \textfont1 = \teni \textfont2 = \tensy + \textfont\itfam = \tenit \textfont\slfam = \tensl \textfont\bffam = \tenbf + \textfont\ttfam = \tentt \textfont\sffam = \tensf +} + + +% The font-changing commands redefine the meanings of \tenSTYLE, instead +% of just \STYLE. We do this so that font changes will continue to work +% in math mode, where it is the current \fam that is relevant in most +% cases, not the current font. Plain TeX does \def\bf{\fam=\bffam +% \tenbf}, for example. By redefining \tenbf, we obviate the need to +% redefine \bf itself. +\def\textfonts{% + \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl + \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc + \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl + \resetmathfonts} +\def\titlefonts{% + \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl + \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc + \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy + \let\tenttsl=\titlettsl + \resetmathfonts \setleading{25pt}} +\def\titlefont#1{{\titlefonts #1}} +\def\chapfonts{% + \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl + \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc + \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl + \resetmathfonts \setleading{19pt}} +\def\secfonts{% + \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl + \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc + \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl + \resetmathfonts \setleading{16pt}} +\def\subsecfonts{% + \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl + \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc + \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl + \resetmathfonts \setleading{15pt}} +\let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf? +\def\indexfonts{% + \let\tenrm=\indrm \let\tenit=\indit \let\tensl=\indsl + \let\tenbf=\indbf \let\tentt=\indtt \let\smallcaps=\indsc + \let\tensf=\indsf \let\teni=\indi \let\tensy=\indsy \let\tenttsl=\indttsl + \resetmathfonts \setleading{12pt}} + +% Set up the default fonts, so we can use them for creating boxes. +% +\textfonts + +% Count depth in font-changes, for error checks +\newcount\fontdepth \fontdepth=0 + +% Fonts for short table of contents. +\setfont\shortcontrm\rmshape{12}{1000} +\setfont\shortcontbf\bxshape{12}{1000} +\setfont\shortcontsl\slshape{12}{1000} + +%% Add scribe-like font environments, plus @l for inline lisp (usually sans +%% serif) and @ii for TeX italic + +% \smartitalic{ARG} outputs arg in italics, followed by an italic correction +% unless the following character is such as not to need one. +\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else\/\fi\fi\fi} +\def\smartitalic#1{{\sl #1}\futurelet\next\smartitalicx} + +\let\i=\smartitalic +\let\var=\smartitalic +\let\dfn=\smartitalic +\let\emph=\smartitalic +\let\cite=\smartitalic + +\def\b#1{{\bf #1}} +\let\strong=\b + +% We can't just use \exhyphenpenalty, because that only has effect at +% the end of a paragraph. Restore normal hyphenation at the end of the +% group within which \nohyphenation is presumably called. +% +\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} +\def\restorehyphenation{\hyphenchar\font = `- } + +\def\t#1{% + {\tt \rawbackslash \frenchspacing #1}% + \null +} +\let\ttfont=\t +\def\samp #1{`\tclose{#1}'\null} +\setfont\smallrm\rmshape{8}{1000} +\font\smallsy=cmsy9 +\def\key#1{{\smallrm\textfont2=\smallsy \leavevmode\hbox{% + \raise0.4pt\hbox{$\langle$}\kern-.08em\vtop{% + \vbox{\hrule\kern-0.4pt + \hbox{\raise0.4pt\hbox{\vphantom{$\langle$}}#1}}% + \kern-0.4pt\hrule}% + \kern-.06em\raise0.4pt\hbox{$\rangle$}}}} +% The old definition, with no lozenge: +%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null} +\def\ctrl #1{{\tt \rawbackslash \hat}#1} + +\let\file=\samp + +% @code is a modification of @t, +% which makes spaces the same size as normal in the surrounding text. +\def\tclose#1{% + {% + % Change normal interword space to be same as for the current font. + \spaceskip = \fontdimen2\font + % + % Switch to typewriter. + \tt + % + % But `\ ' produces the large typewriter interword space. + \def\ {{\spaceskip = 0pt{} }}% + % + % Turn off hyphenation. + \nohyphenation + % + \rawbackslash + \frenchspacing + #1% + }% + \null +} + +% We *must* turn on hyphenation at `-' and `_' in \code. +% Otherwise, it is too hard to avoid overfull hboxes +% in the Emacs manual, the Library manual, etc. + +% Unfortunately, TeX uses one parameter (\hyphenchar) to control +% both hyphenation at - and hyphenation within words. +% We must therefore turn them both off (\tclose does that) +% and arrange explicitly to hyphenate at a dash. +% -- rms. +{ +\catcode`\-=\active +\catcode`\_=\active +\catcode`\|=\active +\global\def\code{\begingroup \catcode`\-=\active \let-\codedash \catcode`\_=\active \let_\codeunder \codex} +% The following is used by \doprintindex to insure that long function names +% wrap around. It is necessary for - and _ to be active before the index is +% read from the file, as \entry parses the arguments long before \code is +% ever called. -- mycroft +% _ is always active; and it shouldn't be \let = to an _ that is a +% subscript character anyway. Then, @cindex @samp{_} (for example) +% fails. --karl +\global\def\indexbreaks{% + \catcode`\-=\active \let-\realdash +} +} + +\def\realdash{-} +\def\codedash{-\discretionary{}{}{}} +\def\codeunder{\ifusingtt{\normalunderscore\discretionary{}{}{}}{\_}} +\def\codex #1{\tclose{#1}\endgroup} + +%\let\exp=\tclose %Was temporary + +% @kbd is like @code, except that if the argument is just one @key command, +% then @kbd has no effect. + +% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), +% `example' (@kbd uses ttsl only inside of @example and friends), +% or `code' (@kbd uses normal tty font always). +\def\kbdinputstyle{\parsearg\kbdinputstylexxx} +\def\kbdinputstylexxx#1{% + \def\arg{#1}% + \ifx\arg\worddistinct + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% + \else\ifx\arg\wordexample + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% + \else\ifx\arg\wordcode + \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% + \fi\fi\fi +} +\def\worddistinct{distinct} +\def\wordexample{example} +\def\wordcode{code} + +% Default is kbdinputdistinct. (Too much of a hassle to call the macro, +% the catcodes are wrong for parsearg to work.) +\gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl} + +\def\xkey{\key} +\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% +\ifx\one\xkey\ifx\threex\three \key{#2}% +\else{\tclose{\kbdfont\look}}\fi +\else{\tclose{\kbdfont\look}}\fi} + +% @url. Quotes do not seem necessary, so use \code. +\let\url=\code + +% @uref (abbreviation for `urlref') takes an optional second argument +% specifying the text to display. First (mandatory) arg is the url. +% Perhaps eventually put in a hypertex \special here. +% +\def\uref#1{\urefxxx #1,,\finish} +\def\urefxxx#1,#2,#3\finish{% + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \unhbox0\ (\code{#1})% + \else + \code{#1}% + \fi +} + +% rms does not like the angle brackets --karl, 17may97. +% So now @email is just like @uref. +%\def\email#1{$\langle${\tt #1}$\rangle$} +\let\email=\uref + +% Check if we are currently using a typewriter font. Since all the +% Computer Modern typewriter fonts have zero interword stretch (and +% shrink), and it is reasonable to expect all typewriter fonts to have +% this property, we can check that font parameter. +% +\def\ifmonospace{\ifdim\fontdimen3\font=0pt } + +% Typeset a dimension, e.g., `in' or `pt'. The only reason for the +% argument is to make the input look right: @dmn{pt} instead of +% @dmn{}pt. +% +\def\dmn#1{\thinspace #1} + +\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par} + +% @l was never documented to mean ``switch to the Lisp font'', +% and it is not used as such in any manual I can find. We need it for +% Polish suppressed-l. --karl, 22sep96. +%\def\l#1{{\li #1}\null} + +\def\r#1{{\rm #1}} % roman font +% Use of \lowercase was suggested. +\def\sc#1{{\smallcaps#1}} % smallcaps font +\def\ii#1{{\it #1}} % italic font + +% @pounds{} is a sterling sign. +\def\pounds{{\it\$}} + + +\message{page headings,} + +\newskip\titlepagetopglue \titlepagetopglue = 1.5in +\newskip\titlepagebottomglue \titlepagebottomglue = 2pc + +% First the title page. Must do @settitle before @titlepage. +\newif\ifseenauthor +\newif\iffinishedtitlepage + +\def\shorttitlepage{\parsearg\shorttitlepagezzz} +\def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% + \endgroup\page\hbox{}\page} + +\def\titlepage{\begingroup \parindent=0pt \textfonts + \let\subtitlerm=\tenrm +% I deinstalled the following change because \cmr12 is undefined. +% This change was not in the ChangeLog anyway. --rms. +% \let\subtitlerm=\cmr12 + \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}% + % + \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines}% + % + % Leave some space at the very top of the page. + \vglue\titlepagetopglue + % + % Now you can print the title using @title. + \def\title{\parsearg\titlezzz}% + \def\titlezzz##1{\leftline{\titlefonts\rm ##1} + % print a rule at the page bottom also. + \finishedtitlepagefalse + \vskip4pt \hrule height 4pt width \hsize \vskip4pt}% + % No rule at page bottom unless we print one at the top with @title. + \finishedtitlepagetrue + % + % Now you can put text using @subtitle. + \def\subtitle{\parsearg\subtitlezzz}% + \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}% + % + % @author should come last, but may come many times. + \def\author{\parsearg\authorzzz}% + \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi + {\authorfont \leftline{##1}}}% + % + % Most title ``pages'' are actually two pages long, with space + % at the top of the second. We don't want the ragged left on the second. + \let\oldpage = \page + \def\page{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + \oldpage + \let\page = \oldpage + \hbox{}}% +% \def\page{\oldpage \hbox{}} +} + +\def\Etitlepage{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + % It is important to do the page break before ending the group, + % because the headline and footline are only empty inside the group. + % If we use the new definition of \page, we always get a blank page + % after the title page, which we certainly don't want. + \oldpage + \endgroup + \HEADINGSon +} + +\def\finishtitlepage{% + \vskip4pt \hrule height 2pt width \hsize + \vskip\titlepagebottomglue + \finishedtitlepagetrue +} + +%%% Set up page headings and footings. + +\let\thispage=\folio + +\newtoks \evenheadline % Token sequence for heading line of even pages +\newtoks \oddheadline % Token sequence for heading line of odd pages +\newtoks \evenfootline % Token sequence for footing line of even pages +\newtoks \oddfootline % Token sequence for footing line of odd pages + +% Now make Tex use those variables +\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline + \else \the\evenheadline \fi}} +\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline + \else \the\evenfootline \fi}\HEADINGShook} +\let\HEADINGShook=\relax + +% Commands to set those variables. +% For example, this is what @headings on does +% @evenheading @thistitle|@thispage|@thischapter +% @oddheading @thischapter|@thispage|@thistitle +% @evenfooting @thisfile|| +% @oddfooting ||@thisfile + +\def\evenheading{\parsearg\evenheadingxxx} +\def\oddheading{\parsearg\oddheadingxxx} +\def\everyheading{\parsearg\everyheadingxxx} + +\def\evenfooting{\parsearg\evenfootingxxx} +\def\oddfooting{\parsearg\oddfootingxxx} +\def\everyfooting{\parsearg\everyfootingxxx} + +{\catcode`\@=0 % + +\gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish} +\gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{% +\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish} +\gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{% +\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\gdef\everyheadingxxx#1{\oddheadingxxx{#1}\evenheadingxxx{#1}}% + +\gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish} +\gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{% +\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish} +\gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{% + \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% + % + % Leave some space for the footline. Hopefully ok to assume + % @evenfooting will not be used by itself. + \global\advance\pageheight by -\baselineskip + \global\advance\vsize by -\baselineskip +} + +\gdef\everyfootingxxx#1{\oddfootingxxx{#1}\evenfootingxxx{#1}} +% +}% unbind the catcode of @. + +% @headings double turns headings on for double-sided printing. +% @headings single turns headings on for single-sided printing. +% @headings off turns them off. +% @headings on same as @headings double, retained for compatibility. +% @headings after turns on double-sided headings after this page. +% @headings doubleafter turns on double-sided headings after this page. +% @headings singleafter turns on single-sided headings after this page. +% By default, they are off at the start of a document, +% and turned `on' after @end titlepage. + +\def\headings #1 {\csname HEADINGS#1\endcsname} + +\def\HEADINGSoff{ +\global\evenheadline={\hfil} \global\evenfootline={\hfil} +\global\oddheadline={\hfil} \global\oddfootline={\hfil}} +\HEADINGSoff +% When we turn headings on, set the page number to 1. +% For double-sided printing, put current file name in lower left corner, +% chapter name on inside top of right hand pages, document +% title on inside top of left hand pages, and page numbers on outside top +% edge of all pages. +\def\HEADINGSdouble{ +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} +\let\contentsalignmacro = \chappager + +% For single-sided printing, chapter title goes across top left of page, +% page number on top right. +\def\HEADINGSsingle{ +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} +\def\HEADINGSon{\HEADINGSdouble} + +\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} +\let\HEADINGSdoubleafter=\HEADINGSafter +\def\HEADINGSdoublex{% +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} + +\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} +\def\HEADINGSsinglex{% +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} + +% Subroutines used in generating headings +% Produces Day Month Year style of output. +\def\today{\number\day\space +\ifcase\month\or +January\or February\or March\or April\or May\or June\or +July\or August\or September\or October\or November\or December\fi +\space\number\year} + +% Use this if you want the Month Day, Year style of output. +%\def\today{\ifcase\month\or +%January\or February\or March\or April\or May\or June\or +%July\or August\or September\or October\or November\or December\fi +%\space\number\day, \number\year} + +% @settitle line... specifies the title of the document, for headings +% It generates no output of its own + +\def\thistitle{No Title} +\def\settitle{\parsearg\settitlezzz} +\def\settitlezzz #1{\gdef\thistitle{#1}} + + +\message{tables,} + +% @tabs -- simple alignment + +% These don't work. For one thing, \+ is defined as outer. +% So these macros cannot even be defined. + +%\def\tabs{\parsearg\tabszzz} +%\def\tabszzz #1{\settabs\+#1\cr} +%\def\tabline{\parsearg\tablinezzz} +%\def\tablinezzz #1{\+#1\cr} +%\def\&{&} + +% Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x). + +% default indentation of table text +\newdimen\tableindent \tableindent=.8in +% default indentation of @itemize and @enumerate text +\newdimen\itemindent \itemindent=.3in +% margin between end of table item and start of table text. +\newdimen\itemmargin \itemmargin=.1in + +% used internally for \itemindent minus \itemmargin +\newdimen\itemmax + +% Note @table, @vtable, and @vtable define @item, @itemx, etc., with +% these defs. +% They also define \itemindex +% to index the item name in whatever manner is desired (perhaps none). + +\newif\ifitemxneedsnegativevskip + +\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} + +\def\internalBitem{\smallbreak \parsearg\itemzzz} +\def\internalBitemx{\itemxpar \parsearg\itemzzz} + +\def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz} +\def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz} + +\def\internalBkitem{\smallbreak \parsearg\kitemzzz} +\def\internalBkitemx{\itemxpar \parsearg\kitemzzz} + +\def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}% + \itemzzz {#1}} + +\def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}% + \itemzzz {#1}} + +\def\itemzzz #1{\begingroup % + \advance\hsize by -\rightskip + \advance\hsize by -\tableindent + \setbox0=\hbox{\itemfont{#1}}% + \itemindex{#1}% + \nobreak % This prevents a break before @itemx. + % + % Be sure we are not still in the middle of a paragraph. + %{\parskip = 0in + %\par + %}% + % + % If the item text does not fit in the space we have, put it on a line + % by itself, and do not allow a page break either before or after that + % line. We do not start a paragraph here because then if the next + % command is, e.g., @kindex, the whatsit would get put into the + % horizontal list on a line by itself, resulting in extra blank space. + \ifdim \wd0>\itemmax + % + % Make this a paragraph so we get the \parskip glue and wrapping, + % but leave it ragged-right. + \begingroup + \advance\leftskip by-\tableindent + \advance\hsize by\tableindent + \advance\rightskip by0pt plus1fil + \leavevmode\unhbox0\par + \endgroup + % + % We're going to be starting a paragraph, but we don't want the + % \parskip glue -- logically it's part of the @item we just started. + \nobreak \vskip-\parskip + % + % Stop a page break at the \parskip glue coming up. Unfortunately + % we can't prevent a possible page break at the following + % \baselineskip glue. + \nobreak + \endgroup + \itemxneedsnegativevskipfalse + \else + % The item text fits into the space. Start a paragraph, so that the + % following text (if any) will end up on the same line. Since that + % text will be indented by \tableindent, we make the item text be in + % a zero-width box. + \noindent + \rlap{\hskip -\tableindent\box0}\ignorespaces% + \endgroup% + \itemxneedsnegativevskiptrue% + \fi +} + +\def\item{\errmessage{@item while not in a table}} +\def\itemx{\errmessage{@itemx while not in a table}} +\def\kitem{\errmessage{@kitem while not in a table}} +\def\kitemx{\errmessage{@kitemx while not in a table}} +\def\xitem{\errmessage{@xitem while not in a table}} +\def\xitemx{\errmessage{@xitemx while not in a table}} + +%% Contains a kludge to get @end[description] to work +\def\description{\tablez{\dontindex}{1}{}{}{}{}} + +\def\table{\begingroup\inENV\obeylines\obeyspaces\tablex} +{\obeylines\obeyspaces% +\gdef\tablex #1^^M{% +\tabley\dontindex#1 \endtabley}} + +\def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex} +{\obeylines\obeyspaces% +\gdef\ftablex #1^^M{% +\tabley\fnitemindex#1 \endtabley +\def\Eftable{\endgraf\afterenvbreak\endgroup}% +\let\Etable=\relax}} + +\def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex} +{\obeylines\obeyspaces% +\gdef\vtablex #1^^M{% +\tabley\vritemindex#1 \endtabley +\def\Evtable{\endgraf\afterenvbreak\endgroup}% +\let\Etable=\relax}} + +\def\dontindex #1{} +\def\fnitemindex #1{\doind {fn}{\code{#1}}}% +\def\vritemindex #1{\doind {vr}{\code{#1}}}% + +{\obeyspaces % +\gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup% +\tablez{#1}{#2}{#3}{#4}{#5}{#6}}} + +\def\tablez #1#2#3#4#5#6{% +\aboveenvbreak % +\begingroup % +\def\Edescription{\Etable}% Necessary kludge. +\let\itemindex=#1% +\ifnum 0#3>0 \advance \leftskip by #3\mil \fi % +\ifnum 0#4>0 \tableindent=#4\mil \fi % +\ifnum 0#5>0 \advance \rightskip by #5\mil \fi % +\def\itemfont{#2}% +\itemmax=\tableindent % +\advance \itemmax by -\itemmargin % +\advance \leftskip by \tableindent % +\exdentamount=\tableindent +\parindent = 0pt +\parskip = \smallskipamount +\ifdim \parskip=0pt \parskip=2pt \fi% +\def\Etable{\endgraf\afterenvbreak\endgroup}% +\let\item = \internalBitem % +\let\itemx = \internalBitemx % +\let\kitem = \internalBkitem % +\let\kitemx = \internalBkitemx % +\let\xitem = \internalBxitem % +\let\xitemx = \internalBxitemx % +} + +% This is the counter used by @enumerate, which is really @itemize + +\newcount \itemno + +\def\itemize{\parsearg\itemizezzz} + +\def\itemizezzz #1{% + \begingroup % ended by the @end itemsize + \itemizey {#1}{\Eitemize} +} + +\def\itemizey #1#2{% +\aboveenvbreak % +\itemmax=\itemindent % +\advance \itemmax by -\itemmargin % +\advance \leftskip by \itemindent % +\exdentamount=\itemindent +\parindent = 0pt % +\parskip = \smallskipamount % +\ifdim \parskip=0pt \parskip=2pt \fi% +\def#2{\endgraf\afterenvbreak\endgroup}% +\def\itemcontents{#1}% +\let\item=\itemizeitem} + +% Set sfcode to normal for the chars that usually have another value. +% These are `.?!:;,' +\def\frenchspacing{\sfcode46=1000 \sfcode63=1000 \sfcode33=1000 + \sfcode58=1000 \sfcode59=1000 \sfcode44=1000 } + +% \splitoff TOKENS\endmark defines \first to be the first token in +% TOKENS, and \rest to be the remainder. +% +\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% + +% Allow an optional argument of an uppercase letter, lowercase letter, +% or number, to specify the first label in the enumerated list. No +% argument is the same as `1'. +% +\def\enumerate{\parsearg\enumeratezzz} +\def\enumeratezzz #1{\enumeratey #1 \endenumeratey} +\def\enumeratey #1 #2\endenumeratey{% + \begingroup % ended by the @end enumerate + % + % If we were given no argument, pretend we were given `1'. + \def\thearg{#1}% + \ifx\thearg\empty \def\thearg{1}\fi + % + % Detect if the argument is a single token. If so, it might be a + % letter. Otherwise, the only valid thing it can be is a number. + % (We will always have one token, because of the test we just made. + % This is a good thing, since \splitoff doesn't work given nothing at + % all -- the first parameter is undelimited.) + \expandafter\splitoff\thearg\endmark + \ifx\rest\empty + % Only one token in the argument. It could still be anything. + % A ``lowercase letter'' is one whose \lccode is nonzero. + % An ``uppercase letter'' is one whose \lccode is both nonzero, and + % not equal to itself. + % Otherwise, we assume it's a number. + % + % We need the \relax at the end of the \ifnum lines to stop TeX from + % continuing to look for a . + % + \ifnum\lccode\expandafter`\thearg=0\relax + \numericenumerate % a number (we hope) + \else + % It's a letter. + \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax + \lowercaseenumerate % lowercase letter + \else + \uppercaseenumerate % uppercase letter + \fi + \fi + \else + % Multiple tokens in the argument. We hope it's a number. + \numericenumerate + \fi +} + +% An @enumerate whose labels are integers. The starting integer is +% given in \thearg. +% +\def\numericenumerate{% + \itemno = \thearg + \startenumeration{\the\itemno}% +} + +% The starting (lowercase) letter is in \thearg. +\def\lowercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more lowercase letters in @enumerate; get a bigger + alphabet}% + \fi + \char\lccode\itemno + }% +} + +% The starting (uppercase) letter is in \thearg. +\def\uppercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more uppercase letters in @enumerate; get a bigger + alphabet} + \fi + \char\uccode\itemno + }% +} + +% Call itemizey, adding a period to the first argument and supplying the +% common last two arguments. Also subtract one from the initial value in +% \itemno, since @item increments \itemno. +% +\def\startenumeration#1{% + \advance\itemno by -1 + \itemizey{#1.}\Eenumerate\flushcr +} + +% @alphaenumerate and @capsenumerate are abbreviations for giving an arg +% to @enumerate. +% +\def\alphaenumerate{\enumerate{a}} +\def\capsenumerate{\enumerate{A}} +\def\Ealphaenumerate{\Eenumerate} +\def\Ecapsenumerate{\Eenumerate} + +% Definition of @item while inside @itemize. + +\def\itemizeitem{% +\advance\itemno by 1 +{\let\par=\endgraf \smallbreak}% +\ifhmode \errmessage{In hmode at itemizeitem}\fi +{\parskip=0in \hskip 0pt +\hbox to 0pt{\hss \itemcontents\hskip \itemmargin}% +\vadjust{\penalty 1200}}% +\flushcr} + +% @multitable macros +% Amy Hendrickson, 8/18/94, 3/6/96 +% +% @multitable ... @end multitable will make as many columns as desired. +% Contents of each column will wrap at width given in preamble. Width +% can be specified either with sample text given in a template line, +% or in percent of \hsize, the current width of text on page. + +% Table can continue over pages but will only break between lines. + +% To make preamble: +% +% Either define widths of columns in terms of percent of \hsize: +% @multitable @columnfractions .25 .3 .45 +% @item ... +% +% Numbers following @columnfractions are the percent of the total +% current hsize to be used for each column. You may use as many +% columns as desired. + + +% Or use a template: +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item ... +% using the widest term desired in each column. +% +% For those who want to use more than one line's worth of words in +% the preamble, break the line within one argument and it +% will parse correctly, i.e., +% +% @multitable {Column 1 template} {Column 2 template} {Column 3 +% template} +% Not: +% @multitable {Column 1 template} {Column 2 template} +% {Column 3 template} + +% Each new table line starts with @item, each subsequent new column +% starts with @tab. Empty columns may be produced by supplying @tab's +% with nothing between them for as many times as empty columns are needed, +% ie, @tab@tab@tab will produce two empty columns. + +% @item, @tab, @multitable or @end multitable do not need to be on their +% own lines, but it will not hurt if they are. + +% Sample multitable: + +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item first col stuff @tab second col stuff @tab third col +% @item +% first col stuff +% @tab +% second col stuff +% @tab +% third col +% @item first col stuff @tab second col stuff +% @tab Many paragraphs of text may be used in any column. +% +% They will wrap at the width determined by the template. +% @item@tab@tab This will be in third column. +% @end multitable + +% Default dimensions may be reset by user. +% @multitableparskip is vertical space between paragraphs in table. +% @multitableparindent is paragraph indent in table. +% @multitablecolmargin is horizontal space to be left between columns. +% @multitablelinespace is space to leave between table items, baseline +% to baseline. +% 0pt means it depends on current normal line spacing. + +%%%% +% Dimensions + +\newskip\multitableparskip +\newskip\multitableparindent +\newdimen\multitablecolspace +\newskip\multitablelinespace +\multitableparskip=0pt +\multitableparindent=6pt +\multitablecolspace=12pt +\multitablelinespace=0pt + +%%%% +% Macros used to set up halign preamble: +\let\endsetuptable\relax +\def\xendsetuptable{\endsetuptable} +\let\columnfractions\relax +\def\xcolumnfractions{\columnfractions} +\newif\ifsetpercent + +%% 2/1/96, to allow fractions to be given with more than one digit. +\def\pickupwholefraction#1 {\global\advance\colcount by1 % +\expandafter\xdef\csname col\the\colcount\endcsname{.#1\hsize}% +\setuptable} + +\newcount\colcount +\def\setuptable#1{\def\firstarg{#1}% +\ifx\firstarg\xendsetuptable\let\go\relax% +\else + \ifx\firstarg\xcolumnfractions\global\setpercenttrue% + \else + \ifsetpercent + \let\go\pickupwholefraction % In this case arg of setuptable + % is the decimal point before the + % number given in percent of hsize. + % We don't need this so we don't use it. + \else + \global\advance\colcount by1 + \setbox0=\hbox{#1 }% Add a normal word space as a separator; + % typically that is always in the input, anyway. + \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% + \fi% + \fi% +\ifx\go\pickupwholefraction\else\let\go\setuptable\fi% +\fi\go} + +%%%% +% multitable syntax +\def\tab{&\hskip1sp\relax} % 2/2/96 + % tiny skip here makes sure this column space is + % maintained, even if it is never used. + + +%%%% +% @multitable ... @end multitable definitions: + +\def\multitable{\parsearg\dotable} + +\def\dotable#1{\bgroup +\let\item\cr +\tolerance=9500 +\hbadness=9500 +\setmultitablespacing +\parskip=\multitableparskip +\parindent=\multitableparindent +\overfullrule=0pt +\global\colcount=0\relax% +\def\Emultitable{\global\setpercentfalse\global\everycr{}\cr\egroup\egroup}% + % To parse everything between @multitable and @item : +\setuptable#1 \endsetuptable + % Need to reset this to 0 after \setuptable. +\global\colcount=0\relax% + % + % This preamble sets up a generic column definition, which will + % be used as many times as user calls for columns. + % \vtop will set a single line and will also let text wrap and + % continue for many paragraphs if desired. +\halign\bgroup&\global\advance\colcount by 1\relax% +\multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname + % In order to keep entries from bumping into each other + % we will add a \leftskip of \multitablecolspace to all columns after + % the first one. + % If a template has been used, we will add \multitablecolspace + % to the width of each template entry. + % If user has set preamble in terms of percent of \hsize + % we will use that dimension as the width of the column, and + % the \leftskip will keep entries from bumping into each other. + % Table will start at left margin and final column will justify at + % right margin. +\ifnum\colcount=1 +\else + \ifsetpercent + \else + % If user has set preamble in terms of percent of \hsize + % we will advance \hsize by \multitablecolspace + \advance\hsize by \multitablecolspace + \fi + % In either case we will make \leftskip=\multitablecolspace: +\leftskip=\multitablecolspace +\fi + % Ignoring space at the beginning and end avoids an occasional spurious + % blank line, when TeX decides to break the line at the space before the + % box from the multistrut, so the strut ends up on a line by itself. + % For example: + % @multitable @columnfractions .11 .89 + % @item @code{#} + % @tab Legal holiday which is valid in major parts of the whole country. + % Is automatically provided with highlighting sequences respectively marking + % characters. + \noindent\ignorespaces##\unskip\multistrut}\cr + % \everycr will reset column counter, \colcount, at the end of + % each line. Every column entry will cause \colcount to advance by one. + % The table preamble + % looks at the current \colcount to find the correct column width. +\global\everycr{\noalign{% +% \filbreak%% keeps underfull box messages off when table breaks over pages. +% Maybe so, but it also creates really weird page breaks when the table +% breaks over pages Wouldn't \vfil be better? Wait until the problem +% manifests itself, so it can be fixed for real --karl. +\global\colcount=0\relax}} +} + +\def\setmultitablespacing{% test to see if user has set \multitablelinespace. +% If so, do nothing. If not, give it an appropriate dimension based on +% current baselineskip. +\ifdim\multitablelinespace=0pt +%% strut to put in table in case some entry doesn't have descenders, +%% to keep lines equally spaced +\let\multistrut = \strut +%% Test to see if parskip is larger than space between lines of +%% table. If not, do nothing. +%% If so, set to same dimension as multitablelinespace. +\else +\gdef\multistrut{\vrule height\multitablelinespace depth\dp0 +width0pt\relax} \fi +\ifdim\multitableparskip>\multitablelinespace +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller + %% than skip between lines in the table. +\fi% +\ifdim\multitableparskip=0pt +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller + %% than skip between lines in the table. +\fi} + + +\message{indexing,} +% Index generation facilities + +% Define \newwrite to be identical to plain tex's \newwrite +% except not \outer, so it can be used within \newindex. +{\catcode`\@=11 +\gdef\newwrite{\alloc@7\write\chardef\sixt@@n}} + +% \newindex {foo} defines an index named foo. +% It automatically defines \fooindex such that +% \fooindex ...rest of line... puts an entry in the index foo. +% It also defines \fooindfile to be the number of the output channel for +% the file that accumulates this index. The file's extension is foo. +% The name of an index should be no more than 2 characters long +% for the sake of vms. + +\def\newindex #1{ +\expandafter\newwrite \csname#1indfile\endcsname% Define number for output file +\openout \csname#1indfile\endcsname \jobname.#1 % Open the file +\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex +\noexpand\doindex {#1}} +} + +% @defindex foo == \newindex{foo} + +\def\defindex{\parsearg\newindex} + +% Define @defcodeindex, like @defindex except put all entries in @code. + +\def\newcodeindex #1{ +\expandafter\newwrite \csname#1indfile\endcsname% Define number for output file +\openout \csname#1indfile\endcsname \jobname.#1 % Open the file +\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex +\noexpand\docodeindex {#1}} +} + +\def\defcodeindex{\parsearg\newcodeindex} + +% @synindex foo bar makes index foo feed into index bar. +% Do this instead of @defindex foo if you don't want it as a separate index. +\def\synindex #1 #2 {% +\expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname +\expandafter\let\csname#1indfile\endcsname=\synindexfoo +\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex +\noexpand\doindex {#2}}% +} + +% @syncodeindex foo bar similar, but put all entries made for index foo +% inside @code. +\def\syncodeindex #1 #2 {% +\expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname +\expandafter\let\csname#1indfile\endcsname=\synindexfoo +\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex +\noexpand\docodeindex {#2}}% +} + +% Define \doindex, the driver for all \fooindex macros. +% Argument #1 is generated by the calling \fooindex macro, +% and it is "foo", the name of the index. + +% \doindex just uses \parsearg; it calls \doind for the actual work. +% This is because \doind is more useful to call from other macros. + +% There is also \dosubind {index}{topic}{subtopic} +% which makes an entry in a two-level index such as the operation index. + +\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} +\def\singleindexer #1{\doind{\indexname}{#1}} + +% like the previous two, but they put @code around the argument. +\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} +\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} + +\def\indexdummies{% +% Take care of the plain tex accent commands. +\def\"{\realbackslash "}% +\def\`{\realbackslash `}% +\def\'{\realbackslash '}% +\def\^{\realbackslash ^}% +\def\~{\realbackslash ~}% +\def\={\realbackslash =}% +\def\b{\realbackslash b}% +\def\c{\realbackslash c}% +\def\d{\realbackslash d}% +\def\u{\realbackslash u}% +\def\v{\realbackslash v}% +\def\H{\realbackslash H}% +% Take care of the plain tex special European modified letters. +\def\oe{\realbackslash oe}% +\def\ae{\realbackslash ae}% +\def\aa{\realbackslash aa}% +\def\OE{\realbackslash OE}% +\def\AE{\realbackslash AE}% +\def\AA{\realbackslash AA}% +\def\o{\realbackslash o}% +\def\O{\realbackslash O}% +\def\l{\realbackslash l}% +\def\L{\realbackslash L}% +\def\ss{\realbackslash ss}% +% Take care of texinfo commands likely to appear in an index entry. +% (Must be a way to avoid doing expansion at all, and thus not have to +% laboriously list every single command here.) +\def\@{@}% will be @@ when we switch to @ as escape char. +%\let\{ = \lbracecmd +%\let\} = \rbracecmd +\def\_{{\realbackslash _}}% +\def\w{\realbackslash w }% +\def\bf{\realbackslash bf }% +%\def\rm{\realbackslash rm }% +\def\sl{\realbackslash sl }% +\def\sf{\realbackslash sf}% +\def\tt{\realbackslash tt}% +\def\gtr{\realbackslash gtr}% +\def\less{\realbackslash less}% +\def\hat{\realbackslash hat}% +%\def\char{\realbackslash char}% +\def\TeX{\realbackslash TeX}% +\def\dots{\realbackslash dots }% +\def\result{\realbackslash result}% +\def\equiv{\realbackslash equiv}% +\def\expansion{\realbackslash expansion}% +\def\print{\realbackslash print}% +\def\error{\realbackslash error}% +\def\point{\realbackslash point}% +\def\copyright{\realbackslash copyright}% +\def\tclose##1{\realbackslash tclose {##1}}% +\def\code##1{\realbackslash code {##1}}% +\def\dotless##1{\realbackslash dotless {##1}}% +\def\samp##1{\realbackslash samp {##1}}% +\def\,##1{\realbackslash ,{##1}}% +\def\t##1{\realbackslash t {##1}}% +\def\r##1{\realbackslash r {##1}}% +\def\i##1{\realbackslash i {##1}}% +\def\b##1{\realbackslash b {##1}}% +\def\sc##1{\realbackslash sc {##1}}% +\def\cite##1{\realbackslash cite {##1}}% +\def\key##1{\realbackslash key {##1}}% +\def\file##1{\realbackslash file {##1}}% +\def\var##1{\realbackslash var {##1}}% +\def\kbd##1{\realbackslash kbd {##1}}% +\def\dfn##1{\realbackslash dfn {##1}}% +\def\emph##1{\realbackslash emph {##1}}% +\def\value##1{\realbackslash value {##1}}% +\unsepspaces +} + +% If an index command is used in an @example environment, any spaces +% therein should become regular spaces in the raw index file, not the +% expansion of \tie (\\leavevmode \penalty \@M \ ). +{\obeyspaces + \gdef\unsepspaces{\obeyspaces\let =\space}} + +% \indexnofonts no-ops all font-change commands. +% This is used when outputting the strings to sort the index by. +\def\indexdummyfont#1{#1} +\def\indexdummytex{TeX} +\def\indexdummydots{...} + +\def\indexnofonts{% +% Just ignore accents. +\let\,=\indexdummyfont +\let\"=\indexdummyfont +\let\`=\indexdummyfont +\let\'=\indexdummyfont +\let\^=\indexdummyfont +\let\~=\indexdummyfont +\let\==\indexdummyfont +\let\b=\indexdummyfont +\let\c=\indexdummyfont +\let\d=\indexdummyfont +\let\u=\indexdummyfont +\let\v=\indexdummyfont +\let\H=\indexdummyfont +\let\dotless=\indexdummyfont +% Take care of the plain tex special European modified letters. +\def\oe{oe}% +\def\ae{ae}% +\def\aa{aa}% +\def\OE{OE}% +\def\AE{AE}% +\def\AA{AA}% +\def\o{o}% +\def\O{O}% +\def\l{l}% +\def\L{L}% +\def\ss{ss}% +\let\w=\indexdummyfont +\let\t=\indexdummyfont +\let\r=\indexdummyfont +\let\i=\indexdummyfont +\let\b=\indexdummyfont +\let\emph=\indexdummyfont +\let\strong=\indexdummyfont +\let\cite=\indexdummyfont +\let\sc=\indexdummyfont +%Don't no-op \tt, since it isn't a user-level command +% and is used in the definitions of the active chars like <, >, |... +%\let\tt=\indexdummyfont +\let\tclose=\indexdummyfont +\let\code=\indexdummyfont +\let\file=\indexdummyfont +\let\samp=\indexdummyfont +\let\kbd=\indexdummyfont +\let\key=\indexdummyfont +\let\var=\indexdummyfont +\let\TeX=\indexdummytex +\let\dots=\indexdummydots +\def\@{@}% +} + +% To define \realbackslash, we must make \ not be an escape. +% We must first make another character (@) an escape +% so we do not become unable to do a definition. + +{\catcode`\@=0 \catcode`\\=\other +@gdef@realbackslash{\}} + +\let\indexbackslash=0 %overridden during \printindex. + +\let\SETmarginindex=\relax %initialize! +% workhorse for all \fooindexes +% #1 is name of index, #2 is stuff to put there +\def\doind #1#2{% + % Put the index entry in the margin if desired. + \ifx\SETmarginindex\relax\else + \insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}% + \fi + {% + \count255=\lastpenalty + {% + \indexdummies % Must do this here, since \bf, etc expand at this stage + \escapechar=`\\ + {% + \let\folio=0% We will expand all macros now EXCEPT \folio. + \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now + % so it will be output as is; and it will print as backslash. + % + % First process the index-string with all font commands turned off + % to get the string to sort by. + {\indexnofonts \xdef\indexsorttmp{#2}}% + % + % Now produce the complete index entry, with both the sort key and the + % original text, including any font commands. + \toks0 = {#2}% + \edef\temp{% + \write\csname#1indfile\endcsname{% + \realbackslash entry{\indexsorttmp}{\folio}{\the\toks0}}% + }% + \temp + }% + }% + \penalty\count255 + }% +} + +\def\dosubind #1#2#3{% +{\count10=\lastpenalty % +{\indexdummies % Must do this here, since \bf, etc expand at this stage +\escapechar=`\\% +{\let\folio=0% +\def\rawbackslashxx{\indexbackslash}% +% +% Now process the index-string once, with all font commands turned off, +% to get the string to sort the index by. +{\indexnofonts +\xdef\temp1{#2 #3}% +}% +% Now produce the complete index entry. We process the index-string again, +% this time with font commands expanded, to get what to print in the index. +\edef\temp{% +\write \csname#1indfile\endcsname{% +\realbackslash entry {\temp1}{\folio}{#2}{#3}}}% +\temp }% +}\penalty\count10}} + +% The index entry written in the file actually looks like +% \entry {sortstring}{page}{topic} +% or +% \entry {sortstring}{page}{topic}{subtopic} +% The texindex program reads in these files and writes files +% containing these kinds of lines: +% \initial {c} +% before the first topic whose initial is c +% \entry {topic}{pagelist} +% for a topic that is used without subtopics +% \primary {topic} +% for the beginning of a topic that is used with subtopics +% \secondary {subtopic}{pagelist} +% for each subtopic. + +% Define the user-accessible indexing commands +% @findex, @vindex, @kindex, @cindex. + +\def\findex {\fnindex} +\def\kindex {\kyindex} +\def\cindex {\cpindex} +\def\vindex {\vrindex} +\def\tindex {\tpindex} +\def\pindex {\pgindex} + +\def\cindexsub {\begingroup\obeylines\cindexsub} +{\obeylines % +\gdef\cindexsub "#1" #2^^M{\endgroup % +\dosubind{cp}{#2}{#1}}} + +% Define the macros used in formatting output of the sorted index material. + +% @printindex causes a particular index (the ??s file) to get printed. +% It does not print any chapter heading (usually an @unnumbered). +% +\def\printindex{\parsearg\doprintindex} +\def\doprintindex#1{\begingroup + \dobreak \chapheadingskip{10000}% + % + \indexfonts \rm + \tolerance = 9500 + \indexbreaks + % + % See if the index file exists and is nonempty. + \openin 1 \jobname.#1s + \ifeof 1 + % \enddoublecolumns gets confused if there is no text in the index, + % and it loses the chapter title and the aux file entries for the + % index. The easiest way to prevent this problem is to make sure + % there is some text. + (Index is nonexistent) + \else + % + % If the index file exists but is empty, then \openin leaves \ifeof + % false. We have to make TeX try to read something from the file, so + % it can discover if there is anything in it. + \read 1 to \temp + \ifeof 1 + (Index is empty) + \else + % Index files are almost Texinfo source, but we use \ as the escape + % character. It would be better to use @, but that's too big a change + % to make right now. + \def\indexbackslash{\rawbackslashxx}% + \catcode`\\ = 0 + \catcode`\@ = 11 + \escapechar = `\\ + \begindoublecolumns + \input \jobname.#1s + \enddoublecolumns + \fi + \fi + \closein 1 +\endgroup} + +% These macros are used by the sorted index file itself. +% Change them to control the appearance of the index. + +% Same as \bigskipamount except no shrink. +% \balancecolumns gets confused if there is any shrink. +\newskip\initialskipamount \initialskipamount 12pt plus4pt + +\def\initial #1{% +{\let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt +\ifdim\lastskip<\initialskipamount +\removelastskip \penalty-200 \vskip \initialskipamount\fi +\line{\secbf#1\hfill}\kern 2pt\penalty10000}} + +% This typesets a paragraph consisting of #1, dot leaders, and then #2 +% flush to the right margin. It is used for index and table of contents +% entries. The paragraph is indented by \leftskip. +% +\def\entry #1#2{\begingroup + % + % Start a new paragraph if necessary, so our assignments below can't + % affect previous text. + \par + % + % Do not fill out the last line with white space. + \parfillskip = 0in + % + % No extra space above this paragraph. + \parskip = 0in + % + % Do not prefer a separate line ending with a hyphen to fewer lines. + \finalhyphendemerits = 0 + % + % \hangindent is only relevant when the entry text and page number + % don't both fit on one line. In that case, bob suggests starting the + % dots pretty far over on the line. Unfortunately, a large + % indentation looks wrong when the entry text itself is broken across + % lines. So we use a small indentation and put up with long leaders. + % + % \hangafter is reset to 1 (which is the value we want) at the start + % of each paragraph, so we need not do anything with that. + \hangindent=2em + % + % When the entry text needs to be broken, just fill out the first line + % with blank space. + \rightskip = 0pt plus1fil + % + % Start a ``paragraph'' for the index entry so the line breaking + % parameters we've set above will have an effect. + \noindent + % + % Insert the text of the index entry. TeX will do line-breaking on it. + #1% + % The following is kludged to not output a line of dots in the index if + % there are no page numbers. The next person who breaks this will be + % cursed by a Unix daemon. + \def\tempa{{\rm }}% + \def\tempb{#2}% + \edef\tempc{\tempa}% + \edef\tempd{\tempb}% + \ifx\tempc\tempd\ \else% + % + % If we must, put the page number on a line of its own, and fill out + % this line with blank space. (The \hfil is overwhelmed with the + % fill leaders glue in \indexdotfill if the page number does fit.) + \hfil\penalty50 + \null\nobreak\indexdotfill % Have leaders before the page number. + % + % The `\ ' here is removed by the implicit \unskip that TeX does as + % part of (the primitive) \par. Without it, a spurious underfull + % \hbox ensues. + \ #2% The page number ends the paragraph. + \fi% + \par +\endgroup} + +% Like \dotfill except takes at least 1 em. +\def\indexdotfill{\cleaders + \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill} + +\def\primary #1{\line{#1\hfil}} + +\newskip\secondaryindent \secondaryindent=0.5cm + +\def\secondary #1#2{ +{\parfillskip=0in \parskip=0in +\hangindent =1in \hangafter=1 +\noindent\hskip\secondaryindent\hbox{#1}\indexdotfill #2\par +}} + +% Define two-column mode, which we use to typeset indexes. +% Adapted from the TeXbook, page 416, which is to say, +% the manmac.tex format used to print the TeXbook itself. +\catcode`\@=11 + +\newbox\partialpage +\newdimen\doublecolumnhsize + +\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns + % Grab any single-column material above us. + \output = {\global\setbox\partialpage = \vbox{% + % + % Here is a possibility not foreseen in manmac: if we accumulate a + % whole lot of material, we might end up calling this \output + % routine twice in a row (see the doublecol-lose test, which is + % essentially a couple of indexes with @setchapternewpage off). In + % that case, we must prevent the second \partialpage from + % simply overwriting the first, causing us to lose the page. + % This will preserve it until a real output routine can ship it + % out. Generally, \partialpage will be empty when this runs and + % this will be a no-op. + \unvbox\partialpage + % + % Unvbox the main output page. + \unvbox255 + \kern-\topskip \kern\baselineskip + }}% + \eject + % + % Use the double-column output routine for subsequent pages. + \output = {\doublecolumnout}% + % + % Change the page size parameters. We could do this once outside this + % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 + % format, but then we repeat the same computation. Repeating a couple + % of assignments once per index is clearly meaningless for the + % execution time, so we may as well do it in one place. + % + % First we halve the line length, less a little for the gutter between + % the columns. We compute the gutter based on the line length, so it + % changes automatically with the paper format. The magic constant + % below is chosen so that the gutter has the same value (well, +-<1pt) + % as it did when we hard-coded it. + % + % We put the result in a separate register, \doublecolumhsize, so we + % can restore it in \pagesofar, after \hsize itself has (potentially) + % been clobbered. + % + \doublecolumnhsize = \hsize + \advance\doublecolumnhsize by -.04154\hsize + \divide\doublecolumnhsize by 2 + \hsize = \doublecolumnhsize + % + % Double the \vsize as well. (We don't need a separate register here, + % since nobody clobbers \vsize.) + \vsize = 2\vsize +} +\def\doublecolumnout{% + \splittopskip=\topskip \splitmaxdepth=\maxdepth + % Get the available space for the double columns -- the normal + % (undoubled) page height minus any material left over from the + % previous page. + \dimen@=\pageheight \advance\dimen@ by-\ht\partialpage + % box0 will be the left-hand column, box2 the right. + \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ + \onepageout\pagesofar + \unvbox255 + \penalty\outputpenalty +} +\def\pagesofar{% + % Re-output the contents of the output page -- any previous material, + % followed by the two boxes we just split. + \unvbox\partialpage + \hsize = \doublecolumnhsize + \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}% +} +\def\enddoublecolumns{% + \output = {\balancecolumns}\eject % split what we have + \endgroup % started in \begindoublecolumns + % + % Back to normal single-column typesetting, but take account of the + % fact that we just accumulated some stuff on the output page. + \pagegoal = \vsize +} +\def\balancecolumns{% + % Called at the end of the double column material. + \setbox0 = \vbox{\unvbox255}% + \dimen@ = \ht0 + \advance\dimen@ by \topskip + \advance\dimen@ by-\baselineskip + \divide\dimen@ by 2 + \splittopskip = \topskip + % Loop until we get a decent breakpoint. + {\vbadness=10000 \loop + \global\setbox3=\copy0 + \global\setbox1=\vsplit3 to\dimen@ + \ifdim\ht3>\dimen@ \global\advance\dimen@ by1pt + \repeat}% + \setbox0=\vbox to\dimen@{\unvbox1}% + \setbox2=\vbox to\dimen@{\unvbox3}% + \pagesofar +} +\catcode`\@ = \other + + +\message{sectioning,} +% Define chapters, sections, etc. + +\newcount\chapno +\newcount\secno \secno=0 +\newcount\subsecno \subsecno=0 +\newcount\subsubsecno \subsubsecno=0 + +% This counter is funny since it counts through charcodes of letters A, B, ... +\newcount\appendixno \appendixno = `\@ +\def\appendixletter{\char\the\appendixno} + +\newwrite\contentsfile +% This is called from \setfilename. +\def\opencontents{\openout\contentsfile = \jobname.toc } + +% Each @chapter defines this as the name of the chapter. +% page headings and footings can use it. @section does likewise + +\def\thischapter{} \def\thissection{} +\def\seccheck#1{\ifnum \pageno<0 + \errmessage{@#1 not allowed after generating table of contents}% +\fi} + +\def\chapternofonts{% + \let\rawbackslash=\relax + \let\frenchspacing=\relax + \def\result{\realbackslash result}% + \def\equiv{\realbackslash equiv}% + \def\expansion{\realbackslash expansion}% + \def\print{\realbackslash print}% + \def\TeX{\realbackslash TeX}% + \def\dots{\realbackslash dots}% + \def\result{\realbackslash result}% + \def\equiv{\realbackslash equiv}% + \def\expansion{\realbackslash expansion}% + \def\print{\realbackslash print}% + \def\error{\realbackslash error}% + \def\point{\realbackslash point}% + \def\copyright{\realbackslash copyright}% + \def\tt{\realbackslash tt}% + \def\bf{\realbackslash bf}% + \def\w{\realbackslash w}% + \def\less{\realbackslash less}% + \def\gtr{\realbackslash gtr}% + \def\hat{\realbackslash hat}% + \def\char{\realbackslash char}% + \def\tclose##1{\realbackslash tclose{##1}}% + \def\code##1{\realbackslash code{##1}}% + \def\samp##1{\realbackslash samp{##1}}% + \def\r##1{\realbackslash r{##1}}% + \def\b##1{\realbackslash b{##1}}% + \def\key##1{\realbackslash key{##1}}% + \def\file##1{\realbackslash file{##1}}% + \def\kbd##1{\realbackslash kbd{##1}}% + % These are redefined because @smartitalic wouldn't work inside xdef. + \def\i##1{\realbackslash i{##1}}% + \def\cite##1{\realbackslash cite{##1}}% + \def\var##1{\realbackslash var{##1}}% + \def\emph##1{\realbackslash emph{##1}}% + \def\dfn##1{\realbackslash dfn{##1}}% +} + +\newcount\absseclevel % used to calculate proper heading level +\newcount\secbase\secbase=0 % @raise/lowersections modify this count + +% @raisesections: treat @section as chapter, @subsection as section, etc. +\def\raisesections{\global\advance\secbase by -1} +\let\up=\raisesections % original BFox name + +% @lowersections: treat @chapter as section, @section as subsection, etc. +\def\lowersections{\global\advance\secbase by 1} +\let\down=\lowersections % original BFox name + +% Choose a numbered-heading macro +% #1 is heading level if unmodified by @raisesections or @lowersections +% #2 is text for heading +\def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 +\ifcase\absseclevel + \chapterzzz{#2} +\or + \seczzz{#2} +\or + \numberedsubseczzz{#2} +\or + \numberedsubsubseczzz{#2} +\else + \ifnum \absseclevel<0 + \chapterzzz{#2} + \else + \numberedsubsubseczzz{#2} + \fi +\fi +} + +% like \numhead, but chooses appendix heading levels +\def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 +\ifcase\absseclevel + \appendixzzz{#2} +\or + \appendixsectionzzz{#2} +\or + \appendixsubseczzz{#2} +\or + \appendixsubsubseczzz{#2} +\else + \ifnum \absseclevel<0 + \appendixzzz{#2} + \else + \appendixsubsubseczzz{#2} + \fi +\fi +} + +% like \numhead, but chooses numberless heading levels +\def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 +\ifcase\absseclevel + \unnumberedzzz{#2} +\or + \unnumberedseczzz{#2} +\or + \unnumberedsubseczzz{#2} +\or + \unnumberedsubsubseczzz{#2} +\else + \ifnum \absseclevel<0 + \unnumberedzzz{#2} + \else + \unnumberedsubsubseczzz{#2} + \fi +\fi +} + + +\def\thischaptername{No Chapter Title} +\outer\def\chapter{\parsearg\chapteryyy} +\def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz +\def\chapterzzz #1{\seccheck{chapter}% +\secno=0 \subsecno=0 \subsubsecno=0 +\global\advance \chapno by 1 \message{\putwordChapter \the\chapno}% +\chapmacro {#1}{\the\chapno}% +\gdef\thissection{#1}% +\gdef\thischaptername{#1}% +% We don't substitute the actual chapter name into \thischapter +% because we don't want its macros evaluated now. +\xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}% +{\chapternofonts% +\toks0 = {#1}% +\edef\temp{{\realbackslash chapentry{\the\toks0}{\the\chapno}{\noexpand\folio}}}% +\escapechar=`\\% +\write \contentsfile \temp % +\donoderef % +\global\let\section = \numberedsec +\global\let\subsection = \numberedsubsec +\global\let\subsubsection = \numberedsubsubsec +}} + +\outer\def\appendix{\parsearg\appendixyyy} +\def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz +\def\appendixzzz #1{\seccheck{appendix}% +\secno=0 \subsecno=0 \subsubsecno=0 +\global\advance \appendixno by 1 \message{Appendix \appendixletter}% +\chapmacro {#1}{\putwordAppendix{} \appendixletter}% +\gdef\thissection{#1}% +\gdef\thischaptername{#1}% +\xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}% +{\chapternofonts% +\toks0 = {#1}% +\edef\temp{{\realbackslash chapentry{\the\toks0}% + {\putwordAppendix{} \appendixletter}{\noexpand\folio}}}% +\escapechar=`\\% +\write \contentsfile \temp % +\appendixnoderef % +\global\let\section = \appendixsec +\global\let\subsection = \appendixsubsec +\global\let\subsubsection = \appendixsubsubsec +}} + +% @centerchap is like @unnumbered, but the heading is centered. +\outer\def\centerchap{\parsearg\centerchapyyy} +\def\centerchapyyy #1{{\let\unnumbchapmacro=\centerchapmacro \unnumberedyyy{#1}}} + +\outer\def\top{\parsearg\unnumberedyyy} +\outer\def\unnumbered{\parsearg\unnumberedyyy} +\def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz +\def\unnumberedzzz #1{\seccheck{unnumbered}% +\secno=0 \subsecno=0 \subsubsecno=0 +% +% This used to be simply \message{#1}, but TeX fully expands the +% argument to \message. Therefore, if #1 contained @-commands, TeX +% expanded them. For example, in `@unnumbered The @cite{Book}', TeX +% expanded @cite (which turns out to cause errors because \cite is meant +% to be executed, not expanded). +% +% Anyway, we don't want the fully-expanded definition of @cite to appear +% as a result of the \message, we just want `@cite' itself. We use +% \the to achieve this: TeX expands \the only once, +% simply yielding the contents of the . +\toks0 = {#1}\message{(\the\toks0)}% +% +\unnumbchapmacro {#1}% +\gdef\thischapter{#1}\gdef\thissection{#1}% +{\chapternofonts% +\toks0 = {#1}% +\edef\temp{{\realbackslash unnumbchapentry{\the\toks0}{\noexpand\folio}}}% +\escapechar=`\\% +\write \contentsfile \temp % +\unnumbnoderef % +\global\let\section = \unnumberedsec +\global\let\subsection = \unnumberedsubsec +\global\let\subsubsection = \unnumberedsubsubsec +}} + +\outer\def\numberedsec{\parsearg\secyyy} +\def\secyyy #1{\numhead1{#1}} % normally calls seczzz +\def\seczzz #1{\seccheck{section}% +\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % +\gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}% +{\chapternofonts% +\toks0 = {#1}% +\edef\temp{{\realbackslash secentry % +{\the\toks0}{\the\chapno}{\the\secno}{\noexpand\folio}}}% +\escapechar=`\\% +\write \contentsfile \temp % +\donoderef % +\penalty 10000 % +}} + +\outer\def\appendixsection{\parsearg\appendixsecyyy} +\outer\def\appendixsec{\parsearg\appendixsecyyy} +\def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz +\def\appendixsectionzzz #1{\seccheck{appendixsection}% +\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % +\gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}% +{\chapternofonts% +\toks0 = {#1}% +\edef\temp{{\realbackslash secentry % +{\the\toks0}{\appendixletter}{\the\secno}{\noexpand\folio}}}% +\escapechar=`\\% +\write \contentsfile \temp % +\appendixnoderef % +\penalty 10000 % +}} + +\outer\def\unnumberedsec{\parsearg\unnumberedsecyyy} +\def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz +\def\unnumberedseczzz #1{\seccheck{unnumberedsec}% +\plainsecheading {#1}\gdef\thissection{#1}% +{\chapternofonts% +\toks0 = {#1}% +\edef\temp{{\realbackslash unnumbsecentry{\the\toks0}{\noexpand\folio}}}% +\escapechar=`\\% +\write \contentsfile \temp % +\unnumbnoderef % +\penalty 10000 % +}} + +\outer\def\numberedsubsec{\parsearg\numberedsubsecyyy} +\def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz +\def\numberedsubseczzz #1{\seccheck{subsection}% +\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % +\subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}% +{\chapternofonts% +\toks0 = {#1}% +\edef\temp{{\realbackslash subsecentry % +{\the\toks0}{\the\chapno}{\the\secno}{\the\subsecno}{\noexpand\folio}}}% +\escapechar=`\\% +\write \contentsfile \temp % +\donoderef % +\penalty 10000 % +}} + +\outer\def\appendixsubsec{\parsearg\appendixsubsecyyy} +\def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz +\def\appendixsubseczzz #1{\seccheck{appendixsubsec}% +\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % +\subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}% +{\chapternofonts% +\toks0 = {#1}% +\edef\temp{{\realbackslash subsecentry % +{\the\toks0}{\appendixletter}{\the\secno}{\the\subsecno}{\noexpand\folio}}}% +\escapechar=`\\% +\write \contentsfile \temp % +\appendixnoderef % +\penalty 10000 % +}} + +\outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy} +\def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz +\def\unnumberedsubseczzz #1{\seccheck{unnumberedsubsec}% +\plainsubsecheading {#1}\gdef\thissection{#1}% +{\chapternofonts% +\toks0 = {#1}% +\edef\temp{{\realbackslash unnumbsubsecentry{\the\toks0}{\noexpand\folio}}}% +\escapechar=`\\% +\write \contentsfile \temp % +\unnumbnoderef % +\penalty 10000 % +}} + +\outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy} +\def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz +\def\numberedsubsubseczzz #1{\seccheck{subsubsection}% +\gdef\thissection{#1}\global\advance \subsubsecno by 1 % +\subsubsecheading {#1} + {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}% +{\chapternofonts% +\toks0 = {#1}% +\edef\temp{{\realbackslash subsubsecentry{\the\toks0} + {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno} + {\noexpand\folio}}}% +\escapechar=`\\% +\write \contentsfile \temp % +\donoderef % +\penalty 10000 % +}} + +\outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy} +\def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz +\def\appendixsubsubseczzz #1{\seccheck{appendixsubsubsec}% +\gdef\thissection{#1}\global\advance \subsubsecno by 1 % +\subsubsecheading {#1} + {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}% +{\chapternofonts% +\toks0 = {#1}% +\edef\temp{{\realbackslash subsubsecentry{\the\toks0}% + {\appendixletter} + {\the\secno}{\the\subsecno}{\the\subsubsecno}{\noexpand\folio}}}% +\escapechar=`\\% +\write \contentsfile \temp % +\appendixnoderef % +\penalty 10000 % +}} + +\outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy} +\def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz +\def\unnumberedsubsubseczzz #1{\seccheck{unnumberedsubsubsec}% +\plainsubsubsecheading {#1}\gdef\thissection{#1}% +{\chapternofonts% +\toks0 = {#1}% +\edef\temp{{\realbackslash unnumbsubsubsecentry{\the\toks0}{\noexpand\folio}}}% +\escapechar=`\\% +\write \contentsfile \temp % +\unnumbnoderef % +\penalty 10000 % +}} + +% These are variants which are not "outer", so they can appear in @ifinfo. +% Actually, they should now be obsolete; ordinary section commands should work. +\def\infotop{\parsearg\unnumberedzzz} +\def\infounnumbered{\parsearg\unnumberedzzz} +\def\infounnumberedsec{\parsearg\unnumberedseczzz} +\def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz} +\def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz} + +\def\infoappendix{\parsearg\appendixzzz} +\def\infoappendixsec{\parsearg\appendixseczzz} +\def\infoappendixsubsec{\parsearg\appendixsubseczzz} +\def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz} + +\def\infochapter{\parsearg\chapterzzz} +\def\infosection{\parsearg\sectionzzz} +\def\infosubsection{\parsearg\subsectionzzz} +\def\infosubsubsection{\parsearg\subsubsectionzzz} + +% These macros control what the section commands do, according +% to what kind of chapter we are in (ordinary, appendix, or unnumbered). +% Define them by default for a numbered chapter. +\global\let\section = \numberedsec +\global\let\subsection = \numberedsubsec +\global\let\subsubsection = \numberedsubsubsec + +% Define @majorheading, @heading and @subheading + +% NOTE on use of \vbox for chapter headings, section headings, and +% such: +% 1) We use \vbox rather than the earlier \line to permit +% overlong headings to fold. +% 2) \hyphenpenalty is set to 10000 because hyphenation in a +% heading is obnoxious; this forbids it. +% 3) Likewise, headings look best if no \parindent is used, and +% if justification is not attempted. Hence \raggedright. + + +\def\majorheading{\parsearg\majorheadingzzz} +\def\majorheadingzzz #1{% +{\advance\chapheadingskip by 10pt \chapbreak }% +{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}\bigskip \par\penalty 200} + +\def\chapheading{\parsearg\chapheadingzzz} +\def\chapheadingzzz #1{\chapbreak % +{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}\bigskip \par\penalty 200} + +% @heading, @subheading, @subsubheading. +\def\heading{\parsearg\plainsecheading} +\def\subheading{\parsearg\plainsubsecheading} +\def\subsubheading{\parsearg\plainsubsubsecheading} + +% These macros generate a chapter, section, etc. heading only +% (including whitespace, linebreaking, etc. around it), +% given all the information in convenient, parsed form. + +%%% Args are the skip and penalty (usually negative) +\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} + +\def\setchapterstyle #1 {\csname CHAPF#1\endcsname} + +%%% Define plain chapter starts, and page on/off switching for it +% Parameter controlling skip before chapter headings (if needed) + +\newskip\chapheadingskip + +\def\chapbreak{\dobreak \chapheadingskip {-4000}} +\def\chappager{\par\vfill\supereject} +\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi} + +\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} + +\def\CHAPPAGoff{ +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chapbreak +\global\let\pagealignmacro=\chappager} + +\def\CHAPPAGon{ +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chappager +\global\let\pagealignmacro=\chappager +\global\def\HEADINGSon{\HEADINGSsingle}} + +\def\CHAPPAGodd{ +\global\let\contentsalignmacro = \chapoddpage +\global\let\pchapsepmacro=\chapoddpage +\global\let\pagealignmacro=\chapoddpage +\global\def\HEADINGSon{\HEADINGSdouble}} + +\CHAPPAGon + +\def\CHAPFplain{ +\global\let\chapmacro=\chfplain +\global\let\unnumbchapmacro=\unnchfplain +\global\let\centerchapmacro=\centerchfplain} + +% Plain chapter opening. +% #1 is the text, #2 the chapter number or empty if unnumbered. +\def\chfplain#1#2{% + \pchapsepmacro + {% + \chapfonts \rm + \def\chapnum{#2}% + \setbox0 = \hbox{#2\ifx\chapnum\empty\else\enspace\fi}% + \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright + \hangindent = \wd0 \centerparametersmaybe + \unhbox0 #1\par}% + }% + \nobreak\bigskip % no page break after a chapter title + \nobreak +} + +% Plain opening for unnumbered. +\def\unnchfplain#1{\chfplain{#1}{}} + +% @centerchap -- centered and unnumbered. +\let\centerparametersmaybe = \relax +\def\centerchfplain#1{{% + \def\centerparametersmaybe{% + \advance\rightskip by 3\rightskip + \leftskip = \rightskip + \parfillskip = 0pt + }% + \chfplain{#1}{}% +}} + +\CHAPFplain % The default + +\def\unnchfopen #1{% +\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}\bigskip \par\penalty 10000 % +} + +\def\chfopen #1#2{\chapoddpage {\chapfonts +\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% +\par\penalty 5000 % +} + +\def\centerchfopen #1{% +\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt + \hfill {\rm #1}\hfill}}\bigskip \par\penalty 10000 % +} + +\def\CHAPFopen{ +\global\let\chapmacro=\chfopen +\global\let\unnumbchapmacro=\unnchfopen +\global\let\centerchapmacro=\centerchfopen} + + +% Section titles. +\newskip\secheadingskip +\def\secheadingbreak{\dobreak \secheadingskip {-1000}} +\def\secheading#1#2#3{\sectionheading{sec}{#2.#3}{#1}} +\def\plainsecheading#1{\sectionheading{sec}{}{#1}} + +% Subsection titles. +\newskip \subsecheadingskip +\def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}} +\def\subsecheading#1#2#3#4{\sectionheading{subsec}{#2.#3.#4}{#1}} +\def\plainsubsecheading#1{\sectionheading{subsec}{}{#1}} + +% Subsubsection titles. +\let\subsubsecheadingskip = \subsecheadingskip +\let\subsubsecheadingbreak = \subsecheadingbreak +\def\subsubsecheading#1#2#3#4#5{\sectionheading{subsubsec}{#2.#3.#4.#5}{#1}} +\def\plainsubsubsecheading#1{\sectionheading{subsubsec}{}{#1}} + + +% Print any size section title. +% +% #1 is the section type (sec/subsec/subsubsec), #2 is the section +% number (maybe empty), #3 the text. +\def\sectionheading#1#2#3{% + {% + \expandafter\advance\csname #1headingskip\endcsname by \parskip + \csname #1headingbreak\endcsname + }% + {% + % Switch to the right set of fonts. + \csname #1fonts\endcsname \rm + % + % Only insert the separating space if we have a section number. + \def\secnum{#2}% + \setbox0 = \hbox{#2\ifx\secnum\empty\else\enspace\fi}% + % + \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright + \hangindent = \wd0 % zero if no section number + \unhbox0 #3}% + }% + \ifdim\parskip<10pt \nobreak\kern10pt\nobreak\kern-\parskip\fi \nobreak +} + + +\message{toc printing,} +% Finish up the main text and prepare to read what we've written +% to \contentsfile. + +\newskip\contentsrightmargin \contentsrightmargin=1in +\def\startcontents#1{% + % If @setchapternewpage on, and @headings double, the contents should + % start on an odd page, unlike chapters. Thus, we maintain + % \contentsalignmacro in parallel with \pagealignmacro. + % From: Torbjorn Granlund + \contentsalignmacro + \immediate\closeout \contentsfile + \ifnum \pageno>0 + \pageno = -1 % Request roman numbered pages. + \fi + % Don't need to put `Contents' or `Short Contents' in the headline. + % It is abundantly clear what they are. + \unnumbchapmacro{#1}\def\thischapter{}% + \begingroup % Set up to handle contents files properly. + \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 + % We can't do this, because then an actual ^ in a section + % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97. + %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi + \raggedbottom % Worry more about breakpoints than the bottom. + \advance\hsize by -\contentsrightmargin % Don't use the full line length. +} + + +% Normal (long) toc. +\outer\def\contents{% + \startcontents{\putwordTableofContents}% + \input \jobname.toc + \endgroup + \vfill \eject +} + +% And just the chapters. +\outer\def\summarycontents{% + \startcontents{\putwordShortContents}% + % + \let\chapentry = \shortchapentry + \let\unnumbchapentry = \shortunnumberedentry + % We want a true roman here for the page numbers. + \secfonts + \let\rm=\shortcontrm \let\bf=\shortcontbf \let\sl=\shortcontsl + \rm + \hyphenpenalty = 10000 + \advance\baselineskip by 1pt % Open it up a little. + \def\secentry ##1##2##3##4{} + \def\unnumbsecentry ##1##2{} + \def\subsecentry ##1##2##3##4##5{} + \def\unnumbsubsecentry ##1##2{} + \def\subsubsecentry ##1##2##3##4##5##6{} + \def\unnumbsubsubsecentry ##1##2{} + \input \jobname.toc + \endgroup + \vfill \eject +} +\let\shortcontents = \summarycontents + +% These macros generate individual entries in the table of contents. +% The first argument is the chapter or section name. +% The last argument is the page number. +% The arguments in between are the chapter number, section number, ... + +% Chapter-level things, for both the long and short contents. +\def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}} + +% See comments in \dochapentry re vbox and related settings +\def\shortchapentry#1#2#3{% + \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno{#3}}% +} + +% Typeset the label for a chapter or appendix for the short contents. +% The arg is, e.g. `Appendix A' for an appendix, or `3' for a chapter. +% We could simplify the code here by writing out an \appendixentry +% command in the toc file for appendices, instead of using \chapentry +% for both, but it doesn't seem worth it. +\setbox0 = \hbox{\shortcontrm \putwordAppendix } +\newdimen\shortappendixwidth \shortappendixwidth = \wd0 + +\def\shortchaplabel#1{% + % We typeset #1 in a box of constant width, regardless of the text of + % #1, so the chapter titles will come out aligned. + \setbox0 = \hbox{#1}% + \dimen0 = \ifdim\wd0 > \shortappendixwidth \shortappendixwidth \else 0pt \fi + % + % This space should be plenty, since a single number is .5em, and the + % widest letter (M) is 1em, at least in the Computer Modern fonts. + % (This space doesn't include the extra space that gets added after + % the label; that gets put in by \shortchapentry above.) + \advance\dimen0 by 1.1em + \hbox to \dimen0{#1\hfil}% +} + +\def\unnumbchapentry#1#2{\dochapentry{#1}{#2}} +\def\shortunnumberedentry#1#2{\tocentry{#1}{\doshortpageno{#2}}} + +% Sections. +\def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}} +\def\unnumbsecentry#1#2{\dosecentry{#1}{#2}} + +% Subsections. +\def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}} +\def\unnumbsubsecentry#1#2{\dosubsecentry{#1}{#2}} + +% And subsubsections. +\def\subsubsecentry#1#2#3#4#5#6{% + \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}} +\def\unnumbsubsubsecentry#1#2{\dosubsubsecentry{#1}{#2}} + +% This parameter controls the indentation of the various levels. +\newdimen\tocindent \tocindent = 3pc + +% Now for the actual typesetting. In all these, #1 is the text and #2 is the +% page number. +% +% If the toc has to be broken over pages, we want it to be at chapters +% if at all possible; hence the \penalty. +\def\dochapentry#1#2{% + \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip + \begingroup + \chapentryfonts + \tocentry{#1}{\dopageno{#2}}% + \endgroup + \nobreak\vskip .25\baselineskip plus.1\baselineskip +} + +\def\dosecentry#1#2{\begingroup + \secentryfonts \leftskip=\tocindent + \tocentry{#1}{\dopageno{#2}}% +\endgroup} + +\def\dosubsecentry#1#2{\begingroup + \subsecentryfonts \leftskip=2\tocindent + \tocentry{#1}{\dopageno{#2}}% +\endgroup} + +\def\dosubsubsecentry#1#2{\begingroup + \subsubsecentryfonts \leftskip=3\tocindent + \tocentry{#1}{\dopageno{#2}}% +\endgroup} + +% Final typesetting of a toc entry; we use the same \entry macro as for +% the index entries, but we want to suppress hyphenation here. (We +% can't do that in the \entry macro, since index entries might consist +% of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) +% +% \turnoffactive is for the sake of @" used for umlauts. +\def\tocentry#1#2{\begingroup + \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks + \entry{\turnoffactive #1}{\turnoffactive #2}% +\endgroup} + +% Space between chapter (or whatever) number and the title. +\def\labelspace{\hskip1em \relax} + +\def\dopageno#1{{\rm #1}} +\def\doshortpageno#1{{\rm #1}} + +\def\chapentryfonts{\secfonts \rm} +\def\secentryfonts{\textfonts} +\let\subsecentryfonts = \textfonts +\let\subsubsecentryfonts = \textfonts + + +\message{environments,} + +% Since these characters are used in examples, it should be an even number of +% \tt widths. Each \tt character is 1en, so two makes it 1em. +% Furthermore, these definitions must come after we define our fonts. +\newbox\dblarrowbox \newbox\longdblarrowbox +\newbox\pushcharbox \newbox\bullbox +\newbox\equivbox \newbox\errorbox + +%{\tentt +%\global\setbox\dblarrowbox = \hbox to 1em{\hfil$\Rightarrow$\hfil} +%\global\setbox\longdblarrowbox = \hbox to 1em{\hfil$\mapsto$\hfil} +%\global\setbox\pushcharbox = \hbox to 1em{\hfil$\dashv$\hfil} +%\global\setbox\equivbox = \hbox to 1em{\hfil$\ptexequiv$\hfil} +% Adapted from the manmac format (p.420 of TeXbook) +%\global\setbox\bullbox = \hbox to 1em{\kern.15em\vrule height .75ex width .85ex +% depth .1ex\hfil} +%} + +% @point{}, @result{}, @expansion{}, @print{}, @equiv{}. +\def\point{$\star$} +\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} +\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}} +\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} +\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}} + +% Adapted from the TeXbook's \boxit. +{\tentt \global\dimen0 = 3em}% Width of the box. +\dimen2 = .55pt % Thickness of rules +% The text. (`r' is open on the right, `e' somewhat less so on the left.) +\setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt} + +\global\setbox\errorbox=\hbox to \dimen0{\hfil + \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. + \advance\hsize by -2\dimen2 % Rules. + \vbox{ + \hrule height\dimen2 + \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. + \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. + \kern3pt\vrule width\dimen2}% Space to right. + \hrule height\dimen2} + \hfil} + +% The @error{} command. +\def\error{\leavevmode\lower.7ex\copy\errorbox} + +% @tex ... @end tex escapes into raw Tex temporarily. +% One exception: @ is still an escape character, so that @end tex works. +% But \@ or @@ will get a plain tex @ character. + +\def\tex{\begingroup +\catcode `\\=0 \catcode `\{=1 \catcode `\}=2 +\catcode `\$=3 \catcode `\&=4 \catcode `\#=6 +\catcode `\^=7 \catcode `\_=8 \catcode `\~=13 \let~=\tie +\catcode `\%=14 +\catcode 43=12 % plus +\catcode`\"=12 +\catcode`\==12 +\catcode`\|=12 +\catcode`\<=12 +\catcode`\>=12 +\escapechar=`\\ +% +\let\,=\ptexcomma +\let\{=\ptexlbrace +\let\}=\ptexrbrace +\let\.=\ptexdot +\let\*=\ptexstar +\let\dots=\ptexdots +\def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% +\def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% +\def\@{@}% +\let\bullet=\ptexbullet +\let\b=\ptexb \let\c=\ptexc \let\i=\ptexi \let\t=\ptext +% +\let\Etex=\endgroup} + +% Define @lisp ... @endlisp. +% @lisp does a \begingroup so it can rebind things, +% including the definition of @endlisp (which normally is erroneous). + +% Amount to narrow the margins by for @lisp. +\newskip\lispnarrowing \lispnarrowing=0.4in + +% This is the definition that ^^M gets inside @lisp, @example, and other +% such environments. \null is better than a space, since it doesn't +% have any width. +\def\lisppar{\null\endgraf} + +% Make each space character in the input produce a normal interword +% space in the output. Don't allow a line break at this space, as this +% is used only in environments like @example, where each line of input +% should produce a line of output anyway. +% +{\obeyspaces % +\gdef\sepspaces{\obeyspaces\let =\tie}} + +% Define \obeyedspace to be our active space, whatever it is. This is +% for use in \parsearg. +{\sepspaces% +\global\let\obeyedspace= } + +% This space is always present above and below environments. +\newskip\envskipamount \envskipamount = 0pt + +% Make spacing and below environment symmetrical. We use \parskip here +% to help in doing that, since in @example-like environments \parskip +% is reset to zero; thus the \afterenvbreak inserts no space -- but the +% start of the next paragraph will insert \parskip +% +\def\aboveenvbreak{{\advance\envskipamount by \parskip +\endgraf \ifdim\lastskip<\envskipamount +\removelastskip \penalty-50 \vskip\envskipamount \fi}} + +\let\afterenvbreak = \aboveenvbreak + +% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins. +\let\nonarrowing=\relax + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \cartouche: draw rectangle w/rounded corners around argument +\font\circle=lcircle10 +\newdimen\circthick +\newdimen\cartouter\newdimen\cartinner +\newskip\normbskip\newskip\normpskip\newskip\normlskip +\circthick=\fontdimen8\circle +% +\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth +\def\ctr{{\hskip 6pt\circle\char'010}} +\def\cbl{{\circle\char'012\hskip -6pt}} +\def\cbr{{\hskip 6pt\circle\char'011}} +\def\carttop{\hbox to \cartouter{\hskip\lskip + \ctl\leaders\hrule height\circthick\hfil\ctr + \hskip\rskip}} +\def\cartbot{\hbox to \cartouter{\hskip\lskip + \cbl\leaders\hrule height\circthick\hfil\cbr + \hskip\rskip}} +% +\newskip\lskip\newskip\rskip + +\long\def\cartouche{% +\begingroup + \lskip=\leftskip \rskip=\rightskip + \leftskip=0pt\rightskip=0pt %we want these *outside*. + \cartinner=\hsize \advance\cartinner by-\lskip + \advance\cartinner by-\rskip + \cartouter=\hsize + \advance\cartouter by 18pt % allow for 3pt kerns on either +% side, and for 6pt waste from +% each corner char + \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip + % Flag to tell @lisp, etc., not to narrow margin. + \let\nonarrowing=\comment + \vbox\bgroup + \baselineskip=0pt\parskip=0pt\lineskip=0pt + \carttop + \hbox\bgroup + \hskip\lskip + \vrule\kern3pt + \vbox\bgroup + \hsize=\cartinner + \kern3pt + \begingroup + \baselineskip=\normbskip + \lineskip=\normlskip + \parskip=\normpskip + \vskip -\parskip +\def\Ecartouche{% + \endgroup + \kern3pt + \egroup + \kern3pt\vrule + \hskip\rskip + \egroup + \cartbot + \egroup +\endgroup +}} + + +% This macro is called at the beginning of all the @example variants, +% inside a group. +\def\nonfillstart{% + \aboveenvbreak + \inENV % This group ends at the end of the body + \hfuzz = 12pt % Don't be fussy + \sepspaces % Make spaces be word-separators rather than space tokens. + \singlespace + \let\par = \lisppar % don't ignore blank lines + \obeylines % each line of input is a line of output + \parskip = 0pt + \parindent = 0pt + \emergencystretch = 0pt % don't try to avoid overfull boxes + % @cartouche defines \nonarrowing to inhibit narrowing + % at next level down. + \ifx\nonarrowing\relax + \advance \leftskip by \lispnarrowing + \exdentamount=\lispnarrowing + \let\exdent=\nofillexdent + \let\nonarrowing=\relax + \fi +} + +% To ending an @example-like environment, we first end the paragraph +% (via \afterenvbreak's vertical glue), and then the group. That way we +% keep the zero \parskip that the environments set -- \parskip glue +% will be inserted at the beginning of the next paragraph in the +% document, after the environment. +% +\def\nonfillfinish{\afterenvbreak\endgroup}% + +\def\lisp{\begingroup + \nonfillstart + \let\Elisp = \nonfillfinish + \tt + % Make @kbd do something special, if requested. + \let\kbdfont\kbdexamplefont + \rawbackslash % have \ input char produce \ char from current font + \gobble +} + +% Define the \E... control sequence only if we are inside the +% environment, so the error checking in \end will work. +% +% We must call \lisp last in the definition, since it reads the +% return following the @example (or whatever) command. +% +\def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp} +\def\smallexample{\begingroup \def\Esmallexample{\nonfillfinish\endgroup}\lisp} +\def\smalllisp{\begingroup \def\Esmalllisp{\nonfillfinish\endgroup}\lisp} + +% @smallexample and @smalllisp. This is not used unless the @smallbook +% command is given. Originally contributed by Pavel@xerox. +% +\def\smalllispx{\begingroup + \nonfillstart + \let\Esmalllisp = \nonfillfinish + \let\Esmallexample = \nonfillfinish + % + % Smaller fonts for small examples. + \indexfonts \tt + \rawbackslash % make \ output the \ character from the current font (tt) + \gobble +} + +% This is @display; same as @lisp except use roman font. +% +\def\display{\begingroup + \nonfillstart + \let\Edisplay = \nonfillfinish + \gobble +} + +% This is @format; same as @display except don't narrow margins. +% +\def\format{\begingroup + \let\nonarrowing = t + \nonfillstart + \let\Eformat = \nonfillfinish + \gobble +} + +% @flushleft (same as @format) and @flushright. +% +\def\flushleft{\begingroup + \let\nonarrowing = t + \nonfillstart + \let\Eflushleft = \nonfillfinish + \gobble +} +\def\flushright{\begingroup + \let\nonarrowing = t + \nonfillstart + \let\Eflushright = \nonfillfinish + \advance\leftskip by 0pt plus 1fill + \gobble} + +% @quotation does normal linebreaking (hence we can't use \nonfillstart) +% and narrows the margins. +% +\def\quotation{% + \begingroup\inENV %This group ends at the end of the @quotation body + {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip + \singlespace + \parindent=0pt + % We have retained a nonzero parskip for the environment, since we're + % doing normal filling. So to avoid extra space below the environment... + \def\Equotation{\parskip = 0pt \nonfillfinish}% + % + % @cartouche defines \nonarrowing to inhibit narrowing at next level down. + \ifx\nonarrowing\relax + \advance\leftskip by \lispnarrowing + \advance\rightskip by \lispnarrowing + \exdentamount = \lispnarrowing + \let\nonarrowing = \relax + \fi +} + +\message{defuns,} +% Define formatter for defuns +% First, allow user to change definition object font (\df) internally +\def\setdeffont #1 {\csname DEF#1\endcsname} + +\newskip\defbodyindent \defbodyindent=.4in +\newskip\defargsindent \defargsindent=50pt +\newskip\deftypemargin \deftypemargin=12pt +\newskip\deflastargmargin \deflastargmargin=18pt + +\newcount\parencount +% define \functionparens, which makes ( and ) and & do special things. +% \functionparens affects the group it is contained in. +\def\activeparens{% +\catcode`\(=\active \catcode`\)=\active \catcode`\&=\active +\catcode`\[=\active \catcode`\]=\active} + +% Make control sequences which act like normal parenthesis chars. +\let\lparen = ( \let\rparen = ) + +{\activeparens % Now, smart parens don't turn on until &foo (see \amprm) + +% Be sure that we always have a definition for `(', etc. For example, +% if the fn name has parens in it, \boldbrax will not be in effect yet, +% so TeX would otherwise complain about undefined control sequence. +\global\let(=\lparen \global\let)=\rparen +\global\let[=\lbrack \global\let]=\rbrack + +\gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } +\gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} +% This is used to turn on special parens +% but make & act ordinary (given that it's active). +\gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr} + +% Definitions of (, ) and & used in args for functions. +% This is the definition of ( outside of all parentheses. +\gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested + \global\advance\parencount by 1 +} +% +% This is the definition of ( when already inside a level of parens. +\gdef\opnested{\char`\(\global\advance\parencount by 1 } +% +\gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0. + % also in that case restore the outer-level definition of (. + \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi + \global\advance \parencount by -1 } +% If we encounter &foo, then turn on ()-hacking afterwards +\gdef\amprm#1 {{\rm\}\let(=\oprm \let)=\clrm\ } +% +\gdef\normalparens{\boldbrax\let&=\ampnr} +} % End of definition inside \activeparens +%% These parens (in \boldbrax) actually are a little bolder than the +%% contained text. This is especially needed for [ and ] +\def\opnr{{\sf\char`\(}\global\advance\parencount by 1 } +\def\clnr{{\sf\char`\)}\global\advance\parencount by -1 } +\def\ampnr{\&} +\def\lbrb{{\bf\char`\[}} +\def\rbrb{{\bf\char`\]}} + +% First, defname, which formats the header line itself. +% #1 should be the function name. +% #2 should be the type of definition, such as "Function". + +\def\defname #1#2{% +% Get the values of \leftskip and \rightskip as they were +% outside the @def... +\dimen2=\leftskip +\advance\dimen2 by -\defbodyindent +\dimen3=\rightskip +\advance\dimen3 by -\defbodyindent +\noindent % +\setbox0=\hbox{\hskip \deflastargmargin{\rm #2}\hskip \deftypemargin}% +\dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line +\dimen1=\hsize \advance \dimen1 by -\defargsindent %size for continuations +\parshape 2 0in \dimen0 \defargsindent \dimen1 % +% Now output arg 2 ("Function" or some such) +% ending at \deftypemargin from the right margin, +% but stuck inside a box of width 0 so it does not interfere with linebreaking +{% Adjust \hsize to exclude the ambient margins, +% so that \rightline will obey them. +\advance \hsize by -\dimen2 \advance \hsize by -\dimen3 +\rlap{\rightline{{\rm #2}\hskip \deftypemargin}}}% +% Make all lines underfull and no complaints: +\tolerance=10000 \hbadness=10000 +\advance\leftskip by -\defbodyindent +\exdentamount=\defbodyindent +{\df #1}\enskip % Generate function name +} + +% Actually process the body of a definition +% #1 should be the terminating control sequence, such as \Edefun. +% #2 should be the "another name" control sequence, such as \defunx. +% #3 should be the control sequence that actually processes the header, +% such as \defunheader. + +\def\defparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2{\begingroup\obeylines\activeparens\spacesplit#3}% +\parindent=0in +\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup % +\catcode 61=\active % 61 is `=' +\obeylines\activeparens\spacesplit#3} + +\def\defmethparsebody #1#2#3#4 {\begingroup\inENV % +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2##1 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}}}% +\parindent=0in +\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup\obeylines\activeparens\spacesplit{#3{#4}}} + +\def\defopparsebody #1#2#3#4#5 {\begingroup\inENV % +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2##1 ##2 {\def#4{##1}% +\begingroup\obeylines\activeparens\spacesplit{#3{##2}}}% +\parindent=0in +\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup\obeylines\activeparens\spacesplit{#3{#5}}} + +% These parsing functions are similar to the preceding ones +% except that they do not make parens into active characters. +% These are used for "variables" since they have no arguments. + +\def\defvarparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2{\begingroup\obeylines\spacesplit#3}% +\parindent=0in +\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup % +\catcode 61=\active % +\obeylines\spacesplit#3} + +% This is used for \def{tp,vr}parsebody. It could probably be used for +% some of the others, too, with some judicious conditionals. +% +\def\parsebodycommon#1#2#3{% + \begingroup\inENV % + \medbreak % + % Define the end token that this defining construct specifies + % so that it will exit this group. + \def#1{\endgraf\endgroup\medbreak}% + \def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}% + \parindent=0in + \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent + \exdentamount=\defbodyindent + \begingroup\obeylines +} + +\def\defvrparsebody#1#2#3#4 {% + \parsebodycommon{#1}{#2}{#3}% + \spacesplit{#3{#4}}% +} + +% This loses on `@deftp {Data Type} {struct termios}' -- it thinks the +% type is just `struct', because we lose the braces in `{struct +% termios}' when \spacesplit reads its undelimited argument. Sigh. +% \let\deftpparsebody=\defvrparsebody +% +% So, to get around this, we put \empty in with the type name. That +% way, TeX won't find exactly `{...}' as an undelimited argument, and +% won't strip off the braces. +% +\def\deftpparsebody #1#2#3#4 {% + \parsebodycommon{#1}{#2}{#3}% + \spacesplit{\parsetpheaderline{#3{#4}}}\empty +} + +% Fine, but then we have to eventually remove the \empty *and* the +% braces (if any). That's what this does. +% +\def\removeemptybraces\empty#1\relax{#1} + +% After \spacesplit has done its work, this is called -- #1 is the final +% thing to call, #2 the type name (which starts with \empty), and #3 +% (which might be empty) the arguments. +% +\def\parsetpheaderline#1#2#3{% + #1{\removeemptybraces#2\relax}{#3}% +}% + +\def\defopvarparsebody #1#2#3#4#5 {\begingroup\inENV % +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2##1 ##2 {\def#4{##1}% +\begingroup\obeylines\spacesplit{#3{##2}}}% +\parindent=0in +\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup\obeylines\spacesplit{#3{#5}}} + +% Split up #2 at the first space token. +% call #1 with two arguments: +% the first is all of #2 before the space token, +% the second is all of #2 after that space token. +% If #2 contains no space token, all of it is passed as the first arg +% and the second is passed as empty. + +{\obeylines +\gdef\spacesplit#1#2^^M{\endgroup\spacesplitfoo{#1}#2 \relax\spacesplitfoo}% +\long\gdef\spacesplitfoo#1#2 #3#4\spacesplitfoo{% +\ifx\relax #3% +#1{#2}{}\else #1{#2}{#3#4}\fi}} + +% So much for the things common to all kinds of definitions. + +% Define @defun. + +% First, define the processing that is wanted for arguments of \defun +% Use this to expand the args and terminate the paragraph they make up + +\def\defunargs #1{\functionparens \sl +% Expand, preventing hyphenation at `-' chars. +% Note that groups don't affect changes in \hyphenchar. +\hyphenchar\tensl=0 +#1% +\hyphenchar\tensl=45 +\ifnum\parencount=0 \else \errmessage{Unbalanced parentheses in @def}\fi% +\interlinepenalty=10000 +\advance\rightskip by 0pt plus 1fil +\endgraf\penalty 10000\vskip -\parskip\penalty 10000% +} + +\def\deftypefunargs #1{% +% Expand, preventing hyphenation at `-' chars. +% Note that groups don't affect changes in \hyphenchar. +% Use \boldbraxnoamp, not \functionparens, so that & is not special. +\boldbraxnoamp +\tclose{#1}% avoid \code because of side effects on active chars +\interlinepenalty=10000 +\advance\rightskip by 0pt plus 1fil +\endgraf\penalty 10000\vskip -\parskip\penalty 10000% +} + +% Do complete processing of one @defun or @defunx line already parsed. + +% @deffn Command forward-char nchars + +\def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader} + +\def\deffnheader #1#2#3{\doind {fn}{\code{#2}}% +\begingroup\defname {#2}{#1}\defunargs{#3}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @defun == @deffn Function + +\def\defun{\defparsebody\Edefun\defunx\defunheader} + +\def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{Function}% +\defunargs {#2}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @deftypefun int foobar (int @var{foo}, float @var{bar}) + +\def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader} + +% #1 is the data type. #2 is the name and args. +\def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax} +% #1 is the data type, #2 the name, #3 the args. +\def\deftypefunheaderx #1#2 #3\relax{% +\doind {fn}{\code{#2}}% Make entry in function index +\begingroup\defname {\defheaderxcond#1\relax$$$#2}{Function}% +\deftypefunargs {#3}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar}) + +\def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader} + +% \defheaderxcond#1\relax$$$ +% puts #1 in @code, followed by a space, but does nothing if #1 is null. +\def\defheaderxcond#1#2$$${\ifx#1\relax\else\code{#1#2} \fi} + +% #1 is the classification. #2 is the data type. #3 is the name and args. +\def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax} +% #1 is the classification, #2 the data type, #3 the name, #4 the args. +\def\deftypefnheaderx #1#2#3 #4\relax{% +\doind {fn}{\code{#3}}% Make entry in function index +\begingroup +\normalparens % notably, turn off `&' magic, which prevents +% at least some C++ text from working +\defname {\defheaderxcond#2\relax$$$#3}{#1}% +\deftypefunargs {#4}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @defmac == @deffn Macro + +\def\defmac{\defparsebody\Edefmac\defmacx\defmacheader} + +\def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{Macro}% +\defunargs {#2}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @defspec == @deffn Special Form + +\def\defspec{\defparsebody\Edefspec\defspecx\defspecheader} + +\def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{Special Form}% +\defunargs {#2}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% This definition is run if you use @defunx +% anywhere other than immediately after a @defun or @defunx. + +\def\deffnx #1 {\errmessage{@deffnx in invalid context}} +\def\defunx #1 {\errmessage{@defunx in invalid context}} +\def\defmacx #1 {\errmessage{@defmacx in invalid context}} +\def\defspecx #1 {\errmessage{@defspecx in invalid context}} +\def\deftypefnx #1 {\errmessage{@deftypefnx in invalid context}} +\def\deftypemethodx #1 {\errmessage{@deftypemethodx in invalid context}} +\def\deftypeunx #1 {\errmessage{@deftypeunx in invalid context}} + +% @defmethod, and so on + +% @defop {Funny Method} foo-class frobnicate argument + +\def\defop #1 {\def\defoptype{#1}% +\defopparsebody\Edefop\defopx\defopheader\defoptype} + +\def\defopheader #1#2#3{% +\dosubind {fn}{\code{#2}}{on #1}% Make entry in function index +\begingroup\defname {#2}{\defoptype{} on #1}% +\defunargs {#3}\endgroup % +} + +% @deftypemethod foo-class return-type foo-method args +% +\def\deftypemethod{% + \defmethparsebody\Edeftypemethod\deftypemethodx\deftypemethodheader} +% +% #1 is the class name, #2 the data type, #3 the method name, #4 the args. +\def\deftypemethodheader#1#2#3#4{% + \deftypefnheaderx{Method on #1}{#2}#3 #4\relax +} + +% @defmethod == @defop Method + +\def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader} + +\def\defmethodheader #1#2#3{% +\dosubind {fn}{\code{#2}}{on #1}% entry in function index +\begingroup\defname {#2}{Method on #1}% +\defunargs {#3}\endgroup % +} + +% @defcv {Class Option} foo-class foo-flag + +\def\defcv #1 {\def\defcvtype{#1}% +\defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype} + +\def\defcvarheader #1#2#3{% +\dosubind {vr}{\code{#2}}{of #1}% Make entry in var index +\begingroup\defname {#2}{\defcvtype{} of #1}% +\defvarargs {#3}\endgroup % +} + +% @defivar == @defcv {Instance Variable} + +\def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader} + +\def\defivarheader #1#2#3{% +\dosubind {vr}{\code{#2}}{of #1}% Make entry in var index +\begingroup\defname {#2}{Instance Variable of #1}% +\defvarargs {#3}\endgroup % +} + +% These definitions are run if you use @defmethodx, etc., +% anywhere other than immediately after a @defmethod, etc. + +\def\defopx #1 {\errmessage{@defopx in invalid context}} +\def\defmethodx #1 {\errmessage{@defmethodx in invalid context}} +\def\defcvx #1 {\errmessage{@defcvx in invalid context}} +\def\defivarx #1 {\errmessage{@defivarx in invalid context}} + +% Now @defvar + +% First, define the processing that is wanted for arguments of @defvar. +% This is actually simple: just print them in roman. +% This must expand the args and terminate the paragraph they make up +\def\defvarargs #1{\normalparens #1% +\interlinepenalty=10000 +\endgraf\penalty 10000\vskip -\parskip\penalty 10000} + +% @defvr Counter foo-count + +\def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader} + +\def\defvrheader #1#2#3{\doind {vr}{\code{#2}}% +\begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup} + +% @defvar == @defvr Variable + +\def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader} + +\def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index +\begingroup\defname {#1}{Variable}% +\defvarargs {#2}\endgroup % +} + +% @defopt == @defvr {User Option} + +\def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader} + +\def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index +\begingroup\defname {#1}{User Option}% +\defvarargs {#2}\endgroup % +} + +% @deftypevar int foobar + +\def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader} + +% #1 is the data type. #2 is the name, perhaps followed by text that +% is actually part of the data type, which should not be put into the index. +\def\deftypevarheader #1#2{% +\dovarind#2 \relax% Make entry in variables index +\begingroup\defname {\defheaderxcond#1\relax$$$#2}{Variable}% +\interlinepenalty=10000 +\endgraf\penalty 10000\vskip -\parskip\penalty 10000 +\endgroup} +\def\dovarind#1 #2\relax{\doind{vr}{\code{#1}}} + +% @deftypevr {Global Flag} int enable + +\def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader} + +\def\deftypevrheader #1#2#3{\dovarind#3 \relax% +\begingroup\defname {\defheaderxcond#2\relax$$$#3}{#1} +\interlinepenalty=10000 +\endgraf\penalty 10000\vskip -\parskip\penalty 10000 +\endgroup} + +% This definition is run if you use @defvarx +% anywhere other than immediately after a @defvar or @defvarx. + +\def\defvrx #1 {\errmessage{@defvrx in invalid context}} +\def\defvarx #1 {\errmessage{@defvarx in invalid context}} +\def\defoptx #1 {\errmessage{@defoptx in invalid context}} +\def\deftypevarx #1 {\errmessage{@deftypevarx in invalid context}} +\def\deftypevrx #1 {\errmessage{@deftypevrx in invalid context}} + +% Now define @deftp +% Args are printed in bold, a slight difference from @defvar. + +\def\deftpargs #1{\bf \defvarargs{#1}} + +% @deftp Class window height width ... + +\def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader} + +\def\deftpheader #1#2#3{\doind {tp}{\code{#2}}% +\begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup} + +% This definition is run if you use @deftpx, etc +% anywhere other than immediately after a @deftp, etc. + +\def\deftpx #1 {\errmessage{@deftpx in invalid context}} + + +\message{cross reference,} +% Define cross-reference macros +\newwrite \auxfile + +\newif\ifhavexrefs % True if xref values are known. +\newif\ifwarnedxrefs % True if we warned once that they aren't known. + +% @inforef is simple. +\def\inforef #1{\inforefzzz #1,,,,**} +\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, + node \samp{\ignorespaces#1{}}} + +% \setref{foo} defines a cross-reference point named foo. + +\def\setref#1{% +\dosetq{#1-title}{Ytitle}% +\dosetq{#1-pg}{Ypagenumber}% +\dosetq{#1-snt}{Ysectionnumberandtype}} + +\def\unnumbsetref#1{% +\dosetq{#1-title}{Ytitle}% +\dosetq{#1-pg}{Ypagenumber}% +\dosetq{#1-snt}{Ynothing}} + +\def\appendixsetref#1{% +\dosetq{#1-title}{Ytitle}% +\dosetq{#1-pg}{Ypagenumber}% +\dosetq{#1-snt}{Yappendixletterandtype}} + +% \xref, \pxref, and \ref generate cross-references to specified points. +% For \xrefX, #1 is the node name, #2 the name of the Info +% cross-reference, #3 the printed node name, #4 the name of the Info +% file, #5 the name of the printed manual. All but the node name can be +% omitted. +% +\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} +\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} +\def\ref#1{\xrefX[#1,,,,,,,]} +\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup + \def\printedmanual{\ignorespaces #5}% + \def\printednodename{\ignorespaces #3}% + \setbox1=\hbox{\printedmanual}% + \setbox0=\hbox{\printednodename}% + \ifdim \wd0 = 0pt + % No printed node name was explicitly given. + \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax + % Use the node name inside the square brackets. + \def\printednodename{\ignorespaces #1}% + \else + % Use the actual chapter/section title appear inside + % the square brackets. Use the real section title if we have it. + \ifdim \wd1>0pt% + % It is in another manual, so we don't have it. + \def\printednodename{\ignorespaces #1}% + \else + \ifhavexrefs + % We know the real title if we have the xref values. + \def\printednodename{\refx{#1-title}{}}% + \else + % Otherwise just copy the Info node name. + \def\printednodename{\ignorespaces #1}% + \fi% + \fi + \fi + \fi + % + % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not + % insert empty discretionaries after hyphens, which means that it will + % not find a line break at a hyphen in a node names. Since some manuals + % are best written with fairly long node names, containing hyphens, this + % is a loss. Therefore, we give the text of the node name again, so it + % is as if TeX is seeing it for the first time. + \ifdim \wd1 > 0pt + \putwordsection{} ``\printednodename'' in \cite{\printedmanual}% + \else + % _ (for example) has to be the character _ for the purposes of the + % control sequence corresponding to the node, but it has to expand + % into the usual \leavevmode...\vrule stuff for purposes of + % printing. So we \turnoffactive for the \refx-snt, back on for the + % printing, back off for the \refx-pg. + {\turnoffactive \refx{#1-snt}{}}% + \space [\printednodename],\space + \turnoffactive \putwordpage\tie\refx{#1-pg}{}% + \fi +\endgroup} + +% \dosetq is the interface for calls from other macros + +% Use \turnoffactive so that punctuation chars such as underscore +% work in node names. +\def\dosetq #1#2{{\let\folio=0 \turnoffactive +\edef\next{\write\auxfile{\internalsetq {#1}{#2}}}% +\next}} + +% \internalsetq {foo}{page} expands into +% CHARACTERS 'xrdef {foo}{...expansion of \Ypage...} +% When the aux file is read, ' is the escape character + +\def\internalsetq #1#2{'xrdef {#1}{\csname #2\endcsname}} + +% Things to be expanded by \internalsetq + +\def\Ypagenumber{\folio} + +\def\Ytitle{\thissection} + +\def\Ynothing{} + +\def\Ysectionnumberandtype{% +\ifnum\secno=0 \putwordChapter\xreftie\the\chapno % +\else \ifnum \subsecno=0 \putwordSection\xreftie\the\chapno.\the\secno % +\else \ifnum \subsubsecno=0 % +\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno % +\else % +\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno % +\fi \fi \fi } + +\def\Yappendixletterandtype{% +\ifnum\secno=0 \putwordAppendix\xreftie'char\the\appendixno{}% +\else \ifnum \subsecno=0 \putwordSection\xreftie'char\the\appendixno.\the\secno % +\else \ifnum \subsubsecno=0 % +\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno % +\else % +\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % +\fi \fi \fi } + +\gdef\xreftie{'tie} + +% Use TeX 3.0's \inputlineno to get the line number, for better error +% messages, but if we're using an old version of TeX, don't do anything. +% +\ifx\inputlineno\thisisundefined + \let\linenumber = \empty % Non-3.0. +\else + \def\linenumber{\the\inputlineno:\space} +\fi + +% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. +% If its value is nonempty, SUFFIX is output afterward. + +\def\refx#1#2{% + \expandafter\ifx\csname X#1\endcsname\relax + % If not defined, say something at least. + $\langle$un\-de\-fined$\rangle$% + \ifhavexrefs + \message{\linenumber Undefined cross reference `#1'.}% + \else + \ifwarnedxrefs\else + \global\warnedxrefstrue + \message{Cross reference values unknown; you must run TeX again.}% + \fi + \fi + \else + % It's defined, so just use it. + \csname X#1\endcsname + \fi + #2% Output the suffix in any case. +} + +% This is the macro invoked by entries in the aux file. +\def\xrdef #1#2{{% + \catcode`\'=\other + \expandafter\gdef\csname X#1\endcsname{#2}% +}} + +% Read the last existing aux file, if any. No error if none exists. +\def\readauxfile{\begingroup + \catcode`\^^@=\other + \catcode`\^^A=\other + \catcode`\^^B=\other + \catcode`\^^C=\other + \catcode`\^^D=\other + \catcode`\^^E=\other + \catcode`\^^F=\other + \catcode`\^^G=\other + \catcode`\^^H=\other + \catcode`\^^K=\other + \catcode`\^^L=\other + \catcode`\^^N=\other + \catcode`\^^P=\other + \catcode`\^^Q=\other + \catcode`\^^R=\other + \catcode`\^^S=\other + \catcode`\^^T=\other + \catcode`\^^U=\other + \catcode`\^^V=\other + \catcode`\^^W=\other + \catcode`\^^X=\other + \catcode`\^^Z=\other + \catcode`\^^[=\other + \catcode`\^^\=\other + \catcode`\^^]=\other + \catcode`\^^^=\other + \catcode`\^^_=\other + \catcode`\@=\other + \catcode`\^=\other + % It was suggested to define this as 7, which would allow ^^e4 etc. + % in xref tags, i.e., node names. But since ^^e4 notation isn't + % supported in the main text, it doesn't seem desirable. Furthermore, + % that is not enough: for node names that actually contain a ^ + % character, we would end up writing a line like this: 'xrdef {'hat + % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first + % argument, and \hat is not an expandable control sequence. It could + % all be worked out, but why? Either we support ^^ or we don't. + % + % The other change necessary for this was to define \auxhat: + % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter + % and then to call \auxhat in \setq. + % + \catcode`\~=\other + \catcode`\[=\other + \catcode`\]=\other + \catcode`\"=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\<=\other + \catcode`\>=\other + \catcode`\$=\other + \catcode`\#=\other + \catcode`\&=\other + % `\+ does not work, so use 43. + \catcode43=\other + % Make the characters 128-255 be printing characters + {% + \count 1=128 + \def\loop{% + \catcode\count 1=\other + \advance\count 1 by 1 + \ifnum \count 1<256 \loop \fi + }% + }% + % The aux file uses ' as the escape (for now). + % Turn off \ as an escape so we do not lose on + % entries which were dumped with control sequences in their names. + % For example, 'xrdef {$\leq $-fun}{page ...} made by @defun ^^ + % Reference to such entries still does not work the way one would wish, + % but at least they do not bomb out when the aux file is read in. + \catcode`\{=1 + \catcode`\}=2 + \catcode`\%=\other + \catcode`\'=0 + \catcode`\\=\other + % + \openin 1 \jobname.aux + \ifeof 1 \else + \closein 1 + \input \jobname.aux + \global\havexrefstrue + \global\warnedobstrue + \fi + % Open the new aux file. TeX will close it automatically at exit. + \openout\auxfile=\jobname.aux +\endgroup} + + +% Footnotes. + +\newcount \footnoteno + +% The trailing space in the following definition for supereject is +% vital for proper filling; pages come out unaligned when you do a +% pagealignmacro call if that space before the closing brace is +% removed. (Generally, numeric constants should always be followed by a +% space to prevent strange expansion errors.) +\def\supereject{\par\penalty -20000\footnoteno =0 } + +% @footnotestyle is meaningful for info output only. +\let\footnotestyle=\comment + +\let\ptexfootnote=\footnote + +{\catcode `\@=11 +% +% Auto-number footnotes. Otherwise like plain. +\gdef\footnote{% + \global\advance\footnoteno by \@ne + \edef\thisfootno{$^{\the\footnoteno}$}% + % + % In case the footnote comes at the end of a sentence, preserve the + % extra spacing after we do the footnote number. + \let\@sf\empty + \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi + % + % Remove inadvertent blank space before typesetting the footnote number. + \unskip + \thisfootno\@sf + \footnotezzz +}% + +% Don't bother with the trickery in plain.tex to not require the +% footnote text as a parameter. Our footnotes don't need to be so general. +% +% Oh yes, they do; otherwise, @ifset and anything else that uses +% \parseargline fail inside footnotes because the tokens are fixed when +% the footnote is read. --karl, 16nov96. +% +\long\gdef\footnotezzz{\insert\footins\bgroup + % We want to typeset this text as a normal paragraph, even if the + % footnote reference occurs in (for example) a display environment. + % So reset some parameters. + \interlinepenalty\interfootnotelinepenalty + \splittopskip\ht\strutbox % top baseline for broken footnotes + \splitmaxdepth\dp\strutbox + \floatingpenalty\@MM + \leftskip\z@skip + \rightskip\z@skip + \spaceskip\z@skip + \xspaceskip\z@skip + \parindent\defaultparindent + % + % Hang the footnote text off the number. + \hang + \textindent{\thisfootno}% + % + % Don't crash into the line above the footnote text. Since this + % expands into a box, it must come within the paragraph, lest it + % provide a place where TeX can split the footnote. + \footstrut + \futurelet\next\fo@t +} +\def\fo@t{\ifcat\bgroup\noexpand\next \let\next\f@@t + \else\let\next\f@t\fi \next} +\def\f@@t{\bgroup\aftergroup\@foot\let\next} +\def\f@t#1{#1\@foot} +\def\@foot{\strut\egroup} + +}%end \catcode `\@=11 + +% Set the baselineskip to #1, and the lineskip and strut size +% correspondingly. There is no deep meaning behind these magic numbers +% used as factors; they just match (closely enough) what Knuth defined. +% +\def\lineskipfactor{.08333} +\def\strutheightpercent{.70833} +\def\strutdepthpercent {.29167} +% +\def\setleading#1{% + \normalbaselineskip = #1\relax + \normallineskip = \lineskipfactor\normalbaselineskip + \normalbaselines + \setbox\strutbox =\hbox{% + \vrule width0pt height\strutheightpercent\baselineskip + depth \strutdepthpercent \baselineskip + }% +} + +% @| inserts a changebar to the left of the current line. It should +% surround any changed text. This approach does *not* work if the +% change spans more than two lines of output. To handle that, we would +% have adopt a much more difficult approach (putting marks into the main +% vertical list for the beginning and end of each change). +% +\def\|{% + % \vadjust can only be used in horizontal mode. + \leavevmode + % + % Append this vertical mode material after the current line in the output. + \vadjust{% + % We want to insert a rule with the height and depth of the current + % leading; that is exactly what \strutbox is supposed to record. + \vskip-\baselineskip + % + % \vadjust-items are inserted at the left edge of the type. So + % the \llap here moves out into the left-hand margin. + \llap{% + % + % For a thicker or thinner bar, change the `1pt'. + \vrule height\baselineskip width1pt + % + % This is the space between the bar and the text. + \hskip 12pt + }% + }% +} + +% For a final copy, take out the rectangles +% that mark overfull boxes (in case you have decided +% that the text looks ok even though it passes the margin). +% +\def\finalout{\overfullrule=0pt} + +% @image. We use the macros from epsf.tex to support this. +% If epsf.tex is not installed and @image is used, we complain. +% +% Check for and read epsf.tex up front. If we read it only at @image +% time, we might be inside a group, and then its definitions would get +% undone and the next image would fail. +\openin 1 = xepsf.tex +\ifeof 1 \else + \closein 1 + \def\epsfannounce{\toks0 = }% do not bother showing banner + \input epsf.tex +\fi +% +\newif\ifwarnednoepsf +\newhelp\noepsfhelp{epsf.tex must be installed for images to + work. It is also included in the Texinfo distribution, or you can get + it from ftp://ftp.tug.org/tex/epsf.tex.} +% +% Only complain once about lack of epsf.tex. +\def\image#1{% + \ifx\epsfbox\undefined + \ifwarnednoepsf \else + \errhelp = \noepsfhelp + \errmessage{epsf.tex not found, images will be ignored}% + \global\warnednoepsftrue + \fi + \else + \imagexxx #1,,,\finish + \fi +} +% +% Arguments to @image: +% #1 is (mandatory) image filename; we tack on .eps extension. +% #2 is (optional) width, #3 is (optional) height. +% #4 is just the usual extra ignored arg for parsing this stuff. +\def\imagexxx#1,#2,#3,#4\finish{% + % \epsfbox itself resets \epsf?size at each figure. + \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi + \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi + \epsfbox{#1.eps}% +} + +% End of control word definitions. + + +\message{and turning on texinfo input format.} + +\def\openindices{% + \newindex{cp}% + \newcodeindex{fn}% + \newcodeindex{vr}% + \newcodeindex{tp}% + \newcodeindex{ky}% + \newcodeindex{pg}% +} + +% Set some numeric style parameters, for 8.5 x 11 format. + +\hsize = 6in +\hoffset = .25in +\newdimen\defaultparindent \defaultparindent = 15pt +\parindent = \defaultparindent +\parskip 3pt plus 2pt minus 1pt +\setleading{13.2pt} +\advance\topskip by 1.2cm + +\chapheadingskip = 15pt plus 4pt minus 2pt +\secheadingskip = 12pt plus 3pt minus 2pt +\subsecheadingskip = 9pt plus 2pt minus 2pt + +% Prevent underfull vbox error messages. +\vbadness=10000 + +% Following George Bush, just get rid of widows and orphans. +\widowpenalty=10000 +\clubpenalty=10000 + +% Use TeX 3.0's \emergencystretch to help line breaking, but if we're +% using an old version of TeX, don't do anything. We want the amount of +% stretch added to depend on the line length, hence the dependence on +% \hsize. This makes it come to about 9pt for the 8.5x11 format. +% +\ifx\emergencystretch\thisisundefined + % Allow us to assign to \emergencystretch anyway. + \def\emergencystretch{\dimen0}% +\else + \emergencystretch = \hsize + \divide\emergencystretch by 45 +\fi + +% Use @smallbook to reset parameters for 7x9.5 format (or else 7x9.25) +\def\smallbook{ + \global\chapheadingskip = 15pt plus 4pt minus 2pt + \global\secheadingskip = 12pt plus 3pt minus 2pt + \global\subsecheadingskip = 9pt plus 2pt minus 2pt + % + \global\lispnarrowing = 0.3in + \setleading{12pt} + \advance\topskip by -1cm + \global\parskip 2pt plus 1pt + \global\hsize = 5in + \global\vsize=7.5in + \global\tolerance=700 + \global\hfuzz=1pt + \global\contentsrightmargin=0pt + \global\deftypemargin=0pt + \global\defbodyindent=.5cm + % + \global\pagewidth=\hsize + \global\pageheight=\vsize + % + \global\let\smalllisp=\smalllispx + \global\let\smallexample=\smalllispx + \global\def\Esmallexample{\Esmalllisp} +} + +% Use @afourpaper to print on European A4 paper. +\def\afourpaper{ +\global\tolerance=700 +\global\hfuzz=1pt +\setleading{12pt} +\global\parskip 15pt plus 1pt + +\global\vsize= 53\baselineskip +\advance\vsize by \topskip +%\global\hsize= 5.85in % A4 wide 10pt +\global\hsize= 6.5in +\global\outerhsize=\hsize +\global\advance\outerhsize by 0.5in +\global\outervsize=\vsize +\global\advance\outervsize by 0.6in + +\global\pagewidth=\hsize +\global\pageheight=\vsize +} + +\bindingoffset=0pt +\normaloffset=\hoffset +\pagewidth=\hsize +\pageheight=\vsize + +% Allow control of the text dimensions. Parameters in order: textheight; +% textwidth; voffset; hoffset; binding offset; topskip. +% All require a dimension; +% header is additional; added length extends the bottom of the page. + +\def\changepagesizes#1#2#3#4#5#6{ + \global\vsize= #1 + \global\topskip= #6 + \advance\vsize by \topskip + \global\voffset= #3 + \global\hsize= #2 + \global\outerhsize=\hsize + \global\advance\outerhsize by 0.5in + \global\outervsize=\vsize + \global\advance\outervsize by 0.6in + \global\pagewidth=\hsize + \global\pageheight=\vsize + \global\normaloffset= #4 + \global\bindingoffset= #5} + +% A specific text layout, 24x15cm overall, intended for A4 paper. Top margin +% 29mm, hence bottom margin 28mm, nominal side margin 3cm. +\def\afourlatex + {\global\tolerance=700 + \global\hfuzz=1pt + \setleading{12pt} + \global\parskip 15pt plus 1pt + \advance\baselineskip by 1.6pt + \changepagesizes{237mm}{150mm}{3.6mm}{3.6mm}{3mm}{7mm} + } + +% Use @afourwide to print on European A4 paper in wide format. +\def\afourwide{\afourpaper +\changepagesizes{9.5in}{6.5in}{\hoffset}{\normaloffset}{\bindingoffset}{7mm}} + +% Define macros to output various characters with catcode for normal text. +\catcode`\"=\other +\catcode`\~=\other +\catcode`\^=\other +\catcode`\_=\other +\catcode`\|=\other +\catcode`\<=\other +\catcode`\>=\other +\catcode`\+=\other +\def\normaldoublequote{"} +\def\normaltilde{~} +\def\normalcaret{^} +\def\normalunderscore{_} +\def\normalverticalbar{|} +\def\normalless{<} +\def\normalgreater{>} +\def\normalplus{+} + +% This macro is used to make a character print one way in ttfont +% where it can probably just be output, and another way in other fonts, +% where something hairier probably needs to be done. +% +% #1 is what to print if we are indeed using \tt; #2 is what to print +% otherwise. Since all the Computer Modern typewriter fonts have zero +% interword stretch (and shrink), and it is reasonable to expect all +% typewriter fonts to have this, we can check that font parameter. +% +\def\ifusingtt#1#2{\ifdim \fontdimen3\the\font=0pt #1\else #2\fi} + +% Turn off all special characters except @ +% (and those which the user can use as if they were ordinary). +% Most of these we simply print from the \tt font, but for some, we can +% use math or other variants that look better in normal text. + +\catcode`\"=\active +\def\activedoublequote{{\tt \char '042}} +\let"=\activedoublequote +\catcode`\~=\active +\def~{{\tt \char '176}} +\chardef\hat=`\^ +\catcode`\^=\active +\def^{{\tt \hat}} + +\catcode`\_=\active +\def_{\ifusingtt\normalunderscore\_} +% Subroutine for the previous macro. +\def\_{\leavevmode \kern.06em \vbox{\hrule width.3em height.1ex}} + +\catcode`\|=\active +\def|{{\tt \char '174}} +\chardef \less=`\< +\catcode`\<=\active +\def<{{\tt \less}} +\chardef \gtr=`\> +\catcode`\>=\active +\def>{{\tt \gtr}} +\catcode`\+=\active +\def+{{\tt \char 43}} +%\catcode 27=\active +%\def^^[{$\diamondsuit$} + +% Set up an active definition for =, but don't enable it most of the time. +{\catcode`\==\active +\global\def={{\tt \char 61}}} + +\catcode`+=\active +\catcode`\_=\active + +% If a .fmt file is being used, characters that might appear in a file +% name cannot be active until we have parsed the command line. +% So turn them off again, and have \everyjob (or @setfilename) turn them on. +% \otherifyactive is called near the end of this file. +\def\otherifyactive{\catcode`+=\other \catcode`\_=\other} + +\catcode`\@=0 + +% \rawbackslashxx output one backslash character in current font +\global\chardef\rawbackslashxx=`\\ +%{\catcode`\\=\other +%@gdef@rawbackslashxx{\}} + +% \rawbackslash redefines \ as input to do \rawbackslashxx. +{\catcode`\\=\active +@gdef@rawbackslash{@let\=@rawbackslashxx }} + +% \normalbackslash outputs one backslash in fixed width font. +\def\normalbackslash{{\tt\rawbackslashxx}} + +% Say @foo, not \foo, in error messages. +\escapechar=`\@ + +% \catcode 17=0 % Define control-q +\catcode`\\=\active + +% Used sometimes to turn off (effectively) the active characters +% even after parsing them. +@def@turnoffactive{@let"=@normaldoublequote +@let\=@realbackslash +@let~=@normaltilde +@let^=@normalcaret +@let_=@normalunderscore +@let|=@normalverticalbar +@let<=@normalless +@let>=@normalgreater +@let+=@normalplus} + +@def@normalturnoffactive{@let"=@normaldoublequote +@let\=@normalbackslash +@let~=@normaltilde +@let^=@normalcaret +@let_=@normalunderscore +@let|=@normalverticalbar +@let<=@normalless +@let>=@normalgreater +@let+=@normalplus} + +% Make _ and + \other characters, temporarily. +% This is canceled by @fixbackslash. +@otherifyactive + +% If a .fmt file is being used, we don't want the `\input texinfo' to show up. +% That is what \eatinput is for; after that, the `\' should revert to printing +% a backslash. +% +@gdef@eatinput input texinfo{@fixbackslash} +@global@let\ = @eatinput + +% On the other hand, perhaps the file did not have a `\input texinfo'. Then +% the first `\{ in the file would cause an error. This macro tries to fix +% that, assuming it is called before the first `\' could plausibly occur. +% Also back turn on active characters that might appear in the input +% file name, in case not using a pre-dumped format. +% +@gdef@fixbackslash{@ifx\@eatinput @let\ = @normalbackslash @fi + @catcode`+=@active @catcode`@_=@active} + +%% These look ok in all fonts, so just make them not special. The @rm below +%% makes sure that the current font starts out as the newly loaded cmr10 +@catcode`@$=@other @catcode`@%=@other @catcode`@&=@other @catcode`@#=@other + +@textfonts +@rm + +@c Local variables: +@c page-delimiter: "^\\\\message" +@c End: diff --git a/reactos/lib/kjs/docs/version.texi b/reactos/lib/kjs/docs/version.texi new file mode 100644 index 00000000000..bdd8ee12d38 --- /dev/null +++ b/reactos/lib/kjs/docs/version.texi @@ -0,0 +1,3 @@ +@set UPDATED 25 November 1998 +@set EDITION 0.2.5 +@set VERSION 0.2.5 diff --git a/reactos/lib/kjs/examples/Makefile b/reactos/lib/kjs/examples/Makefile new file mode 100644 index 00000000000..98daeba2732 --- /dev/null +++ b/reactos/lib/kjs/examples/Makefile @@ -0,0 +1,320 @@ +# Generated automatically from Makefile.in by configure. +# Makefile.in generated automatically by automake 1.3 from Makefile.am + +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Automakefile for the examples directory. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + + +SHELL = /bin/sh + +srcdir = . +top_srcdir = .. +prefix = /usr/local/js-0.2.5 +exec_prefix = ${prefix} + +bindir = ${exec_prefix}/bin +sbindir = ${exec_prefix}/sbin +libexecdir = ${exec_prefix}/libexec +datadir = ${prefix}/share +sysconfdir = ${prefix}/etc +sharedstatedir = ${prefix}/com +localstatedir = ${prefix}/var +libdir = ${exec_prefix}/lib +infodir = ${prefix}/info +mandir = ${prefix}/man +includedir = ${prefix}/include +oldincludedir = /usr/include + +DISTDIR = + +pkgdatadir = $(datadir)/js +pkglibdir = $(libdir)/js +pkgincludedir = $(includedir)/js + +top_builddir = .. + +ACLOCAL = aclocal +AUTOCONF = autoconf +AUTOMAKE = automake +AUTOHEADER = autoheader + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} +transform = s,x,x, + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = i686-pc-linux-gnu +host_triplet = i686-pc-linux-gnu +ACLOCAL_FLAGS_FOR_LIBTOOL = +CC = gcc +CPP = gcc -E +EXTENSIONS = dl_open.lo xjs.lo xmd5.lo md5c.lo +EXTENSIONS_LIBS = -ldl +INTERPRETER_FEATURES = r_std.lo +LD = /usr/bin/ld +LIBTOOL = $(SHELL) $(top_builddir)/libtool +LN_S = ln -s +MAKEINFO = makeinfo +NM = /usr/bin/nm -B +PACKAGE = js +PGCC_BY_PROVENZANO = +RANLIB = ranlib +U = +VERSION = 0.2.5 +XLC_R_AIX = + +INCLUDES = -I$(top_srcdir)/src + +noinst_PROGRAMS = simple ieval + +simple_SOURCES = simple.c + +simple_LDADD = ../src/libjs.la -ldl -lm + +ieval_SOURCES = ieval.c + +ieval_LDADD = ../src/libjs.la -ldl -lm + +EXTRA_DIST = hello.js add.js dload.c +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../jsconfig.h +CONFIG_CLEAN_FILES = +PROGRAMS = $(noinst_PROGRAMS) + + +DEFS = -DHAVE_CONFIG_H -I. -I$(srcdir) -I.. +CPPFLAGS = +LDFLAGS = -rdynamic +LIBS = +simple_OBJECTS = simple.o +simple_DEPENDENCIES = ../src/libjs.la +simple_LDFLAGS = +ieval_OBJECTS = ieval.o +ieval_DEPENDENCIES = ../src/libjs.la +ieval_LDFLAGS = +CFLAGS = -g -O2 +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) +LINK = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP = --best +SOURCES = $(simple_SOURCES) $(ieval_SOURCES) +OBJECTS = $(simple_OBJECTS) $(ieval_OBJECTS) + +all: Makefile $(PROGRAMS) + +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps examples/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-noinstPROGRAMS: + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) + +distclean-noinstPROGRAMS: + +maintainer-clean-noinstPROGRAMS: + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +simple: $(simple_OBJECTS) $(simple_DEPENDENCIES) + @rm -f simple + $(LINK) $(simple_LDFLAGS) $(simple_OBJECTS) $(simple_LDADD) $(LIBS) + +ieval: $(ieval_OBJECTS) $(ieval_DEPENDENCIES) + @rm -f ieval + $(LINK) $(ieval_LDFLAGS) $(ieval_OBJECTS) $(ieval_LDADD) $(LIBS) + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = examples + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done +info: +dvi: +check: all + $(MAKE) +installcheck: +install-exec: + @$(NORMAL_INSTALL) + +install-data: + @$(NORMAL_INSTALL) + +install: install-exec install-data all + @: + +uninstall: + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean: mostlyclean-noinstPROGRAMS mostlyclean-compile \ + mostlyclean-libtool mostlyclean-tags \ + mostlyclean-generic + +clean: clean-noinstPROGRAMS clean-compile clean-libtool clean-tags \ + clean-generic mostlyclean + +distclean: distclean-noinstPROGRAMS distclean-compile distclean-libtool \ + distclean-tags distclean-generic clean + -rm -f config.status + -rm -f libtool + +maintainer-clean: maintainer-clean-noinstPROGRAMS \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-tags maintainer-clean-generic \ + distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +.PHONY: mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \ +clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile mostlyclean-libtool distclean-libtool \ +clean-libtool maintainer-clean-libtool tags mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info dvi \ +installcheck install-exec install-data install uninstall all \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +dload-linux: + $(CC) $(CFLAGS) -shared -fPIC -DPIC dload.c -o dload.so + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/reactos/lib/kjs/examples/Makefile.am b/reactos/lib/kjs/examples/Makefile.am new file mode 100644 index 00000000000..ac84bda705f --- /dev/null +++ b/reactos/lib/kjs/examples/Makefile.am @@ -0,0 +1,40 @@ +# +# Automakefile for the examples directory. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + +INCLUDES = -I$(top_srcdir)/src + +noinst_PROGRAMS = simple ieval + +simple_SOURCES = simple.c + +simple_LDADD = ../src/libjs.la @EXTENSIONS_LIBS@ -lm + +ieval_SOURCES = ieval.c + +ieval_LDADD = ../src/libjs.la @EXTENSIONS_LIBS@ -lm + +EXTRA_DIST = hello.js add.js dload.c + +dload-linux: + $(CC) $(CFLAGS) -shared -fPIC -DPIC dload.c -o dload.so diff --git a/reactos/lib/kjs/examples/Makefile.in b/reactos/lib/kjs/examples/Makefile.in new file mode 100644 index 00000000000..8b46ef33cd9 --- /dev/null +++ b/reactos/lib/kjs/examples/Makefile.in @@ -0,0 +1,320 @@ +# Makefile.in generated automatically by automake 1.3 from Makefile.am + +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Automakefile for the examples directory. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + + +SHELL = /bin/sh + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DISTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_FLAGS_FOR_LIBTOOL = @ACLOCAL_FLAGS_FOR_LIBTOOL@ +CC = @CC@ +CPP = @CPP@ +EXTENSIONS = @EXTENSIONS@ +EXTENSIONS_LIBS = @EXTENSIONS_LIBS@ +INTERPRETER_FEATURES = @INTERPRETER_FEATURES@ +LD = @LD@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +NM = @NM@ +PACKAGE = @PACKAGE@ +PGCC_BY_PROVENZANO = @PGCC_BY_PROVENZANO@ +RANLIB = @RANLIB@ +U = @U@ +VERSION = @VERSION@ +XLC_R_AIX = @XLC_R_AIX@ + +INCLUDES = -I$(top_srcdir)/src + +noinst_PROGRAMS = simple ieval + +simple_SOURCES = simple.c + +simple_LDADD = ../src/libjs.la @EXTENSIONS_LIBS@ -lm + +ieval_SOURCES = ieval.c + +ieval_LDADD = ../src/libjs.la @EXTENSIONS_LIBS@ -lm + +EXTRA_DIST = hello.js add.js dload.c +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../jsconfig.h +CONFIG_CLEAN_FILES = +PROGRAMS = $(noinst_PROGRAMS) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I.. +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +simple_OBJECTS = simple.o +simple_DEPENDENCIES = ../src/libjs.la +simple_LDFLAGS = +ieval_OBJECTS = ieval.o +ieval_DEPENDENCIES = ../src/libjs.la +ieval_LDFLAGS = +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) +LINK = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP = --best +SOURCES = $(simple_SOURCES) $(ieval_SOURCES) +OBJECTS = $(simple_OBJECTS) $(ieval_OBJECTS) + +all: Makefile $(PROGRAMS) + +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps examples/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-noinstPROGRAMS: + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) + +distclean-noinstPROGRAMS: + +maintainer-clean-noinstPROGRAMS: + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +simple: $(simple_OBJECTS) $(simple_DEPENDENCIES) + @rm -f simple + $(LINK) $(simple_LDFLAGS) $(simple_OBJECTS) $(simple_LDADD) $(LIBS) + +ieval: $(ieval_OBJECTS) $(ieval_DEPENDENCIES) + @rm -f ieval + $(LINK) $(ieval_LDFLAGS) $(ieval_OBJECTS) $(ieval_LDADD) $(LIBS) + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = examples + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done +info: +dvi: +check: all + $(MAKE) +installcheck: +install-exec: + @$(NORMAL_INSTALL) + +install-data: + @$(NORMAL_INSTALL) + +install: install-exec install-data all + @: + +uninstall: + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean: mostlyclean-noinstPROGRAMS mostlyclean-compile \ + mostlyclean-libtool mostlyclean-tags \ + mostlyclean-generic + +clean: clean-noinstPROGRAMS clean-compile clean-libtool clean-tags \ + clean-generic mostlyclean + +distclean: distclean-noinstPROGRAMS distclean-compile distclean-libtool \ + distclean-tags distclean-generic clean + -rm -f config.status + -rm -f libtool + +maintainer-clean: maintainer-clean-noinstPROGRAMS \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-tags maintainer-clean-generic \ + distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +.PHONY: mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \ +clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile mostlyclean-libtool distclean-libtool \ +clean-libtool maintainer-clean-libtool tags mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info dvi \ +installcheck install-exec install-data install uninstall all \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +dload-linux: + $(CC) $(CFLAGS) -shared -fPIC -DPIC dload.c -o dload.so + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/reactos/lib/kjs/examples/add.js b/reactos/lib/kjs/examples/add.js new file mode 100644 index 00000000000..3eb4545fe1e --- /dev/null +++ b/reactos/lib/kjs/examples/add.js @@ -0,0 +1,14 @@ +function main () +{ + System.print ("result1=", add (1, 2, 3), "\n"); + System.print ("result2=", add (1, 2, 3.5), "\n"); +} + +main (); + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/examples/dload.c b/reactos/lib/kjs/examples/dload.c new file mode 100644 index 00000000000..96606b76b87 --- /dev/null +++ b/reactos/lib/kjs/examples/dload.c @@ -0,0 +1,60 @@ +/* + * An example of a shared library extension for js. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/examples/dload.c,v $ + * $Id: dload.c,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +#include +#include + +/* + * Static functions. + */ + +/* The `hello' command. */ +JSMethodResult +dlhello_proc (void *context, JSInterpPtr interp, int argc, JSType *argv, + JSType *result_return, char *error_return) +{ + char *msg = context; + + printf ("%s\n", msg); + + return JS_OK; +} + + + +/* + * Global functions. + */ + +void +dload (JSInterpPtr interp) +{ + js_create_global_method (interp, "dlhello", dlhello_proc, + "dlhello: Hello, world!", NULL); +} diff --git a/reactos/lib/kjs/examples/hello.js b/reactos/lib/kjs/examples/hello.js new file mode 100644 index 00000000000..92567d63a74 --- /dev/null +++ b/reactos/lib/kjs/examples/hello.js @@ -0,0 +1,48 @@ +function main () +{ + System.stdout.writeln ("main(): enter"); + + System.stdout.writeln ("calling our `hello' global..."); + hello (); + + System.stdout.writeln ("calling our `Hello.show' method..."); + Hello.show (); + try + { + Hello.fail (); + } + catch (msg) + { + System.stdout.writeln (msg); + } + + System.stdout.writeln ("Hello.msg=" + Hello.msg); + try + { + Hello.msg = "foo"; + } + catch (msg) + { + System.stdout.writeln (msg); + } + + var h1 = new Hello ("Hello, mtr!"); + h1.show (); + + Hello.investigate (h1); + + var h2 = h1.copy (); + h2.show (); + Hello.investigate (h2); + + System.stdout.writeln ("main(): leave"); +} + +main (); + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/examples/ieval.c b/reactos/lib/kjs/examples/ieval.c new file mode 100644 index 00000000000..cf0cf1efabc --- /dev/null +++ b/reactos/lib/kjs/examples/ieval.c @@ -0,0 +1,100 @@ +/* + * Show how the evaluation can be done in phases. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/examples/ieval.c,v $ + * $Id: ieval.c,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +#include +#include +#include +#include + +#include + +/* + * Global functions. + */ + +int +main (int argc, char *argv[]) +{ + char buf[1024]; + JSInterpPtr interp; + + /* Create one interpreter. */ + interp = js_create_interp (NULL); + + /* Enter the query loop. */ + while (1) + { + unsigned char *bc; + unsigned char *bc_copy; + unsigned int bc_len; + char *cp; + + printf ("What file should I evaluate? "); + + if (fgets (buf, sizeof (buf), stdin) == NULL) + break; + + cp = strchr (buf, '\n'); + if (cp) + *cp = '\0'; + + if (js_compile_to_byte_code (interp, buf, &bc, &bc_len) == 0) + { + printf ("Compilation to the byte-code failed: %s\n", + js_error_message (interp)); + continue; + } + + printf ("Compilation returned %d bytes of byte-code data.\n", + bc_len); + + bc_copy = malloc (bc_len); + assert (bc_copy != NULL); + memcpy (bc_copy, bc, bc_len); + + while (1) + { + printf ("Hit ENTER to execute the code. ^D exits the loop. "); + if (getchar () == EOF) + break; + + if (js_execute_byte_code (interp, bc_copy, bc_len) == 0) + printf ("Execution failed: %s\n", js_error_message (interp)); + } + + free (bc_copy); + printf ("\n"); + } + + printf ("\n"); + + js_destroy_interp (interp); + + return 1; +} diff --git a/reactos/lib/kjs/examples/obtype.js b/reactos/lib/kjs/examples/obtype.js new file mode 100644 index 00000000000..6df4239f690 --- /dev/null +++ b/reactos/lib/kjs/examples/obtype.js @@ -0,0 +1,18 @@ +function main () +{ + System.stdout.writeln ("main(): enter"); + + System.stdout.writeln (("fubar").getType().toString()); + System.stdout.writeln ((new Object()).getType().toString()); + + System.stdout.writeln ("main(): leave"); +} + +main (); + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/examples/simple.c b/reactos/lib/kjs/examples/simple.c new file mode 100644 index 00000000000..86456d8ccf3 --- /dev/null +++ b/reactos/lib/kjs/examples/simple.c @@ -0,0 +1,338 @@ +/* + * An example how to embed the JavaScript interpreter to your program. + * Copyright (c) 1998-1999 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/examples/simple.c,v $ + * $Id: simple.c,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +#include +#include + +#include + +/* + * Static functions. + */ + +/* I/O function for the standard error stream. */ +int +io_stderr (void *context, unsigned char *buffer, unsigned int amount) +{ + return fwrite (buffer, 1, amount, stderr); +} + + +/* The `hello' command. */ +JSMethodResult +hello_proc (void *context, JSInterpPtr interp, int argc, JSType *argv, + JSType *result_return, char *error_return) +{ + char *msg = context; + + printf ("%s\n", msg); + + return JS_OK; +} + +/* The `add' command. */ +JSMethodResult +add_proc (void *context, JSInterpPtr interp, int argc, JSType *argv, + JSType *result_return, char *error_return) +{ + int i; + double d = 0.0; + int doubles = 0; + + for (i = 0; i < argc; i++) + { + JSType *arg = &argv[i]; + + switch (arg->type) + { + case JS_TYPE_INTEGER: + d += (double) arg->u.i; + break; + + case JS_TYPE_DOUBLE: + d += arg->u.d; + doubles++; + break; + + default: + sprintf (error_return, "add: illegal argument"); + return JS_ERROR; + break; + } + } + + if (doubles == 0) + { + result_return->type = JS_TYPE_INTEGER; + result_return->u.i = (long) d; + } + else + { + result_return->type = JS_TYPE_DOUBLE; + result_return->u.d = d; + } + + return JS_OK; +} + +/* Methods for the `Hello' class. */ + +/* The instance context for Hello objects. */ +struct hello_ctx_st +{ + char msg[1024]; +}; + +typedef struct hello_ctx_st HelloCtx; + +/* Method `Hello.show()'. */ +static JSMethodResult +hello_show (JSClassPtr cls, void *instance_context, JSInterpPtr interp, + int argc, JSType *argv, JSType *result_return, char *error_return) +{ + HelloCtx *ictx = instance_context; + char *msg; + + if (ictx) + msg = ictx->msg; + else + msg = js_class_context (cls); + + printf ("%s\n", msg); + + return JS_OK; +} + +/* Method `Hello.fail()'. */ +static JSMethodResult +hello_fail (JSClassPtr cls, void *instance_context, JSInterpPtr interp, + int argc, JSType *argv, JSType *result_return, char *error_return) +{ + strcpy (error_return, "My mission is to fail!"); + + return JS_ERROR; +} + +/* Method `Hello.investigate(obj)'. */ +static JSMethodResult +hello_investigate (JSClassPtr cls, void *instance_context, JSInterpPtr interp, + int argc, JSType *argv, JSType *result_return, + char *error_return) +{ + HelloCtx *others_ictx; + + if (argc != 1) + { + strcpy (error_return, "illegal amount of arguments"); + return JS_ERROR; + } + if (!js_isa (interp, &argv[0], js_lookup_class (interp, "Hello"), + (void **) &others_ictx)) + { + strcpy (error_return, "illegal argument"); + return JS_ERROR; + } + + printf ("Hello.investigate(): my argument's message is \"%s\"\n", + others_ictx->msg); + + return JS_OK; +} + +/* Take a copy of us. */ +static JSMethodResult +hello_copy (JSClassPtr cls, void *instance_context, JSInterpPtr interp, + int argc, JSType *argv, JSType *result_return, + char *error_return) +{ + HelloCtx *ictx = instance_context; + HelloCtx *nictx; + JSClassPtr rcls; + + rcls = js_lookup_class (interp, "Hello"); + if (cls != rcls) + { + sprintf (error_return, "internal class error"); + return JS_ERROR; + } + + nictx = malloc (sizeof (*nictx)); + if (ictx) + strcpy (nictx->msg, ictx->msg); + else + strcpy (nictx->msg, "Hello, world!!!!!"); + + js_instantiate_class (interp, cls, nictx, free, result_return); + + return JS_OK; +} + +/* The getter function for the `Hello.msg' property. */ +static JSMethodResult +hello_msg (JSClassPtr cls, void *instance_context, JSInterpPtr interp, + int setp, JSType *value, char *error_return) +{ + HelloCtx *ictx = instance_context; + char *msg; + + if (ictx) + msg = ictx->msg; + else + msg = js_class_context (cls); + + js_type_make_string (interp, value, msg, strlen (msg)); +} + + +static JSMethodResult +hello_constructor (JSClassPtr cls, JSInterpPtr interp, int argc, JSType *argv, + void **ictx_return, JSFreeProc *ictx_destructor_return, + char *error_return) +{ + HelloCtx *ictx; + int len; + + if (argc != 1) + { + strcpy (error_return, "wront amount of arguments"); + return JS_ERROR; + } + if (argv[0].type != JS_TYPE_STRING) + { + strcpy (error_return, "illegal argument"); + return JS_ERROR; + } + + ictx = calloc (1, sizeof (*ictx)); + if (ictx == NULL) + { + strcpy (error_return, "out of memory"); + return JS_ERROR; + } + + len = argv[0].u.s->len; + if (len + 1 > sizeof (ictx->msg)) + len = sizeof (ictx->msg) - 1; + + memcpy (ictx->msg, argv[0].u.s->data, len); + ictx->msg[len] = '\0'; + + *ictx_return = ictx; + *ictx_destructor_return = free; + + return JS_OK; +} + + +/* + * Global functions. + */ + +int +main (int argc, char *argv[]) +{ + JSInterpPtr interp; + JSInterpOptions options; + JSClassPtr cls; + + int i; + + if (argc < 2) + { + fprintf (stderr, "Usage: %s FILE...\n", argv[0]); + exit (1); + } + + /* Create one interpreter. */ + + js_init_default_options (&options); + + options.verbose = 2; + options.s_stderr = io_stderr; + options.s_context = NULL; + + interp = js_create_interp (&options); + + /* Create our extensions. */ + js_create_global_method (interp, "hello", hello_proc, + "(global method) Hello, world!", NULL); + js_create_global_method (interp, "add", add_proc, NULL, NULL); + + /* Create our class. */ + cls = js_class_create ("(Hello) Hello, world!", NULL, 0, + hello_constructor); + + js_class_define_method (cls, "show", JS_CF_STATIC, hello_show); + js_class_define_method (cls, "fail", JS_CF_STATIC, hello_fail); + js_class_define_method (cls, "investigate", JS_CF_STATIC, hello_investigate); + js_class_define_method (cls, "copy", 0, hello_copy); + + js_class_define_property (cls, "msg", JS_CF_STATIC | JS_CF_IMMUTABLE, + hello_msg); + + js_define_class (interp, cls, "Hello"); + + /* Evaluate all argument files. */ + for (i = 1; i < argc; i++) + if (!js_eval_file (interp, argv[i])) + fprintf (stderr, "evaluation of file `%s' failed: %s\n", + argv[i], js_error_message (interp)); + + /* Call our add command with the js_apply() function. */ + { + JSType argv[3]; + + argv[0].type = JS_TYPE_INTEGER; + argv[0].u.i = 42; + + argv[1].type = JS_TYPE_INTEGER; + argv[1].u.i = 72; + + if (!js_apply (interp, "add", 2, argv)) + { + fprintf (stderr, "js_apply() failed: %s\n", js_error_message (interp)); + exit (1); + } + + js_result (interp, &argv[2]); + + if (argv[2].type != JS_TYPE_INTEGER) + { + fprintf (stderr, "add() returned wrong type!\n"); + exit (1); + } + + printf ("%ld + %ld = %ld\n", argv[0].u.i, argv[1].u.i, argv[2].u.i); + } + + /* Cleanup. */ + js_destroy_interp (interp); + + return 1; +} diff --git a/reactos/lib/kjs/include/js.h b/reactos/lib/kjs/include/js.h new file mode 100644 index 00000000000..baaa7a4e2ef --- /dev/null +++ b/reactos/lib/kjs/include/js.h @@ -0,0 +1,503 @@ +/* + * Public API for the JavaScript interpreter. + * Copyright (c) 1998-1999 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/include/js.h,v $ + * $Id: js.h,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +#ifndef JS_H +#define JS_H + +#include + +#ifndef JS_DLLEXPORT + +#ifdef WIN32 +#define JS_DLLEXPORT __declspec(dllexport) +#else /* not WIN32 */ +#define JS_DLLEXPORT +#endif /* not WIN32 */ + +#endif /* not JS_DLLEXPORT */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Types and definitions. + */ + +/* Flags for class methods and properties. */ +#define JS_CF_STATIC 0x01 +#define JS_CF_IMMUTABLE 0x02 + +/* + * This is frustrating. We have to define these, since MS's and + * Borlands' compilers can't agree on how to handle the stupid export + * declarations and function pointer return values. + */ +typedef char *JSCharPtr; +typedef void *JSVoidPtr; + +/* Byte-code instruction dispatch methods. */ +typedef enum +{ + JS_VM_DISPATCH_SWITCH_BASIC, + JS_VM_DISPATCH_SWITCH, + JS_VM_DISPATCH_JUMPS +} JSVMDispatchMethod; + +typedef struct js_interp_st *JSInterpPtr; + +/* + * An I/O function that can be set to interpreter options to redirect + * the system's default streams. + */ +typedef int (*JSIOFunc) (void *context, unsigned char *buffer, + unsigned int amount); + +/* + * Hook that is called at certain points during the byte-code + * execution. Note that the JS_HOOK_OPERAND_COUNT is only available, + * if the interpreter was configured with `--enable-operand-hooks' + * option. + */ + +#define JS_EVENT_OPERAND_COUNT 1 +#define JS_EVENT_GARBAGE_COLLECT 2 + +typedef int (*JSHook) (int event, void *context); + + +/* Interpreter options. */ +struct js_interp_options_st +{ + unsigned int stack_size; + JSVMDispatchMethod dispatch_method; + unsigned int verbose; + + /* Virtual machine flags. */ + + unsigned int no_compiler : 1; + unsigned int stacktrace_on_error : 1; + + unsigned int secure_builtin_file : 1; + unsigned int secure_builtin_system : 1; + + /* Misc compiler flags. */ + unsigned int annotate_assembler : 1; + unsigned int debug_info : 1; + unsigned int executable_bc_files : 1; + + /* Compiler warning flags. */ + unsigned int warn_unused_argument : 1; + unsigned int warn_unused_variable : 1; + unsigned int warn_undef : 1; /* runtime option */ + unsigned int warn_shadow : 1; + unsigned int warn_with_clobber : 1; + unsigned int warn_missing_semicolon : 1; + unsigned int warn_strict_ecma : 1; + unsigned int warn_deprecated : 1; + + /* Compiler optimization flags. */ + unsigned int optimize_peephole : 1; + unsigned int optimize_jumps_to_jumps : 1; + unsigned int optimize_bc_size : 1; + unsigned int optimize_heavy : 1; + + /* + * The standard system streams. If these are NULL, the streams are + * bind to the system's stdin, stdout, and stderr files. + */ + JSIOFunc s_stdin; + JSIOFunc s_stdout; + JSIOFunc s_stderr; + void *s_context; + + /* The callback hook. */ + JSHook hook; + void *hook_context; + + /* + * Call the after the virtual machine has executed this many + * operands. + */ + unsigned int hook_operand_count_trigger; + + /* How many file descriptors the interpreter can allocate. */ + unsigned long fd_count; +}; + +typedef struct js_interp_options_st JSInterpOptions; + + +/* JavaScript public types. */ + +#define JS_TYPE_UNDEFINED 0 +#define JS_TYPE_NULL 1 +#define JS_TYPE_BOOLEAN 2 +#define JS_TYPE_INTEGER 3 +#define JS_TYPE_STRING 4 +#define JS_TYPE_DOUBLE 5 +#define JS_TYPE_ARRAY 6 +#define JS_TYPE_BUILTIN 11 + +/* String type. */ +struct js_type_string_st +{ + unsigned int flags; + unsigned char *data; + unsigned int len; +}; + +typedef struct js_type_string_st JSTypeString; + +/* Array type. */ +struct js_type_array_st +{ + unsigned int length; + struct js_type_st *data; +}; + +typedef struct js_type_array_st JSTypeArray; + +/* The type closure. */ +struct js_type_st +{ + int type; /* One of the JS_TYPE_* values. */ + + union + { + long i; /* integer or boolean */ + JSTypeString *s; /* string */ + double d; /* double */ + JSTypeArray *array; /* array */ + + struct /* Fillter to assure that this the type */ + { /* structure has correct size. */ + unsigned int a1; + unsigned int a2; + } align; + } u; +}; + +typedef struct js_type_st JSType; + +/* Function type to free client data. */ +typedef void (*JSFreeProc) (void *context); + +/* Return types for methods. */ +typedef enum +{ + JS_OK, + JS_ERROR +} JSMethodResult; + +/* Function type for global methods. */ +typedef JSMethodResult (*JSGlobalMethodProc) (void *context, + JSInterpPtr interp, int argc, + JSType *argv, + JSType *result_return, + char *error_return); + +/* Function type for JS modules. */ +typedef void (*JSModuleInitProc) (JSInterpPtr interp); + + +/* Classes. */ + +typedef struct js_class_st *JSClassPtr; + +typedef JSMethodResult (*JSMethodProc) (JSClassPtr cls, void *instance_context, + JSInterpPtr interp, int argc, + JSType *argv, JSType *result_return, + char *error_return); + +typedef JSMethodResult (*JSPropertyProc) (JSClassPtr cls, + void *instance_context, + JSInterpPtr interp, int setp, + JSType *value, char *error_return); + +typedef JSMethodResult (*JSConstructor) (JSClassPtr cls, JSInterpPtr interp, + int argc, JSType *argv, + void **ictx_return, + JSFreeProc *ictx_destructor_return, + char *error_return); + + +/* + * Prototypes global functions. + */ + +/* + * Interpreter handling. + */ + +/* + * Return a string that describes the JavaScript interpreter version + * number. The returned string is in format "MAJOR.MINOR.PATCH", + * where MAJOR, MINOR, and PATCH are integer numbers. + */ +const JSCharPtr JS_DLLEXPORT js_version (); + +/* Initialize interpreter options to system's default values. */ +void JS_DLLEXPORT js_init_default_options (JSInterpOptions *options); + +/* Create a new JavaScript interpreter. */ +struct _KJS; +JSInterpPtr JS_DLLEXPORT js_create_interp (JSInterpOptions *options, + struct _KJS *kjs); + +/* Destroy interpreter . */ +void JS_DLLEXPORT js_destroy_interp (JSInterpPtr interp); + +/* Return error message from the latest error. */ +const JSCharPtr JS_DLLEXPORT js_error_message (JSInterpPtr interp); + +/* + * Get the result of the latest evaluation or execution in interpreter + * . The result is returned in . All data, + * returned in , belongs to the interpreter. The + * caller must not modify or changed it in any ways. + */ +void JS_DLLEXPORT js_result (JSInterpPtr interp, JSType *result_return); + +/* Set the value of global variable to . */ +void JS_DLLEXPORT js_set_var (JSInterpPtr interp, char *name, JSType *value); + +/* Get the value of global variable to . */ +void JS_DLLEXPORT js_get_var (JSInterpPtr interp, char *name, JSType *value); + +/* Get the options of interpreter to . */ +void JS_DLLEXPORT js_get_options (JSInterpPtr interp, + JSInterpOptions *options); + +/* Modify the options of interpreter according to . */ +void JS_DLLEXPORT js_set_options (JSInterpPtr interp, + JSInterpOptions *options); + +/* + * Evaluation and compilation. + */ + +/* Evalutate JavaScript code with interpreter . */ +int JS_DLLEXPORT js_eval (JSInterpPtr interp, char *code); + +/* Evaluate JavaScript code with interpreter . */ +int JS_DLLEXPORT js_eval_data (JSInterpPtr interp, char *data, + unsigned int datalen); + +/* + * Evaluate file with interpreter . File + * can contain JavaScript of byte-code. The function + * return 1 if the evaluation was successful or 0 otherwise. If the + * evaluation failed, the error message can be retrieved with the + * function js_error_message(). + */ +int JS_DLLEXPORT js_eval_file (JSInterpPtr interp, char *filename); + +/* Eval JavaScript file with interpreter . */ +int JS_DLLEXPORT js_eval_javascript_file (JSInterpPtr interp, char *filename); + +/* Execute a byte-code file with interpreter . */ +int JS_DLLEXPORT js_execute_byte_code_file (JSInterpPtr interp, + char *filename); + +/* + * Call funtion with arguments . The return value + * of the function can be retrieved with the js_result() + * function. + */ +int JS_DLLEXPORT js_apply (JSInterpPtr interp, char *name, + unsigned int argc, JSType *argv); + +/* Compile JavaScript file to assembler or byte-code. */ +int JS_DLLEXPORT js_compile (JSInterpPtr interp, char *input_file, + char *assembler_file, char *byte_code_file); + +/* + * Compile JavaScript file to byte-code and return the + * resulting byte-code data in . The + * returned byte-code data belongs to the interpreter + * and it must be saved by the caller *before* any other JS functions + * is called. If the data is not saved, its contents will be invalid + * at the next garbage collection. + */ +int JS_DLLEXPORT js_compile_to_byte_code (JSInterpPtr interp, char *input_file, + unsigned char **bc_return, + unsigned int *bc_len_return); + +/* + * Compile JavaScript code to byte-code and return the + * resulting byte-code data in . + */ +int JS_DLLEXPORT js_compile_data_to_byte_code (JSInterpPtr interp, char *data, + unsigned int datalen, + unsigned char **bc_return, + unsigned int *bc_len_return); + +/* + * Execute byte-code data . The byte-code data is the + * contents of a byte-code file, or a copy of the data returned by the + * js_compile{,_data}_to_byte_code() functions. + * + * Note! You can't use the data from the js_compile{,_data}_to_byte_code() + * functions as an input for this function. Instead, you must take a + * private copy of the data and pass that copy to the function: + * + * if (js_compile_to_byte_code (interp, "./foo.js", &bc, &bclen)) + * { + * char *bc_copy = xmalloc (bclen); + * + * memcpy (bc_copy, bc, bclen); + * js_execute_byte_code (interp, bc_copy, bclen); + * xfree (bc_copy); + * } + */ +int JS_DLLEXPORT js_execute_byte_code (JSInterpPtr interp, unsigned char *bc, + unsigned int bc_len); + + +/* + * Type handling. + */ + +/* + * Create a new string type from that has bytes of data. + * All fields of belong to the interpreter. + */ +void JS_DLLEXPORT js_type_make_string (JSInterpPtr interp, JSType *type, + unsigned char *data, + unsigned int length); + +/* Create a new array with capacity of items. */ +void JS_DLLEXPORT js_type_make_array (JSInterpPtr interp, JSType *type, + unsigned int length); + + +/* + * Global methods. + */ + +/* + * Create a new global method to the interpreter . The + * method's name will be and its implementation is function + * . The argument is a user-specified data that is + * passed to the command . When the command is deleted, the + * argument is called for data to free + * up all resources the might have. The function returns + * 1 if the operation was successful or 0 otherwise. + */ +int JS_DLLEXPORT js_create_global_method (JSInterpPtr interp, char *name, + JSGlobalMethodProc proc, + void *context, + JSFreeProc context_free_proc); + + +/* + * Classes. + */ + +/* + * Create a new class with class context data . The + * context data is destroyed with . If the + * argument is not 0, the JavaScript interpreter + * will *not* destroy the class when the interpreter is destroyed. In + * that case, it is the caller's responsibility to call + * js_class_destroy() for the returned class handle, after the + * interpreter has been destroyed. If the argument is + * not NULL, it is used to instantiate the class when a `new CLASS + * (ARGS);' expression is evaluated in the JavaScript code. + */ +JSClassPtr JS_DLLEXPORT js_class_create (void *class_context, + JSFreeProc class_context_destructor, + int no_auto_destroy, + JSConstructor constuctor); + +void JS_DLLEXPORT js_class_destroy (JSClassPtr cls); + +JSVoidPtr JS_DLLEXPORT js_class_context (JSClassPtr cls); + +int JS_DLLEXPORT js_class_define_method (JSClassPtr cls, char *name, + unsigned int flags, + JSMethodProc method); + +int JS_DLLEXPORT js_class_define_property (JSClassPtr cls, char *name, + unsigned int flags, + JSPropertyProc property); + +int JS_DLLEXPORT js_define_class (JSInterpPtr interp, JSClassPtr cls, + char *name); + +int JS_DLLEXPORT js_instantiate_class (JSInterpPtr interp, JSClassPtr cls, + void *ictx, JSFreeProc ictx_destructor, + JSType *result_return); + +const JSClassPtr JS_DLLEXPORT js_lookup_class (JSInterpPtr interp, + char *name); + +/* + * Check if object is an instance of class . The + * function returns a boolean success status. If the argument + * is not NULL, it will be set to the + * instance context of object . + */ +int JS_DLLEXPORT js_isa (JSInterpPtr interp, JSType *object, JSClassPtr cls, + void **instance_context_return); + + +/* + * Modules. + */ + +/* + * Call the module initialization function . The function + * return 1 if the module was successfully initialized or 0 otherwise. + * In case of error, the error message can be fetched with the + * js_error_mesage() function. + */ +int JS_DLLEXPORT js_define_module (JSInterpPtr interp, + JSModuleInitProc init_proc); + + +/* + * The default modules. + */ + +/* JavaScript interpreter extension. */ +void JS_DLLEXPORT js_ext_JS (JSInterpPtr interp); + +/* Curses extension. */ +void JS_DLLEXPORT js_ext_curses (JSInterpPtr interp); + +/* MD5 extension. */ +void JS_DLLEXPORT js_ext_MD5 (JSInterpPtr interp); + +#ifdef __cplusplus +} +#endif + +#endif /* not JS_H */ diff --git a/reactos/lib/kjs/include/jsconfig.h b/reactos/lib/kjs/include/jsconfig.h new file mode 100644 index 00000000000..9213775f4db --- /dev/null +++ b/reactos/lib/kjs/include/jsconfig.h @@ -0,0 +1,190 @@ +/* jsconfig.h. Generated automatically by configure. */ +/* jsconfig.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _ALL_SOURCE +/* #undef _ALL_SOURCE */ +#endif + +/* Define if using alloca.c. */ +/* #undef C_ALLOCA */ + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. + This function is required for alloca.c support on those systems. */ +/* #undef CRAY_STACKSEG_END */ + +/* Define if you have alloca, as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define if you have and it should be used (not on Ultrix). */ +#define HAVE_ALLOCA_H 1 + +/* Define as __inline if that's what the C compiler calls it. */ +/* #undef inline */ + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown + */ +/* #undef STACK_DIRECTION */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* + * Define the PACKAGE and VERSION only if they are undefined. This means + * that we do not redefine them, when the library is used in another + * GNU like package that defines PACKAGE and VERSION. + */ + +/* Package name. */ +#ifndef PACKAGE +#define PACKAGE "js" +#endif /* no PACKAGE */ + +/* Version number. */ +#ifndef VERSION +#define VERSION "0.2.5" +#endif /* no VERSION */ + +/* Are C prototypes supported. */ +#define PROTOTYPES 1 + +/* Canonical host name and its parts. */ +#define CANONICAL_HOST "i686-pc-linux-gnu" +#define CANONICAL_HOST_CPU "i686" +#define CANONICAL_HOST_VENDOR "pc" +#define CANONICAL_HOST_OS "linux-gnu" + +/* Do we want to build all instruction dispatchers? */ +/* #undef ALL_DISPATCHERS */ + +/* Do we want to profile byte-code operands. */ +/* #undef PROFILING */ + +/* Do we want the byte-code operand hooks. */ +/* #undef BC_OPERAND_HOOKS */ + +/* + * Unconditionall disable the jumps byte-code instruction dispatch + * method. + */ +/* #undef DISABLE_JUMPS */ + +/* Does the struct stat has st_blksize member? */ +#define HAVE_STAT_ST_ST_BLKSIZE 1 + +/* Does the struct stat has st_blocks member? */ +#define HAVE_STAT_ST_ST_BLOCKS 1 + +/* Does the asctime_r() function take three arguments. */ +/* #undef ASCTIME_R_WITH_THREE_ARGS */ + +/* Does the drand48_r() work with DRAND48D data. */ +/* #undef DRAND48_R_WITH_DRAND48D */ + +/* How the attribute structures are passed to the init functions. */ +/* #undef CONDATTR_BY_VALUE */ +/* #undef MUTEXATTR_BY_VALUE */ +/* #undef THREADATTR_BY_VALUE */ + +/* JS */ +#define WITH_JS 1 + +/* Curses. */ +/* #undef WITH_CURSES */ +/* #undef HAVE_CURSES_H */ +/* #undef HAVE_NCURSES_H */ + +/* MD5 */ +#define WITH_MD5 1 + +/* The number of bytes in a int. */ +#define SIZEOF_INT 4 + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 4 + +/* Define if you have the drand48 function. */ +#define HAVE_DRAND48 1 + +/* Define if you have the lstat function. */ +#define HAVE_LSTAT 1 + +/* Define if you have the pthread_attr_create function. */ +/* #undef HAVE_PTHREAD_ATTR_CREATE */ + +/* Define if you have the pthread_attr_setscope function. */ +/* #undef HAVE_PTHREAD_ATTR_SETSCOPE */ + +/* Define if you have the pthread_attr_setstacksize function. */ +/* #undef HAVE_PTHREAD_ATTR_SETSTACKSIZE */ + +/* Define if you have the pthread_condattr_create function. */ +/* #undef HAVE_PTHREAD_CONDATTR_CREATE */ + +/* Define if you have the pthread_condattr_init function. */ +/* #undef HAVE_PTHREAD_CONDATTR_INIT */ + +/* Define if you have the pthread_mutexattr_create function. */ +/* #undef HAVE_PTHREAD_MUTEXATTR_CREATE */ + +/* Define if you have the sleep function. */ +#define HAVE_SLEEP 1 + +/* Define if you have the srand48 function. */ +#define HAVE_SRAND48 1 + +/* Define if you have the usleep function. */ +#define HAVE_USLEEP 1 + +/* Define if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define if you have the header file. */ +#define HAVE_FLOAT_H 1 + +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +#include "ddk/ntddk.h" +#include "ntos/rtl.h" +/* #include "assert.h" */ +#ifndef __TYPE_UINT64 +typedef unsigned __int64 __uint64; +#define __TYPE_UINT64 +#endif/*__TYPE_UINT64*/ + +extern void __kernel_abort(); +#define abort(x) __kernel_abort() +#define HUGE_VAL (__uint64)(-1LL) + +#ifndef SETJMP_DEF +#define SETJMP_DEF +typedef struct _jmpbuf_kernel { + int words[8]; +} jmp_buf[1]; +#endif/*SETJMP_DEF*/ + +int setjmp( jmp_buf j ); +void longjmp( jmp_buf env, int val ); diff --git a/reactos/lib/kjs/include/jsint.h b/reactos/lib/kjs/include/jsint.h new file mode 100644 index 00000000000..09a217ea936 --- /dev/null +++ b/reactos/lib/kjs/include/jsint.h @@ -0,0 +1,1783 @@ +/* + * Internal definitions for the JavaScript interpreter. + * Copyright (c) 1998-1999 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/include/jsint.h,v $ + * $Id: jsint.h,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +#ifndef JSINT_H +#define JSINT_H + +/* We have always jsconfig.h */ +#include +#include "ddk/exfuncs.h" + +#include +#include +/* #include */ +/* #include */ +#include +#include + +#if HAVE_UNISTD_H +#include +#endif + +#if STDC_HEADERS +#include +#include +#include +#include + +#else /* not STDC_HEADERS */ + +#if HAVE_STDLIB_H +#include +#endif + +#if HAVE_ERRNO_H +#include +#endif + +#if HAVE_STRING_H +#include +#endif + +#if HAVE_FLOAT_H +#include +#endif + +#endif /* not STDC_HEADERS */ + +/* Misc system headers. */ + +#include + +/* + * Protability kludges. If something is missing from the w32 + * environment, please edit the micros/w32.{c,h} files and implement + * them. + */ +#ifndef WIN32 + +/* Directory handling. */ +#include + +#endif /* not WIN32 */ + +#include + +#if __cplusplus +extern "C" { +#endif + +/* + * Types and definitions. + */ + +/* Some portability features. */ +#ifdef WIN32 + +#define JS_HOST_LINE_BREAK "\r\n" +#define JS_HOST_LINE_BREAK_LEN 2 + +#else /* not WIN32 */ + +#define JS_HOST_LINE_BREAK "\n" +#define JS_HOST_LINE_BREAK_LEN 1 + +#endif /* not WIN32 */ + + +#define JS_BC_FILE_MAGIC 0xc0014a53 + +#define JS_GLOBAL_NAME ".global" + +#define JS_SYMBOL_NULL ((JSSymbol) -1) + +#define JS_IS_STR_WHITE_SPACE_CHAR(ch) \ + ((ch) == '\t' || (ch) == ' ' || (ch) == '\f' || (ch) == '\v' \ + || (ch) == '\r' || (ch) == '\n') + +/* + * Read macros for byte code files. + */ + +#define JS_BC_READ_INT32(cp, var) \ + (var) = (cp)[0]; \ + (var) <<= 8; \ + (var) |= (cp)[1]; \ + (var) <<= 8; \ + (var) |= (cp)[2]; \ + (var) <<= 8; \ + (var) |= (cp)[3] + +#define JS_BC_READ_INT16(cp, var) \ + (var) = (cp)[0]; \ + (var) <<= 8; \ + (var) |= (cp)[1] + +#define JS_BC_READ_INT8(cp, var) \ + (var) = (cp)[0] + +#define JS_BC_WRITE_INT32(cp, var) \ + cp[3] = (unsigned char) ((var) & 0x000000ff); \ + cp[2] = (unsigned char) (((var) >> 8) & 0x000000ff); \ + cp[1] = (unsigned char) (((var) >> 16) & 0x000000ff); \ + cp[0] = (unsigned char) (((var) >> 24) & 0x000000ff) + + +/* General VM macros. */ + +/* STACKFRAME */ + +#define JS_SP0 sp +#define JS_SP1 (sp + 1) +#define JS_SP2 (sp + 2) +#define JS_SP(n) (sp + (n)) + +#define JS_LOCAL(n) (fp - 4 - (n)) +#define JS_ARG(n) (fp + 1 + (n)) + +#define JS_WITHPTR (fp - 2) +#define JS_ARGS_FIXP (fp - 1) + +#define JS_PUSH() sp-- +#define JS_POP() sp++ +#define JS_POP_N(n) sp += (n) + +#define JS_COPY(to, from) \ + do { \ + (to)->type = (from)->type; \ + (to)->u.copy.a = (from)->u.copy.a; \ + (to)->u.copy.b = (from)->u.copy.b; \ + } while (0) + +#define JS_CONST(n) (&vm->consts[(n)]) +#define JS_GLOBAL(n) (&vm->globals[(n)]) + +#define JS_SAVE_REGS() \ + do { \ + vm->sp = sp; \ + vm->pc = pc; \ + } while (0) + +#define JS_CALL_HOOK(event) \ + do { \ + int hook_result; \ + \ + if (vm->hook) \ + if ((hook_result = (*vm->hook) ((event), vm->hook_context)) != 0) \ + { \ + JS_SAVE_REGS (); \ + sprintf (vm->error, "hook break %d", hook_result); \ + js_vm_error (vm); \ + /* NOTREACHED */ \ + } \ + } while (0) + +#define JS_VM_ALLOCATE_FD(vm, where) \ + do { \ + if ((vm)->fd_count == 0) \ + { \ + sprintf ((vm)->error, "%s: no more file descriptors allowed", \ + (where)); \ + js_vm_error (vm); \ + } \ + (vm)->fd_count--; \ + } while (0) + +#define JS_VM_FREE_FD(vm) \ + do { \ + (vm)->fd_count++; \ + } while (0) + +#define JS_MAYBE_GC() \ + do { \ + if (vm->gc.bytes_allocated >= vm->gc.trigger) \ + { \ + js_vm_garbage_collect (vm, fp, sp); \ + JS_CALL_HOOK (JS_VM_EVENT_GARBAGE_COLLECT); \ + } \ + } while (0) + +#define JS_IS_TRUE(n) ((n)->type > JS_INTEGER \ + || ((n)->type == JS_BOOLEAN && (n)->u.vboolean) \ + || ((n)->type == JS_INTEGER && (n)->u.vinteger)) + +#define JS_IS_FALSE(n) ((n)->type < JS_BOOLEAN \ + || ((n)->type == JS_BOOLEAN && !(n)->u.vboolean) \ + || ((n)->type == JS_INTEGER && !(n)->u.vinteger)) + +#define JS_RESERVE_STACK_FOR_FUNCTION 10 + +#define JS_SUBROUTINE_CALL(function) \ + do { \ + /* Check that we have enought space in the stack. */ \ + if (sp - JS_RESERVE_STACK_FOR_FUNCTION < vm->stack) \ + ERROR ("stack overflow"); \ + \ + /* STACKFRAME */ \ + \ + /* Save frame pointer. */ \ + JS_SP0->type = JS_IPTR; \ + JS_SP0->u.iptr = fp; \ + \ + /* Update fp. */ \ + fp = JS_SP0; \ + JS_PUSH (); \ + \ + /* Insert an empty args_fix. */ \ + JS_SP0->type = JS_ARGS_FIX; \ + JS_SP0->u.args_fix.argc = 0; \ + JS_SP0->u.args_fix.delta = 0; \ + JS_PUSH (); \ + \ + /* Insert empty with pointer. */ \ + JS_SP0->type = JS_IPTR; \ + JS_SP0->u.iptr = NULL; \ + JS_PUSH (); \ + \ + /* Save return address. */ \ + JS_SP0->type = JS_IPTR; \ + JS_SP0->u.iptr = pc; \ + JS_PUSH (); \ + \ + /* And finally, jump to the method code. */ \ + CALL_USER_FUNC ((function)); \ + } while (0) + +#define JS_OPERAND_CMP_REL(_OP_) \ + do { \ + if (JS_SP2->type == JS_STRING && JS_SP1->type == JS_STRING) \ + { \ + JS_SP2->u.vboolean \ + = js_compare_strings (JS_SP2, JS_SP1) _OP_ 0; \ + JS_SP2->type = JS_BOOLEAN; \ + JS_POP (); \ + } \ + else if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) \ + { \ + JS_SP2->u.vboolean \ + = JS_SP2->u.vinteger _OP_ JS_SP1->u.vinteger; \ + JS_SP2->type = JS_BOOLEAN; \ + JS_POP (); \ + } \ + else \ + { \ + JSNode l, r; \ + \ + /* Do it the hard way. */ \ + switch (JS_SP2->type) \ + { \ + case JS_INTEGER: \ + case JS_FLOAT: \ + case JS_NAN: \ + JS_COPY (&l, JS_SP2); \ + break; \ + \ + default: \ + js_vm_to_number (vm, JS_SP2, &l); \ + break; \ + } \ + \ + switch (JS_SP1->type) \ + { \ + case JS_INTEGER: \ + case JS_FLOAT: \ + case JS_NAN: \ + JS_COPY (&r, JS_SP1); \ + break; \ + \ + default: \ + js_vm_to_number (vm, JS_SP1, &r); \ + break; \ + } \ + \ + /* Do the comparison. */ \ + JS_POP (); \ + \ + if (l.type == JS_NAN || r.type == JS_NAN) \ + JS_SP1->type = JS_UNDEFINED; \ + else if (l.type == JS_INTEGER && r.type == JS_INTEGER) \ + { \ + JS_SP1->type = JS_BOOLEAN; \ + JS_SP1->u.vboolean = l.u.vinteger _OP_ r.u.vinteger; \ + } \ + else \ + { \ + double ld, rd; \ + \ + if (l.type == JS_FLOAT) \ + ld = l.u.vfloat; \ + else \ + ld = (double) l.u.vinteger; \ + \ + if (r.type == JS_FLOAT) \ + rd = r.u.vfloat; \ + else \ + rd = (double) r.u.vinteger; \ + \ + JS_SP1->type = JS_BOOLEAN; \ + JS_SP1->u.vboolean = ld _OP_ rd; \ + } \ + } \ + } while (0) + +#define JS_OPERAND_CMP_EQ(_OP_, _VAL_) \ + while (1) { \ + int res; \ + if (JS_SP2->type == JS_SP1->type) \ + { \ + /* Comparsion between same types. */ \ + switch (JS_SP2->type) \ + { \ + case JS_INTEGER: \ + res = JS_SP2->u.vinteger _OP_ JS_SP1->u.vinteger; \ + break; \ + \ + case JS_STRING: \ + res = js_compare_strings (JS_SP2, JS_SP1) _OP_ 0; \ + break; \ + \ + case JS_FLOAT: \ + res = JS_SP2->u.vfloat _OP_ JS_SP1->u.vfloat; \ + break; \ + \ + case JS_NAN: \ + /* 11.9.3: cases 5 and 6 */ \ + res = !_VAL_; \ + break; \ + \ + case JS_BOOLEAN: \ + res = JS_SP2->u.vboolean _OP_ JS_SP1->u.vboolean; \ + break; \ + \ + case JS_OBJECT: \ + res = JS_SP2->u.vobject _OP_ JS_SP1->u.vobject; \ + break; \ + \ + case JS_BUILTIN: \ + res = ((JS_SP2->u.vbuiltin->info \ + == JS_SP1->u.vbuiltin->info \ + && (JS_SP2->u.vbuiltin->instance_context \ + == JS_SP1->u.vbuiltin->instance_context)) \ + ? _VAL_ : !_VAL_); \ + break; \ + \ + case JS_FUNC: \ + res = JS_SP2->u.vfunction _OP_ JS_SP1->u.vfunction; \ + break; \ + \ + case JS_SYMBOL: \ + res = JS_SP2->u.vsymbol _OP_ JS_SP1->u.vsymbol; \ + break; \ + \ + case JS_IPTR: \ + res = JS_SP2->u.iptr _OP_ JS_SP1->u.iptr; \ + break; \ + \ + default: \ + res = _VAL_; \ + break; \ + } \ + } \ + else \ + { \ + /* Type conversions between different types. */ \ + \ + if ((JS_SP2->type == JS_UNDEFINED || JS_SP2->type == JS_NULL) \ + && (JS_SP1->type == JS_UNDEFINED \ + || JS_SP1->type == JS_NULL)) \ + res = _VAL_; \ + \ + /* Numbers. */ \ + else if (JS_IS_NUMBER (JS_SP2) && JS_IS_NUMBER (JS_SP1)) \ + { \ + if (JS_SP2->type == JS_NAN || JS_SP1->type == JS_NAN) \ + /* 11.9.3: cases 5 and 6 */ \ + res = !_VAL_; \ + else if (JS_SP2->type == JS_INTEGER) \ + /* Integer-integer was already handled. */ \ + res = (double) JS_SP2->u.vinteger _OP_ JS_SP1->u.vfloat; \ + else \ + /* Integer-integer was already handled. */ \ + res = JS_SP2->u.vfloat _OP_ (double) JS_SP1->u.vinteger; \ + } \ + else \ + { \ + JSNode l, r; \ + \ + /* Must perform type casts. */ \ + \ + if ((JS_SP2->type == JS_STRING || JS_SP2->type == JS_BOOLEAN \ + || JS_IS_NUMBER (JS_SP2)) \ + && (JS_SP1->type == JS_STRING \ + || JS_SP1->type == JS_BOOLEAN \ + || JS_IS_NUMBER (JS_SP1))) \ + { \ + js_vm_to_number (vm, JS_SP2, &l); \ + js_vm_to_number (vm, JS_SP1, &r); \ + \ + if (l.type == JS_NAN || r.type == JS_NAN) \ + res = !_VAL_; \ + else if (l.type == JS_INTEGER) \ + { \ + if (r.type == JS_INTEGER) \ + res = l.u.vinteger _OP_ r.u.vinteger; \ + else \ + res = (double) l.u.vinteger _OP_ r.u.vfloat; \ + } \ + else \ + { \ + if (r.type == JS_INTEGER) \ + res = l.u.vfloat _OP_ (double) r.u.vinteger; \ + else \ + res = l.u.vfloat _OP_ r.u.vfloat; \ + } \ + } \ + else if (JS_SP2->type == JS_OBJECT \ + && (JS_SP1->type == JS_STRING \ + || JS_IS_NUMBER (JS_SP1))) \ + { \ + JSNode cvt; \ + \ + /* ECMA 11.9.3 21. No preferred type specified. */ \ + js_vm_to_primitive (vm, JS_SP2, &cvt, JS_UNDEFINED); \ + JS_COPY (JS_SP2, &cvt); \ + continue; \ + } \ + else if (JS_SP1->type == JS_OBJECT \ + && (JS_SP2->type == JS_STRING \ + || JS_IS_NUMBER (JS_SP2))) \ + { \ + JSNode cvt; \ + \ + /* ECMA 11.9.3 20. No preferred type specified. */ \ + js_vm_to_primitive (vm, JS_SP1, &cvt, JS_UNDEFINED); \ + JS_COPY (JS_SP1, &cvt); \ + continue; \ + } \ + else \ + res = !_VAL_; \ + } \ + } \ + \ + JS_SP2->type = JS_BOOLEAN; \ + JS_SP2->u.vboolean = res; \ + JS_POP (); \ + break; \ + } + +#define JS_OPERAND_CMP_SEQ(_OP_, _VAL_) \ + do { \ + int res; \ + if (JS_SP2->type == JS_SP1->type) \ + { \ + switch (JS_SP2->type) \ + { \ + case JS_INTEGER: \ + res = JS_SP2->u.vinteger _OP_ JS_SP1->u.vinteger; \ + break; \ + \ + case JS_FLOAT: \ + res = JS_SP2->u.vfloat _OP_ JS_SP1->u.vfloat; \ + break; \ + \ + case JS_NAN: \ + /* 11.9.6: cases 3 and 4 */ \ + res = !_VAL_; \ + break; \ + \ + case JS_STRING: \ + res = js_compare_strings (JS_SP2, JS_SP1) _OP_ 0; \ + break; \ + \ + case JS_BOOLEAN: \ + res = JS_SP2->u.vboolean _OP_ JS_SP1->u.vboolean; \ + break; \ + \ + case JS_OBJECT: \ + res = JS_SP2->u.vobject _OP_ JS_SP1->u.vobject; \ + break; \ + \ + case JS_BUILTIN: \ + res = ((JS_SP2->u.vbuiltin->info \ + == JS_SP1->u.vbuiltin->info \ + && (JS_SP2->u.vbuiltin->instance_context \ + == JS_SP1->u.vbuiltin->instance_context)) \ + ? _VAL_ : !_VAL_); \ + break; \ + \ + case JS_FUNC: \ + res = JS_SP2->u.vfunction _OP_ JS_SP1->u.vfunction; \ + break; \ + \ + default: \ + /* 11.9.6: case 12 */ \ + res = !_VAL_; \ + break; \ + } \ + } \ + else \ + { \ + /* Only numbers are allowed here. */ \ + if (JS_IS_NUMBER (JS_SP2) && JS_IS_NUMBER (JS_SP1)) \ + { \ + if (JS_SP2->type == JS_NAN || JS_SP1->type == JS_NAN) \ + /* 11.9.6: cases 3 and 4 */ \ + res = !_VAL_; \ + else if (JS_SP2->type == JS_INTEGER) \ + res = (double) JS_SP2->u.vinteger _OP_ JS_SP1->u.vfloat; \ + else \ + res = JS_SP2->u.vfloat _OP_ (double) JS_SP1->u.vinteger; \ + } \ + else \ + res = !_VAL_; \ + } \ + \ + JS_SP2->type = JS_BOOLEAN; \ + JS_SP2->u.vboolean = res; \ + JS_POP (); \ + \ + } while (0) + +#define JS_OPERAND_BINARY(_OP_) \ + do { \ + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) \ + { \ + JS_SP2->u.vinteger = ((JSInt32) JS_SP2->u.vinteger \ + _OP_ (JSInt32) JS_SP1->u.vinteger); \ + JS_POP (); \ + } \ + else \ + { \ + JSInt32 l, r; \ + \ + l = js_vm_to_int32 (vm, JS_SP2); \ + r = js_vm_to_int32 (vm, JS_SP1); \ + \ + JS_SP2->u.vinteger = (l _OP_ r); \ + JS_SP2->type = JS_INTEGER; \ + JS_POP (); \ + } \ + } while (0) + + +#define JS_IS_NUMBER(n) \ + ((n)->type == JS_INTEGER || (n)->type == JS_FLOAT || (n)->type == JS_NAN) + +/* Some math macros. */ + +#define JS_MAKE_POSITIVE_INFINITY(node) \ + do { \ + (node)->type = JS_FLOAT; \ + (node)->u.vfloat = HUGE_VAL; \ + } while (0) + +#define JS_MAKE_NEGATIVE_INFINITY(node) \ + do { \ + (node)->type = JS_FLOAT; \ + (node)->u.vfloat = -HUGE_VAL; \ + } while (0) + +#define JS_IS_POSITIVE_INFINITY(node) \ + ((node)->type == JS_FLOAT && (node)->u.vfloat == HUGE_VAL) + +#define JS_IS_NEGATIVE_INFINITY(node) \ + ((node)->type == JS_FLOAT && (node)->u.vfloat == -HUGE_VAL) + +#define JS_IS_FINITE(node) \ + (!JS_IS_POSITIVE_INFINITY ((node)) \ + && !JS_IS_NEGATIVE_INFINITY ((node)) \ + && (node)->type != JS_NAN) \ + +#define JS_IS_PRIMITIVE_VALUE(node) \ + ((node)->type == JS_UNDEFINED || (node)->type == JS_NULL \ + || (node)->type == JS_BOOLEAN || JS_IS_NUMBER ((node)) \ + || (node)->type == JS_STRING) + +/* Macro to clear all flags from a heap memory block. */ +#define JS_HEAP_MEMORY_BLOCK_CLEAR_FLAGS(mb) \ + do { \ + (mb)->flag_mark = 0; \ + (mb)->flag_destroyable = 0; \ + } while (0) + +#define JS_NUM_HEAP_FREELISTS 20 + +/* + * Virtual machine security flags. When these flags are enabled in + * the vm->security, the appropriate built-in modules don't implement + * insecure methods. + */ + +#define JS_VM_SECURE_FILE 0x01 +#define JS_VM_SECURE_SYSTEM 0x02 + +/* + * Noticeable virtual machine events. The `JS_VM_EVENT_OPERAND_COUNT' + * event is generated only if the interpreter was configured with the + * `--enable-operand-hooks' option. + */ + +#define JS_VM_EVENT_OPERAND_COUNT 1 +#define JS_VM_EVENT_GARBAGE_COLLECT 2 + +/* + * Integer types. + */ + +typedef unsigned char JSUInt8; +typedef signed char JSInt8; + +typedef unsigned short JSUInt16; +typedef short JSInt16; + +#if SIZEOF_INT == 4 + +typedef unsigned int JSUInt32; +typedef int JSInt32; + +#else /* not SIZEOF_INT == 4 */ + +#if SIZEOF_LONG == 4 + +typedef unsigned long JSUInt32; +typedef long JSInt32; + +#else /* not SIZEOF_LONG == 4 */ + +#error "do not know how to define a 32 bit long integer" + +#endif /* not SIZEOF_LONG == 4 */ + +#endif /* not SIZEOF_INT == 4 */ + +/* + * An unsigned interger number that can be used to align structures to + * correct byte boundaries. On 64 bit machines (Alpha) this should be + * 64 bits long, etc. For now one, we just assume that the mashine is + * a LP64 so the `unsigned long' is a correct type for it. + */ +typedef unsigned long JSUIntAlign; + +/* I/O streams. */ + +/* Buffer filler or flusher function. */ +typedef int (*JSIOStreamIOFunc) (void *context, unsigned char *buffer, + unsigned int todo, int *error_return); + +typedef int (*JSIOStreamSeek) (void *context, long offset, int whence); + +typedef long (*JSIOStreamGetPosition) (void *context); + +typedef long (*JSIOStreamGetLength) (void *context); + +typedef void (*JSIOStreamClose) (void *context); + +/* The I/O stream handle. */ +struct js_io_stream_st +{ + unsigned char *buffer; /* Must be reallocatable with js_realloc(). */ + unsigned int buflen; + unsigned int data_in_buf; + unsigned int bufpos; + + /* Flags. */ + unsigned int at_eof : 1; + unsigned int autoflush : 1; + unsigned int writep : 1; /* Does the buffer contain write data? */ + + /* The system error code for the last operation that failed. */ + int error; + + /* Only one of the read and write is active. */ + JSIOStreamIOFunc read; + JSIOStreamIOFunc write; + JSIOStreamSeek seek; + JSIOStreamGetPosition get_position; + JSIOStreamGetLength get_length; + + JSIOStreamClose close; + + void *context; +}; + +typedef struct js_io_stream_st JSIOStream; + + +/* The destroy callback for the destroyable heap blocks. */ +typedef void (*JSHeapDestroyableCB) (void *ptr); + +/* + * Each destroyable heap block must be castable to this structure e.g. + * the first item in the block must be pointer to the destroy function. + */ +struct js_heap_destroyable_st +{ + JSHeapDestroyableCB destroy; +}; + +typedef struct js_heap_destroyable_st JSHeapDestroyable; + + +/* Interned symbol. */ +typedef unsigned int JSSymbol; + +/* JavaScript Types. */ + +typedef enum +{ + JS_UNDEFINED = 0, + JS_NULL = 1, + JS_BOOLEAN = 2, + JS_INTEGER = 3, /* Integer, float and nan are `number' */ + JS_STRING = 4, + JS_FLOAT = 5, + JS_ARRAY = 6, + JS_OBJECT = 7, + + /* + * The following ones are the internal types, used by this implementation. + */ + + JS_SYMBOL = 10, + JS_BUILTIN = 11, + JS_FUNC = 12, + JS_NAN = 13, + + JS_IPTR = 14, + JS_ARGS_FIX = 15 +} JSNodeType; + +struct js_node_st; +struct js_vm_st; +struct js_builtin_info_st; + +/* Registry information for builtin objects. */ + +#define JS_PROPERTY_FOUND 1 +#define JS_PROPERTY_UNKNOWN 0 + +typedef void (*JSBuiltinGlobalMethod) (struct js_vm_st *vm, + struct js_builtin_info_st *builtin_info, + void *instance_context, + struct js_node_st *result_return, + struct js_node_st *args); + +/* + * Function to call method from the object. Function must return + * JS_PROPERTY_FOUND if the method was found or JS_PROPERTY_UNKNOWN + * otherwise. + */ +typedef int (*JSBuiltinMethod) (struct js_vm_st *vm, + struct js_builtin_info_st *builtin_info, + void *instance_context, + JSSymbol method, + struct js_node_st *result_return, + struct js_node_st *args); + +/* + * Function to load and set property of object. If + * is true, property should be set to value . Otherwise + * function should return the value of property in . + * Function must return JS_PROPERTY_FOUND if the property was found or + * JS_PROPERTY_UNKNOWN otherwise. + */ +typedef int (*JSBuiltinProperty) (struct js_vm_st *vm, + struct js_builtin_info_st *builtin_info, + void *instance_context, + JSSymbol property, int set, + struct js_node_st *node); + +typedef void (*JSBuiltinNew) (struct js_vm_st *vm, + struct js_builtin_info_st *builtin_info, + struct js_node_st *args, + struct js_node_st *result_return); + +typedef void (*JSBuiltinDelete) (struct js_builtin_info_st *builtin_info, + void *instance_context); + +typedef void (*JSBuiltinMark) (struct js_builtin_info_st *builtin_info, + void *instance_context); + +typedef void (*JSBuiltinObjectCtxDelete) (void *obj_context); + +struct js_builtin_info_st +{ + JSHeapDestroyableCB destroy; + + JSBuiltinGlobalMethod global_method_proc; + JSBuiltinMethod method_proc; + JSBuiltinProperty property_proc; + JSBuiltinNew new_proc; + JSBuiltinDelete delete_proc; + JSBuiltinMark mark_proc; + + void *obj_context; + JSBuiltinObjectCtxDelete obj_context_delete; + + struct js_object_st *prototype; +}; + +typedef struct js_builtin_info_st JSBuiltinInfo; + +/* Builtin object / class. */ +struct js_builtin_st +{ + JSHeapDestroyableCB destroy; + + JSBuiltinInfo *info; + void *instance_context; + + struct js_object_st *prototype; +}; + +typedef struct js_builtin_st JSBuiltin; + +/* String. */ +struct js_string_st +{ + /* Flags. */ + unsigned int staticp : 1; + + unsigned char *data; + unsigned int len; + + struct js_object_st *prototype; +}; + +typedef struct js_string_st JSString; + +/* Array. */ +struct js_array_st +{ + unsigned int length; + struct js_node_st *data; + + struct js_object_st *prototype; +}; + +typedef struct js_array_st JSArray; + +/* Function. */ +struct js_function_st +{ + void *implementation; + struct js_object_st *prototype; +}; + +typedef struct js_function_st JSFunction; + +/* Node. */ +struct js_node_st +{ + JSNodeType type; + + union + { + unsigned int vboolean; + + JSString *vstring; + + long vinteger; + double vfloat; + + struct js_object_st *vobject; + + JSArray *varray; + + /* Internal values. */ + + JSSymbol vsymbol; + + JSBuiltin *vbuiltin; + + JSFunction *vfunction; + + void *iptr; + + struct + { + JSUInt32 argc; + JSUInt32 delta; + } args_fix; + + struct + { + JSUInt32 a; + JSUInt32 b; + } copy; + } u; +}; + +typedef struct js_node_st JSNode; + + +/* Object. */ + +/* Hash node for object's properties. */ +struct js_object_prop_hash_bucket_st +{ + struct js_object_prop_hash_bucket_st *next; + unsigned char *data; + unsigned int len; + unsigned int value; +}; + +typedef struct js_object_prop_hash_bucket_st JSObjectPropHashBucket; + +/* The attribute flags for object's properties. */ +#define JS_ATTRIB_READONLY 1 +#define JS_ATTRIB_DONTENUM 2 +#define JS_ATTRIB_DONTDELETE 4 +#define JS_ATTRIB_Internal 8 + +/* Object's property. */ +struct js_property_st +{ + JSSymbol name; + JSNode value; + unsigned int attributes; +}; + +typedef struct js_property_st JSProperty; + +struct js_object_st +{ + JSObjectPropHashBucket **hash; + unsigned int *hash_lengths; + unsigned int num_props; /* Number of properties in this object. */ + JSProperty *props; +}; + +typedef struct js_object_st JSObject; + + +/* Byte code. */ + +typedef enum +{ + JS_BCST_CODE = 0, + JS_BCST_CONSTANTS = 1, + JS_BCST_SYMTAB = 2, + JS_BCST_DEBUG = 3 +} JSBCSectionType; + +struct js_bc_sect_st +{ + JSBCSectionType type; + unsigned int length; + void *data; /* bytes of data */ +}; + +typedef struct js_bc_sect_st JSBCSect; + +struct js_bc_st +{ + unsigned int num_sects; + JSBCSect *sects; +}; + +typedef struct js_bc_st JSByteCode; + +/* Debug information. */ +#define JS_DI_FILENAME 1 +#define JS_DI_LINENUMBER 2 + +/* Heap block. */ +struct js_heap_block_st +{ + struct js_heap_block_st *next; + unsigned int size; + /* bytes of data follows the structure. */ +}; + +typedef struct js_heap_block_st JSHeapBlock; + +/* Heap memory block. */ + +#define JS_MEM_DEBUG 0 + +/* All allocated blocks have this header. */ +struct js_heap_memory_block_st +{ +#if JS_MEM_DEBUG + JSUIntAlign magic; +#endif + + JSUIntAlign flag_mark : 1; + JSUIntAlign flag_destroyable : 1; + JSUIntAlign size : (sizeof (JSUIntAlign) * 8 - 2); + /* bytes of data follows this header. */ +}; + +typedef struct js_heap_memory_block_st JSHeapMemoryBlock; + +/* + * When the block is on the freelist, it has this header. The first + * sizeof (void *) bytes of the block's data is used to hold the + * freelist next pointer. + */ +struct js_heap_freelist_block_st +{ + JSHeapMemoryBlock block; + JSHeapMemoryBlock *next; +}; + +typedef struct js_heap_freelist_block_st JSHeapFreelistBlock; + + +/* Parsed symbol table entry. */ +struct js_symtab_entry_st +{ + char *name; + unsigned int offset; +}; + +typedef struct js_symtab_entry_st JSSymtabEntry; + + +/* + * Entry points to different byte-code instruction dispatcher functions. + * Each dispatcher must implement these. + */ + +typedef int (*JSVMExecute) (struct js_vm_st *vm, JSByteCode *bc, + JSSymtabEntry *symtab, + unsigned int num_symtab_entries, + unsigned int consts_offset, + unsigned int anonymous_function_offset, + unsigned char *debug_info, + unsigned int debug_info_len, + JSNode *object, JSNode *func, + unsigned int argc, JSNode *argv); + +typedef const char *(*JSVMFuncName) (struct js_vm_st *vm, void *pc); + +typedef const char *(*JSVMDebugPosition) (struct js_vm_st *vm, + unsigned int *linenum_return); + + +/* Virtual Machine. */ + +#define JS_HASH_TABLE_SIZE 256 + +struct js_hash_bucket_st +{ + struct js_hash_bucket_st *next; + char *name; + union + { + void *data; + unsigned int ui; + } u; +}; + +typedef struct js_hash_bucket_st JSHashBucket; + +/* Error handler frame. */ +struct js_error_handler_frame_st +{ + struct js_error_handler_frame_st *next; + jmp_buf error_jmp; + + /* The value thrown by the throw operand. */ + JSNode thrown; + + /* Saved state for the `try_push' operand. */ + JSNode *sp; + JSNode *fp; + void *pc; + JSInt32 pc_delta; +}; + +typedef struct js_error_handler_frame_st JSErrorHandlerFrame; + +struct js_vm_st +{ + /* Options for the virtual machine. */ + unsigned int verbose; /* verbosity has different levels. */ + + unsigned int stacktrace_on_error : 1; + unsigned int verbose_stacktrace : 1; + unsigned int warn_undef : 1; + + /* Security flags. */ + unsigned long security; + + /* The default system streams. */ + JSIOStream *s_stdin; + JSIOStream *s_stdout; + JSIOStream *s_stderr; + + /* The byte-code instruction dispatcher. */ + JSVMDispatchMethod dispatch_method; + const char *dispatch_method_name; + JSVMExecute dispatch_execute; + JSVMFuncName dispatch_func_name; + JSVMDebugPosition dispatch_debug_position; + + /* Constants pool. */ + JSNode *consts; + unsigned int num_consts; + unsigned int consts_alloc; + + /* + * Global symbols (both functions and variables). is + * a name-to-index mapping between symbol names and their positions + * in . + */ + JSHashBucket *globals_hash[JS_HASH_TABLE_SIZE]; + JSNode *globals; + unsigned int num_globals; + unsigned int globals_alloc; + + /* The next anonymous function id. */ + unsigned int anonymous_function_next_id; + + /* Stack. */ + JSNode *stack; + unsigned int stack_size; + JSNode *sp; /* Fuzzy stack pointer. */ + + void *pc; /* Fuzzy program counter. */ + + /* Builtin objects for the primitive datatypes. */ + JSBuiltinInfo *prim[JS_IPTR + 1]; + + /* Some commonly used symbols. */ + struct + { + JSSymbol s___proto__; + JSSymbol s_prototype; + JSSymbol s_toSource; + JSSymbol s_toString; + JSSymbol s_valueOf; + } syms; + + /* Heap. */ + + JSHeapBlock *heap; + JSHeapMemoryBlock *heap_freelists[JS_NUM_HEAP_FREELISTS]; + unsigned long heap_size; + + /* Information for the garbage collector. */ + struct + { + unsigned long trigger; + unsigned long bytes_allocated; + unsigned long bytes_free; + unsigned long count; + } gc; + + /* Error handler frames. */ + JSErrorHandlerFrame *error_handler; + + /* Buffer for the error message. Sorry, we don't support long errors ;-) */ + char error[1024]; + + /* + * The result from the latest evaluation. This is set when the + * js_vm_execute(), js_vm_apply(), or js_vm_call_method() functions + * return to the caller. + */ + JSNode exec_result; + + /* Event callback hook. */ + int (*hook) (int event, void *context); + void *hook_context; + unsigned int hook_operand_count; + unsigned int hook_operand_count_trigger; + + /* How many file descriptors can be allocated. */ + unsigned long fd_count; + +#if PROFILING + + /* Byte-code operand profiling support. */ + + unsigned int prof_count[256]; + unsigned char prof_op; + +#endif /* PROFILING */ +}; + +typedef struct js_vm_st JSVirtualMachine; + +#include "kjs_structs.h" + +/* + * Global variables. + */ + +extern unsigned char js_latin1_tolower[256]; +extern unsigned char js_latin1_toupper[256]; + +/* + * Prototypes for global functions. + */ + +/* + * Memory allocation routines. If the allocation request fails, the + * error recovery is performed according to the argument . If + * is not NULL, an error message is formatted to vm->error and an + * error is raise with js_vm_error(). If the is NULL, the + * functions will return value NULL. It is an error to call these + * functions with a non-NULL that has no error handler + * initialized. + */ + +#ifndef JS_DEBUG_MEMORY_LEAKS +#define JS_DEBUG_MEMORY_LEAKS 0 +#endif /* not JS_DEBUG_MEMORY_LEAKS */ + +#if JS_DEBUG_MEMORY_LEAKS + +#define js_malloc(vm, size) js_malloc_i ((vm), (size), \ + __FILE__, __LINE__) +#define js_calloc(vm, num, size) js_calloc_i ((vm), (num), (size), \ + __FILE__, __LINE__) +#define js_realloc(vm, ptr, size) js_realloc_i ((vm), (ptr), (size), \ + __FILE__, __LINE__) +#define js_strdup(vm, str) js_strdup_i ((vm), (str), \ + __FILE__, __LINE__) + +void *js_malloc_i (JSVirtualMachine *vm, size_t size, char *, int); +void *js_calloc_i (JSVirtualMachine *vm, size_t num, size_t size, char *, int); +void *js_realloc_i (JSVirtualMachine *vm, void *ptr, size_t size, char *, int); +void js_free (void *ptr); +char *js_strdup_i (JSVirtualMachine *vm, const char *str, char *, int); + +#else /* not JS_DEBUG_MEMORY_LEAKS */ + +void *js_malloc (JSVirtualMachine *vm, size_t size); +void *js_calloc (JSVirtualMachine *vm, size_t num, size_t size); +void *js_realloc (JSVirtualMachine *vm, void *ptr, size_t size); +void js_free (void *ptr); +char *js_strdup (JSVirtualMachine *vm, const char *str); + +#endif /* not JS_DEBUG_MEMORY_LEAKS */ + + +/* Byte code. */ + +JSByteCode *js_bc_read_file (FILE *fp); + +JSByteCode *js_bc_read_data (unsigned char *data, unsigned int datalen); + +void js_bc_free (JSByteCode *bc); + + +/* I/O streams. */ + +/* Allocate one I/O stream handle. */ +JSIOStream *js_iostream_new (); + +JSIOStream *js_iostream_file (FILE *fp, int readp, int writep, int do_close); + +JSIOStream *js_iostream_pipe (FILE *fp, int readp); + +size_t js_iostream_read (JSIOStream *stream, void *ptr, size_t size); + +size_t js_iostream_write (JSIOStream *stream, void *ptr, size_t size); + +int js_iostream_flush (JSIOStream *stream); + +int js_iostream_unget (JSIOStream *stream, int byte); + +int js_iostream_close (JSIOStream *stream); + +int js_iostream_seek (JSIOStream *stream, long offset, int whence); + +long js_iostream_get_position (JSIOStream *stream); + +long js_iostream_get_length (JSIOStream *stream); + +void js_iostream_fill_buffer (JSIOStream *stream); + + +/* Virtual machine. */ + +struct _KJS; + +JSVirtualMachine *js_vm_create (struct _KJS *kjs, + unsigned int stack_size, + JSVMDispatchMethod dispatch_method, + unsigned int verbose, int stacktrace_on_error, + JSIOStream *s_stdin, JSIOStream *s_stdout, + JSIOStream *s_stderr); + +void js_vm_destroy (JSVirtualMachine *vm); + +/* + * Execute byte code . Function returns 1 if the operation was + * successful or 0 if any errors were encountered. In case of errors, + * the error message is stored at vm->error. + */ +int js_vm_execute (JSVirtualMachine *vm, JSByteCode *bc); + +/* + * Apply function to arguments . If + * function's name is NULL, then must specify function + * to which arguments are applied. + */ +int js_vm_apply (JSVirtualMachine *vm, char *func_name, JSNode *func, + unsigned int argc, JSNode *argv); + +/* + * Call method from object with arguments . + */ +int js_vm_call_method (JSVirtualMachine *vm, JSNode *object, + const char *method_name, unsigned int argc, + JSNode *argv); + +/* Map program counter to the source file line. */ +const char *js_vm_debug_position (JSVirtualMachine *vm, + unsigned int *linenum_return); + +/* Fetch the function name from the program counter value. */ +const char *js_vm_func_name (JSVirtualMachine *vm, void *pc); + +/* Intern symbol to virtual machine and return its JSSymbol id. */ +JSSymbol js_vm_intern_with_len (JSVirtualMachine *vm, const char *name, + unsigned int len); + +/* Intern symbol to virtual machine and return its JSSymbol id. */ +static inline JSSymbol +js_vm_intern (JSVirtualMachine *vm, const char *name) +{ + return js_vm_intern_with_len (vm, name, strlen (name)); +} + +/* Return the name of symbol . */ +const char *js_vm_symname (JSVirtualMachine *vm, JSSymbol sym); + +/* + * ToPrimitive(). Convert node to its primitive value and return + * the result in . + */ +void js_vm_to_primitive (JSVirtualMachine *vm, const JSNode *n, + JSNode *result_return, JSNodeType preferred_type); + +/* + * ToString(). Convert node to its string presentations and + * return the result in . + */ +void js_vm_to_string (JSVirtualMachine *vm, const JSNode *n, + JSNode *result_return); + +/* + * ToNumber(). Convert node to its number presentations and + * return the result in . + */ +void js_vm_to_number (JSVirtualMachine *vm, const JSNode *n, + JSNode *result_return); + +/* ToObject(). Convert node to object according to its type. */ +void js_vm_to_object (JSVirtualMachine *vm, const JSNode *n, + JSNode *result_return); + +/* + * ToInt32(). Convert node to its signed 32 bit integer + * presentation and return the result. + */ +JSInt32 js_vm_to_int32 (JSVirtualMachine *vm, JSNode *n); + +/* + * ToBoolean(). Convert node to a boolean value and return the + * result. + */ +int js_vm_to_boolean (JSVirtualMachine *vm, JSNode *n); + + +/* + * Raise an error. The error message must have been saved to vm->error + * before this function is called. The function never returns. + */ +void js_vm_error (JSVirtualMachine *vm); + +/* + * Count a hash value for bytes of data . The resulting + * hash value should be re-mapped to the correct range, for example, + * with the mod operand. + */ +static inline unsigned int +js_count_hash (const char *data, unsigned int data_len) +{ + unsigned int val = 0, i; + + for (i = 0; i < data_len; i++) + val = (val << 5) ^ (unsigned char) data[i] + ^ (val >> 16) ^ (val >> 7); + + return val; +} + + +/* Prototypes for the different instruction dispatcher implementations. */ + +#if ALL_DISPATCHERS + +int js_vm_switch0_exec (JSVirtualMachine *vm, JSByteCode *bc, + JSSymtabEntry *symtab, + unsigned int num_symtab_entries, + unsigned int consts_offset, + unsigned int anonymous_function_offset, + unsigned char *debug_info, + unsigned int debug_info_len, + JSNode *object, JSNode *func, + unsigned int argc, JSNode *argv); + +const char *js_vm_switch0_func_name (JSVirtualMachine *vm, void *pc); + +const char *js_vm_switch0_debug_position (JSVirtualMachine *vm, + unsigned int *linenum_return); + +#endif /* ALL_DISPATCHERS */ + +int js_vm_switch_exec (JSVirtualMachine *vm, JSByteCode *bc, + JSSymtabEntry *symtab, + unsigned int num_symtab_entries, + unsigned int consts_offset, + unsigned int anonymous_function_offset, + unsigned char *debug_info, unsigned int debug_info_len, + JSNode *object, JSNode *func, + unsigned int argc, JSNode *argv); + +const char *js_vm_switch_func_name (JSVirtualMachine *vm, void *pc); + +const char *js_vm_switch_debug_position (JSVirtualMachine *vm, + unsigned int *linenum_return); + +int js_vm_jumps_exec (JSVirtualMachine *vm, JSByteCode *bc, + JSSymtabEntry *symtab, + unsigned int num_symtab_entries, + unsigned int consts_offset, + unsigned int anonymous_function_offset, + unsigned char *debug_info, unsigned int debug_info_len, + JSNode *object, JSNode *func, + unsigned int argc, JSNode *argv); + +const char *js_vm_jumps_func_name (JSVirtualMachine *vm, void *pc); + +const char *js_vm_jumps_debug_position (JSVirtualMachine *vm, + unsigned int *linenum_return); + + +/* Heap. */ + +void *js_vm_alloc (JSVirtualMachine *vm, unsigned int size); + +void *js_vm_alloc_destroyable (JSVirtualMachine *vm, unsigned int size); + +void *js_vm_realloc (JSVirtualMachine *vm, void *ptr, unsigned int new_size); + +void js_vm_free (JSVirtualMachine *vm, void *ptr); + +void js_vm_garbage_collect (JSVirtualMachine *vm, JSNode *fp, JSNode *sp); + +void js_vm_clear_heap (JSVirtualMachine *vm); + +void js_vm_mark (JSNode *node); + +int js_vm_mark_ptr (void *ptr); + +int js_vm_is_marked_ptr (void *ptr); + +/* Function. */ + +static inline JSFunction * +js_vm_make_function (JSVirtualMachine *vm, void *implementation) +{ + JSFunction *f = (JSFunction *) js_vm_alloc (vm, sizeof (*f)); + + f->implementation = implementation; + f->prototype = (JSObject *) NULL; + + return f; +} + + +/* Built-in. */ + +/* Create a new built-in info. */ +JSBuiltinInfo *js_vm_builtin_info_create (JSVirtualMachine *vm); + +/* Create a new builtin object with to . */ +void js_vm_builtin_create (JSVirtualMachine *vm, JSNode *result, + JSBuiltinInfo *info, void *instance_context); + +/* Array. */ + +static inline void +js_vm_make_array (JSVirtualMachine *vm, JSNode *n, unsigned int length) +{ + unsigned int i; + + n->type = JS_ARRAY; + n->u.varray = (JSArray *) js_vm_alloc (vm, sizeof (*n->u.varray)); + n->u.varray->prototype = NULL; + n->u.varray->length = length; + n->u.varray->data = (JSNode *) js_vm_alloc (vm, length * sizeof (JSNode)); + + for (i = 0; i < length; i++) + n->u.varray->data[i].type = JS_UNDEFINED; +} + +static inline void +js_vm_expand_array (JSVirtualMachine *vm, JSNode *n, unsigned int length) +{ + if (n->u.varray->length < length) + { + n->u.varray->data = (JSNode *) js_vm_realloc (vm, n->u.varray->data, + length * sizeof (JSNode)); + for (; n->u.varray->length < length; n->u.varray->length++) + n->u.varray->data[n->u.varray->length].type = JS_UNDEFINED; + } +} + +/* File. */ + +/* Enter file to the system. */ +void js_builtin_File_new (JSVirtualMachine *vm, JSNode *result_return, + char *path, JSIOStream *stream, int dont_close); + +/* RegExp. */ + +/* + * Create a new regular expression node from according + * to . The argument defines whether the created + * regexp is immutable. The new regexp is returned in . + * If the is NULL, the function will resolve it. Otherwise the given + * value is used. + */ +void js_builtin_RegExp_new (JSVirtualMachine *vm, char *source, + unsigned int source_len, unsigned int flags, + int immutable, JSBuiltinInfo *info, + JSNode *result_return); + +/* + * Do search-replace for the string by replacing + * matches of with . The resulting string is + * returned in + */ +void js_builtin_RegExp_replace (JSVirtualMachine *vm, char *data, + unsigned int datalen, JSNode *regexp, + char *repl, unsigned int repl_len, + JSNode *result_return); + +/* + * Do regexp match against . Format the result array + * to . + */ +void js_builtin_RegExp_match (JSVirtualMachine *vm, char *data, + unsigned int datalen, JSNode *regexp, + JSNode *result_return); + +/* + * Do regexp search against . Return the start index of + * the match in . + */ +void js_builtin_RegExp_search (JSVirtualMachine *vm, char *data, + unsigned int datalen, JSNode *regexp, + JSNode *result_return); + +/* + * Split the string by regular expression . + * Function returns an array containing the substrings. + */ +void js_builtin_RegExp_split (JSVirtualMachine *vm, char *data, + unsigned int datalen, JSNode *regexp, + unsigned int limit, JSNode *result_return); + +/* Object. */ + +JSObject *js_vm_object_new (JSVirtualMachine *vm); + +void js_vm_object_mark (JSObject *obj); + +int js_vm_object_load_property (JSVirtualMachine *vm, JSObject *obj, + JSSymbol prop, JSNode *value_return); + +void js_vm_object_store_property (JSVirtualMachine *vm, JSObject *obj, + JSSymbol prop, JSNode *value); + +void js_vm_object_delete_property (JSVirtualMachine *vm, JSObject *obj, + JSSymbol prop); + +void js_vm_object_load_array (JSVirtualMachine *vm, JSObject *obj, JSNode *sel, + JSNode *value_return); + +void js_vm_object_store_array (JSVirtualMachine *vm, JSObject *obj, + JSNode *sel, JSNode *value); + +void js_vm_object_delete_array (JSVirtualMachine *vm, JSObject *obj, + JSNode *sel); + +int js_vm_object_nth (JSVirtualMachine *vm, JSObject *obj, int nth, + JSNode *value_return); + + +/* Debug. */ + +void js_vm_stacktrace (JSVirtualMachine *vm, unsigned int num_frames); + + +/* Strings. */ + +static inline void +js_vm_make_string (JSVirtualMachine *vm, JSNode *n, const char *data, + unsigned int data_len) +{ + n->type = JS_STRING; + n->u.vstring = (JSString *) js_vm_alloc (vm, sizeof (*n->u.vstring)); + n->u.vstring->staticp = 0; + n->u.vstring->prototype = NULL; + n->u.vstring->len = data_len; + n->u.vstring->data = (unsigned char *) js_vm_alloc (vm, data_len); + if (data) + memcpy (n->u.vstring->data, data, data_len); + +} + + +static inline void +js_vm_make_static_string (JSVirtualMachine *vm, JSNode *n, const char *data, + unsigned int data_len) +{ + n->type = JS_STRING; + n->u.vstring = (JSString *) js_vm_alloc (vm, sizeof (*n->u.vstring)); + n->u.vstring->staticp = 1; + n->u.vstring->prototype = NULL; + n->u.vstring->len = data_len; + n->u.vstring->data = (unsigned char *) data; +} + + +static inline int +js_compare_strings (JSNode *a, JSNode *b) +{ + unsigned int i; + + for (i = 0; i < a->u.vstring->len && i < b->u.vstring->len; i++) + { + if (a->u.vstring->data[i] < b->u.vstring->data[i]) + return -1; + if (a->u.vstring->data[i] > b->u.vstring->data[i]) + return 1; + } + if (a->u.vstring->len < b->u.vstring->len) + return -1; + if (a->u.vstring->len > b->u.vstring->len) + return 1; + + return 0; +} + + +static inline char * +js_string_to_c_string (JSVirtualMachine *vm, const JSNode *a) +{ + char *cp; + + cp = (char *) js_malloc (vm, a->u.vstring->len + 1); + memcpy (cp, a->u.vstring->data, a->u.vstring->len); + cp[a->u.vstring->len] = '\0'; + + return cp; +} + + +/* Dynamic loading. */ + +/* + * Try to open shared library . If the opening was + * successful, a handle to the library is returned. Otherwise, the + * function returns NULL, and an error message is returned in + * . The argument specifies the + * maximum length of the error message the function should return. + */ +void *js_dl_open (const char *filename, char *error_return, + unsigned int error_return_len); + +/* + * Try to fetch the address of the symbol from shared library + * . + */ +void *js_dl_sym (void *library, char *symbol, char *error_return, + unsigned int error_return_len); + + +/* Misc helper functions. */ + +unsigned long js_crc32 (const unsigned char *s, unsigned int len); + + +/* + * Definitions for the JavaScript part of the JavaScript interp. + */ + +/* Flags for the compiler. See `jsc/entry.js'. */ + +#define JSC_FLAG_VERBOSE 0x00000001 +#define JSC_FLAG_ANNOTATE_ASSEMBLER 0x00000002 +#define JSC_FLAG_GENERATE_DEBUG_INFO 0x00000004 +#define JSC_FLAG_GENERATE_EXECUTABLE_BC_FILES 0x00000008 + +#define JSC_FLAG_OPTIMIZE_PEEPHOLE 0x00000020 +#define JSC_FLAG_OPTIMIZE_JUMPS 0x00000040 +#define JSC_FLAG_OPTIMIZE_BC_SIZE 0x00000080 +#define JSC_FLAG_OPTIMIZE_HEAVY 0x00000100 + +#define JSC_FLAG_OPTIMIZE_MASK 0x0000fff0 + +#define JSC_FLAG_WARN_UNUSED_ARGUMENT 0x00010000 +#define JSC_FLAG_WARN_UNUSED_VARIABLE 0x00020000 +#define JSC_FLAG_WARN_SHADOW 0x00040000 +#define JSC_FLAG_WARN_WITH_CLOBBER 0x00080000 +#define JSC_FLAG_WARN_MISSING_SEMICOLON 0x00100000 +#define JSC_FLAG_WARN_STRICT_ECMA 0x00200000 +#define JSC_FLAG_WARN_DEPRECATED 0x00400000 + +#define JSC_FLAG_WARN_MASK 0xffff0000 + +/* JavaScript interpreter handle. */ +struct js_interp_st +{ + JSInterpOptions options; + JSVirtualMachine *vm; +}; + +/* Declaration for the JS compiler byte-code. */ +extern unsigned char js_compiler_bytecode[]; +extern unsigned int js_compiler_bytecode_len; + +#ifdef __cplusplus +} +#endif + +#endif /* not JSINT_H */ diff --git a/reactos/lib/kjs/include/kjs.h b/reactos/lib/kjs/include/kjs.h new file mode 100644 index 00000000000..1d34a4ca3a9 --- /dev/null +++ b/reactos/lib/kjs/include/kjs.h @@ -0,0 +1,24 @@ +#ifndef KJS_H +#define KJS_H + +#include "jsint.h" +#include "js.h" +#include "kjs_structs.h" + +typedef struct system_ctx_st SystemCtx; + +typedef struct _KJS { + JSInterpPtr interp; + JSVirtualMachine *vm; + SystemCtx *ctx; +} KJS, *PKJS; + +extern PKJS kjs_create_interp( VOID *Reserved ); +extern VOID kjs_destroy_interp( PKJS kjs ); +extern VOID kjs_eval( PKJS js_interp, PCHAR commands ); +extern VOID kjs_system_register( PKJS js_interp, PCHAR method, PVOID context, + PKJS_METHOD function ); +extern VOID kjs_system_unregister( PKJS js_interp, PVOID context, + PKJS_METHOD function ); + +#endif/*KJS_H*/ diff --git a/reactos/lib/kjs/include/kjs_structs.h b/reactos/lib/kjs/include/kjs_structs.h new file mode 100644 index 00000000000..4b30499ac41 --- /dev/null +++ b/reactos/lib/kjs/include/kjs_structs.h @@ -0,0 +1,44 @@ +#ifndef KJS_STRUCTS_H +#define KJS_STRUCTS_H + +struct _KJS; +struct js_node_st; + +typedef int (*PKJS_METHOD)( void *context, + struct js_node_st *js_node, struct js_node_st *result ); + +typedef struct _JSSymbolList { + JSSymbol symbol; + PKJS_METHOD registered_function; + struct _JSSymbolList *next; + PVOID context; +} JSSymbolList; + +struct system_ctx_st +{ + JSSymbol s_print; + JSSymbol s_mread; + JSSymbol s_mwrite; + JSSymbol s_reg; + JSSymbol s_regdir; + + JSSymbolList *registered_symbols; + + JSSymbol s_bits; + JSSymbol s_canonicalHost; + JSSymbol s_canonicalHostCPU; + JSSymbol s_canonicalHostVendor; + JSSymbol s_canonicalHostOS; + JSSymbol s_errno; + JSSymbol s_lineBreakSequence; + JSSymbol s_stderr; + JSSymbol s_stdin; + JSSymbol s_stdout; + + /* System file handles. */ + JSNode pstderr; + JSNode pstdin; + JSNode pstdout; +}; + +#endif/*KJS_STRUCTS_H*/ diff --git a/reactos/lib/kjs/jsas/ChangeLog b/reactos/lib/kjs/jsas/ChangeLog new file mode 100644 index 00000000000..0e61943fdef --- /dev/null +++ b/reactos/lib/kjs/jsas/ChangeLog @@ -0,0 +1,35 @@ +1998-12-17 Markku Rossi + + * process.js (process_file): Added support for integer constants. + (const_string): Fixed a typo from the backslash handing. + +1998-10-28 Markku Rossi + + * process.js (process_file): Use the operand flags instead of + using the hardcoded operand names. + + * extract-operands.js (main): Fixed to obey the flag comments of + the operands.def file. + +1998-10-14 Markku Rossi + + * main.js (main): Fixed to create the output file name from the + input file names. + + * process.js (process_file): Initial support for string + constants. + + * main.js: Implemented -g, -O, and -v options. + +1998-10-13 Markku Rossi + + * extract-operands.js: Extract byte-code operand information from + the `src/operands.def' file, and create the operands.js file. + +1998-10-12 Markku Rossi + + * process.js: New file to handle the assembler file processing. + +1998-06-25 Markku Rossi + + * Created the assembler project. diff --git a/reactos/lib/kjs/jsas/Makefile b/reactos/lib/kjs/jsas/Makefile new file mode 100644 index 00000000000..93f2da3a6f2 --- /dev/null +++ b/reactos/lib/kjs/jsas/Makefile @@ -0,0 +1,244 @@ +# Generated automatically from Makefile.in by configure. +# Makefile.in generated automatically by automake 1.3 from Makefile.am + +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Automakefile for JavaScript assembler. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + + +SHELL = /bin/sh + +srcdir = . +top_srcdir = .. +prefix = /usr/local/js-0.2.5 +exec_prefix = ${prefix} + +bindir = ${exec_prefix}/bin +sbindir = ${exec_prefix}/sbin +libexecdir = ${exec_prefix}/libexec +datadir = ${prefix}/share +sysconfdir = ${prefix}/etc +sharedstatedir = ${prefix}/com +localstatedir = ${prefix}/var +libdir = ${exec_prefix}/lib +infodir = ${prefix}/info +mandir = ${prefix}/man +includedir = ${prefix}/include +oldincludedir = /usr/include + +DISTDIR = + +pkgdatadir = $(datadir)/js +pkglibdir = $(libdir)/js +pkgincludedir = $(includedir)/js + +top_builddir = .. + +ACLOCAL = aclocal +AUTOCONF = autoconf +AUTOMAKE = automake +AUTOHEADER = autoheader + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} +transform = s,x,x, + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = i686-pc-linux-gnu +host_triplet = i686-pc-linux-gnu +ACLOCAL_FLAGS_FOR_LIBTOOL = +CC = gcc +CPP = gcc -E +EXTENSIONS = dl_open.lo xjs.lo xmd5.lo md5c.lo +EXTENSIONS_LIBS = -ldl +INTERPRETER_FEATURES = r_std.lo +LD = /usr/bin/ld +LIBTOOL = $(SHELL) $(top_builddir)/libtool +LN_S = ln -s +MAKEINFO = makeinfo +NM = /usr/bin/nm -B +PACKAGE = js +PGCC_BY_PROVENZANO = +RANLIB = ranlib +U = +VERSION = 0.2.5 +XLC_R_AIX = + +JSCOMPILER = ../src/js +JSCOMPILER_FLAGS = -g -Wpedantic -O2 + +JSS = process.js operands.js main.js +JSCS = process.jsc operands.jsc main.jsc + +EXTRA_DIST = $(JSS) + +bin_SCRIPTS = jsas + +CLEANFILES = jsas $(JSCS) + +SUFFIXES = .jsc .js +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../jsconfig.h +CONFIG_CLEAN_FILES = +SCRIPTS = $(bin_SCRIPTS) + +DIST_COMMON = ChangeLog Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP = --best +all: Makefile $(SCRIPTS) + +.SUFFIXES: +.SUFFIXES: .js .jsc +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps jsas/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +install-binSCRIPTS: $(bin_SCRIPTS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_SCRIPTS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ + $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + else if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ + $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + else :; fi; fi; \ + done + +uninstall-binSCRIPTS: + @$(NORMAL_UNINSTALL) + list='$(bin_SCRIPTS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + done +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = jsas + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done +info: +dvi: +check: all + $(MAKE) +installcheck: +install-exec: install-binSCRIPTS + @$(NORMAL_INSTALL) + +install-data: + @$(NORMAL_INSTALL) + +install: install-exec install-data all + @: + +uninstall: uninstall-binSCRIPTS + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: + $(mkinstalldirs) $(DATADIR)$(bindir) + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean: mostlyclean-generic + +clean: clean-generic mostlyclean + +distclean: distclean-generic clean + -rm -f config.status + -rm -f libtool + +maintainer-clean: maintainer-clean-generic distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +.PHONY: uninstall-binSCRIPTS install-binSCRIPTS tags distdir info dvi \ +installcheck install-exec install-data install uninstall all \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +compile: $(JSCS) + +jsas: $(JSS) + rm -f $@.js + for i in $(JSS); do cat $(srcdir)/$$i >> $@.js; done + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -c $@.js + echo "#!$(bindir)/js --file" > $@ +# echo "#!$(JSCOMPILER) --file" > $@ + cat $@.jsc >> $@ + chmod a+x $@ + +.js.jsc: + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -c $< + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/reactos/lib/kjs/jsas/Makefile.am b/reactos/lib/kjs/jsas/Makefile.am new file mode 100644 index 00000000000..8b41aa0c32a --- /dev/null +++ b/reactos/lib/kjs/jsas/Makefile.am @@ -0,0 +1,51 @@ +# +# Automakefile for JavaScript assembler. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + +JSCOMPILER = ../src/js +JSCOMPILER_FLAGS = -g -Wpedantic -O2 + +JSS = process.js operands.js main.js +JSCS = process.jsc operands.jsc main.jsc + +EXTRA_DIST = $(JSS) + +bin_SCRIPTS = jsas + +compile: $(JSCS) + +jsas: $(JSS) + rm -f $@.js + for i in $(JSS); do cat $(srcdir)/$$i >> $@.js; done + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -c $@.js + echo "#!$(bindir)/js --file" > $@ +# echo "#!$(JSCOMPILER) --file" > $@ + cat $@.jsc >> $@ + chmod a+x $@ + +CLEANFILES = jsas $(JSCS) + +SUFFIXES = .jsc .js + +.js.jsc: + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -c $< diff --git a/reactos/lib/kjs/jsas/Makefile.in b/reactos/lib/kjs/jsas/Makefile.in new file mode 100644 index 00000000000..4237de83233 --- /dev/null +++ b/reactos/lib/kjs/jsas/Makefile.in @@ -0,0 +1,244 @@ +# Makefile.in generated automatically by automake 1.3 from Makefile.am + +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Automakefile for JavaScript assembler. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + + +SHELL = /bin/sh + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DISTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_FLAGS_FOR_LIBTOOL = @ACLOCAL_FLAGS_FOR_LIBTOOL@ +CC = @CC@ +CPP = @CPP@ +EXTENSIONS = @EXTENSIONS@ +EXTENSIONS_LIBS = @EXTENSIONS_LIBS@ +INTERPRETER_FEATURES = @INTERPRETER_FEATURES@ +LD = @LD@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +NM = @NM@ +PACKAGE = @PACKAGE@ +PGCC_BY_PROVENZANO = @PGCC_BY_PROVENZANO@ +RANLIB = @RANLIB@ +U = @U@ +VERSION = @VERSION@ +XLC_R_AIX = @XLC_R_AIX@ + +JSCOMPILER = ../src/js +JSCOMPILER_FLAGS = -g -Wpedantic -O2 + +JSS = process.js operands.js main.js +JSCS = process.jsc operands.jsc main.jsc + +EXTRA_DIST = $(JSS) + +bin_SCRIPTS = jsas + +CLEANFILES = jsas $(JSCS) + +SUFFIXES = .jsc .js +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../jsconfig.h +CONFIG_CLEAN_FILES = +SCRIPTS = $(bin_SCRIPTS) + +DIST_COMMON = ChangeLog Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP = --best +all: Makefile $(SCRIPTS) + +.SUFFIXES: +.SUFFIXES: .js .jsc +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps jsas/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +install-binSCRIPTS: $(bin_SCRIPTS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_SCRIPTS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ + $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + else if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ + $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + else :; fi; fi; \ + done + +uninstall-binSCRIPTS: + @$(NORMAL_UNINSTALL) + list='$(bin_SCRIPTS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + done +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = jsas + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done +info: +dvi: +check: all + $(MAKE) +installcheck: +install-exec: install-binSCRIPTS + @$(NORMAL_INSTALL) + +install-data: + @$(NORMAL_INSTALL) + +install: install-exec install-data all + @: + +uninstall: uninstall-binSCRIPTS + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: + $(mkinstalldirs) $(DATADIR)$(bindir) + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean: mostlyclean-generic + +clean: clean-generic mostlyclean + +distclean: distclean-generic clean + -rm -f config.status + -rm -f libtool + +maintainer-clean: maintainer-clean-generic distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +.PHONY: uninstall-binSCRIPTS install-binSCRIPTS tags distdir info dvi \ +installcheck install-exec install-data install uninstall all \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +compile: $(JSCS) + +jsas: $(JSS) + rm -f $@.js + for i in $(JSS); do cat $(srcdir)/$$i >> $@.js; done + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -c $@.js + echo "#!$(bindir)/js --file" > $@ +# echo "#!$(JSCOMPILER) --file" > $@ + cat $@.jsc >> $@ + chmod a+x $@ + +.js.jsc: + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -c $< + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/reactos/lib/kjs/jsas/jsas.js b/reactos/lib/kjs/jsas/jsas.js new file mode 100644 index 00000000000..12972e49559 --- /dev/null +++ b/reactos/lib/kjs/jsas/jsas.js @@ -0,0 +1,980 @@ +/* + * Process assembler file. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsas/jsas.js,v $ + * $Id: jsas.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +function process_file (name) +{ + var fp = new File (name); + var labels = new Object (); + var label_waits = new Object (); + var op; + + if (fp.open ("r")) + { + var linenum = 0; + + while (!fp.eof ()) + { + var line = fp.readln (); + linenum++; + + /* Remove comments. */ + line = line.replace (/;.*$/, ""); + + /* Extract the labels and symbols. */ + if (/^([^ \t\n]+):(.*)$/.exec (line)) + { + var label = RegExp.$1; + line = RegExp.$2; + + if (/^\.[^ ]+$/.test (label) && label != ".global") + { + /* It is a label. */ + if (labels[label]) + { + System.stderr.writeln (name + ":" + linenum.toString () + + ": label `" + label + + "' is already defined"); + System.stderr.writeln (name + ":" + + (labels[label].linenum + .toString ()) + + ": this is the place of the " + + "previous definition"); + System.exit (1); + } + labels[label] = new JSC$ASM_label (); + labels[label].linenum = linenum; + labels[label].link (); + } + else + { + /* It is a symbol. */ + new JSC$ASM_symbol (linenum, label).link (); + } + } + + /* Skip empty lines. */ + if (/^[ \n\t]*$/.test (line)) + continue; + + if (!/^[ \n\t]*([^ \n\t]+)[ \n\t]*(.*)[ \n\t]*$/.exec (line)) + { + System.stderr.writeln (name + ":" + linenum.toString () + + ": syntax error"); + System.exit (1); + } + var operand = RegExp.$1; + var argument = RegExp.$2; + + /* Check that this is a known operand. */ + if (typeof argument_sizes[operand] == "undefined") + { + System.stderr.writeln (name + ":" + linenum.toString () + + ": unknown operand `" + operand + + "'"); + System.exit (1); + } + + if ((operand_flags[operand] & 0x02) != 0) + { + /* The branch operands. */ + if (argument.length == 0) + { + System.stderr.writeln (name + ":" + linenum.toString () + + ": branch operand requires a " + + " label argument"); + System.exit (1); + } + if (!label_waits[argument]) + label_waits[argument] = new Array (); + + op = give_operand (operand, linenum); + label_waits[argument].push (op); + op.link (); + } + else if ((operand_flags[operand] & 0x01) != 0) + { + /* The symbol operands. */ + if (!/^[A-Za-z_$][A-Za-z_$0-9]*$/.test (argument)) + { + System.stderr.writeln (name + ":" + linenum.toString () + + ": operand `" + operand + + "' requires a symbol argument"); + System.exit (1); + } + op = give_operand (operand, linenum); + op.link (); + op.value = argument; + } + else if (operand == "const") + { + var value; + + if (/^\"(.*)\"$/.test (argument)) + value = const_string (RegExp.$1); + else if (/^[0-9]+$/.test (argument)) + value = parseInt(argument); + else + { + System.stderr.writeln (name + ":" + linenum.toString () + + ": malformed argument `" + + argument + "' for operand `" + + operand + "'"); + System.exit (1); + } + + op = give_operand (operand, linenum); + op.link (); + op.value = value; + } + else + { + if (argument_sizes[operand] == 0) + { + /* Simple operands without arugments. */ + if (argument.length != 0) + { + System.stderr.writeln (name + ":" + linenum.toString () + + ": operand `" + operand + + "' doesn't take argument"); + System.exit (1); + } + give_operand (operand, linenum).link (); + } + else + { + /* Simple operands with integer arguments. */ + if (!/^[-+]?[0-9]+$/.test (argument)) + { + System.stderr.writeln (name + ":" + linenum.toString () + + ": operand `" + operand + + "' requires an integer " + + "argument"); + System.exit (1); + } + op = give_operand (operand, linenum); + op.link (); + op.value = parseInt (argument); + } + } + } + fp.close (); + + /* Patch labels to branch operands. */ + for (var label in label_waits) + for (op in label_waits[label]) + { + if (!labels[label]) + { + System.stderr.writeln (name + ":" + op.linenum.toString () + + ": undefined label `" + label + "'"); + System.exit (1); + } + op.value = labels[label]; + } + } + else + { + System.stderr.writeln (program + ": couldn't open input file `" + + name + "': " + System.strerror (System.errno)); + System.exit (1); + } +} + + +function const_string (source) +{ + var str = new String (""); + var i; + + for (i = 0; i < source.length; i++) + { + switch (source[i]) + { + case #'\\': + if (i + 1 > source.length) + str.append ("\\"); + else + { + i++; + var ch; + + switch (source[i]) + { + case #'n': + ch = "\n"; + break; + + case #'t': + ch = "\t"; + break; + + case #'v': + ch = "\v"; + break; + + case #'b': + ch = "\b"; + break; + + case #'r': + ch = "\r"; + break; + + case #'f': + ch = "\f"; + break; + + case #'a': + ch = "\a"; + break; + + case #'\\': + ch = "\\"; + break; + + case #'?': + ch = "?"; + break; + + case #'\'': + ch = "'"; + break; + + case #'"': + ch = "\""; + break; + + default: + ch = File.byteToString (source[i]); + break; + } + + str.append (ch); + } + break; + + default: + str.append (File.byteToString (source[i])); + break; + } + } + + return str; +} + + +/* +Local variables: +mode: c +End: +*/ +/* -*- c -*- + * Operand definitions for the JavaScript byte-code. + * + * This file is automatically create from the operands.def file. + * Editing is strongly discouraged. You should edit the file + * `extract-operands.js' instead. + */ + +argument_sizes = new Object (); +operand_flags = new Object (); + +function give_operand (name, ln) +{ + switch (name) + { + case "halt": + return new JSC$ASM_halt (ln); + break; + + case "done": + return new JSC$ASM_done (ln); + break; + + case "nop": + return new JSC$ASM_nop (ln); + break; + + case "dup": + return new JSC$ASM_dup (ln); + break; + + case "pop": + return new JSC$ASM_pop (ln); + break; + + case "pop_n": + return new JSC$ASM_pop_n (ln); + break; + + case "apop": + return new JSC$ASM_apop (ln); + break; + + case "swap": + return new JSC$ASM_swap (ln); + break; + + case "roll": + return new JSC$ASM_roll (ln); + break; + + case "const": + return new JSC$ASM_const (ln); + break; + + case "const_null": + return new JSC$ASM_const_null (ln); + break; + + case "const_true": + return new JSC$ASM_const_true (ln); + break; + + case "const_false": + return new JSC$ASM_const_false (ln); + break; + + case "const_undefined": + return new JSC$ASM_const_undefined (ln); + break; + + case "const_i0": + return new JSC$ASM_const_i0 (ln); + break; + + case "const_i1": + return new JSC$ASM_const_i1 (ln); + break; + + case "const_i2": + return new JSC$ASM_const_i2 (ln); + break; + + case "const_i3": + return new JSC$ASM_const_i3 (ln); + break; + + case "const_i": + return new JSC$ASM_const_i (ln); + break; + + case "load_global": + return new JSC$ASM_load_global (ln); + break; + + case "store_global": + return new JSC$ASM_store_global (ln); + break; + + case "load_arg": + return new JSC$ASM_load_arg (ln); + break; + + case "store_arg": + return new JSC$ASM_store_arg (ln); + break; + + case "load_local": + return new JSC$ASM_load_local (ln); + break; + + case "store_local": + return new JSC$ASM_store_local (ln); + break; + + case "load_property": + return new JSC$ASM_load_property (ln); + break; + + case "store_property": + return new JSC$ASM_store_property (ln); + break; + + case "load_array": + return new JSC$ASM_load_array (ln); + break; + + case "store_array": + return new JSC$ASM_store_array (ln); + break; + + case "nth": + return new JSC$ASM_nth (ln); + break; + + case "cmp_eq": + return new JSC$ASM_cmp_eq (ln); + break; + + case "cmp_ne": + return new JSC$ASM_cmp_ne (ln); + break; + + case "cmp_lt": + return new JSC$ASM_cmp_lt (ln); + break; + + case "cmp_gt": + return new JSC$ASM_cmp_gt (ln); + break; + + case "cmp_le": + return new JSC$ASM_cmp_le (ln); + break; + + case "cmp_ge": + return new JSC$ASM_cmp_ge (ln); + break; + + case "cmp_seq": + return new JSC$ASM_cmp_seq (ln); + break; + + case "cmp_sne": + return new JSC$ASM_cmp_sne (ln); + break; + + case "sub": + return new JSC$ASM_sub (ln); + break; + + case "add": + return new JSC$ASM_add (ln); + break; + + case "mul": + return new JSC$ASM_mul (ln); + break; + + case "div": + return new JSC$ASM_div (ln); + break; + + case "mod": + return new JSC$ASM_mod (ln); + break; + + case "neg": + return new JSC$ASM_neg (ln); + break; + + case "and": + return new JSC$ASM_and (ln); + break; + + case "not": + return new JSC$ASM_not (ln); + break; + + case "or": + return new JSC$ASM_or (ln); + break; + + case "xor": + return new JSC$ASM_xor (ln); + break; + + case "shift_left": + return new JSC$ASM_shift_left (ln); + break; + + case "shift_right": + return new JSC$ASM_shift_right (ln); + break; + + case "shift_rright": + return new JSC$ASM_shift_rright (ln); + break; + + case "iffalse": + return new JSC$ASM_iffalse (ln); + break; + + case "iftrue": + return new JSC$ASM_iftrue (ln); + break; + + case "call_method": + return new JSC$ASM_call_method (ln); + break; + + case "jmp": + return new JSC$ASM_jmp (ln); + break; + + case "jsr": + return new JSC$ASM_jsr (ln); + break; + + case "return": + return new JSC$ASM_return (ln); + break; + + case "typeof": + return new JSC$ASM_typeof (ln); + break; + + case "new": + return new JSC$ASM_new (ln); + break; + + case "delete_property": + return new JSC$ASM_delete_property (ln); + break; + + case "delete_array": + return new JSC$ASM_delete_array (ln); + break; + + case "locals": + return new JSC$ASM_locals (ln); + break; + + case "min_args": + return new JSC$ASM_min_args (ln); + break; + + case "load_nth_arg": + return new JSC$ASM_load_nth_arg (ln); + break; + + case "with_push": + return new JSC$ASM_with_push (ln); + break; + + case "with_pop": + return new JSC$ASM_with_pop (ln); + break; + + case "try_push": + return new JSC$ASM_try_push (ln); + break; + + case "try_pop": + return new JSC$ASM_try_pop (ln); + break; + + case "throw": + return new JSC$ASM_throw (ln); + break; + + case "iffalse_b": + return new JSC$ASM_iffalse_b (ln); + break; + + case "iftrue_b": + return new JSC$ASM_iftrue_b (ln); + break; + + case "add_1_i": + return new JSC$ASM_add_1_i (ln); + break; + + case "add_2_i": + return new JSC$ASM_add_2_i (ln); + break; + + case "load_global_w": + return new JSC$ASM_load_global_w (ln); + break; + + case "jsr_w": + return new JSC$ASM_jsr_w (ln); + break; + + default: + System.stderr.writeln (program + ":" + ln.toString () + + ": unknown operand `" + name + "'"); + break; + } +} + +argument_sizes["halt"] = 0; +operand_flags["halt"] = 0x0; +argument_sizes["done"] = 0; +operand_flags["done"] = 0x0; +argument_sizes["nop"] = 0; +operand_flags["nop"] = 0x0; +argument_sizes["dup"] = 0; +operand_flags["dup"] = 0x0; +argument_sizes["pop"] = 0; +operand_flags["pop"] = 0x0; +argument_sizes["pop_n"] = 1; +operand_flags["pop_n"] = 0x0; +argument_sizes["apop"] = 1; +operand_flags["apop"] = 0x0; +argument_sizes["swap"] = 0; +operand_flags["swap"] = 0x0; +argument_sizes["roll"] = 1; +operand_flags["roll"] = 0x0; +argument_sizes["const"] = 4; +operand_flags["const"] = 0x0; +argument_sizes["const_null"] = 0; +operand_flags["const_null"] = 0x0; +argument_sizes["const_true"] = 0; +operand_flags["const_true"] = 0x0; +argument_sizes["const_false"] = 0; +operand_flags["const_false"] = 0x0; +argument_sizes["const_undefined"] = 0; +operand_flags["const_undefined"] = 0x0; +argument_sizes["const_i0"] = 0; +operand_flags["const_i0"] = 0x0; +argument_sizes["const_i1"] = 0; +operand_flags["const_i1"] = 0x0; +argument_sizes["const_i2"] = 0; +operand_flags["const_i2"] = 0x0; +argument_sizes["const_i3"] = 0; +operand_flags["const_i3"] = 0x0; +argument_sizes["const_i"] = 4; +operand_flags["const_i"] = 0x0; +argument_sizes["load_global"] = 4; +operand_flags["load_global"] = 0x1; +argument_sizes["store_global"] = 4; +operand_flags["store_global"] = 0x1; +argument_sizes["load_arg"] = 1; +operand_flags["load_arg"] = 0x0; +argument_sizes["store_arg"] = 1; +operand_flags["store_arg"] = 0x0; +argument_sizes["load_local"] = 2; +operand_flags["load_local"] = 0x0; +argument_sizes["store_local"] = 2; +operand_flags["store_local"] = 0x0; +argument_sizes["load_property"] = 4; +operand_flags["load_property"] = 0x1; +argument_sizes["store_property"] = 4; +operand_flags["store_property"] = 0x1; +argument_sizes["load_array"] = 0; +operand_flags["load_array"] = 0x0; +argument_sizes["store_array"] = 0; +operand_flags["store_array"] = 0x0; +argument_sizes["nth"] = 0; +operand_flags["nth"] = 0x0; +argument_sizes["cmp_eq"] = 0; +operand_flags["cmp_eq"] = 0x0; +argument_sizes["cmp_ne"] = 0; +operand_flags["cmp_ne"] = 0x0; +argument_sizes["cmp_lt"] = 0; +operand_flags["cmp_lt"] = 0x0; +argument_sizes["cmp_gt"] = 0; +operand_flags["cmp_gt"] = 0x0; +argument_sizes["cmp_le"] = 0; +operand_flags["cmp_le"] = 0x0; +argument_sizes["cmp_ge"] = 0; +operand_flags["cmp_ge"] = 0x0; +argument_sizes["cmp_seq"] = 0; +operand_flags["cmp_seq"] = 0x0; +argument_sizes["cmp_sne"] = 0; +operand_flags["cmp_sne"] = 0x0; +argument_sizes["sub"] = 0; +operand_flags["sub"] = 0x0; +argument_sizes["add"] = 0; +operand_flags["add"] = 0x0; +argument_sizes["mul"] = 0; +operand_flags["mul"] = 0x0; +argument_sizes["div"] = 0; +operand_flags["div"] = 0x0; +argument_sizes["mod"] = 0; +operand_flags["mod"] = 0x0; +argument_sizes["neg"] = 0; +operand_flags["neg"] = 0x0; +argument_sizes["and"] = 0; +operand_flags["and"] = 0x0; +argument_sizes["not"] = 0; +operand_flags["not"] = 0x0; +argument_sizes["or"] = 0; +operand_flags["or"] = 0x0; +argument_sizes["xor"] = 0; +operand_flags["xor"] = 0x0; +argument_sizes["shift_left"] = 0; +operand_flags["shift_left"] = 0x0; +argument_sizes["shift_right"] = 0; +operand_flags["shift_right"] = 0x0; +argument_sizes["shift_rright"] = 0; +operand_flags["shift_rright"] = 0x0; +argument_sizes["iffalse"] = 4; +operand_flags["iffalse"] = 0x2; +argument_sizes["iftrue"] = 4; +operand_flags["iftrue"] = 0x2; +argument_sizes["call_method"] = 4; +operand_flags["call_method"] = 0x1; +argument_sizes["jmp"] = 4; +operand_flags["jmp"] = 0x2; +argument_sizes["jsr"] = 0; +operand_flags["jsr"] = 0x0; +argument_sizes["return"] = 0; +operand_flags["return"] = 0x0; +argument_sizes["typeof"] = 0; +operand_flags["typeof"] = 0x0; +argument_sizes["new"] = 0; +operand_flags["new"] = 0x0; +argument_sizes["delete_property"] = 4; +operand_flags["delete_property"] = 0x1; +argument_sizes["delete_array"] = 0; +operand_flags["delete_array"] = 0x0; +argument_sizes["locals"] = 2; +operand_flags["locals"] = 0x0; +argument_sizes["min_args"] = 1; +operand_flags["min_args"] = 0x0; +argument_sizes["load_nth_arg"] = 0; +operand_flags["load_nth_arg"] = 0x0; +argument_sizes["with_push"] = 0; +operand_flags["with_push"] = 0x0; +argument_sizes["with_pop"] = 1; +operand_flags["with_pop"] = 0x0; +argument_sizes["try_push"] = 4; +operand_flags["try_push"] = 0x2; +argument_sizes["try_pop"] = 1; +operand_flags["try_pop"] = 0x0; +argument_sizes["throw"] = 0; +operand_flags["throw"] = 0x0; +argument_sizes["iffalse_b"] = 4; +operand_flags["iffalse_b"] = 0x2; +argument_sizes["iftrue_b"] = 4; +operand_flags["iftrue_b"] = 0x2; +argument_sizes["add_1_i"] = 0; +operand_flags["add_1_i"] = 0x0; +argument_sizes["add_2_i"] = 0; +operand_flags["add_2_i"] = 0x0; +argument_sizes["load_global_w"] = 4; +operand_flags["load_global_w"] = 0x1; +argument_sizes["jsr_w"] = 4; +operand_flags["jsr_w"] = 0x1; +/* + * Assembler for JavaScript assembler. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsas/jsas.js,v $ + * $Id: jsas.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * Variables and definitions. + */ + +version_number = "0.0.1"; + +/* + * Options. + */ + +/* + * -g, --debug + * + * Generate debugging information. + */ + +opt_debug = false; + +/* + * -h, --help + * + * Print short help and exit successfully. + */ + +/* + * -O, --optimize + * + * Optimize the assembler. + */ + +opt_optimize = false; + +/* + * -v, --verbose + * + * Tell what we are doing. + */ + +opt_verbose = false; + +/* + * -V, --version + * + * Print version information and exit successfully. + */ + +/* + * Functions. + */ + +function main () +{ + var idx = ARGS[0].lastIndexOf ("/"); + if (idx >= 0) + program = ARGS[0].substr (idx + 1); + else + program = ARGS[0]; + + /* Handle arguments. */ + var i; + for (i = 1; i < ARGS.length; i++) + { + if (ARGS[i][0] == #'-') + { + if (ARGS[i] == "-g" || ARGS[i] == "--debug") + opt_debug = true; + else if (ARGS[i] == "-h" || ARGS[i] == "--help") + { + usage (); + System.exit (1); + } + else if (ARGS[i] == "-O" || ARGS[i] == "--optimize") + opt_optimize = true; + else if (ARGS[i] == "-v" || ARGS[i] == "--verbose") + opt_verbose = true; + else if (ARGS[i] == "-V" || ARGS[i] == "--version") + { + version (); + System.exit (0); + } + else + { + /* Unrecognized option. */ + System.error (program, ": unrecognized option `", + ARGS[i], "'\n"); + System.error ("Try `", program, + " --help' for more information.\n"); + System.exit (1); + } + } + else + { + /* End of arguments. */ + break; + } + } + + if (i >= ARGS.length) + { + System.error (program, ": no files specified\n"); + System.exit (1); + } + + /* Options. */ + + JSC$verbose = opt_verbose; + JSC$generate_debug_info = opt_debug; + + /* Process files. */ + for (; i < ARGS.length; i++) + { + /* Reset the JSC's assembler package. */ + JSC$asm_reset (); + + /* Process the input file. */ + JSC$filename = ARGS[i]; + process_file (JSC$filename); + + if (opt_optimize) + JSC$asm_optimize (JSC$FLAG_OPTIMIZE_MASK); + + JSC$asm_finalize (); + + var result = JSC$asm_bytecode (); + + /* Create the output file name. */ + var oname = ARGS[i].replace (/\.jas$/, ".jsc"); + if (oname == ARGS[i]) + oname += ".jsc"; + + var ostream = new File (oname); + if (ostream.open ("w")) + { + ostream.write (result); + ostream.close (); + } + else + { + System.stderr.writeln ("jsas: couldn't create bc file `" + + oname + "': " + + System.strerror (System.errno)); + System.exit (1); + } + } +} + +function usage () +{ + System.print ("\ +Usage: ", program, " [OPTION]... FILE...\n\ +Mandatory arguments to long options are mandatory for short options too.\n"); + + System.print ("\ + -g, --debug generate debugging information\n\ + -h, --help print this help and exit\n\ + -O, --optimize optimize the assembler code\n\ + -v, --verbose tell what the assembler is doing\n\ + -V, --version print version number\n\ +"); + + System.print ("\nReport bugs to mtr@ngs.fi.\n"); +} + +function version () +{ + System.print ("NGS JavaScript assembler ", version_number, "\n"); + System.print ("\ +Copyright (C) 1998 New Generation Software (NGS) Oy.\n\ +NGS JavaScript Interpreter comes with NO WARRANTY, to the extent\n\ +permitted by law. You may redistribute copies of NGS JavaScript\n\ +Interpreter under the terms of the GNU Library General Public License.\n\ +For more information about these matters, see the files named COPYING.\n\ +"); +} + +main (); + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/jsas/main.js b/reactos/lib/kjs/jsas/main.js new file mode 100644 index 00000000000..649d23ccee6 --- /dev/null +++ b/reactos/lib/kjs/jsas/main.js @@ -0,0 +1,212 @@ +/* + * Assembler for JavaScript assembler. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsas/main.js,v $ + * $Id: main.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * Variables and definitions. + */ + +version_number = "0.0.1"; + +/* + * Options. + */ + +/* + * -g, --debug + * + * Generate debugging information. + */ + +opt_debug = false; + +/* + * -h, --help + * + * Print short help and exit successfully. + */ + +/* + * -O, --optimize + * + * Optimize the assembler. + */ + +opt_optimize = false; + +/* + * -v, --verbose + * + * Tell what we are doing. + */ + +opt_verbose = false; + +/* + * -V, --version + * + * Print version information and exit successfully. + */ + +/* + * Functions. + */ + +function main () +{ + var idx = ARGS[0].lastIndexOf ("/"); + if (idx >= 0) + program = ARGS[0].substr (idx + 1); + else + program = ARGS[0]; + + /* Handle arguments. */ + var i; + for (i = 1; i < ARGS.length; i++) + { + if (ARGS[i][0] == #'-') + { + if (ARGS[i] == "-g" || ARGS[i] == "--debug") + opt_debug = true; + else if (ARGS[i] == "-h" || ARGS[i] == "--help") + { + usage (); + System.exit (1); + } + else if (ARGS[i] == "-O" || ARGS[i] == "--optimize") + opt_optimize = true; + else if (ARGS[i] == "-v" || ARGS[i] == "--verbose") + opt_verbose = true; + else if (ARGS[i] == "-V" || ARGS[i] == "--version") + { + version (); + System.exit (0); + } + else + { + /* Unrecognized option. */ + System.error (program, ": unrecognized option `", + ARGS[i], "'\n"); + System.error ("Try `", program, + " --help' for more information.\n"); + System.exit (1); + } + } + else + { + /* End of arguments. */ + break; + } + } + + if (i >= ARGS.length) + { + System.error (program, ": no files specified\n"); + System.exit (1); + } + + /* Options. */ + + JSC$verbose = opt_verbose; + JSC$generate_debug_info = opt_debug; + + /* Process files. */ + for (; i < ARGS.length; i++) + { + /* Reset the JSC's assembler package. */ + JSC$asm_reset (); + + /* Process the input file. */ + JSC$filename = ARGS[i]; + process_file (JSC$filename); + + if (opt_optimize) + JSC$asm_optimize (JSC$FLAG_OPTIMIZE_MASK); + + JSC$asm_finalize (); + + var result = JSC$asm_bytecode (); + + /* Create the output file name. */ + var oname = ARGS[i].replace (/\.jas$/, ".jsc"); + if (oname == ARGS[i]) + oname += ".jsc"; + + var ostream = new File (oname); + if (ostream.open ("w")) + { + ostream.write (result); + ostream.close (); + } + else + { + System.stderr.writeln ("jsas: couldn't create bc file `" + + oname + "': " + + System.strerror (System.errno)); + System.exit (1); + } + } +} + +function usage () +{ + System.print ("\ +Usage: ", program, " [OPTION]... FILE...\n\ +Mandatory arguments to long options are mandatory for short options too.\n"); + + System.print ("\ + -g, --debug generate debugging information\n\ + -h, --help print this help and exit\n\ + -O, --optimize optimize the assembler code\n\ + -v, --verbose tell what the assembler is doing\n\ + -V, --version print version number\n\ +"); + + System.print ("\nReport bugs to mtr@ngs.fi.\n"); +} + +function version () +{ + System.print ("NGS JavaScript assembler ", version_number, "\n"); + System.print ("\ +Copyright (C) 1998 New Generation Software (NGS) Oy.\n\ +NGS JavaScript Interpreter comes with NO WARRANTY, to the extent\n\ +permitted by law. You may redistribute copies of NGS JavaScript\n\ +Interpreter under the terms of the GNU Library General Public License.\n\ +For more information about these matters, see the files named COPYING.\n\ +"); +} + +main (); + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/jsas/operands.js b/reactos/lib/kjs/jsas/operands.js new file mode 100644 index 00000000000..4591cb64ef2 --- /dev/null +++ b/reactos/lib/kjs/jsas/operands.js @@ -0,0 +1,472 @@ +/* -*- c -*- + * Operand definitions for the JavaScript byte-code. + * + * This file is automatically create from the operands.def file. + * Editing is strongly discouraged. You should edit the file + * `extract-operands.js' instead. + */ + +argument_sizes = new Object (); +operand_flags = new Object (); + +function give_operand (name, ln) +{ + switch (name) + { + case "halt": + return new JSC$ASM_halt (ln); + break; + + case "done": + return new JSC$ASM_done (ln); + break; + + case "nop": + return new JSC$ASM_nop (ln); + break; + + case "dup": + return new JSC$ASM_dup (ln); + break; + + case "pop": + return new JSC$ASM_pop (ln); + break; + + case "pop_n": + return new JSC$ASM_pop_n (ln); + break; + + case "apop": + return new JSC$ASM_apop (ln); + break; + + case "swap": + return new JSC$ASM_swap (ln); + break; + + case "roll": + return new JSC$ASM_roll (ln); + break; + + case "const": + return new JSC$ASM_const (ln); + break; + + case "const_null": + return new JSC$ASM_const_null (ln); + break; + + case "const_true": + return new JSC$ASM_const_true (ln); + break; + + case "const_false": + return new JSC$ASM_const_false (ln); + break; + + case "const_undefined": + return new JSC$ASM_const_undefined (ln); + break; + + case "const_i0": + return new JSC$ASM_const_i0 (ln); + break; + + case "const_i1": + return new JSC$ASM_const_i1 (ln); + break; + + case "const_i2": + return new JSC$ASM_const_i2 (ln); + break; + + case "const_i3": + return new JSC$ASM_const_i3 (ln); + break; + + case "const_i": + return new JSC$ASM_const_i (ln); + break; + + case "load_global": + return new JSC$ASM_load_global (ln); + break; + + case "store_global": + return new JSC$ASM_store_global (ln); + break; + + case "load_arg": + return new JSC$ASM_load_arg (ln); + break; + + case "store_arg": + return new JSC$ASM_store_arg (ln); + break; + + case "load_local": + return new JSC$ASM_load_local (ln); + break; + + case "store_local": + return new JSC$ASM_store_local (ln); + break; + + case "load_property": + return new JSC$ASM_load_property (ln); + break; + + case "store_property": + return new JSC$ASM_store_property (ln); + break; + + case "load_array": + return new JSC$ASM_load_array (ln); + break; + + case "store_array": + return new JSC$ASM_store_array (ln); + break; + + case "nth": + return new JSC$ASM_nth (ln); + break; + + case "cmp_eq": + return new JSC$ASM_cmp_eq (ln); + break; + + case "cmp_ne": + return new JSC$ASM_cmp_ne (ln); + break; + + case "cmp_lt": + return new JSC$ASM_cmp_lt (ln); + break; + + case "cmp_gt": + return new JSC$ASM_cmp_gt (ln); + break; + + case "cmp_le": + return new JSC$ASM_cmp_le (ln); + break; + + case "cmp_ge": + return new JSC$ASM_cmp_ge (ln); + break; + + case "cmp_seq": + return new JSC$ASM_cmp_seq (ln); + break; + + case "cmp_sne": + return new JSC$ASM_cmp_sne (ln); + break; + + case "sub": + return new JSC$ASM_sub (ln); + break; + + case "add": + return new JSC$ASM_add (ln); + break; + + case "mul": + return new JSC$ASM_mul (ln); + break; + + case "div": + return new JSC$ASM_div (ln); + break; + + case "mod": + return new JSC$ASM_mod (ln); + break; + + case "neg": + return new JSC$ASM_neg (ln); + break; + + case "and": + return new JSC$ASM_and (ln); + break; + + case "not": + return new JSC$ASM_not (ln); + break; + + case "or": + return new JSC$ASM_or (ln); + break; + + case "xor": + return new JSC$ASM_xor (ln); + break; + + case "shift_left": + return new JSC$ASM_shift_left (ln); + break; + + case "shift_right": + return new JSC$ASM_shift_right (ln); + break; + + case "shift_rright": + return new JSC$ASM_shift_rright (ln); + break; + + case "iffalse": + return new JSC$ASM_iffalse (ln); + break; + + case "iftrue": + return new JSC$ASM_iftrue (ln); + break; + + case "call_method": + return new JSC$ASM_call_method (ln); + break; + + case "jmp": + return new JSC$ASM_jmp (ln); + break; + + case "jsr": + return new JSC$ASM_jsr (ln); + break; + + case "return": + return new JSC$ASM_return (ln); + break; + + case "typeof": + return new JSC$ASM_typeof (ln); + break; + + case "new": + return new JSC$ASM_new (ln); + break; + + case "delete_property": + return new JSC$ASM_delete_property (ln); + break; + + case "delete_array": + return new JSC$ASM_delete_array (ln); + break; + + case "locals": + return new JSC$ASM_locals (ln); + break; + + case "min_args": + return new JSC$ASM_min_args (ln); + break; + + case "load_nth_arg": + return new JSC$ASM_load_nth_arg (ln); + break; + + case "with_push": + return new JSC$ASM_with_push (ln); + break; + + case "with_pop": + return new JSC$ASM_with_pop (ln); + break; + + case "try_push": + return new JSC$ASM_try_push (ln); + break; + + case "try_pop": + return new JSC$ASM_try_pop (ln); + break; + + case "throw": + return new JSC$ASM_throw (ln); + break; + + case "iffalse_b": + return new JSC$ASM_iffalse_b (ln); + break; + + case "iftrue_b": + return new JSC$ASM_iftrue_b (ln); + break; + + case "add_1_i": + return new JSC$ASM_add_1_i (ln); + break; + + case "add_2_i": + return new JSC$ASM_add_2_i (ln); + break; + + case "load_global_w": + return new JSC$ASM_load_global_w (ln); + break; + + case "jsr_w": + return new JSC$ASM_jsr_w (ln); + break; + + default: + System.stderr.writeln (program + ":" + ln.toString () + + ": unknown operand `" + name + "'"); + break; + } +} + +argument_sizes["halt"] = 0; +operand_flags["halt"] = 0x0; +argument_sizes["done"] = 0; +operand_flags["done"] = 0x0; +argument_sizes["nop"] = 0; +operand_flags["nop"] = 0x0; +argument_sizes["dup"] = 0; +operand_flags["dup"] = 0x0; +argument_sizes["pop"] = 0; +operand_flags["pop"] = 0x0; +argument_sizes["pop_n"] = 1; +operand_flags["pop_n"] = 0x0; +argument_sizes["apop"] = 1; +operand_flags["apop"] = 0x0; +argument_sizes["swap"] = 0; +operand_flags["swap"] = 0x0; +argument_sizes["roll"] = 1; +operand_flags["roll"] = 0x0; +argument_sizes["const"] = 4; +operand_flags["const"] = 0x0; +argument_sizes["const_null"] = 0; +operand_flags["const_null"] = 0x0; +argument_sizes["const_true"] = 0; +operand_flags["const_true"] = 0x0; +argument_sizes["const_false"] = 0; +operand_flags["const_false"] = 0x0; +argument_sizes["const_undefined"] = 0; +operand_flags["const_undefined"] = 0x0; +argument_sizes["const_i0"] = 0; +operand_flags["const_i0"] = 0x0; +argument_sizes["const_i1"] = 0; +operand_flags["const_i1"] = 0x0; +argument_sizes["const_i2"] = 0; +operand_flags["const_i2"] = 0x0; +argument_sizes["const_i3"] = 0; +operand_flags["const_i3"] = 0x0; +argument_sizes["const_i"] = 4; +operand_flags["const_i"] = 0x0; +argument_sizes["load_global"] = 4; +operand_flags["load_global"] = 0x1; +argument_sizes["store_global"] = 4; +operand_flags["store_global"] = 0x1; +argument_sizes["load_arg"] = 1; +operand_flags["load_arg"] = 0x0; +argument_sizes["store_arg"] = 1; +operand_flags["store_arg"] = 0x0; +argument_sizes["load_local"] = 2; +operand_flags["load_local"] = 0x0; +argument_sizes["store_local"] = 2; +operand_flags["store_local"] = 0x0; +argument_sizes["load_property"] = 4; +operand_flags["load_property"] = 0x1; +argument_sizes["store_property"] = 4; +operand_flags["store_property"] = 0x1; +argument_sizes["load_array"] = 0; +operand_flags["load_array"] = 0x0; +argument_sizes["store_array"] = 0; +operand_flags["store_array"] = 0x0; +argument_sizes["nth"] = 0; +operand_flags["nth"] = 0x0; +argument_sizes["cmp_eq"] = 0; +operand_flags["cmp_eq"] = 0x0; +argument_sizes["cmp_ne"] = 0; +operand_flags["cmp_ne"] = 0x0; +argument_sizes["cmp_lt"] = 0; +operand_flags["cmp_lt"] = 0x0; +argument_sizes["cmp_gt"] = 0; +operand_flags["cmp_gt"] = 0x0; +argument_sizes["cmp_le"] = 0; +operand_flags["cmp_le"] = 0x0; +argument_sizes["cmp_ge"] = 0; +operand_flags["cmp_ge"] = 0x0; +argument_sizes["cmp_seq"] = 0; +operand_flags["cmp_seq"] = 0x0; +argument_sizes["cmp_sne"] = 0; +operand_flags["cmp_sne"] = 0x0; +argument_sizes["sub"] = 0; +operand_flags["sub"] = 0x0; +argument_sizes["add"] = 0; +operand_flags["add"] = 0x0; +argument_sizes["mul"] = 0; +operand_flags["mul"] = 0x0; +argument_sizes["div"] = 0; +operand_flags["div"] = 0x0; +argument_sizes["mod"] = 0; +operand_flags["mod"] = 0x0; +argument_sizes["neg"] = 0; +operand_flags["neg"] = 0x0; +argument_sizes["and"] = 0; +operand_flags["and"] = 0x0; +argument_sizes["not"] = 0; +operand_flags["not"] = 0x0; +argument_sizes["or"] = 0; +operand_flags["or"] = 0x0; +argument_sizes["xor"] = 0; +operand_flags["xor"] = 0x0; +argument_sizes["shift_left"] = 0; +operand_flags["shift_left"] = 0x0; +argument_sizes["shift_right"] = 0; +operand_flags["shift_right"] = 0x0; +argument_sizes["shift_rright"] = 0; +operand_flags["shift_rright"] = 0x0; +argument_sizes["iffalse"] = 4; +operand_flags["iffalse"] = 0x2; +argument_sizes["iftrue"] = 4; +operand_flags["iftrue"] = 0x2; +argument_sizes["call_method"] = 4; +operand_flags["call_method"] = 0x1; +argument_sizes["jmp"] = 4; +operand_flags["jmp"] = 0x2; +argument_sizes["jsr"] = 0; +operand_flags["jsr"] = 0x0; +argument_sizes["return"] = 0; +operand_flags["return"] = 0x0; +argument_sizes["typeof"] = 0; +operand_flags["typeof"] = 0x0; +argument_sizes["new"] = 0; +operand_flags["new"] = 0x0; +argument_sizes["delete_property"] = 4; +operand_flags["delete_property"] = 0x1; +argument_sizes["delete_array"] = 0; +operand_flags["delete_array"] = 0x0; +argument_sizes["locals"] = 2; +operand_flags["locals"] = 0x0; +argument_sizes["min_args"] = 1; +operand_flags["min_args"] = 0x0; +argument_sizes["load_nth_arg"] = 0; +operand_flags["load_nth_arg"] = 0x0; +argument_sizes["with_push"] = 0; +operand_flags["with_push"] = 0x0; +argument_sizes["with_pop"] = 1; +operand_flags["with_pop"] = 0x0; +argument_sizes["try_push"] = 4; +operand_flags["try_push"] = 0x2; +argument_sizes["try_pop"] = 1; +operand_flags["try_pop"] = 0x0; +argument_sizes["throw"] = 0; +operand_flags["throw"] = 0x0; +argument_sizes["iffalse_b"] = 4; +operand_flags["iffalse_b"] = 0x2; +argument_sizes["iftrue_b"] = 4; +operand_flags["iftrue_b"] = 0x2; +argument_sizes["add_1_i"] = 0; +operand_flags["add_1_i"] = 0x0; +argument_sizes["add_2_i"] = 0; +operand_flags["add_2_i"] = 0x0; +argument_sizes["load_global_w"] = 4; +operand_flags["load_global_w"] = 0x1; +argument_sizes["jsr_w"] = 4; +operand_flags["jsr_w"] = 0x1; diff --git a/reactos/lib/kjs/jsas/process.js b/reactos/lib/kjs/jsas/process.js new file mode 100644 index 00000000000..27683c90a9e --- /dev/null +++ b/reactos/lib/kjs/jsas/process.js @@ -0,0 +1,296 @@ +/* + * Process assembler file. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsas/process.js,v $ + * $Id: process.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +function process_file (name) +{ + var fp = new File (name); + var labels = new Object (); + var label_waits = new Object (); + var op; + + if (fp.open ("r")) + { + var linenum = 0; + + while (!fp.eof ()) + { + var line = fp.readln (); + linenum++; + + /* Remove comments. */ + line = line.replace (/;.*$/, ""); + + /* Extract the labels and symbols. */ + if (/^([^ \t\n]+):(.*)$/.exec (line)) + { + var label = RegExp.$1; + line = RegExp.$2; + + if (/^\.[^ ]+$/.test (label) && label != ".global") + { + /* It is a label. */ + if (labels[label]) + { + System.stderr.writeln (name + ":" + linenum.toString () + + ": label `" + label + + "' is already defined"); + System.stderr.writeln (name + ":" + + (labels[label].linenum + .toString ()) + + ": this is the place of the " + + "previous definition"); + System.exit (1); + } + labels[label] = new JSC$ASM_label (); + labels[label].linenum = linenum; + labels[label].link (); + } + else + { + /* It is a symbol. */ + new JSC$ASM_symbol (linenum, label).link (); + } + } + + /* Skip empty lines. */ + if (/^[ \n\t]*$/.test (line)) + continue; + + if (!/^[ \n\t]*([^ \n\t]+)[ \n\t]*(.*)[ \n\t]*$/.exec (line)) + { + System.stderr.writeln (name + ":" + linenum.toString () + + ": syntax error"); + System.exit (1); + } + var operand = RegExp.$1; + var argument = RegExp.$2; + + /* Check that this is a known operand. */ + if (typeof argument_sizes[operand] == "undefined") + { + System.stderr.writeln (name + ":" + linenum.toString () + + ": unknown operand `" + operand + + "'"); + System.exit (1); + } + + if ((operand_flags[operand] & 0x02) != 0) + { + /* The branch operands. */ + if (argument.length == 0) + { + System.stderr.writeln (name + ":" + linenum.toString () + + ": branch operand requires a " + + " label argument"); + System.exit (1); + } + if (!label_waits[argument]) + label_waits[argument] = new Array (); + + op = give_operand (operand, linenum); + label_waits[argument].push (op); + op.link (); + } + else if ((operand_flags[operand] & 0x01) != 0) + { + /* The symbol operands. */ + if (!/^[A-Za-z_$][A-Za-z_$0-9]*$/.test (argument)) + { + System.stderr.writeln (name + ":" + linenum.toString () + + ": operand `" + operand + + "' requires a symbol argument"); + System.exit (1); + } + op = give_operand (operand, linenum); + op.link (); + op.value = argument; + } + else if (operand == "const") + { + var value; + + if (/^\"(.*)\"$/.test (argument)) + value = const_string (RegExp.$1); + else if (/^[0-9]+$/.test (argument)) + value = parseInt(argument); + else + { + System.stderr.writeln (name + ":" + linenum.toString () + + ": malformed argument `" + + argument + "' for operand `" + + operand + "'"); + System.exit (1); + } + + op = give_operand (operand, linenum); + op.link (); + op.value = value; + } + else + { + if (argument_sizes[operand] == 0) + { + /* Simple operands without arugments. */ + if (argument.length != 0) + { + System.stderr.writeln (name + ":" + linenum.toString () + + ": operand `" + operand + + "' doesn't take argument"); + System.exit (1); + } + give_operand (operand, linenum).link (); + } + else + { + /* Simple operands with integer arguments. */ + if (!/^[-+]?[0-9]+$/.test (argument)) + { + System.stderr.writeln (name + ":" + linenum.toString () + + ": operand `" + operand + + "' requires an integer " + + "argument"); + System.exit (1); + } + op = give_operand (operand, linenum); + op.link (); + op.value = parseInt (argument); + } + } + } + fp.close (); + + /* Patch labels to branch operands. */ + for (var label in label_waits) + for (op in label_waits[label]) + { + if (!labels[label]) + { + System.stderr.writeln (name + ":" + op.linenum.toString () + + ": undefined label `" + label + "'"); + System.exit (1); + } + op.value = labels[label]; + } + } + else + { + System.stderr.writeln (program + ": couldn't open input file `" + + name + "': " + System.strerror (System.errno)); + System.exit (1); + } +} + + +function const_string (source) +{ + var str = new String (""); + var i; + + for (i = 0; i < source.length; i++) + { + switch (source[i]) + { + case #'\\': + if (i + 1 > source.length) + str.append ("\\"); + else + { + i++; + var ch; + + switch (source[i]) + { + case #'n': + ch = "\n"; + break; + + case #'t': + ch = "\t"; + break; + + case #'v': + ch = "\v"; + break; + + case #'b': + ch = "\b"; + break; + + case #'r': + ch = "\r"; + break; + + case #'f': + ch = "\f"; + break; + + case #'a': + ch = "\a"; + break; + + case #'\\': + ch = "\\"; + break; + + case #'?': + ch = "?"; + break; + + case #'\'': + ch = "'"; + break; + + case #'"': + ch = "\""; + break; + + default: + ch = File.byteToString (source[i]); + break; + } + + str.append (ch); + } + break; + + default: + str.append (File.byteToString (source[i])); + break; + } + } + + return str; +} + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/jsc/ChangeLog b/reactos/lib/kjs/jsc/ChangeLog new file mode 100644 index 00000000000..52c0ff2a36d --- /dev/null +++ b/reactos/lib/kjs/jsc/ChangeLog @@ -0,0 +1,652 @@ +1999-01-11 Markku Rossi + + * lexer.js (JSC$lexer_read_string): Optimized the stream reading + by using the new String.append(INTEGER) method. + +1998-10-26 Markku Rossi + + * parser.js (JSC$parser_parse_stmt): Implemented function + declarations as statements. + + * gram.js (JSC$stmt_function_declaration): New statement for + nested function declarations. + + * defs.js: New statement type JSC$STMT_FUNCTION_DECLARATION. + + * gram.js (JSC$expr_call_asm): Added support for function + pointers. + + * asm.js: Added support for function pointers. + Added new operands `jsr_w' and `load_global_w' which operate with + the with chains. + +1998-10-12 Markku Rossi + + * gram.js (JSC$expr_additive_constant_folding): Implemented simple + constant folding optimization. + + * parser.js (JSC$parser_parse_assignment_expr): Implemented + constant folding optimization. + + * entry.js (JSC$compile_stream): Added a try-finally block over + the stream compilation. This assures that the stream is always + closed, even if the compilation fails. + +1998-10-01 Markku Rossi + + * parser.js (JSC$parser_parse_function_declaration): Fixed the + parameter list parsing. Now we do require that the parameters are + separated by a ','. + +1998-09-17 Markku Rossi + + * gram.js (JSC$stmt_try_asm): If none of the catch blocks matches + the exception, we must throw it the upper level. + +1998-09-10 Markku Rossi + + * asm.js (JSC$ASM_const_i_print): Cleaned up the output. + + * gram.js (JSC$expr_object_initializer): New expression object for + object literals. + + * parser.js (JSC$parser_parse_primary_expr): Implemented object + literals. + + * asm.js (JSC$ASM_const_i): New operand to push a Int32 integer to + the stack. Effectively this operand removes all integer constants + from the constants section. They can be expressed in the same + space that was used to present the integer index. + + * gram.js (JSC$expr_integer_asm): Changed to use the new `const_i' + operand. + +1998-09-07 Markku Rossi + + * parser.js (JSC$parser_parse_function_declaration): Implemented + the `arguments' property of function instance. + + * gram.js (JSC$function_declaration_asm): Added support for the + `arguments' property of function instance. If the property is + used in the function body, we add code to the beginning of the + function to create the arguments array. + (JSC$stmt_for_count_locals): Fixed the counting of the local + variables. + (JSC$stmt_for_in_count_locals): Fixed the counting of local + variables. + + * entry.js: New flag JSC$FLAG_WARN_DEPRECATED to generate error + messages about uses of deprecated features. + + * asm.js (JSC$ASM_load_nth_arg): New byte-code operand to load the + nth argument of function, where the index is at the top of the + stack. This is needed in the implemenation of the `arguments' + property of function instances. + Re-organized byte-code operand numbers. All old byte-code files + must be re-compiled. + +1998-09-04 Markku Rossi + + * asm.js: Re-organized byte-code operand numbers. All old + byte-code files must be re-compiled. + + * parser.js (JSC$parser_parse_primary_expr): Changed the way how + the regular expression constants are handled. We must decide the + point when we accept a regexp constant. The lexer can't do it + because the div operand and regexp constants can't be + distinguished based on lexical analysis. + (JSC$parser_parse_equality_expr): Implemented strict equals and + does-not-equal operators. The change affects lexer.js, parser.js, + gram.js, asm.js, and defs.js. + + * defs.js: Removed constant JSC$tREGEXP. + + * lexer.js (JSC$lexer): Changed the way how the regular expression + constants are handled. We no longer return them as a token. We + return the starting '/' character as-is and the parser recognizes + the cases when it can start a regexp constant. In those cases, + the parser will call JSC$lexer_read_regexp_constant() that reads + the constant and compiles it to the RegExp built-in object. + +1998-09-03 Markku Rossi + + * lexer.js (JSC$lexer): Changed the way how errors are returned + form the malformed regular expression constants. This is needed + because the syntax of the try-statement was changed. + + * gram.js (JSC$stmt_for): Added support for local variable + declarations. + (JSC$stmt_for_in): Added support for local variable declarations. + + * parser.js (JSC$parser_parse_iteration_stmt): Added support for + local variable declarations in the head of the for statement. + + * entry.js (JSC$compile_stream): Clear the syntax tree after the + assembler has been generated. This saves some memory. + + * Replaced all JC$Lists in the compiler sources with built-in + Array objects. + Removed the list.js file from the project. + + * asm.js (JSC$asm_print): Cleaned up the annotated assembler + output. + + * gram.js (JSC$ContBreak): Added support for labeled statements. + The constructor and all calculation methods were fixed to support + the labels. + (JSC$ContBreak$is_unique_label): New method is_unique_label() to + check if the given label is unique in the current continue-break + stack. + (JSC$stmt_continue): Added support for labeled statements. + (JSC$stmt_break): Added support for labeled statements. + (JSC$stmt_labeled_stmt): New statement for the labeled + statements. + + * parser.js (JSC$parser_parse_stmt): Implemented labeled + statements. + (JSC$parser_parse_stmt): Added optional label to break and + continue statements. + +1998-09-02 Markku Rossi + + * parser.js (JSC$parser_parse_try): New function to parse try + statements. + + * gram.js (JSC$stmt_break_asm): Cleaned up the try and with + nesting calculation. Now we use the methods, instead of directly + investigating the top frame in the cont_break stack. + (JSC$stmt_try): Re-implemented the try statement, including its + asm() and count_locals() methods. Now the implementation is + ECMAScript compatible. + +1998-09-01 Markku Rossi + + * asm.js (JSC$asm_optimize): Optimize cases `const_true, iftrue' + and `const_false, iffalse' to jumps. + (JSC$asm_optimize): Cleaned up the peephole optimizations. + Implemented a new byte-code side optimization that removes + unnecessary jumps to the immediately following labels. + + * gram.js (JSC$stmt_switch): New statement object for the switch + statements. + (JSC$stmt_continue_asm): Fixed to work inside a switch statement. + (JSC$ContBreak): Cleaned up the continue-break handling in loops. + Now it should work inside switch statements, including nested + switch statements. + + * parser.js (JSC$parser_parse_switch): New function to parse + switch statements. + +1998-08-25 Markku Rossi + + * parser.js (JSC$parser_parse_stmt): Added strict_ecma warning + about line terminators between `throw' and the expression. + + * gram.js (JSC$stmt_do_while): New statement object for do...while + statements. + + * parser.js (JSC$parser_parse_variable_stmt): Fixed the variable + declaration parsing. Now it should co-operate correctly with the + automatic semicolon insertion. + (JSC$parser_parse_iteration_stmt): Implemented do...while + statements. + + * lexer.js (JSC$lexer_read_regexp): New function to read regular + expression literals. The backslash escapes within them are so + different from string literals that they need an own function to + handle them. + (JSC$lexer_read_backslash_escape): New function to handle + backslash escapes in strings, character constants, and partly in + regular expression literals. + (JSC$lexer_read_backslash_escape): Added support for \xHH and + \uHHHH escapes. + Now the lexer should be ECMAScript 2.0 (draft) compatible. + +1998-08-19 Markku Rossi + + * parser.js: New functions JSC$warning() and JSC$message() to + report warnings and messages from the compiler. Changed all + outputs in the sources to use these functions. There shouldn't be + any System.error() calls left. + +1998-08-17 Markku Rossi + + * gram.js (JSC$expr_array_initializer): New expression for array + initializers. + + * parser.js (JSC$parser_parse_primary_expr): Implemented array + initializers. + + * defs.js: New expression type JSC$EXPR_ARRAY_INITIALIZER. + + * list.js: Cleaned up the code. + +1998-08-14 Markku Rossi + + * asm.js: Changed JSC$CONST_REGEXP's value to 11. It is returned + as a JS_BUILTIN. + + * parser.js: Added support for the regular expression constants. + + * gram.js (JSC$expr_regexp): New grammar component for the regular + expression constants. + + * asm.js: Added support for the regular expression constants. + + * defs.js: New type constant JSC$JS_BUILTIN. + +1998-08-13 Markku Rossi + + * defs.js: New token constant JSC$tREGEXP. + + * parser.js (JSC$parser_parse): Fixed to report the number of + missing semicolons only if there are any. + + * entry.js: New flag JSC$FLAG_WARN_STRICT_ECMA to generate error + messages about features that are supported but which are agains + the ECMAScript standard. + + * lexer.js (JSC$lexer): Fixed all error messages to be in the + `FILENAME:LINENUM: MESSAGE' format. + (JSC$lexer_read_string): Added warning about line terminators in + string and regular expression constants. + Fixed all error messages. + Optimized the data creation to use the String.append() method. + (JSC$lexer): Implemented regular expression literals. + +1998-08-12 Markku Rossi + + * parser.js: Changed messages about automatic semicolon inserting + to warnings. + + * entry.js: New flag JSC$FLAG_WARN_MISSING_SEMICOLON. + +1998-08-11 Markku Rossi + + * parser.js (JSC$parser_parse_source_element): Tag the global + level variable declarations so that we can distinguish them at the + assembler creation time. + Implemented automatic semicolon inserting. + (JSC$parser_parse): Added statistics about the missing + semicolons. + + * gram.js (JSC$stmt_variable_asm): Changed the variables, declared + at the global level, to be global variables. + Fixed some panic() calls to report the error with the `error()' + global method. + +1998-08-05 Markku Rossi + + * entry.js: New flag JSC$FLAG_GENERATE_EXECUTABLE_BC_FILES. + (JSC$compile_stream): Added support for + JSC$FLAG_GENERATE_EXECUTABLE_BC_FILES. + +1998-06-08 Markku Rossi + + * parser.js (JSC$parser_parse_arguments): Fixed a bug that allowed + us to call functions so that the individual arguements were not + separated by a comma #','. + + * asm.js: Removed operands `assert_args', `assert_min_args', and + `assert_max_args'. + Added operands `min_args', `add_1_i', and `add_2_i'. + + * gram.js (JSC$function_declaration_asm): Removed conditional + function argument count checks. The check were replaced with + `min_args' operand that arranges things so that the minimum amount + of arguments is present. + + * entry.js (JSC$compile_stream): Removed flag + JSC$FLAG_ARGUMENT_COUNT_CHECKS. JavaScript allows functions to be + called with any number of arguments. Therefore, we can't assert + the minimum amount of arguments for function. + + * gram.js (JSC$expr_new_asm): Added support for `new Foo' + expressions. + + * asm.js: Changed constant types to new values. + +1998-06-05 Markku Rossi + + * asm.js (JSC$ASM_mod): Implemented operand mod. + Cleaned up byte-code operand opcodes. + +1998-06-03 Markku Rossi + + * asm.js: Cleaned up the byte-code creation. Now we have common + byte-code creation methods for different operand values: int8, + int16, etc. This cleanup removes redundancy and saves nine + functions. + Cleaned up the compiler progress messages. + +1998-06-02 Markku Rossi + + * lexer.js (JSC$lexer): Implemented 'data' -strings. The + character constants are now presented as #'a'. + +1998-05-15 Markku Rossi + + * gram.js (JSC$stmt_if_count_locals): Changed the way how the + number of locals is counted. We don't need #if + #else, but we + need max(#if, #else). + + * parser.js (JSC$parser_parse_stmt): Implemented the `throw' + statement. + + * gram.js (JSC$stmt_throw): Implemented the `throw' statement. + + * asm.js (JSC$ASM_throw): Implemented operand `throw'. + + * defs.js: Defined new statement JSC$STMT_THROW. + +1998-05-14 Markku Rossi + + * parser.js (JSC$parser_parse_stmt): Implemented the `try...catch' + statement. + Fixed a typo where function syntax_error() was called instead of + JSC$parser_syntax_error(). + + * gram.js (JSC$ContBreak$try_return_nesting): New function to + count how many try_pop's the return statement should invoke. + (JSC$stmt_return_asm): Changed to invoke try_pop's if the return + occurs inside a try-block. + (JSC$stmt_try): Implemented the `try...catch' statement. + + * asm.js: Implemented new operands try_push and try_pop to + implement the `try...catch' statement. + (JSC$asm_is_local_jump): Added JSC$OP_TRY_PUSH. + (JSC$asm_optimize): Changed to stop `dup...pop' searching on + `try_pop' operand. + + * defs.js: Defined tokens for the ECMA Script's future reserved + keywords. + Defined new statement JSC$STMT_TRY. + + * lexer.js (JSC$lexer): Added support for the ECMA Script's future + reserved keywords. + + * gram.js: Cleaned up the `continue' and `break' statement + handling. Now there is an instance of class JSC$ContBreak that + holds the state of the currently active looping constructs. + +1998-05-13 Markku Rossi + + * gram.js: Checked all XXX's and fixed them. + +1998-05-12 Markku Rossi + + * parser.js (JSC$parser_parse_iteration_stmt): Implemented + `for...in' statements. + + * gram.js (JSC$stmt_for_in): Implemented `for...in' statements. + + * defs.js: New statement type JSC$STMT_FOR_IN. + + * asm.js: Reorganized byte-code operands. + (JSC$ASM_roll): New operand to roll the n uppermost items in the + stack. + (JSC$ASM_nth): New operand to return the nth item from array, + object, or string. + +1998-05-11 Markku Rossi + + * asm.js (JSC$ASM_delete_property): New function for the + `delete_property' operand. + (JSC$ASM_delete_array): New function for the `delete_array' + operand. + The new functions JSC$ASM_delete_property and JSC$ASM_delete_array + replace the old `delete' operand. + + * gram.js (JSC$expr_unary_asm): Implemented (correctly) the delete + operator. + +1998-05-07 Markku Rossi + + * asm.js (JSC$asm_optimize): Fixed a bug from the peep-hole + optimization. We must not optimize over subroutine calls like: + jsr, new, call_method or return operands. + + * lexer.js (JSC$lexer_read_string): Fixed to handle + backslash+newline like C does. + +1998-04-16 Markku Rossi + + * lexer.js (JSC$lexer): Implemented decimal literals. + + * asm.js (JSC$ASM_const_bytecode): Implemented float and NaN + constants. + + * entry.js: New flag JSC$FLAG_WARN_WITH_CLOBBER to control + warnings about the with-lookup clobbering. + + * gram.js (JSC$asm_expr_lvalue_load_asm): Added warnings for + symbols which with-lookup is clobbered by a local variable or a + function argument declaration. + +1998-04-15 Markku Rossi + + * asm.js (JSC$ASM_with_pop): Added argument `value' that specifies + how many with-frames the operand pops. + + * gram.js (JSC$stmt_with_asm): Finished with statement. Now it + handles break and continue statements within the with block. + +1998-03-31 Markku Rossi + + * entry.js: Renamed flag JSC$FLAG_OPTIMIZE_JUMPS_TO_JUMPS to + JSC$FLAG_OPTIMIZE_JUMPS. + +1998-03-26 Markku Rossi + + * Added tests for the compiler. + + * defs.js: Changed JSC$alloc_id() calls with constant values. + +1998-03-25 Markku Rossi + + * asm.js (JSC$asm_optimize): Replaced individual `dup nnn pop => + nnn' optimizations with one generic dup-pop optimizations. This + new optimizations handles all the optimizable dup-pop cases. + +1998-03-24 Markku Rossi + + * asm.js (JSC$asm_optimize): New optimizations for `while (true)' + and `while (false)' cases. + +1998-03-05 Markku Rossi + + * parser.js (JSC$parser_parse_left_hand_side_expr): Fixed few + typos where JSC$parser_get_token() was called without arguments. + + * lexer.js (JSC$lexer): Implemented some character constants. Now + the lexer supports all character constants that can be found from + the ANSI-C reference. + + * gram.js: Added language types for all expressions that know + them. + Changed to generate type aware assembler operands for expressions + and statements for which the type is known. + + * entry.js (JSC$compile_stream): Added unconditional + optimizations: constant folding and type optimizations. + + * defs.js: Added language primitive types. + + * asm.js: Implemented type aware iffalse_b and iftrue_b operands. + +1998-03-04 Markku Rossi + + * gram.js (JSC$expr_real_asm): Implemented. + +1998-03-03 Markku Rossi + + * asm.js (JSC$optimize_heavy): New function to perform + optimizations that require the liveness information of local + variables and arguments. + + * entry.js: New flag JSC$FLAG_OPTIMIZE_HEAVY for heavy + optimizations. + + * asm.js: Re-organized assembler operands. + Implemented all missing operands. + + * entry.js: New flag JSC$FLAG_ARGUMENT_COUNT_CHECKS. + + * gram.js (JSC$function_declaration_asm): Added argument count + checks. + Renamed shift operands. + +1998-03-02 Markku Rossi + + * parser.js: Fixes some bugs, shown by the new function argument + count check. + + * gram.js: Changed all `new JSC$ASM_*()' constructors to + explicitly call the link() method. + + * asm.js: Removed call to JSC$asm_append() from all asm + constructors. The linking is now implemented with the link() + method that is defined to all assembler operands, labels and + symbols. + + * gram.js (JSC$function_declaration): Added lbrace_ln to hold the + line number of the opening lbrace of the body. + (JSC$function_declaration_asm): Set locals' linenumber to be + lbrace_ln. + +1998-02-27 Markku Rossi + + * asm.js (JSC$asm_bytecode): Added debugging information. + + * entry.js: Renamed to entry.js from main.js. + New flag JSC$FLAG_ANNOTATE_ASSEMBLER. + (JSC$compile_stream): Changed to handle + JSC$FLAG_ANNOTATE_ASSEMBLER flag. + New flag JSC$FLAG_GENERATE_DEBUG_INFO. + (JSC$compile_stream): Changed to handle + JSC$FLAG_GENERATE_DEBUG_INFO flga. + + * streams.js: Added rewind and readln methods to all streams. + + * asm.js (JSC$asm_print): If requested, annotate the generated + assembler listing with the original source code. + + * gram.js: Added line number information to all assembler + operands. + + * parser.js: Added line number information to all statements and + expressions. + +1998-02-26 Markku Rossi + + * asm.js (JSC$asm_optimize): Implemented new optimization for + assembler, generated from statements like `i++' and `i--'. + +1998-02-24 Markku Rossi + + * asm.js (JSC$ASM_xor): Implemented xor opcode. + (JSC$ASM_with_push): Implemented with statements. + (JSC$asm_generate): Changed to ensure that the evaluation of the + global section returns some sane value to the caller. + (JSC$asm_optimize): New peephole optimization for apop + pop. + (JSC$ASM_locals): Changed the argument to be a 16 bit integer. + + * parser.js (JSC$parser_parse): Fixed an infinite loop. We must + check that parse_source_element() returns true. Otherwise we have + encountered a syntax error. + + * gram.js (JSC$expr_unary_asm): Implemented rest unary + expressions. + (JSC$stmt_with): Implemented with statement. + + * lexer.js (JSC$lexer): Made `#!' a single line commment starter. + (JSC$lexer): Implemented '\ooo' notations to top-level and to + string constants. + +1998-02-23 Markku Rossi + + * namespace.js: Changed namespace to report errors and warnings + about different variable and argument definition illegalities. + + * main.js (JSC$compile_stream): Changed to raise an error if the + input stream couldn't be opened. + + * gram.js (JSC$stmt_variable_asm): Removed warnings about multiply + defined variables. They are now reported directly from + namespace. + + * asm.js (JSC$asm_optimize): Added argument flags that tells which + optimizations the function should perform. + +1998-02-20 Markku Rossi + + * parser.js (JSC$parser_reset): New function to reset all global + variables. + + * main.js (JSC$compiler_reset): New function to reset the whole + compiler. + + * gram.js (JSC$gram_reset): New function to reset all global + variables. + + * asm.js (JSC$asm_reset): New function to reset all global + variables. This replaces the old JSC$asm_clear() function. + + * Changed all errors to be reported with the error() global + method. + +1998-02-18 Markku Rossi + + * main.js (JSC$compile_stream): Made error messages more + informative. + + * streams.js: Added property `error' for all streams. + + * namespace.js (JSC$NameSpace_define_symbol): Changed to return a + boolean status code that identify whether the symbol was already + defined or not. + + * gram.js: Added line number information for statements. + +1998-02-16 Markku Rossi + + * gram.js (JSC$stmt_continue): Implemented `continue' statement. + (JSC$stmt_break): Implemented `break' statement. + + * asm.js (JSC$asm_bytecode): Changed to use String.append() + instead of the plus operand. This saves memory usage noticeably. + +1998-02-13 Markku Rossi + + * asm.js (JSC$asm_optimize): Made heavy optimizations to depend on + the JSC$optimize_heavy variable. + + * main.js: Create a new public interface to the compiler. + Made all diagnostics messages to depend on the JSC$verbose + variable. + + * asm.js (JSC$asm_optimize): Cleaned up the optimization code. + Run the dead code elimination optimizations in a loop until no + more changes can be done. + (JSC$asm_generate): Added support for local variables in the + global statements. + + * parser.js (JSC$parser_parse_left_hand_side_expr): Implemented + array references. + +1998-02-11 Markku Rossi + + * The JavaScript compiler is now self-hosting. It can generate + valid byte-code files which can be executed with the virtual + machine. The perl assembler is no longer needed. + + * gram.js: Changed to generate internal assembler objects instead + of dumping the assembler code to the stdout. + + * asm.js: New file to implement the assembler. + +1998-02-09 Markku Rossi + + * streams.js (JSC$StreamString): Implemented string stream. + + * The JavaScript JavaScript compiler can now compile itself. diff --git a/reactos/lib/kjs/jsc/Makefile b/reactos/lib/kjs/jsc/Makefile new file mode 100644 index 00000000000..090fdffc034 --- /dev/null +++ b/reactos/lib/kjs/jsc/Makefile @@ -0,0 +1,318 @@ +# Generated automatically from Makefile.in by configure. +# Makefile.in generated automatically by automake 1.3 from Makefile.am + +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Automakefile for JavaScript JavaScript compiler. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + + +SHELL = /bin/sh + +srcdir = . +top_srcdir = .. +prefix = /usr/local/js-0.2.5 +exec_prefix = ${prefix} + +bindir = ${exec_prefix}/bin +sbindir = ${exec_prefix}/sbin +libexecdir = ${exec_prefix}/libexec +datadir = ${prefix}/share +sysconfdir = ${prefix}/etc +sharedstatedir = ${prefix}/com +localstatedir = ${prefix}/var +libdir = ${exec_prefix}/lib +infodir = ${prefix}/info +mandir = ${prefix}/man +includedir = ${prefix}/include +oldincludedir = /usr/include + +DISTDIR = + +pkgdatadir = $(datadir)/js +pkglibdir = $(libdir)/js +pkgincludedir = $(includedir)/js + +top_builddir = .. + +ACLOCAL = aclocal +AUTOCONF = autoconf +AUTOMAKE = automake +AUTOHEADER = autoheader + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} +transform = s,x,x, + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = i686-pc-linux-gnu +host_triplet = i686-pc-linux-gnu +ACLOCAL_FLAGS_FOR_LIBTOOL = +CC = gcc +CPP = gcc -E +EXTENSIONS = dl_open.lo xjs.lo xmd5.lo md5c.lo +EXTENSIONS_LIBS = -ldl +INTERPRETER_FEATURES = r_std.lo +LD = /usr/bin/ld +LIBTOOL = $(SHELL) $(top_builddir)/libtool +LN_S = ln -s +MAKEINFO = makeinfo +NM = /usr/bin/nm -B +PACKAGE = js +PGCC_BY_PROVENZANO = +RANLIB = ranlib +U = +VERSION = 0.2.5 +XLC_R_AIX = + +SUBDIRS = tests + +JSCOMPILER = ../src/js +JSCOMPILER_FLAGS = -Wpedantic -O2 + +JSS = defs.js lexer.js parser.js gram.js namespace.js \ + streams.js asm.js entry.js +JSCS = defs.jsc lexer.jsc parser.jsc gram.jsc namespace.jsc \ + streams.jsc asm.jsc entry.jsc + +EXTRA_DIST = $(JSS) $(JSCS) bs.js bs.jsc compiler.js compiler.jsc + +SUFFIXES = .jsc .js +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../jsconfig.h +CONFIG_CLEAN_FILES = +DIST_COMMON = ChangeLog Makefile.am Makefile.in TODO + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP = --best +all: all-recursive all-am + +.SUFFIXES: +.SUFFIXES: .js .jsc +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps jsc/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. + + + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + target=`echo $@ | sed s/-recursive//`; \ + echo "Making $$target in $$subdir"; \ + (cd $$subdir && $(MAKE) $$target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + done; \ + for subdir in $$rev; do \ + target=`echo $@ | sed s/-recursive//`; \ + echo "Making $$target in $$subdir"; \ + (cd $$subdir && $(MAKE) $$target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + (cd $$subdir && $(MAKE) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = jsc + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done + for subdir in $(SUBDIRS); do \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + done +info: info-recursive +dvi: dvi-recursive +check: all-am + $(MAKE) check-recursive +installcheck: installcheck-recursive +all-am: Makefile + +install-exec: install-exec-recursive + @$(NORMAL_INSTALL) + +install-data: install-data-recursive + @$(NORMAL_INSTALL) + +install: install-recursive + @: + +uninstall: uninstall-recursive + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: installdirs-recursive + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean-am: mostlyclean-tags mostlyclean-generic + +clean-am: clean-tags clean-generic mostlyclean-am + +distclean-am: distclean-tags distclean-generic clean-am + +maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \ + distclean-am + +mostlyclean: mostlyclean-recursive mostlyclean-am + +clean: clean-recursive clean-am + +distclean: distclean-recursive distclean-am + -rm -f config.status + -rm -f libtool + +maintainer-clean: maintainer-clean-recursive maintainer-clean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +.PHONY: install-data-recursive uninstall-data-recursive \ +install-exec-recursive uninstall-exec-recursive installdirs-recursive \ +uninstalldirs-recursive all-recursive check-recursive \ +installcheck-recursive info-recursive dvi-recursive \ +mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info dvi \ +installcheck all-am install-exec install-data install uninstall all \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +compile: $(JSCS) bs.jsc + +compiler: compiler.jsc + +compiler.jsc: compiler.js + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -c $< + cp compiler.jsc bak/compiler-`date | sed 's/ /-/g'`.jsc || true + +compiler.js: $(JSS) + cat $(JSS) >compiler.js + +run: compile + $(JSCOMPILER) --load $(JSCS) --file bs.jsc + +wc: + wc $(JSS) + +my-clean: + rm -f $(JSCS) bs.jsc + +.js.jsc: + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -g -c $< + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/reactos/lib/kjs/jsc/Makefile.am b/reactos/lib/kjs/jsc/Makefile.am new file mode 100644 index 00000000000..14ff324f542 --- /dev/null +++ b/reactos/lib/kjs/jsc/Makefile.am @@ -0,0 +1,60 @@ +# +# Automakefile for JavaScript JavaScript compiler. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + +SUBDIRS = tests + +JSCOMPILER = ../src/js +JSCOMPILER_FLAGS = -Wpedantic -O2 + +JSS = defs.js lexer.js parser.js gram.js namespace.js \ + streams.js asm.js entry.js +JSCS = defs.jsc lexer.jsc parser.jsc gram.jsc namespace.jsc \ + streams.jsc asm.jsc entry.jsc + +EXTRA_DIST = $(JSS) $(JSCS) bs.js bs.jsc compiler.js compiler.jsc + +compile: $(JSCS) bs.jsc + +compiler: compiler.jsc + +compiler.jsc: compiler.js + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -c $< + cp compiler.jsc bak/compiler-`date | sed 's/ /-/g'`.jsc || true + +compiler.js: $(JSS) + cat $(JSS) >compiler.js + +run: compile + $(JSCOMPILER) --load $(JSCS) --file bs.jsc + +wc: + wc $(JSS) + +my-clean: + rm -f $(JSCS) bs.jsc + +SUFFIXES = .jsc .js + +.js.jsc: + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -g -c $< diff --git a/reactos/lib/kjs/jsc/Makefile.in b/reactos/lib/kjs/jsc/Makefile.in new file mode 100644 index 00000000000..5b8b257a90a --- /dev/null +++ b/reactos/lib/kjs/jsc/Makefile.in @@ -0,0 +1,318 @@ +# Makefile.in generated automatically by automake 1.3 from Makefile.am + +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Automakefile for JavaScript JavaScript compiler. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + + +SHELL = /bin/sh + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DISTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_FLAGS_FOR_LIBTOOL = @ACLOCAL_FLAGS_FOR_LIBTOOL@ +CC = @CC@ +CPP = @CPP@ +EXTENSIONS = @EXTENSIONS@ +EXTENSIONS_LIBS = @EXTENSIONS_LIBS@ +INTERPRETER_FEATURES = @INTERPRETER_FEATURES@ +LD = @LD@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +NM = @NM@ +PACKAGE = @PACKAGE@ +PGCC_BY_PROVENZANO = @PGCC_BY_PROVENZANO@ +RANLIB = @RANLIB@ +U = @U@ +VERSION = @VERSION@ +XLC_R_AIX = @XLC_R_AIX@ + +SUBDIRS = tests + +JSCOMPILER = ../src/js +JSCOMPILER_FLAGS = -Wpedantic -O2 + +JSS = defs.js lexer.js parser.js gram.js namespace.js \ + streams.js asm.js entry.js +JSCS = defs.jsc lexer.jsc parser.jsc gram.jsc namespace.jsc \ + streams.jsc asm.jsc entry.jsc + +EXTRA_DIST = $(JSS) $(JSCS) bs.js bs.jsc compiler.js compiler.jsc + +SUFFIXES = .jsc .js +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../jsconfig.h +CONFIG_CLEAN_FILES = +DIST_COMMON = ChangeLog Makefile.am Makefile.in TODO + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP = --best +all: all-recursive all-am + +.SUFFIXES: +.SUFFIXES: .js .jsc +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps jsc/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. + +@SET_MAKE@ + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + target=`echo $@ | sed s/-recursive//`; \ + echo "Making $$target in $$subdir"; \ + (cd $$subdir && $(MAKE) $$target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + done; \ + for subdir in $$rev; do \ + target=`echo $@ | sed s/-recursive//`; \ + echo "Making $$target in $$subdir"; \ + (cd $$subdir && $(MAKE) $$target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + (cd $$subdir && $(MAKE) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = jsc + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done + for subdir in $(SUBDIRS); do \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + done +info: info-recursive +dvi: dvi-recursive +check: all-am + $(MAKE) check-recursive +installcheck: installcheck-recursive +all-am: Makefile + +install-exec: install-exec-recursive + @$(NORMAL_INSTALL) + +install-data: install-data-recursive + @$(NORMAL_INSTALL) + +install: install-recursive + @: + +uninstall: uninstall-recursive + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: installdirs-recursive + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean-am: mostlyclean-tags mostlyclean-generic + +clean-am: clean-tags clean-generic mostlyclean-am + +distclean-am: distclean-tags distclean-generic clean-am + +maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \ + distclean-am + +mostlyclean: mostlyclean-recursive mostlyclean-am + +clean: clean-recursive clean-am + +distclean: distclean-recursive distclean-am + -rm -f config.status + -rm -f libtool + +maintainer-clean: maintainer-clean-recursive maintainer-clean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +.PHONY: install-data-recursive uninstall-data-recursive \ +install-exec-recursive uninstall-exec-recursive installdirs-recursive \ +uninstalldirs-recursive all-recursive check-recursive \ +installcheck-recursive info-recursive dvi-recursive \ +mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info dvi \ +installcheck all-am install-exec install-data install uninstall all \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +compile: $(JSCS) bs.jsc + +compiler: compiler.jsc + +compiler.jsc: compiler.js + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -c $< + cp compiler.jsc bak/compiler-`date | sed 's/ /-/g'`.jsc || true + +compiler.js: $(JSS) + cat $(JSS) >compiler.js + +run: compile + $(JSCOMPILER) --load $(JSCS) --file bs.jsc + +wc: + wc $(JSS) + +my-clean: + rm -f $(JSCS) bs.jsc + +.js.jsc: + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -g -c $< + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/reactos/lib/kjs/jsc/TODO b/reactos/lib/kjs/jsc/TODO new file mode 100644 index 00000000000..11ef9c61357 --- /dev/null +++ b/reactos/lib/kjs/jsc/TODO @@ -0,0 +1,24 @@ + + TODO JavaScript JavaScript Compiler + +* General + + - clean up the compiler source + +* Optimizations + + - Improve constant folding: type conversions, expr_multiplicative, + expr_shift, expr_relational, expr_bitwise, etc. + + - create type-specified virtual machine operands for +, -, *, + etc. and use them if the types are known. See JSC$stmt_if_asm() + for an example. + + - delete_{property,array} => delete_{property,array} + pop + const_undefined + +* parser.js + + - 7.8 Sharp Variables + - and more??? diff --git a/reactos/lib/kjs/jsc/asm.js b/reactos/lib/kjs/jsc/asm.js new file mode 100644 index 00000000000..be22b8b0795 --- /dev/null +++ b/reactos/lib/kjs/jsc/asm.js @@ -0,0 +1,2287 @@ +/* + * JavaScript Assembler. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsc/asm.js,v $ + * $Id: asm.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* Byte-code file definitions. */ + +JSC$BC_MAGIC = 0xc0014a53; + +JSC$BC_SECT_CODE = 0; +JSC$BC_SECT_CONSTANTS = 1; +JSC$BC_SECT_SYMTAB = 2; +JSC$BC_SECT_DEBUG = 3; + +JSC$CONST_INT = 3; +JSC$CONST_STRING = 4; +JSC$CONST_FLOAT = 5; +JSC$CONST_SYMBOL = 10; +JSC$CONST_REGEXP = 11; +JSC$CONST_NAN = 13; + +JSC$CONST_REGEXP_FLAG_G = 0x01; +JSC$CONST_REGEXP_FLAG_I = 0x02; + +JSC$DEBUG_FILENAME = 1; +JSC$DEBUG_LINENUMBER = 2; + +/* Opcode definitions. */ + +JSC$OP_HALT = 0; +JSC$OP_DONE = 1; +JSC$OP_NOP = 2; +JSC$OP_DUP = 3; +JSC$OP_POP = 4; +JSC$OP_POP_N = 5; +JSC$OP_APOP = 6; +JSC$OP_SWAP = 7; +JSC$OP_ROLL = 8; +JSC$OP_CONST = 9; +JSC$OP_CONST_NULL = 10; +JSC$OP_CONST_TRUE = 11; +JSC$OP_CONST_FALSE = 12; +JSC$OP_CONST_UNDEFINED = 13; +JSC$OP_CONST_I0 = 14; +JSC$OP_CONST_I1 = 15; +JSC$OP_CONST_I2 = 16; +JSC$OP_CONST_I3 = 17; +JSC$OP_CONST_I = 18; +JSC$OP_LOAD_GLOBAL = 19; +JSC$OP_STORE_GLOBAL = 20; +JSC$OP_LOAD_ARG = 21; +JSC$OP_STORE_ARG = 22; +JSC$OP_LOAD_LOCAL = 23; +JSC$OP_STORE_LOCAL = 24; +JSC$OP_LOAD_PROPERTY = 25; +JSC$OP_STORE_PROPERTY = 26; +JSC$OP_LOAD_ARRAY = 27; +JSC$OP_STORE_ARRAY = 28; +JSC$OP_NTH = 29; +JSC$OP_CMP_EQ = 30; +JSC$OP_CMP_NE = 31; +JSC$OP_CMP_LT = 32; +JSC$OP_CMP_GT = 33; +JSC$OP_CMP_LE = 34; +JSC$OP_CMP_GE = 35; +JSC$OP_CMP_SEQ = 36; +JSC$OP_CMP_SNE = 37; +JSC$OP_SUB = 38; +JSC$OP_ADD = 39; +JSC$OP_MUL = 40; +JSC$OP_DIV = 41; +JSC$OP_MOD = 42; +JSC$OP_NEG = 43; +JSC$OP_AND = 44; +JSC$OP_NOT = 45; +JSC$OP_OR = 46; +JSC$OP_XOR = 47; +JSC$OP_SHIFT_LEFT = 48; +JSC$OP_SHIFT_RIGHT = 49; +JSC$OP_SHIFT_RRIGHT = 50; +JSC$OP_IFFALSE = 51; +JSC$OP_IFTRUE = 52; +JSC$OP_CALL_METHOD = 53; +JSC$OP_JMP = 54; +JSC$OP_JSR = 55; +JSC$OP_RETURN = 56; +JSC$OP_TYPEOF = 57; +JSC$OP_NEW = 58; +JSC$OP_DELETE_PROPERTY = 59; +JSC$OP_DELETE_ARRAY = 60; +JSC$OP_LOCALS = 61; +JSC$OP_MIN_ARGS = 62; +JSC$OP_LOAD_NTH_ARG = 63; +JSC$OP_WITH_PUSH = 64; +JSC$OP_WITH_POP = 65; +JSC$OP_TRY_PUSH = 66; +JSC$OP_TRY_POP = 67; +JSC$OP_THROW = 68; + +/* Type aware operands. */ +JSC$OP_IFFALSE_B = 69; +JSC$OP_IFTRUE_B = 70; +JSC$OP_ADD_1_I = 71; +JSC$OP_ADD_2_I = 72; +JSC$OP_LOAD_GLOBAL_W = 73; +JSC$OP_JSR_W = 74; + +/* Internal values. */ +JSC$ASM_SYMBOL = 1000; +JSC$ASM_LABEL = 1001; + +/* + * General helpers. + */ + +/* Generate byte-code for operands with Int8 value. */ +function JSC$ASM_bytecode_int8 () +{ + return String.pack ("C", this.value); +} + +/* Generate byte-code for operands with Int16 value. */ +function JSC$ASM_bytecode_int16 () +{ + return String.pack ("n", this.value); +} + +/* Generate byte-code for operands with Int32 value. */ +function JSC$ASM_bytecode_int32 () +{ + return String.pack ("N", this.value); +} + +/* Generate byte-code for operands with Symbol value. */ +function JSC$ASM_bytecode_symbol () +{ + var cid = JSC$asm_genconstant (String.pack ("C", JSC$CONST_SYMBOL) + + this.value + String.pack ("C", 0)); + return String.pack ("N", cid); +} + +/* Generate byte-code for local jump operands. */ +function JSC$ASM_bytecode_local_jump () +{ + var delta = this.value.offset - (this.offset + this.size); + return String.pack ("N", delta); +} + + +/* + * Assembler operands. + */ + +/* Symbol. */ + +function JSC$ASM_symbol (ln, value) +{ + this.type = JSC$ASM_SYMBOL; + this.linenum = ln; + this.value = value; + this.size = 0; + this.print = JSC$ASM_symbol_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_symbol_print (stream) +{ + stream.write ("\n" + this.value + ":\n"); +} + +/* Label */ + +function JSC$ASM_label () +{ + this.type = JSC$ASM_LABEL; + this.linenum = 0; + this.size = 0; + this.value = JSC$asm_label_count++; + this.referenced = false; + this.next = null; + this.print = JSC$ASM_label_print; + this.link = JSC$asm_link; + this.format = JSC$ASM_label_format; +} + +function JSC$ASM_label_print (stream) +{ + stream.write (this.format () + ":\n"); +} + +function JSC$ASM_label_format () +{ + return ".L" + this.value.toString (); +} + +/* halt */ + +function JSC$ASM_halt (ln) +{ + this.type = JSC$OP_HALT; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_halt_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_halt_print (stream) +{ + stream.write ("\thalt\n"); +} + +/* done */ + +function JSC$ASM_done (ln) +{ + this.type = JSC$OP_DONE; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_done_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_done_print (stream) +{ + stream.write ("\tdone\n"); +} + +/* nop */ + +function JSC$ASM_nop (ln) +{ + this.type = JSC$OP_NOP; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_nop_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_nop_print (stream) +{ + stream.write ("\tnop\n"); +} + +/* dup */ + +function JSC$ASM_dup (ln) +{ + this.type = JSC$OP_DUP; + this.linenum = ln; + this.stack_delta = 1; + this.size = 1; + this.print = JSC$ASM_dup_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_dup_print (stream) +{ + stream.write ("\tdup\n"); +} + +/* pop */ + +function JSC$ASM_pop (ln) +{ + this.type = JSC$OP_POP; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_pop_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_pop_print (stream) +{ + stream.write ("\tpop\n"); +} + +/* pop_n */ + +function JSC$ASM_pop_n (ln, value) +{ + this.type = JSC$OP_POP_N; + this.linenum = ln; + this.value = value; + this.stack_delta = -value; + this.size = 2; + this.print = JSC$ASM_pop_n_print; + this.link = JSC$asm_link; + this.bytecode = JSC$ASM_bytecode_int8; +} + +function JSC$ASM_pop_n_print (stream) +{ + stream.write ("\tpop_n\t\t" + this.value.toString () + "\n"); +} + +/* apop */ + +function JSC$ASM_apop (ln, value) +{ + this.type = JSC$OP_APOP; + this.linenum = ln; + this.value = value; + this.stack_delta = -value; + this.size = 2; + this.print = JSC$ASM_apop_print; + this.link = JSC$asm_link; + this.bytecode = JSC$ASM_bytecode_int8; +} + +function JSC$ASM_apop_print (stream) +{ + stream.write ("\tapop\t\t" + this.value.toString () + "\n"); +} + +/* swap */ + +function JSC$ASM_swap (ln) +{ + this.type = JSC$OP_SWAP; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_swap_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_swap_print (stream) +{ + stream.write ("\tswap\n"); +} + +/* roll */ +function JSC$ASM_roll (ln, value) +{ + this.type = JSC$OP_ROLL; + this.linenum = ln; + this.value = value; + this.size = 2; + this.print = JSC$ASM_roll_print; + this.link = JSC$asm_link; + this.bytecode = JSC$ASM_bytecode_int8; +} + +function JSC$ASM_roll_print (stream) +{ + stream.write ("\troll\t\t" + this.value.toString () + "\n"); +} + +/* const */ + +function JSC$ASM_const (ln, value) +{ + this.type = JSC$OP_CONST; + this.linenum = ln; + this.value = value; + this.stack_delta = 1; + this.size = 5; + this.print = JSC$ASM_const_print; + this.link = JSC$asm_link; + this.bytecode = JSC$ASM_const_bytecode; +} + +function JSC$ASM_const_print (stream) +{ + if (typeof this.value == "number") + stream.write ("\tconst\t\t" + this.value.toString () + "\n"); + else if (typeof this.value == "string" + || typeof this.value == "#builtin") + { + var i, c; + var ender, src; + var stringp = (typeof this.value == "string"); + + if (stringp) + { + ender = "\""; + src = this.value; + } + else + { + ender = "/"; + src = this.value.source; + } + + stream.write ("\tconst\t\t" + ender); + for (i = 0; i < src.length; i++) + { + c = src.charCodeAt (i); + if (c == ender[0] || c == #'\\') + stream.write ("\\" + src.charAt (i)); + else if (c == #'\n') + stream.write ("\\n"); + else if (c == #'\r') + stream.write ("\\r"); + else if (c == #'\t') + stream.write ("\\t"); + else if (c == #'\f') + stream.write ("\\f"); + else + stream.write (src.charAt (i)); + } + stream.write (ender); + + if (!stringp) + { + if (this.value.global) + stream.write ("g"); + if (this.value.ignoreCase) + stream.write ("i"); + } + + stream.write ("\n"); + } +} + +function JSC$ASM_const_bytecode () +{ + var cid; + + if (typeof this.value == "number") + { + if (isInt (this.value)) + cid = JSC$asm_genconstant (String.pack ("CN", JSC$CONST_INT, + this.value)); + else if (isFloat (this.value)) + cid = JSC$asm_genconstant (String.pack ("Cd", JSC$CONST_FLOAT, + this.value)); + else + cid = JSC$asm_genconstant (String.pack ("C", JSC$CONST_NAN)); + } + else if (typeof this.value == "string") + cid = JSC$asm_genconstant (String.pack ("CN", JSC$CONST_STRING, + this.value.length) + + this.value); + else if (typeof this.value == "#builtin") + { + /* Regular expression. */ + var flags = 0; + + if (this.value.global) + flags |= JSC$CONST_REGEXP_FLAG_G; + if (this.value.ignoreCase) + flags |= JSC$CONST_REGEXP_FLAG_I; + + cid = JSC$asm_genconstant (String.pack ("CCN", JSC$CONST_REGEXP, flags, + this.value.source.length) + + this.value.source); + } + else + error ("ASM_const_bytecode(): unknown type: " + typeof this.value); + + return String.pack ("N", cid); +} + +/* const_null */ + +function JSC$ASM_const_null (ln) +{ + this.type = JSC$OP_CONST_NULL; + this.linenum = ln; + this.stack_delta = 1; + this.size = 1; + this.print = JSC$ASM_const_null_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_const_null_print (stream) +{ + stream.write ("\tconst_null\n"); +} + +/* const_true */ + +function JSC$ASM_const_true (ln) +{ + this.type = JSC$OP_CONST_TRUE; + this.linenum = ln; + this.stack_delta = 1; + this.size = 1; + this.print = JSC$ASM_const_true_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_const_true_print (stream) +{ + stream.write ("\tconst_true\n"); +} + +/* const_false */ + +function JSC$ASM_const_false (ln) +{ + this.type = JSC$OP_CONST_FALSE; + this.linenum = ln; + this.stack_delta = 1; + this.size = 1; + this.print = JSC$ASM_const_false_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_const_false_print (stream) +{ + stream.write ("\tconst_false\n"); +} + +/* const_undefined */ + +function JSC$ASM_const_undefined (ln) +{ + this.type = JSC$OP_CONST_UNDEFINED; + this.linenum = ln; + this.stack_delta = 1; + this.size = 1; + this.print = JSC$ASM_const_undefined_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_const_undefined_print (stream) +{ + stream.write ("\tconst_undefined\n"); +} + +/* const_i0 */ + +function JSC$ASM_const_i0 (ln) +{ + this.type = JSC$OP_CONST_I0; + this.linenum = ln; + this.stack_delta = 1; + this.size = 1; + this.print = JSC$ASM_const_i0_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_const_i0_print (stream) +{ + stream.write ("\tconst_i0\n"); +} + +/* const_i1 */ + +function JSC$ASM_const_i1 (ln) +{ + this.type = JSC$OP_CONST_I1; + this.linenum = ln; + this.stack_delta = 1; + this.size = 1; + this.print = JSC$ASM_const_i1_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_const_i1_print (stream) +{ + stream.write ("\tconst_i1\n"); +} + +/* const_i2 */ + +function JSC$ASM_const_i2 (ln) +{ + this.type = JSC$OP_CONST_I2; + this.linenum = ln; + this.stack_delta = 1; + this.size = 1; + this.print = JSC$ASM_const_i2_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_const_i2_print (stream) +{ + stream.write ("\tconst_i2\n"); +} + +/* const_i3 */ + +function JSC$ASM_const_i3 (ln) +{ + this.type = JSC$OP_CONST_I3; + this.linenum = ln; + this.stack_delta = 1; + this.size = 1; + this.print = JSC$ASM_const_i3_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_const_i3_print (stream) +{ + stream.write ("\tconst_i3\n"); +} + +/* const_i */ + +function JSC$ASM_const_i (ln, value) +{ + this.type = JSC$OP_CONST_I; + this.linenum = ln; + this.value = value; + this.stack_delta = 1; + this.size = 5; + this.print = JSC$ASM_const_i_print; + this.bytecode = JSC$ASM_bytecode_int32; + this.link = JSC$asm_link; +} + +function JSC$ASM_const_i_print (stream) +{ + stream.write ("\tconst_i\t\t" + this.value.toString () + "\n"); +} + +/* load_global */ + +function JSC$ASM_load_global (ln, value) +{ + this.type = JSC$OP_LOAD_GLOBAL; + this.linenum = ln; + this.value = value; + this.stack_delta = 1; + this.size = 5; + this.print = JSC$ASM_load_global_print; + this.bytecode = JSC$ASM_bytecode_symbol; + this.link = JSC$asm_link; +} + +function JSC$ASM_load_global_print (stream) +{ + stream.write ("\tload_global\t" + this.value + "\n"); +} + +/* store_global */ + +function JSC$ASM_store_global (ln, value) +{ + this.type = JSC$OP_STORE_GLOBAL; + this.linenum = ln; + this.value = value; + this.stack_delta = -1; + this.size = 5; + this.print = JSC$ASM_store_global_print; + this.bytecode = JSC$ASM_bytecode_symbol; + this.link = JSC$asm_link; +} + +function JSC$ASM_store_global_print (stream) +{ + stream.write ("\tstore_global\t" + this.value + "\n"); +} + +/* load_arg */ + +function JSC$ASM_load_arg (ln, value) +{ + this.type = JSC$OP_LOAD_ARG; + this.linenum = ln; + this.value = value; + this.stack_delta = 1; + this.size = 2; + this.print = JSC$ASM_load_arg_print; + this.bytecode = JSC$ASM_bytecode_int8; + this.link = JSC$asm_link; +} + +function JSC$ASM_load_arg_print (stream) +{ + stream.write ("\tload_arg\t" + this.value.toString () + "\n"); +} + +/* store_arg */ + +function JSC$ASM_store_arg (ln, value) +{ + this.type = JSC$OP_STORE_ARG; + this.linenum = ln; + this.value = value; + this.stack_delta = -1; + this.size = 2; + this.print = JSC$ASM_store_arg_print; + this.bytecode = JSC$ASM_bytecode_int8; + this.link = JSC$asm_link; +} + +function JSC$ASM_store_arg_print (stream) +{ + stream.write ("\tstore_arg\t" + this.value.toString () + "\n"); +} + +/* load_local */ + +function JSC$ASM_load_local (ln, value) +{ + this.type = JSC$OP_LOAD_LOCAL; + this.linenum = ln; + this.value = value; + this.stack_delta = 1; + this.size = 3; + this.print = JSC$ASM_load_local_print; + this.bytecode = JSC$ASM_bytecode_int16; + this.link = JSC$asm_link; +} + +function JSC$ASM_load_local_print (stream) +{ + stream.write ("\tload_local\t" + this.value.toString () + "\n"); +} + +/* store_local */ + +function JSC$ASM_store_local (ln, value) +{ + this.type = JSC$OP_STORE_LOCAL; + this.linenum = ln; + this.value = value; + this.stack_delta = -1; + this.size = 3; + this.print = JSC$ASM_store_local_print; + this.bytecode = JSC$ASM_bytecode_int16; + this.link = JSC$asm_link; +} + +function JSC$ASM_store_local_print (stream) +{ + stream.write ("\tstore_local\t" + this.value.toString () + "\n"); +} + +/* load_property */ + +function JSC$ASM_load_property (ln, value) +{ + this.type = JSC$OP_LOAD_PROPERTY; + this.linenum = ln; + this.value = value; + this.size = 5; + this.print = JSC$ASM_load_property_print; + this.bytecode = JSC$ASM_bytecode_symbol; + this.link = JSC$asm_link; +} + +function JSC$ASM_load_property_print (stream) +{ + stream.write ("\tload_property\t" + this.value + "\n"); +} + +/* store_property */ + +function JSC$ASM_store_property (ln, value) +{ + this.type = JSC$OP_STORE_PROPERTY; + this.linenum = ln; + this.value = value; + this.stack_delta = -2; + this.size = 5; + this.print = JSC$ASM_store_property_print; + this.bytecode = JSC$ASM_bytecode_symbol; + this.link = JSC$asm_link; +} + +function JSC$ASM_store_property_print (stream) +{ + stream.write ("\tstore_property\t" + this.value + "\n"); +} + +/* load_array */ + +function JSC$ASM_load_array (ln) +{ + this.type = JSC$OP_LOAD_ARRAY; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_load_array_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_load_array_print (stream) +{ + stream.write ("\tload_array\n"); +} + +/* store_array */ + +function JSC$ASM_store_array (ln) +{ + this.type = JSC$OP_STORE_ARRAY; + this.linenum = ln; + this.stack_delta = -3; + this.size = 1; + this.print = JSC$ASM_store_array_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_store_array_print (stream) +{ + stream.write ("\tstore_array\n"); +} + +/* nth */ + +function JSC$ASM_nth (ln) +{ + this.type = JSC$OP_NTH; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_nth_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_nth_print (stream) +{ + stream.write ("\tnth\n"); +} + +/* cmp_eq */ + +function JSC$ASM_cmp_eq (ln) +{ + this.type = JSC$OP_CMP_EQ; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_cmp_eq_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_cmp_eq_print (stream) +{ + stream.write ("\tcmp_eq\n"); +} + +/* cmp_ne */ + +function JSC$ASM_cmp_ne (ln) +{ + this.type = JSC$OP_CMP_NE; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_cmp_ne_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_cmp_ne_print (stream) +{ + stream.write ("\tcmp_ne\n"); +} + +/* cmp_lt */ + +function JSC$ASM_cmp_lt (ln) +{ + this.type = JSC$OP_CMP_LT; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_cmp_lt_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_cmp_lt_print (stream) +{ + stream.write ("\tcmp_lt\n"); +} + +/* cmp_gt */ + +function JSC$ASM_cmp_gt (ln) +{ + this.type = JSC$OP_CMP_GT; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_cmp_gt_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_cmp_gt_print (stream) +{ + stream.write ("\tcmp_gt\n"); +} + +/* cmp_le */ + +function JSC$ASM_cmp_le (ln) +{ + this.type = JSC$OP_CMP_LE; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_cmp_le_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_cmp_le_print (stream) +{ + stream.write ("\tcmp_le\n"); +} + +/* cmp_ge */ + +function JSC$ASM_cmp_ge (ln) +{ + this.type = JSC$OP_CMP_GE; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_cmp_ge_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_cmp_ge_print (stream) +{ + stream.write ("\tcmp_ge\n"); +} + +/* cmp_seq */ + +function JSC$ASM_cmp_seq (ln) +{ + this.type = JSC$OP_CMP_SEQ; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_cmp_seq_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_cmp_seq_print (stream) +{ + stream.write ("\tcmp_seq\n"); +} + +/* cmp_sne */ + +function JSC$ASM_cmp_sne (ln) +{ + this.type = JSC$OP_CMP_SNE; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_cmp_sne_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_cmp_sne_print (stream) +{ + stream.write ("\tcmp_sne\n"); +} + +/* sub */ + +function JSC$ASM_sub (ln) +{ + this.type = JSC$OP_SUB; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_sub_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_sub_print (stream) +{ + stream.write ("\tsub\n"); +} + +/* add */ + +function JSC$ASM_add (ln) +{ + this.type = JSC$OP_ADD; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_add_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_add_print (stream) +{ + stream.write ("\tadd\n"); +} + +/* mul */ + +function JSC$ASM_mul (ln) +{ + this.type = JSC$OP_MUL; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_mul_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_mul_print (stream) +{ + stream.write ("\tmul\n"); +} + +/* div */ + +function JSC$ASM_div (ln) +{ + this.type = JSC$OP_DIV; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_div_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_div_print (stream) +{ + stream.write ("\tdiv\n"); +} + +/* mod */ + +function JSC$ASM_mod (ln) +{ + this.type = JSC$OP_MOD; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_mod_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_mod_print (stream) +{ + stream.write ("\tmod\n"); +} + +/* neg */ + +function JSC$ASM_neg (ln) +{ + this.type = JSC$OP_NEG; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_neg_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_neg_print (stream) +{ + stream.write ("\tneg\n"); +} + +/* and */ + +function JSC$ASM_and (ln) +{ + this.type = JSC$OP_AND; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_and_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_and_print (stream) +{ + stream.write ("\tand\n"); +} + +/* not */ + +function JSC$ASM_not (ln) +{ + this.type = JSC$OP_NOT; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_not_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_not_print (stream) +{ + stream.write ("\tnot\n"); +} + +/* or */ + +function JSC$ASM_or (ln) +{ + this.type = JSC$OP_OR; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_or_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_or_print (stream) +{ + stream.write ("\tor\n"); +} + +/* xor */ + +function JSC$ASM_xor (ln) +{ + this.type = JSC$OP_XOR; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_xor_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_xor_print (stream) +{ + stream.write ("\txor\n"); +} + +/* shift_left */ + +function JSC$ASM_shift_left (ln) +{ + this.type = JSC$OP_SHIFT_LEFT; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_shift_left_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_shift_left_print (stream) +{ + stream.write ("\tshift_left\n"); +} + +/* shift_right */ + +function JSC$ASM_shift_right (ln) +{ + this.type = JSC$OP_SHIFT_RIGHT; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_shift_right_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_shift_right_print (stream) +{ + stream.write ("\tshift_right\n"); +} + +/* shift_rright */ + +function JSC$ASM_shift_rright (ln) +{ + this.type = JSC$OP_SHIFT_RRIGHT; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_shift_rright_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_shift_rright_print (stream) +{ + stream.write ("\tshift_rright\n"); +} + +/* iffalse */ + +function JSC$ASM_iffalse (ln, value) +{ + this.type = JSC$OP_IFFALSE; + this.linenum = ln; + this.value = value; + this.stack_delta = -1; + this.size = 5; + this.print = JSC$ASM_iffalse_print; + this.bytecode = JSC$ASM_bytecode_local_jump; + this.link = JSC$asm_link; +} + +function JSC$ASM_iffalse_print (stream) +{ + stream.write ("\tiffalse\t\t" + this.value.format () + "\n"); +} + +/* iftrue */ + +function JSC$ASM_iftrue (ln, value) +{ + this.type = JSC$OP_IFTRUE; + this.linenum = ln; + this.value = value; + this.stack_delta = -1; + this.size = 5; + this.print = JSC$ASM_iftrue_print; + this.bytecode = JSC$ASM_bytecode_local_jump; + this.link = JSC$asm_link; +} + +function JSC$ASM_iftrue_print (stream) +{ + stream.write ("\tiftrue\t\t" + this.value.format () + "\n"); +} + +/* call_method */ + +function JSC$ASM_call_method (ln, value) +{ + this.type = JSC$OP_CALL_METHOD; + this.linenum = ln; + this.value = value; + this.stack_delta = 1; + this.size = 5; + this.print = JSC$ASM_call_method_print; + this.bytecode = JSC$ASM_bytecode_symbol; + this.link = JSC$asm_link; +} + +function JSC$ASM_call_method_print (stream) +{ + stream.write ("\tcall_method\t" + this.value + "\n"); +} + +/* jmp */ + +function JSC$ASM_jmp (ln, value) +{ + this.type = JSC$OP_JMP; + this.linenum = ln; + this.value = value; + this.size = 5; + this.print = JSC$ASM_jmp_print; + this.bytecode = JSC$ASM_bytecode_local_jump; + this.link = JSC$asm_link; +} + +function JSC$ASM_jmp_print (stream) +{ + stream.write ("\tjmp\t\t" + this.value.format () + "\n"); +} + +/* jsr */ + +function JSC$ASM_jsr (ln) +{ + this.type = JSC$OP_JSR; + this.linenum = ln; + this.stack_delta = 1; + this.size = 1; + this.print = JSC$ASM_jsr_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_jsr_print (stream) +{ + stream.write ("\tjsr\n"); +} + +/* return */ + +function JSC$ASM_return (ln) +{ + this.type = JSC$OP_RETURN; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_return_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_return_print (stream) +{ + stream.write ("\treturn\n"); +} + +/* typeof */ + +function JSC$ASM_typeof (ln) +{ + this.type = JSC$OP_TYPEOF; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_typeof_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_typeof_print (stream) +{ + stream.write ("\ttypeof\n"); +} + +/* new */ + +function JSC$ASM_new (ln) +{ + this.type = JSC$OP_NEW; + this.linenum = ln; + this.stack_delta = 1; + this.size = 1; + this.print = JSC$ASM_new_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_new_print (stream) +{ + stream.write ("\tnew\n"); +} + +/* delete_property */ + +function JSC$ASM_delete_property (ln, value) +{ + this.type = JSC$OP_DELETE_PROPERTY; + this.linenum = ln; + this.value = value; + this.size = 5; + this.print = JSC$ASM_delete_property_print; + this.bytecode = JSC$ASM_bytecode_symbol; + this.link = JSC$asm_link; +} + +function JSC$ASM_delete_property_print (stream) +{ + stream.write ("\tdelete_property\t" + this.value + "\n"); +} + +/* delete_array */ + +function JSC$ASM_delete_array (ln) +{ + this.type = JSC$OP_DELETE_ARRAY; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_delete_array_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_delete_array_print (stream) +{ + stream.write ("\tdelete_array\n"); +} + +/* locals */ + +function JSC$ASM_locals (ln, value) +{ + this.type = JSC$OP_LOCALS; + this.linenum = ln; + this.value = value; + this.stack_delta = value; + this.size = 3; + this.print = JSC$ASM_locals_print; + this.bytecode = JSC$ASM_bytecode_int16; + this.link = JSC$asm_link; +} + +function JSC$ASM_locals_print (stream) +{ + stream.write ("\tlocals\t\t" + this.value.toString () + "\n"); +} + +/* min_args */ + +function JSC$ASM_min_args (ln, value) +{ + this.type = JSC$OP_MIN_ARGS; + this.linenum = ln; + this.value = value; + this.stack_delta = -1; + this.size = 2; + this.print = JSC$ASM_min_args_print; + this.bytecode = JSC$ASM_bytecode_int8; + this.link = JSC$asm_link; +} + +function JSC$ASM_min_args_print (stream) +{ + stream.write ("\tmin_args\t" + this.value.toString () + "\n"); +} + +/* load_nth_arg */ + +function JSC$ASM_load_nth_arg (ln) +{ + this.type = JSC$OP_LOAD_NTH_ARG; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_load_nth_arg_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_load_nth_arg_print (stream) +{ + stream.write ("\tload_nth_arg\n"); +} + +/* with_push */ + +function JSC$ASM_with_push (ln) +{ + this.type = JSC$OP_WITH_PUSH; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_with_push_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_with_push_print (stream) +{ + stream.write ("\twith_push\n"); +} + +/* with_pop */ + +function JSC$ASM_with_pop (ln, value) +{ + this.type = JSC$OP_WITH_POP; + this.linenum = ln; + this.value = value; + this.size = 2; + this.print = JSC$ASM_with_pop_print; + this.bytecode = JSC$ASM_bytecode_int8; + this.link = JSC$asm_link; +} + +function JSC$ASM_with_pop_print (stream) +{ + stream.write ("\twith_pop\t" + this.value.toString () + "\n"); +} + +/* try_push */ + +function JSC$ASM_try_push (ln, value) +{ + this.type = JSC$OP_TRY_PUSH; + this.linenum = ln; + this.value = value; + this.size = 5; + this.print = JSC$ASM_try_push_print; + this.bytecode = JSC$ASM_bytecode_local_jump; + this.link = JSC$asm_link; +} + +function JSC$ASM_try_push_print (stream) +{ + stream.write ("\ttry_push\t" + this.value.format () + "\n"); +} + +/* try_pop */ + +function JSC$ASM_try_pop (ln, value) +{ + this.type = JSC$OP_TRY_POP; + this.linenum = ln; + this.value = value; + this.size = 2; + this.print = JSC$ASM_try_pop_print; + this.bytecode = JSC$ASM_bytecode_int8; + this.link = JSC$asm_link; +} + +function JSC$ASM_try_pop_print (stream) +{ + stream.write ("\ttry_pop\t\t" + this.value.toString () + "\n"); +} + +/* throw */ + +function JSC$ASM_throw (ln) +{ + this.type = JSC$OP_THROW; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_throw_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_throw_print (stream) +{ + stream.write ("\tthrow\n"); +} + +/* iffalse_b */ + +function JSC$ASM_iffalse_b (ln, value) +{ + this.type = JSC$OP_IFFALSE_B; + this.linenum = ln; + this.value = value; + this.stack_delta = -1; + this.size = 5; + this.print = JSC$ASM_iffalse_b_print; + this.bytecode = JSC$ASM_bytecode_local_jump; + this.link = JSC$asm_link; +} + +function JSC$ASM_iffalse_b_print (stream) +{ + stream.write ("\tiffalse_b\t" + this.value.format () + "\n"); +} + +/* iftrue */ + +function JSC$ASM_iftrue_b (ln, value) +{ + this.type = JSC$OP_IFTRUE_B; + this.linenum = ln; + this.value = value; + this.stack_delta = -1; + this.size = 5; + this.print = JSC$ASM_iftrue_b_print; + this.bytecode = JSC$ASM_bytecode_local_jump; + this.link = JSC$asm_link; +} + +function JSC$ASM_iftrue_b_print (stream) +{ + stream.write ("\tiftrue_b\t" + this.value.format () + "\n"); +} + +/* add_1_i */ + +function JSC$ASM_add_1_i (ln) +{ + this.type = JSC$OP_ADD_1_I; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_add_1_i_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_add_1_i_print (stream) +{ + stream.write ("\tadd_1_i\n"); +} + +/* add_2_i */ + +function JSC$ASM_add_2_i (ln) +{ + this.type = JSC$OP_ADD_2_I; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_add_2_i_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_add_2_i_print (stream) +{ + stream.write ("\tadd_2_i\n"); +} + +/* load_global_w */ + +function JSC$ASM_load_global_w (ln, value) +{ + this.type = JSC$OP_LOAD_GLOBAL_W; + this.linenum = ln; + this.value = value; + this.stack_delta = 1; + this.size = 5; + this.print = JSC$ASM_load_global_w_print; + this.bytecode = JSC$ASM_bytecode_symbol; + this.link = JSC$asm_link; +} + +function JSC$ASM_load_global_w_print (stream) +{ + stream.write ("\tload_global_w\t" + this.value + "\n"); +} + +/* jsr_w */ + +function JSC$ASM_jsr_w (ln, value) +{ + this.type = JSC$OP_JSR_W; + this.linenum = ln; + this.value = value; + this.stack_delta = 1; + this.size = 5; + this.print = JSC$ASM_jsr_w_print; + this.bytecode = JSC$ASM_bytecode_symbol; + this.link = JSC$asm_link; +} + +function JSC$ASM_jsr_w_print (stream) +{ + stream.write ("\tjsr_w\t\t" + this.value + "\n"); +} + +/* + * General helpers. + */ + +function JSC$asm_link () +{ + this.next = null; + + if (JSC$asm_tail != null) + { + JSC$asm_tail_prev = JSC$asm_tail; + JSC$asm_tail.next = this; + } + else + JSC$asm_head = this; + + JSC$asm_tail = this; +} + + +/* + * The phases of the assembler. + */ + +/* This is called from the compiler initialization code. */ +function JSC$asm_reset () +{ + JSC$asm_label_count = 1; + JSC$asm_head = JSC$asm_tail = JSC$asm_tail_prev = null; + JSC$asm_constcount = 0; + JSC$asm_constants = null; + JSC$asm_known_constants = null; +} + + +function JSC$asm_generate () +{ + var i; + + if (JSC$verbose) + JSC$message ("jsc: generating assembler"); + + JSC$ns = new JSC$NameSpace (); + + /* Functions. */ + for (i = 0; i < JSC$functions.length; i++) + JSC$functions[i].asm (); + + /* Global statements. */ + if (JSC$global_stmts.length > 0) + { + /* Define the `.global' symbol. */ + new JSC$ASM_symbol (JSC$global_stmts[0].linenum, ".global").link (); + + /* Handle local variables. */ + var num_locals = JSC$count_locals_from_stmt_list (JSC$global_stmts); + if (num_locals > 0) + new JSC$ASM_locals (JSC$global_stmts[0].linenum, num_locals).link (); + + /* Generate assembler. */ + for (i = 0; i < JSC$global_stmts.length; i++) + JSC$global_stmts[i].asm (); + + /* + * Fix things so that also the global statement returns something + * (this is required when we use eval() in JavaScript). + */ + if (JSC$asm_tail_prev == null) + { + /* This is probably illegal, but we don't panic. */ + new JSC$ASM_const_undefined (0).link (); + } + else + { + /* + * If the latest op is `pop', remove it. Otherwise, append + * a `const_undefined'. + */ + if (JSC$asm_tail.type == JSC$OP_POP) + { + JSC$asm_tail = JSC$asm_tail_prev; + JSC$asm_tail.next = null; + JSC$asm_tail_prev = null; + } + else + new JSC$ASM_const_undefined (JSC$asm_tail.linenum).link (); + } + } + + JSC$ns = null; +} + + +function JSC$asm_print (src_stream, stream) +{ + var i; + var last_ln; + var annotate = src_stream ? true : false; + + if (annotate) + { + stream.write ("; -*- asm -*-\n"); + + /* Set the prev properties. */ + var prev = null; + for (i = JSC$asm_head; i != null; prev = i, i = i.next) + i.prev = prev; + + /* + * Fix the label line numbers to be the same that the next + * assembler operand has. + */ + last_ln = 0; + for (i = JSC$asm_tail; i != null; i = i.prev) + { + if (i.type == JSC$ASM_LABEL) + i.linenum = last_ln; + else if (typeof i.linenum != "undefined") + last_ln = i.linenum; + } + } + + last_ln = 0; + for (i = JSC$asm_head; i != null; i = i.next) + { + if (typeof i.linenum == "undefined") + { + if (annotate) + stream.write ("; undefined linenum\n"); + } + else + while (annotate && i.linenum > last_ln) + { + var line = src_stream.readln (); + stream.write ("; " + line + "\n"); + last_ln++; + } + + i.print (stream); + } +} + + +function JSC$asm_is_load_op (op) +{ + return (op.type == JSC$OP_LOAD_GLOBAL + || op.type == JSC$OP_LOAD_ARG + || op.type == JSC$OP_LOAD_LOCAL); +} + + +function JSC$asm_is_store_op (op) +{ + return (op.type == JSC$OP_STORE_GLOBAL + || op.type == JSC$OP_STORE_ARG + || op.type == JSC$OP_STORE_LOCAL); +} + + +function JSC$asm_is_local_jump (op) +{ + return (op.type == JSC$OP_JMP + || op.type == JSC$OP_IFFALSE + || op.type == JSC$OP_IFTRUE + || op.type == JSC$OP_IFFALSE_B + || op.type == JSC$OP_IFTRUE_B + || op.type == JSC$OP_TRY_PUSH); +} + + +function JSC$asm_is_const_op (op) +{ + return (JSC$OP_CONST <= op.type && op.type <= JSC$OP_CONST_I3); +} + + +function JSC$asm_lookup_next_op (item) +{ + while (item != null && + (item.type == JSC$ASM_LABEL || item.type == JSC$ASM_SYMBOL)) + item = item.next; + + return item; +} + + +function JSC$asm_optimize (flags) +{ + var item; + + /* Simple peephole optimization. */ + if ((flags & JSC$FLAG_OPTIMIZE_PEEPHOLE) != 0) + { + if (JSC$verbose) + JSC$message ("jsc: optimize: peephole"); + + for (item = JSC$asm_head; item != null; item = item.next) + { + /* + * Optimization for dup ... pop cases where pop removes the + * item duplicated by dup. + */ + if (item.next != null && item.next.type == JSC$OP_DUP) + { + var balance = 2; + var found = false; + var i1; + + for (i1 = item.next.next; + i1 != null && i1.next != null; + i1 = i1.next) + { + var i2 = i1.next; + + /* + * The lookup ends on branches, and on dup, throw, + * and try_pop operands. We optimize on a basic + * block and we match the closest dup-pop pairs. + */ + if (JSC$asm_is_local_jump (i1) + || i1.type == JSC$OP_JSR + || i1.type == JSC$OP_NEW + || i1.type == JSC$OP_CALL_METHOD + || i1.type == JSC$OP_RETURN + || i1.type == JSC$ASM_SYMBOL + || i1.type == JSC$ASM_LABEL + || i1.type == JSC$OP_DUP + || i1.type == JSC$OP_TRY_POP + || i1.type == JSC$OP_THROW) + break; + + if (i1.stack_delta) + { + balance += i1.stack_delta; + if (balance <= 0) + /* Going to negative. Stop here. */ + break; + } + + if (i2.type == JSC$OP_POP && balance == 1) + { + /* Found a matching pop. */ + found = true; + i1.next = i2.next; + break; + } + } + + if (found) + { + /* The dup can be removed. */ + item.next = item.next.next; + } + } + + /* Two instruction optimization (starting from item.next). */ + if (item.next != null && item.next.next != null) + { + var i1 = item.next; + var i2 = i1.next; + + if (i1.type == JSC$OP_APOP + && i2.type == JSC$OP_POP) + { + /* + * i1: apop n + * i2: pop -> pop_n n + 1 + */ + var i = new JSC$ASM_pop_n (i1.linenum, i1.value + 1); + item.next = i; + i.next = i2.next; + } + } + if (item.next != null && item.next.next != null) + { + var i1 = item.next; + var i2 = i1.next; + + if (i1.type == JSC$OP_CONST_TRUE + && (i2.type == JSC$OP_IFFALSE + || i2.type == JSC$OP_IFFALSE_B)) + { + /* + * i1: const_true + * i2: iffalse{,_b} .LX => --- + */ + item.next = i2.next; + } + } + if (item.next != null && item.next.next != null) + { + var i1 = item.next; + var i2 = i1.next; + + if (i1.type == JSC$OP_CONST_FALSE + && (i2.type == JSC$OP_IFTRUE + || i2.type == JSC$OP_IFTRUE_B)) + { + /* + * i1: const_false + * i2: iftrue{,_b} .LX => --- + */ + item.next = i2.next; + } + } + if (item.next != null && item.next.next != null) + { + var i1 = item.next; + var i2 = i1.next; + + if ((i1.type == JSC$OP_CONST_FALSE + && (i2.type == JSC$OP_IFFALSE + || i2.type == JSC$OP_IFFALSE_B)) + || (i1.type == JSC$OP_CONST_TRUE + && (i2.type == JSC$OP_IFTRUE + || i2.type == JSC$OP_IFTRUE_B))) + { + /* + * i1: const_false + * i2: iffalse{,_b} .LX => jmp .LX + * + * i1: const_true + * i2: iftrue{,_b} .LX => jmp .LX + */ + var i = new JSC$ASM_jmp (i1.linenum, i2.value); + item.next = i; + i.next = i2.next; + } + } + } + } + + /* Jumps to jumps. */ + if ((flags & JSC$FLAG_OPTIMIZE_JUMPS) != 0) + { + if (JSC$verbose) + JSC$message ("jsc: optimize: jumps to jumps"); + for (item = JSC$asm_head; item != null; item = item.next) + if (JSC$asm_is_local_jump (item)) + { + var i2; + + /* Operand's value is a label */ + i2 = JSC$asm_lookup_next_op (item.value); + + if (i2 != null && i2.type == JSC$OP_JMP) + /* Ok, we can jump there directly. */ + item.value = i2.value; + } + } + + if ((flags & JSC$FLAG_OPTIMIZE_HEAVY) != 0) + JSC$optimize_heavy (); + + /* + * Optimizations for the size of the generated byte-code. It isn't + * probably worth of doing these optimization for interactive + * scripts since these won't affect the speed of the execution. + * However, these optimizations make the byte-code files smaller so + * these are nice for batch-compiled files. + */ + if ((flags & JSC$FLAG_OPTIMIZE_BC_SIZE) != 0) + { + var delta = true; + + while (delta) + { + delta = false; + + /* Remove un-referenced labels. */ + + if (JSC$verbose) + JSC$message ("jsc: optimize: removing un-referenced labels"); + + /* First, make all labels unreferenced. */ + for (item = JSC$asm_head; item != null; item = item.next) + if (item.type == JSC$ASM_LABEL) + item.referenced = false; + + /* Second, mark all referenced labels. */ + for (item = JSC$asm_head; item != null; item = item.next) + if (JSC$asm_is_local_jump (item)) + item.value.referenced = true; + + /* Third, remove all un-referenced labels. */ + for (item = JSC$asm_head; item != null; item = item.next) + while (item.next != null && item.next.type == JSC$ASM_LABEL + && !item.next.referenced + && item.next.next != null) + { + delta = true; + item.next = item.next.next; + } + + /* Dead code elimination. */ + if (JSC$verbose) + JSC$message ("jsc: optimize: dead code elimination"); + for (item = JSC$asm_head; item != null; item = item.next) + if (item.type == JSC$OP_RETURN || item.type == JSC$OP_JMP) + while (item.next != null && item.next.type != JSC$ASM_SYMBOL + && item.next.type != JSC$ASM_LABEL) + { + delta = true; + item.next = item.next.next; + } + + + /* Simple peephole optimization. */ + if (JSC$verbose) + JSC$message ("jsc: optimize: peephole"); + for (item = JSC$asm_head; item != null; item = item.next) + { + /* Two instruction optimization (starting from item.next). */ + if (item.next != null && item.next.next != null) + { + var i1 = item.next; + var i2 = i1.next; + + if (i1.type == JSC$OP_JMP + && i2.type == JSC$ASM_LABEL + && i1.value == i2) + { + /* + * i1: jmp .LX + * i2: .LX => .LX + */ + item.next = i2; + delta = true; + } + } + } + } + } +} + + +function JSC$optimize_heavy () +{ + if (JSC$verbose) + JSC$message ("jsc: optimize: liveness analyzing"); + + /* First, set the prev pointers and zero usage flags. */ + var item, prev = null; + + for (item = JSC$asm_head; item != null; prev = item, item = item.next) + { + item.prev = prev; + item.live_args = 0; + item.live_locals = 0; + item.live_used = false; + } + + /* For each function. */ + var ftail, fhead; + for (ftail = JSC$asm_tail; ftail != null; ftail = fhead.prev) + { + var change = true; + + /* While there is change in the liveness. */ + while (change) + { + change = false; + + for (fhead = ftail; + fhead.type != JSC$ASM_SYMBOL; + fhead = fhead.prev) + { + var floc, farg; + + if (fhead.next != null) + { + floc = fhead.next.live_locals; + farg = fhead.next.live_args; + } + else + floc = farg = 0; + + if (fhead.type == JSC$OP_LOAD_LOCAL && fhead.value < 32) + floc |= (1 << fhead.value); + + if (fhead.type == JSC$OP_STORE_LOCAL && fhead.value < 32) + floc &= ~(1 << fhead.value); + + if (fhead.type == JSC$OP_LOAD_ARG && fhead.value < 32) + farg |= (1 << fhead.value); + + if (fhead.type == JSC$OP_STORE_ARG && fhead.value < 32) + farg &= ~(1 << fhead.value); + + if (JSC$asm_is_local_jump (fhead)) + { + floc |= fhead.value.live_locals; + fhead.value.live_used = true; + } + + if (fhead.live_used && (fhead.live_locals != floc + || fhead.live_args != farg)) + change = true; + + fhead.live_used = false; + fhead.live_locals = floc; + fhead.live_args = farg; + } + } + } + + /* + * When we have the liveness analyzing performed, we can do some + * fancy optimizations. + */ + + if (JSC$verbose) + JSC$message ("jsc: optimize: peephole"); + + for (item = JSC$asm_head; item != null; item = item.next) + { + /* Three instruction optimization. */ + if (item.next != null && item.next.next != null + && item.next.next.next != null) + { + var i1 = item.next; + var i2 = i1.next; + var i3 = i2.next; + + if (i1.type == JSC$OP_STORE_LOCAL + && i2.type == JSC$OP_LOAD_LOCAL + && i1.value == i2.value + && (i3.live_locals & (1 << i1.value)) == 0) + { + /* + * i1: store_local n + * i2: load_local n + * i3: nnn (n not live) => nnn + */ + + item.next = i3; + } + } + } +} + + +function JSC$asm_finalize () +{ + var item; + var offset = 0; + + for (item = JSC$asm_head; item != null; item = item.next) + { + item.offset = offset; + offset += item.size; + } +} + + +function JSC$ConstantReg () +{ +} + +function JSC$asm_genconstant (val) +{ + if (JSC$asm_known_constants == null) + JSC$asm_known_constants = new JSC$ConstantReg (); + + /* Lookup from a list of known constants. */ + var id = JSC$asm_known_constants[val]; + if (typeof id == "number") + return id; + + /* This is a new constant. */ + JSC$asm_constants.append (val); + JSC$asm_known_constants[val] = JSC$asm_constcount; + + return JSC$asm_constcount++; +} + +function JSC$asm_bytecode () +{ + var item; + var symtab = new String (""); + var nsymtab_entries = 0; + var code = new String (""); + var debug = new String (""); + var debug_last_linenum = 0; + + if (JSC$verbose) + JSC$message ("jsc: generating byte-code"); + + if (JSC$generate_debug_info) + /* Source file name. */ + debug.append (String.pack ("CN", JSC$DEBUG_FILENAME, JSC$filename.length) + + JSC$filename); + + JSC$asm_constants = new String (""); + + for (item = JSC$asm_head; item != null; item = item.next) + { + if (item.type == JSC$ASM_SYMBOL) + { + symtab.append (item.value + String.pack ("CN", 0, item.offset)); + nsymtab_entries++; + } + else if (item.type == JSC$ASM_LABEL) + ; + else + { + /* Real assembler operands. */ + + if (JSC$generate_debug_info) + if (item.linenum != debug_last_linenum) + { + debug.append (String.pack ("CNN", JSC$DEBUG_LINENUMBER, + item.offset + item.size, + item.linenum)); + debug_last_linenum = item.linenum; + } + + if (item.size == 1) + /* We handle these. */ + code.append (String.pack ("C", item.type)); + else + { + /* + * All operands which take an argument, have a method to create + * the byte code entry for their argument. + */ + code.append (String.pack ("C", item.type) + item.bytecode ()); + } + } + } + + symtab = String.pack ("N", nsymtab_entries) + symtab; + + if (JSC$verbose) + { + var msg = ("jsc: code=" + code.length.toString () + + ", constants=" + JSC$asm_constants.length.toString () + + ", symtab=" + symtab.length.toString ()); + + if (JSC$generate_debug_info) + msg += ", debug=" + debug.length.toString (); + + msg += (", headers=" + + (32 + (JSC$generate_debug_info ? 8 : 0)).toString () + + ", total=" + + (code.length + JSC$asm_constants.length + symtab.length + + debug.length + 32 + + (JSC$generate_debug_info ? 8 : 0)).toString ()); + JSC$message (msg); + } + + return (String.pack ("NN", JSC$BC_MAGIC, + 3 + (JSC$generate_debug_info ? 1 : 0)) + + String.pack ("NN", JSC$BC_SECT_CODE, code.length) + code + + + String.pack ("NN", JSC$BC_SECT_CONSTANTS, + JSC$asm_constants.length) + + JSC$asm_constants + + + String.pack ("NN", JSC$BC_SECT_SYMTAB, symtab.length) + symtab + + + (JSC$generate_debug_info + ? String.pack ("NN", JSC$BC_SECT_DEBUG, debug.length) + debug + : "")); +} + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/jsc/bs.js b/reactos/lib/kjs/jsc/bs.js new file mode 100644 index 00000000000..b74a9afcd53 --- /dev/null +++ b/reactos/lib/kjs/jsc/bs.js @@ -0,0 +1,65 @@ +/* + * Bootstrap file for the JavaScript compiler. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsc/bs.js,v $ + * $Id: bs.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * To run the compiler from vm, just call the entry point with fixed + * arguments. + */ +VM.verbose = 0; + +function compile () +{ + var file = "a.js"; + var verbose = JSC$FLAG_VERBOSE; + + if (ARGS.length == 2) + { + file = ARGS[1]; + verbose = 0; + } + + JSC$compile_file (file, + verbose + | JSC$FLAG_ANNOTATE_ASSEMBLER + | JSC$FLAG_GENERATE_DEBUG_INFO + | JSC$FLAG_OPTIMIZE_MASK + | JSC$FLAG_WARN_MASK & ~JSC$FLAG_WARN_MISSING_SEMICOLON, + "./a.jas", + "./a.jsc"); +} + +compile (); + + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/jsc/compiler.js b/reactos/lib/kjs/jsc/compiler.js new file mode 100644 index 00000000000..b09decea17e --- /dev/null +++ b/reactos/lib/kjs/jsc/compiler.js @@ -0,0 +1,8221 @@ +/* + * Internal definitions. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsc/compiler.js,v $ + * $Id: compiler.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * Constants. + */ + +/* Tokens. */ + +JSC$tEOF = 128; +JSC$tINTEGER = 129; +JSC$tFLOAT = 130; +JSC$tSTRING = 131; +JSC$tIDENTIFIER = 132; + +JSC$tBREAK = 133; +JSC$tCONTINUE = 134; +JSC$tDELETE = 135; +JSC$tELSE = 136; +JSC$tFOR = 137; +JSC$tFUNCTION = 138; +JSC$tIF = 139; +JSC$tIN = 140; +JSC$tNEW = 141; +JSC$tRETURN = 142; +JSC$tTHIS = 143; +JSC$tTYPEOF = 144; +JSC$tVAR = 145; +JSC$tVOID = 146; +JSC$tWHILE = 147; +JSC$tWITH = 148; + +JSC$tCASE = 149; +JSC$tCATCH = 150; +JSC$tCLASS = 151; +JSC$tCONST = 152; +JSC$tDEBUGGER = 153; +JSC$tDEFAULT = 154; +JSC$tDO = 155; +JSC$tENUM = 156; +JSC$tEXPORT = 157; +JSC$tEXTENDS = 158; +JSC$tFINALLY = 159; +JSC$tIMPORT = 160; +JSC$tSUPER = 161; +JSC$tSWITCH = 162; +JSC$tTHROW = 163; +JSC$tTRY = 164; + +JSC$tNULL = 165; +JSC$tTRUE = 166; +JSC$tFALSE = 167; + +JSC$tEQUAL = 168; +JSC$tNEQUAL = 169; +JSC$tLE = 170; +JSC$tGE = 171; +JSC$tAND = 172; +JSC$tOR = 173; +JSC$tPLUSPLUS = 174; +JSC$tMINUSMINUS = 175; +JSC$tMULA = 176; +JSC$tDIVA = 177; +JSC$tMODA = 178; +JSC$tADDA = 179; +JSC$tSUBA = 180; +JSC$tANDA = 181; +JSC$tXORA = 182; +JSC$tORA = 183; +JSC$tLSIA = 184; +JSC$tLSHIFT = 185; +JSC$tRSHIFT = 186; +JSC$tRRSHIFT = 187; +JSC$tRSIA = 188; +JSC$tRRSA = 189; +JSC$tSEQUAL = 190; +JSC$tSNEQUAL = 191; + + +/* Expressions. */ + +JSC$EXPR_COMMA = 0; +JSC$EXPR_ASSIGNMENT = 1; +JSC$EXPR_QUEST_COLON = 2; +JSC$EXPR_LOGICAL = 3; +JSC$EXPR_BITWISE = 4; +JSC$EXPR_EQUALITY = 5; +JSC$EXPR_RELATIONAL = 6; +JSC$EXPR_SHIFT = 7; +JSC$EXPR_MULTIPLICATIVE = 8; +JSC$EXPR_ADDITIVE = 9; +JSC$EXPR_THIS = 10; +JSC$EXPR_NULL = 11; +JSC$EXPR_TRUE = 12; +JSC$EXPR_FALSE = 13; +JSC$EXPR_IDENTIFIER = 14; +JSC$EXPR_FLOAT = 15; +JSC$EXPR_INTEGER = 16; +JSC$EXPR_STRING = 17; +JSC$EXPR_CALL = 18; +JSC$EXPR_OBJECT_PROPERTY = 19; +JSC$EXPR_OBJECT_ARRAY = 20; +JSC$EXPR_NEW = 21; +JSC$EXPR_DELETE = 22; +JSC$EXPR_VOID = 23; +JSC$EXPR_TYPEOF = 24; +JSC$EXPR_PREFIX = 25; +JSC$EXPR_POSTFIX = 26; +JSC$EXPR_UNARY = 27; +JSC$EXPR_REGEXP = 28; +JSC$EXPR_ARRAY_INITIALIZER = 29; +JSC$EXPR_OBJECT_INITIALIZER = 30; + +/* Statements */ + +JSC$STMT_BLOCK = 0; +JSC$STMT_FUNCTION_DECLARATION = 1; +JSC$STMT_VARIABLE = 2; +JSC$STMT_EMPTY = 3; +JSC$STMT_EXPR = 4; +JSC$STMT_IF = 5; +JSC$STMT_WHILE = 6; +JSC$STMT_FOR = 7; +JSC$STMT_FOR_IN = 8; +JSC$STMT_CONTINUE = 9; +JSC$STMT_BREAK = 10; +JSC$STMT_RETURN = 11; +JSC$STMT_WITH = 12; +JSC$STMT_TRY = 13; +JSC$STMT_THROW = 14; +JSC$STMT_DO_WHILE = 15; +JSC$STMT_SWITCH = 16; +JSC$STMT_LABELED_STMT = 17; + +/* JavaScript types. */ + +JSC$JS_UNDEFINED = 0; +JSC$JS_NULL = 1; +JSC$JS_BOOLEAN = 2; +JSC$JS_INTEGER = 3; +JSC$JS_STRING = 4; +JSC$JS_FLOAT = 5; +JSC$JS_ARRAY = 6; +JSC$JS_OBJECT = 7; +JSC$JS_BUILTIN = 11; + + +/* +Local variables: +mode: c +End: +*/ +/* + * Lexer. + * Copyright (c) 1998-1999 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsc/compiler.js,v $ + * $Id: compiler.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * Global functions. + */ + +function JSC$lexer (stream) +{ + var ch, ch2; + + JSC$token_value = null; + + while ((ch = stream.readByte ()) != -1) + { + if (ch == #'\n') + { + JSC$linenum++; + continue; + } + + if (JSC$lexer_is_white_space (ch)) + continue; + + JSC$token_linenum = JSC$linenum; + + if (ch == #'/' && JSC$lexer_peek_char (stream) == #'*') + { + /* Multi line comment. */ + stream.readByte (); + while ((ch = stream.readByte ()) != -1 + && (ch != #'*' || JSC$lexer_peek_char (stream) != #'/')) + if (ch == #'\n') + JSC$linenum++; + + /* Consume the peeked #'/' character. */ + stream.readByte (); + } + else if ((ch == #'/' && JSC$lexer_peek_char (stream) == #'/') + || (ch == #'#' && JSC$lexer_peek_char (stream) == #'!')) + { + /* Single line comment. */ + while ((ch = stream.readByte ()) != -1 && ch != #'\n') + ; + if (ch == #'\n') + JSC$linenum++; + } + else if (ch == #'"' || ch == #'\'') + { + /* String constant. */ + JSC$token_value = JSC$lexer_read_string (stream, "string", ch); + return JSC$tSTRING; + } + + /* Literals. */ + else if (ch == #'=' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + if (JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tSEQUAL; + } + return JSC$tEQUAL; + } + else if (ch == #'!' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + if (JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tSNEQUAL; + } + return JSC$tNEQUAL; + } + else if (ch == #'<' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tLE; + } + else if (ch == #'>' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tGE; + } + else if (ch == #'&' && JSC$lexer_peek_char (stream) == #'&') + { + stream.readByte (); + return JSC$tAND; + } + else if (ch == #'|' && JSC$lexer_peek_char (stream) == #'|') + { + stream.readByte (); + return JSC$tOR; + } + else if (ch == #'+' && JSC$lexer_peek_char (stream) == #'+') + { + stream.readByte (); + return JSC$tPLUSPLUS; + } + else if (ch == #'-' && JSC$lexer_peek_char (stream) == #'-') + { + stream.readByte (); + return JSC$tMINUSMINUS; + } + else if (ch == #'*' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tMULA; + } + else if (ch == #'/' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tDIVA; + } + else if (ch == #'%' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tMODA; + } + else if (ch == #'+' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tADDA; + } + else if (ch == #'-' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tSUBA; + } + else if (ch == #'&' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tANDA; + } + else if (ch == #'^' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tXORA; + } + else if (ch == #'|' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tORA; + } + else if (ch == #'<' && JSC$lexer_peek_char (stream) == #'<') + { + stream.readByte (); + if (JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tLSIA; + } + else + return JSC$tLSHIFT; + } + else if (ch == #'>' && JSC$lexer_peek_char (stream) == #'>') + { + stream.readByte (); + ch2 = JSC$lexer_peek_char (stream); + if (ch2 == #'=') + { + stream.readByte (); + return JSC$tRSIA; + } + else if (ch2 == #'>') + { + stream.readByte (); + if (JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tRRSA; + } + else + return JSC$tRRSHIFT; + } + else + return JSC$tRSHIFT; + } + + /* Identifiers and keywords. */ + else if (JSC$lexer_is_identifier_letter (ch)) + { + /* An identifier. */ + var id = String.fromCharCode (ch); + + while ((ch = stream.readByte ()) != -1 + && (JSC$lexer_is_identifier_letter (ch) + || JSC$lexer_is_decimal_digit (ch))) + id.append (File.byteToString (ch)); + stream.ungetByte (ch); + + /* Keywords. */ + if (id == "break") + return JSC$tBREAK; + else if (id == "continue") + return JSC$tCONTINUE; + else if (id == "delete") + return JSC$tDELETE; + else if (id == "else") + return JSC$tELSE; + else if (id == "for") + return JSC$tFOR; + else if (id == "function") + return JSC$tFUNCTION; + else if (id == "if") + return JSC$tIF; + else if (id == "in") + return JSC$tIN; + else if (id == "new") + return JSC$tNEW; + else if (id == "return") + return JSC$tRETURN; + else if (id == "this") + return JSC$tTHIS; + else if (id == "typeof") + return JSC$tTYPEOF; + else if (id == "var") + return JSC$tVAR; + else if (id == "void") + return JSC$tVOID; + else if (id == "while") + return JSC$tWHILE; + else if (id == "with") + return JSC$tWITH; + + /* + * Future reserved keywords (some of these is already in use + * in this implementation). + */ + else if (id == "case") + return JSC$tCASE; + else if (id == "catch") + return JSC$tCATCH; + else if (id == "class") + return JSC$tCLASS; + else if (id == "const") + return JSC$tCONST; + else if (id == "debugger") + return JSC$tDEBUGGER; + else if (id == "default") + return JSC$tDEFAULT; + else if (id == "do") + return JSC$tDO; + else if (id == "enum") + return JSC$tENUM; + else if (id == "export") + return JSC$tEXPORT; + else if (id == "extends") + return JSC$tEXTENDS; + else if (id == "finally") + return JSC$tFINALLY; + else if (id == "import") + return JSC$tIMPORT; + else if (id == "super") + return JSC$tSUPER; + else if (id == "switch") + return JSC$tSWITCH; + else if (id == "throw") + return JSC$tTHROW; + else if (id == "try") + return JSC$tTRY; + + /* Null and boolean literals. */ + else if (id == "null") + return JSC$tNULL; + else if (id == "true") + return JSC$tTRUE; + else if (id == "false") + return JSC$tFALSE; + else + { + /* It really is an identifier. */ + JSC$token_value = id; + return JSC$tIDENTIFIER; + } + } + + /* Character constants. */ + else if (ch == #'#' && JSC$lexer_peek_char (stream) == #'\'') + { + /* Skip the starting #'\'' and read more. */ + stream.readByte (); + + ch = stream.readByte (); + if (ch == #'\\') + { + JSC$token_value + = JSC$lexer_read_backslash_escape (stream, 0, "character"); + + if (stream.readByte () != #'\'') + error (JSC$filename + ":" + JSC$linenum.toString () + + ": malformed character constant"); + } + else if (JSC$lexer_peek_char (stream) == #'\'') + { + stream.readByte (); + JSC$token_value = ch; + } + else + error (JSC$filename + ":" + JSC$linenum.toString () + + ": malformed character constant"); + + return JSC$tINTEGER; + } + + /* Octal and hex numbers. */ + else if (ch == #'0' + && JSC$lexer_peek_char (stream) != #'.' + && JSC$lexer_peek_char (stream) != #'e' + && JSC$lexer_peek_char (stream) != #'E') + { + JSC$token_value = 0; + ch = stream.readByte (); + if (ch == #'x' || ch == #'X') + { + ch = stream.readByte (); + while (JSC$lexer_is_hex_digit (ch)) + { + JSC$token_value *= 16; + JSC$token_value += JSC$lexer_hex_to_dec (ch); + ch = stream.readByte (); + } + stream.ungetByte (ch); + } + else + { + while (JSC$lexer_is_octal_digit (ch)) + { + JSC$token_value *= 8; + JSC$token_value += ch - #'0'; + ch = stream.readByte (); + } + stream.ungetByte (ch); + } + + return JSC$tINTEGER; + } + + /* Decimal numbers. */ + else if (JSC$lexer_is_decimal_digit (ch) + || (ch == #'.' + && JSC$lexer_is_decimal_digit ( + JSC$lexer_peek_char (stream)))) + { + var is_float = false; + var buf = new String (File.byteToString (ch)); + var accept_dot = true; + + if (ch == #'.') + { + /* + * We started with #'.' and we know that the next character + * is a decimal digit (we peeked it). + */ + is_float = true; + + ch = stream.readByte (); + while (JSC$lexer_is_decimal_digit (ch)) + { + buf.append (File.byteToString (ch)); + ch = stream.readByte (); + } + accept_dot = false; + } + else + { + /* We did start with a decimal digit. */ + ch = stream.readByte (); + while (JSC$lexer_is_decimal_digit (ch)) + { + buf.append (File.byteToString (ch)); + ch = stream.readByte (); + } + } + + if ((accept_dot && ch == #'.') + || ch == #'e' || ch == #'E') + { + is_float = true; + + if (ch == #'.') + { + buf.append (File.byteToString (ch)); + ch = stream.readByte (); + while (JSC$lexer_is_decimal_digit (ch)) + { + buf.append (File.byteToString (ch)); + ch = stream.readByte (); + } + } + + if (ch == #'e' || ch == #'E') + { + buf.append (File.byteToString (ch)); + ch = stream.readByte (); + if (ch == #'+' || ch == #'-') + { + buf.append (File.byteToString (ch)); + ch = stream.readByte (); + } + if (!JSC$lexer_is_decimal_digit (ch)) + error (JSC$filename + ":" + JSC$linenum.toString () + + ": malformed exponent part in a decimal literal"); + + while (JSC$lexer_is_decimal_digit (ch)) + { + buf.append (File.byteToString (ch)); + ch = stream.readByte (); + } + } + } + + /* Finally, we put the last character pack to the stream. */ + stream.ungetByte (ch); + + if (is_float) + { + JSC$token_value = parseFloat (buf); + return JSC$tFLOAT; + } + + JSC$token_value = parseInt (buf); + return JSC$tINTEGER; + } + + /* Just return the character as-is. */ + else + return ch; + } + + /* EOF reached. */ + return JSC$tEOF; +} + + +/* + * Help functions. + */ + +function JSC$lexer_peek_char (stream) +{ + var ch2 = stream.readByte (); + stream.ungetByte (ch2); + + return ch2; +} + + +function JSC$lexer_is_identifier_letter (ch) +{ + return ((#'a' <= ch && ch <= #'z') || (#'A' <= ch && ch <= #'Z') + || ch == #'$' || ch == #'_'); +} + + +function JSC$lexer_is_octal_digit (ch) +{ + return (#'0' <= ch && ch <= #'7'); +} + + +function JSC$lexer_is_decimal_digit (ch) +{ + return #'0' <= ch && ch <= #'9'; +} + + +function JSC$lexer_is_hex_digit (ch) +{ + return ((#'0' <= ch && ch <= #'9') + || (#'a' <= ch && ch <= #'f') + || (#'A' <= ch && ch <= #'F')); +} + + +function JSC$lexer_is_white_space (ch) +{ + return (ch == #' ' || ch == #'\t' || ch == #'\v' || ch == #'\r' + || ch == #'\f' || ch == #'\n'); +} + + +function JSC$lexer_hex_to_dec (ch) +{ + return ((#'0' <= ch && ch <= #'9') + ? ch - #'0' + : ((#'a' <= ch && ch <= #'f') + ? 10 + ch - #'a' + : 10 + ch - #'A')); +} + + +function JSC$lexer_read_backslash_escape (stream, possible_start, name) +{ + var ch = stream.readByte (); + + if (ch == #'n') + ch = #'\n'; + else if (ch == #'t') + ch = #'\t'; + else if (ch == #'v') + ch = #'\v'; + else if (ch == #'b') + ch = #'\b'; + else if (ch == #'r') + ch = #'\r'; + else if (ch == #'f') + ch = #'\f'; + else if (ch == #'a') + ch = #'\a'; + else if (ch == #'\\') + ch = #'\\'; + else if (ch == #'?') + ch = #'?'; + else if (ch == #'\'') + ch = #'\''; + else if (ch == #'"') + ch = #'"'; + else if (ch == #'x') + { + /* HexEscapeSequence. */ + var c1, c2; + + c1 = stream.readByte (); + c2 = stream.readByte (); + + if (c1 == -1 || c2 == -1) + JSC$lexer_eof_in_constant (possible_start, name); + + if (!JSC$lexer_is_hex_digit (c1) || !JSC$lexer_is_hex_digit (c2)) + error (JSC$filename + ":" + JSC$linenum.toString () + + ": \\x used with no following hex digits"); + + ch = (JSC$lexer_hex_to_dec (c1) << 4) + JSC$lexer_hex_to_dec (c2); + } + else if (ch == #'u') + { + /* UnicodeEscapeSequence. */ + var c1, c2, c3, c4; + + c1 = stream.readByte (); + c2 = stream.readByte (); + c3 = stream.readByte (); + c4 = stream.readByte (); + + if (c1 == -1 || c2 == -1 || c3 == -1 || c4 == -1) + JSC$lexer_eof_in_constant (possible_start, name); + + if (!JSC$lexer_is_hex_digit (c1) || !JSC$lexer_is_hex_digit (c2) + || !JSC$lexer_is_hex_digit (c3) || !JSC$lexer_is_hex_digit (c4)) + error (JSC$filename + ":" + JSC$linenum.toString () + + ": \\u used with no following hex digits"); + + ch = ((JSC$lexer_hex_to_dec (c1) << 12) + + (JSC$lexer_hex_to_dec (c2) << 8) + + (JSC$lexer_hex_to_dec (c3) << 4) + + JSC$lexer_hex_to_dec (c4)); + } + else if (JSC$lexer_is_octal_digit (ch)) + { + var result = ch - #'0'; + var i = 1; + + if (ch == #'0') + /* Allow three octal digits after '0'. */ + i = 0; + + ch = stream.readByte (); + while (i < 3 && JSC$lexer_is_octal_digit (ch)) + { + result *= 8; + result += ch - #'0'; + ch = stream.readByte (); + i++; + } + stream.ungetByte (ch); + ch = result; + } + else + { + if (ch == -1) + error (JSC$filename + ":" + JSC$linenum.toString () + + ": unterminated " + name); + + JSC$warning (JSC$filename + ":" + JSC$linenum.toString () + + ": warning: unknown escape sequence `\\" + + File.byteToString (ch) + "'"); + } + + return ch; +} + + +function JSC$lexer_read_string (stream, name, ender) +{ + var str = new String (""); + var done = false, ch; + var possible_start_ln = JSC$linenum; + var warned_line_terminator = false; + + while (!done) + { + ch = stream.readByte (); + if (ch == #'\n') + { + if (JSC$warn_strict_ecma && !warned_line_terminator) + { + JSC$warning (JSC$filename + ":" + JSC$linenum.toString () + + ": warning: ECMAScript don't allow line terminators in " + + name + " constants"); + warned_line_terminator = true; + } + JSC$linenum++; + } + + if (ch == -1) + JSC$lexer_eof_in_constant (possible_start_ln, name); + + else if (ch == ender) + done = true; + else + { + if (ch == #'\\') + { + if (JSC$lexer_peek_char (stream) == #'\n') + { + /* + * Backslash followed by a newline character. Ignore + * them both. + */ + stream.readByte (); + JSC$linenum++; + continue; + } + ch = JSC$lexer_read_backslash_escape (stream, possible_start_ln, + name); + } + str.append (ch); + } + } + + return str; +} + + +function JSC$lexer_read_regexp_constant (stream) +{ + /* Regexp literal. */ + var source = JSC$lexer_read_regexp_source (stream); + + /* Check the possible flags. */ + var flags = new String (""); + while ((ch = JSC$lexer_peek_char (stream)) == #'g' || ch == #'i') + { + stream.readByte (); + flags.append (File.byteToString (ch)); + } + + /* Try to compile it. */ + var msg = false; + var result; + try + { + result = new RegExp (source, flags); + } + catch (msg) + { + var start = msg.lastIndexOf (":"); + msg = (JSC$filename + ":" + JSC$token_linenum.toString () + + ": malformed regular expression constant:" + + msg.substr (start + 1)); + } + if (msg) + error (msg); + + /* Success. */ + + return result; +} + + +function JSC$lexer_read_regexp_source (stream) +{ + var str = new String (""); + var done = false, ch; + var possible_start_ln = JSC$linenum; + var warned_line_terminator = false; + var name = "regular expression"; + + while (!done) + { + ch = stream.readByte (); + if (ch == #'\n') + { + if (JSC$warn_strict_ecma && !warned_line_terminator) + { + JSC$warning (JSC$filename + ":" + JSC$linenum.toString () + + ": warning: ECMAScript don't allow line " + + "terminators in " + name + " constants"); + warned_line_terminator = true; + } + JSC$linenum++; + } + + if (ch == -1) + JSC$lexer_eof_in_constant (possible_start_ln, name); + + else if (ch == #'/') + done = true; + else + { + if (ch == #'\\') + { + ch = stream.readByte (); + if (ch == #'\n') + { + /* + * Backslash followed by a newline character. Ignore + * them both. + */ + JSC$linenum++; + continue; + } + if (ch == -1) + JSC$lexer_eof_in_constant (possible_start_ln, name); + + /* Handle the backslash escapes. */ + if (ch == #'f') + ch = #'\f'; + else if (ch == #'n') + ch = #'\n'; + else if (ch == #'r') + ch = #'\r'; + else if (ch == #'t') + ch = #'\t'; + else if (ch == #'v') + ch == #'\v'; + else if (ch == #'c') + { + /* SourceCharacter. */ + ch = stream.readByte (); + if (ch == -1) + JSC$lexer_eof_in_constant (possible_start_ln, name); + + if (ch == #'\n' && JSC$warn_strict_ecma) + JSC$warning (JSC$filename + ":" + JSC$linenum.toString () + + ": warning: ECMAScript don't allow line termiantor after \\c in regular expression constants"); + + /* + * Append the source-character escape start. The ch + * will be appended later. + */ + str.append ("\\c"); + } + else if (ch == #'u' || ch == #'x' || ch == #'0') + { + /* These can be handled with the read_backslash_escape(). */ + stream.ungetByte (ch); + ch = JSC$lexer_read_backslash_escape (stream); + } + else + { + /* + * Nothing special. Leave it to the result as-is. + * The regular expression backage will handle it. + */ + stream.ungetByte (ch); + ch = #'\\'; + } + } + str.append (File.byteToString (ch)); + } + } + + return str; +} + + +function JSC$lexer_eof_in_constant (possible_start, name) +{ + var msg = (JSC$filename + ":" + JSC$linenum.toString () + + ": unterminated " + name + " constant"); + + if (possible_start > 0) + msg += (System.lineBreakSequence + + JSC$filename + ":" + possible_start.toString () + + ": possible real start of unterminated " + name + " constant"); + + error (msg); +} + + +/* +Local variables: +mode: c +End: +*/ +/* + * Parser. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsc/compiler.js,v $ + * $Id: compiler.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * Global functions. + */ + +function JSC$parser_reset () +{ + JSC$function = null; + JSC$global_stmts = null; + JSC$nested_function_declarations = null; +} + + +function JSC$parser_parse (stream) +{ + JSC$linenum = 1; + JSC$filename = stream.name; + JSC$functions = new Array (); + JSC$global_stmts = new Array (); + JSC$nested_function_declarations = new Array (); + JSC$anonymous_function_count = 0; + JSC$parser_peek_token_valid = false; + JSC$num_tokens = 0; + JSC$num_arguments_identifiers = 0; + JSC$num_missing_semicolons = 0; + + if (JSC$verbose) + JSC$message ("jsc: parsing"); + + while (JSC$parser_peek_token (stream) != JSC$tEOF) + if (!JSC$parser_parse_source_element (stream)) + JSC$parser_syntax_error (); + + if (JSC$verbose) + { + var msg = ("jsc: input stream had " + (JSC$linenum - 1).toString () + + " lines, " + JSC$num_tokens.toString () + " tokens"); + + if (JSC$num_missing_semicolons > 0) + msg += (", " + JSC$num_missing_semicolons.toString () + + " missing semicolons"); + + JSC$message (msg); + } +} + + +/* + * General help functions. + */ + +function JSC$parser_syntax_error () +{ + error (JSC$filename + ":" + JSC$linenum.toString () + ": syntax error"); +} + +/* All warnings are reported through this function. */ +function JSC$warning (line) +{ + System.stderr.writeln (line); +} + +/* All messages are reported throught this function. */ +function JSC$message (line) +{ + System.stderr.writeln (line); +} + + +function JSC$parser_get_token (stream) +{ + JSC$num_tokens++; + + var token; + if (JSC$parser_peek_token_valid) + { + JSC$parser_peek_token_valid = false; + JSC$parser_token_value = JSC$parser_peek_token_value; + JSC$parser_token_linenum = JSC$parser_peek_token_linenum; + token = JSC$parser_peek_token_token; + } + else + { + token = JSC$lexer (stream); + JSC$parser_token_value = JSC$token_value; + JSC$parser_token_linenum = JSC$token_linenum; + } + + if (token == JSC$tIDENTIFIER && JSC$parser_token_value == "arguments") + JSC$num_arguments_identifiers++; + + return token; +} + + +function JSC$parser_peek_token (stream) +{ + if (JSC$parser_peek_token_valid) + return JSC$parser_peek_token_token; + else + { + JSC$parser_peek_token_token = JSC$lexer (stream); + JSC$parser_peek_token_value = JSC$token_value; + JSC$parser_peek_token_linenum = JSC$token_linenum; + JSC$parser_peek_token_valid = true; + return JSC$parser_peek_token_token; + } +} + + +function JSC$parser_get_semicolon_asci (stream) +{ + var token = JSC$parser_peek_token (stream); + + if (token == #';') + { + /* Everything ok. It was there. */ + return JSC$parser_get_token (stream); + } + + /* No semicolon. Let's see if we can insert it there. */ + if (token == #'}' + || JSC$parser_token_linenum < JSC$parser_peek_token_linenum + || token == JSC$tEOF) + { + /* Ok, do the automatic semicolon insertion. */ + if (JSC$warn_missing_semicolon) + JSC$warning (JSC$filename + ":" + JSC$parser_token_linenum.toString () + + ": warning: missing semicolon"); + JSC$num_missing_semicolons++; + return #';'; + } + + /* Sorry, no can do. */ + JSC$parser_syntax_error (); +} + + +function JSC$parser_expr_is_left_hand_side (expr) +{ + return (expr.etype == JSC$EXPR_CALL + || expr.etype == JSC$EXPR_OBJECT_PROPERTY + || expr.etype == JSC$EXPR_OBJECT_ARRAY + || expr.etype == JSC$EXPR_NEW + || expr.etype == JSC$EXPR_THIS + || expr.etype == JSC$EXPR_IDENTIFIER + || expr.etype == JSC$EXPR_FLOAT + || expr.etype == JSC$EXPR_INTEGER + || expr.etype == JSC$EXPR_STRING + || expr.etype == JSC$EXPR_REGEXP + || expr.etype == JSC$EXPR_ARRAY_INITIALIZER + || expr.etype == JSC$EXPR_NULL + || expr.etype == JSC$EXPR_TRUE + || expr.etype == JSC$EXPR_FALSE); +} + + +function JSC$parser_parse_source_element (stream) +{ + if (JSC$parser_parse_function_declaration (stream)) + return true; + + var stmt = JSC$parser_parse_stmt (stream); + if (!stmt) + return false; + + if (stmt.stype == JSC$STMT_VARIABLE) + /* + * This is a variable declaration at the global level. These + * are actually global variables. + */ + stmt.global_level = true; + + JSC$global_stmts.push (stmt); + + return true; +} + + +function JSC$parser_parse_function_declaration (stream) +{ + var id, args, block; + + if (JSC$parser_peek_token (stream) != JSC$tFUNCTION) + return false; + + /* Record how many `arguments' identifiers have been seen so far. */ + var num_arguments_identifiers = JSC$num_arguments_identifiers; + + JSC$parser_get_token (stream); + if (JSC$parser_get_token (stream) != JSC$tIDENTIFIER) + JSC$parser_syntax_error (); + + id = JSC$parser_token_value; + var ln = JSC$parser_token_linenum; + var id_given = id; + + if (JSC$nested_function_declarations.length > 0) + { + /* This is a nested function declaration. */ + id = ".F:" + (JSC$anonymous_function_count++).toString (); + } + JSC$nested_function_declarations.push (id); + + if (JSC$parser_get_token (stream) != #'(') + JSC$parser_syntax_error (); + + /* Formal parameter list opt. */ + args = new Array (); + while (JSC$parser_peek_token (stream) != #')') + { + if (JSC$parser_get_token (stream) != JSC$tIDENTIFIER) + JSC$parser_syntax_error (); + args.push (JSC$parser_token_value); + + var token = JSC$parser_peek_token (stream); + if (token == #',') + { + JSC$parser_get_token (stream); + if (JSC$parser_peek_token (stream) != JSC$tIDENTIFIER) + JSC$parser_syntax_error (); + } + else if (token != #')') + JSC$parser_syntax_error (); + } + + if (JSC$parser_get_token (stream) != #')') + JSC$parser_syntax_error (); + + JSC$parser_peek_token (stream); + var lbrace_ln = JSC$parser_peek_token_linenum; + + block = JSC$parser_parse_block (stream); + if (typeof block == "boolean") + JSC$parser_syntax_error (); + + /* Did the function use the `arguments' identifier? */ + var use_arguments = false; + if (JSC$num_arguments_identifiers > num_arguments_identifiers) + { + use_arguments = true; + if (JSC$warn_deprecated) + JSC$warning (JSC$filename + ":" + ln.toString () + + ": warning: the `arguments' property of Function " + + "instance is deprecated"); + } + + JSC$functions.push (new JSC$function_declaration (ln, lbrace_ln, id, + id_given, args, + block, use_arguments)); + + JSC$nested_function_declarations.pop (); + + return true; +} + + +function JSC$parser_parse_block (stream) +{ + var block; + + if (JSC$parser_peek_token (stream) != #'{') + return false; + + JSC$parser_get_token (stream) != #'{'; + var ln = JSC$parser_peek_token_linenum; + + /* Do we have a statement list? */ + if (JSC$parser_peek_token (stream) != #'}') + /* Yes we have. */ + block = JSC$parser_parse_stmt_list (stream); + else + /* Do we don't */ + block = new Array (); + + if (JSC$parser_get_token (stream) != #'}') + JSC$parser_syntax_error (); + + block.linenum = ln; + + return block; +} + + +function JSC$parser_parse_stmt_list (stream) +{ + var list, done, item; + + list = new Array (); + done = false; + + while (!done) + { + item = JSC$parser_parse_stmt (stream); + if (typeof item == "boolean") + { + /* Can't parse more statements. We'r done. */ + done = true; + } + else + list.push (item); + } + + return list; +} + + +function JSC$parser_parse_stmt (stream) +{ + var item, token; + + if (typeof (item = JSC$parser_parse_block (stream)) != "boolean") + return new JSC$stmt_block (item.linenum, item); + else if (JSC$parser_parse_function_declaration (stream)) + { + /* XXX The function declaration as statement might be incomplete. */ + + if (JSC$nested_function_declarations.length == 0) + /* Function declaration at top-level statements. */ + return new JSC$stmt_empty (JSC$parser_token_linenum); + + /* Function declaration inside another function. */ + + var container_id = JSC$nested_function_declarations.pop (); + JSC$nested_function_declarations.push (container_id); + + var f = JSC$functions[JSC$functions.length - 1]; + var function_id = f.name; + var given_id = f.name_given; + + return new JSC$stmt_function_declaration (JSC$parser_token_linenum, + container_id, function_id, + given_id); + } + else if (typeof (item = JSC$parser_parse_variable_stmt (stream)) + != "boolean") + return item; + else if (typeof (item = JSC$parser_parse_if_stmt (stream)) + != "boolean") + return item; + else if (typeof (item = JSC$parser_parse_iteration_stmt (stream)) + != "boolean") + return item; + else if (typeof (item = JSC$parser_parse_expr (stream)) + != "boolean") + { + if (item.etype == JSC$EXPR_IDENTIFIER) + { + /* Possible `Labeled Statement'. */ + token = JSC$parser_peek_token (stream); + if (token == #':' && item.linenum == JSC$parser_peek_token_linenum) + { + /* Yes it is. */ + JSC$parser_get_token (stream); + var stmt = JSC$parser_parse_stmt (stream); + if (!stmt) + JSC$parser_syntax_error; + + return new JSC$stmt_labeled_stmt (item.linenum, item.value, + stmt); + } + /* FALLTHROUGH */ + } + + JSC$parser_get_semicolon_asci (stream); + return new JSC$stmt_expr (item); + } + else + { + token = JSC$parser_peek_token (stream); + if (token == #';') + { + JSC$parser_get_token (stream); + return new JSC$stmt_empty (JSC$parser_token_linenum); + } + else if (token == JSC$tCONTINUE) + { + JSC$parser_get_token (stream); + + /* Check the possible label. */ + var label = null; + token = JSC$parser_peek_token (stream); + if (token == JSC$tIDENTIFIER + && JSC$parser_token_linenum == JSC$parser_peek_token_linenum) + { + JSC$parser_get_token (stream); + label = JSC$parser_token_value; + } + + item = new JSC$stmt_continue (JSC$parser_token_linenum, label); + + JSC$parser_get_semicolon_asci (stream); + + return item; + } + else if (token == JSC$tBREAK) + { + JSC$parser_get_token (stream); + + /* Check the possible label. */ + var label = null; + token = JSC$parser_peek_token (stream); + if (token == JSC$tIDENTIFIER + && JSC$parser_token_linenum == JSC$parser_peek_token_linenum) + { + JSC$parser_get_token (stream); + label = JSC$parser_token_value; + } + + item = new JSC$stmt_break (JSC$parser_token_linenum, label); + + JSC$parser_get_semicolon_asci (stream); + + return item; + } + else if (token == JSC$tRETURN) + { + JSC$parser_get_token (stream); + var linenum = JSC$parser_token_linenum; + + if (JSC$parser_peek_token (stream) == #';') + { + /* Consume the semicolon. */ + JSC$parser_get_token (stream); + item = null; + } + else + { + if (JSC$parser_peek_token_linenum > linenum) + { + /* + * A line terminator between tRETURN and the next + * token that is not a semicolon. ASCI here. + */ + if (JSC$warn_missing_semicolon) + JSC$warning (JSC$filename + ":" + linenum.toString () + + ": warning: missing semicolon"); + + JSC$num_missing_semicolons++; + item = null; + } + else + { + item = JSC$parser_parse_expr (stream); + if (typeof item == "boolean") + JSC$parser_syntax_error (); + + JSC$parser_get_semicolon_asci (stream); + } + } + + return new JSC$stmt_return (linenum, item); + } + else if (token == JSC$tSWITCH) + { + JSC$parser_get_token (stream); + return JSC$parser_parse_switch (stream); + } + else if (token == JSC$tWITH) + { + JSC$parser_get_token (stream); + var linenum = JSC$parser_token_linenum; + + if (JSC$parser_get_token (stream) != #'(') + JSC$parser_syntax_error (); + + var expr = JSC$parser_parse_expr (stream); + if (typeof expr == "boolean") + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #')') + JSC$parser_syntax_error (); + + var stmt = JSC$parser_parse_stmt (stream); + if (typeof stmt == "boolean") + JSC$parser_syntax_error (); + + return new JSC$stmt_with (linenum, expr, stmt); + } + else if (token == JSC$tTRY) + { + JSC$parser_get_token (stream); + return JSC$parser_parse_try (stream); + } + else if (token == JSC$tTHROW) + { + JSC$parser_get_token (stream); + var linenum = JSC$parser_token_linenum; + + /* + * Get the next token's linenum. We need it for strict_ecma + * warning. + */ + JSC$parser_peek_token (stream); + var peek_linenum = JSC$parser_peek_token_linenum; + + /* The expression to throw. */ + var expr = JSC$parser_parse_expr (stream); + if (typeof expr == "boolean") + JSC$parser_syntax_error (); + + if (JSC$warn_strict_ecma && peek_linenum > linenum) + JSC$warning (JSC$filename + ":" + JSC$linenum.toString () + + ": warning: ECMAScript don't allow line terminators" + + " between `throw' and expression"); + + JSC$parser_get_semicolon_asci (stream); + + return new JSC$stmt_throw (linenum, expr); + } + else + /* Can't parse more. We'r done. */ + return false; + } +} + + +function JSC$parser_parse_switch (stream) +{ + var linenum = JSC$parser_token_linenum; + + if (JSC$parser_get_token (stream) != #'(') + JSC$parser_syntax_error (); + + var expr = JSC$parser_parse_expr (stream); + if (!expr) + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #')') + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #'{') + JSC$parser_syntax_error (); + + /* Parse case clauses. */ + var clauses = new Array (); + while (true) + { + var token = JSC$parser_get_token (stream); + + if (token == #'}') + break; + else if (token == JSC$tCASE || token == JSC$tDEFAULT) + { + var stmts = new Array (); + stmts.expr = null; + + if (token == JSC$tCASE) + { + stmts.expr = JSC$parser_parse_expr (stream); + if (!stmts.expr) + JSC$parser_syntax_error (); + } + if (JSC$parser_get_token (stream) != #':') + JSC$parser_syntax_error (); + + stmts.linenum = JSC$parser_token_linenum; + + /* Read the statement list. */ + while (true) + { + token = JSC$parser_peek_token (stream); + if (token == #'}' || token == JSC$tCASE || token == JSC$tDEFAULT) + /* Done with this branch. */ + break; + + var stmt = JSC$parser_parse_stmt (stream); + if (!stmt) + JSC$parser_syntax_error (); + + stmts.push (stmt); + } + + stmts.last_linenum = JSC$parser_token_linenum; + + /* One clause parsed. */ + clauses.push (stmts); + } + else + JSC$parser_syntax_error (); + } + + return new JSC$stmt_switch (linenum, JSC$parser_token_linenum, expr, + clauses); +} + + +function JSC$parser_parse_try (stream) +{ + var linenum = JSC$parser_token_linenum; + + var block = JSC$parser_parse_stmt (stream); + if (!block) + JSC$parser_syntax_error (); + + var try_block_last_linenum = JSC$parser_token_linenum; + + /* Now we must see `catch' or `finally'. */ + var token = JSC$parser_peek_token (stream); + if (token != JSC$tCATCH && token != JSC$tFINALLY) + JSC$parser_syntax_error (); + + var catch_list = false; + if (token == JSC$tCATCH) + { + /* Parse catch list. */ + + catch_list = new Array (); + catch_list.linenum = JSC$parser_peek_token_linenum; + + while (token == JSC$tCATCH) + { + JSC$parser_get_token (stream); + var c = new Object (); + c.linenum = JSC$parser_token_linenum; + + if (JSC$parser_get_token (stream) != #'(') + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != JSC$tIDENTIFIER) + JSC$parser_syntax_error (); + c.id = JSC$parser_token_value; + + c.guard = false; + if (JSC$parser_peek_token (stream) == JSC$tIF) + { + JSC$parser_get_token (stream); + c.guard = JSC$parser_parse_expr (stream); + if (!c.guard) + JSC$parser_syntax_error (); + } + + if (JSC$parser_get_token (stream) != #')') + JSC$parser_syntax_error (); + + c.stmt = JSC$parser_parse_stmt (stream); + if (!c.stmt) + JSC$parser_syntax_error (); + + catch_list.push (c); + + token = JSC$parser_peek_token (stream); + } + + catch_list.last_linenum = JSC$parser_token_linenum; + } + + var fin = false; + if (token == JSC$tFINALLY) + { + /* Parse the finally. */ + JSC$parser_get_token (stream); + + fin = JSC$parser_parse_stmt (stream); + if (!fin) + JSC$parser_syntax_error (); + } + + return new JSC$stmt_try (linenum, try_block_last_linenum, + JSC$parser_token_linenum, block, catch_list, + fin); +} + + +function JSC$parser_parse_variable_stmt (stream) +{ + var list, id, expr, token; + + if (JSC$parser_peek_token (stream) != JSC$tVAR) + return false; + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + list = new Array (); + + while (true) + { + token = JSC$parser_peek_token (stream); + if (token == JSC$tIDENTIFIER) + { + JSC$parser_get_token (); + id = JSC$parser_token_value; + + if (JSC$parser_peek_token (stream) == #'=') + { + JSC$parser_get_token (stream); + expr = JSC$parser_parse_assignment_expr (stream); + if (typeof expr == "boolean") + JSC$parser_syntax_error (); + } + else + expr = null; + + list.push (new JSC$var_declaration (id, expr)); + + /* Check if we have more input. */ + if (JSC$parser_peek_token (stream) == #',') + { + /* Yes we have. */ + JSC$parser_get_token (stream); + + /* The next token must be tIDENTIFIER. */ + if (JSC$parser_peek_token (stream) != JSC$tIDENTIFIER) + JSC$parser_syntax_error (); + } + else + { + /* No, we don't. */ + JSC$parser_get_semicolon_asci (stream); + break; + } + } + else + { + /* We'r done. */ + JSC$parser_get_semicolon_asci (stream); + break; + } + } + + /* There must be at least one variable declaration. */ + if (list.length == 0) + JSC$parser_syntax_error (); + + return new JSC$stmt_variable (ln, list); +} + + +function JSC$parser_parse_if_stmt (stream) +{ + var expr, stmt, stmt2; + + if (JSC$parser_peek_token (stream) != JSC$tIF) + return false; + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + if (JSC$parser_get_token (stream) != #'(') + JSC$parser_syntax_error (); + + expr = JSC$parser_parse_expr (stream); + if (typeof expr == "boolean") + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #')') + JSC$parser_syntax_error (); + + stmt = JSC$parser_parse_stmt (stream); + if (typeof stmt == "boolean") + JSC$parser_syntax_error (); + + if (JSC$parser_peek_token (stream) == JSC$tELSE) + { + JSC$parser_get_token (stream); + stmt2 = JSC$parser_parse_stmt (stream); + if (typeof stmt2 == "boolean") + JSC$parser_syntax_error (); + } + else + stmt2 = null; + + return new JSC$stmt_if (ln, expr, stmt, stmt2); +} + + +function JSC$parser_parse_iteration_stmt (stream) +{ + var token, expr1, expr2, expr3, stmt; + + token = JSC$parser_peek_token (stream); + if (token == JSC$tDO) + { + /* do Statement while (Expression); */ + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + stmt = JSC$parser_parse_stmt (stream); + if (typeof stmt == "boolean") + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != JSC$tWHILE) + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #'(') + JSC$parser_syntax_error (); + + expr1 = JSC$parser_parse_expr (stream); + if (typeof expr1 == "boolean") + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #')') + JSC$parser_syntax_error (); + + JSC$parser_get_semicolon_asci (stream); + + return new JSC$stmt_do_while (ln, expr1, stmt); + } + else if (token == JSC$tWHILE) + { + /* while (Expression) Statement */ + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + if (JSC$parser_get_token (stream) != #'(') + JSC$parser_syntax_error (); + + expr1 = JSC$parser_parse_expr (stream); + if (typeof expr1 == "boolean") + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #')') + JSC$parser_syntax_error (); + + stmt = JSC$parser_parse_stmt (stream); + if (typeof stmt == "boolean") + JSC$parser_syntax_error (); + + return new JSC$stmt_while (ln, expr1, stmt); + } + else if (token == JSC$tFOR) + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + if (JSC$parser_get_token (stream) != #'(') + JSC$parser_syntax_error (); + + /* Init */ + + var vars = null; + + token = JSC$parser_peek_token (stream); + if (token == JSC$tVAR) + { + JSC$parser_get_token (stream); + vars = new Array (); + + while (true) + { + /* The identifier. */ + token = JSC$parser_peek_token (stream); + if (token != JSC$tIDENTIFIER) + break; + + JSC$parser_get_token (stream); + var id = JSC$parser_token_value; + + /* Possible initializer. */ + var expr = null; + if (JSC$parser_peek_token (stream) == #'=') + { + JSC$parser_get_token (stream); + expr = JSC$parser_parse_assignment_expr (stream); + if (!expr) + JSC$parser_syntax_error (); + } + + vars.push (new JSC$var_declaration (id, expr)); + + /* Check if we have more input. */ + if (JSC$parser_peek_token (stream) == #',') + { + /* Yes we have. */ + JSC$parser_get_token (stream); + + /* The next token must be tIDENTIFIER. */ + if (JSC$parser_peek_token (stream) != JSC$tIDENTIFIER) + JSC$parser_syntax_error (); + } + else + /* No more input. */ + break; + } + + /* Must have at least one variable declaration. */ + if (vars.length == 0) + JSC$parser_syntax_error (); + } + else if (token != #';') + { + expr1 = JSC$parser_parse_expr (stream); + if (typeof expr1 == "boolean") + JSC$parser_syntax_error (); + } + else + expr1 = null; + + token = JSC$parser_get_token (stream); + var for_in = false; + + if (token == #';') + { + /* Normal for-statement. */ + + /* Check */ + if (JSC$parser_peek_token (stream) != #';') + { + expr2 = JSC$parser_parse_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + } + else + expr2 = null; + + if (JSC$parser_get_token (stream) != #';') + JSC$parser_syntax_error (); + + /* Increment */ + if (JSC$parser_peek_token (stream) != #')') + { + expr3 = JSC$parser_parse_expr (stream); + if (typeof expr3 == "boolean") + JSC$parser_syntax_error (); + } + else + expr3 = null; + } + else if (token == JSC$tIN) + { + /* The `for (VAR in EXPR)'-statement. */ + + for_in = true; + + if (expr1) + { + /* The first expression must be an identifier. */ + if (expr1.etype != JSC$EXPR_IDENTIFIER) + JSC$parser_syntax_error (); + } + else + { + /* We must have only one variable declaration. */ + if (vars.length != 1) + JSC$parser_syntax_error (); + } + + /* The second expressions. */ + expr2 = JSC$parser_parse_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + } + else + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #')') + JSC$parser_syntax_error (); + + /* Stmt. */ + stmt = JSC$parser_parse_stmt (stream); + if (typeof stmt == "boolean") + JSC$parser_syntax_error (); + + if (for_in) + return new JSC$stmt_for_in (ln, vars, expr1, expr2, stmt); + + return new JSC$stmt_for (ln, vars, expr1, expr2, expr3, stmt); + } + return false; +} + + +function JSC$parser_parse_expr (stream) +{ + var expr, expr2; + + if (typeof (expr = JSC$parser_parse_assignment_expr (stream)) + == "boolean") + return false; + + /* Check for the comma expression. */ + while (JSC$parser_peek_token (stream) == #',') + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + if (typeof (expr2 = JSC$parser_parse_assignment_expr (stream)) + == "boolean") + JSC$parser_syntax_error (); + expr = new JSC$expr_comma (ln, expr, expr2); + } + + return expr; +} + + +function JSC$parser_parse_assignment_expr (stream) +{ + var expr, expr2, token; + + if (typeof (expr = JSC$parser_parse_conditional_expr (stream)) + == "boolean") + return false; + + if (JSC$parser_expr_is_left_hand_side (expr)) + { + token = JSC$parser_peek_token (stream); + if (token == #'=' || token == JSC$tMULA + || token == JSC$tDIVA || token == JSC$tMODA + || token == JSC$tADDA || token == JSC$tSUBA + || token == JSC$tLSIA || token == JSC$tRSIA + || token == JSC$tRRSA || token == JSC$tANDA + || token == JSC$tXORA || token == JSC$tORA) + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_assignment_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_assignment (ln, token, expr, expr2); + } + } + + if (JSC$optimize_constant_folding && expr.constant_folding) + return expr.constant_folding (); + + return expr; +} + + +function JSC$parser_parse_conditional_expr (stream) +{ + var expr, expr2, expr3, token; + + if (typeof (expr = JSC$parser_parse_logical_or_expr (stream)) + == "boolean") + return false; + + token = JSC$parser_peek_token (stream); + if (token == #'?') + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_assignment_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #':') + JSC$parser_syntax_error (); + expr3 = JSC$parser_parse_assignment_expr (stream); + if (typeof expr3 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_quest_colon (ln, expr, expr2, expr3); + } + + return expr; +} + + +function JSC$parser_parse_logical_or_expr (stream) +{ + var expr, expr2; + + if (typeof (expr = JSC$parser_parse_logical_and_expr (stream)) + == "boolean") + return false; + + while (JSC$parser_peek_token (stream) == JSC$tOR) + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_logical_and_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_logical_or (ln, expr, expr2); + } + + return expr; +} + + +function JSC$parser_parse_logical_and_expr (stream) +{ + var expr, expr2; + + if (typeof (expr = JSC$parser_parse_bitwise_or_expr (stream)) + == "boolean") + return false; + + while (JSC$parser_peek_token (stream) == JSC$tAND) + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_bitwise_or_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_logical_and (ln, expr, expr2); + } + + return expr; +} + + +function JSC$parser_parse_bitwise_or_expr (stream) +{ + var expr, expr2; + + if (typeof (expr = JSC$parser_parse_bitwise_xor_expr (stream)) + == "boolean") + return false; + + while (JSC$parser_peek_token (stream) == #'|') + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_bitwise_xor_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_bitwise_or (ln, expr, expr2); + } + + return expr; +} + + +function JSC$parser_parse_bitwise_xor_expr (stream) +{ + var expr, expr2; + + if (typeof (expr = JSC$parser_parse_bitwise_and_expr (stream)) + == "boolean") + return false; + + while (JSC$parser_peek_token (stream) == #'^') + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_bitwise_and_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_bitwise_xor (ln, expr, expr2); + } + + return expr; +} + + +function JSC$parser_parse_bitwise_and_expr (stream) +{ + var expr, expr2; + + if (typeof (expr = JSC$parser_parse_equality_expr (stream)) + == "boolean") + return false; + + while (JSC$parser_peek_token (stream) == #'&') + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_equality_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_bitwise_and (ln, expr, expr2); + } + + return expr; +} + + +function JSC$parser_parse_equality_expr (stream) +{ + var expr, expr2, token; + + if (typeof (expr = JSC$parser_parse_relational_expr (stream)) + == "boolean") + return false; + + token = JSC$parser_peek_token (stream); + while (token == JSC$tEQUAL || token == JSC$tNEQUAL + || token == JSC$tSEQUAL || token == JSC$tSNEQUAL) + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_relational_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_equality (ln, token, expr, expr2); + token = JSC$parser_peek_token (stream); + } + + return expr; +} + + +function JSC$parser_parse_relational_expr (stream) +{ + var expr, expr2, token; + + if (typeof (expr = JSC$parser_parse_shift_expr (stream)) + == "boolean") + return false; + + token = JSC$parser_peek_token (stream); + while (token == #'<' || token == #'>' || token == JSC$tLE + || token == JSC$tGE) + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_shift_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_relational (ln, token, expr, expr2); + token = JSC$parser_peek_token (stream); + } + + return expr; +} + + +function JSC$parser_parse_shift_expr (stream) +{ + var expr, expr2, token; + + if (typeof (expr = JSC$parser_parse_additive_expr (stream)) + == "boolean") + return false; + + token = JSC$parser_peek_token (stream); + while (token == JSC$tLSHIFT || token == JSC$tRSHIFT || token == JSC$tRRSHIFT) + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_additive_expr (stream); + + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_shift (ln, token, expr, expr2); + token = JSC$parser_peek_token (stream); + } + + return expr; +} + + +function JSC$parser_parse_additive_expr (stream) +{ + var expr, expr2, token; + + if (typeof (expr = JSC$parser_parse_multiplicative_expr (stream)) + == "boolean") + return false; + + token = JSC$parser_peek_token (stream); + while (token == #'+' || token == #'-') + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_multiplicative_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_additive (ln, token, expr, expr2); + token = JSC$parser_peek_token (stream); + } + + return expr; +} + + +function JSC$parser_parse_multiplicative_expr (stream) +{ + var expr, expr2, token; + + if (typeof (expr = JSC$parser_parse_unary_expr (stream)) == "boolean") + return false; + + token = JSC$parser_peek_token (stream); + while (token == #'*' || token == #'/' || token == #'%') + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_unary_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_multiplicative (ln, token, expr, expr2); + token = JSC$parser_peek_token (stream); + } + + return expr; +} + + +function JSC$parser_parse_unary_expr (stream) +{ + var expr, token; + + token = JSC$parser_peek_token (stream); + if (token == JSC$tDELETE + || token == JSC$tVOID + || token == JSC$tTYPEOF + || token == JSC$tPLUSPLUS + || token == JSC$tMINUSMINUS + || token == #'+' + || token == #'-' + || token == #'~' + || token == #'!') + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr = JSC$parser_parse_unary_expr (stream); + if (typeof expr == "boolean") + JSC$parser_syntax_error (); + + return new JSC$expr_unary (ln, token, expr); + } + + return JSC$parser_parse_postfix_expr (stream); +} + + +function JSC$parser_parse_postfix_expr (stream) +{ + var expr, token; + + if (typeof (expr = JSC$parser_parse_left_hand_side_expr (stream)) + == "boolean") + return false; + + token = JSC$parser_peek_token (stream); + if (token == JSC$tPLUSPLUS || token == JSC$tMINUSMINUS) + { + if (JSC$parser_peek_token_linenum > JSC$parser_token_linenum) + { + if (JSC$warn_missing_semicolon) + JSC$warning (JSC$filename + ":" + + JSC$parser_token_linenum.toString () + + ": warning: automatic semicolon insertion cuts the expression before ++ or --"); + } + else + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + return new JSC$expr_postfix (ln, token, expr); + } + } + + return expr; +} + + +function JSC$parser_parse_left_hand_side_expr (stream) +{ + var expr, args, token, expr2; + + if (typeof (expr = JSC$parser_parse_member_expr (stream)) + == "boolean") + return false; + + /* Parse the possible first pair of arguments. */ + if (JSC$parser_peek_token (stream) == #'(') + { + var ln = JSC$parser_peek_token_linenum; + + args = JSC$parser_parse_arguments (stream); + if (typeof args == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_call (ln, expr, args); + } + else + return expr; + + /* Parse to possibly following arguments and selectors. */ + while ((token = JSC$parser_peek_token (stream)) == #'(' + || token == #'[' || token == #'.') + { + var ln = JSC$parser_peek_token_linenum; + + if (token == #'(') + { + args = JSC$parser_parse_arguments (stream); + expr = new JSC$expr_call (ln, expr, args); + } + else if (token == #'[') + { + JSC$parser_get_token (stream); + + expr2 = JSC$parser_parse_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #']') + JSC$parser_syntax_error (); + + expr = new JSC$expr_object_array (ln, expr, expr2); + } + else + { + JSC$parser_get_token (stream); + if (JSC$parser_get_token (stream) != JSC$tIDENTIFIER) + JSC$parser_syntax_error (); + + expr = new JSC$expr_object_property (ln, expr, + JSC$parser_token_value); + } + } + + return expr; +} + + +function JSC$parser_parse_member_expr (stream) +{ + var expr, args, token, expr2; + + if (typeof (expr = JSC$parser_parse_primary_expr (stream)) + == "boolean") + { + token = JSC$parser_peek_token (stream); + + if (token == JSC$tNEW) + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr = JSC$parser_parse_member_expr (stream); + if (typeof expr == "boolean") + JSC$parser_syntax_error (); + + if (JSC$parser_peek_token (stream) == #'(') + { + args = JSC$parser_parse_arguments (stream); + if (typeof args == "boolean") + JSC$parser_syntax_error (); + } + else + return new JSC$expr_new (ln, expr, null); + + expr = new JSC$expr_new (ln, expr, args); + } + else + return false; + } + + /* Ok, now we have valid starter. */ + token = JSC$parser_peek_token (stream); + while (token == #'[' || token == #'.') + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + if (token == #'[') + { + expr2 = JSC$parser_parse_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #']') + JSC$parser_syntax_error (); + + expr = new JSC$expr_object_array (ln, expr, expr2); + } + else + { + if (JSC$parser_get_token (stream) != JSC$tIDENTIFIER) + JSC$parser_syntax_error (); + + expr = new JSC$expr_object_property (ln, expr, + JSC$parser_token_value); + } + + token = JSC$parser_peek_token (stream); + } + + return expr; +} + + +function JSC$parser_parse_primary_expr (stream) +{ + var token, val; + + token = JSC$parser_peek_token (stream); + var ln = JSC$parser_peek_token_linenum; + + if (token == JSC$tTHIS) + val = new JSC$expr_this (ln); + else if (token == JSC$tIDENTIFIER) + val = new JSC$expr_identifier (ln, JSC$parser_peek_token_value); + else if (token == JSC$tFLOAT) + val = new JSC$expr_float (ln, JSC$parser_peek_token_value); + else if (token == JSC$tINTEGER) + val = new JSC$expr_integer (ln, JSC$parser_peek_token_value); + else if (token == JSC$tSTRING) + val = new JSC$expr_string (ln, JSC$parser_peek_token_value); + else if (token == #'/') + { + /* + * Kludge alert! The regular expression constants (/.../) and + * div operands are impossible to distinguish, based only on the + * lexical analysis. Therefore, we need some syntactical + * knowledge when the regular expression constants are possible + * at all. This is the place where they can appear. In all + * other places, the character `/' is interpreted as a div + * operator. + */ + JSC$parser_get_token (stream); + + return new JSC$expr_regexp (ln, JSC$lexer_read_regexp_constant (stream)); + } + else if (token == JSC$tNULL) + val = new JSC$expr_null (ln); + else if (token == JSC$tTRUE) + val = new JSC$expr_true (ln); + else if (token == JSC$tFALSE) + val = new JSC$expr_false (ln); + else if (token == #'[') + { + /* Array initializer. */ + /* TODO: SharpVarDefinition_{opt} */ + + JSC$parser_get_token (stream); + + var items = new Array (); + var pos = 0; + + while ((token = JSC$parser_peek_token (stream)) != #']') + { + if (token == #',') + { + JSC$parser_get_token (stream); + items[++pos] = false; + continue; + } + + var expr = JSC$parser_parse_assignment_expr (stream); + if (!expr) + JSC$parser_syntax_error (); + + items[pos] = expr; + + /* Got one expression. It must be followed by ',' or ']'. */ + token = JSC$parser_peek_token (stream); + if (token != #',' && token != #']') + JSC$parser_syntax_error (); + } + + val = new JSC$expr_array_initializer (ln, items); + } + else if (token == #'{') + { + /* Object literal. */ + /* TODO: SharpVarDefinition_{opt} */ + + JSC$parser_get_token (stream); + + var items = new Array (); + + while ((token = JSC$parser_peek_token (stream)) != #'}') + { + var pair = new Object (); + + token = JSC$parser_get_token (stream); + + pair.linenum = JSC$linenum; + pair.id_type = token; + pair.id = JSC$parser_token_value; + + if (token != JSC$tIDENTIFIER && token != JSC$tSTRING + && token != JSC$tINTEGER) + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #':') + JSC$parser_syntax_error (); + + pair.expr = JSC$parser_parse_assignment_expr (stream); + if (!pair.expr) + JSC$parser_syntax_error (); + + items.push (pair); + + /* + * Got one property, initializer pair. It must be followed + * by ',' or '}'. + */ + token = JSC$parser_peek_token (stream); + if (token == #',') + { + /* Ok, we have more items. */ + JSC$parser_get_token (stream); + + token = JSC$parser_peek_token (stream); + if (token != JSC$tIDENTIFIER && token != JSC$tSTRING + && token != JSC$tINTEGER) + JSC$parser_syntax_error (); + } + else if (token != #'}' && token) + JSC$parser_syntax_error (); + } + + val = new JSC$expr_object_initializer (ln, items); + } + else if (token == #'(') + { + JSC$parser_get_token (stream); + + val = JSC$parser_parse_expr (stream); + if (typeof val == "boolean" + || JSC$parser_peek_token (stream) != #')') + JSC$parser_syntax_error (); + } + else + return false; + + JSC$parser_get_token (stream); + return val; +} + + +function JSC$parser_parse_arguments (stream) +{ + var args, item; + + if (JSC$parser_peek_token (stream) != #'(') + return false; + + args = new Array (); + + JSC$parser_get_token (stream); + while (JSC$parser_peek_token (stream) != #')') + { + item = JSC$parser_parse_assignment_expr (stream); + if (typeof item == "boolean") + JSC$parser_syntax_error (); + args.push (item); + + var token = JSC$parser_peek_token (stream); + if (token == #',') + JSC$parser_get_token (stream); + else if (token != #')') + JSC$parser_syntax_error (); + } + JSC$parser_get_token (stream); + + return args; +} + + +/* +Local variables: +mode: c +End: +*/ +/* + * Grammar components. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsc/compiler.js,v $ + * $Id: compiler.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* General helpers. */ + +function JSC$gram_reset () +{ + JSC$label_count = 1; + JSC$cont_break = new JSC$ContBreak (); +} + + +function JSC$alloc_label (num_labels) +{ + JSC$label_count += num_labels; + + return JSC$label_count - num_labels; +} + + +function JSC$format_label (num) +{ + return ".L" + num.toString (); +} + + +function JSC$count_locals_from_stmt_list (list) +{ + var i; + + /* First, count how many variables we need at the toplevel. */ + var lcount = 0; + for (i = 0; i < list.length; i++) + lcount += list[i].count_locals (false); + + /* Second, count the maximum amount needed by the nested blocks. */ + var rmax = 0; + for (i = 0; i < list.length; i++) + { + var rc = list[i].count_locals (true); + if (rc > rmax) + rmax = rc; + } + + return lcount + rmax; +} + +/* + * The handling of the `continue' and `break' labels for looping + * constructs. The variable `JSC$cont_break' holds an instance of + * JSC$ContBreak class. The instance contains a valid chain of + * looping constructs and the currently active with and try testing + * levels. The actual `continue', `break', and `return' statements + * investigate the chain and generate appropriate `with_pop' and + * `try_pop' operands. + * + * If the instance variable `inswitch' is true, the continue statement + * is inside a switch statement. In this case, the continue statement + * must pop one item from the stack. That item is the value of the + * case expression. + */ + +function JSC$ContBreakFrame (loop_break, loop_continue, inswitch, label, next) +{ + this.loop_break = loop_break; + this.loop_continue = loop_continue; + this.inswitch = inswitch; + this.label = label; + this.next = next; + + this.with_nesting = 0; + this.try_nesting = 0; +} + + +function JSC$ContBreak () +{ + this.top = new JSC$ContBreakFrame (null, null, false, null); +} + +new JSC$ContBreak (); + +function JSC$ContBreak$push (loop_break, loop_continue, inswitch, label) +{ + this.top = new JSC$ContBreakFrame (loop_break, loop_continue, inswitch, + label, this.top); +} +JSC$ContBreak.prototype.push = JSC$ContBreak$push; + +function JSC$ContBreak$pop () +{ + if (this.top == null) + error ("jsc: internal error: continue-break stack underflow"); + + this.top = this.top.next; +} +JSC$ContBreak.prototype.pop = JSC$ContBreak$pop; + +/* + * Count the currently active `try' nesting that should be removed on + * `return' statement. + */ +function JSC$ContBreak$try_return_nesting () +{ + var f; + var count = 0; + + for (f = this.top; f; f = f.next) + count += f.try_nesting; + + return count; +} +JSC$ContBreak.prototype.try_return_nesting = JSC$ContBreak$try_return_nesting; + +/* + * Count currently active `with' nesting that should be removed on + * `continue' or `break' statement. + */ +function JSC$ContBreak$count_with_nesting (label) +{ + var f; + var count = 0; + + for (f = this.top; f; f = f.next) + { + count += f.with_nesting; + if (label) + { + if (f.label == label) + break; + } + else + if (f.loop_continue) + break; + } + return count; +} +JSC$ContBreak.prototype.count_with_nesting = JSC$ContBreak$count_with_nesting; + +/* + * Count the currently active `try' nesting that should be removed on + * `continue' or `break' statement. + */ +function JSC$ContBreak$count_try_nesting (label) +{ + var f; + var count = 0; + + for (f = this.top; f; f = f.next) + { + count += f.try_nesting; + if (label) + { + if (f.label == label) + break; + } + else + if (f.loop_continue) + break; + } + return count; +} +JSC$ContBreak.prototype.count_try_nesting = JSC$ContBreak$count_try_nesting; + +function JSC$ContBreak$count_switch_nesting (label) +{ + var f; + var count = 0; + + for (f = this.top; f; f = f.next) + { + if (f.inswitch) + count++; + if (label) + { + if (f.label == label) + break; + } + else + if (f.loop_continue) + break; + } + return count; +} +JSC$ContBreak.prototype.count_switch_nesting + = JSC$ContBreak$count_switch_nesting; + +function JSC$ContBreak$get_continue (label) +{ + var f; + + for (f = this.top; f; f = f.next) + if (label) + { + if (f.label == label) + return f.loop_continue; + } + else + if (f.loop_continue) + return f.loop_continue; + + return null; +} +JSC$ContBreak.prototype.get_continue = JSC$ContBreak$get_continue; + +function JSC$ContBreak$get_break (label) +{ + var f; + + for (f = this.top; f; f = f.next) + if (label) + { + if (f.label == label) + return f.loop_break; + } + else + if (f.loop_break) + return f.loop_break; + + return null; +} +JSC$ContBreak.prototype.get_break = JSC$ContBreak$get_break; + +function JSC$ContBreak$is_unique_label (label) +{ + var f; + + for (f = this.top; f; f = f.next) + if (f.label == label) + return false; + + return true; +} +JSC$ContBreak.prototype.is_unique_label = JSC$ContBreak$is_unique_label; + +JSC$cont_break = null; + + +/* Function declaration. */ + +function JSC$function_declaration (ln, lbrace_ln, name, name_given, args, + block, use_arguments_prop) +{ + this.linenum = ln; + this.lbrace_linenum = lbrace_ln; + this.name = name; + this.name_given = name_given; + this.args = args; + this.block = block; + this.use_arguments_prop = use_arguments_prop; + this.asm = JSC$function_declaration_asm; +} + +function JSC$function_declaration_asm () +{ + var i, a; + + /* Define arguments. */ + JSC$ns.push_frame (); + + for (i = 0, a = 2; i < this.args.length; i++, a++) + JSC$ns.define_symbol (this.args[i], JSC$SCOPE_ARG, a, this.linenum); + + /* Define the function name to be a global symbol. */ + new JSC$ASM_symbol (this.linenum, this.name).link (); + + /* Check that function gets the required amount of arguments. */ + new JSC$ASM_load_arg (this.lbrace_linenum, 1).link (); + new JSC$ASM_add_2_i (this.lbrace_linenum).link (); + new JSC$ASM_min_args (this.lbrace_linenum, this.args.length + 2).link (); + + /* Count how many local variables we need. */ + var num_locals = JSC$count_locals_from_stmt_list (this.block); + + /* Is the `arguments' property of function instance used? */ + if (this.use_arguments_prop) + num_locals++; + + if (num_locals > 0) + { + new JSC$ASM_locals (this.lbrace_linenum, num_locals).link (); + if (this.use_arguments_prop) + { + /* + * Create an array for the arguments array and store it to + * the first local variable. + */ + var ln = this.lbrace_linenum; + var locn = JSC$ns.alloc_local (); + JSC$ns.define_symbol ("arguments", JSC$SCOPE_LOCAL, locn, ln); + + new JSC$ASM_const_i0 (ln).link (); + new JSC$ASM_load_global (ln, "Array").link (); + new JSC$ASM_new (ln).link (); + new JSC$ASM_swap (ln).link (); + new JSC$ASM_apop (ln, 2).link (); + new JSC$ASM_store_local (ln, locn).link (); + + /* Push individual argumens to the array. */ + + /* Init the loop counter. */ + new JSC$ASM_const_i0 (ln).link (); + + var l_loop = new JSC$ASM_label (); + var l_out = new JSC$ASM_label (); + + l_loop.link (); + + /* Check if we'r done. */ + new JSC$ASM_dup (ln).link (); + new JSC$ASM_load_arg (ln, 1).link (); + new JSC$ASM_cmp_ge (ln).link (); + new JSC$ASM_iftrue_b (ln, l_out).link (); + + /* Load the nth argument to the top of the stack. */ + new JSC$ASM_dup (ln).link (); + new JSC$ASM_add_2_i (ln).link (); + new JSC$ASM_load_nth_arg (ln).link (); + + /* Push it to the array. */ + new JSC$ASM_const_i1 (ln).link (); + new JSC$ASM_load_local (ln, locn).link (); + new JSC$ASM_call_method (ln, "push").link (); + new JSC$ASM_pop_n (ln, 4).link (); + + /* Increment loop counter and continue. */ + new JSC$ASM_add_1_i (ln).link (); + new JSC$ASM_jmp (ln, l_loop).link (); + + /* We'r done. */ + l_out.link (); + + /* Pop the loop counter. */ + new JSC$ASM_pop (ln).link (); + } + } + + /* Assembler for our body. */ + for (i = 0; i < this.block.length; i++) + this.block[i].asm (); + + /* + * Every function must return something. We could check if all + * control flows in this function ends to a return, but that would + * bee too hard... Just append a return const_undefined. The optimizer + * will remove it if it is not needed. + */ + var ln; + if (this.block.length > 0) + ln = this.block[this.block.length - 1].linenum; + else + ln = this.linenum; + + new JSC$ASM_const_undefined (ln).link (); + new JSC$ASM_return (ln).link (); + + /* Pop our namespace. */ + JSC$ns.pop_frame (); +} + + +function JSC$zero_function () +{ + return 0; +} + + +/* + * Statements. + */ + +/* Block. */ + +function JSC$stmt_block (ln, list) +{ + this.stype = JSC$STMT_BLOCK; + this.linenum = ln; + this.stmts = list; + this.asm = JSC$stmt_block_asm; + this.count_locals = JSC$stmt_block_count_locals; +} + +function JSC$stmt_block_asm () +{ + JSC$ns.push_frame (); + + /* Assembler for our stmts. */ + var i; + for (i = 0; i < this.stmts.length; i++) + this.stmts[i].asm (); + + JSC$ns.pop_frame (); +} + + +function JSC$stmt_block_count_locals (recursive) +{ + if (!recursive) + return 0; + + return JSC$count_locals_from_stmt_list (this.stmts); +} + +/* Function declaration. */ + +function JSC$stmt_function_declaration (ln, container_id, function_id, + given_id) +{ + this.stype = JSC$STMT_FUNCTION_DECLARATION; + this.linenum = ln; + this.container_id = container_id; + this.function_id = function_id; + this.given_id = given_id; + this.asm = JSC$stmt_function_declaration_asm; + this.count_locals = JSC$zero_function; +} + +function JSC$stmt_function_declaration_asm () +{ + new JSC$ASM_load_global (this.linenum, this.function_id).link (); + new JSC$ASM_load_global (this.linenum, this.container_id).link (); + new JSC$ASM_store_property (this.linenum, this.given_id).link (); +} + +/* Empty */ + +function JSC$stmt_empty (ln) +{ + this.stype = JSC$STMT_EMPTY; + this.linenum = ln; + this.asm = JSC$stmt_empty_asm; + this.count_locals = JSC$zero_function; +} + +function JSC$stmt_empty_asm () +{ + /* Nothing here. */ +} + + +/* Continue. */ + +function JSC$stmt_continue (ln, label) +{ + this.stype = JSC$STMT_CONTINUE; + this.linenum = ln; + this.label = label; + this.asm = JSC$stmt_continue_asm; + this.count_locals = JSC$zero_function; +} + +function JSC$stmt_continue_asm () +{ + var l_cont = JSC$cont_break.get_continue (this.label); + + if (l_cont == null) + { + if (this.label) + error (JSC$filename + ":" + this.linenum.toString () + + ": label `" + this.label + + "' not found for continue statement"); + else + error (JSC$filename + ":" + this.linenum.toString () + + ": continue statement not within a loop"); + } + + var nesting = JSC$cont_break.count_with_nesting (this.label); + if (nesting > 0) + new JSC$ASM_with_pop (this.linenum, nesting).link (); + + nesting = JSC$cont_break.count_try_nesting (this.label); + if (nesting > 0) + new JSC$ASM_try_pop (this.linenum, nesting).link (); + + nesting = JSC$cont_break.count_switch_nesting (this.label); + if (nesting > 0) + { + /* Pop the value of the switch expression. */ + if (nesting == 1) + new JSC$ASM_pop (this.linenum).link (); + else + new JSC$ASM_pop_n (this.linenum, nesting).link (); + } + + new JSC$ASM_jmp (this.linenum, l_cont).link (); +} + + +/* Break. */ + +function JSC$stmt_break (ln, label) +{ + this.stype = JSC$STMT_BREAK; + this.linenum = ln; + this.label = label; + this.asm = JSC$stmt_break_asm; + this.count_locals = JSC$zero_function; +} + +function JSC$stmt_break_asm () +{ + var l_break = JSC$cont_break.get_break (this.label); + + if (l_break == null) + { + if (this.label) + error (JSC$filename + ":" + this.linenum.toString () + + ": label `" + this.label + + "' not found for break statement"); + else + error (JSC$filename + ":" + this.linenum.toString() + + ": break statement not within a loop or switch"); + } + + var nesting = JSC$cont_break.count_with_nesting (this.label); + if (nesting > 0) + new JSC$ASM_with_pop (this.linenum, nesting).link (); + + nesting = JSC$cont_break.count_try_nesting (this.label); + if (nesting > 0) + new JSC$ASM_try_pop (this.linenum, nesting).link (); + + /* + * For non-labeled breaks, the switch nesting is handled in the + * stmt_switch(). The code after the label, returned by the + * get_break(), will handle the switch nesting in these cases. + * For the labeled breaks, we must pop the switch nesting here. + */ + if (this.label) + { + nesting = JSC$cont_break.count_switch_nesting (this.label); + if (nesting > 0) + { + if (nesting == 1) + new JSC$ASM_pop (this.linenum).link (); + else + new JSC$ASM_pop_n (this.linenum, nesting).link (); + } + } + + new JSC$ASM_jmp (this.linenum, l_break).link (); +} + + +/* Return. */ + +function JSC$stmt_return (ln, expr) +{ + this.stype = JSC$STMT_RETURN; + this.linenum = ln; + this.expr = expr; + this.asm = JSC$stmt_return_asm; + this.count_locals = JSC$zero_function; +} + +function JSC$stmt_return_asm () +{ + var nesting = JSC$cont_break.try_return_nesting (); + if (nesting > 0) + new JSC$ASM_try_pop (this.linenum, nesting).link (); + + if (this.expr != null) + this.expr.asm (); + else + new JSC$ASM_const_undefined (this.linenum).link (); + + new JSC$ASM_return (this.linenum).link (); +} + + +/* Switch. */ + +function JSC$stmt_switch (ln, last_ln, expr, clauses) +{ + this.stype = JSC$STMT_SWITCH; + this.linenum = ln; + this.last_linenum = last_ln; + this.expr = expr; + this.clauses = clauses; + this.asm = JSC$stmt_switch_asm; + this.count_locals = JSC$stmt_switch_count_locals; +} + +function JSC$stmt_switch_asm () +{ + /* Evaluate the switch expression to the top of the stack. */ + this.expr.asm (); + + /* The switch statement define a break label. */ + var l_break = new JSC$ASM_label (); + JSC$cont_break.push (l_break, null, true, null); + + /* For each clause (except the first), insert check and body labels. */ + var i; + for (i = 1; i < this.clauses.length; i++) + { + this.clauses[i].l_check = new JSC$ASM_label (); + this.clauses[i].l_body = new JSC$ASM_label (); + } + + /* Generate code for each clause. */ + for (i = 0; i < this.clauses.length; i++) + { + /* Is this the last clause? */ + var last = i + 1 >= this.clauses.length; + var c = this.clauses[i]; + + var next_check, next_body; + if (last) + next_check = next_body = l_break; + else + { + next_check = this.clauses[i + 1].l_check; + next_body = this.clauses[i + 1].l_body; + } + + if (c.expr) + { + /* + * Must check if this clause matches the expression. If c.expr + * is null, this is the default clause that matches always. + */ + + if (i > 0) + c.l_check.link (); + + new JSC$ASM_dup (c.linenum).link (); + c.expr.asm (); + new JSC$ASM_cmp_eq (c.linenum).link (); + new JSC$ASM_iffalse_b (c.linenum, next_check).link (); + } + else + { + if (i > 0) + /* The check label for the default case. */ + c.l_check.link (); + } + + /* Generate assembler for the body. */ + if (i > 0) + c.l_body.link (); + + var j; + for (j = 0; j < c.length; j++) + c[j].asm (); + + /* And finally, jump to the next body. (this is the fallthrough case). */ + new JSC$ASM_jmp (c.last_linenum, next_body).link (); + } + + JSC$cont_break.pop (); + + /* The break label. */ + l_break.link (); + + /* Pop the value of the switch expression. */ + new JSC$ASM_pop (this.last_linenum).link (); +} + +function JSC$stmt_switch_count_locals (recursive) +{ + var locals = 0; + var i, j; + + if (recursive) + { + /* For the recursive cases, we need the maximum of our clause stmts. */ + for (i = 0; i < this.clauses.length; i++) + { + var c = this.clauses[i]; + for (j = 0; j < c.length; j++) + { + var l = c[j].count_locals (true); + if (l > locals) + locals = l; + } + } + } + else + { + /* + * The case clauses are not blocks. Therefore, we need the amount, + * needed by the clauses at the top-level. + */ + + for (i = 0; i < this.clauses.length; i++) + { + var c = this.clauses[i]; + for (j = 0; j < c.length; j++) + locals += c[j].count_locals (false); + } + } + + return locals; +} + + +/* With. */ + +function JSC$stmt_with (ln, expr, stmt) +{ + this.stype = JSC$STMT_WITH; + this.linenum = ln; + this.expr = expr; + this.stmt = stmt; + this.asm = JSC$stmt_with_asm; + this.count_locals = JSC$stmt_with_count_locals; +} + +function JSC$stmt_with_asm () +{ + this.expr.asm (); + + new JSC$ASM_with_push (this.linenum).link (); + JSC$cont_break.top.with_nesting++; + + this.stmt.asm (); + + JSC$cont_break.top.with_nesting--; + new JSC$ASM_with_pop (this.linenum, 1).link (); +} + +function JSC$stmt_with_count_locals (recursive) +{ + if (!recursive) + { + if (this.stmt.stype == JSC$STMT_VARIABLE) + return this.stmt.list.length; + + return 0; + } + else + return this.stmt.count_locals (true); +} + + +/* Try. */ + +function JSC$stmt_try (ln, try_block_last_ln, try_last_ln, block, catch_list, + fin) +{ + this.stype = JSC$STMT_TRY; + this.linenum = ln; + this.try_block_last_linenum = try_block_last_ln; + this.try_last_linenum = try_last_ln; + this.block = block; + this.catch_list = catch_list; + this.fin = fin; + this.asm = JSC$stmt_try_asm; + this.count_locals = JSC$stmt_try_count_locals; +} + +function JSC$stmt_try_asm () +{ + var l_finally = new JSC$ASM_label (); + + /* Protect and execute the try-block. */ + + var l_try_error = new JSC$ASM_label (); + new JSC$ASM_try_push (this.linenum, l_try_error).link (); + JSC$cont_break.top.try_nesting++; + + this.block.asm (); + + JSC$cont_break.top.try_nesting--; + new JSC$ASM_try_pop (this.try_block_last_linenum, 1).link (); + + /* + * All ok so far. Push a `false' to indicate no error and jump to + * the finally block (or out if we have no finally block). + */ + new JSC$ASM_const_false (this.try_block_last_linenum).link (); + new JSC$ASM_jmp (this.try_block_last_linenum, l_finally).link (); + + /* + * Handle try block failures. The thrown value is on the top of the + * stack. + */ + + l_try_error.link (); + + if (this.catch_list) + { + /* + * We keep one boolean variable below the thrown value. Its default + * value is false. When one of our catch blocks are entered, it is + * set to true to indicate that we shouldn't throw the error + * anymore. + */ + new JSC$ASM_const_false (this.catch_list.linenum).link (); + new JSC$ASM_swap (this.catch_list.linenum).link (); + + /* Protect and execute the catch list. */ + + var l_catch_list_error = new JSC$ASM_label (); + new JSC$ASM_try_push (this.catch_list.linenum, + l_catch_list_error).link (); + JSC$cont_break.top.try_nesting++; + + /* Insert start and body labels for each catch list item. */ + var i; + for (i = 0; i < this.catch_list.length; i++) + { + this.catch_list[i].l_start = new JSC$ASM_label (); + this.catch_list[i].l_body = new JSC$ASM_label (); + } + + /* A label for the catch list end. */ + var l_catch_list_end = new JSC$ASM_label (); + + /* Process the individual catches. */ + for (i = 0; i < this.catch_list.length; i++) + { + var c = this.catch_list[i]; + + /* This is the starting point of this catch frame. */ + c.l_start.link (); + + /* + * Create a new namespace frame and bind the catch's + * identifier to the thrown exception. + */ + + JSC$ns.push_frame (); + JSC$ns.define_symbol (c.id, JSC$SCOPE_LOCAL, JSC$ns.alloc_local (), + c.linenum); + + new JSC$ASM_dup (c.linenum).link (); + new JSC$ASM_store_local (c.linenum, + JSC$ns.lookup_symbol (c.id).value).link (); + + /* Check the possible guard. We must protect its calculation. */ + if (c.guard) + { + var l_guard_error = new JSC$ASM_label (); + new JSC$ASM_try_push (c.linenum, l_guard_error).link (); + JSC$cont_break.top.try_nesting++; + + /* Calculate the guard. */ + c.guard.asm (); + + JSC$cont_break.top.try_nesting--; + new JSC$ASM_try_pop (c.linenum, 1).link (); + + /* + * Wow! We managed to do it. Now, let's check if we + * accept this catch case. + */ + + var next; + if (i + 1 >= this.catch_list.length) + next = l_catch_list_end; + else + next = this.catch_list[i + 1].l_start; + + if (c.guard.lang_type == JSC$JS_BOOLEAN) + new JSC$ASM_iffalse_b (c.linenum, next).link (); + else + new JSC$ASM_iffalse (c.linenum, next).link (); + + /* Yes, we do accept it. Just jump to do the stuffs. */ + new JSC$ASM_jmp (c.linenum, c.l_body).link (); + + /* + * The evaluation of the guard failed. Do the cleanup + * and jump to the next case. + */ + + l_guard_error.link (); + + /* Pop the exception. */ + new JSC$ASM_pop (c.linenum).link (); + + /* Check the next case. */ + new JSC$ASM_jmp (c.linenum, next).link (); + } + + /* + * We did enter the catch body. Let's update our boolean + * status variable to reflect this fact. + */ + c.l_body.link (); + + new JSC$ASM_swap (c.linenum).link (); + new JSC$ASM_pop (c.linenum).link (); + new JSC$ASM_const_true (c.linenum).link (); + new JSC$ASM_swap (c.linenum).link (); + + /* Code for the catch body. */ + c.stmt.asm (); + + /* We'r done with the namespace frame. */ + JSC$ns.pop_frame (); + + /* + * The next catch tag, or the l_catch_list_end follows us, + * so we don't need a jumps here. + */ + } + + /* + * The catch list was evaluated without errors. + */ + + l_catch_list_end.link (); + JSC$cont_break.top.try_nesting--; + new JSC$ASM_try_pop (this.catch_list.last_linenum, 1).link (); + + /* Did we enter any of our catch lists? */ + + var l_we_did_enter = new JSC$ASM_label (); + new JSC$ASM_swap (this.catch_list.last_linenum).link (); + new JSC$ASM_iftrue_b (this.catch_list.last_linenum, + l_we_did_enter).link (); + + /* No we didn't. */ + + /* + * Push `true' to indicate an exception and jump to the finally + * block. The exception is now on the top of the stack. + */ + new JSC$ASM_const_true (this.catch_list.last_linenum).link (); + new JSC$ASM_jmp (this.catch_list.last_linenum, l_finally).link (); + + /* Yes, we did enter one (or many) of our catch lists. */ + + l_we_did_enter.link (); + + /* Pop the try-block's exception */ + new JSC$ASM_pop (this.catch_list.last_linenum).link (); + + /* + * Push a `false' to indicate "no errors" and jump to the + * finally block. + */ + new JSC$ASM_const_false (this.catch_list.last_linenum).link (); + new JSC$ASM_jmp (this.catch_list.last_linenum, l_finally).link (); + + + /* + * Handle catch list failures. The thrown value is on the top of the + * stack. + */ + + l_catch_list_error.link (); + + /* + * Pop the try-block's exception and our boolean `did we enter a + * catch block' variable. They are below our new exception. + */ + new JSC$ASM_apop (this.catch_list.last_linenum, 2).link (); + + /* + * Push `true' to indicate an exception. We will fallthrough to + * the finally part, so no jump is needed here. + */ + new JSC$ASM_const_true (this.catch_list.last_linenum).link (); + } + else + { + /* No catch list. */ + new JSC$ASM_const_true (this.try_block_last_linenum).link (); + } + + /* The possible finally block. */ + + l_finally.link (); + + if (this.fin) + /* Execute it without protection. */ + this.fin.asm (); + + /* We'r almost there. Let's see if we have to raise a new exception. */ + + var l_out = new JSC$ASM_label (); + new JSC$ASM_iffalse_b (this.try_last_linenum, l_out).link (); + + /* Do raise it. */ + new JSC$ASM_throw (this.try_last_linenum).link (); + + /* The possible exception is handled. Please, continue. */ + l_out.link (); +} + +function JSC$stmt_try_count_locals (recursive) +{ + var count = 0; + var c; + + if (recursive) + { + c = this.block.count_locals (true); + if (c > count) + count = c; + + if (this.catch_list) + { + var i; + for (i = 0; i < this.catch_list.length; i++) + { + c = this.catch_list[i].stmt.count_locals (true); + if (c > count) + count = c; + } + } + if (this.fin) + { + c = this.fin.count_locals (true); + if (c > count) + count = c; + } + } + else + { + if (this.block.stype == JSC$STMT_VARIABLE) + count += this.block.list.length; + + if (this.catch_list) + { + /* One for the call variable. */ + count++; + + var i; + for (i = 0; i < this.catch_list.length; i++) + if (this.catch_list[i].stmt.stype == JSC$STMT_VARIABLE) + count += this.catch_list[i].stmt.list.length; + } + + if (this.fin) + if (this.fin.stype == JSC$STMT_VARIABLE) + count += this.fin.list.length; + } + + return count; +} + + +/* Throw. */ + +function JSC$stmt_throw (ln, expr) +{ + this.stype = JSC$STMT_THROW; + this.linenum = ln; + this.expr = expr; + this.asm = JSC$stmt_throw_asm; + this.count_locals = JSC$zero_function; +} + +function JSC$stmt_throw_asm () +{ + this.expr.asm (); + new JSC$ASM_throw (this.linenum).link (); +} + + +/* Labeled statement. */ +function JSC$stmt_labeled_stmt (ln, id, stmt) +{ + this.stype = JSC$STMT_LABELED_STMT; + this.linenum = ln; + this.id = id; + this.stmt = stmt; + this.asm = JSC$stmt_labeled_stmt_asm; + this.count_locals = JSC$stmt_labeled_stmt_count_locals; +} + +function JSC$stmt_labeled_stmt_asm () +{ + var l_continue = new JSC$ASM_label (); + var l_break = new JSC$ASM_label (); + + /* + * It is an error if we already have a labeled statement with the + * same id. + */ + if (!JSC$cont_break.is_unique_label (this.id)) + error (JSC$filename + ":" + this.linenum.toString () + + ": labeled statement is enclosed by another labeled statement " + + "with the same label"); + + /* Push the break and continue labels. */ + JSC$cont_break.push (l_break, l_continue, false, this.id); + + /* Dump the assembler. */ + l_continue.link (); + this.stmt.asm (); + l_break.link (); + + /* And we'r done with out label scope. */ + JSC$cont_break.pop (); +} + +function JSC$stmt_labeled_stmt_count_locals (recursive) +{ + return this.stmt.count_locals (recursive); +} + + +/* Expression. */ + +function JSC$stmt_expr (expr) +{ + this.stype = JSC$STMT_EXPR; + this.linenum = expr.linenum; + this.expr = expr; + this.asm = JSC$stmt_expr_asm; + this.count_locals = JSC$zero_function; +} + +function JSC$stmt_expr_asm () +{ + this.expr.asm (); + new JSC$ASM_pop (this.linenum).link (); +} + + +/* If. */ + +function JSC$stmt_if (ln, expr, stmt1, stmt2) +{ + this.stype = JSC$STMT_IF; + this.linenum = ln; + this.expr = expr; + this.stmt1 = stmt1; + this.stmt2 = stmt2; + this.asm = JSC$stmt_if_asm; + this.count_locals = JSC$stmt_if_count_locals; +} + +function JSC$stmt_if_asm () +{ + this.expr.asm (); + + var l1 = new JSC$ASM_label (); + var l2 = new JSC$ASM_label (); + + if (JSC$optimize_type && this.expr.lang_type + && this.expr.lang_type == JSC$JS_BOOLEAN) + new JSC$ASM_iffalse_b (this.linenum, l1).link (); + else + new JSC$ASM_iffalse (this.linenum, l1).link (); + + /* Code for the then branch. */ + this.stmt1.asm (); + new JSC$ASM_jmp (this.linenum, l2).link (); + + /* Code for the else branch. */ + l1.link (); + if (this.stmt2 != null) + this.stmt2.asm (); + + /* Done label. */ + l2.link (); +} + + +function JSC$stmt_if_count_locals (recursive) +{ + var lcount; + + if (!recursive) + { + lcount = 0; + if (this.stmt1.stype == JSC$STMT_VARIABLE) + lcount += this.stmt1.list.length; + + if (this.stmt2 != null && this.stmt2.stype == JSC$STMT_VARIABLE) + lcount += this.stmt2.list.length; + } + else + { + lcount = this.stmt1.count_locals (true); + + if (this.stmt2) + { + var c = this.stmt2.count_locals (true); + if (c > lcount) + lcount = c; + } + } + + return lcount; +} + + +/* Do...While. */ + +function JSC$stmt_do_while (ln, expr, stmt) +{ + this.stype = JSC$STMT_DO_WHILE; + this.linenum = ln; + this.expr = expr; + this.stmt = stmt; + this.asm = JSC$stmt_do_while_asm; + this.count_locals = JSC$stmt_do_while_count_locals; +} + +function JSC$stmt_do_while_asm () +{ + var l1 = new JSC$ASM_label (); + var l2 = new JSC$ASM_label (); + var l3 = new JSC$ASM_label (); + + /* Loop label. */ + l1.link (); + + /* Body. */ + JSC$cont_break.push (l3, l2, false, null); + this.stmt.asm (); + JSC$cont_break.pop (); + + /* Condition & continue. */ + l2.link (); + this.expr.asm (); + if (JSC$optimize_type && this.expr.lang_type + && this.expr.lang_type == JSC$JS_BOOLEAN) + new JSC$ASM_iftrue_b (this.linenum, l1).link (); + else + new JSC$ASM_iftrue (this.linenum, l1).link (); + + /* Break label. */ + l3.link (); +} + +function JSC$stmt_do_while_count_locals (recursive) +{ + if (!recursive) + { + if (this.stmt.stype == JSC$STMT_VARIABLE) + return this.stmt.list.length; + + return 0; + } + else + return this.stmt.count_locals (true); +} + +/* While. */ + +function JSC$stmt_while (ln, expr, stmt) +{ + this.stype = JSC$STMT_WHILE; + this.linenum = ln; + this.expr = expr; + this.stmt = stmt; + this.asm = JSC$stmt_while_asm; + this.count_locals = JSC$stmt_while_count_locals; +} + +function JSC$stmt_while_asm () +{ + var l1 = new JSC$ASM_label (); + var l2 = new JSC$ASM_label (); + + /* Loop label. */ + l1.link (); + + /* Condition. */ + this.expr.asm (); + if (JSC$optimize_type && this.expr.lang_type + && this.expr.lang_type == JSC$JS_BOOLEAN) + new JSC$ASM_iffalse_b (this.linenum, l2).link (); + else + new JSC$ASM_iffalse (this.linenum, l2).link (); + + /* Body. */ + JSC$cont_break.push (l2, l1, false, null); + this.stmt.asm (); + JSC$cont_break.pop (); + + /* Goto loop. */ + new JSC$ASM_jmp (this.linenum, l1).link (); + + /* Break label. */ + l2.link (); +} + + +function JSC$stmt_while_count_locals (recursive) +{ + if (!recursive) + { + if (this.stmt.stype == JSC$STMT_VARIABLE) + return this.stmt.list.length; + + return 0; + } + else + return this.stmt.count_locals (true); +} + + +/* For. */ + +function JSC$stmt_for (ln, vars, e1, e2, e3, stmt) +{ + this.stype = JSC$STMT_FOR; + this.linenum = ln; + this.vars = vars; + this.expr1 = e1; + this.expr2 = e2; + this.expr3 = e3; + this.stmt = stmt; + this.asm = JSC$stmt_for_asm; + this.count_locals = JSC$stmt_for_count_locals; +} + +function JSC$stmt_for_asm () +{ + /* Code for the init. */ + if (this.vars) + { + /* We have our own variable scope. */ + JSC$ns.push_frame (); + + var i; + for (i = 0; i < this.vars.length; i++) + { + var decl = this.vars[i]; + + JSC$ns.define_symbol (decl.id, JSC$SCOPE_LOCAL, + JSC$ns.alloc_local (), this.linenum); + + /* Possible init. */ + if (decl.expr) + { + decl.expr.asm (); + + var r = JSC$ns.lookup_symbol (decl.id); + if (r == null || r.scope != JSC$SCOPE_LOCAL) + error (JSC$filename + ":" + this.liennum.toString () + + ": internal compiler error in local variable " + + "declaration in for statement"); + + new JSC$ASM_store_local (this.linenum, r.value).link (); + } + } + } + else if (this.expr1 != null) + { + this.expr1.asm (); + new JSC$ASM_pop (this.linenum).link (); + } + + var l1 = new JSC$ASM_label (); + var l2 = new JSC$ASM_label (); + var l3 = new JSC$ASM_label (); + + /* Loop label. */ + l1.link (); + + /* Condition. */ + var type_op = false; + if (this.expr2 != null) + { + this.expr2.asm (); + if (JSC$optimize_type && this.expr2.lang_type + && this.expr2.lang_type == JSC$JS_BOOLEAN) + type_op = true; + } + else + { + new JSC$ASM_const_true (this.linenum).link (); + type_op = JSC$optimize_type; + } + if (type_op) + new JSC$ASM_iffalse_b (this.linenum, l3).link (); + else + new JSC$ASM_iffalse (this.linenum, l3).link (); + + JSC$cont_break.push (l3, l2, false, null); + /* Body. */ + this.stmt.asm (); + JSC$cont_break.pop (); + + /* Continue label. */ + l2.link (); + + /* Increment. */ + if (this.expr3 != null) + { + this.expr3.asm (); + new JSC$ASM_pop (this.linenum).link (); + } + + /* Goto loop. */ + new JSC$ASM_jmp (this.linenum, l1).link (); + + /* Break label. */ + l3.link (); + + if (this.vars) + /* Pop the local variable scope. */ + JSC$ns.pop_frame (); +} + + +function JSC$stmt_for_count_locals (recursive) +{ + var count = 0; + + if (recursive) + { + if (this.vars) + count += this.vars.length; + + count += this.stmt.count_locals (true); + } + else + { + if (this.stmt.stype == JSC$STMT_VARIABLE) + count += this.stmt.list.length; + } + + return count; +} + + +/* For...in. */ + +function JSC$stmt_for_in (ln, vars, e1, e2, stmt) +{ + this.stype = JSC$STMT_FOR_IN; + this.linenum = ln; + this.vars = vars; + this.expr1 = e1; + this.expr2 = e2; + this.stmt = stmt; + this.asm = JSC$stmt_for_in_asm; + this.count_locals = JSC$stmt_for_in_count_locals; +} + +function JSC$stmt_for_in_asm () +{ + var local_id; + + if (this.vars) + { + /* We need our own variable scope here. */ + JSC$ns.push_frame (); + + var decl = this.vars[0]; + local_id = JSC$ns.alloc_local (); + JSC$ns.define_symbol (decl.id, JSC$SCOPE_LOCAL, local_id, this.linenum); + + /* Possible init. */ + if (decl.expr) + { + decl.expr.asm (); + new JSC$ASM_store_local (this.linenum, local_id).link (); + } + } + + /* Init the world. */ + this.expr2.asm (); + new JSC$ASM_dup (this.linenum).link (); + new JSC$ASM_const_i0 (this.linenum).link (); + new JSC$ASM_swap (this.linenum).link (); + new JSC$ASM_const_i0 (this.linenum).link (); + + var l_loop = new JSC$ASM_label (); + var l_cont = new JSC$ASM_label (); + var l_iffalse_b = new JSC$ASM_label (); + var l_break = new JSC$ASM_label (); + + /* Loop label. */ + l_loop.link (); + + /* Fetch nth. */ + new JSC$ASM_nth (this.linenum).link (); + new JSC$ASM_iffalse_b (this.linenum, l_iffalse_b).link (); + + /* Store value to variable. */ + if (this.vars) + new JSC$ASM_store_local (this.linenum, local_id).link (); + else + JSC$asm_expr_lvalue_store_asm (this.expr1); + + /* Body. */ + JSC$cont_break.push (l_break, l_cont, false, null); + this.stmt.asm (); + JSC$cont_break.pop (); + + /* Continue label. */ + l_cont.link (); + + /* Increment. */ + new JSC$ASM_const_i1 (this.linenum).link (); + new JSC$ASM_add (this.linenum).link (); + new JSC$ASM_dup (this.linenum).link (); + new JSC$ASM_roll (this.linenum, -3).link (); + new JSC$ASM_dup (this.linenum).link (); + new JSC$ASM_roll (this.linenum, 4).link (); + new JSC$ASM_swap (this.linenum).link (); + + /* Goto loop. */ + new JSC$ASM_jmp (this.linenum, l_loop).link (); + + /* Out label. */ + l_iffalse_b.link (); + + new JSC$ASM_pop (this.linenum).link (); + + /* Break label. */ + l_break.link (); + new JSC$ASM_pop_n (this.linenum, 2).link (); + + if (this.vars) + /* Pop the variable scope. */ + JSC$ns.pop_frame (); +} + +function JSC$stmt_for_in_count_locals (recursive) +{ + var count = 0; + + if (recursive) + { + if (this.vars) + count++; + + count += this.stmt.count_locals (true); + } + else + { + if (this.stmt.stype == JSC$STMT_VARIABLE) + count += this.stmt.list.length; + + } + + return count; +} + + +/* Variable. */ + +function JSC$stmt_variable (ln, list) +{ + this.stype = JSC$STMT_VARIABLE; + this.linenum = ln; + this.global_level = false; + this.list = list; + this.asm = JSC$stmt_variable_asm; + this.count_locals = JSC$stmt_variable_count_locals; +} + +function JSC$stmt_variable_asm () +{ + var j, r; + + /* Define all local variables to our namespace. */ + for (j = 0; j < this.list.length; j++) + { + var i = this.list[j]; + + if (!this.global_level) + JSC$ns.define_symbol (i.id, JSC$SCOPE_LOCAL, + JSC$ns.alloc_local (), this.linenum); + if (i.expr) + { + i.expr.asm (); + + if (this.global_level) + new JSC$ASM_store_global (this.linenum, i.id).link (); + else + { + r = JSC$ns.lookup_symbol (i.id); + if (r == null || r.scope != JSC$SCOPE_LOCAL) + error (JSC$filename + ":" + this.linenum.toString() + + ": internal compiler error in local variable declaration"); + + new JSC$ASM_store_local (this.linenum, r.value).link (); + } + } + } +} + +function JSC$stmt_variable_count_locals (recursive) +{ + if (!recursive) + { + if (this.global_level) + /* We define these as global variables. */ + return 0; + + return this.list.length; + } + + return 0; +} + +function JSC$var_declaration (id, expr) +{ + this.id = id; + this.expr = expr; +} + + +/* + * Expressions. + */ + +/* This. */ + +function JSC$expr_this (ln) +{ + this.etype = JSC$EXPR_THIS; + this.linenum = ln; + this.asm = JSC$expr_this_asm; +} + +function JSC$expr_this_asm () +{ + new JSC$ASM_load_arg (this.linenum, 0).link (); +} + +/* Identifier. */ + +function JSC$expr_identifier (ln, value) +{ + this.etype = JSC$EXPR_IDENTIFIER; + this.linenum = ln; + this.value = value; + this.asm = JSC$expr_identifier_asm; +} + +function JSC$expr_identifier_asm () +{ + JSC$asm_expr_lvalue_load_asm (this); +} + +/* Float. */ + +function JSC$expr_float (ln, value) +{ + this.etype = JSC$EXPR_FLOAT; + this.lang_type = JSC$JS_FLOAT; + this.linenum = ln; + this.value = value; + this.asm = JSC$expr_float_asm; +} + +function JSC$expr_float_asm () +{ + new JSC$ASM_const (this.linenum, this.value).link (); +} + +/* Integer. */ + +function JSC$expr_integer (ln, value) +{ + this.etype = JSC$EXPR_INTEGER; + this.lang_type = JSC$JS_INTEGER; + this.linenum = ln; + this.value = value; + this.asm = JSC$expr_integer_asm; +} + +function JSC$expr_integer_asm () +{ + if (this.value == 0) + new JSC$ASM_const_i0 (this.linenum).link (); + else if (this.value == 1) + new JSC$ASM_const_i1 (this.linenum).link (); + else if (this.value == 2) + new JSC$ASM_const_i2 (this.linenum).link (); + else if (this.value == 3) + new JSC$ASM_const_i3 (this.linenum).link (); + else + new JSC$ASM_const_i (this.linenum, this.value).link (); +} + +/* String. */ + +function JSC$expr_string (ln, value) +{ + this.etype = JSC$EXPR_STRING; + this.lang_type = JSC$JS_STRING; + this.linenum = ln; + this.value = value; + this.asm = JSC$expr_string_asm; +} + +function JSC$expr_string_asm () +{ + new JSC$ASM_const (this.linenum, this.value).link (); +} + +/* Regexp. */ + +function JSC$expr_regexp (ln, value) +{ + this.etype = JSC$EXPR_REGEXP; + this.lang_type = JSC$JS_BUILTIN; + this.linenum = ln; + this.value = value; + this.asm = JSC$expr_regexp_asm; +} + +function JSC$expr_regexp_asm () +{ + new JSC$ASM_const (this.linenum, this.value).link (); +} + +/* Array initializer. */ + +function JSC$expr_array_initializer (ln, items) +{ + this.etype = JSC$EXPR_ARRAY_INITIALIZER; + this.lang_type = JSC$JS_ARRAY; + this.linenum = ln; + this.items = items; + this.asm = JSC$expr_array_initializer_asm; +} + +function JSC$expr_array_initializer_asm () +{ + /* Generate assembler for the individual items. */ + + var i; + for (i = this.items.length - 1; i >= 0; i--) + { + if (this.items[i]) + this.items[i].asm (); + else + new JSC$ASM_const_undefined (this.linenum).link (); + } + + /* + * The number of items as a negative integer. The Array object's + * constructor knows that if the number of arguments is negative, it + * is called from the array initializer. Why? Because the code: + * + * new Array (5); + * + * creates an array of length of 5, but code: + * + * [5] + * + * creates an array with one item: integer number five. These cases + * must be separatable from the code and that's why the argument + * counts for the array initializers are negative. + */ + new JSC$ASM_const (this.linenum, -this.items.length).link (); + + /* Call the constructor. */ + new JSC$ASM_load_global (this.linenum, "Array").link (); + new JSC$ASM_new (this.linenum).link (); + new JSC$ASM_swap (this.linenum).link (); + new JSC$ASM_apop (this.linenum, this.items.length + 2).link (); +} + +/* Object initializer. */ + +function JSC$expr_object_initializer (ln, items) +{ + this.etype = JSC$EXPR_OBJECT_INITIALIZER; + this.lang_type = JSC$JS_OBJECT; + this.linenum = ln; + this.items = items; + this.asm = JSC$expr_object_initializer_asm; +} + +function JSC$expr_object_initializer_asm () +{ + /* Create a new object. */ + new JSC$ASM_const_i0 (this.linenum).link (); + new JSC$ASM_load_global (this.linenum, "Object").link (); + new JSC$ASM_new (this.linenum).link (); + new JSC$ASM_swap (this.linenum).link (); + new JSC$ASM_apop (this.linenum, 2).link (); + + /* Insert the items. */ + for (var i = 0; i < this.items.length; i++) + { + var item = this.items[i]; + + new JSC$ASM_dup (item.linenum).link (); + item.expr.asm (); + new JSC$ASM_swap (item.linenum).link (); + + switch (item.id_type) + { + case JSC$tIDENTIFIER: + new JSC$ASM_store_property (item.linenum, item.id).link (); + break; + + case JSC$tSTRING: + new JSC$ASM_const (item.linenum, item.id).link (); + new JSC$ASM_store_array (item.linenum).link (); + break; + + case JSC$tINTEGER: + switch (item.id) + { + case 0: + new JSC$ASM_const_i0 (item.linenum).link (); + break; + + case 1: + new JSC$ASM_const_i1 (item.linenum).link (); + break; + + case 2: + new JSC$ASM_const_i2 (item.linenum).link (); + break; + + case 3: + new JSC$ASM_const_i3 (item.linenum).link (); + break; + + default: + new JSC$ASM_const_i (item.linenum, item.id).link (); + break; + } + new JSC$ASM_store_array (item.linenum).link (); + break; + } + } +} + + +/* Null. */ + +function JSC$expr_null (ln) +{ + this.etype = JSC$EXPR_NULL; + this.lang_type = JSC$JS_NULL; + this.linenum = ln; + this.asm = JSC$expr_null_asm; +} + +function JSC$expr_null_asm () +{ + new JSC$ASM_const_null (this.linenum).link (); +} + +/* True. */ + +function JSC$expr_true (ln) +{ + this.etype = JSC$EXPR_TRUE; + this.lang_type = JSC$JS_BOOLEAN; + this.linenum = ln; + this.asm = JSC$expr_true_asm; +} + +function JSC$expr_true_asm () +{ + new JSC$ASM_const_true (this.linenum).link (); +} + +/* False. */ + +function JSC$expr_false (ln) +{ + this.etype = JSC$EXPR_FALSE; + this.lang_type = JSC$JS_BOOLEAN; + this.linenum = ln; + this.asm = JSC$expr_false_asm; +} + +function JSC$expr_false_asm () +{ + new JSC$ASM_const_false (this.linenum).link (); +} + + +/* Multiplicative expr. */ + +function JSC$expr_multiplicative (ln, type, e1, e2) +{ + this.etype = JSC$EXPR_MULTIPLICATIVE; + this.linenum = ln; + this.type = type; + this.e1 = e1; + this.e2 = e2; + this.asm = JSC$expr_multiplicative_asm; +} + +function JSC$expr_multiplicative_asm () +{ + this.e1.asm (); + this.e2.asm (); + if (this.type == #'*') + new JSC$ASM_mul (this.linenum).link (); + else if (this.type == #'/') + new JSC$ASM_div (this.linenum).link (); + else + new JSC$ASM_mod (this.linenum).link (); +} + + +/* Additive expr. */ + +function JSC$expr_additive (ln, type, e1, e2) +{ + this.etype = JSC$EXPR_ADDITIVE; + this.linenum = ln; + this.type = type; + this.e1 = e1; + this.e2 = e2; + this.asm = JSC$expr_additive_asm; + this.constant_folding = JSC$expr_additive_constant_folding; +} + +function JSC$expr_additive_asm () +{ + this.e1.asm (); + this.e2.asm (); + if (this.type == #'+') + new JSC$ASM_add (this.linenum).link (); + else + new JSC$ASM_sub (this.linenum).link (); +} + +function JSC$expr_additive_constant_folding () +{ + if (this.e1.constant_folding) + this.e1 = this.e1.constant_folding (); + if (this.e2.constant_folding) + this.e2 = this.e2.constant_folding (); + + /* This could be smarter. */ + if (this.e1.lang_type && this.e2.lang_type + && this.e1.lang_type == this.e2.lang_type) + { + switch (this.e1.lang_type) + { + case JSC$JS_INTEGER: + return new JSC$expr_integer (this.linenum, + this.type == #'+' + ? this.e1.value + this.e2.value + : this.e1.value - this.e2.value); + break; + + case JSC$JS_FLOAT: + return new JSC$expr_float (this.linenum, + this.type == #'+' + ? this.e1.value + this.e2.value + : this.e1.value - this.e2.value); + break; + + case JSC$JS_STRING: + if (this.type == #'+') + /* Only the addition is available for the strings. */ + return new JSC$expr_string (this.linenum, + this.e1.value + this.e2.value); + break; + + default: + /* FALLTHROUGH */ + break; + } + } + + return this; +} + +/* Shift expr. */ + +function JSC$expr_shift (ln, type, e1, e2) +{ + this.etype = JSC$EXPR_SHIFT; + this.linenum = ln; + this.type = type; + this.e1 = e1; + this.e2 = e2; + this.asm = JSC$expr_shift_asm; +} + +function JSC$expr_shift_asm () +{ + this.e1.asm (); + this.e2.asm (); + + if (this.type == JSC$tLSHIFT) + new JSC$ASM_shift_left (this.linenum).link (); + else if (this.type == JSC$tRSHIFT) + new JSC$ASM_shift_right (this.linenum).link (); + else + new JSC$ASM_shift_rright (this.linenum).link (); +} + + +/* Relational expr. */ + +function JSC$expr_relational (ln, type, e1, e2) +{ + this.etype = JSC$EXPR_RELATIONAL; + this.lang_type = JSC$JS_BOOLEAN; + this.linenum = ln; + this.type = type; + this.e1 = e1; + this.e2 = e2; + this.asm = JSC$expr_relational_asm; +} + +function JSC$expr_relational_asm () +{ + this.e1.asm (); + this.e2.asm (); + + if (this.type == #'<') + new JSC$ASM_cmp_lt (this.linenum).link (); + else if (this.type == #'>') + new JSC$ASM_cmp_gt (this.linenum).link (); + else if (this.type == JSC$tLE) + new JSC$ASM_cmp_le (this.linenum).link (); + else + new JSC$ASM_cmp_ge (this.linenum).link (); +} + + +/* Equality expr. */ + +function JSC$expr_equality (ln, type, e1, e2) +{ + this.etype = JSC$EXPR_EQUALITY; + this.lang_type = JSC$JS_BOOLEAN; + this.linenum = ln; + this.type = type; + this.e1 = e1; + this.e2 = e2; + this.asm = JSC$expr_equality_asm; +} + +function JSC$expr_equality_asm () +{ + this.e1.asm (); + this.e2.asm (); + + switch (this.type) + { + case JSC$tEQUAL: + new JSC$ASM_cmp_eq (this.linenum).link (); + break; + + case JSC$tNEQUAL: + new JSC$ASM_cmp_ne (this.linenum).link (); + break; + + case JSC$tSEQUAL: + new JSC$ASM_cmp_seq (this.linenum).link (); + break; + + case JSC$tSNEQUAL: + new JSC$ASM_cmp_sne (this.linenum).link (); + break; + + default: + error ("jsc: expr_equality: internal compiler error"); + break; + } +} + + +/* Bitwise and expr. */ + +function JSC$expr_bitwise_and (ln, e1, e2) +{ + this.etype = JSC$EXPR_BITWISE; + this.linenum = ln; + this.e1 = e1; + this.e2 = e2; + this.asm = JSC$expr_bitwise_and_asm; +} + +function JSC$expr_bitwise_and_asm () +{ + this.e1.asm (); + this.e2.asm (); + + new JSC$ASM_and (this.linenum).link (); +} + + +/* Bitwise or expr. */ + +function JSC$expr_bitwise_or (ln, e1, e2) +{ + this.etype = JSC$EXPR_BITWISE; + this.linenum = ln; + this.e1 = e1; + this.e2 = e2; + this.asm = JSC$expr_bitwise_or_asm; +} + +function JSC$expr_bitwise_or_asm () +{ + this.e1.asm (); + this.e2.asm (); + + new JSC$ASM_or (this.linenum).link (); +} + + +/* Bitwise xor expr. */ + +function JSC$expr_bitwise_xor (ln, e1, e2) +{ + this.etype = JSC$EXPR_BITWISE; + this.linenum = ln; + this.e1 = e1; + this.e2 = e2; + this.asm = JSC$expr_bitwise_xor_asm; +} + +function JSC$expr_bitwise_xor_asm () +{ + this.e1.asm (); + this.e2.asm (); + + new JSC$ASM_xor (this.linenum).link (); +} + + +/* Logical and expr. */ + +function JSC$expr_logical_and (ln, e1, e2) +{ + this.etype = JSC$EXPR_LOGICAL; + + if (e1.lang_type && e2.lang_type + && e1.lang_type == JSC$JS_BOOLEAN && e2.lang_type == JSC$JS_BOOLEAN) + this.lang_type = JSC$JS_BOOLEAN; + + this.linenum = ln; + this.e1 = e1; + this.e2 = e2; + this.asm = JSC$expr_logical_and_asm; +} + +function JSC$expr_logical_and_asm () +{ + this.e1.asm (); + + var l = new JSC$ASM_label (); + new JSC$ASM_dup (this.linenum).link (); + + if (JSC$optimize_type && this.e1.lang_type + && this.e1.lang_type == JSC$JS_BOOLEAN) + new JSC$ASM_iffalse_b (this.linenum, l).link (); + else + new JSC$ASM_iffalse (this.linenum, l).link (); + + new JSC$ASM_pop (this.linenum).link (); + + this.e2.asm (); + + /* Done label. */ + l.link (); +} + + +/* Logical or expr. */ + +function JSC$expr_logical_or (ln, e1, e2) +{ + this.etype = JSC$EXPR_LOGICAL; + + if (e1.lang_type && e2.lang_type + && e1.lang_type == JSC$JS_BOOLEAN && e2.lang_type == JSC$JS_BOOLEAN) + this.lang_type = JSC$JS_BOOLEAN; + + this.linenum = ln; + this.e1 = e1; + this.e2 = e2; + this.asm = JSC$expr_logical_or_asm; +} + +function JSC$expr_logical_or_asm () +{ + this.e1.asm (); + + var l = new JSC$ASM_label (); + new JSC$ASM_dup (this.linenum).link (); + + if (JSC$optimize_type && this.e1.lang_type + && this.e1.lang_type == JSC$JS_BOOLEAN) + new JSC$ASM_iftrue_b (this.linenum, l).link (); + else + new JSC$ASM_iftrue (this.linenum, l).link (); + + new JSC$ASM_pop (this.linenum).link (); + + this.e2.asm (); + + /* Done label. */ + l.link (); +} + + +/* New expr. */ + +function JSC$expr_new (ln, expr, args) +{ + this.etype = JSC$EXPR_NEW; + this.linenum = ln; + this.expr = expr; + this.args = args; + this.asm = JSC$expr_new_asm; +} + +function JSC$expr_new_asm () +{ + var i; + + if (this.args) + { + /* Code for the arguments. */ + for (i = this.args.length - 1; i >= 0; i--) + this.args[i].asm (); + + if (this.args.length == 0) + new JSC$ASM_const_i0 (this.linenum).link (); + else if (this.args.length == 1) + new JSC$ASM_const_i1 (this.linenum).link (); + else if (this.args.length == 2) + new JSC$ASM_const_i2 (this.linenum).link (); + else if (this.args.length == 3) + new JSC$ASM_const_i3 (this.linenum).link (); + else + new JSC$ASM_const (this.linenum, this.args.length).link (); + } + else + { + /* A `new Foo' call. This is identical to `new Foo ()'. */ + new JSC$ASM_const_i0 (this.linenum).link (); + } + + /* Object. */ + this.expr.asm (); + + /* Call new. */ + new JSC$ASM_new (this.linenum).link (); + + /* Replace the constructor's return value with the object. */ + new JSC$ASM_swap (this.linenum).link (); + + /* Remove the arguments and return the new object. */ + new JSC$ASM_apop (this.linenum, + (this.args ? this.args.length : 0) + 2).link (); +} + + +/* Object property expr. */ + +function JSC$expr_object_property (ln, expr, id) +{ + this.etype = JSC$EXPR_OBJECT_PROPERTY; + this.linenum = ln; + this.expr = expr; + this.id = id; + this.asm = JSC$expr_object_property_asm; +} + +function JSC$expr_object_property_asm () +{ + JSC$asm_expr_lvalue_load_asm (this); +} + + +/* Object array expr. */ + +function JSC$expr_object_array (ln, expr1, expr2) +{ + this.etype = JSC$EXPR_OBJECT_ARRAY; + this.linenum = ln; + this.expr1 = expr1; + this.expr2 = expr2; + this.asm = JSC$expr_object_array_asm; +} + +function JSC$expr_object_array_asm () +{ + JSC$asm_expr_lvalue_load_asm (this); +} + + +/* Call. */ + +function JSC$expr_call (ln, expr, args) +{ + this.etype = JSC$EXPR_CALL; + this.linenum = ln; + this.expr = expr; + this.args = args; + this.asm = JSC$expr_call_asm; +} + +function JSC$expr_call_asm () +{ + var i; + + /* Code for the arguments. */ + for (i = this.args.length - 1; i >= 0; i--) + this.args[i].asm (); + + if (this.args.length == 0) + new JSC$ASM_const_i0 (this.linenum).link (); + else if (this.args.length == 1) + new JSC$ASM_const_i1 (this.linenum).link (); + else if (this.args.length == 2) + new JSC$ASM_const_i2 (this.linenum).link (); + else if (this.args.length == 3) + new JSC$ASM_const_i3 (this.linenum).link (); + else + new JSC$ASM_const (this.linenum, this.args.length).link (); + + /* Check the function type. */ + if (this.expr.etype == JSC$EXPR_IDENTIFIER) + { + /* The simple subroutine or global object method invocation. */ + + var saved_with_nesting = JSC$cont_break.top.with_nesting; + JSC$cont_break.top.with_nesting = 0; + + JSC$asm_expr_lvalue_load_asm (this.expr); + + JSC$cont_break.top.with_nesting = saved_with_nesting; + + if (JSC$cont_break.top.with_nesting > 0) + new JSC$ASM_jsr_w (this.linenum, this.expr.value).link (); + else + new JSC$ASM_jsr (this.linenum).link (); + + new JSC$ASM_apop (this.linenum, this.args.length + 2).link (); + } + else if (this.expr.etype == JSC$EXPR_OBJECT_PROPERTY) + { + /* Method invocation. */ + this.expr.expr.asm (); + new JSC$ASM_call_method (this.linenum, this.expr.id).link (); + new JSC$ASM_apop (this.linenum, this.args.length + 2).link (); + } + else + { + /* Something like a function pointer invocation. */ + JSC$asm_expr_lvalue_load_asm (this.expr); + new JSC$ASM_jsr (this.linenum).link (); + new JSC$ASM_apop (this.linenum, this.args.length + 2).link (); + } +} + + +/* Assignment. */ + +function JSC$expr_assignment (ln, type, expr1, expr2) +{ + this.etype = JSC$EXPR_ASSIGNMENT; + this.linenum = ln; + this.type = type; + this.expr1 = expr1; + this.expr2 = expr2; + this.asm = JSC$expr_assignment_asm; +} + +function JSC$expr_assignment_asm () +{ + if (this.type != #'=') + JSC$asm_expr_lvalue_load_asm (this.expr1); + + /* Count the rvalue. */ + this.expr2.asm (); + + if (this.type == #'=') + /* Nothing here. */ + ; + else if (this.type == JSC$tMULA) + new JSC$ASM_mul (this.linenum).link (); + else if (this.type == JSC$tDIVA) + new JSC$ASM_div (this.linenum).link (); + else if (this.type == JSC$tMODA) + new JSC$ASM_mod (this.linenum).link (); + else if (this.type == JSC$tADDA) + new JSC$ASM_add (this.linenum).link (); + else if (this.type == JSC$tSUBA) + new JSC$ASM_sub (this.linenum).link (); + else if (this.type == JSC$tLSIA) + new JSC$ASM_shift_left (this.linenum).link (); + else if (this.type == JSC$tRSIA) + new JSC$ASM_shift_right (this.linenum).link (); + else if (this.type == JSC$tRRSA) + new JSC$ASM_shift_rright (this.linenum).link (); + else if (this.type == JSC$tANDA) + new JSC$ASM_and (this.linenum).link (); + else if (this.type == JSC$tXORA) + new JSC$ASM_xor (this.linenum).link (); + else if (this.type == JSC$tORA) + new JSC$ASM_or (this.linenum).link (); + else + error (JSC$filename + ":" + this.linenum.toString () + + ": internal compiler error in assignment expression"); + + /* Duplicate the value. */ + new JSC$ASM_dup (this.linenum).link (); + + /* Store it to the lvalue. */ + JSC$asm_expr_lvalue_store_asm (this.expr1); +} + +function JSC$asm_expr_lvalue_load_asm (expr) +{ + var i; + + if (expr.etype == JSC$EXPR_IDENTIFIER) + { + /* Must check global / local / argument. */ + i = JSC$ns.lookup_symbol (expr.value); + if (i == null) + { + if (JSC$cont_break.top.with_nesting > 0) + new JSC$ASM_load_global_w (expr.linenum, expr.value).link (); + else + new JSC$ASM_load_global (expr.linenum, expr.value).link (); + } + else if (i.scope == JSC$SCOPE_ARG) + { + if (JSC$cont_break.top.with_nesting > 0 && JSC$warn_with_clobber) + JSC$warning (JSC$filename + ":" + expr.linenum.toString () + + ": warning: the with-lookup of symbol `" + i.symbol + + "' is clobbered by the argument definition"); + + new JSC$ASM_load_arg (expr.linenum, i.value).link (); + } + else + { + if (JSC$cont_break.top.with_nesting > 0 && JSC$warn_with_clobber) + JSC$warning (JSC$filename + ":" + expr.linenum.toString () + + ": warning: the with-lookup of symbol `" + i.symbol + + "' is clobbered by the local variable definition"); + + new JSC$ASM_load_local (expr.linenum, i.value).link (); + } + } + else if (expr.etype == JSC$EXPR_OBJECT_PROPERTY) + { + expr.expr.asm (); + new JSC$ASM_load_property (expr.linenum, expr.id).link (); + } + else if (expr.etype == JSC$EXPR_OBJECT_ARRAY) + { + expr.expr1.asm (); + expr.expr2.asm (); + new JSC$ASM_load_array (expr.linenum).link (); + } + else + error (JSC$filename + ":" + expr.linenum.toString () + ": syntax error"); +} + +function JSC$asm_expr_lvalue_store_asm (expr) +{ + var i; + + if (expr.etype == JSC$EXPR_IDENTIFIER) + { + i = JSC$ns.lookup_symbol (expr.value); + if (i == null) + new JSC$ASM_store_global (expr.linenum, expr.value).link (); + else if (i.scope == JSC$SCOPE_ARG) + new JSC$ASM_store_arg (expr.linenum, i.value).link (); + else + new JSC$ASM_store_local (expr.linenum, i.value).link (); + } + else if (expr.etype == JSC$EXPR_OBJECT_PROPERTY) + { + expr.expr.asm (); + new JSC$ASM_store_property (expr.linenum, expr.id).link (); + } + else if (expr.etype == JSC$EXPR_OBJECT_ARRAY) + { + expr.expr1.asm (); + expr.expr2.asm (); + new JSC$ASM_store_array (expr.linenum).link (); + } + else + error (JSC$filename + ":" + expr.linenum.toString () + ": syntax error"); +} + + +/* Quest colon. */ + +function JSC$expr_quest_colon (ln, e1, e2, e3) +{ + this.etype = JSC$EXPR_QUEST_COLON; + this.linenum = ln; + this.e1 = e1; + this.e2 = e2; + this.e3 = e3; + this.asm = JSC$expr_quest_colon_asm; +} + +function JSC$expr_quest_colon_asm() +{ + /* Code for the condition. */ + this.e1.asm (); + + var l1 = new JSC$ASM_label (); + var l2 = new JSC$ASM_label (); + + if (JSC$optimize_type && this.e1.lang_type + && this.e1.lang_type == JSC$JS_BOOLEAN) + new JSC$ASM_iffalse_b (this.linenum, l1).link (); + else + new JSC$ASM_iffalse (this.linenum, l1).link (); + + /* Code for the true branch. */ + this.e2.asm (); + new JSC$ASM_jmp (this.linenum, l2).link (); + + /* Code for the false branch. */ + l1.link (); + this.e3.asm (); + + /* Done label. */ + l2.link (); +} + + +/* Unary. */ + +function JSC$expr_unary (ln, type, expr) +{ + this.etype = JSC$EXPR_UNARY; + this.linenum = ln; + this.type = type; + this.expr = expr; + this.asm = JSC$expr_unary_asm; +} + +function JSC$expr_unary_asm () +{ + if (this.type == #'!') + { + this.expr.asm (); + new JSC$ASM_not (this.linenum).link (); + } + else if (this.type == #'+') + { + this.expr.asm (); + /* Nothing here. */ + } + else if (this.type == #'~') + { + this.expr.asm (); + new JSC$ASM_const (this.linenum, -1).link (); + new JSC$ASM_xor (this.linenum).link (); + } + else if (this.type == #'-') + { + this.expr.asm (); + new JSC$ASM_neg (this.linenum).link (); + } + else if (this.type == JSC$tDELETE) + { + if (this.expr.etype == JSC$EXPR_OBJECT_PROPERTY) + { + this.expr.expr.asm (); + new JSC$ASM_delete_property (this.linenum, this.expr.id).link (); + } + else if (this.expr.etype == JSC$EXPR_OBJECT_ARRAY) + { + this.expr.expr1.asm (); + this.expr.expr2.asm (); + new JSC$ASM_delete_array (this.linenum).link (); + } + else if (this.expr.etype == JSC$EXPR_IDENTIFIER) + { + if (JSC$cont_break.top.with_nesting == 0) + error (JSC$filename + ":" + this.linenum.toString () + + ": `delete property' called outside of a with-block"); + + new JSC$ASM_const_null (this.linenum).link (); + new JSC$ASM_delete_property (this.linenum, this.expr.value).link (); + } + else + error (JSC$filename + ":" + this.linenum.toString () + + ": illegal target for the delete operand"); + } + else if (this.type == JSC$tVOID) + { + this.expr.asm (); + new JSC$ASM_pop (this.linenum).link (); + new JSC$ASM_const_undefined (this.linenum).link (); + } + else if (this.type == JSC$tTYPEOF) + { + this.expr.asm (); + new JSC$ASM_typeof (this.linenum).link (); + } + else if (this.type == JSC$tPLUSPLUS + || this.type == JSC$tMINUSMINUS) + { + /* Fetch the old value. */ + JSC$asm_expr_lvalue_load_asm (this.expr); + + /* Do the operation. */ + new JSC$ASM_const_i1 (this.linenum).link (); + if (this.type == JSC$tPLUSPLUS) + new JSC$ASM_add (this.linenum).link (); + else + new JSC$ASM_sub (this.linenum).link (); + + /* Duplicate the value and store one copy pack to lvalue. */ + new JSC$ASM_dup (this.linenum).link (); + JSC$asm_expr_lvalue_store_asm (this.expr); + } + else + { + error ("jsc: internal error: unary expr's type is " + + this.type.toString ()); + } +} + + +/* Postfix. */ + +function JSC$expr_postfix (ln, type, expr) +{ + this.etype = JSC$EXPR_POSTFIX; + this.linenum = ln; + this.type = type; + this.expr = expr; + this.asm = JSC$expr_postfix_asm; +} + +function JSC$expr_postfix_asm () +{ + /* Fetch the old value. */ + JSC$asm_expr_lvalue_load_asm (this.expr); + + /* Duplicate the value since it is the expression's value. */ + new JSC$ASM_dup (this.linenum).link (); + + /* Do the operation. */ + new JSC$ASM_const_i1 (this.linenum).link (); + if (this.type == JSC$tPLUSPLUS) + new JSC$ASM_add (this.linenum).link (); + else + new JSC$ASM_sub (this.linenum).link (); + + /* And finally, store it back. */ + JSC$asm_expr_lvalue_store_asm (this.expr); +} + + +/* Postfix. */ + +function JSC$expr_comma (ln, expr1, expr2) +{ + this.etype = JSC$EXPR_COMMA; + this.linenum = ln; + this.expr1 = expr1; + this.expr2 = expr2; + this.asm = JSC$expr_comma_asm; +} + +function JSC$expr_comma_asm () +{ + this.expr1.asm (); + new JSC$ASM_pop (this.linenum).link (); + this.expr2.asm (); +} + + +/* +Local variables: +mode: c +End: +*/ +/* + * Namespace handling. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsc/compiler.js,v $ + * $Id: compiler.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * Global functions. + */ + +JSC$SCOPE_ARG = 1; +JSC$SCOPE_LOCAL = 2; + +function JSC$NameSpace () +{ + this.frame = new JSC$NameSpaceFrame (); + this.push_frame = JSC$NameSpace_push_frame; + this.pop_frame = JSC$NameSpace_pop_frame; + this.alloc_local = JSC$NameSpace_alloc_local; + this.define_symbol = JSC$NameSpace_define_symbol; + this.lookup_symbol = JSC$NameSpace_lookup_symbol; +} + + +function JSC$NameSpace_push_frame () +{ + var f = new JSC$NameSpaceFrame (); + + f.num_locals = this.frame.num_locals; + + f.next = this.frame; + this.frame = f; +} + + +function JSC$NameSpace_pop_frame () +{ + var i; + + for (i = this.frame.defs; i != null; i = i.next) + if (i.usecount == 0) + { + if (i.scope == JSC$SCOPE_ARG) + { + if (JSC$warn_unused_argument) + JSC$warning (JSC$filename + ":" + i.linenum.toString () + + ": warning: unused argument `" + i.symbol + "'"); + } + else + { + if (JSC$warn_unused_variable) + JSC$warning (JSC$filename + ":" + i.linenum.toString () + + ": warning: unused variable `" + i.symbol + "'"); + } + } + + this.frame = this.frame.next; +} + + +function JSC$NameSpace_alloc_local () +{ + return this.frame.num_locals++; +} + + +function JSC$NameSpace_define_symbol (symbol, scope, value, linenum) +{ + var i; + + for (i = this.frame.defs; i != null; i = i.next) + if (i.symbol == symbol) + { + if (i.scope == scope) + error (JSC$filename + ":" + i.linenum.toString() + + ": redeclaration of `" + i.symbol + "'"); + if (i.scope == JSC$SCOPE_ARG && JSC$warn_shadow) + JSC$warning (JSC$filename + ":" + linenum.toString () + + ": warning: declaration of `" + symbol + + "' shadows a parameter"); + + i.scope = scope; + i.value = value; + i.linenum = linenum; + + return; + } + + /* Create a new definition. */ + i = new JSC$SymbolDefinition (symbol, scope, value, linenum); + i.next = this.frame.defs; + this.frame.defs = i; +} + + +function JSC$NameSpace_lookup_symbol (symbol) +{ + var f, i; + + for (f = this.frame; f != null; f = f.next) + for (i = f.defs; i != null; i = i.next) + if (i.symbol == symbol) + { + i.usecount++; + return i; + } + + return null; +} + +/* + * Static helpers. + */ + +function JSC$NameSpaceFrame () +{ + this.next = null; + this.defs = null; + this.num_locals = 0; +} + + +function JSC$SymbolDefinition (symbol, scope, value, linenum) +{ + this.next = null; + this.symbol = symbol; + this.scope = scope; + this.value = value; + this.linenum = linenum; + this.usecount = 0; +} + + +/* +Local variables: +mode: c +End: +*/ +/* + * Input stream definitions. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsc/compiler.js,v $ + * $Id: compiler.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * File stream. + */ + +function JSC$StreamFile (name) +{ + this.name = name; + this.stream = new File (name); + this.error = ""; + + this.open = JSC$StreamFile_open; + this.close = JSC$StreamFile_close; + this.rewind = JSC$StreamFile_rewind; + this.readByte = JSC$StreamFile_read_byte; + this.ungetByte = JSC$StreamFile_unget_byte; + this.readln = JSC$StreamFile_readln; +} + + +function JSC$StreamFile_open () +{ + if (!this.stream.open ("r")) + { + this.error = System.strerror (System.errno); + return false; + } + + return true; +} + + +function JSC$StreamFile_close () +{ + return this.stream.close (); +} + + +function JSC$StreamFile_rewind () +{ + return this.stream.setPosition (0); +} + + +function JSC$StreamFile_read_byte () +{ + return this.stream.readByte (); +} + + +function JSC$StreamFile_unget_byte (byte) +{ + this.stream.ungetByte (byte); +} + + +function JSC$StreamFile_readln () +{ + return this.stream.readln (); +} + + +/* + * String stream. + */ + +function JSC$StreamString (str) +{ + this.name = "StringStream"; + this.string = str; + this.pos = 0; + this.unget_byte = -1; + this.error = ""; + + this.open = JSC$StreamString_open; + this.close = JSC$StreamString_close; + this.rewind = JSC$StreamString_rewind; + this.readByte = JSC$StreamString_read_byte; + this.ungetByte = JSC$StreamString_unget_byte; + this.readln = JSC$StreamString_readln; +} + + +function JSC$StreamString_open () +{ + return true; +} + + +function JSC$StreamString_close () +{ + return true; +} + + +function JSC$StreamString_rewind () +{ + this.pos = 0; + this.unget_byte = -1; + this.error = ""; + return true; +} + + +function JSC$StreamString_read_byte () +{ + var ch; + + if (this.unget_byte >= 0) + { + ch = this.unget_byte; + this.unget_byte = -1; + return ch; + } + + if (this.pos >= this.string.length) + return -1; + + return this.string.charCodeAt (this.pos++); +} + + +function JSC$StreamString_unget_byte (byte) +{ + this.unget_byte = byte; +} + + +function JSC$StreamString_readln () +{ + var line = new String (""); + var ch; + + while ((ch = this.readByte ()) != -1 && ch != #'\n') + line.append (String.pack ("C", ch)); + + return line; +} + + +/* +Local variables: +mode: c +End: +*/ +/* + * JavaScript Assembler. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsc/compiler.js,v $ + * $Id: compiler.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* Byte-code file definitions. */ + +JSC$BC_MAGIC = 0xc0014a53; + +JSC$BC_SECT_CODE = 0; +JSC$BC_SECT_CONSTANTS = 1; +JSC$BC_SECT_SYMTAB = 2; +JSC$BC_SECT_DEBUG = 3; + +JSC$CONST_INT = 3; +JSC$CONST_STRING = 4; +JSC$CONST_FLOAT = 5; +JSC$CONST_SYMBOL = 10; +JSC$CONST_REGEXP = 11; +JSC$CONST_NAN = 13; + +JSC$CONST_REGEXP_FLAG_G = 0x01; +JSC$CONST_REGEXP_FLAG_I = 0x02; + +JSC$DEBUG_FILENAME = 1; +JSC$DEBUG_LINENUMBER = 2; + +/* Opcode definitions. */ + +JSC$OP_HALT = 0; +JSC$OP_DONE = 1; +JSC$OP_NOP = 2; +JSC$OP_DUP = 3; +JSC$OP_POP = 4; +JSC$OP_POP_N = 5; +JSC$OP_APOP = 6; +JSC$OP_SWAP = 7; +JSC$OP_ROLL = 8; +JSC$OP_CONST = 9; +JSC$OP_CONST_NULL = 10; +JSC$OP_CONST_TRUE = 11; +JSC$OP_CONST_FALSE = 12; +JSC$OP_CONST_UNDEFINED = 13; +JSC$OP_CONST_I0 = 14; +JSC$OP_CONST_I1 = 15; +JSC$OP_CONST_I2 = 16; +JSC$OP_CONST_I3 = 17; +JSC$OP_CONST_I = 18; +JSC$OP_LOAD_GLOBAL = 19; +JSC$OP_STORE_GLOBAL = 20; +JSC$OP_LOAD_ARG = 21; +JSC$OP_STORE_ARG = 22; +JSC$OP_LOAD_LOCAL = 23; +JSC$OP_STORE_LOCAL = 24; +JSC$OP_LOAD_PROPERTY = 25; +JSC$OP_STORE_PROPERTY = 26; +JSC$OP_LOAD_ARRAY = 27; +JSC$OP_STORE_ARRAY = 28; +JSC$OP_NTH = 29; +JSC$OP_CMP_EQ = 30; +JSC$OP_CMP_NE = 31; +JSC$OP_CMP_LT = 32; +JSC$OP_CMP_GT = 33; +JSC$OP_CMP_LE = 34; +JSC$OP_CMP_GE = 35; +JSC$OP_CMP_SEQ = 36; +JSC$OP_CMP_SNE = 37; +JSC$OP_SUB = 38; +JSC$OP_ADD = 39; +JSC$OP_MUL = 40; +JSC$OP_DIV = 41; +JSC$OP_MOD = 42; +JSC$OP_NEG = 43; +JSC$OP_AND = 44; +JSC$OP_NOT = 45; +JSC$OP_OR = 46; +JSC$OP_XOR = 47; +JSC$OP_SHIFT_LEFT = 48; +JSC$OP_SHIFT_RIGHT = 49; +JSC$OP_SHIFT_RRIGHT = 50; +JSC$OP_IFFALSE = 51; +JSC$OP_IFTRUE = 52; +JSC$OP_CALL_METHOD = 53; +JSC$OP_JMP = 54; +JSC$OP_JSR = 55; +JSC$OP_RETURN = 56; +JSC$OP_TYPEOF = 57; +JSC$OP_NEW = 58; +JSC$OP_DELETE_PROPERTY = 59; +JSC$OP_DELETE_ARRAY = 60; +JSC$OP_LOCALS = 61; +JSC$OP_MIN_ARGS = 62; +JSC$OP_LOAD_NTH_ARG = 63; +JSC$OP_WITH_PUSH = 64; +JSC$OP_WITH_POP = 65; +JSC$OP_TRY_PUSH = 66; +JSC$OP_TRY_POP = 67; +JSC$OP_THROW = 68; + +/* Type aware operands. */ +JSC$OP_IFFALSE_B = 69; +JSC$OP_IFTRUE_B = 70; +JSC$OP_ADD_1_I = 71; +JSC$OP_ADD_2_I = 72; +JSC$OP_LOAD_GLOBAL_W = 73; +JSC$OP_JSR_W = 74; + +/* Internal values. */ +JSC$ASM_SYMBOL = 1000; +JSC$ASM_LABEL = 1001; + +/* + * General helpers. + */ + +/* Generate byte-code for operands with Int8 value. */ +function JSC$ASM_bytecode_int8 () +{ + return String.pack ("C", this.value); +} + +/* Generate byte-code for operands with Int16 value. */ +function JSC$ASM_bytecode_int16 () +{ + return String.pack ("n", this.value); +} + +/* Generate byte-code for operands with Int32 value. */ +function JSC$ASM_bytecode_int32 () +{ + return String.pack ("N", this.value); +} + +/* Generate byte-code for operands with Symbol value. */ +function JSC$ASM_bytecode_symbol () +{ + var cid = JSC$asm_genconstant (String.pack ("C", JSC$CONST_SYMBOL) + + this.value + String.pack ("C", 0)); + return String.pack ("N", cid); +} + +/* Generate byte-code for local jump operands. */ +function JSC$ASM_bytecode_local_jump () +{ + var delta = this.value.offset - (this.offset + this.size); + return String.pack ("N", delta); +} + + +/* + * Assembler operands. + */ + +/* Symbol. */ + +function JSC$ASM_symbol (ln, value) +{ + this.type = JSC$ASM_SYMBOL; + this.linenum = ln; + this.value = value; + this.size = 0; + this.print = JSC$ASM_symbol_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_symbol_print (stream) +{ + stream.write ("\n" + this.value + ":\n"); +} + +/* Label */ + +function JSC$ASM_label () +{ + this.type = JSC$ASM_LABEL; + this.linenum = 0; + this.size = 0; + this.value = JSC$asm_label_count++; + this.referenced = false; + this.next = null; + this.print = JSC$ASM_label_print; + this.link = JSC$asm_link; + this.format = JSC$ASM_label_format; +} + +function JSC$ASM_label_print (stream) +{ + stream.write (this.format () + ":\n"); +} + +function JSC$ASM_label_format () +{ + return ".L" + this.value.toString (); +} + +/* halt */ + +function JSC$ASM_halt (ln) +{ + this.type = JSC$OP_HALT; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_halt_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_halt_print (stream) +{ + stream.write ("\thalt\n"); +} + +/* done */ + +function JSC$ASM_done (ln) +{ + this.type = JSC$OP_DONE; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_done_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_done_print (stream) +{ + stream.write ("\tdone\n"); +} + +/* nop */ + +function JSC$ASM_nop (ln) +{ + this.type = JSC$OP_NOP; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_nop_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_nop_print (stream) +{ + stream.write ("\tnop\n"); +} + +/* dup */ + +function JSC$ASM_dup (ln) +{ + this.type = JSC$OP_DUP; + this.linenum = ln; + this.stack_delta = 1; + this.size = 1; + this.print = JSC$ASM_dup_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_dup_print (stream) +{ + stream.write ("\tdup\n"); +} + +/* pop */ + +function JSC$ASM_pop (ln) +{ + this.type = JSC$OP_POP; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_pop_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_pop_print (stream) +{ + stream.write ("\tpop\n"); +} + +/* pop_n */ + +function JSC$ASM_pop_n (ln, value) +{ + this.type = JSC$OP_POP_N; + this.linenum = ln; + this.value = value; + this.stack_delta = -value; + this.size = 2; + this.print = JSC$ASM_pop_n_print; + this.link = JSC$asm_link; + this.bytecode = JSC$ASM_bytecode_int8; +} + +function JSC$ASM_pop_n_print (stream) +{ + stream.write ("\tpop_n\t\t" + this.value.toString () + "\n"); +} + +/* apop */ + +function JSC$ASM_apop (ln, value) +{ + this.type = JSC$OP_APOP; + this.linenum = ln; + this.value = value; + this.stack_delta = -value; + this.size = 2; + this.print = JSC$ASM_apop_print; + this.link = JSC$asm_link; + this.bytecode = JSC$ASM_bytecode_int8; +} + +function JSC$ASM_apop_print (stream) +{ + stream.write ("\tapop\t\t" + this.value.toString () + "\n"); +} + +/* swap */ + +function JSC$ASM_swap (ln) +{ + this.type = JSC$OP_SWAP; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_swap_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_swap_print (stream) +{ + stream.write ("\tswap\n"); +} + +/* roll */ +function JSC$ASM_roll (ln, value) +{ + this.type = JSC$OP_ROLL; + this.linenum = ln; + this.value = value; + this.size = 2; + this.print = JSC$ASM_roll_print; + this.link = JSC$asm_link; + this.bytecode = JSC$ASM_bytecode_int8; +} + +function JSC$ASM_roll_print (stream) +{ + stream.write ("\troll\t\t" + this.value.toString () + "\n"); +} + +/* const */ + +function JSC$ASM_const (ln, value) +{ + this.type = JSC$OP_CONST; + this.linenum = ln; + this.value = value; + this.stack_delta = 1; + this.size = 5; + this.print = JSC$ASM_const_print; + this.link = JSC$asm_link; + this.bytecode = JSC$ASM_const_bytecode; +} + +function JSC$ASM_const_print (stream) +{ + if (typeof this.value == "number") + stream.write ("\tconst\t\t" + this.value.toString () + "\n"); + else if (typeof this.value == "string" + || typeof this.value == "#builtin") + { + var i, c; + var ender, src; + var stringp = (typeof this.value == "string"); + + if (stringp) + { + ender = "\""; + src = this.value; + } + else + { + ender = "/"; + src = this.value.source; + } + + stream.write ("\tconst\t\t" + ender); + for (i = 0; i < src.length; i++) + { + c = src.charCodeAt (i); + if (c == ender[0] || c == #'\\') + stream.write ("\\" + src.charAt (i)); + else if (c == #'\n') + stream.write ("\\n"); + else if (c == #'\r') + stream.write ("\\r"); + else if (c == #'\t') + stream.write ("\\t"); + else if (c == #'\f') + stream.write ("\\f"); + else + stream.write (src.charAt (i)); + } + stream.write (ender); + + if (!stringp) + { + if (this.value.global) + stream.write ("g"); + if (this.value.ignoreCase) + stream.write ("i"); + } + + stream.write ("\n"); + } +} + +function JSC$ASM_const_bytecode () +{ + var cid; + + if (typeof this.value == "number") + { + if (isInt (this.value)) + cid = JSC$asm_genconstant (String.pack ("CN", JSC$CONST_INT, + this.value)); + else if (isFloat (this.value)) + cid = JSC$asm_genconstant (String.pack ("Cd", JSC$CONST_FLOAT, + this.value)); + else + cid = JSC$asm_genconstant (String.pack ("C", JSC$CONST_NAN)); + } + else if (typeof this.value == "string") + cid = JSC$asm_genconstant (String.pack ("CN", JSC$CONST_STRING, + this.value.length) + + this.value); + else if (typeof this.value == "#builtin") + { + /* Regular expression. */ + var flags = 0; + + if (this.value.global) + flags |= JSC$CONST_REGEXP_FLAG_G; + if (this.value.ignoreCase) + flags |= JSC$CONST_REGEXP_FLAG_I; + + cid = JSC$asm_genconstant (String.pack ("CCN", JSC$CONST_REGEXP, flags, + this.value.source.length) + + this.value.source); + } + else + error ("ASM_const_bytecode(): unknown type: " + typeof this.value); + + return String.pack ("N", cid); +} + +/* const_null */ + +function JSC$ASM_const_null (ln) +{ + this.type = JSC$OP_CONST_NULL; + this.linenum = ln; + this.stack_delta = 1; + this.size = 1; + this.print = JSC$ASM_const_null_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_const_null_print (stream) +{ + stream.write ("\tconst_null\n"); +} + +/* const_true */ + +function JSC$ASM_const_true (ln) +{ + this.type = JSC$OP_CONST_TRUE; + this.linenum = ln; + this.stack_delta = 1; + this.size = 1; + this.print = JSC$ASM_const_true_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_const_true_print (stream) +{ + stream.write ("\tconst_true\n"); +} + +/* const_false */ + +function JSC$ASM_const_false (ln) +{ + this.type = JSC$OP_CONST_FALSE; + this.linenum = ln; + this.stack_delta = 1; + this.size = 1; + this.print = JSC$ASM_const_false_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_const_false_print (stream) +{ + stream.write ("\tconst_false\n"); +} + +/* const_undefined */ + +function JSC$ASM_const_undefined (ln) +{ + this.type = JSC$OP_CONST_UNDEFINED; + this.linenum = ln; + this.stack_delta = 1; + this.size = 1; + this.print = JSC$ASM_const_undefined_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_const_undefined_print (stream) +{ + stream.write ("\tconst_undefined\n"); +} + +/* const_i0 */ + +function JSC$ASM_const_i0 (ln) +{ + this.type = JSC$OP_CONST_I0; + this.linenum = ln; + this.stack_delta = 1; + this.size = 1; + this.print = JSC$ASM_const_i0_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_const_i0_print (stream) +{ + stream.write ("\tconst_i0\n"); +} + +/* const_i1 */ + +function JSC$ASM_const_i1 (ln) +{ + this.type = JSC$OP_CONST_I1; + this.linenum = ln; + this.stack_delta = 1; + this.size = 1; + this.print = JSC$ASM_const_i1_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_const_i1_print (stream) +{ + stream.write ("\tconst_i1\n"); +} + +/* const_i2 */ + +function JSC$ASM_const_i2 (ln) +{ + this.type = JSC$OP_CONST_I2; + this.linenum = ln; + this.stack_delta = 1; + this.size = 1; + this.print = JSC$ASM_const_i2_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_const_i2_print (stream) +{ + stream.write ("\tconst_i2\n"); +} + +/* const_i3 */ + +function JSC$ASM_const_i3 (ln) +{ + this.type = JSC$OP_CONST_I3; + this.linenum = ln; + this.stack_delta = 1; + this.size = 1; + this.print = JSC$ASM_const_i3_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_const_i3_print (stream) +{ + stream.write ("\tconst_i3\n"); +} + +/* const_i */ + +function JSC$ASM_const_i (ln, value) +{ + this.type = JSC$OP_CONST_I; + this.linenum = ln; + this.value = value; + this.stack_delta = 1; + this.size = 5; + this.print = JSC$ASM_const_i_print; + this.bytecode = JSC$ASM_bytecode_int32; + this.link = JSC$asm_link; +} + +function JSC$ASM_const_i_print (stream) +{ + stream.write ("\tconst_i\t\t" + this.value.toString () + "\n"); +} + +/* load_global */ + +function JSC$ASM_load_global (ln, value) +{ + this.type = JSC$OP_LOAD_GLOBAL; + this.linenum = ln; + this.value = value; + this.stack_delta = 1; + this.size = 5; + this.print = JSC$ASM_load_global_print; + this.bytecode = JSC$ASM_bytecode_symbol; + this.link = JSC$asm_link; +} + +function JSC$ASM_load_global_print (stream) +{ + stream.write ("\tload_global\t" + this.value + "\n"); +} + +/* store_global */ + +function JSC$ASM_store_global (ln, value) +{ + this.type = JSC$OP_STORE_GLOBAL; + this.linenum = ln; + this.value = value; + this.stack_delta = -1; + this.size = 5; + this.print = JSC$ASM_store_global_print; + this.bytecode = JSC$ASM_bytecode_symbol; + this.link = JSC$asm_link; +} + +function JSC$ASM_store_global_print (stream) +{ + stream.write ("\tstore_global\t" + this.value + "\n"); +} + +/* load_arg */ + +function JSC$ASM_load_arg (ln, value) +{ + this.type = JSC$OP_LOAD_ARG; + this.linenum = ln; + this.value = value; + this.stack_delta = 1; + this.size = 2; + this.print = JSC$ASM_load_arg_print; + this.bytecode = JSC$ASM_bytecode_int8; + this.link = JSC$asm_link; +} + +function JSC$ASM_load_arg_print (stream) +{ + stream.write ("\tload_arg\t" + this.value.toString () + "\n"); +} + +/* store_arg */ + +function JSC$ASM_store_arg (ln, value) +{ + this.type = JSC$OP_STORE_ARG; + this.linenum = ln; + this.value = value; + this.stack_delta = -1; + this.size = 2; + this.print = JSC$ASM_store_arg_print; + this.bytecode = JSC$ASM_bytecode_int8; + this.link = JSC$asm_link; +} + +function JSC$ASM_store_arg_print (stream) +{ + stream.write ("\tstore_arg\t" + this.value.toString () + "\n"); +} + +/* load_local */ + +function JSC$ASM_load_local (ln, value) +{ + this.type = JSC$OP_LOAD_LOCAL; + this.linenum = ln; + this.value = value; + this.stack_delta = 1; + this.size = 3; + this.print = JSC$ASM_load_local_print; + this.bytecode = JSC$ASM_bytecode_int16; + this.link = JSC$asm_link; +} + +function JSC$ASM_load_local_print (stream) +{ + stream.write ("\tload_local\t" + this.value.toString () + "\n"); +} + +/* store_local */ + +function JSC$ASM_store_local (ln, value) +{ + this.type = JSC$OP_STORE_LOCAL; + this.linenum = ln; + this.value = value; + this.stack_delta = -1; + this.size = 3; + this.print = JSC$ASM_store_local_print; + this.bytecode = JSC$ASM_bytecode_int16; + this.link = JSC$asm_link; +} + +function JSC$ASM_store_local_print (stream) +{ + stream.write ("\tstore_local\t" + this.value.toString () + "\n"); +} + +/* load_property */ + +function JSC$ASM_load_property (ln, value) +{ + this.type = JSC$OP_LOAD_PROPERTY; + this.linenum = ln; + this.value = value; + this.size = 5; + this.print = JSC$ASM_load_property_print; + this.bytecode = JSC$ASM_bytecode_symbol; + this.link = JSC$asm_link; +} + +function JSC$ASM_load_property_print (stream) +{ + stream.write ("\tload_property\t" + this.value + "\n"); +} + +/* store_property */ + +function JSC$ASM_store_property (ln, value) +{ + this.type = JSC$OP_STORE_PROPERTY; + this.linenum = ln; + this.value = value; + this.stack_delta = -2; + this.size = 5; + this.print = JSC$ASM_store_property_print; + this.bytecode = JSC$ASM_bytecode_symbol; + this.link = JSC$asm_link; +} + +function JSC$ASM_store_property_print (stream) +{ + stream.write ("\tstore_property\t" + this.value + "\n"); +} + +/* load_array */ + +function JSC$ASM_load_array (ln) +{ + this.type = JSC$OP_LOAD_ARRAY; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_load_array_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_load_array_print (stream) +{ + stream.write ("\tload_array\n"); +} + +/* store_array */ + +function JSC$ASM_store_array (ln) +{ + this.type = JSC$OP_STORE_ARRAY; + this.linenum = ln; + this.stack_delta = -3; + this.size = 1; + this.print = JSC$ASM_store_array_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_store_array_print (stream) +{ + stream.write ("\tstore_array\n"); +} + +/* nth */ + +function JSC$ASM_nth (ln) +{ + this.type = JSC$OP_NTH; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_nth_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_nth_print (stream) +{ + stream.write ("\tnth\n"); +} + +/* cmp_eq */ + +function JSC$ASM_cmp_eq (ln) +{ + this.type = JSC$OP_CMP_EQ; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_cmp_eq_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_cmp_eq_print (stream) +{ + stream.write ("\tcmp_eq\n"); +} + +/* cmp_ne */ + +function JSC$ASM_cmp_ne (ln) +{ + this.type = JSC$OP_CMP_NE; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_cmp_ne_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_cmp_ne_print (stream) +{ + stream.write ("\tcmp_ne\n"); +} + +/* cmp_lt */ + +function JSC$ASM_cmp_lt (ln) +{ + this.type = JSC$OP_CMP_LT; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_cmp_lt_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_cmp_lt_print (stream) +{ + stream.write ("\tcmp_lt\n"); +} + +/* cmp_gt */ + +function JSC$ASM_cmp_gt (ln) +{ + this.type = JSC$OP_CMP_GT; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_cmp_gt_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_cmp_gt_print (stream) +{ + stream.write ("\tcmp_gt\n"); +} + +/* cmp_le */ + +function JSC$ASM_cmp_le (ln) +{ + this.type = JSC$OP_CMP_LE; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_cmp_le_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_cmp_le_print (stream) +{ + stream.write ("\tcmp_le\n"); +} + +/* cmp_ge */ + +function JSC$ASM_cmp_ge (ln) +{ + this.type = JSC$OP_CMP_GE; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_cmp_ge_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_cmp_ge_print (stream) +{ + stream.write ("\tcmp_ge\n"); +} + +/* cmp_seq */ + +function JSC$ASM_cmp_seq (ln) +{ + this.type = JSC$OP_CMP_SEQ; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_cmp_seq_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_cmp_seq_print (stream) +{ + stream.write ("\tcmp_seq\n"); +} + +/* cmp_sne */ + +function JSC$ASM_cmp_sne (ln) +{ + this.type = JSC$OP_CMP_SNE; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_cmp_sne_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_cmp_sne_print (stream) +{ + stream.write ("\tcmp_sne\n"); +} + +/* sub */ + +function JSC$ASM_sub (ln) +{ + this.type = JSC$OP_SUB; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_sub_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_sub_print (stream) +{ + stream.write ("\tsub\n"); +} + +/* add */ + +function JSC$ASM_add (ln) +{ + this.type = JSC$OP_ADD; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_add_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_add_print (stream) +{ + stream.write ("\tadd\n"); +} + +/* mul */ + +function JSC$ASM_mul (ln) +{ + this.type = JSC$OP_MUL; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_mul_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_mul_print (stream) +{ + stream.write ("\tmul\n"); +} + +/* div */ + +function JSC$ASM_div (ln) +{ + this.type = JSC$OP_DIV; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_div_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_div_print (stream) +{ + stream.write ("\tdiv\n"); +} + +/* mod */ + +function JSC$ASM_mod (ln) +{ + this.type = JSC$OP_MOD; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_mod_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_mod_print (stream) +{ + stream.write ("\tmod\n"); +} + +/* neg */ + +function JSC$ASM_neg (ln) +{ + this.type = JSC$OP_NEG; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_neg_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_neg_print (stream) +{ + stream.write ("\tneg\n"); +} + +/* and */ + +function JSC$ASM_and (ln) +{ + this.type = JSC$OP_AND; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_and_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_and_print (stream) +{ + stream.write ("\tand\n"); +} + +/* not */ + +function JSC$ASM_not (ln) +{ + this.type = JSC$OP_NOT; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_not_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_not_print (stream) +{ + stream.write ("\tnot\n"); +} + +/* or */ + +function JSC$ASM_or (ln) +{ + this.type = JSC$OP_OR; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_or_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_or_print (stream) +{ + stream.write ("\tor\n"); +} + +/* xor */ + +function JSC$ASM_xor (ln) +{ + this.type = JSC$OP_XOR; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_xor_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_xor_print (stream) +{ + stream.write ("\txor\n"); +} + +/* shift_left */ + +function JSC$ASM_shift_left (ln) +{ + this.type = JSC$OP_SHIFT_LEFT; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_shift_left_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_shift_left_print (stream) +{ + stream.write ("\tshift_left\n"); +} + +/* shift_right */ + +function JSC$ASM_shift_right (ln) +{ + this.type = JSC$OP_SHIFT_RIGHT; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_shift_right_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_shift_right_print (stream) +{ + stream.write ("\tshift_right\n"); +} + +/* shift_rright */ + +function JSC$ASM_shift_rright (ln) +{ + this.type = JSC$OP_SHIFT_RRIGHT; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_shift_rright_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_shift_rright_print (stream) +{ + stream.write ("\tshift_rright\n"); +} + +/* iffalse */ + +function JSC$ASM_iffalse (ln, value) +{ + this.type = JSC$OP_IFFALSE; + this.linenum = ln; + this.value = value; + this.stack_delta = -1; + this.size = 5; + this.print = JSC$ASM_iffalse_print; + this.bytecode = JSC$ASM_bytecode_local_jump; + this.link = JSC$asm_link; +} + +function JSC$ASM_iffalse_print (stream) +{ + stream.write ("\tiffalse\t\t" + this.value.format () + "\n"); +} + +/* iftrue */ + +function JSC$ASM_iftrue (ln, value) +{ + this.type = JSC$OP_IFTRUE; + this.linenum = ln; + this.value = value; + this.stack_delta = -1; + this.size = 5; + this.print = JSC$ASM_iftrue_print; + this.bytecode = JSC$ASM_bytecode_local_jump; + this.link = JSC$asm_link; +} + +function JSC$ASM_iftrue_print (stream) +{ + stream.write ("\tiftrue\t\t" + this.value.format () + "\n"); +} + +/* call_method */ + +function JSC$ASM_call_method (ln, value) +{ + this.type = JSC$OP_CALL_METHOD; + this.linenum = ln; + this.value = value; + this.stack_delta = 1; + this.size = 5; + this.print = JSC$ASM_call_method_print; + this.bytecode = JSC$ASM_bytecode_symbol; + this.link = JSC$asm_link; +} + +function JSC$ASM_call_method_print (stream) +{ + stream.write ("\tcall_method\t" + this.value + "\n"); +} + +/* jmp */ + +function JSC$ASM_jmp (ln, value) +{ + this.type = JSC$OP_JMP; + this.linenum = ln; + this.value = value; + this.size = 5; + this.print = JSC$ASM_jmp_print; + this.bytecode = JSC$ASM_bytecode_local_jump; + this.link = JSC$asm_link; +} + +function JSC$ASM_jmp_print (stream) +{ + stream.write ("\tjmp\t\t" + this.value.format () + "\n"); +} + +/* jsr */ + +function JSC$ASM_jsr (ln) +{ + this.type = JSC$OP_JSR; + this.linenum = ln; + this.stack_delta = 1; + this.size = 1; + this.print = JSC$ASM_jsr_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_jsr_print (stream) +{ + stream.write ("\tjsr\n"); +} + +/* return */ + +function JSC$ASM_return (ln) +{ + this.type = JSC$OP_RETURN; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_return_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_return_print (stream) +{ + stream.write ("\treturn\n"); +} + +/* typeof */ + +function JSC$ASM_typeof (ln) +{ + this.type = JSC$OP_TYPEOF; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_typeof_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_typeof_print (stream) +{ + stream.write ("\ttypeof\n"); +} + +/* new */ + +function JSC$ASM_new (ln) +{ + this.type = JSC$OP_NEW; + this.linenum = ln; + this.stack_delta = 1; + this.size = 1; + this.print = JSC$ASM_new_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_new_print (stream) +{ + stream.write ("\tnew\n"); +} + +/* delete_property */ + +function JSC$ASM_delete_property (ln, value) +{ + this.type = JSC$OP_DELETE_PROPERTY; + this.linenum = ln; + this.value = value; + this.size = 5; + this.print = JSC$ASM_delete_property_print; + this.bytecode = JSC$ASM_bytecode_symbol; + this.link = JSC$asm_link; +} + +function JSC$ASM_delete_property_print (stream) +{ + stream.write ("\tdelete_property\t" + this.value + "\n"); +} + +/* delete_array */ + +function JSC$ASM_delete_array (ln) +{ + this.type = JSC$OP_DELETE_ARRAY; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_delete_array_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_delete_array_print (stream) +{ + stream.write ("\tdelete_array\n"); +} + +/* locals */ + +function JSC$ASM_locals (ln, value) +{ + this.type = JSC$OP_LOCALS; + this.linenum = ln; + this.value = value; + this.stack_delta = value; + this.size = 3; + this.print = JSC$ASM_locals_print; + this.bytecode = JSC$ASM_bytecode_int16; + this.link = JSC$asm_link; +} + +function JSC$ASM_locals_print (stream) +{ + stream.write ("\tlocals\t\t" + this.value.toString () + "\n"); +} + +/* min_args */ + +function JSC$ASM_min_args (ln, value) +{ + this.type = JSC$OP_MIN_ARGS; + this.linenum = ln; + this.value = value; + this.stack_delta = -1; + this.size = 2; + this.print = JSC$ASM_min_args_print; + this.bytecode = JSC$ASM_bytecode_int8; + this.link = JSC$asm_link; +} + +function JSC$ASM_min_args_print (stream) +{ + stream.write ("\tmin_args\t" + this.value.toString () + "\n"); +} + +/* load_nth_arg */ + +function JSC$ASM_load_nth_arg (ln) +{ + this.type = JSC$OP_LOAD_NTH_ARG; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_load_nth_arg_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_load_nth_arg_print (stream) +{ + stream.write ("\tload_nth_arg\n"); +} + +/* with_push */ + +function JSC$ASM_with_push (ln) +{ + this.type = JSC$OP_WITH_PUSH; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_with_push_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_with_push_print (stream) +{ + stream.write ("\twith_push\n"); +} + +/* with_pop */ + +function JSC$ASM_with_pop (ln, value) +{ + this.type = JSC$OP_WITH_POP; + this.linenum = ln; + this.value = value; + this.size = 2; + this.print = JSC$ASM_with_pop_print; + this.bytecode = JSC$ASM_bytecode_int8; + this.link = JSC$asm_link; +} + +function JSC$ASM_with_pop_print (stream) +{ + stream.write ("\twith_pop\t" + this.value.toString () + "\n"); +} + +/* try_push */ + +function JSC$ASM_try_push (ln, value) +{ + this.type = JSC$OP_TRY_PUSH; + this.linenum = ln; + this.value = value; + this.size = 5; + this.print = JSC$ASM_try_push_print; + this.bytecode = JSC$ASM_bytecode_local_jump; + this.link = JSC$asm_link; +} + +function JSC$ASM_try_push_print (stream) +{ + stream.write ("\ttry_push\t" + this.value.format () + "\n"); +} + +/* try_pop */ + +function JSC$ASM_try_pop (ln, value) +{ + this.type = JSC$OP_TRY_POP; + this.linenum = ln; + this.value = value; + this.size = 2; + this.print = JSC$ASM_try_pop_print; + this.bytecode = JSC$ASM_bytecode_int8; + this.link = JSC$asm_link; +} + +function JSC$ASM_try_pop_print (stream) +{ + stream.write ("\ttry_pop\t\t" + this.value.toString () + "\n"); +} + +/* throw */ + +function JSC$ASM_throw (ln) +{ + this.type = JSC$OP_THROW; + this.linenum = ln; + this.stack_delta = -1; + this.size = 1; + this.print = JSC$ASM_throw_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_throw_print (stream) +{ + stream.write ("\tthrow\n"); +} + +/* iffalse_b */ + +function JSC$ASM_iffalse_b (ln, value) +{ + this.type = JSC$OP_IFFALSE_B; + this.linenum = ln; + this.value = value; + this.stack_delta = -1; + this.size = 5; + this.print = JSC$ASM_iffalse_b_print; + this.bytecode = JSC$ASM_bytecode_local_jump; + this.link = JSC$asm_link; +} + +function JSC$ASM_iffalse_b_print (stream) +{ + stream.write ("\tiffalse_b\t" + this.value.format () + "\n"); +} + +/* iftrue */ + +function JSC$ASM_iftrue_b (ln, value) +{ + this.type = JSC$OP_IFTRUE_B; + this.linenum = ln; + this.value = value; + this.stack_delta = -1; + this.size = 5; + this.print = JSC$ASM_iftrue_b_print; + this.bytecode = JSC$ASM_bytecode_local_jump; + this.link = JSC$asm_link; +} + +function JSC$ASM_iftrue_b_print (stream) +{ + stream.write ("\tiftrue_b\t" + this.value.format () + "\n"); +} + +/* add_1_i */ + +function JSC$ASM_add_1_i (ln) +{ + this.type = JSC$OP_ADD_1_I; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_add_1_i_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_add_1_i_print (stream) +{ + stream.write ("\tadd_1_i\n"); +} + +/* add_2_i */ + +function JSC$ASM_add_2_i (ln) +{ + this.type = JSC$OP_ADD_2_I; + this.linenum = ln; + this.size = 1; + this.print = JSC$ASM_add_2_i_print; + this.link = JSC$asm_link; +} + +function JSC$ASM_add_2_i_print (stream) +{ + stream.write ("\tadd_2_i\n"); +} + +/* load_global_w */ + +function JSC$ASM_load_global_w (ln, value) +{ + this.type = JSC$OP_LOAD_GLOBAL_W; + this.linenum = ln; + this.value = value; + this.stack_delta = 1; + this.size = 5; + this.print = JSC$ASM_load_global_w_print; + this.bytecode = JSC$ASM_bytecode_symbol; + this.link = JSC$asm_link; +} + +function JSC$ASM_load_global_w_print (stream) +{ + stream.write ("\tload_global_w\t" + this.value + "\n"); +} + +/* jsr_w */ + +function JSC$ASM_jsr_w (ln, value) +{ + this.type = JSC$OP_JSR_W; + this.linenum = ln; + this.value = value; + this.stack_delta = 1; + this.size = 5; + this.print = JSC$ASM_jsr_w_print; + this.bytecode = JSC$ASM_bytecode_symbol; + this.link = JSC$asm_link; +} + +function JSC$ASM_jsr_w_print (stream) +{ + stream.write ("\tjsr_w\t\t" + this.value + "\n"); +} + +/* + * General helpers. + */ + +function JSC$asm_link () +{ + this.next = null; + + if (JSC$asm_tail != null) + { + JSC$asm_tail_prev = JSC$asm_tail; + JSC$asm_tail.next = this; + } + else + JSC$asm_head = this; + + JSC$asm_tail = this; +} + + +/* + * The phases of the assembler. + */ + +/* This is called from the compiler initialization code. */ +function JSC$asm_reset () +{ + JSC$asm_label_count = 1; + JSC$asm_head = JSC$asm_tail = JSC$asm_tail_prev = null; + JSC$asm_constcount = 0; + JSC$asm_constants = null; + JSC$asm_known_constants = null; +} + + +function JSC$asm_generate () +{ + var i; + + if (JSC$verbose) + JSC$message ("jsc: generating assembler"); + + JSC$ns = new JSC$NameSpace (); + + /* Functions. */ + for (i = 0; i < JSC$functions.length; i++) + JSC$functions[i].asm (); + + /* Global statements. */ + if (JSC$global_stmts.length > 0) + { + /* Define the `.global' symbol. */ + new JSC$ASM_symbol (JSC$global_stmts[0].linenum, ".global").link (); + + /* Handle local variables. */ + var num_locals = JSC$count_locals_from_stmt_list (JSC$global_stmts); + if (num_locals > 0) + new JSC$ASM_locals (JSC$global_stmts[0].linenum, num_locals).link (); + + /* Generate assembler. */ + for (i = 0; i < JSC$global_stmts.length; i++) + JSC$global_stmts[i].asm (); + + /* + * Fix things so that also the global statement returns something + * (this is required when we use eval() in JavaScript). + */ + if (JSC$asm_tail_prev == null) + { + /* This is probably illegal, but we don't panic. */ + new JSC$ASM_const_undefined (0).link (); + } + else + { + /* + * If the latest op is `pop', remove it. Otherwise, append + * a `const_undefined'. + */ + if (JSC$asm_tail.type == JSC$OP_POP) + { + JSC$asm_tail = JSC$asm_tail_prev; + JSC$asm_tail.next = null; + JSC$asm_tail_prev = null; + } + else + new JSC$ASM_const_undefined (JSC$asm_tail.linenum).link (); + } + } + + JSC$ns = null; +} + + +function JSC$asm_print (src_stream, stream) +{ + var i; + var last_ln; + var annotate = src_stream ? true : false; + + if (annotate) + { + stream.write ("; -*- asm -*-\n"); + + /* Set the prev properties. */ + var prev = null; + for (i = JSC$asm_head; i != null; prev = i, i = i.next) + i.prev = prev; + + /* + * Fix the label line numbers to be the same that the next + * assembler operand has. + */ + last_ln = 0; + for (i = JSC$asm_tail; i != null; i = i.prev) + { + if (i.type == JSC$ASM_LABEL) + i.linenum = last_ln; + else if (typeof i.linenum != "undefined") + last_ln = i.linenum; + } + } + + last_ln = 0; + for (i = JSC$asm_head; i != null; i = i.next) + { + if (typeof i.linenum == "undefined") + { + if (annotate) + stream.write ("; undefined linenum\n"); + } + else + while (annotate && i.linenum > last_ln) + { + var line = src_stream.readln (); + stream.write ("; " + line + "\n"); + last_ln++; + } + + i.print (stream); + } +} + + +function JSC$asm_is_load_op (op) +{ + return (op.type == JSC$OP_LOAD_GLOBAL + || op.type == JSC$OP_LOAD_ARG + || op.type == JSC$OP_LOAD_LOCAL); +} + + +function JSC$asm_is_store_op (op) +{ + return (op.type == JSC$OP_STORE_GLOBAL + || op.type == JSC$OP_STORE_ARG + || op.type == JSC$OP_STORE_LOCAL); +} + + +function JSC$asm_is_local_jump (op) +{ + return (op.type == JSC$OP_JMP + || op.type == JSC$OP_IFFALSE + || op.type == JSC$OP_IFTRUE + || op.type == JSC$OP_IFFALSE_B + || op.type == JSC$OP_IFTRUE_B + || op.type == JSC$OP_TRY_PUSH); +} + + +function JSC$asm_is_const_op (op) +{ + return (JSC$OP_CONST <= op.type && op.type <= JSC$OP_CONST_I3); +} + + +function JSC$asm_lookup_next_op (item) +{ + while (item != null && + (item.type == JSC$ASM_LABEL || item.type == JSC$ASM_SYMBOL)) + item = item.next; + + return item; +} + + +function JSC$asm_optimize (flags) +{ + var item; + + /* Simple peephole optimization. */ + if ((flags & JSC$FLAG_OPTIMIZE_PEEPHOLE) != 0) + { + if (JSC$verbose) + JSC$message ("jsc: optimize: peephole"); + + for (item = JSC$asm_head; item != null; item = item.next) + { + /* + * Optimization for dup ... pop cases where pop removes the + * item duplicated by dup. + */ + if (item.next != null && item.next.type == JSC$OP_DUP) + { + var balance = 2; + var found = false; + var i1; + + for (i1 = item.next.next; + i1 != null && i1.next != null; + i1 = i1.next) + { + var i2 = i1.next; + + /* + * The lookup ends on branches, and on dup, throw, + * and try_pop operands. We optimize on a basic + * block and we match the closest dup-pop pairs. + */ + if (JSC$asm_is_local_jump (i1) + || i1.type == JSC$OP_JSR + || i1.type == JSC$OP_NEW + || i1.type == JSC$OP_CALL_METHOD + || i1.type == JSC$OP_RETURN + || i1.type == JSC$ASM_SYMBOL + || i1.type == JSC$ASM_LABEL + || i1.type == JSC$OP_DUP + || i1.type == JSC$OP_TRY_POP + || i1.type == JSC$OP_THROW) + break; + + if (i1.stack_delta) + { + balance += i1.stack_delta; + if (balance <= 0) + /* Going to negative. Stop here. */ + break; + } + + if (i2.type == JSC$OP_POP && balance == 1) + { + /* Found a matching pop. */ + found = true; + i1.next = i2.next; + break; + } + } + + if (found) + { + /* The dup can be removed. */ + item.next = item.next.next; + } + } + + /* Two instruction optimization (starting from item.next). */ + if (item.next != null && item.next.next != null) + { + var i1 = item.next; + var i2 = i1.next; + + if (i1.type == JSC$OP_APOP + && i2.type == JSC$OP_POP) + { + /* + * i1: apop n + * i2: pop -> pop_n n + 1 + */ + var i = new JSC$ASM_pop_n (i1.linenum, i1.value + 1); + item.next = i; + i.next = i2.next; + } + } + if (item.next != null && item.next.next != null) + { + var i1 = item.next; + var i2 = i1.next; + + if (i1.type == JSC$OP_CONST_TRUE + && (i2.type == JSC$OP_IFFALSE + || i2.type == JSC$OP_IFFALSE_B)) + { + /* + * i1: const_true + * i2: iffalse{,_b} .LX => --- + */ + item.next = i2.next; + } + } + if (item.next != null && item.next.next != null) + { + var i1 = item.next; + var i2 = i1.next; + + if (i1.type == JSC$OP_CONST_FALSE + && (i2.type == JSC$OP_IFTRUE + || i2.type == JSC$OP_IFTRUE_B)) + { + /* + * i1: const_false + * i2: iftrue{,_b} .LX => --- + */ + item.next = i2.next; + } + } + if (item.next != null && item.next.next != null) + { + var i1 = item.next; + var i2 = i1.next; + + if ((i1.type == JSC$OP_CONST_FALSE + && (i2.type == JSC$OP_IFFALSE + || i2.type == JSC$OP_IFFALSE_B)) + || (i1.type == JSC$OP_CONST_TRUE + && (i2.type == JSC$OP_IFTRUE + || i2.type == JSC$OP_IFTRUE_B))) + { + /* + * i1: const_false + * i2: iffalse{,_b} .LX => jmp .LX + * + * i1: const_true + * i2: iftrue{,_b} .LX => jmp .LX + */ + var i = new JSC$ASM_jmp (i1.linenum, i2.value); + item.next = i; + i.next = i2.next; + } + } + } + } + + /* Jumps to jumps. */ + if ((flags & JSC$FLAG_OPTIMIZE_JUMPS) != 0) + { + if (JSC$verbose) + JSC$message ("jsc: optimize: jumps to jumps"); + for (item = JSC$asm_head; item != null; item = item.next) + if (JSC$asm_is_local_jump (item)) + { + var i2; + + /* Operand's value is a label */ + i2 = JSC$asm_lookup_next_op (item.value); + + if (i2 != null && i2.type == JSC$OP_JMP) + /* Ok, we can jump there directly. */ + item.value = i2.value; + } + } + + if ((flags & JSC$FLAG_OPTIMIZE_HEAVY) != 0) + JSC$optimize_heavy (); + + /* + * Optimizations for the size of the generated byte-code. It isn't + * probably worth of doing these optimization for interactive + * scripts since these won't affect the speed of the execution. + * However, these optimizations make the byte-code files smaller so + * these are nice for batch-compiled files. + */ + if ((flags & JSC$FLAG_OPTIMIZE_BC_SIZE) != 0) + { + var delta = true; + + while (delta) + { + delta = false; + + /* Remove un-referenced labels. */ + + if (JSC$verbose) + JSC$message ("jsc: optimize: removing un-referenced labels"); + + /* First, make all labels unreferenced. */ + for (item = JSC$asm_head; item != null; item = item.next) + if (item.type == JSC$ASM_LABEL) + item.referenced = false; + + /* Second, mark all referenced labels. */ + for (item = JSC$asm_head; item != null; item = item.next) + if (JSC$asm_is_local_jump (item)) + item.value.referenced = true; + + /* Third, remove all un-referenced labels. */ + for (item = JSC$asm_head; item != null; item = item.next) + while (item.next != null && item.next.type == JSC$ASM_LABEL + && !item.next.referenced + && item.next.next != null) + { + delta = true; + item.next = item.next.next; + } + + /* Dead code elimination. */ + if (JSC$verbose) + JSC$message ("jsc: optimize: dead code elimination"); + for (item = JSC$asm_head; item != null; item = item.next) + if (item.type == JSC$OP_RETURN || item.type == JSC$OP_JMP) + while (item.next != null && item.next.type != JSC$ASM_SYMBOL + && item.next.type != JSC$ASM_LABEL) + { + delta = true; + item.next = item.next.next; + } + + + /* Simple peephole optimization. */ + if (JSC$verbose) + JSC$message ("jsc: optimize: peephole"); + for (item = JSC$asm_head; item != null; item = item.next) + { + /* Two instruction optimization (starting from item.next). */ + if (item.next != null && item.next.next != null) + { + var i1 = item.next; + var i2 = i1.next; + + if (i1.type == JSC$OP_JMP + && i2.type == JSC$ASM_LABEL + && i1.value == i2) + { + /* + * i1: jmp .LX + * i2: .LX => .LX + */ + item.next = i2; + delta = true; + } + } + } + } + } +} + + +function JSC$optimize_heavy () +{ + if (JSC$verbose) + JSC$message ("jsc: optimize: liveness analyzing"); + + /* First, set the prev pointers and zero usage flags. */ + var item, prev = null; + + for (item = JSC$asm_head; item != null; prev = item, item = item.next) + { + item.prev = prev; + item.live_args = 0; + item.live_locals = 0; + item.live_used = false; + } + + /* For each function. */ + var ftail, fhead; + for (ftail = JSC$asm_tail; ftail != null; ftail = fhead.prev) + { + var change = true; + + /* While there is change in the liveness. */ + while (change) + { + change = false; + + for (fhead = ftail; + fhead.type != JSC$ASM_SYMBOL; + fhead = fhead.prev) + { + var floc, farg; + + if (fhead.next != null) + { + floc = fhead.next.live_locals; + farg = fhead.next.live_args; + } + else + floc = farg = 0; + + if (fhead.type == JSC$OP_LOAD_LOCAL && fhead.value < 32) + floc |= (1 << fhead.value); + + if (fhead.type == JSC$OP_STORE_LOCAL && fhead.value < 32) + floc &= ~(1 << fhead.value); + + if (fhead.type == JSC$OP_LOAD_ARG && fhead.value < 32) + farg |= (1 << fhead.value); + + if (fhead.type == JSC$OP_STORE_ARG && fhead.value < 32) + farg &= ~(1 << fhead.value); + + if (JSC$asm_is_local_jump (fhead)) + { + floc |= fhead.value.live_locals; + fhead.value.live_used = true; + } + + if (fhead.live_used && (fhead.live_locals != floc + || fhead.live_args != farg)) + change = true; + + fhead.live_used = false; + fhead.live_locals = floc; + fhead.live_args = farg; + } + } + } + + /* + * When we have the liveness analyzing performed, we can do some + * fancy optimizations. + */ + + if (JSC$verbose) + JSC$message ("jsc: optimize: peephole"); + + for (item = JSC$asm_head; item != null; item = item.next) + { + /* Three instruction optimization. */ + if (item.next != null && item.next.next != null + && item.next.next.next != null) + { + var i1 = item.next; + var i2 = i1.next; + var i3 = i2.next; + + if (i1.type == JSC$OP_STORE_LOCAL + && i2.type == JSC$OP_LOAD_LOCAL + && i1.value == i2.value + && (i3.live_locals & (1 << i1.value)) == 0) + { + /* + * i1: store_local n + * i2: load_local n + * i3: nnn (n not live) => nnn + */ + + item.next = i3; + } + } + } +} + + +function JSC$asm_finalize () +{ + var item; + var offset = 0; + + for (item = JSC$asm_head; item != null; item = item.next) + { + item.offset = offset; + offset += item.size; + } +} + + +function JSC$ConstantReg () +{ +} + +function JSC$asm_genconstant (val) +{ + if (JSC$asm_known_constants == null) + JSC$asm_known_constants = new JSC$ConstantReg (); + + /* Lookup from a list of known constants. */ + var id = JSC$asm_known_constants[val]; + if (typeof id == "number") + return id; + + /* This is a new constant. */ + JSC$asm_constants.append (val); + JSC$asm_known_constants[val] = JSC$asm_constcount; + + return JSC$asm_constcount++; +} + +function JSC$asm_bytecode () +{ + var item; + var symtab = new String (""); + var nsymtab_entries = 0; + var code = new String (""); + var debug = new String (""); + var debug_last_linenum = 0; + + if (JSC$verbose) + JSC$message ("jsc: generating byte-code"); + + if (JSC$generate_debug_info) + /* Source file name. */ + debug.append (String.pack ("CN", JSC$DEBUG_FILENAME, JSC$filename.length) + + JSC$filename); + + JSC$asm_constants = new String (""); + + for (item = JSC$asm_head; item != null; item = item.next) + { + if (item.type == JSC$ASM_SYMBOL) + { + symtab.append (item.value + String.pack ("CN", 0, item.offset)); + nsymtab_entries++; + } + else if (item.type == JSC$ASM_LABEL) + ; + else + { + /* Real assembler operands. */ + + if (JSC$generate_debug_info) + if (item.linenum != debug_last_linenum) + { + debug.append (String.pack ("CNN", JSC$DEBUG_LINENUMBER, + item.offset + item.size, + item.linenum)); + debug_last_linenum = item.linenum; + } + + if (item.size == 1) + /* We handle these. */ + code.append (String.pack ("C", item.type)); + else + { + /* + * All operands which take an argument, have a method to create + * the byte code entry for their argument. + */ + code.append (String.pack ("C", item.type) + item.bytecode ()); + } + } + } + + symtab = String.pack ("N", nsymtab_entries) + symtab; + + if (JSC$verbose) + { + var msg = ("jsc: code=" + code.length.toString () + + ", constants=" + JSC$asm_constants.length.toString () + + ", symtab=" + symtab.length.toString ()); + + if (JSC$generate_debug_info) + msg += ", debug=" + debug.length.toString (); + + msg += (", headers=" + + (32 + (JSC$generate_debug_info ? 8 : 0)).toString () + + ", total=" + + (code.length + JSC$asm_constants.length + symtab.length + + debug.length + 32 + + (JSC$generate_debug_info ? 8 : 0)).toString ()); + JSC$message (msg); + } + + return (String.pack ("NN", JSC$BC_MAGIC, + 3 + (JSC$generate_debug_info ? 1 : 0)) + + String.pack ("NN", JSC$BC_SECT_CODE, code.length) + code + + + String.pack ("NN", JSC$BC_SECT_CONSTANTS, + JSC$asm_constants.length) + + JSC$asm_constants + + + String.pack ("NN", JSC$BC_SECT_SYMTAB, symtab.length) + symtab + + + (JSC$generate_debug_info + ? String.pack ("NN", JSC$BC_SECT_DEBUG, debug.length) + debug + : "")); +} + + +/* +Local variables: +mode: c +End: +*/ +/* + * Public entry points to the JavaScript compiler. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsc/compiler.js,v $ + * $Id: compiler.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * Definitions. + */ + +JSC$FLAG_VERBOSE = 0x00000001; +JSC$FLAG_ANNOTATE_ASSEMBLER = 0x00000002; +JSC$FLAG_GENERATE_DEBUG_INFO = 0x00000004; +JSC$FLAG_GENERATE_EXECUTABLE_BC_FILES = 0x00000008; + +JSC$FLAG_OPTIMIZE_PEEPHOLE = 0x00000020; +JSC$FLAG_OPTIMIZE_JUMPS = 0x00000040; +JSC$FLAG_OPTIMIZE_BC_SIZE = 0x00000080; +JSC$FLAG_OPTIMIZE_HEAVY = 0x00000100; + +JSC$FLAG_OPTIMIZE_MASK = 0x0000fff0; + +JSC$FLAG_WARN_UNUSED_ARGUMENT = 0x00010000; +JSC$FLAG_WARN_UNUSED_VARIABLE = 0x00020000; +JSC$FLAG_WARN_SHADOW = 0x00040000; +JSC$FLAG_WARN_WITH_CLOBBER = 0x00080000; +JSC$FLAG_WARN_MISSING_SEMICOLON = 0x00100000; +JSC$FLAG_WARN_STRICT_ECMA = 0x00200000; +JSC$FLAG_WARN_DEPRECATED = 0x00400000; + +JSC$FLAG_WARN_MASK = 0xffff0000; + +/* + * Global interfaces to the compiler. + */ + +function JSC$compile_file (fname, flags, asm_file, bc_file) +{ + var stream = new JSC$StreamFile (fname); + return JSC$compile_stream (stream, flags, asm_file, bc_file); +} + + +function JSC$compile_string (str, flags, asm_file, bc_file) +{ + var stream = new JSC$StreamString (str); + return JSC$compile_stream (stream, flags, asm_file, bc_file); +} + + +function JSC$compiler_reset () +{ + /* Reset compiler to a known initial state. */ + JSC$parser_reset (); + JSC$gram_reset (); + JSC$asm_reset (); +} + + +function JSC$compile_stream (stream, flags, asm_file, bc_file) +{ + var result = false; + + JSC$compiler_reset (); + + if (stream.open ()) + { + try + { + JSC$verbose = ((flags & JSC$FLAG_VERBOSE) != 0); + JSC$generate_debug_info + = ((flags & JSC$FLAG_GENERATE_DEBUG_INFO) != 0); + + JSC$warn_unused_argument + = ((flags & JSC$FLAG_WARN_UNUSED_ARGUMENT) != 0); + JSC$warn_unused_variable + = ((flags & JSC$FLAG_WARN_UNUSED_VARIABLE) != 0); + JSC$warn_shadow + = ((flags & JSC$FLAG_WARN_SHADOW) != 0); + JSC$warn_with_clobber + = ((flags & JSC$FLAG_WARN_WITH_CLOBBER) != 0); + JSC$warn_missing_semicolon + = ((flags & JSC$FLAG_WARN_MISSING_SEMICOLON) != 0); + JSC$warn_strict_ecma + = ((flags & JSC$FLAG_WARN_STRICT_ECMA) != 0); + JSC$warn_deprecated + = ((flags & JSC$FLAG_WARN_DEPRECATED) != 0); + + /* Compilation and assembler generation time optimizations. */ + JSC$optimize_constant_folding = true; + JSC$optimize_type = true; + + JSC$parser_parse (stream); + + /* Assembler. */ + JSC$asm_generate (); + + /* + * We don't need the syntax tree anymore. Free it and save + * some memory. + */ + JSC$parser_reset (); + + /* Optimize if requested. */ + if ((flags & JSC$FLAG_OPTIMIZE_MASK) != 0) + JSC$asm_optimize (flags); + + if (typeof asm_file == "string") + { + var asm_stream = new File (asm_file); + var src_stream = false; + + if (asm_stream.open ("w")) + { + if ((flags & JSC$FLAG_ANNOTATE_ASSEMBLER) != 0) + if (stream.rewind ()) + src_stream = stream; + + JSC$asm_print (src_stream, asm_stream); + asm_stream.close (); + } + else + JSC$message ("jsc: couldn't create asm output file \"" + + asm_file + "\": " + + System.strerror (System.errno)); + } + + JSC$asm_finalize (); + + result = JSC$asm_bytecode (); + + /* Remove all intermediate results from the memory. */ + JSC$compiler_reset (); + + if (typeof bc_file == "string") + { + var ostream = new File (bc_file); + if (ostream.open ("w")) + { + ostream.write (result); + ostream.close (); + + if ((flags & JSC$FLAG_GENERATE_EXECUTABLE_BC_FILES) != 0) + { + /* Add execute permissions to the output file. */ + var st = File.stat (bc_file); + if (st) + { + if (!File.chmod (bc_file, st[2] | 0111)) + JSC$message ("jsc: couldn't add execute " + + "permissions to bc file \"" + + bc_file + "\": " + + System.strerror (System.errno)); + } + else + JSC$message ("jsc: couldn't stat bc file \"" + bc_file + + "\": " + + System.strerror (System.errno)); + } + } + else + JSC$message ("jsc: couldn't create bc file \"" + bc_file + + "\": " + System.strerror (System.errno)); + } + } + finally + { + stream.close (); + } + } + else + error ("jsc: couldn't open input stream \"" + stream.name + "\": " + + stream.error); + + return result; +} + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/jsc/defs.js b/reactos/lib/kjs/jsc/defs.js new file mode 100644 index 00000000000..4c2f079e60b --- /dev/null +++ b/reactos/lib/kjs/jsc/defs.js @@ -0,0 +1,178 @@ +/* + * Internal definitions. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsc/defs.js,v $ + * $Id: defs.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * Constants. + */ + +/* Tokens. */ + +JSC$tEOF = 128; +JSC$tINTEGER = 129; +JSC$tFLOAT = 130; +JSC$tSTRING = 131; +JSC$tIDENTIFIER = 132; + +JSC$tBREAK = 133; +JSC$tCONTINUE = 134; +JSC$tDELETE = 135; +JSC$tELSE = 136; +JSC$tFOR = 137; +JSC$tFUNCTION = 138; +JSC$tIF = 139; +JSC$tIN = 140; +JSC$tNEW = 141; +JSC$tRETURN = 142; +JSC$tTHIS = 143; +JSC$tTYPEOF = 144; +JSC$tVAR = 145; +JSC$tVOID = 146; +JSC$tWHILE = 147; +JSC$tWITH = 148; + +JSC$tCASE = 149; +JSC$tCATCH = 150; +JSC$tCLASS = 151; +JSC$tCONST = 152; +JSC$tDEBUGGER = 153; +JSC$tDEFAULT = 154; +JSC$tDO = 155; +JSC$tENUM = 156; +JSC$tEXPORT = 157; +JSC$tEXTENDS = 158; +JSC$tFINALLY = 159; +JSC$tIMPORT = 160; +JSC$tSUPER = 161; +JSC$tSWITCH = 162; +JSC$tTHROW = 163; +JSC$tTRY = 164; + +JSC$tNULL = 165; +JSC$tTRUE = 166; +JSC$tFALSE = 167; + +JSC$tEQUAL = 168; +JSC$tNEQUAL = 169; +JSC$tLE = 170; +JSC$tGE = 171; +JSC$tAND = 172; +JSC$tOR = 173; +JSC$tPLUSPLUS = 174; +JSC$tMINUSMINUS = 175; +JSC$tMULA = 176; +JSC$tDIVA = 177; +JSC$tMODA = 178; +JSC$tADDA = 179; +JSC$tSUBA = 180; +JSC$tANDA = 181; +JSC$tXORA = 182; +JSC$tORA = 183; +JSC$tLSIA = 184; +JSC$tLSHIFT = 185; +JSC$tRSHIFT = 186; +JSC$tRRSHIFT = 187; +JSC$tRSIA = 188; +JSC$tRRSA = 189; +JSC$tSEQUAL = 190; +JSC$tSNEQUAL = 191; + + +/* Expressions. */ + +JSC$EXPR_COMMA = 0; +JSC$EXPR_ASSIGNMENT = 1; +JSC$EXPR_QUEST_COLON = 2; +JSC$EXPR_LOGICAL = 3; +JSC$EXPR_BITWISE = 4; +JSC$EXPR_EQUALITY = 5; +JSC$EXPR_RELATIONAL = 6; +JSC$EXPR_SHIFT = 7; +JSC$EXPR_MULTIPLICATIVE = 8; +JSC$EXPR_ADDITIVE = 9; +JSC$EXPR_THIS = 10; +JSC$EXPR_NULL = 11; +JSC$EXPR_TRUE = 12; +JSC$EXPR_FALSE = 13; +JSC$EXPR_IDENTIFIER = 14; +JSC$EXPR_FLOAT = 15; +JSC$EXPR_INTEGER = 16; +JSC$EXPR_STRING = 17; +JSC$EXPR_CALL = 18; +JSC$EXPR_OBJECT_PROPERTY = 19; +JSC$EXPR_OBJECT_ARRAY = 20; +JSC$EXPR_NEW = 21; +JSC$EXPR_DELETE = 22; +JSC$EXPR_VOID = 23; +JSC$EXPR_TYPEOF = 24; +JSC$EXPR_PREFIX = 25; +JSC$EXPR_POSTFIX = 26; +JSC$EXPR_UNARY = 27; +JSC$EXPR_REGEXP = 28; +JSC$EXPR_ARRAY_INITIALIZER = 29; +JSC$EXPR_OBJECT_INITIALIZER = 30; + +/* Statements */ + +JSC$STMT_BLOCK = 0; +JSC$STMT_FUNCTION_DECLARATION = 1; +JSC$STMT_VARIABLE = 2; +JSC$STMT_EMPTY = 3; +JSC$STMT_EXPR = 4; +JSC$STMT_IF = 5; +JSC$STMT_WHILE = 6; +JSC$STMT_FOR = 7; +JSC$STMT_FOR_IN = 8; +JSC$STMT_CONTINUE = 9; +JSC$STMT_BREAK = 10; +JSC$STMT_RETURN = 11; +JSC$STMT_WITH = 12; +JSC$STMT_TRY = 13; +JSC$STMT_THROW = 14; +JSC$STMT_DO_WHILE = 15; +JSC$STMT_SWITCH = 16; +JSC$STMT_LABELED_STMT = 17; + +/* JavaScript types. */ + +JSC$JS_UNDEFINED = 0; +JSC$JS_NULL = 1; +JSC$JS_BOOLEAN = 2; +JSC$JS_INTEGER = 3; +JSC$JS_STRING = 4; +JSC$JS_FLOAT = 5; +JSC$JS_ARRAY = 6; +JSC$JS_OBJECT = 7; +JSC$JS_BUILTIN = 11; + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/jsc/entry.js b/reactos/lib/kjs/jsc/entry.js new file mode 100644 index 00000000000..2f7a2126870 --- /dev/null +++ b/reactos/lib/kjs/jsc/entry.js @@ -0,0 +1,206 @@ +/* + * Public entry points to the JavaScript compiler. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsc/entry.js,v $ + * $Id: entry.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * Definitions. + */ + +JSC$FLAG_VERBOSE = 0x00000001; +JSC$FLAG_ANNOTATE_ASSEMBLER = 0x00000002; +JSC$FLAG_GENERATE_DEBUG_INFO = 0x00000004; +JSC$FLAG_GENERATE_EXECUTABLE_BC_FILES = 0x00000008; + +JSC$FLAG_OPTIMIZE_PEEPHOLE = 0x00000020; +JSC$FLAG_OPTIMIZE_JUMPS = 0x00000040; +JSC$FLAG_OPTIMIZE_BC_SIZE = 0x00000080; +JSC$FLAG_OPTIMIZE_HEAVY = 0x00000100; + +JSC$FLAG_OPTIMIZE_MASK = 0x0000fff0; + +JSC$FLAG_WARN_UNUSED_ARGUMENT = 0x00010000; +JSC$FLAG_WARN_UNUSED_VARIABLE = 0x00020000; +JSC$FLAG_WARN_SHADOW = 0x00040000; +JSC$FLAG_WARN_WITH_CLOBBER = 0x00080000; +JSC$FLAG_WARN_MISSING_SEMICOLON = 0x00100000; +JSC$FLAG_WARN_STRICT_ECMA = 0x00200000; +JSC$FLAG_WARN_DEPRECATED = 0x00400000; + +JSC$FLAG_WARN_MASK = 0xffff0000; + +/* + * Global interfaces to the compiler. + */ + +function JSC$compile_file (fname, flags, asm_file, bc_file) +{ + var stream = new JSC$StreamFile (fname); + return JSC$compile_stream (stream, flags, asm_file, bc_file); +} + + +function JSC$compile_string (str, flags, asm_file, bc_file) +{ + var stream = new JSC$StreamString (str); + return JSC$compile_stream (stream, flags, asm_file, bc_file); +} + + +function JSC$compiler_reset () +{ + /* Reset compiler to a known initial state. */ + JSC$parser_reset (); + JSC$gram_reset (); + JSC$asm_reset (); +} + + +function JSC$compile_stream (stream, flags, asm_file, bc_file) +{ + var result = false; + + JSC$compiler_reset (); + + if (stream.open ()) + { + try + { + JSC$verbose = ((flags & JSC$FLAG_VERBOSE) != 0); + JSC$generate_debug_info + = ((flags & JSC$FLAG_GENERATE_DEBUG_INFO) != 0); + + JSC$warn_unused_argument + = ((flags & JSC$FLAG_WARN_UNUSED_ARGUMENT) != 0); + JSC$warn_unused_variable + = ((flags & JSC$FLAG_WARN_UNUSED_VARIABLE) != 0); + JSC$warn_shadow + = ((flags & JSC$FLAG_WARN_SHADOW) != 0); + JSC$warn_with_clobber + = ((flags & JSC$FLAG_WARN_WITH_CLOBBER) != 0); + JSC$warn_missing_semicolon + = ((flags & JSC$FLAG_WARN_MISSING_SEMICOLON) != 0); + JSC$warn_strict_ecma + = ((flags & JSC$FLAG_WARN_STRICT_ECMA) != 0); + JSC$warn_deprecated + = ((flags & JSC$FLAG_WARN_DEPRECATED) != 0); + + /* Compilation and assembler generation time optimizations. */ + JSC$optimize_constant_folding = true; + JSC$optimize_type = true; + + JSC$parser_parse (stream); + + /* Assembler. */ + JSC$asm_generate (); + + /* + * We don't need the syntax tree anymore. Free it and save + * some memory. + */ + JSC$parser_reset (); + + /* Optimize if requested. */ + if ((flags & JSC$FLAG_OPTIMIZE_MASK) != 0) + JSC$asm_optimize (flags); + + if (typeof asm_file == "string") + { + var asm_stream = new File (asm_file); + var src_stream = false; + + if (asm_stream.open ("w")) + { + if ((flags & JSC$FLAG_ANNOTATE_ASSEMBLER) != 0) + if (stream.rewind ()) + src_stream = stream; + + JSC$asm_print (src_stream, asm_stream); + asm_stream.close (); + } + else + JSC$message ("jsc: couldn't create asm output file \"" + + asm_file + "\": " + + System.strerror (System.errno)); + } + + JSC$asm_finalize (); + + result = JSC$asm_bytecode (); + + /* Remove all intermediate results from the memory. */ + JSC$compiler_reset (); + + if (typeof bc_file == "string") + { + var ostream = new File (bc_file); + if (ostream.open ("w")) + { + ostream.write (result); + ostream.close (); + + if ((flags & JSC$FLAG_GENERATE_EXECUTABLE_BC_FILES) != 0) + { + /* Add execute permissions to the output file. */ + var st = File.stat (bc_file); + if (st) + { + if (!File.chmod (bc_file, st[2] | 0111)) + JSC$message ("jsc: couldn't add execute " + + "permissions to bc file \"" + + bc_file + "\": " + + System.strerror (System.errno)); + } + else + JSC$message ("jsc: couldn't stat bc file \"" + bc_file + + "\": " + + System.strerror (System.errno)); + } + } + else + JSC$message ("jsc: couldn't create bc file \"" + bc_file + + "\": " + System.strerror (System.errno)); + } + } + finally + { + stream.close (); + } + } + else + error ("jsc: couldn't open input stream \"" + stream.name + "\": " + + stream.error); + + return result; +} + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/jsc/gram.js b/reactos/lib/kjs/jsc/gram.js new file mode 100644 index 00000000000..bc502218cd4 --- /dev/null +++ b/reactos/lib/kjs/jsc/gram.js @@ -0,0 +1,2697 @@ +/* + * Grammar components. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsc/gram.js,v $ + * $Id: gram.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* General helpers. */ + +function JSC$gram_reset () +{ + JSC$label_count = 1; + JSC$cont_break = new JSC$ContBreak (); +} + + +function JSC$alloc_label (num_labels) +{ + JSC$label_count += num_labels; + + return JSC$label_count - num_labels; +} + + +function JSC$format_label (num) +{ + return ".L" + num.toString (); +} + + +function JSC$count_locals_from_stmt_list (list) +{ + var i; + + /* First, count how many variables we need at the toplevel. */ + var lcount = 0; + for (i = 0; i < list.length; i++) + lcount += list[i].count_locals (false); + + /* Second, count the maximum amount needed by the nested blocks. */ + var rmax = 0; + for (i = 0; i < list.length; i++) + { + var rc = list[i].count_locals (true); + if (rc > rmax) + rmax = rc; + } + + return lcount + rmax; +} + +/* + * The handling of the `continue' and `break' labels for looping + * constructs. The variable `JSC$cont_break' holds an instance of + * JSC$ContBreak class. The instance contains a valid chain of + * looping constructs and the currently active with and try testing + * levels. The actual `continue', `break', and `return' statements + * investigate the chain and generate appropriate `with_pop' and + * `try_pop' operands. + * + * If the instance variable `inswitch' is true, the continue statement + * is inside a switch statement. In this case, the continue statement + * must pop one item from the stack. That item is the value of the + * case expression. + */ + +function JSC$ContBreakFrame (loop_break, loop_continue, inswitch, label, next) +{ + this.loop_break = loop_break; + this.loop_continue = loop_continue; + this.inswitch = inswitch; + this.label = label; + this.next = next; + + this.with_nesting = 0; + this.try_nesting = 0; +} + + +function JSC$ContBreak () +{ + this.top = new JSC$ContBreakFrame (null, null, false, null); +} + +new JSC$ContBreak (); + +function JSC$ContBreak$push (loop_break, loop_continue, inswitch, label) +{ + this.top = new JSC$ContBreakFrame (loop_break, loop_continue, inswitch, + label, this.top); +} +JSC$ContBreak.prototype.push = JSC$ContBreak$push; + +function JSC$ContBreak$pop () +{ + if (this.top == null) + error ("jsc: internal error: continue-break stack underflow"); + + this.top = this.top.next; +} +JSC$ContBreak.prototype.pop = JSC$ContBreak$pop; + +/* + * Count the currently active `try' nesting that should be removed on + * `return' statement. + */ +function JSC$ContBreak$try_return_nesting () +{ + var f; + var count = 0; + + for (f = this.top; f; f = f.next) + count += f.try_nesting; + + return count; +} +JSC$ContBreak.prototype.try_return_nesting = JSC$ContBreak$try_return_nesting; + +/* + * Count currently active `with' nesting that should be removed on + * `continue' or `break' statement. + */ +function JSC$ContBreak$count_with_nesting (label) +{ + var f; + var count = 0; + + for (f = this.top; f; f = f.next) + { + count += f.with_nesting; + if (label) + { + if (f.label == label) + break; + } + else + if (f.loop_continue) + break; + } + return count; +} +JSC$ContBreak.prototype.count_with_nesting = JSC$ContBreak$count_with_nesting; + +/* + * Count the currently active `try' nesting that should be removed on + * `continue' or `break' statement. + */ +function JSC$ContBreak$count_try_nesting (label) +{ + var f; + var count = 0; + + for (f = this.top; f; f = f.next) + { + count += f.try_nesting; + if (label) + { + if (f.label == label) + break; + } + else + if (f.loop_continue) + break; + } + return count; +} +JSC$ContBreak.prototype.count_try_nesting = JSC$ContBreak$count_try_nesting; + +function JSC$ContBreak$count_switch_nesting (label) +{ + var f; + var count = 0; + + for (f = this.top; f; f = f.next) + { + if (f.inswitch) + count++; + if (label) + { + if (f.label == label) + break; + } + else + if (f.loop_continue) + break; + } + return count; +} +JSC$ContBreak.prototype.count_switch_nesting + = JSC$ContBreak$count_switch_nesting; + +function JSC$ContBreak$get_continue (label) +{ + var f; + + for (f = this.top; f; f = f.next) + if (label) + { + if (f.label == label) + return f.loop_continue; + } + else + if (f.loop_continue) + return f.loop_continue; + + return null; +} +JSC$ContBreak.prototype.get_continue = JSC$ContBreak$get_continue; + +function JSC$ContBreak$get_break (label) +{ + var f; + + for (f = this.top; f; f = f.next) + if (label) + { + if (f.label == label) + return f.loop_break; + } + else + if (f.loop_break) + return f.loop_break; + + return null; +} +JSC$ContBreak.prototype.get_break = JSC$ContBreak$get_break; + +function JSC$ContBreak$is_unique_label (label) +{ + var f; + + for (f = this.top; f; f = f.next) + if (f.label == label) + return false; + + return true; +} +JSC$ContBreak.prototype.is_unique_label = JSC$ContBreak$is_unique_label; + +JSC$cont_break = null; + + +/* Function declaration. */ + +function JSC$function_declaration (ln, lbrace_ln, name, name_given, args, + block, use_arguments_prop) +{ + this.linenum = ln; + this.lbrace_linenum = lbrace_ln; + this.name = name; + this.name_given = name_given; + this.args = args; + this.block = block; + this.use_arguments_prop = use_arguments_prop; + this.asm = JSC$function_declaration_asm; +} + +function JSC$function_declaration_asm () +{ + var i, a; + + /* Define arguments. */ + JSC$ns.push_frame (); + + for (i = 0, a = 2; i < this.args.length; i++, a++) + JSC$ns.define_symbol (this.args[i], JSC$SCOPE_ARG, a, this.linenum); + + /* Define the function name to be a global symbol. */ + new JSC$ASM_symbol (this.linenum, this.name).link (); + + /* Check that function gets the required amount of arguments. */ + new JSC$ASM_load_arg (this.lbrace_linenum, 1).link (); + new JSC$ASM_add_2_i (this.lbrace_linenum).link (); + new JSC$ASM_min_args (this.lbrace_linenum, this.args.length + 2).link (); + + /* Count how many local variables we need. */ + var num_locals = JSC$count_locals_from_stmt_list (this.block); + + /* Is the `arguments' property of function instance used? */ + if (this.use_arguments_prop) + num_locals++; + + if (num_locals > 0) + { + new JSC$ASM_locals (this.lbrace_linenum, num_locals).link (); + if (this.use_arguments_prop) + { + /* + * Create an array for the arguments array and store it to + * the first local variable. + */ + var ln = this.lbrace_linenum; + var locn = JSC$ns.alloc_local (); + JSC$ns.define_symbol ("arguments", JSC$SCOPE_LOCAL, locn, ln); + + new JSC$ASM_const_i0 (ln).link (); + new JSC$ASM_load_global (ln, "Array").link (); + new JSC$ASM_new (ln).link (); + new JSC$ASM_swap (ln).link (); + new JSC$ASM_apop (ln, 2).link (); + new JSC$ASM_store_local (ln, locn).link (); + + /* Push individual argumens to the array. */ + + /* Init the loop counter. */ + new JSC$ASM_const_i0 (ln).link (); + + var l_loop = new JSC$ASM_label (); + var l_out = new JSC$ASM_label (); + + l_loop.link (); + + /* Check if we'r done. */ + new JSC$ASM_dup (ln).link (); + new JSC$ASM_load_arg (ln, 1).link (); + new JSC$ASM_cmp_ge (ln).link (); + new JSC$ASM_iftrue_b (ln, l_out).link (); + + /* Load the nth argument to the top of the stack. */ + new JSC$ASM_dup (ln).link (); + new JSC$ASM_add_2_i (ln).link (); + new JSC$ASM_load_nth_arg (ln).link (); + + /* Push it to the array. */ + new JSC$ASM_const_i1 (ln).link (); + new JSC$ASM_load_local (ln, locn).link (); + new JSC$ASM_call_method (ln, "push").link (); + new JSC$ASM_pop_n (ln, 4).link (); + + /* Increment loop counter and continue. */ + new JSC$ASM_add_1_i (ln).link (); + new JSC$ASM_jmp (ln, l_loop).link (); + + /* We'r done. */ + l_out.link (); + + /* Pop the loop counter. */ + new JSC$ASM_pop (ln).link (); + } + } + + /* Assembler for our body. */ + for (i = 0; i < this.block.length; i++) + this.block[i].asm (); + + /* + * Every function must return something. We could check if all + * control flows in this function ends to a return, but that would + * bee too hard... Just append a return const_undefined. The optimizer + * will remove it if it is not needed. + */ + var ln; + if (this.block.length > 0) + ln = this.block[this.block.length - 1].linenum; + else + ln = this.linenum; + + new JSC$ASM_const_undefined (ln).link (); + new JSC$ASM_return (ln).link (); + + /* Pop our namespace. */ + JSC$ns.pop_frame (); +} + + +function JSC$zero_function () +{ + return 0; +} + + +/* + * Statements. + */ + +/* Block. */ + +function JSC$stmt_block (ln, list) +{ + this.stype = JSC$STMT_BLOCK; + this.linenum = ln; + this.stmts = list; + this.asm = JSC$stmt_block_asm; + this.count_locals = JSC$stmt_block_count_locals; +} + +function JSC$stmt_block_asm () +{ + JSC$ns.push_frame (); + + /* Assembler for our stmts. */ + var i; + for (i = 0; i < this.stmts.length; i++) + this.stmts[i].asm (); + + JSC$ns.pop_frame (); +} + + +function JSC$stmt_block_count_locals (recursive) +{ + if (!recursive) + return 0; + + return JSC$count_locals_from_stmt_list (this.stmts); +} + +/* Function declaration. */ + +function JSC$stmt_function_declaration (ln, container_id, function_id, + given_id) +{ + this.stype = JSC$STMT_FUNCTION_DECLARATION; + this.linenum = ln; + this.container_id = container_id; + this.function_id = function_id; + this.given_id = given_id; + this.asm = JSC$stmt_function_declaration_asm; + this.count_locals = JSC$zero_function; +} + +function JSC$stmt_function_declaration_asm () +{ + new JSC$ASM_load_global (this.linenum, this.function_id).link (); + new JSC$ASM_load_global (this.linenum, this.container_id).link (); + new JSC$ASM_store_property (this.linenum, this.given_id).link (); +} + +/* Empty */ + +function JSC$stmt_empty (ln) +{ + this.stype = JSC$STMT_EMPTY; + this.linenum = ln; + this.asm = JSC$stmt_empty_asm; + this.count_locals = JSC$zero_function; +} + +function JSC$stmt_empty_asm () +{ + /* Nothing here. */ +} + + +/* Continue. */ + +function JSC$stmt_continue (ln, label) +{ + this.stype = JSC$STMT_CONTINUE; + this.linenum = ln; + this.label = label; + this.asm = JSC$stmt_continue_asm; + this.count_locals = JSC$zero_function; +} + +function JSC$stmt_continue_asm () +{ + var l_cont = JSC$cont_break.get_continue (this.label); + + if (l_cont == null) + { + if (this.label) + error (JSC$filename + ":" + this.linenum.toString () + + ": label `" + this.label + + "' not found for continue statement"); + else + error (JSC$filename + ":" + this.linenum.toString () + + ": continue statement not within a loop"); + } + + var nesting = JSC$cont_break.count_with_nesting (this.label); + if (nesting > 0) + new JSC$ASM_with_pop (this.linenum, nesting).link (); + + nesting = JSC$cont_break.count_try_nesting (this.label); + if (nesting > 0) + new JSC$ASM_try_pop (this.linenum, nesting).link (); + + nesting = JSC$cont_break.count_switch_nesting (this.label); + if (nesting > 0) + { + /* Pop the value of the switch expression. */ + if (nesting == 1) + new JSC$ASM_pop (this.linenum).link (); + else + new JSC$ASM_pop_n (this.linenum, nesting).link (); + } + + new JSC$ASM_jmp (this.linenum, l_cont).link (); +} + + +/* Break. */ + +function JSC$stmt_break (ln, label) +{ + this.stype = JSC$STMT_BREAK; + this.linenum = ln; + this.label = label; + this.asm = JSC$stmt_break_asm; + this.count_locals = JSC$zero_function; +} + +function JSC$stmt_break_asm () +{ + var l_break = JSC$cont_break.get_break (this.label); + + if (l_break == null) + { + if (this.label) + error (JSC$filename + ":" + this.linenum.toString () + + ": label `" + this.label + + "' not found for break statement"); + else + error (JSC$filename + ":" + this.linenum.toString() + + ": break statement not within a loop or switch"); + } + + var nesting = JSC$cont_break.count_with_nesting (this.label); + if (nesting > 0) + new JSC$ASM_with_pop (this.linenum, nesting).link (); + + nesting = JSC$cont_break.count_try_nesting (this.label); + if (nesting > 0) + new JSC$ASM_try_pop (this.linenum, nesting).link (); + + /* + * For non-labeled breaks, the switch nesting is handled in the + * stmt_switch(). The code after the label, returned by the + * get_break(), will handle the switch nesting in these cases. + * For the labeled breaks, we must pop the switch nesting here. + */ + if (this.label) + { + nesting = JSC$cont_break.count_switch_nesting (this.label); + if (nesting > 0) + { + if (nesting == 1) + new JSC$ASM_pop (this.linenum).link (); + else + new JSC$ASM_pop_n (this.linenum, nesting).link (); + } + } + + new JSC$ASM_jmp (this.linenum, l_break).link (); +} + + +/* Return. */ + +function JSC$stmt_return (ln, expr) +{ + this.stype = JSC$STMT_RETURN; + this.linenum = ln; + this.expr = expr; + this.asm = JSC$stmt_return_asm; + this.count_locals = JSC$zero_function; +} + +function JSC$stmt_return_asm () +{ + var nesting = JSC$cont_break.try_return_nesting (); + if (nesting > 0) + new JSC$ASM_try_pop (this.linenum, nesting).link (); + + if (this.expr != null) + this.expr.asm (); + else + new JSC$ASM_const_undefined (this.linenum).link (); + + new JSC$ASM_return (this.linenum).link (); +} + + +/* Switch. */ + +function JSC$stmt_switch (ln, last_ln, expr, clauses) +{ + this.stype = JSC$STMT_SWITCH; + this.linenum = ln; + this.last_linenum = last_ln; + this.expr = expr; + this.clauses = clauses; + this.asm = JSC$stmt_switch_asm; + this.count_locals = JSC$stmt_switch_count_locals; +} + +function JSC$stmt_switch_asm () +{ + /* Evaluate the switch expression to the top of the stack. */ + this.expr.asm (); + + /* The switch statement define a break label. */ + var l_break = new JSC$ASM_label (); + JSC$cont_break.push (l_break, null, true, null); + + /* For each clause (except the first), insert check and body labels. */ + var i; + for (i = 1; i < this.clauses.length; i++) + { + this.clauses[i].l_check = new JSC$ASM_label (); + this.clauses[i].l_body = new JSC$ASM_label (); + } + + /* Generate code for each clause. */ + for (i = 0; i < this.clauses.length; i++) + { + /* Is this the last clause? */ + var last = i + 1 >= this.clauses.length; + var c = this.clauses[i]; + + var next_check, next_body; + if (last) + next_check = next_body = l_break; + else + { + next_check = this.clauses[i + 1].l_check; + next_body = this.clauses[i + 1].l_body; + } + + if (c.expr) + { + /* + * Must check if this clause matches the expression. If c.expr + * is null, this is the default clause that matches always. + */ + + if (i > 0) + c.l_check.link (); + + new JSC$ASM_dup (c.linenum).link (); + c.expr.asm (); + new JSC$ASM_cmp_eq (c.linenum).link (); + new JSC$ASM_iffalse_b (c.linenum, next_check).link (); + } + else + { + if (i > 0) + /* The check label for the default case. */ + c.l_check.link (); + } + + /* Generate assembler for the body. */ + if (i > 0) + c.l_body.link (); + + var j; + for (j = 0; j < c.length; j++) + c[j].asm (); + + /* And finally, jump to the next body. (this is the fallthrough case). */ + new JSC$ASM_jmp (c.last_linenum, next_body).link (); + } + + JSC$cont_break.pop (); + + /* The break label. */ + l_break.link (); + + /* Pop the value of the switch expression. */ + new JSC$ASM_pop (this.last_linenum).link (); +} + +function JSC$stmt_switch_count_locals (recursive) +{ + var locals = 0; + var i, j; + + if (recursive) + { + /* For the recursive cases, we need the maximum of our clause stmts. */ + for (i = 0; i < this.clauses.length; i++) + { + var c = this.clauses[i]; + for (j = 0; j < c.length; j++) + { + var l = c[j].count_locals (true); + if (l > locals) + locals = l; + } + } + } + else + { + /* + * The case clauses are not blocks. Therefore, we need the amount, + * needed by the clauses at the top-level. + */ + + for (i = 0; i < this.clauses.length; i++) + { + var c = this.clauses[i]; + for (j = 0; j < c.length; j++) + locals += c[j].count_locals (false); + } + } + + return locals; +} + + +/* With. */ + +function JSC$stmt_with (ln, expr, stmt) +{ + this.stype = JSC$STMT_WITH; + this.linenum = ln; + this.expr = expr; + this.stmt = stmt; + this.asm = JSC$stmt_with_asm; + this.count_locals = JSC$stmt_with_count_locals; +} + +function JSC$stmt_with_asm () +{ + this.expr.asm (); + + new JSC$ASM_with_push (this.linenum).link (); + JSC$cont_break.top.with_nesting++; + + this.stmt.asm (); + + JSC$cont_break.top.with_nesting--; + new JSC$ASM_with_pop (this.linenum, 1).link (); +} + +function JSC$stmt_with_count_locals (recursive) +{ + if (!recursive) + { + if (this.stmt.stype == JSC$STMT_VARIABLE) + return this.stmt.list.length; + + return 0; + } + else + return this.stmt.count_locals (true); +} + + +/* Try. */ + +function JSC$stmt_try (ln, try_block_last_ln, try_last_ln, block, catch_list, + fin) +{ + this.stype = JSC$STMT_TRY; + this.linenum = ln; + this.try_block_last_linenum = try_block_last_ln; + this.try_last_linenum = try_last_ln; + this.block = block; + this.catch_list = catch_list; + this.fin = fin; + this.asm = JSC$stmt_try_asm; + this.count_locals = JSC$stmt_try_count_locals; +} + +function JSC$stmt_try_asm () +{ + var l_finally = new JSC$ASM_label (); + + /* Protect and execute the try-block. */ + + var l_try_error = new JSC$ASM_label (); + new JSC$ASM_try_push (this.linenum, l_try_error).link (); + JSC$cont_break.top.try_nesting++; + + this.block.asm (); + + JSC$cont_break.top.try_nesting--; + new JSC$ASM_try_pop (this.try_block_last_linenum, 1).link (); + + /* + * All ok so far. Push a `false' to indicate no error and jump to + * the finally block (or out if we have no finally block). + */ + new JSC$ASM_const_false (this.try_block_last_linenum).link (); + new JSC$ASM_jmp (this.try_block_last_linenum, l_finally).link (); + + /* + * Handle try block failures. The thrown value is on the top of the + * stack. + */ + + l_try_error.link (); + + if (this.catch_list) + { + /* + * We keep one boolean variable below the thrown value. Its default + * value is false. When one of our catch blocks are entered, it is + * set to true to indicate that we shouldn't throw the error + * anymore. + */ + new JSC$ASM_const_false (this.catch_list.linenum).link (); + new JSC$ASM_swap (this.catch_list.linenum).link (); + + /* Protect and execute the catch list. */ + + var l_catch_list_error = new JSC$ASM_label (); + new JSC$ASM_try_push (this.catch_list.linenum, + l_catch_list_error).link (); + JSC$cont_break.top.try_nesting++; + + /* Insert start and body labels for each catch list item. */ + var i; + for (i = 0; i < this.catch_list.length; i++) + { + this.catch_list[i].l_start = new JSC$ASM_label (); + this.catch_list[i].l_body = new JSC$ASM_label (); + } + + /* A label for the catch list end. */ + var l_catch_list_end = new JSC$ASM_label (); + + /* Process the individual catches. */ + for (i = 0; i < this.catch_list.length; i++) + { + var c = this.catch_list[i]; + + /* This is the starting point of this catch frame. */ + c.l_start.link (); + + /* + * Create a new namespace frame and bind the catch's + * identifier to the thrown exception. + */ + + JSC$ns.push_frame (); + JSC$ns.define_symbol (c.id, JSC$SCOPE_LOCAL, JSC$ns.alloc_local (), + c.linenum); + + new JSC$ASM_dup (c.linenum).link (); + new JSC$ASM_store_local (c.linenum, + JSC$ns.lookup_symbol (c.id).value).link (); + + /* Check the possible guard. We must protect its calculation. */ + if (c.guard) + { + var l_guard_error = new JSC$ASM_label (); + new JSC$ASM_try_push (c.linenum, l_guard_error).link (); + JSC$cont_break.top.try_nesting++; + + /* Calculate the guard. */ + c.guard.asm (); + + JSC$cont_break.top.try_nesting--; + new JSC$ASM_try_pop (c.linenum, 1).link (); + + /* + * Wow! We managed to do it. Now, let's check if we + * accept this catch case. + */ + + var next; + if (i + 1 >= this.catch_list.length) + next = l_catch_list_end; + else + next = this.catch_list[i + 1].l_start; + + if (c.guard.lang_type == JSC$JS_BOOLEAN) + new JSC$ASM_iffalse_b (c.linenum, next).link (); + else + new JSC$ASM_iffalse (c.linenum, next).link (); + + /* Yes, we do accept it. Just jump to do the stuffs. */ + new JSC$ASM_jmp (c.linenum, c.l_body).link (); + + /* + * The evaluation of the guard failed. Do the cleanup + * and jump to the next case. + */ + + l_guard_error.link (); + + /* Pop the exception. */ + new JSC$ASM_pop (c.linenum).link (); + + /* Check the next case. */ + new JSC$ASM_jmp (c.linenum, next).link (); + } + + /* + * We did enter the catch body. Let's update our boolean + * status variable to reflect this fact. + */ + c.l_body.link (); + + new JSC$ASM_swap (c.linenum).link (); + new JSC$ASM_pop (c.linenum).link (); + new JSC$ASM_const_true (c.linenum).link (); + new JSC$ASM_swap (c.linenum).link (); + + /* Code for the catch body. */ + c.stmt.asm (); + + /* We'r done with the namespace frame. */ + JSC$ns.pop_frame (); + + /* + * The next catch tag, or the l_catch_list_end follows us, + * so we don't need a jumps here. + */ + } + + /* + * The catch list was evaluated without errors. + */ + + l_catch_list_end.link (); + JSC$cont_break.top.try_nesting--; + new JSC$ASM_try_pop (this.catch_list.last_linenum, 1).link (); + + /* Did we enter any of our catch lists? */ + + var l_we_did_enter = new JSC$ASM_label (); + new JSC$ASM_swap (this.catch_list.last_linenum).link (); + new JSC$ASM_iftrue_b (this.catch_list.last_linenum, + l_we_did_enter).link (); + + /* No we didn't. */ + + /* + * Push `true' to indicate an exception and jump to the finally + * block. The exception is now on the top of the stack. + */ + new JSC$ASM_const_true (this.catch_list.last_linenum).link (); + new JSC$ASM_jmp (this.catch_list.last_linenum, l_finally).link (); + + /* Yes, we did enter one (or many) of our catch lists. */ + + l_we_did_enter.link (); + + /* Pop the try-block's exception */ + new JSC$ASM_pop (this.catch_list.last_linenum).link (); + + /* + * Push a `false' to indicate "no errors" and jump to the + * finally block. + */ + new JSC$ASM_const_false (this.catch_list.last_linenum).link (); + new JSC$ASM_jmp (this.catch_list.last_linenum, l_finally).link (); + + + /* + * Handle catch list failures. The thrown value is on the top of the + * stack. + */ + + l_catch_list_error.link (); + + /* + * Pop the try-block's exception and our boolean `did we enter a + * catch block' variable. They are below our new exception. + */ + new JSC$ASM_apop (this.catch_list.last_linenum, 2).link (); + + /* + * Push `true' to indicate an exception. We will fallthrough to + * the finally part, so no jump is needed here. + */ + new JSC$ASM_const_true (this.catch_list.last_linenum).link (); + } + else + { + /* No catch list. */ + new JSC$ASM_const_true (this.try_block_last_linenum).link (); + } + + /* The possible finally block. */ + + l_finally.link (); + + if (this.fin) + /* Execute it without protection. */ + this.fin.asm (); + + /* We'r almost there. Let's see if we have to raise a new exception. */ + + var l_out = new JSC$ASM_label (); + new JSC$ASM_iffalse_b (this.try_last_linenum, l_out).link (); + + /* Do raise it. */ + new JSC$ASM_throw (this.try_last_linenum).link (); + + /* The possible exception is handled. Please, continue. */ + l_out.link (); +} + +function JSC$stmt_try_count_locals (recursive) +{ + var count = 0; + var c; + + if (recursive) + { + c = this.block.count_locals (true); + if (c > count) + count = c; + + if (this.catch_list) + { + var i; + for (i = 0; i < this.catch_list.length; i++) + { + c = this.catch_list[i].stmt.count_locals (true); + if (c > count) + count = c; + } + } + if (this.fin) + { + c = this.fin.count_locals (true); + if (c > count) + count = c; + } + } + else + { + if (this.block.stype == JSC$STMT_VARIABLE) + count += this.block.list.length; + + if (this.catch_list) + { + /* One for the call variable. */ + count++; + + var i; + for (i = 0; i < this.catch_list.length; i++) + if (this.catch_list[i].stmt.stype == JSC$STMT_VARIABLE) + count += this.catch_list[i].stmt.list.length; + } + + if (this.fin) + if (this.fin.stype == JSC$STMT_VARIABLE) + count += this.fin.list.length; + } + + return count; +} + + +/* Throw. */ + +function JSC$stmt_throw (ln, expr) +{ + this.stype = JSC$STMT_THROW; + this.linenum = ln; + this.expr = expr; + this.asm = JSC$stmt_throw_asm; + this.count_locals = JSC$zero_function; +} + +function JSC$stmt_throw_asm () +{ + this.expr.asm (); + new JSC$ASM_throw (this.linenum).link (); +} + + +/* Labeled statement. */ +function JSC$stmt_labeled_stmt (ln, id, stmt) +{ + this.stype = JSC$STMT_LABELED_STMT; + this.linenum = ln; + this.id = id; + this.stmt = stmt; + this.asm = JSC$stmt_labeled_stmt_asm; + this.count_locals = JSC$stmt_labeled_stmt_count_locals; +} + +function JSC$stmt_labeled_stmt_asm () +{ + var l_continue = new JSC$ASM_label (); + var l_break = new JSC$ASM_label (); + + /* + * It is an error if we already have a labeled statement with the + * same id. + */ + if (!JSC$cont_break.is_unique_label (this.id)) + error (JSC$filename + ":" + this.linenum.toString () + + ": labeled statement is enclosed by another labeled statement " + + "with the same label"); + + /* Push the break and continue labels. */ + JSC$cont_break.push (l_break, l_continue, false, this.id); + + /* Dump the assembler. */ + l_continue.link (); + this.stmt.asm (); + l_break.link (); + + /* And we'r done with out label scope. */ + JSC$cont_break.pop (); +} + +function JSC$stmt_labeled_stmt_count_locals (recursive) +{ + return this.stmt.count_locals (recursive); +} + + +/* Expression. */ + +function JSC$stmt_expr (expr) +{ + this.stype = JSC$STMT_EXPR; + this.linenum = expr.linenum; + this.expr = expr; + this.asm = JSC$stmt_expr_asm; + this.count_locals = JSC$zero_function; +} + +function JSC$stmt_expr_asm () +{ + this.expr.asm (); + new JSC$ASM_pop (this.linenum).link (); +} + + +/* If. */ + +function JSC$stmt_if (ln, expr, stmt1, stmt2) +{ + this.stype = JSC$STMT_IF; + this.linenum = ln; + this.expr = expr; + this.stmt1 = stmt1; + this.stmt2 = stmt2; + this.asm = JSC$stmt_if_asm; + this.count_locals = JSC$stmt_if_count_locals; +} + +function JSC$stmt_if_asm () +{ + this.expr.asm (); + + var l1 = new JSC$ASM_label (); + var l2 = new JSC$ASM_label (); + + if (JSC$optimize_type && this.expr.lang_type + && this.expr.lang_type == JSC$JS_BOOLEAN) + new JSC$ASM_iffalse_b (this.linenum, l1).link (); + else + new JSC$ASM_iffalse (this.linenum, l1).link (); + + /* Code for the then branch. */ + this.stmt1.asm (); + new JSC$ASM_jmp (this.linenum, l2).link (); + + /* Code for the else branch. */ + l1.link (); + if (this.stmt2 != null) + this.stmt2.asm (); + + /* Done label. */ + l2.link (); +} + + +function JSC$stmt_if_count_locals (recursive) +{ + var lcount; + + if (!recursive) + { + lcount = 0; + if (this.stmt1.stype == JSC$STMT_VARIABLE) + lcount += this.stmt1.list.length; + + if (this.stmt2 != null && this.stmt2.stype == JSC$STMT_VARIABLE) + lcount += this.stmt2.list.length; + } + else + { + lcount = this.stmt1.count_locals (true); + + if (this.stmt2) + { + var c = this.stmt2.count_locals (true); + if (c > lcount) + lcount = c; + } + } + + return lcount; +} + + +/* Do...While. */ + +function JSC$stmt_do_while (ln, expr, stmt) +{ + this.stype = JSC$STMT_DO_WHILE; + this.linenum = ln; + this.expr = expr; + this.stmt = stmt; + this.asm = JSC$stmt_do_while_asm; + this.count_locals = JSC$stmt_do_while_count_locals; +} + +function JSC$stmt_do_while_asm () +{ + var l1 = new JSC$ASM_label (); + var l2 = new JSC$ASM_label (); + var l3 = new JSC$ASM_label (); + + /* Loop label. */ + l1.link (); + + /* Body. */ + JSC$cont_break.push (l3, l2, false, null); + this.stmt.asm (); + JSC$cont_break.pop (); + + /* Condition & continue. */ + l2.link (); + this.expr.asm (); + if (JSC$optimize_type && this.expr.lang_type + && this.expr.lang_type == JSC$JS_BOOLEAN) + new JSC$ASM_iftrue_b (this.linenum, l1).link (); + else + new JSC$ASM_iftrue (this.linenum, l1).link (); + + /* Break label. */ + l3.link (); +} + +function JSC$stmt_do_while_count_locals (recursive) +{ + if (!recursive) + { + if (this.stmt.stype == JSC$STMT_VARIABLE) + return this.stmt.list.length; + + return 0; + } + else + return this.stmt.count_locals (true); +} + +/* While. */ + +function JSC$stmt_while (ln, expr, stmt) +{ + this.stype = JSC$STMT_WHILE; + this.linenum = ln; + this.expr = expr; + this.stmt = stmt; + this.asm = JSC$stmt_while_asm; + this.count_locals = JSC$stmt_while_count_locals; +} + +function JSC$stmt_while_asm () +{ + var l1 = new JSC$ASM_label (); + var l2 = new JSC$ASM_label (); + + /* Loop label. */ + l1.link (); + + /* Condition. */ + this.expr.asm (); + if (JSC$optimize_type && this.expr.lang_type + && this.expr.lang_type == JSC$JS_BOOLEAN) + new JSC$ASM_iffalse_b (this.linenum, l2).link (); + else + new JSC$ASM_iffalse (this.linenum, l2).link (); + + /* Body. */ + JSC$cont_break.push (l2, l1, false, null); + this.stmt.asm (); + JSC$cont_break.pop (); + + /* Goto loop. */ + new JSC$ASM_jmp (this.linenum, l1).link (); + + /* Break label. */ + l2.link (); +} + + +function JSC$stmt_while_count_locals (recursive) +{ + if (!recursive) + { + if (this.stmt.stype == JSC$STMT_VARIABLE) + return this.stmt.list.length; + + return 0; + } + else + return this.stmt.count_locals (true); +} + + +/* For. */ + +function JSC$stmt_for (ln, vars, e1, e2, e3, stmt) +{ + this.stype = JSC$STMT_FOR; + this.linenum = ln; + this.vars = vars; + this.expr1 = e1; + this.expr2 = e2; + this.expr3 = e3; + this.stmt = stmt; + this.asm = JSC$stmt_for_asm; + this.count_locals = JSC$stmt_for_count_locals; +} + +function JSC$stmt_for_asm () +{ + /* Code for the init. */ + if (this.vars) + { + /* We have our own variable scope. */ + JSC$ns.push_frame (); + + var i; + for (i = 0; i < this.vars.length; i++) + { + var decl = this.vars[i]; + + JSC$ns.define_symbol (decl.id, JSC$SCOPE_LOCAL, + JSC$ns.alloc_local (), this.linenum); + + /* Possible init. */ + if (decl.expr) + { + decl.expr.asm (); + + var r = JSC$ns.lookup_symbol (decl.id); + if (r == null || r.scope != JSC$SCOPE_LOCAL) + error (JSC$filename + ":" + this.liennum.toString () + + ": internal compiler error in local variable " + + "declaration in for statement"); + + new JSC$ASM_store_local (this.linenum, r.value).link (); + } + } + } + else if (this.expr1 != null) + { + this.expr1.asm (); + new JSC$ASM_pop (this.linenum).link (); + } + + var l1 = new JSC$ASM_label (); + var l2 = new JSC$ASM_label (); + var l3 = new JSC$ASM_label (); + + /* Loop label. */ + l1.link (); + + /* Condition. */ + var type_op = false; + if (this.expr2 != null) + { + this.expr2.asm (); + if (JSC$optimize_type && this.expr2.lang_type + && this.expr2.lang_type == JSC$JS_BOOLEAN) + type_op = true; + } + else + { + new JSC$ASM_const_true (this.linenum).link (); + type_op = JSC$optimize_type; + } + if (type_op) + new JSC$ASM_iffalse_b (this.linenum, l3).link (); + else + new JSC$ASM_iffalse (this.linenum, l3).link (); + + JSC$cont_break.push (l3, l2, false, null); + /* Body. */ + this.stmt.asm (); + JSC$cont_break.pop (); + + /* Continue label. */ + l2.link (); + + /* Increment. */ + if (this.expr3 != null) + { + this.expr3.asm (); + new JSC$ASM_pop (this.linenum).link (); + } + + /* Goto loop. */ + new JSC$ASM_jmp (this.linenum, l1).link (); + + /* Break label. */ + l3.link (); + + if (this.vars) + /* Pop the local variable scope. */ + JSC$ns.pop_frame (); +} + + +function JSC$stmt_for_count_locals (recursive) +{ + var count = 0; + + if (recursive) + { + if (this.vars) + count += this.vars.length; + + count += this.stmt.count_locals (true); + } + else + { + if (this.stmt.stype == JSC$STMT_VARIABLE) + count += this.stmt.list.length; + } + + return count; +} + + +/* For...in. */ + +function JSC$stmt_for_in (ln, vars, e1, e2, stmt) +{ + this.stype = JSC$STMT_FOR_IN; + this.linenum = ln; + this.vars = vars; + this.expr1 = e1; + this.expr2 = e2; + this.stmt = stmt; + this.asm = JSC$stmt_for_in_asm; + this.count_locals = JSC$stmt_for_in_count_locals; +} + +function JSC$stmt_for_in_asm () +{ + var local_id; + + if (this.vars) + { + /* We need our own variable scope here. */ + JSC$ns.push_frame (); + + var decl = this.vars[0]; + local_id = JSC$ns.alloc_local (); + JSC$ns.define_symbol (decl.id, JSC$SCOPE_LOCAL, local_id, this.linenum); + + /* Possible init. */ + if (decl.expr) + { + decl.expr.asm (); + new JSC$ASM_store_local (this.linenum, local_id).link (); + } + } + + /* Init the world. */ + this.expr2.asm (); + new JSC$ASM_dup (this.linenum).link (); + new JSC$ASM_const_i0 (this.linenum).link (); + new JSC$ASM_swap (this.linenum).link (); + new JSC$ASM_const_i0 (this.linenum).link (); + + var l_loop = new JSC$ASM_label (); + var l_cont = new JSC$ASM_label (); + var l_iffalse_b = new JSC$ASM_label (); + var l_break = new JSC$ASM_label (); + + /* Loop label. */ + l_loop.link (); + + /* Fetch nth. */ + new JSC$ASM_nth (this.linenum).link (); + new JSC$ASM_iffalse_b (this.linenum, l_iffalse_b).link (); + + /* Store value to variable. */ + if (this.vars) + new JSC$ASM_store_local (this.linenum, local_id).link (); + else + JSC$asm_expr_lvalue_store_asm (this.expr1); + + /* Body. */ + JSC$cont_break.push (l_break, l_cont, false, null); + this.stmt.asm (); + JSC$cont_break.pop (); + + /* Continue label. */ + l_cont.link (); + + /* Increment. */ + new JSC$ASM_const_i1 (this.linenum).link (); + new JSC$ASM_add (this.linenum).link (); + new JSC$ASM_dup (this.linenum).link (); + new JSC$ASM_roll (this.linenum, -3).link (); + new JSC$ASM_dup (this.linenum).link (); + new JSC$ASM_roll (this.linenum, 4).link (); + new JSC$ASM_swap (this.linenum).link (); + + /* Goto loop. */ + new JSC$ASM_jmp (this.linenum, l_loop).link (); + + /* Out label. */ + l_iffalse_b.link (); + + new JSC$ASM_pop (this.linenum).link (); + + /* Break label. */ + l_break.link (); + new JSC$ASM_pop_n (this.linenum, 2).link (); + + if (this.vars) + /* Pop the variable scope. */ + JSC$ns.pop_frame (); +} + +function JSC$stmt_for_in_count_locals (recursive) +{ + var count = 0; + + if (recursive) + { + if (this.vars) + count++; + + count += this.stmt.count_locals (true); + } + else + { + if (this.stmt.stype == JSC$STMT_VARIABLE) + count += this.stmt.list.length; + + } + + return count; +} + + +/* Variable. */ + +function JSC$stmt_variable (ln, list) +{ + this.stype = JSC$STMT_VARIABLE; + this.linenum = ln; + this.global_level = false; + this.list = list; + this.asm = JSC$stmt_variable_asm; + this.count_locals = JSC$stmt_variable_count_locals; +} + +function JSC$stmt_variable_asm () +{ + var j, r; + + /* Define all local variables to our namespace. */ + for (j = 0; j < this.list.length; j++) + { + var i = this.list[j]; + + if (!this.global_level) + JSC$ns.define_symbol (i.id, JSC$SCOPE_LOCAL, + JSC$ns.alloc_local (), this.linenum); + if (i.expr) + { + i.expr.asm (); + + if (this.global_level) + new JSC$ASM_store_global (this.linenum, i.id).link (); + else + { + r = JSC$ns.lookup_symbol (i.id); + if (r == null || r.scope != JSC$SCOPE_LOCAL) + error (JSC$filename + ":" + this.linenum.toString() + + ": internal compiler error in local variable declaration"); + + new JSC$ASM_store_local (this.linenum, r.value).link (); + } + } + } +} + +function JSC$stmt_variable_count_locals (recursive) +{ + if (!recursive) + { + if (this.global_level) + /* We define these as global variables. */ + return 0; + + return this.list.length; + } + + return 0; +} + +function JSC$var_declaration (id, expr) +{ + this.id = id; + this.expr = expr; +} + + +/* + * Expressions. + */ + +/* This. */ + +function JSC$expr_this (ln) +{ + this.etype = JSC$EXPR_THIS; + this.linenum = ln; + this.asm = JSC$expr_this_asm; +} + +function JSC$expr_this_asm () +{ + new JSC$ASM_load_arg (this.linenum, 0).link (); +} + +/* Identifier. */ + +function JSC$expr_identifier (ln, value) +{ + this.etype = JSC$EXPR_IDENTIFIER; + this.linenum = ln; + this.value = value; + this.asm = JSC$expr_identifier_asm; +} + +function JSC$expr_identifier_asm () +{ + JSC$asm_expr_lvalue_load_asm (this); +} + +/* Float. */ + +function JSC$expr_float (ln, value) +{ + this.etype = JSC$EXPR_FLOAT; + this.lang_type = JSC$JS_FLOAT; + this.linenum = ln; + this.value = value; + this.asm = JSC$expr_float_asm; +} + +function JSC$expr_float_asm () +{ + new JSC$ASM_const (this.linenum, this.value).link (); +} + +/* Integer. */ + +function JSC$expr_integer (ln, value) +{ + this.etype = JSC$EXPR_INTEGER; + this.lang_type = JSC$JS_INTEGER; + this.linenum = ln; + this.value = value; + this.asm = JSC$expr_integer_asm; +} + +function JSC$expr_integer_asm () +{ + if (this.value == 0) + new JSC$ASM_const_i0 (this.linenum).link (); + else if (this.value == 1) + new JSC$ASM_const_i1 (this.linenum).link (); + else if (this.value == 2) + new JSC$ASM_const_i2 (this.linenum).link (); + else if (this.value == 3) + new JSC$ASM_const_i3 (this.linenum).link (); + else + new JSC$ASM_const_i (this.linenum, this.value).link (); +} + +/* String. */ + +function JSC$expr_string (ln, value) +{ + this.etype = JSC$EXPR_STRING; + this.lang_type = JSC$JS_STRING; + this.linenum = ln; + this.value = value; + this.asm = JSC$expr_string_asm; +} + +function JSC$expr_string_asm () +{ + new JSC$ASM_const (this.linenum, this.value).link (); +} + +/* Regexp. */ + +function JSC$expr_regexp (ln, value) +{ + this.etype = JSC$EXPR_REGEXP; + this.lang_type = JSC$JS_BUILTIN; + this.linenum = ln; + this.value = value; + this.asm = JSC$expr_regexp_asm; +} + +function JSC$expr_regexp_asm () +{ + new JSC$ASM_const (this.linenum, this.value).link (); +} + +/* Array initializer. */ + +function JSC$expr_array_initializer (ln, items) +{ + this.etype = JSC$EXPR_ARRAY_INITIALIZER; + this.lang_type = JSC$JS_ARRAY; + this.linenum = ln; + this.items = items; + this.asm = JSC$expr_array_initializer_asm; +} + +function JSC$expr_array_initializer_asm () +{ + /* Generate assembler for the individual items. */ + + var i; + for (i = this.items.length - 1; i >= 0; i--) + { + if (this.items[i]) + this.items[i].asm (); + else + new JSC$ASM_const_undefined (this.linenum).link (); + } + + /* + * The number of items as a negative integer. The Array object's + * constructor knows that if the number of arguments is negative, it + * is called from the array initializer. Why? Because the code: + * + * new Array (5); + * + * creates an array of length of 5, but code: + * + * [5] + * + * creates an array with one item: integer number five. These cases + * must be separatable from the code and that's why the argument + * counts for the array initializers are negative. + */ + new JSC$ASM_const (this.linenum, -this.items.length).link (); + + /* Call the constructor. */ + new JSC$ASM_load_global (this.linenum, "Array").link (); + new JSC$ASM_new (this.linenum).link (); + new JSC$ASM_swap (this.linenum).link (); + new JSC$ASM_apop (this.linenum, this.items.length + 2).link (); +} + +/* Object initializer. */ + +function JSC$expr_object_initializer (ln, items) +{ + this.etype = JSC$EXPR_OBJECT_INITIALIZER; + this.lang_type = JSC$JS_OBJECT; + this.linenum = ln; + this.items = items; + this.asm = JSC$expr_object_initializer_asm; +} + +function JSC$expr_object_initializer_asm () +{ + /* Create a new object. */ + new JSC$ASM_const_i0 (this.linenum).link (); + new JSC$ASM_load_global (this.linenum, "Object").link (); + new JSC$ASM_new (this.linenum).link (); + new JSC$ASM_swap (this.linenum).link (); + new JSC$ASM_apop (this.linenum, 2).link (); + + /* Insert the items. */ + for (var i = 0; i < this.items.length; i++) + { + var item = this.items[i]; + + new JSC$ASM_dup (item.linenum).link (); + item.expr.asm (); + new JSC$ASM_swap (item.linenum).link (); + + switch (item.id_type) + { + case JSC$tIDENTIFIER: + new JSC$ASM_store_property (item.linenum, item.id).link (); + break; + + case JSC$tSTRING: + new JSC$ASM_const (item.linenum, item.id).link (); + new JSC$ASM_store_array (item.linenum).link (); + break; + + case JSC$tINTEGER: + switch (item.id) + { + case 0: + new JSC$ASM_const_i0 (item.linenum).link (); + break; + + case 1: + new JSC$ASM_const_i1 (item.linenum).link (); + break; + + case 2: + new JSC$ASM_const_i2 (item.linenum).link (); + break; + + case 3: + new JSC$ASM_const_i3 (item.linenum).link (); + break; + + default: + new JSC$ASM_const_i (item.linenum, item.id).link (); + break; + } + new JSC$ASM_store_array (item.linenum).link (); + break; + } + } +} + + +/* Null. */ + +function JSC$expr_null (ln) +{ + this.etype = JSC$EXPR_NULL; + this.lang_type = JSC$JS_NULL; + this.linenum = ln; + this.asm = JSC$expr_null_asm; +} + +function JSC$expr_null_asm () +{ + new JSC$ASM_const_null (this.linenum).link (); +} + +/* True. */ + +function JSC$expr_true (ln) +{ + this.etype = JSC$EXPR_TRUE; + this.lang_type = JSC$JS_BOOLEAN; + this.linenum = ln; + this.asm = JSC$expr_true_asm; +} + +function JSC$expr_true_asm () +{ + new JSC$ASM_const_true (this.linenum).link (); +} + +/* False. */ + +function JSC$expr_false (ln) +{ + this.etype = JSC$EXPR_FALSE; + this.lang_type = JSC$JS_BOOLEAN; + this.linenum = ln; + this.asm = JSC$expr_false_asm; +} + +function JSC$expr_false_asm () +{ + new JSC$ASM_const_false (this.linenum).link (); +} + + +/* Multiplicative expr. */ + +function JSC$expr_multiplicative (ln, type, e1, e2) +{ + this.etype = JSC$EXPR_MULTIPLICATIVE; + this.linenum = ln; + this.type = type; + this.e1 = e1; + this.e2 = e2; + this.asm = JSC$expr_multiplicative_asm; +} + +function JSC$expr_multiplicative_asm () +{ + this.e1.asm (); + this.e2.asm (); + if (this.type == #'*') + new JSC$ASM_mul (this.linenum).link (); + else if (this.type == #'/') + new JSC$ASM_div (this.linenum).link (); + else + new JSC$ASM_mod (this.linenum).link (); +} + + +/* Additive expr. */ + +function JSC$expr_additive (ln, type, e1, e2) +{ + this.etype = JSC$EXPR_ADDITIVE; + this.linenum = ln; + this.type = type; + this.e1 = e1; + this.e2 = e2; + this.asm = JSC$expr_additive_asm; + this.constant_folding = JSC$expr_additive_constant_folding; +} + +function JSC$expr_additive_asm () +{ + this.e1.asm (); + this.e2.asm (); + if (this.type == #'+') + new JSC$ASM_add (this.linenum).link (); + else + new JSC$ASM_sub (this.linenum).link (); +} + +function JSC$expr_additive_constant_folding () +{ + if (this.e1.constant_folding) + this.e1 = this.e1.constant_folding (); + if (this.e2.constant_folding) + this.e2 = this.e2.constant_folding (); + + /* This could be smarter. */ + if (this.e1.lang_type && this.e2.lang_type + && this.e1.lang_type == this.e2.lang_type) + { + switch (this.e1.lang_type) + { + case JSC$JS_INTEGER: + return new JSC$expr_integer (this.linenum, + this.type == #'+' + ? this.e1.value + this.e2.value + : this.e1.value - this.e2.value); + break; + + case JSC$JS_FLOAT: + return new JSC$expr_float (this.linenum, + this.type == #'+' + ? this.e1.value + this.e2.value + : this.e1.value - this.e2.value); + break; + + case JSC$JS_STRING: + if (this.type == #'+') + /* Only the addition is available for the strings. */ + return new JSC$expr_string (this.linenum, + this.e1.value + this.e2.value); + break; + + default: + /* FALLTHROUGH */ + break; + } + } + + return this; +} + +/* Shift expr. */ + +function JSC$expr_shift (ln, type, e1, e2) +{ + this.etype = JSC$EXPR_SHIFT; + this.linenum = ln; + this.type = type; + this.e1 = e1; + this.e2 = e2; + this.asm = JSC$expr_shift_asm; +} + +function JSC$expr_shift_asm () +{ + this.e1.asm (); + this.e2.asm (); + + if (this.type == JSC$tLSHIFT) + new JSC$ASM_shift_left (this.linenum).link (); + else if (this.type == JSC$tRSHIFT) + new JSC$ASM_shift_right (this.linenum).link (); + else + new JSC$ASM_shift_rright (this.linenum).link (); +} + + +/* Relational expr. */ + +function JSC$expr_relational (ln, type, e1, e2) +{ + this.etype = JSC$EXPR_RELATIONAL; + this.lang_type = JSC$JS_BOOLEAN; + this.linenum = ln; + this.type = type; + this.e1 = e1; + this.e2 = e2; + this.asm = JSC$expr_relational_asm; +} + +function JSC$expr_relational_asm () +{ + this.e1.asm (); + this.e2.asm (); + + if (this.type == #'<') + new JSC$ASM_cmp_lt (this.linenum).link (); + else if (this.type == #'>') + new JSC$ASM_cmp_gt (this.linenum).link (); + else if (this.type == JSC$tLE) + new JSC$ASM_cmp_le (this.linenum).link (); + else + new JSC$ASM_cmp_ge (this.linenum).link (); +} + + +/* Equality expr. */ + +function JSC$expr_equality (ln, type, e1, e2) +{ + this.etype = JSC$EXPR_EQUALITY; + this.lang_type = JSC$JS_BOOLEAN; + this.linenum = ln; + this.type = type; + this.e1 = e1; + this.e2 = e2; + this.asm = JSC$expr_equality_asm; +} + +function JSC$expr_equality_asm () +{ + this.e1.asm (); + this.e2.asm (); + + switch (this.type) + { + case JSC$tEQUAL: + new JSC$ASM_cmp_eq (this.linenum).link (); + break; + + case JSC$tNEQUAL: + new JSC$ASM_cmp_ne (this.linenum).link (); + break; + + case JSC$tSEQUAL: + new JSC$ASM_cmp_seq (this.linenum).link (); + break; + + case JSC$tSNEQUAL: + new JSC$ASM_cmp_sne (this.linenum).link (); + break; + + default: + error ("jsc: expr_equality: internal compiler error"); + break; + } +} + + +/* Bitwise and expr. */ + +function JSC$expr_bitwise_and (ln, e1, e2) +{ + this.etype = JSC$EXPR_BITWISE; + this.linenum = ln; + this.e1 = e1; + this.e2 = e2; + this.asm = JSC$expr_bitwise_and_asm; +} + +function JSC$expr_bitwise_and_asm () +{ + this.e1.asm (); + this.e2.asm (); + + new JSC$ASM_and (this.linenum).link (); +} + + +/* Bitwise or expr. */ + +function JSC$expr_bitwise_or (ln, e1, e2) +{ + this.etype = JSC$EXPR_BITWISE; + this.linenum = ln; + this.e1 = e1; + this.e2 = e2; + this.asm = JSC$expr_bitwise_or_asm; +} + +function JSC$expr_bitwise_or_asm () +{ + this.e1.asm (); + this.e2.asm (); + + new JSC$ASM_or (this.linenum).link (); +} + + +/* Bitwise xor expr. */ + +function JSC$expr_bitwise_xor (ln, e1, e2) +{ + this.etype = JSC$EXPR_BITWISE; + this.linenum = ln; + this.e1 = e1; + this.e2 = e2; + this.asm = JSC$expr_bitwise_xor_asm; +} + +function JSC$expr_bitwise_xor_asm () +{ + this.e1.asm (); + this.e2.asm (); + + new JSC$ASM_xor (this.linenum).link (); +} + + +/* Logical and expr. */ + +function JSC$expr_logical_and (ln, e1, e2) +{ + this.etype = JSC$EXPR_LOGICAL; + + if (e1.lang_type && e2.lang_type + && e1.lang_type == JSC$JS_BOOLEAN && e2.lang_type == JSC$JS_BOOLEAN) + this.lang_type = JSC$JS_BOOLEAN; + + this.linenum = ln; + this.e1 = e1; + this.e2 = e2; + this.asm = JSC$expr_logical_and_asm; +} + +function JSC$expr_logical_and_asm () +{ + this.e1.asm (); + + var l = new JSC$ASM_label (); + new JSC$ASM_dup (this.linenum).link (); + + if (JSC$optimize_type && this.e1.lang_type + && this.e1.lang_type == JSC$JS_BOOLEAN) + new JSC$ASM_iffalse_b (this.linenum, l).link (); + else + new JSC$ASM_iffalse (this.linenum, l).link (); + + new JSC$ASM_pop (this.linenum).link (); + + this.e2.asm (); + + /* Done label. */ + l.link (); +} + + +/* Logical or expr. */ + +function JSC$expr_logical_or (ln, e1, e2) +{ + this.etype = JSC$EXPR_LOGICAL; + + if (e1.lang_type && e2.lang_type + && e1.lang_type == JSC$JS_BOOLEAN && e2.lang_type == JSC$JS_BOOLEAN) + this.lang_type = JSC$JS_BOOLEAN; + + this.linenum = ln; + this.e1 = e1; + this.e2 = e2; + this.asm = JSC$expr_logical_or_asm; +} + +function JSC$expr_logical_or_asm () +{ + this.e1.asm (); + + var l = new JSC$ASM_label (); + new JSC$ASM_dup (this.linenum).link (); + + if (JSC$optimize_type && this.e1.lang_type + && this.e1.lang_type == JSC$JS_BOOLEAN) + new JSC$ASM_iftrue_b (this.linenum, l).link (); + else + new JSC$ASM_iftrue (this.linenum, l).link (); + + new JSC$ASM_pop (this.linenum).link (); + + this.e2.asm (); + + /* Done label. */ + l.link (); +} + + +/* New expr. */ + +function JSC$expr_new (ln, expr, args) +{ + this.etype = JSC$EXPR_NEW; + this.linenum = ln; + this.expr = expr; + this.args = args; + this.asm = JSC$expr_new_asm; +} + +function JSC$expr_new_asm () +{ + var i; + + if (this.args) + { + /* Code for the arguments. */ + for (i = this.args.length - 1; i >= 0; i--) + this.args[i].asm (); + + if (this.args.length == 0) + new JSC$ASM_const_i0 (this.linenum).link (); + else if (this.args.length == 1) + new JSC$ASM_const_i1 (this.linenum).link (); + else if (this.args.length == 2) + new JSC$ASM_const_i2 (this.linenum).link (); + else if (this.args.length == 3) + new JSC$ASM_const_i3 (this.linenum).link (); + else + new JSC$ASM_const (this.linenum, this.args.length).link (); + } + else + { + /* A `new Foo' call. This is identical to `new Foo ()'. */ + new JSC$ASM_const_i0 (this.linenum).link (); + } + + /* Object. */ + this.expr.asm (); + + /* Call new. */ + new JSC$ASM_new (this.linenum).link (); + + /* Replace the constructor's return value with the object. */ + new JSC$ASM_swap (this.linenum).link (); + + /* Remove the arguments and return the new object. */ + new JSC$ASM_apop (this.linenum, + (this.args ? this.args.length : 0) + 2).link (); +} + + +/* Object property expr. */ + +function JSC$expr_object_property (ln, expr, id) +{ + this.etype = JSC$EXPR_OBJECT_PROPERTY; + this.linenum = ln; + this.expr = expr; + this.id = id; + this.asm = JSC$expr_object_property_asm; +} + +function JSC$expr_object_property_asm () +{ + JSC$asm_expr_lvalue_load_asm (this); +} + + +/* Object array expr. */ + +function JSC$expr_object_array (ln, expr1, expr2) +{ + this.etype = JSC$EXPR_OBJECT_ARRAY; + this.linenum = ln; + this.expr1 = expr1; + this.expr2 = expr2; + this.asm = JSC$expr_object_array_asm; +} + +function JSC$expr_object_array_asm () +{ + JSC$asm_expr_lvalue_load_asm (this); +} + + +/* Call. */ + +function JSC$expr_call (ln, expr, args) +{ + this.etype = JSC$EXPR_CALL; + this.linenum = ln; + this.expr = expr; + this.args = args; + this.asm = JSC$expr_call_asm; +} + +function JSC$expr_call_asm () +{ + var i; + + /* Code for the arguments. */ + for (i = this.args.length - 1; i >= 0; i--) + this.args[i].asm (); + + if (this.args.length == 0) + new JSC$ASM_const_i0 (this.linenum).link (); + else if (this.args.length == 1) + new JSC$ASM_const_i1 (this.linenum).link (); + else if (this.args.length == 2) + new JSC$ASM_const_i2 (this.linenum).link (); + else if (this.args.length == 3) + new JSC$ASM_const_i3 (this.linenum).link (); + else + new JSC$ASM_const (this.linenum, this.args.length).link (); + + /* Check the function type. */ + if (this.expr.etype == JSC$EXPR_IDENTIFIER) + { + /* The simple subroutine or global object method invocation. */ + + var saved_with_nesting = JSC$cont_break.top.with_nesting; + JSC$cont_break.top.with_nesting = 0; + + JSC$asm_expr_lvalue_load_asm (this.expr); + + JSC$cont_break.top.with_nesting = saved_with_nesting; + + if (JSC$cont_break.top.with_nesting > 0) + new JSC$ASM_jsr_w (this.linenum, this.expr.value).link (); + else + new JSC$ASM_jsr (this.linenum).link (); + + new JSC$ASM_apop (this.linenum, this.args.length + 2).link (); + } + else if (this.expr.etype == JSC$EXPR_OBJECT_PROPERTY) + { + /* Method invocation. */ + this.expr.expr.asm (); + new JSC$ASM_call_method (this.linenum, this.expr.id).link (); + new JSC$ASM_apop (this.linenum, this.args.length + 2).link (); + } + else + { + /* Something like a function pointer invocation. */ + JSC$asm_expr_lvalue_load_asm (this.expr); + new JSC$ASM_jsr (this.linenum).link (); + new JSC$ASM_apop (this.linenum, this.args.length + 2).link (); + } +} + + +/* Assignment. */ + +function JSC$expr_assignment (ln, type, expr1, expr2) +{ + this.etype = JSC$EXPR_ASSIGNMENT; + this.linenum = ln; + this.type = type; + this.expr1 = expr1; + this.expr2 = expr2; + this.asm = JSC$expr_assignment_asm; +} + +function JSC$expr_assignment_asm () +{ + if (this.type != #'=') + JSC$asm_expr_lvalue_load_asm (this.expr1); + + /* Count the rvalue. */ + this.expr2.asm (); + + if (this.type == #'=') + /* Nothing here. */ + ; + else if (this.type == JSC$tMULA) + new JSC$ASM_mul (this.linenum).link (); + else if (this.type == JSC$tDIVA) + new JSC$ASM_div (this.linenum).link (); + else if (this.type == JSC$tMODA) + new JSC$ASM_mod (this.linenum).link (); + else if (this.type == JSC$tADDA) + new JSC$ASM_add (this.linenum).link (); + else if (this.type == JSC$tSUBA) + new JSC$ASM_sub (this.linenum).link (); + else if (this.type == JSC$tLSIA) + new JSC$ASM_shift_left (this.linenum).link (); + else if (this.type == JSC$tRSIA) + new JSC$ASM_shift_right (this.linenum).link (); + else if (this.type == JSC$tRRSA) + new JSC$ASM_shift_rright (this.linenum).link (); + else if (this.type == JSC$tANDA) + new JSC$ASM_and (this.linenum).link (); + else if (this.type == JSC$tXORA) + new JSC$ASM_xor (this.linenum).link (); + else if (this.type == JSC$tORA) + new JSC$ASM_or (this.linenum).link (); + else + error (JSC$filename + ":" + this.linenum.toString () + + ": internal compiler error in assignment expression"); + + /* Duplicate the value. */ + new JSC$ASM_dup (this.linenum).link (); + + /* Store it to the lvalue. */ + JSC$asm_expr_lvalue_store_asm (this.expr1); +} + +function JSC$asm_expr_lvalue_load_asm (expr) +{ + var i; + + if (expr.etype == JSC$EXPR_IDENTIFIER) + { + /* Must check global / local / argument. */ + i = JSC$ns.lookup_symbol (expr.value); + if (i == null) + { + if (JSC$cont_break.top.with_nesting > 0) + new JSC$ASM_load_global_w (expr.linenum, expr.value).link (); + else + new JSC$ASM_load_global (expr.linenum, expr.value).link (); + } + else if (i.scope == JSC$SCOPE_ARG) + { + if (JSC$cont_break.top.with_nesting > 0 && JSC$warn_with_clobber) + JSC$warning (JSC$filename + ":" + expr.linenum.toString () + + ": warning: the with-lookup of symbol `" + i.symbol + + "' is clobbered by the argument definition"); + + new JSC$ASM_load_arg (expr.linenum, i.value).link (); + } + else + { + if (JSC$cont_break.top.with_nesting > 0 && JSC$warn_with_clobber) + JSC$warning (JSC$filename + ":" + expr.linenum.toString () + + ": warning: the with-lookup of symbol `" + i.symbol + + "' is clobbered by the local variable definition"); + + new JSC$ASM_load_local (expr.linenum, i.value).link (); + } + } + else if (expr.etype == JSC$EXPR_OBJECT_PROPERTY) + { + expr.expr.asm (); + new JSC$ASM_load_property (expr.linenum, expr.id).link (); + } + else if (expr.etype == JSC$EXPR_OBJECT_ARRAY) + { + expr.expr1.asm (); + expr.expr2.asm (); + new JSC$ASM_load_array (expr.linenum).link (); + } + else + error (JSC$filename + ":" + expr.linenum.toString () + ": syntax error"); +} + +function JSC$asm_expr_lvalue_store_asm (expr) +{ + var i; + + if (expr.etype == JSC$EXPR_IDENTIFIER) + { + i = JSC$ns.lookup_symbol (expr.value); + if (i == null) + new JSC$ASM_store_global (expr.linenum, expr.value).link (); + else if (i.scope == JSC$SCOPE_ARG) + new JSC$ASM_store_arg (expr.linenum, i.value).link (); + else + new JSC$ASM_store_local (expr.linenum, i.value).link (); + } + else if (expr.etype == JSC$EXPR_OBJECT_PROPERTY) + { + expr.expr.asm (); + new JSC$ASM_store_property (expr.linenum, expr.id).link (); + } + else if (expr.etype == JSC$EXPR_OBJECT_ARRAY) + { + expr.expr1.asm (); + expr.expr2.asm (); + new JSC$ASM_store_array (expr.linenum).link (); + } + else + error (JSC$filename + ":" + expr.linenum.toString () + ": syntax error"); +} + + +/* Quest colon. */ + +function JSC$expr_quest_colon (ln, e1, e2, e3) +{ + this.etype = JSC$EXPR_QUEST_COLON; + this.linenum = ln; + this.e1 = e1; + this.e2 = e2; + this.e3 = e3; + this.asm = JSC$expr_quest_colon_asm; +} + +function JSC$expr_quest_colon_asm() +{ + /* Code for the condition. */ + this.e1.asm (); + + var l1 = new JSC$ASM_label (); + var l2 = new JSC$ASM_label (); + + if (JSC$optimize_type && this.e1.lang_type + && this.e1.lang_type == JSC$JS_BOOLEAN) + new JSC$ASM_iffalse_b (this.linenum, l1).link (); + else + new JSC$ASM_iffalse (this.linenum, l1).link (); + + /* Code for the true branch. */ + this.e2.asm (); + new JSC$ASM_jmp (this.linenum, l2).link (); + + /* Code for the false branch. */ + l1.link (); + this.e3.asm (); + + /* Done label. */ + l2.link (); +} + + +/* Unary. */ + +function JSC$expr_unary (ln, type, expr) +{ + this.etype = JSC$EXPR_UNARY; + this.linenum = ln; + this.type = type; + this.expr = expr; + this.asm = JSC$expr_unary_asm; +} + +function JSC$expr_unary_asm () +{ + if (this.type == #'!') + { + this.expr.asm (); + new JSC$ASM_not (this.linenum).link (); + } + else if (this.type == #'+') + { + this.expr.asm (); + /* Nothing here. */ + } + else if (this.type == #'~') + { + this.expr.asm (); + new JSC$ASM_const (this.linenum, -1).link (); + new JSC$ASM_xor (this.linenum).link (); + } + else if (this.type == #'-') + { + this.expr.asm (); + new JSC$ASM_neg (this.linenum).link (); + } + else if (this.type == JSC$tDELETE) + { + if (this.expr.etype == JSC$EXPR_OBJECT_PROPERTY) + { + this.expr.expr.asm (); + new JSC$ASM_delete_property (this.linenum, this.expr.id).link (); + } + else if (this.expr.etype == JSC$EXPR_OBJECT_ARRAY) + { + this.expr.expr1.asm (); + this.expr.expr2.asm (); + new JSC$ASM_delete_array (this.linenum).link (); + } + else if (this.expr.etype == JSC$EXPR_IDENTIFIER) + { + if (JSC$cont_break.top.with_nesting == 0) + error (JSC$filename + ":" + this.linenum.toString () + + ": `delete property' called outside of a with-block"); + + new JSC$ASM_const_null (this.linenum).link (); + new JSC$ASM_delete_property (this.linenum, this.expr.value).link (); + } + else + error (JSC$filename + ":" + this.linenum.toString () + + ": illegal target for the delete operand"); + } + else if (this.type == JSC$tVOID) + { + this.expr.asm (); + new JSC$ASM_pop (this.linenum).link (); + new JSC$ASM_const_undefined (this.linenum).link (); + } + else if (this.type == JSC$tTYPEOF) + { + this.expr.asm (); + new JSC$ASM_typeof (this.linenum).link (); + } + else if (this.type == JSC$tPLUSPLUS + || this.type == JSC$tMINUSMINUS) + { + /* Fetch the old value. */ + JSC$asm_expr_lvalue_load_asm (this.expr); + + /* Do the operation. */ + new JSC$ASM_const_i1 (this.linenum).link (); + if (this.type == JSC$tPLUSPLUS) + new JSC$ASM_add (this.linenum).link (); + else + new JSC$ASM_sub (this.linenum).link (); + + /* Duplicate the value and store one copy pack to lvalue. */ + new JSC$ASM_dup (this.linenum).link (); + JSC$asm_expr_lvalue_store_asm (this.expr); + } + else + { + error ("jsc: internal error: unary expr's type is " + + this.type.toString ()); + } +} + + +/* Postfix. */ + +function JSC$expr_postfix (ln, type, expr) +{ + this.etype = JSC$EXPR_POSTFIX; + this.linenum = ln; + this.type = type; + this.expr = expr; + this.asm = JSC$expr_postfix_asm; +} + +function JSC$expr_postfix_asm () +{ + /* Fetch the old value. */ + JSC$asm_expr_lvalue_load_asm (this.expr); + + /* Duplicate the value since it is the expression's value. */ + new JSC$ASM_dup (this.linenum).link (); + + /* Do the operation. */ + new JSC$ASM_const_i1 (this.linenum).link (); + if (this.type == JSC$tPLUSPLUS) + new JSC$ASM_add (this.linenum).link (); + else + new JSC$ASM_sub (this.linenum).link (); + + /* And finally, store it back. */ + JSC$asm_expr_lvalue_store_asm (this.expr); +} + + +/* Postfix. */ + +function JSC$expr_comma (ln, expr1, expr2) +{ + this.etype = JSC$EXPR_COMMA; + this.linenum = ln; + this.expr1 = expr1; + this.expr2 = expr2; + this.asm = JSC$expr_comma_asm; +} + +function JSC$expr_comma_asm () +{ + this.expr1.asm (); + new JSC$ASM_pop (this.linenum).link (); + this.expr2.asm (); +} + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/jsc/lexer.js b/reactos/lib/kjs/jsc/lexer.js new file mode 100644 index 00000000000..d7c7bbbc2f1 --- /dev/null +++ b/reactos/lib/kjs/jsc/lexer.js @@ -0,0 +1,824 @@ +/* + * Lexer. + * Copyright (c) 1998-1999 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsc/lexer.js,v $ + * $Id: lexer.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * Global functions. + */ + +function JSC$lexer (stream) +{ + var ch, ch2; + + JSC$token_value = null; + + while ((ch = stream.readByte ()) != -1) + { + if (ch == #'\n') + { + JSC$linenum++; + continue; + } + + if (JSC$lexer_is_white_space (ch)) + continue; + + JSC$token_linenum = JSC$linenum; + + if (ch == #'/' && JSC$lexer_peek_char (stream) == #'*') + { + /* Multi line comment. */ + stream.readByte (); + while ((ch = stream.readByte ()) != -1 + && (ch != #'*' || JSC$lexer_peek_char (stream) != #'/')) + if (ch == #'\n') + JSC$linenum++; + + /* Consume the peeked #'/' character. */ + stream.readByte (); + } + else if ((ch == #'/' && JSC$lexer_peek_char (stream) == #'/') + || (ch == #'#' && JSC$lexer_peek_char (stream) == #'!')) + { + /* Single line comment. */ + while ((ch = stream.readByte ()) != -1 && ch != #'\n') + ; + if (ch == #'\n') + JSC$linenum++; + } + else if (ch == #'"' || ch == #'\'') + { + /* String constant. */ + JSC$token_value = JSC$lexer_read_string (stream, "string", ch); + return JSC$tSTRING; + } + + /* Literals. */ + else if (ch == #'=' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + if (JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tSEQUAL; + } + return JSC$tEQUAL; + } + else if (ch == #'!' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + if (JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tSNEQUAL; + } + return JSC$tNEQUAL; + } + else if (ch == #'<' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tLE; + } + else if (ch == #'>' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tGE; + } + else if (ch == #'&' && JSC$lexer_peek_char (stream) == #'&') + { + stream.readByte (); + return JSC$tAND; + } + else if (ch == #'|' && JSC$lexer_peek_char (stream) == #'|') + { + stream.readByte (); + return JSC$tOR; + } + else if (ch == #'+' && JSC$lexer_peek_char (stream) == #'+') + { + stream.readByte (); + return JSC$tPLUSPLUS; + } + else if (ch == #'-' && JSC$lexer_peek_char (stream) == #'-') + { + stream.readByte (); + return JSC$tMINUSMINUS; + } + else if (ch == #'*' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tMULA; + } + else if (ch == #'/' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tDIVA; + } + else if (ch == #'%' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tMODA; + } + else if (ch == #'+' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tADDA; + } + else if (ch == #'-' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tSUBA; + } + else if (ch == #'&' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tANDA; + } + else if (ch == #'^' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tXORA; + } + else if (ch == #'|' && JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tORA; + } + else if (ch == #'<' && JSC$lexer_peek_char (stream) == #'<') + { + stream.readByte (); + if (JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tLSIA; + } + else + return JSC$tLSHIFT; + } + else if (ch == #'>' && JSC$lexer_peek_char (stream) == #'>') + { + stream.readByte (); + ch2 = JSC$lexer_peek_char (stream); + if (ch2 == #'=') + { + stream.readByte (); + return JSC$tRSIA; + } + else if (ch2 == #'>') + { + stream.readByte (); + if (JSC$lexer_peek_char (stream) == #'=') + { + stream.readByte (); + return JSC$tRRSA; + } + else + return JSC$tRRSHIFT; + } + else + return JSC$tRSHIFT; + } + + /* Identifiers and keywords. */ + else if (JSC$lexer_is_identifier_letter (ch)) + { + /* An identifier. */ + var id = String.fromCharCode (ch); + + while ((ch = stream.readByte ()) != -1 + && (JSC$lexer_is_identifier_letter (ch) + || JSC$lexer_is_decimal_digit (ch))) + id.append (File.byteToString (ch)); + stream.ungetByte (ch); + + /* Keywords. */ + if (id == "break") + return JSC$tBREAK; + else if (id == "continue") + return JSC$tCONTINUE; + else if (id == "delete") + return JSC$tDELETE; + else if (id == "else") + return JSC$tELSE; + else if (id == "for") + return JSC$tFOR; + else if (id == "function") + return JSC$tFUNCTION; + else if (id == "if") + return JSC$tIF; + else if (id == "in") + return JSC$tIN; + else if (id == "new") + return JSC$tNEW; + else if (id == "return") + return JSC$tRETURN; + else if (id == "this") + return JSC$tTHIS; + else if (id == "typeof") + return JSC$tTYPEOF; + else if (id == "var") + return JSC$tVAR; + else if (id == "void") + return JSC$tVOID; + else if (id == "while") + return JSC$tWHILE; + else if (id == "with") + return JSC$tWITH; + + /* + * Future reserved keywords (some of these is already in use + * in this implementation). + */ + else if (id == "case") + return JSC$tCASE; + else if (id == "catch") + return JSC$tCATCH; + else if (id == "class") + return JSC$tCLASS; + else if (id == "const") + return JSC$tCONST; + else if (id == "debugger") + return JSC$tDEBUGGER; + else if (id == "default") + return JSC$tDEFAULT; + else if (id == "do") + return JSC$tDO; + else if (id == "enum") + return JSC$tENUM; + else if (id == "export") + return JSC$tEXPORT; + else if (id == "extends") + return JSC$tEXTENDS; + else if (id == "finally") + return JSC$tFINALLY; + else if (id == "import") + return JSC$tIMPORT; + else if (id == "super") + return JSC$tSUPER; + else if (id == "switch") + return JSC$tSWITCH; + else if (id == "throw") + return JSC$tTHROW; + else if (id == "try") + return JSC$tTRY; + + /* Null and boolean literals. */ + else if (id == "null") + return JSC$tNULL; + else if (id == "true") + return JSC$tTRUE; + else if (id == "false") + return JSC$tFALSE; + else + { + /* It really is an identifier. */ + JSC$token_value = id; + return JSC$tIDENTIFIER; + } + } + + /* Character constants. */ + else if (ch == #'#' && JSC$lexer_peek_char (stream) == #'\'') + { + /* Skip the starting #'\'' and read more. */ + stream.readByte (); + + ch = stream.readByte (); + if (ch == #'\\') + { + JSC$token_value + = JSC$lexer_read_backslash_escape (stream, 0, "character"); + + if (stream.readByte () != #'\'') + error (JSC$filename + ":" + JSC$linenum.toString () + + ": malformed character constant"); + } + else if (JSC$lexer_peek_char (stream) == #'\'') + { + stream.readByte (); + JSC$token_value = ch; + } + else + error (JSC$filename + ":" + JSC$linenum.toString () + + ": malformed character constant"); + + return JSC$tINTEGER; + } + + /* Octal and hex numbers. */ + else if (ch == #'0' + && JSC$lexer_peek_char (stream) != #'.' + && JSC$lexer_peek_char (stream) != #'e' + && JSC$lexer_peek_char (stream) != #'E') + { + JSC$token_value = 0; + ch = stream.readByte (); + if (ch == #'x' || ch == #'X') + { + ch = stream.readByte (); + while (JSC$lexer_is_hex_digit (ch)) + { + JSC$token_value *= 16; + JSC$token_value += JSC$lexer_hex_to_dec (ch); + ch = stream.readByte (); + } + stream.ungetByte (ch); + } + else + { + while (JSC$lexer_is_octal_digit (ch)) + { + JSC$token_value *= 8; + JSC$token_value += ch - #'0'; + ch = stream.readByte (); + } + stream.ungetByte (ch); + } + + return JSC$tINTEGER; + } + + /* Decimal numbers. */ + else if (JSC$lexer_is_decimal_digit (ch) + || (ch == #'.' + && JSC$lexer_is_decimal_digit ( + JSC$lexer_peek_char (stream)))) + { + var is_float = false; + var buf = new String (File.byteToString (ch)); + var accept_dot = true; + + if (ch == #'.') + { + /* + * We started with #'.' and we know that the next character + * is a decimal digit (we peeked it). + */ + is_float = true; + + ch = stream.readByte (); + while (JSC$lexer_is_decimal_digit (ch)) + { + buf.append (File.byteToString (ch)); + ch = stream.readByte (); + } + accept_dot = false; + } + else + { + /* We did start with a decimal digit. */ + ch = stream.readByte (); + while (JSC$lexer_is_decimal_digit (ch)) + { + buf.append (File.byteToString (ch)); + ch = stream.readByte (); + } + } + + if ((accept_dot && ch == #'.') + || ch == #'e' || ch == #'E') + { + is_float = true; + + if (ch == #'.') + { + buf.append (File.byteToString (ch)); + ch = stream.readByte (); + while (JSC$lexer_is_decimal_digit (ch)) + { + buf.append (File.byteToString (ch)); + ch = stream.readByte (); + } + } + + if (ch == #'e' || ch == #'E') + { + buf.append (File.byteToString (ch)); + ch = stream.readByte (); + if (ch == #'+' || ch == #'-') + { + buf.append (File.byteToString (ch)); + ch = stream.readByte (); + } + if (!JSC$lexer_is_decimal_digit (ch)) + error (JSC$filename + ":" + JSC$linenum.toString () + + ": malformed exponent part in a decimal literal"); + + while (JSC$lexer_is_decimal_digit (ch)) + { + buf.append (File.byteToString (ch)); + ch = stream.readByte (); + } + } + } + + /* Finally, we put the last character pack to the stream. */ + stream.ungetByte (ch); + + if (is_float) + { + JSC$token_value = parseFloat (buf); + return JSC$tFLOAT; + } + + JSC$token_value = parseInt (buf); + return JSC$tINTEGER; + } + + /* Just return the character as-is. */ + else + return ch; + } + + /* EOF reached. */ + return JSC$tEOF; +} + + +/* + * Help functions. + */ + +function JSC$lexer_peek_char (stream) +{ + var ch2 = stream.readByte (); + stream.ungetByte (ch2); + + return ch2; +} + + +function JSC$lexer_is_identifier_letter (ch) +{ + return ((#'a' <= ch && ch <= #'z') || (#'A' <= ch && ch <= #'Z') + || ch == #'$' || ch == #'_'); +} + + +function JSC$lexer_is_octal_digit (ch) +{ + return (#'0' <= ch && ch <= #'7'); +} + + +function JSC$lexer_is_decimal_digit (ch) +{ + return #'0' <= ch && ch <= #'9'; +} + + +function JSC$lexer_is_hex_digit (ch) +{ + return ((#'0' <= ch && ch <= #'9') + || (#'a' <= ch && ch <= #'f') + || (#'A' <= ch && ch <= #'F')); +} + + +function JSC$lexer_is_white_space (ch) +{ + return (ch == #' ' || ch == #'\t' || ch == #'\v' || ch == #'\r' + || ch == #'\f' || ch == #'\n'); +} + + +function JSC$lexer_hex_to_dec (ch) +{ + return ((#'0' <= ch && ch <= #'9') + ? ch - #'0' + : ((#'a' <= ch && ch <= #'f') + ? 10 + ch - #'a' + : 10 + ch - #'A')); +} + + +function JSC$lexer_read_backslash_escape (stream, possible_start, name) +{ + var ch = stream.readByte (); + + if (ch == #'n') + ch = #'\n'; + else if (ch == #'t') + ch = #'\t'; + else if (ch == #'v') + ch = #'\v'; + else if (ch == #'b') + ch = #'\b'; + else if (ch == #'r') + ch = #'\r'; + else if (ch == #'f') + ch = #'\f'; + else if (ch == #'a') + ch = #'\a'; + else if (ch == #'\\') + ch = #'\\'; + else if (ch == #'?') + ch = #'?'; + else if (ch == #'\'') + ch = #'\''; + else if (ch == #'"') + ch = #'"'; + else if (ch == #'x') + { + /* HexEscapeSequence. */ + var c1, c2; + + c1 = stream.readByte (); + c2 = stream.readByte (); + + if (c1 == -1 || c2 == -1) + JSC$lexer_eof_in_constant (possible_start, name); + + if (!JSC$lexer_is_hex_digit (c1) || !JSC$lexer_is_hex_digit (c2)) + error (JSC$filename + ":" + JSC$linenum.toString () + + ": \\x used with no following hex digits"); + + ch = (JSC$lexer_hex_to_dec (c1) << 4) + JSC$lexer_hex_to_dec (c2); + } + else if (ch == #'u') + { + /* UnicodeEscapeSequence. */ + var c1, c2, c3, c4; + + c1 = stream.readByte (); + c2 = stream.readByte (); + c3 = stream.readByte (); + c4 = stream.readByte (); + + if (c1 == -1 || c2 == -1 || c3 == -1 || c4 == -1) + JSC$lexer_eof_in_constant (possible_start, name); + + if (!JSC$lexer_is_hex_digit (c1) || !JSC$lexer_is_hex_digit (c2) + || !JSC$lexer_is_hex_digit (c3) || !JSC$lexer_is_hex_digit (c4)) + error (JSC$filename + ":" + JSC$linenum.toString () + + ": \\u used with no following hex digits"); + + ch = ((JSC$lexer_hex_to_dec (c1) << 12) + + (JSC$lexer_hex_to_dec (c2) << 8) + + (JSC$lexer_hex_to_dec (c3) << 4) + + JSC$lexer_hex_to_dec (c4)); + } + else if (JSC$lexer_is_octal_digit (ch)) + { + var result = ch - #'0'; + var i = 1; + + if (ch == #'0') + /* Allow three octal digits after '0'. */ + i = 0; + + ch = stream.readByte (); + while (i < 3 && JSC$lexer_is_octal_digit (ch)) + { + result *= 8; + result += ch - #'0'; + ch = stream.readByte (); + i++; + } + stream.ungetByte (ch); + ch = result; + } + else + { + if (ch == -1) + error (JSC$filename + ":" + JSC$linenum.toString () + + ": unterminated " + name); + + JSC$warning (JSC$filename + ":" + JSC$linenum.toString () + + ": warning: unknown escape sequence `\\" + + File.byteToString (ch) + "'"); + } + + return ch; +} + + +function JSC$lexer_read_string (stream, name, ender) +{ + var str = new String (""); + var done = false, ch; + var possible_start_ln = JSC$linenum; + var warned_line_terminator = false; + + while (!done) + { + ch = stream.readByte (); + if (ch == #'\n') + { + if (JSC$warn_strict_ecma && !warned_line_terminator) + { + JSC$warning (JSC$filename + ":" + JSC$linenum.toString () + + ": warning: ECMAScript don't allow line terminators in " + + name + " constants"); + warned_line_terminator = true; + } + JSC$linenum++; + } + + if (ch == -1) + JSC$lexer_eof_in_constant (possible_start_ln, name); + + else if (ch == ender) + done = true; + else + { + if (ch == #'\\') + { + if (JSC$lexer_peek_char (stream) == #'\n') + { + /* + * Backslash followed by a newline character. Ignore + * them both. + */ + stream.readByte (); + JSC$linenum++; + continue; + } + ch = JSC$lexer_read_backslash_escape (stream, possible_start_ln, + name); + } + str.append (ch); + } + } + + return str; +} + + +function JSC$lexer_read_regexp_constant (stream) +{ + /* Regexp literal. */ + var source = JSC$lexer_read_regexp_source (stream); + + /* Check the possible flags. */ + var flags = new String (""); + while ((ch = JSC$lexer_peek_char (stream)) == #'g' || ch == #'i') + { + stream.readByte (); + flags.append (File.byteToString (ch)); + } + + /* Try to compile it. */ + var msg = false; + var result; + try + { + result = new RegExp (source, flags); + } + catch (msg) + { + var start = msg.lastIndexOf (":"); + msg = (JSC$filename + ":" + JSC$token_linenum.toString () + + ": malformed regular expression constant:" + + msg.substr (start + 1)); + } + if (msg) + error (msg); + + /* Success. */ + + return result; +} + + +function JSC$lexer_read_regexp_source (stream) +{ + var str = new String (""); + var done = false, ch; + var possible_start_ln = JSC$linenum; + var warned_line_terminator = false; + var name = "regular expression"; + + while (!done) + { + ch = stream.readByte (); + if (ch == #'\n') + { + if (JSC$warn_strict_ecma && !warned_line_terminator) + { + JSC$warning (JSC$filename + ":" + JSC$linenum.toString () + + ": warning: ECMAScript don't allow line " + + "terminators in " + name + " constants"); + warned_line_terminator = true; + } + JSC$linenum++; + } + + if (ch == -1) + JSC$lexer_eof_in_constant (possible_start_ln, name); + + else if (ch == #'/') + done = true; + else + { + if (ch == #'\\') + { + ch = stream.readByte (); + if (ch == #'\n') + { + /* + * Backslash followed by a newline character. Ignore + * them both. + */ + JSC$linenum++; + continue; + } + if (ch == -1) + JSC$lexer_eof_in_constant (possible_start_ln, name); + + /* Handle the backslash escapes. */ + if (ch == #'f') + ch = #'\f'; + else if (ch == #'n') + ch = #'\n'; + else if (ch == #'r') + ch = #'\r'; + else if (ch == #'t') + ch = #'\t'; + else if (ch == #'v') + ch == #'\v'; + else if (ch == #'c') + { + /* SourceCharacter. */ + ch = stream.readByte (); + if (ch == -1) + JSC$lexer_eof_in_constant (possible_start_ln, name); + + if (ch == #'\n' && JSC$warn_strict_ecma) + JSC$warning (JSC$filename + ":" + JSC$linenum.toString () + + ": warning: ECMAScript don't allow line termiantor after \\c in regular expression constants"); + + /* + * Append the source-character escape start. The ch + * will be appended later. + */ + str.append ("\\c"); + } + else if (ch == #'u' || ch == #'x' || ch == #'0') + { + /* These can be handled with the read_backslash_escape(). */ + stream.ungetByte (ch); + ch = JSC$lexer_read_backslash_escape (stream); + } + else + { + /* + * Nothing special. Leave it to the result as-is. + * The regular expression backage will handle it. + */ + stream.ungetByte (ch); + ch = #'\\'; + } + } + str.append (File.byteToString (ch)); + } + } + + return str; +} + + +function JSC$lexer_eof_in_constant (possible_start, name) +{ + var msg = (JSC$filename + ":" + JSC$linenum.toString () + + ": unterminated " + name + " constant"); + + if (possible_start > 0) + msg += (System.lineBreakSequence + + JSC$filename + ":" + possible_start.toString () + + ": possible real start of unterminated " + name + " constant"); + + error (msg); +} + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/jsc/namespace.js b/reactos/lib/kjs/jsc/namespace.js new file mode 100644 index 00000000000..6d10df50adb --- /dev/null +++ b/reactos/lib/kjs/jsc/namespace.js @@ -0,0 +1,161 @@ +/* + * Namespace handling. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsc/namespace.js,v $ + * $Id: namespace.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * Global functions. + */ + +JSC$SCOPE_ARG = 1; +JSC$SCOPE_LOCAL = 2; + +function JSC$NameSpace () +{ + this.frame = new JSC$NameSpaceFrame (); + this.push_frame = JSC$NameSpace_push_frame; + this.pop_frame = JSC$NameSpace_pop_frame; + this.alloc_local = JSC$NameSpace_alloc_local; + this.define_symbol = JSC$NameSpace_define_symbol; + this.lookup_symbol = JSC$NameSpace_lookup_symbol; +} + + +function JSC$NameSpace_push_frame () +{ + var f = new JSC$NameSpaceFrame (); + + f.num_locals = this.frame.num_locals; + + f.next = this.frame; + this.frame = f; +} + + +function JSC$NameSpace_pop_frame () +{ + var i; + + for (i = this.frame.defs; i != null; i = i.next) + if (i.usecount == 0) + { + if (i.scope == JSC$SCOPE_ARG) + { + if (JSC$warn_unused_argument) + JSC$warning (JSC$filename + ":" + i.linenum.toString () + + ": warning: unused argument `" + i.symbol + "'"); + } + else + { + if (JSC$warn_unused_variable) + JSC$warning (JSC$filename + ":" + i.linenum.toString () + + ": warning: unused variable `" + i.symbol + "'"); + } + } + + this.frame = this.frame.next; +} + + +function JSC$NameSpace_alloc_local () +{ + return this.frame.num_locals++; +} + + +function JSC$NameSpace_define_symbol (symbol, scope, value, linenum) +{ + var i; + + for (i = this.frame.defs; i != null; i = i.next) + if (i.symbol == symbol) + { + if (i.scope == scope) + error (JSC$filename + ":" + i.linenum.toString() + + ": redeclaration of `" + i.symbol + "'"); + if (i.scope == JSC$SCOPE_ARG && JSC$warn_shadow) + JSC$warning (JSC$filename + ":" + linenum.toString () + + ": warning: declaration of `" + symbol + + "' shadows a parameter"); + + i.scope = scope; + i.value = value; + i.linenum = linenum; + + return; + } + + /* Create a new definition. */ + i = new JSC$SymbolDefinition (symbol, scope, value, linenum); + i.next = this.frame.defs; + this.frame.defs = i; +} + + +function JSC$NameSpace_lookup_symbol (symbol) +{ + var f, i; + + for (f = this.frame; f != null; f = f.next) + for (i = f.defs; i != null; i = i.next) + if (i.symbol == symbol) + { + i.usecount++; + return i; + } + + return null; +} + +/* + * Static helpers. + */ + +function JSC$NameSpaceFrame () +{ + this.next = null; + this.defs = null; + this.num_locals = 0; +} + + +function JSC$SymbolDefinition (symbol, scope, value, linenum) +{ + this.next = null; + this.symbol = symbol; + this.scope = scope; + this.value = value; + this.linenum = linenum; + this.usecount = 0; +} + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/jsc/parser.js b/reactos/lib/kjs/jsc/parser.js new file mode 100644 index 00000000000..8b471f317e8 --- /dev/null +++ b/reactos/lib/kjs/jsc/parser.js @@ -0,0 +1,1695 @@ +/* + * Parser. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsc/parser.js,v $ + * $Id: parser.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * Global functions. + */ + +function JSC$parser_reset () +{ + JSC$function = null; + JSC$global_stmts = null; + JSC$nested_function_declarations = null; +} + + +function JSC$parser_parse (stream) +{ + JSC$linenum = 1; + JSC$filename = stream.name; + JSC$functions = new Array (); + JSC$global_stmts = new Array (); + JSC$nested_function_declarations = new Array (); + JSC$anonymous_function_count = 0; + JSC$parser_peek_token_valid = false; + JSC$num_tokens = 0; + JSC$num_arguments_identifiers = 0; + JSC$num_missing_semicolons = 0; + + if (JSC$verbose) + JSC$message ("jsc: parsing"); + + while (JSC$parser_peek_token (stream) != JSC$tEOF) + if (!JSC$parser_parse_source_element (stream)) + JSC$parser_syntax_error (); + + if (JSC$verbose) + { + var msg = ("jsc: input stream had " + (JSC$linenum - 1).toString () + + " lines, " + JSC$num_tokens.toString () + " tokens"); + + if (JSC$num_missing_semicolons > 0) + msg += (", " + JSC$num_missing_semicolons.toString () + + " missing semicolons"); + + JSC$message (msg); + } +} + + +/* + * General help functions. + */ + +function JSC$parser_syntax_error () +{ + error (JSC$filename + ":" + JSC$linenum.toString () + ": syntax error"); +} + +/* All warnings are reported through this function. */ +function JSC$warning (line) +{ + System.stderr.writeln (line); +} + +/* All messages are reported throught this function. */ +function JSC$message (line) +{ + System.stderr.writeln (line); +} + + +function JSC$parser_get_token (stream) +{ + JSC$num_tokens++; + + var token; + if (JSC$parser_peek_token_valid) + { + JSC$parser_peek_token_valid = false; + JSC$parser_token_value = JSC$parser_peek_token_value; + JSC$parser_token_linenum = JSC$parser_peek_token_linenum; + token = JSC$parser_peek_token_token; + } + else + { + token = JSC$lexer (stream); + JSC$parser_token_value = JSC$token_value; + JSC$parser_token_linenum = JSC$token_linenum; + } + + if (token == JSC$tIDENTIFIER && JSC$parser_token_value == "arguments") + JSC$num_arguments_identifiers++; + + return token; +} + + +function JSC$parser_peek_token (stream) +{ + if (JSC$parser_peek_token_valid) + return JSC$parser_peek_token_token; + else + { + JSC$parser_peek_token_token = JSC$lexer (stream); + JSC$parser_peek_token_value = JSC$token_value; + JSC$parser_peek_token_linenum = JSC$token_linenum; + JSC$parser_peek_token_valid = true; + return JSC$parser_peek_token_token; + } +} + + +function JSC$parser_get_semicolon_asci (stream) +{ + var token = JSC$parser_peek_token (stream); + + if (token == #';') + { + /* Everything ok. It was there. */ + return JSC$parser_get_token (stream); + } + + /* No semicolon. Let's see if we can insert it there. */ + if (token == #'}' + || JSC$parser_token_linenum < JSC$parser_peek_token_linenum + || token == JSC$tEOF) + { + /* Ok, do the automatic semicolon insertion. */ + if (JSC$warn_missing_semicolon) + JSC$warning (JSC$filename + ":" + JSC$parser_token_linenum.toString () + + ": warning: missing semicolon"); + JSC$num_missing_semicolons++; + return #';'; + } + + /* Sorry, no can do. */ + JSC$parser_syntax_error (); +} + + +function JSC$parser_expr_is_left_hand_side (expr) +{ + return (expr.etype == JSC$EXPR_CALL + || expr.etype == JSC$EXPR_OBJECT_PROPERTY + || expr.etype == JSC$EXPR_OBJECT_ARRAY + || expr.etype == JSC$EXPR_NEW + || expr.etype == JSC$EXPR_THIS + || expr.etype == JSC$EXPR_IDENTIFIER + || expr.etype == JSC$EXPR_FLOAT + || expr.etype == JSC$EXPR_INTEGER + || expr.etype == JSC$EXPR_STRING + || expr.etype == JSC$EXPR_REGEXP + || expr.etype == JSC$EXPR_ARRAY_INITIALIZER + || expr.etype == JSC$EXPR_NULL + || expr.etype == JSC$EXPR_TRUE + || expr.etype == JSC$EXPR_FALSE); +} + + +function JSC$parser_parse_source_element (stream) +{ + if (JSC$parser_parse_function_declaration (stream)) + return true; + + var stmt = JSC$parser_parse_stmt (stream); + if (!stmt) + return false; + + if (stmt.stype == JSC$STMT_VARIABLE) + /* + * This is a variable declaration at the global level. These + * are actually global variables. + */ + stmt.global_level = true; + + JSC$global_stmts.push (stmt); + + return true; +} + + +function JSC$parser_parse_function_declaration (stream) +{ + var id, args, block; + + if (JSC$parser_peek_token (stream) != JSC$tFUNCTION) + return false; + + /* Record how many `arguments' identifiers have been seen so far. */ + var num_arguments_identifiers = JSC$num_arguments_identifiers; + + JSC$parser_get_token (stream); + if (JSC$parser_get_token (stream) != JSC$tIDENTIFIER) + JSC$parser_syntax_error (); + + id = JSC$parser_token_value; + var ln = JSC$parser_token_linenum; + var id_given = id; + + if (JSC$nested_function_declarations.length > 0) + { + /* This is a nested function declaration. */ + id = ".F:" + (JSC$anonymous_function_count++).toString (); + } + JSC$nested_function_declarations.push (id); + + if (JSC$parser_get_token (stream) != #'(') + JSC$parser_syntax_error (); + + /* Formal parameter list opt. */ + args = new Array (); + while (JSC$parser_peek_token (stream) != #')') + { + if (JSC$parser_get_token (stream) != JSC$tIDENTIFIER) + JSC$parser_syntax_error (); + args.push (JSC$parser_token_value); + + var token = JSC$parser_peek_token (stream); + if (token == #',') + { + JSC$parser_get_token (stream); + if (JSC$parser_peek_token (stream) != JSC$tIDENTIFIER) + JSC$parser_syntax_error (); + } + else if (token != #')') + JSC$parser_syntax_error (); + } + + if (JSC$parser_get_token (stream) != #')') + JSC$parser_syntax_error (); + + JSC$parser_peek_token (stream); + var lbrace_ln = JSC$parser_peek_token_linenum; + + block = JSC$parser_parse_block (stream); + if (typeof block == "boolean") + JSC$parser_syntax_error (); + + /* Did the function use the `arguments' identifier? */ + var use_arguments = false; + if (JSC$num_arguments_identifiers > num_arguments_identifiers) + { + use_arguments = true; + if (JSC$warn_deprecated) + JSC$warning (JSC$filename + ":" + ln.toString () + + ": warning: the `arguments' property of Function " + + "instance is deprecated"); + } + + JSC$functions.push (new JSC$function_declaration (ln, lbrace_ln, id, + id_given, args, + block, use_arguments)); + + JSC$nested_function_declarations.pop (); + + return true; +} + + +function JSC$parser_parse_block (stream) +{ + var block; + + if (JSC$parser_peek_token (stream) != #'{') + return false; + + JSC$parser_get_token (stream) != #'{'; + var ln = JSC$parser_peek_token_linenum; + + /* Do we have a statement list? */ + if (JSC$parser_peek_token (stream) != #'}') + /* Yes we have. */ + block = JSC$parser_parse_stmt_list (stream); + else + /* Do we don't */ + block = new Array (); + + if (JSC$parser_get_token (stream) != #'}') + JSC$parser_syntax_error (); + + block.linenum = ln; + + return block; +} + + +function JSC$parser_parse_stmt_list (stream) +{ + var list, done, item; + + list = new Array (); + done = false; + + while (!done) + { + item = JSC$parser_parse_stmt (stream); + if (typeof item == "boolean") + { + /* Can't parse more statements. We'r done. */ + done = true; + } + else + list.push (item); + } + + return list; +} + + +function JSC$parser_parse_stmt (stream) +{ + var item, token; + + if (typeof (item = JSC$parser_parse_block (stream)) != "boolean") + return new JSC$stmt_block (item.linenum, item); + else if (JSC$parser_parse_function_declaration (stream)) + { + /* XXX The function declaration as statement might be incomplete. */ + + if (JSC$nested_function_declarations.length == 0) + /* Function declaration at top-level statements. */ + return new JSC$stmt_empty (JSC$parser_token_linenum); + + /* Function declaration inside another function. */ + + var container_id = JSC$nested_function_declarations.pop (); + JSC$nested_function_declarations.push (container_id); + + var f = JSC$functions[JSC$functions.length - 1]; + var function_id = f.name; + var given_id = f.name_given; + + return new JSC$stmt_function_declaration (JSC$parser_token_linenum, + container_id, function_id, + given_id); + } + else if (typeof (item = JSC$parser_parse_variable_stmt (stream)) + != "boolean") + return item; + else if (typeof (item = JSC$parser_parse_if_stmt (stream)) + != "boolean") + return item; + else if (typeof (item = JSC$parser_parse_iteration_stmt (stream)) + != "boolean") + return item; + else if (typeof (item = JSC$parser_parse_expr (stream)) + != "boolean") + { + if (item.etype == JSC$EXPR_IDENTIFIER) + { + /* Possible `Labeled Statement'. */ + token = JSC$parser_peek_token (stream); + if (token == #':' && item.linenum == JSC$parser_peek_token_linenum) + { + /* Yes it is. */ + JSC$parser_get_token (stream); + var stmt = JSC$parser_parse_stmt (stream); + if (!stmt) + JSC$parser_syntax_error; + + return new JSC$stmt_labeled_stmt (item.linenum, item.value, + stmt); + } + /* FALLTHROUGH */ + } + + JSC$parser_get_semicolon_asci (stream); + return new JSC$stmt_expr (item); + } + else + { + token = JSC$parser_peek_token (stream); + if (token == #';') + { + JSC$parser_get_token (stream); + return new JSC$stmt_empty (JSC$parser_token_linenum); + } + else if (token == JSC$tCONTINUE) + { + JSC$parser_get_token (stream); + + /* Check the possible label. */ + var label = null; + token = JSC$parser_peek_token (stream); + if (token == JSC$tIDENTIFIER + && JSC$parser_token_linenum == JSC$parser_peek_token_linenum) + { + JSC$parser_get_token (stream); + label = JSC$parser_token_value; + } + + item = new JSC$stmt_continue (JSC$parser_token_linenum, label); + + JSC$parser_get_semicolon_asci (stream); + + return item; + } + else if (token == JSC$tBREAK) + { + JSC$parser_get_token (stream); + + /* Check the possible label. */ + var label = null; + token = JSC$parser_peek_token (stream); + if (token == JSC$tIDENTIFIER + && JSC$parser_token_linenum == JSC$parser_peek_token_linenum) + { + JSC$parser_get_token (stream); + label = JSC$parser_token_value; + } + + item = new JSC$stmt_break (JSC$parser_token_linenum, label); + + JSC$parser_get_semicolon_asci (stream); + + return item; + } + else if (token == JSC$tRETURN) + { + JSC$parser_get_token (stream); + var linenum = JSC$parser_token_linenum; + + if (JSC$parser_peek_token (stream) == #';') + { + /* Consume the semicolon. */ + JSC$parser_get_token (stream); + item = null; + } + else + { + if (JSC$parser_peek_token_linenum > linenum) + { + /* + * A line terminator between tRETURN and the next + * token that is not a semicolon. ASCI here. + */ + if (JSC$warn_missing_semicolon) + JSC$warning (JSC$filename + ":" + linenum.toString () + + ": warning: missing semicolon"); + + JSC$num_missing_semicolons++; + item = null; + } + else + { + item = JSC$parser_parse_expr (stream); + if (typeof item == "boolean") + JSC$parser_syntax_error (); + + JSC$parser_get_semicolon_asci (stream); + } + } + + return new JSC$stmt_return (linenum, item); + } + else if (token == JSC$tSWITCH) + { + JSC$parser_get_token (stream); + return JSC$parser_parse_switch (stream); + } + else if (token == JSC$tWITH) + { + JSC$parser_get_token (stream); + var linenum = JSC$parser_token_linenum; + + if (JSC$parser_get_token (stream) != #'(') + JSC$parser_syntax_error (); + + var expr = JSC$parser_parse_expr (stream); + if (typeof expr == "boolean") + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #')') + JSC$parser_syntax_error (); + + var stmt = JSC$parser_parse_stmt (stream); + if (typeof stmt == "boolean") + JSC$parser_syntax_error (); + + return new JSC$stmt_with (linenum, expr, stmt); + } + else if (token == JSC$tTRY) + { + JSC$parser_get_token (stream); + return JSC$parser_parse_try (stream); + } + else if (token == JSC$tTHROW) + { + JSC$parser_get_token (stream); + var linenum = JSC$parser_token_linenum; + + /* + * Get the next token's linenum. We need it for strict_ecma + * warning. + */ + JSC$parser_peek_token (stream); + var peek_linenum = JSC$parser_peek_token_linenum; + + /* The expression to throw. */ + var expr = JSC$parser_parse_expr (stream); + if (typeof expr == "boolean") + JSC$parser_syntax_error (); + + if (JSC$warn_strict_ecma && peek_linenum > linenum) + JSC$warning (JSC$filename + ":" + JSC$linenum.toString () + + ": warning: ECMAScript don't allow line terminators" + + " between `throw' and expression"); + + JSC$parser_get_semicolon_asci (stream); + + return new JSC$stmt_throw (linenum, expr); + } + else + /* Can't parse more. We'r done. */ + return false; + } +} + + +function JSC$parser_parse_switch (stream) +{ + var linenum = JSC$parser_token_linenum; + + if (JSC$parser_get_token (stream) != #'(') + JSC$parser_syntax_error (); + + var expr = JSC$parser_parse_expr (stream); + if (!expr) + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #')') + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #'{') + JSC$parser_syntax_error (); + + /* Parse case clauses. */ + var clauses = new Array (); + while (true) + { + var token = JSC$parser_get_token (stream); + + if (token == #'}') + break; + else if (token == JSC$tCASE || token == JSC$tDEFAULT) + { + var stmts = new Array (); + stmts.expr = null; + + if (token == JSC$tCASE) + { + stmts.expr = JSC$parser_parse_expr (stream); + if (!stmts.expr) + JSC$parser_syntax_error (); + } + if (JSC$parser_get_token (stream) != #':') + JSC$parser_syntax_error (); + + stmts.linenum = JSC$parser_token_linenum; + + /* Read the statement list. */ + while (true) + { + token = JSC$parser_peek_token (stream); + if (token == #'}' || token == JSC$tCASE || token == JSC$tDEFAULT) + /* Done with this branch. */ + break; + + var stmt = JSC$parser_parse_stmt (stream); + if (!stmt) + JSC$parser_syntax_error (); + + stmts.push (stmt); + } + + stmts.last_linenum = JSC$parser_token_linenum; + + /* One clause parsed. */ + clauses.push (stmts); + } + else + JSC$parser_syntax_error (); + } + + return new JSC$stmt_switch (linenum, JSC$parser_token_linenum, expr, + clauses); +} + + +function JSC$parser_parse_try (stream) +{ + var linenum = JSC$parser_token_linenum; + + var block = JSC$parser_parse_stmt (stream); + if (!block) + JSC$parser_syntax_error (); + + var try_block_last_linenum = JSC$parser_token_linenum; + + /* Now we must see `catch' or `finally'. */ + var token = JSC$parser_peek_token (stream); + if (token != JSC$tCATCH && token != JSC$tFINALLY) + JSC$parser_syntax_error (); + + var catch_list = false; + if (token == JSC$tCATCH) + { + /* Parse catch list. */ + + catch_list = new Array (); + catch_list.linenum = JSC$parser_peek_token_linenum; + + while (token == JSC$tCATCH) + { + JSC$parser_get_token (stream); + var c = new Object (); + c.linenum = JSC$parser_token_linenum; + + if (JSC$parser_get_token (stream) != #'(') + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != JSC$tIDENTIFIER) + JSC$parser_syntax_error (); + c.id = JSC$parser_token_value; + + c.guard = false; + if (JSC$parser_peek_token (stream) == JSC$tIF) + { + JSC$parser_get_token (stream); + c.guard = JSC$parser_parse_expr (stream); + if (!c.guard) + JSC$parser_syntax_error (); + } + + if (JSC$parser_get_token (stream) != #')') + JSC$parser_syntax_error (); + + c.stmt = JSC$parser_parse_stmt (stream); + if (!c.stmt) + JSC$parser_syntax_error (); + + catch_list.push (c); + + token = JSC$parser_peek_token (stream); + } + + catch_list.last_linenum = JSC$parser_token_linenum; + } + + var fin = false; + if (token == JSC$tFINALLY) + { + /* Parse the finally. */ + JSC$parser_get_token (stream); + + fin = JSC$parser_parse_stmt (stream); + if (!fin) + JSC$parser_syntax_error (); + } + + return new JSC$stmt_try (linenum, try_block_last_linenum, + JSC$parser_token_linenum, block, catch_list, + fin); +} + + +function JSC$parser_parse_variable_stmt (stream) +{ + var list, id, expr, token; + + if (JSC$parser_peek_token (stream) != JSC$tVAR) + return false; + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + list = new Array (); + + while (true) + { + token = JSC$parser_peek_token (stream); + if (token == JSC$tIDENTIFIER) + { + JSC$parser_get_token (); + id = JSC$parser_token_value; + + if (JSC$parser_peek_token (stream) == #'=') + { + JSC$parser_get_token (stream); + expr = JSC$parser_parse_assignment_expr (stream); + if (typeof expr == "boolean") + JSC$parser_syntax_error (); + } + else + expr = null; + + list.push (new JSC$var_declaration (id, expr)); + + /* Check if we have more input. */ + if (JSC$parser_peek_token (stream) == #',') + { + /* Yes we have. */ + JSC$parser_get_token (stream); + + /* The next token must be tIDENTIFIER. */ + if (JSC$parser_peek_token (stream) != JSC$tIDENTIFIER) + JSC$parser_syntax_error (); + } + else + { + /* No, we don't. */ + JSC$parser_get_semicolon_asci (stream); + break; + } + } + else + { + /* We'r done. */ + JSC$parser_get_semicolon_asci (stream); + break; + } + } + + /* There must be at least one variable declaration. */ + if (list.length == 0) + JSC$parser_syntax_error (); + + return new JSC$stmt_variable (ln, list); +} + + +function JSC$parser_parse_if_stmt (stream) +{ + var expr, stmt, stmt2; + + if (JSC$parser_peek_token (stream) != JSC$tIF) + return false; + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + if (JSC$parser_get_token (stream) != #'(') + JSC$parser_syntax_error (); + + expr = JSC$parser_parse_expr (stream); + if (typeof expr == "boolean") + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #')') + JSC$parser_syntax_error (); + + stmt = JSC$parser_parse_stmt (stream); + if (typeof stmt == "boolean") + JSC$parser_syntax_error (); + + if (JSC$parser_peek_token (stream) == JSC$tELSE) + { + JSC$parser_get_token (stream); + stmt2 = JSC$parser_parse_stmt (stream); + if (typeof stmt2 == "boolean") + JSC$parser_syntax_error (); + } + else + stmt2 = null; + + return new JSC$stmt_if (ln, expr, stmt, stmt2); +} + + +function JSC$parser_parse_iteration_stmt (stream) +{ + var token, expr1, expr2, expr3, stmt; + + token = JSC$parser_peek_token (stream); + if (token == JSC$tDO) + { + /* do Statement while (Expression); */ + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + stmt = JSC$parser_parse_stmt (stream); + if (typeof stmt == "boolean") + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != JSC$tWHILE) + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #'(') + JSC$parser_syntax_error (); + + expr1 = JSC$parser_parse_expr (stream); + if (typeof expr1 == "boolean") + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #')') + JSC$parser_syntax_error (); + + JSC$parser_get_semicolon_asci (stream); + + return new JSC$stmt_do_while (ln, expr1, stmt); + } + else if (token == JSC$tWHILE) + { + /* while (Expression) Statement */ + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + if (JSC$parser_get_token (stream) != #'(') + JSC$parser_syntax_error (); + + expr1 = JSC$parser_parse_expr (stream); + if (typeof expr1 == "boolean") + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #')') + JSC$parser_syntax_error (); + + stmt = JSC$parser_parse_stmt (stream); + if (typeof stmt == "boolean") + JSC$parser_syntax_error (); + + return new JSC$stmt_while (ln, expr1, stmt); + } + else if (token == JSC$tFOR) + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + if (JSC$parser_get_token (stream) != #'(') + JSC$parser_syntax_error (); + + /* Init */ + + var vars = null; + + token = JSC$parser_peek_token (stream); + if (token == JSC$tVAR) + { + JSC$parser_get_token (stream); + vars = new Array (); + + while (true) + { + /* The identifier. */ + token = JSC$parser_peek_token (stream); + if (token != JSC$tIDENTIFIER) + break; + + JSC$parser_get_token (stream); + var id = JSC$parser_token_value; + + /* Possible initializer. */ + var expr = null; + if (JSC$parser_peek_token (stream) == #'=') + { + JSC$parser_get_token (stream); + expr = JSC$parser_parse_assignment_expr (stream); + if (!expr) + JSC$parser_syntax_error (); + } + + vars.push (new JSC$var_declaration (id, expr)); + + /* Check if we have more input. */ + if (JSC$parser_peek_token (stream) == #',') + { + /* Yes we have. */ + JSC$parser_get_token (stream); + + /* The next token must be tIDENTIFIER. */ + if (JSC$parser_peek_token (stream) != JSC$tIDENTIFIER) + JSC$parser_syntax_error (); + } + else + /* No more input. */ + break; + } + + /* Must have at least one variable declaration. */ + if (vars.length == 0) + JSC$parser_syntax_error (); + } + else if (token != #';') + { + expr1 = JSC$parser_parse_expr (stream); + if (typeof expr1 == "boolean") + JSC$parser_syntax_error (); + } + else + expr1 = null; + + token = JSC$parser_get_token (stream); + var for_in = false; + + if (token == #';') + { + /* Normal for-statement. */ + + /* Check */ + if (JSC$parser_peek_token (stream) != #';') + { + expr2 = JSC$parser_parse_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + } + else + expr2 = null; + + if (JSC$parser_get_token (stream) != #';') + JSC$parser_syntax_error (); + + /* Increment */ + if (JSC$parser_peek_token (stream) != #')') + { + expr3 = JSC$parser_parse_expr (stream); + if (typeof expr3 == "boolean") + JSC$parser_syntax_error (); + } + else + expr3 = null; + } + else if (token == JSC$tIN) + { + /* The `for (VAR in EXPR)'-statement. */ + + for_in = true; + + if (expr1) + { + /* The first expression must be an identifier. */ + if (expr1.etype != JSC$EXPR_IDENTIFIER) + JSC$parser_syntax_error (); + } + else + { + /* We must have only one variable declaration. */ + if (vars.length != 1) + JSC$parser_syntax_error (); + } + + /* The second expressions. */ + expr2 = JSC$parser_parse_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + } + else + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #')') + JSC$parser_syntax_error (); + + /* Stmt. */ + stmt = JSC$parser_parse_stmt (stream); + if (typeof stmt == "boolean") + JSC$parser_syntax_error (); + + if (for_in) + return new JSC$stmt_for_in (ln, vars, expr1, expr2, stmt); + + return new JSC$stmt_for (ln, vars, expr1, expr2, expr3, stmt); + } + return false; +} + + +function JSC$parser_parse_expr (stream) +{ + var expr, expr2; + + if (typeof (expr = JSC$parser_parse_assignment_expr (stream)) + == "boolean") + return false; + + /* Check for the comma expression. */ + while (JSC$parser_peek_token (stream) == #',') + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + if (typeof (expr2 = JSC$parser_parse_assignment_expr (stream)) + == "boolean") + JSC$parser_syntax_error (); + expr = new JSC$expr_comma (ln, expr, expr2); + } + + return expr; +} + + +function JSC$parser_parse_assignment_expr (stream) +{ + var expr, expr2, token; + + if (typeof (expr = JSC$parser_parse_conditional_expr (stream)) + == "boolean") + return false; + + if (JSC$parser_expr_is_left_hand_side (expr)) + { + token = JSC$parser_peek_token (stream); + if (token == #'=' || token == JSC$tMULA + || token == JSC$tDIVA || token == JSC$tMODA + || token == JSC$tADDA || token == JSC$tSUBA + || token == JSC$tLSIA || token == JSC$tRSIA + || token == JSC$tRRSA || token == JSC$tANDA + || token == JSC$tXORA || token == JSC$tORA) + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_assignment_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_assignment (ln, token, expr, expr2); + } + } + + if (JSC$optimize_constant_folding && expr.constant_folding) + return expr.constant_folding (); + + return expr; +} + + +function JSC$parser_parse_conditional_expr (stream) +{ + var expr, expr2, expr3, token; + + if (typeof (expr = JSC$parser_parse_logical_or_expr (stream)) + == "boolean") + return false; + + token = JSC$parser_peek_token (stream); + if (token == #'?') + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_assignment_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #':') + JSC$parser_syntax_error (); + expr3 = JSC$parser_parse_assignment_expr (stream); + if (typeof expr3 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_quest_colon (ln, expr, expr2, expr3); + } + + return expr; +} + + +function JSC$parser_parse_logical_or_expr (stream) +{ + var expr, expr2; + + if (typeof (expr = JSC$parser_parse_logical_and_expr (stream)) + == "boolean") + return false; + + while (JSC$parser_peek_token (stream) == JSC$tOR) + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_logical_and_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_logical_or (ln, expr, expr2); + } + + return expr; +} + + +function JSC$parser_parse_logical_and_expr (stream) +{ + var expr, expr2; + + if (typeof (expr = JSC$parser_parse_bitwise_or_expr (stream)) + == "boolean") + return false; + + while (JSC$parser_peek_token (stream) == JSC$tAND) + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_bitwise_or_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_logical_and (ln, expr, expr2); + } + + return expr; +} + + +function JSC$parser_parse_bitwise_or_expr (stream) +{ + var expr, expr2; + + if (typeof (expr = JSC$parser_parse_bitwise_xor_expr (stream)) + == "boolean") + return false; + + while (JSC$parser_peek_token (stream) == #'|') + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_bitwise_xor_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_bitwise_or (ln, expr, expr2); + } + + return expr; +} + + +function JSC$parser_parse_bitwise_xor_expr (stream) +{ + var expr, expr2; + + if (typeof (expr = JSC$parser_parse_bitwise_and_expr (stream)) + == "boolean") + return false; + + while (JSC$parser_peek_token (stream) == #'^') + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_bitwise_and_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_bitwise_xor (ln, expr, expr2); + } + + return expr; +} + + +function JSC$parser_parse_bitwise_and_expr (stream) +{ + var expr, expr2; + + if (typeof (expr = JSC$parser_parse_equality_expr (stream)) + == "boolean") + return false; + + while (JSC$parser_peek_token (stream) == #'&') + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_equality_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_bitwise_and (ln, expr, expr2); + } + + return expr; +} + + +function JSC$parser_parse_equality_expr (stream) +{ + var expr, expr2, token; + + if (typeof (expr = JSC$parser_parse_relational_expr (stream)) + == "boolean") + return false; + + token = JSC$parser_peek_token (stream); + while (token == JSC$tEQUAL || token == JSC$tNEQUAL + || token == JSC$tSEQUAL || token == JSC$tSNEQUAL) + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_relational_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_equality (ln, token, expr, expr2); + token = JSC$parser_peek_token (stream); + } + + return expr; +} + + +function JSC$parser_parse_relational_expr (stream) +{ + var expr, expr2, token; + + if (typeof (expr = JSC$parser_parse_shift_expr (stream)) + == "boolean") + return false; + + token = JSC$parser_peek_token (stream); + while (token == #'<' || token == #'>' || token == JSC$tLE + || token == JSC$tGE) + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_shift_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_relational (ln, token, expr, expr2); + token = JSC$parser_peek_token (stream); + } + + return expr; +} + + +function JSC$parser_parse_shift_expr (stream) +{ + var expr, expr2, token; + + if (typeof (expr = JSC$parser_parse_additive_expr (stream)) + == "boolean") + return false; + + token = JSC$parser_peek_token (stream); + while (token == JSC$tLSHIFT || token == JSC$tRSHIFT || token == JSC$tRRSHIFT) + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_additive_expr (stream); + + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_shift (ln, token, expr, expr2); + token = JSC$parser_peek_token (stream); + } + + return expr; +} + + +function JSC$parser_parse_additive_expr (stream) +{ + var expr, expr2, token; + + if (typeof (expr = JSC$parser_parse_multiplicative_expr (stream)) + == "boolean") + return false; + + token = JSC$parser_peek_token (stream); + while (token == #'+' || token == #'-') + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_multiplicative_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_additive (ln, token, expr, expr2); + token = JSC$parser_peek_token (stream); + } + + return expr; +} + + +function JSC$parser_parse_multiplicative_expr (stream) +{ + var expr, expr2, token; + + if (typeof (expr = JSC$parser_parse_unary_expr (stream)) == "boolean") + return false; + + token = JSC$parser_peek_token (stream); + while (token == #'*' || token == #'/' || token == #'%') + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr2 = JSC$parser_parse_unary_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_multiplicative (ln, token, expr, expr2); + token = JSC$parser_peek_token (stream); + } + + return expr; +} + + +function JSC$parser_parse_unary_expr (stream) +{ + var expr, token; + + token = JSC$parser_peek_token (stream); + if (token == JSC$tDELETE + || token == JSC$tVOID + || token == JSC$tTYPEOF + || token == JSC$tPLUSPLUS + || token == JSC$tMINUSMINUS + || token == #'+' + || token == #'-' + || token == #'~' + || token == #'!') + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr = JSC$parser_parse_unary_expr (stream); + if (typeof expr == "boolean") + JSC$parser_syntax_error (); + + return new JSC$expr_unary (ln, token, expr); + } + + return JSC$parser_parse_postfix_expr (stream); +} + + +function JSC$parser_parse_postfix_expr (stream) +{ + var expr, token; + + if (typeof (expr = JSC$parser_parse_left_hand_side_expr (stream)) + == "boolean") + return false; + + token = JSC$parser_peek_token (stream); + if (token == JSC$tPLUSPLUS || token == JSC$tMINUSMINUS) + { + if (JSC$parser_peek_token_linenum > JSC$parser_token_linenum) + { + if (JSC$warn_missing_semicolon) + JSC$warning (JSC$filename + ":" + + JSC$parser_token_linenum.toString () + + ": warning: automatic semicolon insertion cuts the expression before ++ or --"); + } + else + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + return new JSC$expr_postfix (ln, token, expr); + } + } + + return expr; +} + + +function JSC$parser_parse_left_hand_side_expr (stream) +{ + var expr, args, token, expr2; + + if (typeof (expr = JSC$parser_parse_member_expr (stream)) + == "boolean") + return false; + + /* Parse the possible first pair of arguments. */ + if (JSC$parser_peek_token (stream) == #'(') + { + var ln = JSC$parser_peek_token_linenum; + + args = JSC$parser_parse_arguments (stream); + if (typeof args == "boolean") + JSC$parser_syntax_error (); + + expr = new JSC$expr_call (ln, expr, args); + } + else + return expr; + + /* Parse to possibly following arguments and selectors. */ + while ((token = JSC$parser_peek_token (stream)) == #'(' + || token == #'[' || token == #'.') + { + var ln = JSC$parser_peek_token_linenum; + + if (token == #'(') + { + args = JSC$parser_parse_arguments (stream); + expr = new JSC$expr_call (ln, expr, args); + } + else if (token == #'[') + { + JSC$parser_get_token (stream); + + expr2 = JSC$parser_parse_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #']') + JSC$parser_syntax_error (); + + expr = new JSC$expr_object_array (ln, expr, expr2); + } + else + { + JSC$parser_get_token (stream); + if (JSC$parser_get_token (stream) != JSC$tIDENTIFIER) + JSC$parser_syntax_error (); + + expr = new JSC$expr_object_property (ln, expr, + JSC$parser_token_value); + } + } + + return expr; +} + + +function JSC$parser_parse_member_expr (stream) +{ + var expr, args, token, expr2; + + if (typeof (expr = JSC$parser_parse_primary_expr (stream)) + == "boolean") + { + token = JSC$parser_peek_token (stream); + + if (token == JSC$tNEW) + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + expr = JSC$parser_parse_member_expr (stream); + if (typeof expr == "boolean") + JSC$parser_syntax_error (); + + if (JSC$parser_peek_token (stream) == #'(') + { + args = JSC$parser_parse_arguments (stream); + if (typeof args == "boolean") + JSC$parser_syntax_error (); + } + else + return new JSC$expr_new (ln, expr, null); + + expr = new JSC$expr_new (ln, expr, args); + } + else + return false; + } + + /* Ok, now we have valid starter. */ + token = JSC$parser_peek_token (stream); + while (token == #'[' || token == #'.') + { + JSC$parser_get_token (stream); + var ln = JSC$parser_token_linenum; + + if (token == #'[') + { + expr2 = JSC$parser_parse_expr (stream); + if (typeof expr2 == "boolean") + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #']') + JSC$parser_syntax_error (); + + expr = new JSC$expr_object_array (ln, expr, expr2); + } + else + { + if (JSC$parser_get_token (stream) != JSC$tIDENTIFIER) + JSC$parser_syntax_error (); + + expr = new JSC$expr_object_property (ln, expr, + JSC$parser_token_value); + } + + token = JSC$parser_peek_token (stream); + } + + return expr; +} + + +function JSC$parser_parse_primary_expr (stream) +{ + var token, val; + + token = JSC$parser_peek_token (stream); + var ln = JSC$parser_peek_token_linenum; + + if (token == JSC$tTHIS) + val = new JSC$expr_this (ln); + else if (token == JSC$tIDENTIFIER) + val = new JSC$expr_identifier (ln, JSC$parser_peek_token_value); + else if (token == JSC$tFLOAT) + val = new JSC$expr_float (ln, JSC$parser_peek_token_value); + else if (token == JSC$tINTEGER) + val = new JSC$expr_integer (ln, JSC$parser_peek_token_value); + else if (token == JSC$tSTRING) + val = new JSC$expr_string (ln, JSC$parser_peek_token_value); + else if (token == #'/') + { + /* + * Kludge alert! The regular expression constants (/.../) and + * div operands are impossible to distinguish, based only on the + * lexical analysis. Therefore, we need some syntactical + * knowledge when the regular expression constants are possible + * at all. This is the place where they can appear. In all + * other places, the character `/' is interpreted as a div + * operator. + */ + JSC$parser_get_token (stream); + + return new JSC$expr_regexp (ln, JSC$lexer_read_regexp_constant (stream)); + } + else if (token == JSC$tNULL) + val = new JSC$expr_null (ln); + else if (token == JSC$tTRUE) + val = new JSC$expr_true (ln); + else if (token == JSC$tFALSE) + val = new JSC$expr_false (ln); + else if (token == #'[') + { + /* Array initializer. */ + /* TODO: SharpVarDefinition_{opt} */ + + JSC$parser_get_token (stream); + + var items = new Array (); + var pos = 0; + + while ((token = JSC$parser_peek_token (stream)) != #']') + { + if (token == #',') + { + JSC$parser_get_token (stream); + items[++pos] = false; + continue; + } + + var expr = JSC$parser_parse_assignment_expr (stream); + if (!expr) + JSC$parser_syntax_error (); + + items[pos] = expr; + + /* Got one expression. It must be followed by ',' or ']'. */ + token = JSC$parser_peek_token (stream); + if (token != #',' && token != #']') + JSC$parser_syntax_error (); + } + + val = new JSC$expr_array_initializer (ln, items); + } + else if (token == #'{') + { + /* Object literal. */ + /* TODO: SharpVarDefinition_{opt} */ + + JSC$parser_get_token (stream); + + var items = new Array (); + + while ((token = JSC$parser_peek_token (stream)) != #'}') + { + var pair = new Object (); + + token = JSC$parser_get_token (stream); + + pair.linenum = JSC$linenum; + pair.id_type = token; + pair.id = JSC$parser_token_value; + + if (token != JSC$tIDENTIFIER && token != JSC$tSTRING + && token != JSC$tINTEGER) + JSC$parser_syntax_error (); + + if (JSC$parser_get_token (stream) != #':') + JSC$parser_syntax_error (); + + pair.expr = JSC$parser_parse_assignment_expr (stream); + if (!pair.expr) + JSC$parser_syntax_error (); + + items.push (pair); + + /* + * Got one property, initializer pair. It must be followed + * by ',' or '}'. + */ + token = JSC$parser_peek_token (stream); + if (token == #',') + { + /* Ok, we have more items. */ + JSC$parser_get_token (stream); + + token = JSC$parser_peek_token (stream); + if (token != JSC$tIDENTIFIER && token != JSC$tSTRING + && token != JSC$tINTEGER) + JSC$parser_syntax_error (); + } + else if (token != #'}' && token) + JSC$parser_syntax_error (); + } + + val = new JSC$expr_object_initializer (ln, items); + } + else if (token == #'(') + { + JSC$parser_get_token (stream); + + val = JSC$parser_parse_expr (stream); + if (typeof val == "boolean" + || JSC$parser_peek_token (stream) != #')') + JSC$parser_syntax_error (); + } + else + return false; + + JSC$parser_get_token (stream); + return val; +} + + +function JSC$parser_parse_arguments (stream) +{ + var args, item; + + if (JSC$parser_peek_token (stream) != #'(') + return false; + + args = new Array (); + + JSC$parser_get_token (stream); + while (JSC$parser_peek_token (stream) != #')') + { + item = JSC$parser_parse_assignment_expr (stream); + if (typeof item == "boolean") + JSC$parser_syntax_error (); + args.push (item); + + var token = JSC$parser_peek_token (stream); + if (token == #',') + JSC$parser_get_token (stream); + else if (token != #')') + JSC$parser_syntax_error (); + } + JSC$parser_get_token (stream); + + return args; +} + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/jsc/streams.js b/reactos/lib/kjs/jsc/streams.js new file mode 100644 index 00000000000..9c8a7f018cb --- /dev/null +++ b/reactos/lib/kjs/jsc/streams.js @@ -0,0 +1,173 @@ +/* + * Input stream definitions. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsc/streams.js,v $ + * $Id: streams.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * File stream. + */ + +function JSC$StreamFile (name) +{ + this.name = name; + this.stream = new File (name); + this.error = ""; + + this.open = JSC$StreamFile_open; + this.close = JSC$StreamFile_close; + this.rewind = JSC$StreamFile_rewind; + this.readByte = JSC$StreamFile_read_byte; + this.ungetByte = JSC$StreamFile_unget_byte; + this.readln = JSC$StreamFile_readln; +} + + +function JSC$StreamFile_open () +{ + if (!this.stream.open ("r")) + { + this.error = System.strerror (System.errno); + return false; + } + + return true; +} + + +function JSC$StreamFile_close () +{ + return this.stream.close (); +} + + +function JSC$StreamFile_rewind () +{ + return this.stream.setPosition (0); +} + + +function JSC$StreamFile_read_byte () +{ + return this.stream.readByte (); +} + + +function JSC$StreamFile_unget_byte (byte) +{ + this.stream.ungetByte (byte); +} + + +function JSC$StreamFile_readln () +{ + return this.stream.readln (); +} + + +/* + * String stream. + */ + +function JSC$StreamString (str) +{ + this.name = "StringStream"; + this.string = str; + this.pos = 0; + this.unget_byte = -1; + this.error = ""; + + this.open = JSC$StreamString_open; + this.close = JSC$StreamString_close; + this.rewind = JSC$StreamString_rewind; + this.readByte = JSC$StreamString_read_byte; + this.ungetByte = JSC$StreamString_unget_byte; + this.readln = JSC$StreamString_readln; +} + + +function JSC$StreamString_open () +{ + return true; +} + + +function JSC$StreamString_close () +{ + return true; +} + + +function JSC$StreamString_rewind () +{ + this.pos = 0; + this.unget_byte = -1; + this.error = ""; + return true; +} + + +function JSC$StreamString_read_byte () +{ + var ch; + + if (this.unget_byte >= 0) + { + ch = this.unget_byte; + this.unget_byte = -1; + return ch; + } + + if (this.pos >= this.string.length) + return -1; + + return this.string.charCodeAt (this.pos++); +} + + +function JSC$StreamString_unget_byte (byte) +{ + this.unget_byte = byte; +} + + +function JSC$StreamString_readln () +{ + var line = new String (""); + var ch; + + while ((ch = this.readByte ()) != -1 && ch != #'\n') + line.append (String.pack ("C", ch)); + + return line; +} + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/jsc/tests/ChangeLog b/reactos/lib/kjs/jsc/tests/ChangeLog new file mode 100644 index 00000000000..45c1bff8970 --- /dev/null +++ b/reactos/lib/kjs/jsc/tests/ChangeLog @@ -0,0 +1,11 @@ +1998-11-25 Markku Rossi + + * asci.test: Fixed to work when the builddir != srcdir. + +1998-08-11 Markku Rossi + + * asci.test: Added test for the automatic semicolon insertion. + +1998-03-26 Markku Rossi + + * Makefile.am: Created tests for the JavaScript compiler. diff --git a/reactos/lib/kjs/jsc/tests/Makefile b/reactos/lib/kjs/jsc/tests/Makefile new file mode 100644 index 00000000000..957d17ce1ef --- /dev/null +++ b/reactos/lib/kjs/jsc/tests/Makefile @@ -0,0 +1,223 @@ +# Generated automatically from Makefile.in by configure. +# Makefile.in generated automatically by automake 1.3 from Makefile.am + +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Automakefile for JavaScript compiler tests. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# +# along with this program; see the file COPYING. If not, write to +# the Free Software Foundation, 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# + + +SHELL = /bin/sh + +srcdir = . +top_srcdir = ../.. +prefix = /usr/local/js-0.2.5 +exec_prefix = ${prefix} + +bindir = ${exec_prefix}/bin +sbindir = ${exec_prefix}/sbin +libexecdir = ${exec_prefix}/libexec +datadir = ${prefix}/share +sysconfdir = ${prefix}/etc +sharedstatedir = ${prefix}/com +localstatedir = ${prefix}/var +libdir = ${exec_prefix}/lib +infodir = ${prefix}/info +mandir = ${prefix}/man +includedir = ${prefix}/include +oldincludedir = /usr/include + +DISTDIR = + +pkgdatadir = $(datadir)/js +pkglibdir = $(libdir)/js +pkgincludedir = $(includedir)/js + +top_builddir = ../.. + +ACLOCAL = aclocal +AUTOCONF = autoconf +AUTOMAKE = automake +AUTOHEADER = autoheader + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} +transform = s,x,x, + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = i686-pc-linux-gnu +host_triplet = i686-pc-linux-gnu +ACLOCAL_FLAGS_FOR_LIBTOOL = +CC = gcc +CPP = gcc -E +EXTENSIONS = dl_open.lo xjs.lo xmd5.lo md5c.lo +EXTENSIONS_LIBS = -ldl +INTERPRETER_FEATURES = r_std.lo +LD = /usr/bin/ld +LIBTOOL = $(SHELL) $(top_builddir)/libtool +LN_S = ln -s +MAKEINFO = makeinfo +NM = /usr/bin/nm -B +PACKAGE = js +PGCC_BY_PROVENZANO = +RANLIB = ranlib +U = +VERSION = 0.2.5 +XLC_R_AIX = + +TESTS = compile.test asci.test + +EXTRA_DIST = defs $(TESTS) asci.js +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../../jsconfig.h +CONFIG_CLEAN_FILES = +DIST_COMMON = ChangeLog Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP = --best +all: Makefile + +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps jsc/tests/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = jsc/tests + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done +check-TESTS: $(TESTS) + @failed=0; all=0; \ + srcdir=$(srcdir); export srcdir; \ + for tst in $(TESTS); do \ + if test -f $$tst; then dir=.; \ + else dir="$(srcdir)"; fi; \ + if $(TESTS_ENVIRONMENT) $$dir/$$tst; then \ + all=`expr $$all + 1`; \ + echo "PASS: $$tst"; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="$$failed of $$all tests failed"; \ + fi; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0 +info: +dvi: +check: all + $(MAKE) check-TESTS +installcheck: +install-exec: + @$(NORMAL_INSTALL) + +install-data: + @$(NORMAL_INSTALL) + +install: install-exec install-data all + @: + +uninstall: + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean: mostlyclean-generic + +clean: clean-generic mostlyclean + +distclean: distclean-generic clean + -rm -f config.status + -rm -f libtool + +maintainer-clean: maintainer-clean-generic distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +.PHONY: tags distdir check-TESTS info dvi installcheck install-exec \ +install-data install uninstall all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/reactos/lib/kjs/jsc/tests/Makefile.am b/reactos/lib/kjs/jsc/tests/Makefile.am new file mode 100644 index 00000000000..29266c5dcf1 --- /dev/null +++ b/reactos/lib/kjs/jsc/tests/Makefile.am @@ -0,0 +1,28 @@ +# +# Automakefile for JavaScript compiler tests. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# +# along with this program; see the file COPYING. If not, write to +# the Free Software Foundation, 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# + +TESTS = compile.test asci.test + +EXTRA_DIST = defs $(TESTS) asci.js diff --git a/reactos/lib/kjs/jsc/tests/Makefile.in b/reactos/lib/kjs/jsc/tests/Makefile.in new file mode 100644 index 00000000000..0b10c24f38d --- /dev/null +++ b/reactos/lib/kjs/jsc/tests/Makefile.in @@ -0,0 +1,223 @@ +# Makefile.in generated automatically by automake 1.3 from Makefile.am + +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Automakefile for JavaScript compiler tests. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# +# along with this program; see the file COPYING. If not, write to +# the Free Software Foundation, 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# + + +SHELL = /bin/sh + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DISTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = ../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_FLAGS_FOR_LIBTOOL = @ACLOCAL_FLAGS_FOR_LIBTOOL@ +CC = @CC@ +CPP = @CPP@ +EXTENSIONS = @EXTENSIONS@ +EXTENSIONS_LIBS = @EXTENSIONS_LIBS@ +INTERPRETER_FEATURES = @INTERPRETER_FEATURES@ +LD = @LD@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +NM = @NM@ +PACKAGE = @PACKAGE@ +PGCC_BY_PROVENZANO = @PGCC_BY_PROVENZANO@ +RANLIB = @RANLIB@ +U = @U@ +VERSION = @VERSION@ +XLC_R_AIX = @XLC_R_AIX@ + +TESTS = compile.test asci.test + +EXTRA_DIST = defs $(TESTS) asci.js +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../../jsconfig.h +CONFIG_CLEAN_FILES = +DIST_COMMON = ChangeLog Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP = --best +all: Makefile + +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps jsc/tests/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = jsc/tests + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done +check-TESTS: $(TESTS) + @failed=0; all=0; \ + srcdir=$(srcdir); export srcdir; \ + for tst in $(TESTS); do \ + if test -f $$tst; then dir=.; \ + else dir="$(srcdir)"; fi; \ + if $(TESTS_ENVIRONMENT) $$dir/$$tst; then \ + all=`expr $$all + 1`; \ + echo "PASS: $$tst"; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="$$failed of $$all tests failed"; \ + fi; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0 +info: +dvi: +check: all + $(MAKE) check-TESTS +installcheck: +install-exec: + @$(NORMAL_INSTALL) + +install-data: + @$(NORMAL_INSTALL) + +install: install-exec install-data all + @: + +uninstall: + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean: mostlyclean-generic + +clean: clean-generic mostlyclean + +distclean: distclean-generic clean + -rm -f config.status + -rm -f libtool + +maintainer-clean: maintainer-clean-generic distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +.PHONY: tags distdir check-TESTS info dvi installcheck install-exec \ +install-data install uninstall all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/reactos/lib/kjs/jsc/tests/asci.js b/reactos/lib/kjs/jsc/tests/asci.js new file mode 100644 index 00000000000..d4f97efaad4 --- /dev/null +++ b/reactos/lib/kjs/jsc/tests/asci.js @@ -0,0 +1,44 @@ +function t1 () +{ + 1 +} + +function t2 () +{ + return +} + +function t3 () +{ + return a + b +} + +function t4 () +{ + return + a + b +} + +function t5 () +{ + i + ++i; +} + +function t6 () +{ + i + --i; +} + +t3 () + +{ 1 + 2 } 3 + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/jsc/tests/asci.test b/reactos/lib/kjs/jsc/tests/asci.test new file mode 100755 index 00000000000..0497ba40507 --- /dev/null +++ b/reactos/lib/kjs/jsc/tests/asci.test @@ -0,0 +1,32 @@ +#!/bin/sh +# +# Test the automatic semicolon insertion. +# + +. $srcdir/defs || exit 1 + +ascifiles="asci.js" + +name="asci.test" + +# First, create the state 1 compiler. + +rm -f jsc.js + +for i in $jscsources; do + cat $srcdir/../$i >> jsc.js +done + +echo "$name: creating the state 1 compiler" +$js -Wall -O2 -c jsc.js +mv jsc.jsc stage1.jsc + +# Now, compile our asci test source files with the state 1 compiler. + +for i in $ascifiles; do + $js --load stage1.jsc --file $srcdir/../bs.js $srcdir/$i +done + +# Finally, cleanup. + +rm -f a.jas a.jsc jsc.js stage1.jsc diff --git a/reactos/lib/kjs/jsc/tests/compile.test b/reactos/lib/kjs/jsc/tests/compile.test new file mode 100755 index 00000000000..7544c78e862 --- /dev/null +++ b/reactos/lib/kjs/jsc/tests/compile.test @@ -0,0 +1,50 @@ +#!/bin/sh +# +# Compile the compiler source a couple of times. +# + +. $srcdir/defs || exit 1 + +name="compile.test" + +# First, create the compiler source file. + +rm -f jsc.js + +for i in $jscsources; do + cat $srcdir/../$i >> jsc.js +done + +# Second, compile the source to the stage one compiler. + +echo "$name: creating the stage 1 compiler" +$js -Wall -O2 -c jsc.js +mv jsc.jsc stage1.jsc + +# Third, compile the stage two compiler with our new compiler. + +echo "$name: creating the stage 2 compiler" +$js --load stage1.jsc --file $srcdir/../bs.js jsc.js +mv a.jsc stage2.jsc + +# Fourth, compile stage three compiler. + +echo "$name: creating the stage 3 compiler" +$js --load stage2.jsc --file $srcdir/../bs.js jsc.js +mv a.jsc stage3.jsc + +# Fifth, cleanup. + +rm -f a.jas jsc.js stage1.jsc + +# Finally, check that stage2.jsc and stage3.jsc do not differ. If +# they do, the there is something seriously broken. + +cmp stage2.jsc stage3.jsc || { + rm -f stage2.jsc stage3.jsc + echo "error: the stage 2 and stage 3 compilers differ" + exit 1 +} + +# All ok. +rm -f stage2.jsc stage3.jsc diff --git a/reactos/lib/kjs/jsc/tests/defs b/reactos/lib/kjs/jsc/tests/defs new file mode 100755 index 00000000000..de68aba0938 --- /dev/null +++ b/reactos/lib/kjs/jsc/tests/defs @@ -0,0 +1,15 @@ +#!/bin/sh +# +# Definitions for the JavaScript compiler testing environment. +# + +jscsources="defs.js lexer.js parser.js gram.js namespace.js \ + streams.js asm.js entry.js" + +js="../../src/js" + +# Check that $srcdir is set correctly. +test -f $srcdir/defs || { + echo "defs: installation error" 1>&2 + exit 1 +} diff --git a/reactos/lib/kjs/jsconfig.h.in b/reactos/lib/kjs/jsconfig.h.in new file mode 100644 index 00000000000..cc801a94e08 --- /dev/null +++ b/reactos/lib/kjs/jsconfig.h.in @@ -0,0 +1,167 @@ +/* jsconfig.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _ALL_SOURCE +#undef _ALL_SOURCE +#endif + +/* Define if using alloca.c. */ +#undef C_ALLOCA + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. + This function is required for alloca.c support on those systems. */ +#undef CRAY_STACKSEG_END + +/* Define if you have alloca, as a function or macro. */ +#undef HAVE_ALLOCA + +/* Define if you have and it should be used (not on Ultrix). */ +#undef HAVE_ALLOCA_H + +/* Define as __inline if that's what the C compiler calls it. */ +#undef inline + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown + */ +#undef STACK_DIRECTION + +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* + * Define the PACKAGE and VERSION only if they are undefined. This means + * that we do not redefine them, when the library is used in another + * GNU like package that defines PACKAGE and VERSION. + */ + +/* Package name. */ +#ifndef PACKAGE +#undef PACKAGE +#endif /* no PACKAGE */ + +/* Version number. */ +#ifndef VERSION +#undef VERSION +#endif /* no VERSION */ + +/* Are C prototypes supported. */ +#undef PROTOTYPES + +/* Canonical host name and its parts. */ +#undef CANONICAL_HOST +#undef CANONICAL_HOST_CPU +#undef CANONICAL_HOST_VENDOR +#undef CANONICAL_HOST_OS + +/* Do we want to build all instruction dispatchers? */ +#undef ALL_DISPATCHERS + +/* Do we want to profile byte-code operands. */ +#undef PROFILING + +/* Do we want the byte-code operand hooks. */ +#undef BC_OPERAND_HOOKS + +/* + * Unconditionall disable the jumps byte-code instruction dispatch + * method. + */ +#undef DISABLE_JUMPS + +/* Does the struct stat has st_blksize member? */ +#undef HAVE_STAT_ST_ST_BLKSIZE + +/* Does the struct stat has st_blocks member? */ +#undef HAVE_STAT_ST_ST_BLOCKS + +/* Does the asctime_r() function take three arguments. */ +#undef ASCTIME_R_WITH_THREE_ARGS + +/* Does the drand48_r() work with DRAND48D data. */ +#undef DRAND48_R_WITH_DRAND48D + +/* How the attribute structures are passed to the init functions. */ +#undef CONDATTR_BY_VALUE +#undef MUTEXATTR_BY_VALUE +#undef THREADATTR_BY_VALUE + +/* JS */ +#undef WITH_JS + +/* Curses. */ +#undef WITH_CURSES +#undef HAVE_CURSES_H +#undef HAVE_NCURSES_H + +/* MD5 */ +#undef WITH_MD5 + +/* The number of bytes in a int. */ +#undef SIZEOF_INT + +/* The number of bytes in a long. */ +#undef SIZEOF_LONG + +/* Define if you have the drand48 function. */ +#undef HAVE_DRAND48 + +/* Define if you have the lstat function. */ +#undef HAVE_LSTAT + +/* Define if you have the pthread_attr_create function. */ +#undef HAVE_PTHREAD_ATTR_CREATE + +/* Define if you have the pthread_attr_setscope function. */ +#undef HAVE_PTHREAD_ATTR_SETSCOPE + +/* Define if you have the pthread_attr_setstacksize function. */ +#undef HAVE_PTHREAD_ATTR_SETSTACKSIZE + +/* Define if you have the pthread_condattr_create function. */ +#undef HAVE_PTHREAD_CONDATTR_CREATE + +/* Define if you have the pthread_condattr_init function. */ +#undef HAVE_PTHREAD_CONDATTR_INIT + +/* Define if you have the pthread_mutexattr_create function. */ +#undef HAVE_PTHREAD_MUTEXATTR_CREATE + +/* Define if you have the sleep function. */ +#undef HAVE_SLEEP + +/* Define if you have the srand48 function. */ +#undef HAVE_SRAND48 + +/* Define if you have the usleep function. */ +#undef HAVE_USLEEP + +/* Define if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define if you have the header file. */ +#undef HAVE_ERRNO_H + +/* Define if you have the header file. */ +#undef HAVE_FLOAT_H + +/* Define if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define if you have the header file. */ +#undef HAVE_STRING_H + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H diff --git a/reactos/lib/kjs/jsdas/ChangeLog b/reactos/lib/kjs/jsdas/ChangeLog new file mode 100644 index 00000000000..8150769cbe4 --- /dev/null +++ b/reactos/lib/kjs/jsdas/ChangeLog @@ -0,0 +1,61 @@ +1998-10-26 Markku Rossi + + * extract-op-names.js (main): Fixed to use the flags comments in + the operands.def file. + +1998-09-01 Markku Rossi + + * bc.js (ByteCode$parse): Added a more verbose error message for + cases when the byte-code file is truncated. + +1998-08-25 Markku Rossi + + * bc.js (ByteCode$prettyPrintString): Added support for some + missing character escapes. + +1998-08-14 Markku Rossi + + * bc.js: Added support for the regular expression constants. + +1998-06-08 Markku Rossi + + * Changed all character constants to the new #'f' format. + +1998-05-27 Markku Rossi + + * jsdas.1: Documented the command line options. + +1998-05-25 Markku Rossi + + * main.js (main): Added option -S, --strip to remove the debug + section. + +1998-05-14 Markku Rossi + + * bc.js (ByteCode$printCode): Added support for the `try_push' + operand. + +1998-05-12 Markku Rossi + + * jsdas.1: Initial version of the manual page. + +1998-05-11 Markku Rossi + + * bc.js (ByteCode$printCode): Added support for the + `delete_property' operand. + +1998-05-08 Markku Rossi + + * bc.js: Cleaned up the byte-code file handling. + (ByteCode$printCode): Implemented byte-code printing. + Implemented byte-code file mutators: linkSection(), + removeSection() and write(). + +1998-05-07 Markku Rossi + + * Re-organized the das directory. Now the JavaScript disassembler + is built automatically with the `all' target. It is a + `bin_SCRIPTS' target so it gets installed when the JavaScript + package is installed. The makefile also makes the `jsdasm' an + executable and it sets the `js' interpreter command to the first + line of the compiled `jsdasm' program. diff --git a/reactos/lib/kjs/jsdas/Makefile b/reactos/lib/kjs/jsdas/Makefile new file mode 100644 index 00000000000..01b230a2aaf --- /dev/null +++ b/reactos/lib/kjs/jsdas/Makefile @@ -0,0 +1,290 @@ +# Generated automatically from Makefile.in by configure. +# Makefile.in generated automatically by automake 1.3 from Makefile.am + +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Automakefile for JavaScript disassembler. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + + +SHELL = /bin/sh + +srcdir = . +top_srcdir = .. +prefix = /usr/local/js-0.2.5 +exec_prefix = ${prefix} + +bindir = ${exec_prefix}/bin +sbindir = ${exec_prefix}/sbin +libexecdir = ${exec_prefix}/libexec +datadir = ${prefix}/share +sysconfdir = ${prefix}/etc +sharedstatedir = ${prefix}/com +localstatedir = ${prefix}/var +libdir = ${exec_prefix}/lib +infodir = ${prefix}/info +mandir = ${prefix}/man +includedir = ${prefix}/include +oldincludedir = /usr/include + +DISTDIR = + +pkgdatadir = $(datadir)/js +pkglibdir = $(libdir)/js +pkgincludedir = $(includedir)/js + +top_builddir = .. + +ACLOCAL = aclocal +AUTOCONF = autoconf +AUTOMAKE = automake +AUTOHEADER = autoheader + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} +transform = s,x,x, + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = i686-pc-linux-gnu +host_triplet = i686-pc-linux-gnu +ACLOCAL_FLAGS_FOR_LIBTOOL = +CC = gcc +CPP = gcc -E +EXTENSIONS = dl_open.lo xjs.lo xmd5.lo md5c.lo +EXTENSIONS_LIBS = -ldl +INTERPRETER_FEATURES = r_std.lo +LD = /usr/bin/ld +LIBTOOL = $(SHELL) $(top_builddir)/libtool +LN_S = ln -s +MAKEINFO = makeinfo +NM = /usr/bin/nm -B +PACKAGE = js +PGCC_BY_PROVENZANO = +RANLIB = ranlib +U = +VERSION = 0.2.5 +XLC_R_AIX = + +JSCOMPILER = ../src/js +JSCOMPILER_FLAGS = -Wpedantic -O2 -g + +JSS = bc.js operands.js main.js +JSCS = bc.jsc operands.jsc main.jsc + +EXTRA_DIST = $(JSS) extract-op-names.js jsdas.1 + +man_MANS = jsdas.1 + +bin_SCRIPTS = jsdas + +CLEANFILES = jsdas $(JSCS) + +SUFFIXES = .jsc .js +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../jsconfig.h +CONFIG_CLEAN_FILES = +SCRIPTS = $(bin_SCRIPTS) + +man1dir = $(mandir)/man1 +MANS = $(man_MANS) + +NROFF = nroff +DIST_COMMON = ChangeLog Makefile.am Makefile.in TODO + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP = --best +all: Makefile $(SCRIPTS) $(MANS) + +.SUFFIXES: +.SUFFIXES: .js .jsc +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps jsdas/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +install-binSCRIPTS: $(bin_SCRIPTS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_SCRIPTS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ + $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + else if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ + $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + else :; fi; fi; \ + done + +uninstall-binSCRIPTS: + @$(NORMAL_UNINSTALL) + list='$(bin_SCRIPTS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + done + +install-man1: + $(mkinstalldirs) $(DESTDIR)$(man1dir) + @list='$(man1_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \ + done + +uninstall-man1: + @list='$(man1_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \ + rm -f $(DESTDIR)$(man1dir)/$$inst; \ + done +install-man: $(MANS) + @$(NORMAL_INSTALL) + $(MAKE) install-man1 +uninstall-man: + @$(NORMAL_UNINSTALL) + $(MAKE) uninstall-man1 +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = jsdas + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done +info: +dvi: +check: all + $(MAKE) +installcheck: +install-exec: install-binSCRIPTS + @$(NORMAL_INSTALL) + +install-data: install-man + @$(NORMAL_INSTALL) + +install: install-exec install-data all + @: + +uninstall: uninstall-binSCRIPTS uninstall-man + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: + $(mkinstalldirs) $(DATADIR)$(bindir) $(DESTDIR)$(mandir)/man1 + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean: mostlyclean-generic + +clean: clean-generic mostlyclean + +distclean: distclean-generic clean + -rm -f config.status + -rm -f libtool + +maintainer-clean: maintainer-clean-generic distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +.PHONY: uninstall-binSCRIPTS install-binSCRIPTS install-man1 \ +uninstall-man1 install-man uninstall-man tags distdir info dvi \ +installcheck install-exec install-data install uninstall all \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +compile: $(JSCS) + +jsdas: $(JSS) + rm -f $@.js + for i in $(JSS); do cat $(srcdir)/$$i >> $@.js; done + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -c $@.js + echo "#!$(bindir)/js --file" > $@ +# echo "#!$(JSCOMPILER) --file" > $@ + cat $@.jsc >> $@ + chmod a+x $@ + +.js.jsc: + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -c $< + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/reactos/lib/kjs/jsdas/Makefile.am b/reactos/lib/kjs/jsdas/Makefile.am new file mode 100644 index 00000000000..b957a6f46b9 --- /dev/null +++ b/reactos/lib/kjs/jsdas/Makefile.am @@ -0,0 +1,53 @@ +# +# Automakefile for JavaScript disassembler. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + +JSCOMPILER = ../src/js +JSCOMPILER_FLAGS = -Wpedantic -O2 -g + +JSS = bc.js operands.js main.js +JSCS = bc.jsc operands.jsc main.jsc + +EXTRA_DIST = $(JSS) extract-op-names.js jsdas.1 + +man_MANS = jsdas.1 + +bin_SCRIPTS = jsdas + +compile: $(JSCS) + +jsdas: $(JSS) + rm -f $@.js + for i in $(JSS); do cat $(srcdir)/$$i >> $@.js; done + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -c $@.js + echo "#!$(bindir)/js --file" > $@ +# echo "#!$(JSCOMPILER) --file" > $@ + cat $@.jsc >> $@ + chmod a+x $@ + +CLEANFILES = jsdas $(JSCS) + +SUFFIXES = .jsc .js + +.js.jsc: + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -c $< diff --git a/reactos/lib/kjs/jsdas/Makefile.in b/reactos/lib/kjs/jsdas/Makefile.in new file mode 100644 index 00000000000..62feac181b9 --- /dev/null +++ b/reactos/lib/kjs/jsdas/Makefile.in @@ -0,0 +1,290 @@ +# Makefile.in generated automatically by automake 1.3 from Makefile.am + +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Automakefile for JavaScript disassembler. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + + +SHELL = /bin/sh + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DISTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_FLAGS_FOR_LIBTOOL = @ACLOCAL_FLAGS_FOR_LIBTOOL@ +CC = @CC@ +CPP = @CPP@ +EXTENSIONS = @EXTENSIONS@ +EXTENSIONS_LIBS = @EXTENSIONS_LIBS@ +INTERPRETER_FEATURES = @INTERPRETER_FEATURES@ +LD = @LD@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +NM = @NM@ +PACKAGE = @PACKAGE@ +PGCC_BY_PROVENZANO = @PGCC_BY_PROVENZANO@ +RANLIB = @RANLIB@ +U = @U@ +VERSION = @VERSION@ +XLC_R_AIX = @XLC_R_AIX@ + +JSCOMPILER = ../src/js +JSCOMPILER_FLAGS = -Wpedantic -O2 -g + +JSS = bc.js operands.js main.js +JSCS = bc.jsc operands.jsc main.jsc + +EXTRA_DIST = $(JSS) extract-op-names.js jsdas.1 + +man_MANS = jsdas.1 + +bin_SCRIPTS = jsdas + +CLEANFILES = jsdas $(JSCS) + +SUFFIXES = .jsc .js +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../jsconfig.h +CONFIG_CLEAN_FILES = +SCRIPTS = $(bin_SCRIPTS) + +man1dir = $(mandir)/man1 +MANS = $(man_MANS) + +NROFF = nroff +DIST_COMMON = ChangeLog Makefile.am Makefile.in TODO + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP = --best +all: Makefile $(SCRIPTS) $(MANS) + +.SUFFIXES: +.SUFFIXES: .js .jsc +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps jsdas/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +install-binSCRIPTS: $(bin_SCRIPTS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_SCRIPTS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ + $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + else if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ + $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + else :; fi; fi; \ + done + +uninstall-binSCRIPTS: + @$(NORMAL_UNINSTALL) + list='$(bin_SCRIPTS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + done + +install-man1: + $(mkinstalldirs) $(DESTDIR)$(man1dir) + @list='$(man1_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \ + done + +uninstall-man1: + @list='$(man1_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \ + rm -f $(DESTDIR)$(man1dir)/$$inst; \ + done +install-man: $(MANS) + @$(NORMAL_INSTALL) + $(MAKE) install-man1 +uninstall-man: + @$(NORMAL_UNINSTALL) + $(MAKE) uninstall-man1 +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = jsdas + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done +info: +dvi: +check: all + $(MAKE) +installcheck: +install-exec: install-binSCRIPTS + @$(NORMAL_INSTALL) + +install-data: install-man + @$(NORMAL_INSTALL) + +install: install-exec install-data all + @: + +uninstall: uninstall-binSCRIPTS uninstall-man + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: + $(mkinstalldirs) $(DATADIR)$(bindir) $(DESTDIR)$(mandir)/man1 + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean: mostlyclean-generic + +clean: clean-generic mostlyclean + +distclean: distclean-generic clean + -rm -f config.status + -rm -f libtool + +maintainer-clean: maintainer-clean-generic distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +.PHONY: uninstall-binSCRIPTS install-binSCRIPTS install-man1 \ +uninstall-man1 install-man uninstall-man tags distdir info dvi \ +installcheck install-exec install-data install uninstall all \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +compile: $(JSCS) + +jsdas: $(JSS) + rm -f $@.js + for i in $(JSS); do cat $(srcdir)/$$i >> $@.js; done + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -c $@.js + echo "#!$(bindir)/js --file" > $@ +# echo "#!$(JSCOMPILER) --file" > $@ + cat $@.jsc >> $@ + chmod a+x $@ + +.js.jsc: + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -c $< + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/reactos/lib/kjs/jsdas/TODO b/reactos/lib/kjs/jsdas/TODO new file mode 100644 index 00000000000..fdaf8b53ea4 --- /dev/null +++ b/reactos/lib/kjs/jsdas/TODO @@ -0,0 +1,5 @@ + + TODO JavaScript Disassembler + ============================ + +* option --extract to save contents of a section to file diff --git a/reactos/lib/kjs/jsdas/bc.js b/reactos/lib/kjs/jsdas/bc.js new file mode 100644 index 00000000000..e6e1c3b5d57 --- /dev/null +++ b/reactos/lib/kjs/jsdas/bc.js @@ -0,0 +1,619 @@ +/* + * Byte-code file handling. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsdas/bc.js,v $ + * $Id: bc.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +function ByteCode$SymtabEntry (name, offset) +{ + this.name = name; + this.offset = offset; +} + + +function ByteCode () +{ + /* Private methods. */ + this.sectionName = ByteCode$sectionName; + this.lookupSection = ByteCode$lookupSection; + this.parseConstants = ByteCode$parseConstants; + this.parseSymtab = ByteCode$parseSymtab; + this.prettyPrintString = ByteCode$prettyPrintString; + this.opIsSymbol = ByteCode$opIsSymbol; + this.opIsJump = ByteCode$opIsJump; + + /* Public methods. */ + this.parse = ByteCode$parse; + this.write = ByteCode$write; + this.printInfo = ByteCode$printInfo; + this.printCode = ByteCode$printCode; + this.printConstants = ByteCode$printConstants; + this.printSymtab = ByteCode$printSymtab; + this.printDebug = ByteCode$printDebug; + this.linkSection = ByteCode$linkSection; + this.removeSection = ByteCode$removeSection; +} + + +function ByteCode$sectionName (type) +{ + var name = type.toString (); + + if (type == JSC$BC_SECT_CODE) + name += " (code)"; + else if (type == JSC$BC_SECT_CONSTANTS) + name += " (constants)"; + else if (type == JSC$BC_SECT_SYMTAB) + name += " (symtab)"; + else if (type == JSC$BC_SECT_DEBUG) + name += " (debug)"; + + return name; +} + + +function ByteCode$lookupSection (sect) +{ + var i; + for (i = 0; i < this.sect_types.length; i++) + if (this.sect_types[i] == sect) + return this.sect_data[i]; + + System.print ("jsdas: no section ", this.sectionName (sect), "\n"); + return false; +} + + +function ByteCode$parseConstants () +{ + if (this.constants) + return this.constants; + + var data = this.lookupSection (JSC$BC_SECT_CONSTANTS); + if (!data) + return false; + + this.constants = new Array (); + var pos, count = 0; + for (pos = 0; pos < data.length; count++) + { + var type = data[pos++]; + var val; + + if (type == JSC$CONST_INT) + { + val = data.substr (pos, 4).unpack ("N")[0]; + pos += 4; + } + else if (type == JSC$CONST_STRING) + { + var len = data.substr (pos, 4).unpack ("N")[0]; + pos += 4; + + val = "\"" + data.substr (pos, len); + pos += len; + } + else if (type == JSC$CONST_FLOAT) + { + val = data.substr (pos, 8).unpack ("d")[0]; + pos += 8; + } + else if (type == JSC$CONST_SYMBOL) + { + val = new String ("S"); + for (; data[pos] != #'\0'; pos++) + val.append (data.charAt (pos)); + pos++; + } + else if (type == JSC$CONST_NAN) + { + val = parseFloat ("****"); + } + else if (type == JSC$CONST_REGEXP) + { + var flags = data.substr (pos, 1).unpack ("C")[0]; + pos++; + + var len = data.substr (pos, 4).unpack ("N")[0]; + pos += 4; + + val = "/" + File.byteToString (flags) + data.substr (pos, len); + pos += len; + } + else + { + /* Unknown constant type. */ + this.constants = false; + return false; + } + + this.constants[count] = val; + } + + return this.constants; +} + + +function ByteCode$parseSymtab () +{ + if (this.symtab) + return this.symtab; + + var data = this.lookupSection (JSC$BC_SECT_SYMTAB); + if (!data) + return false; + + this.symtab = new Array (); + + /* Fetch the number of symtab entries. */ + var nentries = data.unpack ("N")[0]; + + var pos, count = 0; + for (pos = 4; pos < data.length; count++) + { + /* Read the symbol name. */ + var name = new String (""); + for (; data[pos] != #'\0'; pos++) + name.append (data.charAt (pos)); + pos++; + + /* Read the offset. */ + var offset = data.substr (pos, 4).unpack ("N")[0]; + pos += 4; + + this.symtab.push (new ByteCode$SymtabEntry (name, offset)); + } + + if (count != nentries) + System.print ("jsdas: warning: expected ", nentries, + " symtab entries, but got ", count, "\n"); + + return this.symtab; +} + + +function ByteCode$prettyPrintString (str) +{ + var i; + var tail = ""; + var ender; + + /* Determine the type. */ + if (str[0] == #'"') + { + i = 1; + ender = "\""; + } + else + { + /* Regexp. */ + var flags = str[1]; + ender = "/"; + + if (flags & JSC$CONST_REGEXP_FLAG_G) + tail += "g"; + if (flags & JSC$CONST_REGEXP_FLAG_I) + tail += "i"; + + i = 2; + } + + System.print (ender); + for (; i < str.length; i++) + { + if (str[i] == ender[0] || str[i] == #'\\') + System.print ("\\" + str.charAt (i)); + else if (str[i] == #'\n') + System.print ("\\n"); + else if (str[i] == #'\t') + System.print ("\\t"); + else if (str[i] == #'\v') + System.print ("\\v"); + else if (str[i] == #'\b') + System.print ("\\b"); + else if (str[i] == #'\r') + System.print ("\\r"); + else if (str[i] == #'\f') + System.print ("\\f"); + else if (str[i] == #'\a') + System.print ("\\a"); + else if (str[i] == #'\'') + System.print ("\\\'"); + else if (str[i] == #'\"') + System.print ("\\\""); + else + System.print (str.charAt (i)); + } + System.print (ender, tail); +} + +function ByteCode$opIsSymbol (op) +{ + return (DASM$op_flags[op] & 0x01) != 0; +} + +function ByteCode$opIsJump (op) +{ + return (DASM$op_flags[op] & 0x02) != 0; +} + + +function ByteCode$parse (stream) +{ + var ch; + var buf; + + ch = stream.readByte (); + if (ch == #'#') + { + if (stream.readByte () != #'!') + return false; + + /* Skip the first comment line. */ + this.first_line = "#!" + stream.readln (); + } + else + { + stream.ungetByte (ch); + this.first_line = false; + } + + buf = stream.read (4); + if (buf.length != 4) + return false; + + var a = buf.unpack ("N"); + if (a[0] != JSC$BC_MAGIC) + { + System.print ("jsdas: illegal magic: ", a[0].toString (16), + ", should be: ", JSC$BC_MAGIC.toString (16), "\n"); + return false; + } + + buf = stream.read (4); + if (buf.length != 4) + return false; + + var num_sections = buf.unpack ("N")[0]; + this.sect_types = new Array (); + this.sect_data = new Array (); + + /* Read sections. */ + for (i = 0; i < num_sections; i++) + { + /* Type and length. */ + buf = stream.read (8); + if (buf.length != 8) + return false; + + a = buf.unpack ("NN"); + + this.sect_types[i] = a[0]; + + var len = a[1]; + buf = stream.read (len); + if (buf.length != len) + { + System.stdout.writeln ("couldn't read section " + i.toString () + + ", expected=" + len.toString () + + ", got=" + buf.length.toString ()); + return false; + } + + this.sect_data[i] = buf; + } + + return true; +} + + +function ByteCode$printInfo () +{ + var i; + + for (i = 0; i < this.sect_types.length; i++) + { + var sectname = this.sectionName (this.sect_types[i]); + System.print (" section ", i, ": "); + System.print ("type=", sectname); + System.print (", length=", this.sect_data[i].length, "\n"); + } +} + + +function ByteCode$printConstants () +{ + if (!this.parseConstants ()) + { + System.print ("jsdas: couldn't find a parse the constants section\n"); + return; + } + + var i; + for (i = 0; i < this.constants.length; i++) + { + System.print (" ", i, ":\t"); + + var c = this.constants[i]; + if (typeof c == "number") + System.print (c); + else if (typeof c == "string") + { + /* Must be a string, regexp or symbol. */ + if (c[0] == #'S') + /* Symbol. */ + System.print (c.substr (1)); + else + this.prettyPrintString (c); + } + else + { + System.print ("jsdas: illegal element in the constans array: type=", + typeof c, "\n"); + return; + } + + System.print ("\n"); + } +} + + +function ByteCode$printSymtab () +{ + var symtab = this.parseSymtab (); + if (!symtab) + { + System.print ("jsdas: couldn't find or parse symtab section\n"); + return; + } + + var i; + for (i = 0; i < symtab.length; i++) + { + var name = symtab[i].name; + var offset = symtab[i].offset; + + System.print (" ", name); + + var pad = name.length; + for (; pad < 40; pad++) + System.print (" "); + + System.print (offset, "\n"); + } +} + + +function ByteCode$printDebug () +{ + var data = this.lookupSection (JSC$BC_SECT_DEBUG); + if (!data) + return; + + var pos, count = 0; + var filename = ""; + for (pos = 0; pos < data.length; count++) + { + var type = data[pos++]; + + if (type == JSC$DEBUG_FILENAME) + { + var len = data.substr (pos, 4).unpack ("N")[0]; + pos += 4; + + filename = data.substr (pos, len); + pos += len; + } + else if (type == JSC$DEBUG_LINENUMBER) + { + var a = data.substr (pos, 8).unpack ("NN"); + pos += 8; + + System.print (" ", a[0], "\t", filename, ":", a[1], "\n"); + } + else + { + System.print ("jsdas: unknown debug entry: ", + "skipping all remaining data\n"); + return; + } + } +} + + +function ByteCode$printCode () +{ + var data = this.lookupSection (JSC$BC_SECT_CODE); + if (!data) + return; + + var consts = this.parseConstants (); + if (!consts) + { + System.print ("jsdas: couldn't find or parse constants\n"); + return; + } + + var symtab = this.parseSymtab (); + if (!symtab) + { + System.print ("jsdas: couldn't find or parse symtab\n"); + return; + } + + var symtab_pos = -1; + var next_symtab_offset = -1; + + var pos; + for (pos = 0; pos < data.length; ) + { + /* Handle symtab entries. */ + if (pos >= next_symtab_offset) + { + while (pos > next_symtab_offset) + { + /* Lookup the next offset. */ + symtab_pos++; + if (symtab_pos >= symtab.length) + next_symtab_offset = data.length + 1; + else + next_symtab_offset = symtab[symtab_pos].offset; + } + + if (pos == next_symtab_offset) + System.print (pos == 0 ? "" : "\n", + symtab[symtab_pos].name, ":\n"); + } + + System.print (" ", pos, "\t"); + + var op = data[pos++]; + if (!DASM$op_names[op]) + { + System.print ("jsdas: unknown operand: ", + "skipping all remaining data\n"); + return; + } + + System.print (DASM$op_names[op], "\t"); + if (DASM$op_names[op].length < 8) + System.print ("\t"); + + var ds = DASM$op_data[op]; + var val; + + if (ds == 1) + val = data[pos]; + else if (ds == 2) + val = data.substr (pos, 2).unpack ("n")[0]; + else if (ds == 4) + val = data.substr (pos, 4).unpack ("N")[0]; + + if (op == JSC$OP_CONST || this.opIsSymbol (op)) + { + /* Handle symbols and constants. */ + + var c = consts[val]; + if (typeof c == "string") + { + if (c[0] == #'S') + System.print (c.substr (1)); + else + this.prettyPrintString (c); + } + else + System.print (c); + } + else if (this.opIsJump (op)) + { + /* Local jumps. */ + val += pos + ds; + System.print (val); + } + else + { + /* Handle all the rest. */ + if (ds != 0) + System.print (val); + } + + pos += ds; + + System.print ("\n"); + } +} + + +function ByteCode$linkSection (type, data) +{ + var i; + for (i = 0; i < this.sect_types.length; i++) + if (this.sect_types[i] == type) + { + this.sect_data[i] = data; + return; + } + + /* Create a new section. */ + this.sect_types.push (type); + this.sect_data.push (data); +} + + +function ByteCode$removeSection (type) +{ + var i; + for (i = 0; i < this.sect_types.length; i++) + if (this.sect_types[i] == type) + { + /* Found it. */ + this.sect_types.splice (i, 1); + this.sect_data.splice (i, 1); + return true; + } + + return false; +} + + +function ByteCode$write (name) +{ + var fp = new File (name); + if (fp.open ("w")) + { + /* Possible first line. */ + if (this.first_line) + fp.writeln (this.first_line); + + /* Magic. */ + fp.write (String.pack ("N", JSC$BC_MAGIC)); + + /* Number of sections. */ + fp.write (String.pack ("N", this.sect_types.length)); + + var i; + for (i = 0; i < this.sect_types.length; i++) + { + /* Write type and the length of the section. */ + fp.write (String.pack ("NN", this.sect_types[i], + this.sect_data[i].length)); + + /* Write the data. */ + fp.write (this.sect_data[i]); + } + + return fp.close (); + } + + return false; +} + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/jsdas/extract-op-names.js b/reactos/lib/kjs/jsdas/extract-op-names.js new file mode 100755 index 00000000000..4c03d461a00 --- /dev/null +++ b/reactos/lib/kjs/jsdas/extract-op-names.js @@ -0,0 +1,117 @@ +#!../src/js +/* + * Extract byte-code operand names from the operands.def file. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsdas/extract-op-names.js,v $ + * $Id: extract-op-names.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +source = "../src/operands.def"; +target = "operands.js"; + +op_re = new RegExp ("\ +^operand[ \t]+([a-zA-Z_][a-zA-Z0-9_]*)[ \t]+([^ \t]+)[ \t]+{(.*)"); + +function main () +{ + var ifp = new File (source); + var ofp = new File (target); + var count = 0; + + if (ifp.open ("r")) + { + if (ofp.open ("w")) + { + header (ofp); + + while (!ifp.eof ()) + { + var line = ifp.readln (); + if (op_re.test (line)) + operand (ofp, RegExp.$1, RegExp.$2, RegExp.$3, count++); + } + + ofp.close (); + } + else + { + ifp.close (); + System.error ("Couldn't create target file `", target, "':", + System.strerror (System.errno), "\n"); + System.exit (1); + } + + ifp.close (); + } + else + { + System.error ("Couldn't open source file `", source, "':", + System.strerror (System.errno), "\n"); + System.exit (1); + } +} + +function header (fp) +{ + fp.write ("\ +/* -*- c -*- + * Operand definitions for the JavaScript byte-code. + * + * This file is automatically create from the operands.def file. + * Editing is strongly discouraged. You should edit the file + * `extract-op-names.js' instead. + */ + +DASM$op_names = new Array (); +DASM$op_data = new Array (); +DASM$op_flags = new Array (); +"); +} + + +function operand (ofp, name, data, flags, count) +{ + var f = 0; + + if (/symbol/.test (flags)) + f |= 0x01; + if (/jump/.test (flags)) + f |= 0x02; + + ofp.write ("\ +DASM$op_names[" + count.toString () + "]\t= \"" + name + "\"; +DASM$op_data[" + count.toString () + "] \t= " + data + "; +DASM$op_flags[" + count.toString () + "] \t= 0x" + f.toString (16) + "; +"); +} + +main (); + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/jsdas/jsdas.1 b/reactos/lib/kjs/jsdas/jsdas.1 new file mode 100644 index 00000000000..4f9ab0a495a --- /dev/null +++ b/reactos/lib/kjs/jsdas/jsdas.1 @@ -0,0 +1,83 @@ +.\" +.\" Manual page for the js disassembler. +.\" Copyright (c) 1998 New Generation Software (NGS) Oy +.\" Author: Markku Rossi +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; either version 2, or (at your option) +.\" any later version. +.\" +.\" This program 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 General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; see the file COPYING. If not, write to +.\" the Free Software Foundation, 59 Temple Place - Suite 330, +.\" Boston, MA 02111-1307, USA. +.\" +.TH JSDAS 1 "May 27, 1998" "JSDAS" "JSDAS" + +.SH NAME +jsdas \- disassemble and manipulate JavaScript byte\-code files + +.SH SYNOPSIS +.B jsdas +[\f3\-cCdhisSV\f1] +[\f3\-l \f2type\f1 \f2data\f1] +[\f3\-r \f2type\f1] +\f2file\f1... + +.SH DESCRIPTION + +The \f3jsdas\f1 program is a disassembler and a manipulator for the +JavaScript byte\-code files. The program can be used to view, +disassemble and manipulate the byte\-code files. + +.SH OPTIONS + +.TP 8 +.B \-c, \-\-code +Print the code section of the byte\-code files. This is the default +action that is preformed if no options are given for the \f3jsdas\f1 +program. +.TP 8 +.B \-C, \-\-constants +Print the constants section of the byte\-code file. +.TP 8 +.B \-d, \-\-debug +Print the debug section of the byte\-code file. +.TP 8 +.B \-h, \-\-help +Print a short help message that describes the options that can be given +to the \f3jsdas\f1 program. +.TP 8 +.B \-i, \-\-info +Print the byte\-code file information. +.TP 8 +.B \-l \f2type\f3 \f2data\f3, \-\-link \f2type\f3 \f2data\f3 +Link a new section to the byte\-code file. The section's type is +\f2type\f1 and its contents is read from file \f2data\f1. +.TP 8 +.B \-r \f2type\f3, \-\-remove \f2type\f3 +Remove section of type \f2type\f1 from the byte\-code files. +.TP 8 +.B \-s, \-\-symtab +Print the symbol table section of the byte\-code file. +.TP 8 +.B \-S, \-\-strip +Remove the debug section from the byte\-code files. +.TP 8 +.B \-V, \-\-version +Print the version number of the \f3jsdas\f1 program. + + +.SH AUTHOR +Markku Rossi + +NGS JavaScript WWW home page: + +.SH SEE ALSO +js(1) diff --git a/reactos/lib/kjs/jsdas/jsdas.js b/reactos/lib/kjs/jsdas/jsdas.js new file mode 100644 index 00000000000..f38ee7d548d --- /dev/null +++ b/reactos/lib/kjs/jsdas/jsdas.js @@ -0,0 +1,1253 @@ +/* + * Byte-code file handling. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsdas/jsdas.js,v $ + * $Id: jsdas.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +function ByteCode$SymtabEntry (name, offset) +{ + this.name = name; + this.offset = offset; +} + + +function ByteCode () +{ + /* Private methods. */ + this.sectionName = ByteCode$sectionName; + this.lookupSection = ByteCode$lookupSection; + this.parseConstants = ByteCode$parseConstants; + this.parseSymtab = ByteCode$parseSymtab; + this.prettyPrintString = ByteCode$prettyPrintString; + this.opIsSymbol = ByteCode$opIsSymbol; + this.opIsJump = ByteCode$opIsJump; + + /* Public methods. */ + this.parse = ByteCode$parse; + this.write = ByteCode$write; + this.printInfo = ByteCode$printInfo; + this.printCode = ByteCode$printCode; + this.printConstants = ByteCode$printConstants; + this.printSymtab = ByteCode$printSymtab; + this.printDebug = ByteCode$printDebug; + this.linkSection = ByteCode$linkSection; + this.removeSection = ByteCode$removeSection; +} + + +function ByteCode$sectionName (type) +{ + var name = type.toString (); + + if (type == JSC$BC_SECT_CODE) + name += " (code)"; + else if (type == JSC$BC_SECT_CONSTANTS) + name += " (constants)"; + else if (type == JSC$BC_SECT_SYMTAB) + name += " (symtab)"; + else if (type == JSC$BC_SECT_DEBUG) + name += " (debug)"; + + return name; +} + + +function ByteCode$lookupSection (sect) +{ + var i; + for (i = 0; i < this.sect_types.length; i++) + if (this.sect_types[i] == sect) + return this.sect_data[i]; + + System.print ("jsdas: no section ", this.sectionName (sect), "\n"); + return false; +} + + +function ByteCode$parseConstants () +{ + if (this.constants) + return this.constants; + + var data = this.lookupSection (JSC$BC_SECT_CONSTANTS); + if (!data) + return false; + + this.constants = new Array (); + var pos, count = 0; + for (pos = 0; pos < data.length; count++) + { + var type = data[pos++]; + var val; + + if (type == JSC$CONST_INT) + { + val = data.substr (pos, 4).unpack ("N")[0]; + pos += 4; + } + else if (type == JSC$CONST_STRING) + { + var len = data.substr (pos, 4).unpack ("N")[0]; + pos += 4; + + val = "\"" + data.substr (pos, len); + pos += len; + } + else if (type == JSC$CONST_FLOAT) + { + val = data.substr (pos, 8).unpack ("d")[0]; + pos += 8; + } + else if (type == JSC$CONST_SYMBOL) + { + val = new String ("S"); + for (; data[pos] != #'\0'; pos++) + val.append (data.charAt (pos)); + pos++; + } + else if (type == JSC$CONST_NAN) + { + val = parseFloat ("****"); + } + else if (type == JSC$CONST_REGEXP) + { + var flags = data.substr (pos, 1).unpack ("C")[0]; + pos++; + + var len = data.substr (pos, 4).unpack ("N")[0]; + pos += 4; + + val = "/" + File.byteToString (flags) + data.substr (pos, len); + pos += len; + } + else + { + /* Unknown constant type. */ + this.constants = false; + return false; + } + + this.constants[count] = val; + } + + return this.constants; +} + + +function ByteCode$parseSymtab () +{ + if (this.symtab) + return this.symtab; + + var data = this.lookupSection (JSC$BC_SECT_SYMTAB); + if (!data) + return false; + + this.symtab = new Array (); + + /* Fetch the number of symtab entries. */ + var nentries = data.unpack ("N")[0]; + + var pos, count = 0; + for (pos = 4; pos < data.length; count++) + { + /* Read the symbol name. */ + var name = new String (""); + for (; data[pos] != #'\0'; pos++) + name.append (data.charAt (pos)); + pos++; + + /* Read the offset. */ + var offset = data.substr (pos, 4).unpack ("N")[0]; + pos += 4; + + this.symtab.push (new ByteCode$SymtabEntry (name, offset)); + } + + if (count != nentries) + System.print ("jsdas: warning: expected ", nentries, + " symtab entries, but got ", count, "\n"); + + return this.symtab; +} + + +function ByteCode$prettyPrintString (str) +{ + var i; + var tail = ""; + var ender; + + /* Determine the type. */ + if (str[0] == #'"') + { + i = 1; + ender = "\""; + } + else + { + /* Regexp. */ + var flags = str[1]; + ender = "/"; + + if (flags & JSC$CONST_REGEXP_FLAG_G) + tail += "g"; + if (flags & JSC$CONST_REGEXP_FLAG_I) + tail += "i"; + + i = 2; + } + + System.print (ender); + for (; i < str.length; i++) + { + if (str[i] == ender[0] || str[i] == #'\\') + System.print ("\\" + str.charAt (i)); + else if (str[i] == #'\n') + System.print ("\\n"); + else if (str[i] == #'\t') + System.print ("\\t"); + else if (str[i] == #'\v') + System.print ("\\v"); + else if (str[i] == #'\b') + System.print ("\\b"); + else if (str[i] == #'\r') + System.print ("\\r"); + else if (str[i] == #'\f') + System.print ("\\f"); + else if (str[i] == #'\a') + System.print ("\\a"); + else if (str[i] == #'\'') + System.print ("\\\'"); + else if (str[i] == #'\"') + System.print ("\\\""); + else + System.print (str.charAt (i)); + } + System.print (ender, tail); +} + +function ByteCode$opIsSymbol (op) +{ + return (DASM$op_flags[op] & 0x01) != 0; +} + +function ByteCode$opIsJump (op) +{ + return (DASM$op_flags[op] & 0x02) != 0; +} + + +function ByteCode$parse (stream) +{ + var ch; + var buf; + + ch = stream.readByte (); + if (ch == #'#') + { + if (stream.readByte () != #'!') + return false; + + /* Skip the first comment line. */ + this.first_line = "#!" + stream.readln (); + } + else + { + stream.ungetByte (ch); + this.first_line = false; + } + + buf = stream.read (4); + if (buf.length != 4) + return false; + + var a = buf.unpack ("N"); + if (a[0] != JSC$BC_MAGIC) + { + System.print ("jsdas: illegal magic: ", a[0].toString (16), + ", should be: ", JSC$BC_MAGIC.toString (16), "\n"); + return false; + } + + buf = stream.read (4); + if (buf.length != 4) + return false; + + var num_sections = buf.unpack ("N")[0]; + this.sect_types = new Array (); + this.sect_data = new Array (); + + /* Read sections. */ + for (i = 0; i < num_sections; i++) + { + /* Type and length. */ + buf = stream.read (8); + if (buf.length != 8) + return false; + + a = buf.unpack ("NN"); + + this.sect_types[i] = a[0]; + + var len = a[1]; + buf = stream.read (len); + if (buf.length != len) + { + System.stdout.writeln ("couldn't read section " + i.toString () + + ", expected=" + len.toString () + + ", got=" + buf.length.toString ()); + return false; + } + + this.sect_data[i] = buf; + } + + return true; +} + + +function ByteCode$printInfo () +{ + var i; + + for (i = 0; i < this.sect_types.length; i++) + { + var sectname = this.sectionName (this.sect_types[i]); + System.print (" section ", i, ": "); + System.print ("type=", sectname); + System.print (", length=", this.sect_data[i].length, "\n"); + } +} + + +function ByteCode$printConstants () +{ + if (!this.parseConstants ()) + { + System.print ("jsdas: couldn't find a parse the constants section\n"); + return; + } + + var i; + for (i = 0; i < this.constants.length; i++) + { + System.print (" ", i, ":\t"); + + var c = this.constants[i]; + if (typeof c == "number") + System.print (c); + else if (typeof c == "string") + { + /* Must be a string, regexp or symbol. */ + if (c[0] == #'S') + /* Symbol. */ + System.print (c.substr (1)); + else + this.prettyPrintString (c); + } + else + { + System.print ("jsdas: illegal element in the constans array: type=", + typeof c, "\n"); + return; + } + + System.print ("\n"); + } +} + + +function ByteCode$printSymtab () +{ + var symtab = this.parseSymtab (); + if (!symtab) + { + System.print ("jsdas: couldn't find or parse symtab section\n"); + return; + } + + var i; + for (i = 0; i < symtab.length; i++) + { + var name = symtab[i].name; + var offset = symtab[i].offset; + + System.print (" ", name); + + var pad = name.length; + for (; pad < 40; pad++) + System.print (" "); + + System.print (offset, "\n"); + } +} + + +function ByteCode$printDebug () +{ + var data = this.lookupSection (JSC$BC_SECT_DEBUG); + if (!data) + return; + + var pos, count = 0; + var filename = ""; + for (pos = 0; pos < data.length; count++) + { + var type = data[pos++]; + + if (type == JSC$DEBUG_FILENAME) + { + var len = data.substr (pos, 4).unpack ("N")[0]; + pos += 4; + + filename = data.substr (pos, len); + pos += len; + } + else if (type == JSC$DEBUG_LINENUMBER) + { + var a = data.substr (pos, 8).unpack ("NN"); + pos += 8; + + System.print (" ", a[0], "\t", filename, ":", a[1], "\n"); + } + else + { + System.print ("jsdas: unknown debug entry: ", + "skipping all remaining data\n"); + return; + } + } +} + + +function ByteCode$printCode () +{ + var data = this.lookupSection (JSC$BC_SECT_CODE); + if (!data) + return; + + var consts = this.parseConstants (); + if (!consts) + { + System.print ("jsdas: couldn't find or parse constants\n"); + return; + } + + var symtab = this.parseSymtab (); + if (!symtab) + { + System.print ("jsdas: couldn't find or parse symtab\n"); + return; + } + + var symtab_pos = -1; + var next_symtab_offset = -1; + + var pos; + for (pos = 0; pos < data.length; ) + { + /* Handle symtab entries. */ + if (pos >= next_symtab_offset) + { + while (pos > next_symtab_offset) + { + /* Lookup the next offset. */ + symtab_pos++; + if (symtab_pos >= symtab.length) + next_symtab_offset = data.length + 1; + else + next_symtab_offset = symtab[symtab_pos].offset; + } + + if (pos == next_symtab_offset) + System.print (pos == 0 ? "" : "\n", + symtab[symtab_pos].name, ":\n"); + } + + System.print (" ", pos, "\t"); + + var op = data[pos++]; + if (!DASM$op_names[op]) + { + System.print ("jsdas: unknown operand: ", + "skipping all remaining data\n"); + return; + } + + System.print (DASM$op_names[op], "\t"); + if (DASM$op_names[op].length < 8) + System.print ("\t"); + + var ds = DASM$op_data[op]; + var val; + + if (ds == 1) + val = data[pos]; + else if (ds == 2) + val = data.substr (pos, 2).unpack ("n")[0]; + else if (ds == 4) + val = data.substr (pos, 4).unpack ("N")[0]; + + if (op == JSC$OP_CONST || this.opIsSymbol (op)) + { + /* Handle symbols and constants. */ + + var c = consts[val]; + if (typeof c == "string") + { + if (c[0] == #'S') + System.print (c.substr (1)); + else + this.prettyPrintString (c); + } + else + System.print (c); + } + else if (this.opIsJump (op)) + { + /* Local jumps. */ + val += pos + ds; + System.print (val); + } + else + { + /* Handle all the rest. */ + if (ds != 0) + System.print (val); + } + + pos += ds; + + System.print ("\n"); + } +} + + +function ByteCode$linkSection (type, data) +{ + var i; + for (i = 0; i < this.sect_types.length; i++) + if (this.sect_types[i] == type) + { + this.sect_data[i] = data; + return; + } + + /* Create a new section. */ + this.sect_types.push (type); + this.sect_data.push (data); +} + + +function ByteCode$removeSection (type) +{ + var i; + for (i = 0; i < this.sect_types.length; i++) + if (this.sect_types[i] == type) + { + /* Found it. */ + this.sect_types.splice (i, 1); + this.sect_data.splice (i, 1); + return true; + } + + return false; +} + + +function ByteCode$write (name) +{ + var fp = new File (name); + if (fp.open ("w")) + { + /* Possible first line. */ + if (this.first_line) + fp.writeln (this.first_line); + + /* Magic. */ + fp.write (String.pack ("N", JSC$BC_MAGIC)); + + /* Number of sections. */ + fp.write (String.pack ("N", this.sect_types.length)); + + var i; + for (i = 0; i < this.sect_types.length; i++) + { + /* Write type and the length of the section. */ + fp.write (String.pack ("NN", this.sect_types[i], + this.sect_data[i].length)); + + /* Write the data. */ + fp.write (this.sect_data[i]); + } + + return fp.close (); + } + + return false; +} + + +/* +Local variables: +mode: c +End: +*/ +/* -*- c -*- + * Operand definitions for the JavaScript byte-code. + * + * This file is automatically create from the operands.def file. + * Editing is strongly discouraged. You should edit the file + * `extract-op-names.js' instead. + */ + +DASM$op_names = new Array (); +DASM$op_data = new Array (); +DASM$op_flags = new Array (); +DASM$op_names[0] = "halt"; +DASM$op_data[0] = 0; +DASM$op_flags[0] = 0x0; +DASM$op_names[1] = "done"; +DASM$op_data[1] = 0; +DASM$op_flags[1] = 0x0; +DASM$op_names[2] = "nop"; +DASM$op_data[2] = 0; +DASM$op_flags[2] = 0x0; +DASM$op_names[3] = "dup"; +DASM$op_data[3] = 0; +DASM$op_flags[3] = 0x0; +DASM$op_names[4] = "pop"; +DASM$op_data[4] = 0; +DASM$op_flags[4] = 0x0; +DASM$op_names[5] = "pop_n"; +DASM$op_data[5] = 1; +DASM$op_flags[5] = 0x0; +DASM$op_names[6] = "apop"; +DASM$op_data[6] = 1; +DASM$op_flags[6] = 0x0; +DASM$op_names[7] = "swap"; +DASM$op_data[7] = 0; +DASM$op_flags[7] = 0x0; +DASM$op_names[8] = "roll"; +DASM$op_data[8] = 1; +DASM$op_flags[8] = 0x0; +DASM$op_names[9] = "const"; +DASM$op_data[9] = 4; +DASM$op_flags[9] = 0x0; +DASM$op_names[10] = "const_null"; +DASM$op_data[10] = 0; +DASM$op_flags[10] = 0x0; +DASM$op_names[11] = "const_true"; +DASM$op_data[11] = 0; +DASM$op_flags[11] = 0x0; +DASM$op_names[12] = "const_false"; +DASM$op_data[12] = 0; +DASM$op_flags[12] = 0x0; +DASM$op_names[13] = "const_undefined"; +DASM$op_data[13] = 0; +DASM$op_flags[13] = 0x0; +DASM$op_names[14] = "const_i0"; +DASM$op_data[14] = 0; +DASM$op_flags[14] = 0x0; +DASM$op_names[15] = "const_i1"; +DASM$op_data[15] = 0; +DASM$op_flags[15] = 0x0; +DASM$op_names[16] = "const_i2"; +DASM$op_data[16] = 0; +DASM$op_flags[16] = 0x0; +DASM$op_names[17] = "const_i3"; +DASM$op_data[17] = 0; +DASM$op_flags[17] = 0x0; +DASM$op_names[18] = "const_i"; +DASM$op_data[18] = 4; +DASM$op_flags[18] = 0x0; +DASM$op_names[19] = "load_global"; +DASM$op_data[19] = 4; +DASM$op_flags[19] = 0x1; +DASM$op_names[20] = "store_global"; +DASM$op_data[20] = 4; +DASM$op_flags[20] = 0x1; +DASM$op_names[21] = "load_arg"; +DASM$op_data[21] = 1; +DASM$op_flags[21] = 0x0; +DASM$op_names[22] = "store_arg"; +DASM$op_data[22] = 1; +DASM$op_flags[22] = 0x0; +DASM$op_names[23] = "load_local"; +DASM$op_data[23] = 2; +DASM$op_flags[23] = 0x0; +DASM$op_names[24] = "store_local"; +DASM$op_data[24] = 2; +DASM$op_flags[24] = 0x0; +DASM$op_names[25] = "load_property"; +DASM$op_data[25] = 4; +DASM$op_flags[25] = 0x1; +DASM$op_names[26] = "store_property"; +DASM$op_data[26] = 4; +DASM$op_flags[26] = 0x1; +DASM$op_names[27] = "load_array"; +DASM$op_data[27] = 0; +DASM$op_flags[27] = 0x0; +DASM$op_names[28] = "store_array"; +DASM$op_data[28] = 0; +DASM$op_flags[28] = 0x0; +DASM$op_names[29] = "nth"; +DASM$op_data[29] = 0; +DASM$op_flags[29] = 0x0; +DASM$op_names[30] = "cmp_eq"; +DASM$op_data[30] = 0; +DASM$op_flags[30] = 0x0; +DASM$op_names[31] = "cmp_ne"; +DASM$op_data[31] = 0; +DASM$op_flags[31] = 0x0; +DASM$op_names[32] = "cmp_lt"; +DASM$op_data[32] = 0; +DASM$op_flags[32] = 0x0; +DASM$op_names[33] = "cmp_gt"; +DASM$op_data[33] = 0; +DASM$op_flags[33] = 0x0; +DASM$op_names[34] = "cmp_le"; +DASM$op_data[34] = 0; +DASM$op_flags[34] = 0x0; +DASM$op_names[35] = "cmp_ge"; +DASM$op_data[35] = 0; +DASM$op_flags[35] = 0x0; +DASM$op_names[36] = "cmp_seq"; +DASM$op_data[36] = 0; +DASM$op_flags[36] = 0x0; +DASM$op_names[37] = "cmp_sne"; +DASM$op_data[37] = 0; +DASM$op_flags[37] = 0x0; +DASM$op_names[38] = "sub"; +DASM$op_data[38] = 0; +DASM$op_flags[38] = 0x0; +DASM$op_names[39] = "add"; +DASM$op_data[39] = 0; +DASM$op_flags[39] = 0x0; +DASM$op_names[40] = "mul"; +DASM$op_data[40] = 0; +DASM$op_flags[40] = 0x0; +DASM$op_names[41] = "div"; +DASM$op_data[41] = 0; +DASM$op_flags[41] = 0x0; +DASM$op_names[42] = "mod"; +DASM$op_data[42] = 0; +DASM$op_flags[42] = 0x0; +DASM$op_names[43] = "neg"; +DASM$op_data[43] = 0; +DASM$op_flags[43] = 0x0; +DASM$op_names[44] = "and"; +DASM$op_data[44] = 0; +DASM$op_flags[44] = 0x0; +DASM$op_names[45] = "not"; +DASM$op_data[45] = 0; +DASM$op_flags[45] = 0x0; +DASM$op_names[46] = "or"; +DASM$op_data[46] = 0; +DASM$op_flags[46] = 0x0; +DASM$op_names[47] = "xor"; +DASM$op_data[47] = 0; +DASM$op_flags[47] = 0x0; +DASM$op_names[48] = "shift_left"; +DASM$op_data[48] = 0; +DASM$op_flags[48] = 0x0; +DASM$op_names[49] = "shift_right"; +DASM$op_data[49] = 0; +DASM$op_flags[49] = 0x0; +DASM$op_names[50] = "shift_rright"; +DASM$op_data[50] = 0; +DASM$op_flags[50] = 0x0; +DASM$op_names[51] = "iffalse"; +DASM$op_data[51] = 4; +DASM$op_flags[51] = 0x2; +DASM$op_names[52] = "iftrue"; +DASM$op_data[52] = 4; +DASM$op_flags[52] = 0x2; +DASM$op_names[53] = "call_method"; +DASM$op_data[53] = 4; +DASM$op_flags[53] = 0x1; +DASM$op_names[54] = "jmp"; +DASM$op_data[54] = 4; +DASM$op_flags[54] = 0x2; +DASM$op_names[55] = "jsr"; +DASM$op_data[55] = 0; +DASM$op_flags[55] = 0x0; +DASM$op_names[56] = "return"; +DASM$op_data[56] = 0; +DASM$op_flags[56] = 0x0; +DASM$op_names[57] = "typeof"; +DASM$op_data[57] = 0; +DASM$op_flags[57] = 0x0; +DASM$op_names[58] = "new"; +DASM$op_data[58] = 0; +DASM$op_flags[58] = 0x0; +DASM$op_names[59] = "delete_property"; +DASM$op_data[59] = 4; +DASM$op_flags[59] = 0x1; +DASM$op_names[60] = "delete_array"; +DASM$op_data[60] = 0; +DASM$op_flags[60] = 0x0; +DASM$op_names[61] = "locals"; +DASM$op_data[61] = 2; +DASM$op_flags[61] = 0x0; +DASM$op_names[62] = "min_args"; +DASM$op_data[62] = 1; +DASM$op_flags[62] = 0x0; +DASM$op_names[63] = "load_nth_arg"; +DASM$op_data[63] = 0; +DASM$op_flags[63] = 0x0; +DASM$op_names[64] = "with_push"; +DASM$op_data[64] = 0; +DASM$op_flags[64] = 0x0; +DASM$op_names[65] = "with_pop"; +DASM$op_data[65] = 1; +DASM$op_flags[65] = 0x0; +DASM$op_names[66] = "try_push"; +DASM$op_data[66] = 4; +DASM$op_flags[66] = 0x2; +DASM$op_names[67] = "try_pop"; +DASM$op_data[67] = 1; +DASM$op_flags[67] = 0x0; +DASM$op_names[68] = "throw"; +DASM$op_data[68] = 0; +DASM$op_flags[68] = 0x0; +DASM$op_names[69] = "iffalse_b"; +DASM$op_data[69] = 4; +DASM$op_flags[69] = 0x2; +DASM$op_names[70] = "iftrue_b"; +DASM$op_data[70] = 4; +DASM$op_flags[70] = 0x2; +DASM$op_names[71] = "add_1_i"; +DASM$op_data[71] = 0; +DASM$op_flags[71] = 0x0; +DASM$op_names[72] = "add_2_i"; +DASM$op_data[72] = 0; +DASM$op_flags[72] = 0x0; +DASM$op_names[73] = "load_global_w"; +DASM$op_data[73] = 4; +DASM$op_flags[73] = 0x1; +DASM$op_names[74] = "jsr_w"; +DASM$op_data[74] = 4; +DASM$op_flags[74] = 0x1; +/* + * Disassembler for JavaScript byte-code files. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsdas/jsdas.js,v $ + * $Id: jsdas.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * Variables and definitions. + */ + +version_number = "0.0.1"; + +/* + * Options. + */ + +/* + * -c, --code + * + * Print code section. + */ + +opt_code = false; + +/* + * -C, --constants + * + * Print constants section. + */ + +opt_constants = false; + +/* + * -d, --debug + * + * Print the debug section. + */ + +opt_debug = false; + +/* + * -h, --help + * + * Print short help and exit successfully. + */ + +/* + * -i, --info + * + * Show general information about the file. + */ + +opt_info = false; + +/* + * -l TYPE DATA, --link TYPE DATA + * + * Link a new section to the byte-code file. The new section's type is + * TYPE and its data is in file DATA. + */ + +opt_link = false; +opt_link_type = 0; +opt_link_data = ""; + +/* + * -r TYPE, --remove TYPE + * + * Remove section TYPE. + */ + +opt_remove = false; +opt_remove_type = 0; + +/* + * -s, --symtab + * + * Print symtab section. + */ + +opt_symtab = false; + +/* + * -S, --strip + * + * Remove the debug section from byte-code files. + */ + +/* + * -V, --version + * + * Print version information and exit successfully. + */ + + +/* + * Functions. + */ + +function main () +{ + var opt_default = true; + + var idx = ARGS[0].lastIndexOf ("/"); + if (idx >= 0) + program = ARGS[0].substr (idx + 1); + else + program = ARGS[0]; + + /* Handle arguments. */ + var i; + for (i = 1; i < ARGS.length; i++) + { + if (ARGS[i][0] == #'-') + { + if (ARGS[i] == "-c" || ARGS[i] == "--code") + { + opt_code = true; + opt_default = false; + } + else if (ARGS[i] == "-C" || ARGS[i] == "--constants") + { + opt_constants = true; + opt_default = false; + } + else if (ARGS[i] == "-d" || ARGS[i] == "--debug") + { + opt_debug = true; + opt_default = false; + } + else if (ARGS[i] == "-i" || ARGS[i] == "--info") + { + opt_info = true; + opt_default = false; + } + else if (ARGS[i] == "-l" || ARGS[i] == "--link") + { + opt_link = true; + opt_default = false; + + if (i + 2 >= ARGS.length) + { + System.error (program, ": no arguments for option --link\n"); + System.exit (1); + } + + opt_link_type = parseInt (ARGS[++i]); + if (isNaN (opt_link_type)) + { + System.error (program, ": illegal section type `", + ARGS[i], "'\n"); + System.exit (1); + } + opt_link_data = (ARGS[++i]); + } + else if (ARGS[i] == "-r" || ARGS[i] == "--remove") + { + opt_remove = true; + opt_default = false; + + if (i + 1 >= ARGS.length) + { + System.error (program, + ": no arguments for option --remove\n"); + System.exit (1); + } + + opt_remove_type = parseInt (ARGS[++i]); + if (isNaN (opt_remove_type)) + { + System.error (program, ": illegal section type `", + ARGS[i], "'\n"); + System.exit (1); + } + } + else if (ARGS[i] == "-s" || ARGS[i] == "--symtab") + { + opt_symtab = true; + opt_default = false; + } + else if (ARGS[i] == "-S" || ARGS[i] == "--strip") + { + opt_remove = true; + opt_default = false; + opt_remove_type = JSC$BC_SECT_DEBUG; + } + else if (ARGS[i] == "-h" || ARGS[i] == "--help") + { + usage (); + System.exit (0); + } + else if (ARGS[i] == "-V" || ARGS[i] == "--version") + { + version (); + System.exit (0); + } + else + { + /* Unrecognized option. */ + System.error (program, ": unrecognized option `", + ARGS[i], "'\n"); + System.error ("Try `", program, + " --help' for more information.\n"); + System.exit (1); + } + } + else + { + /* End of arguments. */ + break; + } + } + + if (i >= ARGS.length) + { + System.error (program, ": no files specified\n"); + System.exit (1); + } + + /* Process files. */ + var first = true; + for (; i < ARGS.length; i++) + { + if (first) + first = false; + else + System.print ("\n"); + + System.print (ARGS[i], ":\n"); + var is = new File (ARGS[i]); + if (is.open ("r")) + { + var bc = new ByteCode (); + var result = bc.parse (is); + is.close (); + + if (!result) + System.print (program, ": couldn't parse byte-code file `", + ARGS[i], "'\n"); + else + { + var write_back = false; + + if (opt_info) + { + System.print ("\n* byte-code file information\n\n"); + bc.printInfo (); + } + + if (opt_constants) + { + System.print ("\n* section `Constants'\n\n"); + bc.printConstants (); + } + + if (opt_default || opt_code) + { + System.print ("\n* section `Code'\n\n"); + bc.printCode (); + } + + if (opt_symtab) + { + System.print ("\n* section `Symtab'\n\n"); + bc.printSymtab (); + } + + if (opt_debug) + { + System.print ("\n* section `Debug'\n\n"); + bc.printDebug (); + } + + if (opt_link) + { + var df = new File (opt_link_data); + if (df.open ("r")) + { + var len = df.getLength (); + var data = df.read (len); + df.close (); + + if (data.length < len) + System.error (program, + ": couldn't read data from file `", + opt_link_data, "': ", + System.strerror (System.errno), "\n"); + else + { + System.print (program, ": linking ", data.length, + " bytes of data to section ", + opt_link_type.toString (), "\n"); + bc.linkSection (opt_link_type, data); + write_back = true; + } + } + else + System.error (program, ": couldn't open data file `", + opt_link_data, "': ", + System.strerror (System.errno), "\n"); + } + + if (opt_remove) + { + System.print (program, ": removing section ", + opt_remove_type, "\n"); + if (bc.removeSection (opt_remove_type)) + write_back = true; + } + + if (write_back) + { + /* Write the byte-code file back to its original file. */ + if (!bc.write (ARGS[i])) + { + System.error (program, ": write failed: ", + System.strerror (System.errno), + "\n"); + System.exit (1); + } + } + } + } + else + System.error (program, ": couldn't open bc file `", ARGS[i], "': ", + System.strerror (System.errno), "\n"); + } +} + + +function usage () +{ + System.print ("\ +Usage: ", program, " [OPTION]... FILE...\n\ +Mandatory arguments to long options are mandatory for short options too.\n"); + + System.print ("\ + -c, --code print code section (default)\n\ + -C, --constants print constants section\n\ + -d, --debug print debug section\n\ + -h, --help print this help and exit\n\ + -i, --info print the byte-code file header and general\n\ + information about the sections\n\ + -l, --link TYPE DATA link data from file DATA to section TYPE\n\ + -r, --remove TYPE remove section TYPE\n\ + -s, --symtab print symtab section\n\ + -S, --strip remove debug section\n\ + -V, --version print version number\n\ +"); + + System.print ("\nReport bugs to mtr@ngs.fi.\n"); +} + + +function version () +{ + System.print ("NGS JavaScript disassembler ", version_number, "\n"); + System.print ("\ +Copyright (C) 1998 New Generation Software (NGS) Oy.\n\ +NGS JavaScript Interpreter comes with NO WARRANTY, to the extent\n\ +permitted by law. You may redistribute copies of NGS JavaScript\n\ +Interpreter under the terms of the GNU Library General Public License.\n\ +For more information about these matters, see the files named COPYING.\n\ +"); +} + + +main (); + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/jsdas/main.js b/reactos/lib/kjs/jsdas/main.js new file mode 100644 index 00000000000..9f2acd44c21 --- /dev/null +++ b/reactos/lib/kjs/jsdas/main.js @@ -0,0 +1,398 @@ +/* + * Disassembler for JavaScript byte-code files. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsdas/main.js,v $ + * $Id: main.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * Variables and definitions. + */ + +version_number = "0.0.1"; + +/* + * Options. + */ + +/* + * -c, --code + * + * Print code section. + */ + +opt_code = false; + +/* + * -C, --constants + * + * Print constants section. + */ + +opt_constants = false; + +/* + * -d, --debug + * + * Print the debug section. + */ + +opt_debug = false; + +/* + * -h, --help + * + * Print short help and exit successfully. + */ + +/* + * -i, --info + * + * Show general information about the file. + */ + +opt_info = false; + +/* + * -l TYPE DATA, --link TYPE DATA + * + * Link a new section to the byte-code file. The new section's type is + * TYPE and its data is in file DATA. + */ + +opt_link = false; +opt_link_type = 0; +opt_link_data = ""; + +/* + * -r TYPE, --remove TYPE + * + * Remove section TYPE. + */ + +opt_remove = false; +opt_remove_type = 0; + +/* + * -s, --symtab + * + * Print symtab section. + */ + +opt_symtab = false; + +/* + * -S, --strip + * + * Remove the debug section from byte-code files. + */ + +/* + * -V, --version + * + * Print version information and exit successfully. + */ + + +/* + * Functions. + */ + +function main () +{ + var opt_default = true; + + var idx = ARGS[0].lastIndexOf ("/"); + if (idx >= 0) + program = ARGS[0].substr (idx + 1); + else + program = ARGS[0]; + + /* Handle arguments. */ + var i; + for (i = 1; i < ARGS.length; i++) + { + if (ARGS[i][0] == #'-') + { + if (ARGS[i] == "-c" || ARGS[i] == "--code") + { + opt_code = true; + opt_default = false; + } + else if (ARGS[i] == "-C" || ARGS[i] == "--constants") + { + opt_constants = true; + opt_default = false; + } + else if (ARGS[i] == "-d" || ARGS[i] == "--debug") + { + opt_debug = true; + opt_default = false; + } + else if (ARGS[i] == "-i" || ARGS[i] == "--info") + { + opt_info = true; + opt_default = false; + } + else if (ARGS[i] == "-l" || ARGS[i] == "--link") + { + opt_link = true; + opt_default = false; + + if (i + 2 >= ARGS.length) + { + System.error (program, ": no arguments for option --link\n"); + System.exit (1); + } + + opt_link_type = parseInt (ARGS[++i]); + if (isNaN (opt_link_type)) + { + System.error (program, ": illegal section type `", + ARGS[i], "'\n"); + System.exit (1); + } + opt_link_data = (ARGS[++i]); + } + else if (ARGS[i] == "-r" || ARGS[i] == "--remove") + { + opt_remove = true; + opt_default = false; + + if (i + 1 >= ARGS.length) + { + System.error (program, + ": no arguments for option --remove\n"); + System.exit (1); + } + + opt_remove_type = parseInt (ARGS[++i]); + if (isNaN (opt_remove_type)) + { + System.error (program, ": illegal section type `", + ARGS[i], "'\n"); + System.exit (1); + } + } + else if (ARGS[i] == "-s" || ARGS[i] == "--symtab") + { + opt_symtab = true; + opt_default = false; + } + else if (ARGS[i] == "-S" || ARGS[i] == "--strip") + { + opt_remove = true; + opt_default = false; + opt_remove_type = JSC$BC_SECT_DEBUG; + } + else if (ARGS[i] == "-h" || ARGS[i] == "--help") + { + usage (); + System.exit (0); + } + else if (ARGS[i] == "-V" || ARGS[i] == "--version") + { + version (); + System.exit (0); + } + else + { + /* Unrecognized option. */ + System.error (program, ": unrecognized option `", + ARGS[i], "'\n"); + System.error ("Try `", program, + " --help' for more information.\n"); + System.exit (1); + } + } + else + { + /* End of arguments. */ + break; + } + } + + if (i >= ARGS.length) + { + System.error (program, ": no files specified\n"); + System.exit (1); + } + + /* Process files. */ + var first = true; + for (; i < ARGS.length; i++) + { + if (first) + first = false; + else + System.print ("\n"); + + System.print (ARGS[i], ":\n"); + var is = new File (ARGS[i]); + if (is.open ("r")) + { + var bc = new ByteCode (); + var result = bc.parse (is); + is.close (); + + if (!result) + System.print (program, ": couldn't parse byte-code file `", + ARGS[i], "'\n"); + else + { + var write_back = false; + + if (opt_info) + { + System.print ("\n* byte-code file information\n\n"); + bc.printInfo (); + } + + if (opt_constants) + { + System.print ("\n* section `Constants'\n\n"); + bc.printConstants (); + } + + if (opt_default || opt_code) + { + System.print ("\n* section `Code'\n\n"); + bc.printCode (); + } + + if (opt_symtab) + { + System.print ("\n* section `Symtab'\n\n"); + bc.printSymtab (); + } + + if (opt_debug) + { + System.print ("\n* section `Debug'\n\n"); + bc.printDebug (); + } + + if (opt_link) + { + var df = new File (opt_link_data); + if (df.open ("r")) + { + var len = df.getLength (); + var data = df.read (len); + df.close (); + + if (data.length < len) + System.error (program, + ": couldn't read data from file `", + opt_link_data, "': ", + System.strerror (System.errno), "\n"); + else + { + System.print (program, ": linking ", data.length, + " bytes of data to section ", + opt_link_type.toString (), "\n"); + bc.linkSection (opt_link_type, data); + write_back = true; + } + } + else + System.error (program, ": couldn't open data file `", + opt_link_data, "': ", + System.strerror (System.errno), "\n"); + } + + if (opt_remove) + { + System.print (program, ": removing section ", + opt_remove_type, "\n"); + if (bc.removeSection (opt_remove_type)) + write_back = true; + } + + if (write_back) + { + /* Write the byte-code file back to its original file. */ + if (!bc.write (ARGS[i])) + { + System.error (program, ": write failed: ", + System.strerror (System.errno), + "\n"); + System.exit (1); + } + } + } + } + else + System.error (program, ": couldn't open bc file `", ARGS[i], "': ", + System.strerror (System.errno), "\n"); + } +} + + +function usage () +{ + System.print ("\ +Usage: ", program, " [OPTION]... FILE...\n\ +Mandatory arguments to long options are mandatory for short options too.\n"); + + System.print ("\ + -c, --code print code section (default)\n\ + -C, --constants print constants section\n\ + -d, --debug print debug section\n\ + -h, --help print this help and exit\n\ + -i, --info print the byte-code file header and general\n\ + information about the sections\n\ + -l, --link TYPE DATA link data from file DATA to section TYPE\n\ + -r, --remove TYPE remove section TYPE\n\ + -s, --symtab print symtab section\n\ + -S, --strip remove debug section\n\ + -V, --version print version number\n\ +"); + + System.print ("\nReport bugs to mtr@ngs.fi.\n"); +} + + +function version () +{ + System.print ("NGS JavaScript disassembler ", version_number, "\n"); + System.print ("\ +Copyright (C) 1998 New Generation Software (NGS) Oy.\n\ +NGS JavaScript Interpreter comes with NO WARRANTY, to the extent\n\ +permitted by law. You may redistribute copies of NGS JavaScript\n\ +Interpreter under the terms of the GNU Library General Public License.\n\ +For more information about these matters, see the files named COPYING.\n\ +"); +} + + +main (); + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/jsdas/operands.js b/reactos/lib/kjs/jsdas/operands.js new file mode 100644 index 00000000000..7f48a072f04 --- /dev/null +++ b/reactos/lib/kjs/jsdas/operands.js @@ -0,0 +1,236 @@ +/* -*- c -*- + * Operand definitions for the JavaScript byte-code. + * + * This file is automatically create from the operands.def file. + * Editing is strongly discouraged. You should edit the file + * `extract-op-names.js' instead. + */ + +DASM$op_names = new Array (); +DASM$op_data = new Array (); +DASM$op_flags = new Array (); +DASM$op_names[0] = "halt"; +DASM$op_data[0] = 0; +DASM$op_flags[0] = 0x0; +DASM$op_names[1] = "done"; +DASM$op_data[1] = 0; +DASM$op_flags[1] = 0x0; +DASM$op_names[2] = "nop"; +DASM$op_data[2] = 0; +DASM$op_flags[2] = 0x0; +DASM$op_names[3] = "dup"; +DASM$op_data[3] = 0; +DASM$op_flags[3] = 0x0; +DASM$op_names[4] = "pop"; +DASM$op_data[4] = 0; +DASM$op_flags[4] = 0x0; +DASM$op_names[5] = "pop_n"; +DASM$op_data[5] = 1; +DASM$op_flags[5] = 0x0; +DASM$op_names[6] = "apop"; +DASM$op_data[6] = 1; +DASM$op_flags[6] = 0x0; +DASM$op_names[7] = "swap"; +DASM$op_data[7] = 0; +DASM$op_flags[7] = 0x0; +DASM$op_names[8] = "roll"; +DASM$op_data[8] = 1; +DASM$op_flags[8] = 0x0; +DASM$op_names[9] = "const"; +DASM$op_data[9] = 4; +DASM$op_flags[9] = 0x0; +DASM$op_names[10] = "const_null"; +DASM$op_data[10] = 0; +DASM$op_flags[10] = 0x0; +DASM$op_names[11] = "const_true"; +DASM$op_data[11] = 0; +DASM$op_flags[11] = 0x0; +DASM$op_names[12] = "const_false"; +DASM$op_data[12] = 0; +DASM$op_flags[12] = 0x0; +DASM$op_names[13] = "const_undefined"; +DASM$op_data[13] = 0; +DASM$op_flags[13] = 0x0; +DASM$op_names[14] = "const_i0"; +DASM$op_data[14] = 0; +DASM$op_flags[14] = 0x0; +DASM$op_names[15] = "const_i1"; +DASM$op_data[15] = 0; +DASM$op_flags[15] = 0x0; +DASM$op_names[16] = "const_i2"; +DASM$op_data[16] = 0; +DASM$op_flags[16] = 0x0; +DASM$op_names[17] = "const_i3"; +DASM$op_data[17] = 0; +DASM$op_flags[17] = 0x0; +DASM$op_names[18] = "const_i"; +DASM$op_data[18] = 4; +DASM$op_flags[18] = 0x0; +DASM$op_names[19] = "load_global"; +DASM$op_data[19] = 4; +DASM$op_flags[19] = 0x1; +DASM$op_names[20] = "store_global"; +DASM$op_data[20] = 4; +DASM$op_flags[20] = 0x1; +DASM$op_names[21] = "load_arg"; +DASM$op_data[21] = 1; +DASM$op_flags[21] = 0x0; +DASM$op_names[22] = "store_arg"; +DASM$op_data[22] = 1; +DASM$op_flags[22] = 0x0; +DASM$op_names[23] = "load_local"; +DASM$op_data[23] = 2; +DASM$op_flags[23] = 0x0; +DASM$op_names[24] = "store_local"; +DASM$op_data[24] = 2; +DASM$op_flags[24] = 0x0; +DASM$op_names[25] = "load_property"; +DASM$op_data[25] = 4; +DASM$op_flags[25] = 0x1; +DASM$op_names[26] = "store_property"; +DASM$op_data[26] = 4; +DASM$op_flags[26] = 0x1; +DASM$op_names[27] = "load_array"; +DASM$op_data[27] = 0; +DASM$op_flags[27] = 0x0; +DASM$op_names[28] = "store_array"; +DASM$op_data[28] = 0; +DASM$op_flags[28] = 0x0; +DASM$op_names[29] = "nth"; +DASM$op_data[29] = 0; +DASM$op_flags[29] = 0x0; +DASM$op_names[30] = "cmp_eq"; +DASM$op_data[30] = 0; +DASM$op_flags[30] = 0x0; +DASM$op_names[31] = "cmp_ne"; +DASM$op_data[31] = 0; +DASM$op_flags[31] = 0x0; +DASM$op_names[32] = "cmp_lt"; +DASM$op_data[32] = 0; +DASM$op_flags[32] = 0x0; +DASM$op_names[33] = "cmp_gt"; +DASM$op_data[33] = 0; +DASM$op_flags[33] = 0x0; +DASM$op_names[34] = "cmp_le"; +DASM$op_data[34] = 0; +DASM$op_flags[34] = 0x0; +DASM$op_names[35] = "cmp_ge"; +DASM$op_data[35] = 0; +DASM$op_flags[35] = 0x0; +DASM$op_names[36] = "cmp_seq"; +DASM$op_data[36] = 0; +DASM$op_flags[36] = 0x0; +DASM$op_names[37] = "cmp_sne"; +DASM$op_data[37] = 0; +DASM$op_flags[37] = 0x0; +DASM$op_names[38] = "sub"; +DASM$op_data[38] = 0; +DASM$op_flags[38] = 0x0; +DASM$op_names[39] = "add"; +DASM$op_data[39] = 0; +DASM$op_flags[39] = 0x0; +DASM$op_names[40] = "mul"; +DASM$op_data[40] = 0; +DASM$op_flags[40] = 0x0; +DASM$op_names[41] = "div"; +DASM$op_data[41] = 0; +DASM$op_flags[41] = 0x0; +DASM$op_names[42] = "mod"; +DASM$op_data[42] = 0; +DASM$op_flags[42] = 0x0; +DASM$op_names[43] = "neg"; +DASM$op_data[43] = 0; +DASM$op_flags[43] = 0x0; +DASM$op_names[44] = "and"; +DASM$op_data[44] = 0; +DASM$op_flags[44] = 0x0; +DASM$op_names[45] = "not"; +DASM$op_data[45] = 0; +DASM$op_flags[45] = 0x0; +DASM$op_names[46] = "or"; +DASM$op_data[46] = 0; +DASM$op_flags[46] = 0x0; +DASM$op_names[47] = "xor"; +DASM$op_data[47] = 0; +DASM$op_flags[47] = 0x0; +DASM$op_names[48] = "shift_left"; +DASM$op_data[48] = 0; +DASM$op_flags[48] = 0x0; +DASM$op_names[49] = "shift_right"; +DASM$op_data[49] = 0; +DASM$op_flags[49] = 0x0; +DASM$op_names[50] = "shift_rright"; +DASM$op_data[50] = 0; +DASM$op_flags[50] = 0x0; +DASM$op_names[51] = "iffalse"; +DASM$op_data[51] = 4; +DASM$op_flags[51] = 0x2; +DASM$op_names[52] = "iftrue"; +DASM$op_data[52] = 4; +DASM$op_flags[52] = 0x2; +DASM$op_names[53] = "call_method"; +DASM$op_data[53] = 4; +DASM$op_flags[53] = 0x1; +DASM$op_names[54] = "jmp"; +DASM$op_data[54] = 4; +DASM$op_flags[54] = 0x2; +DASM$op_names[55] = "jsr"; +DASM$op_data[55] = 0; +DASM$op_flags[55] = 0x0; +DASM$op_names[56] = "return"; +DASM$op_data[56] = 0; +DASM$op_flags[56] = 0x0; +DASM$op_names[57] = "typeof"; +DASM$op_data[57] = 0; +DASM$op_flags[57] = 0x0; +DASM$op_names[58] = "new"; +DASM$op_data[58] = 0; +DASM$op_flags[58] = 0x0; +DASM$op_names[59] = "delete_property"; +DASM$op_data[59] = 4; +DASM$op_flags[59] = 0x1; +DASM$op_names[60] = "delete_array"; +DASM$op_data[60] = 0; +DASM$op_flags[60] = 0x0; +DASM$op_names[61] = "locals"; +DASM$op_data[61] = 2; +DASM$op_flags[61] = 0x0; +DASM$op_names[62] = "min_args"; +DASM$op_data[62] = 1; +DASM$op_flags[62] = 0x0; +DASM$op_names[63] = "load_nth_arg"; +DASM$op_data[63] = 0; +DASM$op_flags[63] = 0x0; +DASM$op_names[64] = "with_push"; +DASM$op_data[64] = 0; +DASM$op_flags[64] = 0x0; +DASM$op_names[65] = "with_pop"; +DASM$op_data[65] = 1; +DASM$op_flags[65] = 0x0; +DASM$op_names[66] = "try_push"; +DASM$op_data[66] = 4; +DASM$op_flags[66] = 0x2; +DASM$op_names[67] = "try_pop"; +DASM$op_data[67] = 1; +DASM$op_flags[67] = 0x0; +DASM$op_names[68] = "throw"; +DASM$op_data[68] = 0; +DASM$op_flags[68] = 0x0; +DASM$op_names[69] = "iffalse_b"; +DASM$op_data[69] = 4; +DASM$op_flags[69] = 0x2; +DASM$op_names[70] = "iftrue_b"; +DASM$op_data[70] = 4; +DASM$op_flags[70] = 0x2; +DASM$op_names[71] = "add_1_i"; +DASM$op_data[71] = 0; +DASM$op_flags[71] = 0x0; +DASM$op_names[72] = "add_2_i"; +DASM$op_data[72] = 0; +DASM$op_flags[72] = 0x0; +DASM$op_names[73] = "load_global_w"; +DASM$op_data[73] = 4; +DASM$op_flags[73] = 0x1; +DASM$op_names[74] = "jsr_w"; +DASM$op_data[74] = 4; +DASM$op_flags[74] = 0x1; diff --git a/reactos/lib/kjs/jswrap/ChangeLog b/reactos/lib/kjs/jswrap/ChangeLog new file mode 100644 index 00000000000..df136ac2d5f --- /dev/null +++ b/reactos/lib/kjs/jswrap/ChangeLog @@ -0,0 +1,13 @@ +1998-08-12 Markku Rossi + + * process.js (path_to_ppname): Fixed to convert all non-identifier + characters to '_'. The function can now also handle file names + which start with an number. + +1998-08-10 Markku Rossi + + * process.js (Func$print_c): Fixed call-by-reference arguments. + Implemented the `static' modifier for arguments. + (c_typename): Changed int's C-type to `long'. + (Func$print_c): Added some casts to make C++ compilers happy about + our code. diff --git a/reactos/lib/kjs/jswrap/Makefile b/reactos/lib/kjs/jswrap/Makefile new file mode 100644 index 00000000000..582511c83e3 --- /dev/null +++ b/reactos/lib/kjs/jswrap/Makefile @@ -0,0 +1,244 @@ +# Generated automatically from Makefile.in by configure. +# Makefile.in generated automatically by automake 1.3 from Makefile.am + +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Automakefile for jswrap. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + + +SHELL = /bin/sh + +srcdir = . +top_srcdir = .. +prefix = /usr/local/js-0.2.5 +exec_prefix = ${prefix} + +bindir = ${exec_prefix}/bin +sbindir = ${exec_prefix}/sbin +libexecdir = ${exec_prefix}/libexec +datadir = ${prefix}/share +sysconfdir = ${prefix}/etc +sharedstatedir = ${prefix}/com +localstatedir = ${prefix}/var +libdir = ${exec_prefix}/lib +infodir = ${prefix}/info +mandir = ${prefix}/man +includedir = ${prefix}/include +oldincludedir = /usr/include + +DISTDIR = + +pkgdatadir = $(datadir)/js +pkglibdir = $(libdir)/js +pkgincludedir = $(includedir)/js + +top_builddir = .. + +ACLOCAL = aclocal +AUTOCONF = autoconf +AUTOMAKE = automake +AUTOHEADER = autoheader + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} +transform = s,x,x, + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = i686-pc-linux-gnu +host_triplet = i686-pc-linux-gnu +ACLOCAL_FLAGS_FOR_LIBTOOL = +CC = gcc +CPP = gcc -E +EXTENSIONS = dl_open.lo xjs.lo xmd5.lo md5c.lo +EXTENSIONS_LIBS = -ldl +INTERPRETER_FEATURES = r_std.lo +LD = /usr/bin/ld +LIBTOOL = $(SHELL) $(top_builddir)/libtool +LN_S = ln -s +MAKEINFO = makeinfo +NM = /usr/bin/nm -B +PACKAGE = js +PGCC_BY_PROVENZANO = +RANLIB = ranlib +U = +VERSION = 0.2.5 +XLC_R_AIX = + +JSCOMPILER = ../src/js +JSCOMPILER_FLAGS = -Wpedantic -O2 -g + +JSS = process.js main.js +JSCS = process.jsc main.jsc + +EXTRA_DIST = $(JSS) + +bin_SCRIPTS = jswrap + +CLEANFILES = jswrap $(JSCS) + +SUFFIXES = .jsc .js +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../jsconfig.h +CONFIG_CLEAN_FILES = +SCRIPTS = $(bin_SCRIPTS) + +DIST_COMMON = ChangeLog Makefile.am Makefile.in TODO + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP = --best +all: Makefile $(SCRIPTS) + +.SUFFIXES: +.SUFFIXES: .js .jsc +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps jswrap/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +install-binSCRIPTS: $(bin_SCRIPTS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_SCRIPTS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ + $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + else if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ + $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + else :; fi; fi; \ + done + +uninstall-binSCRIPTS: + @$(NORMAL_UNINSTALL) + list='$(bin_SCRIPTS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + done +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = jswrap + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done +info: +dvi: +check: all + $(MAKE) +installcheck: +install-exec: install-binSCRIPTS + @$(NORMAL_INSTALL) + +install-data: + @$(NORMAL_INSTALL) + +install: install-exec install-data all + @: + +uninstall: uninstall-binSCRIPTS + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: + $(mkinstalldirs) $(DATADIR)$(bindir) + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean: mostlyclean-generic + +clean: clean-generic mostlyclean + +distclean: distclean-generic clean + -rm -f config.status + -rm -f libtool + +maintainer-clean: maintainer-clean-generic distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +.PHONY: uninstall-binSCRIPTS install-binSCRIPTS tags distdir info dvi \ +installcheck install-exec install-data install uninstall all \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +compile: $(JSCS) + +jswrap: $(JSS) + rm -f $@.js + for i in $(JSS); do cat $(srcdir)/$$i >> $@.js; done + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -c $@.js + echo "#!$(bindir)/js --file" > $@ +# echo "#!$(JSCOMPILER) --file" > $@ + cat $@.jsc >> $@ + chmod a+x $@ + +.js.jsc: + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -c $< + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/reactos/lib/kjs/jswrap/Makefile.am b/reactos/lib/kjs/jswrap/Makefile.am new file mode 100644 index 00000000000..1ff36cde389 --- /dev/null +++ b/reactos/lib/kjs/jswrap/Makefile.am @@ -0,0 +1,51 @@ +# +# Automakefile for jswrap. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + +JSCOMPILER = ../src/js +JSCOMPILER_FLAGS = -Wpedantic -O2 -g + +JSS = process.js main.js +JSCS = process.jsc main.jsc + +EXTRA_DIST = $(JSS) + +bin_SCRIPTS = jswrap + +compile: $(JSCS) + +jswrap: $(JSS) + rm -f $@.js + for i in $(JSS); do cat $(srcdir)/$$i >> $@.js; done + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -c $@.js + echo "#!$(bindir)/js --file" > $@ +# echo "#!$(JSCOMPILER) --file" > $@ + cat $@.jsc >> $@ + chmod a+x $@ + +CLEANFILES = jswrap $(JSCS) + +SUFFIXES = .jsc .js + +.js.jsc: + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -c $< diff --git a/reactos/lib/kjs/jswrap/Makefile.in b/reactos/lib/kjs/jswrap/Makefile.in new file mode 100644 index 00000000000..75a97934fc7 --- /dev/null +++ b/reactos/lib/kjs/jswrap/Makefile.in @@ -0,0 +1,244 @@ +# Makefile.in generated automatically by automake 1.3 from Makefile.am + +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Automakefile for jswrap. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + + +SHELL = /bin/sh + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DISTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_FLAGS_FOR_LIBTOOL = @ACLOCAL_FLAGS_FOR_LIBTOOL@ +CC = @CC@ +CPP = @CPP@ +EXTENSIONS = @EXTENSIONS@ +EXTENSIONS_LIBS = @EXTENSIONS_LIBS@ +INTERPRETER_FEATURES = @INTERPRETER_FEATURES@ +LD = @LD@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +NM = @NM@ +PACKAGE = @PACKAGE@ +PGCC_BY_PROVENZANO = @PGCC_BY_PROVENZANO@ +RANLIB = @RANLIB@ +U = @U@ +VERSION = @VERSION@ +XLC_R_AIX = @XLC_R_AIX@ + +JSCOMPILER = ../src/js +JSCOMPILER_FLAGS = -Wpedantic -O2 -g + +JSS = process.js main.js +JSCS = process.jsc main.jsc + +EXTRA_DIST = $(JSS) + +bin_SCRIPTS = jswrap + +CLEANFILES = jswrap $(JSCS) + +SUFFIXES = .jsc .js +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../jsconfig.h +CONFIG_CLEAN_FILES = +SCRIPTS = $(bin_SCRIPTS) + +DIST_COMMON = ChangeLog Makefile.am Makefile.in TODO + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP = --best +all: Makefile $(SCRIPTS) + +.SUFFIXES: +.SUFFIXES: .js .jsc +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps jswrap/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +install-binSCRIPTS: $(bin_SCRIPTS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_SCRIPTS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ + $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + else if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ + $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + else :; fi; fi; \ + done + +uninstall-binSCRIPTS: + @$(NORMAL_UNINSTALL) + list='$(bin_SCRIPTS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + done +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = jswrap + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done +info: +dvi: +check: all + $(MAKE) +installcheck: +install-exec: install-binSCRIPTS + @$(NORMAL_INSTALL) + +install-data: + @$(NORMAL_INSTALL) + +install: install-exec install-data all + @: + +uninstall: uninstall-binSCRIPTS + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: + $(mkinstalldirs) $(DATADIR)$(bindir) + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean: mostlyclean-generic + +clean: clean-generic mostlyclean + +distclean: distclean-generic clean + -rm -f config.status + -rm -f libtool + +maintainer-clean: maintainer-clean-generic distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +.PHONY: uninstall-binSCRIPTS install-binSCRIPTS tags distdir info dvi \ +installcheck install-exec install-data install uninstall all \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +compile: $(JSCS) + +jswrap: $(JSS) + rm -f $@.js + for i in $(JSS); do cat $(srcdir)/$$i >> $@.js; done + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -c $@.js + echo "#!$(bindir)/js --file" > $@ +# echo "#!$(JSCOMPILER) --file" > $@ + cat $@.jsc >> $@ + chmod a+x $@ + +.js.jsc: + $(JSCOMPILER) $(JSCOMPILER_FLAGS) -c $< + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/reactos/lib/kjs/jswrap/TODO b/reactos/lib/kjs/jswrap/TODO new file mode 100644 index 00000000000..fc9ad63b418 --- /dev/null +++ b/reactos/lib/kjs/jswrap/TODO @@ -0,0 +1,13 @@ + + TODO jswrap + =========== + +* Fix the debugging information in the embedded byte-code files: input + file name (.psw) and line numbers. This requires support from the + compiler. + +* The current version do not optimize with -O2. We can't do the + liveness analysing, because on `return' statements, arguments are + not alive, and the by-reference return values won't work. The + compiler needs a new flag JSC$FLAG_OPTIMIZE_ARGUMENTS_LIVE_ON_RETURN + that would fix the problem. diff --git a/reactos/lib/kjs/jswrap/jswrap.js b/reactos/lib/kjs/jswrap/jswrap.js new file mode 100644 index 00000000000..8b2b48277d8 --- /dev/null +++ b/reactos/lib/kjs/jswrap/jswrap.js @@ -0,0 +1,1138 @@ +/* + * Process the jswrap input files and generate output. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jswrap/jswrap.js,v $ + * $Id: jswrap.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * Constants and definitions. + */ + +/* Tokens. */ + +tEOF = 1000; + +tFUNCTION = 1001; +tIDENTIFIER = 1002; + +tCSTRING = 2001; +tDOUBLE = 2002; +tINT = 2003; +tSTRING = 2004; +tVOID = 2005; + +tIN = 2010; +tOUT = 2011; +tINOUT = 2012; + +tSTATIC = 2020; + +function is_type_token (token) +{ + return (token == tCSTRING || token == tDOUBLE || token == tINT + || token == tSTRING || token == tVOID); +} + +function is_copy_type_token (token) +{ + return (token == tIN || token == tOUT || token == tINOUT); +} + +function typename (token) +{ + if (token == tCSTRING) + return "cstring"; + else if (token == tDOUBLE) + return "double"; + else if (token == tINT) + return "int"; + else if (token == tSTRING) + return "string"; + else if (token == tVOID) + return "void"; + else if (token == tIN) + return "in"; + else if (token == tOUT) + return "out"; + else if (token == tINOUT) + return "inout"; + else + return ""; +} + +function c_typename (token) +{ + if (token == tCSTRING) + return "char *"; + else if (token == tDOUBLE) + return "double "; + else if (token == tINT) + return "long "; + else if (token == tVOID) + return "void "; + else if (token == tOUT || token == tINOUT) + return "*"; + else + return ""; +} + +function jsint_typename (token) +{ + if (token == tCSTRING) + return "JS_STRING"; + else if (token == tDOUBLE) + return "JS_FLOAT"; + else if (token == tINT) + return "JS_INTEGER"; + else if (token == tSTRING) + return "JS_STRING"; + else + return ""; +} + +valid_c_identifier_re = new RegExp ("^[A-Za-z_][A-Za-z_0-9]*$"); + +end_brace_re = new RegExp ("^}[ \t]*$"); + +/* + * Variables. + */ + +/* The input file line number. */ +linenum = 1; + +token_linenum = 1; + +token_value = null; + +/* + * Functions. + */ + +function process () +{ + if (false) + System.print (program, ": processing file `", input_file, + "', header=`", header_file, + "', output=`", output_file, + "', reentrant=", opt_reentrant, "\n"); + + linenum = 1; + + /* Open input file. */ + ifp = new File (input_file); + if (!ifp.open ("r")) + { + System.error (program, ": couldn't open input file `", input_file, + "': ", System.strerror (System.errno), "\n"); + System.exit (1); + } + + /* Create output files. */ + + ofp_c = new File (output_file); + if (!ofp_c.open ("w")) + { + System.error (program, ": couldn't create output file `", output_file, + "': ", System.strerror (System.errno), "\n"); + System.exit (1); + } + + ofp_h = new File (header_file); + if (!ofp_h.open ("w")) + { + ofp_c.close (); + File.remove (output_file); + + System.error (program, ": couldn't create header file `", header_file, + "': ", System.strerror (System.errno), "\n"); + System.exit (1); + } + + if (false) + { + ofp_js = new File (js_file); + if (!ofp_js.open ("w")) + { + ofp_c.close (); + ofp_h.close (); + File.remove (output_file); + File.remove (header_file); + + System.error (program, ": couldn't create JS file `", js_file, + "': ", System.strerror (System.errno), "\n"); + System.exit (1); + } + } + + /* Parse the input. */ + parse (); + + /* Cleanup. */ + + ofp_c.close (); + ofp_h.close (); +} + + +/* + * The Func class to hold function definitions. + */ + +function Func () +{ +} + +new Func (); + +function Func$generate_js () +{ + this.code = new String ("function " + this.name + " ("); + var i; + for (i = 0; i < this.args.length; i++) + { + this.code.append (this.args[i].name); + if (i + 1 < this.args.length) + this.code.append (", "); + } + this.code.append (")\n{"); + this.code.append (this.body); + this.code.append ("}\n"); +} +Func.prototype.generate_js = Func$generate_js; + +function Func$print_js (stream) +{ + stream.write (this.code); +} +Func.prototype.print_js = Func$print_js; + +function Func$print_h (stream, header) +{ + stream.write ("\n"); + stream.write (c_typename (this.return_type) + this.name + " ("); + + if (opt_reentrant) + { + /* The first argument is the interpreter handle. */ + stream.write ("\n\tJSInterpPtr interp"); + if (this.args.length > 0) + stream.write (","); + } + + var i; + for (i = 0; i < this.args.length; i++) + { + stream.write ("\n\t"); + if (this.args[i].type == tSTRING) + { + stream.write ("unsigned char *" + + c_typename (this.args[i].copy_type) + + this.args[i].name + ",\n\t" + + "unsigned int " + + c_typename (this.args[i].copy_type) + + this.args[i].name + "_len"); + } + else + { + stream.write (c_typename (this.args[i].type) + + c_typename (this.args[i].copy_type)); + stream.write (this.args[i].name); + } + + if (i + 1 < this.args.length) + stream.write (", "); + } + stream.write ("\n\t)"); + + if (header) + stream.write (";"); + + stream.write ("\n"); +} +Func.prototype.print_h = Func$print_h; + +function Func$print_c (stream) +{ + this.compile (); + this.dump_bc (stream); + + this.print_h (stream, false); + + stream.write ("{\n"); + + if (!opt_reentrant) + stream.write (" JSInterpPtr interp = jswrap_interp;\n"); + + stream.write (" JSVirtualMachine *vm = interp->vm;\n"); + + stream.write (" JSNode argv[" + + (this.args.length + 1).toString () + + "];\n"); + stream.write (" int result;\n"); + + if (this.return_type == tCSTRING) + stream.write (" char *cp;\n"); + + stream.write ("\n"); + + /* Argument count. */ + stream.write (" argv[0].type = JS_INTEGER;\n"); + stream.write (" argv[0].u.vinteger = " + + this.args.length.toString () + + ";\n"); + + /* Arguments. */ + + /* Construct the argv array. */ + for (i = 0; i < this.args.length; i++) + { + var arg = this.args[i]; + var cspec = ""; + + stream.write ("\n"); + + var argnum = (i + 1).toString (); + + if (arg.copy_type == tOUT) + { + stream.write (" argv[" + argnum + "].type = JS_UNDEFINED;\n"); + } + else + { + if (arg.copy_type == tINOUT) + cspec = "*"; + + if (arg.type == tCSTRING) + { + stream.write (" js_vm_make" + + (arg.staticp ? "_static" : "") + + "_string (vm, &argv[" + + argnum + "], " + + cspec + arg.name + ", strlen (" + + cspec + arg.name + "));\n"); + } + else if (arg.type == tDOUBLE) + { + stream.write (" argv[" + argnum + "].type = JS_FLOAT;\n"); + stream.write (" argv[" + argnum + "].u.vfloat = " + + cspec + arg.name + ";\n"); + } + else if (arg.type == tINT) + { + stream.write (" argv[" + argnum + "].type = JS_INTEGER;\n"); + stream.write (" argv[" + argnum + "].u.vinteger = " + + cspec + arg.name + ";\n"); + } + else if (arg.type == tSTRING) + { + stream.write (" js_vm_make_static_string (vm, &argv[" + + argnum + "], " + + cspec + arg.name + ", " + + cspec + arg.name + "_len);\n"); + } + else + VM.stackTrace (); + } + } + + /* Call the function. */ + stream.write ("\ + + retry: + + result = js_vm_apply (vm, \"" + this.name + "\", NULL, " + + (i + 1).toString () + ", argv); + if (result == 0) + { + JSNode *n = &vm->globals[js_vm_intern (vm, \"" + this.name + "\")]; + + if (n->type != JS_FUNC) + { + JSByteCode *bc = js_bc_read_data (" + this.name + "_bc, + sizeof (" + this.name + "_bc)); + result = js_vm_execute (vm, bc); + js_bc_free (bc); + + if (result == 0) + jswrap_error (interp, \"initialization of function`" + + this.name + "' failed\"); + goto retry; + } + jswrap_error (interp, \"execution of function `" + + this.name + "' failed\"); + } +"); + + /* Handle out and inout parameters. */ + for (i = 0; i < this.args.length; i++) + { + var arg = this.args[i]; + if (arg.copy_type == tIN) + continue; + + var spos = (this.args.length - i).toString (); + + /* Check that we have there a correct type. */ + stream.write (" + if ((vm->sp - " + spos + ")->type != " + jsint_typename (arg.type) + ") + jswrap_error (interp, + \"wrong return type for argument `" + + arg.name + "' of function `" + this.name + "'\"); +"); + + /* Handle the different types. */ + if (arg.type == tCSTRING) + { + stream.write ("\ + *" + arg.name + " = (char *) js_vm_alloc (vm, (vm->sp - " + + spos + ")->u.vstring->len + 1); + memcpy (*" + arg.name + ", (vm->sp - " + spos + ")->u.vstring->data, + (vm->sp - " + spos + ")->u.vstring->len); + " + arg.name + "[(vm->sp - " + spos + ")->u.vstring->len] = '\\0'; +"); + } + else if (arg.type == tDOUBLE) + { + stream.write ("\ + *" + arg.name + " = (vm->sp - " + spos + ")->u.vfloat;\n"); + } + else if (arg.type == tINT) + { + stream.write ("\ + *" + arg.name + " = (vm->sp - " + spos + ")->u.vinteger;\n"); + } + else if (arg.type == tSTRING) + { + stream.write ("\ + *" + arg.name + " = (vm->sp - " + spos + ")->u.vstring->data; + *" + arg.name + "_len = (vm->sp - " + spos + ")->u.vstring->len; +"); + } + } + + /* Handle the function return value. */ + if (this.return_type != tVOID) + { + /* Check that the code returned correct type. */ + stream.write (" + if (vm->exec_result.type != " + jsint_typename (this.return_type) + ") + jswrap_error (interp, \"return type mismatch in function `" + + this.name + "'\"); + +"); + + /* Handle the different types. */ + if (this.return_type == tCSTRING) + { + stream.write ("\ + cp = (char *) js_vm_alloc (vm, vm->exec_result.u.vstring->len + 1); + memcpy (cp, vm->exec_result.u.vstring->data, vm->exec_result.u.vstring->len); + cp[vm->exec_result.u.vstring->len] = '\\0'; + + return cp; +"); + } + else if (this.return_type == tDOUBLE) + stream.write (" return vm->exec_result.u.vfloat;\n"); + else if (this.return_type == tINT) + stream.write (" return vm->exec_result.u.vinteger;\n"); + } + + stream.write ("}\n"); +} +Func.prototype.print_c = Func$print_c; + +function Func$compile () +{ + /* Create the byte-code for this function. */ + + var flags = 0; + + if (false) + flags |= JSC$FLAG_VERBOSE; + + if (opt_debug) + flags |= JSC$FLAG_GENERATE_DEBUG_INFO; + + flags |= (JSC$FLAG_OPTIMIZE_PEEPHOLE + | JSC$FLAG_OPTIMIZE_JUMPS + | JSC$FLAG_OPTIMIZE_BC_SIZE); + + flags |= JSC$FLAG_WARN_MASK; + + try + { + this.bc = JSC$compile_string (this.code, flags, null, null); + } + catch (error) + { + System.error (error, "\n"); + System.exit (1); + } +} +Func.prototype.compile = Func$compile; + +function Func$dump_bc (stream) +{ + stream.write ("\nstatic unsigned char " + this.name + "_bc[] = {"); + + var i; + for (i = 0; i < this.bc.length; i++) + { + if ((i % 12) == 0) + stream.write ("\n "); + + var item = this.bc[i].toString (16); + if (item.length == 1) + item = "0" + item; + + stream.write (" 0x" + item + ","); + } + + stream.write ("\n};\n"); +} +Func.prototype.dump_bc = Func$dump_bc; + +/* + * The Argument class to hold function argument definitions. + */ + +function Argument () +{ + this.type = false; + this.copy_type = tIN; + this.staticp = false; +} + +new Argument (); + +function Argument$print () +{ + System.print (typename (this.copy_type), " ", typename (this.type), + " ", this.name); +} +Argument.prototype.print = Argument$print; + + + +/* + * The .jsw file parsing. + */ + +function parse () +{ + var token; + var func; + + headers (); + + while ((token = get_token ()) != tEOF) + { + if (token != tFUNCTION) + syntax_error (); + + func = new Func (); + + /* Possible return type. */ + token = get_token (); + if (is_type_token (token)) + { + if (token == tSTRING) + { + System.error (input_file, ":", linenum, + ": the function return value can't be `string'\n"); + System.exit (1); + } + + func.return_type = token; + + token = get_token (); + } + else + func.return_type = tVOID; + + /* The name of the function. */ + if (token != tIDENTIFIER) + syntax_error (); + + if (!valid_c_identifier_re.test (token_value)) + { + System.error (input_file, ":", linenum, + ": function name is not a valid C identifier `", + token_value, "'\n"); + System.exit (1); + } + + func.name = token_value; + + /* Arguments. */ + token = get_token (); + if (token != #'(') + syntax_error (); + + var args = new Array (); + + token = get_token (); + while (token != #')') + { + var arg = new Argument (); + + while (token != tIDENTIFIER) + { + if (token == tEOF) + syntax_error (); + + if (is_type_token (token)) + arg.type = token; + else if (is_copy_type_token (token)) + arg.copy_type = token; + else if (token == tSTATIC) + arg.staticp = true; + else + syntax_error (); + + token = get_token (); + } + + if (!valid_c_identifier_re.test (token_value)) + { + System.error (input_file, ":", linenum, + ": argument name is not a valid C identifier `", + token_value, "'\n"); + System.exit (1); + } + arg.name = token_value; + + /* Check some validity conditions. */ + if (!arg.type) + { + System.error (input_file, ":", linenum, + ": no type specified for argument `", + arg.name, "'\n"); + System.exit (1); + } + if (arg.staticp) + { + if (arg.type != tCSTRING && arg.type != tSTRING) + { + System.error (input_file, ":", linenum, + ": type `static' can only be used with `cstring' and `string' arguments\n"); + System.exit (1); + } + if (arg.copy_type == tOUT) + System.error (input_file, ":", linenum, + ": warning: type `static' is meaningful only with `in' and `inout' arguments\n"); + } + + args.push (arg); + + token = get_token (); + if (token == #',') + token = get_token (); + } + + func.args = args; + + /* The opening '{' of the function body. */ + token = get_token (); + if (token != #'{') + syntax_error (); + + /* Get the function body. */ + var code = new String (""); + while (true) + { + var line = ifp.readln (); + if (!line) + syntax_error (); + linenum++; + + if (end_brace_re.test (line)) + break; + + code.append (line + "\n"); + } + + func.body = code; + func.generate_js (); + + // func.print_js (ofp_js); + func.print_h (ofp_h, true); + func.print_c (ofp_c); + } + + trailers (); +} + +function get_token () +{ + var ch; + + while ((ch = ifp.readByte ()) != -1) + { + if (ch == #' ' || ch == #'\t' || ch == #'\v' || ch == #'\r' + || ch == #'\f') + continue; + + if (ch == #'\n') + { + linenum++; + continue; + } + + token_linenum = linenum; + + if (ch == #'/' && peek_char () == #'*') + { + /* Multi line comment. */ + ifp.readByte (); + while ((ch = ifp.readByte ()) != -1 + && (ch != #'*' || peek_char () != #'/')) + if (ch == #'\n') + linenum++; + + /* Consume the peeked #'/' character. */ + ifp.readByte (); + } + + /* Identifiers and keywords. */ + else if (JSC$lexer_is_identifier_letter (ch)) + { + /* An identifier. */ + var id = String.fromCharCode (ch); + + while ((ch = ifp.readByte ()) != -1 + && (JSC$lexer_is_identifier_letter (ch) + || JSC$lexer_is_decimal_digit (ch))) + id.append (File.byteToString (ch)); + ifp.ungetByte (ch); + + /* Keywords. */ + if (id == "function") + return tFUNCTION; + + /* Types. */ + else if (id == "cstring") + return tCSTRING; + else if (id == "double") + return tDOUBLE; + else if (id == "int") + return tINT; + else if (id == "string") + return tSTRING; + else if (id == "void") + return tVOID; + else if (id == "in") + return tIN; + else if (id == "out") + return tOUT; + else if (id == "inout") + return tINOUT; + else if (id == "static") + return tSTATIC; + + else + { + /* It really is an identifier. */ + token_value = id; + return tIDENTIFIER; + } + } + + /* Just return the character as-is. */ + else + return ch; + } + + /* EOF reached. */ + return tEOF; +} + +function peek_char () +{ + var ch = ifp.readByte (); + ifp.ungetByte (ch); + + return ch; +} + +function syntax_error () +{ + System.error (input_file, ":", linenum, ": syntax error\n"); + System.exit (1); +} + +function headers () +{ + var stream; + + /* The header file. */ + + stream = ofp_h; + header_banner (stream); + + var ppname = path_to_ppname (header_file); + stream.write ("\n#ifndef " + ppname + + "\n#define " + ppname + "\n"); + + /* The C file. */ + stream = ofp_c; + header_banner (stream); + stream.write ("\n#include \n"); + + if (!opt_reentrant) + { + stream.write (" +/* + * This global interpreter handle can be removed with " + program + "'s + * option -r, --reentrant. + */ +"); + stream.write ("extern JSInterpPtr jswrap_interp;\n"); + } + + if (opt_no_error_handler) + { + stream.write (" +/* Prototype for the error handler of the JS runtime errors. */ +"); + stream.write ("void jswrap_error (JSInterpPtr interp, char *error);\n"); + } + else + { + /* Define the default jswrap_error() function. */ + stream.write (" +/* + * This is the default error handler for the JS runtime errors. The default + * handler can be removed with " + program + "'s option -n, --no-error-handler. + * In this case, your code must define the handler function. + */ +"); + stream.write ("\ +static void +jswrap_error (JSInterpPtr interp, char *error) +{ + const char *cp; + + fprintf (stderr, \"JS runtime error: %s\", error); + + cp = js_error_message (interp); + if (cp[0]) + fprintf (stderr, \": %s\", cp); + fprintf (stderr, \"\\n\"); + + exit (1); +} +"); + } + + stream.write (" + +/* + * The global function definitions. + */ +"); +} + +function header_banner (stream) +{ + stream.write ("/* This file is automatically generated from `" + + input_file + "' by " + program + ". */\n"); +} + +path_to_ppname_re = new RegExp ("[^A-Za-z_0-9]", "g"); + +function path_to_ppname (path) +{ + var str = path.toUpperCase ().replace (path_to_ppname_re, "_"); + if (#'0' <= str[0] && str[0] <= #'9') + str = "_" + str; + + return str; +} + +function trailers () +{ + /* The header file. */ + var stream = ofp_h; + stream.write ("\n#endif /* not " + path_to_ppname (header_file) + " */\n"); +} + + +/* +Local variables: +mode: c +End: +*/ +/* + * JS C wrapper. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jswrap/jswrap.js,v $ + * $Id: jswrap.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * Variables and definitions. + */ + +version_number = "0.0.1"; + +/* + * Options. + */ + +/* + * -g, --debug + * + * Generate debugging information to the generated JS byte-code. + */ + +opt_debug = false; + +/* + * -h FILE, --header FILE + * + * Generate the C header to file FILE. + */ + +header_file = null; + +/* + * -n, --no-error-handler + * + * Do not create the default error handler to the C files. + */ +opt_no_error_handler = false; + +/* + * -o FILE, --output FILE + * + * Generate the C output to file FILE. + */ + +output_file = null; + +/* + * -r, --reentrant + * + * Generate re-entrant C stubs. + */ + +opt_reentrant = false; + +/* + * -V, --version + * + * Print version information and exit successfully. + */ + +/* + * --help + * + * Print short help and exit successfully. + */ + + +/* + * Functions. + */ + +function main () +{ + var idx = ARGS[0].lastIndexOf ("/"); + if (idx >= 0) + program = ARGS[0].substr (idx + 1); + else + program = ARGS[0]; + + /* Handle arguments. */ + var i; + for (i = 1; i < ARGS.length; i++) + { + if (ARGS[i][0] == #'-') + { + if (ARGS[i] == "-g" || ARGS[i] == "--debug") + opt_debug = true; + else if (ARGS[i] == "-h" || ARGS[i] == "--header") + { + if (i + 1 >= ARGS.length) + { + System.error (program, + ": no argument for option --header\n"); + System.exit (1); + } + + header_file = ARGS[++i]; + } + else if (ARGS[i] == "-n" || ARGS[i] == "--no-error-handler") + opt_no_error_handler = true; + else if (ARGS[i] == "-o" || ARGS[i] == "--output") + { + if (i + 1 >= ARGS.length) + { + System.error (program, + ": no argument for option --output\n"); + System.exit (1); + } + + output_file = ARGS[++i]; + } + else if (ARGS[i] == "-r" || ARGS[i] == "--reentrant") + opt_reentrant = true; + else if (ARGS[i] == "-V" || ARGS[i] == "--version") + { + version (); + System.exit (0); + } + else if (ARGS[i] == "--help") + { + usage (); + System.exit (0); + } + else + { + /* Unrecognized option. */ + System.error (program, ": unrecognized option `", + ARGS[i], "'\n"); + System.error ("Try `", program, + " --help' for more information.\n"); + System.exit (1); + } + } + else + { + /* End of arguments. */ + break; + } + } + + if (i >= ARGS.length) + { + System.error (program, ": no input file specified\n"); + System.exit (1); + } + if (i + 1 < ARGS.length) + { + System.error (program, ": extraneous arguments after input file\n"); + System.exit (1); + } + + input_file = ARGS[i]; + + /* Set the defaults. */ + + var re = new RegExp ("^(.*)\\.jsw$"); + if (!header_file) + { + if (re.test (input_file)) + header_file = RegExp.$1 + ".h"; + else + header_file = input_file + ".h"; + } + if (!output_file) + { + if (re.test (input_file)) + output_file = RegExp.$1 + ".c"; + else + output_file = input_file + ".c"; + } + if (false) + { + if (re.test (input_file)) + js_file = RegExp.$1 + ".js"; + else + js_file = input_file + ".js"; + } + + process (); +} + + +function usage () +{ + System.print ("\ +Usage: ", program, " [OPTION]... FILE\n\ +Mandatory arguments to long options are mandatory for short options too.\n"); + + System.print ("\ + -g, --debug generate debugging information to the generated\n\ + JS byte-code\n\ + -h, --header FILE generate the C header to file FILE\n\ + -n, --no-error-handler do not generate the default error handler\n\ + -o, --output FILE generate the C output to file FILE\n\ + -r, --reentrant generate re-entrant C stubs\n\ + -V, --version print version number\n\ + --help print this help and exit\n\ +"); + + System.print ("\nReport bugs to mtr@ngs.fi.\n"); +} + + +function version () +{ + System.print ("NGS JavaScript C wrapper generator ", version_number, "\n"); + System.print ("\ +Copyright (C) 1998 New Generation Software (NGS) Oy.\n\ +NGS JavaScript Interpreter comes with NO WARRANTY, to the extent\n\ +permitted by law. You may redistribute copies of NGS JavaScript\n\ +Interpreter under the terms of the GNU Library General Public License.\n\ +For more information about these matters, see the files named COPYING.\n\ +"); +} + + +main (); + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/jswrap/main.js b/reactos/lib/kjs/jswrap/main.js new file mode 100644 index 00000000000..0474566bcdd --- /dev/null +++ b/reactos/lib/kjs/jswrap/main.js @@ -0,0 +1,248 @@ +/* + * JS C wrapper. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jswrap/main.js,v $ + * $Id: main.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * Variables and definitions. + */ + +version_number = "0.0.1"; + +/* + * Options. + */ + +/* + * -g, --debug + * + * Generate debugging information to the generated JS byte-code. + */ + +opt_debug = false; + +/* + * -h FILE, --header FILE + * + * Generate the C header to file FILE. + */ + +header_file = null; + +/* + * -n, --no-error-handler + * + * Do not create the default error handler to the C files. + */ +opt_no_error_handler = false; + +/* + * -o FILE, --output FILE + * + * Generate the C output to file FILE. + */ + +output_file = null; + +/* + * -r, --reentrant + * + * Generate re-entrant C stubs. + */ + +opt_reentrant = false; + +/* + * -V, --version + * + * Print version information and exit successfully. + */ + +/* + * --help + * + * Print short help and exit successfully. + */ + + +/* + * Functions. + */ + +function main () +{ + var idx = ARGS[0].lastIndexOf ("/"); + if (idx >= 0) + program = ARGS[0].substr (idx + 1); + else + program = ARGS[0]; + + /* Handle arguments. */ + var i; + for (i = 1; i < ARGS.length; i++) + { + if (ARGS[i][0] == #'-') + { + if (ARGS[i] == "-g" || ARGS[i] == "--debug") + opt_debug = true; + else if (ARGS[i] == "-h" || ARGS[i] == "--header") + { + if (i + 1 >= ARGS.length) + { + System.error (program, + ": no argument for option --header\n"); + System.exit (1); + } + + header_file = ARGS[++i]; + } + else if (ARGS[i] == "-n" || ARGS[i] == "--no-error-handler") + opt_no_error_handler = true; + else if (ARGS[i] == "-o" || ARGS[i] == "--output") + { + if (i + 1 >= ARGS.length) + { + System.error (program, + ": no argument for option --output\n"); + System.exit (1); + } + + output_file = ARGS[++i]; + } + else if (ARGS[i] == "-r" || ARGS[i] == "--reentrant") + opt_reentrant = true; + else if (ARGS[i] == "-V" || ARGS[i] == "--version") + { + version (); + System.exit (0); + } + else if (ARGS[i] == "--help") + { + usage (); + System.exit (0); + } + else + { + /* Unrecognized option. */ + System.error (program, ": unrecognized option `", + ARGS[i], "'\n"); + System.error ("Try `", program, + " --help' for more information.\n"); + System.exit (1); + } + } + else + { + /* End of arguments. */ + break; + } + } + + if (i >= ARGS.length) + { + System.error (program, ": no input file specified\n"); + System.exit (1); + } + if (i + 1 < ARGS.length) + { + System.error (program, ": extraneous arguments after input file\n"); + System.exit (1); + } + + input_file = ARGS[i]; + + /* Set the defaults. */ + + var re = new RegExp ("^(.*)\\.jsw$"); + if (!header_file) + { + if (re.test (input_file)) + header_file = RegExp.$1 + ".h"; + else + header_file = input_file + ".h"; + } + if (!output_file) + { + if (re.test (input_file)) + output_file = RegExp.$1 + ".c"; + else + output_file = input_file + ".c"; + } + if (false) + { + if (re.test (input_file)) + js_file = RegExp.$1 + ".js"; + else + js_file = input_file + ".js"; + } + + process (); +} + + +function usage () +{ + System.print ("\ +Usage: ", program, " [OPTION]... FILE\n\ +Mandatory arguments to long options are mandatory for short options too.\n"); + + System.print ("\ + -g, --debug generate debugging information to the generated\n\ + JS byte-code\n\ + -h, --header FILE generate the C header to file FILE\n\ + -n, --no-error-handler do not generate the default error handler\n\ + -o, --output FILE generate the C output to file FILE\n\ + -r, --reentrant generate re-entrant C stubs\n\ + -V, --version print version number\n\ + --help print this help and exit\n\ +"); + + System.print ("\nReport bugs to mtr@ngs.fi.\n"); +} + + +function version () +{ + System.print ("NGS JavaScript C wrapper generator ", version_number, "\n"); + System.print ("\ +Copyright (C) 1998 New Generation Software (NGS) Oy.\n\ +NGS JavaScript Interpreter comes with NO WARRANTY, to the extent\n\ +permitted by law. You may redistribute copies of NGS JavaScript\n\ +Interpreter under the terms of the GNU Library General Public License.\n\ +For more information about these matters, see the files named COPYING.\n\ +"); +} + + +main (); + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/jswrap/process.js b/reactos/lib/kjs/jswrap/process.js new file mode 100644 index 00000000000..0f8acd6ee21 --- /dev/null +++ b/reactos/lib/kjs/jswrap/process.js @@ -0,0 +1,890 @@ +/* + * Process the jswrap input files and generate output. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jswrap/process.js,v $ + * $Id: process.js,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * Constants and definitions. + */ + +/* Tokens. */ + +tEOF = 1000; + +tFUNCTION = 1001; +tIDENTIFIER = 1002; + +tCSTRING = 2001; +tDOUBLE = 2002; +tINT = 2003; +tSTRING = 2004; +tVOID = 2005; + +tIN = 2010; +tOUT = 2011; +tINOUT = 2012; + +tSTATIC = 2020; + +function is_type_token (token) +{ + return (token == tCSTRING || token == tDOUBLE || token == tINT + || token == tSTRING || token == tVOID); +} + +function is_copy_type_token (token) +{ + return (token == tIN || token == tOUT || token == tINOUT); +} + +function typename (token) +{ + if (token == tCSTRING) + return "cstring"; + else if (token == tDOUBLE) + return "double"; + else if (token == tINT) + return "int"; + else if (token == tSTRING) + return "string"; + else if (token == tVOID) + return "void"; + else if (token == tIN) + return "in"; + else if (token == tOUT) + return "out"; + else if (token == tINOUT) + return "inout"; + else + return ""; +} + +function c_typename (token) +{ + if (token == tCSTRING) + return "char *"; + else if (token == tDOUBLE) + return "double "; + else if (token == tINT) + return "long "; + else if (token == tVOID) + return "void "; + else if (token == tOUT || token == tINOUT) + return "*"; + else + return ""; +} + +function jsint_typename (token) +{ + if (token == tCSTRING) + return "JS_STRING"; + else if (token == tDOUBLE) + return "JS_FLOAT"; + else if (token == tINT) + return "JS_INTEGER"; + else if (token == tSTRING) + return "JS_STRING"; + else + return ""; +} + +valid_c_identifier_re = new RegExp ("^[A-Za-z_][A-Za-z_0-9]*$"); + +end_brace_re = new RegExp ("^}[ \t]*$"); + +/* + * Variables. + */ + +/* The input file line number. */ +linenum = 1; + +token_linenum = 1; + +token_value = null; + +/* + * Functions. + */ + +function process () +{ + if (false) + System.print (program, ": processing file `", input_file, + "', header=`", header_file, + "', output=`", output_file, + "', reentrant=", opt_reentrant, "\n"); + + linenum = 1; + + /* Open input file. */ + ifp = new File (input_file); + if (!ifp.open ("r")) + { + System.error (program, ": couldn't open input file `", input_file, + "': ", System.strerror (System.errno), "\n"); + System.exit (1); + } + + /* Create output files. */ + + ofp_c = new File (output_file); + if (!ofp_c.open ("w")) + { + System.error (program, ": couldn't create output file `", output_file, + "': ", System.strerror (System.errno), "\n"); + System.exit (1); + } + + ofp_h = new File (header_file); + if (!ofp_h.open ("w")) + { + ofp_c.close (); + File.remove (output_file); + + System.error (program, ": couldn't create header file `", header_file, + "': ", System.strerror (System.errno), "\n"); + System.exit (1); + } + + if (false) + { + ofp_js = new File (js_file); + if (!ofp_js.open ("w")) + { + ofp_c.close (); + ofp_h.close (); + File.remove (output_file); + File.remove (header_file); + + System.error (program, ": couldn't create JS file `", js_file, + "': ", System.strerror (System.errno), "\n"); + System.exit (1); + } + } + + /* Parse the input. */ + parse (); + + /* Cleanup. */ + + ofp_c.close (); + ofp_h.close (); +} + + +/* + * The Func class to hold function definitions. + */ + +function Func () +{ +} + +new Func (); + +function Func$generate_js () +{ + this.code = new String ("function " + this.name + " ("); + var i; + for (i = 0; i < this.args.length; i++) + { + this.code.append (this.args[i].name); + if (i + 1 < this.args.length) + this.code.append (", "); + } + this.code.append (")\n{"); + this.code.append (this.body); + this.code.append ("}\n"); +} +Func.prototype.generate_js = Func$generate_js; + +function Func$print_js (stream) +{ + stream.write (this.code); +} +Func.prototype.print_js = Func$print_js; + +function Func$print_h (stream, header) +{ + stream.write ("\n"); + stream.write (c_typename (this.return_type) + this.name + " ("); + + if (opt_reentrant) + { + /* The first argument is the interpreter handle. */ + stream.write ("\n\tJSInterpPtr interp"); + if (this.args.length > 0) + stream.write (","); + } + + var i; + for (i = 0; i < this.args.length; i++) + { + stream.write ("\n\t"); + if (this.args[i].type == tSTRING) + { + stream.write ("unsigned char *" + + c_typename (this.args[i].copy_type) + + this.args[i].name + ",\n\t" + + "unsigned int " + + c_typename (this.args[i].copy_type) + + this.args[i].name + "_len"); + } + else + { + stream.write (c_typename (this.args[i].type) + + c_typename (this.args[i].copy_type)); + stream.write (this.args[i].name); + } + + if (i + 1 < this.args.length) + stream.write (", "); + } + stream.write ("\n\t)"); + + if (header) + stream.write (";"); + + stream.write ("\n"); +} +Func.prototype.print_h = Func$print_h; + +function Func$print_c (stream) +{ + this.compile (); + this.dump_bc (stream); + + this.print_h (stream, false); + + stream.write ("{\n"); + + if (!opt_reentrant) + stream.write (" JSInterpPtr interp = jswrap_interp;\n"); + + stream.write (" JSVirtualMachine *vm = interp->vm;\n"); + + stream.write (" JSNode argv[" + + (this.args.length + 1).toString () + + "];\n"); + stream.write (" int result;\n"); + + if (this.return_type == tCSTRING) + stream.write (" char *cp;\n"); + + stream.write ("\n"); + + /* Argument count. */ + stream.write (" argv[0].type = JS_INTEGER;\n"); + stream.write (" argv[0].u.vinteger = " + + this.args.length.toString () + + ";\n"); + + /* Arguments. */ + + /* Construct the argv array. */ + for (i = 0; i < this.args.length; i++) + { + var arg = this.args[i]; + var cspec = ""; + + stream.write ("\n"); + + var argnum = (i + 1).toString (); + + if (arg.copy_type == tOUT) + { + stream.write (" argv[" + argnum + "].type = JS_UNDEFINED;\n"); + } + else + { + if (arg.copy_type == tINOUT) + cspec = "*"; + + if (arg.type == tCSTRING) + { + stream.write (" js_vm_make" + + (arg.staticp ? "_static" : "") + + "_string (vm, &argv[" + + argnum + "], " + + cspec + arg.name + ", strlen (" + + cspec + arg.name + "));\n"); + } + else if (arg.type == tDOUBLE) + { + stream.write (" argv[" + argnum + "].type = JS_FLOAT;\n"); + stream.write (" argv[" + argnum + "].u.vfloat = " + + cspec + arg.name + ";\n"); + } + else if (arg.type == tINT) + { + stream.write (" argv[" + argnum + "].type = JS_INTEGER;\n"); + stream.write (" argv[" + argnum + "].u.vinteger = " + + cspec + arg.name + ";\n"); + } + else if (arg.type == tSTRING) + { + stream.write (" js_vm_make_static_string (vm, &argv[" + + argnum + "], " + + cspec + arg.name + ", " + + cspec + arg.name + "_len);\n"); + } + else + VM.stackTrace (); + } + } + + /* Call the function. */ + stream.write ("\ + + retry: + + result = js_vm_apply (vm, \"" + this.name + "\", NULL, " + + (i + 1).toString () + ", argv); + if (result == 0) + { + JSNode *n = &vm->globals[js_vm_intern (vm, \"" + this.name + "\")]; + + if (n->type != JS_FUNC) + { + JSByteCode *bc = js_bc_read_data (" + this.name + "_bc, + sizeof (" + this.name + "_bc)); + result = js_vm_execute (vm, bc); + js_bc_free (bc); + + if (result == 0) + jswrap_error (interp, \"initialization of function`" + + this.name + "' failed\"); + goto retry; + } + jswrap_error (interp, \"execution of function `" + + this.name + "' failed\"); + } +"); + + /* Handle out and inout parameters. */ + for (i = 0; i < this.args.length; i++) + { + var arg = this.args[i]; + if (arg.copy_type == tIN) + continue; + + var spos = (this.args.length - i).toString (); + + /* Check that we have there a correct type. */ + stream.write (" + if ((vm->sp - " + spos + ")->type != " + jsint_typename (arg.type) + ") + jswrap_error (interp, + \"wrong return type for argument `" + + arg.name + "' of function `" + this.name + "'\"); +"); + + /* Handle the different types. */ + if (arg.type == tCSTRING) + { + stream.write ("\ + *" + arg.name + " = (char *) js_vm_alloc (vm, (vm->sp - " + + spos + ")->u.vstring->len + 1); + memcpy (*" + arg.name + ", (vm->sp - " + spos + ")->u.vstring->data, + (vm->sp - " + spos + ")->u.vstring->len); + " + arg.name + "[(vm->sp - " + spos + ")->u.vstring->len] = '\\0'; +"); + } + else if (arg.type == tDOUBLE) + { + stream.write ("\ + *" + arg.name + " = (vm->sp - " + spos + ")->u.vfloat;\n"); + } + else if (arg.type == tINT) + { + stream.write ("\ + *" + arg.name + " = (vm->sp - " + spos + ")->u.vinteger;\n"); + } + else if (arg.type == tSTRING) + { + stream.write ("\ + *" + arg.name + " = (vm->sp - " + spos + ")->u.vstring->data; + *" + arg.name + "_len = (vm->sp - " + spos + ")->u.vstring->len; +"); + } + } + + /* Handle the function return value. */ + if (this.return_type != tVOID) + { + /* Check that the code returned correct type. */ + stream.write (" + if (vm->exec_result.type != " + jsint_typename (this.return_type) + ") + jswrap_error (interp, \"return type mismatch in function `" + + this.name + "'\"); + +"); + + /* Handle the different types. */ + if (this.return_type == tCSTRING) + { + stream.write ("\ + cp = (char *) js_vm_alloc (vm, vm->exec_result.u.vstring->len + 1); + memcpy (cp, vm->exec_result.u.vstring->data, vm->exec_result.u.vstring->len); + cp[vm->exec_result.u.vstring->len] = '\\0'; + + return cp; +"); + } + else if (this.return_type == tDOUBLE) + stream.write (" return vm->exec_result.u.vfloat;\n"); + else if (this.return_type == tINT) + stream.write (" return vm->exec_result.u.vinteger;\n"); + } + + stream.write ("}\n"); +} +Func.prototype.print_c = Func$print_c; + +function Func$compile () +{ + /* Create the byte-code for this function. */ + + var flags = 0; + + if (false) + flags |= JSC$FLAG_VERBOSE; + + if (opt_debug) + flags |= JSC$FLAG_GENERATE_DEBUG_INFO; + + flags |= (JSC$FLAG_OPTIMIZE_PEEPHOLE + | JSC$FLAG_OPTIMIZE_JUMPS + | JSC$FLAG_OPTIMIZE_BC_SIZE); + + flags |= JSC$FLAG_WARN_MASK; + + try + { + this.bc = JSC$compile_string (this.code, flags, null, null); + } + catch (error) + { + System.error (error, "\n"); + System.exit (1); + } +} +Func.prototype.compile = Func$compile; + +function Func$dump_bc (stream) +{ + stream.write ("\nstatic unsigned char " + this.name + "_bc[] = {"); + + var i; + for (i = 0; i < this.bc.length; i++) + { + if ((i % 12) == 0) + stream.write ("\n "); + + var item = this.bc[i].toString (16); + if (item.length == 1) + item = "0" + item; + + stream.write (" 0x" + item + ","); + } + + stream.write ("\n};\n"); +} +Func.prototype.dump_bc = Func$dump_bc; + +/* + * The Argument class to hold function argument definitions. + */ + +function Argument () +{ + this.type = false; + this.copy_type = tIN; + this.staticp = false; +} + +new Argument (); + +function Argument$print () +{ + System.print (typename (this.copy_type), " ", typename (this.type), + " ", this.name); +} +Argument.prototype.print = Argument$print; + + + +/* + * The .jsw file parsing. + */ + +function parse () +{ + var token; + var func; + + headers (); + + while ((token = get_token ()) != tEOF) + { + if (token != tFUNCTION) + syntax_error (); + + func = new Func (); + + /* Possible return type. */ + token = get_token (); + if (is_type_token (token)) + { + if (token == tSTRING) + { + System.error (input_file, ":", linenum, + ": the function return value can't be `string'\n"); + System.exit (1); + } + + func.return_type = token; + + token = get_token (); + } + else + func.return_type = tVOID; + + /* The name of the function. */ + if (token != tIDENTIFIER) + syntax_error (); + + if (!valid_c_identifier_re.test (token_value)) + { + System.error (input_file, ":", linenum, + ": function name is not a valid C identifier `", + token_value, "'\n"); + System.exit (1); + } + + func.name = token_value; + + /* Arguments. */ + token = get_token (); + if (token != #'(') + syntax_error (); + + var args = new Array (); + + token = get_token (); + while (token != #')') + { + var arg = new Argument (); + + while (token != tIDENTIFIER) + { + if (token == tEOF) + syntax_error (); + + if (is_type_token (token)) + arg.type = token; + else if (is_copy_type_token (token)) + arg.copy_type = token; + else if (token == tSTATIC) + arg.staticp = true; + else + syntax_error (); + + token = get_token (); + } + + if (!valid_c_identifier_re.test (token_value)) + { + System.error (input_file, ":", linenum, + ": argument name is not a valid C identifier `", + token_value, "'\n"); + System.exit (1); + } + arg.name = token_value; + + /* Check some validity conditions. */ + if (!arg.type) + { + System.error (input_file, ":", linenum, + ": no type specified for argument `", + arg.name, "'\n"); + System.exit (1); + } + if (arg.staticp) + { + if (arg.type != tCSTRING && arg.type != tSTRING) + { + System.error (input_file, ":", linenum, + ": type `static' can only be used with `cstring' and `string' arguments\n"); + System.exit (1); + } + if (arg.copy_type == tOUT) + System.error (input_file, ":", linenum, + ": warning: type `static' is meaningful only with `in' and `inout' arguments\n"); + } + + args.push (arg); + + token = get_token (); + if (token == #',') + token = get_token (); + } + + func.args = args; + + /* The opening '{' of the function body. */ + token = get_token (); + if (token != #'{') + syntax_error (); + + /* Get the function body. */ + var code = new String (""); + while (true) + { + var line = ifp.readln (); + if (!line) + syntax_error (); + linenum++; + + if (end_brace_re.test (line)) + break; + + code.append (line + "\n"); + } + + func.body = code; + func.generate_js (); + + // func.print_js (ofp_js); + func.print_h (ofp_h, true); + func.print_c (ofp_c); + } + + trailers (); +} + +function get_token () +{ + var ch; + + while ((ch = ifp.readByte ()) != -1) + { + if (ch == #' ' || ch == #'\t' || ch == #'\v' || ch == #'\r' + || ch == #'\f') + continue; + + if (ch == #'\n') + { + linenum++; + continue; + } + + token_linenum = linenum; + + if (ch == #'/' && peek_char () == #'*') + { + /* Multi line comment. */ + ifp.readByte (); + while ((ch = ifp.readByte ()) != -1 + && (ch != #'*' || peek_char () != #'/')) + if (ch == #'\n') + linenum++; + + /* Consume the peeked #'/' character. */ + ifp.readByte (); + } + + /* Identifiers and keywords. */ + else if (JSC$lexer_is_identifier_letter (ch)) + { + /* An identifier. */ + var id = String.fromCharCode (ch); + + while ((ch = ifp.readByte ()) != -1 + && (JSC$lexer_is_identifier_letter (ch) + || JSC$lexer_is_decimal_digit (ch))) + id.append (File.byteToString (ch)); + ifp.ungetByte (ch); + + /* Keywords. */ + if (id == "function") + return tFUNCTION; + + /* Types. */ + else if (id == "cstring") + return tCSTRING; + else if (id == "double") + return tDOUBLE; + else if (id == "int") + return tINT; + else if (id == "string") + return tSTRING; + else if (id == "void") + return tVOID; + else if (id == "in") + return tIN; + else if (id == "out") + return tOUT; + else if (id == "inout") + return tINOUT; + else if (id == "static") + return tSTATIC; + + else + { + /* It really is an identifier. */ + token_value = id; + return tIDENTIFIER; + } + } + + /* Just return the character as-is. */ + else + return ch; + } + + /* EOF reached. */ + return tEOF; +} + +function peek_char () +{ + var ch = ifp.readByte (); + ifp.ungetByte (ch); + + return ch; +} + +function syntax_error () +{ + System.error (input_file, ":", linenum, ": syntax error\n"); + System.exit (1); +} + +function headers () +{ + var stream; + + /* The header file. */ + + stream = ofp_h; + header_banner (stream); + + var ppname = path_to_ppname (header_file); + stream.write ("\n#ifndef " + ppname + + "\n#define " + ppname + "\n"); + + /* The C file. */ + stream = ofp_c; + header_banner (stream); + stream.write ("\n#include \n"); + + if (!opt_reentrant) + { + stream.write (" +/* + * This global interpreter handle can be removed with " + program + "'s + * option -r, --reentrant. + */ +"); + stream.write ("extern JSInterpPtr jswrap_interp;\n"); + } + + if (opt_no_error_handler) + { + stream.write (" +/* Prototype for the error handler of the JS runtime errors. */ +"); + stream.write ("void jswrap_error (JSInterpPtr interp, char *error);\n"); + } + else + { + /* Define the default jswrap_error() function. */ + stream.write (" +/* + * This is the default error handler for the JS runtime errors. The default + * handler can be removed with " + program + "'s option -n, --no-error-handler. + * In this case, your code must define the handler function. + */ +"); + stream.write ("\ +static void +jswrap_error (JSInterpPtr interp, char *error) +{ + const char *cp; + + fprintf (stderr, \"JS runtime error: %s\", error); + + cp = js_error_message (interp); + if (cp[0]) + fprintf (stderr, \": %s\", cp); + fprintf (stderr, \"\\n\"); + + exit (1); +} +"); + } + + stream.write (" + +/* + * The global function definitions. + */ +"); +} + +function header_banner (stream) +{ + stream.write ("/* This file is automatically generated from `" + + input_file + "' by " + program + ". */\n"); +} + +path_to_ppname_re = new RegExp ("[^A-Za-z_0-9]", "g"); + +function path_to_ppname (path) +{ + var str = path.toUpperCase ().replace (path_to_ppname_re, "_"); + if (#'0' <= str[0] && str[0] <= #'9') + str = "_" + str; + + return str; +} + +function trailers () +{ + /* The header file. */ + var stream = ofp_h; + stream.write ("\n#endif /* not " + path_to_ppname (header_file) + " */\n"); +} + + +/* +Local variables: +mode: c +End: +*/ diff --git a/reactos/lib/kjs/kjs.def b/reactos/lib/kjs/kjs.def new file mode 100644 index 00000000000..946870b60b7 --- /dev/null +++ b/reactos/lib/kjs/kjs.def @@ -0,0 +1,11 @@ +; $Id: kjs.def,v 1.1 2004/01/10 20:38:17 arty Exp $ +; +; ReactOS Operating System +; +LIBRARY kjs.dll + +EXPORTS +kjs_eval +kjs_system_register +kjs_create_interp +kjs_destroy_interp diff --git a/reactos/lib/kjs/kjs.edf b/reactos/lib/kjs/kjs.edf new file mode 100644 index 00000000000..465370e4ba3 --- /dev/null +++ b/reactos/lib/kjs/kjs.edf @@ -0,0 +1,11 @@ +; $Id: kjs.edf,v 1.1 2004/01/10 20:38:17 arty Exp $ +; +; ReactOS Operating System +; +LIBRARY kjs.dll + +EXPORTS +kjs_eval +kjs_system_register +kjs_create_interp +kjs_destroy_interp diff --git a/reactos/lib/kjs/kjs.rc b/reactos/lib/kjs/kjs.rc new file mode 100644 index 00000000000..5d38cfdceb9 --- /dev/null +++ b/reactos/lib/kjs/kjs.rc @@ -0,0 +1,37 @@ +#include +#include + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +VS_VERSION_INFO VERSIONINFO + FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD + PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", RES_STR_COMPANY_NAME + VALUE "FileDescription", "ReactOS Kernel JavaScript DLL\0" + VALUE "FileVersion", RES_STR_FILE_VERSION + VALUE "InternalName", "kjs\0" + VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT + VALUE "OriginalFilename", "kjs.dll\0" + VALUE "ProductName", RES_STR_PRODUCT_NAME + VALUE "ProductVersion", RES_STR_PRODUCT_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/reactos/lib/kjs/kjsinit.js b/reactos/lib/kjs/kjsinit.js new file mode 100644 index 00000000000..ccf2e852593 --- /dev/null +++ b/reactos/lib/kjs/kjsinit.js @@ -0,0 +1,41 @@ +function write(x) { System.print(x); }' +function regs(n) { return System.regs(n); } +function ebp() { return regs(0); } +function eip() { return regs(1); } +function tf_argmark() { return regs(2); } +function tf_pointer() { return regs(3); } +function tf_tempcs() { return regs(4); } +function tf_tempeip() { return regs(5); } +function dr0() { return regs(6); } +function dr1() { return regs(7); } +function dr2() { return regs(8); } +function dr3() { return regs(9); } +function dr6() { return regs(10); } +function dr7() { return regs(11); } +function gs() { return regs(12) & 0xffff; } +function es() { return regs(13) & 0xffff; } +function ds() { return regs(14) & 0xffff; } +function edx() { return regs(15); } +function ecx() { return regs(16); } +function eax() { return regs(17); } +function tf_pmode() { return regs(18); } +function tf_exl() { return regs(19); } +function fs() { return regs(20) & 0xffff; } +function edi() { return regs(21); } +function cs() { return regs(22) & 0xffff; } +function eflags() { return regs(23); } +function esp() { return regs(24); } +function ss() { return regs(25) & 0xffff; } +function v86_es() { return regs(26) & 0xffff; } +function v86_ds() { return regs(27) & 0xffff; } +function v86_fs() { return regs(28) & 0xffff; } +function v86_gs() { return regs(29) & 0xffff; } +function peekl(a) { return System.mread(4,a); } +function pokel(a,b) { return System.mwrite(4,a,b); } +function peekw(a) { return System.mread(2,a); } +function pokew(a,b) { return System.mwrite(2,a,b); } +function peek(a) { return System.mread(1,a); } +function poke(a,b) { return System.mwrite(1,a,b); } +function regread(x,y) { return System.regread(x,y); } +function findmodule(str) { return System.findmodule(str); } +write('JS Registry Init Complete. Welcome to ReactOS kernel scripting'); \ No newline at end of file diff --git a/reactos/lib/kjs/ksrc/alloc.c b/reactos/lib/kjs/ksrc/alloc.c new file mode 100644 index 00000000000..6da52827b89 --- /dev/null +++ b/reactos/lib/kjs/ksrc/alloc.c @@ -0,0 +1,342 @@ +/* + * Memory allocation routines. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/ksrc/alloc.c,v $ + * $Id: alloc.c,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +#include "ddk/ntddk.h" +#include "jsint.h" + +/* + * Global functions. + */ + +#if JS_DEBUG_MEMORY_LEAKS + +struct mem_debug_st +{ + struct mem_debug_st *next; + struct mem_debug_st *prev; + char *file; + int line; + size_t size; +}; + +typedef struct mem_debug_st MemDebug; + +static MemDebug *mem_debug_blocks = NULL; + +int mem_debug_balance = 0; + +unsigned int alloc_fail = 0; +unsigned int alloc_count = 0; + +static void +register_block (MemDebug *b, size_t size, char *file, int line) +{ + b->next = NULL; + b->prev = NULL; + b->file = file; + b->line = line; + b->size = size; + + if (mem_debug_blocks) + { + b->next = mem_debug_blocks; + mem_debug_blocks->prev = b; + } + + mem_debug_blocks = b; + mem_debug_balance++; +} + + +static void +unregister_block (MemDebug *b) +{ + if (b->file == NULL) + { + fprintf (stderr, "freeing the same block twise\n"); + abort (); + } + + if (b->next) + b->next->prev = b->prev; + + if (b->prev) + b->prev->next = b->next; + else + mem_debug_blocks = b->next; + + b->file = NULL; + + mem_debug_balance--; +} + + +static inline int +check_fail () +{ + return alloc_fail != 0 && ++alloc_count >= alloc_fail; +} + + +void +js_alloc_dump_blocks () +{ + MemDebug *b; + unsigned int bytes = 0; + + fprintf (stderr, "js_alloc_dump_blocks(): #blocks=%d\n", mem_debug_balance); + + for (b = mem_debug_blocks; b; b = b->next) + { + fprintf (stderr, "%s:%d: %lu\n", b->file, b->line, b->size); + bytes += b->size; + } + + fprintf (stderr, "leaks=%u\n", bytes); +} + + + +void * +js_malloc_i (JSVirtualMachine *vm, size_t size, char *file, int line) +{ + MemDebug *ptr; + + ptr = ExAllocatePool (NonPagedPool, + sizeof (MemDebug) + sizeof( size_t ) + size); + if (check_fail () || ptr == NULL) + { + if (vm != NULL) + { + sprintf (vm->error, "VM: memory exhausted"); + js_vm_error (vm); + } + + return NULL; + } + + *((size_t *)ptr) = size; + ptr = &((size_t *)ptr)[1]; + + register_block (ptr, size, file, line); + + return (unsigned char *) ptr + sizeof (MemDebug); +} + + +void * +js_calloc_i (JSVirtualMachine *vm, size_t num, size_t size, char *file, + int line) +{ + MemDebug *ptr; + + ptr = ExAllocatePool (NonPagedPool, sizeof (MemDebug) + sizeof( int ) + num * size); + if (check_fail () || ptr == NULL) + { + if (vm != NULL) + { + sprintf (vm->error, "VM: memory exhausted"); + js_vm_error (vm); + } + + return NULL; + } + + *((size_t *)ptr) = size; + ptr = &((size_t *)ptr)[1]; + + memset (ptr, 0, sizeof (MemDebug) + num * size); + register_block (ptr, num * size, file, line); + + return (unsigned char *) ptr + sizeof (MemDebug); +} + + +void * +js_realloc_i (JSVirtualMachine *vm, void *ptr, size_t size, char *file, + int line) +{ + void *nptr; + MemDebug *b; + + if (ptr == NULL) + return js_malloc_i (vm, size, file, line); + + nptr = js_malloc_i (vm, size, file, line); + if (nptr == NULL) + { + if (vm != NULL) + { + sprintf (vm->error, "VM: memory exhausted"); + js_vm_error (vm); + } + + return NULL; + } + + b = (MemDebug *) ((unsigned char *) ptr - sizeof (MemDebug)); + + memcpy (nptr, ptr, size < b->size ? size : b->size); + + js_free (ptr); + + return nptr; +} + + +void +js_free (void *ptr) +{ + MemDebug *b; + + if (ptr == NULL) + return; + + b = (MemDebug *) ((unsigned char *) ptr - sizeof (MemDebug)); + unregister_block (b); + + ptr = &((size_t *)b)[-1]; + + ExFreePool(ptr); +} + + +char * +js_strdup_i (JSVirtualMachine *vm, const char *str, char *file, int line) +{ + char *tmp; + + tmp = js_malloc_i (vm, strlen (str) + 1, file, line); + if (tmp == NULL) + return NULL; + + strcpy (tmp, str); + + return tmp; +} + +#else /* not JS_DEBUG_MEMORY_LEAKS */ + +void * +js_malloc (JSVirtualMachine *vm, size_t size) +{ + void *ptr; + + ptr = ExAllocatePool (NonPagedPool, sizeof( size_t ) + size); + if (ptr == NULL && vm != NULL) + { + sprintf (vm->error, "VM: memory exhausted"); + js_vm_error (vm); + } + + *((size_t *)ptr) = size; + ptr = &((size_t *)ptr)[1]; + + return ptr; +} + + +void * +js_calloc (JSVirtualMachine *vm, size_t num, size_t size) +{ + void *ptr; + + ptr = ExAllocatePool (NonPagedPool, sizeof( size_t ) + num * size); + if (ptr == NULL && vm != NULL) + { + sprintf (vm->error, "VM: memory exhausted"); + js_vm_error (vm); + } + + *((size_t *)ptr) = size; + ptr = &((size_t *)ptr)[1]; + + RtlZeroMemory( ptr, num * size ); + + return ptr; +} + + +void * +js_realloc (JSVirtualMachine *vm, void *ptr, size_t size) +{ + void *nptr; + size_t old_size; + + if (ptr == NULL) + return js_malloc (vm, size); + + nptr = js_malloc(vm, size); + if (nptr == NULL && vm != NULL) + { + sprintf (vm->error, "VM: memory exhausted"); + js_vm_error (vm); + } + + old_size = ((size_t *)ptr)[-1]; + + if( size && ptr ) { + if (size > old_size) + size = old_size; + RtlCopyMemory( nptr, ptr, size ); + } + + js_free(ptr); + + return nptr; +} + + +void +js_free (void *ptr) +{ + if (ptr == NULL) + return; + + ptr = &((size_t *)ptr)[-1]; + + ExFreePool (ptr); +} + + +char * +js_strdup (JSVirtualMachine *vm, const char *str) +{ + char *tmp; + + tmp = js_malloc (vm, strlen (str) + 1); + if (tmp == NULL) + return NULL; + + strcpy (tmp, str); + + return tmp; +} + +#endif /* not JS_DEBUG_MEMORY_LEAKS */ diff --git a/reactos/lib/kjs/ksrc/b_core.c b/reactos/lib/kjs/ksrc/b_core.c new file mode 100644 index 00000000000..4607ad2d473 --- /dev/null +++ b/reactos/lib/kjs/ksrc/b_core.c @@ -0,0 +1,658 @@ +/* + * Core builtins for the JavaScript VM. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/ksrc/b_core.c,v $ + * $Id: b_core.c,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * Global methods: + * + * parseInt (string[, radix]) + * parseFloat (string) + * escape (string) + * unescape (string) + * isNaN (any) + * isFinite (any) + * debug (any) + * error (string) + * float (any) + * int (any) + * isFloat (any) + * isInt (any) + * print (any[,...]) + */ + +#include "jsint.h" + +/* + * Types and definitions. + */ + +#define EMIT_TO_RESULT(c) \ + do { \ + result_return->u.vstring->data = \ + js_vm_realloc (vm, result_return->u.vstring->data, \ + result_return->u.vstring->len + 1); \ + result_return->u.vstring->data[result_return->u.vstring->len] = (c); \ + result_return->u.vstring->len += 1; \ + } while (0) + + +/* + * Static functions. + */ + +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 (vm->error, "parseInt(): illegal amount of arguments"); + 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; +} + + +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 (vm->error, "parseFloat(): illegal amount of arguments"); + 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; +} + + +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; + + if (args->u.vinteger != 1) + { + sprintf (vm->error, "escape(): illegal amount of arguments"); + 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 + * 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 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_+-./", + 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]); + } + } +} + +/* A helper function for unescape(). */ +static int +scanhexdigits (unsigned char *dp, int nd, unsigned int *cp) +{ + static const char digits[] = "0123456789abcdefABCDEF"; + int i; + unsigned int d; + + *cp = 0; + for (i = 0; i < nd; i += 1) + { + d = strchr (digits, dp[i]) - digits; + if (d < 16) + ; + else if (d < 22) + d -= 6; + else + return 0; + + *cp <<= 4; + *cp += d; + } + + return 1; +} + + +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 (vm->error, "unescape(): illegal amount of arguments"); + 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 + * 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); + } +} + + +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, "isNaN(): illegal amount of arguments"); + 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; +} + + +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 (vm->error, "isFinite(): illegal amount of arguments"); + 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; +} + + +static void +debug_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSNode *result_return, + JSNode *args) +{ + JSNode sitem; + + if (args->u.vinteger != 1) + { + sprintf (vm->error, "debug(): illegal amount of arguments"); + js_vm_error (vm); + } + + /* + * Maybe we should prefix the debug message with `Debug message:' + * prompt. + */ + js_vm_to_string (vm, &args[1], &sitem); + + result_return->type = JS_UNDEFINED; +} + + +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, "error(): illegal amount of arguments"); + js_vm_error (vm); + } + if (args[1].type != JS_STRING) + { + sprintf (vm->error, "error(): 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 */ +} + + +static void +float_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSNode *result_return, + JSNode *args) +{ + double fval; + char *cp, *end; + + if (args->u.vinteger != 1) + { + sprintf (vm->error, "float(): illegal amount of arguments"); + js_vm_error (vm); + } + + switch (args[1].type) + { + case JS_BOOLEAN: + fval = (double) (args[1].u.vboolean != 0); + break; + + case JS_INTEGER: + fval = (double) args[1].u.vinteger; + break; + + case JS_STRING: + cp = js_string_to_c_string (vm, &args[1]); + fval = strtod (cp, &end); + js_free (cp); + + if (cp == end) + fval = 0.0; + break; + + case JS_FLOAT: + fval = args[1].u.vfloat; + break; + + case JS_ARRAY: + fval = (double) args[1].u.varray->length; + break; + + default: + fval = 0.0; + break; + } + + result_return->type = JS_FLOAT; + result_return->u.vfloat = fval; +} + + +static void +int_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSNode *result_return, + JSNode *args) +{ + long ival; + char *cp, *end; + + if (args->u.vinteger != 1) + { + sprintf (vm->error, "int(): illegal amount of arguments"); + js_vm_error (vm); + } + + switch (args[1].type) + { + case JS_BOOLEAN: + ival = (long) (args[1].u.vboolean != 0); + break; + + case JS_INTEGER: + ival = args[1].u.vinteger; + break; + + case JS_STRING: + cp = js_string_to_c_string (vm, &args[1]); + ival = strtol (cp, &end, 0); + js_free (cp); + + if (cp == end) + ival = 0; + break; + + case JS_FLOAT: + ival = (long) args[1].u.vfloat; + break; + + case JS_ARRAY: + ival = (long) args[1].u.varray->length; + break; + + default: + ival = 0; + break; + } + + result_return->type = JS_INTEGER; + result_return->u.vinteger = ival; +} + + +static void +isFloat_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSNode *result_return, + JSNode *args) +{ + /* The default result is false. */ + result_return->type = JS_BOOLEAN; + result_return->u.vboolean = 0; + + if (args->u.vinteger != 1) + { + sprintf (vm->error, "isFloat(): illegal amount of arguments"); + js_vm_error (vm); + } + + if (args[1].type == JS_FLOAT) + result_return->u.vboolean = 1; +} + + +static void +isInt_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSNode *result_return, + JSNode *args) +{ + /* The default result is false. */ + result_return->type = JS_BOOLEAN; + result_return->u.vboolean = 0; + + if (args->u.vinteger != 1) + { + sprintf (vm->error, "isInt(): illegal amount of arguments"); + js_vm_error (vm); + } + + if (args[1].type == JS_INTEGER) + result_return->u.vboolean = 1; +} + + +static void +print_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSNode *result_return, + JSNode *args) +{ + int i; + + /* The result is undefined. */ + result_return->type = JS_UNDEFINED; + + for (i = 1; i <= args->u.vinteger; i++) + { + JSNode result; + + js_vm_to_string (vm, &args[i], &result); + js_iostream_write (vm->s_stdout, result.u.vstring->data, + result.u.vstring->len); + + if (i + 1 <= args->u.vinteger) + js_iostream_write (vm->s_stdout, " ", 1); + } + + js_iostream_write (vm->s_stdout, JS_HOST_LINE_BREAK, JS_HOST_LINE_BREAK_LEN); +} + + +/* + * Global functions. + */ + +static struct +{ + char *name; + JSBuiltinGlobalMethod method; +} global_methods[] = +{ + {"parseInt", parseInt_global_method}, + {"parseFloat", parseFloat_global_method}, + {"escape", escape_global_method}, + {"unescape", unescape_global_method}, + {"isNaN", isNaN_global_method}, + {"isFinite", isFinite_global_method}, + {"debug", debug_global_method}, + {"error", error_global_method}, + {"float", float_global_method}, + {"int", int_global_method}, + {"isFloat", isFloat_global_method}, + {"isInt", isInt_global_method}, + {"print", print_global_method}, + + {NULL, NULL}, +}; + + +void +js_builtin_core (JSVirtualMachine *vm) +{ + int i; + JSNode *n; + + /* Properties. */ + + n = &vm->globals[js_vm_intern (vm, "NaN")]; + n->type = JS_NAN; + + n = &vm->globals[js_vm_intern (vm, "Infinity")]; + JS_MAKE_POSITIVE_INFINITY (n); + + /* Global methods. */ + for (i = 0; global_methods[i].name; i++) + { + JSBuiltinInfo *info; + + info = js_vm_builtin_info_create (vm); + info->global_method_proc = global_methods[i].method; + + n = &vm->globals[js_vm_intern (vm, global_methods[i].name)]; + js_vm_builtin_create (vm, n, info, NULL); + } +} diff --git a/reactos/lib/kjs/ksrc/b_file.c b/reactos/lib/kjs/ksrc/b_file.c new file mode 100644 index 00000000000..05d4a90dbda --- /dev/null +++ b/reactos/lib/kjs/ksrc/b_file.c @@ -0,0 +1,1024 @@ +/* + * The builtin File object. + * Copyright (c) 1998-1999 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/ksrc/b_file.c,v $ + * $Id: b_file.c,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * Static methods. + * + * byteToString (BYTE) => string + * + chmod (string, int) => boolean + * + lstat (PATH) => array / boolean + * + remove (PATH) => boolean + * + rename (FROM, TO) => boolean + * + stat (PATH) => array / boolean + * stringToByte (STRING) => number + * + * Methods: + * + * open (MODE) => boolean + * close () => boolean + * setPosition (POSITION [, WHENCE]) => boolean + * getPosition () => integer + * eof () => boolean + * read (SIZE) => string + * readln () => string + * readByte () => integer + * write (STRING) => boolean + * writeln (STRING) => boolean + * writeByte (INTEGER) => boolean + * + ungetByte (BYTE) => boolean + * flush () => boolean + * getLength () => integer + * exists () => boolean + * error () => integer + * clearError () => true + * + * Properties: + * + * autoFlush boolean mutable + * bufferSize integer mutable + */ + +#include "jsint.h" + +#include + +/* + * Types and definitions. + */ + +#define INSECURE() \ + do { \ + if (secure_mode) \ + goto insecure_feature; \ + } while (0) + +/* Class context. */ +struct file_ctx_st +{ + /* Static methods. */ + JSSymbol s_byteToString; + JSSymbol s_chmod; + JSSymbol s_lstat; + JSSymbol s_remove; + JSSymbol s_rename; + JSSymbol s_stat; + JSSymbol s_stringToByte; + + /* Methods */ + JSSymbol s_open; + JSSymbol s_close; + JSSymbol s_setPosition; + JSSymbol s_getPosition; + JSSymbol s_eof; + JSSymbol s_read; + JSSymbol s_readln; + JSSymbol s_readByte; + JSSymbol s_write; + JSSymbol s_writeln; + JSSymbol s_writeByte; + JSSymbol s_ungetByte; + JSSymbol s_flush; + JSSymbol s_getLength; + JSSymbol s_exists; + JSSymbol s_error; + JSSymbol s_clearError; + + /* Properties. */ + JSSymbol s_autoFlush; + JSSymbol s_bufferSize; +}; + +typedef struct file_ctx_st FileCtx; + +/* Instance context. */ +struct file_instance_ctx_st +{ + /* Flags. */ + unsigned int dont_close : 1; + + char *path; + JSIOStream *stream; + + /* Needed for the delete_proc. */ + JSVirtualMachine *vm; +}; + +typedef struct file_instance_ctx_st FileInstanceCtx; + + +/* + * Static functions. + */ + +/* Method proc. */ +static int +method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol method, JSNode *result_return, + JSNode *args) +{ + FileCtx *ctx = builtin_info->obj_context; + FileInstanceCtx *ictx = instance_context; + char buf[256]; + long int li = 0; + int i = 0; + /* char *cp; */ + int secure_mode = vm->security & JS_VM_SECURE_FILE; + + /* The default result is false. */ + result_return->type = JS_BOOLEAN; + result_return->u.vboolean = 0; + + /* + * Static methods. + */ + if (method == ctx->s_byteToString) + { + if (args->u.vinteger != 1) + goto argument_error; + + i = -1; + if (args[1].type == JS_INTEGER) + { + i = args[1].u.vinteger; + if (i < 0 || i > 255) + i = -1; + } + + js_vm_make_string (vm, result_return, NULL, 1); + + if (i < 0) + result_return->u.vstring->len = 0; + else + result_return->u.vstring->data[0] = i; + } + /* ********************************************************************** */ + else if (method == ctx->s_chmod) + { +#if 0 + INSECURE (); + + if (args->u.vinteger != 2) + goto argument_error; + if (args[1].type != JS_STRING) + goto argument_type_error; + if (args[2].type != JS_INTEGER) + goto argument_type_error; + + result_return->type= JS_BOOLEAN; + + cp = js_string_to_c_string (vm, &args[1]); + result_return->u.vboolean = (chmod (cp, args[2].u.vinteger) == 0); + js_free (cp); +#endif + } + /* ********************************************************************** */ + else if (method == ctx->s_lstat || method == ctx->s_stat) + { +#if 0 + char *path; + struct stat stat_st; + int result; + + INSECURE (); + + if (args->u.vinteger != 1) + goto argument_error; + + path = js_string_to_c_string (vm, &args[1]); + +#if HAVE_LSTAT + if (method == ctx->s_lstat) + result = lstat (path, &stat_st); + else +#endif /* HAVE_LSTAT */ + result = stat (path, &stat_st); + + js_free (path); + + if (result >= 0) + { + JSNode *node; + + /* Success. */ + js_vm_make_array (vm, result_return, 13); + node = result_return->u.varray->data; + + /* dev */ + node->type = JS_INTEGER; + node->u.vinteger = stat_st.st_dev; + node++; + + /* ino */ + node->type = JS_INTEGER; + node->u.vinteger = stat_st.st_ino; + node++; + + /* mode */ + node->type = JS_INTEGER; + node->u.vinteger = stat_st.st_mode; + node++; + + /* nlink */ + node->type = JS_INTEGER; + node->u.vinteger = stat_st.st_nlink; + node++; + + /* uid */ + node->type = JS_INTEGER; + node->u.vinteger = stat_st.st_uid; + node++; + + /* gid */ + node->type = JS_INTEGER; + node->u.vinteger = stat_st.st_gid; + node++; + + /* rdev */ + node->type = JS_INTEGER; + node->u.vinteger = stat_st.st_rdev; + node++; + + /* size */ + node->type = JS_INTEGER; + node->u.vinteger = stat_st.st_size; + node++; + + /* atime */ + node->type = JS_INTEGER; + node->u.vinteger = stat_st.st_atime; + node++; + + /* mtime */ + node->type = JS_INTEGER; + node->u.vinteger = stat_st.st_mtime; + node++; + + /* ctime */ + node->type = JS_INTEGER; + node->u.vinteger = stat_st.st_ctime; + node++; + + /* blksize */ + node->type = JS_INTEGER; +#if HAVE_STAT_ST_ST_BLKSIZE + node->u.vinteger = stat_st.st_blksize; +#else /* not HAVE_STAT_ST_ST_BLKSIZE */ + node->u.vinteger = 0; +#endif /* not HAVE_STAT_ST_ST_BLKSIZE */ + node++; + + /* blocks */ + node->type = JS_INTEGER; +#if HAVE_STAT_ST_ST_BLOCKS + node->u.vinteger = stat_st.st_blocks; +#else /* not HAVE_STAT_ST_ST_BLOCKS */ + node->u.vinteger = 0; +#endif /* not HAVE_STAT_ST_ST_BLOCKS */ + } +#endif + } + /* ********************************************************************** */ + else if (method == ctx->s_remove) + { +#if 0 + char *path; + + INSECURE (); + + 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]); + i = remove (path); + js_free (path); + + result_return->u.vboolean = (i == 0); +#endif + } + /* ********************************************************************** */ + else if (method == ctx->s_rename) + { +#if 0 + char *path1; + char *path2; + + INSECURE (); + + if (args->u.vinteger != 2) + goto argument_error; + + if (args[1].type != JS_STRING || args[2].type != JS_STRING) + goto argument_type_error; + + path1 = js_string_to_c_string (vm, &args[1]); + path2 = js_string_to_c_string (vm, &args[2]); + + i = rename (path1, path2); + + js_free (path1); + js_free (path2); + + result_return->u.vboolean = (i == 0); +#endif + } + /* ********************************************************************** */ + else if (method == ctx->s_stringToByte) + { + if (args->u.vinteger != 1) + goto argument_error; + + result_return->type = JS_INTEGER; + + if (args[1].type == JS_STRING && args[1].u.vstring->len > 0) + result_return->u.vinteger = args[i].u.vstring->data[0]; + else + result_return->u.vinteger = 0; + } + /* ********************************************************************** */ + else if (method == vm->syms.s_toString) + { + if (args->u.vinteger != 0) + goto argument_error; + + if (ictx) + js_vm_make_string (vm, result_return, ictx->path, strlen (ictx->path)); + else + js_vm_make_static_string (vm, result_return, "File", 4); + } + /* ********************************************************************** */ + else if (ictx) + { + /* + * Instance methods. + */ + + if (method == ctx->s_open) + { + int readp = 0; + int writep = 0; + + INSECURE (); + + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_STRING + || args[1].u.vstring->len == 0 + || args[1].u.vstring->len > 3) + goto argument_type_error; + + i = args[1].u.vstring->len; + memcpy (buf, args[1].u.vstring->data, i); + + if (buf[i - 1] != 'b') + buf[i++] = 'b'; + buf[i] = '\0'; + + /* Check that the mode is valid. */ + if (strcmp (buf, "rb") == 0) + readp = 1; + else if (strcmp (buf, "wb") == 0) + writep = 1; + else if (strcmp (buf, "ab") == 0) + writep = 1; + else if (strcmp (buf, "r+b") == 0) + readp = writep = 1; + else if (strcmp (buf, "w+b") == 0) + readp = writep = 1; + else if (strcmp (buf, "a+b") == 0) + readp = writep = 1; + else + { + sprintf (vm->error, "File.%s(): illegal open mode \"%s\"", + js_vm_symname (vm, method), buf); + js_vm_error (vm); + } + + if (ictx->stream == NULL) + { +#if 0 + /* Do open. */ + JS_VM_ALLOCATE_FD (vm, "File.open()"); + ictx->stream = js_iostream_file (fopen (ictx->path, buf), readp, + writep, 1); + if (ictx->stream == NULL) + JS_VM_FREE_FD (vm); + else + result_return->u.vboolean = 1; +#endif + } + } + /* ***************************************************************** */ + else if (method == ctx->s_close) + { + if (ictx->stream != NULL) + { + int result = 0; + + if (!ictx->dont_close) + { + result = js_iostream_close (ictx->stream); + JS_VM_FREE_FD (vm); + } + + ictx->stream = NULL; + result_return->u.vboolean = result >= 0; + } + } + /* ***************************************************************** */ + else if (method == ctx->s_setPosition) + { + if (args->u.vinteger == 1) + { + if (args[1].type != JS_INTEGER) + goto argument_type_error; + li = args[1].u.vinteger; + i = SEEK_SET; + } + else if (args->u.vinteger == 2) + { + if (args[2].type == JS_INTEGER) + { + switch (args[2].u.vinteger) + { + case 1: + i = SEEK_CUR; + break; + + case 2: + i = SEEK_END; + break; + + default: + i = SEEK_SET; + break; + } + } + else + i = SEEK_SET; + } + else + goto argument_error; + + if (ictx->stream && js_iostream_seek (ictx->stream, li, i) >= 0) + result_return->u.vboolean = 1; + } + /* ***************************************************************** */ + else if (method == ctx->s_getPosition) + { + if (args->u.vinteger != 0) + goto argument_error; + + result_return->type = JS_INTEGER; + if (ictx->stream == NULL) + result_return->u.vinteger = -1; + else + result_return->u.vinteger + = js_iostream_get_position (ictx->stream); + } + /* ***************************************************************** */ + else if (method == ctx->s_eof) + { + if (args->u.vinteger != 0) + goto argument_error; + + if (ictx->stream != NULL) + result_return->u.vboolean = ictx->stream->at_eof; + } + /* ***************************************************************** */ + else if (method == ctx->s_read) + { + size_t got; + char *buffer; + + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_INTEGER || args[1].u.vinteger < 0) + goto argument_type_error; + + if (ictx->stream != NULL) + { + buffer = js_vm_alloc (vm, args[1].u.vinteger + 1); + + got = js_iostream_read (ictx->stream, buffer, + args[1].u.vinteger); + if (got < 0) + got = 0; + + js_vm_make_static_string (vm, result_return, buffer, got); + result_return->u.vstring->staticp = 0; + } + } + /* ***************************************************************** */ + else if (method == ctx->s_readln) + { + /* int ch; */ + unsigned int bufpos = 0; + unsigned int buflen = 0; + char *buffer = NULL; + + if (args->u.vinteger != 0) + goto argument_error; + + if (ictx->stream != NULL) + { + /* Flush all buffered output data. */ + js_iostream_flush (ictx->stream); + + while (1) + { + /* Process all the data we have in the buffer. */ + for (; ictx->stream->bufpos < ictx->stream->data_in_buf + && (ictx->stream->buffer[ictx->stream->bufpos] + != '\n'); + ictx->stream->bufpos++) + { + if (bufpos >= buflen) + { + buflen += 1024; + buffer = js_vm_realloc (vm, buffer, buflen); + } + buffer[bufpos++] + = ictx->stream->buffer[ictx->stream->bufpos]; + } + + if (ictx->stream->bufpos >= ictx->stream->data_in_buf) + { + /* int result; */ + + /* Read past the buffer. */ + if (ictx->stream->at_eof) + /* EOF seen. */ + break; + + /* Read more data. */ + js_iostream_fill_buffer (ictx->stream); + } + else + { + /* Got it. Skip the newline character. */ + ictx->stream->bufpos++; + break; + } + } + + /* Remove '\r' characters. */ + while (bufpos > 0) + if (buffer[bufpos - 1] == '\r') + bufpos--; + else + break; + + if (buffer == NULL) + /* An empty string. Allocate one byte. */ + buffer = js_vm_alloc (vm, 1); + + /* + * Use the data we already had. In maximum, it has only + * 1023 bytes overhead. + */ + js_vm_make_static_string (vm, result_return, buffer, bufpos); + result_return->u.vstring->staticp = 0; + } + } + /* ***************************************************************** */ + else if (method == ctx->s_readByte) + { + result_return->type = JS_INTEGER; + if (ictx->stream == NULL) + result_return->u.vinteger = -1; + else + { + retry: + if (ictx->stream->bufpos < ictx->stream->data_in_buf) + result_return->u.vinteger + = ictx->stream->buffer[ictx->stream->bufpos++]; + else + { + if (ictx->stream->at_eof) + result_return->u.vinteger = -1; + else + { + js_iostream_fill_buffer (ictx->stream); + goto retry; + } + } + } + } + /* ***************************************************************** */ + else if (method == ctx->s_write || method == ctx->s_writeln) + { + size_t wrote; + int autoflush; + + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_STRING) + goto argument_type_error; + + if (ictx->stream != NULL) + { + autoflush = ictx->stream->autoflush; + ictx->stream->autoflush = 0; + + wrote = js_iostream_write (ictx->stream, + args[1].u.vstring->data, + args[1].u.vstring->len); + if (wrote == args[1].u.vstring->len) + { + /* Success. */ + result_return->u.vboolean = 1; + + if (method == ctx->s_writeln) + if (js_iostream_write (ictx->stream, + JS_HOST_LINE_BREAK, + JS_HOST_LINE_BREAK_LEN) < 0) + /* No, it was not a success. */ + result_return->u.vboolean = 0; + } + + ictx->stream->autoflush = autoflush; + if (autoflush) + js_iostream_flush (ictx->stream); + } + } + /* ***************************************************************** */ + else if (method == ctx->s_writeByte) + { + unsigned char buf[1]; + + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_INTEGER) + goto argument_type_error; + + buf[0] = args[1].u.vinteger; + + if (ictx->stream != NULL) + result_return->u.vboolean + = js_iostream_write (ictx->stream, buf, 1) >= 0; + } + /* ***************************************************************** */ + else if (method == ctx->s_ungetByte) + { + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_INTEGER) + goto argument_type_error; + + if (ictx->stream != NULL) + result_return->u.vboolean + = js_iostream_unget (ictx->stream, args[1].u.vinteger); + } + /* ***************************************************************** */ + else if (method == ctx->s_flush) + { + if (args->u.vinteger != 0) + goto argument_error; + + if (ictx->stream != NULL && js_iostream_flush (ictx->stream) >= 0) + result_return->u.vboolean = 1; + } + /* ***************************************************************** */ + else if (method == ctx->s_getLength) + { + if (args->u.vinteger != 0) + goto argument_error; + + /* The default error code is an integer -1. */ + result_return->type = JS_INTEGER; + result_return->u.vinteger = -1; + + if (ictx->stream != NULL) + result_return->u.vinteger + = js_iostream_get_length (ictx->stream); + } + /* ***************************************************************** */ + else if (method == ctx->s_exists) + { +#if 0 + if (args->u.vinteger != 0) + goto argument_error; + + if (ictx->stream) + { + /* Since we have opened the file, it must exist. */ + result_return->u.vboolean = 1; + } + else + { + struct stat stat_st; + + if (stat (ictx->path, &stat_st) >= 0) + result_return->u.vboolean = 1; + } +#endif + } + /* ***************************************************************** */ + else if (method == ctx->s_error) + { + if (args->u.vinteger != 0) + goto argument_error; + + result_return->type = JS_INTEGER; + if (ictx->stream == NULL) + result_return->u.vinteger = -1; + else + result_return->u.vinteger = ictx->stream->error; + } + /* ***************************************************************** */ + else if (method == ctx->s_clearError) + { + if (args->u.vinteger != 0) + goto argument_error; + + if (ictx->stream != NULL) + { + ictx->stream->error = 0; + result_return->u.vboolean = 1; + } + } + /* ***************************************************************** */ + else + return JS_PROPERTY_UNKNOWN; + } + else + return JS_PROPERTY_UNKNOWN; + + return JS_PROPERTY_FOUND; + + + /* + * Error handling. + */ + + argument_error: + sprintf (vm->error, "File.%s(): illegal amount of arguments", + js_vm_symname (vm, method)); + js_vm_error (vm); + + argument_type_error: + sprintf (vm->error, "File.%s(): illegal argument", + js_vm_symname (vm, method)); + js_vm_error (vm); + + insecure_feature: + sprintf (vm->error, "File.%s(): not allowed in secure mode", + 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) +{ + FileCtx *ctx = builtin_info->obj_context; + FileInstanceCtx *ictx = instance_context; + + if (ictx) + { + /* Instance properties. */ + if (property == ctx->s_autoFlush) + { + if (ictx->stream == NULL) + goto not_open; + + if (set) + { + if (node->type != JS_BOOLEAN) + goto argument_type_error; + + ictx->stream->autoflush = node->u.vboolean; + } + else + { + node->type = JS_BOOLEAN; + node->u.vboolean = ictx->stream->autoflush; + } + } + /* ***************************************************************** */ + else if (property == ctx->s_bufferSize) + { + if (ictx->stream == NULL) + goto not_open; + + if (set) + { + unsigned char *buf; + unsigned int len; + + if (node->type != JS_INTEGER) + goto argument_type_error; + + js_iostream_flush (ictx->stream); + + len = node->u.vinteger; + buf = js_realloc (vm, ictx->stream->buffer, len); + + ictx->stream->buflen = len; + ictx->stream->buffer = buf; + } + else + { + node->type = JS_INTEGER; + node->u.vinteger = ictx->stream->buflen; + } + } + /* ***************************************************************** */ + else + { + if (!set) + node->type = JS_UNDEFINED; + + return JS_PROPERTY_UNKNOWN; + } + } + else + { + if (!set) + node->type = JS_UNDEFINED; + + return JS_PROPERTY_UNKNOWN; + } + + return JS_PROPERTY_FOUND; + + + /* Error handling. */ + + argument_type_error: + sprintf (vm->error, "File.%s: illegal value", + js_vm_symname (vm, property)); + js_vm_error (vm); + + not_open: + sprintf (vm->error, "File.%s: the stream is not opened", + 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) +{ + FileInstanceCtx *instance; + + if (args->u.vinteger != 1) + { + sprintf (vm->error, "new File(): illegal amount of arguments"); + js_vm_error (vm); + } + if (args[1].type != JS_STRING) + { + sprintf (vm->error, "new File(): illegal argument"); + js_vm_error (vm); + } + + instance = js_calloc (vm, 1, sizeof (*instance)); + instance->path = js_string_to_c_string (vm, &args[1]); + instance->vm = vm; + + js_vm_builtin_create (vm, result_return, builtin_info, instance); +} + +/* Delete proc. */ +static void +delete_proc (JSBuiltinInfo *builtin_info, void *instance_context) +{ + FileInstanceCtx *ictx = instance_context; + + if (ictx) + { + if (ictx->stream) + { + if (!ictx->dont_close) + { + js_iostream_close (ictx->stream); + JS_VM_FREE_FD (ictx->vm); + } + + ictx->stream = NULL; + } + + js_free (ictx->path); + js_free (ictx); + } +} + +/* + * Global functions. + */ + +void +js_builtin_File (JSVirtualMachine *vm) +{ + JSNode *n; + JSBuiltinInfo *info; + FileCtx *ctx; + + ctx = js_calloc (vm, 1, sizeof (*ctx)); + + ctx->s_byteToString = js_vm_intern (vm, "byteToString"); + ctx->s_chmod = js_vm_intern (vm, "chmod"); + ctx->s_lstat = js_vm_intern (vm, "lstat"); + ctx->s_remove = js_vm_intern (vm, "remove"); + ctx->s_rename = js_vm_intern (vm, "rename"); + ctx->s_stat = js_vm_intern (vm, "stat"); + ctx->s_stringToByte = js_vm_intern (vm, "stringToByte"); + + ctx->s_open = js_vm_intern (vm, "open"); + ctx->s_close = js_vm_intern (vm, "close"); + ctx->s_setPosition = js_vm_intern (vm, "setPosition"); + ctx->s_getPosition = js_vm_intern (vm, "getPosition"); + ctx->s_eof = js_vm_intern (vm, "eof"); + ctx->s_read = js_vm_intern (vm, "read"); + ctx->s_readln = js_vm_intern (vm, "readln"); + ctx->s_readByte = js_vm_intern (vm, "readByte"); + ctx->s_write = js_vm_intern (vm, "write"); + ctx->s_writeln = js_vm_intern (vm, "writeln"); + ctx->s_writeByte = js_vm_intern (vm, "writeByte"); + ctx->s_ungetByte = js_vm_intern (vm, "ungetByte"); + ctx->s_flush = js_vm_intern (vm, "flush"); + ctx->s_getLength = js_vm_intern (vm, "getLength"); + ctx->s_exists = js_vm_intern (vm, "exists"); + ctx->s_error = js_vm_intern (vm, "error"); + ctx->s_clearError = js_vm_intern (vm, "clearError"); + + ctx->s_autoFlush = js_vm_intern (vm, "autoFlush"); + ctx->s_bufferSize = js_vm_intern (vm, "bufferSize"); + + + /* Object information. */ + + info = js_vm_builtin_info_create (vm); + + info->method_proc = method; + info->property_proc = property; + info->new_proc = new_proc; + info->delete_proc = delete_proc; + info->obj_context = ctx; + info->obj_context_delete = js_free; + + /* Define it. */ + n = &vm->globals[js_vm_intern (vm, "File")]; + js_vm_builtin_create (vm, n, info, NULL); +} + + +void +js_builtin_File_new (JSVirtualMachine *vm, JSNode *result_return, + char *path, JSIOStream *stream, int dont_close) +{ + JSNode *n; + FileInstanceCtx *ictx; + + /* Lookup our context. */ + n = &vm->globals[js_vm_intern (vm, "File")]; + + /* Create a file instance. */ + ictx = js_calloc (vm, 1, sizeof (*ictx)); + ictx->path = js_strdup (vm, path); + ictx->stream = stream; + ictx->dont_close = dont_close; + ictx->vm = vm; + + /* Create the builtin. */ + js_vm_builtin_create (vm, result_return, n->u.vbuiltin->info, ictx); +} diff --git a/reactos/lib/kjs/ksrc/b_func.c b/reactos/lib/kjs/ksrc/b_func.c new file mode 100644 index 00000000000..fbd64a1fe6b --- /dev/null +++ b/reactos/lib/kjs/ksrc/b_func.c @@ -0,0 +1,78 @@ +/* + * The builtin Function object. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/ksrc/b_func.c,v $ + * $Id: b_func.c,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +#include "jsint.h" + +/* + * Static functions. + */ + +/* Method proc. */ +static int +method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol method, JSNode *result_return, + JSNode *args) +{ + return JS_PROPERTY_UNKNOWN; +} + +/* Property proc. */ +static int +property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol property, int set, JSNode *node) +{ + /* JSNode *n = instance_context; */ + + if (!set) + node->type = JS_UNDEFINED; + + return JS_PROPERTY_UNKNOWN; +} + + +/* + * Global functions. + */ + +void +js_builtin_Function (JSVirtualMachine *vm) +{ + JSNode *n; + JSBuiltinInfo *info; + + info = js_vm_builtin_info_create (vm); + vm->prim[JS_FUNC] = info; + + info->method_proc = method; + info->property_proc = property; + + /* Define it. */ + n = &vm->globals[js_vm_intern (vm, "Function")]; + js_vm_builtin_create (vm, n, info, NULL); +} diff --git a/reactos/lib/kjs/ksrc/b_regexp.c b/reactos/lib/kjs/ksrc/b_regexp.c new file mode 100644 index 00000000000..54be7adf442 --- /dev/null +++ b/reactos/lib/kjs/ksrc/b_regexp.c @@ -0,0 +1,1136 @@ +/* + * The builtin RegExp object. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/ksrc/b_regexp.c,v $ + * $Id: b_regexp.c,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +#include "jsint.h" +#include "regex.h" + +/* + * Types and definitions. + */ + +/* These must be in sync with the values, found from `../jsc/asm.js'. */ +#define JS_REGEXP_FLAG_G 0x01 +#define JS_REGEXP_FLAG_I 0x02 + +/* Class context. */ +struct regexp_ctx_st +{ + /* Static properties. */ + JSSymbol s_S1; + JSSymbol s_S2; + JSSymbol s_S3; + JSSymbol s_S4; + JSSymbol s_S5; + JSSymbol s_S6; + JSSymbol s_S7; + JSSymbol s_S8; + JSSymbol s_S9; + JSSymbol s_S_; + JSSymbol s_input; + JSSymbol s_lastMatch; + JSSymbol s_lastParen; + JSSymbol s_leftContext; + JSSymbol s_multiline; + JSSymbol s_rightContext; + + /* Properties. */ + JSSymbol s_global; + JSSymbol s_ignoreCase; + JSSymbol s_lastIndex; + JSSymbol s_source; + + /* Methods. */ + JSSymbol s_compile; + JSSymbol s_exec; + JSSymbol s_test; + + /* Data that is needed for the static properties. */ + + JSNode input; + struct re_registers regs; +}; + +typedef struct regexp_ctx_st RegexpCtx; + +/* RegExp instance context. */ +struct regexp_instance_ctx_st +{ + /* The source for this regexp. */ + char *source; + unsigned int source_len; + + /* Flags. */ + unsigned int global : 1; + unsigned int ignore_case : 1; + unsigned int immutable : 1; + + /* Compiled pattern. */ + struct re_pattern_buffer compiled; + + /* The index from which the next match is started. */ + unsigned int last_index; +}; + +typedef struct regexp_instance_ctx_st RegexpInstanceCtx; + + +/* + * Prorototypes for some static functions. + */ + +static void new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + JSNode *args, JSNode *result_return); + + +/* + * Static functions. + */ + +/* A helper for RegExp.exec(). XXX Check the compliancy. */ +static void +do_exec (JSVirtualMachine *vm, RegexpCtx *ctx, RegexpInstanceCtx *ictx, + char *input, unsigned int input_len, JSNode *result_return) +{ + int result; + int i, j; + + result = re_search (&ictx->compiled, input, input_len, + ictx->global ? ictx->last_index : 0, + input_len, &ctx->regs); + + if (result < 0) + { + result_return->type = JS_NULL; + return; + } + + /* Success. Count how many matches we had. */ + for (i = 0; i < ctx->regs.num_regs && ctx->regs.start[i] >= 0; i++) + ; + + /* Create the result array and enter the sub-matches. */ + js_vm_make_array (vm, result_return, i); + + for (j = 0; j < i; j++) + js_vm_make_string (vm, &result_return->u.varray->data[j], + input + ctx->regs.start[j], + ctx->regs.end[j] - ctx->regs.start[j]); + + ictx->last_index = ctx->regs.end[0]; +} + +/* Method proc. */ +static int +method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol method, JSNode *result_return, + JSNode *args) +{ + RegexpCtx *ctx = builtin_info->obj_context; + RegexpInstanceCtx *ictx = instance_context; + int result; + int i; + + /* Set the default return value. */ + result_return->type = JS_BOOLEAN; + result_return->u.vboolean = 1; + + /* Static methods. */ + if (method == vm->syms.s_toString) + { + if (ictx) + js_vm_make_string (vm, result_return, ictx->source, ictx->source_len); + else + js_vm_make_static_string (vm, result_return, "RegExp", 6); + } + /* ********************************************************************** */ + else if (ictx) + { + /* Methods */ + + if (method == ctx->s_compile) + { + int global = 0; + int ignore_case = 0; + const char *error; + JSNode *pattern; + JSNode pattern_cvt; + + if (ictx->immutable) + goto immutable; + + if (args->u.vinteger != 1 && args->u.vinteger != 2) + goto argument_error; + + if (args[1].type == JS_STRING) + pattern = &args[1]; + else + { + js_vm_to_string (vm, &args[1], &pattern_cvt); + pattern = &pattern_cvt; + } + + if (args->u.vinteger == 2) + { + JSNode *flags; + JSNode cvt; + + if (args[2].type == JS_STRING) + flags = &args[2]; + else + { + js_vm_to_string (vm, &args[2], &cvt); + flags = &cvt; + } + + for (i = 0; i < flags->u.vstring->len; i++) + switch (flags->u.vstring->data[i]) + { + case 'g': + global = 1; + break; + + case 'i': + ignore_case = 1; + break; + + default: + sprintf (vm->error, "new RegExp(): illegal flag `%c'", + flags->u.vstring->data[i]); + js_vm_error (vm); + break; + } + } + + if (ictx->source) + js_free (ictx->source); + + ictx->source_len = pattern->u.vstring->len; + ictx->source = js_malloc (vm, ictx->source_len); + memcpy (ictx->source, pattern->u.vstring->data, ictx->source_len); + + ictx->global = global; + ictx->ignore_case = ignore_case; + + if (ictx->compiled.fastmap) + js_free (ictx->compiled.fastmap); + + memset (&ictx->compiled, 0, sizeof (ictx->compiled)); + + if (ictx->ignore_case) + ictx->compiled.translate = js_latin1_tolower; + + error = re_compile_pattern (ictx->source, ictx->source_len, + &ictx->compiled); + if (error) + { + sprintf (vm->error, + "RegExp.%s(): compilation of the expression failed: %s", + js_vm_symname (vm, method), error); + js_vm_error (vm); + } + ictx->compiled.fastmap = js_malloc (vm, 256); + re_compile_fastmap (&ictx->compiled); + } + /* ***************************************************************** */ + else if (method == ctx->s_exec) + { + char *input; + unsigned int input_len; + JSNode *input_str; + JSNode cvt; + + if (args->u.vinteger == 0) + { + if (ctx->input.type == JS_STRING) + input_str = &ctx->input; + else + { + js_vm_to_string (vm, &ctx->input, &cvt); + input_str = &cvt; + } + + input = input_str->u.vstring->data; + input_len = input_str->u.vstring->len; + } + else if (args->u.vinteger == 1) + { + if (args[1].type == JS_STRING) + input_str = &args[1]; + else + { + js_vm_to_string (vm, &args[1], &cvt); + input_str = &cvt; + } + + input = input_str->u.vstring->data; + input_len = input_str->u.vstring->len; + + /* Set the input property to the class context. */ + JS_COPY (&ctx->input, input_str); + } + else + goto argument_error; + + do_exec (vm, ctx, ictx, input, input_len, result_return); + } + /* ***************************************************************** */ + else if (method == ctx->s_test) + { + char *input; + unsigned int input_len; + JSNode *input_str; + JSNode cvt; + + if (args->u.vinteger == 0) + { + if (ctx->input.type == JS_STRING) + input_str = &ctx->input; + else + { + js_vm_to_string (vm, &ctx->input, &cvt); + input_str = &cvt; + } + + input = input_str->u.vstring->data; + input_len = input_str->u.vstring->len; + } + else if (args->u.vinteger == 1) + { + if (args[1].type == JS_STRING) + input_str = &args[1]; + else + { + js_vm_to_string (vm, &args[1], &cvt); + input_str = &cvt; + } + + input = input_str->u.vstring->data; + input_len = input_str->u.vstring->len; + + /* Set the input property to the class context. */ + JS_COPY (&ctx->input, input_str); + } + else + goto argument_error; + + result = re_search (&ictx->compiled, input, input_len, + ictx->global ? ictx->last_index : 0, + input_len, &ctx->regs); + + result_return->type = JS_BOOLEAN; + result_return->u.vboolean = result >= 0; + + if (result >= 0) + /* ctx->regs.num_regs can be 0. Or can it??? */ + ictx->last_index = ctx->regs.end[0]; + } + /* ***************************************************************** */ + else + return JS_PROPERTY_UNKNOWN; + } + /* ********************************************************************** */ + else + return JS_PROPERTY_UNKNOWN; + + return JS_PROPERTY_FOUND; + + + /* + * Error handling. + */ + + argument_error: + sprintf (vm->error, "RegExp.%s(): illegal amount of arguments", + js_vm_symname (vm, method)); + js_vm_error (vm); + + /* argument_type_error: */ + sprintf (vm->error, "RegExp.%s(): illegal argument", + js_vm_symname (vm, method)); + js_vm_error (vm); + + immutable: + sprintf (vm->error, "RegExp.%s(): immutable object", + js_vm_symname (vm, method)); + js_vm_error (vm); + + /* NOTREACHED. */ + return 0; +} + +/* Global method proc. */ +static void +global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSNode *result_return, + JSNode *args) +{ + RegexpCtx *ctx = builtin_info->obj_context; + RegexpInstanceCtx *ictx = instance_context; + char *input = NULL; /* Initialized to keep the compiler quiet. */ + unsigned int input_len = 0; /* Likewise. */ + + if (ictx) + { + /* A RegExp instance was called as a function. */ + + if (args->u.vinteger == 0) + { + if (ctx->input.type != JS_STRING) + { + sprintf (vm->error, "RegExp(): RegExp.input is not a string"); + js_vm_error (vm); + } + input = ctx->input.u.vstring->data; + input_len = ctx->input.u.vstring->len; + } + else if (args->u.vinteger == 1) + { + if (args[1].type != JS_STRING) + { + sprintf (vm->error, "RegExp(): illegal argument"); + js_vm_error (vm); + } + + input = args[1].u.vstring->data; + input_len = args[1].u.vstring->len; + + /* Set the input property to the class context. */ + JS_COPY (&ctx->input, &args[1]); + } + else + { + sprintf (vm->error, "RegExp(): illegal amount of arguments"); + js_vm_error (vm); + } + + do_exec (vm, ctx, ictx, input, input_len, result_return); + } + else + { + /* + * The `RegExp' was called as a function. We do exactly the + * same the `new RegExp()' would do with our arguments. + */ + new_proc (vm, builtin_info, args, result_return); + } +} + +/* Property proc. */ +static int +property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol property, int set, JSNode *node) +{ + RegexpCtx *ctx = builtin_info->obj_context; + RegexpInstanceCtx *ictx = instance_context; + int index; + + /* Static properties. */ + if (property == ctx->s_S1) + { + index = 1; + + dollar_index: + + if (set) + goto immutable; + + if (ctx->input.type != JS_STRING + || ctx->regs.end[0] > ctx->input.u.vstring->len + || ctx->regs.start[index] < 0) + node->type = JS_UNDEFINED; + else + js_vm_make_string (vm, node, + ctx->input.u.vstring->data + + ctx->regs.start[index], + ctx->regs.end[index] - ctx->regs.start[index]); + } + /* ********************************************************************** */ + else if (property == ctx->s_S2) + { + index = 2; + goto dollar_index; + } + /* ********************************************************************** */ + else if (property == ctx->s_S3) + { + index = 3; + goto dollar_index; + } + /* ********************************************************************** */ + else if (property == ctx->s_S4) + { + index = 4; + goto dollar_index; + } + /* ********************************************************************** */ + else if (property == ctx->s_S5) + { + index = 5; + goto dollar_index; + } + /* ********************************************************************** */ + else if (property == ctx->s_S6) + { + index = 6; + goto dollar_index; + } + /* ********************************************************************** */ + else if (property == ctx->s_S7) + { + index = 7; + goto dollar_index; + } + /* ********************************************************************** */ + else if (property == ctx->s_S8) + { + index = 8; + goto dollar_index; + } + /* ********************************************************************** */ + else if (property == ctx->s_S9) + { + index = 9; + goto dollar_index; + } + /* ********************************************************************** */ + else if (property == ctx->s_S_ || property == ctx->s_input) + { + if (set) + { + if (node->type != JS_STRING) + goto argument_type_error; + + JS_COPY (&ctx->input, node); + } + else + JS_COPY (node, &ctx->input); + } + /* ********************************************************************** */ + else if (property == ctx->s_lastMatch) + { + if (set) + goto immutable; + + if (ctx->input.type != JS_STRING + || ctx->regs.end[0] > ctx->input.u.vstring->len) + node->type = JS_UNDEFINED; + else + js_vm_make_string (vm, node, + ctx->input.u.vstring->data + ctx->regs.start[0], + ctx->regs.end[0] - ctx->regs.start[0]); + } + /* ********************************************************************** */ + else if (property == ctx->s_lastParen) + { + if (set) + goto immutable; + + if (ctx->input.type != JS_STRING + || ctx->regs.end[0] > ctx->input.u.vstring->len) + node->type = JS_UNDEFINED; + else + { + int i; + + for (i = 1; i < ctx->regs.num_regs && ctx->regs.start[i] >= 0; i++) + ; + i--; + if (i == 0) + node->type = JS_UNDEFINED; + else + js_vm_make_string (vm, node, + ctx->input.u.vstring->data + + ctx->regs.start[i], + ctx->regs.end[i] - ctx->regs.start[i]); + } + } + /* ********************************************************************** */ + else if (property == ctx->s_leftContext) + { + if (set) + goto immutable; + + if (ctx->input.type != JS_STRING + || ctx->regs.end[0] > ctx->input.u.vstring->len) + node->type = JS_UNDEFINED; + else + js_vm_make_string (vm, node, ctx->input.u.vstring->data, + ctx->regs.start[0]); + } + /* ********************************************************************** */ + else if (property == ctx->s_multiline) + { + goto not_implemented_yet; + } + /* ********************************************************************** */ + else if (property == ctx->s_rightContext) + { + if (set) + goto immutable; + if (ctx->input.type != JS_STRING + || ctx->regs.end[0] > ctx->input.u.vstring->len) + node->type = JS_UNDEFINED; + else + js_vm_make_string (vm, node, + ctx->input.u.vstring->data + ctx->regs.end[0], + ctx->input.u.vstring->len - ctx->regs.end[0]); + } + /* ********************************************************************** */ + else if (ictx) + { + /* Properties. */ + if (property == ctx->s_global) + { + if (set) + goto immutable; + + node->type = JS_BOOLEAN; + node->u.vboolean = ictx->global; + } + /* ***************************************************************** */ + else if (property == ctx->s_ignoreCase) + { + if (set) + goto immutable; + + node->type = JS_BOOLEAN; + node->u.vboolean = ictx->ignore_case; + } + /* ***************************************************************** */ + else if (property == ctx->s_lastIndex) + { + if (set) + { + if (ictx->immutable) + goto immutable_object; + + if (node->type != JS_INTEGER) + goto argument_type_error; + + ictx->last_index = node->u.vinteger; + } + else + { + node->type = JS_INTEGER; + node->u.vinteger = ictx->last_index; + } + } + /* ***************************************************************** */ + else if (property == ctx->s_source) + { + if (set) + goto immutable; + + js_vm_make_string (vm, node, ictx->source, ictx->source_len); + } + /* ***************************************************************** */ + else + { + if (!set) + node->type = JS_UNDEFINED; + + return JS_PROPERTY_UNKNOWN; + } + } + /* ********************************************************************** */ + else + { + if (!set) + node->type = JS_UNDEFINED; + + return JS_PROPERTY_UNKNOWN; + } + + return JS_PROPERTY_FOUND; + + + /* Error handling. */ + + argument_type_error: + sprintf (vm->error, "RegExp.%s: illegal value", + js_vm_symname (vm, property)); + js_vm_error (vm); + + not_implemented_yet: + sprintf (vm->error, "RegExp.%s: not implemented yet", + js_vm_symname (vm, property)); + js_vm_error (vm); + + immutable: + sprintf (vm->error, "RegExp.%s: immutable property", + js_vm_symname (vm, property)); + js_vm_error (vm); + + immutable_object: + sprintf (vm->error, "RegExp.%s: immutable object", + 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) +{ + unsigned int flags = 0; + char *source; + unsigned int source_len; + int i; + + if (args->u.vinteger > 2) + { + sprintf (vm->error, "new RegExp(): illegal amount of arguments"); + js_vm_error (vm); + } + + if (args->u.vinteger == 0) + { + source = ""; + source_len = 0; + } + else + { + if (args[1].type != JS_STRING) + { + argument_type_error: + sprintf (vm->error, "new RegExp(): illegal argument"); + js_vm_error (vm); + } + + source = args[1].u.vstring->data; + source_len = args[1].u.vstring->len; + } + + if (args->u.vinteger == 2) + { + if (args[2].type != JS_STRING) + goto argument_type_error; + + for (i = 0; i < args[2].u.vstring->len; i++) + switch (args[2].u.vstring->data[i]) + { + case 'g': + flags |= JS_REGEXP_FLAG_G; + break; + + case 'i': + flags |= JS_REGEXP_FLAG_I; + break; + + default: + sprintf (vm->error, "new RegExp(): illegal flag `%c'", + args[2].u.vstring->data[i]); + js_vm_error (vm); + break; + } + } + + js_builtin_RegExp_new (vm, source, source_len, flags, 0, builtin_info, + result_return); +} + +/* Delete proc. */ +static void +delete_proc (JSBuiltinInfo *builtin_info, void *instance_context) +{ + RegexpInstanceCtx *ictx = instance_context; + + if (ictx) + { + js_free (ictx->source); + + if (ictx->compiled.buffer) + js_free (ictx->compiled.buffer); + if (ictx->compiled.fastmap) + js_free (ictx->compiled.fastmap); + + js_free (ictx); + } +} + +/* Mark proc. */ +static void +mark (JSBuiltinInfo *builtin_info, void *instance_context) +{ + RegexpCtx *ctx = builtin_info->obj_context; + + js_vm_mark (&ctx->input); +} + +/* + * Global functions. + */ + +void +js_builtin_RegExp (JSVirtualMachine *vm) +{ + JSBuiltinInfo *info; + RegexpCtx *ctx; + JSNode *n; + + ctx = js_calloc (vm, 1, sizeof (*ctx)); + + ctx->s_S1 = js_vm_intern (vm, "$1"); + ctx->s_S2 = js_vm_intern (vm, "$2"); + ctx->s_S3 = js_vm_intern (vm, "$3"); + ctx->s_S4 = js_vm_intern (vm, "$4"); + ctx->s_S5 = js_vm_intern (vm, "$5"); + ctx->s_S6 = js_vm_intern (vm, "$6"); + ctx->s_S7 = js_vm_intern (vm, "$7"); + ctx->s_S8 = js_vm_intern (vm, "$8"); + ctx->s_S9 = js_vm_intern (vm, "$9"); + ctx->s_S_ = js_vm_intern (vm, "$_"); + ctx->s_input = js_vm_intern (vm, "input"); + ctx->s_lastMatch = js_vm_intern (vm, "lastMatch"); + ctx->s_lastParen = js_vm_intern (vm, "lastParen"); + ctx->s_leftContext = js_vm_intern (vm, "leftContext"); + ctx->s_multiline = js_vm_intern (vm, "multiline"); + ctx->s_rightContext = js_vm_intern (vm, "rightContext"); + + ctx->s_global = js_vm_intern (vm, "global"); + ctx->s_ignoreCase = js_vm_intern (vm, "ignoreCase"); + ctx->s_lastIndex = js_vm_intern (vm, "lastIndex"); + ctx->s_source = js_vm_intern (vm, "source"); + + ctx->s_compile = js_vm_intern (vm, "compile"); + ctx->s_exec = js_vm_intern (vm, "exec"); + ctx->s_test = js_vm_intern (vm, "test"); + + /* Object information. */ + + info = js_vm_builtin_info_create (vm); + + info->global_method_proc = global_method; + info->method_proc = method; + info->property_proc = property; + info->new_proc = new_proc; + info->delete_proc = delete_proc; + info->mark_proc = mark; + info->obj_context = ctx; + info->obj_context_delete = js_free; + + /* Define it. */ + n = &vm->globals[js_vm_intern (vm, "RegExp")]; + js_vm_builtin_create (vm, n, info, NULL); +} + + +void +js_builtin_RegExp_new (JSVirtualMachine *vm, char *source, + unsigned int source_len, unsigned int flags, + int immutable, JSBuiltinInfo *info, + JSNode *result_return) +{ + RegexpInstanceCtx *instance; + const char *error; + + instance = js_calloc (vm, 1, sizeof (*instance)); + + instance->source_len = source_len; + + /* +1 to avoid zero allocation. */ + instance->source = js_malloc (vm, instance->source_len + 1); + memcpy (instance->source, source, instance->source_len); + + instance->global = (flags & JS_REGEXP_FLAG_G) != 0; + instance->ignore_case = (flags & JS_REGEXP_FLAG_I) != 0; + instance->immutable = immutable; + + if (instance->ignore_case) + instance->compiled.translate = js_latin1_tolower; + + error = re_compile_pattern (instance->source, instance->source_len, + &instance->compiled); + if (error) + { + js_free (instance->source); + js_free (instance); + sprintf (vm->error, + "new RegExp(): compilation of the expression failed: %s", + error); + js_vm_error (vm); + } + instance->compiled.fastmap = js_malloc (vm, 256); + re_compile_fastmap (&instance->compiled); + + if (info == NULL) + { + JSNode *n; + + n = &vm->globals[js_vm_intern (vm, "RegExp")]; + info = n->u.vbuiltin->info; + } + + /* Create a new object. */ + js_vm_builtin_create (vm, result_return, info, instance); +} + + +#define EMIT_TO_RESULT(md, mdl) \ + do { \ + result_return->u.vstring->data \ + = js_vm_realloc (vm, result_return->u.vstring->data, \ + result_return->u.vstring->len + (mdl)); \ + memcpy (result_return->u.vstring->data \ + + result_return->u.vstring->len, \ + (md), (mdl)); \ + result_return->u.vstring->len += (mdl); \ + } while (0) + +void +js_builtin_RegExp_replace (JSVirtualMachine *vm, char *data, + unsigned int datalen, JSNode *regexp, + char *repl, unsigned int repllen, + JSNode *result_return) +{ + int i, j; + RegexpInstanceCtx *ictx = regexp->u.vbuiltin->instance_context; + struct re_registers regs = {0}; + unsigned int substs = 0; + unsigned int pos = 0; + + /* + * Allocate the result string, Let's guess that we need at least + * bytes of data. + */ + js_vm_make_string (vm, result_return, NULL, datalen); + result_return->u.vstring->len = 0; + + /* Do searches. */ + while (pos < datalen) + { + i = re_search (&ictx->compiled, data, datalen, pos, datalen - pos, + ®s); + + /* Check what we got. */ + if (i >= 0) + { + /* Emit all up to the first matched character. */ + EMIT_TO_RESULT (data + pos, regs.start[0] - pos); + + /* Check for empty matches. */ + if (regs.end[0] == regs.start[0]) + { + pos = regs.end[0]; + + /* Still something left to search? */ + if (pos < datalen) + { + /* Go one character forward. */ + EMIT_TO_RESULT (data + pos, 1); + pos++; + } + } + else + { + int start; + + /* Not an empty match. */ + substs++; + + /* Interpret replace string. */ + start = 0; + for (i = 0; i < repllen; i++) + { + if (repl[i] == '$') + { + if (i + 1 >= repllen) + /* The last character is '$'. Just emit it. */ + continue; + + /* First, emit all we have collected so far. */ + EMIT_TO_RESULT (repl + start, i - start); + start = i++; + + /* Check tag. */ + switch (repl[i]) + { + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + /* n:th subexpression. */ + j = repl[i] - '0'; + + if (regs.start[j] >= 0) + EMIT_TO_RESULT (data + regs.start[j], + regs.end[j] - regs.start[j]); + + start = i + 1; + break; + + case '`': + /* Left context. */ + EMIT_TO_RESULT (data, regs.start[0]); + start = i + 1; + break; + + case '\'': + /* Right context. */ + EMIT_TO_RESULT (data + regs.end[0], + datalen - regs.end[0]); + start = i + 1; + break; + + case '&': + /* Last match. */ + EMIT_TO_RESULT (data + regs.start[0], + regs.end[0] - regs.start[0]); + start = i + 1; + break; + + case '$': + /* The dollar sign. */ + EMIT_TO_RESULT ("$", 1); + start = i + 1; + break; + + case '+': + default: + /* Ignore. */ + start = i - 1; + break; + } + } + } + + /* Emit all leftovers. */ + EMIT_TO_RESULT (repl + start, i - start); + + /* Update search position. */ + pos = regs.end[0]; + } + } + else + break; + + if (!ictx->global && substs > 0) + /* Substitute only the first match. */ + break; + } + + /* No more matches. Emit the rest of the string to the result. */ + EMIT_TO_RESULT (data + pos, datalen - pos); + + if (regs.start) + js_free (regs.start); + if (regs.end) + js_free (regs.end); +} + + +void +js_builtin_RegExp_match (JSVirtualMachine *vm, char *data, + unsigned int datalen, JSNode *regexp, + JSNode *result_return) +{ + do_exec (vm, regexp->u.vbuiltin->info->obj_context, + regexp->u.vbuiltin->instance_context, data, datalen, + result_return); +} + + +void +js_builtin_RegExp_search (JSVirtualMachine *vm, char *data, + unsigned int datalen, JSNode *regexp, + JSNode *result_return) +{ + RegexpCtx *ctx = regexp->u.vbuiltin->info->obj_context; + RegexpInstanceCtx *ictx = regexp->u.vbuiltin->instance_context; + + result_return->type = JS_INTEGER; + result_return->u.vinteger = re_search (&ictx->compiled, data, datalen, + ictx->global ? ictx->last_index : 0, + datalen, &ctx->regs); + + if (result_return->u.vinteger >= 0) + ictx->last_index = ctx->regs.end[0]; +} + + +void +js_builtin_RegExp_split (JSVirtualMachine *vm, char *data, + unsigned int datalen, JSNode *regexp, + unsigned int limit, JSNode *result_return) +{ + unsigned int start = 0, pos; + unsigned int alen = 0; + RegexpInstanceCtx *ictx = regexp->u.vbuiltin->instance_context; + struct re_registers regs = {0}; + int i; + + js_vm_make_array (vm, result_return, alen); + + for (pos = 0; alen < limit && pos <= datalen; ) + { + i = re_search (&ictx->compiled, data, datalen, pos, datalen - pos, + ®s); + if (i < 0) + { + pos = datalen; + break; + } + + /* Found the separator. */ + js_vm_expand_array (vm, result_return, alen + 1); + js_vm_make_string (vm, &result_return->u.varray->data[alen], + data + start, regs.start[0] - start); + alen++; + + if (regs.end[0] == pos) + { + /* We didn't advance in the string. */ + start = regs.end[0]; + pos++; + } + else + pos = start = regs.end[0]; + } + + if (alen < limit) + { + /* Insert all leftovers. */ + js_vm_expand_array (vm, result_return, alen + 1); + js_vm_make_string (vm, &result_return->u.varray->data[alen], + data + start, datalen - start); + } + + if (regs.start) + js_free (regs.start); + if (regs.end) + js_free (regs.end); +} diff --git a/reactos/lib/kjs/ksrc/b_system.c b/reactos/lib/kjs/ksrc/b_system.c new file mode 100644 index 00000000000..6d7045855b5 --- /dev/null +++ b/reactos/lib/kjs/ksrc/b_system.c @@ -0,0 +1,394 @@ +/* + * The builtin System object. + * Copyright (c) 1998-1999 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/ksrc/b_system.c,v $ + * $Id: b_system.c,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +/* + * Static methods: + * + * print ([ANY...]) => undefined + * + * Properties: type mutable + * + * bits integer + * canonicalHost string + * canonicalHostCPU string + * canonicalHostVendor string + * canonicalHostOS string + * errno integer + * lineBreakSequence string + * stderr file + * stdin file + * stdout file + */ + +#include "ddk/ntddk.h" +#include "jsint.h" +#include "kjs.h" +#include + +/* + * Types and definitions. + */ + +#define INSECURE() \ + do { \ + if (secure_mode) \ + goto insecure_feature; \ + } while (0) + +/* + * Static functions. + */ + +/* Method proc */ +static int +method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol method, JSNode *result_return, + JSNode *args) +{ + SystemCtx *ctx = builtin_info->obj_context; + int i; + char *cp; + /* int secure_mode = vm->security & JS_VM_SECURE_SYSTEM; */ + + /* The default result. */ + result_return->type = JS_UNDEFINED; + + if (method == ctx->s_mread) + { + if (args->u.vinteger != 2) + goto argument_error; + if (args[1].type != JS_INTEGER) + goto argument_type_error; + if (args[2].type != JS_INTEGER) + goto argument_type_error; + + if (args[1].u.vinteger == 0) /* String type */ + { + result_return->type = JS_STRING; + js_vm_make_string (vm, result_return, (char *)args[2].u.vinteger, + strlen ((char *)args[2].u.vinteger)); + } + else if( args[1].u.vinteger == 1) /* Byte */ + { + result_return->type = JS_INTEGER; + result_return->u.vinteger = *((BYTE *)args[2].u.vinteger); + } + else if( args[1].u.vinteger == 2) /* Word */ + { + result_return->type = JS_INTEGER; + result_return->u.vinteger = *((WORD *)args[2].u.vinteger); + } + else if( args[1].u.vinteger == 4) /* Dword */ + { + result_return->type = JS_INTEGER; + result_return->u.vinteger = *((DWORD *)args[2].u.vinteger); + } + } + else if (method == ctx->s_mwrite) + { + if (args->u.vinteger != 3) + goto argument_error; + if (args[1].type != JS_INTEGER) + goto argument_type_error; + if (args[2].type != JS_INTEGER) + goto argument_type_error; + + if (args[1].u.vinteger == 0) /* String type */ + { + if (args[3].type != JS_STRING) + goto argument_type_error; + + result_return->type = JS_BOOLEAN; + result_return->u.vinteger = 1; + cp = js_string_to_c_string (vm, &args[3]); + strcpy((char *)args[2].u.vinteger, cp); + js_free(cp); + } + else if( args[1].u.vinteger == 1) /* Byte */ + { + result_return->type = JS_INTEGER; + *((BYTE *)args[2].u.vinteger) = args[3].u.vinteger; + } + else if( args[1].u.vinteger == 2) /* Word */ + { + result_return->type = JS_INTEGER; + *((WORD *)args[2].u.vinteger) = args[3].u.vinteger; + } + else if( args[1].u.vinteger == 4) /* Dword */ + { + result_return->type = JS_INTEGER; + *((DWORD *)args[2].u.vinteger) = args[3].u.vinteger; + } + } + /* ********************************************************************** */ + else if (method == ctx->s_print) + { + JSIOStream *stream; + + if (method == ctx->s_print) + stream = vm->s_stdout; + else + stream = vm->s_stderr; + + for (i = 1; i <= args->u.vinteger; i++) + { + JSNode result; + + js_vm_to_string (vm, &args[i], &result); + js_iostream_write (stream, result.u.vstring->data, + result.u.vstring->len); + } + } + /* ********************************************************************** */ + else if (method == vm->syms.s_toString) + { + if (args->u.vinteger != 0) + goto argument_error; + + js_vm_make_static_string (vm, result_return, "System", 6); + } + /* ********************************************************************** */ + else { + JSSymbolList *cur = ctx->registered_symbols; + while( cur ) { + if( cur->symbol == method && cur->registered_function ) { + return cur->registered_function + (cur->context, result_return, args); + } + cur = cur->next; + } + return JS_PROPERTY_UNKNOWN; + } + + return JS_PROPERTY_FOUND; + + + /* + * Error handling. + */ + + argument_error: + sprintf (vm->error, "System.%s(): illegal amout of arguments", + js_vm_symname (vm, method)); + js_vm_error (vm); + + argument_type_error: + sprintf (vm->error, "System.%s(): illegal argument", + js_vm_symname (vm, method)); + js_vm_error (vm); + + /* insecure_feature: */ + sprintf (vm->error, "System.%s(): not allowed in secure mode", + 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) +{ + SystemCtx *ctx = builtin_info->obj_context; + + if (property == ctx->s_bits) + { + if (set) + goto immutable; + + node->type = JS_INTEGER; +#if SIZEOF_INT == 2 + node->u.vinteger = 16; +#else /* not SIZEOF_INT == 2 */ + +#if SIZEOF_LONG == 4 + node->u.vinteger = 32; +#else /* not SIZEOF_LONG == 4 */ + +#if SIZEOF_LONG == 8 + node->u.vinteger = 64; +#else /* not SIZEOF_LONG == 8 */ + + /* Do not know. */ + node->u.vinteger = 0; + +#endif /* not SIZEOF_LONG == 8 */ +#endif /* not SIZEOF_LONG == 4 */ +#endif /* not SIZEOF_INT == 2 */ + } + else if (property == ctx->s_canonicalHost) + { + if (set) + goto immutable; + + js_vm_make_static_string (vm, node, CANONICAL_HOST, + strlen (CANONICAL_HOST)); + } + else if (property == ctx->s_canonicalHostCPU) + { + if (set) + goto immutable; + + js_vm_make_static_string (vm, node, CANONICAL_HOST_CPU, + strlen (CANONICAL_HOST_CPU)); + } + else if (property == ctx->s_canonicalHostVendor) + { + if (set) + goto immutable; + + js_vm_make_static_string (vm, node, CANONICAL_HOST_VENDOR, + strlen (CANONICAL_HOST_VENDOR)); + } + else if (property == ctx->s_canonicalHostOS) + { + if (set) + goto immutable; + + js_vm_make_static_string (vm, node, CANONICAL_HOST_OS, + strlen (CANONICAL_HOST_OS)); + } + else if (property == ctx->s_lineBreakSequence) + { + if (set) + goto immutable; + + js_vm_make_static_string (vm, node, JS_HOST_LINE_BREAK, + JS_HOST_LINE_BREAK_LEN); + } + else if (property == ctx->s_stderr) + { + if (set) + goto immutable; + + JS_COPY (node, &ctx->pstderr); + } + else if (property == ctx->s_stdin) + { + if (set) + goto immutable; + + JS_COPY (node, &ctx->pstdin); + } + else if (property == ctx->s_stdout) + { + if (set) + goto immutable; + + JS_COPY (node, &ctx->pstdout); + } + + else + { + if (!set) + node->type = JS_UNDEFINED; + + return JS_PROPERTY_UNKNOWN; + } + + return JS_PROPERTY_FOUND; + + + /* + * Error handling. + */ + + immutable: + sprintf (vm->error, "System.%s: immutable property", + js_vm_symname (vm, property)); + js_vm_error (vm); + + /* NOTREACHED. */ + return 0; +} + +/* Mark proc. */ +static void +mark (JSBuiltinInfo *builtin_info, void *instance_context) +{ + SystemCtx *ctx = builtin_info->obj_context; + + js_vm_mark (&ctx->pstderr); + js_vm_mark (&ctx->pstdin); + js_vm_mark (&ctx->pstdout); +} + + +/* + * Global functions. + */ + +void +js_builtin_System (PKJS kjs) { + JSNode *n; + JSBuiltinInfo *info; + SystemCtx *ctx; + JSVirtualMachine *vm = kjs->vm; + + kjs->ctx = (SystemCtx *)js_calloc (vm, 1, sizeof (*ctx)); + ctx = kjs->ctx; + + ctx->s_print = js_vm_intern (vm, "print"); + ctx->s_mread = js_vm_intern (vm, "mread"); + ctx->s_mwrite = js_vm_intern (vm, "mwrite"); + ctx->s_reg = js_vm_intern (vm, "reg"); + ctx->s_regdir = js_vm_intern (vm, "regdir"); + + ctx->s_bits = js_vm_intern (vm, "bits"); + ctx->s_canonicalHost = js_vm_intern (vm, "canonicalHost"); + ctx->s_canonicalHostCPU = js_vm_intern (vm, "canonicalHostCPU"); + ctx->s_canonicalHostVendor = js_vm_intern (vm, "canonicalHostVendor"); + ctx->s_canonicalHostOS = js_vm_intern (vm, "canonicalHostOS"); + ctx->s_errno = js_vm_intern (vm, "errno"); + ctx->s_lineBreakSequence = js_vm_intern (vm, "lineBreakSequence"); + ctx->s_stderr = js_vm_intern (vm, "stderr"); + ctx->s_stdin = js_vm_intern (vm, "stdin"); + ctx->s_stdout = js_vm_intern (vm, "stdout"); + + /* Object information. */ + + info = js_vm_builtin_info_create (vm); + + info->method_proc = method; + info->property_proc = property; + info->mark_proc = mark; + info->obj_context = ctx; + info->obj_context_delete = js_free; + + /* Define it. */ + n = &vm->globals[js_vm_intern (vm, "System")]; + js_vm_builtin_create (vm, n, info, NULL); + + /* Enter system properties. */ + js_builtin_File_new (vm, &ctx->pstderr, "stdout", vm->s_stderr, 1); + js_builtin_File_new (vm, &ctx->pstdin, "stdin", vm->s_stdin, 1); + js_builtin_File_new (vm, &ctx->pstdout, "stdout", vm->s_stdout, 1); +} diff --git a/reactos/lib/kjs/ksrc/bc.c b/reactos/lib/kjs/ksrc/bc.c new file mode 100644 index 00000000000..226fad0d6f9 --- /dev/null +++ b/reactos/lib/kjs/ksrc/bc.c @@ -0,0 +1,137 @@ +/* + * Byte code handling routines. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/ksrc/bc.c,v $ + * $Id: bc.c,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +#include "jsint.h" + +/* + * Global functions. + */ + +JSByteCode * +js_bc_read_file (FILE *fp) +{ + return NULL; +} + + +JSByteCode * +js_bc_read_data (unsigned char *data, unsigned int datalen) +{ + JSUInt32 ui; + unsigned int pos = 0; + int i; + JSByteCode *bc = NULL; + + if (data[pos] == '#') + { + /* Skip the first line. */ + for (; pos < datalen && data[pos] != '\n'; pos++) + ; + if (pos >= datalen) + goto format_error; + } + + if (datalen - pos < 8) + goto format_error; + + JS_BC_READ_INT32 (data + pos, ui); + if (ui != JS_BC_FILE_MAGIC) + goto format_error; + pos += 4; + + bc = js_calloc (NULL, 1, sizeof (*bc)); + if (bc == NULL) + return NULL; + + JS_BC_READ_INT32 (data + pos, ui); + bc->num_sects = (unsigned int) ui; + pos += 4; + + bc->sects = js_calloc (NULL, bc->num_sects, sizeof (JSBCSect)); + if (bc->sects == NULL) + { + js_free (bc); + return NULL; + } + + /* Read sections. */ + for (i = 0; i < bc->num_sects; i++) + { + if (datalen - pos < 8) + goto format_error; + + /* Get type. */ + JS_BC_READ_INT32 (data + pos, ui); + bc->sects[i].type = (int) ui; + pos += 4; + + /* Get section length. */ + JS_BC_READ_INT32 (data + pos, ui); + bc->sects[i].length = (unsigned int) ui; + pos += 4; + + bc->sects[i].data = js_malloc (NULL, bc->sects[i].length + 1 + /* +1 to avoid zero allocations */); + if (bc->sects[i].data == NULL) + { + for (i--; i >= 0; i--) + js_free (bc->sects[i].data); + + js_free (bc->sects); + js_free (bc); + return NULL; + } + + /* Read section's data. */ + if (datalen - pos < bc->sects[i].length) + goto format_error; + + memcpy (bc->sects[i].data, data + pos, bc->sects[i].length); + pos += bc->sects[i].length; + } + + if (pos != datalen) + goto format_error; + + return bc; + + + format_error: + + if (bc) + js_bc_free (bc); + + return NULL; +} + + +void +js_bc_free (JSByteCode *bc) +{ +} diff --git a/reactos/lib/kjs/ksrc/compat.c b/reactos/lib/kjs/ksrc/compat.c new file mode 100644 index 00000000000..5245fbd80d9 --- /dev/null +++ b/reactos/lib/kjs/ksrc/compat.c @@ -0,0 +1,67 @@ +#include "ddk/ntddk.h" +#include "ddk/kefuncs.h" +#include "ctype.h" +#include "jsconfig.h" + +void __kernel_abort() { + KeBugCheck(0); +} + +void _assert( const char *expr, const char *file, int line ) { + DbgPrint("%s -- %s:%d\n", expr,file,line ); + __kernel_abort(); +} + +int isalnum( int x ) { return isalpha(x) || isdigit(x); } +int iscntrl( int x ) { return 32 > x; } +int ispunct( int x ) { return !isspace(x) && !isalnum(x) && !iscntrl(x) && !isspace(x); } + +static int belongs_to_base( int x, int base ) { + if( x >= '0' && '9' >= x ) { + if( base > x - '0' ) return x - '0'; + } + if( x >= 'a' && 'z' >= x ) { + if( base > x - 'a' + 10 ) return x - 'a' + 10; + } + if( x >= 'A' && 'A' >= x ) { + if( base > x - 'A' + 10 ) return x - 'A' + 10; + } + return -1; +} + +long strtol( const char *data, char **endptr, int base ) { + long out_number = 0; + + if( base == 0 ) { + if( data[0] == '0' && (data[1] == 'x' || data[1] == 'X') ) { + base = 16; + data += 2; + } else if( data[0] == '0' ) { + base = 8; + data++; + } else { + base = 10; + } + } + + while( data && *data && belongs_to_base( *data, base ) != -1 ) { + out_number *= base; + out_number += belongs_to_base( *data, base ); + data++; + } + if( endptr ) *endptr = (char *)data; + return out_number; +} + +double strtod( const char *data, char **endptr ) { + *endptr = (char *)data; + return 0.0; +} + +int memcmp( const void *a, const void *b, size_t s ) { + char *aa = (char *)a, *bb = (char *)b; + while(s && *aa == *bb) { + aa++; bb++; s--; + } + return s ? *bb - *aa : 0; +} diff --git a/reactos/lib/kjs/ksrc/debug.c b/reactos/lib/kjs/ksrc/debug.c new file mode 100644 index 00000000000..197262ac44d --- /dev/null +++ b/reactos/lib/kjs/ksrc/debug.c @@ -0,0 +1,171 @@ +/* + * Debugging utilities. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/ksrc/debug.c,v $ + * $Id: debug.c,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +#include "jsint.h" + +/* + * Global functions. + */ + +#define STRING_MAX_PRINT_LEN 10 + +void +js_vm_stacktrace (JSVirtualMachine *vm, unsigned int num_frames) +{ + unsigned int frame = 0; + JSNode *sp = vm->sp; + void *pc = vm->pc; + JSNode *fp; + char buf[512]; + /* int i; */ + + sprintf (buf, "VM: stacktrace: stacksize=%d, used=%d%s", + vm->stack_size, + (vm->stack + vm->stack_size - sp), + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + + /* STACKFRAME */ + + /* Find frame pointer. */ + for (fp = sp + 1; fp->type != JS_IPTR; fp++) + ; + + /* The first iptr is the return address. */ + fp++; + + /* The second iptr is the with pointer. */ + fp++; + + /* The third item is a JS_ARGS_FIX node. */ + assert (fp->type == JS_ARGS_FIX); + fp++; + + while (fp && frame < num_frames) + { + JSNode *n; + const char *func_name = js_vm_func_name (vm, pc); + + sprintf (buf, "#%-3u %s%s:", frame++, func_name, + func_name[0] == '.' ? "" : "()"); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + + if (vm->verbose_stacktrace) + { + sprintf (buf, + " ra=0x%lx, wp=0x%lx, af=%d:%d, ofp=0x%lx", + (unsigned long) (fp - 3)->u.iptr, + (unsigned long) JS_WITHPTR->u.iptr, + JS_ARGS_FIXP->u.args_fix.argc, + JS_ARGS_FIXP->u.args_fix.delta, + (unsigned long) fp->u.iptr); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + + for (n = sp + 1; n != fp - 3; n++) + { + switch (n->type) + { + case JS_UNDEFINED: + sprintf (buf, " undefined"); + break; + + case JS_NULL: + sprintf (buf, " null"); + break; + + case JS_BOOLEAN: + sprintf (buf, " %s", n->u.vboolean ? "true" : "false"); + break; + + case JS_INTEGER: + sprintf (buf, " %ld", n->u.vinteger); + break; + + case JS_STRING: + if (n->u.vstring->len > STRING_MAX_PRINT_LEN) + sprintf (buf, " \"%.*s...\"", + STRING_MAX_PRINT_LEN, + n->u.vstring->data); + else + sprintf (buf, " \"%.*s\"", + (int) n->u.vstring->len, + n->u.vstring->data); + break; + + case JS_FLOAT: + sprintf (buf, " %g", n->u.vfloat); + break; + + case JS_ARRAY: + sprintf (buf, " array"); + break; + + case JS_OBJECT: + sprintf (buf, " object"); + break; + + case JS_SYMBOL: + sprintf (buf, " %s", js_vm_symname (vm, n->u.vsymbol)); + break; + + case JS_BUILTIN: + sprintf (buf, " builtin"); + break; + + case JS_FUNC: + sprintf (buf, " function"); + break; + + case JS_IPTR: + sprintf (buf, " 0x%lx", (unsigned long) n->u.iptr); + break; + + case JS_ARGS_FIX: + sprintf (buf, " ", n->u.args_fix.argc, + n->u.args_fix.delta); + break; + + default: + sprintf (buf, " type=%d???", n->type); + break; + } + + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + + js_iostream_write (vm->s_stderr, JS_HOST_LINE_BREAK, + JS_HOST_LINE_BREAK_LEN); + + /* Move to the caller. */ + sp = fp; + pc = fp[-3].u.iptr; + fp = fp->u.iptr; + } +} diff --git a/reactos/lib/kjs/ksrc/ejumps.h b/reactos/lib/kjs/ksrc/ejumps.h new file mode 100644 index 00000000000..b4d6a63e566 --- /dev/null +++ b/reactos/lib/kjs/ksrc/ejumps.h @@ -0,0 +1,2244 @@ +/* operand halt (0) */ +op_halt: + OPERAND (0); + sprintf (buf, "VM: halt%s", JS_HOST_LINE_BREAK); + DbgPrint("%s\n", buf); +#if 0 + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); + + while (1) + sleep (5); +#endif + NEXT (); + +/* operand done (1) */ +op_done: + OPERAND (1); + DONE (); + NEXT (); + +/* operand nop (2) */ +op_nop: + OPERAND (2); + /* Nothing here! */ + NEXT (); + +/* operand dup (3) */ +op_dup: + OPERAND (3); + JS_COPY (JS_SP0, JS_SP1); + JS_PUSH (); + NEXT (); + +/* operand pop (4) */ +op_pop: + OPERAND (4); + JS_POP (); + NEXT (); + +/* operand pop_n (5) */ +op_pop_n: + OPERAND (5); + READ_INT8 (i); + JS_POP_N (i); + NEXT (); + +/* operand apop (6) */ +op_apop: + OPERAND (6); + READ_INT8 (i); + JS_COPY (JS_SP (i + 1), JS_SP1); + JS_POP_N (i); + NEXT (); + +/* operand swap (7) */ +op_swap: + OPERAND (7); + JS_COPY (JS_SP0, JS_SP2); + JS_COPY (JS_SP2, JS_SP1); + JS_COPY (JS_SP1, JS_SP0); + NEXT (); + +/* operand roll (8) */ +op_roll: + OPERAND (8); + READ_INT8 (i8); + + if (i8 > 1) + { + int j; + + for (j = 0; j < i8; j++) + JS_COPY (JS_SP (j), JS_SP (j + 1)); + + JS_COPY (JS_SP (i8), JS_SP0); + } + else if (i8 < -1) + { + i8 = -i8; + + JS_COPY (JS_SP0, JS_SP (i8)); + for (; i8 > 0; i8--) + JS_COPY (JS_SP (i8), JS_SP (i8 - 1)); + } + NEXT (); + +/* operand const (9) */ +op_const: + OPERAND (9); + READ_INT32 (i); + JS_COPY (JS_SP0, JS_CONST (i)); + JS_PUSH (); + NEXT (); + +/* operand const_null (10) */ +op_const_null: + OPERAND (10); + JS_SP0->type = JS_NULL; + JS_PUSH (); + NEXT (); + +/* operand const_true (11) */ +op_const_true: + OPERAND (11); + JS_SP0->type = JS_BOOLEAN; + JS_SP0->u.vboolean = 1; + JS_PUSH (); + NEXT (); + +/* operand const_false (12) */ +op_const_false: + OPERAND (12); + JS_SP0->type = JS_BOOLEAN; + JS_SP0->u.vboolean = 0; + JS_PUSH (); + NEXT (); + +/* operand const_undefined (13) */ +op_const_undefined: + OPERAND (13); + JS_SP0->type = JS_UNDEFINED; + JS_PUSH (); + NEXT (); + +/* operand const_i0 (14) */ +op_const_i0: + OPERAND (14); + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 0; + JS_PUSH (); + NEXT (); + +/* operand const_i1 (15) */ +op_const_i1: + OPERAND (15); + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 1; + JS_PUSH (); + NEXT (); + +/* operand const_i2 (16) */ +op_const_i2: + OPERAND (16); + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 2; + JS_PUSH (); + NEXT (); + +/* operand const_i3 (17) */ +op_const_i3: + OPERAND (17); + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 3; + JS_PUSH (); + NEXT (); + +/* operand const_i (18) */ +op_const_i: + OPERAND (18); + READ_INT32 (i); + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = i; + JS_PUSH (); + NEXT (); + +/* operand load_global (19) */ +op_load_global: + OPERAND (19); + READ_INT32 (j); + + /* Use the global value only. */ + JS_COPY (JS_SP0, JS_GLOBAL (j)); + JS_PUSH (); + + if (vm->warn_undef && JS_SP1->type == JS_UNDEFINED) + { + sprintf (buf, "VM: warning: using undefined global `%s'%s", + js_vm_symname (vm, j), JS_HOST_LINE_BREAK); + DbgPrint( "%s\n", buf); + } + NEXT (); + +/* operand store_global (20) */ +op_store_global: + OPERAND (20); + READ_INT32 (i); + + /* Operand store_global do not check the with-chain. */ + /* WITHCHAIN */ + + /* Set the global value. */ + JS_COPY (JS_GLOBAL (i), JS_SP1); + JS_POP (); + NEXT (); + +/* operand load_arg (21) */ +op_load_arg: + OPERAND (21); + READ_INT8 (i); + JS_COPY (JS_SP0, JS_ARG (i)); + JS_PUSH (); + NEXT (); + +/* operand store_arg (22) */ +op_store_arg: + OPERAND (22); + READ_INT8 (i); + JS_COPY (JS_ARG (i), JS_SP1); + JS_POP (); + NEXT (); + +/* operand load_local (23) */ +op_load_local: + OPERAND (23); + READ_INT16 (i); + JS_COPY (JS_SP0, JS_LOCAL (i)); + JS_PUSH (); + NEXT (); + +/* operand store_local (24) */ +op_store_local: + OPERAND (24); + READ_INT16 (i); + JS_COPY (JS_LOCAL (i), JS_SP1); + JS_POP (); + NEXT (); + +/* operand load_property (25) */ +op_load_property: + OPERAND (25); + /* Fetch the property symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (JS_SP1->u.vbuiltin->info->property_proc) + { + if ((*JS_SP1->u.vbuiltin->info->property_proc) ( + vm, + JS_SP1->u.vbuiltin->info, + JS_SP1->u.vbuiltin->instance_context, + j, 0, &builtin_result) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Looking up the prototype. */ + + builtin_result.type = JS_OBJECT; + if (JS_SP1->u.vbuiltin->prototype) + /* This is an instance. */ + builtin_result.u.vobject = JS_SP1->u.vbuiltin->prototype; + else + /* This is a class. */ + builtin_result.u.vobject + = JS_SP1->u.vbuiltin->info->prototype; + } + else + { + /* Looking up stuffs from the prototype. */ + + if (JS_SP1->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_load_property (vm, + JS_SP1->u.vbuiltin->prototype, + j, &builtin_result); + else + /* A class. */ + js_vm_object_load_property ( + vm, + JS_SP1->u.vbuiltin->info->prototype, + j, &builtin_result); + } + } + JS_COPY (JS_SP1, &builtin_result); + } + else + ERROR ("illegal builtin object for load_property"); + } + else if (JS_SP1->type == JS_OBJECT) + { + js_vm_object_load_property (vm, JS_SP1->u.vobject, j, JS_SP1); + } + else if (vm->prim[JS_SP1->type]) + { + /* The primitive language types. */ + JS_SAVE_REGS (); + if ((*vm->prim[JS_SP1->type]->property_proc) (vm, vm->prim[JS_SP1->type], + JS_SP1, j, 0, + &builtin_result) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Looking up the prototype. */ + switch (JS_SP1->type) + { + case JS_STRING: + if (JS_SP1->u.vstring->prototype) + { + builtin_result.type = JS_OBJECT; + builtin_result.u.vobject = JS_SP1->u.vstring->prototype; + } + else + /* No prototype yet. */ + builtin_result.type = JS_NULL; + break; + + case JS_ARRAY: + if (JS_SP1->u.varray->prototype) + { + builtin_result.type = JS_OBJECT; + builtin_result.u.vobject = JS_SP1->u.varray->prototype; + } + else + /* No prototype yet. */ + builtin_result.type = JS_NULL; + break; + + case JS_FUNC: + if (JS_SP1->u.vfunction->prototype) + { + builtin_result.type = JS_OBJECT; + builtin_result.u.vobject + = JS_SP1->u.vfunction->prototype; + } + else + /* No prototype yet. */ + builtin_result.type = JS_NULL; + break; + + default: + /* The rest do not have prototype. */ + builtin_result.type = JS_NULL; + break; + } + } + else + { + /* Looking up stuffs from the prototype. */ + switch (JS_SP1->type) + { + case JS_STRING: + if (JS_SP1->u.vstring->prototype) + js_vm_object_load_property (vm, + JS_SP1->u.vstring->prototype, + j, &builtin_result); + else + /* Take it from the class' prototype */ + goto _op_load_property_try_proto; + break; + + case JS_ARRAY: + if (JS_SP1->u.varray->prototype) + js_vm_object_load_property (vm, + JS_SP1->u.varray->prototype, + j, &builtin_result); + else + /* Take it from the class' prototype */ + goto _op_load_property_try_proto; + break; + + case JS_FUNC: + if (JS_SP1->u.vfunction->prototype) + js_vm_object_load_property (vm, + JS_SP1->u.vfunction->prototype, + j, &builtin_result); + else + /* Take it from the class' prototype */ + goto _op_load_property_try_proto; + break; + + default: + /* + * The rest do not have instance prototypes; use the + * class prototypes. + */ + _op_load_property_try_proto: + js_vm_object_load_property ( + vm, + vm->prim[JS_SP1->type]->prototype, j, + &builtin_result); + break; + } + } + } + + JS_COPY (JS_SP1, &builtin_result); + } + else + ERROR ("illegal object for load_property"); + NEXT (); + +/* operand store_property (26) */ +op_store_property: + OPERAND (26); + /* Fetch the property symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (JS_SP1->u.vbuiltin->info->property_proc) + { + if ((*JS_SP1->u.vbuiltin->info->property_proc) ( + vm, + JS_SP1->u.vbuiltin->info, + JS_SP1->u.vbuiltin->instance_context, + j, 1, JS_SP2) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Setting the prototype. */ + if (JS_SP2->type != JS_OBJECT) + ERROR ("illegal value for set_property"); + + if (JS_SP1->u.vbuiltin->prototype) + /* Setting the instance's prototype. */ + JS_SP1->u.vbuiltin->prototype = JS_SP2->u.vobject; + else + /* Setting the class' prototype. */ + JS_SP1->u.vbuiltin->info->prototype = JS_SP2->u.vobject; + } + else + { + /* Setting stuff to the prototype. */ + if (JS_SP1->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_store_property (vm, + JS_SP1->u.vbuiltin->prototype, + j, JS_SP2); + else + /* A class. */ + js_vm_object_store_property ( + vm, + JS_SP1->u.vbuiltin->info->prototype, + j, JS_SP2); + } + } + } + else + ERROR ("illegal builtin object for store_property"); + + JS_POP (); + JS_POP (); + } + else if (JS_SP1->type == JS_OBJECT) + { + js_vm_object_store_property (vm, JS_SP1->u.vobject, j, JS_SP2); + JS_POP (); + JS_POP (); + } + else if (vm->prim[JS_SP1->type]) + { + /* The primitive language types. */ + JS_SAVE_REGS (); + if ((*vm->prim[JS_SP1->type]->property_proc) (vm, vm->prim[JS_SP1->type], + JS_SP1, j, 1, JS_SP2) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Setting the prototype. */ + if (JS_SP2->type != JS_OBJECT) + ERROR ("illegal value for set_property"); + + switch (JS_SP1->type) + { + case JS_STRING: + JS_SP1->u.vstring->prototype = JS_SP2->u.vobject; + break; + + case JS_ARRAY: + JS_SP1->u.varray->prototype = JS_SP2->u.vobject; + break; + + case JS_FUNC: + JS_SP1->u.vfunction->prototype = JS_SP2->u.vobject; + break; + + default: + ERROR ("illegal object for set_property"); + break; + } + } + else + { + JSNode prototype; + + /* Setting to the prototype. We create them on demand. */ + switch (JS_SP1->type) + { + case JS_STRING: + if (JS_SP1->u.vstring->prototype == NULL) + { + prototype.type = JS_OBJECT; + + /* Create the prototype and set its __proto__. */ + JS_SP1->u.vstring->prototype = js_vm_object_new (vm); + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property ( + vm, + JS_SP1->u.vstring->prototype, + vm->syms.s___proto__, + &prototype); + } + js_vm_object_store_property (vm, + JS_SP1->u.vstring->prototype, + j, JS_SP2); + break; + + case JS_ARRAY: + if (JS_SP1->u.varray->prototype == NULL) + { + prototype.type = JS_OBJECT; + + /* Create the prototype and set its __proto__. */ + JS_SP1->u.varray->prototype = js_vm_object_new (vm); + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property ( + vm, + JS_SP1->u.varray->prototype, + vm->syms.s___proto__, + &prototype); + } + js_vm_object_store_property (vm, + JS_SP1->u.varray->prototype, + j, JS_SP2); + break; + + case JS_FUNC: + if (JS_SP1->u.vfunction->prototype == NULL) + { + prototype.type = JS_OBJECT; + + /* Create the prototype and set its __proto__. */ + JS_SP1->u.vfunction->prototype = js_vm_object_new (vm); + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property ( + vm, + JS_SP1->u.vfunction->prototype, + vm->syms.s___proto__, + &prototype); + } + js_vm_object_store_property (vm, + JS_SP1->u.vfunction->prototype, + j, JS_SP2); + break; + + default: + ERROR ("illegal object for set_property"); + break; + } + } + } + JS_POP (); + JS_POP (); + } + else + ERROR ("illegal object for store_property"); + + JS_MAYBE_GC (); + NEXT (); + +/* operand load_array (27) */ +op_load_array: + OPERAND (27); + if (JS_SP2->type == JS_BUILTIN) + { + if (JS_SP1->type == JS_INTEGER) + { + ERROR ("integer indexes not implemented yet for BUILTIN in load_array"); + } + else if (JS_SP1->type == JS_STRING) + { + /* Intern the string. */ + j = js_vm_intern_with_len (vm, JS_SP1->u.vstring->data, + JS_SP1->u.vstring->len); + + /* The code below must be in sync with operand `load_property'. */ + JS_SAVE_REGS (); + + if (JS_SP2->u.vbuiltin->info->property_proc) + { + if ((*JS_SP2->u.vbuiltin->info->property_proc) ( + vm, + JS_SP2->u.vbuiltin->info, + JS_SP2->u.vbuiltin->instance_context, + j, 0, &builtin_result) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Looking up the prototype. */ + + builtin_result.type = JS_OBJECT; + if (JS_SP2->u.vbuiltin->prototype) + /* This is an instance. */ + builtin_result.u.vobject + = JS_SP2->u.vbuiltin->prototype; + else + /* This is a class. */ + builtin_result.u.vobject + = JS_SP2->u.vbuiltin->info->prototype; + } + else + { + /* Looking up stuffs from the prototype. */ + + if (JS_SP2->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_load_property ( + vm, + JS_SP2->u.vbuiltin->prototype, + j, &builtin_result); + else + /* A class. */ + js_vm_object_load_property ( + vm, + JS_SP2->u.vbuiltin->info->prototype, + j, &builtin_result); + } + } + JS_COPY (JS_SP2, &builtin_result); + JS_POP (); + } + else + ERROR ("illegal builtin object for load_array"); + } + else + { + sprintf (buf, "illegal array index in load_array (%d)", + JS_SP1->type); + ERROR (buf); + } + } + else if (JS_SP2->type == JS_OBJECT) + { + js_vm_object_load_array (vm, JS_SP2->u.vobject, JS_SP1, JS_SP2); + JS_POP (); + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->type == JS_INTEGER) + { + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.varray->length) + JS_SP2->type = JS_UNDEFINED; + else + { + JSNode *n = &JS_SP2->u.varray->data[JS_SP1->u.vinteger]; + JS_COPY (JS_SP2, n); + } + JS_POP (); + } + else + { + sprintf (buf, "illegal array index in load_array (%d)", + JS_SP1->type); + ERROR (buf); + } + } + else if (JS_SP2->type == JS_STRING) + { + if (JS_SP1->type == JS_INTEGER) + { + int ch; + + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.vstring->len) + ERROR ("string index out of range in load_array"); + + ch = JS_SP2->u.vstring->data[JS_SP1->u.vinteger]; + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = ch; + + JS_POP (); + } + else + ERROR ("illegal string index in load_array"); + } + else + ERROR ("illegal object for load_array"); + NEXT (); + +/* operand store_array (28) */ +op_store_array: + OPERAND (28); + if (JS_SP2->type == JS_BUILTIN) + { + if (JS_SP1->type == JS_INTEGER) + { + ERROR ("integer index not implemented yet for BUILTIN in store_array"); + } + else if (JS_SP1->type == JS_STRING) + { + /* Intern the string. */ + j = js_vm_intern_with_len (vm, JS_SP1->u.vstring->data, + JS_SP1->u.vstring->len); + + /* The code below msut be in sync with operand `store_property'. */ + JS_SAVE_REGS (); + if (JS_SP2->u.vbuiltin->info->property_proc) + { + if ((*JS_SP2->u.vbuiltin->info->property_proc) ( + vm, + JS_SP2->u.vbuiltin->info, + JS_SP2->u.vbuiltin->instance_context, + j, 1, JS_SP (3)) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Setting the prototype. */ + if (JS_SP (3)->type != JS_OBJECT) + ERROR ("illegal value for prototype"); + + if (JS_SP2->u.vbuiltin->prototype) + /* Setting the instance's prototype. */ + JS_SP2->u.vbuiltin->prototype = JS_SP (3)->u.vobject; + else + /* Setting the class' prototype. */ + JS_SP2->u.vbuiltin->info->prototype + = JS_SP (3)->u.vobject; + } + else + { + /* Setting stuff to the prototype. */ + if (JS_SP2->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_store_property ( + vm, + JS_SP2->u.vbuiltin->prototype, + j, JS_SP (3)); + else + /* A class. */ + js_vm_object_store_property ( + vm, + JS_SP2->u.vbuiltin->info->prototype, + j, JS_SP (3)); + } + } + } + else + ERROR ("illegal builtin object for store_array"); + + JS_POP_N (3); + } + else + ERROR ("illegal array index in store_array"); + } + else if (JS_SP2->type == JS_OBJECT) + { + js_vm_object_store_array (vm, JS_SP2->u.vobject, JS_SP1, JS_SP (3)); + JS_POP_N (3); + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->type == JS_INTEGER) + { + if (JS_SP1->u.vinteger < 0) + ERROR ("negative array index in store_array"); + if (JS_SP1->u.vinteger >= JS_SP2->u.varray->length) + js_vm_expand_array (vm, JS_SP2, JS_SP1->u.vinteger + 1); + + JS_COPY (&JS_SP2->u.varray->data[JS_SP1->u.vinteger], JS_SP (3)); + JS_POP_N (3); + } + else + ERROR ("illegal array index in store_array"); + } + else if (JS_SP2->type == JS_STRING) + { + if (JS_SP1->type == JS_INTEGER) + { + if (JS_SP2->u.vstring->staticp) + ERROR ("static string in store_array"); + + if (JS_SP1->u.vinteger < 0) + ERROR ("negative string index in store_array"); + + if (JS_SP (3)->type != JS_INTEGER) + ERROR ("non-integer value to store into string in store_array"); + + if (JS_SP1->u.vinteger >= JS_SP2->u.vstring->len) + { + /* Expand the string. */ + JS_SP2->u.vstring->data = js_vm_realloc (vm, + JS_SP2->u.vstring->data, + JS_SP1->u.vinteger + 1); + /* Fill the gap with ' '. */ + for (; JS_SP2->u.vstring->len <= JS_SP1->u.vinteger;) + JS_SP2->u.vstring->data[JS_SP2->u.vstring->len++] = ' '; + } + + JS_SP2->u.vstring->data[JS_SP1->u.vinteger] + = (unsigned char) JS_SP (3)->u.vinteger; + JS_POP_N (3); + } + else + ERROR ("illegal string index in store_array"); + } + else + ERROR ("illegal object for store_array"); + + JS_MAYBE_GC (); + NEXT (); + +/* operand nth (29) */ +op_nth: + OPERAND (29); + if (JS_SP2->type == JS_STRING) + { + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.vstring->len) + { + JS_SP2->type = JS_UNDEFINED; + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 0; + } + else + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = JS_SP2->u.vstring->data[JS_SP1->u.vinteger]; + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 1; + } + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.varray->length) + { + JS_SP2->type = JS_UNDEFINED; + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 0; + } + else + { + JSNode *n = &JS_SP2->u.varray->data[JS_SP1->u.vinteger]; + JS_COPY (JS_SP2, n); + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 1; + } + } + else if (JS_SP2->type == JS_OBJECT) + { + i = js_vm_object_nth (vm, JS_SP2->u.vobject, JS_SP1->u.vinteger, JS_SP2); + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = i; + } + else + ERROR ("illegal object for nth"); + NEXT (); + +/* operand cmp_eq (30) */ +op_cmp_eq: + OPERAND (30); + JS_OPERAND_CMP_EQ (==, 1); + NEXT (); + +/* operand cmp_ne (31) */ +op_cmp_ne: + OPERAND (31); + JS_OPERAND_CMP_EQ (!=, 0); + NEXT (); + +/* operand cmp_lt (32) */ +op_cmp_lt: + OPERAND (32); + JS_OPERAND_CMP_REL (<); + NEXT (); + +/* operand cmp_gt (33) */ +op_cmp_gt: + OPERAND (33); + JS_OPERAND_CMP_REL (>); + NEXT (); + +/* operand cmp_le (34) */ +op_cmp_le: + OPERAND (34); + JS_OPERAND_CMP_REL (<=); + NEXT (); + +/* operand cmp_ge (35) */ +op_cmp_ge: + OPERAND (35); + JS_OPERAND_CMP_REL (>=); + NEXT (); + +/* operand cmp_seq (36) */ +op_cmp_seq: + OPERAND (36); + JS_OPERAND_CMP_SEQ (==, 1); + NEXT (); + +/* operand cmp_sne (37) */ +op_cmp_sne: + OPERAND (37); + JS_OPERAND_CMP_SEQ (!=, 0); + NEXT (); + +/* operand sub (38) */ +op_sub: + OPERAND (38); + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger -= JS_SP1->u.vinteger; + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (l->type == JS_INTEGER) + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger - r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = (double) l->u.vinteger - r->u.vfloat; + } + } + else + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat - (double) r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat - r->u.vfloat; + } + } + } + + JS_POP (); + NEXT (); + +/* operand add (39) */ +op_add: + OPERAND (39); + if (JS_SP2->type == JS_STRING || JS_SP1->type == JS_STRING) + { + unsigned char *d2, *d1, *ndata; + unsigned int d2_len, d1_len, nlen; + JSNode cvt; + + if (JS_SP2->type == JS_STRING) + { + d2 = JS_SP2->u.vstring->data; + d2_len = JS_SP2->u.vstring->len; + } + else + { + js_vm_to_string (vm, JS_SP2, &cvt); + d2 = cvt.u.vstring->data; + d2_len = cvt.u.vstring->len; + } + if (JS_SP1->type == JS_STRING) + { + d1 = JS_SP1->u.vstring->data; + d1_len = JS_SP1->u.vstring->len; + } + else + { + js_vm_to_string (vm, JS_SP1, &cvt); + d1 = cvt.u.vstring->data; + d1_len = cvt.u.vstring->len; + } + + nlen = d2_len + d1_len; + ndata = js_vm_alloc (vm, nlen); + memcpy (ndata, d2, d2_len); + memcpy (ndata + d2_len, d1, d1_len); + + js_vm_make_static_string (vm, JS_SP2, ndata, nlen); + JS_SP2->u.vstring->staticp = 0; + JS_POP (); + JS_MAYBE_GC (); + } + else if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger += JS_SP1->u.vinteger; + JS_POP (); + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (l->type == JS_INTEGER) + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger + r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = (double) l->u.vinteger + r->u.vfloat; + } + } + else + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat + (double) r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat + r->u.vfloat; + } + } + + JS_POP (); + } + NEXT (); + +/* operand mul (40) */ +op_mul: + OPERAND (40); + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger *= JS_SP1->u.vinteger; + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (l->type == JS_INTEGER) + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger * r->u.vinteger; + } + else + { + if (l->u.vinteger == 0 + && (JS_IS_POSITIVE_INFINITY (r) + || JS_IS_NEGATIVE_INFINITY (r))) + JS_SP2->type = JS_NAN; + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = (double) l->u.vinteger * r->u.vfloat; + } + } + } + else + { + if ((JS_IS_POSITIVE_INFINITY (l) || JS_IS_NEGATIVE_INFINITY (l)) + && ((r->type == JS_INTEGER && r->u.vinteger == 0) + || (r->type == JS_FLOAT && r->u.vfloat == 0.0))) + JS_SP2->type = JS_NAN; + else + { + JS_SP2->type = JS_FLOAT; + + if (r->type == JS_INTEGER) + JS_SP2->u.vfloat = l->u.vfloat * (double) r->u.vinteger; + else + JS_SP2->u.vfloat = l->u.vfloat * r->u.vfloat; + } + } + } + + JS_POP (); + NEXT (); + +/* operand div (41) */ +op_div: + OPERAND (41); + { + int nan = 0; + double l, r; + int l_inf = 0; + int r_inf = 0; + JSNode *n; + JSNode cvt; + + /* Convert divident to float. */ + if (JS_IS_NUMBER (JS_SP2)) + n = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &cvt); + n = &cvt; + } + + switch (n->type) + { + case JS_INTEGER: + l = (double) n->u.vinteger; + break; + + case JS_FLOAT: + l = n->u.vfloat; + if (JS_IS_POSITIVE_INFINITY (n) || JS_IS_NEGATIVE_INFINITY (n)) + l_inf = 1; + break; + + case JS_NAN: + default: + nan = 1; + break; + } + + /* Convert divisor to float. */ + if (JS_IS_NUMBER (JS_SP1)) + n = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP2, &cvt); + n = &cvt; + } + + switch (n->type) + { + case JS_INTEGER: + r = (double) n->u.vinteger; + break; + + case JS_FLOAT: + r = n->u.vfloat; + if (JS_IS_POSITIVE_INFINITY (n) || JS_IS_NEGATIVE_INFINITY (n)) + r_inf = 1; + break; + + case JS_NAN: + default: + nan = 1; + break; + } + + /* Do the division. */ + JS_POP (); + if (nan || (l_inf && r_inf)) + JS_SP1->type = JS_NAN; + else + { + if (l_inf && r == 0.0) + { + /* is already an infinity. */ + JS_SP1->type = JS_FLOAT; + JS_SP1->u.vfloat = l; + } + else if (l == 0.0 && r == 0.0) + JS_SP1->type = JS_NAN; + else + { + JS_SP1->type = JS_FLOAT; + JS_SP1->u.vfloat = l / r; + } + } + } + NEXT (); + +/* operand mod (42) */ +op_mod: + OPERAND (42); + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + if (JS_SP1->u.vinteger == 0) + JS_SP2->type = JS_NAN; + else + JS_SP2->u.vinteger %= JS_SP1->u.vinteger; + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (JS_IS_POSITIVE_INFINITY (l) + || JS_IS_NEGATIVE_INFINITY (l) + || ((r->type == JS_INTEGER && r->u.vinteger == 0) + || (r->type == JS_FLOAT && r->u.vfloat == 0.0))) + JS_SP2->type = JS_NAN; + else if (JS_IS_POSITIVE_INFINITY (r) + || JS_IS_NEGATIVE_INFINITY (r)) + JS_COPY (JS_SP2, l); + else if ((l->type == JS_INTEGER && l->u.vinteger == 0) + || (l->type == JS_FLOAT && l->u.vfloat == 0.0)) + JS_COPY (JS_SP2, l); + else + { + if (l->type == JS_INTEGER && r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger % r->u.vinteger; + } + else + { + double ld, rd; + int full; + + if (l->type == JS_INTEGER) + ld = (double) l->u.vinteger; + else + ld = l->u.vfloat; + + if (r->type == JS_INTEGER) + rd = (double) r->u.vinteger; + else + rd = r->u.vfloat; + + full = ld / rd; + + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = ld - (full * rd); + } + } + } + + JS_POP (); + NEXT (); + +/* operand neg (43) */ +op_neg: + OPERAND (43); + if (JS_SP1->type == JS_INTEGER) + JS_SP1->u.vinteger = -JS_SP1->u.vinteger; + else if (JS_SP1->type == JS_FLOAT) + JS_SP1->u.vfloat = -JS_SP1->u.vfloat; + else if (JS_SP1->type == JS_NAN) + ; + else + { + JSNode cvt; + + js_vm_to_number (vm, JS_SP1, &cvt); + + JS_SP1->type = cvt.type; + switch (cvt.type) + { + case JS_INTEGER: + JS_SP1->u.vinteger = -cvt.u.vinteger; + break; + + case JS_FLOAT: + JS_SP1->u.vfloat = -cvt.u.vfloat; + break; + + case JS_NAN: + default: + /* Nothing here. */ + break; + } + } + NEXT (); + +/* operand and (44) */ +op_and: + OPERAND (44); + JS_OPERAND_BINARY (&); + NEXT (); + +/* operand not (45) */ +op_not: + OPERAND (45); + JS_SP1->u.vboolean = JS_IS_FALSE (JS_SP1); + JS_SP1->type = JS_BOOLEAN; + NEXT (); + +/* operand or (46) */ +op_or: + OPERAND (46); + JS_OPERAND_BINARY (|); + NEXT (); + +/* operand xor (47) */ +op_xor: + OPERAND (47); + JS_OPERAND_BINARY (^); + NEXT (); + +/* operand shift_left (48) */ +op_shift_left: + OPERAND (48); + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger = ((JSInt32) JS_SP2->u.vinteger + << (JSUInt32) JS_SP1->u.vinteger); + JS_POP (); + } + else + { + JSInt32 l; + JSUInt32 r; + + l = js_vm_to_int32 (vm, JS_SP2); + r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1); + + JS_SP2->u.vinteger = l << r; + JS_SP2->type = JS_INTEGER; + JS_POP (); + } + NEXT (); + +/* operand shift_right (49) */ +op_shift_right: + OPERAND (49); + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger = ((JSInt32) JS_SP2->u.vinteger + >> (JSUInt32) JS_SP1->u.vinteger); + JS_POP (); + } + else + { + JSInt32 l; + JSUInt32 r; + + l = js_vm_to_int32 (vm, JS_SP2); + r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1); + + JS_SP2->u.vinteger = l >> r; + JS_SP2->type = JS_INTEGER; + JS_POP (); + } + NEXT (); + +/* operand shift_rright (50) */ +op_shift_rright: + OPERAND (50); + { + JSInt32 l; + JSUInt32 r; + + l = js_vm_to_int32 (vm, JS_SP2); + r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1); + + if (r > 0) + JS_SP2->u.vinteger = (l & 0x7fffffff) >> r; + else + JS_SP2->u.vinteger = l; + + JS_SP2->type = JS_INTEGER; + JS_POP (); + } + NEXT (); + +/* operand iffalse (51) */ +op_iffalse: + OPERAND (51); + READ_INT32 (i); + if (JS_IS_FALSE (JS_SP1)) + SETPC_RELATIVE (i); + JS_POP (); + NEXT (); + +/* operand iftrue (52) */ +op_iftrue: + OPERAND (52); + READ_INT32 (i); + if (JS_IS_TRUE (JS_SP1)) + SETPC_RELATIVE (i); + JS_POP (); + NEXT (); + +/* operand call_method (53) */ +op_call_method: + OPERAND (53); + /* Fetch the method symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (JS_SP1->u.vbuiltin->info->method_proc) + { + if ((*JS_SP1->u.vbuiltin->info->method_proc) ( + vm, + JS_SP1->u.vbuiltin->info, + JS_SP1->u.vbuiltin->instance_context, j, + &builtin_result, JS_SP2) + == JS_PROPERTY_UNKNOWN) + ERROR ("call_method: unknown method"); + } + else + ERROR ("illegal builtin object for call_method"); + + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + JS_MAYBE_GC (); + } + else if (JS_SP1->type == JS_OBJECT) + { + JSNode method; + + if (js_vm_object_load_property (vm, JS_SP1->u.vobject, j, &method) + == JS_PROPERTY_FOUND) + { + /* The property has been defined in the object. */ + + if (method.type != JS_FUNC) + ERROR ("call_method: unknown method"); + + /* And once again. We must do a subroutine call here. */ + JS_SUBROUTINE_CALL (method.u.vfunction->implementation); + } + else + /* Let our prototype handle this. */ + goto _op_call_method_try_proto; + } + else if (vm->prim[JS_SP1->type]) + { + /* The primitive language types. */ + _op_call_method_try_proto: + JS_SAVE_REGS (); + if ((*vm->prim[JS_SP1->type]->method_proc) (vm, vm->prim[JS_SP1->type], + JS_SP1, j, &builtin_result, + JS_SP2) + == JS_PROPERTY_UNKNOWN) + { + JSNode method; + int result = JS_PROPERTY_UNKNOWN; + + /* Let's see if we can find it from the prototype. */ + if (JS_SP1->type == JS_STRING && JS_SP1->u.vstring->prototype) + result = js_vm_object_load_property (vm, + JS_SP1->u.vstring->prototype, + j, &method); + else if (JS_SP1->type == JS_ARRAY && JS_SP1->u.varray->prototype) + result = js_vm_object_load_property (vm, + JS_SP1->u.varray->prototype, + j, &method); + else if (JS_SP1->type == JS_FUNC && JS_SP1->u.vfunction->prototype) + result + = js_vm_object_load_property (vm, JS_SP1->u.vfunction->prototype, + j, &method); + + if (result == JS_PROPERTY_UNKNOWN || method.type != JS_FUNC) + ERROR ("call_method: unknown method"); + + /* Do the subroutine call. */ + JS_SUBROUTINE_CALL (method.u.vfunction->implementation); + } + else + { + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + JS_MAYBE_GC (); + } + } + else + ERROR ("illegal object for call_method"); + NEXT (); + +/* operand jmp (54) */ +op_jmp: + OPERAND (54); + READ_INT32 (i); + SETPC_RELATIVE (i); + NEXT (); + +/* operand jsr (55) */ +op_jsr: + OPERAND (55); + /* Call the global method. */ + { + JSNode f; + + /* Fetch the function to our local variable. */ + JS_COPY (&f, JS_SP1); + function = &f; + + /* Reset the `this' to null. */ + JS_SP1->type = JS_NULL; + + if (function->type == JS_BUILTIN + && function->u.vbuiltin->info->global_method_proc) + { + JS_SAVE_REGS (); + (*function->u.vbuiltin->info->global_method_proc) ( + vm, + function->u.vbuiltin->info, + function->u.vbuiltin->instance_context, + &builtin_result, + JS_SP2); + + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + } + else if (function->type == JS_FUNC) + { + JS_SUBROUTINE_CALL (function->u.vfunction->implementation); + } + else + { + sprintf (buf, "illegal function object in jsr"); + ERROR (buf); + } + } + NEXT (); + +/* operand return (56) */ +op_return: + OPERAND (56); + if (fp->u.iptr == NULL) + /* Return from the global scope. */ + DONE (); + + /* STACKFRAME */ + + /* Check if the stack has been modified by min_args. */ + if (JS_ARGS_FIXP->u.args_fix.delta) + { + unsigned int delta = JS_ARGS_FIXP->u.args_fix.delta; + + /* + * Yes it was. Truncate it back to the state where it was + * before the call. + */ + + memmove (JS_SP1 + delta, JS_SP1, + (fp - JS_SP0 + JS_ARGS_FIXP->u.args_fix.argc) + * sizeof (JSNode)); + + sp += delta; + fp += delta; + } + + /* Set pc to the saved return address. */ +#if 0 + if (fp[-3].type != JS_IPTR) + ERROR ("can't find saved return address"); +#endif + pc = fp[-3].u.iptr; + + { + void *old_fp; + + /* Save old frame pointer. */ +#if 0 + if (fp->type != JS_IPTR) + ERROR ("can't find saved frame pointer"); +#endif + old_fp = fp->u.iptr; + + /* Put return value to its correct location. */ + JS_COPY (fp, JS_SP1); + + /* Restore sp. */ + sp = &fp[-1]; + + /* Restore frame pointer. */ + fp = old_fp; + } + NEXT (); + +/* operand typeof (57) */ +op_typeof: + OPERAND (57); + { + char *typeof_name = ""; /* Initialized to make compiler quiet. */ + + switch (JS_SP1->type) + { + case JS_UNDEFINED: + typeof_name = "undefined"; + break; + + case JS_NULL: + typeof_name = "object"; + break; + + case JS_BOOLEAN: + typeof_name = "boolean"; + break; + + case JS_INTEGER: + case JS_FLOAT: + case JS_NAN: + typeof_name = "number"; + break; + + case JS_STRING: + typeof_name = "string"; + break; + + case JS_ARRAY: + typeof_name = "#array"; + break; + + case JS_OBJECT: + typeof_name = "object"; + break; + + case JS_SYMBOL: + typeof_name = "#symbol"; + break; + + case JS_BUILTIN: + typeof_name = "#builtin"; + break; + + case JS_FUNC: + typeof_name = "function"; + break; + + case JS_IPTR: + typeof_name = "#iptr"; + break; + + case JS_ARGS_FIX: + typeof_name = "#argsfix"; + break; + } + + js_vm_make_static_string (vm, JS_SP1, typeof_name, strlen (typeof_name)); + JS_MAYBE_GC (); + } + NEXT (); + +/* operand new (58) */ +op_new: + OPERAND (58); + /* Check object. */ + if (JS_SP1->type == JS_BUILTIN && JS_SP1->u.vbuiltin->info->new_proc) + { + JS_SAVE_REGS (); + (*JS_SP1->u.vbuiltin->info->new_proc) (vm, JS_SP1->u.vbuiltin->info, + JS_SP2, JS_SP1); + + /* Push a dummy return value for the constructor. This is ignored. */ + JS_SP0->type = JS_UNDEFINED; + JS_PUSH (); + } + else if (JS_SP1->type == JS_FUNC) + { + JSObject *obj; + JSNode f; + JSNode prototype; + + /* The prototype is an object. */ + prototype.type = JS_OBJECT; + + /* Create the prototype for the function, if it is not defined. */ + if (JS_SP1->u.vfunction->prototype == NULL) + { + JS_SP1->u.vfunction->prototype = js_vm_object_new (vm); + + /* Set its __proto__ to point to Object's prototype. */ + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property (vm, JS_SP1->u.vfunction->prototype, + vm->syms.s___proto__, &prototype); + } + + /* Allocate a new object and set its prototype. */ + + obj = js_vm_object_new (vm); + + prototype.u.vobject = JS_SP1->u.vfunction->prototype; + js_vm_object_store_property (vm, obj, vm->syms.s___proto__, &prototype); + + /* + * Basicly we do a jsr to the function given in JS_SP1. But first, + * we must set `this' pointer to the correct value. See `jsr' for + * the details. + */ + JS_COPY (&f, JS_SP1); + + /* Replace func with the new object. */ + JS_SP1->type = JS_OBJECT; + JS_SP1->u.vobject = obj; + + JS_SUBROUTINE_CALL (f.u.vfunction->implementation); + } + /* The primitive language types. */ + else if (vm->prim[JS_SP1->type]) + { + JS_SAVE_REGS (); + (*vm->prim[JS_SP1->type]->new_proc) (vm, vm->prim[JS_SP1->type], JS_SP2, + JS_SP1); + JS_PUSH (); + } + else + ERROR ("illegal object for new"); + + JS_MAYBE_GC (); + NEXT (); + +/* operand delete_property (59) */ +op_delete_property: + OPERAND (59); + /* Fetch the property symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + /* + * XXX It should be possible to apply delete operand to builtin + * XXX objects. + */ + ERROR ("delete_property: JS_BUILTIN: not implemented yet"); + } + else if (JS_SP1->type == JS_OBJECT) + { + js_vm_object_delete_property (vm, JS_SP1->u.vobject, j); + } + else if (JS_SP1->type == JS_NULL) + { + /* Delete a property from an object in the with-chain. */ + /* WITHCHAIN */ + ERROR ("delete_property: not implemented yet for the with-chain objects"); + } + /* The primitive language types. */ + /* + * XXX Since we can't delete properties from builtins, we can't delete + * XXX them from the primitive language types. + */ + else + ERROR ("illegal object for delete_property"); + + /* The delete operand returns an undefined value. */ + JS_SP1->type = JS_UNDEFINED; + NEXT (); + +/* operand delete_array (60) */ +op_delete_array: + OPERAND (60); + if (JS_SP2->type == JS_BUILTIN) + { + ERROR ("delete_array: JS_BUILTIN: not implemented yet"); + } + else if (JS_SP2->type == JS_OBJECT) + { + js_vm_object_delete_array (vm, JS_SP2->u.vobject, JS_SP1); + JS_POP (); + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->type == JS_INTEGER) + { + if (0 <= JS_SP1->u.vinteger + && JS_SP1->u.vinteger < JS_SP2->u.varray->length) + JS_SP2->u.varray->data[JS_SP1->u.vinteger].type = JS_UNDEFINED; + JS_POP (); + } + else + ERROR ("illegal array index in delete_array"); + } + else + ERROR ("illegal object for delete_array"); + + /* The delete operand returns an undefined value. */ + JS_SP1->type = JS_UNDEFINED; + NEXT (); + +/* operand locals (61) */ +op_locals: + OPERAND (61); + READ_INT16 (i); + if (sp - i - JS_RESERVE_STACK_FOR_FUNCTION < vm->stack) + ERROR ("stack overflow"); + + for (; i > 0; i--) + { + JS_SP0->type = JS_UNDEFINED; + JS_PUSH (); + } + NEXT (); + +/* operand min_args (62) */ +op_min_args: + OPERAND (62); + READ_INT8 (i); + + if (JS_SP1->u.vinteger < i) + { + unsigned int delta = i - JS_SP1->u.vinteger; + unsigned int argc = JS_SP1->u.vinteger; + + memmove (JS_SP1 - delta, JS_SP1, (fp - JS_SP0 + argc) * sizeof (JSNode)); + sp -= delta; + fp -= delta; + + /* Fill up the fix_args slot. */ + JS_ARGS_FIXP->u.args_fix.argc = argc; + JS_ARGS_FIXP->u.args_fix.delta = delta; + + for (; argc < i; argc++) + JS_ARG (argc)->type = JS_UNDEFINED; + } + + JS_POP (); + NEXT (); + +/* operand load_nth_arg (63) */ +op_load_nth_arg: + OPERAND (63); + { + int index = JS_SP1->u.vinteger; + JS_COPY (JS_SP1, JS_ARG (index)); + } + NEXT (); + +/* operand with_push (64) */ +op_with_push: + OPERAND (64); + if (JS_SP1->type != JS_OBJECT && JS_SP1->type != JS_BUILTIN) + ERROR ("illegal object for with_push"); + + /* WITHCHAIN */ + + if (JS_WITHPTR->u.iptr == NULL) + { + JSNode *np; + JSUIntAlign *ip = js_vm_alloc (vm, + sizeof (JSUIntAlign) + + sizeof (JSNode)); + *ip = 1; + np = (JSNode *) ((unsigned char *) ip + sizeof (JSUIntAlign)); + + JS_COPY (np, JS_SP1); + JS_WITHPTR->u.iptr = ip; + } + else + { + JSNode *np; + JSUIntAlign *ip = JS_WITHPTR->u.iptr; + JSUIntAlign ui = *ip; + + ip = js_vm_realloc (vm, ip, + sizeof (JSUIntAlign) + + ((ui + 1) * sizeof (JSNode))); + (*ip)++; + np = (JSNode *) ((unsigned char *) ip + sizeof (JSUIntAlign)); + + JS_COPY (&np[ui], JS_SP1); + JS_WITHPTR->u.iptr = ip; + } + + JS_POP (); + NEXT (); + +/* operand with_pop (65) */ +op_with_pop: + OPERAND (65); + READ_INT8 (i); + + /* WITHCHAIN */ + + { + JSUIntAlign *ip = JS_WITHPTR->u.iptr; + + if (ip == NULL || *ip < i) + ERROR ("with stack underflow in with_pop"); + + *ip -= i; + } + NEXT (); + +/* operand try_push (66) */ +op_try_push: + OPERAND (66); + READ_INT32 (i); + + { + JSErrorHandlerFrame *frame = js_calloc (vm, 1, sizeof (*frame)); + + frame->next = vm->error_handler; + frame->sp = sp; + frame->fp = fp; + frame->pc = pc; + frame->pc_delta = i; + vm->error_handler = frame; + + if (setjmp (vm->error_handler->error_jmp)) + { + /* Ok, we caught an error. */ + + /* Restore our state. */ + sp = vm->error_handler->sp; + fp = vm->error_handler->fp; + pc = vm->error_handler->pc; + i = vm->error_handler->pc_delta; + + /* Push the thrown value to the stack. */ + JS_COPY (JS_SP0, &vm->error_handler->thrown); + JS_PUSH (); + + /* Remove this handler frame. */ + frame = vm->error_handler; + vm->error_handler = vm->error_handler->next; + js_free (frame); + + /* Do the jump to the catch block. */ + SETPC_RELATIVE (i); + } + } + NEXT (); + +/* operand try_pop (67) */ +op_try_pop: + OPERAND (67); + READ_INT8 (i); + + for (; i > 0; i--) + { + JSErrorHandlerFrame *frame = vm->error_handler; + + vm->error_handler = vm->error_handler->next; + js_free (frame); + } + NEXT (); + +/* operand throw (68) */ +op_throw: + OPERAND (68); + { + JSErrorHandlerFrame *f = vm->error_handler; + + if (f->sp == NULL) + { + JSNode cvt; + int len; + + /* + * We are jumping to the C-toplevel. Convert our thrown value + * to string and store it to the vm->error. + */ + js_vm_to_string (vm, JS_SP1, &cvt); + + len = cvt.u.vstring->len; + if (len + 1 > sizeof (vm->error)) + len = sizeof (vm->error) - 1; + + memcpy (vm->error, cvt.u.vstring->data, len); + vm->error[len] = '\0'; + } + else + JS_COPY (&f->thrown, JS_SP1); + + longjmp (f->error_jmp, 1); + + /* NOTREACHED (I hope). */ + + sprintf (buf, "VM: no valid error handler initialized%s", + JS_HOST_LINE_BREAK); + DbgPrint("%s\n", buf); +#if 0 + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); +#endif + + abort (); + } + NEXT (); + +/* operand iffalse_b (69) */ +op_iffalse_b: + OPERAND (69); + READ_INT32 (i); + if (!JS_SP1->u.vboolean) + SETPC_RELATIVE (i); + JS_POP (); + NEXT (); + +/* operand iftrue_b (70) */ +op_iftrue_b: + OPERAND (70); + READ_INT32 (i); + if (JS_SP1->u.vboolean) + SETPC_RELATIVE (i); + JS_POP (); + NEXT (); + +/* operand add_1_i (71) */ +op_add_1_i: + OPERAND (71); + JS_SP1->u.vinteger++; + NEXT (); + +/* operand add_2_i (72) */ +op_add_2_i: + OPERAND (72); + JS_SP1->u.vinteger += 2; + NEXT (); + +/* operand load_global_w (73) */ +op_load_global_w: + OPERAND (73); + READ_INT32 (j); + { + int found = 0; + + /* Loop over the with chain. */ + /* WITHCHAIN */ + if (JS_WITHPTR->u.iptr) + { + JSUIntAlign *uip = JS_WITHPTR->u.iptr; + JSUIntAlign ui = *uip; + JSNode *wp = (JSNode *) ((unsigned char *) uip + + sizeof (JSUIntAlign)); + + for (i = 0; i < ui; i++) + { + JSNode *w = &wp[i]; + int result = JS_PROPERTY_UNKNOWN; + + if (w->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (w->u.vbuiltin->info->property_proc) + result = (*w->u.vbuiltin->info->property_proc) ( + vm, + w->u.vbuiltin->info, + w->u.vbuiltin->instance_context, + j, 0, &builtin_result); + } + else if (w->type == JS_OBJECT) + { + result = js_vm_object_load_property (vm, w->u.vobject, j, + &builtin_result); + } + else + ERROR ("corrupted with-chain in load_global"); + + if (result == JS_PROPERTY_FOUND) + { + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + found = 1; + break; + } + } + } + + if (!found) + { + /* Use the global value. */ + JS_COPY (JS_SP0, JS_GLOBAL (j)); + JS_PUSH (); + + if (vm->warn_undef && JS_SP1->type == JS_UNDEFINED) + { + sprintf (buf, "VM: warning: using undefined global `%s'%s", + js_vm_symname (vm, j), JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + } + } + NEXT (); + +/* operand jsr_w (74) */ +op_jsr_w: + OPERAND (74); + /* Read the subroutine symbol index. */ + READ_INT32 (j); + + { + int found = 0; + + /* Loop over the with-chain. */ + /* WITHCHAIN */ + if (JS_WITHPTR->u.iptr) + { + JSUIntAlign *uip = JS_WITHPTR->u.iptr; + JSUIntAlign ui = *uip; + JSNode *wp = (JSNode *) ((unsigned char *) uip + + sizeof (JSUIntAlign)); + + for (i = 0; i < ui; i++) + { + JSNode *w = &wp[i]; + int result = JS_PROPERTY_UNKNOWN; + + if (w->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (w->u.vbuiltin->info->method_proc) + result = (*w->u.vbuiltin->info->method_proc) ( + vm, + w->u.vbuiltin->info, + w->u.vbuiltin->instance_context, j, + &builtin_result, JS_SP2); + JS_MAYBE_GC (); + + if (result == JS_PROPERTY_FOUND) + { + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + } + } + else if (w->type == JS_OBJECT) + { + JSNode method; + + js_vm_object_load_property (vm, w->u.vobject, j, &method); + if (method.type == JS_FUNC) + { + result = JS_PROPERTY_FOUND; + + /* The object defines the method. Do a subroutine call. */ + + /* First: replace the null `this' with `w'. */ + JS_COPY (JS_SP1, w); + + /* Then, do the normal subroutine call. */ + JS_SUBROUTINE_CALL (method.u.vfunction->implementation); + } + } + else + ERROR ("corrupted with-chain in jsr_w"); + + if (result == JS_PROPERTY_FOUND) + { + found = 1; + break; + } + } + } + + if (!found) + { + JSNode f; + + /* Call the global method. */ + JS_COPY (&f, JS_SP1); + function = &f; + + /* Reset the `this' to null. */ + JS_SP1->type = JS_NULL; + + if (function->type == JS_BUILTIN + && function->u.vbuiltin->info->global_method_proc) + { + JS_SAVE_REGS (); + (*function->u.vbuiltin->info->global_method_proc) ( + vm, + function->u.vbuiltin->info, + function->u.vbuiltin->instance_context, + &builtin_result, + JS_SP2); + + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + } + else if (function->type == JS_FUNC) + { + JS_SUBROUTINE_CALL (function->u.vfunction->implementation); + } + else + { + sprintf (buf, "symbol `%s' is undefined as function", + js_vm_symname (vm, j)); + ERROR (buf); + } + } + } + NEXT (); + diff --git a/reactos/lib/kjs/ksrc/eswitch.h b/reactos/lib/kjs/ksrc/eswitch.h new file mode 100644 index 00000000000..e2fd6fce11c --- /dev/null +++ b/reactos/lib/kjs/ksrc/eswitch.h @@ -0,0 +1,2171 @@ +/* operand halt (0) */ +case 0: + sprintf (buf, "VM: halt%s", JS_HOST_LINE_BREAK); + DbgPrint( "%s\n", buf ); +#if 0 + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); +#endif + +#if 0 + while (1) + sleep (5); +#endif + break; + +/* operand done (1) */ +case 1: + DONE (); + break; + +/* operand nop (2) */ +case 2: + /* Nothing here! */ + break; + +/* operand dup (3) */ +case 3: + JS_COPY (JS_SP0, JS_SP1); + JS_PUSH (); + break; + +/* operand pop (4) */ +case 4: + JS_POP (); + break; + +/* operand pop_n (5) */ +case 5: + READ_INT8 (i); + JS_POP_N (i); + break; + +/* operand apop (6) */ +case 6: + READ_INT8 (i); + JS_COPY (JS_SP (i + 1), JS_SP1); + JS_POP_N (i); + break; + +/* operand swap (7) */ +case 7: + JS_COPY (JS_SP0, JS_SP2); + JS_COPY (JS_SP2, JS_SP1); + JS_COPY (JS_SP1, JS_SP0); + break; + +/* operand roll (8) */ +case 8: + READ_INT8 (i8); + + if (i8 > 1) + { + int j; + + for (j = 0; j < i8; j++) + JS_COPY (JS_SP (j), JS_SP (j + 1)); + + JS_COPY (JS_SP (i8), JS_SP0); + } + else if (i8 < -1) + { + i8 = -i8; + + JS_COPY (JS_SP0, JS_SP (i8)); + for (; i8 > 0; i8--) + JS_COPY (JS_SP (i8), JS_SP (i8 - 1)); + } + break; + +/* operand const (9) */ +case 9: + READ_INT32 (i); + JS_COPY (JS_SP0, JS_CONST (i)); + JS_PUSH (); + break; + +/* operand const_null (10) */ +case 10: + JS_SP0->type = JS_NULL; + JS_PUSH (); + break; + +/* operand const_true (11) */ +case 11: + JS_SP0->type = JS_BOOLEAN; + JS_SP0->u.vboolean = 1; + JS_PUSH (); + break; + +/* operand const_false (12) */ +case 12: + JS_SP0->type = JS_BOOLEAN; + JS_SP0->u.vboolean = 0; + JS_PUSH (); + break; + +/* operand const_undefined (13) */ +case 13: + JS_SP0->type = JS_UNDEFINED; + JS_PUSH (); + break; + +/* operand const_i0 (14) */ +case 14: + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 0; + JS_PUSH (); + break; + +/* operand const_i1 (15) */ +case 15: + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 1; + JS_PUSH (); + break; + +/* operand const_i2 (16) */ +case 16: + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 2; + JS_PUSH (); + break; + +/* operand const_i3 (17) */ +case 17: + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 3; + JS_PUSH (); + break; + +/* operand const_i (18) */ +case 18: + READ_INT32 (i); + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = i; + JS_PUSH (); + break; + +/* operand load_global (19) */ +case 19: + READ_INT32 (j); + + /* Use the global value only. */ + JS_COPY (JS_SP0, JS_GLOBAL (j)); + JS_PUSH (); + + if (vm->warn_undef && JS_SP1->type == JS_UNDEFINED) + { + sprintf (buf, "VM: warning: using undefined global `%s'%s", + js_vm_symname (vm, j), JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + break; + +/* operand store_global (20) */ +case 20: + READ_INT32 (i); + + /* Operand store_global do not check the with-chain. */ + /* WITHCHAIN */ + + /* Set the global value. */ + JS_COPY (JS_GLOBAL (i), JS_SP1); + JS_POP (); + break; + +/* operand load_arg (21) */ +case 21: + READ_INT8 (i); + JS_COPY (JS_SP0, JS_ARG (i)); + JS_PUSH (); + break; + +/* operand store_arg (22) */ +case 22: + READ_INT8 (i); + JS_COPY (JS_ARG (i), JS_SP1); + JS_POP (); + break; + +/* operand load_local (23) */ +case 23: + READ_INT16 (i); + JS_COPY (JS_SP0, JS_LOCAL (i)); + JS_PUSH (); + break; + +/* operand store_local (24) */ +case 24: + READ_INT16 (i); + JS_COPY (JS_LOCAL (i), JS_SP1); + JS_POP (); + break; + +/* operand load_property (25) */ +case 25: + /* Fetch the property symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (JS_SP1->u.vbuiltin->info->property_proc) + { + if ((*JS_SP1->u.vbuiltin->info->property_proc) ( + vm, + JS_SP1->u.vbuiltin->info, + JS_SP1->u.vbuiltin->instance_context, + j, 0, &builtin_result) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Looking up the prototype. */ + + builtin_result.type = JS_OBJECT; + if (JS_SP1->u.vbuiltin->prototype) + /* This is an instance. */ + builtin_result.u.vobject = JS_SP1->u.vbuiltin->prototype; + else + /* This is a class. */ + builtin_result.u.vobject + = JS_SP1->u.vbuiltin->info->prototype; + } + else + { + /* Looking up stuffs from the prototype. */ + + if (JS_SP1->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_load_property (vm, + JS_SP1->u.vbuiltin->prototype, + j, &builtin_result); + else + /* A class. */ + js_vm_object_load_property ( + vm, + JS_SP1->u.vbuiltin->info->prototype, + j, &builtin_result); + } + } + JS_COPY (JS_SP1, &builtin_result); + } + else + ERROR ("illegal builtin object for load_property"); + } + else if (JS_SP1->type == JS_OBJECT) + { + js_vm_object_load_property (vm, JS_SP1->u.vobject, j, JS_SP1); + } + else if (vm->prim[JS_SP1->type]) + { + /* The primitive language types. */ + JS_SAVE_REGS (); + if ((*vm->prim[JS_SP1->type]->property_proc) (vm, vm->prim[JS_SP1->type], + JS_SP1, j, 0, + &builtin_result) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Looking up the prototype. */ + switch (JS_SP1->type) + { + case JS_STRING: + if (JS_SP1->u.vstring->prototype) + { + builtin_result.type = JS_OBJECT; + builtin_result.u.vobject = JS_SP1->u.vstring->prototype; + } + else + /* No prototype yet. */ + builtin_result.type = JS_NULL; + break; + + case JS_ARRAY: + if (JS_SP1->u.varray->prototype) + { + builtin_result.type = JS_OBJECT; + builtin_result.u.vobject = JS_SP1->u.varray->prototype; + } + else + /* No prototype yet. */ + builtin_result.type = JS_NULL; + break; + + case JS_FUNC: + if (JS_SP1->u.vfunction->prototype) + { + builtin_result.type = JS_OBJECT; + builtin_result.u.vobject + = JS_SP1->u.vfunction->prototype; + } + else + /* No prototype yet. */ + builtin_result.type = JS_NULL; + break; + + default: + /* The rest do not have prototype. */ + builtin_result.type = JS_NULL; + break; + } + } + else + { + /* Looking up stuffs from the prototype. */ + switch (JS_SP1->type) + { + case JS_STRING: + if (JS_SP1->u.vstring->prototype) + js_vm_object_load_property (vm, + JS_SP1->u.vstring->prototype, + j, &builtin_result); + else + /* Take it from the class' prototype */ + goto _op_load_property_try_proto; + break; + + case JS_ARRAY: + if (JS_SP1->u.varray->prototype) + js_vm_object_load_property (vm, + JS_SP1->u.varray->prototype, + j, &builtin_result); + else + /* Take it from the class' prototype */ + goto _op_load_property_try_proto; + break; + + case JS_FUNC: + if (JS_SP1->u.vfunction->prototype) + js_vm_object_load_property (vm, + JS_SP1->u.vfunction->prototype, + j, &builtin_result); + else + /* Take it from the class' prototype */ + goto _op_load_property_try_proto; + break; + + default: + /* + * The rest do not have instance prototypes; use the + * class prototypes. + */ + _op_load_property_try_proto: + js_vm_object_load_property ( + vm, + vm->prim[JS_SP1->type]->prototype, j, + &builtin_result); + break; + } + } + } + + JS_COPY (JS_SP1, &builtin_result); + } + else + ERROR ("illegal object for load_property"); + break; + +/* operand store_property (26) */ +case 26: + /* Fetch the property symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (JS_SP1->u.vbuiltin->info->property_proc) + { + if ((*JS_SP1->u.vbuiltin->info->property_proc) ( + vm, + JS_SP1->u.vbuiltin->info, + JS_SP1->u.vbuiltin->instance_context, + j, 1, JS_SP2) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Setting the prototype. */ + if (JS_SP2->type != JS_OBJECT) + ERROR ("illegal value for set_property"); + + if (JS_SP1->u.vbuiltin->prototype) + /* Setting the instance's prototype. */ + JS_SP1->u.vbuiltin->prototype = JS_SP2->u.vobject; + else + /* Setting the class' prototype. */ + JS_SP1->u.vbuiltin->info->prototype = JS_SP2->u.vobject; + } + else + { + /* Setting stuff to the prototype. */ + if (JS_SP1->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_store_property (vm, + JS_SP1->u.vbuiltin->prototype, + j, JS_SP2); + else + /* A class. */ + js_vm_object_store_property ( + vm, + JS_SP1->u.vbuiltin->info->prototype, + j, JS_SP2); + } + } + } + else + ERROR ("illegal builtin object for store_property"); + + JS_POP (); + JS_POP (); + } + else if (JS_SP1->type == JS_OBJECT) + { + js_vm_object_store_property (vm, JS_SP1->u.vobject, j, JS_SP2); + JS_POP (); + JS_POP (); + } + else if (vm->prim[JS_SP1->type]) + { + /* The primitive language types. */ + JS_SAVE_REGS (); + if ((*vm->prim[JS_SP1->type]->property_proc) (vm, vm->prim[JS_SP1->type], + JS_SP1, j, 1, JS_SP2) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Setting the prototype. */ + if (JS_SP2->type != JS_OBJECT) + ERROR ("illegal value for set_property"); + + switch (JS_SP1->type) + { + case JS_STRING: + JS_SP1->u.vstring->prototype = JS_SP2->u.vobject; + break; + + case JS_ARRAY: + JS_SP1->u.varray->prototype = JS_SP2->u.vobject; + break; + + case JS_FUNC: + JS_SP1->u.vfunction->prototype = JS_SP2->u.vobject; + break; + + default: + ERROR ("illegal object for set_property"); + break; + } + } + else + { + JSNode prototype; + + /* Setting to the prototype. We create them on demand. */ + switch (JS_SP1->type) + { + case JS_STRING: + if (JS_SP1->u.vstring->prototype == NULL) + { + prototype.type = JS_OBJECT; + + /* Create the prototype and set its __proto__. */ + JS_SP1->u.vstring->prototype = js_vm_object_new (vm); + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property ( + vm, + JS_SP1->u.vstring->prototype, + vm->syms.s___proto__, + &prototype); + } + js_vm_object_store_property (vm, + JS_SP1->u.vstring->prototype, + j, JS_SP2); + break; + + case JS_ARRAY: + if (JS_SP1->u.varray->prototype == NULL) + { + prototype.type = JS_OBJECT; + + /* Create the prototype and set its __proto__. */ + JS_SP1->u.varray->prototype = js_vm_object_new (vm); + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property ( + vm, + JS_SP1->u.varray->prototype, + vm->syms.s___proto__, + &prototype); + } + js_vm_object_store_property (vm, + JS_SP1->u.varray->prototype, + j, JS_SP2); + break; + + case JS_FUNC: + if (JS_SP1->u.vfunction->prototype == NULL) + { + prototype.type = JS_OBJECT; + + /* Create the prototype and set its __proto__. */ + JS_SP1->u.vfunction->prototype = js_vm_object_new (vm); + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property ( + vm, + JS_SP1->u.vfunction->prototype, + vm->syms.s___proto__, + &prototype); + } + js_vm_object_store_property (vm, + JS_SP1->u.vfunction->prototype, + j, JS_SP2); + break; + + default: + ERROR ("illegal object for set_property"); + break; + } + } + } + JS_POP (); + JS_POP (); + } + else + ERROR ("illegal object for store_property"); + + JS_MAYBE_GC (); + break; + +/* operand load_array (27) */ +case 27: + if (JS_SP2->type == JS_BUILTIN) + { + if (JS_SP1->type == JS_INTEGER) + { + ERROR ("integer indexes not implemented yet for BUILTIN in load_array"); + } + else if (JS_SP1->type == JS_STRING) + { + /* Intern the string. */ + j = js_vm_intern_with_len (vm, JS_SP1->u.vstring->data, + JS_SP1->u.vstring->len); + + /* The code below must be in sync with operand `load_property'. */ + JS_SAVE_REGS (); + + if (JS_SP2->u.vbuiltin->info->property_proc) + { + if ((*JS_SP2->u.vbuiltin->info->property_proc) ( + vm, + JS_SP2->u.vbuiltin->info, + JS_SP2->u.vbuiltin->instance_context, + j, 0, &builtin_result) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Looking up the prototype. */ + + builtin_result.type = JS_OBJECT; + if (JS_SP2->u.vbuiltin->prototype) + /* This is an instance. */ + builtin_result.u.vobject + = JS_SP2->u.vbuiltin->prototype; + else + /* This is a class. */ + builtin_result.u.vobject + = JS_SP2->u.vbuiltin->info->prototype; + } + else + { + /* Looking up stuffs from the prototype. */ + + if (JS_SP2->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_load_property ( + vm, + JS_SP2->u.vbuiltin->prototype, + j, &builtin_result); + else + /* A class. */ + js_vm_object_load_property ( + vm, + JS_SP2->u.vbuiltin->info->prototype, + j, &builtin_result); + } + } + JS_COPY (JS_SP2, &builtin_result); + JS_POP (); + } + else + ERROR ("illegal builtin object for load_array"); + } + else + { + sprintf (buf, "illegal array index in load_array (%d)", + JS_SP1->type); + ERROR (buf); + } + } + else if (JS_SP2->type == JS_OBJECT) + { + js_vm_object_load_array (vm, JS_SP2->u.vobject, JS_SP1, JS_SP2); + JS_POP (); + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->type == JS_INTEGER) + { + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.varray->length) + JS_SP2->type = JS_UNDEFINED; + else + { + JSNode *n = &JS_SP2->u.varray->data[JS_SP1->u.vinteger]; + JS_COPY (JS_SP2, n); + } + JS_POP (); + } + else + { + sprintf (buf, "illegal array index in load_array (%d)", + JS_SP1->type); + ERROR (buf); + } + } + else if (JS_SP2->type == JS_STRING) + { + if (JS_SP1->type == JS_INTEGER) + { + int ch; + + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.vstring->len) + ERROR ("string index out of range in load_array"); + + ch = JS_SP2->u.vstring->data[JS_SP1->u.vinteger]; + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = ch; + + JS_POP (); + } + else + ERROR ("illegal string index in load_array"); + } + else + ERROR ("illegal object for load_array"); + break; + +/* operand store_array (28) */ +case 28: + if (JS_SP2->type == JS_BUILTIN) + { + if (JS_SP1->type == JS_INTEGER) + { + ERROR ("integer index not implemented yet for BUILTIN in store_array"); + } + else if (JS_SP1->type == JS_STRING) + { + /* Intern the string. */ + j = js_vm_intern_with_len (vm, JS_SP1->u.vstring->data, + JS_SP1->u.vstring->len); + + /* The code below msut be in sync with operand `store_property'. */ + JS_SAVE_REGS (); + if (JS_SP2->u.vbuiltin->info->property_proc) + { + if ((*JS_SP2->u.vbuiltin->info->property_proc) ( + vm, + JS_SP2->u.vbuiltin->info, + JS_SP2->u.vbuiltin->instance_context, + j, 1, JS_SP (3)) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Setting the prototype. */ + if (JS_SP (3)->type != JS_OBJECT) + ERROR ("illegal value for prototype"); + + if (JS_SP2->u.vbuiltin->prototype) + /* Setting the instance's prototype. */ + JS_SP2->u.vbuiltin->prototype = JS_SP (3)->u.vobject; + else + /* Setting the class' prototype. */ + JS_SP2->u.vbuiltin->info->prototype + = JS_SP (3)->u.vobject; + } + else + { + /* Setting stuff to the prototype. */ + if (JS_SP2->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_store_property ( + vm, + JS_SP2->u.vbuiltin->prototype, + j, JS_SP (3)); + else + /* A class. */ + js_vm_object_store_property ( + vm, + JS_SP2->u.vbuiltin->info->prototype, + j, JS_SP (3)); + } + } + } + else + ERROR ("illegal builtin object for store_array"); + + JS_POP_N (3); + } + else + ERROR ("illegal array index in store_array"); + } + else if (JS_SP2->type == JS_OBJECT) + { + js_vm_object_store_array (vm, JS_SP2->u.vobject, JS_SP1, JS_SP (3)); + JS_POP_N (3); + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->type == JS_INTEGER) + { + if (JS_SP1->u.vinteger < 0) + ERROR ("negative array index in store_array"); + if (JS_SP1->u.vinteger >= JS_SP2->u.varray->length) + js_vm_expand_array (vm, JS_SP2, JS_SP1->u.vinteger + 1); + + JS_COPY (&JS_SP2->u.varray->data[JS_SP1->u.vinteger], JS_SP (3)); + JS_POP_N (3); + } + else + ERROR ("illegal array index in store_array"); + } + else if (JS_SP2->type == JS_STRING) + { + if (JS_SP1->type == JS_INTEGER) + { + if (JS_SP2->u.vstring->staticp) + ERROR ("static string in store_array"); + + if (JS_SP1->u.vinteger < 0) + ERROR ("negative string index in store_array"); + + if (JS_SP (3)->type != JS_INTEGER) + ERROR ("non-integer value to store into string in store_array"); + + if (JS_SP1->u.vinteger >= JS_SP2->u.vstring->len) + { + /* Expand the string. */ + JS_SP2->u.vstring->data = js_vm_realloc (vm, + JS_SP2->u.vstring->data, + JS_SP1->u.vinteger + 1); + /* Fill the gap with ' '. */ + for (; JS_SP2->u.vstring->len <= JS_SP1->u.vinteger;) + JS_SP2->u.vstring->data[JS_SP2->u.vstring->len++] = ' '; + } + + JS_SP2->u.vstring->data[JS_SP1->u.vinteger] + = (unsigned char) JS_SP (3)->u.vinteger; + JS_POP_N (3); + } + else + ERROR ("illegal string index in store_array"); + } + else + ERROR ("illegal object for store_array"); + + JS_MAYBE_GC (); + break; + +/* operand nth (29) */ +case 29: + if (JS_SP2->type == JS_STRING) + { + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.vstring->len) + { + JS_SP2->type = JS_UNDEFINED; + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 0; + } + else + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = JS_SP2->u.vstring->data[JS_SP1->u.vinteger]; + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 1; + } + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.varray->length) + { + JS_SP2->type = JS_UNDEFINED; + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 0; + } + else + { + JSNode *n = &JS_SP2->u.varray->data[JS_SP1->u.vinteger]; + JS_COPY (JS_SP2, n); + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 1; + } + } + else if (JS_SP2->type == JS_OBJECT) + { + i = js_vm_object_nth (vm, JS_SP2->u.vobject, JS_SP1->u.vinteger, JS_SP2); + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = i; + } + else + ERROR ("illegal object for nth"); + break; + +/* operand cmp_eq (30) */ +case 30: + JS_OPERAND_CMP_EQ (==, 1); + break; + +/* operand cmp_ne (31) */ +case 31: + JS_OPERAND_CMP_EQ (!=, 0); + break; + +/* operand cmp_lt (32) */ +case 32: + JS_OPERAND_CMP_REL (<); + break; + +/* operand cmp_gt (33) */ +case 33: + JS_OPERAND_CMP_REL (>); + break; + +/* operand cmp_le (34) */ +case 34: + JS_OPERAND_CMP_REL (<=); + break; + +/* operand cmp_ge (35) */ +case 35: + JS_OPERAND_CMP_REL (>=); + break; + +/* operand cmp_seq (36) */ +case 36: + JS_OPERAND_CMP_SEQ (==, 1); + break; + +/* operand cmp_sne (37) */ +case 37: + JS_OPERAND_CMP_SEQ (!=, 0); + break; + +/* operand sub (38) */ +case 38: + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger -= JS_SP1->u.vinteger; + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (l->type == JS_INTEGER) + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger - r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = (double) l->u.vinteger - r->u.vfloat; + } + } + else + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat - (double) r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat - r->u.vfloat; + } + } + } + + JS_POP (); + break; + +/* operand add (39) */ +case 39: + if (JS_SP2->type == JS_STRING || JS_SP1->type == JS_STRING) + { + unsigned char *d2, *d1, *ndata; + unsigned int d2_len, d1_len, nlen; + JSNode cvt; + + if (JS_SP2->type == JS_STRING) + { + d2 = JS_SP2->u.vstring->data; + d2_len = JS_SP2->u.vstring->len; + } + else + { + js_vm_to_string (vm, JS_SP2, &cvt); + d2 = cvt.u.vstring->data; + d2_len = cvt.u.vstring->len; + } + if (JS_SP1->type == JS_STRING) + { + d1 = JS_SP1->u.vstring->data; + d1_len = JS_SP1->u.vstring->len; + } + else + { + js_vm_to_string (vm, JS_SP1, &cvt); + d1 = cvt.u.vstring->data; + d1_len = cvt.u.vstring->len; + } + + nlen = d2_len + d1_len; + ndata = js_vm_alloc (vm, nlen); + memcpy (ndata, d2, d2_len); + memcpy (ndata + d2_len, d1, d1_len); + + js_vm_make_static_string (vm, JS_SP2, ndata, nlen); + JS_SP2->u.vstring->staticp = 0; + JS_POP (); + JS_MAYBE_GC (); + } + else if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger += JS_SP1->u.vinteger; + JS_POP (); + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (l->type == JS_INTEGER) + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger + r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = (double) l->u.vinteger + r->u.vfloat; + } + } + else + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat + (double) r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat + r->u.vfloat; + } + } + + JS_POP (); + } + break; + +/* operand mul (40) */ +case 40: + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger *= JS_SP1->u.vinteger; + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (l->type == JS_INTEGER) + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger * r->u.vinteger; + } + else + { + if (l->u.vinteger == 0 + && (JS_IS_POSITIVE_INFINITY (r) + || JS_IS_NEGATIVE_INFINITY (r))) + JS_SP2->type = JS_NAN; + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = (double) l->u.vinteger * r->u.vfloat; + } + } + } + else + { + if ((JS_IS_POSITIVE_INFINITY (l) || JS_IS_NEGATIVE_INFINITY (l)) + && ((r->type == JS_INTEGER && r->u.vinteger == 0) + || (r->type == JS_FLOAT && r->u.vfloat == 0.0))) + JS_SP2->type = JS_NAN; + else + { + JS_SP2->type = JS_FLOAT; + + if (r->type == JS_INTEGER) + JS_SP2->u.vfloat = l->u.vfloat * (double) r->u.vinteger; + else + JS_SP2->u.vfloat = l->u.vfloat * r->u.vfloat; + } + } + } + + JS_POP (); + break; + +/* operand div (41) */ +case 41: + { + int nan = 0; + double l, r; + int l_inf = 0; + int r_inf = 0; + JSNode *n; + JSNode cvt; + + /* Convert divident to float. */ + if (JS_IS_NUMBER (JS_SP2)) + n = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &cvt); + n = &cvt; + } + + switch (n->type) + { + case JS_INTEGER: + l = (double) n->u.vinteger; + break; + + case JS_FLOAT: + l = n->u.vfloat; + if (JS_IS_POSITIVE_INFINITY (n) || JS_IS_NEGATIVE_INFINITY (n)) + l_inf = 1; + break; + + case JS_NAN: + default: + nan = 1; + break; + } + + /* Convert divisor to float. */ + if (JS_IS_NUMBER (JS_SP1)) + n = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP2, &cvt); + n = &cvt; + } + + switch (n->type) + { + case JS_INTEGER: + r = (double) n->u.vinteger; + break; + + case JS_FLOAT: + r = n->u.vfloat; + if (JS_IS_POSITIVE_INFINITY (n) || JS_IS_NEGATIVE_INFINITY (n)) + r_inf = 1; + break; + + case JS_NAN: + default: + nan = 1; + break; + } + + /* Do the division. */ + JS_POP (); + if (nan || (l_inf && r_inf)) + JS_SP1->type = JS_NAN; + else + { + if (l_inf && r == 0.0) + { + /* is already an infinity. */ + JS_SP1->type = JS_FLOAT; + JS_SP1->u.vfloat = l; + } + else if (l == 0.0 && r == 0.0) + JS_SP1->type = JS_NAN; + else + { + JS_SP1->type = JS_FLOAT; + JS_SP1->u.vfloat = l / r; + } + } + } + break; + +/* operand mod (42) */ +case 42: + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + if (JS_SP1->u.vinteger == 0) + JS_SP2->type = JS_NAN; + else + JS_SP2->u.vinteger %= JS_SP1->u.vinteger; + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (JS_IS_POSITIVE_INFINITY (l) + || JS_IS_NEGATIVE_INFINITY (l) + || ((r->type == JS_INTEGER && r->u.vinteger == 0) + || (r->type == JS_FLOAT && r->u.vfloat == 0.0))) + JS_SP2->type = JS_NAN; + else if (JS_IS_POSITIVE_INFINITY (r) + || JS_IS_NEGATIVE_INFINITY (r)) + JS_COPY (JS_SP2, l); + else if ((l->type == JS_INTEGER && l->u.vinteger == 0) + || (l->type == JS_FLOAT && l->u.vfloat == 0.0)) + JS_COPY (JS_SP2, l); + else + { + if (l->type == JS_INTEGER && r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger % r->u.vinteger; + } + else + { + double ld, rd; + int full; + + if (l->type == JS_INTEGER) + ld = (double) l->u.vinteger; + else + ld = l->u.vfloat; + + if (r->type == JS_INTEGER) + rd = (double) r->u.vinteger; + else + rd = r->u.vfloat; + + full = ld / rd; + + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = ld - (full * rd); + } + } + } + + JS_POP (); + break; + +/* operand neg (43) */ +case 43: + if (JS_SP1->type == JS_INTEGER) + JS_SP1->u.vinteger = -JS_SP1->u.vinteger; + else if (JS_SP1->type == JS_FLOAT) + JS_SP1->u.vfloat = -JS_SP1->u.vfloat; + else if (JS_SP1->type == JS_NAN) + ; + else + { + JSNode cvt; + + js_vm_to_number (vm, JS_SP1, &cvt); + + JS_SP1->type = cvt.type; + switch (cvt.type) + { + case JS_INTEGER: + JS_SP1->u.vinteger = -cvt.u.vinteger; + break; + + case JS_FLOAT: + JS_SP1->u.vfloat = -cvt.u.vfloat; + break; + + case JS_NAN: + default: + /* Nothing here. */ + break; + } + } + break; + +/* operand and (44) */ +case 44: + JS_OPERAND_BINARY (&); + break; + +/* operand not (45) */ +case 45: + JS_SP1->u.vboolean = JS_IS_FALSE (JS_SP1); + JS_SP1->type = JS_BOOLEAN; + break; + +/* operand or (46) */ +case 46: + JS_OPERAND_BINARY (|); + break; + +/* operand xor (47) */ +case 47: + JS_OPERAND_BINARY (^); + break; + +/* operand shift_left (48) */ +case 48: + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger = ((JSInt32) JS_SP2->u.vinteger + << (JSUInt32) JS_SP1->u.vinteger); + JS_POP (); + } + else + { + JSInt32 l; + JSUInt32 r; + + l = js_vm_to_int32 (vm, JS_SP2); + r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1); + + JS_SP2->u.vinteger = l << r; + JS_SP2->type = JS_INTEGER; + JS_POP (); + } + break; + +/* operand shift_right (49) */ +case 49: + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger = ((JSInt32) JS_SP2->u.vinteger + >> (JSUInt32) JS_SP1->u.vinteger); + JS_POP (); + } + else + { + JSInt32 l; + JSUInt32 r; + + l = js_vm_to_int32 (vm, JS_SP2); + r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1); + + JS_SP2->u.vinteger = l >> r; + JS_SP2->type = JS_INTEGER; + JS_POP (); + } + break; + +/* operand shift_rright (50) */ +case 50: + { + JSInt32 l; + JSUInt32 r; + + l = js_vm_to_int32 (vm, JS_SP2); + r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1); + + if (r > 0) + JS_SP2->u.vinteger = (l & 0x7fffffff) >> r; + else + JS_SP2->u.vinteger = l; + + JS_SP2->type = JS_INTEGER; + JS_POP (); + } + break; + +/* operand iffalse (51) */ +case 51: + READ_INT32 (i); + if (JS_IS_FALSE (JS_SP1)) + SETPC_RELATIVE (i); + JS_POP (); + break; + +/* operand iftrue (52) */ +case 52: + READ_INT32 (i); + if (JS_IS_TRUE (JS_SP1)) + SETPC_RELATIVE (i); + JS_POP (); + break; + +/* operand call_method (53) */ +case 53: + /* Fetch the method symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (JS_SP1->u.vbuiltin->info->method_proc) + { + if ((*JS_SP1->u.vbuiltin->info->method_proc) ( + vm, + JS_SP1->u.vbuiltin->info, + JS_SP1->u.vbuiltin->instance_context, j, + &builtin_result, JS_SP2) + == JS_PROPERTY_UNKNOWN) + ERROR ("call_method: unknown method"); + } + else + ERROR ("illegal builtin object for call_method"); + + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + JS_MAYBE_GC (); + } + else if (JS_SP1->type == JS_OBJECT) + { + JSNode method; + + if (js_vm_object_load_property (vm, JS_SP1->u.vobject, j, &method) + == JS_PROPERTY_FOUND) + { + /* The property has been defined in the object. */ + + if (method.type != JS_FUNC) + ERROR ("call_method: unknown method"); + + /* And once again. We must do a subroutine call here. */ + JS_SUBROUTINE_CALL (method.u.vfunction->implementation); + } + else + /* Let our prototype handle this. */ + goto _op_call_method_try_proto; + } + else if (vm->prim[JS_SP1->type]) + { + /* The primitive language types. */ + _op_call_method_try_proto: + JS_SAVE_REGS (); + if ((*vm->prim[JS_SP1->type]->method_proc) (vm, vm->prim[JS_SP1->type], + JS_SP1, j, &builtin_result, + JS_SP2) + == JS_PROPERTY_UNKNOWN) + { + JSNode method; + int result = JS_PROPERTY_UNKNOWN; + + /* Let's see if we can find it from the prototype. */ + if (JS_SP1->type == JS_STRING && JS_SP1->u.vstring->prototype) + result = js_vm_object_load_property (vm, + JS_SP1->u.vstring->prototype, + j, &method); + else if (JS_SP1->type == JS_ARRAY && JS_SP1->u.varray->prototype) + result = js_vm_object_load_property (vm, + JS_SP1->u.varray->prototype, + j, &method); + else if (JS_SP1->type == JS_FUNC && JS_SP1->u.vfunction->prototype) + result + = js_vm_object_load_property (vm, JS_SP1->u.vfunction->prototype, + j, &method); + + if (result == JS_PROPERTY_UNKNOWN || method.type != JS_FUNC) + ERROR ("call_method: unknown method"); + + /* Do the subroutine call. */ + JS_SUBROUTINE_CALL (method.u.vfunction->implementation); + } + else + { + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + JS_MAYBE_GC (); + } + } + else + ERROR ("illegal object for call_method"); + break; + +/* operand jmp (54) */ +case 54: + READ_INT32 (i); + SETPC_RELATIVE (i); + break; + +/* operand jsr (55) */ +case 55: + /* Call the global method. */ + { + JSNode f; + + /* Fetch the function to our local variable. */ + JS_COPY (&f, JS_SP1); + function = &f; + + /* Reset the `this' to null. */ + JS_SP1->type = JS_NULL; + + if (function->type == JS_BUILTIN + && function->u.vbuiltin->info->global_method_proc) + { + JS_SAVE_REGS (); + (*function->u.vbuiltin->info->global_method_proc) ( + vm, + function->u.vbuiltin->info, + function->u.vbuiltin->instance_context, + &builtin_result, + JS_SP2); + + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + } + else if (function->type == JS_FUNC) + { + JS_SUBROUTINE_CALL (function->u.vfunction->implementation); + } + else + { + sprintf (buf, "illegal function object in jsr"); + ERROR (buf); + } + } + break; + +/* operand return (56) */ +case 56: + if (fp->u.iptr == NULL) + /* Return from the global scope. */ + DONE (); + + /* STACKFRAME */ + + /* Check if the stack has been modified by min_args. */ + if (JS_ARGS_FIXP->u.args_fix.delta) + { + unsigned int delta = JS_ARGS_FIXP->u.args_fix.delta; + + /* + * Yes it was. Truncate it back to the state where it was + * before the call. + */ + + memmove (JS_SP1 + delta, JS_SP1, + (fp - JS_SP0 + JS_ARGS_FIXP->u.args_fix.argc) + * sizeof (JSNode)); + + sp += delta; + fp += delta; + } + + /* Set pc to the saved return address. */ +#if 0 + if (fp[-3].type != JS_IPTR) + ERROR ("can't find saved return address"); +#endif + pc = fp[-3].u.iptr; + + { + void *old_fp; + + /* Save old frame pointer. */ +#if 0 + if (fp->type != JS_IPTR) + ERROR ("can't find saved frame pointer"); +#endif + old_fp = fp->u.iptr; + + /* Put return value to its correct location. */ + JS_COPY (fp, JS_SP1); + + /* Restore sp. */ + sp = &fp[-1]; + + /* Restore frame pointer. */ + fp = old_fp; + } + break; + +/* operand typeof (57) */ +case 57: + { + char *typeof_name = ""; /* Initialized to make compiler quiet. */ + + switch (JS_SP1->type) + { + case JS_UNDEFINED: + typeof_name = "undefined"; + break; + + case JS_NULL: + typeof_name = "object"; + break; + + case JS_BOOLEAN: + typeof_name = "boolean"; + break; + + case JS_INTEGER: + case JS_FLOAT: + case JS_NAN: + typeof_name = "number"; + break; + + case JS_STRING: + typeof_name = "string"; + break; + + case JS_ARRAY: + typeof_name = "#array"; + break; + + case JS_OBJECT: + typeof_name = "object"; + break; + + case JS_SYMBOL: + typeof_name = "#symbol"; + break; + + case JS_BUILTIN: + typeof_name = "#builtin"; + break; + + case JS_FUNC: + typeof_name = "function"; + break; + + case JS_IPTR: + typeof_name = "#iptr"; + break; + + case JS_ARGS_FIX: + typeof_name = "#argsfix"; + break; + } + + js_vm_make_static_string (vm, JS_SP1, typeof_name, strlen (typeof_name)); + JS_MAYBE_GC (); + } + break; + +/* operand new (58) */ +case 58: + /* Check object. */ + if (JS_SP1->type == JS_BUILTIN && JS_SP1->u.vbuiltin->info->new_proc) + { + JS_SAVE_REGS (); + (*JS_SP1->u.vbuiltin->info->new_proc) (vm, JS_SP1->u.vbuiltin->info, + JS_SP2, JS_SP1); + + /* Push a dummy return value for the constructor. This is ignored. */ + JS_SP0->type = JS_UNDEFINED; + JS_PUSH (); + } + else if (JS_SP1->type == JS_FUNC) + { + JSObject *obj; + JSNode f; + JSNode prototype; + + /* The prototype is an object. */ + prototype.type = JS_OBJECT; + + /* Create the prototype for the function, if it is not defined. */ + if (JS_SP1->u.vfunction->prototype == NULL) + { + JS_SP1->u.vfunction->prototype = js_vm_object_new (vm); + + /* Set its __proto__ to point to Object's prototype. */ + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property (vm, JS_SP1->u.vfunction->prototype, + vm->syms.s___proto__, &prototype); + } + + /* Allocate a new object and set its prototype. */ + + obj = js_vm_object_new (vm); + + prototype.u.vobject = JS_SP1->u.vfunction->prototype; + js_vm_object_store_property (vm, obj, vm->syms.s___proto__, &prototype); + + /* + * Basicly we do a jsr to the function given in JS_SP1. But first, + * we must set `this' pointer to the correct value. See `jsr' for + * the details. + */ + JS_COPY (&f, JS_SP1); + + /* Replace func with the new object. */ + JS_SP1->type = JS_OBJECT; + JS_SP1->u.vobject = obj; + + JS_SUBROUTINE_CALL (f.u.vfunction->implementation); + } + /* The primitive language types. */ + else if (vm->prim[JS_SP1->type]) + { + JS_SAVE_REGS (); + (*vm->prim[JS_SP1->type]->new_proc) (vm, vm->prim[JS_SP1->type], JS_SP2, + JS_SP1); + JS_PUSH (); + } + else + ERROR ("illegal object for new"); + + JS_MAYBE_GC (); + break; + +/* operand delete_property (59) */ +case 59: + /* Fetch the property symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + /* + * XXX It should be possible to apply delete operand to builtin + * XXX objects. + */ + ERROR ("delete_property: JS_BUILTIN: not implemented yet"); + } + else if (JS_SP1->type == JS_OBJECT) + { + js_vm_object_delete_property (vm, JS_SP1->u.vobject, j); + } + else if (JS_SP1->type == JS_NULL) + { + /* Delete a property from an object in the with-chain. */ + /* WITHCHAIN */ + ERROR ("delete_property: not implemented yet for the with-chain objects"); + } + /* The primitive language types. */ + /* + * XXX Since we can't delete properties from builtins, we can't delete + * XXX them from the primitive language types. + */ + else + ERROR ("illegal object for delete_property"); + + /* The delete operand returns an undefined value. */ + JS_SP1->type = JS_UNDEFINED; + break; + +/* operand delete_array (60) */ +case 60: + if (JS_SP2->type == JS_BUILTIN) + { + ERROR ("delete_array: JS_BUILTIN: not implemented yet"); + } + else if (JS_SP2->type == JS_OBJECT) + { + js_vm_object_delete_array (vm, JS_SP2->u.vobject, JS_SP1); + JS_POP (); + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->type == JS_INTEGER) + { + if (0 <= JS_SP1->u.vinteger + && JS_SP1->u.vinteger < JS_SP2->u.varray->length) + JS_SP2->u.varray->data[JS_SP1->u.vinteger].type = JS_UNDEFINED; + JS_POP (); + } + else + ERROR ("illegal array index in delete_array"); + } + else + ERROR ("illegal object for delete_array"); + + /* The delete operand returns an undefined value. */ + JS_SP1->type = JS_UNDEFINED; + break; + +/* operand locals (61) */ +case 61: + READ_INT16 (i); + if (sp - i - JS_RESERVE_STACK_FOR_FUNCTION < vm->stack) + ERROR ("stack overflow"); + + for (; i > 0; i--) + { + JS_SP0->type = JS_UNDEFINED; + JS_PUSH (); + } + break; + +/* operand min_args (62) */ +case 62: + READ_INT8 (i); + + if (JS_SP1->u.vinteger < i) + { + unsigned int delta = i - JS_SP1->u.vinteger; + unsigned int argc = JS_SP1->u.vinteger; + + memmove (JS_SP1 - delta, JS_SP1, (fp - JS_SP0 + argc) * sizeof (JSNode)); + sp -= delta; + fp -= delta; + + /* Fill up the fix_args slot. */ + JS_ARGS_FIXP->u.args_fix.argc = argc; + JS_ARGS_FIXP->u.args_fix.delta = delta; + + for (; argc < i; argc++) + JS_ARG (argc)->type = JS_UNDEFINED; + } + + JS_POP (); + break; + +/* operand load_nth_arg (63) */ +case 63: + { + int index = JS_SP1->u.vinteger; + JS_COPY (JS_SP1, JS_ARG (index)); + } + break; + +/* operand with_push (64) */ +case 64: + if (JS_SP1->type != JS_OBJECT && JS_SP1->type != JS_BUILTIN) + ERROR ("illegal object for with_push"); + + /* WITHCHAIN */ + + if (JS_WITHPTR->u.iptr == NULL) + { + JSNode *np; + JSUIntAlign *ip = js_vm_alloc (vm, + sizeof (JSUIntAlign) + + sizeof (JSNode)); + *ip = 1; + np = (JSNode *) ((unsigned char *) ip + sizeof (JSUIntAlign)); + + JS_COPY (np, JS_SP1); + JS_WITHPTR->u.iptr = ip; + } + else + { + JSNode *np; + JSUIntAlign *ip = JS_WITHPTR->u.iptr; + JSUIntAlign ui = *ip; + + ip = js_vm_realloc (vm, ip, + sizeof (JSUIntAlign) + + ((ui + 1) * sizeof (JSNode))); + (*ip)++; + np = (JSNode *) ((unsigned char *) ip + sizeof (JSUIntAlign)); + + JS_COPY (&np[ui], JS_SP1); + JS_WITHPTR->u.iptr = ip; + } + + JS_POP (); + break; + +/* operand with_pop (65) */ +case 65: + READ_INT8 (i); + + /* WITHCHAIN */ + + { + JSUIntAlign *ip = JS_WITHPTR->u.iptr; + + if (ip == NULL || *ip < i) + ERROR ("with stack underflow in with_pop"); + + *ip -= i; + } + break; + +/* operand try_push (66) */ +case 66: + READ_INT32 (i); + + { + JSErrorHandlerFrame *frame = js_calloc (vm, 1, sizeof (*frame)); + + frame->next = vm->error_handler; + frame->sp = sp; + frame->fp = fp; + frame->pc = pc; + frame->pc_delta = i; + vm->error_handler = frame; + + if (setjmp (vm->error_handler->error_jmp)) + { + /* Ok, we caught an error. */ + + /* Restore our state. */ + sp = vm->error_handler->sp; + fp = vm->error_handler->fp; + pc = vm->error_handler->pc; + i = vm->error_handler->pc_delta; + + /* Push the thrown value to the stack. */ + JS_COPY (JS_SP0, &vm->error_handler->thrown); + JS_PUSH (); + + /* Remove this handler frame. */ + frame = vm->error_handler; + vm->error_handler = vm->error_handler->next; + js_free (frame); + + /* Do the jump to the catch block. */ + SETPC_RELATIVE (i); + } + } + break; + +/* operand try_pop (67) */ +case 67: + READ_INT8 (i); + + for (; i > 0; i--) + { + JSErrorHandlerFrame *frame = vm->error_handler; + + vm->error_handler = vm->error_handler->next; + js_free (frame); + } + break; + +/* operand throw (68) */ +case 68: + { + JSErrorHandlerFrame *f = vm->error_handler; + + if (f->sp == NULL) + { + JSNode cvt; + int len; + + /* + * We are jumping to the C-toplevel. Convert our thrown value + * to string and store it to the vm->error. + */ + js_vm_to_string (vm, JS_SP1, &cvt); + + len = cvt.u.vstring->len; + if (len + 1 > sizeof (vm->error)) + len = sizeof (vm->error) - 1; + + memcpy (vm->error, cvt.u.vstring->data, len); + vm->error[len] = '\0'; + } + else + JS_COPY (&f->thrown, JS_SP1); + + longjmp (f->error_jmp, 1); + + /* NOTREACHED (I hope). */ + + sprintf (buf, "VM: no valid error handler initialized%s", + JS_HOST_LINE_BREAK); + DbgPrint("%s\n", buf); +#if 0 + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); +#endif + + abort (); + } + break; + +/* operand iffalse_b (69) */ +case 69: + READ_INT32 (i); + if (!JS_SP1->u.vboolean) + SETPC_RELATIVE (i); + JS_POP (); + break; + +/* operand iftrue_b (70) */ +case 70: + READ_INT32 (i); + if (JS_SP1->u.vboolean) + SETPC_RELATIVE (i); + JS_POP (); + break; + +/* operand add_1_i (71) */ +case 71: + JS_SP1->u.vinteger++; + break; + +/* operand add_2_i (72) */ +case 72: + JS_SP1->u.vinteger += 2; + break; + +/* operand load_global_w (73) */ +case 73: + READ_INT32 (j); + { + int found = 0; + + /* Loop over the with chain. */ + /* WITHCHAIN */ + if (JS_WITHPTR->u.iptr) + { + JSUIntAlign *uip = JS_WITHPTR->u.iptr; + JSUIntAlign ui = *uip; + JSNode *wp = (JSNode *) ((unsigned char *) uip + + sizeof (JSUIntAlign)); + + for (i = 0; i < ui; i++) + { + JSNode *w = &wp[i]; + int result = JS_PROPERTY_UNKNOWN; + + if (w->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (w->u.vbuiltin->info->property_proc) + result = (*w->u.vbuiltin->info->property_proc) ( + vm, + w->u.vbuiltin->info, + w->u.vbuiltin->instance_context, + j, 0, &builtin_result); + } + else if (w->type == JS_OBJECT) + { + result = js_vm_object_load_property (vm, w->u.vobject, j, + &builtin_result); + } + else + ERROR ("corrupted with-chain in load_global"); + + if (result == JS_PROPERTY_FOUND) + { + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + found = 1; + break; + } + } + } + + if (!found) + { + /* Use the global value. */ + JS_COPY (JS_SP0, JS_GLOBAL (j)); + JS_PUSH (); + + if (vm->warn_undef && JS_SP1->type == JS_UNDEFINED) + { + sprintf (buf, "VM: warning: using undefined global `%s'%s", + js_vm_symname (vm, j), JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + } + } + break; + +/* operand jsr_w (74) */ +case 74: + /* Read the subroutine symbol index. */ + READ_INT32 (j); + + { + int found = 0; + + /* Loop over the with-chain. */ + /* WITHCHAIN */ + if (JS_WITHPTR->u.iptr) + { + JSUIntAlign *uip = JS_WITHPTR->u.iptr; + JSUIntAlign ui = *uip; + JSNode *wp = (JSNode *) ((unsigned char *) uip + + sizeof (JSUIntAlign)); + + for (i = 0; i < ui; i++) + { + JSNode *w = &wp[i]; + int result = JS_PROPERTY_UNKNOWN; + + if (w->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (w->u.vbuiltin->info->method_proc) + result = (*w->u.vbuiltin->info->method_proc) ( + vm, + w->u.vbuiltin->info, + w->u.vbuiltin->instance_context, j, + &builtin_result, JS_SP2); + JS_MAYBE_GC (); + + if (result == JS_PROPERTY_FOUND) + { + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + } + } + else if (w->type == JS_OBJECT) + { + JSNode method; + + js_vm_object_load_property (vm, w->u.vobject, j, &method); + if (method.type == JS_FUNC) + { + result = JS_PROPERTY_FOUND; + + /* The object defines the method. Do a subroutine call. */ + + /* First: replace the null `this' with `w'. */ + JS_COPY (JS_SP1, w); + + /* Then, do the normal subroutine call. */ + JS_SUBROUTINE_CALL (method.u.vfunction->implementation); + } + } + else + ERROR ("corrupted with-chain in jsr_w"); + + if (result == JS_PROPERTY_FOUND) + { + found = 1; + break; + } + } + } + + if (!found) + { + JSNode f; + + /* Call the global method. */ + JS_COPY (&f, JS_SP1); + function = &f; + + /* Reset the `this' to null. */ + JS_SP1->type = JS_NULL; + + if (function->type == JS_BUILTIN + && function->u.vbuiltin->info->global_method_proc) + { + JS_SAVE_REGS (); + (*function->u.vbuiltin->info->global_method_proc) ( + vm, + function->u.vbuiltin->info, + function->u.vbuiltin->instance_context, + &builtin_result, + JS_SP2); + + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + } + else if (function->type == JS_FUNC) + { + JS_SUBROUTINE_CALL (function->u.vfunction->implementation); + } + else + { + sprintf (buf, "symbol `%s' is undefined as function", + js_vm_symname (vm, j)); + ERROR (buf); + } + } + } + break; + diff --git a/reactos/lib/kjs/ksrc/eswt0.h b/reactos/lib/kjs/ksrc/eswt0.h new file mode 100644 index 00000000000..df96c6f7207 --- /dev/null +++ b/reactos/lib/kjs/ksrc/eswt0.h @@ -0,0 +1,2169 @@ +/* operand halt (0) */ +case 0: + sprintf (buf, "VM: halt%s", JS_HOST_LINE_BREAK); + DbgPrint("%s\n", buf); +#if 0 + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); + + while (1) + sleep (5); +#endif + break; + +/* operand done (1) */ +case 1: + DONE (); + break; + +/* operand nop (2) */ +case 2: + /* Nothing here! */ + break; + +/* operand dup (3) */ +case 3: + JS_COPY (JS_SP0, JS_SP1); + JS_PUSH (); + break; + +/* operand pop (4) */ +case 4: + JS_POP (); + break; + +/* operand pop_n (5) */ +case 5: + READ_INT8 (i); + JS_POP_N (i); + break; + +/* operand apop (6) */ +case 6: + READ_INT8 (i); + JS_COPY (JS_SP (i + 1), JS_SP1); + JS_POP_N (i); + break; + +/* operand swap (7) */ +case 7: + JS_COPY (JS_SP0, JS_SP2); + JS_COPY (JS_SP2, JS_SP1); + JS_COPY (JS_SP1, JS_SP0); + break; + +/* operand roll (8) */ +case 8: + READ_INT8 (i8); + + if (i8 > 1) + { + int j; + + for (j = 0; j < i8; j++) + JS_COPY (JS_SP (j), JS_SP (j + 1)); + + JS_COPY (JS_SP (i8), JS_SP0); + } + else if (i8 < -1) + { + i8 = -i8; + + JS_COPY (JS_SP0, JS_SP (i8)); + for (; i8 > 0; i8--) + JS_COPY (JS_SP (i8), JS_SP (i8 - 1)); + } + break; + +/* operand const (9) */ +case 9: + READ_INT32 (i); + JS_COPY (JS_SP0, JS_CONST (i)); + JS_PUSH (); + break; + +/* operand const_null (10) */ +case 10: + JS_SP0->type = JS_NULL; + JS_PUSH (); + break; + +/* operand const_true (11) */ +case 11: + JS_SP0->type = JS_BOOLEAN; + JS_SP0->u.vboolean = 1; + JS_PUSH (); + break; + +/* operand const_false (12) */ +case 12: + JS_SP0->type = JS_BOOLEAN; + JS_SP0->u.vboolean = 0; + JS_PUSH (); + break; + +/* operand const_undefined (13) */ +case 13: + JS_SP0->type = JS_UNDEFINED; + JS_PUSH (); + break; + +/* operand const_i0 (14) */ +case 14: + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 0; + JS_PUSH (); + break; + +/* operand const_i1 (15) */ +case 15: + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 1; + JS_PUSH (); + break; + +/* operand const_i2 (16) */ +case 16: + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 2; + JS_PUSH (); + break; + +/* operand const_i3 (17) */ +case 17: + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 3; + JS_PUSH (); + break; + +/* operand const_i (18) */ +case 18: + READ_INT32 (i); + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = i; + JS_PUSH (); + break; + +/* operand load_global (19) */ +case 19: + READ_INT32 (j); + + /* Use the global value only. */ + JS_COPY (JS_SP0, JS_GLOBAL (j)); + JS_PUSH (); + + if (vm->warn_undef && JS_SP1->type == JS_UNDEFINED) + { + sprintf (buf, "VM: warning: using undefined global `%s'%s", + js_vm_symname (vm, j), JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + break; + +/* operand store_global (20) */ +case 20: + READ_INT32 (i); + + /* Operand store_global do not check the with-chain. */ + /* WITHCHAIN */ + + /* Set the global value. */ + JS_COPY (JS_GLOBAL (i), JS_SP1); + JS_POP (); + break; + +/* operand load_arg (21) */ +case 21: + READ_INT8 (i); + JS_COPY (JS_SP0, JS_ARG (i)); + JS_PUSH (); + break; + +/* operand store_arg (22) */ +case 22: + READ_INT8 (i); + JS_COPY (JS_ARG (i), JS_SP1); + JS_POP (); + break; + +/* operand load_local (23) */ +case 23: + READ_INT16 (i); + JS_COPY (JS_SP0, JS_LOCAL (i)); + JS_PUSH (); + break; + +/* operand store_local (24) */ +case 24: + READ_INT16 (i); + JS_COPY (JS_LOCAL (i), JS_SP1); + JS_POP (); + break; + +/* operand load_property (25) */ +case 25: + /* Fetch the property symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (JS_SP1->u.vbuiltin->info->property_proc) + { + if ((*JS_SP1->u.vbuiltin->info->property_proc) ( + vm, + JS_SP1->u.vbuiltin->info, + JS_SP1->u.vbuiltin->instance_context, + j, 0, &builtin_result) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Looking up the prototype. */ + + builtin_result.type = JS_OBJECT; + if (JS_SP1->u.vbuiltin->prototype) + /* This is an instance. */ + builtin_result.u.vobject = JS_SP1->u.vbuiltin->prototype; + else + /* This is a class. */ + builtin_result.u.vobject + = JS_SP1->u.vbuiltin->info->prototype; + } + else + { + /* Looking up stuffs from the prototype. */ + + if (JS_SP1->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_load_property (vm, + JS_SP1->u.vbuiltin->prototype, + j, &builtin_result); + else + /* A class. */ + js_vm_object_load_property ( + vm, + JS_SP1->u.vbuiltin->info->prototype, + j, &builtin_result); + } + } + JS_COPY (JS_SP1, &builtin_result); + } + else + ERROR ("illegal builtin object for load_property"); + } + else if (JS_SP1->type == JS_OBJECT) + { + js_vm_object_load_property (vm, JS_SP1->u.vobject, j, JS_SP1); + } + else if (vm->prim[JS_SP1->type]) + { + /* The primitive language types. */ + JS_SAVE_REGS (); + if ((*vm->prim[JS_SP1->type]->property_proc) (vm, vm->prim[JS_SP1->type], + JS_SP1, j, 0, + &builtin_result) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Looking up the prototype. */ + switch (JS_SP1->type) + { + case JS_STRING: + if (JS_SP1->u.vstring->prototype) + { + builtin_result.type = JS_OBJECT; + builtin_result.u.vobject = JS_SP1->u.vstring->prototype; + } + else + /* No prototype yet. */ + builtin_result.type = JS_NULL; + break; + + case JS_ARRAY: + if (JS_SP1->u.varray->prototype) + { + builtin_result.type = JS_OBJECT; + builtin_result.u.vobject = JS_SP1->u.varray->prototype; + } + else + /* No prototype yet. */ + builtin_result.type = JS_NULL; + break; + + case JS_FUNC: + if (JS_SP1->u.vfunction->prototype) + { + builtin_result.type = JS_OBJECT; + builtin_result.u.vobject + = JS_SP1->u.vfunction->prototype; + } + else + /* No prototype yet. */ + builtin_result.type = JS_NULL; + break; + + default: + /* The rest do not have prototype. */ + builtin_result.type = JS_NULL; + break; + } + } + else + { + /* Looking up stuffs from the prototype. */ + switch (JS_SP1->type) + { + case JS_STRING: + if (JS_SP1->u.vstring->prototype) + js_vm_object_load_property (vm, + JS_SP1->u.vstring->prototype, + j, &builtin_result); + else + /* Take it from the class' prototype */ + goto _op_load_property_try_proto; + break; + + case JS_ARRAY: + if (JS_SP1->u.varray->prototype) + js_vm_object_load_property (vm, + JS_SP1->u.varray->prototype, + j, &builtin_result); + else + /* Take it from the class' prototype */ + goto _op_load_property_try_proto; + break; + + case JS_FUNC: + if (JS_SP1->u.vfunction->prototype) + js_vm_object_load_property (vm, + JS_SP1->u.vfunction->prototype, + j, &builtin_result); + else + /* Take it from the class' prototype */ + goto _op_load_property_try_proto; + break; + + default: + /* + * The rest do not have instance prototypes; use the + * class prototypes. + */ + _op_load_property_try_proto: + js_vm_object_load_property ( + vm, + vm->prim[JS_SP1->type]->prototype, j, + &builtin_result); + break; + } + } + } + + JS_COPY (JS_SP1, &builtin_result); + } + else + ERROR ("illegal object for load_property"); + break; + +/* operand store_property (26) */ +case 26: + /* Fetch the property symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (JS_SP1->u.vbuiltin->info->property_proc) + { + if ((*JS_SP1->u.vbuiltin->info->property_proc) ( + vm, + JS_SP1->u.vbuiltin->info, + JS_SP1->u.vbuiltin->instance_context, + j, 1, JS_SP2) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Setting the prototype. */ + if (JS_SP2->type != JS_OBJECT) + ERROR ("illegal value for set_property"); + + if (JS_SP1->u.vbuiltin->prototype) + /* Setting the instance's prototype. */ + JS_SP1->u.vbuiltin->prototype = JS_SP2->u.vobject; + else + /* Setting the class' prototype. */ + JS_SP1->u.vbuiltin->info->prototype = JS_SP2->u.vobject; + } + else + { + /* Setting stuff to the prototype. */ + if (JS_SP1->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_store_property (vm, + JS_SP1->u.vbuiltin->prototype, + j, JS_SP2); + else + /* A class. */ + js_vm_object_store_property ( + vm, + JS_SP1->u.vbuiltin->info->prototype, + j, JS_SP2); + } + } + } + else + ERROR ("illegal builtin object for store_property"); + + JS_POP (); + JS_POP (); + } + else if (JS_SP1->type == JS_OBJECT) + { + js_vm_object_store_property (vm, JS_SP1->u.vobject, j, JS_SP2); + JS_POP (); + JS_POP (); + } + else if (vm->prim[JS_SP1->type]) + { + /* The primitive language types. */ + JS_SAVE_REGS (); + if ((*vm->prim[JS_SP1->type]->property_proc) (vm, vm->prim[JS_SP1->type], + JS_SP1, j, 1, JS_SP2) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Setting the prototype. */ + if (JS_SP2->type != JS_OBJECT) + ERROR ("illegal value for set_property"); + + switch (JS_SP1->type) + { + case JS_STRING: + JS_SP1->u.vstring->prototype = JS_SP2->u.vobject; + break; + + case JS_ARRAY: + JS_SP1->u.varray->prototype = JS_SP2->u.vobject; + break; + + case JS_FUNC: + JS_SP1->u.vfunction->prototype = JS_SP2->u.vobject; + break; + + default: + ERROR ("illegal object for set_property"); + break; + } + } + else + { + JSNode prototype; + + /* Setting to the prototype. We create them on demand. */ + switch (JS_SP1->type) + { + case JS_STRING: + if (JS_SP1->u.vstring->prototype == NULL) + { + prototype.type = JS_OBJECT; + + /* Create the prototype and set its __proto__. */ + JS_SP1->u.vstring->prototype = js_vm_object_new (vm); + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property ( + vm, + JS_SP1->u.vstring->prototype, + vm->syms.s___proto__, + &prototype); + } + js_vm_object_store_property (vm, + JS_SP1->u.vstring->prototype, + j, JS_SP2); + break; + + case JS_ARRAY: + if (JS_SP1->u.varray->prototype == NULL) + { + prototype.type = JS_OBJECT; + + /* Create the prototype and set its __proto__. */ + JS_SP1->u.varray->prototype = js_vm_object_new (vm); + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property ( + vm, + JS_SP1->u.varray->prototype, + vm->syms.s___proto__, + &prototype); + } + js_vm_object_store_property (vm, + JS_SP1->u.varray->prototype, + j, JS_SP2); + break; + + case JS_FUNC: + if (JS_SP1->u.vfunction->prototype == NULL) + { + prototype.type = JS_OBJECT; + + /* Create the prototype and set its __proto__. */ + JS_SP1->u.vfunction->prototype = js_vm_object_new (vm); + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property ( + vm, + JS_SP1->u.vfunction->prototype, + vm->syms.s___proto__, + &prototype); + } + js_vm_object_store_property (vm, + JS_SP1->u.vfunction->prototype, + j, JS_SP2); + break; + + default: + ERROR ("illegal object for set_property"); + break; + } + } + } + JS_POP (); + JS_POP (); + } + else + ERROR ("illegal object for store_property"); + + JS_MAYBE_GC (); + break; + +/* operand load_array (27) */ +case 27: + if (JS_SP2->type == JS_BUILTIN) + { + if (JS_SP1->type == JS_INTEGER) + { + ERROR ("integer indexes not implemented yet for BUILTIN in load_array"); + } + else if (JS_SP1->type == JS_STRING) + { + /* Intern the string. */ + j = js_vm_intern_with_len (vm, JS_SP1->u.vstring->data, + JS_SP1->u.vstring->len); + + /* The code below must be in sync with operand `load_property'. */ + JS_SAVE_REGS (); + + if (JS_SP2->u.vbuiltin->info->property_proc) + { + if ((*JS_SP2->u.vbuiltin->info->property_proc) ( + vm, + JS_SP2->u.vbuiltin->info, + JS_SP2->u.vbuiltin->instance_context, + j, 0, &builtin_result) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Looking up the prototype. */ + + builtin_result.type = JS_OBJECT; + if (JS_SP2->u.vbuiltin->prototype) + /* This is an instance. */ + builtin_result.u.vobject + = JS_SP2->u.vbuiltin->prototype; + else + /* This is a class. */ + builtin_result.u.vobject + = JS_SP2->u.vbuiltin->info->prototype; + } + else + { + /* Looking up stuffs from the prototype. */ + + if (JS_SP2->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_load_property ( + vm, + JS_SP2->u.vbuiltin->prototype, + j, &builtin_result); + else + /* A class. */ + js_vm_object_load_property ( + vm, + JS_SP2->u.vbuiltin->info->prototype, + j, &builtin_result); + } + } + JS_COPY (JS_SP2, &builtin_result); + JS_POP (); + } + else + ERROR ("illegal builtin object for load_array"); + } + else + { + sprintf (buf, "illegal array index in load_array (%d)", + JS_SP1->type); + ERROR (buf); + } + } + else if (JS_SP2->type == JS_OBJECT) + { + js_vm_object_load_array (vm, JS_SP2->u.vobject, JS_SP1, JS_SP2); + JS_POP (); + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->type == JS_INTEGER) + { + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.varray->length) + JS_SP2->type = JS_UNDEFINED; + else + { + JSNode *n = &JS_SP2->u.varray->data[JS_SP1->u.vinteger]; + JS_COPY (JS_SP2, n); + } + JS_POP (); + } + else + { + sprintf (buf, "illegal array index in load_array (%d)", + JS_SP1->type); + ERROR (buf); + } + } + else if (JS_SP2->type == JS_STRING) + { + if (JS_SP1->type == JS_INTEGER) + { + int ch; + + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.vstring->len) + ERROR ("string index out of range in load_array"); + + ch = JS_SP2->u.vstring->data[JS_SP1->u.vinteger]; + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = ch; + + JS_POP (); + } + else + ERROR ("illegal string index in load_array"); + } + else + ERROR ("illegal object for load_array"); + break; + +/* operand store_array (28) */ +case 28: + if (JS_SP2->type == JS_BUILTIN) + { + if (JS_SP1->type == JS_INTEGER) + { + ERROR ("integer index not implemented yet for BUILTIN in store_array"); + } + else if (JS_SP1->type == JS_STRING) + { + /* Intern the string. */ + j = js_vm_intern_with_len (vm, JS_SP1->u.vstring->data, + JS_SP1->u.vstring->len); + + /* The code below msut be in sync with operand `store_property'. */ + JS_SAVE_REGS (); + if (JS_SP2->u.vbuiltin->info->property_proc) + { + if ((*JS_SP2->u.vbuiltin->info->property_proc) ( + vm, + JS_SP2->u.vbuiltin->info, + JS_SP2->u.vbuiltin->instance_context, + j, 1, JS_SP (3)) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Setting the prototype. */ + if (JS_SP (3)->type != JS_OBJECT) + ERROR ("illegal value for prototype"); + + if (JS_SP2->u.vbuiltin->prototype) + /* Setting the instance's prototype. */ + JS_SP2->u.vbuiltin->prototype = JS_SP (3)->u.vobject; + else + /* Setting the class' prototype. */ + JS_SP2->u.vbuiltin->info->prototype + = JS_SP (3)->u.vobject; + } + else + { + /* Setting stuff to the prototype. */ + if (JS_SP2->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_store_property ( + vm, + JS_SP2->u.vbuiltin->prototype, + j, JS_SP (3)); + else + /* A class. */ + js_vm_object_store_property ( + vm, + JS_SP2->u.vbuiltin->info->prototype, + j, JS_SP (3)); + } + } + } + else + ERROR ("illegal builtin object for store_array"); + + JS_POP_N (3); + } + else + ERROR ("illegal array index in store_array"); + } + else if (JS_SP2->type == JS_OBJECT) + { + js_vm_object_store_array (vm, JS_SP2->u.vobject, JS_SP1, JS_SP (3)); + JS_POP_N (3); + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->type == JS_INTEGER) + { + if (JS_SP1->u.vinteger < 0) + ERROR ("negative array index in store_array"); + if (JS_SP1->u.vinteger >= JS_SP2->u.varray->length) + js_vm_expand_array (vm, JS_SP2, JS_SP1->u.vinteger + 1); + + JS_COPY (&JS_SP2->u.varray->data[JS_SP1->u.vinteger], JS_SP (3)); + JS_POP_N (3); + } + else + ERROR ("illegal array index in store_array"); + } + else if (JS_SP2->type == JS_STRING) + { + if (JS_SP1->type == JS_INTEGER) + { + if (JS_SP2->u.vstring->staticp) + ERROR ("static string in store_array"); + + if (JS_SP1->u.vinteger < 0) + ERROR ("negative string index in store_array"); + + if (JS_SP (3)->type != JS_INTEGER) + ERROR ("non-integer value to store into string in store_array"); + + if (JS_SP1->u.vinteger >= JS_SP2->u.vstring->len) + { + /* Expand the string. */ + JS_SP2->u.vstring->data = js_vm_realloc (vm, + JS_SP2->u.vstring->data, + JS_SP1->u.vinteger + 1); + /* Fill the gap with ' '. */ + for (; JS_SP2->u.vstring->len <= JS_SP1->u.vinteger;) + JS_SP2->u.vstring->data[JS_SP2->u.vstring->len++] = ' '; + } + + JS_SP2->u.vstring->data[JS_SP1->u.vinteger] + = (unsigned char) JS_SP (3)->u.vinteger; + JS_POP_N (3); + } + else + ERROR ("illegal string index in store_array"); + } + else + ERROR ("illegal object for store_array"); + + JS_MAYBE_GC (); + break; + +/* operand nth (29) */ +case 29: + if (JS_SP2->type == JS_STRING) + { + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.vstring->len) + { + JS_SP2->type = JS_UNDEFINED; + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 0; + } + else + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = JS_SP2->u.vstring->data[JS_SP1->u.vinteger]; + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 1; + } + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.varray->length) + { + JS_SP2->type = JS_UNDEFINED; + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 0; + } + else + { + JSNode *n = &JS_SP2->u.varray->data[JS_SP1->u.vinteger]; + JS_COPY (JS_SP2, n); + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 1; + } + } + else if (JS_SP2->type == JS_OBJECT) + { + i = js_vm_object_nth (vm, JS_SP2->u.vobject, JS_SP1->u.vinteger, JS_SP2); + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = i; + } + else + ERROR ("illegal object for nth"); + break; + +/* operand cmp_eq (30) */ +case 30: + JS_OPERAND_CMP_EQ (==, 1); + break; + +/* operand cmp_ne (31) */ +case 31: + JS_OPERAND_CMP_EQ (!=, 0); + break; + +/* operand cmp_lt (32) */ +case 32: + JS_OPERAND_CMP_REL (<); + break; + +/* operand cmp_gt (33) */ +case 33: + JS_OPERAND_CMP_REL (>); + break; + +/* operand cmp_le (34) */ +case 34: + JS_OPERAND_CMP_REL (<=); + break; + +/* operand cmp_ge (35) */ +case 35: + JS_OPERAND_CMP_REL (>=); + break; + +/* operand cmp_seq (36) */ +case 36: + JS_OPERAND_CMP_SEQ (==, 1); + break; + +/* operand cmp_sne (37) */ +case 37: + JS_OPERAND_CMP_SEQ (!=, 0); + break; + +/* operand sub (38) */ +case 38: + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger -= JS_SP1->u.vinteger; + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (l->type == JS_INTEGER) + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger - r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = (double) l->u.vinteger - r->u.vfloat; + } + } + else + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat - (double) r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat - r->u.vfloat; + } + } + } + + JS_POP (); + break; + +/* operand add (39) */ +case 39: + if (JS_SP2->type == JS_STRING || JS_SP1->type == JS_STRING) + { + unsigned char *d2, *d1, *ndata; + unsigned int d2_len, d1_len, nlen; + JSNode cvt; + + if (JS_SP2->type == JS_STRING) + { + d2 = JS_SP2->u.vstring->data; + d2_len = JS_SP2->u.vstring->len; + } + else + { + js_vm_to_string (vm, JS_SP2, &cvt); + d2 = cvt.u.vstring->data; + d2_len = cvt.u.vstring->len; + } + if (JS_SP1->type == JS_STRING) + { + d1 = JS_SP1->u.vstring->data; + d1_len = JS_SP1->u.vstring->len; + } + else + { + js_vm_to_string (vm, JS_SP1, &cvt); + d1 = cvt.u.vstring->data; + d1_len = cvt.u.vstring->len; + } + + nlen = d2_len + d1_len; + ndata = js_vm_alloc (vm, nlen); + memcpy (ndata, d2, d2_len); + memcpy (ndata + d2_len, d1, d1_len); + + js_vm_make_static_string (vm, JS_SP2, ndata, nlen); + JS_SP2->u.vstring->staticp = 0; + JS_POP (); + JS_MAYBE_GC (); + } + else if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger += JS_SP1->u.vinteger; + JS_POP (); + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (l->type == JS_INTEGER) + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger + r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = (double) l->u.vinteger + r->u.vfloat; + } + } + else + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat + (double) r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat + r->u.vfloat; + } + } + + JS_POP (); + } + break; + +/* operand mul (40) */ +case 40: + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger *= JS_SP1->u.vinteger; + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (l->type == JS_INTEGER) + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger * r->u.vinteger; + } + else + { + if (l->u.vinteger == 0 + && (JS_IS_POSITIVE_INFINITY (r) + || JS_IS_NEGATIVE_INFINITY (r))) + JS_SP2->type = JS_NAN; + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = (double) l->u.vinteger * r->u.vfloat; + } + } + } + else + { + if ((JS_IS_POSITIVE_INFINITY (l) || JS_IS_NEGATIVE_INFINITY (l)) + && ((r->type == JS_INTEGER && r->u.vinteger == 0) + || (r->type == JS_FLOAT && r->u.vfloat == 0.0))) + JS_SP2->type = JS_NAN; + else + { + JS_SP2->type = JS_FLOAT; + + if (r->type == JS_INTEGER) + JS_SP2->u.vfloat = l->u.vfloat * (double) r->u.vinteger; + else + JS_SP2->u.vfloat = l->u.vfloat * r->u.vfloat; + } + } + } + + JS_POP (); + break; + +/* operand div (41) */ +case 41: + { + int nan = 0; + double l, r; + int l_inf = 0; + int r_inf = 0; + JSNode *n; + JSNode cvt; + + /* Convert divident to float. */ + if (JS_IS_NUMBER (JS_SP2)) + n = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &cvt); + n = &cvt; + } + + switch (n->type) + { + case JS_INTEGER: + l = (double) n->u.vinteger; + break; + + case JS_FLOAT: + l = n->u.vfloat; + if (JS_IS_POSITIVE_INFINITY (n) || JS_IS_NEGATIVE_INFINITY (n)) + l_inf = 1; + break; + + case JS_NAN: + default: + nan = 1; + break; + } + + /* Convert divisor to float. */ + if (JS_IS_NUMBER (JS_SP1)) + n = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP2, &cvt); + n = &cvt; + } + + switch (n->type) + { + case JS_INTEGER: + r = (double) n->u.vinteger; + break; + + case JS_FLOAT: + r = n->u.vfloat; + if (JS_IS_POSITIVE_INFINITY (n) || JS_IS_NEGATIVE_INFINITY (n)) + r_inf = 1; + break; + + case JS_NAN: + default: + nan = 1; + break; + } + + /* Do the division. */ + JS_POP (); + if (nan || (l_inf && r_inf)) + JS_SP1->type = JS_NAN; + else + { + if (l_inf && r == 0.0) + { + /* is already an infinity. */ + JS_SP1->type = JS_FLOAT; + JS_SP1->u.vfloat = l; + } + else if (l == 0.0 && r == 0.0) + JS_SP1->type = JS_NAN; + else + { + JS_SP1->type = JS_FLOAT; + JS_SP1->u.vfloat = l / r; + } + } + } + break; + +/* operand mod (42) */ +case 42: + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + if (JS_SP1->u.vinteger == 0) + JS_SP2->type = JS_NAN; + else + JS_SP2->u.vinteger %= JS_SP1->u.vinteger; + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (JS_IS_POSITIVE_INFINITY (l) + || JS_IS_NEGATIVE_INFINITY (l) + || ((r->type == JS_INTEGER && r->u.vinteger == 0) + || (r->type == JS_FLOAT && r->u.vfloat == 0.0))) + JS_SP2->type = JS_NAN; + else if (JS_IS_POSITIVE_INFINITY (r) + || JS_IS_NEGATIVE_INFINITY (r)) + JS_COPY (JS_SP2, l); + else if ((l->type == JS_INTEGER && l->u.vinteger == 0) + || (l->type == JS_FLOAT && l->u.vfloat == 0.0)) + JS_COPY (JS_SP2, l); + else + { + if (l->type == JS_INTEGER && r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger % r->u.vinteger; + } + else + { + double ld, rd; + int full; + + if (l->type == JS_INTEGER) + ld = (double) l->u.vinteger; + else + ld = l->u.vfloat; + + if (r->type == JS_INTEGER) + rd = (double) r->u.vinteger; + else + rd = r->u.vfloat; + + full = ld / rd; + + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = ld - (full * rd); + } + } + } + + JS_POP (); + break; + +/* operand neg (43) */ +case 43: + if (JS_SP1->type == JS_INTEGER) + JS_SP1->u.vinteger = -JS_SP1->u.vinteger; + else if (JS_SP1->type == JS_FLOAT) + JS_SP1->u.vfloat = -JS_SP1->u.vfloat; + else if (JS_SP1->type == JS_NAN) + ; + else + { + JSNode cvt; + + js_vm_to_number (vm, JS_SP1, &cvt); + + JS_SP1->type = cvt.type; + switch (cvt.type) + { + case JS_INTEGER: + JS_SP1->u.vinteger = -cvt.u.vinteger; + break; + + case JS_FLOAT: + JS_SP1->u.vfloat = -cvt.u.vfloat; + break; + + case JS_NAN: + default: + /* Nothing here. */ + break; + } + } + break; + +/* operand and (44) */ +case 44: + JS_OPERAND_BINARY (&); + break; + +/* operand not (45) */ +case 45: + JS_SP1->u.vboolean = JS_IS_FALSE (JS_SP1); + JS_SP1->type = JS_BOOLEAN; + break; + +/* operand or (46) */ +case 46: + JS_OPERAND_BINARY (|); + break; + +/* operand xor (47) */ +case 47: + JS_OPERAND_BINARY (^); + break; + +/* operand shift_left (48) */ +case 48: + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger = ((JSInt32) JS_SP2->u.vinteger + << (JSUInt32) JS_SP1->u.vinteger); + JS_POP (); + } + else + { + JSInt32 l; + JSUInt32 r; + + l = js_vm_to_int32 (vm, JS_SP2); + r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1); + + JS_SP2->u.vinteger = l << r; + JS_SP2->type = JS_INTEGER; + JS_POP (); + } + break; + +/* operand shift_right (49) */ +case 49: + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger = ((JSInt32) JS_SP2->u.vinteger + >> (JSUInt32) JS_SP1->u.vinteger); + JS_POP (); + } + else + { + JSInt32 l; + JSUInt32 r; + + l = js_vm_to_int32 (vm, JS_SP2); + r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1); + + JS_SP2->u.vinteger = l >> r; + JS_SP2->type = JS_INTEGER; + JS_POP (); + } + break; + +/* operand shift_rright (50) */ +case 50: + { + JSInt32 l; + JSUInt32 r; + + l = js_vm_to_int32 (vm, JS_SP2); + r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1); + + if (r > 0) + JS_SP2->u.vinteger = (l & 0x7fffffff) >> r; + else + JS_SP2->u.vinteger = l; + + JS_SP2->type = JS_INTEGER; + JS_POP (); + } + break; + +/* operand iffalse (51) */ +case 51: + READ_INT32 (i); + if (JS_IS_FALSE (JS_SP1)) + SETPC_RELATIVE (i); + JS_POP (); + break; + +/* operand iftrue (52) */ +case 52: + READ_INT32 (i); + if (JS_IS_TRUE (JS_SP1)) + SETPC_RELATIVE (i); + JS_POP (); + break; + +/* operand call_method (53) */ +case 53: + /* Fetch the method symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (JS_SP1->u.vbuiltin->info->method_proc) + { + if ((*JS_SP1->u.vbuiltin->info->method_proc) ( + vm, + JS_SP1->u.vbuiltin->info, + JS_SP1->u.vbuiltin->instance_context, j, + &builtin_result, JS_SP2) + == JS_PROPERTY_UNKNOWN) + ERROR ("call_method: unknown method"); + } + else + ERROR ("illegal builtin object for call_method"); + + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + JS_MAYBE_GC (); + } + else if (JS_SP1->type == JS_OBJECT) + { + JSNode method; + + if (js_vm_object_load_property (vm, JS_SP1->u.vobject, j, &method) + == JS_PROPERTY_FOUND) + { + /* The property has been defined in the object. */ + + if (method.type != JS_FUNC) + ERROR ("call_method: unknown method"); + + /* And once again. We must do a subroutine call here. */ + JS_SUBROUTINE_CALL (method.u.vfunction->implementation); + } + else + /* Let our prototype handle this. */ + goto _op_call_method_try_proto; + } + else if (vm->prim[JS_SP1->type]) + { + /* The primitive language types. */ + _op_call_method_try_proto: + JS_SAVE_REGS (); + if ((*vm->prim[JS_SP1->type]->method_proc) (vm, vm->prim[JS_SP1->type], + JS_SP1, j, &builtin_result, + JS_SP2) + == JS_PROPERTY_UNKNOWN) + { + JSNode method; + int result = JS_PROPERTY_UNKNOWN; + + /* Let's see if we can find it from the prototype. */ + if (JS_SP1->type == JS_STRING && JS_SP1->u.vstring->prototype) + result = js_vm_object_load_property (vm, + JS_SP1->u.vstring->prototype, + j, &method); + else if (JS_SP1->type == JS_ARRAY && JS_SP1->u.varray->prototype) + result = js_vm_object_load_property (vm, + JS_SP1->u.varray->prototype, + j, &method); + else if (JS_SP1->type == JS_FUNC && JS_SP1->u.vfunction->prototype) + result + = js_vm_object_load_property (vm, JS_SP1->u.vfunction->prototype, + j, &method); + + if (result == JS_PROPERTY_UNKNOWN || method.type != JS_FUNC) + ERROR ("call_method: unknown method"); + + /* Do the subroutine call. */ + JS_SUBROUTINE_CALL (method.u.vfunction->implementation); + } + else + { + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + JS_MAYBE_GC (); + } + } + else + ERROR ("illegal object for call_method"); + break; + +/* operand jmp (54) */ +case 54: + READ_INT32 (i); + SETPC_RELATIVE (i); + break; + +/* operand jsr (55) */ +case 55: + /* Call the global method. */ + { + JSNode f; + + /* Fetch the function to our local variable. */ + JS_COPY (&f, JS_SP1); + function = &f; + + /* Reset the `this' to null. */ + JS_SP1->type = JS_NULL; + + if (function->type == JS_BUILTIN + && function->u.vbuiltin->info->global_method_proc) + { + JS_SAVE_REGS (); + (*function->u.vbuiltin->info->global_method_proc) ( + vm, + function->u.vbuiltin->info, + function->u.vbuiltin->instance_context, + &builtin_result, + JS_SP2); + + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + } + else if (function->type == JS_FUNC) + { + JS_SUBROUTINE_CALL (function->u.vfunction->implementation); + } + else + { + sprintf (buf, "illegal function object in jsr"); + ERROR (buf); + } + } + break; + +/* operand return (56) */ +case 56: + if (fp->u.iptr == NULL) + /* Return from the global scope. */ + DONE (); + + /* STACKFRAME */ + + /* Check if the stack has been modified by min_args. */ + if (JS_ARGS_FIXP->u.args_fix.delta) + { + unsigned int delta = JS_ARGS_FIXP->u.args_fix.delta; + + /* + * Yes it was. Truncate it back to the state where it was + * before the call. + */ + + memmove (JS_SP1 + delta, JS_SP1, + (fp - JS_SP0 + JS_ARGS_FIXP->u.args_fix.argc) + * sizeof (JSNode)); + + sp += delta; + fp += delta; + } + + /* Set pc to the saved return address. */ +#if 0 + if (fp[-3].type != JS_IPTR) + ERROR ("can't find saved return address"); +#endif + pc = fp[-3].u.iptr; + + { + void *old_fp; + + /* Save old frame pointer. */ +#if 0 + if (fp->type != JS_IPTR) + ERROR ("can't find saved frame pointer"); +#endif + old_fp = fp->u.iptr; + + /* Put return value to its correct location. */ + JS_COPY (fp, JS_SP1); + + /* Restore sp. */ + sp = &fp[-1]; + + /* Restore frame pointer. */ + fp = old_fp; + } + break; + +/* operand typeof (57) */ +case 57: + { + char *typeof_name = ""; /* Initialized to make compiler quiet. */ + + switch (JS_SP1->type) + { + case JS_UNDEFINED: + typeof_name = "undefined"; + break; + + case JS_NULL: + typeof_name = "object"; + break; + + case JS_BOOLEAN: + typeof_name = "boolean"; + break; + + case JS_INTEGER: + case JS_FLOAT: + case JS_NAN: + typeof_name = "number"; + break; + + case JS_STRING: + typeof_name = "string"; + break; + + case JS_ARRAY: + typeof_name = "#array"; + break; + + case JS_OBJECT: + typeof_name = "object"; + break; + + case JS_SYMBOL: + typeof_name = "#symbol"; + break; + + case JS_BUILTIN: + typeof_name = "#builtin"; + break; + + case JS_FUNC: + typeof_name = "function"; + break; + + case JS_IPTR: + typeof_name = "#iptr"; + break; + + case JS_ARGS_FIX: + typeof_name = "#argsfix"; + break; + } + + js_vm_make_static_string (vm, JS_SP1, typeof_name, strlen (typeof_name)); + JS_MAYBE_GC (); + } + break; + +/* operand new (58) */ +case 58: + /* Check object. */ + if (JS_SP1->type == JS_BUILTIN && JS_SP1->u.vbuiltin->info->new_proc) + { + JS_SAVE_REGS (); + (*JS_SP1->u.vbuiltin->info->new_proc) (vm, JS_SP1->u.vbuiltin->info, + JS_SP2, JS_SP1); + + /* Push a dummy return value for the constructor. This is ignored. */ + JS_SP0->type = JS_UNDEFINED; + JS_PUSH (); + } + else if (JS_SP1->type == JS_FUNC) + { + JSObject *obj; + JSNode f; + JSNode prototype; + + /* The prototype is an object. */ + prototype.type = JS_OBJECT; + + /* Create the prototype for the function, if it is not defined. */ + if (JS_SP1->u.vfunction->prototype == NULL) + { + JS_SP1->u.vfunction->prototype = js_vm_object_new (vm); + + /* Set its __proto__ to point to Object's prototype. */ + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property (vm, JS_SP1->u.vfunction->prototype, + vm->syms.s___proto__, &prototype); + } + + /* Allocate a new object and set its prototype. */ + + obj = js_vm_object_new (vm); + + prototype.u.vobject = JS_SP1->u.vfunction->prototype; + js_vm_object_store_property (vm, obj, vm->syms.s___proto__, &prototype); + + /* + * Basicly we do a jsr to the function given in JS_SP1. But first, + * we must set `this' pointer to the correct value. See `jsr' for + * the details. + */ + JS_COPY (&f, JS_SP1); + + /* Replace func with the new object. */ + JS_SP1->type = JS_OBJECT; + JS_SP1->u.vobject = obj; + + JS_SUBROUTINE_CALL (f.u.vfunction->implementation); + } + /* The primitive language types. */ + else if (vm->prim[JS_SP1->type]) + { + JS_SAVE_REGS (); + (*vm->prim[JS_SP1->type]->new_proc) (vm, vm->prim[JS_SP1->type], JS_SP2, + JS_SP1); + JS_PUSH (); + } + else + ERROR ("illegal object for new"); + + JS_MAYBE_GC (); + break; + +/* operand delete_property (59) */ +case 59: + /* Fetch the property symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + /* + * XXX It should be possible to apply delete operand to builtin + * XXX objects. + */ + ERROR ("delete_property: JS_BUILTIN: not implemented yet"); + } + else if (JS_SP1->type == JS_OBJECT) + { + js_vm_object_delete_property (vm, JS_SP1->u.vobject, j); + } + else if (JS_SP1->type == JS_NULL) + { + /* Delete a property from an object in the with-chain. */ + /* WITHCHAIN */ + ERROR ("delete_property: not implemented yet for the with-chain objects"); + } + /* The primitive language types. */ + /* + * XXX Since we can't delete properties from builtins, we can't delete + * XXX them from the primitive language types. + */ + else + ERROR ("illegal object for delete_property"); + + /* The delete operand returns an undefined value. */ + JS_SP1->type = JS_UNDEFINED; + break; + +/* operand delete_array (60) */ +case 60: + if (JS_SP2->type == JS_BUILTIN) + { + ERROR ("delete_array: JS_BUILTIN: not implemented yet"); + } + else if (JS_SP2->type == JS_OBJECT) + { + js_vm_object_delete_array (vm, JS_SP2->u.vobject, JS_SP1); + JS_POP (); + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->type == JS_INTEGER) + { + if (0 <= JS_SP1->u.vinteger + && JS_SP1->u.vinteger < JS_SP2->u.varray->length) + JS_SP2->u.varray->data[JS_SP1->u.vinteger].type = JS_UNDEFINED; + JS_POP (); + } + else + ERROR ("illegal array index in delete_array"); + } + else + ERROR ("illegal object for delete_array"); + + /* The delete operand returns an undefined value. */ + JS_SP1->type = JS_UNDEFINED; + break; + +/* operand locals (61) */ +case 61: + READ_INT16 (i); + if (sp - i - JS_RESERVE_STACK_FOR_FUNCTION < vm->stack) + ERROR ("stack overflow"); + + for (; i > 0; i--) + { + JS_SP0->type = JS_UNDEFINED; + JS_PUSH (); + } + break; + +/* operand min_args (62) */ +case 62: + READ_INT8 (i); + + if (JS_SP1->u.vinteger < i) + { + unsigned int delta = i - JS_SP1->u.vinteger; + unsigned int argc = JS_SP1->u.vinteger; + + memmove (JS_SP1 - delta, JS_SP1, (fp - JS_SP0 + argc) * sizeof (JSNode)); + sp -= delta; + fp -= delta; + + /* Fill up the fix_args slot. */ + JS_ARGS_FIXP->u.args_fix.argc = argc; + JS_ARGS_FIXP->u.args_fix.delta = delta; + + for (; argc < i; argc++) + JS_ARG (argc)->type = JS_UNDEFINED; + } + + JS_POP (); + break; + +/* operand load_nth_arg (63) */ +case 63: + { + int index = JS_SP1->u.vinteger; + JS_COPY (JS_SP1, JS_ARG (index)); + } + break; + +/* operand with_push (64) */ +case 64: + if (JS_SP1->type != JS_OBJECT && JS_SP1->type != JS_BUILTIN) + ERROR ("illegal object for with_push"); + + /* WITHCHAIN */ + + if (JS_WITHPTR->u.iptr == NULL) + { + JSNode *np; + JSUIntAlign *ip = js_vm_alloc (vm, + sizeof (JSUIntAlign) + + sizeof (JSNode)); + *ip = 1; + np = (JSNode *) ((unsigned char *) ip + sizeof (JSUIntAlign)); + + JS_COPY (np, JS_SP1); + JS_WITHPTR->u.iptr = ip; + } + else + { + JSNode *np; + JSUIntAlign *ip = JS_WITHPTR->u.iptr; + JSUIntAlign ui = *ip; + + ip = js_vm_realloc (vm, ip, + sizeof (JSUIntAlign) + + ((ui + 1) * sizeof (JSNode))); + (*ip)++; + np = (JSNode *) ((unsigned char *) ip + sizeof (JSUIntAlign)); + + JS_COPY (&np[ui], JS_SP1); + JS_WITHPTR->u.iptr = ip; + } + + JS_POP (); + break; + +/* operand with_pop (65) */ +case 65: + READ_INT8 (i); + + /* WITHCHAIN */ + + { + JSUIntAlign *ip = JS_WITHPTR->u.iptr; + + if (ip == NULL || *ip < i) + ERROR ("with stack underflow in with_pop"); + + *ip -= i; + } + break; + +/* operand try_push (66) */ +case 66: + READ_INT32 (i); + + { + JSErrorHandlerFrame *frame = js_calloc (vm, 1, sizeof (*frame)); + + frame->next = vm->error_handler; + frame->sp = sp; + frame->fp = fp; + frame->pc = pc; + frame->pc_delta = i; + vm->error_handler = frame; + + if (setjmp (vm->error_handler->error_jmp)) + { + /* Ok, we caught an error. */ + + /* Restore our state. */ + sp = vm->error_handler->sp; + fp = vm->error_handler->fp; + pc = vm->error_handler->pc; + i = vm->error_handler->pc_delta; + + /* Push the thrown value to the stack. */ + JS_COPY (JS_SP0, &vm->error_handler->thrown); + JS_PUSH (); + + /* Remove this handler frame. */ + frame = vm->error_handler; + vm->error_handler = vm->error_handler->next; + js_free (frame); + + /* Do the jump to the catch block. */ + SETPC_RELATIVE (i); + } + } + break; + +/* operand try_pop (67) */ +case 67: + READ_INT8 (i); + + for (; i > 0; i--) + { + JSErrorHandlerFrame *frame = vm->error_handler; + + vm->error_handler = vm->error_handler->next; + js_free (frame); + } + break; + +/* operand throw (68) */ +case 68: + { + JSErrorHandlerFrame *f = vm->error_handler; + + if (f->sp == NULL) + { + JSNode cvt; + int len; + + /* + * We are jumping to the C-toplevel. Convert our thrown value + * to string and store it to the vm->error. + */ + js_vm_to_string (vm, JS_SP1, &cvt); + + len = cvt.u.vstring->len; + if (len + 1 > sizeof (vm->error)) + len = sizeof (vm->error) - 1; + + memcpy (vm->error, cvt.u.vstring->data, len); + vm->error[len] = '\0'; + } + else + JS_COPY (&f->thrown, JS_SP1); + + longjmp (f->error_jmp, 1); + + /* NOTREACHED (I hope). */ + + sprintf (buf, "VM: no valid error handler initialized%s", + JS_HOST_LINE_BREAK); + DbgPrint("%s\n", buf); +#if 0 + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); +#endif + + abort (); + } + break; + +/* operand iffalse_b (69) */ +case 69: + READ_INT32 (i); + if (!JS_SP1->u.vboolean) + SETPC_RELATIVE (i); + JS_POP (); + break; + +/* operand iftrue_b (70) */ +case 70: + READ_INT32 (i); + if (JS_SP1->u.vboolean) + SETPC_RELATIVE (i); + JS_POP (); + break; + +/* operand add_1_i (71) */ +case 71: + JS_SP1->u.vinteger++; + break; + +/* operand add_2_i (72) */ +case 72: + JS_SP1->u.vinteger += 2; + break; + +/* operand load_global_w (73) */ +case 73: + READ_INT32 (j); + { + int found = 0; + + /* Loop over the with chain. */ + /* WITHCHAIN */ + if (JS_WITHPTR->u.iptr) + { + JSUIntAlign *uip = JS_WITHPTR->u.iptr; + JSUIntAlign ui = *uip; + JSNode *wp = (JSNode *) ((unsigned char *) uip + + sizeof (JSUIntAlign)); + + for (i = 0; i < ui; i++) + { + JSNode *w = &wp[i]; + int result = JS_PROPERTY_UNKNOWN; + + if (w->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (w->u.vbuiltin->info->property_proc) + result = (*w->u.vbuiltin->info->property_proc) ( + vm, + w->u.vbuiltin->info, + w->u.vbuiltin->instance_context, + j, 0, &builtin_result); + } + else if (w->type == JS_OBJECT) + { + result = js_vm_object_load_property (vm, w->u.vobject, j, + &builtin_result); + } + else + ERROR ("corrupted with-chain in load_global"); + + if (result == JS_PROPERTY_FOUND) + { + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + found = 1; + break; + } + } + } + + if (!found) + { + /* Use the global value. */ + JS_COPY (JS_SP0, JS_GLOBAL (j)); + JS_PUSH (); + + if (vm->warn_undef && JS_SP1->type == JS_UNDEFINED) + { + sprintf (buf, "VM: warning: using undefined global `%s'%s", + js_vm_symname (vm, j), JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + } + } + break; + +/* operand jsr_w (74) */ +case 74: + /* Read the subroutine symbol index. */ + READ_INT32 (j); + + { + int found = 0; + + /* Loop over the with-chain. */ + /* WITHCHAIN */ + if (JS_WITHPTR->u.iptr) + { + JSUIntAlign *uip = JS_WITHPTR->u.iptr; + JSUIntAlign ui = *uip; + JSNode *wp = (JSNode *) ((unsigned char *) uip + + sizeof (JSUIntAlign)); + + for (i = 0; i < ui; i++) + { + JSNode *w = &wp[i]; + int result = JS_PROPERTY_UNKNOWN; + + if (w->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (w->u.vbuiltin->info->method_proc) + result = (*w->u.vbuiltin->info->method_proc) ( + vm, + w->u.vbuiltin->info, + w->u.vbuiltin->instance_context, j, + &builtin_result, JS_SP2); + JS_MAYBE_GC (); + + if (result == JS_PROPERTY_FOUND) + { + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + } + } + else if (w->type == JS_OBJECT) + { + JSNode method; + + js_vm_object_load_property (vm, w->u.vobject, j, &method); + if (method.type == JS_FUNC) + { + result = JS_PROPERTY_FOUND; + + /* The object defines the method. Do a subroutine call. */ + + /* First: replace the null `this' with `w'. */ + JS_COPY (JS_SP1, w); + + /* Then, do the normal subroutine call. */ + JS_SUBROUTINE_CALL (method.u.vfunction->implementation); + } + } + else + ERROR ("corrupted with-chain in jsr_w"); + + if (result == JS_PROPERTY_FOUND) + { + found = 1; + break; + } + } + } + + if (!found) + { + JSNode f; + + /* Call the global method. */ + JS_COPY (&f, JS_SP1); + function = &f; + + /* Reset the `this' to null. */ + JS_SP1->type = JS_NULL; + + if (function->type == JS_BUILTIN + && function->u.vbuiltin->info->global_method_proc) + { + JS_SAVE_REGS (); + (*function->u.vbuiltin->info->global_method_proc) ( + vm, + function->u.vbuiltin->info, + function->u.vbuiltin->instance_context, + &builtin_result, + JS_SP2); + + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + } + else if (function->type == JS_FUNC) + { + JS_SUBROUTINE_CALL (function->u.vfunction->implementation); + } + else + { + sprintf (buf, "symbol `%s' is undefined as function", + js_vm_symname (vm, j)); + ERROR (buf); + } + } + } + break; + diff --git a/reactos/lib/kjs/ksrc/iostream.c b/reactos/lib/kjs/ksrc/iostream.c new file mode 100644 index 00000000000..75ed6c17eed --- /dev/null +++ b/reactos/lib/kjs/ksrc/iostream.c @@ -0,0 +1,216 @@ +/* + * I/O streams. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/ksrc/iostream.c,v $ + * $Id: iostream.c,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +#include "jsint.h" + +/* + * Types and definitions. + */ + +#define DEFAULT_BUFFER_SIZE 4096 + +/* + * Global functions. + */ + +JSIOStream * +js_iostream_new () +{ + JSIOStream *stream; + + stream = js_calloc (NULL, 1, sizeof (*stream)); + if (stream == NULL) + return NULL; + + stream->buflen = DEFAULT_BUFFER_SIZE; + stream->buffer = js_malloc (NULL, stream->buflen); + if (stream->buffer == NULL) + { + js_free (stream); + return NULL; + } + + return stream; +} + +size_t +js_iostream_read (JSIOStream *stream, void *ptr, size_t size) +{ + size_t total = 0; + int got; + + if (stream->writep) + { + /* We have buffered output data. */ + if (js_iostream_flush (stream) == EOF) + return 0; + + assert (stream->writep == 0); + } + + while (size > 0) + { + /* First, take everything from the buffer. */ + if (stream->bufpos < stream->data_in_buf) + { + got = stream->data_in_buf - stream->bufpos; + + if (size < got) + got = size; + + memcpy (ptr, stream->buffer + stream->bufpos, got); + + stream->bufpos += got; + size -= got; + (unsigned char *) ptr += got; + total += got; + } + else + { + if (stream->at_eof) + /* EOF seen, can't read more. */ + break; + + js_iostream_fill_buffer (stream); + } + } + + return total; +} + + +size_t +js_iostream_write (JSIOStream *stream, void *ptr, size_t size) +{ + int i; + + for( i = 0; size > i; i++ ) + DbgPrint("%c", ((char *)ptr)[i]); + + return i; +} + + +int +js_iostream_flush (JSIOStream *stream) +{ + return 0; +} + +int +js_iostream_unget (JSIOStream *stream, int byte) +{ + return 0; +} + +int +js_iostream_close (JSIOStream *stream) +{ + int result = 0; + + if (stream == NULL) + return result; + + if (js_iostream_flush (stream) == EOF) + result = EOF; + + if (stream->close) + (*stream->close) (stream->context); + + js_free (stream->buffer); + js_free (stream); + + return result; +} + + +int +js_iostream_seek (JSIOStream *stream, long offset, int whence) +{ + int result; + + if (js_iostream_flush (stream) == EOF) + return -1; + + result = (*stream->seek) (stream->context, offset, whence); + if (result == 0) + /* Successful. Clear the eof flag. */ + stream->at_eof = 0; + + return result; +} + + +long +js_iostream_get_position (JSIOStream *stream) +{ + long pos; + + /* Flush the possible buffered output. */ + if (js_iostream_flush (stream) == EOF) + return -1; + + pos = (*stream->get_position) (stream->context); + if (pos < 0) + return pos; + + /* + * The logical position if at , the context's idea is at + * . Adjust. + */ + return pos - (stream->data_in_buf - stream->bufpos); +} + + +long +js_iostream_get_length (JSIOStream *stream) +{ + /* Flush the possible buffered output. */ + if (js_iostream_flush (stream) == EOF) + return -1; + + return (*stream->get_length) (stream->context); +} + + +void +js_iostream_fill_buffer (JSIOStream *stream) +{ + if (stream->read == NULL) + { + stream->at_eof = 1; + return; + } + + stream->data_in_buf = (*stream->read) (stream->context, stream->buffer, + stream->buflen, &stream->error); + stream->bufpos = 0; + if (stream->data_in_buf == 0) + stream->at_eof = 1; +} diff --git a/reactos/lib/kjs/ksrc/js.c b/reactos/lib/kjs/ksrc/js.c new file mode 100644 index 00000000000..4fc2e5603b3 --- /dev/null +++ b/reactos/lib/kjs/ksrc/js.c @@ -0,0 +1,1472 @@ +/* + * JavaScript interpreter main glue. + * Copyright (c) 1998-1999 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/ksrc/js.c,v $ + * $Id: js.c,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +#include "js.h" +#include "jsint.h" +#include "kjs.h" +#include "ddk/kefuncs.h" + +/* + * Types and definitions. + */ + +/* Context for js_global_method_stub. */ +struct js_global_method_context_st +{ + JSGlobalMethodProc proc; + void *context; + JSFreeProc free_proc; + JSInterpPtr interp; +}; + +typedef struct js_global_method_context_st JSGlobalMethodContext; + +/* Context for user I/O function streams. */ +struct js_user_io_func_ctx_st +{ + JSIOFunc func; + void *context; + long position; +}; + +typedef struct js_user_io_func_ctx_st JSUserIOFuncCtx; + +struct js_method_reg_st +{ + JSSymbol sym; + char *name; + unsigned int flags; + JSMethodProc method; +}; + +typedef struct js_method_reg_st JSMethodReg; + +struct js_property_reg_st +{ + JSSymbol sym; + char *name; + unsigned int flags; + JSPropertyProc property; +}; + +typedef struct js_property_reg_st JSPropertyReg; + +/* The class handle. */ +struct js_class_st +{ + char *name; + JSInterpPtr interp; + + /* Flags. */ + unsigned int no_auto_destroy : 1; + unsigned int interned : 1; + + void *class_context; + JSFreeProc class_context_destructor; + + JSConstructor constructor; + + unsigned int num_methods; + JSMethodReg *methods; + + unsigned int num_properties; + JSPropertyReg *properties; +}; + +/* Object instance context. */ +struct js_object_instance_ctx_st +{ + void *instance_context; + JSFreeProc instance_context_destructor; +}; + +typedef struct js_object_instance_ctx_st JSObjectInstanceCtx; + + +/* + * Prototypes for static functions. + */ + +/* The module for JS' core global methods. */ +static void js_core_globals (JSInterpPtr interp); + +/* + * Helper function to evaluate source with compiler function + * . + */ +static int js_eval_source (JSInterpPtr interp, JSNode *source, + char *compiler_function); + +/* + * Helper function to compile source with compiler function + * . If is not NULL, the + * assembler listing of the compilation is saved to that file. If + * is not NULL, the byte_code data is saved to that + * file. If is not NULL, the resulting byte_code data is + * returned in it as a JavaScript string node. + */ +static int js_compile_source (JSInterpPtr interp, JSNode *source, + char *compiler_function, char *assembler_file, + char *byte_code_file, JSNode *bc_return); + +/* + * The stub function for global methods, created with the + * js_create_global_method() API function. + */ +static void js_global_method_stub (JSVirtualMachine *vm, + JSBuiltinInfo *builtin_info, + void *instance_context, + JSNode *result_return, + JSNode *args); + +/* + * Destructor for the global methods, created with the + * js_create_global_method() API function. + */ +static void js_global_method_delete (JSBuiltinInfo *builtin_info, + void *instance_context); + +static JSIOStream *iostream_iofunc (JSIOFunc func, void *context, + int readp, int writep); + + +/* + * Global functions. + */ + +const JSCharPtr +js_version () +{ + return VERSION; +} + + +void +js_init_default_options (JSInterpOptions *options) +{ + memset (options, 0, sizeof (*options)); + + options->stack_size = 2048; + options->dispatch_method = JS_VM_DISPATCH_JUMPS; + + options->warn_undef = 1; + + options->optimize_peephole = 1; + options->optimize_jumps_to_jumps = 1; + + options->fd_count = (unsigned long) -1; +} + + +JSInterpPtr +js_create_interp (JSInterpOptions *options, PKJS kjs) +{ + JSInterpPtr interp = NULL; + JSByteCode *bc; + JSInterpOptions default_options; + JSIOStream *s_stdin = NULL; + JSIOStream *s_stdout = NULL; + JSIOStream *s_stderr = NULL; + + /* + * Sanity check to assure that the js.h and jsint.h APIs share a + * same view to the world. + */ + assert (sizeof (JSNode) == sizeof (JSType)); + + interp = js_calloc (NULL, 1, sizeof (*interp)); + if (interp == NULL) + return NULL; + + if (options == NULL) + { + js_init_default_options (&default_options); + options = &default_options; + } + + memcpy (&interp->options, options, sizeof (*options)); + + /* The default system streams. */ + + s_stdin = iostream_iofunc (options->s_stdin, options->s_context, 1, 0); + s_stdout = iostream_iofunc (options->s_stdout, options->s_context, 0, 1); + s_stderr = iostream_iofunc (options->s_stderr, options->s_context, 0, 1); + + /* Create virtual machine. */ + interp->vm = js_vm_create (kjs, + options->stack_size, + options->dispatch_method, + options->verbose, + options->stacktrace_on_error, + s_stdin, s_stdout, s_stderr); + if (interp->vm == NULL) + KeBugCheck(0); + + /* Set some options. */ + interp->vm->warn_undef = options->warn_undef; + + /* Set the security options. */ + + if (options->secure_builtin_file) + interp->vm->security |= JS_VM_SECURE_FILE; + if (options->secure_builtin_system) + interp->vm->security |= JS_VM_SECURE_SYSTEM; + + /* Set the event hook. */ + interp->vm->hook = options->hook; + interp->vm->hook_context = options->hook_context; + interp->vm->hook_operand_count_trigger = options->hook_operand_count_trigger; + + /* The file descriptor limit. */ + interp->vm->fd_count = options->fd_count; + + if (!options->no_compiler) + { + int result; + + /* Define compiler to the virtual machine. */ + bc = js_bc_read_data (js_compiler_bytecode, js_compiler_bytecode_len); + if (bc == NULL) + KeBugCheck(0); + + result = js_vm_execute (interp->vm, bc); + js_bc_free (bc); + if (!result) + KeBugCheck(0); + } + + /* Initialize our extensions. */ + if (!js_define_module (interp, js_core_globals)) + KeBugCheck(0); + + /* Ok, we'r done. */ + return interp; +} + + +void +js_destroy_interp (JSInterpPtr interp) +{ + js_vm_destroy (interp->vm); + js_free (interp); +} + + +const JSCharPtr +js_error_message (JSInterpPtr interp) +{ + return interp->vm->error; +} + + +void +js_result (JSInterpPtr interp, JSType *result_return) +{ + memcpy (result_return, &interp->vm->exec_result, sizeof (*result_return)); +} + + +int +js_eval (JSInterpPtr interp, char *code) +{ + JSNode source; + + js_vm_make_static_string (interp->vm, &source, code, strlen (code)); + return js_eval_source (interp, &source, "JSC$compile_string"); +} + + +int +js_eval_data (JSInterpPtr interp, char *data, unsigned int datalen) +{ + JSNode source; + + js_vm_make_static_string (interp->vm, &source, data, datalen); + return js_eval_source (interp, &source, "JSC$compile_string"); +} + +int +js_eval_javascript_file (JSInterpPtr interp, char *filename) +{ + JSNode source; + + js_vm_make_static_string (interp->vm, &source, filename, strlen (filename)); + return js_eval_source (interp, &source, "JSC$compile_file"); +} + + +int +js_execute_byte_code_file (JSInterpPtr interp, char *filename) +{ + return 0; +} + + +int +js_apply (JSInterpPtr interp, char *name, unsigned int argc, JSType *argv) +{ + JSNode *args; + unsigned int ui; + int result; + + args = js_malloc (NULL, (argc + 1) * sizeof (JSNode)); + if (args == NULL) + { + sprintf (interp->vm->error, "VM: out of memory"); + return 0; + } + + /* Set the argument count. */ + args[0].type = JS_INTEGER; + args[0].u.vinteger = argc; + + /* Set the arguments. */ + for (ui = 0; ui < argc; ui++) + JS_COPY (&args[ui + 1], (JSNode *) &argv[ui]); + + /* Call it. */ + result = js_vm_apply (interp->vm, name, NULL, argc + 1, args); + + js_free (args); + + return result; +} + + +int +js_compile (JSInterpPtr interp, char *input_file, char *assembler_file, + char *byte_code_file) +{ + JSNode source; + + js_vm_make_static_string (interp->vm, &source, input_file, + strlen (input_file)); + return js_compile_source (interp, &source, "JSC$compile_file", + assembler_file, byte_code_file, NULL); +} + + +int +js_compile_to_byte_code (JSInterpPtr interp, char *input_file, + unsigned char **bc_return, + unsigned int *bc_len_return) +{ + JSNode source; + int result; + + js_vm_make_static_string (interp->vm, &source, input_file, + strlen (input_file)); + result = js_compile_source (interp, &source, "JSC$compile_file", + NULL, NULL, &source); + if (result == 0) + return 0; + + /* Pass the data to the caller. */ + *bc_return = source.u.vstring->data; + *bc_len_return = source.u.vstring->len; + + return result; +} + + +int +js_compile_data_to_byte_code (JSInterpPtr interp, char *data, + unsigned int datalen, + unsigned char **bc_return, + unsigned int *bc_len_return) +{ + JSNode source; + int result; + + js_vm_make_static_string (interp->vm, &source, data, datalen); + result = js_compile_source (interp, &source, "JSC$compile_string", + NULL, NULL, &source); + if (result == 0) + return 0; + + /* Pass the data to the caller. */ + *bc_return = source.u.vstring->data; + *bc_len_return = source.u.vstring->len; + + return result; +} + + +int +js_execute_byte_code (JSInterpPtr interp, unsigned char *bc_data, + unsigned int bc_data_len) +{ + JSByteCode *bc; + int result; + + bc = js_bc_read_data (bc_data, bc_data_len); + if (bc == NULL) + /* Not a valid byte-code data. */ + return 0; + + /* Execute it. */ + result = js_vm_execute (interp->vm, bc); + js_bc_free (bc); + + return result; +} + + +/* Classes. */ + +JSClassPtr +js_class_create (void *class_context, JSFreeProc class_context_destructor, + int no_auto_destroy, JSConstructor constructor) +{ + JSClassPtr cls; + + cls = js_calloc (NULL, 1, sizeof (*cls)); + if (cls == NULL) + return NULL; + + cls->class_context = class_context; + cls->class_context_destructor = class_context_destructor; + + cls->no_auto_destroy = no_auto_destroy; + cls->constructor = constructor; + + return cls; +} + + +void +js_class_destroy (JSClassPtr cls) +{ + if (cls == NULL) + return; + + if (cls->class_context_destructor) + (*cls->class_context_destructor) (cls->class_context); + + js_free (cls); +} + + +JSVoidPtr +js_class_context (JSClassPtr cls) +{ + if (cls) + return cls->class_context; + + return NULL; +} + + +int +js_class_define_method (JSClassPtr cls, char *name, unsigned int flags, + JSMethodProc method) +{ + JSMethodReg *nmethods; + + nmethods = js_realloc (NULL, cls->methods, + (cls->num_methods + 1) * sizeof (JSMethodReg)); + if (nmethods == NULL) + return 0; + + cls->methods = nmethods; + + /* + * The names are interned to symbols when the class is defined to the + * interpreter. + */ + + cls->methods[cls->num_methods].name = js_strdup (NULL, name); + if (cls->methods[cls->num_methods].name == NULL) + return 0; + + cls->methods[cls->num_methods].flags = flags; + cls->methods[cls->num_methods].method = method; + + cls->num_methods++; + + return 1; +} + + +int +js_class_define_property (JSClassPtr cls, char *name, unsigned int flags, + JSPropertyProc property) +{ + JSPropertyReg *nprops; + + nprops = js_realloc (NULL, cls->properties, + (cls->num_properties + 1) * sizeof (JSPropertyReg)); + if (nprops == NULL) + return 0; + + cls->properties = nprops; + + cls->properties[cls->num_properties].name = js_strdup (NULL, name); + if (cls->properties[cls->num_properties].name == NULL) + return 0; + + cls->properties[cls->num_properties].flags = flags; + cls->properties[cls->num_properties].property = property; + + cls->num_properties++; + + return 1; +} + + +/* The stub functions for JSClass built-in objects. */ + +/* Method proc. */ +static int +cls_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol method, JSNode *result_return, + JSNode *args) +{ + JSClassPtr cls = builtin_info->obj_context; + JSObjectInstanceCtx *ictx = instance_context; + int i; + JSMethodResult result; + char msg[1024]; + + /* Let's see if we know the method. */ + for (i = 0; i < cls->num_methods; i++) + if (cls->methods[i].sym == method) + { + /* Found it. */ + + /* Check flags. */ + if ((cls->methods[i].flags & JS_CF_STATIC) == 0 + && instance_context == NULL) + /* An instance method called from the `main' class. */ + break; + + result = (*cls->methods[i].method) (cls, + (ictx + ? ictx->instance_context + : NULL), + cls->interp, args[0].u.vinteger, + (JSType *) &args[1], + (JSType *) result_return, + msg); + if (result == JS_ERROR) + { + sprintf (vm->error, "%s.%s(): %s", cls->name, + cls->methods[i].name, msg); + js_vm_error (vm); + } + + return JS_PROPERTY_FOUND; + } + + return JS_PROPERTY_UNKNOWN; +} + +/* Property proc. */ +static int +cls_property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol property, int set, JSNode *node) +{ + JSClassPtr cls = builtin_info->obj_context; + JSObjectInstanceCtx *ictx = instance_context; + JSMethodResult result; + char msg[1024]; + int i; + + /* Find the property. */ + for (i = 0; i < cls->num_properties; i++) + if (cls->properties[i].sym == property) + { + /* Found it. */ + + /* Check flags. */ + + if ((cls->properties[i].flags & JS_CF_STATIC) == 0 + && instance_context == NULL) + break; + + if ((cls->properties[i].flags & JS_CF_IMMUTABLE) && set) + { + sprintf (vm->error, "%s.%s: immutable property", + cls->name, cls->properties[i].name); + js_vm_error (vm); + } + + result = (*cls->properties[i].property) (cls, + (ictx + ? ictx->instance_context + : NULL), + cls->interp, set, + (JSType *) node, msg); + if (result == JS_ERROR) + { + sprintf (vm->error, "%s.%s: %s", cls->name, + cls->properties[i].name, msg); + js_vm_error (vm); + } + + return JS_PROPERTY_FOUND; + } + + if (!set) + node->type = JS_UNDEFINED; + + return JS_PROPERTY_UNKNOWN; +} + +/* New proc. */ +static void +cls_new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, JSNode *args, + JSNode *result_return) +{ + JSClassPtr cls = builtin_info->obj_context; + JSMethodResult result; + char msg[1024]; + void *instance_context; + JSFreeProc instance_context_destructor; + JSObjectInstanceCtx *ictx; + + result = (*cls->constructor) (cls, cls->interp, args[0].u.vinteger, + (JSType *) &args[1], &instance_context, + &instance_context_destructor, + msg); + if (result == JS_ERROR) + { + sprintf (vm->error, "new %s(): %s", cls->name, msg); + js_vm_error (vm); + } + + ictx = js_calloc (vm, 1, sizeof (*ictx)); + ictx->instance_context = instance_context; + ictx->instance_context_destructor = instance_context_destructor; + + js_vm_builtin_create (vm, result_return, builtin_info, ictx); +} + + +/* Delete proc. */ +static void +cls_delete_proc (JSBuiltinInfo *builtin_info, void *instance_context) +{ + JSObjectInstanceCtx *ictx = instance_context; + + if (ictx) + { + if (ictx->instance_context_destructor) + (*ictx->instance_context_destructor) (ictx->instance_context); + + js_free (ictx); + } +} + +/* + * This is called to destroy the class handle, when there are no more + * references to it. + */ +static void +js_class_destructor (void *context) +{ + JSClassPtr cls = context; + + if (cls->no_auto_destroy) + return; + + js_class_destroy (cls); +} + + +static void +intern_symbols (JSVirtualMachine *vm, JSClassPtr cls) +{ + int i; + + for (i = 0; i < cls->num_methods; i++) + cls->methods[i].sym = js_vm_intern (vm, cls->methods[i].name); + + for (i = 0; i < cls->num_properties; i++) + cls->properties[i].sym = js_vm_intern (vm, cls->properties[i].name); + + cls->interned = 1; +} + + +static JSBuiltinInfo * +one_builtin_info_please (JSVirtualMachine *vm, JSClassPtr cls) +{ + JSBuiltinInfo *info; + + info = js_vm_builtin_info_create (vm); + + info->method_proc = cls_method; + info->property_proc = cls_property; + + if (cls->constructor) + { + info->new_proc = cls_new_proc; + info->delete_proc = cls_delete_proc; + } + + info->obj_context = cls; + info->obj_context_delete = js_class_destructor; + + return info; +} + + +int +js_define_class (JSInterpPtr interp, JSClassPtr cls, char *name) +{ + JSNode *n; + JSVirtualMachine *vm = interp->vm; + JSBuiltinInfo *info; + + /* XXX We need a top-level here */ + + cls->name = js_strdup (vm, name); + cls->interp = interp; + + if (!cls->interned) + /* Intern the symbols and properties. */ + intern_symbols (interp->vm, cls); + + /* Define it to the interpreter. */ + + info = one_builtin_info_please (vm, cls); + + n = &vm->globals[js_vm_intern (vm, name)]; + js_vm_builtin_create (vm, n, info, NULL); + + return 1; +} + + +int +js_instantiate_class (JSInterpPtr interp, JSClassPtr cls, void *ictx, + JSFreeProc ictx_destructor, JSType *result_return) +{ + JSObjectInstanceCtx *instance; + JSVirtualMachine *vm = interp->vm; + JSBuiltinInfo *info; + + if (!cls->interned) + /* Intern the symbols and properties. */ + intern_symbols (vm, cls); + + /* Create an instance. */ + instance = js_calloc (vm, 1, sizeof (*instance)); + instance->instance_context = ictx; + instance->instance_context_destructor = ictx_destructor; + + /* Create a fresh builtin info. */ + info = one_builtin_info_please (vm, cls); + + /* And create it. */ + js_vm_builtin_create (vm, (JSNode *) result_return, info, instance); + + return 1; +} + + +const JSClassPtr +js_lookup_class (JSInterpPtr interp, char *name) +{ + JSNode *n; + JSVirtualMachine *vm = interp->vm; + + n = &vm->globals[js_vm_intern (vm, name)]; + if (n->type != JS_BUILTIN) + return NULL; + + if (n->u.vbuiltin->info->method_proc != cls_method) + /* This is a wrong built-in. */ + return NULL; + + return (JSClassPtr) n->u.vbuiltin->info->obj_context; +} + + +int +js_isa (JSInterpPtr interp, JSType *object, JSClassPtr cls, + void **instance_context_return) +{ + JSNode *n = (JSNode *) object; + JSObjectInstanceCtx *instance; + + if (n->type != JS_BUILTIN || n->u.vbuiltin->info->obj_context != cls + || n->u.vbuiltin->instance_context == NULL) + return 0; + + if (instance_context_return) + { + instance = (JSObjectInstanceCtx *) n->u.vbuiltin->instance_context; + *instance_context_return = instance->instance_context; + } + + return 1; +} + + + +/* Type functions. */ + +void +js_type_make_string (JSInterpPtr interp, JSType *type, unsigned char *data, + unsigned int length) +{ + JSNode *n = (JSNode *) type; + + js_vm_make_string (interp->vm, n, data, length); +} + + +void +js_type_make_array (JSInterpPtr interp, JSType *type, unsigned int length) +{ + JSNode *n = (JSNode *) type; + + js_vm_make_array (interp->vm, n, length); +} + + +void +js_set_var (JSInterpPtr interp, char *name, JSType *value) +{ + JSNode *n = &interp->vm->globals[js_vm_intern (interp->vm, name)]; + JS_COPY (n, (JSNode *) value); +} + + +void +js_get_var (JSInterpPtr interp, char *name, JSType *value) +{ + JSNode *n = &interp->vm->globals[js_vm_intern (interp->vm, name)]; + JS_COPY ((JSNode *) value, n); +} + + +void +js_get_options (JSInterpPtr interp, JSInterpOptions *options) +{ + memcpy (options, &interp->options, sizeof (*options)); +} + + +void +js_set_options (JSInterpPtr interp, JSInterpOptions *options) +{ + memcpy (&interp->options, options, sizeof (*options)); + + /* User can change the security options, */ + + if (interp->options.secure_builtin_file) + interp->vm->security |= JS_VM_SECURE_FILE; + else + interp->vm->security &= ~JS_VM_SECURE_FILE; + + if (interp->options.secure_builtin_system) + interp->vm->security |= JS_VM_SECURE_SYSTEM; + else + interp->vm->security &= ~JS_VM_SECURE_SYSTEM; + + /* and the event hook. */ + interp->vm->hook = options->hook; + interp->vm->hook_context = options->hook_context; + interp->vm->hook_operand_count_trigger = options->hook_operand_count_trigger; +} + + +int +js_create_global_method (JSInterpPtr interp, char *name, + JSGlobalMethodProc proc, void *context, + JSFreeProc context_free_proc) +{ + JSNode *n = &interp->vm->globals[js_vm_intern (interp->vm, name)]; + JSVirtualMachine *vm = interp->vm; + int result = 1; + + /* Need one toplevel here. */ + { + JSErrorHandlerFrame handler; + + /* We must create the toplevel ourself. */ + memset (&handler, 0, sizeof (handler)); + handler.next = vm->error_handler; + vm->error_handler = &handler; + + if (setjmp (vm->error_handler->error_jmp)) + /* An error occurred. */ + result = 0; + else + { + JSBuiltinInfo *info; + JSGlobalMethodContext *ctx; + + /* Context. */ + ctx = js_calloc (vm, 1, sizeof (*ctx)); + + ctx->proc = proc; + ctx->context = context; + ctx->free_proc = context_free_proc; + ctx->interp = interp; + + /* Info. */ + info = js_vm_builtin_info_create (vm); + info->global_method_proc = js_global_method_stub; + info->delete_proc = js_global_method_delete; + + /* Create the builtin. */ + js_vm_builtin_create (interp->vm, n, info, ctx); + } + + /* Pop the error handler. */ + vm->error_handler = vm->error_handler->next; + } + + return result; +} + + +int +js_define_module (JSInterpPtr interp, JSModuleInitProc init_proc) +{ + JSErrorHandlerFrame handler; + JSVirtualMachine *vm = interp->vm; + int result = 1; + + /* Just call the init proc in a toplevel. */ + + memset (&handler, 0, sizeof (handler)); + handler.next = vm->error_handler; + vm->error_handler = &handler; + + if (setjmp (vm->error_handler->error_jmp)) + /* An error occurred. */ + result = 0; + else + /* Call the module init proc. */ + (*init_proc) (interp); + + /* Pop the error handler. */ + vm->error_handler = vm->error_handler->next; + + return result; +} + + + +/* + * Static functions. + */ + +static int +js_eval_source (JSInterpPtr interp, JSNode *source, char *compiler_function) +{ + JSNode argv[5]; + int i = 0; + int result; + JSByteCode *bc; + + /* Let's compile the code. */ + + /* Argument count. */ + argv[i].type = JS_INTEGER; + argv[i].u.vinteger = 4; + i++; + + /* Source to compiler. */ + JS_COPY (&argv[i], source); + i++; + + /* Flags. */ + argv[i].type = JS_INTEGER; + argv[i].u.vinteger = 0; + + if (interp->options.verbose) + argv[i].u.vinteger = JSC_FLAG_VERBOSE; + + argv[i].u.vinteger |= JSC_FLAG_GENERATE_DEBUG_INFO; + + argv[i].u.vinteger |= JSC_FLAG_OPTIMIZE_PEEPHOLE; + argv[i].u.vinteger |= JSC_FLAG_OPTIMIZE_JUMPS; + argv[i].u.vinteger |= JSC_FLAG_WARN_WITH_CLOBBER; + i++; + + /* Assembler file. */ + argv[i].type = JS_NULL; + i++; + + /* Byte-code file. */ + argv[i].type = JS_NULL; + i++; + + /* Call the compiler entry point. */ + result = js_vm_apply (interp->vm, compiler_function, NULL, i, argv); + if (result == 0) + return 0; + + /* + * The resulting byte-code file is now at vm->exec_result. + * + * Note! The byte-code is a string allocated form the vm heap. + * The garbage collector can free it when it wants since the result + * isn't protected. However, we have no risk here because we + * first convert the byte-code data block to our internal + * JSByteCode block that shares no memory with the original data. + */ + + assert (interp->vm->exec_result.type == JS_STRING); + + bc = js_bc_read_data (interp->vm->exec_result.u.vstring->data, + interp->vm->exec_result.u.vstring->len); + + /* And finally, execute it. */ + result = js_vm_execute (interp->vm, bc); + + /* Free the byte-code. */ + js_bc_free (bc); + + return result; +} + + +static int +js_compile_source (JSInterpPtr interp, JSNode *source, + char *compiler_function, char *assembler_file, + char *byte_code_file, JSNode *bc_return) +{ + JSNode argv[5]; + int i = 0; + int result; + + /* Init arguments. */ + + argv[i].type = JS_INTEGER; + argv[i].u.vinteger = 4; + i++; + + /* Source to compiler. */ + JS_COPY (&argv[1], source); + i++; + + /* Flags. */ + argv[i].type = JS_INTEGER; + argv[i].u.vinteger = 0; + + if (interp->options.verbose) + argv[i].u.vinteger |= JSC_FLAG_VERBOSE; + if (interp->options.annotate_assembler) + argv[i].u.vinteger |= JSC_FLAG_ANNOTATE_ASSEMBLER; + if (interp->options.debug_info) + argv[i].u.vinteger |= JSC_FLAG_GENERATE_DEBUG_INFO; + if (interp->options.executable_bc_files) + argv[i].u.vinteger |= JSC_FLAG_GENERATE_EXECUTABLE_BC_FILES; + + if (interp->options.warn_unused_argument) + argv[i].u.vinteger |= JSC_FLAG_WARN_UNUSED_ARGUMENT; + if (interp->options.warn_unused_variable) + argv[i].u.vinteger |= JSC_FLAG_WARN_UNUSED_VARIABLE; + if (interp->options.warn_shadow) + argv[i].u.vinteger |= JSC_FLAG_WARN_SHADOW; + if (interp->options.warn_with_clobber) + argv[i].u.vinteger |= JSC_FLAG_WARN_WITH_CLOBBER; + if (interp->options.warn_missing_semicolon) + argv[i].u.vinteger |= JSC_FLAG_WARN_MISSING_SEMICOLON; + if (interp->options.warn_strict_ecma) + argv[i].u.vinteger |= JSC_FLAG_WARN_STRICT_ECMA; + if (interp->options.warn_deprecated) + argv[i].u.vinteger |= JSC_FLAG_WARN_DEPRECATED; + + if (interp->options.optimize_peephole) + argv[i].u.vinteger |= JSC_FLAG_OPTIMIZE_PEEPHOLE; + if (interp->options.optimize_jumps_to_jumps) + argv[i].u.vinteger |= JSC_FLAG_OPTIMIZE_JUMPS; + if (interp->options.optimize_bc_size) + argv[i].u.vinteger |= JSC_FLAG_OPTIMIZE_BC_SIZE; + if (interp->options.optimize_heavy) + argv[i].u.vinteger |= JSC_FLAG_OPTIMIZE_HEAVY; + + i++; + + /* Assembler file. */ + if (assembler_file) + js_vm_make_static_string (interp->vm, &argv[i], assembler_file, + strlen (assembler_file)); + else + argv[i].type = JS_NULL; + i++; + + /* Byte-code file. */ + if (byte_code_file) + js_vm_make_static_string (interp->vm, &argv[i], byte_code_file, + strlen (byte_code_file)); + else + argv[i].type = JS_NULL; + i++; + + /* Call the compiler entry point. */ + result = js_vm_apply (interp->vm, compiler_function, NULL, i, argv); + if (result == 0) + return 0; + + if (bc_return) + /* User wanted to get the resulting byte-code data. Here it is. */ + JS_COPY (bc_return, &interp->vm->exec_result); + + return result; +} + + +/* + * Global methods. + */ + +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) + { + /* Return it to the caller. */ + JS_COPY (result_return, &args[1]); + return; + } + + /* + * 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. Throw it as an error to our caller. */ + js_vm_error (vm); + } + + /* Pass the return value to our caller. */ + JS_COPY (result_return, &vm->exec_result); +} + +static void +load_class_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, + JSNode *result_return, JSNode *args) +{ + JSInterpPtr interp = instance_context; + int i; + + if (args->u.vinteger == 0) + { + sprintf (vm->error, "loadClass(): no arguments given"); + js_vm_error (vm); + } + + for (i = 1; i <= args->u.vinteger; i++) + { + char *cp, *cp2; + void *lib; + void (*func) (JSInterpPtr interp); + char *func_name; + char buf[512]; + + if (args[i].type != JS_STRING) + { + sprintf (vm->error, "loadClass(): illegal argument"); + js_vm_error (vm); + } + + cp = js_string_to_c_string (vm, &args[i]); + + /* Extract the function name. */ + func_name = strrchr (cp, ':'); + if (func_name == NULL) + { + func_name = strrchr (cp, '/'); + if (func_name == NULL) + func_name = cp; + else + func_name++; + } + else + { + *func_name = '\0'; + func_name++; + } + + /* Try to open the library. */ + lib = js_dl_open (cp, buf, sizeof (buf)); + if (lib == NULL) + { + sprintf (vm->error, "loadClass(): couldn't open library `%s': %s", + cp, buf); + js_vm_error (vm); + } + + /* + * Strip all suffixes from the library name: if the + * is extracted from it, this will convert the library name + * `foo.so.x.y' to the canonical entry point name `foo'. + */ + cp2 = strchr (cp, '.'); + if (cp2) + *cp2 = '\0'; + + func = js_dl_sym (lib, func_name, buf, sizeof (buf)); + if (func == NULL) + { + sprintf (vm->error, + "loadClass(): couldn't find the init function `%s': %s", + func_name, buf); + js_vm_error (vm); + } + + /* All done with this argument. */ + js_free (cp); + + /* + * And finally, call the library entry point. All possible errors + * will throw us to the containing top-level. + */ + (*func) (interp); + } + + result_return->type = JS_UNDEFINED; +} + + +static void +call_method_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, + JSNode *result_return, JSNode *args) +{ + /* JSInterpPtr interp = instance_context; */ + JSNode *argv; + int i; + int result; + char *cp; + + if (args->u.vinteger != 3) + { + sprintf (vm->error, "callMethod(): illegal amount of arguments"); + js_vm_error (vm); + } + if (args[2].type != JS_STRING) + { + illegal_argument: + sprintf (vm->error, "callMethod(): illegal argument"); + js_vm_error (vm); + } + if (args[3].type != JS_ARRAY) + goto illegal_argument; + + /* Create the argument array. */ + argv = js_malloc (vm, (args[3].u.varray->length + 1) * sizeof (JSNode)); + + /* The argument count. */ + argv[0].type = JS_INTEGER; + argv[0].u.vinteger = args[3].u.varray->length; + + for (i = 0; i < args[3].u.varray->length; i++) + JS_COPY (&argv[i + 1], &args[3].u.varray->data[i]); + + /* Method name to C string. */ + cp = js_string_to_c_string (vm, &args[2]); + + /* Call it. */ + result = js_vm_call_method (vm, &args[1], cp, args[3].u.varray->length + 1, + argv); + + /* Cleanup. */ + js_free (cp); + js_free (argv); + + if (result) + JS_COPY (result_return, &vm->exec_result); + else + /* The error message is already there. */ + js_vm_error (vm); +} + + +static void +js_core_globals (JSInterpPtr interp) +{ + JSNode *n; + JSBuiltinInfo *info; + JSVirtualMachine *vm = interp->vm; + + if (!interp->options.no_compiler) + { + /* Command `eval'. */ + + info = js_vm_builtin_info_create (vm); + info->global_method_proc = eval_global_method; + + n = &interp->vm->globals[js_vm_intern (interp->vm, "eval")]; + + js_vm_builtin_create (interp->vm, n, info, interp); + } + + /* Command `loadClass'. */ + + info = js_vm_builtin_info_create (vm); + info->global_method_proc = load_class_global_method; + + n = &interp->vm->globals[js_vm_intern (interp->vm, "loadClass")]; + js_vm_builtin_create (interp->vm, n, info, interp); + + /* Command `callMethod'. */ + + info = js_vm_builtin_info_create (vm); + info->global_method_proc = call_method_global_method; + + n = &interp->vm->globals[js_vm_intern (interp->vm, "callMethod")]; + js_vm_builtin_create (interp->vm, n, info, interp); +} + + +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); +} + + +static void +js_global_method_delete (JSBuiltinInfo *builtin_info, void *instance_context) +{ + JSGlobalMethodContext *ctx = instance_context; + + if (ctx) + { + if (ctx->free_proc) + (*ctx->free_proc) (ctx->context); + + js_free (ctx); + } +} + + +/* I/O Stream to user I/O function. */ + +static int +iofunc_io (void *context, unsigned char *buffer, unsigned int todo, + int *error_return) +{ + JSUserIOFuncCtx *ctx = context; + int moved; + + *error_return = 0; + + moved = (*ctx->func) (ctx->context, buffer, todo); + if (moved >= 0) + ctx->position += moved; + + return moved; +} + + +static int +iofunc_seek (void *context, long offset, int whence) +{ + return -1; +} + + +static long +iofunc_get_position (void *context) +{ + JSUserIOFuncCtx *ctx = context; + + return ctx->position; +} + + +static long +iofunc_get_length (void *context) +{ + return -1; +} + + +static void +iofunc_close (void *context) +{ + js_free (context); +} + +static JSIOStream * +iostream_iofunc (JSIOFunc func, void *context, int readp, int writep) +{ + JSIOStream *stream = js_iostream_new (); + JSUserIOFuncCtx *ctx; + + ctx = js_malloc (NULL, sizeof (*ctx)); + if (ctx == NULL) + { + (void) js_iostream_close (stream); + return NULL; + } + + /* Init context. */ + ctx->func = func; + ctx->context = context; + ctx->position = 0; + + if (readp) + stream->read = iofunc_io; + if (writep) + stream->write = iofunc_io; + + stream->seek = iofunc_seek; + stream->get_position = iofunc_get_position; + stream->get_length = iofunc_get_length; + stream->close = iofunc_close; + stream->context = ctx; + + return stream; +} diff --git a/reactos/lib/kjs/ksrc/kjs.c b/reactos/lib/kjs/ksrc/kjs.c new file mode 100644 index 00000000000..e2be2c6a8bb --- /dev/null +++ b/reactos/lib/kjs/ksrc/kjs.c @@ -0,0 +1,53 @@ +#include "kjs.h" +#include "js.h" + +PKJS kjs_create_interp( VOID *Reserved ) { + PKJS kjs = ExAllocatePool( NonPagedPool, sizeof(KJS) ); + if( !kjs ) return kjs; + kjs->interp = js_create_interp(NULL, kjs); + return kjs; +} + +void kjs_destroy_interp( PKJS kjs ) { + js_destroy_interp( kjs->interp ); + ExFreePool( kjs ); +} + +void kjs_eval( PKJS kjs, PCHAR commands ) { + if( !js_eval( kjs->interp, commands ) ) + DbgPrint( "JS Error: %s\n", kjs->vm->error ); +} + +void kjs_system_register( PKJS kjs, PCHAR name, PVOID context, + PKJS_METHOD function ) { + JSSymbolList *nsym = kjs->ctx->registered_symbols; + JSSymbol sym = js_vm_intern(kjs->vm, name); + + while( nsym ) { + if( sym == nsym->symbol ) { + nsym->registered_function = function; + nsym->context = context; + return; + } + nsym = nsym->next; + } + + nsym = js_calloc(kjs->vm, 1, sizeof(JSSymbolList)); + nsym->symbol = sym; + nsym->registered_function = function; + nsym->context = context; + nsym->next = kjs->ctx->registered_symbols; + kjs->ctx->registered_symbols = nsym; +} + +void kjs_system_unregister( PKJS kjs, PVOID context, PKJS_METHOD function ) { + JSSymbolList *nsym = kjs->ctx->registered_symbols; + while( nsym ) { + if( function == nsym->registered_function && + context == nsym->context ) { + nsym->registered_function = 0; + nsym->context = 0; + } + nsym = nsym->next; + } +} diff --git a/reactos/lib/kjs/ksrc/longjmp.S b/reactos/lib/kjs/ksrc/longjmp.S new file mode 100644 index 00000000000..f998344ae06 --- /dev/null +++ b/reactos/lib/kjs/ksrc/longjmp.S @@ -0,0 +1,72 @@ + .file "longjmp.S" +/* + * Copyright (C) 1998, 1999, Jonathan S. Shapiro. + * + * This file is part of the EROS Operating System. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* #include */ + + /* + * typedef struct { + * unsigned long ebx, esi, edi; + * unsigned long ebp; + * unsigned long sp; + * unsigned long pc; + * } jmp_buf[1]; + */ + + /* + * On entry, the stack to longjmp looks like: + * + * value + * ptr to jmp_buf + * return PC + */ + +.globl _longjmp +_longjmp: + pushl %ebp + movl %esp,%ebp + + movl 8(%ebp),%ecx /* address of jmp_buf to ecx */ + movl 12(%ebp),%eax /* return value to %eax */ + testl %eax,%eax + jne 1f + incl %eax /* return 1 if handed 0 */ + +1: + movl (%ecx),%ebx /* restore %ebx */ + movl 4(%ecx),%esi /* restore %esi */ + movl 8(%ecx),%edi /* restore %edi */ + + /* + * From this instant on we are not running in a valid frame + */ + + movl 12(%ecx),%ebp /* restore %ebp */ + movl 16(%ecx),%esp /* restore %esp */ + /* movl 20(%ecx),%eax return PC */ + + /* + * Since we are abandoning the stack in any case, + * there isn't much point in doing the usual return + * discipline. + */ + + jmpl *20(%ecx) + diff --git a/reactos/lib/kjs/ksrc/main.c b/reactos/lib/kjs/ksrc/main.c new file mode 100644 index 00000000000..8ee02ea705a --- /dev/null +++ b/reactos/lib/kjs/ksrc/main.c @@ -0,0 +1,798 @@ +/* + * The JS shell + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/ksrc/main.c,v $ + * $Id: main.c,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +#if HAVE_CONFIG_H +#include "jsconfig.h" +#endif + +#include +#include + +#if HAVE_STDC_HEADERS +#include +#include +#include + +#else /* not HAVE_STDC_HEADERS */ + +#if HAVE_STDLIB_H +#include +#endif + +#if HAVE_STRING_H +#include +#endif + +#if HAVE_UNISTD_H +#include +#endif + +#endif /* not HAVE_STDC_HEADERS */ + +#include "js.h" +#include "getopt.h" + +/* + * Global variables. + */ + +char *program; + +/* Options. */ + +/* + * -a, --annotate-assembler + * + * Annotate generated assembler listing with the original source code. + */ + +int annotate_assembler = 0; + +/* + * -c, --compile + * + * Compile all given JavaScript files to byte-code and save the result + * to file. + */ + +int compile = 0; + +/* + * -d METHOD, --dispatch=METHOD + * + * Use byte-code instruction dispatch method METHOD. Possible values are + * `switch', `switch-basic' and `jumps'. + */ + +JSVMDispatchMethod dispatch_method = JS_VM_DISPATCH_JUMPS; + +/* + * -e CODE, --eval=CODE + * + * Evaluate JavaScript code CODE. + */ + +/* + * -E, --events + * + * Print virtual machine events to the standard error. + */ +int events = 0; + +/* + * -f, --file + * + * Use the next argument as the main source file and pass all + * remaining arguments to it through the ARGS array. + */ + +/* + * -g, --debug + * + * Generate debugging information to the generated byte-code file. + */ +int generate_debug_info = 0; + +/* + * -h, --help + * + * Print short help and exit successfully. + */ + +/* + * -l, --load + * + * Treat all following arguments, up to option -f / --file, as + * byte-code or JavaScript files and execute them. When option -f, --file + * is encountered, the next argument is the actual main source file that + * is executed with the remaining arguments. + */ + +/* + * -N, --no-compiler + * + * Do not define compiler in the interpreter. Options makes the + * interpreter a pure virtual machine that can't compile any JavaScript + * code. + */ + +int no_compiler = 0; + +/* + * -O [LEVEL], --optimize[=LEVEL] + * + * Optimize at level LEVEL. The default level for batch-compile is 1. + * Value 0 disable optimization. + */ + +int optimize = 1; + +/* + * -r OPTION, --secure=OPTIONS + * + * Turn on security option OPTION. + */ + +int secure_builtin_file = 0; +int secure_builtin_system = 0; + +/* + * -s SIZE, --stack-size=SIZE + * + * Set the virtual machine stack size to SIZE. + */ +unsigned int stack_size = 2048; + +/* + * -S, --no-assemble + * + * Compile al given JavaScript files to JavaScript assembler and save the + * result to file. + */ + +int no_assemble = 0; + +/* + * -t, --stacktrace + * + * Print stack trace on error. + */ + +int stacktrace_on_error = 0; + +/* + * -v, --verbose + * + * Tell more about what we do. + */ + +unsigned int verbose = 0; + +/* + * -V, --version + * + * Print version information and exit successfully. + */ + +/* + * -W OPTION, --compiler-option=OPTION + * + * Set compiler option OPTION. + */ + +int warn_deprecated = 0; +int warn_unused_argument = 0; +int warn_unused_variable = 1; +int warn_undef = 1; +int warn_shadow = 1; +int warn_with_clobber = 1; +int warn_missing_semicolon = 0; +int warn_strict_ecma = 0; + +/* + * -x, --executable + * + * Generate executable byte-code files. + */ +int generate_executable_bc_files = 0; + + +/* + * Static variables. + */ + +static struct option long_options[] = +{ + {"annotate-assembler", no_argument, 0, 'a'}, + {"compile", no_argument, 0, 'c'}, + {"dispatch", required_argument, 0, 'd'}, + {"eval", required_argument, 0, 'e'}, + {"events", no_argument, 0, 'E'}, + {"file", no_argument, 0, 'f'}, + {"debug", no_argument, 0, 'g'}, + {"help", no_argument, 0, 'h'}, + {"load", no_argument, 0, 'l'}, + {"no-compiler", no_argument, 0, 'N'}, + {"optimize", optional_argument, 0, 'O'}, + {"secure", required_argument, 0, 'r'}, + {"stack-size", required_argument, 0, 's'}, + {"no-assemble", no_argument, 0, 'S'}, + {"stacktrace", no_argument, 0, 't'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"compiler-option", required_argument, 0, 'W'}, + {"executable", no_argument, 0, 'x'}, + + {NULL, 0, 0, 0}, +}; + +/* Compiler options. */ + +/* Flags for options. */ +#define JSC_RUNTIME 0x01 +#define JSC_WALL 0x02 +#define JSC_PEDANTIC 0x04 +#define JSC_LINT 0x08 + +static struct +{ + char *name; + int *option; + unsigned int flags; +} compiler_options[] = +{ + {"deprecated", &warn_deprecated, JSC_WALL}, + {"unused-argument", &warn_unused_argument, JSC_WALL}, + {"unused-variable", &warn_unused_variable, JSC_WALL}, + {"undefined", &warn_undef, JSC_RUNTIME}, + {"shadow", &warn_shadow, JSC_WALL}, + {"with-clobber", &warn_with_clobber, JSC_WALL}, + {"missing-semicolon", &warn_missing_semicolon, JSC_PEDANTIC}, + {"strict-ecma", &warn_strict_ecma, JSC_LINT}, + + {NULL, NULL, 0}, +}; + + +/* + * Prototypes for static functions. + */ + +static void handle_compiler_option (char *name); + +static JSInterpPtr create_interp (void); + +static void usage (void); +static void version (void); + +/* + * Global functions. + */ + +int +main (int argc, char *argv[]) +{ + JSInterpPtr interp = NULL; + char *cp; + int do_load = 0; + + /* Get program's name. */ + program = strrchr (argv[0], '/'); + if (program == NULL) + program = argv[0]; + else + program++; + + /* Make getopt_long() to use our modified program name. */ + argv[0] = program; + + /* Parse arguments. */ + while (1) + { + int c; + int option_index = 0; + + c = getopt_long (argc, argv, "acd:e:EfghlNO::r:s:StvVW:x", + long_options, &option_index); + if (c == EOF) + break; + + switch (c) + { + case 'a': /* --annotate-assembler */ + annotate_assembler = 1; + break; + + case 'c': /* --compile */ + compile = 1; + break; + + case 'd': /* --dispatch */ + if (strcmp (optarg, "switch-basic") == 0) + dispatch_method = JS_VM_DISPATCH_SWITCH_BASIC; + else if (strcmp (optarg, "switch") == 0) + dispatch_method = JS_VM_DISPATCH_SWITCH; + else if (strcmp (optarg, "jumps") == 0) + dispatch_method = JS_VM_DISPATCH_JUMPS; + else + { + fprintf (stderr, "%s: illegal dispatch method `%s'\n", + program, optarg); + exit (1); + } + break; + + case 'e': /* --eval */ + if (interp == NULL) + interp = create_interp (); + + if (!js_eval (interp, optarg)) + { + fprintf (stderr, "%s: eval failed: %s\n", program, + js_error_message (interp)); + exit (1); + } + break; + + case 'E': /* --events */ + events = 1; + break; + + case 'f': /* --file */ + if (optind >= argc) + { + no_argument_for_file: + fprintf (stderr, "%s: no arguments after option --file\n", + program); + exit (1); + } + goto arguments_done; + break; + + case 'g': /* --debug */ + generate_debug_info = 1; + break; + + case 'h': /* --help */ + usage (); + exit (0); + break; + + case 'l': /* --load */ + do_load = 1; + goto arguments_done; + break; + + case 'N': /* --no-compiler */ + no_compiler = 1; + break; + + case 'O': /* --optimize */ + if (optarg) + optimize = atoi (optarg); + break; + + case 'r': /* --secure */ + if (strcmp (optarg, "file") == 0) + secure_builtin_file = 1; + else if (strcmp (optarg, "system") == 0) + secure_builtin_system = 1; + else + { + fprintf (stderr, "%s: unknown security option `%s'\n", + program, optarg); + exit (1); + } + break; + + case 's': /* --stack-size */ + stack_size = atoi (optarg); + break; + + case 'S': /* --no-assemble */ + no_assemble = 1; + break; + + case 't': /* --stacktrace */ + stacktrace_on_error = 1; + break; + + case 'v': /* --verbose */ + verbose++; + break; + + case 'V': /* --version */ + version (); + exit (0); + break; + + case 'W': /* --compiler-option */ + handle_compiler_option (optarg); + break; + + case 'x': /* --executable */ + generate_executable_bc_files = 1; + break; + + case '?': + fprintf (stderr, "Try `%s --help' for more information.\n", + program); + exit (1); + break; + + default: + printf ("Hey! main() didn't handle option \"%c\" (%d)", c, c); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + abort (); + break; + } + } + + arguments_done: + + interp = create_interp (); + + /* Let's see what we have to do. */ + if (compile) + { + char *jscname; + + /* + * Treat all remaining arguments as JavaScript files and compile them. + */ + + for (; optind < argc; optind++) + { + /* Create name for the byte-code file. */ + + jscname = malloc (strlen (argv[optind]) + 5); + assert (jscname != NULL); + strcpy (jscname, argv[optind]); + + cp = strrchr (jscname, '.'); + if (cp) + strcpy (++cp, "jsc"); + else + strcat (jscname, ".jsc"); + + if (verbose) + printf ("%s: compiling `%s' to `%s'\n", program, + argv[optind], jscname); + + if (!js_compile (interp, argv[optind], NULL, jscname)) + { + fprintf (stderr, "%s\n", js_error_message (interp)); + exit (1); + } + + free (jscname); + } + } + else if (no_assemble) + { + char *jasname; + + /* Compile argument files to assembler. */ + for (; optind < argc; optind++) + { + /* Create name for the assembler file. */ + + jasname = malloc (strlen (argv[optind]) + 5); + assert (jasname != NULL); + strcpy (jasname, argv[optind]); + + cp = strrchr (jasname, '.'); + if (cp) + strcpy (++cp, "jas"); + else + strcat (jasname, ".jas"); + + if (verbose) + printf ("%s: compiling `%s' to `%s'\n", program, + argv[optind], jasname); + + if (!js_compile (interp, argv[optind], jasname, NULL)) + { + fprintf (stderr, "%s\n", js_error_message (interp)); + exit (1); + } + + free (jasname); + } + } + else if (optind < argc) + { + char *main_file = argv[optind]; + JSType args; + int i; + + /* + * Assume that contains JavaScript (or byte-code) and + * execute it. All the remaining arguments are passed to the + * interpreter through the ARGS array. + */ + + /* Save all remaining arguments to ARGS */ + js_type_make_array (interp, &args, argc - optind); + + for (i = 0; optind + i < argc; i++) + js_type_make_string (interp, &args.u.array->data[i], + argv[optind + i], strlen (argv[optind + i])); + + js_set_var (interp, "ARGS", &args); + + if (!js_eval_file (interp, main_file)) + { + fprintf (stderr, "%s: evaluation of file `%s' failed:\n%s\n", + program, main_file, js_error_message (interp)); + exit (1); + } + } + + js_destroy_interp (interp); + + return 0; +} + + +/* + * Static functions. + */ + +static inline int +is_prefix (char *prefix, char *str) +{ + int i; + + for (i = 0; prefix[i] && str[i] && prefix[i] == str[i]; i++) + ; + if (!prefix[i]) + return 1; + + return 0; +} + + +static void +handle_compiler_option (char *name) +{ + int i; + int value = 1; + int nmatches = 0; + int did_match = 0; + + if (name[0] == 'n' && name[1] == 'o' && name[2] == '-') + { + value = 0; + name += 3; + } + + for (i = 0; compiler_options[i].name; i++) + { + int was_prefix = 0; + + if ((was_prefix = is_prefix (name, compiler_options[i].name)) + || (strcmp (name, "runtime") == 0 + && (compiler_options[i].flags & JSC_RUNTIME)) + || (strcmp (name, "all") == 0 + && (compiler_options[i].flags & JSC_WALL)) + || (strcmp (name, "pedantic") == 0 + && (compiler_options[i].flags & (JSC_WALL | JSC_PEDANTIC)))) + { + *compiler_options[i].option = value; + + if (was_prefix) + nmatches++; + + did_match = 1; + } + } + + if (!did_match) + { + fprintf (stderr, "%s: unknown compiler option `-W%s%s'\n", program, + value ? "" : "no-", name); + exit (1); + } + if (nmatches > 1) + { + fprintf (stderr, "%s: ambiguous compiler option `-W%s%s'\n", + program, value ? "" : "no-", name); + exit (1); + } +} + + +static int +show_events_hook (int event, void *context) +{ + char *event_name; + + switch (event) + { + case JS_EVENT_OPERAND_COUNT: + event_name = "operand count"; + break; + + case JS_EVENT_GARBAGE_COLLECT: + event_name = "garbage collect"; + break; + + default: + event_name = "unknown"; + break; + } + + fprintf (stderr, "[%s: %s]\n", program, event_name); + + return 0; +} + + +static JSInterpPtr +create_interp () +{ + JSInterpOptions options; + JSInterpPtr interp; + + js_init_default_options (&options); + + options.stack_size = stack_size; + options.dispatch_method = dispatch_method; + options.verbose = verbose; + + options.no_compiler = no_compiler; + options.stacktrace_on_error = stacktrace_on_error; + + options.secure_builtin_file = secure_builtin_file; + options.secure_builtin_system = secure_builtin_system; + + options.annotate_assembler = annotate_assembler; + options.debug_info = generate_debug_info; + options.executable_bc_files = generate_executable_bc_files; + + options.warn_unused_argument = warn_unused_argument; + options.warn_unused_variable = warn_unused_variable; + options.warn_undef = warn_undef; + options.warn_shadow = warn_shadow; + options.warn_with_clobber = warn_with_clobber; + options.warn_missing_semicolon = warn_missing_semicolon; + options.warn_strict_ecma = warn_strict_ecma; + options.warn_deprecated = warn_deprecated; + + /* As a default, no optimization */ + options.optimize_peephole = 0; + options.optimize_jumps_to_jumps = 0; + options.optimize_bc_size = 0; + options.optimize_heavy = 0; + + if (optimize >= 1) + { + options.optimize_peephole = 1; + options.optimize_jumps_to_jumps = 1; + options.optimize_bc_size = 1; + } + + if (optimize >= 2) + { + options.optimize_heavy = 1; + } + + /* Show events? */ + if (events) + { + options.hook = show_events_hook; + options.hook_operand_count_trigger = 1000000; + } + + interp = js_create_interp (&options); + if (interp == NULL) + { + fprintf (stderr, "%s: couldn't create interpreter\n", program); + exit (1); + } + + /* And finally, define the requested modules. */ + +#if WITH_JS + if (!js_define_module (interp, js_ext_JS)) + fprintf (stderr, "%s: warning: couldn't create the JS extension\n", + program); +#endif + +#if WITH_CURSES + if (!js_define_module (interp, js_ext_curses)) + fprintf (stderr, "%s: warning: couldn't create the curses extension\n", + program); +#endif + +#if WITH_MD5 + if (!js_define_module (interp, js_ext_MD5)) + fprintf (stderr, "%s: warning: couldn't create the MD5 extension\n", + program); +#endif + + return interp; +} + + +static void +usage () +{ + printf ("\ +Usage: %s [OPTION]... FILE [ARGUMENT]...\n\ +Mandatory arguments to long options are mandatory for short options too.\n\ + -a, --annotate-assembler annotate generated assembler listing with\n\ + the original source code\n\ + -c, --compile compile JavaScript input file to byte-code\n\ + and save the result to the file `FILE.jsc'\n\ + -d, --dispatch=METHOD use method METHOD for byte-code instruction\n\ + dispatching\n\ + -e, --eval=CODE evaluate JavaScript code CODE\n\ + -E, --events print interpreter events\n\ + -f, --file evaluate the next argument file and pass\n\ + all remaining arguments to the interpreter\n\ + through the ARGS array\n\ + -g, --debug generate debugging information\n\ + -h, --help print this help and exit\n\ + -l, --load evaluate argument files until option `-f',\n\ + `--file' is encountered\n\ + -N, --no-compiler do not define compiler to the JavaScript\n\ + interpreter\n\ + -O, --optimize[=LEVEL] optimize at level LEVEL\n\ + -r, --secure=OPTION turn on security option OPTION\n\ + -s, --stack-size=SIZE set the interpreter stack size to SIZE nodes\n\ + -S, --assembler compile JavaScript intput file to assembler\n\ + and save the result to the file `FILE.jas'\n\ + -t, --stacktrace print stacktrace on error\n\ + -v, --verbose tell what the interpreter is doing\n\ + -V, --version print version number\n\ + -W, --compiler-option=OPTION\n\ + set compilation option OPTION\n\ + -x, --executable generate executable byte-code files\n", + program); + + printf ("\nReport bugs to mtr@ngs.fi.\n"); +} + + +static void +version () +{ + printf ("NGS JavaScript Interpter %s\n\ +Copyright (C) 1998 New Generation Software (NGS) Oy.\n\ +NGS JavaScript Interpreter comes with NO WARRANTY, to the extent\n\ +permitted by law. You may redistribute copies of NGS JavaScript\n\ +Interpreter under the terms of the GNU Library General Public License.\n\ +For more information about these matters, see the files named COPYING.\n\ +", + VERSION); +} diff --git a/reactos/lib/kjs/ksrc/mrgsort.c b/reactos/lib/kjs/ksrc/mrgsort.c new file mode 100644 index 00000000000..2ac46de2c2d --- /dev/null +++ b/reactos/lib/kjs/ksrc/mrgsort.c @@ -0,0 +1,120 @@ +/* + * Re-entrant mergesort. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/ksrc/mrgsort.c,v $ + * $Id: mrgsort.c,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +#include "jsconfig.h" +#include "ddk/exfuncs.h" +#define js_malloc(x) ExAllocatePool(NonPagedPool,x) +#define js_free(x) ExFreePool(x) + +#include "mrgsort.h" + +/* + * Types and definitions. + */ + +#define COPY(buf1, idx1, buf2, idx2) \ + memcpy ((buf1) + (idx1) * size, (buf2) + (idx2) * size, size); + +/* + * Static functions. + */ + +static void +do_mergesort (unsigned char *base, unsigned int size, unsigned char *tmp, + unsigned int l, unsigned int r, + MergesortCompFunc func, void *func_ctx) +{ + unsigned int i, j, k, m; + + if (r <= l) + return; + + m = (r + l) / 2; + do_mergesort (base, size, tmp, l, m, func, func_ctx); + do_mergesort (base, size, tmp, m + 1, r, func, func_ctx); + + memcpy (tmp + l * size, base + l * size, (r - l + 1) * size); + + i = l; + j = m + 1; + k = l; + + /* Merge em. */ + while (i <= m && j <= r) + { + if ((*func) (tmp + i * size, tmp + j * size, func_ctx) <= 0) + { + COPY (base, k, tmp, i); + i++; + } + else + { + COPY (base, k, tmp, j); + j++; + } + k++; + } + + /* Copy left-overs. Only one of the following will be executed. */ + for (; i <= m; i++) + { + COPY (base, k, tmp, i); + k++; + } + for (; j <= r; j++) + { + COPY (base, k, tmp, j); + k++; + } +} + + +/* + * Global functions. + */ + +void +mergesort_r (void *base, unsigned int number_of_elements, + unsigned int size, MergesortCompFunc comparison_func, + void *comparison_func_context) +{ + void *tmp; + + if (number_of_elements == 0) + return; + + /* Allocate tmp buffer. */ + tmp = js_malloc (number_of_elements * size); + /* assert (tmp != NULL); */ + + do_mergesort (base, size, tmp, 0, number_of_elements - 1, comparison_func, + comparison_func_context); + + js_free (tmp); +} diff --git a/reactos/lib/kjs/ksrc/object.c b/reactos/lib/kjs/ksrc/object.c new file mode 100644 index 00000000000..a639d025dc1 --- /dev/null +++ b/reactos/lib/kjs/ksrc/object.c @@ -0,0 +1,537 @@ +/* + * User object handling. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/ksrc/object.c,v $ + * $Id: object.c,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +#include "ddk/ntddk.h" +#include "jsint.h" +#include "jsconfig.h" + +/* + * Types and definitions. + */ + +#define HASH_SIZE 128 + +/* + * Prototypes for static functions. + */ + +static void hash_create (JSVirtualMachine *vm, JSObject *obj); + +static void hash_insert (JSVirtualMachine *vm, JSObject *obj, const char *name, + unsigned int name_len, int pos); + +static void hash_delete (JSVirtualMachine *vm, JSObject *obj, const char *name, + unsigned int name_len); + +static int hash_lookup (JSObject *obj, char *name, unsigned int name_len); + + +/* + * Global functions. + */ + +JSObject * +js_vm_object_new (JSVirtualMachine *vm) +{ + JSObject *obj; + + obj = js_vm_alloc (vm, sizeof (*obj)); + obj->hash = NULL; + obj->num_props = 0; + obj->props = NULL; + + return obj; +} + + +void +js_vm_object_mark (JSObject *obj) +{ + int i; + unsigned int num_objects; + + if (obj == NULL) + return; + + tail_recursive: + + if (!js_vm_mark_ptr (obj)) + /* This object has already been marked. Nothing to do here. */ + return; + + js_vm_mark_ptr (obj->props); + + /* Mark property hash. */ + if (obj->hash) + { + JSObjectPropHashBucket *b; + int i; + + js_vm_mark_ptr (obj->hash); + js_vm_mark_ptr (obj->hash_lengths); + + for (i = 0; i < HASH_SIZE; i++) + for (b = obj->hash[i]; b; b = b->next) + { + js_vm_mark_ptr (b); + js_vm_mark_ptr (b->data); + } + } + + /* Mark all non-object properties. */ + num_objects = 0; + for (i = 0; i < obj->num_props; i++) + { + if (obj->props[i].value.type == JS_OBJECT) + { + if (!js_vm_is_marked_ptr (obj->props[i].value.u.vobject)) + num_objects++; + } + else + js_vm_mark (&obj->props[i].value); + } + + /* And finally, mark all objects we have left. */ + if (num_objects > 0) + { + /* Find the objects. */ + for (i = 0; i < obj->num_props; i++) + if (obj->props[i].value.type == JS_OBJECT + && !js_vm_is_marked_ptr (obj->props[i].value.u.vobject)) + { + if (num_objects == 1) + { + /* + * Hahaa, this is the only non-marked object. We can + * do a tail-recursion optimization. + */ + obj = obj->props[i].value.u.vobject; + goto tail_recursive; + } + + /* Just mark it. */ + js_vm_mark (&obj->props[i].value); + } + } +} + + +int +js_vm_object_load_property (JSVirtualMachine *vm, JSObject *obj, + JSSymbol prop, JSNode *value_return) +{ + unsigned int ui; + JSSymbol link_sym = vm->syms.s___proto__; + JSObject *link_obj = NULL; + +follow_link: + + /* Check if we know this property. */ + for (ui = 0; ui < obj->num_props; ui++) + if (obj->props[ui].name == prop) + { + JS_COPY (value_return, &obj->props[ui].value); + return JS_PROPERTY_FOUND; + } + else if (obj->props[ui].name == link_sym + && obj->props[ui].value.type == JS_OBJECT) + link_obj = obj->props[ui].value.u.vobject; + + /* Undefined so far. */ + if (link_obj) + { + /* Follow the link. */ + obj = link_obj; + + link_obj = NULL; + goto follow_link; + } + + /* Undefined. Make it undef. */ + value_return->type = JS_UNDEFINED; + return JS_PROPERTY_UNKNOWN; +} + + +void +js_vm_object_store_property (JSVirtualMachine *vm, JSObject *obj, + JSSymbol prop, JSNode *val) +{ + unsigned int ui; + JSSymbol free_slot = JS_SYMBOL_NULL; + + /* Check if we already know this property. */ + for (ui = 0; ui < obj->num_props; ui++) + if (obj->props[ui].name == prop) + { + JS_COPY (&obj->props[ui].value, val); + return; + } + else if (obj->props[ui].name == JS_SYMBOL_NULL) + free_slot = ui; + + /* Must create a new property. */ + + if (free_slot == JS_SYMBOL_NULL) + { + /* Expand our array of properties. */ + obj->props = js_vm_realloc (vm, obj->props, + (obj->num_props + 1) * sizeof (JSProperty)); + free_slot = obj->num_props++; + } + + obj->props[free_slot].name = prop; + obj->props[free_slot].attributes = 0; + JS_COPY (&obj->props[free_slot].value, val); + + /* Insert it to the hash (if the hash has been created). */ + if (obj->hash) + { + const char *name; + + name = js_vm_symname (vm, prop); + hash_insert (vm, obj, name, strlen (name), free_slot); + } +} + + +void +js_vm_object_delete_property (JSVirtualMachine *vm, JSObject *obj, + JSSymbol prop) +{ + unsigned int ui; + + /* Check if we already know this property. */ + for (ui = 0; ui < obj->num_props; ui++) + if (obj->props[ui].name == prop) + { + /* Found, remove it from our list of properties. */ + obj->props[ui].name = JS_SYMBOL_NULL; + obj->props[ui].value.type = JS_UNDEFINED; + + /* Remove its name from the hash (if present). */ + if (obj->hash) + { + const char *name = js_vm_symname (vm, prop); + hash_delete (vm, obj, name, strlen (name)); + } + + /* All done here. */ + return; + } +} + + +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); + } +} + + +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 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); + } +} + + +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); + } +} + + +int +js_vm_object_nth (JSVirtualMachine *vm, JSObject *obj, int nth, + JSNode *value_return) +{ + int i; + JSObjectPropHashBucket *b; + + value_return->type = JS_UNDEFINED; + + if (nth < 0) + return 0; + + if (obj->hash == NULL) + hash_create (vm, obj); + + for (i = 0; i < HASH_SIZE && nth >= obj->hash_lengths[i]; i++) + nth -= obj->hash_lengths[i]; + + if (i >= HASH_SIZE) + return 0; + + /* The chain is the correct one. */ + for (b = obj->hash[i]; b && nth > 0; b = b->next, nth--) + ; + if (b == NULL) + { + char buf[512]; + + sprintf (buf, + "js_vm_object_nth(): chain didn't contain that many items%s", + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); + + abort (); + } + + js_vm_make_string (vm, value_return, b->data, b->len); + + return 1; +} + + +/* + * Static functions. + */ + +static void +hash_create (JSVirtualMachine *vm, JSObject *obj) +{ + int i; + + obj->hash = js_vm_alloc (vm, HASH_SIZE * sizeof (JSObjectPropHashBucket *)); + memset (obj->hash, 0, HASH_SIZE * sizeof (JSObjectPropHashBucket *)); + + obj->hash_lengths = js_vm_alloc (vm, HASH_SIZE * sizeof (unsigned int)); + memset (obj->hash_lengths, 0, HASH_SIZE * sizeof (unsigned int)); + + /* Insert all known properties to the hash. */ + for (i = 0; i < obj->num_props; i++) + if (obj->props[i].name != JS_SYMBOL_NULL) + { + const char *name; + + name = js_vm_symname (vm, obj->props[i].name); + hash_insert (vm, obj, name, strlen (name), i); + } +} + + +static void +hash_insert (JSVirtualMachine *vm, JSObject *obj, const char *name, + unsigned int name_len, int pos) +{ + unsigned int hash; + JSObjectPropHashBucket *b; + + hash = js_count_hash (name, name_len) % HASH_SIZE; + for (b = obj->hash[hash]; b; b = b->next) + if (b->len == name_len + && memcmp (b->data, name, name_len) == 0) + { + /* Ok, we already have a bucket */ + b->value = pos; + return; + } + + /* Create a new bucket. */ + b = js_vm_alloc (vm, sizeof (*b)); + b->len = name_len; + b->data = js_vm_alloc (vm, b->len); + memcpy (b->data, name, b->len); + + b->value = pos; + + b->next = obj->hash[hash]; + obj->hash[hash] = b; + + obj->hash_lengths[hash]++; +} + + +static void +hash_delete (JSVirtualMachine *vm, JSObject *obj, const char *name, + unsigned int name_len) +{ + unsigned int hash; + JSObjectPropHashBucket *b, *prev; + + hash = js_count_hash (name, name_len) % HASH_SIZE; + for (prev = NULL, b = obj->hash[hash]; b; prev = b, b = b->next) + if (b->len == name_len + && memcmp (b->data, name, name_len) == 0) + { + /* Ok, found it. */ + if (prev) + prev->next = b->next; + else + obj->hash[hash] = b->next; + + obj->hash_lengths[hash]--; + + break; + } +} + + +static int +hash_lookup (JSObject *obj, char *name, unsigned int name_len) +{ + unsigned int hash; + JSObjectPropHashBucket *b; + + hash = js_count_hash (name, name_len) % HASH_SIZE; + for (b = obj->hash[hash]; b; b = b->next) + if (b->len == name_len + && memcmp (b->data, name, name_len) == 0) + return b->value; + + return -1; +} diff --git a/reactos/lib/kjs/ksrc/regex.c b/reactos/lib/kjs/ksrc/regex.c new file mode 100644 index 00000000000..7106d35da4b --- /dev/null +++ b/reactos/lib/kjs/ksrc/regex.c @@ -0,0 +1,5870 @@ +/* This is a modified version of the GNU C Library regular expression + matching library. It is modified to meet the requirements the NGS + JS interpreter has for its extension functions (re-entrancy, etc.). + All modifications are isolated with `JS' defines. You can enable + the original features by defining the pre-processor constant JS to + value 0. */ +#define JS 1 + +/* Extended regular expression matching and search library, + version 0.12. + (Implements POSIX draft P1003.2/D11.2, except for some of the + internationalization features.) + Copyright (C) 1993, 94, 95, 96, 97, 98 Free Software Foundation, Inc. + + The GNU C 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. + + The GNU C 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 the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* AIX requires this to be the first thing in the file. */ +#if defined _AIX && !defined REGEX_MALLOC + #pragma alloca +#endif + +#undef _GNU_SOURCE +#define _GNU_SOURCE + +#if JS +#include +#else /* not JS */ +#ifdef HAVE_CONFIG_H +# include +#endif +#endif /* not JS */ + +#ifndef PARAMS +# if defined __GNUC__ || (defined __STDC__ && __STDC__) +# define PARAMS(args) args +# else +# define PARAMS(args) () +# endif /* GCC. */ +#endif /* Not PARAMS. */ + +#if defined STDC_HEADERS && !defined emacs +# include +#else +/* We need this for `regex.h', and perhaps for the Emacs include files. */ +# include +#endif + +#define WIDE_CHAR_SUPPORT (HAVE_WCTYPE_H && HAVE_WCHAR_H && HAVE_BTOWC) + +/* For platform which support the ISO C amendement 1 functionality we + support user defined character classes. */ +#if defined _LIBC || WIDE_CHAR_SUPPORT +/* Solaris 2.5 has a bug: must be included before . */ +# include +# include +#endif + +extern void js_free( void * ); +extern void *js_realloc( void *, int ); +extern void *js_malloc( int ); + +#define realloc js_realloc +#define malloc js_malloc +#define free js_free + +#ifdef _LIBC +/* We have to keep the namespace clean. */ +# define regfree(preg) __regfree (preg) +# define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef) +# define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags) +# define regerror(errcode, preg, errbuf, errbuf_size) \ + __regerror(errcode, preg, errbuf, errbuf_size) +# define re_set_registers(bu, re, nu, st, en) \ + __re_set_registers (bu, re, nu, st, en) +# define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \ + __re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) +# define re_match(bufp, string, size, pos, regs) \ + __re_match (bufp, string, size, pos, regs) +# define re_search(bufp, string, size, startpos, range, regs) \ + __re_search (bufp, string, size, startpos, range, regs) +# define re_compile_pattern(pattern, length, bufp) \ + __re_compile_pattern (pattern, length, bufp) +# define re_set_syntax(syntax) __re_set_syntax (syntax) +# define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \ + __re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop) +# define re_compile_fastmap(bufp) __re_compile_fastmap (bufp) + +#define btowc __btowc +#endif + +/* This is for other GNU distributions with internationalized messages. */ +#if HAVE_LIBINTL_H || defined _LIBC +# include +#else +# define gettext(msgid) (msgid) +#endif + +#ifndef gettext_noop +/* This define is so xgettext can find the internationalizable + strings. */ +# define gettext_noop(String) String +#endif + +/* The `emacs' switch turns on certain matching commands + that make sense only in Emacs. */ +#ifdef emacs + +# include "lisp.h" +# include "buffer.h" +# include "syntax.h" + +#else /* not emacs */ + +/* If we are not linking with Emacs proper, + we can't use the relocating allocator + even if config.h says that we can. */ +# undef REL_ALLOC + +# if defined STDC_HEADERS || defined _LIBC +# include +# else +char *malloc (); +char *realloc (); +# endif + +/* When used in Emacs's lib-src, we need to get bzero and bcopy somehow. + If nothing else has been done, use the method below. */ +# ifdef INHIBIT_STRING_HEADER +# if !(defined HAVE_BZERO && defined HAVE_BCOPY) +# if !defined bzero && !defined bcopy +# undef INHIBIT_STRING_HEADER +# endif +# endif +# endif + +/* This is the normal way of making sure we have a bcopy and a bzero. + This is used in most programs--a few other programs avoid this + by defining INHIBIT_STRING_HEADER. */ +# ifndef INHIBIT_STRING_HEADER +# if defined HAVE_STRING_H || defined STDC_HEADERS || defined _LIBC +# include +# ifndef bzero +# ifndef _LIBC +# define bzero(s, n) (memset (s, '\0', n), (s)) +# else +# define bzero(s, n) __bzero (s, n) +# endif +# endif +# else +# include +# ifndef memcmp +# define memcmp(s1, s2, n) bcmp (s1, s2, n) +# endif +# ifndef memcpy +# define memcpy(d, s, n) (bcopy (s, d, n), (d)) +# endif +# endif +# endif + +/* Define the syntax stuff for \<, \>, etc. */ + +/* This must be nonzero for the wordchar and notwordchar pattern + commands in re_match_2. */ +# ifndef Sword +# define Sword 1 +# endif + +# ifdef SWITCH_ENUM_BUG +# define SWITCH_ENUM_CAST(x) ((int)(x)) +# else +# define SWITCH_ENUM_CAST(x) (x) +# endif + +/* How many characters in the character set. */ +# define CHAR_SET_SIZE 256 + +# ifdef SYNTAX_TABLE + +extern char *re_syntax_table; + +# else /* not SYNTAX_TABLE */ + +#if JS +static char re_syntax_table[CHAR_SET_SIZE] = +{ +/* + 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 - 0x0f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x2f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3f */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50 - 0x5f */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70 - 0x7f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 - 0xaf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 - 0xbf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 - 0xcf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 - 0xdf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 - 0xef */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xf0 - 0xff */ +}; + +static void +init_syntax_once () +{ + /* Nothing here. */ +} +#else /* not JS */ +static char re_syntax_table[CHAR_SET_SIZE]; + +static void +init_syntax_once () +{ + register int c; + static int done = 0; + + if (done) + return; + + bzero (re_syntax_table, sizeof re_syntax_table); + + for (c = 'a'; c <= 'z'; c++) + re_syntax_table[c] = Sword; + + for (c = 'A'; c <= 'Z'; c++) + re_syntax_table[c] = Sword; + + for (c = '0'; c <= '9'; c++) + re_syntax_table[c] = Sword; + + re_syntax_table['_'] = Sword; + + done = 1; +} +#endif /* not JS */ + +# endif /* not SYNTAX_TABLE */ + +# define SYNTAX(c) re_syntax_table[c] + +#endif /* not emacs */ + +/* Get the interface, including the syntax bits. */ +#include "regex.h" + +/* isalpha etc. are used for the character classes. */ +#include + +/* Jim Meyering writes: + + "... Some ctype macros are valid only for character codes that + isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when + using /bin/cc or gcc but without giving an ansi option). So, all + ctype uses should be through macros like ISPRINT... If + STDC_HEADERS is defined, then autoconf has verified that the ctype + macros don't need to be guarded with references to isascii. ... + Defining isascii to 1 should let any compiler worth its salt + eliminate the && through constant folding." + Solaris defines some of these symbols so we must undefine them first. */ + +#undef ISASCII +#if defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII) +# define ISASCII(c) 1 +#else +# define ISASCII(c) isascii(c) +#endif + +#ifdef isblank +# define ISBLANK(c) (ISASCII (c) && isblank (c)) +#else +# define ISBLANK(c) ((c) == ' ' || (c) == '\t') +#endif +#ifdef isgraph +# define ISGRAPH(c) (ISASCII (c) && isgraph (c)) +#else +# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c)) +#endif + +#undef ISPRINT +#define ISPRINT(c) (ISASCII (c) && isprint (c)) +#define ISDIGIT(c) (ISASCII (c) && isdigit (c)) +#define ISALNUM(c) (ISASCII (c) && isalnum (c)) +#define ISALPHA(c) (ISASCII (c) && isalpha (c)) +#define ISCNTRL(c) (ISASCII (c) && iscntrl (c)) +#define ISLOWER(c) (ISASCII (c) && islower (c)) +#define ISPUNCT(c) (ISASCII (c) && ispunct (c)) +#define ISSPACE(c) (ISASCII (c) && isspace (c)) +#define ISUPPER(c) (ISASCII (c) && isupper (c)) +#define ISXDIGIT(c) (ISASCII (c) && isxdigit (c)) + +#ifndef NULL +# define NULL (void *)0 +#endif + +/* We remove any previous definition of `SIGN_EXTEND_CHAR', + since ours (we hope) works properly with all combinations of + machines, compilers, `char' and `unsigned char' argument types. + (Per Bothner suggested the basic approach.) */ +#undef SIGN_EXTEND_CHAR +#if __STDC__ +# define SIGN_EXTEND_CHAR(c) ((signed char) (c)) +#else /* not __STDC__ */ +/* As in Harbison and Steele. */ +# define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128) +#endif + +/* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we + use `alloca' instead of `malloc'. This is because using malloc in + re_search* or re_match* could cause memory leaks when C-g is used in + Emacs; also, malloc is slower and causes storage fragmentation. On + the other hand, malloc is more portable, and easier to debug. + + Because we sometimes use alloca, some routines have to be macros, + not functions -- `alloca'-allocated space disappears at the end of the + function it is called in. */ + +#ifdef REGEX_MALLOC + +# define REGEX_ALLOCATE js_malloc +# define REGEX_REALLOCATE(source, osize, nsize) js_realloc (source, nsize) +# define REGEX_FREE js_free + +#else /* not REGEX_MALLOC */ + +/* Emacs already defines alloca, sometimes. */ +# ifndef alloca + +/* Make alloca work the best possible way. */ +# ifdef __GNUC__ +# define alloca __builtin_alloca +# else /* not __GNUC__ */ +# if HAVE_ALLOCA_H +# include +# endif /* HAVE_ALLOCA_H */ +# endif /* not __GNUC__ */ + +# endif /* not alloca */ + +# define REGEX_ALLOCATE alloca + +/* Assumes a `char *destination' variable. */ +# define REGEX_REALLOCATE(source, osize, nsize) \ + (destination = (char *) alloca (nsize), \ + memcpy (destination, source, osize)) + +/* No need to do anything to free, after alloca. */ +# define REGEX_FREE(arg) ((void)0) /* Do nothing! But inhibit gcc warning. */ + +#endif /* not REGEX_MALLOC */ + +/* Define how to allocate the failure stack. */ + +#if defined REL_ALLOC && defined REGEX_MALLOC + +# define REGEX_ALLOCATE_STACK(size) \ + r_alloc (&failure_stack_ptr, (size)) +# define REGEX_REALLOCATE_STACK(source, osize, nsize) \ + r_re_alloc (&failure_stack_ptr, (nsize)) +# define REGEX_FREE_STACK(ptr) \ + r_alloc_free (&failure_stack_ptr) + +#else /* not using relocating allocator */ + +# ifdef REGEX_MALLOC + +# define REGEX_ALLOCATE_STACK malloc +# define REGEX_REALLOCATE_STACK(source, osize, nsize) realloc (source, nsize) +# define REGEX_FREE_STACK free + +# else /* not REGEX_MALLOC */ + +# define REGEX_ALLOCATE_STACK alloca + +# define REGEX_REALLOCATE_STACK(source, osize, nsize) \ + REGEX_REALLOCATE (source, osize, nsize) +/* No need to explicitly free anything. */ +# define REGEX_FREE_STACK(arg) + +# endif /* not REGEX_MALLOC */ +#endif /* not using relocating allocator */ + + +/* True if `size1' is non-NULL and PTR is pointing anywhere inside + `string1' or just past its end. This works if PTR is NULL, which is + a good thing. */ +#define FIRST_STRING_P(ptr) \ + (size1 && string1 <= (ptr) && (ptr) <= string1 + size1) + +/* (Re)Allocate N items of type T using malloc, or fail. */ +#define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t))) +#define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t))) +#define RETALLOC_IF(addr, n, t) \ + if (addr) RETALLOC((addr), (n), t); else (addr) = TALLOC ((n), t) +#define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t))) + +#define BYTEWIDTH 8 /* In bits. */ + +#define STREQ(s1, s2) ((strcmp (s1, s2) == 0)) + +#undef MAX +#undef MIN +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +typedef char boolean; +#define false 0 +#define true 1 + +static int re_match_2_internal PARAMS ((struct re_pattern_buffer *bufp, + const char *string1, int size1, + const char *string2, int size2, + int pos, + struct re_registers *regs, + int stop)); + +/* These are the command codes that appear in compiled regular + expressions. Some opcodes are followed by argument bytes. A + command code can specify any interpretation whatsoever for its + arguments. Zero bytes may appear in the compiled regular expression. */ + +typedef enum +{ + no_op = 0, + + /* Succeed right away--no more backtracking. */ + succeed, + + /* Followed by one byte giving n, then by n literal bytes. */ + exactn, + + /* Matches any (more or less) character. */ + anychar, + + /* Matches any one char belonging to specified set. First + following byte is number of bitmap bytes. Then come bytes + for a bitmap saying which chars are in. Bits in each byte + are ordered low-bit-first. A character is in the set if its + bit is 1. A character too large to have a bit in the map is + automatically not in the set. */ + charset, + + /* Same parameters as charset, but match any character that is + not one of those specified. */ + charset_not, + + /* Start remembering the text that is matched, for storing in a + register. Followed by one byte with the register number, in + the range 0 to one less than the pattern buffer's re_nsub + field. Then followed by one byte with the number of groups + inner to this one. (This last has to be part of the + start_memory only because we need it in the on_failure_jump + of re_match_2.) */ + start_memory, + + /* Stop remembering the text that is matched and store it in a + memory register. Followed by one byte with the register + number, in the range 0 to one less than `re_nsub' in the + pattern buffer, and one byte with the number of inner groups, + just like `start_memory'. (We need the number of inner + groups here because we don't have any easy way of finding the + corresponding start_memory when we're at a stop_memory.) */ + stop_memory, + + /* Match a duplicate of something remembered. Followed by one + byte containing the register number. */ + duplicate, + + /* Fail unless at beginning of line. */ + begline, + + /* Fail unless at end of line. */ + endline, + + /* Succeeds if at beginning of buffer (if emacs) or at beginning + of string to be matched (if not). */ + begbuf, + + /* Analogously, for end of buffer/string. */ + endbuf, + + /* Followed by two byte relative address to which to jump. */ + jump, + + /* Same as jump, but marks the end of an alternative. */ + jump_past_alt, + + /* Followed by two-byte relative address of place to resume at + in case of failure. */ + on_failure_jump, + + /* Like on_failure_jump, but pushes a placeholder instead of the + current string position when executed. */ + on_failure_keep_string_jump, + + /* Throw away latest failure point and then jump to following + two-byte relative address. */ + pop_failure_jump, + + /* Change to pop_failure_jump if know won't have to backtrack to + match; otherwise change to jump. This is used to jump + back to the beginning of a repeat. If what follows this jump + clearly won't match what the repeat does, such that we can be + sure that there is no use backtracking out of repetitions + already matched, then we change it to a pop_failure_jump. + Followed by two-byte address. */ + maybe_pop_jump, + + /* Jump to following two-byte address, and push a dummy failure + point. This failure point will be thrown away if an attempt + is made to use it for a failure. A `+' construct makes this + before the first repeat. Also used as an intermediary kind + of jump when compiling an alternative. */ + dummy_failure_jump, + + /* Push a dummy failure point and continue. Used at the end of + alternatives. */ + push_dummy_failure, + + /* Followed by two-byte relative address and two-byte number n. + After matching N times, jump to the address upon failure. */ + succeed_n, + + /* Followed by two-byte relative address, and two-byte number n. + Jump to the address N times, then fail. */ + jump_n, + + /* Set the following two-byte relative address to the + subsequent two-byte number. The address *includes* the two + bytes of number. */ + set_number_at, + + wordchar, /* Matches any word-constituent character. */ + notwordchar, /* Matches any char that is not a word-constituent. */ + + wordbeg, /* Succeeds if at word beginning. */ + wordend, /* Succeeds if at word end. */ + + wordbound, /* Succeeds if at a word boundary. */ + notwordbound /* Succeeds if not at a word boundary. */ + +#ifdef emacs + ,before_dot, /* Succeeds if before point. */ + at_dot, /* Succeeds if at point. */ + after_dot, /* Succeeds if after point. */ + + /* Matches any character whose syntax is specified. Followed by + a byte which contains a syntax code, e.g., Sword. */ + syntaxspec, + + /* Matches any character whose syntax is not that specified. */ + notsyntaxspec +#endif /* emacs */ +} re_opcode_t; + +/* Common operations on the compiled pattern. */ + +/* Store NUMBER in two contiguous bytes starting at DESTINATION. */ + +#define STORE_NUMBER(destination, number) \ + do { \ + (destination)[0] = (number) & 0377; \ + (destination)[1] = (number) >> 8; \ + } while (0) + +/* Same as STORE_NUMBER, except increment DESTINATION to + the byte after where the number is stored. Therefore, DESTINATION + must be an lvalue. */ + +#define STORE_NUMBER_AND_INCR(destination, number) \ + do { \ + STORE_NUMBER (destination, number); \ + (destination) += 2; \ + } while (0) + +/* Put into DESTINATION a number stored in two contiguous bytes starting + at SOURCE. */ + +#define EXTRACT_NUMBER(destination, source) \ + do { \ + (destination) = *(source) & 0377; \ + (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \ + } while (0) + +#ifdef DEBUG +static void extract_number _RE_ARGS ((int *dest, unsigned char *source)); +static void +extract_number (dest, source) + int *dest; + unsigned char *source; +{ + int temp = SIGN_EXTEND_CHAR (*(source + 1)); + *dest = *source & 0377; + *dest += temp << 8; +} + +# ifndef EXTRACT_MACROS /* To debug the macros. */ +# undef EXTRACT_NUMBER +# define EXTRACT_NUMBER(dest, src) extract_number (&dest, src) +# endif /* not EXTRACT_MACROS */ + +#endif /* DEBUG */ + +/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number. + SOURCE must be an lvalue. */ + +#define EXTRACT_NUMBER_AND_INCR(destination, source) \ + do { \ + EXTRACT_NUMBER (destination, source); \ + (source) += 2; \ + } while (0) + +#ifdef DEBUG +static void extract_number_and_incr _RE_ARGS ((int *destination, + unsigned char **source)); +static void +extract_number_and_incr (destination, source) + int *destination; + unsigned char **source; +{ + extract_number (destination, *source); + *source += 2; +} + +# ifndef EXTRACT_MACROS +# undef EXTRACT_NUMBER_AND_INCR +# define EXTRACT_NUMBER_AND_INCR(dest, src) \ + extract_number_and_incr (&dest, &src) +# endif /* not EXTRACT_MACROS */ + +#endif /* DEBUG */ + +/* If DEBUG is defined, Regex prints many voluminous messages about what + it is doing (if the variable `debug' is nonzero). If linked with the + main program in `iregex.c', you can enter patterns and strings + interactively. And if linked with the main program in `main.c' and + the other test files, you can run the already-written tests. */ + +#ifdef DEBUG + +/* We use standard I/O for debugging. */ +# include + +/* It is useful to test things that ``must'' be true when debugging. */ +# include + +static int debug = 0; + +# define DEBUG_STATEMENT(e) e +# define DEBUG_PRINT1(x) if (debug) printf (x) +# define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2) +# define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3) +# define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4) +# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \ + if (debug) print_partial_compiled_pattern (s, e) +# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \ + if (debug) print_double_string (w, s1, sz1, s2, sz2) + + +/* Print the fastmap in human-readable form. */ + +void +print_fastmap (fastmap) + char *fastmap; +{ + unsigned was_a_range = 0; + unsigned i = 0; + + while (i < (1 << BYTEWIDTH)) + { + if (fastmap[i++]) + { + was_a_range = 0; + putchar (i - 1); + while (i < (1 << BYTEWIDTH) && fastmap[i]) + { + was_a_range = 1; + i++; + } + if (was_a_range) + { + printf ("-"); + putchar (i - 1); + } + } + } + putchar ('\n'); +} + + +/* Print a compiled pattern string in human-readable form, starting at + the START pointer into it and ending just before the pointer END. */ + +void +print_partial_compiled_pattern (start, end) + unsigned char *start; + unsigned char *end; +{ + int mcnt, mcnt2; + unsigned char *p1; + unsigned char *p = start; + unsigned char *pend = end; + + if (start == NULL) + { + printf ("(null)\n"); + return; + } + + /* Loop over pattern commands. */ + while (p < pend) + { + printf ("%d:\t", p - start); + + switch ((re_opcode_t) *p++) + { + case no_op: + printf ("/no_op"); + break; + + case exactn: + mcnt = *p++; + printf ("/exactn/%d", mcnt); + do + { + putchar ('/'); + putchar (*p++); + } + while (--mcnt); + break; + + case start_memory: + mcnt = *p++; + printf ("/start_memory/%d/%d", mcnt, *p++); + break; + + case stop_memory: + mcnt = *p++; + printf ("/stop_memory/%d/%d", mcnt, *p++); + break; + + case duplicate: + printf ("/duplicate/%d", *p++); + break; + + case anychar: + printf ("/anychar"); + break; + + case charset: + case charset_not: + { + register int c, last = -100; + register int in_range = 0; + + printf ("/charset [%s", + (re_opcode_t) *(p - 1) == charset_not ? "^" : ""); + + assert (p + *p < pend); + + for (c = 0; c < 256; c++) + if (c / 8 < *p + && (p[1 + (c/8)] & (1 << (c % 8)))) + { + /* Are we starting a range? */ + if (last + 1 == c && ! in_range) + { + putchar ('-'); + in_range = 1; + } + /* Have we broken a range? */ + else if (last + 1 != c && in_range) + { + putchar (last); + in_range = 0; + } + + if (! in_range) + putchar (c); + + last = c; + } + + if (in_range) + putchar (last); + + putchar (']'); + + p += 1 + *p; + } + break; + + case begline: + printf ("/begline"); + break; + + case endline: + printf ("/endline"); + break; + + case on_failure_jump: + extract_number_and_incr (&mcnt, &p); + printf ("/on_failure_jump to %d", p + mcnt - start); + break; + + case on_failure_keep_string_jump: + extract_number_and_incr (&mcnt, &p); + printf ("/on_failure_keep_string_jump to %d", p + mcnt - start); + break; + + case dummy_failure_jump: + extract_number_and_incr (&mcnt, &p); + printf ("/dummy_failure_jump to %d", p + mcnt - start); + break; + + case push_dummy_failure: + printf ("/push_dummy_failure"); + break; + + case maybe_pop_jump: + extract_number_and_incr (&mcnt, &p); + printf ("/maybe_pop_jump to %d", p + mcnt - start); + break; + + case pop_failure_jump: + extract_number_and_incr (&mcnt, &p); + printf ("/pop_failure_jump to %d", p + mcnt - start); + break; + + case jump_past_alt: + extract_number_and_incr (&mcnt, &p); + printf ("/jump_past_alt to %d", p + mcnt - start); + break; + + case jump: + extract_number_and_incr (&mcnt, &p); + printf ("/jump to %d", p + mcnt - start); + break; + + case succeed_n: + extract_number_and_incr (&mcnt, &p); + p1 = p + mcnt; + extract_number_and_incr (&mcnt2, &p); + printf ("/succeed_n to %d, %d times", p1 - start, mcnt2); + break; + + case jump_n: + extract_number_and_incr (&mcnt, &p); + p1 = p + mcnt; + extract_number_and_incr (&mcnt2, &p); + printf ("/jump_n to %d, %d times", p1 - start, mcnt2); + break; + + case set_number_at: + extract_number_and_incr (&mcnt, &p); + p1 = p + mcnt; + extract_number_and_incr (&mcnt2, &p); + printf ("/set_number_at location %d to %d", p1 - start, mcnt2); + break; + + case wordbound: + printf ("/wordbound"); + break; + + case notwordbound: + printf ("/notwordbound"); + break; + + case wordbeg: + printf ("/wordbeg"); + break; + + case wordend: + printf ("/wordend"); + +# ifdef emacs + case before_dot: + printf ("/before_dot"); + break; + + case at_dot: + printf ("/at_dot"); + break; + + case after_dot: + printf ("/after_dot"); + break; + + case syntaxspec: + printf ("/syntaxspec"); + mcnt = *p++; + printf ("/%d", mcnt); + break; + + case notsyntaxspec: + printf ("/notsyntaxspec"); + mcnt = *p++; + printf ("/%d", mcnt); + break; +# endif /* emacs */ + + case wordchar: + printf ("/wordchar"); + break; + + case notwordchar: + printf ("/notwordchar"); + break; + + case begbuf: + printf ("/begbuf"); + break; + + case endbuf: + printf ("/endbuf"); + break; + + default: + printf ("?%d", *(p-1)); + } + + putchar ('\n'); + } + + printf ("%d:\tend of pattern.\n", p - start); +} + + +void +print_compiled_pattern (bufp) + struct re_pattern_buffer *bufp; +{ + unsigned char *buffer = bufp->buffer; + + print_partial_compiled_pattern (buffer, buffer + bufp->used); + printf ("%ld bytes used/%ld bytes allocated.\n", + bufp->used, bufp->allocated); + + if (bufp->fastmap_accurate && bufp->fastmap) + { + printf ("fastmap: "); + print_fastmap (bufp->fastmap); + } + + printf ("re_nsub: %d\t", bufp->re_nsub); + printf ("regs_alloc: %d\t", bufp->regs_allocated); + printf ("can_be_null: %d\t", bufp->can_be_null); + printf ("newline_anchor: %d\n", bufp->newline_anchor); + printf ("no_sub: %d\t", bufp->no_sub); + printf ("not_bol: %d\t", bufp->not_bol); + printf ("not_eol: %d\t", bufp->not_eol); + printf ("syntax: %lx\n", bufp->syntax); + /* Perhaps we should print the translate table? */ +} + + +void +print_double_string (where, string1, size1, string2, size2) + const char *where; + const char *string1; + const char *string2; + int size1; + int size2; +{ + int this_char; + + if (where == NULL) + printf ("(null)"); + else + { + if (FIRST_STRING_P (where)) + { + for (this_char = where - string1; this_char < size1; this_char++) + putchar (string1[this_char]); + + where = string2; + } + + for (this_char = where - string2; this_char < size2; this_char++) + putchar (string2[this_char]); + } +} + +void +printchar (c) + int c; +{ + putc (c, stderr); +} + +#else /* not DEBUG */ + +# undef assert +# define assert(e) + +# define DEBUG_STATEMENT(e) +# define DEBUG_PRINT1(x) +# define DEBUG_PRINT2(x1, x2) +# define DEBUG_PRINT3(x1, x2, x3) +# define DEBUG_PRINT4(x1, x2, x3, x4) +# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) +# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) + +#endif /* not DEBUG */ + +#if JS +reg_syntax_t re_syntax_options = RE_SYNTAX_GNU_AWK; +#else /* not JS */ +/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can + also be assigned to arbitrarily: each pattern buffer stores its own + syntax, so it can be changed between regex compilations. */ +/* This has no initializer because initialized variables in Emacs + become read-only after dumping. */ +reg_syntax_t re_syntax_options; +#endif /* not JS */ + + +/* Specify the precise syntax of regexps for compilation. This provides + for compatibility for various utilities which historically have + different, incompatible syntaxes. + + The argument SYNTAX is a bit mask comprised of the various bits + defined in regex.h. We return the old syntax. */ + +reg_syntax_t +re_set_syntax (syntax) + reg_syntax_t syntax; +{ + reg_syntax_t ret = re_syntax_options; + + re_syntax_options = syntax; +#ifdef DEBUG + if (syntax & RE_DEBUG) + debug = 1; + else if (debug) /* was on but now is not */ + debug = 0; +#endif /* DEBUG */ + return ret; +} +#ifdef _LIBC +weak_alias (__re_set_syntax, re_set_syntax) +#endif + +/* This table gives an error message for each of the error codes listed + in regex.h. Obviously the order here has to be same as there. + POSIX doesn't require that we do anything for REG_NOERROR, + but why not be nice? */ + +static const char *re_error_msgid[] = + { + gettext_noop ("Success"), /* REG_NOERROR */ + gettext_noop ("No match"), /* REG_NOMATCH */ + gettext_noop ("Invalid regular expression"), /* REG_BADPAT */ + gettext_noop ("Invalid collation character"), /* REG_ECOLLATE */ + gettext_noop ("Invalid character class name"), /* REG_ECTYPE */ + gettext_noop ("Trailing backslash"), /* REG_EESCAPE */ + gettext_noop ("Invalid back reference"), /* REG_ESUBREG */ + gettext_noop ("Unmatched [ or [^"), /* REG_EBRACK */ + gettext_noop ("Unmatched ( or \\("), /* REG_EPAREN */ + gettext_noop ("Unmatched \\{"), /* REG_EBRACE */ + gettext_noop ("Invalid content of \\{\\}"), /* REG_BADBR */ + gettext_noop ("Invalid range end"), /* REG_ERANGE */ + gettext_noop ("Memory exhausted"), /* REG_ESPACE */ + gettext_noop ("Invalid preceding regular expression"), /* REG_BADRPT */ + gettext_noop ("Premature end of regular expression"), /* REG_EEND */ + gettext_noop ("Regular expression too big"), /* REG_ESIZE */ + gettext_noop ("Unmatched ) or \\)"), /* REG_ERPAREN */ + }; + +/* Avoiding alloca during matching, to placate r_alloc. */ + +/* Define MATCH_MAY_ALLOCATE unless we need to make sure that the + searching and matching functions should not call alloca. On some + systems, alloca is implemented in terms of malloc, and if we're + using the relocating allocator routines, then malloc could cause a + relocation, which might (if the strings being searched are in the + ralloc heap) shift the data out from underneath the regexp + routines. + + Here's another reason to avoid allocation: Emacs + processes input from X in a signal handler; processing X input may + call malloc; if input arrives while a matching routine is calling + malloc, then we're scrod. But Emacs can't just block input while + calling matching routines; then we don't notice interrupts when + they come in. So, Emacs blocks input around all regexp calls + except the matching calls, which it leaves unprotected, in the + faith that they will not malloc. */ + +/* Normally, this is fine. */ +#define MATCH_MAY_ALLOCATE + +/* When using GNU C, we are not REALLY using the C alloca, no matter + what config.h may say. So don't take precautions for it. */ +#ifdef __GNUC__ +# undef C_ALLOCA +#endif + +/* The match routines may not allocate if (1) they would do it with malloc + and (2) it's not safe for them to use malloc. + Note that if REL_ALLOC is defined, matching would not use malloc for the + failure stack, but we would still use it for the register vectors; + so REL_ALLOC should not affect this. */ +#if (defined C_ALLOCA || defined REGEX_MALLOC) && defined emacs +# undef MATCH_MAY_ALLOCATE +#endif + + +/* Failure stack declarations and macros; both re_compile_fastmap and + re_match_2 use a failure stack. These have to be macros because of + REGEX_ALLOCATE_STACK. */ + + +/* Number of failure points for which to initially allocate space + when matching. If this number is exceeded, we allocate more + space, so it is not a hard limit. */ +#ifndef INIT_FAILURE_ALLOC +# define INIT_FAILURE_ALLOC 5 +#endif + +/* Roughly the maximum number of failure points on the stack. Would be + exactly that if always used MAX_FAILURE_ITEMS items each time we failed. + This is a variable only so users of regex can assign to it; we never + change it ourselves. */ + +#ifdef INT_IS_16BIT + +# if defined MATCH_MAY_ALLOCATE +/* 4400 was enough to cause a crash on Alpha OSF/1, + whose default stack limit is 2mb. */ +long int re_max_failures = 4000; +# else +long int re_max_failures = 2000; +# endif + +union fail_stack_elt +{ + unsigned char *pointer; + long int integer; +}; + +typedef union fail_stack_elt fail_stack_elt_t; + +typedef struct +{ + fail_stack_elt_t *stack; + unsigned long int size; + unsigned long int avail; /* Offset of next open position. */ +} fail_stack_type; + +#else /* not INT_IS_16BIT */ + +# if defined MATCH_MAY_ALLOCATE +/* 4400 was enough to cause a crash on Alpha OSF/1, + whose default stack limit is 2mb. */ +int re_max_failures = 20000; +# else +int re_max_failures = 2000; +# endif + +union fail_stack_elt +{ + unsigned char *pointer; + int integer; +}; + +typedef union fail_stack_elt fail_stack_elt_t; + +typedef struct +{ + fail_stack_elt_t *stack; + unsigned size; + unsigned avail; /* Offset of next open position. */ +} fail_stack_type; + +#endif /* INT_IS_16BIT */ + +#define FAIL_STACK_EMPTY() (fail_stack.avail == 0) +#define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0) +#define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size) + + +/* Define macros to initialize and free the failure stack. + Do `return -2' if the alloc fails. */ + +#ifdef MATCH_MAY_ALLOCATE +# define INIT_FAIL_STACK() \ + do { \ + fail_stack.stack = (fail_stack_elt_t *) \ + REGEX_ALLOCATE_STACK (INIT_FAILURE_ALLOC * sizeof (fail_stack_elt_t)); \ + \ + if (fail_stack.stack == NULL) \ + return -2; \ + \ + fail_stack.size = INIT_FAILURE_ALLOC; \ + fail_stack.avail = 0; \ + } while (0) + +# define RESET_FAIL_STACK() REGEX_FREE_STACK (fail_stack.stack) +#else +# define INIT_FAIL_STACK() \ + do { \ + fail_stack.avail = 0; \ + } while (0) + +# define RESET_FAIL_STACK() +#endif + + +/* Double the size of FAIL_STACK, up to approximately `re_max_failures' items. + + Return 1 if succeeds, and 0 if either ran out of memory + allocating space for it or it was already too large. + + REGEX_REALLOCATE_STACK requires `destination' be declared. */ + +#define DOUBLE_FAIL_STACK(fail_stack) \ + ((fail_stack).size > (unsigned) (re_max_failures * MAX_FAILURE_ITEMS) \ + ? 0 \ + : ((fail_stack).stack = (fail_stack_elt_t *) \ + REGEX_REALLOCATE_STACK ((fail_stack).stack, \ + (fail_stack).size * sizeof (fail_stack_elt_t), \ + ((fail_stack).size << 1) * sizeof (fail_stack_elt_t)), \ + \ + (fail_stack).stack == NULL \ + ? 0 \ + : ((fail_stack).size <<= 1, \ + 1))) + + +/* Push pointer POINTER on FAIL_STACK. + Return 1 if was able to do so and 0 if ran out of memory allocating + space to do so. */ +#define PUSH_PATTERN_OP(POINTER, FAIL_STACK) \ + ((FAIL_STACK_FULL () \ + && !DOUBLE_FAIL_STACK (FAIL_STACK)) \ + ? 0 \ + : ((FAIL_STACK).stack[(FAIL_STACK).avail++].pointer = POINTER, \ + 1)) + +/* Push a pointer value onto the failure stack. + Assumes the variable `fail_stack'. Probably should only + be called from within `PUSH_FAILURE_POINT'. */ +#define PUSH_FAILURE_POINTER(item) \ + fail_stack.stack[fail_stack.avail++].pointer = (unsigned char *) (item) + +/* This pushes an integer-valued item onto the failure stack. + Assumes the variable `fail_stack'. Probably should only + be called from within `PUSH_FAILURE_POINT'. */ +#define PUSH_FAILURE_INT(item) \ + fail_stack.stack[fail_stack.avail++].integer = (item) + +/* Push a fail_stack_elt_t value onto the failure stack. + Assumes the variable `fail_stack'. Probably should only + be called from within `PUSH_FAILURE_POINT'. */ +#define PUSH_FAILURE_ELT(item) \ + fail_stack.stack[fail_stack.avail++] = (item) + +/* These three POP... operations complement the three PUSH... operations. + All assume that `fail_stack' is nonempty. */ +#define POP_FAILURE_POINTER() fail_stack.stack[--fail_stack.avail].pointer +#define POP_FAILURE_INT() fail_stack.stack[--fail_stack.avail].integer +#define POP_FAILURE_ELT() fail_stack.stack[--fail_stack.avail] + +/* Used to omit pushing failure point id's when we're not debugging. */ +#ifdef DEBUG +# define DEBUG_PUSH PUSH_FAILURE_INT +# define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_INT () +#else +# define DEBUG_PUSH(item) +# define DEBUG_POP(item_addr) +#endif + + +/* Push the information about the state we will need + if we ever fail back to it. + + Requires variables fail_stack, regstart, regend, reg_info, and + num_regs_pushed be declared. DOUBLE_FAIL_STACK requires `destination' + be declared. + + Does `return FAILURE_CODE' if runs out of memory. */ + +#define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code) \ + do { \ + char *destination; \ + /* Must be int, so when we don't save any registers, the arithmetic \ + of 0 + -1 isn't done as unsigned. */ \ + /* Can't be int, since there is not a shred of a guarantee that int \ + is wide enough to hold a value of something to which pointer can \ + be assigned */ \ + active_reg_t this_reg; \ + \ + DEBUG_STATEMENT (failure_id++); \ + DEBUG_STATEMENT (nfailure_points_pushed++); \ + DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \ + DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail);\ + DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\ + \ + DEBUG_PRINT2 (" slots needed: %ld\n", NUM_FAILURE_ITEMS); \ + DEBUG_PRINT2 (" available: %d\n", REMAINING_AVAIL_SLOTS); \ + \ + /* Ensure we have enough space allocated for what we will push. */ \ + while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \ + { \ + if (!DOUBLE_FAIL_STACK (fail_stack)) \ + return failure_code; \ + \ + DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \ + (fail_stack).size); \ + DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\ + } \ + \ + /* Push the info, starting with the registers. */ \ + DEBUG_PRINT1 ("\n"); \ + \ + if (1) \ + for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \ + this_reg++) \ + { \ + DEBUG_PRINT2 (" Pushing reg: %lu\n", this_reg); \ + DEBUG_STATEMENT (num_regs_pushed++); \ + \ + DEBUG_PRINT2 (" start: %p\n", regstart[this_reg]); \ + PUSH_FAILURE_POINTER (regstart[this_reg]); \ + \ + DEBUG_PRINT2 (" end: %p\n", regend[this_reg]); \ + PUSH_FAILURE_POINTER (regend[this_reg]); \ + \ + DEBUG_PRINT2 (" info: %p\n ", \ + reg_info[this_reg].word.pointer); \ + DEBUG_PRINT2 (" match_null=%d", \ + REG_MATCH_NULL_STRING_P (reg_info[this_reg])); \ + DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg])); \ + DEBUG_PRINT2 (" matched_something=%d", \ + MATCHED_SOMETHING (reg_info[this_reg])); \ + DEBUG_PRINT2 (" ever_matched=%d", \ + EVER_MATCHED_SOMETHING (reg_info[this_reg])); \ + DEBUG_PRINT1 ("\n"); \ + PUSH_FAILURE_ELT (reg_info[this_reg].word); \ + } \ + \ + DEBUG_PRINT2 (" Pushing low active reg: %ld\n", lowest_active_reg);\ + PUSH_FAILURE_INT (lowest_active_reg); \ + \ + DEBUG_PRINT2 (" Pushing high active reg: %ld\n", highest_active_reg);\ + PUSH_FAILURE_INT (highest_active_reg); \ + \ + DEBUG_PRINT2 (" Pushing pattern %p:\n", pattern_place); \ + DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \ + PUSH_FAILURE_POINTER (pattern_place); \ + \ + DEBUG_PRINT2 (" Pushing string %p: `", string_place); \ + DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, \ + size2); \ + DEBUG_PRINT1 ("'\n"); \ + PUSH_FAILURE_POINTER (string_place); \ + \ + DEBUG_PRINT2 (" Pushing failure id: %u\n", failure_id); \ + DEBUG_PUSH (failure_id); \ + } while (0) + +/* This is the number of items that are pushed and popped on the stack + for each register. */ +#define NUM_REG_ITEMS 3 + +/* Individual items aside from the registers. */ +#ifdef DEBUG +# define NUM_NONREG_ITEMS 5 /* Includes failure point id. */ +#else +# define NUM_NONREG_ITEMS 4 +#endif + +/* We push at most this many items on the stack. */ +/* We used to use (num_regs - 1), which is the number of registers + this regexp will save; but that was changed to 5 + to avoid stack overflow for a regexp with lots of parens. */ +#define MAX_FAILURE_ITEMS (5 * NUM_REG_ITEMS + NUM_NONREG_ITEMS) + +/* We actually push this many items. */ +#define NUM_FAILURE_ITEMS \ + (((0 \ + ? 0 : highest_active_reg - lowest_active_reg + 1) \ + * NUM_REG_ITEMS) \ + + NUM_NONREG_ITEMS) + +/* How many items can still be added to the stack without overflowing it. */ +#define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail) + + +/* Pops what PUSH_FAIL_STACK pushes. + + We restore into the parameters, all of which should be lvalues: + STR -- the saved data position. + PAT -- the saved pattern position. + LOW_REG, HIGH_REG -- the highest and lowest active registers. + REGSTART, REGEND -- arrays of string positions. + REG_INFO -- array of information about each subexpression. + + Also assumes the variables `fail_stack' and (if debugging), `bufp', + `pend', `string1', `size1', `string2', and `size2'. */ + +#define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\ +{ \ + DEBUG_STATEMENT (unsigned failure_id;) \ + active_reg_t this_reg; \ + const unsigned char *string_temp; \ + \ + assert (!FAIL_STACK_EMPTY ()); \ + \ + /* Remove failure points and point to how many regs pushed. */ \ + DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \ + DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \ + DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \ + \ + assert (fail_stack.avail >= NUM_NONREG_ITEMS); \ + \ + DEBUG_POP (&failure_id); \ + DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \ + \ + /* If the saved string location is NULL, it came from an \ + on_failure_keep_string_jump opcode, and we want to throw away the \ + saved NULL, thus retaining our current position in the string. */ \ + string_temp = POP_FAILURE_POINTER (); \ + if (string_temp != NULL) \ + str = (const char *) string_temp; \ + \ + DEBUG_PRINT2 (" Popping string %p: `", str); \ + DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \ + DEBUG_PRINT1 ("'\n"); \ + \ + pat = (unsigned char *) POP_FAILURE_POINTER (); \ + DEBUG_PRINT2 (" Popping pattern %p:\n", pat); \ + DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \ + \ + /* Restore register info. */ \ + high_reg = (active_reg_t) POP_FAILURE_INT (); \ + DEBUG_PRINT2 (" Popping high active reg: %ld\n", high_reg); \ + \ + low_reg = (active_reg_t) POP_FAILURE_INT (); \ + DEBUG_PRINT2 (" Popping low active reg: %ld\n", low_reg); \ + \ + if (1) \ + for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \ + { \ + DEBUG_PRINT2 (" Popping reg: %ld\n", this_reg); \ + \ + reg_info[this_reg].word = POP_FAILURE_ELT (); \ + DEBUG_PRINT2 (" info: %p\n", \ + reg_info[this_reg].word.pointer); \ + \ + regend[this_reg] = (const char *) POP_FAILURE_POINTER (); \ + DEBUG_PRINT2 (" end: %p\n", regend[this_reg]); \ + \ + regstart[this_reg] = (const char *) POP_FAILURE_POINTER (); \ + DEBUG_PRINT2 (" start: %p\n", regstart[this_reg]); \ + } \ + else \ + { \ + for (this_reg = highest_active_reg; this_reg > high_reg; this_reg--) \ + { \ + reg_info[this_reg].word.integer = 0; \ + regend[this_reg] = 0; \ + regstart[this_reg] = 0; \ + } \ + highest_active_reg = high_reg; \ + } \ + \ + set_regs_matched_done = 0; \ + DEBUG_STATEMENT (nfailure_points_popped++); \ +} /* POP_FAILURE_POINT */ + + + +/* Structure for per-register (a.k.a. per-group) information. + Other register information, such as the + starting and ending positions (which are addresses), and the list of + inner groups (which is a bits list) are maintained in separate + variables. + + We are making a (strictly speaking) nonportable assumption here: that + the compiler will pack our bit fields into something that fits into + the type of `word', i.e., is something that fits into one item on the + failure stack. */ + + +/* Declarations and macros for re_match_2. */ + +typedef union +{ + fail_stack_elt_t word; + struct + { + /* This field is one if this group can match the empty string, + zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */ +#define MATCH_NULL_UNSET_VALUE 3 + unsigned match_null_string_p : 2; + unsigned is_active : 1; + unsigned matched_something : 1; + unsigned ever_matched_something : 1; + } bits; +} register_info_type; + +#define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p) +#define IS_ACTIVE(R) ((R).bits.is_active) +#define MATCHED_SOMETHING(R) ((R).bits.matched_something) +#define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something) + + +/* Call this when have matched a real character; it sets `matched' flags + for the subexpressions which we are currently inside. Also records + that those subexprs have matched. */ +#define SET_REGS_MATCHED() \ + do \ + { \ + if (!set_regs_matched_done) \ + { \ + active_reg_t r; \ + set_regs_matched_done = 1; \ + for (r = lowest_active_reg; r <= highest_active_reg; r++) \ + { \ + MATCHED_SOMETHING (reg_info[r]) \ + = EVER_MATCHED_SOMETHING (reg_info[r]) \ + = 1; \ + } \ + } \ + } \ + while (0) + +/* Registers are set to a sentinel when they haven't yet matched. */ +static char reg_unset_dummy; +#define REG_UNSET_VALUE (®_unset_dummy) +#define REG_UNSET(e) ((e) == REG_UNSET_VALUE) + +/* Subroutine declarations and macros for regex_compile. */ + +static reg_errcode_t regex_compile _RE_ARGS ((const char *pattern, size_t size, + reg_syntax_t syntax, + struct re_pattern_buffer *bufp)); +static void store_op1 _RE_ARGS ((re_opcode_t op, unsigned char *loc, int arg)); +static void store_op2 _RE_ARGS ((re_opcode_t op, unsigned char *loc, + int arg1, int arg2)); +static void insert_op1 _RE_ARGS ((re_opcode_t op, unsigned char *loc, + int arg, unsigned char *end)); +static void insert_op2 _RE_ARGS ((re_opcode_t op, unsigned char *loc, + int arg1, int arg2, unsigned char *end)); +static boolean at_begline_loc_p _RE_ARGS ((const char *pattern, const char *p, + reg_syntax_t syntax)); +static boolean at_endline_loc_p _RE_ARGS ((const char *p, const char *pend, + reg_syntax_t syntax)); +static reg_errcode_t compile_range _RE_ARGS ((const char **p_ptr, + const char *pend, + char *translate, + reg_syntax_t syntax, + unsigned char *b)); + +/* Fetch the next character in the uncompiled pattern---translating it + if necessary. Also cast from a signed character in the constant + string passed to us by the user to an unsigned char that we can use + as an array index (in, e.g., `translate'). */ +#ifndef PATFETCH +# define PATFETCH(c) \ + do {if (p == pend) return REG_EEND; \ + c = (unsigned char) *p++; \ + if (translate) c = (unsigned char) translate[c]; \ + } while (0) +#endif + +/* Fetch the next character in the uncompiled pattern, with no + translation. */ +#define PATFETCH_RAW(c) \ + do {if (p == pend) return REG_EEND; \ + c = (unsigned char) *p++; \ + } while (0) + +/* Go backwards one character in the pattern. */ +#define PATUNFETCH p-- + + +/* If `translate' is non-null, return translate[D], else just D. We + cast the subscript to translate because some data is declared as + `char *', to avoid warnings when a string constant is passed. But + when we use a character as a subscript we must make it unsigned. */ +#ifndef TRANSLATE +# define TRANSLATE(d) \ + (translate ? (char) translate[(unsigned char) (d)] : (d)) +#endif + + +/* Macros for outputting the compiled pattern into `buffer'. */ + +/* If the buffer isn't allocated when it comes in, use this. */ +#define INIT_BUF_SIZE 32 + +/* Make sure we have at least N more bytes of space in buffer. */ +#define GET_BUFFER_SPACE(n) \ + while ((unsigned long) (b - bufp->buffer + (n)) > bufp->allocated) \ + EXTEND_BUFFER () + +/* Make sure we have one more byte of buffer space and then add C to it. */ +#define BUF_PUSH(c) \ + do { \ + GET_BUFFER_SPACE (1); \ + *b++ = (unsigned char) (c); \ + } while (0) + + +/* Ensure we have two more bytes of buffer space and then append C1 and C2. */ +#define BUF_PUSH_2(c1, c2) \ + do { \ + GET_BUFFER_SPACE (2); \ + *b++ = (unsigned char) (c1); \ + *b++ = (unsigned char) (c2); \ + } while (0) + + +/* As with BUF_PUSH_2, except for three bytes. */ +#define BUF_PUSH_3(c1, c2, c3) \ + do { \ + GET_BUFFER_SPACE (3); \ + *b++ = (unsigned char) (c1); \ + *b++ = (unsigned char) (c2); \ + *b++ = (unsigned char) (c3); \ + } while (0) + + +/* Store a jump with opcode OP at LOC to location TO. We store a + relative address offset by the three bytes the jump itself occupies. */ +#define STORE_JUMP(op, loc, to) \ + store_op1 (op, loc, (int) ((to) - (loc) - 3)) + +/* Likewise, for a two-argument jump. */ +#define STORE_JUMP2(op, loc, to, arg) \ + store_op2 (op, loc, (int) ((to) - (loc) - 3), arg) + +/* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */ +#define INSERT_JUMP(op, loc, to) \ + insert_op1 (op, loc, (int) ((to) - (loc) - 3), b) + +/* Like `STORE_JUMP2', but for inserting. Assume `b' is the buffer end. */ +#define INSERT_JUMP2(op, loc, to, arg) \ + insert_op2 (op, loc, (int) ((to) - (loc) - 3), arg, b) + + +/* This is not an arbitrary limit: the arguments which represent offsets + into the pattern are two bytes long. So if 2^16 bytes turns out to + be too small, many things would have to change. */ +/* Any other compiler which, like MSC, has allocation limit below 2^16 + bytes will have to use approach similar to what was done below for + MSC and drop MAX_BUF_SIZE a bit. Otherwise you may end up + reallocating to 0 bytes. Such thing is not going to work too well. + You have been warned!! */ +#if defined _MSC_VER && !defined WIN32 +/* Microsoft C 16-bit versions limit malloc to approx 65512 bytes. + The REALLOC define eliminates a flurry of conversion warnings, + but is not required. */ +# define MAX_BUF_SIZE 65500L +# define REALLOC(p,s) realloc ((p), (size_t) (s)) +#else +# define MAX_BUF_SIZE (1L << 16) +# define REALLOC(p,s) realloc ((p), (s)) +#endif + +/* Extend the buffer by twice its current size via realloc and + reset the pointers that pointed into the old block to point to the + correct places in the new one. If extending the buffer results in it + being larger than MAX_BUF_SIZE, then flag memory exhausted. */ +#define EXTEND_BUFFER() \ + do { \ + unsigned char *old_buffer = bufp->buffer; \ + if (bufp->allocated == MAX_BUF_SIZE) \ + return REG_ESIZE; \ + bufp->allocated <<= 1; \ + if (bufp->allocated > MAX_BUF_SIZE) \ + bufp->allocated = MAX_BUF_SIZE; \ + bufp->buffer = (unsigned char *) REALLOC (bufp->buffer, bufp->allocated);\ + if (bufp->buffer == NULL) \ + return REG_ESPACE; \ + /* If the buffer moved, move all the pointers into it. */ \ + if (old_buffer != bufp->buffer) \ + { \ + b = (b - old_buffer) + bufp->buffer; \ + begalt = (begalt - old_buffer) + bufp->buffer; \ + if (fixup_alt_jump) \ + fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;\ + if (laststart) \ + laststart = (laststart - old_buffer) + bufp->buffer; \ + if (pending_exact) \ + pending_exact = (pending_exact - old_buffer) + bufp->buffer; \ + } \ + } while (0) + + +/* Since we have one byte reserved for the register number argument to + {start,stop}_memory, the maximum number of groups we can report + things about is what fits in that byte. */ +#define MAX_REGNUM 255 + +/* But patterns can have more than `MAX_REGNUM' registers. We just + ignore the excess. */ +typedef unsigned regnum_t; + + +/* Macros for the compile stack. */ + +/* Since offsets can go either forwards or backwards, this type needs to + be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1. */ +/* int may be not enough when sizeof(int) == 2. */ +typedef long pattern_offset_t; + +typedef struct +{ + pattern_offset_t begalt_offset; + pattern_offset_t fixup_alt_jump; + pattern_offset_t inner_group_offset; + pattern_offset_t laststart_offset; + regnum_t regnum; +} compile_stack_elt_t; + + +typedef struct +{ + compile_stack_elt_t *stack; + unsigned size; + unsigned avail; /* Offset of next open position. */ +} compile_stack_type; + + +#define INIT_COMPILE_STACK_SIZE 32 + +#define COMPILE_STACK_EMPTY (compile_stack.avail == 0) +#define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size) + +/* The next available element. */ +#define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail]) + + +/* Set the bit for character C in a list. */ +#define SET_LIST_BIT(c) \ + (b[((unsigned char) (c)) / BYTEWIDTH] \ + |= 1 << (((unsigned char) c) % BYTEWIDTH)) + + +/* Get the next unsigned number in the uncompiled pattern. */ +#define GET_UNSIGNED_NUMBER(num) \ + { if (p != pend) \ + { \ + PATFETCH (c); \ + while (ISDIGIT (c)) \ + { \ + if (num < 0) \ + num = 0; \ + num = num * 10 + c - '0'; \ + if (p == pend) \ + break; \ + PATFETCH (c); \ + } \ + } \ + } + +#if defined _LIBC || WIDE_CHAR_SUPPORT +/* The GNU C library provides support for user-defined character classes + and the functions from ISO C amendement 1. */ +# ifdef CHARCLASS_NAME_MAX +# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX +# else +/* This shouldn't happen but some implementation might still have this + problem. Use a reasonable default value. */ +# define CHAR_CLASS_MAX_LENGTH 256 +# endif + +# ifdef _LIBC +# define IS_CHAR_CLASS(string) __wctype (string) +# else +# define IS_CHAR_CLASS(string) wctype (string) +# endif +#else +# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */ + +# define IS_CHAR_CLASS(string) \ + (STREQ (string, "alpha") || STREQ (string, "upper") \ + || STREQ (string, "lower") || STREQ (string, "digit") \ + || STREQ (string, "alnum") || STREQ (string, "xdigit") \ + || STREQ (string, "space") || STREQ (string, "print") \ + || STREQ (string, "punct") || STREQ (string, "graph") \ + || STREQ (string, "cntrl") || STREQ (string, "blank")) +#endif + +#ifndef MATCH_MAY_ALLOCATE + +/* If we cannot allocate large objects within re_match_2_internal, + we make the fail stack and register vectors global. + The fail stack, we grow to the maximum size when a regexp + is compiled. + The register vectors, we adjust in size each time we + compile a regexp, according to the number of registers it needs. */ + +static fail_stack_type fail_stack; + +/* Size with which the following vectors are currently allocated. + That is so we can make them bigger as needed, + but never make them smaller. */ +static int regs_allocated_size; + +static const char ** regstart, ** regend; +static const char ** old_regstart, ** old_regend; +static const char **best_regstart, **best_regend; +static register_info_type *reg_info; +static const char **reg_dummy; +static register_info_type *reg_info_dummy; + +/* Make the register vectors big enough for NUM_REGS registers, + but don't make them smaller. */ + +static +regex_grow_registers (num_regs) + int num_regs; +{ + if (num_regs > regs_allocated_size) + { + RETALLOC_IF (regstart, num_regs, const char *); + RETALLOC_IF (regend, num_regs, const char *); + RETALLOC_IF (old_regstart, num_regs, const char *); + RETALLOC_IF (old_regend, num_regs, const char *); + RETALLOC_IF (best_regstart, num_regs, const char *); + RETALLOC_IF (best_regend, num_regs, const char *); + RETALLOC_IF (reg_info, num_regs, register_info_type); + RETALLOC_IF (reg_dummy, num_regs, const char *); + RETALLOC_IF (reg_info_dummy, num_regs, register_info_type); + + regs_allocated_size = num_regs; + } +} + +#endif /* not MATCH_MAY_ALLOCATE */ + +static boolean group_in_compile_stack _RE_ARGS ((compile_stack_type + compile_stack, + regnum_t regnum)); + +/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX. + Returns one of error codes defined in `regex.h', or zero for success. + + Assumes the `allocated' (and perhaps `buffer') and `translate' + fields are set in BUFP on entry. + + If it succeeds, results are put in BUFP (if it returns an error, the + contents of BUFP are undefined): + `buffer' is the compiled pattern; + `syntax' is set to SYNTAX; + `used' is set to the length of the compiled pattern; + `fastmap_accurate' is zero; + `re_nsub' is the number of subexpressions in PATTERN; + `not_bol' and `not_eol' are zero; + + The `fastmap' and `newline_anchor' fields are neither + examined nor set. */ + +/* Return, freeing storage we allocated. */ +#define FREE_STACK_RETURN(value) \ + return (free (compile_stack.stack), value) + +static reg_errcode_t +regex_compile (pattern, size, syntax, bufp) + const char *pattern; + size_t size; + reg_syntax_t syntax; + struct re_pattern_buffer *bufp; +{ + /* We fetch characters from PATTERN here. Even though PATTERN is + `char *' (i.e., signed), we declare these variables as unsigned, so + they can be reliably used as array indices. */ + register unsigned char c, c1; + + /* A random temporary spot in PATTERN. */ + const char *p1; + + /* Points to the end of the buffer, where we should append. */ + register unsigned char *b; + + /* Keeps track of unclosed groups. */ + compile_stack_type compile_stack; + + /* Points to the current (ending) position in the pattern. */ + const char *p = pattern; + const char *pend = pattern + size; + + /* How to translate the characters in the pattern. */ + RE_TRANSLATE_TYPE translate = bufp->translate; + + /* Address of the count-byte of the most recently inserted `exactn' + command. This makes it possible to tell if a new exact-match + character can be added to that command or if the character requires + a new `exactn' command. */ + unsigned char *pending_exact = 0; + + /* Address of start of the most recently finished expression. + This tells, e.g., postfix * where to find the start of its + operand. Reset at the beginning of groups and alternatives. */ + unsigned char *laststart = 0; + + /* Address of beginning of regexp, or inside of last group. */ + unsigned char *begalt; + + /* Place in the uncompiled pattern (i.e., the {) to + which to go back if the interval is invalid. */ + const char *beg_interval; + + /* Address of the place where a forward jump should go to the end of + the containing expression. Each alternative of an `or' -- except the + last -- ends with a forward jump of this sort. */ + unsigned char *fixup_alt_jump = 0; + + /* Counts open-groups as they are encountered. Remembered for the + matching close-group on the compile stack, so the same register + number is put in the stop_memory as the start_memory. */ + regnum_t regnum = 0; + +#ifdef DEBUG + DEBUG_PRINT1 ("\nCompiling pattern: "); + if (debug) + { + unsigned debug_count; + + for (debug_count = 0; debug_count < size; debug_count++) + putchar (pattern[debug_count]); + putchar ('\n'); + } +#endif /* DEBUG */ + + /* Initialize the compile stack. */ + compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t); + if (compile_stack.stack == NULL) + return REG_ESPACE; + + compile_stack.size = INIT_COMPILE_STACK_SIZE; + compile_stack.avail = 0; + + /* Initialize the pattern buffer. */ + bufp->syntax = syntax; + bufp->fastmap_accurate = 0; + bufp->not_bol = bufp->not_eol = 0; + + /* Set `used' to zero, so that if we return an error, the pattern + printer (for debugging) will think there's no pattern. We reset it + at the end. */ + bufp->used = 0; + + /* Always count groups, whether or not bufp->no_sub is set. */ + bufp->re_nsub = 0; + +#if !defined emacs && !defined SYNTAX_TABLE + /* Initialize the syntax table. */ + init_syntax_once (); +#endif + + if (bufp->allocated == 0) + { + if (bufp->buffer) + { /* If zero allocated, but buffer is non-null, try to realloc + enough space. This loses if buffer's address is bogus, but + that is the user's responsibility. */ + RETALLOC (bufp->buffer, INIT_BUF_SIZE, unsigned char); + } + else + { /* Caller did not allocate a buffer. Do it for them. */ + bufp->buffer = TALLOC (INIT_BUF_SIZE, unsigned char); + } + if (!bufp->buffer) FREE_STACK_RETURN (REG_ESPACE); + + bufp->allocated = INIT_BUF_SIZE; + } + + begalt = b = bufp->buffer; + + /* Loop through the uncompiled pattern until we're at the end. */ + while (p != pend) + { + PATFETCH (c); + + switch (c) + { + case '^': + { + if ( /* If at start of pattern, it's an operator. */ + p == pattern + 1 + /* If context independent, it's an operator. */ + || syntax & RE_CONTEXT_INDEP_ANCHORS + /* Otherwise, depends on what's come before. */ + || at_begline_loc_p (pattern, p, syntax)) + BUF_PUSH (begline); + else + goto normal_char; + } + break; + + + case '$': + { + if ( /* If at end of pattern, it's an operator. */ + p == pend + /* If context independent, it's an operator. */ + || syntax & RE_CONTEXT_INDEP_ANCHORS + /* Otherwise, depends on what's next. */ + || at_endline_loc_p (p, pend, syntax)) + BUF_PUSH (endline); + else + goto normal_char; + } + break; + + + case '+': + case '?': + if ((syntax & RE_BK_PLUS_QM) + || (syntax & RE_LIMITED_OPS)) + goto normal_char; + handle_plus: + case '*': + /* If there is no previous pattern... */ + if (!laststart) + { + if (syntax & RE_CONTEXT_INVALID_OPS) + FREE_STACK_RETURN (REG_BADRPT); + else if (!(syntax & RE_CONTEXT_INDEP_OPS)) + goto normal_char; + } + + { + /* Are we optimizing this jump? */ + boolean keep_string_p = false; + + /* 1 means zero (many) matches is allowed. */ + char zero_times_ok = 0, many_times_ok = 0; + + /* If there is a sequence of repetition chars, collapse it + down to just one (the right one). We can't combine + interval operators with these because of, e.g., `a{2}*', + which should only match an even number of `a's. */ + + for (;;) + { + zero_times_ok |= c != '+'; + many_times_ok |= c != '?'; + + if (p == pend) + break; + + PATFETCH (c); + + if (c == '*' + || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?'))) + ; + + else if (syntax & RE_BK_PLUS_QM && c == '\\') + { + if (p == pend) FREE_STACK_RETURN (REG_EESCAPE); + + PATFETCH (c1); + if (!(c1 == '+' || c1 == '?')) + { + PATUNFETCH; + PATUNFETCH; + break; + } + + c = c1; + } + else + { + PATUNFETCH; + break; + } + + /* If we get here, we found another repeat character. */ + } + + /* Star, etc. applied to an empty pattern is equivalent + to an empty pattern. */ + if (!laststart) + break; + + /* Now we know whether or not zero matches is allowed + and also whether or not two or more matches is allowed. */ + if (many_times_ok) + { /* More than one repetition is allowed, so put in at the + end a backward relative jump from `b' to before the next + jump we're going to put in below (which jumps from + laststart to after this jump). + + But if we are at the `*' in the exact sequence `.*\n', + insert an unconditional jump backwards to the ., + instead of the beginning of the loop. This way we only + push a failure point once, instead of every time + through the loop. */ + assert (p - 1 > pattern); + + /* Allocate the space for the jump. */ + GET_BUFFER_SPACE (3); + + /* We know we are not at the first character of the pattern, + because laststart was nonzero. And we've already + incremented `p', by the way, to be the character after + the `*'. Do we have to do something analogous here + for null bytes, because of RE_DOT_NOT_NULL? */ + if (TRANSLATE (*(p - 2)) == TRANSLATE ('.') + && zero_times_ok + && p < pend && TRANSLATE (*p) == TRANSLATE ('\n') + && !(syntax & RE_DOT_NEWLINE)) + { /* We have .*\n. */ + STORE_JUMP (jump, b, laststart); + keep_string_p = true; + } + else + /* Anything else. */ + STORE_JUMP (maybe_pop_jump, b, laststart - 3); + + /* We've added more stuff to the buffer. */ + b += 3; + } + + /* On failure, jump from laststart to b + 3, which will be the + end of the buffer after this jump is inserted. */ + GET_BUFFER_SPACE (3); + INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump + : on_failure_jump, + laststart, b + 3); + pending_exact = 0; + b += 3; + + if (!zero_times_ok) + { + /* At least one repetition is required, so insert a + `dummy_failure_jump' before the initial + `on_failure_jump' instruction of the loop. This + effects a skip over that instruction the first time + we hit that loop. */ + GET_BUFFER_SPACE (3); + INSERT_JUMP (dummy_failure_jump, laststart, laststart + 6); + b += 3; + } + } + break; + + + case '.': + laststart = b; + BUF_PUSH (anychar); + break; + + + case '[': + { + boolean had_char_class = false; + + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); + + /* Ensure that we have enough space to push a charset: the + opcode, the length count, and the bitset; 34 bytes in all. */ + GET_BUFFER_SPACE (34); + + laststart = b; + + /* We test `*p == '^' twice, instead of using an if + statement, so we only need one BUF_PUSH. */ + BUF_PUSH (*p == '^' ? charset_not : charset); + if (*p == '^') + p++; + + /* Remember the first position in the bracket expression. */ + p1 = p; + + /* Push the number of bytes in the bitmap. */ + BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH); + + /* Clear the whole map. */ + bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH); + + /* charset_not matches newline according to a syntax bit. */ + if ((re_opcode_t) b[-2] == charset_not + && (syntax & RE_HAT_LISTS_NOT_NEWLINE)) + SET_LIST_BIT ('\n'); + + /* Read in characters and ranges, setting map bits. */ + for (;;) + { + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); + + PATFETCH (c); + + /* \ might escape characters inside [...] and [^...]. */ + if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\') + { + if (p == pend) FREE_STACK_RETURN (REG_EESCAPE); + + PATFETCH (c1); + SET_LIST_BIT (c1); + continue; + } + + /* Could be the end of the bracket expression. If it's + not (i.e., when the bracket expression is `[]' so + far), the ']' character bit gets set way below. */ + if (c == ']' && p != p1 + 1) + break; + + /* Look ahead to see if it's a range when the last thing + was a character class. */ + if (had_char_class && c == '-' && *p != ']') + FREE_STACK_RETURN (REG_ERANGE); + + /* Look ahead to see if it's a range when the last thing + was a character: if this is a hyphen not at the + beginning or the end of a list, then it's the range + operator. */ + if (c == '-' + && !(p - 2 >= pattern && p[-2] == '[') + && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^') + && *p != ']') + { + reg_errcode_t ret + = compile_range (&p, pend, translate, syntax, b); + if (ret != REG_NOERROR) FREE_STACK_RETURN (ret); + } + + else if (p[0] == '-' && p[1] != ']') + { /* This handles ranges made up of characters only. */ + reg_errcode_t ret; + + /* Move past the `-'. */ + PATFETCH (c1); + + ret = compile_range (&p, pend, translate, syntax, b); + if (ret != REG_NOERROR) FREE_STACK_RETURN (ret); + } + + /* See if we're at the beginning of a possible character + class. */ + + else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':') + { /* Leave room for the null. */ + char str[CHAR_CLASS_MAX_LENGTH + 1]; + + PATFETCH (c); + c1 = 0; + + /* If pattern is `[[:'. */ + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); + + for (;;) + { + PATFETCH (c); + if ((c == ':' && *p == ']') || p == pend + || c1 == CHAR_CLASS_MAX_LENGTH) + break; + str[c1++] = c; + } + str[c1] = '\0'; + + /* If isn't a word bracketed by `[:' and `:]': + undo the ending character, the letters, and leave + the leading `:' and `[' (but set bits for them). */ + if (c == ':' && *p == ']') + { +#if defined _LIBC || WIDE_CHAR_SUPPORT + boolean is_lower = STREQ (str, "lower"); + boolean is_upper = STREQ (str, "upper"); + wctype_t wt; + int ch; + + wt = IS_CHAR_CLASS (str); + if (wt == 0) + FREE_STACK_RETURN (REG_ECTYPE); + + /* Throw away the ] at the end of the character + class. */ + PATFETCH (c); + + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); + + for (ch = 0; ch < 1 << BYTEWIDTH; ++ch) + { +# ifdef _LIBC + if (__iswctype (__btowc (ch), wt)) + SET_LIST_BIT (ch); +# else + if (iswctype (btowc (ch), wt)) + SET_LIST_BIT (ch); +# endif + + if (translate && (is_upper || is_lower) + && (ISUPPER (ch) || ISLOWER (ch))) + SET_LIST_BIT (ch); + } + + had_char_class = true; +#else + int ch; + boolean is_alnum = STREQ (str, "alnum"); + boolean is_alpha = STREQ (str, "alpha"); + boolean is_blank = STREQ (str, "blank"); + boolean is_cntrl = STREQ (str, "cntrl"); + boolean is_digit = STREQ (str, "digit"); + boolean is_graph = STREQ (str, "graph"); + boolean is_lower = STREQ (str, "lower"); + boolean is_print = STREQ (str, "print"); + boolean is_punct = STREQ (str, "punct"); + boolean is_space = STREQ (str, "space"); + boolean is_upper = STREQ (str, "upper"); + boolean is_xdigit = STREQ (str, "xdigit"); + + if (!IS_CHAR_CLASS (str)) + FREE_STACK_RETURN (REG_ECTYPE); + + /* Throw away the ] at the end of the character + class. */ + PATFETCH (c); + + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); + + for (ch = 0; ch < 1 << BYTEWIDTH; ch++) + { + /* This was split into 3 if's to + avoid an arbitrary limit in some compiler. */ + if ( (is_alnum && ISALNUM (ch)) + || (is_alpha && ISALPHA (ch)) + || (is_blank && ISBLANK (ch)) + || (is_cntrl && ISCNTRL (ch))) + SET_LIST_BIT (ch); + if ( (is_digit && ISDIGIT (ch)) + || (is_graph && ISGRAPH (ch)) + || (is_lower && ISLOWER (ch)) + || (is_print && ISPRINT (ch))) + SET_LIST_BIT (ch); + if ( (is_punct && ISPUNCT (ch)) + || (is_space && ISSPACE (ch)) + || (is_upper && ISUPPER (ch)) + || (is_xdigit && ISXDIGIT (ch))) + SET_LIST_BIT (ch); + if ( translate && (is_upper || is_lower) + && (ISUPPER (ch) || ISLOWER (ch))) + SET_LIST_BIT (ch); + } + had_char_class = true; +#endif /* libc || wctype.h */ + } + else + { + c1++; + while (c1--) + PATUNFETCH; + SET_LIST_BIT ('['); + SET_LIST_BIT (':'); + had_char_class = false; + } + } + else + { + had_char_class = false; + SET_LIST_BIT (c); + } + } + + /* Discard any (non)matching list bytes that are all 0 at the + end of the map. Decrease the map-length byte too. */ + while ((int) b[-1] > 0 && b[b[-1] - 1] == 0) + b[-1]--; + b += b[-1]; + } + break; + + + case '(': + if (syntax & RE_NO_BK_PARENS) + goto handle_open; + else + goto normal_char; + + + case ')': + if (syntax & RE_NO_BK_PARENS) + goto handle_close; + else + goto normal_char; + + + case '\n': + if (syntax & RE_NEWLINE_ALT) + goto handle_alt; + else + goto normal_char; + + + case '|': + if (syntax & RE_NO_BK_VBAR) + goto handle_alt; + else + goto normal_char; + + + case '{': + if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES) + goto handle_interval; + else + goto normal_char; + + + case '\\': + if (p == pend) FREE_STACK_RETURN (REG_EESCAPE); + + /* Do not translate the character after the \, so that we can + distinguish, e.g., \B from \b, even if we normally would + translate, e.g., B to b. */ + PATFETCH_RAW (c); + + switch (c) + { + case '(': + if (syntax & RE_NO_BK_PARENS) + goto normal_backslash; + + handle_open: + bufp->re_nsub++; + regnum++; + + if (COMPILE_STACK_FULL) + { + RETALLOC (compile_stack.stack, compile_stack.size << 1, + compile_stack_elt_t); + if (compile_stack.stack == NULL) return REG_ESPACE; + + compile_stack.size <<= 1; + } + + /* These are the values to restore when we hit end of this + group. They are all relative offsets, so that if the + whole pattern moves because of realloc, they will still + be valid. */ + COMPILE_STACK_TOP.begalt_offset = begalt - bufp->buffer; + COMPILE_STACK_TOP.fixup_alt_jump + = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0; + COMPILE_STACK_TOP.laststart_offset = b - bufp->buffer; + COMPILE_STACK_TOP.regnum = regnum; + + /* We will eventually replace the 0 with the number of + groups inner to this one. But do not push a + start_memory for groups beyond the last one we can + represent in the compiled pattern. */ + if (regnum <= MAX_REGNUM) + { + COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2; + BUF_PUSH_3 (start_memory, regnum, 0); + } + + compile_stack.avail++; + + fixup_alt_jump = 0; + laststart = 0; + begalt = b; + /* If we've reached MAX_REGNUM groups, then this open + won't actually generate any code, so we'll have to + clear pending_exact explicitly. */ + pending_exact = 0; + break; + + + case ')': + if (syntax & RE_NO_BK_PARENS) goto normal_backslash; + + if (COMPILE_STACK_EMPTY) + { + if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD) + goto normal_backslash; + else + FREE_STACK_RETURN (REG_ERPAREN); + } + + handle_close: + if (fixup_alt_jump) + { /* Push a dummy failure point at the end of the + alternative for a possible future + `pop_failure_jump' to pop. See comments at + `push_dummy_failure' in `re_match_2'. */ + BUF_PUSH (push_dummy_failure); + + /* We allocated space for this jump when we assigned + to `fixup_alt_jump', in the `handle_alt' case below. */ + STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1); + } + + /* See similar code for backslashed left paren above. */ + if (COMPILE_STACK_EMPTY) + { + if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD) + goto normal_char; + else + FREE_STACK_RETURN (REG_ERPAREN); + } + + /* Since we just checked for an empty stack above, this + ``can't happen''. */ + assert (compile_stack.avail != 0); + { + /* We don't just want to restore into `regnum', because + later groups should continue to be numbered higher, + as in `(ab)c(de)' -- the second group is #2. */ + regnum_t this_group_regnum; + + compile_stack.avail--; + begalt = bufp->buffer + COMPILE_STACK_TOP.begalt_offset; + fixup_alt_jump + = COMPILE_STACK_TOP.fixup_alt_jump + ? bufp->buffer + COMPILE_STACK_TOP.fixup_alt_jump - 1 + : 0; + laststart = bufp->buffer + COMPILE_STACK_TOP.laststart_offset; + this_group_regnum = COMPILE_STACK_TOP.regnum; + /* If we've reached MAX_REGNUM groups, then this open + won't actually generate any code, so we'll have to + clear pending_exact explicitly. */ + pending_exact = 0; + + /* We're at the end of the group, so now we know how many + groups were inside this one. */ + if (this_group_regnum <= MAX_REGNUM) + { + unsigned char *inner_group_loc + = bufp->buffer + COMPILE_STACK_TOP.inner_group_offset; + + *inner_group_loc = regnum - this_group_regnum; + BUF_PUSH_3 (stop_memory, this_group_regnum, + regnum - this_group_regnum); + } + } + break; + + + case '|': /* `\|'. */ + if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR) + goto normal_backslash; + handle_alt: + if (syntax & RE_LIMITED_OPS) + goto normal_char; + + /* Insert before the previous alternative a jump which + jumps to this alternative if the former fails. */ + GET_BUFFER_SPACE (3); + INSERT_JUMP (on_failure_jump, begalt, b + 6); + pending_exact = 0; + b += 3; + + /* The alternative before this one has a jump after it + which gets executed if it gets matched. Adjust that + jump so it will jump to this alternative's analogous + jump (put in below, which in turn will jump to the next + (if any) alternative's such jump, etc.). The last such + jump jumps to the correct final destination. A picture: + _____ _____ + | | | | + | v | v + a | b | c + + If we are at `b', then fixup_alt_jump right now points to a + three-byte space after `a'. We'll put in the jump, set + fixup_alt_jump to right after `b', and leave behind three + bytes which we'll fill in when we get to after `c'. */ + + if (fixup_alt_jump) + STORE_JUMP (jump_past_alt, fixup_alt_jump, b); + + /* Mark and leave space for a jump after this alternative, + to be filled in later either by next alternative or + when know we're at the end of a series of alternatives. */ + fixup_alt_jump = b; + GET_BUFFER_SPACE (3); + b += 3; + + laststart = 0; + begalt = b; + break; + + + case '{': + /* If \{ is a literal. */ + if (!(syntax & RE_INTERVALS) + /* If we're at `\{' and it's not the open-interval + operator. */ + || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES)) + || (p - 2 == pattern && p == pend)) + goto normal_backslash; + + handle_interval: + { + /* If got here, then the syntax allows intervals. */ + + /* At least (most) this many matches must be made. */ + int lower_bound = -1, upper_bound = -1; + + beg_interval = p - 1; + + if (p == pend) + { + if (syntax & RE_NO_BK_BRACES) + goto unfetch_interval; + else + FREE_STACK_RETURN (REG_EBRACE); + } + + GET_UNSIGNED_NUMBER (lower_bound); + + if (c == ',') + { + GET_UNSIGNED_NUMBER (upper_bound); + if (upper_bound < 0) upper_bound = RE_DUP_MAX; + } + else + /* Interval such as `{1}' => match exactly once. */ + upper_bound = lower_bound; + + if (lower_bound < 0 || upper_bound > RE_DUP_MAX + || lower_bound > upper_bound) + { + if (syntax & RE_NO_BK_BRACES) + goto unfetch_interval; + else + FREE_STACK_RETURN (REG_BADBR); + } + + if (!(syntax & RE_NO_BK_BRACES)) + { + if (c != '\\') FREE_STACK_RETURN (REG_EBRACE); + + PATFETCH (c); + } + + if (c != '}') + { + if (syntax & RE_NO_BK_BRACES) + goto unfetch_interval; + else + FREE_STACK_RETURN (REG_BADBR); + } + + /* We just parsed a valid interval. */ + + /* If it's invalid to have no preceding re. */ + if (!laststart) + { + if (syntax & RE_CONTEXT_INVALID_OPS) + FREE_STACK_RETURN (REG_BADRPT); + else if (syntax & RE_CONTEXT_INDEP_OPS) + laststart = b; + else + goto unfetch_interval; + } + + /* If the upper bound is zero, don't want to succeed at + all; jump from `laststart' to `b + 3', which will be + the end of the buffer after we insert the jump. */ + if (upper_bound == 0) + { + GET_BUFFER_SPACE (3); + INSERT_JUMP (jump, laststart, b + 3); + b += 3; + } + + /* Otherwise, we have a nontrivial interval. When + we're all done, the pattern will look like: + set_number_at + set_number_at + succeed_n + + jump_n + (The upper bound and `jump_n' are omitted if + `upper_bound' is 1, though.) */ + else + { /* If the upper bound is > 1, we need to insert + more at the end of the loop. */ + unsigned nbytes = 10 + (upper_bound > 1) * 10; + + GET_BUFFER_SPACE (nbytes); + + /* Initialize lower bound of the `succeed_n', even + though it will be set during matching by its + attendant `set_number_at' (inserted next), + because `re_compile_fastmap' needs to know. + Jump to the `jump_n' we might insert below. */ + INSERT_JUMP2 (succeed_n, laststart, + b + 5 + (upper_bound > 1) * 5, + lower_bound); + b += 5; + + /* Code to initialize the lower bound. Insert + before the `succeed_n'. The `5' is the last two + bytes of this `set_number_at', plus 3 bytes of + the following `succeed_n'. */ + insert_op2 (set_number_at, laststart, 5, lower_bound, b); + b += 5; + + if (upper_bound > 1) + { /* More than one repetition is allowed, so + append a backward jump to the `succeed_n' + that starts this interval. + + When we've reached this during matching, + we'll have matched the interval once, so + jump back only `upper_bound - 1' times. */ + STORE_JUMP2 (jump_n, b, laststart + 5, + upper_bound - 1); + b += 5; + + /* The location we want to set is the second + parameter of the `jump_n'; that is `b-2' as + an absolute address. `laststart' will be + the `set_number_at' we're about to insert; + `laststart+3' the number to set, the source + for the relative address. But we are + inserting into the middle of the pattern -- + so everything is getting moved up by 5. + Conclusion: (b - 2) - (laststart + 3) + 5, + i.e., b - laststart. + + We insert this at the beginning of the loop + so that if we fail during matching, we'll + reinitialize the bounds. */ + insert_op2 (set_number_at, laststart, b - laststart, + upper_bound - 1, b); + b += 5; + } + } + pending_exact = 0; + beg_interval = NULL; + } + break; + + unfetch_interval: + /* If an invalid interval, match the characters as literals. */ + assert (beg_interval); + p = beg_interval; + beg_interval = NULL; + + /* normal_char and normal_backslash need `c'. */ + PATFETCH (c); + + if (!(syntax & RE_NO_BK_BRACES)) + { + if (p > pattern && p[-1] == '\\') + goto normal_backslash; + } + goto normal_char; + +#ifdef emacs + /* There is no way to specify the before_dot and after_dot + operators. rms says this is ok. --karl */ + case '=': + BUF_PUSH (at_dot); + break; + + case 's': + laststart = b; + PATFETCH (c); + BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]); + break; + + case 'S': + laststart = b; + PATFETCH (c); + BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]); + break; +#endif /* emacs */ + + + case 'w': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + laststart = b; + BUF_PUSH (wordchar); + break; + + + case 'W': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + laststart = b; + BUF_PUSH (notwordchar); + break; + + + case '<': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + BUF_PUSH (wordbeg); + break; + + case '>': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + BUF_PUSH (wordend); + break; + + case 'b': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + BUF_PUSH (wordbound); + break; + + case 'B': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + BUF_PUSH (notwordbound); + break; + + case '`': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + BUF_PUSH (begbuf); + break; + + case '\'': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + BUF_PUSH (endbuf); + break; + + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + if (syntax & RE_NO_BK_REFS) + goto normal_char; + + c1 = c - '0'; + + if (c1 > regnum) + FREE_STACK_RETURN (REG_ESUBREG); + + /* Can't back reference to a subexpression if inside of it. */ + if (group_in_compile_stack (compile_stack, (regnum_t) c1)) + goto normal_char; + + laststart = b; + BUF_PUSH_2 (duplicate, c1); + break; + + + case '+': + case '?': + if (syntax & RE_BK_PLUS_QM) + goto handle_plus; + else + goto normal_backslash; + + default: + normal_backslash: + /* You might think it would be useful for \ to mean + not to translate; but if we don't translate it + it will never match anything. */ + c = TRANSLATE (c); + goto normal_char; + } + break; + + + default: + /* Expects the character in `c'. */ + normal_char: + /* If no exactn currently being built. */ + if (!pending_exact + + /* If last exactn not at current position. */ + || pending_exact + *pending_exact + 1 != b + + /* We have only one byte following the exactn for the count. */ + || *pending_exact == (1 << BYTEWIDTH) - 1 + + /* If followed by a repetition operator. */ + || *p == '*' || *p == '^' + || ((syntax & RE_BK_PLUS_QM) + ? *p == '\\' && (p[1] == '+' || p[1] == '?') + : (*p == '+' || *p == '?')) + || ((syntax & RE_INTERVALS) + && ((syntax & RE_NO_BK_BRACES) + ? *p == '{' + : (p[0] == '\\' && p[1] == '{')))) + { + /* Start building a new exactn. */ + + laststart = b; + + BUF_PUSH_2 (exactn, 0); + pending_exact = b - 1; + } + + BUF_PUSH (c); + (*pending_exact)++; + break; + } /* switch (c) */ + } /* while p != pend */ + + + /* Through the pattern now. */ + + if (fixup_alt_jump) + STORE_JUMP (jump_past_alt, fixup_alt_jump, b); + + if (!COMPILE_STACK_EMPTY) + FREE_STACK_RETURN (REG_EPAREN); + + /* If we don't want backtracking, force success + the first time we reach the end of the compiled pattern. */ + if (syntax & RE_NO_POSIX_BACKTRACKING) + BUF_PUSH (succeed); + + free (compile_stack.stack); + + /* We have succeeded; set the length of the buffer. */ + bufp->used = b - bufp->buffer; + +#ifdef DEBUG + if (debug) + { + DEBUG_PRINT1 ("\nCompiled pattern: \n"); + print_compiled_pattern (bufp); + } +#endif /* DEBUG */ + +#ifndef MATCH_MAY_ALLOCATE + /* Initialize the failure stack to the largest possible stack. This + isn't necessary unless we're trying to avoid calling alloca in + the search and match routines. */ + { + int num_regs = bufp->re_nsub + 1; + + /* Since DOUBLE_FAIL_STACK refuses to double only if the current size + is strictly greater than re_max_failures, the largest possible stack + is 2 * re_max_failures failure points. */ + if (fail_stack.size < (2 * re_max_failures * MAX_FAILURE_ITEMS)) + { + fail_stack.size = (2 * re_max_failures * MAX_FAILURE_ITEMS); + +# ifdef emacs + if (! fail_stack.stack) + fail_stack.stack + = (fail_stack_elt_t *) xmalloc (fail_stack.size + * sizeof (fail_stack_elt_t)); + else + fail_stack.stack + = (fail_stack_elt_t *) xrealloc (fail_stack.stack, + (fail_stack.size + * sizeof (fail_stack_elt_t))); +# else /* not emacs */ + if (! fail_stack.stack) + fail_stack.stack + = (fail_stack_elt_t *) malloc (fail_stack.size + * sizeof (fail_stack_elt_t)); + else + fail_stack.stack + = (fail_stack_elt_t *) realloc (fail_stack.stack, + (fail_stack.size + * sizeof (fail_stack_elt_t))); +# endif /* not emacs */ + } + + regex_grow_registers (num_regs); + } +#endif /* not MATCH_MAY_ALLOCATE */ + + return REG_NOERROR; +} /* regex_compile */ + +/* Subroutines for `regex_compile'. */ + +/* Store OP at LOC followed by two-byte integer parameter ARG. */ + +static void +store_op1 (op, loc, arg) + re_opcode_t op; + unsigned char *loc; + int arg; +{ + *loc = (unsigned char) op; + STORE_NUMBER (loc + 1, arg); +} + + +/* Like `store_op1', but for two two-byte parameters ARG1 and ARG2. */ + +static void +store_op2 (op, loc, arg1, arg2) + re_opcode_t op; + unsigned char *loc; + int arg1, arg2; +{ + *loc = (unsigned char) op; + STORE_NUMBER (loc + 1, arg1); + STORE_NUMBER (loc + 3, arg2); +} + + +/* Copy the bytes from LOC to END to open up three bytes of space at LOC + for OP followed by two-byte integer parameter ARG. */ + +static void +insert_op1 (op, loc, arg, end) + re_opcode_t op; + unsigned char *loc; + int arg; + unsigned char *end; +{ + register unsigned char *pfrom = end; + register unsigned char *pto = end + 3; + + while (pfrom != loc) + *--pto = *--pfrom; + + store_op1 (op, loc, arg); +} + + +/* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2. */ + +static void +insert_op2 (op, loc, arg1, arg2, end) + re_opcode_t op; + unsigned char *loc; + int arg1, arg2; + unsigned char *end; +{ + register unsigned char *pfrom = end; + register unsigned char *pto = end + 5; + + while (pfrom != loc) + *--pto = *--pfrom; + + store_op2 (op, loc, arg1, arg2); +} + + +/* P points to just after a ^ in PATTERN. Return true if that ^ comes + after an alternative or a begin-subexpression. We assume there is at + least one character before the ^. */ + +static boolean +at_begline_loc_p (pattern, p, syntax) + const char *pattern, *p; + reg_syntax_t syntax; +{ + const char *prev = p - 2; + boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\'; + + return + /* After a subexpression? */ + (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash)) + /* After an alternative? */ + || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash)); +} + + +/* The dual of at_begline_loc_p. This one is for $. We assume there is + at least one character after the $, i.e., `P < PEND'. */ + +static boolean +at_endline_loc_p (p, pend, syntax) + const char *p, *pend; + reg_syntax_t syntax; +{ + const char *next = p; + boolean next_backslash = *next == '\\'; + const char *next_next = p + 1 < pend ? p + 1 : 0; + + return + /* Before a subexpression? */ + (syntax & RE_NO_BK_PARENS ? *next == ')' + : next_backslash && next_next && *next_next == ')') + /* Before an alternative? */ + || (syntax & RE_NO_BK_VBAR ? *next == '|' + : next_backslash && next_next && *next_next == '|'); +} + + +/* Returns true if REGNUM is in one of COMPILE_STACK's elements and + false if it's not. */ + +static boolean +group_in_compile_stack (compile_stack, regnum) + compile_stack_type compile_stack; + regnum_t regnum; +{ + int this_element; + + for (this_element = compile_stack.avail - 1; + this_element >= 0; + this_element--) + if (compile_stack.stack[this_element].regnum == regnum) + return true; + + return false; +} + + +/* Read the ending character of a range (in a bracket expression) from the + uncompiled pattern *P_PTR (which ends at PEND). We assume the + starting character is in `P[-2]'. (`P[-1]' is the character `-'.) + Then we set the translation of all bits between the starting and + ending characters (inclusive) in the compiled pattern B. + + Return an error code. + + We use these short variable names so we can use the same macros as + `regex_compile' itself. */ + +static reg_errcode_t +compile_range (p_ptr, pend, translate, syntax, b) + const char **p_ptr, *pend; + RE_TRANSLATE_TYPE translate; + reg_syntax_t syntax; + unsigned char *b; +{ + unsigned this_char; + + const char *p = *p_ptr; + unsigned int range_start, range_end; + + if (p == pend) + return REG_ERANGE; + + /* Even though the pattern is a signed `char *', we need to fetch + with unsigned char *'s; if the high bit of the pattern character + is set, the range endpoints will be negative if we fetch using a + signed char *. + + We also want to fetch the endpoints without translating them; the + appropriate translation is done in the bit-setting loop below. */ + /* The SVR4 compiler on the 3B2 had trouble with unsigned const char *. */ + range_start = ((const unsigned char *) p)[-2]; + range_end = ((const unsigned char *) p)[0]; + + /* Have to increment the pointer into the pattern string, so the + caller isn't still at the ending character. */ + (*p_ptr)++; + + /* If the start is after the end, the range is empty. */ + if (range_start > range_end) + return syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR; + + /* Here we see why `this_char' has to be larger than an `unsigned + char' -- the range is inclusive, so if `range_end' == 0xff + (assuming 8-bit characters), we would otherwise go into an infinite + loop, since all characters <= 0xff. */ + for (this_char = range_start; this_char <= range_end; this_char++) + { + SET_LIST_BIT (TRANSLATE (this_char)); + } + + return REG_NOERROR; +} + +/* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in + BUFP. A fastmap records which of the (1 << BYTEWIDTH) possible + characters can start a string that matches the pattern. This fastmap + is used by re_search to skip quickly over impossible starting points. + + The caller must supply the address of a (1 << BYTEWIDTH)-byte data + area as BUFP->fastmap. + + We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in + the pattern buffer. + + Returns 0 if we succeed, -2 if an internal error. */ + +int +re_compile_fastmap (bufp) + struct re_pattern_buffer *bufp; +{ + int j, k; +#ifdef MATCH_MAY_ALLOCATE + fail_stack_type fail_stack; +#endif +#ifndef REGEX_MALLOC + char *destination; +#endif + + register char *fastmap = bufp->fastmap; + unsigned char *pattern = bufp->buffer; + unsigned char *p = pattern; + register unsigned char *pend = pattern + bufp->used; + +#ifdef REL_ALLOC + /* This holds the pointer to the failure stack, when + it is allocated relocatably. */ + fail_stack_elt_t *failure_stack_ptr; +#endif + + /* Assume that each path through the pattern can be null until + proven otherwise. We set this false at the bottom of switch + statement, to which we get only if a particular path doesn't + match the empty string. */ + boolean path_can_be_null = true; + + /* We aren't doing a `succeed_n' to begin with. */ + boolean succeed_n_p = false; + + assert (fastmap != NULL && p != NULL); + + INIT_FAIL_STACK (); + bzero (fastmap, 1 << BYTEWIDTH); /* Assume nothing's valid. */ + bufp->fastmap_accurate = 1; /* It will be when we're done. */ + bufp->can_be_null = 0; + + while (1) + { + if (p == pend || *p == succeed) + { + /* We have reached the (effective) end of pattern. */ + if (!FAIL_STACK_EMPTY ()) + { + bufp->can_be_null |= path_can_be_null; + + /* Reset for next path. */ + path_can_be_null = true; + + p = fail_stack.stack[--fail_stack.avail].pointer; + + continue; + } + else + break; + } + + /* We should never be about to go beyond the end of the pattern. */ + assert (p < pend); + + switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++)) + { + + /* I guess the idea here is to simply not bother with a fastmap + if a backreference is used, since it's too hard to figure out + the fastmap for the corresponding group. Setting + `can_be_null' stops `re_search_2' from using the fastmap, so + that is all we do. */ + case duplicate: + bufp->can_be_null = 1; + goto done; + + + /* Following are the cases which match a character. These end + with `break'. */ + + case exactn: + fastmap[p[1]] = 1; + break; + + + case charset: + for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) + if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))) + fastmap[j] = 1; + break; + + + case charset_not: + /* Chars beyond end of map must be allowed. */ + for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++) + fastmap[j] = 1; + + for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) + if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))) + fastmap[j] = 1; + break; + + + case wordchar: + for (j = 0; j < (1 << BYTEWIDTH); j++) + if (SYNTAX (j) == Sword) + fastmap[j] = 1; + break; + + + case notwordchar: + for (j = 0; j < (1 << BYTEWIDTH); j++) + if (SYNTAX (j) != Sword) + fastmap[j] = 1; + break; + + + case anychar: + { + int fastmap_newline = fastmap['\n']; + + /* `.' matches anything ... */ + for (j = 0; j < (1 << BYTEWIDTH); j++) + fastmap[j] = 1; + + /* ... except perhaps newline. */ + if (!(bufp->syntax & RE_DOT_NEWLINE)) + fastmap['\n'] = fastmap_newline; + + /* Return if we have already set `can_be_null'; if we have, + then the fastmap is irrelevant. Something's wrong here. */ + else if (bufp->can_be_null) + goto done; + + /* Otherwise, have to check alternative paths. */ + break; + } + +#ifdef emacs + case syntaxspec: + k = *p++; + for (j = 0; j < (1 << BYTEWIDTH); j++) + if (SYNTAX (j) == (enum syntaxcode) k) + fastmap[j] = 1; + break; + + + case notsyntaxspec: + k = *p++; + for (j = 0; j < (1 << BYTEWIDTH); j++) + if (SYNTAX (j) != (enum syntaxcode) k) + fastmap[j] = 1; + break; + + + /* All cases after this match the empty string. These end with + `continue'. */ + + + case before_dot: + case at_dot: + case after_dot: + continue; +#endif /* emacs */ + + + case no_op: + case begline: + case endline: + case begbuf: + case endbuf: + case wordbound: + case notwordbound: + case wordbeg: + case wordend: + case push_dummy_failure: + continue; + + + case jump_n: + case pop_failure_jump: + case maybe_pop_jump: + case jump: + case jump_past_alt: + case dummy_failure_jump: + EXTRACT_NUMBER_AND_INCR (j, p); + p += j; + if (j > 0) + continue; + + /* Jump backward implies we just went through the body of a + loop and matched nothing. Opcode jumped to should be + `on_failure_jump' or `succeed_n'. Just treat it like an + ordinary jump. For a * loop, it has pushed its failure + point already; if so, discard that as redundant. */ + if ((re_opcode_t) *p != on_failure_jump + && (re_opcode_t) *p != succeed_n) + continue; + + p++; + EXTRACT_NUMBER_AND_INCR (j, p); + p += j; + + /* If what's on the stack is where we are now, pop it. */ + if (!FAIL_STACK_EMPTY () + && fail_stack.stack[fail_stack.avail - 1].pointer == p) + fail_stack.avail--; + + continue; + + + case on_failure_jump: + case on_failure_keep_string_jump: + handle_on_failure_jump: + EXTRACT_NUMBER_AND_INCR (j, p); + + /* For some patterns, e.g., `(a?)?', `p+j' here points to the + end of the pattern. We don't want to push such a point, + since when we restore it above, entering the switch will + increment `p' past the end of the pattern. We don't need + to push such a point since we obviously won't find any more + fastmap entries beyond `pend'. Such a pattern can match + the null string, though. */ + if (p + j < pend) + { + if (!PUSH_PATTERN_OP (p + j, fail_stack)) + { + RESET_FAIL_STACK (); + return -2; + } + } + else + bufp->can_be_null = 1; + + if (succeed_n_p) + { + EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */ + succeed_n_p = false; + } + + continue; + + + case succeed_n: + /* Get to the number of times to succeed. */ + p += 2; + + /* Increment p past the n for when k != 0. */ + EXTRACT_NUMBER_AND_INCR (k, p); + if (k == 0) + { + p -= 4; + succeed_n_p = true; /* Spaghetti code alert. */ + goto handle_on_failure_jump; + } + continue; + + + case set_number_at: + p += 4; + continue; + + + case start_memory: + case stop_memory: + p += 2; + continue; + + + default: + abort (); /* We have listed all the cases. */ + } /* switch *p++ */ + + /* Getting here means we have found the possible starting + characters for one path of the pattern -- and that the empty + string does not match. We need not follow this path further. + Instead, look at the next alternative (remembered on the + stack), or quit if no more. The test at the top of the loop + does these things. */ + path_can_be_null = false; + p = pend; + } /* while p */ + + /* Set `can_be_null' for the last path (also the first path, if the + pattern is empty). */ + bufp->can_be_null |= path_can_be_null; + + done: + RESET_FAIL_STACK (); + return 0; +} /* re_compile_fastmap */ +#ifdef _LIBC +weak_alias (__re_compile_fastmap, re_compile_fastmap) +#endif + +/* Set REGS to hold NUM_REGS registers, storing them in STARTS and + ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use + this memory for recording register information. STARTS and ENDS + must be allocated using the malloc library routine, and must each + be at least NUM_REGS * sizeof (regoff_t) bytes long. + + If NUM_REGS == 0, then subsequent matches should allocate their own + register data. + + Unless this function is called, the first search or match using + PATTERN_BUFFER will allocate its own register data, without + freeing the old data. */ + +void +re_set_registers (bufp, regs, num_regs, starts, ends) + struct re_pattern_buffer *bufp; + struct re_registers *regs; + unsigned num_regs; + regoff_t *starts, *ends; +{ + if (num_regs) + { + bufp->regs_allocated = REGS_REALLOCATE; + regs->num_regs = num_regs; + regs->start = starts; + regs->end = ends; + } + else + { + bufp->regs_allocated = REGS_UNALLOCATED; + regs->num_regs = 0; + regs->start = regs->end = (regoff_t *) 0; + } +} +#ifdef _LIBC +weak_alias (__re_set_registers, re_set_registers) +#endif + +/* Searching routines. */ + +/* Like re_search_2, below, but only one string is specified, and + doesn't let you say where to stop matching. */ + +int +re_search (bufp, string, size, startpos, range, regs) + struct re_pattern_buffer *bufp; + const char *string; + int size, startpos, range; + struct re_registers *regs; +{ + return re_search_2 (bufp, NULL, 0, string, size, startpos, range, + regs, size); +} +#ifdef _LIBC +weak_alias (__re_search, re_search) +#endif + + +/* Using the compiled pattern in BUFP->buffer, first tries to match the + virtual concatenation of STRING1 and STRING2, starting first at index + STARTPOS, then at STARTPOS + 1, and so on. + + STRING1 and STRING2 have length SIZE1 and SIZE2, respectively. + + RANGE is how far to scan while trying to match. RANGE = 0 means try + only at STARTPOS; in general, the last start tried is STARTPOS + + RANGE. + + In REGS, return the indices of the virtual concatenation of STRING1 + and STRING2 that matched the entire BUFP->buffer and its contained + subexpressions. + + Do not consider matching one past the index STOP in the virtual + concatenation of STRING1 and STRING2. + + We return either the position in the strings at which the match was + found, -1 if no match, or -2 if error (such as failure + stack overflow). */ + +int +re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop) + struct re_pattern_buffer *bufp; + const char *string1, *string2; + int size1, size2; + int startpos; + int range; + struct re_registers *regs; + int stop; +{ + int val; + register char *fastmap = bufp->fastmap; + register RE_TRANSLATE_TYPE translate = bufp->translate; + int total_size = size1 + size2; + int endpos = startpos + range; + + /* Check for out-of-range STARTPOS. */ + if (startpos < 0 || startpos > total_size) + return -1; + + /* Fix up RANGE if it might eventually take us outside + the virtual concatenation of STRING1 and STRING2. + Make sure we won't move STARTPOS below 0 or above TOTAL_SIZE. */ + if (endpos < 0) + range = 0 - startpos; + else if (endpos > total_size) + range = total_size - startpos; + + /* If the search isn't to be a backwards one, don't waste time in a + search for a pattern that must be anchored. */ + if (bufp->used > 0 && range > 0 + && ((re_opcode_t) bufp->buffer[0] == begbuf + /* `begline' is like `begbuf' if it cannot match at newlines. */ + || ((re_opcode_t) bufp->buffer[0] == begline + && !bufp->newline_anchor))) + { + if (startpos > 0) + return -1; + else + range = 1; + } + +#ifdef emacs + /* In a forward search for something that starts with \=. + don't keep searching past point. */ + if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == at_dot && range > 0) + { + range = PT - startpos; + if (range <= 0) + return -1; + } +#endif /* emacs */ + + /* Update the fastmap now if not correct already. */ + if (fastmap && !bufp->fastmap_accurate) + if (re_compile_fastmap (bufp) == -2) + return -2; + + /* Loop through the string, looking for a place to start matching. */ + for (;;) + { + /* If a fastmap is supplied, skip quickly over characters that + cannot be the start of a match. If the pattern can match the + null string, however, we don't need to skip characters; we want + the first null string. */ + if (fastmap && startpos < total_size && !bufp->can_be_null) + { + if (range > 0) /* Searching forwards. */ + { + register const char *d; + register int lim = 0; + int irange = range; + + if (startpos < size1 && startpos + range >= size1) + lim = range - (size1 - startpos); + + d = (startpos >= size1 ? string2 - size1 : string1) + startpos; + + /* Written out as an if-else to avoid testing `translate' + inside the loop. */ + if (translate) + while (range > lim + && !fastmap[(unsigned char) + translate[(unsigned char) *d++]]) + range--; + else + while (range > lim && !fastmap[(unsigned char) *d++]) + range--; + + startpos += irange - range; + } + else /* Searching backwards. */ + { + register char c = (size1 == 0 || startpos >= size1 + ? string2[startpos - size1] + : string1[startpos]); + + if (!fastmap[(unsigned char) TRANSLATE (c)]) + goto advance; + } + } + + /* If can't match the null string, and that's all we have left, fail. */ + if (range >= 0 && startpos == total_size && fastmap + && !bufp->can_be_null) + return -1; + + val = re_match_2_internal (bufp, string1, size1, string2, size2, + startpos, regs, stop); +#ifndef REGEX_MALLOC +# ifdef C_ALLOCA + alloca (0); +# endif +#endif + + if (val >= 0) + return startpos; + + if (val == -2) + return -2; + + advance: + if (!range) + break; + else if (range > 0) + { + range--; + startpos++; + } + else + { + range++; + startpos--; + } + } + return -1; +} /* re_search_2 */ +#ifdef _LIBC +weak_alias (__re_search_2, re_search_2) +#endif + +/* This converts PTR, a pointer into one of the search strings `string1' + and `string2' into an offset from the beginning of that string. */ +#define POINTER_TO_OFFSET(ptr) \ + (FIRST_STRING_P (ptr) \ + ? ((regoff_t) ((ptr) - string1)) \ + : ((regoff_t) ((ptr) - string2 + size1))) + +/* Macros for dealing with the split strings in re_match_2. */ + +#define MATCHING_IN_FIRST_STRING (dend == end_match_1) + +/* Call before fetching a character with *d. This switches over to + string2 if necessary. */ +#define PREFETCH() \ + while (d == dend) \ + { \ + /* End of string2 => fail. */ \ + if (dend == end_match_2) \ + goto fail; \ + /* End of string1 => advance to string2. */ \ + d = string2; \ + dend = end_match_2; \ + } + + +/* Test if at very beginning or at very end of the virtual concatenation + of `string1' and `string2'. If only one string, it's `string2'. */ +#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2) +#define AT_STRINGS_END(d) ((d) == end2) + + +/* Test if D points to a character which is word-constituent. We have + two special cases to check for: if past the end of string1, look at + the first character in string2; and if before the beginning of + string2, look at the last character in string1. */ +#define WORDCHAR_P(d) \ + (SYNTAX ((d) == end1 ? *string2 \ + : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \ + == Sword) + +/* Disabled due to a compiler bug -- see comment at case wordbound */ +#if 0 +/* Test if the character before D and the one at D differ with respect + to being word-constituent. */ +#define AT_WORD_BOUNDARY(d) \ + (AT_STRINGS_BEG (d) || AT_STRINGS_END (d) \ + || WORDCHAR_P (d - 1) != WORDCHAR_P (d)) +#endif + +/* Free everything we malloc. */ +#ifdef MATCH_MAY_ALLOCATE +# define FREE_VAR(var) if (var) REGEX_FREE (var); var = NULL +# define FREE_VARIABLES() \ + do { \ + REGEX_FREE_STACK (fail_stack.stack); \ + FREE_VAR (regstart); \ + FREE_VAR (regend); \ + FREE_VAR (old_regstart); \ + FREE_VAR (old_regend); \ + FREE_VAR (best_regstart); \ + FREE_VAR (best_regend); \ + FREE_VAR (reg_info); \ + FREE_VAR (reg_dummy); \ + FREE_VAR (reg_info_dummy); \ + } while (0) +#else +# define FREE_VARIABLES() ((void)0) /* Do nothing! But inhibit gcc warning. */ +#endif /* not MATCH_MAY_ALLOCATE */ + +/* These values must meet several constraints. They must not be valid + register values; since we have a limit of 255 registers (because + we use only one byte in the pattern for the register number), we can + use numbers larger than 255. They must differ by 1, because of + NUM_FAILURE_ITEMS above. And the value for the lowest register must + be larger than the value for the highest register, so we do not try + to actually save any registers when none are active. */ +#define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH) +#define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1) + +/* Matching routines. */ + +#ifndef emacs /* Emacs never uses this. */ +/* re_match is like re_match_2 except it takes only a single string. */ + +int +re_match (bufp, string, size, pos, regs) + struct re_pattern_buffer *bufp; + const char *string; + int size, pos; + struct re_registers *regs; +{ + int result = re_match_2_internal (bufp, NULL, 0, string, size, + pos, regs, size); +# ifndef REGEX_MALLOC +# ifdef C_ALLOCA + alloca (0); +# endif +# endif + return result; +} +# ifdef _LIBC +weak_alias (__re_match, re_match) +# endif +#endif /* not emacs */ + +static boolean group_match_null_string_p _RE_ARGS ((unsigned char **p, + unsigned char *end, + register_info_type *reg_info)); +static boolean alt_match_null_string_p _RE_ARGS ((unsigned char *p, + unsigned char *end, + register_info_type *reg_info)); +static boolean common_op_match_null_string_p _RE_ARGS ((unsigned char **p, + unsigned char *end, + register_info_type *reg_info)); +static int bcmp_translate _RE_ARGS ((const char *s1, const char *s2, + int len, char *translate)); + +/* re_match_2 matches the compiled pattern in BUFP against the + the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1 + and SIZE2, respectively). We start matching at POS, and stop + matching at STOP. + + If REGS is non-null and the `no_sub' field of BUFP is nonzero, we + store offsets for the substring each group matched in REGS. See the + documentation for exactly how many groups we fill. + + We return -1 if no match, -2 if an internal error (such as the + failure stack overflowing). Otherwise, we return the length of the + matched substring. */ + +int +re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) + struct re_pattern_buffer *bufp; + const char *string1, *string2; + int size1, size2; + int pos; + struct re_registers *regs; + int stop; +{ + int result = re_match_2_internal (bufp, string1, size1, string2, size2, + pos, regs, stop); +#ifndef REGEX_MALLOC +# ifdef C_ALLOCA + alloca (0); +# endif +#endif + return result; +} +#ifdef _LIBC +weak_alias (__re_match_2, re_match_2) +#endif + +/* This is a separate function so that we can force an alloca cleanup + afterwards. */ +static int +re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop) + struct re_pattern_buffer *bufp; + const char *string1, *string2; + int size1, size2; + int pos; + struct re_registers *regs; + int stop; +{ + /* General temporaries. */ + int mcnt; + unsigned char *p1; + + /* Just past the end of the corresponding string. */ + const char *end1, *end2; + + /* Pointers into string1 and string2, just past the last characters in + each to consider matching. */ + const char *end_match_1, *end_match_2; + + /* Where we are in the data, and the end of the current string. */ + const char *d, *dend; + + /* Where we are in the pattern, and the end of the pattern. */ + unsigned char *p = bufp->buffer; + register unsigned char *pend = p + bufp->used; + + /* Mark the opcode just after a start_memory, so we can test for an + empty subpattern when we get to the stop_memory. */ + unsigned char *just_past_start_mem = 0; + + /* We use this to map every character in the string. */ + RE_TRANSLATE_TYPE translate = bufp->translate; + + /* Failure point stack. Each place that can handle a failure further + down the line pushes a failure point on this stack. It consists of + restart, regend, and reg_info for all registers corresponding to + the subexpressions we're currently inside, plus the number of such + registers, and, finally, two char *'s. The first char * is where + to resume scanning the pattern; the second one is where to resume + scanning the strings. If the latter is zero, the failure point is + a ``dummy''; if a failure happens and the failure point is a dummy, + it gets discarded and the next next one is tried. */ +#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */ + fail_stack_type fail_stack; +#endif +#ifdef DEBUG + static unsigned failure_id = 0; + unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0; +#endif + +#ifdef REL_ALLOC + /* This holds the pointer to the failure stack, when + it is allocated relocatably. */ + fail_stack_elt_t *failure_stack_ptr; +#endif + + /* We fill all the registers internally, independent of what we + return, for use in backreferences. The number here includes + an element for register zero. */ + size_t num_regs = bufp->re_nsub + 1; + + /* The currently active registers. */ + active_reg_t lowest_active_reg = NO_LOWEST_ACTIVE_REG; + active_reg_t highest_active_reg = NO_HIGHEST_ACTIVE_REG; + + /* Information on the contents of registers. These are pointers into + the input strings; they record just what was matched (on this + attempt) by a subexpression part of the pattern, that is, the + regnum-th regstart pointer points to where in the pattern we began + matching and the regnum-th regend points to right after where we + stopped matching the regnum-th subexpression. (The zeroth register + keeps track of what the whole pattern matches.) */ +#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ + const char **regstart, **regend; +#endif + + /* If a group that's operated upon by a repetition operator fails to + match anything, then the register for its start will need to be + restored because it will have been set to wherever in the string we + are when we last see its open-group operator. Similarly for a + register's end. */ +#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ + const char **old_regstart, **old_regend; +#endif + + /* The is_active field of reg_info helps us keep track of which (possibly + nested) subexpressions we are currently in. The matched_something + field of reg_info[reg_num] helps us tell whether or not we have + matched any of the pattern so far this time through the reg_num-th + subexpression. These two fields get reset each time through any + loop their register is in. */ +#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */ + register_info_type *reg_info; +#endif + + /* The following record the register info as found in the above + variables when we find a match better than any we've seen before. + This happens as we backtrack through the failure points, which in + turn happens only if we have not yet matched the entire string. */ + unsigned best_regs_set = false; +#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ + const char **best_regstart, **best_regend; +#endif + + /* Logically, this is `best_regend[0]'. But we don't want to have to + allocate space for that if we're not allocating space for anything + else (see below). Also, we never need info about register 0 for + any of the other register vectors, and it seems rather a kludge to + treat `best_regend' differently than the rest. So we keep track of + the end of the best match so far in a separate variable. We + initialize this to NULL so that when we backtrack the first time + and need to test it, it's not garbage. */ + const char *match_end = NULL; + + /* This helps SET_REGS_MATCHED avoid doing redundant work. */ + int set_regs_matched_done = 0; + + /* Used when we pop values we don't care about. */ +#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ + const char **reg_dummy; + register_info_type *reg_info_dummy; +#endif + +#ifdef DEBUG + /* Counts the total number of registers pushed. */ + unsigned num_regs_pushed = 0; +#endif + + DEBUG_PRINT1 ("\n\nEntering re_match_2.\n"); + + INIT_FAIL_STACK (); + +#ifdef MATCH_MAY_ALLOCATE + /* Do not bother to initialize all the register variables if there are + no groups in the pattern, as it takes a fair amount of time. If + there are groups, we include space for register 0 (the whole + pattern), even though we never use it, since it simplifies the + array indexing. We should fix this. */ + if (bufp->re_nsub) + { + regstart = REGEX_TALLOC (num_regs, const char *); + regend = REGEX_TALLOC (num_regs, const char *); + old_regstart = REGEX_TALLOC (num_regs, const char *); + old_regend = REGEX_TALLOC (num_regs, const char *); + best_regstart = REGEX_TALLOC (num_regs, const char *); + best_regend = REGEX_TALLOC (num_regs, const char *); + reg_info = REGEX_TALLOC (num_regs, register_info_type); + reg_dummy = REGEX_TALLOC (num_regs, const char *); + reg_info_dummy = REGEX_TALLOC (num_regs, register_info_type); + + if (!(regstart && regend && old_regstart && old_regend && reg_info + && best_regstart && best_regend && reg_dummy && reg_info_dummy)) + { + FREE_VARIABLES (); + return -2; + } + } + else + { + /* We must initialize all our variables to NULL, so that + `FREE_VARIABLES' doesn't try to free them. */ + regstart = regend = old_regstart = old_regend = best_regstart + = best_regend = reg_dummy = NULL; + reg_info = reg_info_dummy = (register_info_type *) NULL; + } +#endif /* MATCH_MAY_ALLOCATE */ + + /* The starting position is bogus. */ + if (pos < 0 || pos > size1 + size2) + { + FREE_VARIABLES (); + return -1; + } + + /* Initialize subexpression text positions to -1 to mark ones that no + start_memory/stop_memory has been seen for. Also initialize the + register information struct. */ + for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++) + { + regstart[mcnt] = regend[mcnt] + = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE; + + REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE; + IS_ACTIVE (reg_info[mcnt]) = 0; + MATCHED_SOMETHING (reg_info[mcnt]) = 0; + EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0; + } + + /* We move `string1' into `string2' if the latter's empty -- but not if + `string1' is null. */ + if (size2 == 0 && string1 != NULL) + { + string2 = string1; + size2 = size1; + string1 = 0; + size1 = 0; + } + end1 = string1 + size1; + end2 = string2 + size2; + + /* Compute where to stop matching, within the two strings. */ + if (stop <= size1) + { + end_match_1 = string1 + stop; + end_match_2 = string2; + } + else + { + end_match_1 = end1; + end_match_2 = string2 + stop - size1; + } + + /* `p' scans through the pattern as `d' scans through the data. + `dend' is the end of the input string that `d' points within. `d' + is advanced into the following input string whenever necessary, but + this happens before fetching; therefore, at the beginning of the + loop, `d' can be pointing at the end of a string, but it cannot + equal `string2'. */ + if (size1 > 0 && pos <= size1) + { + d = string1 + pos; + dend = end_match_1; + } + else + { + d = string2 + pos - size1; + dend = end_match_2; + } + + DEBUG_PRINT1 ("The compiled pattern is:\n"); + DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend); + DEBUG_PRINT1 ("The string to match is: `"); + DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2); + DEBUG_PRINT1 ("'\n"); + + /* This loops over pattern commands. It exits by returning from the + function if the match is complete, or it drops through if the match + fails at this starting point in the input data. */ + for (;;) + { +#ifdef _LIBC + DEBUG_PRINT2 ("\n%p: ", p); +#else + DEBUG_PRINT2 ("\n0x%x: ", p); +#endif + + if (p == pend) + { /* End of pattern means we might have succeeded. */ + DEBUG_PRINT1 ("end of pattern ... "); + + /* If we haven't matched the entire string, and we want the + longest match, try backtracking. */ + if (d != end_match_2) + { + /* 1 if this match ends in the same string (string1 or string2) + as the best previous match. */ + boolean same_str_p = (FIRST_STRING_P (match_end) + == MATCHING_IN_FIRST_STRING); + /* 1 if this match is the best seen so far. */ + boolean best_match_p; + + /* AIX compiler got confused when this was combined + with the previous declaration. */ + if (same_str_p) + best_match_p = d > match_end; + else + best_match_p = !MATCHING_IN_FIRST_STRING; + + DEBUG_PRINT1 ("backtracking.\n"); + + if (!FAIL_STACK_EMPTY ()) + { /* More failure points to try. */ + + /* If exceeds best match so far, save it. */ + if (!best_regs_set || best_match_p) + { + best_regs_set = true; + match_end = d; + + DEBUG_PRINT1 ("\nSAVING match as best so far.\n"); + + for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++) + { + best_regstart[mcnt] = regstart[mcnt]; + best_regend[mcnt] = regend[mcnt]; + } + } + goto fail; + } + + /* If no failure points, don't restore garbage. And if + last match is real best match, don't restore second + best one. */ + else if (best_regs_set && !best_match_p) + { + restore_best_regs: + /* Restore best match. It may happen that `dend == + end_match_1' while the restored d is in string2. + For example, the pattern `x.*y.*z' against the + strings `x-' and `y-z-', if the two strings are + not consecutive in memory. */ + DEBUG_PRINT1 ("Restoring best registers.\n"); + + d = match_end; + dend = ((d >= string1 && d <= end1) + ? end_match_1 : end_match_2); + + for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++) + { + regstart[mcnt] = best_regstart[mcnt]; + regend[mcnt] = best_regend[mcnt]; + } + } + } /* d != end_match_2 */ + + succeed_label: + DEBUG_PRINT1 ("Accepting match.\n"); + + /* If caller wants register contents data back, do it. */ + if (regs && !bufp->no_sub) + { + /* Have the register data arrays been allocated? */ + if (bufp->regs_allocated == REGS_UNALLOCATED) + { /* No. So allocate them with malloc. We need one + extra element beyond `num_regs' for the `-1' marker + GNU code uses. */ + regs->num_regs = MAX (RE_NREGS, num_regs + 1); + regs->start = TALLOC (regs->num_regs, regoff_t); + regs->end = TALLOC (regs->num_regs, regoff_t); + if (regs->start == NULL || regs->end == NULL) + { + FREE_VARIABLES (); + return -2; + } + bufp->regs_allocated = REGS_REALLOCATE; + } + else if (bufp->regs_allocated == REGS_REALLOCATE) + { /* Yes. If we need more elements than were already + allocated, reallocate them. If we need fewer, just + leave it alone. */ + if (regs->num_regs < num_regs + 1) + { + regs->num_regs = num_regs + 1; + RETALLOC (regs->start, regs->num_regs, regoff_t); + RETALLOC (regs->end, regs->num_regs, regoff_t); + if (regs->start == NULL || regs->end == NULL) + { + FREE_VARIABLES (); + return -2; + } + } + } + else + { + /* These braces fend off a "empty body in an else-statement" + warning under GCC when assert expands to nothing. */ + assert (bufp->regs_allocated == REGS_FIXED); + } + + /* Convert the pointer data in `regstart' and `regend' to + indices. Register zero has to be set differently, + since we haven't kept track of any info for it. */ + if (regs->num_regs > 0) + { + regs->start[0] = pos; + regs->end[0] = (MATCHING_IN_FIRST_STRING + ? ((regoff_t) (d - string1)) + : ((regoff_t) (d - string2 + size1))); + } + + /* Go through the first `min (num_regs, regs->num_regs)' + registers, since that is all we initialized. */ + for (mcnt = 1; (unsigned) mcnt < MIN (num_regs, regs->num_regs); + mcnt++) + { + if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt])) + regs->start[mcnt] = regs->end[mcnt] = -1; + else + { + regs->start[mcnt] + = (regoff_t) POINTER_TO_OFFSET (regstart[mcnt]); + regs->end[mcnt] + = (regoff_t) POINTER_TO_OFFSET (regend[mcnt]); + } + } + + /* If the regs structure we return has more elements than + were in the pattern, set the extra elements to -1. If + we (re)allocated the registers, this is the case, + because we always allocate enough to have at least one + -1 at the end. */ + for (mcnt = num_regs; (unsigned) mcnt < regs->num_regs; mcnt++) + regs->start[mcnt] = regs->end[mcnt] = -1; + } /* regs && !bufp->no_sub */ + + DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n", + nfailure_points_pushed, nfailure_points_popped, + nfailure_points_pushed - nfailure_points_popped); + DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed); + + mcnt = d - pos - (MATCHING_IN_FIRST_STRING + ? string1 + : string2 - size1); + + DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt); + + FREE_VARIABLES (); + return mcnt; + } + + /* Otherwise match next pattern command. */ + switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++)) + { + /* Ignore these. Used to ignore the n of succeed_n's which + currently have n == 0. */ + case no_op: + DEBUG_PRINT1 ("EXECUTING no_op.\n"); + break; + + case succeed: + DEBUG_PRINT1 ("EXECUTING succeed.\n"); + goto succeed_label; + + /* Match the next n pattern characters exactly. The following + byte in the pattern defines n, and the n bytes after that + are the characters to match. */ + case exactn: + mcnt = *p++; + DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt); + + /* This is written out as an if-else so we don't waste time + testing `translate' inside the loop. */ + if (translate) + { + do + { + PREFETCH (); + if ((unsigned char) translate[(unsigned char) *d++] + != (unsigned char) *p++) + goto fail; + } + while (--mcnt); + } + else + { + do + { + PREFETCH (); + if (*d++ != (char) *p++) goto fail; + } + while (--mcnt); + } + SET_REGS_MATCHED (); + break; + + + /* Match any character except possibly a newline or a null. */ + case anychar: + DEBUG_PRINT1 ("EXECUTING anychar.\n"); + + PREFETCH (); + + if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n') + || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000')) + goto fail; + + SET_REGS_MATCHED (); + DEBUG_PRINT2 (" Matched `%d'.\n", *d); + d++; + break; + + + case charset: + case charset_not: + { + register unsigned char c; + boolean not = (re_opcode_t) *(p - 1) == charset_not; + + DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : ""); + + PREFETCH (); + c = TRANSLATE (*d); /* The character to match. */ + + /* Cast to `unsigned' instead of `unsigned char' in case the + bit list is a full 32 bytes long. */ + if (c < (unsigned) (*p * BYTEWIDTH) + && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) + not = !not; + + p += 1 + *p; + + if (!not) goto fail; + + SET_REGS_MATCHED (); + d++; + break; + } + + + /* The beginning of a group is represented by start_memory. + The arguments are the register number in the next byte, and the + number of groups inner to this one in the next. The text + matched within the group is recorded (in the internal + registers data structure) under the register number. */ + case start_memory: + DEBUG_PRINT3 ("EXECUTING start_memory %d (%d):\n", *p, p[1]); + + /* Find out if this group can match the empty string. */ + p1 = p; /* To send to group_match_null_string_p. */ + + if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE) + REG_MATCH_NULL_STRING_P (reg_info[*p]) + = group_match_null_string_p (&p1, pend, reg_info); + + /* Save the position in the string where we were the last time + we were at this open-group operator in case the group is + operated upon by a repetition operator, e.g., with `(a*)*b' + against `ab'; then we want to ignore where we are now in + the string in case this attempt to match fails. */ + old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p]) + ? REG_UNSET (regstart[*p]) ? d : regstart[*p] + : regstart[*p]; + DEBUG_PRINT2 (" old_regstart: %d\n", + POINTER_TO_OFFSET (old_regstart[*p])); + + regstart[*p] = d; + DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p])); + + IS_ACTIVE (reg_info[*p]) = 1; + MATCHED_SOMETHING (reg_info[*p]) = 0; + + /* Clear this whenever we change the register activity status. */ + set_regs_matched_done = 0; + + /* This is the new highest active register. */ + highest_active_reg = *p; + + /* If nothing was active before, this is the new lowest active + register. */ + if (lowest_active_reg == NO_LOWEST_ACTIVE_REG) + lowest_active_reg = *p; + + /* Move past the register number and inner group count. */ + p += 2; + just_past_start_mem = p; + + break; + + + /* The stop_memory opcode represents the end of a group. Its + arguments are the same as start_memory's: the register + number, and the number of inner groups. */ + case stop_memory: + DEBUG_PRINT3 ("EXECUTING stop_memory %d (%d):\n", *p, p[1]); + + /* We need to save the string position the last time we were at + this close-group operator in case the group is operated + upon by a repetition operator, e.g., with `((a*)*(b*)*)*' + against `aba'; then we want to ignore where we are now in + the string in case this attempt to match fails. */ + old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p]) + ? REG_UNSET (regend[*p]) ? d : regend[*p] + : regend[*p]; + DEBUG_PRINT2 (" old_regend: %d\n", + POINTER_TO_OFFSET (old_regend[*p])); + + regend[*p] = d; + DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p])); + + /* This register isn't active anymore. */ + IS_ACTIVE (reg_info[*p]) = 0; + + /* Clear this whenever we change the register activity status. */ + set_regs_matched_done = 0; + + /* If this was the only register active, nothing is active + anymore. */ + if (lowest_active_reg == highest_active_reg) + { + lowest_active_reg = NO_LOWEST_ACTIVE_REG; + highest_active_reg = NO_HIGHEST_ACTIVE_REG; + } + else + { /* We must scan for the new highest active register, since + it isn't necessarily one less than now: consider + (a(b)c(d(e)f)g). When group 3 ends, after the f), the + new highest active register is 1. */ + unsigned char r = *p - 1; + while (r > 0 && !IS_ACTIVE (reg_info[r])) + r--; + + /* If we end up at register zero, that means that we saved + the registers as the result of an `on_failure_jump', not + a `start_memory', and we jumped to past the innermost + `stop_memory'. For example, in ((.)*) we save + registers 1 and 2 as a result of the *, but when we pop + back to the second ), we are at the stop_memory 1. + Thus, nothing is active. */ + if (r == 0) + { + lowest_active_reg = NO_LOWEST_ACTIVE_REG; + highest_active_reg = NO_HIGHEST_ACTIVE_REG; + } + else + highest_active_reg = r; + } + + /* If just failed to match something this time around with a + group that's operated on by a repetition operator, try to + force exit from the ``loop'', and restore the register + information for this group that we had before trying this + last match. */ + if ((!MATCHED_SOMETHING (reg_info[*p]) + || just_past_start_mem == p - 1) + && (p + 2) < pend) + { + boolean is_a_jump_n = false; + + p1 = p + 2; + mcnt = 0; + switch ((re_opcode_t) *p1++) + { + case jump_n: + is_a_jump_n = true; + case pop_failure_jump: + case maybe_pop_jump: + case jump: + case dummy_failure_jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + if (is_a_jump_n) + p1 += 2; + break; + + default: + /* do nothing */ ; + } + p1 += mcnt; + + /* If the next operation is a jump backwards in the pattern + to an on_failure_jump right before the start_memory + corresponding to this stop_memory, exit from the loop + by forcing a failure after pushing on the stack the + on_failure_jump's jump in the pattern, and d. */ + if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump + && (re_opcode_t) p1[3] == start_memory && p1[4] == *p) + { + /* If this group ever matched anything, then restore + what its registers were before trying this last + failed match, e.g., with `(a*)*b' against `ab' for + regstart[1], and, e.g., with `((a*)*(b*)*)*' + against `aba' for regend[3]. + + Also restore the registers for inner groups for, + e.g., `((a*)(b*))*' against `aba' (register 3 would + otherwise get trashed). */ + + if (EVER_MATCHED_SOMETHING (reg_info[*p])) + { + unsigned r; + + EVER_MATCHED_SOMETHING (reg_info[*p]) = 0; + + /* Restore this and inner groups' (if any) registers. */ + for (r = *p; r < (unsigned) *p + (unsigned) *(p + 1); + r++) + { + regstart[r] = old_regstart[r]; + + /* xx why this test? */ + if (old_regend[r] >= regstart[r]) + regend[r] = old_regend[r]; + } + } + p1++; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + PUSH_FAILURE_POINT (p1 + mcnt, d, -2); + + goto fail; + } + } + + /* Move past the register number and the inner group count. */ + p += 2; + break; + + + /* \ has been turned into a `duplicate' command which is + followed by the numeric value of as the register number. */ + case duplicate: + { + register const char *d2, *dend2; + int regno = *p++; /* Get which register to match against. */ + DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno); + + /* Can't back reference a group which we've never matched. */ + if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno])) + goto fail; + + /* Where in input to try to start matching. */ + d2 = regstart[regno]; + + /* Where to stop matching; if both the place to start and + the place to stop matching are in the same string, then + set to the place to stop, otherwise, for now have to use + the end of the first string. */ + + dend2 = ((FIRST_STRING_P (regstart[regno]) + == FIRST_STRING_P (regend[regno])) + ? regend[regno] : end_match_1); + for (;;) + { + /* If necessary, advance to next segment in register + contents. */ + while (d2 == dend2) + { + if (dend2 == end_match_2) break; + if (dend2 == regend[regno]) break; + + /* End of string1 => advance to string2. */ + d2 = string2; + dend2 = regend[regno]; + } + /* At end of register contents => success */ + if (d2 == dend2) break; + + /* If necessary, advance to next segment in data. */ + PREFETCH (); + + /* How many characters left in this segment to match. */ + mcnt = dend - d; + + /* Want how many consecutive characters we can match in + one shot, so, if necessary, adjust the count. */ + if (mcnt > dend2 - d2) + mcnt = dend2 - d2; + + /* Compare that many; failure if mismatch, else move + past them. */ + if (translate + ? bcmp_translate (d, d2, mcnt, translate) + : memcmp (d, d2, mcnt)) + goto fail; + d += mcnt, d2 += mcnt; + + /* Do this because we've match some characters. */ + SET_REGS_MATCHED (); + } + } + break; + + + /* begline matches the empty string at the beginning of the string + (unless `not_bol' is set in `bufp'), and, if + `newline_anchor' is set, after newlines. */ + case begline: + DEBUG_PRINT1 ("EXECUTING begline.\n"); + + if (AT_STRINGS_BEG (d)) + { + if (!bufp->not_bol) break; + } + else if (d[-1] == '\n' && bufp->newline_anchor) + { + break; + } + /* In all other cases, we fail. */ + goto fail; + + + /* endline is the dual of begline. */ + case endline: + DEBUG_PRINT1 ("EXECUTING endline.\n"); + + if (AT_STRINGS_END (d)) + { + if (!bufp->not_eol) break; + } + + /* We have to ``prefetch'' the next character. */ + else if ((d == end1 ? *string2 : *d) == '\n' + && bufp->newline_anchor) + { + break; + } + goto fail; + + + /* Match at the very beginning of the data. */ + case begbuf: + DEBUG_PRINT1 ("EXECUTING begbuf.\n"); + if (AT_STRINGS_BEG (d)) + break; + goto fail; + + + /* Match at the very end of the data. */ + case endbuf: + DEBUG_PRINT1 ("EXECUTING endbuf.\n"); + if (AT_STRINGS_END (d)) + break; + goto fail; + + + /* on_failure_keep_string_jump is used to optimize `.*\n'. It + pushes NULL as the value for the string on the stack. Then + `pop_failure_point' will keep the current value for the + string, instead of restoring it. To see why, consider + matching `foo\nbar' against `.*\n'. The .* matches the foo; + then the . fails against the \n. But the next thing we want + to do is match the \n against the \n; if we restored the + string value, we would be back at the foo. + + Because this is used only in specific cases, we don't need to + check all the things that `on_failure_jump' does, to make + sure the right things get saved on the stack. Hence we don't + share its code. The only reason to push anything on the + stack at all is that otherwise we would have to change + `anychar's code to do something besides goto fail in this + case; that seems worse than this. */ + case on_failure_keep_string_jump: + DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump"); + + EXTRACT_NUMBER_AND_INCR (mcnt, p); +#ifdef _LIBC + DEBUG_PRINT3 (" %d (to %p):\n", mcnt, p + mcnt); +#else + DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt); +#endif + + PUSH_FAILURE_POINT (p + mcnt, NULL, -2); + break; + + + /* Uses of on_failure_jump: + + Each alternative starts with an on_failure_jump that points + to the beginning of the next alternative. Each alternative + except the last ends with a jump that in effect jumps past + the rest of the alternatives. (They really jump to the + ending jump of the following alternative, because tensioning + these jumps is a hassle.) + + Repeats start with an on_failure_jump that points past both + the repetition text and either the following jump or + pop_failure_jump back to this on_failure_jump. */ + case on_failure_jump: + on_failure: + DEBUG_PRINT1 ("EXECUTING on_failure_jump"); + + EXTRACT_NUMBER_AND_INCR (mcnt, p); +#ifdef _LIBC + DEBUG_PRINT3 (" %d (to %p)", mcnt, p + mcnt); +#else + DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt); +#endif + + /* If this on_failure_jump comes right before a group (i.e., + the original * applied to a group), save the information + for that group and all inner ones, so that if we fail back + to this point, the group's information will be correct. + For example, in \(a*\)*\1, we need the preceding group, + and in \(zz\(a*\)b*\)\2, we need the inner group. */ + + /* We can't use `p' to check ahead because we push + a failure point to `p + mcnt' after we do this. */ + p1 = p; + + /* We need to skip no_op's before we look for the + start_memory in case this on_failure_jump is happening as + the result of a completed succeed_n, as in \(a\)\{1,3\}b\1 + against aba. */ + while (p1 < pend && (re_opcode_t) *p1 == no_op) + p1++; + + if (p1 < pend && (re_opcode_t) *p1 == start_memory) + { + /* We have a new highest active register now. This will + get reset at the start_memory we are about to get to, + but we will have saved all the registers relevant to + this repetition op, as described above. */ + highest_active_reg = *(p1 + 1) + *(p1 + 2); + if (lowest_active_reg == NO_LOWEST_ACTIVE_REG) + lowest_active_reg = *(p1 + 1); + } + + DEBUG_PRINT1 (":\n"); + PUSH_FAILURE_POINT (p + mcnt, d, -2); + break; + + + /* A smart repeat ends with `maybe_pop_jump'. + We change it to either `pop_failure_jump' or `jump'. */ + case maybe_pop_jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt); + { + register unsigned char *p2 = p; + + /* Compare the beginning of the repeat with what in the + pattern follows its end. If we can establish that there + is nothing that they would both match, i.e., that we + would have to backtrack because of (as in, e.g., `a*a') + then we can change to pop_failure_jump, because we'll + never have to backtrack. + + This is not true in the case of alternatives: in + `(a|ab)*' we do need to backtrack to the `ab' alternative + (e.g., if the string was `ab'). But instead of trying to + detect that here, the alternative has put on a dummy + failure point which is what we will end up popping. */ + + /* Skip over open/close-group commands. + If what follows this loop is a ...+ construct, + look at what begins its body, since we will have to + match at least one of that. */ + while (1) + { + if (p2 + 2 < pend + && ((re_opcode_t) *p2 == stop_memory + || (re_opcode_t) *p2 == start_memory)) + p2 += 3; + else if (p2 + 6 < pend + && (re_opcode_t) *p2 == dummy_failure_jump) + p2 += 6; + else + break; + } + + p1 = p + mcnt; + /* p1[0] ... p1[2] are the `on_failure_jump' corresponding + to the `maybe_finalize_jump' of this case. Examine what + follows. */ + + /* If we're at the end of the pattern, we can change. */ + if (p2 == pend) + { + /* Consider what happens when matching ":\(.*\)" + against ":/". I don't really understand this code + yet. */ + p[-3] = (unsigned char) pop_failure_jump; + DEBUG_PRINT1 + (" End of pattern: change to `pop_failure_jump'.\n"); + } + + else if ((re_opcode_t) *p2 == exactn + || (bufp->newline_anchor && (re_opcode_t) *p2 == endline)) + { + register unsigned char c + = *p2 == (unsigned char) endline ? '\n' : p2[2]; + + if ((re_opcode_t) p1[3] == exactn && p1[5] != c) + { + p[-3] = (unsigned char) pop_failure_jump; + DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n", + c, p1[5]); + } + + else if ((re_opcode_t) p1[3] == charset + || (re_opcode_t) p1[3] == charset_not) + { + int not = (re_opcode_t) p1[3] == charset_not; + + if (c < (unsigned char) (p1[4] * BYTEWIDTH) + && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) + not = !not; + + /* `not' is equal to 1 if c would match, which means + that we can't change to pop_failure_jump. */ + if (!not) + { + p[-3] = (unsigned char) pop_failure_jump; + DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); + } + } + } + else if ((re_opcode_t) *p2 == charset) + { +#ifdef DEBUG + register unsigned char c + = *p2 == (unsigned char) endline ? '\n' : p2[2]; +#endif + +#if 0 + if ((re_opcode_t) p1[3] == exactn + && ! ((int) p2[1] * BYTEWIDTH > (int) p1[5] + && (p2[2 + p1[5] / BYTEWIDTH] + & (1 << (p1[5] % BYTEWIDTH))))) +#else + if ((re_opcode_t) p1[3] == exactn + && ! ((int) p2[1] * BYTEWIDTH > (int) p1[4] + && (p2[2 + p1[4] / BYTEWIDTH] + & (1 << (p1[4] % BYTEWIDTH))))) +#endif + { + p[-3] = (unsigned char) pop_failure_jump; + DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n", + c, p1[5]); + } + + else if ((re_opcode_t) p1[3] == charset_not) + { + int idx; + /* We win if the charset_not inside the loop + lists every character listed in the charset after. */ + for (idx = 0; idx < (int) p2[1]; idx++) + if (! (p2[2 + idx] == 0 + || (idx < (int) p1[4] + && ((p2[2 + idx] & ~ p1[5 + idx]) == 0)))) + break; + + if (idx == p2[1]) + { + p[-3] = (unsigned char) pop_failure_jump; + DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); + } + } + else if ((re_opcode_t) p1[3] == charset) + { + int idx; + /* We win if the charset inside the loop + has no overlap with the one after the loop. */ + for (idx = 0; + idx < (int) p2[1] && idx < (int) p1[4]; + idx++) + if ((p2[2 + idx] & p1[5 + idx]) != 0) + break; + + if (idx == p2[1] || idx == p1[4]) + { + p[-3] = (unsigned char) pop_failure_jump; + DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); + } + } + } + } + p -= 2; /* Point at relative address again. */ + if ((re_opcode_t) p[-1] != pop_failure_jump) + { + p[-1] = (unsigned char) jump; + DEBUG_PRINT1 (" Match => jump.\n"); + goto unconditional_jump; + } + /* Note fall through. */ + + + /* The end of a simple repeat has a pop_failure_jump back to + its matching on_failure_jump, where the latter will push a + failure point. The pop_failure_jump takes off failure + points put on by this pop_failure_jump's matching + on_failure_jump; we got through the pattern to here from the + matching on_failure_jump, so didn't fail. */ + case pop_failure_jump: + { + /* We need to pass separate storage for the lowest and + highest registers, even though we don't care about the + actual values. Otherwise, we will restore only one + register from the stack, since lowest will == highest in + `pop_failure_point'. */ + active_reg_t dummy_low_reg, dummy_high_reg; + unsigned char *pdummy; + const char *sdummy; + + DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n"); + POP_FAILURE_POINT (sdummy, pdummy, + dummy_low_reg, dummy_high_reg, + reg_dummy, reg_dummy, reg_info_dummy); + } + /* Note fall through. */ + + unconditional_jump: +#ifdef _LIBC + DEBUG_PRINT2 ("\n%p: ", p); +#else + DEBUG_PRINT2 ("\n0x%x: ", p); +#endif + /* Note fall through. */ + + /* Unconditionally jump (without popping any failure points). */ + case jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */ + DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt); + p += mcnt; /* Do the jump. */ +#ifdef _LIBC + DEBUG_PRINT2 ("(to %p).\n", p); +#else + DEBUG_PRINT2 ("(to 0x%x).\n", p); +#endif + break; + + + /* We need this opcode so we can detect where alternatives end + in `group_match_null_string_p' et al. */ + case jump_past_alt: + DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n"); + goto unconditional_jump; + + + /* Normally, the on_failure_jump pushes a failure point, which + then gets popped at pop_failure_jump. We will end up at + pop_failure_jump, also, and with a pattern of, say, `a+', we + are skipping over the on_failure_jump, so we have to push + something meaningless for pop_failure_jump to pop. */ + case dummy_failure_jump: + DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n"); + /* It doesn't matter what we push for the string here. What + the code at `fail' tests is the value for the pattern. */ + PUSH_FAILURE_POINT (NULL, NULL, -2); + goto unconditional_jump; + + + /* At the end of an alternative, we need to push a dummy failure + point in case we are followed by a `pop_failure_jump', because + we don't want the failure point for the alternative to be + popped. For example, matching `(a|ab)*' against `aab' + requires that we match the `ab' alternative. */ + case push_dummy_failure: + DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n"); + /* See comments just above at `dummy_failure_jump' about the + two zeroes. */ + PUSH_FAILURE_POINT (NULL, NULL, -2); + break; + + /* Have to succeed matching what follows at least n times. + After that, handle like `on_failure_jump'. */ + case succeed_n: + EXTRACT_NUMBER (mcnt, p + 2); + DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt); + + assert (mcnt >= 0); + /* Originally, this is how many times we HAVE to succeed. */ + if (mcnt > 0) + { + mcnt--; + p += 2; + STORE_NUMBER_AND_INCR (p, mcnt); +#ifdef _LIBC + DEBUG_PRINT3 (" Setting %p to %d.\n", p - 2, mcnt); +#else + DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p - 2, mcnt); +#endif + } + else if (mcnt == 0) + { +#ifdef _LIBC + DEBUG_PRINT2 (" Setting two bytes from %p to no_op.\n", p+2); +#else + DEBUG_PRINT2 (" Setting two bytes from 0x%x to no_op.\n", p+2); +#endif + p[2] = (unsigned char) no_op; + p[3] = (unsigned char) no_op; + goto on_failure; + } + break; + + case jump_n: + EXTRACT_NUMBER (mcnt, p + 2); + DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt); + + /* Originally, this is how many times we CAN jump. */ + if (mcnt) + { + mcnt--; + STORE_NUMBER (p + 2, mcnt); +#ifdef _LIBC + DEBUG_PRINT3 (" Setting %p to %d.\n", p + 2, mcnt); +#else + DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p + 2, mcnt); +#endif + goto unconditional_jump; + } + /* If don't have to jump any more, skip over the rest of command. */ + else + p += 4; + break; + + case set_number_at: + { + DEBUG_PRINT1 ("EXECUTING set_number_at.\n"); + + EXTRACT_NUMBER_AND_INCR (mcnt, p); + p1 = p + mcnt; + EXTRACT_NUMBER_AND_INCR (mcnt, p); +#ifdef _LIBC + DEBUG_PRINT3 (" Setting %p to %d.\n", p1, mcnt); +#else + DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p1, mcnt); +#endif + STORE_NUMBER (p1, mcnt); + break; + } + +#if 0 + /* The DEC Alpha C compiler 3.x generates incorrect code for the + test WORDCHAR_P (d - 1) != WORDCHAR_P (d) in the expansion of + AT_WORD_BOUNDARY, so this code is disabled. Expanding the + macro and introducing temporary variables works around the bug. */ + + case wordbound: + DEBUG_PRINT1 ("EXECUTING wordbound.\n"); + if (AT_WORD_BOUNDARY (d)) + break; + goto fail; + + case notwordbound: + DEBUG_PRINT1 ("EXECUTING notwordbound.\n"); + if (AT_WORD_BOUNDARY (d)) + goto fail; + break; +#else + case wordbound: + { + boolean prevchar, thischar; + + DEBUG_PRINT1 ("EXECUTING wordbound.\n"); + if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d)) + break; + + prevchar = WORDCHAR_P (d - 1); + thischar = WORDCHAR_P (d); + if (prevchar != thischar) + break; + goto fail; + } + + case notwordbound: + { + boolean prevchar, thischar; + + DEBUG_PRINT1 ("EXECUTING notwordbound.\n"); + if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d)) + goto fail; + + prevchar = WORDCHAR_P (d - 1); + thischar = WORDCHAR_P (d); + if (prevchar != thischar) + goto fail; + break; + } +#endif + + case wordbeg: + DEBUG_PRINT1 ("EXECUTING wordbeg.\n"); + if (WORDCHAR_P (d) && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1))) + break; + goto fail; + + case wordend: + DEBUG_PRINT1 ("EXECUTING wordend.\n"); + if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1) + && (!WORDCHAR_P (d) || AT_STRINGS_END (d))) + break; + goto fail; + +#ifdef emacs + case before_dot: + DEBUG_PRINT1 ("EXECUTING before_dot.\n"); + if (PTR_CHAR_POS ((unsigned char *) d) >= point) + goto fail; + break; + + case at_dot: + DEBUG_PRINT1 ("EXECUTING at_dot.\n"); + if (PTR_CHAR_POS ((unsigned char *) d) != point) + goto fail; + break; + + case after_dot: + DEBUG_PRINT1 ("EXECUTING after_dot.\n"); + if (PTR_CHAR_POS ((unsigned char *) d) <= point) + goto fail; + break; + + case syntaxspec: + DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt); + mcnt = *p++; + goto matchsyntax; + + case wordchar: + DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n"); + mcnt = (int) Sword; + matchsyntax: + PREFETCH (); + /* Can't use *d++ here; SYNTAX may be an unsafe macro. */ + d++; + if (SYNTAX (d[-1]) != (enum syntaxcode) mcnt) + goto fail; + SET_REGS_MATCHED (); + break; + + case notsyntaxspec: + DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt); + mcnt = *p++; + goto matchnotsyntax; + + case notwordchar: + DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n"); + mcnt = (int) Sword; + matchnotsyntax: + PREFETCH (); + /* Can't use *d++ here; SYNTAX may be an unsafe macro. */ + d++; + if (SYNTAX (d[-1]) == (enum syntaxcode) mcnt) + goto fail; + SET_REGS_MATCHED (); + break; + +#else /* not emacs */ + case wordchar: + DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n"); + PREFETCH (); + if (!WORDCHAR_P (d)) + goto fail; + SET_REGS_MATCHED (); + d++; + break; + + case notwordchar: + DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n"); + PREFETCH (); + if (WORDCHAR_P (d)) + goto fail; + SET_REGS_MATCHED (); + d++; + break; +#endif /* not emacs */ + + default: + abort (); + } + continue; /* Successfully executed one pattern command; keep going. */ + + + /* We goto here if a matching operation fails. */ + fail: + if (!FAIL_STACK_EMPTY ()) + { /* A restart point is known. Restore to that state. */ + DEBUG_PRINT1 ("\nFAIL:\n"); + POP_FAILURE_POINT (d, p, + lowest_active_reg, highest_active_reg, + regstart, regend, reg_info); + + /* If this failure point is a dummy, try the next one. */ + if (!p) + goto fail; + + /* If we failed to the end of the pattern, don't examine *p. */ + assert (p <= pend); + if (p < pend) + { + boolean is_a_jump_n = false; + + /* If failed to a backwards jump that's part of a repetition + loop, need to pop this failure point and use the next one. */ + switch ((re_opcode_t) *p) + { + case jump_n: + is_a_jump_n = true; + case maybe_pop_jump: + case pop_failure_jump: + case jump: + p1 = p + 1; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + p1 += mcnt; + + if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n) + || (!is_a_jump_n + && (re_opcode_t) *p1 == on_failure_jump)) + goto fail; + break; + default: + /* do nothing */ ; + } + } + + if (d >= string1 && d <= end1) + dend = end_match_1; + } + else + break; /* Matching at this starting point really fails. */ + } /* for (;;) */ + + if (best_regs_set) + goto restore_best_regs; + + FREE_VARIABLES (); + + return -1; /* Failure to match. */ +} /* re_match_2 */ + +/* Subroutine definitions for re_match_2. */ + + +/* We are passed P pointing to a register number after a start_memory. + + Return true if the pattern up to the corresponding stop_memory can + match the empty string, and false otherwise. + + If we find the matching stop_memory, sets P to point to one past its number. + Otherwise, sets P to an undefined byte less than or equal to END. + + We don't handle duplicates properly (yet). */ + +static boolean +group_match_null_string_p (p, end, reg_info) + unsigned char **p, *end; + register_info_type *reg_info; +{ + int mcnt; + /* Point to after the args to the start_memory. */ + unsigned char *p1 = *p + 2; + + while (p1 < end) + { + /* Skip over opcodes that can match nothing, and return true or + false, as appropriate, when we get to one that can't, or to the + matching stop_memory. */ + + switch ((re_opcode_t) *p1) + { + /* Could be either a loop or a series of alternatives. */ + case on_failure_jump: + p1++; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + + /* If the next operation is not a jump backwards in the + pattern. */ + + if (mcnt >= 0) + { + /* Go through the on_failure_jumps of the alternatives, + seeing if any of the alternatives cannot match nothing. + The last alternative starts with only a jump, + whereas the rest start with on_failure_jump and end + with a jump, e.g., here is the pattern for `a|b|c': + + /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6 + /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3 + /exactn/1/c + + So, we have to first go through the first (n-1) + alternatives and then deal with the last one separately. */ + + + /* Deal with the first (n-1) alternatives, which start + with an on_failure_jump (see above) that jumps to right + past a jump_past_alt. */ + + while ((re_opcode_t) p1[mcnt-3] == jump_past_alt) + { + /* `mcnt' holds how many bytes long the alternative + is, including the ending `jump_past_alt' and + its number. */ + + if (!alt_match_null_string_p (p1, p1 + mcnt - 3, + reg_info)) + return false; + + /* Move to right after this alternative, including the + jump_past_alt. */ + p1 += mcnt; + + /* Break if it's the beginning of an n-th alternative + that doesn't begin with an on_failure_jump. */ + if ((re_opcode_t) *p1 != on_failure_jump) + break; + + /* Still have to check that it's not an n-th + alternative that starts with an on_failure_jump. */ + p1++; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + if ((re_opcode_t) p1[mcnt-3] != jump_past_alt) + { + /* Get to the beginning of the n-th alternative. */ + p1 -= 3; + break; + } + } + + /* Deal with the last alternative: go back and get number + of the `jump_past_alt' just before it. `mcnt' contains + the length of the alternative. */ + EXTRACT_NUMBER (mcnt, p1 - 2); + + if (!alt_match_null_string_p (p1, p1 + mcnt, reg_info)) + return false; + + p1 += mcnt; /* Get past the n-th alternative. */ + } /* if mcnt > 0 */ + break; + + + case stop_memory: + assert (p1[1] == **p); + *p = p1 + 2; + return true; + + + default: + if (!common_op_match_null_string_p (&p1, end, reg_info)) + return false; + } + } /* while p1 < end */ + + return false; +} /* group_match_null_string_p */ + + +/* Similar to group_match_null_string_p, but doesn't deal with alternatives: + It expects P to be the first byte of a single alternative and END one + byte past the last. The alternative can contain groups. */ + +static boolean +alt_match_null_string_p (p, end, reg_info) + unsigned char *p, *end; + register_info_type *reg_info; +{ + int mcnt; + unsigned char *p1 = p; + + while (p1 < end) + { + /* Skip over opcodes that can match nothing, and break when we get + to one that can't. */ + + switch ((re_opcode_t) *p1) + { + /* It's a loop. */ + case on_failure_jump: + p1++; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + p1 += mcnt; + break; + + default: + if (!common_op_match_null_string_p (&p1, end, reg_info)) + return false; + } + } /* while p1 < end */ + + return true; +} /* alt_match_null_string_p */ + + +/* Deals with the ops common to group_match_null_string_p and + alt_match_null_string_p. + + Sets P to one after the op and its arguments, if any. */ + +static boolean +common_op_match_null_string_p (p, end, reg_info) + unsigned char **p, *end; + register_info_type *reg_info; +{ + int mcnt; + boolean ret; + int reg_no; + unsigned char *p1 = *p; + + switch ((re_opcode_t) *p1++) + { + case no_op: + case begline: + case endline: + case begbuf: + case endbuf: + case wordbeg: + case wordend: + case wordbound: + case notwordbound: +#ifdef emacs + case before_dot: + case at_dot: + case after_dot: +#endif + break; + + case start_memory: + reg_no = *p1; + assert (reg_no > 0 && reg_no <= MAX_REGNUM); + ret = group_match_null_string_p (&p1, end, reg_info); + + /* Have to set this here in case we're checking a group which + contains a group and a back reference to it. */ + + if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE) + REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret; + + if (!ret) + return false; + break; + + /* If this is an optimized succeed_n for zero times, make the jump. */ + case jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + if (mcnt >= 0) + p1 += mcnt; + else + return false; + break; + + case succeed_n: + /* Get to the number of times to succeed. */ + p1 += 2; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + + if (mcnt == 0) + { + p1 -= 4; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + p1 += mcnt; + } + else + return false; + break; + + case duplicate: + if (!REG_MATCH_NULL_STRING_P (reg_info[*p1])) + return false; + break; + + case set_number_at: + p1 += 4; + + default: + /* All other opcodes mean we cannot match the empty string. */ + return false; + } + + *p = p1; + return true; +} /* common_op_match_null_string_p */ + + +/* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN + bytes; nonzero otherwise. */ + +static int +bcmp_translate (s1, s2, len, translate) + const char *s1, *s2; + register int len; + RE_TRANSLATE_TYPE translate; +{ + register const unsigned char *p1 = (const unsigned char *) s1; + register const unsigned char *p2 = (const unsigned char *) s2; + while (len) + { + if (translate[*p1++] != translate[*p2++]) return 1; + len--; + } + return 0; +} + +/* Entry points for GNU code. */ + +/* re_compile_pattern is the GNU regular expression compiler: it + compiles PATTERN (of length SIZE) and puts the result in BUFP. + Returns 0 if the pattern was valid, otherwise an error string. + + Assumes the `allocated' (and perhaps `buffer') and `translate' fields + are set in BUFP on entry. + + We call regex_compile to do the actual compilation. */ + +const char * +re_compile_pattern (pattern, length, bufp) + const char *pattern; + size_t length; + struct re_pattern_buffer *bufp; +{ + reg_errcode_t ret; + + /* GNU code is written to assume at least RE_NREGS registers will be set + (and at least one extra will be -1). */ + bufp->regs_allocated = REGS_UNALLOCATED; + + /* And GNU code determines whether or not to get register information + by passing null for the REGS argument to re_match, etc., not by + setting no_sub. */ + bufp->no_sub = 0; + + /* Match anchors at newline. */ + bufp->newline_anchor = 1; + + ret = regex_compile (pattern, length, re_syntax_options, bufp); + + if (!ret) + return NULL; + return gettext (re_error_msgid[(int) ret]); +} +#ifdef _LIBC +weak_alias (__re_compile_pattern, re_compile_pattern) +#endif + +/* Entry points compatible with 4.2 BSD regex library. We don't define + them unless specifically requested. */ + +#if defined _REGEX_RE_COMP || defined _LIBC + +/* BSD has one and only one pattern buffer. */ +static struct re_pattern_buffer re_comp_buf; + +char * +#ifdef _LIBC +/* Make these definitions weak in libc, so POSIX programs can redefine + these names if they don't use our functions, and still use + regcomp/regexec below without link errors. */ +weak_function +#endif +re_comp (s) + const char *s; +{ + reg_errcode_t ret; + + if (!s) + { + if (!re_comp_buf.buffer) + return gettext ("No previous regular expression"); + return 0; + } + + if (!re_comp_buf.buffer) + { + re_comp_buf.buffer = (unsigned char *) malloc (200); + if (re_comp_buf.buffer == NULL) + return (char *) gettext (re_error_msgid[(int) REG_ESPACE]); + re_comp_buf.allocated = 200; + + re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH); + if (re_comp_buf.fastmap == NULL) + return (char *) gettext (re_error_msgid[(int) REG_ESPACE]); + } + + /* Since `re_exec' always passes NULL for the `regs' argument, we + don't need to initialize the pattern buffer fields which affect it. */ + + /* Match anchors at newlines. */ + re_comp_buf.newline_anchor = 1; + + ret = regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf); + + if (!ret) + return NULL; + + /* Yes, we're discarding `const' here if !HAVE_LIBINTL. */ + return (char *) gettext (re_error_msgid[(int) ret]); +} + + +int +#ifdef _LIBC +weak_function +#endif +re_exec (s) + const char *s; +{ + const int len = strlen (s); + return + 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0); +} + +#endif /* _REGEX_RE_COMP */ + +/* POSIX.2 functions. Don't define these for Emacs. */ + +#ifndef emacs + +/* regcomp takes a regular expression as a string and compiles it. + + PREG is a regex_t *. We do not expect any fields to be initialized, + since POSIX says we shouldn't. Thus, we set + + `buffer' to the compiled pattern; + `used' to the length of the compiled pattern; + `syntax' to RE_SYNTAX_POSIX_EXTENDED if the + REG_EXTENDED bit in CFLAGS is set; otherwise, to + RE_SYNTAX_POSIX_BASIC; + `newline_anchor' to REG_NEWLINE being set in CFLAGS; + `fastmap' and `fastmap_accurate' to zero; + `re_nsub' to the number of subexpressions in PATTERN. + + PATTERN is the address of the pattern string. + + CFLAGS is a series of bits which affect compilation. + + If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we + use POSIX basic syntax. + + If REG_NEWLINE is set, then . and [^...] don't match newline. + Also, regexec will try a match beginning after every newline. + + If REG_ICASE is set, then we considers upper- and lowercase + versions of letters to be equivalent when matching. + + If REG_NOSUB is set, then when PREG is passed to regexec, that + routine will report only success or failure, and nothing about the + registers. + + It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for + the return codes and their meanings.) */ + +int +regcomp (preg, pattern, cflags) + regex_t *preg; + const char *pattern; + int cflags; +{ + reg_errcode_t ret; + reg_syntax_t syntax + = (cflags & REG_EXTENDED) ? + RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC; + + /* regex_compile will allocate the space for the compiled pattern. */ + preg->buffer = 0; + preg->allocated = 0; + preg->used = 0; + + /* Don't bother to use a fastmap when searching. This simplifies the + REG_NEWLINE case: if we used a fastmap, we'd have to put all the + characters after newlines into the fastmap. This way, we just try + every character. */ + preg->fastmap = 0; + + if (cflags & REG_ICASE) + { + unsigned i; + + preg->translate + = (RE_TRANSLATE_TYPE) malloc (CHAR_SET_SIZE + * sizeof (*(RE_TRANSLATE_TYPE)0)); + if (preg->translate == NULL) + return (int) REG_ESPACE; + + /* Map uppercase characters to corresponding lowercase ones. */ + for (i = 0; i < CHAR_SET_SIZE; i++) + preg->translate[i] = ISUPPER (i) ? tolower (i) : i; + } + else + preg->translate = NULL; + + /* If REG_NEWLINE is set, newlines are treated differently. */ + if (cflags & REG_NEWLINE) + { /* REG_NEWLINE implies neither . nor [^...] match newline. */ + syntax &= ~RE_DOT_NEWLINE; + syntax |= RE_HAT_LISTS_NOT_NEWLINE; + /* It also changes the matching behavior. */ + preg->newline_anchor = 1; + } + else + preg->newline_anchor = 0; + + preg->no_sub = !!(cflags & REG_NOSUB); + + /* POSIX says a null character in the pattern terminates it, so we + can use strlen here in compiling the pattern. */ + ret = regex_compile (pattern, strlen (pattern), syntax, preg); + + /* POSIX doesn't distinguish between an unmatched open-group and an + unmatched close-group: both are REG_EPAREN. */ + if (ret == REG_ERPAREN) ret = REG_EPAREN; + + return (int) ret; +} +#ifdef _LIBC +weak_alias (__regcomp, regcomp) +#endif + + +/* regexec searches for a given pattern, specified by PREG, in the + string STRING. + + If NMATCH is zero or REG_NOSUB was set in the cflags argument to + `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at + least NMATCH elements, and we set them to the offsets of the + corresponding matched substrings. + + EFLAGS specifies `execution flags' which affect matching: if + REG_NOTBOL is set, then ^ does not match at the beginning of the + string; if REG_NOTEOL is set, then $ does not match at the end. + + We return 0 if we find a match and REG_NOMATCH if not. */ + +int +regexec (preg, string, nmatch, pmatch, eflags) + const regex_t *preg; + const char *string; + size_t nmatch; + regmatch_t pmatch[]; + int eflags; +{ + int ret; + struct re_registers regs; + regex_t private_preg; + int len = strlen (string); + boolean want_reg_info = !preg->no_sub && nmatch > 0; + + private_preg = *preg; + + private_preg.not_bol = !!(eflags & REG_NOTBOL); + private_preg.not_eol = !!(eflags & REG_NOTEOL); + + /* The user has told us exactly how many registers to return + information about, via `nmatch'. We have to pass that on to the + matching routines. */ + private_preg.regs_allocated = REGS_FIXED; + + if (want_reg_info) + { + regs.num_regs = nmatch; + regs.start = TALLOC (nmatch, regoff_t); + regs.end = TALLOC (nmatch, regoff_t); + if (regs.start == NULL || regs.end == NULL) + return (int) REG_NOMATCH; + } + + /* Perform the searching operation. */ + ret = re_search (&private_preg, string, len, + /* start: */ 0, /* range: */ len, + want_reg_info ? ®s : (struct re_registers *) 0); + + /* Copy the register information to the POSIX structure. */ + if (want_reg_info) + { + if (ret >= 0) + { + unsigned r; + + for (r = 0; r < nmatch; r++) + { + pmatch[r].rm_so = regs.start[r]; + pmatch[r].rm_eo = regs.end[r]; + } + } + + /* If we needed the temporary register info, free the space now. */ + free (regs.start); + free (regs.end); + } + + /* We want zero return to mean success, unlike `re_search'. */ + return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH; +} +#ifdef _LIBC +weak_alias (__regexec, regexec) +#endif + + +/* Returns a message corresponding to an error code, ERRCODE, returned + from either regcomp or regexec. We don't use PREG here. */ + +size_t +regerror (errcode, preg, errbuf, errbuf_size) + int errcode; + const regex_t *preg; + char *errbuf; + size_t errbuf_size; +{ + const char *msg; + size_t msg_size; + + if (errcode < 0 + || errcode >= (int) (sizeof (re_error_msgid) + / sizeof (re_error_msgid[0]))) + /* Only error codes returned by the rest of the code should be passed + to this routine. If we are given anything else, or if other regex + code generates an invalid error code, then the program has a bug. + Dump core so we can fix it. */ + abort (); + + msg = gettext (re_error_msgid[errcode]); + + msg_size = strlen (msg) + 1; /* Includes the null. */ + + if (errbuf_size != 0) + { + if (msg_size > errbuf_size) + { +#if defined HAVE_MEMPCPY || defined _LIBC + *((char *) __mempcpy (errbuf, msg, errbuf_size - 1)) = '\0'; +#else + memcpy (errbuf, msg, errbuf_size - 1); + errbuf[errbuf_size - 1] = 0; +#endif + } + else + memcpy (errbuf, msg, msg_size); + } + + return msg_size; +} +#ifdef _LIBC +weak_alias (__regerror, regerror) +#endif + + +/* Free dynamically allocated space used by PREG. */ + +void +regfree (preg) + regex_t *preg; +{ + if (preg->buffer != NULL) + free (preg->buffer); + preg->buffer = NULL; + + preg->allocated = 0; + preg->used = 0; + + if (preg->fastmap != NULL) + free (preg->fastmap); + preg->fastmap = NULL; + preg->fastmap_accurate = 0; + + if (preg->translate != NULL) + free (preg->translate); + preg->translate = NULL; +} +#ifdef _LIBC +weak_alias (__regfree, regfree) +#endif + +#endif /* not emacs */ diff --git a/reactos/lib/kjs/ksrc/setjmp.S b/reactos/lib/kjs/ksrc/setjmp.S new file mode 100644 index 00000000000..7a596b91cda --- /dev/null +++ b/reactos/lib/kjs/ksrc/setjmp.S @@ -0,0 +1,59 @@ + .file "setjmp.S" +/* + * Copyright (C) 1998, 1999, Jonathan S. Shapiro. + * + * This file is part of the EROS Operating System. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* #include */ + + + /* + * typedef struct { + * unsigned long ebx, esi, edi; + * unsigned long ebp; + * unsigned long sp; + * unsigned long pc; + * } jmp_buf[1]; + */ + + /* + * On entry, the stack to setjmp looks like: + * + * ptr to jmp_buf + * return PC + */ +.globl _setjmp +_setjmp: + pushl %ebp + movl %esp,%ebp + + movl 0x8(%ebp),%eax /* address of jmp_buf to eax */ + movl %ebx,(%eax) /* save %ebx */ + movl %esi,4(%eax) /* save %esi */ + movl %edi,8(%eax) /* save %edi */ + leal 8(%ebp),%edx /* calling proc's esp, not ours! */ + movl %edx,16(%eax) + movl 4(%ebp), %edx /* save return PC */ + movl %edx,20(%eax) + movl 0(%ebp),%edx /* calling proc's ebp, not ours! */ + movl %edx,12(%eax) + + xorl %eax,%eax /* return 0 the first time */ + leave + ret $4 + diff --git a/reactos/lib/kjs/ksrc/vm.c b/reactos/lib/kjs/ksrc/vm.c new file mode 100644 index 00000000000..2ac73c8de4b --- /dev/null +++ b/reactos/lib/kjs/ksrc/vm.c @@ -0,0 +1,968 @@ +/* + * Common parts for the JavaScript virtual machine. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/ksrc/vm.c,v $ + * $Id: vm.c,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +#include "jsint.h" +#include "kjs.h" + +/* + * Types and definitions. + */ + +/* + * Collect garbage if we allocated more than GC_TRIGGER bytes of + * memory since the last gc. + */ +#if SIZEOF_INT == 2 +#define GC_TRIGGER (1L * 1024L * 1024L) +#else +#define GC_TRIGGER (2 * 1024 * 1024) +#endif + +/* + * Prototypes for static functions. + */ + +static void intern_builtins (PKJS kjs); + + +/* + * Global functions. + */ + +JSVirtualMachine * +js_vm_create (PKJS kjs, + unsigned int stack_size, + JSVMDispatchMethod dispatch_method, + unsigned int verbose, + int stacktrace_on_error, + JSIOStream *s_stdin, + JSIOStream *s_stdout, + JSIOStream *s_stderr) +{ + JSVirtualMachine *vm; + + kjs->vm = vm = js_calloc (NULL, 1, sizeof (*vm)); + if (vm == NULL) + return NULL; + + vm->verbose = verbose; + vm->stacktrace_on_error = stacktrace_on_error; + vm->warn_undef = 1; + + /* Set the system streams. */ + vm->s_stdin = s_stdin; + vm->s_stdout = s_stdout; + vm->s_stderr = s_stderr; + + /* Resolve the dispatch method. */ + switch (dispatch_method) + { + case JS_VM_DISPATCH_SWITCH_BASIC: +#if ALL_DISPATCHERS + vm->dispatch_method = dispatch_method; + vm->dispatch_method_name = "switch-basic"; + vm->dispatch_execute = js_vm_switch0_exec; + vm->dispatch_func_name = js_vm_switch0_func_name; + vm->dispatch_debug_position = js_vm_switch0_debug_position; +#endif + break; + + case JS_VM_DISPATCH_JUMPS: +#if __GNUC__ && !DISABLE_JUMPS + vm->dispatch_method = dispatch_method; + vm->dispatch_method_name = "jumps"; + vm->dispatch_execute = js_vm_jumps_exec; + vm->dispatch_func_name = js_vm_jumps_func_name; + vm->dispatch_debug_position = js_vm_jumps_debug_position; +#endif /* not (__GNUC__ && !DISABLE_JUMPS) */ + break; + + case JS_VM_DISPATCH_SWITCH: + /* This is the default, let the default catcher handle us. */ + break; + } + + if (vm->dispatch_execute == NULL) + { + /* Set the default that is the optimized switch. */ + vm->dispatch_method = JS_VM_DISPATCH_SWITCH; + vm->dispatch_method_name = "switch"; + vm->dispatch_execute = js_vm_switch_exec; + vm->dispatch_func_name = js_vm_switch_func_name; + vm->dispatch_debug_position = js_vm_switch_debug_position; + } + + vm->stack_size = stack_size; + vm->stack = js_malloc (NULL, vm->stack_size * sizeof (*vm->stack)); + if (vm->stack == NULL) + { + js_free (vm); + return NULL; + } + + /* Set the initial stack pointer. */ + vm->sp = vm->stack + vm->stack_size - 1; + + vm->gc.trigger = GC_TRIGGER; + + /* We need a toplevel here. */ + { + JSErrorHandlerFrame handler; + int result = 1; + + memset (&handler, 0, sizeof (handler)); + handler.next = vm->error_handler; + vm->error_handler = &handler; + + if (setjmp (vm->error_handler->error_jmp)) + /* An error occurred. */ + result = 0; + else + { + /* Intern some commonly used symbols. */ + vm->syms.s___proto__ = js_vm_intern (vm, "__proto__"); + vm->syms.s_prototype = js_vm_intern (vm, "prototype"); + vm->syms.s_toSource = js_vm_intern (vm, "toSource"); + vm->syms.s_toString = js_vm_intern (vm, "toString"); + vm->syms.s_valueOf = js_vm_intern (vm, "valueOf"); + + /* Intern system built-in objects. */ + intern_builtins (kjs); + } + + /* Pop the error handler. */ + vm->error_handler = vm->error_handler->next; + + if (result == 0) + { + /* Argh, the initialization failed. */ + js_vm_destroy (vm); + return NULL; + } + } + + return vm; +} + + +void +js_vm_destroy (JSVirtualMachine *vm) +{ + int i; + JSHeapBlock *hb, *hb2; + JSErrorHandlerFrame *f, *f2; + JSHashBucket *hashb, *hashb_next; + + /* Free all objects from the heap. */ + js_vm_clear_heap (vm); + + /* Free the constants. */ + + for (i = 0; i < vm->num_consts; i++) + if (vm->consts[i].type == JS_STRING) + js_free (vm->consts[i].u.vstring->data); + js_free (vm->consts); + + /* Free the globals. */ + + for (i = 0; i < JS_HASH_TABLE_SIZE; i++) + for (hashb = vm->globals_hash[i]; hashb; hashb = hashb_next) + { + hashb_next = hashb->next; + js_free (hashb->name); + js_free (hashb); + } + js_free (vm->globals); + + /* Stack. */ + js_free (vm->stack); + + /* Heap blocks. */ + for (hb = vm->heap; hb; hb = hb2) + { + hb2 = hb->next; + js_free (hb); + } + + /* Error handlers. */ + for (f = vm->error_handler; f; f = f2) + { + f2 = f->next; + js_free (f); + } + +#if PROFILING +#define NUM_OPS 68 + + /* Dump profiling data to the stderr. */ + { + unsigned int total = 0; + int i; + + /* Count total interrupts. */ + for (i = 0; i <= NUM_OPS; i++) + total += vm->prof_count[i]; + + /* Dump individual statistics. */ + for (i = 0; i <= NUM_OPS; i++) + { + char buf[512]; + + sprintf (buf, "%d\t%u\t%.2f%s", + i, vm->prof_count[i], + (double) vm->prof_count[i] / total * 100, + JS_HOST_LINE_BREAK); + + js_iostream_write (vm->s_stderr); + } + } +#endif /* PROFILING */ + + /* Flush and free the default system streams. */ + + js_iostream_close (vm->s_stdin); + js_iostream_close (vm->s_stdout); + js_iostream_close (vm->s_stderr); + + /* And finally, the VM handle. */ + js_free (vm); +} + +#if PROFILING +/* + * The support stuffs for the byte-code operand profiling. + */ + +static JSVirtualMachine *profiling_vm = NULL; + +static void +sig_alarm (int sig) +{ + if (profiling_vm && profiling_vm->prof_op < 100) + profiling_vm->prof_count[profiling_vm->prof_op]++; + + signal (sig, sig_alarm); +} + +/* Turn on the byte-code operand profiling. */ +#define PROFILING_ON() \ + profiling_vm = vm; \ + vm->prof_op = 255; \ + signal (SIGALRM, sig_alarm); \ + ualarm (1, 1) + +/* Turn off the byte-code operand profiling. */ +#define PROFILING_OFF() \ + vm->prof_op = 255; \ + ualarm (0, 0); \ + signal (SIGALRM, SIG_IGN); \ + profiling_vm = NULL + +#else /* not PROFILING */ + +#define PROFILING_ON() +#define PROFILING_OFF() + +#endif /* not PROFILING */ + +int +js_vm_execute (JSVirtualMachine *vm, JSByteCode *bc) +{ + int i, sect; + unsigned int ui; + unsigned char *cp; + unsigned int consts_offset; + char buf[256]; + JSSymtabEntry *symtab = NULL; + unsigned int num_symtab_entries = 0; + unsigned int code_len = 0; + JSNode *saved_sp; + JSErrorHandlerFrame *handler, *saved_handler; + int result = 1; + unsigned char *debug_info; + unsigned int debug_info_len; + unsigned int anonymous_function_offset; + + /* We need a toplevel over the whole function. */ + + saved_sp = vm->sp; + saved_handler = vm->error_handler; + + handler = js_calloc (NULL, 1, sizeof (*handler)); + if (handler == NULL) + { + sprintf (vm->error, "VM: out of memory"); + return 0; + } + handler->next = vm->error_handler; + vm->error_handler = handler; + + if (setjmp (vm->error_handler->error_jmp)) + { + /* Ok, we had an error down there somewhere. */ + result = 0; + } + else + { + /* The main stuffs for the execute. */ + + /* Process constants. */ + consts_offset = vm->num_consts; + anonymous_function_offset = vm->anonymous_function_next_id; + + for (sect = 0; sect < bc->num_sects; sect++) + if (bc->sects[sect].type == JS_BCST_CONSTANTS) + { + cp = bc->sects[sect].data; + + for (ui = 0; ui < bc->sects[sect].length;) + { + JSNode *c; + + /* Check that we still have space for this constant. */ + if (vm->num_consts >= vm->consts_alloc) + { + vm->consts = js_realloc (vm, vm->consts, + (vm->consts_alloc + 1024) + * sizeof (JSNode)); + vm->consts_alloc += 1024; + } + c = &vm->consts[vm->num_consts++]; + + /* Process this constant. */ + c->type = (JSNodeType) cp[ui++]; + switch (c->type) + { + case JS_NULL: + break; + + case JS_BOOLEAN: + c->u.vboolean = cp[ui++]; + break; + + case JS_STRING: + c->u.vstring = js_vm_alloc (vm, sizeof (*c->u.vstring)); + c->u.vstring->staticp = 1; + c->u.vstring->prototype = NULL; + + JS_BC_READ_INT32 (cp + ui, c->u.vstring->len); + ui += 4; + + c->u.vstring->data = js_malloc (vm, c->u.vstring->len + 1); + memcpy (c->u.vstring->data, cp + ui, c->u.vstring->len); + c->u.vstring->data[c->u.vstring->len] = '\0'; + + ui += c->u.vstring->len; + break; + + case JS_INTEGER: + JS_BC_READ_INT32 (cp + ui, c->u.vinteger); + ui += 4; + break; + + case JS_FLOAT: + memcpy (&c->u.vfloat, cp + ui, 8); + ui += 8; + break; + + case JS_SYMBOL: + for (i = 0; cp[ui]; ui++, i++) + buf[i] = cp[ui]; + buf[i] = '\0'; + + /* Eat the trailing '\0' from the data. */ + ui++; + + if (buf[0] == '.' && buf[1] == 'F' && buf[2] == ':') + sprintf (buf + 3, "%u", + vm->anonymous_function_next_id++); + + /* Intern symbol. */ + c->u.vsymbol = js_vm_intern (vm, buf); + break; + + case JS_BUILTIN: + /* Regular expression. */ + { + unsigned char flags; + unsigned int length; + + flags = cp[ui++]; + + JS_BC_READ_INT32 (cp + ui, length); + ui += 4; + + js_builtin_RegExp_new (vm, cp + ui, length, flags, 1, + NULL, c); + ui += length; + } + break; + + case JS_NAN: + /* Nothing here. */ + break; + + default: + case JS_IPTR: + sprintf (buf, + "js_vm_execute(): unknown constant type %d%s", + c->type, + JS_HOST_LINE_BREAK); + + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); + + abort (); + break; + } + } + + /* All done with the constants. */ + break; + } + + /* Check how long the code section is. */ + for (sect = 0; sect < bc->num_sects; sect++) + if (bc->sects[sect].type == JS_BCST_CODE) + { + code_len = bc->sects[sect].length; + break; + } + + /* Process symbol table. */ + for (sect = 0; sect < bc->num_sects; sect++) + if (bc->sects[sect].type == JS_BCST_SYMTAB) + { + JSSymtabEntry *se; + char buf[257]; + + cp = bc->sects[sect].data; + + /* The number of symbols. */ + JS_BC_READ_INT32 (cp, num_symtab_entries); + + symtab = js_calloc (vm, num_symtab_entries + 1, sizeof (*symtab)); + + /* Make the terminator by hand. */ + symtab[num_symtab_entries].offset = code_len; + + /* Enter symbols. */ + se = symtab; + for (ui = 4; ui < bc->sects[sect].length; se++) + { + for (i = 0; cp[ui]; ui++, i++) + buf[i] = cp[ui]; + buf[i] = '\0'; + + se->name = js_strdup (vm, buf); + ui++; + + JS_BC_READ_INT32 (cp + ui, se->offset); + ui += 4; + } + break; + } + + /* Check if we have debugging information. */ + debug_info = NULL; + debug_info_len = 0; + for (sect = 0; sect < bc->num_sects; sect++) + if (bc->sects[sect].type == JS_BCST_DEBUG) + { + debug_info = bc->sects[sect].data; + debug_info_len = bc->sects[sect].length; + } + + /* Clear error message and old exec result. */ + vm->error[0] = '\0'; + vm->exec_result.type = JS_UNDEFINED; + + PROFILING_ON (); + + /* Execute. */ + result = (*vm->dispatch_execute) (vm, bc, symtab, num_symtab_entries, + consts_offset, + anonymous_function_offset, + debug_info, debug_info_len, + NULL, NULL, 0, NULL); + } + + PROFILING_OFF (); + + if (symtab) + { + for (ui = 0; ui < num_symtab_entries; ui++) + js_free (symtab[ui].name); + js_free (symtab); + } + + /* Pop all error handler frames from the handler chain. */ + for (; vm->error_handler != saved_handler; vm->error_handler = handler) + { + handler = vm->error_handler->next; + js_free (vm->error_handler); + } + + /* Restore virtual machine's idea about the stack top. */ + vm->sp = saved_sp; + + return result; +} + + +int +js_vm_apply (JSVirtualMachine *vm, char *func_name, JSNode *func, + unsigned int argc, JSNode *argv) +{ + int result = 1; + JSNode *saved_sp; + JSErrorHandlerFrame *handler, *saved_handler; + + /* Initialize error handler. */ + + saved_sp = vm->sp; + saved_handler = vm->error_handler; + + handler = js_calloc (NULL, 1, sizeof (*handler)); + if (handler == NULL) + { + sprintf (vm->error, "VM: out of memory"); + return 0; + } + handler->next = vm->error_handler; + vm->error_handler = handler; + + if (setjmp (vm->error_handler->error_jmp)) + { + /* An error occurred. */ + result = 0; + } + else + { + /* Clear error message and old exec result. */ + vm->error[0] = '\0'; + vm->exec_result.type = JS_UNDEFINED; + + if (func_name) + /* Lookup the function. */ + func = &vm->globals[js_vm_intern (vm, func_name)]; + + /* Check what kind of function should be called. */ + if (func->type == JS_FUNC) + { + PROFILING_ON (); + + /* Call function. */ + result = (*vm->dispatch_execute) (vm, NULL, NULL, 0, 0, 0, + NULL, 0, + NULL, func, argc, argv); + } + else if (func->type == JS_BUILTIN + && func->u.vbuiltin->info->global_method_proc != NULL) + { + (*func->u.vbuiltin->info->global_method_proc) ( + vm, + func->u.vbuiltin->info, + func->u.vbuiltin->instance_context, + &vm->exec_result, + argv); + } + else + { + if (func_name) + sprintf (vm->error, "undefined function `%s' in apply", + func_name); + else + sprintf (vm->error, "undefiend function in apply"); + + result = 0; + } + } + + PROFILING_OFF (); + + /* Pop all error handler frames from the handler chain. */ + for (; vm->error_handler != saved_handler; vm->error_handler = handler) + { + handler = vm->error_handler->next; + js_free (vm->error_handler); + } + + /* Restore virtual machine's idea about the stack top. */ + vm->sp = saved_sp; + + return result; +} + + +int +js_vm_call_method (JSVirtualMachine *vm, JSNode *object, + const char *method_name, unsigned int argc, JSNode *argv) +{ + int result = 1; + JSNode *saved_sp; + JSErrorHandlerFrame *handler, *saved_handler; + JSSymbol symbol; + + /* Initialize error handler. */ + + saved_sp = vm->sp; + saved_handler = vm->error_handler; + + handler = js_calloc (NULL, 1, sizeof (*handler)); + if (handler == NULL) + { + sprintf (vm->error, "VM: out of memory"); + return 0; + } + handler->next = vm->error_handler; + vm->error_handler = handler; + + if (setjmp (vm->error_handler->error_jmp)) + { + /* An error occurred. */ + result = 0; + } + else + { + /* Intern the method name. */ + symbol = js_vm_intern (vm, method_name); + + /* Clear error message and old exec result. */ + vm->error[0] = '\0'; + vm->exec_result.type = JS_UNDEFINED; + + /* What kind of object was called? */ + + if (object->type == JS_BUILTIN) + { + if (object->u.vbuiltin->info->method_proc) + { + if ((*object->u.vbuiltin->info->method_proc) ( + vm, + object->u.vbuiltin->info, + object->u.vbuiltin->instance_context, + symbol, + &vm->exec_result, argv) + == JS_PROPERTY_UNKNOWN) + { + sprintf (vm->error, "call_method: unknown method"); + result = 0; + } + } + else + { + sprintf (vm->error, "illegal builtin object for call_method"); + result = 0; + } + } + else if (object->type == JS_OBJECT) + { + JSNode method; + + /* Fetch the method's implementation. */ + if (js_vm_object_load_property (vm, object->u.vobject, symbol, + &method) + == JS_PROPERTY_FOUND) + { + /* The property has been defined in the object. */ + if (method.type != JS_FUNC) + { + sprintf (vm->error, "call_method: unknown method"); + result = 0; + } + else + { + PROFILING_ON (); + result = (*vm->dispatch_execute) (vm, NULL, NULL, 0, 0, 0, + NULL, 0, + object, &method, argc, + argv); + } + } + else + /* Let the built-in Object handle this. */ + goto to_builtin_please; + } + else if (vm->prim[object->type]) + { + /* The primitive language types. */ + to_builtin_please: + if ((*vm->prim[object->type]->method_proc) (vm, + vm->prim[object->type], + object, symbol, + &vm->exec_result, + argv) + == JS_PROPERTY_UNKNOWN) + { + sprintf (vm->error, "call_method: unknown method"); + result = 0; + } + } + else + { + sprintf (vm->error, "illegal object for call_method"); + result = 0; + } + } + + PROFILING_OFF (); + + /* Pop all error handler frames from the handler chain. */ + for (; vm->error_handler != saved_handler; vm->error_handler = handler) + { + handler = vm->error_handler->next; + js_free (vm->error_handler); + } + + /* Restore virtual machine's idea about the stack top. */ + vm->sp = saved_sp; + + return result; +} + + +const char * +js_vm_func_name (JSVirtualMachine *vm, void *pc) +{ + return (*vm->dispatch_func_name) (vm, pc); +} + + +const char * +js_vm_debug_position (JSVirtualMachine *vm, unsigned int *linenum_return) +{ + return (*vm->dispatch_debug_position) (vm, linenum_return); +} + + +unsigned int +js_vm_intern_with_len (JSVirtualMachine *vm, const char *name, + unsigned int len) +{ + JSHashBucket *b; + unsigned int pos = js_count_hash (name, len) % JS_HASH_TABLE_SIZE; + + for (b = vm->globals_hash[pos]; b; b = b->next) + if (strcmp (b->name, name) == 0) + return b->u.ui; + + b = js_malloc (vm, sizeof (*b)); + b->name = js_strdup (vm, name); + + b->next = vm->globals_hash[pos]; + vm->globals_hash[pos] = b; + + /* Alloc space from the globals array. */ + if (vm->num_globals >= vm->globals_alloc) + { + vm->globals = js_realloc (vm, vm->globals, + (vm->globals_alloc + 1024) * sizeof (JSNode)); + vm->globals_alloc += 1024; + } + + /* Initialize symbol's name spaces. */ + vm->globals[vm->num_globals].type = JS_UNDEFINED; + b->u.ui = vm->num_globals++; + + return b->u.ui; +} + + +const char * +js_vm_symname (JSVirtualMachine *vm, JSSymbol sym) +{ + int i; + JSHashBucket *b; + + for (i = 0; i < JS_HASH_TABLE_SIZE; i++) + for (b = vm->globals_hash[i]; b; b = b->next) + if (b->u.ui == sym) + return b->name; + + return "???"; +} + + +void +js_vm_error (JSVirtualMachine *vm) +{ + const char *file; + unsigned int ln; + char error[1024]; + + file = js_vm_debug_position (vm, &ln); + if (file) + { + sprintf (error, "%s:%u: %s", file, ln, vm->error); + strcpy (vm->error, error); + } + + if (vm->stacktrace_on_error) + { + sprintf (error, "VM: error: %s%s", vm->error, + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, error, strlen (error)); + + js_vm_stacktrace (vm, (unsigned int) -1); + } + + if (vm->error_handler->sp) + /* + * We are jumping to a catch-block. Format our error message to + * the `thrown' node. + */ + js_vm_make_string (vm, &vm->error_handler->thrown, + vm->error, strlen (vm->error)); + + longjmp (vm->error_handler->error_jmp, 1); + + /* NOTREACHED (I hope). */ + + sprintf (error, "VM: no valid error handler initialized%s", + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, error, strlen (error)); + js_iostream_flush (vm->s_stderr); + + abort (); +} + +/* Delete proc for garbaged built-in objects. */ +static void +destroy_builtin (void *ptr) +{ + JSBuiltin *bi = ptr; + + if (bi->info->delete_proc) + (*bi->info->delete_proc) (bi->info, bi->instance_context); +} + +/* Delete proc for garbaged built-in info. */ +static void +destroy_builtin_info (void *ptr) +{ + JSBuiltinInfo *i = ptr; + + if (i->obj_context_delete) + (*i->obj_context_delete) (i->obj_context); +} + + +JSBuiltinInfo * +js_vm_builtin_info_create (JSVirtualMachine *vm) +{ + JSNode prototype; + JSBuiltinInfo *i = js_vm_alloc_destroyable (vm, sizeof (*i)); + + i->destroy = destroy_builtin_info; + i->prototype = js_vm_object_new (vm); + + /* + * Set the __proto__ property to null. We have no prototype object + * above us. + */ + prototype.type = JS_NULL; + js_vm_object_store_property (vm, i->prototype, vm->syms.s___proto__, + &prototype); + + return i; +} + + +void +js_vm_builtin_create (JSVirtualMachine *vm, JSNode *result, + JSBuiltinInfo *info, void *instance_context) +{ + result->type = JS_BUILTIN; + result->u.vbuiltin = js_vm_alloc_destroyable (vm, sizeof (JSBuiltin)); + result->u.vbuiltin->destroy = destroy_builtin; + result->u.vbuiltin->info = info; + + if (instance_context) + { + JSNode prototype; + + result->u.vbuiltin->instance_context = instance_context; + result->u.vbuiltin->prototype = js_vm_object_new (vm); + + /* Set the __proto__ chain. */ + + prototype.type = JS_OBJECT; + prototype.u.vobject = info->prototype; + + js_vm_object_store_property (vm, result->u.vbuiltin->prototype, + vm->syms.s___proto__, &prototype); + } +} + + +/* + * Static functions. + */ + +extern void js_builtin_core (JSVirtualMachine *vm); + +extern void js_builtin_Array (JSVirtualMachine *vm); +extern void js_builtin_Boolean (JSVirtualMachine *vm); +extern void js_builtin_Function (JSVirtualMachine *vm); +extern void js_builtin_Number (JSVirtualMachine *vm); +extern void js_builtin_Object (JSVirtualMachine *vm); +extern void js_builtin_String (JSVirtualMachine *vm); +extern void js_builtin_File (JSVirtualMachine *vm); +extern void js_builtin_System (PKJS kjs); + +extern void js_builtin_RegExp (JSVirtualMachine *vm); +extern void js_builtin_VM (JSVirtualMachine *vm); + + +static void +intern_builtins (PKJS kjs) +{ + JSVirtualMachine *vm = kjs->vm; + /* + * The initialization order is significant. The RegExp object must be + * initialized before String. + */ + + /* The core global methods. */ + js_builtin_core (vm); + + js_builtin_RegExp (vm); + js_builtin_VM (vm); + + /* Language objects. */ + js_builtin_Array (vm); + js_builtin_Boolean (vm); + js_builtin_Function (vm); + js_builtin_String (vm); + js_builtin_Number (vm); + js_builtin_Object (vm); + js_builtin_File (vm); + js_builtin_System (kjs); +} diff --git a/reactos/lib/kjs/ksrc/vmjumps.c b/reactos/lib/kjs/ksrc/vmjumps.c new file mode 100644 index 00000000000..a005a759e04 --- /dev/null +++ b/reactos/lib/kjs/ksrc/vmjumps.c @@ -0,0 +1,581 @@ +/* + * Optimized `jumps' instruction dispatcher. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/ksrc/vmjumps.c,v $ + * $Id: vmjumps.c,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +#include "jsint.h" + +#if __GNUC__ && !DISABLE_JUMPS + +/* + * Types and definitions. + */ + +#define SAVE_OP(a) \ +reloc[cp - code_start - 1] = &f->code[cpos]; \ +f->code[cpos++].u.ptr = (a) + +#define SAVE_INT8(a) f->code[cpos++].u.i8 = (a) +#define SAVE_INT16(a) f->code[cpos++].u.i16 = (a) +#define SAVE_INT32(a) f->code[cpos++].u.i32 = (a) + +#define ARG_INT32() f->code[cpos].u.i32 + +#if BC_OPERAND_HOOKS + +#define NEXT() \ + do { \ + if (++vm->hook_operand_count >= vm->hook_operand_count_trigger) \ + { \ + JS_CALL_HOOK (JS_VM_EVENT_OPERAND_COUNT); \ + vm->hook_operand_count = 0; \ + } \ + goto *((pc++)->u.ptr); \ + } while (0) + +#else /* not BC_OPERAND_HOOKS */ + +#define NEXT() goto *((pc++)->u.ptr) + +#endif /* not BC_OPERAND_HOOKS */ + +#define READ_INT8(var) (var) = (pc++)->u.i8 +#define READ_INT16(var) (var) = (pc++)->u.i16 +#define READ_INT32(var) (var) = (pc++)->u.i32 + +#define SETPC(ofs) pc = (ofs) +#define SETPC_RELATIVE(ofs) pc += (ofs) + +#define CALL_USER_FUNC(f) pc = ((Function *) (f))->code + +#define DONE() goto done + +#define ERROR(msg) \ + do { \ + JS_SAVE_REGS (); \ + strcpy (vm->error, (msg)); \ + js_vm_error (vm); \ + /* NOTREACHED */ \ + } while (0) + +#if PROFILING +#define OPERAND(op) vm->prof_op = (op) +#else +#define OPERAND(op) +#endif + +struct compiled_st +{ + union + { + void *ptr; + JSInt8 i8; + JSInt16 i16; + JSInt32 i32; + } u; +}; + +typedef struct compiled_st Compiled; + +/* Debug information. */ +struct debug_info_st +{ + void *pc; + unsigned int linenum; +}; + +typedef struct debug_info_st DebugInfo; + +struct function_st +{ + JSHeapDestroyableCB destroy; + + char *name; + Compiled *code; + unsigned int length; + + struct + { + char *file; + unsigned int num_info; + DebugInfo *info; + } debug; +}; + +typedef struct function_st Function; + +/* + * Static functions. + */ + +static void +function_destroy (void *ptr) +{ + Function *f = ptr; + + /* Name. */ + js_free (f->name); + + /* Code. */ + js_free (f->code); + + /* Debug info. */ + if (f->debug.file) + js_free (f->debug.file); + if (f->debug.info) + js_free (f->debug.info); +} + + +#endif /* not (__GNUC__ && !DISABLE_JUMPS) */ + +/* + * Global functions. + */ + +int +js_vm_jumps_exec (JSVirtualMachine *vm, JSByteCode *bc, JSSymtabEntry *symtab, + unsigned int num_symtab_entries, unsigned int consts_offset, + unsigned int anonymous_function_offset, + unsigned char *debug_info, unsigned int debug_info_len, + JSNode *object, JSNode *func, + unsigned int argc, JSNode *argv) +{ +#if __GNUC__ && !DISABLE_JUMPS + int s; + unsigned int ui; + Function *global_f = NULL; + Function *f = NULL; + unsigned char *code = NULL; + JSNode *sp = NULL; + JSNode *fp = NULL; + Compiled *pc = NULL; + char *debug_filename = "unknown"; + char buf[512]; + + if (bc) + { + /* Executing byte-code. */ + + /* Find the code section. */ + for (s = 0; s < bc->num_sects; s++) + if (bc->sects[s].type == JS_BCST_CODE) + code = bc->sects[s].data; + assert (code != NULL); + + /* Enter all functions to the known functions of the VM. */ + for (s = 0; s < num_symtab_entries; s++) + { + /* We need one function. */ + f = js_vm_alloc_destroyable (vm, sizeof (*f)); + f->destroy = function_destroy; + f->name = js_strdup (vm, symtab[s].name); + + if (strcmp (symtab[s].name, JS_GLOBAL_NAME) == 0) + global_f = f; + else + { + int is_anonymous = 0; + + /* Check for the anonymous function. */ + if (symtab[s].name[0] == '.' && symtab[s].name[1] == 'F' + && symtab[s].name[2] == ':') + is_anonymous = 1; + + if (vm->verbose > 3) + { + sprintf (buf, "VM: link: %s(): start=%d, length=%d", + symtab[s].name, symtab[s].offset, + symtab[s + 1].offset - symtab[s].offset); + if (is_anonymous) + sprintf (buf + strlen (buf), + ", relocating with offset %u", + anonymous_function_offset); + strcat (buf, JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + + if (is_anonymous) + { + sprintf (buf, ".F:%u", + (unsigned int) atoi (symtab[s].name + 3) + + anonymous_function_offset); + ui = js_vm_intern (vm, buf); + } + else + ui = js_vm_intern (vm, symtab[s].name); + + vm->globals[ui].type = JS_FUNC; + vm->globals[ui].u.vfunction = js_vm_make_function (vm, f); + } + + /* Link the code to our environment.*/ + { + unsigned char *cp; + unsigned char *code_start, *code_end; + unsigned char *fixed_code; + JSInt32 i; + unsigned int cpos; + Compiled **reloc; + unsigned int length; + + length = symtab[s + 1].offset - symtab[s].offset + 1; + + /* + * Allocate space for our compiled code. is enought, + * but is is almost always too much. Who cares? + */ + f->code = js_malloc (vm, length * sizeof (Compiled)); + reloc = js_calloc (vm, 1, length * sizeof (Compiled *)); + fixed_code = js_malloc (vm, length); + + memcpy (fixed_code, code + symtab[s].offset, length); + fixed_code[length - 1] = 1; /* op `done'. */ + + code_start = fixed_code; + code_end = code_start + length; + + /* Link phase 1: constants and symbols. */ + cp = code_start; + cpos = 0; + while (cp < code_end) + { + switch (*cp++) + { + /* include c1jumps.h */ +#include "c1jumps.h" + /* end include c1jumps.h */ + } + } + f->length = cpos; + + /* Link phase 2: relative jumps. */ + cp = code_start; + cpos = 0; + while (cp < code_end) + { + switch (*cp++) + { + /* include c2jumps.h */ +#include "c2jumps.h" + /* end include c2jumps.h */ + } + } + + /* Handle debug info. */ + if (debug_info) + { + unsigned int di_start = symtab[s].offset; + unsigned int di_end = symtab[s + 1].offset; + unsigned int ln; + + for (; debug_info_len > 0;) + { + switch (*debug_info) + { + case JS_DI_FILENAME: + debug_info++; + debug_info_len--; + + JS_BC_READ_INT32 (debug_info, ui); + debug_info += 4; + debug_info_len -= 4; + + f->debug.file = js_malloc (vm, ui + 1); + memcpy (f->debug.file, debug_info, ui); + f->debug.file[ui] = '\0'; + + debug_filename = f->debug.file; + + debug_info += ui; + debug_info_len -= ui; + break; + + case JS_DI_LINENUMBER: + JS_BC_READ_INT32 (debug_info + 1, ui); + if (ui > di_end) + goto debug_info_done; + + /* This belongs to us (maybe). */ + debug_info += 5; + debug_info_len -= 5; + + JS_BC_READ_INT32 (debug_info, ln); + debug_info += 4; + debug_info_len -= 4; + + if (di_start <= ui && ui <= di_end) + { + ui -= di_start; + f->debug.info = js_realloc (vm, f->debug.info, + (f->debug.num_info + 1) + * sizeof (DebugInfo)); + + f->debug.info[f->debug.num_info].pc = reloc[ui]; + f->debug.info[f->debug.num_info].linenum = ln; + f->debug.num_info++; + } + break; + + default: + sprintf (buf, + "VM: unknown debug information type %d%s", + *debug_info, JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); + + abort (); + break; + } + } + + debug_info_done: + if (f->debug.file == NULL) + f->debug.file = js_strdup (vm, debug_filename); + } + + js_free (reloc); + js_free (fixed_code); + } + } + } + else + { + int i; + + /* Applying arguments to function. */ + if (func->type != JS_FUNC) + { + sprintf (vm->error, "illegal function in apply"); + return 0; + } + + if (vm->verbose > 1) + { + sprintf (buf, "VM: calling function%s", + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + f = func->u.vfunction->implementation; + + /* Init stack. */ + sp = vm->sp; + + /* + * Save the applied function to the stack. If our script + * overwrites the function, the function will not be deleted + * under us, since it is protected from the gc in the stack. + */ + JS_COPY (JS_SP0, func); + JS_PUSH (); + + /* Push arguments to the stack. */ + for (i = argc - 1; i >= 0; i--) + { + JS_COPY (JS_SP0, &argv[i]); + JS_PUSH (); + } + + /* This pointer. */ + if (object) + JS_COPY (JS_SP0, object); + else + JS_SP0->type = JS_NULL; + JS_PUSH (); + + /* Init fp and pc so our SUBROUTINE_CALL will work. */ + fp = NULL; + pc = NULL; + + JS_SUBROUTINE_CALL (f); + + /* Run. */ + NEXT (); + } + + if (global_f) + { + if (vm->verbose > 1) + { + sprintf (buf, "VM: exec: %s%s", JS_GLOBAL_NAME, + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + + /* Create the initial stack frame by hand. */ + sp = vm->sp; + + /* + * Push the global function to the stack. There it is protected + * from the garbage collection, as long, as we are executing the + * global code. It is also removed automatically, when the + * execution ends. + */ + JS_SP0->type = JS_FUNC; + JS_SP0->u.vfunction = js_vm_make_function (vm, global_f); + JS_PUSH (); + + /* Empty this pointer. */ + JS_SP0->type = JS_NULL; + JS_PUSH (); + + /* Init fp and pc so our JS_SUBROUTINE_CALL macro works. */ + fp = NULL; + pc = NULL; + + JS_SUBROUTINE_CALL (global_f); + + /* Run. */ + NEXT (); + } + + /* The smart done label. */ + + done: + + /* + * The return value from function calls and global evals is at JS_SP1. + * If is NULL, then we were linking byte-code that didn't have + * .global section. + */ + if (sp) + JS_COPY (&vm->exec_result, JS_SP1); + else + vm->exec_result.type = JS_UNDEFINED; + + /* All done. */ + return 1; + + /* And finally, include the operands. */ + { + JSNode builtin_result; + JSNode *function; + JSInt32 i, j; + JSInt8 i8; + + /* include ejumps.h */ +#include "ejumps.h" + /* end include ejumps.h */ + } +#else /* not (__GNUC__ && !DISABLE_JUMPS) */ + return 0; +#endif /* not (__GNUC__ && !DISABLE_JUMPS) */ +} + + +const char * +js_vm_jumps_func_name (JSVirtualMachine *vm, void *program_counter) +{ +#if __GNUC__ && !DISABLE_JUMPS + int i; + Function *f; + Compiled *pc = program_counter; + JSNode *sp = vm->sp; + + /* Check the globals. */ + for (i = 0; i < vm->num_globals; i++) + if (vm->globals[i].type == JS_FUNC) + { + f = (Function *) vm->globals[i].u.vfunction->implementation; + if (f->code < pc && pc < f->code + f->length) + return f->name; + } + + /* No luck. Let's try the stack. */ + for (sp++; sp < vm->stack + vm->stack_size; sp++) + if (sp->type == JS_FUNC) + { + f = (Function *) sp->u.vfunction->implementation; + if (f->code < pc && pc < f->code + f->length) + return f->name; + } + + /* Still no matches. This shouldn't be reached... ok, who cares? */ + return JS_GLOBAL_NAME; + +#else /* not (__GNUC__ && !DISABLE_JUMPS) */ + return ""; +#endif /* not (__GNUC__ && !DISABLE_JUMPS) */ +} + + +const char * +js_vm_jumps_debug_position (JSVirtualMachine *vm, unsigned int *linenum_return) +{ +#if __GNUC__ && !DISABLE_JUMPS + int i; + Function *f; + void *program_counter = vm->pc; + Compiled *pc = vm->pc; + JSNode *sp = vm->sp; + unsigned int linenum = 0; + + /* Check the globals. */ + for (i = 0; i < vm->num_globals; i++) + if (vm->globals[i].type == JS_FUNC) + { + f = (Function *) vm->globals[i].u.vfunction->implementation; + if (f->code < pc && pc < f->code + f->length) + { + found: + + /* Ok, found it. */ + if (f->debug.file == NULL) + /* No debugging information available for this function. */ + return NULL; + + /* Find the correct pc position. */ + for (i = 0; i < f->debug.num_info; i++) + { + if (f->debug.info[i].pc > program_counter) + break; + + linenum = f->debug.info[i].linenum; + } + + *linenum_return = linenum; + return f->debug.file; + } + } + + /* No luck. Let's try the stack. */ + for (sp++; sp < vm->stack + vm->stack_size; sp++) + if (sp->type == JS_FUNC) + { + f = (Function *) sp->u.vfunction->implementation; + if (f->code < pc && pc < f->code + f->length) + /* Found it. */ + goto found; + } + + /* Couldn't find the function we are executing. */ + return NULL; + +#else /* not (__GNUC__ && !DISABLE_JUMPS) */ + return NULL; +#endif /* not (__GNUC__ && !DISABLE_JUMPS) */ +} diff --git a/reactos/lib/kjs/ksrc/vmswitch.c b/reactos/lib/kjs/ksrc/vmswitch.c new file mode 100644 index 00000000000..d5a193d583f --- /dev/null +++ b/reactos/lib/kjs/ksrc/vmswitch.c @@ -0,0 +1,554 @@ +/* + * Optimized `switch' instruction dispatcher. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/ksrc/vmswitch.c,v $ + * $Id: vmswitch.c,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +#include "jsint.h" + +/* + * Types and definitions. + */ + +#define SAVE_OP(a) \ +reloc[cp - fixed_code - 1] = &f->code[cpos]; \ +f->code[cpos++].u.op = (a) + +#define SAVE_INT8(a) f->code[cpos++].u.i8 = (a) +#define SAVE_INT16(a) f->code[cpos++].u.i16 = (a) +#define SAVE_INT32(a) f->code[cpos++].u.i32 = (a) + +#define ARG_INT32() f->code[cpos].u.i32 + +#define READ_INT8(var) (var) = (pc++)->u.i8 +#define READ_INT16(var) (var) = (pc++)->u.i16 +#define READ_INT32(var) (var) = (pc++)->u.i32 + +#define SETPC(ofs) pc = (ofs) +#define SETPC_RELATIVE(ofs) pc += (ofs) + +#define CALL_USER_FUNC(f) pc = ((Function *) (f))->code + +#define DONE() goto done + +#define ERROR(msg) \ + do { \ + JS_SAVE_REGS (); \ + strcpy (vm->error, (msg)); \ + js_vm_error (vm); \ + /* NOTREACHED */ \ + } while (0) + + +struct compiled_st +{ + union + { + void *ptr; + JSUInt8 op; + JSInt8 i8; + JSInt16 i16; + JSInt32 i32; + } u; +}; + +typedef struct compiled_st Compiled; + +/* Debug information. */ +struct debug_info_st +{ + void *pc; + unsigned int linenum; +}; + +typedef struct debug_info_st DebugInfo; + +struct function_st +{ + JSHeapDestroyableCB destroy; + + char *name; + Compiled *code; + unsigned int length; + + struct + { + char *file; + unsigned int num_info; + DebugInfo *info; + } debug; +}; + +typedef struct function_st Function; + + +/* + * Prototypes for static functions. + */ + +static void function_destroy (void *ptr); + +static Function *link_code (JSVirtualMachine *vm, unsigned char *code, + unsigned int code_len, + unsigned int consts_offset, + unsigned char *debug_info, + unsigned int debug_info_len, + unsigned int code_offset); + +static void execute_code (JSVirtualMachine *vm, JSNode *object, Function *f, + unsigned int argc, JSNode *argv); + + +/* + * Global functions. + */ + +int +js_vm_switch_exec (JSVirtualMachine *vm, JSByteCode *bc, JSSymtabEntry *symtab, + unsigned int num_symtab_entries, + unsigned int consts_offset, + unsigned int anonymous_function_offset, + unsigned char *debug_info, unsigned int debug_info_len, + JSNode *object, JSNode *func, + unsigned int argc, JSNode *argv) +{ + int i; + unsigned int ui; + Function *global_f = NULL; + Function *f; + unsigned char *code = NULL; + char buf[512]; + + if (bc) + { + /* Executing byte-code. */ + + /* Find the code section. */ + for (i = 0; i < bc->num_sects; i++) + if (bc->sects[i].type == JS_BCST_CODE) + code = bc->sects[i].data; + assert (code != NULL); + + /* Enter all functions to the known functions of the VM. */ + for (i = 0; i < num_symtab_entries; i++) + { + /* Link the code to our environment. */ + f = link_code (vm, code + symtab[i].offset, + symtab[i + 1].offset - symtab[i].offset, + consts_offset, debug_info, debug_info_len, + symtab[i].offset); + f->name = js_strdup (vm, symtab[i].name); + + if (strcmp (symtab[i].name, JS_GLOBAL_NAME) == 0) + global_f = f; + else + { + int is_anonymous = 0; + + /* Check for the anonymous function. */ + if (symtab[i].name[0] == '.' && symtab[i].name[1] == 'F' + && symtab[i].name[2] == ':') + is_anonymous = 1; + + if (vm->verbose > 3) + { + sprintf (buf, "VM: link: %s(): start=%d, length=%d", + symtab[i].name, symtab[i].offset, + symtab[i + 1].offset - symtab[i].offset); + if (is_anonymous) + sprintf (buf + strlen (buf), + ", relocating with offset %u", + anonymous_function_offset); + strcat (buf, JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + + if (is_anonymous) + { + sprintf (buf, ".F:%u", + (unsigned int) atoi (symtab[i].name + 3) + + anonymous_function_offset); + ui = js_vm_intern (vm, buf); + } + else + ui = js_vm_intern (vm, symtab[i].name); + + vm->globals[ui].type = JS_FUNC; + vm->globals[ui].u.vfunction = js_vm_make_function (vm, f); + } + } + } + else + { + /* Applying arguments to function. */ + + if (func->type != JS_FUNC) + { + sprintf (vm->error, "illegal function in apply"); + return 0; + } + + if (vm->verbose > 1) + { + sprintf (buf, "VM: calling function%s", + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + f = func->u.vfunction->implementation; + + execute_code (vm, object, f, argc, argv); + } + + if (global_f) + { + if (vm->verbose > 1) + { + sprintf (buf, "VM: exec: %s%s", global_f->name, + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + + /* Execute. */ + execute_code (vm, NULL, global_f, 0, NULL); + } + + return 1; +} + + +const char * +js_vm_switch_func_name (JSVirtualMachine *vm, void *program_counter) +{ + int i; + Function *f; + Compiled *pc = program_counter; + JSNode *sp = vm->sp; + + /* Check the globals. */ + for (i = 0; i < vm->num_globals; i++) + if (vm->globals[i].type == JS_FUNC) + { + f = (Function *) vm->globals[i].u.vfunction->implementation; + if (f->code < pc && pc < f->code + f->length) + return f->name; + } + + /* No luck. Let's try the stack. */ + for (sp++; sp < vm->stack + vm->stack_size; sp++) + if (sp->type == JS_FUNC) + { + f = (Function *) sp->u.vfunction->implementation; + if (f->code < pc && pc < f->code + f->length) + return f->name; + } + + /* Still no matches. This shouldn't be reached... ok, who cares? */ + return JS_GLOBAL_NAME; +} + + +const char * +js_vm_switch_debug_position (JSVirtualMachine *vm, + unsigned int *linenum_return) +{ + int i; + Function *f; + void *program_counter = vm->pc; + Compiled *pc = vm->pc; + JSNode *sp = vm->sp; + unsigned int linenum = 0; + + /* Check the globals. */ + for (i = 0; i < vm->num_globals; i++) + if (vm->globals[i].type == JS_FUNC) + { + f = (Function *) vm->globals[i].u.vfunction->implementation; + if (f->code < pc && pc < f->code + f->length) + { + found: + + /* Ok, found it. */ + if (f->debug.file == NULL) + /* No debugging information available for this function. */ + return NULL; + + /* Find the correct pc position. */ + for (i = 0; i < f->debug.num_info; i++) + { + if (f->debug.info[i].pc > program_counter) + break; + + linenum = f->debug.info[i].linenum; + } + + *linenum_return = linenum; + return f->debug.file; + } + } + + /* No luck. Let's try the stack. */ + for (sp++; sp < vm->stack + vm->stack_size; sp++) + if (sp->type == JS_FUNC) + { + f = (Function *) sp->u.vfunction->implementation; + if (f->code < pc && pc < f->code + f->length) + /* Found it. */ + goto found; + } + + /* Couldn't find the function we are executing. */ + return NULL; +} + + +/* + * Static functions. + */ + +static void +function_destroy (void *ptr) +{ + Function *f = ptr; + + js_free (f->name); + js_free (f->code); + + if (f->debug.file) + js_free (f->debug.file); + if (f->debug.info) + js_free (f->debug.info); +} + + +static Function * +link_code (JSVirtualMachine *vm, unsigned char *code, unsigned int code_len, + unsigned int consts_offset, unsigned char *debug_info, + unsigned int debug_info_len, unsigned int code_offset) +{ + unsigned char *cp, *end; + JSInt32 i; + Compiled **reloc; + unsigned int cpos; + Function *f; + unsigned char *fixed_code; + unsigned int ui; + char *debug_filename = "unknown"; + char buf[512]; + + /* Terminate the code with op `done'. */ + fixed_code = js_malloc (vm, code_len + 1); + memcpy (fixed_code, code, code_len); + fixed_code[code_len] = 1; /* op `done' */ + + cp = fixed_code; + end = fixed_code + code_len + 1; + + /* Alloc function closure. */ + f = js_vm_alloc_destroyable (vm, sizeof (*f)); + f->destroy = function_destroy; + + /* Allocate space for our compiled code. is enought. */ + f->code = js_malloc (vm, (code_len + 1) * sizeof (Compiled)); + reloc = js_calloc (vm, code_len + 1, sizeof (Compiled *)); + + /* Link phase 1: constants and symbols. */ + cpos = 0; + while (cp < end) + { + switch (*cp++) + { + /* include c1switch.h */ +#include "c1switch.h" + /* end include c1switch.h */ + } + } + f->length = cpos; + + /* Link phase 2: relative jumps. */ + cp = fixed_code; + cpos = 0; + while (cp < end) + { + switch (*cp++) + { + /* include c2switch.h */ +#include "c2switch.h" + /* end include c2switch.h */ + } + } + /* Handle debug info. */ + if (debug_info) + { + unsigned int di_start = code_offset; + unsigned int di_end = code_offset + code_len; + unsigned int ln; + + for (; debug_info_len > 0;) + { + switch (*debug_info) + { + case JS_DI_FILENAME: + debug_info++; + debug_info_len--; + + JS_BC_READ_INT32 (debug_info, ui); + debug_info += 4; + debug_info_len -= 4; + + f->debug.file = js_malloc (vm, ui + 1); + memcpy (f->debug.file, debug_info, ui); + f->debug.file[ui] = '\0'; + + debug_filename = f->debug.file; + + debug_info += ui; + debug_info_len -= ui; + break; + + case JS_DI_LINENUMBER: + JS_BC_READ_INT32 (debug_info + 1, ui); + if (ui > di_end) + goto debug_info_done; + + /* This belongs to us (maybe). */ + debug_info += 5; + debug_info_len -= 5; + + JS_BC_READ_INT32 (debug_info, ln); + debug_info += 4; + debug_info_len -= 4; + + if (di_start <= ui && ui <= di_end) + { + ui -= di_start; + f->debug.info = js_realloc (vm, f->debug.info, + (f->debug.num_info + 1) + * sizeof (DebugInfo)); + + f->debug.info[f->debug.num_info].pc = reloc[ui]; + f->debug.info[f->debug.num_info].linenum = ln; + f->debug.num_info++; + } + break; + + default: + sprintf (buf, + "VM: unknown debug information type %d%s", + *debug_info, JS_HOST_LINE_BREAK); + + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); + + abort (); + break; + } + } + + debug_info_done: + if (f->debug.file == NULL) + f->debug.file = js_strdup (vm, debug_filename); + } + + js_free (reloc); + js_free (fixed_code); + + return f; +} + + +/* + * Execute byte code by using the `switch' dispatch technique. + */ + +static void +execute_code (JSVirtualMachine *vm, JSNode *object, Function *f, + unsigned int argc, JSNode *argv) +{ + JSNode *sp; + JSNode *fp; + JSNode *function; + JSNode builtin_result; + Compiled *pc; + JSInt32 i, j; + JSInt8 i8; + char buf[512]; + + /* Create the initial stack frame by hand. */ + sp = vm->sp; + + /* Protect the function from gc. */ + JS_SP0->type = JS_FUNC; + JS_SP0->u.vfunction = js_vm_make_function (vm, f); + JS_PUSH (); + + /* Push arguments to the stack. */ + i = argc; + for (i--; i >= 0; i--) + { + JS_COPY (JS_SP0, &argv[i]); + JS_PUSH (); + } + + /* This pointer. */ + if (object) + JS_COPY (JS_SP0, object); + else + JS_SP0->type = JS_NULL; + JS_PUSH (); + + /* Init fp and pc so our SUBROUTINE_CALL will work. */ + fp = NULL; + pc = NULL; + + JS_SUBROUTINE_CALL (f); + + /* Ok, now we are ready to run. */ + + while (1) + { + switch ((pc++)->u.op) + { + /* include eswitch.h */ +#include "eswitch.h" + /* end include eswitch.h */ + + default: + sprintf (buf, "execute_code: unknown opcode %d%s", + (pc - 1)->u.op, JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); + + abort (); + break; + } + } + + done: + + /* All done. */ + + JS_COPY (&vm->exec_result, JS_SP1); +} diff --git a/reactos/lib/kjs/ksrc/vmswt0.c b/reactos/lib/kjs/ksrc/vmswt0.c new file mode 100644 index 00000000000..e9d547d6db2 --- /dev/null +++ b/reactos/lib/kjs/ksrc/vmswt0.c @@ -0,0 +1,351 @@ +/* + * The basic `switch' instruction dispatcher. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/ksrc/vmswt0.c,v $ + * $Id: vmswt0.c,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +#include "jsint.h" + +/* + * Types and definitions. + */ + +struct function_st +{ + JSHeapDestroyableCB destroy; + + char *name; + unsigned char *code; + unsigned int length; +}; + +typedef struct function_st Function; + + +/* + * Prototypes for static functions. + */ + +static void function_destroy (void *ptr); + +static void link_code (JSVirtualMachine *vm, unsigned char *code, + unsigned int code_len, unsigned int consts_offset); + +static void execute_code (JSVirtualMachine *vm, JSNode *object, Function *f, + unsigned int argc, JSNode *argv); + + +/* + * Global functions. + */ + +int +js_vm_switch0_exec (JSVirtualMachine *vm, JSByteCode *bc, + JSSymtabEntry *symtab, + unsigned int num_symtab_entries, + unsigned int consts_offset, + unsigned int anonymous_function_offset, + unsigned char *debug_info, unsigned int debug_info_len, + JSNode *object, JSNode *func, + unsigned int argc, JSNode *argv) +{ + int i; + unsigned int ui; + Function *global_f = NULL; + Function *f; + unsigned char *code = NULL; + char buf[512]; + + if (bc) + { + /* Executing byte-code. */ + + /* Find the code section. */ + for (i = 0; i < bc->num_sects; i++) + if (bc->sects[i].type == JS_BCST_CODE) + code = bc->sects[i].data; + assert (code != NULL); + + /* Enter all functions to the known functions of the VM. */ + for (i = 0; i < num_symtab_entries; i++) + { + /* Need one function. */ + f = js_vm_alloc_destroyable (vm, sizeof (*f)); + f->destroy = function_destroy; + f->name = js_strdup (vm, symtab[i].name); + + f->length = symtab[i + 1].offset - symtab[i].offset + 1; + f->code = js_malloc (vm, f->length); + memcpy (f->code, code + symtab[i].offset, f->length - 1); + f->code[f->length - 1] = 1; /* op `done' */ + + /* Link the code to our environment. */ + link_code (vm, f->code, f->length, consts_offset); + + if (strcmp (symtab[i].name, JS_GLOBAL_NAME) == 0) + global_f = f; + else + { + int is_anonymous = 0; + + /* Check for the anonymous function. */ + if (symtab[i].name[0] == '.' && symtab[i].name[1] == 'F' + && symtab[i].name[2] == ':') + is_anonymous = 1; + + if (vm->verbose > 3) + { + sprintf (buf, "VM: link: %s(): start=%d, length=%d", + symtab[i].name, symtab[i].offset, + symtab[i + 1].offset - symtab[i].offset); + if (is_anonymous) + sprintf (buf + strlen (buf), + ", relocating with offset %u", + anonymous_function_offset); + strcat (buf, JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + + if (is_anonymous) + { + sprintf (buf, ".F:%u", + (unsigned int) atoi (symtab[i].name + 3) + + anonymous_function_offset); + ui = js_vm_intern (vm, buf); + } + else + ui = js_vm_intern (vm, symtab[i].name); + + vm->globals[ui].type = JS_FUNC; + vm->globals[ui].u.vfunction = js_vm_make_function (vm, f); + } + } + } + else + { + /* Applying arguments to function. */ + if (func->type != JS_FUNC) + { + sprintf (vm->error, "illegal function in apply"); + return 0; + } + + if (vm->verbose > 1) + { + sprintf (buf, "VM: calling function%s", + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + f = func->u.vfunction->implementation; + + execute_code (vm, object, f, argc, argv); + } + + if (global_f) + { + if (vm->verbose > 1) + { + sprintf (buf, "VM: exec: %s%s", global_f->name, + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + + /* Execute. */ + execute_code (vm, NULL, global_f, 0, NULL); + } + + return 1; +} + + +const char * +js_vm_switch0_func_name (JSVirtualMachine *vm, void *program_counter) +{ + int i; + Function *f; + unsigned char *pc = program_counter; + JSNode *sp = vm->sp; + + /* Check the globals. */ + for (i = 0; i < vm->num_globals; i++) + if (vm->globals[i].type == JS_FUNC) + { + f = (Function *) vm->globals[i].u.vfunction->implementation; + if (f->code < pc && pc < f->code + f->length) + return f->name; + } + + /* No luck. Let's try the stack. */ + for (sp++; sp < vm->stack + vm->stack_size; sp++) + if (sp->type == JS_FUNC) + { + f = (Function *) sp->u.vfunction->implementation; + if (f->code < pc && pc < f->code + f->length) + return f->name; + } + + /* Still no matches. This shouldn't be reached... ok, who cares? */ + return JS_GLOBAL_NAME; +} + + +const char * +js_vm_switch0_debug_position (JSVirtualMachine *vm, + unsigned int *linenum_return) +{ + /* XXX */ + return NULL; +} + + +/* + * Static functions. + */ + +static void +function_destroy (void *ptr) +{ + Function *f = ptr; + + js_free (f->name); + js_free (f->code); +} + + +static void +link_code (JSVirtualMachine *vm, unsigned char *code, unsigned int code_len, + unsigned int consts_offset) +{ + unsigned char *cp, *end; + JSInt32 i; + + cp = code; + end = code + code_len; + + while (cp < end) + { + switch (*cp++) + { + /* include c1swt0.h */ +#include "c1swt0.h" + /* end include c1swt0.h */ + } + } +} + + +/* + * Execute byte code by using the `switch' dispatch technique. + */ + +#define READ_INT8(i) JS_BC_READ_INT8(pc, (i)); (i) = (JSInt8) (i); pc++ +#define READ_INT16(i) JS_BC_READ_INT16(pc, (i)); (i) = (JSInt16) (i); pc += 2 +#define READ_INT32(i) JS_BC_READ_INT32(pc, (i)); (i) = (JSInt32) (i); pc += 4 + +#define SETPC(ofs) pc = (ofs) +#define SETPC_RELATIVE(ofs) pc += (ofs) + +#define CALL_USER_FUNC(f) pc = ((Function *) (f))->code + +#define DONE() goto done + +#define ERROR(msg) \ + do { \ + JS_SAVE_REGS (); \ + strcpy (vm->error, (msg)); \ + js_vm_error (vm); \ + /* NOTREACHED */ \ + } while (0) + +static void +execute_code (JSVirtualMachine *vm, JSNode *object, Function *f, + unsigned int argc, JSNode *argv) +{ + JSNode *sp; + JSNode *fp; + JSNode *function; + JSNode builtin_result; + unsigned char *pc; + JSInt32 i, j; + JSInt8 i8; + char buf[512]; + + /* Create the initial stack frame by hand. */ + sp = vm->sp; + + /* Protect the function from gc. */ + JS_SP0->type = JS_FUNC; + JS_SP0->u.vfunction = js_vm_make_function (vm, f); + JS_PUSH (); + + /* Push arguments to the stack. */ + i = argc; + for (i--; i >= 0; i--) + { + JS_COPY (JS_SP0, &argv[i]); + JS_PUSH (); + } + + /* This pointer. */ + if (object) + JS_COPY (JS_SP0, object); + else + JS_SP0->type = JS_NULL; + JS_PUSH (); + + /* Init fp and pc so our SUBROUTINE_CALL will work. */ + fp = NULL; + pc = NULL; + + JS_SUBROUTINE_CALL (f); + + /* Ok, now we are ready to run. */ + + while (1) + { + switch (*pc++) + { + /* include eswt0.h */ +#include "eswt0.h" + /* end include eswt0.h */ + + default: + sprintf (buf, "execute_code: unknown opcode %d%s", *(pc - 1), + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); + + abort (); + break; + } + } + + done: + + /* All done. */ + + JS_COPY (&vm->exec_result, JS_SP1); +} diff --git a/reactos/lib/kjs/ltmain.sh b/reactos/lib/kjs/ltmain.sh new file mode 100644 index 00000000000..e9350b3fab0 --- /dev/null +++ b/reactos/lib/kjs/ltmain.sh @@ -0,0 +1,2453 @@ +# ltmain.sh - Provide generalized library-building support services. +# NOTE: Changing this file will not affect anything until you rerun ltconfig. +# +# Copyright (C) 1996-1998 Free Software Foundation, Inc. +# Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program 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 +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# The name of this program. +progname=`$echo "$0" | sed 's%^.*/%%'` +modename="$progname" + +# Constants. +PROGRAM=ltmain.sh +PACKAGE=libtool +VERSION=1.2 + +default_mode= +help="Try \`$progname --help' for more information." +magic="%%%MAGIC variable%%%" +mkdir="mkdir" +mv="mv -f" +rm="rm -f" + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e s/^X//' +sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g' + +# NLS nuisances. +# Only set LANG and LC_ALL to C if already set. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LANG+set}" = set; then LANG=C; export LANG; fi + +if test "$LTCONFIG_VERSION" != "$VERSION"; then + echo "$modename: ltconfig version \`$LTCONFIG_VERSION' does not match $PROGRAM version \`$VERSION'" 1>&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 +fi + +if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + echo "$modename: not configured to build any kind of library" 1>&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show="$echo" +show_help= +execute_dlfiles= + +# Parse our command line options once, thoroughly. +while test $# -gt 0 +do + arg="$1" + shift + + case "$arg" in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case "$prev" in + execute_dlfiles) + eval "$prev=\"\$$prev \$arg\"" + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case "$arg" in + --help) + show_help=yes + ;; + + --version) + echo "$PROGRAM (GNU $PACKAGE) $VERSION" + exit 0 + ;; + + --dry-run | -n) + run=: + ;; + + --features) + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + exit 0 + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --quiet | --silent) + show=: + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + +if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 +fi + +if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + case "$nonopt" in + *cc | *++ | gcc* | *-gcc*) + mode=link + for arg + do + case "$arg" in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case "$mode" in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + lastarg= + srcfile="$nonopt" + suppress_output= + + for arg + do + # Accept any command-line options. + case "$arg" in + -o) + $echo "$modename: you cannot specify the output filename with \`-o'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + esac + + # Accept the current argument as the source file. + lastarg="$srcfile" + srcfile="$arg" + + # Aesthetically quote the previous argument. + + # Backslashify any backslashes, double quotes, and dollar signs. + # These are the only characters that are still specially + # interpreted inside of double-quoted scrings. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly in scan + # sets, so we specify it separately. + case "$lastarg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + lastarg="\"$lastarg\"" + ;; + esac + + # Add the previous argument to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + done + + # Get the name of the library object. + libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + + # Recognize several different file suffixes. + xform='[cCFSfms]' + case "$libobj" in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.f90) xform=f90 ;; + *.for) xform=for ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case "$libobj" in + *.lo) obj=`$echo "X$libobj" | $Xsed -e 's/\.lo$/.o/'` ;; + *) + $echo "$modename: cannot determine name of library object from \`$srcfile'" 1>&2 + exit 1 + ;; + esac + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + $run $rm $obj $libobj + trap "$run $rm $obj $libobj; exit 1" 1 2 15 + else + $run $rm $libobj + trap "$run $rm $libobj; exit 1" 1 2 15 + fi + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + # All platforms use -DPIC, to notify preprocessed assembler code. + $show "$base_compile$pic_flag -DPIC $srcfile" + if $run eval "$base_compile\$pic_flag -DPIC \$srcfile"; then : + else + test -n "$obj" && $run $rm $obj + exit 1 + fi + + # If we have no pic_flag, then copy the object into place and finish. + if test -z "$pic_flag"; then + $show "$LN_S $obj $libobj" + $run $LN_S $obj $libobj + exit $? + fi + + # Just move the object, then go on to compile the next one + $show "$mv $obj $libobj" + $run $mv $obj $libobj || exit 1 + + # Allow error messages only from the first compilation. + suppress_output=' >/dev/null 2>&1' + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + # Suppress compiler output if we already did a PIC compilation. + $show "$base_compile $srcfile$suppress_output" + if $run eval "$base_compile \$srcfile$suppress_output"; then : + else + $run $rm $obj $libobj + exit 1 + fi + fi + + # Create an invalid libtool object if no PIC, so that we do not + # accidentally link it into a program. + if test "$build_libtool_libs" != yes; then + $show "echo timestamp > $libobj" + $run eval "echo timestamp > \$libobj" || exit $? + fi + + exit 0 + ;; + + # libtool link mode + link) + modename="$modename: link" + CC="$nonopt" + allow_undefined=yes + compile_command="$CC" + finalize_command="$CC" + + compile_shlibpath= + finalize_shlibpath= + deplibs= + dlfiles= + dlprefiles= + export_dynamic=no + hardcode_libdirs= + libobjs= + link_against_libtool_libs= + ltlibs= + objs= + prev= + prevarg= + release= + rpath= + perm_rpath= + temp_rpath= + vinfo= + + # We need to know -static, to get the right output filenames. + for arg + do + case "$arg" in + -all-static | -static) + if test "X$arg" = "X-all-static" && test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2 + fi + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + for arg + do + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case "$prev" in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case "$prev" in + dlfiles|dlprefiles) + case "$arg" in + *.la | *.lo) ;; # We handle these cases below. + *) + dlprefiles="$dlprefiles $arg" + test "$prev" = dlfiles && dlfiles="$dlfiles $arg" + prev= + ;; + esac + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath) + rpath="$rpath $arg" + prev= + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi + + prevarg="$arg" + + case "$arg" in + -all-static) + if test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + if test "$export_dynamic" != yes; then + export_dynamic=yes + if test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + else + arg= + fi + + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + fi + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's%^-L\(.*\)$%\1%'` + case "$dir" in + /* | [A-Za-z]:\\*) + # Add the corresponding hardcode_libdir_flag, if it is not identical. + ;; + *) + $echo "$modename: \`-L$dir' cannot specify a relative directory" 1>&2 + exit 1 + ;; + esac + deplibs="$deplibs $arg" + ;; + + -l*) deplibs="$deplibs $arg" ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -o) prev=output ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -static) + # If we have no pic_flag, then this is the same as -all-static. + if test -z "$pic_flag" && test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + ;; + + *.o | *.a) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A library object. + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + if test "$build_libtool_libs" = yes; then + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e 's/\.lo$/\.o/'` + prev= + fi + libobjs="$libobjs $arg" + ;; + + *.la) + # A libtool-controlled library. + + dlname= + libdir= + library_names= + old_library= + + # Check to see that this really is a libtool archive. + if (sed -e '2q' $arg | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then : + else + $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2 + exit 1 + fi + + # If there is no directory component, then add one. + case "$arg" in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$libdir"; then + $echo "$modename: \`$arg' contains no -rpath information" 1>&2 + exit 1 + fi + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$arg'" 1>&2 + exit 1 + fi + + # Find the relevant object directory and library name. + name=`$echo "X$arg" | $Xsed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'` + dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$arg"; then + dir="$objdir" + else + dir="$dir/$objdir" + fi + + # This library was specified with -dlopen. + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + if test -z "$dlname"; then + # If there is no dlname, we need to preload. + prev=dlprefiles + else + # We should not create a dependency on this library, but we + # may need any libraries it requires. + compile_command="$compile_command$dependency_libs" + finalize_command="$finalize_command$dependency_libs" + prev= + continue + fi + fi + + # The library was specified with -dlpreopen. + if test "$prev" = dlprefiles; then + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + dlprefiles="$dlprefiles $dir/$old_library" + else + dlprefiles="$dlprefiles $dir/$linklib" + fi + prev= + fi + + if test "$build_libtool_libs" = yes && test -n "$library_names"; then + link_against_libtool_libs="$link_against_libtool_libs $arg" + if test -n "$shlibpath_var"; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *) temp_rpath="$temp_rpath $dir" ;; + esac + fi + + # This is the magic to use -rpath. + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + # Put the magic libdir with the hardcode flag. + hardcode_libdirs="$libdir" + libdir="@HARDCODE_LIBDIRS@" + else + # Just accumulate the unique libdirs. + case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + libdir= + fi + fi + + if test -n "$libdir"; then + eval flag=\"$hardcode_libdir_flag_spec\" + + compile_command="$compile_command $flag" + finalize_command="$finalize_command $flag" + fi + elif test -n "$runpath_var"; then + # Do the same for the permanent run path. + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + + + case "$hardcode_action" in + immediate) + if test "$hardcode_direct" = no; then + compile_command="$compile_command $dir/$linklib" + elif test "$hardcode_minus_L" = no; then + compile_command="$compile_command -L$dir -l$name" + elif test "$hardcode_shlibpath_var" = no; then + compile_shlibpath="$compile_shlibpath$dir:" + compile_command="$compile_command -l$name" + fi + ;; + + relink) + # We need an absolute path. + case "$dir" in + /* | [A-Za-z]:\\*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 + exit 1 + fi + dir="$absdir" + ;; + esac + + if test "$hardcode_direct" = yes; then + compile_command="$compile_command $dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + compile_command="$compile_command -L$dir -l$name" + elif test "$hardcode_shlibpath_var" = yes; then + compile_shlibpath="$compile_shlibpath$dir:" + compile_command="$compile_command -l$name" + fi + ;; + + *) + $echo "$modename: \`$hardcode_action' is an unknown hardcode action" 1>&2 + exit 1 + ;; + esac + + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + finalize_command="$finalize_command $libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + finalize_command="$finalize_command -L$libdir -l$name" + elif test "$hardcode_shlibpath_var" = yes; then + finalize_shlibpath="$finalize_shlibpath$libdir:" + finalize_command="$finalize_command -l$name" + else + # We cannot seem to hardcode it, guess we'll fake it. + finalize_command="$finalize_command -L$libdir -l$name" + fi + else + # Transform directly to old archives if we don't build new libraries. + if test -n "$pic_flag" && test -z "$old_library"; then + $echo "$modename: cannot find static library for \`$arg'" 1>&2 + exit 1 + fi + + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_command="$compile_command $dir/$linklib" + finalize_command="$finalize_command $dir/$linklib" + else + compile_command="$compile_command -L$dir -l$name" + finalize_command="$finalize_command -L$dir -l$name" + fi + fi + + # Add in any libraries that this one depends upon. + compile_command="$compile_command$dependency_libs" + finalize_command="$finalize_command$dependency_libs" + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + ;; + esac + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -n "$vinfo" && test -n "$release"; then + $echo "$modename: you cannot specify both \`-version-info' and \`-release'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + oldlib= + oldobjs= + case "$output" in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + + */* | *\\*) + $echo "$modename: output file \`$output' must have no directory components" 1>&2 + exit 1 + ;; + + *.a) + # Now set the variables for building old libraries. + build_libtool_libs=no + build_old_libs=yes + oldlib="$output" + $show "$rm $oldlib" + $run $rm $oldlib + ;; + + *.la) + # Make sure we only generate libraries of the form `libNAME.la'. + case "$output" in + lib*) ;; + *) + $echo "$modename: libtool library \`$arg' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + + name=`$echo "X$output" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval libname=\"$libname_spec\" + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + current=0 + revision=0 + age=0 + + if test -n "$objs"; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1 + exit 1 + fi + + # How the heck are we supposed to write a wrapper for a shared library? + if test -n "$link_against_libtool_libs"; then + $echo "$modename: libtool library \`$output' may not depend on uninstalled libraries:$link_against_libtool_libs" 1>&2 + exit 1 + fi + + if test -n "$dlfiles$dlprefiles"; then + $echo "$modename: warning: \`-dlopen' is ignored while creating libtool libraries" 1>&2 + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi + + if test -z "$rpath"; then + $echo "$modename: you must specify an installation directory with \`-rpath'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + set dummy $rpath + if test $# -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + # Parse the version information argument. + IFS="${IFS= }"; save_ifs="$IFS"; IFS=':' + set dummy $vinfo + IFS="$save_ifs" + + if test -n "$5"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + test -n "$2" && current="$2" + test -n "$3" && revision="$3" + test -n "$4" && age="$4" + + # Check that each of the things are valid numbers. + case "$current" in + 0 | [1-9] | [1-9][0-9]*) ;; + *) + $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case "$revision" in + 0 | [1-9] | [1-9][0-9]*) ;; + *) + $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case "$age" in + 0 | [1-9] | [1-9][0-9]*) ;; + *) + $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + if test $age -gt $current; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + fi + + # Calculate the version variables. + version_vars="version_type current age revision" + case "$version_type" in + none) ;; + + linux) + version_vars="$version_vars major versuffix" + major=`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + version_vars="$version_vars versuffix verstring" + major=`expr $current - $age` + versuffix="$current.$age.$revision" + verstring="$versuffix" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test $loop != 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + version_vars="$version_vars major versuffix" + major="$current" + versuffix="$current.$revision" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 + ;; + esac + + # Create the output directory, or remove our outputs if we need to. + if test -d $objdir; then + $show "$rm $objdir/$output $objdir/$libname.* $objdir/${libname}${release}.*" + $run $rm $objdir/$output $objdir/$libname.* $objdir/${libname}${release}.* + else + $show "$mkdir $objdir" + $run $mkdir $objdir + status=$? + if test $status -eq 0 || test -d $objdir; then : + else + exit $status + fi + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + # Add libc to deplibs on all systems. + dependency_libs="$deplibs" + deplibs="$deplibs -lc" + + if test "$build_libtool_libs" = yes; then + # Get the real and link names of the library. + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + lib="$objdir/$realname" + for link + do + linknames="$linknames $link" + done + + # Use standard objects if they are PIC. + test -z "$pic_flag" && libobjs=`$echo "X$libobjs " | $Xsed -e 's/\.lo /.o /g' -e 's/ $//g'` + + # Do each of the archive commands. + eval cmds=\"$archive_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS=';' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Create links to the real library. + for linkname in $linknames; do + $show "(cd $objdir && $LN_S $realname $linkname)" + $run eval '(cd $objdir && $LN_S $realname $linkname)' || exit $? + done + + # If -export-dynamic was specified, set the dlname. + if test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + + # Now set the variables for building old libraries. + oldlib="$objdir/$libname.a" + ;; + + *.lo | *.o) + if test -n "$link_against_libtool_libs"; then + $echo "$modename: error: cannot link libtool libraries into reloadable objects" 1>&2 + exit 1 + fi + + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored while creating objects" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles"; then + $echo "$modename: warning: \`-dlopen' is ignored while creating objects" 1>&2 + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored while creating objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored while creating objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored while creating objects" 1>&2 + fi + + case "$output" in + *.lo) + if test -n "$objs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit 1 + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e 's/\.lo$/.o/'` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $run $rm $obj $libobj + + # Create the old-style object. + reload_objs="$objs"`$echo "X$libobjs " | $Xsed -e 's/[^ ]*\.a //g' -e 's/\.lo /.o /g' -e 's/ $//g'` + + output="$obj" + eval cmds=\"$reload_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS=';' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + test -z "$libobj" && exit 0 + + if test "$build_libtool_libs" != yes; then + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + $show "echo timestamp > $libobj" + $run eval "echo timestamp > $libobj" || exit $? + exit 0 + fi + + if test -n "$pic_flag"; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs" + output="$libobj" + eval cmds=\"$reload_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS=';' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + else + # Just create a symlink. + $show "$LN_S $obj $libobj" + $run $LN_S $obj $libobj || exit 1 + fi + + exit 0 + ;; + + *) + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored while linking programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored while creating objects" 1>&2 + fi + + if test -n "$rpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + # Put the magic libdir with the hardcode flag. + hardcode_libdirs="$libdir" + libdir="@HARDCODE_LIBDIRS@" + else + # Just accumulate the unique libdirs. + case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + libdir= + fi + fi + + if test -n "$libdir"; then + eval flag=\"$hardcode_libdir_flag_spec\" + + compile_command="$compile_command $flag" + finalize_command="$finalize_command $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + fi + + # Substitute the hardcoded libdirs into the compile commands. + if test -n "$hardcode_libdir_separator"; then + compile_command=`$echo "X$compile_command" | $Xsed -e "s%@HARDCODE_LIBDIRS@%$hardcode_libdirs%g"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@HARDCODE_LIBDIRS@%$hardcode_libdirs%g"` + fi + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$echo "X$compile_command " | $Xsed -e 's/\.lo /.o /g' -e 's/ $//'` + finalize_command=`$echo "X$finalize_command " | $Xsed -e 's/\.lo /.o /g' -e 's/ $//'` + fi + + if test "$export_dynamic" = yes && test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${output}S.c" + else + dlsyms= + fi + + if test -n "$dlsyms"; then + # Add our own program objects to the preloaded list. + dlprefiles=`$echo "X$objs$dlprefiles " | $Xsed -e 's/\.lo /.o /g' -e 's/ $//'` + + # Discover the nlist of each of the dlfiles. + nlist="$objdir/${output}.nm" + + if test -d $objdir; then + $show "$rm $nlist ${nlist}T" + $run $rm "$nlist" "${nlist}T" + else + $show "$mkdir $objdir" + $run $mkdir $objdir + status=$? + if test $status -eq 0 || test -d $objdir; then : + else + exit $status + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + # Parse the name list into a source file. + $show "creating $objdir/$dlsyms" + if test -z "$run"; then + # Make sure we at least have an empty file. + test -f "$nlist" || : > "$nlist" + + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + wcout=`wc "$nlist" 2>/dev/null` + count=`echo "X$wcout" | $Xsed -e 's/^[ ]*\([0-9][0-9]*\).*$/\1/'` + (test "$count" -ge 0) 2>/dev/null || count=-1 + else + $rm "$nlist"T + count=-1 + fi + + case "$dlsyms" in + "") ;; + *.c) + $echo > "$objdir/$dlsyms" "\ +/* $dlsyms - symbol resolution table for \`$output' dlsym emulation. */ +/* Generated by $PROGRAM - GNU $PACKAGE $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* Prevent the only kind of declaration conflicts we can make. */ +#define dld_preloaded_symbol_count some_other_symbol +#define dld_preloaded_symbols some_other_symbol + +/* External symbol declarations for the compiler. */\ +" + + if test -f "$nlist"; then + sed -e 's/^.* \(.*\)$/extern char \1;/' < "$nlist" >> "$objdir/$dlsyms" + else + echo '/* NONE */' >> "$objdir/$dlsyms" + fi + + $echo >> "$objdir/$dlsyms" "\ + +#undef dld_preloaded_symbol_count +#undef dld_preloaded_symbols + +#if defined (__STDC__) && __STDC__ +# define __ptr_t void * +#else +# define __ptr_t char * +#endif + +/* The number of symbols in dld_preloaded_symbols, -1 if unsorted. */ +int dld_preloaded_symbol_count = $count; + +/* The mapping between symbol names and symbols. */ +struct { + char *name; + __ptr_t address; +} +dld_preloaded_symbols[] = +{\ +" + + if test -f "$nlist"; then + sed 's/^\(.*\) \(.*\)$/ {"\1", (__ptr_t) \&\2},/' < "$nlist" >> "$objdir/$dlsyms" + fi + + $echo >> "$objdir/$dlsyms" "\ + {0, (__ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif\ +" + ;; + + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit 1 + ;; + esac + fi + + # Now compile the dynamic symbol file. + $show "(cd $objdir && $CC -c$no_builtin_flag \"$dlsyms\")" + $run eval '(cd $objdir && $CC -c$no_builtin_flag "$dlsyms")' || exit $? + + # Transform the symbol file into the correct name. + compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$objdir/${output}S.o%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$objdir/${output}S.o%"` + elif test "$export_dynamic" != yes; then + test -n "$dlfiles$dlprefiles" && $echo "$modename: warning: \`-dlopen' and \`-dlpreopen' are ignored without \`-export-dynamic'" 1>&2 + else + # We keep going just in case the user didn't refer to + # dld_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi + + if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + finalize_command=`$echo "X$finalize_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + + # We have no uninstalled library dependencies, so finalize right now. + $show "$compile_command" + $run eval "$compile_command" + exit $? + fi + + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$objdir/$output"'%g'` + finalize_command=`$echo "X$finalize_command" | $Xsed -e 's%@OUTPUT@%'"$objdir/$output"'T%g'` + + # Create the binary in the object directory, then wrap it. + if test -d $objdir; then : + else + $show "$mkdir $objdir" + $run $mkdir $objdir + status=$? + if test $status -eq 0 || test -d $objdir; then : + else + exit $status + fi + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case "$dir" in + /* | [A-Za-z]:\\*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + # Delete the old output file. + $run $rm $output + + if test -n "$compile_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_command="$runpath_var=\"$rpath\$$runpath_var\" $compile_command" + finalize_command="$runpath_var=\"$rpath\$$runpath_var\" $finalize_command" + fi + + case "$hardcode_action" in + relink) + # AGH! Flame the AIX and HP-UX people for me, will ya? + $echo "$modename: warning: using a buggy system linker" 1>&2 + $echo "$modename: relinking will be required before \`$output' can be installed" 1>&2 + ;; + esac + + $show "$compile_command" + $run eval "$compile_command" || exit $? + + # Now create the wrapper script. + $show "creating $output" + + # Quote the finalize command for shipping. + finalize_command=`$echo "X$finalize_command" | $Xsed -e "$sed_quote_subst"` + + # Quote $echo for shipping. + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + $rm $output + trap "$rm $output; exit 1" 1 2 15 + + $echo > $output "\ +#! /bin/sh + +# $output - temporary wrapper script for $objdir/$output +# Generated by ltmain.sh - GNU $PACKAGE $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of \``pwd`'. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e s/^X//' +sed_quote_subst='$sed_quote_subst' + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test \"\${CDPATH+set}\" = set; then CDPATH=; export CDPATH; fi + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + link_against_libtool_libs='$link_against_libtool_libs' + finalize_command=\"$finalize_command\" +else + # When we are sourced in execute mode, \$file and \$echo are already set. + if test \"\$libtool_execute_magic\" = \"$magic\"; then : + else + echo=\"$qecho\" + file=\"\$0\" + fi\ +" + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + /* | [A-Za-z]:\\*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" + + progdir=\"\$thisdir/$objdir\" + program='$output' + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/:*\$//'\` + + export $shlibpath_var +" + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + + # Export the path to the program. + PATH=\"\$progdir:\$PATH\" + export PATH + + exec \$program \${1+\"\$@\"} + + \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" + exit 1 + fi + else + # The program doesn't exist. + \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 + \$echo \"This script is just a wrapper for \$program.\" 1>&2 + echo \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" + chmod +x $output + fi + exit 0 + ;; + esac + + # See if we need to build an old-fashioned archive. + if test "$build_old_libs" = "yes"; then + # Transform .lo files to .o files. + oldobjs="$objs"`$echo "X$libobjs " | $Xsed -e 's/[^ ]*\.a //g' -e 's/\.lo /.o /g' -e 's/ $//g'` + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + eval cmds=\"$old_archive_from_new_cmds\" + else + eval cmds=\"$old_archive_cmds\" + fi + IFS="${IFS= }"; save_ifs="$IFS"; IFS=';' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Now create the libtool archive. + case "$output" in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.a" + + $show "creating $output" + + # Only create the output if not a dry run. + if test -z "$run"; then + $echo > $output "\ +# $output - a libtool library file +# Generated by ltmain.sh - GNU $PACKAGE $VERSION + +# The name that we can dlopen(3). +dlname='$dlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Directory that this library needs to be installed in: +libdir='$install_libdir'\ +" + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $objdir && $LN_S ../$output $output)" + $run eval "(cd $objdir && $LN_S ../$output $output)" || exit 1 + ;; + esac + exit 0 + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional /bin/sh argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL"; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg="$nonopt" + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir= + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest="$arg" + continue + fi + + case "$arg" in + -d) isdir=yes ;; + -f) prev="-f" ;; + -g) prev="-g" ;; + -m) prev="-m" ;; + -o) prev="-o" ;; + -s) + stripme=" -s" + continue + ;; + -*) ;; + + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest="$arg" + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit 1 + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test -n "$isdir"; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test $# -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + fi + case "$destdir" in + /* | [A-Za-z]:\\*) ;; + *) + for file in $files; do + case "$file" in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case "$file" in + *.a) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (sed -e '2q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + library_names= + old_library= + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir="`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/" + test "X$dir" = "X$file/" && dir= + dir="$dir$objdir" + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$realname $destdir/$realname" + $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $? + test "X$dlname" = "X$realname" && dlname= + + if test $# -gt 0; then + # Delete the old symlinks. + rmcmd="$rm" + for linkname + do + rmcmd="$rmcmd $destdir/$linkname" + done + $show "$rmcmd" + $run $rmcmd + + # ... and create new ones. + for linkname + do + test "X$dlname" = "X$linkname" && dlname= + $show "(cd $destdir && $LN_S $realname $linkname)" + $run eval "(cd $destdir && $LN_S $realname $linkname)" + done + fi + + if test -n "$dlname"; then + # Install the dynamically-loadable library. + $show "$install_prog $dir/$dlname $destdir/$dlname" + $run eval "$install_prog $dir/$dlname $destdir/$dlname" || exit $? + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + eval cmds=\"$postinstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS=';' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + $show "$install_prog $file $destdir/$name" + $run eval "$install_prog $file $destdir/$name" || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case "$destfile" in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e 's/\.lo$/\.o/'` + ;; + *.o) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e 's/\.lo$/\.o/'` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit 0 + ;; + + *) + # Do a test to see if this is really a libtool program. + if (sed -e '4q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then + link_against_libtool_libs= + finalize_command= + + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Check the variables that should have been set. + if test -z "$link_against_libtool_libs" || test -z "$finalize_command"; then + $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2 + exit 1 + fi + + finalize=yes + for lib in $link_against_libtool_libs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case "$lib" in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/`$echo "X$lib" | $Xsed -e 's%^.*/%%g'`" + if test -z "$libdir"; then + $echo "$modename: warning: \`$lib' contains no -rpath information" 1>&2 + elif test -f "$libfile"; then : + else + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + if test "$hardcode_action" = relink; then + if test "$finalize" = yes; then + $echo "$modename: warning: relinking \`$file' on behalf of your buggy system linker" 1>&2 + $show "$finalize_command" + if $run eval "$finalize_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + continue + fi + file="$objdir/$file"T + else + $echo "$modename: warning: cannot relink \`$file' on behalf of your buggy system linker" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + $show "$install_prog$stripme $file $dest" + $run eval "$install_prog\$stripme \$file \$dest" || exit $? + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + # Do each command in the postinstall commands. + eval cmds=\"$old_postinstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS=';' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec $SHELL $0 --finish$current_libdirs + exit 1 + fi + + exit 0 + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + eval cmds=\"$finish_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS=';' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" + fi + done + fi + + echo "------------------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + echo " $libdir" + done + echo + echo "To link against installed libraries in a given directory, LIBDIR," + echo "you must use the \`-LLIBDIR' flag during linking." + echo + echo " You will also need to do one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + echo " - use the \`$flag' linker flag" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo + echo "See any operating system documentation about shared libraries for" + echo "more information, such as the ld(1) and ld.so(8) manual pages." + echo "------------------------------------------------------------------------------" + exit 0 + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit 1 + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test -f "$file"; then : + else + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + dir= + case "$file" in + *.la) + # Check to see that this really is a libtool archive. + if (sed -e '2q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit 1 + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case "$file" in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (sed -e '4q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + + # Now actually exec the command. + eval "exec \$cmd$args" + + $echo "$modename: cannot exec \$cmd$args" + exit 1 + else + # Display what would be done. + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + $echo "$cmd$args" + exit 0 + fi + ;; + + # libtool uninstall mode + uninstall) + modename="$modename: uninstall" + rm="$nonopt" + files= + + for arg + do + case "$arg" in + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + rmfiles="$file" + + case "$name" in + *.la) + # Possibly a libtool archive, so verify it. + if (sed -e '2q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $dir/$n" + test "X$n" = "X$dlname" && dlname= + done + test -n "$dlname" && rmfiles="$rmfiles $dir/$dlname" + test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library" + + $show "$rm $rmfiles" + $run $rm $rmfiles + + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + eval cmds=\"$postuninstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS=';' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + eval cmds=\"$old_postuninstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS=';' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + done + IFS="$save_ifs" + fi + + # FIXME: should reinstall the best remaining shared library. + fi + ;; + + *.lo) + if test "$build_old_libs" = yes; then + oldobj=`$echo "X$name" | $Xsed -e 's/\.lo$/\.o/'` + rmfiles="$rmfiles $dir/$oldobj" + fi + $show "$rm $rmfiles" + $run $rm $rmfiles + ;; + + *) + $show "$rm $rmfiles" + $run $rm $rmfiles + ;; + esac + done + exit 0 + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + ;; + esac + + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 +fi # test -z "$show_help" + +# We need to display help for each of the modes. +case "$mode" in +"") $echo \ +"Usage: $modename [OPTION]... [MODE-ARG]... + +Provide generalized library-building support services. + +-n, --dry-run display commands without modifying any files + --features display configuration information and exit + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --version print version information + +MODE must be one of the following: + + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for +a more detailed description of MODE." + exit 0 + ;; + +compile) + $echo \ +"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + +execute) + $echo \ +"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + +finish) + $echo \ +"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + +install) + $echo \ +"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + +link) + $echo \ +"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to dld_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -static do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only +library objects (\`.lo' files) may be specified, and \`-rpath' is required. + +If OUTPUT-FILE ends in \`.a', then a standard library is created using \`ar' +and \`ranlib'. + +If OUTPUT-FILE ends in \`.lo' or \`.o', then a reloadable object file is +created, otherwise an executable program is created." + ;; + +uninstall) + $echo +"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + +*) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; +esac + +echo +$echo "Try \`$modename --help' for more information about other modes." + +exit 0 + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/reactos/lib/kjs/makefile b/reactos/lib/kjs/makefile new file mode 100644 index 00000000000..9c2a229d210 --- /dev/null +++ b/reactos/lib/kjs/makefile @@ -0,0 +1,96 @@ +# $Id: makefile,v 1.1 2004/01/10 20:38:17 arty Exp $ +# Kernel JavaScript +# +# You can use this for various things but the most obvious is as a powerful +# interactive debugger. +# +# Other modules might use it as well to prototype parts of the kernel, and +# to implement policy. Since kjs can read the registry, it is possible to +# load libraries from there. Also, I'm adding an easy interface that allows +# a module to introduce its own kjs methods. +# + +PATH_TO_TOP = ../.. + +TARGET_BOOTSTRAP = yes + +TARGET_TYPE = library + +TARGET_NAME = kjs + +TARGET_CFLAGS = -g -D__NTKJS__ -Werror -Wall -I. -Isrc -Iinclude + +# require os code to explicitly request A/W version of structs/functions +TARGET_CFLAGS += -D_DISABLE_TIDENTS + +TARGET_ASFLAGS = -I $(PATH_TO_TOP)/include + +TARGET_LFLAGS = -Wl,--file-alignment,0x1000 \ + -Wl,--section-alignment,0x1000 \ + -nostartfiles -nostdlib \ + +TARGET_GCCLIBS = gcc + +TARGET_BASE = 0x79f60000 + +TARGET_PATH = + +# +# TARGET_ENTRY = 0x0 +# + +ARCH_OBJECTS = ksrc/setjmp.o ksrc/longjmp.o +MOD_OBJECTS = ksrc/alloc.o \ + ksrc/bc.o \ + ksrc/b_core.o \ + ksrc/b_file.o \ + ksrc/b_func.o \ + ksrc/b_regexp.o \ + ksrc/b_system.o \ + ksrc/compat.o \ + ksrc/debug.o \ + ksrc/iostream.o \ + ksrc/js.o \ + ksrc/kjs.o \ + ksrc/mrgsort.o \ + ksrc/object.o \ + ksrc/regex.o \ + ksrc/vm.o \ + ksrc/vmjumps.o \ + ksrc/vmswitch.o \ + ksrc/vmswt0.o +ORIG_OBJECTS = src/b_array.o \ + src/b_bool.o \ + src/b_object.o \ + src/b_number.o \ + src/b_string.o \ + src/b_vm.o \ + src/compiler.o \ + src/crc32.o \ + src/dl_dummy.o \ + src/heap.o \ + src/utils.o +TARGET_OBJECTS = $(ORIG_OBJECTS) $(MOD_OBJECTS) $(ARCH_OBJECTS) \ + ../../dk/w32/lib/ntdll.a +DEP_OBJECTS = $(TARGET_OBJECTS) + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +include $(TOOLS_PATH)/depend.mk + +%/TAGS: + etags -o $(@D)/TAGS $(@D)/\*.c + +etags: csr/TAGS dbg/TAGS ldr/TAGS main/TAGS rtl/TAGS stdio/TAGS stdlib/TAGS string/TAGS stubs/TAGS + etags -i csr/TAGS -i dbg/TAGS -i ldr/TAGS -i main/TAGS -i rtl/TAGS -i stdio/TAGS -i stdlib/TAGS -i string/TAGS -i stubs/TAGS + + +docu: + doxygen Doxyfile + +.PHONY: docu + + +# EOF diff --git a/reactos/lib/kjs/micros/ChangeLog b/reactos/lib/kjs/micros/ChangeLog new file mode 100644 index 00000000000..ccc00679430 --- /dev/null +++ b/reactos/lib/kjs/micros/ChangeLog @@ -0,0 +1,31 @@ +1998-10-16 Markku Rossi + + * makefile.w32: Makefile for the w32 environment. Thanks to Paul + Rohr . + + * Makefile.am (EXTRA_DIST): Added w32 files. + +1998-09-29 Markku Rossi + + * w32.c: Implemented {open,read,close,rewind,seek,tell}dir() + functions. + + * w32.h: New header to hold the w32 definitions. + +1998-08-17 Markku Rossi + + * w32.c: New file to implement some missing functions on w32. + + * jsconfig.w32: The jsconfig.h file for w32 environment. + +1998-04-03 Markku Rossi + + * os2.c: New file to implement some missing functions on OS/2. + +1998-04-01 Markku Rossi + + * ccprops.c (preprocessor): Fetch some preprocessor properties. + +1998-03-30 Markku Rossi + + * ccprops.c: Program to fetch different C-compiler properties. diff --git a/reactos/lib/kjs/micros/Makefile b/reactos/lib/kjs/micros/Makefile new file mode 100644 index 00000000000..afd5374a7be --- /dev/null +++ b/reactos/lib/kjs/micros/Makefile @@ -0,0 +1,196 @@ +# Generated automatically from Makefile.in by configure. +# Makefile.in generated automatically by automake 1.3 from Makefile.am + +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Automakefile for the micro ports directory. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + + +SHELL = /bin/sh + +srcdir = . +top_srcdir = .. +prefix = /usr/local/js-0.2.5 +exec_prefix = ${prefix} + +bindir = ${exec_prefix}/bin +sbindir = ${exec_prefix}/sbin +libexecdir = ${exec_prefix}/libexec +datadir = ${prefix}/share +sysconfdir = ${prefix}/etc +sharedstatedir = ${prefix}/com +localstatedir = ${prefix}/var +libdir = ${exec_prefix}/lib +infodir = ${prefix}/info +mandir = ${prefix}/man +includedir = ${prefix}/include +oldincludedir = /usr/include + +DISTDIR = + +pkgdatadir = $(datadir)/js +pkglibdir = $(libdir)/js +pkgincludedir = $(includedir)/js + +top_builddir = .. + +ACLOCAL = aclocal +AUTOCONF = autoconf +AUTOMAKE = automake +AUTOHEADER = autoheader + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} +transform = s,x,x, + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = i686-pc-linux-gnu +host_triplet = i686-pc-linux-gnu +ACLOCAL_FLAGS_FOR_LIBTOOL = +CC = gcc +CPP = gcc -E +EXTENSIONS = dl_open.lo xjs.lo xmd5.lo md5c.lo +EXTENSIONS_LIBS = -ldl +INTERPRETER_FEATURES = r_std.lo +LD = /usr/bin/ld +LIBTOOL = $(SHELL) $(top_builddir)/libtool +LN_S = ln -s +MAKEINFO = makeinfo +NM = /usr/bin/nm -B +PACKAGE = js +PGCC_BY_PROVENZANO = +RANLIB = ranlib +U = +VERSION = 0.2.5 +XLC_R_AIX = + +EXTRA_DIST = ccprops.c README.OS2 jsconfig.os2 makefile.os2 os2.c \ +jsconfig.w32 makefile.w32 w32.c w32.h +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../jsconfig.h +CONFIG_CLEAN_FILES = +DIST_COMMON = ChangeLog Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP = --best +all: Makefile + +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps micros/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = micros + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done +info: +dvi: +check: all + $(MAKE) +installcheck: +install-exec: + @$(NORMAL_INSTALL) + +install-data: + @$(NORMAL_INSTALL) + +install: install-exec install-data all + @: + +uninstall: + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean: mostlyclean-generic + +clean: clean-generic mostlyclean + +distclean: distclean-generic clean + -rm -f config.status + -rm -f libtool + +maintainer-clean: maintainer-clean-generic distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +.PHONY: tags distdir info dvi installcheck install-exec install-data \ +install uninstall all installdirs mostlyclean-generic distclean-generic \ +clean-generic maintainer-clean-generic clean mostlyclean distclean \ +maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/reactos/lib/kjs/micros/Makefile.am b/reactos/lib/kjs/micros/Makefile.am new file mode 100644 index 00000000000..b1d30e4d113 --- /dev/null +++ b/reactos/lib/kjs/micros/Makefile.am @@ -0,0 +1,26 @@ +# +# Automakefile for the micro ports directory. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + +EXTRA_DIST = ccprops.c README.OS2 jsconfig.os2 makefile.os2 os2.c \ +jsconfig.w32 makefile.w32 w32.c w32.h diff --git a/reactos/lib/kjs/micros/Makefile.in b/reactos/lib/kjs/micros/Makefile.in new file mode 100644 index 00000000000..2712da0e9ea --- /dev/null +++ b/reactos/lib/kjs/micros/Makefile.in @@ -0,0 +1,196 @@ +# Makefile.in generated automatically by automake 1.3 from Makefile.am + +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Automakefile for the micro ports directory. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + + +SHELL = /bin/sh + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DISTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_FLAGS_FOR_LIBTOOL = @ACLOCAL_FLAGS_FOR_LIBTOOL@ +CC = @CC@ +CPP = @CPP@ +EXTENSIONS = @EXTENSIONS@ +EXTENSIONS_LIBS = @EXTENSIONS_LIBS@ +INTERPRETER_FEATURES = @INTERPRETER_FEATURES@ +LD = @LD@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +NM = @NM@ +PACKAGE = @PACKAGE@ +PGCC_BY_PROVENZANO = @PGCC_BY_PROVENZANO@ +RANLIB = @RANLIB@ +U = @U@ +VERSION = @VERSION@ +XLC_R_AIX = @XLC_R_AIX@ + +EXTRA_DIST = ccprops.c README.OS2 jsconfig.os2 makefile.os2 os2.c \ +jsconfig.w32 makefile.w32 w32.c w32.h +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../jsconfig.h +CONFIG_CLEAN_FILES = +DIST_COMMON = ChangeLog Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP = --best +all: Makefile + +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps micros/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = micros + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done +info: +dvi: +check: all + $(MAKE) +installcheck: +install-exec: + @$(NORMAL_INSTALL) + +install-data: + @$(NORMAL_INSTALL) + +install: install-exec install-data all + @: + +uninstall: + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean: mostlyclean-generic + +clean: clean-generic mostlyclean + +distclean: distclean-generic clean + -rm -f config.status + -rm -f libtool + +maintainer-clean: maintainer-clean-generic distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +.PHONY: tags distdir info dvi installcheck install-exec install-data \ +install uninstall all installdirs mostlyclean-generic distclean-generic \ +clean-generic maintainer-clean-generic clean mostlyclean distclean \ +maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/reactos/lib/kjs/micros/README.OS2 b/reactos/lib/kjs/micros/README.OS2 new file mode 100644 index 00000000000..565b04fdf4b --- /dev/null +++ b/reactos/lib/kjs/micros/README.OS2 @@ -0,0 +1,6 @@ + + JavaScript on OS/2 1.3 + ====================== + +This document describes how the JavaScript interpreter version 0.0.2 +was compiled on OS/2-1.3 using the Microsoft's C-compiler 6.0. diff --git a/reactos/lib/kjs/micros/ccprops.c b/reactos/lib/kjs/micros/ccprops.c new file mode 100644 index 00000000000..ece36cb34e9 --- /dev/null +++ b/reactos/lib/kjs/micros/ccprops.c @@ -0,0 +1,78 @@ +/* + * Print CC properties. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/micros/ccprops.c,v $ + * $Id: ccprops.c,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +#include + +/* + * Static functions. + */ + +static void +sizes () +{ + printf ("\n* The sizes of different types\n\n"); + printf ("\ttype\tsize\n\t--------------------\n"); + printf ("\ +\tchar\t%d\n\ +\tshort\t%d\n\ +\tint\t%d\n\ +\tlong\t%d\n\ +\tfloat\t%d\n\ +\tdouble\t%d\n\ +\tvoid *\t%d\n", + sizeof (char), + sizeof (short), + sizeof (int), + sizeof (long), + sizeof (float), + sizeof (double), + sizeof (void *)); +} + +static void +preprocessor () +{ + printf ("\n* Preprocessor\n\n"); +#ifdef __STDC__ + printf ("\t__STDC__=%d\n", __STDC__); +#else /* no __STDC__ */ + printf ("\tno __STDC__\n"); +#endif /* no __STDC__ */ +} + +/* + * Global functions. + */ + +int +main (int argc, char *argv[]) +{ + sizes (); + preprocessor (); +} diff --git a/reactos/lib/kjs/micros/jsconfig.os2 b/reactos/lib/kjs/micros/jsconfig.os2 new file mode 100644 index 00000000000..37aa3399424 --- /dev/null +++ b/reactos/lib/kjs/micros/jsconfig.os2 @@ -0,0 +1,80 @@ +/* jsconfig.h. Generated automatically by configure. */ +/* jsconfig.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#undef _ALL_SOURCE + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define as __inline if that's what the C compiler calls it. */ +#define inline + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Package name. */ +#define PACKAGE "js" + +/* Version number. */ +#define VERSION "0.0.2" + +/* Are C prototypes supported. */ +#define PROTOTYPES 1 + +/* Canonical host name and its parts. */ +#define CANONICAL_HOST "x86-pc-os2.1.3" +#define CANONICAL_HOST_CPU "x86" +#define CANONICAL_HOST_VENDOR "pc" +#define CANONICAL_HOST_OS "os2.1.3" + +/* Do we want to build all instruction dispatchers? */ +#undef ALL_DISPATCHERS + +/* Curses. */ +/* #undef WITH_CURSES */ +/* #undef HAVE_CURSES_H */ +/* #undef HAVE_NCURSES_H */ + +/* The number of bytes in a int. */ +#define SIZEOF_INT 2 + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 4 + +/* Define if you have the drand48 function. */ +#undef HAVE_DRAND48 + +/* Define if you have the sleep function. */ +#undef HAVE_SLEEP + +/* Define if you have the srand48 function. */ +#undef HAVE_SRAND48 + +/* Define if you have the usleep function. */ +#undef HAVE_USLEEP + +/* Define if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define if you have the header file. */ +#define HAVE_FLOAT_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + + +/* + * Prototypes for some compatibility functions. + */ + +unsigned int sleep (unsigned int seconds); +int usleep (unsigned int useconds); diff --git a/reactos/lib/kjs/micros/jsconfig.w32 b/reactos/lib/kjs/micros/jsconfig.w32 new file mode 100644 index 00000000000..da17cf7edd5 --- /dev/null +++ b/reactos/lib/kjs/micros/jsconfig.w32 @@ -0,0 +1,118 @@ +/* jsconfig.h. Generated automatically by configure. */ +/* jsconfig.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#undef _ALL_SOURCE + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define as __inline if that's what the C compiler calls it. */ +#define inline + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* + * Define the PACKAGE and VERSION only if they are undefined. This means + * that we do not redefine them, when the library is used in another + * GNU like package that defines PACKAGE and VERSION. + */ + +/* Package name. */ +#ifndef PACKAGE +#define PACKAGE "js" +#endif /* no PACKAGE */ + +/* Version number. */ +#ifndef VERSION +#define VERSION "0.2.2" +#endif /* no VERSION */ + +/* Are C prototypes supported. */ +#define PROTOTYPES 1 + +/* Canonical host name and its parts. */ +#define CANONICAL_HOST "x86-pc-w32" +#define CANONICAL_HOST_CPU "x86" +#define CANONICAL_HOST_VENDOR "pc" +#define CANONICAL_HOST_OS "w32" + +/* Do we want to build all instruction dispatchers? */ +/* #undef ALL_DISPATCHERS */ + +/* Do we want to profile byte-code operands. */ +/* #undef PROFILING */ + +/* + * Unconditionall disable the jumps byte-code instruction dispatch + * method. + */ +/* #undef DISABLE_JUMPS */ + +/* Does the struct stat has st_blksize member? */ +#undef HAVE_STAT_ST_ST_BLKSIZE + +/* Does the struct stat has st_blocks member? */ +#undef HAVE_STAT_ST_ST_BLOCKS + +/* Does the asctime_r() function take three arguments. */ +/* #undef ASCTIME_R_WITH_THREE_ARGS */ + +/* Does the drand48_r() work with DRAND48D data. */ +/* #undef DRAND48_R_WITH_DRAND48D */ + +/* JS */ +#define WITH_JS 1 + +/* Curses. */ +/* #undef WITH_CURSES */ +/* #undef HAVE_CURSES_H */ +/* #undef HAVE_NCURSES_H */ + +/* MD5 */ +#define WITH_MD5 1 + +/* The number of bytes in a int. */ +#define SIZEOF_INT 4 + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 4 + +/* Define if you have the drand48 function. */ +#undef HAVE_DRAND48 + +/* Define if you have the lstat function. */ +#undef HAVE_LSTAT + +/* Define if you have the sleep function. */ +#define HAVE_SLEEP 1 + +/* Define if you have the srand48 function. */ +#undef HAVE_SRAND48 + +/* Define if you have the usleep function. */ +#define HAVE_USLEEP 1 + +/* Define if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define if you have the header file. */ +#define HAVE_FLOAT_H 1 + +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Include our portability header here. */ +#include "w32.h" diff --git a/reactos/lib/kjs/micros/makefile.os2 b/reactos/lib/kjs/micros/makefile.os2 new file mode 100644 index 00000000000..a4c4ba5d4b1 --- /dev/null +++ b/reactos/lib/kjs/micros/makefile.os2 @@ -0,0 +1,43 @@ + +LIBOBJS = b_array.obj b_bool.obj b_core.obj b_date.obj b_file.obj \ +b_math.obj b_number.obj b_regexp.obj b_string.obj b_system.obj \ +b_vm.obj bc.obj compiler.obj debug.obj getopt.obj getopt1.obj \ +heap.obj js.obj object.obj utils.obj mrgsort.obj vm.obj \ +vmjumps.obj vmswitch.obj xalloc.obj xjs.obj os2.obj + +# +# The mystic flags in the CFLAGS and LDFLAGS?: +# +# -Ml large memory model (yes, that's true) +# -F 3000 ??? +# -W3 warning level 3 +# -Zi generate debugging information +# /st:0x3000 set the stack size to 0x3000 +# + +CC = cl +CFLAGS = -Ml -F 3000 -W3 -Zi +DEFS = -DHAVE_CONFIG_H +LDFLAGS1= -F 3000 -Zi +LDFLAGS2= -link /noe /st:0x9000 + +prefix = ..\..\ngs + +all: js.exe + +js.exe: libjs.lib main.obj + $(CC) $(LDFLAGS1) -o $@ main.obj setargv.obj libjs.lib $(LDFLAGS2) + +libjs.lib: $(LIBOBJS) + -del libjs.lib + lib /p:32 libjs.lib $(LIBOBJS) ; + +install: js.exe + copy js.exe $(prefix)\bin + copy libjs.lib $(prefix)\lib + copy js.h $(prefix)\include + copy jsint.h $(prefix)\include + copy jsconfig.h $(prefix)\include + +.c.obj: + $(CC) $(CFLAGS) $(DEFS) -c $< diff --git a/reactos/lib/kjs/micros/makefile.w32 b/reactos/lib/kjs/micros/makefile.w32 new file mode 100644 index 00000000000..df1efb5ab6b --- /dev/null +++ b/reactos/lib/kjs/micros/makefile.w32 @@ -0,0 +1,50 @@ + +LIBOBJS = b_array.obj b_bool.obj b_core.obj b_date.obj b_file.obj \ +b_math.obj b_number.obj b_regexp.obj b_string.obj b_system.obj \ +b_vm.obj bc.obj compiler.obj debug.obj getopt.obj getopt1.obj \ +heap.obj js.obj object.obj utils.obj mrgsort.obj vm.obj \ +vmjumps.obj vmswitch.obj alloc.obj xjs.obj w32.obj \ +b_dir.obj b_func.obj b_object.obj crc32.obj dl_dummy.obj \ +iostream.obj regex.obj r_std.obj + +MOREOBJS = md5c.obj xmd5.obj + +# +# The mystic flags in the CFLAGS and LDFLAGS?: +# +# -Ml large memory model (yes, that's true) +# -F 3000 ??? +# -W3 warning level 3 +# -Zi generate debugging information +# /st:0x3000 set the stack size to 0x3000 +# + +CC = cl +CFLAGS = -F 3000 -W3 -Zi -I.. -I. -DWIN32 -nologo +DEFS = -DHAVE_CONFIG_H +LDFLAGS1= -F 3000 -Zi -nologo +LDFLAGS2= -link + +prefix = ..\..\ngs + +all: js.exe + +js.exe: libjs.lib main.obj $(MOREOBJS) + $(CC) $(LDFLAGS1) -o $@ main.obj setargv.obj $(MOREOBJS) libjs.lib $(LDFLAGS2) + +libjs.lib: $(LIBOBJS) + rm libjs.lib + lib -NOLOGO -OUT:"$@" $(LIBOBJS) ; + +install: js.exe + copy js.exe $(prefix)\bin + copy libjs.lib $(prefix)\lib + copy js.h $(prefix)\include + copy jsint.h $(prefix)\include + copy jsconfig.h $(prefix)\include + +%.obj: %.c + @$(CC) $(CFLAGS) $(DEFS) -c $< + +clean:: + rm -rf $(LIBOBJS) $(MOREOBJS) diff --git a/reactos/lib/kjs/micros/os2.c b/reactos/lib/kjs/micros/os2.c new file mode 100644 index 00000000000..99056f4d8f9 --- /dev/null +++ b/reactos/lib/kjs/micros/os2.c @@ -0,0 +1,55 @@ +/* + * OS/2 specific functions. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/micros/os2.c,v $ + * $Id: os2.c,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +#include "jsint.h" + +#include + +/* + * Global functions. + */ + +unsigned int +sleep (unsigned int seconds) +{ +#if 0 + DosSleep ((ULONG) seconds * 1000); +#endif + /* XXX Should count how many seconcs we actually slept and return it. */ + return 0; +} + +int +usleep (unsigned int useconds) +{ +#if 0 + DosSleep ((ULONG) useconds / 1000); +#endif + return 0; +} diff --git a/reactos/lib/kjs/micros/w32.c b/reactos/lib/kjs/micros/w32.c new file mode 100644 index 00000000000..00114ba21ba --- /dev/null +++ b/reactos/lib/kjs/micros/w32.c @@ -0,0 +1,150 @@ +/* + * W32 specific functions. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/micros/w32.c,v $ + * $Id: w32.c,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +#include + +#define WIN32_LEAN_AND_MEAN +#include + +/* + * Global functions. + */ + +unsigned int +sleep (unsigned int seconds) +{ + Sleep ((ULONG) seconds * 1000); + + /* XXX Should count how many seconcs we actually slept and return it. */ + return 0; +} + + +int +usleep (unsigned int useconds) +{ + Sleep (useconds); + return 0; +} + + +/* + * Directory handling. + */ + +DIR * +opendir (const char *name) +{ + DIR *dir; + + dir = calloc (1, sizeof (*dir)); + if (dir == NULL) + return NULL; + + dir->path = malloc (strlen (name) + 5); + if (dir->path == NULL) + { + free (dir); + return NULL; + } + sprintf (dir->path, "%s\\*.*", name); + + dir->handle = _findfirst (dir->path, &dir->finddata); + dir->pos = 0; + + return dir; +} + + +struct dirent * +readdir (DIR *dir) +{ + switch (dir->pos) + { + case 0: + dir->de.d_name = "."; + break; + + case 1: + dir->de.d_name = ".."; + break; + + case 2: + if (dir->handle < 0) + /* It was an empty directory. */ + return NULL; + + dir->de.d_name = dir->finddata.name; + break; + + default: + if (_findnext (dir->handle, &dir->finddata) < 0) + return NULL; + + dir->de.d_name = dir->finddata.name; + break; + } + + dir->pos++; + + return &dir->de; +} + + +int +closedir (DIR *dir) +{ + _findclose (dir->handle); + free (dir->path); + free (dir); + + return 0; +} + + +void +rewinddir (DIR *dir) +{ + _findclose (dir->handle); + + dir->pos = 0; + dir->handle = _findfirst (dir->path, &dir->finddata); +} + + +void +seekdir (DIR *dir, long offset) +{ +} + +long +telldir (DIR *dir) +{ + return -1; +} diff --git a/reactos/lib/kjs/micros/w32.h b/reactos/lib/kjs/micros/w32.h new file mode 100644 index 00000000000..70ff8014ecc --- /dev/null +++ b/reactos/lib/kjs/micros/w32.h @@ -0,0 +1,90 @@ +/* + * W32 specific definitions. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/micros/w32.h,v $ + * $Id: w32.h,v 1.1 2004/01/10 20:38:17 arty Exp $ + */ + +#ifndef W32_H +#define W32_H + +/* For chmod() & _find{first,next,close}(). */ +#include + +/* For alloca(). */ +#include + +/* For chdir(). */ +#include + +/* + * Types and definitions. + */ + +#define popen(cmd, mode) (NULL) +#define pclose(fp) (1) + +struct dirent +{ + char *d_name; +}; + +struct DIR_st +{ + char *path; + long handle; + + /* The position in the directory. */ + unsigned int pos; + + struct _finddata_t finddata; + struct dirent de; +}; + +typedef struct DIR_st DIR; + + +/* + * Prototypes for functions, defined in w32.c. + */ + +extern unsigned int sleep (unsigned int seconds); +extern unsigned int usleep (unsigned int useconds); + +/* Directory handling. */ + +DIR *opendir (const char *name); + +struct dirent *readdir (DIR *dir); + +int closedir (DIR *dir); + +void rewinddir (DIR *dir); + +void seekdir (DIR *dir, long offset); + +long telldir (DIR *dir); + +#endif /* not W32_H */ diff --git a/reactos/lib/kjs/projects/ChangeLog b/reactos/lib/kjs/projects/ChangeLog new file mode 100644 index 00000000000..fa3ea02b92b --- /dev/null +++ b/reactos/lib/kjs/projects/ChangeLog @@ -0,0 +1,4 @@ +1998-08-04 Markku Rossi + + * Create this directory to hold JS related work and contributions. + Added the initial project `binfmt_js'. diff --git a/reactos/lib/kjs/projects/Makefile b/reactos/lib/kjs/projects/Makefile new file mode 100644 index 00000000000..5fea4e163f1 --- /dev/null +++ b/reactos/lib/kjs/projects/Makefile @@ -0,0 +1,201 @@ +# Generated automatically from Makefile.in by configure. +# Makefile.in generated automatically by automake 1.3 from Makefile.am + +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Automakefile for the projects sub-directory. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + + +SHELL = /bin/sh + +srcdir = . +top_srcdir = .. +prefix = /usr/local/js-0.2.5 +exec_prefix = ${prefix} + +bindir = ${exec_prefix}/bin +sbindir = ${exec_prefix}/sbin +libexecdir = ${exec_prefix}/libexec +datadir = ${prefix}/share +sysconfdir = ${prefix}/etc +sharedstatedir = ${prefix}/com +localstatedir = ${prefix}/var +libdir = ${exec_prefix}/lib +infodir = ${prefix}/info +mandir = ${prefix}/man +includedir = ${prefix}/include +oldincludedir = /usr/include + +DISTDIR = + +pkgdatadir = $(datadir)/js +pkglibdir = $(libdir)/js +pkgincludedir = $(includedir)/js + +top_builddir = .. + +ACLOCAL = aclocal +AUTOCONF = autoconf +AUTOMAKE = automake +AUTOHEADER = autoheader + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} +transform = s,x,x, + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = i686-pc-linux-gnu +host_triplet = i686-pc-linux-gnu +ACLOCAL_FLAGS_FOR_LIBTOOL = +CC = gcc +CPP = gcc -E +EXTENSIONS = dl_open.lo xjs.lo xmd5.lo md5c.lo +EXTENSIONS_LIBS = -ldl +INTERPRETER_FEATURES = r_std.lo +LD = /usr/bin/ld +LIBTOOL = $(SHELL) $(top_builddir)/libtool +LN_S = ln -s +MAKEINFO = makeinfo +NM = /usr/bin/nm -B +PACKAGE = js +PGCC_BY_PROVENZANO = +RANLIB = ranlib +U = +VERSION = 0.2.5 +XLC_R_AIX = +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../jsconfig.h +CONFIG_CLEAN_FILES = +DIST_COMMON = ChangeLog Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP = --best +all: Makefile + +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps projects/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = projects + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done + $(MAKE) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook +info: +dvi: +check: all + $(MAKE) +installcheck: +install-exec: + @$(NORMAL_INSTALL) + +install-data: + @$(NORMAL_INSTALL) + +install: install-exec install-data all + @: + +uninstall: + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean: mostlyclean-generic + +clean: clean-generic mostlyclean + +distclean: distclean-generic clean + -rm -f config.status + -rm -f libtool + +maintainer-clean: maintainer-clean-generic distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +.PHONY: tags distdir info dvi installcheck install-exec install-data \ +install uninstall all installdirs mostlyclean-generic distclean-generic \ +clean-generic maintainer-clean-generic clean mostlyclean distclean \ +maintainer-clean + + +dist-hook: + mkdir $(distdir)/binfmt_js + cp -p $(srcdir)/binfmt_js/Makefile \ + $(srcdir)/binfmt_js/README \ + $(srcdir)/binfmt_js/binfmt_js.c \ + $(distdir)/binfmt_js + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/reactos/lib/kjs/projects/Makefile.am b/reactos/lib/kjs/projects/Makefile.am new file mode 100644 index 00000000000..f7566f8a7f0 --- /dev/null +++ b/reactos/lib/kjs/projects/Makefile.am @@ -0,0 +1,30 @@ +# +# Automakefile for the projects sub-directory. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + +dist-hook: + mkdir $(distdir)/binfmt_js + cp -p $(srcdir)/binfmt_js/Makefile \ + $(srcdir)/binfmt_js/README \ + $(srcdir)/binfmt_js/binfmt_js.c \ + $(distdir)/binfmt_js diff --git a/reactos/lib/kjs/projects/Makefile.in b/reactos/lib/kjs/projects/Makefile.in new file mode 100644 index 00000000000..5c77f7b2010 --- /dev/null +++ b/reactos/lib/kjs/projects/Makefile.in @@ -0,0 +1,201 @@ +# Makefile.in generated automatically by automake 1.3 from Makefile.am + +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Automakefile for the projects sub-directory. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + + +SHELL = /bin/sh + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DISTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_FLAGS_FOR_LIBTOOL = @ACLOCAL_FLAGS_FOR_LIBTOOL@ +CC = @CC@ +CPP = @CPP@ +EXTENSIONS = @EXTENSIONS@ +EXTENSIONS_LIBS = @EXTENSIONS_LIBS@ +INTERPRETER_FEATURES = @INTERPRETER_FEATURES@ +LD = @LD@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +NM = @NM@ +PACKAGE = @PACKAGE@ +PGCC_BY_PROVENZANO = @PGCC_BY_PROVENZANO@ +RANLIB = @RANLIB@ +U = @U@ +VERSION = @VERSION@ +XLC_R_AIX = @XLC_R_AIX@ +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../jsconfig.h +CONFIG_CLEAN_FILES = +DIST_COMMON = ChangeLog Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP = --best +all: Makefile + +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps projects/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = projects + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done + $(MAKE) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook +info: +dvi: +check: all + $(MAKE) +installcheck: +install-exec: + @$(NORMAL_INSTALL) + +install-data: + @$(NORMAL_INSTALL) + +install: install-exec install-data all + @: + +uninstall: + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean: mostlyclean-generic + +clean: clean-generic mostlyclean + +distclean: distclean-generic clean + -rm -f config.status + -rm -f libtool + +maintainer-clean: maintainer-clean-generic distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +.PHONY: tags distdir info dvi installcheck install-exec install-data \ +install uninstall all installdirs mostlyclean-generic distclean-generic \ +clean-generic maintainer-clean-generic clean mostlyclean distclean \ +maintainer-clean + + +dist-hook: + mkdir $(distdir)/binfmt_js + cp -p $(srcdir)/binfmt_js/Makefile \ + $(srcdir)/binfmt_js/README \ + $(srcdir)/binfmt_js/binfmt_js.c \ + $(distdir)/binfmt_js + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/reactos/lib/kjs/src/ChangeLog b/reactos/lib/kjs/src/ChangeLog new file mode 100644 index 00000000000..b71cbac375c --- /dev/null +++ b/reactos/lib/kjs/src/ChangeLog @@ -0,0 +1,1183 @@ +1999-01-19 Markku Rossi + + * jsint.h (struct js_vm_st): Implemented file descriptor limit. + Now you can specify the maximum amount of file descriptors the + interpreter can allocate. Thanks to Indrek Mandre + . + +1999-01-11 Markku Rossi + + * b_string.c (method): Fixed the append() method to accept also + integer arguments. + +1999-01-08 Markku Rossi + + * js.c (iofunc_close): Fixed a memory leak by freeing the + context. + +1998-11-25 Markku Rossi + + * js.c (js_create_interp): Added a sanity check to assure that the + js.h and jsint.h APIs share a common view about the node size. + + * js.h (struct js_type_st): Changed the JSType to be compatible + with the internal JSNode. + + * operands.def: Changed the with-chain to use a JSUIntAlign count + instead of a JSUInt32 count. + + * jsint.h: New integer type JSUIntAlign that can be used to align + structures on correct byte boundaries. + (struct js_heap_memory_block_st): Changed to use JSUIntAlign + integers instead of JSUInt32s. Now the memory allocation seems to + work on Alpha machines. + +1998-10-26 Markku Rossi + + * vmswt0.c (js_vm_switch0_exec): Added support for anonymous + functions. + + * vmswitch.c (js_vm_switch_exec): Added support for anonymous + functions. + + * vmjumps.c (js_vm_jumps_exec): Added support for anonymous + functions. + + * vm.c (js_vm_execute): Added support for anonymous functions. + + * jsint.h: Added argument `anonymous_function_offset' to + JSVMExecute. All uses changed. + + * operands.def: Tagged all symbol and jump operands with + comments. Now these operands can be handled automatically. + New operands `load_global_w' and `jsr_w'. + Added support for function pointers. + + * js.c (js_create_interp): Pass the `options.warn_undef' to the + virtual machine. + + * jsint.h (JS_OPERAND_CMP_EQ): Fixed to handle the `object _OP_ + string / number' cases. Now the == and != is ECMA compatible. + (JS_IS_PRIMITIVE_VALUE): New macro to check whether the argument + is a primitive value or not. + + * utils.c (js_vm_to_primitive): Implement ToPrimitive() type + conversion. + +1998-10-20 Markku Rossi + + * js.c (js_global_method_delete): New function to delete the user + defined global method from the memory. + + * jsint.h (JS_SUBROUTINE_CALL): Fixed to check that we have + enought stack space for yet another subroutine call. The same + thing is also checked in the `locals' operand, but some functions + don't use any local variables, and therefore, the stack usage + wasn't ever checked. + + * operands.def: Fixed `locals' to use the + JS_RESERVE_STACK_FOR_FUNCTION preprocessor constant. + +1998-10-16 Markku Rossi + + * jsint.h (JS_IS_FINITE): New macro to determine whether a number + node is a finite number. + + * b_date.c: Implemented MakeTime(), MakeDay(), MakeDate(), and + TimeClip() operators. + Implemented the global method invocation of the Date() + constructor. + + * b_regexp.c (new_proc): Fixed to work with 0 arguments. + +1998-10-12 Markku Rossi + + * operands.def: Cleaned up namespace by fixing load_property's + goto labels. + Fixed call_method to lookup the methods also from the prototypes + of string, array, and func built-in objects. + +1998-10-07 Markku Rossi + + * heap.c: Optimized the heap memory consumption by fixing the + block headers and the freelist block handling. The total savings + in the memory usage (with the js_vm_make_function() fix) are about + 15 %. + + * jsint.h (js_vm_make_function): Fixed a typo that caused us to + allocate one JSVirtualMachine for each function, instead of one + JSFunction. + (struct js_heap_memory_block_st): Optimized the header from 12 + bytes to 4 (on 32bit machines). + (struct js_heap_freelist_block_st): Header for the memory block + when it is on the freelist. + +1998-10-05 Markku Rossi + + * operands.def: ECMA compliancy fixes for the `mod' operand. + +1998-10-02 Markku Rossi + + * main.c: New option -E, --events to print the interpreter + events. + + * js.h (struct js_interp_options_st): Added event hooks. + + * vmjumps.c: Implemented byte-code execution hooks. + + * jsint.h: Implemented event hooks for garbage collection and + byte-code operand execution. + + * b_regexp.c: Implemented the `The RegExp Constructor Called as a + Function'. + ECMAScript compliance fixes for the method argument checks. + +1998-10-01 Markku Rossi + + * utils.c (js_vm_to_string): Fixed to work with native Objects. + + * vm.c (js_vm_call_method): Fixed to call the built-in Object's + method proc, if the property hasn't bee defined in the native + object instance. + + * jsint.h: Added some consts to function arguments. + + * b_object.c (method): Implemented toString() method. + + * alloc.c (js_strdup_i): Added const to the dupped string + argument. + + * operands.def: Fixed the operand `call_method' to call the method + from the object's constructor, if the object hasn't redefined the + called method. + + * regex.c: Updated regex.{c,h} files from the glibc-2.0.96. Added + some re-entrancy fixed to regex.c. + +1998-09-29 Markku Rossi + + * b_dir.c: New built-in object `Directory' to handle directories. + + * md5.h: Keep the namespace clean! Defined MD5_CTX to + _JS_MD5_CTX. + +1998-09-25 Markku Rossi + + * b_core.c (print_global_method): New global method `print()' to + print its arguments to system's standard output stream. + + * js.h (struct js_interp_options_st): New security options + `secure_builtin_{file,system}'. + + * main.c: New option -r, --secure to turn on security options. + +1998-09-24 Markku Rossi + + * heap.c (BLOCK_SIZE): Changed to 200 * 1024 bytes on 32 bit and + bigger systems. + (js_vm_alloc): Fixed the `alloc_size' calculation for cases when + it is bigger than BLOCK_SIZE. Now we can re-use those bigger + blocks more efficiently. + +1998-09-22 Markku Rossi + + * js.c (js_create_interp): Added debug call for + js_alloc_dump_blocks() to find out how much memory one interpreter + takes. Maybe the heap.c:BLOCK_SIZE should be an option in the + JSInterpOptions. + +1998-09-21 Markku Rossi + + * b_regexp.c (js_builtin_RegExp): Removed the re_set_syntax() + call, since the correct default is already present in the regex.c. + + * regex.c: Initialized the default syntax to RE_SYNTAX_GNU_AWK. + This removes the re-entrancy problem from b_regexp.c. + + * operands.def: ECMA compliancy fixes for the `and', `or', `xor', + `shift_left', `shift_right', and `shift_rright' operands. + + * jsint.h (JS_OPERAND_BINARY): New macro to implement binary and, + or, and xor operands. + +1998-09-17 Markku Rossi + + * vmswitch.c (link_code): Fixed to handle the debugging + information. + + * operands.def: Fixed operand `throw' to convert the thrown value + to an error when the exception is thrown to the top-level. + +1998-09-15 Markku Rossi + + * operands.def: ECMA compliancy fixes for the `mul', `div', and + `neg' operands. + +1998-09-10 Markku Rossi + + * js.c (js_eval_source): When evaluating the on-demand-compiler + source files, warn only about `with-clobber' cases. + + * operands.def: Made the cmp_{eq,ne}, sub, and add byte-code + operands ECMAScript compatible. + Implemented cmp_{seq,sne} operands. + New operand `const_i' to push a Int32 integer to the stack. + +1998-09-09 Markku Rossi + + * jsint.h (JS_IS_NUMBER): New macro to determine whether a node is + a number or not. + +1998-09-08 Markku Rossi + + * b_math.c (method): Fixed max() and min() to allow multiple + arguments. + Made ECMAScript compatible. + + * utils.c (js_vm_to_boolean): New function to perform the + `ToBoolean()' type conversion. + + * b_bool.c (method): Implemented the `valueOf' method. + Implemented global function invocation `Boolean()'. + + * b_string.c (method): Implemented the `valueOf()' method. + Implemented global function invocation `String()'. + Made the `new' invocation ECMAScript compatible. + (method): Fixed concat() to accept any number of arguments. + + * b_array.c: Implemented global function invocation `Array()'. + Fixed some argument checks. + + * b_object.c: Implemented some ECMAScript features. Some things + are still unimplemented. + + * utils.c (js_vm_to_object): New function to perform the + `ToObject()' type conversion. + + * jsint.h (struct js_vm_st): New symbol s_toSource. + + * utils.c (js_vm_to_int32): New function to perform the + `ToInt32()' type conversion. + + * jsint.h: Created new macros + JS_MAKE_{POSITIVE,NEGATIVE}_INFINITY(), + JS_IS_{POSITIVE,NEGATIVE}_INFINITY() to handle infinity values. + + * js.c: Moved the error() global method to b_core.c. + + * b_core.c: Made ECMAScript compatible. + +1998-09-07 Markku Rossi + + * jsint.h (JS_OPERAND_CMP): New macro to implement relational + comparison. + + * main.c: New compiler option `-Wdeprecated'. + + * operands.def: Added the missing line break sequence to the end + of the warning from the load_global operand. + Made the load_array's error messages more verbose. + Re-implemented the cmp_{lt,gt,le,ge} operands. + Re-implemented the add operand. + Re-implemented the div operand. + Added a missing JS_POP() to mul operand's one argument + combination. + New operand load_nth_arg. + + * b_core.c: Cleaned up the error messages. + (parseInt_global_method): Made ECMAScript compatible. + +1998-09-04 Markku Rossi + + * operands.def: New operands `cmp_seq' and `cmp_sne' for strict + equals and does-not-equal comparisons. + + * js.h: New API function js_lookup_class() to lookup the class + handle by its name. + New API function js_isa() to check whether an object is an + instance of a given class. + +1998-09-02 Markku Rossi + + * js.h: New API function js_version() that returns the interpreter + version number as a string of format "MAJOR.MINOR.PATCH". + +1998-09-01 Markku Rossi + + * b_system.c: Removed the flush method. + + * b_file.c (method): Fixed the read() method to always return a + string. + +1998-08-26 Markku Rossi + + * iostream.c (js_iostream_file): Added argument that + specifies whether the actual `FILE *' file pointer will be closed + when the stream is destroyed. Normally, we don't want to close + stdin, stdout, or stderr when the interpreter is destoyed. + +1998-08-25 Markku Rossi + + * js.h: New API function js_apply() to apply function to + arguments. + + * vm.c (js_vm_apply): Fixed to work also with built-in functions. + + * jsint.h: Removed the argument from the JSVMExecute + function type. All uses changed. + +1998-08-24 Markku Rossi + + * js.h: Keep the namespace clean! Renamed DLLEXPORT to + JS_DLLEXPORT. + New API functions: js_result(), js_{get,set}_options(), and + js_instantiate_class(). + +1998-08-21 Markku Rossi + + * jsint.h: Keep the namespace clean! Renamed + HOST_LINE_BREAK_SEQUENCE{,_LEN} to JS_HOST_LINE_BREAK{,_LEN}. + + * js.h: W32 portability fixes. Now the header should co-operate + with Borland's and MS compilers. + Added support for user-defined classes. + +1998-08-20 Markku Rossi + + * b_vm.c (property): New property verboseStacktrace. + + * jsint.h (struct js_vm_st): New flag `verbose_stacktrace'. + + * operands.def: Added a new slot to the stack frame: args_fix. + The args_fix holds the relocation information from the `min_args' + operand. The operand `return' needs that information when it is + returning from a function that was called with too few arguments. + All uses of STACKFRAME were changed. + +1998-08-19 Markku Rossi + + * b_system.c (property): New property `lineBreakSequence'. The + value of the property is a string that is the line break sequence + on the underlying system. + + * jsint.h: Added portability defines for the line break sequence. + + * b_file.c (property): New instance properties `autoFlush' and + `bufferSize'. + (method): Fixed writeln() to use the host dependent line break + sequence. The sequence is defined in jsint.h. + + * jsint.h: Re-implemented all I/O stuffs to use JSIOStream + interface. All uses of the old `FILE *' interface, including the + stdin, stdout, and stderr streams, are changed. + +1998-08-18 Markku Rossi + + * js.c (call_method_global_method): New global method to call + methods from objects with a given array of arguments. + + * vm.c (js_vm_call_method): New function to call method from an + object. + + * jsint.h: New function js_vm_call_method() to call a method from + an object. + Changed the exec functions of different dispatchers to accept one + extra parameter: the object that should be used as the `this' + object. + +1998-08-17 Markku Rossi + + * js.h: Added DllExport's to all public API functions. These must + be exported explicitly on w32. + + * b_file.c (method): Ported to w32. The member + struct_st.st_blksize is not present there. + + * b_array.c (new_proc): Added support for array initializers which + pass the number of arguments as negative integers. + +1998-08-14 Markku Rossi + + * operands.def: Fixed operand `call_method' to call JS_MAYBE_GC() + also for the language primitives. This fixes a memory leak. + + * vm.c (js_vm_execute): Added support for regular expression + constants. + + * b_regexp.c (js_builtin_RegExp_new): New global function to + create built-in regular expression objects. + (struct regexp_instance_ctx_st): Added flags `immutable'. + + * b_string.c (method): Implemented 'd' modifier for the unpack() + method. + +1998-08-13 Markku Rossi + + * main.c: New compiler option `-Wstrict-ecma'. + + * b_vm.c (property): The property `verbose' can have different + values, not just 0 or 1. Fixed. + +1998-08-12 Markku Rossi + + * main.c: New compiler option -Wmissing-semicolon to warn about + missing semicolons that are fixed by the automatic semicolon + inserting during the compilation. + New warning level -Wpedantic. + + * jsint.h: Renamed js_intern() to js_intern_with_len(). + Implemented inline function js_intern() that counts the length and + passes it to js_intern_with_len(). + New macro JS_POP_N() to pop n elements from the stack. This + should remove all direct sp modifications from the operands.def + file. + + * operands.def: Fixed load_array and store_array to work with + built-in objects with string array indexes. + + * jsint.h (js_string_to_c_string): Made the argument node const. + (JS_IS_STR_WHITE_SPACE_CHAR): Macro to match StrWhiteSpaceChars. + + * utils.c (js_vm_to_number): Convert any JSNode to its Number + presentation. This implementes the ToNumber() type conversion. + + * jsint.h (struct js_vm_st): Added symbol `valueOf'. + + * Renamed all `delete' delete procs to `delete_proc'. + + * b_number.c (global_method): Implemented global method use of the + Number object. + (method): Implemented radix 2 for the `toString()' method. + (method): Implemented method `valueOf()'. + (new_proc): Implemented new proc. + +1998-08-11 Markku Rossi + + * js.h: Added C++'s extern C defs around the header. + + * jsint.h: Added C++'s extern C defs around the header. + +1998-08-10 Markku Rossi + + * jsint.h (struct js_vm_st): Removed variable `exec_result_sp' + since it didn't contain accurate information. The needed values + can be fetched through vm->sp after the apply. + +1998-08-07 Markku Rossi + + * jsint.h (struct js_vm_st): Added variable `exec_result_sp' that + can be used to fetch the valeus of the by-reference arguments. + +1998-08-05 Markku Rossi + + * js.h: New API functions: js_compile_to_byte_code(), + js_compile_data_to_byte_code(), and js_execute_byte_code(). + + * main.c: New option -x, --executable to create executable + byte-code files. + + * js.h (struct js_interp_options_st): New option + `generate_executable_bc_files'. + + * b_file.c (method): New static method chmod() to change + permissions of a file. + +1998-08-04 Markku Rossi + + * dl_dummy.c: Dummy stubs for the dynamic loading functions for + environments which do not support dynamic loading. + + * dl_open.c: Implement dynamic loading with dl{close,open,sym}() + functions. + + * js.c (load_class_global_method): New global method loadClass() + that extend the interpreter by calling extension entry functions + from shared libraries. + +1998-07-30 Markku Rossi + + * operands.def: Fixed a reference bug from operand nth. + +1998-07-07 Markku Rossi + + * b_core.c: New global methods escape() and unescape(). Thanks to + Roger E Critchlow Jr . + + * Changed license to GNU Library General Public License (LGPL). + +1998-06-26 Markku Rossi + + * make-jumps.pl: Changed to generate `OPERAND(op)' statements for + each operand in ejumps.h. These stmts are needed for the + byte-code operand profiling. + + * jsint.h (struct js_vm_st): Added support for byte-code operand + profiling. This is a debugging tool to profile the performance of + individual byte-code operands. It is not intended to be used in + production interpreters. + +1998-06-25 Markku Rossi + + * make-data.c (main): Changed to create also a pre-processor + definition for the data length. It is the same as the data length + variable name, but in upper case. + + * b_regexp.c (EMIT_TO_RESULT): Fixed a typo where the result of + the realloc() wasn't assigned to the reallocated pointer. + +1998-06-09 Markku Rossi + + * operands.def (halt): Changed to sleep forever instead of exiting + the process. + (roll): Fixed the negative roll value. + + * vmswitch.c (struct function_st): Changed the name to be + dynamically allocated. + (execute_code): Save the executed function to the stack. This + protects it against the gc. + (js_vm_switch_func_name): Fixed to lookup the function name also + from the stack. + + * vmswt0.c (struct function_st): Changed the name to be + dynamically allocated. + (execute_code): Save the executed function to the stack. This + protects it against the gc. + (js_vm_switch0_func_name): Fixed to lookup the function name also + from the stack. + + * vmjumps.c (struct function_st): Changed the name to be + dynamically allocated. + (js_vm_jumps_exec): Save the executed function to the stack. + There it is protected against garbage collections and it won't be + collected while we are executing its code. + (js_vm_jumps_func_name): Fixed to lookup the function name also + from the stack. + (js_vm_jumps_debug_position): Fixed to lookup the function also + from the stack. Now we find the `.global' code and we can fetch + the debugging information for it. + + * heap.c (js_vm_garbage_collect): Changed the way how the stack is + marked. Now we do not follow the frame pointers, but we use brute + force and process whole active stack. + + * debug.c (js_vm_stacktrace): Cleaned up the stacktrace output. + Now the function parenthesis () are not printed after `.global'. + +1998-06-08 Markku Rossi + + * operands.def: Added support for the prototype properties of + built-in objects. + + * jsint.h (struct js_builtin_st): Added the prototype property. + (struct js_builtin_info_st): Added the prototype property. + (struct js_string_st): Added the prototype property. + (struct js_array_st): Added the prototype property. + Added `JS_' prefixes to the property attribute values. + + * operands.def: Changed the way how the primitive language objects + are called. + Replaced all by-hand subroutine calls with JS_SUBROUTINE_CALL() + macro. + Removed operands `assert_args', `assert_min_args', and + `assert_max_args'. + Added operands `min_args', `add_1_i', and `add_2_i'. + + * object.c (js_vm_object_load_property): Changed the prototype + property to be always linked through the `__proto__' property. + + * b_func.c (property): Made the `prototype' property mutable. + + * js.h (struct js_interp_options_st): Removed option + argument_count_checks. + + * jsint.h: Added macro JS_SUBROUTINE_CALL() to handle the + subroutine call stack frame creation. All uses changed. + Cleaned up JSNode types. + Changed JSVirtualMachine's primitive object infos to be in an + array that is indexed with the object type. This cleans up the + source noticeably. + Removed flag JSC_FLAG_ARGUMENT_COUNT_CHECKS. All uses changed. + +1998-06-07 Markku Rossi + + * jsint.h: Implemented the prototype property of object. Changed + all uses of the object built-in to use it. + Added the prototype property to functions. + + * b_object.c: New built-in object for the object primitive type. + + * b_func.c: New built-in object for the function primitive type. + +1998-06-05 Markku Rossi + + * operands.def: Implemented mod operand. + Reorganized the operand opcodes. + +1998-06-04 Markku Rossi + + * heap.c: Optimized the heap performance. Now the vm has separate + freelists for each block size. This allows us to put each freed + heap block to the freelist, and therefore, we need much less + memory from the system. + + * jsint.h (struct js_vm_st): Added separate freelists for each + heap block size. + + * vm.c (js_vm_intern): Changed the hash function to + js_count_hash() that creates much evenly distributed hash values. + +1998-06-03 Markku Rossi + + * r_pthrs.c: Implemented an alternative method to count random + numbers. The new method assumes that the drand48() function is + thread-safe. + + * rentrant.h: Added buffer_length argument to the js_asctime() + function. All uses and implementations changed. + +1998-06-02 Markku Rossi + + * rentrant.h: Added vm argument to the js_drand48_create() + function. All uses and implementations changed. + + * make-data.c (main): Changed to take third (first) argument that + specifies the data name. + + * heap.c (js_vm_alloc_destroyable): Changed to return zeroed + memory. + +1998-06-01 Markku Rossi + + * js.h: New function js_define_module() to initialize an extension + module to the interpreter. + + * vm.c (js_vm_destroy): Fixed to destroy everything we allocate + during the initialization and the evaluations. Now there + shouldn't be any memory leaks. + + * js.h: Moved all extension to be public at the js.h API. Now the + interpreter do not initialize any extensions; you have to do it + explictly. + + * heap.c (js_vm_clear_heap): New function to delete all + built-ins, etc. from the heap. This is called from the + js_vm_destroy() to remove everything dynamically allocated from + the heap. + + * b_file.c (struct file_instance_ctx_st): Added flag dont_close to + indicate that the file shouldn't be closed on delete. This is + useful for the system's standard streams. + + * jsint.h (struct js_heap_destroyable_st): Changed the way how the + built-in objects are handled. In the older versions, the + built-ins were allocated with the js_vm_alloc_buitin() function. + Now the function has been renamed to js_vm_alloc_destroyable() + that allocates memory that has a callback function that will be + called, when the garbage collector reclaims the storage. This is + more general way to handle the delete operand in the memory + blocks. The same method are now used also for JSBuiltinInfo, + JSBuiltin, and for the Function closures. + Implemented memory leak checks. Now the memory leaks can be found + easily. Just turn the JS_DEBUG_MEMORY_LEAKS to 1 in the jsint.h + file and dump the leaks after the interpreter has been deleted. + +1998-05-29 Markku Rossi + + * jsint.h: Major reorganization in the memory management. The + interpreter does no longer use the xalloc() semantics, but it will + return an error message to the caller, if the memory were + exhausted. This change affects functions + js_{malloc,calloc,realloc,strdup}() and js_string_to_c_string(). + All uses of these functions were changed. + +1998-05-28 Markku Rossi + + * b_file.c: Removed the historical stdin, stdout, and stderr + references. + + * js.h (struct js_interp_options_st): Added options s_stdin, + s_stdout, and s_stderr. These can be used to redirect the System + builtin's idea about the default streams. All uses of globals + stdin, stdout, and stderr were redirected to these streams. + + * heap.c (js_vm_garbage_collect): Fixed a bug from with-chain + marking. + + * jsint.h: Massive namespace cleanup. All functions, types, and + preprocessor constants have now an appropriate `js' prefix. All + uses changed. + +1998-05-27 Markku Rossi + + * jsint.h: Namespace cleanups for the different integer types. + Added `JS' prefix to types `{U,}Int{8,16,32}'. All uses changed. + + * js.1: Documented the command line options. + +1998-05-26 Markku Rossi + + * xalloc.c: Renamed functions x{malloc,calloc,realloc,free,strdup} + to js_{malloc,calloc,realloc,free,strdup}. All prototypes and + calls changed. + +1998-05-22 Markku Rossi + + * main.c (create_interp): Fixed to pass the `warn_with_clobber' + option to the interpreter. + + * b_date.c (new_proc): Implemented constructors with three and six + arguments. + +1998-05-20 Markku Rossi + + * js.h: Added new API function js_create_global_method() to + implement the user-defined global methods. + + * js.c (js_create_global_method): New API function to implement + user-defined global methods. + + * b_vm.c (method): Fixed the method stackTrace() to pass the limit + argument to the js_vm_stacktrace(). + + * debug.c (js_vm_stacktrace): Added argument `num_frames' to + specify how many stack frames the function should print. + +1998-05-19 Markku Rossi + + * b_md5.c (method): Fixed an off-by-one bug from the final() + method. + + * b_math.c (method): Removed the clock seed setting from the + random() method. + Implemented new method seed() to set the random seed. + +1998-05-18 Markku Rossi + + * b_array.c (method): Set the default result type to be + `undefined'. + +1998-05-15 Markku Rossi + + * jsint.h (struct error_handler_frame_st): Added item `thrown' for + the thrown value. + + * operands.def: Implemented operand throw. + + * vm.c (js_vm_error): When jumping to a catch-block, format the + error message to the vm->error_handler->thrown as a JS string. + +1998-05-14 Markku Rossi + + * operands.def: Implemented operands try_push and try_pop. + + * jsint.h (struct error_handler_frame_st): Added slots for the + try_push operands saved state. + +1998-05-13 Markku Rossi + + * xjs.c (method): Implemented getVar() and setVar() methods. + + * jsint.h: Added prototype for the js_crc32() function. + + * b_md5.c: New builtin object to count the MD5 message digests. + + * b_string.c (method): Implemented method crc32(). + + * b_math.c: Changed to use the rentrant.h API. + + * b_date.c: Changed to use the rentrant.h API. + + * r_std.c: Non-re-entrant versions of the re-entrant functions. + This uses the standard C-library. This shouldn't be used with + threads. + + * r_pthrs.c: Implement Re-entrant functions with Posix threads. + + * rentrant.h: New file to define functions that must be + re-implemented on different operating systems to assure that the + interpreter will be re-entrant. + + * b_date.c (method): Implemented format() and formatGMT() + methods. + + * object.c (js_vm_object_nth): Implemented. This is needed for + the byte-code operand `nth'. + + * jsint.h (struct object_st): Added to hold the + chain lengths of each hash slot. + +1998-05-12 Markku Rossi + + * main.c (long_options): Changed long option `--dispatch' to take + an argument. + + * operands.def: New operands: `roll' and `nth'. + Reorganized the operands. All old byte-code file must be + recompiled. + + * b_date.c: Implemented Date built-in object. + +1998-05-11 Markku Rossi + + * jsint.h (SYMBOL_NULL): New constant for nonexistent symbols. + + * operands.def (delete_property): New operand to delete a property + from an object. + (delete_array): New operand to delete an item from an array. + These two new operands implement the JavaScript `delete' + operator. + + * object.c (js_vm_object_delete_property): New function to delete + a property of an object through the standard object.property + interface. + (js_vm_object_delete_array): New function to delete a property of + an object through the array reference interface. + +1998-05-08 Markku Rossi + + * main.c: Fixed long option --file not to take an argument. The + arguments are handled after the getopt_long() has processed them. + + * js.c (js_eval_file): Added more knowledge to the file type + determination. If we can't determine the file type from the + file's suffix, the file is opened and searched for the magic + number of the JS byte-code file. + + * b_array.c (method): Changed the splice() method to return an + array containing the deleted items, or `undefined' if no items + were deleted. + +1998-05-07 Markku Rossi + + * b_regexp.c (js_builtin_RegExp_split): New function to preform + string split from the matched regexp boundaries. + (new_proc): Fixed a zero allocation bug when a regular expression + was created from an empty string. + + * b_string.c (method): Implemented split() method. + +1998-05-05 Markku Rossi + + * b_core.c: New global methods float() and int(). + +1998-04-23 Markku Rossi + + * b_string.c (method): Implemented slice() method. + + * xcurses.c (method): New method mvaddsubstr() to draw a substring + of a string. + + * b_string.c (method): Cleaned up argument handling for substr() + and substring() methods. + +1998-04-22 Markku Rossi + + * b_regexp.c (js_builtin_RegExp_match): New function to perform + regexp execution against a string. String.match() uses this. + (js_builtin_RegExp_search): New function to perform regexp + search against a string. String.search() uses this. + + * vm.c (intern_builtins): Changed the order in which the built-ins + are initialized. The RegExp object must be initialized before + String. + + * b_regexp.c (js_builtin_RegExp_replace): New function to perform + search-replace operation for a string. + + * b_string.c (method): Implemented replace(), match(), and + search() methods. + + * vm.c: Added `js_' prefix to all built-in global functions. + + * b_regexp.c (method): Changed the test() method to obey and + update the RegExp.lastIndex property. + +1998-04-21 Markku Rossi + + * vm.c (js_vm_apply): Changed to reset the vm->sp to the saved + value in every case, not just when an error occurred. Otherwise + the stack will eventually overflow. + (js_vm_execute): Likewise. + + * b_system.c (method): New method popen(). + (property): Added properties stderr, stdin, and stdout. + + * b_file.c (method): Major cleanup. Added some missing argument + checks. + (builtin_File_new): New function to enter files to the JS system. + (builtin_File): Moved File.stderr, File.stdin, and File.stdout to + the System built-in. + (method): New methods lstat() and stat(). + + * Removed all ToStringProcs from the built-in objects. The + toString() methods is now always implemented in the object's + method proc. + + * Major cleanup for all builtin-objects. Now the instance methods + actually check that there is an instance of the object available; + the instance methods can now longer be called statically. + + * b_string.c (method): Implemented indexOf() and lastIndexOf() + methods. + + * mrgsort.h (mergesort_r): Renamed re_mergesort() to + mergesort_r(). + +1998-04-20 Markku Rossi + + * b_regexp.c: Implemented RegExp built-in object. + +1998-04-16 Markku Rossi + + * mrgsort.h (re_mergesort): Renamed mergesort() to re_mergesort() + because mergesort() was already defined in The FreeBSD's stdlib.h. + + * vm.c (js_vm_execute): Added support for NaN constants. + + * main.c: New compiler option -Wwith-clobber. + + * js.c (js_compile): Added support for option + JSC_FLAG_WARN_WITH_CLOBBER. + + * b_string.c (builtin_String_method): Implemented modifier 'd' for + the pack() method. + + * b_core.c: Implemented global methods isFloat() and isInt(). + +1998-04-15 Markku Rossi + + * heap.c (js_vm_garbage_collect): Updated to mark the with-chains + from the stack. + + * operands.def: Implemented the with-chain. This affected + operands load_global, jsr, with_push, and with_pop. + + * jsint.h (WITHPTR): New macro to refer to the stack frame's with + pointer. + + * object.c (js_vm_object_load_property): Changed to return an + integer return value that specifies whether the property was + defined in the object or not. This is needed by the with + statement. + + * operands.def: Changed with_pop to take an Int8 argument to + specify the number of with-frames to pop. + +1998-04-14 Markku Rossi + + * vmjumps.c (js_vm_jumps_exec): Added a slot for the with chain to + the stack frame. + + * jsint.h: Removed #if HAVE_CONFIG_H from the inclusion of + jsconfig.h. We have it always. + + * b_array.c (method): Implemented splice() method. + +1998-04-03 Markku Rossi + + * mrgsort.c: New file that implements re-entrant, stable + mergesort. + + * utils.c (js_vm_to_string): Changed to generate static strings + when ever it is possible. + + * jsint.h: Changed JSVMExecute function type to allow applying + arguments to an anonymous function pointer. + + * b_array.c (method): Implemented sort() method. + + * vmswitch.c: Optimized to pre-compile the byte-code stream to + internal presentation. This gives some speedup. The old + non-compiled version is now called `switch-basic' and it can be + found from vmswt0.c. + + * debug.c (js_vm_stacktrace): Implemented JS_ARRAY type. + + * jsint.h: Cleaned up byte-code instruction dispatcher + interfaces. + + * js.c (js_create_interp): Added support for the new switch-basic + dispatch method. + + * b_vm.c (builtin_VM_property): Renamed property dispatchType to + dispatchMethod and changed its value to be string that gives the + name of the dispatchmethod. + + * js.h: Added new bc instruction dispatch method switch-basic. + +1998-04-01 Markku Rossi + + * object.c (js_vm_object_mark): Tail-recursive optimization for + linked list properties. This saves the gc-mark stack usage + noticeably. + + * heap.c (js_vm_is_marked_ptr): New function to determine whether + the pointer is marked or not. + +1998-03-31 Markku Rossi + + * b_file.c (builtin_File_method): Changed the open() method to add + the 'b' flag to the fopen mode. + + * js.c (js_execute_byte_code_file): Added 'b' to the fopen mode. + + * Ported to OS/2 1.3. It is a 16 bit system. + + * heap.c: Cleaned up the heap allocation. + + * bc.c (js_bc_read_data): Fixed all 16 / 32 bit issues. + + * main.c: Implemented `--no-compiler' option to disable compiler + from the interpreter. This option makes the interpreter a pure + virtual machine that can only execute byte-code files. + + * b_system.c (builtin_System_property): New property `bits' to + tell the "bits" of the underlying processor (16, 32, 64). + (builtin_System_method): Implement sleep() and usleep() methods + only if the system supports them. + + * b_string.c (builtin_String_method): Fixed pack() and unpack() + methods to work in 16 bit environments. + + * b_math.c: Defined some double constants which can be used if the + system headers do not define them. + (method): Implemented an alternative method to count random + numbers. + + * b_file.c (builtin_File_method): Fixed a typo from the return + value check of fread(). + Included sys/types.h. + + * heap.c (BLOCK_SIZE): Changed the default block size to depend on + the underlying machine (16 / 32 bit). + + * jsint.h: Defined integer types: UInt8, Int8, UInt16, Int16, + UInt32, Int32. + Changed unistd.h to be included only if it is detected by the + configure script. + Included limits.h. + (struct js_vm_st): Changed garbage collection variables to be 32 + bit integers, instead of using unsigned int. + (struct symtab_entry_st): Changed symtab entry's name to be + dynamically allocated. This saves noticeably memory. + Renamed option JSC_FLAG_OPTIMIZE_JUMPS_TO_JUMPS to + JSC_FLAG_OPTIMIZE_JUMPS. + + * vm.c (js_vm_execute): Changed symtab entry's symbol names to be + dynamically allocated. + (js_vm_execute): Removed uses of __FUNCTION__ macros. + +1998-03-30 Markku Rossi + + * main.c (usage): Fixed some compiler warnings. + + * object.c: Fixed some compiler warnings. + + * vm_jumps2.c: Added support for non-gcc environments. + + * vm.c (js_vm_create): Added support for non-gcc environments. + +1998-03-27 Markku Rossi + + * bi_array.c (method): Implemented toString() and join() methods. + (method): Implemented slice() method. + + * utils.c (js_vm_to_string): New function to convert any node to + string. This function is used in all places where a string + presentation of a value is needed. + +1998-03-26 Markku Rossi + + * bi_array.c (method): Implemented reverse() and shift() methods. + + * jsint.h: Changed the definition of truthness and falseness of a + node. Now also integer 0 is false. + + * bi_math.c: Implemented the Math core object. + + * operands.def: Implemented type conversions to operands add, sub, + div and mul. + + * bi_boolean.c: Finished the Boolean core object. + +1998-03-25 Markku Rossi + + * jsint.h: Implemented array core type. + Cleaned up the internal namespace. Now all virtual machine + functions start with prefix `js_vm_'. + + * main.c: Changed the default optimization level to 1. + (main): Pass all arguments (and the name of the script) to the + script through ARGS array. + + * js.h: Implemented public interface to JavaScript's types. + Implemented functions to create string and array types. + Implemented functions to set and get values of global variables. + + * bi_system.c (builtin_System_method): Implemented chdir() and + getcwd() methods. + +1998-03-24 Markku Rossi + + * xcurses.c: Curses extension. It is still under construction. + + * main.c: Changed the default optimization level to be 1 (no heavy + optimizations). + +1998-03-19 Markku Rossi + + * bi_string.c (builtin_String_method): Implemented toLowerCase() + and toUpperCase() methods. + +1998-03-17 Markku Rossi + + * bi_system.c: Implemented canonical host properties: + canonicalHost, canonicalHostCPU, canonicalHostVendor, + canonicalHostOS. + + * bi_vm.c: Implemented version properties: version, versionMajor, + versionMinor, versionPatch. + +1998-03-10 Markku Rossi + + * bi_number.c (builtin_Number_property): Implemented properties. + +1998-03-06 Markku Rossi + + * bi_number.c (builtin_Number_method): Added radix argument to the + toString() method. + + * bi_core.c: New file to implement the virtual machine level + global methods. + + * operands.def: Added some missing SAVE_REGS() calls. + + * defs.h (JSType): New type JS_NAN for NaN numbers. Changed all + places where node types are checked. + + * bi_string.c (builtin_String_method): Implemented methods concat, + fromCharCode, substr and substring. Changed the missing methods + to raise an error. + +1998-03-05 Markku Rossi + + * vm.c (js_vm_builtin_create): New function to create builtin + objects. + + * heap.c (js_vm_alloc_builtin): New function to allocate tagged + memory for the builtin objects. + (js_vm_garbage_collect): Changed to call the possible user-defined + destructor for each collected builtin node. + + * defs.h: Defined macros IS_TRUE() and IS_FALSE() to determine the + trueness and falseness of a node. + Changed all Builtin procs to take BuiltinInfo argument instead of + the object context. + (js_string_to_c_string): New function to convert JS string to a + C-string. + + * vm_jumps2.c (js_vm_exec_jumps2): Optimized the debug info + handling. + + * bi_system.c: New methods: flush, getenv, sleep, system and + usleep. diff --git a/reactos/lib/kjs/src/Makefile b/reactos/lib/kjs/src/Makefile new file mode 100644 index 00000000000..1d83f953e29 --- /dev/null +++ b/reactos/lib/kjs/src/Makefile @@ -0,0 +1,542 @@ +# Generated automatically from Makefile.in by configure. +# Makefile.in generated automatically by automake 1.3 from Makefile.am + +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Automakefile for JavaScript virtual machine. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + + +SHELL = /bin/sh + +srcdir = . +top_srcdir = .. +prefix = /usr/local/js-0.2.5 +exec_prefix = ${prefix} + +bindir = ${exec_prefix}/bin +sbindir = ${exec_prefix}/sbin +libexecdir = ${exec_prefix}/libexec +datadir = ${prefix}/share +sysconfdir = ${prefix}/etc +sharedstatedir = ${prefix}/com +localstatedir = ${prefix}/var +libdir = ${exec_prefix}/lib +infodir = ${prefix}/info +mandir = ${prefix}/man +includedir = ${prefix}/include +oldincludedir = /usr/include + +DISTDIR = + +pkgdatadir = $(datadir)/js +pkglibdir = $(libdir)/js +pkgincludedir = $(includedir)/js + +top_builddir = .. + +ACLOCAL = aclocal +AUTOCONF = autoconf +AUTOMAKE = automake +AUTOHEADER = autoheader + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} +transform = s,x,x, + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = i686-pc-linux-gnu +host_triplet = i686-pc-linux-gnu +ACLOCAL_FLAGS_FOR_LIBTOOL = +CC = gcc +CPP = gcc -E +EXTENSIONS = dl_open.lo xjs.lo xmd5.lo md5c.lo +EXTENSIONS_LIBS = -ldl +INTERPRETER_FEATURES = r_std.lo +LD = /usr/bin/ld +LIBTOOL = $(SHELL) $(top_builddir)/libtool +LN_S = ln -s +MAKEINFO = makeinfo +NM = /usr/bin/nm -B +PACKAGE = js +PGCC_BY_PROVENZANO = +RANLIB = ranlib +U = +VERSION = 0.2.5 +XLC_R_AIX = + +SUBDIRS = tests + +# CFLAGS = -g -O2 -Wall -Wno-unused + +lib_LTLIBRARIES = libjs.la +include_HEADERS = js.h jsint.h + +libjs_la_SOURCES = bc.c heap.c object.c debug.c compiler.c js.c vm.c \ + vmswitch.c vmjumps.c alloc.c utils.c mrgsort.c \ + regex.c crc32.c iostream.c \ + b_array.c b_bool.c b_func.c b_core.c b_number.c \ + b_object.c b_string.c b_date.c b_dir.c b_file.c b_math.c \ + b_regexp.c b_system.c b_vm.c + +libjs_la_LIBADD = r_std.lo dl_open.lo xjs.lo xmd5.lo md5c.lo +libjs_la_DEPENDENCIES = $(libjs_la_LIBADD) +EXTRA_libjs_la_SOURCES = vmswt0.c r_std.c r_pthrs.c dl_open.c dl_dummy.c \ + xjs.c xcurses.c xmd5.c md5c.c + +man_MANS = js.1 + +bin_PROGRAMS = js + +js_SOURCES = main.c getopt.c getopt1.c + +js_LDADD = libjs.la -ldl -lm + +# noinst_PROGRAMS = errtest +# errtest_SOURCES = errtest.c +# errtest_LDADD = libjs.a -ldl -lm + +noinst_HEADERS = c1swt0.h eswt0.h c1switch.h c2switch.h eswitch.h \ + c1jumps.h c2jumps.h ejumps.h rentrant.h \ + getopt.h mrgsort.h regex.h md5.h + +EXTRA_DIST = operands.def make-swt0.pl make-switch.pl make-jumps.pl \ + make-op-def.pl make-data.c js.1 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../jsconfig.h +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(lib_LTLIBRARIES) + + +DEFS = -DHAVE_CONFIG_H -I. -I$(srcdir) -I.. +CPPFLAGS = +LDFLAGS = -rdynamic +LIBS = +libjs_la_LDFLAGS = +libjs_la_OBJECTS = bc.lo heap.lo object.lo debug.lo compiler.lo js.lo \ +vm.lo vmswitch.lo vmjumps.lo alloc.lo utils.lo mrgsort.lo regex.lo \ +crc32.lo iostream.lo b_array.lo b_bool.lo b_func.lo b_core.lo \ +b_number.lo b_object.lo b_string.lo b_date.lo b_dir.lo b_file.lo \ +b_math.lo b_regexp.lo b_system.lo b_vm.lo +PROGRAMS = $(bin_PROGRAMS) + +js_OBJECTS = main.o getopt.o getopt1.o +js_DEPENDENCIES = libjs.la +js_LDFLAGS = +CFLAGS = -g -O2 +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) +LINK = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) -o $@ +man1dir = $(mandir)/man1 +MANS = $(man_MANS) + +NROFF = nroff +HEADERS = $(include_HEADERS) $(noinst_HEADERS) + +DIST_COMMON = ChangeLog Makefile.am Makefile.in TODO + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP = --best +SOURCES = $(libjs_la_SOURCES) $(EXTRA_libjs_la_SOURCES) $(js_SOURCES) +OBJECTS = $(libjs_la_OBJECTS) $(js_OBJECTS) + +all: all-recursive all-am + +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps src/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-libLTLIBRARIES: + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + +distclean-libLTLIBRARIES: + +maintainer-clean-libLTLIBRARIES: + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(libdir) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo "$(LIBTOOL) --mode=install $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p"; \ + $(LIBTOOL) --mode=install $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \ + done + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +libjs.la: $(libjs_la_OBJECTS) $(libjs_la_DEPENDENCIES) + $(LINK) -rpath $(libdir) $(libjs_la_LDFLAGS) $(libjs_la_OBJECTS) $(libjs_la_LIBADD) $(LIBS) + +mostlyclean-binPROGRAMS: + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +distclean-binPROGRAMS: + +maintainer-clean-binPROGRAMS: + +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + list='$(bin_PROGRAMS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + done + +js: $(js_OBJECTS) $(js_DEPENDENCIES) + @rm -f js + $(LINK) $(js_LDFLAGS) $(js_OBJECTS) $(js_LDADD) $(LIBS) + +install-man1: + $(mkinstalldirs) $(DESTDIR)$(man1dir) + @list='$(man1_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \ + done + +uninstall-man1: + @list='$(man1_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \ + rm -f $(DESTDIR)$(man1dir)/$$inst; \ + done +install-man: $(MANS) + @$(NORMAL_INSTALL) + $(MAKE) install-man1 +uninstall-man: + @$(NORMAL_UNINSTALL) + $(MAKE) uninstall-man1 + +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(includedir) + @list='$(include_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + list='$(include_HEADERS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(includedir)/$$p; \ + done + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. + + + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + target=`echo $@ | sed s/-recursive//`; \ + echo "Making $$target in $$subdir"; \ + (cd $$subdir && $(MAKE) $$target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + done; \ + for subdir in $$rev; do \ + target=`echo $@ | sed s/-recursive//`; \ + echo "Making $$target in $$subdir"; \ + (cd $$subdir && $(MAKE) $$target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + (cd $$subdir && $(MAKE) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = src + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done + for subdir in $(SUBDIRS); do \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + done +info: info-recursive +dvi: dvi-recursive +check: all-am + $(MAKE) check-recursive +installcheck: installcheck-recursive +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(MANS) $(HEADERS) + +install-exec-am: install-libLTLIBRARIES install-binPROGRAMS + +install-data-am: install-man install-includeHEADERS + +uninstall-am: uninstall-libLTLIBRARIES uninstall-binPROGRAMS uninstall-man uninstall-includeHEADERS + +install-exec: install-exec-recursive install-exec-am + @$(NORMAL_INSTALL) + +install-data: install-data-recursive install-data-am + @$(NORMAL_INSTALL) + +install: install-recursive install-exec-am install-data-am + @: + +uninstall: uninstall-recursive uninstall-am + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: installdirs-recursive + $(mkinstalldirs) $(DATADIR)$(libdir) $(DATADIR)$(bindir) \ + $(DESTDIR)$(mandir)/man1 $(DATADIR)$(includedir) + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \ + mostlyclean-libtool mostlyclean-binPROGRAMS \ + mostlyclean-tags mostlyclean-generic + +clean-am: clean-libLTLIBRARIES clean-compile clean-libtool \ + clean-binPROGRAMS clean-tags clean-generic \ + mostlyclean-am + +distclean-am: distclean-libLTLIBRARIES distclean-compile \ + distclean-libtool distclean-binPROGRAMS distclean-tags \ + distclean-generic clean-am + +maintainer-clean-am: maintainer-clean-libLTLIBRARIES \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-binPROGRAMS maintainer-clean-tags \ + maintainer-clean-generic distclean-am + +mostlyclean: mostlyclean-recursive mostlyclean-am + +clean: clean-recursive clean-am + +distclean: distclean-recursive distclean-am + -rm -f config.status + -rm -f libtool + +maintainer-clean: maintainer-clean-recursive maintainer-clean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \ +clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \ +uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \ +distclean-compile clean-compile maintainer-clean-compile \ +mostlyclean-libtool distclean-libtool clean-libtool \ +maintainer-clean-libtool mostlyclean-binPROGRAMS distclean-binPROGRAMS \ +clean-binPROGRAMS maintainer-clean-binPROGRAMS uninstall-binPROGRAMS \ +install-binPROGRAMS install-man1 uninstall-man1 install-man \ +uninstall-man uninstall-includeHEADERS install-includeHEADERS \ +install-data-recursive uninstall-data-recursive install-exec-recursive \ +uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \ +all-recursive check-recursive installcheck-recursive info-recursive \ +dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info dvi \ +installcheck all-am install-exec-am install-data-am uninstall-am \ +install-exec install-data install uninstall all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +operands: + ./make-op-def.pl operands.def > op.def + ./make-swt0.pl operands.def + ./make-switch.pl operands.def + ./make-jumps.pl operands.def + +compiler-source: make-data + ./make-data js_compiler_bytecode ../jsc/compiler.jsc compiler.c + +make-data: make-data.o + $(CC) $(ALLLDFLAGS) make-data.o -o make-data + +wc: + wc alloc.c b_*.c bc.c debug.c dl_*.c heap.c iostream.c js.c \ + main.c mrgsort.c object.c r_*.c utils.c vm.c vmjumps.c \ + vmswitch.c vmswt0.c xcurses.c xjs.c xmd5.c js.h jsint.h \ + mrgsort.h rentrant.h operands.def + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/reactos/lib/kjs/src/Makefile.am b/reactos/lib/kjs/src/Makefile.am new file mode 100644 index 00000000000..ccb95b35668 --- /dev/null +++ b/reactos/lib/kjs/src/Makefile.am @@ -0,0 +1,79 @@ +# +# Automakefile for JavaScript virtual machine. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + +SUBDIRS = tests + +# CFLAGS = -g -O2 -Wall -Wno-unused + +lib_LTLIBRARIES = libjs.la +include_HEADERS = js.h jsint.h + +libjs_la_SOURCES = bc.c heap.c object.c debug.c compiler.c js.c vm.c \ + vmswitch.c vmjumps.c alloc.c utils.c mrgsort.c \ + regex.c crc32.c iostream.c \ + b_array.c b_bool.c b_func.c b_core.c b_number.c \ + b_object.c b_string.c b_date.c b_dir.c b_file.c b_math.c \ + b_regexp.c b_system.c b_vm.c + +libjs_la_LIBADD = @INTERPRETER_FEATURES@ @EXTENSIONS@ +libjs_la_DEPENDENCIES = $(libjs_la_LIBADD) +EXTRA_libjs_la_SOURCES = vmswt0.c r_std.c r_pthrs.c dl_open.c dl_dummy.c \ + xjs.c xcurses.c xmd5.c md5c.c + +man_MANS = js.1 + +bin_PROGRAMS = js + +js_SOURCES = main.c getopt.c getopt1.c + +js_LDADD = libjs.la @EXTENSIONS_LIBS@ -lm + +# noinst_PROGRAMS = errtest +# errtest_SOURCES = errtest.c +# errtest_LDADD = libjs.a @EXTENSIONS_LIBS@ -lm + +noinst_HEADERS = c1swt0.h eswt0.h c1switch.h c2switch.h eswitch.h \ + c1jumps.h c2jumps.h ejumps.h rentrant.h \ + getopt.h mrgsort.h regex.h md5.h + +EXTRA_DIST = operands.def make-swt0.pl make-switch.pl make-jumps.pl \ + make-op-def.pl make-data.c js.1 + +operands: + ./make-op-def.pl operands.def > op.def + ./make-swt0.pl operands.def + ./make-switch.pl operands.def + ./make-jumps.pl operands.def + +compiler-source: make-data + ./make-data js_compiler_bytecode ../jsc/compiler.jsc compiler.c + +make-data: make-data.o + $(CC) $(ALLLDFLAGS) make-data.o -o make-data + +wc: + wc alloc.c b_*.c bc.c debug.c dl_*.c heap.c iostream.c js.c \ + main.c mrgsort.c object.c r_*.c utils.c vm.c vmjumps.c \ + vmswitch.c vmswt0.c xcurses.c xjs.c xmd5.c js.h jsint.h \ + mrgsort.h rentrant.h operands.def diff --git a/reactos/lib/kjs/src/Makefile.in b/reactos/lib/kjs/src/Makefile.in new file mode 100644 index 00000000000..b8fa0625b22 --- /dev/null +++ b/reactos/lib/kjs/src/Makefile.in @@ -0,0 +1,542 @@ +# Makefile.in generated automatically by automake 1.3 from Makefile.am + +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Automakefile for JavaScript virtual machine. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# + + +SHELL = /bin/sh + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DISTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_FLAGS_FOR_LIBTOOL = @ACLOCAL_FLAGS_FOR_LIBTOOL@ +CC = @CC@ +CPP = @CPP@ +EXTENSIONS = @EXTENSIONS@ +EXTENSIONS_LIBS = @EXTENSIONS_LIBS@ +INTERPRETER_FEATURES = @INTERPRETER_FEATURES@ +LD = @LD@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +NM = @NM@ +PACKAGE = @PACKAGE@ +PGCC_BY_PROVENZANO = @PGCC_BY_PROVENZANO@ +RANLIB = @RANLIB@ +U = @U@ +VERSION = @VERSION@ +XLC_R_AIX = @XLC_R_AIX@ + +SUBDIRS = tests + +# CFLAGS = -g -O2 -Wall -Wno-unused + +lib_LTLIBRARIES = libjs.la +include_HEADERS = js.h jsint.h + +libjs_la_SOURCES = bc.c heap.c object.c debug.c compiler.c js.c vm.c \ + vmswitch.c vmjumps.c alloc.c utils.c mrgsort.c \ + regex.c crc32.c iostream.c \ + b_array.c b_bool.c b_func.c b_core.c b_number.c \ + b_object.c b_string.c b_date.c b_dir.c b_file.c b_math.c \ + b_regexp.c b_system.c b_vm.c + +libjs_la_LIBADD = @INTERPRETER_FEATURES@ @EXTENSIONS@ +libjs_la_DEPENDENCIES = $(libjs_la_LIBADD) +EXTRA_libjs_la_SOURCES = vmswt0.c r_std.c r_pthrs.c dl_open.c dl_dummy.c \ + xjs.c xcurses.c xmd5.c md5c.c + +man_MANS = js.1 + +bin_PROGRAMS = js + +js_SOURCES = main.c getopt.c getopt1.c + +js_LDADD = libjs.la @EXTENSIONS_LIBS@ -lm + +# noinst_PROGRAMS = errtest +# errtest_SOURCES = errtest.c +# errtest_LDADD = libjs.a @EXTENSIONS_LIBS@ -lm + +noinst_HEADERS = c1swt0.h eswt0.h c1switch.h c2switch.h eswitch.h \ + c1jumps.h c2jumps.h ejumps.h rentrant.h \ + getopt.h mrgsort.h regex.h md5.h + +EXTRA_DIST = operands.def make-swt0.pl make-switch.pl make-jumps.pl \ + make-op-def.pl make-data.c js.1 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../jsconfig.h +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(lib_LTLIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I.. +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +libjs_la_LDFLAGS = +libjs_la_OBJECTS = bc.lo heap.lo object.lo debug.lo compiler.lo js.lo \ +vm.lo vmswitch.lo vmjumps.lo alloc.lo utils.lo mrgsort.lo regex.lo \ +crc32.lo iostream.lo b_array.lo b_bool.lo b_func.lo b_core.lo \ +b_number.lo b_object.lo b_string.lo b_date.lo b_dir.lo b_file.lo \ +b_math.lo b_regexp.lo b_system.lo b_vm.lo +PROGRAMS = $(bin_PROGRAMS) + +js_OBJECTS = main.o getopt.o getopt1.o +js_DEPENDENCIES = libjs.la +js_LDFLAGS = +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) +LINK = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) -o $@ +man1dir = $(mandir)/man1 +MANS = $(man_MANS) + +NROFF = nroff +HEADERS = $(include_HEADERS) $(noinst_HEADERS) + +DIST_COMMON = ChangeLog Makefile.am Makefile.in TODO + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP = --best +SOURCES = $(libjs_la_SOURCES) $(EXTRA_libjs_la_SOURCES) $(js_SOURCES) +OBJECTS = $(libjs_la_OBJECTS) $(js_OBJECTS) + +all: all-recursive all-am + +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps src/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-libLTLIBRARIES: + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + +distclean-libLTLIBRARIES: + +maintainer-clean-libLTLIBRARIES: + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(libdir) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo "$(LIBTOOL) --mode=install $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p"; \ + $(LIBTOOL) --mode=install $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \ + done + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +libjs.la: $(libjs_la_OBJECTS) $(libjs_la_DEPENDENCIES) + $(LINK) -rpath $(libdir) $(libjs_la_LDFLAGS) $(libjs_la_OBJECTS) $(libjs_la_LIBADD) $(LIBS) + +mostlyclean-binPROGRAMS: + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +distclean-binPROGRAMS: + +maintainer-clean-binPROGRAMS: + +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + list='$(bin_PROGRAMS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + done + +js: $(js_OBJECTS) $(js_DEPENDENCIES) + @rm -f js + $(LINK) $(js_LDFLAGS) $(js_OBJECTS) $(js_LDADD) $(LIBS) + +install-man1: + $(mkinstalldirs) $(DESTDIR)$(man1dir) + @list='$(man1_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \ + done + +uninstall-man1: + @list='$(man1_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \ + rm -f $(DESTDIR)$(man1dir)/$$inst; \ + done +install-man: $(MANS) + @$(NORMAL_INSTALL) + $(MAKE) install-man1 +uninstall-man: + @$(NORMAL_UNINSTALL) + $(MAKE) uninstall-man1 + +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(includedir) + @list='$(include_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + list='$(include_HEADERS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(includedir)/$$p; \ + done + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. + +@SET_MAKE@ + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + target=`echo $@ | sed s/-recursive//`; \ + echo "Making $$target in $$subdir"; \ + (cd $$subdir && $(MAKE) $$target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + done; \ + for subdir in $$rev; do \ + target=`echo $@ | sed s/-recursive//`; \ + echo "Making $$target in $$subdir"; \ + (cd $$subdir && $(MAKE) $$target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + (cd $$subdir && $(MAKE) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = src + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done + for subdir in $(SUBDIRS); do \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + done +info: info-recursive +dvi: dvi-recursive +check: all-am + $(MAKE) check-recursive +installcheck: installcheck-recursive +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(MANS) $(HEADERS) + +install-exec-am: install-libLTLIBRARIES install-binPROGRAMS + +install-data-am: install-man install-includeHEADERS + +uninstall-am: uninstall-libLTLIBRARIES uninstall-binPROGRAMS uninstall-man uninstall-includeHEADERS + +install-exec: install-exec-recursive install-exec-am + @$(NORMAL_INSTALL) + +install-data: install-data-recursive install-data-am + @$(NORMAL_INSTALL) + +install: install-recursive install-exec-am install-data-am + @: + +uninstall: uninstall-recursive uninstall-am + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: installdirs-recursive + $(mkinstalldirs) $(DATADIR)$(libdir) $(DATADIR)$(bindir) \ + $(DESTDIR)$(mandir)/man1 $(DATADIR)$(includedir) + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \ + mostlyclean-libtool mostlyclean-binPROGRAMS \ + mostlyclean-tags mostlyclean-generic + +clean-am: clean-libLTLIBRARIES clean-compile clean-libtool \ + clean-binPROGRAMS clean-tags clean-generic \ + mostlyclean-am + +distclean-am: distclean-libLTLIBRARIES distclean-compile \ + distclean-libtool distclean-binPROGRAMS distclean-tags \ + distclean-generic clean-am + +maintainer-clean-am: maintainer-clean-libLTLIBRARIES \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-binPROGRAMS maintainer-clean-tags \ + maintainer-clean-generic distclean-am + +mostlyclean: mostlyclean-recursive mostlyclean-am + +clean: clean-recursive clean-am + +distclean: distclean-recursive distclean-am + -rm -f config.status + -rm -f libtool + +maintainer-clean: maintainer-clean-recursive maintainer-clean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \ +clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \ +uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \ +distclean-compile clean-compile maintainer-clean-compile \ +mostlyclean-libtool distclean-libtool clean-libtool \ +maintainer-clean-libtool mostlyclean-binPROGRAMS distclean-binPROGRAMS \ +clean-binPROGRAMS maintainer-clean-binPROGRAMS uninstall-binPROGRAMS \ +install-binPROGRAMS install-man1 uninstall-man1 install-man \ +uninstall-man uninstall-includeHEADERS install-includeHEADERS \ +install-data-recursive uninstall-data-recursive install-exec-recursive \ +uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \ +all-recursive check-recursive installcheck-recursive info-recursive \ +dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info dvi \ +installcheck all-am install-exec-am install-data-am uninstall-am \ +install-exec install-data install uninstall all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +operands: + ./make-op-def.pl operands.def > op.def + ./make-swt0.pl operands.def + ./make-switch.pl operands.def + ./make-jumps.pl operands.def + +compiler-source: make-data + ./make-data js_compiler_bytecode ../jsc/compiler.jsc compiler.c + +make-data: make-data.o + $(CC) $(ALLLDFLAGS) make-data.o -o make-data + +wc: + wc alloc.c b_*.c bc.c debug.c dl_*.c heap.c iostream.c js.c \ + main.c mrgsort.c object.c r_*.c utils.c vm.c vmjumps.c \ + vmswitch.c vmswt0.c xcurses.c xjs.c xmd5.c js.h jsint.h \ + mrgsort.h rentrant.h operands.def + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/reactos/lib/kjs/src/TODO b/reactos/lib/kjs/src/TODO new file mode 100644 index 00000000000..95988ed1057 --- /dev/null +++ b/reactos/lib/kjs/src/TODO @@ -0,0 +1,104 @@ + + TODO Virtual Machine & JS API + ============================= + +* Write tests for the built-in File object. + +* js_interp_reinit(): restore the interpreter to the same state where + it was after the js_create_interp() call. Or, js_clone_interp() to + create a clone of a running interpreter. Or, speedup the compiler + definition: on-demand, something else? + +* src/regexp.h file: + + #define regcomp my_regcomp + #define regexec my_regexec + #define regfree my_regfree + +* Cleanup the error message and error code passing in the JSIOStream + interface. + +* compilation / configuration + + - `--with-*' options to enable / disable features like: crc32, + regexp, compiler, getcwd, popen + +* There are still some memory leaks that occur when the dynamic memory + allocation fails and we have some previously allocated stuffs on + stack variables. Find a nice solution for this. + +* Dynamic stack expansion in case of stack overflow and shrinking when + the stack usage is less that some fraction of the stack space. + +* System + + methods: readln(), printf() + +* object Function + + implement + +* object Date + + methods: parse, getTimezoneOffset, UTC + constructor with 1 argument + +* object Object + + properties: constructor + methods: toString + + Check that all built-in objects implement toString(). The other + methods and all properties are currently unimplemented. + +* Added the flags JS_ATTRIB_READONLY, JS_ATTRIB_DONTENUM, etc. for the + object properties. + +* Built-ins + + Allow users to overwrite the default methods. Basicly, we have all + that is needed for this. I just want to think this one for a while, + because the default __proto__ lookup will slow the built-in method + dispatching. + +* String.format() might be handy + +* byte-code operands + + - `load_array' and `store_array' to work with built-in objects with + integer array indexes + - `nth' to work with built-in objects + - cmp_{eq,ne}: object OP string/number + +* operand delete_property: support for the with-chains + +* RegExp.multiline property + +* String.{,un}pack(): implement all missing type specifiers + +* allow user-defined global methods for the JavaScript extension + +* Tcl extension + +* Garbage collection should be re-implemented. Incremental? + Generational? Maybe, maybe not. + +* Garbage collection (slot recycling) for constants. The current + implementation leaks the constant slots when functions (and + therefore the constants) are freed. + +* tests for built-in objects and methods. Do this at the same time + when the documentation is updated. + +* byte-code operand profiling shows the following facts: + + operand #hits relative hits + ---------------------------------------- + store_property 1048 21.38 + load_property 741 15.12 + call_method 531 10.83 + store_local 272 5.55 + ... + + maybe the implementation of the object properties could be + optimized \ No newline at end of file diff --git a/reactos/lib/kjs/src/alloc.c b/reactos/lib/kjs/src/alloc.c new file mode 100644 index 00000000000..6b1f4873e8f --- /dev/null +++ b/reactos/lib/kjs/src/alloc.c @@ -0,0 +1,311 @@ +/* + * Memory allocation routines. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/alloc.c,v $ + * $Id: alloc.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" + +/* + * Global functions. + */ + +#if JS_DEBUG_MEMORY_LEAKS + +struct mem_debug_st +{ + struct mem_debug_st *next; + struct mem_debug_st *prev; + char *file; + int line; + size_t size; +}; + +typedef struct mem_debug_st MemDebug; + +static MemDebug *mem_debug_blocks = NULL; + +int mem_debug_balance = 0; + +unsigned int alloc_fail = 0; +unsigned int alloc_count = 0; + +static void +register_block (MemDebug *b, size_t size, char *file, int line) +{ + b->next = NULL; + b->prev = NULL; + b->file = file; + b->line = line; + b->size = size; + + if (mem_debug_blocks) + { + b->next = mem_debug_blocks; + mem_debug_blocks->prev = b; + } + + mem_debug_blocks = b; + mem_debug_balance++; +} + + +static void +unregister_block (MemDebug *b) +{ + if (b->file == NULL) + { + fprintf (stderr, "freeing the same block twise\n"); + abort (); + } + + if (b->next) + b->next->prev = b->prev; + + if (b->prev) + b->prev->next = b->next; + else + mem_debug_blocks = b->next; + + b->file = NULL; + + mem_debug_balance--; +} + + +static inline int +check_fail () +{ + return alloc_fail != 0 && ++alloc_count >= alloc_fail; +} + + +void +js_alloc_dump_blocks () +{ + MemDebug *b; + unsigned int bytes = 0; + + fprintf (stderr, "js_alloc_dump_blocks(): #blocks=%d\n", mem_debug_balance); + + for (b = mem_debug_blocks; b; b = b->next) + { + fprintf (stderr, "%s:%d: %lu\n", b->file, b->line, b->size); + bytes += b->size; + } + + fprintf (stderr, "leaks=%u\n", bytes); +} + + + +void * +js_malloc_i (JSVirtualMachine *vm, size_t size, char *file, int line) +{ + MemDebug *ptr; + + ptr = malloc (sizeof (MemDebug) + size); + if (check_fail () || ptr == NULL) + { + if (vm != NULL) + { + sprintf (vm->error, "VM: memory exhausted"); + js_vm_error (vm); + } + + return NULL; + } + + register_block (ptr, size, file, line); + + return (unsigned char *) ptr + sizeof (MemDebug); +} + + +void * +js_calloc_i (JSVirtualMachine *vm, size_t num, size_t size, char *file, + int line) +{ + MemDebug *ptr; + + ptr = malloc (sizeof (MemDebug) + num * size); + if (check_fail () || ptr == NULL) + { + if (vm != NULL) + { + sprintf (vm->error, "VM: memory exhausted"); + js_vm_error (vm); + } + + return NULL; + } + + memset (ptr, 0, sizeof (MemDebug) + num * size); + register_block (ptr, num * size, file, line); + + return (unsigned char *) ptr + sizeof (MemDebug); +} + + +void * +js_realloc_i (JSVirtualMachine *vm, void *ptr, size_t size, char *file, + int line) +{ + void *nptr; + MemDebug *b; + + if (ptr == NULL) + return js_malloc_i (vm, size, file, line); + + nptr = js_malloc_i (vm, size, file, line); + if (nptr == NULL) + { + if (vm != NULL) + { + sprintf (vm->error, "VM: memory exhausted"); + js_vm_error (vm); + } + + return NULL; + } + + b = (MemDebug *) ((unsigned char *) ptr - sizeof (MemDebug)); + + memcpy (nptr, ptr, size < b->size ? size : b->size); + + js_free (ptr); + + return nptr; +} + + +void +js_free (void *ptr) +{ + MemDebug *b; + + if (ptr == NULL) + return; + + b = (MemDebug *) ((unsigned char *) ptr - sizeof (MemDebug)); + unregister_block (b); + + free (b); +} + + +char * +js_strdup_i (JSVirtualMachine *vm, const char *str, char *file, int line) +{ + char *tmp; + + tmp = js_malloc_i (vm, strlen (str) + 1, file, line); + if (tmp == NULL) + return NULL; + + strcpy (tmp, str); + + return tmp; +} + +#else /* not JS_DEBUG_MEMORY_LEAKS */ + +void * +js_malloc (JSVirtualMachine *vm, size_t size) +{ + void *ptr; + + ptr = malloc (size); + if (ptr == NULL && vm != NULL) + { + sprintf (vm->error, "VM: memory exhausted"); + js_vm_error (vm); + } + + return ptr; +} + + +void * +js_calloc (JSVirtualMachine *vm, size_t num, size_t size) +{ + void *ptr; + + ptr = calloc (num, size); + if (ptr == NULL && vm != NULL) + { + sprintf (vm->error, "VM: memory exhausted"); + js_vm_error (vm); + } + + return ptr; +} + + +void * +js_realloc (JSVirtualMachine *vm, void *ptr, size_t size) +{ + void *nptr; + + if (ptr == NULL) + return js_malloc (vm, size); + + nptr = realloc (ptr, size); + if (nptr == NULL && vm != NULL) + { + sprintf (vm->error, "VM: memory exhausted"); + js_vm_error (vm); + } + + return nptr; +} + + +void +js_free (void *ptr) +{ + if (ptr == NULL) + return; + + free (ptr); +} + + +char * +js_strdup (JSVirtualMachine *vm, const char *str) +{ + char *tmp; + + tmp = js_malloc (vm, strlen (str) + 1); + if (tmp == NULL) + return NULL; + + strcpy (tmp, str); + + return tmp; +} + +#endif /* not JS_DEBUG_MEMORY_LEAKS */ diff --git a/reactos/lib/kjs/src/b_array.c b/reactos/lib/kjs/src/b_array.c new file mode 100644 index 00000000000..2505db6eb56 --- /dev/null +++ b/reactos/lib/kjs/src/b_array.c @@ -0,0 +1,650 @@ +/* + * The builtin Array object. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/b_array.c,v $ + * $Id: b_array.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +/* + * Mehtods: + * + * concat (array) => array + * join ([glue]) => string + * pop () => last_element + * push (any...) => last_element_added + * reverse () + * shift () => first_element + * slice (start, end) => array + * splice (index, how_many[, any...]) => array + * sort ([sort_function]) + * toString () => string + * unshift (any...) => length_of_the_array + * + * Properties: + * + * length + */ + +#include "jsint.h" +#include "mrgsort.h" + +/* + * Types and definitions. + */ + +/* Class context. */ +struct array_ctx_st +{ + JSSymbol s_concat; + JSSymbol s_join; + JSSymbol s_pop; + JSSymbol s_push; + JSSymbol s_reverse; + JSSymbol s_shift; + JSSymbol s_slice; + JSSymbol s_splice; + JSSymbol s_sort; + JSSymbol s_unshift; + + JSSymbol s_length; +}; + +typedef struct array_ctx_st ArrayCtx; + +/* Context for array sorts with JavaScript functions. */ +struct array_sort_ctx_st +{ + JSVirtualMachine *vm; + JSNode *func; + JSNode argv[3]; +}; + +typedef struct array_sort_ctx_st ArraySortCtx; + +/* + * Prototypes for static functions. + */ + +static void new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + JSNode *args, JSNode *result_return); + + +/* + * Static functions. + */ + +static int +sort_default_cmp_func (const void *aptr, const void *bptr, void *context) +{ + JSVirtualMachine *vm = context; + const JSNode *a = aptr; + const JSNode *b = bptr; + JSNode astr, bstr; + + if (a->type == JS_UNDEFINED) + return 1; + if (b->type == JS_UNDEFINED) + return -1; + + js_vm_to_string (vm, a, &astr); + js_vm_to_string (vm, b, &bstr); + + return js_compare_strings (&astr, &bstr); +} + + +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; +} + + +/* Global method proc. */ +static void +global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSNode *result_return, + JSNode *args) +{ + /* This does exactly the same as the new_proc. */ + new_proc (vm, builtin_info, args, result_return); +} + + +/* 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; + + /* XXX 15.7.4.3 toSource(). */ + + /* Handle static methods here. */ + if (instance_context == NULL) + { + if (method == vm->syms.s_toString) + js_vm_make_static_string (vm, result_return, "Array", 5); + /* ************************************************************ */ + else + return JS_PROPERTY_UNKNOWN; + + return JS_PROPERTY_FOUND; + } + + /* Handle the instance methods. */ + + /* Set the default result type. */ + result_return->type = JS_UNDEFINED; + + if (method == ctx->s_concat) + { + int nlen; + int pos; + + /* Count the new len; */ + + nlen = n->u.varray->length; + for (i = 0; i < args->u.vinteger; i++) + { + if (args[i + 1].type != JS_ARRAY) + goto argument_error; + + nlen += args[i + 1].u.varray->length; + } + + js_vm_make_array (vm, result_return, nlen); + + /* Insert the items. */ + memcpy (result_return->u.varray->data, n->u.varray->data, + n->u.varray->length * sizeof (JSNode)); + pos = n->u.varray->length; + + for (i = 0; i < args->u.vinteger; i++) + { + memcpy (&result_return->u.varray->data[pos], + args[i + 1].u.varray->data, + args[i + 1].u.varray->length * sizeof (JSNode)); + pos += args[i + 1].u.varray->length; + } + } + /* ********************************************************************** */ + 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; +} + +/* Property proc. */ +static int +property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol property, int set, JSNode *node) +{ + ArrayCtx *ctx = builtin_info->obj_context; + JSNode *n = instance_context; + + if (property == ctx->s_length) + { + if (set) + goto immutable; + + node->type = JS_INTEGER; + node->u.vinteger = n->u.varray->length; + } + else + { + if (!set) + node->type = JS_UNDEFINED; + + return JS_PROPERTY_UNKNOWN; + } + + return JS_PROPERTY_FOUND; + + + /* + * Error handling. + */ + + immutable: + sprintf (vm->error, "Array.%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) +{ + int i; + + if (args->u.vinteger == 1 && args[1].type == JS_INTEGER) + { + /* Create a fixed length array. */ + js_vm_make_array (vm, result_return, args[1].u.vinteger); + } + else + { + if (args->u.vinteger < 0) + /* We are called from the array initializer. */ + args->u.vinteger = -args->u.vinteger; + + js_vm_make_array (vm, result_return, args->u.vinteger); + for (i = 0; i < args->u.vinteger; i++) + JS_COPY (&result_return->u.varray->data[i], &args[i + 1]); + } + /* Set the [[Prototype]] and [[Class]] properties. */ + /* XXX 15.7.2.1 */ +} + + +/* + * Global functions. + */ + +void +js_builtin_Array (JSVirtualMachine *vm) +{ + ArrayCtx *ctx; + JSNode *n; + JSBuiltinInfo *info; + + ctx = js_calloc (vm, 1, sizeof (*ctx)); + + ctx->s_concat = js_vm_intern (vm, "concat"); + ctx->s_join = js_vm_intern (vm, "join"); + ctx->s_pop = js_vm_intern (vm, "pop"); + ctx->s_push = js_vm_intern (vm, "push"); + ctx->s_reverse = js_vm_intern (vm, "reverse"); + ctx->s_shift = js_vm_intern (vm, "shift"); + ctx->s_slice = js_vm_intern (vm, "slice"); + ctx->s_splice = js_vm_intern (vm, "splice"); + ctx->s_sort = js_vm_intern (vm, "sort"); + ctx->s_unshift = js_vm_intern (vm, "unshift"); + + ctx->s_length = js_vm_intern (vm, "length"); + + info = js_vm_builtin_info_create (vm); + vm->prim[JS_ARRAY] = 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, "Array")]; + js_vm_builtin_create (vm, n, info, NULL); +} diff --git a/reactos/lib/kjs/src/b_bool.c b/reactos/lib/kjs/src/b_bool.c new file mode 100644 index 00000000000..cf2e4ff09ca --- /dev/null +++ b/reactos/lib/kjs/src/b_bool.c @@ -0,0 +1,153 @@ +/* + * The builtin Boolean object. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/b_bool.c,v $ + * $Id: b_bool.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" + +/* + * Static functions. + */ + +/* Global method proc. */ +static void +global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSNode *result_return, + JSNode *args) +{ + result_return->type = JS_BOOLEAN; + + if (args->u.vinteger == 0) + result_return->u.vboolean = 0; + else if (args->u.vinteger == 1) + result_return->u.vboolean = js_vm_to_boolean (vm, &args[1]); + else + { + sprintf (vm->error, "Boolean(): 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 *cp; + + if (method == vm->syms.s_toString) + { + if (args->u.vinteger != 0) + { + sprintf (vm->error, "Boolean.%s(): illegal amount of arguments", + js_vm_symname (vm, method)); + js_vm_error (vm); + } + + if (n) + { + cp = n->u.vboolean ? "true" : "false"; + js_vm_make_static_string (vm, result_return, cp, strlen (cp)); + } + else + js_vm_make_static_string (vm, result_return, "Boolean", 7); + } + /* ********************************************************************** */ + else if (method == vm->syms.s_valueOf) + { + if (n) + JS_COPY (result_return, n); + else + { + n = &vm->globals[js_vm_intern (vm, "Boolean")]; + JS_COPY (result_return, n); + } + } + /* ********************************************************************** */ + else + return JS_PROPERTY_UNKNOWN; + + return JS_PROPERTY_FOUND; +} + +/* Property proc. */ +static int +property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol property, int set, JSNode *node) +{ + if (!set) + node->type = JS_UNDEFINED; + + return JS_PROPERTY_UNKNOWN; +} + +/* New proc. */ +static void +new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, JSNode *args, + JSNode *result_return) +{ + result_return->type = JS_BOOLEAN; + + if (args->u.vinteger == 0) + result_return->u.vboolean = 0; + else if (args->u.vinteger == 1) + result_return->u.vboolean = js_vm_to_boolean (vm, &args[1]); + else + { + sprintf (vm->error, "new Boolean(): illegal amount of arguments"); + js_vm_error (vm); + } + + /* Set the [[Prototype]] and [[Class]] properties. */ + /* XXX 15.10.2.1 */ +} + + +/* + * Global functions. + */ + +void +js_builtin_Boolean (JSVirtualMachine *vm) +{ + JSNode *n; + JSBuiltinInfo *info; + + info = js_vm_builtin_info_create (vm); + vm->prim[JS_BOOLEAN] = info; + + info->global_method_proc = global_method; + info->method_proc = method; + info->property_proc = property; + info->new_proc = new_proc; + + /* Define it. */ + n = &vm->globals[js_vm_intern (vm, "Boolean")]; + js_vm_builtin_create (vm, n, info, NULL); +} diff --git a/reactos/lib/kjs/src/b_core.c b/reactos/lib/kjs/src/b_core.c new file mode 100644 index 00000000000..0a6c6be953a --- /dev/null +++ b/reactos/lib/kjs/src/b_core.c @@ -0,0 +1,659 @@ +/* + * Core builtins for the JavaScript VM. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/b_core.c,v $ + * $Id: b_core.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +/* + * Global methods: + * + * parseInt (string[, radix]) + * parseFloat (string) + * escape (string) + * unescape (string) + * isNaN (any) + * isFinite (any) + * debug (any) + * error (string) + * float (any) + * int (any) + * isFloat (any) + * isInt (any) + * print (any[,...]) + */ + +#include "jsint.h" + +/* + * Types and definitions. + */ + +#define EMIT_TO_RESULT(c) \ + do { \ + result_return->u.vstring->data = \ + js_vm_realloc (vm, result_return->u.vstring->data, \ + result_return->u.vstring->len + 1); \ + result_return->u.vstring->data[result_return->u.vstring->len] = (c); \ + result_return->u.vstring->len += 1; \ + } while (0) + + +/* + * Static functions. + */ + +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 (vm->error, "parseInt(): illegal amount of arguments"); + 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; +} + + +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 (vm->error, "parseFloat(): illegal amount of arguments"); + 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; +} + + +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; + + if (args->u.vinteger != 1) + { + sprintf (vm->error, "escape(): illegal amount of arguments"); + 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 + * 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 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_+-./", + 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]); + } + } +} + +/* A helper function for unescape(). */ +static int +scanhexdigits (unsigned char *dp, int nd, unsigned int *cp) +{ + static const char digits[] = "0123456789abcdefABCDEF"; + int i; + unsigned int d; + + *cp = 0; + for (i = 0; i < nd; i += 1) + { + d = strchr (digits, dp[i]) - digits; + if (d < 16) + ; + else if (d < 22) + d -= 6; + else + return 0; + + *cp <<= 4; + *cp += d; + } + + return 1; +} + + +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 (vm->error, "unescape(): illegal amount of arguments"); + 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 + * 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); + } +} + + +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, "isNaN(): illegal amount of arguments"); + 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; +} + + +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 (vm->error, "isFinite(): illegal amount of arguments"); + 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; +} + + +static void +debug_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSNode *result_return, + JSNode *args) +{ + JSNode sitem; + + if (args->u.vinteger != 1) + { + sprintf (vm->error, "debug(): illegal amount of arguments"); + js_vm_error (vm); + } + + /* + * Maybe we should prefix the debug message with `Debug message:' + * prompt. + */ + js_vm_to_string (vm, &args[1], &sitem); + fwrite (sitem.u.vstring->data, sitem.u.vstring->len, 1, stderr); + + result_return->type = JS_UNDEFINED; +} + + +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, "error(): illegal amount of arguments"); + js_vm_error (vm); + } + if (args[1].type != JS_STRING) + { + sprintf (vm->error, "error(): 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 */ +} + + +static void +float_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSNode *result_return, + JSNode *args) +{ + double fval; + char *cp, *end; + + if (args->u.vinteger != 1) + { + sprintf (vm->error, "float(): illegal amount of arguments"); + js_vm_error (vm); + } + + switch (args[1].type) + { + case JS_BOOLEAN: + fval = (double) (args[1].u.vboolean != 0); + break; + + case JS_INTEGER: + fval = (double) args[1].u.vinteger; + break; + + case JS_STRING: + cp = js_string_to_c_string (vm, &args[1]); + fval = strtod (cp, &end); + js_free (cp); + + if (cp == end) + fval = 0.0; + break; + + case JS_FLOAT: + fval = args[1].u.vfloat; + break; + + case JS_ARRAY: + fval = (double) args[1].u.varray->length; + break; + + default: + fval = 0.0; + break; + } + + result_return->type = JS_FLOAT; + result_return->u.vfloat = fval; +} + + +static void +int_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSNode *result_return, + JSNode *args) +{ + long ival; + char *cp, *end; + + if (args->u.vinteger != 1) + { + sprintf (vm->error, "int(): illegal amount of arguments"); + js_vm_error (vm); + } + + switch (args[1].type) + { + case JS_BOOLEAN: + ival = (long) (args[1].u.vboolean != 0); + break; + + case JS_INTEGER: + ival = args[1].u.vinteger; + break; + + case JS_STRING: + cp = js_string_to_c_string (vm, &args[1]); + ival = strtol (cp, &end, 0); + js_free (cp); + + if (cp == end) + ival = 0; + break; + + case JS_FLOAT: + ival = (long) args[1].u.vfloat; + break; + + case JS_ARRAY: + ival = (long) args[1].u.varray->length; + break; + + default: + ival = 0; + break; + } + + result_return->type = JS_INTEGER; + result_return->u.vinteger = ival; +} + + +static void +isFloat_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSNode *result_return, + JSNode *args) +{ + /* The default result is false. */ + result_return->type = JS_BOOLEAN; + result_return->u.vboolean = 0; + + if (args->u.vinteger != 1) + { + sprintf (vm->error, "isFloat(): illegal amount of arguments"); + js_vm_error (vm); + } + + if (args[1].type == JS_FLOAT) + result_return->u.vboolean = 1; +} + + +static void +isInt_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSNode *result_return, + JSNode *args) +{ + /* The default result is false. */ + result_return->type = JS_BOOLEAN; + result_return->u.vboolean = 0; + + if (args->u.vinteger != 1) + { + sprintf (vm->error, "isInt(): illegal amount of arguments"); + js_vm_error (vm); + } + + if (args[1].type == JS_INTEGER) + result_return->u.vboolean = 1; +} + + +static void +print_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSNode *result_return, + JSNode *args) +{ + int i; + + /* The result is undefined. */ + result_return->type = JS_UNDEFINED; + + for (i = 1; i <= args->u.vinteger; i++) + { + JSNode result; + + js_vm_to_string (vm, &args[i], &result); + js_iostream_write (vm->s_stdout, result.u.vstring->data, + result.u.vstring->len); + + if (i + 1 <= args->u.vinteger) + js_iostream_write (vm->s_stdout, " ", 1); + } + + js_iostream_write (vm->s_stdout, JS_HOST_LINE_BREAK, JS_HOST_LINE_BREAK_LEN); +} + + +/* + * Global functions. + */ + +static struct +{ + char *name; + JSBuiltinGlobalMethod method; +} global_methods[] = +{ + {"parseInt", parseInt_global_method}, + {"parseFloat", parseFloat_global_method}, + {"escape", escape_global_method}, + {"unescape", unescape_global_method}, + {"isNaN", isNaN_global_method}, + {"isFinite", isFinite_global_method}, + {"debug", debug_global_method}, + {"error", error_global_method}, + {"float", float_global_method}, + {"int", int_global_method}, + {"isFloat", isFloat_global_method}, + {"isInt", isInt_global_method}, + {"print", print_global_method}, + + {NULL, NULL}, +}; + + +void +js_builtin_core (JSVirtualMachine *vm) +{ + int i; + JSNode *n; + + /* Properties. */ + + n = &vm->globals[js_vm_intern (vm, "NaN")]; + n->type = JS_NAN; + + n = &vm->globals[js_vm_intern (vm, "Infinity")]; + JS_MAKE_POSITIVE_INFINITY (n); + + /* Global methods. */ + for (i = 0; global_methods[i].name; i++) + { + JSBuiltinInfo *info; + + info = js_vm_builtin_info_create (vm); + info->global_method_proc = global_methods[i].method; + + n = &vm->globals[js_vm_intern (vm, global_methods[i].name)]; + js_vm_builtin_create (vm, n, info, NULL); + } +} diff --git a/reactos/lib/kjs/src/b_date.c b/reactos/lib/kjs/src/b_date.c new file mode 100644 index 00000000000..87815b1c13c --- /dev/null +++ b/reactos/lib/kjs/src/b_date.c @@ -0,0 +1,792 @@ +/* + * The builtin Date object. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/b_date.c,v $ + * $Id: b_date.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" +#include "rentrant.h" + +/* XXX TODO 15.13.3 -> */ + +/* + * Types and definitions. + */ + +#define GMT_DATE_FORMAT "%a, %d %b %Y %H:%M:%S GMT" + +#define MS_PER_SECOND 1000 +#define MS_PER_MINUTE (60 * MS_PER_SECOND) +#define MS_PER_HOUR (60 * MS_PER_MINUTE) +#define MS_PER_DAY (24 * MS_PER_HOUR) + +/* Class context. */ +struct date_ctx_st +{ + /* Static methods. */ + JSSymbol s_parse; + + /* Methods. */ + JSSymbol s_format; + JSSymbol s_formatGMT; + JSSymbol s_getDate; + JSSymbol s_getDay; + JSSymbol s_getHours; + JSSymbol s_getMinutes; + JSSymbol s_getMonth; + JSSymbol s_getSeconds; + JSSymbol s_getTime; + JSSymbol s_getTimezoneOffset; + JSSymbol s_getYear; + JSSymbol s_setDate; + JSSymbol s_setHours; + JSSymbol s_setMinutes; + JSSymbol s_setMonth; + JSSymbol s_setSeconds; + JSSymbol s_setTime; + JSSymbol s_setYear; + JSSymbol s_toGMTString; + JSSymbol s_toLocaleString; + JSSymbol s_UTC; +}; + +typedef struct date_ctx_st DateCtx; + +/* Date instance context. */ +struct date_instance_ctx_st +{ + time_t secs; + struct tm localtime; +}; + +typedef struct date_instance_ctx_st DateInstanceCtx; + +/* + * Static functions. + */ + +/* Global methods. */ +void +MakeTime_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSNode *result_return, + JSNode *args) +{ + if (args->u.vinteger != 4) + { + sprintf (vm->error, "MakeTime: illegal amount of argument"); + js_vm_error (vm); + } + if (!JS_IS_NUMBER (&args[1]) || !JS_IS_NUMBER (&args[2]) + || !JS_IS_NUMBER (&args[3]) || !JS_IS_NUMBER (&args[4])) + { + sprintf (vm->error, "MakeTime: illegal argument"); + js_vm_error (vm); + } + if (!JS_IS_FINITE (&args[1]) || !JS_IS_FINITE (&args[2]) + || !JS_IS_FINITE (&args[3]) || !JS_IS_FINITE (&args[4])) + { + result_return->type = JS_NAN; + } + else + { + JSInt32 hour, min, sec, ms; + + hour = js_vm_to_int32 (vm, &args[1]); + min = js_vm_to_int32 (vm, &args[2]); + sec = js_vm_to_int32 (vm, &args[3]); + ms = js_vm_to_int32 (vm, &args[4]); + + result_return->type = JS_FLOAT; + result_return->u.vfloat = (hour * MS_PER_HOUR + + min * MS_PER_MINUTE + + sec * MS_PER_SECOND + + ms); + } +} + + +void +MakeDay_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSNode *result_return, + JSNode *args) +{ + if (args->u.vinteger != 3) + { + sprintf (vm->error, "MakeDay: illegal amount of argument"); + js_vm_error (vm); + } + if (!JS_IS_NUMBER (&args[1]) || !JS_IS_NUMBER (&args[2]) + || !JS_IS_NUMBER (&args[3])) + { + sprintf (vm->error, "MakeDay: illegal argument"); + js_vm_error (vm); + } + if (!JS_IS_FINITE (&args[1]) || !JS_IS_FINITE (&args[2]) + || !JS_IS_FINITE (&args[3])) + { + result_return->type = JS_NAN; + } + else + { + JSInt32 year, month, day; + + year = js_vm_to_int32 (vm, &args[1]); + month = js_vm_to_int32 (vm, &args[2]); + day = js_vm_to_int32 (vm, &args[3]); + + sprintf (vm->error, "MakeDay: not implemented yet"); + js_vm_error (vm); + } +} + + +void +MakeDate_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSNode *result_return, + JSNode *args) +{ + if (args->u.vinteger != 2) + { + sprintf (vm->error, "MakeDate: illegal amount of argument"); + js_vm_error (vm); + } + if (!JS_IS_NUMBER (&args[1]) || !JS_IS_NUMBER (&args[2])) + { + sprintf (vm->error, "MakeDate: illegal argument"); + js_vm_error (vm); + } + if (!JS_IS_FINITE (&args[1]) || !JS_IS_FINITE (&args[2])) + { + result_return->type = JS_NAN; + } + else + { + JSInt32 day; + JSInt32 time; + + day = js_vm_to_int32 (vm, &args[1]); + time = js_vm_to_int32 (vm, &args[2]); + + result_return->type = JS_FLOAT; + result_return->u.vfloat = (day * MS_PER_DAY + time); + } +} + + +void +TimeClip_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSNode *result_return, + JSNode *args) +{ + if (args->u.vinteger != 1) + { + sprintf (vm->error, "TimeClip: illegal amount of argument"); + js_vm_error (vm); + } + if (!JS_IS_NUMBER (&args[1])) + { + sprintf (vm->error, "TimeClip: illegal argument"); + js_vm_error (vm); + } + if (!JS_IS_FINITE (&args[1])) + { + result_return->type = JS_NAN; + } + else + { + result_return->type = JS_FLOAT; + + if (args[1].type == JS_INTEGER) + result_return->u.vfloat = (double) args[1].u.vinteger; + else + result_return->u.vfloat = args[1].u.vfloat; + + if (result_return->u.vfloat > 8.64e15 + || result_return->u.vfloat < -8.64e15) + result_return->type = JS_NAN; + } +} + +/* Method proc. */ +static int +method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol method, JSNode *result_return, + JSNode *args) +{ + DateCtx *ctx = builtin_info->obj_context; + DateInstanceCtx *ictx = instance_context; + + /* The default return type is integer. */ + result_return->type = JS_INTEGER; + + /* Static methods. */ + if (method == ctx->s_parse) + { + goto not_implemented_yet; + } + /* ********************************************************************** */ + else if (method == vm->syms.s_toString) + { + if (args->u.vinteger != 0) + goto argument_error; + + if (ictx) + goto date_to_string; + else + js_vm_make_static_string (vm, result_return, "Date", 4); + } + /* ********************************************************************** */ + else if (ictx) + { + /* Methods. */ + + if (method == ctx->s_format || method == ctx->s_formatGMT) + { + struct tm tm_st; + struct tm *tm = &ictx->localtime; + char *fmt; + char *buf; + unsigned int buflen; + + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_STRING) + goto argument_type_error; + + fmt = js_string_to_c_string (vm, &args[1]); + + buflen = args[1].u.vstring->len * 2 + 1; + buf = js_malloc (vm, buflen); + + if (method == ctx->s_formatGMT) + { + js_gmtime (&ictx->secs, &tm_st); + tm = &tm_st; + } + + if (args[1].u.vstring->len == 0) + buf[0] = '\0'; + else + { + while (strftime (buf, buflen, fmt, tm) == 0) + { + /* Expand the buffer. */ + buflen *= 2; + buf = js_realloc (vm, buf, buflen); + } + } + + js_vm_make_string (vm, result_return, buf, strlen (buf)); + + js_free (fmt); + js_free (buf); + } + /* ***************************************************************** */ + else if (method == ctx->s_getDate) + { + if (args->u.vinteger != 0) + goto argument_error; + + result_return->u.vinteger = ictx->localtime.tm_mday; + } + /* ***************************************************************** */ + else if (method == ctx->s_getDay) + { + if (args->u.vinteger != 0) + goto argument_error; + + result_return->u.vinteger = ictx->localtime.tm_wday; + } + /* ***************************************************************** */ + else if (method == ctx->s_getHours) + { + if (args->u.vinteger != 0) + goto argument_error; + + result_return->u.vinteger = ictx->localtime.tm_hour; + } + /* ***************************************************************** */ + else if (method == ctx->s_getMinutes) + { + if (args->u.vinteger != 0) + goto argument_error; + + result_return->u.vinteger = ictx->localtime.tm_min; + } + /* ***************************************************************** */ + else if (method == ctx->s_getMonth) + { + if (args->u.vinteger != 0) + goto argument_error; + + result_return->u.vinteger = ictx->localtime.tm_mon; + } + /* ***************************************************************** */ + else if (method == ctx->s_getSeconds) + { + if (args->u.vinteger != 0) + goto argument_error; + + result_return->u.vinteger = ictx->localtime.tm_sec; + } + /* ***************************************************************** */ + else if (method == ctx->s_getTime) + { + if (args->u.vinteger != 0) + goto argument_error; + + result_return->type = JS_FLOAT; + result_return->u.vfloat = (double) ictx->secs * 1000; + } + /* ***************************************************************** */ + else if (method == ctx->s_getTimezoneOffset) + goto not_implemented_yet; + /* ***************************************************************** */ + else if (method == ctx->s_getYear) + { + if (args->u.vinteger != 0) + goto argument_error; + + result_return->u.vinteger = ictx->localtime.tm_year; + if (ictx->localtime.tm_year >= 100 + || ictx->localtime.tm_year < 0) + result_return->u.vinteger += 1900; + } + /* ***************************************************************** */ + else if (method == ctx->s_setDate) + { + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_INTEGER) + goto argument_type_error; + + if (1 <= args[1].u.vinteger && args[1].u.vinteger <= 31) + { + ictx->localtime.tm_mday = args[1].u.vinteger; + ictx->secs = mktime (&ictx->localtime); + } + else + goto argument_range_error; + } + /* ***************************************************************** */ + else if (method == ctx->s_setHours) + { + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_INTEGER) + goto argument_type_error; + + if (0 <= args[1].u.vinteger && args[1].u.vinteger <= 23) + { + ictx->localtime.tm_hour = args[1].u.vinteger; + ictx->secs = mktime (&ictx->localtime); + } + else + goto argument_range_error; + } + /* ***************************************************************** */ + else if (method == ctx->s_setMinutes) + { + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_INTEGER) + goto argument_type_error; + + if (0 <= args[1].u.vinteger && args[1].u.vinteger <= 59) + { + ictx->localtime.tm_min = args[1].u.vinteger; + ictx->secs = mktime (&ictx->localtime); + } + else + goto argument_range_error; + } + /* ***************************************************************** */ + else if (method == ctx->s_setMonth) + { + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_INTEGER) + goto argument_type_error; + + if (0 <= args[1].u.vinteger && args[1].u.vinteger <= 11) + { + ictx->localtime.tm_mon = args[1].u.vinteger; + ictx->secs = mktime (&ictx->localtime); + } + else + goto argument_range_error; + } + /* ***************************************************************** */ + else if (method == ctx->s_setSeconds) + { + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_INTEGER) + goto argument_type_error; + + if (0 <= args[1].u.vinteger && args[1].u.vinteger <= 59) + { + ictx->localtime.tm_sec = args[1].u.vinteger; + ictx->secs = mktime (&ictx->localtime); + } + else + goto argument_range_error; + } + /* ***************************************************************** */ + else if (method == ctx->s_setTime) + { + if (args->u.vinteger != 1) + goto argument_error; + + if (args[1].type == JS_INTEGER) + ictx->secs = args[1].u.vinteger / 1000; + else if (args[1].type == JS_FLOAT) + ictx->secs = (long) (args[1].u.vfloat / 1000); + else + goto argument_type_error; + + js_localtime (&ictx->secs, &ictx->localtime); + } + /* ***************************************************************** */ + else if (method == ctx->s_setYear) + { + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_INTEGER) + goto argument_type_error; + + ictx->localtime.tm_year = args[1].u.vinteger; + if (args[1].u.vinteger < 0 || args[1].u.vinteger >= 100) + ictx->localtime.tm_year -= 1900; + + ictx->secs = mktime (&ictx->localtime); + } + /* ***************************************************************** */ + else if (method == ctx->s_toGMTString) + { + struct tm tm_st; + char buf[1024]; /* This is enought. */ + + if (args->u.vinteger != 0) + goto argument_error; + + js_gmtime (&ictx->secs, &tm_st); + strftime (buf, sizeof (buf), GMT_DATE_FORMAT, &tm_st); + + js_vm_make_string (vm, result_return, buf, strlen (buf)); + } + /* ***************************************************************** */ + else if (method == ctx->s_toLocaleString) + { + char *cp; + char buf[1024]; /* This is enought */ + + if (args->u.vinteger != 0) + goto argument_error; + + date_to_string: + + js_asctime (&ictx->localtime, buf, sizeof (buf)); + cp = strchr (buf, '\n'); + if (cp) + *cp = '\0'; + + js_vm_make_string (vm, result_return, buf, strlen (buf)); + } + /* ***************************************************************** */ + else if (method == ctx->s_UTC) + goto not_implemented_yet; + /* ***************************************************************** */ + else + return JS_PROPERTY_UNKNOWN; + } + /* ********************************************************************** */ + else + return JS_PROPERTY_UNKNOWN; + + return JS_PROPERTY_FOUND; + + + /* + * Error handling. + */ + + not_implemented_yet: + sprintf (vm->error, "Date.%s(): not implemented yet", + js_vm_symname (vm, method)); + js_vm_error (vm); + + argument_error: + sprintf (vm->error, "Date.%s(): illegal amount of arguments", + js_vm_symname (vm, method)); + js_vm_error (vm); + + argument_type_error: + sprintf (vm->error, "Date.%s(): illegal argument", + js_vm_symname (vm, method)); + js_vm_error (vm); + + argument_range_error: + sprintf (vm->error, "Date.%s(): argument out of range", + js_vm_symname (vm, method)); + js_vm_error (vm); + + /* NOTREACHED. */ + return 0; +} + + +/* Global method proc. */ +static void +global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSNode *result_return, + JSNode *args) +{ + time_t secs; + struct tm localtime; + char buf[512]; + char *cp; + + if (args->u.vinteger > 7) + { + sprintf (vm->error, "Date(): illegal amount of arguments"); + js_vm_error (vm); + } + + /* + * We ignore our arguments and return the result of: + * `new Date ().toString ()'. + */ + + secs = time (NULL); + js_localtime (&secs, &localtime); + js_asctime (&localtime, buf, sizeof (buf)); + + cp = strchr (buf, '\n'); + if (cp) + *cp = '\0'; + + js_vm_make_string (vm, result_return, buf, strlen (buf)); +} + + +/* Property proc. */ +static int +property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol property, int set, JSNode *node) +{ + if (!set) + node->type = JS_UNDEFINED; + + return JS_PROPERTY_UNKNOWN; +} + +/* New proc. */ +static void +new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, JSNode *args, + JSNode *result_return) +{ + DateInstanceCtx *instance; + time_t seconds = 0; /* Initialized to keep compiler quiet. */ + + instance = js_calloc (vm, 1, sizeof (*instance)); + + if (args->u.vinteger == 0) + { + instance->secs = time (NULL); + js_localtime (&instance->secs, &instance->localtime); + } + else if (args->u.vinteger == 1) + goto not_implemented_yet; + else if (args->u.vinteger == 3 || args->u.vinteger == 6) + { + int i; + + for (i = 0; i < args->u.vinteger; i++) + if (args[i + 1].type != JS_INTEGER) + goto argument_type_error; + + /* Year. */ + instance->localtime.tm_year = args[1].u.vinteger; + if (args[1].u.vinteger < 0 || args[1].u.vinteger >= 100) + instance->localtime.tm_year -= 1900; + + /* Month. */ + if (0 <= args[2].u.vinteger && args[2].u.vinteger <= 11) + instance->localtime.tm_mon = args[2].u.vinteger; + else + goto argument_range_error; + + /* Day. */ + if (1 <= args[3].u.vinteger && args[3].u.vinteger <= 31) + instance->localtime.tm_mday = args[3].u.vinteger; + else + goto argument_range_error; + + if (args->u.vinteger == 6) + { + /* Sync the localtime according to year, month and day. */ + mktime (&instance->localtime); + + /* Hours. */ + if (0 <= args[4].u.vinteger && args[4].u.vinteger <= 23) + instance->localtime.tm_hour = args[4].u.vinteger; + else + goto argument_range_error; + + /* Minutes. */ + if (0 <= args[5].u.vinteger && args[5].u.vinteger <= 59) + instance->localtime.tm_min = args[5].u.vinteger; + else + goto argument_range_error; + + /* Seconds. */ + if (0 <= args[6].u.vinteger && args[6].u.vinteger <= 59) + instance->localtime.tm_sec = args[6].u.vinteger; + else + goto argument_range_error; + } + + instance->secs = mktime (&instance->localtime); + } + else + { + js_free (instance); + + sprintf (vm->error, "new Date(): illegal amount of arguments"); + js_vm_error (vm); + } + + js_vm_builtin_create (vm, result_return, builtin_info, instance); + + return; + + /* + * Error handling. + */ + + not_implemented_yet: + sprintf (vm->error, "new Date(%ld args): not implemented yet", + args->u.vinteger); + js_vm_error (vm); + + argument_type_error: + sprintf (vm->error, "new Date(): illegal argument"); + js_vm_error (vm); + + argument_range_error: + sprintf (vm->error, "new Date(): argument out of range"); + js_vm_error (vm); +} + +/* Delete proc. */ +static void +delete_proc (JSBuiltinInfo *builtin_info, void *instance_context) +{ + DateInstanceCtx *ictx = instance_context; + + if (ictx) + js_free (ictx); +} + + +/* + * Global functions. + */ + +static struct +{ + char *name; + JSBuiltinGlobalMethod method; +} global_methods[] = +{ + {"MakeTime", MakeTime_global_method}, + {"MakeDay", MakeDay_global_method}, + {"MakeDate", MakeDate_global_method}, + {"TimeClip", TimeClip_global_method}, + + {NULL, NULL}, +}; + +void +js_builtin_Date (JSVirtualMachine *vm) +{ + JSBuiltinInfo *info; + DateCtx *ctx; + JSNode *n; + int i; + + ctx = js_calloc (vm, 1, sizeof (*ctx)); + + ctx->s_format = js_vm_intern (vm, "format"); + ctx->s_formatGMT = js_vm_intern (vm, "formatGMT"); + ctx->s_getDate = js_vm_intern (vm, "getDate"); + ctx->s_getDay = js_vm_intern (vm, "getDay"); + ctx->s_getHours = js_vm_intern (vm, "getHours"); + ctx->s_getMinutes = js_vm_intern (vm, "getMinutes"); + ctx->s_getMonth = js_vm_intern (vm, "getMonth"); + ctx->s_getSeconds = js_vm_intern (vm, "getSeconds"); + ctx->s_getTime = js_vm_intern (vm, "getTime"); + ctx->s_getTimezoneOffset = js_vm_intern (vm, "getTimezoneOffset"); + ctx->s_getYear = js_vm_intern (vm, "getYear"); + ctx->s_parse = js_vm_intern (vm, "parse"); + ctx->s_setDate = js_vm_intern (vm, "setDate"); + ctx->s_setHours = js_vm_intern (vm, "setHours"); + ctx->s_setMinutes = js_vm_intern (vm, "setMinutes"); + ctx->s_setMonth = js_vm_intern (vm, "setMonth"); + ctx->s_setSeconds = js_vm_intern (vm, "setSeconds"); + ctx->s_setTime = js_vm_intern (vm, "setTime"); + ctx->s_setYear = js_vm_intern (vm, "setYear"); + ctx->s_toGMTString = js_vm_intern (vm, "toGMTString"); + ctx->s_toLocaleString = js_vm_intern (vm, "toLocaleString"); + ctx->s_UTC = js_vm_intern (vm, "UTC"); + + /* Object information. */ + + info = js_vm_builtin_info_create (vm); + + info->method_proc = method; + info->global_method_proc = global_method; + info->property_proc = property; + info->new_proc = new_proc; + info->delete_proc = delete_proc; + info->obj_context = ctx; + info->obj_context_delete = js_free; + + /* Define it. */ + n = &vm->globals[js_vm_intern (vm, "Date")]; + js_vm_builtin_create (vm, n, info, NULL); + + /* Global methods. */ + + for (i = 0; global_methods[i].name; i++) + { + info = js_vm_builtin_info_create (vm); + info->global_method_proc = global_methods[i].method; + n = &vm->globals[js_vm_intern (vm, global_methods[i].name)]; + js_vm_builtin_create (vm, n, info, NULL); + } +} diff --git a/reactos/lib/kjs/src/b_dir.c b/reactos/lib/kjs/src/b_dir.c new file mode 100644 index 00000000000..fd24aa187fa --- /dev/null +++ b/reactos/lib/kjs/src/b_dir.c @@ -0,0 +1,319 @@ +/* + * The builtin Directory object. + * Copyright (c) 1998-1999 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/b_dir.c,v $ + * $Id: b_dir.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" + +/* + * Types and definitions. + */ + +/* Class context. */ +struct dir_ctx_st +{ + /* Methods. */ + JSSymbol s_close; + JSSymbol s_open; + JSSymbol s_read; + JSSymbol s_rewind; + JSSymbol s_seek; + JSSymbol s_tell; +}; + +typedef struct dir_ctx_st DirCtx; + +/* Instance context. */ +struct dir_instance_ctx_st +{ + DIR *dir; + char *path; + + /* The virtual machine handle is needed for the delete_proc. */ + JSVirtualMachine *vm; +}; + +typedef struct dir_instance_ctx_st DirInstanceCtx; + + +/* + * Static functions. + */ + +/* Method proc. */ +static int +method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol method, JSNode *result_return, + JSNode *args) +{ + DirCtx *ctx = builtin_info->obj_context; + DirInstanceCtx *ictx = instance_context; + + /* Static methods. */ + if (method == vm->syms.s_toString) + { + if (args->u.vinteger != 0) + goto argument_error; + + if (ictx) + js_vm_make_string (vm, result_return, ictx->path, strlen (ictx->path)); + else + js_vm_make_static_string (vm, result_return, "Directory", 9); + } + /* ********************************************************************** */ + else if (ictx) + { + /* + * Instance methods. + */ + if (method == ctx->s_close) + { + if (args->u.vinteger != 0) + goto argument_error; + + if (ictx->dir) + if (closedir (ictx->dir) >= 0) + { + ictx->dir = NULL; + JS_VM_FREE_FD (vm); + } + + result_return->type = JS_BOOLEAN; + result_return->u.vboolean = ictx->dir == NULL; + } + /* ***************************************************************** */ + else if (method == ctx->s_open) + { + if (args->u.vinteger != 0) + goto argument_error; + + if (ictx->dir == NULL) + { + JS_VM_ALLOCATE_FD (vm, "Directory.open()"); + ictx->dir = opendir (ictx->path); + + if (ictx->dir == NULL) + /* Directory opening failed. */ + JS_VM_FREE_FD (vm); + } + + result_return->type = JS_BOOLEAN; + result_return->u.vboolean = ictx->dir != NULL; + } + /* ***************************************************************** */ + else if (method == ctx->s_read) + { + struct dirent *de; + + if (args->u.vinteger != 0) + goto argument_error; + if (ictx->dir == NULL) + goto not_open; + + de = readdir (ictx->dir); + if (de) + js_vm_make_string (vm, result_return, de->d_name, + strlen (de->d_name)); + else + { + result_return->type = JS_BOOLEAN; + result_return->u.vboolean = 0; + } + } + /* ***************************************************************** */ + else if (method == ctx->s_rewind) + { + if (args->u.vinteger != 0) + goto argument_error; + if (ictx->dir == NULL) + goto not_open; + + rewinddir (ictx->dir); + result_return->type = JS_UNDEFINED; + } + /* ***************************************************************** */ + else if (method == ctx->s_seek) + { + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_INTEGER) + goto argument_type_error; + if (ictx->dir == NULL) + goto not_open; + + seekdir (ictx->dir, args[1].u.vinteger); + result_return->type = JS_UNDEFINED; + } + /* ***************************************************************** */ + else if (method == ctx->s_tell) + { + if (args->u.vinteger != 0) + goto argument_error; + if (ictx->dir == NULL) + goto not_open; + + result_return->u.vinteger = telldir (ictx->dir); + if (result_return->u.vinteger < 0) + { + result_return->type = JS_BOOLEAN; + result_return->u.vboolean = 0; + } + else + result_return->type = JS_INTEGER; + } + /* ***************************************************************** */ + else + return JS_PROPERTY_UNKNOWN; + } + /* ********************************************************************** */ + else + return JS_PROPERTY_UNKNOWN; + + return JS_PROPERTY_FOUND; + + + /* + * Error handling. + */ + + argument_error: + sprintf (vm->error, "Directory.%s(): illegal amount of arguments", + js_vm_symname (vm, method)); + js_vm_error (vm); + + argument_type_error: + sprintf (vm->error, "Directory.%s(): illegal argument", + js_vm_symname (vm, method)); + js_vm_error (vm); + + not_open: + sprintf (vm->error, "Directory.%s(): directory is no opened", + js_vm_symname (vm, method)); + js_vm_error (vm); + + insecure_feature: + sprintf (vm->error, "Directory.%s(): not allowed in secure mode", + 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) +{ + /* We have no properties. */ + + if (!set) + node->type = JS_UNDEFINED; + + return JS_PROPERTY_UNKNOWN; +} + +/* New proc. */ +static void +new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, JSNode *args, + JSNode *result_return) +{ + DirInstanceCtx *instance; + if (args->u.vinteger != 1) + { + sprintf (vm->error, "new Directory(): illegal amount of arguments"); + js_vm_error (vm); + } + if (args[1].type != JS_STRING) + { + sprintf (vm->error, "new Directory(): illegal argument"); + js_vm_error (vm); + } + + instance = js_calloc (vm, 1, sizeof (*instance)); + instance->path = js_string_to_c_string (vm, &args[1]); + instance->vm = vm; + + js_vm_builtin_create (vm, result_return, builtin_info, instance); +} + +/* Delete proc. */ +static void +delete_proc (JSBuiltinInfo *builtin_info, void *instance_context) +{ + DirInstanceCtx *ictx = instance_context; + + if (ictx) + { + if (ictx->dir) + { + closedir (ictx->dir); + JS_VM_FREE_FD (ictx->vm); + } + + js_free (ictx->path); + js_free (ictx); + } +} + + +/* + * Global functions. + */ + +void +js_builtin_Directory (JSVirtualMachine *vm) +{ + JSNode *n; + JSBuiltinInfo *info; + DirCtx *ctx; + + ctx = js_calloc (vm, 1, sizeof (*ctx)); + + ctx->s_close = js_vm_intern (vm, "close"); + ctx->s_open = js_vm_intern (vm, "open"); + ctx->s_read = js_vm_intern (vm, "read"); + ctx->s_rewind = js_vm_intern (vm, "rewind"); + ctx->s_seek = js_vm_intern (vm, "seek"); + ctx->s_tell = js_vm_intern (vm, "tell"); + + /* Object information. */ + + info = js_vm_builtin_info_create (vm); + + info->method_proc = method; + info->property_proc = property; + info->new_proc = new_proc; + info->delete_proc = delete_proc; + info->obj_context = ctx; + info->obj_context_delete = js_free; + + /* Define it. */ + n = &vm->globals[js_vm_intern (vm, "Directory")]; + js_vm_builtin_create (vm, n, info, NULL); +} diff --git a/reactos/lib/kjs/src/b_file.c b/reactos/lib/kjs/src/b_file.c new file mode 100644 index 00000000000..03c1f287d15 --- /dev/null +++ b/reactos/lib/kjs/src/b_file.c @@ -0,0 +1,1012 @@ +/* + * The builtin File object. + * Copyright (c) 1998-1999 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/b_file.c,v $ + * $Id: b_file.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +/* + * Static methods. + * + * byteToString (BYTE) => string + * + chmod (string, int) => boolean + * + lstat (PATH) => array / boolean + * + remove (PATH) => boolean + * + rename (FROM, TO) => boolean + * + stat (PATH) => array / boolean + * stringToByte (STRING) => number + * + * Methods: + * + * open (MODE) => boolean + * close () => boolean + * setPosition (POSITION [, WHENCE]) => boolean + * getPosition () => integer + * eof () => boolean + * read (SIZE) => string + * readln () => string + * readByte () => integer + * write (STRING) => boolean + * writeln (STRING) => boolean + * writeByte (INTEGER) => boolean + * + ungetByte (BYTE) => boolean + * flush () => boolean + * getLength () => integer + * exists () => boolean + * error () => integer + * clearError () => true + * + * Properties: + * + * autoFlush boolean mutable + * bufferSize integer mutable + */ + +#include "jsint.h" + +#include + +/* + * Types and definitions. + */ + +#define INSECURE() \ + do { \ + if (secure_mode) \ + goto insecure_feature; \ + } while (0) + +/* Class context. */ +struct file_ctx_st +{ + /* Static methods. */ + JSSymbol s_byteToString; + JSSymbol s_chmod; + JSSymbol s_lstat; + JSSymbol s_remove; + JSSymbol s_rename; + JSSymbol s_stat; + JSSymbol s_stringToByte; + + /* Methods */ + JSSymbol s_open; + JSSymbol s_close; + JSSymbol s_setPosition; + JSSymbol s_getPosition; + JSSymbol s_eof; + JSSymbol s_read; + JSSymbol s_readln; + JSSymbol s_readByte; + JSSymbol s_write; + JSSymbol s_writeln; + JSSymbol s_writeByte; + JSSymbol s_ungetByte; + JSSymbol s_flush; + JSSymbol s_getLength; + JSSymbol s_exists; + JSSymbol s_error; + JSSymbol s_clearError; + + /* Properties. */ + JSSymbol s_autoFlush; + JSSymbol s_bufferSize; +}; + +typedef struct file_ctx_st FileCtx; + +/* Instance context. */ +struct file_instance_ctx_st +{ + /* Flags. */ + unsigned int dont_close : 1; + + char *path; + JSIOStream *stream; + + /* Needed for the delete_proc. */ + JSVirtualMachine *vm; +}; + +typedef struct file_instance_ctx_st FileInstanceCtx; + + +/* + * Static functions. + */ + +/* Method proc. */ +static int +method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol method, JSNode *result_return, + JSNode *args) +{ + FileCtx *ctx = builtin_info->obj_context; + FileInstanceCtx *ictx = instance_context; + char buf[256]; + long int li = 0; + int i = 0; + char *cp; + int secure_mode = vm->security & JS_VM_SECURE_FILE; + + /* The default result is false. */ + result_return->type = JS_BOOLEAN; + result_return->u.vboolean = 0; + + /* + * Static methods. + */ + if (method == ctx->s_byteToString) + { + if (args->u.vinteger != 1) + goto argument_error; + + i = -1; + if (args[1].type == JS_INTEGER) + { + i = args[1].u.vinteger; + if (i < 0 || i > 255) + i = -1; + } + + js_vm_make_string (vm, result_return, NULL, 1); + + if (i < 0) + result_return->u.vstring->len = 0; + else + result_return->u.vstring->data[0] = i; + } + /* ********************************************************************** */ + else if (method == ctx->s_chmod) + { + INSECURE (); + + if (args->u.vinteger != 2) + goto argument_error; + if (args[1].type != JS_STRING) + goto argument_type_error; + if (args[2].type != JS_INTEGER) + goto argument_type_error; + + result_return->type= JS_BOOLEAN; + + cp = js_string_to_c_string (vm, &args[1]); + result_return->u.vboolean = (chmod (cp, args[2].u.vinteger) == 0); + js_free (cp); + } + /* ********************************************************************** */ + else if (method == ctx->s_lstat || method == ctx->s_stat) + { + char *path; + struct stat stat_st; + int result; + + INSECURE (); + + if (args->u.vinteger != 1) + goto argument_error; + + path = js_string_to_c_string (vm, &args[1]); + +#if HAVE_LSTAT + if (method == ctx->s_lstat) + result = lstat (path, &stat_st); + else +#endif /* HAVE_LSTAT */ + result = stat (path, &stat_st); + + js_free (path); + + if (result >= 0) + { + JSNode *node; + + /* Success. */ + js_vm_make_array (vm, result_return, 13); + node = result_return->u.varray->data; + + /* dev */ + node->type = JS_INTEGER; + node->u.vinteger = stat_st.st_dev; + node++; + + /* ino */ + node->type = JS_INTEGER; + node->u.vinteger = stat_st.st_ino; + node++; + + /* mode */ + node->type = JS_INTEGER; + node->u.vinteger = stat_st.st_mode; + node++; + + /* nlink */ + node->type = JS_INTEGER; + node->u.vinteger = stat_st.st_nlink; + node++; + + /* uid */ + node->type = JS_INTEGER; + node->u.vinteger = stat_st.st_uid; + node++; + + /* gid */ + node->type = JS_INTEGER; + node->u.vinteger = stat_st.st_gid; + node++; + + /* rdev */ + node->type = JS_INTEGER; + node->u.vinteger = stat_st.st_rdev; + node++; + + /* size */ + node->type = JS_INTEGER; + node->u.vinteger = stat_st.st_size; + node++; + + /* atime */ + node->type = JS_INTEGER; + node->u.vinteger = stat_st.st_atime; + node++; + + /* mtime */ + node->type = JS_INTEGER; + node->u.vinteger = stat_st.st_mtime; + node++; + + /* ctime */ + node->type = JS_INTEGER; + node->u.vinteger = stat_st.st_ctime; + node++; + + /* blksize */ + node->type = JS_INTEGER; +#if HAVE_STAT_ST_ST_BLKSIZE + node->u.vinteger = stat_st.st_blksize; +#else /* not HAVE_STAT_ST_ST_BLKSIZE */ + node->u.vinteger = 0; +#endif /* not HAVE_STAT_ST_ST_BLKSIZE */ + node++; + + /* blocks */ + node->type = JS_INTEGER; +#if HAVE_STAT_ST_ST_BLOCKS + node->u.vinteger = stat_st.st_blocks; +#else /* not HAVE_STAT_ST_ST_BLOCKS */ + node->u.vinteger = 0; +#endif /* not HAVE_STAT_ST_ST_BLOCKS */ + } + } + /* ********************************************************************** */ + else if (method == ctx->s_remove) + { + char *path; + + INSECURE (); + + 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]); + i = remove (path); + js_free (path); + + result_return->u.vboolean = (i == 0); + } + /* ********************************************************************** */ + else if (method == ctx->s_rename) + { + char *path1; + char *path2; + + INSECURE (); + + if (args->u.vinteger != 2) + goto argument_error; + + if (args[1].type != JS_STRING || args[2].type != JS_STRING) + goto argument_type_error; + + path1 = js_string_to_c_string (vm, &args[1]); + path2 = js_string_to_c_string (vm, &args[2]); + + i = rename (path1, path2); + + js_free (path1); + js_free (path2); + + result_return->u.vboolean = (i == 0); + } + /* ********************************************************************** */ + else if (method == ctx->s_stringToByte) + { + if (args->u.vinteger != 1) + goto argument_error; + + result_return->type = JS_INTEGER; + + if (args[1].type == JS_STRING && args[1].u.vstring->len > 0) + result_return->u.vinteger = args[i].u.vstring->data[0]; + else + result_return->u.vinteger = 0; + } + /* ********************************************************************** */ + else if (method == vm->syms.s_toString) + { + if (args->u.vinteger != 0) + goto argument_error; + + if (ictx) + js_vm_make_string (vm, result_return, ictx->path, strlen (ictx->path)); + else + js_vm_make_static_string (vm, result_return, "File", 4); + } + /* ********************************************************************** */ + else if (ictx) + { + /* + * Instance methods. + */ + + if (method == ctx->s_open) + { + int readp = 0; + int writep = 0; + + INSECURE (); + + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_STRING + || args[1].u.vstring->len == 0 + || args[1].u.vstring->len > 3) + goto argument_type_error; + + i = args[1].u.vstring->len; + memcpy (buf, args[1].u.vstring->data, i); + + if (buf[i - 1] != 'b') + buf[i++] = 'b'; + buf[i] = '\0'; + + /* Check that the mode is valid. */ + if (strcmp (buf, "rb") == 0) + readp = 1; + else if (strcmp (buf, "wb") == 0) + writep = 1; + else if (strcmp (buf, "ab") == 0) + writep = 1; + else if (strcmp (buf, "r+b") == 0) + readp = writep = 1; + else if (strcmp (buf, "w+b") == 0) + readp = writep = 1; + else if (strcmp (buf, "a+b") == 0) + readp = writep = 1; + else + { + sprintf (vm->error, "File.%s(): illegal open mode \"%s\"", + js_vm_symname (vm, method), buf); + js_vm_error (vm); + } + + if (ictx->stream == NULL) + { + /* Do open. */ + JS_VM_ALLOCATE_FD (vm, "File.open()"); + ictx->stream = js_iostream_file (fopen (ictx->path, buf), readp, + writep, 1); + if (ictx->stream == NULL) + JS_VM_FREE_FD (vm); + else + result_return->u.vboolean = 1; + } + } + /* ***************************************************************** */ + else if (method == ctx->s_close) + { + if (ictx->stream != NULL) + { + int result = 0; + + if (!ictx->dont_close) + { + result = js_iostream_close (ictx->stream); + JS_VM_FREE_FD (vm); + } + + ictx->stream = NULL; + result_return->u.vboolean = result >= 0; + } + } + /* ***************************************************************** */ + else if (method == ctx->s_setPosition) + { + if (args->u.vinteger == 1) + { + if (args[1].type != JS_INTEGER) + goto argument_type_error; + li = args[1].u.vinteger; + i = SEEK_SET; + } + else if (args->u.vinteger == 2) + { + if (args[2].type == JS_INTEGER) + { + switch (args[2].u.vinteger) + { + case 1: + i = SEEK_CUR; + break; + + case 2: + i = SEEK_END; + break; + + default: + i = SEEK_SET; + break; + } + } + else + i = SEEK_SET; + } + else + goto argument_error; + + if (ictx->stream && js_iostream_seek (ictx->stream, li, i) >= 0) + result_return->u.vboolean = 1; + } + /* ***************************************************************** */ + else if (method == ctx->s_getPosition) + { + if (args->u.vinteger != 0) + goto argument_error; + + result_return->type = JS_INTEGER; + if (ictx->stream == NULL) + result_return->u.vinteger = -1; + else + result_return->u.vinteger + = js_iostream_get_position (ictx->stream); + } + /* ***************************************************************** */ + else if (method == ctx->s_eof) + { + if (args->u.vinteger != 0) + goto argument_error; + + if (ictx->stream != NULL) + result_return->u.vboolean = ictx->stream->at_eof; + } + /* ***************************************************************** */ + else if (method == ctx->s_read) + { + size_t got; + char *buffer; + + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_INTEGER || args[1].u.vinteger < 0) + goto argument_type_error; + + if (ictx->stream != NULL) + { + buffer = js_vm_alloc (vm, args[1].u.vinteger + 1); + + got = js_iostream_read (ictx->stream, buffer, + args[1].u.vinteger); + if (got < 0) + got = 0; + + js_vm_make_static_string (vm, result_return, buffer, got); + result_return->u.vstring->staticp = 0; + } + } + /* ***************************************************************** */ + else if (method == ctx->s_readln) + { + int ch; + unsigned int bufpos = 0; + unsigned int buflen = 0; + char *buffer = NULL; + + if (args->u.vinteger != 0) + goto argument_error; + + if (ictx->stream != NULL) + { + /* Flush all buffered output data. */ + js_iostream_flush (ictx->stream); + + while (1) + { + /* Process all the data we have in the buffer. */ + for (; ictx->stream->bufpos < ictx->stream->data_in_buf + && (ictx->stream->buffer[ictx->stream->bufpos] + != '\n'); + ictx->stream->bufpos++) + { + if (bufpos >= buflen) + { + buflen += 1024; + buffer = js_vm_realloc (vm, buffer, buflen); + } + buffer[bufpos++] + = ictx->stream->buffer[ictx->stream->bufpos]; + } + + if (ictx->stream->bufpos >= ictx->stream->data_in_buf) + { + int result; + + /* Read past the buffer. */ + if (ictx->stream->at_eof) + /* EOF seen. */ + break; + + /* Read more data. */ + js_iostream_fill_buffer (ictx->stream); + } + else + { + /* Got it. Skip the newline character. */ + ictx->stream->bufpos++; + break; + } + } + + /* Remove '\r' characters. */ + while (bufpos > 0) + if (buffer[bufpos - 1] == '\r') + bufpos--; + else + break; + + if (buffer == NULL) + /* An empty string. Allocate one byte. */ + buffer = js_vm_alloc (vm, 1); + + /* + * Use the data we already had. In maximum, it has only + * 1023 bytes overhead. + */ + js_vm_make_static_string (vm, result_return, buffer, bufpos); + result_return->u.vstring->staticp = 0; + } + } + /* ***************************************************************** */ + else if (method == ctx->s_readByte) + { + result_return->type = JS_INTEGER; + if (ictx->stream == NULL) + result_return->u.vinteger = -1; + else + { + retry: + if (ictx->stream->bufpos < ictx->stream->data_in_buf) + result_return->u.vinteger + = ictx->stream->buffer[ictx->stream->bufpos++]; + else + { + if (ictx->stream->at_eof) + result_return->u.vinteger = -1; + else + { + js_iostream_fill_buffer (ictx->stream); + goto retry; + } + } + } + } + /* ***************************************************************** */ + else if (method == ctx->s_write || method == ctx->s_writeln) + { + size_t wrote; + int autoflush; + + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_STRING) + goto argument_type_error; + + if (ictx->stream != NULL) + { + autoflush = ictx->stream->autoflush; + ictx->stream->autoflush = 0; + + wrote = js_iostream_write (ictx->stream, + args[1].u.vstring->data, + args[1].u.vstring->len); + if (wrote == args[1].u.vstring->len) + { + /* Success. */ + result_return->u.vboolean = 1; + + if (method == ctx->s_writeln) + if (js_iostream_write (ictx->stream, + JS_HOST_LINE_BREAK, + JS_HOST_LINE_BREAK_LEN) < 0) + /* No, it was not a success. */ + result_return->u.vboolean = 0; + } + + ictx->stream->autoflush = autoflush; + if (autoflush) + js_iostream_flush (ictx->stream); + } + } + /* ***************************************************************** */ + else if (method == ctx->s_writeByte) + { + unsigned char buf[1]; + + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_INTEGER) + goto argument_type_error; + + buf[0] = args[1].u.vinteger; + + if (ictx->stream != NULL) + result_return->u.vboolean + = js_iostream_write (ictx->stream, buf, 1) >= 0; + } + /* ***************************************************************** */ + else if (method == ctx->s_ungetByte) + { + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_INTEGER) + goto argument_type_error; + + if (ictx->stream != NULL) + result_return->u.vboolean + = js_iostream_unget (ictx->stream, args[1].u.vinteger); + } + /* ***************************************************************** */ + else if (method == ctx->s_flush) + { + if (args->u.vinteger != 0) + goto argument_error; + + if (ictx->stream != NULL && js_iostream_flush (ictx->stream) >= 0) + result_return->u.vboolean = 1; + } + /* ***************************************************************** */ + else if (method == ctx->s_getLength) + { + if (args->u.vinteger != 0) + goto argument_error; + + /* The default error code is an integer -1. */ + result_return->type = JS_INTEGER; + result_return->u.vinteger = -1; + + if (ictx->stream != NULL) + result_return->u.vinteger + = js_iostream_get_length (ictx->stream); + } + /* ***************************************************************** */ + else if (method == ctx->s_exists) + { + if (args->u.vinteger != 0) + goto argument_error; + + if (ictx->stream) + { + /* Since we have opened the file, it must exist. */ + result_return->u.vboolean = 1; + } + else + { + struct stat stat_st; + + if (stat (ictx->path, &stat_st) >= 0) + result_return->u.vboolean = 1; + } + } + /* ***************************************************************** */ + else if (method == ctx->s_error) + { + if (args->u.vinteger != 0) + goto argument_error; + + result_return->type = JS_INTEGER; + if (ictx->stream == NULL) + result_return->u.vinteger = -1; + else + result_return->u.vinteger = ictx->stream->error; + } + /* ***************************************************************** */ + else if (method == ctx->s_clearError) + { + if (args->u.vinteger != 0) + goto argument_error; + + if (ictx->stream != NULL) + { + ictx->stream->error = 0; + result_return->u.vboolean = 1; + } + } + /* ***************************************************************** */ + else + return JS_PROPERTY_UNKNOWN; + } + else + return JS_PROPERTY_UNKNOWN; + + return JS_PROPERTY_FOUND; + + + /* + * Error handling. + */ + + argument_error: + sprintf (vm->error, "File.%s(): illegal amount of arguments", + js_vm_symname (vm, method)); + js_vm_error (vm); + + argument_type_error: + sprintf (vm->error, "File.%s(): illegal argument", + js_vm_symname (vm, method)); + js_vm_error (vm); + + insecure_feature: + sprintf (vm->error, "File.%s(): not allowed in secure mode", + 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) +{ + FileCtx *ctx = builtin_info->obj_context; + FileInstanceCtx *ictx = instance_context; + + if (ictx) + { + /* Instance properties. */ + if (property == ctx->s_autoFlush) + { + if (ictx->stream == NULL) + goto not_open; + + if (set) + { + if (node->type != JS_BOOLEAN) + goto argument_type_error; + + ictx->stream->autoflush = node->u.vboolean; + } + else + { + node->type = JS_BOOLEAN; + node->u.vboolean = ictx->stream->autoflush; + } + } + /* ***************************************************************** */ + else if (property == ctx->s_bufferSize) + { + if (ictx->stream == NULL) + goto not_open; + + if (set) + { + unsigned char *buf; + unsigned int len; + + if (node->type != JS_INTEGER) + goto argument_type_error; + + js_iostream_flush (ictx->stream); + + len = node->u.vinteger; + buf = js_realloc (vm, ictx->stream->buffer, len); + + ictx->stream->buflen = len; + ictx->stream->buffer = buf; + } + else + { + node->type = JS_INTEGER; + node->u.vinteger = ictx->stream->buflen; + } + } + /* ***************************************************************** */ + else + { + if (!set) + node->type = JS_UNDEFINED; + + return JS_PROPERTY_UNKNOWN; + } + } + else + { + if (!set) + node->type = JS_UNDEFINED; + + return JS_PROPERTY_UNKNOWN; + } + + return JS_PROPERTY_FOUND; + + + /* Error handling. */ + + argument_type_error: + sprintf (vm->error, "File.%s: illegal value", + js_vm_symname (vm, property)); + js_vm_error (vm); + + not_open: + sprintf (vm->error, "File.%s: the stream is not opened", + 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) +{ + FileInstanceCtx *instance; + + if (args->u.vinteger != 1) + { + sprintf (vm->error, "new File(): illegal amount of arguments"); + js_vm_error (vm); + } + if (args[1].type != JS_STRING) + { + sprintf (vm->error, "new File(): illegal argument"); + js_vm_error (vm); + } + + instance = js_calloc (vm, 1, sizeof (*instance)); + instance->path = js_string_to_c_string (vm, &args[1]); + instance->vm = vm; + + js_vm_builtin_create (vm, result_return, builtin_info, instance); +} + +/* Delete proc. */ +static void +delete_proc (JSBuiltinInfo *builtin_info, void *instance_context) +{ + FileInstanceCtx *ictx = instance_context; + + if (ictx) + { + if (ictx->stream) + { + if (!ictx->dont_close) + { + js_iostream_close (ictx->stream); + JS_VM_FREE_FD (ictx->vm); + } + + ictx->stream = NULL; + } + + js_free (ictx->path); + js_free (ictx); + } +} + +/* + * Global functions. + */ + +void +js_builtin_File (JSVirtualMachine *vm) +{ + JSNode *n; + JSBuiltinInfo *info; + FileCtx *ctx; + + ctx = js_calloc (vm, 1, sizeof (*ctx)); + + ctx->s_byteToString = js_vm_intern (vm, "byteToString"); + ctx->s_chmod = js_vm_intern (vm, "chmod"); + ctx->s_lstat = js_vm_intern (vm, "lstat"); + ctx->s_remove = js_vm_intern (vm, "remove"); + ctx->s_rename = js_vm_intern (vm, "rename"); + ctx->s_stat = js_vm_intern (vm, "stat"); + ctx->s_stringToByte = js_vm_intern (vm, "stringToByte"); + + ctx->s_open = js_vm_intern (vm, "open"); + ctx->s_close = js_vm_intern (vm, "close"); + ctx->s_setPosition = js_vm_intern (vm, "setPosition"); + ctx->s_getPosition = js_vm_intern (vm, "getPosition"); + ctx->s_eof = js_vm_intern (vm, "eof"); + ctx->s_read = js_vm_intern (vm, "read"); + ctx->s_readln = js_vm_intern (vm, "readln"); + ctx->s_readByte = js_vm_intern (vm, "readByte"); + ctx->s_write = js_vm_intern (vm, "write"); + ctx->s_writeln = js_vm_intern (vm, "writeln"); + ctx->s_writeByte = js_vm_intern (vm, "writeByte"); + ctx->s_ungetByte = js_vm_intern (vm, "ungetByte"); + ctx->s_flush = js_vm_intern (vm, "flush"); + ctx->s_getLength = js_vm_intern (vm, "getLength"); + ctx->s_exists = js_vm_intern (vm, "exists"); + ctx->s_error = js_vm_intern (vm, "error"); + ctx->s_clearError = js_vm_intern (vm, "clearError"); + + ctx->s_autoFlush = js_vm_intern (vm, "autoFlush"); + ctx->s_bufferSize = js_vm_intern (vm, "bufferSize"); + + + /* Object information. */ + + info = js_vm_builtin_info_create (vm); + + info->method_proc = method; + info->property_proc = property; + info->new_proc = new_proc; + info->delete_proc = delete_proc; + info->obj_context = ctx; + info->obj_context_delete = js_free; + + /* Define it. */ + n = &vm->globals[js_vm_intern (vm, "File")]; + js_vm_builtin_create (vm, n, info, NULL); +} + + +void +js_builtin_File_new (JSVirtualMachine *vm, JSNode *result_return, + char *path, JSIOStream *stream, int dont_close) +{ + JSNode *n; + FileInstanceCtx *ictx; + + /* Lookup our context. */ + n = &vm->globals[js_vm_intern (vm, "File")]; + + /* Create a file instance. */ + ictx = js_calloc (vm, 1, sizeof (*ictx)); + ictx->path = js_strdup (vm, path); + ictx->stream = stream; + ictx->dont_close = dont_close; + ictx->vm = vm; + + /* Create the builtin. */ + js_vm_builtin_create (vm, result_return, n->u.vbuiltin->info, ictx); +} diff --git a/reactos/lib/kjs/src/b_func.c b/reactos/lib/kjs/src/b_func.c new file mode 100644 index 00000000000..40b4e9305d1 --- /dev/null +++ b/reactos/lib/kjs/src/b_func.c @@ -0,0 +1,78 @@ +/* + * The builtin Function object. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/b_func.c,v $ + * $Id: b_func.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" + +/* + * Static functions. + */ + +/* Method proc. */ +static int +method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol method, JSNode *result_return, + JSNode *args) +{ + return JS_PROPERTY_UNKNOWN; +} + +/* Property proc. */ +static int +property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol property, int set, JSNode *node) +{ + JSNode *n = instance_context; + + if (!set) + node->type = JS_UNDEFINED; + + return JS_PROPERTY_UNKNOWN; +} + + +/* + * Global functions. + */ + +void +js_builtin_Function (JSVirtualMachine *vm) +{ + JSNode *n; + JSBuiltinInfo *info; + + info = js_vm_builtin_info_create (vm); + vm->prim[JS_FUNC] = info; + + info->method_proc = method; + info->property_proc = property; + + /* Define it. */ + n = &vm->globals[js_vm_intern (vm, "Function")]; + js_vm_builtin_create (vm, n, info, NULL); +} diff --git a/reactos/lib/kjs/src/b_math.c b/reactos/lib/kjs/src/b_math.c new file mode 100644 index 00000000000..8a25c9f13b1 --- /dev/null +++ b/reactos/lib/kjs/src/b_math.c @@ -0,0 +1,511 @@ +/* + * The builtin Math object. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/b_math.c,v $ + * $Id: b_math.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" +#include "rentrant.h" + +/* + * Types and definitions. + */ + +#ifndef M_E +#define M_E 2.71828182845904523536028747135266250 +#endif + +#ifndef M_LN10 +#define M_LN10 2.302585092994046 +#endif + +#ifndef M_LN2 +#define M_LN2 0.693147180559945309417232121458176568 +#endif + +#ifndef M_LOG10E +#define M_LOG10E 0.434294481903251827651128918916605082 +#endif + +#ifndef M_LOG2E +#define M_LOG2E 1.44269504088896340735992468100189214 +#endif + +#ifndef M_PI +#define M_PI 3.14159265358979323846264338327950288 +#endif + +#ifndef M_SQRT1_2 +#define M_SQRT1_2 0.707106781186547524400844362104849039 +#endif + +#ifndef M_SQRT2 +#define M_SQRT2 1.41421356237309504880168872420969808 +#endif + + +#define ONE_ARG() \ + do { \ + JSNode cvt; \ + \ + if (args->u.vinteger != 1) \ + goto argument_error; \ + \ + js_vm_to_number (vm, &args[1], &cvt); \ + if (cvt.type == JS_INTEGER) \ + d = (double) cvt.u.vinteger; \ + else if (cvt.type == JS_FLOAT) \ + d = cvt.u.vfloat; \ + else \ + { \ + /* Must be NaN. */ \ + result_return->type = JS_NAN; \ + goto done; \ + } \ + } while (0) + +#define TWO_ARGS() \ + do { \ + JSNode cvt; \ + \ + if (args->u.vinteger != 2) \ + goto argument_error; \ + \ + js_vm_to_number (vm, &args[1], &cvt); \ + if (cvt.type == JS_INTEGER) \ + d = (double) cvt.u.vinteger; \ + else if (cvt.type == JS_FLOAT) \ + d = cvt.u.vfloat; \ + else \ + { \ + /* Must be NaN. */ \ + result_return->type = JS_NAN; \ + goto done; \ + } \ + \ + js_vm_to_number (vm, &args[2], &cvt); \ + if (cvt.type == JS_INTEGER) \ + d2 = (double) args[1].u.vinteger; \ + else if (cvt.type == JS_FLOAT) \ + d2 = cvt.u.vfloat; \ + else \ + { \ + /* Must be NaN. */ \ + result_return->type = JS_NAN; \ + goto done; \ + } \ + \ + } while (0) + +/* Class context. */ +struct math_ctx_st +{ + JSSymbol s_abs; + JSSymbol s_acos; + JSSymbol s_asin; + JSSymbol s_atan; + JSSymbol s_atan2; + JSSymbol s_ceil; + JSSymbol s_cos; + JSSymbol s_exp; + JSSymbol s_floor; + JSSymbol s_log; + JSSymbol s_max; + JSSymbol s_min; + JSSymbol s_pow; + JSSymbol s_random; + JSSymbol s_round; + JSSymbol s_seed; + JSSymbol s_sin; + JSSymbol s_sqrt; + JSSymbol s_tan; + + JSSymbol s_E; + JSSymbol s_LN10; + JSSymbol s_LN2; + JSSymbol s_LOG10E; + JSSymbol s_LOG2E; + JSSymbol s_PI; + JSSymbol s_SQRT1_2; + JSSymbol s_SQRT2; + + void *drand48_context; +}; + +typedef struct math_ctx_st MathCtx; + +/* + * Static functions. + */ + +/* Method proc. */ +static int +method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol method, JSNode *result_return, + JSNode *args) +{ + MathCtx *ctx = builtin_info->obj_context; + double d, d2; + int i; + + /* The default return value. */ + result_return->type = JS_FLOAT; + + if (method == ctx->s_abs) + { + ONE_ARG (); + result_return->u.vfloat = fabs (d); + } + /* ********************************************************************** */ + else if (method == ctx->s_acos) + { + ONE_ARG (); + result_return->u.vfloat = acos (d); + } + /* ********************************************************************** */ + else if (method == ctx->s_asin) + { + ONE_ARG (); + result_return->u.vfloat = asin (d); + } + /* ********************************************************************** */ + else if (method == ctx->s_atan) + { + ONE_ARG (); + result_return->u.vfloat = atan (d); + } + /* ********************************************************************** */ + else if (method == ctx->s_atan2) + { + TWO_ARGS (); + result_return->u.vfloat = atan2 (d, d2); + } + /* ********************************************************************** */ + else if (method == ctx->s_ceil) + { + ONE_ARG (); + result_return->u.vfloat = ceil (d); + } + /* ********************************************************************** */ + else if (method == ctx->s_cos) + { + ONE_ARG (); + result_return->u.vfloat = cos (d); + } + /* ********************************************************************** */ + else if (method == ctx->s_exp) + { + ONE_ARG (); + result_return->u.vfloat = exp (d); + } + /* ********************************************************************** */ + else if (method == ctx->s_floor) + { + ONE_ARG (); + result_return->u.vfloat = floor (d); + } + /* ********************************************************************** */ + else if (method == ctx->s_log) + { + ONE_ARG (); + result_return->u.vfloat = log (d); + } + /* ********************************************************************** */ + else if (method == ctx->s_max || method == ctx->s_min) + { + JSNode cvt; + + if (args->u.vinteger < 1) + goto argument_error; + + /* Take the initial argument. */ + js_vm_to_number (vm, &args[1], &cvt); + if (cvt.type == JS_NAN) + { + result_return->type = JS_NAN; + goto done; + } + if (cvt.type == JS_INTEGER) + d = (double) cvt.u.vinteger; + else + d = cvt.u.vfloat; + + /* Handle the rest. */ + for (i = 1; i < args->u.vinteger; i++) + { + js_vm_to_number (vm, &args[1], &cvt); + if (cvt.type == JS_NAN) + { + result_return->type = JS_NAN; + goto done; + } + if (cvt.type == JS_INTEGER) + d2 = (double) cvt.u.vinteger; + else + d2 = cvt.u.vfloat; + + if (method == ctx->s_max) + { + if (d2 > d) + d = d2; + } + else + { + if (d2 < d) + d = d2; + } + } + + result_return->type = JS_FLOAT; + result_return->u.vfloat = d; + } + /* ********************************************************************** */ + else if (method == ctx->s_pow) + { + TWO_ARGS (); + result_return->u.vfloat = pow (d, d2); + } + /* ********************************************************************** */ + else if (method == ctx->s_random) + { + if (args->u.vinteger != 0) + goto argument_error; + + /* js_srand48 (ctx->drand48_context, time (NULL)); */ + js_drand48 (ctx->drand48_context, &result_return->u.vfloat); + } + /* ********************************************************************** */ + else if (method == ctx->s_round) + { + ONE_ARG (); + result_return->type = JS_INTEGER; + result_return->u.vinteger = (long) (d + 0.5); + } + /* ********************************************************************** */ + else if (method == ctx->s_seed) + { + ONE_ARG (); + js_srand48 (ctx->drand48_context, (long) d); + result_return->type = JS_UNDEFINED; + } + /* ********************************************************************** */ + else if (method == ctx->s_sin) + { + ONE_ARG (); + result_return->u.vfloat = sin (d); + } + /* ********************************************************************** */ + else if (method == ctx->s_sqrt) + { + ONE_ARG (); + result_return->u.vfloat = sqrt (d); + } + /* ********************************************************************** */ + else if (method == ctx->s_tan) + { + ONE_ARG (); + result_return->u.vfloat = tan (d); + } + /* ********************************************************************** */ + else if (method == vm->syms.s_toString) + { + js_vm_make_static_string (vm, result_return, "Math", 4); + } + /* ********************************************************************** */ + else + return JS_PROPERTY_UNKNOWN; + + done: + + return JS_PROPERTY_FOUND; + + + /* + * Error handling. + */ + + argument_error: + sprintf (vm->error, "Math.%s(): illegal amount of arguments", + js_vm_symname (vm, method)); + js_vm_error (vm); + + argument_type_error: + sprintf (vm->error, "Math.%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) +{ + MathCtx *ctx = builtin_info->obj_context; + + /* The default result is float. */ + node->type = JS_FLOAT; + + if (property == ctx->s_E) + { + if (set) + goto immutable; + + node->u.vfloat = M_E; + } + else if (property == ctx->s_LN10) + { + if (set) + goto immutable; + + node->u.vfloat = M_LN10; + } + else if (property == ctx->s_LN2) + { + if (set) + goto immutable; + + node->u.vfloat = M_LN2; + } + else if (property == ctx->s_LOG10E) + { + if (set) + goto immutable; + + node->u.vfloat = M_LOG10E; + } + else if (property == ctx->s_LOG2E) + { + if (set) + goto immutable; + + node->u.vfloat = M_LOG2E; + } + else if (property == ctx->s_PI) + { + if (set) + goto immutable; + + node->u.vfloat = M_PI; + } + else if (property == ctx->s_SQRT1_2) + { + if (set) + goto immutable; + + node->u.vfloat = M_SQRT1_2; + } + else if (property == ctx->s_SQRT2) + { + if (set) + goto immutable; + + node->u.vfloat = M_SQRT2; + } + else + { + if (!set) + node->type = JS_UNDEFINED; + + return JS_PROPERTY_UNKNOWN; + } + + return JS_PROPERTY_FOUND; + + + /* + * Error handling. + */ + + immutable: + sprintf (vm->error, "Math.%s: immutable property", + js_vm_symname (vm, property)); + js_vm_error (vm); + + /* NOTREACHED. */ + return 0; +} + + +/* + * Global functions. + */ + +void +js_builtin_Math (JSVirtualMachine *vm) +{ + JSBuiltinInfo *info; + MathCtx *ctx; + JSNode *n; + + ctx = js_calloc (vm, 1, sizeof (*ctx)); + + ctx->s_abs = js_vm_intern (vm, "abs"); + ctx->s_acos = js_vm_intern (vm, "acos"); + ctx->s_asin = js_vm_intern (vm, "asin"); + ctx->s_atan = js_vm_intern (vm, "atan"); + ctx->s_atan2 = js_vm_intern (vm, "atan2"); + ctx->s_ceil = js_vm_intern (vm, "ceil"); + ctx->s_cos = js_vm_intern (vm, "cos"); + ctx->s_exp = js_vm_intern (vm, "exp"); + ctx->s_floor = js_vm_intern (vm, "floor"); + ctx->s_log = js_vm_intern (vm, "log"); + ctx->s_max = js_vm_intern (vm, "max"); + ctx->s_min = js_vm_intern (vm, "min"); + ctx->s_pow = js_vm_intern (vm, "pow"); + ctx->s_random = js_vm_intern (vm, "random"); + ctx->s_round = js_vm_intern (vm, "round"); + ctx->s_seed = js_vm_intern (vm, "seed"); + ctx->s_sin = js_vm_intern (vm, "sin"); + ctx->s_sqrt = js_vm_intern (vm, "sqrt"); + ctx->s_tan = js_vm_intern (vm, "tan"); + + ctx->s_E = js_vm_intern (vm, "E"); + ctx->s_LN10 = js_vm_intern (vm, "LN10"); + ctx->s_LN2 = js_vm_intern (vm, "LN2"); + ctx->s_LOG10E = js_vm_intern (vm, "LOG10E"); + ctx->s_LOG2E = js_vm_intern (vm, "LOG2E"); + ctx->s_PI = js_vm_intern (vm, "PI"); + ctx->s_SQRT1_2 = js_vm_intern (vm, "SQRT1_2"); + ctx->s_SQRT2 = js_vm_intern (vm, "SQRT2"); + + ctx->drand48_context = js_drand48_create (vm); + + /* 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, "Math")]; + js_vm_builtin_create (vm, n, info, NULL); +} diff --git a/reactos/lib/kjs/src/b_number.c b/reactos/lib/kjs/src/b_number.c new file mode 100644 index 00000000000..28da8260893 --- /dev/null +++ b/reactos/lib/kjs/src/b_number.c @@ -0,0 +1,320 @@ +/* + * The builtin Number object. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/b_number.c,v $ + * $Id: b_number.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +/* + * Standard: ECMAScript-2.0.draft-22-Apr-98 + */ + +#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); +} diff --git a/reactos/lib/kjs/src/b_object.c b/reactos/lib/kjs/src/b_object.c new file mode 100644 index 00000000000..5ab588ade8c --- /dev/null +++ b/reactos/lib/kjs/src/b_object.c @@ -0,0 +1,195 @@ +/* + * The builtin Object object. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/b_object.c,v $ + * $Id: b_object.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" + +/* + * 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 > 1) + { + sprintf (vm->error, "Object(): illegal amount of arguments"); + js_vm_error (vm); + } + if (args->u.vinteger == 0 + || (args->u.vinteger == 1 + && (args[1].type == JS_NULL + || args[1].type == JS_UNDEFINED))) + { + /* Create a fresh new object. */ + result_return->type = JS_OBJECT; + result_return->u.vobject = js_vm_object_new (vm); + } + else + { + /* We have one argument. Call ToObject() for it. */ + js_vm_to_object (vm, &args[1], result_return); + } +} + +/* Method proc. */ +static int +method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol method, JSNode *result_return, + JSNode *args) +{ + JSNode *n = instance_context; + + if (method == vm->syms.s_toSource) + { + char *source; + + if (instance_context) + { + result_return->type = JS_UNDEFINED; + /* XXX 15.2.4.3 */ + } + else + { + source = "new Object()"; + js_vm_make_static_string (vm, result_return, source, + strlen (source)); + } + } + /* ********************************************************************** */ + else if (method == vm->syms.s_toString) + { + if (instance_context) + js_vm_make_static_string (vm, result_return, "[object Object]", 15); + else + js_vm_make_static_string (vm, result_return, "Object", 6); + } + /* ********************************************************************** */ + else if (method == vm->syms.s_valueOf) + { + if (instance_context) + JS_COPY (result_return, n); + else + { + n = &vm->globals[js_vm_intern (vm, "Object")]; + JS_COPY (result_return, n); + } + } + /* ********************************************************************** */ + else + return JS_PROPERTY_UNKNOWN; + + return JS_PROPERTY_FOUND; +} + + +/* Property proc. */ +static int +property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol property, int set, JSNode *node) +{ + if (!set) + node->type = JS_UNDEFINED; + + return JS_PROPERTY_UNKNOWN; +} + +/* New proc. */ +static void +new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, JSNode *args, + JSNode *result_return) +{ + if (args->u.vinteger == 0) + { + return_native_object: + result_return->type = JS_OBJECT; + result_return->u.vobject = js_vm_object_new (vm); + + /* Set the [[Prototype]] and [[Class]] properties. */ + /* XXX 15.2.2.2 */ + } + else if (args->u.vinteger == 1) + { + switch (args[1].type) + { + case JS_OBJECT: + JS_COPY (result_return, &args[1]); + break; + + case JS_STRING: + case JS_BOOLEAN: + case JS_INTEGER: + case JS_FLOAT: + case JS_NAN: + js_vm_to_object (vm, &args[1], result_return); + break; + + case JS_NULL: + case JS_UNDEFINED: + goto return_native_object; + break; + + default: + /* The rest are implementation dependent. */ + JS_COPY (result_return, &args[1]); + break; + } + } + else + { + sprintf (vm->error, "new Object(): illegal amount of arguments"); + js_vm_error (vm); + } +} + + +/* + * Global functions. + */ + +void +js_builtin_Object (JSVirtualMachine *vm) +{ + JSNode *n; + JSBuiltinInfo *info; + + info = js_vm_builtin_info_create (vm); + vm->prim[JS_OBJECT] = info; + + info->global_method_proc = global_method; + info->method_proc = method; + info->property_proc = property; + info->new_proc = new_proc; + + /* Define it. */ + n = &vm->globals[js_vm_intern (vm, "Object")]; + js_vm_builtin_create (vm, n, info, NULL); +} diff --git a/reactos/lib/kjs/src/b_regexp.c b/reactos/lib/kjs/src/b_regexp.c new file mode 100644 index 00000000000..d5b1d1f2f0f --- /dev/null +++ b/reactos/lib/kjs/src/b_regexp.c @@ -0,0 +1,1136 @@ +/* + * The builtin RegExp object. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/b_regexp.c,v $ + * $Id: b_regexp.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" +#include "regex.h" + +/* + * Types and definitions. + */ + +/* These must be in sync with the values, found from `../jsc/asm.js'. */ +#define JS_REGEXP_FLAG_G 0x01 +#define JS_REGEXP_FLAG_I 0x02 + +/* Class context. */ +struct regexp_ctx_st +{ + /* Static properties. */ + JSSymbol s_S1; + JSSymbol s_S2; + JSSymbol s_S3; + JSSymbol s_S4; + JSSymbol s_S5; + JSSymbol s_S6; + JSSymbol s_S7; + JSSymbol s_S8; + JSSymbol s_S9; + JSSymbol s_S_; + JSSymbol s_input; + JSSymbol s_lastMatch; + JSSymbol s_lastParen; + JSSymbol s_leftContext; + JSSymbol s_multiline; + JSSymbol s_rightContext; + + /* Properties. */ + JSSymbol s_global; + JSSymbol s_ignoreCase; + JSSymbol s_lastIndex; + JSSymbol s_source; + + /* Methods. */ + JSSymbol s_compile; + JSSymbol s_exec; + JSSymbol s_test; + + /* Data that is needed for the static properties. */ + + JSNode input; + struct re_registers regs; +}; + +typedef struct regexp_ctx_st RegexpCtx; + +/* RegExp instance context. */ +struct regexp_instance_ctx_st +{ + /* The source for this regexp. */ + char *source; + unsigned int source_len; + + /* Flags. */ + unsigned int global : 1; + unsigned int ignore_case : 1; + unsigned int immutable : 1; + + /* Compiled pattern. */ + struct re_pattern_buffer compiled; + + /* The index from which the next match is started. */ + unsigned int last_index; +}; + +typedef struct regexp_instance_ctx_st RegexpInstanceCtx; + + +/* + * Prorototypes for some static functions. + */ + +static void new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + JSNode *args, JSNode *result_return); + + +/* + * Static functions. + */ + +/* A helper for RegExp.exec(). XXX Check the compliancy. */ +static void +do_exec (JSVirtualMachine *vm, RegexpCtx *ctx, RegexpInstanceCtx *ictx, + char *input, unsigned int input_len, JSNode *result_return) +{ + int result; + int i, j; + + result = re_search (&ictx->compiled, input, input_len, + ictx->global ? ictx->last_index : 0, + input_len, &ctx->regs); + + if (result < 0) + { + result_return->type = JS_NULL; + return; + } + + /* Success. Count how many matches we had. */ + for (i = 0; i < ctx->regs.num_regs && ctx->regs.start[i] >= 0; i++) + ; + + /* Create the result array and enter the sub-matches. */ + js_vm_make_array (vm, result_return, i); + + for (j = 0; j < i; j++) + js_vm_make_string (vm, &result_return->u.varray->data[j], + input + ctx->regs.start[j], + ctx->regs.end[j] - ctx->regs.start[j]); + + ictx->last_index = ctx->regs.end[0]; +} + +/* Method proc. */ +static int +method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol method, JSNode *result_return, + JSNode *args) +{ + RegexpCtx *ctx = builtin_info->obj_context; + RegexpInstanceCtx *ictx = instance_context; + int result; + int i; + + /* Set the default return value. */ + result_return->type = JS_BOOLEAN; + result_return->u.vboolean = 1; + + /* Static methods. */ + if (method == vm->syms.s_toString) + { + if (ictx) + js_vm_make_string (vm, result_return, ictx->source, ictx->source_len); + else + js_vm_make_static_string (vm, result_return, "RegExp", 6); + } + /* ********************************************************************** */ + else if (ictx) + { + /* Methods */ + + if (method == ctx->s_compile) + { + int global = 0; + int ignore_case = 0; + const char *error; + JSNode *pattern; + JSNode pattern_cvt; + + if (ictx->immutable) + goto immutable; + + if (args->u.vinteger != 1 && args->u.vinteger != 2) + goto argument_error; + + if (args[1].type == JS_STRING) + pattern = &args[1]; + else + { + js_vm_to_string (vm, &args[1], &pattern_cvt); + pattern = &pattern_cvt; + } + + if (args->u.vinteger == 2) + { + JSNode *flags; + JSNode cvt; + + if (args[2].type == JS_STRING) + flags = &args[2]; + else + { + js_vm_to_string (vm, &args[2], &cvt); + flags = &cvt; + } + + for (i = 0; i < flags->u.vstring->len; i++) + switch (flags->u.vstring->data[i]) + { + case 'g': + global = 1; + break; + + case 'i': + ignore_case = 1; + break; + + default: + sprintf (vm->error, "new RegExp(): illegal flag `%c'", + flags->u.vstring->data[i]); + js_vm_error (vm); + break; + } + } + + if (ictx->source) + js_free (ictx->source); + + ictx->source_len = pattern->u.vstring->len; + ictx->source = js_malloc (vm, ictx->source_len); + memcpy (ictx->source, pattern->u.vstring->data, ictx->source_len); + + ictx->global = global; + ictx->ignore_case = ignore_case; + + if (ictx->compiled.fastmap) + js_free (ictx->compiled.fastmap); + + memset (&ictx->compiled, 0, sizeof (ictx->compiled)); + + if (ictx->ignore_case) + ictx->compiled.translate = js_latin1_tolower; + + error = re_compile_pattern (ictx->source, ictx->source_len, + &ictx->compiled); + if (error) + { + sprintf (vm->error, + "RegExp.%s(): compilation of the expression failed: %s", + js_vm_symname (vm, method), error); + js_vm_error (vm); + } + ictx->compiled.fastmap = js_malloc (vm, 256); + re_compile_fastmap (&ictx->compiled); + } + /* ***************************************************************** */ + else if (method == ctx->s_exec) + { + char *input; + unsigned int input_len; + JSNode *input_str; + JSNode cvt; + + if (args->u.vinteger == 0) + { + if (ctx->input.type == JS_STRING) + input_str = &ctx->input; + else + { + js_vm_to_string (vm, &ctx->input, &cvt); + input_str = &cvt; + } + + input = input_str->u.vstring->data; + input_len = input_str->u.vstring->len; + } + else if (args->u.vinteger == 1) + { + if (args[1].type == JS_STRING) + input_str = &args[1]; + else + { + js_vm_to_string (vm, &args[1], &cvt); + input_str = &cvt; + } + + input = input_str->u.vstring->data; + input_len = input_str->u.vstring->len; + + /* Set the input property to the class context. */ + JS_COPY (&ctx->input, input_str); + } + else + goto argument_error; + + do_exec (vm, ctx, ictx, input, input_len, result_return); + } + /* ***************************************************************** */ + else if (method == ctx->s_test) + { + char *input; + unsigned int input_len; + JSNode *input_str; + JSNode cvt; + + if (args->u.vinteger == 0) + { + if (ctx->input.type == JS_STRING) + input_str = &ctx->input; + else + { + js_vm_to_string (vm, &ctx->input, &cvt); + input_str = &cvt; + } + + input = input_str->u.vstring->data; + input_len = input_str->u.vstring->len; + } + else if (args->u.vinteger == 1) + { + if (args[1].type == JS_STRING) + input_str = &args[1]; + else + { + js_vm_to_string (vm, &args[1], &cvt); + input_str = &cvt; + } + + input = input_str->u.vstring->data; + input_len = input_str->u.vstring->len; + + /* Set the input property to the class context. */ + JS_COPY (&ctx->input, input_str); + } + else + goto argument_error; + + result = re_search (&ictx->compiled, input, input_len, + ictx->global ? ictx->last_index : 0, + input_len, &ctx->regs); + + result_return->type = JS_BOOLEAN; + result_return->u.vboolean = result >= 0; + + if (result >= 0) + /* ctx->regs.num_regs can be 0. Or can it??? */ + ictx->last_index = ctx->regs.end[0]; + } + /* ***************************************************************** */ + else + return JS_PROPERTY_UNKNOWN; + } + /* ********************************************************************** */ + else + return JS_PROPERTY_UNKNOWN; + + return JS_PROPERTY_FOUND; + + + /* + * Error handling. + */ + + argument_error: + sprintf (vm->error, "RegExp.%s(): illegal amount of arguments", + js_vm_symname (vm, method)); + js_vm_error (vm); + + argument_type_error: + sprintf (vm->error, "RegExp.%s(): illegal argument", + js_vm_symname (vm, method)); + js_vm_error (vm); + + immutable: + sprintf (vm->error, "RegExp.%s(): immutable object", + js_vm_symname (vm, method)); + js_vm_error (vm); + + /* NOTREACHED. */ + return 0; +} + +/* Global method proc. */ +static void +global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSNode *result_return, + JSNode *args) +{ + RegexpCtx *ctx = builtin_info->obj_context; + RegexpInstanceCtx *ictx = instance_context; + char *input = NULL; /* Initialized to keep the compiler quiet. */ + unsigned int input_len = 0; /* Likewise. */ + + if (ictx) + { + /* A RegExp instance was called as a function. */ + + if (args->u.vinteger == 0) + { + if (ctx->input.type != JS_STRING) + { + sprintf (vm->error, "RegExp(): RegExp.input is not a string"); + js_vm_error (vm); + } + input = ctx->input.u.vstring->data; + input_len = ctx->input.u.vstring->len; + } + else if (args->u.vinteger == 1) + { + if (args[1].type != JS_STRING) + { + sprintf (vm->error, "RegExp(): illegal argument"); + js_vm_error (vm); + } + + input = args[1].u.vstring->data; + input_len = args[1].u.vstring->len; + + /* Set the input property to the class context. */ + JS_COPY (&ctx->input, &args[1]); + } + else + { + sprintf (vm->error, "RegExp(): illegal amount of arguments"); + js_vm_error (vm); + } + + do_exec (vm, ctx, ictx, input, input_len, result_return); + } + else + { + /* + * The `RegExp' was called as a function. We do exactly the + * same the `new RegExp()' would do with our arguments. + */ + new_proc (vm, builtin_info, args, result_return); + } +} + +/* Property proc. */ +static int +property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol property, int set, JSNode *node) +{ + RegexpCtx *ctx = builtin_info->obj_context; + RegexpInstanceCtx *ictx = instance_context; + int index; + + /* Static properties. */ + if (property == ctx->s_S1) + { + index = 1; + + dollar_index: + + if (set) + goto immutable; + + if (ctx->input.type != JS_STRING + || ctx->regs.end[0] > ctx->input.u.vstring->len + || ctx->regs.start[index] < 0) + node->type = JS_UNDEFINED; + else + js_vm_make_string (vm, node, + ctx->input.u.vstring->data + + ctx->regs.start[index], + ctx->regs.end[index] - ctx->regs.start[index]); + } + /* ********************************************************************** */ + else if (property == ctx->s_S2) + { + index = 2; + goto dollar_index; + } + /* ********************************************************************** */ + else if (property == ctx->s_S3) + { + index = 3; + goto dollar_index; + } + /* ********************************************************************** */ + else if (property == ctx->s_S4) + { + index = 4; + goto dollar_index; + } + /* ********************************************************************** */ + else if (property == ctx->s_S5) + { + index = 5; + goto dollar_index; + } + /* ********************************************************************** */ + else if (property == ctx->s_S6) + { + index = 6; + goto dollar_index; + } + /* ********************************************************************** */ + else if (property == ctx->s_S7) + { + index = 7; + goto dollar_index; + } + /* ********************************************************************** */ + else if (property == ctx->s_S8) + { + index = 8; + goto dollar_index; + } + /* ********************************************************************** */ + else if (property == ctx->s_S9) + { + index = 9; + goto dollar_index; + } + /* ********************************************************************** */ + else if (property == ctx->s_S_ || property == ctx->s_input) + { + if (set) + { + if (node->type != JS_STRING) + goto argument_type_error; + + JS_COPY (&ctx->input, node); + } + else + JS_COPY (node, &ctx->input); + } + /* ********************************************************************** */ + else if (property == ctx->s_lastMatch) + { + if (set) + goto immutable; + + if (ctx->input.type != JS_STRING + || ctx->regs.end[0] > ctx->input.u.vstring->len) + node->type = JS_UNDEFINED; + else + js_vm_make_string (vm, node, + ctx->input.u.vstring->data + ctx->regs.start[0], + ctx->regs.end[0] - ctx->regs.start[0]); + } + /* ********************************************************************** */ + else if (property == ctx->s_lastParen) + { + if (set) + goto immutable; + + if (ctx->input.type != JS_STRING + || ctx->regs.end[0] > ctx->input.u.vstring->len) + node->type = JS_UNDEFINED; + else + { + int i; + + for (i = 1; i < ctx->regs.num_regs && ctx->regs.start[i] >= 0; i++) + ; + i--; + if (i == 0) + node->type = JS_UNDEFINED; + else + js_vm_make_string (vm, node, + ctx->input.u.vstring->data + + ctx->regs.start[i], + ctx->regs.end[i] - ctx->regs.start[i]); + } + } + /* ********************************************************************** */ + else if (property == ctx->s_leftContext) + { + if (set) + goto immutable; + + if (ctx->input.type != JS_STRING + || ctx->regs.end[0] > ctx->input.u.vstring->len) + node->type = JS_UNDEFINED; + else + js_vm_make_string (vm, node, ctx->input.u.vstring->data, + ctx->regs.start[0]); + } + /* ********************************************************************** */ + else if (property == ctx->s_multiline) + { + goto not_implemented_yet; + } + /* ********************************************************************** */ + else if (property == ctx->s_rightContext) + { + if (set) + goto immutable; + if (ctx->input.type != JS_STRING + || ctx->regs.end[0] > ctx->input.u.vstring->len) + node->type = JS_UNDEFINED; + else + js_vm_make_string (vm, node, + ctx->input.u.vstring->data + ctx->regs.end[0], + ctx->input.u.vstring->len - ctx->regs.end[0]); + } + /* ********************************************************************** */ + else if (ictx) + { + /* Properties. */ + if (property == ctx->s_global) + { + if (set) + goto immutable; + + node->type = JS_BOOLEAN; + node->u.vboolean = ictx->global; + } + /* ***************************************************************** */ + else if (property == ctx->s_ignoreCase) + { + if (set) + goto immutable; + + node->type = JS_BOOLEAN; + node->u.vboolean = ictx->ignore_case; + } + /* ***************************************************************** */ + else if (property == ctx->s_lastIndex) + { + if (set) + { + if (ictx->immutable) + goto immutable_object; + + if (node->type != JS_INTEGER) + goto argument_type_error; + + ictx->last_index = node->u.vinteger; + } + else + { + node->type = JS_INTEGER; + node->u.vinteger = ictx->last_index; + } + } + /* ***************************************************************** */ + else if (property == ctx->s_source) + { + if (set) + goto immutable; + + js_vm_make_string (vm, node, ictx->source, ictx->source_len); + } + /* ***************************************************************** */ + else + { + if (!set) + node->type = JS_UNDEFINED; + + return JS_PROPERTY_UNKNOWN; + } + } + /* ********************************************************************** */ + else + { + if (!set) + node->type = JS_UNDEFINED; + + return JS_PROPERTY_UNKNOWN; + } + + return JS_PROPERTY_FOUND; + + + /* Error handling. */ + + argument_type_error: + sprintf (vm->error, "RegExp.%s: illegal value", + js_vm_symname (vm, property)); + js_vm_error (vm); + + not_implemented_yet: + sprintf (vm->error, "RegExp.%s: not implemented yet", + js_vm_symname (vm, property)); + js_vm_error (vm); + + immutable: + sprintf (vm->error, "RegExp.%s: immutable property", + js_vm_symname (vm, property)); + js_vm_error (vm); + + immutable_object: + sprintf (vm->error, "RegExp.%s: immutable object", + 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) +{ + unsigned int flags = 0; + char *source; + unsigned int source_len; + int i; + + if (args->u.vinteger > 2) + { + sprintf (vm->error, "new RegExp(): illegal amount of arguments"); + js_vm_error (vm); + } + + if (args->u.vinteger == 0) + { + source = ""; + source_len = 0; + } + else + { + if (args[1].type != JS_STRING) + { + argument_type_error: + sprintf (vm->error, "new RegExp(): illegal argument"); + js_vm_error (vm); + } + + source = args[1].u.vstring->data; + source_len = args[1].u.vstring->len; + } + + if (args->u.vinteger == 2) + { + if (args[2].type != JS_STRING) + goto argument_type_error; + + for (i = 0; i < args[2].u.vstring->len; i++) + switch (args[2].u.vstring->data[i]) + { + case 'g': + flags |= JS_REGEXP_FLAG_G; + break; + + case 'i': + flags |= JS_REGEXP_FLAG_I; + break; + + default: + sprintf (vm->error, "new RegExp(): illegal flag `%c'", + args[2].u.vstring->data[i]); + js_vm_error (vm); + break; + } + } + + js_builtin_RegExp_new (vm, source, source_len, flags, 0, builtin_info, + result_return); +} + +/* Delete proc. */ +static void +delete_proc (JSBuiltinInfo *builtin_info, void *instance_context) +{ + RegexpInstanceCtx *ictx = instance_context; + + if (ictx) + { + js_free (ictx->source); + + if (ictx->compiled.buffer) + free (ictx->compiled.buffer); + if (ictx->compiled.fastmap) + js_free (ictx->compiled.fastmap); + + js_free (ictx); + } +} + +/* Mark proc. */ +static void +mark (JSBuiltinInfo *builtin_info, void *instance_context) +{ + RegexpCtx *ctx = builtin_info->obj_context; + + js_vm_mark (&ctx->input); +} + +/* + * Global functions. + */ + +void +js_builtin_RegExp (JSVirtualMachine *vm) +{ + JSBuiltinInfo *info; + RegexpCtx *ctx; + JSNode *n; + + ctx = js_calloc (vm, 1, sizeof (*ctx)); + + ctx->s_S1 = js_vm_intern (vm, "$1"); + ctx->s_S2 = js_vm_intern (vm, "$2"); + ctx->s_S3 = js_vm_intern (vm, "$3"); + ctx->s_S4 = js_vm_intern (vm, "$4"); + ctx->s_S5 = js_vm_intern (vm, "$5"); + ctx->s_S6 = js_vm_intern (vm, "$6"); + ctx->s_S7 = js_vm_intern (vm, "$7"); + ctx->s_S8 = js_vm_intern (vm, "$8"); + ctx->s_S9 = js_vm_intern (vm, "$9"); + ctx->s_S_ = js_vm_intern (vm, "$_"); + ctx->s_input = js_vm_intern (vm, "input"); + ctx->s_lastMatch = js_vm_intern (vm, "lastMatch"); + ctx->s_lastParen = js_vm_intern (vm, "lastParen"); + ctx->s_leftContext = js_vm_intern (vm, "leftContext"); + ctx->s_multiline = js_vm_intern (vm, "multiline"); + ctx->s_rightContext = js_vm_intern (vm, "rightContext"); + + ctx->s_global = js_vm_intern (vm, "global"); + ctx->s_ignoreCase = js_vm_intern (vm, "ignoreCase"); + ctx->s_lastIndex = js_vm_intern (vm, "lastIndex"); + ctx->s_source = js_vm_intern (vm, "source"); + + ctx->s_compile = js_vm_intern (vm, "compile"); + ctx->s_exec = js_vm_intern (vm, "exec"); + ctx->s_test = js_vm_intern (vm, "test"); + + /* Object information. */ + + info = js_vm_builtin_info_create (vm); + + info->global_method_proc = global_method; + info->method_proc = method; + info->property_proc = property; + info->new_proc = new_proc; + info->delete_proc = delete_proc; + info->mark_proc = mark; + info->obj_context = ctx; + info->obj_context_delete = js_free; + + /* Define it. */ + n = &vm->globals[js_vm_intern (vm, "RegExp")]; + js_vm_builtin_create (vm, n, info, NULL); +} + + +void +js_builtin_RegExp_new (JSVirtualMachine *vm, char *source, + unsigned int source_len, unsigned int flags, + int immutable, JSBuiltinInfo *info, + JSNode *result_return) +{ + RegexpInstanceCtx *instance; + const char *error; + + instance = js_calloc (vm, 1, sizeof (*instance)); + + instance->source_len = source_len; + + /* +1 to avoid zero allocation. */ + instance->source = js_malloc (vm, instance->source_len + 1); + memcpy (instance->source, source, instance->source_len); + + instance->global = (flags & JS_REGEXP_FLAG_G) != 0; + instance->ignore_case = (flags & JS_REGEXP_FLAG_I) != 0; + instance->immutable = immutable; + + if (instance->ignore_case) + instance->compiled.translate = js_latin1_tolower; + + error = re_compile_pattern (instance->source, instance->source_len, + &instance->compiled); + if (error) + { + js_free (instance->source); + js_free (instance); + sprintf (vm->error, + "new RegExp(): compilation of the expression failed: %s", + error); + js_vm_error (vm); + } + instance->compiled.fastmap = js_malloc (vm, 256); + re_compile_fastmap (&instance->compiled); + + if (info == NULL) + { + JSNode *n; + + n = &vm->globals[js_vm_intern (vm, "RegExp")]; + info = n->u.vbuiltin->info; + } + + /* Create a new object. */ + js_vm_builtin_create (vm, result_return, info, instance); +} + + +#define EMIT_TO_RESULT(md, mdl) \ + do { \ + result_return->u.vstring->data \ + = js_vm_realloc (vm, result_return->u.vstring->data, \ + result_return->u.vstring->len + (mdl)); \ + memcpy (result_return->u.vstring->data \ + + result_return->u.vstring->len, \ + (md), (mdl)); \ + result_return->u.vstring->len += (mdl); \ + } while (0) + +void +js_builtin_RegExp_replace (JSVirtualMachine *vm, char *data, + unsigned int datalen, JSNode *regexp, + char *repl, unsigned int repllen, + JSNode *result_return) +{ + int i, j; + RegexpInstanceCtx *ictx = regexp->u.vbuiltin->instance_context; + struct re_registers regs = {0}; + unsigned int substs = 0; + unsigned int pos = 0; + + /* + * Allocate the result string, Let's guess that we need at least + * bytes of data. + */ + js_vm_make_string (vm, result_return, NULL, datalen); + result_return->u.vstring->len = 0; + + /* Do searches. */ + while (pos < datalen) + { + i = re_search (&ictx->compiled, data, datalen, pos, datalen - pos, + ®s); + + /* Check what we got. */ + if (i >= 0) + { + /* Emit all up to the first matched character. */ + EMIT_TO_RESULT (data + pos, regs.start[0] - pos); + + /* Check for empty matches. */ + if (regs.end[0] == regs.start[0]) + { + pos = regs.end[0]; + + /* Still something left to search? */ + if (pos < datalen) + { + /* Go one character forward. */ + EMIT_TO_RESULT (data + pos, 1); + pos++; + } + } + else + { + int start; + + /* Not an empty match. */ + substs++; + + /* Interpret replace string. */ + start = 0; + for (i = 0; i < repllen; i++) + { + if (repl[i] == '$') + { + if (i + 1 >= repllen) + /* The last character is '$'. Just emit it. */ + continue; + + /* First, emit all we have collected so far. */ + EMIT_TO_RESULT (repl + start, i - start); + start = i++; + + /* Check tag. */ + switch (repl[i]) + { + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + /* n:th subexpression. */ + j = repl[i] - '0'; + + if (regs.start[j] >= 0) + EMIT_TO_RESULT (data + regs.start[j], + regs.end[j] - regs.start[j]); + + start = i + 1; + break; + + case '`': + /* Left context. */ + EMIT_TO_RESULT (data, regs.start[0]); + start = i + 1; + break; + + case '\'': + /* Right context. */ + EMIT_TO_RESULT (data + regs.end[0], + datalen - regs.end[0]); + start = i + 1; + break; + + case '&': + /* Last match. */ + EMIT_TO_RESULT (data + regs.start[0], + regs.end[0] - regs.start[0]); + start = i + 1; + break; + + case '$': + /* The dollar sign. */ + EMIT_TO_RESULT ("$", 1); + start = i + 1; + break; + + case '+': + default: + /* Ignore. */ + start = i - 1; + break; + } + } + } + + /* Emit all leftovers. */ + EMIT_TO_RESULT (repl + start, i - start); + + /* Update search position. */ + pos = regs.end[0]; + } + } + else + break; + + if (!ictx->global && substs > 0) + /* Substitute only the first match. */ + break; + } + + /* No more matches. Emit the rest of the string to the result. */ + EMIT_TO_RESULT (data + pos, datalen - pos); + + if (regs.start) + free (regs.start); + if (regs.end) + free (regs.end); +} + + +void +js_builtin_RegExp_match (JSVirtualMachine *vm, char *data, + unsigned int datalen, JSNode *regexp, + JSNode *result_return) +{ + do_exec (vm, regexp->u.vbuiltin->info->obj_context, + regexp->u.vbuiltin->instance_context, data, datalen, + result_return); +} + + +void +js_builtin_RegExp_search (JSVirtualMachine *vm, char *data, + unsigned int datalen, JSNode *regexp, + JSNode *result_return) +{ + RegexpCtx *ctx = regexp->u.vbuiltin->info->obj_context; + RegexpInstanceCtx *ictx = regexp->u.vbuiltin->instance_context; + + result_return->type = JS_INTEGER; + result_return->u.vinteger = re_search (&ictx->compiled, data, datalen, + ictx->global ? ictx->last_index : 0, + datalen, &ctx->regs); + + if (result_return->u.vinteger >= 0) + ictx->last_index = ctx->regs.end[0]; +} + + +void +js_builtin_RegExp_split (JSVirtualMachine *vm, char *data, + unsigned int datalen, JSNode *regexp, + unsigned int limit, JSNode *result_return) +{ + unsigned int start = 0, pos; + unsigned int alen = 0; + RegexpInstanceCtx *ictx = regexp->u.vbuiltin->instance_context; + struct re_registers regs = {0}; + int i; + + js_vm_make_array (vm, result_return, alen); + + for (pos = 0; alen < limit && pos <= datalen; ) + { + i = re_search (&ictx->compiled, data, datalen, pos, datalen - pos, + ®s); + if (i < 0) + { + pos = datalen; + break; + } + + /* Found the separator. */ + js_vm_expand_array (vm, result_return, alen + 1); + js_vm_make_string (vm, &result_return->u.varray->data[alen], + data + start, regs.start[0] - start); + alen++; + + if (regs.end[0] == pos) + { + /* We didn't advance in the string. */ + start = regs.end[0]; + pos++; + } + else + pos = start = regs.end[0]; + } + + if (alen < limit) + { + /* Insert all leftovers. */ + js_vm_expand_array (vm, result_return, alen + 1); + js_vm_make_string (vm, &result_return->u.varray->data[alen], + data + start, datalen - start); + } + + if (regs.start) + free (regs.start); + if (regs.end) + free (regs.end); +} diff --git a/reactos/lib/kjs/src/b_string.c b/reactos/lib/kjs/src/b_string.c new file mode 100644 index 00000000000..c98c2d8d3b4 --- /dev/null +++ b/reactos/lib/kjs/src/b_string.c @@ -0,0 +1,937 @@ +/* + * The builtin String object. + * Copyright (c) 1998-1999 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/b_string.c,v $ + * $Id: b_string.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +/* TODO: global method: String (obj) => string */ + +#include "jsint.h" + +/* + * Types and definitions. + */ + +#define UNPACK_NEED(n) \ + do { \ + if (bufpos + (n) > buflen) \ + { \ + sprintf (vm->error, \ + "String.%s(): too short string for the format", \ + js_vm_symname (vm, method)); \ + js_vm_error (vm); \ + } \ + } while (0) + +#define UNPACK_EXPAND() \ + do { \ + js_vm_expand_array (vm, result_return, result_len + 1); \ + rnode = &result_return->u.varray->data[result_len]; \ + result_len++; \ + } while (0) + +/* Class context. */ +struct string_ctx_st +{ + JSSymbol s_length; + + JSSymbol s_append; + JSSymbol s_charAt; + JSSymbol s_charCodeAt; + JSSymbol s_concat; + JSSymbol s_crc32; + JSSymbol s_fromCharCode; + JSSymbol s_indexOf; + JSSymbol s_lastIndexOf; + JSSymbol s_match; + JSSymbol s_pack; + JSSymbol s_replace; + JSSymbol s_search; + JSSymbol s_slice; + JSSymbol s_split; + JSSymbol s_substr; + JSSymbol s_substring; + JSSymbol s_toLowerCase; + JSSymbol s_toUpperCase; + JSSymbol s_unpack; + + /* Data we need to implement the RegExp related stuffs. */ + JSBuiltinInfo *regexp_info; +}; + +typedef struct string_ctx_st StringCtx; + + +/* + * 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) + js_vm_make_static_string (vm, result_return, "", 0); + else if (args->u.vinteger == 1) + js_vm_to_string (vm, &args[1], result_return); + else + { + sprintf (vm->error, "String(): 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) +{ + StringCtx *ctx = builtin_info->obj_context; + JSNode *n = instance_context; + unsigned int ui; + int i; + + /* + * Static methods. + */ + + if (method == ctx->s_fromCharCode) + { + js_vm_make_string (vm, result_return, NULL, args->u.vinteger); + + for (i = 0; i < args->u.vinteger; i++) + { + if (args[1 + i].type != JS_INTEGER) + goto argument_type_error; + + result_return->u.vstring->data[i] + = (unsigned char) args[1 + i].u.vinteger; + } + } + /* ********************************************************************** */ + else if (method == ctx->s_pack) + { + unsigned int op; + unsigned int arg = 2; + JSUInt32 ui; + double dval; + unsigned char *buffer = NULL; + unsigned int bufpos = 0; + + if (args->u.vinteger < 1) + goto argument_error; + if (args[1].type != JS_STRING) + goto argument_type_error; + + for (op = 0; op < args[1].u.vstring->len; op++) + { + if (arg >= args->u.vinteger + 1) + { + sprintf (vm->error, "String.%s(): too few arguments for format", + js_vm_symname (vm, method)); + js_vm_error (vm); + } + + switch (args[1].u.vstring->data[op]) + { + case 'C': + if (args[arg].type != JS_INTEGER) + goto argument_type_error; + + buffer = js_vm_realloc (vm, buffer, bufpos + 1); + buffer[bufpos++] = (unsigned char) args[arg++].u.vinteger; + break; + + case 'n': + if (args[arg].type != JS_INTEGER) + goto argument_type_error; + + ui = args[arg++].u.vinteger; + + buffer = js_vm_realloc (vm, buffer, bufpos + 2); + buffer[bufpos++] = (unsigned char) ((ui & 0x0000ff00) >> 8); + buffer[bufpos++] = (unsigned char) (ui & 0x000000ff); + break; + + case 'N': + if (args[arg].type != JS_INTEGER) + goto argument_type_error; + + ui = args[arg++].u.vinteger; + + buffer = js_vm_realloc (vm, buffer, bufpos + 4); + buffer[bufpos++] = (unsigned char) ((ui & 0xff000000) >> 24); + buffer[bufpos++] = (unsigned char) ((ui & 0x00ff0000) >> 16); + buffer[bufpos++] = (unsigned char) ((ui & 0x0000ff00) >> 8); + buffer[bufpos++] = (unsigned char) ((ui & 0x000000ff)); + break; + + case 'd': + if (args[arg].type != JS_INTEGER && args[arg].type != JS_FLOAT) + goto argument_type_error; + + if (args[arg].type == JS_INTEGER) + dval = (double) args[arg].u.vinteger; + else + dval = args[arg].u.vfloat; + arg++; + + buffer = js_vm_realloc (vm, buffer, bufpos + sizeof (double)); + memcpy (buffer + bufpos, &dval, sizeof (double)); + bufpos += sizeof (double); + break; + + default: + /* Silently ignore it. */ + break; + } + } + + js_vm_make_static_string (vm, result_return, buffer, bufpos); + result_return->u.vstring->staticp = 0; + } + /* ********************************************************************** */ + else if (method == vm->syms.s_toString) + { + if (n) + JS_COPY (result_return, n); + else + js_vm_make_static_string (vm, result_return, "String", 6); + } + /* ********************************************************************** */ + else if (method == vm->syms.s_valueOf) + { + if (n) + JS_COPY (result_return, n); + else + { + n = &vm->globals[js_vm_intern (vm, "String")]; + JS_COPY (result_return, n); + } + } + /* ********************************************************************** */ + else if (n) + { + /* + * Instance methods. + */ + + if (method == ctx->s_append) + { + if (args->u.vinteger != 1) + goto argument_error; + + if (n->u.vstring->staticp) + { + sprintf (vm->error, + "String.%s(): can't append to a static string", + js_vm_symname (vm, method)); + js_vm_error (vm); + } + + if (args[1].type == JS_STRING) + { + /* Append a string. */ + n->u.vstring->data = js_vm_realloc (vm, n->u.vstring->data, + n->u.vstring->len + + args[1].u.vstring->len); + memcpy (n->u.vstring->data + n->u.vstring->len, + args[1].u.vstring->data, + args[1].u.vstring->len); + n->u.vstring->len += args[1].u.vstring->len; + } + else if (args[1].type == JS_INTEGER) + { + /* Append a character. */ + n->u.vstring->data = js_vm_realloc (vm, n->u.vstring->data, + n->u.vstring->len + 1); + n->u.vstring->data[n->u.vstring->len++] + = (unsigned char) args[1].u.vinteger; + } + else + goto argument_type_error; + } + /* ***************************************************************** */ + else if (method == ctx->s_charAt) + { + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_INTEGER) + goto argument_type_error; + + js_vm_make_string (vm, result_return, NULL, 1); + + ui = args[1].u.vinteger; + + if (ui >= n->u.vstring->len) + result_return->u.vstring->len = 0; + else + result_return->u.vstring->data[0] = n->u.vstring->data[ui]; + } + /* ***************************************************************** */ + else if (method == ctx->s_charCodeAt) + { + if (args->u.vinteger == 0) + ui = 0; + else if (args->u.vinteger == 1) + { + if (args[1].type != JS_INTEGER) + goto argument_type_error; + ui = args[1].u.vinteger; + } + else + goto argument_error; + + if (ui >= n->u.vstring->len) + { + sprintf (vm->error, "String.%s(): index out of range", + js_vm_symname (vm, method)); + js_vm_error (vm); + } + + result_return->type = JS_INTEGER; + result_return->u.vinteger = n->u.vstring->data[ui]; + } + /* ***************************************************************** */ + else if (method == ctx->s_concat) + { + int nlen, pos; + + /* Count the new length. */ + + nlen = n->u.vstring->len; + + for (i = 0; i < args->u.vinteger; i++) + { + if (args[i + 1].type != JS_STRING) + goto argument_type_error; + nlen += args[i + 1].u.vstring->len; + } + + js_vm_make_string (vm, result_return, NULL, nlen); + + memcpy (result_return->u.vstring->data, n->u.vstring->data, + n->u.vstring->len); + + /* Append the argumens. */ + + pos = n->u.vstring->len; + + for (i = 0; i < args->u.vinteger; i++) + { + memcpy (result_return->u.vstring->data + pos, + args[i + 1].u.vstring->data, args[i + 1].u.vstring->len); + pos += args[i + 1].u.vstring->len; + } + } + /* ***************************************************************** */ + else if (method == ctx->s_crc32) + { + if (args->u.vinteger != 0) + goto argument_error; + + result_return->type = JS_INTEGER; + result_return->u.vinteger = js_crc32 (n->u.vstring->data, + n->u.vstring->len); + } + /* ***************************************************************** */ + else if (method == ctx->s_indexOf) + { + int start_index = 0; + + if (args->u.vinteger < 1 || args->u.vinteger > 2) + goto argument_error; + if (args[1].type != JS_STRING) + goto argument_type_error; + + if (args->u.vinteger == 2) + { + if (args[2].type != JS_INTEGER) + goto argument_type_error; + + start_index = args[2].u.vinteger; + } + + result_return->type = JS_INTEGER; + result_return->u.vinteger = -1; + + if (start_index >= 0 + && start_index + args[1].u.vstring->len <= n->u.vstring->len) + { + /* Use the Brute Force Luke! */ + for (; start_index + args[1].u.vstring->len <= n->u.vstring->len; + start_index++) + if (memcmp (n->u.vstring->data + start_index, + args[1].u.vstring->data, + args[1].u.vstring->len) == 0) + { + result_return->u.vinteger = start_index; + break; + } + } + } + /* ***************************************************************** */ + else if (method == ctx->s_lastIndexOf) + { + int start_index; + + if (args->u.vinteger < 1 || args->u.vinteger > 2) + goto argument_error; + if (args[1].type != JS_STRING) + goto argument_type_error; + + if (args->u.vinteger == 2) + { + if (args[2].type != JS_INTEGER) + goto argument_type_error; + + start_index = args[2].u.vinteger; + } + else + start_index = n->u.vstring->len - args[1].u.vstring->len; + + result_return->type = JS_INTEGER; + result_return->u.vinteger = -1; + + if (start_index >= 0 + && start_index + args[1].u.vstring->len <= n->u.vstring->len) + { + for (; start_index >= 0; start_index--) + if (memcmp (n->u.vstring->data + start_index, + args[1].u.vstring->data, + args[1].u.vstring->len) == 0) + { + result_return->u.vinteger = start_index; + break; + } + } + } + /* ***************************************************************** */ + else if (method == ctx->s_match) + { + if (args->u.vinteger != 1) + goto argument_error; + + if (args[1].type != JS_BUILTIN + || args[1].u.vbuiltin->info != ctx->regexp_info) + goto argument_type_error; + + js_builtin_RegExp_match (vm, n->u.vstring->data, n->u.vstring->len, + &args[1], result_return); + } + /* ***************************************************************** */ + else if (method == ctx->s_replace) + { + if (args->u.vinteger != 2) + goto argument_error; + + if (args[1].type != JS_BUILTIN + || args[1].u.vbuiltin->info != ctx->regexp_info + || args[2].type != JS_STRING) + goto argument_type_error; + + js_builtin_RegExp_replace (vm, n->u.vstring->data, n->u.vstring->len, + &args[1], args[2].u.vstring->data, + args[2].u.vstring->len, result_return); + } + /* ***************************************************************** */ + else if (method == ctx->s_search) + { + if (args->u.vinteger != 1) + goto argument_error; + + if (args[1].type != JS_BUILTIN + || args[1].u.vbuiltin->info != ctx->regexp_info) + goto argument_type_error; + + js_builtin_RegExp_search (vm, n->u.vstring->data, n->u.vstring->len, + &args[1], result_return); + } + /* ***************************************************************** */ + 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 (start < 0) + start += n->u.vstring->len; + if (start < 0) + start = 0; + if (start > n->u.vstring->len) + start = n->u.vstring->len; + + if (args->u.vinteger == 2) + { + if (args[2].type != JS_INTEGER) + goto argument_type_error; + + end = args[2].u.vinteger; + if (end < 0) + end += n->u.vstring->len; + if (end < 0) + end = 0; + if (end > n->u.vstring->len) + end = n->u.vstring->len; + } + else + end = n->u.vstring->len; + + if (start > end) + end = start; + + js_vm_make_string (vm, result_return, n->u.vstring->data + start, + end - start); + } + /* ***************************************************************** */ + else if (method == ctx->s_split) + { + if (args->u.vinteger == 0) + { + js_vm_make_array (vm, result_return, 1); + js_vm_make_string (vm, &result_return->u.varray->data[0], + n->u.vstring->data, n->u.vstring->len); + } + else + { + unsigned int limit; + + if (args->u.vinteger == 1) + limit = -1; + else if (args->u.vinteger == 2) + { + if (args[2].type != JS_INTEGER) + goto argument_type_error; + + limit = args[2].u.vinteger; + } + else + goto argument_error; + + if (args[1].type == JS_STRING) + { + unsigned int start = 0, pos; + unsigned int alen = 0; + + js_vm_make_array (vm, result_return, alen); + + for (pos = 0; + (alen < limit + && pos + args[1].u.vstring->len <= n->u.vstring->len); + ) + { + if (memcmp (n->u.vstring->data + pos, + args[1].u.vstring->data, + args[1].u.vstring->len) == 0) + { + /* Found the separator. */ + js_vm_expand_array (vm, result_return, alen + 1); + js_vm_make_string (vm, + &(result_return + ->u.varray->data[alen]), + n->u.vstring->data + start, + pos - start); + alen++; + + if (args[1].u.vstring->len == 0) + { + start = pos; + pos++; + } + else + { + pos += args[1].u.vstring->len; + start = pos; + } + } + else + pos++; + } + + if (alen < limit) + { + /* And finally, insert all leftovers. */ + js_vm_expand_array (vm, result_return, alen + 1); + js_vm_make_string (vm, + &result_return->u.varray->data[alen], + n->u.vstring->data + start, + n->u.vstring->len - start); + } + } + else if (args[1].type == JS_BUILTIN + && args[1].u.vbuiltin->info == ctx->regexp_info) + { + js_builtin_RegExp_split (vm, n->u.vstring->data, + n->u.vstring->len, &args[1], + limit, result_return); + } + else + goto argument_type_error; + } + } + /* ***************************************************************** */ + else if (method == ctx->s_substr) + { + int start, length; + + 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; + + length = args[2].u.vinteger; + if (length < 0) + length = 0; + } + else + length = n->u.vstring->len; + + if (start < 0) + start += n->u.vstring->len; + if (start < 0) + start = 0; + if (start > n->u.vstring->len) + start = n->u.vstring->len; + + if (start + length > n->u.vstring->len) + length = n->u.vstring->len - start; + + js_vm_make_string (vm, result_return, n->u.vstring->data + start, + length); + } + /* ***************************************************************** */ + else if (method == ctx->s_substring) + { + 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.vstring->len; + + if (start < 0) + start = 0; + + if (end > n->u.vstring->len) + end = n->u.vstring->len; + + if (start > end) + { + sprintf (vm->error, + "String.%s(): start index is bigger than end", + js_vm_symname (vm, method)); + js_vm_error (vm); + } + + js_vm_make_string (vm, result_return, n->u.vstring->data + start, + end - start); + } + /* ***************************************************************** */ + else if (method == ctx->s_toLowerCase) + { + if (args->u.vinteger != 0) + goto argument_type_error; + + js_vm_make_string (vm, result_return, n->u.vstring->data, + n->u.vstring->len); + + for (i = 0; i < result_return->u.vstring->len; i++) + result_return->u.vstring->data[i] + = js_latin1_tolower[result_return->u.vstring->data[i]]; + } + /* ***************************************************************** */ + else if (method == ctx->s_toUpperCase) + { + if (args->u.vinteger != 0) + goto argument_type_error; + + js_vm_make_string (vm, result_return, n->u.vstring->data, + n->u.vstring->len); + + for (i = 0; i < result_return->u.vstring->len; i++) + result_return->u.vstring->data[i] + = js_latin1_toupper[result_return->u.vstring->data[i]]; + } + /* ***************************************************************** */ + else if (method == ctx->s_unpack) + { + unsigned int op; + unsigned char *buffer; + unsigned int buflen; + unsigned int bufpos = 0; + JSUInt32 ui; + unsigned int result_len = 0; + JSNode *rnode; + + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_STRING) + goto argument_type_error; + + buffer = n->u.vstring->data; + buflen = n->u.vstring->len; + + js_vm_make_array (vm, result_return, 0); + + for (op = 0; op < args[1].u.vstring->len; op++) + { + switch (args[1].u.vstring->data[op]) + { + case 'C': + UNPACK_NEED (1); + UNPACK_EXPAND (); + rnode->type = JS_INTEGER; + rnode->u.vinteger = buffer[bufpos++]; + break; + + case 'n': + UNPACK_NEED (2); + UNPACK_EXPAND (); + + ui = buffer[bufpos++]; + ui <<= 8; + ui |= buffer[bufpos++]; + + rnode->type = JS_INTEGER; + rnode->u.vinteger = ui; + break; + + case 'N': + UNPACK_NEED (4); + UNPACK_EXPAND (); + + ui = buffer[bufpos++]; + ui <<= 8; + ui |= buffer[bufpos++]; + ui <<= 8; + ui |= buffer[bufpos++]; + ui <<= 8; + ui |= buffer[bufpos++]; + + rnode->type = JS_INTEGER; + rnode->u.vinteger = ui; + break; + + case 'd': + UNPACK_NEED (8); + UNPACK_EXPAND (); + + rnode->type = JS_FLOAT; + memcpy (&rnode->u.vfloat, buffer + bufpos, 8); + bufpos += 8; + break; + + default: + /* Silently ignore it. */ + break; + } + } + } + /* ***************************************************************** */ + else + return JS_PROPERTY_UNKNOWN; + } + else + return JS_PROPERTY_UNKNOWN; + + return JS_PROPERTY_FOUND; + + + /* + * Error handling. + */ + + argument_error: + sprintf (vm->error, "String.%s(): illegal amount of arguments", + js_vm_symname (vm, method)); + js_vm_error (vm); + + argument_type_error: + sprintf (vm->error, "String %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) +{ + StringCtx *ctx = builtin_info->obj_context; + JSNode *n = instance_context; + + if (n && property == ctx->s_length) + { + if (set) + goto immutable; + + node->type = JS_INTEGER; + node->u.vinteger = n->u.vstring->len; + } + else + { + if (!set) + node->type = JS_UNDEFINED; + + return JS_PROPERTY_UNKNOWN; + } + + return JS_PROPERTY_FOUND; + + + /* + * Error handling. + */ + + immutable: + sprintf (vm->error, "String.%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) +{ + JSNode source_n; + JSNode *source; + + if (args->u.vinteger == 0) + js_vm_make_string (vm, result_return, NULL, 0); + else if (args->u.vinteger == 1) + { + if (args[1].type == JS_STRING) + source = &args[1]; + else + { + js_vm_to_string (vm, &args[1], &source_n); + source = &source_n; + } + + js_vm_make_string (vm, result_return, source->u.vstring->data, + source->u.vstring->len); + } + else + { + sprintf (vm->error, "new String(): illegal amount of arguments"); + js_vm_error (vm); + } + + /* Set the [[Prototype]] and [[Class]] properties. */ + /* XXX 15.8.2 */ +} + +/* + * Global functions. + */ + +void +js_builtin_String (JSVirtualMachine *vm) +{ + StringCtx *ctx; + JSNode *n; + JSBuiltinInfo *info; + + ctx = js_calloc (vm, 1, sizeof (*ctx)); + + ctx->s_length = js_vm_intern (vm, "length"); + + ctx->s_append = js_vm_intern (vm, "append"); + ctx->s_charAt = js_vm_intern (vm, "charAt"); + ctx->s_charCodeAt = js_vm_intern (vm, "charCodeAt"); + ctx->s_concat = js_vm_intern (vm, "concat"); + ctx->s_crc32 = js_vm_intern (vm, "crc32"); + ctx->s_fromCharCode = js_vm_intern (vm, "fromCharCode"); + ctx->s_indexOf = js_vm_intern (vm, "indexOf"); + ctx->s_lastIndexOf = js_vm_intern (vm, "lastIndexOf"); + ctx->s_match = js_vm_intern (vm, "match"); + ctx->s_pack = js_vm_intern (vm, "pack"); + ctx->s_replace = js_vm_intern (vm, "replace"); + ctx->s_search = js_vm_intern (vm, "search"); + ctx->s_slice = js_vm_intern (vm, "slice"); + ctx->s_split = js_vm_intern (vm, "split"); + ctx->s_substr = js_vm_intern (vm, "substr"); + ctx->s_substring = js_vm_intern (vm, "substring"); + ctx->s_toLowerCase = js_vm_intern (vm, "toLowerCase"); + ctx->s_toUpperCase = js_vm_intern (vm, "toUpperCase"); + ctx->s_unpack = js_vm_intern (vm, "unpack"); + + info = js_vm_builtin_info_create (vm); + vm->prim[JS_STRING] = 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, "String")]; + js_vm_builtin_create (vm, n, info, NULL); + + /* Fetch the JSBuiltinInfo of the RegExp object. */ + n = &vm->globals[js_vm_intern (vm, "RegExp")]; + ctx->regexp_info = n->u.vbuiltin->info; +} diff --git a/reactos/lib/kjs/src/b_system.c b/reactos/lib/kjs/src/b_system.c new file mode 100644 index 00000000000..a820561a8f7 --- /dev/null +++ b/reactos/lib/kjs/src/b_system.c @@ -0,0 +1,521 @@ +/* + * The builtin System object. + * Copyright (c) 1998-1999 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/b_system.c,v $ + * $Id: b_system.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +/* + * Static methods: + * + * chdir (string) => boolean + * error ([ANY...]) => undefined + * exit (value) + * getcwd () => string + * getenv (string) => string / undefined + * popen (COMMAND, MODE) => file + * print ([ANY...]) => undefined + * sleep (int) => undefined + * strerror (errno) => string + * system (string) => integer + * usleep (int) => undefined + * + * Properties: type mutable + * + * bits integer + * canonicalHost string + * canonicalHostCPU string + * canonicalHostVendor string + * canonicalHostOS string + * errno integer + * lineBreakSequence string + * stderr file + * stdin file + * stdout file + */ + +#include "jsint.h" + +/* + * Types and definitions. + */ + +#define INSECURE() \ + do { \ + if (secure_mode) \ + goto insecure_feature; \ + } while (0) + +struct system_ctx_st +{ + JSSymbol s_chdir; + JSSymbol s_error; + JSSymbol s_exit; + JSSymbol s_getcwd; + JSSymbol s_getenv; + JSSymbol s_popen; + JSSymbol s_print; + JSSymbol s_sleep; + JSSymbol s_strerror; + JSSymbol s_system; + JSSymbol s_usleep; + + JSSymbol s_bits; + JSSymbol s_canonicalHost; + JSSymbol s_canonicalHostCPU; + JSSymbol s_canonicalHostVendor; + JSSymbol s_canonicalHostOS; + JSSymbol s_errno; + JSSymbol s_lineBreakSequence; + JSSymbol s_stderr; + JSSymbol s_stdin; + JSSymbol s_stdout; + + /* System file handles. */ + JSNode pstderr; + JSNode pstdin; + JSNode pstdout; +}; + +typedef struct system_ctx_st SystemCtx; + + +/* + * Static functions. + */ + +/* Method proc */ +static int +method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol method, JSNode *result_return, + JSNode *args) +{ + SystemCtx *ctx = builtin_info->obj_context; + int i; + char *cp; + int secure_mode = vm->security & JS_VM_SECURE_SYSTEM; + + /* The default result. */ + result_return->type = JS_UNDEFINED; + + if (method == ctx->s_chdir) + { + INSECURE (); + + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_STRING) + goto argument_type_error; + + result_return->type= JS_BOOLEAN; + + cp = js_string_to_c_string (vm, &args[1]); + result_return->u.vboolean = (chdir (cp) == 0); + js_free (cp); + } + /* ********************************************************************** */ + else if (method == ctx->s_exit) + { + INSECURE (); + + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_INTEGER) + goto argument_type_error; + + /* Exit. */ + exit (args[1].u.vinteger); + } + /* ********************************************************************** */ + else if (method == ctx->s_getcwd) + { + int size = 10 * 1024; + + INSECURE (); + + if (args->u.vinteger != 0) + goto argument_error; + + cp = js_malloc (vm, size); + if (!getcwd (cp, size)) + { + result_return->type = JS_BOOLEAN; + result_return->u.vboolean = 0; + js_free (cp); + } + else + { + js_vm_make_string (vm, result_return, cp, strlen (cp)); + js_free (cp); + } + } + /* ********************************************************************** */ + else if (method == ctx->s_getenv) + { + char *val; + + 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]); + val = getenv (cp); + js_free (cp); + + if (val) + js_vm_make_string (vm, result_return, val, strlen (val)); + } + /* ********************************************************************** */ + else if (method == ctx->s_popen) + { + char *cmd, *mode; + FILE *fp; + int readp = 0; + + INSECURE (); + + if (args->u.vinteger != 2) + goto argument_error; + if (args[1].type != JS_STRING || args[2].type != JS_STRING + || args[2].u.vstring->len > 10) + goto argument_type_error; + + cmd = js_string_to_c_string (vm, &args[1]); + mode = js_string_to_c_string (vm, &args[2]); + + for (i = 0; mode[i]; i++) + if (mode[i] == 'r') + readp = 1; + + JS_VM_ALLOCATE_FD (vm, "System.popen()"); + fp = popen (cmd, mode); + + if (fp == NULL) + JS_VM_FREE_FD (vm); + else + js_builtin_File_new (vm, result_return, cmd, + js_iostream_pipe (fp, readp), 0); + + js_free (cmd); + js_free (mode); + } + /* ********************************************************************** */ + else if (method == ctx->s_print || method == ctx->s_error) + { + JSIOStream *stream; + + if (method == ctx->s_print) + stream = vm->s_stdout; + else + stream = vm->s_stderr; + + for (i = 1; i <= args->u.vinteger; i++) + { + JSNode result; + + js_vm_to_string (vm, &args[i], &result); + js_iostream_write (stream, result.u.vstring->data, + result.u.vstring->len); + } + } + /* ********************************************************************** */ + else if (method == ctx->s_sleep) + { + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_INTEGER) + goto argument_type_error; + + sleep (args[1].u.vinteger); + } + /* ********************************************************************** */ + else if (method == ctx->s_strerror) + { + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_INTEGER) + goto argument_type_error; + + cp = strerror (args[1].u.vinteger); + js_vm_make_string (vm, result_return, cp, strlen (cp)); + } + /* ********************************************************************** */ + else if (method == ctx->s_system) + { + INSECURE (); + + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_STRING) + goto argument_type_error; + + result_return->type = JS_INTEGER; + + cp = js_string_to_c_string (vm, &args[1]); + result_return->u.vinteger = system (cp); + js_free (cp); + } + /* ********************************************************************** */ + else if (method == vm->syms.s_toString) + { + if (args->u.vinteger != 0) + goto argument_error; + + js_vm_make_static_string (vm, result_return, "System", 6); + } + /* ********************************************************************** */ + else if (method == ctx->s_usleep) + { + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_INTEGER) + goto argument_type_error; + + usleep (args[1].u.vinteger); + } + /* ********************************************************************** */ + else + return JS_PROPERTY_UNKNOWN; + + return JS_PROPERTY_FOUND; + + + /* + * Error handling. + */ + + argument_error: + sprintf (vm->error, "System.%s(): illegal amout of arguments", + js_vm_symname (vm, method)); + js_vm_error (vm); + + argument_type_error: + sprintf (vm->error, "System.%s(): illegal argument", + js_vm_symname (vm, method)); + js_vm_error (vm); + + insecure_feature: + sprintf (vm->error, "System.%s(): not allowed in secure mode", + 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) +{ + SystemCtx *ctx = builtin_info->obj_context; + + if (property == ctx->s_bits) + { + if (set) + goto immutable; + + node->type = JS_INTEGER; +#if SIZEOF_INT == 2 + node->u.vinteger = 16; +#else /* not SIZEOF_INT == 2 */ + +#if SIZEOF_LONG == 4 + node->u.vinteger = 32; +#else /* not SIZEOF_LONG == 4 */ + +#if SIZEOF_LONG == 8 + node->u.vinteger = 64; +#else /* not SIZEOF_LONG == 8 */ + + /* Do not know. */ + node->u.vinteger = 0; + +#endif /* not SIZEOF_LONG == 8 */ +#endif /* not SIZEOF_LONG == 4 */ +#endif /* not SIZEOF_INT == 2 */ + } + else if (property == ctx->s_canonicalHost) + { + if (set) + goto immutable; + + js_vm_make_static_string (vm, node, CANONICAL_HOST, + strlen (CANONICAL_HOST)); + } + else if (property == ctx->s_canonicalHostCPU) + { + if (set) + goto immutable; + + js_vm_make_static_string (vm, node, CANONICAL_HOST_CPU, + strlen (CANONICAL_HOST_CPU)); + } + else if (property == ctx->s_canonicalHostVendor) + { + if (set) + goto immutable; + + js_vm_make_static_string (vm, node, CANONICAL_HOST_VENDOR, + strlen (CANONICAL_HOST_VENDOR)); + } + else if (property == ctx->s_canonicalHostOS) + { + if (set) + goto immutable; + + js_vm_make_static_string (vm, node, CANONICAL_HOST_OS, + strlen (CANONICAL_HOST_OS)); + } + else if (property == ctx->s_errno) + { + if (set) + goto immutable; + + node->type = JS_INTEGER; + node->u.vinteger = errno; + } + else if (property == ctx->s_lineBreakSequence) + { + if (set) + goto immutable; + + js_vm_make_static_string (vm, node, JS_HOST_LINE_BREAK, + JS_HOST_LINE_BREAK_LEN); + } + else if (property == ctx->s_stderr) + { + if (set) + goto immutable; + + JS_COPY (node, &ctx->pstderr); + } + else if (property == ctx->s_stdin) + { + if (set) + goto immutable; + + JS_COPY (node, &ctx->pstdin); + } + else if (property == ctx->s_stdout) + { + if (set) + goto immutable; + + JS_COPY (node, &ctx->pstdout); + } + + else + { + if (!set) + node->type = JS_UNDEFINED; + + return JS_PROPERTY_UNKNOWN; + } + + return JS_PROPERTY_FOUND; + + + /* + * Error handling. + */ + + immutable: + sprintf (vm->error, "System.%s: immutable property", + js_vm_symname (vm, property)); + js_vm_error (vm); + + /* NOTREACHED. */ + return 0; +} + +/* Mark proc. */ +static void +mark (JSBuiltinInfo *builtin_info, void *instance_context) +{ + SystemCtx *ctx = builtin_info->obj_context; + + js_vm_mark (&ctx->pstderr); + js_vm_mark (&ctx->pstdin); + js_vm_mark (&ctx->pstdout); +} + + +/* + * Global functions. + */ + +void +js_builtin_System (JSVirtualMachine *vm) +{ + JSNode *n; + JSBuiltinInfo *info; + SystemCtx *ctx; + + ctx = js_calloc (vm, 1, sizeof (*ctx)); + + ctx->s_chdir = js_vm_intern (vm, "chdir"); + ctx->s_error = js_vm_intern (vm, "error"); + ctx->s_exit = js_vm_intern (vm, "exit"); + ctx->s_getcwd = js_vm_intern (vm, "getcwd"); + ctx->s_getenv = js_vm_intern (vm, "getenv"); + ctx->s_popen = js_vm_intern (vm, "popen"); + ctx->s_print = js_vm_intern (vm, "print"); + ctx->s_sleep = js_vm_intern (vm, "sleep"); + ctx->s_strerror = js_vm_intern (vm, "strerror"); + ctx->s_system = js_vm_intern (vm, "system"); + ctx->s_usleep = js_vm_intern (vm, "usleep"); + + ctx->s_bits = js_vm_intern (vm, "bits"); + ctx->s_canonicalHost = js_vm_intern (vm, "canonicalHost"); + ctx->s_canonicalHostCPU = js_vm_intern (vm, "canonicalHostCPU"); + ctx->s_canonicalHostVendor = js_vm_intern (vm, "canonicalHostVendor"); + ctx->s_canonicalHostOS = js_vm_intern (vm, "canonicalHostOS"); + ctx->s_errno = js_vm_intern (vm, "errno"); + ctx->s_lineBreakSequence = js_vm_intern (vm, "lineBreakSequence"); + ctx->s_stderr = js_vm_intern (vm, "stderr"); + ctx->s_stdin = js_vm_intern (vm, "stdin"); + ctx->s_stdout = js_vm_intern (vm, "stdout"); + + /* Object information. */ + + info = js_vm_builtin_info_create (vm); + + info->method_proc = method; + info->property_proc = property; + info->mark_proc = mark; + info->obj_context = ctx; + info->obj_context_delete = js_free; + + /* Define it. */ + n = &vm->globals[js_vm_intern (vm, "System")]; + js_vm_builtin_create (vm, n, info, NULL); + + /* Enter system properties. */ + js_builtin_File_new (vm, &ctx->pstderr, "stdout", vm->s_stderr, 1); + js_builtin_File_new (vm, &ctx->pstdin, "stdin", vm->s_stdin, 1); + js_builtin_File_new (vm, &ctx->pstdout, "stdout", vm->s_stdout, 1); +} diff --git a/reactos/lib/kjs/src/b_vm.c b/reactos/lib/kjs/src/b_vm.c new file mode 100644 index 00000000000..9f0942953be --- /dev/null +++ b/reactos/lib/kjs/src/b_vm.c @@ -0,0 +1,445 @@ +/* + * The builtin VM object. + * Copyright (c) 1998-1999 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/b_vm.c,v $ + * $Id: b_vm.c,v 1.1 2004/01/10 20:38:18 arty 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 + */ + +#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); +} diff --git a/reactos/lib/kjs/src/bc.c b/reactos/lib/kjs/src/bc.c new file mode 100644 index 00000000000..9f46176082a --- /dev/null +++ b/reactos/lib/kjs/src/bc.c @@ -0,0 +1,224 @@ +/* + * Byte code handling routines. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/bc.c,v $ + * $Id: bc.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" + +/* + * Global functions. + */ + +JSByteCode * +js_bc_read_file (FILE *fp) +{ + unsigned char header[8]; + JSUInt32 ui; + int i, got; + JSByteCode *bc = NULL; + + if ((i = fgetc (fp)) == '#') + { + /* Skip the first line. */ + while ((i = fgetc (fp)) != EOF && i != '\n') + ; + if (i == EOF) + goto format_error; + } + else + ungetc (i, fp); + + got = fread (header, 4, 2, fp); + if (got != 2) + goto format_error; + + JS_BC_READ_INT32 (header, ui); + if (ui != JS_BC_FILE_MAGIC) + goto format_error; + + bc = js_calloc (NULL, 1, sizeof (*bc)); + if (bc == NULL) + return NULL; + + + JS_BC_READ_INT32 (header + 4, ui); + bc->num_sects = (unsigned int) ui; + + bc->sects = js_calloc (NULL, bc->num_sects, sizeof (JSBCSect)); + if (bc->sects == NULL) + { + js_free (bc); + return NULL; + } + + /* Read sections. */ + for (i = 0; i < bc->num_sects; i++) + { + got = fread (header, 4, 2, fp); + if (got != 2) + goto format_error; + + /* Get type. */ + JS_BC_READ_INT32 (header, ui); + bc->sects[i].type = (int) ui; + + /* Get section length. */ + JS_BC_READ_INT32 (header + 4, ui); + bc->sects[i].length = (unsigned int) ui; + bc->sects[i].data = js_malloc (NULL, bc->sects[i].length + 1 + /* +1 to avoid zero allocations */); + if (bc->sects[i].data == NULL) + { + for (i--; i >= 0; i--) + js_free (bc->sects[i].data); + + js_free (bc->sects); + js_free (bc); + return NULL; + } + + + /* Read section's data. */ + got = fread (bc->sects[i].data, 1, bc->sects[i].length, fp); + if (got != bc->sects[i].length) + goto format_error; + } + + return bc; + + format_error: + + if (bc) + js_bc_free (bc); + + return NULL; +} + + +JSByteCode * +js_bc_read_data (unsigned char *data, unsigned int datalen) +{ + JSUInt32 ui; + unsigned int pos = 0; + int i; + JSByteCode *bc = NULL; + + if (data[pos] == '#') + { + /* Skip the first line. */ + for (; pos < datalen && data[pos] != '\n'; pos++) + ; + if (pos >= datalen) + goto format_error; + } + + if (datalen - pos < 8) + goto format_error; + + JS_BC_READ_INT32 (data + pos, ui); + if (ui != JS_BC_FILE_MAGIC) + goto format_error; + pos += 4; + + bc = js_calloc (NULL, 1, sizeof (*bc)); + if (bc == NULL) + return NULL; + + JS_BC_READ_INT32 (data + pos, ui); + bc->num_sects = (unsigned int) ui; + pos += 4; + + bc->sects = js_calloc (NULL, bc->num_sects, sizeof (JSBCSect)); + if (bc->sects == NULL) + { + js_free (bc); + return NULL; + } + + /* Read sections. */ + for (i = 0; i < bc->num_sects; i++) + { + if (datalen - pos < 8) + goto format_error; + + /* Get type. */ + JS_BC_READ_INT32 (data + pos, ui); + bc->sects[i].type = (int) ui; + pos += 4; + + /* Get section length. */ + JS_BC_READ_INT32 (data + pos, ui); + bc->sects[i].length = (unsigned int) ui; + pos += 4; + + bc->sects[i].data = js_malloc (NULL, bc->sects[i].length + 1 + /* +1 to avoid zero allocations */); + if (bc->sects[i].data == NULL) + { + for (i--; i >= 0; i--) + js_free (bc->sects[i].data); + + js_free (bc->sects); + js_free (bc); + return NULL; + } + + /* Read section's data. */ + if (datalen - pos < bc->sects[i].length) + goto format_error; + + memcpy (bc->sects[i].data, data + pos, bc->sects[i].length); + pos += bc->sects[i].length; + } + + if (pos != datalen) + goto format_error; + + return bc; + + + format_error: + + if (bc) + js_bc_free (bc); + + return NULL; +} + + +void +js_bc_free (JSByteCode *bc) +{ + int i; + + for (i = 0; i < bc->num_sects; i++) + if (bc->sects[i].data) + js_free (bc->sects[i].data); + + js_free (bc->sects); + js_free (bc); +} diff --git a/reactos/lib/kjs/src/c1jumps.h b/reactos/lib/kjs/src/c1jumps.h new file mode 100644 index 00000000000..e879f6c9e96 --- /dev/null +++ b/reactos/lib/kjs/src/c1jumps.h @@ -0,0 +1,521 @@ +/* operand halt (0) */ +case 0: + SAVE_OP (&&op_halt); + cp += 0; + break; + +/* operand done (1) */ +case 1: + SAVE_OP (&&op_done); + cp += 0; + break; + +/* operand nop (2) */ +case 2: + SAVE_OP (&&op_nop); + cp += 0; + break; + +/* operand dup (3) */ +case 3: + SAVE_OP (&&op_dup); + cp += 0; + break; + +/* operand pop (4) */ +case 4: + SAVE_OP (&&op_pop); + cp += 0; + break; + +/* operand pop_n (5) */ +case 5: + SAVE_OP (&&op_pop_n); + JS_BC_READ_INT8 (cp, i); + SAVE_INT8 (i); + cp += 1; + break; + +/* operand apop (6) */ +case 6: + SAVE_OP (&&op_apop); + JS_BC_READ_INT8 (cp, i); + SAVE_INT8 (i); + cp += 1; + break; + +/* operand swap (7) */ +case 7: + SAVE_OP (&&op_swap); + cp += 0; + break; + +/* operand roll (8) */ +case 8: + SAVE_OP (&&op_roll); + JS_BC_READ_INT8 (cp, i); + SAVE_INT8 (i); + cp += 1; + break; + +/* operand const (9) */ +case 9: + SAVE_OP (&&op_const); + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + SAVE_INT32 (i); + cp += 4; + break; + +/* operand const_null (10) */ +case 10: + SAVE_OP (&&op_const_null); + cp += 0; + break; + +/* operand const_true (11) */ +case 11: + SAVE_OP (&&op_const_true); + cp += 0; + break; + +/* operand const_false (12) */ +case 12: + SAVE_OP (&&op_const_false); + cp += 0; + break; + +/* operand const_undefined (13) */ +case 13: + SAVE_OP (&&op_const_undefined); + cp += 0; + break; + +/* operand const_i0 (14) */ +case 14: + SAVE_OP (&&op_const_i0); + cp += 0; + break; + +/* operand const_i1 (15) */ +case 15: + SAVE_OP (&&op_const_i1); + cp += 0; + break; + +/* operand const_i2 (16) */ +case 16: + SAVE_OP (&&op_const_i2); + cp += 0; + break; + +/* operand const_i3 (17) */ +case 17: + SAVE_OP (&&op_const_i3); + cp += 0; + break; + +/* operand const_i (18) */ +case 18: + SAVE_OP (&&op_const_i); + JS_BC_READ_INT32 (cp, i); + SAVE_INT32 (i); + cp += 4; + break; + +/* operand load_global (19) */ +case 19: + SAVE_OP (&&op_load_global); + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + SAVE_INT32 (i); + cp += 4; + break; + +/* operand store_global (20) */ +case 20: + SAVE_OP (&&op_store_global); + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + SAVE_INT32 (i); + cp += 4; + break; + +/* operand load_arg (21) */ +case 21: + SAVE_OP (&&op_load_arg); + JS_BC_READ_INT8 (cp, i); + SAVE_INT8 (i); + cp += 1; + break; + +/* operand store_arg (22) */ +case 22: + SAVE_OP (&&op_store_arg); + JS_BC_READ_INT8 (cp, i); + SAVE_INT8 (i); + cp += 1; + break; + +/* operand load_local (23) */ +case 23: + SAVE_OP (&&op_load_local); + JS_BC_READ_INT16 (cp, i); + SAVE_INT16 (i); + cp += 2; + break; + +/* operand store_local (24) */ +case 24: + SAVE_OP (&&op_store_local); + JS_BC_READ_INT16 (cp, i); + SAVE_INT16 (i); + cp += 2; + break; + +/* operand load_property (25) */ +case 25: + SAVE_OP (&&op_load_property); + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + SAVE_INT32 (i); + cp += 4; + break; + +/* operand store_property (26) */ +case 26: + SAVE_OP (&&op_store_property); + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + SAVE_INT32 (i); + cp += 4; + break; + +/* operand load_array (27) */ +case 27: + SAVE_OP (&&op_load_array); + cp += 0; + break; + +/* operand store_array (28) */ +case 28: + SAVE_OP (&&op_store_array); + cp += 0; + break; + +/* operand nth (29) */ +case 29: + SAVE_OP (&&op_nth); + cp += 0; + break; + +/* operand cmp_eq (30) */ +case 30: + SAVE_OP (&&op_cmp_eq); + cp += 0; + break; + +/* operand cmp_ne (31) */ +case 31: + SAVE_OP (&&op_cmp_ne); + cp += 0; + break; + +/* operand cmp_lt (32) */ +case 32: + SAVE_OP (&&op_cmp_lt); + cp += 0; + break; + +/* operand cmp_gt (33) */ +case 33: + SAVE_OP (&&op_cmp_gt); + cp += 0; + break; + +/* operand cmp_le (34) */ +case 34: + SAVE_OP (&&op_cmp_le); + cp += 0; + break; + +/* operand cmp_ge (35) */ +case 35: + SAVE_OP (&&op_cmp_ge); + cp += 0; + break; + +/* operand cmp_seq (36) */ +case 36: + SAVE_OP (&&op_cmp_seq); + cp += 0; + break; + +/* operand cmp_sne (37) */ +case 37: + SAVE_OP (&&op_cmp_sne); + cp += 0; + break; + +/* operand sub (38) */ +case 38: + SAVE_OP (&&op_sub); + cp += 0; + break; + +/* operand add (39) */ +case 39: + SAVE_OP (&&op_add); + cp += 0; + break; + +/* operand mul (40) */ +case 40: + SAVE_OP (&&op_mul); + cp += 0; + break; + +/* operand div (41) */ +case 41: + SAVE_OP (&&op_div); + cp += 0; + break; + +/* operand mod (42) */ +case 42: + SAVE_OP (&&op_mod); + cp += 0; + break; + +/* operand neg (43) */ +case 43: + SAVE_OP (&&op_neg); + cp += 0; + break; + +/* operand and (44) */ +case 44: + SAVE_OP (&&op_and); + cp += 0; + break; + +/* operand not (45) */ +case 45: + SAVE_OP (&&op_not); + cp += 0; + break; + +/* operand or (46) */ +case 46: + SAVE_OP (&&op_or); + cp += 0; + break; + +/* operand xor (47) */ +case 47: + SAVE_OP (&&op_xor); + cp += 0; + break; + +/* operand shift_left (48) */ +case 48: + SAVE_OP (&&op_shift_left); + cp += 0; + break; + +/* operand shift_right (49) */ +case 49: + SAVE_OP (&&op_shift_right); + cp += 0; + break; + +/* operand shift_rright (50) */ +case 50: + SAVE_OP (&&op_shift_rright); + cp += 0; + break; + +/* operand iffalse (51) */ +case 51: + SAVE_OP (&&op_iffalse); + JS_BC_READ_INT32 (cp, i); + SAVE_INT32 (i); + cp += 4; + break; + +/* operand iftrue (52) */ +case 52: + SAVE_OP (&&op_iftrue); + JS_BC_READ_INT32 (cp, i); + SAVE_INT32 (i); + cp += 4; + break; + +/* operand call_method (53) */ +case 53: + SAVE_OP (&&op_call_method); + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + SAVE_INT32 (i); + cp += 4; + break; + +/* operand jmp (54) */ +case 54: + SAVE_OP (&&op_jmp); + JS_BC_READ_INT32 (cp, i); + SAVE_INT32 (i); + cp += 4; + break; + +/* operand jsr (55) */ +case 55: + SAVE_OP (&&op_jsr); + cp += 0; + break; + +/* operand return (56) */ +case 56: + SAVE_OP (&&op_return); + cp += 0; + break; + +/* operand typeof (57) */ +case 57: + SAVE_OP (&&op_typeof); + cp += 0; + break; + +/* operand new (58) */ +case 58: + SAVE_OP (&&op_new); + cp += 0; + break; + +/* operand delete_property (59) */ +case 59: + SAVE_OP (&&op_delete_property); + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + SAVE_INT32 (i); + cp += 4; + break; + +/* operand delete_array (60) */ +case 60: + SAVE_OP (&&op_delete_array); + cp += 0; + break; + +/* operand locals (61) */ +case 61: + SAVE_OP (&&op_locals); + JS_BC_READ_INT16 (cp, i); + SAVE_INT16 (i); + cp += 2; + break; + +/* operand min_args (62) */ +case 62: + SAVE_OP (&&op_min_args); + JS_BC_READ_INT8 (cp, i); + SAVE_INT8 (i); + cp += 1; + break; + +/* operand load_nth_arg (63) */ +case 63: + SAVE_OP (&&op_load_nth_arg); + cp += 0; + break; + +/* operand with_push (64) */ +case 64: + SAVE_OP (&&op_with_push); + cp += 0; + break; + +/* operand with_pop (65) */ +case 65: + SAVE_OP (&&op_with_pop); + JS_BC_READ_INT8 (cp, i); + SAVE_INT8 (i); + cp += 1; + break; + +/* operand try_push (66) */ +case 66: + SAVE_OP (&&op_try_push); + JS_BC_READ_INT32 (cp, i); + SAVE_INT32 (i); + cp += 4; + break; + +/* operand try_pop (67) */ +case 67: + SAVE_OP (&&op_try_pop); + JS_BC_READ_INT8 (cp, i); + SAVE_INT8 (i); + cp += 1; + break; + +/* operand throw (68) */ +case 68: + SAVE_OP (&&op_throw); + cp += 0; + break; + +/* operand iffalse_b (69) */ +case 69: + SAVE_OP (&&op_iffalse_b); + JS_BC_READ_INT32 (cp, i); + SAVE_INT32 (i); + cp += 4; + break; + +/* operand iftrue_b (70) */ +case 70: + SAVE_OP (&&op_iftrue_b); + JS_BC_READ_INT32 (cp, i); + SAVE_INT32 (i); + cp += 4; + break; + +/* operand add_1_i (71) */ +case 71: + SAVE_OP (&&op_add_1_i); + cp += 0; + break; + +/* operand add_2_i (72) */ +case 72: + SAVE_OP (&&op_add_2_i); + cp += 0; + break; + +/* operand load_global_w (73) */ +case 73: + SAVE_OP (&&op_load_global_w); + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + SAVE_INT32 (i); + cp += 4; + break; + +/* operand jsr_w (74) */ +case 74: + SAVE_OP (&&op_jsr_w); + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + SAVE_INT32 (i); + cp += 4; + break; + diff --git a/reactos/lib/kjs/src/c1switch.h b/reactos/lib/kjs/src/c1switch.h new file mode 100644 index 00000000000..36a04a6dc6c --- /dev/null +++ b/reactos/lib/kjs/src/c1switch.h @@ -0,0 +1,521 @@ +/* operand halt (0) */ +case 0: + SAVE_OP (0); + cp += 0; + break; + +/* operand done (1) */ +case 1: + SAVE_OP (1); + cp += 0; + break; + +/* operand nop (2) */ +case 2: + SAVE_OP (2); + cp += 0; + break; + +/* operand dup (3) */ +case 3: + SAVE_OP (3); + cp += 0; + break; + +/* operand pop (4) */ +case 4: + SAVE_OP (4); + cp += 0; + break; + +/* operand pop_n (5) */ +case 5: + SAVE_OP (5); + JS_BC_READ_INT8 (cp, i); + SAVE_INT8 (i); + cp += 1; + break; + +/* operand apop (6) */ +case 6: + SAVE_OP (6); + JS_BC_READ_INT8 (cp, i); + SAVE_INT8 (i); + cp += 1; + break; + +/* operand swap (7) */ +case 7: + SAVE_OP (7); + cp += 0; + break; + +/* operand roll (8) */ +case 8: + SAVE_OP (8); + JS_BC_READ_INT8 (cp, i); + SAVE_INT8 (i); + cp += 1; + break; + +/* operand const (9) */ +case 9: + SAVE_OP (9); + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + SAVE_INT32 (i); + cp += 4; + break; + +/* operand const_null (10) */ +case 10: + SAVE_OP (10); + cp += 0; + break; + +/* operand const_true (11) */ +case 11: + SAVE_OP (11); + cp += 0; + break; + +/* operand const_false (12) */ +case 12: + SAVE_OP (12); + cp += 0; + break; + +/* operand const_undefined (13) */ +case 13: + SAVE_OP (13); + cp += 0; + break; + +/* operand const_i0 (14) */ +case 14: + SAVE_OP (14); + cp += 0; + break; + +/* operand const_i1 (15) */ +case 15: + SAVE_OP (15); + cp += 0; + break; + +/* operand const_i2 (16) */ +case 16: + SAVE_OP (16); + cp += 0; + break; + +/* operand const_i3 (17) */ +case 17: + SAVE_OP (17); + cp += 0; + break; + +/* operand const_i (18) */ +case 18: + SAVE_OP (18); + JS_BC_READ_INT32 (cp, i); + SAVE_INT32 (i); + cp += 4; + break; + +/* operand load_global (19) */ +case 19: + SAVE_OP (19); + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + SAVE_INT32 (i); + cp += 4; + break; + +/* operand store_global (20) */ +case 20: + SAVE_OP (20); + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + SAVE_INT32 (i); + cp += 4; + break; + +/* operand load_arg (21) */ +case 21: + SAVE_OP (21); + JS_BC_READ_INT8 (cp, i); + SAVE_INT8 (i); + cp += 1; + break; + +/* operand store_arg (22) */ +case 22: + SAVE_OP (22); + JS_BC_READ_INT8 (cp, i); + SAVE_INT8 (i); + cp += 1; + break; + +/* operand load_local (23) */ +case 23: + SAVE_OP (23); + JS_BC_READ_INT16 (cp, i); + SAVE_INT16 (i); + cp += 2; + break; + +/* operand store_local (24) */ +case 24: + SAVE_OP (24); + JS_BC_READ_INT16 (cp, i); + SAVE_INT16 (i); + cp += 2; + break; + +/* operand load_property (25) */ +case 25: + SAVE_OP (25); + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + SAVE_INT32 (i); + cp += 4; + break; + +/* operand store_property (26) */ +case 26: + SAVE_OP (26); + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + SAVE_INT32 (i); + cp += 4; + break; + +/* operand load_array (27) */ +case 27: + SAVE_OP (27); + cp += 0; + break; + +/* operand store_array (28) */ +case 28: + SAVE_OP (28); + cp += 0; + break; + +/* operand nth (29) */ +case 29: + SAVE_OP (29); + cp += 0; + break; + +/* operand cmp_eq (30) */ +case 30: + SAVE_OP (30); + cp += 0; + break; + +/* operand cmp_ne (31) */ +case 31: + SAVE_OP (31); + cp += 0; + break; + +/* operand cmp_lt (32) */ +case 32: + SAVE_OP (32); + cp += 0; + break; + +/* operand cmp_gt (33) */ +case 33: + SAVE_OP (33); + cp += 0; + break; + +/* operand cmp_le (34) */ +case 34: + SAVE_OP (34); + cp += 0; + break; + +/* operand cmp_ge (35) */ +case 35: + SAVE_OP (35); + cp += 0; + break; + +/* operand cmp_seq (36) */ +case 36: + SAVE_OP (36); + cp += 0; + break; + +/* operand cmp_sne (37) */ +case 37: + SAVE_OP (37); + cp += 0; + break; + +/* operand sub (38) */ +case 38: + SAVE_OP (38); + cp += 0; + break; + +/* operand add (39) */ +case 39: + SAVE_OP (39); + cp += 0; + break; + +/* operand mul (40) */ +case 40: + SAVE_OP (40); + cp += 0; + break; + +/* operand div (41) */ +case 41: + SAVE_OP (41); + cp += 0; + break; + +/* operand mod (42) */ +case 42: + SAVE_OP (42); + cp += 0; + break; + +/* operand neg (43) */ +case 43: + SAVE_OP (43); + cp += 0; + break; + +/* operand and (44) */ +case 44: + SAVE_OP (44); + cp += 0; + break; + +/* operand not (45) */ +case 45: + SAVE_OP (45); + cp += 0; + break; + +/* operand or (46) */ +case 46: + SAVE_OP (46); + cp += 0; + break; + +/* operand xor (47) */ +case 47: + SAVE_OP (47); + cp += 0; + break; + +/* operand shift_left (48) */ +case 48: + SAVE_OP (48); + cp += 0; + break; + +/* operand shift_right (49) */ +case 49: + SAVE_OP (49); + cp += 0; + break; + +/* operand shift_rright (50) */ +case 50: + SAVE_OP (50); + cp += 0; + break; + +/* operand iffalse (51) */ +case 51: + SAVE_OP (51); + JS_BC_READ_INT32 (cp, i); + SAVE_INT32 (i); + cp += 4; + break; + +/* operand iftrue (52) */ +case 52: + SAVE_OP (52); + JS_BC_READ_INT32 (cp, i); + SAVE_INT32 (i); + cp += 4; + break; + +/* operand call_method (53) */ +case 53: + SAVE_OP (53); + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + SAVE_INT32 (i); + cp += 4; + break; + +/* operand jmp (54) */ +case 54: + SAVE_OP (54); + JS_BC_READ_INT32 (cp, i); + SAVE_INT32 (i); + cp += 4; + break; + +/* operand jsr (55) */ +case 55: + SAVE_OP (55); + cp += 0; + break; + +/* operand return (56) */ +case 56: + SAVE_OP (56); + cp += 0; + break; + +/* operand typeof (57) */ +case 57: + SAVE_OP (57); + cp += 0; + break; + +/* operand new (58) */ +case 58: + SAVE_OP (58); + cp += 0; + break; + +/* operand delete_property (59) */ +case 59: + SAVE_OP (59); + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + SAVE_INT32 (i); + cp += 4; + break; + +/* operand delete_array (60) */ +case 60: + SAVE_OP (60); + cp += 0; + break; + +/* operand locals (61) */ +case 61: + SAVE_OP (61); + JS_BC_READ_INT16 (cp, i); + SAVE_INT16 (i); + cp += 2; + break; + +/* operand min_args (62) */ +case 62: + SAVE_OP (62); + JS_BC_READ_INT8 (cp, i); + SAVE_INT8 (i); + cp += 1; + break; + +/* operand load_nth_arg (63) */ +case 63: + SAVE_OP (63); + cp += 0; + break; + +/* operand with_push (64) */ +case 64: + SAVE_OP (64); + cp += 0; + break; + +/* operand with_pop (65) */ +case 65: + SAVE_OP (65); + JS_BC_READ_INT8 (cp, i); + SAVE_INT8 (i); + cp += 1; + break; + +/* operand try_push (66) */ +case 66: + SAVE_OP (66); + JS_BC_READ_INT32 (cp, i); + SAVE_INT32 (i); + cp += 4; + break; + +/* operand try_pop (67) */ +case 67: + SAVE_OP (67); + JS_BC_READ_INT8 (cp, i); + SAVE_INT8 (i); + cp += 1; + break; + +/* operand throw (68) */ +case 68: + SAVE_OP (68); + cp += 0; + break; + +/* operand iffalse_b (69) */ +case 69: + SAVE_OP (69); + JS_BC_READ_INT32 (cp, i); + SAVE_INT32 (i); + cp += 4; + break; + +/* operand iftrue_b (70) */ +case 70: + SAVE_OP (70); + JS_BC_READ_INT32 (cp, i); + SAVE_INT32 (i); + cp += 4; + break; + +/* operand add_1_i (71) */ +case 71: + SAVE_OP (71); + cp += 0; + break; + +/* operand add_2_i (72) */ +case 72: + SAVE_OP (72); + cp += 0; + break; + +/* operand load_global_w (73) */ +case 73: + SAVE_OP (73); + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + SAVE_INT32 (i); + cp += 4; + break; + +/* operand jsr_w (74) */ +case 74: + SAVE_OP (74); + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + SAVE_INT32 (i); + cp += 4; + break; + diff --git a/reactos/lib/kjs/src/c1swt0.h b/reactos/lib/kjs/src/c1swt0.h new file mode 100644 index 00000000000..190c40f3b0a --- /dev/null +++ b/reactos/lib/kjs/src/c1swt0.h @@ -0,0 +1,410 @@ +/* operand halt (0) */ +case 0: + cp += 0; + break; + +/* operand done (1) */ +case 1: + cp += 0; + break; + +/* operand nop (2) */ +case 2: + cp += 0; + break; + +/* operand dup (3) */ +case 3: + cp += 0; + break; + +/* operand pop (4) */ +case 4: + cp += 0; + break; + +/* operand pop_n (5) */ +case 5: + cp += 1; + break; + +/* operand apop (6) */ +case 6: + cp += 1; + break; + +/* operand swap (7) */ +case 7: + cp += 0; + break; + +/* operand roll (8) */ +case 8: + cp += 1; + break; + +/* operand const (9) */ +case 9: + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + JS_BC_WRITE_INT32 (cp, i); + cp += 4; + break; + +/* operand const_null (10) */ +case 10: + cp += 0; + break; + +/* operand const_true (11) */ +case 11: + cp += 0; + break; + +/* operand const_false (12) */ +case 12: + cp += 0; + break; + +/* operand const_undefined (13) */ +case 13: + cp += 0; + break; + +/* operand const_i0 (14) */ +case 14: + cp += 0; + break; + +/* operand const_i1 (15) */ +case 15: + cp += 0; + break; + +/* operand const_i2 (16) */ +case 16: + cp += 0; + break; + +/* operand const_i3 (17) */ +case 17: + cp += 0; + break; + +/* operand const_i (18) */ +case 18: + cp += 4; + break; + +/* operand load_global (19) */ +case 19: + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + JS_BC_WRITE_INT32 (cp, i); + cp += 4; + break; + +/* operand store_global (20) */ +case 20: + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + JS_BC_WRITE_INT32 (cp, i); + cp += 4; + break; + +/* operand load_arg (21) */ +case 21: + cp += 1; + break; + +/* operand store_arg (22) */ +case 22: + cp += 1; + break; + +/* operand load_local (23) */ +case 23: + cp += 2; + break; + +/* operand store_local (24) */ +case 24: + cp += 2; + break; + +/* operand load_property (25) */ +case 25: + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + JS_BC_WRITE_INT32 (cp, i); + cp += 4; + break; + +/* operand store_property (26) */ +case 26: + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + JS_BC_WRITE_INT32 (cp, i); + cp += 4; + break; + +/* operand load_array (27) */ +case 27: + cp += 0; + break; + +/* operand store_array (28) */ +case 28: + cp += 0; + break; + +/* operand nth (29) */ +case 29: + cp += 0; + break; + +/* operand cmp_eq (30) */ +case 30: + cp += 0; + break; + +/* operand cmp_ne (31) */ +case 31: + cp += 0; + break; + +/* operand cmp_lt (32) */ +case 32: + cp += 0; + break; + +/* operand cmp_gt (33) */ +case 33: + cp += 0; + break; + +/* operand cmp_le (34) */ +case 34: + cp += 0; + break; + +/* operand cmp_ge (35) */ +case 35: + cp += 0; + break; + +/* operand cmp_seq (36) */ +case 36: + cp += 0; + break; + +/* operand cmp_sne (37) */ +case 37: + cp += 0; + break; + +/* operand sub (38) */ +case 38: + cp += 0; + break; + +/* operand add (39) */ +case 39: + cp += 0; + break; + +/* operand mul (40) */ +case 40: + cp += 0; + break; + +/* operand div (41) */ +case 41: + cp += 0; + break; + +/* operand mod (42) */ +case 42: + cp += 0; + break; + +/* operand neg (43) */ +case 43: + cp += 0; + break; + +/* operand and (44) */ +case 44: + cp += 0; + break; + +/* operand not (45) */ +case 45: + cp += 0; + break; + +/* operand or (46) */ +case 46: + cp += 0; + break; + +/* operand xor (47) */ +case 47: + cp += 0; + break; + +/* operand shift_left (48) */ +case 48: + cp += 0; + break; + +/* operand shift_right (49) */ +case 49: + cp += 0; + break; + +/* operand shift_rright (50) */ +case 50: + cp += 0; + break; + +/* operand iffalse (51) */ +case 51: + cp += 4; + break; + +/* operand iftrue (52) */ +case 52: + cp += 4; + break; + +/* operand call_method (53) */ +case 53: + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + JS_BC_WRITE_INT32 (cp, i); + cp += 4; + break; + +/* operand jmp (54) */ +case 54: + cp += 4; + break; + +/* operand jsr (55) */ +case 55: + cp += 0; + break; + +/* operand return (56) */ +case 56: + cp += 0; + break; + +/* operand typeof (57) */ +case 57: + cp += 0; + break; + +/* operand new (58) */ +case 58: + cp += 0; + break; + +/* operand delete_property (59) */ +case 59: + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + JS_BC_WRITE_INT32 (cp, i); + cp += 4; + break; + +/* operand delete_array (60) */ +case 60: + cp += 0; + break; + +/* operand locals (61) */ +case 61: + cp += 2; + break; + +/* operand min_args (62) */ +case 62: + cp += 1; + break; + +/* operand load_nth_arg (63) */ +case 63: + cp += 0; + break; + +/* operand with_push (64) */ +case 64: + cp += 0; + break; + +/* operand with_pop (65) */ +case 65: + cp += 1; + break; + +/* operand try_push (66) */ +case 66: + cp += 4; + break; + +/* operand try_pop (67) */ +case 67: + cp += 1; + break; + +/* operand throw (68) */ +case 68: + cp += 0; + break; + +/* operand iffalse_b (69) */ +case 69: + cp += 4; + break; + +/* operand iftrue_b (70) */ +case 70: + cp += 4; + break; + +/* operand add_1_i (71) */ +case 71: + cp += 0; + break; + +/* operand add_2_i (72) */ +case 72: + cp += 0; + break; + +/* operand load_global_w (73) */ +case 73: + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + JS_BC_WRITE_INT32 (cp, i); + cp += 4; + break; + +/* operand jsr_w (74) */ +case 74: + JS_BC_READ_INT32 (cp, i); + i += consts_offset; + i = vm->consts[i].u.vsymbol; + JS_BC_WRITE_INT32 (cp, i); + cp += 4; + break; + diff --git a/reactos/lib/kjs/src/c2jumps.h b/reactos/lib/kjs/src/c2jumps.h new file mode 100644 index 00000000000..6c67af828f8 --- /dev/null +++ b/reactos/lib/kjs/src/c2jumps.h @@ -0,0 +1,447 @@ +/* operand halt (0) */ +case 0: + cpos++; + break; + +/* operand done (1) */ +case 1: + cpos++; + break; + +/* operand nop (2) */ +case 2: + cpos++; + break; + +/* operand dup (3) */ +case 3: + cpos++; + break; + +/* operand pop (4) */ +case 4: + cpos++; + break; + +/* operand pop_n (5) */ +case 5: + cpos++; + cp += 1; + cpos++; + break; + +/* operand apop (6) */ +case 6: + cpos++; + cp += 1; + cpos++; + break; + +/* operand swap (7) */ +case 7: + cpos++; + break; + +/* operand roll (8) */ +case 8: + cpos++; + cp += 1; + cpos++; + break; + +/* operand const (9) */ +case 9: + cpos++; + cp += 4; + cpos++; + break; + +/* operand const_null (10) */ +case 10: + cpos++; + break; + +/* operand const_true (11) */ +case 11: + cpos++; + break; + +/* operand const_false (12) */ +case 12: + cpos++; + break; + +/* operand const_undefined (13) */ +case 13: + cpos++; + break; + +/* operand const_i0 (14) */ +case 14: + cpos++; + break; + +/* operand const_i1 (15) */ +case 15: + cpos++; + break; + +/* operand const_i2 (16) */ +case 16: + cpos++; + break; + +/* operand const_i3 (17) */ +case 17: + cpos++; + break; + +/* operand const_i (18) */ +case 18: + cpos++; + cp += 4; + cpos++; + break; + +/* operand load_global (19) */ +case 19: + cpos++; + cp += 4; + cpos++; + break; + +/* operand store_global (20) */ +case 20: + cpos++; + cp += 4; + cpos++; + break; + +/* operand load_arg (21) */ +case 21: + cpos++; + cp += 1; + cpos++; + break; + +/* operand store_arg (22) */ +case 22: + cpos++; + cp += 1; + cpos++; + break; + +/* operand load_local (23) */ +case 23: + cpos++; + cp += 2; + cpos++; + break; + +/* operand store_local (24) */ +case 24: + cpos++; + cp += 2; + cpos++; + break; + +/* operand load_property (25) */ +case 25: + cpos++; + cp += 4; + cpos++; + break; + +/* operand store_property (26) */ +case 26: + cpos++; + cp += 4; + cpos++; + break; + +/* operand load_array (27) */ +case 27: + cpos++; + break; + +/* operand store_array (28) */ +case 28: + cpos++; + break; + +/* operand nth (29) */ +case 29: + cpos++; + break; + +/* operand cmp_eq (30) */ +case 30: + cpos++; + break; + +/* operand cmp_ne (31) */ +case 31: + cpos++; + break; + +/* operand cmp_lt (32) */ +case 32: + cpos++; + break; + +/* operand cmp_gt (33) */ +case 33: + cpos++; + break; + +/* operand cmp_le (34) */ +case 34: + cpos++; + break; + +/* operand cmp_ge (35) */ +case 35: + cpos++; + break; + +/* operand cmp_seq (36) */ +case 36: + cpos++; + break; + +/* operand cmp_sne (37) */ +case 37: + cpos++; + break; + +/* operand sub (38) */ +case 38: + cpos++; + break; + +/* operand add (39) */ +case 39: + cpos++; + break; + +/* operand mul (40) */ +case 40: + cpos++; + break; + +/* operand div (41) */ +case 41: + cpos++; + break; + +/* operand mod (42) */ +case 42: + cpos++; + break; + +/* operand neg (43) */ +case 43: + cpos++; + break; + +/* operand and (44) */ +case 44: + cpos++; + break; + +/* operand not (45) */ +case 45: + cpos++; + break; + +/* operand or (46) */ +case 46: + cpos++; + break; + +/* operand xor (47) */ +case 47: + cpos++; + break; + +/* operand shift_left (48) */ +case 48: + cpos++; + break; + +/* operand shift_right (49) */ +case 49: + cpos++; + break; + +/* operand shift_rright (50) */ +case 50: + cpos++; + break; + +/* operand iffalse (51) */ +case 51: + cpos++; + i = ARG_INT32 (); + i = reloc[cp - code_start + 4 + i] - &f->code[cpos + 1]; + ARG_INT32 () = i; + cp += 4; + cpos++; + break; + +/* operand iftrue (52) */ +case 52: + cpos++; + i = ARG_INT32 (); + i = reloc[cp - code_start + 4 + i] - &f->code[cpos + 1]; + ARG_INT32 () = i; + cp += 4; + cpos++; + break; + +/* operand call_method (53) */ +case 53: + cpos++; + cp += 4; + cpos++; + break; + +/* operand jmp (54) */ +case 54: + cpos++; + i = ARG_INT32 (); + i = reloc[cp - code_start + 4 + i] - &f->code[cpos + 1]; + ARG_INT32 () = i; + cp += 4; + cpos++; + break; + +/* operand jsr (55) */ +case 55: + cpos++; + break; + +/* operand return (56) */ +case 56: + cpos++; + break; + +/* operand typeof (57) */ +case 57: + cpos++; + break; + +/* operand new (58) */ +case 58: + cpos++; + break; + +/* operand delete_property (59) */ +case 59: + cpos++; + cp += 4; + cpos++; + break; + +/* operand delete_array (60) */ +case 60: + cpos++; + break; + +/* operand locals (61) */ +case 61: + cpos++; + cp += 2; + cpos++; + break; + +/* operand min_args (62) */ +case 62: + cpos++; + cp += 1; + cpos++; + break; + +/* operand load_nth_arg (63) */ +case 63: + cpos++; + break; + +/* operand with_push (64) */ +case 64: + cpos++; + break; + +/* operand with_pop (65) */ +case 65: + cpos++; + cp += 1; + cpos++; + break; + +/* operand try_push (66) */ +case 66: + cpos++; + i = ARG_INT32 (); + i = reloc[cp - code_start + 4 + i] - &f->code[cpos + 1]; + ARG_INT32 () = i; + cp += 4; + cpos++; + break; + +/* operand try_pop (67) */ +case 67: + cpos++; + cp += 1; + cpos++; + break; + +/* operand throw (68) */ +case 68: + cpos++; + break; + +/* operand iffalse_b (69) */ +case 69: + cpos++; + i = ARG_INT32 (); + i = reloc[cp - code_start + 4 + i] - &f->code[cpos + 1]; + ARG_INT32 () = i; + cp += 4; + cpos++; + break; + +/* operand iftrue_b (70) */ +case 70: + cpos++; + i = ARG_INT32 (); + i = reloc[cp - code_start + 4 + i] - &f->code[cpos + 1]; + ARG_INT32 () = i; + cp += 4; + cpos++; + break; + +/* operand add_1_i (71) */ +case 71: + cpos++; + break; + +/* operand add_2_i (72) */ +case 72: + cpos++; + break; + +/* operand load_global_w (73) */ +case 73: + cpos++; + cp += 4; + cpos++; + break; + +/* operand jsr_w (74) */ +case 74: + cpos++; + cp += 4; + cpos++; + break; + diff --git a/reactos/lib/kjs/src/c2switch.h b/reactos/lib/kjs/src/c2switch.h new file mode 100644 index 00000000000..a388f7778a3 --- /dev/null +++ b/reactos/lib/kjs/src/c2switch.h @@ -0,0 +1,447 @@ +/* operand halt (0) */ +case 0: + cpos++; + break; + +/* operand done (1) */ +case 1: + cpos++; + break; + +/* operand nop (2) */ +case 2: + cpos++; + break; + +/* operand dup (3) */ +case 3: + cpos++; + break; + +/* operand pop (4) */ +case 4: + cpos++; + break; + +/* operand pop_n (5) */ +case 5: + cpos++; + cp += 1; + cpos++; + break; + +/* operand apop (6) */ +case 6: + cpos++; + cp += 1; + cpos++; + break; + +/* operand swap (7) */ +case 7: + cpos++; + break; + +/* operand roll (8) */ +case 8: + cpos++; + cp += 1; + cpos++; + break; + +/* operand const (9) */ +case 9: + cpos++; + cp += 4; + cpos++; + break; + +/* operand const_null (10) */ +case 10: + cpos++; + break; + +/* operand const_true (11) */ +case 11: + cpos++; + break; + +/* operand const_false (12) */ +case 12: + cpos++; + break; + +/* operand const_undefined (13) */ +case 13: + cpos++; + break; + +/* operand const_i0 (14) */ +case 14: + cpos++; + break; + +/* operand const_i1 (15) */ +case 15: + cpos++; + break; + +/* operand const_i2 (16) */ +case 16: + cpos++; + break; + +/* operand const_i3 (17) */ +case 17: + cpos++; + break; + +/* operand const_i (18) */ +case 18: + cpos++; + cp += 4; + cpos++; + break; + +/* operand load_global (19) */ +case 19: + cpos++; + cp += 4; + cpos++; + break; + +/* operand store_global (20) */ +case 20: + cpos++; + cp += 4; + cpos++; + break; + +/* operand load_arg (21) */ +case 21: + cpos++; + cp += 1; + cpos++; + break; + +/* operand store_arg (22) */ +case 22: + cpos++; + cp += 1; + cpos++; + break; + +/* operand load_local (23) */ +case 23: + cpos++; + cp += 2; + cpos++; + break; + +/* operand store_local (24) */ +case 24: + cpos++; + cp += 2; + cpos++; + break; + +/* operand load_property (25) */ +case 25: + cpos++; + cp += 4; + cpos++; + break; + +/* operand store_property (26) */ +case 26: + cpos++; + cp += 4; + cpos++; + break; + +/* operand load_array (27) */ +case 27: + cpos++; + break; + +/* operand store_array (28) */ +case 28: + cpos++; + break; + +/* operand nth (29) */ +case 29: + cpos++; + break; + +/* operand cmp_eq (30) */ +case 30: + cpos++; + break; + +/* operand cmp_ne (31) */ +case 31: + cpos++; + break; + +/* operand cmp_lt (32) */ +case 32: + cpos++; + break; + +/* operand cmp_gt (33) */ +case 33: + cpos++; + break; + +/* operand cmp_le (34) */ +case 34: + cpos++; + break; + +/* operand cmp_ge (35) */ +case 35: + cpos++; + break; + +/* operand cmp_seq (36) */ +case 36: + cpos++; + break; + +/* operand cmp_sne (37) */ +case 37: + cpos++; + break; + +/* operand sub (38) */ +case 38: + cpos++; + break; + +/* operand add (39) */ +case 39: + cpos++; + break; + +/* operand mul (40) */ +case 40: + cpos++; + break; + +/* operand div (41) */ +case 41: + cpos++; + break; + +/* operand mod (42) */ +case 42: + cpos++; + break; + +/* operand neg (43) */ +case 43: + cpos++; + break; + +/* operand and (44) */ +case 44: + cpos++; + break; + +/* operand not (45) */ +case 45: + cpos++; + break; + +/* operand or (46) */ +case 46: + cpos++; + break; + +/* operand xor (47) */ +case 47: + cpos++; + break; + +/* operand shift_left (48) */ +case 48: + cpos++; + break; + +/* operand shift_right (49) */ +case 49: + cpos++; + break; + +/* operand shift_rright (50) */ +case 50: + cpos++; + break; + +/* operand iffalse (51) */ +case 51: + cpos++; + i = ARG_INT32 (); + i = reloc[cp - fixed_code + 4 + i] - &f->code[cpos + 1]; + ARG_INT32 () = i; + cp += 4; + cpos++; + break; + +/* operand iftrue (52) */ +case 52: + cpos++; + i = ARG_INT32 (); + i = reloc[cp - fixed_code + 4 + i] - &f->code[cpos + 1]; + ARG_INT32 () = i; + cp += 4; + cpos++; + break; + +/* operand call_method (53) */ +case 53: + cpos++; + cp += 4; + cpos++; + break; + +/* operand jmp (54) */ +case 54: + cpos++; + i = ARG_INT32 (); + i = reloc[cp - fixed_code + 4 + i] - &f->code[cpos + 1]; + ARG_INT32 () = i; + cp += 4; + cpos++; + break; + +/* operand jsr (55) */ +case 55: + cpos++; + break; + +/* operand return (56) */ +case 56: + cpos++; + break; + +/* operand typeof (57) */ +case 57: + cpos++; + break; + +/* operand new (58) */ +case 58: + cpos++; + break; + +/* operand delete_property (59) */ +case 59: + cpos++; + cp += 4; + cpos++; + break; + +/* operand delete_array (60) */ +case 60: + cpos++; + break; + +/* operand locals (61) */ +case 61: + cpos++; + cp += 2; + cpos++; + break; + +/* operand min_args (62) */ +case 62: + cpos++; + cp += 1; + cpos++; + break; + +/* operand load_nth_arg (63) */ +case 63: + cpos++; + break; + +/* operand with_push (64) */ +case 64: + cpos++; + break; + +/* operand with_pop (65) */ +case 65: + cpos++; + cp += 1; + cpos++; + break; + +/* operand try_push (66) */ +case 66: + cpos++; + i = ARG_INT32 (); + i = reloc[cp - fixed_code + 4 + i] - &f->code[cpos + 1]; + ARG_INT32 () = i; + cp += 4; + cpos++; + break; + +/* operand try_pop (67) */ +case 67: + cpos++; + cp += 1; + cpos++; + break; + +/* operand throw (68) */ +case 68: + cpos++; + break; + +/* operand iffalse_b (69) */ +case 69: + cpos++; + i = ARG_INT32 (); + i = reloc[cp - fixed_code + 4 + i] - &f->code[cpos + 1]; + ARG_INT32 () = i; + cp += 4; + cpos++; + break; + +/* operand iftrue_b (70) */ +case 70: + cpos++; + i = ARG_INT32 (); + i = reloc[cp - fixed_code + 4 + i] - &f->code[cpos + 1]; + ARG_INT32 () = i; + cp += 4; + cpos++; + break; + +/* operand add_1_i (71) */ +case 71: + cpos++; + break; + +/* operand add_2_i (72) */ +case 72: + cpos++; + break; + +/* operand load_global_w (73) */ +case 73: + cpos++; + cp += 4; + cpos++; + break; + +/* operand jsr_w (74) */ +case 74: + cpos++; + cp += 4; + cpos++; + break; + diff --git a/reactos/lib/kjs/src/compiler.c b/reactos/lib/kjs/src/compiler.c new file mode 100644 index 00000000000..01bcc7c4774 --- /dev/null +++ b/reactos/lib/kjs/src/compiler.c @@ -0,0 +1,11198 @@ +unsigned char js_compiler_bytecode[] = { + 0xc0, 0x01, 0x4a, 0x53, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0x54, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x05, + 0x0a, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x00, 0x01, 0x06, 0x02, + 0x03, 0x18, 0x00, 0x00, 0x0f, 0x2b, 0x1f, 0x45, + 0x00, 0x00, 0x0f, 0x1d, 0x17, 0x00, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x0a, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x11, 0x13, 0x00, 0x00, 0x00, 0x02, 0x0f, + 0x27, 0x14, 0x00, 0x00, 0x00, 0x02, 0x36, 0xff, + 0xff, 0xff, 0xcb, 0x17, 0x00, 0x00, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0x03, 0x37, 0x06, 0x03, 0x33, + 0x00, 0x00, 0x00, 0x05, 0x36, 0xff, 0xff, 0xff, + 0xb5, 0x13, 0x00, 0x00, 0x00, 0x02, 0x14, 0x00, + 0x00, 0x00, 0x04, 0x17, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x2f, 0x1e, 0x03, 0x45, 0x00, 0x00, + 0x00, 0x12, 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x05, 0x37, 0x06, 0x03, 0x12, 0x00, + 0x00, 0x00, 0x2a, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x76, 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, + 0x01, 0x05, 0x03, 0x0e, 0x15, 0x02, 0x35, 0x00, + 0x00, 0x00, 0x01, 0x06, 0x02, 0x03, 0x18, 0x00, + 0x00, 0x0f, 0x2b, 0x1f, 0x03, 0x45, 0x00, 0x00, + 0x00, 0x22, 0x04, 0x17, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x2a, 0x1f, 0x03, 0x46, 0x00, 0x00, + 0x00, 0x12, 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x05, 0x37, 0x06, 0x03, 0x12, 0x00, + 0x00, 0x00, 0x2f, 0x1f, 0x45, 0x00, 0x00, 0x00, + 0x1f, 0x17, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x0a, 0x1e, 0x45, 0xff, 0xff, 0xff, 0xb4, 0x13, + 0x00, 0x00, 0x00, 0x02, 0x0f, 0x27, 0x14, 0x00, + 0x00, 0x00, 0x02, 0x36, 0xff, 0xff, 0xff, 0xa3, + 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, 0x01, + 0x05, 0x03, 0x36, 0xff, 0xff, 0xff, 0x0f, 0x17, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x2f, 0x1e, + 0x03, 0x45, 0x00, 0x00, 0x00, 0x12, 0x04, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x05, 0x37, + 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x2f, 0x1e, + 0x03, 0x46, 0x00, 0x00, 0x00, 0x22, 0x04, 0x17, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x23, 0x1e, + 0x03, 0x45, 0x00, 0x00, 0x00, 0x12, 0x04, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x05, 0x37, + 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x21, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x4a, 0x0e, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x00, 0x01, 0x06, 0x02, 0x03, + 0x18, 0x00, 0x00, 0x0f, 0x2b, 0x1f, 0x03, 0x45, + 0x00, 0x00, 0x00, 0x0a, 0x04, 0x17, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x0a, 0x1f, 0x45, 0x00, + 0x00, 0x00, 0x05, 0x36, 0xff, 0xff, 0xff, 0xd5, + 0x17, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x0a, + 0x1e, 0x45, 0x00, 0x00, 0x0d, 0xb6, 0x13, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x27, 0x14, 0x00, 0x00, + 0x00, 0x02, 0x36, 0x00, 0x00, 0x0d, 0xa5, 0x17, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x22, 0x1e, + 0x03, 0x46, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x17, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x27, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x1e, 0x17, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x06, 0x15, 0x02, 0x11, + 0x13, 0x00, 0x00, 0x00, 0x07, 0x37, 0x06, 0x05, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x08, 0x38, 0x17, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x3d, 0x1e, 0x03, 0x45, 0x00, 0x00, + 0x00, 0x12, 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x05, 0x37, 0x06, 0x03, 0x12, 0x00, + 0x00, 0x00, 0x3d, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x36, 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, + 0x01, 0x05, 0x03, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x05, 0x37, 0x06, 0x03, 0x12, 0x00, + 0x00, 0x00, 0x3d, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x10, 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, + 0x01, 0x05, 0x03, 0x13, 0x00, 0x00, 0x00, 0x09, + 0x38, 0x13, 0x00, 0x00, 0x00, 0x0a, 0x38, 0x17, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x21, 0x1e, + 0x03, 0x45, 0x00, 0x00, 0x00, 0x12, 0x04, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x05, 0x37, + 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x3d, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x36, 0x0e, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x00, 0x01, 0x05, 0x03, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x05, 0x37, + 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x3d, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x00, 0x01, 0x05, 0x03, 0x13, + 0x00, 0x00, 0x00, 0x0b, 0x38, 0x13, 0x00, 0x00, + 0x00, 0x0c, 0x38, 0x17, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x3c, 0x1e, 0x03, 0x45, 0x00, 0x00, + 0x00, 0x12, 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x05, 0x37, 0x06, 0x03, 0x12, 0x00, + 0x00, 0x00, 0x3d, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x10, 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, + 0x01, 0x05, 0x03, 0x13, 0x00, 0x00, 0x00, 0x0d, + 0x38, 0x17, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x3e, 0x1e, 0x03, 0x45, 0x00, 0x00, 0x00, 0x12, + 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0x05, 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, + 0x3d, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x10, 0x0e, + 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, 0x01, 0x05, + 0x03, 0x13, 0x00, 0x00, 0x00, 0x0e, 0x38, 0x17, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x26, 0x1e, + 0x03, 0x45, 0x00, 0x00, 0x00, 0x12, 0x04, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x05, 0x37, + 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x26, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x00, 0x01, 0x05, 0x03, 0x13, + 0x00, 0x00, 0x00, 0x0f, 0x38, 0x17, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x7c, 0x1e, 0x03, 0x45, + 0x00, 0x00, 0x00, 0x12, 0x04, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0x05, 0x37, 0x06, 0x03, + 0x12, 0x00, 0x00, 0x00, 0x7c, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x10, 0x0e, 0x15, 0x02, 0x35, 0x00, + 0x00, 0x00, 0x01, 0x05, 0x03, 0x13, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x17, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x2b, 0x1e, 0x03, 0x45, 0x00, 0x00, + 0x00, 0x12, 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x05, 0x37, 0x06, 0x03, 0x12, 0x00, + 0x00, 0x00, 0x2b, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x10, 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, + 0x01, 0x05, 0x03, 0x13, 0x00, 0x00, 0x00, 0x11, + 0x38, 0x17, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x2d, 0x1e, 0x03, 0x45, 0x00, 0x00, 0x00, 0x12, + 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0x05, 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, + 0x2d, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x10, 0x0e, + 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, 0x01, 0x05, + 0x03, 0x13, 0x00, 0x00, 0x00, 0x12, 0x38, 0x17, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x2a, 0x1e, + 0x03, 0x45, 0x00, 0x00, 0x00, 0x12, 0x04, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x05, 0x37, + 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x3d, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x00, 0x01, 0x05, 0x03, 0x13, + 0x00, 0x00, 0x00, 0x13, 0x38, 0x17, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x2f, 0x1e, 0x03, 0x45, + 0x00, 0x00, 0x00, 0x12, 0x04, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0x05, 0x37, 0x06, 0x03, + 0x12, 0x00, 0x00, 0x00, 0x3d, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x10, 0x0e, 0x15, 0x02, 0x35, 0x00, + 0x00, 0x00, 0x01, 0x05, 0x03, 0x13, 0x00, 0x00, + 0x00, 0x14, 0x38, 0x17, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x25, 0x1e, 0x03, 0x45, 0x00, 0x00, + 0x00, 0x12, 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x05, 0x37, 0x06, 0x03, 0x12, 0x00, + 0x00, 0x00, 0x3d, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x10, 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, + 0x01, 0x05, 0x03, 0x13, 0x00, 0x00, 0x00, 0x15, + 0x38, 0x17, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x2b, 0x1e, 0x03, 0x45, 0x00, 0x00, 0x00, 0x12, + 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0x05, 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, + 0x3d, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x10, 0x0e, + 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, 0x01, 0x05, + 0x03, 0x13, 0x00, 0x00, 0x00, 0x16, 0x38, 0x17, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x2d, 0x1e, + 0x03, 0x45, 0x00, 0x00, 0x00, 0x12, 0x04, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x05, 0x37, + 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x3d, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x00, 0x01, 0x05, 0x03, 0x13, + 0x00, 0x00, 0x00, 0x17, 0x38, 0x17, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x26, 0x1e, 0x03, 0x45, + 0x00, 0x00, 0x00, 0x12, 0x04, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0x05, 0x37, 0x06, 0x03, + 0x12, 0x00, 0x00, 0x00, 0x3d, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x10, 0x0e, 0x15, 0x02, 0x35, 0x00, + 0x00, 0x00, 0x01, 0x05, 0x03, 0x13, 0x00, 0x00, + 0x00, 0x18, 0x38, 0x17, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x5e, 0x1e, 0x03, 0x45, 0x00, 0x00, + 0x00, 0x12, 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x05, 0x37, 0x06, 0x03, 0x12, 0x00, + 0x00, 0x00, 0x3d, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x10, 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, + 0x01, 0x05, 0x03, 0x13, 0x00, 0x00, 0x00, 0x19, + 0x38, 0x17, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x7c, 0x1e, 0x03, 0x45, 0x00, 0x00, 0x00, 0x12, + 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0x05, 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, + 0x3d, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x10, 0x0e, + 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, 0x01, 0x05, + 0x03, 0x13, 0x00, 0x00, 0x00, 0x1a, 0x38, 0x17, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x3c, 0x1e, + 0x03, 0x45, 0x00, 0x00, 0x00, 0x12, 0x04, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x05, 0x37, + 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x3c, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x36, 0x0e, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x00, 0x01, 0x05, 0x03, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x05, 0x37, + 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x3d, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x00, 0x01, 0x05, 0x03, 0x13, + 0x00, 0x00, 0x00, 0x1b, 0x38, 0x13, 0x00, 0x00, + 0x00, 0x1c, 0x38, 0x17, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x3e, 0x1e, 0x03, 0x45, 0x00, 0x00, + 0x00, 0x12, 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x05, 0x37, 0x06, 0x03, 0x12, 0x00, + 0x00, 0x00, 0x3e, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x80, 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, + 0x01, 0x05, 0x03, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x05, 0x37, 0x06, 0x03, 0x18, 0x00, + 0x01, 0x17, 0x00, 0x01, 0x12, 0x00, 0x00, 0x00, + 0x3d, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x10, 0x0e, + 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, 0x01, 0x05, + 0x03, 0x13, 0x00, 0x00, 0x00, 0x1d, 0x38, 0x17, + 0x00, 0x01, 0x12, 0x00, 0x00, 0x00, 0x3e, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x36, 0x0e, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x00, 0x01, 0x05, 0x03, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x05, 0x37, + 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x3d, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x00, 0x01, 0x05, 0x03, 0x13, + 0x00, 0x00, 0x00, 0x1e, 0x38, 0x13, 0x00, 0x00, + 0x00, 0x1f, 0x38, 0x13, 0x00, 0x00, 0x00, 0x20, + 0x38, 0x17, 0x00, 0x00, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0x21, 0x37, 0x06, 0x03, 0x33, 0x00, 0x00, + 0x03, 0x46, 0x17, 0x00, 0x00, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x22, 0x35, 0x00, 0x00, 0x00, 0x23, + 0x06, 0x03, 0x18, 0x00, 0x02, 0x0e, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x00, 0x01, 0x06, 0x02, 0x03, + 0x18, 0x00, 0x00, 0x0f, 0x2b, 0x1f, 0x03, 0x45, + 0x00, 0x00, 0x00, 0x20, 0x04, 0x17, 0x00, 0x00, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0x21, 0x37, 0x06, + 0x03, 0x03, 0x34, 0x00, 0x00, 0x00, 0x0d, 0x04, + 0x17, 0x00, 0x00, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0x24, 0x37, 0x06, 0x03, 0x33, 0x00, 0x00, 0x00, + 0x20, 0x17, 0x00, 0x00, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0x25, 0x35, 0x00, 0x00, 0x00, 0x26, 0x06, + 0x03, 0x0f, 0x17, 0x00, 0x02, 0x35, 0x00, 0x00, + 0x00, 0x27, 0x05, 0x04, 0x36, 0xff, 0xff, 0xff, + 0xa4, 0x17, 0x00, 0x00, 0x0f, 0x15, 0x02, 0x35, + 0x00, 0x00, 0x00, 0x28, 0x05, 0x04, 0x17, 0x00, + 0x02, 0x09, 0x00, 0x00, 0x00, 0x29, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x06, 0x13, 0x00, 0x00, 0x00, + 0x2a, 0x38, 0x17, 0x00, 0x02, 0x09, 0x00, 0x00, + 0x00, 0x2b, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x06, + 0x13, 0x00, 0x00, 0x00, 0x2c, 0x38, 0x17, 0x00, + 0x02, 0x09, 0x00, 0x00, 0x00, 0x2d, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x06, 0x13, 0x00, 0x00, 0x00, + 0x2e, 0x38, 0x17, 0x00, 0x02, 0x09, 0x00, 0x00, + 0x00, 0x2f, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x06, + 0x13, 0x00, 0x00, 0x00, 0x30, 0x38, 0x17, 0x00, + 0x02, 0x09, 0x00, 0x00, 0x00, 0x31, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x06, 0x13, 0x00, 0x00, 0x00, + 0x32, 0x38, 0x17, 0x00, 0x02, 0x09, 0x00, 0x00, + 0x00, 0x33, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x06, + 0x13, 0x00, 0x00, 0x00, 0x34, 0x38, 0x17, 0x00, + 0x02, 0x09, 0x00, 0x00, 0x00, 0x35, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x06, 0x13, 0x00, 0x00, 0x00, + 0x36, 0x38, 0x17, 0x00, 0x02, 0x09, 0x00, 0x00, + 0x00, 0x37, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x06, + 0x13, 0x00, 0x00, 0x00, 0x38, 0x38, 0x17, 0x00, + 0x02, 0x09, 0x00, 0x00, 0x00, 0x39, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x06, 0x13, 0x00, 0x00, 0x00, + 0x3a, 0x38, 0x17, 0x00, 0x02, 0x09, 0x00, 0x00, + 0x00, 0x3b, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x06, + 0x13, 0x00, 0x00, 0x00, 0x3c, 0x38, 0x17, 0x00, + 0x02, 0x09, 0x00, 0x00, 0x00, 0x3d, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x06, 0x13, 0x00, 0x00, 0x00, + 0x3e, 0x38, 0x17, 0x00, 0x02, 0x09, 0x00, 0x00, + 0x00, 0x3f, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x06, + 0x13, 0x00, 0x00, 0x00, 0x40, 0x38, 0x17, 0x00, + 0x02, 0x09, 0x00, 0x00, 0x00, 0x41, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x06, 0x13, 0x00, 0x00, 0x00, + 0x42, 0x38, 0x17, 0x00, 0x02, 0x09, 0x00, 0x00, + 0x00, 0x43, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x06, + 0x13, 0x00, 0x00, 0x00, 0x44, 0x38, 0x17, 0x00, + 0x02, 0x09, 0x00, 0x00, 0x00, 0x45, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x06, 0x13, 0x00, 0x00, 0x00, + 0x46, 0x38, 0x17, 0x00, 0x02, 0x09, 0x00, 0x00, + 0x00, 0x47, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x06, + 0x13, 0x00, 0x00, 0x00, 0x48, 0x38, 0x17, 0x00, + 0x02, 0x09, 0x00, 0x00, 0x00, 0x49, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x06, 0x13, 0x00, 0x00, 0x00, + 0x4a, 0x38, 0x17, 0x00, 0x02, 0x09, 0x00, 0x00, + 0x00, 0x4b, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x06, + 0x13, 0x00, 0x00, 0x00, 0x4c, 0x38, 0x17, 0x00, + 0x02, 0x09, 0x00, 0x00, 0x00, 0x4d, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x06, 0x13, 0x00, 0x00, 0x00, + 0x4e, 0x38, 0x17, 0x00, 0x02, 0x09, 0x00, 0x00, + 0x00, 0x4f, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x06, + 0x13, 0x00, 0x00, 0x00, 0x50, 0x38, 0x17, 0x00, + 0x02, 0x09, 0x00, 0x00, 0x00, 0x51, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x06, 0x13, 0x00, 0x00, 0x00, + 0x52, 0x38, 0x17, 0x00, 0x02, 0x09, 0x00, 0x00, + 0x00, 0x53, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x06, + 0x13, 0x00, 0x00, 0x00, 0x54, 0x38, 0x17, 0x00, + 0x02, 0x09, 0x00, 0x00, 0x00, 0x55, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x06, 0x13, 0x00, 0x00, 0x00, + 0x56, 0x38, 0x17, 0x00, 0x02, 0x09, 0x00, 0x00, + 0x00, 0x57, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x06, + 0x13, 0x00, 0x00, 0x00, 0x58, 0x38, 0x17, 0x00, + 0x02, 0x09, 0x00, 0x00, 0x00, 0x59, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x06, 0x13, 0x00, 0x00, 0x00, + 0x5a, 0x38, 0x17, 0x00, 0x02, 0x09, 0x00, 0x00, + 0x00, 0x5b, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x06, + 0x13, 0x00, 0x00, 0x00, 0x5c, 0x38, 0x17, 0x00, + 0x02, 0x09, 0x00, 0x00, 0x00, 0x5d, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x06, 0x13, 0x00, 0x00, 0x00, + 0x5e, 0x38, 0x17, 0x00, 0x02, 0x09, 0x00, 0x00, + 0x00, 0x5f, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x06, + 0x13, 0x00, 0x00, 0x00, 0x60, 0x38, 0x17, 0x00, + 0x02, 0x09, 0x00, 0x00, 0x00, 0x61, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x06, 0x13, 0x00, 0x00, 0x00, + 0x62, 0x38, 0x17, 0x00, 0x02, 0x09, 0x00, 0x00, + 0x00, 0x63, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x06, + 0x13, 0x00, 0x00, 0x00, 0x64, 0x38, 0x17, 0x00, + 0x02, 0x09, 0x00, 0x00, 0x00, 0x65, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x06, 0x13, 0x00, 0x00, 0x00, + 0x66, 0x38, 0x17, 0x00, 0x02, 0x09, 0x00, 0x00, + 0x00, 0x67, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x06, + 0x13, 0x00, 0x00, 0x00, 0x68, 0x38, 0x17, 0x00, + 0x02, 0x09, 0x00, 0x00, 0x00, 0x69, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x06, 0x13, 0x00, 0x00, 0x00, + 0x6a, 0x38, 0x17, 0x00, 0x02, 0x09, 0x00, 0x00, + 0x00, 0x6b, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x06, + 0x13, 0x00, 0x00, 0x00, 0x6c, 0x38, 0x17, 0x00, + 0x02, 0x09, 0x00, 0x00, 0x00, 0x6d, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x06, 0x13, 0x00, 0x00, 0x00, + 0x6e, 0x38, 0x17, 0x00, 0x02, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x6f, 0x38, + 0x17, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x23, + 0x1e, 0x03, 0x45, 0x00, 0x00, 0x00, 0x12, 0x04, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x05, + 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x27, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0xd8, 0x0e, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x00, 0x01, 0x05, 0x03, + 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, 0x01, + 0x06, 0x02, 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x5c, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x58, 0x09, 0x00, 0x00, 0x00, 0x70, + 0x0e, 0x15, 0x02, 0x11, 0x13, 0x00, 0x00, 0x00, + 0x71, 0x37, 0x06, 0x05, 0x14, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, + 0x01, 0x06, 0x02, 0x12, 0x00, 0x00, 0x00, 0x27, + 0x1f, 0x45, 0x00, 0x00, 0x00, 0x82, 0x13, 0x00, + 0x00, 0x00, 0x72, 0x09, 0x00, 0x00, 0x00, 0x73, + 0x27, 0x0e, 0x13, 0x00, 0x00, 0x00, 0x02, 0x35, + 0x00, 0x00, 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, + 0x00, 0x00, 0x00, 0x75, 0x27, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x76, 0x37, 0x05, 0x04, 0x36, 0x00, + 0x00, 0x00, 0x55, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x05, 0x37, 0x06, 0x03, 0x12, 0x00, + 0x00, 0x00, 0x27, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x17, 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, + 0x01, 0x05, 0x03, 0x17, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, + 0x13, 0x00, 0x00, 0x00, 0x72, 0x09, 0x00, 0x00, + 0x00, 0x73, 0x27, 0x0e, 0x13, 0x00, 0x00, 0x00, + 0x02, 0x35, 0x00, 0x00, 0x00, 0x74, 0x06, 0x02, + 0x27, 0x09, 0x00, 0x00, 0x00, 0x75, 0x27, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0x76, 0x37, 0x05, 0x04, + 0x13, 0x00, 0x00, 0x00, 0x77, 0x38, 0x17, 0x00, + 0x00, 0x12, 0x00, 0x00, 0x00, 0x30, 0x1e, 0x03, + 0x45, 0x00, 0x00, 0x00, 0x12, 0x04, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0x05, 0x37, 0x06, + 0x03, 0x12, 0x00, 0x00, 0x00, 0x2e, 0x1f, 0x03, + 0x45, 0x00, 0x00, 0x00, 0x12, 0x04, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0x05, 0x37, 0x06, + 0x03, 0x12, 0x00, 0x00, 0x00, 0x65, 0x1f, 0x03, + 0x45, 0x00, 0x00, 0x00, 0x12, 0x04, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0x05, 0x37, 0x06, + 0x03, 0x12, 0x00, 0x00, 0x00, 0x45, 0x1f, 0x45, + 0x00, 0x00, 0x00, 0xf4, 0x0e, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, + 0x00, 0x01, 0x06, 0x02, 0x18, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x78, 0x1e, + 0x03, 0x46, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x17, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x58, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x69, 0x0e, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x00, 0x01, 0x06, 0x02, 0x18, + 0x00, 0x00, 0x17, 0x00, 0x00, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x78, 0x37, 0x06, 0x03, 0x33, 0x00, + 0x00, 0x00, 0x39, 0x13, 0x00, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x10, 0x28, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0x79, 0x37, 0x06, 0x03, 0x27, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, + 0x00, 0x01, 0x06, 0x02, 0x18, 0x00, 0x00, 0x36, + 0xff, 0xff, 0xff, 0xb6, 0x17, 0x00, 0x00, 0x0f, + 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, 0x28, 0x05, + 0x04, 0x36, 0x00, 0x00, 0x00, 0x54, 0x17, 0x00, + 0x00, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x7a, 0x37, + 0x06, 0x03, 0x33, 0x00, 0x00, 0x00, 0x36, 0x13, + 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x08, 0x28, 0x14, 0x00, 0x00, 0x00, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x30, 0x26, 0x27, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x0e, 0x15, 0x02, 0x35, 0x00, + 0x00, 0x00, 0x01, 0x06, 0x02, 0x18, 0x00, 0x00, + 0x36, 0xff, 0xff, 0xff, 0xb9, 0x17, 0x00, 0x00, + 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, 0x28, + 0x05, 0x04, 0x13, 0x00, 0x00, 0x00, 0x77, 0x38, + 0x17, 0x00, 0x00, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0x24, 0x37, 0x06, 0x03, 0x03, 0x34, 0x00, 0x00, + 0x00, 0x25, 0x04, 0x17, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x2e, 0x1e, 0x03, 0x45, 0x00, 0x00, + 0x00, 0x15, 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x05, 0x37, 0x06, 0x03, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0x24, 0x37, 0x06, 0x03, 0x33, + 0x00, 0x00, 0x02, 0xdc, 0x0c, 0x18, 0x00, 0x02, + 0x17, 0x00, 0x00, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0x25, 0x35, 0x00, 0x00, 0x00, 0x26, 0x06, 0x03, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0x22, 0x3a, 0x07, + 0x06, 0x03, 0x18, 0x00, 0x03, 0x0b, 0x18, 0x00, + 0x04, 0x17, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x2e, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x58, 0x0b, + 0x18, 0x00, 0x02, 0x0e, 0x15, 0x02, 0x35, 0x00, + 0x00, 0x00, 0x01, 0x06, 0x02, 0x18, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0x24, 0x37, 0x06, 0x03, 0x33, 0x00, 0x00, 0x00, + 0x2d, 0x17, 0x00, 0x00, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0x25, 0x35, 0x00, 0x00, 0x00, 0x26, 0x06, + 0x03, 0x0f, 0x17, 0x00, 0x03, 0x35, 0x00, 0x00, + 0x00, 0x27, 0x05, 0x04, 0x0e, 0x15, 0x02, 0x35, + 0x00, 0x00, 0x00, 0x01, 0x06, 0x02, 0x18, 0x00, + 0x00, 0x36, 0xff, 0xff, 0xff, 0xc2, 0x0c, 0x18, + 0x00, 0x04, 0x36, 0x00, 0x00, 0x00, 0x4b, 0x0e, + 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, 0x01, 0x06, + 0x02, 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0x24, 0x37, 0x06, 0x03, + 0x33, 0x00, 0x00, 0x00, 0x2d, 0x17, 0x00, 0x00, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0x25, 0x35, 0x00, + 0x00, 0x00, 0x26, 0x06, 0x03, 0x0f, 0x17, 0x00, + 0x03, 0x35, 0x00, 0x00, 0x00, 0x27, 0x05, 0x04, + 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, 0x01, + 0x06, 0x02, 0x18, 0x00, 0x00, 0x36, 0xff, 0xff, + 0xff, 0xc2, 0x17, 0x00, 0x04, 0x03, 0x33, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x17, 0x00, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x2e, 0x1e, 0x03, 0x34, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x17, 0x00, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x65, 0x1e, 0x03, 0x34, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x17, 0x00, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x45, 0x1e, 0x33, 0x00, 0x00, + 0x01, 0x8b, 0x0b, 0x18, 0x00, 0x02, 0x17, 0x00, + 0x00, 0x12, 0x00, 0x00, 0x00, 0x2e, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x66, 0x17, 0x00, 0x00, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0x25, 0x35, 0x00, 0x00, + 0x00, 0x26, 0x06, 0x03, 0x0f, 0x17, 0x00, 0x03, + 0x35, 0x00, 0x00, 0x00, 0x27, 0x05, 0x04, 0x0e, + 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, 0x01, 0x06, + 0x02, 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0x24, 0x37, 0x06, 0x03, + 0x33, 0x00, 0x00, 0x00, 0x2d, 0x17, 0x00, 0x00, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0x25, 0x35, 0x00, + 0x00, 0x00, 0x26, 0x06, 0x03, 0x0f, 0x17, 0x00, + 0x03, 0x35, 0x00, 0x00, 0x00, 0x27, 0x05, 0x04, + 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, 0x01, + 0x06, 0x02, 0x18, 0x00, 0x00, 0x36, 0xff, 0xff, + 0xff, 0xc2, 0x17, 0x00, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x65, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0a, 0x04, 0x17, 0x00, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x45, 0x1e, 0x45, 0x00, 0x00, 0x00, 0xf5, + 0x17, 0x00, 0x00, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0x25, 0x35, 0x00, 0x00, 0x00, 0x26, 0x06, 0x03, + 0x0f, 0x17, 0x00, 0x03, 0x35, 0x00, 0x00, 0x00, + 0x27, 0x05, 0x04, 0x0e, 0x15, 0x02, 0x35, 0x00, + 0x00, 0x00, 0x01, 0x06, 0x02, 0x18, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x2b, + 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x17, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x2d, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x2d, 0x17, 0x00, + 0x00, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x25, 0x35, + 0x00, 0x00, 0x00, 0x26, 0x06, 0x03, 0x0f, 0x17, + 0x00, 0x03, 0x35, 0x00, 0x00, 0x00, 0x27, 0x05, + 0x04, 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, + 0x01, 0x06, 0x02, 0x18, 0x00, 0x00, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0x24, 0x37, 0x06, 0x03, 0x2d, + 0x33, 0x00, 0x00, 0x00, 0x2d, 0x13, 0x00, 0x00, + 0x00, 0x72, 0x09, 0x00, 0x00, 0x00, 0x73, 0x27, + 0x0e, 0x13, 0x00, 0x00, 0x00, 0x02, 0x35, 0x00, + 0x00, 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, + 0x00, 0x00, 0x7b, 0x27, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0x76, 0x37, 0x05, 0x04, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x17, 0x00, 0x00, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x24, 0x37, 0x06, 0x03, 0x33, 0x00, + 0x00, 0x00, 0x2d, 0x17, 0x00, 0x00, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0x25, 0x35, 0x00, 0x00, 0x00, + 0x26, 0x06, 0x03, 0x0f, 0x17, 0x00, 0x03, 0x35, + 0x00, 0x00, 0x00, 0x27, 0x05, 0x04, 0x0e, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x00, 0x01, 0x06, 0x02, + 0x18, 0x00, 0x00, 0x36, 0xff, 0xff, 0xff, 0xc2, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, + 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, 0x28, + 0x05, 0x04, 0x17, 0x00, 0x02, 0x33, 0x00, 0x00, + 0x00, 0x17, 0x17, 0x00, 0x03, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x7c, 0x37, 0x06, 0x03, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x7d, + 0x38, 0x17, 0x00, 0x03, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0x7e, 0x37, 0x06, 0x03, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x77, 0x38, + 0x17, 0x00, 0x00, 0x38, 0x36, 0xff, 0xff, 0xf0, + 0xcd, 0x13, 0x00, 0x00, 0x00, 0x7f, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x01, 0x0e, + 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, 0x01, 0x06, + 0x02, 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, 0x0f, + 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, 0x28, 0x05, + 0x04, 0x17, 0x00, 0x00, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x03, 0x12, 0x00, 0x00, 0x00, 0x61, 0x15, + 0x02, 0x22, 0x03, 0x45, 0x00, 0x00, 0x00, 0x09, + 0x04, 0x15, 0x02, 0x12, 0x00, 0x00, 0x00, 0x7a, + 0x22, 0x03, 0x46, 0x00, 0x00, 0x00, 0x18, 0x04, + 0x12, 0x00, 0x00, 0x00, 0x41, 0x15, 0x02, 0x22, + 0x03, 0x45, 0x00, 0x00, 0x00, 0x09, 0x04, 0x15, + 0x02, 0x12, 0x00, 0x00, 0x00, 0x5a, 0x22, 0x03, + 0x46, 0x00, 0x00, 0x00, 0x09, 0x04, 0x15, 0x02, + 0x12, 0x00, 0x00, 0x00, 0x24, 0x1e, 0x03, 0x46, + 0x00, 0x00, 0x00, 0x09, 0x04, 0x15, 0x02, 0x12, + 0x00, 0x00, 0x00, 0x5f, 0x1e, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x12, 0x00, 0x00, 0x00, 0x30, + 0x15, 0x02, 0x22, 0x03, 0x45, 0x00, 0x00, 0x00, + 0x09, 0x04, 0x15, 0x02, 0x12, 0x00, 0x00, 0x00, + 0x37, 0x22, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, + 0x12, 0x00, 0x00, 0x00, 0x30, 0x15, 0x02, 0x22, + 0x03, 0x45, 0x00, 0x00, 0x00, 0x09, 0x04, 0x15, + 0x02, 0x12, 0x00, 0x00, 0x00, 0x39, 0x22, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x12, 0x00, 0x00, + 0x00, 0x30, 0x15, 0x02, 0x22, 0x03, 0x45, 0x00, + 0x00, 0x00, 0x09, 0x04, 0x15, 0x02, 0x12, 0x00, + 0x00, 0x00, 0x39, 0x22, 0x03, 0x46, 0x00, 0x00, + 0x00, 0x18, 0x04, 0x12, 0x00, 0x00, 0x00, 0x61, + 0x15, 0x02, 0x22, 0x03, 0x45, 0x00, 0x00, 0x00, + 0x09, 0x04, 0x15, 0x02, 0x12, 0x00, 0x00, 0x00, + 0x66, 0x22, 0x03, 0x46, 0x00, 0x00, 0x00, 0x18, + 0x04, 0x12, 0x00, 0x00, 0x00, 0x41, 0x15, 0x02, + 0x22, 0x03, 0x45, 0x00, 0x00, 0x00, 0x09, 0x04, + 0x15, 0x02, 0x12, 0x00, 0x00, 0x00, 0x46, 0x22, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x15, 0x02, + 0x12, 0x00, 0x00, 0x00, 0x20, 0x1e, 0x03, 0x46, + 0x00, 0x00, 0x00, 0x09, 0x04, 0x15, 0x02, 0x12, + 0x00, 0x00, 0x00, 0x09, 0x1e, 0x03, 0x46, 0x00, + 0x00, 0x00, 0x09, 0x04, 0x15, 0x02, 0x12, 0x00, + 0x00, 0x00, 0x0b, 0x1e, 0x03, 0x46, 0x00, 0x00, + 0x00, 0x09, 0x04, 0x15, 0x02, 0x12, 0x00, 0x00, + 0x00, 0x0d, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x09, 0x04, 0x15, 0x02, 0x12, 0x00, 0x00, 0x00, + 0x0c, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, 0x09, + 0x04, 0x15, 0x02, 0x12, 0x00, 0x00, 0x00, 0x0a, + 0x1e, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x12, + 0x00, 0x00, 0x00, 0x30, 0x15, 0x02, 0x22, 0x03, + 0x45, 0x00, 0x00, 0x00, 0x09, 0x04, 0x15, 0x02, + 0x12, 0x00, 0x00, 0x00, 0x39, 0x22, 0x45, 0x00, + 0x00, 0x00, 0x0d, 0x15, 0x02, 0x12, 0x00, 0x00, + 0x00, 0x30, 0x26, 0x36, 0x00, 0x00, 0x00, 0x3d, + 0x12, 0x00, 0x00, 0x00, 0x61, 0x15, 0x02, 0x22, + 0x03, 0x45, 0x00, 0x00, 0x00, 0x09, 0x04, 0x15, + 0x02, 0x12, 0x00, 0x00, 0x00, 0x66, 0x22, 0x45, + 0x00, 0x00, 0x00, 0x13, 0x12, 0x00, 0x00, 0x00, + 0x0a, 0x15, 0x02, 0x27, 0x12, 0x00, 0x00, 0x00, + 0x61, 0x26, 0x36, 0x00, 0x00, 0x00, 0x0e, 0x12, + 0x00, 0x00, 0x00, 0x0a, 0x15, 0x02, 0x27, 0x12, + 0x00, 0x00, 0x00, 0x41, 0x26, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x05, 0x3d, 0x00, 0x05, 0x0e, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x00, 0x01, 0x06, 0x02, + 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x6e, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x0d, 0x12, 0x00, 0x00, 0x00, 0x0a, 0x18, 0x00, + 0x00, 0x36, 0x00, 0x00, 0x04, 0x4c, 0x17, 0x00, + 0x00, 0x12, 0x00, 0x00, 0x00, 0x74, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x0d, 0x12, 0x00, 0x00, 0x00, + 0x09, 0x18, 0x00, 0x00, 0x36, 0x00, 0x00, 0x04, + 0x31, 0x17, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x76, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x0d, 0x12, + 0x00, 0x00, 0x00, 0x0b, 0x18, 0x00, 0x00, 0x36, + 0x00, 0x00, 0x04, 0x16, 0x17, 0x00, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x62, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x0d, 0x12, 0x00, 0x00, 0x00, 0x08, 0x18, + 0x00, 0x00, 0x36, 0x00, 0x00, 0x03, 0xfb, 0x17, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x72, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x0d, 0x12, 0x00, 0x00, + 0x00, 0x0d, 0x18, 0x00, 0x00, 0x36, 0x00, 0x00, + 0x03, 0xe0, 0x17, 0x00, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x66, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x0d, + 0x12, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x03, 0xc5, 0x17, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x61, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x0d, 0x12, 0x00, 0x00, 0x00, 0x07, + 0x18, 0x00, 0x00, 0x36, 0x00, 0x00, 0x03, 0xaa, + 0x17, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x5c, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x0d, 0x12, 0x00, + 0x00, 0x00, 0x5c, 0x18, 0x00, 0x00, 0x36, 0x00, + 0x00, 0x03, 0x8f, 0x17, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x3f, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x0d, 0x12, 0x00, 0x00, 0x00, 0x3f, 0x18, 0x00, + 0x00, 0x36, 0x00, 0x00, 0x03, 0x74, 0x17, 0x00, + 0x00, 0x12, 0x00, 0x00, 0x00, 0x27, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x0d, 0x12, 0x00, 0x00, 0x00, + 0x27, 0x18, 0x00, 0x00, 0x36, 0x00, 0x00, 0x03, + 0x59, 0x17, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x22, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x0d, 0x12, + 0x00, 0x00, 0x00, 0x22, 0x18, 0x00, 0x00, 0x36, + 0x00, 0x00, 0x03, 0x3e, 0x17, 0x00, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x78, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0xbe, 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, + 0x00, 0x01, 0x06, 0x02, 0x18, 0x00, 0x01, 0x0e, + 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, 0x01, 0x06, + 0x02, 0x18, 0x00, 0x02, 0x17, 0x00, 0x01, 0x0f, + 0x2b, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, 0x07, + 0x04, 0x17, 0x00, 0x02, 0x0f, 0x2b, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x12, 0x15, 0x04, 0x15, 0x03, + 0x10, 0x13, 0x00, 0x00, 0x00, 0x80, 0x37, 0x05, + 0x05, 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, + 0x01, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x78, 0x37, + 0x06, 0x03, 0x2d, 0x03, 0x34, 0x00, 0x00, 0x00, + 0x0e, 0x04, 0x17, 0x00, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x78, 0x37, 0x06, 0x03, 0x2d, 0x33, + 0x00, 0x00, 0x00, 0x2d, 0x13, 0x00, 0x00, 0x00, + 0x72, 0x09, 0x00, 0x00, 0x00, 0x73, 0x27, 0x0e, + 0x13, 0x00, 0x00, 0x00, 0x02, 0x35, 0x00, 0x00, + 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, + 0x00, 0x81, 0x27, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0x76, 0x37, 0x05, 0x04, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x17, 0x00, 0x01, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0x79, 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, + 0x00, 0x04, 0x30, 0x17, 0x00, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0x79, 0x37, 0x06, 0x03, 0x27, + 0x18, 0x00, 0x00, 0x36, 0x00, 0x00, 0x02, 0x72, + 0x17, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x75, + 0x1e, 0x45, 0x00, 0x00, 0x01, 0x40, 0x0e, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x00, 0x01, 0x06, 0x02, + 0x18, 0x00, 0x01, 0x0e, 0x15, 0x02, 0x35, 0x00, + 0x00, 0x00, 0x01, 0x06, 0x02, 0x18, 0x00, 0x02, + 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, 0x01, + 0x06, 0x02, 0x18, 0x00, 0x03, 0x0e, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x00, 0x01, 0x06, 0x02, 0x18, + 0x00, 0x04, 0x17, 0x00, 0x01, 0x0f, 0x2b, 0x1e, + 0x03, 0x46, 0x00, 0x00, 0x00, 0x07, 0x04, 0x17, + 0x00, 0x02, 0x0f, 0x2b, 0x1e, 0x03, 0x46, 0x00, + 0x00, 0x00, 0x07, 0x04, 0x17, 0x00, 0x03, 0x0f, + 0x2b, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, 0x07, + 0x04, 0x17, 0x00, 0x04, 0x0f, 0x2b, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x12, 0x15, 0x04, 0x15, 0x03, + 0x10, 0x13, 0x00, 0x00, 0x00, 0x80, 0x37, 0x05, + 0x05, 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, + 0x01, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x78, 0x37, + 0x06, 0x03, 0x2d, 0x03, 0x34, 0x00, 0x00, 0x00, + 0x0e, 0x04, 0x17, 0x00, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x78, 0x37, 0x06, 0x03, 0x2d, 0x03, + 0x34, 0x00, 0x00, 0x00, 0x0e, 0x04, 0x17, 0x00, + 0x03, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x78, 0x37, + 0x06, 0x03, 0x2d, 0x03, 0x34, 0x00, 0x00, 0x00, + 0x0e, 0x04, 0x17, 0x00, 0x04, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x78, 0x37, 0x06, 0x03, 0x2d, 0x33, + 0x00, 0x00, 0x00, 0x2d, 0x13, 0x00, 0x00, 0x00, + 0x72, 0x09, 0x00, 0x00, 0x00, 0x73, 0x27, 0x0e, + 0x13, 0x00, 0x00, 0x00, 0x02, 0x35, 0x00, 0x00, + 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, + 0x00, 0x82, 0x27, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0x76, 0x37, 0x05, 0x04, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x17, 0x00, 0x01, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0x79, 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, + 0x00, 0x0c, 0x30, 0x17, 0x00, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0x79, 0x37, 0x06, 0x03, 0x12, + 0x00, 0x00, 0x00, 0x08, 0x30, 0x27, 0x17, 0x00, + 0x03, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x79, 0x37, + 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x04, 0x30, + 0x27, 0x17, 0x00, 0x04, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0x79, 0x37, 0x06, 0x03, 0x27, 0x18, 0x00, + 0x00, 0x36, 0x00, 0x00, 0x01, 0x24, 0x17, 0x00, + 0x00, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x7a, 0x37, + 0x06, 0x03, 0x33, 0x00, 0x00, 0x00, 0x99, 0x17, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x30, 0x26, + 0x18, 0x00, 0x01, 0x0f, 0x18, 0x00, 0x02, 0x17, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x30, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x09, 0x0e, 0x18, 0x00, + 0x02, 0x36, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x00, 0x01, 0x06, 0x02, + 0x18, 0x00, 0x00, 0x17, 0x00, 0x02, 0x11, 0x20, + 0x03, 0x45, 0x00, 0x00, 0x00, 0x0d, 0x04, 0x17, + 0x00, 0x00, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x7a, + 0x37, 0x06, 0x03, 0x33, 0x00, 0x00, 0x00, 0x30, + 0x17, 0x00, 0x01, 0x12, 0x00, 0x00, 0x00, 0x08, + 0x28, 0x17, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x30, 0x26, 0x27, 0x18, 0x00, 0x01, 0x0e, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x00, 0x01, 0x06, 0x02, + 0x18, 0x00, 0x00, 0x17, 0x00, 0x02, 0x0f, 0x27, + 0x18, 0x00, 0x02, 0x36, 0xff, 0xff, 0xff, 0xb3, + 0x17, 0x00, 0x00, 0x0f, 0x15, 0x02, 0x35, 0x00, + 0x00, 0x00, 0x28, 0x05, 0x04, 0x17, 0x00, 0x01, + 0x18, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x7a, + 0x17, 0x00, 0x00, 0x0f, 0x2b, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x30, 0x13, 0x00, 0x00, 0x00, 0x72, + 0x09, 0x00, 0x00, 0x00, 0x73, 0x27, 0x0e, 0x13, + 0x00, 0x00, 0x00, 0x02, 0x35, 0x00, 0x00, 0x00, + 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, 0x00, + 0x83, 0x27, 0x15, 0x04, 0x27, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x76, 0x37, 0x05, 0x04, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x72, + 0x09, 0x00, 0x00, 0x00, 0x73, 0x27, 0x0e, 0x13, + 0x00, 0x00, 0x00, 0x02, 0x35, 0x00, 0x00, 0x00, + 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, 0x00, + 0x84, 0x27, 0x17, 0x00, 0x00, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x25, 0x35, 0x00, 0x00, 0x00, 0x26, + 0x06, 0x03, 0x27, 0x09, 0x00, 0x00, 0x00, 0x85, + 0x27, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x86, 0x37, + 0x05, 0x04, 0x17, 0x00, 0x00, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x05, 0x3d, 0x00, 0x05, 0x09, 0x00, + 0x00, 0x00, 0x87, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0x22, 0x3a, 0x07, 0x06, 0x03, 0x18, 0x00, 0x00, + 0x0c, 0x18, 0x00, 0x01, 0x13, 0x00, 0x00, 0x00, + 0x02, 0x18, 0x00, 0x03, 0x0c, 0x18, 0x00, 0x04, + 0x17, 0x00, 0x01, 0x2d, 0x33, 0x00, 0x00, 0x01, + 0x17, 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, + 0x01, 0x06, 0x02, 0x18, 0x00, 0x02, 0x17, 0x00, + 0x02, 0x12, 0x00, 0x00, 0x00, 0x0a, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x60, 0x13, 0x00, 0x00, 0x00, + 0x88, 0x03, 0x33, 0x00, 0x00, 0x00, 0x05, 0x04, + 0x17, 0x00, 0x04, 0x2d, 0x33, 0x00, 0x00, 0x00, + 0x3a, 0x13, 0x00, 0x00, 0x00, 0x72, 0x09, 0x00, + 0x00, 0x00, 0x73, 0x27, 0x0e, 0x13, 0x00, 0x00, + 0x00, 0x02, 0x35, 0x00, 0x00, 0x00, 0x74, 0x06, + 0x02, 0x27, 0x09, 0x00, 0x00, 0x00, 0x89, 0x27, + 0x15, 0x03, 0x27, 0x09, 0x00, 0x00, 0x00, 0x8a, + 0x27, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x86, 0x37, + 0x05, 0x04, 0x0b, 0x18, 0x00, 0x04, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, + 0x0f, 0x27, 0x14, 0x00, 0x00, 0x00, 0x02, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x02, 0x0f, + 0x2b, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x13, 0x15, + 0x03, 0x17, 0x00, 0x03, 0x10, 0x13, 0x00, 0x00, + 0x00, 0x80, 0x37, 0x05, 0x05, 0x36, 0xff, 0xff, + 0xff, 0x5e, 0x17, 0x00, 0x02, 0x15, 0x04, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x09, 0x0b, 0x18, 0x00, + 0x01, 0x36, 0xff, 0xff, 0xff, 0x4a, 0x17, 0x00, + 0x02, 0x12, 0x00, 0x00, 0x00, 0x5c, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x49, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0x05, 0x37, 0x06, 0x03, 0x12, + 0x00, 0x00, 0x00, 0x0a, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x1b, 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, + 0x00, 0x01, 0x05, 0x03, 0x13, 0x00, 0x00, 0x00, + 0x02, 0x0f, 0x27, 0x14, 0x00, 0x00, 0x00, 0x02, + 0x36, 0xff, 0xff, 0xff, 0x0b, 0x15, 0x03, 0x17, + 0x00, 0x03, 0x15, 0x02, 0x11, 0x13, 0x00, 0x00, + 0x00, 0x71, 0x37, 0x06, 0x05, 0x18, 0x00, 0x02, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x02, + 0x0f, 0x17, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, + 0x27, 0x05, 0x04, 0x36, 0xff, 0xff, 0xfe, 0xe0, + 0x17, 0x00, 0x00, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x3d, 0x00, 0x06, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0x8b, 0x37, 0x06, 0x03, 0x18, + 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x87, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0x22, 0x3a, 0x07, 0x06, + 0x03, 0x18, 0x00, 0x01, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0x05, 0x37, 0x06, 0x03, 0x03, + 0x14, 0x00, 0x00, 0x00, 0x8c, 0x12, 0x00, 0x00, + 0x00, 0x67, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0c, 0x04, 0x13, 0x00, 0x00, 0x00, 0x8c, 0x12, + 0x00, 0x00, 0x00, 0x69, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x2c, 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, + 0x00, 0x01, 0x05, 0x03, 0x13, 0x00, 0x00, 0x00, + 0x8c, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x25, 0x35, + 0x00, 0x00, 0x00, 0x26, 0x06, 0x03, 0x0f, 0x17, + 0x00, 0x01, 0x35, 0x00, 0x00, 0x00, 0x27, 0x05, + 0x04, 0x36, 0xff, 0xff, 0xff, 0xa6, 0x0c, 0x18, + 0x00, 0x02, 0x42, 0x00, 0x00, 0x00, 0x1b, 0x17, + 0x00, 0x01, 0x17, 0x00, 0x00, 0x10, 0x13, 0x00, + 0x00, 0x00, 0x8d, 0x3a, 0x07, 0x06, 0x04, 0x18, + 0x00, 0x03, 0x43, 0x01, 0x0c, 0x36, 0x00, 0x00, + 0x00, 0x6d, 0x0c, 0x07, 0x42, 0x00, 0x00, 0x00, + 0x63, 0x03, 0x18, 0x00, 0x04, 0x07, 0x04, 0x0b, + 0x07, 0x09, 0x00, 0x00, 0x00, 0x73, 0x0f, 0x17, + 0x00, 0x04, 0x35, 0x00, 0x00, 0x00, 0x8e, 0x06, + 0x03, 0x18, 0x00, 0x05, 0x13, 0x00, 0x00, 0x00, + 0x72, 0x09, 0x00, 0x00, 0x00, 0x73, 0x27, 0x0e, + 0x13, 0x00, 0x00, 0x00, 0x04, 0x35, 0x00, 0x00, + 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, + 0x00, 0x8f, 0x27, 0x17, 0x00, 0x05, 0x0f, 0x27, + 0x0f, 0x17, 0x00, 0x04, 0x35, 0x00, 0x00, 0x00, + 0x90, 0x06, 0x03, 0x27, 0x18, 0x00, 0x04, 0x43, + 0x01, 0x07, 0x46, 0x00, 0x00, 0x00, 0x06, 0x0b, + 0x36, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x0c, 0x36, + 0x00, 0x00, 0x00, 0x03, 0x06, 0x02, 0x0b, 0x45, + 0x00, 0x00, 0x00, 0x01, 0x44, 0x17, 0x00, 0x02, + 0x33, 0x00, 0x00, 0x00, 0x11, 0x17, 0x00, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0x76, 0x37, 0x05, + 0x04, 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, + 0x03, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x3d, + 0x00, 0x06, 0x09, 0x00, 0x00, 0x00, 0x87, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0x22, 0x3a, 0x07, 0x06, + 0x03, 0x18, 0x00, 0x00, 0x0c, 0x18, 0x00, 0x01, + 0x13, 0x00, 0x00, 0x00, 0x02, 0x18, 0x00, 0x03, + 0x0c, 0x18, 0x00, 0x04, 0x09, 0x00, 0x00, 0x00, + 0x91, 0x18, 0x00, 0x05, 0x17, 0x00, 0x01, 0x2d, + 0x33, 0x00, 0x00, 0x02, 0xb8, 0x0e, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x00, 0x01, 0x06, 0x02, 0x18, + 0x00, 0x02, 0x17, 0x00, 0x02, 0x12, 0x00, 0x00, + 0x00, 0x0a, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x67, + 0x13, 0x00, 0x00, 0x00, 0x88, 0x03, 0x33, 0x00, + 0x00, 0x00, 0x05, 0x04, 0x17, 0x00, 0x04, 0x2d, + 0x33, 0x00, 0x00, 0x00, 0x41, 0x13, 0x00, 0x00, + 0x00, 0x72, 0x09, 0x00, 0x00, 0x00, 0x73, 0x27, + 0x0e, 0x13, 0x00, 0x00, 0x00, 0x02, 0x35, 0x00, + 0x00, 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, + 0x00, 0x00, 0x92, 0x27, 0x09, 0x00, 0x00, 0x00, + 0x93, 0x27, 0x17, 0x00, 0x05, 0x27, 0x09, 0x00, + 0x00, 0x00, 0x8a, 0x27, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0x86, 0x37, 0x05, 0x04, 0x0b, 0x18, 0x00, + 0x04, 0x36, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x27, 0x14, 0x00, 0x00, + 0x00, 0x02, 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x02, 0x0f, 0x2b, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x14, 0x17, 0x00, 0x05, 0x17, 0x00, 0x03, + 0x10, 0x13, 0x00, 0x00, 0x00, 0x80, 0x37, 0x05, + 0x05, 0x36, 0xff, 0xff, 0xff, 0x56, 0x17, 0x00, + 0x02, 0x12, 0x00, 0x00, 0x00, 0x2f, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x09, 0x0b, 0x18, 0x00, 0x01, + 0x36, 0xff, 0xff, 0xff, 0x3f, 0x17, 0x00, 0x02, + 0x12, 0x00, 0x00, 0x00, 0x5c, 0x1e, 0x45, 0x00, + 0x00, 0x01, 0xd2, 0x0e, 0x15, 0x02, 0x35, 0x00, + 0x00, 0x00, 0x01, 0x06, 0x02, 0x18, 0x00, 0x02, + 0x17, 0x00, 0x02, 0x12, 0x00, 0x00, 0x00, 0x0a, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x11, 0x13, 0x00, + 0x00, 0x00, 0x02, 0x0f, 0x27, 0x14, 0x00, 0x00, + 0x00, 0x02, 0x36, 0xff, 0xff, 0xff, 0x05, 0x17, + 0x00, 0x02, 0x0f, 0x2b, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x14, 0x17, 0x00, 0x05, 0x17, 0x00, 0x03, + 0x10, 0x13, 0x00, 0x00, 0x00, 0x80, 0x37, 0x05, + 0x05, 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, + 0x02, 0x12, 0x00, 0x00, 0x00, 0x66, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x0d, 0x12, 0x00, 0x00, 0x00, + 0x0c, 0x18, 0x00, 0x02, 0x36, 0x00, 0x00, 0x01, + 0x6c, 0x17, 0x00, 0x02, 0x12, 0x00, 0x00, 0x00, + 0x6e, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x0d, 0x12, + 0x00, 0x00, 0x00, 0x0a, 0x18, 0x00, 0x02, 0x36, + 0x00, 0x00, 0x01, 0x51, 0x17, 0x00, 0x02, 0x12, + 0x00, 0x00, 0x00, 0x72, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x0d, 0x12, 0x00, 0x00, 0x00, 0x0d, 0x18, + 0x00, 0x02, 0x36, 0x00, 0x00, 0x01, 0x36, 0x17, + 0x00, 0x02, 0x12, 0x00, 0x00, 0x00, 0x74, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x0d, 0x12, 0x00, 0x00, + 0x00, 0x09, 0x18, 0x00, 0x02, 0x36, 0x00, 0x00, + 0x01, 0x1b, 0x17, 0x00, 0x02, 0x12, 0x00, 0x00, + 0x00, 0x76, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x0f, + 0x17, 0x00, 0x02, 0x12, 0x00, 0x00, 0x00, 0x0b, + 0x1e, 0x04, 0x36, 0x00, 0x00, 0x00, 0xfe, 0x17, + 0x00, 0x02, 0x12, 0x00, 0x00, 0x00, 0x63, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x88, 0x0e, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x00, 0x01, 0x06, 0x02, 0x18, + 0x00, 0x02, 0x17, 0x00, 0x02, 0x0f, 0x2b, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x14, 0x17, 0x00, 0x05, + 0x17, 0x00, 0x03, 0x10, 0x13, 0x00, 0x00, 0x00, + 0x80, 0x37, 0x05, 0x05, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x17, 0x00, 0x02, 0x12, 0x00, 0x00, 0x00, + 0x0a, 0x1e, 0x03, 0x45, 0x00, 0x00, 0x00, 0x06, + 0x04, 0x13, 0x00, 0x00, 0x00, 0x88, 0x33, 0x00, + 0x00, 0x00, 0x2d, 0x13, 0x00, 0x00, 0x00, 0x72, + 0x09, 0x00, 0x00, 0x00, 0x73, 0x27, 0x0e, 0x13, + 0x00, 0x00, 0x00, 0x02, 0x35, 0x00, 0x00, 0x00, + 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, 0x00, + 0x94, 0x27, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x86, + 0x37, 0x05, 0x04, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x95, 0x0f, 0x17, 0x00, + 0x00, 0x35, 0x00, 0x00, 0x00, 0x27, 0x05, 0x04, + 0x36, 0x00, 0x00, 0x00, 0x68, 0x17, 0x00, 0x02, + 0x12, 0x00, 0x00, 0x00, 0x75, 0x1e, 0x03, 0x46, + 0x00, 0x00, 0x00, 0x0a, 0x04, 0x17, 0x00, 0x02, + 0x12, 0x00, 0x00, 0x00, 0x78, 0x1e, 0x03, 0x46, + 0x00, 0x00, 0x00, 0x0a, 0x04, 0x17, 0x00, 0x02, + 0x12, 0x00, 0x00, 0x00, 0x30, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x20, 0x17, 0x00, 0x02, 0x0f, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x00, 0x28, 0x05, 0x04, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x71, + 0x37, 0x06, 0x03, 0x18, 0x00, 0x02, 0x36, 0x00, + 0x00, 0x00, 0x1a, 0x17, 0x00, 0x02, 0x0f, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x00, 0x28, 0x05, 0x04, + 0x12, 0x00, 0x00, 0x00, 0x5c, 0x18, 0x00, 0x02, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0x25, 0x35, 0x00, + 0x00, 0x00, 0x26, 0x06, 0x03, 0x0f, 0x17, 0x00, + 0x00, 0x35, 0x00, 0x00, 0x00, 0x27, 0x05, 0x04, + 0x36, 0xff, 0xff, 0xfd, 0x3f, 0x17, 0x00, 0x00, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x04, 0x3d, 0x00, + 0x01, 0x13, 0x00, 0x00, 0x00, 0x72, 0x09, 0x00, + 0x00, 0x00, 0x73, 0x27, 0x0e, 0x13, 0x00, 0x00, + 0x00, 0x02, 0x35, 0x00, 0x00, 0x00, 0x74, 0x06, + 0x02, 0x27, 0x09, 0x00, 0x00, 0x00, 0x83, 0x27, + 0x15, 0x03, 0x27, 0x09, 0x00, 0x00, 0x00, 0x96, + 0x27, 0x18, 0x00, 0x00, 0x15, 0x02, 0x0e, 0x21, + 0x45, 0x00, 0x00, 0x00, 0x3c, 0x17, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x97, 0x19, 0x00, 0x00, + 0x00, 0x98, 0x13, 0x00, 0x00, 0x00, 0x72, 0x27, + 0x09, 0x00, 0x00, 0x00, 0x73, 0x27, 0x0e, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x00, 0x74, 0x06, 0x02, + 0x27, 0x09, 0x00, 0x00, 0x00, 0x99, 0x27, 0x15, + 0x03, 0x27, 0x09, 0x00, 0x00, 0x00, 0x96, 0x27, + 0x27, 0x18, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x17, 0x00, 0x00, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0x76, 0x37, 0x05, 0x04, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x02, 0x0a, 0x14, 0x00, 0x00, + 0x00, 0x9a, 0x0a, 0x14, 0x00, 0x00, 0x00, 0x9b, + 0x0a, 0x14, 0x00, 0x00, 0x00, 0x9c, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x01, + 0x0f, 0x14, 0x00, 0x00, 0x00, 0x02, 0x15, 0x02, + 0x19, 0x00, 0x00, 0x00, 0x9d, 0x14, 0x00, 0x00, + 0x00, 0x72, 0x0e, 0x13, 0x00, 0x00, 0x00, 0x9e, + 0x3a, 0x07, 0x06, 0x02, 0x14, 0x00, 0x00, 0x00, + 0x9f, 0x0e, 0x13, 0x00, 0x00, 0x00, 0x9e, 0x3a, + 0x07, 0x06, 0x02, 0x14, 0x00, 0x00, 0x00, 0x9b, + 0x0e, 0x13, 0x00, 0x00, 0x00, 0x9e, 0x3a, 0x07, + 0x06, 0x02, 0x14, 0x00, 0x00, 0x00, 0x9c, 0x0e, + 0x14, 0x00, 0x00, 0x00, 0xa0, 0x0c, 0x14, 0x00, + 0x00, 0x00, 0xa1, 0x0e, 0x14, 0x00, 0x00, 0x00, + 0xa2, 0x0e, 0x14, 0x00, 0x00, 0x00, 0xa3, 0x0e, + 0x14, 0x00, 0x00, 0x00, 0xa4, 0x13, 0x00, 0x00, + 0x00, 0xa5, 0x33, 0x00, 0x00, 0x00, 0x13, 0x09, + 0x00, 0x00, 0x00, 0xa6, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xa7, 0x37, 0x05, 0x04, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xa8, 0x37, 0x06, 0x03, 0x13, 0x00, 0x00, + 0x00, 0x7f, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x1f, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa9, + 0x37, 0x06, 0x03, 0x2d, 0x33, 0xff, 0xff, 0xff, + 0xd9, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, + 0x05, 0x03, 0x36, 0xff, 0xff, 0xff, 0xcb, 0x13, + 0x00, 0x00, 0x00, 0xa5, 0x33, 0x00, 0x00, 0x00, + 0x74, 0x09, 0x00, 0x00, 0x00, 0xab, 0x0e, 0x13, + 0x00, 0x00, 0x00, 0x02, 0x0f, 0x26, 0x35, 0x00, + 0x00, 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, + 0x00, 0x00, 0xac, 0x27, 0x0e, 0x13, 0x00, 0x00, + 0x00, 0xa2, 0x35, 0x00, 0x00, 0x00, 0x74, 0x06, + 0x02, 0x27, 0x09, 0x00, 0x00, 0x00, 0xad, 0x27, + 0x18, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xa4, + 0x0e, 0x21, 0x45, 0x00, 0x00, 0x00, 0x25, 0x17, + 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xae, 0x0e, + 0x13, 0x00, 0x00, 0x00, 0xa4, 0x35, 0x00, 0x00, + 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, + 0x00, 0xaf, 0x27, 0x27, 0x18, 0x00, 0x00, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xa7, 0x37, 0x05, 0x04, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x02, 0x13, 0x00, 0x00, 0x00, + 0x72, 0x09, 0x00, 0x00, 0x00, 0x73, 0x27, 0x0e, + 0x13, 0x00, 0x00, 0x00, 0x02, 0x35, 0x00, 0x00, + 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, + 0x00, 0xb0, 0x27, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0x76, 0x37, 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x97, 0x19, 0x00, 0x00, 0x00, 0xb1, + 0x35, 0x00, 0x00, 0x00, 0xb2, 0x05, 0x04, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0x97, 0x19, 0x00, + 0x00, 0x00, 0xb1, 0x35, 0x00, 0x00, 0x00, 0xb2, + 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x3d, 0x00, 0x01, 0x13, 0x00, 0x00, 0x00, + 0xa2, 0x0f, 0x27, 0x14, 0x00, 0x00, 0x00, 0xa2, + 0x13, 0x00, 0x00, 0x00, 0xa1, 0x33, 0x00, 0x00, + 0x00, 0x27, 0x0c, 0x14, 0x00, 0x00, 0x00, 0xa1, + 0x13, 0x00, 0x00, 0x00, 0xb3, 0x14, 0x00, 0x00, + 0x00, 0xb4, 0x13, 0x00, 0x00, 0x00, 0xb5, 0x14, + 0x00, 0x00, 0x00, 0xb6, 0x13, 0x00, 0x00, 0x00, + 0xb7, 0x18, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, + 0x22, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xb8, 0x37, 0x06, 0x03, 0x18, 0x00, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0xb4, 0x13, 0x00, 0x00, 0x00, 0x04, 0x14, 0x00, + 0x00, 0x00, 0xb6, 0x17, 0x00, 0x00, 0x13, 0x00, + 0x00, 0x00, 0x6f, 0x1e, 0x03, 0x45, 0x00, 0x00, + 0x00, 0x0c, 0x04, 0x13, 0x00, 0x00, 0x00, 0xb4, + 0x09, 0x00, 0x00, 0x00, 0xb9, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x11, 0x13, 0x00, 0x00, 0x00, 0xa3, + 0x0f, 0x27, 0x14, 0x00, 0x00, 0x00, 0xa3, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x13, 0x00, 0x00, + 0x00, 0xa1, 0x33, 0x00, 0x00, 0x00, 0x06, 0x13, + 0x00, 0x00, 0x00, 0xb7, 0x38, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xb8, 0x37, 0x06, 0x03, + 0x14, 0x00, 0x00, 0x00, 0xb7, 0x13, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xb3, 0x13, + 0x00, 0x00, 0x00, 0x04, 0x14, 0x00, 0x00, 0x00, + 0xb5, 0x0b, 0x14, 0x00, 0x00, 0x00, 0xa1, 0x13, + 0x00, 0x00, 0x00, 0xb7, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x03, 0x3d, 0x00, 0x01, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, + 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x3b, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x0c, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xba, 0x37, 0x06, 0x03, 0x38, 0x17, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x7d, 0x1e, 0x03, 0x46, + 0x00, 0x00, 0x00, 0x0c, 0x04, 0x13, 0x00, 0x00, + 0x00, 0xb6, 0x13, 0x00, 0x00, 0x00, 0xb5, 0x20, + 0x03, 0x46, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x17, + 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x7f, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x49, 0x13, 0x00, 0x00, + 0x00, 0xbb, 0x33, 0x00, 0x00, 0x00, 0x2d, 0x13, + 0x00, 0x00, 0x00, 0x72, 0x09, 0x00, 0x00, 0x00, + 0x73, 0x27, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xb6, + 0x35, 0x00, 0x00, 0x00, 0x74, 0x06, 0x02, 0x27, + 0x09, 0x00, 0x00, 0x00, 0xbc, 0x27, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0x86, 0x37, 0x05, 0x04, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0xa4, 0x0f, 0x27, 0x14, 0x00, 0x00, 0x00, 0xa4, + 0x12, 0x00, 0x00, 0x00, 0x3b, 0x38, 0x0e, 0x13, + 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x15, 0x02, + 0x19, 0x00, 0x00, 0x00, 0xbd, 0x13, 0x00, 0x00, + 0x00, 0xbe, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0e, 0x04, 0x15, 0x02, 0x19, 0x00, 0x00, 0x00, + 0xbd, 0x13, 0x00, 0x00, 0x00, 0xbf, 0x1e, 0x03, + 0x46, 0x00, 0x00, 0x00, 0x0e, 0x04, 0x15, 0x02, + 0x19, 0x00, 0x00, 0x00, 0xbd, 0x13, 0x00, 0x00, + 0x00, 0xc0, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0e, 0x04, 0x15, 0x02, 0x19, 0x00, 0x00, 0x00, + 0xbd, 0x13, 0x00, 0x00, 0x00, 0xc1, 0x1e, 0x03, + 0x46, 0x00, 0x00, 0x00, 0x0e, 0x04, 0x15, 0x02, + 0x19, 0x00, 0x00, 0x00, 0xbd, 0x13, 0x00, 0x00, + 0x00, 0xc2, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0e, 0x04, 0x15, 0x02, 0x19, 0x00, 0x00, 0x00, + 0xbd, 0x13, 0x00, 0x00, 0x00, 0xc3, 0x1e, 0x03, + 0x46, 0x00, 0x00, 0x00, 0x0e, 0x04, 0x15, 0x02, + 0x19, 0x00, 0x00, 0x00, 0xbd, 0x13, 0x00, 0x00, + 0x00, 0xc4, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0e, 0x04, 0x15, 0x02, 0x19, 0x00, 0x00, 0x00, + 0xbd, 0x13, 0x00, 0x00, 0x00, 0xc5, 0x1e, 0x03, + 0x46, 0x00, 0x00, 0x00, 0x0e, 0x04, 0x15, 0x02, + 0x19, 0x00, 0x00, 0x00, 0xbd, 0x13, 0x00, 0x00, + 0x00, 0xc6, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0e, 0x04, 0x15, 0x02, 0x19, 0x00, 0x00, 0x00, + 0xbd, 0x13, 0x00, 0x00, 0x00, 0xc7, 0x1e, 0x03, + 0x46, 0x00, 0x00, 0x00, 0x0e, 0x04, 0x15, 0x02, + 0x19, 0x00, 0x00, 0x00, 0xbd, 0x13, 0x00, 0x00, + 0x00, 0xc8, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0e, 0x04, 0x15, 0x02, 0x19, 0x00, 0x00, 0x00, + 0xbd, 0x13, 0x00, 0x00, 0x00, 0xc9, 0x1e, 0x03, + 0x46, 0x00, 0x00, 0x00, 0x0e, 0x04, 0x15, 0x02, + 0x19, 0x00, 0x00, 0x00, 0xbd, 0x13, 0x00, 0x00, + 0x00, 0xca, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0e, 0x04, 0x15, 0x02, 0x19, 0x00, 0x00, 0x00, + 0xbd, 0x13, 0x00, 0x00, 0x00, 0xcb, 0x1e, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x01, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xcc, + 0x37, 0x06, 0x03, 0x33, 0x00, 0x00, 0x00, 0x02, + 0x0b, 0x38, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xcd, 0x37, 0x06, 0x03, 0x18, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x2d, 0x33, 0x00, 0x00, 0x00, + 0x02, 0x0c, 0x38, 0x17, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xce, 0x13, 0x00, 0x00, 0x00, 0xcf, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x0e, 0x0b, 0x17, + 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xd0, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0x9b, 0x35, 0x00, 0x00, + 0x00, 0xd1, 0x05, 0x04, 0x0b, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x09, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, + 0x03, 0x13, 0x00, 0x00, 0x00, 0x34, 0x1f, 0x45, + 0x00, 0x00, 0x00, 0x02, 0x0c, 0x38, 0x13, 0x00, + 0x00, 0x00, 0xa3, 0x18, 0x00, 0x03, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, + 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xba, 0x37, 0x06, 0x03, 0x13, 0x00, 0x00, 0x00, + 0x6f, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x0e, 0x0e, + 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0xb4, 0x18, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0xb6, 0x18, 0x00, 0x04, 0x17, 0x00, 0x00, + 0x18, 0x00, 0x05, 0x13, 0x00, 0x00, 0x00, 0x9c, + 0x19, 0x00, 0x00, 0x00, 0xd2, 0x0e, 0x21, 0x45, + 0x00, 0x00, 0x00, 0x23, 0x09, 0x00, 0x00, 0x00, + 0xd3, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xa0, 0x03, + 0x0f, 0x27, 0x14, 0x00, 0x00, 0x00, 0xa0, 0x35, + 0x00, 0x00, 0x00, 0x74, 0x06, 0x02, 0x27, 0x18, + 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x9c, + 0x35, 0x00, 0x00, 0x00, 0xd1, 0x05, 0x04, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, + 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x28, 0x1f, + 0x45, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, + 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x0e, 0x13, 0x00, 0x00, 0x00, + 0x9e, 0x3a, 0x07, 0x06, 0x02, 0x18, 0x00, 0x01, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa8, + 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x29, + 0x1f, 0x45, 0x00, 0x00, 0x00, 0xa0, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, 0x06, + 0x03, 0x13, 0x00, 0x00, 0x00, 0x6f, 0x1f, 0x45, + 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, + 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xb4, 0x0f, + 0x17, 0x00, 0x01, 0x35, 0x00, 0x00, 0x00, 0xd1, + 0x05, 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xa8, 0x37, 0x06, 0x03, 0x18, 0x00, 0x06, + 0x17, 0x00, 0x06, 0x12, 0x00, 0x00, 0x00, 0x2c, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x2f, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, + 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xa8, 0x37, 0x06, 0x03, 0x13, 0x00, 0x00, 0x00, + 0x6f, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x2a, 0x0e, + 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, + 0x36, 0x00, 0x00, 0x00, 0x1c, 0x17, 0x00, 0x06, + 0x12, 0x00, 0x00, 0x00, 0x29, 0x1f, 0x45, 0xff, + 0xff, 0xff, 0x5d, 0x0e, 0x13, 0x00, 0x00, 0x00, + 0xaa, 0x37, 0x05, 0x03, 0x36, 0xff, 0xff, 0xff, + 0x4f, 0x36, 0xff, 0xff, 0xff, 0x4a, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, 0x06, + 0x03, 0x12, 0x00, 0x00, 0x00, 0x29, 0x1f, 0x45, + 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, + 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xa8, 0x37, 0x05, 0x04, 0x13, 0x00, 0x00, + 0x00, 0xb5, 0x18, 0x00, 0x06, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xd4, 0x37, 0x06, 0x03, + 0x18, 0x00, 0x02, 0x17, 0x00, 0x02, 0x39, 0x09, + 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, + 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x18, 0x00, 0x07, 0x13, 0x00, 0x00, 0x00, + 0xa3, 0x17, 0x00, 0x03, 0x21, 0x45, 0x00, 0x00, + 0x00, 0x3f, 0x0b, 0x18, 0x00, 0x07, 0x13, 0x00, + 0x00, 0x00, 0xd6, 0x33, 0x00, 0x00, 0x00, 0x31, + 0x13, 0x00, 0x00, 0x00, 0x72, 0x09, 0x00, 0x00, + 0x00, 0x73, 0x27, 0x0e, 0x17, 0x00, 0x04, 0x35, + 0x00, 0x00, 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, + 0x00, 0x00, 0x00, 0xd7, 0x27, 0x09, 0x00, 0x00, + 0x00, 0xd8, 0x27, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0x86, 0x37, 0x05, 0x04, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x17, 0x00, 0x07, 0x17, 0x00, 0x02, 0x17, + 0x00, 0x01, 0x17, 0x00, 0x05, 0x17, 0x00, 0x00, + 0x17, 0x00, 0x06, 0x17, 0x00, 0x04, 0x09, 0x00, + 0x00, 0x00, 0xd9, 0x13, 0x00, 0x00, 0x00, 0xda, + 0x3a, 0x07, 0x06, 0x09, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0x9f, 0x35, 0x00, 0x00, 0x00, 0xd1, 0x05, + 0x04, 0x0e, 0x13, 0x00, 0x00, 0x00, 0x9c, 0x35, + 0x00, 0x00, 0x00, 0xdb, 0x05, 0x03, 0x0b, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x02, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa8, + 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x7b, + 0x1f, 0x45, 0x00, 0x00, 0x00, 0x02, 0x0c, 0x38, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, + 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x7b, + 0x1f, 0x04, 0x13, 0x00, 0x00, 0x00, 0xb5, 0x18, + 0x00, 0x01, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xa8, 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, + 0x00, 0x7d, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x13, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xdc, + 0x37, 0x06, 0x03, 0x18, 0x00, 0x00, 0x36, 0x00, + 0x00, 0x00, 0x0d, 0x0e, 0x13, 0x00, 0x00, 0x00, + 0x9e, 0x3a, 0x07, 0x06, 0x02, 0x18, 0x00, 0x00, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, + 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x7d, + 0x1f, 0x45, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, + 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x01, 0x17, + 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x17, + 0x00, 0x00, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, + 0x3d, 0x00, 0x03, 0x0e, 0x13, 0x00, 0x00, 0x00, + 0x9e, 0x3a, 0x07, 0x06, 0x02, 0x18, 0x00, 0x00, + 0x0c, 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, 0x2d, + 0x33, 0x00, 0x00, 0x00, 0x39, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xcd, 0x37, 0x06, 0x03, + 0x18, 0x00, 0x02, 0x17, 0x00, 0x02, 0x39, 0x09, + 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x09, 0x0b, 0x18, 0x00, 0x01, 0x36, 0xff, + 0xff, 0xff, 0xd1, 0x17, 0x00, 0x02, 0x0f, 0x17, + 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0xd1, 0x05, + 0x04, 0x36, 0xff, 0xff, 0xff, 0xbe, 0x17, 0x00, + 0x00, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x3d, + 0x00, 0x06, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xd4, 0x37, 0x06, 0x03, 0x03, 0x18, 0x00, + 0x00, 0x39, 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1f, + 0x45, 0x00, 0x00, 0x00, 0x16, 0x17, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x10, 0x13, 0x00, 0x00, 0x00, 0xde, 0x3a, 0x07, + 0x06, 0x04, 0x38, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xcc, 0x37, 0x06, 0x03, 0x33, 0x00, + 0x00, 0x00, 0x83, 0x13, 0x00, 0x00, 0x00, 0x9c, + 0x19, 0x00, 0x00, 0x00, 0xd2, 0x0e, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x10, 0x13, 0x00, 0x00, 0x00, + 0xb6, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xdf, 0x3a, + 0x07, 0x06, 0x03, 0x38, 0x0e, 0x13, 0x00, 0x00, + 0x00, 0x9c, 0x35, 0x00, 0x00, 0x00, 0xdb, 0x06, + 0x02, 0x18, 0x00, 0x02, 0x17, 0x00, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0x9c, 0x35, 0x00, 0x00, + 0x00, 0xd1, 0x05, 0x04, 0x13, 0x00, 0x00, 0x00, + 0x9f, 0x13, 0x00, 0x00, 0x00, 0x9f, 0x19, 0x00, + 0x00, 0x00, 0xd2, 0x0f, 0x26, 0x1b, 0x18, 0x00, + 0x03, 0x17, 0x00, 0x03, 0x19, 0x00, 0x00, 0x00, + 0x9d, 0x18, 0x00, 0x04, 0x17, 0x00, 0x03, 0x19, + 0x00, 0x00, 0x00, 0xe0, 0x17, 0x00, 0x04, 0x17, + 0x00, 0x02, 0x13, 0x00, 0x00, 0x00, 0xb6, 0x09, + 0x00, 0x00, 0x00, 0xe1, 0x13, 0x00, 0x00, 0x00, + 0xe2, 0x3a, 0x07, 0x06, 0x06, 0x38, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xe3, 0x37, 0x06, + 0x03, 0x03, 0x18, 0x00, 0x00, 0x39, 0x09, 0x00, + 0x00, 0x00, 0xd5, 0x1f, 0x45, 0x00, 0x00, 0x00, + 0x04, 0x17, 0x00, 0x00, 0x38, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xe4, 0x37, 0x06, 0x03, + 0x03, 0x18, 0x00, 0x00, 0x39, 0x09, 0x00, 0x00, + 0x00, 0xd5, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x04, + 0x17, 0x00, 0x00, 0x38, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xe5, 0x37, 0x06, 0x03, 0x03, + 0x18, 0x00, 0x00, 0x39, 0x09, 0x00, 0x00, 0x00, + 0xd5, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x04, 0x17, + 0x00, 0x00, 0x38, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xe6, 0x37, 0x06, 0x03, 0x03, 0x18, + 0x00, 0x00, 0x39, 0x09, 0x00, 0x00, 0x00, 0xd5, + 0x1f, 0x45, 0x00, 0x00, 0x00, 0xa2, 0x17, 0x00, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xbd, 0x13, 0x00, + 0x00, 0x00, 0xc3, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x76, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xa8, 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, + 0x3a, 0x1e, 0x03, 0x45, 0x00, 0x00, 0x00, 0x0f, + 0x04, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x13, 0x00, 0x00, 0x00, 0xb5, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x4b, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, 0x04, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xcd, 0x37, + 0x06, 0x03, 0x18, 0x00, 0x02, 0x17, 0x00, 0x02, + 0x2d, 0x33, 0x00, 0x00, 0x00, 0x0b, 0x13, 0x00, + 0x00, 0x00, 0xaa, 0x04, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x17, 0x00, 0x02, 0x17, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xe7, 0x17, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x11, 0x13, 0x00, 0x00, + 0x00, 0xe8, 0x3a, 0x07, 0x06, 0x05, 0x38, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xe9, 0x37, + 0x05, 0x04, 0x17, 0x00, 0x00, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xea, 0x3a, 0x07, 0x06, 0x03, 0x38, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa8, + 0x37, 0x06, 0x03, 0x18, 0x00, 0x01, 0x17, 0x00, + 0x01, 0x12, 0x00, 0x00, 0x00, 0x3b, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x1b, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, 0x04, 0x13, + 0x00, 0x00, 0x00, 0xb6, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xdf, 0x3a, 0x07, 0x06, 0x03, 0x38, 0x17, + 0x00, 0x01, 0x13, 0x00, 0x00, 0x00, 0x2c, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x79, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, 0x04, + 0x0a, 0x18, 0x00, 0x02, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, 0x18, + 0x00, 0x01, 0x17, 0x00, 0x01, 0x13, 0x00, 0x00, + 0x00, 0x6f, 0x1e, 0x03, 0x45, 0x00, 0x00, 0x00, + 0x0c, 0x04, 0x13, 0x00, 0x00, 0x00, 0xb6, 0x13, + 0x00, 0x00, 0x00, 0xb5, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x18, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xba, 0x37, 0x05, 0x04, 0x13, 0x00, 0x00, + 0x00, 0xb4, 0x18, 0x00, 0x02, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x17, 0x00, 0x02, 0x13, 0x00, 0x00, + 0x00, 0xb6, 0x10, 0x13, 0x00, 0x00, 0x00, 0xeb, + 0x3a, 0x07, 0x06, 0x04, 0x18, 0x00, 0x00, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xe9, 0x37, + 0x05, 0x04, 0x17, 0x00, 0x00, 0x38, 0x17, 0x00, + 0x01, 0x13, 0x00, 0x00, 0x00, 0x2a, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x79, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, 0x04, 0x0a, + 0x18, 0x00, 0x02, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, 0x18, 0x00, + 0x01, 0x17, 0x00, 0x01, 0x13, 0x00, 0x00, 0x00, + 0x6f, 0x1e, 0x03, 0x45, 0x00, 0x00, 0x00, 0x0c, + 0x04, 0x13, 0x00, 0x00, 0x00, 0xb6, 0x13, 0x00, + 0x00, 0x00, 0xb5, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x18, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xba, 0x37, 0x05, 0x04, 0x13, 0x00, 0x00, 0x00, + 0xb4, 0x18, 0x00, 0x02, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x17, 0x00, 0x02, 0x13, 0x00, 0x00, 0x00, + 0xb6, 0x10, 0x13, 0x00, 0x00, 0x00, 0xec, 0x3a, + 0x07, 0x06, 0x04, 0x18, 0x00, 0x00, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xe9, 0x37, 0x05, + 0x04, 0x17, 0x00, 0x00, 0x38, 0x17, 0x00, 0x01, + 0x13, 0x00, 0x00, 0x00, 0x3c, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0xdc, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xba, 0x37, 0x05, 0x04, 0x13, 0x00, + 0x00, 0x00, 0xb6, 0x18, 0x00, 0x02, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, + 0x03, 0x12, 0x00, 0x00, 0x00, 0x3b, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x14, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, 0x04, 0x0a, + 0x18, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x8e, + 0x13, 0x00, 0x00, 0x00, 0xb5, 0x17, 0x00, 0x02, + 0x21, 0x45, 0x00, 0x00, 0x00, 0x4a, 0x13, 0x00, + 0x00, 0x00, 0xbb, 0x33, 0x00, 0x00, 0x00, 0x2b, + 0x13, 0x00, 0x00, 0x00, 0x72, 0x09, 0x00, 0x00, + 0x00, 0x73, 0x27, 0x0e, 0x17, 0x00, 0x02, 0x35, + 0x00, 0x00, 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, + 0x00, 0x00, 0x00, 0xbc, 0x27, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x86, 0x37, 0x05, 0x04, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xa4, + 0x0f, 0x27, 0x14, 0x00, 0x00, 0x00, 0xa4, 0x0a, + 0x18, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x36, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xe6, + 0x37, 0x06, 0x03, 0x18, 0x00, 0x00, 0x17, 0x00, + 0x00, 0x39, 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, + 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xe9, 0x37, 0x05, 0x04, 0x17, 0x00, + 0x00, 0x17, 0x00, 0x02, 0x10, 0x13, 0x00, 0x00, + 0x00, 0xed, 0x3a, 0x07, 0x06, 0x04, 0x38, 0x17, + 0x00, 0x01, 0x13, 0x00, 0x00, 0x00, 0x64, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x17, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, 0x04, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xee, + 0x37, 0x06, 0x03, 0x38, 0x17, 0x00, 0x01, 0x13, + 0x00, 0x00, 0x00, 0x48, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0xc5, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xba, 0x37, 0x05, 0x04, 0x13, 0x00, 0x00, + 0x00, 0xb6, 0x18, 0x00, 0x02, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, 0x06, 0x03, + 0x12, 0x00, 0x00, 0x00, 0x28, 0x1f, 0x45, 0x00, + 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, + 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xe6, 0x37, 0x06, 0x03, 0x18, 0x00, 0x03, 0x17, + 0x00, 0x03, 0x39, 0x09, 0x00, 0x00, 0x00, 0xd5, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, + 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xba, 0x37, 0x06, 0x03, 0x12, + 0x00, 0x00, 0x00, 0x29, 0x1f, 0x45, 0x00, 0x00, + 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, + 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xcd, + 0x37, 0x06, 0x03, 0x18, 0x00, 0x04, 0x17, 0x00, + 0x04, 0x39, 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, + 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x17, 0x00, + 0x03, 0x17, 0x00, 0x02, 0x11, 0x13, 0x00, 0x00, + 0x00, 0xef, 0x3a, 0x07, 0x06, 0x05, 0x38, 0x17, + 0x00, 0x01, 0x13, 0x00, 0x00, 0x00, 0x68, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x17, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, 0x04, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xf0, + 0x37, 0x06, 0x03, 0x38, 0x17, 0x00, 0x01, 0x13, + 0x00, 0x00, 0x00, 0x66, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0xb8, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xba, 0x37, 0x05, 0x04, 0x13, 0x00, 0x00, + 0x00, 0xb6, 0x18, 0x00, 0x02, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, 0x05, 0x04, + 0x13, 0x00, 0x00, 0x00, 0xb5, 0x18, 0x00, 0x03, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xe6, + 0x37, 0x06, 0x03, 0x18, 0x00, 0x04, 0x17, 0x00, + 0x04, 0x39, 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, + 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x88, + 0x03, 0x33, 0x00, 0x00, 0x00, 0x08, 0x04, 0x17, + 0x00, 0x03, 0x17, 0x00, 0x02, 0x21, 0x33, 0x00, + 0x00, 0x00, 0x33, 0x13, 0x00, 0x00, 0x00, 0x72, + 0x09, 0x00, 0x00, 0x00, 0x73, 0x27, 0x0e, 0x13, + 0x00, 0x00, 0x00, 0x02, 0x35, 0x00, 0x00, 0x00, + 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, 0x00, + 0xf1, 0x27, 0x09, 0x00, 0x00, 0x00, 0xf2, 0x27, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0x86, 0x37, 0x05, + 0x04, 0x36, 0x00, 0x00, 0x00, 0x00, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xe9, 0x37, 0x05, + 0x04, 0x17, 0x00, 0x04, 0x17, 0x00, 0x02, 0x10, + 0x13, 0x00, 0x00, 0x00, 0xf3, 0x3a, 0x07, 0x06, + 0x04, 0x38, 0x0c, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x3d, 0x00, 0x06, 0x13, 0x00, 0x00, 0x00, + 0xb6, 0x18, 0x00, 0x00, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xba, 0x37, 0x06, 0x03, 0x12, + 0x00, 0x00, 0x00, 0x28, 0x1f, 0x45, 0x00, 0x00, + 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, + 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xe6, + 0x37, 0x06, 0x03, 0x18, 0x00, 0x01, 0x17, 0x00, + 0x01, 0x2d, 0x33, 0x00, 0x00, 0x00, 0x0e, 0x0e, + 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, 0x06, 0x03, + 0x12, 0x00, 0x00, 0x00, 0x29, 0x1f, 0x45, 0x00, + 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, + 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xba, 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, + 0x7b, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x0e, 0x0e, + 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x13, 0x00, + 0x00, 0x00, 0x9e, 0x3a, 0x07, 0x06, 0x02, 0x18, + 0x00, 0x02, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xba, 0x37, 0x06, 0x03, 0x18, 0x00, 0x03, + 0x17, 0x00, 0x03, 0x12, 0x00, 0x00, 0x00, 0x7d, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x05, 0x36, 0x00, + 0x00, 0x01, 0x49, 0x17, 0x00, 0x03, 0x13, 0x00, + 0x00, 0x00, 0x4a, 0x1e, 0x03, 0x46, 0x00, 0x00, + 0x00, 0x0a, 0x04, 0x17, 0x00, 0x03, 0x13, 0x00, + 0x00, 0x00, 0x54, 0x1e, 0x45, 0x00, 0x00, 0x01, + 0x1d, 0x0e, 0x13, 0x00, 0x00, 0x00, 0x9e, 0x3a, + 0x07, 0x06, 0x02, 0x18, 0x00, 0x04, 0x0a, 0x17, + 0x00, 0x04, 0x1a, 0x00, 0x00, 0x00, 0xf4, 0x17, + 0x00, 0x03, 0x13, 0x00, 0x00, 0x00, 0x4a, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x2f, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xe6, 0x37, 0x06, 0x03, + 0x17, 0x00, 0x04, 0x1a, 0x00, 0x00, 0x00, 0xf4, + 0x17, 0x00, 0x04, 0x19, 0x00, 0x00, 0x00, 0xf4, + 0x2d, 0x33, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, + 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xba, 0x37, 0x06, 0x03, 0x12, + 0x00, 0x00, 0x00, 0x3a, 0x1f, 0x45, 0x00, 0x00, + 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, + 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0xb6, 0x17, 0x00, 0x04, + 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, + 0x18, 0x00, 0x03, 0x17, 0x00, 0x03, 0x12, 0x00, + 0x00, 0x00, 0x7d, 0x1e, 0x03, 0x46, 0x00, 0x00, + 0x00, 0x0a, 0x04, 0x17, 0x00, 0x03, 0x13, 0x00, + 0x00, 0x00, 0x4a, 0x1e, 0x03, 0x46, 0x00, 0x00, + 0x00, 0x0a, 0x04, 0x17, 0x00, 0x03, 0x13, 0x00, + 0x00, 0x00, 0x54, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x05, 0x36, 0x00, 0x00, 0x00, 0x38, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xcd, 0x37, 0x06, + 0x03, 0x18, 0x00, 0x05, 0x17, 0x00, 0x05, 0x2d, + 0x33, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, + 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x05, 0x0f, 0x17, + 0x00, 0x04, 0x35, 0x00, 0x00, 0x00, 0xd1, 0x05, + 0x04, 0x36, 0xff, 0xff, 0xff, 0x87, 0x13, 0x00, + 0x00, 0x00, 0xb6, 0x17, 0x00, 0x04, 0x1a, 0x00, + 0x00, 0x00, 0xf5, 0x17, 0x00, 0x04, 0x0f, 0x17, + 0x00, 0x02, 0x35, 0x00, 0x00, 0x00, 0xd1, 0x05, + 0x04, 0x36, 0xff, 0xff, 0xfe, 0xa4, 0x0e, 0x13, + 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, + 0xff, 0xff, 0xfe, 0x96, 0x17, 0x00, 0x02, 0x17, + 0x00, 0x01, 0x13, 0x00, 0x00, 0x00, 0xb6, 0x17, + 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xe1, 0x13, + 0x00, 0x00, 0x00, 0xf6, 0x3a, 0x07, 0x06, 0x06, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, + 0x07, 0x13, 0x00, 0x00, 0x00, 0xb6, 0x18, 0x00, + 0x00, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xcd, 0x37, 0x06, 0x03, 0x18, 0x00, 0x01, 0x17, + 0x00, 0x01, 0x2d, 0x33, 0x00, 0x00, 0x00, 0x0e, + 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, + 0x00, 0x00, 0xb6, 0x18, 0x00, 0x02, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, + 0x03, 0x18, 0x00, 0x03, 0x17, 0x00, 0x03, 0x13, + 0x00, 0x00, 0x00, 0x4c, 0x1f, 0x03, 0x45, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x17, 0x00, 0x03, 0x13, + 0x00, 0x00, 0x00, 0x5e, 0x1f, 0x45, 0x00, 0x00, + 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, + 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x18, 0x00, 0x04, 0x17, 0x00, 0x03, 0x13, + 0x00, 0x00, 0x00, 0x4c, 0x1e, 0x45, 0x00, 0x00, + 0x01, 0x81, 0x0e, 0x13, 0x00, 0x00, 0x00, 0x9e, + 0x3a, 0x07, 0x06, 0x02, 0x18, 0x00, 0x04, 0x13, + 0x00, 0x00, 0x00, 0xb5, 0x17, 0x00, 0x04, 0x1a, + 0x00, 0x00, 0x00, 0xdd, 0x17, 0x00, 0x03, 0x13, + 0x00, 0x00, 0x00, 0x4c, 0x1e, 0x45, 0x00, 0x00, + 0x01, 0x47, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xba, 0x37, 0x05, 0x04, 0x0e, 0x13, 0x00, + 0x00, 0x00, 0xf7, 0x3a, 0x07, 0x06, 0x02, 0x18, + 0x00, 0x05, 0x13, 0x00, 0x00, 0x00, 0xb6, 0x17, + 0x00, 0x05, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, + 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x28, 0x1f, + 0x45, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, + 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xba, 0x37, 0x06, 0x03, 0x13, 0x00, + 0x00, 0x00, 0x6f, 0x1f, 0x45, 0x00, 0x00, 0x00, + 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, + 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x13, + 0x00, 0x00, 0x00, 0xb4, 0x17, 0x00, 0x05, 0x1a, + 0x00, 0x00, 0x00, 0xf8, 0x0c, 0x17, 0x00, 0x05, + 0x1a, 0x00, 0x00, 0x00, 0xf9, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, + 0x13, 0x00, 0x00, 0x00, 0x36, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x3a, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xba, 0x37, 0x05, 0x04, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xe6, 0x37, 0x06, + 0x03, 0x17, 0x00, 0x05, 0x1a, 0x00, 0x00, 0x00, + 0xf9, 0x17, 0x00, 0x05, 0x19, 0x00, 0x00, 0x00, + 0xf9, 0x2d, 0x33, 0x00, 0x00, 0x00, 0x0e, 0x0e, + 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, 0x06, 0x03, + 0x12, 0x00, 0x00, 0x00, 0x29, 0x1f, 0x45, 0x00, + 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, + 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xcd, 0x37, 0x06, 0x03, 0x17, 0x00, 0x05, 0x1a, + 0x00, 0x00, 0x00, 0xfa, 0x17, 0x00, 0x05, 0x19, + 0x00, 0x00, 0x00, 0xfa, 0x2d, 0x33, 0x00, 0x00, + 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, + 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x05, 0x0f, 0x17, 0x00, 0x04, 0x35, + 0x00, 0x00, 0x00, 0xd1, 0x05, 0x04, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, + 0x03, 0x18, 0x00, 0x03, 0x36, 0xff, 0xff, 0xfe, + 0xab, 0x13, 0x00, 0x00, 0x00, 0xb6, 0x17, 0x00, + 0x04, 0x1a, 0x00, 0x00, 0x00, 0xf5, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x18, 0x00, 0x05, 0x17, + 0x00, 0x03, 0x13, 0x00, 0x00, 0x00, 0x5e, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x30, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, 0x04, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xcd, + 0x37, 0x06, 0x03, 0x18, 0x00, 0x05, 0x17, 0x00, + 0x05, 0x2d, 0x33, 0x00, 0x00, 0x00, 0x0e, 0x0e, + 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x05, + 0x17, 0x00, 0x04, 0x17, 0x00, 0x01, 0x13, 0x00, + 0x00, 0x00, 0xb6, 0x17, 0x00, 0x02, 0x17, 0x00, + 0x00, 0x09, 0x00, 0x00, 0x00, 0xfb, 0x13, 0x00, + 0x00, 0x00, 0xfc, 0x3a, 0x07, 0x06, 0x08, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x05, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa8, + 0x37, 0x06, 0x03, 0x13, 0x00, 0x00, 0x00, 0x42, + 0x1f, 0x45, 0x00, 0x00, 0x00, 0x02, 0x0c, 0x38, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, + 0x37, 0x05, 0x04, 0x13, 0x00, 0x00, 0x00, 0xb6, + 0x18, 0x00, 0x04, 0x0e, 0x13, 0x00, 0x00, 0x00, + 0x9e, 0x3a, 0x07, 0x06, 0x02, 0x18, 0x00, 0x00, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa8, + 0x37, 0x06, 0x03, 0x13, 0x00, 0x00, 0x00, 0x6f, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0xd6, 0x0e, 0x13, + 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, 0x03, 0x13, + 0x00, 0x00, 0x00, 0xb4, 0x18, 0x00, 0x01, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, + 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x3d, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x36, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, 0x04, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xfd, + 0x37, 0x06, 0x03, 0x18, 0x00, 0x02, 0x17, 0x00, + 0x02, 0x39, 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x12, 0x0e, 0x13, 0x00, + 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x04, 0x0a, 0x18, 0x00, 0x02, 0x17, + 0x00, 0x02, 0x17, 0x00, 0x01, 0x10, 0x13, 0x00, + 0x00, 0x00, 0xfe, 0x3a, 0x07, 0x06, 0x04, 0x0f, + 0x17, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0xd1, + 0x05, 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xa8, 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, + 0x00, 0x2c, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x2f, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, + 0x37, 0x05, 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, 0x13, 0x00, + 0x00, 0x00, 0x6f, 0x1f, 0x45, 0x00, 0x00, 0x00, + 0x1e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, + 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x10, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xe9, 0x37, + 0x05, 0x04, 0x36, 0x00, 0x00, 0x00, 0x10, 0x36, + 0xff, 0xff, 0xff, 0x14, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xe9, 0x37, 0x05, 0x04, 0x17, + 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0xd2, 0x0e, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, + 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x17, + 0x00, 0x04, 0x10, 0x13, 0x00, 0x00, 0x00, 0xff, + 0x3a, 0x07, 0x06, 0x04, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x03, 0x3d, 0x00, 0x04, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, + 0x13, 0x00, 0x00, 0x00, 0x36, 0x1f, 0x45, 0x00, + 0x00, 0x00, 0x02, 0x0c, 0x38, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, 0x04, + 0x13, 0x00, 0x00, 0x00, 0xb6, 0x18, 0x00, 0x03, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, + 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x28, + 0x1f, 0x45, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, + 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xe6, 0x37, 0x06, 0x03, 0x18, + 0x00, 0x00, 0x17, 0x00, 0x00, 0x39, 0x09, 0x00, + 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, + 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, + 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x29, 0x1f, + 0x45, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, + 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xcd, 0x37, 0x06, 0x03, 0x18, 0x00, + 0x01, 0x17, 0x00, 0x01, 0x39, 0x09, 0x00, 0x00, + 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x0e, + 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, + 0x03, 0x13, 0x00, 0x00, 0x00, 0x30, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x36, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, 0x04, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xcd, 0x37, + 0x06, 0x03, 0x18, 0x00, 0x02, 0x17, 0x00, 0x02, + 0x39, 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x12, 0x0e, 0x13, 0x00, 0x00, + 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, + 0x00, 0x04, 0x0a, 0x18, 0x00, 0x02, 0x17, 0x00, + 0x02, 0x17, 0x00, 0x01, 0x17, 0x00, 0x00, 0x17, + 0x00, 0x03, 0x09, 0x00, 0x00, 0x00, 0xe1, 0x13, + 0x00, 0x00, 0x01, 0x00, 0x3a, 0x07, 0x06, 0x06, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, + 0x0a, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xa8, 0x37, 0x06, 0x03, 0x18, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x56, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0xf4, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, 0x04, + 0x13, 0x00, 0x00, 0x00, 0xb6, 0x18, 0x00, 0x05, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xcd, + 0x37, 0x06, 0x03, 0x18, 0x00, 0x04, 0x17, 0x00, + 0x04, 0x39, 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, + 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xba, 0x37, 0x06, 0x03, 0x13, 0x00, + 0x00, 0x00, 0x46, 0x1f, 0x45, 0x00, 0x00, 0x00, + 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, + 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, + 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x28, 0x1f, + 0x45, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, + 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xe6, 0x37, 0x06, 0x03, 0x18, 0x00, + 0x01, 0x17, 0x00, 0x01, 0x39, 0x09, 0x00, 0x00, + 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x0e, + 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, 0x06, + 0x03, 0x12, 0x00, 0x00, 0x00, 0x29, 0x1f, 0x45, + 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, + 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xe9, 0x37, 0x05, 0x04, 0x17, 0x00, 0x04, + 0x17, 0x00, 0x01, 0x17, 0x00, 0x05, 0x11, 0x13, + 0x00, 0x00, 0x01, 0x01, 0x3a, 0x07, 0x06, 0x05, + 0x38, 0x17, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x46, 0x1e, 0x45, 0x00, 0x00, 0x00, 0xc5, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, + 0x05, 0x04, 0x13, 0x00, 0x00, 0x00, 0xb6, 0x18, + 0x00, 0x05, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xba, 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, + 0x00, 0x28, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x0e, + 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xe6, 0x37, 0x06, + 0x03, 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, 0x39, + 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, + 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xba, 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, + 0x29, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x0e, 0x0e, + 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xcd, 0x37, 0x06, 0x03, + 0x18, 0x00, 0x04, 0x17, 0x00, 0x04, 0x39, 0x09, + 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, + 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x04, 0x17, 0x00, 0x01, 0x17, 0x00, + 0x05, 0x11, 0x13, 0x00, 0x00, 0x01, 0x02, 0x3a, + 0x07, 0x06, 0x05, 0x38, 0x17, 0x00, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x32, 0x1e, 0x45, 0x00, 0x00, + 0x03, 0x9c, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xba, 0x37, 0x05, 0x04, 0x13, 0x00, 0x00, + 0x00, 0xb6, 0x18, 0x00, 0x05, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, 0x06, 0x03, + 0x12, 0x00, 0x00, 0x00, 0x28, 0x1f, 0x45, 0x00, + 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, + 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x0a, 0x18, 0x00, 0x06, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, + 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, 0x13, 0x00, + 0x00, 0x00, 0x42, 0x1e, 0x45, 0x00, 0x00, 0x01, + 0x13, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xba, 0x37, 0x05, 0x04, 0x0e, 0x13, 0x00, 0x00, + 0x00, 0x9e, 0x3a, 0x07, 0x06, 0x02, 0x18, 0x00, + 0x06, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xa8, 0x37, 0x06, 0x03, 0x18, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x6f, 0x1f, + 0x45, 0x00, 0x00, 0x00, 0x05, 0x36, 0x00, 0x00, + 0x00, 0xbd, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xba, 0x37, 0x05, 0x04, 0x13, 0x00, 0x00, + 0x00, 0xb4, 0x18, 0x00, 0x07, 0x0a, 0x18, 0x00, + 0x08, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xa8, 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, + 0x3d, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x30, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, + 0x05, 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xfd, 0x37, 0x06, 0x03, 0x18, 0x00, 0x08, + 0x17, 0x00, 0x08, 0x2d, 0x33, 0x00, 0x00, 0x00, + 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, + 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x08, 0x17, 0x00, 0x07, 0x10, 0x13, 0x00, + 0x00, 0x00, 0xfe, 0x3a, 0x07, 0x06, 0x04, 0x0f, + 0x17, 0x00, 0x06, 0x35, 0x00, 0x00, 0x00, 0xd1, + 0x05, 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xa8, 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, + 0x00, 0x2c, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x2f, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, + 0x37, 0x05, 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, 0x13, 0x00, + 0x00, 0x00, 0x6f, 0x1f, 0x45, 0x00, 0x00, 0x00, + 0x09, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, + 0x05, 0x03, 0x36, 0xff, 0xff, 0xff, 0x22, 0x17, + 0x00, 0x06, 0x19, 0x00, 0x00, 0x00, 0xd2, 0x0e, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x4b, 0x0e, 0x13, + 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x3d, 0x17, 0x00, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x3b, 0x1f, 0x45, 0x00, 0x00, + 0x00, 0x2b, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xe6, 0x37, 0x06, 0x03, 0x18, 0x00, 0x01, + 0x17, 0x00, 0x01, 0x39, 0x09, 0x00, 0x00, 0x00, + 0xd5, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x12, 0x0e, + 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, + 0x36, 0x00, 0x00, 0x00, 0x04, 0x0a, 0x18, 0x00, + 0x01, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xba, 0x37, 0x06, 0x03, 0x18, 0x00, 0x00, 0x0c, + 0x18, 0x00, 0x07, 0x17, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x3b, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0xb3, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xa8, 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, + 0x3b, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x2b, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xe6, 0x37, + 0x06, 0x03, 0x18, 0x00, 0x02, 0x17, 0x00, 0x02, + 0x39, 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x12, 0x0e, 0x13, 0x00, 0x00, + 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, + 0x00, 0x04, 0x0a, 0x18, 0x00, 0x02, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, 0x06, + 0x03, 0x12, 0x00, 0x00, 0x00, 0x3b, 0x1f, 0x45, + 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, + 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xa8, 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, + 0x00, 0x29, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x2b, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xe6, + 0x37, 0x06, 0x03, 0x18, 0x00, 0x03, 0x17, 0x00, + 0x03, 0x39, 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x12, 0x0e, 0x13, 0x00, + 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x04, 0x0a, 0x18, 0x00, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x8c, 0x17, 0x00, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x38, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x75, 0x0b, 0x18, 0x00, 0x07, 0x17, 0x00, + 0x01, 0x33, 0x00, 0x00, 0x00, 0x21, 0x17, 0x00, + 0x01, 0x19, 0x00, 0x00, 0x00, 0xbd, 0x13, 0x00, + 0x00, 0x00, 0xc3, 0x1f, 0x45, 0x00, 0x00, 0x00, + 0x2b, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, + 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x1d, 0x17, + 0x00, 0x06, 0x19, 0x00, 0x00, 0x00, 0xd2, 0x0f, + 0x1f, 0x45, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, + 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xe6, 0x37, 0x06, 0x03, 0x18, + 0x00, 0x02, 0x17, 0x00, 0x02, 0x39, 0x09, 0x00, + 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x17, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, + 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x09, 0x0e, + 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, + 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x29, + 0x1f, 0x45, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, + 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xcd, 0x37, 0x06, 0x03, 0x18, + 0x00, 0x04, 0x17, 0x00, 0x04, 0x39, 0x09, 0x00, + 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, + 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x07, 0x33, 0x00, 0x00, 0x00, 0x1e, 0x17, + 0x00, 0x04, 0x17, 0x00, 0x02, 0x17, 0x00, 0x01, + 0x17, 0x00, 0x06, 0x17, 0x00, 0x05, 0x09, 0x00, + 0x00, 0x01, 0x03, 0x13, 0x00, 0x00, 0x01, 0x04, + 0x3a, 0x07, 0x06, 0x07, 0x38, 0x17, 0x00, 0x04, + 0x17, 0x00, 0x03, 0x17, 0x00, 0x02, 0x17, 0x00, + 0x01, 0x17, 0x00, 0x06, 0x17, 0x00, 0x05, 0x09, + 0x00, 0x00, 0x00, 0xfb, 0x13, 0x00, 0x00, 0x01, + 0x05, 0x3a, 0x07, 0x06, 0x08, 0x38, 0x0c, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x03, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xfd, + 0x37, 0x06, 0x03, 0x03, 0x18, 0x00, 0x00, 0x39, + 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x02, 0x0c, 0x38, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, + 0x12, 0x00, 0x00, 0x00, 0x2c, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x57, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xba, 0x37, 0x05, 0x04, 0x13, 0x00, + 0x00, 0x00, 0xb6, 0x18, 0x00, 0x02, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xfd, 0x37, 0x06, + 0x03, 0x03, 0x18, 0x00, 0x01, 0x39, 0x09, 0x00, + 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, + 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x01, 0x17, 0x00, 0x00, 0x17, 0x00, 0x02, + 0x11, 0x13, 0x00, 0x00, 0x01, 0x06, 0x3a, 0x07, + 0x06, 0x05, 0x18, 0x00, 0x00, 0x36, 0xff, 0xff, + 0xff, 0x93, 0x17, 0x00, 0x00, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x04, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x01, 0x07, 0x37, 0x06, + 0x03, 0x03, 0x18, 0x00, 0x00, 0x39, 0x09, 0x00, + 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x02, 0x0c, 0x38, 0x17, 0x00, 0x00, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0x08, 0x37, 0x06, 0x03, 0x33, + 0x00, 0x00, 0x01, 0x2c, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, 0x18, + 0x00, 0x02, 0x17, 0x00, 0x02, 0x12, 0x00, 0x00, + 0x00, 0x3d, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0a, 0x04, 0x17, 0x00, 0x02, 0x13, 0x00, 0x00, + 0x00, 0x13, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0a, 0x04, 0x17, 0x00, 0x02, 0x13, 0x00, 0x00, + 0x00, 0x14, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0a, 0x04, 0x17, 0x00, 0x02, 0x13, 0x00, 0x00, + 0x00, 0x15, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0a, 0x04, 0x17, 0x00, 0x02, 0x13, 0x00, 0x00, + 0x00, 0x16, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0a, 0x04, 0x17, 0x00, 0x02, 0x13, 0x00, 0x00, + 0x00, 0x17, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0a, 0x04, 0x17, 0x00, 0x02, 0x13, 0x00, 0x00, + 0x00, 0x1b, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0a, 0x04, 0x17, 0x00, 0x02, 0x13, 0x00, 0x00, + 0x00, 0x1d, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0a, 0x04, 0x17, 0x00, 0x02, 0x13, 0x00, 0x00, + 0x00, 0x1e, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0a, 0x04, 0x17, 0x00, 0x02, 0x13, 0x00, 0x00, + 0x00, 0x18, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0a, 0x04, 0x17, 0x00, 0x02, 0x13, 0x00, 0x00, + 0x00, 0x19, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0a, 0x04, 0x17, 0x00, 0x02, 0x13, 0x00, 0x00, + 0x00, 0x1a, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x60, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, + 0x37, 0x05, 0x04, 0x13, 0x00, 0x00, 0x00, 0xb6, + 0x18, 0x00, 0x03, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xfd, 0x37, 0x06, 0x03, 0x18, 0x00, + 0x01, 0x17, 0x00, 0x01, 0x39, 0x09, 0x00, 0x00, + 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x0e, + 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, + 0x01, 0x17, 0x00, 0x00, 0x17, 0x00, 0x02, 0x17, + 0x00, 0x03, 0x09, 0x00, 0x00, 0x00, 0xe1, 0x13, + 0x00, 0x00, 0x01, 0x09, 0x3a, 0x07, 0x06, 0x06, + 0x18, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x01, 0x0a, 0x03, 0x33, 0x00, + 0x00, 0x00, 0x09, 0x04, 0x17, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x01, 0x0b, 0x33, 0x00, 0x00, 0x00, + 0x0c, 0x0e, 0x17, 0x00, 0x00, 0x35, 0x00, 0x00, + 0x01, 0x0b, 0x06, 0x02, 0x38, 0x17, 0x00, 0x00, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, + 0x05, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x01, + 0x0c, 0x37, 0x06, 0x03, 0x03, 0x18, 0x00, 0x00, + 0x39, 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x02, 0x0c, 0x38, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, + 0x03, 0x12, 0x00, 0x00, 0x00, 0x3f, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0xaf, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, 0x04, 0x13, + 0x00, 0x00, 0x00, 0xb6, 0x18, 0x00, 0x04, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xfd, 0x37, + 0x06, 0x03, 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, + 0x39, 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, + 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xba, 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, + 0x00, 0x3a, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x0e, + 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xfd, 0x37, 0x06, + 0x03, 0x18, 0x00, 0x02, 0x17, 0x00, 0x02, 0x39, + 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, + 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x17, 0x00, 0x02, 0x17, 0x00, 0x01, 0x17, + 0x00, 0x00, 0x17, 0x00, 0x04, 0x09, 0x00, 0x00, + 0x00, 0xe1, 0x13, 0x00, 0x00, 0x01, 0x0d, 0x3a, + 0x07, 0x06, 0x06, 0x18, 0x00, 0x00, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x03, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x0e, 0x37, + 0x06, 0x03, 0x03, 0x18, 0x00, 0x00, 0x39, 0x09, + 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x02, 0x0c, 0x38, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, 0x13, + 0x00, 0x00, 0x00, 0x10, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x59, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xba, 0x37, 0x05, 0x04, 0x13, 0x00, 0x00, + 0x00, 0xb6, 0x18, 0x00, 0x02, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0x0e, 0x37, 0x06, 0x03, + 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, 0x39, 0x09, + 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, + 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x01, 0x17, 0x00, 0x00, 0x17, 0x00, + 0x02, 0x11, 0x13, 0x00, 0x00, 0x01, 0x0f, 0x3a, + 0x07, 0x06, 0x05, 0x18, 0x00, 0x00, 0x36, 0xff, + 0xff, 0xff, 0x91, 0x17, 0x00, 0x00, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x03, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x10, 0x37, + 0x06, 0x03, 0x03, 0x18, 0x00, 0x00, 0x39, 0x09, + 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x02, 0x0c, 0x38, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, 0x13, + 0x00, 0x00, 0x00, 0x0f, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x59, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xba, 0x37, 0x05, 0x04, 0x13, 0x00, 0x00, + 0x00, 0xb6, 0x18, 0x00, 0x02, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0x10, 0x37, 0x06, 0x03, + 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, 0x39, 0x09, + 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, + 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x01, 0x17, 0x00, 0x00, 0x17, 0x00, + 0x02, 0x11, 0x13, 0x00, 0x00, 0x01, 0x11, 0x3a, + 0x07, 0x06, 0x05, 0x18, 0x00, 0x00, 0x36, 0xff, + 0xff, 0xff, 0x91, 0x17, 0x00, 0x00, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x03, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x12, 0x37, + 0x06, 0x03, 0x03, 0x18, 0x00, 0x00, 0x39, 0x09, + 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x02, 0x0c, 0x38, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, 0x12, + 0x00, 0x00, 0x00, 0x7c, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x59, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xba, 0x37, 0x05, 0x04, 0x13, 0x00, 0x00, + 0x00, 0xb6, 0x18, 0x00, 0x02, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0x12, 0x37, 0x06, 0x03, + 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, 0x39, 0x09, + 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, + 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x01, 0x17, 0x00, 0x00, 0x17, 0x00, + 0x02, 0x11, 0x13, 0x00, 0x00, 0x01, 0x13, 0x3a, + 0x07, 0x06, 0x05, 0x18, 0x00, 0x00, 0x36, 0xff, + 0xff, 0xff, 0x91, 0x17, 0x00, 0x00, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x03, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x14, 0x37, + 0x06, 0x03, 0x03, 0x18, 0x00, 0x00, 0x39, 0x09, + 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x02, 0x0c, 0x38, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, 0x12, + 0x00, 0x00, 0x00, 0x5e, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x59, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xba, 0x37, 0x05, 0x04, 0x13, 0x00, 0x00, + 0x00, 0xb6, 0x18, 0x00, 0x02, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0x14, 0x37, 0x06, 0x03, + 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, 0x39, 0x09, + 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, + 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x01, 0x17, 0x00, 0x00, 0x17, 0x00, + 0x02, 0x11, 0x13, 0x00, 0x00, 0x01, 0x15, 0x3a, + 0x07, 0x06, 0x05, 0x18, 0x00, 0x00, 0x36, 0xff, + 0xff, 0xff, 0x91, 0x17, 0x00, 0x00, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x03, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x16, 0x37, + 0x06, 0x03, 0x03, 0x18, 0x00, 0x00, 0x39, 0x09, + 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x02, 0x0c, 0x38, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, 0x12, + 0x00, 0x00, 0x00, 0x26, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x59, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xba, 0x37, 0x05, 0x04, 0x13, 0x00, 0x00, + 0x00, 0xb6, 0x18, 0x00, 0x02, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0x16, 0x37, 0x06, 0x03, + 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, 0x39, 0x09, + 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, + 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x01, 0x17, 0x00, 0x00, 0x17, 0x00, + 0x02, 0x11, 0x13, 0x00, 0x00, 0x01, 0x17, 0x3a, + 0x07, 0x06, 0x05, 0x18, 0x00, 0x00, 0x36, 0xff, + 0xff, 0xff, 0x91, 0x17, 0x00, 0x00, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x04, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x18, 0x37, + 0x06, 0x03, 0x03, 0x18, 0x00, 0x00, 0x39, 0x09, + 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x02, 0x0c, 0x38, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, 0x18, + 0x00, 0x02, 0x17, 0x00, 0x02, 0x13, 0x00, 0x00, + 0x00, 0x0a, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0a, 0x04, 0x17, 0x00, 0x02, 0x13, 0x00, 0x00, + 0x00, 0x0c, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0a, 0x04, 0x17, 0x00, 0x02, 0x13, 0x00, 0x00, + 0x00, 0x09, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0a, 0x04, 0x17, 0x00, 0x02, 0x13, 0x00, 0x00, + 0x00, 0x0b, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x6e, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, + 0x37, 0x05, 0x04, 0x13, 0x00, 0x00, 0x00, 0xb6, + 0x18, 0x00, 0x03, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0x18, 0x37, 0x06, 0x03, 0x18, 0x00, + 0x01, 0x17, 0x00, 0x01, 0x39, 0x09, 0x00, 0x00, + 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x0e, + 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, + 0x01, 0x17, 0x00, 0x00, 0x17, 0x00, 0x02, 0x17, + 0x00, 0x03, 0x09, 0x00, 0x00, 0x00, 0xe1, 0x13, + 0x00, 0x00, 0x01, 0x19, 0x3a, 0x07, 0x06, 0x06, + 0x18, 0x00, 0x00, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, 0x18, 0x00, + 0x02, 0x36, 0xff, 0xff, 0xff, 0x54, 0x17, 0x00, + 0x00, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x3d, + 0x00, 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x01, 0x1a, 0x37, 0x06, 0x03, 0x03, 0x18, 0x00, + 0x00, 0x39, 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x02, 0x0c, 0x38, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, + 0x06, 0x03, 0x18, 0x00, 0x02, 0x17, 0x00, 0x02, + 0x12, 0x00, 0x00, 0x00, 0x3c, 0x1e, 0x03, 0x46, + 0x00, 0x00, 0x00, 0x0a, 0x04, 0x17, 0x00, 0x02, + 0x12, 0x00, 0x00, 0x00, 0x3e, 0x1e, 0x03, 0x46, + 0x00, 0x00, 0x00, 0x0a, 0x04, 0x17, 0x00, 0x02, + 0x13, 0x00, 0x00, 0x00, 0x0d, 0x1e, 0x03, 0x46, + 0x00, 0x00, 0x00, 0x0a, 0x04, 0x17, 0x00, 0x02, + 0x13, 0x00, 0x00, 0x00, 0x0e, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x6e, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xba, 0x37, 0x05, 0x04, 0x13, 0x00, + 0x00, 0x00, 0xb6, 0x18, 0x00, 0x03, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x01, 0x1a, 0x37, 0x06, + 0x03, 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, 0x39, + 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, + 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x17, 0x00, 0x01, 0x17, 0x00, 0x00, 0x17, + 0x00, 0x02, 0x17, 0x00, 0x03, 0x09, 0x00, 0x00, + 0x00, 0xe1, 0x13, 0x00, 0x00, 0x01, 0x1b, 0x3a, + 0x07, 0x06, 0x06, 0x18, 0x00, 0x00, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, + 0x03, 0x18, 0x00, 0x02, 0x36, 0xff, 0xff, 0xff, + 0x54, 0x17, 0x00, 0x00, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x03, 0x3d, 0x00, 0x04, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0x1c, 0x37, 0x06, 0x03, + 0x03, 0x18, 0x00, 0x00, 0x39, 0x09, 0x00, 0x00, + 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x02, + 0x0c, 0x38, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xa8, 0x37, 0x06, 0x03, 0x18, 0x00, 0x02, + 0x17, 0x00, 0x02, 0x13, 0x00, 0x00, 0x00, 0x1c, + 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x17, 0x00, 0x02, 0x13, 0x00, 0x00, 0x00, 0x20, + 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x17, 0x00, 0x02, 0x13, 0x00, 0x00, 0x00, 0x1f, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x6e, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, + 0x04, 0x13, 0x00, 0x00, 0x00, 0xb6, 0x18, 0x00, + 0x03, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x01, + 0x1c, 0x37, 0x06, 0x03, 0x18, 0x00, 0x01, 0x17, + 0x00, 0x01, 0x39, 0x09, 0x00, 0x00, 0x00, 0xd5, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, + 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x01, 0x17, + 0x00, 0x00, 0x17, 0x00, 0x02, 0x17, 0x00, 0x03, + 0x09, 0x00, 0x00, 0x00, 0xe1, 0x13, 0x00, 0x00, + 0x01, 0x1d, 0x3a, 0x07, 0x06, 0x06, 0x18, 0x00, + 0x00, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xa8, 0x37, 0x06, 0x03, 0x18, 0x00, 0x02, 0x36, + 0xff, 0xff, 0xff, 0x64, 0x17, 0x00, 0x00, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x04, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x1e, + 0x37, 0x06, 0x03, 0x03, 0x18, 0x00, 0x00, 0x39, + 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x02, 0x0c, 0x38, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, + 0x18, 0x00, 0x02, 0x17, 0x00, 0x02, 0x12, 0x00, + 0x00, 0x00, 0x2b, 0x1e, 0x03, 0x46, 0x00, 0x00, + 0x00, 0x0a, 0x04, 0x17, 0x00, 0x02, 0x12, 0x00, + 0x00, 0x00, 0x2d, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x6e, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xba, 0x37, 0x05, 0x04, 0x13, 0x00, 0x00, 0x00, + 0xb6, 0x18, 0x00, 0x03, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0x1e, 0x37, 0x06, 0x03, 0x18, + 0x00, 0x01, 0x17, 0x00, 0x01, 0x39, 0x09, 0x00, + 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, + 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x01, 0x17, 0x00, 0x00, 0x17, 0x00, 0x02, + 0x17, 0x00, 0x03, 0x09, 0x00, 0x00, 0x00, 0xe1, + 0x13, 0x00, 0x00, 0x01, 0x1f, 0x3a, 0x07, 0x06, + 0x06, 0x18, 0x00, 0x00, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, 0x18, + 0x00, 0x02, 0x36, 0xff, 0xff, 0xff, 0x74, 0x17, + 0x00, 0x00, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, + 0x3d, 0x00, 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0x20, 0x37, 0x06, 0x03, 0x03, 0x18, + 0x00, 0x00, 0x39, 0x09, 0x00, 0x00, 0x00, 0xd5, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x02, 0x0c, 0x38, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa8, + 0x37, 0x06, 0x03, 0x18, 0x00, 0x02, 0x17, 0x00, + 0x02, 0x12, 0x00, 0x00, 0x00, 0x2a, 0x1e, 0x03, + 0x46, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x17, 0x00, + 0x02, 0x12, 0x00, 0x00, 0x00, 0x2f, 0x1e, 0x03, + 0x46, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x17, 0x00, + 0x02, 0x12, 0x00, 0x00, 0x00, 0x25, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x6e, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, 0x04, 0x13, + 0x00, 0x00, 0x00, 0xb6, 0x18, 0x00, 0x03, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x20, 0x37, + 0x06, 0x03, 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, + 0x39, 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, + 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x17, 0x00, 0x01, 0x17, 0x00, 0x00, + 0x17, 0x00, 0x02, 0x17, 0x00, 0x03, 0x09, 0x00, + 0x00, 0x00, 0xe1, 0x13, 0x00, 0x00, 0x01, 0x21, + 0x3a, 0x07, 0x06, 0x06, 0x18, 0x00, 0x00, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, + 0x06, 0x03, 0x18, 0x00, 0x02, 0x36, 0xff, 0xff, + 0xff, 0x64, 0x17, 0x00, 0x00, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x03, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, + 0x03, 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, 0x13, + 0x00, 0x00, 0x00, 0x2e, 0x1e, 0x03, 0x46, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x17, 0x00, 0x01, 0x13, + 0x00, 0x00, 0x00, 0x44, 0x1e, 0x03, 0x46, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x17, 0x00, 0x01, 0x13, + 0x00, 0x00, 0x00, 0x40, 0x1e, 0x03, 0x46, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x17, 0x00, 0x01, 0x13, + 0x00, 0x00, 0x00, 0x11, 0x1e, 0x03, 0x46, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x17, 0x00, 0x01, 0x13, + 0x00, 0x00, 0x00, 0x12, 0x1e, 0x03, 0x46, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x17, 0x00, 0x01, 0x12, + 0x00, 0x00, 0x00, 0x2b, 0x1e, 0x03, 0x46, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x17, 0x00, 0x01, 0x12, + 0x00, 0x00, 0x00, 0x2d, 0x1e, 0x03, 0x46, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x17, 0x00, 0x01, 0x12, + 0x00, 0x00, 0x00, 0x7e, 0x1e, 0x03, 0x46, 0x00, + 0x00, 0x00, 0x0a, 0x04, 0x17, 0x00, 0x01, 0x12, + 0x00, 0x00, 0x00, 0x21, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x52, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xba, 0x37, 0x05, 0x04, 0x13, 0x00, 0x00, + 0x00, 0xb6, 0x18, 0x00, 0x02, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0x20, 0x37, 0x06, 0x03, + 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, 0x39, 0x09, + 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, + 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x17, 0x00, 0x01, 0x17, 0x00, + 0x02, 0x11, 0x13, 0x00, 0x00, 0x01, 0x22, 0x3a, + 0x07, 0x06, 0x05, 0x38, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0x23, 0x37, 0x06, 0x03, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x03, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x24, + 0x37, 0x06, 0x03, 0x03, 0x18, 0x00, 0x00, 0x39, + 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x02, 0x0c, 0x38, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, + 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, 0x13, 0x00, + 0x00, 0x00, 0x11, 0x1e, 0x03, 0x46, 0x00, 0x00, + 0x00, 0x0a, 0x04, 0x17, 0x00, 0x01, 0x13, 0x00, + 0x00, 0x00, 0x12, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x73, 0x13, 0x00, 0x00, 0x00, 0xb5, 0x13, 0x00, + 0x00, 0x00, 0xb6, 0x21, 0x45, 0x00, 0x00, 0x00, + 0x37, 0x13, 0x00, 0x00, 0x00, 0xbb, 0x33, 0x00, + 0x00, 0x00, 0x54, 0x13, 0x00, 0x00, 0x00, 0x72, + 0x09, 0x00, 0x00, 0x00, 0x73, 0x27, 0x0e, 0x13, + 0x00, 0x00, 0x00, 0xb6, 0x35, 0x00, 0x00, 0x00, + 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, 0x01, + 0x25, 0x27, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x86, + 0x37, 0x05, 0x04, 0x36, 0x00, 0x00, 0x00, 0x27, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, + 0x37, 0x05, 0x04, 0x13, 0x00, 0x00, 0x00, 0xb6, + 0x18, 0x00, 0x02, 0x17, 0x00, 0x00, 0x17, 0x00, + 0x01, 0x17, 0x00, 0x02, 0x11, 0x13, 0x00, 0x00, + 0x01, 0x26, 0x3a, 0x07, 0x06, 0x05, 0x38, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x05, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x27, + 0x37, 0x06, 0x03, 0x03, 0x18, 0x00, 0x00, 0x39, + 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x02, 0x0c, 0x38, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, + 0x12, 0x00, 0x00, 0x00, 0x28, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x4e, 0x13, 0x00, 0x00, 0x00, 0xb5, + 0x18, 0x00, 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0x28, 0x37, 0x06, 0x03, 0x18, 0x00, + 0x01, 0x17, 0x00, 0x01, 0x39, 0x09, 0x00, 0x00, + 0x00, 0xd5, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x0e, + 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, + 0x01, 0x17, 0x00, 0x00, 0x17, 0x00, 0x04, 0x11, + 0x13, 0x00, 0x00, 0x01, 0x29, 0x3a, 0x07, 0x06, + 0x05, 0x18, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, + 0x04, 0x17, 0x00, 0x00, 0x38, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, + 0x03, 0x18, 0x00, 0x02, 0x12, 0x00, 0x00, 0x00, + 0x28, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, 0x0a, + 0x04, 0x17, 0x00, 0x02, 0x12, 0x00, 0x00, 0x00, + 0x5b, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, 0x0a, + 0x04, 0x17, 0x00, 0x02, 0x12, 0x00, 0x00, 0x00, + 0x2e, 0x1e, 0x45, 0x00, 0x00, 0x01, 0x08, 0x13, + 0x00, 0x00, 0x00, 0xb5, 0x18, 0x00, 0x04, 0x17, + 0x00, 0x02, 0x12, 0x00, 0x00, 0x00, 0x28, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x23, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0x28, 0x37, 0x06, 0x03, + 0x17, 0x00, 0x00, 0x17, 0x00, 0x04, 0x11, 0x13, + 0x00, 0x00, 0x01, 0x29, 0x3a, 0x07, 0x06, 0x05, + 0x18, 0x00, 0x00, 0x36, 0xff, 0xff, 0xff, 0x8d, + 0x17, 0x00, 0x02, 0x12, 0x00, 0x00, 0x00, 0x5b, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x75, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, + 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xe6, 0x37, 0x06, 0x03, 0x18, 0x00, 0x03, 0x17, + 0x00, 0x03, 0x39, 0x09, 0x00, 0x00, 0x00, 0xd5, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, + 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xba, 0x37, 0x06, 0x03, 0x12, + 0x00, 0x00, 0x00, 0x5d, 0x1f, 0x45, 0x00, 0x00, + 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, + 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x03, 0x17, 0x00, 0x00, 0x17, 0x00, + 0x04, 0x11, 0x13, 0x00, 0x00, 0x01, 0x2a, 0x3a, + 0x07, 0x06, 0x05, 0x18, 0x00, 0x00, 0x36, 0xff, + 0xff, 0xff, 0x0a, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xba, 0x37, 0x05, 0x04, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, 0x06, + 0x03, 0x13, 0x00, 0x00, 0x00, 0x6f, 0x1f, 0x45, + 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, + 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xb4, 0x17, + 0x00, 0x00, 0x17, 0x00, 0x04, 0x11, 0x13, 0x00, + 0x00, 0x01, 0x2b, 0x3a, 0x07, 0x06, 0x05, 0x18, + 0x00, 0x00, 0x36, 0xff, 0xff, 0xfe, 0xbe, 0x17, + 0x00, 0x00, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, + 0x3d, 0x00, 0x05, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0x2c, 0x37, 0x06, 0x03, 0x03, 0x18, + 0x00, 0x00, 0x39, 0x09, 0x00, 0x00, 0x00, 0xd5, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0xc4, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, + 0x03, 0x13, 0x00, 0x00, 0x00, 0x3a, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0xac, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, 0x04, 0x13, + 0x00, 0x00, 0x00, 0xb6, 0x18, 0x00, 0x04, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x27, 0x37, + 0x06, 0x03, 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, + 0x39, 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, + 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xa8, 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, + 0x00, 0x28, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x2b, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x28, + 0x37, 0x06, 0x03, 0x18, 0x00, 0x01, 0x17, 0x00, + 0x01, 0x39, 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x20, 0x0e, 0x13, 0x00, + 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x12, 0x0a, 0x17, 0x00, 0x00, 0x17, + 0x00, 0x04, 0x11, 0x13, 0x00, 0x00, 0x01, 0x2d, + 0x3a, 0x07, 0x06, 0x05, 0x38, 0x17, 0x00, 0x01, + 0x17, 0x00, 0x00, 0x17, 0x00, 0x04, 0x11, 0x13, + 0x00, 0x00, 0x01, 0x2d, 0x3a, 0x07, 0x06, 0x05, + 0x18, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x02, + 0x0c, 0x38, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xa8, 0x37, 0x06, 0x03, 0x18, 0x00, 0x02, + 0x17, 0x00, 0x02, 0x12, 0x00, 0x00, 0x00, 0x5b, + 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, 0x0a, 0x04, + 0x17, 0x00, 0x02, 0x12, 0x00, 0x00, 0x00, 0x2e, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0xda, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, + 0x04, 0x13, 0x00, 0x00, 0x00, 0xb6, 0x18, 0x00, + 0x04, 0x17, 0x00, 0x02, 0x12, 0x00, 0x00, 0x00, + 0x5b, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x6a, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xe6, 0x37, + 0x06, 0x03, 0x18, 0x00, 0x03, 0x17, 0x00, 0x03, + 0x39, 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, + 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xba, 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, + 0x00, 0x5d, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x0e, + 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, + 0x03, 0x17, 0x00, 0x00, 0x17, 0x00, 0x04, 0x11, + 0x13, 0x00, 0x00, 0x01, 0x2a, 0x3a, 0x07, 0x06, + 0x05, 0x18, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, + 0x3c, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xba, 0x37, 0x06, 0x03, 0x13, 0x00, 0x00, 0x00, + 0x6f, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x0e, 0x0e, + 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0xb4, 0x17, 0x00, 0x00, 0x17, 0x00, 0x04, + 0x11, 0x13, 0x00, 0x00, 0x01, 0x2b, 0x3a, 0x07, + 0x06, 0x05, 0x18, 0x00, 0x00, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, + 0x18, 0x00, 0x02, 0x36, 0xff, 0xff, 0xff, 0x08, + 0x17, 0x00, 0x00, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x3d, 0x00, 0x06, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, 0x18, + 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xb5, 0x18, + 0x00, 0x02, 0x17, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x3e, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x15, + 0x17, 0x00, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x01, + 0x2e, 0x3a, 0x07, 0x06, 0x03, 0x18, 0x00, 0x01, + 0x36, 0x00, 0x00, 0x04, 0x5d, 0x17, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x6f, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x1a, 0x13, 0x00, 0x00, 0x00, 0xb3, + 0x17, 0x00, 0x02, 0x10, 0x13, 0x00, 0x00, 0x01, + 0x2f, 0x3a, 0x07, 0x06, 0x04, 0x18, 0x00, 0x01, + 0x36, 0x00, 0x00, 0x04, 0x35, 0x17, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x7d, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x1a, 0x13, 0x00, 0x00, 0x00, 0xb3, + 0x17, 0x00, 0x02, 0x10, 0x13, 0x00, 0x00, 0x01, + 0x30, 0x3a, 0x07, 0x06, 0x04, 0x18, 0x00, 0x01, + 0x36, 0x00, 0x00, 0x04, 0x0d, 0x17, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x77, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x1a, 0x13, 0x00, 0x00, 0x00, 0xb3, + 0x17, 0x00, 0x02, 0x10, 0x13, 0x00, 0x00, 0x01, + 0x31, 0x3a, 0x07, 0x06, 0x04, 0x18, 0x00, 0x01, + 0x36, 0x00, 0x00, 0x03, 0xe5, 0x17, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x08, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x1a, 0x13, 0x00, 0x00, 0x00, 0xb3, + 0x17, 0x00, 0x02, 0x10, 0x13, 0x00, 0x00, 0x01, + 0x32, 0x3a, 0x07, 0x06, 0x04, 0x18, 0x00, 0x01, + 0x36, 0x00, 0x00, 0x03, 0xbd, 0x17, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x2f, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x24, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xba, 0x37, 0x05, 0x04, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x01, 0x33, 0x37, 0x06, + 0x03, 0x17, 0x00, 0x02, 0x10, 0x13, 0x00, 0x00, + 0x01, 0x34, 0x3a, 0x07, 0x06, 0x04, 0x38, 0x17, + 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x6a, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x15, 0x17, 0x00, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x01, 0x35, 0x3a, 0x07, + 0x06, 0x03, 0x18, 0x00, 0x01, 0x36, 0x00, 0x00, + 0x03, 0x68, 0x17, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x6c, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x15, + 0x17, 0x00, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x01, + 0x36, 0x3a, 0x07, 0x06, 0x03, 0x18, 0x00, 0x01, + 0x36, 0x00, 0x00, 0x03, 0x45, 0x17, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x6e, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x15, 0x17, 0x00, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0x37, 0x3a, 0x07, 0x06, 0x03, + 0x18, 0x00, 0x01, 0x36, 0x00, 0x00, 0x03, 0x22, + 0x17, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x5b, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0xe5, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, + 0x04, 0x0e, 0x13, 0x00, 0x00, 0x00, 0x9e, 0x3a, + 0x07, 0x06, 0x02, 0x18, 0x00, 0x03, 0x0e, 0x18, + 0x00, 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xa8, 0x37, 0x06, 0x03, 0x03, 0x18, 0x00, + 0x00, 0x12, 0x00, 0x00, 0x00, 0x5d, 0x1f, 0x45, + 0x00, 0x00, 0x00, 0x97, 0x17, 0x00, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x2c, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x20, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xba, 0x37, 0x05, 0x04, 0x0c, 0x03, 0x17, + 0x00, 0x03, 0x17, 0x00, 0x04, 0x0f, 0x27, 0x03, + 0x18, 0x00, 0x04, 0x1c, 0x04, 0x36, 0xff, 0xff, + 0xff, 0xb8, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xfd, 0x37, 0x06, 0x03, 0x18, 0x00, 0x05, + 0x17, 0x00, 0x05, 0x2d, 0x33, 0x00, 0x00, 0x00, + 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, + 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x05, 0x17, 0x00, 0x03, 0x17, 0x00, 0x04, + 0x1c, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xa8, 0x37, 0x06, 0x03, 0x18, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x2c, 0x1f, + 0x03, 0x45, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x17, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x5d, 0x1f, + 0x45, 0xff, 0xff, 0xff, 0x5d, 0x0e, 0x13, 0x00, + 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0xff, + 0xff, 0xff, 0x4f, 0x17, 0x00, 0x03, 0x17, 0x00, + 0x02, 0x10, 0x13, 0x00, 0x00, 0x01, 0x38, 0x3a, + 0x07, 0x06, 0x04, 0x18, 0x00, 0x01, 0x36, 0x00, + 0x00, 0x02, 0x2f, 0x17, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x7b, 0x1e, 0x45, 0x00, 0x00, 0x01, + 0xc3, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xba, 0x37, 0x05, 0x04, 0x0e, 0x13, 0x00, 0x00, + 0x00, 0x9e, 0x3a, 0x07, 0x06, 0x02, 0x18, 0x00, + 0x03, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xa8, 0x37, 0x06, 0x03, 0x03, 0x18, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x7d, 0x1f, 0x45, 0x00, + 0x00, 0x01, 0x79, 0x0e, 0x13, 0x00, 0x00, 0x00, + 0xf7, 0x3a, 0x07, 0x06, 0x02, 0x18, 0x00, 0x04, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, + 0x37, 0x06, 0x03, 0x18, 0x00, 0x00, 0x13, 0x00, + 0x00, 0x00, 0x02, 0x17, 0x00, 0x04, 0x1a, 0x00, + 0x00, 0x00, 0xdd, 0x17, 0x00, 0x00, 0x17, 0x00, + 0x04, 0x1a, 0x00, 0x00, 0x01, 0x39, 0x13, 0x00, + 0x00, 0x00, 0xb4, 0x17, 0x00, 0x04, 0x1a, 0x00, + 0x00, 0x00, 0xf8, 0x17, 0x00, 0x00, 0x13, 0x00, + 0x00, 0x00, 0x6f, 0x1f, 0x03, 0x45, 0x00, 0x00, + 0x00, 0x0a, 0x04, 0x17, 0x00, 0x00, 0x13, 0x00, + 0x00, 0x00, 0x08, 0x1f, 0x03, 0x45, 0x00, 0x00, + 0x00, 0x0a, 0x04, 0x17, 0x00, 0x00, 0x13, 0x00, + 0x00, 0x00, 0x77, 0x1f, 0x45, 0x00, 0x00, 0x00, + 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, + 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, + 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, 0x3a, 0x1f, + 0x45, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, + 0x00, 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x15, 0x02, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xfd, 0x37, 0x06, 0x03, 0x17, 0x00, + 0x04, 0x1a, 0x00, 0x00, 0x00, 0xf4, 0x17, 0x00, + 0x04, 0x19, 0x00, 0x00, 0x00, 0xf4, 0x2d, 0x33, + 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, + 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x17, 0x00, 0x04, 0x0f, 0x17, 0x00, + 0x03, 0x35, 0x00, 0x00, 0x00, 0xd1, 0x05, 0x04, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa8, + 0x37, 0x06, 0x03, 0x18, 0x00, 0x00, 0x17, 0x00, + 0x00, 0x12, 0x00, 0x00, 0x00, 0x2c, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x55, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, 0x04, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa8, 0x37, + 0x06, 0x03, 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x6f, 0x1f, 0x03, 0x45, + 0x00, 0x00, 0x00, 0x0a, 0x04, 0x17, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x08, 0x1f, 0x03, 0x45, + 0x00, 0x00, 0x00, 0x0a, 0x04, 0x17, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x77, 0x1f, 0x45, 0x00, + 0x00, 0x00, 0x34, 0x0e, 0x13, 0x00, 0x00, 0x00, + 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, + 0x26, 0x17, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x7d, 0x1f, 0x03, 0x45, 0x00, 0x00, 0x00, 0x04, + 0x04, 0x17, 0x00, 0x00, 0x33, 0xff, 0xff, 0xfe, + 0x80, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, 0x37, + 0x05, 0x03, 0x36, 0xff, 0xff, 0xfe, 0x72, 0x36, + 0xff, 0xff, 0xfe, 0x6d, 0x17, 0x00, 0x03, 0x17, + 0x00, 0x02, 0x10, 0x13, 0x00, 0x00, 0x01, 0x3a, + 0x3a, 0x07, 0x06, 0x04, 0x18, 0x00, 0x01, 0x36, + 0x00, 0x00, 0x00, 0x5e, 0x17, 0x00, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x28, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x4e, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xba, 0x37, 0x05, 0x04, 0x15, 0x02, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xe6, 0x37, 0x06, 0x03, + 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, 0x39, 0x09, + 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x03, 0x46, 0x00, + 0x00, 0x00, 0x12, 0x04, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xa8, 0x37, 0x06, 0x03, 0x12, + 0x00, 0x00, 0x00, 0x29, 0x1f, 0x45, 0x00, 0x00, + 0x00, 0x10, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, + 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x02, + 0x0c, 0x38, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0xba, 0x37, 0x05, 0x04, 0x17, 0x00, 0x01, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, + 0x03, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xa8, 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, + 0x28, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x02, 0x0c, + 0x38, 0x0e, 0x13, 0x00, 0x00, 0x00, 0x9e, 0x3a, + 0x07, 0x06, 0x02, 0x18, 0x00, 0x00, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, + 0x04, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xa8, 0x37, 0x06, 0x03, 0x12, 0x00, 0x00, 0x00, + 0x29, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x81, 0x15, + 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xfd, 0x37, + 0x06, 0x03, 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, + 0x39, 0x09, 0x00, 0x00, 0x00, 0xd5, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, + 0x00, 0xaa, 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x17, 0x00, 0x01, 0x0f, 0x17, 0x00, + 0x00, 0x35, 0x00, 0x00, 0x00, 0xd1, 0x05, 0x04, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa8, + 0x37, 0x06, 0x03, 0x18, 0x00, 0x02, 0x17, 0x00, + 0x02, 0x12, 0x00, 0x00, 0x00, 0x2c, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x10, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xba, 0x37, 0x05, 0x04, 0x36, + 0xff, 0xff, 0xff, 0x85, 0x17, 0x00, 0x02, 0x12, + 0x00, 0x00, 0x00, 0x29, 0x1f, 0x45, 0xff, 0xff, + 0xff, 0x77, 0x0e, 0x13, 0x00, 0x00, 0x00, 0xaa, + 0x37, 0x05, 0x03, 0x36, 0xff, 0xff, 0xff, 0x69, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xba, + 0x37, 0x05, 0x04, 0x17, 0x00, 0x00, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x02, 0x0f, 0x14, 0x00, 0x00, + 0x01, 0x3b, 0x0e, 0x13, 0x00, 0x00, 0x01, 0x3c, + 0x3a, 0x07, 0x06, 0x02, 0x14, 0x00, 0x00, 0x01, + 0x3d, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, + 0x13, 0x00, 0x00, 0x01, 0x3b, 0x15, 0x02, 0x27, + 0x14, 0x00, 0x00, 0x01, 0x3b, 0x13, 0x00, 0x00, + 0x01, 0x3b, 0x15, 0x02, 0x26, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, 0x01, 0x3e, + 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, 0x00, 0x74, + 0x06, 0x02, 0x27, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x3d, 0x00, 0x04, 0x0e, 0x18, 0x00, 0x01, + 0x0e, 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, 0x15, + 0x02, 0x19, 0x00, 0x00, 0x00, 0xd2, 0x20, 0x45, + 0x00, 0x00, 0x00, 0x23, 0x17, 0x00, 0x01, 0x0c, + 0x0f, 0x15, 0x02, 0x17, 0x00, 0x00, 0x1b, 0x35, + 0x00, 0x00, 0x01, 0x3f, 0x06, 0x03, 0x27, 0x18, + 0x00, 0x01, 0x17, 0x00, 0x00, 0x0f, 0x27, 0x18, + 0x00, 0x00, 0x36, 0xff, 0xff, 0xff, 0xcd, 0x0e, + 0x18, 0x00, 0x02, 0x0e, 0x18, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x15, 0x02, 0x19, 0x00, 0x00, 0x00, + 0xd2, 0x20, 0x45, 0x00, 0x00, 0x00, 0x36, 0x0b, + 0x0f, 0x15, 0x02, 0x17, 0x00, 0x00, 0x1b, 0x35, + 0x00, 0x00, 0x01, 0x3f, 0x06, 0x03, 0x18, 0x00, + 0x03, 0x17, 0x00, 0x03, 0x17, 0x00, 0x02, 0x21, + 0x45, 0x00, 0x00, 0x00, 0x0b, 0x17, 0x00, 0x03, + 0x18, 0x00, 0x02, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x0f, 0x27, 0x18, 0x00, 0x00, + 0x36, 0xff, 0xff, 0xff, 0xba, 0x17, 0x00, 0x01, + 0x17, 0x00, 0x02, 0x27, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x07, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0x40, 0x15, 0x03, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x41, 0x15, 0x04, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0x42, 0x15, 0x05, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0x43, 0x15, 0x06, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x44, 0x0e, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x45, 0x0e, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x46, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x0a, 0x0c, + 0x0a, 0x0a, 0x09, 0x00, 0x00, 0x00, 0xe1, 0x13, + 0x00, 0x00, 0x01, 0x47, 0x3a, 0x07, 0x06, 0x06, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x48, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x06, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x48, 0x15, 0x05, 0x15, + 0x04, 0x15, 0x03, 0x15, 0x02, 0x09, 0x00, 0x00, + 0x01, 0x03, 0x13, 0x00, 0x00, 0x01, 0x47, 0x3a, + 0x07, 0x06, 0x07, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0x48, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x02, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0x48, + 0x0a, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x13, 0x09, + 0x00, 0x00, 0x01, 0x49, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0x76, 0x37, 0x05, 0x04, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x48, 0x19, 0x00, 0x00, 0x01, 0x44, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0x48, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x02, 0x3d, 0x00, 0x02, 0x0e, + 0x18, 0x00, 0x01, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0x48, 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, + 0x33, 0x00, 0x00, 0x00, 0x1f, 0x17, 0x00, 0x01, + 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0x46, + 0x27, 0x18, 0x00, 0x01, 0x17, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x01, 0x44, 0x18, 0x00, 0x00, 0x36, + 0xff, 0xff, 0xff, 0xd9, 0x17, 0x00, 0x01, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x02, + 0x0e, 0x18, 0x00, 0x01, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0x48, 0x18, 0x00, 0x00, 0x17, 0x00, + 0x00, 0x33, 0x00, 0x00, 0x00, 0x4d, 0x17, 0x00, + 0x01, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x45, 0x27, 0x18, 0x00, 0x01, 0x15, 0x02, 0x33, + 0x00, 0x00, 0x00, 0x15, 0x17, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x01, 0x43, 0x15, 0x02, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x17, 0x36, 0x00, 0x00, 0x00, + 0x22, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x41, 0x33, 0x00, 0x00, 0x00, 0x05, 0x36, 0x00, + 0x00, 0x00, 0x10, 0x17, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x01, 0x44, 0x18, 0x00, 0x00, 0x36, 0xff, + 0xff, 0xff, 0xab, 0x17, 0x00, 0x01, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x02, 0x0e, + 0x18, 0x00, 0x01, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0x48, 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, + 0x33, 0x00, 0x00, 0x00, 0x4d, 0x17, 0x00, 0x01, + 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0x46, + 0x27, 0x18, 0x00, 0x01, 0x15, 0x02, 0x33, 0x00, + 0x00, 0x00, 0x15, 0x17, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x01, 0x43, 0x15, 0x02, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x17, 0x36, 0x00, 0x00, 0x00, 0x22, + 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0x41, + 0x33, 0x00, 0x00, 0x00, 0x05, 0x36, 0x00, 0x00, + 0x00, 0x10, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, + 0x01, 0x44, 0x18, 0x00, 0x00, 0x36, 0xff, 0xff, + 0xff, 0xab, 0x17, 0x00, 0x01, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x02, 0x0e, 0x18, + 0x00, 0x01, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x48, 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, 0x33, + 0x00, 0x00, 0x00, 0x58, 0x17, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x01, 0x42, 0x33, 0x00, 0x00, 0x00, + 0x0d, 0x17, 0x00, 0x01, 0x0f, 0x27, 0x18, 0x00, + 0x01, 0x36, 0x00, 0x00, 0x00, 0x00, 0x15, 0x02, + 0x33, 0x00, 0x00, 0x00, 0x15, 0x17, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x43, 0x15, 0x02, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x17, 0x36, 0x00, 0x00, + 0x00, 0x22, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, + 0x01, 0x41, 0x33, 0x00, 0x00, 0x00, 0x05, 0x36, + 0x00, 0x00, 0x00, 0x10, 0x17, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x01, 0x44, 0x18, 0x00, 0x00, 0x36, + 0xff, 0xff, 0xff, 0xa0, 0x17, 0x00, 0x01, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x01, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0x48, 0x18, + 0x00, 0x00, 0x17, 0x00, 0x00, 0x33, 0x00, 0x00, + 0x00, 0x46, 0x15, 0x02, 0x33, 0x00, 0x00, 0x00, + 0x19, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x43, 0x15, 0x02, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x1f, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x41, 0x38, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, + 0x01, 0x41, 0x33, 0x00, 0x00, 0x00, 0x09, 0x17, + 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0x41, 0x38, + 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0x44, + 0x18, 0x00, 0x00, 0x36, 0xff, 0xff, 0xff, 0xb2, + 0x0a, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x3d, + 0x00, 0x01, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x48, 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, 0x33, + 0x00, 0x00, 0x00, 0x46, 0x15, 0x02, 0x33, 0x00, + 0x00, 0x00, 0x19, 0x17, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x01, 0x43, 0x15, 0x02, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x1f, 0x17, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x01, 0x40, 0x38, 0x17, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x01, 0x40, 0x33, 0x00, 0x00, 0x00, + 0x09, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x40, 0x38, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, + 0x01, 0x44, 0x18, 0x00, 0x00, 0x36, 0xff, 0xff, + 0xff, 0xb2, 0x0a, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x3d, 0x00, 0x01, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0x48, 0x18, 0x00, 0x00, 0x17, 0x00, + 0x00, 0x33, 0x00, 0x00, 0x00, 0x22, 0x17, 0x00, + 0x00, 0x19, 0x00, 0x00, 0x01, 0x43, 0x15, 0x02, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x02, 0x0c, 0x38, + 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0x44, + 0x18, 0x00, 0x00, 0x36, 0xff, 0xff, 0xff, 0xd6, + 0x0b, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x09, 0x15, + 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, + 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0x4a, 0x15, 0x04, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0x9d, 0x15, 0x05, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xe0, 0x15, 0x06, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x4b, 0x15, 0x07, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0x4c, 0x15, 0x08, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4d, 0x13, 0x00, + 0x00, 0x01, 0x4e, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0x4f, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x02, 0x3d, 0x00, 0x08, 0x0e, 0x13, 0x00, 0x00, + 0x01, 0x50, 0x35, 0x00, 0x00, 0x01, 0x51, 0x05, + 0x03, 0x0e, 0x18, 0x00, 0x00, 0x10, 0x18, 0x00, + 0x01, 0x17, 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0x4b, 0x19, 0x00, 0x00, 0x00, 0xd2, + 0x20, 0x45, 0x00, 0x00, 0x00, 0x40, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x17, 0x00, 0x01, + 0x13, 0x00, 0x00, 0x01, 0x52, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0x4b, 0x17, 0x00, 0x00, 0x1b, + 0x09, 0x00, 0x00, 0x00, 0xe1, 0x13, 0x00, 0x00, + 0x01, 0x50, 0x35, 0x00, 0x00, 0x01, 0x53, 0x05, + 0x07, 0x17, 0x00, 0x00, 0x0f, 0x27, 0x18, 0x00, + 0x00, 0x17, 0x00, 0x01, 0x0f, 0x27, 0x18, 0x00, + 0x01, 0x36, 0xff, 0xff, 0xff, 0xab, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0x9d, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, + 0x00, 0x01, 0x54, 0x3a, 0x07, 0x06, 0x04, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x0f, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0x4a, 0x10, + 0x13, 0x00, 0x00, 0x01, 0x56, 0x3a, 0x07, 0x06, + 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0x4a, + 0x0f, 0x13, 0x00, 0x00, 0x01, 0x57, 0x3a, 0x07, + 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x4b, 0x19, 0x00, 0x00, 0x00, 0xd2, 0x10, 0x27, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0x4a, 0x10, + 0x13, 0x00, 0x00, 0x01, 0x58, 0x3a, 0x07, 0x06, + 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0x4c, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0x59, 0x37, 0x06, 0x03, + 0x18, 0x00, 0x02, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0x4d, 0x33, 0x00, 0x00, 0x00, 0x0d, 0x17, + 0x00, 0x02, 0x0f, 0x27, 0x18, 0x00, 0x02, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x02, 0x0e, + 0x21, 0x45, 0x00, 0x00, 0x02, 0x6e, 0x0e, 0x17, + 0x00, 0x02, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x4a, 0x10, 0x13, 0x00, 0x00, 0x01, 0x5a, 0x3a, + 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x4d, 0x33, 0x00, 0x00, 0x02, 0x46, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x4a, 0x18, 0x00, 0x03, + 0x0e, 0x13, 0x00, 0x00, 0x01, 0x50, 0x35, 0x00, + 0x00, 0x01, 0x5b, 0x06, 0x02, 0x18, 0x00, 0x04, + 0x17, 0x00, 0x03, 0x17, 0x00, 0x04, 0x13, 0x00, + 0x00, 0x01, 0x5c, 0x09, 0x00, 0x00, 0x00, 0xb9, + 0x09, 0x00, 0x00, 0x00, 0xe1, 0x13, 0x00, 0x00, + 0x01, 0x50, 0x35, 0x00, 0x00, 0x01, 0x53, 0x05, + 0x07, 0x0e, 0x17, 0x00, 0x03, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0x5d, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x09, + 0x00, 0x00, 0x01, 0x5e, 0x17, 0x00, 0x03, 0x10, + 0x13, 0x00, 0x00, 0x01, 0x5f, 0x3a, 0x07, 0x06, + 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x0e, 0x17, 0x00, 0x03, 0x0f, 0x13, 0x00, 0x00, + 0x01, 0x60, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x17, 0x00, + 0x03, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x61, 0x3a, + 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x0e, 0x10, 0x17, 0x00, 0x03, 0x10, + 0x13, 0x00, 0x00, 0x01, 0x62, 0x3a, 0x07, 0x06, + 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x0e, 0x17, 0x00, 0x04, 0x17, 0x00, 0x03, 0x10, + 0x13, 0x00, 0x00, 0x01, 0x63, 0x3a, 0x07, 0x06, + 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x0e, 0x17, 0x00, 0x03, 0x0f, 0x13, 0x00, 0x00, + 0x01, 0x5d, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x13, 0x00, + 0x00, 0x01, 0x64, 0x3a, 0x07, 0x06, 0x02, 0x18, + 0x00, 0x05, 0x0e, 0x13, 0x00, 0x00, 0x01, 0x64, + 0x3a, 0x07, 0x06, 0x02, 0x18, 0x00, 0x06, 0x0e, + 0x17, 0x00, 0x05, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x0e, 0x17, 0x00, 0x03, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0x65, 0x3a, 0x07, 0x06, 0x03, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, + 0x0f, 0x17, 0x00, 0x03, 0x10, 0x13, 0x00, 0x00, + 0x01, 0x56, 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x17, 0x00, + 0x03, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x66, 0x3a, + 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x0e, 0x17, 0x00, 0x06, 0x17, 0x00, + 0x03, 0x10, 0x13, 0x00, 0x00, 0x01, 0x67, 0x3a, + 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x0e, 0x17, 0x00, 0x03, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0x65, 0x3a, 0x07, 0x06, 0x03, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, + 0x17, 0x00, 0x03, 0x0f, 0x13, 0x00, 0x00, 0x01, + 0x57, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x0e, 0x17, 0x00, 0x03, + 0x0f, 0x13, 0x00, 0x00, 0x01, 0x68, 0x3a, 0x07, + 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x0e, 0x17, 0x00, 0x03, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0x69, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x17, + 0x00, 0x04, 0x17, 0x00, 0x03, 0x10, 0x13, 0x00, + 0x00, 0x01, 0x6a, 0x3a, 0x07, 0x06, 0x04, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x09, + 0x00, 0x00, 0x01, 0x6b, 0x17, 0x00, 0x03, 0x10, + 0x13, 0x00, 0x00, 0x01, 0x6c, 0x3a, 0x07, 0x06, + 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x0e, 0x12, 0x00, 0x00, 0x00, 0x04, 0x17, 0x00, + 0x03, 0x10, 0x13, 0x00, 0x00, 0x01, 0x6d, 0x3a, + 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x0e, 0x17, 0x00, 0x03, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0x6e, 0x3a, 0x07, 0x06, 0x03, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, + 0x17, 0x00, 0x05, 0x17, 0x00, 0x03, 0x10, 0x13, + 0x00, 0x00, 0x01, 0x6f, 0x3a, 0x07, 0x06, 0x04, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, + 0x17, 0x00, 0x06, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x0e, 0x17, 0x00, 0x03, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0x70, 0x3a, 0x07, 0x06, 0x03, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x18, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0x4c, 0x19, 0x00, 0x00, 0x00, 0xd2, 0x20, + 0x45, 0x00, 0x00, 0x00, 0x20, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x4c, 0x17, 0x00, 0x00, + 0x1b, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, + 0x17, 0x00, 0x00, 0x0f, 0x27, 0x18, 0x00, 0x00, + 0x36, 0xff, 0xff, 0xff, 0xcb, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0x4c, 0x19, 0x00, 0x00, 0x00, + 0xd2, 0x0e, 0x21, 0x45, 0x00, 0x00, 0x00, 0x23, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0x4c, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x01, 0x4c, 0x19, 0x00, + 0x00, 0x00, 0xd2, 0x0f, 0x26, 0x1b, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x18, 0x00, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x0a, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x18, 0x00, 0x03, 0x0e, 0x17, 0x00, + 0x03, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x71, 0x3a, + 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x0e, 0x17, 0x00, 0x03, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0x72, 0x3a, 0x07, 0x06, 0x03, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, + 0x13, 0x00, 0x00, 0x01, 0x50, 0x35, 0x00, 0x00, + 0x01, 0x73, 0x05, 0x03, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x02, 0x0e, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x04, 0x13, 0x00, 0x00, 0x01, 0x74, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xce, 0x15, 0x02, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, + 0x03, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x75, + 0x13, 0x00, 0x00, 0x01, 0x76, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x4f, 0x13, 0x00, 0x00, 0x01, + 0x77, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x3f, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x3d, + 0x00, 0x01, 0x0e, 0x13, 0x00, 0x00, 0x01, 0x50, + 0x35, 0x00, 0x00, 0x01, 0x51, 0x05, 0x03, 0x0e, + 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x75, 0x19, 0x00, 0x00, + 0x00, 0xd2, 0x20, 0x45, 0x00, 0x00, 0x00, 0x20, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0x75, + 0x17, 0x00, 0x00, 0x1b, 0x35, 0x00, 0x00, 0x01, + 0x4f, 0x05, 0x03, 0x17, 0x00, 0x00, 0x0f, 0x27, + 0x18, 0x00, 0x00, 0x36, 0xff, 0xff, 0xff, 0xcb, + 0x0e, 0x13, 0x00, 0x00, 0x01, 0x50, 0x35, 0x00, + 0x00, 0x01, 0x73, 0x05, 0x03, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x15, 0x02, 0x2d, 0x33, + 0x00, 0x00, 0x00, 0x02, 0x0e, 0x38, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x75, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0x59, 0x37, 0x06, 0x03, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x06, 0x13, 0x00, 0x00, 0x01, + 0x78, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xce, + 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0x79, 0x15, 0x04, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0x7a, 0x15, 0x05, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x7b, 0x13, 0x00, 0x00, 0x01, + 0x7c, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, + 0x13, 0x00, 0x00, 0x01, 0x7d, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x3f, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x02, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0x7a, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0x5f, + 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0x79, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0x5f, + 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0x7b, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0x7e, + 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x03, 0x13, 0x00, 0x00, 0x01, 0x7f, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xce, 0x15, 0x02, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x13, + 0x00, 0x00, 0x01, 0x80, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0x4f, 0x13, 0x00, 0x00, 0x01, 0x7d, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x3f, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x04, 0x13, 0x00, 0x00, + 0x01, 0x81, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xce, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0x43, 0x13, 0x00, 0x00, 0x01, 0x82, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, 0x13, + 0x00, 0x00, 0x01, 0x7d, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0x3f, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x02, 0x3d, 0x00, 0x02, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0x43, 0x0f, 0x13, 0x00, 0x00, + 0x01, 0x3d, 0x35, 0x00, 0x00, 0x01, 0x83, 0x06, + 0x03, 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, 0x0a, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x78, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x43, 0x33, 0x00, 0x00, + 0x00, 0x3d, 0x13, 0x00, 0x00, 0x00, 0x72, 0x09, + 0x00, 0x00, 0x00, 0x73, 0x27, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x35, 0x00, 0x00, + 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, + 0x01, 0x84, 0x27, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0x43, 0x27, 0x09, 0x00, 0x00, 0x01, 0x85, + 0x27, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x76, 0x37, + 0x05, 0x04, 0x36, 0x00, 0x00, 0x00, 0x2f, 0x13, + 0x00, 0x00, 0x00, 0x72, 0x09, 0x00, 0x00, 0x00, + 0x73, 0x27, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x35, 0x00, 0x00, 0x00, 0x74, 0x06, + 0x02, 0x27, 0x09, 0x00, 0x00, 0x01, 0x86, 0x27, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0x76, 0x37, 0x05, + 0x04, 0x36, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x43, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0x3d, 0x35, 0x00, 0x00, 0x01, 0x87, + 0x06, 0x03, 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, + 0x0e, 0x21, 0x45, 0x00, 0x00, 0x00, 0x21, 0x0e, + 0x17, 0x00, 0x01, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0x88, + 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0x43, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0x3d, 0x35, 0x00, 0x00, + 0x01, 0x89, 0x06, 0x03, 0x18, 0x00, 0x01, 0x17, + 0x00, 0x01, 0x0e, 0x21, 0x45, 0x00, 0x00, 0x00, + 0x21, 0x0e, 0x17, 0x00, 0x01, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, + 0x01, 0x8a, 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x43, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x3d, 0x35, + 0x00, 0x00, 0x01, 0x8b, 0x06, 0x03, 0x18, 0x00, + 0x01, 0x17, 0x00, 0x01, 0x0e, 0x21, 0x45, 0x00, + 0x00, 0x00, 0x49, 0x17, 0x00, 0x01, 0x0f, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0x70, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x21, 0x0e, 0x17, 0x00, 0x01, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, + 0x00, 0x00, 0x01, 0x6d, 0x3a, 0x07, 0x06, 0x04, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x17, 0x00, 0x00, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, + 0x13, 0x00, 0x00, 0x01, 0x6f, 0x3a, 0x07, 0x06, + 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x04, 0x13, + 0x00, 0x00, 0x01, 0x8c, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xce, 0x15, 0x02, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0x43, 0x13, 0x00, 0x00, + 0x01, 0x8d, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0x4f, 0x13, 0x00, 0x00, 0x01, 0x7d, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0x3f, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x02, 0x3d, 0x00, 0x02, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x01, 0x43, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0x3d, 0x35, 0x00, 0x00, 0x01, + 0x8e, 0x06, 0x03, 0x18, 0x00, 0x00, 0x17, 0x00, + 0x00, 0x0a, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x78, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0x43, 0x33, + 0x00, 0x00, 0x00, 0x3d, 0x13, 0x00, 0x00, 0x00, + 0x72, 0x09, 0x00, 0x00, 0x00, 0x73, 0x27, 0x0e, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x35, + 0x00, 0x00, 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, + 0x00, 0x00, 0x01, 0x84, 0x27, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0x43, 0x27, 0x09, 0x00, 0x00, + 0x01, 0x8f, 0x27, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0x76, 0x37, 0x05, 0x04, 0x36, 0x00, 0x00, 0x00, + 0x2f, 0x13, 0x00, 0x00, 0x00, 0x72, 0x09, 0x00, + 0x00, 0x00, 0x73, 0x27, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x35, 0x00, 0x00, 0x00, + 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, 0x01, + 0x90, 0x27, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x76, + 0x37, 0x05, 0x04, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0x43, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0x3d, 0x35, 0x00, 0x00, + 0x01, 0x87, 0x06, 0x03, 0x18, 0x00, 0x01, 0x17, + 0x00, 0x01, 0x0e, 0x21, 0x45, 0x00, 0x00, 0x00, + 0x21, 0x0e, 0x17, 0x00, 0x01, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, + 0x01, 0x88, 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x43, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x3d, 0x35, + 0x00, 0x00, 0x01, 0x89, 0x06, 0x03, 0x18, 0x00, + 0x01, 0x17, 0x00, 0x01, 0x0e, 0x21, 0x45, 0x00, + 0x00, 0x00, 0x21, 0x0e, 0x17, 0x00, 0x01, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, + 0x00, 0x00, 0x01, 0x8a, 0x3a, 0x07, 0x06, 0x04, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0x43, 0x33, 0x00, 0x00, 0x00, 0x6f, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0x43, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0x3d, 0x35, 0x00, 0x00, + 0x01, 0x8b, 0x06, 0x03, 0x18, 0x00, 0x01, 0x17, + 0x00, 0x01, 0x0e, 0x21, 0x45, 0x00, 0x00, 0x00, + 0x4e, 0x17, 0x00, 0x01, 0x0f, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, + 0x70, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, + 0x21, 0x0e, 0x17, 0x00, 0x01, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, + 0x01, 0x6d, 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, + 0x00, 0x05, 0x36, 0x00, 0x00, 0x00, 0x00, 0x0e, + 0x17, 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0x6f, + 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x04, 0x13, 0x00, 0x00, 0x01, 0x91, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xce, 0x15, 0x02, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, + 0x03, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xf4, + 0x13, 0x00, 0x00, 0x01, 0x92, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x4f, 0x13, 0x00, 0x00, 0x01, + 0x7d, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x3f, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x3d, + 0x00, 0x01, 0x0e, 0x13, 0x00, 0x00, 0x01, 0x3d, + 0x35, 0x00, 0x00, 0x01, 0x93, 0x06, 0x02, 0x18, + 0x00, 0x00, 0x17, 0x00, 0x00, 0x0e, 0x21, 0x45, + 0x00, 0x00, 0x00, 0x21, 0x0e, 0x17, 0x00, 0x00, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, + 0x13, 0x00, 0x00, 0x01, 0x8a, 0x3a, 0x07, 0x06, + 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xf4, 0x0a, 0x1f, 0x45, 0x00, + 0x00, 0x00, 0x14, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xf4, 0x35, 0x00, 0x00, 0x01, 0x4f, + 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x19, 0x0e, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0x71, 0x3a, 0x07, 0x06, + 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x13, 0x00, 0x00, 0x01, 0x72, 0x3a, 0x07, + 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x06, + 0x13, 0x00, 0x00, 0x01, 0x94, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xce, 0x15, 0x02, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, 0x03, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xf5, 0x15, 0x04, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xf4, 0x15, + 0x05, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x95, + 0x13, 0x00, 0x00, 0x01, 0x96, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x4f, 0x13, 0x00, 0x00, 0x01, + 0x97, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x3f, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x3d, + 0x00, 0x07, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xf4, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, + 0x03, 0x0e, 0x13, 0x00, 0x00, 0x01, 0x64, 0x3a, + 0x07, 0x06, 0x02, 0x18, 0x00, 0x00, 0x0a, 0x0b, + 0x0a, 0x17, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0xe1, 0x13, 0x00, 0x00, 0x01, 0x3d, 0x35, 0x00, + 0x00, 0x00, 0xd1, 0x05, 0x07, 0x0f, 0x18, 0x00, + 0x01, 0x17, 0x00, 0x01, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0x95, 0x19, 0x00, 0x00, 0x00, 0xd2, + 0x20, 0x45, 0x00, 0x00, 0x00, 0x41, 0x0e, 0x13, + 0x00, 0x00, 0x01, 0x64, 0x3a, 0x07, 0x06, 0x02, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0x95, 0x17, + 0x00, 0x01, 0x1b, 0x1a, 0x00, 0x00, 0x01, 0x98, + 0x0e, 0x13, 0x00, 0x00, 0x01, 0x64, 0x3a, 0x07, + 0x06, 0x02, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x95, 0x17, 0x00, 0x01, 0x1b, 0x1a, 0x00, 0x00, + 0x01, 0x99, 0x17, 0x00, 0x01, 0x0f, 0x27, 0x18, + 0x00, 0x01, 0x36, 0xff, 0xff, 0xff, 0xaa, 0x0e, + 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x95, 0x19, 0x00, 0x00, + 0x00, 0xd2, 0x20, 0x45, 0x00, 0x00, 0x01, 0x8f, + 0x17, 0x00, 0x01, 0x0f, 0x27, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0x95, 0x19, 0x00, 0x00, 0x00, + 0xd2, 0x23, 0x18, 0x00, 0x02, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0x95, 0x17, 0x00, 0x01, 0x1b, + 0x18, 0x00, 0x03, 0x17, 0x00, 0x02, 0x33, 0x00, + 0x00, 0x00, 0x0f, 0x17, 0x00, 0x00, 0x03, 0x18, + 0x00, 0x05, 0x18, 0x00, 0x04, 0x36, 0x00, 0x00, + 0x00, 0x2a, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x95, 0x17, 0x00, 0x01, 0x0f, 0x27, 0x1b, 0x19, + 0x00, 0x00, 0x01, 0x98, 0x18, 0x00, 0x04, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x01, 0x95, 0x17, 0x00, + 0x01, 0x0f, 0x27, 0x1b, 0x19, 0x00, 0x00, 0x01, + 0x99, 0x18, 0x00, 0x05, 0x17, 0x00, 0x03, 0x19, + 0x00, 0x00, 0x00, 0xf4, 0x33, 0x00, 0x00, 0x00, + 0x85, 0x17, 0x00, 0x01, 0x0e, 0x21, 0x45, 0x00, + 0x00, 0x00, 0x15, 0x0e, 0x17, 0x00, 0x03, 0x19, + 0x00, 0x00, 0x01, 0x98, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x0e, 0x17, 0x00, 0x03, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x65, 0x3a, + 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x0e, 0x17, 0x00, 0x03, 0x19, 0x00, + 0x00, 0x00, 0xf4, 0x35, 0x00, 0x00, 0x01, 0x4f, + 0x05, 0x03, 0x0e, 0x17, 0x00, 0x03, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, + 0x9a, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x0e, 0x17, 0x00, 0x04, + 0x17, 0x00, 0x03, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x10, 0x13, 0x00, 0x00, 0x01, 0x9b, 0x3a, 0x07, + 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x00, 0x1f, 0x17, 0x00, + 0x01, 0x0e, 0x21, 0x45, 0x00, 0x00, 0x00, 0x15, + 0x0e, 0x17, 0x00, 0x03, 0x19, 0x00, 0x00, 0x01, + 0x98, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x01, + 0x0e, 0x21, 0x45, 0x00, 0x00, 0x00, 0x15, 0x0e, + 0x17, 0x00, 0x03, 0x19, 0x00, 0x00, 0x01, 0x99, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x18, 0x00, 0x06, + 0x17, 0x00, 0x06, 0x17, 0x00, 0x03, 0x19, 0x00, + 0x00, 0x00, 0xd2, 0x20, 0x45, 0x00, 0x00, 0x00, + 0x1c, 0x0e, 0x17, 0x00, 0x03, 0x17, 0x00, 0x06, + 0x1b, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, + 0x17, 0x00, 0x06, 0x0f, 0x27, 0x18, 0x00, 0x06, + 0x36, 0xff, 0xff, 0xff, 0xd3, 0x0e, 0x17, 0x00, + 0x05, 0x17, 0x00, 0x03, 0x19, 0x00, 0x00, 0x00, + 0xf5, 0x10, 0x13, 0x00, 0x00, 0x01, 0x6f, 0x3a, + 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x17, 0x00, 0x01, 0x0f, 0x27, 0x18, + 0x00, 0x01, 0x36, 0xff, 0xff, 0xfe, 0x5c, 0x0e, + 0x13, 0x00, 0x00, 0x01, 0x3d, 0x35, 0x00, 0x00, + 0x00, 0xdb, 0x05, 0x03, 0x0e, 0x17, 0x00, 0x00, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xf5, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0x70, 0x3a, 0x07, 0x06, + 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x3d, + 0x00, 0x05, 0x0e, 0x18, 0x00, 0x00, 0x15, 0x02, + 0x33, 0x00, 0x00, 0x00, 0x80, 0x0e, 0x18, 0x00, + 0x01, 0x17, 0x00, 0x01, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0x95, 0x19, 0x00, 0x00, 0x00, 0xd2, + 0x20, 0x45, 0x00, 0x00, 0x00, 0xd4, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x95, 0x17, 0x00, 0x01, + 0x1b, 0x18, 0x00, 0x03, 0x0e, 0x18, 0x00, 0x02, + 0x17, 0x00, 0x02, 0x17, 0x00, 0x03, 0x19, 0x00, + 0x00, 0x00, 0xd2, 0x20, 0x45, 0x00, 0x00, 0x00, + 0x37, 0x0b, 0x0f, 0x17, 0x00, 0x03, 0x17, 0x00, + 0x02, 0x1b, 0x35, 0x00, 0x00, 0x01, 0x3f, 0x06, + 0x03, 0x18, 0x00, 0x04, 0x17, 0x00, 0x04, 0x17, + 0x00, 0x00, 0x21, 0x45, 0x00, 0x00, 0x00, 0x0b, + 0x17, 0x00, 0x04, 0x18, 0x00, 0x00, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x02, 0x0f, 0x27, + 0x18, 0x00, 0x02, 0x36, 0xff, 0xff, 0xff, 0xb8, + 0x17, 0x00, 0x01, 0x0f, 0x27, 0x18, 0x00, 0x01, + 0x36, 0xff, 0xff, 0xff, 0x84, 0x0e, 0x18, 0x00, + 0x01, 0x17, 0x00, 0x01, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0x95, 0x19, 0x00, 0x00, 0x00, 0xd2, + 0x20, 0x45, 0x00, 0x00, 0x00, 0x54, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x95, 0x17, 0x00, 0x01, + 0x1b, 0x18, 0x00, 0x03, 0x0e, 0x18, 0x00, 0x02, + 0x17, 0x00, 0x02, 0x17, 0x00, 0x03, 0x19, 0x00, + 0x00, 0x00, 0xd2, 0x20, 0x45, 0x00, 0x00, 0x00, + 0x24, 0x17, 0x00, 0x00, 0x0c, 0x0f, 0x17, 0x00, + 0x03, 0x17, 0x00, 0x02, 0x1b, 0x35, 0x00, 0x00, + 0x01, 0x3f, 0x06, 0x03, 0x27, 0x18, 0x00, 0x00, + 0x17, 0x00, 0x02, 0x0f, 0x27, 0x18, 0x00, 0x02, + 0x36, 0xff, 0xff, 0xff, 0xcb, 0x17, 0x00, 0x01, + 0x0f, 0x27, 0x18, 0x00, 0x01, 0x36, 0xff, 0xff, + 0xff, 0x97, 0x17, 0x00, 0x00, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x05, 0x13, 0x00, 0x00, 0x01, 0x9c, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xce, 0x15, + 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, + 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xf4, 0x15, 0x04, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xfa, 0x13, 0x00, 0x00, 0x01, 0x9d, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, 0x13, 0x00, + 0x00, 0x01, 0x9e, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0x3f, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x02, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xf4, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x13, 0x00, 0x00, 0x01, 0x9f, 0x3a, 0x07, + 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x13, 0x00, 0x00, 0x01, 0x3d, 0x19, 0x00, + 0x00, 0x01, 0x48, 0x19, 0x00, 0x00, 0x01, 0x45, + 0x0f, 0x27, 0x13, 0x00, 0x00, 0x01, 0x3d, 0x19, + 0x00, 0x00, 0x01, 0x48, 0x1a, 0x00, 0x00, 0x01, + 0x45, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xfa, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, + 0x13, 0x00, 0x00, 0x01, 0x3d, 0x19, 0x00, 0x00, + 0x01, 0x48, 0x19, 0x00, 0x00, 0x01, 0x45, 0x0f, + 0x26, 0x13, 0x00, 0x00, 0x01, 0x3d, 0x19, 0x00, + 0x00, 0x01, 0x48, 0x1a, 0x00, 0x00, 0x01, 0x45, + 0x0e, 0x0f, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0x88, 0x3a, + 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x15, 0x02, 0x2d, 0x33, 0x00, 0x00, 0x00, + 0x2b, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xfa, + 0x19, 0x00, 0x00, 0x00, 0xce, 0x13, 0x00, 0x00, + 0x00, 0xcf, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x12, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xfa, 0x19, + 0x00, 0x00, 0x01, 0xa0, 0x19, 0x00, 0x00, 0x00, + 0xd2, 0x38, 0x0e, 0x38, 0x0b, 0x0f, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xfa, 0x35, 0x00, 0x00, + 0x01, 0x3f, 0x06, 0x03, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x08, 0x13, 0x00, 0x00, 0x01, 0xa1, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xce, 0x15, 0x02, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, + 0x03, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xa2, + 0x15, 0x04, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0xa3, 0x15, 0x05, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0x4c, 0x15, 0x06, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xa4, 0x15, 0x07, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0xa5, 0x13, 0x00, 0x00, 0x01, + 0xa6, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, + 0x13, 0x00, 0x00, 0x01, 0xa7, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x3f, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x02, 0x3d, 0x00, 0x0a, 0x0e, 0x13, + 0x00, 0x00, 0x01, 0x64, 0x3a, 0x07, 0x06, 0x02, + 0x18, 0x00, 0x00, 0x0e, 0x13, 0x00, 0x00, 0x01, + 0x64, 0x3a, 0x07, 0x06, 0x02, 0x18, 0x00, 0x01, + 0x0e, 0x17, 0x00, 0x01, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, + 0xa8, 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x13, 0x00, 0x00, 0x01, + 0x3d, 0x19, 0x00, 0x00, 0x01, 0x48, 0x19, 0x00, + 0x00, 0x01, 0x46, 0x0f, 0x27, 0x13, 0x00, 0x00, + 0x01, 0x3d, 0x19, 0x00, 0x00, 0x01, 0x48, 0x1a, + 0x00, 0x00, 0x01, 0x46, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0x4c, 0x35, 0x00, 0x00, 0x01, + 0x4f, 0x05, 0x03, 0x13, 0x00, 0x00, 0x01, 0x3d, + 0x19, 0x00, 0x00, 0x01, 0x48, 0x19, 0x00, 0x00, + 0x01, 0x46, 0x0f, 0x26, 0x13, 0x00, 0x00, 0x01, + 0x3d, 0x19, 0x00, 0x00, 0x01, 0x48, 0x1a, 0x00, + 0x00, 0x01, 0x46, 0x0e, 0x0f, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0xa2, 0x10, 0x13, 0x00, 0x00, + 0x01, 0x8a, 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0xa2, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0xa9, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x17, + 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xa2, 0x10, 0x13, 0x00, 0x00, 0x01, 0x6f, 0x3a, + 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x0e, 0x17, 0x00, 0x01, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0xa4, 0x33, 0x00, 0x00, 0x05, + 0x7b, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xa4, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0xa9, 0x3a, 0x07, 0x06, 0x03, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xa4, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, + 0x01, 0x61, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x13, 0x00, + 0x00, 0x01, 0x64, 0x3a, 0x07, 0x06, 0x02, 0x18, + 0x00, 0x02, 0x0e, 0x17, 0x00, 0x02, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0xa4, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0xa8, + 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x13, 0x00, 0x00, 0x01, 0x3d, + 0x19, 0x00, 0x00, 0x01, 0x48, 0x19, 0x00, 0x00, + 0x01, 0x46, 0x0f, 0x27, 0x13, 0x00, 0x00, 0x01, + 0x3d, 0x19, 0x00, 0x00, 0x01, 0x48, 0x1a, 0x00, + 0x00, 0x01, 0x46, 0x0e, 0x18, 0x00, 0x03, 0x17, + 0x00, 0x03, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xa4, 0x19, 0x00, 0x00, 0x00, 0xd2, 0x20, 0x45, + 0x00, 0x00, 0x00, 0x41, 0x0e, 0x13, 0x00, 0x00, + 0x01, 0x64, 0x3a, 0x07, 0x06, 0x02, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0xa4, 0x17, 0x00, 0x03, + 0x1b, 0x1a, 0x00, 0x00, 0x01, 0xaa, 0x0e, 0x13, + 0x00, 0x00, 0x01, 0x64, 0x3a, 0x07, 0x06, 0x02, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xa4, 0x17, + 0x00, 0x03, 0x1b, 0x1a, 0x00, 0x00, 0x01, 0x99, + 0x17, 0x00, 0x03, 0x0f, 0x27, 0x18, 0x00, 0x03, + 0x36, 0xff, 0xff, 0xff, 0xaa, 0x0e, 0x13, 0x00, + 0x00, 0x01, 0x64, 0x3a, 0x07, 0x06, 0x02, 0x18, + 0x00, 0x04, 0x0e, 0x18, 0x00, 0x03, 0x17, 0x00, + 0x03, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xa4, + 0x19, 0x00, 0x00, 0x00, 0xd2, 0x20, 0x45, 0x00, + 0x00, 0x02, 0xe7, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xa4, 0x17, 0x00, 0x03, 0x1b, 0x18, 0x00, + 0x05, 0x0e, 0x17, 0x00, 0x05, 0x19, 0x00, 0x00, + 0x01, 0xaa, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x0e, 0x13, 0x00, 0x00, 0x01, 0x50, 0x35, + 0x00, 0x00, 0x01, 0x51, 0x05, 0x03, 0x17, 0x00, + 0x05, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0e, 0x13, + 0x00, 0x00, 0x01, 0x50, 0x35, 0x00, 0x00, 0x01, + 0x5b, 0x06, 0x02, 0x13, 0x00, 0x00, 0x01, 0x5c, + 0x17, 0x00, 0x05, 0x19, 0x00, 0x00, 0x00, 0xf8, + 0x09, 0x00, 0x00, 0x00, 0xe1, 0x13, 0x00, 0x00, + 0x01, 0x50, 0x35, 0x00, 0x00, 0x01, 0x53, 0x05, + 0x07, 0x0e, 0x17, 0x00, 0x05, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x65, + 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x0e, 0x17, 0x00, 0x05, 0x19, + 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x13, 0x00, 0x00, + 0x01, 0x50, 0x35, 0x00, 0x00, 0x01, 0xab, 0x06, + 0x03, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x17, 0x00, + 0x05, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, + 0x00, 0x00, 0x01, 0x63, 0x3a, 0x07, 0x06, 0x04, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x17, + 0x00, 0x05, 0x19, 0x00, 0x00, 0x00, 0xf9, 0x33, + 0x00, 0x00, 0x01, 0x8c, 0x0e, 0x13, 0x00, 0x00, + 0x01, 0x64, 0x3a, 0x07, 0x06, 0x02, 0x18, 0x00, + 0x06, 0x0e, 0x17, 0x00, 0x06, 0x17, 0x00, 0x05, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, + 0x00, 0x01, 0xa8, 0x3a, 0x07, 0x06, 0x04, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x13, 0x00, + 0x00, 0x01, 0x3d, 0x19, 0x00, 0x00, 0x01, 0x48, + 0x19, 0x00, 0x00, 0x01, 0x46, 0x0f, 0x27, 0x13, + 0x00, 0x00, 0x01, 0x3d, 0x19, 0x00, 0x00, 0x01, + 0x48, 0x1a, 0x00, 0x00, 0x01, 0x46, 0x0e, 0x17, + 0x00, 0x05, 0x19, 0x00, 0x00, 0x00, 0xf9, 0x35, + 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, 0x13, 0x00, + 0x00, 0x01, 0x3d, 0x19, 0x00, 0x00, 0x01, 0x48, + 0x19, 0x00, 0x00, 0x01, 0x46, 0x0f, 0x26, 0x13, + 0x00, 0x00, 0x01, 0x3d, 0x19, 0x00, 0x00, 0x01, + 0x48, 0x1a, 0x00, 0x00, 0x01, 0x46, 0x0e, 0x0f, + 0x17, 0x00, 0x05, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x10, 0x13, 0x00, 0x00, 0x01, 0x8a, 0x3a, 0x07, + 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x17, 0x00, 0x03, 0x0f, 0x27, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0xa4, 0x19, 0x00, 0x00, + 0x00, 0xd2, 0x23, 0x45, 0x00, 0x00, 0x00, 0x0b, + 0x17, 0x00, 0x04, 0x18, 0x00, 0x07, 0x36, 0x00, + 0x00, 0x00, 0x15, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xa4, 0x17, 0x00, 0x03, 0x0f, 0x27, 0x1b, + 0x19, 0x00, 0x00, 0x01, 0xaa, 0x18, 0x00, 0x07, + 0x17, 0x00, 0x05, 0x19, 0x00, 0x00, 0x00, 0xf9, + 0x19, 0x00, 0x00, 0x01, 0xac, 0x13, 0x00, 0x00, + 0x01, 0xad, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x22, + 0x0e, 0x17, 0x00, 0x07, 0x17, 0x00, 0x05, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, + 0x01, 0x9b, 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, + 0x00, 0x1d, 0x0e, 0x17, 0x00, 0x07, 0x17, 0x00, + 0x05, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, + 0x00, 0x00, 0x01, 0xae, 0x3a, 0x07, 0x06, 0x04, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, + 0x17, 0x00, 0x05, 0x19, 0x00, 0x00, 0x01, 0x99, + 0x17, 0x00, 0x05, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x10, 0x13, 0x00, 0x00, 0x01, 0x6f, 0x3a, 0x07, + 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x0e, 0x17, 0x00, 0x06, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x0e, 0x17, 0x00, 0x05, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0x70, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x17, + 0x00, 0x07, 0x17, 0x00, 0x05, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0x6f, + 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x0e, 0x17, 0x00, 0x05, 0x19, 0x00, 0x00, 0x01, + 0x99, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x0e, 0x17, 0x00, 0x05, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x61, 0x3a, + 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x0e, 0x17, 0x00, 0x05, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, + 0x70, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x0e, 0x17, 0x00, 0x05, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0xaf, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x17, + 0x00, 0x05, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0x61, 0x3a, 0x07, 0x06, + 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x0e, 0x17, 0x00, 0x05, 0x19, 0x00, 0x00, 0x00, + 0xfa, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, + 0x0e, 0x13, 0x00, 0x00, 0x01, 0x50, 0x35, 0x00, + 0x00, 0x01, 0x73, 0x05, 0x03, 0x17, 0x00, 0x03, + 0x0f, 0x27, 0x18, 0x00, 0x03, 0x36, 0xff, 0xff, + 0xfd, 0x04, 0x0e, 0x17, 0x00, 0x04, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x13, 0x00, 0x00, + 0x01, 0x3d, 0x19, 0x00, 0x00, 0x01, 0x48, 0x19, + 0x00, 0x00, 0x01, 0x46, 0x0f, 0x26, 0x13, 0x00, + 0x00, 0x01, 0x3d, 0x19, 0x00, 0x00, 0x01, 0x48, + 0x1a, 0x00, 0x00, 0x01, 0x46, 0x0e, 0x0f, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x01, 0xa4, 0x19, 0x00, + 0x00, 0x00, 0xf5, 0x10, 0x13, 0x00, 0x00, 0x01, + 0x8a, 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x0e, 0x13, 0x00, 0x00, + 0x01, 0x64, 0x3a, 0x07, 0x06, 0x02, 0x18, 0x00, + 0x05, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xa4, 0x19, 0x00, 0x00, 0x00, 0xf5, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0x61, 0x3a, 0x07, 0x06, 0x03, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, + 0x17, 0x00, 0x05, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xa4, 0x19, 0x00, 0x00, 0x00, 0xf5, 0x10, + 0x13, 0x00, 0x00, 0x01, 0x67, 0x3a, 0x07, 0x06, + 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xa4, + 0x19, 0x00, 0x00, 0x00, 0xf5, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0xaf, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x17, + 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xa4, 0x19, 0x00, 0x00, 0x00, 0xf5, 0x10, 0x13, + 0x00, 0x00, 0x01, 0x6f, 0x3a, 0x07, 0x06, 0x04, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, + 0x17, 0x00, 0x05, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xa4, 0x19, 0x00, 0x00, 0x00, 0xf5, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0x70, 0x3a, 0x07, 0x06, + 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xa4, + 0x19, 0x00, 0x00, 0x00, 0xf5, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0xa9, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x17, + 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xa4, 0x19, 0x00, 0x00, 0x00, 0xf5, 0x10, 0x13, + 0x00, 0x00, 0x01, 0x6f, 0x3a, 0x07, 0x06, 0x04, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, + 0x17, 0x00, 0x02, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x0e, 0x10, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0xa4, 0x19, 0x00, 0x00, 0x00, 0xf5, + 0x10, 0x13, 0x00, 0x00, 0x01, 0x62, 0x3a, 0x07, + 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xa4, 0x19, 0x00, 0x00, 0x00, 0xf5, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0xaf, 0x3a, 0x07, 0x06, 0x03, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x19, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0xa2, 0x0f, 0x13, 0x00, 0x00, + 0x01, 0xaf, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x17, 0x00, + 0x00, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xa5, 0x33, + 0x00, 0x00, 0x00, 0x14, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0xa5, 0x35, 0x00, 0x00, 0x01, + 0x4f, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x0e, 0x13, 0x00, 0x00, 0x01, 0x64, 0x3a, 0x07, + 0x06, 0x02, 0x18, 0x00, 0x02, 0x0e, 0x17, 0x00, + 0x02, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xa3, + 0x10, 0x13, 0x00, 0x00, 0x01, 0x9b, 0x3a, 0x07, + 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xa3, 0x0f, 0x13, 0x00, 0x00, 0x01, 0xb0, 0x3a, + 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x0e, 0x17, 0x00, 0x02, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x03, 0x0e, + 0x18, 0x00, 0x00, 0x15, 0x02, 0x33, 0x00, 0x00, + 0x00, 0xc5, 0x0b, 0x0f, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0x4c, 0x35, 0x00, 0x00, 0x01, 0x3f, + 0x06, 0x03, 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, + 0x17, 0x00, 0x00, 0x21, 0x45, 0x00, 0x00, 0x00, + 0x0b, 0x17, 0x00, 0x01, 0x18, 0x00, 0x00, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0xa4, 0x33, 0x00, 0x00, 0x00, 0x59, + 0x0e, 0x18, 0x00, 0x02, 0x17, 0x00, 0x02, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x01, 0xa4, 0x19, 0x00, + 0x00, 0x00, 0xd2, 0x20, 0x45, 0x00, 0x00, 0x00, + 0x40, 0x0b, 0x0f, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xa4, 0x17, 0x00, 0x02, 0x1b, 0x19, 0x00, + 0x00, 0x00, 0xfa, 0x35, 0x00, 0x00, 0x01, 0x3f, + 0x06, 0x03, 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, + 0x17, 0x00, 0x00, 0x21, 0x45, 0x00, 0x00, 0x00, + 0x0b, 0x17, 0x00, 0x01, 0x18, 0x00, 0x00, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x02, 0x0f, + 0x27, 0x18, 0x00, 0x02, 0x36, 0xff, 0xff, 0xff, + 0xab, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xa5, + 0x33, 0x00, 0x00, 0x01, 0x1e, 0x0b, 0x0f, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x01, 0xa5, 0x35, 0x00, + 0x00, 0x01, 0x3f, 0x06, 0x03, 0x18, 0x00, 0x01, + 0x17, 0x00, 0x01, 0x17, 0x00, 0x00, 0x21, 0x45, + 0x00, 0x00, 0x00, 0x06, 0x17, 0x00, 0x01, 0x18, + 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0xf4, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x01, 0x4c, 0x19, 0x00, + 0x00, 0x00, 0xce, 0x13, 0x00, 0x00, 0x00, 0xcf, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x1d, 0x17, 0x00, + 0x00, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0x4c, + 0x19, 0x00, 0x00, 0x01, 0xa0, 0x19, 0x00, 0x00, + 0x00, 0xd2, 0x27, 0x18, 0x00, 0x00, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xa4, 0x33, 0x00, 0x00, 0x00, 0x74, 0x17, + 0x00, 0x00, 0x0f, 0x27, 0x18, 0x00, 0x00, 0x0e, + 0x18, 0x00, 0x02, 0x17, 0x00, 0x02, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0xa4, 0x19, 0x00, 0x00, + 0x00, 0xd2, 0x20, 0x45, 0x00, 0x00, 0x00, 0x53, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xa4, 0x17, + 0x00, 0x02, 0x1b, 0x19, 0x00, 0x00, 0x00, 0xfa, + 0x19, 0x00, 0x00, 0x00, 0xce, 0x13, 0x00, 0x00, + 0x00, 0xcf, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x26, + 0x17, 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xa4, 0x17, 0x00, 0x02, 0x1b, 0x19, 0x00, + 0x00, 0x00, 0xfa, 0x19, 0x00, 0x00, 0x01, 0xa0, + 0x19, 0x00, 0x00, 0x00, 0xd2, 0x27, 0x18, 0x00, + 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, + 0x02, 0x0f, 0x27, 0x18, 0x00, 0x02, 0x36, 0xff, + 0xff, 0xff, 0x98, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xa5, 0x33, 0x00, 0x00, 0x00, 0x34, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x01, 0xa5, 0x19, 0x00, + 0x00, 0x00, 0xce, 0x13, 0x00, 0x00, 0x00, 0xcf, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x1d, 0x17, 0x00, + 0x00, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xa5, + 0x19, 0x00, 0x00, 0x01, 0xa0, 0x19, 0x00, 0x00, + 0x00, 0xd2, 0x27, 0x18, 0x00, 0x00, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x04, 0x13, 0x00, 0x00, 0x01, + 0xb1, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xce, + 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xf4, 0x13, 0x00, 0x00, 0x01, 0xb2, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, 0x13, 0x00, + 0x00, 0x01, 0x7d, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0x3f, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x02, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xf4, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x13, 0x00, 0x00, 0x01, 0xb0, 0x3a, 0x07, + 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x05, + 0x13, 0x00, 0x00, 0x01, 0xb3, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xce, 0x15, 0x02, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, 0x03, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xf8, 0x15, 0x04, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xfa, 0x13, + 0x00, 0x00, 0x01, 0xb4, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0x4f, 0x13, 0x00, 0x00, 0x01, 0xb5, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x3f, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x3d, 0x00, + 0x02, 0x0e, 0x13, 0x00, 0x00, 0x01, 0x64, 0x3a, + 0x07, 0x06, 0x02, 0x18, 0x00, 0x00, 0x0e, 0x13, + 0x00, 0x00, 0x01, 0x64, 0x3a, 0x07, 0x06, 0x02, + 0x18, 0x00, 0x01, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xf8, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x3d, + 0x35, 0x00, 0x00, 0x01, 0xb6, 0x06, 0x03, 0x2d, + 0x33, 0x00, 0x00, 0x00, 0x35, 0x13, 0x00, 0x00, + 0x00, 0x72, 0x09, 0x00, 0x00, 0x00, 0x73, 0x27, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x35, 0x00, 0x00, 0x00, 0x74, 0x06, 0x02, 0x27, + 0x09, 0x00, 0x00, 0x01, 0xb7, 0x27, 0x09, 0x00, + 0x00, 0x01, 0xb8, 0x27, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0x76, 0x37, 0x05, 0x04, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xf8, 0x0c, 0x17, 0x00, 0x00, 0x17, 0x00, 0x01, + 0x09, 0x00, 0x00, 0x00, 0xe1, 0x13, 0x00, 0x00, + 0x01, 0x3d, 0x35, 0x00, 0x00, 0x00, 0xd1, 0x05, + 0x07, 0x0e, 0x17, 0x00, 0x00, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xfa, 0x35, 0x00, 0x00, 0x01, + 0x4f, 0x05, 0x03, 0x0e, 0x17, 0x00, 0x01, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x13, + 0x00, 0x00, 0x01, 0x3d, 0x35, 0x00, 0x00, 0x00, + 0xdb, 0x05, 0x03, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x03, 0x15, 0x02, 0x0f, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xfa, 0x35, 0x00, 0x00, 0x01, + 0x3f, 0x06, 0x03, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x13, 0x00, 0x00, 0x01, 0xb9, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xce, 0x15, 0x02, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xdd, 0x15, 0x02, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xf4, 0x13, 0x00, 0x00, 0x01, + 0xba, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, + 0x13, 0x00, 0x00, 0x01, 0x7d, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x3f, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x02, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xf4, 0x35, 0x00, 0x00, 0x01, 0x4f, + 0x05, 0x03, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x70, + 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x06, 0x13, 0x00, 0x00, 0x01, 0xbb, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xce, 0x15, 0x02, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, + 0x03, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xf4, + 0x15, 0x04, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0xbc, 0x15, 0x05, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0xbd, 0x13, 0x00, 0x00, 0x01, 0xbe, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, 0x13, 0x00, + 0x00, 0x01, 0xbf, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0x3f, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x02, 0x3d, 0x00, 0x02, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xf4, 0x35, 0x00, 0x00, 0x01, + 0x4f, 0x05, 0x03, 0x0e, 0x13, 0x00, 0x00, 0x01, + 0x64, 0x3a, 0x07, 0x06, 0x02, 0x18, 0x00, 0x00, + 0x0e, 0x13, 0x00, 0x00, 0x01, 0x64, 0x3a, 0x07, + 0x06, 0x02, 0x18, 0x00, 0x01, 0x13, 0x00, 0x00, + 0x01, 0xc0, 0x03, 0x33, 0x00, 0x00, 0x00, 0x0d, + 0x04, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xf4, + 0x19, 0x00, 0x00, 0x01, 0xac, 0x03, 0x33, 0x00, + 0x00, 0x00, 0x13, 0x04, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xf4, 0x19, 0x00, 0x00, 0x01, 0xac, + 0x13, 0x00, 0x00, 0x01, 0xad, 0x1e, 0x33, 0x00, + 0x00, 0x00, 0x21, 0x0e, 0x17, 0x00, 0x00, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, + 0x00, 0x00, 0x01, 0x9b, 0x3a, 0x07, 0x06, 0x04, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x1c, 0x0e, 0x17, 0x00, 0x00, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, + 0x13, 0x00, 0x00, 0x01, 0xae, 0x3a, 0x07, 0x06, + 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xbc, + 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, 0x0e, + 0x17, 0x00, 0x01, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0x6f, + 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x0e, 0x17, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0xbd, 0x0a, 0x1f, 0x45, + 0x00, 0x00, 0x00, 0x14, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0xbd, 0x35, 0x00, 0x00, 0x01, + 0x4f, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x0e, 0x17, 0x00, 0x01, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x03, 0x3d, 0x00, 0x02, 0x15, 0x02, 0x2d, + 0x33, 0x00, 0x00, 0x00, 0x7c, 0x0e, 0x18, 0x00, + 0x00, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xbc, + 0x19, 0x00, 0x00, 0x00, 0xce, 0x13, 0x00, 0x00, + 0x00, 0xcf, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x1d, + 0x17, 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xbc, 0x19, 0x00, 0x00, 0x01, 0xa0, 0x19, + 0x00, 0x00, 0x00, 0xd2, 0x27, 0x18, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0xbd, 0x0a, 0x1f, 0x03, 0x45, + 0x00, 0x00, 0x00, 0x13, 0x04, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0xbd, 0x19, 0x00, 0x00, 0x00, + 0xce, 0x13, 0x00, 0x00, 0x00, 0xcf, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x66, 0x17, 0x00, 0x00, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x01, 0xbd, 0x19, 0x00, + 0x00, 0x01, 0xa0, 0x19, 0x00, 0x00, 0x00, 0xd2, + 0x27, 0x18, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, + 0x49, 0x0b, 0x0f, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xbc, 0x35, 0x00, 0x00, 0x01, 0x3f, 0x06, + 0x03, 0x18, 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0xbd, 0x33, 0x00, 0x00, 0x00, 0x2a, + 0x0b, 0x0f, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xbd, 0x35, 0x00, 0x00, 0x01, 0x3f, 0x06, 0x03, + 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, 0x17, 0x00, + 0x00, 0x21, 0x45, 0x00, 0x00, 0x00, 0x0b, 0x17, + 0x00, 0x01, 0x18, 0x00, 0x00, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x17, 0x00, 0x00, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x05, 0x13, 0x00, 0x00, 0x01, 0xc1, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xce, 0x15, + 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, + 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xf4, 0x15, 0x04, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xfa, 0x13, 0x00, 0x00, 0x01, 0xc2, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, 0x13, 0x00, + 0x00, 0x01, 0xc3, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0x3f, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x02, 0x3d, 0x00, 0x03, 0x0e, 0x13, 0x00, 0x00, + 0x01, 0x64, 0x3a, 0x07, 0x06, 0x02, 0x18, 0x00, + 0x00, 0x0e, 0x13, 0x00, 0x00, 0x01, 0x64, 0x3a, + 0x07, 0x06, 0x02, 0x18, 0x00, 0x01, 0x0e, 0x13, + 0x00, 0x00, 0x01, 0x64, 0x3a, 0x07, 0x06, 0x02, + 0x18, 0x00, 0x02, 0x0e, 0x17, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0a, 0x0c, + 0x17, 0x00, 0x01, 0x17, 0x00, 0x02, 0x09, 0x00, + 0x00, 0x00, 0xe1, 0x13, 0x00, 0x00, 0x01, 0x3d, + 0x35, 0x00, 0x00, 0x00, 0xd1, 0x05, 0x07, 0x0e, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xfa, 0x35, + 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, 0x0e, 0x13, + 0x00, 0x00, 0x01, 0x3d, 0x35, 0x00, 0x00, 0x00, + 0xdb, 0x05, 0x03, 0x0e, 0x17, 0x00, 0x01, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xf4, 0x35, 0x00, + 0x00, 0x01, 0x4f, 0x05, 0x03, 0x13, 0x00, 0x00, + 0x01, 0xc0, 0x03, 0x33, 0x00, 0x00, 0x00, 0x0d, + 0x04, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xf4, + 0x19, 0x00, 0x00, 0x01, 0xac, 0x03, 0x33, 0x00, + 0x00, 0x00, 0x13, 0x04, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xf4, 0x19, 0x00, 0x00, 0x01, 0xac, + 0x13, 0x00, 0x00, 0x01, 0xad, 0x1e, 0x33, 0x00, + 0x00, 0x00, 0x21, 0x0e, 0x17, 0x00, 0x00, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, + 0x00, 0x00, 0x01, 0x67, 0x3a, 0x07, 0x06, 0x04, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x1c, 0x0e, 0x17, 0x00, 0x00, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, + 0x13, 0x00, 0x00, 0x01, 0xc4, 0x3a, 0x07, 0x06, + 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x0e, 0x17, 0x00, 0x02, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x03, 0x15, 0x02, 0x2d, 0x33, 0x00, 0x00, + 0x00, 0x2b, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xfa, 0x19, 0x00, 0x00, 0x00, 0xce, 0x13, 0x00, + 0x00, 0x00, 0xcf, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x12, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xfa, + 0x19, 0x00, 0x00, 0x01, 0xa0, 0x19, 0x00, 0x00, + 0x00, 0xd2, 0x38, 0x0e, 0x38, 0x0b, 0x0f, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xfa, 0x35, 0x00, + 0x00, 0x01, 0x3f, 0x06, 0x03, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x05, 0x13, 0x00, 0x00, 0x01, 0xc5, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xce, 0x15, + 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, + 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xf4, 0x15, 0x04, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xfa, 0x13, 0x00, 0x00, 0x01, 0xc6, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, 0x13, 0x00, + 0x00, 0x01, 0xc7, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0x3f, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x02, 0x3d, 0x00, 0x02, 0x0e, 0x13, 0x00, 0x00, + 0x01, 0x64, 0x3a, 0x07, 0x06, 0x02, 0x18, 0x00, + 0x00, 0x0e, 0x13, 0x00, 0x00, 0x01, 0x64, 0x3a, + 0x07, 0x06, 0x02, 0x18, 0x00, 0x01, 0x0e, 0x17, + 0x00, 0x00, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xf4, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, + 0x13, 0x00, 0x00, 0x01, 0xc0, 0x03, 0x33, 0x00, + 0x00, 0x00, 0x0d, 0x04, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xf4, 0x19, 0x00, 0x00, 0x01, 0xac, + 0x03, 0x33, 0x00, 0x00, 0x00, 0x13, 0x04, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xf4, 0x19, 0x00, + 0x00, 0x01, 0xac, 0x13, 0x00, 0x00, 0x01, 0xad, + 0x1e, 0x33, 0x00, 0x00, 0x00, 0x21, 0x0e, 0x17, + 0x00, 0x01, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0x9b, 0x3a, + 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x1c, 0x0e, + 0x17, 0x00, 0x01, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0xae, + 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x0a, 0x0c, 0x17, 0x00, 0x00, + 0x17, 0x00, 0x01, 0x09, 0x00, 0x00, 0x00, 0xe1, + 0x13, 0x00, 0x00, 0x01, 0x3d, 0x35, 0x00, 0x00, + 0x00, 0xd1, 0x05, 0x07, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xfa, 0x35, 0x00, 0x00, 0x01, + 0x4f, 0x05, 0x03, 0x0e, 0x13, 0x00, 0x00, 0x01, + 0x3d, 0x35, 0x00, 0x00, 0x00, 0xdb, 0x05, 0x03, + 0x0e, 0x17, 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, + 0x6f, 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x0e, 0x17, 0x00, 0x01, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x15, 0x02, + 0x2d, 0x33, 0x00, 0x00, 0x00, 0x2b, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xfa, 0x19, 0x00, 0x00, + 0x00, 0xce, 0x13, 0x00, 0x00, 0x00, 0xcf, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x12, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xfa, 0x19, 0x00, 0x00, 0x01, + 0xa0, 0x19, 0x00, 0x00, 0x00, 0xd2, 0x38, 0x0e, + 0x38, 0x0b, 0x0f, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xfa, 0x35, 0x00, 0x00, 0x01, 0x3f, 0x06, + 0x03, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x08, 0x13, + 0x00, 0x00, 0x01, 0xc8, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xce, 0x15, 0x02, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0xc9, 0x15, 0x04, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0xca, 0x15, 0x05, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xcb, 0x15, + 0x06, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xcc, + 0x15, 0x07, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xfa, 0x13, 0x00, 0x00, 0x01, 0xcd, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0x4f, 0x13, 0x00, 0x00, + 0x01, 0xce, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0x3f, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, + 0x3d, 0x00, 0x07, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xc9, 0x33, 0x00, 0x00, 0x01, 0x22, 0x0e, + 0x13, 0x00, 0x00, 0x01, 0x50, 0x35, 0x00, 0x00, + 0x01, 0x51, 0x05, 0x03, 0x0e, 0x18, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xc9, 0x19, 0x00, 0x00, 0x00, 0xd2, 0x20, + 0x45, 0x00, 0x00, 0x01, 0x37, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0xc9, 0x17, 0x00, 0x00, 0x1b, + 0x18, 0x00, 0x01, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x0e, 0x13, 0x00, 0x00, 0x01, 0x50, + 0x35, 0x00, 0x00, 0x01, 0x5b, 0x06, 0x02, 0x13, + 0x00, 0x00, 0x01, 0x5c, 0x17, 0x00, 0x01, 0x19, + 0x00, 0x00, 0x00, 0xf8, 0x09, 0x00, 0x00, 0x00, + 0xe1, 0x13, 0x00, 0x00, 0x01, 0x50, 0x35, 0x00, + 0x00, 0x01, 0x53, 0x05, 0x07, 0x17, 0x00, 0x01, + 0x19, 0x00, 0x00, 0x00, 0xf4, 0x33, 0x00, 0x00, + 0x00, 0xa2, 0x0e, 0x17, 0x00, 0x01, 0x19, 0x00, + 0x00, 0x00, 0xf4, 0x35, 0x00, 0x00, 0x01, 0x4f, + 0x05, 0x03, 0x17, 0x00, 0x01, 0x19, 0x00, 0x00, + 0x00, 0xf8, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x50, + 0x35, 0x00, 0x00, 0x01, 0xab, 0x06, 0x03, 0x18, + 0x00, 0x02, 0x17, 0x00, 0x02, 0x0a, 0x1e, 0x03, + 0x46, 0x00, 0x00, 0x00, 0x0f, 0x04, 0x17, 0x00, + 0x02, 0x19, 0x00, 0x00, 0x01, 0xcf, 0x13, 0x00, + 0x00, 0x01, 0x5c, 0x1f, 0x45, 0x00, 0x00, 0x00, + 0x35, 0x13, 0x00, 0x00, 0x00, 0x72, 0x09, 0x00, + 0x00, 0x00, 0x73, 0x27, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0xd0, 0x35, 0x00, 0x00, 0x00, + 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, 0x01, + 0xd1, 0x27, 0x09, 0x00, 0x00, 0x01, 0xd2, 0x27, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0x76, 0x37, 0x05, + 0x04, 0x36, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x17, + 0x00, 0x02, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, + 0x00, 0x00, 0x01, 0x63, 0x3a, 0x07, 0x06, 0x04, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x0f, + 0x27, 0x18, 0x00, 0x00, 0x36, 0xff, 0xff, 0xfe, + 0xef, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xca, + 0x0a, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x2d, 0x0e, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xca, 0x35, + 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0x70, 0x3a, 0x07, 0x06, 0x03, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x13, 0x00, 0x00, + 0x01, 0x64, 0x3a, 0x07, 0x06, 0x02, 0x18, 0x00, + 0x00, 0x0e, 0x13, 0x00, 0x00, 0x01, 0x64, 0x3a, + 0x07, 0x06, 0x02, 0x18, 0x00, 0x01, 0x0e, 0x13, + 0x00, 0x00, 0x01, 0x64, 0x3a, 0x07, 0x06, 0x02, + 0x18, 0x00, 0x02, 0x0e, 0x17, 0x00, 0x00, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0c, 0x18, + 0x00, 0x03, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xcb, 0x0a, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x4e, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xcb, + 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, 0x13, + 0x00, 0x00, 0x01, 0xc0, 0x03, 0x33, 0x00, 0x00, + 0x00, 0x0d, 0x04, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xcb, 0x19, 0x00, 0x00, 0x01, 0xac, 0x03, + 0x33, 0x00, 0x00, 0x00, 0x13, 0x04, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0xcb, 0x19, 0x00, 0x00, + 0x01, 0xac, 0x13, 0x00, 0x00, 0x01, 0xad, 0x1e, + 0x33, 0x00, 0x00, 0x00, 0x2a, 0x0b, 0x18, 0x00, + 0x03, 0x36, 0x00, 0x00, 0x00, 0x21, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0xaf, 0x3a, 0x07, 0x06, 0x03, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x13, + 0x00, 0x00, 0x01, 0xc0, 0x18, 0x00, 0x03, 0x17, + 0x00, 0x03, 0x33, 0x00, 0x00, 0x00, 0x21, 0x0e, + 0x17, 0x00, 0x02, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0x9b, + 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x1c, + 0x0e, 0x17, 0x00, 0x02, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, + 0xae, 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x0a, 0x0c, 0x17, 0x00, + 0x01, 0x17, 0x00, 0x02, 0x09, 0x00, 0x00, 0x00, + 0xe1, 0x13, 0x00, 0x00, 0x01, 0x3d, 0x35, 0x00, + 0x00, 0x00, 0xd1, 0x05, 0x07, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xfa, 0x35, 0x00, 0x00, + 0x01, 0x4f, 0x05, 0x03, 0x0e, 0x13, 0x00, 0x00, + 0x01, 0x3d, 0x35, 0x00, 0x00, 0x00, 0xdb, 0x05, + 0x03, 0x0e, 0x17, 0x00, 0x01, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0xcc, 0x0a, 0x1f, 0x45, 0x00, 0x00, + 0x00, 0x2d, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xcc, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, + 0x03, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x70, 0x3a, + 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x0e, + 0x17, 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0x6f, + 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x0e, 0x17, 0x00, 0x02, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0xc9, 0x33, 0x00, 0x00, + 0x00, 0x12, 0x0e, 0x13, 0x00, 0x00, 0x01, 0x50, + 0x35, 0x00, 0x00, 0x01, 0x73, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x01, 0x0e, 0x18, + 0x00, 0x00, 0x15, 0x02, 0x33, 0x00, 0x00, 0x00, + 0x40, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xc9, + 0x33, 0x00, 0x00, 0x00, 0x18, 0x17, 0x00, 0x00, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xc9, 0x19, + 0x00, 0x00, 0x00, 0xd2, 0x27, 0x18, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, + 0x0b, 0x0f, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xfa, 0x35, 0x00, 0x00, 0x01, 0x3f, 0x06, 0x03, + 0x27, 0x18, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, + 0x34, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xfa, + 0x19, 0x00, 0x00, 0x00, 0xce, 0x13, 0x00, 0x00, + 0x00, 0xcf, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x1d, + 0x17, 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xfa, 0x19, 0x00, 0x00, 0x01, 0xa0, 0x19, + 0x00, 0x00, 0x00, 0xd2, 0x27, 0x18, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x07, 0x13, 0x00, + 0x00, 0x01, 0xd3, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xce, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0xc9, 0x15, 0x04, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0xca, 0x15, 0x05, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0xcb, 0x15, 0x06, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xfa, 0x13, + 0x00, 0x00, 0x01, 0xd4, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0x4f, 0x13, 0x00, 0x00, 0x01, 0xd5, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x3f, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x3d, 0x00, + 0x06, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xc9, + 0x33, 0x00, 0x00, 0x00, 0x8f, 0x0e, 0x13, 0x00, + 0x00, 0x01, 0x50, 0x35, 0x00, 0x00, 0x01, 0x51, + 0x05, 0x03, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xc9, 0x0e, 0x1b, 0x18, 0x00, 0x01, 0x0e, 0x13, + 0x00, 0x00, 0x01, 0x50, 0x35, 0x00, 0x00, 0x01, + 0x5b, 0x06, 0x02, 0x18, 0x00, 0x00, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x17, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x01, 0x5c, 0x17, 0x00, 0x01, + 0x19, 0x00, 0x00, 0x00, 0xf8, 0x09, 0x00, 0x00, + 0x00, 0xe1, 0x13, 0x00, 0x00, 0x01, 0x50, 0x35, + 0x00, 0x00, 0x01, 0x53, 0x05, 0x07, 0x17, 0x00, + 0x01, 0x19, 0x00, 0x00, 0x00, 0xf4, 0x33, 0x00, + 0x00, 0x00, 0x31, 0x0e, 0x17, 0x00, 0x01, 0x19, + 0x00, 0x00, 0x00, 0xf4, 0x35, 0x00, 0x00, 0x01, + 0x4f, 0x05, 0x03, 0x0e, 0x17, 0x00, 0x00, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, + 0x00, 0x00, 0x01, 0x63, 0x3a, 0x07, 0x06, 0x04, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0xcb, 0x35, 0x00, 0x00, 0x01, + 0x4f, 0x05, 0x03, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, + 0x65, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, + 0x01, 0x5d, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0x61, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0x5d, 0x3a, 0x07, 0x06, 0x03, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, + 0x13, 0x00, 0x00, 0x01, 0x64, 0x3a, 0x07, 0x06, + 0x02, 0x18, 0x00, 0x01, 0x0e, 0x13, 0x00, 0x00, + 0x01, 0x64, 0x3a, 0x07, 0x06, 0x02, 0x18, 0x00, + 0x02, 0x0e, 0x13, 0x00, 0x00, 0x01, 0x64, 0x3a, + 0x07, 0x06, 0x02, 0x18, 0x00, 0x03, 0x0e, 0x13, + 0x00, 0x00, 0x01, 0x64, 0x3a, 0x07, 0x06, 0x02, + 0x18, 0x00, 0x04, 0x0e, 0x17, 0x00, 0x01, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0xd6, 0x3a, 0x07, 0x06, 0x03, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, + 0x17, 0x00, 0x03, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0x9b, + 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xc9, 0x33, 0x00, 0x00, 0x00, 0x21, 0x0e, + 0x17, 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0x63, + 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x10, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xca, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0xd7, 0x37, 0x05, 0x04, + 0x0a, 0x0c, 0x17, 0x00, 0x02, 0x17, 0x00, 0x04, + 0x09, 0x00, 0x00, 0x00, 0xe1, 0x13, 0x00, 0x00, + 0x01, 0x3d, 0x35, 0x00, 0x00, 0x00, 0xd1, 0x05, + 0x07, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xfa, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, + 0x0e, 0x13, 0x00, 0x00, 0x01, 0x3d, 0x35, 0x00, + 0x00, 0x00, 0xdb, 0x05, 0x03, 0x0e, 0x17, 0x00, + 0x02, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x13, 0x00, 0x00, 0x01, 0x69, 0x3a, 0x07, + 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, 0xd8, 0x3a, + 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x65, + 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x0e, 0x11, 0x2b, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, + 0x00, 0x01, 0xd9, 0x3a, 0x07, 0x06, 0x04, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0x65, 0x3a, 0x07, 0x06, 0x03, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, + 0x12, 0x00, 0x00, 0x00, 0x04, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, + 0x01, 0xd9, 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0x61, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x17, + 0x00, 0x01, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0x6f, 0x3a, + 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x0e, 0x17, 0x00, 0x03, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0x70, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x17, + 0x00, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x0e, 0x10, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0x6d, + 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xc9, 0x33, 0x00, 0x00, 0x00, 0x12, 0x0e, + 0x13, 0x00, 0x00, 0x01, 0x50, 0x35, 0x00, 0x00, + 0x01, 0x73, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, + 0x3d, 0x00, 0x01, 0x0e, 0x18, 0x00, 0x00, 0x15, + 0x02, 0x33, 0x00, 0x00, 0x00, 0x35, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0xc9, 0x33, 0x00, 0x00, + 0x00, 0x0d, 0x17, 0x00, 0x00, 0x0f, 0x27, 0x18, + 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x0b, 0x0f, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xfa, 0x35, 0x00, 0x00, 0x01, 0x3f, + 0x06, 0x03, 0x27, 0x18, 0x00, 0x00, 0x36, 0x00, + 0x00, 0x00, 0x34, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xfa, 0x19, 0x00, 0x00, 0x00, 0xce, 0x13, + 0x00, 0x00, 0x00, 0xcf, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x1d, 0x17, 0x00, 0x00, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xfa, 0x19, 0x00, 0x00, 0x01, + 0xa0, 0x19, 0x00, 0x00, 0x00, 0xd2, 0x27, 0x18, + 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x04, + 0x13, 0x00, 0x00, 0x00, 0xcf, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xce, 0x15, 0x02, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x0c, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xd0, 0x15, 0x03, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0xa0, 0x13, 0x00, + 0x00, 0x01, 0xda, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0x4f, 0x13, 0x00, 0x00, 0x01, 0xdb, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0x3f, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x02, 0x3d, 0x00, 0x03, + 0x0e, 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x01, 0xa0, 0x19, 0x00, + 0x00, 0x00, 0xd2, 0x20, 0x45, 0x00, 0x00, 0x01, + 0x3a, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xa0, + 0x17, 0x00, 0x00, 0x1b, 0x18, 0x00, 0x02, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xd0, 0x2d, 0x33, + 0x00, 0x00, 0x00, 0x37, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0e, 0x13, 0x00, 0x00, 0x01, + 0x50, 0x35, 0x00, 0x00, 0x01, 0x5b, 0x06, 0x02, + 0x13, 0x00, 0x00, 0x01, 0x5c, 0x17, 0x00, 0x02, + 0x19, 0x00, 0x00, 0x00, 0xf8, 0x09, 0x00, 0x00, + 0x00, 0xe1, 0x13, 0x00, 0x00, 0x01, 0x50, 0x35, + 0x00, 0x00, 0x01, 0x53, 0x05, 0x07, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x02, 0x19, 0x00, + 0x00, 0x00, 0xf4, 0x33, 0x00, 0x00, 0x00, 0xce, + 0x0e, 0x17, 0x00, 0x02, 0x19, 0x00, 0x00, 0x00, + 0xf4, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xd0, 0x33, + 0x00, 0x00, 0x00, 0x26, 0x0e, 0x17, 0x00, 0x02, + 0x19, 0x00, 0x00, 0x00, 0xf8, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, + 0x01, 0xdc, 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, + 0x00, 0x8c, 0x17, 0x00, 0x02, 0x19, 0x00, 0x00, + 0x00, 0xf8, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x50, + 0x35, 0x00, 0x00, 0x01, 0xab, 0x06, 0x03, 0x18, + 0x00, 0x01, 0x17, 0x00, 0x01, 0x0a, 0x1e, 0x03, + 0x46, 0x00, 0x00, 0x00, 0x0f, 0x04, 0x17, 0x00, + 0x01, 0x19, 0x00, 0x00, 0x01, 0xcf, 0x13, 0x00, + 0x00, 0x01, 0x5c, 0x1f, 0x45, 0x00, 0x00, 0x00, + 0x2f, 0x13, 0x00, 0x00, 0x00, 0x72, 0x09, 0x00, + 0x00, 0x00, 0x73, 0x27, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x35, 0x00, 0x00, 0x00, + 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, 0x01, + 0xdd, 0x27, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x76, + 0x37, 0x05, 0x04, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x0e, 0x17, 0x00, 0x01, 0x19, 0x00, 0x00, 0x00, + 0xe7, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x10, 0x13, 0x00, 0x00, 0x01, 0x63, 0x3a, 0x07, + 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, + 0x00, 0x0f, 0x27, 0x18, 0x00, 0x00, 0x36, 0xff, + 0xff, 0xfe, 0xb1, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x03, 0x15, 0x02, 0x2d, 0x33, 0x00, 0x00, + 0x00, 0x1b, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xd0, 0x33, 0x00, 0x00, 0x00, 0x02, 0x0e, 0x38, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xa0, 0x19, + 0x00, 0x00, 0x00, 0xd2, 0x38, 0x0e, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x04, 0x15, 0x02, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xf8, 0x15, 0x03, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xf4, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x13, 0x00, 0x00, + 0x00, 0xc2, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xbd, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xdd, 0x13, 0x00, 0x00, 0x01, 0xde, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x02, 0x0e, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, + 0x00, 0x00, 0x01, 0x56, 0x3a, 0x07, 0x06, 0x04, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x04, 0x13, 0x00, + 0x00, 0x00, 0xc3, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xbd, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xe7, 0x13, 0x00, 0x00, 0x01, + 0xdf, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x15, + 0x00, 0x0f, 0x13, 0x00, 0x00, 0x01, 0xe0, 0x37, + 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x04, 0x13, 0x00, 0x00, 0x00, 0xc4, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xbd, 0x13, 0x00, 0x00, + 0x01, 0xe1, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0xac, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xe7, 0x13, 0x00, 0x00, 0x01, 0xe2, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, + 0x00, 0x01, 0xe3, 0x3a, 0x07, 0x06, 0x04, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x04, 0x13, 0x00, 0x00, + 0x00, 0xc5, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xbd, 0x13, 0x00, 0x00, 0x01, 0xe4, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0xac, 0x15, 0x02, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, 0x03, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xe7, 0x13, + 0x00, 0x00, 0x01, 0xe5, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0x4f, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x02, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xe7, 0x0e, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x1e, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x13, 0x00, 0x00, 0x01, 0x5d, 0x3a, 0x07, + 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x00, 0xa4, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xe7, 0x0f, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, + 0x01, 0x69, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, + 0x00, 0x78, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xe7, 0x10, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x1e, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x13, 0x00, 0x00, 0x01, 0xe6, 0x3a, 0x07, + 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x00, 0x4c, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xe7, 0x11, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, + 0x01, 0xe7, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, + 0x00, 0x20, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xe7, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0xe8, 0x3a, + 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x04, 0x13, 0x00, 0x00, 0x00, 0xc6, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xbd, 0x13, 0x00, 0x00, + 0x01, 0xe9, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0xac, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xe7, 0x13, 0x00, 0x00, 0x01, 0xea, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, + 0x00, 0x01, 0xe3, 0x3a, 0x07, 0x06, 0x04, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x04, 0x13, 0x00, 0x00, + 0x00, 0xc7, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xbd, 0x13, 0x00, 0x00, 0x01, 0xeb, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0xac, 0x15, 0x02, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, 0x03, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xe7, 0x13, + 0x00, 0x00, 0x01, 0xec, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0x4f, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x02, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xe7, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0xe3, 0x3a, + 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x04, 0x13, 0x00, 0x00, 0x00, 0xc8, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xbd, 0x13, 0x00, 0x00, + 0x01, 0xed, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0xac, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xee, 0x13, 0x00, 0x00, 0x01, 0xef, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x3d, 0x00, + 0x01, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xee, + 0x19, 0x00, 0x00, 0x00, 0xd2, 0x0f, 0x26, 0x18, + 0x00, 0x00, 0x17, 0x00, 0x00, 0x0e, 0x23, 0x45, + 0x00, 0x00, 0x00, 0x4e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0xee, 0x17, 0x00, 0x00, 0x1b, 0x33, + 0x00, 0x00, 0x00, 0x18, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0xee, 0x17, 0x00, 0x00, 0x1b, + 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x19, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, + 0x01, 0x71, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x17, 0x00, 0x00, + 0x0f, 0x26, 0x18, 0x00, 0x00, 0x36, 0xff, 0xff, + 0xff, 0xa8, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xee, 0x19, 0x00, 0x00, 0x00, 0xd2, 0x2b, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, + 0x13, 0x00, 0x00, 0x01, 0xe3, 0x3a, 0x07, 0x06, + 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x0e, 0x09, 0x00, 0x00, 0x01, 0x5e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, + 0x00, 0x01, 0x5f, 0x3a, 0x07, 0x06, 0x04, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0x60, 0x3a, 0x07, 0x06, 0x03, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0x61, 0x3a, 0x07, 0x06, + 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xee, + 0x19, 0x00, 0x00, 0x00, 0xd2, 0x10, 0x27, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, + 0x00, 0x00, 0x01, 0x62, 0x3a, 0x07, 0x06, 0x04, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x04, 0x13, 0x00, + 0x00, 0x01, 0xf0, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xbd, 0x13, 0x00, 0x00, 0x01, 0xf1, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0xac, 0x15, 0x02, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, + 0x03, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xee, + 0x13, 0x00, 0x00, 0x01, 0xf2, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x4f, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x02, 0x3d, 0x00, 0x02, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0x5d, 0x3a, 0x07, 0x06, 0x03, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, + 0x09, 0x00, 0x00, 0x01, 0xf3, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, + 0x01, 0x5f, 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0x60, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0x61, 0x3a, 0x07, 0x06, 0x03, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, + 0x10, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x10, 0x13, 0x00, 0x00, 0x01, 0x62, 0x3a, 0x07, + 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x0e, 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xee, 0x19, + 0x00, 0x00, 0x00, 0xd2, 0x20, 0x45, 0x00, 0x00, + 0x01, 0xd5, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xee, 0x17, 0x00, 0x00, 0x1b, 0x18, 0x00, 0x01, + 0x0e, 0x17, 0x00, 0x01, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x65, 0x3a, + 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x0e, 0x17, 0x00, 0x01, 0x19, 0x00, + 0x00, 0x00, 0xf4, 0x35, 0x00, 0x00, 0x01, 0x4f, + 0x05, 0x03, 0x0e, 0x17, 0x00, 0x01, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, + 0x61, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x17, 0x00, 0x01, 0x19, + 0x00, 0x00, 0x01, 0x39, 0x03, 0x13, 0x00, 0x00, + 0x00, 0x6f, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x27, + 0x0e, 0x17, 0x00, 0x01, 0x19, 0x00, 0x00, 0x00, + 0xf8, 0x17, 0x00, 0x01, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0x7e, 0x3a, + 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x36, 0x00, 0x00, 0x01, 0x3a, 0x03, + 0x13, 0x00, 0x00, 0x00, 0x08, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x41, 0x0e, 0x17, 0x00, 0x01, 0x19, + 0x00, 0x00, 0x00, 0xf8, 0x17, 0x00, 0x01, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, + 0x01, 0xe3, 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x17, 0x00, + 0x01, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0xf4, 0x3a, 0x07, 0x06, 0x03, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0xed, 0x03, 0x13, 0x00, 0x00, + 0x00, 0x77, 0x1e, 0x45, 0x00, 0x00, 0x00, 0xe1, + 0x17, 0x00, 0x01, 0x19, 0x00, 0x00, 0x00, 0xf8, + 0x03, 0x0e, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x1f, + 0x0e, 0x17, 0x00, 0x01, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x5d, 0x3a, + 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x97, 0x03, + 0x0f, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x1f, 0x0e, + 0x17, 0x00, 0x01, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x13, 0x00, 0x00, 0x01, 0x69, 0x3a, 0x07, + 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x00, 0x70, 0x03, 0x10, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x1f, 0x0e, 0x17, + 0x00, 0x01, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0xe6, 0x3a, 0x07, 0x06, + 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x36, 0x00, 0x00, 0x00, 0x49, 0x03, 0x11, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x1f, 0x0e, 0x17, 0x00, + 0x01, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0xe7, 0x3a, 0x07, 0x06, 0x03, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x22, 0x0e, 0x17, 0x00, 0x01, + 0x19, 0x00, 0x00, 0x00, 0xf8, 0x17, 0x00, 0x01, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, + 0x00, 0x01, 0xe8, 0x3a, 0x07, 0x06, 0x04, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x04, 0x0e, + 0x17, 0x00, 0x01, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x13, 0x00, 0x00, 0x01, 0xf4, 0x3a, 0x07, + 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x04, 0x17, 0x00, 0x00, 0x0f, 0x27, 0x18, + 0x00, 0x00, 0x36, 0xff, 0xff, 0xfe, 0x16, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x13, 0x00, + 0x00, 0x00, 0xc9, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xbd, 0x13, 0x00, 0x00, 0x01, 0xf5, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0xac, 0x15, 0x02, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x13, + 0x00, 0x00, 0x01, 0xf6, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0x4f, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x02, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, 0xf7, + 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x03, 0x13, 0x00, 0x00, 0x00, 0xca, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xbd, 0x13, 0x00, + 0x00, 0x01, 0xad, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0xac, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xdd, 0x13, 0x00, 0x00, 0x01, 0xf8, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0xaf, 0x3a, 0x07, 0x06, 0x03, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x13, 0x00, + 0x00, 0x00, 0xcb, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xbd, 0x13, 0x00, 0x00, 0x01, 0xad, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0xac, 0x15, 0x02, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x13, + 0x00, 0x00, 0x01, 0xf9, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0x4f, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x02, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, 0xa9, + 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x06, 0x13, 0x00, 0x00, 0x01, 0xfa, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xbd, 0x15, 0x02, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, + 0x03, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, + 0x15, 0x04, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0xfc, 0x15, 0x05, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0xfd, 0x13, 0x00, 0x00, 0x01, 0xfe, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x02, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0xfc, 0x35, 0x00, 0x00, + 0x01, 0x4f, 0x05, 0x03, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0xfd, 0x35, 0x00, 0x00, 0x01, + 0x4f, 0x05, 0x03, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xfb, 0x12, 0x00, 0x00, 0x00, 0x2a, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0xff, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x49, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xfb, 0x12, 0x00, 0x00, 0x00, 0x2f, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, + 0x00, 0x02, 0x00, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x19, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x02, + 0x01, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x06, 0x13, 0x00, 0x00, 0x02, 0x02, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xbd, 0x15, + 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, + 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0xfb, 0x15, 0x04, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0xfc, 0x15, 0x05, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xfd, 0x13, 0x00, 0x00, 0x02, 0x03, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, 0x13, + 0x00, 0x00, 0x02, 0x04, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0x0b, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x02, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xfc, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, + 0x03, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xfd, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfb, 0x12, + 0x00, 0x00, 0x00, 0x2b, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x1e, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, 0xd8, + 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x19, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x13, 0x00, 0x00, 0x02, 0x05, 0x3a, 0x07, + 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfc, 0x19, + 0x00, 0x00, 0x01, 0x0b, 0x33, 0x00, 0x00, 0x00, + 0x1b, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xfc, 0x35, 0x00, 0x00, 0x01, 0x0b, 0x06, 0x02, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfc, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0xfd, 0x19, 0x00, 0x00, 0x01, 0x0b, + 0x33, 0x00, 0x00, 0x00, 0x1b, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0xfd, 0x35, 0x00, 0x00, + 0x01, 0x0b, 0x06, 0x02, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xfd, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfc, 0x19, + 0x00, 0x00, 0x01, 0xac, 0x03, 0x33, 0x00, 0x00, + 0x00, 0x0d, 0x04, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xfd, 0x19, 0x00, 0x00, 0x01, 0xac, 0x03, + 0x33, 0x00, 0x00, 0x00, 0x1a, 0x04, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0xfc, 0x19, 0x00, 0x00, + 0x01, 0xac, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xfd, 0x19, 0x00, 0x00, 0x01, 0xac, 0x1e, 0x33, + 0x00, 0x00, 0x01, 0x29, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0xfc, 0x19, 0x00, 0x00, 0x01, 0xac, + 0x03, 0x13, 0x00, 0x00, 0x01, 0xe4, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x5b, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0xfb, 0x12, 0x00, 0x00, 0x00, 0x2b, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x1e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0xfc, 0x19, 0x00, 0x00, + 0x00, 0xe7, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xfd, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x27, 0x36, + 0x00, 0x00, 0x00, 0x19, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0xfc, 0x19, 0x00, 0x00, 0x00, 0xe7, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfd, 0x19, + 0x00, 0x00, 0x00, 0xe7, 0x26, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, + 0x01, 0x31, 0x3a, 0x07, 0x06, 0x04, 0x38, 0x03, + 0x13, 0x00, 0x00, 0x01, 0xe1, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x5b, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xfb, 0x12, 0x00, 0x00, 0x00, 0x2b, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x1e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0xfc, 0x19, 0x00, 0x00, 0x00, + 0xe7, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfd, + 0x19, 0x00, 0x00, 0x00, 0xe7, 0x27, 0x36, 0x00, + 0x00, 0x00, 0x19, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xfc, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x01, 0xfd, 0x19, 0x00, + 0x00, 0x00, 0xe7, 0x26, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, + 0x30, 0x3a, 0x07, 0x06, 0x04, 0x38, 0x03, 0x13, + 0x00, 0x00, 0x01, 0xe9, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x3d, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xfb, 0x12, 0x00, 0x00, 0x00, 0x2b, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x2b, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0xfc, 0x19, 0x00, 0x00, 0x00, 0xe7, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfd, 0x19, + 0x00, 0x00, 0x00, 0xe7, 0x27, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, + 0x01, 0x32, 0x3a, 0x07, 0x06, 0x04, 0x38, 0x04, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x06, 0x13, 0x00, 0x00, + 0x02, 0x06, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xbd, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xfb, 0x15, 0x04, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0xfc, 0x15, 0x05, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0xfd, 0x13, 0x00, 0x00, + 0x02, 0x07, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0x4f, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfc, + 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, 0x0e, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfd, 0x35, + 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, + 0x00, 0x1c, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x1e, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x13, 0x00, 0x00, 0x02, 0x08, 0x3a, 0x07, + 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x00, 0x49, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, + 0x00, 0x20, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x1e, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x13, 0x00, 0x00, 0x02, 0x09, 0x3a, 0x07, + 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x00, 0x19, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, + 0x00, 0x00, 0x02, 0x0a, 0x3a, 0x07, 0x06, 0x03, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x06, 0x13, 0x00, + 0x00, 0x02, 0x0b, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xbd, 0x13, 0x00, 0x00, 0x01, 0xad, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0xac, 0x15, 0x02, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, + 0x03, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, + 0x15, 0x04, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0xfc, 0x15, 0x05, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0xfd, 0x13, 0x00, 0x00, 0x02, 0x0c, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x02, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0xfc, 0x35, 0x00, 0x00, + 0x01, 0x4f, 0x05, 0x03, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0xfd, 0x35, 0x00, 0x00, 0x01, + 0x4f, 0x05, 0x03, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xfb, 0x12, 0x00, 0x00, 0x00, 0x3c, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, + 0x00, 0x02, 0x0d, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x79, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xfb, 0x12, 0x00, 0x00, 0x00, 0x3e, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, + 0x00, 0x02, 0x0e, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x49, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xfb, 0x13, 0x00, 0x00, 0x00, 0x0d, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, + 0x00, 0x02, 0x0f, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x19, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, + 0x66, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x06, 0x13, 0x00, 0x00, 0x02, 0x10, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xbd, 0x13, + 0x00, 0x00, 0x01, 0xad, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xac, 0x15, 0x02, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, 0x04, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfc, 0x15, 0x05, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfd, 0x13, + 0x00, 0x00, 0x02, 0x11, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0x4f, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x02, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xfc, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, + 0x03, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xfd, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfb, 0x03, + 0x13, 0x00, 0x00, 0x00, 0x0a, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, + 0x9a, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, + 0x8c, 0x03, 0x13, 0x00, 0x00, 0x00, 0x0c, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, + 0x00, 0x02, 0x12, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x62, 0x03, 0x13, 0x00, 0x00, 0x00, + 0x09, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x1e, 0x0e, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, + 0x13, 0x00, 0x00, 0x02, 0x13, 0x3a, 0x07, 0x06, + 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x36, 0x00, 0x00, 0x00, 0x38, 0x03, 0x13, 0x00, + 0x00, 0x00, 0x0b, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x1e, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x02, 0x14, 0x3a, + 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x0e, 0x09, + 0x00, 0x00, 0x02, 0x15, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0x76, 0x37, 0x05, 0x04, 0x04, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x05, 0x13, 0x00, 0x00, + 0x02, 0x16, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xbd, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xfc, 0x15, 0x04, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0xfd, 0x13, 0x00, 0x00, 0x02, + 0x17, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x0e, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfc, 0x35, + 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x01, 0xfd, 0x35, 0x00, + 0x00, 0x01, 0x4f, 0x05, 0x03, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, + 0x00, 0x02, 0x18, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x05, 0x13, 0x00, 0x00, + 0x02, 0x16, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xbd, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xfc, 0x15, 0x04, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0xfd, 0x13, 0x00, 0x00, 0x02, + 0x19, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x0e, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfc, 0x35, + 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x01, 0xfd, 0x35, 0x00, + 0x00, 0x01, 0x4f, 0x05, 0x03, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, + 0x00, 0x02, 0x1a, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x05, 0x13, 0x00, 0x00, + 0x02, 0x16, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xbd, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xfc, 0x15, 0x04, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0xfd, 0x13, 0x00, 0x00, 0x02, + 0x1b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x0e, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfc, 0x35, + 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x01, 0xfd, 0x35, 0x00, + 0x00, 0x01, 0x4f, 0x05, 0x03, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, + 0x00, 0x02, 0x1c, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x05, 0x13, 0x00, 0x00, + 0x02, 0x1d, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xbd, 0x15, 0x03, 0x19, 0x00, 0x00, 0x01, 0xac, + 0x03, 0x33, 0x00, 0x00, 0x00, 0x08, 0x04, 0x15, + 0x04, 0x19, 0x00, 0x00, 0x01, 0xac, 0x03, 0x33, + 0x00, 0x00, 0x00, 0x0e, 0x04, 0x15, 0x03, 0x19, + 0x00, 0x00, 0x01, 0xac, 0x13, 0x00, 0x00, 0x01, + 0xad, 0x1e, 0x03, 0x33, 0x00, 0x00, 0x00, 0x0e, + 0x04, 0x15, 0x04, 0x19, 0x00, 0x00, 0x01, 0xac, + 0x13, 0x00, 0x00, 0x01, 0xad, 0x1e, 0x33, 0x00, + 0x00, 0x00, 0x11, 0x13, 0x00, 0x00, 0x01, 0xad, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xac, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x15, 0x02, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, 0x03, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfc, 0x15, 0x04, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfd, 0x13, + 0x00, 0x00, 0x02, 0x1e, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0x4f, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x02, 0x3d, 0x00, 0x01, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0xfc, 0x35, 0x00, 0x00, + 0x01, 0x4f, 0x05, 0x03, 0x0e, 0x13, 0x00, 0x00, + 0x01, 0x64, 0x3a, 0x07, 0x06, 0x02, 0x18, 0x00, + 0x00, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x65, 0x3a, + 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x13, 0x00, 0x00, 0x01, 0xc0, 0x03, + 0x33, 0x00, 0x00, 0x00, 0x0d, 0x04, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0xfc, 0x19, 0x00, 0x00, + 0x01, 0xac, 0x03, 0x33, 0x00, 0x00, 0x00, 0x13, + 0x04, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfc, + 0x19, 0x00, 0x00, 0x01, 0xac, 0x13, 0x00, 0x00, + 0x01, 0xad, 0x1e, 0x33, 0x00, 0x00, 0x00, 0x21, + 0x0e, 0x17, 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, + 0x9b, 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, + 0x1c, 0x0e, 0x17, 0x00, 0x00, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, + 0x01, 0xae, 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0x70, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x01, 0xfd, 0x35, 0x00, + 0x00, 0x01, 0x4f, 0x05, 0x03, 0x0e, 0x17, 0x00, + 0x00, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x05, 0x13, + 0x00, 0x00, 0x02, 0x1d, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xbd, 0x15, 0x03, 0x19, 0x00, 0x00, + 0x01, 0xac, 0x03, 0x33, 0x00, 0x00, 0x00, 0x08, + 0x04, 0x15, 0x04, 0x19, 0x00, 0x00, 0x01, 0xac, + 0x03, 0x33, 0x00, 0x00, 0x00, 0x0e, 0x04, 0x15, + 0x03, 0x19, 0x00, 0x00, 0x01, 0xac, 0x13, 0x00, + 0x00, 0x01, 0xad, 0x1e, 0x03, 0x33, 0x00, 0x00, + 0x00, 0x0e, 0x04, 0x15, 0x04, 0x19, 0x00, 0x00, + 0x01, 0xac, 0x13, 0x00, 0x00, 0x01, 0xad, 0x1e, + 0x33, 0x00, 0x00, 0x00, 0x11, 0x13, 0x00, 0x00, + 0x01, 0xad, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0xac, 0x36, 0x00, 0x00, 0x00, 0x00, 0x15, 0x02, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, + 0x03, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfc, + 0x15, 0x04, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0xfd, 0x13, 0x00, 0x00, 0x02, 0x1f, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0x4f, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x02, 0x3d, 0x00, 0x01, 0x0e, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfc, 0x35, + 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, 0x0e, 0x13, + 0x00, 0x00, 0x01, 0x64, 0x3a, 0x07, 0x06, 0x02, + 0x18, 0x00, 0x00, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, + 0x65, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x13, 0x00, 0x00, 0x01, + 0xc0, 0x03, 0x33, 0x00, 0x00, 0x00, 0x0d, 0x04, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfc, 0x19, + 0x00, 0x00, 0x01, 0xac, 0x03, 0x33, 0x00, 0x00, + 0x00, 0x13, 0x04, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xfc, 0x19, 0x00, 0x00, 0x01, 0xac, 0x13, + 0x00, 0x00, 0x01, 0xad, 0x1e, 0x33, 0x00, 0x00, + 0x00, 0x21, 0x0e, 0x17, 0x00, 0x00, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, + 0x00, 0x01, 0x67, 0x3a, 0x07, 0x06, 0x04, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x1c, 0x0e, 0x17, 0x00, 0x00, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, + 0x00, 0x00, 0x01, 0xc4, 0x3a, 0x07, 0x06, 0x04, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0x70, 0x3a, 0x07, 0x06, + 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfd, + 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, 0x0e, + 0x17, 0x00, 0x00, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x05, 0x13, 0x00, 0x00, 0x00, 0xc1, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xbd, 0x15, 0x02, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, 0x03, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xf4, 0x15, + 0x04, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4b, + 0x13, 0x00, 0x00, 0x02, 0x20, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x4f, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x02, 0x3d, 0x00, 0x01, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x4b, 0x33, 0x00, 0x00, + 0x01, 0x29, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x4b, 0x19, 0x00, 0x00, 0x00, 0xd2, 0x0f, 0x26, + 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, 0x0e, 0x23, + 0x45, 0x00, 0x00, 0x00, 0x20, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x4b, 0x17, 0x00, 0x00, + 0x1b, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, + 0x17, 0x00, 0x00, 0x0f, 0x26, 0x18, 0x00, 0x00, + 0x36, 0xff, 0xff, 0xff, 0xd6, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0x4b, 0x19, 0x00, 0x00, 0x00, + 0xd2, 0x0e, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x1e, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x13, 0x00, 0x00, 0x01, 0x5d, 0x3a, 0x07, + 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x00, 0xd6, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x4b, 0x19, 0x00, 0x00, + 0x00, 0xd2, 0x0f, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x1e, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x69, 0x3a, + 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0xa5, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x01, 0x4b, 0x19, 0x00, + 0x00, 0x00, 0xd2, 0x10, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x1e, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, 0xe6, + 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x74, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0x4b, 0x19, + 0x00, 0x00, 0x00, 0xd2, 0x11, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, + 0xe7, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, + 0x43, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x4b, 0x19, 0x00, 0x00, 0x00, 0xd2, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, + 0x00, 0x01, 0xe3, 0x3a, 0x07, 0x06, 0x04, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x19, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, + 0x5d, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xf4, 0x35, 0x00, 0x00, 0x01, + 0x4f, 0x05, 0x03, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, + 0x60, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, + 0x01, 0x61, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x4b, 0x33, 0x00, 0x00, + 0x00, 0x11, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x4b, 0x19, 0x00, 0x00, 0x00, 0xd2, 0x36, 0x00, + 0x00, 0x00, 0x01, 0x0e, 0x10, 0x27, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, + 0x00, 0x01, 0x62, 0x3a, 0x07, 0x06, 0x04, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x05, 0x13, 0x00, 0x00, + 0x00, 0xbf, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xbd, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xf4, 0x15, 0x04, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xf8, 0x13, 0x00, 0x00, 0x02, + 0x21, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x15, + 0x00, 0x0f, 0x13, 0x00, 0x00, 0x01, 0xe0, 0x37, + 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x05, 0x13, 0x00, 0x00, 0x00, 0xc0, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xbd, 0x15, 0x02, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, 0x03, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xca, 0x15, + 0x04, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xcb, + 0x13, 0x00, 0x00, 0x02, 0x22, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x4f, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x02, 0x15, 0x00, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0xe0, 0x37, 0x05, 0x04, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x05, 0x13, 0x00, 0x00, + 0x00, 0xbe, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xbd, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xf4, 0x15, 0x04, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x4b, 0x13, 0x00, 0x00, 0x02, + 0x23, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x3d, + 0x00, 0x02, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x4b, 0x19, 0x00, 0x00, 0x00, 0xd2, 0x0f, 0x26, + 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, 0x0e, 0x23, + 0x45, 0x00, 0x00, 0x00, 0x20, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x4b, 0x17, 0x00, 0x00, + 0x1b, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, + 0x17, 0x00, 0x00, 0x0f, 0x26, 0x18, 0x00, 0x00, + 0x36, 0xff, 0xff, 0xff, 0xd6, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0x4b, 0x19, 0x00, 0x00, 0x00, + 0xd2, 0x0e, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x1e, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x13, 0x00, 0x00, 0x01, 0x5d, 0x3a, 0x07, + 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x00, 0xb8, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x4b, 0x19, 0x00, 0x00, + 0x00, 0xd2, 0x0f, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x1e, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x69, 0x3a, + 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x87, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x01, 0x4b, 0x19, 0x00, + 0x00, 0x00, 0xd2, 0x10, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x1e, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, 0xe6, + 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x56, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0x4b, 0x19, + 0x00, 0x00, 0x00, 0xd2, 0x11, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, + 0xe7, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, + 0x25, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x4b, 0x19, 0x00, 0x00, 0x00, 0xd2, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, + 0x00, 0x01, 0xe3, 0x3a, 0x07, 0x06, 0x04, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xf4, 0x19, 0x00, 0x00, + 0x00, 0xbd, 0x13, 0x00, 0x00, 0x00, 0xc3, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0xc9, 0x13, 0x00, 0x00, + 0x01, 0x3d, 0x19, 0x00, 0x00, 0x01, 0x48, 0x19, + 0x00, 0x00, 0x01, 0x45, 0x18, 0x00, 0x01, 0x0e, + 0x13, 0x00, 0x00, 0x01, 0x3d, 0x19, 0x00, 0x00, + 0x01, 0x48, 0x1a, 0x00, 0x00, 0x01, 0x45, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xf4, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0xe0, 0x37, 0x05, 0x04, 0x17, + 0x00, 0x01, 0x13, 0x00, 0x00, 0x01, 0x3d, 0x19, + 0x00, 0x00, 0x01, 0x48, 0x1a, 0x00, 0x00, 0x01, + 0x45, 0x13, 0x00, 0x00, 0x01, 0x3d, 0x19, 0x00, + 0x00, 0x01, 0x48, 0x19, 0x00, 0x00, 0x01, 0x45, + 0x0e, 0x21, 0x45, 0x00, 0x00, 0x00, 0x2a, 0x0e, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xf4, 0x19, + 0x00, 0x00, 0x00, 0xe7, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x02, + 0x24, 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, + 0x19, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x02, 0x25, 0x3a, + 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0x4b, 0x19, 0x00, 0x00, 0x00, 0xd2, 0x10, + 0x27, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x10, 0x13, 0x00, 0x00, 0x01, 0x62, 0x3a, 0x07, + 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x00, 0xcc, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xf4, 0x19, 0x00, 0x00, + 0x00, 0xbd, 0x13, 0x00, 0x00, 0x00, 0xbf, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x65, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xf4, 0x19, 0x00, 0x00, + 0x00, 0xf4, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, + 0x03, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xf4, 0x19, 0x00, 0x00, 0x00, 0xf8, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, + 0x00, 0x01, 0x6c, 0x3a, 0x07, 0x06, 0x04, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x01, 0x4b, 0x19, 0x00, + 0x00, 0x00, 0xd2, 0x10, 0x27, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, + 0x01, 0x62, 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, + 0x00, 0x50, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xf4, 0x0f, 0x13, 0x00, 0x00, 0x01, 0xe0, 0x37, + 0x05, 0x04, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x02, 0x25, + 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0x4b, 0x19, 0x00, 0x00, 0x00, 0xd2, + 0x10, 0x27, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0x62, 0x3a, + 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x06, 0x13, 0x00, 0x00, 0x02, 0x26, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xbd, 0x15, 0x02, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, 0x03, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, + 0x04, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xca, + 0x15, 0x05, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0xcb, 0x13, 0x00, 0x00, 0x02, 0x27, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0x4f, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x02, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0xfb, 0x12, 0x00, 0x00, 0x00, 0x3d, + 0x1f, 0x45, 0x00, 0x00, 0x00, 0x15, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0xca, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0xe0, 0x37, 0x05, 0x04, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0xcb, 0x35, 0x00, 0x00, 0x01, 0x4f, + 0x05, 0x03, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xfb, 0x12, 0x00, 0x00, 0x00, 0x3d, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x05, 0x36, 0x00, 0x00, 0x02, + 0x3a, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfb, + 0x13, 0x00, 0x00, 0x00, 0x13, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, + 0xff, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x02, + 0x0a, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfb, + 0x13, 0x00, 0x00, 0x00, 0x14, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x02, + 0x00, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x01, + 0xda, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfb, + 0x13, 0x00, 0x00, 0x00, 0x15, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x02, + 0x01, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x01, + 0xaa, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfb, + 0x13, 0x00, 0x00, 0x00, 0x16, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, + 0xd8, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x01, + 0x7a, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfb, + 0x13, 0x00, 0x00, 0x00, 0x17, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x02, + 0x05, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x01, + 0x4a, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfb, + 0x13, 0x00, 0x00, 0x00, 0x1b, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x02, + 0x08, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x01, + 0x1a, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfb, + 0x13, 0x00, 0x00, 0x00, 0x1d, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x02, + 0x09, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, + 0xea, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfb, + 0x13, 0x00, 0x00, 0x00, 0x1e, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x02, + 0x0a, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, + 0xba, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfb, + 0x13, 0x00, 0x00, 0x00, 0x18, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x02, + 0x18, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, + 0x8a, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfb, + 0x13, 0x00, 0x00, 0x00, 0x19, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x02, + 0x1c, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, + 0x5a, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfb, + 0x13, 0x00, 0x00, 0x00, 0x1a, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x1e, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x02, + 0x1a, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, + 0x2a, 0x13, 0x00, 0x00, 0x00, 0x72, 0x09, 0x00, + 0x00, 0x00, 0x73, 0x27, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x35, 0x00, 0x00, 0x00, + 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, 0x02, + 0x28, 0x27, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x76, + 0x37, 0x05, 0x04, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, + 0x65, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0xca, 0x0f, 0x13, 0x00, 0x00, 0x01, + 0xd7, 0x37, 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x01, 0x15, 0x02, + 0x19, 0x00, 0x00, 0x00, 0xbd, 0x13, 0x00, 0x00, + 0x00, 0xc3, 0x1e, 0x45, 0x00, 0x00, 0x01, 0xa0, + 0x15, 0x02, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0x50, 0x35, 0x00, 0x00, + 0x01, 0xab, 0x06, 0x03, 0x18, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x0a, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x60, 0x13, 0x00, 0x00, 0x01, 0x3d, 0x19, 0x00, + 0x00, 0x01, 0x48, 0x19, 0x00, 0x00, 0x01, 0x45, + 0x0e, 0x21, 0x45, 0x00, 0x00, 0x00, 0x25, 0x0e, + 0x15, 0x02, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x15, + 0x02, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, + 0x00, 0x00, 0x02, 0x29, 0x3a, 0x07, 0x06, 0x04, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x01, 0x3f, 0x0e, 0x15, 0x02, 0x19, + 0x00, 0x00, 0x00, 0xe7, 0x15, 0x02, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, + 0x5f, 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x01, + 0xdd, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xcf, 0x13, 0x00, 0x00, 0x01, 0x52, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x86, 0x13, 0x00, 0x00, 0x01, + 0x3d, 0x19, 0x00, 0x00, 0x01, 0x48, 0x19, 0x00, + 0x00, 0x01, 0x45, 0x0e, 0x21, 0x03, 0x45, 0x00, + 0x00, 0x00, 0x06, 0x04, 0x13, 0x00, 0x00, 0x02, + 0x2a, 0x33, 0x00, 0x00, 0x00, 0x3e, 0x13, 0x00, + 0x00, 0x00, 0x72, 0x09, 0x00, 0x00, 0x00, 0x73, + 0x27, 0x0e, 0x15, 0x02, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x35, 0x00, 0x00, 0x00, 0x74, 0x06, 0x02, + 0x27, 0x09, 0x00, 0x00, 0x02, 0x2b, 0x27, 0x17, + 0x00, 0x00, 0x19, 0x00, 0x00, 0x02, 0x2c, 0x27, + 0x09, 0x00, 0x00, 0x02, 0x2d, 0x27, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0x86, 0x37, 0x05, 0x04, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x17, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xe7, 0x15, 0x02, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, + 0x01, 0x56, 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, + 0x01, 0x44, 0x13, 0x00, 0x00, 0x01, 0x3d, 0x19, + 0x00, 0x00, 0x01, 0x48, 0x19, 0x00, 0x00, 0x01, + 0x45, 0x0e, 0x21, 0x03, 0x45, 0x00, 0x00, 0x00, + 0x06, 0x04, 0x13, 0x00, 0x00, 0x02, 0x2a, 0x33, + 0x00, 0x00, 0x00, 0x3e, 0x13, 0x00, 0x00, 0x00, + 0x72, 0x09, 0x00, 0x00, 0x00, 0x73, 0x27, 0x0e, + 0x15, 0x02, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x35, + 0x00, 0x00, 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, + 0x00, 0x00, 0x02, 0x2b, 0x27, 0x17, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x02, 0x2c, 0x27, 0x09, 0x00, + 0x00, 0x02, 0x2e, 0x27, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0x86, 0x37, 0x05, 0x04, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x17, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xe7, 0x15, 0x02, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0x6a, + 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0xbe, + 0x15, 0x02, 0x19, 0x00, 0x00, 0x00, 0xbd, 0x13, + 0x00, 0x00, 0x00, 0xbf, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x34, 0x0e, 0x15, 0x02, 0x19, 0x00, 0x00, + 0x00, 0xf4, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, + 0x03, 0x0e, 0x15, 0x02, 0x19, 0x00, 0x00, 0x00, + 0xf8, 0x15, 0x02, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x10, 0x13, 0x00, 0x00, 0x02, 0x2f, 0x3a, 0x07, + 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x00, 0x78, 0x15, 0x02, + 0x19, 0x00, 0x00, 0x00, 0xbd, 0x13, 0x00, 0x00, + 0x00, 0xc0, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x3c, + 0x0e, 0x15, 0x02, 0x19, 0x00, 0x00, 0x01, 0xca, + 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, 0x0e, + 0x15, 0x02, 0x19, 0x00, 0x00, 0x01, 0xcb, 0x35, + 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, 0x0e, 0x15, + 0x02, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, + 0x00, 0x00, 0x02, 0x30, 0x3a, 0x07, 0x06, 0x03, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x00, 0x2a, 0x13, 0x00, 0x00, 0x00, + 0x72, 0x09, 0x00, 0x00, 0x00, 0x73, 0x27, 0x0e, + 0x15, 0x02, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x35, + 0x00, 0x00, 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, + 0x00, 0x00, 0x00, 0xb0, 0x27, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x76, 0x37, 0x05, 0x04, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x01, + 0x15, 0x02, 0x19, 0x00, 0x00, 0x00, 0xbd, 0x13, + 0x00, 0x00, 0x00, 0xc3, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0xa5, 0x15, 0x02, 0x19, 0x00, 0x00, 0x00, + 0xe7, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x50, 0x35, + 0x00, 0x00, 0x01, 0xab, 0x06, 0x03, 0x18, 0x00, + 0x00, 0x17, 0x00, 0x00, 0x0a, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x25, 0x0e, 0x15, 0x02, 0x19, 0x00, + 0x00, 0x00, 0xe7, 0x15, 0x02, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0xdc, + 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x01, 0x1d, + 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0xcf, + 0x13, 0x00, 0x00, 0x01, 0x52, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x26, 0x0e, 0x17, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xe7, 0x15, 0x02, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x02, + 0x31, 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, + 0xe4, 0x0e, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xe7, 0x15, 0x02, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0x63, 0x3a, + 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0xbe, 0x15, + 0x02, 0x19, 0x00, 0x00, 0x00, 0xbd, 0x13, 0x00, + 0x00, 0x00, 0xbf, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x34, 0x0e, 0x15, 0x02, 0x19, 0x00, 0x00, 0x00, + 0xf4, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, + 0x0e, 0x15, 0x02, 0x19, 0x00, 0x00, 0x00, 0xf8, + 0x15, 0x02, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, + 0x13, 0x00, 0x00, 0x01, 0x7e, 0x3a, 0x07, 0x06, + 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x36, 0x00, 0x00, 0x00, 0x78, 0x15, 0x02, 0x19, + 0x00, 0x00, 0x00, 0xbd, 0x13, 0x00, 0x00, 0x00, + 0xc0, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x3c, 0x0e, + 0x15, 0x02, 0x19, 0x00, 0x00, 0x01, 0xca, 0x35, + 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, 0x0e, 0x15, + 0x02, 0x19, 0x00, 0x00, 0x01, 0xcb, 0x35, 0x00, + 0x00, 0x01, 0x4f, 0x05, 0x03, 0x0e, 0x15, 0x02, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0xf4, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x2a, 0x13, 0x00, 0x00, 0x00, 0x72, + 0x09, 0x00, 0x00, 0x00, 0x73, 0x27, 0x0e, 0x15, + 0x02, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x35, 0x00, + 0x00, 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, + 0x00, 0x00, 0xb0, 0x27, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0x76, 0x37, 0x05, 0x04, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x06, 0x13, 0x00, 0x00, 0x02, + 0x32, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xbd, + 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0xfc, 0x15, 0x04, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xfd, 0x15, 0x05, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x33, 0x13, 0x00, 0x00, 0x02, + 0x34, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x3d, + 0x00, 0x02, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xfc, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, + 0x03, 0x0e, 0x13, 0x00, 0x00, 0x01, 0x64, 0x3a, + 0x07, 0x06, 0x02, 0x18, 0x00, 0x00, 0x0e, 0x13, + 0x00, 0x00, 0x01, 0x64, 0x3a, 0x07, 0x06, 0x02, + 0x18, 0x00, 0x01, 0x13, 0x00, 0x00, 0x01, 0xc0, + 0x03, 0x33, 0x00, 0x00, 0x00, 0x0d, 0x04, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x01, 0xfc, 0x19, 0x00, + 0x00, 0x01, 0xac, 0x03, 0x33, 0x00, 0x00, 0x00, + 0x13, 0x04, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xfc, 0x19, 0x00, 0x00, 0x01, 0xac, 0x13, 0x00, + 0x00, 0x01, 0xad, 0x1e, 0x33, 0x00, 0x00, 0x00, + 0x21, 0x0e, 0x17, 0x00, 0x00, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, + 0x01, 0x9b, 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, + 0x00, 0x1c, 0x0e, 0x17, 0x00, 0x00, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, + 0x00, 0x01, 0xae, 0x3a, 0x07, 0x06, 0x04, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x01, 0xfd, 0x35, 0x00, + 0x00, 0x01, 0x4f, 0x05, 0x03, 0x0e, 0x17, 0x00, + 0x01, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x10, 0x13, 0x00, 0x00, 0x01, 0x6f, 0x3a, 0x07, + 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x0e, 0x17, 0x00, 0x00, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x02, 0x33, 0x35, 0x00, 0x00, 0x01, + 0x4f, 0x05, 0x03, 0x0e, 0x17, 0x00, 0x01, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x05, 0x13, 0x00, 0x00, + 0x02, 0x35, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xbd, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xfb, 0x15, 0x04, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xf4, 0x13, 0x00, 0x00, 0x02, + 0x36, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x01, 0xfb, 0x12, 0x00, + 0x00, 0x00, 0x21, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x2d, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xf4, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x13, 0x00, 0x00, 0x02, 0x37, 0x3a, 0x07, + 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x03, 0xcc, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0xfb, 0x12, 0x00, 0x00, + 0x00, 0x2b, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x14, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xf4, + 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x03, 0xa6, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x01, 0xfb, 0x12, 0x00, 0x00, 0x00, 0x7e, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x48, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xf4, 0x35, 0x00, + 0x00, 0x01, 0x4f, 0x05, 0x03, 0x0e, 0x0f, 0x2b, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, + 0x13, 0x00, 0x00, 0x01, 0xe3, 0x3a, 0x07, 0x06, + 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x13, 0x00, 0x00, 0x02, 0x1c, 0x3a, 0x07, + 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x03, 0x4c, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0xfb, 0x12, 0x00, 0x00, + 0x00, 0x2d, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x2d, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xf4, + 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, 0x0e, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, + 0x13, 0x00, 0x00, 0x02, 0x38, 0x3a, 0x07, 0x06, + 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x36, 0x00, 0x00, 0x03, 0x0d, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, 0x00, + 0x2e, 0x1e, 0x45, 0x00, 0x00, 0x01, 0x80, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xf4, 0x19, 0x00, + 0x00, 0x00, 0xbd, 0x13, 0x00, 0x00, 0x00, 0xbf, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x3e, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xf4, 0x19, 0x00, + 0x00, 0x00, 0xf4, 0x35, 0x00, 0x00, 0x01, 0x4f, + 0x05, 0x03, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xf4, 0x19, 0x00, 0x00, 0x00, 0xf8, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, + 0x00, 0x00, 0x02, 0x39, 0x3a, 0x07, 0x06, 0x04, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x36, + 0x00, 0x00, 0x02, 0xa6, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xf4, 0x19, 0x00, 0x00, 0x00, 0xbd, + 0x13, 0x00, 0x00, 0x00, 0xc0, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x46, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xf4, 0x19, 0x00, 0x00, 0x01, 0xca, + 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, 0x0e, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xf4, 0x19, + 0x00, 0x00, 0x01, 0xcb, 0x35, 0x00, 0x00, 0x01, + 0x4f, 0x05, 0x03, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x02, + 0x3a, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x02, + 0x49, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xf4, + 0x19, 0x00, 0x00, 0x00, 0xbd, 0x13, 0x00, 0x00, + 0x00, 0xc3, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x88, + 0x13, 0x00, 0x00, 0x01, 0x3d, 0x19, 0x00, 0x00, + 0x01, 0x48, 0x19, 0x00, 0x00, 0x01, 0x45, 0x0e, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x2f, 0x13, 0x00, + 0x00, 0x00, 0x72, 0x09, 0x00, 0x00, 0x00, 0x73, + 0x27, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x35, 0x00, 0x00, 0x00, 0x74, 0x06, 0x02, + 0x27, 0x09, 0x00, 0x00, 0x02, 0x3b, 0x27, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0x76, 0x37, 0x05, 0x04, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0xf7, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xf4, 0x19, 0x00, + 0x00, 0x00, 0xe7, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, 0x02, 0x39, + 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, + 0x55, 0x05, 0x03, 0x36, 0x00, 0x00, 0x01, 0xaa, + 0x13, 0x00, 0x00, 0x00, 0x72, 0x09, 0x00, 0x00, + 0x00, 0x73, 0x27, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x35, 0x00, 0x00, 0x00, 0x74, + 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, 0x02, 0x3c, + 0x27, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x76, 0x37, + 0x05, 0x04, 0x36, 0x00, 0x00, 0x01, 0x7b, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, + 0x00, 0x00, 0x44, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x46, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xf4, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x13, 0x00, 0x00, 0x01, 0x70, 0x3a, 0x07, + 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x71, 0x3a, + 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x36, 0x00, 0x00, 0x01, 0x23, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, + 0x00, 0x00, 0x40, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x2d, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xf4, 0x35, 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x13, 0x00, 0x00, 0x02, 0x3d, 0x3a, 0x07, + 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x00, 0xe4, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, + 0x00, 0x11, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x0e, 0x04, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xfb, 0x13, 0x00, 0x00, 0x00, 0x12, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0xa0, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xf4, 0x0f, 0x13, 0x00, 0x00, 0x01, + 0xe0, 0x37, 0x05, 0x04, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, + 0x01, 0x69, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, 0x00, + 0x11, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x1e, 0x0e, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0xd8, 0x3a, 0x07, 0x06, + 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x36, 0x00, 0x00, 0x00, 0x19, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, + 0x00, 0x02, 0x05, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0x65, 0x3a, 0x07, 0x06, 0x03, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xf4, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0xd7, 0x37, 0x05, 0x04, 0x36, + 0x00, 0x00, 0x00, 0x1e, 0x09, 0x00, 0x00, 0x02, + 0x3e, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xfb, 0x35, 0x00, 0x00, 0x00, 0x74, 0x06, 0x02, + 0x27, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x76, 0x37, + 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x05, 0x13, 0x00, 0x00, 0x02, 0x3f, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xbd, 0x15, 0x02, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, 0x03, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, + 0x04, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xf4, + 0x13, 0x00, 0x00, 0x02, 0x40, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x4f, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x02, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xf4, 0x0f, 0x13, 0x00, 0x00, 0x01, 0xe0, + 0x37, 0x05, 0x04, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, 0x01, + 0x65, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, + 0x01, 0x55, 0x05, 0x03, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, 0x00, + 0x01, 0x69, 0x3a, 0x07, 0x06, 0x03, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, 0x00, + 0x11, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x1e, 0x0e, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0xd8, 0x3a, 0x07, 0x06, + 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x36, 0x00, 0x00, 0x00, 0x19, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, 0x00, + 0x00, 0x02, 0x05, 0x3a, 0x07, 0x06, 0x03, 0x35, + 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xf4, 0x0f, 0x13, 0x00, + 0x00, 0x01, 0xd7, 0x37, 0x05, 0x04, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x05, 0x13, 0x00, 0x00, + 0x02, 0x41, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xbd, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xca, 0x15, 0x04, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0xcb, 0x13, 0x00, 0x00, 0x02, + 0x42, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x4f, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x0e, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xca, 0x35, + 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x13, + 0x00, 0x00, 0x01, 0x70, 0x3a, 0x07, 0x06, 0x03, + 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, 0x0e, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x01, 0xcb, 0x35, + 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x02, 0x0e, 0x13, 0x00, + 0x00, 0x02, 0x43, 0x3a, 0x07, 0x06, 0x02, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x44, 0x13, 0x00, + 0x00, 0x02, 0x45, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0x51, 0x13, 0x00, 0x00, 0x02, 0x46, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0x73, 0x13, 0x00, + 0x00, 0x02, 0x47, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0x5b, 0x13, 0x00, 0x00, 0x02, 0x48, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0x53, 0x13, 0x00, + 0x00, 0x02, 0x49, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0xab, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x02, 0x3d, 0x00, 0x01, 0x0e, 0x13, 0x00, 0x00, + 0x02, 0x43, 0x3a, 0x07, 0x06, 0x02, 0x18, 0x00, + 0x00, 0x15, 0x00, 0x19, 0x00, 0x00, 0x02, 0x44, + 0x19, 0x00, 0x00, 0x02, 0x4a, 0x17, 0x00, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x4a, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x02, 0x44, 0x17, 0x00, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x44, 0x17, 0x00, 0x00, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x44, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x02, 0x3d, 0x00, 0x01, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x02, 0x44, 0x19, + 0x00, 0x00, 0x02, 0x4b, 0x18, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x0a, 0x1f, 0x45, 0x00, 0x00, 0x00, + 0xc9, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x02, + 0x4c, 0x0e, 0x1e, 0x45, 0x00, 0x00, 0x00, 0xaa, + 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0xcf, + 0x13, 0x00, 0x00, 0x01, 0x52, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x49, 0x13, 0x00, 0x00, 0x02, 0x4d, + 0x33, 0x00, 0x00, 0x00, 0x88, 0x13, 0x00, 0x00, + 0x00, 0x72, 0x09, 0x00, 0x00, 0x00, 0x73, 0x27, + 0x0e, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x35, 0x00, 0x00, 0x00, 0x74, 0x06, 0x02, + 0x27, 0x09, 0x00, 0x00, 0x02, 0x4e, 0x27, 0x17, + 0x00, 0x00, 0x19, 0x00, 0x00, 0x02, 0x2c, 0x27, + 0x09, 0x00, 0x00, 0x00, 0x85, 0x27, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0x86, 0x37, 0x05, 0x04, 0x36, + 0x00, 0x00, 0x00, 0x49, 0x13, 0x00, 0x00, 0x02, + 0x4f, 0x33, 0x00, 0x00, 0x00, 0x44, 0x13, 0x00, + 0x00, 0x00, 0x72, 0x09, 0x00, 0x00, 0x00, 0x73, + 0x27, 0x0e, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xdd, 0x35, 0x00, 0x00, 0x00, 0x74, 0x06, + 0x02, 0x27, 0x09, 0x00, 0x00, 0x02, 0x50, 0x27, + 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x02, 0x2c, + 0x27, 0x09, 0x00, 0x00, 0x00, 0x85, 0x27, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0x86, 0x37, 0x05, 0x04, + 0x36, 0x00, 0x00, 0x00, 0x05, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, + 0x01, 0x44, 0x18, 0x00, 0x00, 0x36, 0xff, 0xff, + 0xff, 0x2d, 0x15, 0x00, 0x19, 0x00, 0x00, 0x02, + 0x44, 0x19, 0x00, 0x00, 0x01, 0x44, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x44, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x02, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x02, 0x44, 0x19, 0x00, 0x00, 0x02, 0x4a, + 0x03, 0x0f, 0x27, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x02, 0x44, 0x1a, 0x00, 0x00, 0x02, 0x4a, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x06, 0x3d, 0x00, 0x01, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x02, 0x44, 0x19, + 0x00, 0x00, 0x02, 0x4b, 0x18, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x0a, 0x1f, 0x45, 0x00, 0x00, 0x00, + 0xe1, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x02, + 0x2c, 0x15, 0x02, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0xc1, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xcf, 0x15, 0x03, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x3f, 0x13, 0x00, 0x00, 0x00, 0x72, 0x09, 0x00, + 0x00, 0x00, 0x73, 0x27, 0x0e, 0x17, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x35, 0x00, 0x00, + 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, + 0x02, 0x51, 0x27, 0x17, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x02, 0x2c, 0x27, 0x09, 0x00, 0x00, 0x00, + 0x85, 0x27, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x76, + 0x37, 0x05, 0x04, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0xcf, + 0x13, 0x00, 0x00, 0x01, 0x52, 0x1e, 0x03, 0x45, + 0x00, 0x00, 0x00, 0x06, 0x04, 0x13, 0x00, 0x00, + 0x02, 0x52, 0x33, 0x00, 0x00, 0x00, 0x33, 0x13, + 0x00, 0x00, 0x00, 0x72, 0x09, 0x00, 0x00, 0x00, + 0x73, 0x27, 0x0e, 0x15, 0x05, 0x35, 0x00, 0x00, + 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, + 0x02, 0x53, 0x27, 0x15, 0x02, 0x27, 0x09, 0x00, + 0x00, 0x02, 0x54, 0x27, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0x86, 0x37, 0x05, 0x04, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x15, 0x03, 0x17, 0x00, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0xcf, 0x15, 0x04, 0x17, 0x00, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xe7, 0x15, 0x05, + 0x17, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, + 0x0d, 0x38, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, + 0x01, 0x44, 0x18, 0x00, 0x00, 0x36, 0xff, 0xff, + 0xff, 0x15, 0x15, 0x05, 0x15, 0x04, 0x15, 0x03, + 0x15, 0x02, 0x09, 0x00, 0x00, 0x00, 0xe1, 0x13, + 0x00, 0x00, 0x02, 0x55, 0x3a, 0x07, 0x06, 0x06, + 0x18, 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x02, 0x44, 0x19, 0x00, 0x00, 0x02, 0x4b, 0x17, + 0x00, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x44, 0x17, + 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, 0x00, 0x02, + 0x44, 0x1a, 0x00, 0x00, 0x02, 0x4b, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x02, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x02, 0x44, 0x18, + 0x00, 0x00, 0x17, 0x00, 0x00, 0x0a, 0x1f, 0x45, + 0x00, 0x00, 0x00, 0x5b, 0x17, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x02, 0x4b, 0x18, 0x00, 0x01, 0x17, + 0x00, 0x01, 0x0a, 0x1f, 0x45, 0x00, 0x00, 0x00, + 0x36, 0x17, 0x00, 0x01, 0x19, 0x00, 0x00, 0x02, + 0x2c, 0x15, 0x02, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x16, 0x17, 0x00, 0x01, 0x19, 0x00, 0x00, 0x02, + 0x4c, 0x0f, 0x27, 0x17, 0x00, 0x01, 0x1a, 0x00, + 0x00, 0x02, 0x4c, 0x17, 0x00, 0x01, 0x38, 0x17, + 0x00, 0x01, 0x19, 0x00, 0x00, 0x01, 0x44, 0x18, + 0x00, 0x01, 0x36, 0xff, 0xff, 0xff, 0xc0, 0x17, + 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0x44, 0x18, + 0x00, 0x00, 0x36, 0xff, 0xff, 0xff, 0x9b, 0x0a, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x0a, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0x44, 0x0a, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x4b, 0x0e, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x4a, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x06, 0x0a, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0x44, 0x15, 0x02, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x2c, 0x15, 0x03, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xcf, 0x15, + 0x04, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xe7, + 0x15, 0x05, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xdd, 0x0e, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x4c, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, + 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x9d, 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0x25, 0x3a, 0x07, 0x06, 0x03, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x56, 0x09, 0x00, 0x00, 0x00, + 0x87, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x76, + 0x13, 0x00, 0x00, 0x02, 0x57, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x58, 0x13, 0x00, 0x00, 0x02, + 0x59, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x5a, + 0x13, 0x00, 0x00, 0x02, 0x5b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x5c, 0x13, 0x00, 0x00, 0x02, + 0x5d, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, + 0x13, 0x00, 0x00, 0x02, 0x5e, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0x28, 0x13, 0x00, 0x00, 0x02, + 0x5f, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x60, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x09, + 0x00, 0x00, 0x02, 0x61, 0x0f, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x02, 0x56, 0x35, 0x00, 0x00, 0x02, + 0x58, 0x06, 0x03, 0x2d, 0x33, 0x00, 0x00, 0x00, + 0x20, 0x13, 0x00, 0x00, 0x00, 0x97, 0x19, 0x00, + 0x00, 0x02, 0x62, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0x97, 0x35, 0x00, 0x00, 0x02, 0x63, 0x06, 0x03, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x76, 0x0c, + 0x38, 0x0b, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x02, 0x56, + 0x35, 0x00, 0x00, 0x02, 0x5a, 0x06, 0x02, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x02, 0x0e, 0x0f, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x02, 0x56, 0x35, 0x00, + 0x00, 0x02, 0x64, 0x06, 0x03, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x02, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x02, 0x56, 0x35, 0x00, 0x00, 0x00, 0x01, + 0x06, 0x02, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, + 0x15, 0x02, 0x0f, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x02, 0x56, 0x35, 0x00, 0x00, 0x00, 0x28, 0x05, + 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x02, 0x56, + 0x35, 0x00, 0x00, 0x02, 0x60, 0x06, 0x02, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, + 0x02, 0x65, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x9d, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x66, 0x0e, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x67, 0x0f, 0x2b, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x68, 0x09, 0x00, 0x00, 0x00, 0x87, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x76, 0x13, + 0x00, 0x00, 0x02, 0x69, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x58, 0x13, 0x00, 0x00, 0x02, 0x6a, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x5a, 0x13, + 0x00, 0x00, 0x02, 0x6b, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x5c, 0x13, 0x00, 0x00, 0x02, 0x6c, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, 0x13, + 0x00, 0x00, 0x02, 0x6d, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0x28, 0x13, 0x00, 0x00, 0x02, 0x6e, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x60, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x0b, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x02, 0x0b, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x02, 0x0e, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x67, 0x0f, 0x2b, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x68, 0x09, 0x00, 0x00, + 0x00, 0x87, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x76, 0x0b, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, + 0x3d, 0x00, 0x01, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x02, 0x68, 0x0e, 0x23, 0x45, 0x00, 0x00, 0x00, + 0x17, 0x15, 0x00, 0x19, 0x00, 0x00, 0x02, 0x68, + 0x18, 0x00, 0x00, 0x0f, 0x2b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x68, 0x17, 0x00, 0x00, 0x38, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x02, 0x67, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x02, 0x66, 0x19, 0x00, + 0x00, 0x00, 0xd2, 0x23, 0x45, 0x00, 0x00, 0x00, + 0x03, 0x0f, 0x2b, 0x38, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x02, 0x67, 0x03, 0x0f, 0x27, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x67, 0x0f, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x02, 0x66, 0x35, 0x00, 0x00, + 0x02, 0x6f, 0x06, 0x03, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x03, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x68, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x02, 0x3d, 0x00, 0x02, 0x09, 0x00, 0x00, + 0x00, 0x87, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x22, + 0x3a, 0x07, 0x06, 0x03, 0x18, 0x00, 0x00, 0x0e, + 0x15, 0x00, 0x35, 0x00, 0x00, 0x00, 0x01, 0x06, + 0x02, 0x03, 0x18, 0x00, 0x01, 0x0f, 0x2b, 0x1f, + 0x03, 0x45, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x17, + 0x00, 0x01, 0x12, 0x00, 0x00, 0x00, 0x0a, 0x1f, + 0x45, 0x00, 0x00, 0x00, 0x25, 0x17, 0x00, 0x01, + 0x09, 0x00, 0x00, 0x02, 0x70, 0x10, 0x13, 0x00, + 0x00, 0x00, 0x22, 0x35, 0x00, 0x00, 0x02, 0x71, + 0x06, 0x04, 0x0f, 0x17, 0x00, 0x00, 0x35, 0x00, + 0x00, 0x00, 0x27, 0x05, 0x04, 0x36, 0xff, 0xff, + 0xff, 0xb5, 0x17, 0x00, 0x00, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x02, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xe7, 0x09, 0x00, 0x00, 0x02, 0x70, 0x10, + 0x13, 0x00, 0x00, 0x00, 0x22, 0x35, 0x00, 0x00, + 0x02, 0x71, 0x06, 0x04, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x02, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xe7, 0x09, 0x00, 0x00, 0x02, 0x72, 0x10, 0x13, + 0x00, 0x00, 0x00, 0x22, 0x35, 0x00, 0x00, 0x02, + 0x71, 0x06, 0x04, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x02, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, + 0x09, 0x00, 0x00, 0x02, 0x73, 0x10, 0x13, 0x00, + 0x00, 0x00, 0x22, 0x35, 0x00, 0x00, 0x02, 0x71, + 0x06, 0x04, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, + 0x3d, 0x00, 0x01, 0x13, 0x00, 0x00, 0x02, 0x74, + 0x09, 0x00, 0x00, 0x02, 0x70, 0x10, 0x13, 0x00, + 0x00, 0x00, 0x22, 0x35, 0x00, 0x00, 0x02, 0x71, + 0x06, 0x04, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xe7, 0x27, 0x0e, 0x09, 0x00, 0x00, 0x02, 0x70, + 0x10, 0x13, 0x00, 0x00, 0x00, 0x22, 0x35, 0x00, + 0x00, 0x02, 0x71, 0x06, 0x04, 0x27, 0x0f, 0x13, + 0x00, 0x00, 0x02, 0x75, 0x37, 0x06, 0x03, 0x09, + 0x00, 0x00, 0x02, 0x73, 0x10, 0x13, 0x00, 0x00, + 0x00, 0x22, 0x35, 0x00, 0x00, 0x02, 0x71, 0x06, + 0x04, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x3d, + 0x00, 0x01, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xe7, 0x19, 0x00, 0x00, 0x02, 0x76, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x02, 0x76, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x02, 0x77, 0x27, 0x26, 0x09, 0x00, + 0x00, 0x02, 0x73, 0x10, 0x13, 0x00, 0x00, 0x00, + 0x22, 0x35, 0x00, 0x00, 0x02, 0x71, 0x06, 0x04, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x04, 0x13, 0x00, + 0x00, 0x02, 0x78, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xe7, 0x0e, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, 0x02, + 0x79, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, + 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, 0x02, 0x7c, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x27, + 0x09, 0x00, 0x00, 0x02, 0x7d, 0x27, 0x0f, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x13, + 0x00, 0x00, 0x02, 0x7f, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xfb, 0x0e, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xdd, 0x0e, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, 0x02, 0x80, + 0x03, 0x0f, 0x27, 0x14, 0x00, 0x00, 0x02, 0x80, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xe7, 0x0c, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x81, 0x0a, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x44, 0x13, + 0x00, 0x00, 0x02, 0x82, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, 0x7b, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, 0x13, + 0x00, 0x00, 0x02, 0x83, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x84, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x03, 0x0e, 0x15, 0x00, 0x35, 0x00, 0x00, + 0x02, 0x84, 0x06, 0x02, 0x09, 0x00, 0x00, 0x02, + 0x7d, 0x27, 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, + 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x02, 0x09, 0x00, 0x00, 0x01, 0x3e, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, + 0x35, 0x00, 0x00, 0x00, 0x74, 0x06, 0x02, 0x27, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x13, 0x00, + 0x00, 0x02, 0x85, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, 0x02, 0x86, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, + 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x03, 0x09, 0x00, 0x00, 0x02, 0x87, 0x0f, + 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, + 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, + 0x13, 0x00, 0x00, 0x02, 0x88, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, + 0x02, 0x89, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x7a, 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, 0x02, + 0x8a, 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, + 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x03, 0x13, 0x00, 0x00, 0x02, 0x8b, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, 0x02, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x0f, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, + 0x00, 0x00, 0x02, 0x8c, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, 0x7b, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, + 0x00, 0x02, 0x8d, 0x0f, 0x15, 0x02, 0x35, 0x00, + 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x13, 0x00, 0x00, 0x02, + 0x8e, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, + 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xdd, 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x8f, 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x77, 0x13, 0x00, 0x00, 0x02, 0x90, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, + 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, + 0x09, 0x00, 0x00, 0x02, 0x91, 0x0f, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x13, 0x00, + 0x00, 0x02, 0x92, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x2b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x8f, 0x0f, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, 0x02, + 0x93, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, + 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, 0x02, 0x94, + 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, + 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x04, 0x13, 0x00, 0x00, 0x02, 0x95, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, 0x03, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xe7, 0x15, + 0x03, 0x2b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x8f, 0x10, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x77, 0x13, 0x00, 0x00, 0x02, 0x96, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, + 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0x55, 0x13, 0x00, 0x00, 0x02, 0x97, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x98, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, 0x02, + 0x99, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xe7, 0x35, 0x00, 0x00, 0x00, 0x74, 0x06, 0x02, + 0x27, 0x09, 0x00, 0x00, 0x02, 0x7c, 0x27, 0x0f, + 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, + 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x04, + 0x13, 0x00, 0x00, 0x02, 0x9a, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, 0x03, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xe7, 0x15, 0x03, + 0x2b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x8f, + 0x10, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, + 0x13, 0x00, 0x00, 0x02, 0x9b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, + 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, + 0x13, 0x00, 0x00, 0x02, 0x97, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x98, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, 0x02, 0x9c, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, + 0x35, 0x00, 0x00, 0x00, 0x74, 0x06, 0x02, 0x27, + 0x09, 0x00, 0x00, 0x02, 0x7c, 0x27, 0x0f, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x13, + 0x00, 0x00, 0x02, 0x9d, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, 0x02, + 0x9e, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, + 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, 0x02, 0x9f, + 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, + 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x04, 0x13, 0x00, 0x00, 0x02, 0xa0, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, 0x03, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xe7, 0x10, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, + 0x00, 0x00, 0x02, 0xa1, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, 0x7b, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, 0x13, + 0x00, 0x00, 0x02, 0x97, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x98, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x03, 0x09, 0x00, 0x00, 0x02, 0xa2, 0x0e, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x35, + 0x00, 0x00, 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, + 0x00, 0x00, 0x02, 0x7c, 0x27, 0x0f, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x04, 0x13, 0x00, + 0x00, 0x02, 0xa3, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xe7, 0x0f, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x8f, 0x12, 0x00, 0x00, 0x00, + 0x05, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, + 0x13, 0x00, 0x00, 0x02, 0xa4, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, + 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, + 0x13, 0x00, 0x00, 0x02, 0xa5, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x98, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x05, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xe7, 0x39, 0x09, 0x00, + 0x00, 0x02, 0xa6, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x2a, 0x09, 0x00, 0x00, 0x02, 0xa7, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x35, 0x00, + 0x00, 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, + 0x00, 0x02, 0x7c, 0x27, 0x0f, 0x15, 0x02, 0x35, + 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x36, 0x00, + 0x00, 0x02, 0x0a, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xe7, 0x39, 0x09, 0x00, 0x00, 0x00, 0x06, + 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, 0x0f, 0x04, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x39, + 0x09, 0x00, 0x00, 0x02, 0xa8, 0x1e, 0x45, 0x00, + 0x00, 0x01, 0xe2, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xe7, 0x39, 0x09, 0x00, 0x00, 0x00, 0x06, + 0x1e, 0x18, 0x00, 0x04, 0x17, 0x00, 0x04, 0x33, + 0x00, 0x00, 0x00, 0x17, 0x09, 0x00, 0x00, 0x02, + 0xa9, 0x18, 0x00, 0x02, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xe7, 0x18, 0x00, 0x03, 0x36, 0x00, + 0x00, 0x00, 0x17, 0x09, 0x00, 0x00, 0x02, 0xaa, + 0x18, 0x00, 0x02, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xe7, 0x19, 0x00, 0x00, 0x02, 0xab, 0x18, + 0x00, 0x03, 0x09, 0x00, 0x00, 0x02, 0xa7, 0x17, + 0x00, 0x02, 0x27, 0x0f, 0x15, 0x02, 0x35, 0x00, + 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0e, 0x18, 0x00, + 0x00, 0x17, 0x00, 0x00, 0x17, 0x00, 0x03, 0x19, + 0x00, 0x00, 0x00, 0xd2, 0x20, 0x45, 0x00, 0x00, + 0x00, 0xff, 0x17, 0x00, 0x00, 0x0f, 0x17, 0x00, + 0x03, 0x35, 0x00, 0x00, 0x02, 0x6f, 0x06, 0x03, + 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, 0x17, 0x00, + 0x02, 0x0e, 0x1b, 0x1e, 0x03, 0x46, 0x00, 0x00, + 0x00, 0x0a, 0x04, 0x17, 0x00, 0x01, 0x12, 0x00, + 0x00, 0x00, 0x5c, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x23, 0x09, 0x00, 0x00, 0x02, 0xac, 0x17, 0x00, + 0x00, 0x0f, 0x17, 0x00, 0x03, 0x35, 0x00, 0x00, + 0x02, 0xad, 0x06, 0x03, 0x27, 0x0f, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x36, + 0x00, 0x00, 0x00, 0xa0, 0x17, 0x00, 0x01, 0x12, + 0x00, 0x00, 0x00, 0x0a, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x14, 0x09, 0x00, 0x00, 0x02, 0xae, 0x0f, + 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, + 0x04, 0x36, 0x00, 0x00, 0x00, 0x7e, 0x17, 0x00, + 0x01, 0x12, 0x00, 0x00, 0x00, 0x0d, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x00, 0x02, + 0xaf, 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, + 0x7e, 0x05, 0x04, 0x36, 0x00, 0x00, 0x00, 0x5c, + 0x17, 0x00, 0x01, 0x12, 0x00, 0x00, 0x00, 0x09, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, + 0x00, 0x02, 0xb0, 0x0f, 0x15, 0x02, 0x35, 0x00, + 0x00, 0x02, 0x7e, 0x05, 0x04, 0x36, 0x00, 0x00, + 0x00, 0x3a, 0x17, 0x00, 0x01, 0x12, 0x00, 0x00, + 0x00, 0x0c, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x14, + 0x09, 0x00, 0x00, 0x02, 0xb1, 0x0f, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x36, + 0x00, 0x00, 0x00, 0x18, 0x17, 0x00, 0x00, 0x0f, + 0x17, 0x00, 0x03, 0x35, 0x00, 0x00, 0x02, 0xad, + 0x06, 0x03, 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, + 0x02, 0x7e, 0x05, 0x04, 0x17, 0x00, 0x00, 0x0f, + 0x27, 0x18, 0x00, 0x00, 0x36, 0xff, 0xff, 0xfe, + 0xf0, 0x17, 0x00, 0x02, 0x0f, 0x15, 0x02, 0x35, + 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x17, 0x00, + 0x04, 0x2d, 0x33, 0x00, 0x00, 0x00, 0x4a, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x19, 0x00, + 0x00, 0x02, 0xb2, 0x33, 0x00, 0x00, 0x00, 0x14, + 0x09, 0x00, 0x00, 0x02, 0xb3, 0x0f, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xe7, 0x19, 0x00, 0x00, 0x02, 0xb4, + 0x33, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x00, + 0x02, 0xb5, 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, + 0x02, 0x7e, 0x05, 0x04, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x09, 0x00, 0x00, 0x02, 0x7c, 0x0f, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x02, 0x3d, 0x00, 0x02, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x39, 0x09, + 0x00, 0x00, 0x02, 0xa6, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0xb0, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xe7, 0x0f, 0x13, 0x00, 0x00, 0x02, 0xb6, 0x37, + 0x06, 0x03, 0x33, 0x00, 0x00, 0x00, 0x2f, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x13, 0x00, + 0x00, 0x02, 0xb7, 0x09, 0x00, 0x00, 0x02, 0xb8, + 0x11, 0x13, 0x00, 0x00, 0x00, 0x22, 0x35, 0x00, + 0x00, 0x02, 0x71, 0x06, 0x05, 0x0f, 0x13, 0x00, + 0x00, 0x02, 0x75, 0x37, 0x06, 0x03, 0x18, 0x00, + 0x00, 0x36, 0x00, 0x00, 0x01, 0x7a, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xe7, 0x0f, 0x13, 0x00, + 0x00, 0x02, 0xb9, 0x37, 0x06, 0x03, 0x33, 0x00, + 0x00, 0x00, 0x2f, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xe7, 0x13, 0x00, 0x00, 0x02, 0xba, 0x09, + 0x00, 0x00, 0x02, 0xbb, 0x11, 0x13, 0x00, 0x00, + 0x00, 0x22, 0x35, 0x00, 0x00, 0x02, 0x71, 0x06, + 0x05, 0x0f, 0x13, 0x00, 0x00, 0x02, 0x75, 0x37, + 0x06, 0x03, 0x18, 0x00, 0x00, 0x36, 0x00, 0x00, + 0x01, 0x36, 0x13, 0x00, 0x00, 0x02, 0xbc, 0x09, + 0x00, 0x00, 0x02, 0x70, 0x10, 0x13, 0x00, 0x00, + 0x00, 0x22, 0x35, 0x00, 0x00, 0x02, 0x71, 0x06, + 0x04, 0x0f, 0x13, 0x00, 0x00, 0x02, 0x75, 0x37, + 0x06, 0x03, 0x18, 0x00, 0x00, 0x36, 0x00, 0x00, + 0x01, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xe7, 0x39, 0x09, 0x00, 0x00, 0x00, 0x06, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x3c, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xe7, 0x19, 0x00, 0x00, 0x00, + 0xd2, 0x13, 0x00, 0x00, 0x02, 0xbd, 0x09, 0x00, + 0x00, 0x02, 0xb8, 0x11, 0x13, 0x00, 0x00, 0x00, + 0x22, 0x35, 0x00, 0x00, 0x02, 0x71, 0x06, 0x05, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x27, + 0x0f, 0x13, 0x00, 0x00, 0x02, 0x75, 0x37, 0x06, + 0x03, 0x18, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, + 0xbf, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, + 0x39, 0x09, 0x00, 0x00, 0x02, 0xa8, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x95, 0x0e, 0x18, 0x00, 0x01, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x19, + 0x00, 0x00, 0x02, 0xb2, 0x33, 0x00, 0x00, 0x00, + 0x11, 0x17, 0x00, 0x01, 0x13, 0x00, 0x00, 0x02, + 0xbe, 0x2e, 0x18, 0x00, 0x01, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xe7, 0x19, 0x00, 0x00, 0x02, 0xb4, 0x33, 0x00, + 0x00, 0x00, 0x11, 0x17, 0x00, 0x01, 0x13, 0x00, + 0x00, 0x02, 0xbf, 0x2e, 0x18, 0x00, 0x01, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xe7, 0x19, 0x00, 0x00, 0x02, 0xab, + 0x19, 0x00, 0x00, 0x00, 0xd2, 0x17, 0x00, 0x01, + 0x13, 0x00, 0x00, 0x02, 0xc0, 0x09, 0x00, 0x00, + 0x02, 0xc1, 0x09, 0x00, 0x00, 0x00, 0xe1, 0x13, + 0x00, 0x00, 0x00, 0x22, 0x35, 0x00, 0x00, 0x02, + 0x71, 0x06, 0x06, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xe7, 0x19, 0x00, 0x00, 0x02, 0xab, 0x27, + 0x0f, 0x13, 0x00, 0x00, 0x02, 0x75, 0x37, 0x06, + 0x03, 0x18, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, + 0x17, 0x09, 0x00, 0x00, 0x02, 0xc2, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xe7, 0x39, 0x27, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0x76, 0x37, 0x05, 0x04, + 0x17, 0x00, 0x00, 0x09, 0x00, 0x00, 0x02, 0x73, + 0x10, 0x13, 0x00, 0x00, 0x00, 0x22, 0x35, 0x00, + 0x00, 0x02, 0x71, 0x06, 0x04, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x13, 0x00, 0x00, 0x02, 0xc3, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, + 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x8f, + 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, + 0x13, 0x00, 0x00, 0x02, 0xc4, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, + 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, + 0x00, 0x00, 0x02, 0xc5, 0x0f, 0x15, 0x02, 0x35, + 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x13, 0x00, 0x00, + 0x02, 0xc6, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xdd, 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x8f, 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x77, 0x13, 0x00, 0x00, 0x02, 0xc7, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, + 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x09, 0x00, 0x00, 0x02, 0xc8, 0x0f, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x13, + 0x00, 0x00, 0x02, 0xc9, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x8f, 0x0f, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, 0x02, + 0xca, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, + 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, 0x02, 0xcb, + 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, + 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x13, 0x00, 0x00, 0x02, 0xcc, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x8f, 0x0f, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, + 0x00, 0x02, 0xcd, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, + 0x02, 0xce, 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, + 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x13, 0x00, 0x00, 0x02, 0xcf, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, + 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x8f, + 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, + 0x13, 0x00, 0x00, 0x02, 0xd0, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, + 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, + 0x00, 0x00, 0x02, 0xd1, 0x0f, 0x15, 0x02, 0x35, + 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x13, 0x00, 0x00, + 0x02, 0xd2, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xdd, 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x8f, 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x77, 0x13, 0x00, 0x00, 0x02, 0xd3, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, + 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x09, 0x00, 0x00, 0x02, 0xd4, 0x0f, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x13, + 0x00, 0x00, 0x02, 0xd5, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x8f, 0x0f, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, 0x02, + 0xd6, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, + 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, 0x02, 0xd7, + 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, + 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x13, 0x00, 0x00, 0x02, 0xd8, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x8f, 0x0f, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, + 0x00, 0x02, 0xd9, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, + 0x02, 0xda, 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, + 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x04, 0x13, 0x00, 0x00, 0x02, 0xdb, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, + 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, + 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xe7, 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x8f, 0x12, 0x00, 0x00, 0x00, 0x05, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, + 0x02, 0xdc, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x7a, 0x13, 0x00, 0x00, 0x02, 0xdd, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x98, 0x13, 0x00, 0x00, + 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, + 0x09, 0x00, 0x00, 0x02, 0xde, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xe7, 0x35, 0x00, 0x00, + 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, + 0x02, 0x7c, 0x27, 0x0f, 0x15, 0x02, 0x35, 0x00, + 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x04, 0x13, 0x00, 0x00, 0x02, + 0xdf, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, + 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xe7, 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x8f, 0x12, 0x00, 0x00, 0x00, 0x05, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, + 0x00, 0x02, 0xe0, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, 0xe1, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x98, 0x13, 0x00, + 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x09, 0x00, 0x00, 0x02, 0xe2, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xe7, 0x27, 0x09, 0x00, + 0x00, 0x02, 0x7c, 0x27, 0x0f, 0x15, 0x02, 0x35, + 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x04, 0x13, 0x00, 0x00, + 0x02, 0xe3, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xe7, 0x0f, 0x2b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x8f, 0x12, 0x00, 0x00, 0x00, + 0x05, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, + 0x13, 0x00, 0x00, 0x02, 0xe4, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, + 0xe1, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x98, + 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, 0x02, 0xe5, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x27, + 0x09, 0x00, 0x00, 0x02, 0x7c, 0x27, 0x0f, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x04, 0x13, + 0x00, 0x00, 0x02, 0xe6, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xe7, 0x0f, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x8f, 0x10, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, + 0x02, 0xe7, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x7a, 0x13, 0x00, 0x00, 0x02, 0x97, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x98, 0x13, 0x00, 0x00, + 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, + 0x09, 0x00, 0x00, 0x02, 0xe8, 0x0e, 0x15, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xe7, 0x35, 0x00, 0x00, + 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, + 0x02, 0x7c, 0x27, 0x0f, 0x15, 0x02, 0x35, 0x00, + 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x04, 0x13, 0x00, 0x00, 0x02, + 0xe9, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, + 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xe7, 0x0f, 0x2b, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x8f, 0x10, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, 0x02, 0xea, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, + 0x00, 0x00, 0x02, 0x97, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x98, 0x13, 0x00, 0x00, 0x02, 0x7b, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, + 0x00, 0x02, 0xeb, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xe7, 0x35, 0x00, 0x00, 0x00, 0x74, + 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, 0x02, 0x7c, + 0x27, 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, + 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x04, 0x13, 0x00, 0x00, 0x02, 0xec, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, 0x02, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, + 0x03, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xe7, + 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x8f, + 0x11, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, + 0x13, 0x00, 0x00, 0x02, 0xed, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, + 0xee, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x98, + 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, 0x02, 0xef, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, + 0x35, 0x00, 0x00, 0x00, 0x74, 0x06, 0x02, 0x27, + 0x09, 0x00, 0x00, 0x02, 0x7c, 0x27, 0x0f, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x04, 0x13, + 0x00, 0x00, 0x02, 0xf0, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xe7, 0x0f, 0x2b, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x8f, 0x11, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, + 0x00, 0x02, 0xf1, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, 0xee, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x98, 0x13, 0x00, + 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x09, 0x00, 0x00, 0x02, 0xf2, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x35, 0x00, + 0x00, 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, + 0x00, 0x02, 0x7c, 0x27, 0x0f, 0x15, 0x02, 0x35, + 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x04, 0x13, 0x00, 0x00, + 0x02, 0xf3, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xe7, 0x12, 0x00, 0x00, 0x00, 0x05, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, + 0x00, 0x00, 0x02, 0xf4, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, 0xe1, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x98, 0x13, + 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x03, 0x09, 0x00, 0x00, 0x02, 0xf5, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x27, 0x09, + 0x00, 0x00, 0x02, 0x7c, 0x27, 0x0f, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x04, 0x13, 0x00, + 0x00, 0x02, 0xf6, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xe7, 0x10, 0x2b, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x8f, 0x12, 0x00, 0x00, + 0x00, 0x05, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x77, 0x13, 0x00, 0x00, 0x02, 0xf7, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, + 0x02, 0xe1, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x98, 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, 0x02, + 0xf8, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, + 0x27, 0x09, 0x00, 0x00, 0x02, 0x7c, 0x27, 0x0f, + 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, + 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, + 0x13, 0x00, 0x00, 0x02, 0xf9, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x2b, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x8f, 0x0f, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, + 0x00, 0x02, 0xfa, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, + 0x02, 0xfb, 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, + 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x13, 0x00, 0x00, 0x02, 0xfc, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, + 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, + 0x11, 0x2b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x8f, 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x77, 0x13, 0x00, 0x00, 0x02, 0xfd, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, + 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, + 0x09, 0x00, 0x00, 0x02, 0xfe, 0x0f, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x13, 0x00, + 0x00, 0x02, 0xff, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, 0x03, 0x00, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, + 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x03, 0x09, 0x00, 0x00, 0x03, 0x01, 0x0f, + 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, + 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, + 0x13, 0x00, 0x00, 0x03, 0x02, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x2b, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x8f, 0x0f, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, + 0x00, 0x03, 0x03, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, + 0x03, 0x04, 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, + 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x13, 0x00, 0x00, 0x03, 0x05, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, + 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x2b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x8f, 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x77, 0x13, 0x00, 0x00, 0x03, 0x06, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, + 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, + 0x09, 0x00, 0x00, 0x03, 0x07, 0x0f, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x13, 0x00, + 0x00, 0x03, 0x08, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x2b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x8f, 0x0f, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, 0x03, + 0x09, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, + 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, 0x03, 0x0a, + 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, + 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x13, 0x00, 0x00, 0x03, 0x0b, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x2b, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x8f, 0x0f, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, + 0x00, 0x00, 0x03, 0x0c, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, 0x7b, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, + 0x00, 0x03, 0x0d, 0x0f, 0x15, 0x02, 0x35, 0x00, + 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x13, 0x00, 0x00, 0x03, + 0x0e, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, + 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xdd, 0x0f, 0x2b, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x8f, 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x77, 0x13, 0x00, 0x00, 0x03, 0x0f, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, + 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x09, 0x00, 0x00, 0x03, 0x10, 0x0f, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x13, + 0x00, 0x00, 0x03, 0x11, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x2b, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x8f, 0x0f, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, + 0x03, 0x12, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x7a, 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, 0x03, + 0x13, 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, + 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x03, 0x13, 0x00, 0x00, 0x03, 0x14, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, 0x02, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x0f, + 0x2b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x8f, + 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, + 0x13, 0x00, 0x00, 0x03, 0x15, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, + 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, + 0x00, 0x00, 0x03, 0x16, 0x0f, 0x15, 0x02, 0x35, + 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x13, 0x00, 0x00, + 0x03, 0x17, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xdd, 0x0f, 0x2b, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x8f, 0x0f, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, 0x03, 0x18, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, + 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x03, 0x09, 0x00, 0x00, 0x03, 0x19, 0x0f, + 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, + 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, + 0x13, 0x00, 0x00, 0x03, 0x1a, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x2b, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x8f, 0x0f, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, + 0x00, 0x03, 0x1b, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, + 0x03, 0x1c, 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, + 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x13, 0x00, 0x00, 0x03, 0x1d, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, + 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x2b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x8f, 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x77, 0x13, 0x00, 0x00, 0x03, 0x1e, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, + 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, + 0x09, 0x00, 0x00, 0x03, 0x1f, 0x0f, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x13, 0x00, + 0x00, 0x03, 0x20, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x2b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x8f, 0x0f, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, 0x03, + 0x21, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, + 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, 0x03, 0x22, + 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, + 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x13, 0x00, 0x00, 0x03, 0x23, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x2b, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x8f, 0x0f, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, + 0x00, 0x00, 0x03, 0x24, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, 0x7b, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, + 0x00, 0x03, 0x25, 0x0f, 0x15, 0x02, 0x35, 0x00, + 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x13, 0x00, 0x00, 0x03, + 0x26, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, + 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xdd, 0x0f, 0x2b, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x8f, 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x77, 0x13, 0x00, 0x00, 0x03, 0x27, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, + 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x09, 0x00, 0x00, 0x03, 0x28, 0x0f, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x13, + 0x00, 0x00, 0x03, 0x29, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, 0x03, + 0x2a, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, + 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, 0x03, 0x2b, + 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, + 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x13, 0x00, 0x00, 0x03, 0x2c, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x2b, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x8f, 0x0f, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, + 0x00, 0x00, 0x03, 0x2d, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, 0x7b, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, + 0x00, 0x03, 0x2e, 0x0f, 0x15, 0x02, 0x35, 0x00, + 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x13, 0x00, 0x00, 0x03, + 0x2f, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, + 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xdd, 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x77, 0x13, 0x00, 0x00, 0x03, 0x30, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, + 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, + 0x09, 0x00, 0x00, 0x03, 0x31, 0x0f, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x13, 0x00, + 0x00, 0x03, 0x32, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xdd, 0x0f, 0x2b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x8f, 0x0f, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, 0x03, + 0x33, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, + 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, 0x03, 0x34, + 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, + 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x13, 0x00, 0x00, 0x03, 0x35, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x2b, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x8f, 0x0f, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, + 0x00, 0x00, 0x03, 0x36, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, 0x7b, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, + 0x00, 0x03, 0x37, 0x0f, 0x15, 0x02, 0x35, 0x00, + 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x13, 0x00, 0x00, 0x03, + 0x38, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, + 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xdd, 0x0f, 0x2b, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x8f, 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x77, 0x13, 0x00, 0x00, 0x03, 0x39, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, + 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x09, 0x00, 0x00, 0x03, 0x3a, 0x0f, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x13, + 0x00, 0x00, 0x03, 0x3b, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x2b, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x8f, 0x0f, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, + 0x03, 0x3c, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x7a, 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, 0x03, + 0x3d, 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, + 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x03, 0x13, 0x00, 0x00, 0x03, 0x3e, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, 0x02, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x0f, + 0x2b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x8f, + 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, + 0x13, 0x00, 0x00, 0x03, 0x3f, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, + 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, + 0x00, 0x00, 0x03, 0x40, 0x0f, 0x15, 0x02, 0x35, + 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x04, 0x13, 0x00, 0x00, + 0x03, 0x41, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xe7, 0x0f, 0x2b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x8f, 0x12, 0x00, 0x00, 0x00, + 0x05, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, + 0x13, 0x00, 0x00, 0x03, 0x42, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, 0x03, + 0x43, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x98, + 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, 0x03, 0x44, + 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, + 0x35, 0x00, 0x00, 0x02, 0x84, 0x06, 0x02, 0x27, + 0x09, 0x00, 0x00, 0x02, 0x7c, 0x27, 0x0f, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x04, 0x13, + 0x00, 0x00, 0x03, 0x45, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xe7, 0x0f, 0x2b, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x8f, 0x12, 0x00, + 0x00, 0x00, 0x05, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x77, 0x13, 0x00, 0x00, 0x03, 0x46, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, + 0x00, 0x03, 0x43, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x98, 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, + 0x03, 0x47, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xe7, 0x35, 0x00, 0x00, 0x02, 0x84, 0x06, + 0x02, 0x27, 0x09, 0x00, 0x00, 0x02, 0x7c, 0x27, + 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, + 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x04, 0x13, 0x00, 0x00, 0x03, 0x48, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, 0x03, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xe7, 0x0f, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x8f, 0x12, + 0x00, 0x00, 0x00, 0x05, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, 0x03, 0x49, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, + 0x00, 0x00, 0x02, 0xe1, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x98, 0x13, 0x00, 0x00, 0x02, 0x7b, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, + 0x00, 0x03, 0x4a, 0x15, 0x00, 0x19, 0x00, 0x00, + 0x00, 0xe7, 0x27, 0x09, 0x00, 0x00, 0x02, 0x7c, + 0x27, 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, + 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x04, 0x13, 0x00, 0x00, 0x03, 0x4b, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, 0x02, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, + 0x03, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xe7, + 0x12, 0x00, 0x00, 0x00, 0x05, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, 0x03, + 0x4c, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, + 0x13, 0x00, 0x00, 0x03, 0x43, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x98, 0x13, 0x00, 0x00, 0x02, + 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, + 0x00, 0x00, 0x03, 0x4d, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xe7, 0x35, 0x00, 0x00, 0x02, + 0x84, 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, 0x02, + 0x7c, 0x27, 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, + 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x13, 0x00, 0x00, 0x03, 0x4e, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, + 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x8f, + 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, + 0x13, 0x00, 0x00, 0x03, 0x4f, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, + 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, + 0x00, 0x00, 0x03, 0x50, 0x0f, 0x15, 0x02, 0x35, + 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x13, 0x00, 0x00, + 0x03, 0x51, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xdd, 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x77, 0x13, 0x00, 0x00, 0x03, 0x52, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, + 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x09, 0x00, 0x00, 0x03, 0x53, 0x0f, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x13, + 0x00, 0x00, 0x03, 0x54, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, 0x03, + 0x55, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, + 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, 0x03, 0x56, + 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, + 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x13, 0x00, 0x00, 0x03, 0x57, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x0f, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x8f, 0x0f, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, + 0x00, 0x03, 0x58, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, + 0x03, 0x59, 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, + 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x04, 0x13, 0x00, 0x00, 0x03, 0x5a, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, + 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, + 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xe7, 0x12, 0x00, 0x00, 0x00, 0x05, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, + 0x03, 0x5b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x7a, 0x13, 0x00, 0x00, 0x02, 0xe1, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x98, 0x13, 0x00, 0x00, + 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, + 0x09, 0x00, 0x00, 0x03, 0x5c, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xe7, 0x27, 0x09, 0x00, 0x00, + 0x02, 0x7c, 0x27, 0x0f, 0x15, 0x02, 0x35, 0x00, + 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x13, 0x00, 0x00, 0x03, + 0x5d, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, + 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xdd, 0x0f, 0x2b, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x8f, 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x77, 0x13, 0x00, 0x00, 0x03, 0x5e, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, + 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x09, 0x00, 0x00, 0x03, 0x5f, 0x0f, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x04, 0x13, + 0x00, 0x00, 0x03, 0x60, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xe7, 0x15, 0x03, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x8f, 0x11, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, + 0x00, 0x03, 0x61, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, 0xee, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x98, 0x13, 0x00, + 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x09, 0x00, 0x00, 0x03, 0x62, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x35, 0x00, + 0x00, 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, + 0x00, 0x02, 0x7c, 0x27, 0x0f, 0x15, 0x02, 0x35, + 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x04, 0x13, 0x00, 0x00, + 0x03, 0x63, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xe7, 0x0f, 0x2b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x8f, 0x10, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, 0x03, + 0x64, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, + 0x13, 0x00, 0x00, 0x02, 0x97, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x98, 0x13, 0x00, 0x00, 0x02, + 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, + 0x00, 0x00, 0x03, 0x65, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xe7, 0x35, 0x00, 0x00, 0x00, + 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, 0x02, + 0x7c, 0x27, 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, + 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x13, 0x00, 0x00, 0x03, 0x66, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, + 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, + 0x13, 0x00, 0x00, 0x03, 0x67, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, + 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, + 0x00, 0x00, 0x03, 0x68, 0x0f, 0x15, 0x02, 0x35, + 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x13, 0x00, 0x00, + 0x03, 0x69, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xdd, 0x0f, 0x2b, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x8f, 0x0f, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, 0x03, 0x6a, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, + 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x03, 0x09, 0x00, 0x00, 0x03, 0x6b, 0x0f, + 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, + 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x04, + 0x13, 0x00, 0x00, 0x03, 0x6c, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, 0x03, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xe7, 0x10, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, + 0x00, 0x03, 0x6d, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, 0x97, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x02, 0x98, 0x13, 0x00, + 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x09, 0x00, 0x00, 0x03, 0x6e, 0x0e, 0x15, + 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x35, 0x00, + 0x00, 0x00, 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, + 0x00, 0x02, 0x7c, 0x27, 0x0f, 0x15, 0x02, 0x35, + 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x04, 0x13, 0x00, 0x00, + 0x03, 0x6f, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xe7, 0x12, 0x00, 0x00, 0x00, 0x05, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, + 0x00, 0x00, 0x03, 0x70, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, 0x03, 0x43, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x98, 0x13, + 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x03, 0x09, 0x00, 0x00, 0x03, 0x71, 0x0e, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x35, + 0x00, 0x00, 0x02, 0x84, 0x06, 0x02, 0x27, 0x09, + 0x00, 0x00, 0x02, 0x7c, 0x27, 0x0f, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x04, 0x13, 0x00, + 0x00, 0x03, 0x72, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xe7, 0x10, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, 0x03, + 0x73, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, + 0x13, 0x00, 0x00, 0x02, 0x97, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x98, 0x13, 0x00, 0x00, 0x02, + 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, + 0x00, 0x00, 0x03, 0x74, 0x0e, 0x15, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xe7, 0x35, 0x00, 0x00, 0x00, + 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, 0x02, + 0x7c, 0x27, 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, + 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x13, 0x00, 0x00, 0x03, 0x75, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, + 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, + 0x0f, 0x2b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x8f, 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x77, 0x13, 0x00, 0x00, 0x03, 0x76, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, + 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, + 0x09, 0x00, 0x00, 0x03, 0x77, 0x0f, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x04, 0x13, 0x00, + 0x00, 0x03, 0x78, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xe7, 0x0f, 0x2b, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x8f, 0x12, 0x00, 0x00, + 0x00, 0x05, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x77, 0x13, 0x00, 0x00, 0x03, 0x79, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, + 0x03, 0x43, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x98, 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, 0x03, + 0x7a, 0x0e, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xe7, 0x35, 0x00, 0x00, 0x02, 0x84, 0x06, 0x02, + 0x27, 0x09, 0x00, 0x00, 0x02, 0x7c, 0x27, 0x0f, + 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, + 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x04, + 0x13, 0x00, 0x00, 0x03, 0x7b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x15, 0x03, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xe7, 0x0f, 0x2b, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x8f, 0x12, + 0x00, 0x00, 0x00, 0x05, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x77, 0x13, 0x00, 0x00, 0x03, 0x7c, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, + 0x00, 0x00, 0x03, 0x43, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x98, 0x13, 0x00, 0x00, 0x02, 0x7b, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, + 0x00, 0x03, 0x7d, 0x0e, 0x15, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xe7, 0x35, 0x00, 0x00, 0x02, 0x84, + 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, 0x02, 0x7c, + 0x27, 0x0f, 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, + 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x03, 0x13, 0x00, 0x00, 0x03, 0x7e, 0x15, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, 0x15, 0x02, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, 0x0f, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, 0x13, + 0x00, 0x00, 0x03, 0x7f, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, 0x7b, + 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x55, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, + 0x00, 0x03, 0x80, 0x0f, 0x15, 0x02, 0x35, 0x00, + 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x13, 0x00, 0x00, 0x03, + 0x81, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0xfb, + 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0xdd, 0x0f, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x77, 0x13, 0x00, 0x00, 0x03, 0x82, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, + 0x02, 0x7b, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0x55, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, + 0x09, 0x00, 0x00, 0x03, 0x83, 0x0f, 0x15, 0x02, + 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x04, 0x13, 0x00, + 0x00, 0x03, 0x84, 0x15, 0x00, 0x1a, 0x00, 0x00, + 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xe7, 0x0f, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x8f, 0x12, 0x00, 0x00, 0x00, + 0x05, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x77, + 0x13, 0x00, 0x00, 0x03, 0x85, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, 0x02, + 0xe1, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x98, + 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, 0x03, 0x86, + 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x27, + 0x09, 0x00, 0x00, 0x02, 0x7c, 0x27, 0x0f, 0x15, + 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, + 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x04, 0x13, + 0x00, 0x00, 0x03, 0x87, 0x15, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0xfb, 0x15, 0x02, 0x15, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xdd, 0x15, 0x03, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0xe7, 0x0f, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x8f, 0x12, 0x00, 0x00, + 0x00, 0x05, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x77, 0x13, 0x00, 0x00, 0x03, 0x88, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x02, 0x7a, 0x13, 0x00, 0x00, + 0x02, 0xe1, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x02, + 0x98, 0x13, 0x00, 0x00, 0x02, 0x7b, 0x15, 0x00, + 0x1a, 0x00, 0x00, 0x01, 0x55, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x09, 0x00, 0x00, 0x03, + 0x89, 0x15, 0x00, 0x19, 0x00, 0x00, 0x00, 0xe7, + 0x27, 0x09, 0x00, 0x00, 0x02, 0x7c, 0x27, 0x0f, + 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, + 0x04, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, + 0x0a, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x44, + 0x13, 0x00, 0x00, 0x03, 0x8a, 0x0a, 0x1f, 0x45, + 0x00, 0x00, 0x00, 0x1b, 0x13, 0x00, 0x00, 0x03, + 0x8a, 0x14, 0x00, 0x00, 0x03, 0x8b, 0x15, 0x00, + 0x13, 0x00, 0x00, 0x03, 0x8a, 0x1a, 0x00, 0x00, + 0x01, 0x44, 0x36, 0x00, 0x00, 0x00, 0x07, 0x15, + 0x00, 0x14, 0x00, 0x00, 0x03, 0x8c, 0x15, 0x00, + 0x14, 0x00, 0x00, 0x03, 0x8a, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x02, 0x0f, 0x14, 0x00, 0x00, + 0x02, 0x80, 0x0a, 0x03, 0x14, 0x00, 0x00, 0x03, + 0x8b, 0x03, 0x14, 0x00, 0x00, 0x03, 0x8a, 0x14, + 0x00, 0x00, 0x03, 0x8c, 0x0e, 0x14, 0x00, 0x00, + 0x03, 0x8d, 0x0a, 0x14, 0x00, 0x00, 0x03, 0x8e, + 0x0a, 0x14, 0x00, 0x00, 0x03, 0x8f, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x02, 0x3d, 0x00, 0x02, + 0x13, 0x00, 0x00, 0x00, 0xa5, 0x33, 0x00, 0x00, + 0x00, 0x13, 0x09, 0x00, 0x00, 0x03, 0x90, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xa7, 0x37, 0x05, 0x04, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x13, 0x00, + 0x00, 0x03, 0x91, 0x3a, 0x07, 0x06, 0x02, 0x14, + 0x00, 0x00, 0x01, 0x50, 0x0e, 0x18, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x9f, + 0x19, 0x00, 0x00, 0x00, 0xd2, 0x20, 0x45, 0x00, + 0x00, 0x00, 0x1e, 0x0e, 0x13, 0x00, 0x00, 0x00, + 0x9f, 0x17, 0x00, 0x00, 0x1b, 0x35, 0x00, 0x00, + 0x01, 0x4f, 0x05, 0x03, 0x17, 0x00, 0x00, 0x0f, + 0x27, 0x18, 0x00, 0x00, 0x36, 0xff, 0xff, 0xff, + 0xcf, 0x13, 0x00, 0x00, 0x00, 0x9b, 0x19, 0x00, + 0x00, 0x00, 0xd2, 0x0e, 0x21, 0x45, 0x00, 0x00, + 0x01, 0x13, 0x0e, 0x09, 0x00, 0x00, 0x03, 0x92, + 0x13, 0x00, 0x00, 0x00, 0x9b, 0x0e, 0x1b, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x10, 0x13, 0x00, 0x00, + 0x01, 0x54, 0x3a, 0x07, 0x06, 0x04, 0x35, 0x00, + 0x00, 0x01, 0x55, 0x05, 0x03, 0x13, 0x00, 0x00, + 0x00, 0x9b, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x59, + 0x37, 0x06, 0x03, 0x18, 0x00, 0x01, 0x17, 0x00, + 0x01, 0x0e, 0x21, 0x45, 0x00, 0x00, 0x00, 0x26, + 0x0e, 0x17, 0x00, 0x01, 0x13, 0x00, 0x00, 0x00, + 0x9b, 0x0e, 0x1b, 0x19, 0x00, 0x00, 0x00, 0xdd, + 0x10, 0x13, 0x00, 0x00, 0x01, 0x5a, 0x3a, 0x07, + 0x06, 0x04, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, + 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x18, + 0x00, 0x00, 0x17, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x9b, 0x19, 0x00, 0x00, 0x00, 0xd2, 0x20, + 0x45, 0x00, 0x00, 0x00, 0x1e, 0x0e, 0x13, 0x00, + 0x00, 0x00, 0x9b, 0x17, 0x00, 0x00, 0x1b, 0x35, + 0x00, 0x00, 0x01, 0x4f, 0x05, 0x03, 0x17, 0x00, + 0x00, 0x0f, 0x27, 0x18, 0x00, 0x00, 0x36, 0xff, + 0xff, 0xff, 0xcf, 0x13, 0x00, 0x00, 0x03, 0x8b, + 0x0a, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x18, 0x0e, + 0x0e, 0x0f, 0x13, 0x00, 0x00, 0x01, 0x71, 0x3a, + 0x07, 0x06, 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, + 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x56, 0x13, + 0x00, 0x00, 0x03, 0x8a, 0x19, 0x00, 0x00, 0x01, + 0xfb, 0x13, 0x00, 0x00, 0x02, 0x92, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x20, 0x13, 0x00, 0x00, 0x03, + 0x8b, 0x14, 0x00, 0x00, 0x03, 0x8a, 0x0a, 0x13, + 0x00, 0x00, 0x03, 0x8a, 0x1a, 0x00, 0x00, 0x01, + 0x44, 0x0a, 0x14, 0x00, 0x00, 0x03, 0x8b, 0x36, + 0x00, 0x00, 0x00, 0x21, 0x0e, 0x13, 0x00, 0x00, + 0x03, 0x8a, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x0f, + 0x13, 0x00, 0x00, 0x01, 0x71, 0x3a, 0x07, 0x06, + 0x03, 0x35, 0x00, 0x00, 0x01, 0x55, 0x05, 0x03, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x14, 0x00, + 0x00, 0x01, 0x50, 0x0d, 0x38, 0x15, 0x01, 0x48, + 0x3e, 0x04, 0x3d, 0x00, 0x04, 0x15, 0x02, 0x33, + 0x00, 0x00, 0x00, 0x06, 0x0b, 0x36, 0x00, 0x00, + 0x00, 0x01, 0x0c, 0x18, 0x00, 0x02, 0x17, 0x00, + 0x02, 0x33, 0x00, 0x00, 0x00, 0xb3, 0x09, 0x00, + 0x00, 0x03, 0x93, 0x0f, 0x15, 0x03, 0x35, 0x00, + 0x00, 0x02, 0x7e, 0x05, 0x04, 0x0a, 0x18, 0x00, + 0x03, 0x13, 0x00, 0x00, 0x03, 0x8c, 0x18, 0x00, + 0x00, 0x17, 0x00, 0x00, 0x0a, 0x1f, 0x45, 0x00, + 0x00, 0x00, 0x21, 0x17, 0x00, 0x03, 0x17, 0x00, + 0x00, 0x1a, 0x00, 0x00, 0x03, 0x94, 0x17, 0x00, + 0x00, 0x18, 0x00, 0x03, 0x17, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x01, 0x44, 0x18, 0x00, 0x00, 0x36, + 0xff, 0xff, 0xff, 0xd5, 0x0e, 0x18, 0x00, 0x01, + 0x13, 0x00, 0x00, 0x03, 0x8a, 0x18, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x0a, 0x1f, 0x45, 0x00, 0x00, + 0x00, 0x57, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xfb, 0x13, 0x00, 0x00, 0x02, 0x7f, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x10, 0x17, 0x00, 0x01, + 0x17, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xdd, + 0x36, 0x00, 0x00, 0x00, 0x24, 0x17, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xdd, 0x39, 0x09, 0x00, + 0x00, 0x03, 0x95, 0x1f, 0x45, 0x00, 0x00, 0x00, + 0x10, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x18, 0x00, 0x01, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x03, + 0x94, 0x18, 0x00, 0x00, 0x36, 0xff, 0xff, 0xff, + 0x9f, 0x0e, 0x18, 0x00, 0x01, 0x13, 0x00, 0x00, + 0x03, 0x8c, 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, + 0x0a, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x9b, 0x17, + 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x39, + 0x09, 0x00, 0x00, 0x03, 0x95, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x1c, 0x17, 0x00, 0x02, 0x33, 0x00, + 0x00, 0x00, 0x62, 0x09, 0x00, 0x00, 0x03, 0x96, + 0x0f, 0x15, 0x03, 0x35, 0x00, 0x00, 0x02, 0x7e, + 0x05, 0x04, 0x36, 0x00, 0x00, 0x00, 0x4e, 0x17, + 0x00, 0x02, 0x03, 0x33, 0x00, 0x00, 0x00, 0x0d, + 0x04, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x17, 0x00, 0x01, 0x21, 0x33, 0x00, 0x00, + 0x00, 0x33, 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, + 0x02, 0x60, 0x06, 0x02, 0x18, 0x00, 0x03, 0x09, + 0x00, 0x00, 0x03, 0x97, 0x17, 0x00, 0x03, 0x27, + 0x09, 0x00, 0x00, 0x02, 0x7c, 0x27, 0x0f, 0x15, + 0x03, 0x35, 0x00, 0x00, 0x02, 0x7e, 0x05, 0x04, + 0x17, 0x00, 0x01, 0x0f, 0x27, 0x18, 0x00, 0x01, + 0x36, 0xff, 0xff, 0xff, 0xb2, 0x15, 0x03, 0x0f, + 0x17, 0x00, 0x00, 0x35, 0x00, 0x00, 0x02, 0x7a, + 0x05, 0x04, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, + 0x01, 0x44, 0x18, 0x00, 0x00, 0x36, 0xff, 0xff, + 0xff, 0x5b, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x03, 0x15, 0x02, 0x19, 0x00, 0x00, 0x01, 0xfb, + 0x13, 0x00, 0x00, 0x02, 0xdf, 0x1e, 0x03, 0x46, + 0x00, 0x00, 0x00, 0x0e, 0x04, 0x15, 0x02, 0x19, + 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, 0x02, + 0xe6, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, 0x0e, + 0x04, 0x15, 0x02, 0x19, 0x00, 0x00, 0x01, 0xfb, + 0x13, 0x00, 0x00, 0x02, 0xec, 0x1e, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x15, 0x02, 0x19, 0x00, + 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, 0x02, 0xe3, + 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, 0x0e, 0x04, + 0x15, 0x02, 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, + 0x00, 0x00, 0x02, 0xe9, 0x1e, 0x03, 0x46, 0x00, + 0x00, 0x00, 0x0e, 0x04, 0x15, 0x02, 0x19, 0x00, + 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, 0x02, 0xf0, + 0x1e, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x15, + 0x02, 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, + 0x00, 0x03, 0x4b, 0x1e, 0x03, 0x46, 0x00, 0x00, + 0x00, 0x0e, 0x04, 0x15, 0x02, 0x19, 0x00, 0x00, + 0x01, 0xfb, 0x13, 0x00, 0x00, 0x03, 0x41, 0x1e, + 0x03, 0x46, 0x00, 0x00, 0x00, 0x0e, 0x04, 0x15, + 0x02, 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, + 0x00, 0x03, 0x45, 0x1e, 0x03, 0x46, 0x00, 0x00, + 0x00, 0x0e, 0x04, 0x15, 0x02, 0x19, 0x00, 0x00, + 0x01, 0xfb, 0x13, 0x00, 0x00, 0x03, 0x78, 0x1e, + 0x03, 0x46, 0x00, 0x00, 0x00, 0x0e, 0x04, 0x15, + 0x02, 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, + 0x00, 0x03, 0x7b, 0x1e, 0x03, 0x46, 0x00, 0x00, + 0x00, 0x0e, 0x04, 0x15, 0x02, 0x19, 0x00, 0x00, + 0x01, 0xfb, 0x13, 0x00, 0x00, 0x03, 0x6f, 0x1e, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x03, 0x13, 0x00, + 0x00, 0x02, 0xa3, 0x15, 0x02, 0x19, 0x00, 0x00, + 0x01, 0xfb, 0x22, 0x03, 0x45, 0x00, 0x00, 0x00, + 0x0e, 0x04, 0x15, 0x02, 0x19, 0x00, 0x00, 0x01, + 0xfb, 0x13, 0x00, 0x00, 0x02, 0xd8, 0x22, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x15, 0x02, 0x0a, + 0x1f, 0x03, 0x45, 0x00, 0x00, 0x00, 0x22, 0x04, + 0x15, 0x02, 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, + 0x00, 0x00, 0x02, 0x7f, 0x1e, 0x03, 0x46, 0x00, + 0x00, 0x00, 0x0e, 0x04, 0x15, 0x02, 0x19, 0x00, + 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, 0x02, 0x78, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x0e, 0x15, 0x02, + 0x19, 0x00, 0x00, 0x01, 0x44, 0x16, 0x02, 0x36, + 0xff, 0xff, 0xff, 0xc1, 0x15, 0x02, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x05, 0x15, + 0x02, 0x13, 0x00, 0x00, 0x03, 0x98, 0x2c, 0x0e, + 0x1f, 0x45, 0x00, 0x00, 0x04, 0xbe, 0x13, 0x00, + 0x00, 0x00, 0xa5, 0x33, 0x00, 0x00, 0x00, 0x13, + 0x09, 0x00, 0x00, 0x03, 0x99, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xa7, 0x37, 0x05, 0x04, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x03, 0x8c, + 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, 0x0a, 0x1f, + 0x45, 0x00, 0x00, 0x04, 0x8f, 0x17, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x44, 0x0a, 0x1f, 0x03, + 0x45, 0x00, 0x00, 0x00, 0x14, 0x04, 0x17, 0x00, + 0x00, 0x19, 0x00, 0x00, 0x01, 0x44, 0x19, 0x00, + 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, 0x02, 0x8e, + 0x1e, 0x45, 0x00, 0x00, 0x01, 0xa6, 0x10, 0x18, + 0x00, 0x01, 0x0c, 0x18, 0x00, 0x02, 0x17, 0x00, + 0x00, 0x19, 0x00, 0x00, 0x01, 0x44, 0x19, 0x00, + 0x00, 0x01, 0x44, 0x18, 0x00, 0x03, 0x17, 0x00, + 0x03, 0x0a, 0x1f, 0x03, 0x45, 0x00, 0x00, 0x00, + 0x0b, 0x04, 0x17, 0x00, 0x03, 0x19, 0x00, 0x00, + 0x01, 0x44, 0x0a, 0x1f, 0x45, 0x00, 0x00, 0x01, + 0x51, 0x17, 0x00, 0x03, 0x19, 0x00, 0x00, 0x01, + 0x44, 0x18, 0x00, 0x04, 0x17, 0x00, 0x03, 0x0f, + 0x13, 0x00, 0x00, 0x03, 0x9a, 0x37, 0x06, 0x03, + 0x03, 0x34, 0x00, 0x00, 0x00, 0x0f, 0x04, 0x17, + 0x00, 0x03, 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, + 0x00, 0x00, 0x03, 0x4e, 0x1e, 0x03, 0x34, 0x00, + 0x00, 0x00, 0x0f, 0x04, 0x17, 0x00, 0x03, 0x19, + 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, 0x03, + 0x57, 0x1e, 0x03, 0x34, 0x00, 0x00, 0x00, 0x0f, + 0x04, 0x17, 0x00, 0x03, 0x19, 0x00, 0x00, 0x01, + 0xfb, 0x13, 0x00, 0x00, 0x03, 0x48, 0x1e, 0x03, + 0x34, 0x00, 0x00, 0x00, 0x0f, 0x04, 0x17, 0x00, + 0x03, 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, + 0x00, 0x03, 0x51, 0x1e, 0x03, 0x34, 0x00, 0x00, + 0x00, 0x0f, 0x04, 0x17, 0x00, 0x03, 0x19, 0x00, + 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, 0x02, 0x78, + 0x1e, 0x03, 0x34, 0x00, 0x00, 0x00, 0x0f, 0x04, + 0x17, 0x00, 0x03, 0x19, 0x00, 0x00, 0x01, 0xfb, + 0x13, 0x00, 0x00, 0x02, 0x7f, 0x1e, 0x03, 0x34, + 0x00, 0x00, 0x00, 0x0f, 0x04, 0x17, 0x00, 0x03, + 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, + 0x02, 0x8e, 0x1e, 0x03, 0x34, 0x00, 0x00, 0x00, + 0x0f, 0x04, 0x17, 0x00, 0x03, 0x19, 0x00, 0x00, + 0x01, 0xfb, 0x13, 0x00, 0x00, 0x03, 0x72, 0x1e, + 0x03, 0x34, 0x00, 0x00, 0x00, 0x0f, 0x04, 0x17, + 0x00, 0x03, 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, + 0x00, 0x00, 0x03, 0x75, 0x1e, 0x33, 0x00, 0x00, + 0x00, 0x05, 0x36, 0x00, 0x00, 0x00, 0x73, 0x17, + 0x00, 0x03, 0x19, 0x00, 0x00, 0x02, 0x8f, 0x33, + 0x00, 0x00, 0x00, 0x1e, 0x17, 0x00, 0x01, 0x17, + 0x00, 0x03, 0x19, 0x00, 0x00, 0x02, 0x8f, 0x27, + 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, 0x0e, 0x22, + 0x45, 0x00, 0x00, 0x00, 0x05, 0x36, 0x00, 0x00, + 0x00, 0x48, 0x17, 0x00, 0x04, 0x19, 0x00, 0x00, + 0x01, 0xfb, 0x13, 0x00, 0x00, 0x02, 0x92, 0x1e, + 0x03, 0x45, 0x00, 0x00, 0x00, 0x06, 0x04, 0x17, + 0x00, 0x01, 0x0f, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x19, 0x0b, 0x18, 0x00, 0x02, 0x17, 0x00, 0x04, + 0x19, 0x00, 0x00, 0x01, 0x44, 0x17, 0x00, 0x03, + 0x1a, 0x00, 0x00, 0x01, 0x44, 0x36, 0x00, 0x00, + 0x00, 0x10, 0x17, 0x00, 0x03, 0x19, 0x00, 0x00, + 0x01, 0x44, 0x18, 0x00, 0x03, 0x36, 0xff, 0xff, + 0xfe, 0x94, 0x17, 0x00, 0x02, 0x33, 0x00, 0x00, + 0x00, 0x1a, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, + 0x01, 0x44, 0x19, 0x00, 0x00, 0x01, 0x44, 0x17, + 0x00, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x44, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x01, 0x44, 0x0a, 0x1f, 0x03, 0x45, + 0x00, 0x00, 0x00, 0x10, 0x04, 0x17, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x44, 0x19, 0x00, 0x00, + 0x01, 0x44, 0x0a, 0x1f, 0x45, 0x00, 0x00, 0x00, + 0x7d, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x44, 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, 0x19, + 0x00, 0x00, 0x01, 0x44, 0x18, 0x00, 0x02, 0x17, + 0x00, 0x01, 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, + 0x00, 0x00, 0x02, 0x9a, 0x1e, 0x03, 0x45, 0x00, + 0x00, 0x00, 0x0f, 0x04, 0x17, 0x00, 0x02, 0x19, + 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, 0x02, + 0x92, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x3f, 0x17, + 0x00, 0x01, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x0f, + 0x27, 0x17, 0x00, 0x01, 0x19, 0x00, 0x00, 0x00, + 0xdd, 0x10, 0x13, 0x00, 0x00, 0x01, 0x6d, 0x3a, + 0x07, 0x06, 0x04, 0x18, 0x00, 0x03, 0x17, 0x00, + 0x03, 0x17, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0x44, 0x17, 0x00, 0x02, 0x19, 0x00, 0x00, 0x01, + 0x44, 0x17, 0x00, 0x03, 0x1a, 0x00, 0x00, 0x01, + 0x44, 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, + 0x00, 0x19, 0x00, 0x00, 0x01, 0x44, 0x0a, 0x1f, + 0x03, 0x45, 0x00, 0x00, 0x00, 0x10, 0x04, 0x17, + 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0x44, 0x19, + 0x00, 0x00, 0x01, 0x44, 0x0a, 0x1f, 0x45, 0x00, + 0x00, 0x00, 0x68, 0x17, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x01, 0x44, 0x18, 0x00, 0x01, 0x17, 0x00, + 0x01, 0x19, 0x00, 0x00, 0x01, 0x44, 0x18, 0x00, + 0x02, 0x17, 0x00, 0x01, 0x19, 0x00, 0x00, 0x01, + 0xfb, 0x13, 0x00, 0x00, 0x02, 0xc6, 0x1e, 0x03, + 0x45, 0x00, 0x00, 0x00, 0x24, 0x04, 0x17, 0x00, + 0x02, 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, + 0x00, 0x03, 0x41, 0x1e, 0x03, 0x46, 0x00, 0x00, + 0x00, 0x0f, 0x04, 0x17, 0x00, 0x02, 0x19, 0x00, + 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, 0x03, 0x78, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x15, 0x17, 0x00, + 0x02, 0x19, 0x00, 0x00, 0x01, 0x44, 0x17, 0x00, + 0x00, 0x1a, 0x00, 0x00, 0x01, 0x44, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x01, 0x44, 0x0a, 0x1f, 0x03, 0x45, 0x00, + 0x00, 0x00, 0x10, 0x04, 0x17, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x01, 0x44, 0x19, 0x00, 0x00, 0x01, + 0x44, 0x0a, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x68, + 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0x44, + 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, 0x19, 0x00, + 0x00, 0x01, 0x44, 0x18, 0x00, 0x02, 0x17, 0x00, + 0x01, 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, + 0x00, 0x02, 0xc9, 0x1e, 0x03, 0x45, 0x00, 0x00, + 0x00, 0x24, 0x04, 0x17, 0x00, 0x02, 0x19, 0x00, + 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, 0x03, 0x45, + 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, 0x0f, 0x04, + 0x17, 0x00, 0x02, 0x19, 0x00, 0x00, 0x01, 0xfb, + 0x13, 0x00, 0x00, 0x03, 0x7b, 0x1e, 0x45, 0x00, + 0x00, 0x00, 0x15, 0x17, 0x00, 0x02, 0x19, 0x00, + 0x00, 0x01, 0x44, 0x17, 0x00, 0x00, 0x1a, 0x00, + 0x00, 0x01, 0x44, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0x44, + 0x0a, 0x1f, 0x03, 0x45, 0x00, 0x00, 0x00, 0x10, + 0x04, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x44, 0x19, 0x00, 0x00, 0x01, 0x44, 0x0a, 0x1f, + 0x45, 0x00, 0x00, 0x00, 0xcf, 0x17, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x44, 0x18, 0x00, 0x01, + 0x17, 0x00, 0x01, 0x19, 0x00, 0x00, 0x01, 0x44, + 0x18, 0x00, 0x02, 0x17, 0x00, 0x01, 0x19, 0x00, + 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, 0x02, 0xc9, + 0x1e, 0x03, 0x45, 0x00, 0x00, 0x00, 0x24, 0x04, + 0x17, 0x00, 0x02, 0x19, 0x00, 0x00, 0x01, 0xfb, + 0x13, 0x00, 0x00, 0x03, 0x41, 0x1e, 0x03, 0x46, + 0x00, 0x00, 0x00, 0x0f, 0x04, 0x17, 0x00, 0x02, + 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, + 0x03, 0x78, 0x1e, 0x03, 0x46, 0x00, 0x00, 0x00, + 0x39, 0x04, 0x17, 0x00, 0x01, 0x19, 0x00, 0x00, + 0x01, 0xfb, 0x13, 0x00, 0x00, 0x02, 0xc6, 0x1e, + 0x03, 0x45, 0x00, 0x00, 0x00, 0x24, 0x04, 0x17, + 0x00, 0x02, 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, + 0x00, 0x00, 0x03, 0x45, 0x1e, 0x03, 0x46, 0x00, + 0x00, 0x00, 0x0f, 0x04, 0x17, 0x00, 0x02, 0x19, + 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, 0x03, + 0x7b, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x3d, 0x17, + 0x00, 0x02, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x17, + 0x00, 0x01, 0x19, 0x00, 0x00, 0x00, 0xdd, 0x10, + 0x13, 0x00, 0x00, 0x01, 0x6f, 0x3a, 0x07, 0x06, + 0x04, 0x18, 0x00, 0x03, 0x17, 0x00, 0x03, 0x17, + 0x00, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x44, 0x17, + 0x00, 0x02, 0x19, 0x00, 0x00, 0x01, 0x44, 0x17, + 0x00, 0x03, 0x1a, 0x00, 0x00, 0x01, 0x44, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x01, 0x44, 0x18, 0x00, 0x00, 0x36, + 0xff, 0xff, 0xfb, 0x67, 0x15, 0x02, 0x13, 0x00, + 0x00, 0x03, 0x9b, 0x2c, 0x0e, 0x1f, 0x45, 0x00, + 0x00, 0x00, 0x98, 0x13, 0x00, 0x00, 0x00, 0xa5, + 0x33, 0x00, 0x00, 0x00, 0x13, 0x09, 0x00, 0x00, + 0x03, 0x9c, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa7, + 0x37, 0x05, 0x04, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x03, 0x8c, 0x18, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x0a, 0x1f, 0x45, 0x00, 0x00, + 0x00, 0x69, 0x17, 0x00, 0x00, 0x0f, 0x13, 0x00, + 0x00, 0x03, 0x9a, 0x37, 0x06, 0x03, 0x33, 0x00, + 0x00, 0x00, 0x48, 0x17, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xe7, 0x0f, 0x13, 0x00, 0x00, 0x03, + 0x9d, 0x37, 0x06, 0x03, 0x18, 0x00, 0x01, 0x17, + 0x00, 0x01, 0x0a, 0x1f, 0x03, 0x45, 0x00, 0x00, + 0x00, 0x0f, 0x04, 0x17, 0x00, 0x01, 0x19, 0x00, + 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, 0x03, 0x4b, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x15, 0x17, 0x00, + 0x01, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x17, 0x00, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0xe7, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x01, 0x44, 0x18, 0x00, 0x00, 0x36, 0xff, + 0xff, 0xff, 0x8d, 0x15, 0x02, 0x13, 0x00, 0x00, + 0x03, 0x9e, 0x2c, 0x0e, 0x1f, 0x45, 0x00, 0x00, + 0x00, 0x0e, 0x0e, 0x13, 0x00, 0x00, 0x03, 0x9f, + 0x37, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x15, 0x02, 0x13, 0x00, 0x00, 0x03, 0xa0, 0x2c, + 0x0e, 0x1f, 0x45, 0x00, 0x00, 0x02, 0xdb, 0x0b, + 0x18, 0x00, 0x01, 0x17, 0x00, 0x01, 0x33, 0x00, + 0x00, 0x02, 0xcf, 0x0c, 0x18, 0x00, 0x01, 0x13, + 0x00, 0x00, 0x00, 0xa5, 0x33, 0x00, 0x00, 0x00, + 0x13, 0x09, 0x00, 0x00, 0x03, 0xa1, 0x0f, 0x13, + 0x00, 0x00, 0x00, 0xa7, 0x37, 0x05, 0x04, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x03, + 0x8c, 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, 0x0a, + 0x1f, 0x45, 0x00, 0x00, 0x00, 0x31, 0x17, 0x00, + 0x00, 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, + 0x00, 0x02, 0x7f, 0x1e, 0x45, 0x00, 0x00, 0x00, + 0x0e, 0x0c, 0x17, 0x00, 0x00, 0x1a, 0x00, 0x00, + 0x02, 0x81, 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0x44, 0x18, + 0x00, 0x00, 0x36, 0xff, 0xff, 0xff, 0xc5, 0x13, + 0x00, 0x00, 0x03, 0x8c, 0x18, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x0a, 0x1f, 0x45, 0x00, 0x00, 0x00, + 0x34, 0x17, 0x00, 0x00, 0x0f, 0x13, 0x00, 0x00, + 0x03, 0x9a, 0x37, 0x06, 0x03, 0x33, 0x00, 0x00, + 0x00, 0x13, 0x0b, 0x17, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xe7, 0x1a, 0x00, 0x00, 0x02, 0x81, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x44, 0x18, 0x00, 0x00, + 0x36, 0xff, 0xff, 0xff, 0xc2, 0x13, 0x00, 0x00, + 0x03, 0x8c, 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, + 0x0a, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x82, 0x17, + 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0x44, 0x0a, + 0x1f, 0x03, 0x45, 0x00, 0x00, 0x00, 0x14, 0x04, + 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0x44, + 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, + 0x02, 0x7f, 0x1e, 0x03, 0x45, 0x00, 0x00, 0x00, + 0x0f, 0x04, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, + 0x01, 0x44, 0x19, 0x00, 0x00, 0x02, 0x81, 0x2d, + 0x03, 0x33, 0x00, 0x00, 0x00, 0x10, 0x04, 0x17, + 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0x44, 0x19, + 0x00, 0x00, 0x01, 0x44, 0x0a, 0x1f, 0x33, 0x00, + 0x00, 0x00, 0x1e, 0x0b, 0x18, 0x00, 0x01, 0x17, + 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0x44, 0x19, + 0x00, 0x00, 0x01, 0x44, 0x17, 0x00, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x44, 0x36, 0xff, 0xff, 0xff, + 0x8e, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x44, 0x18, 0x00, 0x00, 0x36, 0xff, 0xff, 0xff, + 0x74, 0x13, 0x00, 0x00, 0x00, 0xa5, 0x33, 0x00, + 0x00, 0x00, 0x13, 0x09, 0x00, 0x00, 0x03, 0xa2, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa7, 0x37, 0x05, + 0x04, 0x36, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, + 0x00, 0x03, 0x8c, 0x18, 0x00, 0x00, 0x17, 0x00, + 0x00, 0x0a, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x99, + 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0xfb, + 0x13, 0x00, 0x00, 0x03, 0x51, 0x1e, 0x03, 0x46, + 0x00, 0x00, 0x00, 0x0f, 0x04, 0x17, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, + 0x03, 0x4b, 0x1e, 0x45, 0x00, 0x00, 0x00, 0x61, + 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0x44, + 0x0a, 0x1f, 0x03, 0x45, 0x00, 0x00, 0x00, 0x14, + 0x04, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x44, 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, + 0x00, 0x02, 0x78, 0x1f, 0x03, 0x45, 0x00, 0x00, + 0x00, 0x14, 0x04, 0x17, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x01, 0x44, 0x19, 0x00, 0x00, 0x01, 0xfb, + 0x13, 0x00, 0x00, 0x02, 0x7f, 0x1f, 0x45, 0x00, + 0x00, 0x00, 0x1e, 0x0b, 0x18, 0x00, 0x01, 0x17, + 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0x44, 0x19, + 0x00, 0x00, 0x01, 0x44, 0x17, 0x00, 0x00, 0x1a, + 0x00, 0x00, 0x01, 0x44, 0x36, 0xff, 0xff, 0xff, + 0x9f, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x44, 0x18, 0x00, 0x00, 0x36, 0xff, 0xff, 0xff, + 0x5d, 0x13, 0x00, 0x00, 0x00, 0xa5, 0x33, 0x00, + 0x00, 0x00, 0x13, 0x09, 0x00, 0x00, 0x03, 0x99, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa7, 0x37, 0x05, + 0x04, 0x36, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, + 0x00, 0x03, 0x8c, 0x18, 0x00, 0x00, 0x17, 0x00, + 0x00, 0x0a, 0x1f, 0x45, 0xff, 0xff, 0xfd, 0xc3, + 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0x44, + 0x0a, 0x1f, 0x03, 0x45, 0x00, 0x00, 0x00, 0x10, + 0x04, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x44, 0x19, 0x00, 0x00, 0x01, 0x44, 0x0a, 0x1f, + 0x45, 0x00, 0x00, 0x00, 0x65, 0x17, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x44, 0x18, 0x00, 0x02, + 0x17, 0x00, 0x02, 0x19, 0x00, 0x00, 0x01, 0x44, + 0x18, 0x00, 0x03, 0x17, 0x00, 0x02, 0x19, 0x00, + 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, 0x03, 0x4b, + 0x1e, 0x03, 0x45, 0x00, 0x00, 0x00, 0x0f, 0x04, + 0x17, 0x00, 0x03, 0x19, 0x00, 0x00, 0x01, 0xfb, + 0x13, 0x00, 0x00, 0x02, 0x7f, 0x1e, 0x03, 0x45, + 0x00, 0x00, 0x00, 0x0d, 0x04, 0x17, 0x00, 0x02, + 0x19, 0x00, 0x00, 0x00, 0xe7, 0x17, 0x00, 0x03, + 0x1e, 0x45, 0x00, 0x00, 0x00, 0x14, 0x17, 0x00, + 0x03, 0x17, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x01, + 0x44, 0x0b, 0x18, 0x00, 0x01, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, + 0x01, 0x44, 0x18, 0x00, 0x00, 0x36, 0xff, 0xff, + 0xff, 0x5c, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x02, 0x3d, 0x00, 0x07, 0x13, 0x00, 0x00, 0x00, + 0xa5, 0x33, 0x00, 0x00, 0x00, 0x13, 0x09, 0x00, + 0x00, 0x03, 0xa3, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0xa7, 0x37, 0x05, 0x04, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x0a, 0x18, 0x00, 0x01, 0x13, 0x00, 0x00, + 0x03, 0x8c, 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, + 0x0a, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x3c, 0x17, + 0x00, 0x01, 0x17, 0x00, 0x00, 0x1a, 0x00, 0x00, + 0x03, 0x94, 0x0e, 0x17, 0x00, 0x00, 0x1a, 0x00, + 0x00, 0x03, 0xa4, 0x0e, 0x17, 0x00, 0x00, 0x1a, + 0x00, 0x00, 0x03, 0xa5, 0x0c, 0x17, 0x00, 0x00, + 0x1a, 0x00, 0x00, 0x03, 0xa6, 0x17, 0x00, 0x00, + 0x18, 0x00, 0x01, 0x17, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x01, 0x44, 0x18, 0x00, 0x00, 0x36, 0xff, + 0xff, 0xff, 0xba, 0x13, 0x00, 0x00, 0x03, 0x8a, + 0x18, 0x00, 0x02, 0x17, 0x00, 0x02, 0x0a, 0x1f, + 0x45, 0x00, 0x00, 0x02, 0x1c, 0x0b, 0x18, 0x00, + 0x04, 0x17, 0x00, 0x04, 0x33, 0x00, 0x00, 0x02, + 0x00, 0x0c, 0x18, 0x00, 0x04, 0x17, 0x00, 0x02, + 0x18, 0x00, 0x03, 0x17, 0x00, 0x03, 0x19, 0x00, + 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, 0x02, 0x78, + 0x1f, 0x45, 0xff, 0xff, 0xff, 0xdb, 0x17, 0x00, + 0x03, 0x19, 0x00, 0x00, 0x01, 0x44, 0x0a, 0x1f, + 0x45, 0x00, 0x00, 0x00, 0x25, 0x17, 0x00, 0x03, + 0x19, 0x00, 0x00, 0x01, 0x44, 0x19, 0x00, 0x00, + 0x03, 0xa5, 0x18, 0x00, 0x05, 0x17, 0x00, 0x03, + 0x19, 0x00, 0x00, 0x01, 0x44, 0x19, 0x00, 0x00, + 0x03, 0xa4, 0x18, 0x00, 0x06, 0x36, 0x00, 0x00, + 0x00, 0x08, 0x0e, 0x03, 0x18, 0x00, 0x06, 0x18, + 0x00, 0x05, 0x17, 0x00, 0x03, 0x19, 0x00, 0x00, + 0x01, 0xfb, 0x13, 0x00, 0x00, 0x02, 0xec, 0x1e, + 0x03, 0x45, 0x00, 0x00, 0x00, 0x0f, 0x04, 0x17, + 0x00, 0x03, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x12, + 0x00, 0x00, 0x00, 0x20, 0x20, 0x45, 0x00, 0x00, + 0x00, 0x16, 0x17, 0x00, 0x05, 0x0f, 0x17, 0x00, + 0x03, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x30, 0x2e, + 0x18, 0x00, 0x05, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x03, 0x19, 0x00, 0x00, 0x01, 0xfb, + 0x13, 0x00, 0x00, 0x02, 0xf0, 0x1e, 0x03, 0x45, + 0x00, 0x00, 0x00, 0x0f, 0x04, 0x17, 0x00, 0x03, + 0x19, 0x00, 0x00, 0x00, 0xe7, 0x12, 0x00, 0x00, + 0x00, 0x20, 0x20, 0x45, 0x00, 0x00, 0x00, 0x1c, + 0x17, 0x00, 0x05, 0x0f, 0x17, 0x00, 0x03, 0x19, + 0x00, 0x00, 0x00, 0xe7, 0x30, 0x09, 0x00, 0x00, + 0x03, 0xa7, 0x2f, 0x2c, 0x18, 0x00, 0x05, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x03, 0x19, + 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, 0x00, 0x02, + 0xe6, 0x1e, 0x03, 0x45, 0x00, 0x00, 0x00, 0x0f, + 0x04, 0x17, 0x00, 0x03, 0x19, 0x00, 0x00, 0x00, + 0xe7, 0x12, 0x00, 0x00, 0x00, 0x20, 0x20, 0x45, + 0x00, 0x00, 0x00, 0x16, 0x17, 0x00, 0x06, 0x0f, + 0x17, 0x00, 0x03, 0x19, 0x00, 0x00, 0x00, 0xe7, + 0x30, 0x2e, 0x18, 0x00, 0x06, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x17, 0x00, 0x03, 0x19, 0x00, 0x00, + 0x01, 0xfb, 0x13, 0x00, 0x00, 0x02, 0xe9, 0x1e, + 0x03, 0x45, 0x00, 0x00, 0x00, 0x0f, 0x04, 0x17, + 0x00, 0x03, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x12, + 0x00, 0x00, 0x00, 0x20, 0x20, 0x45, 0x00, 0x00, + 0x00, 0x1c, 0x17, 0x00, 0x06, 0x0f, 0x17, 0x00, + 0x03, 0x19, 0x00, 0x00, 0x00, 0xe7, 0x30, 0x09, + 0x00, 0x00, 0x03, 0xa7, 0x2f, 0x2c, 0x18, 0x00, + 0x06, 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, + 0x03, 0x0f, 0x13, 0x00, 0x00, 0x03, 0x9a, 0x37, + 0x06, 0x03, 0x33, 0x00, 0x00, 0x00, 0x27, 0x17, + 0x00, 0x05, 0x17, 0x00, 0x03, 0x19, 0x00, 0x00, + 0x00, 0xe7, 0x19, 0x00, 0x00, 0x03, 0xa5, 0x2e, + 0x18, 0x00, 0x05, 0x0b, 0x17, 0x00, 0x03, 0x19, + 0x00, 0x00, 0x00, 0xe7, 0x1a, 0x00, 0x00, 0x03, + 0xa6, 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, + 0x03, 0x19, 0x00, 0x00, 0x03, 0xa6, 0x03, 0x33, + 0x00, 0x00, 0x00, 0x20, 0x04, 0x17, 0x00, 0x03, + 0x19, 0x00, 0x00, 0x03, 0xa5, 0x17, 0x00, 0x05, + 0x1f, 0x03, 0x46, 0x00, 0x00, 0x00, 0x0d, 0x04, + 0x17, 0x00, 0x03, 0x19, 0x00, 0x00, 0x03, 0xa4, + 0x17, 0x00, 0x06, 0x1f, 0x33, 0x00, 0x00, 0x00, + 0x09, 0x0b, 0x18, 0x00, 0x04, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x17, 0x00, 0x03, 0x1a, 0x00, + 0x00, 0x03, 0xa6, 0x17, 0x00, 0x05, 0x17, 0x00, + 0x03, 0x1a, 0x00, 0x00, 0x03, 0xa5, 0x17, 0x00, + 0x06, 0x17, 0x00, 0x03, 0x1a, 0x00, 0x00, 0x03, + 0xa4, 0x17, 0x00, 0x03, 0x19, 0x00, 0x00, 0x03, + 0x94, 0x18, 0x00, 0x03, 0x36, 0xff, 0xff, 0xfe, + 0x0a, 0x17, 0x00, 0x03, 0x19, 0x00, 0x00, 0x03, + 0x94, 0x18, 0x00, 0x02, 0x36, 0xff, 0xff, 0xfd, + 0xda, 0x13, 0x00, 0x00, 0x00, 0xa5, 0x33, 0x00, + 0x00, 0x00, 0x13, 0x09, 0x00, 0x00, 0x03, 0x99, + 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa7, 0x37, 0x05, + 0x04, 0x36, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, + 0x00, 0x03, 0x8c, 0x18, 0x00, 0x00, 0x17, 0x00, + 0x00, 0x0a, 0x1f, 0x45, 0x00, 0x00, 0x00, 0xdd, + 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0x44, + 0x0a, 0x1f, 0x03, 0x45, 0x00, 0x00, 0x00, 0x10, + 0x04, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, + 0x44, 0x19, 0x00, 0x00, 0x01, 0x44, 0x0a, 0x1f, + 0x03, 0x45, 0x00, 0x00, 0x00, 0x15, 0x04, 0x17, + 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0x44, 0x19, + 0x00, 0x00, 0x01, 0x44, 0x19, 0x00, 0x00, 0x01, + 0x44, 0x0a, 0x1f, 0x45, 0x00, 0x00, 0x00, 0x8d, + 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0x44, + 0x18, 0x00, 0x04, 0x17, 0x00, 0x04, 0x19, 0x00, + 0x00, 0x01, 0x44, 0x18, 0x00, 0x05, 0x17, 0x00, + 0x05, 0x19, 0x00, 0x00, 0x01, 0x44, 0x18, 0x00, + 0x06, 0x17, 0x00, 0x04, 0x19, 0x00, 0x00, 0x01, + 0xfb, 0x13, 0x00, 0x00, 0x02, 0xf0, 0x1e, 0x03, + 0x45, 0x00, 0x00, 0x00, 0x0f, 0x04, 0x17, 0x00, + 0x05, 0x19, 0x00, 0x00, 0x01, 0xfb, 0x13, 0x00, + 0x00, 0x02, 0xec, 0x1e, 0x03, 0x45, 0x00, 0x00, + 0x00, 0x12, 0x04, 0x17, 0x00, 0x04, 0x19, 0x00, + 0x00, 0x00, 0xe7, 0x17, 0x00, 0x05, 0x19, 0x00, + 0x00, 0x00, 0xe7, 0x1e, 0x03, 0x45, 0x00, 0x00, + 0x00, 0x16, 0x04, 0x17, 0x00, 0x06, 0x19, 0x00, + 0x00, 0x03, 0xa5, 0x0f, 0x17, 0x00, 0x04, 0x19, + 0x00, 0x00, 0x00, 0xe7, 0x30, 0x2c, 0x0e, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x10, 0x17, 0x00, 0x06, + 0x17, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x44, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x44, 0x18, 0x00, 0x00, + 0x36, 0xff, 0xff, 0xff, 0x19, 0x0d, 0x38, 0x15, + 0x01, 0x48, 0x3e, 0x02, 0x3d, 0x00, 0x02, 0x0e, + 0x18, 0x00, 0x01, 0x13, 0x00, 0x00, 0x03, 0x8c, + 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, 0x0a, 0x1f, + 0x45, 0x00, 0x00, 0x00, 0x2a, 0x17, 0x00, 0x01, + 0x17, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x02, 0x76, + 0x17, 0x00, 0x01, 0x17, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x02, 0x77, 0x27, 0x18, 0x00, 0x01, 0x17, + 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, 0x44, 0x18, + 0x00, 0x00, 0x36, 0xff, 0xff, 0xff, 0xcc, 0x0d, + 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x0d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x03, 0x3d, 0x00, 0x01, + 0x13, 0x00, 0x00, 0x03, 0x8f, 0x0a, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x14, 0x0e, 0x13, 0x00, 0x00, + 0x03, 0xa8, 0x3a, 0x07, 0x06, 0x02, 0x14, 0x00, + 0x00, 0x03, 0x8f, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x03, 0x8f, 0x15, 0x02, 0x1b, + 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, 0x39, 0x09, + 0x00, 0x00, 0x02, 0xa6, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x04, 0x17, 0x00, 0x00, 0x38, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x03, 0x8e, 0x35, 0x00, + 0x00, 0x00, 0x27, 0x05, 0x04, 0x13, 0x00, 0x00, + 0x03, 0x8d, 0x13, 0x00, 0x00, 0x03, 0x8f, 0x15, + 0x02, 0x1c, 0x13, 0x00, 0x00, 0x03, 0x8d, 0x03, + 0x0f, 0x27, 0x14, 0x00, 0x00, 0x03, 0x8d, 0x38, + 0x15, 0x01, 0x48, 0x3e, 0x02, 0x3d, 0x00, 0x07, + 0x09, 0x00, 0x00, 0x00, 0x87, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x22, 0x3a, 0x07, 0x06, 0x03, 0x18, + 0x00, 0x01, 0x0e, 0x18, 0x00, 0x02, 0x09, 0x00, + 0x00, 0x00, 0x87, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0x22, 0x3a, 0x07, 0x06, 0x03, 0x18, 0x00, 0x03, + 0x09, 0x00, 0x00, 0x00, 0x87, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x22, 0x3a, 0x07, 0x06, 0x03, 0x18, + 0x00, 0x04, 0x0e, 0x18, 0x00, 0x05, 0x13, 0x00, + 0x00, 0x00, 0xa5, 0x33, 0x00, 0x00, 0x00, 0x13, + 0x09, 0x00, 0x00, 0x03, 0xa9, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xa7, 0x37, 0x05, 0x04, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x03, 0xaa, + 0x33, 0x00, 0x00, 0x00, 0x37, 0x13, 0x00, 0x00, + 0x00, 0x72, 0x19, 0x00, 0x00, 0x00, 0xd2, 0x13, + 0x00, 0x00, 0x03, 0xab, 0x09, 0x00, 0x00, 0x02, + 0xb8, 0x11, 0x13, 0x00, 0x00, 0x00, 0x22, 0x35, + 0x00, 0x00, 0x02, 0x71, 0x06, 0x05, 0x13, 0x00, + 0x00, 0x00, 0x72, 0x27, 0x0f, 0x17, 0x00, 0x04, + 0x35, 0x00, 0x00, 0x00, 0x27, 0x05, 0x04, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x87, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x22, 0x3a, + 0x07, 0x06, 0x03, 0x14, 0x00, 0x00, 0x03, 0x8e, + 0x13, 0x00, 0x00, 0x03, 0x8c, 0x18, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x0a, 0x1f, 0x45, 0x00, 0x00, + 0x01, 0x4b, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xfb, 0x13, 0x00, 0x00, 0x02, 0x78, 0x1e, + 0x45, 0x00, 0x00, 0x00, 0x3c, 0x17, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xe7, 0x17, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x02, 0x76, 0x0e, 0x09, 0x00, + 0x00, 0x02, 0xb8, 0x11, 0x13, 0x00, 0x00, 0x00, + 0x22, 0x35, 0x00, 0x00, 0x02, 0x71, 0x06, 0x05, + 0x27, 0x0f, 0x17, 0x00, 0x01, 0x35, 0x00, 0x00, + 0x00, 0x27, 0x05, 0x04, 0x17, 0x00, 0x02, 0x0f, + 0x27, 0x18, 0x00, 0x02, 0x36, 0x00, 0x00, 0x00, + 0xec, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, 0x01, + 0xfb, 0x13, 0x00, 0x00, 0x02, 0x7f, 0x1e, 0x45, + 0x00, 0x00, 0x00, 0x05, 0x36, 0x00, 0x00, 0x00, + 0xd4, 0x13, 0x00, 0x00, 0x03, 0xaa, 0x33, 0x00, + 0x00, 0x00, 0x60, 0x17, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x17, 0x00, 0x05, 0x1f, 0x45, + 0x00, 0x00, 0x00, 0x4f, 0x17, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x00, 0xdd, 0x17, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x02, 0x76, 0x17, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x02, 0x77, 0x27, 0x13, 0x00, 0x00, + 0x03, 0xac, 0x09, 0x00, 0x00, 0x03, 0xad, 0x09, + 0x00, 0x00, 0x00, 0xe1, 0x13, 0x00, 0x00, 0x00, + 0x22, 0x35, 0x00, 0x00, 0x02, 0x71, 0x06, 0x06, + 0x0f, 0x17, 0x00, 0x04, 0x35, 0x00, 0x00, 0x00, + 0x27, 0x05, 0x04, 0x17, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x00, 0xdd, 0x18, 0x00, 0x05, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x02, 0x77, 0x0f, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0x2a, 0x17, 0x00, 0x00, 0x19, 0x00, 0x00, + 0x01, 0xfb, 0x09, 0x00, 0x00, 0x02, 0x70, 0x10, + 0x13, 0x00, 0x00, 0x00, 0x22, 0x35, 0x00, 0x00, + 0x02, 0x71, 0x06, 0x04, 0x0f, 0x17, 0x00, 0x03, + 0x35, 0x00, 0x00, 0x00, 0x27, 0x05, 0x04, 0x36, + 0x00, 0x00, 0x00, 0x31, 0x17, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x01, 0xfb, 0x09, 0x00, 0x00, 0x02, + 0x70, 0x10, 0x13, 0x00, 0x00, 0x00, 0x22, 0x35, + 0x00, 0x00, 0x02, 0x71, 0x06, 0x04, 0x0e, 0x17, + 0x00, 0x00, 0x35, 0x00, 0x00, 0x02, 0x98, 0x06, + 0x02, 0x27, 0x0f, 0x17, 0x00, 0x03, 0x35, 0x00, + 0x00, 0x00, 0x27, 0x05, 0x04, 0x17, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x01, 0x44, 0x18, 0x00, 0x00, + 0x36, 0xff, 0xff, 0xfe, 0xab, 0x17, 0x00, 0x02, + 0x09, 0x00, 0x00, 0x02, 0x73, 0x10, 0x13, 0x00, + 0x00, 0x00, 0x22, 0x35, 0x00, 0x00, 0x02, 0x71, + 0x06, 0x04, 0x17, 0x00, 0x01, 0x27, 0x18, 0x00, + 0x01, 0x13, 0x00, 0x00, 0x00, 0xa5, 0x33, 0x00, + 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0xae, + 0x0e, 0x17, 0x00, 0x03, 0x19, 0x00, 0x00, 0x00, + 0xd2, 0x35, 0x00, 0x00, 0x00, 0x74, 0x06, 0x02, + 0x27, 0x09, 0x00, 0x00, 0x03, 0xaf, 0x27, 0x0e, + 0x13, 0x00, 0x00, 0x03, 0x8e, 0x19, 0x00, 0x00, + 0x00, 0xd2, 0x35, 0x00, 0x00, 0x00, 0x74, 0x06, + 0x02, 0x27, 0x09, 0x00, 0x00, 0x03, 0xb0, 0x27, + 0x0e, 0x17, 0x00, 0x01, 0x19, 0x00, 0x00, 0x00, + 0xd2, 0x35, 0x00, 0x00, 0x00, 0x74, 0x06, 0x02, + 0x27, 0x18, 0x00, 0x06, 0x13, 0x00, 0x00, 0x03, + 0xaa, 0x33, 0x00, 0x00, 0x00, 0x22, 0x17, 0x00, + 0x06, 0x09, 0x00, 0x00, 0x03, 0xb1, 0x0e, 0x17, + 0x00, 0x04, 0x19, 0x00, 0x00, 0x00, 0xd2, 0x35, + 0x00, 0x00, 0x00, 0x74, 0x06, 0x02, 0x27, 0x27, + 0x18, 0x00, 0x06, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x06, 0x09, 0x00, 0x00, 0x03, 0xb2, + 0x0e, 0x12, 0x00, 0x00, 0x00, 0x20, 0x13, 0x00, + 0x00, 0x03, 0xaa, 0x33, 0x00, 0x00, 0x00, 0x0a, + 0x12, 0x00, 0x00, 0x00, 0x08, 0x36, 0x00, 0x00, + 0x00, 0x01, 0x0e, 0x27, 0x35, 0x00, 0x00, 0x00, + 0x74, 0x06, 0x02, 0x27, 0x09, 0x00, 0x00, 0x03, + 0xb3, 0x27, 0x0e, 0x17, 0x00, 0x03, 0x19, 0x00, + 0x00, 0x00, 0xd2, 0x13, 0x00, 0x00, 0x03, 0x8e, + 0x19, 0x00, 0x00, 0x00, 0xd2, 0x27, 0x17, 0x00, + 0x01, 0x19, 0x00, 0x00, 0x00, 0xd2, 0x27, 0x17, + 0x00, 0x04, 0x19, 0x00, 0x00, 0x00, 0xd2, 0x27, + 0x12, 0x00, 0x00, 0x00, 0x20, 0x27, 0x13, 0x00, + 0x00, 0x03, 0xaa, 0x33, 0x00, 0x00, 0x00, 0x0a, + 0x12, 0x00, 0x00, 0x00, 0x08, 0x36, 0x00, 0x00, + 0x00, 0x01, 0x0e, 0x27, 0x35, 0x00, 0x00, 0x00, + 0x74, 0x06, 0x02, 0x27, 0x27, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xa7, 0x37, 0x05, 0x04, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x11, 0x13, 0x00, 0x00, 0x03, + 0xaa, 0x33, 0x00, 0x00, 0x00, 0x06, 0x0f, 0x36, + 0x00, 0x00, 0x00, 0x01, 0x0e, 0x27, 0x13, 0x00, + 0x00, 0x03, 0xb4, 0x09, 0x00, 0x00, 0x03, 0xb5, + 0x11, 0x13, 0x00, 0x00, 0x00, 0x22, 0x35, 0x00, + 0x00, 0x02, 0x71, 0x06, 0x05, 0x17, 0x00, 0x03, + 0x19, 0x00, 0x00, 0x00, 0xd2, 0x13, 0x00, 0x00, + 0x03, 0xb6, 0x09, 0x00, 0x00, 0x03, 0xb5, 0x11, + 0x13, 0x00, 0x00, 0x00, 0x22, 0x35, 0x00, 0x00, + 0x02, 0x71, 0x06, 0x05, 0x27, 0x17, 0x00, 0x03, + 0x27, 0x13, 0x00, 0x00, 0x03, 0x8e, 0x19, 0x00, + 0x00, 0x00, 0xd2, 0x13, 0x00, 0x00, 0x03, 0xb7, + 0x09, 0x00, 0x00, 0x03, 0xb5, 0x11, 0x13, 0x00, + 0x00, 0x00, 0x22, 0x35, 0x00, 0x00, 0x02, 0x71, + 0x06, 0x05, 0x27, 0x13, 0x00, 0x00, 0x03, 0x8e, + 0x27, 0x17, 0x00, 0x01, 0x19, 0x00, 0x00, 0x00, + 0xd2, 0x13, 0x00, 0x00, 0x03, 0xb8, 0x09, 0x00, + 0x00, 0x03, 0xb5, 0x11, 0x13, 0x00, 0x00, 0x00, + 0x22, 0x35, 0x00, 0x00, 0x02, 0x71, 0x06, 0x05, + 0x27, 0x17, 0x00, 0x01, 0x27, 0x13, 0x00, 0x00, + 0x03, 0xaa, 0x33, 0x00, 0x00, 0x00, 0x28, 0x17, + 0x00, 0x04, 0x19, 0x00, 0x00, 0x00, 0xd2, 0x13, + 0x00, 0x00, 0x03, 0xb9, 0x09, 0x00, 0x00, 0x03, + 0xb5, 0x11, 0x13, 0x00, 0x00, 0x00, 0x22, 0x35, + 0x00, 0x00, 0x02, 0x71, 0x06, 0x05, 0x17, 0x00, + 0x04, 0x27, 0x36, 0x00, 0x00, 0x00, 0x05, 0x09, + 0x00, 0x00, 0x00, 0x87, 0x27, 0x38, 0x15, 0x01, + 0x48, 0x3e, 0x06, 0x3d, 0x00, 0x01, 0x15, 0x02, + 0x0f, 0x13, 0x00, 0x00, 0x03, 0xba, 0x3a, 0x07, + 0x06, 0x03, 0x18, 0x00, 0x00, 0x15, 0x05, 0x15, + 0x04, 0x15, 0x03, 0x17, 0x00, 0x00, 0x09, 0x00, + 0x00, 0x00, 0xe1, 0x13, 0x00, 0x00, 0x03, 0xbb, + 0x37, 0x06, 0x06, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x06, 0x3d, 0x00, 0x01, 0x15, 0x02, 0x0f, 0x13, + 0x00, 0x00, 0x03, 0xbc, 0x3a, 0x07, 0x06, 0x03, + 0x18, 0x00, 0x00, 0x15, 0x05, 0x15, 0x04, 0x15, + 0x03, 0x17, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0xe1, 0x13, 0x00, 0x00, 0x03, 0xbb, 0x37, 0x06, + 0x06, 0x38, 0x15, 0x01, 0x48, 0x3e, 0x02, 0x0e, + 0x13, 0x00, 0x00, 0x03, 0xbd, 0x37, 0x05, 0x03, + 0x0e, 0x13, 0x00, 0x00, 0x03, 0xbe, 0x37, 0x05, + 0x03, 0x0e, 0x13, 0x00, 0x00, 0x03, 0xbf, 0x37, + 0x05, 0x03, 0x0d, 0x38, 0x15, 0x01, 0x48, 0x3e, + 0x06, 0x3d, 0x00, 0x03, 0x0c, 0x18, 0x00, 0x00, + 0x0e, 0x13, 0x00, 0x00, 0x03, 0xc0, 0x37, 0x05, + 0x03, 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, + 0x58, 0x06, 0x02, 0x33, 0x00, 0x00, 0x02, 0xf1, + 0x42, 0x00, 0x00, 0x02, 0xd6, 0x15, 0x03, 0x13, + 0x00, 0x00, 0x03, 0xc1, 0x2c, 0x0e, 0x1f, 0x14, + 0x00, 0x00, 0x00, 0xa5, 0x15, 0x03, 0x13, 0x00, + 0x00, 0x03, 0xc2, 0x2c, 0x0e, 0x1f, 0x14, 0x00, + 0x00, 0x03, 0xaa, 0x15, 0x03, 0x13, 0x00, 0x00, + 0x03, 0xc3, 0x2c, 0x0e, 0x1f, 0x14, 0x00, 0x00, + 0x02, 0x4d, 0x15, 0x03, 0x13, 0x00, 0x00, 0x03, + 0xc4, 0x2c, 0x0e, 0x1f, 0x14, 0x00, 0x00, 0x02, + 0x4f, 0x15, 0x03, 0x13, 0x00, 0x00, 0x03, 0xc5, + 0x2c, 0x0e, 0x1f, 0x14, 0x00, 0x00, 0x02, 0x52, + 0x15, 0x03, 0x13, 0x00, 0x00, 0x03, 0xc6, 0x2c, + 0x0e, 0x1f, 0x14, 0x00, 0x00, 0x02, 0x2a, 0x15, + 0x03, 0x13, 0x00, 0x00, 0x03, 0xc7, 0x2c, 0x0e, + 0x1f, 0x14, 0x00, 0x00, 0x00, 0xbb, 0x15, 0x03, + 0x13, 0x00, 0x00, 0x03, 0xc8, 0x2c, 0x0e, 0x1f, + 0x14, 0x00, 0x00, 0x00, 0x88, 0x15, 0x03, 0x13, + 0x00, 0x00, 0x03, 0xc9, 0x2c, 0x0e, 0x1f, 0x14, + 0x00, 0x00, 0x00, 0xd6, 0x0b, 0x14, 0x00, 0x00, + 0x01, 0x0a, 0x0b, 0x14, 0x00, 0x00, 0x01, 0xc0, + 0x15, 0x02, 0x0f, 0x13, 0x00, 0x00, 0x03, 0xca, + 0x37, 0x05, 0x04, 0x0e, 0x13, 0x00, 0x00, 0x03, + 0xcb, 0x37, 0x05, 0x03, 0x0e, 0x13, 0x00, 0x00, + 0x03, 0xbd, 0x37, 0x05, 0x03, 0x15, 0x03, 0x13, + 0x00, 0x00, 0x03, 0xcc, 0x2c, 0x0e, 0x1f, 0x45, + 0x00, 0x00, 0x00, 0x10, 0x15, 0x03, 0x0f, 0x13, + 0x00, 0x00, 0x03, 0xcd, 0x37, 0x05, 0x04, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x15, 0x04, 0x39, 0x09, + 0x00, 0x00, 0x00, 0x06, 0x1e, 0x45, 0x00, 0x00, + 0x00, 0xa3, 0x15, 0x04, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0x25, 0x3a, 0x07, 0x06, 0x03, 0x18, 0x00, + 0x01, 0x0c, 0x18, 0x00, 0x02, 0x09, 0x00, 0x00, + 0x03, 0xce, 0x0f, 0x17, 0x00, 0x01, 0x35, 0x00, + 0x00, 0x02, 0x58, 0x06, 0x03, 0x33, 0x00, 0x00, + 0x00, 0x47, 0x15, 0x03, 0x13, 0x00, 0x00, 0x03, + 0xcf, 0x2c, 0x0e, 0x1f, 0x45, 0x00, 0x00, 0x00, + 0x19, 0x0e, 0x15, 0x02, 0x35, 0x00, 0x00, 0x02, + 0x5c, 0x06, 0x02, 0x33, 0x00, 0x00, 0x00, 0x0a, + 0x15, 0x02, 0x18, 0x00, 0x02, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x17, 0x00, 0x01, 0x17, 0x00, 0x02, + 0x10, 0x13, 0x00, 0x00, 0x03, 0xd0, 0x37, 0x05, + 0x05, 0x0e, 0x17, 0x00, 0x01, 0x35, 0x00, 0x00, + 0x02, 0x5a, 0x05, 0x03, 0x36, 0x00, 0x00, 0x00, + 0x34, 0x09, 0x00, 0x00, 0x03, 0xd1, 0x15, 0x04, + 0x27, 0x09, 0x00, 0x00, 0x03, 0xd2, 0x27, 0x13, + 0x00, 0x00, 0x00, 0x97, 0x19, 0x00, 0x00, 0x02, + 0x62, 0x0f, 0x13, 0x00, 0x00, 0x00, 0x97, 0x35, + 0x00, 0x00, 0x02, 0x63, 0x06, 0x03, 0x27, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0xa7, 0x37, 0x05, 0x04, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x13, 0x00, + 0x00, 0x03, 0xd3, 0x37, 0x05, 0x03, 0x0e, 0x13, + 0x00, 0x00, 0x03, 0xd4, 0x37, 0x06, 0x02, 0x18, + 0x00, 0x00, 0x0e, 0x13, 0x00, 0x00, 0x03, 0xc0, + 0x37, 0x05, 0x03, 0x15, 0x05, 0x39, 0x09, 0x00, + 0x00, 0x00, 0x06, 0x1e, 0x45, 0x00, 0x00, 0x01, + 0x22, 0x15, 0x05, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0x25, 0x3a, 0x07, 0x06, 0x03, 0x18, 0x00, 0x01, + 0x09, 0x00, 0x00, 0x03, 0xce, 0x0f, 0x17, 0x00, + 0x01, 0x35, 0x00, 0x00, 0x02, 0x58, 0x06, 0x03, + 0x33, 0x00, 0x00, 0x00, 0xca, 0x17, 0x00, 0x00, + 0x0f, 0x17, 0x00, 0x01, 0x35, 0x00, 0x00, 0x02, + 0x7e, 0x05, 0x04, 0x0e, 0x17, 0x00, 0x01, 0x35, + 0x00, 0x00, 0x02, 0x5a, 0x05, 0x03, 0x15, 0x03, + 0x13, 0x00, 0x00, 0x03, 0xd5, 0x2c, 0x0e, 0x1f, + 0x45, 0x00, 0x00, 0x00, 0xd1, 0x15, 0x05, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0x25, 0x35, 0x00, 0x00, + 0x03, 0xd6, 0x06, 0x03, 0x18, 0x00, 0x02, 0x17, + 0x00, 0x02, 0x33, 0x00, 0x00, 0x00, 0x54, 0x17, + 0x00, 0x02, 0x10, 0x1b, 0x12, 0x00, 0x00, 0x00, + 0x49, 0x2e, 0x15, 0x05, 0x10, 0x13, 0x00, 0x00, + 0x00, 0x25, 0x35, 0x00, 0x00, 0x03, 0xd7, 0x06, + 0x04, 0x2d, 0x33, 0x00, 0x00, 0x00, 0x63, 0x09, + 0x00, 0x00, 0x03, 0xd8, 0x15, 0x05, 0x27, 0x09, + 0x00, 0x00, 0x03, 0xd2, 0x27, 0x13, 0x00, 0x00, + 0x00, 0x97, 0x19, 0x00, 0x00, 0x02, 0x62, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0x97, 0x35, 0x00, 0x00, + 0x02, 0x63, 0x06, 0x03, 0x27, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xa7, 0x37, 0x05, 0x04, 0x36, 0x00, + 0x00, 0x00, 0x2f, 0x09, 0x00, 0x00, 0x03, 0xd9, + 0x15, 0x05, 0x27, 0x09, 0x00, 0x00, 0x03, 0xd2, + 0x27, 0x13, 0x00, 0x00, 0x00, 0x97, 0x19, 0x00, + 0x00, 0x02, 0x62, 0x0f, 0x13, 0x00, 0x00, 0x00, + 0x97, 0x35, 0x00, 0x00, 0x02, 0x63, 0x06, 0x03, + 0x27, 0x0f, 0x13, 0x00, 0x00, 0x00, 0xa7, 0x37, + 0x05, 0x04, 0x36, 0x00, 0x00, 0x00, 0x2f, 0x09, + 0x00, 0x00, 0x03, 0xda, 0x15, 0x05, 0x27, 0x09, + 0x00, 0x00, 0x03, 0xd2, 0x27, 0x13, 0x00, 0x00, + 0x00, 0x97, 0x19, 0x00, 0x00, 0x02, 0x62, 0x0f, + 0x13, 0x00, 0x00, 0x00, 0x97, 0x35, 0x00, 0x00, + 0x02, 0x63, 0x06, 0x03, 0x27, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0xa7, 0x37, 0x05, 0x04, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x43, 0x01, 0x0c, 0x36, 0x00, + 0x00, 0x00, 0x01, 0x0b, 0x0e, 0x15, 0x02, 0x35, + 0x00, 0x00, 0x02, 0x5a, 0x05, 0x03, 0x45, 0x00, + 0x00, 0x00, 0x2a, 0x44, 0x36, 0x00, 0x00, 0x00, + 0x24, 0x09, 0x00, 0x00, 0x03, 0xdb, 0x15, 0x02, + 0x19, 0x00, 0x00, 0x00, 0x9d, 0x27, 0x09, 0x00, + 0x00, 0x03, 0xd2, 0x27, 0x15, 0x02, 0x19, 0x00, + 0x00, 0x00, 0x76, 0x27, 0x0f, 0x13, 0x00, 0x00, + 0x00, 0x76, 0x37, 0x05, 0x04, 0x17, 0x00, 0x00, + 0x38, 0x12, 0x00, 0x00, 0x00, 0x80, 0x14, 0x00, + 0x00, 0x00, 0x7f, 0x12, 0x00, 0x00, 0x00, 0x81, + 0x14, 0x00, 0x00, 0x00, 0x77, 0x12, 0x00, 0x00, + 0x00, 0x82, 0x14, 0x00, 0x00, 0x00, 0x7d, 0x12, + 0x00, 0x00, 0x00, 0x83, 0x14, 0x00, 0x00, 0x00, + 0x08, 0x12, 0x00, 0x00, 0x00, 0x84, 0x14, 0x00, + 0x00, 0x00, 0x6f, 0x12, 0x00, 0x00, 0x00, 0x85, + 0x14, 0x00, 0x00, 0x00, 0x2a, 0x12, 0x00, 0x00, + 0x00, 0x86, 0x14, 0x00, 0x00, 0x00, 0x2c, 0x12, + 0x00, 0x00, 0x00, 0x87, 0x14, 0x00, 0x00, 0x00, + 0x2e, 0x12, 0x00, 0x00, 0x00, 0x88, 0x14, 0x00, + 0x00, 0x00, 0x30, 0x12, 0x00, 0x00, 0x00, 0x89, + 0x14, 0x00, 0x00, 0x00, 0x32, 0x12, 0x00, 0x00, + 0x00, 0x8a, 0x14, 0x00, 0x00, 0x00, 0x34, 0x12, + 0x00, 0x00, 0x00, 0x8b, 0x14, 0x00, 0x00, 0x00, + 0x36, 0x12, 0x00, 0x00, 0x00, 0x8c, 0x14, 0x00, + 0x00, 0x00, 0x38, 0x12, 0x00, 0x00, 0x00, 0x8d, + 0x14, 0x00, 0x00, 0x00, 0x3a, 0x12, 0x00, 0x00, + 0x00, 0x8e, 0x14, 0x00, 0x00, 0x00, 0x3c, 0x12, + 0x00, 0x00, 0x00, 0x8f, 0x14, 0x00, 0x00, 0x00, + 0x3e, 0x12, 0x00, 0x00, 0x00, 0x90, 0x14, 0x00, + 0x00, 0x00, 0x40, 0x12, 0x00, 0x00, 0x00, 0x91, + 0x14, 0x00, 0x00, 0x00, 0x42, 0x12, 0x00, 0x00, + 0x00, 0x92, 0x14, 0x00, 0x00, 0x00, 0x44, 0x12, + 0x00, 0x00, 0x00, 0x93, 0x14, 0x00, 0x00, 0x00, + 0x46, 0x12, 0x00, 0x00, 0x00, 0x94, 0x14, 0x00, + 0x00, 0x00, 0x48, 0x12, 0x00, 0x00, 0x00, 0x95, + 0x14, 0x00, 0x00, 0x00, 0x4a, 0x12, 0x00, 0x00, + 0x00, 0x96, 0x14, 0x00, 0x00, 0x00, 0x4c, 0x12, + 0x00, 0x00, 0x00, 0x97, 0x14, 0x00, 0x00, 0x00, + 0x4e, 0x12, 0x00, 0x00, 0x00, 0x98, 0x14, 0x00, + 0x00, 0x00, 0x50, 0x12, 0x00, 0x00, 0x00, 0x99, + 0x14, 0x00, 0x00, 0x00, 0x52, 0x12, 0x00, 0x00, + 0x00, 0x9a, 0x14, 0x00, 0x00, 0x00, 0x54, 0x12, + 0x00, 0x00, 0x00, 0x9b, 0x14, 0x00, 0x00, 0x00, + 0x56, 0x12, 0x00, 0x00, 0x00, 0x9c, 0x14, 0x00, + 0x00, 0x00, 0x58, 0x12, 0x00, 0x00, 0x00, 0x9d, + 0x14, 0x00, 0x00, 0x00, 0x5a, 0x12, 0x00, 0x00, + 0x00, 0x9e, 0x14, 0x00, 0x00, 0x00, 0x5c, 0x12, + 0x00, 0x00, 0x00, 0x9f, 0x14, 0x00, 0x00, 0x00, + 0x5e, 0x12, 0x00, 0x00, 0x00, 0xa0, 0x14, 0x00, + 0x00, 0x00, 0x60, 0x12, 0x00, 0x00, 0x00, 0xa1, + 0x14, 0x00, 0x00, 0x00, 0x62, 0x12, 0x00, 0x00, + 0x00, 0xa2, 0x14, 0x00, 0x00, 0x00, 0x64, 0x12, + 0x00, 0x00, 0x00, 0xa3, 0x14, 0x00, 0x00, 0x00, + 0x66, 0x12, 0x00, 0x00, 0x00, 0xa4, 0x14, 0x00, + 0x00, 0x00, 0x68, 0x12, 0x00, 0x00, 0x00, 0xa5, + 0x14, 0x00, 0x00, 0x00, 0x6a, 0x12, 0x00, 0x00, + 0x00, 0xa6, 0x14, 0x00, 0x00, 0x00, 0x6c, 0x12, + 0x00, 0x00, 0x00, 0xa7, 0x14, 0x00, 0x00, 0x00, + 0x6e, 0x12, 0x00, 0x00, 0x00, 0xa8, 0x14, 0x00, + 0x00, 0x00, 0x0a, 0x12, 0x00, 0x00, 0x00, 0xa9, + 0x14, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x00, 0x00, + 0x00, 0xaa, 0x14, 0x00, 0x00, 0x00, 0x0d, 0x12, + 0x00, 0x00, 0x00, 0xab, 0x14, 0x00, 0x00, 0x00, + 0x0e, 0x12, 0x00, 0x00, 0x00, 0xac, 0x14, 0x00, + 0x00, 0x00, 0x0f, 0x12, 0x00, 0x00, 0x00, 0xad, + 0x14, 0x00, 0x00, 0x00, 0x10, 0x12, 0x00, 0x00, + 0x00, 0xae, 0x14, 0x00, 0x00, 0x00, 0x11, 0x12, + 0x00, 0x00, 0x00, 0xaf, 0x14, 0x00, 0x00, 0x00, + 0x12, 0x12, 0x00, 0x00, 0x00, 0xb0, 0x14, 0x00, + 0x00, 0x00, 0x13, 0x12, 0x00, 0x00, 0x00, 0xb1, + 0x14, 0x00, 0x00, 0x00, 0x14, 0x12, 0x00, 0x00, + 0x00, 0xb2, 0x14, 0x00, 0x00, 0x00, 0x15, 0x12, + 0x00, 0x00, 0x00, 0xb3, 0x14, 0x00, 0x00, 0x00, + 0x16, 0x12, 0x00, 0x00, 0x00, 0xb4, 0x14, 0x00, + 0x00, 0x00, 0x17, 0x12, 0x00, 0x00, 0x00, 0xb5, + 0x14, 0x00, 0x00, 0x00, 0x18, 0x12, 0x00, 0x00, + 0x00, 0xb6, 0x14, 0x00, 0x00, 0x00, 0x19, 0x12, + 0x00, 0x00, 0x00, 0xb7, 0x14, 0x00, 0x00, 0x00, + 0x1a, 0x12, 0x00, 0x00, 0x00, 0xb8, 0x14, 0x00, + 0x00, 0x00, 0x1b, 0x12, 0x00, 0x00, 0x00, 0xb9, + 0x14, 0x00, 0x00, 0x00, 0x1c, 0x12, 0x00, 0x00, + 0x00, 0xba, 0x14, 0x00, 0x00, 0x00, 0x20, 0x12, + 0x00, 0x00, 0x00, 0xbb, 0x14, 0x00, 0x00, 0x00, + 0x1f, 0x12, 0x00, 0x00, 0x00, 0xbc, 0x14, 0x00, + 0x00, 0x00, 0x1d, 0x12, 0x00, 0x00, 0x00, 0xbd, + 0x14, 0x00, 0x00, 0x00, 0x1e, 0x12, 0x00, 0x00, + 0x00, 0xbe, 0x14, 0x00, 0x00, 0x00, 0x09, 0x12, + 0x00, 0x00, 0x00, 0xbf, 0x14, 0x00, 0x00, 0x00, + 0x0b, 0x0e, 0x14, 0x00, 0x00, 0x02, 0x41, 0x0f, + 0x14, 0x00, 0x00, 0x02, 0x26, 0x10, 0x14, 0x00, + 0x00, 0x02, 0x32, 0x11, 0x14, 0x00, 0x00, 0x02, + 0x1d, 0x12, 0x00, 0x00, 0x00, 0x04, 0x14, 0x00, + 0x00, 0x02, 0x16, 0x12, 0x00, 0x00, 0x00, 0x05, + 0x14, 0x00, 0x00, 0x02, 0x10, 0x12, 0x00, 0x00, + 0x00, 0x06, 0x14, 0x00, 0x00, 0x02, 0x0b, 0x12, + 0x00, 0x00, 0x00, 0x07, 0x14, 0x00, 0x00, 0x02, + 0x06, 0x12, 0x00, 0x00, 0x00, 0x08, 0x14, 0x00, + 0x00, 0x01, 0xfa, 0x12, 0x00, 0x00, 0x00, 0x09, + 0x14, 0x00, 0x00, 0x02, 0x02, 0x12, 0x00, 0x00, + 0x00, 0x0a, 0x14, 0x00, 0x00, 0x00, 0xc2, 0x12, + 0x00, 0x00, 0x00, 0x0b, 0x14, 0x00, 0x00, 0x00, + 0xc9, 0x12, 0x00, 0x00, 0x00, 0x0c, 0x14, 0x00, + 0x00, 0x00, 0xca, 0x12, 0x00, 0x00, 0x00, 0x0d, + 0x14, 0x00, 0x00, 0x00, 0xcb, 0x12, 0x00, 0x00, + 0x00, 0x0e, 0x14, 0x00, 0x00, 0x00, 0xc3, 0x12, + 0x00, 0x00, 0x00, 0x0f, 0x14, 0x00, 0x00, 0x00, + 0xc4, 0x12, 0x00, 0x00, 0x00, 0x10, 0x14, 0x00, + 0x00, 0x00, 0xc5, 0x12, 0x00, 0x00, 0x00, 0x11, + 0x14, 0x00, 0x00, 0x00, 0xc6, 0x12, 0x00, 0x00, + 0x00, 0x12, 0x14, 0x00, 0x00, 0x00, 0xbe, 0x12, + 0x00, 0x00, 0x00, 0x13, 0x14, 0x00, 0x00, 0x00, + 0xbf, 0x12, 0x00, 0x00, 0x00, 0x14, 0x14, 0x00, + 0x00, 0x00, 0xc0, 0x12, 0x00, 0x00, 0x00, 0x15, + 0x14, 0x00, 0x00, 0x00, 0xc1, 0x12, 0x00, 0x00, + 0x00, 0x16, 0x14, 0x00, 0x00, 0x03, 0xdc, 0x12, + 0x00, 0x00, 0x00, 0x17, 0x14, 0x00, 0x00, 0x03, + 0xdd, 0x12, 0x00, 0x00, 0x00, 0x18, 0x14, 0x00, + 0x00, 0x03, 0xde, 0x12, 0x00, 0x00, 0x00, 0x19, + 0x14, 0x00, 0x00, 0x03, 0xdf, 0x12, 0x00, 0x00, + 0x00, 0x1a, 0x14, 0x00, 0x00, 0x02, 0x3f, 0x12, + 0x00, 0x00, 0x00, 0x1b, 0x14, 0x00, 0x00, 0x02, + 0x35, 0x12, 0x00, 0x00, 0x00, 0x1c, 0x14, 0x00, + 0x00, 0x00, 0xc7, 0x12, 0x00, 0x00, 0x00, 0x1d, + 0x14, 0x00, 0x00, 0x00, 0xc8, 0x12, 0x00, 0x00, + 0x00, 0x1e, 0x14, 0x00, 0x00, 0x01, 0xf0, 0x0e, + 0x14, 0x00, 0x00, 0x01, 0x74, 0x0f, 0x14, 0x00, + 0x00, 0x01, 0x78, 0x10, 0x14, 0x00, 0x00, 0x00, + 0xcf, 0x11, 0x14, 0x00, 0x00, 0x01, 0x7f, 0x12, + 0x00, 0x00, 0x00, 0x04, 0x14, 0x00, 0x00, 0x01, + 0xb9, 0x12, 0x00, 0x00, 0x00, 0x05, 0x14, 0x00, + 0x00, 0x01, 0xbb, 0x12, 0x00, 0x00, 0x00, 0x06, + 0x14, 0x00, 0x00, 0x01, 0xc5, 0x12, 0x00, 0x00, + 0x00, 0x07, 0x14, 0x00, 0x00, 0x01, 0xc8, 0x12, + 0x00, 0x00, 0x00, 0x08, 0x14, 0x00, 0x00, 0x01, + 0xd3, 0x12, 0x00, 0x00, 0x00, 0x09, 0x14, 0x00, + 0x00, 0x01, 0x81, 0x12, 0x00, 0x00, 0x00, 0x0a, + 0x14, 0x00, 0x00, 0x01, 0x8c, 0x12, 0x00, 0x00, + 0x00, 0x0b, 0x14, 0x00, 0x00, 0x01, 0x91, 0x12, + 0x00, 0x00, 0x00, 0x0c, 0x14, 0x00, 0x00, 0x01, + 0x9c, 0x12, 0x00, 0x00, 0x00, 0x0d, 0x14, 0x00, + 0x00, 0x01, 0xa1, 0x12, 0x00, 0x00, 0x00, 0x0e, + 0x14, 0x00, 0x00, 0x01, 0xb1, 0x12, 0x00, 0x00, + 0x00, 0x0f, 0x14, 0x00, 0x00, 0x01, 0xc1, 0x12, + 0x00, 0x00, 0x00, 0x10, 0x14, 0x00, 0x00, 0x01, + 0x94, 0x12, 0x00, 0x00, 0x00, 0x11, 0x14, 0x00, + 0x00, 0x01, 0xb3, 0x0e, 0x14, 0x00, 0x00, 0x03, + 0xe0, 0x0f, 0x14, 0x00, 0x00, 0x01, 0xf5, 0x10, + 0x14, 0x00, 0x00, 0x01, 0xad, 0x11, 0x14, 0x00, + 0x00, 0x01, 0xe4, 0x12, 0x00, 0x00, 0x00, 0x04, + 0x14, 0x00, 0x00, 0x01, 0xe9, 0x12, 0x00, 0x00, + 0x00, 0x05, 0x14, 0x00, 0x00, 0x01, 0xe1, 0x12, + 0x00, 0x00, 0x00, 0x06, 0x14, 0x00, 0x00, 0x01, + 0xed, 0x12, 0x00, 0x00, 0x00, 0x07, 0x14, 0x00, + 0x00, 0x01, 0xf1, 0x12, 0x00, 0x00, 0x00, 0x0b, + 0x14, 0x00, 0x00, 0x01, 0xeb, 0x0e, 0x13, 0x00, + 0x00, 0x01, 0x3c, 0x3a, 0x07, 0x05, 0x03, 0x13, + 0x00, 0x00, 0x03, 0xe1, 0x13, 0x00, 0x00, 0x01, + 0x3c, 0x19, 0x00, 0x00, 0x03, 0xe2, 0x1a, 0x00, + 0x00, 0x00, 0xd1, 0x13, 0x00, 0x00, 0x03, 0xe3, + 0x13, 0x00, 0x00, 0x01, 0x3c, 0x19, 0x00, 0x00, + 0x03, 0xe2, 0x1a, 0x00, 0x00, 0x00, 0xdb, 0x13, + 0x00, 0x00, 0x03, 0xe4, 0x13, 0x00, 0x00, 0x01, + 0x3c, 0x19, 0x00, 0x00, 0x03, 0xe2, 0x1a, 0x00, + 0x00, 0x01, 0x93, 0x13, 0x00, 0x00, 0x03, 0xe5, + 0x13, 0x00, 0x00, 0x01, 0x3c, 0x19, 0x00, 0x00, + 0x03, 0xe2, 0x1a, 0x00, 0x00, 0x01, 0x87, 0x13, + 0x00, 0x00, 0x03, 0xe6, 0x13, 0x00, 0x00, 0x01, + 0x3c, 0x19, 0x00, 0x00, 0x03, 0xe2, 0x1a, 0x00, + 0x00, 0x01, 0x89, 0x13, 0x00, 0x00, 0x03, 0xe7, + 0x13, 0x00, 0x00, 0x01, 0x3c, 0x19, 0x00, 0x00, + 0x03, 0xe2, 0x1a, 0x00, 0x00, 0x01, 0x8b, 0x13, + 0x00, 0x00, 0x03, 0xe8, 0x13, 0x00, 0x00, 0x01, + 0x3c, 0x19, 0x00, 0x00, 0x03, 0xe2, 0x1a, 0x00, + 0x00, 0x01, 0x83, 0x13, 0x00, 0x00, 0x03, 0xe9, + 0x13, 0x00, 0x00, 0x01, 0x3c, 0x19, 0x00, 0x00, + 0x03, 0xe2, 0x1a, 0x00, 0x00, 0x01, 0x8e, 0x13, + 0x00, 0x00, 0x03, 0xea, 0x13, 0x00, 0x00, 0x01, + 0x3c, 0x19, 0x00, 0x00, 0x03, 0xe2, 0x1a, 0x00, + 0x00, 0x01, 0xb6, 0x0a, 0x14, 0x00, 0x00, 0x01, + 0x3d, 0x0f, 0x14, 0x00, 0x00, 0x01, 0x52, 0x10, + 0x14, 0x00, 0x00, 0x01, 0x5c, 0x12, 0xc0, 0x01, + 0x4a, 0x53, 0x14, 0x00, 0x00, 0x03, 0xb4, 0x0e, + 0x14, 0x00, 0x00, 0x03, 0xb6, 0x0f, 0x14, 0x00, + 0x00, 0x03, 0xb7, 0x10, 0x14, 0x00, 0x00, 0x03, + 0xb8, 0x11, 0x14, 0x00, 0x00, 0x03, 0xb9, 0x11, + 0x14, 0x00, 0x00, 0x02, 0xb7, 0x12, 0x00, 0x00, + 0x00, 0x04, 0x14, 0x00, 0x00, 0x02, 0xbd, 0x12, + 0x00, 0x00, 0x00, 0x05, 0x14, 0x00, 0x00, 0x02, + 0xba, 0x12, 0x00, 0x00, 0x00, 0x0a, 0x14, 0x00, + 0x00, 0x02, 0x74, 0x12, 0x00, 0x00, 0x00, 0x0b, + 0x14, 0x00, 0x00, 0x02, 0xc0, 0x12, 0x00, 0x00, + 0x00, 0x0d, 0x14, 0x00, 0x00, 0x02, 0xbc, 0x0f, + 0x14, 0x00, 0x00, 0x02, 0xbe, 0x10, 0x14, 0x00, + 0x00, 0x02, 0xbf, 0x0f, 0x14, 0x00, 0x00, 0x03, + 0xab, 0x10, 0x14, 0x00, 0x00, 0x03, 0xac, 0x0e, + 0x14, 0x00, 0x00, 0x02, 0x85, 0x0f, 0x14, 0x00, + 0x00, 0x02, 0x88, 0x10, 0x14, 0x00, 0x00, 0x02, + 0x8b, 0x11, 0x14, 0x00, 0x00, 0x02, 0x8e, 0x12, + 0x00, 0x00, 0x00, 0x04, 0x14, 0x00, 0x00, 0x02, + 0x92, 0x12, 0x00, 0x00, 0x00, 0x05, 0x14, 0x00, + 0x00, 0x02, 0x95, 0x12, 0x00, 0x00, 0x00, 0x06, + 0x14, 0x00, 0x00, 0x02, 0x9a, 0x12, 0x00, 0x00, + 0x00, 0x07, 0x14, 0x00, 0x00, 0x02, 0x9d, 0x12, + 0x00, 0x00, 0x00, 0x08, 0x14, 0x00, 0x00, 0x02, + 0xa0, 0x12, 0x00, 0x00, 0x00, 0x09, 0x14, 0x00, + 0x00, 0x02, 0xa3, 0x12, 0x00, 0x00, 0x00, 0x0a, + 0x14, 0x00, 0x00, 0x02, 0xc3, 0x12, 0x00, 0x00, + 0x00, 0x0b, 0x14, 0x00, 0x00, 0x02, 0xc6, 0x12, + 0x00, 0x00, 0x00, 0x0c, 0x14, 0x00, 0x00, 0x02, + 0xc9, 0x12, 0x00, 0x00, 0x00, 0x0d, 0x14, 0x00, + 0x00, 0x02, 0xcc, 0x12, 0x00, 0x00, 0x00, 0x0e, + 0x14, 0x00, 0x00, 0x02, 0xcf, 0x12, 0x00, 0x00, + 0x00, 0x0f, 0x14, 0x00, 0x00, 0x02, 0xd2, 0x12, + 0x00, 0x00, 0x00, 0x10, 0x14, 0x00, 0x00, 0x02, + 0xd5, 0x12, 0x00, 0x00, 0x00, 0x11, 0x14, 0x00, + 0x00, 0x02, 0xd8, 0x12, 0x00, 0x00, 0x00, 0x12, + 0x14, 0x00, 0x00, 0x02, 0xdb, 0x12, 0x00, 0x00, + 0x00, 0x13, 0x14, 0x00, 0x00, 0x02, 0xdf, 0x12, + 0x00, 0x00, 0x00, 0x14, 0x14, 0x00, 0x00, 0x02, + 0xe3, 0x12, 0x00, 0x00, 0x00, 0x15, 0x14, 0x00, + 0x00, 0x02, 0xe6, 0x12, 0x00, 0x00, 0x00, 0x16, + 0x14, 0x00, 0x00, 0x02, 0xe9, 0x12, 0x00, 0x00, + 0x00, 0x17, 0x14, 0x00, 0x00, 0x02, 0xec, 0x12, + 0x00, 0x00, 0x00, 0x18, 0x14, 0x00, 0x00, 0x02, + 0xf0, 0x12, 0x00, 0x00, 0x00, 0x19, 0x14, 0x00, + 0x00, 0x02, 0xf3, 0x12, 0x00, 0x00, 0x00, 0x1a, + 0x14, 0x00, 0x00, 0x02, 0xf6, 0x12, 0x00, 0x00, + 0x00, 0x1b, 0x14, 0x00, 0x00, 0x02, 0xf9, 0x12, + 0x00, 0x00, 0x00, 0x1c, 0x14, 0x00, 0x00, 0x02, + 0xfc, 0x12, 0x00, 0x00, 0x00, 0x1d, 0x14, 0x00, + 0x00, 0x02, 0xff, 0x12, 0x00, 0x00, 0x00, 0x1e, + 0x14, 0x00, 0x00, 0x03, 0x02, 0x12, 0x00, 0x00, + 0x00, 0x1f, 0x14, 0x00, 0x00, 0x03, 0x05, 0x12, + 0x00, 0x00, 0x00, 0x20, 0x14, 0x00, 0x00, 0x03, + 0x08, 0x12, 0x00, 0x00, 0x00, 0x21, 0x14, 0x00, + 0x00, 0x03, 0x0b, 0x12, 0x00, 0x00, 0x00, 0x22, + 0x14, 0x00, 0x00, 0x03, 0x0e, 0x12, 0x00, 0x00, + 0x00, 0x23, 0x14, 0x00, 0x00, 0x03, 0x11, 0x12, + 0x00, 0x00, 0x00, 0x24, 0x14, 0x00, 0x00, 0x03, + 0x14, 0x12, 0x00, 0x00, 0x00, 0x25, 0x14, 0x00, + 0x00, 0x03, 0x17, 0x12, 0x00, 0x00, 0x00, 0x26, + 0x14, 0x00, 0x00, 0x03, 0x1a, 0x12, 0x00, 0x00, + 0x00, 0x27, 0x14, 0x00, 0x00, 0x03, 0x1d, 0x12, + 0x00, 0x00, 0x00, 0x28, 0x14, 0x00, 0x00, 0x03, + 0x20, 0x12, 0x00, 0x00, 0x00, 0x29, 0x14, 0x00, + 0x00, 0x03, 0x23, 0x12, 0x00, 0x00, 0x00, 0x2a, + 0x14, 0x00, 0x00, 0x03, 0x26, 0x12, 0x00, 0x00, + 0x00, 0x2b, 0x14, 0x00, 0x00, 0x03, 0x29, 0x12, + 0x00, 0x00, 0x00, 0x2c, 0x14, 0x00, 0x00, 0x03, + 0x2c, 0x12, 0x00, 0x00, 0x00, 0x2d, 0x14, 0x00, + 0x00, 0x03, 0x2f, 0x12, 0x00, 0x00, 0x00, 0x2e, + 0x14, 0x00, 0x00, 0x03, 0x32, 0x12, 0x00, 0x00, + 0x00, 0x2f, 0x14, 0x00, 0x00, 0x03, 0x35, 0x12, + 0x00, 0x00, 0x00, 0x30, 0x14, 0x00, 0x00, 0x03, + 0x38, 0x12, 0x00, 0x00, 0x00, 0x31, 0x14, 0x00, + 0x00, 0x03, 0x3b, 0x12, 0x00, 0x00, 0x00, 0x32, + 0x14, 0x00, 0x00, 0x03, 0x3e, 0x12, 0x00, 0x00, + 0x00, 0x33, 0x14, 0x00, 0x00, 0x03, 0x41, 0x12, + 0x00, 0x00, 0x00, 0x34, 0x14, 0x00, 0x00, 0x03, + 0x45, 0x12, 0x00, 0x00, 0x00, 0x35, 0x14, 0x00, + 0x00, 0x03, 0x48, 0x12, 0x00, 0x00, 0x00, 0x36, + 0x14, 0x00, 0x00, 0x03, 0x4b, 0x12, 0x00, 0x00, + 0x00, 0x37, 0x14, 0x00, 0x00, 0x03, 0x4e, 0x12, + 0x00, 0x00, 0x00, 0x38, 0x14, 0x00, 0x00, 0x03, + 0x51, 0x12, 0x00, 0x00, 0x00, 0x39, 0x14, 0x00, + 0x00, 0x03, 0x54, 0x12, 0x00, 0x00, 0x00, 0x3a, + 0x14, 0x00, 0x00, 0x03, 0x57, 0x12, 0x00, 0x00, + 0x00, 0x3b, 0x14, 0x00, 0x00, 0x03, 0x5a, 0x12, + 0x00, 0x00, 0x00, 0x3c, 0x14, 0x00, 0x00, 0x03, + 0x5d, 0x12, 0x00, 0x00, 0x00, 0x3d, 0x14, 0x00, + 0x00, 0x03, 0x60, 0x12, 0x00, 0x00, 0x00, 0x3e, + 0x14, 0x00, 0x00, 0x03, 0x63, 0x12, 0x00, 0x00, + 0x00, 0x3f, 0x14, 0x00, 0x00, 0x03, 0x66, 0x12, + 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0x00, 0x03, + 0x69, 0x12, 0x00, 0x00, 0x00, 0x41, 0x14, 0x00, + 0x00, 0x03, 0x6c, 0x12, 0x00, 0x00, 0x00, 0x42, + 0x14, 0x00, 0x00, 0x03, 0x6f, 0x12, 0x00, 0x00, + 0x00, 0x43, 0x14, 0x00, 0x00, 0x03, 0x72, 0x12, + 0x00, 0x00, 0x00, 0x44, 0x14, 0x00, 0x00, 0x03, + 0x75, 0x12, 0x00, 0x00, 0x00, 0x45, 0x14, 0x00, + 0x00, 0x03, 0x78, 0x12, 0x00, 0x00, 0x00, 0x46, + 0x14, 0x00, 0x00, 0x03, 0x7b, 0x12, 0x00, 0x00, + 0x00, 0x47, 0x14, 0x00, 0x00, 0x03, 0x7e, 0x12, + 0x00, 0x00, 0x00, 0x48, 0x14, 0x00, 0x00, 0x03, + 0x81, 0x12, 0x00, 0x00, 0x00, 0x49, 0x14, 0x00, + 0x00, 0x03, 0x84, 0x12, 0x00, 0x00, 0x00, 0x4a, + 0x14, 0x00, 0x00, 0x03, 0x87, 0x12, 0x00, 0x00, + 0x03, 0xe8, 0x14, 0x00, 0x00, 0x02, 0x78, 0x12, + 0x00, 0x00, 0x03, 0xe9, 0x14, 0x00, 0x00, 0x02, + 0x7f, 0x0f, 0x14, 0x00, 0x00, 0x03, 0xc1, 0x10, + 0x14, 0x00, 0x00, 0x03, 0xcf, 0x12, 0x00, 0x00, + 0x00, 0x04, 0x14, 0x00, 0x00, 0x03, 0xc2, 0x12, + 0x00, 0x00, 0x00, 0x08, 0x14, 0x00, 0x00, 0x03, + 0xd5, 0x12, 0x00, 0x00, 0x00, 0x20, 0x14, 0x00, + 0x00, 0x03, 0x98, 0x12, 0x00, 0x00, 0x00, 0x40, + 0x14, 0x00, 0x00, 0x03, 0x9b, 0x12, 0x00, 0x00, + 0x00, 0x80, 0x14, 0x00, 0x00, 0x03, 0xa0, 0x12, + 0x00, 0x00, 0x01, 0x00, 0x14, 0x00, 0x00, 0x03, + 0x9e, 0x12, 0x00, 0x00, 0xff, 0xf0, 0x14, 0x00, + 0x00, 0x03, 0xcc, 0x12, 0x00, 0x01, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x03, 0xc3, 0x12, 0x00, 0x02, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x03, 0xc4, 0x12, + 0x00, 0x04, 0x00, 0x00, 0x14, 0x00, 0x00, 0x03, + 0xc5, 0x12, 0x00, 0x08, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x03, 0xc6, 0x12, 0x00, 0x10, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x03, 0xc7, 0x12, 0x00, 0x20, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x03, 0xc8, 0x12, + 0x00, 0x40, 0x00, 0x00, 0x14, 0x00, 0x00, 0x03, + 0xc9, 0x12, 0xff, 0xff, 0x00, 0x00, 0x03, 0x14, + 0x00, 0x00, 0x03, 0xeb, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x48, 0xc0, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x00, 0x0a, 0x72, 0x65, + 0x61, 0x64, 0x42, 0x79, 0x74, 0x65, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x6c, 0x69, 0x6e, 0x65, + 0x6e, 0x75, 0x6d, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x6c, 0x65, 0x78, 0x65, 0x72, 0x5f, 0x69, + 0x73, 0x5f, 0x77, 0x68, 0x69, 0x74, 0x65, 0x5f, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x6e, 0x75, 0x6d, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x6c, 0x65, + 0x78, 0x65, 0x72, 0x5f, 0x70, 0x65, 0x65, 0x6b, + 0x5f, 0x63, 0x68, 0x61, 0x72, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x6c, 0x65, + 0x78, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x61, 0x64, + 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, 0x53, 0x54, + 0x52, 0x49, 0x4e, 0x47, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x74, 0x53, 0x45, 0x51, 0x55, 0x41, + 0x4c, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, + 0x45, 0x51, 0x55, 0x41, 0x4c, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x74, 0x53, 0x4e, 0x45, 0x51, + 0x55, 0x41, 0x4c, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x74, 0x4e, 0x45, 0x51, 0x55, 0x41, 0x4c, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, 0x4c, + 0x45, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, + 0x47, 0x45, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x74, 0x41, 0x4e, 0x44, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x74, 0x4f, 0x52, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x74, 0x50, 0x4c, 0x55, 0x53, + 0x50, 0x4c, 0x55, 0x53, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x74, 0x4d, 0x49, 0x4e, 0x55, 0x53, + 0x4d, 0x49, 0x4e, 0x55, 0x53, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x74, 0x4d, 0x55, 0x4c, 0x41, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, 0x44, + 0x49, 0x56, 0x41, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x74, 0x4d, 0x4f, 0x44, 0x41, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x74, 0x41, 0x44, 0x44, + 0x41, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, + 0x53, 0x55, 0x42, 0x41, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x74, 0x41, 0x4e, 0x44, 0x41, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, 0x58, 0x4f, + 0x52, 0x41, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x74, 0x4f, 0x52, 0x41, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x74, 0x4c, 0x53, 0x49, 0x41, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, 0x4c, 0x53, + 0x48, 0x49, 0x46, 0x54, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x74, 0x52, 0x53, 0x49, 0x41, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, 0x52, 0x52, + 0x53, 0x41, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x74, 0x52, 0x52, 0x53, 0x48, 0x49, 0x46, 0x54, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, 0x52, + 0x53, 0x48, 0x49, 0x46, 0x54, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x6c, 0x65, 0x78, 0x65, 0x72, + 0x5f, 0x69, 0x73, 0x5f, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x5f, 0x6c, + 0x65, 0x74, 0x74, 0x65, 0x72, 0x00, 0x0a, 0x53, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x00, 0x0a, 0x66, + 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x43, + 0x6f, 0x64, 0x65, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x6c, 0x65, 0x78, 0x65, 0x72, 0x5f, 0x69, + 0x73, 0x5f, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, + 0x6c, 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 0x00, + 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x00, 0x0a, 0x62, + 0x79, 0x74, 0x65, 0x54, 0x6f, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x00, 0x0a, 0x61, 0x70, 0x70, + 0x65, 0x6e, 0x64, 0x00, 0x0a, 0x75, 0x6e, 0x67, + 0x65, 0x74, 0x42, 0x79, 0x74, 0x65, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x05, 0x62, 0x72, 0x65, 0x61, + 0x6b, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, 0x42, + 0x52, 0x45, 0x41, 0x4b, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, + 0x75, 0x65, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, + 0x43, 0x4f, 0x4e, 0x54, 0x49, 0x4e, 0x55, 0x45, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x74, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x65, 0x6c, + 0x73, 0x65, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, + 0x45, 0x4c, 0x53, 0x45, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x03, 0x66, 0x6f, 0x72, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x74, 0x46, 0x4f, 0x52, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x08, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x74, 0x46, 0x55, 0x4e, 0x43, 0x54, 0x49, + 0x4f, 0x4e, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, + 0x69, 0x66, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, + 0x49, 0x46, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, + 0x69, 0x6e, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, + 0x49, 0x4e, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, + 0x6e, 0x65, 0x77, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x74, 0x4e, 0x45, 0x57, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x06, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, 0x52, 0x45, + 0x54, 0x55, 0x52, 0x4e, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x04, 0x74, 0x68, 0x69, 0x73, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x74, 0x54, 0x48, 0x49, 0x53, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x74, 0x79, + 0x70, 0x65, 0x6f, 0x66, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x74, 0x54, 0x59, 0x50, 0x45, 0x4f, 0x46, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x76, 0x61, + 0x72, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, 0x56, + 0x41, 0x52, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, + 0x76, 0x6f, 0x69, 0x64, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x74, 0x56, 0x4f, 0x49, 0x44, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x05, 0x77, 0x68, 0x69, 0x6c, + 0x65, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, 0x57, + 0x48, 0x49, 0x4c, 0x45, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x04, 0x77, 0x69, 0x74, 0x68, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x74, 0x57, 0x49, 0x54, 0x48, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x63, 0x61, + 0x73, 0x65, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, + 0x43, 0x41, 0x53, 0x45, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x05, 0x63, 0x61, 0x74, 0x63, 0x68, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x74, 0x43, 0x41, 0x54, + 0x43, 0x48, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x74, 0x43, 0x4c, 0x41, 0x53, 0x53, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x74, 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x08, 0x64, 0x65, 0x62, 0x75, + 0x67, 0x67, 0x65, 0x72, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x74, 0x44, 0x45, 0x42, 0x55, 0x47, 0x47, + 0x45, 0x52, 0x00, 0x04, 0x00, 0x00, 0x00, 0x07, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x74, 0x44, 0x45, 0x46, + 0x41, 0x55, 0x4c, 0x54, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x02, 0x64, 0x6f, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x74, 0x44, 0x4f, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x04, 0x65, 0x6e, 0x75, 0x6d, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x74, 0x45, 0x4e, 0x55, 0x4d, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x65, 0x78, + 0x70, 0x6f, 0x72, 0x74, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x74, 0x45, 0x58, 0x50, 0x4f, 0x52, 0x54, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x07, 0x65, 0x78, + 0x74, 0x65, 0x6e, 0x64, 0x73, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x74, 0x45, 0x58, 0x54, 0x45, 0x4e, + 0x44, 0x53, 0x00, 0x04, 0x00, 0x00, 0x00, 0x07, + 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x74, 0x46, 0x49, 0x4e, + 0x41, 0x4c, 0x4c, 0x59, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x06, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, 0x49, 0x4d, + 0x50, 0x4f, 0x52, 0x54, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x05, 0x73, 0x75, 0x70, 0x65, 0x72, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x74, 0x53, 0x55, 0x50, + 0x45, 0x52, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, + 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x74, 0x53, 0x57, 0x49, 0x54, + 0x43, 0x48, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, + 0x74, 0x68, 0x72, 0x6f, 0x77, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x74, 0x54, 0x48, 0x52, 0x4f, 0x57, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x74, 0x72, + 0x79, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, 0x54, + 0x52, 0x59, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, + 0x6e, 0x75, 0x6c, 0x6c, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x74, 0x4e, 0x55, 0x4c, 0x4c, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0x74, 0x72, 0x75, 0x65, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, 0x54, 0x52, + 0x55, 0x45, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, + 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x74, 0x46, 0x41, 0x4c, 0x53, 0x45, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, 0x49, + 0x44, 0x45, 0x4e, 0x54, 0x49, 0x46, 0x49, 0x45, + 0x52, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x63, + 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x6c, 0x65, 0x78, + 0x65, 0x72, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x5f, + 0x62, 0x61, 0x63, 0x6b, 0x73, 0x6c, 0x61, 0x73, + 0x68, 0x5f, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x66, 0x69, + 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x3a, 0x0a, 0x74, 0x6f, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x1e, 0x3a, 0x20, 0x6d, 0x61, + 0x6c, 0x66, 0x6f, 0x72, 0x6d, 0x65, 0x64, 0x20, + 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, + 0x72, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x74, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x74, 0x49, + 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x6c, 0x65, 0x78, 0x65, + 0x72, 0x5f, 0x69, 0x73, 0x5f, 0x68, 0x65, 0x78, + 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x6c, 0x65, 0x78, 0x65, + 0x72, 0x5f, 0x68, 0x65, 0x78, 0x5f, 0x74, 0x6f, + 0x5f, 0x64, 0x65, 0x63, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x6c, 0x65, 0x78, 0x65, 0x72, 0x5f, + 0x69, 0x73, 0x5f, 0x6f, 0x63, 0x74, 0x61, 0x6c, + 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x2e, 0x3a, 0x20, 0x6d, 0x61, + 0x6c, 0x66, 0x6f, 0x72, 0x6d, 0x65, 0x64, 0x20, + 0x65, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, + 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x69, 0x6e, + 0x20, 0x61, 0x20, 0x64, 0x65, 0x63, 0x69, 0x6d, + 0x61, 0x6c, 0x20, 0x6c, 0x69, 0x74, 0x65, 0x72, + 0x61, 0x6c, 0x0a, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x74, 0x46, 0x4c, 0x4f, 0x41, + 0x54, 0x00, 0x0a, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x49, 0x6e, 0x74, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x74, 0x45, 0x4f, 0x46, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x6c, 0x65, 0x78, 0x65, 0x72, + 0x5f, 0x65, 0x6f, 0x66, 0x5f, 0x69, 0x6e, 0x5f, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x26, 0x3a, 0x20, + 0x5c, 0x78, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, + 0x77, 0x69, 0x74, 0x68, 0x20, 0x6e, 0x6f, 0x20, + 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, + 0x67, 0x20, 0x68, 0x65, 0x78, 0x20, 0x64, 0x69, + 0x67, 0x69, 0x74, 0x73, 0x04, 0x00, 0x00, 0x00, + 0x26, 0x3a, 0x20, 0x5c, 0x75, 0x20, 0x75, 0x73, + 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, + 0x6e, 0x6f, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, + 0x77, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x65, 0x78, + 0x20, 0x64, 0x69, 0x67, 0x69, 0x74, 0x73, 0x04, + 0x00, 0x00, 0x00, 0x0f, 0x3a, 0x20, 0x75, 0x6e, + 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x04, 0x00, 0x00, 0x00, 0x25, + 0x3a, 0x20, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, + 0x67, 0x3a, 0x20, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, + 0x77, 0x6e, 0x20, 0x65, 0x73, 0x63, 0x61, 0x70, + 0x65, 0x20, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, + 0x63, 0x65, 0x20, 0x60, 0x5c, 0x04, 0x00, 0x00, + 0x00, 0x01, 0x27, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x77, 0x61, 0x72, 0x6e, 0x5f, 0x73, + 0x74, 0x72, 0x69, 0x63, 0x74, 0x5f, 0x65, 0x63, + 0x6d, 0x61, 0x00, 0x04, 0x00, 0x00, 0x00, 0x36, + 0x3a, 0x20, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, + 0x67, 0x3a, 0x20, 0x45, 0x43, 0x4d, 0x41, 0x53, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x64, 0x6f, + 0x6e, 0x27, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x6f, + 0x77, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x74, + 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, + 0x72, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x04, 0x00, + 0x00, 0x00, 0x0a, 0x20, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x74, 0x73, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x6c, 0x65, 0x78, 0x65, 0x72, 0x5f, + 0x72, 0x65, 0x61, 0x64, 0x5f, 0x72, 0x65, 0x67, + 0x65, 0x78, 0x70, 0x5f, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x00, 0x0a, 0x63, 0x68, 0x00, 0x0a, + 0x52, 0x65, 0x67, 0x45, 0x78, 0x70, 0x00, 0x0a, + 0x6c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x4f, 0x66, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x28, 0x3a, 0x20, 0x6d, 0x61, 0x6c, 0x66, 0x6f, + 0x72, 0x6d, 0x65, 0x64, 0x20, 0x72, 0x65, 0x67, + 0x75, 0x6c, 0x61, 0x72, 0x20, 0x65, 0x78, 0x70, + 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, + 0x3a, 0x0a, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x12, 0x72, 0x65, + 0x67, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x65, 0x78, + 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x04, 0x00, 0x00, 0x00, 0x27, 0x3a, 0x20, 0x77, + 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x3a, 0x20, + 0x45, 0x43, 0x4d, 0x41, 0x53, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x20, 0x64, 0x6f, 0x6e, 0x27, 0x74, + 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x20, 0x6c, + 0x69, 0x6e, 0x65, 0x20, 0x04, 0x00, 0x00, 0x00, + 0x0f, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, + 0x74, 0x6f, 0x72, 0x73, 0x20, 0x69, 0x6e, 0x20, + 0x04, 0x00, 0x00, 0x00, 0x5a, 0x3a, 0x20, 0x77, + 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x3a, 0x20, + 0x45, 0x43, 0x4d, 0x41, 0x53, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x20, 0x64, 0x6f, 0x6e, 0x27, 0x74, + 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x20, 0x6c, + 0x69, 0x6e, 0x65, 0x20, 0x74, 0x65, 0x72, 0x6d, + 0x69, 0x61, 0x6e, 0x74, 0x6f, 0x72, 0x20, 0x61, + 0x66, 0x74, 0x65, 0x72, 0x20, 0x5c, 0x63, 0x20, + 0x69, 0x6e, 0x20, 0x72, 0x65, 0x67, 0x75, 0x6c, + 0x61, 0x72, 0x20, 0x65, 0x78, 0x70, 0x72, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x73, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x5c, 0x63, 0x04, 0x00, + 0x00, 0x00, 0x09, 0x20, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x74, 0x0a, 0x53, 0x79, 0x73, + 0x74, 0x65, 0x6d, 0x00, 0x0a, 0x6c, 0x69, 0x6e, + 0x65, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x53, 0x65, + 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x26, 0x3a, 0x20, 0x70, 0x6f, + 0x73, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x72, + 0x65, 0x61, 0x6c, 0x20, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x6e, 0x74, + 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, + 0x64, 0x20, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x67, 0x6c, 0x6f, + 0x62, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x6d, 0x74, + 0x73, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x6e, + 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, + 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x00, 0x0a, 0x6e, 0x61, 0x6d, + 0x65, 0x00, 0x0a, 0x41, 0x72, 0x72, 0x61, 0x79, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x61, 0x6e, 0x6f, + 0x6e, 0x79, 0x6d, 0x6f, 0x75, 0x73, 0x5f, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x72, 0x5f, 0x70, 0x65, 0x65, 0x6b, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x6e, 0x75, 0x6d, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x73, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x6e, 0x75, 0x6d, 0x5f, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x69, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, + 0x73, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x6e, + 0x75, 0x6d, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x6d, 0x69, 0x63, + 0x6f, 0x6c, 0x6f, 0x6e, 0x73, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x76, 0x65, 0x72, 0x62, 0x6f, + 0x73, 0x65, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, + 0x6a, 0x73, 0x63, 0x3a, 0x20, 0x70, 0x61, 0x72, + 0x73, 0x69, 0x6e, 0x67, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x65, 0x65, + 0x6b, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x5f, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x72, 0x5f, 0x73, 0x79, 0x6e, + 0x74, 0x61, 0x78, 0x5f, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x00, 0x04, 0x00, 0x00, 0x00, 0x16, 0x6a, + 0x73, 0x63, 0x3a, 0x20, 0x69, 0x6e, 0x70, 0x75, + 0x74, 0x20, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x20, 0x68, 0x61, 0x64, 0x20, 0x04, 0x00, 0x00, + 0x00, 0x08, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x73, + 0x2c, 0x20, 0x04, 0x00, 0x00, 0x00, 0x07, 0x20, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x04, 0x00, + 0x00, 0x00, 0x02, 0x2c, 0x20, 0x04, 0x00, 0x00, + 0x00, 0x13, 0x20, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6e, 0x67, 0x20, 0x73, 0x65, 0x6d, 0x69, 0x63, + 0x6f, 0x6c, 0x6f, 0x6e, 0x73, 0x04, 0x00, 0x00, + 0x00, 0x0e, 0x3a, 0x20, 0x73, 0x79, 0x6e, 0x74, + 0x61, 0x78, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x0a, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x00, + 0x0a, 0x77, 0x72, 0x69, 0x74, 0x65, 0x6c, 0x6e, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x65, 0x65, + 0x6b, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x72, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x72, 0x5f, 0x70, 0x65, 0x65, 0x6b, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x6c, 0x69, 0x6e, + 0x65, 0x6e, 0x75, 0x6d, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, + 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x6c, + 0x69, 0x6e, 0x65, 0x6e, 0x75, 0x6d, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x72, 0x5f, 0x70, 0x65, 0x65, 0x6b, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x6c, 0x65, 0x78, 0x65, 0x72, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x09, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, + 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x77, 0x61, 0x72, 0x6e, 0x5f, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x6d, + 0x69, 0x63, 0x6f, 0x6c, 0x6f, 0x6e, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x1c, 0x3a, 0x20, 0x77, 0x61, + 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x73, + 0x65, 0x6d, 0x69, 0x63, 0x6f, 0x6c, 0x6f, 0x6e, + 0x0a, 0x65, 0x74, 0x79, 0x70, 0x65, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x45, 0x58, 0x50, 0x52, + 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x45, 0x58, 0x50, 0x52, 0x5f, + 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x50, + 0x52, 0x4f, 0x50, 0x45, 0x52, 0x54, 0x59, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x45, 0x58, 0x50, + 0x52, 0x5f, 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, + 0x5f, 0x41, 0x52, 0x52, 0x41, 0x59, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x45, 0x58, 0x50, 0x52, + 0x5f, 0x4e, 0x45, 0x57, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x45, 0x58, 0x50, 0x52, 0x5f, 0x54, + 0x48, 0x49, 0x53, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x45, 0x58, 0x50, 0x52, 0x5f, 0x49, 0x44, + 0x45, 0x4e, 0x54, 0x49, 0x46, 0x49, 0x45, 0x52, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x45, 0x58, + 0x50, 0x52, 0x5f, 0x46, 0x4c, 0x4f, 0x41, 0x54, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x45, 0x58, + 0x50, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x47, + 0x45, 0x52, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x45, 0x58, 0x50, 0x52, 0x5f, 0x53, 0x54, 0x52, + 0x49, 0x4e, 0x47, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x45, 0x58, 0x50, 0x52, 0x5f, 0x52, 0x45, + 0x47, 0x45, 0x58, 0x50, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x45, 0x58, 0x50, 0x52, 0x5f, 0x41, + 0x52, 0x52, 0x41, 0x59, 0x5f, 0x49, 0x4e, 0x49, + 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x45, 0x52, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x45, 0x58, + 0x50, 0x52, 0x5f, 0x4e, 0x55, 0x4c, 0x4c, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x45, 0x58, 0x50, + 0x52, 0x5f, 0x54, 0x52, 0x55, 0x45, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x45, 0x58, 0x50, 0x52, + 0x5f, 0x46, 0x41, 0x4c, 0x53, 0x45, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, + 0x73, 0x74, 0x6d, 0x74, 0x00, 0x0a, 0x73, 0x74, + 0x79, 0x70, 0x65, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x53, 0x54, 0x4d, 0x54, 0x5f, 0x56, 0x41, + 0x52, 0x49, 0x41, 0x42, 0x4c, 0x45, 0x00, 0x0a, + 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6c, + 0x65, 0x76, 0x65, 0x6c, 0x00, 0x0a, 0x70, 0x75, + 0x73, 0x68, 0x00, 0x0a, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, + 0x2e, 0x46, 0x3a, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, + 0x61, 0x72, 0x73, 0x65, 0x5f, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x00, 0x04, 0x00, 0x00, 0x00, 0x07, + 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x77, 0x61, 0x72, 0x6e, + 0x5f, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, + 0x74, 0x65, 0x64, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x30, 0x3a, 0x20, 0x77, 0x61, 0x72, 0x6e, 0x69, + 0x6e, 0x67, 0x3a, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x60, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x27, 0x20, 0x70, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x20, + 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x04, 0x00, 0x00, 0x00, 0x16, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x69, + 0x73, 0x20, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, + 0x61, 0x74, 0x65, 0x64, 0x03, 0x00, 0x00, 0x00, + 0x07, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, + 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x00, 0x0a, 0x70, 0x6f, 0x70, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x5f, 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x6c, + 0x69, 0x73, 0x74, 0x00, 0x0a, 0x6c, 0x69, 0x6e, + 0x65, 0x6e, 0x75, 0x6d, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x65, + 0x6d, 0x70, 0x74, 0x79, 0x00, 0x0a, 0x6e, 0x61, + 0x6d, 0x65, 0x5f, 0x67, 0x69, 0x76, 0x65, 0x6e, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, + 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, 0x76, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, + 0x73, 0x74, 0x6d, 0x74, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, + 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, 0x69, + 0x66, 0x5f, 0x73, 0x74, 0x6d, 0x74, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x5f, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x6d, 0x74, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x00, 0x0a, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x65, 0x64, 0x5f, + 0x73, 0x74, 0x6d, 0x74, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, + 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6d, + 0x69, 0x63, 0x6f, 0x6c, 0x6f, 0x6e, 0x5f, 0x61, + 0x73, 0x63, 0x69, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x65, 0x78, + 0x70, 0x72, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x63, 0x6f, 0x6e, + 0x74, 0x69, 0x6e, 0x75, 0x65, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, + 0x62, 0x72, 0x65, 0x61, 0x6b, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x5f, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, + 0x74, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x5f, 0x74, 0x72, 0x79, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x32, 0x3a, 0x20, 0x77, 0x61, 0x72, 0x6e, + 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x45, 0x43, 0x4d, + 0x41, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, + 0x64, 0x6f, 0x6e, 0x27, 0x74, 0x20, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x20, 0x6c, 0x69, 0x6e, 0x65, + 0x20, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, + 0x74, 0x6f, 0x72, 0x73, 0x04, 0x00, 0x00, 0x00, + 0x1f, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, + 0x6e, 0x20, 0x60, 0x74, 0x68, 0x72, 0x6f, 0x77, + 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x65, 0x78, + 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, + 0x74, 0x5f, 0x74, 0x68, 0x72, 0x6f, 0x77, 0x00, + 0x0a, 0x65, 0x78, 0x70, 0x72, 0x00, 0x0a, 0x6c, + 0x61, 0x73, 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x65, + 0x6e, 0x75, 0x6d, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x73, 0x77, + 0x69, 0x74, 0x63, 0x68, 0x00, 0x0a, 0x4f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x00, 0x0a, 0x69, 0x64, + 0x00, 0x0a, 0x67, 0x75, 0x61, 0x72, 0x64, 0x00, + 0x0a, 0x73, 0x74, 0x6d, 0x74, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x06, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x74, 0x72, 0x79, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, + 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x65, 0x78, + 0x70, 0x72, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x76, 0x61, 0x72, 0x5f, 0x64, 0x65, 0x63, 0x6c, + 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, + 0x74, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, + 0x6c, 0x65, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x69, 0x66, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, + 0x74, 0x5f, 0x64, 0x6f, 0x5f, 0x77, 0x68, 0x69, + 0x6c, 0x65, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x77, 0x68, 0x69, + 0x6c, 0x65, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, + 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x69, 0x6e, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, + 0x6d, 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x5f, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x65, 0x78, 0x70, + 0x72, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x70, + 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, 0x65, 0x78, + 0x70, 0x72, 0x5f, 0x69, 0x73, 0x5f, 0x6c, 0x65, + 0x66, 0x74, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x5f, + 0x73, 0x69, 0x64, 0x65, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x61, + 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, + 0x74, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x6f, + 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x5f, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, + 0x5f, 0x66, 0x6f, 0x6c, 0x64, 0x69, 0x6e, 0x67, + 0x00, 0x0a, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x74, 0x5f, 0x66, 0x6f, 0x6c, 0x64, 0x69, + 0x6e, 0x67, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, + 0x61, 0x72, 0x73, 0x65, 0x5f, 0x6c, 0x6f, 0x67, + 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x6f, 0x72, 0x5f, + 0x65, 0x78, 0x70, 0x72, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x6c, + 0x6f, 0x6e, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, + 0x61, 0x72, 0x73, 0x65, 0x5f, 0x6c, 0x6f, 0x67, + 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x61, 0x6e, 0x64, + 0x5f, 0x65, 0x78, 0x70, 0x72, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, + 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x5f, + 0x6f, 0x72, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, + 0x61, 0x72, 0x73, 0x65, 0x5f, 0x62, 0x69, 0x74, + 0x77, 0x69, 0x73, 0x65, 0x5f, 0x6f, 0x72, 0x5f, + 0x65, 0x78, 0x70, 0x72, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x6c, + 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x61, + 0x6e, 0x64, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, + 0x61, 0x72, 0x73, 0x65, 0x5f, 0x62, 0x69, 0x74, + 0x77, 0x69, 0x73, 0x65, 0x5f, 0x78, 0x6f, 0x72, + 0x5f, 0x65, 0x78, 0x70, 0x72, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, + 0x62, 0x69, 0x74, 0x77, 0x69, 0x73, 0x65, 0x5f, + 0x6f, 0x72, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, + 0x61, 0x72, 0x73, 0x65, 0x5f, 0x62, 0x69, 0x74, + 0x77, 0x69, 0x73, 0x65, 0x5f, 0x61, 0x6e, 0x64, + 0x5f, 0x65, 0x78, 0x70, 0x72, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, + 0x62, 0x69, 0x74, 0x77, 0x69, 0x73, 0x65, 0x5f, + 0x78, 0x6f, 0x72, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, 0x65, 0x71, + 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x65, + 0x78, 0x70, 0x72, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x62, 0x69, + 0x74, 0x77, 0x69, 0x73, 0x65, 0x5f, 0x61, 0x6e, + 0x64, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x70, + 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x5f, 0x72, 0x65, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x65, + 0x78, 0x70, 0x72, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x65, 0x71, + 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x5f, 0x73, 0x68, 0x69, 0x66, 0x74, 0x5f, 0x65, + 0x78, 0x70, 0x72, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x72, 0x65, + 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x69, 0x74, + 0x69, 0x76, 0x65, 0x5f, 0x65, 0x78, 0x70, 0x72, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, + 0x70, 0x72, 0x5f, 0x73, 0x68, 0x69, 0x66, 0x74, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x76, + 0x65, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x76, + 0x65, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x70, + 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x5f, 0x75, 0x6e, 0x61, 0x72, + 0x79, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x76, 0x65, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, + 0x72, 0x5f, 0x75, 0x6e, 0x61, 0x72, 0x79, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x5f, 0x70, 0x6f, 0x73, 0x74, 0x66, 0x69, + 0x78, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x5f, 0x6c, 0x65, 0x66, 0x74, 0x5f, 0x68, 0x61, + 0x6e, 0x64, 0x5f, 0x73, 0x69, 0x64, 0x65, 0x5f, + 0x65, 0x78, 0x70, 0x72, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x4c, 0x3a, 0x20, 0x77, 0x61, 0x72, 0x6e, + 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x61, 0x75, 0x74, + 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x20, 0x73, + 0x65, 0x6d, 0x69, 0x63, 0x6f, 0x6c, 0x6f, 0x6e, + 0x20, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x63, 0x75, 0x74, 0x73, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x65, 0x78, 0x70, 0x72, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x62, + 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x2b, 0x2b, + 0x20, 0x6f, 0x72, 0x20, 0x2d, 0x2d, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, + 0x70, 0x6f, 0x73, 0x74, 0x66, 0x69, 0x78, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x5f, 0x65, 0x78, 0x70, 0x72, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x65, + 0x78, 0x70, 0x72, 0x5f, 0x63, 0x61, 0x6c, 0x6c, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, + 0x70, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x5f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, + 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x79, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x70, + 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x5f, 0x70, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x5f, 0x65, 0x78, 0x70, 0x72, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, + 0x70, 0x72, 0x5f, 0x6e, 0x65, 0x77, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x74, 0x68, 0x69, 0x73, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, + 0x65, 0x72, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x65, 0x78, 0x70, 0x72, 0x5f, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x65, 0x78, 0x70, 0x72, 0x5f, 0x69, 0x6e, 0x74, + 0x65, 0x67, 0x65, 0x72, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x6c, 0x65, 0x78, 0x65, 0x72, + 0x5f, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x72, 0x65, + 0x67, 0x65, 0x78, 0x70, 0x5f, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x74, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, + 0x72, 0x65, 0x67, 0x65, 0x78, 0x70, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x6e, 0x75, 0x6c, 0x6c, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, + 0x74, 0x72, 0x75, 0x65, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x66, + 0x61, 0x6c, 0x73, 0x65, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x61, + 0x72, 0x72, 0x61, 0x79, 0x5f, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x72, + 0x00, 0x0a, 0x69, 0x64, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x65, + 0x78, 0x70, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x72, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x43, 0x6f, 0x6e, + 0x74, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x63, 0x6f, 0x6e, 0x74, + 0x5f, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x2e, 0x4c, 0x0a, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x73, 0x00, 0x0a, 0x6c, 0x6f, 0x6f, + 0x70, 0x5f, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x00, + 0x0a, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x63, 0x6f, + 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x00, 0x0a, + 0x69, 0x6e, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, + 0x00, 0x0a, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x00, + 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x00, 0x0a, 0x77, + 0x69, 0x74, 0x68, 0x5f, 0x6e, 0x65, 0x73, 0x74, + 0x69, 0x6e, 0x67, 0x00, 0x0a, 0x74, 0x72, 0x79, + 0x5f, 0x6e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x43, 0x6f, + 0x6e, 0x74, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x46, + 0x72, 0x61, 0x6d, 0x65, 0x00, 0x0a, 0x74, 0x6f, + 0x70, 0x00, 0x04, 0x00, 0x00, 0x00, 0x33, 0x6a, + 0x73, 0x63, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, + 0x69, 0x6e, 0x75, 0x65, 0x2d, 0x62, 0x72, 0x65, + 0x61, 0x6b, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x66, 0x6c, + 0x6f, 0x77, 0x0a, 0x6c, 0x62, 0x72, 0x61, 0x63, + 0x65, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x6e, 0x75, + 0x6d, 0x00, 0x0a, 0x61, 0x72, 0x67, 0x73, 0x00, + 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x00, 0x0a, + 0x75, 0x73, 0x65, 0x5f, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x70, 0x72, + 0x6f, 0x70, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x73, 0x6d, + 0x00, 0x0a, 0x61, 0x73, 0x6d, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x6e, 0x73, 0x00, 0x0a, 0x70, + 0x75, 0x73, 0x68, 0x5f, 0x66, 0x72, 0x61, 0x6d, + 0x65, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x53, + 0x43, 0x4f, 0x50, 0x45, 0x5f, 0x41, 0x52, 0x47, + 0x00, 0x0a, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, + 0x5f, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x00, + 0x0a, 0x6c, 0x69, 0x6e, 0x6b, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6c, + 0x6f, 0x61, 0x64, 0x5f, 0x61, 0x72, 0x67, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x61, 0x64, 0x64, 0x5f, 0x32, 0x5f, 0x69, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x6d, 0x69, 0x6e, 0x5f, 0x61, 0x72, + 0x67, 0x73, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x73, 0x5f, 0x66, 0x72, 0x6f, + 0x6d, 0x5f, 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x6c, + 0x69, 0x73, 0x74, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x73, 0x00, 0x0a, 0x61, 0x6c, 0x6c, + 0x6f, 0x63, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x53, 0x43, + 0x4f, 0x50, 0x45, 0x5f, 0x4c, 0x4f, 0x43, 0x41, + 0x4c, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x5f, 0x69, 0x30, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x05, 0x41, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6c, + 0x6f, 0x61, 0x64, 0x5f, 0x67, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x6e, 0x65, 0x77, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x73, 0x77, 0x61, 0x70, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x61, + 0x70, 0x6f, 0x70, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x64, 0x75, 0x70, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6d, + 0x70, 0x5f, 0x67, 0x65, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x69, 0x66, + 0x74, 0x72, 0x75, 0x65, 0x5f, 0x62, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x6e, 0x74, 0x68, + 0x5f, 0x61, 0x72, 0x67, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x5f, 0x69, 0x31, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, + 0x70, 0x75, 0x73, 0x68, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x61, 0x6c, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x70, 0x6f, 0x70, 0x5f, 0x6e, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x61, 0x64, 0x64, 0x5f, 0x31, 0x5f, 0x69, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x6a, 0x6d, 0x70, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x70, + 0x6f, 0x70, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x5f, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, + 0x6e, 0x65, 0x64, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x00, 0x0a, 0x70, 0x6f, 0x70, + 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x53, 0x54, 0x4d, 0x54, + 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x00, 0x0a, + 0x73, 0x74, 0x6d, 0x74, 0x73, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x61, 0x73, + 0x6d, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x73, + 0x74, 0x6d, 0x74, 0x5f, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x53, 0x54, 0x4d, 0x54, + 0x5f, 0x46, 0x55, 0x4e, 0x43, 0x54, 0x49, 0x4f, + 0x4e, 0x5f, 0x44, 0x45, 0x43, 0x4c, 0x41, 0x52, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x0a, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x5f, 0x69, 0x64, 0x00, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, + 0x00, 0x0a, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x5f, + 0x69, 0x64, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x65, + 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x7a, 0x65, 0x72, 0x6f, 0x5f, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, + 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x53, 0x54, + 0x4d, 0x54, 0x5f, 0x45, 0x4d, 0x50, 0x54, 0x59, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, + 0x6d, 0x74, 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, + 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x53, 0x54, 0x4d, 0x54, 0x5f, 0x43, + 0x4f, 0x4e, 0x54, 0x49, 0x4e, 0x55, 0x45, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, + 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, + 0x75, 0x65, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x0a, + 0x67, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, + 0x69, 0x6e, 0x75, 0x65, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x09, 0x3a, 0x20, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x20, 0x60, 0x04, 0x00, 0x00, 0x00, 0x22, + 0x27, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, + 0x75, 0x6e, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, + 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, + 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x04, 0x00, 0x00, 0x00, 0x26, 0x3a, + 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, + 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, + 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x61, + 0x20, 0x6c, 0x6f, 0x6f, 0x70, 0x0a, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x77, 0x69, 0x74, 0x68, + 0x5f, 0x6e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x70, + 0x6f, 0x70, 0x00, 0x0a, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x5f, 0x74, 0x72, 0x79, 0x5f, 0x6e, 0x65, + 0x73, 0x74, 0x69, 0x6e, 0x67, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x74, + 0x72, 0x79, 0x5f, 0x70, 0x6f, 0x70, 0x00, 0x0a, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x73, 0x77, + 0x69, 0x74, 0x63, 0x68, 0x5f, 0x6e, 0x65, 0x73, + 0x74, 0x69, 0x6e, 0x67, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x53, 0x54, 0x4d, 0x54, 0x5f, 0x42, + 0x52, 0x45, 0x41, 0x4b, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x62, + 0x72, 0x65, 0x61, 0x6b, 0x5f, 0x61, 0x73, 0x6d, + 0x00, 0x0a, 0x67, 0x65, 0x74, 0x5f, 0x62, 0x72, + 0x65, 0x61, 0x6b, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x1f, 0x27, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, + 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x66, 0x6f, 0x72, + 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x20, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x04, 0x00, 0x00, 0x00, 0x2d, 0x3a, 0x20, 0x62, + 0x72, 0x65, 0x61, 0x6b, 0x20, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6e, + 0x6f, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, + 0x6e, 0x20, 0x61, 0x20, 0x6c, 0x6f, 0x6f, 0x70, + 0x20, 0x6f, 0x72, 0x20, 0x73, 0x77, 0x69, 0x74, + 0x63, 0x68, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x53, + 0x54, 0x4d, 0x54, 0x5f, 0x52, 0x45, 0x54, 0x55, + 0x52, 0x4e, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x5f, 0x61, 0x73, 0x6d, 0x00, + 0x0a, 0x74, 0x72, 0x79, 0x5f, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x5f, 0x6e, 0x65, 0x73, 0x74, + 0x69, 0x6e, 0x67, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x53, 0x54, 0x4d, 0x54, 0x5f, 0x53, 0x57, + 0x49, 0x54, 0x43, 0x48, 0x00, 0x0a, 0x63, 0x6c, + 0x61, 0x75, 0x73, 0x65, 0x73, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, + 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x5f, 0x61, + 0x73, 0x6d, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x73, 0x77, 0x69, + 0x74, 0x63, 0x68, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, + 0x00, 0x0a, 0x6c, 0x5f, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x00, 0x0a, 0x6c, 0x5f, 0x62, 0x6f, 0x64, + 0x79, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x63, 0x6d, 0x70, 0x5f, 0x65, + 0x71, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x69, 0x66, 0x66, 0x61, 0x6c, + 0x73, 0x65, 0x5f, 0x62, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x53, 0x54, 0x4d, 0x54, 0x5f, 0x57, + 0x49, 0x54, 0x48, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x77, 0x69, + 0x74, 0x68, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, + 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x73, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x77, 0x69, 0x74, 0x68, + 0x5f, 0x70, 0x75, 0x73, 0x68, 0x00, 0x0a, 0x6c, + 0x69, 0x73, 0x74, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x53, 0x54, 0x4d, 0x54, 0x5f, 0x54, 0x52, + 0x59, 0x00, 0x0a, 0x74, 0x72, 0x79, 0x5f, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6c, 0x61, 0x73, + 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x6e, 0x75, + 0x6d, 0x00, 0x0a, 0x74, 0x72, 0x79, 0x5f, 0x6c, + 0x61, 0x73, 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x65, + 0x6e, 0x75, 0x6d, 0x00, 0x0a, 0x63, 0x61, 0x74, + 0x63, 0x68, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x00, + 0x0a, 0x66, 0x69, 0x6e, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x74, + 0x72, 0x79, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, + 0x5f, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x73, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x74, 0x72, 0x79, 0x5f, 0x70, + 0x75, 0x73, 0x68, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x5f, 0x66, 0x61, 0x6c, 0x73, 0x65, + 0x00, 0x0a, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x00, 0x0a, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, + 0x70, 0x5f, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, + 0x00, 0x0a, 0x6c, 0x61, 0x6e, 0x67, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x4a, 0x53, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, + 0x45, 0x41, 0x4e, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x69, 0x66, 0x66, + 0x61, 0x6c, 0x73, 0x65, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x5f, 0x74, 0x72, 0x75, 0x65, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x74, 0x68, 0x72, 0x6f, 0x77, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x53, 0x54, 0x4d, + 0x54, 0x5f, 0x54, 0x48, 0x52, 0x4f, 0x57, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, + 0x74, 0x5f, 0x74, 0x68, 0x72, 0x6f, 0x77, 0x5f, + 0x61, 0x73, 0x6d, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x53, 0x54, 0x4d, 0x54, 0x5f, 0x4c, 0x41, + 0x42, 0x45, 0x4c, 0x45, 0x44, 0x5f, 0x53, 0x54, + 0x4d, 0x54, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x6d, + 0x74, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x65, 0x64, 0x5f, + 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x73, 0x00, 0x0a, 0x69, 0x73, 0x5f, 0x75, 0x6e, + 0x69, 0x71, 0x75, 0x65, 0x5f, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3d, + 0x3a, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x65, + 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x20, 0x69, 0x73, 0x20, 0x65, + 0x6e, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x20, + 0x62, 0x79, 0x20, 0x61, 0x6e, 0x6f, 0x74, 0x68, + 0x65, 0x72, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x65, 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x04, 0x00, 0x00, + 0x00, 0x13, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x53, 0x54, 0x4d, 0x54, 0x5f, 0x45, + 0x58, 0x50, 0x52, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x65, 0x78, + 0x70, 0x72, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x53, 0x54, 0x4d, 0x54, + 0x5f, 0x49, 0x46, 0x00, 0x0a, 0x73, 0x74, 0x6d, + 0x74, 0x31, 0x00, 0x0a, 0x73, 0x74, 0x6d, 0x74, + 0x32, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x73, + 0x74, 0x6d, 0x74, 0x5f, 0x69, 0x66, 0x5f, 0x61, + 0x73, 0x6d, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x69, 0x66, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x73, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, + 0x7a, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x53, 0x54, 0x4d, + 0x54, 0x5f, 0x44, 0x4f, 0x5f, 0x57, 0x48, 0x49, + 0x4c, 0x45, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x64, 0x6f, 0x5f, + 0x77, 0x68, 0x69, 0x6c, 0x65, 0x5f, 0x61, 0x73, + 0x6d, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x73, + 0x74, 0x6d, 0x74, 0x5f, 0x64, 0x6f, 0x5f, 0x77, + 0x68, 0x69, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x73, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x69, 0x66, 0x74, 0x72, 0x75, + 0x65, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x53, + 0x54, 0x4d, 0x54, 0x5f, 0x57, 0x48, 0x49, 0x4c, + 0x45, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x73, + 0x74, 0x6d, 0x74, 0x5f, 0x77, 0x68, 0x69, 0x6c, + 0x65, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, + 0x77, 0x68, 0x69, 0x6c, 0x65, 0x5f, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x73, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x53, 0x54, 0x4d, 0x54, 0x5f, 0x46, 0x4f, 0x52, + 0x00, 0x0a, 0x76, 0x61, 0x72, 0x73, 0x00, 0x0a, + 0x65, 0x78, 0x70, 0x72, 0x31, 0x00, 0x0a, 0x65, + 0x78, 0x70, 0x72, 0x32, 0x00, 0x0a, 0x65, 0x78, + 0x70, 0x72, 0x33, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x66, 0x6f, + 0x72, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, + 0x66, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, + 0x00, 0x0a, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x00, + 0x0a, 0x6c, 0x69, 0x65, 0x6e, 0x6e, 0x75, 0x6d, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x2c, 0x3a, 0x20, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x72, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, + 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, + 0x65, 0x20, 0x04, 0x00, 0x00, 0x00, 0x1c, 0x64, + 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x53, 0x54, 0x4d, 0x54, 0x5f, 0x46, 0x4f, 0x52, + 0x5f, 0x49, 0x4e, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x66, 0x6f, + 0x72, 0x5f, 0x69, 0x6e, 0x5f, 0x61, 0x73, 0x6d, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, + 0x6d, 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x69, + 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x6e, 0x74, 0x68, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x61, 0x73, 0x6d, 0x5f, 0x65, 0x78, 0x70, + 0x72, 0x5f, 0x6c, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x61, + 0x73, 0x6d, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x61, 0x64, 0x64, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x72, 0x6f, 0x6c, 0x6c, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, + 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, + 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x76, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x73, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x5f, 0x67, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x00, 0x04, 0x00, 0x00, 0x00, 0x37, + 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x69, + 0x6c, 0x65, 0x72, 0x20, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, + 0x62, 0x6c, 0x65, 0x20, 0x64, 0x65, 0x63, 0x6c, + 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x74, 0x68, 0x69, 0x73, 0x5f, 0x61, 0x73, + 0x6d, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x65, + 0x78, 0x70, 0x72, 0x5f, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x5f, 0x61, + 0x73, 0x6d, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x61, 0x73, 0x6d, 0x5f, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x6c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, + 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x61, 0x73, 0x6d, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4a, 0x53, + 0x5f, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x5f, 0x61, + 0x73, 0x6d, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4a, + 0x53, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, + 0x52, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x65, + 0x78, 0x70, 0x72, 0x5f, 0x69, 0x6e, 0x74, 0x65, + 0x67, 0x65, 0x72, 0x5f, 0x61, 0x73, 0x6d, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x69, + 0x32, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x5f, 0x69, 0x33, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x5f, 0x69, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x4a, 0x53, 0x5f, 0x53, 0x54, 0x52, + 0x49, 0x4e, 0x47, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x73, 0x6d, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4a, 0x53, + 0x5f, 0x42, 0x55, 0x49, 0x4c, 0x54, 0x49, 0x4e, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, + 0x70, 0x72, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, + 0x70, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x4a, 0x53, 0x5f, 0x41, 0x52, + 0x52, 0x41, 0x59, 0x00, 0x0a, 0x69, 0x74, 0x65, + 0x6d, 0x73, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x65, 0x78, 0x70, 0x72, 0x5f, 0x61, 0x72, 0x72, + 0x61, 0x79, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x72, 0x5f, 0x61, + 0x73, 0x6d, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x45, 0x58, 0x50, 0x52, 0x5f, 0x4f, 0x42, 0x4a, + 0x45, 0x43, 0x54, 0x5f, 0x49, 0x4e, 0x49, 0x54, + 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x45, 0x52, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4a, 0x53, 0x5f, + 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, + 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, + 0x7a, 0x65, 0x72, 0x5f, 0x61, 0x73, 0x6d, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x06, 0x4f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x5f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4a, 0x53, 0x5f, + 0x4e, 0x55, 0x4c, 0x4c, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x6e, + 0x75, 0x6c, 0x6c, 0x5f, 0x61, 0x73, 0x6d, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x6e, + 0x75, 0x6c, 0x6c, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x74, 0x72, + 0x75, 0x65, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x5f, 0x61, + 0x73, 0x6d, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x45, 0x58, 0x50, 0x52, 0x5f, 0x4d, 0x55, 0x4c, + 0x54, 0x49, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, + 0x49, 0x56, 0x45, 0x00, 0x0a, 0x74, 0x79, 0x70, + 0x65, 0x00, 0x0a, 0x65, 0x31, 0x00, 0x0a, 0x65, + 0x32, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x65, + 0x78, 0x70, 0x72, 0x5f, 0x6d, 0x75, 0x6c, 0x74, + 0x69, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x76, 0x65, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x6d, 0x75, 0x6c, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x64, 0x69, 0x76, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x6d, 0x6f, 0x64, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x45, 0x58, 0x50, 0x52, 0x5f, + 0x41, 0x44, 0x44, 0x49, 0x54, 0x49, 0x56, 0x45, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, + 0x70, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x69, 0x74, + 0x69, 0x76, 0x65, 0x5f, 0x61, 0x73, 0x6d, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, + 0x72, 0x5f, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, + 0x76, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x74, 0x5f, 0x66, 0x6f, 0x6c, 0x64, + 0x69, 0x6e, 0x67, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x73, 0x75, 0x62, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x45, 0x58, + 0x50, 0x52, 0x5f, 0x53, 0x48, 0x49, 0x46, 0x54, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, + 0x70, 0x72, 0x5f, 0x73, 0x68, 0x69, 0x66, 0x74, + 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x73, 0x68, + 0x69, 0x66, 0x74, 0x5f, 0x6c, 0x65, 0x66, 0x74, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x73, 0x68, 0x69, 0x66, 0x74, 0x5f, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x73, + 0x68, 0x69, 0x66, 0x74, 0x5f, 0x72, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x45, 0x58, 0x50, 0x52, 0x5f, 0x52, 0x45, + 0x4c, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x41, 0x4c, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, + 0x70, 0x72, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x61, 0x73, + 0x6d, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x63, 0x6d, 0x70, 0x5f, 0x6c, + 0x74, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x63, 0x6d, 0x70, 0x5f, 0x67, + 0x74, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x63, 0x6d, 0x70, 0x5f, 0x6c, + 0x65, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x45, + 0x58, 0x50, 0x52, 0x5f, 0x45, 0x51, 0x55, 0x41, + 0x4c, 0x49, 0x54, 0x59, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x65, + 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x5f, + 0x61, 0x73, 0x6d, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6d, 0x70, + 0x5f, 0x6e, 0x65, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6d, 0x70, + 0x5f, 0x73, 0x65, 0x71, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6d, + 0x70, 0x5f, 0x73, 0x6e, 0x65, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x2b, 0x6a, 0x73, 0x63, 0x3a, 0x20, + 0x65, 0x78, 0x70, 0x72, 0x5f, 0x65, 0x71, 0x75, + 0x61, 0x6c, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, + 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, + 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x45, 0x58, 0x50, 0x52, 0x5f, + 0x42, 0x49, 0x54, 0x57, 0x49, 0x53, 0x45, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, + 0x72, 0x5f, 0x62, 0x69, 0x74, 0x77, 0x69, 0x73, + 0x65, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x61, 0x73, + 0x6d, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x61, 0x6e, 0x64, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x62, 0x69, 0x74, 0x77, 0x69, 0x73, 0x65, + 0x5f, 0x6f, 0x72, 0x5f, 0x61, 0x73, 0x6d, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x6f, 0x72, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x62, 0x69, + 0x74, 0x77, 0x69, 0x73, 0x65, 0x5f, 0x78, 0x6f, + 0x72, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x78, + 0x6f, 0x72, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x45, 0x58, 0x50, 0x52, 0x5f, 0x4c, 0x4f, 0x47, + 0x49, 0x43, 0x41, 0x4c, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x6c, + 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x61, + 0x6e, 0x64, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, + 0x5f, 0x6f, 0x72, 0x5f, 0x61, 0x73, 0x6d, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, + 0x72, 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x61, 0x73, + 0x6d, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x65, + 0x78, 0x70, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x79, 0x5f, 0x61, 0x73, 0x6d, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, + 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x5f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5f, 0x61, + 0x73, 0x6d, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x65, 0x78, 0x70, 0x72, 0x5f, 0x63, 0x61, 0x6c, + 0x6c, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6a, + 0x73, 0x72, 0x5f, 0x77, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6a, 0x73, + 0x72, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x45, + 0x58, 0x50, 0x52, 0x5f, 0x41, 0x53, 0x53, 0x49, + 0x47, 0x4e, 0x4d, 0x45, 0x4e, 0x54, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, + 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x73, 0x6d, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x32, 0x3a, 0x20, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, + 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, + 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x69, + 0x6e, 0x20, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, + 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x65, 0x78, 0x70, + 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x67, 0x6c, 0x6f, + 0x62, 0x61, 0x6c, 0x5f, 0x77, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x77, 0x61, 0x72, 0x6e, 0x5f, + 0x77, 0x69, 0x74, 0x68, 0x5f, 0x63, 0x6c, 0x6f, + 0x62, 0x62, 0x65, 0x72, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x26, 0x3a, 0x20, 0x77, 0x61, 0x72, 0x6e, + 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x2d, 0x6c, 0x6f, + 0x6f, 0x6b, 0x75, 0x70, 0x20, 0x6f, 0x66, 0x20, + 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x20, 0x60, + 0x0a, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x29, 0x27, 0x20, 0x69, + 0x73, 0x20, 0x63, 0x6c, 0x6f, 0x62, 0x62, 0x65, + 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x20, 0x64, 0x65, 0x66, 0x69, + 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x04, 0x00, + 0x00, 0x00, 0x2f, 0x27, 0x20, 0x69, 0x73, 0x20, + 0x63, 0x6c, 0x6f, 0x62, 0x62, 0x65, 0x72, 0x65, + 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x76, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x20, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x5f, + 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x61, + 0x72, 0x72, 0x61, 0x79, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x5f, 0x61, 0x72, 0x67, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x45, 0x58, 0x50, + 0x52, 0x5f, 0x51, 0x55, 0x45, 0x53, 0x54, 0x5f, + 0x43, 0x4f, 0x4c, 0x4f, 0x4e, 0x00, 0x0a, 0x65, + 0x33, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x65, + 0x78, 0x70, 0x72, 0x5f, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x6e, 0x5f, + 0x61, 0x73, 0x6d, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x45, 0x58, 0x50, 0x52, 0x5f, 0x55, 0x4e, + 0x41, 0x52, 0x59, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x75, 0x6e, + 0x61, 0x72, 0x79, 0x5f, 0x61, 0x73, 0x6d, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x6e, 0x6f, 0x74, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6e, 0x65, + 0x67, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x64, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x5f, 0x61, 0x72, 0x72, 0x61, 0x79, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x32, 0x3a, 0x20, + 0x60, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, + 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x27, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, + 0x20, 0x6f, 0x75, 0x74, 0x73, 0x69, 0x64, 0x65, + 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x77, 0x69, + 0x74, 0x68, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x04, 0x00, 0x00, 0x00, 0x27, 0x3a, 0x20, 0x69, + 0x6c, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x20, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x20, 0x6f, 0x70, 0x65, + 0x72, 0x61, 0x6e, 0x64, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x6f, 0x66, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x2a, 0x6a, 0x73, 0x63, 0x3a, 0x20, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x20, 0x75, 0x6e, + 0x61, 0x72, 0x79, 0x20, 0x65, 0x78, 0x70, 0x72, + 0x27, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x69, 0x73, 0x20, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x45, 0x58, 0x50, 0x52, 0x5f, 0x50, 0x4f, 0x53, + 0x54, 0x46, 0x49, 0x58, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x70, + 0x6f, 0x73, 0x74, 0x66, 0x69, 0x78, 0x5f, 0x61, + 0x73, 0x6d, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x45, 0x58, 0x50, 0x52, 0x5f, 0x43, 0x4f, 0x4d, + 0x4d, 0x41, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x65, 0x78, 0x70, 0x72, 0x5f, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x4e, 0x61, 0x6d, 0x65, + 0x53, 0x70, 0x61, 0x63, 0x65, 0x46, 0x72, 0x61, + 0x6d, 0x65, 0x00, 0x0a, 0x66, 0x72, 0x61, 0x6d, + 0x65, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4e, + 0x61, 0x6d, 0x65, 0x53, 0x70, 0x61, 0x63, 0x65, + 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x72, + 0x61, 0x6d, 0x65, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x70, 0x61, + 0x63, 0x65, 0x5f, 0x70, 0x6f, 0x70, 0x5f, 0x66, + 0x72, 0x61, 0x6d, 0x65, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x70, + 0x61, 0x63, 0x65, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, + 0x63, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4e, 0x61, 0x6d, + 0x65, 0x53, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x64, + 0x65, 0x66, 0x69, 0x6e, 0x65, 0x5f, 0x73, 0x79, + 0x6d, 0x62, 0x6f, 0x6c, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x70, + 0x61, 0x63, 0x65, 0x5f, 0x6c, 0x6f, 0x6f, 0x6b, + 0x75, 0x70, 0x5f, 0x73, 0x79, 0x6d, 0x62, 0x6f, + 0x6c, 0x00, 0x0a, 0x6e, 0x75, 0x6d, 0x5f, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x00, 0x0a, 0x64, + 0x65, 0x66, 0x73, 0x00, 0x0a, 0x75, 0x73, 0x65, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x77, 0x61, 0x72, 0x6e, 0x5f, + 0x75, 0x6e, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x1c, 0x3a, 0x20, 0x77, + 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x3a, 0x20, + 0x75, 0x6e, 0x75, 0x73, 0x65, 0x64, 0x20, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x20, + 0x60, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x77, 0x61, + 0x72, 0x6e, 0x5f, 0x75, 0x6e, 0x75, 0x73, 0x65, + 0x64, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, + 0x6c, 0x65, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1c, + 0x3a, 0x20, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, + 0x67, 0x3a, 0x20, 0x75, 0x6e, 0x75, 0x73, 0x65, + 0x64, 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, + 0x6c, 0x65, 0x20, 0x60, 0x04, 0x00, 0x00, 0x00, + 0x14, 0x3a, 0x20, 0x72, 0x65, 0x64, 0x65, 0x63, + 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6f, 0x66, 0x20, 0x60, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x77, 0x61, 0x72, 0x6e, 0x5f, 0x73, + 0x68, 0x61, 0x64, 0x6f, 0x77, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x1b, 0x3a, 0x20, 0x77, 0x61, 0x72, + 0x6e, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x64, 0x65, + 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x60, 0x04, 0x00, + 0x00, 0x00, 0x15, 0x27, 0x20, 0x73, 0x68, 0x61, + 0x64, 0x6f, 0x77, 0x73, 0x20, 0x61, 0x20, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x53, 0x79, 0x6d, + 0x62, 0x6f, 0x6c, 0x44, 0x65, 0x66, 0x69, 0x6e, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x0a, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x46, 0x69, 0x6c, 0x65, 0x5f, 0x6f, 0x70, + 0x65, 0x6e, 0x00, 0x0a, 0x6f, 0x70, 0x65, 0x6e, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x46, 0x69, 0x6c, 0x65, + 0x5f, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x00, 0x0a, + 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x46, 0x69, 0x6c, 0x65, 0x5f, 0x72, 0x65, + 0x77, 0x69, 0x6e, 0x64, 0x00, 0x0a, 0x72, 0x65, + 0x77, 0x69, 0x6e, 0x64, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x46, 0x69, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x61, + 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x46, 0x69, 0x6c, 0x65, 0x5f, 0x75, + 0x6e, 0x67, 0x65, 0x74, 0x5f, 0x62, 0x79, 0x74, + 0x65, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x46, 0x69, 0x6c, + 0x65, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x6c, 0x6e, + 0x00, 0x0a, 0x72, 0x65, 0x61, 0x64, 0x6c, 0x6e, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x72, 0x0a, + 0x65, 0x72, 0x72, 0x6e, 0x6f, 0x00, 0x0a, 0x73, + 0x74, 0x72, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x00, + 0x0a, 0x73, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x0c, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x0a, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x00, 0x0a, 0x70, + 0x6f, 0x73, 0x00, 0x0a, 0x75, 0x6e, 0x67, 0x65, + 0x74, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, + 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, + 0x72, 0x65, 0x77, 0x69, 0x6e, 0x64, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x5f, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x62, 0x79, + 0x74, 0x65, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x75, 0x6e, 0x67, + 0x65, 0x74, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x6c, 0x6e, + 0x00, 0x0a, 0x63, 0x68, 0x61, 0x72, 0x43, 0x6f, + 0x64, 0x65, 0x41, 0x74, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x01, 0x43, 0x0a, 0x70, 0x61, 0x63, 0x6b, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x6e, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x4e, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x5f, + 0x53, 0x59, 0x4d, 0x42, 0x4f, 0x4c, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x61, 0x73, 0x6d, 0x5f, + 0x67, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x74, 0x00, 0x0a, 0x6f, 0x66, 0x66, + 0x73, 0x65, 0x74, 0x00, 0x0a, 0x73, 0x69, 0x7a, + 0x65, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x53, 0x59, 0x4d, 0x42, 0x4f, + 0x4c, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x73, 0x79, 0x6d, 0x62, 0x6f, + 0x6c, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x61, 0x73, 0x6d, 0x5f, + 0x6c, 0x69, 0x6e, 0x6b, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x01, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x02, + 0x3a, 0x0a, 0x0a, 0x77, 0x72, 0x69, 0x74, 0x65, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x4c, 0x41, 0x42, 0x45, 0x4c, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x61, 0x73, 0x6d, + 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x0a, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x64, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x5f, 0x66, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x00, 0x0a, 0x66, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x4f, 0x50, 0x5f, 0x48, 0x41, 0x4c, 0x54, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x68, 0x61, 0x6c, 0x74, 0x5f, 0x70, + 0x72, 0x69, 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x06, 0x09, 0x68, 0x61, 0x6c, 0x74, 0x0a, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, + 0x44, 0x4f, 0x4e, 0x45, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x64, 0x6f, + 0x6e, 0x65, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x09, 0x64, + 0x6f, 0x6e, 0x65, 0x0a, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x4f, 0x50, 0x5f, 0x4e, 0x4f, 0x50, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x6e, 0x6f, 0x70, 0x5f, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, + 0x09, 0x6e, 0x6f, 0x70, 0x0a, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x44, 0x55, 0x50, + 0x00, 0x0a, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, + 0x64, 0x65, 0x6c, 0x74, 0x61, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x64, + 0x75, 0x70, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x09, 0x64, + 0x75, 0x70, 0x0a, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x4f, 0x50, 0x5f, 0x50, 0x4f, 0x50, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x70, 0x6f, 0x70, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x09, + 0x70, 0x6f, 0x70, 0x0a, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x4f, 0x50, 0x5f, 0x50, 0x4f, 0x50, 0x5f, + 0x4e, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x70, 0x6f, 0x70, 0x5f, 0x6e, + 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x62, 0x79, 0x74, 0x65, 0x63, 0x6f, 0x64, 0x65, + 0x5f, 0x69, 0x6e, 0x74, 0x38, 0x00, 0x0a, 0x62, + 0x79, 0x74, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x08, 0x09, 0x70, 0x6f, + 0x70, 0x5f, 0x6e, 0x09, 0x09, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x41, 0x50, 0x4f, + 0x50, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x61, 0x70, 0x6f, 0x70, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x07, 0x09, 0x61, 0x70, 0x6f, 0x70, + 0x09, 0x09, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, + 0x50, 0x5f, 0x53, 0x57, 0x41, 0x50, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x73, 0x77, 0x61, 0x70, 0x5f, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, + 0x09, 0x73, 0x77, 0x61, 0x70, 0x0a, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x52, 0x4f, + 0x4c, 0x4c, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x72, 0x6f, 0x6c, 0x6c, + 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x07, 0x09, 0x72, 0x6f, 0x6c, + 0x6c, 0x09, 0x09, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x4f, 0x50, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x54, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x62, 0x79, 0x74, + 0x65, 0x63, 0x6f, 0x64, 0x65, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x04, 0x00, 0x00, 0x00, 0x08, 0x09, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x09, 0x09, 0x04, 0x00, + 0x00, 0x00, 0x08, 0x23, 0x62, 0x75, 0x69, 0x6c, + 0x74, 0x69, 0x6e, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x22, 0x04, 0x00, 0x00, 0x00, 0x01, 0x2f, 0x0a, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x5c, 0x0a, 0x63, 0x68, + 0x61, 0x72, 0x41, 0x74, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x02, 0x5c, 0x6e, 0x04, 0x00, 0x00, 0x00, + 0x02, 0x5c, 0x72, 0x04, 0x00, 0x00, 0x00, 0x02, + 0x5c, 0x74, 0x04, 0x00, 0x00, 0x00, 0x02, 0x5c, + 0x66, 0x0a, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x67, 0x0a, + 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x43, 0x61, + 0x73, 0x65, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x69, 0x0a, 0x69, 0x73, 0x49, 0x6e, 0x74, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x43, 0x4f, 0x4e, + 0x53, 0x54, 0x5f, 0x49, 0x4e, 0x54, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x43, 0x4e, 0x0a, 0x69, + 0x73, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x43, 0x4f, 0x4e, 0x53, + 0x54, 0x5f, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x02, 0x43, 0x64, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x43, 0x4f, 0x4e, 0x53, + 0x54, 0x5f, 0x4e, 0x41, 0x4e, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x43, 0x4f, 0x4e, 0x53, 0x54, + 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x43, 0x4f, 0x4e, + 0x53, 0x54, 0x5f, 0x52, 0x45, 0x47, 0x45, 0x58, + 0x50, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x5f, 0x47, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x43, 0x4f, + 0x4e, 0x53, 0x54, 0x5f, 0x52, 0x45, 0x47, 0x45, + 0x58, 0x50, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x5f, + 0x49, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x43, + 0x4f, 0x4e, 0x53, 0x54, 0x5f, 0x52, 0x45, 0x47, + 0x45, 0x58, 0x50, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x03, 0x43, 0x43, 0x4e, 0x04, 0x00, 0x00, 0x00, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x63, + 0x6f, 0x64, 0x65, 0x28, 0x29, 0x3a, 0x20, 0x75, + 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x3a, 0x20, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x43, 0x4f, 0x4e, + 0x53, 0x54, 0x5f, 0x4e, 0x55, 0x4c, 0x4c, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x6e, + 0x75, 0x6c, 0x6c, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, 0x09, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x6e, 0x75, + 0x6c, 0x6c, 0x0a, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x4f, 0x50, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x54, + 0x5f, 0x54, 0x52, 0x55, 0x45, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x74, 0x72, 0x75, + 0x65, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x0c, 0x09, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x5f, 0x74, 0x72, 0x75, 0x65, + 0x0a, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, + 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x5f, 0x46, + 0x41, 0x4c, 0x53, 0x45, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x5f, 0x66, 0x61, 0x6c, 0x73, + 0x65, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x0d, 0x09, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x5f, 0x66, 0x61, 0x6c, 0x73, + 0x65, 0x0a, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, + 0x50, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x5f, + 0x55, 0x4e, 0x44, 0x45, 0x46, 0x49, 0x4e, 0x45, + 0x44, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x5f, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, + 0x65, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0x09, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x75, 0x6e, 0x64, + 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x0a, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x43, + 0x4f, 0x4e, 0x53, 0x54, 0x5f, 0x49, 0x30, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x69, + 0x30, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x0a, 0x09, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x5f, 0x69, 0x30, 0x0a, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x43, + 0x4f, 0x4e, 0x53, 0x54, 0x5f, 0x49, 0x31, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x69, + 0x31, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x0a, 0x09, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x5f, 0x69, 0x31, 0x0a, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x43, + 0x4f, 0x4e, 0x53, 0x54, 0x5f, 0x49, 0x32, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x69, + 0x32, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x0a, 0x09, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x5f, 0x69, 0x32, 0x0a, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x43, + 0x4f, 0x4e, 0x53, 0x54, 0x5f, 0x49, 0x33, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x69, + 0x33, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x0a, 0x09, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x5f, 0x69, 0x33, 0x0a, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x43, + 0x4f, 0x4e, 0x53, 0x54, 0x5f, 0x49, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x69, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x62, + 0x79, 0x74, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x5f, + 0x69, 0x6e, 0x74, 0x33, 0x32, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x5f, 0x69, 0x09, 0x09, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x4c, 0x4f, 0x41, + 0x44, 0x5f, 0x47, 0x4c, 0x4f, 0x42, 0x41, 0x4c, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x67, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x62, 0x79, 0x74, + 0x65, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x73, 0x79, + 0x6d, 0x62, 0x6f, 0x6c, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x0d, 0x09, 0x6c, 0x6f, 0x61, 0x64, 0x5f, + 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x09, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x53, + 0x54, 0x4f, 0x52, 0x45, 0x5f, 0x47, 0x4c, 0x4f, + 0x42, 0x41, 0x4c, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x0e, 0x09, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x5f, 0x67, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x09, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x4f, 0x50, 0x5f, 0x4c, 0x4f, 0x41, 0x44, 0x5f, + 0x41, 0x52, 0x47, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6c, 0x6f, 0x61, + 0x64, 0x5f, 0x61, 0x72, 0x67, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x0a, 0x09, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x61, + 0x72, 0x67, 0x09, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x4f, 0x50, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x45, + 0x5f, 0x41, 0x52, 0x47, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x5f, 0x61, 0x72, 0x67, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x0b, 0x09, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x5f, 0x61, 0x72, 0x67, 0x09, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x4c, 0x4f, + 0x41, 0x44, 0x5f, 0x4c, 0x4f, 0x43, 0x41, 0x4c, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x62, 0x79, 0x74, 0x65, + 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x6e, 0x74, + 0x31, 0x36, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, + 0x09, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x09, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x4f, 0x50, 0x5f, 0x53, 0x54, 0x4f, 0x52, + 0x45, 0x5f, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0d, + 0x09, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x09, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x4c, 0x4f, 0x41, + 0x44, 0x5f, 0x50, 0x52, 0x4f, 0x50, 0x45, 0x52, + 0x54, 0x59, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x6c, 0x6f, 0x61, 0x64, + 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x79, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x0f, 0x09, 0x6c, 0x6f, + 0x61, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x79, 0x09, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x4f, 0x50, 0x5f, 0x53, 0x54, 0x4f, 0x52, + 0x45, 0x5f, 0x50, 0x52, 0x4f, 0x50, 0x45, 0x52, + 0x54, 0x59, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x09, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x70, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x09, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x4c, 0x4f, + 0x41, 0x44, 0x5f, 0x41, 0x52, 0x52, 0x41, 0x59, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x61, + 0x72, 0x72, 0x61, 0x79, 0x5f, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, + 0x09, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x61, 0x72, + 0x72, 0x61, 0x79, 0x0a, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x4f, 0x50, 0x5f, 0x53, 0x54, 0x4f, 0x52, + 0x45, 0x5f, 0x41, 0x52, 0x52, 0x41, 0x59, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x61, + 0x72, 0x72, 0x61, 0x79, 0x5f, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0d, + 0x09, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x61, + 0x72, 0x72, 0x61, 0x79, 0x0a, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x4e, 0x54, 0x48, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x6e, 0x74, 0x68, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x05, 0x09, 0x6e, 0x74, 0x68, 0x0a, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x43, 0x4d, + 0x50, 0x5f, 0x45, 0x51, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6d, + 0x70, 0x5f, 0x65, 0x71, 0x5f, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, + 0x09, 0x63, 0x6d, 0x70, 0x5f, 0x65, 0x71, 0x0a, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, + 0x43, 0x4d, 0x50, 0x5f, 0x4e, 0x45, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x63, 0x6d, 0x70, 0x5f, 0x6e, 0x65, 0x5f, 0x70, + 0x72, 0x69, 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x08, 0x09, 0x63, 0x6d, 0x70, 0x5f, 0x6e, + 0x65, 0x0a, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, + 0x50, 0x5f, 0x43, 0x4d, 0x50, 0x5f, 0x4c, 0x54, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x63, 0x6d, 0x70, 0x5f, 0x6c, 0x74, + 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x08, 0x09, 0x63, 0x6d, 0x70, + 0x5f, 0x6c, 0x74, 0x0a, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x4f, 0x50, 0x5f, 0x43, 0x4d, 0x50, 0x5f, + 0x47, 0x54, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6d, 0x70, 0x5f, + 0x67, 0x74, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x09, 0x63, + 0x6d, 0x70, 0x5f, 0x67, 0x74, 0x0a, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x43, 0x4d, + 0x50, 0x5f, 0x4c, 0x45, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6d, + 0x70, 0x5f, 0x6c, 0x65, 0x5f, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, + 0x09, 0x63, 0x6d, 0x70, 0x5f, 0x6c, 0x65, 0x0a, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, + 0x43, 0x4d, 0x50, 0x5f, 0x47, 0x45, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x63, 0x6d, 0x70, 0x5f, 0x67, 0x65, 0x5f, 0x70, + 0x72, 0x69, 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x08, 0x09, 0x63, 0x6d, 0x70, 0x5f, 0x67, + 0x65, 0x0a, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, + 0x50, 0x5f, 0x43, 0x4d, 0x50, 0x5f, 0x53, 0x45, + 0x51, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x63, 0x6d, 0x70, 0x5f, 0x73, + 0x65, 0x71, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x09, 0x63, + 0x6d, 0x70, 0x5f, 0x73, 0x65, 0x71, 0x0a, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x43, + 0x4d, 0x50, 0x5f, 0x53, 0x4e, 0x45, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x63, 0x6d, 0x70, 0x5f, 0x73, 0x6e, 0x65, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x09, 0x09, 0x63, 0x6d, 0x70, 0x5f, + 0x73, 0x6e, 0x65, 0x0a, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x4f, 0x50, 0x5f, 0x53, 0x55, 0x42, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x73, 0x75, 0x62, 0x5f, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, + 0x09, 0x73, 0x75, 0x62, 0x0a, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x41, 0x44, 0x44, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x61, 0x64, 0x64, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x05, 0x09, 0x61, 0x64, 0x64, 0x0a, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x4d, 0x55, + 0x4c, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x6d, 0x75, 0x6c, 0x5f, 0x70, + 0x72, 0x69, 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x05, 0x09, 0x6d, 0x75, 0x6c, 0x0a, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x44, + 0x49, 0x56, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x64, 0x69, 0x76, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x05, 0x09, 0x64, 0x69, 0x76, 0x0a, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, + 0x4d, 0x4f, 0x44, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6d, 0x6f, 0x64, + 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x05, 0x09, 0x6d, 0x6f, 0x64, + 0x0a, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, + 0x5f, 0x4e, 0x45, 0x47, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6e, 0x65, + 0x67, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x05, 0x09, 0x6e, 0x65, + 0x67, 0x0a, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, + 0x50, 0x5f, 0x41, 0x4e, 0x44, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x61, + 0x6e, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x09, 0x61, + 0x6e, 0x64, 0x0a, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x4f, 0x50, 0x5f, 0x4e, 0x4f, 0x54, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x6e, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x09, + 0x6e, 0x6f, 0x74, 0x0a, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x4f, 0x50, 0x5f, 0x4f, 0x52, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x09, 0x6f, + 0x72, 0x0a, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, + 0x50, 0x5f, 0x58, 0x4f, 0x52, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x78, + 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x09, 0x78, + 0x6f, 0x72, 0x0a, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x4f, 0x50, 0x5f, 0x53, 0x48, 0x49, 0x46, 0x54, + 0x5f, 0x4c, 0x45, 0x46, 0x54, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x73, + 0x68, 0x69, 0x66, 0x74, 0x5f, 0x6c, 0x65, 0x66, + 0x74, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x0c, 0x09, 0x73, 0x68, + 0x69, 0x66, 0x74, 0x5f, 0x6c, 0x65, 0x66, 0x74, + 0x0a, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, + 0x5f, 0x53, 0x48, 0x49, 0x46, 0x54, 0x5f, 0x52, + 0x49, 0x47, 0x48, 0x54, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x73, 0x68, + 0x69, 0x66, 0x74, 0x5f, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x0d, 0x09, 0x73, 0x68, + 0x69, 0x66, 0x74, 0x5f, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x0a, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, + 0x50, 0x5f, 0x53, 0x48, 0x49, 0x46, 0x54, 0x5f, + 0x52, 0x52, 0x49, 0x47, 0x48, 0x54, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x73, 0x68, 0x69, 0x66, 0x74, 0x5f, 0x72, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x5f, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0e, + 0x09, 0x73, 0x68, 0x69, 0x66, 0x74, 0x5f, 0x72, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x0a, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x49, 0x46, + 0x46, 0x41, 0x4c, 0x53, 0x45, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x69, + 0x66, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x5f, 0x70, + 0x72, 0x69, 0x6e, 0x74, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x62, 0x79, + 0x74, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x6a, 0x75, 0x6d, + 0x70, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x09, + 0x69, 0x66, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x09, + 0x09, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, + 0x5f, 0x49, 0x46, 0x54, 0x52, 0x55, 0x45, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x69, 0x66, 0x74, 0x72, 0x75, 0x65, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x09, 0x09, 0x69, 0x66, 0x74, 0x72, + 0x75, 0x65, 0x09, 0x09, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x4f, 0x50, 0x5f, 0x43, 0x41, 0x4c, 0x4c, + 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x6d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x5f, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0d, + 0x09, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x6d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x09, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x4a, 0x4d, 0x50, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x6a, 0x6d, 0x70, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x06, 0x09, 0x6a, 0x6d, 0x70, 0x09, 0x09, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x4a, + 0x53, 0x52, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x6a, 0x73, 0x72, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x05, 0x09, 0x6a, 0x73, 0x72, 0x0a, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, + 0x52, 0x45, 0x54, 0x55, 0x52, 0x4e, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x70, + 0x72, 0x69, 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x08, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x0a, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, + 0x50, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x4f, 0x46, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, + 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x08, 0x09, 0x74, 0x79, 0x70, + 0x65, 0x6f, 0x66, 0x0a, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x4f, 0x50, 0x5f, 0x4e, 0x45, 0x57, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, + 0x09, 0x6e, 0x65, 0x77, 0x0a, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x44, 0x45, 0x4c, + 0x45, 0x54, 0x45, 0x5f, 0x50, 0x52, 0x4f, 0x50, + 0x45, 0x52, 0x54, 0x59, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x70, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x11, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x79, 0x09, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, + 0x50, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, + 0x5f, 0x41, 0x52, 0x52, 0x41, 0x59, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x61, + 0x72, 0x72, 0x61, 0x79, 0x5f, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0e, + 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, + 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x4c, 0x4f, + 0x43, 0x41, 0x4c, 0x53, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x73, 0x5f, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x09, + 0x09, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, + 0x5f, 0x4d, 0x49, 0x4e, 0x5f, 0x41, 0x52, 0x47, + 0x53, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x6d, 0x69, 0x6e, 0x5f, 0x61, + 0x72, 0x67, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x09, + 0x6d, 0x69, 0x6e, 0x5f, 0x61, 0x72, 0x67, 0x73, + 0x09, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, + 0x5f, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x4e, 0x54, + 0x48, 0x5f, 0x41, 0x52, 0x47, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6c, + 0x6f, 0x61, 0x64, 0x5f, 0x6e, 0x74, 0x68, 0x5f, + 0x61, 0x72, 0x67, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0e, 0x09, + 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x6e, 0x74, 0x68, + 0x5f, 0x61, 0x72, 0x67, 0x0a, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x57, 0x49, 0x54, + 0x48, 0x5f, 0x50, 0x55, 0x53, 0x48, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x77, 0x69, 0x74, 0x68, 0x5f, 0x70, 0x75, 0x73, + 0x68, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x0b, 0x09, 0x77, 0x69, + 0x74, 0x68, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x0a, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, + 0x57, 0x49, 0x54, 0x48, 0x5f, 0x50, 0x4f, 0x50, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x70, + 0x6f, 0x70, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x09, 0x77, + 0x69, 0x74, 0x68, 0x5f, 0x70, 0x6f, 0x70, 0x09, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, + 0x54, 0x52, 0x59, 0x5f, 0x50, 0x55, 0x53, 0x48, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x74, 0x72, 0x79, 0x5f, 0x70, 0x75, + 0x73, 0x68, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x09, 0x74, + 0x72, 0x79, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x09, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, + 0x54, 0x52, 0x59, 0x5f, 0x50, 0x4f, 0x50, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x74, 0x72, 0x79, 0x5f, 0x70, 0x6f, 0x70, + 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0a, 0x09, 0x74, 0x72, 0x79, + 0x5f, 0x70, 0x6f, 0x70, 0x09, 0x09, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x54, 0x48, + 0x52, 0x4f, 0x57, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x74, 0x68, 0x72, + 0x6f, 0x77, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x07, 0x09, 0x74, + 0x68, 0x72, 0x6f, 0x77, 0x0a, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x49, 0x46, 0x46, + 0x41, 0x4c, 0x53, 0x45, 0x5f, 0x42, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x69, 0x66, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x5f, + 0x62, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x0b, 0x09, 0x69, 0x66, + 0x66, 0x61, 0x6c, 0x73, 0x65, 0x5f, 0x62, 0x09, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, + 0x49, 0x46, 0x54, 0x52, 0x55, 0x45, 0x5f, 0x42, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x69, 0x66, 0x74, 0x72, 0x75, 0x65, + 0x5f, 0x62, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x09, 0x69, + 0x66, 0x74, 0x72, 0x75, 0x65, 0x5f, 0x62, 0x09, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, 0x5f, + 0x41, 0x44, 0x44, 0x5f, 0x31, 0x5f, 0x49, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x61, 0x64, 0x64, 0x5f, 0x31, 0x5f, 0x69, + 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x09, 0x09, 0x61, 0x64, 0x64, + 0x5f, 0x31, 0x5f, 0x69, 0x0a, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x4f, 0x50, 0x5f, 0x41, 0x44, 0x44, + 0x5f, 0x32, 0x5f, 0x49, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x61, 0x64, + 0x64, 0x5f, 0x32, 0x5f, 0x69, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x09, 0x09, 0x61, 0x64, 0x64, 0x5f, 0x32, 0x5f, + 0x69, 0x0a, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, + 0x50, 0x5f, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x47, + 0x4c, 0x4f, 0x42, 0x41, 0x4c, 0x5f, 0x57, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x67, 0x6c, + 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x77, 0x5f, 0x70, + 0x72, 0x69, 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x0f, 0x09, 0x6c, 0x6f, 0x61, 0x64, 0x5f, + 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x77, + 0x09, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x4f, 0x50, + 0x5f, 0x4a, 0x53, 0x52, 0x5f, 0x57, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x6a, 0x73, 0x72, 0x5f, 0x77, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x08, 0x09, 0x6a, 0x73, 0x72, 0x5f, 0x77, 0x09, + 0x09, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x61, 0x73, + 0x6d, 0x5f, 0x74, 0x61, 0x69, 0x6c, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x61, 0x73, 0x6d, 0x5f, + 0x74, 0x61, 0x69, 0x6c, 0x5f, 0x70, 0x72, 0x65, + 0x76, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x61, + 0x73, 0x6d, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x61, 0x73, 0x6d, + 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x61, 0x73, 0x6d, 0x5f, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x74, 0x73, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x61, 0x73, 0x6d, 0x5f, + 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x73, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x19, 0x6a, 0x73, 0x63, + 0x3a, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x73, 0x73, + 0x65, 0x6d, 0x62, 0x6c, 0x65, 0x72, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x4e, 0x61, 0x6d, 0x65, 0x53, + 0x70, 0x61, 0x63, 0x65, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x07, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x04, 0x00, 0x00, 0x00, 0x0e, 0x3b, 0x20, + 0x2d, 0x2a, 0x2d, 0x20, 0x61, 0x73, 0x6d, 0x20, + 0x2d, 0x2a, 0x2d, 0x0a, 0x0a, 0x70, 0x72, 0x65, + 0x76, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x75, + 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, + 0x04, 0x00, 0x00, 0x00, 0x14, 0x3b, 0x20, 0x75, + 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, + 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x6e, 0x75, 0x6d, + 0x0a, 0x04, 0x00, 0x00, 0x00, 0x02, 0x3b, 0x20, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x46, 0x4c, 0x41, + 0x47, 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4d, 0x49, + 0x5a, 0x45, 0x5f, 0x50, 0x45, 0x45, 0x50, 0x48, + 0x4f, 0x4c, 0x45, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x17, 0x6a, 0x73, 0x63, 0x3a, 0x20, 0x6f, 0x70, + 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x3a, 0x20, + 0x70, 0x65, 0x65, 0x70, 0x68, 0x6f, 0x6c, 0x65, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x61, 0x73, 0x6d, + 0x5f, 0x69, 0x73, 0x5f, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x5f, 0x6a, 0x75, 0x6d, 0x70, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x46, 0x4c, 0x41, 0x47, + 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4d, 0x49, 0x5a, + 0x45, 0x5f, 0x4a, 0x55, 0x4d, 0x50, 0x53, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x1d, 0x6a, 0x73, 0x63, + 0x3a, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, + 0x7a, 0x65, 0x3a, 0x20, 0x6a, 0x75, 0x6d, 0x70, + 0x73, 0x20, 0x74, 0x6f, 0x20, 0x6a, 0x75, 0x6d, + 0x70, 0x73, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x61, + 0x73, 0x6d, 0x5f, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, + 0x70, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x6f, + 0x70, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x46, + 0x4c, 0x41, 0x47, 0x5f, 0x4f, 0x50, 0x54, 0x49, + 0x4d, 0x49, 0x5a, 0x45, 0x5f, 0x48, 0x45, 0x41, + 0x56, 0x59, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, + 0x5f, 0x68, 0x65, 0x61, 0x76, 0x79, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x46, 0x4c, 0x41, 0x47, + 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4d, 0x49, 0x5a, + 0x45, 0x5f, 0x42, 0x43, 0x5f, 0x53, 0x49, 0x5a, + 0x45, 0x00, 0x04, 0x00, 0x00, 0x00, 0x2c, 0x6a, + 0x73, 0x63, 0x3a, 0x20, 0x6f, 0x70, 0x74, 0x69, + 0x6d, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x72, 0x65, + 0x6d, 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x75, + 0x6e, 0x2d, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x64, 0x20, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x73, 0x04, 0x00, 0x00, 0x00, 0x24, + 0x6a, 0x73, 0x63, 0x3a, 0x20, 0x6f, 0x70, 0x74, + 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x64, + 0x65, 0x61, 0x64, 0x20, 0x63, 0x6f, 0x64, 0x65, + 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x04, 0x00, 0x00, 0x00, + 0x21, 0x6a, 0x73, 0x63, 0x3a, 0x20, 0x6f, 0x70, + 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x3a, 0x20, + 0x6c, 0x69, 0x76, 0x65, 0x6e, 0x65, 0x73, 0x73, + 0x20, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x69, + 0x6e, 0x67, 0x0a, 0x6c, 0x69, 0x76, 0x65, 0x5f, + 0x61, 0x72, 0x67, 0x73, 0x00, 0x0a, 0x6c, 0x69, + 0x76, 0x65, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x73, 0x00, 0x0a, 0x6c, 0x69, 0x76, 0x65, 0x5f, + 0x75, 0x73, 0x65, 0x64, 0x00, 0x03, 0xff, 0xff, + 0xff, 0xff, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x43, + 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x52, + 0x65, 0x67, 0x00, 0x04, 0x00, 0x00, 0x00, 0x19, + 0x6a, 0x73, 0x63, 0x3a, 0x20, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, + 0x62, 0x79, 0x74, 0x65, 0x2d, 0x63, 0x6f, 0x64, + 0x65, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x64, + 0x65, 0x62, 0x75, 0x67, 0x5f, 0x69, 0x6e, 0x66, + 0x6f, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x44, + 0x45, 0x42, 0x55, 0x47, 0x5f, 0x46, 0x49, 0x4c, + 0x45, 0x4e, 0x41, 0x4d, 0x45, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x44, 0x45, 0x42, 0x55, 0x47, + 0x5f, 0x4c, 0x49, 0x4e, 0x45, 0x4e, 0x55, 0x4d, + 0x42, 0x45, 0x52, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x03, 0x43, 0x4e, 0x4e, 0x04, 0x00, 0x00, 0x00, + 0x0a, 0x6a, 0x73, 0x63, 0x3a, 0x20, 0x63, 0x6f, + 0x64, 0x65, 0x3d, 0x04, 0x00, 0x00, 0x00, 0x0c, + 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x74, 0x73, 0x3d, 0x04, 0x00, 0x00, 0x00, + 0x09, 0x2c, 0x20, 0x73, 0x79, 0x6d, 0x74, 0x61, + 0x62, 0x3d, 0x04, 0x00, 0x00, 0x00, 0x08, 0x2c, + 0x20, 0x64, 0x65, 0x62, 0x75, 0x67, 0x3d, 0x04, + 0x00, 0x00, 0x00, 0x0a, 0x2c, 0x20, 0x68, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x73, 0x3d, 0x04, 0x00, + 0x00, 0x00, 0x08, 0x2c, 0x20, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x3d, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x42, 0x43, 0x5f, 0x4d, 0x41, 0x47, 0x49, 0x43, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x4e, 0x4e, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x42, 0x43, 0x5f, + 0x53, 0x45, 0x43, 0x54, 0x5f, 0x43, 0x4f, 0x44, + 0x45, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x42, + 0x43, 0x5f, 0x53, 0x45, 0x43, 0x54, 0x5f, 0x43, + 0x4f, 0x4e, 0x53, 0x54, 0x41, 0x4e, 0x54, 0x53, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x42, 0x43, + 0x5f, 0x53, 0x45, 0x43, 0x54, 0x5f, 0x53, 0x59, + 0x4d, 0x54, 0x41, 0x42, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x42, 0x43, 0x5f, 0x53, 0x45, 0x43, + 0x54, 0x5f, 0x44, 0x45, 0x42, 0x55, 0x47, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x46, 0x69, 0x6c, 0x65, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x63, 0x6f, 0x6d, + 0x70, 0x69, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x72, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x74, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x67, 0x72, 0x61, + 0x6d, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x74, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x61, 0x73, 0x6d, + 0x5f, 0x72, 0x65, 0x73, 0x65, 0x74, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x63, 0x6f, 0x6d, 0x70, + 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x73, + 0x65, 0x74, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x46, 0x4c, 0x41, 0x47, 0x5f, 0x56, 0x45, 0x52, + 0x42, 0x4f, 0x53, 0x45, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x46, 0x4c, 0x41, 0x47, 0x5f, 0x47, + 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x45, 0x5f, + 0x44, 0x45, 0x42, 0x55, 0x47, 0x5f, 0x49, 0x4e, + 0x46, 0x4f, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x46, 0x4c, 0x41, 0x47, 0x5f, 0x57, 0x41, 0x52, + 0x4e, 0x5f, 0x55, 0x4e, 0x55, 0x53, 0x45, 0x44, + 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, + 0x54, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x46, + 0x4c, 0x41, 0x47, 0x5f, 0x57, 0x41, 0x52, 0x4e, + 0x5f, 0x55, 0x4e, 0x55, 0x53, 0x45, 0x44, 0x5f, + 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, 0x45, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x46, 0x4c, + 0x41, 0x47, 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x5f, + 0x53, 0x48, 0x41, 0x44, 0x4f, 0x57, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x46, 0x4c, 0x41, 0x47, + 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x5f, 0x57, 0x49, + 0x54, 0x48, 0x5f, 0x43, 0x4c, 0x4f, 0x42, 0x42, + 0x45, 0x52, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x46, 0x4c, 0x41, 0x47, 0x5f, 0x57, 0x41, 0x52, + 0x4e, 0x5f, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4e, + 0x47, 0x5f, 0x53, 0x45, 0x4d, 0x49, 0x43, 0x4f, + 0x4c, 0x4f, 0x4e, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x46, 0x4c, 0x41, 0x47, 0x5f, 0x57, 0x41, + 0x52, 0x4e, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x43, + 0x54, 0x5f, 0x45, 0x43, 0x4d, 0x41, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x46, 0x4c, 0x41, 0x47, + 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x5f, 0x44, 0x45, + 0x50, 0x52, 0x45, 0x43, 0x41, 0x54, 0x45, 0x44, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x61, 0x73, 0x6d, 0x5f, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x46, 0x4c, 0x41, 0x47, 0x5f, 0x4f, + 0x50, 0x54, 0x49, 0x4d, 0x49, 0x5a, 0x45, 0x5f, + 0x4d, 0x41, 0x53, 0x4b, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x61, 0x73, 0x6d, 0x5f, 0x6f, 0x70, + 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x77, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x46, 0x4c, 0x41, 0x47, 0x5f, 0x41, + 0x4e, 0x4e, 0x4f, 0x54, 0x41, 0x54, 0x45, 0x5f, + 0x41, 0x53, 0x53, 0x45, 0x4d, 0x42, 0x4c, 0x45, + 0x52, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x61, + 0x73, 0x6d, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x26, 0x6a, 0x73, + 0x63, 0x3a, 0x20, 0x63, 0x6f, 0x75, 0x6c, 0x64, + 0x6e, 0x27, 0x74, 0x20, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x20, 0x61, 0x73, 0x6d, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x66, 0x69, + 0x6c, 0x65, 0x20, 0x22, 0x04, 0x00, 0x00, 0x00, + 0x03, 0x22, 0x3a, 0x20, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x61, 0x73, 0x6d, 0x5f, 0x66, 0x69, 0x6e, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x61, 0x73, 0x6d, 0x5f, 0x62, + 0x79, 0x74, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x46, 0x4c, 0x41, + 0x47, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, + 0x54, 0x45, 0x5f, 0x45, 0x58, 0x45, 0x43, 0x55, + 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x42, 0x43, + 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x53, 0x00, 0x0a, + 0x73, 0x74, 0x61, 0x74, 0x00, 0x0a, 0x63, 0x68, + 0x6d, 0x6f, 0x64, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x32, 0x6a, 0x73, 0x63, 0x3a, 0x20, 0x63, 0x6f, + 0x75, 0x6c, 0x64, 0x6e, 0x27, 0x74, 0x20, 0x61, + 0x64, 0x64, 0x20, 0x65, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x65, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, + 0x6f, 0x20, 0x62, 0x63, 0x20, 0x66, 0x69, 0x6c, + 0x65, 0x20, 0x22, 0x04, 0x00, 0x00, 0x00, 0x1c, + 0x6a, 0x73, 0x63, 0x3a, 0x20, 0x63, 0x6f, 0x75, + 0x6c, 0x64, 0x6e, 0x27, 0x74, 0x20, 0x73, 0x74, + 0x61, 0x74, 0x20, 0x62, 0x63, 0x20, 0x66, 0x69, + 0x6c, 0x65, 0x20, 0x22, 0x04, 0x00, 0x00, 0x00, + 0x1e, 0x6a, 0x73, 0x63, 0x3a, 0x20, 0x63, 0x6f, + 0x75, 0x6c, 0x64, 0x6e, 0x27, 0x74, 0x20, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x62, 0x63, + 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x22, 0x04, + 0x00, 0x00, 0x00, 0x21, 0x6a, 0x73, 0x63, 0x3a, + 0x20, 0x63, 0x6f, 0x75, 0x6c, 0x64, 0x6e, 0x27, + 0x74, 0x20, 0x6f, 0x70, 0x65, 0x6e, 0x20, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x20, 0x73, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x20, 0x22, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x45, 0x58, 0x50, 0x52, 0x5f, 0x44, + 0x45, 0x4c, 0x45, 0x54, 0x45, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x45, 0x58, 0x50, 0x52, 0x5f, + 0x56, 0x4f, 0x49, 0x44, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x45, 0x58, 0x50, 0x52, 0x5f, 0x54, + 0x59, 0x50, 0x45, 0x4f, 0x46, 0x00, 0x0a, 0x4a, + 0x53, 0x43, 0x24, 0x45, 0x58, 0x50, 0x52, 0x5f, + 0x50, 0x52, 0x45, 0x46, 0x49, 0x58, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x4a, 0x53, 0x5f, 0x55, + 0x4e, 0x44, 0x45, 0x46, 0x49, 0x4e, 0x45, 0x44, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x43, 0x6f, + 0x6e, 0x74, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x24, + 0x70, 0x75, 0x73, 0x68, 0x00, 0x0a, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x43, 0x6f, 0x6e, + 0x74, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x24, 0x70, + 0x6f, 0x70, 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, + 0x43, 0x6f, 0x6e, 0x74, 0x42, 0x72, 0x65, 0x61, + 0x6b, 0x24, 0x74, 0x72, 0x79, 0x5f, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x6e, 0x65, 0x73, + 0x74, 0x69, 0x6e, 0x67, 0x00, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x43, 0x6f, 0x6e, 0x74, 0x42, 0x72, + 0x65, 0x61, 0x6b, 0x24, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x6e, + 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x00, 0x0a, + 0x4a, 0x53, 0x43, 0x24, 0x43, 0x6f, 0x6e, 0x74, + 0x42, 0x72, 0x65, 0x61, 0x6b, 0x24, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x72, 0x79, 0x5f, + 0x6e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x43, 0x6f, 0x6e, + 0x74, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x24, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x73, 0x77, 0x69, + 0x74, 0x63, 0x68, 0x5f, 0x6e, 0x65, 0x73, 0x74, + 0x69, 0x6e, 0x67, 0x00, 0x0a, 0x4a, 0x53, 0x43, + 0x24, 0x43, 0x6f, 0x6e, 0x74, 0x42, 0x72, 0x65, + 0x61, 0x6b, 0x24, 0x67, 0x65, 0x74, 0x5f, 0x63, + 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x43, 0x6f, 0x6e, + 0x74, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x24, 0x67, + 0x65, 0x74, 0x5f, 0x62, 0x72, 0x65, 0x61, 0x6b, + 0x00, 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x43, 0x6f, + 0x6e, 0x74, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x24, + 0x69, 0x73, 0x5f, 0x75, 0x6e, 0x69, 0x71, 0x75, + 0x65, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x00, + 0x0a, 0x4a, 0x53, 0x43, 0x24, 0x46, 0x4c, 0x41, + 0x47, 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x5f, 0x4d, + 0x41, 0x53, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x25, 0x9c, 0x00, 0x00, 0x01, 0x7f, + 0x4a, 0x53, 0x43, 0x24, 0x6c, 0x65, 0x78, 0x65, + 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x53, + 0x43, 0x24, 0x6c, 0x65, 0x78, 0x65, 0x72, 0x5f, + 0x70, 0x65, 0x65, 0x6b, 0x5f, 0x63, 0x68, 0x61, + 0x72, 0x00, 0x00, 0x00, 0x0f, 0x47, 0x4a, 0x53, + 0x43, 0x24, 0x6c, 0x65, 0x78, 0x65, 0x72, 0x5f, + 0x69, 0x73, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x72, 0x5f, 0x6c, 0x65, + 0x74, 0x74, 0x65, 0x72, 0x00, 0x00, 0x00, 0x0f, + 0x6d, 0x4a, 0x53, 0x43, 0x24, 0x6c, 0x65, 0x78, + 0x65, 0x72, 0x5f, 0x69, 0x73, 0x5f, 0x6f, 0x63, + 0x74, 0x61, 0x6c, 0x5f, 0x64, 0x69, 0x67, 0x69, + 0x74, 0x00, 0x00, 0x00, 0x0f, 0xc6, 0x4a, 0x53, + 0x43, 0x24, 0x6c, 0x65, 0x78, 0x65, 0x72, 0x5f, + 0x69, 0x73, 0x5f, 0x64, 0x65, 0x63, 0x69, 0x6d, + 0x61, 0x6c, 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, + 0x00, 0x00, 0x00, 0x0f, 0xe3, 0x4a, 0x53, 0x43, + 0x24, 0x6c, 0x65, 0x78, 0x65, 0x72, 0x5f, 0x69, + 0x73, 0x5f, 0x68, 0x65, 0x78, 0x5f, 0x64, 0x69, + 0x67, 0x69, 0x74, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x4a, 0x53, 0x43, 0x24, 0x6c, 0x65, 0x78, 0x65, + 0x72, 0x5f, 0x69, 0x73, 0x5f, 0x77, 0x68, 0x69, + 0x74, 0x65, 0x5f, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x00, 0x00, 0x00, 0x10, 0x59, 0x4a, 0x53, 0x43, + 0x24, 0x6c, 0x65, 0x78, 0x65, 0x72, 0x5f, 0x68, + 0x65, 0x78, 0x5f, 0x74, 0x6f, 0x5f, 0x64, 0x65, + 0x63, 0x00, 0x00, 0x00, 0x10, 0xb2, 0x4a, 0x53, + 0x43, 0x24, 0x6c, 0x65, 0x78, 0x65, 0x72, 0x5f, + 0x72, 0x65, 0x61, 0x64, 0x5f, 0x62, 0x61, 0x63, + 0x6b, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x5f, 0x65, + 0x73, 0x63, 0x61, 0x70, 0x65, 0x00, 0x00, 0x00, + 0x11, 0x1e, 0x4a, 0x53, 0x43, 0x24, 0x6c, 0x65, + 0x78, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x61, 0x64, + 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x00, + 0x00, 0x00, 0x15, 0x9e, 0x4a, 0x53, 0x43, 0x24, + 0x6c, 0x65, 0x78, 0x65, 0x72, 0x5f, 0x72, 0x65, + 0x61, 0x64, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, + 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x74, 0x00, 0x00, 0x00, 0x16, 0xec, 0x4a, + 0x53, 0x43, 0x24, 0x6c, 0x65, 0x78, 0x65, 0x72, + 0x5f, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x72, 0x65, + 0x67, 0x65, 0x78, 0x70, 0x5f, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x00, 0x00, 0x00, 0x18, 0x22, + 0x4a, 0x53, 0x43, 0x24, 0x6c, 0x65, 0x78, 0x65, + 0x72, 0x5f, 0x65, 0x6f, 0x66, 0x5f, 0x69, 0x6e, + 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x74, 0x00, 0x00, 0x00, 0x1b, 0x19, 0x4a, 0x53, + 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, + 0x5f, 0x72, 0x65, 0x73, 0x65, 0x74, 0x00, 0x00, + 0x00, 0x1b, 0x9f, 0x4a, 0x53, 0x43, 0x24, 0x70, + 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x00, 0x00, 0x00, 0x1b, 0xb8, + 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x72, 0x5f, 0x73, 0x79, 0x6e, 0x74, 0x61, + 0x78, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x00, + 0x00, 0x00, 0x1c, 0xef, 0x4a, 0x53, 0x43, 0x24, + 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x00, + 0x00, 0x00, 0x1d, 0x1e, 0x4a, 0x53, 0x43, 0x24, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x00, + 0x00, 0x00, 0x1d, 0x39, 0x4a, 0x53, 0x43, 0x24, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, 0x67, + 0x65, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x00, 0x00, 0x00, 0x1d, 0x54, 0x4a, 0x53, 0x43, + 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, + 0x70, 0x65, 0x65, 0x6b, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x00, 0x00, 0x00, 0x1d, 0xf0, 0x4a, + 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x72, 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x65, + 0x6d, 0x69, 0x63, 0x6f, 0x6c, 0x6f, 0x6e, 0x5f, + 0x61, 0x73, 0x63, 0x69, 0x00, 0x00, 0x00, 0x1e, + 0x35, 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x72, 0x5f, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x69, 0x73, 0x5f, 0x6c, 0x65, 0x66, 0x74, + 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x5f, 0x73, 0x69, + 0x64, 0x65, 0x00, 0x00, 0x00, 0x1e, 0xe9, 0x4a, + 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x65, + 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x4a, 0x53, 0x43, 0x24, 0x70, + 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x5f, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x63, + 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x00, 0x00, 0x00, 0x20, 0x66, 0x4a, 0x53, 0x43, + 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x00, 0x00, 0x00, 0x22, 0xf0, + 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x5f, 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x6c, 0x69, + 0x73, 0x74, 0x00, 0x00, 0x00, 0x23, 0x93, 0x4a, + 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, + 0x73, 0x74, 0x6d, 0x74, 0x00, 0x00, 0x00, 0x23, + 0xf2, 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x5f, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, + 0x00, 0x00, 0x00, 0x29, 0xec, 0x4a, 0x53, 0x43, + 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, 0x74, 0x72, + 0x79, 0x00, 0x00, 0x00, 0x2c, 0x21, 0x4a, 0x53, + 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, + 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, 0x76, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, + 0x73, 0x74, 0x6d, 0x74, 0x00, 0x00, 0x00, 0x2e, + 0x90, 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x5f, 0x69, 0x66, 0x5f, 0x73, 0x74, 0x6d, + 0x74, 0x00, 0x00, 0x00, 0x2f, 0xf5, 0x4a, 0x53, + 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, + 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, 0x69, + 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x73, 0x74, 0x6d, 0x74, 0x00, 0x00, 0x00, + 0x31, 0x31, 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x00, + 0x00, 0x00, 0x36, 0xc8, 0x4a, 0x53, 0x43, 0x24, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, + 0x61, 0x72, 0x73, 0x65, 0x5f, 0x61, 0x73, 0x73, + 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, + 0x65, 0x78, 0x70, 0x72, 0x00, 0x00, 0x00, 0x37, + 0x5e, 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x65, 0x78, + 0x70, 0x72, 0x00, 0x00, 0x00, 0x38, 0xe9, 0x4a, + 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, + 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x5f, + 0x6f, 0x72, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x00, + 0x00, 0x00, 0x39, 0xd7, 0x4a, 0x53, 0x43, 0x24, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, + 0x61, 0x72, 0x73, 0x65, 0x5f, 0x6c, 0x6f, 0x67, + 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x61, 0x6e, 0x64, + 0x5f, 0x65, 0x78, 0x70, 0x72, 0x00, 0x00, 0x00, + 0x3a, 0x6f, 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x5f, 0x62, 0x69, 0x74, 0x77, 0x69, + 0x73, 0x65, 0x5f, 0x6f, 0x72, 0x5f, 0x65, 0x78, + 0x70, 0x72, 0x00, 0x00, 0x00, 0x3b, 0x07, 0x4a, + 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, + 0x62, 0x69, 0x74, 0x77, 0x69, 0x73, 0x65, 0x5f, + 0x78, 0x6f, 0x72, 0x5f, 0x65, 0x78, 0x70, 0x72, + 0x00, 0x00, 0x00, 0x3b, 0x9f, 0x4a, 0x53, 0x43, + 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, 0x62, 0x69, + 0x74, 0x77, 0x69, 0x73, 0x65, 0x5f, 0x61, 0x6e, + 0x64, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x00, 0x00, + 0x00, 0x3c, 0x37, 0x4a, 0x53, 0x43, 0x24, 0x70, + 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x5f, 0x65, 0x71, 0x75, 0x61, + 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x65, 0x78, 0x70, + 0x72, 0x00, 0x00, 0x00, 0x3c, 0xcf, 0x4a, 0x53, + 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, + 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, 0x72, + 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, + 0x6c, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x00, 0x00, + 0x00, 0x3d, 0xb2, 0x4a, 0x53, 0x43, 0x24, 0x70, + 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x5f, 0x73, 0x68, 0x69, 0x66, + 0x74, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x00, 0x00, + 0x00, 0x3e, 0x95, 0x4a, 0x53, 0x43, 0x24, 0x70, + 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x69, + 0x74, 0x69, 0x76, 0x65, 0x5f, 0x65, 0x78, 0x70, + 0x72, 0x00, 0x00, 0x00, 0x3f, 0x68, 0x4a, 0x53, + 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, + 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, 0x6d, + 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x65, 0x78, + 0x70, 0x72, 0x00, 0x00, 0x00, 0x40, 0x2b, 0x4a, + 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, + 0x75, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x65, 0x78, + 0x70, 0x72, 0x00, 0x00, 0x00, 0x40, 0xfe, 0x4a, + 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, + 0x70, 0x6f, 0x73, 0x74, 0x66, 0x69, 0x78, 0x5f, + 0x65, 0x78, 0x70, 0x72, 0x00, 0x00, 0x00, 0x42, + 0x00, 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x5f, 0x6c, 0x65, 0x66, 0x74, 0x5f, 0x68, + 0x61, 0x6e, 0x64, 0x5f, 0x73, 0x69, 0x64, 0x65, + 0x5f, 0x65, 0x78, 0x70, 0x72, 0x00, 0x00, 0x00, + 0x42, 0xc8, 0x4a, 0x53, 0x43, 0x24, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x00, 0x00, + 0x00, 0x44, 0x9b, 0x4a, 0x53, 0x43, 0x24, 0x70, + 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x5f, 0x70, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x5f, 0x65, 0x78, 0x70, 0x72, + 0x00, 0x00, 0x00, 0x46, 0x8c, 0x4a, 0x53, 0x43, + 0x24, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x00, + 0x00, 0x00, 0x4b, 0x39, 0x4a, 0x53, 0x43, 0x24, + 0x67, 0x72, 0x61, 0x6d, 0x5f, 0x72, 0x65, 0x73, + 0x65, 0x74, 0x00, 0x00, 0x00, 0x4c, 0x17, 0x4a, + 0x53, 0x43, 0x24, 0x61, 0x6c, 0x6c, 0x6f, 0x63, + 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x00, 0x00, + 0x00, 0x4c, 0x33, 0x4a, 0x53, 0x43, 0x24, 0x66, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x5f, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x00, 0x00, 0x00, 0x4c, 0x4e, + 0x4a, 0x53, 0x43, 0x24, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, + 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x73, 0x74, + 0x6d, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x00, + 0x00, 0x00, 0x4c, 0x64, 0x4a, 0x53, 0x43, 0x24, + 0x43, 0x6f, 0x6e, 0x74, 0x42, 0x72, 0x65, 0x61, + 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x00, 0x00, + 0x00, 0x4c, 0xfd, 0x4a, 0x53, 0x43, 0x24, 0x43, + 0x6f, 0x6e, 0x74, 0x42, 0x72, 0x65, 0x61, 0x6b, + 0x00, 0x00, 0x00, 0x4d, 0x41, 0x4a, 0x53, 0x43, + 0x24, 0x43, 0x6f, 0x6e, 0x74, 0x42, 0x72, 0x65, + 0x61, 0x6b, 0x24, 0x70, 0x75, 0x73, 0x68, 0x00, + 0x00, 0x00, 0x4d, 0x61, 0x4a, 0x53, 0x43, 0x24, + 0x43, 0x6f, 0x6e, 0x74, 0x42, 0x72, 0x65, 0x61, + 0x6b, 0x24, 0x70, 0x6f, 0x70, 0x00, 0x00, 0x00, + 0x4d, 0x8c, 0x4a, 0x53, 0x43, 0x24, 0x43, 0x6f, + 0x6e, 0x74, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x24, + 0x74, 0x72, 0x79, 0x5f, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x5f, 0x6e, 0x65, 0x73, 0x74, 0x69, + 0x6e, 0x67, 0x00, 0x00, 0x00, 0x4d, 0xc7, 0x4a, + 0x53, 0x43, 0x24, 0x43, 0x6f, 0x6e, 0x74, 0x42, + 0x72, 0x65, 0x61, 0x6b, 0x24, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, + 0x6e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x00, + 0x00, 0x00, 0x4e, 0x08, 0x4a, 0x53, 0x43, 0x24, + 0x43, 0x6f, 0x6e, 0x74, 0x42, 0x72, 0x65, 0x61, + 0x6b, 0x24, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, + 0x74, 0x72, 0x79, 0x5f, 0x6e, 0x65, 0x73, 0x74, + 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x4e, 0x77, + 0x4a, 0x53, 0x43, 0x24, 0x43, 0x6f, 0x6e, 0x74, + 0x42, 0x72, 0x65, 0x61, 0x6b, 0x24, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x73, 0x77, 0x69, 0x74, + 0x63, 0x68, 0x5f, 0x6e, 0x65, 0x73, 0x74, 0x69, + 0x6e, 0x67, 0x00, 0x00, 0x00, 0x4e, 0xe6, 0x4a, + 0x53, 0x43, 0x24, 0x43, 0x6f, 0x6e, 0x74, 0x42, + 0x72, 0x65, 0x61, 0x6b, 0x24, 0x67, 0x65, 0x74, + 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, + 0x65, 0x00, 0x00, 0x00, 0x4f, 0x60, 0x4a, 0x53, + 0x43, 0x24, 0x43, 0x6f, 0x6e, 0x74, 0x42, 0x72, + 0x65, 0x61, 0x6b, 0x24, 0x67, 0x65, 0x74, 0x5f, + 0x62, 0x72, 0x65, 0x61, 0x6b, 0x00, 0x00, 0x00, + 0x4f, 0xc2, 0x4a, 0x53, 0x43, 0x24, 0x43, 0x6f, + 0x6e, 0x74, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x24, + 0x69, 0x73, 0x5f, 0x75, 0x6e, 0x69, 0x71, 0x75, + 0x65, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x00, + 0x00, 0x00, 0x50, 0x24, 0x4a, 0x53, 0x43, 0x24, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x50, + 0x62, 0x4a, 0x53, 0x43, 0x24, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x65, + 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x00, 0x00, + 0x50, 0xb4, 0x4a, 0x53, 0x43, 0x24, 0x7a, 0x65, + 0x72, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x54, 0xf6, + 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, + 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x00, 0x00, + 0x00, 0x54, 0xfd, 0x4a, 0x53, 0x43, 0x24, 0x73, + 0x74, 0x6d, 0x74, 0x5f, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x00, 0x00, + 0x55, 0x3a, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, + 0x6d, 0x74, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x00, 0x00, 0x00, + 0x55, 0x97, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, + 0x6d, 0x74, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x63, 0x6c, + 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x00, 0x00, 0x55, 0xb7, 0x4a, 0x53, 0x43, 0x24, + 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x65, + 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x00, 0x00, + 0x56, 0x06, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, + 0x6d, 0x74, 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, + 0x00, 0x00, 0x00, 0x56, 0x6d, 0x4a, 0x53, 0x43, + 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x65, 0x6d, + 0x70, 0x74, 0x79, 0x5f, 0x61, 0x73, 0x6d, 0x00, + 0x00, 0x00, 0x56, 0xa1, 0x4a, 0x53, 0x43, 0x24, + 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x63, 0x6f, 0x6e, + 0x74, 0x69, 0x6e, 0x75, 0x65, 0x00, 0x00, 0x00, + 0x56, 0xa8, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, + 0x6d, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x69, + 0x6e, 0x75, 0x65, 0x5f, 0x61, 0x73, 0x6d, 0x00, + 0x00, 0x00, 0x56, 0xe5, 0x4a, 0x53, 0x43, 0x24, + 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x62, 0x72, 0x65, + 0x61, 0x6b, 0x00, 0x00, 0x00, 0x58, 0x92, 0x4a, + 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, + 0x62, 0x72, 0x65, 0x61, 0x6b, 0x5f, 0x61, 0x73, + 0x6d, 0x00, 0x00, 0x00, 0x58, 0xcf, 0x4a, 0x53, + 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x00, 0x00, 0x00, + 0x5a, 0x8d, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, + 0x6d, 0x74, 0x5f, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x00, 0x00, + 0x5a, 0xca, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, + 0x6d, 0x74, 0x5f, 0x73, 0x77, 0x69, 0x74, 0x63, + 0x68, 0x00, 0x00, 0x00, 0x5b, 0x63, 0x4a, 0x53, + 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x73, + 0x77, 0x69, 0x74, 0x63, 0x68, 0x5f, 0x61, 0x73, + 0x6d, 0x00, 0x00, 0x00, 0x5b, 0xb2, 0x4a, 0x53, + 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x73, + 0x77, 0x69, 0x74, 0x63, 0x68, 0x5f, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x73, 0x00, 0x00, 0x00, 0x5e, 0x22, 0x4a, + 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, + 0x77, 0x69, 0x74, 0x68, 0x00, 0x00, 0x00, 0x5f, + 0x26, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, + 0x74, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x61, + 0x73, 0x6d, 0x00, 0x00, 0x00, 0x5f, 0x6c, 0x4a, + 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, + 0x77, 0x69, 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x73, 0x00, 0x00, 0x00, 0x60, 0x04, 0x4a, 0x53, + 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x74, + 0x72, 0x79, 0x00, 0x00, 0x00, 0x60, 0x4d, 0x4a, + 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, + 0x74, 0x72, 0x79, 0x5f, 0x61, 0x73, 0x6d, 0x00, + 0x00, 0x00, 0x60, 0xae, 0x4a, 0x53, 0x43, 0x24, + 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x74, 0x72, 0x79, + 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x00, 0x00, 0x00, + 0x67, 0xaf, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, + 0x6d, 0x74, 0x5f, 0x74, 0x68, 0x72, 0x6f, 0x77, + 0x00, 0x00, 0x00, 0x69, 0x7f, 0x4a, 0x53, 0x43, + 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x74, 0x68, + 0x72, 0x6f, 0x77, 0x5f, 0x61, 0x73, 0x6d, 0x00, + 0x00, 0x00, 0x69, 0xbc, 0x4a, 0x53, 0x43, 0x24, + 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x6d, + 0x74, 0x00, 0x00, 0x00, 0x69, 0xeb, 0x4a, 0x53, + 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x65, 0x64, 0x5f, 0x73, + 0x74, 0x6d, 0x74, 0x5f, 0x61, 0x73, 0x6d, 0x00, + 0x00, 0x00, 0x6a, 0x31, 0x4a, 0x53, 0x43, 0x24, + 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x6d, + 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x00, 0x00, + 0x00, 0x6a, 0xf5, 0x4a, 0x53, 0x43, 0x24, 0x73, + 0x74, 0x6d, 0x74, 0x5f, 0x65, 0x78, 0x70, 0x72, + 0x00, 0x00, 0x00, 0x6b, 0x0c, 0x4a, 0x53, 0x43, + 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x65, 0x78, + 0x70, 0x72, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x00, + 0x00, 0x6b, 0x4e, 0x4a, 0x53, 0x43, 0x24, 0x73, + 0x74, 0x6d, 0x74, 0x5f, 0x69, 0x66, 0x00, 0x00, + 0x00, 0x6b, 0x7d, 0x4a, 0x53, 0x43, 0x24, 0x73, + 0x74, 0x6d, 0x74, 0x5f, 0x69, 0x66, 0x5f, 0x61, + 0x73, 0x6d, 0x00, 0x00, 0x00, 0x6b, 0xcc, 0x4a, + 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, + 0x69, 0x66, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x00, + 0x00, 0x00, 0x6c, 0xd5, 0x4a, 0x53, 0x43, 0x24, + 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x64, 0x6f, 0x5f, + 0x77, 0x68, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x00, + 0x6d, 0xae, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, + 0x6d, 0x74, 0x5f, 0x64, 0x6f, 0x5f, 0x77, 0x68, + 0x69, 0x6c, 0x65, 0x5f, 0x61, 0x73, 0x6d, 0x00, + 0x00, 0x00, 0x6d, 0xf4, 0x4a, 0x53, 0x43, 0x24, + 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x64, 0x6f, 0x5f, + 0x77, 0x68, 0x69, 0x6c, 0x65, 0x5f, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x73, 0x00, 0x00, 0x00, 0x6e, 0xfd, 0x4a, + 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, + 0x77, 0x68, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x00, + 0x6f, 0x46, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, + 0x6d, 0x74, 0x5f, 0x77, 0x68, 0x69, 0x6c, 0x65, + 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x00, 0x00, 0x6f, + 0x8c, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, + 0x74, 0x5f, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x73, 0x00, 0x00, 0x00, 0x70, + 0x99, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, + 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x00, 0x00, 0x00, + 0x70, 0xe2, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, + 0x6d, 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x61, + 0x73, 0x6d, 0x00, 0x00, 0x00, 0x71, 0x43, 0x4a, + 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, + 0x66, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, + 0x00, 0x00, 0x00, 0x74, 0x6e, 0x4a, 0x53, 0x43, + 0x24, 0x73, 0x74, 0x6d, 0x74, 0x5f, 0x66, 0x6f, + 0x72, 0x5f, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x74, + 0xf9, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, + 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x69, 0x6e, + 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x00, 0x00, 0x75, + 0x51, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, + 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x69, 0x6e, + 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x00, 0x00, 0x00, + 0x78, 0x93, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, + 0x6d, 0x74, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, + 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x79, 0x13, + 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, 0x6d, 0x74, + 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, + 0x65, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x00, 0x00, + 0x79, 0x58, 0x4a, 0x53, 0x43, 0x24, 0x73, 0x74, + 0x6d, 0x74, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, + 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, + 0x00, 0x00, 0x00, 0x7a, 0xb5, 0x4a, 0x53, 0x43, + 0x24, 0x76, 0x61, 0x72, 0x5f, 0x64, 0x65, 0x63, + 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x00, 0x00, 0x00, 0x7a, 0xdf, 0x4a, 0x53, 0x43, + 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x74, 0x68, + 0x69, 0x73, 0x00, 0x00, 0x00, 0x7a, 0xf8, 0x4a, + 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, + 0x74, 0x68, 0x69, 0x73, 0x5f, 0x61, 0x73, 0x6d, + 0x00, 0x00, 0x00, 0x7b, 0x20, 0x4a, 0x53, 0x43, + 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x69, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, + 0x00, 0x00, 0x00, 0x7b, 0x41, 0x4a, 0x53, 0x43, + 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x69, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, + 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x00, 0x00, 0x7b, + 0x72, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, + 0x72, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x00, + 0x00, 0x00, 0x7b, 0x84, 0x4a, 0x53, 0x43, 0x24, + 0x65, 0x78, 0x70, 0x72, 0x5f, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x00, + 0x00, 0x7b, 0xc1, 0x4a, 0x53, 0x43, 0x24, 0x65, + 0x78, 0x70, 0x72, 0x5f, 0x69, 0x6e, 0x74, 0x65, + 0x67, 0x65, 0x72, 0x00, 0x00, 0x00, 0x7b, 0xe8, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, + 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x00, 0x00, 0x7c, + 0x25, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, + 0x72, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x00, 0x00, 0x00, 0x7c, 0xfc, 0x4a, 0x53, 0x43, + 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x73, 0x6d, + 0x00, 0x00, 0x00, 0x7d, 0x39, 0x4a, 0x53, 0x43, + 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x72, 0x65, + 0x67, 0x65, 0x78, 0x70, 0x00, 0x00, 0x00, 0x7d, + 0x60, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, + 0x72, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x70, + 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x00, 0x00, 0x7d, + 0x9d, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, + 0x72, 0x5f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5f, + 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, + 0x7a, 0x65, 0x72, 0x00, 0x00, 0x00, 0x7d, 0xc4, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5f, 0x69, + 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, + 0x65, 0x72, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x00, + 0x00, 0x7e, 0x01, 0x4a, 0x53, 0x43, 0x24, 0x65, + 0x78, 0x70, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x72, 0x00, 0x00, + 0x00, 0x7f, 0x11, 0x4a, 0x53, 0x43, 0x24, 0x65, + 0x78, 0x70, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x72, 0x5f, 0x61, + 0x73, 0x6d, 0x00, 0x00, 0x00, 0x7f, 0x4e, 0x4a, + 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, + 0x6e, 0x75, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x81, + 0xc9, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, + 0x72, 0x5f, 0x6e, 0x75, 0x6c, 0x6c, 0x5f, 0x61, + 0x73, 0x6d, 0x00, 0x00, 0x00, 0x81, 0xfd, 0x4a, + 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, + 0x74, 0x72, 0x75, 0x65, 0x00, 0x00, 0x00, 0x82, + 0x1d, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, + 0x72, 0x5f, 0x74, 0x72, 0x75, 0x65, 0x5f, 0x61, + 0x73, 0x6d, 0x00, 0x00, 0x00, 0x82, 0x51, 0x4a, + 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, + 0x66, 0x61, 0x6c, 0x73, 0x65, 0x00, 0x00, 0x00, + 0x82, 0x71, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, + 0x70, 0x72, 0x5f, 0x66, 0x61, 0x6c, 0x73, 0x65, + 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x00, 0x00, 0x82, + 0xa5, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, + 0x72, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x00, 0x00, 0x00, 0x82, 0xc5, 0x4a, 0x53, 0x43, + 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x6d, 0x75, + 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x73, 0x6d, + 0x00, 0x00, 0x00, 0x83, 0x08, 0x4a, 0x53, 0x43, + 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x61, 0x64, + 0x64, 0x69, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, + 0x00, 0x83, 0xa6, 0x4a, 0x53, 0x43, 0x24, 0x65, + 0x78, 0x70, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x69, + 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x73, 0x6d, + 0x00, 0x00, 0x00, 0x83, 0xf5, 0x4a, 0x53, 0x43, + 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x61, 0x64, + 0x64, 0x69, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x5f, + 0x66, 0x6f, 0x6c, 0x64, 0x69, 0x6e, 0x67, 0x00, + 0x00, 0x00, 0x84, 0x63, 0x4a, 0x53, 0x43, 0x24, + 0x65, 0x78, 0x70, 0x72, 0x5f, 0x73, 0x68, 0x69, + 0x66, 0x74, 0x00, 0x00, 0x00, 0x86, 0x30, 0x4a, + 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, + 0x73, 0x68, 0x69, 0x66, 0x74, 0x5f, 0x61, 0x73, + 0x6d, 0x00, 0x00, 0x00, 0x86, 0x73, 0x4a, 0x53, + 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x72, + 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, + 0x6c, 0x00, 0x00, 0x00, 0x87, 0x11, 0x4a, 0x53, + 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x72, + 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, + 0x6c, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x00, 0x00, + 0x87, 0x60, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, + 0x70, 0x72, 0x5f, 0x65, 0x71, 0x75, 0x61, 0x6c, + 0x69, 0x74, 0x79, 0x00, 0x00, 0x00, 0x88, 0x2e, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, + 0x79, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x00, 0x00, + 0x88, 0x7d, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, + 0x70, 0x72, 0x5f, 0x62, 0x69, 0x74, 0x77, 0x69, + 0x73, 0x65, 0x5f, 0x61, 0x6e, 0x64, 0x00, 0x00, + 0x00, 0x89, 0x60, 0x4a, 0x53, 0x43, 0x24, 0x65, + 0x78, 0x70, 0x72, 0x5f, 0x62, 0x69, 0x74, 0x77, + 0x69, 0x73, 0x65, 0x5f, 0x61, 0x6e, 0x64, 0x5f, + 0x61, 0x73, 0x6d, 0x00, 0x00, 0x00, 0x89, 0x9a, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x62, 0x69, 0x74, 0x77, 0x69, 0x73, 0x65, + 0x5f, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x89, 0xd8, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x62, 0x69, 0x74, 0x77, 0x69, 0x73, 0x65, + 0x5f, 0x6f, 0x72, 0x5f, 0x61, 0x73, 0x6d, 0x00, + 0x00, 0x00, 0x8a, 0x12, 0x4a, 0x53, 0x43, 0x24, + 0x65, 0x78, 0x70, 0x72, 0x5f, 0x62, 0x69, 0x74, + 0x77, 0x69, 0x73, 0x65, 0x5f, 0x78, 0x6f, 0x72, + 0x00, 0x00, 0x00, 0x8a, 0x50, 0x4a, 0x53, 0x43, + 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x62, 0x69, + 0x74, 0x77, 0x69, 0x73, 0x65, 0x5f, 0x78, 0x6f, + 0x72, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x00, 0x00, + 0x8a, 0x8a, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, + 0x70, 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x63, + 0x61, 0x6c, 0x5f, 0x61, 0x6e, 0x64, 0x00, 0x00, + 0x00, 0x8a, 0xc8, 0x4a, 0x53, 0x43, 0x24, 0x65, + 0x78, 0x70, 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x69, + 0x63, 0x61, 0x6c, 0x5f, 0x61, 0x6e, 0x64, 0x5f, + 0x61, 0x73, 0x6d, 0x00, 0x00, 0x00, 0x8b, 0x55, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, + 0x5f, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x8c, 0x3a, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, + 0x5f, 0x6f, 0x72, 0x5f, 0x61, 0x73, 0x6d, 0x00, + 0x00, 0x00, 0x8c, 0xc7, 0x4a, 0x53, 0x43, 0x24, + 0x65, 0x78, 0x70, 0x72, 0x5f, 0x6e, 0x65, 0x77, + 0x00, 0x00, 0x00, 0x8d, 0xac, 0x4a, 0x53, 0x43, + 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x6e, 0x65, + 0x77, 0x5f, 0x61, 0x73, 0x6d, 0x00, 0x00, 0x00, + 0x8d, 0xe6, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, + 0x70, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x00, 0x00, 0x00, 0x8f, 0xb8, 0x4a, + 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, + 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x70, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, + 0x61, 0x73, 0x6d, 0x00, 0x00, 0x00, 0x8f, 0xf2, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, + 0x61, 0x72, 0x72, 0x61, 0x79, 0x00, 0x00, 0x00, + 0x90, 0x04, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, + 0x70, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x5f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5f, + 0x61, 0x73, 0x6d, 0x00, 0x00, 0x00, 0x90, 0x3e, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x00, 0x00, 0x00, + 0x90, 0x50, 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, + 0x70, 0x72, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, + 0x61, 0x73, 0x6d, 0x00, 0x00, 0x00, 0x90, 0x8a, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, + 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x93, 0x64, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, + 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x73, 0x6d, 0x00, + 0x00, 0x00, 0x93, 0xa7, 0x4a, 0x53, 0x43, 0x24, + 0x61, 0x73, 0x6d, 0x5f, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x6c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, + 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x61, 0x73, 0x6d, + 0x00, 0x00, 0x00, 0x96, 0x5e, 0x4a, 0x53, 0x43, + 0x24, 0x61, 0x73, 0x6d, 0x5f, 0x65, 0x78, 0x70, + 0x72, 0x5f, 0x6c, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x61, + 0x73, 0x6d, 0x00, 0x00, 0x00, 0x98, 0xd8, 0x4a, + 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, + 0x6c, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x9a, 0x57, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x63, + 0x6f, 0x6c, 0x6f, 0x6e, 0x5f, 0x61, 0x73, 0x6d, + 0x00, 0x00, 0x00, 0x9a, 0x9a, 0x4a, 0x53, 0x43, + 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x75, 0x6e, + 0x61, 0x72, 0x79, 0x00, 0x00, 0x00, 0x9b, 0x90, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x75, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x61, + 0x73, 0x6d, 0x00, 0x00, 0x00, 0x9b, 0xca, 0x4a, + 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, + 0x70, 0x6f, 0x73, 0x74, 0x66, 0x69, 0x78, 0x00, + 0x00, 0x00, 0x9f, 0xdc, 0x4a, 0x53, 0x43, 0x24, + 0x65, 0x78, 0x70, 0x72, 0x5f, 0x70, 0x6f, 0x73, + 0x74, 0x66, 0x69, 0x78, 0x5f, 0x61, 0x73, 0x6d, + 0x00, 0x00, 0x00, 0xa0, 0x16, 0x4a, 0x53, 0x43, + 0x24, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x63, 0x6f, + 0x6d, 0x6d, 0x61, 0x00, 0x00, 0x00, 0xa0, 0xb8, + 0x4a, 0x53, 0x43, 0x24, 0x65, 0x78, 0x70, 0x72, + 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x5f, 0x61, + 0x73, 0x6d, 0x00, 0x00, 0x00, 0xa0, 0xf2, 0x4a, + 0x53, 0x43, 0x24, 0x4e, 0x61, 0x6d, 0x65, 0x53, + 0x70, 0x61, 0x63, 0x65, 0x00, 0x00, 0x00, 0xa1, + 0x30, 0x4a, 0x53, 0x43, 0x24, 0x4e, 0x61, 0x6d, + 0x65, 0x53, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x70, + 0x75, 0x73, 0x68, 0x5f, 0x66, 0x72, 0x61, 0x6d, + 0x65, 0x00, 0x00, 0x00, 0xa1, 0x84, 0x4a, 0x53, + 0x43, 0x24, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x70, + 0x61, 0x63, 0x65, 0x5f, 0x70, 0x6f, 0x70, 0x5f, + 0x66, 0x72, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, + 0xa1, 0xc8, 0x4a, 0x53, 0x43, 0x24, 0x4e, 0x61, + 0x6d, 0x65, 0x53, 0x70, 0x61, 0x63, 0x65, 0x5f, + 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x5f, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x00, 0x00, 0x00, 0xa2, 0xc7, + 0x4a, 0x53, 0x43, 0x24, 0x4e, 0x61, 0x6d, 0x65, + 0x53, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x65, 0x5f, 0x73, 0x79, 0x6d, + 0x62, 0x6f, 0x6c, 0x00, 0x00, 0x00, 0xa2, 0xe8, + 0x4a, 0x53, 0x43, 0x24, 0x4e, 0x61, 0x6d, 0x65, + 0x53, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6c, 0x6f, + 0x6f, 0x6b, 0x75, 0x70, 0x5f, 0x73, 0x79, 0x6d, + 0x62, 0x6f, 0x6c, 0x00, 0x00, 0x00, 0xa4, 0x28, + 0x4a, 0x53, 0x43, 0x24, 0x4e, 0x61, 0x6d, 0x65, + 0x53, 0x70, 0x61, 0x63, 0x65, 0x46, 0x72, 0x61, + 0x6d, 0x65, 0x00, 0x00, 0x00, 0xa4, 0xa1, 0x4a, + 0x53, 0x43, 0x24, 0x53, 0x79, 0x6d, 0x62, 0x6f, + 0x6c, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0xa4, 0xc0, + 0x4a, 0x53, 0x43, 0x24, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x46, 0x69, 0x6c, 0x65, 0x00, 0x00, + 0x00, 0xa4, 0xfb, 0x4a, 0x53, 0x43, 0x24, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x46, 0x69, 0x6c, + 0x65, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x00, 0x00, + 0x00, 0xa5, 0x72, 0x4a, 0x53, 0x43, 0x24, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x46, 0x69, 0x6c, + 0x65, 0x5f, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x00, + 0x00, 0x00, 0xa5, 0xb3, 0x4a, 0x53, 0x43, 0x24, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x46, 0x69, + 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x77, 0x69, 0x6e, + 0x64, 0x00, 0x00, 0x00, 0xa5, 0xc8, 0x4a, 0x53, + 0x43, 0x24, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x46, 0x69, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x61, + 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x00, 0x00, + 0x00, 0xa5, 0xde, 0x4a, 0x53, 0x43, 0x24, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x46, 0x69, 0x6c, + 0x65, 0x5f, 0x75, 0x6e, 0x67, 0x65, 0x74, 0x5f, + 0x62, 0x79, 0x74, 0x65, 0x00, 0x00, 0x00, 0xa5, + 0xf3, 0x4a, 0x53, 0x43, 0x24, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x46, 0x69, 0x6c, 0x65, 0x5f, + 0x72, 0x65, 0x61, 0x64, 0x6c, 0x6e, 0x00, 0x00, + 0x00, 0xa6, 0x0b, 0x4a, 0x53, 0x43, 0x24, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0xa6, 0x20, + 0x4a, 0x53, 0x43, 0x24, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x00, 0x00, 0x00, + 0xa6, 0xa1, 0x4a, 0x53, 0x43, 0x24, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x5f, 0x63, 0x6c, 0x6f, 0x73, 0x65, + 0x00, 0x00, 0x00, 0xa6, 0xa8, 0x4a, 0x53, 0x43, + 0x24, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x65, + 0x77, 0x69, 0x6e, 0x64, 0x00, 0x00, 0x00, 0xa6, + 0xaf, 0x4a, 0x53, 0x43, 0x24, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x62, + 0x79, 0x74, 0x65, 0x00, 0x00, 0x00, 0xa6, 0xd3, + 0x4a, 0x53, 0x43, 0x24, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x5f, 0x75, 0x6e, 0x67, 0x65, 0x74, 0x5f, 0x62, + 0x79, 0x74, 0x65, 0x00, 0x00, 0x00, 0xa7, 0x3d, + 0x4a, 0x53, 0x43, 0x24, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x5f, 0x72, 0x65, 0x61, 0x64, 0x6c, 0x6e, 0x00, + 0x00, 0x00, 0xa7, 0x4d, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x62, 0x79, 0x74, 0x65, + 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x6e, 0x74, + 0x38, 0x00, 0x00, 0x00, 0xa7, 0xb6, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x62, 0x79, + 0x74, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x69, + 0x6e, 0x74, 0x31, 0x36, 0x00, 0x00, 0x00, 0xa7, + 0xd5, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x62, 0x79, 0x74, 0x65, 0x63, 0x6f, 0x64, + 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x00, + 0x00, 0x00, 0xa7, 0xf4, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x62, 0x79, 0x74, 0x65, + 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x73, 0x79, 0x6d, + 0x62, 0x6f, 0x6c, 0x00, 0x00, 0x00, 0xa8, 0x13, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x62, 0x79, 0x74, 0x65, 0x63, 0x6f, 0x64, 0x65, + 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x6a, + 0x75, 0x6d, 0x70, 0x00, 0x00, 0x00, 0xa8, 0x6a, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x00, 0x00, + 0x00, 0xa8, 0xa1, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x73, 0x79, 0x6d, 0x62, 0x6f, + 0x6c, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x00, 0x00, 0xa8, 0xe6, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x00, 0x00, 0x00, 0xa9, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x00, 0x00, 0xa9, 0x75, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x5f, 0x66, 0x6f, 0x72, 0x6d, + 0x61, 0x74, 0x00, 0x00, 0x00, 0xa9, 0x96, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x68, + 0x61, 0x6c, 0x74, 0x00, 0x00, 0x00, 0xa9, 0xb1, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x68, 0x61, 0x6c, 0x74, 0x5f, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x00, 0x00, 0x00, 0xa9, 0xed, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x64, + 0x6f, 0x6e, 0x65, 0x00, 0x00, 0x00, 0xaa, 0x03, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x64, 0x6f, 0x6e, 0x65, 0x5f, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x00, 0x00, 0x00, 0xaa, 0x3f, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6e, + 0x6f, 0x70, 0x00, 0x00, 0x00, 0xaa, 0x55, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6e, + 0x6f, 0x70, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x00, 0x00, 0x00, 0xaa, 0x91, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x64, 0x75, 0x70, + 0x00, 0x00, 0x00, 0xaa, 0xa7, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x64, 0x75, 0x70, + 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, + 0x00, 0xaa, 0xeb, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x70, 0x6f, 0x70, 0x00, 0x00, + 0x00, 0xab, 0x01, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x70, 0x6f, 0x70, 0x5f, 0x70, + 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, 0xab, + 0x46, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x70, 0x6f, 0x70, 0x5f, 0x6e, 0x00, 0x00, + 0x00, 0xab, 0x5c, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x70, 0x6f, 0x70, 0x5f, 0x6e, + 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, + 0x00, 0xab, 0xb7, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x61, 0x70, 0x6f, 0x70, 0x00, + 0x00, 0x00, 0xab, 0xe3, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x61, 0x70, 0x6f, 0x70, + 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, + 0x00, 0xac, 0x3e, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x73, 0x77, 0x61, 0x70, 0x00, + 0x00, 0x00, 0xac, 0x6a, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x73, 0x77, 0x61, 0x70, + 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, + 0x00, 0xac, 0xa6, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x72, 0x6f, 0x6c, 0x6c, 0x00, + 0x00, 0x00, 0xac, 0xbc, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x72, 0x6f, 0x6c, 0x6c, + 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, + 0x00, 0xad, 0x0d, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x00, 0x00, 0x00, 0xad, 0x39, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x00, 0x00, 0x00, 0xad, 0x96, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x63, + 0x6f, 0x64, 0x65, 0x00, 0x00, 0x00, 0xaf, 0xe7, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x6e, 0x75, + 0x6c, 0x6c, 0x00, 0x00, 0x00, 0xb1, 0xd6, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x6e, 0x75, 0x6c, + 0x6c, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x00, 0x00, 0xb2, 0x1a, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x5f, 0x74, 0x72, 0x75, 0x65, 0x00, 0x00, + 0x00, 0xb2, 0x30, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x5f, 0x74, 0x72, 0x75, 0x65, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, 0xb2, 0x74, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x66, 0x61, + 0x6c, 0x73, 0x65, 0x00, 0x00, 0x00, 0xb2, 0x8a, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x66, 0x61, + 0x6c, 0x73, 0x65, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x00, 0x00, 0xb2, 0xce, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x5f, 0x75, 0x6e, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x65, 0x64, 0x00, 0x00, 0x00, + 0xb2, 0xe4, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, + 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, + 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x00, 0x00, 0xb3, 0x28, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x5f, 0x69, 0x30, 0x00, 0x00, 0x00, 0xb3, + 0x3e, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x69, + 0x30, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x00, 0x00, 0xb3, 0x82, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x5f, 0x69, 0x31, 0x00, 0x00, 0x00, 0xb3, + 0x98, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x69, + 0x31, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x00, 0x00, 0xb3, 0xdc, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x5f, 0x69, 0x32, 0x00, 0x00, 0x00, 0xb3, + 0xf2, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x69, + 0x32, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x00, 0x00, 0xb4, 0x36, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x5f, 0x69, 0x33, 0x00, 0x00, 0x00, 0xb4, + 0x4c, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x69, + 0x33, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x00, 0x00, 0xb4, 0x90, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x5f, 0x69, 0x00, 0x00, 0x00, 0xb4, 0xa6, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x69, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, + 0xb5, 0x03, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x67, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x00, 0x00, 0x00, + 0xb5, 0x2f, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x67, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, 0xb5, 0x8c, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x67, 0x6c, + 0x6f, 0x62, 0x61, 0x6c, 0x00, 0x00, 0x00, 0xb5, + 0xb0, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x67, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, 0xb6, 0x0e, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x61, 0x72, 0x67, + 0x00, 0x00, 0x00, 0xb6, 0x32, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6c, 0x6f, 0x61, + 0x64, 0x5f, 0x61, 0x72, 0x67, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, 0xb6, 0x8b, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x61, 0x72, + 0x67, 0x00, 0x00, 0x00, 0xb6, 0xb7, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x5f, 0x61, 0x72, 0x67, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, + 0xb7, 0x11, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x00, 0xb7, + 0x3d, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x00, 0x00, 0xb7, 0x96, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x5f, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x00, 0x00, 0x00, 0xb7, 0xc2, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x5f, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x00, 0x00, 0xb8, 0x1c, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x6c, 0x6f, 0x61, 0x64, + 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x79, 0x00, 0x00, 0x00, 0xb8, 0x48, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6c, 0x6f, + 0x61, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x00, 0x00, 0xb8, 0x9d, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x79, 0x00, 0x00, 0x00, 0xb8, + 0xc1, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x70, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, + 0xb9, 0x1f, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x61, + 0x72, 0x72, 0x61, 0x79, 0x00, 0x00, 0x00, 0xb9, + 0x43, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x61, 0x72, + 0x72, 0x61, 0x79, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x00, 0x00, 0xb9, 0x88, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x5f, 0x61, 0x72, 0x72, 0x61, + 0x79, 0x00, 0x00, 0x00, 0xb9, 0x9e, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x5f, 0x61, 0x72, 0x72, 0x61, + 0x79, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x00, 0x00, 0xb9, 0xe3, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x6e, 0x74, 0x68, 0x00, + 0x00, 0x00, 0xb9, 0xf9, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x6e, 0x74, 0x68, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, + 0xba, 0x35, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x63, 0x6d, 0x70, 0x5f, 0x65, 0x71, + 0x00, 0x00, 0x00, 0xba, 0x4b, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6d, 0x70, + 0x5f, 0x65, 0x71, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x00, 0x00, 0xba, 0x90, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6d, + 0x70, 0x5f, 0x6e, 0x65, 0x00, 0x00, 0x00, 0xba, + 0xa6, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x63, 0x6d, 0x70, 0x5f, 0x6e, 0x65, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, + 0xba, 0xeb, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x63, 0x6d, 0x70, 0x5f, 0x6c, 0x74, + 0x00, 0x00, 0x00, 0xbb, 0x01, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6d, 0x70, + 0x5f, 0x6c, 0x74, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x00, 0x00, 0xbb, 0x46, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6d, + 0x70, 0x5f, 0x67, 0x74, 0x00, 0x00, 0x00, 0xbb, + 0x5c, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x63, 0x6d, 0x70, 0x5f, 0x67, 0x74, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, + 0xbb, 0xa1, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x63, 0x6d, 0x70, 0x5f, 0x6c, 0x65, + 0x00, 0x00, 0x00, 0xbb, 0xb7, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6d, 0x70, + 0x5f, 0x6c, 0x65, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x00, 0x00, 0xbb, 0xfc, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6d, + 0x70, 0x5f, 0x67, 0x65, 0x00, 0x00, 0x00, 0xbc, + 0x12, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x63, 0x6d, 0x70, 0x5f, 0x67, 0x65, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, + 0xbc, 0x57, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x63, 0x6d, 0x70, 0x5f, 0x73, 0x65, + 0x71, 0x00, 0x00, 0x00, 0xbc, 0x6d, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6d, + 0x70, 0x5f, 0x73, 0x65, 0x71, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, 0xbc, 0xb2, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x63, 0x6d, 0x70, 0x5f, 0x73, 0x6e, 0x65, 0x00, + 0x00, 0x00, 0xbc, 0xc8, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x6d, 0x70, 0x5f, + 0x73, 0x6e, 0x65, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x00, 0x00, 0xbd, 0x0d, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x73, 0x75, + 0x62, 0x00, 0x00, 0x00, 0xbd, 0x23, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x73, 0x75, + 0x62, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x00, 0x00, 0xbd, 0x68, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x61, 0x64, 0x64, 0x00, + 0x00, 0x00, 0xbd, 0x7e, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x61, 0x64, 0x64, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, + 0xbd, 0xc3, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x6d, 0x75, 0x6c, 0x00, 0x00, 0x00, + 0xbd, 0xd9, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x6d, 0x75, 0x6c, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, 0xbe, 0x1e, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x64, 0x69, 0x76, 0x00, 0x00, 0x00, 0xbe, 0x34, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x64, 0x69, 0x76, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x00, 0x00, 0xbe, 0x79, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6d, 0x6f, + 0x64, 0x00, 0x00, 0x00, 0xbe, 0x8f, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6d, 0x6f, + 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x00, 0x00, 0xbe, 0xd4, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x6e, 0x65, 0x67, 0x00, + 0x00, 0x00, 0xbe, 0xea, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x6e, 0x65, 0x67, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, + 0xbf, 0x26, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x61, 0x6e, 0x64, 0x00, 0x00, 0x00, + 0xbf, 0x3c, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, 0xbf, 0x81, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x6e, 0x6f, 0x74, 0x00, 0x00, 0x00, 0xbf, 0x97, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x6e, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x00, 0x00, 0xbf, 0xd3, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6f, 0x72, + 0x00, 0x00, 0x00, 0xbf, 0xe9, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6f, 0x72, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, + 0xc0, 0x2e, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x78, 0x6f, 0x72, 0x00, 0x00, 0x00, + 0xc0, 0x44, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x78, 0x6f, 0x72, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, 0xc0, 0x89, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x73, 0x68, 0x69, 0x66, 0x74, 0x5f, 0x6c, 0x65, + 0x66, 0x74, 0x00, 0x00, 0x00, 0xc0, 0x9f, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x73, + 0x68, 0x69, 0x66, 0x74, 0x5f, 0x6c, 0x65, 0x66, + 0x74, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x00, 0x00, 0xc0, 0xe4, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x73, 0x68, 0x69, 0x66, + 0x74, 0x5f, 0x72, 0x69, 0x67, 0x68, 0x74, 0x00, + 0x00, 0x00, 0xc0, 0xfa, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x73, 0x68, 0x69, 0x66, + 0x74, 0x5f, 0x72, 0x69, 0x67, 0x68, 0x74, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, + 0xc1, 0x3f, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x73, 0x68, 0x69, 0x66, 0x74, 0x5f, + 0x72, 0x72, 0x69, 0x67, 0x68, 0x74, 0x00, 0x00, + 0x00, 0xc1, 0x55, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x73, 0x68, 0x69, 0x66, 0x74, + 0x5f, 0x72, 0x72, 0x69, 0x67, 0x68, 0x74, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, + 0xc1, 0x9a, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x69, 0x66, 0x66, 0x61, 0x6c, 0x73, + 0x65, 0x00, 0x00, 0x00, 0xc1, 0xb0, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x69, 0x66, + 0x66, 0x61, 0x6c, 0x73, 0x65, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, 0xc2, 0x0e, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x69, 0x66, 0x74, 0x72, 0x75, 0x65, 0x00, 0x00, + 0x00, 0xc2, 0x3a, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x69, 0x66, 0x74, 0x72, 0x75, + 0x65, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x00, 0x00, 0xc2, 0x98, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x61, 0x6c, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x00, + 0x00, 0x00, 0xc2, 0xc4, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x63, 0x61, 0x6c, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, + 0xc3, 0x21, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x6a, 0x6d, 0x70, 0x00, 0x00, 0x00, + 0xc3, 0x45, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x6a, 0x6d, 0x70, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, 0xc3, 0x9a, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x6a, 0x73, 0x72, 0x00, 0x00, 0x00, 0xc3, 0xc6, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x6a, 0x73, 0x72, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x00, 0x00, 0xc4, 0x0a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x00, 0x00, 0x00, 0xc4, + 0x20, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, + 0x5f, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, + 0xc4, 0x5c, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, + 0x00, 0x00, 0x00, 0xc4, 0x72, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x6f, 0x66, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x00, 0x00, 0xc4, 0xae, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6e, 0x65, + 0x77, 0x00, 0x00, 0x00, 0xc4, 0xc4, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6e, 0x65, + 0x77, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x00, 0x00, 0xc5, 0x08, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x64, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x79, 0x00, 0x00, 0x00, 0xc5, 0x1e, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x70, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, + 0xc5, 0x73, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x5f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x00, 0x00, + 0x00, 0xc5, 0x97, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x5f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, + 0xc5, 0xdc, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, + 0x00, 0x00, 0x00, 0xc5, 0xf2, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x00, 0x00, 0xc6, 0x4c, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6d, 0x69, + 0x6e, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x00, 0x00, + 0x00, 0xc6, 0x78, 0x4a, 0x53, 0x43, 0x24, 0x41, + 0x53, 0x4d, 0x5f, 0x6d, 0x69, 0x6e, 0x5f, 0x61, + 0x72, 0x67, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x00, 0x00, 0xc6, 0xd2, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6c, 0x6f, + 0x61, 0x64, 0x5f, 0x6e, 0x74, 0x68, 0x5f, 0x61, + 0x72, 0x67, 0x00, 0x00, 0x00, 0xc6, 0xfe, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6c, + 0x6f, 0x61, 0x64, 0x5f, 0x6e, 0x74, 0x68, 0x5f, + 0x61, 0x72, 0x67, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x00, 0x00, 0xc7, 0x3a, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x77, 0x69, + 0x74, 0x68, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x00, + 0x00, 0x00, 0xc7, 0x50, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x77, 0x69, 0x74, 0x68, + 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, 0xc7, 0x95, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x77, 0x69, 0x74, 0x68, 0x5f, 0x70, 0x6f, 0x70, + 0x00, 0x00, 0x00, 0xc7, 0xab, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x77, 0x69, 0x74, + 0x68, 0x5f, 0x70, 0x6f, 0x70, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, 0xc7, 0xfc, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x74, 0x72, 0x79, 0x5f, 0x70, 0x75, 0x73, 0x68, + 0x00, 0x00, 0x00, 0xc8, 0x28, 0x4a, 0x53, 0x43, + 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x74, 0x72, 0x79, + 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, 0xc8, 0x7d, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x74, 0x72, 0x79, 0x5f, 0x70, 0x6f, 0x70, 0x00, + 0x00, 0x00, 0xc8, 0xa9, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x74, 0x72, 0x79, 0x5f, + 0x70, 0x6f, 0x70, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x00, 0x00, 0xc8, 0xfa, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x74, 0x68, + 0x72, 0x6f, 0x77, 0x00, 0x00, 0x00, 0xc9, 0x26, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x74, 0x68, 0x72, 0x6f, 0x77, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, 0xc9, 0x6b, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x69, 0x66, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x5f, + 0x62, 0x00, 0x00, 0x00, 0xc9, 0x81, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x69, 0x66, + 0x66, 0x61, 0x6c, 0x73, 0x65, 0x5f, 0x62, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, + 0xc9, 0xdf, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x69, 0x66, 0x74, 0x72, 0x75, 0x65, + 0x5f, 0x62, 0x00, 0x00, 0x00, 0xca, 0x0b, 0x4a, + 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x69, + 0x66, 0x74, 0x72, 0x75, 0x65, 0x5f, 0x62, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, + 0xca, 0x69, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x61, 0x64, 0x64, 0x5f, 0x31, 0x5f, + 0x69, 0x00, 0x00, 0x00, 0xca, 0x95, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x61, 0x64, + 0x64, 0x5f, 0x31, 0x5f, 0x69, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, 0xca, 0xd1, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x61, 0x64, 0x64, 0x5f, 0x32, 0x5f, 0x69, 0x00, + 0x00, 0x00, 0xca, 0xe7, 0x4a, 0x53, 0x43, 0x24, + 0x41, 0x53, 0x4d, 0x5f, 0x61, 0x64, 0x64, 0x5f, + 0x32, 0x5f, 0x69, 0x5f, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x00, 0x00, 0x00, 0xcb, 0x23, 0x4a, 0x53, + 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, 0x6c, 0x6f, + 0x61, 0x64, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x5f, 0x77, 0x00, 0x00, 0x00, 0xcb, 0x39, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x67, 0x6c, 0x6f, + 0x62, 0x61, 0x6c, 0x5f, 0x77, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, 0xcb, 0x96, + 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, 0x4d, 0x5f, + 0x6a, 0x73, 0x72, 0x5f, 0x77, 0x00, 0x00, 0x00, + 0xcb, 0xba, 0x4a, 0x53, 0x43, 0x24, 0x41, 0x53, + 0x4d, 0x5f, 0x6a, 0x73, 0x72, 0x5f, 0x77, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, + 0xcc, 0x17, 0x4a, 0x53, 0x43, 0x24, 0x61, 0x73, + 0x6d, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x00, 0x00, + 0x00, 0xcc, 0x3b, 0x4a, 0x53, 0x43, 0x24, 0x61, + 0x73, 0x6d, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x74, + 0x00, 0x00, 0x00, 0xcc, 0x7f, 0x4a, 0x53, 0x43, + 0x24, 0x61, 0x73, 0x6d, 0x5f, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, + 0xcc, 0xb0, 0x4a, 0x53, 0x43, 0x24, 0x61, 0x73, + 0x6d, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, + 0x00, 0x00, 0xce, 0x45, 0x4a, 0x53, 0x43, 0x24, + 0x61, 0x73, 0x6d, 0x5f, 0x69, 0x73, 0x5f, 0x6c, + 0x6f, 0x61, 0x64, 0x5f, 0x6f, 0x70, 0x00, 0x00, + 0x00, 0xcf, 0xcc, 0x4a, 0x53, 0x43, 0x24, 0x61, + 0x73, 0x6d, 0x5f, 0x69, 0x73, 0x5f, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x5f, 0x6f, 0x70, 0x00, 0x00, + 0x00, 0xd0, 0x07, 0x4a, 0x53, 0x43, 0x24, 0x61, + 0x73, 0x6d, 0x5f, 0x69, 0x73, 0x5f, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x5f, 0x6a, 0x75, 0x6d, 0x70, + 0x00, 0x00, 0x00, 0xd0, 0x42, 0x4a, 0x53, 0x43, + 0x24, 0x61, 0x73, 0x6d, 0x5f, 0x69, 0x73, 0x5f, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x6f, 0x70, + 0x00, 0x00, 0x00, 0xd0, 0xb9, 0x4a, 0x53, 0x43, + 0x24, 0x61, 0x73, 0x6d, 0x5f, 0x6c, 0x6f, 0x6f, + 0x6b, 0x75, 0x70, 0x5f, 0x6e, 0x65, 0x78, 0x74, + 0x5f, 0x6f, 0x70, 0x00, 0x00, 0x00, 0xd0, 0xe0, + 0x4a, 0x53, 0x43, 0x24, 0x61, 0x73, 0x6d, 0x5f, + 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, + 0x00, 0x00, 0x00, 0xd1, 0x27, 0x4a, 0x53, 0x43, + 0x24, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, + 0x65, 0x5f, 0x68, 0x65, 0x61, 0x76, 0x79, 0x00, + 0x00, 0x00, 0xd9, 0xac, 0x4a, 0x53, 0x43, 0x24, + 0x61, 0x73, 0x6d, 0x5f, 0x66, 0x69, 0x6e, 0x61, + 0x6c, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0xdd, + 0x5f, 0x4a, 0x53, 0x43, 0x24, 0x43, 0x6f, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x67, + 0x00, 0x00, 0x00, 0xdd, 0xa9, 0x4a, 0x53, 0x43, + 0x24, 0x61, 0x73, 0x6d, 0x5f, 0x67, 0x65, 0x6e, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, + 0x00, 0x00, 0x00, 0xdd, 0xb0, 0x4a, 0x53, 0x43, + 0x24, 0x61, 0x73, 0x6d, 0x5f, 0x62, 0x79, 0x74, + 0x65, 0x63, 0x6f, 0x64, 0x65, 0x00, 0x00, 0x00, + 0xde, 0x20, 0x4a, 0x53, 0x43, 0x24, 0x63, 0x6f, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x5f, 0x66, 0x69, + 0x6c, 0x65, 0x00, 0x00, 0x00, 0xe2, 0x2e, 0x4a, + 0x53, 0x43, 0x24, 0x63, 0x6f, 0x6d, 0x70, 0x69, + 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x00, 0x00, 0x00, 0xe2, 0x5c, 0x4a, 0x53, + 0x43, 0x24, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, + 0x65, 0x72, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x74, + 0x00, 0x00, 0x00, 0xe2, 0x8a, 0x4a, 0x53, 0x43, + 0x24, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x00, + 0x00, 0x00, 0xe2, 0xac, 0x2e, 0x67, 0x6c, 0x6f, + 0x62, 0x61, 0x6c, 0x00, 0x00, 0x00, 0xe5, 0xe9, +}; +unsigned int js_compiler_bytecode_len = 89552; +#define JS_COMPILER_BYTECODE_LEN 89552 diff --git a/reactos/lib/kjs/src/crc32.c b/reactos/lib/kjs/src/crc32.c new file mode 100644 index 00000000000..8058cc6f268 --- /dev/null +++ b/reactos/lib/kjs/src/crc32.c @@ -0,0 +1,112 @@ +/* The implementation here was originally done by Gary S. Brown. I have + borrowed the tables directly, and made some minor changes to the + crc32-function (including changing the interface). // mtr */ + + /* ============================================================= */ + /* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or */ + /* code or tables extracted from it, as desired without restriction. */ + /* */ + /* First, the polynomial itself and its table of feedback terms. The */ + /* polynomial is */ + /* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ + /* */ + /* Note that we take it "backwards" and put the highest-order term in */ + /* the lowest-order bit. The X^32 term is "implied"; the LSB is the */ + /* X^31 term, etc. The X^0 term (usually shown as "+1") results in */ + /* the MSB being 1. */ + /* */ + /* Note that the usual hardware shift register implementation, which */ + /* is what we're using (we're merely optimizing it by doing eight-bit */ + /* chunks at a time) shifts bits into the lowest-order term. In our */ + /* implementation, that means shifting towards the right. Why do we */ + /* do it this way? Because the calculated CRC must be transmitted in */ + /* order from highest-order term to lowest-order term. UARTs transmit */ + /* characters in order from LSB to MSB. By storing the CRC this way, */ + /* we hand it to the UART in the order low-byte to high-byte; the UART */ + /* sends each low-bit to hight-bit; and the result is transmission bit */ + /* by bit from highest- to lowest-order term without requiring any bit */ + /* shuffling on our part. Reception works similarly. */ + /* */ + /* The feedback terms table consists of 256, 32-bit entries. Notes: */ + /* */ + /* The table can be generated at runtime if desired; code to do so */ + /* is shown later. It might not be obvious, but the feedback */ + /* terms simply represent the results of eight shift/xor opera- */ + /* tions for all combinations of data and CRC register values. */ + /* */ + /* The values must be right-shifted by eight bits by the "updcrc" */ + /* logic; the shift must be unsigned (bring in zeroes). On some */ + /* hardware you could probably optimize the shift in assembler by */ + /* using byte-swap instructions. */ + /* polynomial $edb88320 */ + /* */ + /* -------------------------------------------------------------------- */ + +static unsigned long crc32_tab[] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL + }; + +/* Return a 32-bit CRC of the contents of the buffer. */ + +unsigned long +js_crc32 (const unsigned char *s, unsigned int len) +{ + unsigned int i; + unsigned long crc32val = 0; + + for (i = 0; i < len; i++) + crc32val = crc32_tab[(unsigned char) crc32val ^ s[i]] ^ (crc32val >> 8); + + return crc32val; +} diff --git a/reactos/lib/kjs/src/debug.c b/reactos/lib/kjs/src/debug.c new file mode 100644 index 00000000000..ce9a3c501eb --- /dev/null +++ b/reactos/lib/kjs/src/debug.c @@ -0,0 +1,171 @@ +/* + * Debugging utilities. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/debug.c,v $ + * $Id: debug.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" + +/* + * Global functions. + */ + +#define STRING_MAX_PRINT_LEN 10 + +void +js_vm_stacktrace (JSVirtualMachine *vm, unsigned int num_frames) +{ + unsigned int frame = 0; + JSNode *sp = vm->sp; + void *pc = vm->pc; + JSNode *fp; + char buf[512]; + int i; + + sprintf (buf, "VM: stacktrace: stacksize=%d, used=%d%s", + vm->stack_size, + (vm->stack + vm->stack_size - sp), + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + + /* STACKFRAME */ + + /* Find frame pointer. */ + for (fp = sp + 1; fp->type != JS_IPTR; fp++) + ; + + /* The first iptr is the return address. */ + fp++; + + /* The second iptr is the with pointer. */ + fp++; + + /* The third item is a JS_ARGS_FIX node. */ + assert (fp->type == JS_ARGS_FIX); + fp++; + + while (fp && frame < num_frames) + { + JSNode *n; + const char *func_name = js_vm_func_name (vm, pc); + + sprintf (buf, "#%-3u %s%s:", frame++, func_name, + func_name[0] == '.' ? "" : "()"); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + + if (vm->verbose_stacktrace) + { + sprintf (buf, + " ra=0x%lx, wp=0x%lx, af=%d:%d, ofp=0x%lx", + (unsigned long) (fp - 3)->u.iptr, + (unsigned long) JS_WITHPTR->u.iptr, + JS_ARGS_FIXP->u.args_fix.argc, + JS_ARGS_FIXP->u.args_fix.delta, + (unsigned long) fp->u.iptr); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + + for (n = sp + 1; n != fp - 3; n++) + { + switch (n->type) + { + case JS_UNDEFINED: + sprintf (buf, " undefined"); + break; + + case JS_NULL: + sprintf (buf, " null"); + break; + + case JS_BOOLEAN: + sprintf (buf, " %s", n->u.vboolean ? "true" : "false"); + break; + + case JS_INTEGER: + sprintf (buf, " %ld", n->u.vinteger); + break; + + case JS_STRING: + if (n->u.vstring->len > STRING_MAX_PRINT_LEN) + sprintf (buf, " \"%.*s...\"", + STRING_MAX_PRINT_LEN, + n->u.vstring->data); + else + sprintf (buf, " \"%.*s\"", + (int) n->u.vstring->len, + n->u.vstring->data); + break; + + case JS_FLOAT: + sprintf (buf, " %g", n->u.vfloat); + break; + + case JS_ARRAY: + sprintf (buf, " array"); + break; + + case JS_OBJECT: + sprintf (buf, " object"); + break; + + case JS_SYMBOL: + sprintf (buf, " %s", js_vm_symname (vm, n->u.vsymbol)); + break; + + case JS_BUILTIN: + sprintf (buf, " builtin"); + break; + + case JS_FUNC: + sprintf (buf, " function"); + break; + + case JS_IPTR: + sprintf (buf, " 0x%lx", (unsigned long) n->u.iptr); + break; + + case JS_ARGS_FIX: + sprintf (buf, " ", n->u.args_fix.argc, + n->u.args_fix.delta); + break; + + default: + sprintf (buf, " type=%d???", n->type); + break; + } + + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + + js_iostream_write (vm->s_stderr, JS_HOST_LINE_BREAK, + JS_HOST_LINE_BREAK_LEN); + + /* Move to the caller. */ + sp = fp; + pc = fp[-3].u.iptr; + fp = fp->u.iptr; + } +} diff --git a/reactos/lib/kjs/src/dl_dummy.c b/reactos/lib/kjs/src/dl_dummy.c new file mode 100644 index 00000000000..7d3c141602b --- /dev/null +++ b/reactos/lib/kjs/src/dl_dummy.c @@ -0,0 +1,77 @@ +/* + * Dummy dynamic loading functions for systems that do not support dload. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/dl_dummy.c,v $ + * $Id: dl_dummy.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" + +/* + * Prototypes for static functions. + */ + +static void set_error (char *error_return, unsigned int error_return_len); + + +/* + * Global functions. + */ + +void * +js_dl_open (const char *filename, char *error_return, + unsigned int error_return_len) +{ + set_error (error_return, error_return_len); + return NULL; +} + +void * +js_dl_sym (void *library, char *symbol, char *error_return, + unsigned int error_return_len) +{ + set_error (error_return, error_return_len); + return NULL; +} + + +/* + * Static functions. + */ + +static void +set_error (char *error_return, unsigned int error_return_len) +{ + char msg[512]; + unsigned int msg_len; + + sprintf (msg, "dynamic loading is not supported on %s", CANONICAL_HOST); + msg_len = strlen (msg); + if (msg_len > error_return_len - 1) + msg_len = error_return_len - 1; + + memcpy (error_return, msg, msg_len); + error_return[msg_len] = '\0'; +} diff --git a/reactos/lib/kjs/src/dl_open.c b/reactos/lib/kjs/src/dl_open.c new file mode 100644 index 00000000000..a210f97adc9 --- /dev/null +++ b/reactos/lib/kjs/src/dl_open.c @@ -0,0 +1,80 @@ +/* + * Dynamic loading with dl{open,close,sym}() functions. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/dl_open.c,v $ + * $Id: dl_open.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" +#include + +/* + * Global functions. + */ + +void * +js_dl_open (const char *filename, char *error_return, + unsigned int error_return_len) +{ + void *lib = dlopen (filename, RTLD_NOW); + + if (lib == NULL) + { + const char *msg = dlerror (); + unsigned int msg_len; + + msg_len = strlen (msg); + if (msg_len > error_return_len - 1) + msg_len = error_return_len - 1; + + memcpy (error_return, msg, msg_len); + error_return[msg_len] = '\0'; + } + + return lib; +} + + +void * +js_dl_sym (void *library, char *symbol, char *error_return, + unsigned int error_return_len) +{ + void *sym = dlsym (library, symbol); + + if (sym == NULL) + { + const char *msg = dlerror (); + unsigned int msg_len; + + msg_len = strlen (msg); + if (msg_len > error_return_len - 1) + msg_len = error_return_len - 1; + + memcpy (error_return, msg, msg_len); + error_return[msg_len] = '\0'; + } + + return sym; +} diff --git a/reactos/lib/kjs/src/ejumps.h b/reactos/lib/kjs/src/ejumps.h new file mode 100644 index 00000000000..43cf83b4722 --- /dev/null +++ b/reactos/lib/kjs/src/ejumps.h @@ -0,0 +1,2239 @@ +/* operand halt (0) */ +op_halt: + OPERAND (0); + sprintf (buf, "VM: halt%s", JS_HOST_LINE_BREAK); + + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); + + while (1) + sleep (5); + NEXT (); + +/* operand done (1) */ +op_done: + OPERAND (1); + DONE (); + NEXT (); + +/* operand nop (2) */ +op_nop: + OPERAND (2); + /* Nothing here! */ + NEXT (); + +/* operand dup (3) */ +op_dup: + OPERAND (3); + JS_COPY (JS_SP0, JS_SP1); + JS_PUSH (); + NEXT (); + +/* operand pop (4) */ +op_pop: + OPERAND (4); + JS_POP (); + NEXT (); + +/* operand pop_n (5) */ +op_pop_n: + OPERAND (5); + READ_INT8 (i); + JS_POP_N (i); + NEXT (); + +/* operand apop (6) */ +op_apop: + OPERAND (6); + READ_INT8 (i); + JS_COPY (JS_SP (i + 1), JS_SP1); + JS_POP_N (i); + NEXT (); + +/* operand swap (7) */ +op_swap: + OPERAND (7); + JS_COPY (JS_SP0, JS_SP2); + JS_COPY (JS_SP2, JS_SP1); + JS_COPY (JS_SP1, JS_SP0); + NEXT (); + +/* operand roll (8) */ +op_roll: + OPERAND (8); + READ_INT8 (i8); + + if (i8 > 1) + { + int j; + + for (j = 0; j < i8; j++) + JS_COPY (JS_SP (j), JS_SP (j + 1)); + + JS_COPY (JS_SP (i8), JS_SP0); + } + else if (i8 < -1) + { + i8 = -i8; + + JS_COPY (JS_SP0, JS_SP (i8)); + for (; i8 > 0; i8--) + JS_COPY (JS_SP (i8), JS_SP (i8 - 1)); + } + NEXT (); + +/* operand const (9) */ +op_const: + OPERAND (9); + READ_INT32 (i); + JS_COPY (JS_SP0, JS_CONST (i)); + JS_PUSH (); + NEXT (); + +/* operand const_null (10) */ +op_const_null: + OPERAND (10); + JS_SP0->type = JS_NULL; + JS_PUSH (); + NEXT (); + +/* operand const_true (11) */ +op_const_true: + OPERAND (11); + JS_SP0->type = JS_BOOLEAN; + JS_SP0->u.vboolean = 1; + JS_PUSH (); + NEXT (); + +/* operand const_false (12) */ +op_const_false: + OPERAND (12); + JS_SP0->type = JS_BOOLEAN; + JS_SP0->u.vboolean = 0; + JS_PUSH (); + NEXT (); + +/* operand const_undefined (13) */ +op_const_undefined: + OPERAND (13); + JS_SP0->type = JS_UNDEFINED; + JS_PUSH (); + NEXT (); + +/* operand const_i0 (14) */ +op_const_i0: + OPERAND (14); + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 0; + JS_PUSH (); + NEXT (); + +/* operand const_i1 (15) */ +op_const_i1: + OPERAND (15); + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 1; + JS_PUSH (); + NEXT (); + +/* operand const_i2 (16) */ +op_const_i2: + OPERAND (16); + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 2; + JS_PUSH (); + NEXT (); + +/* operand const_i3 (17) */ +op_const_i3: + OPERAND (17); + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 3; + JS_PUSH (); + NEXT (); + +/* operand const_i (18) */ +op_const_i: + OPERAND (18); + READ_INT32 (i); + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = i; + JS_PUSH (); + NEXT (); + +/* operand load_global (19) */ +op_load_global: + OPERAND (19); + READ_INT32 (j); + + /* Use the global value only. */ + JS_COPY (JS_SP0, JS_GLOBAL (j)); + JS_PUSH (); + + if (vm->warn_undef && JS_SP1->type == JS_UNDEFINED) + { + sprintf (buf, "VM: warning: using undefined global `%s'%s", + js_vm_symname (vm, j), JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + NEXT (); + +/* operand store_global (20) */ +op_store_global: + OPERAND (20); + READ_INT32 (i); + + /* Operand store_global do not check the with-chain. */ + /* WITHCHAIN */ + + /* Set the global value. */ + JS_COPY (JS_GLOBAL (i), JS_SP1); + JS_POP (); + NEXT (); + +/* operand load_arg (21) */ +op_load_arg: + OPERAND (21); + READ_INT8 (i); + JS_COPY (JS_SP0, JS_ARG (i)); + JS_PUSH (); + NEXT (); + +/* operand store_arg (22) */ +op_store_arg: + OPERAND (22); + READ_INT8 (i); + JS_COPY (JS_ARG (i), JS_SP1); + JS_POP (); + NEXT (); + +/* operand load_local (23) */ +op_load_local: + OPERAND (23); + READ_INT16 (i); + JS_COPY (JS_SP0, JS_LOCAL (i)); + JS_PUSH (); + NEXT (); + +/* operand store_local (24) */ +op_store_local: + OPERAND (24); + READ_INT16 (i); + JS_COPY (JS_LOCAL (i), JS_SP1); + JS_POP (); + NEXT (); + +/* operand load_property (25) */ +op_load_property: + OPERAND (25); + /* Fetch the property symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (JS_SP1->u.vbuiltin->info->property_proc) + { + if ((*JS_SP1->u.vbuiltin->info->property_proc) ( + vm, + JS_SP1->u.vbuiltin->info, + JS_SP1->u.vbuiltin->instance_context, + j, 0, &builtin_result) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Looking up the prototype. */ + + builtin_result.type = JS_OBJECT; + if (JS_SP1->u.vbuiltin->prototype) + /* This is an instance. */ + builtin_result.u.vobject = JS_SP1->u.vbuiltin->prototype; + else + /* This is a class. */ + builtin_result.u.vobject + = JS_SP1->u.vbuiltin->info->prototype; + } + else + { + /* Looking up stuffs from the prototype. */ + + if (JS_SP1->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_load_property (vm, + JS_SP1->u.vbuiltin->prototype, + j, &builtin_result); + else + /* A class. */ + js_vm_object_load_property ( + vm, + JS_SP1->u.vbuiltin->info->prototype, + j, &builtin_result); + } + } + JS_COPY (JS_SP1, &builtin_result); + } + else + ERROR ("illegal builtin object for load_property"); + } + else if (JS_SP1->type == JS_OBJECT) + { + js_vm_object_load_property (vm, JS_SP1->u.vobject, j, JS_SP1); + } + else if (vm->prim[JS_SP1->type]) + { + /* The primitive language types. */ + JS_SAVE_REGS (); + if ((*vm->prim[JS_SP1->type]->property_proc) (vm, vm->prim[JS_SP1->type], + JS_SP1, j, 0, + &builtin_result) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Looking up the prototype. */ + switch (JS_SP1->type) + { + case JS_STRING: + if (JS_SP1->u.vstring->prototype) + { + builtin_result.type = JS_OBJECT; + builtin_result.u.vobject = JS_SP1->u.vstring->prototype; + } + else + /* No prototype yet. */ + builtin_result.type = JS_NULL; + break; + + case JS_ARRAY: + if (JS_SP1->u.varray->prototype) + { + builtin_result.type = JS_OBJECT; + builtin_result.u.vobject = JS_SP1->u.varray->prototype; + } + else + /* No prototype yet. */ + builtin_result.type = JS_NULL; + break; + + case JS_FUNC: + if (JS_SP1->u.vfunction->prototype) + { + builtin_result.type = JS_OBJECT; + builtin_result.u.vobject + = JS_SP1->u.vfunction->prototype; + } + else + /* No prototype yet. */ + builtin_result.type = JS_NULL; + break; + + default: + /* The rest do not have prototype. */ + builtin_result.type = JS_NULL; + break; + } + } + else + { + /* Looking up stuffs from the prototype. */ + switch (JS_SP1->type) + { + case JS_STRING: + if (JS_SP1->u.vstring->prototype) + js_vm_object_load_property (vm, + JS_SP1->u.vstring->prototype, + j, &builtin_result); + else + /* Take it from the class' prototype */ + goto _op_load_property_try_proto; + break; + + case JS_ARRAY: + if (JS_SP1->u.varray->prototype) + js_vm_object_load_property (vm, + JS_SP1->u.varray->prototype, + j, &builtin_result); + else + /* Take it from the class' prototype */ + goto _op_load_property_try_proto; + break; + + case JS_FUNC: + if (JS_SP1->u.vfunction->prototype) + js_vm_object_load_property (vm, + JS_SP1->u.vfunction->prototype, + j, &builtin_result); + else + /* Take it from the class' prototype */ + goto _op_load_property_try_proto; + break; + + default: + /* + * The rest do not have instance prototypes; use the + * class prototypes. + */ + _op_load_property_try_proto: + js_vm_object_load_property ( + vm, + vm->prim[JS_SP1->type]->prototype, j, + &builtin_result); + break; + } + } + } + + JS_COPY (JS_SP1, &builtin_result); + } + else + ERROR ("illegal object for load_property"); + NEXT (); + +/* operand store_property (26) */ +op_store_property: + OPERAND (26); + /* Fetch the property symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (JS_SP1->u.vbuiltin->info->property_proc) + { + if ((*JS_SP1->u.vbuiltin->info->property_proc) ( + vm, + JS_SP1->u.vbuiltin->info, + JS_SP1->u.vbuiltin->instance_context, + j, 1, JS_SP2) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Setting the prototype. */ + if (JS_SP2->type != JS_OBJECT) + ERROR ("illegal value for set_property"); + + if (JS_SP1->u.vbuiltin->prototype) + /* Setting the instance's prototype. */ + JS_SP1->u.vbuiltin->prototype = JS_SP2->u.vobject; + else + /* Setting the class' prototype. */ + JS_SP1->u.vbuiltin->info->prototype = JS_SP2->u.vobject; + } + else + { + /* Setting stuff to the prototype. */ + if (JS_SP1->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_store_property (vm, + JS_SP1->u.vbuiltin->prototype, + j, JS_SP2); + else + /* A class. */ + js_vm_object_store_property ( + vm, + JS_SP1->u.vbuiltin->info->prototype, + j, JS_SP2); + } + } + } + else + ERROR ("illegal builtin object for store_property"); + + JS_POP (); + JS_POP (); + } + else if (JS_SP1->type == JS_OBJECT) + { + js_vm_object_store_property (vm, JS_SP1->u.vobject, j, JS_SP2); + JS_POP (); + JS_POP (); + } + else if (vm->prim[JS_SP1->type]) + { + /* The primitive language types. */ + JS_SAVE_REGS (); + if ((*vm->prim[JS_SP1->type]->property_proc) (vm, vm->prim[JS_SP1->type], + JS_SP1, j, 1, JS_SP2) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Setting the prototype. */ + if (JS_SP2->type != JS_OBJECT) + ERROR ("illegal value for set_property"); + + switch (JS_SP1->type) + { + case JS_STRING: + JS_SP1->u.vstring->prototype = JS_SP2->u.vobject; + break; + + case JS_ARRAY: + JS_SP1->u.varray->prototype = JS_SP2->u.vobject; + break; + + case JS_FUNC: + JS_SP1->u.vfunction->prototype = JS_SP2->u.vobject; + break; + + default: + ERROR ("illegal object for set_property"); + break; + } + } + else + { + JSNode prototype; + + /* Setting to the prototype. We create them on demand. */ + switch (JS_SP1->type) + { + case JS_STRING: + if (JS_SP1->u.vstring->prototype == NULL) + { + prototype.type = JS_OBJECT; + + /* Create the prototype and set its __proto__. */ + JS_SP1->u.vstring->prototype = js_vm_object_new (vm); + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property ( + vm, + JS_SP1->u.vstring->prototype, + vm->syms.s___proto__, + &prototype); + } + js_vm_object_store_property (vm, + JS_SP1->u.vstring->prototype, + j, JS_SP2); + break; + + case JS_ARRAY: + if (JS_SP1->u.varray->prototype == NULL) + { + prototype.type = JS_OBJECT; + + /* Create the prototype and set its __proto__. */ + JS_SP1->u.varray->prototype = js_vm_object_new (vm); + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property ( + vm, + JS_SP1->u.varray->prototype, + vm->syms.s___proto__, + &prototype); + } + js_vm_object_store_property (vm, + JS_SP1->u.varray->prototype, + j, JS_SP2); + break; + + case JS_FUNC: + if (JS_SP1->u.vfunction->prototype == NULL) + { + prototype.type = JS_OBJECT; + + /* Create the prototype and set its __proto__. */ + JS_SP1->u.vfunction->prototype = js_vm_object_new (vm); + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property ( + vm, + JS_SP1->u.vfunction->prototype, + vm->syms.s___proto__, + &prototype); + } + js_vm_object_store_property (vm, + JS_SP1->u.vfunction->prototype, + j, JS_SP2); + break; + + default: + ERROR ("illegal object for set_property"); + break; + } + } + } + JS_POP (); + JS_POP (); + } + else + ERROR ("illegal object for store_property"); + + JS_MAYBE_GC (); + NEXT (); + +/* operand load_array (27) */ +op_load_array: + OPERAND (27); + if (JS_SP2->type == JS_BUILTIN) + { + if (JS_SP1->type == JS_INTEGER) + { + ERROR ("integer indexes not implemented yet for BUILTIN in load_array"); + } + else if (JS_SP1->type == JS_STRING) + { + /* Intern the string. */ + j = js_vm_intern_with_len (vm, JS_SP1->u.vstring->data, + JS_SP1->u.vstring->len); + + /* The code below must be in sync with operand `load_property'. */ + JS_SAVE_REGS (); + + if (JS_SP2->u.vbuiltin->info->property_proc) + { + if ((*JS_SP2->u.vbuiltin->info->property_proc) ( + vm, + JS_SP2->u.vbuiltin->info, + JS_SP2->u.vbuiltin->instance_context, + j, 0, &builtin_result) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Looking up the prototype. */ + + builtin_result.type = JS_OBJECT; + if (JS_SP2->u.vbuiltin->prototype) + /* This is an instance. */ + builtin_result.u.vobject + = JS_SP2->u.vbuiltin->prototype; + else + /* This is a class. */ + builtin_result.u.vobject + = JS_SP2->u.vbuiltin->info->prototype; + } + else + { + /* Looking up stuffs from the prototype. */ + + if (JS_SP2->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_load_property ( + vm, + JS_SP2->u.vbuiltin->prototype, + j, &builtin_result); + else + /* A class. */ + js_vm_object_load_property ( + vm, + JS_SP2->u.vbuiltin->info->prototype, + j, &builtin_result); + } + } + JS_COPY (JS_SP2, &builtin_result); + JS_POP (); + } + else + ERROR ("illegal builtin object for load_array"); + } + else + { + sprintf (buf, "illegal array index in load_array (%d)", + JS_SP1->type); + ERROR (buf); + } + } + else if (JS_SP2->type == JS_OBJECT) + { + js_vm_object_load_array (vm, JS_SP2->u.vobject, JS_SP1, JS_SP2); + JS_POP (); + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->type == JS_INTEGER) + { + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.varray->length) + JS_SP2->type = JS_UNDEFINED; + else + { + JSNode *n = &JS_SP2->u.varray->data[JS_SP1->u.vinteger]; + JS_COPY (JS_SP2, n); + } + JS_POP (); + } + else + { + sprintf (buf, "illegal array index in load_array (%d)", + JS_SP1->type); + ERROR (buf); + } + } + else if (JS_SP2->type == JS_STRING) + { + if (JS_SP1->type == JS_INTEGER) + { + int ch; + + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.vstring->len) + ERROR ("string index out of range in load_array"); + + ch = JS_SP2->u.vstring->data[JS_SP1->u.vinteger]; + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = ch; + + JS_POP (); + } + else + ERROR ("illegal string index in load_array"); + } + else + ERROR ("illegal object for load_array"); + NEXT (); + +/* operand store_array (28) */ +op_store_array: + OPERAND (28); + if (JS_SP2->type == JS_BUILTIN) + { + if (JS_SP1->type == JS_INTEGER) + { + ERROR ("integer index not implemented yet for BUILTIN in store_array"); + } + else if (JS_SP1->type == JS_STRING) + { + /* Intern the string. */ + j = js_vm_intern_with_len (vm, JS_SP1->u.vstring->data, + JS_SP1->u.vstring->len); + + /* The code below msut be in sync with operand `store_property'. */ + JS_SAVE_REGS (); + if (JS_SP2->u.vbuiltin->info->property_proc) + { + if ((*JS_SP2->u.vbuiltin->info->property_proc) ( + vm, + JS_SP2->u.vbuiltin->info, + JS_SP2->u.vbuiltin->instance_context, + j, 1, JS_SP (3)) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Setting the prototype. */ + if (JS_SP (3)->type != JS_OBJECT) + ERROR ("illegal value for prototype"); + + if (JS_SP2->u.vbuiltin->prototype) + /* Setting the instance's prototype. */ + JS_SP2->u.vbuiltin->prototype = JS_SP (3)->u.vobject; + else + /* Setting the class' prototype. */ + JS_SP2->u.vbuiltin->info->prototype + = JS_SP (3)->u.vobject; + } + else + { + /* Setting stuff to the prototype. */ + if (JS_SP2->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_store_property ( + vm, + JS_SP2->u.vbuiltin->prototype, + j, JS_SP (3)); + else + /* A class. */ + js_vm_object_store_property ( + vm, + JS_SP2->u.vbuiltin->info->prototype, + j, JS_SP (3)); + } + } + } + else + ERROR ("illegal builtin object for store_array"); + + JS_POP_N (3); + } + else + ERROR ("illegal array index in store_array"); + } + else if (JS_SP2->type == JS_OBJECT) + { + js_vm_object_store_array (vm, JS_SP2->u.vobject, JS_SP1, JS_SP (3)); + JS_POP_N (3); + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->type == JS_INTEGER) + { + if (JS_SP1->u.vinteger < 0) + ERROR ("negative array index in store_array"); + if (JS_SP1->u.vinteger >= JS_SP2->u.varray->length) + js_vm_expand_array (vm, JS_SP2, JS_SP1->u.vinteger + 1); + + JS_COPY (&JS_SP2->u.varray->data[JS_SP1->u.vinteger], JS_SP (3)); + JS_POP_N (3); + } + else + ERROR ("illegal array index in store_array"); + } + else if (JS_SP2->type == JS_STRING) + { + if (JS_SP1->type == JS_INTEGER) + { + if (JS_SP2->u.vstring->staticp) + ERROR ("static string in store_array"); + + if (JS_SP1->u.vinteger < 0) + ERROR ("negative string index in store_array"); + + if (JS_SP (3)->type != JS_INTEGER) + ERROR ("non-integer value to store into string in store_array"); + + if (JS_SP1->u.vinteger >= JS_SP2->u.vstring->len) + { + /* Expand the string. */ + JS_SP2->u.vstring->data = js_vm_realloc (vm, + JS_SP2->u.vstring->data, + JS_SP1->u.vinteger + 1); + /* Fill the gap with ' '. */ + for (; JS_SP2->u.vstring->len <= JS_SP1->u.vinteger;) + JS_SP2->u.vstring->data[JS_SP2->u.vstring->len++] = ' '; + } + + JS_SP2->u.vstring->data[JS_SP1->u.vinteger] + = (unsigned char) JS_SP (3)->u.vinteger; + JS_POP_N (3); + } + else + ERROR ("illegal string index in store_array"); + } + else + ERROR ("illegal object for store_array"); + + JS_MAYBE_GC (); + NEXT (); + +/* operand nth (29) */ +op_nth: + OPERAND (29); + if (JS_SP2->type == JS_STRING) + { + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.vstring->len) + { + JS_SP2->type = JS_UNDEFINED; + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 0; + } + else + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = JS_SP2->u.vstring->data[JS_SP1->u.vinteger]; + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 1; + } + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.varray->length) + { + JS_SP2->type = JS_UNDEFINED; + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 0; + } + else + { + JSNode *n = &JS_SP2->u.varray->data[JS_SP1->u.vinteger]; + JS_COPY (JS_SP2, n); + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 1; + } + } + else if (JS_SP2->type == JS_OBJECT) + { + i = js_vm_object_nth (vm, JS_SP2->u.vobject, JS_SP1->u.vinteger, JS_SP2); + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = i; + } + else + ERROR ("illegal object for nth"); + NEXT (); + +/* operand cmp_eq (30) */ +op_cmp_eq: + OPERAND (30); + JS_OPERAND_CMP_EQ (==, 1); + NEXT (); + +/* operand cmp_ne (31) */ +op_cmp_ne: + OPERAND (31); + JS_OPERAND_CMP_EQ (!=, 0); + NEXT (); + +/* operand cmp_lt (32) */ +op_cmp_lt: + OPERAND (32); + JS_OPERAND_CMP_REL (<); + NEXT (); + +/* operand cmp_gt (33) */ +op_cmp_gt: + OPERAND (33); + JS_OPERAND_CMP_REL (>); + NEXT (); + +/* operand cmp_le (34) */ +op_cmp_le: + OPERAND (34); + JS_OPERAND_CMP_REL (<=); + NEXT (); + +/* operand cmp_ge (35) */ +op_cmp_ge: + OPERAND (35); + JS_OPERAND_CMP_REL (>=); + NEXT (); + +/* operand cmp_seq (36) */ +op_cmp_seq: + OPERAND (36); + JS_OPERAND_CMP_SEQ (==, 1); + NEXT (); + +/* operand cmp_sne (37) */ +op_cmp_sne: + OPERAND (37); + JS_OPERAND_CMP_SEQ (!=, 0); + NEXT (); + +/* operand sub (38) */ +op_sub: + OPERAND (38); + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger -= JS_SP1->u.vinteger; + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (l->type == JS_INTEGER) + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger - r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = (double) l->u.vinteger - r->u.vfloat; + } + } + else + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat - (double) r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat - r->u.vfloat; + } + } + } + + JS_POP (); + NEXT (); + +/* operand add (39) */ +op_add: + OPERAND (39); + if (JS_SP2->type == JS_STRING || JS_SP1->type == JS_STRING) + { + unsigned char *d2, *d1, *ndata; + unsigned int d2_len, d1_len, nlen; + JSNode cvt; + + if (JS_SP2->type == JS_STRING) + { + d2 = JS_SP2->u.vstring->data; + d2_len = JS_SP2->u.vstring->len; + } + else + { + js_vm_to_string (vm, JS_SP2, &cvt); + d2 = cvt.u.vstring->data; + d2_len = cvt.u.vstring->len; + } + if (JS_SP1->type == JS_STRING) + { + d1 = JS_SP1->u.vstring->data; + d1_len = JS_SP1->u.vstring->len; + } + else + { + js_vm_to_string (vm, JS_SP1, &cvt); + d1 = cvt.u.vstring->data; + d1_len = cvt.u.vstring->len; + } + + nlen = d2_len + d1_len; + ndata = js_vm_alloc (vm, nlen); + memcpy (ndata, d2, d2_len); + memcpy (ndata + d2_len, d1, d1_len); + + js_vm_make_static_string (vm, JS_SP2, ndata, nlen); + JS_SP2->u.vstring->staticp = 0; + JS_POP (); + JS_MAYBE_GC (); + } + else if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger += JS_SP1->u.vinteger; + JS_POP (); + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (l->type == JS_INTEGER) + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger + r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = (double) l->u.vinteger + r->u.vfloat; + } + } + else + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat + (double) r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat + r->u.vfloat; + } + } + + JS_POP (); + } + NEXT (); + +/* operand mul (40) */ +op_mul: + OPERAND (40); + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger *= JS_SP1->u.vinteger; + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (l->type == JS_INTEGER) + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger * r->u.vinteger; + } + else + { + if (l->u.vinteger == 0 + && (JS_IS_POSITIVE_INFINITY (r) + || JS_IS_NEGATIVE_INFINITY (r))) + JS_SP2->type = JS_NAN; + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = (double) l->u.vinteger * r->u.vfloat; + } + } + } + else + { + if ((JS_IS_POSITIVE_INFINITY (l) || JS_IS_NEGATIVE_INFINITY (l)) + && ((r->type == JS_INTEGER && r->u.vinteger == 0) + || (r->type == JS_FLOAT && r->u.vfloat == 0.0))) + JS_SP2->type = JS_NAN; + else + { + JS_SP2->type = JS_FLOAT; + + if (r->type == JS_INTEGER) + JS_SP2->u.vfloat = l->u.vfloat * (double) r->u.vinteger; + else + JS_SP2->u.vfloat = l->u.vfloat * r->u.vfloat; + } + } + } + + JS_POP (); + NEXT (); + +/* operand div (41) */ +op_div: + OPERAND (41); + { + int nan = 0; + double l, r; + int l_inf = 0; + int r_inf = 0; + JSNode *n; + JSNode cvt; + + /* Convert divident to float. */ + if (JS_IS_NUMBER (JS_SP2)) + n = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &cvt); + n = &cvt; + } + + switch (n->type) + { + case JS_INTEGER: + l = (double) n->u.vinteger; + break; + + case JS_FLOAT: + l = n->u.vfloat; + if (JS_IS_POSITIVE_INFINITY (n) || JS_IS_NEGATIVE_INFINITY (n)) + l_inf = 1; + break; + + case JS_NAN: + default: + nan = 1; + break; + } + + /* Convert divisor to float. */ + if (JS_IS_NUMBER (JS_SP1)) + n = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP2, &cvt); + n = &cvt; + } + + switch (n->type) + { + case JS_INTEGER: + r = (double) n->u.vinteger; + break; + + case JS_FLOAT: + r = n->u.vfloat; + if (JS_IS_POSITIVE_INFINITY (n) || JS_IS_NEGATIVE_INFINITY (n)) + r_inf = 1; + break; + + case JS_NAN: + default: + nan = 1; + break; + } + + /* Do the division. */ + JS_POP (); + if (nan || (l_inf && r_inf)) + JS_SP1->type = JS_NAN; + else + { + if (l_inf && r == 0.0) + { + /* is already an infinity. */ + JS_SP1->type = JS_FLOAT; + JS_SP1->u.vfloat = l; + } + else if (l == 0.0 && r == 0.0) + JS_SP1->type = JS_NAN; + else + { + JS_SP1->type = JS_FLOAT; + JS_SP1->u.vfloat = l / r; + } + } + } + NEXT (); + +/* operand mod (42) */ +op_mod: + OPERAND (42); + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + if (JS_SP1->u.vinteger == 0) + JS_SP2->type = JS_NAN; + else + JS_SP2->u.vinteger %= JS_SP1->u.vinteger; + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (JS_IS_POSITIVE_INFINITY (l) + || JS_IS_NEGATIVE_INFINITY (l) + || ((r->type == JS_INTEGER && r->u.vinteger == 0) + || (r->type == JS_FLOAT && r->u.vfloat == 0.0))) + JS_SP2->type = JS_NAN; + else if (JS_IS_POSITIVE_INFINITY (r) + || JS_IS_NEGATIVE_INFINITY (r)) + JS_COPY (JS_SP2, l); + else if ((l->type == JS_INTEGER && l->u.vinteger == 0) + || (l->type == JS_FLOAT && l->u.vfloat == 0.0)) + JS_COPY (JS_SP2, l); + else + { + if (l->type == JS_INTEGER && r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger % r->u.vinteger; + } + else + { + double ld, rd; + int full; + + if (l->type == JS_INTEGER) + ld = (double) l->u.vinteger; + else + ld = l->u.vfloat; + + if (r->type == JS_INTEGER) + rd = (double) r->u.vinteger; + else + rd = r->u.vfloat; + + full = ld / rd; + + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = ld - (full * rd); + } + } + } + + JS_POP (); + NEXT (); + +/* operand neg (43) */ +op_neg: + OPERAND (43); + if (JS_SP1->type == JS_INTEGER) + JS_SP1->u.vinteger = -JS_SP1->u.vinteger; + else if (JS_SP1->type == JS_FLOAT) + JS_SP1->u.vfloat = -JS_SP1->u.vfloat; + else if (JS_SP1->type == JS_NAN) + ; + else + { + JSNode cvt; + + js_vm_to_number (vm, JS_SP1, &cvt); + + JS_SP1->type = cvt.type; + switch (cvt.type) + { + case JS_INTEGER: + JS_SP1->u.vinteger = -cvt.u.vinteger; + break; + + case JS_FLOAT: + JS_SP1->u.vfloat = -cvt.u.vfloat; + break; + + case JS_NAN: + default: + /* Nothing here. */ + break; + } + } + NEXT (); + +/* operand and (44) */ +op_and: + OPERAND (44); + JS_OPERAND_BINARY (&); + NEXT (); + +/* operand not (45) */ +op_not: + OPERAND (45); + JS_SP1->u.vboolean = JS_IS_FALSE (JS_SP1); + JS_SP1->type = JS_BOOLEAN; + NEXT (); + +/* operand or (46) */ +op_or: + OPERAND (46); + JS_OPERAND_BINARY (|); + NEXT (); + +/* operand xor (47) */ +op_xor: + OPERAND (47); + JS_OPERAND_BINARY (^); + NEXT (); + +/* operand shift_left (48) */ +op_shift_left: + OPERAND (48); + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger = ((JSInt32) JS_SP2->u.vinteger + << (JSUInt32) JS_SP1->u.vinteger); + JS_POP (); + } + else + { + JSInt32 l; + JSUInt32 r; + + l = js_vm_to_int32 (vm, JS_SP2); + r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1); + + JS_SP2->u.vinteger = l << r; + JS_SP2->type = JS_INTEGER; + JS_POP (); + } + NEXT (); + +/* operand shift_right (49) */ +op_shift_right: + OPERAND (49); + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger = ((JSInt32) JS_SP2->u.vinteger + >> (JSUInt32) JS_SP1->u.vinteger); + JS_POP (); + } + else + { + JSInt32 l; + JSUInt32 r; + + l = js_vm_to_int32 (vm, JS_SP2); + r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1); + + JS_SP2->u.vinteger = l >> r; + JS_SP2->type = JS_INTEGER; + JS_POP (); + } + NEXT (); + +/* operand shift_rright (50) */ +op_shift_rright: + OPERAND (50); + { + JSInt32 l; + JSUInt32 r; + + l = js_vm_to_int32 (vm, JS_SP2); + r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1); + + if (r > 0) + JS_SP2->u.vinteger = (l & 0x7fffffff) >> r; + else + JS_SP2->u.vinteger = l; + + JS_SP2->type = JS_INTEGER; + JS_POP (); + } + NEXT (); + +/* operand iffalse (51) */ +op_iffalse: + OPERAND (51); + READ_INT32 (i); + if (JS_IS_FALSE (JS_SP1)) + SETPC_RELATIVE (i); + JS_POP (); + NEXT (); + +/* operand iftrue (52) */ +op_iftrue: + OPERAND (52); + READ_INT32 (i); + if (JS_IS_TRUE (JS_SP1)) + SETPC_RELATIVE (i); + JS_POP (); + NEXT (); + +/* operand call_method (53) */ +op_call_method: + OPERAND (53); + /* Fetch the method symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (JS_SP1->u.vbuiltin->info->method_proc) + { + if ((*JS_SP1->u.vbuiltin->info->method_proc) ( + vm, + JS_SP1->u.vbuiltin->info, + JS_SP1->u.vbuiltin->instance_context, j, + &builtin_result, JS_SP2) + == JS_PROPERTY_UNKNOWN) + ERROR ("call_method: unknown method"); + } + else + ERROR ("illegal builtin object for call_method"); + + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + JS_MAYBE_GC (); + } + else if (JS_SP1->type == JS_OBJECT) + { + JSNode method; + + if (js_vm_object_load_property (vm, JS_SP1->u.vobject, j, &method) + == JS_PROPERTY_FOUND) + { + /* The property has been defined in the object. */ + + if (method.type != JS_FUNC) + ERROR ("call_method: unknown method"); + + /* And once again. We must do a subroutine call here. */ + JS_SUBROUTINE_CALL (method.u.vfunction->implementation); + } + else + /* Let our prototype handle this. */ + goto _op_call_method_try_proto; + } + else if (vm->prim[JS_SP1->type]) + { + /* The primitive language types. */ + _op_call_method_try_proto: + JS_SAVE_REGS (); + if ((*vm->prim[JS_SP1->type]->method_proc) (vm, vm->prim[JS_SP1->type], + JS_SP1, j, &builtin_result, + JS_SP2) + == JS_PROPERTY_UNKNOWN) + { + JSNode method; + int result = JS_PROPERTY_UNKNOWN; + + /* Let's see if we can find it from the prototype. */ + if (JS_SP1->type == JS_STRING && JS_SP1->u.vstring->prototype) + result = js_vm_object_load_property (vm, + JS_SP1->u.vstring->prototype, + j, &method); + else if (JS_SP1->type == JS_ARRAY && JS_SP1->u.varray->prototype) + result = js_vm_object_load_property (vm, + JS_SP1->u.varray->prototype, + j, &method); + else if (JS_SP1->type == JS_FUNC && JS_SP1->u.vfunction->prototype) + result + = js_vm_object_load_property (vm, JS_SP1->u.vfunction->prototype, + j, &method); + + if (result == JS_PROPERTY_UNKNOWN || method.type != JS_FUNC) + ERROR ("call_method: unknown method"); + + /* Do the subroutine call. */ + JS_SUBROUTINE_CALL (method.u.vfunction->implementation); + } + else + { + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + JS_MAYBE_GC (); + } + } + else + ERROR ("illegal object for call_method"); + NEXT (); + +/* operand jmp (54) */ +op_jmp: + OPERAND (54); + READ_INT32 (i); + SETPC_RELATIVE (i); + NEXT (); + +/* operand jsr (55) */ +op_jsr: + OPERAND (55); + /* Call the global method. */ + { + JSNode f; + + /* Fetch the function to our local variable. */ + JS_COPY (&f, JS_SP1); + function = &f; + + /* Reset the `this' to null. */ + JS_SP1->type = JS_NULL; + + if (function->type == JS_BUILTIN + && function->u.vbuiltin->info->global_method_proc) + { + JS_SAVE_REGS (); + (*function->u.vbuiltin->info->global_method_proc) ( + vm, + function->u.vbuiltin->info, + function->u.vbuiltin->instance_context, + &builtin_result, + JS_SP2); + + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + } + else if (function->type == JS_FUNC) + { + JS_SUBROUTINE_CALL (function->u.vfunction->implementation); + } + else + { + sprintf (buf, "illegal function object in jsr"); + ERROR (buf); + } + } + NEXT (); + +/* operand return (56) */ +op_return: + OPERAND (56); + if (fp->u.iptr == NULL) + /* Return from the global scope. */ + DONE (); + + /* STACKFRAME */ + + /* Check if the stack has been modified by min_args. */ + if (JS_ARGS_FIXP->u.args_fix.delta) + { + unsigned int delta = JS_ARGS_FIXP->u.args_fix.delta; + + /* + * Yes it was. Truncate it back to the state where it was + * before the call. + */ + + memmove (JS_SP1 + delta, JS_SP1, + (fp - JS_SP0 + JS_ARGS_FIXP->u.args_fix.argc) + * sizeof (JSNode)); + + sp += delta; + fp += delta; + } + + /* Set pc to the saved return address. */ +#if 0 + if (fp[-3].type != JS_IPTR) + ERROR ("can't find saved return address"); +#endif + pc = fp[-3].u.iptr; + + { + void *old_fp; + + /* Save old frame pointer. */ +#if 0 + if (fp->type != JS_IPTR) + ERROR ("can't find saved frame pointer"); +#endif + old_fp = fp->u.iptr; + + /* Put return value to its correct location. */ + JS_COPY (fp, JS_SP1); + + /* Restore sp. */ + sp = &fp[-1]; + + /* Restore frame pointer. */ + fp = old_fp; + } + NEXT (); + +/* operand typeof (57) */ +op_typeof: + OPERAND (57); + { + char *typeof_name = ""; /* Initialized to make compiler quiet. */ + + switch (JS_SP1->type) + { + case JS_UNDEFINED: + typeof_name = "undefined"; + break; + + case JS_NULL: + typeof_name = "object"; + break; + + case JS_BOOLEAN: + typeof_name = "boolean"; + break; + + case JS_INTEGER: + case JS_FLOAT: + case JS_NAN: + typeof_name = "number"; + break; + + case JS_STRING: + typeof_name = "string"; + break; + + case JS_ARRAY: + typeof_name = "#array"; + break; + + case JS_OBJECT: + typeof_name = "object"; + break; + + case JS_SYMBOL: + typeof_name = "#symbol"; + break; + + case JS_BUILTIN: + typeof_name = "#builtin"; + break; + + case JS_FUNC: + typeof_name = "function"; + break; + + case JS_IPTR: + typeof_name = "#iptr"; + break; + + case JS_ARGS_FIX: + typeof_name = "#argsfix"; + break; + } + + js_vm_make_static_string (vm, JS_SP1, typeof_name, strlen (typeof_name)); + JS_MAYBE_GC (); + } + NEXT (); + +/* operand new (58) */ +op_new: + OPERAND (58); + /* Check object. */ + if (JS_SP1->type == JS_BUILTIN && JS_SP1->u.vbuiltin->info->new_proc) + { + JS_SAVE_REGS (); + (*JS_SP1->u.vbuiltin->info->new_proc) (vm, JS_SP1->u.vbuiltin->info, + JS_SP2, JS_SP1); + + /* Push a dummy return value for the constructor. This is ignored. */ + JS_SP0->type = JS_UNDEFINED; + JS_PUSH (); + } + else if (JS_SP1->type == JS_FUNC) + { + JSObject *obj; + JSNode f; + JSNode prototype; + + /* The prototype is an object. */ + prototype.type = JS_OBJECT; + + /* Create the prototype for the function, if it is not defined. */ + if (JS_SP1->u.vfunction->prototype == NULL) + { + JS_SP1->u.vfunction->prototype = js_vm_object_new (vm); + + /* Set its __proto__ to point to Object's prototype. */ + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property (vm, JS_SP1->u.vfunction->prototype, + vm->syms.s___proto__, &prototype); + } + + /* Allocate a new object and set its prototype. */ + + obj = js_vm_object_new (vm); + + prototype.u.vobject = JS_SP1->u.vfunction->prototype; + js_vm_object_store_property (vm, obj, vm->syms.s___proto__, &prototype); + + /* + * Basicly we do a jsr to the function given in JS_SP1. But first, + * we must set `this' pointer to the correct value. See `jsr' for + * the details. + */ + JS_COPY (&f, JS_SP1); + + /* Replace func with the new object. */ + JS_SP1->type = JS_OBJECT; + JS_SP1->u.vobject = obj; + + JS_SUBROUTINE_CALL (f.u.vfunction->implementation); + } + /* The primitive language types. */ + else if (vm->prim[JS_SP1->type]) + { + JS_SAVE_REGS (); + (*vm->prim[JS_SP1->type]->new_proc) (vm, vm->prim[JS_SP1->type], JS_SP2, + JS_SP1); + JS_PUSH (); + } + else + ERROR ("illegal object for new"); + + JS_MAYBE_GC (); + NEXT (); + +/* operand delete_property (59) */ +op_delete_property: + OPERAND (59); + /* Fetch the property symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + /* + * XXX It should be possible to apply delete operand to builtin + * XXX objects. + */ + ERROR ("delete_property: JS_BUILTIN: not implemented yet"); + } + else if (JS_SP1->type == JS_OBJECT) + { + js_vm_object_delete_property (vm, JS_SP1->u.vobject, j); + } + else if (JS_SP1->type == JS_NULL) + { + /* Delete a property from an object in the with-chain. */ + /* WITHCHAIN */ + ERROR ("delete_property: not implemented yet for the with-chain objects"); + } + /* The primitive language types. */ + /* + * XXX Since we can't delete properties from builtins, we can't delete + * XXX them from the primitive language types. + */ + else + ERROR ("illegal object for delete_property"); + + /* The delete operand returns an undefined value. */ + JS_SP1->type = JS_UNDEFINED; + NEXT (); + +/* operand delete_array (60) */ +op_delete_array: + OPERAND (60); + if (JS_SP2->type == JS_BUILTIN) + { + ERROR ("delete_array: JS_BUILTIN: not implemented yet"); + } + else if (JS_SP2->type == JS_OBJECT) + { + js_vm_object_delete_array (vm, JS_SP2->u.vobject, JS_SP1); + JS_POP (); + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->type == JS_INTEGER) + { + if (0 <= JS_SP1->u.vinteger + && JS_SP1->u.vinteger < JS_SP2->u.varray->length) + JS_SP2->u.varray->data[JS_SP1->u.vinteger].type = JS_UNDEFINED; + JS_POP (); + } + else + ERROR ("illegal array index in delete_array"); + } + else + ERROR ("illegal object for delete_array"); + + /* The delete operand returns an undefined value. */ + JS_SP1->type = JS_UNDEFINED; + NEXT (); + +/* operand locals (61) */ +op_locals: + OPERAND (61); + READ_INT16 (i); + if (sp - i - JS_RESERVE_STACK_FOR_FUNCTION < vm->stack) + ERROR ("stack overflow"); + + for (; i > 0; i--) + { + JS_SP0->type = JS_UNDEFINED; + JS_PUSH (); + } + NEXT (); + +/* operand min_args (62) */ +op_min_args: + OPERAND (62); + READ_INT8 (i); + + if (JS_SP1->u.vinteger < i) + { + unsigned int delta = i - JS_SP1->u.vinteger; + unsigned int argc = JS_SP1->u.vinteger; + + memmove (JS_SP1 - delta, JS_SP1, (fp - JS_SP0 + argc) * sizeof (JSNode)); + sp -= delta; + fp -= delta; + + /* Fill up the fix_args slot. */ + JS_ARGS_FIXP->u.args_fix.argc = argc; + JS_ARGS_FIXP->u.args_fix.delta = delta; + + for (; argc < i; argc++) + JS_ARG (argc)->type = JS_UNDEFINED; + } + + JS_POP (); + NEXT (); + +/* operand load_nth_arg (63) */ +op_load_nth_arg: + OPERAND (63); + { + int index = JS_SP1->u.vinteger; + JS_COPY (JS_SP1, JS_ARG (index)); + } + NEXT (); + +/* operand with_push (64) */ +op_with_push: + OPERAND (64); + if (JS_SP1->type != JS_OBJECT && JS_SP1->type != JS_BUILTIN) + ERROR ("illegal object for with_push"); + + /* WITHCHAIN */ + + if (JS_WITHPTR->u.iptr == NULL) + { + JSNode *np; + JSUIntAlign *ip = js_vm_alloc (vm, + sizeof (JSUIntAlign) + + sizeof (JSNode)); + *ip = 1; + np = (JSNode *) ((unsigned char *) ip + sizeof (JSUIntAlign)); + + JS_COPY (np, JS_SP1); + JS_WITHPTR->u.iptr = ip; + } + else + { + JSNode *np; + JSUIntAlign *ip = JS_WITHPTR->u.iptr; + JSUIntAlign ui = *ip; + + ip = js_vm_realloc (vm, ip, + sizeof (JSUIntAlign) + + ((ui + 1) * sizeof (JSNode))); + (*ip)++; + np = (JSNode *) ((unsigned char *) ip + sizeof (JSUIntAlign)); + + JS_COPY (&np[ui], JS_SP1); + JS_WITHPTR->u.iptr = ip; + } + + JS_POP (); + NEXT (); + +/* operand with_pop (65) */ +op_with_pop: + OPERAND (65); + READ_INT8 (i); + + /* WITHCHAIN */ + + { + JSUIntAlign *ip = JS_WITHPTR->u.iptr; + + if (ip == NULL || *ip < i) + ERROR ("with stack underflow in with_pop"); + + *ip -= i; + } + NEXT (); + +/* operand try_push (66) */ +op_try_push: + OPERAND (66); + READ_INT32 (i); + + { + JSErrorHandlerFrame *frame = js_calloc (vm, 1, sizeof (*frame)); + + frame->next = vm->error_handler; + frame->sp = sp; + frame->fp = fp; + frame->pc = pc; + frame->pc_delta = i; + vm->error_handler = frame; + + if (setjmp (vm->error_handler->error_jmp)) + { + /* Ok, we caught an error. */ + + /* Restore our state. */ + sp = vm->error_handler->sp; + fp = vm->error_handler->fp; + pc = vm->error_handler->pc; + i = vm->error_handler->pc_delta; + + /* Push the thrown value to the stack. */ + JS_COPY (JS_SP0, &vm->error_handler->thrown); + JS_PUSH (); + + /* Remove this handler frame. */ + frame = vm->error_handler; + vm->error_handler = vm->error_handler->next; + js_free (frame); + + /* Do the jump to the catch block. */ + SETPC_RELATIVE (i); + } + } + NEXT (); + +/* operand try_pop (67) */ +op_try_pop: + OPERAND (67); + READ_INT8 (i); + + for (; i > 0; i--) + { + JSErrorHandlerFrame *frame = vm->error_handler; + + vm->error_handler = vm->error_handler->next; + js_free (frame); + } + NEXT (); + +/* operand throw (68) */ +op_throw: + OPERAND (68); + { + JSErrorHandlerFrame *f = vm->error_handler; + + if (f->sp == NULL) + { + JSNode cvt; + int len; + + /* + * We are jumping to the C-toplevel. Convert our thrown value + * to string and store it to the vm->error. + */ + js_vm_to_string (vm, JS_SP1, &cvt); + + len = cvt.u.vstring->len; + if (len + 1 > sizeof (vm->error)) + len = sizeof (vm->error) - 1; + + memcpy (vm->error, cvt.u.vstring->data, len); + vm->error[len] = '\0'; + } + else + JS_COPY (&f->thrown, JS_SP1); + + longjmp (f->error_jmp, 1); + + /* NOTREACHED (I hope). */ + + sprintf (buf, "VM: no valid error handler initialized%s", + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); + + abort (); + } + NEXT (); + +/* operand iffalse_b (69) */ +op_iffalse_b: + OPERAND (69); + READ_INT32 (i); + if (!JS_SP1->u.vboolean) + SETPC_RELATIVE (i); + JS_POP (); + NEXT (); + +/* operand iftrue_b (70) */ +op_iftrue_b: + OPERAND (70); + READ_INT32 (i); + if (JS_SP1->u.vboolean) + SETPC_RELATIVE (i); + JS_POP (); + NEXT (); + +/* operand add_1_i (71) */ +op_add_1_i: + OPERAND (71); + JS_SP1->u.vinteger++; + NEXT (); + +/* operand add_2_i (72) */ +op_add_2_i: + OPERAND (72); + JS_SP1->u.vinteger += 2; + NEXT (); + +/* operand load_global_w (73) */ +op_load_global_w: + OPERAND (73); + READ_INT32 (j); + { + int found = 0; + + /* Loop over the with chain. */ + /* WITHCHAIN */ + if (JS_WITHPTR->u.iptr) + { + JSUIntAlign *uip = JS_WITHPTR->u.iptr; + JSUIntAlign ui = *uip; + JSNode *wp = (JSNode *) ((unsigned char *) uip + + sizeof (JSUIntAlign)); + + for (i = 0; i < ui; i++) + { + JSNode *w = &wp[i]; + int result = JS_PROPERTY_UNKNOWN; + + if (w->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (w->u.vbuiltin->info->property_proc) + result = (*w->u.vbuiltin->info->property_proc) ( + vm, + w->u.vbuiltin->info, + w->u.vbuiltin->instance_context, + j, 0, &builtin_result); + } + else if (w->type == JS_OBJECT) + { + result = js_vm_object_load_property (vm, w->u.vobject, j, + &builtin_result); + } + else + ERROR ("corrupted with-chain in load_global"); + + if (result == JS_PROPERTY_FOUND) + { + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + found = 1; + break; + } + } + } + + if (!found) + { + /* Use the global value. */ + JS_COPY (JS_SP0, JS_GLOBAL (j)); + JS_PUSH (); + + if (vm->warn_undef && JS_SP1->type == JS_UNDEFINED) + { + sprintf (buf, "VM: warning: using undefined global `%s'%s", + js_vm_symname (vm, j), JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + } + } + NEXT (); + +/* operand jsr_w (74) */ +op_jsr_w: + OPERAND (74); + /* Read the subroutine symbol index. */ + READ_INT32 (j); + + { + int found = 0; + + /* Loop over the with-chain. */ + /* WITHCHAIN */ + if (JS_WITHPTR->u.iptr) + { + JSUIntAlign *uip = JS_WITHPTR->u.iptr; + JSUIntAlign ui = *uip; + JSNode *wp = (JSNode *) ((unsigned char *) uip + + sizeof (JSUIntAlign)); + + for (i = 0; i < ui; i++) + { + JSNode *w = &wp[i]; + int result = JS_PROPERTY_UNKNOWN; + + if (w->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (w->u.vbuiltin->info->method_proc) + result = (*w->u.vbuiltin->info->method_proc) ( + vm, + w->u.vbuiltin->info, + w->u.vbuiltin->instance_context, j, + &builtin_result, JS_SP2); + JS_MAYBE_GC (); + + if (result == JS_PROPERTY_FOUND) + { + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + } + } + else if (w->type == JS_OBJECT) + { + JSNode method; + + js_vm_object_load_property (vm, w->u.vobject, j, &method); + if (method.type == JS_FUNC) + { + result = JS_PROPERTY_FOUND; + + /* The object defines the method. Do a subroutine call. */ + + /* First: replace the null `this' with `w'. */ + JS_COPY (JS_SP1, w); + + /* Then, do the normal subroutine call. */ + JS_SUBROUTINE_CALL (method.u.vfunction->implementation); + } + } + else + ERROR ("corrupted with-chain in jsr_w"); + + if (result == JS_PROPERTY_FOUND) + { + found = 1; + break; + } + } + } + + if (!found) + { + JSNode f; + + /* Call the global method. */ + JS_COPY (&f, JS_SP1); + function = &f; + + /* Reset the `this' to null. */ + JS_SP1->type = JS_NULL; + + if (function->type == JS_BUILTIN + && function->u.vbuiltin->info->global_method_proc) + { + JS_SAVE_REGS (); + (*function->u.vbuiltin->info->global_method_proc) ( + vm, + function->u.vbuiltin->info, + function->u.vbuiltin->instance_context, + &builtin_result, + JS_SP2); + + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + } + else if (function->type == JS_FUNC) + { + JS_SUBROUTINE_CALL (function->u.vfunction->implementation); + } + else + { + sprintf (buf, "symbol `%s' is undefined as function", + js_vm_symname (vm, j)); + ERROR (buf); + } + } + } + NEXT (); + diff --git a/reactos/lib/kjs/src/eswitch.h b/reactos/lib/kjs/src/eswitch.h new file mode 100644 index 00000000000..c974acabf9f --- /dev/null +++ b/reactos/lib/kjs/src/eswitch.h @@ -0,0 +1,2164 @@ +/* operand halt (0) */ +case 0: + sprintf (buf, "VM: halt%s", JS_HOST_LINE_BREAK); + + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); + + while (1) + sleep (5); + break; + +/* operand done (1) */ +case 1: + DONE (); + break; + +/* operand nop (2) */ +case 2: + /* Nothing here! */ + break; + +/* operand dup (3) */ +case 3: + JS_COPY (JS_SP0, JS_SP1); + JS_PUSH (); + break; + +/* operand pop (4) */ +case 4: + JS_POP (); + break; + +/* operand pop_n (5) */ +case 5: + READ_INT8 (i); + JS_POP_N (i); + break; + +/* operand apop (6) */ +case 6: + READ_INT8 (i); + JS_COPY (JS_SP (i + 1), JS_SP1); + JS_POP_N (i); + break; + +/* operand swap (7) */ +case 7: + JS_COPY (JS_SP0, JS_SP2); + JS_COPY (JS_SP2, JS_SP1); + JS_COPY (JS_SP1, JS_SP0); + break; + +/* operand roll (8) */ +case 8: + READ_INT8 (i8); + + if (i8 > 1) + { + int j; + + for (j = 0; j < i8; j++) + JS_COPY (JS_SP (j), JS_SP (j + 1)); + + JS_COPY (JS_SP (i8), JS_SP0); + } + else if (i8 < -1) + { + i8 = -i8; + + JS_COPY (JS_SP0, JS_SP (i8)); + for (; i8 > 0; i8--) + JS_COPY (JS_SP (i8), JS_SP (i8 - 1)); + } + break; + +/* operand const (9) */ +case 9: + READ_INT32 (i); + JS_COPY (JS_SP0, JS_CONST (i)); + JS_PUSH (); + break; + +/* operand const_null (10) */ +case 10: + JS_SP0->type = JS_NULL; + JS_PUSH (); + break; + +/* operand const_true (11) */ +case 11: + JS_SP0->type = JS_BOOLEAN; + JS_SP0->u.vboolean = 1; + JS_PUSH (); + break; + +/* operand const_false (12) */ +case 12: + JS_SP0->type = JS_BOOLEAN; + JS_SP0->u.vboolean = 0; + JS_PUSH (); + break; + +/* operand const_undefined (13) */ +case 13: + JS_SP0->type = JS_UNDEFINED; + JS_PUSH (); + break; + +/* operand const_i0 (14) */ +case 14: + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 0; + JS_PUSH (); + break; + +/* operand const_i1 (15) */ +case 15: + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 1; + JS_PUSH (); + break; + +/* operand const_i2 (16) */ +case 16: + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 2; + JS_PUSH (); + break; + +/* operand const_i3 (17) */ +case 17: + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 3; + JS_PUSH (); + break; + +/* operand const_i (18) */ +case 18: + READ_INT32 (i); + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = i; + JS_PUSH (); + break; + +/* operand load_global (19) */ +case 19: + READ_INT32 (j); + + /* Use the global value only. */ + JS_COPY (JS_SP0, JS_GLOBAL (j)); + JS_PUSH (); + + if (vm->warn_undef && JS_SP1->type == JS_UNDEFINED) + { + sprintf (buf, "VM: warning: using undefined global `%s'%s", + js_vm_symname (vm, j), JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + break; + +/* operand store_global (20) */ +case 20: + READ_INT32 (i); + + /* Operand store_global do not check the with-chain. */ + /* WITHCHAIN */ + + /* Set the global value. */ + JS_COPY (JS_GLOBAL (i), JS_SP1); + JS_POP (); + break; + +/* operand load_arg (21) */ +case 21: + READ_INT8 (i); + JS_COPY (JS_SP0, JS_ARG (i)); + JS_PUSH (); + break; + +/* operand store_arg (22) */ +case 22: + READ_INT8 (i); + JS_COPY (JS_ARG (i), JS_SP1); + JS_POP (); + break; + +/* operand load_local (23) */ +case 23: + READ_INT16 (i); + JS_COPY (JS_SP0, JS_LOCAL (i)); + JS_PUSH (); + break; + +/* operand store_local (24) */ +case 24: + READ_INT16 (i); + JS_COPY (JS_LOCAL (i), JS_SP1); + JS_POP (); + break; + +/* operand load_property (25) */ +case 25: + /* Fetch the property symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (JS_SP1->u.vbuiltin->info->property_proc) + { + if ((*JS_SP1->u.vbuiltin->info->property_proc) ( + vm, + JS_SP1->u.vbuiltin->info, + JS_SP1->u.vbuiltin->instance_context, + j, 0, &builtin_result) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Looking up the prototype. */ + + builtin_result.type = JS_OBJECT; + if (JS_SP1->u.vbuiltin->prototype) + /* This is an instance. */ + builtin_result.u.vobject = JS_SP1->u.vbuiltin->prototype; + else + /* This is a class. */ + builtin_result.u.vobject + = JS_SP1->u.vbuiltin->info->prototype; + } + else + { + /* Looking up stuffs from the prototype. */ + + if (JS_SP1->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_load_property (vm, + JS_SP1->u.vbuiltin->prototype, + j, &builtin_result); + else + /* A class. */ + js_vm_object_load_property ( + vm, + JS_SP1->u.vbuiltin->info->prototype, + j, &builtin_result); + } + } + JS_COPY (JS_SP1, &builtin_result); + } + else + ERROR ("illegal builtin object for load_property"); + } + else if (JS_SP1->type == JS_OBJECT) + { + js_vm_object_load_property (vm, JS_SP1->u.vobject, j, JS_SP1); + } + else if (vm->prim[JS_SP1->type]) + { + /* The primitive language types. */ + JS_SAVE_REGS (); + if ((*vm->prim[JS_SP1->type]->property_proc) (vm, vm->prim[JS_SP1->type], + JS_SP1, j, 0, + &builtin_result) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Looking up the prototype. */ + switch (JS_SP1->type) + { + case JS_STRING: + if (JS_SP1->u.vstring->prototype) + { + builtin_result.type = JS_OBJECT; + builtin_result.u.vobject = JS_SP1->u.vstring->prototype; + } + else + /* No prototype yet. */ + builtin_result.type = JS_NULL; + break; + + case JS_ARRAY: + if (JS_SP1->u.varray->prototype) + { + builtin_result.type = JS_OBJECT; + builtin_result.u.vobject = JS_SP1->u.varray->prototype; + } + else + /* No prototype yet. */ + builtin_result.type = JS_NULL; + break; + + case JS_FUNC: + if (JS_SP1->u.vfunction->prototype) + { + builtin_result.type = JS_OBJECT; + builtin_result.u.vobject + = JS_SP1->u.vfunction->prototype; + } + else + /* No prototype yet. */ + builtin_result.type = JS_NULL; + break; + + default: + /* The rest do not have prototype. */ + builtin_result.type = JS_NULL; + break; + } + } + else + { + /* Looking up stuffs from the prototype. */ + switch (JS_SP1->type) + { + case JS_STRING: + if (JS_SP1->u.vstring->prototype) + js_vm_object_load_property (vm, + JS_SP1->u.vstring->prototype, + j, &builtin_result); + else + /* Take it from the class' prototype */ + goto _op_load_property_try_proto; + break; + + case JS_ARRAY: + if (JS_SP1->u.varray->prototype) + js_vm_object_load_property (vm, + JS_SP1->u.varray->prototype, + j, &builtin_result); + else + /* Take it from the class' prototype */ + goto _op_load_property_try_proto; + break; + + case JS_FUNC: + if (JS_SP1->u.vfunction->prototype) + js_vm_object_load_property (vm, + JS_SP1->u.vfunction->prototype, + j, &builtin_result); + else + /* Take it from the class' prototype */ + goto _op_load_property_try_proto; + break; + + default: + /* + * The rest do not have instance prototypes; use the + * class prototypes. + */ + _op_load_property_try_proto: + js_vm_object_load_property ( + vm, + vm->prim[JS_SP1->type]->prototype, j, + &builtin_result); + break; + } + } + } + + JS_COPY (JS_SP1, &builtin_result); + } + else + ERROR ("illegal object for load_property"); + break; + +/* operand store_property (26) */ +case 26: + /* Fetch the property symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (JS_SP1->u.vbuiltin->info->property_proc) + { + if ((*JS_SP1->u.vbuiltin->info->property_proc) ( + vm, + JS_SP1->u.vbuiltin->info, + JS_SP1->u.vbuiltin->instance_context, + j, 1, JS_SP2) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Setting the prototype. */ + if (JS_SP2->type != JS_OBJECT) + ERROR ("illegal value for set_property"); + + if (JS_SP1->u.vbuiltin->prototype) + /* Setting the instance's prototype. */ + JS_SP1->u.vbuiltin->prototype = JS_SP2->u.vobject; + else + /* Setting the class' prototype. */ + JS_SP1->u.vbuiltin->info->prototype = JS_SP2->u.vobject; + } + else + { + /* Setting stuff to the prototype. */ + if (JS_SP1->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_store_property (vm, + JS_SP1->u.vbuiltin->prototype, + j, JS_SP2); + else + /* A class. */ + js_vm_object_store_property ( + vm, + JS_SP1->u.vbuiltin->info->prototype, + j, JS_SP2); + } + } + } + else + ERROR ("illegal builtin object for store_property"); + + JS_POP (); + JS_POP (); + } + else if (JS_SP1->type == JS_OBJECT) + { + js_vm_object_store_property (vm, JS_SP1->u.vobject, j, JS_SP2); + JS_POP (); + JS_POP (); + } + else if (vm->prim[JS_SP1->type]) + { + /* The primitive language types. */ + JS_SAVE_REGS (); + if ((*vm->prim[JS_SP1->type]->property_proc) (vm, vm->prim[JS_SP1->type], + JS_SP1, j, 1, JS_SP2) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Setting the prototype. */ + if (JS_SP2->type != JS_OBJECT) + ERROR ("illegal value for set_property"); + + switch (JS_SP1->type) + { + case JS_STRING: + JS_SP1->u.vstring->prototype = JS_SP2->u.vobject; + break; + + case JS_ARRAY: + JS_SP1->u.varray->prototype = JS_SP2->u.vobject; + break; + + case JS_FUNC: + JS_SP1->u.vfunction->prototype = JS_SP2->u.vobject; + break; + + default: + ERROR ("illegal object for set_property"); + break; + } + } + else + { + JSNode prototype; + + /* Setting to the prototype. We create them on demand. */ + switch (JS_SP1->type) + { + case JS_STRING: + if (JS_SP1->u.vstring->prototype == NULL) + { + prototype.type = JS_OBJECT; + + /* Create the prototype and set its __proto__. */ + JS_SP1->u.vstring->prototype = js_vm_object_new (vm); + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property ( + vm, + JS_SP1->u.vstring->prototype, + vm->syms.s___proto__, + &prototype); + } + js_vm_object_store_property (vm, + JS_SP1->u.vstring->prototype, + j, JS_SP2); + break; + + case JS_ARRAY: + if (JS_SP1->u.varray->prototype == NULL) + { + prototype.type = JS_OBJECT; + + /* Create the prototype and set its __proto__. */ + JS_SP1->u.varray->prototype = js_vm_object_new (vm); + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property ( + vm, + JS_SP1->u.varray->prototype, + vm->syms.s___proto__, + &prototype); + } + js_vm_object_store_property (vm, + JS_SP1->u.varray->prototype, + j, JS_SP2); + break; + + case JS_FUNC: + if (JS_SP1->u.vfunction->prototype == NULL) + { + prototype.type = JS_OBJECT; + + /* Create the prototype and set its __proto__. */ + JS_SP1->u.vfunction->prototype = js_vm_object_new (vm); + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property ( + vm, + JS_SP1->u.vfunction->prototype, + vm->syms.s___proto__, + &prototype); + } + js_vm_object_store_property (vm, + JS_SP1->u.vfunction->prototype, + j, JS_SP2); + break; + + default: + ERROR ("illegal object for set_property"); + break; + } + } + } + JS_POP (); + JS_POP (); + } + else + ERROR ("illegal object for store_property"); + + JS_MAYBE_GC (); + break; + +/* operand load_array (27) */ +case 27: + if (JS_SP2->type == JS_BUILTIN) + { + if (JS_SP1->type == JS_INTEGER) + { + ERROR ("integer indexes not implemented yet for BUILTIN in load_array"); + } + else if (JS_SP1->type == JS_STRING) + { + /* Intern the string. */ + j = js_vm_intern_with_len (vm, JS_SP1->u.vstring->data, + JS_SP1->u.vstring->len); + + /* The code below must be in sync with operand `load_property'. */ + JS_SAVE_REGS (); + + if (JS_SP2->u.vbuiltin->info->property_proc) + { + if ((*JS_SP2->u.vbuiltin->info->property_proc) ( + vm, + JS_SP2->u.vbuiltin->info, + JS_SP2->u.vbuiltin->instance_context, + j, 0, &builtin_result) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Looking up the prototype. */ + + builtin_result.type = JS_OBJECT; + if (JS_SP2->u.vbuiltin->prototype) + /* This is an instance. */ + builtin_result.u.vobject + = JS_SP2->u.vbuiltin->prototype; + else + /* This is a class. */ + builtin_result.u.vobject + = JS_SP2->u.vbuiltin->info->prototype; + } + else + { + /* Looking up stuffs from the prototype. */ + + if (JS_SP2->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_load_property ( + vm, + JS_SP2->u.vbuiltin->prototype, + j, &builtin_result); + else + /* A class. */ + js_vm_object_load_property ( + vm, + JS_SP2->u.vbuiltin->info->prototype, + j, &builtin_result); + } + } + JS_COPY (JS_SP2, &builtin_result); + JS_POP (); + } + else + ERROR ("illegal builtin object for load_array"); + } + else + { + sprintf (buf, "illegal array index in load_array (%d)", + JS_SP1->type); + ERROR (buf); + } + } + else if (JS_SP2->type == JS_OBJECT) + { + js_vm_object_load_array (vm, JS_SP2->u.vobject, JS_SP1, JS_SP2); + JS_POP (); + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->type == JS_INTEGER) + { + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.varray->length) + JS_SP2->type = JS_UNDEFINED; + else + { + JSNode *n = &JS_SP2->u.varray->data[JS_SP1->u.vinteger]; + JS_COPY (JS_SP2, n); + } + JS_POP (); + } + else + { + sprintf (buf, "illegal array index in load_array (%d)", + JS_SP1->type); + ERROR (buf); + } + } + else if (JS_SP2->type == JS_STRING) + { + if (JS_SP1->type == JS_INTEGER) + { + int ch; + + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.vstring->len) + ERROR ("string index out of range in load_array"); + + ch = JS_SP2->u.vstring->data[JS_SP1->u.vinteger]; + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = ch; + + JS_POP (); + } + else + ERROR ("illegal string index in load_array"); + } + else + ERROR ("illegal object for load_array"); + break; + +/* operand store_array (28) */ +case 28: + if (JS_SP2->type == JS_BUILTIN) + { + if (JS_SP1->type == JS_INTEGER) + { + ERROR ("integer index not implemented yet for BUILTIN in store_array"); + } + else if (JS_SP1->type == JS_STRING) + { + /* Intern the string. */ + j = js_vm_intern_with_len (vm, JS_SP1->u.vstring->data, + JS_SP1->u.vstring->len); + + /* The code below msut be in sync with operand `store_property'. */ + JS_SAVE_REGS (); + if (JS_SP2->u.vbuiltin->info->property_proc) + { + if ((*JS_SP2->u.vbuiltin->info->property_proc) ( + vm, + JS_SP2->u.vbuiltin->info, + JS_SP2->u.vbuiltin->instance_context, + j, 1, JS_SP (3)) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Setting the prototype. */ + if (JS_SP (3)->type != JS_OBJECT) + ERROR ("illegal value for prototype"); + + if (JS_SP2->u.vbuiltin->prototype) + /* Setting the instance's prototype. */ + JS_SP2->u.vbuiltin->prototype = JS_SP (3)->u.vobject; + else + /* Setting the class' prototype. */ + JS_SP2->u.vbuiltin->info->prototype + = JS_SP (3)->u.vobject; + } + else + { + /* Setting stuff to the prototype. */ + if (JS_SP2->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_store_property ( + vm, + JS_SP2->u.vbuiltin->prototype, + j, JS_SP (3)); + else + /* A class. */ + js_vm_object_store_property ( + vm, + JS_SP2->u.vbuiltin->info->prototype, + j, JS_SP (3)); + } + } + } + else + ERROR ("illegal builtin object for store_array"); + + JS_POP_N (3); + } + else + ERROR ("illegal array index in store_array"); + } + else if (JS_SP2->type == JS_OBJECT) + { + js_vm_object_store_array (vm, JS_SP2->u.vobject, JS_SP1, JS_SP (3)); + JS_POP_N (3); + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->type == JS_INTEGER) + { + if (JS_SP1->u.vinteger < 0) + ERROR ("negative array index in store_array"); + if (JS_SP1->u.vinteger >= JS_SP2->u.varray->length) + js_vm_expand_array (vm, JS_SP2, JS_SP1->u.vinteger + 1); + + JS_COPY (&JS_SP2->u.varray->data[JS_SP1->u.vinteger], JS_SP (3)); + JS_POP_N (3); + } + else + ERROR ("illegal array index in store_array"); + } + else if (JS_SP2->type == JS_STRING) + { + if (JS_SP1->type == JS_INTEGER) + { + if (JS_SP2->u.vstring->staticp) + ERROR ("static string in store_array"); + + if (JS_SP1->u.vinteger < 0) + ERROR ("negative string index in store_array"); + + if (JS_SP (3)->type != JS_INTEGER) + ERROR ("non-integer value to store into string in store_array"); + + if (JS_SP1->u.vinteger >= JS_SP2->u.vstring->len) + { + /* Expand the string. */ + JS_SP2->u.vstring->data = js_vm_realloc (vm, + JS_SP2->u.vstring->data, + JS_SP1->u.vinteger + 1); + /* Fill the gap with ' '. */ + for (; JS_SP2->u.vstring->len <= JS_SP1->u.vinteger;) + JS_SP2->u.vstring->data[JS_SP2->u.vstring->len++] = ' '; + } + + JS_SP2->u.vstring->data[JS_SP1->u.vinteger] + = (unsigned char) JS_SP (3)->u.vinteger; + JS_POP_N (3); + } + else + ERROR ("illegal string index in store_array"); + } + else + ERROR ("illegal object for store_array"); + + JS_MAYBE_GC (); + break; + +/* operand nth (29) */ +case 29: + if (JS_SP2->type == JS_STRING) + { + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.vstring->len) + { + JS_SP2->type = JS_UNDEFINED; + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 0; + } + else + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = JS_SP2->u.vstring->data[JS_SP1->u.vinteger]; + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 1; + } + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.varray->length) + { + JS_SP2->type = JS_UNDEFINED; + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 0; + } + else + { + JSNode *n = &JS_SP2->u.varray->data[JS_SP1->u.vinteger]; + JS_COPY (JS_SP2, n); + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 1; + } + } + else if (JS_SP2->type == JS_OBJECT) + { + i = js_vm_object_nth (vm, JS_SP2->u.vobject, JS_SP1->u.vinteger, JS_SP2); + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = i; + } + else + ERROR ("illegal object for nth"); + break; + +/* operand cmp_eq (30) */ +case 30: + JS_OPERAND_CMP_EQ (==, 1); + break; + +/* operand cmp_ne (31) */ +case 31: + JS_OPERAND_CMP_EQ (!=, 0); + break; + +/* operand cmp_lt (32) */ +case 32: + JS_OPERAND_CMP_REL (<); + break; + +/* operand cmp_gt (33) */ +case 33: + JS_OPERAND_CMP_REL (>); + break; + +/* operand cmp_le (34) */ +case 34: + JS_OPERAND_CMP_REL (<=); + break; + +/* operand cmp_ge (35) */ +case 35: + JS_OPERAND_CMP_REL (>=); + break; + +/* operand cmp_seq (36) */ +case 36: + JS_OPERAND_CMP_SEQ (==, 1); + break; + +/* operand cmp_sne (37) */ +case 37: + JS_OPERAND_CMP_SEQ (!=, 0); + break; + +/* operand sub (38) */ +case 38: + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger -= JS_SP1->u.vinteger; + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (l->type == JS_INTEGER) + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger - r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = (double) l->u.vinteger - r->u.vfloat; + } + } + else + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat - (double) r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat - r->u.vfloat; + } + } + } + + JS_POP (); + break; + +/* operand add (39) */ +case 39: + if (JS_SP2->type == JS_STRING || JS_SP1->type == JS_STRING) + { + unsigned char *d2, *d1, *ndata; + unsigned int d2_len, d1_len, nlen; + JSNode cvt; + + if (JS_SP2->type == JS_STRING) + { + d2 = JS_SP2->u.vstring->data; + d2_len = JS_SP2->u.vstring->len; + } + else + { + js_vm_to_string (vm, JS_SP2, &cvt); + d2 = cvt.u.vstring->data; + d2_len = cvt.u.vstring->len; + } + if (JS_SP1->type == JS_STRING) + { + d1 = JS_SP1->u.vstring->data; + d1_len = JS_SP1->u.vstring->len; + } + else + { + js_vm_to_string (vm, JS_SP1, &cvt); + d1 = cvt.u.vstring->data; + d1_len = cvt.u.vstring->len; + } + + nlen = d2_len + d1_len; + ndata = js_vm_alloc (vm, nlen); + memcpy (ndata, d2, d2_len); + memcpy (ndata + d2_len, d1, d1_len); + + js_vm_make_static_string (vm, JS_SP2, ndata, nlen); + JS_SP2->u.vstring->staticp = 0; + JS_POP (); + JS_MAYBE_GC (); + } + else if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger += JS_SP1->u.vinteger; + JS_POP (); + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (l->type == JS_INTEGER) + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger + r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = (double) l->u.vinteger + r->u.vfloat; + } + } + else + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat + (double) r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat + r->u.vfloat; + } + } + + JS_POP (); + } + break; + +/* operand mul (40) */ +case 40: + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger *= JS_SP1->u.vinteger; + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (l->type == JS_INTEGER) + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger * r->u.vinteger; + } + else + { + if (l->u.vinteger == 0 + && (JS_IS_POSITIVE_INFINITY (r) + || JS_IS_NEGATIVE_INFINITY (r))) + JS_SP2->type = JS_NAN; + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = (double) l->u.vinteger * r->u.vfloat; + } + } + } + else + { + if ((JS_IS_POSITIVE_INFINITY (l) || JS_IS_NEGATIVE_INFINITY (l)) + && ((r->type == JS_INTEGER && r->u.vinteger == 0) + || (r->type == JS_FLOAT && r->u.vfloat == 0.0))) + JS_SP2->type = JS_NAN; + else + { + JS_SP2->type = JS_FLOAT; + + if (r->type == JS_INTEGER) + JS_SP2->u.vfloat = l->u.vfloat * (double) r->u.vinteger; + else + JS_SP2->u.vfloat = l->u.vfloat * r->u.vfloat; + } + } + } + + JS_POP (); + break; + +/* operand div (41) */ +case 41: + { + int nan = 0; + double l, r; + int l_inf = 0; + int r_inf = 0; + JSNode *n; + JSNode cvt; + + /* Convert divident to float. */ + if (JS_IS_NUMBER (JS_SP2)) + n = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &cvt); + n = &cvt; + } + + switch (n->type) + { + case JS_INTEGER: + l = (double) n->u.vinteger; + break; + + case JS_FLOAT: + l = n->u.vfloat; + if (JS_IS_POSITIVE_INFINITY (n) || JS_IS_NEGATIVE_INFINITY (n)) + l_inf = 1; + break; + + case JS_NAN: + default: + nan = 1; + break; + } + + /* Convert divisor to float. */ + if (JS_IS_NUMBER (JS_SP1)) + n = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP2, &cvt); + n = &cvt; + } + + switch (n->type) + { + case JS_INTEGER: + r = (double) n->u.vinteger; + break; + + case JS_FLOAT: + r = n->u.vfloat; + if (JS_IS_POSITIVE_INFINITY (n) || JS_IS_NEGATIVE_INFINITY (n)) + r_inf = 1; + break; + + case JS_NAN: + default: + nan = 1; + break; + } + + /* Do the division. */ + JS_POP (); + if (nan || (l_inf && r_inf)) + JS_SP1->type = JS_NAN; + else + { + if (l_inf && r == 0.0) + { + /* is already an infinity. */ + JS_SP1->type = JS_FLOAT; + JS_SP1->u.vfloat = l; + } + else if (l == 0.0 && r == 0.0) + JS_SP1->type = JS_NAN; + else + { + JS_SP1->type = JS_FLOAT; + JS_SP1->u.vfloat = l / r; + } + } + } + break; + +/* operand mod (42) */ +case 42: + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + if (JS_SP1->u.vinteger == 0) + JS_SP2->type = JS_NAN; + else + JS_SP2->u.vinteger %= JS_SP1->u.vinteger; + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (JS_IS_POSITIVE_INFINITY (l) + || JS_IS_NEGATIVE_INFINITY (l) + || ((r->type == JS_INTEGER && r->u.vinteger == 0) + || (r->type == JS_FLOAT && r->u.vfloat == 0.0))) + JS_SP2->type = JS_NAN; + else if (JS_IS_POSITIVE_INFINITY (r) + || JS_IS_NEGATIVE_INFINITY (r)) + JS_COPY (JS_SP2, l); + else if ((l->type == JS_INTEGER && l->u.vinteger == 0) + || (l->type == JS_FLOAT && l->u.vfloat == 0.0)) + JS_COPY (JS_SP2, l); + else + { + if (l->type == JS_INTEGER && r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger % r->u.vinteger; + } + else + { + double ld, rd; + int full; + + if (l->type == JS_INTEGER) + ld = (double) l->u.vinteger; + else + ld = l->u.vfloat; + + if (r->type == JS_INTEGER) + rd = (double) r->u.vinteger; + else + rd = r->u.vfloat; + + full = ld / rd; + + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = ld - (full * rd); + } + } + } + + JS_POP (); + break; + +/* operand neg (43) */ +case 43: + if (JS_SP1->type == JS_INTEGER) + JS_SP1->u.vinteger = -JS_SP1->u.vinteger; + else if (JS_SP1->type == JS_FLOAT) + JS_SP1->u.vfloat = -JS_SP1->u.vfloat; + else if (JS_SP1->type == JS_NAN) + ; + else + { + JSNode cvt; + + js_vm_to_number (vm, JS_SP1, &cvt); + + JS_SP1->type = cvt.type; + switch (cvt.type) + { + case JS_INTEGER: + JS_SP1->u.vinteger = -cvt.u.vinteger; + break; + + case JS_FLOAT: + JS_SP1->u.vfloat = -cvt.u.vfloat; + break; + + case JS_NAN: + default: + /* Nothing here. */ + break; + } + } + break; + +/* operand and (44) */ +case 44: + JS_OPERAND_BINARY (&); + break; + +/* operand not (45) */ +case 45: + JS_SP1->u.vboolean = JS_IS_FALSE (JS_SP1); + JS_SP1->type = JS_BOOLEAN; + break; + +/* operand or (46) */ +case 46: + JS_OPERAND_BINARY (|); + break; + +/* operand xor (47) */ +case 47: + JS_OPERAND_BINARY (^); + break; + +/* operand shift_left (48) */ +case 48: + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger = ((JSInt32) JS_SP2->u.vinteger + << (JSUInt32) JS_SP1->u.vinteger); + JS_POP (); + } + else + { + JSInt32 l; + JSUInt32 r; + + l = js_vm_to_int32 (vm, JS_SP2); + r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1); + + JS_SP2->u.vinteger = l << r; + JS_SP2->type = JS_INTEGER; + JS_POP (); + } + break; + +/* operand shift_right (49) */ +case 49: + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger = ((JSInt32) JS_SP2->u.vinteger + >> (JSUInt32) JS_SP1->u.vinteger); + JS_POP (); + } + else + { + JSInt32 l; + JSUInt32 r; + + l = js_vm_to_int32 (vm, JS_SP2); + r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1); + + JS_SP2->u.vinteger = l >> r; + JS_SP2->type = JS_INTEGER; + JS_POP (); + } + break; + +/* operand shift_rright (50) */ +case 50: + { + JSInt32 l; + JSUInt32 r; + + l = js_vm_to_int32 (vm, JS_SP2); + r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1); + + if (r > 0) + JS_SP2->u.vinteger = (l & 0x7fffffff) >> r; + else + JS_SP2->u.vinteger = l; + + JS_SP2->type = JS_INTEGER; + JS_POP (); + } + break; + +/* operand iffalse (51) */ +case 51: + READ_INT32 (i); + if (JS_IS_FALSE (JS_SP1)) + SETPC_RELATIVE (i); + JS_POP (); + break; + +/* operand iftrue (52) */ +case 52: + READ_INT32 (i); + if (JS_IS_TRUE (JS_SP1)) + SETPC_RELATIVE (i); + JS_POP (); + break; + +/* operand call_method (53) */ +case 53: + /* Fetch the method symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (JS_SP1->u.vbuiltin->info->method_proc) + { + if ((*JS_SP1->u.vbuiltin->info->method_proc) ( + vm, + JS_SP1->u.vbuiltin->info, + JS_SP1->u.vbuiltin->instance_context, j, + &builtin_result, JS_SP2) + == JS_PROPERTY_UNKNOWN) + ERROR ("call_method: unknown method"); + } + else + ERROR ("illegal builtin object for call_method"); + + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + JS_MAYBE_GC (); + } + else if (JS_SP1->type == JS_OBJECT) + { + JSNode method; + + if (js_vm_object_load_property (vm, JS_SP1->u.vobject, j, &method) + == JS_PROPERTY_FOUND) + { + /* The property has been defined in the object. */ + + if (method.type != JS_FUNC) + ERROR ("call_method: unknown method"); + + /* And once again. We must do a subroutine call here. */ + JS_SUBROUTINE_CALL (method.u.vfunction->implementation); + } + else + /* Let our prototype handle this. */ + goto _op_call_method_try_proto; + } + else if (vm->prim[JS_SP1->type]) + { + /* The primitive language types. */ + _op_call_method_try_proto: + JS_SAVE_REGS (); + if ((*vm->prim[JS_SP1->type]->method_proc) (vm, vm->prim[JS_SP1->type], + JS_SP1, j, &builtin_result, + JS_SP2) + == JS_PROPERTY_UNKNOWN) + { + JSNode method; + int result = JS_PROPERTY_UNKNOWN; + + /* Let's see if we can find it from the prototype. */ + if (JS_SP1->type == JS_STRING && JS_SP1->u.vstring->prototype) + result = js_vm_object_load_property (vm, + JS_SP1->u.vstring->prototype, + j, &method); + else if (JS_SP1->type == JS_ARRAY && JS_SP1->u.varray->prototype) + result = js_vm_object_load_property (vm, + JS_SP1->u.varray->prototype, + j, &method); + else if (JS_SP1->type == JS_FUNC && JS_SP1->u.vfunction->prototype) + result + = js_vm_object_load_property (vm, JS_SP1->u.vfunction->prototype, + j, &method); + + if (result == JS_PROPERTY_UNKNOWN || method.type != JS_FUNC) + ERROR ("call_method: unknown method"); + + /* Do the subroutine call. */ + JS_SUBROUTINE_CALL (method.u.vfunction->implementation); + } + else + { + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + JS_MAYBE_GC (); + } + } + else + ERROR ("illegal object for call_method"); + break; + +/* operand jmp (54) */ +case 54: + READ_INT32 (i); + SETPC_RELATIVE (i); + break; + +/* operand jsr (55) */ +case 55: + /* Call the global method. */ + { + JSNode f; + + /* Fetch the function to our local variable. */ + JS_COPY (&f, JS_SP1); + function = &f; + + /* Reset the `this' to null. */ + JS_SP1->type = JS_NULL; + + if (function->type == JS_BUILTIN + && function->u.vbuiltin->info->global_method_proc) + { + JS_SAVE_REGS (); + (*function->u.vbuiltin->info->global_method_proc) ( + vm, + function->u.vbuiltin->info, + function->u.vbuiltin->instance_context, + &builtin_result, + JS_SP2); + + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + } + else if (function->type == JS_FUNC) + { + JS_SUBROUTINE_CALL (function->u.vfunction->implementation); + } + else + { + sprintf (buf, "illegal function object in jsr"); + ERROR (buf); + } + } + break; + +/* operand return (56) */ +case 56: + if (fp->u.iptr == NULL) + /* Return from the global scope. */ + DONE (); + + /* STACKFRAME */ + + /* Check if the stack has been modified by min_args. */ + if (JS_ARGS_FIXP->u.args_fix.delta) + { + unsigned int delta = JS_ARGS_FIXP->u.args_fix.delta; + + /* + * Yes it was. Truncate it back to the state where it was + * before the call. + */ + + memmove (JS_SP1 + delta, JS_SP1, + (fp - JS_SP0 + JS_ARGS_FIXP->u.args_fix.argc) + * sizeof (JSNode)); + + sp += delta; + fp += delta; + } + + /* Set pc to the saved return address. */ +#if 0 + if (fp[-3].type != JS_IPTR) + ERROR ("can't find saved return address"); +#endif + pc = fp[-3].u.iptr; + + { + void *old_fp; + + /* Save old frame pointer. */ +#if 0 + if (fp->type != JS_IPTR) + ERROR ("can't find saved frame pointer"); +#endif + old_fp = fp->u.iptr; + + /* Put return value to its correct location. */ + JS_COPY (fp, JS_SP1); + + /* Restore sp. */ + sp = &fp[-1]; + + /* Restore frame pointer. */ + fp = old_fp; + } + break; + +/* operand typeof (57) */ +case 57: + { + char *typeof_name = ""; /* Initialized to make compiler quiet. */ + + switch (JS_SP1->type) + { + case JS_UNDEFINED: + typeof_name = "undefined"; + break; + + case JS_NULL: + typeof_name = "object"; + break; + + case JS_BOOLEAN: + typeof_name = "boolean"; + break; + + case JS_INTEGER: + case JS_FLOAT: + case JS_NAN: + typeof_name = "number"; + break; + + case JS_STRING: + typeof_name = "string"; + break; + + case JS_ARRAY: + typeof_name = "#array"; + break; + + case JS_OBJECT: + typeof_name = "object"; + break; + + case JS_SYMBOL: + typeof_name = "#symbol"; + break; + + case JS_BUILTIN: + typeof_name = "#builtin"; + break; + + case JS_FUNC: + typeof_name = "function"; + break; + + case JS_IPTR: + typeof_name = "#iptr"; + break; + + case JS_ARGS_FIX: + typeof_name = "#argsfix"; + break; + } + + js_vm_make_static_string (vm, JS_SP1, typeof_name, strlen (typeof_name)); + JS_MAYBE_GC (); + } + break; + +/* operand new (58) */ +case 58: + /* Check object. */ + if (JS_SP1->type == JS_BUILTIN && JS_SP1->u.vbuiltin->info->new_proc) + { + JS_SAVE_REGS (); + (*JS_SP1->u.vbuiltin->info->new_proc) (vm, JS_SP1->u.vbuiltin->info, + JS_SP2, JS_SP1); + + /* Push a dummy return value for the constructor. This is ignored. */ + JS_SP0->type = JS_UNDEFINED; + JS_PUSH (); + } + else if (JS_SP1->type == JS_FUNC) + { + JSObject *obj; + JSNode f; + JSNode prototype; + + /* The prototype is an object. */ + prototype.type = JS_OBJECT; + + /* Create the prototype for the function, if it is not defined. */ + if (JS_SP1->u.vfunction->prototype == NULL) + { + JS_SP1->u.vfunction->prototype = js_vm_object_new (vm); + + /* Set its __proto__ to point to Object's prototype. */ + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property (vm, JS_SP1->u.vfunction->prototype, + vm->syms.s___proto__, &prototype); + } + + /* Allocate a new object and set its prototype. */ + + obj = js_vm_object_new (vm); + + prototype.u.vobject = JS_SP1->u.vfunction->prototype; + js_vm_object_store_property (vm, obj, vm->syms.s___proto__, &prototype); + + /* + * Basicly we do a jsr to the function given in JS_SP1. But first, + * we must set `this' pointer to the correct value. See `jsr' for + * the details. + */ + JS_COPY (&f, JS_SP1); + + /* Replace func with the new object. */ + JS_SP1->type = JS_OBJECT; + JS_SP1->u.vobject = obj; + + JS_SUBROUTINE_CALL (f.u.vfunction->implementation); + } + /* The primitive language types. */ + else if (vm->prim[JS_SP1->type]) + { + JS_SAVE_REGS (); + (*vm->prim[JS_SP1->type]->new_proc) (vm, vm->prim[JS_SP1->type], JS_SP2, + JS_SP1); + JS_PUSH (); + } + else + ERROR ("illegal object for new"); + + JS_MAYBE_GC (); + break; + +/* operand delete_property (59) */ +case 59: + /* Fetch the property symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + /* + * XXX It should be possible to apply delete operand to builtin + * XXX objects. + */ + ERROR ("delete_property: JS_BUILTIN: not implemented yet"); + } + else if (JS_SP1->type == JS_OBJECT) + { + js_vm_object_delete_property (vm, JS_SP1->u.vobject, j); + } + else if (JS_SP1->type == JS_NULL) + { + /* Delete a property from an object in the with-chain. */ + /* WITHCHAIN */ + ERROR ("delete_property: not implemented yet for the with-chain objects"); + } + /* The primitive language types. */ + /* + * XXX Since we can't delete properties from builtins, we can't delete + * XXX them from the primitive language types. + */ + else + ERROR ("illegal object for delete_property"); + + /* The delete operand returns an undefined value. */ + JS_SP1->type = JS_UNDEFINED; + break; + +/* operand delete_array (60) */ +case 60: + if (JS_SP2->type == JS_BUILTIN) + { + ERROR ("delete_array: JS_BUILTIN: not implemented yet"); + } + else if (JS_SP2->type == JS_OBJECT) + { + js_vm_object_delete_array (vm, JS_SP2->u.vobject, JS_SP1); + JS_POP (); + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->type == JS_INTEGER) + { + if (0 <= JS_SP1->u.vinteger + && JS_SP1->u.vinteger < JS_SP2->u.varray->length) + JS_SP2->u.varray->data[JS_SP1->u.vinteger].type = JS_UNDEFINED; + JS_POP (); + } + else + ERROR ("illegal array index in delete_array"); + } + else + ERROR ("illegal object for delete_array"); + + /* The delete operand returns an undefined value. */ + JS_SP1->type = JS_UNDEFINED; + break; + +/* operand locals (61) */ +case 61: + READ_INT16 (i); + if (sp - i - JS_RESERVE_STACK_FOR_FUNCTION < vm->stack) + ERROR ("stack overflow"); + + for (; i > 0; i--) + { + JS_SP0->type = JS_UNDEFINED; + JS_PUSH (); + } + break; + +/* operand min_args (62) */ +case 62: + READ_INT8 (i); + + if (JS_SP1->u.vinteger < i) + { + unsigned int delta = i - JS_SP1->u.vinteger; + unsigned int argc = JS_SP1->u.vinteger; + + memmove (JS_SP1 - delta, JS_SP1, (fp - JS_SP0 + argc) * sizeof (JSNode)); + sp -= delta; + fp -= delta; + + /* Fill up the fix_args slot. */ + JS_ARGS_FIXP->u.args_fix.argc = argc; + JS_ARGS_FIXP->u.args_fix.delta = delta; + + for (; argc < i; argc++) + JS_ARG (argc)->type = JS_UNDEFINED; + } + + JS_POP (); + break; + +/* operand load_nth_arg (63) */ +case 63: + { + int index = JS_SP1->u.vinteger; + JS_COPY (JS_SP1, JS_ARG (index)); + } + break; + +/* operand with_push (64) */ +case 64: + if (JS_SP1->type != JS_OBJECT && JS_SP1->type != JS_BUILTIN) + ERROR ("illegal object for with_push"); + + /* WITHCHAIN */ + + if (JS_WITHPTR->u.iptr == NULL) + { + JSNode *np; + JSUIntAlign *ip = js_vm_alloc (vm, + sizeof (JSUIntAlign) + + sizeof (JSNode)); + *ip = 1; + np = (JSNode *) ((unsigned char *) ip + sizeof (JSUIntAlign)); + + JS_COPY (np, JS_SP1); + JS_WITHPTR->u.iptr = ip; + } + else + { + JSNode *np; + JSUIntAlign *ip = JS_WITHPTR->u.iptr; + JSUIntAlign ui = *ip; + + ip = js_vm_realloc (vm, ip, + sizeof (JSUIntAlign) + + ((ui + 1) * sizeof (JSNode))); + (*ip)++; + np = (JSNode *) ((unsigned char *) ip + sizeof (JSUIntAlign)); + + JS_COPY (&np[ui], JS_SP1); + JS_WITHPTR->u.iptr = ip; + } + + JS_POP (); + break; + +/* operand with_pop (65) */ +case 65: + READ_INT8 (i); + + /* WITHCHAIN */ + + { + JSUIntAlign *ip = JS_WITHPTR->u.iptr; + + if (ip == NULL || *ip < i) + ERROR ("with stack underflow in with_pop"); + + *ip -= i; + } + break; + +/* operand try_push (66) */ +case 66: + READ_INT32 (i); + + { + JSErrorHandlerFrame *frame = js_calloc (vm, 1, sizeof (*frame)); + + frame->next = vm->error_handler; + frame->sp = sp; + frame->fp = fp; + frame->pc = pc; + frame->pc_delta = i; + vm->error_handler = frame; + + if (setjmp (vm->error_handler->error_jmp)) + { + /* Ok, we caught an error. */ + + /* Restore our state. */ + sp = vm->error_handler->sp; + fp = vm->error_handler->fp; + pc = vm->error_handler->pc; + i = vm->error_handler->pc_delta; + + /* Push the thrown value to the stack. */ + JS_COPY (JS_SP0, &vm->error_handler->thrown); + JS_PUSH (); + + /* Remove this handler frame. */ + frame = vm->error_handler; + vm->error_handler = vm->error_handler->next; + js_free (frame); + + /* Do the jump to the catch block. */ + SETPC_RELATIVE (i); + } + } + break; + +/* operand try_pop (67) */ +case 67: + READ_INT8 (i); + + for (; i > 0; i--) + { + JSErrorHandlerFrame *frame = vm->error_handler; + + vm->error_handler = vm->error_handler->next; + js_free (frame); + } + break; + +/* operand throw (68) */ +case 68: + { + JSErrorHandlerFrame *f = vm->error_handler; + + if (f->sp == NULL) + { + JSNode cvt; + int len; + + /* + * We are jumping to the C-toplevel. Convert our thrown value + * to string and store it to the vm->error. + */ + js_vm_to_string (vm, JS_SP1, &cvt); + + len = cvt.u.vstring->len; + if (len + 1 > sizeof (vm->error)) + len = sizeof (vm->error) - 1; + + memcpy (vm->error, cvt.u.vstring->data, len); + vm->error[len] = '\0'; + } + else + JS_COPY (&f->thrown, JS_SP1); + + longjmp (f->error_jmp, 1); + + /* NOTREACHED (I hope). */ + + sprintf (buf, "VM: no valid error handler initialized%s", + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); + + abort (); + } + break; + +/* operand iffalse_b (69) */ +case 69: + READ_INT32 (i); + if (!JS_SP1->u.vboolean) + SETPC_RELATIVE (i); + JS_POP (); + break; + +/* operand iftrue_b (70) */ +case 70: + READ_INT32 (i); + if (JS_SP1->u.vboolean) + SETPC_RELATIVE (i); + JS_POP (); + break; + +/* operand add_1_i (71) */ +case 71: + JS_SP1->u.vinteger++; + break; + +/* operand add_2_i (72) */ +case 72: + JS_SP1->u.vinteger += 2; + break; + +/* operand load_global_w (73) */ +case 73: + READ_INT32 (j); + { + int found = 0; + + /* Loop over the with chain. */ + /* WITHCHAIN */ + if (JS_WITHPTR->u.iptr) + { + JSUIntAlign *uip = JS_WITHPTR->u.iptr; + JSUIntAlign ui = *uip; + JSNode *wp = (JSNode *) ((unsigned char *) uip + + sizeof (JSUIntAlign)); + + for (i = 0; i < ui; i++) + { + JSNode *w = &wp[i]; + int result = JS_PROPERTY_UNKNOWN; + + if (w->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (w->u.vbuiltin->info->property_proc) + result = (*w->u.vbuiltin->info->property_proc) ( + vm, + w->u.vbuiltin->info, + w->u.vbuiltin->instance_context, + j, 0, &builtin_result); + } + else if (w->type == JS_OBJECT) + { + result = js_vm_object_load_property (vm, w->u.vobject, j, + &builtin_result); + } + else + ERROR ("corrupted with-chain in load_global"); + + if (result == JS_PROPERTY_FOUND) + { + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + found = 1; + break; + } + } + } + + if (!found) + { + /* Use the global value. */ + JS_COPY (JS_SP0, JS_GLOBAL (j)); + JS_PUSH (); + + if (vm->warn_undef && JS_SP1->type == JS_UNDEFINED) + { + sprintf (buf, "VM: warning: using undefined global `%s'%s", + js_vm_symname (vm, j), JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + } + } + break; + +/* operand jsr_w (74) */ +case 74: + /* Read the subroutine symbol index. */ + READ_INT32 (j); + + { + int found = 0; + + /* Loop over the with-chain. */ + /* WITHCHAIN */ + if (JS_WITHPTR->u.iptr) + { + JSUIntAlign *uip = JS_WITHPTR->u.iptr; + JSUIntAlign ui = *uip; + JSNode *wp = (JSNode *) ((unsigned char *) uip + + sizeof (JSUIntAlign)); + + for (i = 0; i < ui; i++) + { + JSNode *w = &wp[i]; + int result = JS_PROPERTY_UNKNOWN; + + if (w->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (w->u.vbuiltin->info->method_proc) + result = (*w->u.vbuiltin->info->method_proc) ( + vm, + w->u.vbuiltin->info, + w->u.vbuiltin->instance_context, j, + &builtin_result, JS_SP2); + JS_MAYBE_GC (); + + if (result == JS_PROPERTY_FOUND) + { + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + } + } + else if (w->type == JS_OBJECT) + { + JSNode method; + + js_vm_object_load_property (vm, w->u.vobject, j, &method); + if (method.type == JS_FUNC) + { + result = JS_PROPERTY_FOUND; + + /* The object defines the method. Do a subroutine call. */ + + /* First: replace the null `this' with `w'. */ + JS_COPY (JS_SP1, w); + + /* Then, do the normal subroutine call. */ + JS_SUBROUTINE_CALL (method.u.vfunction->implementation); + } + } + else + ERROR ("corrupted with-chain in jsr_w"); + + if (result == JS_PROPERTY_FOUND) + { + found = 1; + break; + } + } + } + + if (!found) + { + JSNode f; + + /* Call the global method. */ + JS_COPY (&f, JS_SP1); + function = &f; + + /* Reset the `this' to null. */ + JS_SP1->type = JS_NULL; + + if (function->type == JS_BUILTIN + && function->u.vbuiltin->info->global_method_proc) + { + JS_SAVE_REGS (); + (*function->u.vbuiltin->info->global_method_proc) ( + vm, + function->u.vbuiltin->info, + function->u.vbuiltin->instance_context, + &builtin_result, + JS_SP2); + + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + } + else if (function->type == JS_FUNC) + { + JS_SUBROUTINE_CALL (function->u.vfunction->implementation); + } + else + { + sprintf (buf, "symbol `%s' is undefined as function", + js_vm_symname (vm, j)); + ERROR (buf); + } + } + } + break; + diff --git a/reactos/lib/kjs/src/eswt0.h b/reactos/lib/kjs/src/eswt0.h new file mode 100644 index 00000000000..c974acabf9f --- /dev/null +++ b/reactos/lib/kjs/src/eswt0.h @@ -0,0 +1,2164 @@ +/* operand halt (0) */ +case 0: + sprintf (buf, "VM: halt%s", JS_HOST_LINE_BREAK); + + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); + + while (1) + sleep (5); + break; + +/* operand done (1) */ +case 1: + DONE (); + break; + +/* operand nop (2) */ +case 2: + /* Nothing here! */ + break; + +/* operand dup (3) */ +case 3: + JS_COPY (JS_SP0, JS_SP1); + JS_PUSH (); + break; + +/* operand pop (4) */ +case 4: + JS_POP (); + break; + +/* operand pop_n (5) */ +case 5: + READ_INT8 (i); + JS_POP_N (i); + break; + +/* operand apop (6) */ +case 6: + READ_INT8 (i); + JS_COPY (JS_SP (i + 1), JS_SP1); + JS_POP_N (i); + break; + +/* operand swap (7) */ +case 7: + JS_COPY (JS_SP0, JS_SP2); + JS_COPY (JS_SP2, JS_SP1); + JS_COPY (JS_SP1, JS_SP0); + break; + +/* operand roll (8) */ +case 8: + READ_INT8 (i8); + + if (i8 > 1) + { + int j; + + for (j = 0; j < i8; j++) + JS_COPY (JS_SP (j), JS_SP (j + 1)); + + JS_COPY (JS_SP (i8), JS_SP0); + } + else if (i8 < -1) + { + i8 = -i8; + + JS_COPY (JS_SP0, JS_SP (i8)); + for (; i8 > 0; i8--) + JS_COPY (JS_SP (i8), JS_SP (i8 - 1)); + } + break; + +/* operand const (9) */ +case 9: + READ_INT32 (i); + JS_COPY (JS_SP0, JS_CONST (i)); + JS_PUSH (); + break; + +/* operand const_null (10) */ +case 10: + JS_SP0->type = JS_NULL; + JS_PUSH (); + break; + +/* operand const_true (11) */ +case 11: + JS_SP0->type = JS_BOOLEAN; + JS_SP0->u.vboolean = 1; + JS_PUSH (); + break; + +/* operand const_false (12) */ +case 12: + JS_SP0->type = JS_BOOLEAN; + JS_SP0->u.vboolean = 0; + JS_PUSH (); + break; + +/* operand const_undefined (13) */ +case 13: + JS_SP0->type = JS_UNDEFINED; + JS_PUSH (); + break; + +/* operand const_i0 (14) */ +case 14: + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 0; + JS_PUSH (); + break; + +/* operand const_i1 (15) */ +case 15: + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 1; + JS_PUSH (); + break; + +/* operand const_i2 (16) */ +case 16: + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 2; + JS_PUSH (); + break; + +/* operand const_i3 (17) */ +case 17: + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 3; + JS_PUSH (); + break; + +/* operand const_i (18) */ +case 18: + READ_INT32 (i); + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = i; + JS_PUSH (); + break; + +/* operand load_global (19) */ +case 19: + READ_INT32 (j); + + /* Use the global value only. */ + JS_COPY (JS_SP0, JS_GLOBAL (j)); + JS_PUSH (); + + if (vm->warn_undef && JS_SP1->type == JS_UNDEFINED) + { + sprintf (buf, "VM: warning: using undefined global `%s'%s", + js_vm_symname (vm, j), JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + break; + +/* operand store_global (20) */ +case 20: + READ_INT32 (i); + + /* Operand store_global do not check the with-chain. */ + /* WITHCHAIN */ + + /* Set the global value. */ + JS_COPY (JS_GLOBAL (i), JS_SP1); + JS_POP (); + break; + +/* operand load_arg (21) */ +case 21: + READ_INT8 (i); + JS_COPY (JS_SP0, JS_ARG (i)); + JS_PUSH (); + break; + +/* operand store_arg (22) */ +case 22: + READ_INT8 (i); + JS_COPY (JS_ARG (i), JS_SP1); + JS_POP (); + break; + +/* operand load_local (23) */ +case 23: + READ_INT16 (i); + JS_COPY (JS_SP0, JS_LOCAL (i)); + JS_PUSH (); + break; + +/* operand store_local (24) */ +case 24: + READ_INT16 (i); + JS_COPY (JS_LOCAL (i), JS_SP1); + JS_POP (); + break; + +/* operand load_property (25) */ +case 25: + /* Fetch the property symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (JS_SP1->u.vbuiltin->info->property_proc) + { + if ((*JS_SP1->u.vbuiltin->info->property_proc) ( + vm, + JS_SP1->u.vbuiltin->info, + JS_SP1->u.vbuiltin->instance_context, + j, 0, &builtin_result) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Looking up the prototype. */ + + builtin_result.type = JS_OBJECT; + if (JS_SP1->u.vbuiltin->prototype) + /* This is an instance. */ + builtin_result.u.vobject = JS_SP1->u.vbuiltin->prototype; + else + /* This is a class. */ + builtin_result.u.vobject + = JS_SP1->u.vbuiltin->info->prototype; + } + else + { + /* Looking up stuffs from the prototype. */ + + if (JS_SP1->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_load_property (vm, + JS_SP1->u.vbuiltin->prototype, + j, &builtin_result); + else + /* A class. */ + js_vm_object_load_property ( + vm, + JS_SP1->u.vbuiltin->info->prototype, + j, &builtin_result); + } + } + JS_COPY (JS_SP1, &builtin_result); + } + else + ERROR ("illegal builtin object for load_property"); + } + else if (JS_SP1->type == JS_OBJECT) + { + js_vm_object_load_property (vm, JS_SP1->u.vobject, j, JS_SP1); + } + else if (vm->prim[JS_SP1->type]) + { + /* The primitive language types. */ + JS_SAVE_REGS (); + if ((*vm->prim[JS_SP1->type]->property_proc) (vm, vm->prim[JS_SP1->type], + JS_SP1, j, 0, + &builtin_result) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Looking up the prototype. */ + switch (JS_SP1->type) + { + case JS_STRING: + if (JS_SP1->u.vstring->prototype) + { + builtin_result.type = JS_OBJECT; + builtin_result.u.vobject = JS_SP1->u.vstring->prototype; + } + else + /* No prototype yet. */ + builtin_result.type = JS_NULL; + break; + + case JS_ARRAY: + if (JS_SP1->u.varray->prototype) + { + builtin_result.type = JS_OBJECT; + builtin_result.u.vobject = JS_SP1->u.varray->prototype; + } + else + /* No prototype yet. */ + builtin_result.type = JS_NULL; + break; + + case JS_FUNC: + if (JS_SP1->u.vfunction->prototype) + { + builtin_result.type = JS_OBJECT; + builtin_result.u.vobject + = JS_SP1->u.vfunction->prototype; + } + else + /* No prototype yet. */ + builtin_result.type = JS_NULL; + break; + + default: + /* The rest do not have prototype. */ + builtin_result.type = JS_NULL; + break; + } + } + else + { + /* Looking up stuffs from the prototype. */ + switch (JS_SP1->type) + { + case JS_STRING: + if (JS_SP1->u.vstring->prototype) + js_vm_object_load_property (vm, + JS_SP1->u.vstring->prototype, + j, &builtin_result); + else + /* Take it from the class' prototype */ + goto _op_load_property_try_proto; + break; + + case JS_ARRAY: + if (JS_SP1->u.varray->prototype) + js_vm_object_load_property (vm, + JS_SP1->u.varray->prototype, + j, &builtin_result); + else + /* Take it from the class' prototype */ + goto _op_load_property_try_proto; + break; + + case JS_FUNC: + if (JS_SP1->u.vfunction->prototype) + js_vm_object_load_property (vm, + JS_SP1->u.vfunction->prototype, + j, &builtin_result); + else + /* Take it from the class' prototype */ + goto _op_load_property_try_proto; + break; + + default: + /* + * The rest do not have instance prototypes; use the + * class prototypes. + */ + _op_load_property_try_proto: + js_vm_object_load_property ( + vm, + vm->prim[JS_SP1->type]->prototype, j, + &builtin_result); + break; + } + } + } + + JS_COPY (JS_SP1, &builtin_result); + } + else + ERROR ("illegal object for load_property"); + break; + +/* operand store_property (26) */ +case 26: + /* Fetch the property symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (JS_SP1->u.vbuiltin->info->property_proc) + { + if ((*JS_SP1->u.vbuiltin->info->property_proc) ( + vm, + JS_SP1->u.vbuiltin->info, + JS_SP1->u.vbuiltin->instance_context, + j, 1, JS_SP2) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Setting the prototype. */ + if (JS_SP2->type != JS_OBJECT) + ERROR ("illegal value for set_property"); + + if (JS_SP1->u.vbuiltin->prototype) + /* Setting the instance's prototype. */ + JS_SP1->u.vbuiltin->prototype = JS_SP2->u.vobject; + else + /* Setting the class' prototype. */ + JS_SP1->u.vbuiltin->info->prototype = JS_SP2->u.vobject; + } + else + { + /* Setting stuff to the prototype. */ + if (JS_SP1->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_store_property (vm, + JS_SP1->u.vbuiltin->prototype, + j, JS_SP2); + else + /* A class. */ + js_vm_object_store_property ( + vm, + JS_SP1->u.vbuiltin->info->prototype, + j, JS_SP2); + } + } + } + else + ERROR ("illegal builtin object for store_property"); + + JS_POP (); + JS_POP (); + } + else if (JS_SP1->type == JS_OBJECT) + { + js_vm_object_store_property (vm, JS_SP1->u.vobject, j, JS_SP2); + JS_POP (); + JS_POP (); + } + else if (vm->prim[JS_SP1->type]) + { + /* The primitive language types. */ + JS_SAVE_REGS (); + if ((*vm->prim[JS_SP1->type]->property_proc) (vm, vm->prim[JS_SP1->type], + JS_SP1, j, 1, JS_SP2) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Setting the prototype. */ + if (JS_SP2->type != JS_OBJECT) + ERROR ("illegal value for set_property"); + + switch (JS_SP1->type) + { + case JS_STRING: + JS_SP1->u.vstring->prototype = JS_SP2->u.vobject; + break; + + case JS_ARRAY: + JS_SP1->u.varray->prototype = JS_SP2->u.vobject; + break; + + case JS_FUNC: + JS_SP1->u.vfunction->prototype = JS_SP2->u.vobject; + break; + + default: + ERROR ("illegal object for set_property"); + break; + } + } + else + { + JSNode prototype; + + /* Setting to the prototype. We create them on demand. */ + switch (JS_SP1->type) + { + case JS_STRING: + if (JS_SP1->u.vstring->prototype == NULL) + { + prototype.type = JS_OBJECT; + + /* Create the prototype and set its __proto__. */ + JS_SP1->u.vstring->prototype = js_vm_object_new (vm); + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property ( + vm, + JS_SP1->u.vstring->prototype, + vm->syms.s___proto__, + &prototype); + } + js_vm_object_store_property (vm, + JS_SP1->u.vstring->prototype, + j, JS_SP2); + break; + + case JS_ARRAY: + if (JS_SP1->u.varray->prototype == NULL) + { + prototype.type = JS_OBJECT; + + /* Create the prototype and set its __proto__. */ + JS_SP1->u.varray->prototype = js_vm_object_new (vm); + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property ( + vm, + JS_SP1->u.varray->prototype, + vm->syms.s___proto__, + &prototype); + } + js_vm_object_store_property (vm, + JS_SP1->u.varray->prototype, + j, JS_SP2); + break; + + case JS_FUNC: + if (JS_SP1->u.vfunction->prototype == NULL) + { + prototype.type = JS_OBJECT; + + /* Create the prototype and set its __proto__. */ + JS_SP1->u.vfunction->prototype = js_vm_object_new (vm); + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property ( + vm, + JS_SP1->u.vfunction->prototype, + vm->syms.s___proto__, + &prototype); + } + js_vm_object_store_property (vm, + JS_SP1->u.vfunction->prototype, + j, JS_SP2); + break; + + default: + ERROR ("illegal object for set_property"); + break; + } + } + } + JS_POP (); + JS_POP (); + } + else + ERROR ("illegal object for store_property"); + + JS_MAYBE_GC (); + break; + +/* operand load_array (27) */ +case 27: + if (JS_SP2->type == JS_BUILTIN) + { + if (JS_SP1->type == JS_INTEGER) + { + ERROR ("integer indexes not implemented yet for BUILTIN in load_array"); + } + else if (JS_SP1->type == JS_STRING) + { + /* Intern the string. */ + j = js_vm_intern_with_len (vm, JS_SP1->u.vstring->data, + JS_SP1->u.vstring->len); + + /* The code below must be in sync with operand `load_property'. */ + JS_SAVE_REGS (); + + if (JS_SP2->u.vbuiltin->info->property_proc) + { + if ((*JS_SP2->u.vbuiltin->info->property_proc) ( + vm, + JS_SP2->u.vbuiltin->info, + JS_SP2->u.vbuiltin->instance_context, + j, 0, &builtin_result) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Looking up the prototype. */ + + builtin_result.type = JS_OBJECT; + if (JS_SP2->u.vbuiltin->prototype) + /* This is an instance. */ + builtin_result.u.vobject + = JS_SP2->u.vbuiltin->prototype; + else + /* This is a class. */ + builtin_result.u.vobject + = JS_SP2->u.vbuiltin->info->prototype; + } + else + { + /* Looking up stuffs from the prototype. */ + + if (JS_SP2->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_load_property ( + vm, + JS_SP2->u.vbuiltin->prototype, + j, &builtin_result); + else + /* A class. */ + js_vm_object_load_property ( + vm, + JS_SP2->u.vbuiltin->info->prototype, + j, &builtin_result); + } + } + JS_COPY (JS_SP2, &builtin_result); + JS_POP (); + } + else + ERROR ("illegal builtin object for load_array"); + } + else + { + sprintf (buf, "illegal array index in load_array (%d)", + JS_SP1->type); + ERROR (buf); + } + } + else if (JS_SP2->type == JS_OBJECT) + { + js_vm_object_load_array (vm, JS_SP2->u.vobject, JS_SP1, JS_SP2); + JS_POP (); + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->type == JS_INTEGER) + { + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.varray->length) + JS_SP2->type = JS_UNDEFINED; + else + { + JSNode *n = &JS_SP2->u.varray->data[JS_SP1->u.vinteger]; + JS_COPY (JS_SP2, n); + } + JS_POP (); + } + else + { + sprintf (buf, "illegal array index in load_array (%d)", + JS_SP1->type); + ERROR (buf); + } + } + else if (JS_SP2->type == JS_STRING) + { + if (JS_SP1->type == JS_INTEGER) + { + int ch; + + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.vstring->len) + ERROR ("string index out of range in load_array"); + + ch = JS_SP2->u.vstring->data[JS_SP1->u.vinteger]; + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = ch; + + JS_POP (); + } + else + ERROR ("illegal string index in load_array"); + } + else + ERROR ("illegal object for load_array"); + break; + +/* operand store_array (28) */ +case 28: + if (JS_SP2->type == JS_BUILTIN) + { + if (JS_SP1->type == JS_INTEGER) + { + ERROR ("integer index not implemented yet for BUILTIN in store_array"); + } + else if (JS_SP1->type == JS_STRING) + { + /* Intern the string. */ + j = js_vm_intern_with_len (vm, JS_SP1->u.vstring->data, + JS_SP1->u.vstring->len); + + /* The code below msut be in sync with operand `store_property'. */ + JS_SAVE_REGS (); + if (JS_SP2->u.vbuiltin->info->property_proc) + { + if ((*JS_SP2->u.vbuiltin->info->property_proc) ( + vm, + JS_SP2->u.vbuiltin->info, + JS_SP2->u.vbuiltin->instance_context, + j, 1, JS_SP (3)) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Setting the prototype. */ + if (JS_SP (3)->type != JS_OBJECT) + ERROR ("illegal value for prototype"); + + if (JS_SP2->u.vbuiltin->prototype) + /* Setting the instance's prototype. */ + JS_SP2->u.vbuiltin->prototype = JS_SP (3)->u.vobject; + else + /* Setting the class' prototype. */ + JS_SP2->u.vbuiltin->info->prototype + = JS_SP (3)->u.vobject; + } + else + { + /* Setting stuff to the prototype. */ + if (JS_SP2->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_store_property ( + vm, + JS_SP2->u.vbuiltin->prototype, + j, JS_SP (3)); + else + /* A class. */ + js_vm_object_store_property ( + vm, + JS_SP2->u.vbuiltin->info->prototype, + j, JS_SP (3)); + } + } + } + else + ERROR ("illegal builtin object for store_array"); + + JS_POP_N (3); + } + else + ERROR ("illegal array index in store_array"); + } + else if (JS_SP2->type == JS_OBJECT) + { + js_vm_object_store_array (vm, JS_SP2->u.vobject, JS_SP1, JS_SP (3)); + JS_POP_N (3); + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->type == JS_INTEGER) + { + if (JS_SP1->u.vinteger < 0) + ERROR ("negative array index in store_array"); + if (JS_SP1->u.vinteger >= JS_SP2->u.varray->length) + js_vm_expand_array (vm, JS_SP2, JS_SP1->u.vinteger + 1); + + JS_COPY (&JS_SP2->u.varray->data[JS_SP1->u.vinteger], JS_SP (3)); + JS_POP_N (3); + } + else + ERROR ("illegal array index in store_array"); + } + else if (JS_SP2->type == JS_STRING) + { + if (JS_SP1->type == JS_INTEGER) + { + if (JS_SP2->u.vstring->staticp) + ERROR ("static string in store_array"); + + if (JS_SP1->u.vinteger < 0) + ERROR ("negative string index in store_array"); + + if (JS_SP (3)->type != JS_INTEGER) + ERROR ("non-integer value to store into string in store_array"); + + if (JS_SP1->u.vinteger >= JS_SP2->u.vstring->len) + { + /* Expand the string. */ + JS_SP2->u.vstring->data = js_vm_realloc (vm, + JS_SP2->u.vstring->data, + JS_SP1->u.vinteger + 1); + /* Fill the gap with ' '. */ + for (; JS_SP2->u.vstring->len <= JS_SP1->u.vinteger;) + JS_SP2->u.vstring->data[JS_SP2->u.vstring->len++] = ' '; + } + + JS_SP2->u.vstring->data[JS_SP1->u.vinteger] + = (unsigned char) JS_SP (3)->u.vinteger; + JS_POP_N (3); + } + else + ERROR ("illegal string index in store_array"); + } + else + ERROR ("illegal object for store_array"); + + JS_MAYBE_GC (); + break; + +/* operand nth (29) */ +case 29: + if (JS_SP2->type == JS_STRING) + { + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.vstring->len) + { + JS_SP2->type = JS_UNDEFINED; + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 0; + } + else + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = JS_SP2->u.vstring->data[JS_SP1->u.vinteger]; + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 1; + } + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.varray->length) + { + JS_SP2->type = JS_UNDEFINED; + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 0; + } + else + { + JSNode *n = &JS_SP2->u.varray->data[JS_SP1->u.vinteger]; + JS_COPY (JS_SP2, n); + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 1; + } + } + else if (JS_SP2->type == JS_OBJECT) + { + i = js_vm_object_nth (vm, JS_SP2->u.vobject, JS_SP1->u.vinteger, JS_SP2); + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = i; + } + else + ERROR ("illegal object for nth"); + break; + +/* operand cmp_eq (30) */ +case 30: + JS_OPERAND_CMP_EQ (==, 1); + break; + +/* operand cmp_ne (31) */ +case 31: + JS_OPERAND_CMP_EQ (!=, 0); + break; + +/* operand cmp_lt (32) */ +case 32: + JS_OPERAND_CMP_REL (<); + break; + +/* operand cmp_gt (33) */ +case 33: + JS_OPERAND_CMP_REL (>); + break; + +/* operand cmp_le (34) */ +case 34: + JS_OPERAND_CMP_REL (<=); + break; + +/* operand cmp_ge (35) */ +case 35: + JS_OPERAND_CMP_REL (>=); + break; + +/* operand cmp_seq (36) */ +case 36: + JS_OPERAND_CMP_SEQ (==, 1); + break; + +/* operand cmp_sne (37) */ +case 37: + JS_OPERAND_CMP_SEQ (!=, 0); + break; + +/* operand sub (38) */ +case 38: + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger -= JS_SP1->u.vinteger; + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (l->type == JS_INTEGER) + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger - r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = (double) l->u.vinteger - r->u.vfloat; + } + } + else + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat - (double) r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat - r->u.vfloat; + } + } + } + + JS_POP (); + break; + +/* operand add (39) */ +case 39: + if (JS_SP2->type == JS_STRING || JS_SP1->type == JS_STRING) + { + unsigned char *d2, *d1, *ndata; + unsigned int d2_len, d1_len, nlen; + JSNode cvt; + + if (JS_SP2->type == JS_STRING) + { + d2 = JS_SP2->u.vstring->data; + d2_len = JS_SP2->u.vstring->len; + } + else + { + js_vm_to_string (vm, JS_SP2, &cvt); + d2 = cvt.u.vstring->data; + d2_len = cvt.u.vstring->len; + } + if (JS_SP1->type == JS_STRING) + { + d1 = JS_SP1->u.vstring->data; + d1_len = JS_SP1->u.vstring->len; + } + else + { + js_vm_to_string (vm, JS_SP1, &cvt); + d1 = cvt.u.vstring->data; + d1_len = cvt.u.vstring->len; + } + + nlen = d2_len + d1_len; + ndata = js_vm_alloc (vm, nlen); + memcpy (ndata, d2, d2_len); + memcpy (ndata + d2_len, d1, d1_len); + + js_vm_make_static_string (vm, JS_SP2, ndata, nlen); + JS_SP2->u.vstring->staticp = 0; + JS_POP (); + JS_MAYBE_GC (); + } + else if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger += JS_SP1->u.vinteger; + JS_POP (); + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (l->type == JS_INTEGER) + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger + r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = (double) l->u.vinteger + r->u.vfloat; + } + } + else + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat + (double) r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat + r->u.vfloat; + } + } + + JS_POP (); + } + break; + +/* operand mul (40) */ +case 40: + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger *= JS_SP1->u.vinteger; + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (l->type == JS_INTEGER) + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger * r->u.vinteger; + } + else + { + if (l->u.vinteger == 0 + && (JS_IS_POSITIVE_INFINITY (r) + || JS_IS_NEGATIVE_INFINITY (r))) + JS_SP2->type = JS_NAN; + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = (double) l->u.vinteger * r->u.vfloat; + } + } + } + else + { + if ((JS_IS_POSITIVE_INFINITY (l) || JS_IS_NEGATIVE_INFINITY (l)) + && ((r->type == JS_INTEGER && r->u.vinteger == 0) + || (r->type == JS_FLOAT && r->u.vfloat == 0.0))) + JS_SP2->type = JS_NAN; + else + { + JS_SP2->type = JS_FLOAT; + + if (r->type == JS_INTEGER) + JS_SP2->u.vfloat = l->u.vfloat * (double) r->u.vinteger; + else + JS_SP2->u.vfloat = l->u.vfloat * r->u.vfloat; + } + } + } + + JS_POP (); + break; + +/* operand div (41) */ +case 41: + { + int nan = 0; + double l, r; + int l_inf = 0; + int r_inf = 0; + JSNode *n; + JSNode cvt; + + /* Convert divident to float. */ + if (JS_IS_NUMBER (JS_SP2)) + n = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &cvt); + n = &cvt; + } + + switch (n->type) + { + case JS_INTEGER: + l = (double) n->u.vinteger; + break; + + case JS_FLOAT: + l = n->u.vfloat; + if (JS_IS_POSITIVE_INFINITY (n) || JS_IS_NEGATIVE_INFINITY (n)) + l_inf = 1; + break; + + case JS_NAN: + default: + nan = 1; + break; + } + + /* Convert divisor to float. */ + if (JS_IS_NUMBER (JS_SP1)) + n = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP2, &cvt); + n = &cvt; + } + + switch (n->type) + { + case JS_INTEGER: + r = (double) n->u.vinteger; + break; + + case JS_FLOAT: + r = n->u.vfloat; + if (JS_IS_POSITIVE_INFINITY (n) || JS_IS_NEGATIVE_INFINITY (n)) + r_inf = 1; + break; + + case JS_NAN: + default: + nan = 1; + break; + } + + /* Do the division. */ + JS_POP (); + if (nan || (l_inf && r_inf)) + JS_SP1->type = JS_NAN; + else + { + if (l_inf && r == 0.0) + { + /* is already an infinity. */ + JS_SP1->type = JS_FLOAT; + JS_SP1->u.vfloat = l; + } + else if (l == 0.0 && r == 0.0) + JS_SP1->type = JS_NAN; + else + { + JS_SP1->type = JS_FLOAT; + JS_SP1->u.vfloat = l / r; + } + } + } + break; + +/* operand mod (42) */ +case 42: + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + if (JS_SP1->u.vinteger == 0) + JS_SP2->type = JS_NAN; + else + JS_SP2->u.vinteger %= JS_SP1->u.vinteger; + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (JS_IS_POSITIVE_INFINITY (l) + || JS_IS_NEGATIVE_INFINITY (l) + || ((r->type == JS_INTEGER && r->u.vinteger == 0) + || (r->type == JS_FLOAT && r->u.vfloat == 0.0))) + JS_SP2->type = JS_NAN; + else if (JS_IS_POSITIVE_INFINITY (r) + || JS_IS_NEGATIVE_INFINITY (r)) + JS_COPY (JS_SP2, l); + else if ((l->type == JS_INTEGER && l->u.vinteger == 0) + || (l->type == JS_FLOAT && l->u.vfloat == 0.0)) + JS_COPY (JS_SP2, l); + else + { + if (l->type == JS_INTEGER && r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger % r->u.vinteger; + } + else + { + double ld, rd; + int full; + + if (l->type == JS_INTEGER) + ld = (double) l->u.vinteger; + else + ld = l->u.vfloat; + + if (r->type == JS_INTEGER) + rd = (double) r->u.vinteger; + else + rd = r->u.vfloat; + + full = ld / rd; + + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = ld - (full * rd); + } + } + } + + JS_POP (); + break; + +/* operand neg (43) */ +case 43: + if (JS_SP1->type == JS_INTEGER) + JS_SP1->u.vinteger = -JS_SP1->u.vinteger; + else if (JS_SP1->type == JS_FLOAT) + JS_SP1->u.vfloat = -JS_SP1->u.vfloat; + else if (JS_SP1->type == JS_NAN) + ; + else + { + JSNode cvt; + + js_vm_to_number (vm, JS_SP1, &cvt); + + JS_SP1->type = cvt.type; + switch (cvt.type) + { + case JS_INTEGER: + JS_SP1->u.vinteger = -cvt.u.vinteger; + break; + + case JS_FLOAT: + JS_SP1->u.vfloat = -cvt.u.vfloat; + break; + + case JS_NAN: + default: + /* Nothing here. */ + break; + } + } + break; + +/* operand and (44) */ +case 44: + JS_OPERAND_BINARY (&); + break; + +/* operand not (45) */ +case 45: + JS_SP1->u.vboolean = JS_IS_FALSE (JS_SP1); + JS_SP1->type = JS_BOOLEAN; + break; + +/* operand or (46) */ +case 46: + JS_OPERAND_BINARY (|); + break; + +/* operand xor (47) */ +case 47: + JS_OPERAND_BINARY (^); + break; + +/* operand shift_left (48) */ +case 48: + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger = ((JSInt32) JS_SP2->u.vinteger + << (JSUInt32) JS_SP1->u.vinteger); + JS_POP (); + } + else + { + JSInt32 l; + JSUInt32 r; + + l = js_vm_to_int32 (vm, JS_SP2); + r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1); + + JS_SP2->u.vinteger = l << r; + JS_SP2->type = JS_INTEGER; + JS_POP (); + } + break; + +/* operand shift_right (49) */ +case 49: + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger = ((JSInt32) JS_SP2->u.vinteger + >> (JSUInt32) JS_SP1->u.vinteger); + JS_POP (); + } + else + { + JSInt32 l; + JSUInt32 r; + + l = js_vm_to_int32 (vm, JS_SP2); + r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1); + + JS_SP2->u.vinteger = l >> r; + JS_SP2->type = JS_INTEGER; + JS_POP (); + } + break; + +/* operand shift_rright (50) */ +case 50: + { + JSInt32 l; + JSUInt32 r; + + l = js_vm_to_int32 (vm, JS_SP2); + r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1); + + if (r > 0) + JS_SP2->u.vinteger = (l & 0x7fffffff) >> r; + else + JS_SP2->u.vinteger = l; + + JS_SP2->type = JS_INTEGER; + JS_POP (); + } + break; + +/* operand iffalse (51) */ +case 51: + READ_INT32 (i); + if (JS_IS_FALSE (JS_SP1)) + SETPC_RELATIVE (i); + JS_POP (); + break; + +/* operand iftrue (52) */ +case 52: + READ_INT32 (i); + if (JS_IS_TRUE (JS_SP1)) + SETPC_RELATIVE (i); + JS_POP (); + break; + +/* operand call_method (53) */ +case 53: + /* Fetch the method symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (JS_SP1->u.vbuiltin->info->method_proc) + { + if ((*JS_SP1->u.vbuiltin->info->method_proc) ( + vm, + JS_SP1->u.vbuiltin->info, + JS_SP1->u.vbuiltin->instance_context, j, + &builtin_result, JS_SP2) + == JS_PROPERTY_UNKNOWN) + ERROR ("call_method: unknown method"); + } + else + ERROR ("illegal builtin object for call_method"); + + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + JS_MAYBE_GC (); + } + else if (JS_SP1->type == JS_OBJECT) + { + JSNode method; + + if (js_vm_object_load_property (vm, JS_SP1->u.vobject, j, &method) + == JS_PROPERTY_FOUND) + { + /* The property has been defined in the object. */ + + if (method.type != JS_FUNC) + ERROR ("call_method: unknown method"); + + /* And once again. We must do a subroutine call here. */ + JS_SUBROUTINE_CALL (method.u.vfunction->implementation); + } + else + /* Let our prototype handle this. */ + goto _op_call_method_try_proto; + } + else if (vm->prim[JS_SP1->type]) + { + /* The primitive language types. */ + _op_call_method_try_proto: + JS_SAVE_REGS (); + if ((*vm->prim[JS_SP1->type]->method_proc) (vm, vm->prim[JS_SP1->type], + JS_SP1, j, &builtin_result, + JS_SP2) + == JS_PROPERTY_UNKNOWN) + { + JSNode method; + int result = JS_PROPERTY_UNKNOWN; + + /* Let's see if we can find it from the prototype. */ + if (JS_SP1->type == JS_STRING && JS_SP1->u.vstring->prototype) + result = js_vm_object_load_property (vm, + JS_SP1->u.vstring->prototype, + j, &method); + else if (JS_SP1->type == JS_ARRAY && JS_SP1->u.varray->prototype) + result = js_vm_object_load_property (vm, + JS_SP1->u.varray->prototype, + j, &method); + else if (JS_SP1->type == JS_FUNC && JS_SP1->u.vfunction->prototype) + result + = js_vm_object_load_property (vm, JS_SP1->u.vfunction->prototype, + j, &method); + + if (result == JS_PROPERTY_UNKNOWN || method.type != JS_FUNC) + ERROR ("call_method: unknown method"); + + /* Do the subroutine call. */ + JS_SUBROUTINE_CALL (method.u.vfunction->implementation); + } + else + { + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + JS_MAYBE_GC (); + } + } + else + ERROR ("illegal object for call_method"); + break; + +/* operand jmp (54) */ +case 54: + READ_INT32 (i); + SETPC_RELATIVE (i); + break; + +/* operand jsr (55) */ +case 55: + /* Call the global method. */ + { + JSNode f; + + /* Fetch the function to our local variable. */ + JS_COPY (&f, JS_SP1); + function = &f; + + /* Reset the `this' to null. */ + JS_SP1->type = JS_NULL; + + if (function->type == JS_BUILTIN + && function->u.vbuiltin->info->global_method_proc) + { + JS_SAVE_REGS (); + (*function->u.vbuiltin->info->global_method_proc) ( + vm, + function->u.vbuiltin->info, + function->u.vbuiltin->instance_context, + &builtin_result, + JS_SP2); + + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + } + else if (function->type == JS_FUNC) + { + JS_SUBROUTINE_CALL (function->u.vfunction->implementation); + } + else + { + sprintf (buf, "illegal function object in jsr"); + ERROR (buf); + } + } + break; + +/* operand return (56) */ +case 56: + if (fp->u.iptr == NULL) + /* Return from the global scope. */ + DONE (); + + /* STACKFRAME */ + + /* Check if the stack has been modified by min_args. */ + if (JS_ARGS_FIXP->u.args_fix.delta) + { + unsigned int delta = JS_ARGS_FIXP->u.args_fix.delta; + + /* + * Yes it was. Truncate it back to the state where it was + * before the call. + */ + + memmove (JS_SP1 + delta, JS_SP1, + (fp - JS_SP0 + JS_ARGS_FIXP->u.args_fix.argc) + * sizeof (JSNode)); + + sp += delta; + fp += delta; + } + + /* Set pc to the saved return address. */ +#if 0 + if (fp[-3].type != JS_IPTR) + ERROR ("can't find saved return address"); +#endif + pc = fp[-3].u.iptr; + + { + void *old_fp; + + /* Save old frame pointer. */ +#if 0 + if (fp->type != JS_IPTR) + ERROR ("can't find saved frame pointer"); +#endif + old_fp = fp->u.iptr; + + /* Put return value to its correct location. */ + JS_COPY (fp, JS_SP1); + + /* Restore sp. */ + sp = &fp[-1]; + + /* Restore frame pointer. */ + fp = old_fp; + } + break; + +/* operand typeof (57) */ +case 57: + { + char *typeof_name = ""; /* Initialized to make compiler quiet. */ + + switch (JS_SP1->type) + { + case JS_UNDEFINED: + typeof_name = "undefined"; + break; + + case JS_NULL: + typeof_name = "object"; + break; + + case JS_BOOLEAN: + typeof_name = "boolean"; + break; + + case JS_INTEGER: + case JS_FLOAT: + case JS_NAN: + typeof_name = "number"; + break; + + case JS_STRING: + typeof_name = "string"; + break; + + case JS_ARRAY: + typeof_name = "#array"; + break; + + case JS_OBJECT: + typeof_name = "object"; + break; + + case JS_SYMBOL: + typeof_name = "#symbol"; + break; + + case JS_BUILTIN: + typeof_name = "#builtin"; + break; + + case JS_FUNC: + typeof_name = "function"; + break; + + case JS_IPTR: + typeof_name = "#iptr"; + break; + + case JS_ARGS_FIX: + typeof_name = "#argsfix"; + break; + } + + js_vm_make_static_string (vm, JS_SP1, typeof_name, strlen (typeof_name)); + JS_MAYBE_GC (); + } + break; + +/* operand new (58) */ +case 58: + /* Check object. */ + if (JS_SP1->type == JS_BUILTIN && JS_SP1->u.vbuiltin->info->new_proc) + { + JS_SAVE_REGS (); + (*JS_SP1->u.vbuiltin->info->new_proc) (vm, JS_SP1->u.vbuiltin->info, + JS_SP2, JS_SP1); + + /* Push a dummy return value for the constructor. This is ignored. */ + JS_SP0->type = JS_UNDEFINED; + JS_PUSH (); + } + else if (JS_SP1->type == JS_FUNC) + { + JSObject *obj; + JSNode f; + JSNode prototype; + + /* The prototype is an object. */ + prototype.type = JS_OBJECT; + + /* Create the prototype for the function, if it is not defined. */ + if (JS_SP1->u.vfunction->prototype == NULL) + { + JS_SP1->u.vfunction->prototype = js_vm_object_new (vm); + + /* Set its __proto__ to point to Object's prototype. */ + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property (vm, JS_SP1->u.vfunction->prototype, + vm->syms.s___proto__, &prototype); + } + + /* Allocate a new object and set its prototype. */ + + obj = js_vm_object_new (vm); + + prototype.u.vobject = JS_SP1->u.vfunction->prototype; + js_vm_object_store_property (vm, obj, vm->syms.s___proto__, &prototype); + + /* + * Basicly we do a jsr to the function given in JS_SP1. But first, + * we must set `this' pointer to the correct value. See `jsr' for + * the details. + */ + JS_COPY (&f, JS_SP1); + + /* Replace func with the new object. */ + JS_SP1->type = JS_OBJECT; + JS_SP1->u.vobject = obj; + + JS_SUBROUTINE_CALL (f.u.vfunction->implementation); + } + /* The primitive language types. */ + else if (vm->prim[JS_SP1->type]) + { + JS_SAVE_REGS (); + (*vm->prim[JS_SP1->type]->new_proc) (vm, vm->prim[JS_SP1->type], JS_SP2, + JS_SP1); + JS_PUSH (); + } + else + ERROR ("illegal object for new"); + + JS_MAYBE_GC (); + break; + +/* operand delete_property (59) */ +case 59: + /* Fetch the property symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + /* + * XXX It should be possible to apply delete operand to builtin + * XXX objects. + */ + ERROR ("delete_property: JS_BUILTIN: not implemented yet"); + } + else if (JS_SP1->type == JS_OBJECT) + { + js_vm_object_delete_property (vm, JS_SP1->u.vobject, j); + } + else if (JS_SP1->type == JS_NULL) + { + /* Delete a property from an object in the with-chain. */ + /* WITHCHAIN */ + ERROR ("delete_property: not implemented yet for the with-chain objects"); + } + /* The primitive language types. */ + /* + * XXX Since we can't delete properties from builtins, we can't delete + * XXX them from the primitive language types. + */ + else + ERROR ("illegal object for delete_property"); + + /* The delete operand returns an undefined value. */ + JS_SP1->type = JS_UNDEFINED; + break; + +/* operand delete_array (60) */ +case 60: + if (JS_SP2->type == JS_BUILTIN) + { + ERROR ("delete_array: JS_BUILTIN: not implemented yet"); + } + else if (JS_SP2->type == JS_OBJECT) + { + js_vm_object_delete_array (vm, JS_SP2->u.vobject, JS_SP1); + JS_POP (); + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->type == JS_INTEGER) + { + if (0 <= JS_SP1->u.vinteger + && JS_SP1->u.vinteger < JS_SP2->u.varray->length) + JS_SP2->u.varray->data[JS_SP1->u.vinteger].type = JS_UNDEFINED; + JS_POP (); + } + else + ERROR ("illegal array index in delete_array"); + } + else + ERROR ("illegal object for delete_array"); + + /* The delete operand returns an undefined value. */ + JS_SP1->type = JS_UNDEFINED; + break; + +/* operand locals (61) */ +case 61: + READ_INT16 (i); + if (sp - i - JS_RESERVE_STACK_FOR_FUNCTION < vm->stack) + ERROR ("stack overflow"); + + for (; i > 0; i--) + { + JS_SP0->type = JS_UNDEFINED; + JS_PUSH (); + } + break; + +/* operand min_args (62) */ +case 62: + READ_INT8 (i); + + if (JS_SP1->u.vinteger < i) + { + unsigned int delta = i - JS_SP1->u.vinteger; + unsigned int argc = JS_SP1->u.vinteger; + + memmove (JS_SP1 - delta, JS_SP1, (fp - JS_SP0 + argc) * sizeof (JSNode)); + sp -= delta; + fp -= delta; + + /* Fill up the fix_args slot. */ + JS_ARGS_FIXP->u.args_fix.argc = argc; + JS_ARGS_FIXP->u.args_fix.delta = delta; + + for (; argc < i; argc++) + JS_ARG (argc)->type = JS_UNDEFINED; + } + + JS_POP (); + break; + +/* operand load_nth_arg (63) */ +case 63: + { + int index = JS_SP1->u.vinteger; + JS_COPY (JS_SP1, JS_ARG (index)); + } + break; + +/* operand with_push (64) */ +case 64: + if (JS_SP1->type != JS_OBJECT && JS_SP1->type != JS_BUILTIN) + ERROR ("illegal object for with_push"); + + /* WITHCHAIN */ + + if (JS_WITHPTR->u.iptr == NULL) + { + JSNode *np; + JSUIntAlign *ip = js_vm_alloc (vm, + sizeof (JSUIntAlign) + + sizeof (JSNode)); + *ip = 1; + np = (JSNode *) ((unsigned char *) ip + sizeof (JSUIntAlign)); + + JS_COPY (np, JS_SP1); + JS_WITHPTR->u.iptr = ip; + } + else + { + JSNode *np; + JSUIntAlign *ip = JS_WITHPTR->u.iptr; + JSUIntAlign ui = *ip; + + ip = js_vm_realloc (vm, ip, + sizeof (JSUIntAlign) + + ((ui + 1) * sizeof (JSNode))); + (*ip)++; + np = (JSNode *) ((unsigned char *) ip + sizeof (JSUIntAlign)); + + JS_COPY (&np[ui], JS_SP1); + JS_WITHPTR->u.iptr = ip; + } + + JS_POP (); + break; + +/* operand with_pop (65) */ +case 65: + READ_INT8 (i); + + /* WITHCHAIN */ + + { + JSUIntAlign *ip = JS_WITHPTR->u.iptr; + + if (ip == NULL || *ip < i) + ERROR ("with stack underflow in with_pop"); + + *ip -= i; + } + break; + +/* operand try_push (66) */ +case 66: + READ_INT32 (i); + + { + JSErrorHandlerFrame *frame = js_calloc (vm, 1, sizeof (*frame)); + + frame->next = vm->error_handler; + frame->sp = sp; + frame->fp = fp; + frame->pc = pc; + frame->pc_delta = i; + vm->error_handler = frame; + + if (setjmp (vm->error_handler->error_jmp)) + { + /* Ok, we caught an error. */ + + /* Restore our state. */ + sp = vm->error_handler->sp; + fp = vm->error_handler->fp; + pc = vm->error_handler->pc; + i = vm->error_handler->pc_delta; + + /* Push the thrown value to the stack. */ + JS_COPY (JS_SP0, &vm->error_handler->thrown); + JS_PUSH (); + + /* Remove this handler frame. */ + frame = vm->error_handler; + vm->error_handler = vm->error_handler->next; + js_free (frame); + + /* Do the jump to the catch block. */ + SETPC_RELATIVE (i); + } + } + break; + +/* operand try_pop (67) */ +case 67: + READ_INT8 (i); + + for (; i > 0; i--) + { + JSErrorHandlerFrame *frame = vm->error_handler; + + vm->error_handler = vm->error_handler->next; + js_free (frame); + } + break; + +/* operand throw (68) */ +case 68: + { + JSErrorHandlerFrame *f = vm->error_handler; + + if (f->sp == NULL) + { + JSNode cvt; + int len; + + /* + * We are jumping to the C-toplevel. Convert our thrown value + * to string and store it to the vm->error. + */ + js_vm_to_string (vm, JS_SP1, &cvt); + + len = cvt.u.vstring->len; + if (len + 1 > sizeof (vm->error)) + len = sizeof (vm->error) - 1; + + memcpy (vm->error, cvt.u.vstring->data, len); + vm->error[len] = '\0'; + } + else + JS_COPY (&f->thrown, JS_SP1); + + longjmp (f->error_jmp, 1); + + /* NOTREACHED (I hope). */ + + sprintf (buf, "VM: no valid error handler initialized%s", + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); + + abort (); + } + break; + +/* operand iffalse_b (69) */ +case 69: + READ_INT32 (i); + if (!JS_SP1->u.vboolean) + SETPC_RELATIVE (i); + JS_POP (); + break; + +/* operand iftrue_b (70) */ +case 70: + READ_INT32 (i); + if (JS_SP1->u.vboolean) + SETPC_RELATIVE (i); + JS_POP (); + break; + +/* operand add_1_i (71) */ +case 71: + JS_SP1->u.vinteger++; + break; + +/* operand add_2_i (72) */ +case 72: + JS_SP1->u.vinteger += 2; + break; + +/* operand load_global_w (73) */ +case 73: + READ_INT32 (j); + { + int found = 0; + + /* Loop over the with chain. */ + /* WITHCHAIN */ + if (JS_WITHPTR->u.iptr) + { + JSUIntAlign *uip = JS_WITHPTR->u.iptr; + JSUIntAlign ui = *uip; + JSNode *wp = (JSNode *) ((unsigned char *) uip + + sizeof (JSUIntAlign)); + + for (i = 0; i < ui; i++) + { + JSNode *w = &wp[i]; + int result = JS_PROPERTY_UNKNOWN; + + if (w->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (w->u.vbuiltin->info->property_proc) + result = (*w->u.vbuiltin->info->property_proc) ( + vm, + w->u.vbuiltin->info, + w->u.vbuiltin->instance_context, + j, 0, &builtin_result); + } + else if (w->type == JS_OBJECT) + { + result = js_vm_object_load_property (vm, w->u.vobject, j, + &builtin_result); + } + else + ERROR ("corrupted with-chain in load_global"); + + if (result == JS_PROPERTY_FOUND) + { + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + found = 1; + break; + } + } + } + + if (!found) + { + /* Use the global value. */ + JS_COPY (JS_SP0, JS_GLOBAL (j)); + JS_PUSH (); + + if (vm->warn_undef && JS_SP1->type == JS_UNDEFINED) + { + sprintf (buf, "VM: warning: using undefined global `%s'%s", + js_vm_symname (vm, j), JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + } + } + break; + +/* operand jsr_w (74) */ +case 74: + /* Read the subroutine symbol index. */ + READ_INT32 (j); + + { + int found = 0; + + /* Loop over the with-chain. */ + /* WITHCHAIN */ + if (JS_WITHPTR->u.iptr) + { + JSUIntAlign *uip = JS_WITHPTR->u.iptr; + JSUIntAlign ui = *uip; + JSNode *wp = (JSNode *) ((unsigned char *) uip + + sizeof (JSUIntAlign)); + + for (i = 0; i < ui; i++) + { + JSNode *w = &wp[i]; + int result = JS_PROPERTY_UNKNOWN; + + if (w->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (w->u.vbuiltin->info->method_proc) + result = (*w->u.vbuiltin->info->method_proc) ( + vm, + w->u.vbuiltin->info, + w->u.vbuiltin->instance_context, j, + &builtin_result, JS_SP2); + JS_MAYBE_GC (); + + if (result == JS_PROPERTY_FOUND) + { + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + } + } + else if (w->type == JS_OBJECT) + { + JSNode method; + + js_vm_object_load_property (vm, w->u.vobject, j, &method); + if (method.type == JS_FUNC) + { + result = JS_PROPERTY_FOUND; + + /* The object defines the method. Do a subroutine call. */ + + /* First: replace the null `this' with `w'. */ + JS_COPY (JS_SP1, w); + + /* Then, do the normal subroutine call. */ + JS_SUBROUTINE_CALL (method.u.vfunction->implementation); + } + } + else + ERROR ("corrupted with-chain in jsr_w"); + + if (result == JS_PROPERTY_FOUND) + { + found = 1; + break; + } + } + } + + if (!found) + { + JSNode f; + + /* Call the global method. */ + JS_COPY (&f, JS_SP1); + function = &f; + + /* Reset the `this' to null. */ + JS_SP1->type = JS_NULL; + + if (function->type == JS_BUILTIN + && function->u.vbuiltin->info->global_method_proc) + { + JS_SAVE_REGS (); + (*function->u.vbuiltin->info->global_method_proc) ( + vm, + function->u.vbuiltin->info, + function->u.vbuiltin->instance_context, + &builtin_result, + JS_SP2); + + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + } + else if (function->type == JS_FUNC) + { + JS_SUBROUTINE_CALL (function->u.vfunction->implementation); + } + else + { + sprintf (buf, "symbol `%s' is undefined as function", + js_vm_symname (vm, j)); + ERROR (buf); + } + } + } + break; + diff --git a/reactos/lib/kjs/src/getopt.c b/reactos/lib/kjs/src/getopt.c new file mode 100644 index 00000000000..74002f10fd7 --- /dev/null +++ b/reactos/lib/kjs/src/getopt.c @@ -0,0 +1,1000 @@ +/* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu + before changing it! + + Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97 + Free Software Foundation, Inc. + + This file is part of the GNU C Library. Its master source is NOT part of + the C library, however. The master source lives in /gd/gnu/lib. + + The GNU C 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. + + The GNU C 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 the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in . + Ditto for AIX 3.2 and . */ +#ifndef _NO_PROTO +#define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +#include +#endif + +#if !defined (__STDC__) || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2 +#include +#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +#define ELIDE_CODE +#endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +#include +#include +#endif /* GNU C library. */ + +#ifdef VMS +#include +#if HAVE_STRING_H - 0 +#include +#endif +#endif + +#if defined (WIN32) && !defined (__CYGWIN32__) +/* It's not Unix, really. See? Capital letters. */ +#include +#define getpid() GetCurrentProcessId() +#endif + +#ifndef _ +/* This is for other GNU distributions with internationalized messages. + When compiling libc, the _ macro is predefined. */ +#ifdef HAVE_LIBINTL_H +# include +# define _(msgid) gettext (msgid) +#else +# define _(msgid) (msgid) +#endif +#endif + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#include "getopt.h" + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +char *optarg = NULL; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* 1003.2 says this must be 1 before any call. */ +int optind = 1; + +/* Formerly, initialization of getopt depended on optind==0, which + causes problems with re-calling getopt as programs generally don't + know that. */ + +int __getopt_initialized = 0; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +int optopt = '?'; + +/* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return -1 with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +#include +#define my_index strchr +#else + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +char *getenv (); + +static char * +my_index (str, chr) + const char *str; + int chr; +{ + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +#if !defined (__STDC__) || !__STDC__ +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int strlen (const char *); +#endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +#ifdef _LIBC +/* Bash 2.0 gives us an environment variable containing flags + indicating ARGV elements that should not be considered arguments. */ + +static const char *nonoption_flags; +static int nonoption_flags_len; + +static int original_argc; +static char *const *original_argv; + +/* Make sure the environment variable bash 2.0 puts in the environment + is valid for the getopt call we must make sure that the ARGV passed + to getopt is that one passed to the process. */ +static void store_args (int argc, char *const *argv) __attribute__ ((unused)); +static void +store_args (int argc, char *const *argv) +{ + /* XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ + original_argc = argc; + original_argv = argv; +} +text_set_element (__libc_subinit, store_args); +#endif + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +#if defined (__STDC__) && __STDC__ +static void exchange (char **); +#endif + +static void +exchange (argv) + char **argv; +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +#if defined (__STDC__) && __STDC__ +static const char *_getopt_initialize (int, char *const *, const char *); +#endif +static const char * +_getopt_initialize (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind = 1; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + +#ifdef _LIBC + if (posixly_correct == NULL + && argc == original_argc && argv == original_argv) + { + /* Bash 2.0 puts a special variable in the environment for each + command it runs, specifying which ARGV elements are the results of + file name wildcard expansion and therefore should not be + considered as options. */ + char var[100]; + sprintf (var, "_%d_GNU_nonoption_argv_flags_", getpid ()); + nonoption_flags = getenv (var); + if (nonoption_flags == NULL) + nonoption_flags_len = 0; + else + nonoption_flags_len = strlen (nonoption_flags); + } + else + nonoption_flags_len = 0; +#endif + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns -1. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longind; + int long_only; +{ + optarg = NULL; + + if (!__getopt_initialized || optind == 0) + { + optstring = _getopt_initialize (argc, argv, optstring); + optind = 1; /* Don't scan ARGV[0], the program name. */ + __getopt_initialized = 1; + } + + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ +#ifdef _LIBC +#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ + || (optind < nonoption_flags_len \ + && nonoption_flags[optind] == '1')) +#else +#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') +#endif + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (last_nonopt > optind) + last_nonopt = optind; + if (first_nonopt > optind) + first_nonopt = optind; + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc && NONOPTION_P) + optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if (NONOPTION_P) + { + if (ordering == REQUIRE_ORDER) + return -1; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) + == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (opterr) + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + optopt = 0; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (opterr) + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + _("%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + _("%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], pfound->name); + + nextchar += strlen (nextchar); + + optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (opterr) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) + { + if (opterr) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (opterr) + { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: illegal option -- %c\n"), + argv[0], c); + else + fprintf (stderr, _("%s: invalid option -- %c\n"), + argv[0], c); + } + optopt = c; + return '?'; + } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (opterr) + fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (opterr) + fprintf (stderr, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); + + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (opterr) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, + _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); +} + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == -1) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/reactos/lib/kjs/src/getopt.h b/reactos/lib/kjs/src/getopt.h new file mode 100644 index 00000000000..7dad11b79ff --- /dev/null +++ b/reactos/lib/kjs/src/getopt.h @@ -0,0 +1,133 @@ +/* Declarations for getopt. + Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc. + + This file is part of the GNU C Library. Its master source is NOT part of + the C library, however. The master source lives in /gd/gnu/lib. + + The GNU C 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. + + The GNU C 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 the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _GETOPT_H +#define _GETOPT_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ +#if defined (__STDC__) && __STDC__ + const char *name; +#else + char *name; +#endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +#if defined (__STDC__) && __STDC__ +#ifdef __GNU_LIBRARY__ +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int argc, char *const *argv, const char *shortopts); +#else /* not __GNU_LIBRARY__ */ +extern int getopt (); +#endif /* __GNU_LIBRARY__ */ +extern int getopt_long (int argc, char *const *argv, const char *shortopts, + const struct option *longopts, int *longind); +extern int getopt_long_only (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind, + int long_only); +#else /* not __STDC__ */ +extern int getopt (); +extern int getopt_long (); +extern int getopt_long_only (); + +extern int _getopt_internal (); +#endif /* __STDC__ */ + +#ifdef __cplusplus +} +#endif + +#endif /* _GETOPT_H */ diff --git a/reactos/lib/kjs/src/getopt1.c b/reactos/lib/kjs/src/getopt1.c new file mode 100644 index 00000000000..6690db0c0ba --- /dev/null +++ b/reactos/lib/kjs/src/getopt1.c @@ -0,0 +1,189 @@ +/* getopt_long and getopt_long_only entry points for GNU getopt. + Copyright (C) 1987,88,89,90,91,92,93,94,96,97 Free Software Foundation, Inc. + + This file is part of the GNU C Library. Its master source is NOT part of + the C library, however. The master source lives in /gd/gnu/lib. + + The GNU C 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. + + The GNU C 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 the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "getopt.h" + +#if !defined (__STDC__) || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2 +#include +#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +#define ELIDE_CODE +#endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +#include +#endif + +#ifndef NULL +#define NULL 0 +#endif + +int +getopt_long (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 0); +} + +/* Like getopt_long, but '-' as well as '--' can indicate a long option. + If an option that starts with '-' (not '--') doesn't match a long option, + but does match a short option, it is parsed as a short option + instead. */ + +int +getopt_long_only (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 1); +} + + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +#include + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = + { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + + c = getopt_long (argc, argv, "abc:d:0123456789", + long_options, &option_index); + if (c == -1) + break; + + switch (c) + { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case 'd': + printf ("option d with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/reactos/lib/kjs/src/heap.c b/reactos/lib/kjs/src/heap.c new file mode 100644 index 00000000000..293ec09386a --- /dev/null +++ b/reactos/lib/kjs/src/heap.c @@ -0,0 +1,586 @@ +/* + * Dynamic memory allocation. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/heap.c,v $ + * $Id: heap.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" + +/* + * Types and definitions. + */ + +#if SIZEOF_INT == 2 +#define BLOCK_SIZE (63 * 1024) +#else +#define BLOCK_SIZE (100 * 1024) +#endif + +/* + * The size of the minimum block that can be allocated from the heap. + * The block must be big enought to hold one pointer that is used when + * then block is entered to the freelist. + */ +#define MIN_ALLOC (sizeof (void *)) + +#if JS_MEM_DEBUG +#define MAGIC 0xfe109abe +#endif + +/* + * Prototypes for static functions. + */ + +static inline unsigned int +list (unsigned int size) +{ + unsigned int list = 0; + size >>= 3; + + while (size > 0) + { + size >>= 1; + list++; + } + if (list >= JS_NUM_HEAP_FREELISTS) + list = JS_NUM_HEAP_FREELISTS - 1; + + return list; +} + + +static inline void +delete_destroyable (JSHeapMemoryBlock *b) +{ + JSHeapDestroyable *destroyable + = (JSHeapDestroyable *) ((unsigned char *) b + + sizeof (JSHeapMemoryBlock)); + + if (destroyable->destroy) + (*destroyable->destroy) (destroyable); +} + + +static unsigned long +sweep (JSVirtualMachine *vm) +{ + JSHeapBlock *hb; + unsigned long bytes_in_use = 0; + int i; + unsigned int freelist; + + for (i = 0; i < JS_NUM_HEAP_FREELISTS; i++) + vm->heap_freelists[i] = NULL; + + vm->gc.bytes_free = 0; + vm->gc.bytes_allocated = 0; + + for (hb = vm->heap; hb; hb = hb->next) + { + JSHeapMemoryBlock *b, *e, *bnext; + + b = (JSHeapMemoryBlock *) ((unsigned char *) hb + sizeof (JSHeapBlock)); + e = (JSHeapMemoryBlock *) ((unsigned char *) hb + sizeof (JSHeapBlock) + + hb->size); + for (; b < e; b = bnext) + { +#if JS_MEM_DEBUG + assert (b->magic == MAGIC); +#endif + bnext = (JSHeapMemoryBlock *) ((unsigned char *) b + + sizeof (JSHeapMemoryBlock) + + b->size); + + if (b->flag_mark) + { + bytes_in_use += b->size; + b->flag_mark = 0; + vm->gc.bytes_allocated = b->size; + } + else + { + if (b->flag_destroyable) + delete_destroyable (b); + + /* Pack consecutive free blocks to one big block. */ + while (bnext < e && bnext->flag_mark == 0) + { +#if JS_MEM_DEBUG + assert (bnext->magic == MAGIC); +#endif + if (bnext->flag_destroyable) + delete_destroyable (bnext); + + b->size += bnext->size + sizeof (JSHeapMemoryBlock); + bnext = (JSHeapMemoryBlock *) ((unsigned char *) bnext + + sizeof (JSHeapMemoryBlock) + + bnext->size); + } + + JS_HEAP_MEMORY_BLOCK_CLEAR_FLAGS (b); + + /* Link it to the freelist. */ + freelist = list (b->size); + + ((JSHeapFreelistBlock *) b)->next = vm->heap_freelists[freelist]; + vm->heap_freelists[freelist] = b; + vm->gc.bytes_free += b->size; + } + } + } + + return bytes_in_use; +} + + +/* + * Global functions. + */ + +void * +js_vm_alloc (JSVirtualMachine *vm, unsigned int size) +{ + JSHeapMemoryBlock *b, *prev; + unsigned int alloc_size; + JSHeapBlock *hb; + unsigned int to_alloc; + unsigned int freelist; + char buf[512]; + + /* Round it up to the next pow of two. */ + for (alloc_size = MIN_ALLOC; alloc_size < size; alloc_size *= 2) + ; + + retry: + + /* Take first block from the freelist that is big enough for us. */ + for (freelist = list (alloc_size); freelist < JS_NUM_HEAP_FREELISTS; + freelist++) + for (prev = NULL, b = vm->heap_freelists[freelist]; b; + prev = b, b = ((JSHeapFreelistBlock *) b)->next) + if (b->size >= alloc_size) + { + /* Ok, take this one. */ + if (prev) + ((JSHeapFreelistBlock *) prev)->next + = ((JSHeapFreelistBlock *) b)->next; + else + vm->heap_freelists[freelist] = ((JSHeapFreelistBlock *) b)->next; + + if (b->size > alloc_size + sizeof (JSHeapMemoryBlock) + MIN_ALLOC) + { + JSHeapMemoryBlock *nb; + + /* We can split it. */ + nb = ((JSHeapMemoryBlock *) + ((unsigned char *) b + + sizeof (JSHeapMemoryBlock) + alloc_size)); + +#if JS_MEM_DEBUG + nb->magic = MAGIC; +#endif + JS_HEAP_MEMORY_BLOCK_CLEAR_FLAGS (nb); + nb->size = b->size - sizeof (JSHeapMemoryBlock) - alloc_size; + + vm->gc.bytes_free -= sizeof (JSHeapMemoryBlock); + + freelist = list (nb->size); + ((JSHeapFreelistBlock *) nb)->next + = vm->heap_freelists[freelist]; + vm->heap_freelists[freelist] = nb; + + b->size = alloc_size; + } + + JS_HEAP_MEMORY_BLOCK_CLEAR_FLAGS (b); + vm->gc.bytes_free -= b->size; + vm->gc.bytes_allocated += b->size; + + return (unsigned char *) b + sizeof (JSHeapMemoryBlock); + } + + /* Must allocate new blocks to the freelist. */ + + if (alloc_size > (BLOCK_SIZE + - sizeof (JSHeapBlock) + - sizeof (JSHeapMemoryBlock))) + to_alloc = alloc_size + sizeof (JSHeapBlock) + sizeof (JSHeapMemoryBlock); + else + to_alloc = BLOCK_SIZE; + + if (vm->verbose > 2) + { + sprintf (buf, + "VM: heap: malloc(%u): needed=%u, size=%lu, free=%lu, allocated=%lu%s", + to_alloc, alloc_size, vm->heap_size, vm->gc.bytes_free, + vm->gc.bytes_allocated, + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + + hb = js_malloc (vm, to_alloc); + + vm->heap_size += to_alloc; + hb->next = vm->heap; + vm->heap = hb; + hb->size = to_alloc - sizeof (JSHeapBlock); + + /* Link it to the freelist. */ + b = (JSHeapMemoryBlock *) ((unsigned char *) hb + sizeof (JSHeapBlock)); + +#if JS_MEM_DEBUG + b->magic = MAGIC; +#endif + JS_HEAP_MEMORY_BLOCK_CLEAR_FLAGS (b); + b->size = hb->size - sizeof (JSHeapMemoryBlock); + + freelist = list (b->size); + + ((JSHeapFreelistBlock *) b)->next = vm->heap_freelists[freelist]; + vm->heap_freelists[freelist] = b; + + vm->gc.bytes_free += b->size; + + goto retry; + + /* NOTRECHED */ + return NULL; +} + + +void * +js_vm_alloc_destroyable (JSVirtualMachine *vm, unsigned int size) +{ + unsigned char *bi; + JSHeapMemoryBlock *b; + + bi = js_vm_alloc (vm, size); + memset (bi, 0, size); + + b = (JSHeapMemoryBlock *) (bi - sizeof (JSHeapMemoryBlock)); + b->flag_destroyable = 1; + + return bi; +} + + +void * +js_vm_realloc (JSVirtualMachine *vm, void *ptr, unsigned int new_size) +{ + JSHeapMemoryBlock *b; + void *nptr; + + if (ptr == NULL) + return js_vm_alloc (vm, new_size); + + /* Can be use the old block? */ + + b = (JSHeapMemoryBlock *) ((unsigned char *) ptr + - sizeof (JSHeapMemoryBlock)); + +#if JS_MEM_DEBUG + assert (b->magic == MAGIC); +#endif + + if (b->size >= new_size) + /* Yes we can. */ + return ptr; + + /* No we can't. Must allocate a new one. */ + nptr = js_vm_alloc (vm, new_size); + memcpy (nptr, ptr, b->size < new_size ? b->size : new_size); + + js_vm_free (vm, ptr); + + return nptr; +} + + +void +js_vm_free (JSVirtualMachine *vm, void *ptr) +{ + JSHeapMemoryBlock *b; + unsigned int freelist; + + b = (JSHeapMemoryBlock *) ((unsigned char *) ptr + - sizeof (JSHeapMemoryBlock)); + +#if JS_MEM_DEBUG + assert (b->magic == MAGIC); +#endif + + freelist = list (b->size); + + ((JSHeapFreelistBlock *) b)->next = vm->heap_freelists[freelist]; + vm->heap_freelists[freelist] = b; + vm->gc.bytes_free += b->size; + + /* + * We could try to compact the heap, but we left it to the garbage + * collection. + */ +} + + +int +js_vm_mark_ptr (void *ptr) +{ + JSHeapMemoryBlock *b; + + if (ptr == NULL) + return 0; + + b = (JSHeapMemoryBlock *) ((unsigned char *) ptr + - sizeof (JSHeapMemoryBlock)); +#if JS_MEM_DEBUG + assert (b->magic == MAGIC); +#endif + + if (b->flag_mark) + return 0; + + b->flag_mark = 1; + + return 1; +} + + +int +js_vm_is_marked_ptr (void *ptr) +{ + JSHeapMemoryBlock *b; + + if (ptr == NULL) + return 1; + + b = (JSHeapMemoryBlock *) ((unsigned char *) ptr + - sizeof (JSHeapMemoryBlock)); +#if JS_MEM_DEBUG + assert (b->magic == MAGIC); +#endif + + if (b->flag_mark) + return 1; + + return 0; +} + + +void +js_vm_mark (JSNode *n) +{ + unsigned int i; + + switch (n->type) + { + case JS_UNDEFINED: + case JS_NULL: + case JS_BOOLEAN: + case JS_INTEGER: + case JS_FLOAT: + case JS_SYMBOL: + case JS_NAN: + case JS_IPTR: + case JS_ARGS_FIX: + /* Nothing here. */ + break; + + case JS_STRING: + js_vm_mark_ptr (n->u.vstring); + if (!n->u.vstring->staticp) + js_vm_mark_ptr (n->u.vstring->data); + + js_vm_object_mark (n->u.vstring->prototype); + break; + + case JS_OBJECT: + js_vm_object_mark (n->u.vobject); + break; + + case JS_ARRAY: + if (js_vm_mark_ptr (n->u.varray)) + { + js_vm_mark_ptr (n->u.varray->data); + + for (i = 0; i < n->u.varray->length; i++) + js_vm_mark (&n->u.varray->data[i]); + + js_vm_object_mark (n->u.varray->prototype); + } + break; + + case JS_BUILTIN: + if (js_vm_mark_ptr (n->u.vbuiltin)) + { + js_vm_mark_ptr (n->u.vbuiltin->info); + + js_vm_object_mark (n->u.vbuiltin->info->prototype); + js_vm_object_mark (n->u.vbuiltin->prototype); + + if (n->u.vbuiltin->info->mark_proc) + (*n->u.vbuiltin->info->mark_proc) ( + n->u.vbuiltin->info, + n->u.vbuiltin->instance_context); + } + break; + + case JS_FUNC: + js_vm_mark_ptr (n->u.vfunction); + js_vm_mark_ptr (n->u.vfunction->implementation); + js_vm_object_mark (n->u.vfunction->prototype); + break; + } +} + +#define GC_TIMES 0 + +void +js_vm_garbage_collect (JSVirtualMachine *vm, JSNode *fp, JSNode *sp) +{ + unsigned int i; + unsigned long bytes_in_use; + char buf[512]; +#if GC_TIMES + clock_t start_clock; + clock_t after_mark_clock; + clock_t after_sweep_clock; +#endif + + if (vm->verbose > 1) + { + sprintf (buf, + "VM: heap: garbage collect: num_consts=%u, num_globals=%u%s", + vm->num_consts, vm->num_globals, + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + + vm->gc.count++; + + /* Mark */ + +#if GC_TIMES + start_clock = clock (); +#endif + + /* Mark all constants. */ + for (i = 0; i < vm->num_consts; i++) + js_vm_mark (&vm->consts[i]); + + /* Mark all globals. */ + for (i = 0; i < vm->num_globals; i++) + js_vm_mark (&vm->globals[i]); + + /* Mark the buitin-infos of the core objects. */ + for (i = 0; i <= JS_IPTR; i++) + js_vm_mark_ptr (vm->prim[i]); + + /* Mark stack. */ + + /* STACKFRAME */ + + /* Use brute force and mark the whole stack. */ + for (sp++; sp < vm->stack + vm->stack_size; sp++) + { + if (sp->type == JS_IPTR) + { + /* Handle the stack frames here. */ + + /* Skip the return address. */ + sp++; + + /* Possible with-chain. */ + if (sp->u.iptr) + { + JSUIntAlign *uip = sp->u.iptr; + JSUIntAlign ui = *uip; + JSNode *wp; + + /* Mark the with-chain block. */ + js_vm_mark_ptr (uip); + + /* Mark the objects in the with-chain. */ + wp = (JSNode *) ((unsigned char *) uip + sizeof (JSUIntAlign)); + + for (i = 0; i < ui; i++) + js_vm_mark (&wp[i]); + + } + sp++; + + /* Skip the args_fix. */ + sp++; + + /* + * And now we point to the old_fp. We skip it too at the + * for-loop. + */ + } + else + /* Mark this stack item. */ + js_vm_mark (sp); + } + + /* Sweep all blocks and collect free nodes to the freelist. */ + +#if GC_TIMES + after_mark_clock = clock (); +#endif + + bytes_in_use = sweep (vm); + +#if GC_TIMES + after_sweep_clock = clock (); +#endif + + if (vm->verbose > 1) + { + sprintf (buf, "VM: heap: bytes_in_use=%lu, bytes_free=%lu%s", + bytes_in_use, vm->gc.bytes_free, + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + +#if GC_TIMES + if (vm->verbose > 1) + { + sprintf (buf, "VM: heap: mark_time=%.4f, sweep_time=%.4f%s", + (double) (after_mark_clock - start_clock) / CLOCKS_PER_SEC, + (double) (after_sweep_clock - after_mark_clock) + / CLOCKS_PER_SEC, + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } +#endif +} + + +void +js_vm_clear_heap (JSVirtualMachine *vm) +{ + /* Just sweep without marking. */ + sweep (vm); +} diff --git a/reactos/lib/kjs/src/iostream.c b/reactos/lib/kjs/src/iostream.c new file mode 100644 index 00000000000..b0db47f78aa --- /dev/null +++ b/reactos/lib/kjs/src/iostream.c @@ -0,0 +1,471 @@ +/* + * I/O streams. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/iostream.c,v $ + * $Id: iostream.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" + +/* + * Types and definitions. + */ + +#define DEFAULT_BUFFER_SIZE 4096 + +/* + * Global functions. + */ + +JSIOStream * +js_iostream_new () +{ + JSIOStream *stream; + + stream = js_calloc (NULL, 1, sizeof (*stream)); + if (stream == NULL) + return NULL; + + stream->buflen = DEFAULT_BUFFER_SIZE; + stream->buffer = js_malloc (NULL, stream->buflen); + if (stream->buffer == NULL) + { + js_free (stream); + return NULL; + } + + return stream; +} + + +/* The `FILE *' stream. */ + +static int +file_read (void *context, unsigned char *buffer, unsigned int todo, + int *error_return) +{ + int got; + + errno = 0; + got = fread (buffer, 1, todo, (FILE *) context); + *error_return = errno; + + return got; +} + + +static int +file_write (void *context, unsigned char *buffer, unsigned int todo, + int *error_return) +{ + int wrote; + + errno = 0; + wrote = fwrite (buffer, 1, todo, (FILE *) context); + *error_return = errno; + + return wrote; +} + + +static int +file_seek (void *context, long offset, int whence) +{ + return fseek ((FILE *) context, offset, whence); +} + + +static long +file_get_position (void *context) +{ + return ftell ((FILE *) context); +} + + +static long +file_get_length (void *context) +{ + FILE *fp = (FILE *) context; + long cpos; + long result = -1; + + /* Save current position. */ + cpos = ftell (fp); + if (cpos >= 0) + { + /* Seek to the end of the file. */ + if (fseek (fp, 0, SEEK_END) >= 0) + { + /* Fetch result. */ + result = ftell (fp); + + /* Seek back. */ + if (fseek (fp, cpos, SEEK_SET) < 0) + /* Couldn't revert the fp to the original position. */ + result = -1; + } + } + + return result; +} + + +static void +file_close (void *context) +{ + fclose ((FILE *) context); +} + + +JSIOStream * +js_iostream_file (FILE *fp, int readp, int writep, int do_close) +{ + JSIOStream *stream; + + if (fp == NULL) + return NULL; + + stream = js_iostream_new (); + if (stream == NULL) + return NULL; + + if (readp) + stream->read = file_read; + if (writep) + stream->write = file_write; + + stream->seek = file_seek; + stream->get_position = file_get_position; + stream->get_length = file_get_length; + + if (do_close) + stream->close = file_close; + + stream->context = fp; + + return stream; +} + + +static void +close_pipe (void *context) +{ + pclose ((FILE *) context); +} + + +JSIOStream * +js_iostream_pipe (FILE *fp, int readp) +{ + JSIOStream *stream; + + if (fp == NULL) + return NULL; + + stream = js_iostream_new (); + + if (stream == NULL) + return NULL; + + if (readp) + stream->read = file_read; + else + stream->write = file_write; + + stream->seek = file_seek; + stream->get_position = file_get_position; + stream->get_length = file_get_length; + stream->close = close_pipe; + stream->context = fp; + + return stream; +} + + +size_t +js_iostream_read (JSIOStream *stream, void *ptr, size_t size) +{ + size_t total = 0; + int got; + + if (stream->writep) + { + /* We have buffered output data. */ + if (js_iostream_flush (stream) == EOF) + return 0; + + assert (stream->writep == 0); + } + + while (size > 0) + { + /* First, take everything from the buffer. */ + if (stream->bufpos < stream->data_in_buf) + { + got = stream->data_in_buf - stream->bufpos; + + if (size < got) + got = size; + + memcpy (ptr, stream->buffer + stream->bufpos, got); + + stream->bufpos += got; + size -= got; + (unsigned char *) ptr += got; + total += got; + } + else + { + if (stream->at_eof) + /* EOF seen, can't read more. */ + break; + + js_iostream_fill_buffer (stream); + } + } + + return total; +} + + +size_t +js_iostream_write (JSIOStream *stream, void *ptr, size_t size) +{ + int space; + size_t total = 0; + + if (stream->write == NULL) + { + stream->error = EBADF; + return 0; + } + + if (!stream->writep && stream->bufpos < stream->data_in_buf) + { + /* + * We have some buffered data in the stream => the actual stream + * position in stream->context is not in sync with stream->bufpos. + * Seek back. + */ + + if ((*stream->seek) (stream->context, SEEK_CUR, + stream->bufpos - stream->data_in_buf) < 0) + /* XXX Error value. */ + return 0; + + stream->bufpos = 0; + stream->data_in_buf = 0; + } + + while (size > 0) + { + space = stream->buflen - stream->data_in_buf; + if (size < space) + space = size; + + /* Append data to the buffer. */ + memcpy (stream->buffer + stream->data_in_buf, ptr, space); + stream->data_in_buf += space; + total += space; + size -= space; + (unsigned char *) ptr += space; + + /* Now the buffer contains buffered write data. */ + stream->writep = 1; + + if (size > 0) + { + /* Still some data left. Must flush */ + if (js_iostream_flush (stream) == EOF) + return total; + } + } + + /* Autoflush. */ + if (stream->autoflush && stream->writep) + if (js_iostream_flush (stream) == EOF) + /* Failed. Just return something smaller than */ + return total - stream->data_in_buf; + + return total; +} + + +int +js_iostream_flush (JSIOStream *stream) +{ + if (stream == NULL || stream->write == NULL || !stream->writep) + return 0; + + stream->writep = 0; + assert (stream->bufpos == 0); + + if (stream->data_in_buf > 0) + { + int to_write = stream->data_in_buf; + + stream->data_in_buf = 0; + if ((*stream->write) (stream->context, stream->buffer, + to_write, &stream->error) < to_write) + { + stream->error = errno; + return EOF; + } + } + + return 0; +} + + +int +js_iostream_unget (JSIOStream *stream, int byte) +{ + if (stream->writep) + { + /* We have buffered output data. */ + if (js_iostream_flush (stream) == EOF) + return EOF; + + assert (stream->writep == 0); + } + + if (stream->bufpos > 0) + { + /* It fits. */ + stream->buffer[--stream->bufpos] = byte; + } + else if (stream->data_in_buf < stream->buflen) + { + move: + memmove (stream->buffer + 1, stream->buffer, stream->data_in_buf); + stream->data_in_buf++; + stream->buffer[0] = byte; + } + else + { + /* Allocate a bigger buffer. */ + unsigned char *new_buffer = js_realloc (NULL, stream->buffer, + stream->buflen + 1); + if (new_buffer == NULL) + { + stream->error = errno; + return EOF; + } + + stream->buflen++; + stream->buffer = new_buffer; + goto move; + } + + /* Upon successful completion, we must return the byte. */ + return byte; +} + + +int +js_iostream_close (JSIOStream *stream) +{ + int result = 0; + + if (stream == NULL) + return result; + + if (js_iostream_flush (stream) == EOF) + result = EOF; + + if (stream->close) + (*stream->close) (stream->context); + + js_free (stream->buffer); + js_free (stream); + + return result; +} + + +int +js_iostream_seek (JSIOStream *stream, long offset, int whence) +{ + int result; + + if (js_iostream_flush (stream) == EOF) + return -1; + + result = (*stream->seek) (stream->context, offset, whence); + if (result == 0) + /* Successful. Clear the eof flag. */ + stream->at_eof = 0; + + return result; +} + + +long +js_iostream_get_position (JSIOStream *stream) +{ + long pos; + + /* Flush the possible buffered output. */ + if (js_iostream_flush (stream) == EOF) + return -1; + + pos = (*stream->get_position) (stream->context); + if (pos < 0) + return pos; + + /* + * The logical position if at , the context's idea is at + * . Adjust. + */ + return pos - (stream->data_in_buf - stream->bufpos); +} + + +long +js_iostream_get_length (JSIOStream *stream) +{ + /* Flush the possible buffered output. */ + if (js_iostream_flush (stream) == EOF) + return -1; + + return (*stream->get_length) (stream->context); +} + + +void +js_iostream_fill_buffer (JSIOStream *stream) +{ + if (stream->read == NULL) + { + stream->at_eof = 1; + return; + } + + stream->data_in_buf = (*stream->read) (stream->context, stream->buffer, + stream->buflen, &stream->error); + stream->bufpos = 0; + if (stream->data_in_buf == 0) + stream->at_eof = 1; +} diff --git a/reactos/lib/kjs/src/js.1 b/reactos/lib/kjs/src/js.1 new file mode 100644 index 00000000000..09b80dc3970 --- /dev/null +++ b/reactos/lib/kjs/src/js.1 @@ -0,0 +1,234 @@ +.\" +.\" Manual page for the js interpreter. +.\" Copyright (c) 1998 New Generation Software (NGS) Oy +.\" Author: Markku Rossi +.\" +.\" 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 +.\" +.TH JS 1 "Sep 25, 1998" "JS" "JS" + +.SH NAME +js \- interpret, execute, and compile JavaScript files + +.SH SYNOPSIS +.B js +[\f3\-acfghlNStvV\f1] +[\f1\-d \f2type\f1] +[\f1\-e \f2code\f1] +[\f1\-O\f1[\f2level\f1]] +[\f1\-r \f2option\f1] +[\f1\-s \f2size\f1] +[\f1\-W \f2option\f1] +\f2file\f1 [\f2argument\f1]... + +.SH DESCRIPTION + +The \f3js\f1 program is the JavaScript interpreter command. It can be +used to execute JavaScript and JavaScript byte-code files. The progam +can also be used to compile JavaScript files into the byte-code files. + +.SH OPTIONS + +.TP 8 +.B \-a, \-\-annotate\-assembler +Annotate the created assembler listing with the original JavaScript +source code. The option can be used only with the \f3\-\-assembler\f1 +option. +.TP 8 +.B \-c, \-\-compile +Compile JavaScript files to byte\-code. The generated byte\-code is +saved to file which name is created from the name of the input file by +replacing the suffix \f3.js\f1 with the suffix \f3.jsc\f1. The +compilation can be controlled with options \f3\-\-debug\f1, +\f3\-\-optimize\f1, and \f3\-\-compiler-option\f1. +.TP 8 +.B \-d \f2type\f3, \-\-dispatch=\f2type\f3 +Use the byte-code instruction dispatch method \f2type\f1. The current +implementation supports the following dispatch methods: +.RS 8 +.TP 8 +.B switch\-basic +The basic switch-method using a big switch-case table to dispatch the +instruction. This method is available only if the interpreter has been +configured with the option \f3\-\-with\-all\-dispatchers\f1. +.TP 8 +.B switch +An optimized version of the switch\-method. This method is supported on +all environments. +.TP +.B jumps +The fastest dispatch method that uses the `computed goto' statement of +the GNU C\-compiler. This method is available if the interpreter has +been compiled with the GNU C\-compiler. +.RE +The default dispatch method, for environments that has the GNU +C-compiler, is \f3jumps\f1. For all other environments, the default +method is \f3switch\f1. +.TP +.B \-e \f2code\f1, \-\-eval=\f2code\f3 +Evaluate JavaScript code \f2code\f1. +.TP +.B \-f, \-\-file +Stop processing options and use the next argument as the name of the +JavaScript (or byte\-code) file. All the remaining arguments are +passed to the interpreter through the \f3ARGS\f1 array. The first +item of the array will be the name of the script, i.e. the argument +that follows the option \f3\-\-file\f1. +.TP +.B \-g, \-\-debug +Make the compiler to generate debugging information to the generated +byte\-code files. This option can be used with the option +\f3\-\-compile\f1. +.TP +.B \-h, \-\-help +Print a short help message that describes the options that can be given +to the \f3js\f1 program. +.TP +.B \-l, \-\-load +Load multiple JavaScript and JavaScript byte\-code files to the +interpreter. Normally, the first non\-option argument is evaluated +and all remaining arguments are passed to the script as arguments. +With the option \f3\-\-load\f1, multiple files can be loaded the to +the interpreter. The loading can be stopped with option +\f3\-\-file\f1 that specifies the last file to load. +.TP +.B \-N, \-\-no\-compiler +Do not define the compiler to the virtual machine. This option makes +the interpreter smaller, but the interpreter can only execute +pre\-compiled byte\-code files. The option disables the \f3eval\f1 +global method. +.TP +.B \-O \f1[\f2level\f1]\f3, \-\-optimize\f1[\f3=\f2level\f1]\f3 +Set the compiler optimization level to \f2level\f1. The compiler has +three different optimization levels: +.RS 8 +.TP 8 +.B 0 +Do not optimize. +.TP 8 +.B 1 +Perform all cheap optimizations which do not required heavy assembler +instruction analyzing. +.TP 8 +.B 2 +Perform all optimizations, supported by the compiler. +.RE +The default optimization level is 1. +.TP +.B \-r \f2option\f3, \-\-secure=\f2option\f3 +Turn on virtual machine security option \f2option\f1. The following +security options are available: +.RS 8 +.TP 8 +.B file +Disable insecure methods from the buit-in File object. +.TP 8 +.B system +Disable insecure methods from the buit-in System object. +.RE +.TP +.B \-s \f2size\f3, \-\-stack\-size=\f2size\f3 +Set the size of the virtual machine operand stack to \f2size\f1. The +size of the virtual machine operand stack is set at the startup\-time +and it can't be enlarged dynamically at the runtime. +.TP +.B \-S, \-\-assembler +Compile JavaScript files to JavaScript assembler. The generated +assembler listing is saved to file which name is created from the name +of the input file by replacing the suffix \f3.js\f1 with the suffix +\f3.jas\f1. The compilation can be controlled with options +\f3\-\-optimize\f1, and \f3\-\-compiler\-option\f1. +.TP +.B \-t, \-\-stacktrace +Print a stack trace on error. When an error occurs during the +evaluation of a script, the virtual machine will halt and the \f3js\f1 +program terminates. If the option \f3\-\-stacktrace\f1 was given to +the interpreter, the virtual machine will print a stack trace that +shows the call stack at the point of the error. +.TP +.B \-v, \-\-verbose +Increase the verbosity of the interpreter. The option can be given +multiple times to increase the amount of messages the interpreter +prints. +.TP +.B \-V, \-\-version +Print the version number of the \f3js\f1 program. +.TP +.B \-W \f3option\f3, \-\-compiler\-option=\f2option\f3 +Set JavaScript compiler options according to the option specification +\f2option\f1. The specification \f2option\f1 can be given in two +forms. In the normal form, the option specifies a compiler option +that should be set on. If the specification @var{option} starts with +the prefix `\f3no-\f1', the specified option will be turn off. The +following option specifications are currently implemented: +.RS 8 +.TP 8 +.B all +match most of the compile time options +.TP 8 +.B pedantic +match all compile time options. This option generates as much warnings +as possible. It will also complain about some things that are allowed +by the ECMAScript standard, but which are consired to show bad +programming style, for example, missing semicolons. +.TP 8 +.B runtime +match all runtime options +.TP 8 +.B shadow +warn if a variable declaration shadows a parameter +.TP 8 +.B undefined +runtime check for undefined global variables +.TP 8 +.B unused\-argument +warn about unused arguments +.TP 8 +.B unused-variable +warn about unused local variables +.TP 8 +.B with\-clobber +warn if the with\-lookup of a symbol is clobbered because the symbol is +defined to be a local variable or a function argument +.TP 8 +.B missing\-semicolon +warn about missing semicolons that are fixed by the missing semicolon +inserting during the compilation +.TP 8 +.B strict\-ecma +warn about things that are supported by this implementation, but are not +allowed by the ECMAScript standard. These features are: +.RS 8 +.TP 2 +\- line terminators in string and regular expression constant +.RE +.TP 8 +.B deprecated +warn if deprecated features has been used in the source code +.RE +.TP 8 +.B \-x, \-\-executable +Add execute permissions to the generated byte-code files. This option +is useful on Linux environments where JavaScript byte-code files can be +executed natively with the `binfmt_js' module. + +.SH AUTHOR +Markku Rossi + +NGS JavaScript WWW home page: + +.SH SEE ALSO +jsdas(1) diff --git a/reactos/lib/kjs/src/js.c b/reactos/lib/kjs/src/js.c new file mode 100644 index 00000000000..08ecee23878 --- /dev/null +++ b/reactos/lib/kjs/src/js.c @@ -0,0 +1,1684 @@ +/* + * JavaScript interpreter main glue. + * Copyright (c) 1998-1999 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/js.c,v $ + * $Id: js.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "js.h" +#include "jsint.h" + +/* + * Types and definitions. + */ + +/* Context for js_global_method_stub. */ +struct js_global_method_context_st +{ + JSGlobalMethodProc proc; + void *context; + JSFreeProc free_proc; + JSInterpPtr interp; +}; + +typedef struct js_global_method_context_st JSGlobalMethodContext; + +/* Context for user I/O function streams. */ +struct js_user_io_func_ctx_st +{ + JSIOFunc func; + void *context; + long position; +}; + +typedef struct js_user_io_func_ctx_st JSUserIOFuncCtx; + +struct js_method_reg_st +{ + JSSymbol sym; + char *name; + unsigned int flags; + JSMethodProc method; +}; + +typedef struct js_method_reg_st JSMethodReg; + +struct js_property_reg_st +{ + JSSymbol sym; + char *name; + unsigned int flags; + JSPropertyProc property; +}; + +typedef struct js_property_reg_st JSPropertyReg; + +/* The class handle. */ +struct js_class_st +{ + char *name; + JSInterpPtr interp; + + /* Flags. */ + unsigned int no_auto_destroy : 1; + unsigned int interned : 1; + + void *class_context; + JSFreeProc class_context_destructor; + + JSConstructor constructor; + + unsigned int num_methods; + JSMethodReg *methods; + + unsigned int num_properties; + JSPropertyReg *properties; +}; + +/* Object instance context. */ +struct js_object_instance_ctx_st +{ + void *instance_context; + JSFreeProc instance_context_destructor; +}; + +typedef struct js_object_instance_ctx_st JSObjectInstanceCtx; + + +/* + * Prototypes for static functions. + */ + +/* The module for JS' core global methods. */ +static void js_core_globals (JSInterpPtr interp); + +/* + * Helper function to evaluate source with compiler function + * . + */ +static int js_eval_source (JSInterpPtr interp, JSNode *source, + char *compiler_function); + +/* + * Helper function to compile source with compiler function + * . If is not NULL, the + * assembler listing of the compilation is saved to that file. If + * is not NULL, the byte_code data is saved to that + * file. If is not NULL, the resulting byte_code data is + * returned in it as a JavaScript string node. + */ +static int js_compile_source (JSInterpPtr interp, JSNode *source, + char *compiler_function, char *assembler_file, + char *byte_code_file, JSNode *bc_return); + +/* + * The stub function for global methods, created with the + * js_create_global_method() API function. + */ +static void js_global_method_stub (JSVirtualMachine *vm, + JSBuiltinInfo *builtin_info, + void *instance_context, + JSNode *result_return, + JSNode *args); + +/* + * Destructor for the global methods, created with the + * js_create_global_method() API function. + */ +static void js_global_method_delete (JSBuiltinInfo *builtin_info, + void *instance_context); + +static JSIOStream *iostream_iofunc (JSIOFunc func, void *context, + int readp, int writep); + + +/* + * Global functions. + */ + +const JSCharPtr +js_version () +{ + return VERSION; +} + + +void +js_init_default_options (JSInterpOptions *options) +{ + memset (options, 0, sizeof (*options)); + + options->stack_size = 2048; + options->dispatch_method = JS_VM_DISPATCH_JUMPS; + + options->warn_undef = 1; + + options->optimize_peephole = 1; + options->optimize_jumps_to_jumps = 1; + + options->fd_count = (unsigned long) -1; +} + + +JSInterpPtr +js_create_interp (JSInterpOptions *options) +{ + JSInterpPtr interp = NULL; + JSByteCode *bc; + JSInterpOptions default_options; + JSIOStream *s_stdin = NULL; + JSIOStream *s_stdout = NULL; + JSIOStream *s_stderr = NULL; + + /* + * Sanity check to assure that the js.h and jsint.h APIs share a + * same view to the world. + */ + assert (sizeof (JSNode) == sizeof (JSType)); + + interp = js_calloc (NULL, 1, sizeof (*interp)); + if (interp == NULL) + return NULL; + + if (options == NULL) + { + js_init_default_options (&default_options); + options = &default_options; + } + + memcpy (&interp->options, options, sizeof (*options)); + + /* The default system streams. */ + + if (options->s_stdin) + s_stdin = iostream_iofunc (options->s_stdin, options->s_context, 1, 0); + else + s_stdin = js_iostream_file (stdin, 1, 0, 0); + + if (s_stdin == NULL) + goto error_out; + + if (options->s_stdout) + s_stdout = iostream_iofunc (options->s_stdout, options->s_context, 0, 1); + else + s_stdout = js_iostream_file (stdout, 0, 1, 0); + + if (s_stdout == NULL) + goto error_out; + s_stdout->autoflush = 1; + + if (options->s_stderr) + s_stderr = iostream_iofunc (options->s_stderr, options->s_context, 0, 1); + else + s_stderr = js_iostream_file (stderr, 0, 1, 0); + + if (s_stderr == NULL) + goto error_out; + s_stderr->autoflush = 1; + + /* Create virtual machine. */ + interp->vm = js_vm_create (options->stack_size, + options->dispatch_method, + options->verbose, + options->stacktrace_on_error, + s_stdin, s_stdout, s_stderr); + if (interp->vm == NULL) + goto error_out; + + /* Set some options. */ + interp->vm->warn_undef = options->warn_undef; + + /* Set the security options. */ + + if (options->secure_builtin_file) + interp->vm->security |= JS_VM_SECURE_FILE; + if (options->secure_builtin_system) + interp->vm->security |= JS_VM_SECURE_SYSTEM; + + /* Set the event hook. */ + interp->vm->hook = options->hook; + interp->vm->hook_context = options->hook_context; + interp->vm->hook_operand_count_trigger = options->hook_operand_count_trigger; + + /* The file descriptor limit. */ + interp->vm->fd_count = options->fd_count; + + if (!options->no_compiler) + { + int result; + + /* Define compiler to the virtual machine. */ + bc = js_bc_read_data (js_compiler_bytecode, js_compiler_bytecode_len); + if (bc == NULL) + goto error_out; + + result = js_vm_execute (interp->vm, bc); + js_bc_free (bc); + if (!result) + goto error_out; + } + + /* Initialize our extensions. */ + if (!js_define_module (interp, js_core_globals)) + goto error_out; + + /* Ok, we'r done. */ + +#if 0 +#if JS_DEBUG_MEMORY_LEAKS + /* Let's see how much memory an empty interpreter takes. */ + js_alloc_dump_blocks (); +#endif /* JS_DEBUG_MEMORY_LEAKS */ +#endif + + return interp; + + + /* + * Error handling. + */ + + error_out: + + if (interp) + { + if (interp->vm) + js_vm_destroy (interp->vm); + js_free (interp); + } + + if (s_stdin) + js_iostream_close (s_stdin); + if (s_stdout) + js_iostream_close (s_stdout); + if (s_stderr) + js_iostream_close (s_stderr); + + return NULL; +} + + +void +js_destroy_interp (JSInterpPtr interp) +{ + js_vm_destroy (interp->vm); + js_free (interp); + +#if 0 +#if JS_DEBUG_MEMORY_LEAKS + /* Let's see how much memory we leak. */ + js_alloc_dump_blocks (); +#endif /* JS_DEBUG_MEMORY_LEAKS */ +#endif +} + + +const JSCharPtr +js_error_message (JSInterpPtr interp) +{ + return interp->vm->error; +} + + +void +js_result (JSInterpPtr interp, JSType *result_return) +{ + memcpy (result_return, &interp->vm->exec_result, sizeof (*result_return)); +} + + +int +js_eval (JSInterpPtr interp, char *code) +{ + JSNode source; + + js_vm_make_static_string (interp->vm, &source, code, strlen (code)); + return js_eval_source (interp, &source, "JSC$compile_string"); +} + + +int +js_eval_data (JSInterpPtr interp, char *data, unsigned int datalen) +{ + JSNode source; + + js_vm_make_static_string (interp->vm, &source, data, datalen); + return js_eval_source (interp, &source, "JSC$compile_string"); +} + + +int +js_eval_file (JSInterpPtr interp, char *filename) +{ + char *cp; + int result; + + cp = strrchr (filename, '.'); + if (cp && strcmp (cp, ".jsc") == 0) + { + run_bytecode: + result = js_execute_byte_code_file (interp, filename); + } + else if (cp && strcmp (cp, ".js") == 0) + { + try_javascript: + result = js_eval_javascript_file (interp, filename); + } + else + { + FILE *fp; + + /* Must look into the file. */ + + fp = fopen (filename, "r"); + if (fp) + { + int ch; + + if ((ch = getc (fp)) == '#') + { + /* Skip the first sh-command line. */ + while ((ch = getc (fp)) != EOF && ch != '\n') + ; + if (ch == EOF) + { + fclose (fp); + goto try_javascript; + } + } + else + ungetc (ch, fp); + + /* Check if we can read the file magic. */ + ch = getc (fp); + if (ch == 0xc0) + { + ch = getc (fp); + if (ch == 0x01) + { + ch = getc (fp); + if (ch == 'J') + { + ch = getc (fp); + if (ch == 'S') + { + /* Got it. We find a valid byte-code file magic. */ + fclose (fp); + goto run_bytecode; + } + } + } + } + + fclose (fp); + /* FALLTHROUGH */ + } + + /* + * If nothing else helps, we assume that the file contains JavaScript + * source code that must be compiled. + */ + goto try_javascript; + } + + return result; +} + + +int +js_eval_javascript_file (JSInterpPtr interp, char *filename) +{ + JSNode source; + + js_vm_make_static_string (interp->vm, &source, filename, strlen (filename)); + return js_eval_source (interp, &source, "JSC$compile_file"); +} + + +int +js_execute_byte_code_file (JSInterpPtr interp, char *filename) +{ + JSByteCode *bc; + FILE *fp; + int result; + + fp = fopen (filename, "rb"); + if (fp == NULL) + { + /* Let's borrow vm's error buffer. */ + sprintf (interp->vm->error, "couldn't open byte-code file \"%s\": %s", + filename, strerror (errno)); + return 0; + } + + bc = js_bc_read_file (fp); + fclose (fp); + + if (bc == NULL) + /* XXX Error message. */ + return 0; + + /* Execute it. */ + + result = js_vm_execute (interp->vm, bc); + js_bc_free (bc); + + return result; +} + + +int +js_apply (JSInterpPtr interp, char *name, unsigned int argc, JSType *argv) +{ + JSNode *args; + unsigned int ui; + int result; + + args = js_malloc (NULL, (argc + 1) * sizeof (JSNode)); + if (args == NULL) + { + sprintf (interp->vm->error, "VM: out of memory"); + return 0; + } + + /* Set the argument count. */ + args[0].type = JS_INTEGER; + args[0].u.vinteger = argc; + + /* Set the arguments. */ + for (ui = 0; ui < argc; ui++) + JS_COPY (&args[ui + 1], (JSNode *) &argv[ui]); + + /* Call it. */ + result = js_vm_apply (interp->vm, name, NULL, argc + 1, args); + + js_free (args); + + return result; +} + + +int +js_compile (JSInterpPtr interp, char *input_file, char *assembler_file, + char *byte_code_file) +{ + JSNode source; + + js_vm_make_static_string (interp->vm, &source, input_file, + strlen (input_file)); + return js_compile_source (interp, &source, "JSC$compile_file", + assembler_file, byte_code_file, NULL); +} + + +int +js_compile_to_byte_code (JSInterpPtr interp, char *input_file, + unsigned char **bc_return, + unsigned int *bc_len_return) +{ + JSNode source; + int result; + + js_vm_make_static_string (interp->vm, &source, input_file, + strlen (input_file)); + result = js_compile_source (interp, &source, "JSC$compile_file", + NULL, NULL, &source); + if (result == 0) + return 0; + + /* Pass the data to the caller. */ + *bc_return = source.u.vstring->data; + *bc_len_return = source.u.vstring->len; + + return result; +} + + +int +js_compile_data_to_byte_code (JSInterpPtr interp, char *data, + unsigned int datalen, + unsigned char **bc_return, + unsigned int *bc_len_return) +{ + JSNode source; + int result; + + js_vm_make_static_string (interp->vm, &source, data, datalen); + result = js_compile_source (interp, &source, "JSC$compile_string", + NULL, NULL, &source); + if (result == 0) + return 0; + + /* Pass the data to the caller. */ + *bc_return = source.u.vstring->data; + *bc_len_return = source.u.vstring->len; + + return result; +} + + +int +js_execute_byte_code (JSInterpPtr interp, unsigned char *bc_data, + unsigned int bc_data_len) +{ + JSByteCode *bc; + int result; + + bc = js_bc_read_data (bc_data, bc_data_len); + if (bc == NULL) + /* Not a valid byte-code data. */ + return 0; + + /* Execute it. */ + result = js_vm_execute (interp->vm, bc); + js_bc_free (bc); + + return result; +} + + +/* Classes. */ + +JSClassPtr +js_class_create (void *class_context, JSFreeProc class_context_destructor, + int no_auto_destroy, JSConstructor constructor) +{ + JSClassPtr cls; + + cls = js_calloc (NULL, 1, sizeof (*cls)); + if (cls == NULL) + return NULL; + + cls->class_context = class_context; + cls->class_context_destructor = class_context_destructor; + + cls->no_auto_destroy = no_auto_destroy; + cls->constructor = constructor; + + return cls; +} + + +void +js_class_destroy (JSClassPtr cls) +{ + if (cls == NULL) + return; + + if (cls->class_context_destructor) + (*cls->class_context_destructor) (cls->class_context); + + js_free (cls); +} + + +JSVoidPtr +js_class_context (JSClassPtr cls) +{ + if (cls) + return cls->class_context; + + return NULL; +} + + +int +js_class_define_method (JSClassPtr cls, char *name, unsigned int flags, + JSMethodProc method) +{ + JSMethodReg *nmethods; + + nmethods = js_realloc (NULL, cls->methods, + (cls->num_methods + 1) * sizeof (JSMethodReg)); + if (nmethods == NULL) + return 0; + + cls->methods = nmethods; + + /* + * The names are interned to symbols when the class is defined to the + * interpreter. + */ + + cls->methods[cls->num_methods].name = js_strdup (NULL, name); + if (cls->methods[cls->num_methods].name == NULL) + return 0; + + cls->methods[cls->num_methods].flags = flags; + cls->methods[cls->num_methods].method = method; + + cls->num_methods++; + + return 1; +} + + +int +js_class_define_property (JSClassPtr cls, char *name, unsigned int flags, + JSPropertyProc property) +{ + JSPropertyReg *nprops; + + nprops = js_realloc (NULL, cls->properties, + (cls->num_properties + 1) * sizeof (JSPropertyReg)); + if (nprops == NULL) + return 0; + + cls->properties = nprops; + + cls->properties[cls->num_properties].name = js_strdup (NULL, name); + if (cls->properties[cls->num_properties].name == NULL) + return 0; + + cls->properties[cls->num_properties].flags = flags; + cls->properties[cls->num_properties].property = property; + + cls->num_properties++; + + return 1; +} + + +/* The stub functions for JSClass built-in objects. */ + +/* Method proc. */ +static int +cls_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol method, JSNode *result_return, + JSNode *args) +{ + JSClassPtr cls = builtin_info->obj_context; + JSObjectInstanceCtx *ictx = instance_context; + int i; + JSMethodResult result; + char msg[1024]; + + /* Let's see if we know the method. */ + for (i = 0; i < cls->num_methods; i++) + if (cls->methods[i].sym == method) + { + /* Found it. */ + + /* Check flags. */ + if ((cls->methods[i].flags & JS_CF_STATIC) == 0 + && instance_context == NULL) + /* An instance method called from the `main' class. */ + break; + + result = (*cls->methods[i].method) (cls, + (ictx + ? ictx->instance_context + : NULL), + cls->interp, args[0].u.vinteger, + (JSType *) &args[1], + (JSType *) result_return, + msg); + if (result == JS_ERROR) + { + sprintf (vm->error, "%s.%s(): %s", cls->name, + cls->methods[i].name, msg); + js_vm_error (vm); + } + + return JS_PROPERTY_FOUND; + } + + return JS_PROPERTY_UNKNOWN; +} + +/* Property proc. */ +static int +cls_property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol property, int set, JSNode *node) +{ + JSClassPtr cls = builtin_info->obj_context; + JSObjectInstanceCtx *ictx = instance_context; + JSMethodResult result; + char msg[1024]; + int i; + + /* Find the property. */ + for (i = 0; i < cls->num_properties; i++) + if (cls->properties[i].sym == property) + { + /* Found it. */ + + /* Check flags. */ + + if ((cls->properties[i].flags & JS_CF_STATIC) == 0 + && instance_context == NULL) + break; + + if ((cls->properties[i].flags & JS_CF_IMMUTABLE) && set) + { + sprintf (vm->error, "%s.%s: immutable property", + cls->name, cls->properties[i].name); + js_vm_error (vm); + } + + result = (*cls->properties[i].property) (cls, + (ictx + ? ictx->instance_context + : NULL), + cls->interp, set, + (JSType *) node, msg); + if (result == JS_ERROR) + { + sprintf (vm->error, "%s.%s: %s", cls->name, + cls->properties[i].name, msg); + js_vm_error (vm); + } + + return JS_PROPERTY_FOUND; + } + + if (!set) + node->type = JS_UNDEFINED; + + return JS_PROPERTY_UNKNOWN; +} + +/* New proc. */ +static void +cls_new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, JSNode *args, + JSNode *result_return) +{ + JSClassPtr cls = builtin_info->obj_context; + JSMethodResult result; + char msg[1024]; + void *instance_context; + JSFreeProc instance_context_destructor; + JSObjectInstanceCtx *ictx; + + result = (*cls->constructor) (cls, cls->interp, args[0].u.vinteger, + (JSType *) &args[1], &instance_context, + &instance_context_destructor, + msg); + if (result == JS_ERROR) + { + sprintf (vm->error, "new %s(): %s", cls->name, msg); + js_vm_error (vm); + } + + ictx = js_calloc (vm, 1, sizeof (*ictx)); + ictx->instance_context = instance_context; + ictx->instance_context_destructor = instance_context_destructor; + + js_vm_builtin_create (vm, result_return, builtin_info, ictx); +} + + +/* Delete proc. */ +static void +cls_delete_proc (JSBuiltinInfo *builtin_info, void *instance_context) +{ + JSObjectInstanceCtx *ictx = instance_context; + + if (ictx) + { + if (ictx->instance_context_destructor) + (*ictx->instance_context_destructor) (ictx->instance_context); + + js_free (ictx); + } +} + +/* + * This is called to destroy the class handle, when there are no more + * references to it. + */ +static void +js_class_destructor (void *context) +{ + JSClassPtr cls = context; + + if (cls->no_auto_destroy) + return; + + js_class_destroy (cls); +} + + +static void +intern_symbols (JSVirtualMachine *vm, JSClassPtr cls) +{ + int i; + + for (i = 0; i < cls->num_methods; i++) + cls->methods[i].sym = js_vm_intern (vm, cls->methods[i].name); + + for (i = 0; i < cls->num_properties; i++) + cls->properties[i].sym = js_vm_intern (vm, cls->properties[i].name); + + cls->interned = 1; +} + + +static JSBuiltinInfo * +one_builtin_info_please (JSVirtualMachine *vm, JSClassPtr cls) +{ + JSBuiltinInfo *info; + + info = js_vm_builtin_info_create (vm); + + info->method_proc = cls_method; + info->property_proc = cls_property; + + if (cls->constructor) + { + info->new_proc = cls_new_proc; + info->delete_proc = cls_delete_proc; + } + + info->obj_context = cls; + info->obj_context_delete = js_class_destructor; + + return info; +} + + +int +js_define_class (JSInterpPtr interp, JSClassPtr cls, char *name) +{ + JSNode *n; + JSVirtualMachine *vm = interp->vm; + JSBuiltinInfo *info; + + /* XXX We need a top-level here */ + + cls->name = js_strdup (vm, name); + cls->interp = interp; + + if (!cls->interned) + /* Intern the symbols and properties. */ + intern_symbols (interp->vm, cls); + + /* Define it to the interpreter. */ + + info = one_builtin_info_please (vm, cls); + + n = &vm->globals[js_vm_intern (vm, name)]; + js_vm_builtin_create (vm, n, info, NULL); + + return 1; +} + + +int +js_instantiate_class (JSInterpPtr interp, JSClassPtr cls, void *ictx, + JSFreeProc ictx_destructor, JSType *result_return) +{ + JSObjectInstanceCtx *instance; + JSVirtualMachine *vm = interp->vm; + JSBuiltinInfo *info; + + if (!cls->interned) + /* Intern the symbols and properties. */ + intern_symbols (vm, cls); + + /* Create an instance. */ + instance = js_calloc (vm, 1, sizeof (*instance)); + instance->instance_context = ictx; + instance->instance_context_destructor = ictx_destructor; + + /* Create a fresh builtin info. */ + info = one_builtin_info_please (vm, cls); + + /* And create it. */ + js_vm_builtin_create (vm, (JSNode *) result_return, info, instance); + + return 1; +} + + +const JSClassPtr +js_lookup_class (JSInterpPtr interp, char *name) +{ + JSNode *n; + JSVirtualMachine *vm = interp->vm; + + n = &vm->globals[js_vm_intern (vm, name)]; + if (n->type != JS_BUILTIN) + return NULL; + + if (n->u.vbuiltin->info->method_proc != cls_method) + /* This is a wrong built-in. */ + return NULL; + + return (JSClassPtr) n->u.vbuiltin->info->obj_context; +} + + +int +js_isa (JSInterpPtr interp, JSType *object, JSClassPtr cls, + void **instance_context_return) +{ + JSNode *n = (JSNode *) object; + JSObjectInstanceCtx *instance; + + if (n->type != JS_BUILTIN || n->u.vbuiltin->info->obj_context != cls + || n->u.vbuiltin->instance_context == NULL) + return 0; + + if (instance_context_return) + { + instance = (JSObjectInstanceCtx *) n->u.vbuiltin->instance_context; + *instance_context_return = instance->instance_context; + } + + return 1; +} + + + +/* Type functions. */ + +void +js_type_make_string (JSInterpPtr interp, JSType *type, unsigned char *data, + unsigned int length) +{ + JSNode *n = (JSNode *) type; + + js_vm_make_string (interp->vm, n, data, length); +} + + +void +js_type_make_array (JSInterpPtr interp, JSType *type, unsigned int length) +{ + JSNode *n = (JSNode *) type; + + js_vm_make_array (interp->vm, n, length); +} + + +void +js_set_var (JSInterpPtr interp, char *name, JSType *value) +{ + JSNode *n = &interp->vm->globals[js_vm_intern (interp->vm, name)]; + JS_COPY (n, (JSNode *) value); +} + + +void +js_get_var (JSInterpPtr interp, char *name, JSType *value) +{ + JSNode *n = &interp->vm->globals[js_vm_intern (interp->vm, name)]; + JS_COPY ((JSNode *) value, n); +} + + +void +js_get_options (JSInterpPtr interp, JSInterpOptions *options) +{ + memcpy (options, &interp->options, sizeof (*options)); +} + + +void +js_set_options (JSInterpPtr interp, JSInterpOptions *options) +{ + memcpy (&interp->options, options, sizeof (*options)); + + /* User can change the security options, */ + + if (interp->options.secure_builtin_file) + interp->vm->security |= JS_VM_SECURE_FILE; + else + interp->vm->security &= ~JS_VM_SECURE_FILE; + + if (interp->options.secure_builtin_system) + interp->vm->security |= JS_VM_SECURE_SYSTEM; + else + interp->vm->security &= ~JS_VM_SECURE_SYSTEM; + + /* and the event hook. */ + interp->vm->hook = options->hook; + interp->vm->hook_context = options->hook_context; + interp->vm->hook_operand_count_trigger = options->hook_operand_count_trigger; +} + + +int +js_create_global_method (JSInterpPtr interp, char *name, + JSGlobalMethodProc proc, void *context, + JSFreeProc context_free_proc) +{ + JSNode *n = &interp->vm->globals[js_vm_intern (interp->vm, name)]; + JSVirtualMachine *vm = interp->vm; + int result = 1; + + /* Need one toplevel here. */ + { + JSErrorHandlerFrame handler; + + /* We must create the toplevel ourself. */ + memset (&handler, 0, sizeof (handler)); + handler.next = vm->error_handler; + vm->error_handler = &handler; + + if (setjmp (vm->error_handler->error_jmp)) + /* An error occurred. */ + result = 0; + else + { + JSBuiltinInfo *info; + JSGlobalMethodContext *ctx; + + /* Context. */ + ctx = js_calloc (vm, 1, sizeof (*ctx)); + + ctx->proc = proc; + ctx->context = context; + ctx->free_proc = context_free_proc; + ctx->interp = interp; + + /* Info. */ + info = js_vm_builtin_info_create (vm); + info->global_method_proc = js_global_method_stub; + info->delete_proc = js_global_method_delete; + + /* Create the builtin. */ + js_vm_builtin_create (interp->vm, n, info, ctx); + } + + /* Pop the error handler. */ + vm->error_handler = vm->error_handler->next; + } + + return result; +} + + +int +js_define_module (JSInterpPtr interp, JSModuleInitProc init_proc) +{ + JSErrorHandlerFrame handler; + JSVirtualMachine *vm = interp->vm; + int result = 1; + + /* Just call the init proc in a toplevel. */ + + memset (&handler, 0, sizeof (handler)); + handler.next = vm->error_handler; + vm->error_handler = &handler; + + if (setjmp (vm->error_handler->error_jmp)) + /* An error occurred. */ + result = 0; + else + /* Call the module init proc. */ + (*init_proc) (interp); + + /* Pop the error handler. */ + vm->error_handler = vm->error_handler->next; + + return result; +} + + + +/* + * Static functions. + */ + +static int +js_eval_source (JSInterpPtr interp, JSNode *source, char *compiler_function) +{ + JSNode argv[5]; + int i = 0; + int result; + JSByteCode *bc; + + /* Let's compile the code. */ + + /* Argument count. */ + argv[i].type = JS_INTEGER; + argv[i].u.vinteger = 4; + i++; + + /* Source to compiler. */ + JS_COPY (&argv[i], source); + i++; + + /* Flags. */ + argv[i].type = JS_INTEGER; + argv[i].u.vinteger = 0; + + if (interp->options.verbose) + argv[i].u.vinteger = JSC_FLAG_VERBOSE; + + argv[i].u.vinteger |= JSC_FLAG_GENERATE_DEBUG_INFO; + + argv[i].u.vinteger |= JSC_FLAG_OPTIMIZE_PEEPHOLE; + argv[i].u.vinteger |= JSC_FLAG_OPTIMIZE_JUMPS; + argv[i].u.vinteger |= JSC_FLAG_WARN_WITH_CLOBBER; + i++; + + /* Assembler file. */ + argv[i].type = JS_NULL; + i++; + + /* Byte-code file. */ + argv[i].type = JS_NULL; + i++; + + /* Call the compiler entry point. */ + result = js_vm_apply (interp->vm, compiler_function, NULL, i, argv); + if (result == 0) + return 0; + + /* + * The resulting byte-code file is now at vm->exec_result. + * + * Note! The byte-code is a string allocated form the vm heap. + * The garbage collector can free it when it wants since the result + * isn't protected. However, we have no risk here because we + * first convert the byte-code data block to our internal + * JSByteCode block that shares no memory with the original data. + */ + + assert (interp->vm->exec_result.type == JS_STRING); + + bc = js_bc_read_data (interp->vm->exec_result.u.vstring->data, + interp->vm->exec_result.u.vstring->len); + + /* And finally, execute it. */ + result = js_vm_execute (interp->vm, bc); + + /* Free the byte-code. */ + js_bc_free (bc); + + return result; +} + + +static int +js_compile_source (JSInterpPtr interp, JSNode *source, + char *compiler_function, char *assembler_file, + char *byte_code_file, JSNode *bc_return) +{ + JSNode argv[5]; + int i = 0; + int result; + + /* Init arguments. */ + + argv[i].type = JS_INTEGER; + argv[i].u.vinteger = 4; + i++; + + /* Source to compiler. */ + JS_COPY (&argv[1], source); + i++; + + /* Flags. */ + argv[i].type = JS_INTEGER; + argv[i].u.vinteger = 0; + + if (interp->options.verbose) + argv[i].u.vinteger |= JSC_FLAG_VERBOSE; + if (interp->options.annotate_assembler) + argv[i].u.vinteger |= JSC_FLAG_ANNOTATE_ASSEMBLER; + if (interp->options.debug_info) + argv[i].u.vinteger |= JSC_FLAG_GENERATE_DEBUG_INFO; + if (interp->options.executable_bc_files) + argv[i].u.vinteger |= JSC_FLAG_GENERATE_EXECUTABLE_BC_FILES; + + if (interp->options.warn_unused_argument) + argv[i].u.vinteger |= JSC_FLAG_WARN_UNUSED_ARGUMENT; + if (interp->options.warn_unused_variable) + argv[i].u.vinteger |= JSC_FLAG_WARN_UNUSED_VARIABLE; + if (interp->options.warn_shadow) + argv[i].u.vinteger |= JSC_FLAG_WARN_SHADOW; + if (interp->options.warn_with_clobber) + argv[i].u.vinteger |= JSC_FLAG_WARN_WITH_CLOBBER; + if (interp->options.warn_missing_semicolon) + argv[i].u.vinteger |= JSC_FLAG_WARN_MISSING_SEMICOLON; + if (interp->options.warn_strict_ecma) + argv[i].u.vinteger |= JSC_FLAG_WARN_STRICT_ECMA; + if (interp->options.warn_deprecated) + argv[i].u.vinteger |= JSC_FLAG_WARN_DEPRECATED; + + if (interp->options.optimize_peephole) + argv[i].u.vinteger |= JSC_FLAG_OPTIMIZE_PEEPHOLE; + if (interp->options.optimize_jumps_to_jumps) + argv[i].u.vinteger |= JSC_FLAG_OPTIMIZE_JUMPS; + if (interp->options.optimize_bc_size) + argv[i].u.vinteger |= JSC_FLAG_OPTIMIZE_BC_SIZE; + if (interp->options.optimize_heavy) + argv[i].u.vinteger |= JSC_FLAG_OPTIMIZE_HEAVY; + + i++; + + /* Assembler file. */ + if (assembler_file) + js_vm_make_static_string (interp->vm, &argv[i], assembler_file, + strlen (assembler_file)); + else + argv[i].type = JS_NULL; + i++; + + /* Byte-code file. */ + if (byte_code_file) + js_vm_make_static_string (interp->vm, &argv[i], byte_code_file, + strlen (byte_code_file)); + else + argv[i].type = JS_NULL; + i++; + + /* Call the compiler entry point. */ + result = js_vm_apply (interp->vm, compiler_function, NULL, i, argv); + if (result == 0) + return 0; + + if (bc_return) + /* User wanted to get the resulting byte-code data. Here it is. */ + JS_COPY (bc_return, &interp->vm->exec_result); + + return result; +} + + +/* + * Global methods. + */ + +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) + { + /* Return it to the caller. */ + JS_COPY (result_return, &args[1]); + return; + } + + /* + * 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. Throw it as an error to our caller. */ + js_vm_error (vm); + } + + /* Pass the return value to our caller. */ + JS_COPY (result_return, &vm->exec_result); +} + + +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; +} + + +static void +load_class_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, + JSNode *result_return, JSNode *args) +{ + JSInterpPtr interp = instance_context; + int i; + + if (args->u.vinteger == 0) + { + sprintf (vm->error, "loadClass(): no arguments given"); + js_vm_error (vm); + } + + for (i = 1; i <= args->u.vinteger; i++) + { + char *cp, *cp2; + void *lib; + void (*func) (JSInterpPtr interp); + char *func_name; + char buf[512]; + + if (args[i].type != JS_STRING) + { + sprintf (vm->error, "loadClass(): illegal argument"); + js_vm_error (vm); + } + + cp = js_string_to_c_string (vm, &args[i]); + + /* Extract the function name. */ + func_name = strrchr (cp, ':'); + if (func_name == NULL) + { + func_name = strrchr (cp, '/'); + if (func_name == NULL) + func_name = cp; + else + func_name++; + } + else + { + *func_name = '\0'; + func_name++; + } + + /* Try to open the library. */ + lib = js_dl_open (cp, buf, sizeof (buf)); + if (lib == NULL) + { + sprintf (vm->error, "loadClass(): couldn't open library `%s': %s", + cp, buf); + js_vm_error (vm); + } + + /* + * Strip all suffixes from the library name: if the + * is extracted from it, this will convert the library name + * `foo.so.x.y' to the canonical entry point name `foo'. + */ + cp2 = strchr (cp, '.'); + if (cp2) + *cp2 = '\0'; + + func = js_dl_sym (lib, func_name, buf, sizeof (buf)); + if (func == NULL) + { + sprintf (vm->error, + "loadClass(): couldn't find the init function `%s': %s", + func_name, buf); + js_vm_error (vm); + } + + /* All done with this argument. */ + js_free (cp); + + /* + * And finally, call the library entry point. All possible errors + * will throw us to the containing top-level. + */ + (*func) (interp); + } + + result_return->type = JS_UNDEFINED; +} + + +static void +call_method_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, + JSNode *result_return, JSNode *args) +{ + JSInterpPtr interp = instance_context; + JSNode *argv; + int i; + int result; + char *cp; + + if (args->u.vinteger != 3) + { + sprintf (vm->error, "callMethod(): illegal amount of arguments"); + js_vm_error (vm); + } + if (args[2].type != JS_STRING) + { + illegal_argument: + sprintf (vm->error, "callMethod(): illegal argument"); + js_vm_error (vm); + } + if (args[3].type != JS_ARRAY) + goto illegal_argument; + + /* Create the argument array. */ + argv = js_malloc (vm, (args[3].u.varray->length + 1) * sizeof (JSNode)); + + /* The argument count. */ + argv[0].type = JS_INTEGER; + argv[0].u.vinteger = args[3].u.varray->length; + + for (i = 0; i < args[3].u.varray->length; i++) + JS_COPY (&argv[i + 1], &args[3].u.varray->data[i]); + + /* Method name to C string. */ + cp = js_string_to_c_string (vm, &args[2]); + + /* Call it. */ + result = js_vm_call_method (vm, &args[1], cp, args[3].u.varray->length + 1, + argv); + + /* Cleanup. */ + js_free (cp); + js_free (argv); + + if (result) + JS_COPY (result_return, &vm->exec_result); + else + /* The error message is already there. */ + js_vm_error (vm); +} + + +static void +js_core_globals (JSInterpPtr interp) +{ + JSNode *n; + JSBuiltinInfo *info; + JSVirtualMachine *vm = interp->vm; + + if (!interp->options.no_compiler) + { + /* Command `eval'. */ + + info = js_vm_builtin_info_create (vm); + info->global_method_proc = eval_global_method; + + n = &interp->vm->globals[js_vm_intern (interp->vm, "eval")]; + + js_vm_builtin_create (interp->vm, n, info, interp); + } + + /* Command `load'. */ + + info = js_vm_builtin_info_create (vm); + info->global_method_proc = load_global_method; + + n = &interp->vm->globals[js_vm_intern (interp->vm, "load")]; + js_vm_builtin_create (interp->vm, n, info, interp); + + /* Command `loadClass'. */ + + info = js_vm_builtin_info_create (vm); + info->global_method_proc = load_class_global_method; + + n = &interp->vm->globals[js_vm_intern (interp->vm, "loadClass")]; + js_vm_builtin_create (interp->vm, n, info, interp); + + /* Command `callMethod'. */ + + info = js_vm_builtin_info_create (vm); + info->global_method_proc = call_method_global_method; + + n = &interp->vm->globals[js_vm_intern (interp->vm, "callMethod")]; + js_vm_builtin_create (interp->vm, n, info, interp); +} + + +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); +} + + +static void +js_global_method_delete (JSBuiltinInfo *builtin_info, void *instance_context) +{ + JSGlobalMethodContext *ctx = instance_context; + + if (ctx) + { + if (ctx->free_proc) + (*ctx->free_proc) (ctx->context); + + js_free (ctx); + } +} + + +/* I/O Stream to user I/O function. */ + +static int +iofunc_io (void *context, unsigned char *buffer, unsigned int todo, + int *error_return) +{ + JSUserIOFuncCtx *ctx = context; + int moved; + + *error_return = 0; + + moved = (*ctx->func) (ctx->context, buffer, todo); + if (moved >= 0) + ctx->position += moved; + + return moved; +} + + +static int +iofunc_seek (void *context, long offset, int whence) +{ + return -1; +} + + +static long +iofunc_get_position (void *context) +{ + JSUserIOFuncCtx *ctx = context; + + return ctx->position; +} + + +static long +iofunc_get_length (void *context) +{ + return -1; +} + + +static void +iofunc_close (void *context) +{ + js_free (context); +} + + +static JSIOStream * +iostream_iofunc (JSIOFunc func, void *context, int readp, int writep) +{ + JSIOStream *stream = js_iostream_new (); + JSUserIOFuncCtx *ctx; + + if (stream == NULL) + return NULL; + + ctx = js_malloc (NULL, sizeof (*ctx)); + if (ctx == NULL) + { + (void) js_iostream_close (stream); + return NULL; + } + + /* Init context. */ + ctx->func = func; + ctx->context = context; + ctx->position = 0; + + if (readp) + stream->read = iofunc_io; + if (writep) + stream->write = iofunc_io; + + stream->seek = iofunc_seek; + stream->get_position = iofunc_get_position; + stream->get_length = iofunc_get_length; + stream->close = iofunc_close; + stream->context = ctx; + + return stream; +} diff --git a/reactos/lib/kjs/src/main.c b/reactos/lib/kjs/src/main.c new file mode 100644 index 00000000000..bd1479b3575 --- /dev/null +++ b/reactos/lib/kjs/src/main.c @@ -0,0 +1,831 @@ +/* + * The JS shell + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/main.c,v $ + * $Id: main.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#if HAVE_CONFIG_H +#include "jsconfig.h" +#endif + +#include +#include + +#if HAVE_STDC_HEADERS +#include +#include +#include + +#else /* not HAVE_STDC_HEADERS */ + +#if HAVE_STDLIB_H +#include +#endif + +#if HAVE_STRING_H +#include +#endif + +#if HAVE_UNISTD_H +#include +#endif + +#endif /* not HAVE_STDC_HEADERS */ + +#include "js.h" +#include "getopt.h" + +/* + * Global variables. + */ + +char *program; + +/* Options. */ + +/* + * -a, --annotate-assembler + * + * Annotate generated assembler listing with the original source code. + */ + +int annotate_assembler = 0; + +/* + * -c, --compile + * + * Compile all given JavaScript files to byte-code and save the result + * to file. + */ + +int compile = 0; + +/* + * -d METHOD, --dispatch=METHOD + * + * Use byte-code instruction dispatch method METHOD. Possible values are + * `switch', `switch-basic' and `jumps'. + */ + +JSVMDispatchMethod dispatch_method = JS_VM_DISPATCH_JUMPS; + +/* + * -e CODE, --eval=CODE + * + * Evaluate JavaScript code CODE. + */ + +/* + * -E, --events + * + * Print virtual machine events to the standard error. + */ +int events = 0; + +/* + * -f, --file + * + * Use the next argument as the main source file and pass all + * remaining arguments to it through the ARGS array. + */ + +/* + * -g, --debug + * + * Generate debugging information to the generated byte-code file. + */ +int generate_debug_info = 0; + +/* + * -h, --help + * + * Print short help and exit successfully. + */ + +/* + * -l, --load + * + * Treat all following arguments, up to option -f / --file, as + * byte-code or JavaScript files and execute them. When option -f, --file + * is encountered, the next argument is the actual main source file that + * is executed with the remaining arguments. + */ + +/* + * -N, --no-compiler + * + * Do not define compiler in the interpreter. Options makes the + * interpreter a pure virtual machine that can't compile any JavaScript + * code. + */ + +int no_compiler = 0; + +/* + * -O [LEVEL], --optimize[=LEVEL] + * + * Optimize at level LEVEL. The default level for batch-compile is 1. + * Value 0 disable optimization. + */ + +int optimize = 1; + +/* + * -r OPTION, --secure=OPTIONS + * + * Turn on security option OPTION. + */ + +int secure_builtin_file = 0; +int secure_builtin_system = 0; + +/* + * -s SIZE, --stack-size=SIZE + * + * Set the virtual machine stack size to SIZE. + */ +unsigned int stack_size = 2048; + +/* + * -S, --no-assemble + * + * Compile al given JavaScript files to JavaScript assembler and save the + * result to file. + */ + +int no_assemble = 0; + +/* + * -t, --stacktrace + * + * Print stack trace on error. + */ + +int stacktrace_on_error = 0; + +/* + * -v, --verbose + * + * Tell more about what we do. + */ + +unsigned int verbose = 0; + +/* + * -V, --version + * + * Print version information and exit successfully. + */ + +/* + * -W OPTION, --compiler-option=OPTION + * + * Set compiler option OPTION. + */ + +int warn_deprecated = 0; +int warn_unused_argument = 0; +int warn_unused_variable = 1; +int warn_undef = 1; +int warn_shadow = 1; +int warn_with_clobber = 1; +int warn_missing_semicolon = 0; +int warn_strict_ecma = 0; + +/* + * -x, --executable + * + * Generate executable byte-code files. + */ +int generate_executable_bc_files = 0; + + +/* + * Static variables. + */ + +static struct option long_options[] = +{ + {"annotate-assembler", no_argument, 0, 'a'}, + {"compile", no_argument, 0, 'c'}, + {"dispatch", required_argument, 0, 'd'}, + {"eval", required_argument, 0, 'e'}, + {"events", no_argument, 0, 'E'}, + {"file", no_argument, 0, 'f'}, + {"debug", no_argument, 0, 'g'}, + {"help", no_argument, 0, 'h'}, + {"load", no_argument, 0, 'l'}, + {"no-compiler", no_argument, 0, 'N'}, + {"optimize", optional_argument, 0, 'O'}, + {"secure", required_argument, 0, 'r'}, + {"stack-size", required_argument, 0, 's'}, + {"no-assemble", no_argument, 0, 'S'}, + {"stacktrace", no_argument, 0, 't'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"compiler-option", required_argument, 0, 'W'}, + {"executable", no_argument, 0, 'x'}, + + {NULL, 0, 0, 0}, +}; + +/* Compiler options. */ + +/* Flags for options. */ +#define JSC_RUNTIME 0x01 +#define JSC_WALL 0x02 +#define JSC_PEDANTIC 0x04 +#define JSC_LINT 0x08 + +static struct +{ + char *name; + int *option; + unsigned int flags; +} compiler_options[] = +{ + {"deprecated", &warn_deprecated, JSC_WALL}, + {"unused-argument", &warn_unused_argument, JSC_WALL}, + {"unused-variable", &warn_unused_variable, JSC_WALL}, + {"undefined", &warn_undef, JSC_RUNTIME}, + {"shadow", &warn_shadow, JSC_WALL}, + {"with-clobber", &warn_with_clobber, JSC_WALL}, + {"missing-semicolon", &warn_missing_semicolon, JSC_PEDANTIC}, + {"strict-ecma", &warn_strict_ecma, JSC_LINT}, + + {NULL, NULL, 0}, +}; + + +/* + * Prototypes for static functions. + */ + +static void handle_compiler_option (char *name); + +static JSInterpPtr create_interp (void); + +static void usage (void); +static void version (void); + +/* + * Global functions. + */ + +int +main (int argc, char *argv[]) +{ + JSInterpPtr interp = NULL; + char *cp; + int do_load = 0; + + /* Get program's name. */ + program = strrchr (argv[0], '/'); + if (program == NULL) + program = argv[0]; + else + program++; + + /* Make getopt_long() to use our modified program name. */ + argv[0] = program; + + /* Parse arguments. */ + while (1) + { + int c; + int option_index = 0; + + c = getopt_long (argc, argv, "acd:e:EfghlNO::r:s:StvVW:x", + long_options, &option_index); + if (c == EOF) + break; + + switch (c) + { + case 'a': /* --annotate-assembler */ + annotate_assembler = 1; + break; + + case 'c': /* --compile */ + compile = 1; + break; + + case 'd': /* --dispatch */ + if (strcmp (optarg, "switch-basic") == 0) + dispatch_method = JS_VM_DISPATCH_SWITCH_BASIC; + else if (strcmp (optarg, "switch") == 0) + dispatch_method = JS_VM_DISPATCH_SWITCH; + else if (strcmp (optarg, "jumps") == 0) + dispatch_method = JS_VM_DISPATCH_JUMPS; + else + { + fprintf (stderr, "%s: illegal dispatch method `%s'\n", + program, optarg); + exit (1); + } + break; + + case 'e': /* --eval */ + if (interp == NULL) + interp = create_interp (); + + if (!js_eval (interp, optarg)) + { + fprintf (stderr, "%s: eval failed: %s\n", program, + js_error_message (interp)); + exit (1); + } + break; + + case 'E': /* --events */ + events = 1; + break; + + case 'f': /* --file */ + if (optind >= argc) + { + no_argument_for_file: + fprintf (stderr, "%s: no arguments after option --file\n", + program); + exit (1); + } + goto arguments_done; + break; + + case 'g': /* --debug */ + generate_debug_info = 1; + break; + + case 'h': /* --help */ + usage (); + exit (0); + break; + + case 'l': /* --load */ + do_load = 1; + goto arguments_done; + break; + + case 'N': /* --no-compiler */ + no_compiler = 1; + break; + + case 'O': /* --optimize */ + if (optarg) + optimize = atoi (optarg); + break; + + case 'r': /* --secure */ + if (strcmp (optarg, "file") == 0) + secure_builtin_file = 1; + else if (strcmp (optarg, "system") == 0) + secure_builtin_system = 1; + else + { + fprintf (stderr, "%s: unknown security option `%s'\n", + program, optarg); + exit (1); + } + break; + + case 's': /* --stack-size */ + stack_size = atoi (optarg); + break; + + case 'S': /* --no-assemble */ + no_assemble = 1; + break; + + case 't': /* --stacktrace */ + stacktrace_on_error = 1; + break; + + case 'v': /* --verbose */ + verbose++; + break; + + case 'V': /* --version */ + version (); + exit (0); + break; + + case 'W': /* --compiler-option */ + handle_compiler_option (optarg); + break; + + case 'x': /* --executable */ + generate_executable_bc_files = 1; + break; + + case '?': + fprintf (stderr, "Try `%s --help' for more information.\n", + program); + exit (1); + break; + + default: + printf ("Hey! main() didn't handle option \"%c\" (%d)", c, c); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + abort (); + break; + } + } + + arguments_done: + + interp = create_interp (); + + /* Handle loading here. */ + if (do_load) + { + for (; optind < argc; optind++) + { + if (strcmp (argv[optind], "-f") == 0 + || strcmp (argv[optind], "--file") == 0) + { + optind++; + if (optind >= argc) + goto no_argument_for_file; + + break; + } + + if (!js_eval_file (interp, argv[optind])) + { + fprintf (stderr, "%s: loading of file `%s' failed:\n%s\n", + program, argv[optind], js_error_message (interp)); + exit (1); + } + } + } + + /* Let's see what we have to do. */ + if (compile) + { + char *jscname; + + /* + * Treat all remaining arguments as JavaScript files and compile them. + */ + + for (; optind < argc; optind++) + { + /* Create name for the byte-code file. */ + + jscname = malloc (strlen (argv[optind]) + 5); + assert (jscname != NULL); + strcpy (jscname, argv[optind]); + + cp = strrchr (jscname, '.'); + if (cp) + strcpy (++cp, "jsc"); + else + strcat (jscname, ".jsc"); + + if (verbose) + printf ("%s: compiling `%s' to `%s'\n", program, + argv[optind], jscname); + + if (!js_compile (interp, argv[optind], NULL, jscname)) + { + fprintf (stderr, "%s\n", js_error_message (interp)); + exit (1); + } + + free (jscname); + } + } + else if (no_assemble) + { + char *jasname; + + /* Compile argument files to assembler. */ + for (; optind < argc; optind++) + { + /* Create name for the assembler file. */ + + jasname = malloc (strlen (argv[optind]) + 5); + assert (jasname != NULL); + strcpy (jasname, argv[optind]); + + cp = strrchr (jasname, '.'); + if (cp) + strcpy (++cp, "jas"); + else + strcat (jasname, ".jas"); + + if (verbose) + printf ("%s: compiling `%s' to `%s'\n", program, + argv[optind], jasname); + + if (!js_compile (interp, argv[optind], jasname, NULL)) + { + fprintf (stderr, "%s\n", js_error_message (interp)); + exit (1); + } + + free (jasname); + } + } + else if (optind < argc) + { + char *main_file = argv[optind]; + JSType args; + int i; + + /* + * Assume that contains JavaScript (or byte-code) and + * execute it. All the remaining arguments are passed to the + * interpreter through the ARGS array. + */ + + /* Save all remaining arguments to ARGS */ + js_type_make_array (interp, &args, argc - optind); + + for (i = 0; optind + i < argc; i++) + js_type_make_string (interp, &args.u.array->data[i], + argv[optind + i], strlen (argv[optind + i])); + + js_set_var (interp, "ARGS", &args); + + if (!js_eval_file (interp, main_file)) + { + fprintf (stderr, "%s: evaluation of file `%s' failed:\n%s\n", + program, main_file, js_error_message (interp)); + exit (1); + } + } + + js_destroy_interp (interp); + +#if 0 + /* Use with JS_DEBUG_MEMORY_LEAKS in jsint.h. */ + js_alloc_dump_blocks (); +#endif + + return 0; +} + + +/* + * Static functions. + */ + +static inline int +is_prefix (char *prefix, char *str) +{ + int i; + + for (i = 0; prefix[i] && str[i] && prefix[i] == str[i]; i++) + ; + if (!prefix[i]) + return 1; + + return 0; +} + + +static void +handle_compiler_option (char *name) +{ + int i; + int value = 1; + int nmatches = 0; + int did_match = 0; + + if (name[0] == 'n' && name[1] == 'o' && name[2] == '-') + { + value = 0; + name += 3; + } + + for (i = 0; compiler_options[i].name; i++) + { + int was_prefix = 0; + + if ((was_prefix = is_prefix (name, compiler_options[i].name)) + || (strcmp (name, "runtime") == 0 + && (compiler_options[i].flags & JSC_RUNTIME)) + || (strcmp (name, "all") == 0 + && (compiler_options[i].flags & JSC_WALL)) + || (strcmp (name, "pedantic") == 0 + && (compiler_options[i].flags & (JSC_WALL | JSC_PEDANTIC)))) + { + *compiler_options[i].option = value; + + if (was_prefix) + nmatches++; + + did_match = 1; +#if 0 + fprintf (stderr, "set %s to %d\n", compiler_options[i].name, + value); +#endif + } + } + + if (!did_match) + { + fprintf (stderr, "%s: unknown compiler option `-W%s%s'\n", program, + value ? "" : "no-", name); + exit (1); + } + if (nmatches > 1) + { + fprintf (stderr, "%s: ambiguous compiler option `-W%s%s'\n", + program, value ? "" : "no-", name); + exit (1); + } +} + + +static int +show_events_hook (int event, void *context) +{ + char *event_name; + + switch (event) + { + case JS_EVENT_OPERAND_COUNT: + event_name = "operand count"; + break; + + case JS_EVENT_GARBAGE_COLLECT: + event_name = "garbage collect"; + break; + + default: + event_name = "unknown"; + break; + } + + fprintf (stderr, "[%s: %s]\n", program, event_name); + + return 0; +} + + +static JSInterpPtr +create_interp () +{ + JSInterpOptions options; + JSInterpPtr interp; + + js_init_default_options (&options); + + options.stack_size = stack_size; + options.dispatch_method = dispatch_method; + options.verbose = verbose; + + options.no_compiler = no_compiler; + options.stacktrace_on_error = stacktrace_on_error; + + options.secure_builtin_file = secure_builtin_file; + options.secure_builtin_system = secure_builtin_system; + + options.annotate_assembler = annotate_assembler; + options.debug_info = generate_debug_info; + options.executable_bc_files = generate_executable_bc_files; + + options.warn_unused_argument = warn_unused_argument; + options.warn_unused_variable = warn_unused_variable; + options.warn_undef = warn_undef; + options.warn_shadow = warn_shadow; + options.warn_with_clobber = warn_with_clobber; + options.warn_missing_semicolon = warn_missing_semicolon; + options.warn_strict_ecma = warn_strict_ecma; + options.warn_deprecated = warn_deprecated; + + /* As a default, no optimization */ + options.optimize_peephole = 0; + options.optimize_jumps_to_jumps = 0; + options.optimize_bc_size = 0; + options.optimize_heavy = 0; + + if (optimize >= 1) + { + options.optimize_peephole = 1; + options.optimize_jumps_to_jumps = 1; + options.optimize_bc_size = 1; + } + + if (optimize >= 2) + { + options.optimize_heavy = 1; + } + + /* Show events? */ + if (events) + { + options.hook = show_events_hook; + options.hook_operand_count_trigger = 1000000; + } + + interp = js_create_interp (&options); + if (interp == NULL) + { + fprintf (stderr, "%s: couldn't create interpreter\n", program); + exit (1); + } + + /* And finally, define the requested modules. */ + +#if WITH_JS + if (!js_define_module (interp, js_ext_JS)) + fprintf (stderr, "%s: warning: couldn't create the JS extension\n", + program); +#endif + +#if WITH_CURSES + if (!js_define_module (interp, js_ext_curses)) + fprintf (stderr, "%s: warning: couldn't create the curses extension\n", + program); +#endif + +#if WITH_MD5 + if (!js_define_module (interp, js_ext_MD5)) + fprintf (stderr, "%s: warning: couldn't create the MD5 extension\n", + program); +#endif + + return interp; +} + + +static void +usage () +{ + printf ("\ +Usage: %s [OPTION]... FILE [ARGUMENT]...\n\ +Mandatory arguments to long options are mandatory for short options too.\n\ + -a, --annotate-assembler annotate generated assembler listing with\n\ + the original source code\n\ + -c, --compile compile JavaScript input file to byte-code\n\ + and save the result to the file `FILE.jsc'\n\ + -d, --dispatch=METHOD use method METHOD for byte-code instruction\n\ + dispatching\n\ + -e, --eval=CODE evaluate JavaScript code CODE\n\ + -E, --events print interpreter events\n\ + -f, --file evaluate the next argument file and pass\n\ + all remaining arguments to the interpreter\n\ + through the ARGS array\n\ + -g, --debug generate debugging information\n\ + -h, --help print this help and exit\n\ + -l, --load evaluate argument files until option `-f',\n\ + `--file' is encountered\n\ + -N, --no-compiler do not define compiler to the JavaScript\n\ + interpreter\n\ + -O, --optimize[=LEVEL] optimize at level LEVEL\n\ + -r, --secure=OPTION turn on security option OPTION\n\ + -s, --stack-size=SIZE set the interpreter stack size to SIZE nodes\n\ + -S, --assembler compile JavaScript intput file to assembler\n\ + and save the result to the file `FILE.jas'\n\ + -t, --stacktrace print stacktrace on error\n\ + -v, --verbose tell what the interpreter is doing\n\ + -V, --version print version number\n\ + -W, --compiler-option=OPTION\n\ + set compilation option OPTION\n\ + -x, --executable generate executable byte-code files\n", + program); + + printf ("\nReport bugs to mtr@ngs.fi.\n"); +} + + +static void +version () +{ + printf ("NGS JavaScript Interpter %s\n\ +Copyright (C) 1998 New Generation Software (NGS) Oy.\n\ +NGS JavaScript Interpreter comes with NO WARRANTY, to the extent\n\ +permitted by law. You may redistribute copies of NGS JavaScript\n\ +Interpreter under the terms of the GNU Library General Public License.\n\ +For more information about these matters, see the files named COPYING.\n\ +", + VERSION); +} diff --git a/reactos/lib/kjs/src/make-data.c b/reactos/lib/kjs/src/make-data.c new file mode 100644 index 00000000000..5790ab47396 --- /dev/null +++ b/reactos/lib/kjs/src/make-data.c @@ -0,0 +1,90 @@ +/* + * Make C-string from a binary data file. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/make-data.c,v $ + * $Id: make-data.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include +#include +#include +#include +#include + +int +main (int argc, char *argv[]) +{ + FILE *ifp, *ofp; + unsigned int pos; + int ch, i; + + if (argc != 4) + { + fprintf (stderr, "Usage: %s DATANAME INPUT OUTPUT\n", argv[0]); + exit (1); + } + + ifp = fopen (argv[2], "r"); + if (ifp == NULL) + { + fprintf (stderr, "%s: couldn't open input file \"%s\": %s\n", + argv[0], argv[2], strerror (errno)); + exit (1); + } + + ofp = fopen (argv[3], "w"); + if (ofp == NULL) + { + fprintf (stderr, "%s: couldn't create output file \"%s\": %s\n", + argv[0], argv[3], strerror (errno)); + exit (1); + } + + fprintf (ofp, "unsigned char %s[] = {", argv[1]); + + pos = 0; + + while ((ch = getc (ifp)) != EOF) + { + if ((pos % 8) == 0) + fprintf (ofp, "\n "); + fprintf (ofp, " 0x%02x,", ch); + pos++; + } + + fprintf (ofp, "\n};\n"); + fprintf (ofp, "unsigned int %s_len = %u;\n", argv[1], pos); + + for (i = 0; argv[1][i]; i++) + if (islower (argv[1][i])) + argv[1][i] = toupper (argv[1][i]); + + fprintf (ofp, "#define %s_LEN %u\n", argv[1], pos); + + fclose (ifp); + fclose (ofp); + + return 0; +} diff --git a/reactos/lib/kjs/src/make-jumps.pl b/reactos/lib/kjs/src/make-jumps.pl new file mode 100755 index 00000000000..2c80fe2b809 --- /dev/null +++ b/reactos/lib/kjs/src/make-jumps.pl @@ -0,0 +1,155 @@ +#!/usr/local/bin/perl -w +# +# Create link and execute definitions for jumps2 dispatch method. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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 +# +# +# +# $Id: make-jumps.pl,v 1.1 2004/01/10 20:38:18 arty Exp $ +# + +$linenumbers = 0; +$opcount = 0; + +$target = "c1jumps.h"; +open(CFP, ">$target") || die "couldn't create `$target': $!\n"; + +$target = "c2jumps.h"; +open(CFP2, ">$target") || die "couldn't create `$target': $!\n"; + +$target = "./ejumps.h"; +open(EFP, ">$target") || die "couldn't create `$target': $!\n"; + +while (<>) { + if (/operand\s+([a-zA-Z_][a-zA-Z0-9_]*)\s+([\S]+)\s+\{(.*)/) { + $operand = $1; + $args = $2; + $flags = $3; + + $f_symbol = 0; + if ($flags =~ /symbol/) { + $f_symbol = 1; + } + $f_jump = 0; + if ($flags =~ /jump/) { + $f_jump = 1; + } + + if ($linenumbers) { + printf CFP ("#line %d \"%s\"\n", $. - 1, $ARGV); + } + # + # Compilation phase 1. + # + print CFP "/* operand $operand ($opcount) */\n"; + print CFP "case $opcount:\n"; + print CFP " SAVE_OP (&&op_$operand);\n"; + + if ($operand eq "const") { + # Patch const offsets. + printf CFP " JS_BC_READ_INT32 (cp, i);\n"; + printf CFP " i += consts_offset;\n"; + printf CFP " SAVE_INT32 (i);\n"; + } elsif ($f_symbol) { + # Link symbols. + printf CFP " JS_BC_READ_INT32 (cp, i);\n"; + printf CFP " i += consts_offset;\n"; + printf CFP " i = vm->consts[i].u.vsymbol;\n"; + printf CFP " SAVE_INT32 (i);\n"; + } else { + # Handle standard arguments. + if ($args =~ /0/) { + } elsif ($args =~ /1/) { + print CFP " JS_BC_READ_INT8 (cp, i);\n"; + print CFP " SAVE_INT8 (i);\n"; + } elsif ($args =~ /2/) { + print CFP " JS_BC_READ_INT16 (cp, i);\n"; + print CFP " SAVE_INT16 (i);\n"; + } elsif ($args =~ /4/) { + print CFP " JS_BC_READ_INT32 (cp, i);\n"; + print CFP " SAVE_INT32 (i);\n"; + } else { + die("$ARGV:$.: illegal argument: $args\n"); + } + } + + print CFP " cp += $args;\n"; + print CFP " break;\n\n"; + } else { + next; + } + + # + # Compilation phase 2. + # + if ($linenumbers) { + printf CFP2 "#line %d \"%s\"\n", $. - 1, $ARGV; + } + print CFP2 "/* operand $operand ($opcount) */\n"; + print CFP2 "case $opcount:\n"; + print CFP2 " cpos++;\n"; + if ($f_jump){ + print CFP2 " i = ARG_INT32 ();\n"; + if (0) { + print CFP2 " printf(\"%s: delta=%d, cp=%d\\n\", \"$operand\", i, cp - code_start - 1);\n"; + } + print CFP2 " i = reloc[cp - code_start + 4 + i] - &f->code[cpos + 1];\n"; + if (0) { + print CFP2 " printf (\"%s: newdelta=%d\\n\", \"$operand\", i);\n"; + } + print CFP2 " ARG_INT32 () = i;\n"; + } + if ($args ne "0") { + print CFP2 " cp += $args;\n"; + print CFP2 " cpos++;\n"; + } + print CFP2 " break;\n\n"; + + + # + # Execution. + # + if ($linenumbers) { + printf EFP "#line %d \"%s\"\n", $. - 1, $ARGV; + } + print EFP "/* operand $operand ($opcount) */\n"; + print EFP "op_$operand:\n"; + print EFP " OPERAND ($opcount);\n"; + + if (0) { + print EFP "printf (\"$operand\\n\");\n"; + } + + while (<>) { + if (/^\}/) { + print EFP " NEXT ();\n"; + print EFP "\n"; + last; + } + print EFP; + } + + $opcount++; +} +close(CFP); +close(CFP2); +close(EFP); diff --git a/reactos/lib/kjs/src/make-op-def.pl b/reactos/lib/kjs/src/make-op-def.pl new file mode 100755 index 00000000000..1807daec9a8 --- /dev/null +++ b/reactos/lib/kjs/src/make-op-def.pl @@ -0,0 +1,43 @@ +#!/usr/local/bin/perl -w +# +# Opcode extractor. +# Copyright (c) 1997-1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/make-op-def.pl,v $ +# $Id: make-op-def.pl,v 1.1 2004/01/10 20:38:18 arty Exp $ +# + +$opcount = 0; + +print "# name \topcode\tdatasize\n"; +print "# ----------------------------------------\n"; + +while (<>) { + if (/operand\s+([a-zA-Z_][a-zA-Z0-9_]*)\s+([\S]+)\s+\{/) { + printf ("%-20s\t$opcount\t$2\n", $1); + } else { + next; + } + $opcount++; +} diff --git a/reactos/lib/kjs/src/make-switch.pl b/reactos/lib/kjs/src/make-switch.pl new file mode 100755 index 00000000000..10b838c4d63 --- /dev/null +++ b/reactos/lib/kjs/src/make-switch.pl @@ -0,0 +1,150 @@ +#!/usr/local/bin/perl -w +# +# Create link and execute definitions for switch dispatch method. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/make-switch.pl,v $ +# $Id: make-switch.pl,v 1.1 2004/01/10 20:38:18 arty Exp $ +# + +$linenumbers = 0; + +$opcount = 0; + +$target = "./c1switch.h"; +open(CFP, ">$target") || die "couldn't create `$target': $!\n"; + +$target = "./c2switch.h"; +open(CFP2, ">$target") || die "couldn't create `$target': $!\n"; + +$target = "./eswitch.h"; +open(EFP, ">$target") || die "couldn't create `$target': $!\n"; + +while (<>) { + if (/operand\s+([a-zA-Z_][a-zA-Z0-9_]+)\s+([\S]+)\s+\{(.*)/) { + $operand = $1; + $args = $2; + $flags = $3; + + $f_symbol = 0; + if ($flags =~ /symbol/) { + $f_symbol = 1; + } + $f_jump = 0; + if ($flags =~ /jump/) { + $f_jump = 1; + } + + if ($linenumbers) { + printf CFP ("#line %d \"%s\"\n", $. - 1, $ARGV); + } + + # + # Compilation phase 1. + # + print CFP "/* operand $operand ($opcount) */\n"; + print CFP "case $opcount:\n"; + print CFP " SAVE_OP ($opcount);\n"; + + if ($operand eq "const") { + # Patch const offsets. + printf CFP " JS_BC_READ_INT32 (cp, i);\n"; + printf CFP " i += consts_offset;\n"; + printf CFP " SAVE_INT32 (i);\n"; + } elsif ($f_symbol) { + # Link symbols. + printf CFP " JS_BC_READ_INT32 (cp, i);\n"; + printf CFP " i += consts_offset;\n"; + printf CFP " i = vm->consts[i].u.vsymbol;\n"; + printf CFP " SAVE_INT32 (i);\n"; + } else { + # Handle standard arguments. + if ($args =~ /0/) { + } elsif ($args =~ /1/) { + print CFP " JS_BC_READ_INT8 (cp, i);\n"; + print CFP " SAVE_INT8 (i);\n"; + } elsif ($args =~ /2/) { + print CFP " JS_BC_READ_INT16 (cp, i);\n"; + print CFP " SAVE_INT16 (i);\n"; + } elsif ($args =~ /4/) { + print CFP " JS_BC_READ_INT32 (cp, i);\n"; + print CFP " SAVE_INT32 (i);\n"; + } else { + die("$ARGV:$.: illegal argument: $args\n"); + } + } + + print CFP " cp += $args;\n"; + print CFP " break;\n\n"; + } else { + next; + } + + # + # Compilation phase 2. + # + if ($linenumbers) { + printf CFP2 "#line %d \"%s\"\n", $. - 1, $ARGV; + } + print CFP2 "/* operand $operand ($opcount) */\n"; + print CFP2 "case $opcount:\n"; + print CFP2 " cpos++;\n"; + if ($f_jump) { + print CFP2 " i = ARG_INT32 ();\n"; + if (0) { + print CFP2 " printf(\"%s: delta=%d, cp=%d\\n\", \"$operand\", i, cp - code_start - 1);\n"; + } + print CFP2 " i = reloc[cp - fixed_code + 4 + i] - &f->code[cpos + 1];\n"; + if (0) { + print CFP2 " printf (\"%s: newdelta=%d\\n\", \"$operand\", i);\n"; + } + print CFP2 " ARG_INT32 () = i;\n"; + } + if ($args ne "0") { + print CFP2 " cp += $args;\n"; + print CFP2 " cpos++;\n"; + } + print CFP2 " break;\n\n"; + + # + # Execution. + # + if ($linenumbers) { + printf EFP "#line %d\"%s\"\n", $. - 1, $ARGV; + } + print EFP "/* operand $operand ($opcount) */\n"; + print EFP "case $opcount:\n"; + while (<>) { + if (/^\}/) { + print EFP " break;\n\n"; + last; + } + print EFP; + } + + $opcount++; +} +close(CFP); +close(CFP2); +close(EFP); diff --git a/reactos/lib/kjs/src/make-swt0.pl b/reactos/lib/kjs/src/make-swt0.pl new file mode 100755 index 00000000000..5c4324f39f3 --- /dev/null +++ b/reactos/lib/kjs/src/make-swt0.pl @@ -0,0 +1,95 @@ +#!/usr/local/bin/perl -w +# +# Create link and execute definitions for switch-basic dispatch method. +# Copyright (c) 1998 New Generation Software (NGS) Oy +# +# Author: Markku Rossi +# + +# +# 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/make-swt0.pl,v $ +# $Id: make-swt0.pl,v 1.1 2004/01/10 20:38:18 arty Exp $ +# + +$linenumbers = 0; + +$opcount = 0; + +$target = "./c1swt0.h"; +open(CFP, ">$target") || die "couldn't create `$target': $!\n"; + +$target = "./eswt0.h"; +open(EFP, ">$target") || die "couldn't create `$target': $!\n"; + +while (<>) { + if (/operand\s+([a-zA-Z_][a-zA-Z0-9_]+)\s+([\S]+)\s+\{(.*)/) { + $operand = $1; + $args = $2; + $flags = $3; + + $f_symbol = 0; + if ($flags =~ /symbol/) { + $f_symbol = 1; + } + $f_jump = 0; + if ($flags =~ /jump/) { + $f_jump = 1; + } + + if ($linenumbers) { + printf CFP ("#line %d \"%s\"\n", $. - 1, $ARGV); + } + print CFP "/* operand $operand ($opcount) */\n"; + print CFP "case $opcount:\n"; + if ($operand eq "const") { + # Patch const offsets. + printf CFP " JS_BC_READ_INT32 (cp, i);\n"; + printf CFP " i += consts_offset;\n"; + printf CFP " JS_BC_WRITE_INT32 (cp, i);\n"; + } elsif ($f_symbol) { + # Link symbols. + printf CFP " JS_BC_READ_INT32 (cp, i);\n"; + printf CFP " i += consts_offset;\n"; + printf CFP " i = vm->consts[i].u.vsymbol;\n"; + printf CFP " JS_BC_WRITE_INT32 (cp, i);\n"; + } + print CFP " cp += $args;\n"; + print CFP " break;\n\n"; + } else { + next; + } + + if ($linenumbers) { + printf EFP "#line %d\"%s\"\n", $. - 1, $ARGV; + } + print EFP "/* operand $operand ($opcount) */\n"; + print EFP "case $opcount:\n"; + while (<>) { + if (/^\}/) { + print EFP " break;\n\n"; + last; + } + print EFP; + } + + $opcount++; +} +close(CFP); +close(EFP); diff --git a/reactos/lib/kjs/src/md5.h b/reactos/lib/kjs/src/md5.h new file mode 100644 index 00000000000..a54e70bd23e --- /dev/null +++ b/reactos/lib/kjs/src/md5.h @@ -0,0 +1,96 @@ +/* MD5.H - header file for MD5C.C + */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + */ + +/* ========== include global.h ========== */ +/* GLOBAL.H - RSAREF types and constants + */ + +/* PROTOTYPES should be set to one if and only if the compiler supports + function argument prototyping. +The following makes PROTOTYPES default to 0 if it has not already + been defined with C compiler flags. + */ +#ifdef HAVE_PROTOTYPES +#define PROTOTYPES 1 +#endif +#ifndef PROTOTYPES +#define PROTOTYPES 0 +#endif + +/* POINTER defines a generic pointer type */ +typedef unsigned char *POINTER; + +/* UINT2 defines a two byte word */ +typedef unsigned short int UINT2; + +#ifdef HAVE_LIMITS_H +#include +#else +/* Wild guess */ +#define LONG_MAX 2147483647L +#endif + +/* UINT4 defines a four byte word */ +#if defined(INT_MAX) && INT_MAX == 2147483647 +typedef unsigned int UINT4; +#else +#if defined(LONG_MAX) && LONG_MAX == 2147483647L +typedef unsigned long int UINT4; +#endif +/* Too bad if neither is */ +#endif + +/* PROTO_LIST is defined depending on how PROTOTYPES is defined above. +If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it + returns an empty list. + */ +#if PROTOTYPES +#define PROTO_LIST(list) list +#else +#define PROTO_LIST(list) () +#endif +/* ========== End global.h; continue md5.h ========== */ + +/* Rename all exported symbols to avoid conflicts with similarly named + symbols in some systems' standard C libraries... */ + +#define MD5_CTX _JS_MD5_CTX + +#define MD5Init _JS_MD5Init +#define MD5Update _JS_MD5Update +#define MD5Final _JS_MD5Final + +/* MD5 context. */ +typedef struct { + UINT4 state[4]; /* state (ABCD) */ + UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ + unsigned char buffer[64]; /* input buffer */ +} MD5_CTX; + + +void MD5Init PROTO_LIST ((MD5_CTX *)); +void MD5Update PROTO_LIST + ((MD5_CTX *, unsigned char *, unsigned int)); +void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *)); diff --git a/reactos/lib/kjs/src/md5c.c b/reactos/lib/kjs/src/md5c.c new file mode 100644 index 00000000000..cfd98cdd77f --- /dev/null +++ b/reactos/lib/kjs/src/md5c.c @@ -0,0 +1,335 @@ +/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm + */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + */ + +#include "jsint.h" +#include "md5.h" + +/* Constants for MD5Transform routine. + */ + +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + +static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64])); +static void Encode PROTO_LIST + ((unsigned char *, UINT4 *, unsigned int)); +static void Decode PROTO_LIST + ((UINT4 *, unsigned char *, unsigned int)); +static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int)); +static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int)); + +static unsigned char PADDING[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* F, G, H and I are basic MD5 functions. + */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits. + */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +Rotation is separate from addition to prevent recomputation. + */ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + +/* MD5 initialization. Begins an MD5 operation, writing a new context. + */ +void MD5Init (context) +MD5_CTX *context; /* context */ +{ + context->count[0] = context->count[1] = 0; + /* Load magic initialization constants. +*/ + context->state[0] = 0x67452301; + context->state[1] = 0xefcdab89; + context->state[2] = 0x98badcfe; + context->state[3] = 0x10325476; +} + +/* MD5 block update operation. Continues an MD5 message-digest + operation, processing another message block, and updating the + context. + */ +void MD5Update (context, input, inputLen) +MD5_CTX *context; /* context */ +unsigned char *input; /* input block */ +unsigned int inputLen; /* length of input block */ +{ + unsigned int i, index, partLen; + + /* Compute number of bytes mod 64 */ + index = (unsigned int)((context->count[0] >> 3) & 0x3F); + + /* Update number of bits */ + if ((context->count[0] += ((UINT4)inputLen << 3)) + < ((UINT4)inputLen << 3)) + context->count[1]++; + context->count[1] += ((UINT4)inputLen >> 29); + + partLen = 64 - index; + + /* Transform as many times as possible. +*/ + if (inputLen >= partLen) { + MD5_memcpy + ((POINTER)&context->buffer[index], (POINTER)input, partLen); + MD5Transform (context->state, context->buffer); + + for (i = partLen; i + 63 < inputLen; i += 64) + MD5Transform (context->state, &input[i]); + + index = 0; + } + else + i = 0; + + /* Buffer remaining input */ + MD5_memcpy + ((POINTER)&context->buffer[index], (POINTER)&input[i], + inputLen-i); +} + +/* MD5 finalization. Ends an MD5 message-digest operation, writing the + the message digest and zeroizing the context. + */ +void MD5Final (digest, context) +unsigned char digest[16]; /* message digest */ +MD5_CTX *context; /* context */ +{ + unsigned char bits[8]; + unsigned int index, padLen; + + /* Save number of bits */ + Encode (bits, context->count, 8); + + /* Pad out to 56 mod 64. +*/ + index = (unsigned int)((context->count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + MD5Update (context, PADDING, padLen); + + /* Append length (before padding) */ + MD5Update (context, bits, 8); + + /* Store state in digest */ + Encode (digest, context->state, 16); + + /* Zeroize sensitive information. +*/ + MD5_memset ((POINTER)context, 0, sizeof (*context)); +} + +/* MD5 basic transformation. Transforms state based on block. + */ +static void MD5Transform (state, block) +UINT4 state[4]; +unsigned char block[64]; +{ + UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + + Decode (x, block, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + /* Zeroize sensitive information. +*/ + MD5_memset ((POINTER)x, 0, sizeof (x)); +} + +/* Encodes input (UINT4) into output (unsigned char). Assumes len is + a multiple of 4. + */ +static void Encode (output, input, len) +unsigned char *output; +UINT4 *input; +unsigned int len; +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (unsigned char)(input[i] & 0xff); + output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); + output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); + output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); + } +} + +/* Decodes input (unsigned char) into output (UINT4). Assumes len is + a multiple of 4. + */ +static void Decode (output, input, len) +UINT4 *output; +unsigned char *input; +unsigned int len; +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | + (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); +} + +/* Note: Replace "for loop" with standard memcpy if possible. + */ + +static void MD5_memcpy (output, input, len) +POINTER output; +POINTER input; +unsigned int len; +{ + unsigned int i; + + for (i = 0; i < len; i++) + output[i] = input[i]; +} + +/* Note: Replace "for loop" with standard memset if possible. + */ +static void MD5_memset (output, value, len) +POINTER output; +int value; +unsigned int len; +{ + unsigned int i; + + for (i = 0; i < len; i++) + ((char *)output)[i] = (char)value; +} diff --git a/reactos/lib/kjs/src/mrgsort.c b/reactos/lib/kjs/src/mrgsort.c new file mode 100644 index 00000000000..18df61fd78d --- /dev/null +++ b/reactos/lib/kjs/src/mrgsort.c @@ -0,0 +1,119 @@ +/* + * Re-entrant mergesort. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/mrgsort.c,v $ + * $Id: mrgsort.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include +#include +#include + +#include "mrgsort.h" + +/* + * Types and definitions. + */ + +#define COPY(buf1, idx1, buf2, idx2) \ + memcpy ((buf1) + (idx1) * size, (buf2) + (idx2) * size, size); + +/* + * Static functions. + */ + +static void +do_mergesort (unsigned char *base, unsigned int size, unsigned char *tmp, + unsigned int l, unsigned int r, + MergesortCompFunc func, void *func_ctx) +{ + unsigned int i, j, k, m; + + if (r <= l) + return; + + m = (r + l) / 2; + do_mergesort (base, size, tmp, l, m, func, func_ctx); + do_mergesort (base, size, tmp, m + 1, r, func, func_ctx); + + memcpy (tmp + l * size, base + l * size, (r - l + 1) * size); + + i = l; + j = m + 1; + k = l; + + /* Merge em. */ + while (i <= m && j <= r) + { + if ((*func) (tmp + i * size, tmp + j * size, func_ctx) <= 0) + { + COPY (base, k, tmp, i); + i++; + } + else + { + COPY (base, k, tmp, j); + j++; + } + k++; + } + + /* Copy left-overs. Only one of the following will be executed. */ + for (; i <= m; i++) + { + COPY (base, k, tmp, i); + k++; + } + for (; j <= r; j++) + { + COPY (base, k, tmp, j); + k++; + } +} + + +/* + * Global functions. + */ + +void +mergesort_r (void *base, unsigned int number_of_elements, + unsigned int size, MergesortCompFunc comparison_func, + void *comparison_func_context) +{ + void *tmp; + + if (number_of_elements == 0) + return; + + /* Allocate tmp buffer. */ + tmp = malloc (number_of_elements * size); + assert (tmp != NULL); + + do_mergesort (base, size, tmp, 0, number_of_elements - 1, comparison_func, + comparison_func_context); + + free (tmp); +} diff --git a/reactos/lib/kjs/src/mrgsort.h b/reactos/lib/kjs/src/mrgsort.h new file mode 100644 index 00000000000..8e94f2cf570 --- /dev/null +++ b/reactos/lib/kjs/src/mrgsort.h @@ -0,0 +1,49 @@ +/* + * Re-entrant mergesort. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/mrgsort.h,v $ + * $Id: mrgsort.h,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#ifndef MERGESORT_H +#define MERGESORT_H + +/* + * Types and definitions. + */ + +typedef int (*MergesortCompFunc) (const void *a, const void *b, + void *context); + +/* + * Prototypes for global functions. + */ + +void mergesort_r (void *base, unsigned int number_of_elements, + unsigned int size, MergesortCompFunc comparison_func, + void *comparison_func_context); + + +#endif /* not MERGESORT_H */ diff --git a/reactos/lib/kjs/src/object.c b/reactos/lib/kjs/src/object.c new file mode 100644 index 00000000000..424079973bc --- /dev/null +++ b/reactos/lib/kjs/src/object.c @@ -0,0 +1,535 @@ +/* + * User object handling. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/object.c,v $ + * $Id: object.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" + +/* + * Types and definitions. + */ + +#define HASH_SIZE 128 + +/* + * Prototypes for static functions. + */ + +static void hash_create (JSVirtualMachine *vm, JSObject *obj); + +static void hash_insert (JSVirtualMachine *vm, JSObject *obj, const char *name, + unsigned int name_len, int pos); + +static void hash_delete (JSVirtualMachine *vm, JSObject *obj, const char *name, + unsigned int name_len); + +static int hash_lookup (JSObject *obj, char *name, unsigned int name_len); + + +/* + * Global functions. + */ + +JSObject * +js_vm_object_new (JSVirtualMachine *vm) +{ + JSObject *obj; + + obj = js_vm_alloc (vm, sizeof (*obj)); + obj->hash = NULL; + obj->num_props = 0; + obj->props = NULL; + + return obj; +} + + +void +js_vm_object_mark (JSObject *obj) +{ + int i; + unsigned int num_objects; + + if (obj == NULL) + return; + + tail_recursive: + + if (!js_vm_mark_ptr (obj)) + /* This object has already been marked. Nothing to do here. */ + return; + + js_vm_mark_ptr (obj->props); + + /* Mark property hash. */ + if (obj->hash) + { + JSObjectPropHashBucket *b; + int i; + + js_vm_mark_ptr (obj->hash); + js_vm_mark_ptr (obj->hash_lengths); + + for (i = 0; i < HASH_SIZE; i++) + for (b = obj->hash[i]; b; b = b->next) + { + js_vm_mark_ptr (b); + js_vm_mark_ptr (b->data); + } + } + + /* Mark all non-object properties. */ + num_objects = 0; + for (i = 0; i < obj->num_props; i++) + { + if (obj->props[i].value.type == JS_OBJECT) + { + if (!js_vm_is_marked_ptr (obj->props[i].value.u.vobject)) + num_objects++; + } + else + js_vm_mark (&obj->props[i].value); + } + + /* And finally, mark all objects we have left. */ + if (num_objects > 0) + { + /* Find the objects. */ + for (i = 0; i < obj->num_props; i++) + if (obj->props[i].value.type == JS_OBJECT + && !js_vm_is_marked_ptr (obj->props[i].value.u.vobject)) + { + if (num_objects == 1) + { + /* + * Hahaa, this is the only non-marked object. We can + * do a tail-recursion optimization. + */ + obj = obj->props[i].value.u.vobject; + goto tail_recursive; + } + + /* Just mark it. */ + js_vm_mark (&obj->props[i].value); + } + } +} + + +int +js_vm_object_load_property (JSVirtualMachine *vm, JSObject *obj, + JSSymbol prop, JSNode *value_return) +{ + unsigned int ui; + JSSymbol link_sym = vm->syms.s___proto__; + JSObject *link_obj = NULL; + +follow_link: + + /* Check if we know this property. */ + for (ui = 0; ui < obj->num_props; ui++) + if (obj->props[ui].name == prop) + { + JS_COPY (value_return, &obj->props[ui].value); + return JS_PROPERTY_FOUND; + } + else if (obj->props[ui].name == link_sym + && obj->props[ui].value.type == JS_OBJECT) + link_obj = obj->props[ui].value.u.vobject; + + /* Undefined so far. */ + if (link_obj) + { + /* Follow the link. */ + obj = link_obj; + + link_obj = NULL; + goto follow_link; + } + + /* Undefined. Make it undef. */ + value_return->type = JS_UNDEFINED; + return JS_PROPERTY_UNKNOWN; +} + + +void +js_vm_object_store_property (JSVirtualMachine *vm, JSObject *obj, + JSSymbol prop, JSNode *val) +{ + unsigned int ui; + JSSymbol free_slot = JS_SYMBOL_NULL; + + /* Check if we already know this property. */ + for (ui = 0; ui < obj->num_props; ui++) + if (obj->props[ui].name == prop) + { + JS_COPY (&obj->props[ui].value, val); + return; + } + else if (obj->props[ui].name == JS_SYMBOL_NULL) + free_slot = ui; + + /* Must create a new property. */ + + if (free_slot == JS_SYMBOL_NULL) + { + /* Expand our array of properties. */ + obj->props = js_vm_realloc (vm, obj->props, + (obj->num_props + 1) * sizeof (JSProperty)); + free_slot = obj->num_props++; + } + + obj->props[free_slot].name = prop; + obj->props[free_slot].attributes = 0; + JS_COPY (&obj->props[free_slot].value, val); + + /* Insert it to the hash (if the hash has been created). */ + if (obj->hash) + { + const char *name; + + name = js_vm_symname (vm, prop); + hash_insert (vm, obj, name, strlen (name), free_slot); + } +} + + +void +js_vm_object_delete_property (JSVirtualMachine *vm, JSObject *obj, + JSSymbol prop) +{ + unsigned int ui; + + /* Check if we already know this property. */ + for (ui = 0; ui < obj->num_props; ui++) + if (obj->props[ui].name == prop) + { + /* Found, remove it from our list of properties. */ + obj->props[ui].name = JS_SYMBOL_NULL; + obj->props[ui].value.type = JS_UNDEFINED; + + /* Remove its name from the hash (if present). */ + if (obj->hash) + { + const char *name = js_vm_symname (vm, prop); + hash_delete (vm, obj, name, strlen (name)); + } + + /* All done here. */ + return; + } +} + + +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); + } +} + + +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 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); + } +} + + +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); + } +} + + +int +js_vm_object_nth (JSVirtualMachine *vm, JSObject *obj, int nth, + JSNode *value_return) +{ + int i; + JSObjectPropHashBucket *b; + + value_return->type = JS_UNDEFINED; + + if (nth < 0) + return 0; + + if (obj->hash == NULL) + hash_create (vm, obj); + + for (i = 0; i < HASH_SIZE && nth >= obj->hash_lengths[i]; i++) + nth -= obj->hash_lengths[i]; + + if (i >= HASH_SIZE) + return 0; + + /* The chain is the correct one. */ + for (b = obj->hash[i]; b && nth > 0; b = b->next, nth--) + ; + if (b == NULL) + { + char buf[512]; + + sprintf (buf, + "js_vm_object_nth(): chain didn't contain that many items%s", + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); + + abort (); + } + + js_vm_make_string (vm, value_return, b->data, b->len); + + return 1; +} + + +/* + * Static functions. + */ + +static void +hash_create (JSVirtualMachine *vm, JSObject *obj) +{ + int i; + + obj->hash = js_vm_alloc (vm, HASH_SIZE * sizeof (JSObjectPropHashBucket *)); + memset (obj->hash, 0, HASH_SIZE * sizeof (JSObjectPropHashBucket *)); + + obj->hash_lengths = js_vm_alloc (vm, HASH_SIZE * sizeof (unsigned int)); + memset (obj->hash_lengths, 0, HASH_SIZE * sizeof (unsigned int)); + + /* Insert all known properties to the hash. */ + for (i = 0; i < obj->num_props; i++) + if (obj->props[i].name != JS_SYMBOL_NULL) + { + const char *name; + + name = js_vm_symname (vm, obj->props[i].name); + hash_insert (vm, obj, name, strlen (name), i); + } +} + + +static void +hash_insert (JSVirtualMachine *vm, JSObject *obj, const char *name, + unsigned int name_len, int pos) +{ + unsigned int hash; + JSObjectPropHashBucket *b; + + hash = js_count_hash (name, name_len) % HASH_SIZE; + for (b = obj->hash[hash]; b; b = b->next) + if (b->len == name_len + && memcmp (b->data, name, name_len) == 0) + { + /* Ok, we already have a bucket */ + b->value = pos; + return; + } + + /* Create a new bucket. */ + b = js_vm_alloc (vm, sizeof (*b)); + b->len = name_len; + b->data = js_vm_alloc (vm, b->len); + memcpy (b->data, name, b->len); + + b->value = pos; + + b->next = obj->hash[hash]; + obj->hash[hash] = b; + + obj->hash_lengths[hash]++; +} + + +static void +hash_delete (JSVirtualMachine *vm, JSObject *obj, const char *name, + unsigned int name_len) +{ + unsigned int hash; + JSObjectPropHashBucket *b, *prev; + + hash = js_count_hash (name, name_len) % HASH_SIZE; + for (prev = NULL, b = obj->hash[hash]; b; prev = b, b = b->next) + if (b->len == name_len + && memcmp (b->data, name, name_len) == 0) + { + /* Ok, found it. */ + if (prev) + prev->next = b->next; + else + obj->hash[hash] = b->next; + + obj->hash_lengths[hash]--; + + break; + } +} + + +static int +hash_lookup (JSObject *obj, char *name, unsigned int name_len) +{ + unsigned int hash; + JSObjectPropHashBucket *b; + + hash = js_count_hash (name, name_len) % HASH_SIZE; + for (b = obj->hash[hash]; b; b = b->next) + if (b->len == name_len + && memcmp (b->data, name, name_len) == 0) + return b->value; + + return -1; +} diff --git a/reactos/lib/kjs/src/operands.def b/reactos/lib/kjs/src/operands.def new file mode 100644 index 00000000000..575b34fbf43 --- /dev/null +++ b/reactos/lib/kjs/src/operands.def @@ -0,0 +1,2117 @@ +/* -*- c -*- + * Operand definitions for the JavaScript byte-code. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/operands.def,v $ + * $Id: operands.def,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +operand halt 0 { + sprintf (buf, "VM: halt%s", JS_HOST_LINE_BREAK); + + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); + + while (1) + sleep (5); +} + +operand done 0 { + DONE (); +} + +operand nop 0 { + /* Nothing here! */ +} + +operand dup 0 { + JS_COPY (JS_SP0, JS_SP1); + JS_PUSH (); +} + +operand pop 0 { + JS_POP (); +} + +operand pop_n 1 { + READ_INT8 (i); + JS_POP_N (i); +} + +operand apop 1 { + READ_INT8 (i); + JS_COPY (JS_SP (i + 1), JS_SP1); + JS_POP_N (i); +} + +operand swap 0 { + JS_COPY (JS_SP0, JS_SP2); + JS_COPY (JS_SP2, JS_SP1); + JS_COPY (JS_SP1, JS_SP0); +} + +operand roll 1 { + READ_INT8 (i8); + + if (i8 > 1) + { + int j; + + for (j = 0; j < i8; j++) + JS_COPY (JS_SP (j), JS_SP (j + 1)); + + JS_COPY (JS_SP (i8), JS_SP0); + } + else if (i8 < -1) + { + i8 = -i8; + + JS_COPY (JS_SP0, JS_SP (i8)); + for (; i8 > 0; i8--) + JS_COPY (JS_SP (i8), JS_SP (i8 - 1)); + } +} + +operand const 4 { + READ_INT32 (i); + JS_COPY (JS_SP0, JS_CONST (i)); + JS_PUSH (); +} + +operand const_null 0 { + JS_SP0->type = JS_NULL; + JS_PUSH (); +} + +operand const_true 0 { + JS_SP0->type = JS_BOOLEAN; + JS_SP0->u.vboolean = 1; + JS_PUSH (); +} + +operand const_false 0 { + JS_SP0->type = JS_BOOLEAN; + JS_SP0->u.vboolean = 0; + JS_PUSH (); +} + +operand const_undefined 0 { + JS_SP0->type = JS_UNDEFINED; + JS_PUSH (); +} + +operand const_i0 0 { + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 0; + JS_PUSH (); +} + +operand const_i1 0 { + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 1; + JS_PUSH (); +} + +operand const_i2 0 { + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 2; + JS_PUSH (); +} + +operand const_i3 0 { + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = 3; + JS_PUSH (); +} + +operand const_i 4 { + READ_INT32 (i); + JS_SP0->type = JS_INTEGER; + JS_SP0->u.vinteger = i; + JS_PUSH (); +} + +operand load_global 4 { /* symbol */ + READ_INT32 (j); + + /* Use the global value only. */ + JS_COPY (JS_SP0, JS_GLOBAL (j)); + JS_PUSH (); + + if (vm->warn_undef && JS_SP1->type == JS_UNDEFINED) + { + sprintf (buf, "VM: warning: using undefined global `%s'%s", + js_vm_symname (vm, j), JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } +} + +operand store_global 4 { /* symbol */ + READ_INT32 (i); + + /* Operand store_global do not check the with-chain. */ + /* WITHCHAIN */ + + /* Set the global value. */ + JS_COPY (JS_GLOBAL (i), JS_SP1); + JS_POP (); +} + +operand load_arg 1 { + READ_INT8 (i); + JS_COPY (JS_SP0, JS_ARG (i)); + JS_PUSH (); +} + +operand store_arg 1 { + READ_INT8 (i); + JS_COPY (JS_ARG (i), JS_SP1); + JS_POP (); +} + +operand load_local 2 { + READ_INT16 (i); + JS_COPY (JS_SP0, JS_LOCAL (i)); + JS_PUSH (); +} + +operand store_local 2 { + READ_INT16 (i); + JS_COPY (JS_LOCAL (i), JS_SP1); + JS_POP (); +} + +operand load_property 4 { /* symbol */ + /* Fetch the property symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (JS_SP1->u.vbuiltin->info->property_proc) + { + if ((*JS_SP1->u.vbuiltin->info->property_proc) ( + vm, + JS_SP1->u.vbuiltin->info, + JS_SP1->u.vbuiltin->instance_context, + j, 0, &builtin_result) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Looking up the prototype. */ + + builtin_result.type = JS_OBJECT; + if (JS_SP1->u.vbuiltin->prototype) + /* This is an instance. */ + builtin_result.u.vobject = JS_SP1->u.vbuiltin->prototype; + else + /* This is a class. */ + builtin_result.u.vobject + = JS_SP1->u.vbuiltin->info->prototype; + } + else + { + /* Looking up stuffs from the prototype. */ + + if (JS_SP1->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_load_property (vm, + JS_SP1->u.vbuiltin->prototype, + j, &builtin_result); + else + /* A class. */ + js_vm_object_load_property ( + vm, + JS_SP1->u.vbuiltin->info->prototype, + j, &builtin_result); + } + } + JS_COPY (JS_SP1, &builtin_result); + } + else + ERROR ("illegal builtin object for load_property"); + } + else if (JS_SP1->type == JS_OBJECT) + { + js_vm_object_load_property (vm, JS_SP1->u.vobject, j, JS_SP1); + } + else if (vm->prim[JS_SP1->type]) + { + /* The primitive language types. */ + JS_SAVE_REGS (); + if ((*vm->prim[JS_SP1->type]->property_proc) (vm, vm->prim[JS_SP1->type], + JS_SP1, j, 0, + &builtin_result) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Looking up the prototype. */ + switch (JS_SP1->type) + { + case JS_STRING: + if (JS_SP1->u.vstring->prototype) + { + builtin_result.type = JS_OBJECT; + builtin_result.u.vobject = JS_SP1->u.vstring->prototype; + } + else + /* No prototype yet. */ + builtin_result.type = JS_NULL; + break; + + case JS_ARRAY: + if (JS_SP1->u.varray->prototype) + { + builtin_result.type = JS_OBJECT; + builtin_result.u.vobject = JS_SP1->u.varray->prototype; + } + else + /* No prototype yet. */ + builtin_result.type = JS_NULL; + break; + + case JS_FUNC: + if (JS_SP1->u.vfunction->prototype) + { + builtin_result.type = JS_OBJECT; + builtin_result.u.vobject + = JS_SP1->u.vfunction->prototype; + } + else + /* No prototype yet. */ + builtin_result.type = JS_NULL; + break; + + default: + /* The rest do not have prototype. */ + builtin_result.type = JS_NULL; + break; + } + } + else + { + /* Looking up stuffs from the prototype. */ + switch (JS_SP1->type) + { + case JS_STRING: + if (JS_SP1->u.vstring->prototype) + js_vm_object_load_property (vm, + JS_SP1->u.vstring->prototype, + j, &builtin_result); + else + /* Take it from the class' prototype */ + goto _op_load_property_try_proto; + break; + + case JS_ARRAY: + if (JS_SP1->u.varray->prototype) + js_vm_object_load_property (vm, + JS_SP1->u.varray->prototype, + j, &builtin_result); + else + /* Take it from the class' prototype */ + goto _op_load_property_try_proto; + break; + + case JS_FUNC: + if (JS_SP1->u.vfunction->prototype) + js_vm_object_load_property (vm, + JS_SP1->u.vfunction->prototype, + j, &builtin_result); + else + /* Take it from the class' prototype */ + goto _op_load_property_try_proto; + break; + + default: + /* + * The rest do not have instance prototypes; use the + * class prototypes. + */ + _op_load_property_try_proto: + js_vm_object_load_property ( + vm, + vm->prim[JS_SP1->type]->prototype, j, + &builtin_result); + break; + } + } + } + + JS_COPY (JS_SP1, &builtin_result); + } + else + ERROR ("illegal object for load_property"); +} + +operand store_property 4 { /* symbol */ + /* Fetch the property symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (JS_SP1->u.vbuiltin->info->property_proc) + { + if ((*JS_SP1->u.vbuiltin->info->property_proc) ( + vm, + JS_SP1->u.vbuiltin->info, + JS_SP1->u.vbuiltin->instance_context, + j, 1, JS_SP2) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Setting the prototype. */ + if (JS_SP2->type != JS_OBJECT) + ERROR ("illegal value for set_property"); + + if (JS_SP1->u.vbuiltin->prototype) + /* Setting the instance's prototype. */ + JS_SP1->u.vbuiltin->prototype = JS_SP2->u.vobject; + else + /* Setting the class' prototype. */ + JS_SP1->u.vbuiltin->info->prototype = JS_SP2->u.vobject; + } + else + { + /* Setting stuff to the prototype. */ + if (JS_SP1->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_store_property (vm, + JS_SP1->u.vbuiltin->prototype, + j, JS_SP2); + else + /* A class. */ + js_vm_object_store_property ( + vm, + JS_SP1->u.vbuiltin->info->prototype, + j, JS_SP2); + } + } + } + else + ERROR ("illegal builtin object for store_property"); + + JS_POP (); + JS_POP (); + } + else if (JS_SP1->type == JS_OBJECT) + { + js_vm_object_store_property (vm, JS_SP1->u.vobject, j, JS_SP2); + JS_POP (); + JS_POP (); + } + else if (vm->prim[JS_SP1->type]) + { + /* The primitive language types. */ + JS_SAVE_REGS (); + if ((*vm->prim[JS_SP1->type]->property_proc) (vm, vm->prim[JS_SP1->type], + JS_SP1, j, 1, JS_SP2) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Setting the prototype. */ + if (JS_SP2->type != JS_OBJECT) + ERROR ("illegal value for set_property"); + + switch (JS_SP1->type) + { + case JS_STRING: + JS_SP1->u.vstring->prototype = JS_SP2->u.vobject; + break; + + case JS_ARRAY: + JS_SP1->u.varray->prototype = JS_SP2->u.vobject; + break; + + case JS_FUNC: + JS_SP1->u.vfunction->prototype = JS_SP2->u.vobject; + break; + + default: + ERROR ("illegal object for set_property"); + break; + } + } + else + { + JSNode prototype; + + /* Setting to the prototype. We create them on demand. */ + switch (JS_SP1->type) + { + case JS_STRING: + if (JS_SP1->u.vstring->prototype == NULL) + { + prototype.type = JS_OBJECT; + + /* Create the prototype and set its __proto__. */ + JS_SP1->u.vstring->prototype = js_vm_object_new (vm); + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property ( + vm, + JS_SP1->u.vstring->prototype, + vm->syms.s___proto__, + &prototype); + } + js_vm_object_store_property (vm, + JS_SP1->u.vstring->prototype, + j, JS_SP2); + break; + + case JS_ARRAY: + if (JS_SP1->u.varray->prototype == NULL) + { + prototype.type = JS_OBJECT; + + /* Create the prototype and set its __proto__. */ + JS_SP1->u.varray->prototype = js_vm_object_new (vm); + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property ( + vm, + JS_SP1->u.varray->prototype, + vm->syms.s___proto__, + &prototype); + } + js_vm_object_store_property (vm, + JS_SP1->u.varray->prototype, + j, JS_SP2); + break; + + case JS_FUNC: + if (JS_SP1->u.vfunction->prototype == NULL) + { + prototype.type = JS_OBJECT; + + /* Create the prototype and set its __proto__. */ + JS_SP1->u.vfunction->prototype = js_vm_object_new (vm); + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property ( + vm, + JS_SP1->u.vfunction->prototype, + vm->syms.s___proto__, + &prototype); + } + js_vm_object_store_property (vm, + JS_SP1->u.vfunction->prototype, + j, JS_SP2); + break; + + default: + ERROR ("illegal object for set_property"); + break; + } + } + } + JS_POP (); + JS_POP (); + } + else + ERROR ("illegal object for store_property"); + + JS_MAYBE_GC (); +} + +operand load_array 0 { + if (JS_SP2->type == JS_BUILTIN) + { + if (JS_SP1->type == JS_INTEGER) + { + ERROR ("integer indexes not implemented yet for BUILTIN in load_array"); + } + else if (JS_SP1->type == JS_STRING) + { + /* Intern the string. */ + j = js_vm_intern_with_len (vm, JS_SP1->u.vstring->data, + JS_SP1->u.vstring->len); + + /* The code below must be in sync with operand `load_property'. */ + JS_SAVE_REGS (); + + if (JS_SP2->u.vbuiltin->info->property_proc) + { + if ((*JS_SP2->u.vbuiltin->info->property_proc) ( + vm, + JS_SP2->u.vbuiltin->info, + JS_SP2->u.vbuiltin->instance_context, + j, 0, &builtin_result) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Looking up the prototype. */ + + builtin_result.type = JS_OBJECT; + if (JS_SP2->u.vbuiltin->prototype) + /* This is an instance. */ + builtin_result.u.vobject + = JS_SP2->u.vbuiltin->prototype; + else + /* This is a class. */ + builtin_result.u.vobject + = JS_SP2->u.vbuiltin->info->prototype; + } + else + { + /* Looking up stuffs from the prototype. */ + + if (JS_SP2->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_load_property ( + vm, + JS_SP2->u.vbuiltin->prototype, + j, &builtin_result); + else + /* A class. */ + js_vm_object_load_property ( + vm, + JS_SP2->u.vbuiltin->info->prototype, + j, &builtin_result); + } + } + JS_COPY (JS_SP2, &builtin_result); + JS_POP (); + } + else + ERROR ("illegal builtin object for load_array"); + } + else + { + sprintf (buf, "illegal array index in load_array (%d)", + JS_SP1->type); + ERROR (buf); + } + } + else if (JS_SP2->type == JS_OBJECT) + { + js_vm_object_load_array (vm, JS_SP2->u.vobject, JS_SP1, JS_SP2); + JS_POP (); + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->type == JS_INTEGER) + { + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.varray->length) + JS_SP2->type = JS_UNDEFINED; + else + { + JSNode *n = &JS_SP2->u.varray->data[JS_SP1->u.vinteger]; + JS_COPY (JS_SP2, n); + } + JS_POP (); + } + else + { + sprintf (buf, "illegal array index in load_array (%d)", + JS_SP1->type); + ERROR (buf); + } + } + else if (JS_SP2->type == JS_STRING) + { + if (JS_SP1->type == JS_INTEGER) + { + int ch; + + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.vstring->len) + ERROR ("string index out of range in load_array"); + + ch = JS_SP2->u.vstring->data[JS_SP1->u.vinteger]; + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = ch; + + JS_POP (); + } + else + ERROR ("illegal string index in load_array"); + } + else + ERROR ("illegal object for load_array"); +} + +operand store_array 0 { + if (JS_SP2->type == JS_BUILTIN) + { + if (JS_SP1->type == JS_INTEGER) + { + ERROR ("integer index not implemented yet for BUILTIN in store_array"); + } + else if (JS_SP1->type == JS_STRING) + { + /* Intern the string. */ + j = js_vm_intern_with_len (vm, JS_SP1->u.vstring->data, + JS_SP1->u.vstring->len); + + /* The code below msut be in sync with operand `store_property'. */ + JS_SAVE_REGS (); + if (JS_SP2->u.vbuiltin->info->property_proc) + { + if ((*JS_SP2->u.vbuiltin->info->property_proc) ( + vm, + JS_SP2->u.vbuiltin->info, + JS_SP2->u.vbuiltin->instance_context, + j, 1, JS_SP (3)) + == JS_PROPERTY_UNKNOWN) + { + if (j == vm->syms.s_prototype) + { + /* Setting the prototype. */ + if (JS_SP (3)->type != JS_OBJECT) + ERROR ("illegal value for prototype"); + + if (JS_SP2->u.vbuiltin->prototype) + /* Setting the instance's prototype. */ + JS_SP2->u.vbuiltin->prototype = JS_SP (3)->u.vobject; + else + /* Setting the class' prototype. */ + JS_SP2->u.vbuiltin->info->prototype + = JS_SP (3)->u.vobject; + } + else + { + /* Setting stuff to the prototype. */ + if (JS_SP2->u.vbuiltin->prototype) + /* An instance. */ + js_vm_object_store_property ( + vm, + JS_SP2->u.vbuiltin->prototype, + j, JS_SP (3)); + else + /* A class. */ + js_vm_object_store_property ( + vm, + JS_SP2->u.vbuiltin->info->prototype, + j, JS_SP (3)); + } + } + } + else + ERROR ("illegal builtin object for store_array"); + + JS_POP_N (3); + } + else + ERROR ("illegal array index in store_array"); + } + else if (JS_SP2->type == JS_OBJECT) + { + js_vm_object_store_array (vm, JS_SP2->u.vobject, JS_SP1, JS_SP (3)); + JS_POP_N (3); + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->type == JS_INTEGER) + { + if (JS_SP1->u.vinteger < 0) + ERROR ("negative array index in store_array"); + if (JS_SP1->u.vinteger >= JS_SP2->u.varray->length) + js_vm_expand_array (vm, JS_SP2, JS_SP1->u.vinteger + 1); + + JS_COPY (&JS_SP2->u.varray->data[JS_SP1->u.vinteger], JS_SP (3)); + JS_POP_N (3); + } + else + ERROR ("illegal array index in store_array"); + } + else if (JS_SP2->type == JS_STRING) + { + if (JS_SP1->type == JS_INTEGER) + { + if (JS_SP2->u.vstring->staticp) + ERROR ("static string in store_array"); + + if (JS_SP1->u.vinteger < 0) + ERROR ("negative string index in store_array"); + + if (JS_SP (3)->type != JS_INTEGER) + ERROR ("non-integer value to store into string in store_array"); + + if (JS_SP1->u.vinteger >= JS_SP2->u.vstring->len) + { + /* Expand the string. */ + JS_SP2->u.vstring->data = js_vm_realloc (vm, + JS_SP2->u.vstring->data, + JS_SP1->u.vinteger + 1); + /* Fill the gap with ' '. */ + for (; JS_SP2->u.vstring->len <= JS_SP1->u.vinteger;) + JS_SP2->u.vstring->data[JS_SP2->u.vstring->len++] = ' '; + } + + JS_SP2->u.vstring->data[JS_SP1->u.vinteger] + = (unsigned char) JS_SP (3)->u.vinteger; + JS_POP_N (3); + } + else + ERROR ("illegal string index in store_array"); + } + else + ERROR ("illegal object for store_array"); + + JS_MAYBE_GC (); +} + +operand nth 0 { + if (JS_SP2->type == JS_STRING) + { + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.vstring->len) + { + JS_SP2->type = JS_UNDEFINED; + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 0; + } + else + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = JS_SP2->u.vstring->data[JS_SP1->u.vinteger]; + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 1; + } + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->u.vinteger < 0 + || JS_SP1->u.vinteger >= JS_SP2->u.varray->length) + { + JS_SP2->type = JS_UNDEFINED; + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 0; + } + else + { + JSNode *n = &JS_SP2->u.varray->data[JS_SP1->u.vinteger]; + JS_COPY (JS_SP2, n); + + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = 1; + } + } + else if (JS_SP2->type == JS_OBJECT) + { + i = js_vm_object_nth (vm, JS_SP2->u.vobject, JS_SP1->u.vinteger, JS_SP2); + JS_SP1->type = JS_BOOLEAN; + JS_SP1->u.vboolean = i; + } + else + ERROR ("illegal object for nth"); +} + +operand cmp_eq 0 { + JS_OPERAND_CMP_EQ (==, 1); +} + +operand cmp_ne 0 { + JS_OPERAND_CMP_EQ (!=, 0); +} + +operand cmp_lt 0 { + JS_OPERAND_CMP_REL (<); +} + +operand cmp_gt 0 { + JS_OPERAND_CMP_REL (>); +} + +operand cmp_le 0 { + JS_OPERAND_CMP_REL (<=); +} + +operand cmp_ge 0 { + JS_OPERAND_CMP_REL (>=); +} + +operand cmp_seq 0 { + JS_OPERAND_CMP_SEQ (==, 1); +} + +operand cmp_sne 0 { + JS_OPERAND_CMP_SEQ (!=, 0); +} + +operand sub 0 { + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger -= JS_SP1->u.vinteger; + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (l->type == JS_INTEGER) + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger - r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = (double) l->u.vinteger - r->u.vfloat; + } + } + else + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat - (double) r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat - r->u.vfloat; + } + } + } + + JS_POP (); +} + +operand add 0 { + if (JS_SP2->type == JS_STRING || JS_SP1->type == JS_STRING) + { + unsigned char *d2, *d1, *ndata; + unsigned int d2_len, d1_len, nlen; + JSNode cvt; + + if (JS_SP2->type == JS_STRING) + { + d2 = JS_SP2->u.vstring->data; + d2_len = JS_SP2->u.vstring->len; + } + else + { + js_vm_to_string (vm, JS_SP2, &cvt); + d2 = cvt.u.vstring->data; + d2_len = cvt.u.vstring->len; + } + if (JS_SP1->type == JS_STRING) + { + d1 = JS_SP1->u.vstring->data; + d1_len = JS_SP1->u.vstring->len; + } + else + { + js_vm_to_string (vm, JS_SP1, &cvt); + d1 = cvt.u.vstring->data; + d1_len = cvt.u.vstring->len; + } + + nlen = d2_len + d1_len; + ndata = js_vm_alloc (vm, nlen); + memcpy (ndata, d2, d2_len); + memcpy (ndata + d2_len, d1, d1_len); + + js_vm_make_static_string (vm, JS_SP2, ndata, nlen); + JS_SP2->u.vstring->staticp = 0; + JS_POP (); + JS_MAYBE_GC (); + } + else if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger += JS_SP1->u.vinteger; + JS_POP (); + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (l->type == JS_INTEGER) + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger + r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = (double) l->u.vinteger + r->u.vfloat; + } + } + else + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat + (double) r->u.vinteger; + } + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = l->u.vfloat + r->u.vfloat; + } + } + + JS_POP (); + } +} + +operand mul 0 { + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger *= JS_SP1->u.vinteger; + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (l->type == JS_INTEGER) + { + if (r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger * r->u.vinteger; + } + else + { + if (l->u.vinteger == 0 + && (JS_IS_POSITIVE_INFINITY (r) + || JS_IS_NEGATIVE_INFINITY (r))) + JS_SP2->type = JS_NAN; + else + { + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = (double) l->u.vinteger * r->u.vfloat; + } + } + } + else + { + if ((JS_IS_POSITIVE_INFINITY (l) || JS_IS_NEGATIVE_INFINITY (l)) + && ((r->type == JS_INTEGER && r->u.vinteger == 0) + || (r->type == JS_FLOAT && r->u.vfloat == 0.0))) + JS_SP2->type = JS_NAN; + else + { + JS_SP2->type = JS_FLOAT; + + if (r->type == JS_INTEGER) + JS_SP2->u.vfloat = l->u.vfloat * (double) r->u.vinteger; + else + JS_SP2->u.vfloat = l->u.vfloat * r->u.vfloat; + } + } + } + + JS_POP (); +} + +operand div 0 { + { + int nan = 0; + double l, r; + int l_inf = 0; + int r_inf = 0; + JSNode *n; + JSNode cvt; + + /* Convert divident to float. */ + if (JS_IS_NUMBER (JS_SP2)) + n = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &cvt); + n = &cvt; + } + + switch (n->type) + { + case JS_INTEGER: + l = (double) n->u.vinteger; + break; + + case JS_FLOAT: + l = n->u.vfloat; + if (JS_IS_POSITIVE_INFINITY (n) || JS_IS_NEGATIVE_INFINITY (n)) + l_inf = 1; + break; + + case JS_NAN: + default: + nan = 1; + break; + } + + /* Convert divisor to float. */ + if (JS_IS_NUMBER (JS_SP1)) + n = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP2, &cvt); + n = &cvt; + } + + switch (n->type) + { + case JS_INTEGER: + r = (double) n->u.vinteger; + break; + + case JS_FLOAT: + r = n->u.vfloat; + if (JS_IS_POSITIVE_INFINITY (n) || JS_IS_NEGATIVE_INFINITY (n)) + r_inf = 1; + break; + + case JS_NAN: + default: + nan = 1; + break; + } + + /* Do the division. */ + JS_POP (); + if (nan || (l_inf && r_inf)) + JS_SP1->type = JS_NAN; + else + { + if (l_inf && r == 0.0) + { + /* is already an infinity. */ + JS_SP1->type = JS_FLOAT; + JS_SP1->u.vfloat = l; + } + else if (l == 0.0 && r == 0.0) + JS_SP1->type = JS_NAN; + else + { + JS_SP1->type = JS_FLOAT; + JS_SP1->u.vfloat = l / r; + } + } + } +} + +operand mod 0 { + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + if (JS_SP1->u.vinteger == 0) + JS_SP2->type = JS_NAN; + else + JS_SP2->u.vinteger %= JS_SP1->u.vinteger; + } + else + { + JSNode l_cvt, r_cvt; + JSNode *l, *r; + + if (JS_IS_NUMBER (JS_SP2)) + l = JS_SP2; + else + { + js_vm_to_number (vm, JS_SP2, &l_cvt); + l = &l_cvt; + } + + if (JS_IS_NUMBER (JS_SP1)) + r = JS_SP1; + else + { + js_vm_to_number (vm, JS_SP1, &r_cvt); + r = &r_cvt; + } + + if (l->type == JS_NAN || r->type == JS_NAN) + JS_SP2->type = JS_NAN; + else if (JS_IS_POSITIVE_INFINITY (l) + || JS_IS_NEGATIVE_INFINITY (l) + || ((r->type == JS_INTEGER && r->u.vinteger == 0) + || (r->type == JS_FLOAT && r->u.vfloat == 0.0))) + JS_SP2->type = JS_NAN; + else if (JS_IS_POSITIVE_INFINITY (r) + || JS_IS_NEGATIVE_INFINITY (r)) + JS_COPY (JS_SP2, l); + else if ((l->type == JS_INTEGER && l->u.vinteger == 0) + || (l->type == JS_FLOAT && l->u.vfloat == 0.0)) + JS_COPY (JS_SP2, l); + else + { + if (l->type == JS_INTEGER && r->type == JS_INTEGER) + { + JS_SP2->type = JS_INTEGER; + JS_SP2->u.vinteger = l->u.vinteger % r->u.vinteger; + } + else + { + double ld, rd; + int full; + + if (l->type == JS_INTEGER) + ld = (double) l->u.vinteger; + else + ld = l->u.vfloat; + + if (r->type == JS_INTEGER) + rd = (double) r->u.vinteger; + else + rd = r->u.vfloat; + + full = ld / rd; + + JS_SP2->type = JS_FLOAT; + JS_SP2->u.vfloat = ld - (full * rd); + } + } + } + + JS_POP (); +} + +operand neg 0 { + if (JS_SP1->type == JS_INTEGER) + JS_SP1->u.vinteger = -JS_SP1->u.vinteger; + else if (JS_SP1->type == JS_FLOAT) + JS_SP1->u.vfloat = -JS_SP1->u.vfloat; + else if (JS_SP1->type == JS_NAN) + ; + else + { + JSNode cvt; + + js_vm_to_number (vm, JS_SP1, &cvt); + + JS_SP1->type = cvt.type; + switch (cvt.type) + { + case JS_INTEGER: + JS_SP1->u.vinteger = -cvt.u.vinteger; + break; + + case JS_FLOAT: + JS_SP1->u.vfloat = -cvt.u.vfloat; + break; + + case JS_NAN: + default: + /* Nothing here. */ + break; + } + } +} + +operand and 0 { + JS_OPERAND_BINARY (&); +} + +operand not 0 { + JS_SP1->u.vboolean = JS_IS_FALSE (JS_SP1); + JS_SP1->type = JS_BOOLEAN; +} + +operand or 0 { + JS_OPERAND_BINARY (|); +} + +operand xor 0 { + JS_OPERAND_BINARY (^); +} + +operand shift_left 0 { + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger = ((JSInt32) JS_SP2->u.vinteger + << (JSUInt32) JS_SP1->u.vinteger); + JS_POP (); + } + else + { + JSInt32 l; + JSUInt32 r; + + l = js_vm_to_int32 (vm, JS_SP2); + r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1); + + JS_SP2->u.vinteger = l << r; + JS_SP2->type = JS_INTEGER; + JS_POP (); + } +} + +operand shift_right 0 { + if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER) + { + JS_SP2->u.vinteger = ((JSInt32) JS_SP2->u.vinteger + >> (JSUInt32) JS_SP1->u.vinteger); + JS_POP (); + } + else + { + JSInt32 l; + JSUInt32 r; + + l = js_vm_to_int32 (vm, JS_SP2); + r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1); + + JS_SP2->u.vinteger = l >> r; + JS_SP2->type = JS_INTEGER; + JS_POP (); + } +} + +operand shift_rright 0 { + { + JSInt32 l; + JSUInt32 r; + + l = js_vm_to_int32 (vm, JS_SP2); + r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1); + + if (r > 0) + JS_SP2->u.vinteger = (l & 0x7fffffff) >> r; + else + JS_SP2->u.vinteger = l; + + JS_SP2->type = JS_INTEGER; + JS_POP (); + } +} + +operand iffalse 4 { /* jump */ + READ_INT32 (i); + if (JS_IS_FALSE (JS_SP1)) + SETPC_RELATIVE (i); + JS_POP (); +} + +operand iftrue 4 { /* jump */ + READ_INT32 (i); + if (JS_IS_TRUE (JS_SP1)) + SETPC_RELATIVE (i); + JS_POP (); +} + +operand call_method 4 { /* symbol */ + /* Fetch the method symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (JS_SP1->u.vbuiltin->info->method_proc) + { + if ((*JS_SP1->u.vbuiltin->info->method_proc) ( + vm, + JS_SP1->u.vbuiltin->info, + JS_SP1->u.vbuiltin->instance_context, j, + &builtin_result, JS_SP2) + == JS_PROPERTY_UNKNOWN) + ERROR ("call_method: unknown method"); + } + else + ERROR ("illegal builtin object for call_method"); + + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + JS_MAYBE_GC (); + } + else if (JS_SP1->type == JS_OBJECT) + { + JSNode method; + + if (js_vm_object_load_property (vm, JS_SP1->u.vobject, j, &method) + == JS_PROPERTY_FOUND) + { + /* The property has been defined in the object. */ + + if (method.type != JS_FUNC) + ERROR ("call_method: unknown method"); + + /* And once again. We must do a subroutine call here. */ + JS_SUBROUTINE_CALL (method.u.vfunction->implementation); + } + else + /* Let our prototype handle this. */ + goto _op_call_method_try_proto; + } + else if (vm->prim[JS_SP1->type]) + { + /* The primitive language types. */ + _op_call_method_try_proto: + JS_SAVE_REGS (); + if ((*vm->prim[JS_SP1->type]->method_proc) (vm, vm->prim[JS_SP1->type], + JS_SP1, j, &builtin_result, + JS_SP2) + == JS_PROPERTY_UNKNOWN) + { + JSNode method; + int result = JS_PROPERTY_UNKNOWN; + + /* Let's see if we can find it from the prototype. */ + if (JS_SP1->type == JS_STRING && JS_SP1->u.vstring->prototype) + result = js_vm_object_load_property (vm, + JS_SP1->u.vstring->prototype, + j, &method); + else if (JS_SP1->type == JS_ARRAY && JS_SP1->u.varray->prototype) + result = js_vm_object_load_property (vm, + JS_SP1->u.varray->prototype, + j, &method); + else if (JS_SP1->type == JS_FUNC && JS_SP1->u.vfunction->prototype) + result + = js_vm_object_load_property (vm, JS_SP1->u.vfunction->prototype, + j, &method); + + if (result == JS_PROPERTY_UNKNOWN || method.type != JS_FUNC) + ERROR ("call_method: unknown method"); + + /* Do the subroutine call. */ + JS_SUBROUTINE_CALL (method.u.vfunction->implementation); + } + else + { + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + JS_MAYBE_GC (); + } + } + else + ERROR ("illegal object for call_method"); +} + +operand jmp 4 { /* jump */ + READ_INT32 (i); + SETPC_RELATIVE (i); +} + +operand jsr 0 { + /* Call the global method. */ + { + JSNode f; + + /* Fetch the function to our local variable. */ + JS_COPY (&f, JS_SP1); + function = &f; + + /* Reset the `this' to null. */ + JS_SP1->type = JS_NULL; + + if (function->type == JS_BUILTIN + && function->u.vbuiltin->info->global_method_proc) + { + JS_SAVE_REGS (); + (*function->u.vbuiltin->info->global_method_proc) ( + vm, + function->u.vbuiltin->info, + function->u.vbuiltin->instance_context, + &builtin_result, + JS_SP2); + + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + } + else if (function->type == JS_FUNC) + { + JS_SUBROUTINE_CALL (function->u.vfunction->implementation); + } + else + { + sprintf (buf, "illegal function object in jsr"); + ERROR (buf); + } + } +} + +operand return 0 { + if (fp->u.iptr == NULL) + /* Return from the global scope. */ + DONE (); + + /* STACKFRAME */ + + /* Check if the stack has been modified by min_args. */ + if (JS_ARGS_FIXP->u.args_fix.delta) + { + unsigned int delta = JS_ARGS_FIXP->u.args_fix.delta; + + /* + * Yes it was. Truncate it back to the state where it was + * before the call. + */ + + memmove (JS_SP1 + delta, JS_SP1, + (fp - JS_SP0 + JS_ARGS_FIXP->u.args_fix.argc) + * sizeof (JSNode)); + + sp += delta; + fp += delta; + } + + /* Set pc to the saved return address. */ +#if 0 + if (fp[-3].type != JS_IPTR) + ERROR ("can't find saved return address"); +#endif + pc = fp[-3].u.iptr; + + { + void *old_fp; + + /* Save old frame pointer. */ +#if 0 + if (fp->type != JS_IPTR) + ERROR ("can't find saved frame pointer"); +#endif + old_fp = fp->u.iptr; + + /* Put return value to its correct location. */ + JS_COPY (fp, JS_SP1); + + /* Restore sp. */ + sp = &fp[-1]; + + /* Restore frame pointer. */ + fp = old_fp; + } +} + +operand typeof 0 { + { + char *typeof_name = ""; /* Initialized to make compiler quiet. */ + + switch (JS_SP1->type) + { + case JS_UNDEFINED: + typeof_name = "undefined"; + break; + + case JS_NULL: + typeof_name = "object"; + break; + + case JS_BOOLEAN: + typeof_name = "boolean"; + break; + + case JS_INTEGER: + case JS_FLOAT: + case JS_NAN: + typeof_name = "number"; + break; + + case JS_STRING: + typeof_name = "string"; + break; + + case JS_ARRAY: + typeof_name = "#array"; + break; + + case JS_OBJECT: + typeof_name = "object"; + break; + + case JS_SYMBOL: + typeof_name = "#symbol"; + break; + + case JS_BUILTIN: + typeof_name = "#builtin"; + break; + + case JS_FUNC: + typeof_name = "function"; + break; + + case JS_IPTR: + typeof_name = "#iptr"; + break; + + case JS_ARGS_FIX: + typeof_name = "#argsfix"; + break; + } + + js_vm_make_static_string (vm, JS_SP1, typeof_name, strlen (typeof_name)); + JS_MAYBE_GC (); + } +} + +operand new 0 { + /* Check object. */ + if (JS_SP1->type == JS_BUILTIN && JS_SP1->u.vbuiltin->info->new_proc) + { + JS_SAVE_REGS (); + (*JS_SP1->u.vbuiltin->info->new_proc) (vm, JS_SP1->u.vbuiltin->info, + JS_SP2, JS_SP1); + + /* Push a dummy return value for the constructor. This is ignored. */ + JS_SP0->type = JS_UNDEFINED; + JS_PUSH (); + } + else if (JS_SP1->type == JS_FUNC) + { + JSObject *obj; + JSNode f; + JSNode prototype; + + /* The prototype is an object. */ + prototype.type = JS_OBJECT; + + /* Create the prototype for the function, if it is not defined. */ + if (JS_SP1->u.vfunction->prototype == NULL) + { + JS_SP1->u.vfunction->prototype = js_vm_object_new (vm); + + /* Set its __proto__ to point to Object's prototype. */ + prototype.u.vobject = vm->prim[JS_OBJECT]->prototype; + js_vm_object_store_property (vm, JS_SP1->u.vfunction->prototype, + vm->syms.s___proto__, &prototype); + } + + /* Allocate a new object and set its prototype. */ + + obj = js_vm_object_new (vm); + + prototype.u.vobject = JS_SP1->u.vfunction->prototype; + js_vm_object_store_property (vm, obj, vm->syms.s___proto__, &prototype); + + /* + * Basicly we do a jsr to the function given in JS_SP1. But first, + * we must set `this' pointer to the correct value. See `jsr' for + * the details. + */ + JS_COPY (&f, JS_SP1); + + /* Replace func with the new object. */ + JS_SP1->type = JS_OBJECT; + JS_SP1->u.vobject = obj; + + JS_SUBROUTINE_CALL (f.u.vfunction->implementation); + } + /* The primitive language types. */ + else if (vm->prim[JS_SP1->type]) + { + JS_SAVE_REGS (); + (*vm->prim[JS_SP1->type]->new_proc) (vm, vm->prim[JS_SP1->type], JS_SP2, + JS_SP1); + JS_PUSH (); + } + else + ERROR ("illegal object for new"); + + JS_MAYBE_GC (); +} + +operand delete_property 4 { /* symbol */ + /* Fetch the property symbol. */ + READ_INT32 (j); + + if (JS_SP1->type == JS_BUILTIN) + { + /* + * XXX It should be possible to apply delete operand to builtin + * XXX objects. + */ + ERROR ("delete_property: JS_BUILTIN: not implemented yet"); + } + else if (JS_SP1->type == JS_OBJECT) + { + js_vm_object_delete_property (vm, JS_SP1->u.vobject, j); + } + else if (JS_SP1->type == JS_NULL) + { + /* Delete a property from an object in the with-chain. */ + /* WITHCHAIN */ + ERROR ("delete_property: not implemented yet for the with-chain objects"); + } + /* The primitive language types. */ + /* + * XXX Since we can't delete properties from builtins, we can't delete + * XXX them from the primitive language types. + */ + else + ERROR ("illegal object for delete_property"); + + /* The delete operand returns an undefined value. */ + JS_SP1->type = JS_UNDEFINED; +} + +operand delete_array 0 { + if (JS_SP2->type == JS_BUILTIN) + { + ERROR ("delete_array: JS_BUILTIN: not implemented yet"); + } + else if (JS_SP2->type == JS_OBJECT) + { + js_vm_object_delete_array (vm, JS_SP2->u.vobject, JS_SP1); + JS_POP (); + } + else if (JS_SP2->type == JS_ARRAY) + { + if (JS_SP1->type == JS_INTEGER) + { + if (0 <= JS_SP1->u.vinteger + && JS_SP1->u.vinteger < JS_SP2->u.varray->length) + JS_SP2->u.varray->data[JS_SP1->u.vinteger].type = JS_UNDEFINED; + JS_POP (); + } + else + ERROR ("illegal array index in delete_array"); + } + else + ERROR ("illegal object for delete_array"); + + /* The delete operand returns an undefined value. */ + JS_SP1->type = JS_UNDEFINED; +} + +operand locals 2 { + READ_INT16 (i); + if (sp - i - JS_RESERVE_STACK_FOR_FUNCTION < vm->stack) + ERROR ("stack overflow"); + + for (; i > 0; i--) + { + JS_SP0->type = JS_UNDEFINED; + JS_PUSH (); + } +} + +operand min_args 1 { + READ_INT8 (i); + + if (JS_SP1->u.vinteger < i) + { + unsigned int delta = i - JS_SP1->u.vinteger; + unsigned int argc = JS_SP1->u.vinteger; + + memmove (JS_SP1 - delta, JS_SP1, (fp - JS_SP0 + argc) * sizeof (JSNode)); + sp -= delta; + fp -= delta; + + /* Fill up the fix_args slot. */ + JS_ARGS_FIXP->u.args_fix.argc = argc; + JS_ARGS_FIXP->u.args_fix.delta = delta; + + for (; argc < i; argc++) + JS_ARG (argc)->type = JS_UNDEFINED; + } + + JS_POP (); +} + +operand load_nth_arg 0 { + { + int index = JS_SP1->u.vinteger; + JS_COPY (JS_SP1, JS_ARG (index)); + } +} + +operand with_push 0 { + if (JS_SP1->type != JS_OBJECT && JS_SP1->type != JS_BUILTIN) + ERROR ("illegal object for with_push"); + + /* WITHCHAIN */ + + if (JS_WITHPTR->u.iptr == NULL) + { + JSNode *np; + JSUIntAlign *ip = js_vm_alloc (vm, + sizeof (JSUIntAlign) + + sizeof (JSNode)); + *ip = 1; + np = (JSNode *) ((unsigned char *) ip + sizeof (JSUIntAlign)); + + JS_COPY (np, JS_SP1); + JS_WITHPTR->u.iptr = ip; + } + else + { + JSNode *np; + JSUIntAlign *ip = JS_WITHPTR->u.iptr; + JSUIntAlign ui = *ip; + + ip = js_vm_realloc (vm, ip, + sizeof (JSUIntAlign) + + ((ui + 1) * sizeof (JSNode))); + (*ip)++; + np = (JSNode *) ((unsigned char *) ip + sizeof (JSUIntAlign)); + + JS_COPY (&np[ui], JS_SP1); + JS_WITHPTR->u.iptr = ip; + } + + JS_POP (); +} + +operand with_pop 1 { + READ_INT8 (i); + + /* WITHCHAIN */ + + { + JSUIntAlign *ip = JS_WITHPTR->u.iptr; + + if (ip == NULL || *ip < i) + ERROR ("with stack underflow in with_pop"); + + *ip -= i; + } +} + +operand try_push 4 { /* jump */ + READ_INT32 (i); + + { + JSErrorHandlerFrame *frame = js_calloc (vm, 1, sizeof (*frame)); + + frame->next = vm->error_handler; + frame->sp = sp; + frame->fp = fp; + frame->pc = pc; + frame->pc_delta = i; + vm->error_handler = frame; + + if (setjmp (vm->error_handler->error_jmp)) + { + /* Ok, we caught an error. */ + + /* Restore our state. */ + sp = vm->error_handler->sp; + fp = vm->error_handler->fp; + pc = vm->error_handler->pc; + i = vm->error_handler->pc_delta; + + /* Push the thrown value to the stack. */ + JS_COPY (JS_SP0, &vm->error_handler->thrown); + JS_PUSH (); + + /* Remove this handler frame. */ + frame = vm->error_handler; + vm->error_handler = vm->error_handler->next; + js_free (frame); + + /* Do the jump to the catch block. */ + SETPC_RELATIVE (i); + } + } +} + +operand try_pop 1 { + READ_INT8 (i); + + for (; i > 0; i--) + { + JSErrorHandlerFrame *frame = vm->error_handler; + + vm->error_handler = vm->error_handler->next; + js_free (frame); + } +} + +operand throw 0 { + { + JSErrorHandlerFrame *f = vm->error_handler; + + if (f->sp == NULL) + { + JSNode cvt; + int len; + + /* + * We are jumping to the C-toplevel. Convert our thrown value + * to string and store it to the vm->error. + */ + js_vm_to_string (vm, JS_SP1, &cvt); + + len = cvt.u.vstring->len; + if (len + 1 > sizeof (vm->error)) + len = sizeof (vm->error) - 1; + + memcpy (vm->error, cvt.u.vstring->data, len); + vm->error[len] = '\0'; + } + else + JS_COPY (&f->thrown, JS_SP1); + + longjmp (f->error_jmp, 1); + + /* NOTREACHED (I hope). */ + + sprintf (buf, "VM: no valid error handler initialized%s", + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); + + abort (); + } +} + +operand iffalse_b 4 { /* jump */ + READ_INT32 (i); + if (!JS_SP1->u.vboolean) + SETPC_RELATIVE (i); + JS_POP (); +} + +operand iftrue_b 4 { /* jump */ + READ_INT32 (i); + if (JS_SP1->u.vboolean) + SETPC_RELATIVE (i); + JS_POP (); +} + +operand add_1_i 0 { + JS_SP1->u.vinteger++; +} + +operand add_2_i 0 { + JS_SP1->u.vinteger += 2; +} + +operand load_global_w 4 { /* symbol */ + READ_INT32 (j); + { + int found = 0; + + /* Loop over the with chain. */ + /* WITHCHAIN */ + if (JS_WITHPTR->u.iptr) + { + JSUIntAlign *uip = JS_WITHPTR->u.iptr; + JSUIntAlign ui = *uip; + JSNode *wp = (JSNode *) ((unsigned char *) uip + + sizeof (JSUIntAlign)); + + for (i = 0; i < ui; i++) + { + JSNode *w = &wp[i]; + int result = JS_PROPERTY_UNKNOWN; + + if (w->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (w->u.vbuiltin->info->property_proc) + result = (*w->u.vbuiltin->info->property_proc) ( + vm, + w->u.vbuiltin->info, + w->u.vbuiltin->instance_context, + j, 0, &builtin_result); + } + else if (w->type == JS_OBJECT) + { + result = js_vm_object_load_property (vm, w->u.vobject, j, + &builtin_result); + } + else + ERROR ("corrupted with-chain in load_global"); + + if (result == JS_PROPERTY_FOUND) + { + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + found = 1; + break; + } + } + } + + if (!found) + { + /* Use the global value. */ + JS_COPY (JS_SP0, JS_GLOBAL (j)); + JS_PUSH (); + + if (vm->warn_undef && JS_SP1->type == JS_UNDEFINED) + { + sprintf (buf, "VM: warning: using undefined global `%s'%s", + js_vm_symname (vm, j), JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + } + } +} + +operand jsr_w 4 { /* symbol */ + /* Read the subroutine symbol index. */ + READ_INT32 (j); + + { + int found = 0; + + /* Loop over the with-chain. */ + /* WITHCHAIN */ + if (JS_WITHPTR->u.iptr) + { + JSUIntAlign *uip = JS_WITHPTR->u.iptr; + JSUIntAlign ui = *uip; + JSNode *wp = (JSNode *) ((unsigned char *) uip + + sizeof (JSUIntAlign)); + + for (i = 0; i < ui; i++) + { + JSNode *w = &wp[i]; + int result = JS_PROPERTY_UNKNOWN; + + if (w->type == JS_BUILTIN) + { + JS_SAVE_REGS (); + if (w->u.vbuiltin->info->method_proc) + result = (*w->u.vbuiltin->info->method_proc) ( + vm, + w->u.vbuiltin->info, + w->u.vbuiltin->instance_context, j, + &builtin_result, JS_SP2); + JS_MAYBE_GC (); + + if (result == JS_PROPERTY_FOUND) + { + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + } + } + else if (w->type == JS_OBJECT) + { + JSNode method; + + js_vm_object_load_property (vm, w->u.vobject, j, &method); + if (method.type == JS_FUNC) + { + result = JS_PROPERTY_FOUND; + + /* The object defines the method. Do a subroutine call. */ + + /* First: replace the null `this' with `w'. */ + JS_COPY (JS_SP1, w); + + /* Then, do the normal subroutine call. */ + JS_SUBROUTINE_CALL (method.u.vfunction->implementation); + } + } + else + ERROR ("corrupted with-chain in jsr_w"); + + if (result == JS_PROPERTY_FOUND) + { + found = 1; + break; + } + } + } + + if (!found) + { + JSNode f; + + /* Call the global method. */ + JS_COPY (&f, JS_SP1); + function = &f; + + /* Reset the `this' to null. */ + JS_SP1->type = JS_NULL; + + if (function->type == JS_BUILTIN + && function->u.vbuiltin->info->global_method_proc) + { + JS_SAVE_REGS (); + (*function->u.vbuiltin->info->global_method_proc) ( + vm, + function->u.vbuiltin->info, + function->u.vbuiltin->instance_context, + &builtin_result, + JS_SP2); + + JS_COPY (JS_SP0, &builtin_result); + JS_PUSH (); + } + else if (function->type == JS_FUNC) + { + JS_SUBROUTINE_CALL (function->u.vfunction->implementation); + } + else + { + sprintf (buf, "symbol `%s' is undefined as function", + js_vm_symname (vm, j)); + ERROR (buf); + } + } + } +} diff --git a/reactos/lib/kjs/src/r_pthrs.c b/reactos/lib/kjs/src/r_pthrs.c new file mode 100644 index 00000000000..e0a80e466ef --- /dev/null +++ b/reactos/lib/kjs/src/r_pthrs.c @@ -0,0 +1,129 @@ +/* + * Re-entrant functions from the Posix thread library. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/r_pthrs.c,v $ + * $Id: r_pthrs.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" +#include "rentrant.h" + +/* + * Types and definitions. + */ + +/* + * Global functions. + */ + +/* Time. */ + +void +js_localtime (const time_t *clock, struct tm *result) +{ + localtime_r (clock, result); +} + + +void +js_gmtime (const time_t *clock, struct tm *result) +{ + gmtime_r (clock, result); +} + + +void +js_asctime (const struct tm *tm, char *buffer, int buffer_length) +{ + asctime_r (tm, buffer +#if ASCTIME_R_WITH_THREE_ARGS + , buffer_length +#endif /* ASCTIME_R_WITH_THREE_ARGS */ + ); +} + + +/* Drand48. */ + +#if DRAND48_R_WITH_DRAND48D + +void * +js_drand48_create (JSVirtualMachine *vm) +{ + return js_malloc (vm, sizeof (DRAND48D)); +} + + +void +js_drand48_destroy (void *drand48_context) +{ + js_free (drand48_context); +} + + +void +js_srand48 (void *drand48_context, long seed) +{ + DRAND48D *ctx = drand48_context; + srand48_r (seed, ctx); +} + +void +js_drand48 (void *drand48_context, double *random_return) +{ + DRAND48D *ctx = drand48_context; + drand48_r (ctx, random_return); +} + +#else /* not DRAND48_R_WITH_DRAND48D */ + +/* We trust the drand48() to be thread-safe. */ + +void * +js_drand48_create (JSVirtualMachine *vm) +{ + return NULL; +} + + +void +js_drand48_destroy (void *drand48_context) +{ +} + + +void +js_srand48 (void *drand48_context, long seed) +{ + srand48 (seed); +} + +void +js_drand48 (void *drand48_context, double *random_return) +{ + *random_return = drand48 (); +} + +#endif /* not DRAND48_R_WITH_DRAND48D */ diff --git a/reactos/lib/kjs/src/r_std.c b/reactos/lib/kjs/src/r_std.c new file mode 100644 index 00000000000..5dd8e88f0d4 --- /dev/null +++ b/reactos/lib/kjs/src/r_std.c @@ -0,0 +1,100 @@ +/* + * Standard non re-entrant versions of the re-entrant functions. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/r_std.c,v $ + * $Id: r_std.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" +#include "rentrant.h" + +/* + * Types and definitions. + */ + +/* + * Global functions. + */ + +/* Time. */ + +void +js_localtime (const time_t *clock, struct tm *result) +{ + struct tm *tm = localtime (clock); + memcpy (result, tm, sizeof (*tm)); +} + + +void +js_gmtime (const time_t *clock, struct tm *result) +{ + struct tm *tm = gmtime (clock); + memcpy (result, tm, sizeof (*tm)); +} + + +void +js_asctime (const struct tm *tm, char *buffer, int buffer_length) +{ + char *cp = asctime (tm); + strcpy (buffer, cp); +} + + +/* Drand48. */ + +void * +js_drand48_create (JSVirtualMachine *vm) +{ + return NULL; +} + + +void +js_drand48_destroy (void *drand48_context) +{ +} + + +void +js_srand48 (void *drand48_context, long seed) +{ +#if HAVE_DRAND48 + srand48 (seed); +#else /* not HAVE_DRAND48 */ + srand (seed); +#endif /* not HAVE_DRAND48 */ +} + +void +js_drand48 (void *drand48_context, double *random_return) +{ +#if HAVE_DRAND48 + *random_return = drand48 (); +#else /* not HAVE_DRAND48 */ + *random_return = (double ) rand () / (double) INT_MAX; +#endif /* not HAVE_DRAND48 */ +} diff --git a/reactos/lib/kjs/src/regex.c b/reactos/lib/kjs/src/regex.c new file mode 100644 index 00000000000..f522230ebe9 --- /dev/null +++ b/reactos/lib/kjs/src/regex.c @@ -0,0 +1,5862 @@ +/* This is a modified version of the GNU C Library regular expression + matching library. It is modified to meet the requirements the NGS + JS interpreter has for its extension functions (re-entrancy, etc.). + All modifications are isolated with `JS' defines. You can enable + the original features by defining the pre-processor constant JS to + value 0. */ +#define JS 1 + +/* Extended regular expression matching and search library, + version 0.12. + (Implements POSIX draft P1003.2/D11.2, except for some of the + internationalization features.) + Copyright (C) 1993, 94, 95, 96, 97, 98 Free Software Foundation, Inc. + + The GNU C 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. + + The GNU C 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 the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* AIX requires this to be the first thing in the file. */ +#if defined _AIX && !defined REGEX_MALLOC + #pragma alloca +#endif + +#undef _GNU_SOURCE +#define _GNU_SOURCE + +#if JS +#include +#else /* not JS */ +#ifdef HAVE_CONFIG_H +# include +#endif +#endif /* not JS */ + +#ifndef PARAMS +# if defined __GNUC__ || (defined __STDC__ && __STDC__) +# define PARAMS(args) args +# else +# define PARAMS(args) () +# endif /* GCC. */ +#endif /* Not PARAMS. */ + +#if defined STDC_HEADERS && !defined emacs +# include +#else +/* We need this for `regex.h', and perhaps for the Emacs include files. */ +# include +#endif + +#define WIDE_CHAR_SUPPORT (HAVE_WCTYPE_H && HAVE_WCHAR_H && HAVE_BTOWC) + +/* For platform which support the ISO C amendement 1 functionality we + support user defined character classes. */ +#if defined _LIBC || WIDE_CHAR_SUPPORT +/* Solaris 2.5 has a bug: must be included before . */ +# include +# include +#endif + +#ifdef _LIBC +/* We have to keep the namespace clean. */ +# define regfree(preg) __regfree (preg) +# define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef) +# define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags) +# define regerror(errcode, preg, errbuf, errbuf_size) \ + __regerror(errcode, preg, errbuf, errbuf_size) +# define re_set_registers(bu, re, nu, st, en) \ + __re_set_registers (bu, re, nu, st, en) +# define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \ + __re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) +# define re_match(bufp, string, size, pos, regs) \ + __re_match (bufp, string, size, pos, regs) +# define re_search(bufp, string, size, startpos, range, regs) \ + __re_search (bufp, string, size, startpos, range, regs) +# define re_compile_pattern(pattern, length, bufp) \ + __re_compile_pattern (pattern, length, bufp) +# define re_set_syntax(syntax) __re_set_syntax (syntax) +# define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \ + __re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop) +# define re_compile_fastmap(bufp) __re_compile_fastmap (bufp) + +#define btowc __btowc +#endif + +/* This is for other GNU distributions with internationalized messages. */ +#if HAVE_LIBINTL_H || defined _LIBC +# include +#else +# define gettext(msgid) (msgid) +#endif + +#ifndef gettext_noop +/* This define is so xgettext can find the internationalizable + strings. */ +# define gettext_noop(String) String +#endif + +/* The `emacs' switch turns on certain matching commands + that make sense only in Emacs. */ +#ifdef emacs + +# include "lisp.h" +# include "buffer.h" +# include "syntax.h" + +#else /* not emacs */ + +/* If we are not linking with Emacs proper, + we can't use the relocating allocator + even if config.h says that we can. */ +# undef REL_ALLOC + +# if defined STDC_HEADERS || defined _LIBC +# include +# else +char *malloc (); +char *realloc (); +# endif + +/* When used in Emacs's lib-src, we need to get bzero and bcopy somehow. + If nothing else has been done, use the method below. */ +# ifdef INHIBIT_STRING_HEADER +# if !(defined HAVE_BZERO && defined HAVE_BCOPY) +# if !defined bzero && !defined bcopy +# undef INHIBIT_STRING_HEADER +# endif +# endif +# endif + +/* This is the normal way of making sure we have a bcopy and a bzero. + This is used in most programs--a few other programs avoid this + by defining INHIBIT_STRING_HEADER. */ +# ifndef INHIBIT_STRING_HEADER +# if defined HAVE_STRING_H || defined STDC_HEADERS || defined _LIBC +# include +# ifndef bzero +# ifndef _LIBC +# define bzero(s, n) (memset (s, '\0', n), (s)) +# else +# define bzero(s, n) __bzero (s, n) +# endif +# endif +# else +# include +# ifndef memcmp +# define memcmp(s1, s2, n) bcmp (s1, s2, n) +# endif +# ifndef memcpy +# define memcpy(d, s, n) (bcopy (s, d, n), (d)) +# endif +# endif +# endif + +/* Define the syntax stuff for \<, \>, etc. */ + +/* This must be nonzero for the wordchar and notwordchar pattern + commands in re_match_2. */ +# ifndef Sword +# define Sword 1 +# endif + +# ifdef SWITCH_ENUM_BUG +# define SWITCH_ENUM_CAST(x) ((int)(x)) +# else +# define SWITCH_ENUM_CAST(x) (x) +# endif + +/* How many characters in the character set. */ +# define CHAR_SET_SIZE 256 + +# ifdef SYNTAX_TABLE + +extern char *re_syntax_table; + +# else /* not SYNTAX_TABLE */ + +#if JS +static char re_syntax_table[CHAR_SET_SIZE] = +{ +/* + 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 - 0x0f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x2f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3f */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50 - 0x5f */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70 - 0x7f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 - 0xaf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 - 0xbf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 - 0xcf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 - 0xdf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 - 0xef */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xf0 - 0xff */ +}; + +static void +init_syntax_once () +{ + /* Nothing here. */ +} +#else /* not JS */ +static char re_syntax_table[CHAR_SET_SIZE]; + +static void +init_syntax_once () +{ + register int c; + static int done = 0; + + if (done) + return; + + bzero (re_syntax_table, sizeof re_syntax_table); + + for (c = 'a'; c <= 'z'; c++) + re_syntax_table[c] = Sword; + + for (c = 'A'; c <= 'Z'; c++) + re_syntax_table[c] = Sword; + + for (c = '0'; c <= '9'; c++) + re_syntax_table[c] = Sword; + + re_syntax_table['_'] = Sword; + + done = 1; +} +#endif /* not JS */ + +# endif /* not SYNTAX_TABLE */ + +# define SYNTAX(c) re_syntax_table[c] + +#endif /* not emacs */ + +/* Get the interface, including the syntax bits. */ +#include "regex.h" + +/* isalpha etc. are used for the character classes. */ +#include + +/* Jim Meyering writes: + + "... Some ctype macros are valid only for character codes that + isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when + using /bin/cc or gcc but without giving an ansi option). So, all + ctype uses should be through macros like ISPRINT... If + STDC_HEADERS is defined, then autoconf has verified that the ctype + macros don't need to be guarded with references to isascii. ... + Defining isascii to 1 should let any compiler worth its salt + eliminate the && through constant folding." + Solaris defines some of these symbols so we must undefine them first. */ + +#undef ISASCII +#if defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII) +# define ISASCII(c) 1 +#else +# define ISASCII(c) isascii(c) +#endif + +#ifdef isblank +# define ISBLANK(c) (ISASCII (c) && isblank (c)) +#else +# define ISBLANK(c) ((c) == ' ' || (c) == '\t') +#endif +#ifdef isgraph +# define ISGRAPH(c) (ISASCII (c) && isgraph (c)) +#else +# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c)) +#endif + +#undef ISPRINT +#define ISPRINT(c) (ISASCII (c) && isprint (c)) +#define ISDIGIT(c) (ISASCII (c) && isdigit (c)) +#define ISALNUM(c) (ISASCII (c) && isalnum (c)) +#define ISALPHA(c) (ISASCII (c) && isalpha (c)) +#define ISCNTRL(c) (ISASCII (c) && iscntrl (c)) +#define ISLOWER(c) (ISASCII (c) && islower (c)) +#define ISPUNCT(c) (ISASCII (c) && ispunct (c)) +#define ISSPACE(c) (ISASCII (c) && isspace (c)) +#define ISUPPER(c) (ISASCII (c) && isupper (c)) +#define ISXDIGIT(c) (ISASCII (c) && isxdigit (c)) + +#ifndef NULL +# define NULL (void *)0 +#endif + +/* We remove any previous definition of `SIGN_EXTEND_CHAR', + since ours (we hope) works properly with all combinations of + machines, compilers, `char' and `unsigned char' argument types. + (Per Bothner suggested the basic approach.) */ +#undef SIGN_EXTEND_CHAR +#if __STDC__ +# define SIGN_EXTEND_CHAR(c) ((signed char) (c)) +#else /* not __STDC__ */ +/* As in Harbison and Steele. */ +# define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128) +#endif + +/* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we + use `alloca' instead of `malloc'. This is because using malloc in + re_search* or re_match* could cause memory leaks when C-g is used in + Emacs; also, malloc is slower and causes storage fragmentation. On + the other hand, malloc is more portable, and easier to debug. + + Because we sometimes use alloca, some routines have to be macros, + not functions -- `alloca'-allocated space disappears at the end of the + function it is called in. */ + +#ifdef REGEX_MALLOC + +# define REGEX_ALLOCATE malloc +# define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize) +# define REGEX_FREE free + +#else /* not REGEX_MALLOC */ + +/* Emacs already defines alloca, sometimes. */ +# ifndef alloca + +/* Make alloca work the best possible way. */ +# ifdef __GNUC__ +# define alloca __builtin_alloca +# else /* not __GNUC__ */ +# if HAVE_ALLOCA_H +# include +# endif /* HAVE_ALLOCA_H */ +# endif /* not __GNUC__ */ + +# endif /* not alloca */ + +# define REGEX_ALLOCATE alloca + +/* Assumes a `char *destination' variable. */ +# define REGEX_REALLOCATE(source, osize, nsize) \ + (destination = (char *) alloca (nsize), \ + memcpy (destination, source, osize)) + +/* No need to do anything to free, after alloca. */ +# define REGEX_FREE(arg) ((void)0) /* Do nothing! But inhibit gcc warning. */ + +#endif /* not REGEX_MALLOC */ + +/* Define how to allocate the failure stack. */ + +#if defined REL_ALLOC && defined REGEX_MALLOC + +# define REGEX_ALLOCATE_STACK(size) \ + r_alloc (&failure_stack_ptr, (size)) +# define REGEX_REALLOCATE_STACK(source, osize, nsize) \ + r_re_alloc (&failure_stack_ptr, (nsize)) +# define REGEX_FREE_STACK(ptr) \ + r_alloc_free (&failure_stack_ptr) + +#else /* not using relocating allocator */ + +# ifdef REGEX_MALLOC + +# define REGEX_ALLOCATE_STACK malloc +# define REGEX_REALLOCATE_STACK(source, osize, nsize) realloc (source, nsize) +# define REGEX_FREE_STACK free + +# else /* not REGEX_MALLOC */ + +# define REGEX_ALLOCATE_STACK alloca + +# define REGEX_REALLOCATE_STACK(source, osize, nsize) \ + REGEX_REALLOCATE (source, osize, nsize) +/* No need to explicitly free anything. */ +# define REGEX_FREE_STACK(arg) + +# endif /* not REGEX_MALLOC */ +#endif /* not using relocating allocator */ + + +/* True if `size1' is non-NULL and PTR is pointing anywhere inside + `string1' or just past its end. This works if PTR is NULL, which is + a good thing. */ +#define FIRST_STRING_P(ptr) \ + (size1 && string1 <= (ptr) && (ptr) <= string1 + size1) + +/* (Re)Allocate N items of type T using malloc, or fail. */ +#define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t))) +#define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t))) +#define RETALLOC_IF(addr, n, t) \ + if (addr) RETALLOC((addr), (n), t); else (addr) = TALLOC ((n), t) +#define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t))) + +#define BYTEWIDTH 8 /* In bits. */ + +#define STREQ(s1, s2) ((strcmp (s1, s2) == 0)) + +#undef MAX +#undef MIN +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +typedef char boolean; +#define false 0 +#define true 1 + +static int re_match_2_internal PARAMS ((struct re_pattern_buffer *bufp, + const char *string1, int size1, + const char *string2, int size2, + int pos, + struct re_registers *regs, + int stop)); + +/* These are the command codes that appear in compiled regular + expressions. Some opcodes are followed by argument bytes. A + command code can specify any interpretation whatsoever for its + arguments. Zero bytes may appear in the compiled regular expression. */ + +typedef enum +{ + no_op = 0, + + /* Succeed right away--no more backtracking. */ + succeed, + + /* Followed by one byte giving n, then by n literal bytes. */ + exactn, + + /* Matches any (more or less) character. */ + anychar, + + /* Matches any one char belonging to specified set. First + following byte is number of bitmap bytes. Then come bytes + for a bitmap saying which chars are in. Bits in each byte + are ordered low-bit-first. A character is in the set if its + bit is 1. A character too large to have a bit in the map is + automatically not in the set. */ + charset, + + /* Same parameters as charset, but match any character that is + not one of those specified. */ + charset_not, + + /* Start remembering the text that is matched, for storing in a + register. Followed by one byte with the register number, in + the range 0 to one less than the pattern buffer's re_nsub + field. Then followed by one byte with the number of groups + inner to this one. (This last has to be part of the + start_memory only because we need it in the on_failure_jump + of re_match_2.) */ + start_memory, + + /* Stop remembering the text that is matched and store it in a + memory register. Followed by one byte with the register + number, in the range 0 to one less than `re_nsub' in the + pattern buffer, and one byte with the number of inner groups, + just like `start_memory'. (We need the number of inner + groups here because we don't have any easy way of finding the + corresponding start_memory when we're at a stop_memory.) */ + stop_memory, + + /* Match a duplicate of something remembered. Followed by one + byte containing the register number. */ + duplicate, + + /* Fail unless at beginning of line. */ + begline, + + /* Fail unless at end of line. */ + endline, + + /* Succeeds if at beginning of buffer (if emacs) or at beginning + of string to be matched (if not). */ + begbuf, + + /* Analogously, for end of buffer/string. */ + endbuf, + + /* Followed by two byte relative address to which to jump. */ + jump, + + /* Same as jump, but marks the end of an alternative. */ + jump_past_alt, + + /* Followed by two-byte relative address of place to resume at + in case of failure. */ + on_failure_jump, + + /* Like on_failure_jump, but pushes a placeholder instead of the + current string position when executed. */ + on_failure_keep_string_jump, + + /* Throw away latest failure point and then jump to following + two-byte relative address. */ + pop_failure_jump, + + /* Change to pop_failure_jump if know won't have to backtrack to + match; otherwise change to jump. This is used to jump + back to the beginning of a repeat. If what follows this jump + clearly won't match what the repeat does, such that we can be + sure that there is no use backtracking out of repetitions + already matched, then we change it to a pop_failure_jump. + Followed by two-byte address. */ + maybe_pop_jump, + + /* Jump to following two-byte address, and push a dummy failure + point. This failure point will be thrown away if an attempt + is made to use it for a failure. A `+' construct makes this + before the first repeat. Also used as an intermediary kind + of jump when compiling an alternative. */ + dummy_failure_jump, + + /* Push a dummy failure point and continue. Used at the end of + alternatives. */ + push_dummy_failure, + + /* Followed by two-byte relative address and two-byte number n. + After matching N times, jump to the address upon failure. */ + succeed_n, + + /* Followed by two-byte relative address, and two-byte number n. + Jump to the address N times, then fail. */ + jump_n, + + /* Set the following two-byte relative address to the + subsequent two-byte number. The address *includes* the two + bytes of number. */ + set_number_at, + + wordchar, /* Matches any word-constituent character. */ + notwordchar, /* Matches any char that is not a word-constituent. */ + + wordbeg, /* Succeeds if at word beginning. */ + wordend, /* Succeeds if at word end. */ + + wordbound, /* Succeeds if at a word boundary. */ + notwordbound /* Succeeds if not at a word boundary. */ + +#ifdef emacs + ,before_dot, /* Succeeds if before point. */ + at_dot, /* Succeeds if at point. */ + after_dot, /* Succeeds if after point. */ + + /* Matches any character whose syntax is specified. Followed by + a byte which contains a syntax code, e.g., Sword. */ + syntaxspec, + + /* Matches any character whose syntax is not that specified. */ + notsyntaxspec +#endif /* emacs */ +} re_opcode_t; + +/* Common operations on the compiled pattern. */ + +/* Store NUMBER in two contiguous bytes starting at DESTINATION. */ + +#define STORE_NUMBER(destination, number) \ + do { \ + (destination)[0] = (number) & 0377; \ + (destination)[1] = (number) >> 8; \ + } while (0) + +/* Same as STORE_NUMBER, except increment DESTINATION to + the byte after where the number is stored. Therefore, DESTINATION + must be an lvalue. */ + +#define STORE_NUMBER_AND_INCR(destination, number) \ + do { \ + STORE_NUMBER (destination, number); \ + (destination) += 2; \ + } while (0) + +/* Put into DESTINATION a number stored in two contiguous bytes starting + at SOURCE. */ + +#define EXTRACT_NUMBER(destination, source) \ + do { \ + (destination) = *(source) & 0377; \ + (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \ + } while (0) + +#ifdef DEBUG +static void extract_number _RE_ARGS ((int *dest, unsigned char *source)); +static void +extract_number (dest, source) + int *dest; + unsigned char *source; +{ + int temp = SIGN_EXTEND_CHAR (*(source + 1)); + *dest = *source & 0377; + *dest += temp << 8; +} + +# ifndef EXTRACT_MACROS /* To debug the macros. */ +# undef EXTRACT_NUMBER +# define EXTRACT_NUMBER(dest, src) extract_number (&dest, src) +# endif /* not EXTRACT_MACROS */ + +#endif /* DEBUG */ + +/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number. + SOURCE must be an lvalue. */ + +#define EXTRACT_NUMBER_AND_INCR(destination, source) \ + do { \ + EXTRACT_NUMBER (destination, source); \ + (source) += 2; \ + } while (0) + +#ifdef DEBUG +static void extract_number_and_incr _RE_ARGS ((int *destination, + unsigned char **source)); +static void +extract_number_and_incr (destination, source) + int *destination; + unsigned char **source; +{ + extract_number (destination, *source); + *source += 2; +} + +# ifndef EXTRACT_MACROS +# undef EXTRACT_NUMBER_AND_INCR +# define EXTRACT_NUMBER_AND_INCR(dest, src) \ + extract_number_and_incr (&dest, &src) +# endif /* not EXTRACT_MACROS */ + +#endif /* DEBUG */ + +/* If DEBUG is defined, Regex prints many voluminous messages about what + it is doing (if the variable `debug' is nonzero). If linked with the + main program in `iregex.c', you can enter patterns and strings + interactively. And if linked with the main program in `main.c' and + the other test files, you can run the already-written tests. */ + +#ifdef DEBUG + +/* We use standard I/O for debugging. */ +# include + +/* It is useful to test things that ``must'' be true when debugging. */ +# include + +static int debug = 0; + +# define DEBUG_STATEMENT(e) e +# define DEBUG_PRINT1(x) if (debug) printf (x) +# define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2) +# define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3) +# define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4) +# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \ + if (debug) print_partial_compiled_pattern (s, e) +# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \ + if (debug) print_double_string (w, s1, sz1, s2, sz2) + + +/* Print the fastmap in human-readable form. */ + +void +print_fastmap (fastmap) + char *fastmap; +{ + unsigned was_a_range = 0; + unsigned i = 0; + + while (i < (1 << BYTEWIDTH)) + { + if (fastmap[i++]) + { + was_a_range = 0; + putchar (i - 1); + while (i < (1 << BYTEWIDTH) && fastmap[i]) + { + was_a_range = 1; + i++; + } + if (was_a_range) + { + printf ("-"); + putchar (i - 1); + } + } + } + putchar ('\n'); +} + + +/* Print a compiled pattern string in human-readable form, starting at + the START pointer into it and ending just before the pointer END. */ + +void +print_partial_compiled_pattern (start, end) + unsigned char *start; + unsigned char *end; +{ + int mcnt, mcnt2; + unsigned char *p1; + unsigned char *p = start; + unsigned char *pend = end; + + if (start == NULL) + { + printf ("(null)\n"); + return; + } + + /* Loop over pattern commands. */ + while (p < pend) + { + printf ("%d:\t", p - start); + + switch ((re_opcode_t) *p++) + { + case no_op: + printf ("/no_op"); + break; + + case exactn: + mcnt = *p++; + printf ("/exactn/%d", mcnt); + do + { + putchar ('/'); + putchar (*p++); + } + while (--mcnt); + break; + + case start_memory: + mcnt = *p++; + printf ("/start_memory/%d/%d", mcnt, *p++); + break; + + case stop_memory: + mcnt = *p++; + printf ("/stop_memory/%d/%d", mcnt, *p++); + break; + + case duplicate: + printf ("/duplicate/%d", *p++); + break; + + case anychar: + printf ("/anychar"); + break; + + case charset: + case charset_not: + { + register int c, last = -100; + register int in_range = 0; + + printf ("/charset [%s", + (re_opcode_t) *(p - 1) == charset_not ? "^" : ""); + + assert (p + *p < pend); + + for (c = 0; c < 256; c++) + if (c / 8 < *p + && (p[1 + (c/8)] & (1 << (c % 8)))) + { + /* Are we starting a range? */ + if (last + 1 == c && ! in_range) + { + putchar ('-'); + in_range = 1; + } + /* Have we broken a range? */ + else if (last + 1 != c && in_range) + { + putchar (last); + in_range = 0; + } + + if (! in_range) + putchar (c); + + last = c; + } + + if (in_range) + putchar (last); + + putchar (']'); + + p += 1 + *p; + } + break; + + case begline: + printf ("/begline"); + break; + + case endline: + printf ("/endline"); + break; + + case on_failure_jump: + extract_number_and_incr (&mcnt, &p); + printf ("/on_failure_jump to %d", p + mcnt - start); + break; + + case on_failure_keep_string_jump: + extract_number_and_incr (&mcnt, &p); + printf ("/on_failure_keep_string_jump to %d", p + mcnt - start); + break; + + case dummy_failure_jump: + extract_number_and_incr (&mcnt, &p); + printf ("/dummy_failure_jump to %d", p + mcnt - start); + break; + + case push_dummy_failure: + printf ("/push_dummy_failure"); + break; + + case maybe_pop_jump: + extract_number_and_incr (&mcnt, &p); + printf ("/maybe_pop_jump to %d", p + mcnt - start); + break; + + case pop_failure_jump: + extract_number_and_incr (&mcnt, &p); + printf ("/pop_failure_jump to %d", p + mcnt - start); + break; + + case jump_past_alt: + extract_number_and_incr (&mcnt, &p); + printf ("/jump_past_alt to %d", p + mcnt - start); + break; + + case jump: + extract_number_and_incr (&mcnt, &p); + printf ("/jump to %d", p + mcnt - start); + break; + + case succeed_n: + extract_number_and_incr (&mcnt, &p); + p1 = p + mcnt; + extract_number_and_incr (&mcnt2, &p); + printf ("/succeed_n to %d, %d times", p1 - start, mcnt2); + break; + + case jump_n: + extract_number_and_incr (&mcnt, &p); + p1 = p + mcnt; + extract_number_and_incr (&mcnt2, &p); + printf ("/jump_n to %d, %d times", p1 - start, mcnt2); + break; + + case set_number_at: + extract_number_and_incr (&mcnt, &p); + p1 = p + mcnt; + extract_number_and_incr (&mcnt2, &p); + printf ("/set_number_at location %d to %d", p1 - start, mcnt2); + break; + + case wordbound: + printf ("/wordbound"); + break; + + case notwordbound: + printf ("/notwordbound"); + break; + + case wordbeg: + printf ("/wordbeg"); + break; + + case wordend: + printf ("/wordend"); + +# ifdef emacs + case before_dot: + printf ("/before_dot"); + break; + + case at_dot: + printf ("/at_dot"); + break; + + case after_dot: + printf ("/after_dot"); + break; + + case syntaxspec: + printf ("/syntaxspec"); + mcnt = *p++; + printf ("/%d", mcnt); + break; + + case notsyntaxspec: + printf ("/notsyntaxspec"); + mcnt = *p++; + printf ("/%d", mcnt); + break; +# endif /* emacs */ + + case wordchar: + printf ("/wordchar"); + break; + + case notwordchar: + printf ("/notwordchar"); + break; + + case begbuf: + printf ("/begbuf"); + break; + + case endbuf: + printf ("/endbuf"); + break; + + default: + printf ("?%d", *(p-1)); + } + + putchar ('\n'); + } + + printf ("%d:\tend of pattern.\n", p - start); +} + + +void +print_compiled_pattern (bufp) + struct re_pattern_buffer *bufp; +{ + unsigned char *buffer = bufp->buffer; + + print_partial_compiled_pattern (buffer, buffer + bufp->used); + printf ("%ld bytes used/%ld bytes allocated.\n", + bufp->used, bufp->allocated); + + if (bufp->fastmap_accurate && bufp->fastmap) + { + printf ("fastmap: "); + print_fastmap (bufp->fastmap); + } + + printf ("re_nsub: %d\t", bufp->re_nsub); + printf ("regs_alloc: %d\t", bufp->regs_allocated); + printf ("can_be_null: %d\t", bufp->can_be_null); + printf ("newline_anchor: %d\n", bufp->newline_anchor); + printf ("no_sub: %d\t", bufp->no_sub); + printf ("not_bol: %d\t", bufp->not_bol); + printf ("not_eol: %d\t", bufp->not_eol); + printf ("syntax: %lx\n", bufp->syntax); + /* Perhaps we should print the translate table? */ +} + + +void +print_double_string (where, string1, size1, string2, size2) + const char *where; + const char *string1; + const char *string2; + int size1; + int size2; +{ + int this_char; + + if (where == NULL) + printf ("(null)"); + else + { + if (FIRST_STRING_P (where)) + { + for (this_char = where - string1; this_char < size1; this_char++) + putchar (string1[this_char]); + + where = string2; + } + + for (this_char = where - string2; this_char < size2; this_char++) + putchar (string2[this_char]); + } +} + +void +printchar (c) + int c; +{ + putc (c, stderr); +} + +#else /* not DEBUG */ + +# undef assert +# define assert(e) + +# define DEBUG_STATEMENT(e) +# define DEBUG_PRINT1(x) +# define DEBUG_PRINT2(x1, x2) +# define DEBUG_PRINT3(x1, x2, x3) +# define DEBUG_PRINT4(x1, x2, x3, x4) +# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) +# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) + +#endif /* not DEBUG */ + +#if JS +reg_syntax_t re_syntax_options = RE_SYNTAX_GNU_AWK; +#else /* not JS */ +/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can + also be assigned to arbitrarily: each pattern buffer stores its own + syntax, so it can be changed between regex compilations. */ +/* This has no initializer because initialized variables in Emacs + become read-only after dumping. */ +reg_syntax_t re_syntax_options; +#endif /* not JS */ + + +/* Specify the precise syntax of regexps for compilation. This provides + for compatibility for various utilities which historically have + different, incompatible syntaxes. + + The argument SYNTAX is a bit mask comprised of the various bits + defined in regex.h. We return the old syntax. */ + +reg_syntax_t +re_set_syntax (syntax) + reg_syntax_t syntax; +{ + reg_syntax_t ret = re_syntax_options; + + re_syntax_options = syntax; +#ifdef DEBUG + if (syntax & RE_DEBUG) + debug = 1; + else if (debug) /* was on but now is not */ + debug = 0; +#endif /* DEBUG */ + return ret; +} +#ifdef _LIBC +weak_alias (__re_set_syntax, re_set_syntax) +#endif + +/* This table gives an error message for each of the error codes listed + in regex.h. Obviously the order here has to be same as there. + POSIX doesn't require that we do anything for REG_NOERROR, + but why not be nice? */ + +static const char *re_error_msgid[] = + { + gettext_noop ("Success"), /* REG_NOERROR */ + gettext_noop ("No match"), /* REG_NOMATCH */ + gettext_noop ("Invalid regular expression"), /* REG_BADPAT */ + gettext_noop ("Invalid collation character"), /* REG_ECOLLATE */ + gettext_noop ("Invalid character class name"), /* REG_ECTYPE */ + gettext_noop ("Trailing backslash"), /* REG_EESCAPE */ + gettext_noop ("Invalid back reference"), /* REG_ESUBREG */ + gettext_noop ("Unmatched [ or [^"), /* REG_EBRACK */ + gettext_noop ("Unmatched ( or \\("), /* REG_EPAREN */ + gettext_noop ("Unmatched \\{"), /* REG_EBRACE */ + gettext_noop ("Invalid content of \\{\\}"), /* REG_BADBR */ + gettext_noop ("Invalid range end"), /* REG_ERANGE */ + gettext_noop ("Memory exhausted"), /* REG_ESPACE */ + gettext_noop ("Invalid preceding regular expression"), /* REG_BADRPT */ + gettext_noop ("Premature end of regular expression"), /* REG_EEND */ + gettext_noop ("Regular expression too big"), /* REG_ESIZE */ + gettext_noop ("Unmatched ) or \\)"), /* REG_ERPAREN */ + }; + +/* Avoiding alloca during matching, to placate r_alloc. */ + +/* Define MATCH_MAY_ALLOCATE unless we need to make sure that the + searching and matching functions should not call alloca. On some + systems, alloca is implemented in terms of malloc, and if we're + using the relocating allocator routines, then malloc could cause a + relocation, which might (if the strings being searched are in the + ralloc heap) shift the data out from underneath the regexp + routines. + + Here's another reason to avoid allocation: Emacs + processes input from X in a signal handler; processing X input may + call malloc; if input arrives while a matching routine is calling + malloc, then we're scrod. But Emacs can't just block input while + calling matching routines; then we don't notice interrupts when + they come in. So, Emacs blocks input around all regexp calls + except the matching calls, which it leaves unprotected, in the + faith that they will not malloc. */ + +/* Normally, this is fine. */ +#define MATCH_MAY_ALLOCATE + +/* When using GNU C, we are not REALLY using the C alloca, no matter + what config.h may say. So don't take precautions for it. */ +#ifdef __GNUC__ +# undef C_ALLOCA +#endif + +/* The match routines may not allocate if (1) they would do it with malloc + and (2) it's not safe for them to use malloc. + Note that if REL_ALLOC is defined, matching would not use malloc for the + failure stack, but we would still use it for the register vectors; + so REL_ALLOC should not affect this. */ +#if (defined C_ALLOCA || defined REGEX_MALLOC) && defined emacs +# undef MATCH_MAY_ALLOCATE +#endif + + +/* Failure stack declarations and macros; both re_compile_fastmap and + re_match_2 use a failure stack. These have to be macros because of + REGEX_ALLOCATE_STACK. */ + + +/* Number of failure points for which to initially allocate space + when matching. If this number is exceeded, we allocate more + space, so it is not a hard limit. */ +#ifndef INIT_FAILURE_ALLOC +# define INIT_FAILURE_ALLOC 5 +#endif + +/* Roughly the maximum number of failure points on the stack. Would be + exactly that if always used MAX_FAILURE_ITEMS items each time we failed. + This is a variable only so users of regex can assign to it; we never + change it ourselves. */ + +#ifdef INT_IS_16BIT + +# if defined MATCH_MAY_ALLOCATE +/* 4400 was enough to cause a crash on Alpha OSF/1, + whose default stack limit is 2mb. */ +long int re_max_failures = 4000; +# else +long int re_max_failures = 2000; +# endif + +union fail_stack_elt +{ + unsigned char *pointer; + long int integer; +}; + +typedef union fail_stack_elt fail_stack_elt_t; + +typedef struct +{ + fail_stack_elt_t *stack; + unsigned long int size; + unsigned long int avail; /* Offset of next open position. */ +} fail_stack_type; + +#else /* not INT_IS_16BIT */ + +# if defined MATCH_MAY_ALLOCATE +/* 4400 was enough to cause a crash on Alpha OSF/1, + whose default stack limit is 2mb. */ +int re_max_failures = 20000; +# else +int re_max_failures = 2000; +# endif + +union fail_stack_elt +{ + unsigned char *pointer; + int integer; +}; + +typedef union fail_stack_elt fail_stack_elt_t; + +typedef struct +{ + fail_stack_elt_t *stack; + unsigned size; + unsigned avail; /* Offset of next open position. */ +} fail_stack_type; + +#endif /* INT_IS_16BIT */ + +#define FAIL_STACK_EMPTY() (fail_stack.avail == 0) +#define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0) +#define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size) + + +/* Define macros to initialize and free the failure stack. + Do `return -2' if the alloc fails. */ + +#ifdef MATCH_MAY_ALLOCATE +# define INIT_FAIL_STACK() \ + do { \ + fail_stack.stack = (fail_stack_elt_t *) \ + REGEX_ALLOCATE_STACK (INIT_FAILURE_ALLOC * sizeof (fail_stack_elt_t)); \ + \ + if (fail_stack.stack == NULL) \ + return -2; \ + \ + fail_stack.size = INIT_FAILURE_ALLOC; \ + fail_stack.avail = 0; \ + } while (0) + +# define RESET_FAIL_STACK() REGEX_FREE_STACK (fail_stack.stack) +#else +# define INIT_FAIL_STACK() \ + do { \ + fail_stack.avail = 0; \ + } while (0) + +# define RESET_FAIL_STACK() +#endif + + +/* Double the size of FAIL_STACK, up to approximately `re_max_failures' items. + + Return 1 if succeeds, and 0 if either ran out of memory + allocating space for it or it was already too large. + + REGEX_REALLOCATE_STACK requires `destination' be declared. */ + +#define DOUBLE_FAIL_STACK(fail_stack) \ + ((fail_stack).size > (unsigned) (re_max_failures * MAX_FAILURE_ITEMS) \ + ? 0 \ + : ((fail_stack).stack = (fail_stack_elt_t *) \ + REGEX_REALLOCATE_STACK ((fail_stack).stack, \ + (fail_stack).size * sizeof (fail_stack_elt_t), \ + ((fail_stack).size << 1) * sizeof (fail_stack_elt_t)), \ + \ + (fail_stack).stack == NULL \ + ? 0 \ + : ((fail_stack).size <<= 1, \ + 1))) + + +/* Push pointer POINTER on FAIL_STACK. + Return 1 if was able to do so and 0 if ran out of memory allocating + space to do so. */ +#define PUSH_PATTERN_OP(POINTER, FAIL_STACK) \ + ((FAIL_STACK_FULL () \ + && !DOUBLE_FAIL_STACK (FAIL_STACK)) \ + ? 0 \ + : ((FAIL_STACK).stack[(FAIL_STACK).avail++].pointer = POINTER, \ + 1)) + +/* Push a pointer value onto the failure stack. + Assumes the variable `fail_stack'. Probably should only + be called from within `PUSH_FAILURE_POINT'. */ +#define PUSH_FAILURE_POINTER(item) \ + fail_stack.stack[fail_stack.avail++].pointer = (unsigned char *) (item) + +/* This pushes an integer-valued item onto the failure stack. + Assumes the variable `fail_stack'. Probably should only + be called from within `PUSH_FAILURE_POINT'. */ +#define PUSH_FAILURE_INT(item) \ + fail_stack.stack[fail_stack.avail++].integer = (item) + +/* Push a fail_stack_elt_t value onto the failure stack. + Assumes the variable `fail_stack'. Probably should only + be called from within `PUSH_FAILURE_POINT'. */ +#define PUSH_FAILURE_ELT(item) \ + fail_stack.stack[fail_stack.avail++] = (item) + +/* These three POP... operations complement the three PUSH... operations. + All assume that `fail_stack' is nonempty. */ +#define POP_FAILURE_POINTER() fail_stack.stack[--fail_stack.avail].pointer +#define POP_FAILURE_INT() fail_stack.stack[--fail_stack.avail].integer +#define POP_FAILURE_ELT() fail_stack.stack[--fail_stack.avail] + +/* Used to omit pushing failure point id's when we're not debugging. */ +#ifdef DEBUG +# define DEBUG_PUSH PUSH_FAILURE_INT +# define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_INT () +#else +# define DEBUG_PUSH(item) +# define DEBUG_POP(item_addr) +#endif + + +/* Push the information about the state we will need + if we ever fail back to it. + + Requires variables fail_stack, regstart, regend, reg_info, and + num_regs_pushed be declared. DOUBLE_FAIL_STACK requires `destination' + be declared. + + Does `return FAILURE_CODE' if runs out of memory. */ + +#define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code) \ + do { \ + char *destination; \ + /* Must be int, so when we don't save any registers, the arithmetic \ + of 0 + -1 isn't done as unsigned. */ \ + /* Can't be int, since there is not a shred of a guarantee that int \ + is wide enough to hold a value of something to which pointer can \ + be assigned */ \ + active_reg_t this_reg; \ + \ + DEBUG_STATEMENT (failure_id++); \ + DEBUG_STATEMENT (nfailure_points_pushed++); \ + DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \ + DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail);\ + DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\ + \ + DEBUG_PRINT2 (" slots needed: %ld\n", NUM_FAILURE_ITEMS); \ + DEBUG_PRINT2 (" available: %d\n", REMAINING_AVAIL_SLOTS); \ + \ + /* Ensure we have enough space allocated for what we will push. */ \ + while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \ + { \ + if (!DOUBLE_FAIL_STACK (fail_stack)) \ + return failure_code; \ + \ + DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \ + (fail_stack).size); \ + DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\ + } \ + \ + /* Push the info, starting with the registers. */ \ + DEBUG_PRINT1 ("\n"); \ + \ + if (1) \ + for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \ + this_reg++) \ + { \ + DEBUG_PRINT2 (" Pushing reg: %lu\n", this_reg); \ + DEBUG_STATEMENT (num_regs_pushed++); \ + \ + DEBUG_PRINT2 (" start: %p\n", regstart[this_reg]); \ + PUSH_FAILURE_POINTER (regstart[this_reg]); \ + \ + DEBUG_PRINT2 (" end: %p\n", regend[this_reg]); \ + PUSH_FAILURE_POINTER (regend[this_reg]); \ + \ + DEBUG_PRINT2 (" info: %p\n ", \ + reg_info[this_reg].word.pointer); \ + DEBUG_PRINT2 (" match_null=%d", \ + REG_MATCH_NULL_STRING_P (reg_info[this_reg])); \ + DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg])); \ + DEBUG_PRINT2 (" matched_something=%d", \ + MATCHED_SOMETHING (reg_info[this_reg])); \ + DEBUG_PRINT2 (" ever_matched=%d", \ + EVER_MATCHED_SOMETHING (reg_info[this_reg])); \ + DEBUG_PRINT1 ("\n"); \ + PUSH_FAILURE_ELT (reg_info[this_reg].word); \ + } \ + \ + DEBUG_PRINT2 (" Pushing low active reg: %ld\n", lowest_active_reg);\ + PUSH_FAILURE_INT (lowest_active_reg); \ + \ + DEBUG_PRINT2 (" Pushing high active reg: %ld\n", highest_active_reg);\ + PUSH_FAILURE_INT (highest_active_reg); \ + \ + DEBUG_PRINT2 (" Pushing pattern %p:\n", pattern_place); \ + DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \ + PUSH_FAILURE_POINTER (pattern_place); \ + \ + DEBUG_PRINT2 (" Pushing string %p: `", string_place); \ + DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, \ + size2); \ + DEBUG_PRINT1 ("'\n"); \ + PUSH_FAILURE_POINTER (string_place); \ + \ + DEBUG_PRINT2 (" Pushing failure id: %u\n", failure_id); \ + DEBUG_PUSH (failure_id); \ + } while (0) + +/* This is the number of items that are pushed and popped on the stack + for each register. */ +#define NUM_REG_ITEMS 3 + +/* Individual items aside from the registers. */ +#ifdef DEBUG +# define NUM_NONREG_ITEMS 5 /* Includes failure point id. */ +#else +# define NUM_NONREG_ITEMS 4 +#endif + +/* We push at most this many items on the stack. */ +/* We used to use (num_regs - 1), which is the number of registers + this regexp will save; but that was changed to 5 + to avoid stack overflow for a regexp with lots of parens. */ +#define MAX_FAILURE_ITEMS (5 * NUM_REG_ITEMS + NUM_NONREG_ITEMS) + +/* We actually push this many items. */ +#define NUM_FAILURE_ITEMS \ + (((0 \ + ? 0 : highest_active_reg - lowest_active_reg + 1) \ + * NUM_REG_ITEMS) \ + + NUM_NONREG_ITEMS) + +/* How many items can still be added to the stack without overflowing it. */ +#define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail) + + +/* Pops what PUSH_FAIL_STACK pushes. + + We restore into the parameters, all of which should be lvalues: + STR -- the saved data position. + PAT -- the saved pattern position. + LOW_REG, HIGH_REG -- the highest and lowest active registers. + REGSTART, REGEND -- arrays of string positions. + REG_INFO -- array of information about each subexpression. + + Also assumes the variables `fail_stack' and (if debugging), `bufp', + `pend', `string1', `size1', `string2', and `size2'. */ + +#define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\ +{ \ + DEBUG_STATEMENT (unsigned failure_id;) \ + active_reg_t this_reg; \ + const unsigned char *string_temp; \ + \ + assert (!FAIL_STACK_EMPTY ()); \ + \ + /* Remove failure points and point to how many regs pushed. */ \ + DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \ + DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \ + DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \ + \ + assert (fail_stack.avail >= NUM_NONREG_ITEMS); \ + \ + DEBUG_POP (&failure_id); \ + DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \ + \ + /* If the saved string location is NULL, it came from an \ + on_failure_keep_string_jump opcode, and we want to throw away the \ + saved NULL, thus retaining our current position in the string. */ \ + string_temp = POP_FAILURE_POINTER (); \ + if (string_temp != NULL) \ + str = (const char *) string_temp; \ + \ + DEBUG_PRINT2 (" Popping string %p: `", str); \ + DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \ + DEBUG_PRINT1 ("'\n"); \ + \ + pat = (unsigned char *) POP_FAILURE_POINTER (); \ + DEBUG_PRINT2 (" Popping pattern %p:\n", pat); \ + DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \ + \ + /* Restore register info. */ \ + high_reg = (active_reg_t) POP_FAILURE_INT (); \ + DEBUG_PRINT2 (" Popping high active reg: %ld\n", high_reg); \ + \ + low_reg = (active_reg_t) POP_FAILURE_INT (); \ + DEBUG_PRINT2 (" Popping low active reg: %ld\n", low_reg); \ + \ + if (1) \ + for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \ + { \ + DEBUG_PRINT2 (" Popping reg: %ld\n", this_reg); \ + \ + reg_info[this_reg].word = POP_FAILURE_ELT (); \ + DEBUG_PRINT2 (" info: %p\n", \ + reg_info[this_reg].word.pointer); \ + \ + regend[this_reg] = (const char *) POP_FAILURE_POINTER (); \ + DEBUG_PRINT2 (" end: %p\n", regend[this_reg]); \ + \ + regstart[this_reg] = (const char *) POP_FAILURE_POINTER (); \ + DEBUG_PRINT2 (" start: %p\n", regstart[this_reg]); \ + } \ + else \ + { \ + for (this_reg = highest_active_reg; this_reg > high_reg; this_reg--) \ + { \ + reg_info[this_reg].word.integer = 0; \ + regend[this_reg] = 0; \ + regstart[this_reg] = 0; \ + } \ + highest_active_reg = high_reg; \ + } \ + \ + set_regs_matched_done = 0; \ + DEBUG_STATEMENT (nfailure_points_popped++); \ +} /* POP_FAILURE_POINT */ + + + +/* Structure for per-register (a.k.a. per-group) information. + Other register information, such as the + starting and ending positions (which are addresses), and the list of + inner groups (which is a bits list) are maintained in separate + variables. + + We are making a (strictly speaking) nonportable assumption here: that + the compiler will pack our bit fields into something that fits into + the type of `word', i.e., is something that fits into one item on the + failure stack. */ + + +/* Declarations and macros for re_match_2. */ + +typedef union +{ + fail_stack_elt_t word; + struct + { + /* This field is one if this group can match the empty string, + zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */ +#define MATCH_NULL_UNSET_VALUE 3 + unsigned match_null_string_p : 2; + unsigned is_active : 1; + unsigned matched_something : 1; + unsigned ever_matched_something : 1; + } bits; +} register_info_type; + +#define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p) +#define IS_ACTIVE(R) ((R).bits.is_active) +#define MATCHED_SOMETHING(R) ((R).bits.matched_something) +#define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something) + + +/* Call this when have matched a real character; it sets `matched' flags + for the subexpressions which we are currently inside. Also records + that those subexprs have matched. */ +#define SET_REGS_MATCHED() \ + do \ + { \ + if (!set_regs_matched_done) \ + { \ + active_reg_t r; \ + set_regs_matched_done = 1; \ + for (r = lowest_active_reg; r <= highest_active_reg; r++) \ + { \ + MATCHED_SOMETHING (reg_info[r]) \ + = EVER_MATCHED_SOMETHING (reg_info[r]) \ + = 1; \ + } \ + } \ + } \ + while (0) + +/* Registers are set to a sentinel when they haven't yet matched. */ +static char reg_unset_dummy; +#define REG_UNSET_VALUE (®_unset_dummy) +#define REG_UNSET(e) ((e) == REG_UNSET_VALUE) + +/* Subroutine declarations and macros for regex_compile. */ + +static reg_errcode_t regex_compile _RE_ARGS ((const char *pattern, size_t size, + reg_syntax_t syntax, + struct re_pattern_buffer *bufp)); +static void store_op1 _RE_ARGS ((re_opcode_t op, unsigned char *loc, int arg)); +static void store_op2 _RE_ARGS ((re_opcode_t op, unsigned char *loc, + int arg1, int arg2)); +static void insert_op1 _RE_ARGS ((re_opcode_t op, unsigned char *loc, + int arg, unsigned char *end)); +static void insert_op2 _RE_ARGS ((re_opcode_t op, unsigned char *loc, + int arg1, int arg2, unsigned char *end)); +static boolean at_begline_loc_p _RE_ARGS ((const char *pattern, const char *p, + reg_syntax_t syntax)); +static boolean at_endline_loc_p _RE_ARGS ((const char *p, const char *pend, + reg_syntax_t syntax)); +static reg_errcode_t compile_range _RE_ARGS ((const char **p_ptr, + const char *pend, + char *translate, + reg_syntax_t syntax, + unsigned char *b)); + +/* Fetch the next character in the uncompiled pattern---translating it + if necessary. Also cast from a signed character in the constant + string passed to us by the user to an unsigned char that we can use + as an array index (in, e.g., `translate'). */ +#ifndef PATFETCH +# define PATFETCH(c) \ + do {if (p == pend) return REG_EEND; \ + c = (unsigned char) *p++; \ + if (translate) c = (unsigned char) translate[c]; \ + } while (0) +#endif + +/* Fetch the next character in the uncompiled pattern, with no + translation. */ +#define PATFETCH_RAW(c) \ + do {if (p == pend) return REG_EEND; \ + c = (unsigned char) *p++; \ + } while (0) + +/* Go backwards one character in the pattern. */ +#define PATUNFETCH p-- + + +/* If `translate' is non-null, return translate[D], else just D. We + cast the subscript to translate because some data is declared as + `char *', to avoid warnings when a string constant is passed. But + when we use a character as a subscript we must make it unsigned. */ +#ifndef TRANSLATE +# define TRANSLATE(d) \ + (translate ? (char) translate[(unsigned char) (d)] : (d)) +#endif + + +/* Macros for outputting the compiled pattern into `buffer'. */ + +/* If the buffer isn't allocated when it comes in, use this. */ +#define INIT_BUF_SIZE 32 + +/* Make sure we have at least N more bytes of space in buffer. */ +#define GET_BUFFER_SPACE(n) \ + while ((unsigned long) (b - bufp->buffer + (n)) > bufp->allocated) \ + EXTEND_BUFFER () + +/* Make sure we have one more byte of buffer space and then add C to it. */ +#define BUF_PUSH(c) \ + do { \ + GET_BUFFER_SPACE (1); \ + *b++ = (unsigned char) (c); \ + } while (0) + + +/* Ensure we have two more bytes of buffer space and then append C1 and C2. */ +#define BUF_PUSH_2(c1, c2) \ + do { \ + GET_BUFFER_SPACE (2); \ + *b++ = (unsigned char) (c1); \ + *b++ = (unsigned char) (c2); \ + } while (0) + + +/* As with BUF_PUSH_2, except for three bytes. */ +#define BUF_PUSH_3(c1, c2, c3) \ + do { \ + GET_BUFFER_SPACE (3); \ + *b++ = (unsigned char) (c1); \ + *b++ = (unsigned char) (c2); \ + *b++ = (unsigned char) (c3); \ + } while (0) + + +/* Store a jump with opcode OP at LOC to location TO. We store a + relative address offset by the three bytes the jump itself occupies. */ +#define STORE_JUMP(op, loc, to) \ + store_op1 (op, loc, (int) ((to) - (loc) - 3)) + +/* Likewise, for a two-argument jump. */ +#define STORE_JUMP2(op, loc, to, arg) \ + store_op2 (op, loc, (int) ((to) - (loc) - 3), arg) + +/* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */ +#define INSERT_JUMP(op, loc, to) \ + insert_op1 (op, loc, (int) ((to) - (loc) - 3), b) + +/* Like `STORE_JUMP2', but for inserting. Assume `b' is the buffer end. */ +#define INSERT_JUMP2(op, loc, to, arg) \ + insert_op2 (op, loc, (int) ((to) - (loc) - 3), arg, b) + + +/* This is not an arbitrary limit: the arguments which represent offsets + into the pattern are two bytes long. So if 2^16 bytes turns out to + be too small, many things would have to change. */ +/* Any other compiler which, like MSC, has allocation limit below 2^16 + bytes will have to use approach similar to what was done below for + MSC and drop MAX_BUF_SIZE a bit. Otherwise you may end up + reallocating to 0 bytes. Such thing is not going to work too well. + You have been warned!! */ +#if defined _MSC_VER && !defined WIN32 +/* Microsoft C 16-bit versions limit malloc to approx 65512 bytes. + The REALLOC define eliminates a flurry of conversion warnings, + but is not required. */ +# define MAX_BUF_SIZE 65500L +# define REALLOC(p,s) realloc ((p), (size_t) (s)) +#else +# define MAX_BUF_SIZE (1L << 16) +# define REALLOC(p,s) realloc ((p), (s)) +#endif + +/* Extend the buffer by twice its current size via realloc and + reset the pointers that pointed into the old block to point to the + correct places in the new one. If extending the buffer results in it + being larger than MAX_BUF_SIZE, then flag memory exhausted. */ +#define EXTEND_BUFFER() \ + do { \ + unsigned char *old_buffer = bufp->buffer; \ + if (bufp->allocated == MAX_BUF_SIZE) \ + return REG_ESIZE; \ + bufp->allocated <<= 1; \ + if (bufp->allocated > MAX_BUF_SIZE) \ + bufp->allocated = MAX_BUF_SIZE; \ + bufp->buffer = (unsigned char *) REALLOC (bufp->buffer, bufp->allocated);\ + if (bufp->buffer == NULL) \ + return REG_ESPACE; \ + /* If the buffer moved, move all the pointers into it. */ \ + if (old_buffer != bufp->buffer) \ + { \ + b = (b - old_buffer) + bufp->buffer; \ + begalt = (begalt - old_buffer) + bufp->buffer; \ + if (fixup_alt_jump) \ + fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;\ + if (laststart) \ + laststart = (laststart - old_buffer) + bufp->buffer; \ + if (pending_exact) \ + pending_exact = (pending_exact - old_buffer) + bufp->buffer; \ + } \ + } while (0) + + +/* Since we have one byte reserved for the register number argument to + {start,stop}_memory, the maximum number of groups we can report + things about is what fits in that byte. */ +#define MAX_REGNUM 255 + +/* But patterns can have more than `MAX_REGNUM' registers. We just + ignore the excess. */ +typedef unsigned regnum_t; + + +/* Macros for the compile stack. */ + +/* Since offsets can go either forwards or backwards, this type needs to + be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1. */ +/* int may be not enough when sizeof(int) == 2. */ +typedef long pattern_offset_t; + +typedef struct +{ + pattern_offset_t begalt_offset; + pattern_offset_t fixup_alt_jump; + pattern_offset_t inner_group_offset; + pattern_offset_t laststart_offset; + regnum_t regnum; +} compile_stack_elt_t; + + +typedef struct +{ + compile_stack_elt_t *stack; + unsigned size; + unsigned avail; /* Offset of next open position. */ +} compile_stack_type; + + +#define INIT_COMPILE_STACK_SIZE 32 + +#define COMPILE_STACK_EMPTY (compile_stack.avail == 0) +#define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size) + +/* The next available element. */ +#define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail]) + + +/* Set the bit for character C in a list. */ +#define SET_LIST_BIT(c) \ + (b[((unsigned char) (c)) / BYTEWIDTH] \ + |= 1 << (((unsigned char) c) % BYTEWIDTH)) + + +/* Get the next unsigned number in the uncompiled pattern. */ +#define GET_UNSIGNED_NUMBER(num) \ + { if (p != pend) \ + { \ + PATFETCH (c); \ + while (ISDIGIT (c)) \ + { \ + if (num < 0) \ + num = 0; \ + num = num * 10 + c - '0'; \ + if (p == pend) \ + break; \ + PATFETCH (c); \ + } \ + } \ + } + +#if defined _LIBC || WIDE_CHAR_SUPPORT +/* The GNU C library provides support for user-defined character classes + and the functions from ISO C amendement 1. */ +# ifdef CHARCLASS_NAME_MAX +# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX +# else +/* This shouldn't happen but some implementation might still have this + problem. Use a reasonable default value. */ +# define CHAR_CLASS_MAX_LENGTH 256 +# endif + +# ifdef _LIBC +# define IS_CHAR_CLASS(string) __wctype (string) +# else +# define IS_CHAR_CLASS(string) wctype (string) +# endif +#else +# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */ + +# define IS_CHAR_CLASS(string) \ + (STREQ (string, "alpha") || STREQ (string, "upper") \ + || STREQ (string, "lower") || STREQ (string, "digit") \ + || STREQ (string, "alnum") || STREQ (string, "xdigit") \ + || STREQ (string, "space") || STREQ (string, "print") \ + || STREQ (string, "punct") || STREQ (string, "graph") \ + || STREQ (string, "cntrl") || STREQ (string, "blank")) +#endif + +#ifndef MATCH_MAY_ALLOCATE + +/* If we cannot allocate large objects within re_match_2_internal, + we make the fail stack and register vectors global. + The fail stack, we grow to the maximum size when a regexp + is compiled. + The register vectors, we adjust in size each time we + compile a regexp, according to the number of registers it needs. */ + +static fail_stack_type fail_stack; + +/* Size with which the following vectors are currently allocated. + That is so we can make them bigger as needed, + but never make them smaller. */ +static int regs_allocated_size; + +static const char ** regstart, ** regend; +static const char ** old_regstart, ** old_regend; +static const char **best_regstart, **best_regend; +static register_info_type *reg_info; +static const char **reg_dummy; +static register_info_type *reg_info_dummy; + +/* Make the register vectors big enough for NUM_REGS registers, + but don't make them smaller. */ + +static +regex_grow_registers (num_regs) + int num_regs; +{ + if (num_regs > regs_allocated_size) + { + RETALLOC_IF (regstart, num_regs, const char *); + RETALLOC_IF (regend, num_regs, const char *); + RETALLOC_IF (old_regstart, num_regs, const char *); + RETALLOC_IF (old_regend, num_regs, const char *); + RETALLOC_IF (best_regstart, num_regs, const char *); + RETALLOC_IF (best_regend, num_regs, const char *); + RETALLOC_IF (reg_info, num_regs, register_info_type); + RETALLOC_IF (reg_dummy, num_regs, const char *); + RETALLOC_IF (reg_info_dummy, num_regs, register_info_type); + + regs_allocated_size = num_regs; + } +} + +#endif /* not MATCH_MAY_ALLOCATE */ + +static boolean group_in_compile_stack _RE_ARGS ((compile_stack_type + compile_stack, + regnum_t regnum)); + +/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX. + Returns one of error codes defined in `regex.h', or zero for success. + + Assumes the `allocated' (and perhaps `buffer') and `translate' + fields are set in BUFP on entry. + + If it succeeds, results are put in BUFP (if it returns an error, the + contents of BUFP are undefined): + `buffer' is the compiled pattern; + `syntax' is set to SYNTAX; + `used' is set to the length of the compiled pattern; + `fastmap_accurate' is zero; + `re_nsub' is the number of subexpressions in PATTERN; + `not_bol' and `not_eol' are zero; + + The `fastmap' and `newline_anchor' fields are neither + examined nor set. */ + +/* Return, freeing storage we allocated. */ +#define FREE_STACK_RETURN(value) \ + return (free (compile_stack.stack), value) + +static reg_errcode_t +regex_compile (pattern, size, syntax, bufp) + const char *pattern; + size_t size; + reg_syntax_t syntax; + struct re_pattern_buffer *bufp; +{ + /* We fetch characters from PATTERN here. Even though PATTERN is + `char *' (i.e., signed), we declare these variables as unsigned, so + they can be reliably used as array indices. */ + register unsigned char c, c1; + + /* A random temporary spot in PATTERN. */ + const char *p1; + + /* Points to the end of the buffer, where we should append. */ + register unsigned char *b; + + /* Keeps track of unclosed groups. */ + compile_stack_type compile_stack; + + /* Points to the current (ending) position in the pattern. */ + const char *p = pattern; + const char *pend = pattern + size; + + /* How to translate the characters in the pattern. */ + RE_TRANSLATE_TYPE translate = bufp->translate; + + /* Address of the count-byte of the most recently inserted `exactn' + command. This makes it possible to tell if a new exact-match + character can be added to that command or if the character requires + a new `exactn' command. */ + unsigned char *pending_exact = 0; + + /* Address of start of the most recently finished expression. + This tells, e.g., postfix * where to find the start of its + operand. Reset at the beginning of groups and alternatives. */ + unsigned char *laststart = 0; + + /* Address of beginning of regexp, or inside of last group. */ + unsigned char *begalt; + + /* Place in the uncompiled pattern (i.e., the {) to + which to go back if the interval is invalid. */ + const char *beg_interval; + + /* Address of the place where a forward jump should go to the end of + the containing expression. Each alternative of an `or' -- except the + last -- ends with a forward jump of this sort. */ + unsigned char *fixup_alt_jump = 0; + + /* Counts open-groups as they are encountered. Remembered for the + matching close-group on the compile stack, so the same register + number is put in the stop_memory as the start_memory. */ + regnum_t regnum = 0; + +#ifdef DEBUG + DEBUG_PRINT1 ("\nCompiling pattern: "); + if (debug) + { + unsigned debug_count; + + for (debug_count = 0; debug_count < size; debug_count++) + putchar (pattern[debug_count]); + putchar ('\n'); + } +#endif /* DEBUG */ + + /* Initialize the compile stack. */ + compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t); + if (compile_stack.stack == NULL) + return REG_ESPACE; + + compile_stack.size = INIT_COMPILE_STACK_SIZE; + compile_stack.avail = 0; + + /* Initialize the pattern buffer. */ + bufp->syntax = syntax; + bufp->fastmap_accurate = 0; + bufp->not_bol = bufp->not_eol = 0; + + /* Set `used' to zero, so that if we return an error, the pattern + printer (for debugging) will think there's no pattern. We reset it + at the end. */ + bufp->used = 0; + + /* Always count groups, whether or not bufp->no_sub is set. */ + bufp->re_nsub = 0; + +#if !defined emacs && !defined SYNTAX_TABLE + /* Initialize the syntax table. */ + init_syntax_once (); +#endif + + if (bufp->allocated == 0) + { + if (bufp->buffer) + { /* If zero allocated, but buffer is non-null, try to realloc + enough space. This loses if buffer's address is bogus, but + that is the user's responsibility. */ + RETALLOC (bufp->buffer, INIT_BUF_SIZE, unsigned char); + } + else + { /* Caller did not allocate a buffer. Do it for them. */ + bufp->buffer = TALLOC (INIT_BUF_SIZE, unsigned char); + } + if (!bufp->buffer) FREE_STACK_RETURN (REG_ESPACE); + + bufp->allocated = INIT_BUF_SIZE; + } + + begalt = b = bufp->buffer; + + /* Loop through the uncompiled pattern until we're at the end. */ + while (p != pend) + { + PATFETCH (c); + + switch (c) + { + case '^': + { + if ( /* If at start of pattern, it's an operator. */ + p == pattern + 1 + /* If context independent, it's an operator. */ + || syntax & RE_CONTEXT_INDEP_ANCHORS + /* Otherwise, depends on what's come before. */ + || at_begline_loc_p (pattern, p, syntax)) + BUF_PUSH (begline); + else + goto normal_char; + } + break; + + + case '$': + { + if ( /* If at end of pattern, it's an operator. */ + p == pend + /* If context independent, it's an operator. */ + || syntax & RE_CONTEXT_INDEP_ANCHORS + /* Otherwise, depends on what's next. */ + || at_endline_loc_p (p, pend, syntax)) + BUF_PUSH (endline); + else + goto normal_char; + } + break; + + + case '+': + case '?': + if ((syntax & RE_BK_PLUS_QM) + || (syntax & RE_LIMITED_OPS)) + goto normal_char; + handle_plus: + case '*': + /* If there is no previous pattern... */ + if (!laststart) + { + if (syntax & RE_CONTEXT_INVALID_OPS) + FREE_STACK_RETURN (REG_BADRPT); + else if (!(syntax & RE_CONTEXT_INDEP_OPS)) + goto normal_char; + } + + { + /* Are we optimizing this jump? */ + boolean keep_string_p = false; + + /* 1 means zero (many) matches is allowed. */ + char zero_times_ok = 0, many_times_ok = 0; + + /* If there is a sequence of repetition chars, collapse it + down to just one (the right one). We can't combine + interval operators with these because of, e.g., `a{2}*', + which should only match an even number of `a's. */ + + for (;;) + { + zero_times_ok |= c != '+'; + many_times_ok |= c != '?'; + + if (p == pend) + break; + + PATFETCH (c); + + if (c == '*' + || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?'))) + ; + + else if (syntax & RE_BK_PLUS_QM && c == '\\') + { + if (p == pend) FREE_STACK_RETURN (REG_EESCAPE); + + PATFETCH (c1); + if (!(c1 == '+' || c1 == '?')) + { + PATUNFETCH; + PATUNFETCH; + break; + } + + c = c1; + } + else + { + PATUNFETCH; + break; + } + + /* If we get here, we found another repeat character. */ + } + + /* Star, etc. applied to an empty pattern is equivalent + to an empty pattern. */ + if (!laststart) + break; + + /* Now we know whether or not zero matches is allowed + and also whether or not two or more matches is allowed. */ + if (many_times_ok) + { /* More than one repetition is allowed, so put in at the + end a backward relative jump from `b' to before the next + jump we're going to put in below (which jumps from + laststart to after this jump). + + But if we are at the `*' in the exact sequence `.*\n', + insert an unconditional jump backwards to the ., + instead of the beginning of the loop. This way we only + push a failure point once, instead of every time + through the loop. */ + assert (p - 1 > pattern); + + /* Allocate the space for the jump. */ + GET_BUFFER_SPACE (3); + + /* We know we are not at the first character of the pattern, + because laststart was nonzero. And we've already + incremented `p', by the way, to be the character after + the `*'. Do we have to do something analogous here + for null bytes, because of RE_DOT_NOT_NULL? */ + if (TRANSLATE (*(p - 2)) == TRANSLATE ('.') + && zero_times_ok + && p < pend && TRANSLATE (*p) == TRANSLATE ('\n') + && !(syntax & RE_DOT_NEWLINE)) + { /* We have .*\n. */ + STORE_JUMP (jump, b, laststart); + keep_string_p = true; + } + else + /* Anything else. */ + STORE_JUMP (maybe_pop_jump, b, laststart - 3); + + /* We've added more stuff to the buffer. */ + b += 3; + } + + /* On failure, jump from laststart to b + 3, which will be the + end of the buffer after this jump is inserted. */ + GET_BUFFER_SPACE (3); + INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump + : on_failure_jump, + laststart, b + 3); + pending_exact = 0; + b += 3; + + if (!zero_times_ok) + { + /* At least one repetition is required, so insert a + `dummy_failure_jump' before the initial + `on_failure_jump' instruction of the loop. This + effects a skip over that instruction the first time + we hit that loop. */ + GET_BUFFER_SPACE (3); + INSERT_JUMP (dummy_failure_jump, laststart, laststart + 6); + b += 3; + } + } + break; + + + case '.': + laststart = b; + BUF_PUSH (anychar); + break; + + + case '[': + { + boolean had_char_class = false; + + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); + + /* Ensure that we have enough space to push a charset: the + opcode, the length count, and the bitset; 34 bytes in all. */ + GET_BUFFER_SPACE (34); + + laststart = b; + + /* We test `*p == '^' twice, instead of using an if + statement, so we only need one BUF_PUSH. */ + BUF_PUSH (*p == '^' ? charset_not : charset); + if (*p == '^') + p++; + + /* Remember the first position in the bracket expression. */ + p1 = p; + + /* Push the number of bytes in the bitmap. */ + BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH); + + /* Clear the whole map. */ + bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH); + + /* charset_not matches newline according to a syntax bit. */ + if ((re_opcode_t) b[-2] == charset_not + && (syntax & RE_HAT_LISTS_NOT_NEWLINE)) + SET_LIST_BIT ('\n'); + + /* Read in characters and ranges, setting map bits. */ + for (;;) + { + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); + + PATFETCH (c); + + /* \ might escape characters inside [...] and [^...]. */ + if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\') + { + if (p == pend) FREE_STACK_RETURN (REG_EESCAPE); + + PATFETCH (c1); + SET_LIST_BIT (c1); + continue; + } + + /* Could be the end of the bracket expression. If it's + not (i.e., when the bracket expression is `[]' so + far), the ']' character bit gets set way below. */ + if (c == ']' && p != p1 + 1) + break; + + /* Look ahead to see if it's a range when the last thing + was a character class. */ + if (had_char_class && c == '-' && *p != ']') + FREE_STACK_RETURN (REG_ERANGE); + + /* Look ahead to see if it's a range when the last thing + was a character: if this is a hyphen not at the + beginning or the end of a list, then it's the range + operator. */ + if (c == '-' + && !(p - 2 >= pattern && p[-2] == '[') + && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^') + && *p != ']') + { + reg_errcode_t ret + = compile_range (&p, pend, translate, syntax, b); + if (ret != REG_NOERROR) FREE_STACK_RETURN (ret); + } + + else if (p[0] == '-' && p[1] != ']') + { /* This handles ranges made up of characters only. */ + reg_errcode_t ret; + + /* Move past the `-'. */ + PATFETCH (c1); + + ret = compile_range (&p, pend, translate, syntax, b); + if (ret != REG_NOERROR) FREE_STACK_RETURN (ret); + } + + /* See if we're at the beginning of a possible character + class. */ + + else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':') + { /* Leave room for the null. */ + char str[CHAR_CLASS_MAX_LENGTH + 1]; + + PATFETCH (c); + c1 = 0; + + /* If pattern is `[[:'. */ + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); + + for (;;) + { + PATFETCH (c); + if ((c == ':' && *p == ']') || p == pend + || c1 == CHAR_CLASS_MAX_LENGTH) + break; + str[c1++] = c; + } + str[c1] = '\0'; + + /* If isn't a word bracketed by `[:' and `:]': + undo the ending character, the letters, and leave + the leading `:' and `[' (but set bits for them). */ + if (c == ':' && *p == ']') + { +#if defined _LIBC || WIDE_CHAR_SUPPORT + boolean is_lower = STREQ (str, "lower"); + boolean is_upper = STREQ (str, "upper"); + wctype_t wt; + int ch; + + wt = IS_CHAR_CLASS (str); + if (wt == 0) + FREE_STACK_RETURN (REG_ECTYPE); + + /* Throw away the ] at the end of the character + class. */ + PATFETCH (c); + + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); + + for (ch = 0; ch < 1 << BYTEWIDTH; ++ch) + { +# ifdef _LIBC + if (__iswctype (__btowc (ch), wt)) + SET_LIST_BIT (ch); +# else + if (iswctype (btowc (ch), wt)) + SET_LIST_BIT (ch); +# endif + + if (translate && (is_upper || is_lower) + && (ISUPPER (ch) || ISLOWER (ch))) + SET_LIST_BIT (ch); + } + + had_char_class = true; +#else + int ch; + boolean is_alnum = STREQ (str, "alnum"); + boolean is_alpha = STREQ (str, "alpha"); + boolean is_blank = STREQ (str, "blank"); + boolean is_cntrl = STREQ (str, "cntrl"); + boolean is_digit = STREQ (str, "digit"); + boolean is_graph = STREQ (str, "graph"); + boolean is_lower = STREQ (str, "lower"); + boolean is_print = STREQ (str, "print"); + boolean is_punct = STREQ (str, "punct"); + boolean is_space = STREQ (str, "space"); + boolean is_upper = STREQ (str, "upper"); + boolean is_xdigit = STREQ (str, "xdigit"); + + if (!IS_CHAR_CLASS (str)) + FREE_STACK_RETURN (REG_ECTYPE); + + /* Throw away the ] at the end of the character + class. */ + PATFETCH (c); + + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); + + for (ch = 0; ch < 1 << BYTEWIDTH; ch++) + { + /* This was split into 3 if's to + avoid an arbitrary limit in some compiler. */ + if ( (is_alnum && ISALNUM (ch)) + || (is_alpha && ISALPHA (ch)) + || (is_blank && ISBLANK (ch)) + || (is_cntrl && ISCNTRL (ch))) + SET_LIST_BIT (ch); + if ( (is_digit && ISDIGIT (ch)) + || (is_graph && ISGRAPH (ch)) + || (is_lower && ISLOWER (ch)) + || (is_print && ISPRINT (ch))) + SET_LIST_BIT (ch); + if ( (is_punct && ISPUNCT (ch)) + || (is_space && ISSPACE (ch)) + || (is_upper && ISUPPER (ch)) + || (is_xdigit && ISXDIGIT (ch))) + SET_LIST_BIT (ch); + if ( translate && (is_upper || is_lower) + && (ISUPPER (ch) || ISLOWER (ch))) + SET_LIST_BIT (ch); + } + had_char_class = true; +#endif /* libc || wctype.h */ + } + else + { + c1++; + while (c1--) + PATUNFETCH; + SET_LIST_BIT ('['); + SET_LIST_BIT (':'); + had_char_class = false; + } + } + else + { + had_char_class = false; + SET_LIST_BIT (c); + } + } + + /* Discard any (non)matching list bytes that are all 0 at the + end of the map. Decrease the map-length byte too. */ + while ((int) b[-1] > 0 && b[b[-1] - 1] == 0) + b[-1]--; + b += b[-1]; + } + break; + + + case '(': + if (syntax & RE_NO_BK_PARENS) + goto handle_open; + else + goto normal_char; + + + case ')': + if (syntax & RE_NO_BK_PARENS) + goto handle_close; + else + goto normal_char; + + + case '\n': + if (syntax & RE_NEWLINE_ALT) + goto handle_alt; + else + goto normal_char; + + + case '|': + if (syntax & RE_NO_BK_VBAR) + goto handle_alt; + else + goto normal_char; + + + case '{': + if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES) + goto handle_interval; + else + goto normal_char; + + + case '\\': + if (p == pend) FREE_STACK_RETURN (REG_EESCAPE); + + /* Do not translate the character after the \, so that we can + distinguish, e.g., \B from \b, even if we normally would + translate, e.g., B to b. */ + PATFETCH_RAW (c); + + switch (c) + { + case '(': + if (syntax & RE_NO_BK_PARENS) + goto normal_backslash; + + handle_open: + bufp->re_nsub++; + regnum++; + + if (COMPILE_STACK_FULL) + { + RETALLOC (compile_stack.stack, compile_stack.size << 1, + compile_stack_elt_t); + if (compile_stack.stack == NULL) return REG_ESPACE; + + compile_stack.size <<= 1; + } + + /* These are the values to restore when we hit end of this + group. They are all relative offsets, so that if the + whole pattern moves because of realloc, they will still + be valid. */ + COMPILE_STACK_TOP.begalt_offset = begalt - bufp->buffer; + COMPILE_STACK_TOP.fixup_alt_jump + = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0; + COMPILE_STACK_TOP.laststart_offset = b - bufp->buffer; + COMPILE_STACK_TOP.regnum = regnum; + + /* We will eventually replace the 0 with the number of + groups inner to this one. But do not push a + start_memory for groups beyond the last one we can + represent in the compiled pattern. */ + if (regnum <= MAX_REGNUM) + { + COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2; + BUF_PUSH_3 (start_memory, regnum, 0); + } + + compile_stack.avail++; + + fixup_alt_jump = 0; + laststart = 0; + begalt = b; + /* If we've reached MAX_REGNUM groups, then this open + won't actually generate any code, so we'll have to + clear pending_exact explicitly. */ + pending_exact = 0; + break; + + + case ')': + if (syntax & RE_NO_BK_PARENS) goto normal_backslash; + + if (COMPILE_STACK_EMPTY) + { + if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD) + goto normal_backslash; + else + FREE_STACK_RETURN (REG_ERPAREN); + } + + handle_close: + if (fixup_alt_jump) + { /* Push a dummy failure point at the end of the + alternative for a possible future + `pop_failure_jump' to pop. See comments at + `push_dummy_failure' in `re_match_2'. */ + BUF_PUSH (push_dummy_failure); + + /* We allocated space for this jump when we assigned + to `fixup_alt_jump', in the `handle_alt' case below. */ + STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1); + } + + /* See similar code for backslashed left paren above. */ + if (COMPILE_STACK_EMPTY) + { + if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD) + goto normal_char; + else + FREE_STACK_RETURN (REG_ERPAREN); + } + + /* Since we just checked for an empty stack above, this + ``can't happen''. */ + assert (compile_stack.avail != 0); + { + /* We don't just want to restore into `regnum', because + later groups should continue to be numbered higher, + as in `(ab)c(de)' -- the second group is #2. */ + regnum_t this_group_regnum; + + compile_stack.avail--; + begalt = bufp->buffer + COMPILE_STACK_TOP.begalt_offset; + fixup_alt_jump + = COMPILE_STACK_TOP.fixup_alt_jump + ? bufp->buffer + COMPILE_STACK_TOP.fixup_alt_jump - 1 + : 0; + laststart = bufp->buffer + COMPILE_STACK_TOP.laststart_offset; + this_group_regnum = COMPILE_STACK_TOP.regnum; + /* If we've reached MAX_REGNUM groups, then this open + won't actually generate any code, so we'll have to + clear pending_exact explicitly. */ + pending_exact = 0; + + /* We're at the end of the group, so now we know how many + groups were inside this one. */ + if (this_group_regnum <= MAX_REGNUM) + { + unsigned char *inner_group_loc + = bufp->buffer + COMPILE_STACK_TOP.inner_group_offset; + + *inner_group_loc = regnum - this_group_regnum; + BUF_PUSH_3 (stop_memory, this_group_regnum, + regnum - this_group_regnum); + } + } + break; + + + case '|': /* `\|'. */ + if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR) + goto normal_backslash; + handle_alt: + if (syntax & RE_LIMITED_OPS) + goto normal_char; + + /* Insert before the previous alternative a jump which + jumps to this alternative if the former fails. */ + GET_BUFFER_SPACE (3); + INSERT_JUMP (on_failure_jump, begalt, b + 6); + pending_exact = 0; + b += 3; + + /* The alternative before this one has a jump after it + which gets executed if it gets matched. Adjust that + jump so it will jump to this alternative's analogous + jump (put in below, which in turn will jump to the next + (if any) alternative's such jump, etc.). The last such + jump jumps to the correct final destination. A picture: + _____ _____ + | | | | + | v | v + a | b | c + + If we are at `b', then fixup_alt_jump right now points to a + three-byte space after `a'. We'll put in the jump, set + fixup_alt_jump to right after `b', and leave behind three + bytes which we'll fill in when we get to after `c'. */ + + if (fixup_alt_jump) + STORE_JUMP (jump_past_alt, fixup_alt_jump, b); + + /* Mark and leave space for a jump after this alternative, + to be filled in later either by next alternative or + when know we're at the end of a series of alternatives. */ + fixup_alt_jump = b; + GET_BUFFER_SPACE (3); + b += 3; + + laststart = 0; + begalt = b; + break; + + + case '{': + /* If \{ is a literal. */ + if (!(syntax & RE_INTERVALS) + /* If we're at `\{' and it's not the open-interval + operator. */ + || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES)) + || (p - 2 == pattern && p == pend)) + goto normal_backslash; + + handle_interval: + { + /* If got here, then the syntax allows intervals. */ + + /* At least (most) this many matches must be made. */ + int lower_bound = -1, upper_bound = -1; + + beg_interval = p - 1; + + if (p == pend) + { + if (syntax & RE_NO_BK_BRACES) + goto unfetch_interval; + else + FREE_STACK_RETURN (REG_EBRACE); + } + + GET_UNSIGNED_NUMBER (lower_bound); + + if (c == ',') + { + GET_UNSIGNED_NUMBER (upper_bound); + if (upper_bound < 0) upper_bound = RE_DUP_MAX; + } + else + /* Interval such as `{1}' => match exactly once. */ + upper_bound = lower_bound; + + if (lower_bound < 0 || upper_bound > RE_DUP_MAX + || lower_bound > upper_bound) + { + if (syntax & RE_NO_BK_BRACES) + goto unfetch_interval; + else + FREE_STACK_RETURN (REG_BADBR); + } + + if (!(syntax & RE_NO_BK_BRACES)) + { + if (c != '\\') FREE_STACK_RETURN (REG_EBRACE); + + PATFETCH (c); + } + + if (c != '}') + { + if (syntax & RE_NO_BK_BRACES) + goto unfetch_interval; + else + FREE_STACK_RETURN (REG_BADBR); + } + + /* We just parsed a valid interval. */ + + /* If it's invalid to have no preceding re. */ + if (!laststart) + { + if (syntax & RE_CONTEXT_INVALID_OPS) + FREE_STACK_RETURN (REG_BADRPT); + else if (syntax & RE_CONTEXT_INDEP_OPS) + laststart = b; + else + goto unfetch_interval; + } + + /* If the upper bound is zero, don't want to succeed at + all; jump from `laststart' to `b + 3', which will be + the end of the buffer after we insert the jump. */ + if (upper_bound == 0) + { + GET_BUFFER_SPACE (3); + INSERT_JUMP (jump, laststart, b + 3); + b += 3; + } + + /* Otherwise, we have a nontrivial interval. When + we're all done, the pattern will look like: + set_number_at + set_number_at + succeed_n + + jump_n + (The upper bound and `jump_n' are omitted if + `upper_bound' is 1, though.) */ + else + { /* If the upper bound is > 1, we need to insert + more at the end of the loop. */ + unsigned nbytes = 10 + (upper_bound > 1) * 10; + + GET_BUFFER_SPACE (nbytes); + + /* Initialize lower bound of the `succeed_n', even + though it will be set during matching by its + attendant `set_number_at' (inserted next), + because `re_compile_fastmap' needs to know. + Jump to the `jump_n' we might insert below. */ + INSERT_JUMP2 (succeed_n, laststart, + b + 5 + (upper_bound > 1) * 5, + lower_bound); + b += 5; + + /* Code to initialize the lower bound. Insert + before the `succeed_n'. The `5' is the last two + bytes of this `set_number_at', plus 3 bytes of + the following `succeed_n'. */ + insert_op2 (set_number_at, laststart, 5, lower_bound, b); + b += 5; + + if (upper_bound > 1) + { /* More than one repetition is allowed, so + append a backward jump to the `succeed_n' + that starts this interval. + + When we've reached this during matching, + we'll have matched the interval once, so + jump back only `upper_bound - 1' times. */ + STORE_JUMP2 (jump_n, b, laststart + 5, + upper_bound - 1); + b += 5; + + /* The location we want to set is the second + parameter of the `jump_n'; that is `b-2' as + an absolute address. `laststart' will be + the `set_number_at' we're about to insert; + `laststart+3' the number to set, the source + for the relative address. But we are + inserting into the middle of the pattern -- + so everything is getting moved up by 5. + Conclusion: (b - 2) - (laststart + 3) + 5, + i.e., b - laststart. + + We insert this at the beginning of the loop + so that if we fail during matching, we'll + reinitialize the bounds. */ + insert_op2 (set_number_at, laststart, b - laststart, + upper_bound - 1, b); + b += 5; + } + } + pending_exact = 0; + beg_interval = NULL; + } + break; + + unfetch_interval: + /* If an invalid interval, match the characters as literals. */ + assert (beg_interval); + p = beg_interval; + beg_interval = NULL; + + /* normal_char and normal_backslash need `c'. */ + PATFETCH (c); + + if (!(syntax & RE_NO_BK_BRACES)) + { + if (p > pattern && p[-1] == '\\') + goto normal_backslash; + } + goto normal_char; + +#ifdef emacs + /* There is no way to specify the before_dot and after_dot + operators. rms says this is ok. --karl */ + case '=': + BUF_PUSH (at_dot); + break; + + case 's': + laststart = b; + PATFETCH (c); + BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]); + break; + + case 'S': + laststart = b; + PATFETCH (c); + BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]); + break; +#endif /* emacs */ + + + case 'w': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + laststart = b; + BUF_PUSH (wordchar); + break; + + + case 'W': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + laststart = b; + BUF_PUSH (notwordchar); + break; + + + case '<': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + BUF_PUSH (wordbeg); + break; + + case '>': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + BUF_PUSH (wordend); + break; + + case 'b': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + BUF_PUSH (wordbound); + break; + + case 'B': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + BUF_PUSH (notwordbound); + break; + + case '`': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + BUF_PUSH (begbuf); + break; + + case '\'': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + BUF_PUSH (endbuf); + break; + + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + if (syntax & RE_NO_BK_REFS) + goto normal_char; + + c1 = c - '0'; + + if (c1 > regnum) + FREE_STACK_RETURN (REG_ESUBREG); + + /* Can't back reference to a subexpression if inside of it. */ + if (group_in_compile_stack (compile_stack, (regnum_t) c1)) + goto normal_char; + + laststart = b; + BUF_PUSH_2 (duplicate, c1); + break; + + + case '+': + case '?': + if (syntax & RE_BK_PLUS_QM) + goto handle_plus; + else + goto normal_backslash; + + default: + normal_backslash: + /* You might think it would be useful for \ to mean + not to translate; but if we don't translate it + it will never match anything. */ + c = TRANSLATE (c); + goto normal_char; + } + break; + + + default: + /* Expects the character in `c'. */ + normal_char: + /* If no exactn currently being built. */ + if (!pending_exact + + /* If last exactn not at current position. */ + || pending_exact + *pending_exact + 1 != b + + /* We have only one byte following the exactn for the count. */ + || *pending_exact == (1 << BYTEWIDTH) - 1 + + /* If followed by a repetition operator. */ + || *p == '*' || *p == '^' + || ((syntax & RE_BK_PLUS_QM) + ? *p == '\\' && (p[1] == '+' || p[1] == '?') + : (*p == '+' || *p == '?')) + || ((syntax & RE_INTERVALS) + && ((syntax & RE_NO_BK_BRACES) + ? *p == '{' + : (p[0] == '\\' && p[1] == '{')))) + { + /* Start building a new exactn. */ + + laststart = b; + + BUF_PUSH_2 (exactn, 0); + pending_exact = b - 1; + } + + BUF_PUSH (c); + (*pending_exact)++; + break; + } /* switch (c) */ + } /* while p != pend */ + + + /* Through the pattern now. */ + + if (fixup_alt_jump) + STORE_JUMP (jump_past_alt, fixup_alt_jump, b); + + if (!COMPILE_STACK_EMPTY) + FREE_STACK_RETURN (REG_EPAREN); + + /* If we don't want backtracking, force success + the first time we reach the end of the compiled pattern. */ + if (syntax & RE_NO_POSIX_BACKTRACKING) + BUF_PUSH (succeed); + + free (compile_stack.stack); + + /* We have succeeded; set the length of the buffer. */ + bufp->used = b - bufp->buffer; + +#ifdef DEBUG + if (debug) + { + DEBUG_PRINT1 ("\nCompiled pattern: \n"); + print_compiled_pattern (bufp); + } +#endif /* DEBUG */ + +#ifndef MATCH_MAY_ALLOCATE + /* Initialize the failure stack to the largest possible stack. This + isn't necessary unless we're trying to avoid calling alloca in + the search and match routines. */ + { + int num_regs = bufp->re_nsub + 1; + + /* Since DOUBLE_FAIL_STACK refuses to double only if the current size + is strictly greater than re_max_failures, the largest possible stack + is 2 * re_max_failures failure points. */ + if (fail_stack.size < (2 * re_max_failures * MAX_FAILURE_ITEMS)) + { + fail_stack.size = (2 * re_max_failures * MAX_FAILURE_ITEMS); + +# ifdef emacs + if (! fail_stack.stack) + fail_stack.stack + = (fail_stack_elt_t *) xmalloc (fail_stack.size + * sizeof (fail_stack_elt_t)); + else + fail_stack.stack + = (fail_stack_elt_t *) xrealloc (fail_stack.stack, + (fail_stack.size + * sizeof (fail_stack_elt_t))); +# else /* not emacs */ + if (! fail_stack.stack) + fail_stack.stack + = (fail_stack_elt_t *) malloc (fail_stack.size + * sizeof (fail_stack_elt_t)); + else + fail_stack.stack + = (fail_stack_elt_t *) realloc (fail_stack.stack, + (fail_stack.size + * sizeof (fail_stack_elt_t))); +# endif /* not emacs */ + } + + regex_grow_registers (num_regs); + } +#endif /* not MATCH_MAY_ALLOCATE */ + + return REG_NOERROR; +} /* regex_compile */ + +/* Subroutines for `regex_compile'. */ + +/* Store OP at LOC followed by two-byte integer parameter ARG. */ + +static void +store_op1 (op, loc, arg) + re_opcode_t op; + unsigned char *loc; + int arg; +{ + *loc = (unsigned char) op; + STORE_NUMBER (loc + 1, arg); +} + + +/* Like `store_op1', but for two two-byte parameters ARG1 and ARG2. */ + +static void +store_op2 (op, loc, arg1, arg2) + re_opcode_t op; + unsigned char *loc; + int arg1, arg2; +{ + *loc = (unsigned char) op; + STORE_NUMBER (loc + 1, arg1); + STORE_NUMBER (loc + 3, arg2); +} + + +/* Copy the bytes from LOC to END to open up three bytes of space at LOC + for OP followed by two-byte integer parameter ARG. */ + +static void +insert_op1 (op, loc, arg, end) + re_opcode_t op; + unsigned char *loc; + int arg; + unsigned char *end; +{ + register unsigned char *pfrom = end; + register unsigned char *pto = end + 3; + + while (pfrom != loc) + *--pto = *--pfrom; + + store_op1 (op, loc, arg); +} + + +/* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2. */ + +static void +insert_op2 (op, loc, arg1, arg2, end) + re_opcode_t op; + unsigned char *loc; + int arg1, arg2; + unsigned char *end; +{ + register unsigned char *pfrom = end; + register unsigned char *pto = end + 5; + + while (pfrom != loc) + *--pto = *--pfrom; + + store_op2 (op, loc, arg1, arg2); +} + + +/* P points to just after a ^ in PATTERN. Return true if that ^ comes + after an alternative or a begin-subexpression. We assume there is at + least one character before the ^. */ + +static boolean +at_begline_loc_p (pattern, p, syntax) + const char *pattern, *p; + reg_syntax_t syntax; +{ + const char *prev = p - 2; + boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\'; + + return + /* After a subexpression? */ + (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash)) + /* After an alternative? */ + || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash)); +} + + +/* The dual of at_begline_loc_p. This one is for $. We assume there is + at least one character after the $, i.e., `P < PEND'. */ + +static boolean +at_endline_loc_p (p, pend, syntax) + const char *p, *pend; + reg_syntax_t syntax; +{ + const char *next = p; + boolean next_backslash = *next == '\\'; + const char *next_next = p + 1 < pend ? p + 1 : 0; + + return + /* Before a subexpression? */ + (syntax & RE_NO_BK_PARENS ? *next == ')' + : next_backslash && next_next && *next_next == ')') + /* Before an alternative? */ + || (syntax & RE_NO_BK_VBAR ? *next == '|' + : next_backslash && next_next && *next_next == '|'); +} + + +/* Returns true if REGNUM is in one of COMPILE_STACK's elements and + false if it's not. */ + +static boolean +group_in_compile_stack (compile_stack, regnum) + compile_stack_type compile_stack; + regnum_t regnum; +{ + int this_element; + + for (this_element = compile_stack.avail - 1; + this_element >= 0; + this_element--) + if (compile_stack.stack[this_element].regnum == regnum) + return true; + + return false; +} + + +/* Read the ending character of a range (in a bracket expression) from the + uncompiled pattern *P_PTR (which ends at PEND). We assume the + starting character is in `P[-2]'. (`P[-1]' is the character `-'.) + Then we set the translation of all bits between the starting and + ending characters (inclusive) in the compiled pattern B. + + Return an error code. + + We use these short variable names so we can use the same macros as + `regex_compile' itself. */ + +static reg_errcode_t +compile_range (p_ptr, pend, translate, syntax, b) + const char **p_ptr, *pend; + RE_TRANSLATE_TYPE translate; + reg_syntax_t syntax; + unsigned char *b; +{ + unsigned this_char; + + const char *p = *p_ptr; + unsigned int range_start, range_end; + + if (p == pend) + return REG_ERANGE; + + /* Even though the pattern is a signed `char *', we need to fetch + with unsigned char *'s; if the high bit of the pattern character + is set, the range endpoints will be negative if we fetch using a + signed char *. + + We also want to fetch the endpoints without translating them; the + appropriate translation is done in the bit-setting loop below. */ + /* The SVR4 compiler on the 3B2 had trouble with unsigned const char *. */ + range_start = ((const unsigned char *) p)[-2]; + range_end = ((const unsigned char *) p)[0]; + + /* Have to increment the pointer into the pattern string, so the + caller isn't still at the ending character. */ + (*p_ptr)++; + + /* If the start is after the end, the range is empty. */ + if (range_start > range_end) + return syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR; + + /* Here we see why `this_char' has to be larger than an `unsigned + char' -- the range is inclusive, so if `range_end' == 0xff + (assuming 8-bit characters), we would otherwise go into an infinite + loop, since all characters <= 0xff. */ + for (this_char = range_start; this_char <= range_end; this_char++) + { + SET_LIST_BIT (TRANSLATE (this_char)); + } + + return REG_NOERROR; +} + +/* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in + BUFP. A fastmap records which of the (1 << BYTEWIDTH) possible + characters can start a string that matches the pattern. This fastmap + is used by re_search to skip quickly over impossible starting points. + + The caller must supply the address of a (1 << BYTEWIDTH)-byte data + area as BUFP->fastmap. + + We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in + the pattern buffer. + + Returns 0 if we succeed, -2 if an internal error. */ + +int +re_compile_fastmap (bufp) + struct re_pattern_buffer *bufp; +{ + int j, k; +#ifdef MATCH_MAY_ALLOCATE + fail_stack_type fail_stack; +#endif +#ifndef REGEX_MALLOC + char *destination; +#endif + + register char *fastmap = bufp->fastmap; + unsigned char *pattern = bufp->buffer; + unsigned char *p = pattern; + register unsigned char *pend = pattern + bufp->used; + +#ifdef REL_ALLOC + /* This holds the pointer to the failure stack, when + it is allocated relocatably. */ + fail_stack_elt_t *failure_stack_ptr; +#endif + + /* Assume that each path through the pattern can be null until + proven otherwise. We set this false at the bottom of switch + statement, to which we get only if a particular path doesn't + match the empty string. */ + boolean path_can_be_null = true; + + /* We aren't doing a `succeed_n' to begin with. */ + boolean succeed_n_p = false; + + assert (fastmap != NULL && p != NULL); + + INIT_FAIL_STACK (); + bzero (fastmap, 1 << BYTEWIDTH); /* Assume nothing's valid. */ + bufp->fastmap_accurate = 1; /* It will be when we're done. */ + bufp->can_be_null = 0; + + while (1) + { + if (p == pend || *p == succeed) + { + /* We have reached the (effective) end of pattern. */ + if (!FAIL_STACK_EMPTY ()) + { + bufp->can_be_null |= path_can_be_null; + + /* Reset for next path. */ + path_can_be_null = true; + + p = fail_stack.stack[--fail_stack.avail].pointer; + + continue; + } + else + break; + } + + /* We should never be about to go beyond the end of the pattern. */ + assert (p < pend); + + switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++)) + { + + /* I guess the idea here is to simply not bother with a fastmap + if a backreference is used, since it's too hard to figure out + the fastmap for the corresponding group. Setting + `can_be_null' stops `re_search_2' from using the fastmap, so + that is all we do. */ + case duplicate: + bufp->can_be_null = 1; + goto done; + + + /* Following are the cases which match a character. These end + with `break'. */ + + case exactn: + fastmap[p[1]] = 1; + break; + + + case charset: + for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) + if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))) + fastmap[j] = 1; + break; + + + case charset_not: + /* Chars beyond end of map must be allowed. */ + for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++) + fastmap[j] = 1; + + for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) + if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))) + fastmap[j] = 1; + break; + + + case wordchar: + for (j = 0; j < (1 << BYTEWIDTH); j++) + if (SYNTAX (j) == Sword) + fastmap[j] = 1; + break; + + + case notwordchar: + for (j = 0; j < (1 << BYTEWIDTH); j++) + if (SYNTAX (j) != Sword) + fastmap[j] = 1; + break; + + + case anychar: + { + int fastmap_newline = fastmap['\n']; + + /* `.' matches anything ... */ + for (j = 0; j < (1 << BYTEWIDTH); j++) + fastmap[j] = 1; + + /* ... except perhaps newline. */ + if (!(bufp->syntax & RE_DOT_NEWLINE)) + fastmap['\n'] = fastmap_newline; + + /* Return if we have already set `can_be_null'; if we have, + then the fastmap is irrelevant. Something's wrong here. */ + else if (bufp->can_be_null) + goto done; + + /* Otherwise, have to check alternative paths. */ + break; + } + +#ifdef emacs + case syntaxspec: + k = *p++; + for (j = 0; j < (1 << BYTEWIDTH); j++) + if (SYNTAX (j) == (enum syntaxcode) k) + fastmap[j] = 1; + break; + + + case notsyntaxspec: + k = *p++; + for (j = 0; j < (1 << BYTEWIDTH); j++) + if (SYNTAX (j) != (enum syntaxcode) k) + fastmap[j] = 1; + break; + + + /* All cases after this match the empty string. These end with + `continue'. */ + + + case before_dot: + case at_dot: + case after_dot: + continue; +#endif /* emacs */ + + + case no_op: + case begline: + case endline: + case begbuf: + case endbuf: + case wordbound: + case notwordbound: + case wordbeg: + case wordend: + case push_dummy_failure: + continue; + + + case jump_n: + case pop_failure_jump: + case maybe_pop_jump: + case jump: + case jump_past_alt: + case dummy_failure_jump: + EXTRACT_NUMBER_AND_INCR (j, p); + p += j; + if (j > 0) + continue; + + /* Jump backward implies we just went through the body of a + loop and matched nothing. Opcode jumped to should be + `on_failure_jump' or `succeed_n'. Just treat it like an + ordinary jump. For a * loop, it has pushed its failure + point already; if so, discard that as redundant. */ + if ((re_opcode_t) *p != on_failure_jump + && (re_opcode_t) *p != succeed_n) + continue; + + p++; + EXTRACT_NUMBER_AND_INCR (j, p); + p += j; + + /* If what's on the stack is where we are now, pop it. */ + if (!FAIL_STACK_EMPTY () + && fail_stack.stack[fail_stack.avail - 1].pointer == p) + fail_stack.avail--; + + continue; + + + case on_failure_jump: + case on_failure_keep_string_jump: + handle_on_failure_jump: + EXTRACT_NUMBER_AND_INCR (j, p); + + /* For some patterns, e.g., `(a?)?', `p+j' here points to the + end of the pattern. We don't want to push such a point, + since when we restore it above, entering the switch will + increment `p' past the end of the pattern. We don't need + to push such a point since we obviously won't find any more + fastmap entries beyond `pend'. Such a pattern can match + the null string, though. */ + if (p + j < pend) + { + if (!PUSH_PATTERN_OP (p + j, fail_stack)) + { + RESET_FAIL_STACK (); + return -2; + } + } + else + bufp->can_be_null = 1; + + if (succeed_n_p) + { + EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */ + succeed_n_p = false; + } + + continue; + + + case succeed_n: + /* Get to the number of times to succeed. */ + p += 2; + + /* Increment p past the n for when k != 0. */ + EXTRACT_NUMBER_AND_INCR (k, p); + if (k == 0) + { + p -= 4; + succeed_n_p = true; /* Spaghetti code alert. */ + goto handle_on_failure_jump; + } + continue; + + + case set_number_at: + p += 4; + continue; + + + case start_memory: + case stop_memory: + p += 2; + continue; + + + default: + abort (); /* We have listed all the cases. */ + } /* switch *p++ */ + + /* Getting here means we have found the possible starting + characters for one path of the pattern -- and that the empty + string does not match. We need not follow this path further. + Instead, look at the next alternative (remembered on the + stack), or quit if no more. The test at the top of the loop + does these things. */ + path_can_be_null = false; + p = pend; + } /* while p */ + + /* Set `can_be_null' for the last path (also the first path, if the + pattern is empty). */ + bufp->can_be_null |= path_can_be_null; + + done: + RESET_FAIL_STACK (); + return 0; +} /* re_compile_fastmap */ +#ifdef _LIBC +weak_alias (__re_compile_fastmap, re_compile_fastmap) +#endif + +/* Set REGS to hold NUM_REGS registers, storing them in STARTS and + ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use + this memory for recording register information. STARTS and ENDS + must be allocated using the malloc library routine, and must each + be at least NUM_REGS * sizeof (regoff_t) bytes long. + + If NUM_REGS == 0, then subsequent matches should allocate their own + register data. + + Unless this function is called, the first search or match using + PATTERN_BUFFER will allocate its own register data, without + freeing the old data. */ + +void +re_set_registers (bufp, regs, num_regs, starts, ends) + struct re_pattern_buffer *bufp; + struct re_registers *regs; + unsigned num_regs; + regoff_t *starts, *ends; +{ + if (num_regs) + { + bufp->regs_allocated = REGS_REALLOCATE; + regs->num_regs = num_regs; + regs->start = starts; + regs->end = ends; + } + else + { + bufp->regs_allocated = REGS_UNALLOCATED; + regs->num_regs = 0; + regs->start = regs->end = (regoff_t *) 0; + } +} +#ifdef _LIBC +weak_alias (__re_set_registers, re_set_registers) +#endif + +/* Searching routines. */ + +/* Like re_search_2, below, but only one string is specified, and + doesn't let you say where to stop matching. */ + +int +re_search (bufp, string, size, startpos, range, regs) + struct re_pattern_buffer *bufp; + const char *string; + int size, startpos, range; + struct re_registers *regs; +{ + return re_search_2 (bufp, NULL, 0, string, size, startpos, range, + regs, size); +} +#ifdef _LIBC +weak_alias (__re_search, re_search) +#endif + + +/* Using the compiled pattern in BUFP->buffer, first tries to match the + virtual concatenation of STRING1 and STRING2, starting first at index + STARTPOS, then at STARTPOS + 1, and so on. + + STRING1 and STRING2 have length SIZE1 and SIZE2, respectively. + + RANGE is how far to scan while trying to match. RANGE = 0 means try + only at STARTPOS; in general, the last start tried is STARTPOS + + RANGE. + + In REGS, return the indices of the virtual concatenation of STRING1 + and STRING2 that matched the entire BUFP->buffer and its contained + subexpressions. + + Do not consider matching one past the index STOP in the virtual + concatenation of STRING1 and STRING2. + + We return either the position in the strings at which the match was + found, -1 if no match, or -2 if error (such as failure + stack overflow). */ + +int +re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop) + struct re_pattern_buffer *bufp; + const char *string1, *string2; + int size1, size2; + int startpos; + int range; + struct re_registers *regs; + int stop; +{ + int val; + register char *fastmap = bufp->fastmap; + register RE_TRANSLATE_TYPE translate = bufp->translate; + int total_size = size1 + size2; + int endpos = startpos + range; + + /* Check for out-of-range STARTPOS. */ + if (startpos < 0 || startpos > total_size) + return -1; + + /* Fix up RANGE if it might eventually take us outside + the virtual concatenation of STRING1 and STRING2. + Make sure we won't move STARTPOS below 0 or above TOTAL_SIZE. */ + if (endpos < 0) + range = 0 - startpos; + else if (endpos > total_size) + range = total_size - startpos; + + /* If the search isn't to be a backwards one, don't waste time in a + search for a pattern that must be anchored. */ + if (bufp->used > 0 && range > 0 + && ((re_opcode_t) bufp->buffer[0] == begbuf + /* `begline' is like `begbuf' if it cannot match at newlines. */ + || ((re_opcode_t) bufp->buffer[0] == begline + && !bufp->newline_anchor))) + { + if (startpos > 0) + return -1; + else + range = 1; + } + +#ifdef emacs + /* In a forward search for something that starts with \=. + don't keep searching past point. */ + if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == at_dot && range > 0) + { + range = PT - startpos; + if (range <= 0) + return -1; + } +#endif /* emacs */ + + /* Update the fastmap now if not correct already. */ + if (fastmap && !bufp->fastmap_accurate) + if (re_compile_fastmap (bufp) == -2) + return -2; + + /* Loop through the string, looking for a place to start matching. */ + for (;;) + { + /* If a fastmap is supplied, skip quickly over characters that + cannot be the start of a match. If the pattern can match the + null string, however, we don't need to skip characters; we want + the first null string. */ + if (fastmap && startpos < total_size && !bufp->can_be_null) + { + if (range > 0) /* Searching forwards. */ + { + register const char *d; + register int lim = 0; + int irange = range; + + if (startpos < size1 && startpos + range >= size1) + lim = range - (size1 - startpos); + + d = (startpos >= size1 ? string2 - size1 : string1) + startpos; + + /* Written out as an if-else to avoid testing `translate' + inside the loop. */ + if (translate) + while (range > lim + && !fastmap[(unsigned char) + translate[(unsigned char) *d++]]) + range--; + else + while (range > lim && !fastmap[(unsigned char) *d++]) + range--; + + startpos += irange - range; + } + else /* Searching backwards. */ + { + register char c = (size1 == 0 || startpos >= size1 + ? string2[startpos - size1] + : string1[startpos]); + + if (!fastmap[(unsigned char) TRANSLATE (c)]) + goto advance; + } + } + + /* If can't match the null string, and that's all we have left, fail. */ + if (range >= 0 && startpos == total_size && fastmap + && !bufp->can_be_null) + return -1; + + val = re_match_2_internal (bufp, string1, size1, string2, size2, + startpos, regs, stop); +#ifndef REGEX_MALLOC +# ifdef C_ALLOCA + alloca (0); +# endif +#endif + + if (val >= 0) + return startpos; + + if (val == -2) + return -2; + + advance: + if (!range) + break; + else if (range > 0) + { + range--; + startpos++; + } + else + { + range++; + startpos--; + } + } + return -1; +} /* re_search_2 */ +#ifdef _LIBC +weak_alias (__re_search_2, re_search_2) +#endif + +/* This converts PTR, a pointer into one of the search strings `string1' + and `string2' into an offset from the beginning of that string. */ +#define POINTER_TO_OFFSET(ptr) \ + (FIRST_STRING_P (ptr) \ + ? ((regoff_t) ((ptr) - string1)) \ + : ((regoff_t) ((ptr) - string2 + size1))) + +/* Macros for dealing with the split strings in re_match_2. */ + +#define MATCHING_IN_FIRST_STRING (dend == end_match_1) + +/* Call before fetching a character with *d. This switches over to + string2 if necessary. */ +#define PREFETCH() \ + while (d == dend) \ + { \ + /* End of string2 => fail. */ \ + if (dend == end_match_2) \ + goto fail; \ + /* End of string1 => advance to string2. */ \ + d = string2; \ + dend = end_match_2; \ + } + + +/* Test if at very beginning or at very end of the virtual concatenation + of `string1' and `string2'. If only one string, it's `string2'. */ +#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2) +#define AT_STRINGS_END(d) ((d) == end2) + + +/* Test if D points to a character which is word-constituent. We have + two special cases to check for: if past the end of string1, look at + the first character in string2; and if before the beginning of + string2, look at the last character in string1. */ +#define WORDCHAR_P(d) \ + (SYNTAX ((d) == end1 ? *string2 \ + : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \ + == Sword) + +/* Disabled due to a compiler bug -- see comment at case wordbound */ +#if 0 +/* Test if the character before D and the one at D differ with respect + to being word-constituent. */ +#define AT_WORD_BOUNDARY(d) \ + (AT_STRINGS_BEG (d) || AT_STRINGS_END (d) \ + || WORDCHAR_P (d - 1) != WORDCHAR_P (d)) +#endif + +/* Free everything we malloc. */ +#ifdef MATCH_MAY_ALLOCATE +# define FREE_VAR(var) if (var) REGEX_FREE (var); var = NULL +# define FREE_VARIABLES() \ + do { \ + REGEX_FREE_STACK (fail_stack.stack); \ + FREE_VAR (regstart); \ + FREE_VAR (regend); \ + FREE_VAR (old_regstart); \ + FREE_VAR (old_regend); \ + FREE_VAR (best_regstart); \ + FREE_VAR (best_regend); \ + FREE_VAR (reg_info); \ + FREE_VAR (reg_dummy); \ + FREE_VAR (reg_info_dummy); \ + } while (0) +#else +# define FREE_VARIABLES() ((void)0) /* Do nothing! But inhibit gcc warning. */ +#endif /* not MATCH_MAY_ALLOCATE */ + +/* These values must meet several constraints. They must not be valid + register values; since we have a limit of 255 registers (because + we use only one byte in the pattern for the register number), we can + use numbers larger than 255. They must differ by 1, because of + NUM_FAILURE_ITEMS above. And the value for the lowest register must + be larger than the value for the highest register, so we do not try + to actually save any registers when none are active. */ +#define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH) +#define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1) + +/* Matching routines. */ + +#ifndef emacs /* Emacs never uses this. */ +/* re_match is like re_match_2 except it takes only a single string. */ + +int +re_match (bufp, string, size, pos, regs) + struct re_pattern_buffer *bufp; + const char *string; + int size, pos; + struct re_registers *regs; +{ + int result = re_match_2_internal (bufp, NULL, 0, string, size, + pos, regs, size); +# ifndef REGEX_MALLOC +# ifdef C_ALLOCA + alloca (0); +# endif +# endif + return result; +} +# ifdef _LIBC +weak_alias (__re_match, re_match) +# endif +#endif /* not emacs */ + +static boolean group_match_null_string_p _RE_ARGS ((unsigned char **p, + unsigned char *end, + register_info_type *reg_info)); +static boolean alt_match_null_string_p _RE_ARGS ((unsigned char *p, + unsigned char *end, + register_info_type *reg_info)); +static boolean common_op_match_null_string_p _RE_ARGS ((unsigned char **p, + unsigned char *end, + register_info_type *reg_info)); +static int bcmp_translate _RE_ARGS ((const char *s1, const char *s2, + int len, char *translate)); + +/* re_match_2 matches the compiled pattern in BUFP against the + the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1 + and SIZE2, respectively). We start matching at POS, and stop + matching at STOP. + + If REGS is non-null and the `no_sub' field of BUFP is nonzero, we + store offsets for the substring each group matched in REGS. See the + documentation for exactly how many groups we fill. + + We return -1 if no match, -2 if an internal error (such as the + failure stack overflowing). Otherwise, we return the length of the + matched substring. */ + +int +re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) + struct re_pattern_buffer *bufp; + const char *string1, *string2; + int size1, size2; + int pos; + struct re_registers *regs; + int stop; +{ + int result = re_match_2_internal (bufp, string1, size1, string2, size2, + pos, regs, stop); +#ifndef REGEX_MALLOC +# ifdef C_ALLOCA + alloca (0); +# endif +#endif + return result; +} +#ifdef _LIBC +weak_alias (__re_match_2, re_match_2) +#endif + +/* This is a separate function so that we can force an alloca cleanup + afterwards. */ +static int +re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop) + struct re_pattern_buffer *bufp; + const char *string1, *string2; + int size1, size2; + int pos; + struct re_registers *regs; + int stop; +{ + /* General temporaries. */ + int mcnt; + unsigned char *p1; + + /* Just past the end of the corresponding string. */ + const char *end1, *end2; + + /* Pointers into string1 and string2, just past the last characters in + each to consider matching. */ + const char *end_match_1, *end_match_2; + + /* Where we are in the data, and the end of the current string. */ + const char *d, *dend; + + /* Where we are in the pattern, and the end of the pattern. */ + unsigned char *p = bufp->buffer; + register unsigned char *pend = p + bufp->used; + + /* Mark the opcode just after a start_memory, so we can test for an + empty subpattern when we get to the stop_memory. */ + unsigned char *just_past_start_mem = 0; + + /* We use this to map every character in the string. */ + RE_TRANSLATE_TYPE translate = bufp->translate; + + /* Failure point stack. Each place that can handle a failure further + down the line pushes a failure point on this stack. It consists of + restart, regend, and reg_info for all registers corresponding to + the subexpressions we're currently inside, plus the number of such + registers, and, finally, two char *'s. The first char * is where + to resume scanning the pattern; the second one is where to resume + scanning the strings. If the latter is zero, the failure point is + a ``dummy''; if a failure happens and the failure point is a dummy, + it gets discarded and the next next one is tried. */ +#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */ + fail_stack_type fail_stack; +#endif +#ifdef DEBUG + static unsigned failure_id = 0; + unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0; +#endif + +#ifdef REL_ALLOC + /* This holds the pointer to the failure stack, when + it is allocated relocatably. */ + fail_stack_elt_t *failure_stack_ptr; +#endif + + /* We fill all the registers internally, independent of what we + return, for use in backreferences. The number here includes + an element for register zero. */ + size_t num_regs = bufp->re_nsub + 1; + + /* The currently active registers. */ + active_reg_t lowest_active_reg = NO_LOWEST_ACTIVE_REG; + active_reg_t highest_active_reg = NO_HIGHEST_ACTIVE_REG; + + /* Information on the contents of registers. These are pointers into + the input strings; they record just what was matched (on this + attempt) by a subexpression part of the pattern, that is, the + regnum-th regstart pointer points to where in the pattern we began + matching and the regnum-th regend points to right after where we + stopped matching the regnum-th subexpression. (The zeroth register + keeps track of what the whole pattern matches.) */ +#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ + const char **regstart, **regend; +#endif + + /* If a group that's operated upon by a repetition operator fails to + match anything, then the register for its start will need to be + restored because it will have been set to wherever in the string we + are when we last see its open-group operator. Similarly for a + register's end. */ +#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ + const char **old_regstart, **old_regend; +#endif + + /* The is_active field of reg_info helps us keep track of which (possibly + nested) subexpressions we are currently in. The matched_something + field of reg_info[reg_num] helps us tell whether or not we have + matched any of the pattern so far this time through the reg_num-th + subexpression. These two fields get reset each time through any + loop their register is in. */ +#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */ + register_info_type *reg_info; +#endif + + /* The following record the register info as found in the above + variables when we find a match better than any we've seen before. + This happens as we backtrack through the failure points, which in + turn happens only if we have not yet matched the entire string. */ + unsigned best_regs_set = false; +#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ + const char **best_regstart, **best_regend; +#endif + + /* Logically, this is `best_regend[0]'. But we don't want to have to + allocate space for that if we're not allocating space for anything + else (see below). Also, we never need info about register 0 for + any of the other register vectors, and it seems rather a kludge to + treat `best_regend' differently than the rest. So we keep track of + the end of the best match so far in a separate variable. We + initialize this to NULL so that when we backtrack the first time + and need to test it, it's not garbage. */ + const char *match_end = NULL; + + /* This helps SET_REGS_MATCHED avoid doing redundant work. */ + int set_regs_matched_done = 0; + + /* Used when we pop values we don't care about. */ +#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ + const char **reg_dummy; + register_info_type *reg_info_dummy; +#endif + +#ifdef DEBUG + /* Counts the total number of registers pushed. */ + unsigned num_regs_pushed = 0; +#endif + + DEBUG_PRINT1 ("\n\nEntering re_match_2.\n"); + + INIT_FAIL_STACK (); + +#ifdef MATCH_MAY_ALLOCATE + /* Do not bother to initialize all the register variables if there are + no groups in the pattern, as it takes a fair amount of time. If + there are groups, we include space for register 0 (the whole + pattern), even though we never use it, since it simplifies the + array indexing. We should fix this. */ + if (bufp->re_nsub) + { + regstart = REGEX_TALLOC (num_regs, const char *); + regend = REGEX_TALLOC (num_regs, const char *); + old_regstart = REGEX_TALLOC (num_regs, const char *); + old_regend = REGEX_TALLOC (num_regs, const char *); + best_regstart = REGEX_TALLOC (num_regs, const char *); + best_regend = REGEX_TALLOC (num_regs, const char *); + reg_info = REGEX_TALLOC (num_regs, register_info_type); + reg_dummy = REGEX_TALLOC (num_regs, const char *); + reg_info_dummy = REGEX_TALLOC (num_regs, register_info_type); + + if (!(regstart && regend && old_regstart && old_regend && reg_info + && best_regstart && best_regend && reg_dummy && reg_info_dummy)) + { + FREE_VARIABLES (); + return -2; + } + } + else + { + /* We must initialize all our variables to NULL, so that + `FREE_VARIABLES' doesn't try to free them. */ + regstart = regend = old_regstart = old_regend = best_regstart + = best_regend = reg_dummy = NULL; + reg_info = reg_info_dummy = (register_info_type *) NULL; + } +#endif /* MATCH_MAY_ALLOCATE */ + + /* The starting position is bogus. */ + if (pos < 0 || pos > size1 + size2) + { + FREE_VARIABLES (); + return -1; + } + + /* Initialize subexpression text positions to -1 to mark ones that no + start_memory/stop_memory has been seen for. Also initialize the + register information struct. */ + for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++) + { + regstart[mcnt] = regend[mcnt] + = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE; + + REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE; + IS_ACTIVE (reg_info[mcnt]) = 0; + MATCHED_SOMETHING (reg_info[mcnt]) = 0; + EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0; + } + + /* We move `string1' into `string2' if the latter's empty -- but not if + `string1' is null. */ + if (size2 == 0 && string1 != NULL) + { + string2 = string1; + size2 = size1; + string1 = 0; + size1 = 0; + } + end1 = string1 + size1; + end2 = string2 + size2; + + /* Compute where to stop matching, within the two strings. */ + if (stop <= size1) + { + end_match_1 = string1 + stop; + end_match_2 = string2; + } + else + { + end_match_1 = end1; + end_match_2 = string2 + stop - size1; + } + + /* `p' scans through the pattern as `d' scans through the data. + `dend' is the end of the input string that `d' points within. `d' + is advanced into the following input string whenever necessary, but + this happens before fetching; therefore, at the beginning of the + loop, `d' can be pointing at the end of a string, but it cannot + equal `string2'. */ + if (size1 > 0 && pos <= size1) + { + d = string1 + pos; + dend = end_match_1; + } + else + { + d = string2 + pos - size1; + dend = end_match_2; + } + + DEBUG_PRINT1 ("The compiled pattern is:\n"); + DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend); + DEBUG_PRINT1 ("The string to match is: `"); + DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2); + DEBUG_PRINT1 ("'\n"); + + /* This loops over pattern commands. It exits by returning from the + function if the match is complete, or it drops through if the match + fails at this starting point in the input data. */ + for (;;) + { +#ifdef _LIBC + DEBUG_PRINT2 ("\n%p: ", p); +#else + DEBUG_PRINT2 ("\n0x%x: ", p); +#endif + + if (p == pend) + { /* End of pattern means we might have succeeded. */ + DEBUG_PRINT1 ("end of pattern ... "); + + /* If we haven't matched the entire string, and we want the + longest match, try backtracking. */ + if (d != end_match_2) + { + /* 1 if this match ends in the same string (string1 or string2) + as the best previous match. */ + boolean same_str_p = (FIRST_STRING_P (match_end) + == MATCHING_IN_FIRST_STRING); + /* 1 if this match is the best seen so far. */ + boolean best_match_p; + + /* AIX compiler got confused when this was combined + with the previous declaration. */ + if (same_str_p) + best_match_p = d > match_end; + else + best_match_p = !MATCHING_IN_FIRST_STRING; + + DEBUG_PRINT1 ("backtracking.\n"); + + if (!FAIL_STACK_EMPTY ()) + { /* More failure points to try. */ + + /* If exceeds best match so far, save it. */ + if (!best_regs_set || best_match_p) + { + best_regs_set = true; + match_end = d; + + DEBUG_PRINT1 ("\nSAVING match as best so far.\n"); + + for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++) + { + best_regstart[mcnt] = regstart[mcnt]; + best_regend[mcnt] = regend[mcnt]; + } + } + goto fail; + } + + /* If no failure points, don't restore garbage. And if + last match is real best match, don't restore second + best one. */ + else if (best_regs_set && !best_match_p) + { + restore_best_regs: + /* Restore best match. It may happen that `dend == + end_match_1' while the restored d is in string2. + For example, the pattern `x.*y.*z' against the + strings `x-' and `y-z-', if the two strings are + not consecutive in memory. */ + DEBUG_PRINT1 ("Restoring best registers.\n"); + + d = match_end; + dend = ((d >= string1 && d <= end1) + ? end_match_1 : end_match_2); + + for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++) + { + regstart[mcnt] = best_regstart[mcnt]; + regend[mcnt] = best_regend[mcnt]; + } + } + } /* d != end_match_2 */ + + succeed_label: + DEBUG_PRINT1 ("Accepting match.\n"); + + /* If caller wants register contents data back, do it. */ + if (regs && !bufp->no_sub) + { + /* Have the register data arrays been allocated? */ + if (bufp->regs_allocated == REGS_UNALLOCATED) + { /* No. So allocate them with malloc. We need one + extra element beyond `num_regs' for the `-1' marker + GNU code uses. */ + regs->num_regs = MAX (RE_NREGS, num_regs + 1); + regs->start = TALLOC (regs->num_regs, regoff_t); + regs->end = TALLOC (regs->num_regs, regoff_t); + if (regs->start == NULL || regs->end == NULL) + { + FREE_VARIABLES (); + return -2; + } + bufp->regs_allocated = REGS_REALLOCATE; + } + else if (bufp->regs_allocated == REGS_REALLOCATE) + { /* Yes. If we need more elements than were already + allocated, reallocate them. If we need fewer, just + leave it alone. */ + if (regs->num_regs < num_regs + 1) + { + regs->num_regs = num_regs + 1; + RETALLOC (regs->start, regs->num_regs, regoff_t); + RETALLOC (regs->end, regs->num_regs, regoff_t); + if (regs->start == NULL || regs->end == NULL) + { + FREE_VARIABLES (); + return -2; + } + } + } + else + { + /* These braces fend off a "empty body in an else-statement" + warning under GCC when assert expands to nothing. */ + assert (bufp->regs_allocated == REGS_FIXED); + } + + /* Convert the pointer data in `regstart' and `regend' to + indices. Register zero has to be set differently, + since we haven't kept track of any info for it. */ + if (regs->num_regs > 0) + { + regs->start[0] = pos; + regs->end[0] = (MATCHING_IN_FIRST_STRING + ? ((regoff_t) (d - string1)) + : ((regoff_t) (d - string2 + size1))); + } + + /* Go through the first `min (num_regs, regs->num_regs)' + registers, since that is all we initialized. */ + for (mcnt = 1; (unsigned) mcnt < MIN (num_regs, regs->num_regs); + mcnt++) + { + if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt])) + regs->start[mcnt] = regs->end[mcnt] = -1; + else + { + regs->start[mcnt] + = (regoff_t) POINTER_TO_OFFSET (regstart[mcnt]); + regs->end[mcnt] + = (regoff_t) POINTER_TO_OFFSET (regend[mcnt]); + } + } + + /* If the regs structure we return has more elements than + were in the pattern, set the extra elements to -1. If + we (re)allocated the registers, this is the case, + because we always allocate enough to have at least one + -1 at the end. */ + for (mcnt = num_regs; (unsigned) mcnt < regs->num_regs; mcnt++) + regs->start[mcnt] = regs->end[mcnt] = -1; + } /* regs && !bufp->no_sub */ + + DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n", + nfailure_points_pushed, nfailure_points_popped, + nfailure_points_pushed - nfailure_points_popped); + DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed); + + mcnt = d - pos - (MATCHING_IN_FIRST_STRING + ? string1 + : string2 - size1); + + DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt); + + FREE_VARIABLES (); + return mcnt; + } + + /* Otherwise match next pattern command. */ + switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++)) + { + /* Ignore these. Used to ignore the n of succeed_n's which + currently have n == 0. */ + case no_op: + DEBUG_PRINT1 ("EXECUTING no_op.\n"); + break; + + case succeed: + DEBUG_PRINT1 ("EXECUTING succeed.\n"); + goto succeed_label; + + /* Match the next n pattern characters exactly. The following + byte in the pattern defines n, and the n bytes after that + are the characters to match. */ + case exactn: + mcnt = *p++; + DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt); + + /* This is written out as an if-else so we don't waste time + testing `translate' inside the loop. */ + if (translate) + { + do + { + PREFETCH (); + if ((unsigned char) translate[(unsigned char) *d++] + != (unsigned char) *p++) + goto fail; + } + while (--mcnt); + } + else + { + do + { + PREFETCH (); + if (*d++ != (char) *p++) goto fail; + } + while (--mcnt); + } + SET_REGS_MATCHED (); + break; + + + /* Match any character except possibly a newline or a null. */ + case anychar: + DEBUG_PRINT1 ("EXECUTING anychar.\n"); + + PREFETCH (); + + if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n') + || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000')) + goto fail; + + SET_REGS_MATCHED (); + DEBUG_PRINT2 (" Matched `%d'.\n", *d); + d++; + break; + + + case charset: + case charset_not: + { + register unsigned char c; + boolean not = (re_opcode_t) *(p - 1) == charset_not; + + DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : ""); + + PREFETCH (); + c = TRANSLATE (*d); /* The character to match. */ + + /* Cast to `unsigned' instead of `unsigned char' in case the + bit list is a full 32 bytes long. */ + if (c < (unsigned) (*p * BYTEWIDTH) + && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) + not = !not; + + p += 1 + *p; + + if (!not) goto fail; + + SET_REGS_MATCHED (); + d++; + break; + } + + + /* The beginning of a group is represented by start_memory. + The arguments are the register number in the next byte, and the + number of groups inner to this one in the next. The text + matched within the group is recorded (in the internal + registers data structure) under the register number. */ + case start_memory: + DEBUG_PRINT3 ("EXECUTING start_memory %d (%d):\n", *p, p[1]); + + /* Find out if this group can match the empty string. */ + p1 = p; /* To send to group_match_null_string_p. */ + + if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE) + REG_MATCH_NULL_STRING_P (reg_info[*p]) + = group_match_null_string_p (&p1, pend, reg_info); + + /* Save the position in the string where we were the last time + we were at this open-group operator in case the group is + operated upon by a repetition operator, e.g., with `(a*)*b' + against `ab'; then we want to ignore where we are now in + the string in case this attempt to match fails. */ + old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p]) + ? REG_UNSET (regstart[*p]) ? d : regstart[*p] + : regstart[*p]; + DEBUG_PRINT2 (" old_regstart: %d\n", + POINTER_TO_OFFSET (old_regstart[*p])); + + regstart[*p] = d; + DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p])); + + IS_ACTIVE (reg_info[*p]) = 1; + MATCHED_SOMETHING (reg_info[*p]) = 0; + + /* Clear this whenever we change the register activity status. */ + set_regs_matched_done = 0; + + /* This is the new highest active register. */ + highest_active_reg = *p; + + /* If nothing was active before, this is the new lowest active + register. */ + if (lowest_active_reg == NO_LOWEST_ACTIVE_REG) + lowest_active_reg = *p; + + /* Move past the register number and inner group count. */ + p += 2; + just_past_start_mem = p; + + break; + + + /* The stop_memory opcode represents the end of a group. Its + arguments are the same as start_memory's: the register + number, and the number of inner groups. */ + case stop_memory: + DEBUG_PRINT3 ("EXECUTING stop_memory %d (%d):\n", *p, p[1]); + + /* We need to save the string position the last time we were at + this close-group operator in case the group is operated + upon by a repetition operator, e.g., with `((a*)*(b*)*)*' + against `aba'; then we want to ignore where we are now in + the string in case this attempt to match fails. */ + old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p]) + ? REG_UNSET (regend[*p]) ? d : regend[*p] + : regend[*p]; + DEBUG_PRINT2 (" old_regend: %d\n", + POINTER_TO_OFFSET (old_regend[*p])); + + regend[*p] = d; + DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p])); + + /* This register isn't active anymore. */ + IS_ACTIVE (reg_info[*p]) = 0; + + /* Clear this whenever we change the register activity status. */ + set_regs_matched_done = 0; + + /* If this was the only register active, nothing is active + anymore. */ + if (lowest_active_reg == highest_active_reg) + { + lowest_active_reg = NO_LOWEST_ACTIVE_REG; + highest_active_reg = NO_HIGHEST_ACTIVE_REG; + } + else + { /* We must scan for the new highest active register, since + it isn't necessarily one less than now: consider + (a(b)c(d(e)f)g). When group 3 ends, after the f), the + new highest active register is 1. */ + unsigned char r = *p - 1; + while (r > 0 && !IS_ACTIVE (reg_info[r])) + r--; + + /* If we end up at register zero, that means that we saved + the registers as the result of an `on_failure_jump', not + a `start_memory', and we jumped to past the innermost + `stop_memory'. For example, in ((.)*) we save + registers 1 and 2 as a result of the *, but when we pop + back to the second ), we are at the stop_memory 1. + Thus, nothing is active. */ + if (r == 0) + { + lowest_active_reg = NO_LOWEST_ACTIVE_REG; + highest_active_reg = NO_HIGHEST_ACTIVE_REG; + } + else + highest_active_reg = r; + } + + /* If just failed to match something this time around with a + group that's operated on by a repetition operator, try to + force exit from the ``loop'', and restore the register + information for this group that we had before trying this + last match. */ + if ((!MATCHED_SOMETHING (reg_info[*p]) + || just_past_start_mem == p - 1) + && (p + 2) < pend) + { + boolean is_a_jump_n = false; + + p1 = p + 2; + mcnt = 0; + switch ((re_opcode_t) *p1++) + { + case jump_n: + is_a_jump_n = true; + case pop_failure_jump: + case maybe_pop_jump: + case jump: + case dummy_failure_jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + if (is_a_jump_n) + p1 += 2; + break; + + default: + /* do nothing */ ; + } + p1 += mcnt; + + /* If the next operation is a jump backwards in the pattern + to an on_failure_jump right before the start_memory + corresponding to this stop_memory, exit from the loop + by forcing a failure after pushing on the stack the + on_failure_jump's jump in the pattern, and d. */ + if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump + && (re_opcode_t) p1[3] == start_memory && p1[4] == *p) + { + /* If this group ever matched anything, then restore + what its registers were before trying this last + failed match, e.g., with `(a*)*b' against `ab' for + regstart[1], and, e.g., with `((a*)*(b*)*)*' + against `aba' for regend[3]. + + Also restore the registers for inner groups for, + e.g., `((a*)(b*))*' against `aba' (register 3 would + otherwise get trashed). */ + + if (EVER_MATCHED_SOMETHING (reg_info[*p])) + { + unsigned r; + + EVER_MATCHED_SOMETHING (reg_info[*p]) = 0; + + /* Restore this and inner groups' (if any) registers. */ + for (r = *p; r < (unsigned) *p + (unsigned) *(p + 1); + r++) + { + regstart[r] = old_regstart[r]; + + /* xx why this test? */ + if (old_regend[r] >= regstart[r]) + regend[r] = old_regend[r]; + } + } + p1++; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + PUSH_FAILURE_POINT (p1 + mcnt, d, -2); + + goto fail; + } + } + + /* Move past the register number and the inner group count. */ + p += 2; + break; + + + /* \ has been turned into a `duplicate' command which is + followed by the numeric value of as the register number. */ + case duplicate: + { + register const char *d2, *dend2; + int regno = *p++; /* Get which register to match against. */ + DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno); + + /* Can't back reference a group which we've never matched. */ + if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno])) + goto fail; + + /* Where in input to try to start matching. */ + d2 = regstart[regno]; + + /* Where to stop matching; if both the place to start and + the place to stop matching are in the same string, then + set to the place to stop, otherwise, for now have to use + the end of the first string. */ + + dend2 = ((FIRST_STRING_P (regstart[regno]) + == FIRST_STRING_P (regend[regno])) + ? regend[regno] : end_match_1); + for (;;) + { + /* If necessary, advance to next segment in register + contents. */ + while (d2 == dend2) + { + if (dend2 == end_match_2) break; + if (dend2 == regend[regno]) break; + + /* End of string1 => advance to string2. */ + d2 = string2; + dend2 = regend[regno]; + } + /* At end of register contents => success */ + if (d2 == dend2) break; + + /* If necessary, advance to next segment in data. */ + PREFETCH (); + + /* How many characters left in this segment to match. */ + mcnt = dend - d; + + /* Want how many consecutive characters we can match in + one shot, so, if necessary, adjust the count. */ + if (mcnt > dend2 - d2) + mcnt = dend2 - d2; + + /* Compare that many; failure if mismatch, else move + past them. */ + if (translate + ? bcmp_translate (d, d2, mcnt, translate) + : memcmp (d, d2, mcnt)) + goto fail; + d += mcnt, d2 += mcnt; + + /* Do this because we've match some characters. */ + SET_REGS_MATCHED (); + } + } + break; + + + /* begline matches the empty string at the beginning of the string + (unless `not_bol' is set in `bufp'), and, if + `newline_anchor' is set, after newlines. */ + case begline: + DEBUG_PRINT1 ("EXECUTING begline.\n"); + + if (AT_STRINGS_BEG (d)) + { + if (!bufp->not_bol) break; + } + else if (d[-1] == '\n' && bufp->newline_anchor) + { + break; + } + /* In all other cases, we fail. */ + goto fail; + + + /* endline is the dual of begline. */ + case endline: + DEBUG_PRINT1 ("EXECUTING endline.\n"); + + if (AT_STRINGS_END (d)) + { + if (!bufp->not_eol) break; + } + + /* We have to ``prefetch'' the next character. */ + else if ((d == end1 ? *string2 : *d) == '\n' + && bufp->newline_anchor) + { + break; + } + goto fail; + + + /* Match at the very beginning of the data. */ + case begbuf: + DEBUG_PRINT1 ("EXECUTING begbuf.\n"); + if (AT_STRINGS_BEG (d)) + break; + goto fail; + + + /* Match at the very end of the data. */ + case endbuf: + DEBUG_PRINT1 ("EXECUTING endbuf.\n"); + if (AT_STRINGS_END (d)) + break; + goto fail; + + + /* on_failure_keep_string_jump is used to optimize `.*\n'. It + pushes NULL as the value for the string on the stack. Then + `pop_failure_point' will keep the current value for the + string, instead of restoring it. To see why, consider + matching `foo\nbar' against `.*\n'. The .* matches the foo; + then the . fails against the \n. But the next thing we want + to do is match the \n against the \n; if we restored the + string value, we would be back at the foo. + + Because this is used only in specific cases, we don't need to + check all the things that `on_failure_jump' does, to make + sure the right things get saved on the stack. Hence we don't + share its code. The only reason to push anything on the + stack at all is that otherwise we would have to change + `anychar's code to do something besides goto fail in this + case; that seems worse than this. */ + case on_failure_keep_string_jump: + DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump"); + + EXTRACT_NUMBER_AND_INCR (mcnt, p); +#ifdef _LIBC + DEBUG_PRINT3 (" %d (to %p):\n", mcnt, p + mcnt); +#else + DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt); +#endif + + PUSH_FAILURE_POINT (p + mcnt, NULL, -2); + break; + + + /* Uses of on_failure_jump: + + Each alternative starts with an on_failure_jump that points + to the beginning of the next alternative. Each alternative + except the last ends with a jump that in effect jumps past + the rest of the alternatives. (They really jump to the + ending jump of the following alternative, because tensioning + these jumps is a hassle.) + + Repeats start with an on_failure_jump that points past both + the repetition text and either the following jump or + pop_failure_jump back to this on_failure_jump. */ + case on_failure_jump: + on_failure: + DEBUG_PRINT1 ("EXECUTING on_failure_jump"); + + EXTRACT_NUMBER_AND_INCR (mcnt, p); +#ifdef _LIBC + DEBUG_PRINT3 (" %d (to %p)", mcnt, p + mcnt); +#else + DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt); +#endif + + /* If this on_failure_jump comes right before a group (i.e., + the original * applied to a group), save the information + for that group and all inner ones, so that if we fail back + to this point, the group's information will be correct. + For example, in \(a*\)*\1, we need the preceding group, + and in \(zz\(a*\)b*\)\2, we need the inner group. */ + + /* We can't use `p' to check ahead because we push + a failure point to `p + mcnt' after we do this. */ + p1 = p; + + /* We need to skip no_op's before we look for the + start_memory in case this on_failure_jump is happening as + the result of a completed succeed_n, as in \(a\)\{1,3\}b\1 + against aba. */ + while (p1 < pend && (re_opcode_t) *p1 == no_op) + p1++; + + if (p1 < pend && (re_opcode_t) *p1 == start_memory) + { + /* We have a new highest active register now. This will + get reset at the start_memory we are about to get to, + but we will have saved all the registers relevant to + this repetition op, as described above. */ + highest_active_reg = *(p1 + 1) + *(p1 + 2); + if (lowest_active_reg == NO_LOWEST_ACTIVE_REG) + lowest_active_reg = *(p1 + 1); + } + + DEBUG_PRINT1 (":\n"); + PUSH_FAILURE_POINT (p + mcnt, d, -2); + break; + + + /* A smart repeat ends with `maybe_pop_jump'. + We change it to either `pop_failure_jump' or `jump'. */ + case maybe_pop_jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt); + { + register unsigned char *p2 = p; + + /* Compare the beginning of the repeat with what in the + pattern follows its end. If we can establish that there + is nothing that they would both match, i.e., that we + would have to backtrack because of (as in, e.g., `a*a') + then we can change to pop_failure_jump, because we'll + never have to backtrack. + + This is not true in the case of alternatives: in + `(a|ab)*' we do need to backtrack to the `ab' alternative + (e.g., if the string was `ab'). But instead of trying to + detect that here, the alternative has put on a dummy + failure point which is what we will end up popping. */ + + /* Skip over open/close-group commands. + If what follows this loop is a ...+ construct, + look at what begins its body, since we will have to + match at least one of that. */ + while (1) + { + if (p2 + 2 < pend + && ((re_opcode_t) *p2 == stop_memory + || (re_opcode_t) *p2 == start_memory)) + p2 += 3; + else if (p2 + 6 < pend + && (re_opcode_t) *p2 == dummy_failure_jump) + p2 += 6; + else + break; + } + + p1 = p + mcnt; + /* p1[0] ... p1[2] are the `on_failure_jump' corresponding + to the `maybe_finalize_jump' of this case. Examine what + follows. */ + + /* If we're at the end of the pattern, we can change. */ + if (p2 == pend) + { + /* Consider what happens when matching ":\(.*\)" + against ":/". I don't really understand this code + yet. */ + p[-3] = (unsigned char) pop_failure_jump; + DEBUG_PRINT1 + (" End of pattern: change to `pop_failure_jump'.\n"); + } + + else if ((re_opcode_t) *p2 == exactn + || (bufp->newline_anchor && (re_opcode_t) *p2 == endline)) + { + register unsigned char c + = *p2 == (unsigned char) endline ? '\n' : p2[2]; + + if ((re_opcode_t) p1[3] == exactn && p1[5] != c) + { + p[-3] = (unsigned char) pop_failure_jump; + DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n", + c, p1[5]); + } + + else if ((re_opcode_t) p1[3] == charset + || (re_opcode_t) p1[3] == charset_not) + { + int not = (re_opcode_t) p1[3] == charset_not; + + if (c < (unsigned char) (p1[4] * BYTEWIDTH) + && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) + not = !not; + + /* `not' is equal to 1 if c would match, which means + that we can't change to pop_failure_jump. */ + if (!not) + { + p[-3] = (unsigned char) pop_failure_jump; + DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); + } + } + } + else if ((re_opcode_t) *p2 == charset) + { +#ifdef DEBUG + register unsigned char c + = *p2 == (unsigned char) endline ? '\n' : p2[2]; +#endif + +#if 0 + if ((re_opcode_t) p1[3] == exactn + && ! ((int) p2[1] * BYTEWIDTH > (int) p1[5] + && (p2[2 + p1[5] / BYTEWIDTH] + & (1 << (p1[5] % BYTEWIDTH))))) +#else + if ((re_opcode_t) p1[3] == exactn + && ! ((int) p2[1] * BYTEWIDTH > (int) p1[4] + && (p2[2 + p1[4] / BYTEWIDTH] + & (1 << (p1[4] % BYTEWIDTH))))) +#endif + { + p[-3] = (unsigned char) pop_failure_jump; + DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n", + c, p1[5]); + } + + else if ((re_opcode_t) p1[3] == charset_not) + { + int idx; + /* We win if the charset_not inside the loop + lists every character listed in the charset after. */ + for (idx = 0; idx < (int) p2[1]; idx++) + if (! (p2[2 + idx] == 0 + || (idx < (int) p1[4] + && ((p2[2 + idx] & ~ p1[5 + idx]) == 0)))) + break; + + if (idx == p2[1]) + { + p[-3] = (unsigned char) pop_failure_jump; + DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); + } + } + else if ((re_opcode_t) p1[3] == charset) + { + int idx; + /* We win if the charset inside the loop + has no overlap with the one after the loop. */ + for (idx = 0; + idx < (int) p2[1] && idx < (int) p1[4]; + idx++) + if ((p2[2 + idx] & p1[5 + idx]) != 0) + break; + + if (idx == p2[1] || idx == p1[4]) + { + p[-3] = (unsigned char) pop_failure_jump; + DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); + } + } + } + } + p -= 2; /* Point at relative address again. */ + if ((re_opcode_t) p[-1] != pop_failure_jump) + { + p[-1] = (unsigned char) jump; + DEBUG_PRINT1 (" Match => jump.\n"); + goto unconditional_jump; + } + /* Note fall through. */ + + + /* The end of a simple repeat has a pop_failure_jump back to + its matching on_failure_jump, where the latter will push a + failure point. The pop_failure_jump takes off failure + points put on by this pop_failure_jump's matching + on_failure_jump; we got through the pattern to here from the + matching on_failure_jump, so didn't fail. */ + case pop_failure_jump: + { + /* We need to pass separate storage for the lowest and + highest registers, even though we don't care about the + actual values. Otherwise, we will restore only one + register from the stack, since lowest will == highest in + `pop_failure_point'. */ + active_reg_t dummy_low_reg, dummy_high_reg; + unsigned char *pdummy; + const char *sdummy; + + DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n"); + POP_FAILURE_POINT (sdummy, pdummy, + dummy_low_reg, dummy_high_reg, + reg_dummy, reg_dummy, reg_info_dummy); + } + /* Note fall through. */ + + unconditional_jump: +#ifdef _LIBC + DEBUG_PRINT2 ("\n%p: ", p); +#else + DEBUG_PRINT2 ("\n0x%x: ", p); +#endif + /* Note fall through. */ + + /* Unconditionally jump (without popping any failure points). */ + case jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */ + DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt); + p += mcnt; /* Do the jump. */ +#ifdef _LIBC + DEBUG_PRINT2 ("(to %p).\n", p); +#else + DEBUG_PRINT2 ("(to 0x%x).\n", p); +#endif + break; + + + /* We need this opcode so we can detect where alternatives end + in `group_match_null_string_p' et al. */ + case jump_past_alt: + DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n"); + goto unconditional_jump; + + + /* Normally, the on_failure_jump pushes a failure point, which + then gets popped at pop_failure_jump. We will end up at + pop_failure_jump, also, and with a pattern of, say, `a+', we + are skipping over the on_failure_jump, so we have to push + something meaningless for pop_failure_jump to pop. */ + case dummy_failure_jump: + DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n"); + /* It doesn't matter what we push for the string here. What + the code at `fail' tests is the value for the pattern. */ + PUSH_FAILURE_POINT (NULL, NULL, -2); + goto unconditional_jump; + + + /* At the end of an alternative, we need to push a dummy failure + point in case we are followed by a `pop_failure_jump', because + we don't want the failure point for the alternative to be + popped. For example, matching `(a|ab)*' against `aab' + requires that we match the `ab' alternative. */ + case push_dummy_failure: + DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n"); + /* See comments just above at `dummy_failure_jump' about the + two zeroes. */ + PUSH_FAILURE_POINT (NULL, NULL, -2); + break; + + /* Have to succeed matching what follows at least n times. + After that, handle like `on_failure_jump'. */ + case succeed_n: + EXTRACT_NUMBER (mcnt, p + 2); + DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt); + + assert (mcnt >= 0); + /* Originally, this is how many times we HAVE to succeed. */ + if (mcnt > 0) + { + mcnt--; + p += 2; + STORE_NUMBER_AND_INCR (p, mcnt); +#ifdef _LIBC + DEBUG_PRINT3 (" Setting %p to %d.\n", p - 2, mcnt); +#else + DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p - 2, mcnt); +#endif + } + else if (mcnt == 0) + { +#ifdef _LIBC + DEBUG_PRINT2 (" Setting two bytes from %p to no_op.\n", p+2); +#else + DEBUG_PRINT2 (" Setting two bytes from 0x%x to no_op.\n", p+2); +#endif + p[2] = (unsigned char) no_op; + p[3] = (unsigned char) no_op; + goto on_failure; + } + break; + + case jump_n: + EXTRACT_NUMBER (mcnt, p + 2); + DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt); + + /* Originally, this is how many times we CAN jump. */ + if (mcnt) + { + mcnt--; + STORE_NUMBER (p + 2, mcnt); +#ifdef _LIBC + DEBUG_PRINT3 (" Setting %p to %d.\n", p + 2, mcnt); +#else + DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p + 2, mcnt); +#endif + goto unconditional_jump; + } + /* If don't have to jump any more, skip over the rest of command. */ + else + p += 4; + break; + + case set_number_at: + { + DEBUG_PRINT1 ("EXECUTING set_number_at.\n"); + + EXTRACT_NUMBER_AND_INCR (mcnt, p); + p1 = p + mcnt; + EXTRACT_NUMBER_AND_INCR (mcnt, p); +#ifdef _LIBC + DEBUG_PRINT3 (" Setting %p to %d.\n", p1, mcnt); +#else + DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p1, mcnt); +#endif + STORE_NUMBER (p1, mcnt); + break; + } + +#if 0 + /* The DEC Alpha C compiler 3.x generates incorrect code for the + test WORDCHAR_P (d - 1) != WORDCHAR_P (d) in the expansion of + AT_WORD_BOUNDARY, so this code is disabled. Expanding the + macro and introducing temporary variables works around the bug. */ + + case wordbound: + DEBUG_PRINT1 ("EXECUTING wordbound.\n"); + if (AT_WORD_BOUNDARY (d)) + break; + goto fail; + + case notwordbound: + DEBUG_PRINT1 ("EXECUTING notwordbound.\n"); + if (AT_WORD_BOUNDARY (d)) + goto fail; + break; +#else + case wordbound: + { + boolean prevchar, thischar; + + DEBUG_PRINT1 ("EXECUTING wordbound.\n"); + if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d)) + break; + + prevchar = WORDCHAR_P (d - 1); + thischar = WORDCHAR_P (d); + if (prevchar != thischar) + break; + goto fail; + } + + case notwordbound: + { + boolean prevchar, thischar; + + DEBUG_PRINT1 ("EXECUTING notwordbound.\n"); + if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d)) + goto fail; + + prevchar = WORDCHAR_P (d - 1); + thischar = WORDCHAR_P (d); + if (prevchar != thischar) + goto fail; + break; + } +#endif + + case wordbeg: + DEBUG_PRINT1 ("EXECUTING wordbeg.\n"); + if (WORDCHAR_P (d) && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1))) + break; + goto fail; + + case wordend: + DEBUG_PRINT1 ("EXECUTING wordend.\n"); + if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1) + && (!WORDCHAR_P (d) || AT_STRINGS_END (d))) + break; + goto fail; + +#ifdef emacs + case before_dot: + DEBUG_PRINT1 ("EXECUTING before_dot.\n"); + if (PTR_CHAR_POS ((unsigned char *) d) >= point) + goto fail; + break; + + case at_dot: + DEBUG_PRINT1 ("EXECUTING at_dot.\n"); + if (PTR_CHAR_POS ((unsigned char *) d) != point) + goto fail; + break; + + case after_dot: + DEBUG_PRINT1 ("EXECUTING after_dot.\n"); + if (PTR_CHAR_POS ((unsigned char *) d) <= point) + goto fail; + break; + + case syntaxspec: + DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt); + mcnt = *p++; + goto matchsyntax; + + case wordchar: + DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n"); + mcnt = (int) Sword; + matchsyntax: + PREFETCH (); + /* Can't use *d++ here; SYNTAX may be an unsafe macro. */ + d++; + if (SYNTAX (d[-1]) != (enum syntaxcode) mcnt) + goto fail; + SET_REGS_MATCHED (); + break; + + case notsyntaxspec: + DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt); + mcnt = *p++; + goto matchnotsyntax; + + case notwordchar: + DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n"); + mcnt = (int) Sword; + matchnotsyntax: + PREFETCH (); + /* Can't use *d++ here; SYNTAX may be an unsafe macro. */ + d++; + if (SYNTAX (d[-1]) == (enum syntaxcode) mcnt) + goto fail; + SET_REGS_MATCHED (); + break; + +#else /* not emacs */ + case wordchar: + DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n"); + PREFETCH (); + if (!WORDCHAR_P (d)) + goto fail; + SET_REGS_MATCHED (); + d++; + break; + + case notwordchar: + DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n"); + PREFETCH (); + if (WORDCHAR_P (d)) + goto fail; + SET_REGS_MATCHED (); + d++; + break; +#endif /* not emacs */ + + default: + abort (); + } + continue; /* Successfully executed one pattern command; keep going. */ + + + /* We goto here if a matching operation fails. */ + fail: + if (!FAIL_STACK_EMPTY ()) + { /* A restart point is known. Restore to that state. */ + DEBUG_PRINT1 ("\nFAIL:\n"); + POP_FAILURE_POINT (d, p, + lowest_active_reg, highest_active_reg, + regstart, regend, reg_info); + + /* If this failure point is a dummy, try the next one. */ + if (!p) + goto fail; + + /* If we failed to the end of the pattern, don't examine *p. */ + assert (p <= pend); + if (p < pend) + { + boolean is_a_jump_n = false; + + /* If failed to a backwards jump that's part of a repetition + loop, need to pop this failure point and use the next one. */ + switch ((re_opcode_t) *p) + { + case jump_n: + is_a_jump_n = true; + case maybe_pop_jump: + case pop_failure_jump: + case jump: + p1 = p + 1; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + p1 += mcnt; + + if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n) + || (!is_a_jump_n + && (re_opcode_t) *p1 == on_failure_jump)) + goto fail; + break; + default: + /* do nothing */ ; + } + } + + if (d >= string1 && d <= end1) + dend = end_match_1; + } + else + break; /* Matching at this starting point really fails. */ + } /* for (;;) */ + + if (best_regs_set) + goto restore_best_regs; + + FREE_VARIABLES (); + + return -1; /* Failure to match. */ +} /* re_match_2 */ + +/* Subroutine definitions for re_match_2. */ + + +/* We are passed P pointing to a register number after a start_memory. + + Return true if the pattern up to the corresponding stop_memory can + match the empty string, and false otherwise. + + If we find the matching stop_memory, sets P to point to one past its number. + Otherwise, sets P to an undefined byte less than or equal to END. + + We don't handle duplicates properly (yet). */ + +static boolean +group_match_null_string_p (p, end, reg_info) + unsigned char **p, *end; + register_info_type *reg_info; +{ + int mcnt; + /* Point to after the args to the start_memory. */ + unsigned char *p1 = *p + 2; + + while (p1 < end) + { + /* Skip over opcodes that can match nothing, and return true or + false, as appropriate, when we get to one that can't, or to the + matching stop_memory. */ + + switch ((re_opcode_t) *p1) + { + /* Could be either a loop or a series of alternatives. */ + case on_failure_jump: + p1++; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + + /* If the next operation is not a jump backwards in the + pattern. */ + + if (mcnt >= 0) + { + /* Go through the on_failure_jumps of the alternatives, + seeing if any of the alternatives cannot match nothing. + The last alternative starts with only a jump, + whereas the rest start with on_failure_jump and end + with a jump, e.g., here is the pattern for `a|b|c': + + /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6 + /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3 + /exactn/1/c + + So, we have to first go through the first (n-1) + alternatives and then deal with the last one separately. */ + + + /* Deal with the first (n-1) alternatives, which start + with an on_failure_jump (see above) that jumps to right + past a jump_past_alt. */ + + while ((re_opcode_t) p1[mcnt-3] == jump_past_alt) + { + /* `mcnt' holds how many bytes long the alternative + is, including the ending `jump_past_alt' and + its number. */ + + if (!alt_match_null_string_p (p1, p1 + mcnt - 3, + reg_info)) + return false; + + /* Move to right after this alternative, including the + jump_past_alt. */ + p1 += mcnt; + + /* Break if it's the beginning of an n-th alternative + that doesn't begin with an on_failure_jump. */ + if ((re_opcode_t) *p1 != on_failure_jump) + break; + + /* Still have to check that it's not an n-th + alternative that starts with an on_failure_jump. */ + p1++; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + if ((re_opcode_t) p1[mcnt-3] != jump_past_alt) + { + /* Get to the beginning of the n-th alternative. */ + p1 -= 3; + break; + } + } + + /* Deal with the last alternative: go back and get number + of the `jump_past_alt' just before it. `mcnt' contains + the length of the alternative. */ + EXTRACT_NUMBER (mcnt, p1 - 2); + + if (!alt_match_null_string_p (p1, p1 + mcnt, reg_info)) + return false; + + p1 += mcnt; /* Get past the n-th alternative. */ + } /* if mcnt > 0 */ + break; + + + case stop_memory: + assert (p1[1] == **p); + *p = p1 + 2; + return true; + + + default: + if (!common_op_match_null_string_p (&p1, end, reg_info)) + return false; + } + } /* while p1 < end */ + + return false; +} /* group_match_null_string_p */ + + +/* Similar to group_match_null_string_p, but doesn't deal with alternatives: + It expects P to be the first byte of a single alternative and END one + byte past the last. The alternative can contain groups. */ + +static boolean +alt_match_null_string_p (p, end, reg_info) + unsigned char *p, *end; + register_info_type *reg_info; +{ + int mcnt; + unsigned char *p1 = p; + + while (p1 < end) + { + /* Skip over opcodes that can match nothing, and break when we get + to one that can't. */ + + switch ((re_opcode_t) *p1) + { + /* It's a loop. */ + case on_failure_jump: + p1++; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + p1 += mcnt; + break; + + default: + if (!common_op_match_null_string_p (&p1, end, reg_info)) + return false; + } + } /* while p1 < end */ + + return true; +} /* alt_match_null_string_p */ + + +/* Deals with the ops common to group_match_null_string_p and + alt_match_null_string_p. + + Sets P to one after the op and its arguments, if any. */ + +static boolean +common_op_match_null_string_p (p, end, reg_info) + unsigned char **p, *end; + register_info_type *reg_info; +{ + int mcnt; + boolean ret; + int reg_no; + unsigned char *p1 = *p; + + switch ((re_opcode_t) *p1++) + { + case no_op: + case begline: + case endline: + case begbuf: + case endbuf: + case wordbeg: + case wordend: + case wordbound: + case notwordbound: +#ifdef emacs + case before_dot: + case at_dot: + case after_dot: +#endif + break; + + case start_memory: + reg_no = *p1; + assert (reg_no > 0 && reg_no <= MAX_REGNUM); + ret = group_match_null_string_p (&p1, end, reg_info); + + /* Have to set this here in case we're checking a group which + contains a group and a back reference to it. */ + + if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE) + REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret; + + if (!ret) + return false; + break; + + /* If this is an optimized succeed_n for zero times, make the jump. */ + case jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + if (mcnt >= 0) + p1 += mcnt; + else + return false; + break; + + case succeed_n: + /* Get to the number of times to succeed. */ + p1 += 2; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + + if (mcnt == 0) + { + p1 -= 4; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + p1 += mcnt; + } + else + return false; + break; + + case duplicate: + if (!REG_MATCH_NULL_STRING_P (reg_info[*p1])) + return false; + break; + + case set_number_at: + p1 += 4; + + default: + /* All other opcodes mean we cannot match the empty string. */ + return false; + } + + *p = p1; + return true; +} /* common_op_match_null_string_p */ + + +/* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN + bytes; nonzero otherwise. */ + +static int +bcmp_translate (s1, s2, len, translate) + const char *s1, *s2; + register int len; + RE_TRANSLATE_TYPE translate; +{ + register const unsigned char *p1 = (const unsigned char *) s1; + register const unsigned char *p2 = (const unsigned char *) s2; + while (len) + { + if (translate[*p1++] != translate[*p2++]) return 1; + len--; + } + return 0; +} + +/* Entry points for GNU code. */ + +/* re_compile_pattern is the GNU regular expression compiler: it + compiles PATTERN (of length SIZE) and puts the result in BUFP. + Returns 0 if the pattern was valid, otherwise an error string. + + Assumes the `allocated' (and perhaps `buffer') and `translate' fields + are set in BUFP on entry. + + We call regex_compile to do the actual compilation. */ + +const char * +re_compile_pattern (pattern, length, bufp) + const char *pattern; + size_t length; + struct re_pattern_buffer *bufp; +{ + reg_errcode_t ret; + + /* GNU code is written to assume at least RE_NREGS registers will be set + (and at least one extra will be -1). */ + bufp->regs_allocated = REGS_UNALLOCATED; + + /* And GNU code determines whether or not to get register information + by passing null for the REGS argument to re_match, etc., not by + setting no_sub. */ + bufp->no_sub = 0; + + /* Match anchors at newline. */ + bufp->newline_anchor = 1; + + ret = regex_compile (pattern, length, re_syntax_options, bufp); + + if (!ret) + return NULL; + return gettext (re_error_msgid[(int) ret]); +} +#ifdef _LIBC +weak_alias (__re_compile_pattern, re_compile_pattern) +#endif + +/* Entry points compatible with 4.2 BSD regex library. We don't define + them unless specifically requested. */ + +#if defined _REGEX_RE_COMP || defined _LIBC + +/* BSD has one and only one pattern buffer. */ +static struct re_pattern_buffer re_comp_buf; + +char * +#ifdef _LIBC +/* Make these definitions weak in libc, so POSIX programs can redefine + these names if they don't use our functions, and still use + regcomp/regexec below without link errors. */ +weak_function +#endif +re_comp (s) + const char *s; +{ + reg_errcode_t ret; + + if (!s) + { + if (!re_comp_buf.buffer) + return gettext ("No previous regular expression"); + return 0; + } + + if (!re_comp_buf.buffer) + { + re_comp_buf.buffer = (unsigned char *) malloc (200); + if (re_comp_buf.buffer == NULL) + return (char *) gettext (re_error_msgid[(int) REG_ESPACE]); + re_comp_buf.allocated = 200; + + re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH); + if (re_comp_buf.fastmap == NULL) + return (char *) gettext (re_error_msgid[(int) REG_ESPACE]); + } + + /* Since `re_exec' always passes NULL for the `regs' argument, we + don't need to initialize the pattern buffer fields which affect it. */ + + /* Match anchors at newlines. */ + re_comp_buf.newline_anchor = 1; + + ret = regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf); + + if (!ret) + return NULL; + + /* Yes, we're discarding `const' here if !HAVE_LIBINTL. */ + return (char *) gettext (re_error_msgid[(int) ret]); +} + + +int +#ifdef _LIBC +weak_function +#endif +re_exec (s) + const char *s; +{ + const int len = strlen (s); + return + 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0); +} + +#endif /* _REGEX_RE_COMP */ + +/* POSIX.2 functions. Don't define these for Emacs. */ + +#ifndef emacs + +/* regcomp takes a regular expression as a string and compiles it. + + PREG is a regex_t *. We do not expect any fields to be initialized, + since POSIX says we shouldn't. Thus, we set + + `buffer' to the compiled pattern; + `used' to the length of the compiled pattern; + `syntax' to RE_SYNTAX_POSIX_EXTENDED if the + REG_EXTENDED bit in CFLAGS is set; otherwise, to + RE_SYNTAX_POSIX_BASIC; + `newline_anchor' to REG_NEWLINE being set in CFLAGS; + `fastmap' and `fastmap_accurate' to zero; + `re_nsub' to the number of subexpressions in PATTERN. + + PATTERN is the address of the pattern string. + + CFLAGS is a series of bits which affect compilation. + + If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we + use POSIX basic syntax. + + If REG_NEWLINE is set, then . and [^...] don't match newline. + Also, regexec will try a match beginning after every newline. + + If REG_ICASE is set, then we considers upper- and lowercase + versions of letters to be equivalent when matching. + + If REG_NOSUB is set, then when PREG is passed to regexec, that + routine will report only success or failure, and nothing about the + registers. + + It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for + the return codes and their meanings.) */ + +int +regcomp (preg, pattern, cflags) + regex_t *preg; + const char *pattern; + int cflags; +{ + reg_errcode_t ret; + reg_syntax_t syntax + = (cflags & REG_EXTENDED) ? + RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC; + + /* regex_compile will allocate the space for the compiled pattern. */ + preg->buffer = 0; + preg->allocated = 0; + preg->used = 0; + + /* Don't bother to use a fastmap when searching. This simplifies the + REG_NEWLINE case: if we used a fastmap, we'd have to put all the + characters after newlines into the fastmap. This way, we just try + every character. */ + preg->fastmap = 0; + + if (cflags & REG_ICASE) + { + unsigned i; + + preg->translate + = (RE_TRANSLATE_TYPE) malloc (CHAR_SET_SIZE + * sizeof (*(RE_TRANSLATE_TYPE)0)); + if (preg->translate == NULL) + return (int) REG_ESPACE; + + /* Map uppercase characters to corresponding lowercase ones. */ + for (i = 0; i < CHAR_SET_SIZE; i++) + preg->translate[i] = ISUPPER (i) ? tolower (i) : i; + } + else + preg->translate = NULL; + + /* If REG_NEWLINE is set, newlines are treated differently. */ + if (cflags & REG_NEWLINE) + { /* REG_NEWLINE implies neither . nor [^...] match newline. */ + syntax &= ~RE_DOT_NEWLINE; + syntax |= RE_HAT_LISTS_NOT_NEWLINE; + /* It also changes the matching behavior. */ + preg->newline_anchor = 1; + } + else + preg->newline_anchor = 0; + + preg->no_sub = !!(cflags & REG_NOSUB); + + /* POSIX says a null character in the pattern terminates it, so we + can use strlen here in compiling the pattern. */ + ret = regex_compile (pattern, strlen (pattern), syntax, preg); + + /* POSIX doesn't distinguish between an unmatched open-group and an + unmatched close-group: both are REG_EPAREN. */ + if (ret == REG_ERPAREN) ret = REG_EPAREN; + + return (int) ret; +} +#ifdef _LIBC +weak_alias (__regcomp, regcomp) +#endif + + +/* regexec searches for a given pattern, specified by PREG, in the + string STRING. + + If NMATCH is zero or REG_NOSUB was set in the cflags argument to + `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at + least NMATCH elements, and we set them to the offsets of the + corresponding matched substrings. + + EFLAGS specifies `execution flags' which affect matching: if + REG_NOTBOL is set, then ^ does not match at the beginning of the + string; if REG_NOTEOL is set, then $ does not match at the end. + + We return 0 if we find a match and REG_NOMATCH if not. */ + +int +regexec (preg, string, nmatch, pmatch, eflags) + const regex_t *preg; + const char *string; + size_t nmatch; + regmatch_t pmatch[]; + int eflags; +{ + int ret; + struct re_registers regs; + regex_t private_preg; + int len = strlen (string); + boolean want_reg_info = !preg->no_sub && nmatch > 0; + + private_preg = *preg; + + private_preg.not_bol = !!(eflags & REG_NOTBOL); + private_preg.not_eol = !!(eflags & REG_NOTEOL); + + /* The user has told us exactly how many registers to return + information about, via `nmatch'. We have to pass that on to the + matching routines. */ + private_preg.regs_allocated = REGS_FIXED; + + if (want_reg_info) + { + regs.num_regs = nmatch; + regs.start = TALLOC (nmatch, regoff_t); + regs.end = TALLOC (nmatch, regoff_t); + if (regs.start == NULL || regs.end == NULL) + return (int) REG_NOMATCH; + } + + /* Perform the searching operation. */ + ret = re_search (&private_preg, string, len, + /* start: */ 0, /* range: */ len, + want_reg_info ? ®s : (struct re_registers *) 0); + + /* Copy the register information to the POSIX structure. */ + if (want_reg_info) + { + if (ret >= 0) + { + unsigned r; + + for (r = 0; r < nmatch; r++) + { + pmatch[r].rm_so = regs.start[r]; + pmatch[r].rm_eo = regs.end[r]; + } + } + + /* If we needed the temporary register info, free the space now. */ + free (regs.start); + free (regs.end); + } + + /* We want zero return to mean success, unlike `re_search'. */ + return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH; +} +#ifdef _LIBC +weak_alias (__regexec, regexec) +#endif + + +/* Returns a message corresponding to an error code, ERRCODE, returned + from either regcomp or regexec. We don't use PREG here. */ + +size_t +regerror (errcode, preg, errbuf, errbuf_size) + int errcode; + const regex_t *preg; + char *errbuf; + size_t errbuf_size; +{ + const char *msg; + size_t msg_size; + + if (errcode < 0 + || errcode >= (int) (sizeof (re_error_msgid) + / sizeof (re_error_msgid[0]))) + /* Only error codes returned by the rest of the code should be passed + to this routine. If we are given anything else, or if other regex + code generates an invalid error code, then the program has a bug. + Dump core so we can fix it. */ + abort (); + + msg = gettext (re_error_msgid[errcode]); + + msg_size = strlen (msg) + 1; /* Includes the null. */ + + if (errbuf_size != 0) + { + if (msg_size > errbuf_size) + { +#if defined HAVE_MEMPCPY || defined _LIBC + *((char *) __mempcpy (errbuf, msg, errbuf_size - 1)) = '\0'; +#else + memcpy (errbuf, msg, errbuf_size - 1); + errbuf[errbuf_size - 1] = 0; +#endif + } + else + memcpy (errbuf, msg, msg_size); + } + + return msg_size; +} +#ifdef _LIBC +weak_alias (__regerror, regerror) +#endif + + +/* Free dynamically allocated space used by PREG. */ + +void +regfree (preg) + regex_t *preg; +{ + if (preg->buffer != NULL) + free (preg->buffer); + preg->buffer = NULL; + + preg->allocated = 0; + preg->used = 0; + + if (preg->fastmap != NULL) + free (preg->fastmap); + preg->fastmap = NULL; + preg->fastmap_accurate = 0; + + if (preg->translate != NULL) + free (preg->translate); + preg->translate = NULL; +} +#ifdef _LIBC +weak_alias (__regfree, regfree) +#endif + +#endif /* not emacs */ diff --git a/reactos/lib/kjs/src/regex.h b/reactos/lib/kjs/src/regex.h new file mode 100644 index 00000000000..2bca5378a41 --- /dev/null +++ b/reactos/lib/kjs/src/regex.h @@ -0,0 +1,572 @@ +/* Definitions for data structures and routines for the regular + expression library, version 0.12. + Copyright (C) 1985,89,90,91,92,93,95,96,97,98 Free Software Foundation, Inc. + + This file is part of the GNU C Library. Its master source is NOT part of + the C library, however. The master source lives in /gd/gnu/lib. + + The GNU C 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. + + The GNU C 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 the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _REGEX_H +#define _REGEX_H 1 + +/* Allow the use in C++ code. */ +#ifdef __cplusplus +extern "C" { +#endif + +/* POSIX says that must be included (by the caller) before + . */ + +#if !defined _POSIX_C_SOURCE && !defined _POSIX_SOURCE && defined VMS +/* VMS doesn't have `size_t' in , even though POSIX says it + should be there. */ +# include +#endif + +/* The following two types have to be signed and unsigned integer type + wide enough to hold a value of a pointer. For most ANSI compilers + ptrdiff_t and size_t should be likely OK. Still size of these two + types is 2 for Microsoft C. Ugh... */ +typedef long int s_reg_t; +typedef unsigned long int active_reg_t; + +/* The following bits are used to determine the regexp syntax we + recognize. The set/not-set meanings are chosen so that Emacs syntax + remains the value 0. The bits are given in alphabetical order, and + the definitions shifted by one from the previous bit; thus, when we + add or remove a bit, only one other definition need change. */ +typedef unsigned long int reg_syntax_t; + +/* If this bit is not set, then \ inside a bracket expression is literal. + If set, then such a \ quotes the following character. */ +#define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1) + +/* If this bit is not set, then + and ? are operators, and \+ and \? are + literals. + If set, then \+ and \? are operators and + and ? are literals. */ +#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1) + +/* If this bit is set, then character classes are supported. They are: + [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:], + [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:]. + If not set, then character classes are not supported. */ +#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1) + +/* If this bit is set, then ^ and $ are always anchors (outside bracket + expressions, of course). + If this bit is not set, then it depends: + ^ is an anchor if it is at the beginning of a regular + expression or after an open-group or an alternation operator; + $ is an anchor if it is at the end of a regular expression, or + before a close-group or an alternation operator. + + This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because + POSIX draft 11.2 says that * etc. in leading positions is undefined. + We already implemented a previous draft which made those constructs + invalid, though, so we haven't changed the code back. */ +#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1) + +/* If this bit is set, then special characters are always special + regardless of where they are in the pattern. + If this bit is not set, then special characters are special only in + some contexts; otherwise they are ordinary. Specifically, + * + ? and intervals are only special when not after the beginning, + open-group, or alternation operator. */ +#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1) + +/* If this bit is set, then *, +, ?, and { cannot be first in an re or + immediately after an alternation or begin-group operator. */ +#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1) + +/* If this bit is set, then . matches newline. + If not set, then it doesn't. */ +#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1) + +/* If this bit is set, then . doesn't match NUL. + If not set, then it does. */ +#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1) + +/* If this bit is set, nonmatching lists [^...] do not match newline. + If not set, they do. */ +#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1) + +/* If this bit is set, either \{...\} or {...} defines an + interval, depending on RE_NO_BK_BRACES. + If not set, \{, \}, {, and } are literals. */ +#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1) + +/* If this bit is set, +, ? and | aren't recognized as operators. + If not set, they are. */ +#define RE_LIMITED_OPS (RE_INTERVALS << 1) + +/* If this bit is set, newline is an alternation operator. + If not set, newline is literal. */ +#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1) + +/* If this bit is set, then `{...}' defines an interval, and \{ and \} + are literals. + If not set, then `\{...\}' defines an interval. */ +#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1) + +/* If this bit is set, (...) defines a group, and \( and \) are literals. + If not set, \(...\) defines a group, and ( and ) are literals. */ +#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1) + +/* If this bit is set, then \ matches . + If not set, then \ is a back-reference. */ +#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1) + +/* If this bit is set, then | is an alternation operator, and \| is literal. + If not set, then \| is an alternation operator, and | is literal. */ +#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1) + +/* If this bit is set, then an ending range point collating higher + than the starting range point, as in [z-a], is invalid. + If not set, then when ending range point collates higher than the + starting range point, the range is ignored. */ +#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1) + +/* If this bit is set, then an unmatched ) is ordinary. + If not set, then an unmatched ) is invalid. */ +#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1) + +/* If this bit is set, succeed as soon as we match the whole pattern, + without further backtracking. */ +#define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1) + +/* If this bit is set, do not process the GNU regex operators. + If not set, then the GNU regex operators are recognized. */ +#define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1) + +/* If this bit is set, turn on internal regex debugging. + If not set, and debugging was on, turn it off. + This only works if regex.c is compiled -DDEBUG. + We define this bit always, so that all that's needed to turn on + debugging is to recompile regex.c; the calling code can always have + this bit set, and it won't affect anything in the normal case. */ +#define RE_DEBUG (RE_NO_GNU_OPS << 1) + +/* This global variable defines the particular regexp syntax to use (for + some interfaces). When a regexp is compiled, the syntax used is + stored in the pattern buffer, so changing this does not affect + already-compiled regexps. */ +extern reg_syntax_t re_syntax_options; + +/* Define combinations of the above bits for the standard possibilities. + (The [[[ comments delimit what gets put into the Texinfo file, so + don't delete them!) */ +/* [[[begin syntaxes]]] */ +#define RE_SYNTAX_EMACS 0 + +#define RE_SYNTAX_AWK \ + (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ + | RE_NO_BK_PARENS | RE_NO_BK_REFS \ + | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \ + | RE_DOT_NEWLINE | RE_CONTEXT_INDEP_ANCHORS \ + | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS) + +#define RE_SYNTAX_GNU_AWK \ + ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG) \ + & ~(RE_DOT_NOT_NULL | RE_INTERVALS | RE_CONTEXT_INDEP_OPS)) + +#define RE_SYNTAX_POSIX_AWK \ + (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \ + | RE_INTERVALS | RE_NO_GNU_OPS) + +#define RE_SYNTAX_GREP \ + (RE_BK_PLUS_QM | RE_CHAR_CLASSES \ + | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \ + | RE_NEWLINE_ALT) + +#define RE_SYNTAX_EGREP \ + (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \ + | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \ + | RE_NEWLINE_ALT | RE_NO_BK_PARENS \ + | RE_NO_BK_VBAR) + +#define RE_SYNTAX_POSIX_EGREP \ + (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES) + +/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */ +#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC + +#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC + +/* Syntax bits common to both basic and extended POSIX regex syntax. */ +#define _RE_SYNTAX_POSIX_COMMON \ + (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \ + | RE_INTERVALS | RE_NO_EMPTY_RANGES) + +#define RE_SYNTAX_POSIX_BASIC \ + (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM) + +/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes + RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this + isn't minimal, since other operators, such as \`, aren't disabled. */ +#define RE_SYNTAX_POSIX_MINIMAL_BASIC \ + (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS) + +#define RE_SYNTAX_POSIX_EXTENDED \ + (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ + | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \ + | RE_NO_BK_PARENS | RE_NO_BK_VBAR \ + | RE_UNMATCHED_RIGHT_PAREN_ORD) + +/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS + replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */ +#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \ + (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ + | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \ + | RE_NO_BK_PARENS | RE_NO_BK_REFS \ + | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD) +/* [[[end syntaxes]]] */ + +/* Maximum number of duplicates an interval can allow. Some systems + (erroneously) define this in other header files, but we want our + value, so remove any previous define. */ +#ifdef RE_DUP_MAX +# undef RE_DUP_MAX +#endif +/* If sizeof(int) == 2, then ((1 << 15) - 1) overflows. */ +#define RE_DUP_MAX (0x7fff) + + +/* POSIX `cflags' bits (i.e., information for `regcomp'). */ + +/* If this bit is set, then use extended regular expression syntax. + If not set, then use basic regular expression syntax. */ +#define REG_EXTENDED 1 + +/* If this bit is set, then ignore case when matching. + If not set, then case is significant. */ +#define REG_ICASE (REG_EXTENDED << 1) + +/* If this bit is set, then anchors do not match at newline + characters in the string. + If not set, then anchors do match at newlines. */ +#define REG_NEWLINE (REG_ICASE << 1) + +/* If this bit is set, then report only success or fail in regexec. + If not set, then returns differ between not matching and errors. */ +#define REG_NOSUB (REG_NEWLINE << 1) + + +/* POSIX `eflags' bits (i.e., information for regexec). */ + +/* If this bit is set, then the beginning-of-line operator doesn't match + the beginning of the string (presumably because it's not the + beginning of a line). + If not set, then the beginning-of-line operator does match the + beginning of the string. */ +#define REG_NOTBOL 1 + +/* Like REG_NOTBOL, except for the end-of-line. */ +#define REG_NOTEOL (1 << 1) + + +/* If any error codes are removed, changed, or added, update the + `re_error_msg' table in regex.c. */ +typedef enum +{ +#ifdef _XOPEN_SOURCE + REG_ENOSYS = -1, /* This will never happen for this implementation. */ +#endif + + REG_NOERROR = 0, /* Success. */ + REG_NOMATCH, /* Didn't find a match (for regexec). */ + + /* POSIX regcomp return error codes. (In the order listed in the + standard.) */ + REG_BADPAT, /* Invalid pattern. */ + REG_ECOLLATE, /* Not implemented. */ + REG_ECTYPE, /* Invalid character class name. */ + REG_EESCAPE, /* Trailing backslash. */ + REG_ESUBREG, /* Invalid back reference. */ + REG_EBRACK, /* Unmatched left bracket. */ + REG_EPAREN, /* Parenthesis imbalance. */ + REG_EBRACE, /* Unmatched \{. */ + REG_BADBR, /* Invalid contents of \{\}. */ + REG_ERANGE, /* Invalid range end. */ + REG_ESPACE, /* Ran out of memory. */ + REG_BADRPT, /* No preceding re for repetition op. */ + + /* Error codes we've added. */ + REG_EEND, /* Premature end. */ + REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */ + REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */ +} reg_errcode_t; + +/* This data structure represents a compiled pattern. Before calling + the pattern compiler, the fields `buffer', `allocated', `fastmap', + `translate', and `no_sub' can be set. After the pattern has been + compiled, the `re_nsub' field is available. All other fields are + private to the regex routines. */ + +#ifndef RE_TRANSLATE_TYPE +# define RE_TRANSLATE_TYPE char * +#endif + +struct re_pattern_buffer +{ +/* [[[begin pattern_buffer]]] */ + /* Space that holds the compiled pattern. It is declared as + `unsigned char *' because its elements are + sometimes used as array indexes. */ + unsigned char *buffer; + + /* Number of bytes to which `buffer' points. */ + unsigned long int allocated; + + /* Number of bytes actually used in `buffer'. */ + unsigned long int used; + + /* Syntax setting with which the pattern was compiled. */ + reg_syntax_t syntax; + + /* Pointer to a fastmap, if any, otherwise zero. re_search uses + the fastmap, if there is one, to skip over impossible + starting points for matches. */ + char *fastmap; + + /* Either a translate table to apply to all characters before + comparing them, or zero for no translation. The translation + is applied to a pattern when it is compiled and to a string + when it is matched. */ + RE_TRANSLATE_TYPE translate; + + /* Number of subexpressions found by the compiler. */ + size_t re_nsub; + + /* Zero if this pattern cannot match the empty string, one else. + Well, in truth it's used only in `re_search_2', to see + whether or not we should use the fastmap, so we don't set + this absolutely perfectly; see `re_compile_fastmap' (the + `duplicate' case). */ + unsigned can_be_null : 1; + + /* If REGS_UNALLOCATED, allocate space in the `regs' structure + for `max (RE_NREGS, re_nsub + 1)' groups. + If REGS_REALLOCATE, reallocate space if necessary. + If REGS_FIXED, use what's there. */ +#define REGS_UNALLOCATED 0 +#define REGS_REALLOCATE 1 +#define REGS_FIXED 2 + unsigned regs_allocated : 2; + + /* Set to zero when `regex_compile' compiles a pattern; set to one + by `re_compile_fastmap' if it updates the fastmap. */ + unsigned fastmap_accurate : 1; + + /* If set, `re_match_2' does not return information about + subexpressions. */ + unsigned no_sub : 1; + + /* If set, a beginning-of-line anchor doesn't match at the + beginning of the string. */ + unsigned not_bol : 1; + + /* Similarly for an end-of-line anchor. */ + unsigned not_eol : 1; + + /* If true, an anchor at a newline matches. */ + unsigned newline_anchor : 1; + +/* [[[end pattern_buffer]]] */ +}; + +typedef struct re_pattern_buffer regex_t; + +/* Type for byte offsets within the string. POSIX mandates this. */ +typedef int regoff_t; + + +/* This is the structure we store register match data in. See + regex.texinfo for a full description of what registers match. */ +struct re_registers +{ + unsigned num_regs; + regoff_t *start; + regoff_t *end; +}; + + +/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer, + `re_match_2' returns information about at least this many registers + the first time a `regs' structure is passed. */ +#ifndef RE_NREGS +# define RE_NREGS 30 +#endif + + +/* POSIX specification for registers. Aside from the different names than + `re_registers', POSIX uses an array of structures, instead of a + structure of arrays. */ +typedef struct +{ + regoff_t rm_so; /* Byte offset from string's start to substring's start. */ + regoff_t rm_eo; /* Byte offset from string's start to substring's end. */ +} regmatch_t; + +/* Declarations for routines. */ + +/* To avoid duplicating every routine declaration -- once with a + prototype (if we are ANSI), and once without (if we aren't) -- we + use the following macro to declare argument types. This + unfortunately clutters up the declarations a bit, but I think it's + worth it. */ + +#if __STDC__ + +# define _RE_ARGS(args) args + +#else /* not __STDC__ */ + +# define _RE_ARGS(args) () + +#endif /* not __STDC__ */ + +/* Sets the current default syntax to SYNTAX, and return the old syntax. + You can also simply assign to the `re_syntax_options' variable. */ +extern reg_syntax_t __re_set_syntax _RE_ARGS ((reg_syntax_t syntax)); +extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax)); + +/* Compile the regular expression PATTERN, with length LENGTH + and syntax given by the global `re_syntax_options', into the buffer + BUFFER. Return NULL if successful, and an error string if not. */ +extern const char *__re_compile_pattern + _RE_ARGS ((const char *pattern, size_t length, + struct re_pattern_buffer *buffer)); +extern const char *re_compile_pattern + _RE_ARGS ((const char *pattern, size_t length, + struct re_pattern_buffer *buffer)); + + +/* Compile a fastmap for the compiled pattern in BUFFER; used to + accelerate searches. Return 0 if successful and -2 if was an + internal error. */ +extern int __re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer)); +extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer)); + + +/* Search in the string STRING (with length LENGTH) for the pattern + compiled into BUFFER. Start searching at position START, for RANGE + characters. Return the starting position of the match, -1 for no + match, or -2 for an internal error. Also return register + information in REGS (if REGS and BUFFER->no_sub are nonzero). */ +extern int __re_search + _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, + int length, int start, int range, struct re_registers *regs)); +extern int re_search + _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, + int length, int start, int range, struct re_registers *regs)); + + +/* Like `re_search', but search in the concatenation of STRING1 and + STRING2. Also, stop searching at index START + STOP. */ +extern int __re_search_2 + _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, + int length1, const char *string2, int length2, + int start, int range, struct re_registers *regs, int stop)); +extern int re_search_2 + _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, + int length1, const char *string2, int length2, + int start, int range, struct re_registers *regs, int stop)); + + +/* Like `re_search', but return how many characters in STRING the regexp + in BUFFER matched, starting at position START. */ +extern int __re_match + _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, + int length, int start, struct re_registers *regs)); +extern int re_match + _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, + int length, int start, struct re_registers *regs)); + + +/* Relates to `re_match' as `re_search_2' relates to `re_search'. */ +extern int __re_match_2 + _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, + int length1, const char *string2, int length2, + int start, struct re_registers *regs, int stop)); +extern int re_match_2 + _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, + int length1, const char *string2, int length2, + int start, struct re_registers *regs, int stop)); + + +/* Set REGS to hold NUM_REGS registers, storing them in STARTS and + ENDS. Subsequent matches using BUFFER and REGS will use this memory + for recording register information. STARTS and ENDS must be + allocated with malloc, and must each be at least `NUM_REGS * sizeof + (regoff_t)' bytes long. + + If NUM_REGS == 0, then subsequent matches should allocate their own + register data. + + Unless this function is called, the first search or match using + PATTERN_BUFFER will allocate its own register data, without + freeing the old data. */ +extern void __re_set_registers + _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs, + unsigned num_regs, regoff_t *starts, regoff_t *ends)); +extern void re_set_registers + _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs, + unsigned num_regs, regoff_t *starts, regoff_t *ends)); + +#ifdef _REGEX_RE_COMP +# ifndef _CRAY +/* 4.2 bsd compatibility. */ +extern char *re_comp _RE_ARGS ((const char *)); +extern int re_exec _RE_ARGS ((const char *)); +# endif +#endif + +/* POSIX compatibility. */ +extern int __regcomp _RE_ARGS ((regex_t *__preg, const char *__pattern, + int __cflags)); +extern int regcomp _RE_ARGS ((regex_t *__preg, const char *__pattern, + int __cflags)); + +extern int __regexec _RE_ARGS ((const regex_t *__preg, + const char *__string, size_t __nmatch, + regmatch_t __pmatch[], int __eflags)); +extern int regexec _RE_ARGS ((const regex_t *__preg, + const char *__string, size_t __nmatch, + regmatch_t __pmatch[], int __eflags)); + +extern size_t __regerror _RE_ARGS ((int __errcode, const regex_t *__preg, + char *__errbuf, size_t __errbuf_size)); +extern size_t regerror _RE_ARGS ((int __errcode, const regex_t *__preg, + char *__errbuf, size_t __errbuf_size)); + +extern void __regfree _RE_ARGS ((regex_t *__preg)); +extern void regfree _RE_ARGS ((regex_t *__preg)); + + +#ifdef __cplusplus +} +#endif /* C++ */ + +#endif /* regex.h */ + +/* +Local variables: +make-backup-files: t +version-control: t +trim-versions-without-asking: nil +End: +*/ diff --git a/reactos/lib/kjs/src/rentrant.h b/reactos/lib/kjs/src/rentrant.h new file mode 100644 index 00000000000..23c31e9ae1c --- /dev/null +++ b/reactos/lib/kjs/src/rentrant.h @@ -0,0 +1,52 @@ +/* + * Definitions for functions that must be re-implement to guarantee + * the re-entrancy of the interpreter. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/rentrant.h,v $ + * $Id: rentrant.h,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#ifndef RENTRANT_H +#define RENTRANT_H + +/* Time. */ + +void js_localtime (const time_t *clock, struct tm *result); + +void js_gmtime (const time_t *clock, struct tm *result); + +void js_asctime (const struct tm *tm, char *buffer, int buffer_length); + +/* Drand48. */ + +void *js_drand48_create (JSVirtualMachine *vm); + +void js_drand48_destroy (void *drand48_context); + +void js_srand48 (void *drand48_context, long seed); + +void js_drand48 (void *drand48_context, double *random_return); + +#endif /* not RENTRANT_H */ diff --git a/reactos/lib/kjs/src/utils.c b/reactos/lib/kjs/src/utils.c new file mode 100644 index 00000000000..da3d5d71ca9 --- /dev/null +++ b/reactos/lib/kjs/src/utils.c @@ -0,0 +1,439 @@ +/* + * General utilites. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/utils.c,v $ + * $Id: utils.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" + +/* + * Global variables. + */ + +unsigned char js_latin1_tolower[256] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0x61, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xd7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +unsigned char js_latin1_toupper[256] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xe6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xf7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xff, +}; + + +/* + * Global functions. + */ + +void +js_vm_to_primitive (JSVirtualMachine *vm, const JSNode *n, + JSNode *result_return, JSNodeType preferred_type) +{ + JSNode args; + + switch (n->type) + { + case JS_UNDEFINED: + case JS_NULL: + case JS_BOOLEAN: + case JS_INTEGER: + case JS_FLOAT: + case JS_NAN: + case JS_STRING: + JS_COPY (result_return, n); + break; + + case JS_OBJECT: + if (preferred_type == JS_STRING) + { + if (js_vm_call_method (vm, (JSNode *) n, "toString", 0, &args) + && JS_IS_PRIMITIVE_VALUE (&vm->exec_result)) + JS_COPY (result_return, &vm->exec_result); + else if (js_vm_call_method (vm, (JSNode *) n, "valueOf", 0, &args) + && JS_IS_PRIMITIVE_VALUE (&vm->exec_result)) + JS_COPY (result_return, &vm->exec_result); + else + { + sprintf (vm->error, "ToPrimitive(): couldn't convert"); + js_vm_error (vm); + } + } + else + { + /* It must be, or it defaults to NUMBER. */ + if (js_vm_call_method (vm, (JSNode *) n, "valueOf", 0, &args) + && JS_IS_PRIMITIVE_VALUE (&vm->exec_result)) + JS_COPY (result_return, &vm->exec_result); + else + js_vm_to_string (vm, n, result_return); + } + break; + + case JS_BUILTIN: + /* XXX ToPrimitive() for built-ins. */ + sprintf (vm->error, "ToPrimitive(): not implemented yet for built-ins"); + js_vm_error (vm); + break; + + case JS_ARRAY: + case JS_SYMBOL: + case JS_FUNC: + case JS_IPTR: + default: + sprintf (vm->error, "ToPrimitive(): couldn't convert (%d)", n->type); + js_vm_error (vm); + break; + } +} + + +void +js_vm_to_string (JSVirtualMachine *vm, const JSNode *n, JSNode *result_return) +{ + const char *tostring; + JSNode args; + JSNode *nnoconst = (JSNode *) n; /* toString methods behave `constantly' + so no panic here. */ + + /* Create empty arguments. */ + args.type = JS_INTEGER; + args.u.vinteger = 0; + + switch (n->type) + { + case JS_UNDEFINED: + tostring = "undefined"; + break; + + case JS_NULL: + tostring = "null"; + break; + + case JS_BOOLEAN: + case JS_INTEGER: + case JS_FLOAT: + case JS_NAN: + case JS_STRING: + case JS_ARRAY: + (void) (*vm->prim[n->type]->method_proc) (vm, vm->prim[n->type], + nnoconst, vm->syms.s_toString, + result_return, &args); + return; + break; + + case JS_OBJECT: + /* Try to call object's toString() method. */ + if (js_vm_call_method (vm, (JSNode *) n, "toString", 0, &args) + && vm->exec_result.type == JS_STRING) + { + JS_COPY (result_return, &vm->exec_result); + return; + } + + /* No match. */ + tostring = "object"; + break; + + case JS_SYMBOL: + tostring = js_vm_symname (vm, n->u.vsymbol); + break; + + case JS_BUILTIN: + if (n->u.vbuiltin->info->method_proc) + if ((*n->u.vbuiltin->info->method_proc) ( + vm, + n->u.vbuiltin->info, + n->u.vbuiltin->instance_context, + vm->syms.s_toString, result_return, + &args) + == JS_PROPERTY_FOUND) + return; + + /* Builtin didn't answer toString(). Let's use our default. */ + tostring = "builtin"; + break; + + case JS_FUNC: + tostring = "function"; + break; + + case JS_IPTR: + tostring = "pointer"; + break; + + default: + tostring = "??? unknown type in js_vm_to_string() ???"; + break; + } + + js_vm_make_static_string (vm, result_return, tostring, strlen (tostring)); +} + + +void +js_vm_to_number (JSVirtualMachine *vm, const JSNode *n, JSNode *result_return) +{ + char *cp, *end; + + switch (n->type) + { + case JS_UNDEFINED: + result_return->type = JS_NAN; + break; + + case JS_NULL: + result_return->type = JS_INTEGER; + result_return->u.vinteger = 0; + break; + + case JS_BOOLEAN: + result_return->type = JS_INTEGER; + result_return->u.vinteger = n->u.vboolean ? 1 : 0; + break; + + case JS_INTEGER: + case JS_FLOAT: + case JS_NAN: + JS_COPY (result_return, n); + break; + + case JS_STRING: + cp = js_string_to_c_string (vm, n); + result_return->u.vinteger = strtol (cp, &end, 10); + + if (cp == end) + { + int i; + + /* It failed. Check the `Infinity'. */ + + for (i = 0; cp[i] && JS_IS_STR_WHITE_SPACE_CHAR (cp[i]); i++) + ; + + if (cp[i] && memcmp (cp + i, "Infinity", 8) == 0) + JS_MAKE_POSITIVE_INFINITY (result_return); + else + result_return->type = JS_NAN; + } + else + { + if (*end == '.' || *end == 'e' || *end == 'E') + { + /* It is a float number. */ + result_return->u.vfloat = strtod (cp, &end); + if (cp == end) + /* Couldn't parse. */ + result_return->type = JS_NAN; + else + /* Success. */ + result_return->type = JS_FLOAT; + } + else + { + /* It is an integer. */ + result_return->type = JS_INTEGER; + } + } + + js_free (cp); + break; + + case JS_ARRAY: + case JS_OBJECT: + case JS_BUILTIN: + /* XXX Not implemented yet. */ + result_return->type = JS_NAN; + break; + + case JS_SYMBOL: + case JS_FUNC: + case JS_IPTR: + default: + result_return->type = JS_NAN; + break; + } +} + + +void +js_vm_to_object (JSVirtualMachine *vm, const JSNode *n, JSNode *result_return) +{ + switch (n->type) + { + case JS_BOOLEAN: + case JS_INTEGER: + case JS_FLOAT: + case JS_NAN: + case JS_OBJECT: + JS_COPY (result_return, n); + break; + + case JS_STRING: + js_vm_make_string (vm, result_return, n->u.vstring->data, + n->u.vstring->len); + break; + + case JS_UNDEFINED: + case JS_NULL: + default: + sprintf (vm->error, "ToObject(): illegal argument"); + js_vm_error (vm); + break; + } +} + + +JSInt32 +js_vm_to_int32 (JSVirtualMachine *vm, JSNode *n) +{ + JSNode intermediate; + JSInt32 result; + + js_vm_to_number (vm, n, &intermediate); + + switch (intermediate.type) + { + case JS_INTEGER: + result = (JSInt32) intermediate.u.vinteger; + break; + + case JS_FLOAT: + if (JS_IS_POSITIVE_INFINITY (&intermediate) + || JS_IS_NEGATIVE_INFINITY (&intermediate)) + result = 0; + else + result = (JSInt32) intermediate.u.vfloat; + break; + + case JS_NAN: + default: + result = 0; + break; + } + + return result; +} + + +int +js_vm_to_boolean (JSVirtualMachine *vm, JSNode *n) +{ + int result; + + switch (n->type) + { + case JS_BOOLEAN: + result = n->u.vboolean; + break; + + case JS_INTEGER: + result = n->u.vinteger != 0; + break; + + case JS_FLOAT: + result = n->u.vfloat != 0; + break; + + case JS_STRING: + result = n->u.vstring->len > 0; + break; + + case JS_OBJECT: + result = 1; + break; + + case JS_UNDEFINED: + case JS_NULL: + case JS_NAN: + default: + result = 0; + break; + } + + return result; +} diff --git a/reactos/lib/kjs/src/vm.c b/reactos/lib/kjs/src/vm.c new file mode 100644 index 00000000000..be01d579da8 --- /dev/null +++ b/reactos/lib/kjs/src/vm.c @@ -0,0 +1,968 @@ +/* + * Common parts for the JavaScript virtual machine. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/vm.c,v $ + * $Id: vm.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" + +/* + * Types and definitions. + */ + +/* + * Collect garbage if we allocated more than GC_TRIGGER bytes of + * memory since the last gc. + */ +#if SIZEOF_INT == 2 +#define GC_TRIGGER (1L * 1024L * 1024L) +#else +#define GC_TRIGGER (2 * 1024 * 1024) +#endif + +/* + * Prototypes for static functions. + */ + +static void intern_builtins (JSVirtualMachine *vm); + + +/* + * Global functions. + */ + +JSVirtualMachine * +js_vm_create (unsigned int stack_size, JSVMDispatchMethod dispatch_method, + unsigned int verbose, int stacktrace_on_error, + JSIOStream *s_stdin, JSIOStream *s_stdout, JSIOStream *s_stderr) +{ + JSVirtualMachine *vm; + + vm = js_calloc (NULL, 1, sizeof (*vm)); + if (vm == NULL) + return NULL; + + vm->verbose = verbose; + vm->stacktrace_on_error = stacktrace_on_error; + vm->warn_undef = 1; + + /* Set the system streams. */ + vm->s_stdin = s_stdin; + vm->s_stdout = s_stdout; + vm->s_stderr = s_stderr; + + /* Resolve the dispatch method. */ + switch (dispatch_method) + { + case JS_VM_DISPATCH_SWITCH_BASIC: +#if ALL_DISPATCHERS + vm->dispatch_method = dispatch_method; + vm->dispatch_method_name = "switch-basic"; + vm->dispatch_execute = js_vm_switch0_exec; + vm->dispatch_func_name = js_vm_switch0_func_name; + vm->dispatch_debug_position = js_vm_switch0_debug_position; +#endif + break; + + case JS_VM_DISPATCH_JUMPS: +#if __GNUC__ && !DISABLE_JUMPS + vm->dispatch_method = dispatch_method; + vm->dispatch_method_name = "jumps"; + vm->dispatch_execute = js_vm_jumps_exec; + vm->dispatch_func_name = js_vm_jumps_func_name; + vm->dispatch_debug_position = js_vm_jumps_debug_position; +#endif /* not (__GNUC__ && !DISABLE_JUMPS) */ + break; + + case JS_VM_DISPATCH_SWITCH: + /* This is the default, let the default catcher handle us. */ + break; + } + + if (vm->dispatch_execute == NULL) + { + /* Set the default that is the optimized switch. */ + vm->dispatch_method = JS_VM_DISPATCH_SWITCH; + vm->dispatch_method_name = "switch"; + vm->dispatch_execute = js_vm_switch_exec; + vm->dispatch_func_name = js_vm_switch_func_name; + vm->dispatch_debug_position = js_vm_switch_debug_position; + } + + vm->stack_size = stack_size; + vm->stack = js_malloc (NULL, vm->stack_size * sizeof (*vm->stack)); + if (vm->stack == NULL) + { + js_free (vm); + return NULL; + } + + /* Set the initial stack pointer. */ + vm->sp = vm->stack + vm->stack_size - 1; + + vm->gc.trigger = GC_TRIGGER; + + /* We need a toplevel here. */ + { + JSErrorHandlerFrame handler; + int result = 1; + + memset (&handler, 0, sizeof (handler)); + handler.next = vm->error_handler; + vm->error_handler = &handler; + + if (setjmp (vm->error_handler->error_jmp)) + /* An error occurred. */ + result = 0; + else + { + /* Intern some commonly used symbols. */ + vm->syms.s___proto__ = js_vm_intern (vm, "__proto__"); + vm->syms.s_prototype = js_vm_intern (vm, "prototype"); + vm->syms.s_toSource = js_vm_intern (vm, "toSource"); + vm->syms.s_toString = js_vm_intern (vm, "toString"); + vm->syms.s_valueOf = js_vm_intern (vm, "valueOf"); + + /* Intern system built-in objects. */ + intern_builtins (vm); + } + + /* Pop the error handler. */ + vm->error_handler = vm->error_handler->next; + + if (result == 0) + { + /* Argh, the initialization failed. */ + js_vm_destroy (vm); + return NULL; + } + } + + return vm; +} + + +void +js_vm_destroy (JSVirtualMachine *vm) +{ + int i; + JSHeapBlock *hb, *hb2; + JSErrorHandlerFrame *f, *f2; + JSHashBucket *hashb, *hashb_next; + + /* Free all objects from the heap. */ + js_vm_clear_heap (vm); + + /* Free the constants. */ + + for (i = 0; i < vm->num_consts; i++) + if (vm->consts[i].type == JS_STRING) + js_free (vm->consts[i].u.vstring->data); + js_free (vm->consts); + + /* Free the globals. */ + + for (i = 0; i < JS_HASH_TABLE_SIZE; i++) + for (hashb = vm->globals_hash[i]; hashb; hashb = hashb_next) + { + hashb_next = hashb->next; + js_free (hashb->name); + js_free (hashb); + } + js_free (vm->globals); + + /* Stack. */ + js_free (vm->stack); + + /* Heap blocks. */ + for (hb = vm->heap; hb; hb = hb2) + { + hb2 = hb->next; + js_free (hb); + } + + /* Error handlers. */ + for (f = vm->error_handler; f; f = f2) + { + f2 = f->next; + js_free (f); + } + +#if PROFILING +#define NUM_OPS 68 + + /* Dump profiling data to the stderr. */ + { + unsigned int total = 0; + int i; + + /* Count total interrupts. */ + for (i = 0; i <= NUM_OPS; i++) + total += vm->prof_count[i]; + + /* Dump individual statistics. */ + for (i = 0; i <= NUM_OPS; i++) + { + char buf[512]; + + sprintf (buf, "%d\t%u\t%.2f%s", + i, vm->prof_count[i], + (double) vm->prof_count[i] / total * 100, + JS_HOST_LINE_BREAK); + + js_iostream_write (vm->s_stderr); + } + } +#endif /* PROFILING */ + + /* Flush and free the default system streams. */ + + js_iostream_close (vm->s_stdin); + js_iostream_close (vm->s_stdout); + js_iostream_close (vm->s_stderr); + + /* And finally, the VM handle. */ + js_free (vm); +} + +#if PROFILING +/* + * The support stuffs for the byte-code operand profiling. + */ + +static JSVirtualMachine *profiling_vm = NULL; + +static void +sig_alarm (int sig) +{ + if (profiling_vm && profiling_vm->prof_op < 100) + profiling_vm->prof_count[profiling_vm->prof_op]++; + + signal (sig, sig_alarm); +} + +/* Turn on the byte-code operand profiling. */ +#define PROFILING_ON() \ + profiling_vm = vm; \ + vm->prof_op = 255; \ + signal (SIGALRM, sig_alarm); \ + ualarm (1, 1) + +/* Turn off the byte-code operand profiling. */ +#define PROFILING_OFF() \ + vm->prof_op = 255; \ + ualarm (0, 0); \ + signal (SIGALRM, SIG_IGN); \ + profiling_vm = NULL + +#else /* not PROFILING */ + +#define PROFILING_ON() +#define PROFILING_OFF() + +#endif /* not PROFILING */ + +int +js_vm_execute (JSVirtualMachine *vm, JSByteCode *bc) +{ + int i, sect; + unsigned int ui; + unsigned char *cp; + unsigned int consts_offset; + char buf[256]; + JSSymtabEntry *symtab = NULL; + unsigned int num_symtab_entries = 0; + unsigned int code_len = 0; + JSNode *saved_sp; + JSErrorHandlerFrame *handler, *saved_handler; + int result = 1; + unsigned char *debug_info; + unsigned int debug_info_len; + unsigned int anonymous_function_offset; + + /* We need a toplevel over the whole function. */ + + saved_sp = vm->sp; + saved_handler = vm->error_handler; + + handler = js_calloc (NULL, 1, sizeof (*handler)); + if (handler == NULL) + { + sprintf (vm->error, "VM: out of memory"); + return 0; + } + handler->next = vm->error_handler; + vm->error_handler = handler; + + if (setjmp (vm->error_handler->error_jmp)) + { + /* Ok, we had an error down there somewhere. */ + result = 0; + } + else + { + /* The main stuffs for the execute. */ + + /* Process constants. */ + consts_offset = vm->num_consts; + anonymous_function_offset = vm->anonymous_function_next_id; + + for (sect = 0; sect < bc->num_sects; sect++) + if (bc->sects[sect].type == JS_BCST_CONSTANTS) + { + cp = bc->sects[sect].data; + + for (ui = 0; ui < bc->sects[sect].length;) + { + JSNode *c; + + /* Check that we still have space for this constant. */ + if (vm->num_consts >= vm->consts_alloc) + { + vm->consts = js_realloc (vm, vm->consts, + (vm->consts_alloc + 1024) + * sizeof (JSNode)); + vm->consts_alloc += 1024; + } + c = &vm->consts[vm->num_consts++]; + + /* Process this constant. */ + c->type = (JSNodeType) cp[ui++]; + switch (c->type) + { + case JS_NULL: + break; + + case JS_BOOLEAN: + c->u.vboolean = cp[ui++]; + break; + + case JS_STRING: + c->u.vstring = js_vm_alloc (vm, sizeof (*c->u.vstring)); + c->u.vstring->staticp = 1; + c->u.vstring->prototype = NULL; + + JS_BC_READ_INT32 (cp + ui, c->u.vstring->len); + ui += 4; + + c->u.vstring->data = js_malloc (vm, c->u.vstring->len + 1); + memcpy (c->u.vstring->data, cp + ui, c->u.vstring->len); + c->u.vstring->data[c->u.vstring->len] = '\0'; + + ui += c->u.vstring->len; + break; + + case JS_INTEGER: + JS_BC_READ_INT32 (cp + ui, c->u.vinteger); + ui += 4; + break; + + case JS_FLOAT: + memcpy (&c->u.vfloat, cp + ui, 8); + ui += 8; + break; + + case JS_SYMBOL: + for (i = 0; cp[ui]; ui++, i++) + buf[i] = cp[ui]; + buf[i] = '\0'; + + /* Eat the trailing '\0' from the data. */ + ui++; + + if (buf[0] == '.' && buf[1] == 'F' && buf[2] == ':') + sprintf (buf + 3, "%u", + vm->anonymous_function_next_id++); + + /* Intern symbol. */ + c->u.vsymbol = js_vm_intern (vm, buf); + break; + + case JS_BUILTIN: + /* Regular expression. */ + { + unsigned char flags; + unsigned int length; + + flags = cp[ui++]; + + JS_BC_READ_INT32 (cp + ui, length); + ui += 4; + + js_builtin_RegExp_new (vm, cp + ui, length, flags, 1, + NULL, c); + ui += length; + } + break; + + case JS_NAN: + /* Nothing here. */ + break; + + default: + case JS_IPTR: + sprintf (buf, + "js_vm_execute(): unknown constant type %d%s", + c->type, + JS_HOST_LINE_BREAK); + + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); + + abort (); + break; + } + } + + /* All done with the constants. */ + break; + } + + /* Check how long the code section is. */ + for (sect = 0; sect < bc->num_sects; sect++) + if (bc->sects[sect].type == JS_BCST_CODE) + { + code_len = bc->sects[sect].length; + break; + } + + /* Process symbol table. */ + for (sect = 0; sect < bc->num_sects; sect++) + if (bc->sects[sect].type == JS_BCST_SYMTAB) + { + JSSymtabEntry *se; + char buf[257]; + + cp = bc->sects[sect].data; + + /* The number of symbols. */ + JS_BC_READ_INT32 (cp, num_symtab_entries); + + symtab = js_calloc (vm, num_symtab_entries + 1, sizeof (*symtab)); + + /* Make the terminator by hand. */ + symtab[num_symtab_entries].offset = code_len; + + /* Enter symbols. */ + se = symtab; + for (ui = 4; ui < bc->sects[sect].length; se++) + { + for (i = 0; cp[ui]; ui++, i++) + buf[i] = cp[ui]; + buf[i] = '\0'; + + se->name = js_strdup (vm, buf); + ui++; + + JS_BC_READ_INT32 (cp + ui, se->offset); + ui += 4; + } + break; + } + + /* Check if we have debugging information. */ + debug_info = NULL; + debug_info_len = 0; + for (sect = 0; sect < bc->num_sects; sect++) + if (bc->sects[sect].type == JS_BCST_DEBUG) + { + debug_info = bc->sects[sect].data; + debug_info_len = bc->sects[sect].length; + } + + /* Clear error message and old exec result. */ + vm->error[0] = '\0'; + vm->exec_result.type = JS_UNDEFINED; + + PROFILING_ON (); + + /* Execute. */ + result = (*vm->dispatch_execute) (vm, bc, symtab, num_symtab_entries, + consts_offset, + anonymous_function_offset, + debug_info, debug_info_len, + NULL, NULL, 0, NULL); + } + + PROFILING_OFF (); + + if (symtab) + { + for (ui = 0; ui < num_symtab_entries; ui++) + js_free (symtab[ui].name); + js_free (symtab); + } + + /* Pop all error handler frames from the handler chain. */ + for (; vm->error_handler != saved_handler; vm->error_handler = handler) + { + handler = vm->error_handler->next; + js_free (vm->error_handler); + } + + /* Restore virtual machine's idea about the stack top. */ + vm->sp = saved_sp; + + return result; +} + + +int +js_vm_apply (JSVirtualMachine *vm, char *func_name, JSNode *func, + unsigned int argc, JSNode *argv) +{ + int result = 1; + JSNode *saved_sp; + JSErrorHandlerFrame *handler, *saved_handler; + + /* Initialize error handler. */ + + saved_sp = vm->sp; + saved_handler = vm->error_handler; + + handler = js_calloc (NULL, 1, sizeof (*handler)); + if (handler == NULL) + { + sprintf (vm->error, "VM: out of memory"); + return 0; + } + handler->next = vm->error_handler; + vm->error_handler = handler; + + if (setjmp (vm->error_handler->error_jmp)) + { + /* An error occurred. */ + result = 0; + } + else + { + /* Clear error message and old exec result. */ + vm->error[0] = '\0'; + vm->exec_result.type = JS_UNDEFINED; + + if (func_name) + /* Lookup the function. */ + func = &vm->globals[js_vm_intern (vm, func_name)]; + + /* Check what kind of function should be called. */ + if (func->type == JS_FUNC) + { + PROFILING_ON (); + + /* Call function. */ + result = (*vm->dispatch_execute) (vm, NULL, NULL, 0, 0, 0, + NULL, 0, + NULL, func, argc, argv); + } + else if (func->type == JS_BUILTIN + && func->u.vbuiltin->info->global_method_proc != NULL) + { + (*func->u.vbuiltin->info->global_method_proc) ( + vm, + func->u.vbuiltin->info, + func->u.vbuiltin->instance_context, + &vm->exec_result, + argv); + } + else + { + if (func_name) + sprintf (vm->error, "undefined function `%s' in apply", + func_name); + else + sprintf (vm->error, "undefiend function in apply"); + + result = 0; + } + } + + PROFILING_OFF (); + + /* Pop all error handler frames from the handler chain. */ + for (; vm->error_handler != saved_handler; vm->error_handler = handler) + { + handler = vm->error_handler->next; + js_free (vm->error_handler); + } + + /* Restore virtual machine's idea about the stack top. */ + vm->sp = saved_sp; + + return result; +} + + +int +js_vm_call_method (JSVirtualMachine *vm, JSNode *object, + const char *method_name, unsigned int argc, JSNode *argv) +{ + int result = 1; + JSNode *saved_sp; + JSErrorHandlerFrame *handler, *saved_handler; + JSSymbol symbol; + + /* Initialize error handler. */ + + saved_sp = vm->sp; + saved_handler = vm->error_handler; + + handler = js_calloc (NULL, 1, sizeof (*handler)); + if (handler == NULL) + { + sprintf (vm->error, "VM: out of memory"); + return 0; + } + handler->next = vm->error_handler; + vm->error_handler = handler; + + if (setjmp (vm->error_handler->error_jmp)) + { + /* An error occurred. */ + result = 0; + } + else + { + /* Intern the method name. */ + symbol = js_vm_intern (vm, method_name); + + /* Clear error message and old exec result. */ + vm->error[0] = '\0'; + vm->exec_result.type = JS_UNDEFINED; + + /* What kind of object was called? */ + + if (object->type == JS_BUILTIN) + { + if (object->u.vbuiltin->info->method_proc) + { + if ((*object->u.vbuiltin->info->method_proc) ( + vm, + object->u.vbuiltin->info, + object->u.vbuiltin->instance_context, + symbol, + &vm->exec_result, argv) + == JS_PROPERTY_UNKNOWN) + { + sprintf (vm->error, "call_method: unknown method"); + result = 0; + } + } + else + { + sprintf (vm->error, "illegal builtin object for call_method"); + result = 0; + } + } + else if (object->type == JS_OBJECT) + { + JSNode method; + + /* Fetch the method's implementation. */ + if (js_vm_object_load_property (vm, object->u.vobject, symbol, + &method) + == JS_PROPERTY_FOUND) + { + /* The property has been defined in the object. */ + if (method.type != JS_FUNC) + { + sprintf (vm->error, "call_method: unknown method"); + result = 0; + } + else + { + PROFILING_ON (); + result = (*vm->dispatch_execute) (vm, NULL, NULL, 0, 0, 0, + NULL, 0, + object, &method, argc, + argv); + } + } + else + /* Let the built-in Object handle this. */ + goto to_builtin_please; + } + else if (vm->prim[object->type]) + { + /* The primitive language types. */ + to_builtin_please: + if ((*vm->prim[object->type]->method_proc) (vm, + vm->prim[object->type], + object, symbol, + &vm->exec_result, + argv) + == JS_PROPERTY_UNKNOWN) + { + sprintf (vm->error, "call_method: unknown method"); + result = 0; + } + } + else + { + sprintf (vm->error, "illegal object for call_method"); + result = 0; + } + } + + PROFILING_OFF (); + + /* Pop all error handler frames from the handler chain. */ + for (; vm->error_handler != saved_handler; vm->error_handler = handler) + { + handler = vm->error_handler->next; + js_free (vm->error_handler); + } + + /* Restore virtual machine's idea about the stack top. */ + vm->sp = saved_sp; + + return result; +} + + +const char * +js_vm_func_name (JSVirtualMachine *vm, void *pc) +{ + return (*vm->dispatch_func_name) (vm, pc); +} + + +const char * +js_vm_debug_position (JSVirtualMachine *vm, unsigned int *linenum_return) +{ + return (*vm->dispatch_debug_position) (vm, linenum_return); +} + + +unsigned int +js_vm_intern_with_len (JSVirtualMachine *vm, const char *name, + unsigned int len) +{ + JSHashBucket *b; + unsigned int pos = js_count_hash (name, len) % JS_HASH_TABLE_SIZE; + + for (b = vm->globals_hash[pos]; b; b = b->next) + if (strcmp (b->name, name) == 0) + return b->u.ui; + + b = js_malloc (vm, sizeof (*b)); + b->name = js_strdup (vm, name); + + b->next = vm->globals_hash[pos]; + vm->globals_hash[pos] = b; + + /* Alloc space from the globals array. */ + if (vm->num_globals >= vm->globals_alloc) + { + vm->globals = js_realloc (vm, vm->globals, + (vm->globals_alloc + 1024) * sizeof (JSNode)); + vm->globals_alloc += 1024; + } + + /* Initialize symbol's name spaces. */ + vm->globals[vm->num_globals].type = JS_UNDEFINED; + b->u.ui = vm->num_globals++; + + return b->u.ui; +} + + +const char * +js_vm_symname (JSVirtualMachine *vm, JSSymbol sym) +{ + int i; + JSHashBucket *b; + + for (i = 0; i < JS_HASH_TABLE_SIZE; i++) + for (b = vm->globals_hash[i]; b; b = b->next) + if (b->u.ui == sym) + return b->name; + + return "???"; +} + + +void +js_vm_error (JSVirtualMachine *vm) +{ + const char *file; + unsigned int ln; + char error[1024]; + + file = js_vm_debug_position (vm, &ln); + if (file) + { + sprintf (error, "%s:%u: %s", file, ln, vm->error); + strcpy (vm->error, error); + } + + if (vm->stacktrace_on_error) + { + sprintf (error, "VM: error: %s%s", vm->error, + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, error, strlen (error)); + + js_vm_stacktrace (vm, (unsigned int) -1); + } + + if (vm->error_handler->sp) + /* + * We are jumping to a catch-block. Format our error message to + * the `thrown' node. + */ + js_vm_make_string (vm, &vm->error_handler->thrown, + vm->error, strlen (vm->error)); + + longjmp (vm->error_handler->error_jmp, 1); + + /* NOTREACHED (I hope). */ + + sprintf (error, "VM: no valid error handler initialized%s", + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, error, strlen (error)); + js_iostream_flush (vm->s_stderr); + + abort (); +} + +/* Delete proc for garbaged built-in objects. */ +static void +destroy_builtin (void *ptr) +{ + JSBuiltin *bi = ptr; + + if (bi->info->delete_proc) + (*bi->info->delete_proc) (bi->info, bi->instance_context); +} + +/* Delete proc for garbaged built-in info. */ +static void +destroy_builtin_info (void *ptr) +{ + JSBuiltinInfo *i = ptr; + + if (i->obj_context_delete) + (*i->obj_context_delete) (i->obj_context); +} + + +JSBuiltinInfo * +js_vm_builtin_info_create (JSVirtualMachine *vm) +{ + JSNode prototype; + JSBuiltinInfo *i = js_vm_alloc_destroyable (vm, sizeof (*i)); + + i->destroy = destroy_builtin_info; + i->prototype = js_vm_object_new (vm); + + /* + * Set the __proto__ property to null. We have no prototype object + * above us. + */ + prototype.type = JS_NULL; + js_vm_object_store_property (vm, i->prototype, vm->syms.s___proto__, + &prototype); + + return i; +} + + +void +js_vm_builtin_create (JSVirtualMachine *vm, JSNode *result, + JSBuiltinInfo *info, void *instance_context) +{ + result->type = JS_BUILTIN; + result->u.vbuiltin = js_vm_alloc_destroyable (vm, sizeof (JSBuiltin)); + result->u.vbuiltin->destroy = destroy_builtin; + result->u.vbuiltin->info = info; + + if (instance_context) + { + JSNode prototype; + + result->u.vbuiltin->instance_context = instance_context; + result->u.vbuiltin->prototype = js_vm_object_new (vm); + + /* Set the __proto__ chain. */ + + prototype.type = JS_OBJECT; + prototype.u.vobject = info->prototype; + + js_vm_object_store_property (vm, result->u.vbuiltin->prototype, + vm->syms.s___proto__, &prototype); + } +} + + +/* + * Static functions. + */ + +extern void js_builtin_core (JSVirtualMachine *vm); + +extern void js_builtin_Array (JSVirtualMachine *vm); +extern void js_builtin_Boolean (JSVirtualMachine *vm); +extern void js_builtin_Function (JSVirtualMachine *vm); +extern void js_builtin_Number (JSVirtualMachine *vm); +extern void js_builtin_Object (JSVirtualMachine *vm); +extern void js_builtin_String (JSVirtualMachine *vm); + +extern void js_builtin_Date (JSVirtualMachine *vm); +extern void js_builtin_Directory (JSVirtualMachine *vm); +extern void js_builtin_File (JSVirtualMachine *vm); +extern void js_builtin_Math (JSVirtualMachine *vm); +extern void js_builtin_RegExp (JSVirtualMachine *vm); +extern void js_builtin_System (JSVirtualMachine *vm); +extern void js_builtin_VM (JSVirtualMachine *vm); + + +static void +intern_builtins (JSVirtualMachine *vm) +{ + /* + * The initialization order is significant. The RegExp object must be + * initialized before String. + */ + + /* The core global methods. */ + js_builtin_core (vm); + + /* Our builtin extensions. */ + js_builtin_Date (vm); + js_builtin_Directory (vm); + js_builtin_File (vm); + js_builtin_Math (vm); + js_builtin_RegExp (vm); + js_builtin_System (vm); + js_builtin_VM (vm); + + /* Language objects. */ + js_builtin_Array (vm); + js_builtin_Boolean (vm); + js_builtin_Function (vm); + js_builtin_Number (vm); + js_builtin_Object (vm); + js_builtin_String (vm); +} diff --git a/reactos/lib/kjs/src/vmjumps.c b/reactos/lib/kjs/src/vmjumps.c new file mode 100644 index 00000000000..26a5c5b0b14 --- /dev/null +++ b/reactos/lib/kjs/src/vmjumps.c @@ -0,0 +1,583 @@ +/* + * Optimized `jumps' instruction dispatcher. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/vmjumps.c,v $ + * $Id: vmjumps.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" + +#if __GNUC__ && !DISABLE_JUMPS + +/* + * Types and definitions. + */ + +#define SAVE_OP(a) \ +reloc[cp - code_start - 1] = &f->code[cpos]; \ +f->code[cpos++].u.ptr = (a) + +#define SAVE_INT8(a) f->code[cpos++].u.i8 = (a) +#define SAVE_INT16(a) f->code[cpos++].u.i16 = (a) +#define SAVE_INT32(a) f->code[cpos++].u.i32 = (a) + +#define ARG_INT32() f->code[cpos].u.i32 + +#if BC_OPERAND_HOOKS + +#define NEXT() \ + do { \ + if (++vm->hook_operand_count >= vm->hook_operand_count_trigger) \ + { \ + JS_CALL_HOOK (JS_VM_EVENT_OPERAND_COUNT); \ + vm->hook_operand_count = 0; \ + } \ + goto *((pc++)->u.ptr); \ + } while (0) + +#else /* not BC_OPERAND_HOOKS */ + +#define NEXT() goto *((pc++)->u.ptr) + +#endif /* not BC_OPERAND_HOOKS */ + +#define READ_INT8(var) (var) = (pc++)->u.i8 +#define READ_INT16(var) (var) = (pc++)->u.i16 +#define READ_INT32(var) (var) = (pc++)->u.i32 + +#define SETPC(ofs) pc = (ofs) +#define SETPC_RELATIVE(ofs) pc += (ofs) + +#define CALL_USER_FUNC(f) pc = ((Function *) (f))->code + +#define DONE() goto done + +#define ERROR(msg) \ + do { \ + JS_SAVE_REGS (); \ + strcpy (vm->error, (msg)); \ + js_vm_error (vm); \ + /* NOTREACHED */ \ + } while (0) + +#if PROFILING +#define OPERAND(op) vm->prof_op = (op) +#else +#define OPERAND(op) +#endif + +struct compiled_st +{ + union + { + void *ptr; + JSInt8 i8; + JSInt16 i16; + JSInt32 i32; + } u; +}; + +typedef struct compiled_st Compiled; + +/* Debug information. */ +struct debug_info_st +{ + void *pc; + unsigned int linenum; +}; + +typedef struct debug_info_st DebugInfo; + +struct function_st +{ + JSHeapDestroyableCB destroy; + + char *name; + Compiled *code; + unsigned int length; + + struct + { + char *file; + unsigned int num_info; + DebugInfo *info; + } debug; +}; + +typedef struct function_st Function; + +/* + * Static functions. + */ + +static void +function_destroy (void *ptr) +{ + Function *f = ptr; + int i; + + /* Name. */ + js_free (f->name); + + /* Code. */ + js_free (f->code); + + /* Debug info. */ + if (f->debug.file) + js_free (f->debug.file); + if (f->debug.info) + js_free (f->debug.info); +} + + +#endif /* not (__GNUC__ && !DISABLE_JUMPS) */ + +/* + * Global functions. + */ + +int +js_vm_jumps_exec (JSVirtualMachine *vm, JSByteCode *bc, JSSymtabEntry *symtab, + unsigned int num_symtab_entries, unsigned int consts_offset, + unsigned int anonymous_function_offset, + unsigned char *debug_info, unsigned int debug_info_len, + JSNode *object, JSNode *func, + unsigned int argc, JSNode *argv) +{ +#if __GNUC__ && !DISABLE_JUMPS + int s; + unsigned int ui; + Function *global_f = NULL; + Function *f = NULL; + unsigned char *code = NULL; + JSNode *sp = NULL; + JSNode *fp = NULL; + Compiled *pc = NULL; + char *debug_filename = "unknown"; + char buf[512]; + unsigned int opcount = 0; + + if (bc) + { + /* Executing byte-code. */ + + /* Find the code section. */ + for (s = 0; s < bc->num_sects; s++) + if (bc->sects[s].type == JS_BCST_CODE) + code = bc->sects[s].data; + assert (code != NULL); + + /* Enter all functions to the known functions of the VM. */ + for (s = 0; s < num_symtab_entries; s++) + { + /* We need one function. */ + f = js_vm_alloc_destroyable (vm, sizeof (*f)); + f->destroy = function_destroy; + f->name = js_strdup (vm, symtab[s].name); + + if (strcmp (symtab[s].name, JS_GLOBAL_NAME) == 0) + global_f = f; + else + { + int is_anonymous = 0; + + /* Check for the anonymous function. */ + if (symtab[s].name[0] == '.' && symtab[s].name[1] == 'F' + && symtab[s].name[2] == ':') + is_anonymous = 1; + + if (vm->verbose > 3) + { + sprintf (buf, "VM: link: %s(): start=%d, length=%d", + symtab[s].name, symtab[s].offset, + symtab[s + 1].offset - symtab[s].offset); + if (is_anonymous) + sprintf (buf + strlen (buf), + ", relocating with offset %u", + anonymous_function_offset); + strcat (buf, JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + + if (is_anonymous) + { + sprintf (buf, ".F:%u", + (unsigned int) atoi (symtab[s].name + 3) + + anonymous_function_offset); + ui = js_vm_intern (vm, buf); + } + else + ui = js_vm_intern (vm, symtab[s].name); + + vm->globals[ui].type = JS_FUNC; + vm->globals[ui].u.vfunction = js_vm_make_function (vm, f); + } + + /* Link the code to our environment.*/ + { + unsigned char *cp; + unsigned char *code_start, *code_end; + unsigned char *fixed_code; + JSInt32 i; + unsigned int cpos; + Compiled **reloc; + unsigned int length; + + length = symtab[s + 1].offset - symtab[s].offset + 1; + + /* + * Allocate space for our compiled code. is enought, + * but is is almost always too much. Who cares? + */ + f->code = js_malloc (vm, length * sizeof (Compiled)); + reloc = js_calloc (vm, 1, length * sizeof (Compiled *)); + fixed_code = js_malloc (vm, length); + + memcpy (fixed_code, code + symtab[s].offset, length); + fixed_code[length - 1] = 1; /* op `done'. */ + + code_start = fixed_code; + code_end = code_start + length; + + /* Link phase 1: constants and symbols. */ + cp = code_start; + cpos = 0; + while (cp < code_end) + { + switch (*cp++) + { + /* include c1jumps.h */ +#include "c1jumps.h" + /* end include c1jumps.h */ + } + } + f->length = cpos; + + /* Link phase 2: relative jumps. */ + cp = code_start; + cpos = 0; + while (cp < code_end) + { + switch (*cp++) + { + /* include c2jumps.h */ +#include "c2jumps.h" + /* end include c2jumps.h */ + } + } + + /* Handle debug info. */ + if (debug_info) + { + unsigned int di_start = symtab[s].offset; + unsigned int di_end = symtab[s + 1].offset; + unsigned int ln; + + for (; debug_info_len > 0;) + { + switch (*debug_info) + { + case JS_DI_FILENAME: + debug_info++; + debug_info_len--; + + JS_BC_READ_INT32 (debug_info, ui); + debug_info += 4; + debug_info_len -= 4; + + f->debug.file = js_malloc (vm, ui + 1); + memcpy (f->debug.file, debug_info, ui); + f->debug.file[ui] = '\0'; + + debug_filename = f->debug.file; + + debug_info += ui; + debug_info_len -= ui; + break; + + case JS_DI_LINENUMBER: + JS_BC_READ_INT32 (debug_info + 1, ui); + if (ui > di_end) + goto debug_info_done; + + /* This belongs to us (maybe). */ + debug_info += 5; + debug_info_len -= 5; + + JS_BC_READ_INT32 (debug_info, ln); + debug_info += 4; + debug_info_len -= 4; + + if (di_start <= ui && ui <= di_end) + { + ui -= di_start; + f->debug.info = js_realloc (vm, f->debug.info, + (f->debug.num_info + 1) + * sizeof (DebugInfo)); + + f->debug.info[f->debug.num_info].pc = reloc[ui]; + f->debug.info[f->debug.num_info].linenum = ln; + f->debug.num_info++; + } + break; + + default: + sprintf (buf, + "VM: unknown debug information type %d%s", + *debug_info, JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); + + abort (); + break; + } + } + + debug_info_done: + if (f->debug.file == NULL) + f->debug.file = js_strdup (vm, debug_filename); + } + + js_free (reloc); + js_free (fixed_code); + } + } + } + else + { + int i; + + /* Applying arguments to function. */ + if (func->type != JS_FUNC) + { + sprintf (vm->error, "illegal function in apply"); + return 0; + } + + if (vm->verbose > 1) + { + sprintf (buf, "VM: calling function%s", + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + f = func->u.vfunction->implementation; + + /* Init stack. */ + sp = vm->sp; + + /* + * Save the applied function to the stack. If our script + * overwrites the function, the function will not be deleted + * under us, since it is protected from the gc in the stack. + */ + JS_COPY (JS_SP0, func); + JS_PUSH (); + + /* Push arguments to the stack. */ + for (i = argc - 1; i >= 0; i--) + { + JS_COPY (JS_SP0, &argv[i]); + JS_PUSH (); + } + + /* This pointer. */ + if (object) + JS_COPY (JS_SP0, object); + else + JS_SP0->type = JS_NULL; + JS_PUSH (); + + /* Init fp and pc so our SUBROUTINE_CALL will work. */ + fp = NULL; + pc = NULL; + + JS_SUBROUTINE_CALL (f); + + /* Run. */ + NEXT (); + } + + if (global_f) + { + if (vm->verbose > 1) + { + sprintf (buf, "VM: exec: %s%s", JS_GLOBAL_NAME, + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + + /* Create the initial stack frame by hand. */ + sp = vm->sp; + + /* + * Push the global function to the stack. There it is protected + * from the garbage collection, as long, as we are executing the + * global code. It is also removed automatically, when the + * execution ends. + */ + JS_SP0->type = JS_FUNC; + JS_SP0->u.vfunction = js_vm_make_function (vm, global_f); + JS_PUSH (); + + /* Empty this pointer. */ + JS_SP0->type = JS_NULL; + JS_PUSH (); + + /* Init fp and pc so our JS_SUBROUTINE_CALL macro works. */ + fp = NULL; + pc = NULL; + + JS_SUBROUTINE_CALL (global_f); + + /* Run. */ + NEXT (); + } + + /* The smart done label. */ + + done: + + /* + * The return value from function calls and global evals is at JS_SP1. + * If is NULL, then we were linking byte-code that didn't have + * .global section. + */ + if (sp) + JS_COPY (&vm->exec_result, JS_SP1); + else + vm->exec_result.type = JS_UNDEFINED; + + /* All done. */ + return 1; + + /* And finally, include the operands. */ + { + JSNode builtin_result; + JSNode *function; + JSInt32 i, j; + JSInt8 i8; + + /* include ejumps.h */ +#include "ejumps.h" + /* end include ejumps.h */ + } +#else /* not (__GNUC__ && !DISABLE_JUMPS) */ + return 0; +#endif /* not (__GNUC__ && !DISABLE_JUMPS) */ +} + + +const char * +js_vm_jumps_func_name (JSVirtualMachine *vm, void *program_counter) +{ +#if __GNUC__ && !DISABLE_JUMPS + int i; + Function *f; + Compiled *pc = program_counter; + JSNode *sp = vm->sp; + + /* Check the globals. */ + for (i = 0; i < vm->num_globals; i++) + if (vm->globals[i].type == JS_FUNC) + { + f = (Function *) vm->globals[i].u.vfunction->implementation; + if (f->code < pc && pc < f->code + f->length) + return f->name; + } + + /* No luck. Let's try the stack. */ + for (sp++; sp < vm->stack + vm->stack_size; sp++) + if (sp->type == JS_FUNC) + { + f = (Function *) sp->u.vfunction->implementation; + if (f->code < pc && pc < f->code + f->length) + return f->name; + } + + /* Still no matches. This shouldn't be reached... ok, who cares? */ + return JS_GLOBAL_NAME; + +#else /* not (__GNUC__ && !DISABLE_JUMPS) */ + return ""; +#endif /* not (__GNUC__ && !DISABLE_JUMPS) */ +} + + +const char * +js_vm_jumps_debug_position (JSVirtualMachine *vm, unsigned int *linenum_return) +{ +#if __GNUC__ && !DISABLE_JUMPS + int i; + Function *f; + void *program_counter = vm->pc; + Compiled *pc = vm->pc; + JSNode *sp = vm->sp; + unsigned int linenum = 0; + + /* Check the globals. */ + for (i = 0; i < vm->num_globals; i++) + if (vm->globals[i].type == JS_FUNC) + { + f = (Function *) vm->globals[i].u.vfunction->implementation; + if (f->code < pc && pc < f->code + f->length) + { + found: + + /* Ok, found it. */ + if (f->debug.file == NULL) + /* No debugging information available for this function. */ + return NULL; + + /* Find the correct pc position. */ + for (i = 0; i < f->debug.num_info; i++) + { + if (f->debug.info[i].pc > program_counter) + break; + + linenum = f->debug.info[i].linenum; + } + + *linenum_return = linenum; + return f->debug.file; + } + } + + /* No luck. Let's try the stack. */ + for (sp++; sp < vm->stack + vm->stack_size; sp++) + if (sp->type == JS_FUNC) + { + f = (Function *) sp->u.vfunction->implementation; + if (f->code < pc && pc < f->code + f->length) + /* Found it. */ + goto found; + } + + /* Couldn't find the function we are executing. */ + return NULL; + +#else /* not (__GNUC__ && !DISABLE_JUMPS) */ + return NULL; +#endif /* not (__GNUC__ && !DISABLE_JUMPS) */ +} diff --git a/reactos/lib/kjs/src/vmswitch.c b/reactos/lib/kjs/src/vmswitch.c new file mode 100644 index 00000000000..d34b720a7e1 --- /dev/null +++ b/reactos/lib/kjs/src/vmswitch.c @@ -0,0 +1,554 @@ +/* + * Optimized `switch' instruction dispatcher. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/vmswitch.c,v $ + * $Id: vmswitch.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" + +/* + * Types and definitions. + */ + +#define SAVE_OP(a) \ +reloc[cp - fixed_code - 1] = &f->code[cpos]; \ +f->code[cpos++].u.op = (a) + +#define SAVE_INT8(a) f->code[cpos++].u.i8 = (a) +#define SAVE_INT16(a) f->code[cpos++].u.i16 = (a) +#define SAVE_INT32(a) f->code[cpos++].u.i32 = (a) + +#define ARG_INT32() f->code[cpos].u.i32 + +#define READ_INT8(var) (var) = (pc++)->u.i8 +#define READ_INT16(var) (var) = (pc++)->u.i16 +#define READ_INT32(var) (var) = (pc++)->u.i32 + +#define SETPC(ofs) pc = (ofs) +#define SETPC_RELATIVE(ofs) pc += (ofs) + +#define CALL_USER_FUNC(f) pc = ((Function *) (f))->code + +#define DONE() goto done + +#define ERROR(msg) \ + do { \ + JS_SAVE_REGS (); \ + strcpy (vm->error, (msg)); \ + js_vm_error (vm); \ + /* NOTREACHED */ \ + } while (0) + + +struct compiled_st +{ + union + { + void *ptr; + JSUInt8 op; + JSInt8 i8; + JSInt16 i16; + JSInt32 i32; + } u; +}; + +typedef struct compiled_st Compiled; + +/* Debug information. */ +struct debug_info_st +{ + void *pc; + unsigned int linenum; +}; + +typedef struct debug_info_st DebugInfo; + +struct function_st +{ + JSHeapDestroyableCB destroy; + + char *name; + Compiled *code; + unsigned int length; + + struct + { + char *file; + unsigned int num_info; + DebugInfo *info; + } debug; +}; + +typedef struct function_st Function; + + +/* + * Prototypes for static functions. + */ + +static void function_destroy (void *ptr); + +static Function *link_code (JSVirtualMachine *vm, unsigned char *code, + unsigned int code_len, + unsigned int consts_offset, + unsigned char *debug_info, + unsigned int debug_info_len, + unsigned int code_offset); + +static void execute_code (JSVirtualMachine *vm, JSNode *object, Function *f, + unsigned int argc, JSNode *argv); + + +/* + * Global functions. + */ + +int +js_vm_switch_exec (JSVirtualMachine *vm, JSByteCode *bc, JSSymtabEntry *symtab, + unsigned int num_symtab_entries, + unsigned int consts_offset, + unsigned int anonymous_function_offset, + unsigned char *debug_info, unsigned int debug_info_len, + JSNode *object, JSNode *func, + unsigned int argc, JSNode *argv) +{ + int i; + unsigned int ui; + Function *global_f = NULL; + Function *f; + unsigned char *code = NULL; + char buf[512]; + + if (bc) + { + /* Executing byte-code. */ + + /* Find the code section. */ + for (i = 0; i < bc->num_sects; i++) + if (bc->sects[i].type == JS_BCST_CODE) + code = bc->sects[i].data; + assert (code != NULL); + + /* Enter all functions to the known functions of the VM. */ + for (i = 0; i < num_symtab_entries; i++) + { + /* Link the code to our environment. */ + f = link_code (vm, code + symtab[i].offset, + symtab[i + 1].offset - symtab[i].offset, + consts_offset, debug_info, debug_info_len, + symtab[i].offset); + f->name = js_strdup (vm, symtab[i].name); + + if (strcmp (symtab[i].name, JS_GLOBAL_NAME) == 0) + global_f = f; + else + { + int is_anonymous = 0; + + /* Check for the anonymous function. */ + if (symtab[i].name[0] == '.' && symtab[i].name[1] == 'F' + && symtab[i].name[2] == ':') + is_anonymous = 1; + + if (vm->verbose > 3) + { + sprintf (buf, "VM: link: %s(): start=%d, length=%d", + symtab[i].name, symtab[i].offset, + symtab[i + 1].offset - symtab[i].offset); + if (is_anonymous) + sprintf (buf + strlen (buf), + ", relocating with offset %u", + anonymous_function_offset); + strcat (buf, JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + + if (is_anonymous) + { + sprintf (buf, ".F:%u", + (unsigned int) atoi (symtab[i].name + 3) + + anonymous_function_offset); + ui = js_vm_intern (vm, buf); + } + else + ui = js_vm_intern (vm, symtab[i].name); + + vm->globals[ui].type = JS_FUNC; + vm->globals[ui].u.vfunction = js_vm_make_function (vm, f); + } + } + } + else + { + /* Applying arguments to function. */ + + if (func->type != JS_FUNC) + { + sprintf (vm->error, "illegal function in apply"); + return 0; + } + + if (vm->verbose > 1) + { + sprintf (buf, "VM: calling function%s", + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + f = func->u.vfunction->implementation; + + execute_code (vm, object, f, argc, argv); + } + + if (global_f) + { + if (vm->verbose > 1) + { + sprintf (buf, "VM: exec: %s%s", global_f->name, + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + + /* Execute. */ + execute_code (vm, NULL, global_f, 0, NULL); + } + + return 1; +} + + +const char * +js_vm_switch_func_name (JSVirtualMachine *vm, void *program_counter) +{ + int i; + Function *f; + Compiled *pc = program_counter; + JSNode *sp = vm->sp; + + /* Check the globals. */ + for (i = 0; i < vm->num_globals; i++) + if (vm->globals[i].type == JS_FUNC) + { + f = (Function *) vm->globals[i].u.vfunction->implementation; + if (f->code < pc && pc < f->code + f->length) + return f->name; + } + + /* No luck. Let's try the stack. */ + for (sp++; sp < vm->stack + vm->stack_size; sp++) + if (sp->type == JS_FUNC) + { + f = (Function *) sp->u.vfunction->implementation; + if (f->code < pc && pc < f->code + f->length) + return f->name; + } + + /* Still no matches. This shouldn't be reached... ok, who cares? */ + return JS_GLOBAL_NAME; +} + + +const char * +js_vm_switch_debug_position (JSVirtualMachine *vm, + unsigned int *linenum_return) +{ + int i; + Function *f; + void *program_counter = vm->pc; + Compiled *pc = vm->pc; + JSNode *sp = vm->sp; + unsigned int linenum = 0; + + /* Check the globals. */ + for (i = 0; i < vm->num_globals; i++) + if (vm->globals[i].type == JS_FUNC) + { + f = (Function *) vm->globals[i].u.vfunction->implementation; + if (f->code < pc && pc < f->code + f->length) + { + found: + + /* Ok, found it. */ + if (f->debug.file == NULL) + /* No debugging information available for this function. */ + return NULL; + + /* Find the correct pc position. */ + for (i = 0; i < f->debug.num_info; i++) + { + if (f->debug.info[i].pc > program_counter) + break; + + linenum = f->debug.info[i].linenum; + } + + *linenum_return = linenum; + return f->debug.file; + } + } + + /* No luck. Let's try the stack. */ + for (sp++; sp < vm->stack + vm->stack_size; sp++) + if (sp->type == JS_FUNC) + { + f = (Function *) sp->u.vfunction->implementation; + if (f->code < pc && pc < f->code + f->length) + /* Found it. */ + goto found; + } + + /* Couldn't find the function we are executing. */ + return NULL; +} + + +/* + * Static functions. + */ + +static void +function_destroy (void *ptr) +{ + Function *f = ptr; + + js_free (f->name); + js_free (f->code); + + if (f->debug.file) + js_free (f->debug.file); + if (f->debug.info) + js_free (f->debug.info); +} + + +static Function * +link_code (JSVirtualMachine *vm, unsigned char *code, unsigned int code_len, + unsigned int consts_offset, unsigned char *debug_info, + unsigned int debug_info_len, unsigned int code_offset) +{ + unsigned char *cp, *end; + JSInt32 i; + Compiled **reloc; + unsigned int cpos; + Function *f; + unsigned char *fixed_code; + unsigned int ui; + char *debug_filename = "unknown"; + char buf[512]; + + /* Terminate the code with op `done'. */ + fixed_code = js_malloc (vm, code_len + 1); + memcpy (fixed_code, code, code_len); + fixed_code[code_len] = 1; /* op `done' */ + + cp = fixed_code; + end = fixed_code + code_len + 1; + + /* Alloc function closure. */ + f = js_vm_alloc_destroyable (vm, sizeof (*f)); + f->destroy = function_destroy; + + /* Allocate space for our compiled code. is enought. */ + f->code = js_malloc (vm, (code_len + 1) * sizeof (Compiled)); + reloc = js_calloc (vm, code_len + 1, sizeof (Compiled *)); + + /* Link phase 1: constants and symbols. */ + cpos = 0; + while (cp < end) + { + switch (*cp++) + { + /* include c1switch.h */ +#include "c1switch.h" + /* end include c1switch.h */ + } + } + f->length = cpos; + + /* Link phase 2: relative jumps. */ + cp = fixed_code; + cpos = 0; + while (cp < end) + { + switch (*cp++) + { + /* include c2switch.h */ +#include "c2switch.h" + /* end include c2switch.h */ + } + } + /* Handle debug info. */ + if (debug_info) + { + unsigned int di_start = code_offset; + unsigned int di_end = code_offset + code_len; + unsigned int ln; + + for (; debug_info_len > 0;) + { + switch (*debug_info) + { + case JS_DI_FILENAME: + debug_info++; + debug_info_len--; + + JS_BC_READ_INT32 (debug_info, ui); + debug_info += 4; + debug_info_len -= 4; + + f->debug.file = js_malloc (vm, ui + 1); + memcpy (f->debug.file, debug_info, ui); + f->debug.file[ui] = '\0'; + + debug_filename = f->debug.file; + + debug_info += ui; + debug_info_len -= ui; + break; + + case JS_DI_LINENUMBER: + JS_BC_READ_INT32 (debug_info + 1, ui); + if (ui > di_end) + goto debug_info_done; + + /* This belongs to us (maybe). */ + debug_info += 5; + debug_info_len -= 5; + + JS_BC_READ_INT32 (debug_info, ln); + debug_info += 4; + debug_info_len -= 4; + + if (di_start <= ui && ui <= di_end) + { + ui -= di_start; + f->debug.info = js_realloc (vm, f->debug.info, + (f->debug.num_info + 1) + * sizeof (DebugInfo)); + + f->debug.info[f->debug.num_info].pc = reloc[ui]; + f->debug.info[f->debug.num_info].linenum = ln; + f->debug.num_info++; + } + break; + + default: + sprintf (buf, + "VM: unknown debug information type %d%s", + *debug_info, JS_HOST_LINE_BREAK); + + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); + + abort (); + break; + } + } + + debug_info_done: + if (f->debug.file == NULL) + f->debug.file = js_strdup (vm, debug_filename); + } + + js_free (reloc); + js_free (fixed_code); + + return f; +} + + +/* + * Execute byte code by using the `switch' dispatch technique. + */ + +static void +execute_code (JSVirtualMachine *vm, JSNode *object, Function *f, + unsigned int argc, JSNode *argv) +{ + JSNode *sp; + JSNode *fp; + JSNode *function; + JSNode builtin_result; + Compiled *pc; + JSInt32 i, j; + JSInt8 i8; + char buf[512]; + + /* Create the initial stack frame by hand. */ + sp = vm->sp; + + /* Protect the function from gc. */ + JS_SP0->type = JS_FUNC; + JS_SP0->u.vfunction = js_vm_make_function (vm, f); + JS_PUSH (); + + /* Push arguments to the stack. */ + i = argc; + for (i--; i >= 0; i--) + { + JS_COPY (JS_SP0, &argv[i]); + JS_PUSH (); + } + + /* This pointer. */ + if (object) + JS_COPY (JS_SP0, object); + else + JS_SP0->type = JS_NULL; + JS_PUSH (); + + /* Init fp and pc so our SUBROUTINE_CALL will work. */ + fp = NULL; + pc = NULL; + + JS_SUBROUTINE_CALL (f); + + /* Ok, now we are ready to run. */ + + while (1) + { + switch ((pc++)->u.op) + { + /* include eswitch.h */ +#include "eswitch.h" + /* end include eswitch.h */ + + default: + sprintf (buf, "execute_code: unknown opcode %d%s", + (pc - 1)->u.op, JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); + + abort (); + break; + } + } + + done: + + /* All done. */ + + JS_COPY (&vm->exec_result, JS_SP1); +} diff --git a/reactos/lib/kjs/src/vmswt0.c b/reactos/lib/kjs/src/vmswt0.c new file mode 100644 index 00000000000..272226b53ab --- /dev/null +++ b/reactos/lib/kjs/src/vmswt0.c @@ -0,0 +1,351 @@ +/* + * The basic `switch' instruction dispatcher. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/vmswt0.c,v $ + * $Id: vmswt0.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" + +/* + * Types and definitions. + */ + +struct function_st +{ + JSHeapDestroyableCB destroy; + + char *name; + unsigned char *code; + unsigned int length; +}; + +typedef struct function_st Function; + + +/* + * Prototypes for static functions. + */ + +static void function_destroy (void *ptr); + +static void link_code (JSVirtualMachine *vm, unsigned char *code, + unsigned int code_len, unsigned int consts_offset); + +static void execute_code (JSVirtualMachine *vm, JSNode *object, Function *f, + unsigned int argc, JSNode *argv); + + +/* + * Global functions. + */ + +int +js_vm_switch0_exec (JSVirtualMachine *vm, JSByteCode *bc, + JSSymtabEntry *symtab, + unsigned int num_symtab_entries, + unsigned int consts_offset, + unsigned int anonymous_function_offset, + unsigned char *debug_info, unsigned int debug_info_len, + JSNode *object, JSNode *func, + unsigned int argc, JSNode *argv) +{ + int i; + unsigned int ui; + Function *global_f = NULL; + Function *f; + unsigned char *code = NULL; + char buf[512]; + + if (bc) + { + /* Executing byte-code. */ + + /* Find the code section. */ + for (i = 0; i < bc->num_sects; i++) + if (bc->sects[i].type == JS_BCST_CODE) + code = bc->sects[i].data; + assert (code != NULL); + + /* Enter all functions to the known functions of the VM. */ + for (i = 0; i < num_symtab_entries; i++) + { + /* Need one function. */ + f = js_vm_alloc_destroyable (vm, sizeof (*f)); + f->destroy = function_destroy; + f->name = js_strdup (vm, symtab[i].name); + + f->length = symtab[i + 1].offset - symtab[i].offset + 1; + f->code = js_malloc (vm, f->length); + memcpy (f->code, code + symtab[i].offset, f->length - 1); + f->code[f->length - 1] = 1; /* op `done' */ + + /* Link the code to our environment. */ + link_code (vm, f->code, f->length, consts_offset); + + if (strcmp (symtab[i].name, JS_GLOBAL_NAME) == 0) + global_f = f; + else + { + int is_anonymous = 0; + + /* Check for the anonymous function. */ + if (symtab[i].name[0] == '.' && symtab[i].name[1] == 'F' + && symtab[i].name[2] == ':') + is_anonymous = 1; + + if (vm->verbose > 3) + { + sprintf (buf, "VM: link: %s(): start=%d, length=%d", + symtab[i].name, symtab[i].offset, + symtab[i + 1].offset - symtab[i].offset); + if (is_anonymous) + sprintf (buf + strlen (buf), + ", relocating with offset %u", + anonymous_function_offset); + strcat (buf, JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + + if (is_anonymous) + { + sprintf (buf, ".F:%u", + (unsigned int) atoi (symtab[i].name + 3) + + anonymous_function_offset); + ui = js_vm_intern (vm, buf); + } + else + ui = js_vm_intern (vm, symtab[i].name); + + vm->globals[ui].type = JS_FUNC; + vm->globals[ui].u.vfunction = js_vm_make_function (vm, f); + } + } + } + else + { + /* Applying arguments to function. */ + if (func->type != JS_FUNC) + { + sprintf (vm->error, "illegal function in apply"); + return 0; + } + + if (vm->verbose > 1) + { + sprintf (buf, "VM: calling function%s", + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + f = func->u.vfunction->implementation; + + execute_code (vm, object, f, argc, argv); + } + + if (global_f) + { + if (vm->verbose > 1) + { + sprintf (buf, "VM: exec: %s%s", global_f->name, + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + } + + /* Execute. */ + execute_code (vm, NULL, global_f, 0, NULL); + } + + return 1; +} + + +const char * +js_vm_switch0_func_name (JSVirtualMachine *vm, void *program_counter) +{ + int i; + Function *f; + unsigned char *pc = program_counter; + JSNode *sp = vm->sp; + + /* Check the globals. */ + for (i = 0; i < vm->num_globals; i++) + if (vm->globals[i].type == JS_FUNC) + { + f = (Function *) vm->globals[i].u.vfunction->implementation; + if (f->code < pc && pc < f->code + f->length) + return f->name; + } + + /* No luck. Let's try the stack. */ + for (sp++; sp < vm->stack + vm->stack_size; sp++) + if (sp->type == JS_FUNC) + { + f = (Function *) sp->u.vfunction->implementation; + if (f->code < pc && pc < f->code + f->length) + return f->name; + } + + /* Still no matches. This shouldn't be reached... ok, who cares? */ + return JS_GLOBAL_NAME; +} + + +const char * +js_vm_switch0_debug_position (JSVirtualMachine *vm, + unsigned int *linenum_return) +{ + /* XXX */ + return NULL; +} + + +/* + * Static functions. + */ + +static void +function_destroy (void *ptr) +{ + Function *f = ptr; + + js_free (f->name); + js_free (f->code); +} + + +static void +link_code (JSVirtualMachine *vm, unsigned char *code, unsigned int code_len, + unsigned int consts_offset) +{ + unsigned char *cp, *end; + JSInt32 i; + + cp = code; + end = code + code_len; + + while (cp < end) + { + switch (*cp++) + { + /* include c1swt0.h */ +#include "c1swt0.h" + /* end include c1swt0.h */ + } + } +} + + +/* + * Execute byte code by using the `switch' dispatch technique. + */ + +#define READ_INT8(i) JS_BC_READ_INT8(pc, (i)); (i) = (JSInt8) (i); pc++ +#define READ_INT16(i) JS_BC_READ_INT16(pc, (i)); (i) = (JSInt16) (i); pc += 2 +#define READ_INT32(i) JS_BC_READ_INT32(pc, (i)); (i) = (JSInt32) (i); pc += 4 + +#define SETPC(ofs) pc = (ofs) +#define SETPC_RELATIVE(ofs) pc += (ofs) + +#define CALL_USER_FUNC(f) pc = ((Function *) (f))->code + +#define DONE() goto done + +#define ERROR(msg) \ + do { \ + JS_SAVE_REGS (); \ + strcpy (vm->error, (msg)); \ + js_vm_error (vm); \ + /* NOTREACHED */ \ + } while (0) + +static void +execute_code (JSVirtualMachine *vm, JSNode *object, Function *f, + unsigned int argc, JSNode *argv) +{ + JSNode *sp; + JSNode *fp; + JSNode *function; + JSNode builtin_result; + unsigned char *pc; + JSInt32 i, j; + JSInt8 i8; + char buf[512]; + + /* Create the initial stack frame by hand. */ + sp = vm->sp; + + /* Protect the function from gc. */ + JS_SP0->type = JS_FUNC; + JS_SP0->u.vfunction = js_vm_make_function (vm, f); + JS_PUSH (); + + /* Push arguments to the stack. */ + i = argc; + for (i--; i >= 0; i--) + { + JS_COPY (JS_SP0, &argv[i]); + JS_PUSH (); + } + + /* This pointer. */ + if (object) + JS_COPY (JS_SP0, object); + else + JS_SP0->type = JS_NULL; + JS_PUSH (); + + /* Init fp and pc so our SUBROUTINE_CALL will work. */ + fp = NULL; + pc = NULL; + + JS_SUBROUTINE_CALL (f); + + /* Ok, now we are ready to run. */ + + while (1) + { + switch (*pc++) + { + /* include eswt0.h */ +#include "eswt0.h" + /* end include eswt0.h */ + + default: + sprintf (buf, "execute_code: unknown opcode %d%s", *(pc - 1), + JS_HOST_LINE_BREAK); + js_iostream_write (vm->s_stderr, buf, strlen (buf)); + js_iostream_flush (vm->s_stderr); + + abort (); + break; + } + } + + done: + + /* All done. */ + + JS_COPY (&vm->exec_result, JS_SP1); +} diff --git a/reactos/lib/kjs/src/xcurses.c b/reactos/lib/kjs/src/xcurses.c new file mode 100644 index 00000000000..0f57101aef2 --- /dev/null +++ b/reactos/lib/kjs/src/xcurses.c @@ -0,0 +1,450 @@ +/* + * Curses extension. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/xcurses.c,v $ + * $Id: xcurses.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" + +#include + +/* Curses context. */ +struct curses_ctx_st +{ + JSSymbol s_addstr; + JSSymbol s_attron; + JSSymbol s_attroff; + JSSymbol s_attset; + JSSymbol s_beep; + JSSymbol s_cbreak; + JSSymbol s_clear; + JSSymbol s_clrtobot; + JSSymbol s_clrtoeol; + JSSymbol s_echo; + JSSymbol s_endwin; + JSSymbol s_getch; + JSSymbol s_initscr; + JSSymbol s_keypad; + JSSymbol s_move; + JSSymbol s_mvaddstr; + JSSymbol s_mvaddsubstr; + JSSymbol s_mvgetch; + JSSymbol s_nocbreak; + JSSymbol s_noecho; + JSSymbol s_refresh; + JSSymbol s_standend; + JSSymbol s_standout; + + JSSymbol s_LINES; + JSSymbol s_COLS; +}; + +typedef struct curses_ctx_st CursesCtx; + +/* + * Static functions. + */ + +/* 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; +} + + +/* 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; +} + +/* + * Global functions. + */ + +void +js_ext_curses (JSInterpPtr interp) +{ + CursesCtx *ctx; + JSBuiltinInfo *info; + JSNode *n; + JSVirtualMachine *vm = interp->vm; + + /* Class context. */ + ctx = js_calloc (vm, 1, sizeof (*ctx)); + + ctx->s_addstr = js_vm_intern (vm, "addstr"); + ctx->s_attron = js_vm_intern (vm, "attron"); + ctx->s_attroff = js_vm_intern (vm, "attroff"); + ctx->s_beep = js_vm_intern (vm, "beep"); + ctx->s_cbreak = js_vm_intern (vm, "cbreak"); + ctx->s_clear = js_vm_intern (vm, "clear"); + ctx->s_clrtobot = js_vm_intern (vm, "clrtobot"); + ctx->s_clrtoeol = js_vm_intern (vm, "clrtoeol"); + ctx->s_echo = js_vm_intern (vm, "echo"); + ctx->s_endwin = js_vm_intern (vm, "endwin"); + ctx->s_getch = js_vm_intern (vm, "getch"); + ctx->s_initscr = js_vm_intern (vm, "initscr"); + ctx->s_keypad = js_vm_intern (vm, "keypad"); + ctx->s_move = js_vm_intern (vm, "move"); + ctx->s_mvaddstr = js_vm_intern (vm, "mvaddstr"); + ctx->s_mvaddsubstr = js_vm_intern (vm, "mvaddsubstr"); + ctx->s_mvgetch = js_vm_intern (vm, "mvgetch"); + ctx->s_nocbreak = js_vm_intern (vm, "nocbreak"); + ctx->s_noecho = js_vm_intern (vm, "noecho"); + ctx->s_refresh = js_vm_intern (vm, "refresh"); + ctx->s_standend = js_vm_intern (vm, "standend"); + ctx->s_standout = js_vm_intern (vm, "standout"); + + ctx->s_LINES = js_vm_intern (vm, "LINES"); + ctx->s_COLS = js_vm_intern (vm, "COLS"); + + /* 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, "Curses")]; + js_vm_builtin_create (vm, n, info, NULL); +} diff --git a/reactos/lib/kjs/src/xjs.c b/reactos/lib/kjs/src/xjs.c new file mode 100644 index 00000000000..ab3cf0fbfea --- /dev/null +++ b/reactos/lib/kjs/src/xjs.c @@ -0,0 +1,460 @@ +/* + * JavaScript extension. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/xjs.c,v $ + * $Id: xjs.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "js.h" +#include "jsint.h" + +/* + * Types and definitions. + */ + +/* Class context. */ +struct xjs_ctx_st +{ + /* Methods. */ + JSSymbol s_compile; + JSSymbol s_eval; + JSSymbol s_evalFile; + JSSymbol s_evalJavaScriptFile; + JSSymbol s_executeByteCodeFile; + JSSymbol s_getVar; + JSSymbol s_setVar; + + /* Properties. */ + JSSymbol s_errorMessage; +}; + +typedef struct xjs_ctx_st XJSCtx; + +/* Instance context. */ +struct xjs_instance_ctx_st +{ + JSInterpPtr interp; +}; + +typedef struct xjs_instance_ctx_st XJSInstanceCtx; + + +/* + * Static functions. + */ + +static void +copy_from_type_to_node (JSVirtualMachine *vm, JSNode *to, JSType *from) +{ + int i; + + switch (from->type) + { + case JS_TYPE_NULL: + to->type = JS_NULL; + break; + + case JS_TYPE_BOOLEAN: + to->type = JS_BOOLEAN; + to->u.vboolean = from->u.i; + break; + + case JS_TYPE_INTEGER: + to->type = JS_INTEGER; + to->u.vinteger = from->u.i; + break; + + case JS_TYPE_STRING: + js_vm_make_string (vm, to, from->u.s->data, from->u.s->len); + break; + + case JS_TYPE_DOUBLE: + to->type = JS_FLOAT; + to->u.vfloat = from->u.d; + break; + + case JS_TYPE_ARRAY: + js_vm_make_array (vm, to, from->u.array->length); + for (i = 0; i < from->u.array->length; i++) + copy_from_type_to_node (vm, + &to->u.varray->data[i], + &from->u.array->data[i]); + break; + + default: + to->type = JS_UNDEFINED; + break; + } +} + + +static void +copy_from_node_to_type (JSInterpPtr interp, JSType *to, JSNode *from) +{ + int i; + + switch (from->type) + { + case JS_NULL: + to->type = JS_TYPE_NULL; + break; + + case JS_BOOLEAN: + to->type = JS_TYPE_BOOLEAN; + to->u.i = from->u.vboolean; + break; + + case JS_INTEGER: + to->type = JS_TYPE_INTEGER; + to->u.i = from->u.vinteger; + break; + + case JS_STRING: + js_type_make_string (interp, to, from->u.vstring->data, + from->u.vstring->len); + break; + + case JS_FLOAT: + to->type = JS_TYPE_DOUBLE; + to->u.d = from->u.vfloat; + break; + + case JS_ARRAY: + js_type_make_array (interp, to, from->u.varray->length); + for (i = 0; i < from->u.varray->length; i++) + copy_from_node_to_type (interp, + &to->u.array->data[i], + &from->u.varray->data[i]); + break; + + default: + to->type = JS_TYPE_UNDEFINED; + break; + } +} + + +/* 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; +} + + +/* 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; +} + + +/* 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); +} + +/* Delete proc. */ +static void +delete_proc (JSBuiltinInfo *builtin_info, void *instance_context) +{ + XJSInstanceCtx *instance = instance_context; + + if (instance) + { + js_destroy_interp (instance->interp); + js_free (instance); + } +} + + +/* + * Global functions. + */ + +void +js_ext_JS (JSInterpPtr interp) +{ + JSNode *n; + JSBuiltinInfo *info; + JSSymbol sym; + XJSCtx *ctx; + JSVirtualMachine *vm = interp->vm; + + ctx = js_calloc (vm, 1, sizeof (*ctx)); + + ctx->s_compile = js_vm_intern (vm, "compile"); + ctx->s_eval = js_vm_intern (vm, "eval"); + ctx->s_evalFile = js_vm_intern (vm, "evalFile"); + ctx->s_evalJavaScriptFile = js_vm_intern (vm, "evalJavaScriptFile"); + ctx->s_executeByteCodeFile = js_vm_intern (vm, "executeByteCodeFile"); + ctx->s_getVar = js_vm_intern (vm, "getVar"); + ctx->s_setVar = js_vm_intern (vm, "setVar"); + + ctx->s_errorMessage = js_vm_intern (vm, "errorMessage"); + + /* Object information. */ + + info = js_vm_builtin_info_create (vm); + + info->method_proc = method; + info->property_proc = property; + info->new_proc = new_proc; + info->delete_proc = delete_proc; + info->obj_context = ctx; + info->obj_context_delete = js_free; + + /* Define it. */ + sym = js_vm_intern (vm, "JS"); + n = &vm->globals[sym]; + + js_vm_builtin_create (vm, n, info, NULL); +} diff --git a/reactos/lib/kjs/src/xmd5.c b/reactos/lib/kjs/src/xmd5.c new file mode 100644 index 00000000000..d2b0baacb5a --- /dev/null +++ b/reactos/lib/kjs/src/xmd5.c @@ -0,0 +1,222 @@ +/* + * The MD5 extension. + * Copyright (c) 1998 New Generation Software (NGS) Oy + * + * Author: Markku Rossi + */ + +/* + * 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: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/xmd5.c,v $ + * $Id: xmd5.c,v 1.1 2004/01/10 20:38:18 arty Exp $ + */ + +#include "jsint.h" +#include "md5.h" + +/* + * Types and definitions. + */ + +/* Class context. */ +struct md5_ctx_st +{ + /* Methods. */ + JSSymbol s_final; + JSSymbol s_finalBinary; + JSSymbol s_init; + JSSymbol s_update; +}; + +typedef struct md5_ctx_st MD5Ctx; + +/* + * Static functions. + */ + +/* Method proc. */ +static int +method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, + void *instance_context, JSSymbol method, JSNode *result_return, + JSNode *args) +{ + MD5Ctx *ctx = builtin_info->obj_context; + MD5_CTX *ictx = instance_context; + unsigned char final[16]; + + /* Static methods. */ + if (method == vm->syms.s_toString) + { + if (ictx) + goto default_to_string; + else + js_vm_make_static_string (vm, result_return, "MD5", 3); + } + /* ********************************************************************** */ + else if (ictx) + { + /* Methods. */ + if (method == ctx->s_final) + { + char buf[33]; /* +1 for the trailing '\0'. */ + char *cp; + int i; + + default_to_string: + + if (args->u.vinteger != 0) + goto argument_error; + + MD5Final (final, ictx); + for (i = 0, cp = buf; i < 16; i++, cp += 2) + sprintf (cp, "%02X", final[i]); + + js_vm_make_string (vm, result_return, buf, 32); + } + /* ***************************************************************** */ + else if (method == ctx->s_finalBinary) + { + if (args->u.vinteger != 0) + goto argument_error; + + MD5Final (final, ictx); + js_vm_make_string (vm, result_return, final, 16); + } + /* ***************************************************************** */ + else if (method == ctx->s_init) + { + if (args->u.vinteger != 0) + goto argument_error; + + MD5Init (ictx); + result_return->type = JS_UNDEFINED; + } + /* ***************************************************************** */ + else if (method == ctx->s_update) + { + if (args->u.vinteger != 1) + goto argument_error; + if (args[1].type != JS_STRING) + goto argument_type_error; + + MD5Update (ictx, args[1].u.vstring->data, args[1].u.vstring->len); + 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, "MD5.%s(): illegal amount of arguments", + js_vm_symname (vm, method)); + js_vm_error (vm); + + argument_type_error: + sprintf (vm->error, "MD5.%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) +{ + if (!set) + node->type = JS_UNDEFINED; + + return JS_PROPERTY_UNKNOWN; +} + +/* New proc. */ +static void +new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, JSNode *args, + JSNode *result_return) +{ + MD5_CTX *instance; + + if (args->u.vinteger != 0) + { + sprintf (vm->error, "new MD5(): illegal amount of arguments"); + js_vm_error (vm); + } + + instance = js_calloc (vm, 1, sizeof (*instance)); + MD5Init (instance); + + js_vm_builtin_create (vm, result_return, builtin_info, instance); +} + +/* Delete proc. */ +static void +delete_proc (JSBuiltinInfo *builtin_info, void *instance_context) +{ + if (instance_context) + js_free (instance_context); +} + + +/* + * Global functions. + */ + +void +js_ext_MD5 (JSInterpPtr interp) +{ + JSBuiltinInfo *info; + MD5Ctx *ctx; + JSNode *n; + JSVirtualMachine *vm = interp->vm; + + ctx = js_calloc (vm, 1, sizeof (*ctx)); + + ctx->s_final = js_vm_intern (vm, "final"); + ctx->s_finalBinary = js_vm_intern (vm, "finalBinary"); + ctx->s_init = js_vm_intern (vm, "init"); + ctx->s_update = js_vm_intern (vm, "update"); + + /* Object information. */ + + info = js_vm_builtin_info_create (vm); + + info->method_proc = method; + info->property_proc = property; + info->new_proc = new_proc; + info->delete_proc = delete_proc; + info->obj_context = ctx; + info->obj_context_delete = js_free; + + /* Define it. */ + n = &vm->globals[js_vm_intern (vm, "MD5")]; + js_vm_builtin_create (vm, n, info, NULL); +} diff --git a/reactos/lib/kjs/stamp-h b/reactos/lib/kjs/stamp-h new file mode 100644 index 00000000000..9788f70238c --- /dev/null +++ b/reactos/lib/kjs/stamp-h @@ -0,0 +1 @@ +timestamp diff --git a/reactos/lib/kjs/stamp-h.in b/reactos/lib/kjs/stamp-h.in new file mode 100644 index 00000000000..9788f70238c --- /dev/null +++ b/reactos/lib/kjs/stamp-h.in @@ -0,0 +1 @@ +timestamp