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