Compare commits

..

345 Commits

Author SHA1 Message Date
(no author)
a617ee3a29 This commit was manufactured by cvs2svn to create tag 'furtest'.
git-svn-id: svn://10.0.0.236/tags/furtest@14018 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-03 23:12:57 +00:00
mang%netscape.com
52d6b91235 Recur into fdlibm directory.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@14017 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-03 23:12:56 +00:00
mccabe%netscape.com
55dc58958a Propagate cls@seawood.org fix:
Removed some MKLINUX & MACLINUX ifdefs. Replace a couple with
(defined(linux) && defined(__powerpc__)).  Added glibc ifndefs to
strdup declarations.  Fixed problem with stderr under glibc 2.1.

Patch submitted by Tom Rini <trini@kernel.crashing.org>.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@14015 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-03 22:51:28 +00:00
mang%netscape.com
682df8db3e For autoconf.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13984 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-03 14:21:21 +00:00
mang%netscape.com
8ed39db9a8 Revved to match Makefile
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13983 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-03 14:08:14 +00:00
mang%netscape.com
33d0464867 More cruft removal.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13982 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-03 13:39:35 +00:00
mang%netscape.com
490b91850b Added dependency on jslibmath.h
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13981 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-03 13:30:38 +00:00
mang%netscape.com
25da940352 Don't build or link useless files.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13980 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-03 13:16:04 +00:00
mang%netscape.com
f0ca36ba7d Need the real ld. Available on most (all?) platforms.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13979 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-03 12:27:16 +00:00
mang%netscape.com
480dbe043f fdlibm makefile.win
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13978 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-03 12:02:26 +00:00
mang%netscape.com
19b9471938 fdlibm Makefile
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13973 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-03 09:35:31 +00:00
mang%netscape.com
68fe0d88b6 Statically link jsmath.o against libfdm.a so as to link in only those
math routines that are needed.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13952 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-03 05:57:54 +00:00
mang%netscape.com
a6fcbc6e38 Sometimes I forget that the whole world doesn't use GNU tools.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13950 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-03 05:45:11 +00:00
mang%netscape.com
a0f85cea3a Post release cleanup.
Removed unnecessary defines (fd_fmod will be used later).
Removal of unnecessary files in fdlibm to follow.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13947 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-03 01:29:14 +00:00
fur%netscape.com
3f5735fcf7 Added more compiler build flags so that we use the correct libc DLL and optimization settings
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13784 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-31 02:58:41 +00:00
mang%netscape.com
0ab0796234 Backed out use of fd_floor on IRIX. See bugsplat bug #332475.
IRIX system floor now fails this special case:
Infinity/Math.floor(-0) = Infinity  FAILED! expected: -Infinity


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13780 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-31 01:32:50 +00:00
jband%netscape.com
0e145d79c2 modified makefile and readme to more easily support tree structure in jsjava.jar
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13776 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-31 00:54:54 +00:00
jband%netscape.com
3e89c252c4 updated README
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13741 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-30 21:41:20 +00:00
jband%netscape.com
6e0204a004 improved comments
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13740 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-30 21:38:52 +00:00
shaver%netscape.com
4b9ed1baa8 allow additional flags to the linker, so we can specify soname and such; need variants for other Unix platforms, but do those later
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13728 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-30 18:09:50 +00:00
norris%netscape.com
b9f4c69e12 Update release string format.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13687 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-29 23:31:24 +00:00
bjorn%netscape.com
5f6a0b9c3a Patch which fixes a problem in the alignment code. I wasn't taking sizeof(JSString)
properly.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13683 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-29 22:38:41 +00:00
fur%netscape.com
f68735a6bb wtc sez': Get rid of use of obsolete NSPR20 build var.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13676 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-29 21:59:30 +00:00
fur%netscape.com
8616bd54f5 Removing obsolete file
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13675 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-29 21:51:46 +00:00
fur%netscape.com
09e0785f68 Removing obsolete/unused files.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13674 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-29 21:50:22 +00:00
fur%netscape.com
dd8953010a Removed uses of obsolete NSPR20 build variable
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13673 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-29 21:43:17 +00:00
fur%netscape.com
a67d8ed2fe + Updated build directions for all platforms.
+ Added table of contents.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13663 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-29 20:00:58 +00:00
shaver%netscape.com
935f0e5ac8 need to poke the GC when hitting the cache on a set
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13645 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-29 03:55:53 +00:00
fur%netscape.com
97aa1f7699 Ignore generated files
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13643 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-29 02:15:23 +00:00
fur%netscape.com
f399e21216 Reporting of uncaught exceptions should occur when JS_HAS_EXCEPTIONS is set,
even if JS_HAS_ERROR_EXCEPTIONS is not.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13642 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-29 02:09:34 +00:00
coop%netscape.com
823cb6e29e Made constructor for wrappedException private and removed deprecation warning.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13638 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-29 00:43:38 +00:00
fur%netscape.com
84e135cd01 Restore build prosperity for Mac LiveConnect after ref/src merge.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13637 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-29 00:24:05 +00:00
fur%netscape.com
ac3516411a No real change: Reorganized a few .c files that had fallen out of their folder.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13636 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-29 00:23:02 +00:00
mang%netscape.com
db237360fa Added section for AIX, thus fixing several bugs.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13634 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-29 00:16:38 +00:00
fur%netscape.com
92e443d317 Restore Mac-specific Java file, lost in the ref/src transition
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13633 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-29 00:12:41 +00:00
rogerl%netscape.com
87c9e8ae4d Changed references to stdout and stderr to generic file handles so that all
output can be redirected to a file. This is needed for the mac where shell
redirection is not an option.
Added MAC_TEST_HACK that uses this redirection and also parses a text file
to build the argv/argc values.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13632 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-28 22:12:01 +00:00
fur%netscape.com
3fa38c1d6a Added a workaround for a bug in AIX JDK1.1.6 (See #331620), in which
static initializers are not run when a static field is referenced from
native code.  The problem does not manifest itself if the field is
accessed from Java code, so we first call some Java code to access
the fields of interest before attempting to read them from native code.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13621 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-28 20:22:22 +00:00
norris%netscape.com
ce487f127c Fix 331720 Continue to label in for..in doesn't work
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13612 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-28 20:13:50 +00:00
fur%netscape.com
cc1651828e We allow conversion from NaN numbers to Java integral types, but not when
the NaN is the result of conversion from a non-number, e.g. a string.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13609 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-28 17:59:10 +00:00
fur%netscape.com
22f7fd9b4a Fixed two related bugs in overloaded method resolution:
+ The precedence of java.lang.String was higher than it should have been
  + When an ambiguous method match was reported, the best-matching method
    was being left off the list.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13605 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-28 17:06:01 +00:00
mccabe%netscape.com
ad72e12927 Added proposed methods Object.prototype.hasOwnProperty,
Object.prototype.propertyIsEnumerable,
Object.prototype.isPrototypeOf... all turned off for v140 in
jsconfig.h.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13603 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-28 06:31:55 +00:00
fur%netscape.com
b6ada3318c Fix for #331634: Inability to invoke Java method when a method and field have
the same name.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13598 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-28 05:26:58 +00:00
bjorn%netscape.com
82ac5c4e2f Fixes for AIX and SunOS. AIX now compiles and runs in optimized mode as well,
and SunOS now compiles for common architecture when JS_THREADSAFE is not set.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13595 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-28 04:07:35 +00:00
wynholds%netscape.com
5430e4b688 for use with creating source jar file. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13586 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-28 02:25:31 +00:00
wynholds%netscape.com
33219cbcb1 adding shipSource target which will, yep, you guessed it, ship the source. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13582 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-28 02:03:45 +00:00
mang%netscape.com
e10c7eb54b Replace native exp on Linux opt build.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13578 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-28 00:39:25 +00:00
mang%netscape.com
70bd48b576 Math.toSource() == 'Math'
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13577 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-27 23:56:19 +00:00
bjorn%netscape.com
6bc17963c7 *** empty log message ***
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13576 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-27 23:53:01 +00:00
mang%netscape.com
168c0f6f50 Want to use some fdlibm functions but fdlibm broken on OSF1/alpha.
See bugsplat bugs 331500, 332038


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13572 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-27 23:07:40 +00:00
fur%netscape.com
eef72a91bc More LC3 features:
+ The __proto__ property of JavaObjects can be assigned and the
  prototype chain of these objects is searched, just as the engine's
  built-in js_ObjectOps routines do.  This is a featurette for the
  NGLayout DOM.

+ Static Java methods and fields can now be accessed via LiveConnect
  through an instance of a Java class, just as in Java itself.

+ Instances of java.lang.String "inherit" the standard ECMA string
  methods of String.prototype.  (All of the ECMA string methods
  convert the Java string to a JS string before operating on it.)

+ Similarly, instances of Java arrays "inherit" the standard ECMA
  array methods of Array.prototype.  (Not all of these methods work
  properly on JavaArray objects, however, since the 'length' property
  is read-only.)


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13571 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-27 22:28:03 +00:00
rogerl%netscape.com
76e06e7e4d Bug from field - unicode handling messed up with 2 or more unicode literal
characters ("i" only) - missing multiply and endian problem.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13570 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-27 21:57:10 +00:00
rogerl%netscape.com
6d03a825d3 Bug #331349, previous fix to disallow object to function conversion was too
sweeping, screwing up closures. Now we proceed with the convert if a call op
exists in the class.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13567 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-27 18:45:54 +00:00
shaver%netscape.com
9a0cc72a2d quell (spurious) warnings
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13565 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-27 16:57:19 +00:00
norris%netscape.com
6139484b7e Fix warnings.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13548 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-27 04:53:40 +00:00
fur%netscape.com
b576db0575 Eliminated gcc warnings, some spurious, some indicative of real bugs:
Spurious warnings:
jsobj.c: In function `js_EnterSharpObject':
    jsobj.c: In function `js_obj_toSource':
    jsobj.c:365: warning: `nchars' might be used uninitialized in this function
    jsobj.c: In function `obj_eval':
    jsobj.c:588: warning: `implicitWith' might be used uninitialized in this function
    jsobj.c: In function `js_DefineProperty':
    jsobj.c:1323: warning: `_c' might be used uninitialized in this function
    jsobj.c: In function `js_LookupProperty':
    jsobj.c:1394: warning: `_c' might be used uninitialized in this function
    jsobj.c: In function `js_FindProperty':
    jsobj.c:1472: warning: `lastobj' might be used uninitialized in this function
    jsobj.c: In function `js_GetProperty':
    jsobj.c:1599: warning: `_c' might be used uninitialized in this function
    jsobj.c: In function `js_SetProperty':
    jsobj.c:1645: warning: `protoid' might be used uninitialized in this function
    jsobj.c:1646: warning: `protogetter' might be used uninitialized in this function
    jsobj.c:1646: warning: `protosetter' might be used uninitialized in this function
    jsobj.c:1647: warning: `protoattrs' might be used uninitialized in this function
    jsobj.c:1665: warning: `_c' might be used uninitialized in this function
    jsobj.c: In function `js_DeleteProperty':
    jsobj.c:1939: warning: `_c' might be used uninitialized in this function

Warnings indicating real bugs:
jsobj.c: In function `js_EnterSharpObject':
    jsobj.c:252: warning: `sharpid' might be used uninitialized in this function


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13547 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-27 04:35:50 +00:00
fur%netscape.com
1858d69e49 Fixed gcc warnings (and real bugs indicated by warnings)
Spurious warnings:
jsdtoa.c: In function `JS_strtod':
    jsdtoa.c:1210: warning: `bb' might be used uninitialized in this function
    jsdtoa.c:1210: warning: `bd' might be used uninitialized in this function
    jsdtoa.c:1210: warning: `bs' might be used uninitialized in this function
    jsdtoa.c:1210: warning: `delta' might be used uninitialized in this function
    jsdtoa.c: In function `JS_dtoa':
    jsdtoa.c:1913: warning: `ilim1' might be used uninitialized in this function

Real errors:
    jsdtoa.c: In function `JS_dtoa':
    jsdtoa.c:1913: warning: `ilim' might be used uninitialized in this function
    jsdtoa.c:1915: warning: `spec_case' might be used uninitialized in this function
    jsdtoa.c:1921: warning: `mlo' might be used uninitialized in this function


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13539 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-27 03:10:55 +00:00
mccabe%netscape.com
76326b2efb Warning fix to 331245.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13536 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-27 02:53:22 +00:00
fur%netscape.com
06a7abeacf Fix allocation bug caused by use of initialized variable, discovered via gcc warning
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13531 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-27 01:21:16 +00:00
mang%netscape.com
2ae04afc70 Added section for OSF1. Fixes lots of ecma math bugs.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13526 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-27 00:18:43 +00:00
norris%netscape.com
754415d2a7 Fix "js -f x.js" for Christine.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13496 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-26 22:59:10 +00:00
norris%netscape.com
d719a6f851 Fix warnings, and clean up memory leak.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13482 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-26 21:23:56 +00:00
waldemar%netscape.com
cdcef88024 Fixed Mac warnings
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13479 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-26 21:16:28 +00:00
jband%netscape.com
34fd322859 adding READMEs
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13478 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-26 21:09:49 +00:00
jband%netscape.com
d848312079 adding a doc
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13475 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-26 20:45:49 +00:00
mccabe%netscape.com
cdc32c49b5 Fix warnings:
jsstr.c: In function `str_escape':
jsstr.c💯 warning: `mask' might be used uninitialized in this function
jsstr.c: In function `str_split':
jsstr.c:1415: warning: `limit' might be used uninitialized in this function
jsstr.c: In function `tagify':
jsstr.c:1746: warning: `parlen' might be used uninitialized in this function


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13473 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-26 20:22:17 +00:00
jband%netscape.com
93a992bb20 fixed compile error when JS_THREADSAFE used
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13470 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-26 20:13:52 +00:00
mccabe%netscape.com
256ad44f6c Quiet these warnings:
jsarray.c: In function `IdIsIndex':
jsarray.c:81: warning: `c' might be used uninitialized in this function
jsarray.c: In function `array_splice':
jsarray.c:948: warning: `obj2' might be used uninitialized in this function


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13469 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-26 20:10:29 +00:00
jband%netscape.com
c76f45fb75 adding two helper batchfiles
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13468 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-26 20:09:33 +00:00
norris%netscape.com
a7a3555cc8 Fix warnings.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13466 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-26 19:39:13 +00:00
rogerl%netscape.com
3140821cd1 #318482, recursive death arising from defining valueOf to be the this object
is now a version 1.2 feature only.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13462 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-26 19:16:08 +00:00
rogerl%netscape.com
befd55d8ba #318482, recursive death arising from defining valueOf to be the this object
is now only a version 1.2 feature, but the error mechanism needed to be
protected from failure even so.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13460 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-26 19:15:01 +00:00
norris%netscape.com
3962bfda99 Fix warnings under gcc.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13458 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-26 18:39:01 +00:00
norris%netscape.com
faca6b626e "js -f foo.js" wasn't working correctly.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13455 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-26 18:13:40 +00:00
fur%netscape.com
8c1af11605 Eliminate gcc warnings
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13452 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-26 17:41:35 +00:00
fur%netscape.com
6c8f42225c + Eliminated unused JavaMemberVal struct/type
+ Tweaked JS->Java method overload resolution
   + Don't allow JavaArrays to be passed as arguments to Java methods
     that accept scalar numeric types, since there's no meaningful
     conversion available.
   + Permit JavaObjects and JavaArrays to be passed to Java methods
     that accept a boolean argument for backward-compatibility.

+ Added explicit overload-method resolution to override ambiguous cases, e.g.
  m = java.lang.String["valueOf(char[],int,int)"]
  return m(myCharArray, 3, 7);


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13443 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-26 07:03:41 +00:00
norris%netscape.com
847bebb065 Implement X.Y.Z implementation version.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13442 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-26 05:44:04 +00:00
norris%netscape.com
2c9b897958 Fix 330840 monkey - assertion failure in import expression decompilation
Wrong length for JSOP_IMPORTELEM.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13440 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-26 05:38:22 +00:00
bjorn%netscape.com
b01cc3080f Added volatile to avoid bug in gcc
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13434 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-25 22:45:22 +00:00
bjorn%netscape.com
9cd7750dd1 move_sym_to_front avoids aliasing problem on AIX
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13432 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-25 22:17:57 +00:00
mang%netscape.com
ed9c4d7ee1 Don't use fdlibm by default.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13408 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-24 01:49:17 +00:00
bjorn%netscape.com
ceb34941c8 Changed the typedef of JSCList to work around what seems to be a bug in gcc and xlc (AIX).
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13407 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-23 23:56:29 +00:00
mang%netscape.com
f20e53875b Don't use fdlibm by default.
There can be problems with endian-ness.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13406 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-23 23:53:45 +00:00
norris%netscape.com
7c8275aae3 Use %p to print out pointer values: works better on 64 bit machines.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13405 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-23 21:35:56 +00:00
jband%netscape.com
30e0d801a7 fix default target - msdev bug in writing out .mak file!
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13397 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-23 20:34:18 +00:00
fur%netscape.com
a899984e09 Added fdlibm
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13393 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-23 19:43:52 +00:00
coop%netscape.com
54e5a64304 Constructors are once again public, but have been marked as deprecated so
that people won't get too fond of using them.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13392 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-23 19:23:36 +00:00
fur%netscape.com
4016979d0d Added fdlibm
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13391 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-23 19:16:28 +00:00
fur%netscape.com
663693cafe Ignore .pdb files
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13388 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-23 18:24:44 +00:00
wynholds%netscape.com
aed4dd4310 fixing NT build with new fdlibm stuff and an old error gone unnoticed until now. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13379 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-23 17:30:41 +00:00
norris%netscape.com
6c7c73d822 Fix 330845 digital unix: arithmetic exception in string stuff:
Expression "argv[argc-1]", where argc == 0 and argc was a 32 bit unsigned quantity,
was causing a memory exception on the 64 bit machine because it was evaluating as
argv[0xffffffff] rather than argv[-1].


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13376 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-23 16:51:08 +00:00
wynholds%netscape.com
28c93d2218 fixing fdlibm stuff. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13374 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-23 16:35:58 +00:00
norris%netscape.com
ca95b9b63a Add patch number.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13373 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-23 15:35:41 +00:00
mang%netscape.com
67d738630a Landing of MANG_MATH_10231998
Replaces many system math routines with ECMA/IEEE compliant routines
from fdlibm.
These new routines are big and slow, so there are platform specific
defines in jslibmath.h that determine which fdlibm routines to use.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13372 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-23 10:16:50 +00:00
(no author)
f018a06aa7 This commit was manufactured by cvs2svn to create branch
'SpiderMonkey140_BRANCH'.

git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13371 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-23 09:14:03 +00:00
norris%netscape.com
eb89b3d136 Fix 330071 Remove catch condition support from 1.4
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13364 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-23 05:51:29 +00:00
wynholds%netscape.com
6c156d7134 fixed ship target to correctly take into account any variation of JS_THREADSAFE and JS_LIVECONNECT. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13354 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-23 01:20:32 +00:00
mccabe%netscape.com
7f123a804d Sigh. Turn of reflection of runtime errors as exceptions.
Because the immediate demand for it in the client seems to have
lessened somewhat, and because it makes our cross-engine story make
more sense for external customers if we wait 'till it's implemented
for both engines.

Also, attempting to make exceptions work cleanly in a cross-context way
turned out to be difficult; it probably makes sense to take a step
back and look at how to find the best solution for the long term
development of the language.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13353 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-23 00:37:15 +00:00
wynholds%netscape.com
ec0edbcba0 adding HPUX 10.20 config makefiles. they are just copies of HPUX 10.10 makefiles. hope they work. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13351 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-23 00:30:46 +00:00
norris%netscape.com
2687debc8e Fix bug 330462 monkey: decompilation of comma op causes ASSERT/script failure
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13347 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-22 23:55:09 +00:00
mccabe%netscape.com
5fb184d473 Another fix to 329807.
Rather than nulling out the error reporter during the execution of
'load', replace it with a new error reporter that ignores all error
reports with the JSREPORT_EXCEPTION flag set.

Also fix a bug in jsexn.c where I was failing to actually set that
flag, and Eich-ify a few curly-brace placements.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13313 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-22 19:55:11 +00:00
mccabe%netscape.com
4885772ba8 Fix to 330589. Back out a tree-rewriting of foo[0] -> foo.0 because
the resulting code decompiles to foo.0.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13301 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-22 03:44:56 +00:00
rogerl%netscape.com
3d0da2df12 Bug #310514 - for eror report on calling toString on a not-function, was
calling toString to get the name of the object. Duh. Now calls getTypeName.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13290 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-22 00:05:16 +00:00
rogerl%netscape.com
030655be79 Bug #324451 - eval was bailing out early if the arg was not a string, and
so skipping the indirect-eval check.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13289 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-22 00:01:49 +00:00
fur%netscape.com
c21e3de07e Match changes in Makefile for auto-generating jsautocfg.h
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13279 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-21 21:43:59 +00:00
mccabe%netscape.com
f654a47a49 Fix to 329807.
'load' in the shell makes 'toplevel' calls to the js interpreter, so
the mechanism for detecting and reporting uncaught exceptions at the
top level kicks in prematurely.  To work around this problem, I set
the error reporter to NULL.  A better fix might be to use a custom
error reporter for load that knew to ignore exception error reports,
expecting that the javascript context calling load would catch or
report them.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13276 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-21 20:52:43 +00:00
norris%netscape.com
c11ef38890 Fix 330074 arguments object uses Array.prototype.toString
Unfortunately, I can see no way to version this behavior.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13275 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-21 20:45:41 +00:00
norris%netscape.com
d8f121d794 Better debugging code for printing objects.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13273 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-21 20:19:46 +00:00
rogerl%netscape.com
47f4088f27 Bug #330051 - previous fix for end of string with empty sep. should have
been 1.2 only and should have set the sep->length to 1 in order to break
out of the split loop.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13264 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-21 18:02:24 +00:00
rogerl%netscape.com
9d8444be44 Plugging a memory leak whenever an error is reported.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13261 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-21 17:54:30 +00:00
wynholds%netscape.com
0bd94e4384 CFLAGS needs to be +='ed, not ='ed. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13206 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-20 17:02:13 +00:00
wynholds%netscape.com
e0a486e300 need another include directory in liveconnect directory. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13205 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-20 16:47:16 +00:00
fur%netscape.com
4bf9c6a227 Fixed INCLUDES problem when JS_THREADSAFE is set
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13199 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-20 15:32:46 +00:00
fur%netscape.com
3277bdac18 Auto-generate jsautocfg.h instead of using checked-in jscpucfg.h file
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13192 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-20 07:32:26 +00:00
fur%netscape.com
87c868ffbe Improve clobber rule
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13191 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-20 07:31:21 +00:00
fur%netscape.com
5f6bbab561 Eliminate dependency on jscpucfg.h for Windows
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13186 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-20 05:00:16 +00:00
fur%netscape.com
55cebfe0cb It turns out that even though we were generating jscpucfg.h, we weren't
using it.  Rather the static, checked-in version was being used.  Fixed, now.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13185 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-20 04:42:33 +00:00
fur%netscape.com
26c815ff77 Generate jscpucfg.h on Unix platforms rather than relying on per-platform
static definitions.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13181 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-20 03:24:47 +00:00
fur%netscape.com
facfc365cb Ignore generated files
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13143 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-20 00:09:26 +00:00
fur%netscape.com
63ace590d6 Get rid of -D_SVID_GETTOD
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13142 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-19 23:59:29 +00:00
mccabe%netscape.com
31c250eee9 Fix from Joe Keane to avoid reiniting the scanner except when
necessary.  Thanks!

From: Joe Keane <jgk@jgk.org>  Fri 19:11
Subject:                       Re: JS_SetVersion not
To:                            Mike McCabe <mccabe@netscape.com>

The main caller i saw was libmocha.  In `win_run_timeout', it calls
`JS_SetVersion' twice every time there's a JavaScript timeout; it sets
the version before running the expression, then it sets it back when
it's done.  It looks like a couple times per second, not the worst
thing in the world, but nice to get rid of if it's easy enough.

I had some question about whether it's doing something dumb and it can
be improved.  This may be true, but there are some other callers, for
example it gets called indirectly by `PL_HandleEvent'.  Overall it
seems like a simple and pretty right thing to do anyway.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13134 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-19 22:15:39 +00:00
jband%netscape.com
60b5308f58 Added JSD support for DebugErrorHook
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13069 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-17 06:18:16 +00:00
jband%netscape.com
d2b9c6a168 - added 'DebugErrorHook' which (when present) is called before the ErrorReporter. And in cases where an error exception is raised but the ErrorReporter is not called. This allows for the debugger catching errors when they happen that the ErrorReporter will not now see until they become uncaught errors. This also simplifies the debugger by not having it try to track an ErrorReporter chain. This now works more like the Rhino system.
- #if 0'd js_ReportCompileError which is no longer used (replaced by js_ReportCompileErrorNumber). I'm all for cutting this out of the codebase. Shall we just do that?


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13061 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-17 02:26:19 +00:00
jband%netscape.com
b6525cde8b fix script leakage if !JS_HAS_ERROR_EXCEPTIONS
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13060 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-17 02:11:27 +00:00
bjorn%netscape.com
c4741a81fe Made cc be the default.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13022 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-16 21:47:52 +00:00
bjorn%netscape.com
0649a670ac Moved declaration of FAR to satisfy 'cc' on Dec Unix.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@13020 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-16 21:45:44 +00:00
bjorn%netscape.com
d418df2eb7 Extra config stuff for cc on OSF.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12998 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-16 18:16:26 +00:00
bjorn%netscape.com
e86bd6fd57 switch for OSF1.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12997 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-16 18:13:53 +00:00
jband%netscape.com
6d79b5ec64 fix 'typedef struct' redefinition - problem for jsd too before it becomes a build issue
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12992 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-16 10:36:20 +00:00
jband%netscape.com
46800959c2 fix build bustage on Unix due to 'typedef struct' redefinition - the Windows compiler didn't mind
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12991 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-16 10:26:22 +00:00
mccabe%netscape.com
e29596b37b Fix the javascript-visible Exception constructor to make objects of
jsclass Exception.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12987 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-16 09:34:29 +00:00
mccabe%netscape.com
1419ca574a Make the toSource stuff #if JS_HAS_TOSOURCE
Viva jsconfig.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12985 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-16 09:21:22 +00:00
jband%netscape.com
e5892b8370 Added support for throw hook. Added locals() and args() to jsdb to demonstrate/test JSDValue/JSDProperty stuff
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12972 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-16 04:07:41 +00:00
jband%netscape.com
60fe37f18d added save/restore/drop of JSExceptionState. This allows opaque scheme for doing evals and stuff on a context without screwing up the state of the exception information. This helps now with rooting the saved exception and will help more later if additional hidden exception information is added to the context; e.g. source location of thrown exception, etc. Also added throw hook. This is necessary since the relationship between the exceptions and error reporter changed
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12971 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-16 04:03:46 +00:00
fur%netscape.com
98c0f47746 Fix AIX build bustage
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12970 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-16 03:58:25 +00:00
fur%netscape.com
55a926e2c4 Fix gcc warning
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12969 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-16 03:58:07 +00:00
fur%netscape.com
f7387ecdae Fix gettimeofday() on Solaris for the umpteenth time
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12968 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-16 03:51:56 +00:00
fur%netscape.com
ecf83e4f36 + HAVE_LONG_LONG ==> JS_HAVE_LONG_LONG, so as to avoid conflict with NSPR
macro of the same name.
+ Changed JS_HAVE_LONG_LONG to be defined on Linux, since we compile with
  gcc on that platform.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12963 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-16 03:42:06 +00:00
bjorn%netscape.com
7d02cdd1c2 changed from int to unsigned int in alignment code.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12921 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-15 21:06:57 +00:00
mang%netscape.com
0bd5df16b7 Include jsfile.h only when building with JS_HAS_FILE_OBJECT
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12917 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-15 20:55:02 +00:00
mccabe%netscape.com
145eb6f922 Toss the cx->exceptionProtos vector and go to looking up exception
prototypes by using the the constructor names in the current context.
This has some failure modes if users have overwritten the
constructors, but they seem tolerable:

js> sil
1: ReferenceError: sil is not defined
js> ReferenceError = 'foo'
foo
js> sil
3: Exception: sil is not defined
js> Exception = 'bar'
bar
js> sil
5: [object Exception]


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12878 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-15 08:46:59 +00:00
mccabe%netscape.com
f98b15d6d3 Update js.c from the previous behavior of ignoring errors tagged as
exceptions - this caused toplevel compile errors to be ignored.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12877 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-15 08:35:03 +00:00
fur%netscape.com
da9f65325b Propagated changes from JS_STABLE_10131998_BRANCH, required to build mozilla.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12861 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-15 03:07:09 +00:00
mang%netscape.com
25bbd958a9 Now duplicate string instead of trying to modify read-only memory on Unix
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12860 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-15 02:58:12 +00:00
bjorn%netscape.com
3e8f4b2074 Change so that the local structure used to represent a JS pointer is aligned
modulo 8 rather than 4.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12852 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-15 01:22:15 +00:00
mang%netscape.com
6547ff01ff Added NPL
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12834 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-14 22:04:23 +00:00
wynholds%netscape.com
dd55af2615 xlC_r on AIX seems to not be able to hand C++ comments. seems kinds stupid, but what the hell? so i changed it to a C-style comment. no hard no foul.
-mw


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12831 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-14 21:42:37 +00:00
wynholds%netscape.com
619f867c2d ship target now supports JS_LIVECONNECT to be defined or undefined. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12829 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-14 21:36:29 +00:00
rogerl%netscape.com
2ffc6eb8cf Bug #315139 - for character split and empty separator, return string length
for end of string.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12828 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-14 21:32:11 +00:00
rogerl%netscape.com
444ed356ed Fix precedence issue (inappropriate distributive use)
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12826 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-14 20:58:31 +00:00
mccabe%netscape.com
ad709b1cfa GC_MARK the pending exception as a GCTHING rather than as a jsval
during garbage collection.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12794 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-14 07:13:34 +00:00
mccabe%netscape.com
90dc42fec0 Fix warnings.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12714 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-13 19:44:39 +00:00
mccabe%netscape.com
7b3a25dde6 Further work on errors as exceptions -
Changes to js.c back out much of the error-checking code of the
previous checkin; proper exception handling now requires fewer changes
to the host.

Exception prototypes are per-context, with no way (yet) to have
instanceof work properly with exceptions from other contexts.
Per-runtime prototypes (to make instanceof work naturally) worked OK,
but sealing these objects to prevent leaking information between
threads turned out to be hairy.  (Because Exception.prototype.toString
needed sealing too...)

Errors for which a corresponding exception is thrown are suppressed,
and compile errors are always suppressed except at the top level.
Entry functions in jsapi.c now detect failure of calls to the
interpreter and call the error reporter if an exception was raised;
exception-savvy hosts may provide an error reporter that ignores these
reports by checking JSREPORT_EXCEPTION in the report flags.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12686 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-13 09:58:28 +00:00
mang%netscape.com
3b086e1130 JS File Object (not fully implemented yet)
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12662 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-13 03:20:37 +00:00
jband%netscape.com
43ea6c73ea Added reflection of JSDValue, JSDProperty, and JSDObject stuff to jsdb. Initial support for this in debugger.js
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12646 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-13 01:02:25 +00:00
jband%netscape.com
8b37303301 added a comment
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12644 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-13 00:57:53 +00:00
bjorn%netscape.com
a9d4091b08 Updated js_list_scope_lookup() to use void pointers for casting, instead
of JSSymbol. This removed a problem on AIX where the compiler shuffled
code around, thinking that it was safe to do so. Waldemar helped me
track this one down.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12638 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-13 00:17:36 +00:00
fur%netscape.com
0e74fd5849 Merge changes from trunk
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12621 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-12 22:32:49 +00:00
fur%netscape.com
9bbc9990a2 Fix JS_FRIEND_DATA for Mac
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12614 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-12 22:12:08 +00:00
fur%netscape.com
5cea729be2 Updated file for JS1.4
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12606 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-12 21:01:57 +00:00
fur%netscape.com
c7838f766a Get rid of obsolete files
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12588 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-12 18:40:42 +00:00
norris%netscape.com
d6adc823ec Fix bug 299903 Inheriting from a Date object causes crash
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12582 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-12 17:54:44 +00:00
fur%netscape.com
65fea2e956 Remove out-of-date MSVC5 project files
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12580 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-12 17:37:11 +00:00
fur%netscape.com
bc6d33a86b Get rid of isatty() warning on Windows
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12577 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-12 16:43:17 +00:00
(no author)
f9446c3323 This commit was manufactured by cvs2svn to create branch
'SpiderMonkey140_BRANCH'.

git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12554 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-12 08:05:38 +00:00
fur%netscape.com
f2dde02af9 1) Fixed bug in which incorrect netscape.javascript.JSException constructor
was being called when wrapping JavaScript exception objects thrown as
   a result of evaluating JavaScript from Java.

2) Implemented improved LiveConnect overloaded method resolution as described
   in the spec: http://www.mozilla.org/js/liveconnect/lc3_method_overloading.html
   (Explicit method specification not yet implemented, however).


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12551 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-12 07:32:14 +00:00
jband%netscape.com
41ebf8c0e0 Added type info to handles to support automatic 'dropping' of JSDValues (to be supported soon). Added name prop to handles to avoid toString having to repeatedly create the name on the fly. Also misc cleanup.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12545 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-12 02:39:27 +00:00
fur%netscape.com
ab971b977f Changed files for building JS for Mac after js ref/src merge
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12499 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-10 03:17:19 +00:00
fur%netscape.com
9c77f182aa Fix use of uninitialized variable.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12498 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-10 03:16:23 +00:00
fur%netscape.com
b25aef6c55 Privatize some names that conflict with NSPR identifiers missed in the first round of js ref/src merging.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12497 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-10 03:13:38 +00:00
fur%netscape.com
a82b563a25 Kill Mac warnings
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12496 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-10 03:11:30 +00:00
jband%netscape.com
02314c78f6 turn off debug tracing output
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12490 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-10 02:23:56 +00:00
jband%netscape.com
425d07341a added JSObject tracking system that supports iterating all JSObjects with info about the source line that created them and the source line and name of their constructors
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12488 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-10 02:10:07 +00:00
fur%netscape.com
268dfb88cb Fix to make JSObject native methods load on unix
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12485 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-10 00:53:33 +00:00
fur%netscape.com
bc2ec58a7b Get rid of outdated Java implementation of JSObject.equals(). It was replaced by native code a long time ago.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12483 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-10 00:53:05 +00:00
fur%netscape.com
cf373daa53 Don't use deprecated PrintStream API
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12482 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-10 00:52:03 +00:00
coop%netscape.com
7fe8465ded Changed constructor JSException(Object) to public so that Java users can
throw exceptions to JS cleanly.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12427 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-09 15:38:08 +00:00
mccabe%netscape.com
37ec2963c9 Added NPL.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12421 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-09 08:11:32 +00:00
fur%netscape.com
5ea0bc5e25 Revert to my non-standard, but more tabular white-space formatting
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12385 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-09 01:17:24 +00:00
fur%netscape.com
a492c3a964 Fix for #328274 (Unable to pass JS objects to Java)
Thanks to coop for noticing the problem.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12384 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-09 01:16:45 +00:00
rogerl%netscape.com
a256793772 #324451 - disallow indirect calls to eval
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12367 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-08 23:51:18 +00:00
rogerl%netscape.com
fa7759865b #324451 - if eval not invoked with CALLSPECIAL, then complain that it was
called indirectly, not allowed for new ECMA.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12366 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-08 23:50:06 +00:00
rogerl%netscape.com
7a57c4b47a #324451 - CALLSPECIAL opcode for detecting indirect calls to eval
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12365 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-08 23:48:57 +00:00
rogerl%netscape.com
a2ebae060e #324451 - detect direct call of eval and use CALLSPECIAl opcode instead
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12364 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-08 23:48:14 +00:00
rogerl%netscape.com
a8dc44aaa9 #324451 - Added callSpecial opcode to identify indirect eval calls
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12363 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-08 23:46:29 +00:00
rogerl%netscape.com
3c18b0c3ba #324451 Added eval to atomState so that we can detect indirect calls to eval
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12362 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-08 23:42:03 +00:00
coop%netscape.com
c122de69b8 Made all constructors private.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12347 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-08 21:57:30 +00:00
coop%netscape.com
4a3d57e324 Changed references to JSWrappedException to point to JSException instead.
Fixed nesting for vreport_java_error that prevented pending exception from
being set or cleared properly.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12306 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-08 20:16:51 +00:00
coop%netscape.com
a3f846bbf0 Changed references to JSWrappedException to point to JSException instead.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12305 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-08 20:12:36 +00:00
coop%netscape.com
189fd42355 JSWrappedException: removed
JSException: now extends RuntimeException
	     added Object wrappedException
	     added new constructor that takes an Object
	     added instance method getWrappedException(), returns wrappedException.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12304 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-08 20:08:01 +00:00
jband%netscape.com
63410ef469 added debug hook for notification of JSObject new and finalize
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12229 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-07 22:07:37 +00:00
norris%netscape.com
7f25afca90 Sigh. Back out fix that caused regressions.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12224 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-07 21:34:44 +00:00
jband%netscape.com
81d08cb271 support for resume with returnVal or throwVal
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12148 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-07 01:55:53 +00:00
jband%netscape.com
deefcc6b8d support for throwing from hook, prep for client checkin: fix locks, mods to makefile.win
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12147 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-07 01:52:25 +00:00
jband%netscape.com
e9b1c82736 added JSTRAP_THROW -- support for throwing an exception from any of the three kinds of interpreter hooks: interrupt, pc trap, debugger keyword
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12146 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-07 01:39:30 +00:00
wynholds%netscape.com
27a80cf6d2 some hacky stuff to get NT building right with gmake -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12141 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-07 01:15:11 +00:00
mccabe%netscape.com
1022f9e0ce Initialize cx->throwing to JS_FALSE #if JS_HAS_EXCEPTIONS!
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12139 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-07 00:54:26 +00:00
jband%netscape.com
c9bb9195dd only call JS_DestroyScript on non-NULL script in shell Load
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12138 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-07 00:43:20 +00:00
wynholds%netscape.com
095999e32b getting NT stuff build build EXEs correctly/at all -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12136 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-07 00:40:51 +00:00
wynholds%netscape.com
d76a5a9080 oops, typo for HP package. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12127 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-06 23:52:55 +00:00
wynholds%netscape.com
a70e9a2aaa NT executables end in .exe ! -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12126 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-06 23:51:33 +00:00
wynholds%netscape.com
e359fd71fc HP uses libnspr21.sl -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12124 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-06 23:47:50 +00:00
wynholds%netscape.com
04e1b5c3d1 NT uses a different nsinstall (built into shmsdos.exe) -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12122 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-06 23:44:53 +00:00
wynholds%netscape.com
fa2407ee2e don't forget this header file. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12121 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-06 23:32:06 +00:00
wynholds%netscape.com
49bb4bd95c package the right files on NT. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12120 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-06 23:30:18 +00:00
wynholds%netscape.com
3c49adc57b packaging libnspr21.so now. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12116 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-06 23:26:34 +00:00
wynholds%netscape.com
3f7cdf786b only use EXPORT_JS_API while building libjs.dll -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12113 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-06 23:07:41 +00:00
wynholds%netscape.com
78fba657bd LOOP_OVER_DIRS now can go only one level deep at a time -m
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12112 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-06 23:05:04 +00:00
wynholds%netscape.com
5b6a656e48 now NT's link line will create the right .lib and .pdb -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12091 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-06 21:42:00 +00:00
wynholds%netscape.com
fbbe5d2674 we need to use a JDK built especially for HP-UX10 (not 11) because on 11 it links with libm.sl.2, and on 10 it links with libm.sl.1. anyway, on 10, we don't have libm.2 so we obviously need the right one. i put it in /share/builds/components/jdk/1.1.5/HP-UX10/... -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12086 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-06 21:23:42 +00:00
wynholds%netscape.com
d9d717001f using cc instead of gcc (stupid gcc on HP). -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12085 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-06 21:21:08 +00:00
wynholds%netscape.com
1dde42d623 HP has to use native c compiler now, but hey, gcc just wasn't cutting it. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12049 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-06 19:39:46 +00:00
wynholds%netscape.com
1ed0446da5 get the link line right for NT. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12046 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-06 16:29:47 +00:00
wynholds%netscape.com
3fd73fdffd jsref_opt.jar and jsref_dbg.jar -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12045 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-06 16:18:16 +00:00
wynholds%netscape.com
cfa1a86909 a fix for UNIX on LOOP_OVER_DIRS -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12044 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-06 15:53:36 +00:00
coop%netscape.com
6b78529f1f Removed references to getWrappedException java method.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12043 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-06 14:46:50 +00:00
norris%netscape.com
4fd0fc55ca Fix bug 327540 "monkey: crash in some negative tests"
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@12025 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-06 04:08:25 +00:00
norris%netscape.com
b1e460a74a Fix 325843 "function f(a){var a,b;} asserts/crashes"
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11980 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-06 00:26:15 +00:00
wynholds%netscape.com
a5a20628a0 HP 10.10 stuff -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11977 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-06 00:19:22 +00:00
wynholds%netscape.com
d9eb58cdec need this to get HP linking. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11976 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-06 00:18:34 +00:00
wynholds%netscape.com
037c43596e uses reltools now
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11974 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 23:59:25 +00:00
wynholds%netscape.com
79b38ca130 get liveconnect building on NT
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11973 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 23:52:02 +00:00
wynholds%netscape.com
2f59039158 NT specific stuff
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11972 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 23:50:12 +00:00
wynholds%netscape.com
d32e31eda5 make DIRS NT friendly
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11971 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 23:49:23 +00:00
wynholds%netscape.com
ccf4b130af links correctly with NSPR on NT
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11970 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 23:46:20 +00:00
coop%netscape.com
c66acfa187 JSWrappedException wraps a JavaScript exception in a java.lang.Object wrapper.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11968 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 23:39:09 +00:00
coop%netscape.com
89d32f85be Removed "if 0"s referencing JSWrappedException code.
Changed references to JSWrappedException to reflect changes to that objects
structure, ie. JSWrappedException now contains a java.lang.Object instead
of an integer.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11967 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 23:35:22 +00:00
coop%netscape.com
0f8d890868 Removed "if 0"s referencing JSWrappedException code.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11966 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 23:32:28 +00:00
coop%netscape.com
3c8ae5aafe Removed "if 0"s referencing JSWrapped exception code.
Changed throw_any_pending_js_error_as_a_java_exception to reflect the
new make-up/construction of JSWrappedException (contains an java.lang.Object
instead of an integer).


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11965 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 23:31:35 +00:00
coop%netscape.com
f909920e91 Removed "if 0"s for references to JSWrappedException.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11963 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 23:27:26 +00:00
wynholds%netscape.com
ad73f38c85 installing programs to dist/bin directory now, and giving the owner write permissions. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11945 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 21:58:28 +00:00
wynholds%netscape.com
e18fa8a56f added ship target for packaging. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11944 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 21:57:50 +00:00
wynholds%netscape.com
e81b4d3657 this is the right config file for DEC, not dgux.mk. i dunno what version of uname that comes from. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11940 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 21:23:13 +00:00
wynholds%netscape.com
19c49a56be get DEC building -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11939 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 21:22:33 +00:00
wynholds%netscape.com
3e2489f92c point to java stuff for HP. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11934 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 20:55:29 +00:00
wynholds%netscape.com
b9e217c7e8 get HP 11 to link shared libraries. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11933 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 20:53:57 +00:00
wynholds%netscape.com
940ee6966f using /share/builds/components/jdk/1.1.6/IRIX instead of /usr/java so everybody can use it!. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11925 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 19:30:18 +00:00
wynholds%netscape.com
13337f0a89 using /share/builds/components/jdk/1.1.6/IRIX instead of /usr/java so we can all use it! -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11924 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 19:29:04 +00:00
wynholds%netscape.com
aabb8920ae need to hack AIX 4.1 to grab 4.2 because 4.1 doesn't exist. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11918 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 19:15:11 +00:00
wynholds%netscape.com
bd32e33753 trying to get AIX 4.1 to build, but no real luck yet. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11917 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 19:13:14 +00:00
wynholds%netscape.com
c68e984b99 link with libdl.a when doing threadsafe builds (NSPR needs it). -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11912 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 18:34:01 +00:00
wynholds%netscape.com
35b4a8183d get AIX 4.1.5 building. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11911 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 18:33:22 +00:00
wynholds%netscape.com
f746d5d6c5 added SunOS5.6.mk file to get it building. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11910 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 18:07:21 +00:00
wynholds%netscape.com
dccd95eeaa new target to grab NSPR from /share/builds/components. for use with JS_THREADSAFE standalone builds. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11909 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 17:46:30 +00:00
mccabe%netscape.com
0dc9a5a868 Be more paranoid in various ways about properly handling exceptions,
from compilation or execution.  Load is now somewhat more exception-savvy.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11899 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 09:56:06 +00:00
mccabe%netscape.com
f46f66eea8 Change some engine semantics to propagate exceptions better.
js_DefaultValue and a few other places used js_TryMethod,
js_TryValueOf.  The return value of these functions was always ignored
(well, was void) even if they found a method to call and that method
raised an exception.  As a result, functions like valueOf which might
have been user-defined to throw an exception didn't end up propagating
the exception.

I changed js_TryMethod, js_TryValueOf, and JS_ConvertStub (which calls
js_TryValueOf) to propagate failure.  Note that they'll still succeed
if they fail to find an appropriate method value to call.  (so 'Try'
still means something in this context.)  js_DefaultValue now uses
these return values to decide how to proceed.

As a result js_DefaultValue and obj->convert now may fail in a few
places where they previously did not.  I think that this is best in
terms of making the engine interpret a consistent language, but it
might trip us up on old code.  Fingers now crossed.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11898 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 09:40:59 +00:00
mccabe%netscape.com
8ade5f78d3 If compiletime errors are already reflected as exceptions, suppress
any compiletime errors that don't occur at the top level.  The intent
is to retain as much as possible the existing behavior of giving
multiple compile error messages for toplevel compiles.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11897 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 09:16:07 +00:00
mccabe%netscape.com
58a8a3d984 Only look for enclosing try/catch statements on abrupt frame exit when
returning failure with a pending exception, not just when there's a
pending exception.  (The pending exception could have been an
uncleared exception another script in the same context.)


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11896 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 09:07:48 +00:00
mccabe%netscape.com
e539af4e6f Fix to 318250. Disable an assert that was firing for a
default-value-throws-exn object used in an expression.  Code exists to
handle the case for which the assertion failed, but it was effectively
disabled in debug builds.  Anybody know the history of this one?


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11895 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 08:17:48 +00:00
norris%netscape.com
27e172913a Fix 299903 Inheriting from a Date object causes crash
and Actra global regexp problem (Function clone of regexp object because
it is of type Function).


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11894 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-05 06:32:34 +00:00
fur%netscape.com
b54505be31 Changed PR_* to JS_* names
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11890 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-04 23:18:51 +00:00
fur%netscape.com
2433dae015 Propagating README from js/ref
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11889 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-04 23:16:44 +00:00
mccabe%netscape.com
c2bcde8466 Only raise an exception for the first syntax error that's reported on
any given compile.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11843 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-03 03:27:13 +00:00
mccabe%netscape.com
90fb1dfb90 Comment fix.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11842 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-03 03:23:08 +00:00
val4%cornell.edu
132d1f5b26 Minor modification to readme reflecting the changes in the directory structure.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11791 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-02 19:42:37 +00:00
val4%cornell.edu
4c69c950da Looks like CRs on this file were scred up, which didn't allow MSDEV to
open them properly. Hopefully, it will work now.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11781 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-02 18:35:59 +00:00
coop%netscape.com
d5329cfd00 Added NPL.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11772 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-02 15:30:56 +00:00
coop%netscape.com
83cb0cf419 Added code to vreport_java_error that reports, sets and clears JS exceptions
based on the type of java exception encountered. Parts referencing
JSWrappedException are currently commented out.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11771 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-02 15:30:11 +00:00
coop%netscape.com
d3eee3f5c6 Added extern references for class JSWrappedException. Currently commented out.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11770 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-02 15:27:48 +00:00
coop%netscape.com
c78787a61a Added code to throw_any_pending_js_error_as_a_java_exception which
wraps an exception in a JSWrappedException wrapper. Currently commented
out.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11769 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-02 15:26:18 +00:00
coop%netscape.com
fd99e42a1e Added references (jclass, jmethodID, etc.) for JSWrappedException class.
Class does not currently exist, so references are commented out.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11768 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-02 15:23:46 +00:00
coop%netscape.com
f536714915 Added NPL for all classes.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11767 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-02 15:21:41 +00:00
shaver%netscape.com
16977a5881 fix Linux build of shared JS
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11740 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-02 02:02:23 +00:00
(no author)
d58d92ba30 This commit was manufactured by cvs2svn to create branch
'SpiderMonkey140_BRANCH'.

git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11725 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-01 23:57:01 +00:00
bjorn%netscape.com
70aa311f1a Some final touches to the make system, just when you thought they
were all over... I got rid of the silly JS_STATIC. More pain than
pleasure, really.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11713 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-01 22:11:21 +00:00
wynholds%netscape.com
d6d4547e60 adding nsinstall-target target which will build the nsinstall executable needed for gmake export. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11678 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-01 19:32:00 +00:00
bjorn%netscape.com
cddb4bee49 Changed environment flag from JS_THREADSAFE to USE_NSPR.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11670 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-01 17:53:22 +00:00
bjorn%netscape.com
215e4f521a Added '+' to CFLAGS definition.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11649 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-01 04:52:28 +00:00
bjorn%netscape.com
b374ece734 Added JS_STATIC flag which, when set, links LiveConnect statically with JS.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11648 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-01 04:47:20 +00:00
bjorn%netscape.com
db88d15e60 IRIX 6.2 support for LiveConnect.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11620 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-30 23:30:52 +00:00
bjorn%netscape.com
17a3a3fede IRIX6.2 support.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11619 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-30 23:30:14 +00:00
bjorn%netscape.com
802ea94da2 Changes to make export work from inside liveconnect.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11618 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-30 23:28:20 +00:00
bjorn%netscape.com
87987c22eb LC support for IRIX.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11617 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-30 23:24:05 +00:00
mccabe%netscape.com
92e75b047c Fix to 320443. Restructure jsinterp.c to always check a raised
exception against any enclosing try statement within the current frame
before attempting to return from the frame.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11612 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-30 22:34:13 +00:00
bjorn%netscape.com
d72d172d7a Fixes to properly generate the executable 'jsj'.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11611 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-30 22:33:44 +00:00
rogerl%netscape.com
8e7b173eef ErrorNumber handling changes to support UC
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11607 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-30 21:51:59 +00:00
rogerl%netscape.com
d898e8430d Fixed bug #104766. DecompileFunctionBody needs to set the scope in its
JSPrinter arg.
Changed error number handling code to support UC version as well.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11606 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-30 21:50:52 +00:00
rogerl%netscape.com
55edce6a15 Fixed bug #104766. DecompileFunctionBody needs to set the scope in its
JSPrinter arg.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11603 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-30 21:48:00 +00:00
rogerl%netscape.com
f962f59ccc Fixing bugs #310514, 310502 - calling function.toString, .call & .apply
on non-function objects now results in a runtime error.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11599 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-30 21:30:26 +00:00
bjorn%netscape.com
75187e5e57 DIST is now a variable set in Makefile.ref so that the export rule
can be made to export to a chosen directory.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11572 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-30 18:13:50 +00:00
bjorn%netscape.com
3522f2112e Removed JDK include.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11566 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-30 17:14:29 +00:00
bjorn%netscape.com
b2bc5afac7 New support for AIX.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11565 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-30 17:14:12 +00:00
bjorn%netscape.com
1b857628d4 AIX 4.2 make support.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11564 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-30 16:59:47 +00:00
fur%netscape.com
4034d6af4c Added MKSHLIB macro
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11528 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-30 03:45:54 +00:00
bjorn%netscape.com
1d5e647e2c Added includes.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11527 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-30 03:10:19 +00:00
bjorn%netscape.com
2aabababd7 New support for standalone make system.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11526 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-30 03:08:00 +00:00
fur%netscape.com
024311a2ab Fixed an incorrect assertion that I believe was intended to confirm that
all JS roots pointed into the GC'able JS arena, but which wasn't coded correctly.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11525 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-30 03:03:15 +00:00
mccabe%netscape.com
55fcddec90 Changed some remaining messages from js_ReportCompileError(<hardcoded
string>) to js_ReportCompileErrorNumber(<error number>).  To make
runtime exceptions work for lexical errors, because the mechanism
piggybacks off of js_ReportCompileErrorNumber.

Also propagated a free->JS_free change.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11522 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-30 01:53:45 +00:00
bjorn%netscape.com
0c95c94909 Fixes to the assembly for SPARC v8, and to accommodate for new source
tree.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11478 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-29 23:32:29 +00:00
bjorn%netscape.com
8da98334c6 Fixed the test when the pointer is busy (tst -> cmp)
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11474 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-29 23:18:26 +00:00
shaver%netscape.com
defa10fc43 added Linux config file
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11469 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-29 22:54:37 +00:00
bjorn%netscape.com
f0cdddb20c Changed assertion in CompareAndSwap to look for nv != -1.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11465 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-29 22:47:27 +00:00
fur%netscape.com
a17e03c381 Re-fixed comment
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11419 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-29 20:35:44 +00:00
shaver%netscape.com
595794ecfe don't overwrite catchall jump with rethrow address
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11414 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-29 19:14:36 +00:00
shaver%netscape.com
1a0b1b8a29 fix catchall-after-catchguard spurious error
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11347 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-29 09:50:04 +00:00
fur%netscape.com
670d4d69fa Moved from js/ref to js/src
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11326 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-29 05:56:30 +00:00
fur%netscape.com
c5a6bb1af7 Migrated LiveConnect from js/ref to js/src.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11325 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-29 05:55:25 +00:00
jband%netscape.com
00a574acf2 added call to new JSD unicode function JSD_AppendUCSourceText to simplify shell and remove truncation hackery (which really just got pushed into JSD)
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11257 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-28 20:37:22 +00:00
jband%netscape.com
68900225d1 - removed MY_XP junk, abandon Win16, assume that realloc works
- removed HACK_FOR_OLD_JS
- made JS_LOWLEVEL_SOURCE work in jsdb
- added Unicode JSD_AppendUCSourceText to simplify shells
- some gratuitous whitespace reformatting


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11256 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-28 20:34:46 +00:00
mccabe%netscape.com
97a1eacae2 Propagate mcafee fix: Added Rhapsody to the long list of OS's that
can't handle localtime_r().


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11235 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-28 19:41:17 +00:00
jband%netscape.com
1061a7961a Source notes for line numbers are generated at the top of js_EmitTree. The code generation in the TOK_TRY case was bypassing this code (i.e. emitting code for source lines before recursing into js_EmitTree). So, I brokeout that linenumber code into a macro to be inlined at the top of js_EmitTree and also into a static function that can be called elsewhere -- I didn't want to force an extra (and often unneeded) function call at the top of each invocation of js_EmitTree, nor inline 15 lines of code in a bunch of places, so this seemed a good compromise. This substantially fixes lineno errors in try/catch/finally code. There are still non-lineno problems in that code that shaver and coop are looking at - so this code in not final.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11210 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-28 08:02:43 +00:00
jband%netscape.com
95f197f31a function mis-declared as JS_FRIEND_DATA. changed to JS_FRIEND_API
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11209 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-28 07:51:21 +00:00
jband%netscape.com
aeb19b804e fix CompileTokenStream to always call js_CloseTokenStream. It was not doing so on syntax errors. This caused .js files loaded in the shell to be left open and would also fail to have JSPRINCIPALS_DROP be called in cases where principles are used.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11069 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-25 21:15:49 +00:00
norris%netscape.com
22b83ef992 Back out breaking change.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11017 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-25 04:36:13 +00:00
mccabe%netscape.com
cf89f9dbea Fix to xp problem on solaris. Use 1-argument form of gettimeofday #if
defined( SOLARIS ) - hack borrowed from ref/prtime.c.  Why wasn't it
needed in src/prmjtime.c previously?


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@11006 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-25 00:58:26 +00:00
norris%netscape.com
b9f52d961c Fix bug 299903 Inheriting from a Date object causes crash.
The test code is

     function MyDate() { this.foo = "bar"; }
     MyDate.prototype = new Date();
     x = new MyDate();
     print(x.toString())

The problem is that object x is created with an associated class of date_class, but with an undefined value in the private slot. Then when
date_getProlog is called on x, the JS_InstanceOf test passes since the class of the object is date_class, but then a bogus pointer is returned
since there isn't really a double in the private data slot.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10983 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-24 23:30:36 +00:00
jband%netscape.com
b9b66713eb added build() to js.c to display date/time of build in shell. Uses __DATE__ and __TIME__ which are supposed to be ansi C -- tested on Windows and Linux
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10975 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-24 22:52:07 +00:00
fur%netscape.com
3287009b56 Added/deleted files to accomodate ref/src merge.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10903 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-24 07:44:22 +00:00
jband%netscape.com
d0ad9c946c last automatic conversion of js/ref/jsd to js/jsd based on fur's conversion system of js/ref to js/src
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10900 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-24 07:22:17 +00:00
jband%netscape.com
b3c707fd61 removed NETSCAPE_INTERNAL. Made JS_IsAssigning a JS_FRIEND_API with a warning in jsapi.h that the function might be removed in the future
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10899 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-24 07:17:59 +00:00
fur%netscape.com
03332fd3ac Final changes merged from js/ref
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10897 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-24 05:40:16 +00:00
fur%netscape.com
ef97812295 + Make JS1.4 build in Mozilla
+ Get rid of all uses of NSPR20 macro


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10893 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-24 04:16:35 +00:00
fur%netscape.com
ca0614a7b6 Converted README to README.html
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10892 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-24 04:15:15 +00:00
fur%netscape.com
4c1594b677 Changes for merged js ref/src.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10886 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-24 03:55:11 +00:00
fur%netscape.com
914637bd3e Fixed JS_FRIEND_* macros
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10882 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-24 03:18:10 +00:00
fur%netscape.com
91dbe3c171 Added extern C declarations for inclusion into C++
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10881 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-24 03:17:55 +00:00
fur%netscape.com
c3bd0c5f7d Fix PR_EXTERN
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10878 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-24 02:41:11 +00:00
jband%netscape.com
cff140c431 adding a PR_PUBLIC_XXX conversions back in
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10809 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-23 18:45:12 +00:00
fur%netscape.com
923990dd99 Updated dependencies
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10785 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-23 07:44:40 +00:00
fur%netscape.com
45291c870a More name substitutions for ref/src merge
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10784 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-23 07:40:51 +00:00
jband%netscape.com
33d0d8a72b improved makefiles. added javawrap
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10768 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-23 04:01:03 +00:00
fur%netscape.com
2066c6b9ce Got rid of OS-dependent header files. Everything is in jsosdep.h now
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10765 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-23 02:37:53 +00:00
jband%netscape.com
46e77ac0e1 change path make standalone debugger work
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10735 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-23 01:42:03 +00:00
jband%netscape.com
7507e060b5 moved from ref/samples. work with ref/src merged js. ripped out jsd and jsdebugger build stuff
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10734 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-23 01:23:33 +00:00
jband%netscape.com
1cc86f1b54 jsd to go with ref/src merge. first checkin of new java stuff and jsdb
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10733 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-23 01:22:09 +00:00
fur%netscape.com
a4156ea8c1 Fix windows compilation error
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10727 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-22 23:39:13 +00:00
fur%netscape.com
4e17e7d0b6 Updated dependencies
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10723 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-22 23:27:41 +00:00
fur%netscape.com
0b9f4a6066 Make it build on the Mac
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10669 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-22 02:57:17 +00:00
fur%netscape.com
88e2efb86c Make it build on the Mac
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10668 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-22 02:47:25 +00:00
fur%netscape.com
f70c006cd2 Strange...some initialization of prmjtime.c is actually done in NSPR.
I had to copy the routines out of prtime.c so that prmjtime.c would
not be dependent on NSPR.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10666 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-22 02:37:06 +00:00
fur%netscape.com
2d43318eeb Replace PR_snprintf's
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10655 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-22 02:07:32 +00:00
fur%netscape.com
464cfb0128 + Added missing conversion of PR_*printf functions to JS_*printf.
+ Changed jsopcode.def to jsopcode.tbl


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10653 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-22 01:52:52 +00:00
fur%netscape.com
ccd9fea75c *** empty log message ***
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10633 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-21 23:28:00 +00:00
fur%netscape.com
adbbf081d4 Changes to build ref/src merged files on Win32 platform.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10607 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-21 20:04:13 +00:00
fur%netscape.com
087895e0d4 Standalone makefiles for js ref/src merge
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10606 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-21 20:03:11 +00:00
fur%netscape.com
f53236bbe5 Replaced with js*.h
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10598 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-21 18:58:46 +00:00
fur%netscape.com
4525a93346 Replaced with jsdtoa.c
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10597 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-21 18:57:51 +00:00
fur%netscape.com
92ce8e0953 This check-in is a first attempt at reducing JavaScript's dependency
on NSPR.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10589 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-21 17:54:36 +00:00
fur%netscape.com
4f506cbcbc prarena.c is now jsarena.c
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10586 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-21 17:47:37 +00:00
fur%netscape.com
53fed9d6ad This check-in is a first attempt at reducing JavaScript's dependency
on NSPR.  In fact, the JS C-engine no longer depends on NSPR at all in
a single-threaded environment and the multi-threaded version relies on
NSPR strictly for its threading primitives.  This change was made for
several reasons:

 + To merge the js/src and js/ref directories, which differ only in that
   the former is designed to link with NSPR2, but the latter makes use of
   an NSPR1 subset.  The automatic generation of src from ref often led
   to confusion and sometimes to merge-related errors.

 + To avoid the requirement to link against multiple versions of NSPR
   when delivering JS binaries. (Different internal customers of JS have
   standardized upon different NSPR releases.)

 + To shield JS from incompatible changes to NSPR.

Most of the changes involved simple renaming of types, macros,
identifiers and file names, i.e. from pr* to js*.  In some cases, this
transformation resulted in name collisions and a different name was
chosen.  One place where renaming was *not* performed was in the
definition of simple scalar types, i.e. int32, uint16, etc.  The
jsotypes.h header file was specially handled so as to avoid typename
collision with NSPR types of the same name.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10585 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-21 17:45:48 +00:00
fur%netscape.com
a7fb2e53b5 Removing dependency on NSPR
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10579 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-21 17:21:23 +00:00
(no author)
cddacc3fc7 This commit was manufactured by cvs2svn to create branch
'SpiderMonkey140_BRANCH'.

git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10431 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-18 19:56:46 +00:00
fur%netscape.com
6f925ed79a We decided not to do mini-nspr
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10422 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-18 18:21:58 +00:00
fur%netscape.com
91ff9d9174 Checkpoint mini-nspr files, even though we're probably not going to use mini-nspr
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@10292 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-17 18:55:29 +00:00
fur%netscape.com
cb5c11135f Make it build on unix
git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@9520 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-08 19:58:23 +00:00
(no author)
d02f29a398 This commit was manufactured by cvs2svn to create branch
'SpiderMonkey140_BRANCH'.

git-svn-id: svn://10.0.0.236/branches/SpiderMonkey140_BRANCH@9511 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-08 19:08:10 +00:00
195 changed files with 63024 additions and 18589 deletions

47
mozilla/js/src/MANIFEST Normal file
View File

@@ -0,0 +1,47 @@
# This file is required for the Mac client mozilla build.
# This is a list of local files which get copied to the mozilla:dist directory
#
js.msg
jsapi.h
jsarena.h
jspubtd.h
jsarray.h
jsatom.h
jsbool.h
jsclist.h
jscntxt.h
jscompat.h
jsconfig.h
jscpucfg.h
jsdate.h
jsdbgapi.h
jsdtoa.h
jsemit.h
jsfun.h
jsgc.h
jshash.h
jsinterp.h
jslock.h
jslong.h
jsmath.h
jsnum.h
jsobj.h
jsopcode.tbl
jsopcode.h
jsosdep.h
jsotypes.h
jsparse.h
jsprf.h
jsprvtd.h
jspubtd.h
jsregexp.h
jsscan.h
jsscope.h
jsscript.h
jsstr.h
jstypes.h
jsutil.h
jsxdrapi.h

267
mozilla/js/src/Makefile Normal file
View File

@@ -0,0 +1,267 @@
#! gmake
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH = ../..
include $(DEPTH)/config/config.mk
ifdef MOZ_OJI
DIRS = liveconnect
endif
LIBRARY_NAME = js
ifeq ($(subst /,_,$(shell uname -s)),OS2)
ifndef XCFLAGS
OS2_IMPLIB=1
LIBRARY = js$(MOZ_BITS)$(VERSION_NUMBER).$(LIB_SUFFIX)
DEF_FILE = jsos2$(VERSION_NUMBER).def
EXTRA_LIBS = $(LIBNSPR) $(LIBNSJAVA)
else
EXTRA_LIBS = $(LIBNSPR) $(LIBNSJAVA) $(OBJDIR)/libjs.lib
endif
endif
MODULE = js
CSRCS = jsapi.c \
jsarena.c \
jsarray.c \
jsatom.c \
jsbool.c \
jscntxt.c \
jsdate.c \
jsdbgapi.c \
jsdtoa.c \
jsemit.c \
jsexn.c \
jsfun.c \
jsgc.c \
jshash.c \
jsinterp.c \
jslock.c \
jslog2.c \
jslong.c \
jsmath.c \
jsnum.c \
jsobj.c \
jsopcode.c \
jsparse.c \
jsprf.c \
jsregexp.c \
jsscan.c \
jsscope.c \
jsscript.c \
jsstr.c \
jsutil.c \
jsxdrapi.c \
prmjtime.c \
$(NULL)
EXPORTS = js.msg \
jsapi.h \
jsarray.h \
jsarena.h \
jsatom.h \
jsbit.h \
jsbool.h \
jsclist.h \
jscntxt.h \
jscompat.h \
jsconfig.h \
jsdate.h \
jsdbgapi.h \
jsemit.h \
jsfun.h \
jsgc.h \
jshash.h \
jsinterp.h \
jslock.h \
jslong.h \
jsmath.h \
jsnum.h \
jsobj.h \
jsopcode.tbl \
jsopcode.h \
jsosdep.h \
jsotypes.h \
jsparse.h \
jsprf.h \
jsprvtd.h \
jspubtd.h \
jsregexp.h \
jsscan.h \
jsscope.h \
jsscript.h \
jsstr.h \
jstypes.h \
jsutil.h \
jsxdrapi.h \
$(NULL)
# when using gcc the assembly is inlined in the C-file (see jslock.c)
ifdef NS_USE_NATIVE
ASFILES = $(wildcard *_$(OS_ARCH).s)
endif
JS_SAFE_ARENA = 1
ifdef JS_SAFE_ARENA
DEFINES += -DJS_USE_SAFE_ARENA
endif
include $(DEPTH)/config/rules.mk
ifndef BUILD_OPT
MOCHAFILE = 1
endif
ifdef JSFILE
DEFINES += -DJSFILE
endif
ifdef JS_THREADSAFE
DEFINES += -DJS_THREADSAFE
endif
ifdef JS_NO_THIN_LOCKS
DEFINES += -DJS_USE_ONLY_NSPR_LOCKS
endif
ifdef JS_VERSION
DEFINES += -DJS_VERSION=$(JS_VERSION)
endif
ifeq ($(CPU_ARCH),sparc)
ifndef JS_NO_ULTRA
ULTRA_OPTIONS := -xarch=v8plus,-DULTRA_SPARC
ULTRA_OPTIONSCC := -DULTRA_SPARC
else
ULTRA_OPTIONS := -xarch=v8
ULTRA_OPTIONSCC :=
endif
ifeq ($(shell uname -m),sun4u)
ASFLAGS += -Wa,$(ULTRA_OPTIONS),-P,-L,-D_ASM,-D__STDC__=0 $(ULTRA_OPTIONSCC)
else
ASFLAGS += -Wa,-xarch=v8,-P,-L,-D_ASM,-D__STDC__=0
endif
endif # sparc
INCLUDES += -I.
ifndef NSBUILDROOT
JSJAVA_STUBHEADERS = -I$(DEPTH)/sun-java/include/_gen \
-I$(DEPTH)/sun-java/netscape/javascript/_jri \
-I$(DEPTH)/sun-java/netscape/security/_jri
else
JSJAVA_STUBHEADERS = -I$(JRI_GEN_DIR) -I$(JDK_GEN_DIR)
endif
JSJAVA_CFLAGS = -I$(DEPTH)/sun-java/md-include \
-I$(DEPTH)/sun-java/include \
$(JSJAVA_STUBHEADERS)
# LIBNSPR abstracts nspr version, etc. nicely.
LDFLAGS = $(LIBNSPR) -lm
ifeq ($(OS_ARCH), OSF1)
LDFLAGS += -lc_r
endif
ifeq ($(OS_ARCH), SunOS)
LDFLAGS += -lposix4 -ldl -lnsl -lsocket
endif
ifeq ($(OS_ARCH), Linux)
LDFLAGS += -ldl
endif
FDLIBM_LIBRARY = fdlibm/$(OBJDIR)/libfdm.a
JSMATH_PRELINK = $(OBJDIR)/jsmathtemp.o
# special rule for jsmath.o since we want to incrementally link
# against fdlibm to pull in only what is needed
$(OBJDIR)/jsmath.o: $(FDLIBM_LIBRARY) $(JSMATH_PRELINK)
@$(MAKE_OBJDIR)
ifneq (,$(filter OS2 WINNT,$(OS_ARCH)))
ld -r -o $@ $(JSMATH_PRELINK) $(FDLIBM_LIBRARY)
else
ld -r -o $@ $(JSMATH_PRELINK) $(FDLIBM_LIBRARY)
endif
$(JSMATH_PRELINK): jsmath.c jslibmath.h
@$(MAKE_OBJDIR)
ifneq (,$(filter OS2 WINNT,$(OS_ARCH)))
$(CC) -Fo$@ -c $(CFLAGS) $<
else
$(CC) -o $@ -c $(CFLAGS) $<
endif
$(FDLIBM_LIBRARY):
cd fdlibm; $(MAKE)
# this requires clobbering and recompiling with XCFLAGS=-DJSFILE
js:
$(MAKE) clobber
$(MAKE) XCFLAGS=-DJSFILE $(OBJDIR)/js$(BIN_SUFFIX)
.PHONY: js$(BIN_SUFFIX)
ifneq ($(OS_ARCH),OS2)
$(OBJDIR)/js$(BIN_SUFFIX): $(OBJDIR)/js.o $(LIBRARY)
@$(MAKE_OBJDIR)
$(CC) -o $@ $(OBJDIR)/js.o $(LIBRARY) $(LDFLAGS)
else
OS_CFLAGS += -tm-
$(OBJDIR)/js$(BIN_SUFFIX): $(OBJDIR)/js.o $(LIBRARY)
@$(MAKE_OBJDIR)
$(LINK_EXE) -OUT:$@ $(OBJDIR)/js.o $(LIBRARIES) $(EXTRA_LIBS)
endif
# hardwire dependencies on jsopcode.tbl
jsopcode.h jsopcode.c: jsopcode.tbl
# Generate jsautocfg.h header
$(OBJDIR)/jsautocfg.h: $(OBJDIR)/jscpucfg
rm -f $@
$(OBJDIR)/jscpucfg > $@
$(OBJDIR)/jscpucfg: $(OBJDIR)/jscpucfg.o
$(CC) -o $@ $(OBJDIR)/jscpucfg.o
export:: $(OBJDIR)/jsautocfg.h
$(INSTALL) -m 444 $(OBJDIR)/jsautocfg.h $(DIST)/include
# Add to TARGETS so clobber rule works
TARGETS += $(OBJDIR)/jsautocfg.h $(OBJDIR)/jscpucfg $(OBJDIR)/jscpucfg.o
# this section was put in the merged by danda into the
# JAVA_*_MERGE section and normally would have
# been removed. However it looks like it shouldn't have
# been put there in the first place, so we're leaving it
# here until danda can confirm (we don't have OS/2 machines
# to build on) - hshaw/sudu
#
ifeq ($(OS_ARCH),OS2)
$(OBJDIR)/js.o: js.c
@$(MAKE_OBJDIR)
$(CC) -Fo$@ -c $(CFLAGS) $(JSJAVA_CFLAGS) js.c
endif
clobber::
rm -f $(OBJDIR)/jscpucfg $(OBJDIR)/jscpucfg.h

268
mozilla/js/src/Makefile.in Normal file
View File

@@ -0,0 +1,268 @@
#! gmake
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH = ../..
topsrcdir = @top_srcdir@
VPATH = @srcdir@
srcdir = @srcdir@
include $(DEPTH)/config/autoconf.mk
ifdef MOZ_OJI
DIRS = liveconnect
endif
LIBRARY_NAME = js
ifeq ($(subst /,_,$(shell uname -s)),OS2)
ifndef XCFLAGS
OS2_IMPLIB=1
LIBRARY = js$(MOZ_BITS)$(VERSION_NUMBER).$(LIB_SUFFIX)
DEF_FILE = jsos2$(VERSION_NUMBER).def
EXTRA_LIBS = $(LIBNSPR) $(LIBNSJAVA)
else
EXTRA_LIBS = $(LIBNSPR) $(LIBNSJAVA) $(OBJDIR)/libjs.lib
endif
endif
MODULE = js
CSRCS = jsapi.c \
jsarena.c \
jsarray.c \
jsatom.c \
jsbool.c \
jscntxt.c \
jsdate.c \
jsdbgapi.c \
jsdtoa.c \
jsemit.c \
jsexn.c \
jsfun.c \
jsgc.c \
jshash.c \
jsinterp.c \
jslock.c \
jslog2.c \
jslong.c \
jsmath.c \
jsnum.c \
jsobj.c \
jsopcode.c \
jsparse.c \
jsprf.c \
jsregexp.c \
jsscan.c \
jsscope.c \
jsscript.c \
jsstr.c \
jsutil.c \
jsxdrapi.c \
prmjtime.c \
$(NULL)
EXPORTS = js.msg \
jsapi.h \
jsarray.h \
jsarena.h \
jsatom.h \
jsbit.h \
jsbool.h \
jsclist.h \
jscntxt.h \
jscompat.h \
jsconfig.h \
jsdate.h \
jsdbgapi.h \
jsemit.h \
jsfun.h \
jsgc.h \
jshash.h \
jsinterp.h \
jslock.h \
jslong.h \
jsmath.h \
jsnum.h \
jsobj.h \
jsopcode.tbl \
jsopcode.h \
jsosdep.h \
jsotypes.h \
jsparse.h \
jsprf.h \
jsprvtd.h \
jspubtd.h \
jsregexp.h \
jsscan.h \
jsscope.h \
jsscript.h \
jsstr.h \
jstypes.h \
jsutil.h \
jsxdrapi.h \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
# when using gcc the assembly is inlined in the C-file (see jslock.c)
ifdef NS_USE_NATIVE
ASFILES = $(wildcard $(srcdir)/*_$(OS_ARCH).s)
endif
JS_SAFE_ARENA = 1
ifdef JS_SAFE_ARENA
DEFINES += -DJS_USE_SAFE_ARENA
endif
include $(topsrcdir)/config/rules.mk
ifndef BUILD_OPT
MOCHAFILE = 1
endif
ifdef JSFILE
DEFINES += -DJSFILE
endif
ifdef JS_THREADSAFE
DEFINES += -DJS_THREADSAFE
endif
ifdef JS_NO_THIN_LOCKS
DEFINES += -DJS_USE_ONLY_NSPR_LOCKS
endif
ifdef JS_VERSION
DEFINES += -DJS_VERSION=$(JS_VERSION)
endif
ifeq ($(CPU_ARCH),sparc)
ifndef JS_NO_ULTRA
ULTRA_OPTIONS := -xarch=v8plus,-DULTRA_SPARC
ULTRA_OPTIONSCC := -DULTRA_SPARC
else
ULTRA_OPTIONS := -xarch=v8
ULTRA_OPTIONSCC :=
endif
ifeq ($(shell uname -m),sun4u)
ASFLAGS += -Wa,$(ULTRA_OPTIONS),-P,-L,-D_ASM,-D__STDC__=0 $(ULTRA_OPTIONSCC)
else
ASFLAGS += -Wa,-xarch=v8,-P,-L,-D_ASM,-D__STDC__=0
endif
endif # sparc
INCLUDES += -I$(srcdir)
ifndef NSBUILDROOT
JSJAVA_STUBHEADERS = -I$(topsrcdir)/sun-java/include/_gen \
-I$(topsrcdir)/sun-java/netscape/javascript/_jri \
-I$(topsrcdir)/sun-java/netscape/security/_jri
else
JSJAVA_STUBHEADERS = -I$(JRI_GEN_DIR) -I$(JDK_GEN_DIR)
endif
JSJAVA_CFLAGS = -I$(topsrcdir)/sun-java/md-include \
-I$(topsrcdir)/sun-java/include \
$(JSJAVA_STUBHEADERS)
# LIBNSPR abstracts nspr version, etc. nicely.
LDFLAGS = $(LIBNSPR) -lm
ifeq ($(OS_ARCH), OSF1)
LDFLAGS += -lc_r
endif
ifeq ($(OS_ARCH), SunOS)
LDFLAGS += -lposix4 -ldl -lnsl -lsocket
endif
ifeq ($(OS_ARCH), Linux)
LDFLAGS += -ldl
endif
FDLIBM_LIBRARY = fdlibm/$(OBJDIR)/libfdm.a
JSMATH_PRELINK = $(OBJDIR)/jsmathtemp.o
# special rule for jsmath.o since we want to incrementally link
# against fdlibm to pull in only what is needed
$(OBJDIR)/jsmath.o: $(FDLIBM_LIBRARY) $(JSMATH_PRELINK)
@$(MAKE_OBJDIR)
ifneq (,$(filter OS2 WINNT,$(OS_ARCH)))
ld -r -o $@ $(JSMATH_PRELINK) $(FDLIBM_LIBRARY)
else
ld -r -o $@ $(JSMATH_PRELINK) $(FDLIBM_LIBRARY)
endif
$(JSMATH_PRELINK): jsmath.c
@$(MAKE_OBJDIR)
ifneq (,$(filter OS2 WINNT,$(OS_ARCH)))
$(CC) -Fo$@ -c $(CFLAGS) $<
else
$(CC) -o $@ -c $(CFLAGS) $<
endif
$(FDLIBM_LIBRARY):
cd fdlibm; $(MAKE)
# this requires clobbering and recompiling with XCFLAGS=-DJSFILE
js:
$(MAKE) clobber
$(MAKE) XCFLAGS=-DJSFILE $(OBJDIR)/js$(BIN_SUFFIX)
.PHONY: js$(BIN_SUFFIX)
ifneq ($(OS_ARCH),OS2)
$(OBJDIR)/js$(BIN_SUFFIX): $(OBJDIR)/js.o $(LIBRARY)
@$(MAKE_OBJDIR)
$(CC) -o $@ $(OBJDIR)/js.o $(LIBRARY) $(LDFLAGS)
else
OS_CFLAGS += -tm-
$(OBJDIR)/js$(BIN_SUFFIX): $(OBJDIR)/js.o $(LIBRARY)
@$(MAKE_OBJDIR)
$(LINK_EXE) -OUT:$@ $(OBJDIR)/js.o $(LIBRARIES) $(EXTRA_LIBS)
endif
# hardwire dependencies on jsopcode.tbl
jsopcode.h jsopcode.c: jsopcode.tbl
# Generate jsautocfg.h header
$(OBJDIR)/jsautocfg.h: $(OBJDIR)/jscpucfg
rm -f $@
$(OBJDIR)/jscpucfg > $@
$(OBJDIR)/jscpucfg: $(OBJDIR)/jscpucfg.o
$(CC) -o $@ $(OBJDIR)/jscpucfg.o
export:: $(OBJDIR)/jsautocfg.h
$(INSTALL) -m 444 $(OBJDIR)/jsautocfg.h $(DIST)/include
# Add to TARGETS so clobber rule works
TARGETS += $(OBJDIR)/jsautocfg.h $(OBJDIR)/jscpucfg $(OBJDIR)/jscpucfg.o
# this section was put in the merged by danda into the
# JAVA_*_MERGE section and normally would have
# been removed. However it looks like it shouldn't have
# been put there in the first place, so we're leaving it
# here until danda can confirm (we don't have OS/2 machines
# to build on) - hshaw/sudu
#
ifeq ($(OS_ARCH),OS2)
$(OBJDIR)/js.o: js.c
@$(MAKE_OBJDIR)
$(CC) -Fo$@ -c $(CFLAGS) $(JSJAVA_CFLAGS) js.c
endif

239
mozilla/js/src/Makefile.ref Normal file
View File

@@ -0,0 +1,239 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
# JSRef GNUmake makefile.
#
DEPTH = .
include config.mk
#NS_USE_NATIVE = 1
ifdef USE_MSVC
OTHER_LIBS += fdlibm/$(OBJDIR)/fdlibm.lib
else
OTHER_LIBS += -Lfdlibm/$(OBJDIR) -lfdm
endif
ifdef JS_THREADSAFE
DEFINES += -DJS_THREADSAFE
INCLUDES += -I../../dist/$(OBJDIR)/include
ifdef USE_MSVC
OTHER_LIBS += ../../dist/$(OBJDIR)/lib/libnspr21.lib
else
OTHER_LIBS += -L../../dist/$(OBJDIR)/lib -lnspr21
endif
endif
ifdef JS_NO_THIN_LOCKS
DEFINES += -DJS_USE_ONLY_NSPR_LOCKS
endif
ifdef JS_HAS_FILE_OBJECT
DEFINES += -DJS_HAS_FILE_OBJECT
endif
#
# XCFLAGS may be set in the environment or on the gmake command line
#
CFLAGS += $(OPTIMIZER) $(OS_CFLAGS) $(DEFINES) $(INCLUDES) \
-DJSFILE $(XCFLAGS)
LDFLAGS = -lm $(XLDFLAGS)
#
# Ask perl what flags it was built with, so we can build js with similar flags
# and link properly. Viva gmake.
#
ifdef JS_PERLCONNECT
DEFINES += -DPERLCONNECT
PERLCFLAGS := $(shell perl -MExtUtils::Embed -e ccopts)
PERLLDFLAGS := $(shell perl -MExtUtils::Embed -e ldopts)
CFLAGS += $(PERLCFLAGS)
LDFLAGS += $(PERLLDFLAGS)
endif
# For purify
PURE_CFLAGS = -DXP_UNIX $(OPTIMIZER) $(PURE_OS_CFLAGS) $(DEFINES) \
$(INCLUDES) $(XCFLAGS)
#
# JS file lists
#
JS_HFILES = \
jsarray.h \
jsatom.h \
jsbool.h \
jsconfig.h \
jscntxt.h \
jsdate.h \
jsemit.h \
jsexn.h \
jsfun.h \
jsgc.h \
jsinterp.h \
jslibmath.h \
jslock.h \
jsmath.h \
jsnum.h \
jsobj.h \
jsopcode.h \
jsparse.h \
jsarena.h \
jsclist.h \
jsdtoa.h \
jshash.h \
jslong.h \
jsosdep.h \
jstypes.h \
jsprvtd.h \
jspubtd.h \
jsregexp.h \
jsscan.h \
jsscope.h \
jsscript.h \
jsstr.h \
jsxdrapi.h \
$(NULL)
API_HFILES = \
jsapi.h \
jsdbgapi.h \
$(NULL)
HFILES = $(JS_HFILES) $(API_HFILES)
JS_CFILES = \
jsapi.c \
jsarena.c \
jsarray.c \
jsatom.c \
jsbool.c \
jscntxt.c \
jsdate.c \
jsdbgapi.c \
jsdtoa.c \
jsemit.c \
jsexn.c \
jsfun.c \
jsgc.c \
jshash.c \
jsinterp.c \
jslock.c \
jslog2.c \
jslong.c \
jsmath.c \
jsnum.c \
jsobj.c \
jsopcode.c \
jsparse.c \
jsprf.c \
jsregexp.c \
jsscan.c \
jsscope.c \
jsscript.c \
jsstr.c \
jsutil.c \
jsxdrapi.c \
prmjtime.c \
$(NULL)
PREDIRS += fdlibm
ifdef JS_LIVECONNECT
DIRS += liveconnect
endif
ifdef JS_PERLCONNECT
JS_CFILES += jsperl.c
endif
ifdef JS_HAS_FILE_OBJECT
JS_CFILES += jsfile.c
JS_HFILES += jsfile.h
endif
LIB_CFILES = $(JS_CFILES)
LIB_ASFILES := $(wildcard *_$(OS_ARCH).s)
PROG_CFILES = js.c
ifdef USE_MSVC
LIBRARY = $(OBJDIR)/js32.lib
SHARED_LIBRARY = $(OBJDIR)/js32.dll
PROGRAM = $(OBJDIR)/js.exe
else
LIBRARY = $(OBJDIR)/libjs.a
SHARED_LIBRARY = $(OBJDIR)/libjs.so
PROGRAM = $(OBJDIR)/js
endif
ifdef USE_MSVC
FDLIBM_LIBRARY = fdlibm.lib
else
FDLIBM_LIBRARY = libfdm.a
endif
include rules.mk
MOZ_DEPTH = ../..
include jsconfig.mk
nsinstall-target:
cd ../../config; $(MAKE) OBJDIR=$(OBJDIR) OBJDIR_NAME=$(OBJDIR)
ifdef USE_MSVC
$(PROGRAM): $(PROG_OBJS) $(LIBRARY)
link.exe -out:"$@" $(EXE_LINK_FLAGS) $^
else
$(PROGRAM): $(PROG_OBJS) $(LIBRARY)
$(CC) -o $@ $(CFLAGS) $(PROG_OBJS) $(LIBRARY) $(LDFLAGS) $(OTHER_LIBS)
endif
$(PROGRAM).pure: $(PROG_OBJS) $(LIBRARY)
purify $(PUREFLAGS) \
$(CC) -o $@ $(PURE_OS_CFLAGS) $(PROG_OBJS) $(LIBRARY) $(LDFLAGS) $(OTHER_LIBS)
ifndef PREBUILT_CPUCFG
$(HFILES) $(CFILES): $(OBJDIR)/jsautocfg.h
$(OBJDIR)/jsautocfg.h: $(OBJDIR)/jscpucfg
rm -f $@
$(OBJDIR)/jscpucfg > $@
$(OBJDIR)/jscpucfg: $(OBJDIR)/jscpucfg.o
$(CC) -o $@ $(OBJDIR)/jscpucfg.o
# Look in OBJDIR to find jsautocfg.h
INCLUDES += -I$(OBJDIR)
# Add to TARGETS for clobber rule
TARGETS += $(OBJDIR)/jsautocfg.h $(OBJDIR)/jscpucfg $(OBJDIR)/jscpucfg.o
endif
#
# Hardwire dependencies on jsopcode.tbl
#
jsopcode.h jsopcode.c: jsopcode.tbl
-include $(DEPENDENCIES)
TARNAME = jsref.tar
TARFILES = files `cat files`
SUFFIXES: .i
%.i: %.c
$(CC) -C -E $(CFLAGS) $< > $*.i

755
mozilla/js/src/README.html Normal file
View File

@@ -0,0 +1,755 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.5 [en] (WinNT; I) [Netscape]">
<title>JavaScript Reference Implementation (JSRef) README</title>
</head>
<body>
<h2>
Table of Contents</h2>
<ul>
<li>
<a href="#Introduction">Introduction</a></li>
<li>
<a href="#Build">Build conventions (standalone JS engine and shell)</a></li>
<li>
<a href="#Debugging">Debugging notes</a></li>
<li>
<a href="#Conventions">Naming and coding conventions</a></li>
<li>
<a href="#JSAPI">Using the JS API</a></li>
<li>
<a href="#Design">Design walk-through</a></li>
</ul>
<h2>
<a NAME="Introduction"></a>Introduction</h2>
This is the README file for the&nbsp;<span CLASS=LXRSHORTDESC>JavaScript
Reference (JSRef) implementation.</span> It consists of build conventions
and instructions, source code conventions, a design walk-through, and a
brief file-by-file description of the source.
<p><span CLASS=LXRLONGDESC>JSRef builds a library or DLL containing the
JavaScript runtime (compiler, interpreter, decompiler, garbage collector,
atom manager, standard classes). It then compiles a small "shell" program
and links that with the library to make an interpreter that can be used
interactively and with test .js files to run scripts.&nbsp; The code has
no dependencies on the Navigator code.</span>
<p><i>Quick start tip</i>: skip to "Using the JS API" below, build the
js shell, and play with the object named "it" (start by setting 'it.noisy
= true').
<h2>
<a NAME="Build"></a>Build conventions (standalone JS engine and shell)</h2>
These build directions refer only to building the standalone JavaScript
engine and shell.&nbsp; To build within the browser, refer to the <a href="http://www.mozilla.org/docs/">build
directions</a> on the mozilla.org website.
<p>By default, all platforms build a version of the JS engine that is <i>not</i>
threadsafe.&nbsp; If you require thread-safety, you must also populate
the <tt>mozilla/dist</tt> directory with <a href="http://www.mozilla.org/docs/tplist/catCode/nsprdesc.htm">NSPR</a>
headers and libraries.&nbsp; (NSPR implements a portable threading library,
among other things.&nbsp; The source is downloadable via <a href="http://www.mozilla.org/cvs.html">CVS</a>
from <tt><a href="http://cvs-mirror.mozilla.org/webtools/lxr/source/nsprpub">mozilla/nsprpub</a></tt>.)&nbsp;
Next, you must define <tt>JS_THREADSAFE</tt> when building the JS engine,
either on the command-line (gmake/nmake) or in a universal header file.
<h3>
Windows</h3>
<ul>
<li>
Use MSVC 4.2 or 5.0.</li>
<li>
For building from the IDE use <tt>js/src/js.mdp</tt>.&nbsp; (<tt>js.mdp</tt>
is an MSVC4.2 project file, but if you load it into MSVC5, it will be converted
to the newer project file format.)&nbsp; <font color="#CC0000">NOTE: makefile.win
is an nmake file used only for building the JS-engine in the Mozilla browser.&nbsp;
Don't attempt to use it to build the standalone JS-engine.</font></li>
<li>
If you prefer to build from the command-line, use '<tt>nmake -f js.mak</tt>'</li>
<li>
Executable shell <tt>js.exe</tt> and runtime library <tt>js32.dll</tt>
are created in either <tt>js/src/Debug</tt> or <tt>js/src/Release</tt>.</li>
</ul>
<h3>
Macintosh</h3>
<ul>
<li>
Use CodeWarrior 3.x</li>
<li>
Load the project file <tt>js:src:macbuild:JSRef.mcp </tt>and select "Make"
from the menu.</li>
</ul>
<h3>
Unix</h3>
<ul>
<li>
Use '<tt>gmake -f Makefile.ref</tt>' to build. To compile optimized code,
pass <tt>BUILD_OPT=1</tt> on the gmake command line or preset it in the
environment or <tt>Makefile.ref</tt>.&nbsp; <font color="#CC0000">NOTE:
Do not attempt to use Makefile to build the standalone JavaScript engine.&nbsp;
This file is used only for building the JS-engine in the Mozilla browser.</font></li>
<li>
<font color="#000000">Each platform on which JS is built must have a <tt>*.mk</tt>
configuration file in the <tt>js/src/config</tt> directory.&nbsp; The configuration
file specifies the compiler/linker to be used and allows for customization
of command-line options.&nbsp; To date, the build system has been tested
on Solaris, AIX, HP/UX, OSF, IRIX, x86 Linux and Windows NT.</font></li>
<li>
<font color="#000000">Most platforms will work with either the vendor compiler
</font>or
<a href="ftp://prep.ai.mit.edu/pub/gnu">gcc</a>.&nbsp;
(Except that HP builds only work using the native compiler.&nbsp; gcc won't
link correctly with shared libraries on that platform.&nbsp; If someone
knows a way to fix this, <a href="mailto:wynholds@netscape.com">let us
know</a>.)</li>
<li>
<font color="#000000">If you define <tt>JS_LIVECONNECT</tt>, gmake will
descend into the liveconnect directory and build <a href="http://cvs-mirror.mozilla.org/webtools/lxr/source/js/src/liveconnect/README.html">LiveConnect</a>
after building the JS engine.</font></li>
<li>
To build a binary drop (a zip'ed up file of headers, libraries, binaries),
check out <tt>mozilla/config</tt> and <tt>mozilla/nsprpub/config</tt>.&nbsp;
Use '<tt>gmake -f Makefile.ref nsinstall-target all export ship</tt>'</li>
</ul>
<h2>
<a NAME="Debugging"></a>Debugging notes</h2>
<ul>
<li>
To turn on GC instrumentation, define <tt>JS_GCMETER</tt>.</li>
<li>
To turn on the arena package's instrumentation, define <tt>JS_ARENAMETER</tt>.</li>
<li>
To turn on the hash table package's metering, define <tt>JS_HASHMETER</tt>.</li>
</ul>
<h2>
<a NAME="Conventions"></a>Naming and coding conventions</h2>
<ul>
<li>
Public function names begin with <tt>JS_</tt> followed by capitalized "intercaps",
e.g. <tt>JS_NewObject</tt>.</li>
<li>
Extern but library-private function names use a <tt>js_</tt> prefix and
mixed case, e.g. <tt>js_LookupSymbol</tt>.</li>
<li>
Most static function names have unprefixed, mixed-case names: <tt>GetChar</tt>.</li>
<li>
But static native methods of JS objects have lowercase, underscore-separated
or intercaps names, e.g., <tt>str_indexOf</tt>.</li>
<li>
And library-private and static data use underscores, not intercaps (but
library-private data do use a <tt>js_</tt> prefix).</li>
<li>
Scalar type names are lowercase and js-prefixed: <tt>jsdouble</tt>.</li>
<li>
Aggregate type names are JS-prefixed and mixed-case: <tt>JSObject.</tt></li>
<li>
Macros are generally <tt>ALL_CAPS </tt>and underscored, to call out potential
side effects, multiple uses of a formal argument, etc. - Four spaces of
indentation per statement nesting level.</li>
<li>
Tabs are taken to be eight spaces, and an Emacs magic comment at the top
of each file tries to help. If you're using MSVC or similar, you'll want
to set tab width to 8, or convert these files to be space-filled.</li>
<li>
DLL entry points have their return type expanded within a <tt>JS_PUBLIC_API()</tt>
macro call, to get the right Windows secret type qualifiers in the right
places for both 16- and 32-bit builds.</li>
<li>
Callback functions that might be called from a DLL are similarly macroized
with <tt>JS_STATIC_DLL_CALLBACK</tt> (if the function otherwise would be
static to hide its name) or <tt>JS_DLL_CALLBACK</tt> (this macro takes
no type argument; it should be used after the return type and before the
function name).</li>
</ul>
<h2>
<a NAME="JSAPI"></a>Using the JS API</h2>
<h4>
Starting up</h4>
<pre><tt>&nbsp;&nbsp;&nbsp; /*
&nbsp;&nbsp;&nbsp;&nbsp; * Tune this to avoid wasting space for shallow stacks, while saving on
&nbsp;&nbsp;&nbsp;&nbsp; * malloc overhead/fragmentation for deep or highly-variable stacks.
&nbsp;&nbsp;&nbsp;&nbsp; */
&nbsp;&nbsp;&nbsp; #define STACK_CHUNK_SIZE&nbsp;&nbsp;&nbsp; 8192
&nbsp;&nbsp;&nbsp; JSRuntime *rt;
&nbsp;&nbsp;&nbsp; JSContext *cx;
&nbsp;&nbsp;&nbsp; /* You need a runtime and one or more contexts to do anything with JS. */
&nbsp;&nbsp;&nbsp; rt = JS_Init(1000000L);
&nbsp;&nbsp;&nbsp; if (!rt)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fail("can't create JavaScript runtime");
&nbsp;&nbsp;&nbsp; cx = JS_NewContext(rt, STACK_CHUNK_SIZE);
&nbsp;&nbsp;&nbsp; if (!cx)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fail("can't create JavaScript context");
&nbsp;&nbsp;&nbsp; /*
&nbsp;&nbsp;&nbsp;&nbsp; * The context definitely wants a global object, in order to have standard
&nbsp;&nbsp;&nbsp;&nbsp; * classes and functions like Date and parseInt.&nbsp; See below for details on
&nbsp;&nbsp;&nbsp;&nbsp; * JS_NewObject.
&nbsp;&nbsp;&nbsp;&nbsp; */
&nbsp;&nbsp;&nbsp; JSObject *globalObj;
&nbsp;&nbsp;&nbsp; globalObj = JS_NewObject(cx, &amp;my_global_class, 0, 0);
&nbsp;&nbsp;&nbsp; JS_InitStandardClasses(cx, globalObj);</tt></pre>
<h4>
Defining objects and properties</h4>
<pre><tt>&nbsp;&nbsp;&nbsp; /* Statically initialize a class to make "one-off" objects. */
&nbsp;&nbsp;&nbsp; JSClass my_class = {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "MyClass",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* All of these can be replaced with the corresponding JS_*Stub
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; function pointers. */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my_addProperty, my_delProperty, my_getProperty, my_setProperty,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my_enumerate,&nbsp;&nbsp; my_resolve,&nbsp;&nbsp;&nbsp;&nbsp; my_convert,&nbsp;&nbsp;&nbsp;&nbsp; my_finalize
&nbsp;&nbsp;&nbsp; };
&nbsp;&nbsp;&nbsp; JSObject *obj;
&nbsp;&nbsp;&nbsp; /*
&nbsp;&nbsp;&nbsp;&nbsp; * Define an object named in the global scope that can be enumerated by
&nbsp;&nbsp;&nbsp;&nbsp; * for/in loops.&nbsp; The parent object is passed as the second argument, as
&nbsp;&nbsp;&nbsp;&nbsp; * with all other API calls that take an object/name pair.&nbsp; The prototype
&nbsp;&nbsp;&nbsp;&nbsp; * passed in is null, so the default object prototype will be used.
&nbsp;&nbsp;&nbsp;&nbsp; */
&nbsp;&nbsp;&nbsp; obj = JS_DefineObject(cx, globalObj, "myObject", &amp;my_class, 0,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JSPROP_ENUMERATE);
&nbsp;&nbsp;&nbsp; /*
&nbsp;&nbsp;&nbsp;&nbsp; * Define a bunch of properties with a JSPropertySpec array statically
&nbsp;&nbsp;&nbsp;&nbsp; * initialized and terminated with a null-name entry.&nbsp; Besides its name,
&nbsp;&nbsp;&nbsp;&nbsp; * each property has a "tiny" identifier (MY_COLOR, e.g.) that can be used
&nbsp;&nbsp;&nbsp;&nbsp; * in switch statements (in a common my_getProperty function, for example).
&nbsp;&nbsp;&nbsp;&nbsp; */
&nbsp;&nbsp;&nbsp; enum my_tinyid {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MY_COLOR, MY_HEIGHT, MY_WIDTH, MY_FUNNY, MY_ARRAY, MY_RDONLY
&nbsp;&nbsp;&nbsp; };
&nbsp;&nbsp;&nbsp; static JSPropertySpec my_props[] = {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {"color",&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MY_COLOR,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JSPROP_ENUMERATE},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {"height",&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MY_HEIGHT,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JSPROP_ENUMERATE},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {"width",&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MY_WIDTH,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JSPROP_ENUMERATE},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {"funny",&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MY_FUNNY,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JSPROP_ENUMERATE},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {"array",&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MY_ARRAY,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JSPROP_ENUMERATE},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {"rdonly",&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MY_RDONLY,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JSPROP_READONLY},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {0}
&nbsp;&nbsp;&nbsp; };
&nbsp;&nbsp;&nbsp; JS_DefineProperties(cx, obj, my_props);
&nbsp;&nbsp;&nbsp; /*
&nbsp;&nbsp;&nbsp;&nbsp; * Given the above definitions and call to JS_DefineProperties, obj will
&nbsp;&nbsp;&nbsp;&nbsp; * need this sort of "getter" method in its class (my_class, above).&nbsp; See
&nbsp;&nbsp;&nbsp;&nbsp; * the example for the "It" class in js.c.
&nbsp;&nbsp;&nbsp;&nbsp; */
&nbsp;&nbsp;&nbsp; static JSBool
&nbsp;&nbsp;&nbsp; my_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (JSVAL_IS_INT(id)) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch (JSVAL_TO_INT(id)) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case MY_COLOR:&nbsp; *vp = . . .; break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case MY_HEIGHT: *vp = . . .; break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case MY_WIDTH:&nbsp; *vp = . . .; break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case MY_FUNNY:&nbsp; *vp = . . .; break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case MY_ARRAY:&nbsp; *vp = . . .; break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case MY_RDONLY: *vp = . . .; break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return JS_TRUE;
&nbsp;&nbsp;&nbsp; }</tt></pre>
<h4>
Defining functions</h4>
<pre><tt>&nbsp;&nbsp;&nbsp; /* Define a bunch of native functions first: */
&nbsp;&nbsp;&nbsp; static JSBool
&nbsp;&nbsp;&nbsp; my_abs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jsdouble x, z;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!JS_ValueToNumber(cx, argv[0], &amp;x))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return JS_FALSE;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; z = (x &lt; 0) ? -x : x;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return JS_NewDoubleValue(cx, z, rval);
&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp; . . .
&nbsp;&nbsp;&nbsp; /*
&nbsp;&nbsp;&nbsp;&nbsp; * Use a JSFunctionSpec array terminated with a null name to define a
&nbsp;&nbsp;&nbsp;&nbsp; * bunch of native functions.
&nbsp;&nbsp;&nbsp;&nbsp; */
&nbsp;&nbsp;&nbsp; static JSFunctionSpec my_functions[] = {
&nbsp;&nbsp;&nbsp; /*&nbsp;&nbsp;&nbsp; name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; native&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nargs&nbsp;&nbsp;&nbsp; */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {"abs",&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my_abs,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {"acos",&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my_acos,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {"asin",&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my_asin,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; . . .
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {0}
&nbsp;&nbsp;&nbsp; };
&nbsp;&nbsp;&nbsp; /*
&nbsp;&nbsp;&nbsp;&nbsp; * Pass a particular object to define methods for it alone.&nbsp; If you pass
&nbsp;&nbsp;&nbsp;&nbsp; * a prototype object, the methods will apply to all instances past and
&nbsp;&nbsp;&nbsp;&nbsp; * future of the prototype's class (see below for classes).
&nbsp;&nbsp;&nbsp;&nbsp; */
&nbsp;&nbsp;&nbsp; JS_DefineFunctions(cx, globalObj, my_functions);</tt></pre>
<h4>
Defining classes</h4>
<pre><tt>&nbsp;&nbsp;&nbsp; /*
&nbsp;&nbsp;&nbsp;&nbsp; * This pulls together the above API elements by defining a constructor
&nbsp;&nbsp;&nbsp;&nbsp; * function, a prototype object, and properties of the prototype and of
&nbsp;&nbsp;&nbsp;&nbsp; * the constructor, all with one API call.
&nbsp;&nbsp;&nbsp;&nbsp; *
&nbsp;&nbsp;&nbsp;&nbsp; * Initialize a class by defining its constructor function, prototype, and
&nbsp;&nbsp;&nbsp;&nbsp; * per-instance and per-class properties.&nbsp; The latter are called "static"
&nbsp;&nbsp;&nbsp;&nbsp; * below by analogy to Java.&nbsp; They are defined in the constructor object's
&nbsp;&nbsp;&nbsp;&nbsp; * scope, so that 'MyClass.myStaticProp' works along with 'new MyClass()'.
&nbsp;&nbsp;&nbsp;&nbsp; *
&nbsp;&nbsp;&nbsp;&nbsp; * JS_InitClass takes a lot of arguments, but you can pass null for any of
&nbsp;&nbsp;&nbsp;&nbsp; * the last four if there are no such properties or methods.
&nbsp;&nbsp;&nbsp;&nbsp; *
&nbsp;&nbsp;&nbsp;&nbsp; * Note that you do not need to call JS_InitClass to make a new instance of
&nbsp;&nbsp;&nbsp;&nbsp; * that class -- otherwise there would be a chicken-and-egg problem making
&nbsp;&nbsp;&nbsp;&nbsp; * the global object -- but you should call JS_InitClass if you require a
&nbsp;&nbsp;&nbsp;&nbsp; * constructor function for script authors to call via new, and/or a class
&nbsp;&nbsp;&nbsp;&nbsp; * prototype object ('MyClass.prototype') for authors to extend with new
&nbsp;&nbsp;&nbsp;&nbsp; * properties at run-time.
&nbsp;&nbsp;&nbsp;&nbsp; */
&nbsp;&nbsp;&nbsp; protoObj = JS_InitClass(cx, globalObj, &amp;my_class,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* native constructor function and min arg count */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MyClass, 0,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* prototype object properties and methods -- these
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; will be "inherited" by all instances through
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delegation up the instance's prototype link. */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my_props, my_methods,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* class constructor properties and methods */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my_static_props, my_static_methods);</tt></pre>
<h4>
Running scripts</h4>
<pre><tt>&nbsp;&nbsp;&nbsp; /* These should indicate source location for diagnostics. */
&nbsp;&nbsp;&nbsp; char *filename;
&nbsp;&nbsp;&nbsp; uintN lineno;
&nbsp;&nbsp;&nbsp; /*
&nbsp;&nbsp;&nbsp;&nbsp; * The return value comes back here -- if it could be a GC thing, you must
&nbsp;&nbsp;&nbsp;&nbsp; * add it to the GC's "root set" with JS_AddRoot(cx, &amp;thing) where thing
&nbsp;&nbsp;&nbsp;&nbsp; * is a JSString *, JSObject *, or jsdouble *, and remove the root before
&nbsp;&nbsp;&nbsp;&nbsp; * rval goes out of scope, or when rval is no longer needed.
&nbsp;&nbsp;&nbsp;&nbsp; */
&nbsp;&nbsp;&nbsp; jsval rval;
&nbsp;&nbsp;&nbsp; JSBool ok;
&nbsp;&nbsp;&nbsp; /*
&nbsp;&nbsp;&nbsp;&nbsp; * Some example source in a C string.&nbsp; Larger, non-null-terminated buffers
&nbsp;&nbsp;&nbsp;&nbsp; * can be used, if you pass the buffer length to JS_EvaluateScript.
&nbsp;&nbsp;&nbsp;&nbsp; */
&nbsp;&nbsp;&nbsp; char *source = "x * f(y)";
&nbsp;&nbsp;&nbsp; ok = JS_EvaluateScript(cx, globalObj, source, strlen(source),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; filename, lineno, &amp;rval);
&nbsp;&nbsp;&nbsp; if (ok) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Should get a number back from the example source. */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jsdouble d;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ok = JS_ValueToNumber(cx, rval, &amp;d);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; . . .
&nbsp;&nbsp;&nbsp; }</tt></pre>
<h4>
Calling functions</h4>
<pre><tt>&nbsp;&nbsp;&nbsp; /* Call a global function named "foo" that takes no arguments. */
&nbsp;&nbsp;&nbsp; ok = JS_CallFunctionName(cx, globalObj, "foo", 0, 0, &amp;rval);
&nbsp;&nbsp;&nbsp; jsval argv[2];
&nbsp;&nbsp;&nbsp; /* Call a function in obj's scope named "method", passing two arguments. */
&nbsp;&nbsp;&nbsp; argv[0] = . . .;
&nbsp;&nbsp;&nbsp; argv[1] = . . .;
&nbsp;&nbsp;&nbsp; ok = JS_CallFunctionName(cx, obj, "method", 2, argv, &amp;rval);</tt></pre>
<h4>
Shutting down</h4>
<pre><tt>&nbsp;&nbsp;&nbsp; /* For each context you've created: */
&nbsp;&nbsp;&nbsp; JS_DestroyContext(cx);
&nbsp;&nbsp;&nbsp; /* And finally: */
&nbsp;&nbsp;&nbsp; JS_Finish(rt);</tt></pre>
<h4>
Debugging API</h4>
See the<tt> trap, untrap, watch, unwatch, line2pc</tt>, and <tt>pc2line</tt>
commands in <tt>js.c</tt>. Also the (scant) comments in <i>jsdbgapi.h</i>.
<h2>
<a NAME="Design"></a>Design walk-through</h2>
This section must be brief for now -- it could easily turn into a book.
<h4>
JS "JavaScript Proper"</h4>
JS modules declare and implement the JavaScript compiler, interpreter,
decompiler, GC and atom manager, and standard classes.
<p>JavaScript uses untyped bytecode and runtime type tagging of data values.
The <tt>jsval</tt> type is a signed machine word that contains either a
signed integer value (if the low bit is set), or a type-tagged pointer
or boolean value (if the low bit is clear). Tagged pointers all refer to
8-byte-aligned things in the GC heap.
<p>Objects consist of a possibly shared structural description, called
the map or scope; and unshared property values in a vector, called the
slots. Object properties are associated with nonnegative integers stored
in <tt>jsval</tt>'s, or with atoms (unique string descriptors) if named
by an identifier or a non-integral index expression.
<p>Scripts contain bytecode, source annotations, and a pool of string,
number, and identifier literals. Functions are objects that extend scripts
or native functions with formal parameters, a literal syntax, and a distinct
primitive type ("function").
<p>The compiler consists of a recursive-descent parser and a random-logic
rather than table-driven lexical scanner. Semantic and lexical feedback
are used to disambiguate hard cases such as missing semicolons, assignable
expressions ("lvalues" in C parlance), etc. The parser generates bytecode
as it parses, using fixup lists for downward branches and code buffering
and rewriting for exceptional cases such as for loops. It attempts no error
recovery. The interpreter executes the bytecode of top-level scripts, and
calls itself indirectly to interpret function bodies (which are also scripts).
All state associated with an interpreter instance is passed through formal
parameters to the interpreter entry point; most implicit state is collected
in a type named JSContext. Therefore, all API and almost all other functions
in JSRef take a JSContext pointer as their first argument.
<p>The decompiler translates postfix bytecode into infix source by consulting
a separate byte-sized code, called source notes, to disambiguate bytecodes
that result from more than one grammatical production.
<p>The GC is a mark-and-sweep, non-conservative (perfect) collector. It
can allocate only fixed-sized things -- the current size is two machine
words. It is used to hold JS object and string descriptors (but not property
lists or string bytes), and double-precision floating point numbers. It
runs automatically only when maxbytes (as passed to <tt>JS_Init()</tt>)
bytes of GC things have been allocated and another thing-allocation request
is made. JS API users should call <tt>JS_GC()</tt> or <tt>JS_MaybeGC()</tt>
between script executions or from the branch callback, as often as necessary.
<p>An important point about the GC's "perfection": you must add roots for
new objects created by your native methods if you store references to them
into a non-JS structure in the malloc heap or in static data. Also, if
you make a new object in a native method, but do not store it through the
<tt>rval</tt>
result parameter (see math_abs in the "Using the JS API" section above)
so that it is in a known root, the object is guaranteed to survive only
until another new object is created. Either lock the first new object when
making two in a row, or store it in a root you've added, or store it via
rval.
<p>The atom manager consists of a hash table associating strings uniquely
with scanner/parser information such as keyword type, index in script or
function literal pool, etc. Atoms play three roles in JSRef: as literals
referred to by unaligned 16-bit immediate bytecode operands, as unique
string descriptors for efficient property name hashing, and as members
of the root GC set for perfect GC. This design therefore requires atoms
to be manually reference counted, from script literal pools (<tt>JSAtomMap</tt>)
and object symbol (<tt>JSSymbol</tt>) entry keys.
<p>Native objects and methods for arrays, booleans, dates, functions, numbers,
and strings are implemented using the JS API and certain internal interfaces
used as "fast paths".
<p>In general, errors are signaled by false or unoverloaded-null return
values, and are reported using <tt>JS_ReportError()</tt> or one of its
variants by the lowest level in order to provide the most detail. Client
code can substitute its own error reporting function and suppress errors,
or reflect them into Java or some other runtime system as exceptions, GUI
dialogs, etc..
<h2>
File walk-through (BADLY OUT OF DATE!)</h2>
<h4>
jsapi.c, jsapi.h</h4>
The public API to be used by almost all client code.&nbsp; If your client
code can't make do with <tt>jsapi.h</tt>, and must reach into a friend
or private js* file, please let us know so we can extend <tt>jsapi.h</tt>
to include what you need in a fashion that we can support over the long
run.
<h4>
jspubtd.h, jsprvtd.h</h4>
These files exist to group struct and scalar typedefs so they can be used
everywhere without dragging in struct definitions from N different files.
The <tt>jspubtd.h</tt> file contains public typedefs, and is included by
<tt>jsapi.h</tt>.
The <tt>jsprvtd.h</tt> file contains private typedefs and is included by
various .h files that need type names, but not type sizes or declarations.
<h4>
jsdbgapi.c, jsdbgapi.h</h4>
The Debugging API, still very much under development. Provided so far:
<ul>
<li>
Traps, with which breakpoints, single-stepping, step over, step out, and
so on can be implemented. The debugger will have to consult jsopcode.def
on its own to figure out where to plant trap instructions to implement
functions like step out, but a future jsdbgapi.h will provide convenience
interfaces to do these things. At most one trap per bytecode can be set.
When a script (<tt>JSScript</tt>) is destroyed, all traps set in its bytecode
are cleared.</li>
<li>
Watchpoints, for intercepting set operations on properties and running
a debugger-supplied function that receives the old value and a pointer
to the new one, which it can use to modify the new value being set.</li>
<li>
Line number to PC and back mapping functions. The line-to-PC direction
"rounds" toward the next bytecode generated from a line greater than or
equal to the input line, and may return the PC of a for-loop update part,
if given the line number of the loop body's closing brace. Any line after
the last one in a script or function maps to a PC one byte beyond the last
bytecode in the script. An example, from perfect.js:</li>
<pre><tt>14&nbsp;&nbsp; function perfect(n)
15&nbsp;&nbsp; {
16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print("The perfect numbers up to " +&nbsp; n + " are:");
17
18&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // We build sumOfDivisors[i] to hold a string expression for
19&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // the sum of the divisors of i, excluding i itself.
20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var sumOfDivisors = new ExprArray(n+1,1);
21&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (var divisor = 2; divisor &lt;= n; divisor++) {
22&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (var j = divisor + divisor; j &lt;= n; j += divisor) {
23&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sumOfDivisors[j] += " + " + divisor;
24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
25&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // At this point everything up to 'divisor' has its sumOfDivisors
26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // expression calculated, so we can determine whether it's perfect
27&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // already by evaluating.
28&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (eval(sumOfDivisors[divisor]) == divisor) {
29&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print("" + divisor + " = " + sumOfDivisors[divisor]);
30&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
31&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete sumOfDivisors;
33&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print("That's all.");
34&nbsp;&nbsp; }</tt></pre>
The line number to PC and back mappings can be tested using the js program
with the following script:
<pre><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; load("perfect.js")
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(perfect)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dis(perfect)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (var ln = 0; ln &lt;= 40; ln++) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var pc = line2pc(perfect,ln)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var ln2 = pc2line(perfect,pc)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print("\tline " + ln + " => pc " + pc + " => line " + ln2)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt></pre>
The result of the for loop over lines 0 to 40 inclusive is:
<pre><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 0 => pc 0 => line 16
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 1 => pc 0 => line 16
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 2 => pc 0 => line 16
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 3 => pc 0 => line 16
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 4 => pc 0 => line 16
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 5 => pc 0 => line 16
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 6 => pc 0 => line 16
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 7 => pc 0 => line 16
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 8 => pc 0 => line 16
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 9 => pc 0 => line 16
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 10 => pc 0 => line 16
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 11 => pc 0 => line 16
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 12 => pc 0 => line 16
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 13 => pc 0 => line 16
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 14 => pc 0 => line 16
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 15 => pc 0 => line 16
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 16 => pc 0 => line 16
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 17 => pc 19 => line 20
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 18 => pc 19 => line 20
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 19 => pc 19 => line 20
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 20 => pc 19 => line 20
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 21 => pc 36 => line 21
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 22 => pc 53 => line 22
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 23 => pc 74 => line 23
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 24 => pc 92 => line 22
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 25 => pc 106 => line 28
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 26 => pc 106 => line 28
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 27 => pc 106 => line 28
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 28 => pc 106 => line 28
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 29 => pc 127 => line 29
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 30 => pc 154 => line 21
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 31 => pc 154 => line 21
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 32 => pc 161 => line 32
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 33 => pc 172 => line 33
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 34 => pc 172 => line 33
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 35 => pc 172 => line 33
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 36 => pc 172 => line 33
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 37 => pc 172 => line 33
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 38 => pc 172 => line 33
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 39 => pc 172 => line 33
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line 40 => pc 172 => line 33</tt></pre>
</ul>
<h4>
jsconfig.h</h4>
Various configuration macros defined as 0 or 1 depending on how <tt>JS_VERSION</tt>
is defined (as 10 for JavaScript 1.0, 11 for JavaScript 1.1, etc.). Not
all macros are tested around related code yet. In particular, JS 1.0 support
is missing from JSRef. JS 1.2 support will appear in a future JSRef release.
<br>&nbsp;
<h4>
js.c</h4>
The "JS shell", a simple interpreter program that uses the JS API and more
than a few internal interfaces (some of these internal interfaces could
be replaced by <tt>jsapi.h</tt> calls). The js program built from this
source provides a test vehicle for evaluating scripts and calling functions,
trying out new debugger primitives, etc.
<h4>
jsarray.*, jsbool.*, jdsdate.*, jsfun.*, jsmath.*, jsnum.*, jsstr.*</h4>
These file pairs implement the standard classes and (where they exist)
their underlying primitive types. They have similar structure, generally
starting with class definitions and continuing with internal constructors,
finalizers, and helper functions.
<h4>
jsobj.*, jsscope.*</h4>
These two pairs declare and implement the JS object system. All of the
following happen here:
<ul>
<li>
creating objects by class and prototype, and finalizing objects;</li>
<li>
defining, looking up, getting, setting, and deleting properties;</li>
<li>
creating and destroying properties and binding names to them.</li>
</ul>
The details of an object map (scope) are mostly hidden in <tt>jsscope.[ch]</tt>,
where scopes start out as linked lists of symbols, and grow after some
threshold into PR hash tables.
<h4>
jsatom.c, jsatom.h</h4>
The atom manager. Contains well-known string constants, their atoms, the
global atom hash table and related state, the js_Atomize() function that
turns a counted string of bytes into an atom, and literal pool (<tt>JSAtomMap</tt>)
methods.
<h4>
jsgc.c, jsgc.h</h4>
[TBD]
<h4>
jsinterp.*, jscntxt.*</h4>
The bytecode interpreter, and related functions such as Call and AllocStack,
live in <i>jsinterp.c</i>. The JSContext constructor and destructor are
factored out into <i>jscntxt.c</i> for minimal linking when the compiler
part of JS is split from the interpreter part into a separate program.
<h4>
jsemit.*, jsopcode.tbl, jsopcode.*, jsparse.*, jsscan.*, jsscript.*</h4>
Compiler and decompiler modules. The <i>jsopcode.tbl</i> file is a C preprocessor
source that defines almost everything there is to know about JS bytecodes.
See its major comment for how to use it. For now, a debugger will use it
and its dependents such as <i>jsopcode.h</i> directly, but over time we
intend to extend <i>jsdbgapi.h</i> to hide uninteresting details and provide
conveniences. The code generator is split across paragraphs of code in
<i>jsparse.c</i>,
and the utility methods called on <tt>JSCodeGenerator</tt> appear in <i>jsemit.c</i>.
Source notes generated by <i>jsparse.c</i> and
<i>jsemit.c</i> are used
in <i>jsscript.c</i> to map line number to program counter and back.
<h4>
jstypes.h, jslog2.c</h4>
Fundamental representation types and utility macros. This file alone among
all .h files in JSRef must be included first by .c files. It is not nested
in .h files, as other prerequisite .h files generally are, since it is
also a direct dependency of most .c files and would be over-included if
nested in addition to being directly included. The one "not-quite-a-macro
macro" is the <tt>JS_CeilingLog2()</tt> function in <i>jslog2.c</i>.
<h4>
jsarena.c, jsarena.h</h4>
Last-In-First-Out allocation macros that amortize malloc costs and allow
for en-masse freeing. See the paper mentioned in prarena.h's major comment.
<h4>
jsutil.c, jsutil.h</h4>
The <tt>JS_ASSERT</tt> macro is used throughout JSRef source as a proof
device to make invariants and preconditions clear to the reader, and to
hold the line during maintenance and evolution against regressions or violations
of assumptions that it would be too expensive to test unconditionally at
run-time. Certain assertions are followed by run-time tests that cope with
assertion failure, but only where I'm too smart or paranoid to believe
the assertion will never fail...
<h4>
jsclist.h</h4>
Doubly-linked circular list struct and macros.
<h4>
jscpucfg.c</h4>
This standalone program generates <i>jscpucfg.h</i>, a header file containing
bytes per word and other constants that depend on CPU architecture and
C compiler type model. It tries to discover most of these constants by
running its own experiments on the build host, so if you are cross-compiling,
beware.
<h4>
prdtoa.c, prdtoa.h</h4>
David Gay's portable double-precision floating point to string conversion
code, with Permission To Use notice included.
<h4>
prhash.c, prhash.h</h4>
Portable, extensible hash tables. These use multiplicative hash for strength
reduction over division hash, yet with very good key distribution over
power of two table sizes. Collisions resolve via chaining, so each entry
burns a malloc and can fragment the heap.
<h4>
prlong.c, prlong.h</h4>
64-bit integer emulation, and compatible macros that use C's long long
type where it exists (my last company mapped long long to a 128-bit type,
but no real architecture does 128-bit ints yet).
<h4>
jsosdep.h</h4>
Annoying OS dependencies rationalized into a few "feature-test" macros
such as <tt>JS_HAVE_LONG_LONG</tt>.
<h4>
jsprf.*</h4>
Portable, buffer-overrun-resistant sprintf and friends. For no good reason
save lack of time, the %e, %f, and %g formats cause your system's native
sprintf, rather than <tt>JS_dtoa()</tt>, to be used. This bug doesn't affect
JSRef, because it uses its own <tt>JS_dtoa()</tt> call in <i>jsnum.c</i>
to convert from double to string, but it's a bug that we'll fix later,
and one you should be aware of if you intend to use a <tt>JS_*printf()</tt>&nbsp;
function with your own floating type arguments - various vendor sprintf's
mishandle NaN, +/-Inf, and some even print normal floating values inaccurately.
<h4>
prmjtime.c, prmjtime.h</h4>
Time functions. These interfaces are named in a way that makes local vs.
universal time confusion likely. Caveat emptor, and we're working on it.
To make matters worse, Java (and therefore JavaScript) uses "local" time
numbers (offsets from the epoch) in its Date class.
</body>
</html>

View File

@@ -0,0 +1,12 @@
mozilla/js/src/*
mozilla/js/src/config/*
mozilla/js/src/fdlibm/*
mozilla/js/src/liveconnect/*
mozilla/js/src/liveconnect/_jni/*
mozilla/js/src/liveconnect/classes/*
mozilla/js/src/liveconnect/classes/netscape/*
mozilla/js/src/liveconnect/classes/netscape/javascript/*
mozilla/js/src/liveconnect/config/*
mozilla/js/src/liveconnect/macbuild/*
mozilla/js/src/liveconnect/macbuild/JavaSession/*
mozilla/js/src/macbuild/*

65
mozilla/js/src/config.mk Normal file
View File

@@ -0,0 +1,65 @@
ifdef JS_DIST
DIST = $(JS_DIST)
else
DIST = $(DEPTH)/../../dist/$(OBJDIR)
endif
# Set os+release dependent make variables
OS_ARCH := $(subst /,_,$(shell uname -s))
# Attempt to differentiate between SunOS 5.4 and x86 5.4
OS_CPUARCH := $(shell uname -m)
ifeq ($(OS_CPUARCH),i86pc)
OS_RELEASE := $(shell uname -r)_$(OS_CPUARCH)
else
ifeq ($(OS_ARCH),AIX)
OS_RELEASE := $(shell uname -v).$(shell uname -r)
else
OS_RELEASE := $(shell uname -r)
endif
endif
# Virtually all Linux versions are identical.
# Any distinctions are handled in linux.h
ifeq ($(OS_ARCH),Linux)
OS_CONFIG := Linux_All
else
ifeq ($(OS_ARCH),dgux)
OS_CONFIG := dgux
else
OS_CONFIG := $(OS_ARCH)$(OS_OBJTYPE)$(OS_RELEASE)
endif
endif
ASFLAGS =
DEFINES =
ifeq ($(OS_ARCH), WINNT)
INSTALL = nsinstall
else
INSTALL = $(DEPTH)/../../dist/$(OBJDIR)/bin/nsinstall
endif
ifdef BUILD_OPT
OPTIMIZER = -O
DEFINES += -UDEBUG -DNDEBUG -UDEBUG_$(shell whoami)
OBJDIR_TAG = _OPT
else
ifdef USE_MSVC
OPTIMIZER = -Zi
else
OPTIMIZER = -g
endif
DEFINES += -DDEBUG -DDEBUG_$(shell whoami)
OBJDIR_TAG = _DBG
endif
include $(DEPTH)/config/$(OS_CONFIG).mk
# Name of the binary code directories
OBJDIR = $(OS_CONFIG)$(OBJDIR_TAG).OBJ
VPATH = $(OBJDIR)
# Automatic make dependencies file
DEPENDENCIES = $(OBJDIR)/.md

1609
mozilla/js/src/js.c Normal file

File diff suppressed because it is too large Load Diff

4027
mozilla/js/src/js.mak Normal file

File diff suppressed because it is too large Load Diff

BIN
mozilla/js/src/js.mdp Normal file

Binary file not shown.

206
mozilla/js/src/js.msg Normal file
View File

@@ -0,0 +1,206 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
This is the JavaScript error message file.
The format for each JS error message is:
MSG_DEF(<SYMBOLIC_NAME>, <ERROR_NUMBER>, <ARGUMENT_COUNT>, <EXCEPTION_NAME>,
<FORMAT_STRING>)
where ;
<SYMBOLIC_NAME> is a legal C identifer that will be used in the
JS engine source.
<ERROR_NUMBER> is an unique integral value identifying this error.
<ARGUMENT_COUNT> is an integer literal specifying the total number of
replaceable arguments in the following format string.
<EXCEPTION_NAME> is an exception index from the enum in jsexn.c;
JSEXN_NONE for none. The given exception index will be raised by the
engine when the corresponding error occurs.
<FORMAT_STRING> is a string literal, optionally containing sequences
{X} where X is an integer representing the argument number that will
be replaced with a string value when the error is reported.
e.g.
MSG_DEF(JSMSG_NOT_A_SUBSPECIES, 73, JSEXN_NONE, 2,
"{0} is not a member of the {1} family")
can be used :
JS_ReportErrorNumber(JSMSG_NOT_A_SUBSPECIES, "Rhino", "Monkey");
to report :
"Rhino is not a member of the Monkey family"
*/
MSG_DEF(JSMSG_NOT_AN_ERROR, 0, 0, JSEXN_NONE, "<Error #0 is reserved>")
MSG_DEF(JSMSG_NOT_DEFINED, 1, 1, JSEXN_REFERENCEERR, "{0} is not defined")
MSG_DEF(JSMSG_NO_REG_EXPS, 2, 1, JSEXN_INTERNALERR, "sorry, regular expression are not supported")
MSG_DEF(JSMSG_MORE_ARGS_NEEDED, 3, 3, JSEXN_NONE, "{0} requires more than {1} argument{2}")
MSG_DEF(JSMSG_BAD_CHAR, 4, 1, JSEXN_NONE, "invalid format character {0}")
MSG_DEF(JSMSG_BAD_TYPE, 5, 1, JSEXN_NONE, "unknown type {0}")
MSG_DEF(JSMSG_CANT_LOCK, 6, 0, JSEXN_NONE, "can't lock memory")
MSG_DEF(JSMSG_CANT_UNLOCK, 7, 0, JSEXN_NONE, "can't unlock memory")
MSG_DEF(JSMSG_INCOMPATIBLE_PROTO, 8, 3, JSEXN_TARGETERR, "{0}.prototype.{1} called on incompatible {2}")
MSG_DEF(JSMSG_NO_CONSTRUCTOR, 9, 1, JSEXN_NONE, "{0} has no constructor")
MSG_DEF(JSMSG_CANT_ALIAS, 10, 3, JSEXN_NONE, "can't alias {0} to {1} in class {2}")
MSG_DEF(JSMSG_NO_PROTO, 11, 1, JSEXN_INTERNALERR, "sorry, Array.prototype.{0} is not yet implemented")
MSG_DEF(JSMSG_BAD_SORT_ARG, 12, 0, JSEXN_ARRAYERR, "invalid Array.prototype.sort argument")
MSG_DEF(JSMSG_BAD_ATOMIC_NUMBER, 13, 1, JSEXN_INTERNALERR, "internal error: no index for atom {0}")
MSG_DEF(JSMSG_TOO_MANY_LITERALS, 14, 0, JSEXN_INTERNALERR, "too many literals")
MSG_DEF(JSMSG_CANT_WATCH, 15, 1, JSEXN_NONE, "can't watch non-native objects of class {0}")
MSG_DEF(JSMSG_STACK_UNDERFLOW, 16, 2, JSEXN_INTERNALERR, "internal error compiling {0}: stack underflow at pc {1}")
MSG_DEF(JSMSG_NEED_DIET, 17, 1, JSEXN_SYNTAXERR, "{0} too large")
MSG_DEF(JSMSG_BAD_CASE, 18, 2, JSEXN_SYNTAXERR, "{0}, line {1}: invalid case expression")
MSG_DEF(JSMSG_READ_ONLY, 19, 1, JSEXN_ERR, "{0} is read-only")
MSG_DEF(JSMSG_BAD_FORMAL, 20, 0, JSEXN_SYNTAXERR, "malformed formal parameter")
MSG_DEF(JSMSG_SAME_FORMAL, 21, 1, JSEXN_NONE, "duplicate formal argument {0}")
MSG_DEF(JSMSG_NOT_FUNCTION, 22, 1, JSEXN_CALLERR, "{0} is not a function")
MSG_DEF(JSMSG_NOT_CONSTRUCTOR, 23, 1, JSEXN_CONSTRUCTORERR, "{0} is not a constructor")
MSG_DEF(JSMSG_STACK_OVERFLOW, 24, 1, JSEXN_NONE, "stack overflow in {0}")
MSG_DEF(JSMSG_NOT_EXPORTED, 25, 1, JSEXN_NONE, "{0} is not exported")
MSG_DEF(JSMSG_OVER_RECURSED, 26, 0, JSEXN_NONE, "too much recursion")
MSG_DEF(JSMSG_IN_NOT_OBJECT, 27, 0, JSEXN_ERR, "target of 'in' operator must be an object")
MSG_DEF(JSMSG_BAD_NEW_RESULT, 28, 1, JSEXN_NONE, "invalid new expression result {0}")
MSG_DEF(JSMSG_BAD_SHARP_DEF, 29, 1, JSEXN_ERR, "invalid sharp variable definition #{0}=")
MSG_DEF(JSMSG_BAD_SHARP_USE, 30, 1, JSEXN_ERR, "invalid sharp variable use #{0}#")
MSG_DEF(JSMSG_BAD_INSTANCEOF_RHS, 31, 1, JSEXN_ERR, "invalid instanceof operand {0}")
MSG_DEF(JSMSG_BAD_BYTECODE, 32, 1, JSEXN_INTERNALERR, "unimplemented JavaScript bytecode {0}")
MSG_DEF(JSMSG_BAD_RADIX, 33, 1, JSEXN_ERR, "illegal radix {0}")
MSG_DEF(JSMSG_NAN, 34, 1, JSEXN_ERR, "{0} is not a number")
MSG_DEF(JSMSG_CANT_CONVERT, 35, 1, JSEXN_TOPRIMITIVEERR, "can't convert {0} to an integer")
MSG_DEF(JSMSG_CYCLIC_VALUE, 36, 1, JSEXN_ERR, "cyclic {0} value")
MSG_DEF(JSMSG_PERMANENT, 37, 1, JSEXN_ERR, "{0} is permanent")
MSG_DEF(JSMSG_CANT_CONVERT_TO, 38, 2, JSEXN_DEFAULTVALUEERR, "can't convert {0} to {1}")
MSG_DEF(JSMSG_NO_PROPERTIES, 39, 1, JSEXN_TOOBJECTERR, "{0} has no properties")
MSG_DEF(JSMSG_CANT_FIND_CLASS, 40, 1, JSEXN_NONE, "can't find class id {0}")
MSG_DEF(JSMSG_CANT_XDR_CLASS, 41, 1, JSEXN_NONE, "can't XDR class {0}")
MSG_DEF(JSMSG_BYTECODE_TOO_BIG, 42, 2, JSEXN_INTERNALERR, "bytecode {0} too large (limit {1})")
MSG_DEF(JSMSG_UNKNOWN_FORMAT, 43, 1, JSEXN_INTERNALERR, "unknown bytecode format {0}")
MSG_DEF(JSMSG_TOO_MANY_CON_ARGS, 44, 0, JSEXN_SYNTAXERR, "too many constructor arguments")
MSG_DEF(JSMSG_TOO_MANY_FUN_ARGS, 45, 0, JSEXN_SYNTAXERR, "too many function arguments")
MSG_DEF(JSMSG_BAD_QUANTIFIER, 46, 1, JSEXN_SYNTAXERR, "invalid quantifier {0}")
MSG_DEF(JSMSG_MIN_TOO_BIG, 47, 1, JSEXN_SYNTAXERR, "overlarge minimum {0}")
MSG_DEF(JSMSG_MAX_TOO_BIG, 48, 1, JSEXN_SYNTAXERR, "overlarge maximum {0}")
MSG_DEF(JSMSG_OUT_OF_ORDER, 49, 1, JSEXN_SYNTAXERR, "maximum {0} less than minimum")
MSG_DEF(JSMSG_ZERO_QUANTIFIER, 50, 1, JSEXN_SYNTAXERR, "zero quantifier {0}")
MSG_DEF(JSMSG_UNTERM_QUANTIFIER, 51, 1, JSEXN_SYNTAXERR, "unterminated quantifier {0}")
MSG_DEF(JSMSG_EMPTY_BEFORE_STAR, 52, 0, JSEXN_SYNTAXERR, "regular expression before * could be empty")
MSG_DEF(JSMSG_EMPTY_BEFORE_PLUS, 53, 0, JSEXN_SYNTAXERR, "regular expression before + could be empty")
MSG_DEF(JSMSG_MISSING_PAREN, 54, 1, JSEXN_SYNTAXERR, "unterminated parenthetical {0}")
MSG_DEF(JSMSG_UNTERM_CLASS, 55, 1, JSEXN_SYNTAXERR, "unterminated character class {0}")
MSG_DEF(JSMSG_TRAILING_SLASH, 56, 0, JSEXN_SYNTAXERR, "trailing \\ in regular expression")
MSG_DEF(JSMSG_BAD_CLASS_RANGE, 57, 0, JSEXN_SYNTAXERR, "invalid range in character class")
MSG_DEF(JSMSG_BAD_FLAG, 58, 1, JSEXN_SYNTAXERR, "invalid regular expression flag {0}")
MSG_DEF(JSMSG_NO_INPUT, 59, 3, JSEXN_SYNTAXERR, "no input for /{0}/{1}{2}")
MSG_DEF(JSMSG_CANT_OPEN, 60, 2, JSEXN_NONE, "can't open {0}: {1}")
MSG_DEF(JSMSG_BAD_STRING_MASK, 61, 1, JSEXN_ERR, "invalid string escape mask {0}")
MSG_DEF(JSMSG_NO_STRING_PROTO, 62, 1, JSEXN_INTERNALERR, "sorry, String.prototype.{0} is not yet implemented")
MSG_DEF(JSMSG_END_OF_DATA, 63, 0, JSEXN_NONE, "unexpected end of data")
MSG_DEF(JSMSG_SEEK_BEYOND_START, 64, 0, JSEXN_NONE, "illegal seek beyond start")
MSG_DEF(JSMSG_SEEK_BEYOND_END, 65, 0, JSEXN_NONE, "illegal seek beyond end")
MSG_DEF(JSMSG_END_SEEK, 66, 0, JSEXN_NONE, "illegal end-based seek")
MSG_DEF(JSMSG_WHITHER_WHENCE, 67, 1, JSEXN_NONE, "unknown seek whence: {0}")
MSG_DEF(JSMSG_BAD_JVAL_TYPE, 68, 1, JSEXN_NONE, "unknown jsval type {0} for XDR")
MSG_DEF(JSMSG_PAREN_BEFORE_FORMAL, 69, 0, JSEXN_SYNTAXERR, "missing ( before formal parameters")
MSG_DEF(JSMSG_MISSING_FORMAL, 70, 0, JSEXN_SYNTAXERR, "missing formal parameter")
MSG_DEF(JSMSG_PAREN_AFTER_FORMAL, 71, 0, JSEXN_SYNTAXERR, "missing ) after formal parameters")
MSG_DEF(JSMSG_CURLY_BEFORE_BODY, 72, 0, JSEXN_SYNTAXERR, "missing { before function body")
MSG_DEF(JSMSG_CURLY_AFTER_BODY, 73, 0, JSEXN_SYNTAXERR, "missing } after function body")
MSG_DEF(JSMSG_PAREN_BEFORE_COND, 74, 0, JSEXN_SYNTAXERR, "missing ( before condition")
MSG_DEF(JSMSG_PAREN_AFTER_COND, 75, 0, JSEXN_SYNTAXERR, "missing ) after condition")
MSG_DEF(JSMSG_NO_IMPORT_NAME, 76, 0, JSEXN_SYNTAXERR, "missing name in import statement")
MSG_DEF(JSMSG_NAME_AFTER_DOT, 77, 0, JSEXN_SYNTAXERR, "missing name after . operator")
MSG_DEF(JSMSG_BRACKET_IN_INDEX, 78, 0, JSEXN_SYNTAXERR, "missing ] in index expression")
MSG_DEF(JSMSG_NO_EXPORT_NAME, 79, 0, JSEXN_SYNTAXERR, "missing name in export statement")
MSG_DEF(JSMSG_PAREN_BEFORE_SWITCH, 80, 0, JSEXN_SYNTAXERR, "missing ( before switch expression")
MSG_DEF(JSMSG_PAREN_AFTER_SWITCH, 81, 0, JSEXN_SYNTAXERR, "missing ) after switch expression")
MSG_DEF(JSMSG_CURLY_BEFORE_SWITCH, 82, 0, JSEXN_SYNTAXERR, "missing { before switch body")
MSG_DEF(JSMSG_COLON_AFTER_CASE, 83, 0, JSEXN_SYNTAXERR, "missing : after case label")
MSG_DEF(JSMSG_WHILE_AFTER_DO, 84, 0, JSEXN_SYNTAXERR, "missing while after do-loop body")
MSG_DEF(JSMSG_PAREN_AFTER_FOR, 85, 0, JSEXN_SYNTAXERR, "missing ( after for")
MSG_DEF(JSMSG_SEMI_AFTER_FOR_INIT, 86, 0, JSEXN_SYNTAXERR, "missing ; after for-loop initializer")
MSG_DEF(JSMSG_SEMI_AFTER_FOR_COND, 87, 0, JSEXN_SYNTAXERR, "missing ; after for-loop condition")
MSG_DEF(JSMSG_PAREN_AFTER_FOR_CTRL, 88, 0, JSEXN_SYNTAXERR, "missing ) after for-loop control")
MSG_DEF(JSMSG_CURLY_BEFORE_TRY, 89, 0, JSEXN_SYNTAXERR, "missing { before try block")
MSG_DEF(JSMSG_CURLY_AFTER_TRY, 90, 0, JSEXN_SYNTAXERR, "missing } after try block")
MSG_DEF(JSMSG_PAREN_BEFORE_CATCH, 91, 0, JSEXN_SYNTAXERR, "missing ( before catch")
MSG_DEF(JSMSG_CATCH_IDENTIFIER, 92, 0, JSEXN_SYNTAXERR, "missing identifier in catch")
MSG_DEF(JSMSG_PAREN_AFTER_CATCH, 93, 0, JSEXN_SYNTAXERR, "missing ) after catch")
MSG_DEF(JSMSG_CURLY_BEFORE_CATCH, 94, 0, JSEXN_SYNTAXERR, "missing { before catch block")
MSG_DEF(JSMSG_CURLY_AFTER_CATCH, 95, 0, JSEXN_SYNTAXERR, "missing } after catch block")
MSG_DEF(JSMSG_CURLY_BEFORE_FINALLY, 96, 0, JSEXN_SYNTAXERR, "missing { before finally block")
MSG_DEF(JSMSG_CURLY_AFTER_FINALLY, 97, 0, JSEXN_SYNTAXERR, "missing } after finally block")
MSG_DEF(JSMSG_CATCH_OR_FINALLY, 98, 0, JSEXN_SYNTAXERR, "missing catch or finally after try")
MSG_DEF(JSMSG_PAREN_BEFORE_WITH, 99, 0, JSEXN_SYNTAXERR, "missing ( before with-statement object")
MSG_DEF(JSMSG_PAREN_AFTER_WITH, 100, 0, JSEXN_SYNTAXERR, "missing ) after with-statement object")
MSG_DEF(JSMSG_CURLY_IN_COMPOUND, 101, 0, JSEXN_SYNTAXERR, "missing } in compound statement")
MSG_DEF(JSMSG_NO_VARIABLE_NAME, 102, 0, JSEXN_SYNTAXERR, "missing variable name")
MSG_DEF(JSMSG_COLON_IN_COND, 103, 0, JSEXN_SYNTAXERR, "missing : in conditional expression")
MSG_DEF(JSMSG_PAREN_AFTER_ARGS, 104, 0, JSEXN_SYNTAXERR, "missing ) after argument list")
MSG_DEF(JSMSG_BRACKET_AFTER_LIST, 105, 0, JSEXN_SYNTAXERR, "missing ] after element list")
MSG_DEF(JSMSG_COLON_AFTER_ID, 106, 0, JSEXN_SYNTAXERR, "missing : after property id")
MSG_DEF(JSMSG_CURLY_AFTER_LIST, 107, 0, JSEXN_SYNTAXERR, "missing } after property list")
MSG_DEF(JSMSG_PAREN_IN_PAREN, 108, 0, JSEXN_SYNTAXERR, "missing ) in parenthetical")
MSG_DEF(JSMSG_SEMI_BEFORE_STMNT, 109, 0, JSEXN_SYNTAXERR, "missing ; before statement")
MSG_DEF(JSMSG_NO_RETURN_VALUE, 110, 0, JSEXN_NONE, "function does not always return a value")
MSG_DEF(JSMSG_DUPLICATE_FORMAL, 111, 1, JSEXN_NONE, "duplicate formal argument {0}")
MSG_DEF(JSMSG_EQUAL_AS_ASSIGN, 112, 1, JSEXN_NONE, "test for equality (==) mistyped as assignment (=)?{0}")
MSG_DEF(JSMSG_BAD_IMPORT, 113, 0, JSEXN_SYNTAXERR, "invalid import expression")
MSG_DEF(JSMSG_TOO_MANY_DEFAULTS, 114, 0, JSEXN_SYNTAXERR, "more than one switch default")
MSG_DEF(JSMSG_TOO_MANY_CASES, 115, 0, JSEXN_INTERNALERR, "too many switch cases")
MSG_DEF(JSMSG_BAD_SWITCH, 116, 0, JSEXN_SYNTAXERR, "invalid switch statement")
MSG_DEF(JSMSG_BAD_FOR_LEFTSIDE, 117, 0, JSEXN_SYNTAXERR, "invalid for/in left-hand side")
MSG_DEF(JSMSG_CATCH_AFTER_GENERAL, 118, 0, JSEXN_NONE, "catch clause after general catch")
MSG_DEF(JSMSG_CATCH_WITHOUT_TRY, 119, 0, JSEXN_SYNTAXERR, "catch without try")
MSG_DEF(JSMSG_FINALLY_WITHOUT_TRY, 120, 0, JSEXN_SYNTAXERR, "finally without try")
MSG_DEF(JSMSG_LABEL_NOT_FOUND, 121, 0, JSEXN_SYNTAXERR, "label not found")
MSG_DEF(JSMSG_TOUGH_BREAK, 122, 0, JSEXN_SYNTAXERR, "invalid break")
MSG_DEF(JSMSG_BAD_CONTINUE, 123, 0, JSEXN_SYNTAXERR, "invalid continue")
MSG_DEF(JSMSG_BAD_RETURN, 124, 0, JSEXN_SYNTAXERR, "invalid return")
MSG_DEF(JSMSG_BAD_LABEL, 125, 0, JSEXN_SYNTAXERR, "invalid label")
MSG_DEF(JSMSG_DUPLICATE_LABEL, 126, 0, JSEXN_SYNTAXERR, "duplicate label")
MSG_DEF(JSMSG_VAR_HIDES_ARG, 127, 1, JSEXN_NONE, "variable {0} hides argument")
MSG_DEF(JSMSG_BAD_VAR_INIT, 128, 0, JSEXN_SYNTAXERR, "invalid variable initialization")
MSG_DEF(JSMSG_BAD_LEFTSIDE_OF_ASS, 129, 0, JSEXN_SYNTAXERR, "invalid assignment left-hand side")
MSG_DEF(JSMSG_BAD_OPERAND, 130, 1, JSEXN_SYNTAXERR, "invalid {0} operand")
MSG_DEF(JSMSG_BAD_PROP_ID, 131, 0, JSEXN_SYNTAXERR, "invalid property id")
MSG_DEF(JSMSG_RESERVED_ID, 132, 1, JSEXN_SYNTAXERR, "{0} is a reserved identifier")
MSG_DEF(JSMSG_SYNTAX_ERROR, 133, 0, JSEXN_SYNTAXERR, "syntax error")
MSG_DEF(JSMSG_BAD_SHARP_VAR_DEF, 134, 0, JSEXN_SYNTAXERR, "invalid sharp variable definition")
MSG_DEF(JSMSG_BAD_PROTOTYPE, 135, 1, JSEXN_ERR, "'prototype' property of {0} is not an object")
MSG_DEF(JSMSG_MISSING_EXPONENT, 136, 0, JSEXN_SYNTAXERR, "missing exponent")
MSG_DEF(JSMSG_OUT_OF_MEMORY, 137, 0, JSEXN_ERR, "out of memory")
MSG_DEF(JSMSG_UNTERMINATED_STRING, 138, 0, JSEXN_SYNTAXERR, "unterminated string literal")
MSG_DEF(JSMSG_NESTED_COMMENT, 139, 0, JSEXN_SYNTAXERR, "nested comment")
MSG_DEF(JSMSG_UNTERMINATED_COMMENT, 140, 0, JSEXN_SYNTAXERR, "unterminated comment")
MSG_DEF(JSMSG_UNTERMINATED_REGEXP, 141, 0, JSEXN_SYNTAXERR, "unterminated regular expression literal")
MSG_DEF(JSMSG_BAD_REGEXP_FLAG, 142, 0, JSEXN_SYNTAXERR, "invalid flag after regular expression")
MSG_DEF(JSMSG_SHARPVAR_TOO_BIG, 143, 0, JSEXN_SYNTAXERR, "overlarge sharp variable number")
MSG_DEF(JSMSG_ILLEGAL_CHARACTER, 144, 0, JSEXN_SYNTAXERR, "illegal character")
MSG_DEF(JSMSG_BAD_OCTAL, 145, 1, JSEXN_NONE, "{0} is not a legal ECMA-262 numeric constant")
MSG_DEF(JSMSG_BAD_INDIRECT_CALL, 146, 1, JSEXN_CALLERR, "function {0} must be called directly, and not by way of a function of another name.")
MSG_DEF(JSMSG_UNCAUGHT_EXCEPTION, 147, 1, JSEXN_NONE, "uncaught exception: {0}")

79
mozilla/js/src/js3240.rc Normal file
View File

@@ -0,0 +1,79 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winver.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,0,0,0
PRODUCTVERSION 4,0,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x10004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904e4"
BEGIN
VALUE "CompanyName", "Netscape Communications Corporation\0"
VALUE "FileDescription", "Netscape 32-bit JavaScript Module\0"
VALUE "FileVersion", "4.0\0"
VALUE "InternalName", "JS3240\0"
VALUE "LegalCopyright", "Copyright Netscape Communications. 1994-96\0"
VALUE "LegalTrademarks", "Netscape, Mozilla\0"
VALUE "OriginalFilename", "js3240.dll\0"
VALUE "ProductName", "NETSCAPE\0"
VALUE "ProductVersion", "4.0\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""winver.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////

623
mozilla/js/src/jsOS240.def Normal file
View File

@@ -0,0 +1,623 @@
; The contents of this file are subject to the Netscape Public License
; Version 1.0 (the "NPL"); you may not use this file except in
; compliance with the NPL. You may obtain a copy of the NPL at
; http://www.mozilla.org/NPL/
;
; Software distributed under the NPL is distributed on an "AS IS" basis,
; WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
; for the specific language governing rights and limitations under the
; NPL.
;
; The Initial Developer of this code under the NPL is Netscape
; Communications Corporation. Portions created by Netscape are
; Copyright (C) 1998 Netscape Communications Corporation. All Rights
; Reserved.
LIBRARY JS3240 INITINSTANCE TERMINSTANCE
PROTMODE
DESCRIPTION 'Netscape OS/2 JavaScript Library'
CODE LOADONCALL MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE MULTIPLE NONSHARED
EXPORTS
;====================== win16 exports these at least... ===========
; JS_Init = JS_Init @2
; JS_Finish = JS_Finish @3
; JS_GetNaNValue
; JS_GetNegativeInfinityValue
; JS_GetPositiveInfinityValue
; JS_GetEmptyStringValue
; JS_ConvertValue
; JS_ValueToObject
; JS_ValueToFunction
; JS_ValueToString
; JS_ValueToNumber
; JS_ValueToBoolean
; JS_TypeOfValue
; JS_GetTypeName
; JS_Lock
; JS_Unlock
; JS_NewContext
; JS_DestroyContext
; JS_ContextIterator
; JS_GetGlobalObject
; JS_SetGlobalObject
; JS_InitStandardClasses
;; JS_GetStaticLink
; JS_malloc
; JS_realloc
; JS_free
; JS_strdup
; JS_NewDouble
; JS_NewDoubleValue
; JS_AddRoot
; JS_RemoveRoot
; JS_LockGCThing
; JS_UnlockGCThing
; JS_GC
; JS_PropertyStub
; JS_EnumerateStub
; JS_ResolveStub
; JS_ConvertStub
; JS_FinalizeStub
; JS_InitClass
; JS_GetClass
; JS_InstanceOf
; JS_GetPrivate
; JS_SetPrivate
; JS_GetInstancePrivate
; JS_GetPrototype
; JS_GetParent
; JS_SetParent
; JS_GetConstructor
; JS_NewObject
; JS_DefineObject
; JS_DefineConstDoubles
; JS_DefineProperties
; JS_DefineProperty
; JS_DefinePropertyWithTinyId
; JS_AliasProperty
; JS_LookupProperty
; JS_GetProperty
; JS_SetProperty
; JS_DeleteProperty
; JS_NewArrayObject
; JS_DefineElement
; JS_AliasElement
; JS_LookupElement
; JS_GetElement
; JS_SetElement
; JS_DeleteElement
; JS_ClearScope
; JS_NewFunction
; JS_GetFunctionObject
; JS_GetFunctionName
; JS_DefineFunctions
; JS_DefineFunction
; JS_CompileScript
; JS_DestroyScript
; JS_CompileFunction
; JS_DecompileScript
; JS_DecompileFunction
; JS_DecompileFunctionBody
; JS_ExecuteScript
; JS_EvaluateScript
; JS_CallFunction
; JS_CallFunctionName
; JS_CallFunctionValue
; JS_SetBranchCallback
; JS_IsRunning
; JS_NewString
; JS_NewStringCopyN
; JS_NewStringCopyZ
; JS_InternString
; JS_GetStringBytes
; JS_GetStringLength
; JS_CompareStrings
; JS_ReportError
; JS_ReportOutOfMemory
; JS_SetErrorReporter
; JS_NewRegExpObject
; JS_SetRegExpInput
; JS_ClearRegExpStatics
;=================================================
;00001:jsstr (OFFSET:0x00002e17, SIZE:0x0000ae17):
; - Public Definitions:
; js_EmptySubString
; js_CompareStrings
; js_HashString
; js_ValueToString
; js_StringToObject
; js_FinalizeString
; js_NewStringCopyZ
; js_NewString
; js_InitStringClass
; js_NewStringCopyN
; js_BoyerMooreHorspool
;
;
;00002:jsscript (OFFSET:0x0000dc2e, SIZE:0x00003abb):
; - Public Definitions:
; js_LineNumberToPC
; js_PCToLineNumber
; js_GetSrcNote
; js_DestroyScript
; js_NewScript
;
;
;00003:jsscope (OFFSET:0x000116e9, SIZE:0x00004f82):
; - Public Definitions:
; js_hash_scope_ops
; js_list_scope_ops
; js_DestroyProperty
; js_NewProperty
; js_IdToValue
; js_HashValue
; js_DestroyScope
; js_MutateScope
; js_DropScope
; js_HoldScope
; js_NewScope
; js_GetMutableScope
; js_HoldProperty
; js_DropProperty
;
;
;00004:jsscan (OFFSET:0x0001666b, SIZE:0x00008890):
; - Public Definitions:
; js_MatchToken
; js_FlushNewlines
; js_PeekTokenSameLine
; js_UngetToken
; js_GetToken
; js_PeekToken
; js_ReportCompileError
js_CloseTokenStream
js_NewBufferTokenStream
; js_NewTokenStream
; js_InitScanner
;
;
;00005:jsregexp (OFFSET:0x0001eefb, SIZE:0x0000eee4):
; - Public Definitions:
; js_RegExpClass
; reopsize
; js_NewRegExpObject
; js_InitRegExpClass
; js_FreeRegExpStatics
; js_InitRegExpStatics
; js_ExecuteRegExp
; js_NewRegExpOpt
; js_DestroyRegExp
; js_NewRegExp
;
;
;00006:jsparse (OFFSET:0x0002dddf, SIZE:0x00010b71):
; - Public Definitions:
; js_ParseFunctionBody
js_Parse
;
;
;00007:jsopcode (OFFSET:0x0003e950, SIZE:0x0000d362):
; - Public Definitions:
; js_EscapeMap
; js_NumCodeSpecs
; js_CodeSpec
; js_incop_str
; js_true_str
; js_false_str
; js_this_str
; js_null_str
; js_void_str
; js_typeof_str
; js_delete_str
; js_new_str
; js_ValueToSource
; js_DecompileScript
; js_DecompileCode
; js_DecompileFunction
; js_puts
; js_printf
; js_GetPrinterOutput
; js_DestroyPrinter
; js_NewPrinter
; js_EscapeString
; js_Disassemble1
; js_Disassemble
;
;00008:jsobj (OFFSET:0x0004bcb2, SIZE:0x000090a4):
; - Public Definitions:
; js_WithClass
; js_ObjectClass
; js_TryValueOf
; js_ValueToNonNullObject
; js_TryMethod
; js_ObjectToString
; js_SetClassPrototype
; js_DeleteProperty2
; js_DeleteProperty
; js_SetProperty
; js_GetProperty
; js_FindVariableScope
; js_FindVariable
; js_FindProperty
; js_LookupProperty
; js_DefineProperty
; js_FreeSlot
; js_AllocSlot
; js_FinalizeObject
; js_GetClassPrototype
; js_NewObject
; js_InitObjectClass
; js_ValueToObject
; js_obj_toString
; js_SetSlot
; js_GetSlot
;
;
;00009:jsnum (OFFSET:0x00054d56, SIZE:0x00004f29):
; - Public Definitions:
; js_ValueToInt32
; js_NumberToObject
; js_FinalizeDouble
; js_InitNumberClass
; js_NumberToString
; js_NewDoubleValue
; js_NewDouble
; js_ValueToNumber
;
;
;00010:jsmath (OFFSET:0x00059c7f, SIZE:0x000054b6):
; - Public Definitions:
; js_InitMathClass
;
;
;00011:jsjava (OFFSET:0x0005f135, SIZE:0x00022aad):
; - Public Definitions:
; js_Hooks
; MojaSrcLog
; finalizeTask
JSJ_FindCurrentJSContext
; JSJ_GetPrincipals
JSJ_IsSafeMethod
JSJ_InitContext
JSJ_Init
js_JSErrorToJException
js_JavaErrorReporter
js_RemoveReflection
js_ReflectJObjectToJSObject
js_convertJObjectToJSValue
js_convertJSValueToJObject
js_ReflectJSObjectToJObject
; js_ReflectJClassToJSObject
JSJ_ExitJS
JSJ_EnterJS
JSJ_CurrentContext
JSJ_IsEnabled
;added in GA code - DSR70297
JSJ_Finish
JSJ_IsCalledFromJava
js_GetJSPrincipalsFromJavaCaller
;
;
;00012:jsinterp (OFFSET:0x00081be2, SIZE:0x00012274):
; - Public Definitions:
; js_Call
; js_Interpret
; js_SetLocalVariable
; js_GetLocalVariable
; js_SetArgument
; js_GetArgument
; js_FlushPropertyCacheByProp
; js_FlushPropertyCache
;
;
;00013:jsgc (OFFSET:0x00093e56, SIZE:0x00004f8d):
; - Public Definitions:
; js_ForceGC
; js_UnlockGCThing
; js_LockGCThing
; js_GC
; js_AllocGCThing
; js_RemoveRoot
; js_AddRoot
; js_FinishGC
; js_InitGC
;
;
;00014:jsfun (OFFSET:0x00098de3, SIZE:0x0000977c):
; - Public Definitions:
; js_FunctionClass
; js_ClosureClass
; js_CallClass
; js_DefineFunction
; js_NewFunction
; js_InitCallAndClosureClasses
; js_InitFunctionClass
; js_ValueToFunction
; js_SetCallVariable
; js_GetCallVariable
; js_PutCallObject
; js_GetCallObject
;
;
;00015:jsemit (OFFSET:0x000a255f, SIZE:0x000077be):
; - Public Definitions:
; js_SrcNoteName
; js_SrcNoteArity
js_FinishTakingSrcNotes
; js_MoveSrcNotes
; js_GetSrcNoteOffset
; js_BumpSrcNoteDelta
; js_NewSrcNote3
; js_NewSrcNote2
; js_PopStatement
; js_EmitContinue
; js_EmitBreak
; js_SetSrcNoteOffset
; js_NewSrcNote
; js_PushStatement
; js_MoveCode
; js_SetJumpOffset
; js_Emit3
; js_Emit2
; js_Emit1
; js_UpdateDepth
; js_SrcNoteLength
; js_CancelLastOpcode
js_InitCodeGenerator
;
;
;00016:jsdbgapi (OFFSET:0x000a9d1d, SIZE:0x000057db):
; - Public Definitions:
; js_watchpoint_list
; js_trap_list
; JS_SetAnnotationInFrame
; JS_GetAnnotationFromFrame
; JS_GetJSPrincipalArrayFromFrame
; JS_NextJSFrame
; JS_InitJSFrameIterator
JS_LineNumberToPC
JS_PCToLineNumber
JS_ClearAllWatchPoints
JS_ClearWatchPoint
JS_SetWatchPoint
JS_HandleTrap
JS_ClearAllTraps
JS_ClearScriptTraps
JS_ClearTrap
JS_GetTrapOpcode
JS_SetTrap
;DSR070297 - added in GA code
JS_FrameIterator
JS_GetFrameAnnotation
JS_GetFramePrincipalArray
JS_GetFrameScript
JS_GetScriptFilename
JS_SetFrameAnnotation
JS_GetFramePC
JS_GetFunctionScript
;
;
;00017:jsdate (OFFSET:0x000af4f8, SIZE:0x00009a8e):
; - Public Definitions:
js_DateGetSeconds
js_DateGetMinutes
js_DateGetHours
js_DateGetDate
js_DateGetMonth
js_DateGetYear
js_NewDateObject
; js_InitDateClass
;
;
;00018:jscntxt (OFFSET:0x000b8f86, SIZE:0x00003732):
; - Public Definitions:
; js_InterpreterHooks
; js_ReportIsNotDefined
; js_ReportErrorAgain
; js_ReportErrorVA
; js_ContextIterator
; js_DestroyContext
; js_NewContext
; js_SetInterpreterHooks
;
;
;00019:jsbool (OFFSET:0x000bc6b8, SIZE:0x00003375):
; - Public Definitions:
; js_BooleanToString
; js_BooleanToObject
; js_InitBooleanClass
; js_ValueToBoolean
;
;
;00020:jsatom (OFFSET:0x000bfa2d, SIZE:0x000058d0):
; - Public Definitions:
; js_valueOf_str
; js_toString_str
; js_length_str
; js_eval_str
; js_constructor_str
; js_class_prototype_str
; js_assign_str
; js_anonymous_str
; js_Object_str
; js_Array_str
; js_type_str
; js_DropUnmappedAtoms
js_FreeAtomMap
js_InitAtomMap
; js_GetAtom
; js_DropAtom
; js_IndexAtom
; js_ValueToStringAtom
; js_AtomizeString
; js_AtomizeDouble
; js_AtomizeInt
; js_AtomizeBoolean
; js_AtomizeObject
; js_HoldAtom
; js_MarkAtomState
; js_FreeAtomState
; js_Atomize
; js_InitAtomState
;
;
;00021:jsarray (OFFSET:0x000c52fd, SIZE:0x00007c86):
; - Public Definitions:
; js_ArrayClass
; js_SetArrayLength
; js_GetArrayLength
; js_InitArrayClass
; js_NewArrayObject
; PR_qsort
;
;
;00022:jsapi (OFFSET:0x000ccf83, SIZE:0x0000de8c):
; - Public Definitions:
JS_ClearRegExpStatics
JS_SetRegExpInput
JS_NewRegExpObject
JS_SetErrorReporter
JS_CompareStrings
JS_GetStringLength
JS_GetStringBytes
JS_InternString
JS_NewStringCopyZ
JS_NewStringCopyN
JS_NewString
JS_IsRunning
JS_SetBranchCallback
JS_CallFunctionValue
JS_CallFunctionName
JS_CallFunction
JS_EvaluateScriptForPrincipals
JS_EvaluateScript
JS_ExecuteScript
JS_DecompileFunctionBody
JS_DecompileFunction
JS_DecompileScript
JS_CompileFunctionForPrincipals
JS_CompileFunction
JS_DestroyScript
JS_CompileScriptForPrincipals
JS_CompileScript
JS_DefineFunction
JS_GetFunctionName
JS_GetFunctionObject
JS_NewFunction
JS_ClearScope
JS_DeleteElement
JS_SetElement
JS_GetElement
JS_LookupElement
JS_AliasElement
JS_DefineElement
JS_SetArrayLength
JS_GetArrayLength
JS_NewArrayObject
JS_DeleteProperty
JS_SetProperty
JS_GetProperty
JS_LookupProperty
JS_AliasProperty
JS_DefinePropertyWithTinyId
JS_DefineProperty
JS_DefineConstDoubles
JS_DefineObject
JS_NewObject
JS_GetConstructor
JS_SetParent
JS_GetParent
JS_SetPrototype
JS_GetPrototype
JS_GetInstancePrivate
JS_SetPrivate
JS_GetPrivate
JS_InstanceOf
JS_GetClass
JS_DefineFunctions
JS_DefineProperties
JS_InitClass
JS_FinalizeStub
JS_ConvertStub
JS_ResolveStub
JS_EnumerateStub
JS_PropertyStub
JS_GC
JS_UnlockGCThing
JS_LockGCThing
JS_RemoveRoot
JS_AddRoot
JS_NewDoubleValue
JS_NewDouble
JS_strdup
JS_free
JS_realloc
JS_ReportOutOfMemory
JS_malloc
JS_GetScopeChain
JS_InitStandardClasses
JS_SetGlobalObject
JS_GetGlobalObject
JS_SetVersion
JS_GetVersion
JS_ContextIterator
JS_GetTaskState
JS_DestroyContext
JS_NewContext
JS_Unlock
JS_Lock
JS_Finish
JS_Init
JS_GetTypeName
JS_TypeOfValue
JS_ValueToBoolean
JS_ValueToInt32
JS_ValueToNumber
JS_ValueToString
JS_ValueToFunction
JS_ValueToObject
JS_ReportError
JS_ConvertValue
JS_GetEmptyStringValue
JS_GetPositiveInfinityValue
JS_GetNegativeInfinityValue
JS_GetNaNValue
;DSR062897 - added for GA code
JS_MaybeGC
JS_GetScriptPrincipals
JS_IsAssigning
JS_SetCharSetInfo
;
;
;00023:prmjtime (OFFSET:0x000dae0f, SIZE:0x00008986):
; - Public Definitions:
PRMJ_FormatTimeUSEnglish
PRMJ_gmtime
PRMJ_FormatTime
PRMJ_mktime
PRMJ_ComputeTime
PRMJ_localtime
PRMJ_ExplodeTime
PRMJ_ToLocal
PRMJ_ToGMT
PRMJ_NowLocal
PRMJ_DSTOffset
PRMJ_NowS
PRMJ_NowMS
PRMJ_Now
PRMJ_ToExtendedTime
PRMJ_ToBaseTime
PRMJ_setDST
PRMJ_LocalGMTDifference

42
mozilla/js/src/jsaddr.c Normal file
View File

@@ -0,0 +1,42 @@
/* -*- Mode: C; tab-width: 8 -*-
* Copyright © 1996 Netscape Communications Corporation, All Rights Reserved.
*/
#include <stdio.h>
#include <stdlib.h>
#include "jsapi.h"
#include "jsinterp.h"
/* These functions are needed to get the addresses of certain functions
* in the JS module. On WIN32 especially, these symbols have a different
* address from the actual address of these functions in the JS module.
* This is because on WIN32, import function address fixups are done only
* at load time and function calls are made by indirection - that is by
* using a couple extra instructions to lookup the actual function address
* in the importing module's import address table.
*/
JS_EXPORT_API(JSPropertyOp)
js_GetArgumentAddress()
{
return ((void *)js_GetArgument);
}
JS_EXPORT_API(JSPropertyOp)
js_SetArgumentAddress()
{
return ((void *)js_SetArgument);
}
JS_EXPORT_API(JSPropertyOp)
js_GetLocalVariableAddress()
{
return ((void *)js_GetLocalVariable);
}
JS_EXPORT_API(JSPropertyOp)
js_SetLocalVariableAddress()
{
return ((void *)js_SetLocalVariable);
}

20
mozilla/js/src/jsaddr.h Normal file
View File

@@ -0,0 +1,20 @@
/* -*- Mode: C; tab-width: 8 -*-
* Copyright © 1996 Netscape Communications Corporation, All Rights Reserved.
*/
#ifndef jsaddr_h___
#define jsaddr_h___
JS_EXTERN_API(JSPropertyOp)
js_GetArgumentAddress();
JS_EXTERN_API(JSPropertyOp)
js_SetArgumentAddress();
JS_EXTERN_API(JSPropertyOp)
js_GetLocalVariableAddress();
JS_EXTERN_API(JSPropertyOp)
js_SetLocalVariableAddress();
#endif /* jsaddr_h___ */

2864
mozilla/js/src/jsapi.c Normal file

File diff suppressed because it is too large Load Diff

1087
mozilla/js/src/jsapi.h Normal file

File diff suppressed because it is too large Load Diff

336
mozilla/js/src/jsarena.c Normal file
View File

@@ -0,0 +1,336 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* Lifetime-based fast allocation, inspired by much prior art, including
* "Fast Allocation and Deallocation of Memory Based on Object Lifetimes"
* David R. Hanson, Software -- Practice and Experience, Vol. 20(1).
*/
#include "jsstddef.h"
#include <stdlib.h>
#include <string.h>
#include "jstypes.h"
#include "jsbit.h"
#include "jsarena.h" /* Added by JSIFY */
#include "jsutil.h" /* Added by JSIFY */
#ifdef JS_THREADSAFE
extern js_CompareAndSwap(jsword *, jsword, jsword);
#endif
static JSArena *arena_freelist;
#ifdef JS_ARENAMETER
static JSArenaStats *arena_stats_list;
#define COUNT(pool,what) (pool)->stats.what++
#else
#define COUNT(pool,what) /* nothing */
#endif
#define JS_ARENA_DEFAULT_ALIGN sizeof(double)
JS_EXPORT_API(void)
JS_InitArenaPool(JSArenaPool *pool, const char *name, JSUint32 size, JSUint32 align)
{
if (align == 0)
align = JS_ARENA_DEFAULT_ALIGN;
pool->mask = JS_BITMASK(JS_CeilingLog2(align));
pool->first.next = NULL;
pool->first.base = pool->first.avail = pool->first.limit =
(jsuword)JS_ARENA_ALIGN(pool, &pool->first + 1);
pool->current = &pool->first;
pool->arenasize = size;
#ifdef JS_ARENAMETER
memset(&pool->stats, 0, sizeof pool->stats);
pool->stats.name = strdup(name);
pool->stats.next = arena_stats_list;
arena_stats_list = &pool->stats;
#endif
}
JS_EXPORT_API(void *)
JS_ArenaAllocate(JSArenaPool *pool, JSUint32 nb)
{
JSArena **ap, *a, *b;
#ifdef JS_THREADSAFE
JSArena *c;
#endif
JSUint32 sz;
void *p;
JS_ASSERT((nb & pool->mask) == 0);
#if defined(XP_PC) && !defined(_WIN32)
if (nb >= 60000U)
return 0;
#endif /* WIN16 */
ap = &arena_freelist;
for (a = pool->current; a->avail + nb > a->limit; pool->current = a) {
if (a->next) { /* move to next arena */
a = a->next;
continue;
}
while ((b = *ap) != NULL) { /* reclaim a free arena */
if (b->limit - b->base == pool->arenasize) {
#ifdef JS_THREADSAFE
do {
b = *ap;
c = b->next;
} while (!js_CompareAndSwap((jsword *)ap,(jsword)b,(jsword)c));
#else
*ap = b->next;
#endif
b->next = NULL;
a = a->next = b;
COUNT(pool, nreclaims);
goto claim;
}
ap = &b->next;
}
sz = JS_MAX(pool->arenasize, nb); /* allocate a new arena */
sz += sizeof *a + pool->mask; /* header and alignment slop */
b = malloc(sz);
if (!b)
return 0;
a = a->next = b;
a->next = NULL;
a->limit = (jsuword)a + sz;
JS_COUNT_ARENA(pool,++);
COUNT(pool, nmallocs);
claim:
a->base = a->avail = (jsuword)JS_ARENA_ALIGN(pool, a + 1);
}
p = (void *)a->avail;
a->avail += nb;
return p;
}
JS_EXPORT_API(void *)
JS_ArenaGrow(JSArenaPool *pool, void *p, JSUint32 size, JSUint32 incr)
{
void *newp;
JS_ARENA_ALLOCATE(newp, pool, size + incr);
memcpy(newp, p, size);
return newp;
}
/*
* Free tail arenas linked after head, which may not be the true list head.
* Reset pool->current to point to head in case it pointed at a tail arena.
*/
static void
FreeArenaList(JSArenaPool *pool, JSArena *head, JSBool reallyFree)
{
JSArena **ap, *a;
#ifdef JS_THREADSAFE
JSArena *b;
#endif
ap = &head->next;
a = *ap;
if (!a)
return;
#ifdef DEBUG
do {
JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
a->avail = a->base;
JS_CLEAR_UNUSED(a);
} while ((a = a->next) != NULL);
a = *ap;
#endif
if (reallyFree) {
do {
*ap = a->next;
JS_CLEAR_ARENA(a);
JS_COUNT_ARENA(pool,--);
free(a);
} while ((a = *ap) != NULL);
} else {
/* Insert the whole arena chain at the front of the freelist. */
do {
ap = &(*ap)->next;
} while (*ap);
#ifdef JS_THREADSAFE
do {
*ap = b = arena_freelist;
} while (!js_CompareAndSwap((jsword*)&arena_freelist,(jsword)b,(jsword)a));
#else
*ap = arena_freelist;
arena_freelist = a;
#endif
head->next = NULL;
}
pool->current = head;
}
JS_EXPORT_API(void)
JS_ArenaRelease(JSArenaPool *pool, char *mark)
{
JSArena *a;
for (a = pool->first.next; a; a = a->next) {
if (JS_UPTRDIFF(mark, a) < JS_UPTRDIFF(a->avail, a)) {
a->avail = (jsuword)JS_ARENA_ALIGN(pool, mark);
FreeArenaList(pool, a, JS_TRUE);
return;
}
}
}
JS_EXPORT_API(void)
JS_FreeArenaPool(JSArenaPool *pool)
{
FreeArenaList(pool, &pool->first, JS_FALSE);
COUNT(pool, ndeallocs);
}
JS_EXPORT_API(void)
JS_FinishArenaPool(JSArenaPool *pool)
{
FreeArenaList(pool, &pool->first, JS_TRUE);
#ifdef JS_ARENAMETER
{
JSArenaStats *stats, **statsp;
if (pool->stats.name)
free(pool->stats.name);
for (statsp = &arena_stats_list; (stats = *statsp) != 0;
statsp = &stats->next) {
if (stats == &pool->stats) {
*statsp = stats->next;
return;
}
}
}
#endif
}
JS_EXPORT_API(void)
JS_CompactArenaPool(JSArenaPool *pool)
{
#if 0 /* XP_MAC */
JSArena *a = pool->first.next;
while (a) {
reallocSmaller(a, a->avail - (jsuword)a);
a->limit = a->avail;
a = a->next;
}
#endif
}
JS_EXPORT_API(void)
JS_ArenaFinish()
{
JSArena *a, *next;
#ifdef JS_THREADSAFE
while (arena_freelist) {
a = arena_freelist;
next = a->next;
if (js_CompareAndSwap((jsword*)&arena_freelist,(jsword)a,(jsword)next))
free(a);
}
#else
for (a = arena_freelist; a; a = next) {
next = a->next;
free(a);
}
arena_freelist = NULL;
#endif
}
#ifdef JS_ARENAMETER
JS_EXPORT_API(void)
JS_ArenaCountAllocation(JSArenaPool *pool, JSUint32 nb)
{
pool->stats.nallocs++;
pool->stats.nbytes += nb;
if (nb > pool->stats.maxalloc)
pool->stats.maxalloc = nb;
pool->stats.variance += nb * nb;
}
JS_EXPORT_API(void)
JS_ArenaCountInplaceGrowth(JSArenaPool *pool, JSUint32 size, JSUint32 incr)
{
pool->stats.ninplace++;
}
JS_EXPORT_API(void)
JS_ArenaCountGrowth(JSArenaPool *pool, JSUint32 size, JSUint32 incr)
{
pool->stats.ngrows++;
pool->stats.nbytes += incr;
pool->stats.variance -= size * size;
size += incr;
if (size > pool->stats.maxalloc)
pool->stats.maxalloc = size;
pool->stats.variance += size * size;
}
JS_EXPORT_API(void)
JS_ArenaCountRelease(JSArenaPool *pool, char *mark)
{
pool->stats.nreleases++;
}
JS_EXPORT_API(void)
JS_ArenaCountRetract(JSArenaPool *pool, char *mark)
{
pool->stats.nfastrels++;
}
#include <math.h>
#include <stdio.h>
JS_EXPORT_API(void)
JS_DumpArenaStats(FILE *fp)
{
JSArenaStats *stats;
double mean, variance;
for (stats = arena_stats_list; stats; stats = stats->next) {
if (stats->nallocs != 0) {
mean = (double)stats->nbytes / stats->nallocs;
variance = fabs(stats->variance / stats->nallocs - mean * mean);
} else {
mean = variance = 0;
}
fprintf(fp, "\n%s allocation statistics:\n", stats->name);
fprintf(fp, " number of arenas: %u\n", stats->narenas);
fprintf(fp, " number of allocations: %u\n", stats->nallocs);
fprintf(fp, " number of free arena reclaims: %u\n", stats->nreclaims);
fprintf(fp, " number of malloc calls: %u\n", stats->nmallocs);
fprintf(fp, " number of deallocations: %u\n", stats->ndeallocs);
fprintf(fp, " number of allocation growths: %u\n", stats->ngrows);
fprintf(fp, " number of in-place growths: %u\n", stats->ninplace);
fprintf(fp, "number of released allocations: %u\n", stats->nreleases);
fprintf(fp, " number of fast releases: %u\n", stats->nfastrels);
fprintf(fp, " total bytes allocated: %u\n", stats->nbytes);
fprintf(fp, " mean allocation size: %g\n", mean);
fprintf(fp, " standard deviation: %g\n", sqrt(variance));
fprintf(fp, " maximum allocation size: %u\n", stats->maxalloc);
}
}
#endif /* JS_ARENAMETER */

246
mozilla/js/src/jsarena.h Normal file
View File

@@ -0,0 +1,246 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsarena_h___
#define jsarena_h___
/*
* Lifetime-based fast allocation, inspired by much prior art, including
* "Fast Allocation and Deallocation of Memory Based on Object Lifetimes"
* David R. Hanson, Software -- Practice and Experience, Vol. 20(1).
*
* Also supports LIFO allocation (JS_ARENA_MARK/JS_ARENA_RELEASE).
*/
#include <stdlib.h>
#include <string.h>
#include "jstypes.h"
#include "jscompat.h"
JS_BEGIN_EXTERN_C
typedef struct JSArena JSArena;
typedef struct JSArenaPool JSArenaPool;
struct JSArena {
JSArena *next; /* next arena for this lifetime */
jsuword base; /* aligned base address, follows this header */
jsuword limit; /* one beyond last byte in arena */
jsuword avail; /* points to next available byte */
};
#ifdef JS_ARENAMETER
typedef struct JSArenaStats JSArenaStats;
struct JSArenaStats {
JSArenaStats *next; /* next in arenaStats list */
char *name; /* name for debugging */
uint32 narenas; /* number of arenas in pool */
uint32 nallocs; /* number of JS_ARENA_ALLOCATE() calls */
uint32 nreclaims; /* number of reclaims from freeArenas */
uint32 nmallocs; /* number of malloc() calls */
uint32 ndeallocs; /* number of lifetime deallocations */
uint32 ngrows; /* number of JS_ARENA_GROW() calls */
uint32 ninplace; /* number of in-place growths */
uint32 nreleases; /* number of JS_ARENA_RELEASE() calls */
uint32 nfastrels; /* number of "fast path" releases */
size_t nbytes; /* total bytes allocated */
size_t maxalloc; /* maximum allocation size in bytes */
double variance; /* size variance accumulator */
};
#endif
struct JSArenaPool {
JSArena first; /* first arena in pool list */
JSArena *current; /* arena from which to allocate space */
size_t arenasize; /* net exact size of a new arena */
jsuword mask; /* alignment mask (power-of-2 - 1) */
#ifdef JS_ARENAMETER
JSArenaStats stats;
#endif
};
/*
* If the including .c file uses only one power-of-2 alignment, it may define
* JS_ARENA_CONST_ALIGN_MASK to the alignment mask and save a few instructions
* per ALLOCATE and GROW.
*/
#ifdef JS_ARENA_CONST_ALIGN_MASK
#define JS_ARENA_ALIGN(pool, n) (((jsuword)(n) + JS_ARENA_CONST_ALIGN_MASK) \
& ~JS_ARENA_CONST_ALIGN_MASK)
#define JS_INIT_ARENA_POOL(pool, name, size) \
JS_InitArenaPool(pool, name, size, JS_ARENA_CONST_ALIGN_MASK + 1)
#else
#define JS_ARENA_ALIGN(pool, n) (((jsuword)(n) + (pool)->mask) & ~(pool)->mask)
#endif
#define JS_ARENA_ALLOCATE(p, pool, nb) \
JS_BEGIN_MACRO \
JSArena *_a = (pool)->current; \
size_t _nb = JS_ARENA_ALIGN(pool, nb); \
jsuword _p = _a->avail; \
jsuword _q = _p + _nb; \
if (_q > _a->limit) \
_p = (jsuword)JS_ArenaAllocate(pool, _nb); \
else \
_a->avail = _q; \
p = (void *)_p; \
JS_ArenaCountAllocation(pool, nb); \
JS_END_MACRO
#define JS_ARENA_GROW(p, pool, size, incr) \
JS_BEGIN_MACRO \
JSArena *_a = (pool)->current; \
size_t _incr = JS_ARENA_ALIGN(pool, incr); \
jsuword _p = _a->avail; \
jsuword _q = _p + _incr; \
if (_p == (jsuword)(p) + JS_ARENA_ALIGN(pool, size) && \
_q <= _a->limit) { \
_a->avail = _q; \
JS_ArenaCountInplaceGrowth(pool, size, incr); \
} else { \
p = JS_ArenaGrow(pool, p, size, incr); \
} \
JS_ArenaCountGrowth(pool, size, incr); \
JS_END_MACRO
#define JS_ARENA_MARK(pool) ((void *) (pool)->current->avail)
#define JS_UPTRDIFF(p,q) ((jsuword)(p) - (jsuword)(q))
#ifdef DEBUG
#define free_PATTERN 0xDA
#define JS_CLEAR_UNUSED(a) (JS_ASSERT((a)->avail <= (a)->limit), \
memset((void*)(a)->avail, free_PATTERN, \
(a)->limit - (a)->avail))
#define JS_CLEAR_ARENA(a) memset((void*)(a), free_PATTERN, \
(a)->limit - (jsuword)(a))
#else
#define JS_CLEAR_UNUSED(a) /* nothing */
#define JS_CLEAR_ARENA(a) /* nothing */
#endif
#define JS_ARENA_RELEASE(pool, mark) \
JS_BEGIN_MACRO \
char *_m = (char *)(mark); \
JSArena *_a = (pool)->current; \
if (JS_UPTRDIFF(_m, _a) <= JS_UPTRDIFF(_a->avail, _a)) { \
_a->avail = (jsuword)JS_ARENA_ALIGN(pool, _m); \
JS_CLEAR_UNUSED(_a); \
JS_ArenaCountRetract(pool, _m); \
} else { \
JS_ArenaRelease(pool, _m); \
} \
JS_ArenaCountRelease(pool, _m); \
JS_END_MACRO
#ifdef JS_ARENAMETER
#define JS_COUNT_ARENA(pool,op) ((pool)->stats.narenas op)
#else
#define JS_COUNT_ARENA(pool,op)
#endif
#define JS_ARENA_DESTROY(pool, a, pnext) \
JS_BEGIN_MACRO \
JS_COUNT_ARENA(pool,--); \
if ((pool)->current == (a)) (pool)->current = &(pool)->first; \
*(pnext) = (a)->next; \
JS_CLEAR_ARENA(a); \
free(a); \
(a) = NULL; \
JS_END_MACRO
/*
* Initialize an arena pool with the given name for debugging and metering,
* with a minimum size per arena of size bytes.
*/
JS_EXTERN_API(void)
JS_InitArenaPool(JSArenaPool *pool, const char *name, JSUint32 size,
JSUint32 align);
/*
* Free the arenas in pool. The user may continue to allocate from pool
* after calling this function. There is no need to call JS_InitArenaPool()
* again unless JS_FinishArenaPool(pool) has been called.
*/
JS_EXTERN_API(void)
JS_FreeArenaPool(JSArenaPool *pool);
/*
* Free the arenas in pool and finish using it altogether.
*/
JS_EXTERN_API(void)
JS_FinishArenaPool(JSArenaPool *pool);
/*
* Compact all of the arenas in a pool so that no space is wasted.
*/
JS_EXTERN_API(void)
JS_CompactArenaPool(JSArenaPool *pool);
/*
* Finish using arenas, freeing all memory associated with them.
*/
JS_EXTERN_API(void)
JS_ArenaFinish(void);
/*
* Friend functions used by the JS_ARENA_*() macros.
*/
JS_EXTERN_API(void *)
JS_ArenaAllocate(JSArenaPool *pool, JSUint32 nb);
JS_EXTERN_API(void *)
JS_ArenaGrow(JSArenaPool *pool, void *p, JSUint32 size, JSUint32 incr);
JS_EXTERN_API(void)
JS_ArenaRelease(JSArenaPool *pool, char *mark);
#ifdef JS_ARENAMETER
#include <stdio.h>
JS_EXTERN_API(void)
JS_ArenaCountAllocation(JSArenaPool *pool, JSUint32 nb);
JS_EXTERN_API(void)
JS_ArenaCountInplaceGrowth(JSArenaPool *pool, JSUint32 size, JSUint32 incr);
JS_EXTERN_API(void)
JS_ArenaCountGrowth(JSArenaPool *pool, JSUint32 size, JSUint32incr);
JS_EXTERN_API(void)
JS_ArenaCountRelease(JSArenaPool *pool, char *mark);
JS_EXTERN_API(void)
JS_ArenaCountRetract(JSArenaPool *pool, char *mark);
JS_EXTERN_API(void)
JS_DumpArenaStats(FILE *fp);
#else /* !JS_ARENAMETER */
#define JS_ArenaCountAllocation(ap, nb) /* nothing */
#define JS_ArenaCountInplaceGrowth(ap, size, incr) /* nothing */
#define JS_ArenaCountGrowth(ap, size, incr) /* nothing */
#define JS_ArenaCountRelease(ap, mark) /* nothing */
#define JS_ArenaCountRetract(ap, mark) /* nothing */
#endif /* !JS_ARENAMETER */
JS_END_EXTERN_C
#endif /* jsarena_h___ */

1298
mozilla/js/src/jsarray.c Normal file

File diff suppressed because it is too large Load Diff

56
mozilla/js/src/jsarray.h Normal file
View File

@@ -0,0 +1,56 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsarray_h___
#define jsarray_h___
/*
* JS Array interface.
*/
#include "jsprvtd.h"
#include "jspubtd.h"
JS_BEGIN_EXTERN_C
extern JSClass js_ArrayClass;
extern JSObject *
js_InitArrayClass(JSContext *cx, JSObject *obj);
extern JSObject *
js_NewArrayObject(JSContext *cx, jsuint length, jsval *vector);
extern JSBool
js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp);
extern JSBool
js_SetLengthProperty(JSContext *cx, JSObject *obj, jsuint length);
extern JSBool
js_HasLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp);
/*
* JS-specific qsort function.
*/
typedef int (*JSComparator)(const void *a, const void *b, void *arg);
extern JSBool
js_qsort(void *vec, size_t nel, size_t elsize, JSComparator cmp, void *arg);
JS_END_EXTERN_C
#endif /* jsarray_h___ */

655
mozilla/js/src/jsatom.c Normal file
View File

@@ -0,0 +1,655 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* JS atom table.
*/
#include "jsstddef.h"
#include <stdlib.h>
#include <string.h>
#include "jstypes.h"
#include "jsutil.h" /* Added by JSIFY */
#include "jshash.h" /* Added by JSIFY */
#include "jsprf.h"
#include "jsapi.h"
#include "jsatom.h"
#include "jscntxt.h"
#include "jsgc.h"
#include "jslock.h"
#include "jsnum.h"
#include "jsopcode.h"
#include "jsstr.h"
/*
* Keep this in sync with jspubtd.h -- an assertion below will insist that
* its length match the JSType enum's JSTYPE_LIMIT limit value.
*/
char *js_type_str[] = {
"undefined",
"object",
"function",
"string",
"number",
"boolean",
};
char *js_boolean_str[] = {
js_false_str,
js_true_str
};
char js_Array_str[] = "Array";
char js_Math_str[] = "Math";
char js_Object_str[] = "Object";
char js_anonymous_str[] = "anonymous";
char js_arguments_str[] = "arguments";
char js_arity_str[] = "arity";
char js_assign_str[] = "assign";
char js_callee_str[] = "callee";
char js_caller_str[] = "caller";
char js_class_prototype_str[] = "prototype";
char js_constructor_str[] = "constructor";
char js_count_str[] = "__count__";
char js_eval_str[] = "eval";
char js_index_str[] = "index";
char js_input_str[] = "input";
char js_length_str[] = "length";
char js_name_str[] = "name";
char js_parent_str[] = "__parent__";
char js_proto_str[] = "__proto__";
char js_toSource_str[] = "toSource";
char js_toString_str[] = "toString";
char js_valueOf_str[] = "valueOf";
#define HASH_OBJECT(o) ((JSHashNumber)(o) >> JSVAL_TAGBITS)
#define HASH_INT(i) ((JSHashNumber)(i))
#define HASH_DOUBLE(dp) ((JSHashNumber)(((uint32*)(dp))[0] ^ ((uint32*)(dp))[1]))
#define HASH_BOOLEAN(b) ((JSHashNumber)(b))
JS_STATIC_DLL_CALLBACK(JSHashNumber)
js_hash_atom_key(const void *key)
{
jsval v;
jsdouble *dp;
/* Order JSVAL_IS_* tests by likelihood of success. */
v = (jsval)key;
if (JSVAL_IS_STRING(v))
return js_HashString(JSVAL_TO_STRING(v));
if (JSVAL_IS_INT(v))
return HASH_INT(JSVAL_TO_INT(v));
if (JSVAL_IS_DOUBLE(v)) {
dp = JSVAL_TO_DOUBLE(v);
return HASH_DOUBLE(dp);
}
if (JSVAL_IS_OBJECT(v))
return HASH_OBJECT(JSVAL_TO_OBJECT(v));
if (JSVAL_IS_BOOLEAN(v))
return HASH_BOOLEAN(JSVAL_TO_BOOLEAN(v));
return (JSHashNumber)v;
}
JS_STATIC_DLL_CALLBACK(intN)
js_compare_atom_keys(const void *k1, const void *k2)
{
jsval v1, v2;
v1 = (jsval)k1, v2 = (jsval)k2;
if (JSVAL_IS_STRING(v1) && JSVAL_IS_STRING(v2))
return !js_CompareStrings(JSVAL_TO_STRING(v1), JSVAL_TO_STRING(v2));
if (JSVAL_IS_DOUBLE(v1) && JSVAL_IS_DOUBLE(v2)) {
double d1 = *JSVAL_TO_DOUBLE(v1);
double d2 = *JSVAL_TO_DOUBLE(v2);
if (JSDOUBLE_IS_NaN(d1))
return JSDOUBLE_IS_NaN(d2);
#ifdef XP_PC
/* XXX MSVC miscompiles such that (NaN == 0) */
if (JSDOUBLE_IS_NaN(d2))
return JS_FALSE;
#endif
return d1 == d2;
}
return v1 == v2;
}
JS_STATIC_DLL_CALLBACK(int)
js_compare_stub(const void *v1, const void *v2)
{
return 1;
}
JS_STATIC_DLL_CALLBACK(void *)
js_alloc_atom_space(void *priv, size_t size)
{
return malloc(size);
}
JS_STATIC_DLL_CALLBACK(void)
js_free_atom_space(void *priv, void *item)
{
free(item);
}
JS_STATIC_DLL_CALLBACK(JSHashEntry *)
js_alloc_atom(void *priv, const void *key)
{
JSAtomState *state = priv;
JSAtom *atom;
atom = malloc(sizeof(JSAtom));
if (!atom)
return NULL;
#ifdef JS_THREADSAFE
state->tablegen++;
#endif
atom->entry.key = key;
atom->entry.value = NULL;
atom->flags = 0;
atom->kwindex = -1;
atom->number = state->number++;
return &atom->entry;
}
JS_STATIC_DLL_CALLBACK(void)
js_free_atom(void *priv, JSHashEntry *he, uintN flag)
{
if (flag != HT_FREE_ENTRY)
return;
#ifdef JS_THREADSAFE
((JSAtomState *)priv)->tablegen++;
#endif
free(he);
}
static JSHashAllocOps atom_alloc_ops = {
js_alloc_atom_space, js_free_atom_space,
js_alloc_atom, js_free_atom
};
#define JS_ATOM_HASH_SIZE 1024
JSBool
js_InitAtomState(JSContext *cx, JSAtomState *state)
{
uintN i;
state->runtime = cx->runtime;
state->number = 0;
state->table = JS_NewHashTable(JS_ATOM_HASH_SIZE, js_hash_atom_key,
js_compare_atom_keys, js_compare_stub,
&atom_alloc_ops, state);
if (!state->table) {
JS_ReportOutOfMemory(cx);
return JS_FALSE;
}
#ifdef JS_THREADSAFE
js_NewLock(&state->lock);
state->tablegen = 0;
#endif
#define FROB(lval,str) { \
if (!(state->lval = js_Atomize(cx, str, strlen(str), ATOM_PINNED))) { \
js_FreeAtomState(cx, state); \
return JS_FALSE; \
} \
}
JS_ASSERT(sizeof js_type_str / sizeof js_type_str[0] == JSTYPE_LIMIT);
for (i = 0; i < JSTYPE_LIMIT; i++)
FROB(typeAtoms[i], js_type_str[i]);
FROB(booleanAtoms[0], js_false_str);
FROB(booleanAtoms[1], js_true_str);
FROB(nullAtom, js_null_str);
FROB(ArrayAtom, js_Array_str);
FROB(MathAtom, js_Math_str);
FROB(ObjectAtom, js_Object_str);
FROB(anonymousAtom, js_anonymous_str);
FROB(argumentsAtom, js_arguments_str);
FROB(arityAtom, js_arity_str);
FROB(assignAtom, js_assign_str);
FROB(calleeAtom, js_callee_str);
FROB(callerAtom, js_caller_str);
FROB(classPrototypeAtom, js_class_prototype_str);
FROB(constructorAtom, js_constructor_str);
FROB(countAtom, js_count_str);
FROB(indexAtom, js_index_str);
FROB(inputAtom, js_input_str);
FROB(lengthAtom, js_length_str);
FROB(nameAtom, js_name_str);
FROB(parentAtom, js_parent_str);
FROB(protoAtom, js_proto_str);
FROB(toSourceAtom, js_toSource_str);
FROB(toStringAtom, js_toString_str);
FROB(valueOfAtom, js_valueOf_str);
FROB(evalAtom, js_eval_str);
#undef FROB
return JS_TRUE;
}
void
js_FreeAtomState(JSContext *cx, JSAtomState *state)
{
state->runtime = NULL;
JS_HashTableDestroy(state->table);
state->table = NULL;
state->number = 0;
#ifdef JS_THREADSAFE
js_DestroyLock(&state->lock);
#endif
}
typedef struct MarkArgs {
JSRuntime *runtime;
JSGCThingMarker mark;
} MarkArgs;
JS_STATIC_DLL_CALLBACK(intN)
js_atom_marker(JSHashEntry *he, intN i, void *arg)
{
JSAtom *atom;
jsval key;
MarkArgs *args;
atom = (JSAtom *)he;
if (atom->flags & ATOM_PINNED) {
atom->flags |= ATOM_MARK;
key = ATOM_KEY(atom);
if (JSVAL_IS_GCTHING(key)) {
args = arg;
args->mark(args->runtime, JSVAL_TO_GCTHING(key));
}
}
return HT_ENUMERATE_NEXT;
}
void
js_MarkAtomState(JSAtomState *state, JSGCThingMarker mark)
{
MarkArgs args;
args.runtime = state->runtime;
args.mark = mark;
JS_HashTableEnumerateEntries(state->table, js_atom_marker, &args);
}
JS_STATIC_DLL_CALLBACK(intN)
js_atom_sweeper(JSHashEntry *he, intN i, void *arg)
{
JSAtom *atom;
atom = (JSAtom *)he;
if (atom->flags & ATOM_MARK) {
atom->flags &= ~ATOM_MARK;
return HT_ENUMERATE_NEXT;
}
JS_ASSERT((atom->flags & ATOM_PINNED) == 0);
atom->entry.key = NULL;
atom->flags = 0;
return HT_ENUMERATE_REMOVE;
}
void
js_SweepAtomState(JSAtomState *state)
{
JS_HashTableEnumerateEntries(state->table, js_atom_sweeper, NULL);
}
JS_STATIC_DLL_CALLBACK(intN)
js_atom_unpinner(JSHashEntry *he, intN i, void *arg)
{
JSAtom *atom;
atom = (JSAtom *)he;
atom->flags &= ~ATOM_PINNED;
return HT_ENUMERATE_NEXT;
}
void
js_UnpinPinnedAtoms(JSAtomState *state)
{
JS_HashTableEnumerateEntries(state->table, js_atom_unpinner, NULL);
}
static JSAtom *
js_AtomizeHashedKey(JSContext *cx, jsval key, JSHashNumber keyHash, uintN flags)
{
JSAtomState *state;
JSHashTable *table;
JSHashEntry *he, **hep;
JSAtom *atom;
state = &cx->runtime->atomState;
JS_LOCK(&state->lock,cx);
table = state->table;
hep = JS_HashTableRawLookup(table, keyHash, (void *)key);
if ((he = *hep) == NULL) {
he = JS_HashTableRawAdd(table, hep, keyHash, (void *)key, NULL);
if (!he) {
JS_ReportOutOfMemory(cx);
atom = NULL;
goto out;
}
}
atom = (JSAtom *)he;
atom->flags |= flags;
out:
JS_UNLOCK(&state->lock,cx);
return atom;
}
JSAtom *
js_AtomizeObject(JSContext *cx, JSObject *obj, uintN flags)
{
jsval key;
JSHashNumber keyHash;
/* XXX must be set in the following order or MSVC1.52 will crash */
keyHash = HASH_OBJECT(obj);
key = OBJECT_TO_JSVAL(obj);
return js_AtomizeHashedKey(cx, key, keyHash, flags);
}
JSAtom *
js_AtomizeBoolean(JSContext *cx, JSBool b, uintN flags)
{
jsval key;
JSHashNumber keyHash;
key = BOOLEAN_TO_JSVAL(b);
keyHash = HASH_BOOLEAN(b);
return js_AtomizeHashedKey(cx, key, keyHash, flags);
}
JSAtom *
js_AtomizeInt(JSContext *cx, jsint i, uintN flags)
{
jsval key;
JSHashNumber keyHash;
key = INT_TO_JSVAL(i);
keyHash = HASH_INT(i);
return js_AtomizeHashedKey(cx, key, keyHash, flags);
}
JSAtom *
js_AtomizeDouble(JSContext *cx, jsdouble d, uintN flags)
{
jsdouble *dp;
JSHashNumber keyHash;
jsval key;
JSAtomState *state;
JSHashTable *table;
JSHashEntry *he, **hep;
JSAtom *atom;
#define ALIGNNUM ((1<<JSVAL_TAGBITS) < sizeof(double) ? sizeof(double) : (1<<JSVAL_TAGBITS))
char alignbuf[2*ALIGNNUM];
jsuword alignint = (jsuword)alignbuf;
jsuword xtra = ALIGNNUM-(alignint%ALIGNNUM);
#undef ALIGNNUM
dp = (jsdouble *)&alignbuf[xtra];
*dp = d;
keyHash = HASH_DOUBLE(dp);
key = DOUBLE_TO_JSVAL(dp);
state = &cx->runtime->atomState;
JS_LOCK(&state->lock,cx);
table = state->table;
hep = JS_HashTableRawLookup(table, keyHash, (void *)key);
if ((he = *hep) == NULL) {
#ifdef JS_THREADSAFE
uint32 gen = state->tablegen;
#endif
JS_UNLOCK(&state->lock,cx);
if (!js_NewDoubleValue(cx, d, &key))
return NULL;
JS_LOCK(&state->lock,cx);
#ifdef JS_THREADSAFE
if (state->tablegen != gen) {
hep = JS_HashTableRawLookup(table, keyHash, (void *)key);
if ((he = *hep) != NULL) {
atom = (JSAtom *)he;
goto out;
}
}
#endif
he = JS_HashTableRawAdd(table, hep, keyHash, (void *)key, NULL);
if (!he) {
JS_ReportOutOfMemory(cx);
atom = NULL;
goto out;
}
}
atom = (JSAtom *)he;
atom->flags |= flags;
out:
JS_UNLOCK(&state->lock,cx);
return atom;
}
JSAtom *
js_AtomizeString(JSContext *cx, JSString *str, uintN flags)
{
JSHashNumber keyHash;
jsval key;
JSAtomState *state;
JSHashTable *table;
JSHashEntry *he, **hep;
JSAtom *atom;
keyHash = js_HashString(str);
key = STRING_TO_JSVAL(str);
state = &cx->runtime->atomState;
JS_LOCK(&state->lock,cx);
table = state->table;
hep = JS_HashTableRawLookup(table, keyHash, (void *)key);
if ((he = *hep) == NULL) {
if (flags & ATOM_TMPSTR) {
#ifdef JS_THREADSAFE
uint32 gen = state->tablegen;
#endif
JS_UNLOCK(&state->lock,cx);
flags &= ~ATOM_TMPSTR;
if (flags & ATOM_NOCOPY) {
flags &= ~ATOM_NOCOPY;
str = js_NewString(cx, str->chars, str->length, 0);
} else {
str = js_NewStringCopyN(cx, str->chars, str->length, 0);
}
if (!str)
return NULL;
key = STRING_TO_JSVAL(str);
JS_LOCK(&state->lock,cx);
#ifdef JS_THREADSAFE
if (state->tablegen != gen) {
hep = JS_HashTableRawLookup(table, keyHash, (void *)key);
if ((he = *hep) != NULL) {
atom = (JSAtom *)he;
goto out;
}
}
#endif
}
he = JS_HashTableRawAdd(table, hep, keyHash, (void *)key, NULL);
if (!he) {
JS_ReportOutOfMemory(cx);
atom = NULL;
goto out;
}
}
atom = (JSAtom *)he;
atom->flags |= flags;
out:
JS_UNLOCK(&state->lock,cx);
return atom;
}
JS_FRIEND_API(JSAtom *)
js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags)
{
jschar *chars;
JSString *str;
JSAtom *atom;
#define ALIGNNUM ((1<<JSVAL_TAGBITS) < sizeof(JSString) ? sizeof(JSString) : (1<<JSVAL_TAGBITS))
char alignbuf[2*ALIGNNUM];
jsuword alignint = (jsuword)alignbuf;
jsuword xtra = ALIGNNUM-(alignint%ALIGNNUM);
#undef ALIGNNUM
str = (JSString *)&alignbuf[xtra];
chars = js_InflateString(cx, bytes, length);
if (!chars)
return NULL;
str->chars = chars;
str->length = length;
atom = js_AtomizeString(cx, str, ATOM_TMPSTR | ATOM_NOCOPY | flags);
if (!atom || ATOM_TO_STRING(atom)->chars != chars)
JS_free(cx, chars);
return atom;
}
JS_FRIEND_API(JSAtom *)
js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags)
{
JSString *str;
#define ALIGNNUM ((1<<JSVAL_TAGBITS) < sizeof(JSString) ? sizeof(JSString) : (1<<JSVAL_TAGBITS))
char alignbuf[2*ALIGNNUM];
jsuword alignint = (jsuword)alignbuf;
jsuword xtra = ALIGNNUM-(alignint%ALIGNNUM);
#undef ALIGNNUM
str = (JSString *)&alignbuf[xtra];
str->chars = (jschar *)chars;
str->length = length;
return js_AtomizeString(cx, str, ATOM_TMPSTR | flags);
}
JSAtom *
js_AtomizeValue(JSContext *cx, jsval value, uintN flags)
{
if (JSVAL_IS_STRING(value))
return js_AtomizeString(cx, JSVAL_TO_STRING(value), flags);
if (JSVAL_IS_INT(value))
return js_AtomizeInt(cx, JSVAL_TO_INT(value), flags);
if (JSVAL_IS_DOUBLE(value))
return js_AtomizeDouble(cx, *JSVAL_TO_DOUBLE(value), flags);
if (JSVAL_IS_OBJECT(value))
return js_AtomizeObject(cx, JSVAL_TO_OBJECT(value), flags);
if (JSVAL_IS_BOOLEAN(value))
return js_AtomizeBoolean(cx, JSVAL_TO_BOOLEAN(value), flags);
return js_AtomizeHashedKey(cx, value, (JSHashNumber)value, flags);
}
JSAtom *
js_ValueToStringAtom(JSContext *cx, jsval v)
{
JSString *str;
str = js_ValueToString(cx, v);
if (!str)
return NULL;
return js_AtomizeString(cx, str, 0);
}
JSAtomListElement *
js_IndexAtom(JSContext *cx, JSAtom *atom, JSAtomList *al)
{
JSAtomListElement *ale;
ATOM_LIST_SEARCH(ale, al, atom);
if (!ale) {
JS_ARENA_ALLOCATE(ale, &cx->tempPool, sizeof(JSAtomListElement));
if (!ale) {
JS_ReportOutOfMemory(cx);
return NULL;
}
ale->atom = atom;
ale->index = (jsatomid) al->count++;
ale->next = al->list;
al->list = ale;
}
return ale;
}
JS_FRIEND_API(JSAtom *)
js_GetAtom(JSContext *cx, JSAtomMap *map, jsatomid i)
{
JSAtom *atom;
JS_ASSERT(map->vector && i < map->length);
if (!map->vector || i >= map->length) {
char numBuf[12];
JS_snprintf(numBuf, sizeof numBuf, "%lu", (unsigned long)i);
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_BAD_ATOMIC_NUMBER, numBuf);
return NULL;
}
atom = map->vector[i];
JS_ASSERT(atom);
return atom;
}
JS_FRIEND_API(JSBool)
js_InitAtomMap(JSContext *cx, JSAtomMap *map, JSAtomList *al)
{
JSAtom **vector;
JSAtomListElement *ale, *next;
uint32 count;
ale = al->list;
if (!ale) {
map->vector = NULL;
map->length = 0;
return JS_TRUE;
}
count = al->count;
if (count >= ATOM_INDEX_LIMIT) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_TOO_MANY_LITERALS);
return JS_FALSE;
}
vector = JS_malloc(cx, (size_t) count * sizeof *vector);
if (!vector)
return JS_FALSE;
do {
vector[ale->index] = ale->atom;
next = ale->next;
ale->next = NULL;
} while ((ale = next) != NULL);
al->list = NULL;
al->count = 0;
map->vector = vector;
map->length = (jsatomid)count;
return JS_TRUE;
}
JS_FRIEND_API(void)
js_FreeAtomMap(JSContext *cx, JSAtomMap *map)
{
if (map->vector) {
free(map->vector);
map->vector = NULL;
}
map->length = 0;
}

273
mozilla/js/src/jsatom.h Normal file
View File

@@ -0,0 +1,273 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsatom_h___
#define jsatom_h___
/*
* JS atom table.
*/
#include <stddef.h>
#include "jstypes.h"
#include "jshash.h" /* Added by JSIFY */
#include "jsapi.h"
#include "jsprvtd.h"
#include "jspubtd.h"
#ifdef JS_THREADSAFE
#include "jslock.h"
#endif
JS_BEGIN_EXTERN_C
#define ATOM_NOCOPY 0x01 /* don't copy atom string bytes */
#define ATOM_TMPSTR 0x02 /* internal, to avoid extra string */
#define ATOM_MARK 0x04 /* atom is reachable via GC */
#define ATOM_PINNED 0x08 /* atom is pinned against GC */
struct JSAtom {
JSHashEntry entry; /* key is jsval, value keyword info */
uint8 flags; /* flags, PINNED and/or MARK for now */
int8 kwindex; /* keyword index, -1 if not keyword */
jsatomid number; /* atom serial number and hash code */
};
#define ATOM_KEY(atom) ((jsval)(atom)->entry.key)
#define ATOM_IS_OBJECT(atom) JSVAL_IS_OBJECT(ATOM_KEY(atom))
#define ATOM_TO_OBJECT(atom) JSVAL_TO_OBJECT(ATOM_KEY(atom))
#define ATOM_IS_INT(atom) JSVAL_IS_INT(ATOM_KEY(atom))
#define ATOM_TO_INT(atom) JSVAL_TO_INT(ATOM_KEY(atom))
#define ATOM_IS_DOUBLE(atom) JSVAL_IS_DOUBLE(ATOM_KEY(atom))
#define ATOM_TO_DOUBLE(atom) JSVAL_TO_DOUBLE(ATOM_KEY(atom))
#define ATOM_IS_STRING(atom) JSVAL_IS_STRING(ATOM_KEY(atom))
#define ATOM_TO_STRING(atom) JSVAL_TO_STRING(ATOM_KEY(atom))
#define ATOM_IS_BOOLEAN(atom) JSVAL_IS_BOOLEAN(ATOM_KEY(atom))
#define ATOM_TO_BOOLEAN(atom) JSVAL_TO_BOOLEAN(ATOM_KEY(atom))
#define ATOM_BYTES(atom) JS_GetStringBytes(ATOM_TO_STRING(atom))
struct JSAtomListElement {
JSAtomListElement *next;
jsatomid index; /* index in script-specific atom map */
JSAtom *atom;
};
struct JSAtomList {
JSAtomListElement *list; /* literals indexed for mapping */
jsuint count; /* count of indexed literals */
};
#define ATOM_LIST_INIT(al) ((al)->list = NULL, (al)->count = 0)
#define ATOM_LIST_SEARCH(_ale,_al,_atom) \
JS_BEGIN_MACRO \
JSAtomListElement **_alep = &(_al)->list; \
while ((_ale = *_alep) != NULL) { \
if (_ale->atom == (_atom)) { \
/* Hit, move atom's element to the front of the list. */ \
*_alep = _ale->next; \
_ale->next = (_al)->list; \
(_al)->list = _ale; \
break; \
} \
_alep = &_ale->next; \
} \
JS_END_MACRO
struct JSAtomMap {
JSAtom **vector; /* array of ptrs to indexed atoms */
jsatomid length; /* count of (to-be-)indexed atoms */
};
struct JSAtomState {
JSRuntime *runtime; /* runtime that owns us */
JSHashTable *table; /* hash table containing all atoms */
jsatomid number; /* one beyond greatest atom number */
/* Type names and value literals. */
JSAtom *typeAtoms[JSTYPE_LIMIT];
JSAtom *booleanAtoms[2];
JSAtom *nullAtom;
/* Various built-in or commonly-used atoms. */
JSAtom *ArrayAtom;
JSAtom *MathAtom;
JSAtom *ObjectAtom;
JSAtom *anonymousAtom;
JSAtom *argumentsAtom;
JSAtom *arityAtom;
JSAtom *assignAtom;
JSAtom *calleeAtom;
JSAtom *callerAtom;
JSAtom *classPrototypeAtom;
JSAtom *constructorAtom;
JSAtom *countAtom;
JSAtom *indexAtom;
JSAtom *inputAtom;
JSAtom *lengthAtom;
JSAtom *nameAtom;
JSAtom *parentAtom;
JSAtom *protoAtom;
JSAtom *toSourceAtom;
JSAtom *toStringAtom;
JSAtom *valueOfAtom;
JSAtom *evalAtom;
#ifdef JS_THREADSAFE
JSThinLock lock;
volatile uint32 tablegen;
#endif
};
/* Well-known predefined strings and their atoms. */
extern char *js_type_str[];
extern char *js_boolean_str[];
extern char js_Array_str[];
extern char js_Math_str[];
extern char js_Object_str[];
extern char js_anonymous_str[];
extern char js_arguments_str[];
extern char js_arity_str[];
extern char js_assign_str[];
extern char js_callee_str[];
extern char js_caller_str[];
extern char js_class_prototype_str[];
extern char js_constructor_str[];
extern char js_count_str[];
extern char js_eval_str[];
extern char js_index_str[];
extern char js_input_str[];
extern char js_length_str[];
extern char js_name_str[];
extern char js_parent_str[];
extern char js_proto_str[];
extern char js_toSource_str[];
extern char js_toString_str[];
extern char js_valueOf_str[];
/*
* Initialize atom state. Return true on success, false with an out of
* memory error report on failure.
*/
extern JSBool
js_InitAtomState(JSContext *cx, JSAtomState *state);
/*
* Free and clear atom state.
*/
extern void
js_FreeAtomState(JSContext *cx, JSAtomState *state);
/*
* Atom garbage collection hooks.
*/
typedef void
(*JSGCThingMarker)(JSRuntime *rt, void *thing);
extern void
js_MarkAtomState(JSAtomState *state, JSGCThingMarker mark);
extern void
js_SweepAtomState(JSAtomState *state);
extern void
js_UnpinPinnedAtoms(JSAtomState *state);
/*
* Find or create the atom for an object. If we create a new atom, give it the
* type indicated in flags. Return 0 on failure to allocate memory.
*/
extern JSAtom *
js_AtomizeObject(JSContext *cx, JSObject *obj, uintN flags);
/*
* Find or create the atom for a Boolean value. If we create a new atom, give
* it the type indicated in flags. Return 0 on failure to allocate memory.
*/
extern JSAtom *
js_AtomizeBoolean(JSContext *cx, JSBool b, uintN flags);
/*
* Find or create the atom for an integer value. If we create a new atom, give
* it the type indicated in flags. Return 0 on failure to allocate memory.
*/
extern JSAtom *
js_AtomizeInt(JSContext *cx, jsint i, uintN flags);
/*
* Find or create the atom for a double value. If we create a new atom, give
* it the type indicated in flags. Return 0 on failure to allocate memory.
*/
extern JSAtom *
js_AtomizeDouble(JSContext *cx, jsdouble d, uintN flags);
/*
* Find or create the atom for a string. If we create a new atom, give it the
* type indicated in flags. Return 0 on failure to allocate memory.
*/
extern JSAtom *
js_AtomizeString(JSContext *cx, JSString *str, uintN flags);
extern JS_FRIEND_API(JSAtom *)
js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags);
extern JS_FRIEND_API(JSAtom *)
js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags);
/*
* This variant handles all value tag types.
*/
extern JSAtom *
js_AtomizeValue(JSContext *cx, jsval value, uintN flags);
/*
* Convert v to an atomized string.
*/
extern JSAtom *
js_ValueToStringAtom(JSContext *cx, jsval v);
/*
* Assign atom an index and insert it on al.
*/
extern JSAtomListElement *
js_IndexAtom(JSContext *cx, JSAtom *atom, JSAtomList *al);
/*
* Get the atom with index i from map.
*/
extern JS_FRIEND_API(JSAtom *)
js_GetAtom(JSContext *cx, JSAtomMap *map, jsatomid i);
/*
* For all unmapped atoms recorded in al, add a mapping from the atom's index
* to its address. The GC must not run until all indexed atoms in atomLists
* have been mapped by scripts connected to live objects (Function and Script
* class objects have scripts as/in their private data -- the GC knows about
* these two classes).
*/
extern JS_FRIEND_API(JSBool)
js_InitAtomMap(JSContext *cx, JSAtomMap *map, JSAtomList *al);
/*
* Free map->vector and clear map.
*/
extern JS_FRIEND_API(void)
js_FreeAtomMap(JSContext *cx, JSAtomMap *map);
JS_END_EXTERN_C
#endif /* jsatom_h___ */

92
mozilla/js/src/jsbit.h Normal file
View File

@@ -0,0 +1,92 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsbit_h___
#define jsbit_h___
#include "jstypes.h"
JS_BEGIN_EXTERN_C
/*
** A jsbitmap_t is a long integer that can be used for bitmaps
*/
typedef unsigned long jsbitmap_t;
#define JS_TEST_BIT(_map,_bit) \
((_map)[(_bit)>>JS_BITS_PER_LONG_LOG2] & (1L << ((_bit) & (JS_BITS_PER_LONG-1))))
#define JS_SET_BIT(_map,_bit) \
((_map)[(_bit)>>JS_BITS_PER_LONG_LOG2] |= (1L << ((_bit) & (JS_BITS_PER_LONG-1))))
#define JS_CLEAR_BIT(_map,_bit) \
((_map)[(_bit)>>JS_BITS_PER_LONG_LOG2] &= ~(1L << ((_bit) & (JS_BITS_PER_LONG-1))))
/*
** Compute the log of the least power of 2 greater than or equal to n
*/
JS_EXTERN_API(JSIntn) JS_CeilingLog2(JSUint32 i);
/*
** Compute the log of the greatest power of 2 less than or equal to n
*/
JS_EXTERN_API(JSIntn) JS_FloorLog2(JSUint32 i);
/*
** Macro version of JS_CeilingLog2: Compute the log of the least power of
** 2 greater than or equal to _n. The result is returned in _log2.
*/
#define JS_CEILING_LOG2(_log2,_n) \
JS_BEGIN_MACRO \
JSUint32 j_ = (JSUint32)(_n); \
(_log2) = 0; \
if ((j_) & ((j_)-1)) \
(_log2) += 1; \
if ((j_) >> 16) \
(_log2) += 16, (j_) >>= 16; \
if ((j_) >> 8) \
(_log2) += 8, (j_) >>= 8; \
if ((j_) >> 4) \
(_log2) += 4, (j_) >>= 4; \
if ((j_) >> 2) \
(_log2) += 2, (j_) >>= 2; \
if ((j_) >> 1) \
(_log2) += 1; \
JS_END_MACRO
/*
** Macro version of JS_FloorLog2: Compute the log of the greatest power of
** 2 less than or equal to _n. The result is returned in _log2.
**
** This is equivalent to finding the highest set bit in the word.
*/
#define JS_FLOOR_LOG2(_log2,_n) \
JS_BEGIN_MACRO \
JSUint32 j_ = (JSUint32)(_n); \
(_log2) = 0; \
if ((j_) >> 16) \
(_log2) += 16, (j_) >>= 16; \
if ((j_) >> 8) \
(_log2) += 8, (j_) >>= 8; \
if ((j_) >> 4) \
(_log2) += 4, (j_) >>= 4; \
if ((j_) >> 2) \
(_log2) += 2, (j_) >>= 2; \
if ((j_) >> 1) \
(_log2) += 1; \
JS_END_MACRO
JS_END_EXTERN_C
#endif /* jsbit_h___ */

222
mozilla/js/src/jsbool.c Normal file
View File

@@ -0,0 +1,222 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* JS boolean implementation.
*/
#include "jsstddef.h"
#include "jstypes.h"
#include "jsutil.h" /* Added by JSIFY */
#include "jsapi.h"
#include "jsatom.h"
#include "jsbool.h"
#include "jscntxt.h"
#include "jsconfig.h"
#include "jsinterp.h"
#include "jslock.h"
#include "jsnum.h"
#include "jsobj.h"
#include "jsstr.h"
static JSClass boolean_class = {
"Boolean",
JSCLASS_HAS_PRIVATE,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
};
#if JS_HAS_TOSOURCE
#include "jsprf.h"
static JSBool
bool_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
jsval v;
char buf[32];
JSString *str;
if (!JS_InstanceOf(cx, obj, &boolean_class, argv))
return JS_FALSE;
v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
if (!JSVAL_IS_BOOLEAN(v))
return js_obj_toSource(cx, obj, argc, argv, rval);
JS_snprintf(buf, sizeof buf, "(new %s(%s))",
boolean_class.name,
js_boolean_str[JSVAL_TO_BOOLEAN(v) ? 1 : 0]);
str = JS_NewStringCopyZ(cx, buf);
if (!str)
return JS_FALSE;
*rval = STRING_TO_JSVAL(str);
return JS_TRUE;
}
#endif
static JSBool
bool_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
jsval v;
JSAtom *atom;
JSString *str;
if (!JS_InstanceOf(cx, obj, &boolean_class, argv))
return JS_FALSE;
v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
if (!JSVAL_IS_BOOLEAN(v))
return js_obj_toString(cx, obj, argc, argv, rval);
atom = cx->runtime->atomState.booleanAtoms[JSVAL_TO_BOOLEAN(v) ? 1 : 0];
str = ATOM_TO_STRING(atom);
if (!str)
return JS_FALSE;
*rval = STRING_TO_JSVAL(str);
return JS_TRUE;
}
static JSBool
bool_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
if (!JS_InstanceOf(cx, obj, &boolean_class, argv))
return JS_FALSE;
*rval = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
return JS_TRUE;
}
static JSFunctionSpec boolean_methods[] = {
#if JS_HAS_TOSOURCE
{js_toSource_str, bool_toSource, 0},
#endif
{js_toString_str, bool_toString, 0},
{js_valueOf_str, bool_valueOf, 0},
{0}
};
#ifdef XP_MAC
#undef Boolean
#define Boolean js_Boolean
#endif
static JSBool
Boolean(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
JSBool b;
jsval bval;
if (argc != 0) {
if (!js_ValueToBoolean(cx, argv[0], &b))
return JS_FALSE;
bval = BOOLEAN_TO_JSVAL(b);
} else {
bval = JSVAL_FALSE;
}
if (!cx->fp->constructing) {
*rval = bval;
return JS_TRUE;
}
OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, bval);
return JS_TRUE;
}
JSObject *
js_InitBooleanClass(JSContext *cx, JSObject *obj)
{
JSObject *proto;
proto = JS_InitClass(cx, obj, NULL, &boolean_class, Boolean, 1,
NULL, boolean_methods, NULL, NULL);
if (!proto)
return NULL;
OBJ_SET_SLOT(cx, proto, JSSLOT_PRIVATE, JSVAL_FALSE);
return proto;
}
JSObject *
js_BooleanToObject(JSContext *cx, JSBool b)
{
JSObject *obj;
obj = js_NewObject(cx, &boolean_class, NULL, NULL);
if (!obj)
return NULL;
OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, BOOLEAN_TO_JSVAL(b));
return obj;
}
JSString *
js_BooleanToString(JSContext *cx, JSBool b)
{
return ATOM_TO_STRING(cx->runtime->atomState.booleanAtoms[b ? 1 : 0]);
}
JSBool
js_ValueToBoolean(JSContext *cx, jsval v, JSBool *bp)
{
JSBool b;
jsdouble d;
#if defined XP_PC && defined _MSC_VER && _MSC_VER <= 800
/* MSVC1.5 coredumps */
if (!bp)
return JS_TRUE;
/* This should be an if-else chain, but MSVC1.5 crashes if it is. */
#define ELSE
#else
#define ELSE else
#endif
if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v)) {
/* Must return early to avoid falling thru to JSVAL_IS_OBJECT case. */
*bp = JS_FALSE;
return JS_TRUE;
}
if (JSVAL_IS_OBJECT(v)) {
if (!JSVERSION_IS_ECMA(cx->version)) {
if (!OBJ_DEFAULT_VALUE(cx, JSVAL_TO_OBJECT(v), JSTYPE_BOOLEAN, &v))
return JS_FALSE;
if (!JSVAL_IS_BOOLEAN(v))
v = JSVAL_TRUE; /* non-null object is true */
b = JSVAL_TO_BOOLEAN(v);
} else {
b = JS_TRUE;
}
} ELSE
if (JSVAL_IS_STRING(v)) {
b = JSVAL_TO_STRING(v)->length ? JS_TRUE : JS_FALSE;
} ELSE
if (JSVAL_IS_INT(v)) {
b = JSVAL_TO_INT(v) ? JS_TRUE : JS_FALSE;
} ELSE
if (JSVAL_IS_DOUBLE(v)) {
d = *JSVAL_TO_DOUBLE(v);
b = (!JSDOUBLE_IS_NaN(d) && d != 0) ? JS_TRUE : JS_FALSE;
} ELSE
#if defined XP_PC && defined _MSC_VER && _MSC_VER <= 800
if (JSVAL_IS_BOOLEAN(v)) {
b = JSVAL_TO_BOOLEAN(v);
}
#else
{
JS_ASSERT(JSVAL_IS_BOOLEAN(v));
b = JSVAL_TO_BOOLEAN(v);
}
#endif
#undef ELSE
*bp = b;
return JS_TRUE;
}

View File

@@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
@@ -16,10 +16,26 @@
* Reserved.
*/
#ifndef __NS_JSWINREG_H__
#define __NS_JSWINREG_H__
#ifndef jsbool_h___
#define jsbool_h___
/*
* JS boolean interface.
*/
PRInt32
InitWinRegPrototype(JSContext *jscontext, JSObject *global, JSObject **winRegPrototype);
JS_BEGIN_EXTERN_C
#endif
extern JSObject *
js_InitBooleanClass(JSContext *cx, JSObject *obj);
extern JSObject *
js_BooleanToObject(JSContext *cx, JSBool b);
extern JSString *
js_BooleanToString(JSContext *cx, JSBool b);
extern JSBool
js_ValueToBoolean(JSContext *cx, jsval v, JSBool *bp);
JS_END_EXTERN_C
#endif /* jsbool_h___ */

119
mozilla/js/src/jsclist.h Normal file
View File

@@ -0,0 +1,119 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsclist_h___
#define jsclist_h___
#include "jstypes.h"
/*
** Circular linked list
*/
typedef struct JSCListStr {
struct JSCListStr *next;
struct JSCListStr *prev;
} JSCList;
/*
** Insert element "_e" into the list, before "_l".
*/
#define JS_INSERT_BEFORE(_e,_l) \
JS_BEGIN_MACRO \
(_e)->next = (_l); \
(_e)->prev = (_l)->prev; \
(_l)->prev->next = (_e); \
(_l)->prev = (_e); \
JS_END_MACRO
/*
** Insert element "_e" into the list, after "_l".
*/
#define JS_INSERT_AFTER(_e,_l) \
JS_BEGIN_MACRO \
(_e)->next = (_l)->next; \
(_e)->prev = (_l); \
(_l)->next->prev = (_e); \
(_l)->next = (_e); \
JS_END_MACRO
/*
** Return the element following element "_e"
*/
#define JS_NEXT_LINK(_e) \
((_e)->next)
/*
** Return the element preceding element "_e"
*/
#define JS_PREV_LINK(_e) \
((_e)->prev)
/*
** Append an element "_e" to the end of the list "_l"
*/
#define JS_APPEND_LINK(_e,_l) JS_INSERT_BEFORE(_e,_l)
/*
** Insert an element "_e" at the head of the list "_l"
*/
#define JS_INSERT_LINK(_e,_l) JS_INSERT_AFTER(_e,_l)
/* Return the head/tail of the list */
#define JS_LIST_HEAD(_l) (_l)->next
#define JS_LIST_TAIL(_l) (_l)->prev
/*
** Remove the element "_e" from it's circular list.
*/
#define JS_REMOVE_LINK(_e) \
JS_BEGIN_MACRO \
(_e)->prev->next = (_e)->next; \
(_e)->next->prev = (_e)->prev; \
JS_END_MACRO
/*
** Remove the element "_e" from it's circular list. Also initializes the
** linkage.
*/
#define JS_REMOVE_AND_INIT_LINK(_e) \
JS_BEGIN_MACRO \
(_e)->prev->next = (_e)->next; \
(_e)->next->prev = (_e)->prev; \
(_e)->next = (_e); \
(_e)->prev = (_e); \
JS_END_MACRO
/*
** Return non-zero if the given circular list "_l" is empty, zero if the
** circular list is not empty
*/
#define JS_CLIST_IS_EMPTY(_l) \
((_l)->next == (_l))
/*
** Initialize a circular list
*/
#define JS_INIT_CLIST(_l) \
JS_BEGIN_MACRO \
(_l)->next = (_l); \
(_l)->prev = (_l); \
JS_END_MACRO
#define JS_INIT_STATIC_CLIST(_l) \
{(_l), (_l)}
#endif /* jsclist_h___ */

455
mozilla/js/src/jscntxt.c Normal file
View File

@@ -0,0 +1,455 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* JS execution context.
*/
#include "jsstddef.h"
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "jstypes.h"
#include "jsarena.h" /* Added by JSIFY */
#include "jsutil.h" /* Added by JSIFY */
#include "jsclist.h"
#include "jsprf.h"
#include "jsatom.h"
#include "jscntxt.h"
#include "jsconfig.h"
#include "jsdbgapi.h"
#include "jsexn.h"
#include "jsgc.h"
#include "jslock.h"
#include "jsobj.h"
#include "jsopcode.h"
#include "jsscan.h"
#include "jsscript.h"
JSContext *
js_NewContext(JSRuntime *rt, size_t stacksize)
{
JSContext *cx;
cx = malloc(sizeof *cx);
if (!cx)
return NULL;
memset(cx, 0, sizeof *cx);
cx->runtime = rt;
#ifdef JS_THREADSAFE
js_InitContextForLocking(cx);
#endif
if (rt->contextList.next == (JSCList *)&rt->contextList) {
/* First context on this runtime: initialize atoms and keywords. */
if (!js_InitAtomState(cx, &rt->atomState) ||
!js_InitScanner(cx)) {
free(cx);
return NULL;
}
}
/* Atomicly append cx to rt's context list. */
JS_LOCK_RUNTIME_VOID(rt, JS_APPEND_LINK(&cx->links, &rt->contextList));
cx->version = JSVERSION_DEFAULT;
cx->jsop_eq = JSOP_EQ;
cx->jsop_ne = JSOP_NE;
JS_InitArenaPool(&cx->stackPool, "stack", stacksize, sizeof(jsval));
JS_InitArenaPool(&cx->codePool, "code", 1024, sizeof(jsbytecode));
JS_InitArenaPool(&cx->tempPool, "temp", 1024, sizeof(jsdouble));
#if JS_HAS_REGEXPS
if (!js_InitRegExpStatics(cx, &cx->regExpStatics)) {
js_DestroyContext(cx);
return NULL;
}
#endif
#if JS_HAS_EXCEPTIONS
cx->throwing = JS_FALSE;
#endif
return cx;
}
void
js_DestroyContext(JSContext *cx)
{
JSRuntime *rt;
JSBool rtempty;
rt = cx->runtime;
/* Remove cx from context list first. */
JS_LOCK_RUNTIME(rt);
JS_REMOVE_LINK(&cx->links);
rtempty = (rt->contextList.next == (JSCList *)&rt->contextList);
JS_UNLOCK_RUNTIME(rt);
if (rtempty) {
/* Unpin all pinned atoms before final GC. */
js_UnpinPinnedAtoms(&rt->atomState);
/* Unlock GC things held by runtime pointers. */
js_UnlockGCThing(cx, rt->jsNaN);
js_UnlockGCThing(cx, rt->jsNegativeInfinity);
js_UnlockGCThing(cx, rt->jsPositiveInfinity);
js_UnlockGCThing(cx, rt->emptyString);
/*
* Clear these so they get recreated if the standard classes are
* initialized again.
*/
rt->jsNaN = NULL;
rt->jsNegativeInfinity = NULL;
rt->jsPositiveInfinity = NULL;
rt->emptyString = NULL;
/* Clear debugging state to remove GC roots. */
JS_ClearAllTraps(cx);
JS_ClearAllWatchPoints(cx);
}
/* Remove more GC roots in regExpStatics, then collect garbage. */
#if JS_HAS_REGEXPS
js_FreeRegExpStatics(cx, &cx->regExpStatics);
#endif
js_ForceGC(cx);
if (rtempty) {
/* Free atom state now that we've run the GC. */
js_FreeAtomState(cx, &rt->atomState);
}
/* Free the stuff hanging off of cx. */
JS_FinishArenaPool(&cx->stackPool);
JS_FinishArenaPool(&cx->codePool);
JS_FinishArenaPool(&cx->tempPool);
if (cx->lastMessage)
free(cx->lastMessage);
free(cx);
}
JSContext *
js_ContextIterator(JSRuntime *rt, JSContext **iterp)
{
JSContext *cx = *iterp;
JS_LOCK_RUNTIME(rt);
if (!cx)
cx = (JSContext *)rt->contextList.next;
if ((void *)cx == &rt->contextList)
cx = NULL;
else
*iterp = (JSContext *)cx->links.next;
JS_UNLOCK_RUNTIME(rt);
return cx;
}
void
js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap)
{
JSStackFrame *fp;
JSErrorReport report, *reportp;
char *last;
fp = cx->fp;
if (fp && fp->script && fp->pc) {
report.filename = fp->script->filename;
report.lineno = js_PCToLineNumber(fp->script, fp->pc);
/* XXX should fetch line somehow */
report.linebuf = NULL;
report.tokenptr = NULL;
report.flags = flags;
reportp = &report;
} else {
/* XXXshaver still fill out report here for flags? */
reportp = NULL;
}
last = JS_vsmprintf(format, ap);
if (!last)
return;
js_ReportErrorAgain(cx, last, reportp);
free(last);
}
/*
* The arguments from ap need to be packaged up into an array and stored
* into the report struct.
*
* The format string addressed by the error number may contain operands
* identified by the format {N}, where N is a decimal digit. Each of these
* is to be replaced by the Nth argument from the va_list. The complete
* message is placed into reportp->ucmessage converted to a JSString.
*
* returns true/false if the expansion succeeds (can fail for memory errors)
*/
JSBool
js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,
void *userRef, const uintN errorNumber,
char **messagep, JSErrorReport *reportp,
JSBool charArgs, va_list ap)
{
const JSErrorFormatString *fmtData;
int i;
int argCount;
*messagep = NULL;
if (callback) {
fmtData = (*callback)(userRef, "Mountain View", errorNumber);
if (fmtData != NULL) {
int totalArgsLength = 0;
int argLengths[10]; /* only {0} thru {9} supported */
argCount = fmtData->argCount;
JS_ASSERT(argCount <= 10);
if (argCount > 0) {
/*
* Gather the arguments into an array, and accumulate
* their sizes. We allocate 1 more than necessary and
* null it out to act as the caboose when we free the
* pointers later.
*/
reportp->messageArgs
= JS_malloc(cx, sizeof(jschar *) * (argCount + 1));
if (!reportp->messageArgs)
return JS_FALSE;
reportp->messageArgs[argCount] = NULL;
for (i = 0; i < argCount; i++) {
if (charArgs) {
char *charArg = va_arg(ap, char *);
reportp->messageArgs[i]
= js_InflateString(cx, charArg, strlen(charArg));
}
else
reportp->messageArgs[i] = va_arg(ap, jschar *);
argLengths[i] = js_strlen(reportp->messageArgs[i]);
totalArgsLength += argLengths[i];
}
/* NULL-terminate for easy copying. */
reportp->messageArgs[i] = NULL;
}
/*
* Parse the error format, substituting the argument X
* for {X} in the format.
*/
if (argCount > 0) {
if (fmtData->format) {
const char *fmt;
const jschar *arg;
jschar *out;
int expandedArgs = 0;
int expandedLength
= strlen(fmtData->format)
- (3 * argCount) /* exclude the {n} */
+ totalArgsLength;
/* Note - the above calculation assumes that each argument
* is used once and only once in the expansion !!!
*/
reportp->ucmessage = out
= JS_malloc(cx, (expandedLength + 1) * sizeof(jschar));
if (!out) {
if (reportp->messageArgs) {
JS_free(cx, (void *)reportp->messageArgs);
reportp->messageArgs = NULL;
}
return JS_FALSE;
}
fmt = fmtData->format;
while (*fmt) {
if (*fmt == '{') { /* balance} */
if (isdigit(fmt[1])) {
int d = JS7_UNDEC(fmt[1]);
JS_ASSERT(expandedArgs < argCount);
arg = reportp->messageArgs[d];
js_strncpy(out, arg, argLengths[d]);
out += argLengths[d];
fmt += 3;
expandedArgs++;
continue;
}
}
/*
* is this kosher?
*/
*out++ = (unsigned char)(*fmt++);
}
JS_ASSERT(expandedArgs == argCount);
*out = 0;
*messagep = js_DeflateString(cx, reportp->ucmessage,
out - reportp->ucmessage);
}
} else { /* 0 arguments, the format string
(if it exists) is the entire message */
if (fmtData->format) {
*messagep = JS_strdup(cx, fmtData->format);
reportp->ucmessage
= js_InflateString(cx, *messagep, strlen(*messagep));
}
}
}
}
if (*messagep == NULL) {
/* where's the right place for this ??? */
const char *defaultErrorMessage
= "No error message available for error number %d";
size_t nbytes = strlen(defaultErrorMessage) + 16;
*messagep = (char *)JS_malloc(cx, nbytes);
JS_snprintf(*messagep, nbytes, defaultErrorMessage, errorNumber);
}
return JS_TRUE;
}
void
js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback,
void *userRef, const uintN errorNumber,
JSBool charArgs, va_list ap)
{
JSStackFrame *fp;
JSErrorReport report;
char *message;
report.messageArgs = NULL;
report.ucmessage = NULL;
message = NULL;
fp = cx->fp;
if (fp && fp->script && fp->pc) {
report.filename = fp->script->filename;
report.lineno = js_PCToLineNumber(fp->script, fp->pc);
} else {
report.filename = NULL;
report.lineno = 0;
}
/* XXX should fetch line somehow */
report.linebuf = NULL;
report.tokenptr = NULL;
report.flags = flags;
report.errorNumber = errorNumber;
if (!js_ExpandErrorArguments(cx, callback, userRef, errorNumber,
&message, &report, charArgs, ap))
return;
#if JS_HAS_ERROR_EXCEPTIONS
/*
* Check the error report, and set a JavaScript-catchable exception
* if the error is defined to have an associated exception. If an
* exception is thrown, then the JSREPORT_EXCEPTION flag will be set
* on the error report, and exception-aware hosts should ignore it.
* We set the JSREPORT_EXCEPTION flag for the special case of
* user-thrown exeptions.
*/
if (errorNumber == JSMSG_UNCAUGHT_EXCEPTION)
report.flags |= JSREPORT_EXCEPTION;
/*
* Only call the error reporter if an exception wasn't raised.
*
* If an exception was raised, then we call the debugErrorHook
* (if present) to give it a chance to see the error before it
* propigates out of scope. This is needed for compatability with
* the old scheme.
*/
if (!js_ErrorToException(cx, message, &report))
js_ReportErrorAgain(cx, message, &report);
else if (cx->runtime->debugErrorHook && cx->errorReporter) {
JSDebugErrorHook hook = cx->runtime->debugErrorHook;
/* test local in case debugErrorHook changed on another thread */
if (hook)
hook(cx, message, &report, cx->runtime->debugErrorHookData);
}
#else
js_ReportErrorAgain(cx, message, &report);
#endif
if (message)
JS_free(cx, message);
if (report.messageArgs) {
int i = 0;
while (report.messageArgs[i])
JS_free(cx, (void *)report.messageArgs[i++]);
JS_free(cx, (void *)report.messageArgs);
}
if (report.ucmessage)
JS_free(cx, (void *)report.ucmessage);
}
JS_FRIEND_API(void)
js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *reportp)
{
JSErrorReporter onError;
if (!message)
return;
if (cx->lastMessage)
free(cx->lastMessage);
cx->lastMessage = JS_strdup(cx, message);
if (!cx->lastMessage)
return;
onError = cx->errorReporter;
/*
* If debugErrorHook is present then we give it a chance to veto
* sending the error on to the regular ErrorReporter.
*/
if (cx->runtime->debugErrorHook && onError) {
JSDebugErrorHook hook = cx->runtime->debugErrorHook;
/* test local in case debugErrorHook changed on another thread */
if (hook && !hook(cx, message, reportp,
cx->runtime->debugErrorHookData)) {
onError = NULL;
}
}
if (onError)
(*onError)(cx, cx->lastMessage, reportp);
}
void
js_ReportIsNotDefined(JSContext *cx, const char *name)
{
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NOT_DEFINED, name);
}
#if defined DEBUG && defined XP_UNIX
/* For gdb usage. */
void js_traceon(JSContext *cx) { cx->tracefp = stderr; }
void js_traceoff(JSContext *cx) { cx->tracefp = NULL; }
#endif
JSErrorFormatString js_ErrorFormatString[JSErr_Limit] = {
#if JS_HAS_DFLT_MSG_STRINGS
#define MSG_DEF(name, number, count, exception, format) \
{ format, count } ,
#else
#define MSG_DEF(name, number, count, exception, format) \
{ NULL, count } ,
#endif
#include "js.msg"
#undef MSG_DEF
};
const JSErrorFormatString *
js_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber)
{
if ((errorNumber > 0) && (errorNumber < JSErr_Limit))
return &js_ErrorFormatString[errorNumber];
else
return NULL;
}

232
mozilla/js/src/jscntxt.h Normal file
View File

@@ -0,0 +1,232 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jscntxt_h___
#define jscntxt_h___
/*
* JS execution context.
*/
#include "jsarena.h" /* Added by JSIFY */
#include "jsclist.h"
#include "jslong.h"
#include "jsatom.h"
#include "jsconfig.h"
#include "jsgc.h"
#include "jsinterp.h"
#include "jsobj.h"
#include "jsprvtd.h"
#include "jspubtd.h"
#include "jsregexp.h"
JS_BEGIN_EXTERN_C
struct JSRuntime {
/* Garbage collector state, used by jsgc.c. */
JSArenaPool gcArenaPool;
JSArenaPool gcFlagsPool;
JSHashTable *gcRootsHash;
JSGCThing *gcFreeList;
uint32 gcBytes;
uint32 gcLastBytes;
uint32 gcMaxBytes;
uint32 gcLevel;
uint32 gcNumber;
JSBool gcPoke;
JSGCCallback gcCallback;
#ifdef JS_GCMETER
JSGCStats gcStats;
#endif
/* Literal table maintained by jsatom.c functions. */
JSAtomState atomState;
/* Random number generator state, used by jsmath.c. */
JSBool rngInitialized;
int64 rngMultiplier;
int64 rngAddend;
int64 rngMask;
int64 rngSeed;
jsdouble rngDscale;
/* Well-known numbers held for use by this runtime's contexts. */
jsdouble *jsNaN;
jsdouble *jsNegativeInfinity;
jsdouble *jsPositiveInfinity;
/* Empty string held for use by this runtime's contexts. */
JSString *emptyString;
/* List of active contexts sharing this runtime. */
JSCList contextList;
/* These are used for debugging -- see jsprvtd.h and jsdbgapi.h. */
JSTrapHandler interruptHandler;
void *interruptHandlerData;
JSNewScriptHook newScriptHook;
void *newScriptHookData;
JSDestroyScriptHook destroyScriptHook;
void *destroyScriptHookData;
JSTrapHandler debuggerHandler;
void *debuggerHandlerData;
JSSourceHandler sourceHandler;
void *sourceHandlerData;
JSInterpreterHook executeHook;
void *executeHookData;
JSInterpreterHook callHook;
void *callHookData;
JSObjectHook objectHook;
void *objectHookData;
JSTrapHandler throwHook;
void *throwHookData;
JSDebugErrorHook debugErrorHook;
void *debugErrorHookData;
/* More debugging state, see jsdbgapi.c. */
JSCList trapList;
JSCList watchPointList;
/* Weak links to properties, indexed by quickened get/set opcodes. */
/* XXX must come after JSCLists or MSVC alignment bug bites empty lists */
JSPropertyCache propertyCache;
#ifdef JS_THREADSAFE
/* These combine to interlock the GC and new requests. */
PRLock *gcLock;
PRCondVar *gcDone;
PRCondVar *requestDone;
uint32 requestCount;
/* Lock and owning thread pointer for JS_LOCK_RUNTIME. */
JSThinLock rtLock;
#endif
};
struct JSContext {
JSCList links;
/* Interpreter activation count. */
uintN interpLevel;
/* Runtime version control identifier and equality operators. */
JSVersion version;
jsbytecode jsop_eq;
jsbytecode jsop_ne;
/* Data shared by threads in an address space. */
JSRuntime *runtime;
/* Stack arena pool and frame pointer register. */
JSArenaPool stackPool;
JSStackFrame *fp;
/* Temporary arena pools used while compiling and decompiling. */
JSArenaPool codePool;
JSArenaPool tempPool;
/* Top-level object and pointer to top stack frame's scope chain. */
JSObject *globalObject;
/* Most recently created things by type, members of the GC's root set. */
JSGCThing *newborn[GCX_NTYPES];
/* Regular expression class statics (XXX not shared globally). */
JSRegExpStatics regExpStatics;
/* State for object and array toSource conversion. */
JSSharpObjectMap sharpObjectMap;
/* Last message string and trace file for debugging. */
char *lastMessage;
#ifdef DEBUG
void *tracefp;
#endif
/* Per-context optional user callbacks. */
JSBranchCallback branchCallback;
JSErrorReporter errorReporter;
/* Client opaque pointer */
void *data;
/* GC and thread-safe state. */
JSStackFrame *dormantFrameChain; /* dormant stack frame to scan */
uint32 gcDisabled; /* XXX for pre-ECMAv2 switch */
#ifdef JS_THREADSAFE
jsword thread;
jsrefcount requestDepth;
JSPackedBool gcActive;
#endif
/* Exception state (NB: throwing is packed with gcActive above). */
JSPackedBool throwing; /* is there a pending exception? */
jsval exception; /* most-recently-thrown exceptin */
};
extern JSContext *
js_NewContext(JSRuntime *rt, size_t stacksize);
extern void
js_DestroyContext(JSContext *cx);
extern JSContext *
js_ContextIterator(JSRuntime *rt, JSContext **iterp);
/*
* Report an exception, which is currently realized as a printf-style format
* string and its arguments.
*/
typedef enum JSErrNum {
#define MSG_DEF(name, number, count, exception, format) \
name = number,
#include "js.msg"
#undef MSG_DEF
JSErr_Limit
} JSErrNum;
extern const JSErrorFormatString *
js_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber);
#ifdef va_start
extern void
js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap);
extern void
js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback,
void *userRef, const uintN errorNumber,
JSBool charArgs, va_list ap);
extern JSBool
js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,
void *userRef, const uintN errorNumber,
char **message, JSErrorReport *reportp,
JSBool charArgs, va_list ap);
#endif
/*
* Report an exception using a previously composed JSErrorReport.
*/
extern JS_FRIEND_API(void)
js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *report);
extern void
js_ReportIsNotDefined(JSContext *cx, const char *name);
extern JSErrorFormatString js_ErrorFormatString[JSErr_Limit];
JS_END_EXTERN_C
#endif /* jscntxt_h___ */

20
mozilla/js/src/jscompat.h Normal file
View File

@@ -0,0 +1,20 @@
/* -*- Mode: C; tab-width: 8 -*-
* Copyright © 1996 Netscape Communications Corporation, All Rights Reserved.
*/
#ifndef jscompat_h___
#define jscompat_h___
/*
* Compatibility glue for various NSPR versions. We must always define int8,
* int16, jsword, and so on to minimize differences with js/ref, no matter what
* the NSPR typedef names may be.
*/
#include "jstypes.h"
#include "jslong.h"
typedef JSIntn intN;
typedef JSUintn uintN;
typedef JSUword jsuword;
typedef JSWord jsword;
typedef float float32;
#define allocPriv allocPool
#endif /* jscompat_h___ */

277
mozilla/js/src/jsconfig.h Normal file
View File

@@ -0,0 +1,277 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* JS configuration macros.
*/
#ifndef JS_VERSION
#define JS_VERSION 140
#endif
#if JS_VERSION == 100
#define JS_BUG_AUTO_INDEX_PROPS 1 /* new object o: o.p = v sets o[0] */
#define JS_BUG_NULL_INDEX_PROPS 1 /* o[0] defaults to null, not void */
#define JS_BUG_EMPTY_INDEX_ZERO 1 /* o[""] is equivalent to o[0] */
#define JS_BUG_SHORT_CIRCUIT 1 /* 1 && 1 => true, 1 && 0 => 0 bug */
#define JS_BUG_EAGER_TOSTRING 1 /* o.toString() trumps o.valueOf() */
#define JS_BUG_VOID_TOSTRING 0 /* void 0 + 0 == "undefined0" */
#define JS_BUG_EVAL_THIS_FUN 0 /* eval('this') in function f is f */
#define JS_BUG_EVAL_THIS_SCOPE 0 /* Math.eval('sin(x)') vs. local x */
#define JS_BUG_FALLIBLE_EQOPS 1 /* fallible/intransitive equality ops */
#define JS_BUG_FALLIBLE_TONUM 1 /* fallible ValueToNumber primitive */
#define JS_BUG_WITH_CLOSURE 0 /* with(o)function f(){} sets o.f */
#define JS_BUG_SET_ENUMERATE 1 /* o.p=q flags o.p JSPROP_ENUMERATE */
#define JS_HAS_PROP_DELETE 0 /* delete o.p removes p from o */
#define JS_HAS_CALL_OBJECT 0 /* fun.caller is stack frame obj */
#define JS_HAS_LABEL_STATEMENT 0 /* has break/continue to label: */
#define JS_HAS_DO_WHILE_LOOP 0 /* has do {...} while (b) */
#define JS_HAS_SWITCH_STATEMENT 0 /* has switch (v) {case c: ...} */
#define JS_HAS_SOME_PERL_FUN 0 /* has array.join/reverse/sort */
#define JS_HAS_MORE_PERL_FUN 0 /* has array.push, str.substr, etc */
#define JS_HAS_VALUEOF_HINT 0 /* valueOf(hint) where hint is typeof */
#define JS_HAS_LEXICAL_CLOSURE 0 /* nested functions, lexically closed */
#define JS_HAS_APPLY_FUNCTION 0 /* has fun.apply(obj, argArray) */
#define JS_HAS_CALL_FUNCTION 0 /* has fun.call(obj, arg1, ... argN) */
#define JS_HAS_OBJ_PROTO_PROP 0 /* has o.__proto__ etc. */
#define JS_HAS_REGEXPS 0 /* has perl r.e.s via RegExp, /pat/ */
#define JS_HAS_SEQUENCE_OPS 0 /* has array.slice, string.concat */
#define JS_HAS_INITIALIZERS 0 /* has var o = {'foo': 42, 'bar':3} */
#define JS_HAS_OBJ_WATCHPOINT 0 /* has o.watch and o.unwatch */
#define JS_HAS_EXPORT_IMPORT 0 /* has export fun; import obj.fun */
#define JS_HAS_EVAL_THIS_SCOPE 0 /* Math.eval is same as with (Math) */
#define JS_HAS_TRIPLE_EQOPS 0 /* has === and !== identity eqops */
#define JS_HAS_SHARP_VARS 0 /* has #n=, #n# for object literals */
#define JS_HAS_REPLACE_LAMBDA 0 /* has string.replace(re, lambda) */
#define JS_HAS_SCRIPT_OBJECT 0 /* has (new Script("x++")).exec() */
#define JS_HAS_XDR 0 /* has XDR API and object methods */
#define JS_HAS_EXCEPTIONS 0 /* has exception handling */
#define JS_HAS_UNDEFINED 0 /* has global "undefined" property */
#define JS_HAS_TOSOURCE 0 /* has Object/Array toSource method */
#define JS_HAS_IN_OPERATOR 0 /* has in operator ('p' in {p:1}) */
#define JS_HAS_INSTANCEOF 0 /* has {p:1} instanceof Object */
#define JS_HAS_ARGS_OBJECT 0 /* has minimal ECMA arguments object */
#define JS_HAS_DEBUGGER_KEYWORD 0 /* has hook for debugger keyword */
#define JS_HAS_ERROR_EXCEPTIONS 0 /* has error object hierarchy */
#define JS_HAS_CATCH_GUARD 0 /* has exception handling catch guard */
#define JS_HAS_NEW_OBJ_METHODS 0 /* has Object.prototype query methods */
#elif JS_VERSION == 110
#define JS_BUG_AUTO_INDEX_PROPS 0 /* new object o: o.p = v sets o[0] */
#define JS_BUG_NULL_INDEX_PROPS 1 /* o[0] defaults to null, not void */
#define JS_BUG_EMPTY_INDEX_ZERO 1 /* o[""] is equivalent to o[0] */
#define JS_BUG_SHORT_CIRCUIT 1 /* 1 && 1 => true, 1 && 0 => 0 bug */
#define JS_BUG_EAGER_TOSTRING 1 /* o.toString() trumps o.valueOf() */
#define JS_BUG_VOID_TOSTRING 0 /* void 0 + 0 == "undefined0" */
#define JS_BUG_EVAL_THIS_FUN 1 /* eval('this') in function f is f */
#define JS_BUG_EVAL_THIS_SCOPE 1 /* Math.eval('sin(x)') vs. local x */
#define JS_BUG_FALLIBLE_EQOPS 1 /* fallible/intransitive equality ops */
#define JS_BUG_FALLIBLE_TONUM 1 /* fallible ValueToNumber primitive */
#define JS_BUG_WITH_CLOSURE 0 /* with(o)function f(){} sets o.f */
#define JS_BUG_SET_ENUMERATE 1 /* o.p=q flags o.p JSPROP_ENUMERATE */
#define JS_HAS_PROP_DELETE 0 /* delete o.p removes p from o */
#define JS_HAS_CALL_OBJECT 0 /* fun.caller is stack frame obj */
#define JS_HAS_LABEL_STATEMENT 0 /* has break/continue to label: */
#define JS_HAS_DO_WHILE_LOOP 0 /* has do {...} while (b) */
#define JS_HAS_SWITCH_STATEMENT 0 /* has switch (v) {case c: ...} */
#define JS_HAS_SOME_PERL_FUN 1 /* has array.join/reverse/sort */
#define JS_HAS_MORE_PERL_FUN 0 /* has array.push, str.substr, etc */
#define JS_HAS_VALUEOF_HINT 0 /* valueOf(hint) where hint is typeof */
#define JS_HAS_LEXICAL_CLOSURE 0 /* nested functions, lexically closed */
#define JS_HAS_APPLY_FUNCTION 0 /* has apply(fun, arg1, ... argN) */
#define JS_HAS_CALL_FUNCTION 0 /* has fun.call(obj, arg1, ... argN) */
#define JS_HAS_OBJ_PROTO_PROP 0 /* has o.__proto__ etc. */
#define JS_HAS_REGEXPS 0 /* has perl r.e.s via RegExp, /pat/ */
#define JS_HAS_SEQUENCE_OPS 0 /* has array.slice, string.concat */
#define JS_HAS_INITIALIZERS 0 /* has var o = {'foo': 42, 'bar':3} */
#define JS_HAS_OBJ_WATCHPOINT 0 /* has o.watch and o.unwatch */
#define JS_HAS_EXPORT_IMPORT 0 /* has export fun; import obj.fun */
#define JS_HAS_EVAL_THIS_SCOPE 0 /* Math.eval is same as with (Math) */
#define JS_HAS_TRIPLE_EQOPS 0 /* has === and !== identity eqops */
#define JS_HAS_SHARP_VARS 0 /* has #n=, #n# for object literals */
#define JS_HAS_REPLACE_LAMBDA 0 /* has string.replace(re, lambda) */
#define JS_HAS_SCRIPT_OBJECT 0 /* has (new Script("x++")).exec() */
#define JS_HAS_XDR 0 /* has XDR API and object methods */
#define JS_HAS_EXCEPTIONS 0 /* has exception handling */
#define JS_HAS_UNDEFINED 0 /* has global "undefined" property */
#define JS_HAS_TOSOURCE 0 /* has Object/Array toSource method */
#define JS_HAS_IN_OPERATOR 0 /* has in operator ('p' in {p:1}) */
#define JS_HAS_INSTANCEOF 0 /* has {p:1} instanceof Object */
#define JS_HAS_ARGS_OBJECT 0 /* has minimal ECMA arguments object */
#define JS_HAS_DEBUGGER_KEYWORD 0 /* has hook for debugger keyword */
#define JS_HAS_ERROR_EXCEPTIONS 0 /* has error object hierarchy */
#define JS_HAS_CATCH_GUARD 0 /* has exception handling catch guard */
#define JS_HAS_NEW_OBJ_METHODS 0 /* has Object.prototype query methods */
#elif JS_VERSION == 120
#define JS_BUG_AUTO_INDEX_PROPS 0 /* new object o: o.p = v sets o[0] */
#define JS_BUG_NULL_INDEX_PROPS 0 /* o[0] defaults to null, not void */
#define JS_BUG_EMPTY_INDEX_ZERO 0 /* o[""] is equivalent to o[0] */
#define JS_BUG_SHORT_CIRCUIT 0 /* 1 && 1 => true, 1 && 0 => 0 bug */
#define JS_BUG_EAGER_TOSTRING 0 /* o.toString() trumps o.valueOf() */
#define JS_BUG_VOID_TOSTRING 1 /* void 0 + 0 == "undefined0" */
#define JS_BUG_EVAL_THIS_FUN 0 /* eval('this') in function f is f */
#define JS_BUG_EVAL_THIS_SCOPE 0 /* Math.eval('sin(x)') vs. local x */
#define JS_BUG_FALLIBLE_EQOPS 0 /* fallible/intransitive equality ops */
#define JS_BUG_FALLIBLE_TONUM 0 /* fallible ValueToNumber primitive */
#define JS_BUG_WITH_CLOSURE 1 /* with(o)function f(){} sets o.f */
#define JS_BUG_SET_ENUMERATE 1 /* o.p=q flags o.p JSPROP_ENUMERATE */
#define JS_HAS_PROP_DELETE 1 /* delete o.p removes p from o */
#define JS_HAS_CALL_OBJECT 1 /* fun.caller is stack frame obj */
#define JS_HAS_LABEL_STATEMENT 1 /* has break/continue to label: */
#define JS_HAS_DO_WHILE_LOOP 1 /* has do {...} while (b) */
#define JS_HAS_SWITCH_STATEMENT 1 /* has switch (v) {case c: ...} */
#define JS_HAS_SOME_PERL_FUN 1 /* has array.join/reverse/sort */
#define JS_HAS_MORE_PERL_FUN 1 /* has array.push, str.substr, etc */
#define JS_HAS_VALUEOF_HINT 1 /* valueOf(hint) where hint is typeof */
#define JS_HAS_LEXICAL_CLOSURE 1 /* nested functions, lexically closed */
#define JS_HAS_APPLY_FUNCTION 1 /* has apply(fun, arg1, ... argN) */
#define JS_HAS_CALL_FUNCTION 0 /* has fun.call(obj, arg1, ... argN) */
#define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */
#define JS_HAS_REGEXPS 1 /* has perl r.e.s via RegExp, /pat/ */
#define JS_HAS_SEQUENCE_OPS 1 /* has array.slice, string.concat */
#define JS_HAS_INITIALIZERS 1 /* has var o = {'foo': 42, 'bar':3} */
#define JS_HAS_OBJ_WATCHPOINT 1 /* has o.watch and o.unwatch */
#define JS_HAS_EXPORT_IMPORT 1 /* has export fun; import obj.fun */
#define JS_HAS_EVAL_THIS_SCOPE 1 /* Math.eval is same as with (Math) */
#define JS_HAS_TRIPLE_EQOPS 0 /* has === and !== identity eqops */
#define JS_HAS_SHARP_VARS 0 /* has #n=, #n# for object literals */
#define JS_HAS_REPLACE_LAMBDA 0 /* has string.replace(re, lambda) */
#define JS_HAS_SCRIPT_OBJECT 0 /* has (new Script("x++")).exec() */
#define JS_HAS_XDR 0 /* has XDR API and object methods */
#define JS_HAS_EXCEPTIONS 0 /* has exception handling */
#define JS_HAS_UNDEFINED 0 /* has global "undefined" property */
#define JS_HAS_TOSOURCE 0 /* has Object/Array toSource method */
#define JS_HAS_IN_OPERATOR 0 /* has in operator ('p' in {p:1}) */
#define JS_HAS_INSTANCEOF 0 /* has {p:1} instanceof Object */
#define JS_HAS_ARGS_OBJECT 0 /* has minimal ECMA arguments object */
#define JS_HAS_DEBUGGER_KEYWORD 0 /* has hook for debugger keyword */
#define JS_HAS_ERROR_EXCEPTIONS 0 /* has error object hierarchy */
#define JS_HAS_CATCH_GUARD 0 /* has exception handling catch guard */
#define JS_HAS_NEW_OBJ_METHODS 0 /* has Object.prototype query methods */
#elif JS_VERSION == 130
#define JS_BUG_AUTO_INDEX_PROPS 0 /* new object o: o.p = v sets o[0] */
#define JS_BUG_NULL_INDEX_PROPS 0 /* o[0] defaults to null, not void */
#define JS_BUG_EMPTY_INDEX_ZERO 0 /* o[""] is equivalent to o[0] */
#define JS_BUG_SHORT_CIRCUIT 0 /* 1 && 1 => true, 1 && 0 => 0 bug */
#define JS_BUG_EAGER_TOSTRING 0 /* o.toString() trumps o.valueOf() */
#define JS_BUG_VOID_TOSTRING 0 /* void 0 + 0 == "undefined0" */
#define JS_BUG_EVAL_THIS_FUN 0 /* eval('this') in function f is f */
#define JS_BUG_EVAL_THIS_SCOPE 0 /* Math.eval('sin(x)') vs. local x */
#define JS_BUG_FALLIBLE_EQOPS 0 /* fallible/intransitive equality ops */
#define JS_BUG_FALLIBLE_TONUM 0 /* fallible ValueToNumber primitive */
#define JS_BUG_WITH_CLOSURE 1 /* with(o)function f(){} sets o.f */
#define JS_BUG_SET_ENUMERATE 0 /* o.p=q flags o.p JSPROP_ENUMERATE */
#define JS_HAS_PROP_DELETE 1 /* delete o.p removes p from o */
#define JS_HAS_CALL_OBJECT 1 /* fun.caller is stack frame obj */
#define JS_HAS_LABEL_STATEMENT 1 /* has break/continue to label: */
#define JS_HAS_DO_WHILE_LOOP 1 /* has do {...} while (b) */
#define JS_HAS_SWITCH_STATEMENT 1 /* has switch (v) {case c: ...} */
#define JS_HAS_SOME_PERL_FUN 1 /* has array.join/reverse/sort */
#define JS_HAS_MORE_PERL_FUN 1 /* has array.push, str.substr, etc */
#define JS_HAS_VALUEOF_HINT 1 /* valueOf(hint) where hint is typeof */
#define JS_HAS_LEXICAL_CLOSURE 1 /* nested functions, lexically closed */
#define JS_HAS_APPLY_FUNCTION 1 /* has apply(fun, arg1, ... argN) */
#define JS_HAS_CALL_FUNCTION 1 /* has fun.call(obj, arg1, ... argN) */
#define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */
#define JS_HAS_REGEXPS 1 /* has perl r.e.s via RegExp, /pat/ */
#define JS_HAS_SEQUENCE_OPS 1 /* has array.slice, string.concat */
#define JS_HAS_INITIALIZERS 1 /* has var o = {'foo': 42, 'bar':3} */
#define JS_HAS_OBJ_WATCHPOINT 1 /* has o.watch and o.unwatch */
#define JS_HAS_EXPORT_IMPORT 1 /* has export fun; import obj.fun */
#define JS_HAS_EVAL_THIS_SCOPE 1 /* Math.eval is same as with (Math) */
#define JS_HAS_TRIPLE_EQOPS 1 /* has === and !== identity eqops */
#define JS_HAS_SHARP_VARS 1 /* has #n=, #n# for object literals */
#define JS_HAS_REPLACE_LAMBDA 1 /* has string.replace(re, lambda) */
#define JS_HAS_SCRIPT_OBJECT 1 /* has (new Script("x++")).exec() */
#define JS_HAS_XDR 1 /* has XDR API and object methods */
#define JS_HAS_EXCEPTIONS 0 /* has exception handling */
#define JS_HAS_UNDEFINED 1 /* has global "undefined" property */
#define JS_HAS_TOSOURCE 1 /* has Object/Array toSource method */
#define JS_HAS_IN_OPERATOR 0 /* has in operator ('p' in {p:1}) */
#define JS_HAS_INSTANCEOF 0 /* has {p:1} instanceof Object */
#define JS_HAS_ARGS_OBJECT 1 /* has minimal ECMA arguments object */
#define JS_HAS_DEBUGGER_KEYWORD 1 /* has hook for debugger keyword */
#define JS_HAS_ERROR_EXCEPTIONS 0 /* has error object hierarchy */
#define JS_HAS_CATCH_GUARD 0 /* has exception handling catch guard */
#define JS_HAS_NEW_OBJ_METHODS 0 /* has Object.prototype query methods */
#elif JS_VERSION == 140
#define JS_BUG_AUTO_INDEX_PROPS 0 /* new object o: o.p = v sets o[0] */
#define JS_BUG_NULL_INDEX_PROPS 0 /* o[0] defaults to null, not void */
#define JS_BUG_EMPTY_INDEX_ZERO 0 /* o[""] is equivalent to o[0] */
#define JS_BUG_SHORT_CIRCUIT 0 /* 1 && 1 => true, 1 && 0 => 0 bug */
#define JS_BUG_EAGER_TOSTRING 0 /* o.toString() trumps o.valueOf() */
#define JS_BUG_VOID_TOSTRING 0 /* void 0 + 0 == "undefined0" */
#define JS_BUG_EVAL_THIS_FUN 0 /* eval('this') in function f is f */
#define JS_BUG_EVAL_THIS_SCOPE 0 /* Math.eval('sin(x)') vs. local x */
#define JS_BUG_FALLIBLE_EQOPS 0 /* fallible/intransitive equality ops */
#define JS_BUG_FALLIBLE_TONUM 0 /* fallible ValueToNumber primitive */
#define JS_BUG_WITH_CLOSURE 1 /* with(o)function f(){} sets o.f */
#define JS_BUG_SET_ENUMERATE 0 /* o.p=q flags o.p JSPROP_ENUMERATE */
#define JS_HAS_PROP_DELETE 1 /* delete o.p removes p from o */
#define JS_HAS_CALL_OBJECT 1 /* fun.caller is stack frame obj */
#define JS_HAS_LABEL_STATEMENT 1 /* has break/continue to label: */
#define JS_HAS_DO_WHILE_LOOP 1 /* has do {...} while (b) */
#define JS_HAS_SWITCH_STATEMENT 1 /* has switch (v) {case c: ...} */
#define JS_HAS_SOME_PERL_FUN 1 /* has array.join/reverse/sort */
#define JS_HAS_MORE_PERL_FUN 1 /* has array.push, str.substr, etc */
#define JS_HAS_VALUEOF_HINT 1 /* valueOf(hint) where hint is typeof */
#define JS_HAS_LEXICAL_CLOSURE 1 /* nested functions, lexically closed */
#define JS_HAS_APPLY_FUNCTION 1 /* has apply(fun, arg1, ... argN) */
#define JS_HAS_CALL_FUNCTION 1 /* has fun.call(obj, arg1, ... argN) */
#define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */
#define JS_HAS_REGEXPS 1 /* has perl r.e.s via RegExp, /pat/ */
#define JS_HAS_SEQUENCE_OPS 1 /* has array.slice, string.concat */
#define JS_HAS_INITIALIZERS 1 /* has var o = {'foo': 42, 'bar':3} */
#define JS_HAS_OBJ_WATCHPOINT 1 /* has o.watch and o.unwatch */
#define JS_HAS_EXPORT_IMPORT 1 /* has export fun; import obj.fun */
#define JS_HAS_EVAL_THIS_SCOPE 1 /* Math.eval is same as with (Math) */
#define JS_HAS_TRIPLE_EQOPS 1 /* has === and !== identity eqops */
#define JS_HAS_SHARP_VARS 1 /* has #n=, #n# for object literals */
#define JS_HAS_REPLACE_LAMBDA 1 /* has string.replace(re, lambda) */
#define JS_HAS_SCRIPT_OBJECT 1 /* has (new Script("x++")).exec() */
#define JS_HAS_XDR 1 /* has XDR API and object methods */
#define JS_HAS_EXCEPTIONS 1 /* has exception handling */
#define JS_HAS_UNDEFINED 1 /* has global "undefined" property */
#define JS_HAS_TOSOURCE 1 /* has Object/Array toSource method */
#define JS_HAS_IN_OPERATOR 1 /* has in operator ('p' in {p:1}) */
#define JS_HAS_INSTANCEOF 1 /* has {p:1} instanceof Object */
#define JS_HAS_ARGS_OBJECT 1 /* has minimal ECMA arguments object */
#define JS_HAS_DEBUGGER_KEYWORD 1 /* has hook for debugger keyword */
#define JS_HAS_ERROR_EXCEPTIONS 0 /* rt errors reflected as exceptions */
#define JS_HAS_CATCH_GUARD 0 /* has exception handling catch guard */
#define JS_HAS_NEW_OBJ_METHODS 0 /* has Object.prototype query methods */
#define JS_HAS_DFLT_MSG_STRINGS 1 /* provides English error messages */
#else
#error "unknown JS_VERSION"
#endif

135
mozilla/js/src/jsconfig.mk Normal file
View File

@@ -0,0 +1,135 @@
ifndef OBJDIR
ifdef OBJDIR_NAME
OBJDIR = $(OBJDIR_NAME)
endif
endif
NSPR_VERSION = 19980120
NSPR_LOCAL = $(MOZ_DEPTH)/dist/$(OBJDIR)/nspr
NSPR_DIST = $(MOZ_DEPTH)/dist/$(OBJDIR)
NSPR_OBJDIR = $(OBJDIR)
ifeq ($(OS_ARCH), SunOS)
NSPR_OBJDIR := $(subst _sparc,,$(NSPR_OBJDIR))
endif
ifeq ($(OS_ARCH), Linux)
NSPR_OBJDIR := $(subst _All,ELF2.0,$(NSPR_OBJDIR))
endif
ifeq ($(OS_ARCH), AIX)
NSPR_OBJDIR := $(subst 4.1,4.2,$(NSPR_OBJDIR))
endif
ifeq ($(OS_ARCH), WINNT)
NSPR_OBJDIR := $(subst WINNT,WIN95,$(NSPR_OBJDIR))
ifeq ($(OBJDIR), WIN32_D.OBJ)
NSPR_OBJDIR = WIN954.0_DBG.OBJ
endif
ifeq ($(OBJDIR), WIN32_O.OBJ)
NSPR_OBJDIR = WIN954.0_OPT.OBJ
endif
endif
NSPR_SHARED = /share/builds/components/nspr20/$(NSPR_VERSION)/$(NSPR_OBJDIR)
ifeq ($(OS_ARCH), WINNT)
NSPR_SHARED = nspr20/$(NSPR_VERSION)/$(NSPR_OBJDIR)
endif
NSPR_VERSIONFILE = $(NSPR_LOCAL)/Version
NSPR_CURVERSION := $(shell cat $(NSPR_VERSIONFILE))
get_nspr:
@echo "Grabbing NSPR component..."
ifeq ($(NSPR_VERSION), $(NSPR_CURVERSION))
@echo "No need, NSPR is up to date in this tree (ver=$(NSPR_VERSION))."
else
mkdir -p $(NSPR_LOCAL)
mkdir -p $(NSPR_DIST)
ifneq ($(OS_ARCH), WINNT)
cp $(NSPR_SHARED)/*.jar $(NSPR_LOCAL)
else
sh $(MOZ_DEPTH)/../reltools/compftp.sh $(NSPR_SHARED) $(NSPR_LOCAL) *.jar
endif
unzip -o $(NSPR_LOCAL)/mdbinary.jar -d $(NSPR_DIST)
mkdir -p $(NSPR_DIST)/include
unzip -o $(NSPR_LOCAL)/mdheader.jar -d $(NSPR_DIST)/include
rm -rf $(NSPR_DIST)/META-INF
rm -rf $(NSPR_DIST)/include/META-INF
echo $(NSPR_VERSION) > $(NSPR_VERSIONFILE)
endif
SHIP_DIST = $(MOZ_DEPTH)/dist/$(OBJDIR)
SHIP_DIR = $(SHIP_DIST)/SHIP
SHIP_LIBS = libjs.so
ifdef JS_LIVECONNECT
SHIP_LIBS += jsj.so
endif
ifdef JS_THREADSAFE
ifeq ($(OS_ARCH), HP-UX)
SHIP_LIBS += libnspr21.sl
else
SHIP_LIBS += libnspr21.so
endif
endif
ifeq ($(OS_ARCH), WINNT)
SHIP_LIBS = js32.dll
ifdef JS_LIVECONNECT
SHIP_LIBS += jsj.dll
endif
ifdef JS_THREADSAFE
SHIP_LIBS += libnspr21.dll
endif
endif
SHIP_LIBS := $(addprefix $(SHIP_DIST)/lib/, $(SHIP_LIBS))
SHIP_INCS = js*.h
ifdef JS_LIVECONNECT
SHIP_INCS += netscape*.h
endif
SHIP_INCS := $(addprefix $(SHIP_DIST)/include/, $(SHIP_INCS))
SHIP_BINS = js
ifdef JS_LIVECONNECT
SHIP_BINS += jsj
endif
ifeq ($(OS_ARCH), WINNT)
SHIP_BINS := $(addsuffix .exe, $(SHIP_BINS))
endif
SHIP_BINS := $(addprefix $(SHIP_DIST)/bin/, $(SHIP_BINS))
ifdef BUILD_OPT
JSREFJAR = jsref_opt.jar
else
JSREFJAR = jsref_dbg.jar
endif
ship:
mkdir -p $(SHIP_DIR)/lib
mkdir -p $(SHIP_DIR)/include
mkdir -p $(SHIP_DIR)/bin
cp $(SHIP_LIBS) $(SHIP_DIR)/lib
cp $(SHIP_INCS) $(SHIP_DIR)/include
cp $(SHIP_BINS) $(SHIP_DIR)/bin
cd $(SHIP_DIR); \
zip -r $(JSREFJAR) bin lib include
ifdef BUILD_SHIP
cp $(SHIP_DIR)/$(JSREFJAR) $(BUILD_SHIP)
endif
CWD = $(shell pwd)
shipSource: $(SHIP_DIR)/jsref_src.lst .FORCE
mkdir -p $(SHIP_DIR)
cd $(MOZ_DEPTH)/.. ; \
zip $(CWD)/$(SHIP_DIR)/jsref_src.jar -@ < $(CWD)/$(SHIP_DIR)/jsref_src.lst
ifdef BUILD_SHIP
cp $(SHIP_DIR)/jsref_src.jar $(BUILD_SHIP)
endif
JSREFSRCDIRS := $(shell cat $(DEPTH)/SpiderMonkey.rsp)
$(SHIP_DIR)/jsref_src.lst: .FORCE
mkdir -p $(SHIP_DIR)
rm -f $@
touch $@
for d in $(JSREFSRCDIRS); do \
cd $(MOZ_DEPTH)/..; \
ls -1 -d $$d | grep -v CVS | grep -v \.OBJ >> $(CWD)/$@; \
cd $(CWD); \
done
.FORCE:

282
mozilla/js/src/jscpucfg.c Normal file
View File

@@ -0,0 +1,282 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* Generate CPU-specific bit-size and similar #defines.
*/
#include <stdio.h>
#ifdef sgi
#ifndef IRIX
# error "IRIX is not defined"
#endif
#endif
#ifdef __sun
#if defined(__svr4) || defined(__svr4__)
#ifndef SOLARIS
# error "SOLARIS is not defined"
#endif
#else
#ifndef SUNOS4
# error "SUNOS4 is not defined"
#endif
#endif
#endif
#ifdef __hpux
#ifndef HPUX
# error "HPUX is not defined"
#endif
#endif
#ifdef __osf__
#ifndef OSF1
# error "OSF1 is not defined"
#endif
#endif
#ifdef _IBMR2
#ifndef AIX
# error "AIX is not defined"
#endif
#endif
#ifdef bsdi
#ifndef BSDI
# error "BSDI is not defined"
#endif
#endif
#ifdef M_UNIX
#ifndef SCO
# error "SCO is not defined"
#endif
#endif
#if !defined(M_UNIX) && defined(_USLC_)
#ifndef UNIXWARE
# error "UNIXWARE is not defined"
#endif
#endif
#ifdef __MWERKS__
#define XP_MAC 1
#endif
/************************************************************************/
/* Generate cpucfg.h */
#ifdef XP_MAC
#include <Types.h>
#define INT64 UnsignedWide
#else
#ifdef XP_PC
#ifdef WIN32
#define INT64 _int64
#else
#define INT64 long
#endif
#else
#if defined(HPUX) || defined(SCO) || defined(UNIXWARE)
#define INT64 long
#else
#define INT64 long long
#endif
#endif
#endif
typedef void *prword;
struct align_short {
char c;
short a;
};
struct align_int {
char c;
int a;
};
struct align_long {
char c;
long a;
};
struct align_int64 {
char c;
INT64 a;
};
struct align_fakelonglong {
char c;
struct {
long hi, lo;
} a;
};
struct align_float {
char c;
float a;
};
struct align_double {
char c;
double a;
};
struct align_pointer {
char c;
void *a;
};
struct align_prword {
char c;
prword a;
};
#define ALIGN_OF(type) \
(((char*)&(((struct align_##type *)0)->a)) - ((char*)0))
int bpb;
static int Log2(int n)
{
int log2 = 0;
if (n & (n-1))
log2++;
if (n >> 16)
log2 += 16, n >>= 16;
if (n >> 8)
log2 += 8, n >>= 8;
if (n >> 4)
log2 += 4, n >>= 4;
if (n >> 2)
log2 += 2, n >>= 2;
if (n >> 1)
log2++;
return log2;
}
/* We assume that int's are 32 bits */
static void do64(void)
{
union {
long i;
char c[4];
} u;
u.i = 0x01020304;
if (u.c[0] == 0x01) {
printf("#undef IS_LITTLE_ENDIAN\n");
printf("#define IS_BIG_ENDIAN 1\n\n");
} else {
printf("#define IS_LITTLE_ENDIAN 1\n");
printf("#undef IS_BIG_ENDIAN\n\n");
}
}
static void do32(void)
{
union {
long i;
char c[4];
} u;
u.i = 0x01020304;
if (u.c[0] == 0x01) {
printf("#undef IS_LITTLE_ENDIAN\n");
printf("#define IS_BIG_ENDIAN 1\n\n");
} else {
printf("#define IS_LITTLE_ENDIAN 1\n");
printf("#undef IS_BIG_ENDIAN\n\n");
}
}
/*
* Conceivably this could actually be used, but there is lots of code out
* there with ands and shifts in it that assumes a byte is exactly 8 bits,
* so forget about porting THIS code to all those non 8 bit byte machines.
*/
static void BitsPerByte(void)
{
bpb = 8;
}
int main(int argc, char **argv)
{
BitsPerByte();
printf("#ifndef js_cpucfg___\n");
printf("#define js_cpucfg___\n\n");
printf("/* AUTOMATICALLY GENERATED - DO NOT EDIT */\n\n");
if (sizeof(long) == 8) {
do64();
} else {
do32();
}
printf("#define JS_BYTES_PER_BYTE %dL\n", sizeof(char));
printf("#define JS_BYTES_PER_SHORT %dL\n", sizeof(short));
printf("#define JS_BYTES_PER_INT %dL\n", sizeof(int));
printf("#define JS_BYTES_PER_INT64 %dL\n", 8);
printf("#define JS_BYTES_PER_LONG %dL\n", sizeof(long));
printf("#define JS_BYTES_PER_FLOAT %dL\n", sizeof(float));
printf("#define JS_BYTES_PER_DOUBLE %dL\n", sizeof(double));
printf("#define JS_BYTES_PER_WORD %dL\n", sizeof(prword));
printf("#define JS_BYTES_PER_DWORD %dL\n", 8);
printf("\n");
printf("#define JS_BITS_PER_BYTE %dL\n", bpb);
printf("#define JS_BITS_PER_SHORT %dL\n", bpb * sizeof(short));
printf("#define JS_BITS_PER_INT %dL\n", bpb * sizeof(int));
printf("#define JS_BITS_PER_INT64 %dL\n", bpb * 8);
printf("#define JS_BITS_PER_LONG %dL\n", bpb * sizeof(long));
printf("#define JS_BITS_PER_FLOAT %dL\n", bpb * sizeof(float));
printf("#define JS_BITS_PER_DOUBLE %dL\n", bpb * sizeof(double));
printf("#define JS_BITS_PER_WORD %dL\n", bpb * sizeof(prword));
printf("\n");
printf("#define JS_BITS_PER_BYTE_LOG2 %dL\n", Log2(bpb));
printf("#define JS_BITS_PER_SHORT_LOG2 %dL\n", Log2(bpb * sizeof(short)));
printf("#define JS_BITS_PER_INT_LOG2 %dL\n", Log2(bpb * sizeof(int)));
printf("#define JS_BITS_PER_INT64_LOG2 %dL\n", 6);
printf("#define JS_BITS_PER_LONG_LOG2 %dL\n", Log2(bpb * sizeof(long)));
printf("#define JS_BITS_PER_FLOAT_LOG2 %dL\n", Log2(bpb * sizeof(float)));
printf("#define JS_BITS_PER_DOUBLE_LOG2 %dL\n", Log2(bpb * sizeof(double)));
printf("#define JS_BITS_PER_WORD_LOG2 %dL\n", Log2(bpb * sizeof(prword)));
printf("\n");
printf("#define JS_ALIGN_OF_SHORT %dL\n", ALIGN_OF(short));
printf("#define JS_ALIGN_OF_INT %dL\n", ALIGN_OF(int));
printf("#define JS_ALIGN_OF_LONG %dL\n", ALIGN_OF(long));
if (sizeof(INT64) < 8) {
/* this machine doesn't actually support int64's */
printf("#define JS_ALIGN_OF_INT64 %dL\n", ALIGN_OF(fakelonglong));
} else {
printf("#define JS_ALIGN_OF_INT64 %dL\n", ALIGN_OF(int64));
}
printf("#define JS_ALIGN_OF_FLOAT %dL\n", ALIGN_OF(float));
printf("#define JS_ALIGN_OF_DOUBLE %dL\n", ALIGN_OF(double));
printf("#define JS_ALIGN_OF_POINTER %dL\n", ALIGN_OF(pointer));
printf("#define JS_ALIGN_OF_WORD %dL\n", ALIGN_OF(prword));
printf("\n");
printf("#define JS_BYTES_PER_WORD_LOG2 %dL\n", Log2(sizeof(prword)));
printf("#define JS_BYTES_PER_DWORD_LOG2 %dL\n", Log2(8));
printf("#define JS_WORDS_PER_DWORD_LOG2 %dL\n", Log2(8/sizeof(prword)));
printf("\n");
printf("#endif /* js_cpucfg___ */\n");
return 0;
}

175
mozilla/js/src/jscpucfg.h Normal file
View File

@@ -0,0 +1,175 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef js_cpucfg___
#define js_cpucfg___
#include "jsosdep.h"
#ifdef XP_MAC
#undef IS_LITTLE_ENDIAN
#define IS_BIG_ENDIAN 1
#define JS_BYTES_PER_BYTE 1L
#define JS_BYTES_PER_SHORT 2L
#define JS_BYTES_PER_INT 4L
#define JS_BYTES_PER_INT64 8L
#define JS_BYTES_PER_LONG 4L
#define JS_BYTES_PER_FLOAT 4L
#define JS_BYTES_PER_DOUBLE 8L
#define JS_BYTES_PER_WORD 4L
#define JS_BYTES_PER_DWORD 8L
#define JS_BITS_PER_BYTE 8L
#define JS_BITS_PER_SHORT 16L
#define JS_BITS_PER_INT 32L
#define JS_BITS_PER_INT64 64L
#define JS_BITS_PER_LONG 32L
#define JS_BITS_PER_FLOAT 32L
#define JS_BITS_PER_DOUBLE 64L
#define JS_BITS_PER_WORD 32L
#define JS_BITS_PER_BYTE_LOG2 3L
#define JS_BITS_PER_SHORT_LOG2 4L
#define JS_BITS_PER_INT_LOG2 5L
#define JS_BITS_PER_INT64_LOG2 6L
#define JS_BITS_PER_LONG_LOG2 5L
#define JS_BITS_PER_FLOAT_LOG2 5L
#define JS_BITS_PER_DOUBLE_LOG2 6L
#define JS_BITS_PER_WORD_LOG2 5L
#define JS_ALIGN_OF_SHORT 2L
#define JS_ALIGN_OF_INT 4L
#define JS_ALIGN_OF_LONG 4L
#define JS_ALIGN_OF_INT64 2L
#define JS_ALIGN_OF_FLOAT 4L
#define JS_ALIGN_OF_DOUBLE 4L
#define JS_ALIGN_OF_POINTER 4L
#define JS_ALIGN_OF_WORD 4L
#define JS_BYTES_PER_WORD_LOG2 2L
#define JS_BYTES_PER_DWORD_LOG2 3L
#define PR_WORDS_PER_DWORD_LOG2 1L
#elif defined(XP_PC)
#ifdef _WIN32
#define IS_LITTLE_ENDIAN 1
#undef IS_BIG_ENDIAN
#define JS_BYTES_PER_BYTE 1L
#define JS_BYTES_PER_SHORT 2L
#define JS_BYTES_PER_INT 4L
#define JS_BYTES_PER_INT64 8L
#define JS_BYTES_PER_LONG 4L
#define JS_BYTES_PER_FLOAT 4L
#define JS_BYTES_PER_DOUBLE 8L
#define JS_BYTES_PER_WORD 4L
#define JS_BYTES_PER_DWORD 8L
#define JS_BITS_PER_BYTE 8L
#define JS_BITS_PER_SHORT 16L
#define JS_BITS_PER_INT 32L
#define JS_BITS_PER_INT64 64L
#define JS_BITS_PER_LONG 32L
#define JS_BITS_PER_FLOAT 32L
#define JS_BITS_PER_DOUBLE 64L
#define JS_BITS_PER_WORD 32L
#define JS_BITS_PER_BYTE_LOG2 3L
#define JS_BITS_PER_SHORT_LOG2 4L
#define JS_BITS_PER_INT_LOG2 5L
#define JS_BITS_PER_INT64_LOG2 6L
#define JS_BITS_PER_LONG_LOG2 5L
#define JS_BITS_PER_FLOAT_LOG2 5L
#define JS_BITS_PER_DOUBLE_LOG2 6L
#define JS_BITS_PER_WORD_LOG2 5L
#define JS_ALIGN_OF_SHORT 2L
#define JS_ALIGN_OF_INT 4L
#define JS_ALIGN_OF_LONG 4L
#define JS_ALIGN_OF_INT64 8L
#define JS_ALIGN_OF_FLOAT 4L
#define JS_ALIGN_OF_DOUBLE 4L
#define JS_ALIGN_OF_POINTER 4L
#define JS_ALIGN_OF_WORD 4L
#define JS_BYTES_PER_WORD_LOG2 2L
#define JS_BYTES_PER_DWORD_LOG2 3L
#define PR_WORDS_PER_DWORD_LOG2 1L
#endif /* _WIN32 */
#if defined(_WINDOWS) && !defined(_WIN32) /* WIN16 */
#define IS_LITTLE_ENDIAN 1
#undef IS_BIG_ENDIAN
#define JS_BYTES_PER_BYTE 1L
#define JS_BYTES_PER_SHORT 2L
#define JS_BYTES_PER_INT 2L
#define JS_BYTES_PER_INT64 8L
#define JS_BYTES_PER_LONG 4L
#define JS_BYTES_PER_FLOAT 4L
#define JS_BYTES_PER_DOUBLE 8L
#define JS_BYTES_PER_WORD 4L
#define JS_BYTES_PER_DWORD 8L
#define JS_BITS_PER_BYTE 8L
#define JS_BITS_PER_SHORT 16L
#define JS_BITS_PER_INT 16L
#define JS_BITS_PER_INT64 64L
#define JS_BITS_PER_LONG 32L
#define JS_BITS_PER_FLOAT 32L
#define JS_BITS_PER_DOUBLE 64L
#define JS_BITS_PER_WORD 32L
#define JS_BITS_PER_BYTE_LOG2 3L
#define JS_BITS_PER_SHORT_LOG2 4L
#define JS_BITS_PER_INT_LOG2 4L
#define JS_BITS_PER_INT64_LOG2 6L
#define JS_BITS_PER_LONG_LOG2 5L
#define JS_BITS_PER_FLOAT_LOG2 5L
#define JS_BITS_PER_DOUBLE_LOG2 6L
#define JS_BITS_PER_WORD_LOG2 5L
#define JS_ALIGN_OF_SHORT 2L
#define JS_ALIGN_OF_INT 2L
#define JS_ALIGN_OF_LONG 2L
#define JS_ALIGN_OF_INT64 2L
#define JS_ALIGN_OF_FLOAT 2L
#define JS_ALIGN_OF_DOUBLE 2L
#define JS_ALIGN_OF_POINTER 2L
#define JS_ALIGN_OF_WORD 2L
#define JS_BYTES_PER_WORD_LOG2 2L
#define JS_BYTES_PER_DWORD_LOG2 3L
#define PR_WORDS_PER_DWORD_LOG2 1L
#endif /* defined(_WINDOWS) && !defined(_WIN32) */
#elif defined(XP_UNIX)
#error "This file is supposed to be auto-generated on UNIX platforms, but the"
#error "static version for Mac and Windows platforms is being used."
#error "Something's probably wrong with paths/headers/dependencies/Makefiles."
#else
#error "Must define one of XP_MAC, XP_PC or XP_UNIX"
#endif
#endif /* js_cpucfg___ */

2022
mozilla/js/src/jsdate.c Normal file

File diff suppressed because it is too large Load Diff

76
mozilla/js/src/jsdate.h Normal file
View File

@@ -0,0 +1,76 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsdate_h___
#define jsdate_h___
/*
* JS Date class interface.
*/
JS_BEGIN_EXTERN_C
extern JSObject *
js_InitDateClass(JSContext *cx, JSObject *obj);
/*
* These functions provide a C interface to the date/time object
*/
extern JS_FRIEND_API(JSObject*)
js_NewDateObject(JSContext* cx, int year, int mon, int mday,
int hour, int min, int sec);
extern JS_FRIEND_API(int)
js_DateGetYear(JSContext *cx, JSObject* obj);
extern JS_FRIEND_API(int)
js_DateGetMonth(JSContext *cx, JSObject* obj);
extern JS_FRIEND_API(int)
js_DateGetDate(JSContext *cx, JSObject* obj);
extern JS_FRIEND_API(int)
js_DateGetHours(JSContext *cx, JSObject* obj);
extern JS_FRIEND_API(int)
js_DateGetMinutes(JSContext *cx, JSObject* obj);
extern JS_FRIEND_API(int)
js_DateGetSeconds(JSContext *cx, JSObject* obj);
extern JS_FRIEND_API(void)
js_DateSetYear(JSContext *cx, JSObject *obj, int year);
extern JS_FRIEND_API(void)
js_DateSetMonth(JSContext *cx, JSObject *obj, int year);
extern JS_FRIEND_API(void)
js_DateSetDate(JSContext *cx, JSObject *obj, int date);
extern JS_FRIEND_API(void)
js_DateSetHours(JSContext *cx, JSObject *obj, int hours);
extern JS_FRIEND_API(void)
js_DateSetMinutes(JSContext *cx, JSObject *obj, int minutes);
extern JS_FRIEND_API(void)
js_DateSetSeconds(JSContext *cx, JSObject *obj, int seconds);
JS_END_EXTERN_C
#endif /* jsdate_h___ */

880
mozilla/js/src/jsdbgapi.c Normal file
View File

@@ -0,0 +1,880 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* JS debugging API.
*/
#include "jsstddef.h"
#include <string.h>
#include "jstypes.h"
#include "jsutil.h" /* Added by JSIFY */
#include "jsclist.h"
#include "jsapi.h"
#include "jscntxt.h"
#include "jsconfig.h"
#include "jsdbgapi.h"
#include "jsfun.h"
#include "jsgc.h"
#include "jsinterp.h"
#include "jslock.h"
#include "jsobj.h"
#include "jsopcode.h"
#include "jsscope.h"
#include "jsscript.h"
#include "jsstr.h"
typedef struct JSTrap {
JSCList links;
JSScript *script;
jsbytecode *pc;
JSOp op;
JSTrapHandler handler;
void *closure;
} JSTrap;
static JSTrap *
FindTrap(JSRuntime *rt, JSScript *script, jsbytecode *pc)
{
JSTrap *trap;
for (trap = (JSTrap *)rt->trapList.next;
trap != (JSTrap *)&rt->trapList;
trap = (JSTrap *)trap->links.next) {
if (trap->script == script && trap->pc == pc)
return trap;
}
return NULL;
}
void
js_PatchOpcode(JSContext *cx, JSScript *script, jsbytecode *pc, JSOp op)
{
JSTrap *trap;
trap = FindTrap(cx->runtime, script, pc);
if (trap)
trap->op = op;
else
*pc = (jsbytecode)op;
}
JS_PUBLIC_API(JSBool)
JS_SetTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
JSTrapHandler handler, void *closure)
{
JSRuntime *rt;
JSTrap *trap;
rt = cx->runtime;
trap = FindTrap(rt, script, pc);
if (trap) {
/* Restore opcode at pc so it can be saved again. */
*pc = (jsbytecode)trap->op;
} else {
trap = JS_malloc(cx, sizeof *trap);
if (!trap || !js_AddRoot(cx, &trap->closure, "trap->closure")) {
if (trap)
JS_free(cx, trap);
return JS_FALSE;
}
}
JS_APPEND_LINK(&trap->links, &rt->trapList);
trap->script = script;
trap->pc = pc;
trap->op = (JSOp)*pc;
trap->handler = handler;
trap->closure = closure;
*pc = JSOP_TRAP;
return JS_TRUE;
}
JS_PUBLIC_API(JSOp)
JS_GetTrapOpcode(JSContext *cx, JSScript *script, jsbytecode *pc)
{
JSTrap *trap;
trap = FindTrap(cx->runtime, script, pc);
if (!trap) {
JS_ASSERT(0); /* XXX can't happen */
return JSOP_LIMIT;
}
return trap->op;
}
static void
DestroyTrap(JSContext *cx, JSTrap *trap)
{
JS_REMOVE_LINK(&trap->links);
*trap->pc = (jsbytecode)trap->op;
js_RemoveRoot(cx, &trap->closure);
JS_free(cx, trap);
}
JS_PUBLIC_API(void)
JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
JSTrapHandler *handlerp, void **closurep)
{
JSTrap *trap;
trap = FindTrap(cx->runtime, script, pc);
if (handlerp)
*handlerp = trap ? trap->handler : NULL;
if (closurep)
*closurep = trap ? trap->closure : NULL;
if (trap)
DestroyTrap(cx, trap);
}
JS_PUBLIC_API(void)
JS_ClearScriptTraps(JSContext *cx, JSScript *script)
{
JSRuntime *rt;
JSTrap *trap, *next;
rt = cx->runtime;
for (trap = (JSTrap *)rt->trapList.next;
trap != (JSTrap *)&rt->trapList;
trap = next) {
next = (JSTrap *)trap->links.next;
if (trap->script == script)
DestroyTrap(cx, trap);
}
}
JS_PUBLIC_API(void)
JS_ClearAllTraps(JSContext *cx)
{
JSRuntime *rt;
JSTrap *trap, *next;
rt = cx->runtime;
for (trap = (JSTrap *)rt->trapList.next;
trap != (JSTrap *)&rt->trapList;
trap = next) {
next = (JSTrap *)trap->links.next;
DestroyTrap(cx, trap);
}
}
JS_PUBLIC_API(JSTrapStatus)
JS_HandleTrap(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval)
{
JSTrap *trap;
JSTrapStatus status;
jsint op;
trap = FindTrap(cx->runtime, script, pc);
if (!trap) {
JS_ASSERT(0); /* XXX can't happen */
return JSTRAP_ERROR;
}
/*
* It's important that we not use 'trap->' after calling the callback --
* the callback might remove the trap!
*/
op = (jsint)trap->op;
status = trap->handler(cx, script, pc, rval, trap->closure);
if (status == JSTRAP_CONTINUE) {
/* By convention, return the true op to the interpreter in rval. */
*rval = INT_TO_JSVAL(op);
}
return status;
}
JS_PUBLIC_API(JSBool)
JS_SetInterrupt(JSRuntime *rt, JSTrapHandler handler, void *closure)
{
rt->interruptHandler = handler;
rt->interruptHandlerData = closure;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_ClearInterrupt(JSRuntime *rt, JSTrapHandler *handlerp, void **closurep)
{
if (handlerp)
*handlerp = (JSTrapHandler)rt->interruptHandler;
if (closurep)
*closurep = rt->interruptHandlerData;
rt->interruptHandler = 0;
rt->interruptHandlerData = 0;
return JS_TRUE;
}
typedef struct JSWatchPoint {
JSCList links;
JSObject *object; /* weak link, see js_FinalizeObject */
jsval userid;
JSScopeProperty *sprop;
JSPropertyOp setter;
JSWatchPointHandler handler;
void *closure;
jsrefcount nrefs;
} JSWatchPoint;
#define HoldWatchPoint(wp) ((wp)->nrefs++)
static void
DropWatchPoint(JSContext *cx, JSWatchPoint *wp)
{
if (--wp->nrefs != 0)
return;
wp->sprop->setter = wp->setter;
JS_LOCK_OBJ_VOID(cx, wp->object,
js_DropScopeProperty(cx, (JSScope *)wp->object->map,
wp->sprop));
JS_REMOVE_LINK(&wp->links);
js_RemoveRoot(cx, &wp->closure);
JS_free(cx, wp);
}
static JSWatchPoint *
FindWatchPoint(JSRuntime *rt, JSObject *obj, jsval userid)
{
JSWatchPoint *wp;
for (wp = (JSWatchPoint *)rt->watchPointList.next;
wp != (JSWatchPoint *)&rt->watchPointList;
wp = (JSWatchPoint *)wp->links.next) {
if (wp->object == obj && wp->userid == userid)
return wp;
}
return NULL;
}
JSScopeProperty *
js_FindWatchPoint(JSRuntime *rt, JSObject *obj, jsval userid)
{
JSWatchPoint *wp;
wp = FindWatchPoint(rt, obj, userid);
if (!wp)
return NULL;
return wp->sprop;
}
JSBool JS_DLL_CALLBACK
js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
JSRuntime *rt;
JSWatchPoint *wp;
JSScopeProperty *sprop;
JSSymbol *sym;
jsval userid, value;
jsid symid;
JSScope *scope;
JSAtom *atom;
JSBool ok;
rt = cx->runtime;
for (wp = (JSWatchPoint *)rt->watchPointList.next;
wp != (JSWatchPoint *)&rt->watchPointList;
wp = (JSWatchPoint *)wp->links.next) {
sprop = wp->sprop;
if (wp->object == obj && sprop->id == id) {
JS_LOCK_OBJ(cx, obj);
sym = sprop->symbols;
if (!sym) {
userid = wp->userid;
atom = NULL;
if (JSVAL_IS_INT(userid)) {
symid = (jsid)userid;
} else {
atom = js_ValueToStringAtom(cx, userid);
if (!atom) {
JS_UNLOCK_OBJ(cx, obj);
return JS_FALSE;
}
symid = (jsid)atom;
}
scope = (JSScope *) obj->map;
JS_ASSERT(scope->props);
ok = LOCKED_OBJ_GET_CLASS(obj)->addProperty(cx, obj, sprop->id,
&value);
if (!ok) {
JS_UNLOCK_OBJ(cx, obj);
return JS_FALSE;
}
ok = (scope->ops->add(cx, scope, symid, sprop) != NULL);
if (!ok) {
JS_UNLOCK_OBJ(cx, obj);
return JS_FALSE;
}
sym = sprop->symbols;
}
JS_UNLOCK_OBJ(cx, obj);
HoldWatchPoint(wp);
ok = wp->handler(cx, obj, js_IdToValue(sym_id(sym)),
OBJ_GET_SLOT(cx, obj, wp->sprop->slot), vp,
wp->closure);
if (ok)
ok = wp->setter(cx, obj, id, vp);
DropWatchPoint(cx, wp);
return ok;
}
}
JS_ASSERT(0); /* XXX can't happen */
return JS_FALSE;
}
JS_PUBLIC_API(JSBool)
JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval id,
JSWatchPointHandler handler, void *closure)
{
JSAtom *atom;
jsid symid;
JSObject *pobj;
JSScopeProperty *sprop;
JSRuntime *rt;
JSWatchPoint *wp;
if (!OBJ_IS_NATIVE(obj)) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_WATCH,
OBJ_GET_CLASS(cx, obj)->name);
return JS_FALSE;
}
if (JSVAL_IS_INT(id)) {
symid = (jsid)id;
atom = NULL;
} else {
atom = js_ValueToStringAtom(cx, id);
if (!atom)
return JS_FALSE;
symid = (jsid)atom;
}
if (!js_LookupProperty(cx, obj, symid, &pobj, (JSProperty **)&sprop))
return JS_FALSE;
rt = cx->runtime;
if (!sprop) {
/* Check for a deleted symbol watchpoint, which holds its property. */
sprop = js_FindWatchPoint(rt, obj, id);
if (sprop) {
#ifdef JS_THREADSAFE
/* Emulate js_LookupProperty if thread-safe. */
JS_LOCK_OBJ(cx, obj);
sprop->nrefs++;
#endif
} else {
/* Make a new property in obj so we can watch for the first set. */
if (!js_DefineProperty(cx, obj, symid, JSVAL_VOID, NULL, NULL, 0,
(JSProperty **)&sprop)) {
sprop = NULL;
}
}
} else if (pobj != obj) {
/* Clone the prototype property so we can watch the right object. */
jsval value;
JSPropertyOp getter, setter;
uintN attrs;
if (OBJ_IS_NATIVE(pobj)) {
value = LOCKED_OBJ_GET_SLOT(pobj, sprop->slot);
} else {
if (!OBJ_GET_PROPERTY(cx, pobj, id, &value)) {
OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
return JS_FALSE;
}
}
getter = sprop->getter;
setter = sprop->setter;
attrs = sprop->attrs;
OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
if (!js_DefineProperty(cx, obj, symid, value, getter, setter, attrs,
(JSProperty **)&sprop)) {
sprop = NULL;
}
}
if (!sprop)
return JS_FALSE;
wp = FindWatchPoint(rt, obj, id);
if (!wp) {
wp = JS_malloc(cx, sizeof *wp);
if (!wp)
return JS_FALSE;
if (!js_AddRoot(cx, &wp->closure, "wp->closure")) {
JS_free(cx, wp);
return JS_FALSE;
}
JS_APPEND_LINK(&wp->links, &rt->watchPointList);
wp->object = obj;
wp->userid = id;
wp->sprop = js_HoldScopeProperty(cx, (JSScope *)obj->map, sprop);
wp->setter = sprop->setter;
sprop->setter = js_watch_set;
wp->nrefs = 1;
}
wp->handler = handler;
wp->closure = closure;
OBJ_DROP_PROPERTY(cx, obj, (JSProperty *)sprop);
return JS_TRUE;
}
JS_PUBLIC_API(void)
JS_ClearWatchPoint(JSContext *cx, JSObject *obj, jsval id,
JSWatchPointHandler *handlerp, void **closurep)
{
JSRuntime *rt;
JSWatchPoint *wp;
rt = cx->runtime;
for (wp = (JSWatchPoint *)rt->watchPointList.next;
wp != (JSWatchPoint *)&rt->watchPointList;
wp = (JSWatchPoint *)wp->links.next) {
if (wp->object == obj && wp->userid == id) {
if (handlerp)
*handlerp = wp->handler;
if (closurep)
*closurep = wp->closure;
DropWatchPoint(cx, wp);
return;
}
}
if (handlerp)
*handlerp = NULL;
if (closurep)
*closurep = NULL;
}
JS_PUBLIC_API(void)
JS_ClearWatchPointsForObject(JSContext *cx, JSObject *obj)
{
JSRuntime *rt;
JSWatchPoint *wp, *next;
rt = cx->runtime;
for (wp = (JSWatchPoint *)rt->watchPointList.next;
wp != (JSWatchPoint *)&rt->watchPointList;
wp = next) {
next = (JSWatchPoint *)wp->links.next;
if (wp->object == obj)
DropWatchPoint(cx, wp);
}
}
JS_PUBLIC_API(void)
JS_ClearAllWatchPoints(JSContext *cx)
{
JSRuntime *rt;
JSWatchPoint *wp, *next;
rt = cx->runtime;
for (wp = (JSWatchPoint *)rt->watchPointList.next;
wp != (JSWatchPoint *)&rt->watchPointList;
wp = next) {
next = (JSWatchPoint *)wp->links.next;
DropWatchPoint(cx, wp);
}
}
JS_PUBLIC_API(uintN)
JS_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
{
return js_PCToLineNumber(script, pc);
}
JS_PUBLIC_API(jsbytecode *)
JS_LineNumberToPC(JSContext *cx, JSScript *script, uintN lineno)
{
return js_LineNumberToPC(script, lineno);
}
JS_PUBLIC_API(JSScript *)
JS_GetFunctionScript(JSContext *cx, JSFunction *fun)
{
return fun->script;
}
JS_PUBLIC_API(JSPrincipals *)
JS_GetScriptPrincipals(JSContext *cx, JSScript *script)
{
return script->principals;
}
/*
* Stack Frame Iterator
*/
JS_PUBLIC_API(JSStackFrame *)
JS_FrameIterator(JSContext *cx, JSStackFrame **iteratorp)
{
*iteratorp = (*iteratorp == NULL) ? cx->fp : (*iteratorp)->down;
return *iteratorp;
}
JS_PUBLIC_API(JSScript *)
JS_GetFrameScript(JSContext *cx, JSStackFrame *fp)
{
return fp->script;
}
JS_PUBLIC_API(jsbytecode *)
JS_GetFramePC(JSContext *cx, JSStackFrame *fp)
{
return fp->pc;
}
JS_PUBLIC_API(void *)
JS_GetFrameAnnotation(JSContext *cx, JSStackFrame *fp)
{
if (fp->annotation) {
JSPrincipals *principals = fp->script
? fp->script->principals
: NULL;
if (principals == NULL)
return NULL;
if (principals->globalPrivilegesEnabled(cx, principals)) {
/*
* Only give out an annotation if privileges have not
* been revoked globally.
*/
return fp->annotation;
}
}
return NULL;
}
JS_PUBLIC_API(void)
JS_SetFrameAnnotation(JSContext *cx, JSStackFrame *fp, void *annotation)
{
fp->annotation = annotation;
}
JS_PUBLIC_API(void *)
JS_GetFramePrincipalArray(JSContext *cx, JSStackFrame *fp)
{
JSPrincipals *principals = fp->script
? fp->script->principals
: NULL;
return principals
? principals->getPrincipalArray(cx, principals)
: NULL;
}
JS_PUBLIC_API(JSBool)
JS_IsNativeFrame(JSContext *cx, JSStackFrame *fp)
{
return fp->fun && fp->fun->call;
}
/* this is deprecated, use JS_GetFrameScopeChain instead */
JS_PUBLIC_API(JSObject *)
JS_GetFrameObject(JSContext *cx, JSStackFrame *fp)
{
return fp->scopeChain;
}
JS_PUBLIC_API(JSObject *)
JS_GetFrameScopeChain(JSContext *cx, JSStackFrame *fp)
{
/* Force creation of argument and call objects if not yet created */
JS_GetFrameCallObject(cx, fp);
return fp->scopeChain;
}
JS_PUBLIC_API(JSObject *)
JS_GetFrameCallObject(JSContext *cx, JSStackFrame *fp)
{
if (! fp->fun)
return NULL;
/* Force creation of argument object if not yet created */
js_GetArgsObject(cx, fp);
#if JS_HAS_CALL_OBJECT
return js_GetCallObject(cx, fp, NULL, NULL);
#else
return NULL;
#endif /* JS_HAS_CALL_OBJECT */
}
JS_PUBLIC_API(JSObject *)
JS_GetFrameThis(JSContext *cx, JSStackFrame *fp)
{
return fp->thisp;
}
JS_PUBLIC_API(JSFunction *)
JS_GetFrameFunction(JSContext *cx, JSStackFrame *fp)
{
return fp->fun;
}
JS_PUBLIC_API(JSBool)
JS_IsContructorFrame(JSContext *cx, JSStackFrame *fp)
{
return fp->constructing;
}
JS_PUBLIC_API(JSBool)
JS_IsDebuggerFrame(JSContext *cx, JSStackFrame *fp)
{
return fp->debugging;
}
JS_PUBLIC_API(jsval)
JS_GetFrameReturnValue(JSContext *cx, JSStackFrame *fp)
{
return fp->rval;
}
JS_PUBLIC_API(void)
JS_SetFrameReturnValue(JSContext *cx, JSStackFrame *fp, jsval rval)
{
fp->rval = rval;
}
/************************************************************************/
JS_PUBLIC_API(const char *)
JS_GetScriptFilename(JSContext *cx, JSScript *script)
{
return script->filename;
}
JS_PUBLIC_API(uintN)
JS_GetScriptBaseLineNumber(JSContext *cx, JSScript *script)
{
return script->lineno;
}
JS_PUBLIC_API(uintN)
JS_GetScriptLineExtent(JSContext *cx, JSScript *script)
{
return js_GetScriptLineExtent(script);
}
/***************************************************************************/
JS_PUBLIC_API(void)
JS_SetNewScriptHook(JSRuntime *rt, JSNewScriptHook hook, void *callerdata)
{
rt->newScriptHook = hook;
rt->newScriptHookData = callerdata;
}
JS_PUBLIC_API(void)
JS_SetDestroyScriptHook(JSRuntime *rt, JSDestroyScriptHook hook,
void *callerdata)
{
rt->destroyScriptHook = hook;
rt->destroyScriptHookData = callerdata;
}
/***************************************************************************/
JS_PUBLIC_API(JSBool)
JS_EvaluateInStackFrame(JSContext *cx, JSStackFrame *fp,
const char *bytes, uintN length,
const char *filename, uintN lineno,
jsval *rval)
{
JSScript *script;
JSBool ok;
script = JS_CompileScriptForPrincipals(cx, fp->scopeChain,
fp->script ? fp->script->principals
: NULL,
bytes, length, filename, lineno);
if (!script)
return JS_FALSE;
ok = js_Execute(cx, fp->scopeChain, script, fp->fun, fp, JS_TRUE, rval);
js_DestroyScript(cx, script);
return ok;
}
/************************************************************************/
JS_PUBLIC_API(JSScopeProperty *)
JS_PropertyIterator(JSObject *obj, JSScopeProperty **iteratorp)
{
JSScopeProperty *sprop;
JSScope *scope;
sprop = *iteratorp;
scope = (JSScope *) obj->map;
sprop = (sprop == NULL) ? scope->props : sprop->next;
*iteratorp = sprop;
return sprop;
}
JS_PUBLIC_API(JSBool)
JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop,
JSPropertyDesc *pd)
{
JSSymbol *sym;
sym = sprop->symbols;
pd->id = sym ? js_IdToValue(sym_id(sym)) : JSVAL_VOID;
if (!sym || !js_GetProperty(cx, obj, sym_id(sym), &pd->value))
pd->value = OBJ_GET_SLOT(cx, obj, sprop->slot);
pd->flags = ((sprop->attrs & JSPROP_ENUMERATE) ? JSPD_ENUMERATE : 0)
| ((sprop->attrs & JSPROP_READONLY) ? JSPD_READONLY : 0)
| ((sprop->attrs & JSPROP_PERMANENT) ? JSPD_PERMANENT : 0)
#if JS_HAS_CALL_OBJECT
| ((sprop->getter == js_GetCallVariable) ? JSPD_VARIABLE : 0)
#endif /* JS_HAS_CALL_OBJECT */
| ((sprop->getter == js_GetArgument) ? JSPD_ARGUMENT : 0)
| ((sprop->getter == js_GetLocalVariable) ? JSPD_VARIABLE : 0);
#if JS_HAS_CALL_OBJECT
/* for Call Object 'real' getter isn't passed in to us */
if (OBJ_GET_CLASS(cx, obj) == &js_CallClass &&
OBJ_GET_CLASS(cx, obj)->getProperty == sprop->getter)
pd->flags |= JSPD_ARGUMENT;
#endif /* JS_HAS_CALL_OBJECT */
pd->spare = 0;
pd->slot = (pd->flags & (JSPD_ARGUMENT | JSPD_VARIABLE))
? JSVAL_TO_INT(sprop->id)
: 0;
if (!sym || !sym->next || (pd->flags & (JSPD_ARGUMENT | JSPD_VARIABLE))) {
pd->alias = JSVAL_VOID;
} else {
pd->alias = js_IdToValue(sym_id(sym->next));
pd->flags |= JSPD_ALIAS;
}
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda)
{
JSScope *scope;
uint32 i, n;
JSPropertyDesc *pd;
JSScopeProperty *sprop;
jsval state;
jsid num_prop;
if (!OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &state, &num_prop))
return JS_FALSE;
scope = (JSScope *)obj->map;
/* have no props, or object's scope has not mutated from that of proto */
if (!scope->props ||
(OBJ_GET_PROTO(cx,obj) &&
scope == (JSScope *)(OBJ_GET_PROTO(cx,obj)->map))) {
pda->length = 0;
pda->array = NULL;
return JS_TRUE;
}
n = scope->map.freeslot;
pd = JS_malloc(cx, (size_t)n * sizeof(JSPropertyDesc));
if (!pd)
return JS_FALSE;
i = 0;
for (sprop = scope->props; sprop; sprop = sprop->next) {
if (!js_AddRoot(cx, &pd[i].id, NULL))
goto bad;
if (!js_AddRoot(cx, &pd[i].value, NULL))
goto bad;
JS_GetPropertyDesc(cx, obj, sprop, &pd[i]);
if ((pd[i].flags & JSPD_ALIAS) && !js_AddRoot(cx, &pd[i].alias, NULL))
goto bad;
if (++i == n)
break;
}
pda->length = i;
pda->array = pd;
return JS_TRUE;
bad:
pda->length = i + 1;
pda->array = pd;
JS_PutPropertyDescArray(cx, pda);
return JS_FALSE;
}
JS_PUBLIC_API(void)
JS_PutPropertyDescArray(JSContext *cx, JSPropertyDescArray *pda)
{
JSPropertyDesc *pd;
uint32 i;
pd = pda->array;
for (i = 0; i < pda->length; i++) {
js_RemoveRoot(cx, &pd[i].id);
js_RemoveRoot(cx, &pd[i].value);
if (pd[i].flags & JSPD_ALIAS)
js_RemoveRoot(cx, &pd[i].alias);
}
JS_free(cx, pd);
}
/************************************************************************/
JS_PUBLIC_API(JSBool)
JS_SetDebuggerHandler(JSRuntime *rt, JSTrapHandler handler, void *closure)
{
rt->debuggerHandler = handler;
rt->debuggerHandlerData = closure;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SetSourceHandler(JSRuntime *rt, JSSourceHandler handler, void *closure)
{
rt->sourceHandler = handler;
rt->sourceHandlerData = closure;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SetExecuteHook(JSRuntime *rt, JSInterpreterHook hook, void *closure)
{
rt->executeHook = hook;
rt->executeHookData = closure;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SetCallHook(JSRuntime *rt, JSInterpreterHook hook, void *closure)
{
rt->callHook = hook;
rt->callHookData = closure;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SetObjectHook(JSRuntime *rt, JSObjectHook hook, void *closure)
{
rt->objectHook = hook;
rt->objectHookData = closure;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SetThrowHook(JSRuntime *rt, JSTrapHandler hook, void *closure)
{
rt->throwHook = hook;
rt->throwHookData = closure;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure)
{
rt->debugErrorHook = hook;
rt->debugErrorHookData = closure;
return JS_TRUE;
}

254
mozilla/js/src/jsdbgapi.h Normal file
View File

@@ -0,0 +1,254 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsdbgapi_h___
#define jsdbgapi_h___
/*
* JS debugger API.
*/
#include "jsapi.h"
#include "jsopcode.h"
#include "jsprvtd.h"
JS_BEGIN_EXTERN_C
extern void
js_PatchOpcode(JSContext *cx, JSScript *script, jsbytecode *pc, JSOp op);
extern JS_PUBLIC_API(JSBool)
JS_SetTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
JSTrapHandler handler, void *closure);
extern JS_PUBLIC_API(JSOp)
JS_GetTrapOpcode(JSContext *cx, JSScript *script, jsbytecode *pc);
extern JS_PUBLIC_API(void)
JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
JSTrapHandler *handlerp, void **closurep);
extern JS_PUBLIC_API(void)
JS_ClearScriptTraps(JSContext *cx, JSScript *script);
extern JS_PUBLIC_API(void)
JS_ClearAllTraps(JSContext *cx);
extern JS_PUBLIC_API(JSTrapStatus)
JS_HandleTrap(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval);
extern JS_PUBLIC_API(JSBool)
JS_SetInterrupt(JSRuntime *rt, JSTrapHandler handler, void *closure);
extern JS_PUBLIC_API(JSBool)
JS_ClearInterrupt(JSRuntime *rt, JSTrapHandler *handlerp, void **closurep);
/************************************************************************/
extern JS_PUBLIC_API(JSBool)
JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval id,
JSWatchPointHandler handler, void *closure);
extern JS_PUBLIC_API(void)
JS_ClearWatchPoint(JSContext *cx, JSObject *obj, jsval id,
JSWatchPointHandler *handlerp, void **closurep);
extern JS_PUBLIC_API(void)
JS_ClearWatchPointsForObject(JSContext *cx, JSObject *obj);
extern JS_PUBLIC_API(void)
JS_ClearAllWatchPoints(JSContext *cx);
#ifdef JS_HAS_OBJ_WATCHPOINT
/*
* Hide these non-API function prototypes by testing whether the internal
* header file "jsconfig.h" has been included.
*/
extern JSScopeProperty *
js_FindWatchPoint(JSRuntime *rt, JSObject *obj, jsval userid);
extern JSBool JS_DLL_CALLBACK
js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
#endif
/************************************************************************/
extern JS_PUBLIC_API(uintN)
JS_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc);
extern JS_PUBLIC_API(jsbytecode *)
JS_LineNumberToPC(JSContext *cx, JSScript *script, uintN lineno);
extern JS_PUBLIC_API(JSScript *)
JS_GetFunctionScript(JSContext *cx, JSFunction *fun);
extern JS_PUBLIC_API(JSPrincipals *)
JS_GetScriptPrincipals(JSContext *cx, JSScript *script);
/*
* Stack Frame Iterator
*
* Used to iterate through the JS stack frames to extract
* information from the frames.
*/
extern JS_PUBLIC_API(JSStackFrame *)
JS_FrameIterator(JSContext *cx, JSStackFrame **iteratorp);
extern JS_PUBLIC_API(JSScript *)
JS_GetFrameScript(JSContext *cx, JSStackFrame *fp);
extern JS_PUBLIC_API(jsbytecode *)
JS_GetFramePC(JSContext *cx, JSStackFrame *fp);
extern JS_PUBLIC_API(JSBool)
JS_IsNativeFrame(JSContext *cx, JSStackFrame *fp);
extern JS_PUBLIC_API(void *)
JS_GetFrameAnnotation(JSContext *cx, JSStackFrame *fp);
extern JS_PUBLIC_API(void)
JS_SetFrameAnnotation(JSContext *cx, JSStackFrame *fp, void *annotation);
extern JS_PUBLIC_API(void *)
JS_GetFramePrincipalArray(JSContext *cx, JSStackFrame *fp);
/* this is deprecated, use JS_GetFrameScopeChain instead */
extern JS_PUBLIC_API(JSObject *)
JS_GetFrameObject(JSContext *cx, JSStackFrame *fp);
extern JS_PUBLIC_API(JSObject *)
JS_GetFrameScopeChain(JSContext *cx, JSStackFrame *fp);
extern JS_PUBLIC_API(JSObject *)
JS_GetFrameCallObject(JSContext *cx, JSStackFrame *fp);
extern JS_PUBLIC_API(JSObject *)
JS_GetFrameThis(JSContext *cx, JSStackFrame *fp);
extern JS_PUBLIC_API(JSFunction *)
JS_GetFrameFunction(JSContext *cx, JSStackFrame *fp);
extern JS_PUBLIC_API(JSBool)
JS_IsContructorFrame(JSContext *cx, JSStackFrame *fp);
extern JS_PUBLIC_API(JSBool)
JS_IsDebuggerFrame(JSContext *cx, JSStackFrame *fp);
extern JS_PUBLIC_API(jsval)
JS_GetFrameReturnValue(JSContext *cx, JSStackFrame *fp);
extern JS_PUBLIC_API(void)
JS_SetFrameReturnValue(JSContext *cx, JSStackFrame *fp, jsval rval);
/************************************************************************/
extern JS_PUBLIC_API(const char *)
JS_GetScriptFilename(JSContext *cx, JSScript *script);
extern JS_PUBLIC_API(uintN)
JS_GetScriptBaseLineNumber(JSContext *cx, JSScript *script);
extern JS_PUBLIC_API(uintN)
JS_GetScriptLineExtent(JSContext *cx, JSScript *script);
/************************************************************************/
/*
* Hook setters for script creation and destruction, see jsprvtd.h for the
* typedefs. These macros provide binary compatibility and newer, shorter
* synonyms.
*/
#define JS_SetNewScriptHook JS_SetNewScriptHookProc
#define JS_SetDestroyScriptHook JS_SetDestroyScriptHookProc
extern JS_PUBLIC_API(void)
JS_SetNewScriptHook(JSRuntime *rt, JSNewScriptHook hook, void *callerdata);
extern JS_PUBLIC_API(void)
JS_SetDestroyScriptHook(JSRuntime *rt, JSDestroyScriptHook hook,
void *callerdata);
/************************************************************************/
extern JS_PUBLIC_API(JSBool)
JS_EvaluateInStackFrame(JSContext *cx, JSStackFrame *fp,
const char *bytes, uintN length,
const char *filename, uintN lineno,
jsval *rval);
/************************************************************************/
typedef struct JSPropertyDesc {
jsval id; /* primary id, a string or int */
jsval value; /* property value */
uint8 flags; /* flags, see below */
uint8 spare; /* unused */
uint16 slot; /* argument/variable slot */
jsval alias; /* alias id if JSPD_ALIAS flag */
} JSPropertyDesc;
#define JSPD_ENUMERATE 0x01 /* visible to for/in loop */
#define JSPD_READONLY 0x02 /* assignment is error */
#define JSPD_PERMANENT 0x04 /* property cannot be deleted */
#define JSPD_ALIAS 0x08 /* property has an alias id */
#define JSPD_ARGUMENT 0x10 /* argument to function */
#define JSPD_VARIABLE 0x20 /* local variable in function */
typedef struct JSPropertyDescArray {
uint32 length; /* number of elements in array */
JSPropertyDesc *array; /* alloc'd by Get, freed by Put */
} JSPropertyDescArray;
extern JS_PUBLIC_API(JSScopeProperty *)
JS_PropertyIterator(JSObject *obj, JSScopeProperty **iteratorp);
extern JS_PUBLIC_API(JSBool)
JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop,
JSPropertyDesc *pd);
extern JS_PUBLIC_API(JSBool)
JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda);
extern JS_PUBLIC_API(void)
JS_PutPropertyDescArray(JSContext *cx, JSPropertyDescArray *pda);
/************************************************************************/
extern JS_PUBLIC_API(JSBool)
JS_SetDebuggerHandler(JSRuntime *rt, JSTrapHandler handler, void *closure);
extern JS_PUBLIC_API(JSBool)
JS_SetSourceHandler(JSRuntime *rt, JSSourceHandler handler, void *closure);
extern JS_PUBLIC_API(JSBool)
JS_SetExecuteHook(JSRuntime *rt, JSInterpreterHook hook, void *closure);
extern JS_PUBLIC_API(JSBool)
JS_SetCallHook(JSRuntime *rt, JSInterpreterHook hook, void *closure);
extern JS_PUBLIC_API(JSBool)
JS_SetObjectHook(JSRuntime *rt, JSObjectHook hook, void *closure);
extern JS_PUBLIC_API(JSBool)
JS_SetThrowHook(JSRuntime *rt, JSTrapHandler hook, void *closure);
extern JS_PUBLIC_API(JSBool)
JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure);
JS_END_EXTERN_C
#endif /* jsdbgapi_h___ */

2611
mozilla/js/src/jsdtoa.c Normal file

File diff suppressed because it is too large Load Diff

54
mozilla/js/src/jsdtoa.h Normal file
View File

@@ -0,0 +1,54 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsdtoa_h___
#define jsdtoa_h___
/*
* Public interface to portable double-precision floating point to string
* and back conversion package.
*/
#include "jscompat.h"
JS_BEGIN_EXTERN_C
/*
* JS_strtod() returns as a double-precision floating-point number
* the value represented by the character string pointed to by
* s00. The string is scanned up to the first unrecognized
* character.
* If the value of se is not (char **)NULL, a pointer to
* the character terminating the scan is returned in the location pointed
* to by se. If no number can be formed, se is set to s00r, and
* zero is returned.
*/
JS_FRIEND_API(double)
JS_strtod(const char *s00, char **se);
/*
* JS_cnvtf()
* conversion routines for floating point
* prcsn - number of digits of precision to generate floating
* point value.
*/
JS_FRIEND_API(void)
JS_cnvtf(char *buf, intN bufsz, intN prcsn, double dval);
JS_END_EXTERN_C
#endif /* jsdtoa_h___ */

2539
mozilla/js/src/jsemit.c Normal file

File diff suppressed because it is too large Load Diff

369
mozilla/js/src/jsemit.h Normal file
View File

@@ -0,0 +1,369 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsemit_h___
#define jsemit_h___
/*
* JS bytecode generation.
*/
#include "jsstddef.h"
#include "jstypes.h"
#include "jsatom.h"
#include "jsopcode.h"
#include "jsprvtd.h"
#include "jspubtd.h"
JS_BEGIN_EXTERN_C
typedef enum JSStmtType {
STMT_BLOCK = 0, /* compound statement: { s1[;... sN] } */
STMT_LABEL = 1, /* labeled statement: l: s */
STMT_IF = 2, /* if (then) statement */
STMT_ELSE = 3, /* else statement */
STMT_SWITCH = 4, /* switch statement */
STMT_WITH = 5, /* with statement */
STMT_TRY = 6, /* try statement */
STMT_CATCH = 7, /* catch block */
STMT_FINALLY = 8, /* finally statement */
STMT_DO_LOOP = 9, /* do/while loop statement */
STMT_FOR_LOOP = 10, /* for loop statement */
STMT_FOR_IN_LOOP = 11, /* for/in loop statement */
STMT_WHILE_LOOP = 12 /* while loop statement */
} JSStmtType;
#define STMT_IS_LOOP(stmt) ((stmt)->type >= STMT_DO_LOOP)
typedef struct JSStmtInfo JSStmtInfo;
struct JSStmtInfo {
JSStmtType type; /* statement type */
ptrdiff_t top; /* offset of loop top from cg base */
ptrdiff_t update; /* loop update offset (top if none) */
ptrdiff_t breaks; /* offset of last break in loop */
ptrdiff_t continues; /* offset of last continue in loop */
JSAtom *label; /* label name if type is STMT_LABEL */
JSStmtInfo *down; /* info for enclosing statement */
};
#define SET_STATEMENT_TOP(stmt, top) \
((stmt)->top = (stmt)->update = (top), (stmt)->breaks = (stmt)->continues = (-1))
struct JSTreeContext { /* tree context for semantic checks */
uint32 flags; /* statement state flags, see below */
uint32 tryCount; /* total count of try statements parsed */
JSStmtInfo *topStmt; /* top of statement info stack */
};
#define TCF_IN_FUNCTION 0x01 /* parsing inside function body */
#define TCF_RETURN_EXPR 0x02 /* function has 'return expr;' */
#define TCF_RETURN_VOID 0x04 /* function has 'return;' */
#define TCF_IN_FOR_INIT 0x08 /* parsing init expr of for; exclude 'in' */
#define TREE_CONTEXT_INIT(tc) \
((tc)->flags = 0, (tc)->tryCount = 0, (tc)->topStmt = NULL)
struct JSCodeGenerator {
void *codeMark; /* low watermark in cx->codePool */
void *tempMark; /* low watermark in cx->tempPool */
jsbytecode *base; /* base of JS bytecode vector */
jsbytecode *limit; /* one byte beyond end of bytecode */
jsbytecode *next; /* pointer to next free bytecode */
const char *filename; /* null or weak link to source filename */
uintN firstLine; /* first line, for js_NewScriptFromCG */
uintN currentLine; /* line number for tree-based srcnote gen */
JSPrincipals *principals; /* principals for constant folding eval */
JSTreeContext treeContext; /* for break/continue code generation */
JSAtomList atomList; /* literals indexed for mapping */
intN stackDepth; /* current stack depth in basic block */
uintN maxStackDepth; /* maximum stack depth so far */
jssrcnote *notes; /* source notes, see below */
uintN noteCount; /* number of source notes so far */
ptrdiff_t lastNoteOffset; /* code offset for last source note */
JSTryNote *tryBase; /* first exception handling note */
JSTryNote *tryNext; /* next available note */
size_t tryNoteSpace; /* # of bytes allocated at tryBase */
};
#define CG_CODE(cg,offset) ((cg)->base + (offset))
#define CG_OFFSET(cg) PTRDIFF((cg)->next, (cg)->base, jsbytecode)
/*
* Initialize cg to allocate bytecode space from cx->codePool, and srcnote
* space from cx->tempPool. Return true on success. Report an error and
* return false if the initial code segment can't be allocated.
*/
extern JS_FRIEND_API(JSBool)
js_InitCodeGenerator(JSContext *cx, JSCodeGenerator *cg,
const char *filename, uintN lineno,
JSPrincipals *principals);
/*
* Release cx->codePool and cx->tempPool to marks set by js_InitCodeGenerator.
* Note that cgs are magic: they own tempPool and codePool "tops-of-stack"
* above their codeMark and tempMark points. This means you cannot alloc
* from tempPool and save the pointer beyond the next JS_FinishCodeGenerator.
*/
extern JS_FRIEND_API(void)
js_FinishCodeGenerator(JSContext *cx, JSCodeGenerator *cg);
/*
* Emit one bytecode.
*/
extern ptrdiff_t
js_Emit1(JSContext *cx, JSCodeGenerator *cg, JSOp op);
/*
* Emit two bytecodes, an opcode (op) with a byte of immediate operand (op1).
*/
extern ptrdiff_t
js_Emit2(JSContext *cx, JSCodeGenerator *cg, JSOp op, jsbytecode op1);
/*
* Emit three bytecodes, an opcode with two bytes of immediate operands.
*/
extern ptrdiff_t
js_Emit3(JSContext *cx, JSCodeGenerator *cg, JSOp op, jsbytecode op1,
jsbytecode op2);
/*
* Emit (1 + extra) bytecodes, for N bytes of op and its immediate operand.
*/
extern ptrdiff_t
js_EmitN(JSContext *cx, JSCodeGenerator *cg, JSOp op, size_t extra);
/*
* Unsafe macro to call js_SetJumpOffset and return false if it does.
*/
#define CHECK_AND_SET_JUMP_OFFSET(cx,cg,pc,off) \
JS_BEGIN_MACRO \
if (!js_SetJumpOffset(cx, cg, pc, off)) \
return JS_FALSE; \
JS_END_MACRO
#define CHECK_AND_SET_JUMP_OFFSET_AT(cx,cg,off) \
CHECK_AND_SET_JUMP_OFFSET(cx, cg, CG_CODE(cg,off), CG_OFFSET(cg) - (off))
extern JSBool
js_SetJumpOffset(JSContext *cx, JSCodeGenerator *cg, jsbytecode *pc,
ptrdiff_t off);
/*
* Push the C-stack-allocated struct at stmt onto the stmtInfo stack.
*/
extern void
js_PushStatement(JSTreeContext *tc, JSStmtInfo *stmt, JSStmtType type,
ptrdiff_t top);
/*
* Emit a break instruction, recording it for backpatching.
*/
extern ptrdiff_t
js_EmitBreak(JSContext *cx, JSCodeGenerator *cg, JSStmtInfo *stmt,
JSAtomListElement *label);
/*
* Emit a continue instruction, recording it for backpatching.
*/
extern ptrdiff_t
js_EmitContinue(JSContext *cx, JSCodeGenerator *cg, JSStmtInfo *stmt,
JSAtomListElement *label);
/*
* Pop tc->topStmt. If the top JSStmtInfo struct is not stack-allocated, it
* is up to the caller to free it.
*/
extern void
js_PopStatement(JSTreeContext *tc);
/*
* Like js_PopStatement(&cg->treeContext), also patch breaks and continues.
* May fail if a jump offset overflows.
*/
extern JSBool
js_PopStatementCG(JSContext *cx, JSCodeGenerator *cg);
/*
* Emit code into cg for the tree rooted at pn.
*/
extern JSBool
js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn);
/*
* Emit code into cg for the tree rooted at body, then create a persistent
* script for fun from cg.
*/
extern JSBool
js_EmitFunctionBody(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body,
JSFunction *fun);
/*
* Source notes generated along with bytecode for decompiling and debugging.
* A source note is a uint8 with 5 bits of type and 3 of offset from the pc of
* the previous note. If 3 bits of offset aren't enough, extended delta notes
* (SRC_XDELTA) consisting of 2 set high order bits followed by 6 offset bits
* are emitted before the next note. Some notes have operand offsets encoded
* immediately after them, in note bytes or byte-triples.
*
* At most one "gettable" note (i.e., a note of type other than SRC_NEWLINE,
* SRC_SETLINE, and SRC_XDELTA) applies to a given bytecode.
*
* NB: the js_SrcNoteName and js_SrcNoteArity arrays in jsemit.c are indexed
* by this enum, so their initializers need to match the order here.
*/
typedef enum JSSrcNoteType {
SRC_NULL = 0, /* terminates a note vector */
SRC_IF = 1, /* JSOP_IFEQ bytecode is from an if-then */
SRC_IF_ELSE = 2, /* JSOP_IFEQ bytecode is from an if-then-else */
SRC_WHILE = 3, /* JSOP_IFEQ is from a while loop */
SRC_FOR = 4, /* JSOP_NOP or JSOP_POP in for loop head */
SRC_CONTINUE = 5, /* JSOP_GOTO is a continue, not a break;
also used on JSOP_ENDINIT if extra comma
at end of array literal: [1,2,,] */
SRC_VAR = 6, /* JSOP_NAME/FORNAME with a var declaration */
SRC_PCDELTA = 7, /* offset from comma-operator to next POP,
or from CONDSWITCH to first CASE opcode */
SRC_ASSIGNOP = 8, /* += or another assign-op follows */
SRC_COND = 9, /* JSOP_IFEQ is from conditional ?: operator */
SRC_PAREN = 10, /* JSOP_NOP generated to mark user parens */
SRC_HIDDEN = 11, /* opcode shouldn't be decompiled */
SRC_PCBASE = 12, /* offset of first obj.prop.subprop bytecode */
SRC_LABEL = 13, /* JSOP_NOP for label: with atomid immediate */
SRC_LABELBRACE = 14, /* JSOP_NOP for label: {...} begin brace */
SRC_ENDBRACE = 15, /* JSOP_NOP for label: {...} end brace */
SRC_BREAK2LABEL = 16, /* JSOP_GOTO for 'break label' with atomid */
SRC_CONT2LABEL = 17, /* JSOP_GOTO for 'continue label' with atomid */
SRC_SWITCH = 18, /* JSOP_*SWITCH with offset to end of switch,
2nd off to first JSOP_CASE if condswitch */
SRC_FUNCDEF = 19, /* JSOP_NOP for function f() with atomid */
SRC_TRYFIN = 20, /* JSOP_NOP for try or finally section */
SRC_CATCH = 21, /* catch block has guard */
SRC_NEWLINE = 22, /* bytecode follows a source newline */
SRC_SETLINE = 23, /* a file-absolute source line number note */
SRC_XDELTA = 24 /* 24-31 are for extended delta notes */
} JSSrcNoteType;
#define SN_TYPE_BITS 5
#define SN_DELTA_BITS 3
#define SN_XDELTA_BITS 6
#define SN_TYPE_MASK (JS_BITMASK(SN_TYPE_BITS) << SN_DELTA_BITS)
#define SN_DELTA_MASK ((ptrdiff_t)JS_BITMASK(SN_DELTA_BITS))
#define SN_XDELTA_MASK ((ptrdiff_t)JS_BITMASK(SN_XDELTA_BITS))
#define SN_MAKE_NOTE(sn,t,d) (*(sn) = (jssrcnote) \
(((t) << SN_DELTA_BITS) \
| ((d) & SN_DELTA_MASK)))
#define SN_MAKE_XDELTA(sn,d) (*(sn) = (jssrcnote) \
((SRC_XDELTA << SN_DELTA_BITS) \
| ((d) & SN_XDELTA_MASK)))
#define SN_IS_XDELTA(sn) ((*(sn) >> SN_DELTA_BITS) >= SRC_XDELTA)
#define SN_TYPE(sn) (SN_IS_XDELTA(sn) ? SRC_XDELTA \
: *(sn) >> SN_DELTA_BITS)
#define SN_SET_TYPE(sn,type) SN_MAKE_NOTE(sn, type, SN_DELTA(sn))
#define SN_IS_GETTABLE(sn) (SN_TYPE(sn) < SRC_NEWLINE)
#define SN_DELTA(sn) ((ptrdiff_t)(SN_IS_XDELTA(sn) \
? *(sn) & SN_XDELTA_MASK \
: *(sn) & SN_DELTA_MASK))
#define SN_SET_DELTA(sn,delta) (SN_IS_XDELTA(sn) \
? SN_MAKE_XDELTA(sn, delta) \
: SN_MAKE_NOTE(sn, SN_TYPE(sn), delta))
#define SN_DELTA_LIMIT ((ptrdiff_t)JS_BIT(SN_DELTA_BITS))
#define SN_XDELTA_LIMIT ((ptrdiff_t)JS_BIT(SN_XDELTA_BITS))
/*
* Offset fields follow certain notes and are frequency-encoded: an offset in
* [0,0x7f] consumes one byte, an offset in [0x80,0x7fffff] takes three, and
* the high bit of the first byte is set.
*/
#define SN_3BYTE_OFFSET_FLAG 0x80
#define SN_3BYTE_OFFSET_MASK 0x7f
extern JS_FRIEND_DATA(const char *) js_SrcNoteName[];
extern JS_FRIEND_DATA(uint8) js_SrcNoteArity[];
extern JS_FRIEND_API(uintN) js_SrcNoteLength(jssrcnote *sn);
#define SN_LENGTH(sn) ((js_SrcNoteArity[SN_TYPE(sn)] == 0) ? 1 \
: js_SrcNoteLength(sn))
#define SN_NEXT(sn) ((sn) + SN_LENGTH(sn))
/* A source note array is terminated by an all-zero element. */
#define SN_MAKE_TERMINATOR(sn) (*(sn) = SRC_NULL)
#define SN_IS_TERMINATOR(sn) (*(sn) == SRC_NULL)
/*
* Append a new source note of the given type (and therefore size) to cg's
* notes dynamic array, updating cg->noteCount. Return the new note's index
* within the array pointed at by cg->notes. Return -1 if out of memory.
*/
extern intN
js_NewSrcNote(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type);
extern intN
js_NewSrcNote2(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type,
ptrdiff_t offset);
extern intN
js_NewSrcNote3(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type,
ptrdiff_t offset1, ptrdiff_t offset2);
/*
* Get and set the offset operand identified by which (0 for the first, etc.).
*/
extern JS_FRIEND_API(ptrdiff_t)
js_GetSrcNoteOffset(jssrcnote *sn, uintN which);
extern JSBool
js_SetSrcNoteOffset(JSContext *cx, JSCodeGenerator *cg, uintN index,
uintN which, ptrdiff_t offset);
/*
* Finish taking source notes in cx's tempPool by copying them to new
* stable store allocated via JS_malloc. Return null on malloc failure,
* which means this function reported an error.
*/
extern jssrcnote *
js_FinishTakingSrcNotes(JSContext *cx, JSCodeGenerator *cg);
/*
* Allocate cg->treeContext.tryCount notes (plus one for the end sentinel)
* from cx->tempPool and set up cg->tryBase/tryNext for exactly tryCount
* js_NewTryNote calls. The storage is freed by js_FinishCodeGenerator.
*/
extern JSBool
js_AllocTryNotes(JSContext *cx, JSCodeGenerator *cg);
/*
* Grab the next trynote slot in cg, filling it in appropriately.
*/
extern JSTryNote *
js_NewTryNote(JSContext *cx, JSCodeGenerator *cg, ptrdiff_t start,
ptrdiff_t end, ptrdiff_t catchStart);
/*
* Finish generating exception information, and copy it to JS_malloc
* storage.
*/
extern JSBool
js_FinishTakingTryNotes(JSContext *cx, JSCodeGenerator *cg, JSTryNote **tryp);
JS_END_EXTERN_C
#endif /* jsemit_h___ */

619
mozilla/js/src/jsexn.c Normal file
View File

@@ -0,0 +1,619 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* JS standard exception implementation.
*/
#include "jsstddef.h"
#include "jstypes.h"
#include "jsutil.h" /* Added by JSIFY */
#include "jsprf.h"
#include "jsapi.h"
#include "jscntxt.h"
#include "jsconfig.h"
#include "jsexn.h"
#include "jsfun.h"
#if JS_HAS_ERROR_EXCEPTIONS
#if !JS_HAS_EXCEPTIONS
# error "JS_HAS_EXCEPTIONS must be defined to use JS_HAS_ERROR_EXCEPTIONS"
#endif
/* Declaration to resolve circular reference of exn_class by Exception. */
static JSBool
Exception(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
static void
exn_finalize(JSContext *cx, JSObject *obj);
static JSClass exn_class = {
"Exception",
JSCLASS_HAS_PRIVATE,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize,
NULL, NULL, NULL, Exception
};
/*
* A copy of the JSErrorReport originally generated.
*/
typedef struct JSExnPrivate {
JSErrorReport *errorReport;
} JSExnPrivate;
/*
* Copy everything interesting about an error into allocated memory.
*/
static JSExnPrivate *
exn_initPrivate(JSContext *cx, JSErrorReport *report)
{
JSExnPrivate *newPrivate;
JSErrorReport *newReport;
newPrivate = (JSExnPrivate *)JS_malloc(cx, sizeof (JSExnPrivate));
/* Copy the error report */
newReport = (JSErrorReport *)JS_malloc(cx, sizeof (JSErrorReport));
if (report->filename != NULL) {
newReport->filename =
(const char *)JS_malloc(cx, strlen(report->filename)+1);
strcpy((char *)newReport->filename, report->filename);
} else {
newReport->filename = NULL;
}
newReport->lineno = report->lineno;
/*
* We don't need to copy linebuf and tokenptr, because they
* point into the deflated string cache. (currently?)
*/
newReport->linebuf = report->linebuf;
newReport->tokenptr = report->tokenptr;
/*
* But we do need to copy uclinebuf, uctokenptr, because they're
* pointers into internal tokenstream structs, and may go away.
*
* NOTE nothing uses this and I'm not really maintaining it until
* I know it's the desired API.
*
* Temporarily disabled, because uclinebuf is 0x10 when I evaluate 'Math()'!
*/
#if 0
if (report->uclinebuf != NULL) {
len = js_strlen(report->uclinebuf) + 1;
newReport->uclinebuf =
(const jschar *)JS_malloc(cx, len * sizeof(jschar));
js_strncpy(newReport->uclinebuf, report->uclinebuf, len);
newReport->uctokenptr = newReport->uclinebuf + (report->uctokenptr -
report->uclinebuf);
} else
#endif
newReport->uclinebuf = newReport->uctokenptr = NULL;
/* Executing the code below makes a seg fault where JS_malloc fails!? */
#if 0
if (report->ucmessage != NULL) {
len = js_strlen(report->ucmessage) + 1;
newReport->ucmessage = (const jschar *)JS_malloc(cx, len);
js_strncpy((jschar *)newReport->ucmessage, report->ucmessage, len);
if (report->messageArgs) {
int i;
for (i = 0; report->messageArgs[i] != NULL; i++)
;
JS_ASSERT(i);
newReport->messageArgs =
(const jschar **)JS_malloc(cx, (i + 1) * sizeof(jschar *));
for (i = 0; report->messageArgs[i] != NULL; i++) {
len = js_strlen(report->messageArgs[i]) + 1;
newReport->messageArgs[i] =
(const jschar *)JS_malloc(cx, len * sizeof(jschar));
js_strncpy((jschar *)(newReport->messageArgs[i]),
report->messageArgs[i], len);
}
report->messageArgs[i] = NULL;
} else {
report->messageArgs = NULL;
}
} else {
newReport->ucmessage = NULL;
newReport->messageArgs = NULL;
}
#else
newReport->ucmessage = NULL;
newReport->messageArgs = NULL;
#endif
/* Note that this is before it gets flagged with JSREPORT_EXCEPTION */
newReport->flags = report->flags;
newPrivate->errorReport = newReport;
return newPrivate;
}
/*
* Undo all the damage done by exn_initPrivate.
*/
static void
exn_destroyPrivate(JSContext *cx, JSExnPrivate *privateData)
{
JSErrorReport *report;
const jschar **args;
report = privateData->errorReport;
JS_ASSERT(report);
if (report->uclinebuf)
JS_free(cx, (void *)report->uclinebuf);
if (report->filename)
JS_free(cx, (void *)report->filename);
if (report->ucmessage)
JS_free(cx, (void *)report->ucmessage);
if (report->ucmessage)
JS_free(cx, (void *)report->ucmessage);
if (report->messageArgs) {
args = report->messageArgs;
while(*args++ != NULL)
JS_free(cx, (void *)*args);
JS_free(cx, (void *)report->messageArgs);
}
JS_free(cx, report);
JS_free(cx, privateData);
}
static void
exn_finalize(JSContext *cx, JSObject *obj)
{
JSExnPrivate *privateData;
jsval private;
private = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
if (private != JSVAL_NULL) {
privateData = JSVAL_TO_PRIVATE(private);
if (privateData)
exn_destroyPrivate(cx, privateData);
}
}
static JSErrorReport *
js_ErrorFromException(JSContext *cx, jsval exn)
{
JSObject *obj;
JSExnPrivate *privateData;
jsval private;
if (!JSVAL_IS_OBJECT(exn))
return NULL;
obj = JSVAL_TO_OBJECT(exn);
if (OBJ_GET_CLASS(cx, obj) != &exn_class)
return NULL;
private = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
privateData = JSVAL_TO_PRIVATE(OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE));
if (!privateData)
return NULL;
JS_ASSERT(privateData->errorReport);
return privateData->errorReport;
}
/* This must be kept in synch with the exceptions array below. */
typedef enum JSExnType {
JSEXN_NONE = -1,
JSEXN_EXCEPTION,
JSEXN_ERR,
JSEXN_INTERNALERR,
JSEXN_SYNTAXERR,
JSEXN_REFERENCEERR,
JSEXN_CALLERR,
JSEXN_TARGETERR,
JSEXN_CONSTRUCTORERR,
JSEXN_CONVERSIONERR,
JSEXN_TOOBJECTERR,
JSEXN_TOPRIMITIVEERR,
JSEXN_DEFAULTVALUEERR,
JSEXN_ARRAYERR,
JSEXN_LIMIT
} JSExnType;
struct JSExnSpec {
int protoIndex;
const char *name;
};
static struct JSExnSpec exceptions[] = {
{ JSEXN_NONE, "Exception" },
{ JSEXN_EXCEPTION, "Error" },
{ JSEXN_ERR, "InternalError" },
{ JSEXN_ERR, "SyntaxError" },
{ JSEXN_ERR, "ReferenceError" },
{ JSEXN_ERR, "CallError" },
{ JSEXN_CALLERR, "TargetError" },
{ JSEXN_ERR, "ConstructorError" },
{ JSEXN_ERR, "ConversionError" },
{ JSEXN_CONVERSIONERR, "ToObjectError" },
{ JSEXN_CONVERSIONERR, "ToPrimitiveError" },
{ JSEXN_CONVERSIONERR, "DefaultValueError" },
{ JSEXN_ERR, "ArrayError" },
{0}
};
static JSBool
Exception(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
JSString *message;
/*
* Does it make sense to throw a not-a-function-error here?
* A constructor that was not a function would be novel.
*/
if (!cx->fp->constructing) {
return JS_TRUE;
}
/*
* If it's a new object of class Exception, then null out the private
* data so that the finalizer doesn't attempt to free it.
*/
if (OBJ_GET_CLASS(cx, obj) == &exn_class)
OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, JSVAL_NULL);
/*
* Set the 'message' property.
*/
if (argc > 0) {
message = js_ValueToString(cx, argv[0]);
if (!message)
return JS_FALSE;
} else {
message = cx->runtime->emptyString;
}
if (!JS_DefineProperty(cx, obj, "message", STRING_TO_JSVAL(message),
NULL, NULL, JSPROP_ENUMERATE));
return JS_TRUE;
}
/*
* Convert to string.
*
* This method only uses JavaScript-modifiable properties name, message; it is
* left to the host to check for private data and report filename and line
* number information along with this message.
*/
static JSBool
exn_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsval v;
JSString *name, *message, *result;
jschar *chars, *cp;
size_t length;
jsid id;
id = (jsid) cx->runtime->atomState.nameAtom;
if (!OBJ_GET_PROPERTY(cx, obj, id, &v) || !(name = js_ValueToString(cx, v)))
return JS_FALSE;
if (!JS_GetProperty(cx, obj, "message", &v) ||
!(message = js_ValueToString(cx, v)))
return JS_FALSE;
if (message->length > 0) {
length = name->length + message->length + 2;
cp = chars = JS_malloc(cx, (length + 1) * sizeof(jschar));
if (!chars)
return JS_FALSE;
js_strncpy(cp, name->chars, name->length);
cp += name->length;
*cp++ = ':'; *cp++ = ' ';
js_strncpy(cp, message->chars, message->length);
cp += message->length;
*cp = 0;
result = js_NewString(cx, chars, length, 0);
if (!result) {
JS_free(cx, chars);
return JS_FALSE;
}
} else {
result = name;
}
*rval = STRING_TO_JSVAL(result);
return JS_TRUE;
}
#if JS_HAS_TOSOURCE
/*
* Return a string that may eval to something similar to the original object.
*/
static JSBool
exn_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
JSString *name, *message, *result;
jschar *chars, *cp;
jsid id;
size_t length;
jsval v;
id = (jsid) cx->runtime->atomState.nameAtom;
if (!OBJ_GET_PROPERTY(cx, obj, id, &v) || !(name = js_ValueToString(cx, v)))
return JS_FALSE;
if (!JS_GetProperty(cx, obj, "message", &v) ||
!(message = js_ValueToString(cx, v)))
return JS_FALSE;
length = (message->length > 0) ? name->length + message->length + 10
: name->length + 8;
cp = chars = JS_malloc(cx, (length + 1) * sizeof(jschar));
if (!chars)
return JS_FALSE;
*cp++ = '('; *cp++ = 'n'; *cp++ = 'e'; *cp++ = 'w'; *cp++ = ' ';
js_strncpy(cp, name->chars, name->length);
cp += name->length;
*cp++ = '(';
if (message->length > 0) {
*cp++ = '"';
js_strncpy(cp, message->chars, message->length);
cp += message->length;
*cp++ = '"';
}
*cp++ = ')'; *cp++ = ')'; *cp = 0;
result = js_NewString(cx, chars, length, 0);
if (!result) {
JS_free(cx, chars);
return JS_FALSE;
}
*rval = STRING_TO_JSVAL(result);
return JS_TRUE;
}
#endif
static JSFunctionSpec exception_methods[] = {
#if JS_HAS_TOSOURCE
{js_toSource_str, exn_toSource, 0},
#endif
{js_toString_str, exn_toString, 0},
{0}
};
JSObject *
js_InitExceptionClasses(JSContext *cx, JSObject *obj)
{
int i;
JSObject *protos[JSEXN_LIMIT];
/* Initialize the prototypes first. */
for (i = 0; exceptions[i].name != 0; i++) {
JSAtom *atom;
JSFunction *fun;
JSString *nameString;
int protoidx = exceptions[i].protoIndex;
/* Make the prototype for the current constructor name. */
protos[i] = js_NewObject(cx, &exn_class,
protoidx >= 0 ? protos[protoidx] : NULL,
obj);
if (!protos[i])
return NULL;
atom = js_Atomize(cx, exceptions[i].name, strlen(exceptions[i].name), 0);
/* Make a constructor function for the current name. */
fun = js_DefineFunction(cx, obj, atom, Exception, 1, 0);
if (!fun)
return NULL; /* XXX also remove named property from obj... */
/* Make this constructor make objects of class Exception. */
fun->clasp = &exn_class;
/* Make the prototype and constructor links. */
if (!js_SetClassPrototype(cx, fun->object, protos[i],
JSPROP_READONLY | JSPROP_PERMANENT))
return NULL;
/* proto bootstrap bit from JS_InitClass omitted. */
nameString = JS_NewStringCopyZ(cx, exceptions[i].name);
if (nameString == NULL)
return NULL;
/* Add the name property to the prototype. */
if (!JS_DefineProperty(cx, protos[i], js_name_str,
STRING_TO_JSVAL(nameString),
NULL, NULL,
JSPROP_ENUMERATE)) {
/* release it? */
return NULL;
}
/* So finalize knows whether to. */
OBJ_SET_SLOT(cx, protos[i], JSSLOT_PRIVATE, JSVAL_NULL);
}
/*
* Add an empty message property. (To Exception.prototype only,
* because this property will be the same for all the exception
* protos.)
*/
if (!JS_DefineProperty(cx, protos[0], "message",
STRING_TO_JSVAL(cx->runtime->emptyString),
NULL, NULL, JSPROP_ENUMERATE))
return NULL;
/*
* Add methods only to Exception.prototype, because ostensibly all
* exception types delegate to that.
*/
if (!JS_DefineFunctions(cx, protos[0], exception_methods))
return NULL;
return protos[0];
}
static JSExnType errorToExceptionNum[] = {
#define MSG_DEF(name, number, count, exception, format) \
exception,
#include "js.msg"
#undef MSG_DEF
};
#if defined ( DEBUG_mccabe ) && defined ( PRINTNAMES )
/* For use below... get character strings for error name and exception name */
static struct exnname { char *name; char *exception; } errortoexnname[] = {
#define MSG_DEF(name, number, count, exception, format) \
{#name, #exception},
#include "js.msg"
#undef MSG_DEF
};
#endif /* DEBUG */
JSBool
js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp)
{
JSErrNum errorNumber;
JSObject *errObject, *errProto;
JSExnType exn;
JSExnPrivate *privateData;
JSString *msgstr;
/* Find the exception index associated with this error. */
JS_ASSERT(reportp);
errorNumber = reportp->errorNumber;
exn = errorToExceptionNum[errorNumber];
JS_ASSERT(exn < JSEXN_LIMIT);
#if defined( DEBUG_mccabe ) && defined ( PRINTNAMES )
/* Print the error name and the associated exception name to stderr */
fprintf(stderr, "%s\t%s\n",
errortoexnname[errorNumber].name,
errortoexnname[errorNumber].exception);
#endif
/*
* Return false (no exception raised) if no exception is associated
* with the given error number.
*/
if (exn == JSEXN_NONE)
return JS_FALSE;
/*
* Try to get an appropriate prototype by looking up the corresponding
* exception constructor name in the current context. If the constructor
* has been deleted or overwritten, this may fail or return NULL, and
* js_NewObject will fall back to using Object.prototype.
*/
if (!js_GetClassPrototype(cx, exceptions[exn].name, &errProto))
errProto = NULL;
/*
* Use js_NewObject instead of js_ConstructObject, because
* js_ConstructObject seems to require a frame.
*/
errObject = js_NewObject(cx, &exn_class, errProto, NULL);
/* Store 'message' as a javascript-visible value. */
msgstr = JS_NewStringCopyZ(cx, message);
if (!JS_DefineProperty(cx, errObject, "message", STRING_TO_JSVAL(msgstr),
NULL, NULL,
JSPROP_ENUMERATE))
return JS_FALSE;
/*
* Construct a new copy of the error report, and store it in the
* exception objects' private data. We can't use the error report
* handed in, because it's stack-allocated, and may point to transient
* data in the JSTokenStream.
*/
privateData = exn_initPrivate(cx, reportp);
OBJ_SET_SLOT(cx, errObject, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(privateData));
/* Set the generated Exception object as the current exception. */
JS_SetPendingException(cx, OBJECT_TO_JSVAL(errObject));
/* Flag the error report passed in to indicate an exception was raised. */
reportp->flags |= JSREPORT_EXCEPTION;
return JS_TRUE;
}
#endif /* JS_HAS_ERROR_EXCEPTIONS */
#if JS_HAS_EXCEPTIONS
extern JSBool
js_ReportUncaughtException(JSContext *cx)
{
JSObject *exnObject;
JSString *str;
jsval exn;
JSErrorReport *reportp;
if (!JS_IsExceptionPending(cx))
return JS_FALSE;
if (!JS_GetPendingException(cx, &exn))
return JS_FALSE;
/*
* Because js_ValueToString below could error and an exception object
* could become unrooted, we root it here.
*/
if (JSVAL_IS_OBJECT(exn)) {
exnObject = JSVAL_TO_OBJECT(exn);
if (!js_AddRoot(cx, exnObject, "exn.report.root"))
return JS_FALSE;
} else {
exnObject = NULL;
}
str = js_ValueToString(cx, exn);
#if JS_HAS_ERROR_EXCEPTIONS
reportp = js_ErrorFromException(cx, exn);
#else
reportp = NULL;
#endif
if (reportp == NULL) {
/*
* XXXmccabe todo: Instead of doing this, synthesize an error report
* struct that includes the filename, lineno where the exception was
* originally thrown.
*/
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_UNCAUGHT_EXCEPTION, js_GetStringBytes(str));
} else {
/* Flag the error as an exception. */
reportp->flags |= JSREPORT_EXCEPTION;
js_ReportErrorAgain(cx, js_GetStringBytes(str), reportp);
}
if (exnObject != NULL)
js_RemoveRoot(cx, exnObject);
return JS_TRUE;
}
#endif /* JS_HAS_EXCEPTIONS */

66
mozilla/js/src/jsexn.h Normal file
View File

@@ -0,0 +1,66 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* JS runtime exception classes.
*/
#ifndef jsexn_h___
#define jsexn_h___
JS_BEGIN_EXTERN_C
/*
* Initialize exception object hierarchy.
*/
extern JSObject *
js_InitExceptionClasses(JSContext *cx, JSObject *obj);
/*
* Given a JSErrorReport, check to see if there is an exception associated with
* the error number. If there is, then create an appropriate exception object,
* set it as the pending exception, and set the JSREPORT_EXCEPTION flag on the
* error report. Exception-aware host error reporters should probably ignore
* error reports so flagged. Returns JS_TRUE if an associated exception is
* found and set, JS_FALSE otherwise..
*/
extern JSBool
js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp);
/*
* Called if an api call to js_Execute or js_CallFunctionValue fails; calls the
* error reporter with the error report associated with any uncaught exception
* that has been raised. Returns true if there was an exception pending, and
* the error reporter was actually called.
*
* The JSErrorReport * that the error reporter is called with is currently
* associated with a JavaScript object, and is not guaranteed to persist after
* the object is collected. Any persistent uses of the JSErrorReport contents
* should make their own copy.
*
* The flags field of the JSErrorReport will have the JSREPORT_EXCEPTION flag
* set; embeddings that want to silently propagate JavaScript exceptions to
* other contexts may want to use an error reporter that ignores errors with
* this flag.
*/
extern JSBool
js_ReportUncaughtException(JSContext *cx);
JS_END_EXTERN_C
#endif /* jsexn_h___ */

2265
mozilla/js/src/jsfile.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
@@ -16,9 +16,12 @@
* Reserved.
*/
#include "nsWinRegValue.h"
#ifndef _jsfile_h__
#define _jsfile_h__
PR_BEGIN_EXTERN_C
extern JSObject*
js_InitFileClass(JSContext *cx, JSObject* obj);
PR_END_EXTERN_C
#endif /* _jsfile_h__ */

1816
mozilla/js/src/jsfun.c Normal file

File diff suppressed because it is too large Load Diff

108
mozilla/js/src/jsfun.h Normal file
View File

@@ -0,0 +1,108 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsfun_h___
#define jsfun_h___
/*
* JS function definitions.
*/
#include "jsprvtd.h"
#include "jspubtd.h"
JS_BEGIN_EXTERN_C
struct JSFunction {
jsrefcount nrefs; /* number of referencing objects */
JSObject *object; /* back-pointer to GC'ed object header */
JSNative call; /* native method pointer or null */
uint16 nargs; /* minimum number of actual arguments */
uint16 extra; /* number of arg slots for local GC roots */
uint16 nvars; /* number of local variables */
uint8 flags; /* bound method and other flags, see jsapi.h */
uint8 spare; /* reserved for future use */
JSAtom *atom; /* name for diagnostics and decompiling */
JSScript *script; /* interpreted bytecode descriptor or null */
JSClass *clasp; /* this function is a constructor for objects
* of this class */
};
extern JSClass js_ArgumentsClass;
extern JSClass js_CallClass;
extern JSClass js_ClosureClass;
/* JS_FRIEND_DATA so that JSVAL_IS_FUNCTION is callable from outside */
extern JS_FRIEND_DATA(JSClass) js_FunctionClass;
/*
* NB: jsapi.h and jsobj.h must be included before any call to this macro.
*/
#define JSVAL_IS_FUNCTION(cx, v) \
(JSVAL_IS_OBJECT(v) && JSVAL_TO_OBJECT(v) && \
OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_FunctionClass)
extern JSBool
js_IsIdentifier(JSString *str);
extern JSObject *
js_InitFunctionClass(JSContext *cx, JSObject *obj);
extern JSBool
js_InitArgsCallClosureClasses(JSContext *cx, JSObject *obj,
JSObject *objProto);
extern JSFunction *
js_NewFunction(JSContext *cx, JSObject *funobj, JSNative call, uintN nargs,
uintN flags, JSObject *parent, JSAtom *atom);
extern JSBool
js_LinkFunctionObject(JSContext *cx, JSFunction *fun, JSObject *object);
extern JSFunction *
js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, JSNative call,
uintN nargs, uintN flags);
extern JSFunction *
js_ValueToFunction(JSContext *cx, jsval *vp, JSBool constructing);
extern void
js_ReportIsNotFunction(JSContext *cx, jsval *vp, JSBool constructing);
extern JSObject *
js_GetCallObject(JSContext *cx, JSStackFrame *fp, JSObject *parent,
JSObject *withobj);
extern JSBool
js_PutCallObject(JSContext *cx, JSStackFrame *fp);
extern JSBool
js_GetCallVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
extern JSBool
js_SetCallVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
extern JSObject *
js_GetArgsObject(JSContext *cx, JSStackFrame *fp);
extern JSBool
js_PutArgsObject(JSContext *cx, JSStackFrame *fp);
extern JSBool
js_XDRFunction(JSXDRState *xdr, JSObject **objp);
JS_END_EXTERN_C
#endif /* jsfun_h___ */

918
mozilla/js/src/jsgc.c Normal file
View File

@@ -0,0 +1,918 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* JS Mark-and-Sweep Garbage Collector.
*
* This GC allocates only fixed-sized things big enough to contain two words
* (pointers) on any host architecture. It allocates from an arena pool (see
* jsarena.h). It uses a parallel arena-pool array of flag bytes to hold the
* mark bit, finalizer type index, etc.
*
* XXX swizzle page to freelist for better locality of reference
*/
#include "jsstddef.h"
#include <stdlib.h> /* for free, called by JS_ARENA_DESTROY */
#include <string.h> /* for memset, called by jsarena.h macros if DEBUG */
#include "jstypes.h"
#include "jsarena.h" /* Added by JSIFY */
#include "jsutil.h" /* Added by JSIFY */
#include "jshash.h" /* Added by JSIFY */
#include "jsapi.h"
#include "jsatom.h"
#include "jscntxt.h"
#include "jsfun.h"
#include "jsgc.h"
#include "jsinterp.h"
#include "jslock.h"
#include "jsnum.h"
#include "jsobj.h"
#include "jsscope.h"
#include "jsscript.h"
#include "jsstr.h"
/*
* Arena sizes, the first must be a multiple of the second so the two arena
* pools can be maintained (in particular, arenas may be destroyed from the
* middle of each pool) in parallel.
*/
#define GC_ARENA_SIZE 8192 /* 1024 (512 on Alpha) objects */
#define GC_FLAGS_SIZE (GC_ARENA_SIZE / sizeof(JSGCThing))
#define GC_ROOTS_SIZE 256 /* SWAG, small enough to amortize */
static JSHashNumber gc_hash_root(const void *key);
struct JSGCThing {
JSGCThing *next;
uint8 *flagp;
};
typedef void (*GCFinalizeOp)(JSContext *cx, JSGCThing *thing);
static GCFinalizeOp gc_finalizers[GCX_NTYPES];
#ifdef JS_GCMETER
#define METER(x) x
#else
#define METER(x) /* nothing */
#endif
JSBool
js_InitGC(JSRuntime *rt, uint32 maxbytes)
{
if (!gc_finalizers[GCX_OBJECT]) {
gc_finalizers[GCX_OBJECT] = (GCFinalizeOp)js_FinalizeObject;
gc_finalizers[GCX_STRING] = (GCFinalizeOp)js_FinalizeString;
gc_finalizers[GCX_DOUBLE] = (GCFinalizeOp)js_FinalizeDouble;
}
JS_InitArenaPool(&rt->gcArenaPool, "gc-arena", GC_ARENA_SIZE,
sizeof(JSGCThing));
JS_InitArenaPool(&rt->gcFlagsPool, "gc-flags", GC_FLAGS_SIZE,
sizeof(uint8));
rt->gcRootsHash = JS_NewHashTable(GC_ROOTS_SIZE, gc_hash_root,
JS_CompareValues, JS_CompareValues,
NULL, NULL);
if (!rt->gcRootsHash)
return JS_FALSE;
rt->gcMaxBytes = maxbytes;
return JS_TRUE;
}
#ifdef JS_GCMETER
void
js_DumpGCStats(JSRuntime *rt, FILE *fp)
{
fprintf(fp, "\nGC allocation statistics:\n");
fprintf(fp, " bytes currently allocated: %lu\n", rt->gcBytes);
fprintf(fp, " alloc attempts: %lu\n", rt->gcStats.alloc);
fprintf(fp, " GC freelist length: %lu\n", rt->gcStats.freelen);
fprintf(fp, " recycles through GC freelist: %lu\n", rt->gcStats.recycle);
fprintf(fp, "alloc retries after running GC: %lu\n", rt->gcStats.retry);
fprintf(fp, " allocation failures: %lu\n", rt->gcStats.fail);
fprintf(fp, " valid lock calls: %lu\n", rt->gcStats.lock);
fprintf(fp, " valid unlock calls: %lu\n", rt->gcStats.unlock);
fprintf(fp, " locks that hit stuck counts: %lu\n", rt->gcStats.stuck);
fprintf(fp, " unlocks that saw stuck counts: %lu\n", rt->gcStats.unstuck);
fprintf(fp, " mark recursion depth: %lu\n", rt->gcStats.depth);
fprintf(fp, " maximum mark recursion depth: %lu\n", rt->gcStats.maxdepth);
fprintf(fp, " maximum GC nesting level: %lu\n", rt->gcStats.maxlevel);
fprintf(fp, " potentially useful GC calls: %lu\n", rt->gcStats.poke);
fprintf(fp, " useless GC calls: %lu\n", rt->gcStats.nopoke);
fprintf(fp, " thing arena corruption: %lu\n", rt->gcStats.badarena);
fprintf(fp, " flags arena corruption: %lu\n", rt->gcStats.badflag);
fprintf(fp, " thing arenas freed so far: %lu\n", rt->gcStats.afree);
fprintf(fp, " flags arenas freed so far: %lu\n", rt->gcStats.fafree);
#ifdef JS_ARENAMETER
JS_DumpArenaStats(fp);
#endif
}
#endif
void
js_FinishGC(JSRuntime *rt)
{
#ifdef JS_ARENAMETER
JS_DumpArenaStats(stdout);
#endif
#ifdef JS_GCMETER
js_DumpGCStats(rt, stdout);
#endif
JS_FinishArenaPool(&rt->gcArenaPool);
JS_FinishArenaPool(&rt->gcFlagsPool);
JS_ArenaFinish();
JS_HashTableDestroy(rt->gcRootsHash);
rt->gcRootsHash = NULL;
rt->gcFreeList = NULL;
}
JSBool
js_AddRoot(JSContext *cx, void *rp, const char *name)
{
JSRuntime *rt;
JSBool ok;
rt = cx->runtime;
JS_LOCK_GC_VOID(rt,
ok = (JS_HashTableAdd(rt->gcRootsHash, rp, (void *)name) != NULL));
if (!ok)
JS_ReportOutOfMemory(cx);
return ok;
}
JSBool
js_RemoveRoot(JSContext *cx, void *rp)
{
JSRuntime *rt;
rt = cx->runtime;
JS_LOCK_GC_VOID(rt, JS_HashTableRemove(rt->gcRootsHash, rp));
return JS_TRUE;
}
void *
js_AllocGCThing(JSContext *cx, uintN flags)
{
JSRuntime *rt;
JSGCThing *thing;
uint8 *flagp = NULL;
#ifdef TOO_MUCH_GC
JSBool tried_gc = JS_TRUE;
js_GC(cx);
#else
JSBool tried_gc = JS_FALSE;
#endif
rt = cx->runtime;
JS_LOCK_GC(rt);
METER(rt->gcStats.alloc++);
retry:
thing = rt->gcFreeList;
if (thing) {
rt->gcFreeList = thing->next;
flagp = thing->flagp;
METER(rt->gcStats.freelen--);
METER(rt->gcStats.recycle++);
} else {
if (rt->gcBytes < rt->gcMaxBytes) {
JS_ARENA_ALLOCATE(thing, &rt->gcArenaPool, sizeof(JSGCThing));
JS_ARENA_ALLOCATE(flagp, &rt->gcFlagsPool, sizeof(uint8));
}
if (!thing || !flagp) {
if (thing)
JS_ARENA_RELEASE(&rt->gcArenaPool, thing);
if (!tried_gc) {
JS_UNLOCK_GC(rt);
js_GC(cx);
tried_gc = JS_TRUE;
JS_LOCK_GC(rt);
METER(rt->gcStats.retry++);
goto retry;
}
METER(rt->gcStats.fail++);
JS_UNLOCK_GC(rt);
JS_ReportOutOfMemory(cx);
return NULL;
}
}
*flagp = (uint8)flags;
rt->gcBytes += sizeof(JSGCThing) + sizeof(uint8);
cx->newborn[flags & GCF_TYPEMASK] = thing;
/*
* Clear thing before unlocking in case a GC run is about to scan it,
* finding it via cx->newborn[].
*/
thing->next = NULL;
thing->flagp = NULL;
JS_UNLOCK_GC(rt);
return thing;
}
static uint8 *
gc_find_flags(JSRuntime *rt, void *thing)
{
jsuword index, offset, length;
JSArena *a, *fa;
index = 0;
for (a = rt->gcArenaPool.first.next; a; a = a->next) {
offset = JS_UPTRDIFF(thing, a->base);
length = a->avail - a->base;
if (offset < length) {
index += offset / sizeof(JSGCThing);
for (fa = rt->gcFlagsPool.first.next; fa; fa = fa->next) {
offset = fa->avail - fa->base;
if (index < offset)
return (uint8 *)fa->base + index;
index -= offset;
}
return NULL;
}
index += length / sizeof(JSGCThing);
}
return NULL;
}
JSBool
js_LockGCThing(JSContext *cx, void *thing)
{
uint8 *flagp, flags;
if (!thing)
return JS_TRUE;
flagp = gc_find_flags(cx->runtime, thing);
if (!flagp)
return JS_FALSE;
flags = *flagp;
if ((flags & GCF_LOCKMASK) != GCF_LOCKMASK) {
*flagp = (uint8)(flags + GCF_LOCK);
} else {
METER(cx->runtime->gcStats.stuck++);
}
METER(cx->runtime->gcStats.lock++);
return JS_TRUE;
}
JSBool
js_UnlockGCThing(JSContext *cx, void *thing)
{
uint8 *flagp, flags;
if (!thing)
return JS_TRUE;
flagp = gc_find_flags(cx->runtime, thing);
if (!flagp)
return JS_FALSE;
flags = *flagp;
if ((flags & GCF_LOCKMASK) != GCF_LOCKMASK) {
*flagp = (uint8)(flags - GCF_LOCK);
} else {
METER(cx->runtime->gcStats.unstuck++);
}
METER(cx->runtime->gcStats.unlock++);
return JS_TRUE;
}
#ifdef GC_MARK_DEBUG
#include <stdio.h>
#include <stdlib.h>
#include "jsprf.h"
JS_FRIEND_DATA(FILE *) js_DumpGCHeap;
JS_FRIEND_DATA(void *) js_LiveThingToFind;
typedef struct GCMarkNode GCMarkNode;
struct GCMarkNode {
void *thing;
char *name;
GCMarkNode *next;
GCMarkNode *prev;
};
static void
gc_dump_thing(JSGCThing *thing, uint8 flags, GCMarkNode *prev, FILE *fp)
{
GCMarkNode *next = NULL;
char *path = NULL;
JSObject *obj;
JSClass *clasp;
while (prev) {
next = prev;
prev = prev->prev;
}
while (next) {
path = JS_sprintf_append(path, "%s.", next->name);
next = next->next;
}
if (!path)
return;
fprintf(fp, "%08lx ", (long)thing);
switch (flags & GCF_TYPEMASK) {
case GCX_OBJECT:
obj = (JSObject *)thing;
clasp = JSVAL_TO_PRIVATE(obj->slots[JSSLOT_CLASS]);
fprintf(fp, "object %s", clasp->name);
break;
case GCX_STRING:
fprintf(fp, "string %s", JS_GetStringBytes((JSString *)thing));
break;
case GCX_DOUBLE:
fprintf(fp, "double %g", *(jsdouble *)thing);
break;
case GCX_DECIMAL:
break;
}
fprintf(fp, " via %s\n", path);
free(path);
}
static void
gc_mark_node(JSRuntime *rt, void *thing, GCMarkNode *prev);
#define GC_MARK(_rt, _thing, _name, _prev) \
JS_BEGIN_MACRO \
GCMarkNode _node; \
_node.thing = _thing; \
_node.name = _name; \
_node.next = NULL; \
_node.prev = _prev; \
if (_prev) ((GCMarkNode *)(_prev))->next = &_node; \
gc_mark_node(_rt, _thing, &_node); \
JS_END_MACRO
static void
gc_mark(JSRuntime *rt, void *thing)
{
GC_MARK(rt, thing, "atom", NULL);
}
#define GC_MARK_ATOM(rt, atom, prev) gc_mark_atom(rt, atom, prev)
#define GC_MARK_SCRIPT(rt, script, prev) gc_mark_script(rt, script, prev)
#else /* !GC_MARK_DEBUG */
#define GC_MARK(rt, thing, name, prev) gc_mark(rt, thing)
#define GC_MARK_ATOM(rt, atom, prev) gc_mark_atom(rt, atom)
#define GC_MARK_SCRIPT(rt, script, prev) gc_mark_script(rt, script)
static void
gc_mark(JSRuntime *rt, void *thing);
#endif /* !GC_MARK_DEBUG */
static void
gc_mark_atom(JSRuntime *rt, JSAtom *atom
#ifdef GC_MARK_DEBUG
, GCMarkNode *prev
#endif
)
{
jsval key;
if (!atom || atom->flags & ATOM_MARK)
return;
atom->flags |= ATOM_MARK;
key = ATOM_KEY(atom);
if (JSVAL_IS_GCTHING(key)) {
#ifdef GC_MARK_DEBUG
char name[32];
if (JSVAL_IS_STRING(key)) {
JS_snprintf(name, sizeof name, "'%s'",
JS_GetStringBytes(JSVAL_TO_STRING(key)));
} else {
JS_snprintf(name, sizeof name, "<%x>", key);
}
#endif
GC_MARK(rt, JSVAL_TO_GCTHING(key), name, prev);
}
}
static void
gc_mark_script(JSRuntime *rt, JSScript *script
#ifdef GC_MARK_DEBUG
, GCMarkNode *prev
#endif
)
{
JSAtomMap *map;
uintN i, length;
JSAtom **vector;
map = &script->atomMap;
length = map->length;
vector = map->vector;
for (i = 0; i < length; i++)
GC_MARK_ATOM(rt, vector[i], prev);
}
static void
#ifdef GC_MARK_DEBUG
gc_mark_node(JSRuntime *rt, void *thing, GCMarkNode *prev)
#else
gc_mark(JSRuntime *rt, void *thing)
#endif
{
uint8 flags, *flagp;
JSObject *obj;
jsval v, *vp, *end;
JSScope *scope;
JSClass *clasp;
JSScript *script;
JSFunction *fun;
JSScopeProperty *sprop;
JSSymbol *sym;
if (!thing)
return;
flagp = gc_find_flags(rt, thing);
if (!flagp)
return;
/* Check for something on the GC freelist to handle recycled stack. */
flags = *flagp;
if (flags == GCF_FINAL)
return;
#ifdef GC_MARK_DEBUG
if (js_LiveThingToFind == thing)
gc_dump_thing(thing, flags, prev, stderr);
#endif
if (flags & GCF_MARK)
return;
*flagp |= GCF_MARK;
METER(if (++rt->gcStats.depth > rt->gcStats.maxdepth)
rt->gcStats.maxdepth = rt->gcStats.depth);
#ifdef GC_MARK_DEBUG
if (js_DumpGCHeap)
gc_dump_thing(thing, flags, prev, js_DumpGCHeap);
#endif
if ((flags & GCF_TYPEMASK) == GCX_OBJECT) {
obj = thing;
vp = obj->slots;
if (vp) {
scope = OBJ_IS_NATIVE(obj) ? (JSScope *) obj->map : NULL;
if (scope) {
clasp = JSVAL_TO_PRIVATE(obj->slots[JSSLOT_CLASS]);
if (clasp == &js_ScriptClass) {
v = vp[JSSLOT_PRIVATE];
if (!JSVAL_IS_VOID(v)) {
script = JSVAL_TO_PRIVATE(v);
if (script)
GC_MARK_SCRIPT(rt, script, prev);
}
}
if (clasp == &js_FunctionClass) {
v = vp[JSSLOT_PRIVATE];
if (!JSVAL_IS_VOID(v)) {
fun = JSVAL_TO_PRIVATE(v);
if (fun) {
if (fun->atom)
GC_MARK_ATOM(rt, fun->atom, prev);
if (fun->script)
GC_MARK_SCRIPT(rt, fun->script, prev);
}
}
}
for (sprop = scope->props; sprop; sprop = sprop->next) {
for (sym = sprop->symbols; sym; sym = sym->next) {
if (JSVAL_IS_INT(sym_id(sym)))
continue;
GC_MARK_ATOM(rt, sym_atom(sym), prev);
}
}
}
if (!scope || scope->object == obj)
end = vp + obj->map->freeslot;
else
end = vp + JS_INITIAL_NSLOTS;
for (; vp < end; vp++) {
v = *vp;
if (JSVAL_IS_GCTHING(v)) {
#ifdef GC_MARK_DEBUG
char name[32];
if (scope) {
uint32 slot;
jsval nval;
slot = vp - obj->slots;
for (sprop = scope->props; ; sprop = sprop->next) {
if (!sprop) {
switch (slot) {
case JSSLOT_PROTO:
strcpy(name, "__proto__");
break;
case JSSLOT_PARENT:
strcpy(name, "__parent__");
break;
case JSSLOT_PRIVATE:
strcpy(name, "__private__");
break;
default:
JS_snprintf(name, sizeof name,
"**UNKNOWN SLOT %ld**",
(long)slot);
break;
}
break;
}
if (sprop->slot == slot) {
nval = sprop->symbols
? js_IdToValue(sym_id(sprop->symbols))
: sprop->id;
if (JSVAL_IS_INT(nval)) {
JS_snprintf(name, sizeof name, "%ld",
(long)JSVAL_TO_INT(nval));
} else if (JSVAL_IS_STRING(nval)) {
JS_snprintf(name, sizeof name, "%s",
JS_GetStringBytes(JSVAL_TO_STRING(nval)));
} else {
strcpy(name, "**FINALIZED ATOM KEY**");
}
break;
}
}
}
#endif
GC_MARK(rt, JSVAL_TO_GCTHING(v), name, prev);
}
}
}
}
METER(rt->gcStats.depth--);
}
static JSHashNumber
gc_hash_root(const void *key)
{
JSHashNumber num = (JSHashNumber) key; /* help lame MSVC1.5 on Win16 */
return num >> 2;
}
JS_STATIC_DLL_CALLBACK(intN)
gc_root_marker(JSHashEntry *he, intN i, void *arg)
{
void **rp = (void **)he->key;
if (*rp) {
#ifdef DEBUG
JSArena *a;
JSRuntime *rt = (JSRuntime *)arg;
JSBool root_points_to_gcArenaPool = JS_FALSE;
if (rp && *rp) {
for (a = rt->gcArenaPool.first.next; a; a = a->next) {
if (*rp >= (void *)a->base && *rp <= (void *)a->avail) {
root_points_to_gcArenaPool = JS_TRUE;
break;
}
}
JS_ASSERT(root_points_to_gcArenaPool);
}
#endif
GC_MARK(arg, *rp, he->value ? he->value : "root", NULL);
}
return HT_ENUMERATE_NEXT;
}
JS_FRIEND_API(void)
js_ForceGC(JSContext *cx)
{
cx->newborn[GCX_OBJECT] = NULL;
cx->newborn[GCX_STRING] = NULL;
cx->newborn[GCX_DOUBLE] = NULL;
cx->runtime->gcPoke = JS_TRUE;
js_GC(cx);
JS_ArenaFinish();
}
void
js_GC(JSContext *cx)
{
JSRuntime *rt;
JSContext *iter, *acx;
JSArena *a, *ma, *fa, **ap, **fap;
jsval v, *vp, *sp;
jsuword begin, end;
JSStackFrame *fp, *chain;
void *mark;
uint8 flags, *flagp;
JSGCThing *thing, *final, **flp, **oflp;
GCFinalizeOp finalizer;
JSBool a_all_clear, f_all_clear;
/*
* XXX kludge for pre-ECMAv2 compile-time switch case expr eval, see
* jsemit.c:js_EmitTree, under case TOK_SWITCH: (look for XXX).
*/
if (cx->gcDisabled)
return;
rt = cx->runtime;
#ifdef JS_THREADSAFE
/* Avoid deadlock. */
JS_ASSERT(!JS_IS_RUNTIME_LOCKED(rt));
#endif
/* Let the API user decide to defer a GC if it wants to. */
if (rt->gcCallback && !rt->gcCallback(cx, JSGC_BEGIN))
return;
/* Lock out other GC allocator and collector invocations. */
JS_LOCK_GC(rt);
/* Do nothing if no assignment has executed since the last GC. */
if (!rt->gcPoke) {
METER(rt->gcStats.nopoke++);
JS_UNLOCK_GC(rt);
return;
}
rt->gcPoke = JS_FALSE;
METER(rt->gcStats.poke++);
#ifdef JS_THREADSAFE
/* Bump gcLevel and return rather than nest on this context. */
if (cx->gcActive) {
rt->gcLevel++;
METER(if (rt->gcLevel > rt->gcStats.maxlevel)
rt->gcStats.maxlevel = rt->gcLevel);
if (rt->gcLevel > 1) {
JS_UNLOCK_GC(rt);
return;
}
}
/* If we're in a request, indicate, temporarily, that we're inactive. */
if (cx->requestDepth) {
rt->requestCount--;
JS_NOTIFY_REQUEST_DONE(rt);
}
/* If another thread is already in GC, don't attempt GC; wait instead. */
if (rt->gcLevel > 0) {
while (rt->gcLevel > 0)
JS_AWAIT_GC_DONE(rt);
if (cx->requestDepth)
rt->requestCount++;
JS_UNLOCK_GC(rt);
return;
}
/* No other thread is in GC, so indicate that we're now in GC. */
rt->gcLevel = 1;
/* Also indicate that GC is active on this context. */
cx->gcActive = JS_TRUE;
/* Wait for all other requests to finish. */
while (rt->requestCount > 0)
JS_AWAIT_REQUEST_DONE(rt);
#else /* !JS_THREADSAFE */
/* Bump gcLevel and return rather than nest; the outer gc will restart. */
rt->gcLevel++;
METER(if (rt->gcLevel > rt->gcStats.maxlevel)
rt->gcStats.maxlevel = rt->gcLevel);
if (rt->gcLevel > 1)
return;
#endif /* !JS_THREADSAFE */
/* Drop atoms held by the property cache, and clear property weak links. */
js_FlushPropertyCache(cx);
restart:
rt->gcNumber++;
/* Mark phase. */
JS_HashTableEnumerateEntries(rt->gcRootsHash, gc_root_marker, rt);
js_MarkAtomState(&rt->atomState, gc_mark);
iter = NULL;
while ((acx = js_ContextIterator(rt, &iter)) != NULL) {
/*
* Iterate frame chain and dormant chains. Temporarily tack current
* frame onto the head of the dormant list to ease iteration.
*
* (NOTE: see comment on this whole 'dormant' thing in js_Execute)
*/
chain = acx->fp;
if (chain) {
JS_ASSERT(!chain->dormantNext);
chain->dormantNext = acx->dormantFrameChain;
} else {
chain = acx->dormantFrameChain;
}
for (fp=chain; fp; fp = chain = chain->dormantNext) {
sp = fp->sp;
if (sp) {
for (a = acx->stackPool.first.next; a; a = a->next) {
begin = a->base;
end = a->avail;
if (JS_UPTRDIFF(sp, begin) < JS_UPTRDIFF(end, begin))
end = (jsuword)sp;
for (vp = (jsval *)begin; vp < (jsval *)end; vp++) {
v = *vp;
if (JSVAL_IS_GCTHING(v))
GC_MARK(rt, JSVAL_TO_GCTHING(v), "stack", NULL);
}
if (end == (jsuword)sp)
break;
}
}
do {
GC_MARK(rt, fp->scopeChain, "scope chain", NULL);
GC_MARK(rt, fp->thisp, "this", NULL);
if (JSVAL_IS_GCTHING(fp->rval))
GC_MARK(rt, JSVAL_TO_GCTHING(fp->rval), "rval", NULL);
if (fp->callobj)
GC_MARK(rt, fp->callobj, "call object", NULL);
if (fp->argsobj)
GC_MARK(rt, fp->argsobj, "arguments object", NULL);
if (fp->script)
GC_MARK_SCRIPT(rt, fp->script, NULL);
if (fp->sharpArray)
GC_MARK(rt, fp->sharpArray, "sharp array", NULL);
} while ((fp = fp->down) != NULL);
}
/* cleanup temporary link */
if (acx->fp)
acx->fp->dormantNext = NULL;
GC_MARK(rt, acx->globalObject, "global object", NULL);
GC_MARK(rt, acx->newborn[GCX_OBJECT], "newborn object", NULL);
GC_MARK(rt, acx->newborn[GCX_STRING], "newborn string", NULL);
GC_MARK(rt, acx->newborn[GCX_DOUBLE], "newborn double", NULL);
#if JS_HAS_EXCEPTIONS
if (acx->throwing && JSVAL_IS_GCTHING(acx->exception))
GC_MARK(rt, JSVAL_TO_GCTHING(acx->exception), "exception", NULL);
#endif
}
/* Sweep phase. Mark in tempPool for release at label out:. */
ma = cx->tempPool.current;
mark = JS_ARENA_MARK(&cx->tempPool);
js_SweepAtomState(&rt->atomState);
fa = rt->gcFlagsPool.first.next;
flagp = (uint8 *)fa->base;
for (a = rt->gcArenaPool.first.next; a; a = a->next) {
for (thing = (JSGCThing *)a->base; thing < (JSGCThing *)a->avail;
thing++) {
if (flagp >= (uint8 *)fa->avail) {
fa = fa->next;
JS_ASSERT(fa);
if (!fa) {
METER(rt->gcStats.badflag++);
goto out;
}
flagp = (uint8 *)fa->base;
}
flags = *flagp;
if (flags & GCF_MARK) {
*flagp &= ~GCF_MARK;
} else if (!(flags & (GCF_LOCKMASK | GCF_FINAL))) {
JS_ARENA_ALLOCATE(final, &cx->tempPool, sizeof(JSGCThing));
if (!final)
goto out;
final->next = thing;
final->flagp = flagp;
JS_ASSERT(rt->gcBytes >= sizeof(JSGCThing) + sizeof(uint8));
rt->gcBytes -= sizeof(JSGCThing) + sizeof(uint8);
}
flagp++;
}
}
/* Finalize phase. Don't hold the GC lock while running finalizers! */
JS_UNLOCK_GC(rt);
for (final = mark; ; final++) {
if ((jsuword)final >= ma->avail) {
ma = ma->next;
if (!ma)
break;
final = (JSGCThing *)ma->base;
}
thing = final->next;
flagp = final->flagp;
flags = *flagp;
finalizer = gc_finalizers[flags & GCF_TYPEMASK];
if (finalizer) {
*flagp |= GCF_FINAL;
finalizer(cx, thing);
}
/*
* Set flags to GCF_FINAL, signifying that thing is free, but don't
* thread thing onto rt->gcFreeList. We need the GC lock to rebuild
* the freelist below while also looking for free-able arenas.
*/
*flagp = GCF_FINAL;
}
JS_LOCK_GC(rt);
/* Free unused arenas and rebuild the freelist. */
ap = &rt->gcArenaPool.first.next;
a = *ap;
if (!a)
goto out;
thing = (JSGCThing *)a->base;
a_all_clear = f_all_clear = JS_TRUE;
flp = oflp = &rt->gcFreeList;
*flp = NULL;
METER(rt->gcStats.freelen = 0);
fap = &rt->gcFlagsPool.first.next;
while ((fa = *fap) != NULL) {
/* XXX optimize by unrolling to use word loads */
for (flagp = (uint8 *)fa->base; ; flagp++) {
JS_ASSERT(a);
if (!a) {
METER(rt->gcStats.badarena++);
goto out;
}
if (thing >= (JSGCThing *)a->avail) {
if (a_all_clear) {
JS_ARENA_DESTROY(&rt->gcArenaPool, a, ap);
flp = oflp;
METER(rt->gcStats.afree++);
} else {
ap = &a->next;
a_all_clear = JS_TRUE;
oflp = flp;
}
a = *ap;
if (!a)
break;
thing = (JSGCThing *)a->base;
}
if (flagp >= (uint8 *)fa->avail)
break;
if (*flagp != GCF_FINAL) {
a_all_clear = f_all_clear = JS_FALSE;
} else {
thing->flagp = flagp;
*flp = thing;
flp = &thing->next;
METER(rt->gcStats.freelen++);
}
thing++;
}
if (f_all_clear) {
JS_ARENA_DESTROY(&rt->gcFlagsPool, fa, fap);
METER(rt->gcStats.fafree++);
} else {
fap = &fa->next;
f_all_clear = JS_TRUE;
}
}
/* Terminate the new freelist. */
*flp = NULL;
out:
JS_ARENA_RELEASE(&cx->tempPool, mark);
if (rt->gcLevel > 1) {
rt->gcLevel = 1;
goto restart;
}
rt->gcLevel = 0;
rt->gcLastBytes = rt->gcBytes;
#ifdef JS_THREADSAFE
/* If we were invoked during a request, undo the temporary decrement. */
if (cx->requestDepth)
rt->requestCount++;
cx->gcActive = JS_FALSE;
JS_NOTIFY_GC_DONE(rt);
JS_UNLOCK_GC(rt);
#endif
if (rt->gcCallback)
(void) rt->gcCallback(cx, JSGC_END);
}

110
mozilla/js/src/jsgc.h Normal file
View File

@@ -0,0 +1,110 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsgc_h___
#define jsgc_h___
/*
* JS Garbage Collector.
*/
#include "jspubtd.h"
JS_BEGIN_EXTERN_C
/* GC thing type indexes. */
#define GCX_OBJECT 0 /* JSObject */
#define GCX_STRING 1 /* JSString */
#define GCX_DOUBLE 2 /* jsdouble */
#define GCX_DECIMAL 3 /* JSDecimal */
#define GCX_NTYPES 4
/* GC flag definitions (type index goes in low bits). */
#define GCF_TYPEMASK JS_BITMASK(2) /* use low bits for type */
#define GCF_MARK JS_BIT(2) /* mark bit */
#define GCF_FINAL JS_BIT(3) /* in finalization bit */
#define GCF_LOCKBIT 4 /* lock bit shift and mask */
#define GCF_LOCKMASK (JS_BITMASK(4) << GCF_LOCKBIT)
#define GCF_LOCK JS_BIT(GCF_LOCKBIT) /* lock request bit in API */
#if 1
/*
* Since we're forcing a GC from JS_GC anyway, don't bother wasting cycles
* loading oldval. XXX remove implied force, poke in addroot/removeroot, &c
*/
#define GC_POKE(cx, oldval) ((cx)->runtime->gcPoke = JS_TRUE)
#else
#define GC_POKE(cx, oldval) ((cx)->runtime->gcPoke = JSVAL_IS_GCTHING(oldval))
#endif
extern JSBool
js_InitGC(JSRuntime *rt, uint32 maxbytes);
extern void
js_FinishGC(JSRuntime *rt);
extern JSBool
js_AddRoot(JSContext *cx, void *rp, const char *name);
extern JSBool
js_RemoveRoot(JSContext *cx, void *rp);
extern void *
js_AllocGCThing(JSContext *cx, uintN flags);
extern JSBool
js_LockGCThing(JSContext *cx, void *thing);
extern JSBool
js_UnlockGCThing(JSContext *cx, void *thing);
extern JS_FRIEND_API(void)
js_ForceGC(JSContext *cx);
extern void
js_GC(JSContext *cx);
#ifdef JS_GCMETER
typedef struct JSGCStats {
uint32 alloc; /* number of allocation attempts */
uint32 freelen; /* gcFreeList length */
uint32 recycle; /* number of things recycled through gcFreeList */
uint32 retry; /* allocation attempt retries after running the GC */
uint32 fail; /* allocation failures */
uint32 lock; /* valid lock calls */
uint32 unlock; /* valid unlock calls */
uint32 stuck; /* stuck reference counts seen by lock calls */
uint32 unstuck; /* unlock calls that saw a stuck lock count */
uint32 depth; /* mark recursion depth */
uint32 maxdepth; /* maximum mark recursion depth */
uint32 maxlevel; /* maximum GC nesting (indirect recursion) level */
uint32 poke; /* number of potentially useful GC calls */
uint32 nopoke; /* useless GC calls where js_PokeGC was not set */
uint32 badarena; /* thing arena corruption */
uint32 badflag; /* flags arena corruption */
uint32 afree; /* thing arenas freed so far */
uint32 fafree; /* flags arenas freed so far */
} JSGCStats;
extern void
js_DumpGCStats(JSRuntime *rt, FILE *fp);
#endif /* JS_GCMETER */
JS_END_EXTERN_C
#endif /* jsgc_h___ */

450
mozilla/js/src/jshash.c Normal file
View File

@@ -0,0 +1,450 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* PR hash table package.
*/
#include <stdlib.h>
#include <string.h>
#include "jstypes.h"
#include "jsbit.h"
#include "jsutil.h" /* Added by JSIFY */
#include "jshash.h" /* Added by JSIFY */
/* Compute the number of buckets in ht */
#define NBUCKETS(ht) JS_BIT(JS_HASH_BITS - (ht)->shift)
/* The smallest table has 16 buckets */
#define MINBUCKETSLOG2 4
#define MINBUCKETS JS_BIT(MINBUCKETSLOG2)
/* Compute the maximum entries given n buckets that we will tolerate, ~90% */
#define OVERLOADED(n) ((n) - ((n) >> 3))
/* Compute the number of entries below which we shrink the table by half */
#define UNDERLOADED(n) (((n) > MINBUCKETS) ? ((n) >> 2) : 0)
/*
** Stubs for default hash allocator ops.
*/
static void *
DefaultAllocTable(void *pool, size_t size)
{
return malloc(size);
}
static void
DefaultFreeTable(void *pool, void *item)
{
free(item);
}
static JSHashEntry *
DefaultAllocEntry(void *pool, const void *key)
{
return malloc(sizeof(JSHashEntry));
}
static void
DefaultFreeEntry(void *pool, JSHashEntry *he, uintN flag)
{
if (flag == HT_FREE_ENTRY)
free(he);
}
static JSHashAllocOps defaultHashAllocOps = {
DefaultAllocTable, DefaultFreeTable,
DefaultAllocEntry, DefaultFreeEntry
};
JS_EXPORT_API(JSHashTable *)
JS_NewHashTable(uint32 n, JSHashFunction keyHash,
JSHashComparator keyCompare, JSHashComparator valueCompare,
JSHashAllocOps *allocOps, void *allocPriv)
{
JSHashTable *ht;
size_t nb;
if (n <= MINBUCKETS) {
n = MINBUCKETSLOG2;
} else {
n = JS_CeilingLog2(n);
if ((int32)n < 0)
return NULL;
}
if (!allocOps) allocOps = &defaultHashAllocOps;
ht = (*allocOps->allocTable)(allocPriv, sizeof *ht);
if (!ht)
return NULL;
memset(ht, 0, sizeof *ht);
ht->shift = JS_HASH_BITS - n;
n = JS_BIT(n);
#if defined(XP_PC) && defined _MSC_VER && _MSC_VER <= 800
if (n > 16000) {
(*allocOps->freeTable)(allocPriv, ht);
return NULL;
}
#endif /* WIN16 */
nb = n * sizeof(JSHashEntry *);
ht->buckets = (*allocOps->allocTable)(allocPriv, nb);
if (!ht->buckets) {
(*allocOps->freeTable)(allocPriv, ht);
return NULL;
}
memset(ht->buckets, 0, nb);
ht->keyHash = keyHash;
ht->keyCompare = keyCompare;
ht->valueCompare = valueCompare;
ht->allocOps = allocOps;
ht->allocPriv = allocPriv;
return ht;
}
JS_EXPORT_API(void)
JS_HashTableDestroy(JSHashTable *ht)
{
uint32 i, n;
JSHashEntry *he, *next;
JSHashAllocOps *allocOps = ht->allocOps;
void *allocPriv = ht->allocPriv;
n = NBUCKETS(ht);
for (i = 0; i < n; i++) {
for (he = ht->buckets[i]; he; he = next) {
next = he->next;
(*allocOps->freeEntry)(allocPriv, he, HT_FREE_ENTRY);
}
}
#ifdef DEBUG
memset(ht->buckets, 0xDB, n * sizeof ht->buckets[0]);
#endif
(*allocOps->freeTable)(allocPriv, ht->buckets);
#ifdef DEBUG
memset(ht, 0xDB, sizeof *ht);
#endif
(*allocOps->freeTable)(allocPriv, ht);
}
/*
** Multiplicative hash, from Knuth 6.4.
*/
JS_EXPORT_API(JSHashEntry **)
JS_HashTableRawLookup(JSHashTable *ht, JSHashNumber keyHash, const void *key)
{
JSHashEntry *he, **hep, **hep0;
JSHashNumber h;
#ifdef HASHMETER
ht->nlookups++;
#endif
h = keyHash * JS_GOLDEN_RATIO;
h >>= ht->shift;
hep = hep0 = &ht->buckets[h];
while ((he = *hep) != NULL) {
if (he->keyHash == keyHash && (*ht->keyCompare)(key, he->key)) {
/* Move to front of chain if not already there */
if (hep != hep0) {
*hep = he->next;
he->next = *hep0;
*hep0 = he;
}
return hep0;
}
hep = &he->next;
#ifdef HASHMETER
ht->nsteps++;
#endif
}
return hep;
}
JS_EXPORT_API(JSHashEntry *)
JS_HashTableRawAdd(JSHashTable *ht, JSHashEntry **hep,
JSHashNumber keyHash, const void *key, void *value)
{
uint32 i, n;
JSHashEntry *he, *next, **oldbuckets;
size_t nb;
/* Grow the table if it is overloaded */
n = NBUCKETS(ht);
if (ht->nentries >= OVERLOADED(n)) {
#ifdef HASHMETER
ht->ngrows++;
#endif
ht->shift--;
oldbuckets = ht->buckets;
#if defined(XP_PC) && defined _MSC_VER && _MSC_VER <= 800
if (2 * n > 16000)
return NULL;
#endif /* WIN16 */
nb = 2 * n * sizeof(JSHashEntry *);
ht->buckets = (*ht->allocOps->allocTable)(ht->allocPriv, nb);
if (!ht->buckets) {
ht->buckets = oldbuckets;
return NULL;
}
memset(ht->buckets, 0, nb);
for (i = 0; i < n; i++) {
for (he = oldbuckets[i]; he; he = next) {
next = he->next;
hep = JS_HashTableRawLookup(ht, he->keyHash, he->key);
JS_ASSERT(*hep == NULL);
he->next = NULL;
*hep = he;
}
}
#ifdef DEBUG
memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]);
#endif
(*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets);
hep = JS_HashTableRawLookup(ht, keyHash, key);
}
/* Make a new key value entry */
he = (*ht->allocOps->allocEntry)(ht->allocPriv, key);
if (!he)
return NULL;
he->keyHash = keyHash;
he->key = key;
he->value = value;
he->next = *hep;
*hep = he;
ht->nentries++;
return he;
}
JS_EXPORT_API(JSHashEntry *)
JS_HashTableAdd(JSHashTable *ht, const void *key, void *value)
{
JSHashNumber keyHash;
JSHashEntry *he, **hep;
keyHash = (*ht->keyHash)(key);
hep = JS_HashTableRawLookup(ht, keyHash, key);
if ((he = *hep) != NULL) {
/* Hit; see if values match */
if ((*ht->valueCompare)(he->value, value)) {
/* key,value pair is already present in table */
return he;
}
if (he->value)
(*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_VALUE);
he->value = value;
return he;
}
return JS_HashTableRawAdd(ht, hep, keyHash, key, value);
}
JS_EXPORT_API(void)
JS_HashTableRawRemove(JSHashTable *ht, JSHashEntry **hep, JSHashEntry *he)
{
uint32 i, n;
JSHashEntry *next, **oldbuckets;
size_t nb;
*hep = he->next;
(*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_ENTRY);
/* Shrink table if it's underloaded */
n = NBUCKETS(ht);
if (--ht->nentries < UNDERLOADED(n)) {
#ifdef HASHMETER
ht->nshrinks++;
#endif
ht->shift++;
oldbuckets = ht->buckets;
nb = n * sizeof(JSHashEntry*) / 2;
ht->buckets = (*ht->allocOps->allocTable)(ht->allocPriv, nb);
if (!ht->buckets) {
ht->buckets = oldbuckets;
return;
}
memset(ht->buckets, 0, nb);
for (i = 0; i < n; i++) {
for (he = oldbuckets[i]; he; he = next) {
next = he->next;
hep = JS_HashTableRawLookup(ht, he->keyHash, he->key);
JS_ASSERT(*hep == NULL);
he->next = NULL;
*hep = he;
}
}
#ifdef DEBUG
memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]);
#endif
(*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets);
}
}
JS_EXPORT_API(JSBool)
JS_HashTableRemove(JSHashTable *ht, const void *key)
{
JSHashNumber keyHash;
JSHashEntry *he, **hep;
keyHash = (*ht->keyHash)(key);
hep = JS_HashTableRawLookup(ht, keyHash, key);
if ((he = *hep) == NULL)
return JS_FALSE;
/* Hit; remove element */
JS_HashTableRawRemove(ht, hep, he);
return JS_TRUE;
}
JS_EXPORT_API(void *)
JS_HashTableLookup(JSHashTable *ht, const void *key)
{
JSHashNumber keyHash;
JSHashEntry *he, **hep;
keyHash = (*ht->keyHash)(key);
hep = JS_HashTableRawLookup(ht, keyHash, key);
if ((he = *hep) != NULL) {
return he->value;
}
return NULL;
}
/*
** Iterate over the entries in the hash table calling func for each
** entry found. Stop if "f" says to (return value & JS_ENUMERATE_STOP).
** Return a count of the number of elements scanned.
*/
JS_EXPORT_API(int)
JS_HashTableEnumerateEntries(JSHashTable *ht, JSHashEnumerator f, void *arg)
{
JSHashEntry *he, **hep;
uint32 i, nbuckets;
int rv, n = 0;
JSHashEntry *todo = NULL;
nbuckets = NBUCKETS(ht);
for (i = 0; i < nbuckets; i++) {
hep = &ht->buckets[i];
while ((he = *hep) != NULL) {
rv = (*f)(he, n, arg);
n++;
if (rv & (HT_ENUMERATE_REMOVE | HT_ENUMERATE_UNHASH)) {
*hep = he->next;
if (rv & HT_ENUMERATE_REMOVE) {
he->next = todo;
todo = he;
}
} else {
hep = &he->next;
}
if (rv & HT_ENUMERATE_STOP) {
goto out;
}
}
}
out:
hep = &todo;
while ((he = *hep) != NULL) {
JS_HashTableRawRemove(ht, hep, he);
}
return n;
}
#ifdef HASHMETER
#include <math.h>
#include <stdio.h>
JS_EXPORT_API(void)
JS_HashTableDumpMeter(JSHashTable *ht, JSHashEnumerator dump, FILE *fp)
{
double mean, variance;
uint32 nchains, nbuckets;
uint32 i, n, maxChain, maxChainLen;
JSHashEntry *he;
variance = 0;
nchains = 0;
maxChainLen = 0;
nbuckets = NBUCKETS(ht);
for (i = 0; i < nbuckets; i++) {
he = ht->buckets[i];
if (!he)
continue;
nchains++;
for (n = 0; he; he = he->next)
n++;
variance += n * n;
if (n > maxChainLen) {
maxChainLen = n;
maxChain = i;
}
}
mean = (double)ht->nentries / nchains;
variance = fabs(variance / nchains - mean * mean);
fprintf(fp, "\nHash table statistics:\n");
fprintf(fp, " number of lookups: %u\n", ht->nlookups);
fprintf(fp, " number of entries: %u\n", ht->nentries);
fprintf(fp, " number of grows: %u\n", ht->ngrows);
fprintf(fp, " number of shrinks: %u\n", ht->nshrinks);
fprintf(fp, " mean steps per hash: %g\n", (double)ht->nsteps
/ ht->nlookups);
fprintf(fp, "mean hash chain length: %g\n", mean);
fprintf(fp, " standard deviation: %g\n", sqrt(variance));
fprintf(fp, " max hash chain length: %u\n", maxChainLen);
fprintf(fp, " max hash chain: [%u]\n", maxChain);
for (he = ht->buckets[maxChain], i = 0; he; he = he->next, i++)
if ((*dump)(he, i, fp) != HT_ENUMERATE_NEXT)
break;
}
#endif /* HASHMETER */
JS_EXPORT_API(int)
JS_HashTableDump(JSHashTable *ht, JSHashEnumerator dump, FILE *fp)
{
int count;
count = JS_HashTableEnumerateEntries(ht, dump, fp);
#ifdef HASHMETER
JS_HashTableDumpMeter(ht, dump, fp);
#endif
return count;
}
JS_EXPORT_API(JSHashNumber)
JS_HashString(const void *key)
{
JSHashNumber h;
const unsigned char *s;
h = 0;
for (s = key; *s; s++)
h = (h >> 28) ^ (h << 4) ^ *s;
return h;
}
JS_EXPORT_API(int)
JS_CompareValues(const void *v1, const void *v2)
{
return v1 == v2;
}

131
mozilla/js/src/jshash.h Normal file
View File

@@ -0,0 +1,131 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jshash_h___
#define jshash_h___
/*
* API to portable hash table code.
*/
#include <stddef.h>
#include <stdio.h>
#include "jstypes.h"
#include "jscompat.h"
JS_BEGIN_EXTERN_C
typedef uint32 JSHashNumber;
typedef struct JSHashEntry JSHashEntry;
typedef struct JSHashTable JSHashTable;
#define JS_HASH_BITS 32
#define JS_GOLDEN_RATIO 0x9E3779B9U
typedef JSHashNumber (*JSHashFunction)(const void *key);
typedef intN (*JSHashComparator)(const void *v1, const void *v2);
typedef intN (*JSHashEnumerator)(JSHashEntry *he, intN i, void *arg);
/* Flag bits in JSHashEnumerator's return value */
#define HT_ENUMERATE_NEXT 0 /* continue enumerating entries */
#define HT_ENUMERATE_STOP 1 /* stop enumerating entries */
#define HT_ENUMERATE_REMOVE 2 /* remove and free the current entry */
#define HT_ENUMERATE_UNHASH 4 /* just unhash the current entry */
typedef struct JSHashAllocOps {
void * (*allocTable)(void *pool, size_t size);
void (*freeTable)(void *pool, void *item);
JSHashEntry * (*allocEntry)(void *pool, const void *key);
void (*freeEntry)(void *pool, JSHashEntry *he, uintN flag);
} JSHashAllocOps;
#define HT_FREE_VALUE 0 /* just free the entry's value */
#define HT_FREE_ENTRY 1 /* free value and entire entry */
struct JSHashEntry {
JSHashEntry *next; /* hash chain linkage */
JSHashNumber keyHash; /* key hash function result */
const void *key; /* ptr to opaque key */
void *value; /* ptr to opaque value */
};
struct JSHashTable {
JSHashEntry **buckets; /* vector of hash buckets */
uint32 nentries; /* number of entries in table */
uint32 shift; /* multiplicative hash shift */
JSHashFunction keyHash; /* key hash function */
JSHashComparator keyCompare; /* key comparison function */
JSHashComparator valueCompare; /* value comparison function */
JSHashAllocOps *allocOps; /* allocation operations */
void *allocPriv; /* allocation private data */
#ifdef HASHMETER
uint32 nlookups; /* total number of lookups */
uint32 nsteps; /* number of hash chains traversed */
uint32 ngrows; /* number of table expansions */
uint32 nshrinks; /* number of table contractions */
#endif
};
/*
* Create a new hash table.
* If allocOps is null, use default allocator ops built on top of malloc().
*/
JS_EXTERN_API(JSHashTable *)
JS_NewHashTable(uint32 n, JSHashFunction keyHash,
JSHashComparator keyCompare, JSHashComparator valueCompare,
JSHashAllocOps *allocOps, void *allocPriv);
JS_EXTERN_API(void)
JS_HashTableDestroy(JSHashTable *ht);
/* Low level access methods */
JS_EXTERN_API(JSHashEntry **)
JS_HashTableRawLookup(JSHashTable *ht, JSHashNumber keyHash, const void *key);
JS_EXTERN_API(JSHashEntry *)
JS_HashTableRawAdd(JSHashTable *ht, JSHashEntry **hep, JSHashNumber keyHash,
const void *key, void *value);
JS_EXTERN_API(void)
JS_HashTableRawRemove(JSHashTable *ht, JSHashEntry **hep, JSHashEntry *he);
/* Higher level access methods */
JS_EXTERN_API(JSHashEntry *)
JS_HashTableAdd(JSHashTable *ht, const void *key, void *value);
JS_EXTERN_API(JSBool)
JS_HashTableRemove(JSHashTable *ht, const void *key);
JS_EXTERN_API(intN)
JS_HashTableEnumerateEntries(JSHashTable *ht, JSHashEnumerator f, void *arg);
JS_EXTERN_API(void *)
JS_HashTableLookup(JSHashTable *ht, const void *key);
JS_EXTERN_API(intN)
JS_HashTableDump(JSHashTable *ht, JSHashEnumerator dump, FILE *fp);
/* General-purpose C string hash function. */
JS_EXTERN_API(JSHashNumber)
JS_HashString(const void *key);
/* Stub function just returns v1 == v2 */
JS_EXTERN_API(intN)
JS_CompareValues(const void *v1, const void *v2);
JS_END_EXTERN_C
#endif /* jshash_h___ */

485
mozilla/js/src/jsify.pl Normal file
View File

@@ -0,0 +1,485 @@
#!/usr/local/bin/perl
# This script modifies C code to use the hijacked NSPR routines that are
# now baked into the JavaScript engine rather than using the NSPR
# routines that they were based on, i.e. types like PRArenaPool are changed
# to JSArenaPool.
#
# This script was used in 9/98 to facilitate the incorporation of some NSPR
# code into the JS engine so as to minimize dependency on NSPR.
#
# Command-line: jsify.pl [options] [filename]*
#
# Options:
# -r Reverse direction of transformation, i.e. JS ==> NSPR2
# -outdir Directory in which to place output files
# NSPR2 symbols that will be modified to JS symbols, e.g.
# PRArena <==> JSArena
@NSPR_symbols = (
"PRArena",
"PRArenaPool",
"PRArenaStats",
"PR_ARENAMETER",
"PR_ARENA_",
"PR_ARENA_ALIGN",
"PR_ARENA_ALLOCATE",
"PR_ARENA_CONST_ALIGN_MASK",
"PR_ARENA_DEFAULT_ALIGN",
"PR_ARENA_DESTROY",
"PR_ARENA_GROW",
"PR_ARENA_MARK",
"PR_ARENA_RELEASE",
"PR_smprintf",
"PR_smprintf_free",
"PR_snprintf",
"PR_sprintf_append",
"PR_sscanf",
"PR_sxprintf",
"PR_vsmprintf",
"PR_vsnprintf",
"PR_vsprintf_append",
"PR_vsxprintf",
"PRCList",
"PRCListStr",
"PRCLists",
"PRDestroyEventProc",
"PREvent",
"PREventFunProc",
"PREventQueue",
"PRHandleEventProc",
"PR_PostEvent",
"PR_PostSynchronousEvent",
"PR_ProcessPendingEvents",
"PR_CreateEventQueue",
"PR_DequeueEvent",
"PR_DestroyEvent",
"PR_DestroyEventQueue",
"PR_EventAvailable",
"PR_EventLoop",
"PR_GetEvent",
"PR_GetEventOwner",
"PR_GetEventQueueMonitor",
"PR_GetEventQueueSelectFD",
"PR_GetMainEventQueue",
"PR_HandleEvent",
"PR_InitEvent",
"PR_ENTER_EVENT_QUEUE_MONITOR",
"PR_EXIT_EVENT_QUEUE_MONITOR",
"PR_MapEvents",
"PR_RevokeEvents",
"PR_cnvtf",
"PR_dtoa",
"PR_strtod",
"PRFileDesc",
"PR_HASH_BITS",
"PR_GOLDEN_RATIO",
"PRHashAllocOps",
"PRHashComparator",
"PRHashEntry",
"PRHashEnumerator",
"PRHashFunction",
"PRHashNumber",
"PRHashTable",
"PR_HashString",
"PR_HashTableAdd",
"PR_HashTableDestroy",
"PR_HashTableDump",
"PR_HashTableEnumerateEntries",
"PR_HashTableLookup",
"PR_HashTableRawAdd",
"PR_HashTableRawLookup",
"PR_HashTableRawRemove",
"PR_HashTableRemove",
"PRBool",
"PRFloat64",
"PRInt16",
"PRInt32",
"PRInt64",
"PRInt8",
"PRIntn",
"PRUint16",
"PRUint32",
"PRUint64",
"PRUint8",
"PRUintn",
"PRPtrDiff",
"PRPtrdiff",
"PRUptrdiff",
"PRUword",
"PRWord",
"PRPackedBool",
"PRSize",
"PRStatus",
"pruword",
"prword",
"prword_t",
"PR_ALIGN_OF_DOUBLE",
"PR_ALIGN_OF_FLOAT",
"PR_ALIGN_OF_INT",
"PR_ALIGN_OF_INT64",
"PR_ALIGN_OF_LONG",
"PR_ALIGN_OF_POINTER",
"PR_ALIGN_OF_SHORT",
"PR_ALIGN_OF_WORD",
"PR_BITS_PER_BYTE",
"PR_BITS_PER_BYTE_LOG2",
"PR_BITS_PER_DOUBLE",
"PR_BITS_PER_DOUBLE_LOG2",
"PR_BITS_PER_FLOAT",
"PR_BITS_PER_FLOAT_LOG2",
"PR_BITS_PER_INT",
"PR_BITS_PER_INT64",
"PR_BITS_PER_INT64_LOG2",
"PR_BITS_PER_INT_LOG2",
"PR_BITS_PER_LONG",
"PR_BITS_PER_LONG_LOG2",
"PR_BITS_PER_SHORT",
"PR_BITS_PER_SHORT_LOG2",
"PR_BITS_PER_WORD",
"PR_BITS_PER_WORD_LOG2",
"PR_BYTES_PER_BYTE",
"PR_BYTES_PER_DOUBLE",
"PR_BYTES_PER_DWORD",
"PR_BYTES_PER_DWORD_LOG2",
"PR_BYTES_PER_FLOAT",
"PR_BYTES_PER_INT",
"PR_BYTES_PER_INT64",
"PR_BYTES_PER_LONG",
"PR_BYTES_PER_SHORT",
"PR_BYTES_PER_WORD",
"PR_BYTES_PER_WORD_LOG2",
"PRSegment",
"PRSegmentAccess",
"PRStuffFunc",
"PRThread",
"PR_APPEND_LINK",
"PR_ASSERT",
"PR_ATOMIC_DWORD_LOAD",
"PR_ATOMIC_DWORD_STORE",
"PR_Abort",
"PR_ArenaAllocate",
"PR_ArenaCountAllocation",
"PR_ArenaCountGrowth",
"PR_ArenaCountInplaceGrowth",
"PR_ArenaCountRelease",
"PR_ArenaCountRetract",
"PR_ArenaFinish",
"PR_ArenaGrow",
"PR_ArenaRelease",
"PR_CompactArenaPool",
"PR_DumpArenaStats",
"PR_FinishArenaPool",
"PR_FreeArenaPool",
"PR_InitArenaPool",
"PR_Assert",
"PR_AttachThread",
"PR_BEGIN_EXTERN_C",
"PR_BEGIN_MACRO",
"PR_BIT",
"PR_BITMASK",
"PR_BUFFER_OVERFLOW_ERROR",
"PR_CALLBACK",
"PR_CALLBACK_DECL",
"PR_CALLOC",
"PR_CEILING_LOG2",
"PR_CLEAR_ARENA",
"PR_CLEAR_BIT",
"PR_CLEAR_UNUSED",
"PR_CLIST_IS_EMPTY",
"PR_COUNT_ARENA",
"PR_CURRENT_THREAD",
"PR_GetSegmentAccess",
"PR_GetSegmentSize",
"PR_GetSegmentVaddr",
"PR_GrowSegment",
"PR_DestroySegment",
"PR_MapSegment",
"PR_NewSegment",
"PR_Segment",
"PR_Seg",
"PR_SEGMENT_NONE",
"PR_SEGMENT_RDONLY",
"PR_SEGMENT_RDWR",
"PR_Calloc",
"PR_CeilingLog2",
"PR_CompareStrings",
"PR_CompareValues",
"PR_DELETE",
"PR_END_EXTERN_C",
"PR_END_MACRO",
"PR_ENUMERATE_STOP",
"PR_FAILURE",
"PR_FALSE",
"PR_FLOOR_LOG2",
"PR_FREEIF",
"PR_FREE_PATTERN",
"PR_FloorLog2",
"PR_FormatTime",
"PR_Free",
"PR_GetEnv",
"PR_GetError",
"PR_INIT_ARENA_POOL",
"PR_INIT_CLIST",
"PR_INIT_STATIC_CLIST",
"PR_INLINE",
"PR_INSERT_AFTER",
"PR_INSERT_BEFORE",
"PR_INSERT_LINK",
"PR_INT32",
"PR_INTERVAL_NO_TIMEOUT",
"PR_INTERVAL_NO_WAIT",
"PR_Init",
"PR_LIST_HEAD",
"PR_LIST_TAIL",
"PR_LOG",
"PR_LOGGING",
"PR_LOG_ALWAYS",
"PR_LOG_BEGIN",
"PR_LOG_DEBUG",
"PR_LOG_DEFINE",
"PR_LOG_END",
"PR_LOG_ERROR",
"PR_LOG_MAX",
"PR_LOG_MIN",
"PR_LOG_NONE",
"PR_LOG_NOTICE",
"PR_LOG_TEST",
"PR_LOG_WARN",
"PR_LOG_WARNING",
"PR_LogFlush",
"PR_LogPrint",
"PR_MALLOC",
"PR_MAX",
"PR_MD_calloc",
"PR_MD_free",
"PR_MD_malloc",
"PR_MD_realloc",
"PR_MIN",
"PR_Malloc",
"PR_NEW",
"PR_NEWZAP",
"PR_NEXT_LINK",
"PR_NOT_REACHED",
"PR_NewCondVar",
"PR_NewHashTable",
"PR_NewLogModule",
"PR_PREV_LINK",
"PR_PUBLIC_API",
"PR_PUBLIC_DATA",
"PR_RANGE_ERROR",
"PR_REALLOC",
"PR_REMOVE_AND_INIT_LINK",
"PR_REMOVE_LINK",
"PR_ROUNDUP",
"PR_Realloc",
"PR_SET_BIT",
"PR_STATIC_CALLBACK",
"PR_SUCCESS",
"PR_SetError",
"PR_SetLogBuffering",
"PR_SetLogFile",
"PR_TEST_BIT",
"PR_TRUE",
"PR_UINT32",
"PR_UPTRDIFF",
"prarena_h___",
"prbit_h___",
"prclist_h___",
"prdtoa_h___",
"prlog_h___",
"prlong_h___",
"prmacos_h___",
"prmem_h___",
"prprf_h___",
"prtypes_h___",
"prarena",
"prbit",
"prbitmap_t",
"prclist",
"prcpucfg",
"prdtoa",
"prhash",
"plhash",
"prlong",
"prmacos",
"prmem",
"prosdep",
"protypes",
"prprf",
"prtypes"
);
while ($ARGV[0] =~ /^-/) {
if ($ARGV[0] eq "-r") {
shift;
$reverse_conversion = 1;
} elsif ($ARGV[0] eq "-outdir") {
shift;
$outdir = shift;
}
}
# Given an NSPR symbol compute the JS equivalent or
# vice-versa
sub subst {
local ($replacement);
local ($sym) = @_;
$replacement = substr($sym,0,2) eq "pr" ? "js" : "JS";
$replacement .= substr($sym, 2);
return $replacement;
}
# Build the regular expression that will convert between the NSPR
# types and the JS types
if ($reverse_conversion) {
die "Not implemented yet";
} else {
foreach $sym (@NSPR_symbols) {
$regexp .= $sym . "|"
}
# Get rid of the last "!"
chop $regexp;
# Replace PR* with JS* and replace pr* with js*
$regexp = 's/(^|\\W)(' . $regexp . ')/$1 . &subst($2)/eg';
# print $regexp;
}
# Pre-compile a little subroutine to perform the regexp substitution
# between NSPR types and JS types
eval('sub convert_from_NSPR {($line) = @_; $line =~ ' . $regexp . ';}');
sub convert_mallocs {
($line) = @_;
$line =~ s/PR_MALLOC/malloc/g;
$line =~ s/PR_REALLOC/realloc/g;
$line =~ s/PR_FREE/free/g;
return $line;
}
sub convert_includes {
($line) = @_;
if ($line !~ /include/) {
return $line;
}
if ($line =~ /prlog\.h/) {
$line = '#include "jsutil.h"'. " /* Added by JSIFY */\n";
} elsif ($line =~ /plhash\.h/) {
$line = '#include "jshash.h"'. " /* Added by JSIFY */\n";
} elsif ($line =~ /plarena\.h/) {
$line = '#include "jsarena.h"'. " /* Added by JSIFY */\n";
} elsif ($line =~ /prmem\.h/) {
$line = "";
} elsif ($line =~ /jsmsg\.def/) {
$line = '#include "js.msg"' . "\n";
} elsif ($line =~ /shellmsg\.def/) {
$line = '#include "jsshell.msg"' . "\n";
} elsif ($line =~ /jsopcode\.def/) {
$line = '#include "jsopcode.tbl"' . "\n";
}
return $line;
}
sub convert_declarations {
($line) = @_;
$line =~ s/PR_EXTERN/JS_EXTERN_API/g;
$line =~ s/PR_IMPLEMENT_DATA/JS_EXPORT_DATA/g;
$line =~ s/PR_IMPLEMENT/JS_EXPORT_API/g;
$line =~ s/PR_CALLBACK/JS_DLL_CALLBACK/g;
$line =~ s/PR_STATIC_CALLBACK/JS_STATIC_DLL_CALLBACK/g;
$line =~ s/PR_IMPORT/JS_IMPORT/g;
$line =~ s/PR_PUBLIC_API/JS_EXPORT_API/g;
$line =~ s/PR_PUBLIC_DATA/JS_EXPORT_DATA/g;
return $line;
}
sub convert_long_long_macros {
($line) = @_;
$line =~ s/\b(LL_)/JSLL_/g;
return $line;
}
sub convert_asserts {
($line) = @_;
$line =~ s/\bPR_ASSERT/JS_ASSERT/g;
return $line;
}
while ($#ARGV >= 0) {
$infile = shift;
# Change filename, e.g. prtime.h to jsprtime.h, except for legacy
# files that start with 'prmj', like prmjtime.h.
$outfile = $infile;
if ($infile !~ /^prmj/) {
$outfile =~ s/^pr/js/;
$outfile =~ s/^pl/js/;
}
if ($outdir) {
$outfile = $outdir . '/' . $outfile;
}
if ($infile eq $outfile) {
die "Error: refuse to overwrite $outfile, use -outdir option."
}
die "Can't open $infile" if !open(INFILE, "<$infile");
die "Can't open $outfile for writing" if !open(OUTFILE, ">$outfile");
while (<INFILE>) {
$line = $_;
#Get rid of #include "prlog.h"
&convert_includes($line);
# Rename PR_EXTERN, PR_IMPORT, etc.
&convert_declarations($line);
# Convert from PR_MALLOC to malloc, etc.
&convert_mallocs($line);
# Convert from PR_ASSERT to JS_ASSERT
# &convert_asserts($line);
# Convert from, e.g. PRArena to JSPRArena
&convert_from_NSPR($line);
# Change LL_* macros to JSLL_*
&convert_long_long_macros($line);
print OUTFILE $line;
}
}

2853
mozilla/js/src/jsinterp.c Normal file

File diff suppressed because it is too large Load Diff

209
mozilla/js/src/jsinterp.h Normal file
View File

@@ -0,0 +1,209 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsinterp_h___
#define jsinterp_h___
/*
* JS interpreter interface.
*/
#include "jsprvtd.h"
#include "jspubtd.h"
/*
* JS stack frame, allocated on the C stack.
*/
struct JSStackFrame {
JSObject *callobj; /* lazily created Call object */
JSObject *argsobj; /* lazily created arguments object */
JSScript *script; /* script being interpreted */
JSFunction *fun; /* function being called or null */
JSObject *thisp; /* "this" pointer if in method */
uintN argc; /* actual argument count */
jsval *argv; /* base of argument stack slots */
jsval rval; /* function return value */
uintN nvars; /* local variable count */
jsval *vars; /* base of variable stack slots */
JSStackFrame *down; /* previous frame */
void *annotation; /* used by Java security */
JSObject *scopeChain; /* scope chain */
jsbytecode *pc; /* program counter */
jsval *sp; /* stack pointer */
uintN sharpDepth; /* array/object initializer depth */
JSObject *sharpArray; /* scope for #n= initializer vars */
JSPackedBool constructing; /* true if called via new operator */
uint8 overrides; /* bit-set of overridden Call properties */
JSPackedBool debugging; /* true if for JS_EvaluateInStackFrame */
JSStackFrame *dormantNext; /* next dormant frame chain */
};
/*
* Property cache for quickened get/set property opcodes.
*/
#define PROPERTY_CACHE_LOG2 10
#define PROPERTY_CACHE_SIZE JS_BIT(PROPERTY_CACHE_LOG2)
#define PROPERTY_CACHE_MASK JS_BITMASK(PROPERTY_CACHE_LOG2)
#define PROPERTY_CACHE_HASH(obj, id) \
((((jsuword)(obj) >> JSVAL_TAGBITS) ^ (jsuword)(id)) & PROPERTY_CACHE_MASK)
#ifdef JS_THREADSAFE
#if HAVE_ATOMIC_DWORD_ACCESS
#define PCE_LOAD(cache, pce, entry) JS_ATOMIC_DWORD_LOAD(pce, entry)
#define PCE_STORE(cache, pce, entry) JS_ATOMIC_DWORD_STORE(pce, entry)
#else /* !HAVE_ATOMIC_DWORD_ACCESS */
#define PCE_LOAD(cache, pce, entry) \
JS_BEGIN_MACRO \
uint32 _prefills; \
uint32 _fills = (cache)->fills; \
do { \
/* Load until cache->fills is stable (see FILL macro below). */ \
_prefills = _fills; \
(entry) = *(pce); \
} while ((_fills = (cache)->fills) != _prefills); \
JS_END_MACRO
#define PCE_STORE(cache, pce, entry) \
JS_BEGIN_MACRO \
do { \
/* Store until no racing collider stores half or all of pce. */ \
*(pce) = (entry); \
} while (PCE_OBJECT(*pce) != PCE_OBJECT(entry) || \
PCE_PROPERTY(*pce) != PCE_PROPERTY(entry)); \
JS_END_MACRO
#endif /* !HAVE_ATOMIC_DWORD_ACCESS */
#else /* !JS_THREADSAFE */
#define PCE_LOAD(cache, pce, entry) ((entry) = *(pce))
#define PCE_STORE(cache, pce, entry) (*(pce) = (entry))
#endif /* !JS_THREADSAFE */
typedef union JSPropertyCacheEntry {
struct {
JSObject *object; /* weak link to object */
JSProperty *property; /* weak link to property, or not-found id */
} s;
#ifdef HAVE_ATOMIC_DWORD_ACCESS
prdword align;
#endif
} JSPropertyCacheEntry;
/* These may be called in lvalue or rvalue position. */
#define PCE_OBJECT(entry) ((entry).s.object)
#define PCE_PROPERTY(entry) ((entry).s.property)
typedef struct JSPropertyCache {
JSPropertyCacheEntry table[PROPERTY_CACHE_SIZE];
JSBool empty;
uint32 fills;
uint32 recycles;
uint32 tests;
uint32 misses;
uint32 flushes;
} JSPropertyCache;
/* Property-not-found lookup results are cached using this invalid pointer. */
#define PROP_NOT_FOUND(obj,id) ((JSProperty *) ((jsword)(id) | 1))
#define PROP_NOT_FOUND_ID(prop) ((jsid) ((jsword)(prop) & ~1))
#define PROP_FOUND(prop) ((prop) && ((jsword)(prop) & 1) == 0)
#define PROPERTY_CACHE_FILL(cx, cache, obj, id, prop) \
JS_BEGIN_MACRO \
uintN _hashIndex = (uintN)PROPERTY_CACHE_HASH(obj, id); \
JSPropertyCache *_cache = (cache); \
JSPropertyCacheEntry *_pce = &_cache->table[_hashIndex]; \
JSPropertyCacheEntry _entry; \
JSProperty *_pce_prop; \
PCE_LOAD(_cache, _pce, _entry); \
_pce_prop = PCE_PROPERTY(_entry); \
if (_pce_prop && _pce_prop != prop) \
_cache->recycles++; \
PCE_OBJECT(_entry) = obj; \
PCE_PROPERTY(_entry) = prop; \
_cache->empty = JS_FALSE; \
_cache->fills++; \
PCE_STORE(_cache, _pce, _entry); \
JS_END_MACRO
#define PROPERTY_CACHE_TEST(cache, obj, id, prop) \
JS_BEGIN_MACRO \
uintN _hashIndex = (uintN)PROPERTY_CACHE_HASH(obj, id); \
JSPropertyCache *_cache = (cache); \
JSPropertyCacheEntry *_pce = &_cache->table[_hashIndex]; \
JSPropertyCacheEntry _entry; \
JSProperty *_pce_prop; \
PCE_LOAD(_cache, _pce, _entry); \
_pce_prop = PCE_PROPERTY(_entry); \
_cache->tests++; \
if (_pce_prop && \
(((jsword)_pce_prop & 1) \
? PROP_NOT_FOUND_ID(_pce_prop) \
: sym_id(((JSScopeProperty *)_pce_prop)->symbols)) == id && \
PCE_OBJECT(_entry) == obj) { \
prop = _pce_prop; \
} else { \
_cache->misses++; \
prop = NULL; \
} \
JS_END_MACRO
extern void
js_FlushPropertyCache(JSContext *cx);
extern void
js_FlushPropertyCacheByProp(JSContext *cx, JSProperty *prop);
extern jsval *
js_AllocStack(JSContext *cx, uintN nslots, void **markp);
extern void
js_FreeStack(JSContext *cx, void *mark);
extern JSBool
js_GetArgument(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
extern JSBool
js_SetArgument(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
extern JSBool
js_GetLocalVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
extern JSBool
js_SetLocalVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
extern JSBool
js_Invoke(JSContext *cx, uintN argc, JSBool constructing);
extern JSBool
js_CallFunctionValue(JSContext *cx, JSObject *obj, jsval fval,
uintN argc, jsval *argv, jsval *rval);
extern JSBool
js_Execute(JSContext *cx, JSObject *chain, JSScript *script, JSFunction *fun,
JSStackFrame *down, JSBool debugging, jsval *result);
extern JSBool
js_Interpret(JSContext *cx, jsval *result);
#endif /* jsinterp_h___ */

272
mozilla/js/src/jslibmath.h Normal file
View File

@@ -0,0 +1,272 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* By default all math calls go to fdlibm. The defines for each platform
* remap the math calls to native routines.
*/
#ifndef _LIBMATH_H
#define _LIBMATH_H
#include <math.h>
#include "jsconfig.h"
/*
* Define which platforms on which to use fdlibm. Not used
* by default since there can be problems with endian-ness and such.
*/
#if defined(_WIN32)
#define JS_USE_FDLIBM_MATH 1
#elif defined(SUNOS4)
#define JS_USE_FDLIBM_MATH 1
#elif defined(IRIX)
#define JS_USE_FDLIBM_MATH 1
#elif defined(SOLARIS)
#define JS_USE_FDLIBM_MATH 1
#elif defined(HPUX)
#define JS_USE_FDLIBM_MATH 1
#elif defined(linux)
#define JS_USE_FDLIBM_MATH 1
#elif defined(OSF1)
/* Want to use some fdlibm functions but fdlibm broken on OSF1/alpha. */
#define JS_USE_FDLIBM_MATH 0
#elif defined(AIX)
#define JS_USE_FDLIBM_MATH 1
#else
#define JS_USE_FDLIBM_MATH 0
#endif
#if !JS_USE_FDLIBM_MATH
/*
* Use system provided math routines.
*/
#define fd_acos acos
#define fd_asin asin
#define fd_atan atan
#define fd_atan2 atan2
#define fd_ceil ceil
#define fd_copysign copysign
#define fd_cos cos
#define fd_exp exp
#define fd_fabs fabs
#define fd_floor floor
#define fd_fmod fmod
#define fd_log log
#define fd_pow pow
#define fd_sin sin
#define fd_sqrt sqrt
#define fd_tan tan
#else
/*
* Use math routines in fdlibm.
*/
#ifdef __STDC__
#define __P(p) p
#else
#define __P(p) ()
#endif
#if defined _WIN32 || defined SUNOS4
#define fd_acos acos
#define fd_asin asin
#define fd_atan atan
#define fd_cos cos
#define fd_sin sin
#define fd_tan tan
#define fd_exp exp
#define fd_log log
#define fd_sqrt sqrt
#define fd_ceil ceil
#define fd_fabs fabs
#define fd_floor floor
#define fd_fmod fmod
extern double fd_atan2 __P((double, double));
extern double fd_copysign __P((double, double));
#ifdef DEBUG
extern double fd_pow __P((double, double));
#else
#define fd_pow pow
#endif
#elif defined IRIX
#define fd_acos acos
#define fd_asin asin
#define fd_atan atan
#define fd_exp exp
#define fd_log log
#define fd_log10 log10
#define fd_sqrt sqrt
#define fd_fabs fabs
#define fd_floor floor
#define fd_fmod fmod
extern double fd_cos __P((double));
extern double fd_sin __P((double));
extern double fd_tan __P((double));
extern double fd_atan2 __P((double, double));
extern double fd_pow __P((double, double));
extern double fd_ceil __P((double));
extern double fd_copysign __P((double, double));
#elif defined SOLARIS
#define fd_atan atan
#define fd_cos cos
#define fd_sin sin
#define fd_tan tan
#define fd_exp exp
#define fd_sqrt sqrt
#define fd_ceil ceil
#define fd_fabs fabs
#define fd_floor floor
#define fd_fmod fmod
extern double fd_acos __P((double));
extern double fd_asin __P((double));
extern double fd_log __P((double));
extern double fd_atan2 __P((double, double));
extern double fd_pow __P((double, double));
extern double fd_copysign __P((double, double));
#elif defined HPUX
#define fd_cos cos
#define fd_sin sin
#define fd_exp exp
#define fd_sqrt sqrt
#define fd_fabs fabs
#define fd_floor floor
#define fd_fmod fmod
extern double fd_ceil __P((double));
extern double fd_acos __P((double));
extern double fd_log __P((double));
extern double fd_atan2 __P((double, double));
extern double fd_tan __P((double));
extern double fd_pow __P((double, double));
extern double fd_asin __P((double));
extern double fd_atan __P((double));
extern double fd_copysign __P((double, double));
#elif defined(linux)
#define fd_atan atan
#define fd_atan2 atan2
#define fd_ceil ceil
#define fd_cos cos
#define fd_fabs fabs
#define fd_floor floor
#define fd_fmod fmod
#define fd_sin sin
#define fd_sqrt sqrt
#define fd_tan tan
extern double fd_asin __P((double));
extern double fd_acos __P((double));
extern double fd_exp __P((double));
extern double fd_log __P((double));
extern double fd_pow __P((double, double));
extern double fd_copysign __P((double, double));
#elif defined(OSF1)
#define fd_acos acos
#define fd_asin asin
#define fd_atan atan
#define fd_copysign copysign
#define fd_cos cos
#define fd_exp exp
#define fd_fabs fabs
#define fd_fmod fmod
#define fd_sin sin
#define fd_sqrt sqrt
#define fd_tan tan
extern double fd_atan2 __P((double, double));
extern double fd_ceil __P((double));
extern double fd_floor __P((double));
extern double fd_log __P((double));
extern double fd_pow __P((double, double));
#elif defined(AIX)
#define fd_acos acos
#define fd_asin asin
#define fd_atan2 atan2
#define fd_copysign copysign
#define fd_cos cos
#define fd_exp exp
#define fd_fabs fabs
#define fd_floor floor
#define fd_fmod fmod
#define fd_log log
#define fd_sin sin
#define fd_sqrt sqrt
extern double fd_atan __P((double));
extern double fd_ceil __P((double));
extern double fd_pow __P((double,double));
extern double fd_tan __P((double));
#else /* other platform.. generic paranoid slow fdlibm */
extern double fd_acos __P((double));
extern double fd_asin __P((double));
extern double fd_atan __P((double));
extern double fd_cos __P((double));
extern double fd_sin __P((double));
extern double fd_tan __P((double));
extern double fd_exp __P((double));
extern double fd_log __P((double));
extern double fd_sqrt __P((double));
extern double fd_ceil __P((double));
extern double fd_fabs __P((double));
extern double fd_floor __P((double));
extern double fd_fmod __P((double, double));
extern double fd_atan2 __P((double, double));
extern double fd_pow __P((double, double));
extern double fd_copysign __P((double, double));
#endif
#endif /* JS_USE_FDLIBM_MATH */
#endif /* _LIBMATH_H */

781
mozilla/js/src/jslock.c Normal file
View File

@@ -0,0 +1,781 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifdef JS_THREADSAFE
/*
* JS locking stubs.
*/
#include "jsstddef.h"
#include <stdlib.h>
#include "jspubtd.h"
#include "prthread.h"
#include "pratom.h"
#include "jsutil.h" /* Added by JSIFY */
#include "jscntxt.h"
#include "jsscope.h"
#include "jspubtd.h"
#include "jslock.h"
static PRLock *_global_lock;
static void
js_LockGlobal()
{
PR_Lock(_global_lock);
}
static void
js_UnlockGlobal()
{
PR_Unlock(_global_lock);
}
#define ReadWord(W) (W)
#define AtomicAddBody(P,I)\
jsword n;\
do {\
n = ReadWord(*(P));\
} while (!js_CompareAndSwap(P, n, n + I));
#if defined(_WIN32) && !defined(NSPR_LOCK)
#pragma warning( disable : 4035 )
JS_INLINE int
js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
{
__asm {
mov eax,ov
mov ecx, nv
mov ebx, w
lock cmpxchg [ebx], ecx
sete al
and eax,1h
}
}
#elif defined(SOLARIS) && !defined(NSPR_LOCK)
#ifndef ULTRA_SPARC
JS_INLINE jsword
js_ReadWord(jsword *p)
{
jsword n;
while ((n = *p) == -1)
;
return n;
}
#undef ReadWord
#define ReadWord(W) js_ReadWord(&(W))
static PRLock *_counter_lock;
#define UsingCounterLock 1
#undef AtomicAddBody
#define AtomicAddBody(P,I) \
PR_Lock(_counter_lock);\
*(P) += I;\
PR_Unlock(_counter_lock);
#endif /* !ULTRA_SPARC */
JS_INLINE int
js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
{
#if defined(__GNUC__)
unsigned int res;
#ifndef ULTRA_SPARC
JS_ASSERT(nv != -1);
asm volatile ("\
stbar\n\
swap [%1],%4\n\
1: cmp %4,-1\n\
be,a 1b\n\
swap [%1],%4\n\
cmp %2,%4\n\
be,a 2f\n\
swap [%1],%3\n\
swap [%1],%4\n\
ba 3f\n\
mov 0,%0\n\
2: mov 1,%0\n\
3:"
: "=r" (res)
: "r" (w), "r" (ov), "r" (nv), "r" (-1));
#else /* ULTRA_SPARC */
JS_ASSERT(ov != nv);
asm volatile ("\
stbar\n\
cas [%1],%2,%3\n\
cmp %2,%3\n\
be,a 1f\n\
mov 1,%0\n\
mov 0,%0\n\
1:"
: "=r" (res)
: "r" (w), "r" (ov), "r" (nv));
#endif /* ULTRA_SPARC */
return (int)res;
#else /* !__GNUC__ */
extern int compare_and_swap(jsword*,jsword,jsword);
#ifndef ULTRA_SPARC
JS_ASSERT(nv != -1);
#else
JS_ASSERT(ov != nv);
#endif
return compare_and_swap(w,ov,nv);
#endif
}
#elif defined(AIX) && !defined(NSPR_LOCK)
#include <sys/atomic_op.h>
JS_INLINE int
js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
{
return !_check_lock(w,ov,nv);
}
#else
static PRLock *_counter_lock;
#define UsingCounterLock 1
#undef AtomicAddBody
#define AtomicAddBody(P,I) \
PR_Lock(_counter_lock);\
*(P) += I;\
PR_Unlock(_counter_lock);
static PRLock *_compare_and_swap_lock;
#define UsingCompareAndSwapLock 1
JS_INLINE int
js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
{
int res = 0;
PR_Lock(_compare_and_swap_lock);
if (*w == ov) {
*w = nv;
res = 1;
}
PR_Unlock(_compare_and_swap_lock);
return res;
}
#endif /* arch-tests */
JS_INLINE void
js_AtomicAdd(jsword *p, jsword i)
{
AtomicAddBody(p,i);
}
static JS_INLINE jsword
js_AtomicSet(jsword *p, jsword n)
{
jsword o;
do {
o = ReadWord(*p);
} while (!js_CompareAndSwap(p,o,n));
return o;
}
jsword
js_CurrentThreadId()
{
return CurrentThreadId();
}
void
js_NewLock(JSThinLock *p)
{
#ifdef NSPR_LOCK
p->owner = 0;
p->fat = (JSFatLock*)JS_NEW_LOCK();
#else
memset(p, 0, sizeof(JSThinLock));
#endif
}
void
js_DestroyLock(JSThinLock *p)
{
#ifdef NSPR_LOCK
p->owner = 0xdeadbeef;
JS_DESTROY_LOCK(((JSLock*)p->fat));
#else
JS_ASSERT(p->owner == 0);
JS_ASSERT(p->fat == NULL);
#endif
}
static void js_Dequeue(JSThinLock *);
JS_INLINE jsval
js_GetSlotWhileLocked(JSContext *cx, JSObject *obj, uint32 slot)
{
jsval v;
#ifndef NSPR_LOCK
JSScope *scp = (JSScope *)obj->map;
JSThinLock *p = &scp->lock;
jsword me = cx->thread;
#endif
JS_ASSERT(obj->slots && slot < obj->map->freeslot);
#ifndef NSPR_LOCK
JS_ASSERT(me == CurrentThreadId());
if (js_CompareAndSwap(&p->owner, 0, me)) {
if (scp == (JSScope *)obj->map) {
v = obj->slots[slot];
if (!js_CompareAndSwap(&p->owner, me, 0)) {
scp->count = 1;
js_UnlockObj(cx,obj);
}
return v;
}
if (!js_CompareAndSwap(&p->owner, me, 0))
js_Dequeue(p);
}
else if (Thin_RemoveWait(ReadWord(p->owner)) == me) {
return obj->slots[slot];
}
#endif
js_LockObj(cx,obj);
v = obj->slots[slot];
js_UnlockObj(cx,obj);
return v;
}
JS_INLINE void
js_SetSlotWhileLocked(JSContext *cx, JSObject *obj, uint32 slot, jsval v)
{
#ifndef NSPR_LOCK
JSScope *scp = (JSScope *)obj->map;
JSThinLock *p = &scp->lock;
jsword me = cx->thread;
#endif
JS_ASSERT(obj->slots && slot < obj->map->freeslot);
#ifndef NSPR_LOCK
JS_ASSERT(me == CurrentThreadId());
if (js_CompareAndSwap(&p->owner, 0, me)) {
if (scp == (JSScope *)obj->map) {
obj->slots[slot] = v;
if (!js_CompareAndSwap(&p->owner, me, 0)) {
scp->count = 1;
js_UnlockObj(cx,obj);
}
return;
}
if (!js_CompareAndSwap(&p->owner, me, 0))
js_Dequeue(p);
}
else if (Thin_RemoveWait(ReadWord(p->owner)) == me) {
obj->slots[slot] = v;
return;
}
#endif
js_LockObj(cx,obj);
obj->slots[slot] = v;
js_UnlockObj(cx,obj);
}
static JSFatLock *
mallocFatlock()
{
JSFatLock *fl = (JSFatLock *)malloc(sizeof(JSFatLock)); /* for now */
JS_ASSERT(fl);
fl->susp = 0;
fl->next = NULL;
fl->prev = NULL;
fl->slock = PR_NewLock();
fl->svar = PR_NewCondVar(fl->slock);
return fl;
}
static void
freeFatlock(JSFatLock *fl)
{
PR_DestroyLock(fl->slock);
PR_DestroyCondVar(fl->svar);
free(fl);
}
static int
js_SuspendThread(JSThinLock *p)
{
JSFatLock *fl;
JSStatus stat;
while ((fl = (JSFatLock*)js_AtomicSet((jsword*)&p->fat,1)) == (JSFatLock*)1) /* busy wait */
PR_Sleep(PR_INTERVAL_NO_WAIT);
if (fl == NULL)
return 1;
PR_Lock(fl->slock);
js_AtomicSet((jsword*)&p->fat,(jsword)fl);
fl->susp++;
if (fl->susp < 1) {
PR_Unlock(fl->slock);
return 1;
}
stat = PR_WaitCondVar(fl->svar,PR_INTERVAL_NO_TIMEOUT);
if (stat == JS_FAILURE) {
fl->susp--;
return 0;
}
PR_Unlock(fl->slock);
return 1;
}
static void
js_ResumeThread(JSThinLock *p)
{
JSFatLock *fl;
JSStatus stat;
while ((fl = (JSFatLock*)js_AtomicSet((jsword*)&p->fat,1)) == (JSFatLock*)1)
PR_Sleep(PR_INTERVAL_NO_WAIT);
if (fl == NULL)
return;
PR_Lock(fl->slock);
js_AtomicSet((jsword*)&p->fat,(jsword)fl);
fl->susp--;
if (fl->susp < 0) {
PR_Unlock(fl->slock);
return;
}
stat = PR_NotifyCondVar(fl->svar);
JS_ASSERT(stat != JS_FAILURE);
PR_Unlock(fl->slock);
}
static JSFatLock *
listOfFatlocks(int l)
{
JSFatLock *m;
JSFatLock *m0;
int i;
JS_ASSERT(l>0);
m0 = m = mallocFatlock();
for (i=1; i<l; i++) {
m->next = mallocFatlock();
m = m->next;
}
return m0;
}
static void
deleteListOfFatlocks(JSFatLock *m)
{
JSFatLock *m0;
for (; m; m=m0) {
m0 = m->next;
freeFatlock(m);
}
}
static JSFatLockTable _fl_table;
static JSFatLock *
allocateFatlock()
{
JSFatLock *m;
js_LockGlobal();
if (_fl_table.free == NULL) {
#ifdef DEBUG
printf("Ran out of fat locks!\n");
#endif
_fl_table.free = listOfFatlocks(10);
}
m = _fl_table.free;
_fl_table.free = m->next;
_fl_table.free->prev = NULL;
m->susp = 0;
m->next = _fl_table.taken;
m->prev = NULL;
if (_fl_table.taken != NULL)
_fl_table.taken->prev = m;
_fl_table.taken = m;
js_UnlockGlobal();
return m;
}
static void
deallocateFatlock(JSFatLock *m)
{
if (m == NULL)
return;
js_LockGlobal();
if (m->prev != NULL)
m->prev->next = m->next;
if (m->next != NULL)
m->next->prev = m->prev;
if (m == _fl_table.taken)
_fl_table.taken = m->next;
m->next = _fl_table.free;
_fl_table.free = m;
js_UnlockGlobal();
}
int
js_SetupLocks(int l)
{
if (l > 10000) /* l equals number of initially allocated fat locks */
#ifdef DEBUG
printf("Number %d very large in js_SetupLocks()!\n",l);
#endif
if (_global_lock)
return 1;
_global_lock = PR_NewLock();
JS_ASSERT(_global_lock);
#ifdef UsingCounterLock
_counter_lock = PR_NewLock();
JS_ASSERT(_counter_lock);
#endif
#ifdef UsingCompareAndSwapLock
_compare_and_swap_lock = PR_NewLock();
JS_ASSERT(_compare_and_swap_lock);
#endif
_fl_table.free = listOfFatlocks(l);
_fl_table.taken = NULL;
return 1;
}
void
js_CleanupLocks()
{
if (_global_lock != NULL) {
deleteListOfFatlocks(_fl_table.free);
_fl_table.free = NULL;
deleteListOfFatlocks(_fl_table.taken);
_fl_table.taken = NULL;
PR_DestroyLock(_global_lock);
_global_lock = NULL;
#ifdef UsingCounterLock
PR_DestroyLock(_counter_lock);
_counter_lock = NULL;
#endif
#ifdef UsingCompareAndSwapLock
PR_DestroyLock(_compare_and_swap_lock);
_compare_and_swap_lock = NULL;
#endif
}
}
JS_PUBLIC_API(void)
js_InitContextForLocking(JSContext *cx)
{
cx->thread = CurrentThreadId();
JS_ASSERT(Thin_GetWait(cx->thread) == 0);
}
/*
It is important that emptyFatlock() clears p->fat in the empty case
while holding p->slock. This serializes the access of p->fat wrt
js_SuspendThread(), which also requires p->slock. There would
otherwise be a race condition as follows. Thread A is about to
clear p->fat, having woken up after being suspended in a situation
where no other thread has yet suspended on p. However, suppose
thread B is about to suspend on p, having just released the global
lock, and is currently calling js_SuspendThread(). In the unfortunate
case where A precedes B ever so slightly, A will think that it
should clear p->fat (being currently empty but not for long), at the
same time as B is about to suspend on p->fat. Now, A deallocates
p->fat while B is about to suspend on it. Thus, the suspension of B
is lost and B will not be properly activated.
Using p->slock as below (and correspondingly in js_SuspendThread()),
js_SuspendThread() will notice that p->fat is empty, and hence return
immediately.
*/
static int
emptyFatlock(JSThinLock *p)
{
JSFatLock *fl;
int i;
PRLock* lck;
while ((fl = (JSFatLock*)js_AtomicSet((jsword*)&p->fat,1)) == (JSFatLock*)1)
PR_Sleep(PR_INTERVAL_NO_WAIT);
if (fl == NULL) {
js_AtomicSet((jsword*)&p->fat,(jsword)fl);
return 1;
}
lck = fl->slock;
PR_Lock(lck);
i = fl->susp;
if (i < 1) {
fl->susp = -1;
deallocateFatlock(fl);
fl = NULL;
}
js_AtomicSet((jsword*)&p->fat,(jsword)fl);
PR_Unlock(lck);
return i < 1;
}
/*
Fast locking and unlocking is implemented by delaying the
allocation of a system lock (fat lock) until contention. As long as
a locking thread A runs uncontended, the lock is represented solely
by storing A's identity in the object being locked.
If another thread B tries to lock the object currently locked by A,
B is enqueued into a fat lock structure (which might have to be
allocated and pointed to by the object), and suspended using NSPR
conditional variables (wait). A wait bit (Bacon bit) is set in the
lock word of the object, signalling to A that when releasing the
lock, B must be dequeued and notified.
The basic operation of the locking primitives (js_Lock(),
js_Unlock(), js_Enqueue(), and js_Dequeue()) is
compare-and-swap. Hence, when locking into p, if
compare-and-swap(p,NULL,me) succeeds this implies that p is
unlocked. Similarly, when unlocking p, if
compare-and-swap(p,me,NULL) succeeds this implies that p is
uncontended (no one is waiting because the wait bit is not set).
Furthermore, when enqueueing (after the compare-and-swap has failed
to lock the object), p->fat is used to serialize the different
accesses to the fat lock. The four function thus synchronized are
js_Enqueue, emptyFatLock, js_SuspendThread, and js_ResumeThread.
When dequeueing, the lock is released, and one of the threads
suspended on the lock is notified. If other threads still are
waiting, the wait bit is kept (in js_Enqueue), and if not, the fat
lock is deallocated (in emptyFatlock()).
p->fat is set to 1 by enqueue and emptyFatlock to signal that the pointer
is being accessed.
*/
static void
js_Enqueue(JSThinLock *p, jsword me)
{
jsword o, n;
while (1) {
o = ReadWord(p->owner);
n = Thin_SetWait(o);
if (o != 0 && js_CompareAndSwap(&p->owner,o,n)) {
JSFatLock* fl;
while ((fl = (JSFatLock*)js_AtomicSet((jsword*)&p->fat,1)) == (JSFatLock*)1)
PR_Sleep(PR_INTERVAL_NO_WAIT);
if (fl == NULL)
fl = allocateFatlock();
js_AtomicSet((jsword*)&p->fat,(jsword)fl);
js_SuspendThread(p);
if (emptyFatlock(p))
me = Thin_RemoveWait(me);
else
me = Thin_SetWait(me);
}
else if (js_CompareAndSwap(&p->owner,0,me)) {
return;
}
}
}
static void
js_Dequeue(JSThinLock *p)
{
int o = ReadWord(p->owner);
JS_ASSERT(Thin_GetWait(o));
if (!js_CompareAndSwap(&p->owner,o,0)) /* release it */
JS_ASSERT(0);
js_ResumeThread(p);
}
JS_INLINE void
js_Lock(JSThinLock *p, jsword me)
{
JS_ASSERT(me == CurrentThreadId());
if (js_CompareAndSwap(&p->owner, 0, me))
return;
if (Thin_RemoveWait(ReadWord(p->owner)) != me)
js_Enqueue(p, me);
#ifdef DEBUG
else
JS_ASSERT(0);
#endif
}
JS_INLINE void
js_Unlock(JSThinLock *p, jsword me)
{
JS_ASSERT(me == CurrentThreadId());
if (js_CompareAndSwap(&p->owner, me, 0))
return;
if (Thin_RemoveWait(ReadWord(p->owner)) == me)
js_Dequeue(p);
#ifdef DEBUG
else
JS_ASSERT(0);
#endif
}
void
js_LockRuntime(JSRuntime *rt)
{
jsword me = CurrentThreadId();
JSThinLock *p;
JS_ASSERT(Thin_RemoveWait(ReadWord(rt->rtLock.owner)) != me);
p = &rt->rtLock;
JS_LOCK0(p,me);
}
void
js_UnlockRuntime(JSRuntime *rt)
{
jsword me = CurrentThreadId();
JSThinLock *p;
JS_ASSERT(Thin_RemoveWait(ReadWord(rt->rtLock.owner)) == me);
p = &rt->rtLock;
JS_UNLOCK0(p,me);
}
static JS_INLINE void
js_LockScope1(JSContext *cx, JSScope *scope, jsword me)
{
JSThinLock *p;
if (Thin_RemoveWait(ReadWord(scope->lock.owner)) == me) {
JS_ASSERT(scope->count > 0);
scope->count++;
} else {
p = &scope->lock;
JS_LOCK0(p,me);
JS_ASSERT(scope->count == 0);
scope->count = 1;
}
}
void
js_LockScope(JSContext *cx, JSScope *scope)
{
JS_ASSERT(cx->thread == CurrentThreadId());
js_LockScope1(cx,scope,cx->thread);
}
void
js_UnlockScope(JSContext *cx, JSScope *scope)
{
jsword me = cx->thread;
JSThinLock *p;
JS_ASSERT(scope->count > 0);
if (Thin_RemoveWait(ReadWord(scope->lock.owner)) != me) {
JS_ASSERT(0);
return;
}
if (--scope->count == 0) {
p = &scope->lock;
JS_UNLOCK0(p,me);
}
}
void
js_TransferScopeLock(JSContext *cx, JSScope *oldscope, JSScope *newscope)
{
jsword me;
JSThinLock *p;
JS_ASSERT(JS_IS_SCOPE_LOCKED(newscope));
/*
* If the last reference to oldscope went away, newscope needs no lock
* state update.
*/
if (!oldscope) {
return;
}
JS_ASSERT(JS_IS_SCOPE_LOCKED(oldscope));
/*
* Transfer oldscope's entry count to newscope, as it will be unlocked
* now via JS_UNLOCK_OBJ(cx,obj) calls made while we unwind the C stack
* from the current point (under js_GetMutableScope).
*/
newscope->count = oldscope->count;
/*
* Reset oldscope's lock state so that it is completely unlocked.
*/
oldscope->count = 0;
p = &oldscope->lock;
me = cx->thread;
JS_UNLOCK0(p,me);
}
void
js_LockObj(JSContext *cx, JSObject *obj)
{
JSScope *scope;
jsword me = cx->thread;
JS_ASSERT(me == CurrentThreadId());
for (;;) {
scope = (JSScope *) obj->map;
js_LockScope1(cx, scope, me);
/* If obj still has this scope, we're done. */
if (scope == (JSScope *) obj->map)
return;
/* Lost a race with a mutator; retry with obj's new scope. */
js_UnlockScope(cx, scope);
}
}
void
js_UnlockObj(JSContext *cx, JSObject *obj)
{
js_UnlockScope(cx, (JSScope *) obj->map);
}
#ifdef DEBUG
JSBool
js_IsRuntimeLocked(JSRuntime *rt)
{
return CurrentThreadId() == Thin_RemoveWait(ReadWord(rt->rtLock.owner));
}
JSBool
js_IsObjLocked(JSObject *obj)
{
JSObjectMap *map = obj->map;
return MAP_IS_NATIVE(map) && CurrentThreadId() == Thin_RemoveWait(ReadWord(((JSScope *)map)->lock.owner));
}
JSBool
js_IsScopeLocked(JSScope *scope)
{
return CurrentThreadId() == Thin_RemoveWait(ReadWord(scope->lock.owner));
}
#endif
#undef ReadWord
#endif /* JS_THREADSAFE */

213
mozilla/js/src/jslock.h Normal file
View File

@@ -0,0 +1,213 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jslock_h__
#define jslock_h__
#ifdef JS_THREADSAFE
#include "jstypes.h"
#include "prlock.h"
#include "prcvar.h"
#include "jshash.h" /* Added by JSIFY */
#define Thin_GetWait(W) ((jsword)(W) & 0x1)
#define Thin_SetWait(W) ((jsword)(W) | 0x1)
#define Thin_RemoveWait(W) ((jsword)(W) & ~0x1)
typedef struct JSFatLock {
int susp;
PRLock* slock;
PRCondVar* svar;
struct JSFatLock *next;
struct JSFatLock *prev;
} JSFatLock;
typedef struct JSThinLock {
jsword owner;
JSFatLock *fat;
} JSThinLock;
typedef PRLock JSLock;
typedef struct JSFatLockTable {
JSFatLock *free;
JSFatLock *taken;
} JSFatLockTable;
#define JS_ATOMIC_ADDREF(p, i) js_AtomicAdd(p,i)
#define CurrentThreadId() (jsword)PR_GetCurrentThread()
#define JS_CurrentThreadId() js_CurrentThreadId()
#define JS_NEW_LOCK() PR_NewLock()
#define JS_DESTROY_LOCK(l) PR_DestroyLock(l)
#define JS_ACQUIRE_LOCK(l) PR_Lock(l)
#define JS_RELEASE_LOCK(l) PR_Unlock(l)
#define JS_LOCK0(P,M) js_Lock(P,M)
#define JS_UNLOCK0(P,M) js_Unlock(P,M)
#define JS_NEW_CONDVAR(l) PR_NewCondVar(l)
#define JS_DESTROY_CONDVAR(cv) PR_DestroyCondVar(cv)
#define JS_WAIT_CONDVAR(cv,to) PR_WaitCondVar(cv,to)
#define JS_NO_TIMEOUT PR_INTERVAL_NO_TIMEOUT
#define JS_NOTIFY_CONDVAR(cv) PR_NotifyCondVar(cv)
#define JS_NOTIFY_ALL_CONDVAR(cv) PR_NotifyAllCondVar(cv)
#ifdef DEBUG
#include "jsscope.h"
#define _SET_OBJ_INFO(obj,f,l) \
_SET_SCOPE_INFO(((JSScope*)obj->map),f,l)
#define _SET_SCOPE_INFO(scope,f,l) \
(JS_ASSERT(scope->count > 0 && scope->count <= 4), \
scope->file[scope->count-1] = f, \
scope->line[scope->count-1] = l)
#endif /* DEBUG */
#define JS_LOCK_RUNTIME(rt) js_LockRuntime(rt)
#define JS_UNLOCK_RUNTIME(rt) js_UnlockRuntime(rt)
#define JS_LOCK_OBJ(cx,obj) (js_LockObj(cx, obj), \
_SET_OBJ_INFO(obj,__FILE__,__LINE__))
#define JS_UNLOCK_OBJ(cx,obj) js_UnlockObj(cx, obj)
#define JS_LOCK_SCOPE(cx,scope) (js_LockScope(cx, scope), \
_SET_SCOPE_INFO(scope,__FILE__,__LINE__))
#define JS_UNLOCK_SCOPE(cx,scope) js_UnlockScope(cx, scope)
#define JS_TRANSFER_SCOPE_LOCK(cx, scope, newscope) js_TransferScopeLock(cx, scope, newscope)
extern jsword js_CurrentThreadId();
extern JS_INLINE void js_Lock(JSThinLock *, jsword);
extern JS_INLINE void js_Unlock(JSThinLock *, jsword);
extern int js_CompareAndSwap(jsword *, jsword, jsword);
extern void js_AtomicAdd(jsword*, jsword);
extern void js_LockRuntime(JSRuntime *rt);
extern void js_UnlockRuntime(JSRuntime *rt);
extern void js_LockObj(JSContext *cx, JSObject *obj);
extern void js_UnlockObj(JSContext *cx, JSObject *obj);
extern void js_LockScope(JSContext *cx, JSScope *scope);
extern void js_UnlockScope(JSContext *cx, JSScope *scope);
extern int js_SetupLocks(int);
extern void js_CleanupLocks();
extern JS_PUBLIC_API(void) js_InitContextForLocking(JSContext *);
extern void js_TransferScopeLock(JSContext *, JSScope *, JSScope *);
extern JS_PUBLIC_API(jsval) js_GetSlotWhileLocked(JSContext *, JSObject *, uint32);
extern JS_PUBLIC_API(void) js_SetSlotWhileLocked(JSContext *, JSObject *, uint32, jsval);
extern void js_NewLock(JSThinLock *);
extern void js_DestroyLock(JSThinLock *);
#ifdef DEBUG
#define JS_IS_RUNTIME_LOCKED(rt) js_IsRuntimeLocked(rt)
#define JS_IS_OBJ_LOCKED(obj) js_IsObjLocked(obj)
#define JS_IS_SCOPE_LOCKED(scope) js_IsScopeLocked(scope)
extern JSBool js_IsRuntimeLocked(JSRuntime *rt);
extern JSBool js_IsObjLocked(JSObject *obj);
extern JSBool js_IsScopeLocked(JSScope *scope);
#else
#define JS_IS_RUNTIME_LOCKED(rt) 0
#define JS_IS_OBJ_LOCKED(obj) 1
#define JS_IS_SCOPE_LOCKED(scope) 1
#endif /* DEBUG */
#define JS_LOCK_OBJ_VOID(cx, obj, e) \
JS_BEGIN_MACRO \
js_LockObj(cx, obj); \
e; \
js_UnlockObj(cx, obj); \
JS_END_MACRO
#define JS_LOCK_VOID(cx, e) \
JS_BEGIN_MACRO \
JSRuntime *_rt = (cx)->runtime; \
JS_LOCK_RUNTIME_VOID(_rt, e); \
JS_END_MACRO
#if defined(JS_USE_ONLY_NSPR_LOCKS) || !(defined(_WIN32) || defined(SOLARIS) || defined(AIX))
#undef JS_LOCK0
#undef JS_UNLOCK0
#define JS_LOCK0(P,M) JS_ACQUIRE_LOCK(((JSLock*)(P)->fat)); (P)->owner = (M)
#define JS_UNLOCK0(P,M) (P)->owner = 0; JS_RELEASE_LOCK(((JSLock*)(P)->fat))
#define NSPR_LOCK 1
#endif /* arch-tests */
#else /* !JS_THREADSAFE */
#define JS_ATOMIC_ADDREF(p,i) (*(p) += i)
#define JS_CurrentThreadId() 0
#define JS_NEW_LOCK() NULL
#define JS_DESTROY_LOCK(l) ((void)0)
#define JS_ACQUIRE_LOCK(l) ((void)0)
#define JS_RELEASE_LOCK(l) ((void)0)
#define JS_LOCK0(P,M) ((void)0)
#define JS_UNLOCK0(P,M) ((void)0)
#define JS_NEW_CONDVAR(l) NULL
#define JS_DESTROY_CONDVAR(cv) ((void)0)
#define JS_WAIT_CONDVAR(cv,to) ((void)0)
#define JS_NOTIFY_CONDVAR(cv) ((void)0)
#define JS_NOTIFY_ALL_CONDVAR(cv) ((void)0)
#define JS_LOCK_RUNTIME(rt) ((void)0)
#define JS_UNLOCK_RUNTIME(rt) ((void)0)
#define JS_LOCK_OBJ(cx,obj) ((void)0)
#define JS_UNLOCK_OBJ(cx,obj) ((void)0)
#define JS_LOCK_OBJ_VOID(cx,obj,e) (e)
#define JS_LOCK_SCOPE(cx,scope) ((void)0)
#define JS_UNLOCK_SCOPE(cx,scope) ((void)0)
#define JS_TRANSFER_SCOPE_LOCK(c,o,n) ((void)0)
#define JS_IS_RUNTIME_LOCKED(rt) 1
#define JS_IS_OBJ_LOCKED(obj) 1
#define JS_IS_SCOPE_LOCKED(scope) 1
#define JS_LOCK_VOID(cx, e) JS_LOCK_RUNTIME_VOID((cx)->runtime, e)
#endif /* !JS_THREADSAFE */
#define JS_LOCK_RUNTIME_VOID(rt,e) \
JS_BEGIN_MACRO \
JS_LOCK_RUNTIME(rt); \
e; \
JS_UNLOCK_RUNTIME(rt); \
JS_END_MACRO
#define JS_LOCK_GC(rt) JS_ACQUIRE_LOCK((rt)->gcLock)
#define JS_UNLOCK_GC(rt) JS_RELEASE_LOCK((rt)->gcLock)
#define JS_LOCK_GC_VOID(rt,e) (JS_LOCK_GC(rt), (e), JS_UNLOCK_GC(rt))
#define JS_AWAIT_GC_DONE(rt) JS_WAIT_CONDVAR((rt)->gcDone, JS_NO_TIMEOUT)
#define JS_NOTIFY_GC_DONE(rt) JS_NOTIFY_ALL_CONDVAR((rt)->gcDone)
#define JS_AWAIT_REQUEST_DONE(rt) JS_WAIT_CONDVAR((rt)->requestDone, \
JS_NO_TIMEOUT)
#define JS_NOTIFY_REQUEST_DONE(rt) JS_NOTIFY_CONDVAR((rt)->requestDone)
#define JS_LOCK(P,CX) JS_LOCK0(P,(CX)->thread)
#define JS_UNLOCK(P,CX) JS_UNLOCK0(P,(CX)->thread)
#ifndef _SET_OBJ_INFO
#define _SET_OBJ_INFO(obj,f,l) ((void)0)
#endif
#ifndef _SET_SCOPE_INFO
#define _SET_SCOPE_INFO(scope,f,l) ((void)0)
#endif
#endif /* jslock_h___ */

62
mozilla/js/src/jslog2.c Normal file
View File

@@ -0,0 +1,62 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "jsbit.h"
/*
** Compute the log of the least power of 2 greater than or equal to n
*/
JS_EXPORT_API(JSIntn) JS_CeilingLog2(JSUint32 n)
{
JSIntn log2 = 0;
if (n & (n-1))
log2++;
if (n >> 16)
log2 += 16, n >>= 16;
if (n >> 8)
log2 += 8, n >>= 8;
if (n >> 4)
log2 += 4, n >>= 4;
if (n >> 2)
log2 += 2, n >>= 2;
if (n >> 1)
log2++;
return log2;
}
/*
** Compute the log of the greatest power of 2 less than or equal to n.
** This really just finds the highest set bit in the word.
*/
JS_EXPORT_API(JSIntn) JS_FloorLog2(JSUint32 n)
{
JSIntn log2 = 0;
if (n >> 16)
log2 += 16, n >>= 16;
if (n >> 8)
log2 += 8, n >>= 8;
if (n >> 4)
log2 += 4, n >>= 4;
if (n >> 2)
log2 += 2, n >>= 2;
if (n >> 1)
log2++;
return log2;
}

260
mozilla/js/src/jslong.c Normal file
View File

@@ -0,0 +1,260 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "jstypes.h"
#include "jslong.h"
static JSInt64 ll_zero = JSLL_INIT( 0x00000000,0x00000000 );
static JSInt64 ll_maxint = JSLL_INIT( 0x7fffffff, 0xffffffff );
static JSInt64 ll_minint = JSLL_INIT( 0x80000000, 0x00000000 );
#ifdef HAVE_WATCOM_BUG_2
JSInt64 __pascal __loadds __export
JSLL_Zero(void) { return ll_zero; }
JSInt64 __pascal __loadds __export
JSLL_MaxInt(void) { return ll_maxint; }
JSInt64 __pascal __loadds __export
JSLL_MinInt(void) { return ll_minint; }
#else
JS_EXPORT_API(JSInt64) JSLL_Zero(void) { return ll_zero; }
JS_EXPORT_API(JSInt64) JSLL_MaxInt(void) { return ll_maxint; }
JS_EXPORT_API(JSInt64) JSLL_MinInt(void) { return ll_minint; }
#endif
#ifndef JS_HAVE_LONG_LONG
/*
** Divide 64-bit a by 32-bit b, which must be normalized so its high bit is 1.
*/
static void norm_udivmod32(JSUint32 *qp, JSUint32 *rp, JSUint64 a, JSUint32 b)
{
JSUint32 d1, d0, q1, q0;
JSUint32 r1, r0, m;
d1 = jshi16(b);
d0 = jslo16(b);
r1 = a.hi % d1;
q1 = a.hi / d1;
m = q1 * d0;
r1 = (r1 << 16) | jshi16(a.lo);
if (r1 < m) {
q1--, r1 += b;
if (r1 >= b /* i.e., we didn't get a carry when adding to r1 */
&& r1 < m) {
q1--, r1 += b;
}
}
r1 -= m;
r0 = r1 % d1;
q0 = r1 / d1;
m = q0 * d0;
r0 = (r0 << 16) | jslo16(a.lo);
if (r0 < m) {
q0--, r0 += b;
if (r0 >= b
&& r0 < m) {
q0--, r0 += b;
}
}
*qp = (q1 << 16) | q0;
*rp = r0 - m;
}
static JSUint32 CountLeadingZeros(JSUint32 a)
{
JSUint32 t;
JSUint32 r = 32;
if ((t = a >> 16) != 0)
r -= 16, a = t;
if ((t = a >> 8) != 0)
r -= 8, a = t;
if ((t = a >> 4) != 0)
r -= 4, a = t;
if ((t = a >> 2) != 0)
r -= 2, a = t;
if ((t = a >> 1) != 0)
r -= 1, a = t;
if (a & 1)
r--;
return r;
}
JS_EXPORT_API(void) jsll_udivmod(JSUint64 *qp, JSUint64 *rp, JSUint64 a, JSUint64 b)
{
JSUint32 n0, n1, n2;
JSUint32 q0, q1;
JSUint32 rsh, lsh;
n0 = a.lo;
n1 = a.hi;
if (b.hi == 0) {
if (b.lo > n1) {
/* (0 q0) = (n1 n0) / (0 D0) */
lsh = CountLeadingZeros(b.lo);
if (lsh) {
/*
* Normalize, i.e. make the most significant bit of the
* denominator be set.
*/
b.lo = b.lo << lsh;
n1 = (n1 << lsh) | (n0 >> (32 - lsh));
n0 = n0 << lsh;
}
a.lo = n0, a.hi = n1;
norm_udivmod32(&q0, &n0, a, b.lo);
q1 = 0;
/* remainder is in n0 >> lsh */
} else {
/* (q1 q0) = (n1 n0) / (0 d0) */
if (b.lo == 0) /* user wants to divide by zero! */
b.lo = 1 / b.lo; /* so go ahead and crash */
lsh = CountLeadingZeros(b.lo);
if (lsh == 0) {
/*
* From (n1 >= b.lo)
* && (the most significant bit of b.lo is set),
* conclude that
* (the most significant bit of n1 is set)
* && (the leading quotient digit q1 = 1).
*
* This special case is necessary, not an optimization
* (Shifts counts of 32 are undefined).
*/
n1 -= b.lo;
q1 = 1;
} else {
/*
* Normalize.
*/
rsh = 32 - lsh;
b.lo = b.lo << lsh;
n2 = n1 >> rsh;
n1 = (n1 << lsh) | (n0 >> rsh);
n0 = n0 << lsh;
a.lo = n1, a.hi = n2;
norm_udivmod32(&q1, &n1, a, b.lo);
}
/* n1 != b.lo... */
a.lo = n0, a.hi = n1;
norm_udivmod32(&q0, &n0, a, b.lo);
/* remainder in n0 >> lsh */
}
if (rp) {
rp->lo = n0 >> lsh;
rp->hi = 0;
}
} else {
if (b.hi > n1) {
/* (0 0) = (n1 n0) / (D1 d0) */
q0 = 0;
q1 = 0;
/* remainder in (n1 n0) */
if (rp) {
rp->lo = n0;
rp->hi = n1;
}
} else {
/* (0 q0) = (n1 n0) / (d1 d0) */
lsh = CountLeadingZeros(b.hi);
if (lsh == 0) {
/*
* From (n1 >= b.hi)
* && (the most significant bit of b.hi is set),
* conclude that
* (the most significant bit of n1 is set)
* && (the quotient digit q0 = 0 or 1).
*
* This special case is necessary, not an optimization.
*/
/*
* The condition on the next line takes advantage of that
* n1 >= b.hi (true due to control flow).
*/
if (n1 > b.hi || n0 >= b.lo) {
q0 = 1;
a.lo = n0, a.hi = n1;
JSLL_SUB(a, a, b);
} else {
q0 = 0;
}
q1 = 0;
if (rp) {
rp->lo = n0;
rp->hi = n1;
}
} else {
JSInt64 m;
/*
* Normalize.
*/
rsh = 32 - lsh;
b.hi = (b.hi << lsh) | (b.lo >> rsh);
b.lo = b.lo << lsh;
n2 = n1 >> rsh;
n1 = (n1 << lsh) | (n0 >> rsh);
n0 = n0 << lsh;
a.lo = n1, a.hi = n2;
norm_udivmod32(&q0, &n1, a, b.hi);
JSLL_MUL32(m, q0, b.lo);
if ((m.hi > n1) || ((m.hi == n1) && (m.lo > n0))) {
q0--;
JSLL_SUB(m, m, b);
}
q1 = 0;
/* Remainder is ((n1 n0) - (m1 m0)) >> lsh */
if (rp) {
a.lo = n0, a.hi = n1;
JSLL_SUB(a, a, m);
rp->lo = (a.hi << rsh) | (a.lo >> lsh);
rp->hi = a.hi >> lsh;
}
}
}
}
if (qp) {
qp->lo = q0;
qp->hi = q1;
}
}
#endif /* !JS_HAVE_LONG_LONG */

409
mozilla/js/src/jslong.h Normal file
View File

@@ -0,0 +1,409 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
** File: jslong.h
** Description: Portable access to 64 bit numerics
**
** Long-long (64-bit signed integer type) support. Some C compilers
** don't support 64 bit integers yet, so we use these macros to
** support both machines that do and don't.
**/
#ifndef jslong_h___
#define jslong_h___
#include "jstypes.h"
JS_BEGIN_EXTERN_C
/***********************************************************************
** DEFINES: JSLL_MaxInt
** JSLL_MinInt
** JSLL_Zero
** DESCRIPTION:
** Various interesting constants and static variable
** initializer
***********************************************************************/
#ifdef HAVE_WATCOM_BUG_2
JSInt64 __pascal __loadds __export
JSLL_MaxInt(void);
JSInt64 __pascal __loadds __export
JSLL_MinInt(void);
JSInt64 __pascal __loadds __export
JSLL_Zero(void);
#else
JS_EXTERN_API(JSInt64) JSLL_MaxInt(void);
JS_EXTERN_API(JSInt64) JSLL_MinInt(void);
JS_EXTERN_API(JSInt64) JSLL_Zero(void);
#endif
#define JSLL_MAXINT JSLL_MaxInt()
#define JSLL_MININT JSLL_MinInt()
#define JSLL_ZERO JSLL_Zero()
#ifdef JS_HAVE_LONG_LONG
#if JS_BYTES_PER_LONG == 8
#define JSLL_INIT(hi, lo) ((hi ## L << 32) + lo ## L)
#elif defined(WIN32) || defined(WIN16)
#define JSLL_INIT(hi, lo) ((hi ## i64 << 32) + lo ## i64)
#else
#define JSLL_INIT(hi, lo) ((hi ## LL << 32) + lo ## LL)
#endif
/***********************************************************************
** MACROS: JSLL_*
** DESCRIPTION:
** The following macros define portable access to the 64 bit
** math facilities.
**
***********************************************************************/
/***********************************************************************
** MACROS: JSLL_<relational operators>
**
** JSLL_IS_ZERO Test for zero
** JSLL_EQ Test for equality
** JSLL_NE Test for inequality
** JSLL_GE_ZERO Test for zero or positive
** JSLL_CMP Compare two values
***********************************************************************/
#define JSLL_IS_ZERO(a) ((a) == 0)
#define JSLL_EQ(a, b) ((a) == (b))
#define JSLL_NE(a, b) ((a) != (b))
#define JSLL_GE_ZERO(a) ((a) >= 0)
#define JSLL_CMP(a, op, b) ((JSInt64)(a) op (JSInt64)(b))
#define JSLL_UCMP(a, op, b) ((JSUint64)(a) op (JSUint64)(b))
/***********************************************************************
** MACROS: JSLL_<logical operators>
**
** JSLL_AND Logical and
** JSLL_OR Logical or
** JSLL_XOR Logical exclusion
** JSLL_OR2 A disgusting deviation
** JSLL_NOT Negation (one's compliment)
***********************************************************************/
#define JSLL_AND(r, a, b) ((r) = (a) & (b))
#define JSLL_OR(r, a, b) ((r) = (a) | (b))
#define JSLL_XOR(r, a, b) ((r) = (a) ^ (b))
#define JSLL_OR2(r, a) ((r) = (r) | (a))
#define JSLL_NOT(r, a) ((r) = ~(a))
/***********************************************************************
** MACROS: JSLL_<mathematical operators>
**
** JSLL_NEG Negation (two's compliment)
** JSLL_ADD Summation (two's compliment)
** JSLL_SUB Difference (two's compliment)
***********************************************************************/
#define JSLL_NEG(r, a) ((r) = -(a))
#define JSLL_ADD(r, a, b) ((r) = (a) + (b))
#define JSLL_SUB(r, a, b) ((r) = (a) - (b))
/***********************************************************************
** MACROS: JSLL_<mathematical operators>
**
** JSLL_MUL Product (two's compliment)
** JSLL_DIV Quotient (two's compliment)
** JSLL_MOD Modulus (two's compliment)
***********************************************************************/
#define JSLL_MUL(r, a, b) ((r) = (a) * (b))
#define JSLL_DIV(r, a, b) ((r) = (a) / (b))
#define JSLL_MOD(r, a, b) ((r) = (a) % (b))
/***********************************************************************
** MACROS: JSLL_<shifting operators>
**
** JSLL_SHL Shift left [0..64] bits
** JSLL_SHR Shift right [0..64] bits with sign extension
** JSLL_USHR Unsigned shift right [0..64] bits
** JSLL_ISHL Signed shift left [0..64] bits
***********************************************************************/
#define JSLL_SHL(r, a, b) ((r) = (JSInt64)(a) << (b))
#define JSLL_SHR(r, a, b) ((r) = (JSInt64)(a) >> (b))
#define JSLL_USHR(r, a, b) ((r) = (JSUint64)(a) >> (b))
#define JSLL_ISHL(r, a, b) ((r) = (JSInt64)(a) << (b))
/***********************************************************************
** MACROS: JSLL_<conversion operators>
**
** JSLL_L2I Convert to signed 32 bit
** JSLL_L2UI Convert to unsigned 32 bit
** JSLL_L2F Convert to floating point
** JSLL_L2D Convert to floating point
** JSLL_I2L Convert signed to 64 bit
** JSLL_UI2L Convert unsigned to 64 bit
** JSLL_F2L Convert float to 64 bit
** JSLL_D2L Convert float to 64 bit
***********************************************************************/
#define JSLL_L2I(i, l) ((i) = (JSInt32)(l))
#define JSLL_L2UI(ui, l) ((ui) = (JSUint32)(l))
#define JSLL_L2F(f, l) ((f) = (JSFloat64)(l))
#define JSLL_L2D(d, l) ((d) = (JSFloat64)(l))
#define JSLL_I2L(l, i) ((l) = (JSInt64)(i))
#define JSLL_UI2L(l, ui) ((l) = (JSInt64)(ui))
#define JSLL_F2L(l, f) ((l) = (JSInt64)(f))
#define JSLL_D2L(l, d) ((l) = (JSInt64)(d))
/***********************************************************************
** MACROS: JSLL_UDIVMOD
** DESCRIPTION:
** Produce both a quotient and a remainder given an unsigned
** INPUTS: JSUint64 a: The dividend of the operation
** JSUint64 b: The quotient of the operation
** OUTPUTS: JSUint64 *qp: pointer to quotient
** JSUint64 *rp: pointer to remainder
***********************************************************************/
#define JSLL_UDIVMOD(qp, rp, a, b) \
(*(qp) = ((JSUint64)(a) / (b)), \
*(rp) = ((JSUint64)(a) % (b)))
#else /* !JS_HAVE_LONG_LONG */
#ifdef IS_LITTLE_ENDIAN
#define JSLL_INIT(hi, lo) {JS_INT32(lo), JS_INT32(hi)}
#else
#define JSLL_INIT(hi, lo) {JS_INT32(hi), JS_INT32(lo)}
#endif
#define JSLL_IS_ZERO(a) (((a).hi == 0) && ((a).lo == 0))
#define JSLL_EQ(a, b) (((a).hi == (b).hi) && ((a).lo == (b).lo))
#define JSLL_NE(a, b) (((a).hi != (b).hi) || ((a).lo != (b).lo))
#define JSLL_GE_ZERO(a) (((a).hi >> 31) == 0)
#define JSLL_CMP(a, op, b) (((JSInt32)(a).hi op (JSInt32)(b).hi) || \
(((a).hi == (b).hi) && ((a).lo op (b).lo)))
#define JSLL_UCMP(a, op, b) (((a).hi op (b).hi) || \
(((a).hi == (b).hi) && ((a).lo op (b).lo)))
#define JSLL_AND(r, a, b) ((r).lo = (a).lo & (b).lo, \
(r).hi = (a).hi & (b).hi)
#define JSLL_OR(r, a, b) ((r).lo = (a).lo | (b).lo, \
(r).hi = (a).hi | (b).hi)
#define JSLL_XOR(r, a, b) ((r).lo = (a).lo ^ (b).lo, \
(r).hi = (a).hi ^ (b).hi)
#define JSLL_OR2(r, a) ((r).lo = (r).lo | (a).lo, \
(r).hi = (r).hi | (a).hi)
#define JSLL_NOT(r, a) ((r).lo = ~(a).lo, \
(r).hi = ~(a).hi)
#define JSLL_NEG(r, a) ((r).lo = -(JSInt32)(a).lo, \
(r).hi = -(JSInt32)(a).hi - ((r).lo != 0))
#define JSLL_ADD(r, a, b) { \
JSInt64 _a, _b; \
_a = a; _b = b; \
(r).lo = _a.lo + _b.lo; \
(r).hi = _a.hi + _b.hi + ((r).lo < _b.lo); \
}
#define JSLL_SUB(r, a, b) { \
JSInt64 _a, _b; \
_a = a; _b = b; \
(r).lo = _a.lo - _b.lo; \
(r).hi = _a.hi - _b.hi - (_a.lo < _b.lo); \
}
#define JSLL_MUL(r, a, b) { \
JSInt64 _a, _b; \
_a = a; _b = b; \
JSLL_MUL32(r, _a.lo, _b.lo); \
(r).hi += _a.hi * _b.lo + _a.lo * _b.hi; \
}
#define jslo16(a) ((a) & JS_BITMASK(16))
#define jshi16(a) ((a) >> 16)
#define JSLL_MUL32(r, a, b) { \
JSUint32 _a1, _a0, _b1, _b0, _y0, _y1, _y2, _y3; \
_a1 = jshi16(a), _a0 = jslo16(a); \
_b1 = jshi16(b), _b0 = jslo16(b); \
_y0 = _a0 * _b0; \
_y1 = _a0 * _b1; \
_y2 = _a1 * _b0; \
_y3 = _a1 * _b1; \
_y1 += jshi16(_y0); /* can't carry */ \
_y1 += _y2; /* might carry */ \
if (_y1 < _y2) \
_y3 += (JSUint32)(JS_BIT(16)); /* propagate */ \
(r).lo = (jslo16(_y1) << 16) + jslo16(_y0); \
(r).hi = _y3 + jshi16(_y1); \
}
#define JSLL_UDIVMOD(qp, rp, a, b) jsll_udivmod(qp, rp, a, b)
JS_EXTERN_API(void) jsll_udivmod(JSUint64 *qp, JSUint64 *rp, JSUint64 a, JSUint64 b);
#define JSLL_DIV(r, a, b) { \
JSInt64 _a, _b; \
JSUint32 _negative = (JSInt32)(a).hi < 0; \
if (_negative) { \
JSLL_NEG(_a, a); \
} else { \
_a = a; \
} \
if ((JSInt32)(b).hi < 0) { \
_negative ^= 1; \
JSLL_NEG(_b, b); \
} else { \
_b = b; \
} \
JSLL_UDIVMOD(&(r), 0, _a, _b); \
if (_negative) \
JSLL_NEG(r, r); \
}
#define JSLL_MOD(r, a, b) { \
JSInt64 _a, _b; \
JSUint32 _negative = (JSInt32)(a).hi < 0; \
if (_negative) { \
JSLL_NEG(_a, a); \
} else { \
_a = a; \
} \
if ((JSInt32)(b).hi < 0) { \
JSLL_NEG(_b, b); \
} else { \
_b = b; \
} \
JSLL_UDIVMOD(0, &(r), _a, _b); \
if (_negative) \
JSLL_NEG(r, r); \
}
#define JSLL_SHL(r, a, b) { \
if (b) { \
JSInt64 _a; \
_a = a; \
if ((b) < 32) { \
(r).lo = _a.lo << ((b) & 31); \
(r).hi = (_a.hi << ((b) & 31)) | (_a.lo >> (32 - (b))); \
} else { \
(r).lo = 0; \
(r).hi = _a.lo << ((b) & 31); \
} \
} else { \
(r) = (a); \
} \
}
/* a is an JSInt32, b is JSInt32, r is JSInt64 */
#define JSLL_ISHL(r, a, b) { \
if (b) { \
JSInt64 _a; \
_a.lo = (a); \
_a.hi = 0; \
if ((b) < 32) { \
(r).lo = (a) << ((b) & 31); \
(r).hi = ((a) >> (32 - (b))); \
} else { \
(r).lo = 0; \
(r).hi = (a) << ((b) & 31); \
} \
} else { \
(r).lo = (a); \
(r).hi = 0; \
} \
}
#define JSLL_SHR(r, a, b) { \
if (b) { \
JSInt64 _a; \
_a = a; \
if ((b) < 32) { \
(r).lo = (_a.hi << (32 - (b))) | (_a.lo >> ((b) & 31)); \
(r).hi = (JSInt32)_a.hi >> ((b) & 31); \
} else { \
(r).lo = (JSInt32)_a.hi >> ((b) & 31); \
(r).hi = (JSInt32)_a.hi >> 31; \
} \
} else { \
(r) = (a); \
} \
}
#define JSLL_USHR(r, a, b) { \
if (b) { \
JSInt64 _a; \
_a = a; \
if ((b) < 32) { \
(r).lo = (_a.hi << (32 - (b))) | (_a.lo >> ((b) & 31)); \
(r).hi = _a.hi >> ((b) & 31); \
} else { \
(r).lo = _a.hi >> ((b) & 31); \
(r).hi = 0; \
} \
} else { \
(r) = (a); \
} \
}
#define JSLL_L2I(i, l) ((i) = (l).lo)
#define JSLL_L2UI(ui, l) ((ui) = (l).lo)
#define JSLL_L2F(f, l) { double _d; JSLL_L2D(_d, l); (f) = (JSFloat64)_d; }
#define JSLL_L2D(d, l) { \
int _negative; \
JSInt64 _absval; \
\
_negative = (l).hi >> 31; \
if (_negative) { \
JSLL_NEG(_absval, l); \
} else { \
_absval = l; \
} \
(d) = (double)_absval.hi * 4.294967296e9 + _absval.lo; \
if (_negative) \
(d) = -(d); \
}
#define JSLL_I2L(l, i) { JSInt32 _i = (i) >> 31; (l).lo = (i); (l).hi = _i; }
#define JSLL_UI2L(l, ui) ((l).lo = (ui), (l).hi = 0)
#define JSLL_F2L(l, f) { double _d = (double)f; JSLL_D2L(l, _d); }
#define JSLL_D2L(l, d) { \
int _negative; \
double _absval, _d_hi; \
JSInt64 _lo_d; \
\
_negative = ((d) < 0); \
_absval = _negative ? -(d) : (d); \
\
(l).hi = _absval / 4.294967296e9; \
(l).lo = 0; \
JSLL_L2D(_d_hi, l); \
_absval -= _d_hi; \
_lo_d.hi = 0; \
if (_absval < 0) { \
_lo_d.lo = -_absval; \
JSLL_SUB(l, l, _lo_d); \
} else { \
_lo_d.lo = _absval; \
JSLL_ADD(l, l, _lo_d); \
} \
\
if (_negative) \
JSLL_NEG(l, l); \
}
#endif /* !JS_HAVE_LONG_LONG */
JS_END_EXTERN_C
#endif /* jslong_h___ */

427
mozilla/js/src/jsmath.c Normal file
View File

@@ -0,0 +1,427 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* JS math package.
*/
#include "jsstddef.h"
#include "jslibmath.h"
#include <stdlib.h>
#include "jstypes.h"
#include "jslong.h"
#include "prmjtime.h"
#include "jsapi.h"
#include "jsatom.h"
#include "jscntxt.h"
#include "jsconfig.h"
#include "jslock.h"
#include "jsmath.h"
#include "jsnum.h"
#include "jsobj.h"
#ifndef M_E
#define M_E 2.7182818284590452354
#endif
#ifndef M_LOG2E
#define M_LOG2E 1.4426950408889634074
#endif
#ifndef M_LOG10E
#define M_LOG10E 0.43429448190325182765
#endif
#ifndef M_LN2
#define M_LN2 0.69314718055994530942
#endif
#ifndef M_LN10
#define M_LN10 2.30258509299404568402
#endif
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifndef M_SQRT2
#define M_SQRT2 1.41421356237309504880
#endif
#ifndef M_SQRT1_2
#define M_SQRT1_2 0.70710678118654752440
#endif
static JSConstDoubleSpec math_constants[] = {
{M_E, "E"},
{M_LOG2E, "LOG2E"},
{M_LOG10E, "LOG10E"},
{M_LN2, "LN2"},
{M_LN10, "LN10"},
{M_PI, "PI"},
{M_SQRT2, "SQRT2"},
{M_SQRT1_2, "SQRT1_2"},
{0}
};
static JSClass math_class = {
"Math",
0,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
};
static JSBool
math_abs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, argv[0], &x))
return JS_FALSE;
z = fd_fabs(x);
return js_NewNumberValue(cx, z, rval);
}
static JSBool
math_acos(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, argv[0], &x))
return JS_FALSE;
z = fd_acos(x);
return js_NewNumberValue(cx, z, rval);
}
static JSBool
math_asin(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, argv[0], &x))
return JS_FALSE;
z = fd_asin(x);
return js_NewNumberValue(cx, z, rval);
}
static JSBool
math_atan(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, argv[0], &x))
return JS_FALSE;
z = fd_atan(x);
return js_NewNumberValue(cx, z, rval);
}
static JSBool
math_atan2(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble x, y, z;
if (!js_ValueToNumber(cx, argv[0], &x))
return JS_FALSE;
if (!js_ValueToNumber(cx, argv[1], &y))
return JS_FALSE;
z = fd_atan2(x, y);
return js_NewNumberValue(cx, z, rval);
}
static JSBool
math_ceil(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, argv[0], &x))
return JS_FALSE;
z = fd_ceil(x);
return js_NewNumberValue(cx, z, rval);
}
static JSBool
math_cos(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, argv[0], &x))
return JS_FALSE;
z = fd_cos(x);
return js_NewNumberValue(cx, z, rval);
}
static JSBool
math_exp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, argv[0], &x))
return JS_FALSE;
z = fd_exp(x);
return js_NewNumberValue(cx, z, rval);
}
static JSBool
math_floor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, argv[0], &x))
return JS_FALSE;
z = fd_floor(x);
return js_NewNumberValue(cx, z, rval);
}
static JSBool
math_log(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, argv[0], &x))
return JS_FALSE;
z = fd_log(x);
return js_NewNumberValue(cx, z, rval);
}
static JSBool
math_max(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble x, y, z;
if (!js_ValueToNumber(cx, argv[0], &x))
return JS_FALSE;
if (!js_ValueToNumber(cx, argv[1], &y))
return JS_FALSE;
if (JSDOUBLE_IS_NaN(y)||JSDOUBLE_IS_NaN(x))
{
*rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
return JS_TRUE;
}
if ((x==0)&&(x==y)&&(fd_copysign(1,y)==-1))
z = x;
else
z = (x > y) ? x : y;
return js_NewNumberValue(cx, z, rval);
}
static JSBool
math_min(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble x, y, z;
if (!js_ValueToNumber(cx, argv[0], &x))
return JS_FALSE;
if (!js_ValueToNumber(cx, argv[1], &y))
return JS_FALSE;
if (JSDOUBLE_IS_NaN(y)||JSDOUBLE_IS_NaN(x))
{
*rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
return JS_TRUE;
}
if ((x==0)&&(x==y)&&(fd_copysign(1,y)==-1))
z = y;
else
z = (x < y) ? x : y;
return js_NewNumberValue(cx, z, rval);
}
static JSBool
math_pow(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble x, y, z;
if (!js_ValueToNumber(cx, argv[0], &x))
return JS_FALSE;
if (!js_ValueToNumber(cx, argv[1], &y))
return JS_FALSE;
z = fd_pow(x, y);
return js_NewNumberValue(cx, z, rval);
}
/*
* Math.random() support, lifted from java.util.Random.java.
*/
static void
random_setSeed(JSRuntime *rt, int64 seed)
{
int64 tmp;
JSLL_I2L(tmp, 1000);
JSLL_DIV(seed, seed, tmp);
JSLL_XOR(tmp, seed, rt->rngMultiplier);
JSLL_AND(rt->rngSeed, tmp, rt->rngMask);
}
static void
random_init(JSRuntime *rt)
{
int64 tmp, tmp2;
/* Do at most once. */
if (rt->rngInitialized)
return;
rt->rngInitialized = JS_TRUE;
/* rt->rngMultiplier = 0x5DEECE66DL */
JSLL_ISHL(tmp, 0x5D, 32);
JSLL_UI2L(tmp2, 0xEECE66DL);
JSLL_OR(rt->rngMultiplier, tmp, tmp2);
/* rt->rngAddend = 0xBL */
JSLL_I2L(rt->rngAddend, 0xBL);
/* rt->rngMask = (1L << 48) - 1 */
JSLL_I2L(tmp, 1);
JSLL_SHL(tmp2, tmp, 48);
JSLL_SUB(rt->rngMask, tmp2, tmp);
/* rt->rngDscale = (jsdouble)(1L << 54) */
JSLL_SHL(tmp2, tmp, 54);
JSLL_L2D(rt->rngDscale, tmp2);
/* Finally, set the seed from current time. */
random_setSeed(rt, PRMJ_Now());
}
static uint32
random_next(JSRuntime *rt, int bits)
{
int64 nextseed, tmp;
uint32 retval;
JSLL_MUL(nextseed, rt->rngSeed, rt->rngMultiplier);
JSLL_ADD(nextseed, nextseed, rt->rngAddend);
JSLL_AND(nextseed, nextseed, rt->rngMask);
rt->rngSeed = nextseed;
JSLL_USHR(tmp, nextseed, 48 - bits);
JSLL_L2I(retval, tmp);
return retval;
}
static jsdouble
random_nextDouble(JSRuntime *rt)
{
int64 tmp, tmp2;
jsdouble d;
JSLL_ISHL(tmp, random_next(rt, 27), 27);
JSLL_UI2L(tmp2, random_next(rt, 27));
JSLL_ADD(tmp, tmp, tmp2);
JSLL_L2D(d, tmp);
return d / rt->rngDscale;
}
static JSBool
math_random(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
JSRuntime *rt;
jsdouble z;
rt = cx->runtime;
JS_LOCK_RUNTIME(rt);
random_init(rt);
z = random_nextDouble(rt);
JS_UNLOCK_RUNTIME(rt);
return js_NewNumberValue(cx, z, rval);
}
static JSBool
math_round(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, argv[0], &x))
return JS_FALSE;
z = fd_copysign(fd_floor(x + 0.5), x);
return js_NewNumberValue(cx, z, rval);
}
static JSBool
math_sin(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, argv[0], &x))
return JS_FALSE;
z = fd_sin(x);
return js_NewNumberValue(cx, z, rval);
}
static JSBool
math_sqrt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, argv[0], &x))
return JS_FALSE;
z = fd_sqrt(x);
return js_NewNumberValue(cx, z, rval);
}
static JSBool
math_tan(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble x, z;
if (!js_ValueToNumber(cx, argv[0], &x))
return JS_FALSE;
z = fd_tan(x);
return js_NewNumberValue(cx, z, rval);
}
#if JS_HAS_TOSOURCE
static JSBool
math_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
*rval = ATOM_KEY(cx->runtime->atomState.MathAtom);
return JS_TRUE;
}
#endif
static JSFunctionSpec math_static_methods[] = {
#ifdef JS_HAS_TOSOURCE
{js_toSource_str, math_toSource, 0},
#endif
{"abs", math_abs, 1},
{"acos", math_acos, 1},
{"asin", math_asin, 1},
{"atan", math_atan, 1},
{"atan2", math_atan2, 2},
{"ceil", math_ceil, 1},
{"cos", math_cos, 1},
{"exp", math_exp, 1},
{"floor", math_floor, 1},
{"log", math_log, 1},
{"max", math_max, 2},
{"min", math_min, 2},
{"pow", math_pow, 2},
{"random", math_random, 0},
{"round", math_round, 1},
{"sin", math_sin, 1},
{"sqrt", math_sqrt, 1},
{"tan", math_tan, 1},
{0}
};
JSObject *
js_InitMathClass(JSContext *cx, JSObject *obj)
{
JSObject *Math;
Math = JS_DefineObject(cx, obj, "Math", &math_class, NULL, 0);
if (!Math)
return NULL;
if (!JS_DefineFunctions(cx, Math, math_static_methods))
return NULL;
if (!JS_DefineConstDoubles(cx, Math, math_constants))
return NULL;
return Math;
}

18
mozilla/js/src/jsmath.h Normal file
View File

@@ -0,0 +1,18 @@
/* -*- Mode: C; tab-width: 8 -*-
* Copyright (C) 1998 Netscape Communications Corporation, All Rights Reserved.
*/
#ifndef jsmath_h___
#define jsmath_h___
/*
* JS math functions.
*/
JS_BEGIN_EXTERN_C
extern JSObject *
js_InitMathClass(JSContext *cx, JSObject *obj);
JS_END_EXTERN_C
#endif /* jsmath_h___ */

840
mozilla/js/src/jsnum.c Normal file
View File

@@ -0,0 +1,840 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* JS number type and wrapper class.
*/
#include "jsstddef.h"
#include <errno.h>
#ifdef XP_PC
#include <float.h>
#endif
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "jstypes.h"
#include "jsutil.h" /* Added by JSIFY */
#include "jsdtoa.h"
#include "jsprf.h"
#include "jsapi.h"
#include "jsatom.h"
#include "jscntxt.h"
#include "jsconfig.h"
#include "jsgc.h"
#include "jsinterp.h"
#include "jsnum.h"
#include "jsobj.h"
#include "jsopcode.h"
#include "jsstr.h"
union dpun {
struct {
#ifdef IS_LITTLE_ENDIAN
uint32 lo, hi;
#else
uint32 hi, lo;
#endif
} s;
jsdouble d;
};
static JSBool
num_isNaN(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble x;
if (!js_ValueToNumber(cx, argv[0], &x))
return JS_FALSE;
*rval = BOOLEAN_TO_JSVAL(JSDOUBLE_IS_NaN(x));
return JS_TRUE;
}
static JSBool
num_isFinite(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble x;
if (!js_ValueToNumber(cx, argv[0], &x))
return JS_FALSE;
*rval = BOOLEAN_TO_JSVAL(JSDOUBLE_IS_FINITE(x));
return JS_TRUE;
}
static JSBool
num_parseFloat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
JSString *str;
jsdouble d;
const jschar *ep;
str = js_ValueToString(cx, argv[0]);
if (!str)
return JS_FALSE;
if (!js_strtod(cx, str->chars, &ep, &d))
return JS_FALSE;
if (ep == str->chars) {
*rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
return JS_TRUE;
}
return js_NewNumberValue(cx, d, rval);
}
/* See ECMA 15.1.2.2. */
static JSBool
num_parseInt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
JSString *str;
jsint radix;
jsdouble d;
const jschar *ep;
str = js_ValueToString(cx, argv[0]);
if (!str)
return JS_FALSE;
if (argc > 1) {
if (!js_ValueToECMAInt32(cx, argv[1], &radix))
return JS_FALSE;
} else
radix = 0;
if (radix != 0 && (radix < 2 || radix > 36)) {
*rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
return JS_TRUE;
}
if (!js_strtointeger(cx, str->chars, &ep, radix, &d))
return JS_FALSE;
if (ep == str->chars) {
*rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
return JS_TRUE;
}
return js_NewNumberValue(cx, d, rval);
}
static JSFunctionSpec number_functions[] = {
{"isNaN", num_isNaN, 1},
{"isFinite", num_isFinite, 1},
{"parseFloat", num_parseFloat, 1},
{"parseInt", num_parseInt, 2},
{0}
};
static JSClass number_class = {
"Number",
JSCLASS_HAS_PRIVATE,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
};
static JSBool
Number(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble d;
jsval v;
if (argc != 0) {
if (!js_ValueToNumber(cx, argv[0], &d))
return JS_FALSE;
} else {
d = 0.0;
}
if (!js_NewNumberValue(cx, d, &v))
return JS_FALSE;
if (!cx->fp->constructing) {
*rval = v;
return JS_TRUE;
}
OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, v);
return JS_TRUE;
}
#if JS_HAS_TOSOURCE
static JSBool
num_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsval v;
jsdouble d;
size_t i;
char buf[64];
JSString *str;
if (!JS_InstanceOf(cx, obj, &number_class, argv))
return JS_FALSE;
v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
if (!JSVAL_IS_NUMBER(v))
return js_obj_toSource(cx, obj, argc, argv, rval);
d = JSVAL_IS_INT(v) ? (jsdouble)JSVAL_TO_INT(v) : *JSVAL_TO_DOUBLE(v);
i = JS_snprintf(buf, sizeof buf, "(new %s(", number_class.name);
JS_cnvtf(buf + i, sizeof buf - i, 20, d);
i = strlen(buf);
JS_snprintf(buf + i, sizeof buf - i, "))");
str = JS_NewStringCopyZ(cx, buf);
if (!str)
return JS_FALSE;
*rval = STRING_TO_JSVAL(str);
return JS_TRUE;
}
#endif
static JSBool
num_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsval v;
jsdouble d;
jsint base, ival, dval;
char *bp, buf[32];
JSString *str;
if (!JS_InstanceOf(cx, obj, &number_class, argv))
return JS_FALSE;
v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
if (!JSVAL_IS_NUMBER(v))
return js_obj_toString(cx, obj, argc, argv, rval);
d = JSVAL_IS_INT(v) ? (jsdouble)JSVAL_TO_INT(v) : *JSVAL_TO_DOUBLE(v);
if (argc != 0) {
if (!js_ValueToECMAInt32(cx, argv[0], &base))
return JS_FALSE;
if (base < 2 || base > 36) {
char numBuf[12];
JS_snprintf(numBuf, sizeof numBuf, "%ld", (long) base);
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_RADIX,
numBuf);
return JS_FALSE;
}
if (base != 10 && JSDOUBLE_IS_FINITE(d)) {
ival = (jsint) js_DoubleToInteger(d);
bp = buf + sizeof buf;
for (*--bp = '\0'; ival != 0 && --bp >= buf; ival /= base) {
dval = ival % base;
*bp = (char)((dval >= 10) ? 'a' - 10 + dval : '0' + dval);
}
if (*bp == '\0')
*--bp = '0';
str = JS_NewStringCopyZ(cx, bp);
} else {
str = js_NumberToString(cx, d);
}
} else {
str = js_NumberToString(cx, d);
}
if (!str)
return JS_FALSE;
*rval = STRING_TO_JSVAL(str);
return JS_TRUE;
}
static JSBool
num_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
if (!JS_InstanceOf(cx, obj, &number_class, argv))
return JS_FALSE;
*rval = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
return JS_TRUE;
}
static JSFunctionSpec number_methods[] = {
#if JS_HAS_TOSOURCE
{js_toSource_str, num_toSource, 0},
#endif
{js_toString_str, num_toString, 0},
{js_valueOf_str, num_valueOf, 0},
{0}
};
/* NB: Keep this in synch with number_constants[]. */
enum nc_slot {
NC_NaN,
NC_POSITIVE_INFINITY,
NC_NEGATIVE_INFINITY,
NC_MAX_VALUE,
NC_MIN_VALUE,
NC_LIMIT
};
/*
* Some to most C compilers forbid spelling these at compile time, or barf
* if you try, so all but MAX_VALUE are set at runtime by js_InitNumberClass
* using union dpun.
*/
static JSConstDoubleSpec number_constants[] = {
{0, "NaN"},
{0, "POSITIVE_INFINITY"},
{0, "NEGATIVE_INFINITY"},
{1.7976931348623157E+308, "MAX_VALUE"},
{0, "MIN_VALUE"},
{0}
};
static jsdouble NaN;
JSObject *
js_InitNumberClass(JSContext *cx, JSObject *obj)
{
JSRuntime *rt;
union dpun u;
JSObject *proto, *ctor;
rt = cx->runtime;
if (!rt->jsNaN) {
#ifdef XP_PC
#ifdef XP_OS2
/*DSR071597 - I have no idea what this really does other than mucking with the floating */
/*point unit, but it does fix a "floating point underflow" exception I am getting, and there*/
/*is similar code in the Hursley java. Making sure we have the same code in Javascript */
/*where Netscape was calling control87 on Windows... */
_control87(MCW_EM+PC_53+RC_NEAR,MCW_EM+MCW_PC+MCW_RC);
#else
_control87(MCW_EM, MCW_EM);
#endif
#endif
u.s.hi = JSDOUBLE_HI32_EXPMASK | JSDOUBLE_HI32_MANTMASK;
u.s.lo = 0xffffffff;
number_constants[NC_NaN].dval = NaN = u.d;
rt->jsNaN = js_NewDouble(cx, NaN);
if (!rt->jsNaN || !js_LockGCThing(cx, rt->jsNaN))
return NULL;
u.s.hi = JSDOUBLE_HI32_EXPMASK;
u.s.lo = 0x00000000;
number_constants[NC_POSITIVE_INFINITY].dval = u.d;
rt->jsPositiveInfinity = js_NewDouble(cx, u.d);
if (!rt->jsPositiveInfinity ||
!js_LockGCThing(cx, rt->jsPositiveInfinity)) {
return NULL;
}
u.s.hi = JSDOUBLE_HI32_SIGNBIT | JSDOUBLE_HI32_EXPMASK;
u.s.lo = 0x00000000;
number_constants[NC_NEGATIVE_INFINITY].dval = u.d;
rt->jsNegativeInfinity = js_NewDouble(cx, u.d);
if (!rt->jsNegativeInfinity ||
!js_LockGCThing(cx, rt->jsNegativeInfinity)) {
return NULL;
}
u.s.hi = 0;
u.s.lo = 1;
number_constants[NC_MIN_VALUE].dval = u.d;
}
if (!JS_DefineFunctions(cx, obj, number_functions))
return NULL;
proto = JS_InitClass(cx, obj, NULL, &number_class, Number, 1,
NULL, number_methods, NULL, NULL);
if (!proto || !(ctor = JS_GetConstructor(cx, proto)))
return NULL;
OBJ_SET_SLOT(cx, proto, JSSLOT_PRIVATE, JSVAL_ZERO);
if (!JS_DefineConstDoubles(cx, ctor, number_constants))
return NULL;
/* ECMA 15.1.1.1 */
if (!JS_DefineProperty(cx, obj, "NaN", DOUBLE_TO_JSVAL(rt->jsNaN),
NULL, NULL, 0)) {
return NULL;
}
/* ECMA 15.1.1.2 */
if (!JS_DefineProperty(cx, obj, "Infinity",
DOUBLE_TO_JSVAL(rt->jsPositiveInfinity),
NULL, NULL, 0)) {
return NULL;
}
return proto;
}
jsdouble *
js_NewDouble(JSContext *cx, jsdouble d)
{
jsdouble *dp;
dp = js_AllocGCThing(cx, GCX_DOUBLE);
if (!dp)
return NULL;
*dp = d;
return dp;
}
void
js_FinalizeDouble(JSContext *cx, jsdouble *dp)
{
*dp = NaN;
}
JSBool
js_NewDoubleValue(JSContext *cx, jsdouble d, jsval *rval)
{
jsdouble *dp;
dp = js_NewDouble(cx, d);
if (!dp)
return JS_FALSE;
*rval = DOUBLE_TO_JSVAL(dp);
return JS_TRUE;
}
JSBool
js_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval)
{
jsint i;
if (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i)) {
*rval = INT_TO_JSVAL(i);
} else {
if (!js_NewDoubleValue(cx, d, rval))
return JS_FALSE;
}
return JS_TRUE;
}
JSObject *
js_NumberToObject(JSContext *cx, jsdouble d)
{
JSObject *obj;
jsval v;
obj = js_NewObject(cx, &number_class, NULL, NULL);
if (!obj)
return NULL;
if (!js_NewNumberValue(cx, d, &v)) {
cx->newborn[GCX_OBJECT] = NULL;
return NULL;
}
OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, v);
return obj;
}
/* XXXbe rewrite me to be ECMA-based! */
JSString *
js_NumberToString(JSContext *cx, jsdouble d)
{
jsint i;
char buf[32];
if (JSDOUBLE_IS_INT(d, i)) {
JS_snprintf(buf, sizeof buf, "%ld", (long)i);
} else {
JS_cnvtf(buf, sizeof buf, 20, d);
}
return JS_NewStringCopyZ(cx, buf);
}
JSBool
js_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp)
{
JSObject *obj;
JSString *str;
const jschar *ep;
jsdouble d;
if (JSVAL_IS_OBJECT(v)) {
obj = JSVAL_TO_OBJECT(v);
if (!obj) {
*dp = 0;
return JS_TRUE;
}
if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_NUMBER, &v))
return JS_FALSE;
}
if (JSVAL_IS_INT(v)) {
*dp = (jsdouble)JSVAL_TO_INT(v);
} else if (JSVAL_IS_DOUBLE(v)) {
*dp = *JSVAL_TO_DOUBLE(v);
} else if (JSVAL_IS_STRING(v)) {
str = JSVAL_TO_STRING(v);
errno = 0;
/* Note that ECMAScript doesn't treat numbers beginning with a zero as octal numbers here.
* This works because all such numbers will be interpreted as decimal by js_strtod and
* will never get passed to js_strtointeger, which would interpret them as octal. */
if ((!js_strtod(cx, str->chars, &ep, &d) || js_SkipWhiteSpace(ep) != str->chars + str->length) &&
(!js_strtointeger(cx, str->chars, &ep, 0, &d) || js_SkipWhiteSpace(ep) != str->chars + str->length)) {
goto badstr;
}
*dp = d;
} else if (JSVAL_IS_BOOLEAN(v)) {
*dp = JSVAL_TO_BOOLEAN(v) ? 1 : 0;
} else {
#if JS_BUG_FALLIBLE_TONUM
str = js_DecompileValueGenerator(cx, v, NULL);
badstr:
if (str) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NAN,
JS_GetStringBytes(str));
}
return JS_FALSE;
#else
badstr:
*dp = *cx->runtime->jsNaN;
#endif
}
return JS_TRUE;
}
JSBool
js_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip)
{
jsdouble d;
if (!js_ValueToNumber(cx, v, &d))
return JS_FALSE;
return js_DoubleToECMAInt32(cx, d, ip);
}
JSBool
js_DoubleToECMAInt32(JSContext *cx, jsdouble d, int32 *ip)
{
jsdouble two32 = 4294967296.0;
jsdouble two31 = 2147483648.0;
if (!JSDOUBLE_IS_FINITE(d) || d == 0) {
*ip = 0;
return JS_TRUE;
}
d = fmod(d, two32);
d = d >= 0 ? d : d + two32;
if (d >= two31)
*ip = (int32)(d - two32);
else
*ip = (int32)d;
return JS_TRUE;
}
JSBool
js_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip)
{
jsdouble d;
if (!js_ValueToNumber(cx, v, &d))
return JS_FALSE;
return js_DoubleToECMAUint32(cx, d, ip);
}
JSBool
js_DoubleToECMAUint32(JSContext *cx, jsdouble d, uint32 *ip)
{
JSBool neg;
jsdouble two32 = 4294967296.0;
if (!JSDOUBLE_IS_FINITE(d) || d == 0) {
*ip = 0;
return JS_TRUE;
}
neg = (d < 0);
d = floor(neg ? -d : d);
d = neg ? -d : d;
d = fmod(d, two32);
d = d >= 0 ? d : d + two32;
*ip = (uint32)d;
return JS_TRUE;
}
JSBool
js_ValueToInt32(JSContext *cx, jsval v, int32 *ip)
{
jsdouble d;
JSString *str;
if (!js_ValueToNumber(cx, v, &d))
return JS_FALSE;
if (JSDOUBLE_IS_NaN(d) || d <= -2147483649.0 || 2147483648.0 <= d) {
str = js_DecompileValueGenerator(cx, v, NULL);
if (str) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_CANT_CONVERT, JS_GetStringBytes(str));
}
return JS_FALSE;
}
*ip = (int32)floor(d + 0.5); /* Round to nearest */
return JS_TRUE;
}
JSBool
js_ValueToUint16(JSContext *cx, jsval v, uint16 *ip)
{
jsdouble d;
jsuint i, m;
JSBool neg;
if (!js_ValueToNumber(cx, v, &d))
return JS_FALSE;
if (d == 0 || !JSDOUBLE_IS_FINITE(d)) {
*ip = 0;
return JS_TRUE;
}
i = (jsuint)d;
if ((jsdouble)i == d) {
*ip = (uint16)i;
return JS_TRUE;
}
neg = (d < 0);
d = floor(neg ? -d : d);
d = neg ? -d : d;
m = JS_BIT(16);
d = fmod(d, m);
if (d < 0)
d += m;
*ip = (uint16) d;
return JS_TRUE;
}
jsdouble
js_DoubleToInteger(jsdouble d)
{
JSBool neg;
if (d == 0)
return d;
if (!JSDOUBLE_IS_FINITE(d)) {
if (JSDOUBLE_IS_NaN(d))
return 0;
return d;
}
neg = (d < 0);
d = floor(neg ? -d : d);
return neg ? -d : d;
}
JSBool
js_strtod(JSContext *cx, const jschar *s, const jschar **ep, jsdouble *dp)
{
size_t i;
char *cstr, *istr, *estr;
JSBool negative;
jsdouble d;
const jschar *s1 = js_SkipWhiteSpace(s);
size_t length = js_strlen(s1);
cstr = malloc(length + 1);
if (!cstr)
return JS_FALSE;
for (i = 0; i <= length; i++) {
if (s1[i] >> 8) {
cstr[i] = 0;
break;
}
cstr[i] = (char)s1[i];
}
istr = cstr;
if ((negative = (*istr == '-')) != 0 || *istr == '+')
istr++;
if (!strncmp(istr, "Infinity", 8)) {
d = *(negative ? cx->runtime->jsNegativeInfinity : cx->runtime->jsPositiveInfinity);
estr = istr + 8;
} else {
errno = 0;
d = JS_strtod(cstr, &estr);
if (errno == ERANGE)
if (d == HUGE_VAL)
d = *cx->runtime->jsPositiveInfinity;
else if (d == -HUGE_VAL)
d = *cx->runtime->jsNegativeInfinity;
#ifdef HPUX
if (d == 0.0 && negative) {
/*
* "-0", "-1e-2000" come out as positive zero
* here on HPUX. Force a negative zero instead.
*/
JSDOUBLE_HI32(d) = JSDOUBLE_HI32_SIGNBIT;
JSDOUBLE_LO32(d) = 0;
}
#endif
}
free(cstr);
i = estr - cstr;
*ep = i ? s1 + i : s;
*dp = d;
return JS_TRUE;
}
struct BinaryDigitReader
{
uintN base; /* Base of number; must be a power of 2 */
uintN digit; /* Current digit value in radix given by base */
uintN digitMask; /* Mask to extract the next bit from digit */
const jschar *digits; /* Pointer to the remaining digits */
const jschar *end; /* Pointer to first non-digit */
};
/* Return the next binary digit from the number or -1 if done */
static intN GetNextBinaryDigit(struct BinaryDigitReader *bdr)
{
intN bit;
if (bdr->digitMask == 0) {
uintN c;
if (bdr->digits == bdr->end)
return -1;
c = *bdr->digits++;
if ('0' <= c && c <= '9')
bdr->digit = c - '0';
else if ('a' <= c && c <= 'z')
bdr->digit = c - 'a' + 10;
else bdr->digit = c - 'A' + 10;
bdr->digitMask = bdr->base >> 1;
}
bit = (bdr->digit & bdr->digitMask) != 0;
bdr->digitMask >>= 1;
return bit;
}
JSBool
js_strtointeger(JSContext *cx, const jschar *s, const jschar **ep, jsint base, jsdouble *dp)
{
JSBool negative;
jsdouble value;
const jschar *start;
const jschar *s1 = js_SkipWhiteSpace(s);
if ((negative = (*s1 == '-')) != 0 || *s1 == '+')
s1++;
if (base == 0)
/* No base supplied, or some base that evaluated to 0. */
if (*s1 == '0')
/* It's either hex or octal; only increment char if str isn't '0' */
if (s1[1] == 'X' || s1[1] == 'x') { /* Hex */
s1 += 2;
base = 16;
} else /* Octal */
base = 8;
else
base = 10; /* Default to decimal. */
else if (base == 16 && *s1 == '0' && (s1[1] == 'X' || s1[1] == 'x'))
/* If base is 16, ignore hex prefix. */
s1 += 2;
/* Done with the preliminaries; find some prefix of the string that's
* a number in the given base.
*/
start = s1; /* Mark - if string is empty, we return NaN. */
value = 0.0;
while (1) {
uintN digit;
jschar c = *s1;
if ('0' <= c && c <= '9')
digit = c - '0';
else if ('a' <= c && c <= 'z')
digit = c - 'a' + 10;
else if ('A' <= c && c <= 'Z')
digit = c - 'A' + 10;
else
break;
if (digit >= (uintN)base)
break;
value = value*base + digit;
s1++;
}
if (value >= 9007199254740992.0)
if (base == 10) {
/* If we're accumulating a decimal number and the number is >= 2^53, then
* the result from the repeated multiply-add above may be inaccurate. Call
* JS_strtod to get the correct answer.
*/
size_t i;
size_t length = s1 - start;
char *cstr = malloc(length + 1);
char *estr;
if (!cstr)
return JS_FALSE;
for (i = 0; i != length; i++)
cstr[i] = (char)start[i];
cstr[length] = 0;
errno = 0;
value = JS_strtod(cstr, &estr);
if (errno == ERANGE && value == HUGE_VAL)
value = *cx->runtime->jsPositiveInfinity;
free(cstr);
} else if (base == 2 || base == 4 || base == 8 || base == 16 || base == 32) {
/* The number may also be inaccurate for one of these bases. This
* happens if the addition in value*base + digit causes a round-down
* to an even least significant mantissa bit when the first dropped bit
* is a one. If any of the following digits in the number (which haven't
* been added in yet) are nonzero then the correct action would have
* been to round up instead of down. An example of this occurs when
* reading the number 0x1000000000000081, which rounds to 0x1000000000000000
* instead of 0x1000000000000100.
*/
struct BinaryDigitReader bdr;
intN bit, bit2;
intN j;
bdr.base = base;
bdr.digitMask = 0;
bdr.digits = start;
bdr.end = s1;
value = 0.0;
/* Skip leading zeros. */
do {
bit = GetNextBinaryDigit(&bdr);
} while (bit == 0);
if (bit == 1) {
/* Gather the 53 significant bits (including the leading 1) */
value = 1.0;
for (j = 52; j; j--) {
bit = GetNextBinaryDigit(&bdr);
if (bit < 0)
goto done;
value = value*2 + bit;
}
/* bit2 is the 54th bit (the first dropped from the mantissa) */
bit2 = GetNextBinaryDigit(&bdr);
if (bit2 >= 0) {
jsdouble factor = 2.0;
intN sticky = 0; /* sticky is 1 if any bit beyond the 54th is 1 */
intN bit3;
while ((bit3 = GetNextBinaryDigit(&bdr)) >= 0) {
sticky |= bit3;
factor *= 2;
}
value += bit2 & (bit | sticky);
value *= factor;
}
done:;
}
}
/* We don't worry about inaccurate numbers for any other base. */
if (s1 == start) {
*dp = 0.0;
*ep = s;
} else {
*dp = negative ? -value : value;
*ep = s1;
}
return JS_TRUE;
}

167
mozilla/js/src/jsnum.h Normal file
View File

@@ -0,0 +1,167 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsnum_h___
#define jsnum_h___
/*
* JS number (IEEE double) interface.
*
* JS numbers are optimistically stored in the top 31 bits of 32-bit integers,
* but floating point literals, results that overflow 31 bits, and division and
* modulus operands and results require a 64-bit IEEE double. These are GC'ed
* and pointed to by 32-bit jsvals on the stack and in object properties.
*
* When a JS number is treated as an object (followed by . or []), the runtime
* wraps it with a JSObject whose valueOf method returns the unwrapped number.
*/
JS_BEGIN_EXTERN_C
#ifdef IS_LITTLE_ENDIAN
#define JSDOUBLE_HI32(x) (((uint32 *)&(x))[1])
#define JSDOUBLE_LO32(x) (((uint32 *)&(x))[0])
#else
#define JSDOUBLE_HI32(x) (((uint32 *)&(x))[0])
#define JSDOUBLE_LO32(x) (((uint32 *)&(x))[1])
#endif
#define JSDOUBLE_HI32_SIGNBIT 0x80000000
#define JSDOUBLE_HI32_EXPMASK 0x7ff00000
#define JSDOUBLE_HI32_MANTMASK 0x000fffff
#define JSDOUBLE_IS_NaN(x) \
((JSDOUBLE_HI32(x) & JSDOUBLE_HI32_EXPMASK) == JSDOUBLE_HI32_EXPMASK && \
(JSDOUBLE_LO32(x) || (JSDOUBLE_HI32(x) & JSDOUBLE_HI32_MANTMASK)))
#define JSDOUBLE_IS_INFINITE(x) \
((JSDOUBLE_HI32(x) & ~JSDOUBLE_HI32_SIGNBIT) == JSDOUBLE_HI32_EXPMASK && \
!JSDOUBLE_LO32(x))
#define JSDOUBLE_IS_FINITE(x) \
((JSDOUBLE_HI32(x) & JSDOUBLE_HI32_EXPMASK) != JSDOUBLE_HI32_EXPMASK)
#define JSDOUBLE_IS_NEGZERO(d) (JSDOUBLE_HI32(d) == JSDOUBLE_HI32_SIGNBIT && \
JSDOUBLE_LO32(d) == 0)
/*
* JSDOUBLE_IS_INT first checks that d is neither NaN nor infinite, to avoid
* raising SIGFPE on platforms such as Alpha Linux, then (only if the cast is
* safe) leaves i as (jsint)d. This also avoid anomalous NaN floating point
* comparisons under MSVC.
*/
#define JSDOUBLE_IS_INT(d, i) (JSDOUBLE_IS_FINITE(d) && !JSDOUBLE_IS_NEGZERO(d) \
&& ((d) == (i = (jsint)(d))))
/* Initialize the Number class, returning its prototype object. */
extern JSObject *
js_InitNumberClass(JSContext *cx, JSObject *obj);
/* GC-allocate a new JS number. */
extern jsdouble *
js_NewDouble(JSContext *cx, jsdouble d);
extern void
js_FinalizeDouble(JSContext *cx, jsdouble *dp);
extern JSBool
js_NewDoubleValue(JSContext *cx, jsdouble d, jsval *rval);
extern JSBool
js_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval);
/* Construct a Number instance that wraps around d. */
extern JSObject *
js_NumberToObject(JSContext *cx, jsdouble d);
/* Convert a number to a GC'ed string. */
extern JSString *
js_NumberToString(JSContext *cx, jsdouble d);
/*
* Convert a value to a number, returning false after reporting any error,
* otherwise returning true with *dp set.
*/
extern JSBool
js_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp);
/*
* Convert a value or a double to an int32, according to the ECMA rules
* for ToInt32.
*/
extern JSBool
js_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip);
extern JSBool
js_DoubleToECMAInt32(JSContext *cx, jsdouble d, int32 *ip);
/*
* Convert a value or a double to a uint32, according to the ECMA rules
* for ToUint32.
*/
extern JSBool
js_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip);
extern JSBool
js_DoubleToECMAUint32(JSContext *cx, jsdouble d, uint32 *ip);
/*
* Convert a value to a number, then to an int32 if it fits by rounding to
* nearest; but failing with an error report if the double is out of range
* or unordered.
*/
extern JSBool
js_ValueToInt32(JSContext *cx, jsval v, int32 *ip);
/*
* Convert a value to a number, then to a uint16 according to the ECMA rules
* for ToUint16.
*/
extern JSBool
js_ValueToUint16(JSContext *cx, jsval v, uint16 *ip);
/*
* Convert a jsdouble to an integral number, stored in a jsdouble.
* If d is NaN, return 0. If d is an infinity, return it without conversion.
*/
extern jsdouble
js_DoubleToInteger(jsdouble d);
/*
* Similar to strtod except that replaces overflows with infinities of the correct
* sign and underflows with zeros of the correct sign. Guaranteed to return the
* closest double number to the given input in dp.
* Also allows inputs of the form [+|-]Infinity, which produce an infinity of the
* appropriate sign. The case of the "Infinity" string must match.
* If the string does not have a number in it, set *ep to s and return 0.0 in dp.
* Return false if out of memory.
*/
extern JSBool
js_strtod(JSContext *cx, const jschar *s, const jschar **ep, jsdouble *dp);
/*
* Similar to strtol except that handles integers of arbitrary size. Guaranteed to
* return the closest double number to the given input when radix is 10 or a power of 2.
* May experience roundoff errors for very large numbers of a different radix.
* If the string does not have a number in it, set *ep to s and return 0.0 in dp.
* Return false if out of memory.
*/
extern JSBool
js_strtointeger(JSContext *cx, const jschar *s, const jschar **ep, jsint radix, jsdouble *dp);
JS_END_EXTERN_C
#endif /* jsnum_h___ */

2692
mozilla/js/src/jsobj.c Normal file

File diff suppressed because it is too large Load Diff

327
mozilla/js/src/jsobj.h Normal file
View File

@@ -0,0 +1,327 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsobj_h___
#define jsobj_h___
/*
* JS object definitions.
*
* A JS object consists of a possibly-shared object descriptor containing
* ordered property names, called the map; and a dense vector of property
* values, called slots. The map/slot pointer pair is GC'ed, while the map
* is reference counted and the slot vector is malloc'ed.
*/
#include "jshash.h" /* Added by JSIFY */
#include "jsprvtd.h"
#include "jspubtd.h"
JS_BEGIN_EXTERN_C
struct JSObjectMap {
jsrefcount nrefs; /* count of all referencing objects */
JSObjectOps *ops; /* high level object operation vtable */
uint32 nslots; /* length of obj->slots vector */
uint32 freeslot; /* index of next free obj->slots element */
};
/* Shorthand macros for frequently-made calls. */
#if defined JS_THREADSAFE && defined DEBUG
#define OBJ_LOOKUP_PROPERTY(cx,obj,id,objp,propp) \
(obj)->map->ops->lookupProperty(cx,obj,id,objp,propp,__FILE__,__LINE__)
#else
#define OBJ_LOOKUP_PROPERTY(cx,obj,id,objp,propp) \
(obj)->map->ops->lookupProperty(cx,obj,id,objp,propp)
#endif
#define OBJ_DEFINE_PROPERTY(cx,obj,id,value,getter,setter,attrs,propp) \
(obj)->map->ops->defineProperty(cx,obj,id,value,getter,setter,attrs,propp)
#define OBJ_GET_PROPERTY(cx,obj,id,vp) \
(obj)->map->ops->getProperty(cx,obj,id,vp)
#define OBJ_SET_PROPERTY(cx,obj,id,vp) \
(obj)->map->ops->setProperty(cx,obj,id,vp)
#define OBJ_GET_ATTRIBUTES(cx,obj,id,prop,attrsp) \
(obj)->map->ops->getAttributes(cx,obj,id,prop,attrsp)
#define OBJ_SET_ATTRIBUTES(cx,obj,id,prop,attrsp) \
(obj)->map->ops->setAttributes(cx,obj,id,prop,attrsp)
#define OBJ_DELETE_PROPERTY(cx,obj,id,rval) \
(obj)->map->ops->deleteProperty(cx,obj,id,rval)
#define OBJ_DEFAULT_VALUE(cx,obj,hint,vp) \
(obj)->map->ops->defaultValue(cx,obj,hint,vp)
#define OBJ_ENUMERATE(cx,obj,enum_op,statep,idp) \
(obj)->map->ops->enumerate(cx,obj,enum_op,statep,idp)
#define OBJ_CHECK_ACCESS(cx,obj,id,mode,vp,attrsp) \
(obj)->map->ops->checkAccess(cx,obj,id,mode,vp,attrsp)
/* These two are time-optimized to avoid stub calls. */
#define OBJ_THIS_OBJECT(cx,obj) \
((obj)->map->ops->thisObject \
? (obj)->map->ops->thisObject(cx,obj) \
: (obj))
#define OBJ_DROP_PROPERTY(cx,obj,prop) \
((obj)->map->ops->dropProperty \
? (obj)->map->ops->dropProperty(cx,obj,prop) \
: (void)0)
struct JSObject {
JSObjectMap *map;
jsval *slots;
};
#define JSSLOT_PROTO 0
#define JSSLOT_PARENT 1
#define JSSLOT_CLASS 2
#define JSSLOT_PRIVATE 3
#define JSSLOT_START 3
#define JSSLOT_FREE(clasp) (((clasp)->flags & JSCLASS_HAS_PRIVATE) \
? JSSLOT_PRIVATE + 1 \
: JSSLOT_START)
#define JS_INITIAL_NSLOTS 5
#ifdef DEBUG
#define MAP_CHECK_SLOT(map,slot) \
JS_ASSERT((uint32)slot < JS_MAX((map)->nslots, (map)->freeslot))
#define OBJ_CHECK_SLOT(obj,slot) \
MAP_CHECK_SLOT((obj)->map, slot)
#else
#define OBJ_CHECK_SLOT(obj,slot) ((void)0)
#endif
/* Fast macros for accessing obj->slots while obj is locked (if thread-safe). */
#define LOCKED_OBJ_GET_SLOT(obj,slot) \
(OBJ_CHECK_SLOT(obj, slot), (obj)->slots[slot])
#define LOCKED_OBJ_SET_SLOT(obj,slot,value) \
(OBJ_CHECK_SLOT(obj, slot), (obj)->slots[slot] = (value))
#define LOCKED_OBJ_GET_PROTO(obj) \
JSVAL_TO_OBJECT(LOCKED_OBJ_GET_SLOT(obj, JSSLOT_PROTO))
#define LOCKED_OBJ_GET_CLASS(obj) \
((JSClass *)JSVAL_TO_PRIVATE(LOCKED_OBJ_GET_SLOT(obj, JSSLOT_CLASS)))
#ifdef JS_THREADSAFE
/* Thread-safe functions and wrapper macros for accessing obj->slots. */
#define OBJ_GET_SLOT(cx,obj,slot) \
(OBJ_CHECK_SLOT(obj, slot), js_GetSlotWhileLocked(cx, obj, slot))
#define OBJ_SET_SLOT(cx,obj,slot,value) \
(OBJ_CHECK_SLOT(obj, slot), js_SetSlotWhileLocked(cx, obj, slot, value))
#else /* !JS_THREADSAFE */
#define OBJ_GET_SLOT(cx,obj,slot) LOCKED_OBJ_GET_SLOT(obj,slot)
#define OBJ_SET_SLOT(cx,obj,slot,value) LOCKED_OBJ_SET_SLOT(obj,slot,value)
#endif /* !JS_THREADSAFE */
/* Thread-safe proto, parent, and class access macros. */
#define OBJ_GET_PROTO(cx,obj) \
JSVAL_TO_OBJECT(OBJ_GET_SLOT(cx, obj, JSSLOT_PROTO))
#define OBJ_SET_PROTO(cx,obj,proto) \
OBJ_SET_SLOT(cx, obj, JSSLOT_PROTO, OBJECT_TO_JSVAL(proto))
#define OBJ_GET_PARENT(cx,obj) \
JSVAL_TO_OBJECT(OBJ_GET_SLOT(cx, obj, JSSLOT_PARENT))
#define OBJ_SET_PARENT(cx,obj,parent) \
OBJ_SET_SLOT(cx, obj, JSSLOT_PARENT, OBJECT_TO_JSVAL(parent))
#define OBJ_GET_CLASS(cx,obj) \
((JSClass *)JSVAL_TO_PRIVATE(OBJ_GET_SLOT(cx, obj, JSSLOT_CLASS)))
/* Test whether a map or object is native. */
#define MAP_IS_NATIVE(map) ((map)->ops == &js_ObjectOps || \
(map)->ops == &js_WithObjectOps)
#define OBJ_IS_NATIVE(obj) MAP_IS_NATIVE((obj)->map)
extern JS_FRIEND_DATA(JSObjectOps) js_ObjectOps;
extern JS_FRIEND_DATA(JSObjectOps) js_WithObjectOps;
extern JSClass js_ObjectClass;
extern JSClass js_WithClass;
struct JSSharpObjectMap {
jsrefcount depth;
jsatomid sharpgen;
JSHashTable *table;
};
#define SHARP_BIT 1
#define IS_SHARP(he) ((jsatomid)(he)->value & SHARP_BIT)
#define MAKE_SHARP(he) ((he)->value = (void*)((jsatomid)(he)->value|SHARP_BIT))
extern JSHashEntry *
js_EnterSharpObject(JSContext *cx, JSObject *obj, JSIdArray **idap,
jschar **sp);
extern void
js_LeaveSharpObject(JSContext *cx, JSIdArray **idap);
extern JSBool
js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval);
extern JSBool
js_obj_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval);
extern JSObject *
js_InitObjectClass(JSContext *cx, JSObject *obj);
extern void
js_InitObjectMap(JSObjectMap *map, jsrefcount nrefs, JSObjectOps *ops,
JSClass *clasp);
extern JSObjectMap *
js_NewObjectMap(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops,
JSClass *clasp, JSObject *obj);
extern void
js_DestroyObjectMap(JSContext *cx, JSObjectMap *map);
extern JSObjectMap *
js_HoldObjectMap(JSContext *cx, JSObjectMap *map);
extern JSObjectMap *
js_DropObjectMap(JSContext *cx, JSObjectMap *map, JSObject *obj);
extern JSObject *
js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent);
extern JSObject *
js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
JSObject *parent);
extern void
js_FinalizeObject(JSContext *cx, JSObject *obj);
extern JSBool
js_AllocSlot(JSContext *cx, JSObject *obj, uint32 *slotp);
extern void
js_FreeSlot(JSContext *cx, JSObject *obj, uint32 slot);
/*
* On error, return false. On success, if propp is non-null, return true with
* obj locked and with a held property in *propp; if propp is null, return true
* but release obj's lock first. Therefore all callers who pass non-null propp
* result parameters must later call OBJ_DROP_PROPERTY(cx, obj, *propp) both to
* drop the held property, and to release the lock on obj.
*/
extern JSBool
js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
JSProperty **propp);
/*
* Unlike js_DefineProperty, propp must be non-null. On success, and if id was
* found, return true with *objp non-null and locked, and with a held property
* stored in *propp. If successful but id was not found, return true with both
* *objp and *propp null. Therefore all callers who receive a non-null *propp
* must later call OBJ_DROP_PROPERTY(cx, *objp, *propp).
*/
#if defined JS_THREADSAFE && defined DEBUG
extern JS_FRIEND_API(JSBool)
_js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
JSProperty **propp, const char *file, uintN line);
#define js_LookupProperty(cx,obj,id,objp,propp) \
_js_LookupProperty(cx,obj,id,objp,propp,__FILE__,__LINE__)
#else
extern JS_FRIEND_API(JSBool)
js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
JSProperty **propp);
#endif
extern JS_FRIEND_API(JSBool)
js_FindProperty(JSContext *cx, jsid id, JSObject **objp, JSObject **pobjp,
JSProperty **propp);
extern JSBool
js_FindVariable(JSContext *cx, jsid id, JSObject **objp, JSObject **pobjp,
JSProperty **propp);
extern JSObject *
js_FindVariableScope(JSContext *cx, JSFunction **funp);
extern JSBool
js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
extern JSBool
js_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
extern JSBool
js_GetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
uintN *attrsp);
extern JSBool
js_SetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
uintN *attrsp);
extern JSBool
js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval);
extern JSBool
js_DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp);
extern JSBool
js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
jsval *statep, jsid *idp);
extern JSBool
js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
jsval *vp, uintN *attrsp);
extern JSBool
js_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
extern JSBool
js_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval);
extern JSBool
js_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp);
extern JSBool
js_IsDelegate(JSContext *cx, JSObject *obj, jsval v, JSBool *bp);
extern JSBool
js_GetClassPrototype(JSContext *cx, const char *name, JSObject **protop);
extern JSBool
js_SetClassPrototype(JSContext *cx, JSObject *ctor, JSObject *proto,
uintN attrs);
extern JSBool
js_ValueToObject(JSContext *cx, jsval v, JSObject **objp);
extern JSObject *
js_ValueToNonNullObject(JSContext *cx, jsval v);
extern JSBool
js_TryValueOf(JSContext *cx, JSObject *obj, JSType type, jsval *rval);
extern JSBool
js_TryMethod(JSContext *cx, JSObject *obj, JSAtom *atom,
uintN argc, jsval *argv, jsval *rval);
extern JSBool
js_XDRObject(JSXDRState *xdr, JSObject **objp);
extern JSIdArray *
js_NewIdArray(JSContext *cx, jsint length);
JS_END_EXTERN_C
#endif /* jsobj_h___ */

2219
mozilla/js/src/jsopcode.c Normal file

File diff suppressed because it is too large Load Diff

191
mozilla/js/src/jsopcode.h Normal file
View File

@@ -0,0 +1,191 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsopcode_h___
#define jsopcode_h___
/*
* JS bytecode definitions.
*/
#include <stddef.h>
#include "jsprvtd.h"
#include "jspubtd.h"
JS_BEGIN_EXTERN_C
/*
* JS operation bytecodes.
*/
typedef enum JSOp {
#define OPDEF(op,val,name,token,length,nuses,ndefs,prec,format) \
op = val,
#include "jsopcode.tbl"
#undef OPDEF
JSOP_LIMIT
} JSOp;
/*
* JS bytecode formats.
*/
#define JOF_BYTE 0 /* single bytecode, no immediates */
#define JOF_JUMP 1 /* signed 16-bit jump offset immediate */
#define JOF_CONST 2 /* unsigned 16-bit constant pool index */
#define JOF_UINT16 3 /* unsigned 16-bit immediate operand */
#define JOF_TABLESWITCH 4 /* table switch */
#define JOF_LOOKUPSWITCH 5 /* lookup switch */
#define JOF_QARG 6 /* quickened get/set function argument ops */
#define JOF_QVAR 7 /* quickened get/set local variable ops */
#define JOF_TYPEMASK 0x000f /* mask for above immediate types */
#define JOF_NAME 0x0010 /* name operation */
#define JOF_PROP 0x0020 /* obj.prop operation */
#define JOF_ELEM 0x0030 /* obj[index] operation */
#define JOF_MODEMASK 0x0030 /* mask for above addressing modes */
#define JOF_SET 0x0040 /* set (i.e., assignment) operation */
#define JOF_DEL 0x0080 /* delete operation */
#define JOF_DEC 0x0100 /* decrement (--, not ++) opcode */
#define JOF_INC 0x0200 /* increment (++, not --) opcode */
#define JOF_INCDEC 0x0300 /* increment or decrement opcode */
#define JOF_POST 0x0400 /* postorder increment or decrement */
#define JOF_IMPORT 0x0800 /* import property op */
#define JOF_FOR2 0x1000 /* new for/in loop bytecodes */
/*
* Immediate operand getters, setters, and bounds.
*/
#define JUMP_OFFSET_LEN 2
#define JUMP_OFFSET_HI(off) ((jsbytecode)((off) >> 8))
#define JUMP_OFFSET_LO(off) ((jsbytecode)(off))
#define GET_JUMP_OFFSET(pc) ((int16)(((pc)[1] << 8) | (pc)[2]))
#define SET_JUMP_OFFSET(pc,off) ((pc)[1] = JUMP_OFFSET_HI(off), \
(pc)[2] = JUMP_OFFSET_LO(off))
#define JUMP_OFFSET_MIN ((int16)0x8000)
#define JUMP_OFFSET_MAX ((int16)0x7fff)
#define ATOM_INDEX_LEN 2
#define ATOM_INDEX_HI(index) ((jsbytecode)((index) >> 8))
#define ATOM_INDEX_LO(index) ((jsbytecode)(index))
#define GET_ATOM_INDEX(pc) (((pc)[1] << 8) | (pc)[2])
#define SET_ATOM_INDEX(pc,index)((pc)[1] = ATOM_INDEX_HI(index), \
(pc)[2] = ATOM_INDEX_LO(index))
#define GET_ATOM(cx,script,pc) js_GetAtom((cx), &(script)->atomMap, \
GET_ATOM_INDEX(pc))
#define ATOM_INDEX_LIMIT_LOG2 16
#define ATOM_INDEX_LIMIT ((uint32)1 << ATOM_INDEX_LIMIT_LOG2)
#define ARGC_HI(argc) ((jsbytecode)((argc) >> 8))
#define ARGC_LO(argc) ((jsbytecode)(argc))
#define GET_ARGC(pc) (((pc)[1] << 8) | (pc)[2])
#define ARGC_LIMIT ((uint32)1 << 16)
/* Synonyms for quick JOF_QARG and JOF_QVAR bytecodes. */
#define GET_ARGNO(pc) GET_ARGC(pc)
#define SET_ARGNO(pc,argno) SET_JUMP_OFFSET(pc,argno)
#define GET_VARNO(pc) GET_ARGC(pc)
#define SET_VARNO(pc,varno) SET_JUMP_OFFSET(pc,varno)
struct JSCodeSpec {
const char *name; /* JS bytecode name */
const char *token; /* JS source literal or null */
int8 length; /* length including opcode byte */
int8 nuses; /* arity, -1 if variadic */
int8 ndefs; /* number of stack results */
uint8 prec; /* operator precedence */
uint32 format; /* immediate operand format */
};
extern char js_in_str[];
extern char js_instanceof_str[];
extern char js_new_str[];
extern char js_delete_str[];
extern char js_typeof_str[];
extern char js_void_str[];
extern char js_null_str[];
extern char js_this_str[];
extern char js_false_str[];
extern char js_true_str[];
extern JSCodeSpec js_CodeSpec[];
extern uintN js_NumCodeSpecs;
extern jschar js_EscapeMap[];
/*
* Return a GC'ed string containing the chars in str, with any non-printing
* chars or quotes (' or " as specified by the quote argument) escaped, and
* with the quote character at the beginning and end of the result string.
*/
extern JSString *
js_QuoteString(JSContext *cx, JSString *str, jschar quote);
/*
* JSPrinter operations, for printf style message formatting. The return
* value from js_GetPrinterOutput() is the printer's cumulative output, in
* a GC'ed string.
*/
extern JSPrinter *
js_NewPrinter(JSContext *cx, const char *name, uintN indent);
extern void
js_DestroyPrinter(JSPrinter *jp);
extern JSString *
js_GetPrinterOutput(JSPrinter *jp);
extern int
js_printf(JSPrinter *jp, char *format, ...);
extern JSBool
js_puts(JSPrinter *jp, char *s);
#ifdef DEBUG
/*
* Disassemblers, for debugging only.
*/
#include <stdio.h>
extern JS_FRIEND_API(void)
js_Disassemble(JSContext *cx, JSScript *script, JSBool lines, FILE *fp);
extern JS_FRIEND_API(uintN)
js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc,
JSBool lines, FILE *fp);
#endif /* DEBUG */
/*
* Decompilers, for script, function, and expression pretty-printing.
*/
extern JSBool
js_DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, uintN len);
extern JSBool
js_DecompileScript(JSPrinter *jp, JSScript *script);
extern JSBool
js_DecompileFunctionBody(JSPrinter *jp, JSFunction *fun, JSBool newlines);
extern JSBool
js_DecompileFunction(JSPrinter *jp, JSFunction *fun, JSBool newlines);
/*
* Find the source expression that resulted in v, and return a new string
* containing it. Fall back on v's string conversion if we can't find the
* bytecode that generated and pushed v on the operand stack.
*/
extern JSString *
js_DecompileValueGenerator(JSContext *cx, jsval v, JSString *fallback);
JS_END_EXTERN_C
#endif /* jsopcode_h___ */

217
mozilla/js/src/jsopcode.tbl Normal file
View File

@@ -0,0 +1,217 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* JavaScript operation bytecodes.
*
* Includers must define an OPDEF macro of the following form:
*
* #define OPDEF(op,val,name,image,length,nuses,ndefs,prec,format) ...
*
* Selected arguments can be expanded in initializers. The op argument is
* expanded followed by comma in the JSOp enum (jsopcode.h), e.g. The value
* field must be dense for now, because jsopcode.c uses an OPDEF() expansion
* inside the js_CodeSpec[] initializer.
*
* Field Description
* op Bytecode name, which is the JSOp enumerator name
* value Bytecode value, which is the JSOp enumerator value
* name C string containing name for disassembler
* image C string containing "image" for pretty-printer, null if ugly
* length Number of bytes including any immediate operands
* nuses Number of stack slots consumed by bytecode, -1 if variadic
* ndefs Number of stack slots produced by bytecode
* prec Operator precedence, zero if not an operator
* format Bytecode plus immediate operand encoding format
*
* This file is best viewed with 116 columns:
01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345
*/
/* legend: op val name image len use def prec format */
/* Permanently-assigned bytecodes. */
OPDEF(JSOP_NOP, 0, "nop", NULL, 1, 0, 0, 0, JOF_BYTE)
OPDEF(JSOP_PUSH, 1, "push", NULL, 1, 0, 1, 0, JOF_BYTE)
OPDEF(JSOP_POPV, 2, "popv", NULL, 1, 1, 0, 0, JOF_BYTE)
OPDEF(JSOP_ENTERWITH, 3, "enterwith", NULL, 1, 1, 1, 0, JOF_BYTE)
OPDEF(JSOP_LEAVEWITH, 4, "leavewith", NULL, 1, 1, 0, 0, JOF_BYTE)
OPDEF(JSOP_RETURN, 5, "return", NULL, 1, 1, 0, 0, JOF_BYTE)
OPDEF(JSOP_GOTO, 6, "goto", NULL, 3, 0, 0, 0, JOF_JUMP)
OPDEF(JSOP_IFEQ, 7, "ifeq", NULL, 3, 1, 0, 0, JOF_JUMP)
OPDEF(JSOP_IFNE, 8, "ifne", NULL, 3, 1, 0, 0, JOF_JUMP)
OPDEF(JSOP_FORNAME, 9, "forname", NULL, 3, 1, 1, 0, JOF_CONST|JOF_NAME|JOF_SET)
OPDEF(JSOP_FORPROP, 10, "forprop", NULL, 3, 2, 1, 0, JOF_CONST|JOF_PROP|JOF_SET)
OPDEF(JSOP_FORELEM, 11, "forelem", NULL, 1, 3, 1, 0, JOF_BYTE |JOF_ELEM|JOF_SET)
OPDEF(JSOP_DUP, 12, "dup", NULL, 1, 1, 2, 0, JOF_BYTE)
OPDEF(JSOP_DUP2, 13, "dup2", NULL, 1, 2, 4, 0, JOF_BYTE)
OPDEF(JSOP_SETNAME, 14, "setname", NULL, 3, 1, 1, 1, JOF_CONST|JOF_NAME|JOF_SET)
OPDEF(JSOP_BITOR, 15, "bitor", "|", 1, 2, 1, 2, JOF_BYTE)
OPDEF(JSOP_BITXOR, 16, "bitxor", "^", 1, 2, 1, 3, JOF_BYTE)
OPDEF(JSOP_BITAND, 17, "bitand", "&", 1, 2, 1, 4, JOF_BYTE)
OPDEF(JSOP_EQ, 18, "eq", "==", 1, 2, 1, 5, JOF_BYTE)
OPDEF(JSOP_NE, 19, "ne", "!=", 1, 2, 1, 5, JOF_BYTE)
OPDEF(JSOP_LT, 20, "lt", "<", 1, 2, 1, 6, JOF_BYTE)
OPDEF(JSOP_LE, 21, "le", "<=", 1, 2, 1, 6, JOF_BYTE)
OPDEF(JSOP_GT, 22, "gt", ">", 1, 2, 1, 6, JOF_BYTE)
OPDEF(JSOP_GE, 23, "ge", ">=", 1, 2, 1, 6, JOF_BYTE)
OPDEF(JSOP_LSH, 24, "lsh", "<<", 1, 2, 1, 7, JOF_BYTE)
OPDEF(JSOP_RSH, 25, "rsh", ">>", 1, 2, 1, 7, JOF_BYTE)
OPDEF(JSOP_URSH, 26, "ursh", ">>>", 1, 2, 1, 7, JOF_BYTE)
OPDEF(JSOP_ADD, 27, "add", "+", 1, 2, 1, 8, JOF_BYTE)
OPDEF(JSOP_SUB, 28, "sub", "-", 1, 2, 1, 8, JOF_BYTE)
OPDEF(JSOP_MUL, 29, "mul", "*", 1, 2, 1, 9, JOF_BYTE)
OPDEF(JSOP_DIV, 30, "div", "/", 1, 2, 1, 9, JOF_BYTE)
OPDEF(JSOP_MOD, 31, "mod", "%", 1, 2, 1, 9, JOF_BYTE)
OPDEF(JSOP_NOT, 32, "not", "!", 1, 1, 1, 10, JOF_BYTE)
OPDEF(JSOP_BITNOT, 33, "bitnot", "~", 1, 1, 1, 10, JOF_BYTE)
OPDEF(JSOP_NEG, 34, "neg", "-", 1, 1, 1, 10, JOF_BYTE)
OPDEF(JSOP_NEW, 35, js_new_str, NULL, 3, -1, 1, 10, JOF_UINT16)
OPDEF(JSOP_DELNAME, 36, "delname", NULL, 3, 0, 1, 10, JOF_CONST|JOF_NAME|JOF_DEL)
OPDEF(JSOP_DELPROP, 37, "delprop", NULL, 3, 1, 1, 10, JOF_CONST|JOF_PROP|JOF_DEL)
OPDEF(JSOP_DELELEM, 38, "delelem", NULL, 1, 2, 1, 10, JOF_BYTE |JOF_ELEM|JOF_DEL)
OPDEF(JSOP_TYPEOF, 39, js_typeof_str,NULL, 1, 1, 1, 10, JOF_BYTE)
OPDEF(JSOP_VOID, 40, js_void_str, NULL, 1, 1, 1, 10, JOF_BYTE)
OPDEF(JSOP_INCNAME, 41, "incname", NULL, 3, 0, 1, 10, JOF_CONST|JOF_NAME|JOF_INC)
OPDEF(JSOP_INCPROP, 42, "incprop", NULL, 3, 1, 1, 10, JOF_CONST|JOF_PROP|JOF_INC)
OPDEF(JSOP_INCELEM, 43, "incelem", NULL, 1, 2, 1, 10, JOF_BYTE |JOF_ELEM|JOF_INC)
OPDEF(JSOP_DECNAME, 44, "decname", NULL, 3, 0, 1, 10, JOF_CONST|JOF_NAME|JOF_DEC)
OPDEF(JSOP_DECPROP, 45, "decprop", NULL, 3, 1, 1, 10, JOF_CONST|JOF_PROP|JOF_DEC)
OPDEF(JSOP_DECELEM, 46, "decelem", NULL, 1, 2, 1, 10, JOF_BYTE |JOF_ELEM|JOF_DEC)
OPDEF(JSOP_NAMEINC, 47, "nameinc", NULL, 3, 0, 1, 10, JOF_CONST|JOF_NAME|JOF_INC|JOF_POST)
OPDEF(JSOP_PROPINC, 48, "propinc", NULL, 3, 1, 1, 10, JOF_CONST|JOF_PROP|JOF_INC|JOF_POST)
OPDEF(JSOP_ELEMINC, 49, "eleminc", NULL, 1, 2, 1, 10, JOF_BYTE |JOF_ELEM|JOF_INC|JOF_POST)
OPDEF(JSOP_NAMEDEC, 50, "namedec", NULL, 3, 0, 1, 10, JOF_CONST|JOF_NAME|JOF_DEC|JOF_POST)
OPDEF(JSOP_PROPDEC, 51, "propdec", NULL, 3, 1, 1, 10, JOF_CONST|JOF_PROP|JOF_DEC|JOF_POST)
OPDEF(JSOP_ELEMDEC, 52, "elemdec", NULL, 1, 2, 1, 10, JOF_BYTE |JOF_ELEM|JOF_DEC|JOF_POST)
OPDEF(JSOP_GETPROP, 53, "getprop", NULL, 3, 1, 1, 11, JOF_CONST|JOF_PROP)
OPDEF(JSOP_SETPROP, 54, "setprop", NULL, 3, 2, 1, 1, JOF_CONST|JOF_PROP|JOF_SET)
OPDEF(JSOP_GETELEM, 55, "getelem", NULL, 1, 2, 1, 11, JOF_BYTE |JOF_ELEM)
OPDEF(JSOP_SETELEM, 56, "setelem", NULL, 1, 3, 1, 1, JOF_BYTE |JOF_ELEM|JOF_SET)
OPDEF(JSOP_PUSHOBJ, 57, "pushobj", NULL, 1, 0, 1, 0, JOF_BYTE)
OPDEF(JSOP_CALL, 58, "call", NULL, 3, -1, 1, 11, JOF_UINT16)
OPDEF(JSOP_NAME, 59, "name", NULL, 3, 0, 1, 12, JOF_CONST|JOF_NAME)
OPDEF(JSOP_NUMBER, 60, "number", NULL, 3, 0, 1, 12, JOF_CONST)
OPDEF(JSOP_STRING, 61, "string", NULL, 3, 0, 1, 12, JOF_CONST)
OPDEF(JSOP_ZERO, 62, "zero", "0", 1, 0, 1, 12, JOF_BYTE)
OPDEF(JSOP_ONE, 63, "one", "1", 1, 0, 1, 12, JOF_BYTE)
OPDEF(JSOP_NULL, 64, js_null_str, js_null_str, 1, 0, 1, 12, JOF_BYTE)
OPDEF(JSOP_THIS, 65, js_this_str, js_this_str, 1, 0, 1, 12, JOF_BYTE)
OPDEF(JSOP_FALSE, 66, js_false_str, js_false_str, 1, 0, 1, 12, JOF_BYTE)
OPDEF(JSOP_TRUE, 67, js_true_str, js_true_str, 1, 0, 1, 12, JOF_BYTE)
OPDEF(JSOP_OR, 68, "or", NULL, 3, 1, 0, 0, JOF_JUMP)
OPDEF(JSOP_AND, 69, "and", NULL, 3, 1, 0, 0, JOF_JUMP)
/* The switch bytecodes have variable length. */
OPDEF(JSOP_TABLESWITCH, 70, "tableswitch", NULL, -1, 1, 0, 0, JOF_TABLESWITCH)
OPDEF(JSOP_LOOKUPSWITCH, 71, "lookupswitch", NULL, -1, 1, 0, 0, JOF_LOOKUPSWITCH)
/* New, infallible/transitive identity ops. */
OPDEF(JSOP_NEW_EQ, 72, "eq", NULL, 1, 2, 1, 5, JOF_BYTE)
OPDEF(JSOP_NEW_NE, 73, "ne", NULL, 1, 2, 1, 5, JOF_BYTE)
/* Lexical closure constructor. */
OPDEF(JSOP_CLOSURE, 74, "closure", NULL, 3, 0, 1, 0, JOF_CONST)
/* Export and import ops. */
OPDEF(JSOP_EXPORTALL, 75, "exportall", NULL, 1, 0, 0, 0, JOF_BYTE)
OPDEF(JSOP_EXPORTNAME,76, "exportname", NULL, 3, 0, 0, 0, JOF_CONST|JOF_NAME)
OPDEF(JSOP_IMPORTALL, 77, "importall", NULL, 1, 1, 0, 0, JOF_BYTE)
OPDEF(JSOP_IMPORTPROP,78, "importprop", NULL, 3, 1, 0, 0, JOF_CONST|JOF_PROP|JOF_IMPORT)
OPDEF(JSOP_IMPORTELEM,79, "importelem", NULL, 1, 2, 0, 0, JOF_BYTE |JOF_ELEM|JOF_IMPORT)
/* Push object literal. */
OPDEF(JSOP_OBJECT, 80, "object", NULL, 3, 0, 1, 12, JOF_CONST)
/* Pop value and discard it. */
OPDEF(JSOP_POP, 81, "pop", NULL, 1, 1, 0, 0, JOF_BYTE)
/* Convert value to number, for unary +. */
OPDEF(JSOP_POS, 82, "pos", "+", 1, 1, 1, 10, JOF_BYTE)
/* Trap into debugger for breakpoint, etc. */
OPDEF(JSOP_TRAP, 83, "trap", NULL, 1, 0, 0, 0, JOF_BYTE)
/* Fast get/set ops for function arguments and local variables. */
OPDEF(JSOP_GETARG, 84, "getarg", NULL, 3, 0, 1, 12, JOF_QARG |JOF_NAME)
OPDEF(JSOP_SETARG, 85, "setarg", NULL, 3, 1, 1, 1, JOF_QARG |JOF_NAME|JOF_SET)
OPDEF(JSOP_GETVAR, 86, "getvar", NULL, 3, 0, 1, 12, JOF_QVAR |JOF_NAME)
OPDEF(JSOP_SETVAR, 87, "setvar", NULL, 3, 1, 1, 1, JOF_QVAR |JOF_NAME|JOF_SET)
/* Push unsigned 16-bit int constant. */
OPDEF(JSOP_UINT16, 88, "uint16", NULL, 3, 0, 1, 12, JOF_UINT16)
/* Object and array literal support. */
OPDEF(JSOP_NEWINIT, 89, "newinit", NULL, 1, 2, 1, 10, JOF_BYTE)
OPDEF(JSOP_ENDINIT, 90, "endinit", NULL, 1, 0, 0, 0, JOF_BYTE)
OPDEF(JSOP_INITPROP, 91, "initprop", NULL, 3, 1, 0, 0, JOF_CONST|JOF_PROP)
OPDEF(JSOP_INITELEM, 92, "initelem", NULL, 1, 2, 0, 0, JOF_BYTE |JOF_ELEM)
OPDEF(JSOP_DEFSHARP, 93, "defsharp", NULL, 3, 0, 0, 0, JOF_UINT16)
OPDEF(JSOP_USESHARP, 94, "usesharp", NULL, 3, 0, 1, 0, JOF_UINT16)
/* Fast inc/dec ops for args and local vars. */
OPDEF(JSOP_INCARG, 95, "incarg", NULL, 3, 0, 1, 10, JOF_QARG |JOF_NAME|JOF_INC)
OPDEF(JSOP_INCVAR, 96, "incvar", NULL, 3, 0, 1, 10, JOF_QVAR |JOF_NAME|JOF_INC)
OPDEF(JSOP_DECARG, 97, "decarg", NULL, 3, 0, 1, 10, JOF_QARG |JOF_NAME|JOF_DEC)
OPDEF(JSOP_DECVAR, 98, "decvar", NULL, 3, 0, 1, 10, JOF_QVAR |JOF_NAME|JOF_DEC)
OPDEF(JSOP_ARGINC, 99, "arginc", NULL, 3, 0, 1, 10, JOF_QARG |JOF_NAME|JOF_INC|JOF_POST)
OPDEF(JSOP_VARINC, 100,"varinc", NULL, 3, 0, 1, 10, JOF_QVAR |JOF_NAME|JOF_INC|JOF_POST)
OPDEF(JSOP_ARGDEC, 101,"argdec", NULL, 3, 0, 1, 10, JOF_QARG |JOF_NAME|JOF_DEC|JOF_POST)
OPDEF(JSOP_VARDEC, 102,"vardec", NULL, 3, 0, 1, 10, JOF_QVAR |JOF_NAME|JOF_DEC|JOF_POST)
/* ECMA-compliant for/in ops. */
OPDEF(JSOP_TOOBJECT, 103,"toobject", NULL, 1, 1, 1, 0, JOF_BYTE)
OPDEF(JSOP_FORNAME2, 104,"forname2", NULL, 3, 0, 1, 0, JOF_CONST|JOF_NAME|JOF_SET|JOF_FOR2)
OPDEF(JSOP_FORPROP2, 105,"forprop2", NULL, 3, 1, 1, 0, JOF_CONST|JOF_PROP|JOF_SET|JOF_FOR2)
OPDEF(JSOP_FORELEM2, 106,"forelem2", NULL, 1, 2, 1, 0, JOF_BYTE |JOF_ELEM|JOF_SET|JOF_FOR2)
OPDEF(JSOP_POP2, 107,"pop2", NULL, 1, 2, 0, 0, JOF_BYTE)
/* ECMA-complaint assignment ops. */
OPDEF(JSOP_BINDNAME, 108,"bindname", NULL, 3, 0, 1, 0, JOF_CONST|JOF_NAME)
OPDEF(JSOP_SETNAME2, 109,"setname2", NULL, 3, 2, 1, 1, JOF_CONST|JOF_NAME|JOF_SET)
/* Exception handling ops. */
OPDEF(JSOP_THROW, 110,"throw", NULL, 1, 1, 0, 0, JOF_BYTE)
/* 'in' and 'instanceof' ops. */
OPDEF(JSOP_IN, 111,js_in_str, js_in_str, 1, 2, 1, 6, JOF_BYTE)
OPDEF(JSOP_INSTANCEOF,112,js_instanceof_str,js_instanceof_str,1,2,1,6,JOF_BYTE)
/* debugger op */
OPDEF(JSOP_DEBUGGER, 113,"debugger", NULL, 1, 0, 0, 0, JOF_BYTE)
/* gosub/retsub for finally handling */
OPDEF(JSOP_GOSUB, 114,"gosub", NULL, 3, 0, 1, 0, JOF_JUMP)
OPDEF(JSOP_RETSUB, 115,"retsub", NULL, 1, 1, 0, 0, JOF_BYTE)
/* more exception handling ops */
OPDEF(JSOP_EXCEPTION, 116,"exception", NULL, 1, 0, 1, 0, JOF_BYTE)
OPDEF(JSOP_SETSP, 117,"setsp", NULL, 3, 0, 0, 0, JOF_UINT16)
/*
* ECMA-compliant switch statement ops.
* CONDSWITCH is a decompilable NOP; CASE is ===, POP, jump if true, re-push
* lval if false; and DEFAULT is POP lval and GOTO.
*/
OPDEF(JSOP_CONDSWITCH,118,"condswitch", NULL, 1, 0, 0, 0, JOF_BYTE)
OPDEF(JSOP_CASE, 119,"case", NULL, 3, 1, 0, 0, JOF_JUMP)
OPDEF(JSOP_DEFAULT, 120,"default", NULL, 3, 1, 0, 0, JOF_JUMP)
/*
* ECMA-compliant call to eval op
*/
OPDEF(JSOP_CALLSPECIAL,121,"callspecial",NULL, 3, -1, 1, 11, JOF_UINT16)

92
mozilla/js/src/jsosdep.h Normal file
View File

@@ -0,0 +1,92 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsosdep_h___
#define jsosdep_h___
/*
* OS (and machine, and compiler XXX) dependent information.
*/
#ifdef XP_PC
#ifdef _WIN32
#define JS_HAVE_LONG_LONG
#else
#undef JS_HAVE_LONG_LONG
#endif
#endif /* XP_PC */
#ifdef XP_MAC
JS_BEGIN_EXTERN_C
#include <stddef.h>
extern void* reallocSmaller(void* block, size_t newSize);
extern char* strdup(const char* str);
JS_END_EXTERN_C
#endif /* XP_MAC */
#ifdef XP_UNIX
/*
* Get OS specific header information.
*/
#if defined(AIXV3)
#define JS_HAVE_LONG_LONG
#elif defined(BSDI)
#define JS_HAVE_LONG_LONG
#elif defined(HPUX)
#undef JS_HAVE_LONG_LONG
#elif defined(IRIX)
#define JS_HAVE_LONG_LONG
#elif defined(linux)
#define JS_HAVE_LONG_LONG
#elif defined(OSF1)
#define JS_HAVE_LONG_LONG
#elif defined(SCO)
#undef JS_HAVE_LONG_LONG
#elif defined(SOLARIS)
#define JS_HAVE_LONG_LONG
#elif defined(SUNOS4)
#undef JS_HAVE_LONG_LONG
/*
** Missing function prototypes
*/
extern void *sbrk(int);
#elif defined(UNIXWARE)
#undef JS_HAVE_LONG_LONG
#endif
#endif /* XP_UNIX */
#endif /* jsosdep_h___ */

176
mozilla/js/src/jsotypes.h Normal file
View File

@@ -0,0 +1,176 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* This section typedefs the old 'native' types to the new PR<type>s.
* These definitions are scheduled to be eliminated at the earliest
* possible time. The NSPR API is implemented and documented using
* the new definitions.
*/
/*
* Note that we test for PROTYPES_H, not JSOTYPES_H. This is to avoid
* double-definitions of scalar types such as uint32, if NSPR's
* protypes.h is also included.
*/
#ifndef PROTYPES_H
#define PROTYPES_H
/* SVR4 typedef of uint is commonly found on UNIX machines. */
#ifdef XP_UNIX
#include <sys/types.h>
#else
typedef JSUintn uint;
#endif
typedef JSUintn uintn;
typedef JSUint64 uint64;
#if !defined(XP_MAC) && !defined(_WIN32) && !defined(XP_OS2)
typedef JSUint32 uint32;
#else
typedef unsigned long uint32;
#endif
typedef JSUint16 uint16;
typedef JSUint8 uint8;
#ifndef _XP_Core_
typedef JSIntn intn;
#endif
/*
* On AIX 4.3, sys/inttypes.h (which is included by sys/types.h, a very
* common header file) defines the types int8, int16, int32, and int64.
* So we don't define these four types here to avoid conflicts in case
* the code also includes sys/types.h.
*/
#ifdef AIX4_3
#include <sys/inttypes.h>
#else
typedef JSInt64 int64;
/* /usr/include/model.h on HP-UX defines int8, int16, and int32 */
#ifdef HPUX
#include <model.h>
#else
#if !defined(WIN32) || !defined(_WINSOCK2API_) /* defines its own "int32" */
#if !defined(XP_MAC) && !defined(_WIN32) && !defined(XP_OS2)
typedef JSInt32 int32;
#else
typedef long int32;
#endif
#endif
typedef JSInt16 int16;
typedef JSInt8 int8;
#endif /* HPUX */
#endif /* AIX4_3 */
typedef JSFloat64 float64;
/* Re: jsbit.h */
#define TEST_BIT JS_TEST_BIT
#define SET_BIT JS_SET_BIT
#define CLEAR_BIT JS_CLEAR_BIT
/* Re: prarena.h->plarena.h */
#define PRArena PLArena
#define PRArenaPool PLArenaPool
#define PRArenaStats PLArenaStats
#define PR_ARENA_ALIGN PL_ARENA_ALIGN
#define PR_INIT_ARENA_POOL PL_INIT_ARENA_POOL
#define PR_ARENA_ALLOCATE PL_ARENA_ALLOCATE
#define PR_ARENA_GROW PL_ARENA_GROW
#define PR_ARENA_MARK PL_ARENA_MARK
#define PR_CLEAR_UNUSED PL_CLEAR_UNUSED
#define PR_CLEAR_ARENA PL_CLEAR_ARENA
#define PR_ARENA_RELEASE PL_ARENA_RELEASE
#define PR_COUNT_ARENA PL_COUNT_ARENA
#define PR_ARENA_DESTROY PL_ARENA_DESTROY
#define PR_InitArenaPool PL_InitArenaPool
#define PR_FreeArenaPool PL_FreeArenaPool
#define PR_FinishArenaPool PL_FinishArenaPool
#define PR_CompactArenaPool PL_CompactArenaPool
#define PR_ArenaFinish PL_ArenaFinish
#define PR_ArenaAllocate PL_ArenaAllocate
#define PR_ArenaGrow PL_ArenaGrow
#define PR_ArenaRelease PL_ArenaRelease
#define PR_ArenaCountAllocation PL_ArenaCountAllocation
#define PR_ArenaCountInplaceGrowth PL_ArenaCountInplaceGrowth
#define PR_ArenaCountGrowth PL_ArenaCountGrowth
#define PR_ArenaCountRelease PL_ArenaCountRelease
#define PR_ArenaCountRetract PL_ArenaCountRetract
/* Re: prevent.h->plevent.h */
#define PREvent PLEvent
#define PREventQueue PLEventQueue
#define PR_CreateEventQueue PL_CreateEventQueue
#define PR_DestroyEventQueue PL_DestroyEventQueue
#define PR_GetEventQueueMonitor PL_GetEventQueueMonitor
#define PR_ENTER_EVENT_QUEUE_MONITOR PL_ENTER_EVENT_QUEUE_MONITOR
#define PR_EXIT_EVENT_QUEUE_MONITOR PL_EXIT_EVENT_QUEUE_MONITOR
#define PR_PostEvent PL_PostEvent
#define PR_PostSynchronousEvent PL_PostSynchronousEvent
#define PR_GetEvent PL_GetEvent
#define PR_EventAvailable PL_EventAvailable
#define PREventFunProc PLEventFunProc
#define PR_MapEvents PL_MapEvents
#define PR_RevokeEvents PL_RevokeEvents
#define PR_ProcessPendingEvents PL_ProcessPendingEvents
#define PR_WaitForEvent PL_WaitForEvent
#define PR_EventLoop PL_EventLoop
#define PR_GetEventQueueSelectFD PL_GetEventQueueSelectFD
#define PRHandleEventProc PLHandleEventProc
#define PRDestroyEventProc PLDestroyEventProc
#define PR_InitEvent PL_InitEvent
#define PR_GetEventOwner PL_GetEventOwner
#define PR_HandleEvent PL_HandleEvent
#define PR_DestroyEvent PL_DestroyEvent
#define PR_DequeueEvent PL_DequeueEvent
#define PR_GetMainEventQueue PL_GetMainEventQueue
/* Re: prhash.h->plhash.h */
#define PRHashEntry PLHashEntry
#define PRHashTable PLHashTable
#define PRHashNumber PLHashNumber
#define PRHashFunction PLHashFunction
#define PRHashComparator PLHashComparator
#define PRHashEnumerator PLHashEnumerator
#define PRHashAllocOps PLHashAllocOps
#define PR_NewHashTable PL_NewHashTable
#define PR_HashTableDestroy PL_HashTableDestroy
#define PR_HashTableRawLookup PL_HashTableRawLookup
#define PR_HashTableRawAdd PL_HashTableRawAdd
#define PR_HashTableRawRemove PL_HashTableRawRemove
#define PR_HashTableAdd PL_HashTableAdd
#define PR_HashTableRemove PL_HashTableRemove
#define PR_HashTableEnumerateEntries PL_HashTableEnumerateEntries
#define PR_HashTableLookup PL_HashTableLookup
#define PR_HashTableDump PL_HashTableDump
#define PR_HashString PL_HashString
#define PR_CompareStrings PL_CompareStrings
#define PR_CompareValues PL_CompareValues
#ifdef XP_MAC
#ifndef TRUE /* Mac standard is lower case true */
#define TRUE 1
#endif
#ifndef FALSE /* Mac standard is lower case false */
#define FALSE 0
#endif
#endif
#endif /* !defined(PROTYPES_H) */

2727
mozilla/js/src/jsparse.c Normal file

File diff suppressed because it is too large Load Diff

256
mozilla/js/src/jsparse.h Normal file
View File

@@ -0,0 +1,256 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsparse_h___
#define jsparse_h___
/*
* JS parser definitions.
*/
#include "jsprvtd.h"
#include "jspubtd.h"
#include "jsscan.h"
JS_BEGIN_EXTERN_C
/*
* Parsing builds a tree of nodes that directs code generation. This tree is
* not a concrete syntax tree in all respects (for example, || and && are left
* associative, but (A && B && C) translates into the right-associated tree
* <A && <B && C>> so that code generation can emit a left-associative branch
* around <B && C> when A is false). Nodes are labeled by token type, with a
* JSOp secondary label when needed:
*
* Label Variant Members
* ----- ------- -------
* <Definitions>
* TOK_FUNCTION func pn_fun: function, contains arg and var properties
* pn_body: TOK_LC node for function body
* NB: We define or create the function object at
* parse (not emit) time, in order to specialize arg
* and var bytecodes early.
* pn_tryCount: of try statements in function
*
* <Statements>
* TOK_LC list pn_head: list of pn_count statements
* TOK_EXPORT list pn_head: list of pn_count TOK_NAMEs or one TOK_STAR
* (which is not a multiply node)
* TOK_IMPORT list pn_head: list of pn_count sub-trees of the form
* a.b.*, a[b].*, a.*, a.b, or a[b] -- but never a.
* Each member is expressed with TOK_DOT or TOK_LB.
* Each sub-tree's root node has a pn_op in the set
* JSOP_IMPORT{ALL,PROP,ELEM}
* TOK_IF ternary pn_kid1: cond, pn_kid2: then, pn_kid3: else or null
* TOK_SWITCH binary pn_left: discriminant
* pn_right: list of TOK_CASE nodes, with at most one
* TOK_DEFAULT node
* TOK_CASE, binary pn_left: case expr or null if TOK_DEFAULT
* TOK_DEFAULT pn_right: TOK_LC node for this case's statements
* TOK_WHILE binary pn_left: cond, pn_right: body
* TOK_DO binary pn_left: body, pn_right: cond
* TOK_FOR binary pn_left: either
* for/in loop: a binary TOK_IN node with
* pn_left: TOK_VAR or TOK_NAME to left of 'in'
* pn_right: object expr to right of 'in'
* for(;;) loop: a ternary TOK_RESERVED node with
* pn_kid1: init expr before first ';'
* pn_kid2: cond expr before second ';'
* pn_kid3: update expr after second ';'
* any kid may be null
* pn_right: body
* TOK_THROW unary pn_op: JSOP_THROW, pn_kid: exception
* TOK_BREAK name pn_atom: label or null
* TOK_CONTINUE name pn_atom: label or null
* TOK_WITH binary pn_left: head expr, pn_right: body
* TOK_VAR list pn_head: list of pn_count TOK_NAME nodes
* each name node has pn_atom: variable name and
* pn_expr: initializer or null
* TOK_RETURN unary pn_kid: return expr or null
* TOK_SEMI unary pn_kid: expr or null statement
* TOK_COLON name pn_atom: label, pn_expr: labeled statement
*
* <Expressions>
* TOK_COMMA list pn_head: list of pn_count comma-separated exprs
* TOK_ASSIGN binary pn_left: lvalue, pn_right: rvalue
* TOK_HOOK ternary pn_kid1: cond, pn_kid2: then, pn_kid3: else
* TOK_OR binary pn_left: first in || chain, pn_right: rest of chain
* TOK_AND binary pn_left: first in && chain, pn_right: rest of chain
* TOK_BITOR binary pn_left: left-assoc | expr, pn_right: ^ expr
* TOK_BITXOR binary pn_left: left-assoc ^ expr, pn_right: & expr
* TOK_BITAND binary pn_left: left-assoc & expr, pn_right: EQ expr
* TOK_EQOP binary pn_left: left-assoc EQ expr, pn_right: REL expr
* pn_op: JSOP_EQ, JSOP_NE, JSOP_NEW_EQ, JSOP_NEW_NE
* TOK_RELOP binary pn_left: left-assoc REL expr, pn_right: SH expr
* pn_op: JSOP_LT, JSOP_LE, JSOP_GT, JSOP_GE
* TOK_SHOP binary pn_left: left-assoc SH expr, pn_right: ADD expr
* pn_op: JSOP_LSH, JSOP_RSH, JSOP_URSH
* TOK_PLUS, binary pn_left: left-assoc ADD expr, pn_right: MUL expr
* TOK_MINUS pn_op: JSOP_ADD, JSOP_SUB
* TOK_STAR, binary pn_left: left-assoc MUL expr, pn_right: UNARY expr
* TOK_DIVOP pn_op: JSOP_MUL, JSOP_DIV, JSOP_MOD
* TOK_UNARYOP unary pn_kid: UNARY expr, pn_op: JSOP_NEG, JSOP_POS,
* JSOP_NOT, JSOP_BITNOT, JSOP_TYPEOF, JSOP_VOID
* TOK_INC, unary pn_kid: MEMBER expr
* TOK_DEC pn_num: arg or local var slot if non-negative
* TOK_NEW list pn_head: list of ctor, arg1, arg2, ... argN
* pn_count: 1 + N (where N is number of args)
* ctor is a MEMBER expr
* TOK_DELETE unary pn_kid: MEMBER expr
* TOK_DOT name pn_expr: MEMBER expr to left of .
* pn_atom: name to right of .
* TOK_LB binary pn_left: MEMBER expr to left of [
* pn_right: expr between [ and ]
* TOK_LP list pn_head: list of call, arg1, arg2, ... argN
* pn_count: 1 + N (where N is number of args)
* call is a MEMBER expr naming a callable object
* TOK_RB list pn_head: list of pn_count array element exprs
* [,,] holes are represented by TOK_COMMA nodes
* #n=[...] produces TOK_DEFSHARP at head of list
* pn_extra: true if extra comma at end
* TOK_RC list pn_head: list of pn_count TOK_COLON nodes where
* each has pn_left: property id, pn_right: value
* #n={...} produces TOK_DEFSHARP at head of list
* TOK_DEFSHARP unary pn_num: jsint value of n in #n=
* pn_kid: null for #n=[...] and #n={...}, primary
* if #n=primary for function, paren, name, object
* literal expressions
* TOK_USESHARP nullary pn_num: jsint value of n in #n#
* TOK_RP unary pn_kid: parenthesized expression
* TOK_NAME, name pn_atom: name, string, or object atom
* TOK_STRING, pn_op: JSOP_NAME, JSOP_STRING, or JSOP_OBJECT
* TOK_OBJECT pn_op may be *ARG or *VAR with pn_slot >= 0
* TOK_NUMBER dval pn_dval: double value of numeric literal
* TOK_PRIMARY nullary pn_op: JSOp bytecode
*/
typedef enum JSParseNodeArity {
PN_FUNC = -3,
PN_LIST = -2,
PN_TERNARY = 3,
PN_BINARY = 2,
PN_UNARY = 1,
PN_NAME = -1,
PN_NULLARY = 0
} JSParseNodeArity;
struct JSParseNode {
JSTokenType pn_type;
JSTokenPos pn_pos;
JSOp pn_op;
ptrdiff_t pn_offset; /* first generated bytecode offset */
JSParseNodeArity pn_arity;
union {
struct { /* TOK_FUNCTION node */
JSFunction *fun; /* function object private data */
JSParseNode *body; /* TOK_LC list of statements */
uint32 tryCount; /* try statement count */
} func;
struct { /* list of next-linked nodes */
JSParseNode *head; /* first node in list */
JSParseNode **tail; /* ptr to ptr to last node in list */
uint32 count; /* number of nodes in list */
JSBool extra; /* extra comma flag for [1,2,,] */
} list;
struct { /* ternary: if, for(;;), ?: */
JSParseNode *kid1; /* condition, discriminant, etc. */
JSParseNode *kid2; /* then-part, case list, etc. */
JSParseNode *kid3; /* else-part, default case, etc. */
} ternary;
struct { /* two kids if binary */
JSParseNode *left;
JSParseNode *right;
jsval val; /* switch case value */
} binary;
struct { /* one kid if unary */
JSParseNode *kid;
jsint num; /* -1 or arg or local/sharp var num */
} unary;
struct { /* name, labeled statement, etc. */
JSAtom *atom; /* name or label atom, null if slot */
JSParseNode *expr; /* object or initializer */
jsint slot; /* -1 or arg or local var slot */
} name;
jsdouble dval; /* aligned numeric literal value */
} pn_u;
JSParseNode *pn_next; /* here to align dval and pn_u on RISCs */
};
#define pn_fun pn_u.func.fun
#define pn_body pn_u.func.body
#define pn_tryCount pn_u.func.tryCount
#define pn_head pn_u.list.head
#define pn_tail pn_u.list.tail
#define pn_count pn_u.list.count
#define pn_extra pn_u.list.extra
#define pn_kid1 pn_u.ternary.kid1
#define pn_kid2 pn_u.ternary.kid2
#define pn_kid3 pn_u.ternary.kid3
#define pn_left pn_u.binary.left
#define pn_right pn_u.binary.right
#define pn_val pn_u.binary.val
#define pn_kid pn_u.unary.kid
#define pn_num pn_u.unary.num
#define pn_atom pn_u.name.atom
#define pn_expr pn_u.name.expr
#define pn_slot pn_u.name.slot
#define pn_dval pn_u.dval
/*
* Compute a pointer to the last JSParseNode element in a singly-linked list.
* NB: list must be non-empty for correct PN_LAST usage!
*/
#define PN_LAST(list) \
((JSParseNode *)((char *)(list)->pn_tail - offsetof(JSParseNode, pn_next)))
#define PN_INIT_LIST(list) \
JS_BEGIN_MACRO \
(list)->pn_head = NULL; \
(list)->pn_tail = &(list)->pn_head; \
(list)->pn_count = 0; \
JS_END_MACRO
#define PN_INIT_LIST_1(list, pn) \
JS_BEGIN_MACRO \
(list)->pn_head = (pn); \
(list)->pn_tail = &(pn)->pn_next; \
(list)->pn_count = 1; \
JS_END_MACRO
#define PN_APPEND(list, pn) \
JS_BEGIN_MACRO \
*(list)->pn_tail = (pn); \
(list)->pn_tail = &(pn)->pn_next; \
(list)->pn_count++; \
JS_END_MACRO
/* New names to connote code generation in addition to parse tree gen. */
#define js_CompileTokenStream js_Parse
#define js_CompileFunctionBody js_ParseFunctionBody
extern JS_FRIEND_API(JSBool)
js_CompileTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts,
JSCodeGenerator *cg);
extern JSBool
js_CompileFunctionBody(JSContext *cx, JSTokenStream *ts, JSFunction *fun);
/* XXXbe expose js_Parse{TokenStream,FunctionBody} that return trees? */
extern JSBool
js_FoldConstants(JSContext *cx, JSParseNode *pn);
JS_END_EXTERN_C
#endif /* jsparse_h___ */

1225
mozilla/js/src/jsprf.c Normal file

File diff suppressed because it is too large Load Diff

128
mozilla/js/src/jsprf.h Normal file
View File

@@ -0,0 +1,128 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsprf_h___
#define jsprf_h___
/*
** API for PR printf like routines. Supports the following formats
** %d - decimal
** %u - unsigned decimal
** %x - unsigned hex
** %X - unsigned uppercase hex
** %o - unsigned octal
** %hd, %hu, %hx, %hX, %ho - 16-bit versions of above
** %ld, %lu, %lx, %lX, %lo - 32-bit versions of above
** %lld, %llu, %llx, %llX, %llo - 64 bit versions of above
** %s - string
** %c - character
** %p - pointer (deals with machine dependent pointer size)
** %f - float
** %g - float
*/
#include "jstypes.h"
#include <stdio.h>
#include <stdarg.h>
JS_BEGIN_EXTERN_C
/*
** sprintf into a fixed size buffer. Guarantees that a NUL is at the end
** of the buffer. Returns the length of the written output, NOT including
** the NUL, or (JSUint32)-1 if an error occurs.
*/
JS_EXTERN_API(JSUint32) JS_snprintf(char *out, JSUint32 outlen, const char *fmt, ...);
/*
** sprintf into a malloc'd buffer. Return a pointer to the malloc'd
** buffer on success, NULL on failure. Call "JS_smprintf_free" to release
** the memory returned.
*/
JS_EXTERN_API(char*) JS_smprintf(const char *fmt, ...);
/*
** Free the memory allocated, for the caller, by JS_smprintf
*/
JS_EXTERN_API(void) JS_smprintf_free(char *mem);
/*
** "append" sprintf into a malloc'd buffer. "last" is the last value of
** the malloc'd buffer. sprintf will append data to the end of last,
** growing it as necessary using realloc. If last is NULL, JS_sprintf_append
** will allocate the initial string. The return value is the new value of
** last for subsequent calls, or NULL if there is a malloc failure.
*/
JS_EXTERN_API(char*) JS_sprintf_append(char *last, const char *fmt, ...);
/*
** sprintf into a function. The function "f" is called with a string to
** place into the output. "arg" is an opaque pointer used by the stuff
** function to hold any state needed to do the storage of the output
** data. The return value is a count of the number of characters fed to
** the stuff function, or (JSUint32)-1 if an error occurs.
*/
typedef JSIntn (*JSStuffFunc)(void *arg, const char *s, JSUint32 slen);
JS_EXTERN_API(JSUint32) JS_sxprintf(JSStuffFunc f, void *arg, const char *fmt, ...);
/*
** va_list forms of the above.
*/
JS_EXTERN_API(JSUint32) JS_vsnprintf(char *out, JSUint32 outlen, const char *fmt, va_list ap);
JS_EXTERN_API(char*) JS_vsmprintf(const char *fmt, va_list ap);
JS_EXTERN_API(char*) JS_vsprintf_append(char *last, const char *fmt, va_list ap);
JS_EXTERN_API(JSUint32) JS_vsxprintf(JSStuffFunc f, void *arg, const char *fmt, va_list ap);
/*
***************************************************************************
** FUNCTION: JS_sscanf
** DESCRIPTION:
** JS_sscanf() scans the input character string, performs data
** conversions, and stores the converted values in the data objects
** pointed to by its arguments according to the format control
** string.
**
** JS_sscanf() behaves the same way as the sscanf() function in the
** Standard C Library (stdio.h), with the following exceptions:
** - JS_sscanf() handles the NSPR integer and floating point types,
** such as JSInt16, JSInt32, JSInt64, and JSFloat64, whereas
** sscanf() handles the standard C types like short, int, long,
** and double.
** - JS_sscanf() has no multibyte character support, while sscanf()
** does.
** INPUTS:
** const char *buf
** a character string holding the input to scan
** const char *fmt
** the format control string for the conversions
** ...
** variable number of arguments, each of them is a pointer to
** a data object in which the converted value will be stored
** OUTPUTS: none
** RETURNS: JSInt32
** The number of values converted and stored.
** RESTRICTIONS:
** Multibyte characters in 'buf' or 'fmt' are not allowed.
***************************************************************************
*/
JS_EXTERN_API(JSInt32) JS_sscanf(const char *buf, const char *fmt, ...);
JS_END_EXTERN_C
#endif /* jsprf_h___ */

131
mozilla/js/src/jsprhash.h Normal file
View File

@@ -0,0 +1,131 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef JSplhash_h___
#define JSplhash_h___
/*
* API to portable hash table code.
*/
#include <stddef.h>
#include <stdio.h>
#include "jsprtypes.h"
JSPR_BEGIN_EXTERN_C
typedef struct JSPRHashEntry JSPRHashEntry;
typedef struct JSPRHashTable JSPRHashTable;
typedef JSPRUint32 JSPRHashNumber;
#define JSPR_HASH_BITS 32
typedef JSPRHashNumber (JSJS_DLL_CALLBACK *JSPRHashFunction)(const void *key);
typedef JSPRIntn (JSJS_DLL_CALLBACK *JSPRHashComparator)(const void *v1, const void *v2);
typedef JSPRIntn (JSJS_DLL_CALLBACK *JSPRHashEnumerator)(JSPRHashEntry *he, JSPRIntn i, void *arg);
/* Flag bits in JSPRHashEnumerator's return value */
#define HT_ENUMERATE_NEXT 0 /* continue enumerating entries */
#define HT_ENUMERATE_STOP 1 /* stop enumerating entries */
#define HT_ENUMERATE_REMOVE 2 /* remove and free the current entry */
#define HT_ENUMERATE_UNHASH 4 /* just unhash the current entry */
typedef struct JSPRHashAllocOps {
void * (JSJS_DLL_CALLBACK *allocTable)(void *pool, JSPRSize size);
void (JSJS_DLL_CALLBACK *freeTable)(void *pool, void *item);
JSPRHashEntry * (JSJS_DLL_CALLBACK *allocEntry)(void *pool, const void *key);
void (JSJS_DLL_CALLBACK *freeEntry)(void *pool, JSPRHashEntry *he, JSPRUintn flag);
} JSPRHashAllocOps;
#define HT_FREE_VALUE 0 /* just free the entry's value */
#define HT_FREE_ENTRY 1 /* free value and entire entry */
struct JSPRHashEntry {
JSPRHashEntry *next; /* hash chain linkage */
JSPRHashNumber keyHash; /* key hash function result */
const void *key; /* ptr to opaque key */
void *value; /* ptr to opaque value */
};
struct JSPRHashTable {
JSPRHashEntry **buckets; /* vector of hash buckets */
JSPRUint32 nentries; /* number of entries in table */
JSPRUint32 shift; /* multiplicative hash shift */
JSPRHashFunction keyHash; /* key hash function */
JSPRHashComparator keyCompare; /* key comparison function */
JSPRHashComparator valueCompare; /* value comparison function */
JSPRHashAllocOps *allocOps; /* allocation operations */
void *allocPriv; /* allocation private data */
#ifdef HASHMETER
JSPRUint32 nlookups; /* total number of lookups */
JSPRUint32 nsteps; /* number of hash chains traversed */
JSPRUint32 ngrows; /* number of table expansions */
JSPRUint32 nshrinks; /* number of table contractions */
#endif
};
/*
* Create a new hash table.
* If allocOps is null, use default allocator ops built on top of malloc().
*/
JSJS_EXTERN_API(JSPRHashTable *)
JSPR_NewHashTable(JSPRUint32 n, JSPRHashFunction keyHash,
JSPRHashComparator keyCompare, JSPRHashComparator valueCompare,
JSPRHashAllocOps *allocOps, void *allocPriv);
JSJS_EXTERN_API(void)
JSPR_HashTableDestroy(JSPRHashTable *ht);
/* Low level access methods */
JSJS_EXTERN_API(JSPRHashEntry **)
JSPR_HashTableRawLookup(JSPRHashTable *ht, JSPRHashNumber keyHash, const void *key);
JSJS_EXTERN_API(JSPRHashEntry *)
JSPR_HashTableRawAdd(JSPRHashTable *ht, JSPRHashEntry **hep, JSPRHashNumber keyHash,
const void *key, void *value);
JSJS_EXTERN_API(void)
JSPR_HashTableRawRemove(JSPRHashTable *ht, JSPRHashEntry **hep, JSPRHashEntry *he);
/* Higher level access methods */
JSJS_EXTERN_API(JSPRHashEntry *)
JSPR_HashTableAdd(JSPRHashTable *ht, const void *key, void *value);
JSJS_EXTERN_API(JSPRBool)
JSPR_HashTableRemove(JSPRHashTable *ht, const void *key);
JSJS_EXTERN_API(JSPRIntn)
JSPR_HashTableEnumerateEntries(JSPRHashTable *ht, JSPRHashEnumerator f, void *arg);
JSJS_EXTERN_API(void *)
JSPR_HashTableLookup(JSPRHashTable *ht, const void *key);
JSJS_EXTERN_API(JSPRIntn)
JSPR_HashTableDump(JSPRHashTable *ht, JSPRHashEnumerator dump, FILE *fp);
/* General-purpose C string hash function. */
JSJS_EXTERN_API(JSPRHashNumber)
JSPR_HashString(const void *key);
/* Compare strings using strcmp(), return true if equal. */
JSJS_EXTERN_API(int)
JSPR_CompareStrings(const void *v1, const void *v2);
/* Stub function just returns v1 == v2 */
JSJS_EXTERN_API(JSPRIntn)
JSPR_CompareValues(const void *v1, const void *v2);
JSPR_END_EXTERN_C
#endif /* JSplhash_h___ */

157
mozilla/js/src/jsprvtd.h Normal file
View File

@@ -0,0 +1,157 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsprvtd_h___
#define jsprvtd_h___
/*
* JS private typename definitions.
*
* This header is included only in other .h files, for convenience and for
* simplicity of type naming. The alternative for structures is to use tags,
* which are named the same as their typedef names (legal in C/C++, and less
* noisy than suffixing the typedef name with "Struct" or "Str"). Instead,
* all .h files that include this file may use the same typedef name, whether
* declaring a pointer to struct type, or defining a member of struct type.
*
* A few fundamental scalar types are defined here too. Neither the scalar
* nor the struct typedefs should change much, therefore the nearly-global
* make dependency induced by this file should not prove painful.
*/
#include "jspubtd.h"
/* Scalar typedefs. */
typedef uint8 jsbytecode;
typedef uint8 jssrcnote;
typedef uint32 jsatomid;
/* Struct typedefs. */
typedef struct JSCodeGenerator JSCodeGenerator;
typedef struct JSGCThing JSGCThing;
typedef struct JSParseNode JSParseNode;
typedef struct JSSharpObjectMap JSSharpObjectMap;
typedef struct JSToken JSToken;
typedef struct JSTokenPos JSTokenPos;
typedef struct JSTokenPtr JSTokenPtr;
typedef struct JSTokenStream JSTokenStream;
typedef struct JSTreeContext JSTreeContext;
typedef struct JSTryNote JSTryNote;
/* Friend "Advanced API" typedefs. */
typedef struct JSAtom JSAtom;
typedef struct JSAtomList JSAtomList;
typedef struct JSAtomListElement JSAtomListElement;
typedef struct JSAtomMap JSAtomMap;
typedef struct JSAtomState JSAtomState;
typedef struct JSCodeSpec JSCodeSpec;
typedef struct JSPrinter JSPrinter;
typedef struct JSRegExp JSRegExp;
typedef struct JSRegExpStatics JSRegExpStatics;
typedef struct JSScope JSScope;
typedef struct JSScopeOps JSScopeOps;
typedef struct JSScopeProperty JSScopeProperty;
typedef struct JSStackFrame JSStackFrame;
typedef struct JSSubString JSSubString;
typedef struct JSSymbol JSSymbol;
/* "Friend" types used by jscntxt.h and jsdbgapi.h. */
typedef enum JSTrapStatus {
JSTRAP_ERROR,
JSTRAP_CONTINUE,
JSTRAP_RETURN,
JSTRAP_THROW,
JSTRAP_LIMIT
} JSTrapStatus;
#ifndef CRT_CALL
#ifdef XP_OS2
#define CRT_CALL _Optlink
#else
#define CRT_CALL
#endif
#endif
typedef JSTrapStatus
(* CRT_CALL JSTrapHandler)(JSContext *cx, JSScript *script, jsbytecode *pc,
jsval *rval, void *closure);
typedef JSBool
(* CRT_CALL JSWatchPointHandler)(JSContext *cx, JSObject *obj, jsval id,
jsval old, jsval *newp, void *closure);
/* called just after script creation */
typedef void
(* CRT_CALL JSNewScriptHook)(JSContext *cx,
const char *filename, /* URL of script */
uintN lineno, /* line script starts */
JSScript *script,
JSFunction *fun,
void *callerdata);
/* called just before script destruction */
typedef void
(* CRT_CALL JSDestroyScriptHook)(JSContext *cx,
JSScript *script,
void *callerdata);
typedef void
(* CRT_CALL JSSourceHandler)(const char *filename, uintN lineno,
jschar *str, size_t length,
void **listenerTSData, void *closure);
/*
* This hook captures high level script execution and function calls
* (JS or native).
* It is used by JS_SetExecuteHook to hook top level scripts and by
* JS_SetCallHook to hook function calls.
* It will get called twice per script or function call:
* just before execution begins and just after it finishes. In both cases
* the 'current' frame is that of the executing code.
*
* The 'before' param is JS_TRUE for the hook invocation before the execution
* and JS_FALSE for the invocation after the code has run.
*
* The 'ok' param is significant only on the post execution invocation to
* signify whether or not the code completed 'normally'.
*
* The 'closure' param is as passed to JS_SetExecuteHook or JS_SetCallHook
* for the 'before'invocation, but is whatever value is returned from that
* invocation for the 'after' invocation. Thus, the hook implementor *could*
* allocate a stucture in the 'before' invocation and return a pointer
* to that structure. The pointer would then be handed to the hook for
* the 'after' invocation. Alternately, the 'before' could just return the
* same value as in 'closure' to cause the 'after' invocation to be called
* with the same 'closure' value as the 'before'.
*
* Returning NULL in the 'before' hook will cause the 'after' hook to
* NOT be called.
*/
typedef void *
(* CRT_CALL JSInterpreterHook)(JSContext *cx, JSStackFrame *fp, JSBool before,
JSBool *ok, void *closure);
typedef void
(* CRT_CALL JSObjectHook)(JSContext *cx, JSObject *obj, JSBool isNew,
void *closure);
typedef JSBool
(* CRT_CALL JSDebugErrorHook)(JSContext *cx, const char *message,
JSErrorReport *report, void *closure);
#endif /* jsprvtd_h___ */

243
mozilla/js/src/jspubtd.h Normal file
View File

@@ -0,0 +1,243 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jspubtd_h___
#define jspubtd_h___
/*
* JS public API typedefs.
*/
#include "jstypes.h"
#include "jscompat.h"
JS_BEGIN_EXTERN_C
/* Scalar typedefs. */
typedef uint16 jschar;
typedef int32 jsint;
typedef uint32 jsuint;
typedef float64 jsdouble;
typedef jsword jsval;
typedef jsword jsid;
typedef jsword jsrefcount;
typedef enum JSVersion {
JSVERSION_1_0 = 100,
JSVERSION_1_1 = 110,
JSVERSION_1_2 = 120,
JSVERSION_1_3 = 130,
JSVERSION_1_4 = 140,
JSVERSION_DEFAULT = 0,
JSVERSION_UNKNOWN = -1
} JSVersion;
#define JSVERSION_IS_ECMA(version) \
((version) == JSVERSION_DEFAULT || (version) >= JSVERSION_1_3)
/* Result of typeof operator enumeration. */
typedef enum JSType {
JSTYPE_VOID, /* undefined */
JSTYPE_OBJECT, /* object */
JSTYPE_FUNCTION, /* function */
JSTYPE_STRING, /* string */
JSTYPE_NUMBER, /* number */
JSTYPE_BOOLEAN, /* boolean */
JSTYPE_LIMIT
} JSType;
/* JSObjectOps.checkAccess mode enumeration. */
typedef enum JSAccessMode {
JSACC_PROTO,
JSACC_PARENT,
JSACC_IMPORT,
JSACC_WATCH,
JSACC_LIMIT
} JSAccessMode;
/*
* This enum type is used to control the behavior of a JSObject property
* iterator function that has type JSNewEnumerate.
*/
typedef enum JSIterateOp {
JSENUMERATE_INIT, /* Create new iterator state */
JSENUMERATE_NEXT, /* Iterate once */
JSENUMERATE_DESTROY /* Destroy iterator state */
} JSIterateOp;
/* Struct typedefs. */
typedef struct JSClass JSClass;
typedef struct JSConstDoubleSpec JSConstDoubleSpec;
typedef struct JSContext JSContext;
typedef struct JSErrorReport JSErrorReport;
typedef struct JSFunction JSFunction;
typedef struct JSFunctionSpec JSFunctionSpec;
typedef struct JSIdArray JSIdArray;
typedef struct JSProperty JSProperty;
typedef struct JSPropertySpec JSPropertySpec;
typedef struct JSObject JSObject;
typedef struct JSObjectMap JSObjectMap;
typedef struct JSObjectOps JSObjectOps;
typedef struct JSRuntime JSRuntime;
typedef struct JSRuntime JSTaskState; /* XXX deprecated name */
typedef struct JSScript JSScript;
typedef struct JSString JSString;
typedef struct JSXDRState JSXDRState;
typedef struct JSExceptionState JSExceptionState;
#ifndef CRT_CALL
#ifdef XP_OS2
#define CRT_CALL _Optlink
#else
#define CRT_CALL
#endif
#endif
/* JSClass (and JSObjectOps where appropriate) function pointer typedefs. */
typedef JSBool
(* CRT_CALL JSPropertyOp)(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
/*
* This function type is used for callbacks that enumerate the properties of a
* JSObject. The behavior depends on the value of enum_op:
*
* JSENUMERATE_INIT - A new, opaque iterator state should be allocated and
* stored in *statep. (You can use PRIVATE_TO_JSVAL() to store
* a pointer in *statep). The number of properties that will be
* enumerated should be returned as an integer jsval in *idp, if idp
* is non-NULL.
* JSENUMERATE_NEXT - A previously allocated opaque iterator state is passed
* in via statep. Return the next jsid in the iteration using *idp.
* The opaque iterator state pointed at by statep is destroyed and
* *statep is set to JSVAL_NULL if there are no properties left to
* enumerate.
* JSENUMERATE_DESTROY - Destroy the opaque iterator previous allocated by
* a call to this function with enum_op set to JSENUMERATE_INIT.
*
* The return value is always used to indicate success, with a value of JS_FALSE
* for failure.
*/
typedef JSBool
(* CRT_CALL JSNewEnumerateOp)(JSContext *cx, JSObject *obj,
JSIterateOp enum_op,
jsval *statep, jsid *idp);
typedef JSBool
(* CRT_CALL JSEnumerateOp)(JSContext *cx, JSObject *obj);
typedef JSBool
(* CRT_CALL JSResolveOp)(JSContext *cx, JSObject *obj, jsval id);
typedef JSBool
(* CRT_CALL JSNewResolveOp)(JSContext *cx, JSObject *obj, jsval id, uintN flags,
JSObject **objp);
typedef JSBool
(* CRT_CALL JSConvertOp)(JSContext *cx, JSObject *obj, JSType type, jsval *vp);
typedef void
(* CRT_CALL JSFinalizeOp)(JSContext *cx, JSObject *obj);
typedef JSObjectOps *
(* CRT_CALL JSGetObjectOps)(JSContext *cx, JSClass *clasp);
typedef JSBool
(* CRT_CALL JSCheckAccessOp)(JSContext *cx, JSObject *obj, jsval id,
JSAccessMode mode, jsval *vp);
typedef JSBool
(* CRT_CALL JSXDRObjectOp)(JSXDRState *xdr, JSObject **objp);
typedef JSBool
(* CRT_CALL JSHasInstanceOp)(JSContext *cx, JSObject *obj, jsval v,
JSBool *bp);
/* JSObjectOps function pointer typedefs. */
typedef JSObjectMap *
(* CRT_CALL JSNewObjectMapOp)(JSContext *cx, jsrefcount nrefs,
JSObjectOps *ops, JSClass *clasp,
JSObject *obj);
typedef void
(* CRT_CALL JSObjectMapOp)(JSContext *cx, JSObjectMap *map);
typedef JSBool
(* CRT_CALL JSLookupPropOp)(JSContext *cx, JSObject *obj, jsid id,
JSObject **objp, JSProperty **propp
#if defined JS_THREADSAFE && defined DEBUG
, const char *file, uintN line
#endif
);
typedef JSBool
(* CRT_CALL JSDefinePropOp)(JSContext *cx, JSObject *obj, jsid id, jsval value,
JSPropertyOp getter, JSPropertyOp setter,
uintN attrs, JSProperty **propp);
typedef JSBool
(* CRT_CALL JSPropertyIdOp)(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
typedef JSBool
(* CRT_CALL JSAttributesOp)(JSContext *cx, JSObject *obj, jsid id,
JSProperty *prop, uintN *attrsp);
typedef JSBool
(* CRT_CALL JSCheckAccessIdOp)(JSContext *cx, JSObject *obj, jsid id,
JSAccessMode mode, jsval *vp, uintN *attrsp);
typedef JSObject *
(* CRT_CALL JSObjectOp)(JSContext *cx, JSObject *obj);
typedef void
(* CRT_CALL JSPropertyRefOp)(JSContext *cx, JSObject *obj, JSProperty *prop);
/* Typedef for native functions called by the JS VM. */
typedef JSBool
(* CRT_CALL JSNative)(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval);
/* Callbacks and their arguments. */
typedef enum JSGCStatus {
JSGC_BEGIN,
JSGC_END
} JSGCStatus;
typedef JSBool
(* CRT_CALL JSGCCallback)(JSContext *cx, JSGCStatus status);
typedef JSBool
(* CRT_CALL JSBranchCallback)(JSContext *cx, JSScript *script);
typedef void
(* CRT_CALL JSErrorReporter)(JSContext *cx, const char *message,
JSErrorReport *report);
typedef struct JSErrorFormatString {
const char *format;
const uintN argCount;
} JSErrorFormatString;
typedef const JSErrorFormatString *
(* CRT_CALL JSErrorCallback)(void *userRef, const char *locale,
const uintN errorNumber);
JS_END_EXTERN_C
#endif /* jspubtd_h___ */

3318
mozilla/js/src/jsregexp.c Normal file

File diff suppressed because it is too large Load Diff

107
mozilla/js/src/jsregexp.h Normal file
View File

@@ -0,0 +1,107 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsregexp_h___
#define jsregexp_h___
/*
* JS regular expression interface.
*/
#include <stddef.h>
#include "jspubtd.h"
#include "jsstr.h"
struct JSRegExpStatics {
JSString *input; /* input string to match (perl $_, GC root) */
JSBool multiline; /* whether input contains newlines (perl $*) */
uintN parenCount; /* number of valid elements in parens[] */
uintN moreLength; /* number of allocated elements in moreParens */
JSSubString parens[9]; /* last set of parens matched (perl $1, $2) */
JSSubString *moreParens; /* null or realloc'd vector for $10, etc. */
JSSubString lastMatch; /* last string matched (perl $&) */
JSSubString lastParen; /* last paren matched (perl $+) */
JSSubString leftContext; /* input to left of last match (perl $`) */
JSSubString rightContext; /* input to right of last match (perl $') */
};
/*
* This macro is safe because moreParens is guaranteed to be allocated and big
* enough to hold parenCount, or else be null when parenCount is 0.
*/
#define REGEXP_PAREN_SUBSTRING(res, num) \
(((jsuint)(num) < (jsuint)(res)->parenCount) \
? ((jsuint)(num) < 9) \
? &(res)->parens[num] \
: &(res)->moreParens[(num) - 9] \
: &js_EmptySubString)
struct JSRegExp {
JSString *source; /* locked source string, sans // */
size_t length; /* program length in bytes */
size_t lastIndex; /* index after last match, for //g iterator */
uintN parenCount; /* number of parenthesized submatches */
uint8 flags; /* flags, see jsapi.h */
jsbytecode program[1]; /* regular expression bytecode */
};
extern JSRegExp *
js_NewRegExp(JSContext *cx, JSString *str, uintN flags);
extern JSRegExp *
js_NewRegExpOpt(JSContext *cx, JSString *str, JSString *opt);
extern void
js_DestroyRegExp(JSContext *cx, JSRegExp *re);
/*
* Execute re on input str at *indexp, returning null in *rval on mismatch.
* On match, return true if test is true, otherwise return an array object.
* Update *indexp and cx->regExpStatics always on match.
*/
extern JSBool
js_ExecuteRegExp(JSContext *cx, JSRegExp *re, JSString *str, size_t *indexp,
JSBool test, jsval *rval);
/*
* These two add and remove GC roots, respectively, so their calls must be
* well-ordered.
*/
extern JSBool
js_InitRegExpStatics(JSContext *cx, JSRegExpStatics *res);
extern void
js_FreeRegExpStatics(JSContext *cx, JSRegExpStatics *res);
#define JSVAL_IS_REGEXP(cx, v) \
(JSVAL_IS_OBJECT(v) && JSVAL_TO_OBJECT(v) && \
OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_RegExpClass)
extern JSClass js_RegExpClass;
extern JSObject *
js_InitRegExpClass(JSContext *cx, JSObject *obj);
/*
* Create a new RegExp object.
*/
extern JSObject *
js_NewRegExpObject(JSContext *cx, jschar *chars, size_t length, uintN flags);
extern JSBool
js_XDRRegExp(JSXDRState *xdr, JSObject **objp);
#endif /* jsregexp_h___ */

1194
mozilla/js/src/jsscan.c Normal file

File diff suppressed because it is too large Load Diff

264
mozilla/js/src/jsscan.h Normal file
View File

@@ -0,0 +1,264 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsscan_h___
#define jsscan_h___
/*
* JS lexical scanner interface.
*/
#include <stddef.h>
#ifdef JSFILE
#include <stdio.h>
#endif
#include "jsopcode.h"
#include "jsprvtd.h"
#include "jspubtd.h"
JS_BEGIN_EXTERN_C
typedef enum JSTokenType {
TOK_ERROR = -1, /* well-known as the only code < EOF */
TOK_EOF = 0, /* end of file */
TOK_EOL = 1, /* end of line */
TOK_SEMI = 2, /* semicolon */
TOK_LB = 3, TOK_RB = 4, /* left and right brackets */
TOK_LC = 5, TOK_RC = 6, /* left and right curlies (braces) */
TOK_LP = 7, TOK_RP = 8, /* left and right parentheses */
TOK_COMMA = 9, /* comma operator */
TOK_ASSIGN = 10, /* assignment ops (= += -= etc.) */
TOK_HOOK = 11, TOK_COLON = 12, /* conditional (?:) */
TOK_OR = 13, /* logical or (||) */
TOK_AND = 14, /* logical and (&&) */
TOK_BITOR = 15, /* bitwise-or (|) */
TOK_BITXOR = 16, /* bitwise-xor (^) */
TOK_BITAND = 17, /* bitwise-and (&) */
TOK_EQOP = 18, /* equality ops (== !=) */
TOK_RELOP = 19, /* relational ops (< <= > >=) */
TOK_SHOP = 20, /* shift ops (<< >> >>>) */
TOK_PLUS = 21, /* plus */
TOK_MINUS = 22, /* minus */
TOK_STAR = 23, TOK_DIVOP = 24, /* multiply/divide ops (* / %) */
TOK_UNARYOP = 25, /* unary prefix operator */
TOK_INC = 26, TOK_DEC = 27, /* increment/decrement (++ --) */
TOK_DOT = 28, /* member operator (.) */
TOK_NAME = 29, /* identifier */
TOK_NUMBER = 30, /* numeric constant */
TOK_STRING = 31, /* string constant */
TOK_OBJECT = 32, /* RegExp or other object constant */
TOK_PRIMARY = 33, /* true, false, null, this, super */
TOK_FUNCTION = 34, /* function keyword */
TOK_EXPORT = 35, /* export keyword */
TOK_IMPORT = 36, /* import keyword */
TOK_IF = 37, /* if keyword */
TOK_ELSE = 38, /* else keyword */
TOK_SWITCH = 39, /* switch keyword */
TOK_CASE = 40, /* case keyword */
TOK_DEFAULT = 41, /* default keyword */
TOK_WHILE = 42, /* while keyword */
TOK_DO = 43, /* do keyword */
TOK_FOR = 44, /* for keyword */
TOK_BREAK = 45, /* break keyword */
TOK_CONTINUE = 46, /* continue keyword */
TOK_IN = 47, /* in keyword */
TOK_VAR = 48, /* var keyword */
TOK_WITH = 49, /* with keyword */
TOK_RETURN = 50, /* return keyword */
TOK_NEW = 51, /* new keyword */
TOK_DELETE = 52, /* delete keyword */
TOK_DEFSHARP = 53, /* #n= for object/array initializers */
TOK_USESHARP = 54, /* #n# for object/array initializers */
TOK_TRY = 55, /* try keyword */
TOK_CATCH = 56, /* catch keyword */
TOK_FINALLY = 57, /* finally keyword */
TOK_THROW = 58, /* throw keyword */
TOK_INSTANCEOF = 59, /* instanceof keyword */
TOK_DEBUGGER = 60, /* debugger keyword */
TOK_RESERVED, /* reserved keywords */
TOK_LIMIT /* domain size */
} JSTokenType;
#define IS_PRIMARY_TOKEN(tt) \
((uintN)((tt) - TOK_NAME) <= (uintN)(TOK_PRIMARY - TOK_NAME))
struct JSTokenPtr {
uint16 index; /* index of char in physical line */
uint16 lineno; /* physical line number */
};
struct JSTokenPos {
JSTokenPtr begin; /* first character and line of token */
JSTokenPtr end; /* index 1 past last char, last line */
};
struct JSToken {
JSTokenType type; /* char value or above enumerator */
JSTokenPos pos; /* token position in file */
jschar *ptr; /* beginning of token in line buffer */
union {
struct {
JSOp op; /* operator, for minimal parser */
JSAtom *atom; /* atom table entry */
} s;
jsdouble dval; /* floating point number */
} u;
};
#define t_op u.s.op
#define t_atom u.s.atom
#define t_dval u.dval
typedef struct JSTokenBuf {
jschar *base; /* base of line or stream buffer */
jschar *limit; /* limit for quick bounds check */
jschar *ptr; /* next char to get, or slot to use */
} JSTokenBuf;
#define JS_LINE_LIMIT 256 /* logical line buffer size limit --
physical line length is unlimited */
struct JSTokenStream {
JSToken token; /* last token scanned */
JSToken pushback; /* pushed-back already-scanned token */
uintN lineno; /* current line number */
uintN ungetpos; /* next free char slot in ungetbuf */
jschar ungetbuf[4]; /* at most 4, for \uXXXX lookahead */
uintN flags; /* flags -- see below */
ptrdiff_t linelen; /* physical linebuf segment length */
ptrdiff_t linepos; /* linebuf offset in physical line */
JSTokenBuf linebuf; /* line buffer for diagnostics */
JSTokenBuf userbuf; /* user input buffer if !file */
JSTokenBuf tokenbuf; /* current token string buffer */
const char *filename; /* input filename or null */
#ifdef JSFILE
FILE *file; /* stdio stream if reading from file */
#endif
JSPrincipals *principals; /* principals associated with given input */
JSSourceHandler listener; /* callback for source; eg debugger */
void *listenerData; /* listener 'this' data */
void *listenerTSData;/* listener data for this TokenStream */
};
/* JSTokenStream flags */
#define TSF_ERROR 0x01 /* fatal error while scanning */
#define TSF_EOF 0x02 /* hit end of file */
#define TSF_NEWLINES 0x04 /* tokenize newlines */
#define TSF_REGEXP 0x08 /* looking for a regular expression */
#define TSF_INTERACTIVE 0x10 /* interactive parsing mode */
#define TSF_NLFLAG 0x20 /* last linebuf ended with \n */
#define TSF_CRFLAG 0x40 /* linebuf would have ended with \r */
#define TSF_BADCOMPILE 0x80 /* compile failed, stop throwing exns */
/*
* At most one non-EOF token can be pushed back onto a TokenStream between
* Get or successful Match operations. These macros manipulate the pushback
* token to clear it when changing scanning modes (upon initialzation, after
* errors, or between newline-sensitive and insensitive states).
*/
#define CLEAR_PUSHBACK(ts) ((ts)->pushback.type = TOK_EOF)
#define SCAN_NEWLINES(ts) ((ts)->flags |= TSF_NEWLINES)
#define HIDE_NEWLINES(ts) \
JS_BEGIN_MACRO \
(ts)->flags &= ~TSF_NEWLINES; \
if ((ts)->pushback.type == TOK_EOL) \
(ts)->pushback.type = TOK_EOF; \
JS_END_MACRO
/* Clear ts member that might point above a released cx->tempPool mark. */
#define RESET_TOKENBUF(ts) ((ts)->tokenbuf.base = (ts)->tokenbuf.limit = NULL)
/*
* Create a new token stream, either from an input buffer or from a file.
* Return null on file-open or memory-allocation failure.
*
* NB: All of js_New{,Buffer,File}TokenStream() return a pointer to transient
* memory in the current context's temp pool. This memory is deallocated via
* JS_ARENA_RELEASE() after parsing is finished.
*/
extern JSTokenStream *
js_NewTokenStream(JSContext *cx, const jschar *base, size_t length,
const char *filename, uintN lineno, JSPrincipals *principals);
extern JS_FRIEND_API(JSTokenStream *)
js_NewBufferTokenStream(JSContext *cx, const jschar *base, size_t length);
#ifdef JSFILE
extern JS_FRIEND_API(JSTokenStream *)
js_NewFileTokenStream(JSContext *cx, const char *filename, FILE *defaultfp);
#endif
extern JS_FRIEND_API(JSBool)
js_CloseTokenStream(JSContext *cx, JSTokenStream *ts);
/*
* Initialize the scanner, installing JS keywords into cx's global scope.
*/
extern JSBool
js_InitScanner(JSContext *cx);
/*
* Friend-exported API entry point to call a mapping function on each reserved
* identifier in the scanner's keyword table.
*/
extern JS_FRIEND_API(void)
js_MapKeywords(void (*mapfun)(const char *));
/*
* Report an error found while scanning ts to a window or other output device
* associated with cx.
*/
#if 0
/* XXX js_ReportCompileError is unused */
extern void
js_ReportCompileError(JSContext *cx, JSTokenStream *ts, uintN flags,
const char *format, ...);
#endif
void
js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts, uintN flags,
const uintN errorNumber, ...);
/*
* Look ahead one token and return its type.
*/
extern JSTokenType
js_PeekToken(JSContext *cx, JSTokenStream *ts);
extern JSTokenType
js_PeekTokenSameLine(JSContext *cx, JSTokenStream *ts);
/*
* Get the next token from ts.
*/
extern JSTokenType
js_GetToken(JSContext *cx, JSTokenStream *ts);
/*
* Push back the last scanned token onto ts.
*/
extern void
js_UngetToken(JSTokenStream *ts);
/*
* Get the next token from ts if its type is tt.
*/
extern JSBool
js_MatchToken(JSContext *cx, JSTokenStream *ts, JSTokenType tt);
JS_END_EXTERN_C
#endif /* jsscan_h___ */

524
mozilla/js/src/jsscope.c Normal file
View File

@@ -0,0 +1,524 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* JS symbol tables.
*/
#include "jsstddef.h"
#include <string.h>
#include "jstypes.h"
#include "jsutil.h" /* Added by JSIFY */
#include "jsapi.h"
#include "jsatom.h"
#include "jscntxt.h"
#include "jsinterp.h"
#include "jslock.h"
#include "jsnum.h"
#include "jsscope.h"
#include "jsstr.h"
JS_STATIC_DLL_CALLBACK(JSHashNumber)
js_hash_id(const void *key)
{
jsval v;
const JSAtom *atom;
v = (jsval)key;
if (JSVAL_IS_INT(v))
return JSVAL_TO_INT(v);
atom = key;
return atom->number;
}
typedef struct JSScopePrivate {
JSContext *context;
JSScope *scope;
} JSScopePrivate;
JS_STATIC_DLL_CALLBACK(void *)
js_alloc_scope_space(void *priv, size_t size)
{
return JS_malloc(((JSScopePrivate *)priv)->context, size);
}
JS_STATIC_DLL_CALLBACK(void)
js_free_scope_space(void *priv, void *item)
{
JS_free(((JSScopePrivate *)priv)->context, item);
}
JS_STATIC_DLL_CALLBACK(JSHashEntry *)
js_alloc_symbol(void *priv, const void *key)
{
JSScopePrivate *spriv;
JSContext *cx;
JSSymbol *sym;
spriv = priv;
JS_ASSERT(JS_IS_SCOPE_LOCKED(spriv->scope));
cx = spriv->context;
sym = JS_malloc(cx, sizeof(JSSymbol));
if (!sym)
return NULL;
sym->entry.key = key;
return &sym->entry;
}
JS_STATIC_DLL_CALLBACK(void)
js_free_symbol(void *priv, JSHashEntry *he, uintN flag)
{
JSScopePrivate *spriv;
JSContext *cx;
JSSymbol *sym, **sp;
JSScopeProperty *sprop;
spriv = priv;
JS_ASSERT(JS_IS_SCOPE_LOCKED(spriv->scope));
cx = spriv->context;
sym = (JSSymbol *)he;
sprop = sym->entry.value;
if (sprop) {
sym->entry.value = NULL;
sprop = js_DropScopeProperty(cx, spriv->scope, sprop);
if (sprop) {
for (sp = &sprop->symbols; *sp; sp = &(*sp)->next) {
if (*sp == sym) {
*sp = sym->next;
if (!*sp)
break;
}
}
sym->next = NULL;
}
}
if (flag == HT_FREE_ENTRY)
JS_free(cx, he);
}
static JSHashAllocOps hash_scope_alloc_ops = {
js_alloc_scope_space, js_free_scope_space,
js_alloc_symbol, js_free_symbol
};
/************************************************************************/
JS_STATIC_DLL_CALLBACK(JSSymbol *)
js_hash_scope_lookup(JSContext *cx, JSScope *scope, jsid id, JSHashNumber hash)
{
JSHashTable *table = scope->data;
JSHashEntry **hep;
JSSymbol *sym;
hep = JS_HashTableRawLookup(table, hash, (const void *)id);
sym = (JSSymbol *) *hep;
return sym;
}
#define SCOPE_ADD(PRIV, CLASS_SPECIFIC_CODE) \
JS_BEGIN_MACRO \
if (sym) { \
if (sym->entry.value == sprop) \
return sym; \
if (sym->entry.value) \
js_free_symbol(PRIV, &sym->entry, HT_FREE_VALUE); \
} else { \
CLASS_SPECIFIC_CODE \
sym->scope = scope; \
sym->next = NULL; \
} \
if (sprop) { \
sym->entry.value = js_HoldScopeProperty(cx, scope, sprop); \
for (sp = &sprop->symbols; *sp; sp = &(*sp)->next) \
; \
*sp = sym; \
} else { \
sym->entry.value = NULL; \
} \
JS_END_MACRO
JS_STATIC_DLL_CALLBACK(JSSymbol *)
js_hash_scope_add(JSContext *cx, JSScope *scope, jsid id, JSScopeProperty *sprop)
{
JSHashTable *table = scope->data;
const void *key;
JSHashNumber keyHash;
JSHashEntry **hep;
JSSymbol *sym, **sp;
JSScopePrivate *priv;
JS_ASSERT(JS_IS_SCOPE_LOCKED(scope));
priv = table->allocPriv;
priv->context = cx;
key = (const void *)id;
keyHash = js_hash_id(key);
hep = JS_HashTableRawLookup(table, keyHash, key);
sym = (JSSymbol *) *hep;
SCOPE_ADD(priv,
sym = (JSSymbol *) JS_HashTableRawAdd(table, hep, keyHash, key, NULL);
if (!sym)
return NULL;
);
return sym;
}
JS_STATIC_DLL_CALLBACK(JSBool)
js_hash_scope_remove(JSContext *cx, JSScope *scope, jsid id)
{
JSHashTable *table = scope->data;
JSScopePrivate *priv;
JS_ASSERT(JS_IS_SCOPE_LOCKED(scope));
priv = table->allocPriv;
priv->context = cx;
return JS_HashTableRemove(table, (const void *)id);
}
/* Forward declaration for use by js_hash_scope_clear(). */
extern JS_FRIEND_DATA(JSScopeOps) js_list_scope_ops;
JS_STATIC_DLL_CALLBACK(void)
js_hash_scope_clear(JSContext *cx, JSScope *scope)
{
JSHashTable *table = scope->data;
JSScopePrivate *priv;
JS_ASSERT(JS_IS_SCOPE_LOCKED(scope));
priv = table->allocPriv;
priv->context = cx;
JS_HashTableDestroy(table);
JS_free(cx, priv);
scope->ops = &js_list_scope_ops;
scope->data = NULL;
}
JSScopeOps js_hash_scope_ops = {
js_hash_scope_lookup,
js_hash_scope_add,
js_hash_scope_remove,
js_hash_scope_clear
};
/************************************************************************/
static void
move_sym_to_front(JSSymbol *sym, JSSymbol **nextp, JSSymbol **front)
{
*nextp = (JSSymbol*)sym->entry.next;
sym->entry.next = &(*front)->entry;
*front = sym;
}
JS_STATIC_DLL_CALLBACK(JSSymbol *)
js_list_scope_lookup(JSContext *cx, JSScope *scope, jsid id, JSHashNumber hash)
{
JSSymbol *sym, **sp;
JS_ASSERT(JS_IS_SCOPE_LOCKED(scope));
for (sp = (JSSymbol **)&scope->data; (sym = *sp) != 0;
sp = (JSSymbol **)&sym->entry.next) {
if (sym_id(sym) == id) {
/* Move sym to the front for shorter searches. */
move_sym_to_front(sym,sp,(JSSymbol**)&scope->data);
return sym;
}
}
return NULL;
}
#define HASH_THRESHOLD 5
JS_STATIC_DLL_CALLBACK(JSSymbol *)
js_list_scope_add(JSContext *cx, JSScope *scope, jsid id, JSScopeProperty *sprop)
{
JSSymbol *list = scope->data;
uint32 nsyms;
JSSymbol *sym, *next, **sp;
JSHashTable *table;
JSHashEntry **hep;
JSScopePrivate priv;
JS_ASSERT(JS_IS_SCOPE_LOCKED(scope));
nsyms = 0;
for (sym = list; sym; sym = (JSSymbol *)sym->entry.next) {
if (sym_id(sym) == id)
break;
nsyms++;
}
if (nsyms >= HASH_THRESHOLD) {
JSScopePrivate *priv = JS_malloc(cx, sizeof(JSScopePrivate));
if (!priv) return NULL;
priv->context = cx;
priv->scope = scope;
table = JS_NewHashTable(nsyms, js_hash_id,
JS_CompareValues, JS_CompareValues,
&hash_scope_alloc_ops, priv);
if (table) {
for (sym = list; sym; sym = next) {
/* Save next for loop update, before it changes in lookup. */
next = (JSSymbol *)sym->entry.next;
/* Now compute missing keyHash fields. */
sym->entry.keyHash = js_hash_id(sym->entry.key);
sym->entry.next = NULL;
hep = JS_HashTableRawLookup(table,
sym->entry.keyHash,
sym->entry.key);
*hep = &sym->entry;
}
table->nentries = nsyms;
scope->ops = &js_hash_scope_ops;
scope->data = table;
return scope->ops->add(cx, scope, id, sprop);
}
}
priv.context = cx;
priv.scope = scope;
SCOPE_ADD(&priv,
sym = (JSSymbol *)js_alloc_symbol(&priv, (const void *)id);
if (!sym)
return NULL;
/* Don't set keyHash until we know we need it, above. */
sym->entry.next = scope->data;
scope->data = sym;
);
return sym;
}
JS_STATIC_DLL_CALLBACK(JSBool)
js_list_scope_remove(JSContext *cx, JSScope *scope, jsid id)
{
JSSymbol *sym, **sp;
JSScopePrivate priv;
JS_ASSERT(JS_IS_SCOPE_LOCKED(scope));
for (sp = (JSSymbol **)&scope->data; (sym = *sp) != 0;
sp = (JSSymbol **)&sym->entry.next) {
if (sym_id(sym) == id) {
*sp = (JSSymbol *)sym->entry.next;
priv.context = cx;
priv.scope = scope;
js_free_symbol(&priv, &sym->entry, HT_FREE_ENTRY);
return JS_TRUE;
}
}
return JS_FALSE;
}
JS_STATIC_DLL_CALLBACK(void)
js_list_scope_clear(JSContext *cx, JSScope *scope)
{
JSSymbol *sym;
JSScopePrivate priv;
JS_ASSERT(JS_IS_SCOPE_LOCKED(scope));
while ((sym = scope->data) != NULL) {
scope->data = sym->entry.next;
priv.context = cx;
priv.scope = scope;
js_free_symbol(&priv, &sym->entry, HT_FREE_ENTRY);
}
}
JSScopeOps JS_FRIEND_DATA(js_list_scope_ops) = {
js_list_scope_lookup,
js_list_scope_add,
js_list_scope_remove,
js_list_scope_clear
};
/************************************************************************/
JSScope *
js_GetMutableScope(JSContext *cx, JSObject *obj)
{
JSScope *scope, *newscope;
scope = (JSScope *) obj->map;
JS_ASSERT(JS_IS_SCOPE_LOCKED(scope));
if (scope->object == obj)
return scope;
newscope = js_NewScope(cx, 0, scope->map.ops, LOCKED_OBJ_GET_CLASS(obj),
obj);
if (!newscope)
return NULL;
JS_LOCK_SCOPE(cx, newscope);
obj->map = js_HoldObjectMap(cx, &newscope->map);
scope = (JSScope *) js_DropObjectMap(cx, &scope->map, obj);
JS_TRANSFER_SCOPE_LOCK(cx, scope, newscope);
return newscope;
}
JSScope *
js_MutateScope(JSContext *cx, JSObject *obj, jsid id,
JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
JSScopeProperty **propp)
{
/* XXX pessimal */
*propp = NULL;
return js_GetMutableScope(cx, obj);
}
JSScope *
js_NewScope(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, JSClass *clasp,
JSObject *obj)
{
JSScope *scope;
scope = JS_malloc(cx, sizeof(JSScope));
if (!scope)
return NULL;
js_InitObjectMap(&scope->map, nrefs, ops, clasp);
scope->object = obj;
scope->props = NULL;
scope->proptail = &scope->props;
scope->ops = &js_list_scope_ops;
scope->data = NULL;
#ifdef JS_THREADSAFE
js_NewLock(&scope->lock);
scope->count = 0;
#ifdef DEBUG
scope->file[0] = scope->file[1] = scope->file[2] = scope->file[3] = NULL;
scope->line[0] = scope->line[1] = scope->line[2] = scope->line[3] = 0;
#endif
#endif
return scope;
}
void
js_DestroyScope(JSContext *cx, JSScope *scope)
{
JS_LOCK_SCOPE(cx, scope);
scope->ops->clear(cx, scope);
JS_UNLOCK_SCOPE(cx, scope);
#ifdef JS_THREADSAFE
JS_ASSERT(scope->count == 0);
js_DestroyLock(&scope->lock);
#endif
JS_free(cx, scope);
}
JSHashNumber
js_HashValue(jsval v)
{
return js_hash_id((const void *)v);
}
jsval
js_IdToValue(jsid id)
{
JSAtom *atom;
if (JSVAL_IS_INT(id))
return id;
atom = (JSAtom *)id;
return ATOM_KEY(atom);
}
JSScopeProperty *
js_NewScopeProperty(JSContext *cx, JSScope *scope, jsid id,
JSPropertyOp getter, JSPropertyOp setter, uintN attrs)
{
uint32 slot;
JSScopeProperty *sprop;
JS_ASSERT(JS_IS_SCOPE_LOCKED(scope));
if (!js_AllocSlot(cx, scope->object, &slot))
return NULL;
sprop = JS_malloc(cx, sizeof(JSScopeProperty));
if (!sprop) {
js_FreeSlot(cx, scope->object, slot);
return NULL;
}
sprop->nrefs = 0;
sprop->id = js_IdToValue(id);
sprop->getter = getter;
sprop->setter = setter;
sprop->slot = slot;
sprop->attrs = attrs;
sprop->spare = 0;
sprop->symbols = NULL;
sprop->next = NULL;
sprop->prevp = scope->proptail;
*scope->proptail = sprop;
scope->proptail = &sprop->next;
return sprop;
}
void
js_DestroyScopeProperty(JSContext *cx, JSScope *scope, JSScopeProperty *sprop)
{
/*
* Test whether obj was finalized before prop's last dereference.
*
* This can happen when a deleted property is held by a property iterator
* object (which points to obj, keeping obj alive so long as the property
* iterator is reachable). As soon as the GC finds the iterator to be
* unreachable, it will finalize the iterator, and may also finalize obj,
* in an unpredictable order. If obj is finalized first, its map will be
* null below, and we need only free prop.
*
* In the more typical case of a property whose last reference (from a
* symbol in obj's scope) goes away before obj is finalized, we must be
* sure to free prop's slot and unlink it from obj's property list.
*/
if (scope) {
JS_ASSERT(JS_IS_SCOPE_LOCKED(scope));
if (scope->object) {
js_FreeSlot(cx, scope->object, sprop->slot);
*sprop->prevp = sprop->next;
if (sprop->next)
sprop->next->prevp = sprop->prevp;
else
scope->proptail = sprop->prevp;
}
}
/* Purge any cached weak links to prop, then free it. */
js_FlushPropertyCacheByProp(cx, (JSProperty *)sprop);
JS_free(cx, sprop);
}
JSScopeProperty *
js_HoldScopeProperty(JSContext *cx, JSScope *scope, JSScopeProperty *sprop)
{
JS_ASSERT(JS_IS_SCOPE_LOCKED(scope));
if (sprop) {
JS_ASSERT(sprop->nrefs >= 0);
sprop->nrefs++;
}
return sprop;
}
JSScopeProperty *
js_DropScopeProperty(JSContext *cx, JSScope *scope, JSScopeProperty *sprop)
{
JS_ASSERT(JS_IS_SCOPE_LOCKED(scope));
if (sprop) {
JS_ASSERT(sprop->nrefs > 0);
if (--sprop->nrefs == 0) {
js_DestroyScopeProperty(cx, scope, sprop);
sprop = NULL;
}
}
return sprop;
}

122
mozilla/js/src/jsscope.h Normal file
View File

@@ -0,0 +1,122 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsscope_h___
#define jsscope_h___
/*
* JS symbol tables.
*/
#include "jstypes.h"
#include "jshash.h" /* Added by JSIFY */
#include "jsobj.h"
#include "jsprvtd.h"
#include "jspubtd.h"
struct JSScopeOps {
JSSymbol * (*lookup)(JSContext *cx, JSScope *scope, jsid id,
JSHashNumber hash);
JSSymbol * (*add)(JSContext *cx, JSScope *scope, jsid id,
JSScopeProperty *sprop);
JSBool (*remove)(JSContext *cx, JSScope *scope, jsid id);
void (*clear)(JSContext *cx, JSScope *scope);
};
struct JSScope {
JSObjectMap map; /* base class state */
JSObject *object; /* object that owns this scope */
JSScopeProperty *props; /* property list in definition order */
JSScopeProperty **proptail; /* pointer to pointer to last prop */
JSScopeOps *ops; /* virtual operations */
void *data; /* private data specific to ops */
#ifdef JS_THREADSAFE
JSThinLock lock; /* binary semaphore protecting scope */
int32 count; /* entry count for reentrancy */
#ifdef DEBUG
const char *file[4]; /* file where lock was (re-)taken */
unsigned int line[4]; /* line where lock was (re-)taken */
#endif
#endif
};
struct JSSymbol {
JSHashEntry entry; /* base class state */
JSScope *scope; /* pointer to owning scope */
JSSymbol *next; /* next in type-specific list */
};
#define sym_id(sym) ((jsid)(sym)->entry.key)
#define sym_atom(sym) ((JSAtom *)(sym)->entry.key)
#define sym_property(sym) ((JSScopeProperty *)(sym)->entry.value)
struct JSScopeProperty {
jsrefcount nrefs; /* number of referencing symbols */
jsval id; /* id passed to getter and setter */
JSPropertyOp getter; /* getter and setter methods */
JSPropertyOp setter;
uint32 slot; /* index in obj->slots vector */
uint8 attrs; /* attributes, see jsapi.h JSPROP_ */
uint8 spare; /* reserved for future use */
JSSymbol *symbols; /* list of aliasing symbols */
JSScopeProperty *next; /* doubly-linked list linkage */
JSScopeProperty **prevp;
};
/*
* These macros are designed to decouple getter and setter from sprop, by
* passing obj2 (in whose scope sprop lives, and in whose scope getter and
* setter might be stored apart from sprop -- say in scope->opTable[i] for
* a compressed getter or setter index i that is stored in sprop).
*/
#define SPROP_GET(cx,sprop,obj,obj2,vp) ((sprop)->getter(cx,obj,sprop->id,vp))
#define SPROP_SET(cx,sprop,obj,obj2,vp) ((sprop)->setter(cx,obj,sprop->id,vp))
extern JSScope *
js_GetMutableScope(JSContext *cx, JSObject *obj);
extern JSScope *
js_MutateScope(JSContext *cx, JSObject *obj, jsid id,
JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
JSScopeProperty **propp);
extern JSScope *
js_NewScope(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, JSClass *clasp,
JSObject *obj);
extern void
js_DestroyScope(JSContext *cx, JSScope *scope);
extern JSHashNumber
js_HashValue(jsval v);
extern jsval
js_IdToValue(jsid id);
extern JSScopeProperty *
js_NewScopeProperty(JSContext *cx, JSScope *scope, jsid id,
JSPropertyOp getter, JSPropertyOp setter, uintN attrs);
extern void
js_DestroyScopeProperty(JSContext *cx, JSScope *scope, JSScopeProperty *sprop);
extern JSScopeProperty *
js_HoldScopeProperty(JSContext *cx, JSScope *scope, JSScopeProperty *sprop);
extern JSScopeProperty *
js_DropScopeProperty(JSContext *cx, JSScope *scope, JSScopeProperty *sprop);
#endif /* jsscope_h___ */

783
mozilla/js/src/jsscript.c Normal file
View File

@@ -0,0 +1,783 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* JS script operations.
*/
#include "jsstddef.h"
#include <string.h>
#include "jstypes.h"
#include "jsutil.h" /* Added by JSIFY */
#include "jsprf.h"
#include "jsapi.h"
#include "jsatom.h"
#include "jscntxt.h"
#include "jsconfig.h"
#include "jsdbgapi.h"
#include "jsemit.h"
#include "jsfun.h"
#include "jsinterp.h"
#include "jsnum.h"
#include "jsopcode.h"
#include "jsscript.h"
#if JS_HAS_XDR
#include "jsxdrapi.h"
#endif
#if JS_HAS_SCRIPT_OBJECT
#if JS_HAS_TOSOURCE
static JSBool
script_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
JSScript *script;
size_t i, j, k, n;
char buf[16];
jschar *s, *t;
uint32 indent;
JSString *str;
if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
return JS_FALSE;
script = JS_GetPrivate(cx, obj);
/* Let n count the source string length, j the "front porch" length. */
j = JS_snprintf(buf, sizeof buf, "(new %s(", js_ScriptClass.name);
n = j + 2;
if (!script) {
/* Let k count the constructor argument string length. */
k = 0;
s = NULL; /* quell GCC overwarning */
} else {
indent = 0;
if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent))
return JS_FALSE;
str = JS_DecompileScript(cx, script, "Script.prototype.toSource",
(uintN)indent);
if (!str)
return JS_FALSE;
str = js_QuoteString(cx, str, '\'');
if (!str)
return JS_FALSE;
s = str->chars;
k = str->length;
n += k;
}
/* Allocate the source string and copy into it. */
t = JS_malloc(cx, (n + 1) * sizeof(jschar));
if (!t)
return JS_FALSE;
for (i = 0; i < j; i++)
t[i] = buf[i];
for (j = 0; j < k; i++, j++)
t[i] = s[j];
t[i++] = ')';
t[i++] = ')';
t[i] = 0;
/* Create and return a JS string for t. */
str = JS_NewUCString(cx, t, n);
if (!str) {
JS_free(cx, t);
return JS_FALSE;
}
*rval = STRING_TO_JSVAL(str);
return JS_TRUE;
}
#endif /* JS_HAS_TOSOURCE */
static JSBool
script_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
JSScript *script;
uint32 indent;
JSString *str;
if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
return JS_FALSE;
script = JS_GetPrivate(cx, obj);
if (!script) {
*rval = STRING_TO_JSVAL(cx->runtime->emptyString);
return JS_TRUE;
}
indent = 0;
if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent))
return JS_FALSE;
str = JS_DecompileScript(cx, script, "Script.prototype.toString",
(uintN)indent);
if (!str)
return JS_FALSE;
*rval = STRING_TO_JSVAL(str);
return JS_TRUE;
}
static JSBool
script_compile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
JSScript *oldscript, *script;
JSString *str;
JSStackFrame *fp, *caller;
JSObject *scopeobj;
const char *file;
uintN line;
JSPrincipals *principals;
/* If no args, leave private undefined and return early. */
if (argc == 0)
goto out;
/* Otherwise, the first arg is the script source to compile. */
str = js_ValueToString(cx, argv[0]);
if (!str)
return JS_FALSE;
/* Compile using the caller's scope chain, which js_Invoke passes to fp. */
fp = cx->fp;
caller = fp->down;
JS_ASSERT(fp->scopeChain == caller->scopeChain);
scopeobj = NULL;
if (argc >= 2) {
if (!js_ValueToObject(cx, argv[1], &scopeobj))
return JS_FALSE;
argv[1] = OBJECT_TO_JSVAL(scopeobj);
}
if (!scopeobj)
scopeobj = caller->scopeChain;
if (caller->script) {
file = caller->script->filename;
line = js_PCToLineNumber(caller->script, caller->pc);
principals = caller->script->principals;
} else {
file = NULL;
line = 0;
principals = NULL;
}
/* Compile the new script using the caller's scope chain, a la eval(). */
script = JS_CompileUCScriptForPrincipals(cx, scopeobj, principals,
str->chars, str->length,
file, line);
if (!script)
return JS_FALSE;
/* Swap script for obj's old script, if any. */
oldscript = JS_GetPrivate(cx, obj);
if (!JS_SetPrivate(cx, obj, script)) {
js_DestroyScript(cx, script);
return JS_FALSE;
}
if (oldscript)
js_DestroyScript(cx, oldscript);
script->object = obj;
out:
/* Return the object. */
*rval = OBJECT_TO_JSVAL(obj);
return JS_TRUE;
}
static JSBool
script_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
JSScript *script;
JSStackFrame *fp, *caller;
JSObject *scopeobj;
if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
return JS_FALSE;
script = JS_GetPrivate(cx, obj);
if (!script)
return JS_TRUE;
scopeobj = NULL;
if (argc) {
if (!js_ValueToObject(cx, argv[0], &scopeobj))
return JS_FALSE;
argv[0] = OBJECT_TO_JSVAL(scopeobj);
}
/* Emulate eval() by using caller's this, scope chain, and sharp array. */
fp = cx->fp;
caller = fp->down;
if (!scopeobj)
scopeobj = caller->scopeChain;
fp->thisp = caller->thisp;
JS_ASSERT(fp->scopeChain == caller->scopeChain);
fp->sharpArray = caller->sharpArray;
return js_Execute(cx, scopeobj, script, NULL, fp, JS_FALSE, rval);
}
#if JS_HAS_XDR
static JSBool
XDRAtom1(JSXDRState *xdr, JSAtomListElement *ale)
{
uint32 type;
jsval value;
if (xdr->mode == JSXDR_ENCODE) {
type = JSVAL_TAG(ATOM_KEY(ale->atom));
value = ATOM_KEY(ale->atom);
}
if (!JS_XDRUint32(xdr, &ale->index) ||
!JS_XDRValue(xdr, &value))
return JS_FALSE;
if (xdr->mode == JSXDR_DECODE) {
ale->atom = js_AtomizeValue(xdr->cx, value, 0);
if (!ale->atom)
return JS_FALSE;
}
return JS_TRUE;
}
static JSBool
XDRAtomMap(JSXDRState *xdr, JSAtomMap *map)
{
uint32 length;
uintN i;
if (xdr->mode == JSXDR_ENCODE)
length = map->length;
if (!JS_XDRUint32(xdr, &length))
return JS_FALSE;
if (xdr->mode == JSXDR_DECODE) {
JSContext *cx;
void *mark;
JSAtomList al;
JSAtomListElement *ale;
cx = xdr->cx;
mark = JS_ARENA_MARK(&cx->tempPool);
ATOM_LIST_INIT(&al);
for (i = 0; i < length; i++) {
JS_ARENA_ALLOCATE(ale, &cx->tempPool, sizeof(*ale));
if (!ale ||
!XDRAtom1(xdr, ale)) {
if (!ale)
JS_ReportOutOfMemory(cx);
JS_ARENA_RELEASE(&cx->tempPool, mark);
return JS_FALSE;
}
ale->next = al.list;
al.count++;
al.list = ale;
}
if (!js_InitAtomMap(cx, map, &al)) {
JS_ARENA_RELEASE(&cx->tempPool, mark);
return JS_FALSE;
}
JS_ARENA_RELEASE(&cx->tempPool, mark);
} else if (xdr->mode == JSXDR_ENCODE) {
JSAtomListElement ale;
for (i = 0; i < map->length; i++) {
ale.atom = map->vector[i];
ale.index = i;
if (!XDRAtom1(xdr, &ale))
return JS_FALSE;
}
}
return JS_TRUE;
}
JSBool
js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *magic)
{
JSScript *script = *scriptp;
uint32 length, lineno, depth, magicval;
if (xdr->mode == JSXDR_ENCODE)
magicval = SCRIPT_XDRMAGIC;
if (!JS_XDRUint32(xdr, &magicval))
return JS_FALSE;
if (magicval != SCRIPT_XDRMAGIC) {
*magic = JS_FALSE;
return JS_TRUE;
}
*magic = JS_TRUE;
if (xdr->mode == JSXDR_ENCODE) {
length = script->length;
lineno = (uint32)script->lineno;
depth = (uint32)script->depth;
}
if (!JS_XDRUint32(xdr, &length))
return JS_FALSE;
if (xdr->mode == JSXDR_DECODE) {
script = js_NewScript(xdr->cx, length);
if (!script)
return JS_FALSE;
*scriptp = script;
}
if (!JS_XDRBytes(xdr, (char **)&script->code, length) ||
!XDRAtomMap(xdr, &script->atomMap) ||
!JS_XDRCStringOrNull(xdr, (char **)&script->notes) ||
!JS_XDRCStringOrNull(xdr, (char **)&script->filename) ||
!JS_XDRUint32(xdr, &lineno) ||
!JS_XDRUint32(xdr, &depth)) {
if (xdr->mode == JSXDR_DECODE) {
js_DestroyScript(xdr->cx, script);
*scriptp = NULL;
}
return JS_FALSE;
}
if (xdr->mode == JSXDR_DECODE) {
script->lineno = (uintN)lineno;
script->depth = (uintN)depth;
}
return JS_TRUE;
}
static JSBool
script_freeze(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
JSXDRState *xdr;
JSScript *script;
JSBool ok, magic;
uint32 len;
void *buf;
JSString *str;
if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
return JS_FALSE;
script = JS_GetPrivate(cx, obj);
if (!script)
return JS_TRUE;
/* create new XDR */
xdr = JS_XDRNewMem(cx, JSXDR_ENCODE);
if (!xdr)
return JS_FALSE;
/* write */
ok = js_XDRScript(xdr, &script, &magic);
if (!ok)
goto out;
if (!magic) {
*rval = JSVAL_VOID;
goto out;
}
buf = JS_XDRMemGetData(xdr, &len);
if (!buf) {
ok = JS_FALSE;
goto out;
}
JS_ASSERT((jsword)buf % sizeof(jschar) == 0);
len /= sizeof(jschar);
str = JS_NewUCStringCopyN(cx, (jschar *)buf, len);
if (!str) {
ok = JS_FALSE;
goto out;
}
#if IS_BIG_ENDIAN
{
jschar *chars;
uint32 i;
/* Swap bytes in Unichars to keep frozen strings machine-independent. */
chars = JS_GetStringChars(str);
for (i = 0; i < len; i++)
chars[i] = JSXDR_SWAB16(chars[i]);
}
#endif
*rval = STRING_TO_JSVAL(str);
out:
JS_XDRDestroy(xdr);
return ok;
}
static JSBool
script_thaw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
JSXDRState *xdr;
JSString *str;
void *buf;
uint32 len;
JSScript *script, *oldscript;
JSBool ok, magic;
if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
return JS_FALSE;
if (argc == 0)
return JS_TRUE;
str = js_ValueToString(cx, argv[0]);
if (!str)
return JS_FALSE;
/* create new XDR */
xdr = JS_XDRNewMem(cx, JSXDR_DECODE);
if (!xdr)
return JS_FALSE;
buf = JS_GetStringChars(str);
len = JS_GetStringLength(str);
#if IS_BIG_ENDIAN
{
jschar *from, *to;
uint32 i;
/* Swap bytes in Unichars to keep frozen strings machine-independent. */
from = (jschar *)buf;
to = JS_malloc(cx, len * sizeof(jschar));
if (!to)
return JS_FALSE;
for (i = 0; i < len; i++)
to[i] = JSXDR_SWAB16(from[i]);
buf = (char *)to;
}
#endif
len *= sizeof(jschar);
JS_XDRMemSetData(xdr, buf, len);
/* XXXbe should magic mismatch be error, or false return value? */
ok = js_XDRScript(xdr, &script, &magic);
if (!ok)
goto out;
if (!magic) {
*rval = JSVAL_FALSE;
goto out;
}
/* Swap script for obj's old script, if any. */
oldscript = JS_GetPrivate(cx, obj);
ok = JS_SetPrivate(cx, obj, script);
if (!ok) {
JS_free(cx, script);
goto out;
}
if (oldscript)
js_DestroyScript(cx, oldscript);
script->object = obj;
out:
/*
* We reset the buffer to be NULL so that it doesn't free the chars
* memory owned by str (argv[0]).
*/
JS_XDRMemSetData(xdr, NULL, 0);
JS_XDRDestroy(xdr);
#if IS_BIG_ENDIAN
JS_free(cx, buf);
#endif
*rval = JSVAL_TRUE;
return ok;
}
#endif /* JS_HAS_XDR */
static char js_thaw_str[] = "thaw";
static JSFunctionSpec script_methods[] = {
#if JS_HAS_TOSOURCE
{js_toSource_str, script_toSource, 0},
#endif
{js_toString_str, script_toString, 0},
{"compile", script_compile, 2},
{"exec", script_exec, 1},
#if JS_HAS_XDR
{"freeze", script_freeze, 0},
{js_thaw_str, script_thaw, 1},
#endif /* JS_HAS_XDR */
{0}
};
#endif /* JS_HAS_SCRIPT_OBJECT */
static void
script_finalize(JSContext *cx, JSObject *obj)
{
JSScript *script;
script = JS_GetPrivate(cx, obj);
if (script)
js_DestroyScript(cx, script);
}
static JSBool
script_call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
return script_exec(cx, JSVAL_TO_OBJECT(argv[-2]), argc, argv, rval);
}
JSClass js_ScriptClass = {
"Script",
JSCLASS_HAS_PRIVATE,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, script_finalize,
NULL, NULL, script_call, NULL,/*XXXbe xdr*/
};
#if JS_HAS_SCRIPT_OBJECT
static JSBool
Script(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
/* If not constructing, replace obj with a new Script object. */
if (!cx->fp->constructing) {
obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL);
if (!obj)
return JS_FALSE;
}
return script_compile(cx, obj, argc, argv, rval);
}
#if JS_HAS_XDR
static JSBool
script_static_thaw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL);
if (!obj)
return JS_FALSE;
if (!script_thaw(cx, obj, argc, argv, rval))
return JS_FALSE;
*rval = OBJECT_TO_JSVAL(obj);
return JS_TRUE;
}
static JSFunctionSpec script_static_methods[] = {
{js_thaw_str, script_static_thaw, 1},
{0}
};
#else /* !JS_HAS_XDR */
#define script_static_methods NULL
#endif /* !JS_HAS_XDR */
JSObject *
js_InitScriptClass(JSContext *cx, JSObject *obj)
{
return JS_InitClass(cx, obj, NULL, &js_ScriptClass, Script, 1,
NULL, script_methods, NULL, script_static_methods);
}
#endif /* JS_HAS_SCRIPT_OBJECT */
JSScript *
js_NewScript(JSContext *cx, uint32 length)
{
JSScript *script;
script = JS_malloc(cx, sizeof(JSScript) + length * sizeof(jsbytecode));
if (!script)
return NULL;
memset(script, 0, sizeof(JSScript));
script->code = (jsbytecode *)(script + 1);
script->length = length;
return script;
}
JSScript *
js_NewScriptFromParams(JSContext *cx, jsbytecode *code, uint32 length,
const char *filename, uintN lineno, uintN depth,
jssrcnote *notes, JSTryNote *trynotes,
JSPrincipals *principals)
{
JSScript *script;
script = js_NewScript(cx, length);
if (!script)
return NULL;
memcpy(script->code, code, length * sizeof(jsbytecode));
if (filename) {
script->filename = JS_strdup(cx, filename);
if (!script->filename) {
js_DestroyScript(cx, script);
return NULL;
}
}
script->lineno = lineno;
script->depth = depth;
script->notes = notes;
script->trynotes = trynotes;
if (principals)
JSPRINCIPALS_HOLD(cx, principals);
script->principals = principals;
return script;
}
JS_FRIEND_API(JSScript *)
js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg, JSFunction *fun)
{
JSTryNote *trynotes;
jssrcnote *notes;
JSScript *script;
JSRuntime *rt;
JSNewScriptHook hook;
if (!js_FinishTakingTryNotes(cx, cg, &trynotes))
return NULL;
notes = js_FinishTakingSrcNotes(cx, cg);
script = js_NewScriptFromParams(cx, cg->base, CG_OFFSET(cg),
cg->filename, cg->firstLine,
cg->maxStackDepth, notes, trynotes,
cg->principals);
if (!script)
return NULL;
if (!notes || !js_InitAtomMap(cx, &script->atomMap, &cg->atomList)) {
js_DestroyScript(cx, script);
return NULL;
}
/* Tell the debugger about this compiled script. */
rt = cx->runtime;
hook = rt->newScriptHook;
if (hook) {
(*hook)(cx, cg->filename, cg->firstLine, script, fun,
rt->newScriptHookData);
}
return script;
}
void
js_DestroyScript(JSContext *cx, JSScript *script)
{
JSRuntime *rt;
JSDestroyScriptHook hook;
rt = cx->runtime;
hook = rt->destroyScriptHook;
if (hook)
(*hook)(cx, script, rt->destroyScriptHookData);
JS_ClearScriptTraps(cx, script);
js_FreeAtomMap(cx, &script->atomMap);
JS_free(cx, (void *)script->filename);
JS_free(cx, script->notes);
JS_free(cx, script->trynotes);
if (script->principals)
JSPRINCIPALS_DROP(cx, script->principals);
JS_free(cx, script);
}
jssrcnote *
js_GetSrcNote(JSScript *script, jsbytecode *pc)
{
jssrcnote *sn;
ptrdiff_t offset, target;
sn = script->notes;
if (!sn)
return NULL;
target = PTRDIFF(pc, script->code, jsbytecode);
if ((uintN)target >= script->length)
return NULL;
for (offset = 0; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
offset += SN_DELTA(sn);
if (offset == target && SN_IS_GETTABLE(sn))
return sn;
}
return NULL;
}
uintN
js_PCToLineNumber(JSScript *script, jsbytecode *pc)
{
jssrcnote *sn;
ptrdiff_t offset, target;
uintN lineno;
JSSrcNoteType type;
sn = script->notes;
if (!sn)
return 0;
target = PTRDIFF(pc, script->code, jsbytecode);
lineno = script->lineno;
for (offset = 0; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
offset += SN_DELTA(sn);
type = SN_TYPE(sn);
if (type == SRC_SETLINE) {
if (offset <= target)
lineno = (uintN) js_GetSrcNoteOffset(sn, 0);
} else if (type == SRC_NEWLINE) {
if (offset <= target)
lineno++;
}
if (offset > target)
break;
}
return lineno;
}
jsbytecode *
js_LineNumberToPC(JSScript *script, uintN target)
{
jssrcnote *sn;
uintN lineno;
ptrdiff_t offset;
JSSrcNoteType type;
sn = script->notes;
if (!sn)
return NULL;
lineno = script->lineno;
for (offset = 0; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
if (lineno >= target)
break;
offset += SN_DELTA(sn);
type = SN_TYPE(sn);
if (type == SRC_SETLINE) {
lineno = (uintN) js_GetSrcNoteOffset(sn, 0);
} else if (type == SRC_NEWLINE) {
lineno++;
}
}
return script->code + offset;
}
uintN
js_GetScriptLineExtent(JSScript *script)
{
jssrcnote *sn;
uintN lineno;
JSSrcNoteType type;
sn = script->notes;
if (!sn)
return 0;
lineno = script->lineno;
for (; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
type = SN_TYPE(sn);
if (type == SRC_SETLINE) {
lineno = (uintN) js_GetSrcNoteOffset(sn, 0);
} else if (type == SRC_NEWLINE) {
lineno++;
}
}
return 1 + lineno - script->lineno;
}

93
mozilla/js/src/jsscript.h Normal file
View File

@@ -0,0 +1,93 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsscript_h___
#define jsscript_h___
/*
* JS script descriptor.
*/
#include "jsatom.h"
#include "jsprvtd.h"
JS_BEGIN_EXTERN_C
/*
* Exception handling runtime information.
*
* All fields except length are code offsets, relative to the beginning of
* the script. If script->trynotes is not null, it points to a vector of
* these structs terminated by one with start, catchStart, and finallyStart
* all equal to 0, and length == script->length.
*/
struct JSTryNote {
ptrdiff_t start; /* start of try statement */
ptrdiff_t length; /* count of try statement bytecodes */
ptrdiff_t catchStart; /* start of catch block (0 if none) */
};
struct JSScript {
jsbytecode *code; /* bytecodes and their immediate operands */
uint32 length; /* length of code vector */
JSAtomMap atomMap; /* maps immediate index to literal struct */
const char *filename; /* source filename or null */
uintN lineno; /* base line number of script */
uintN depth; /* maximum stack depth in slots */
jssrcnote *notes; /* line number and other decompiling data */
JSTryNote *trynotes; /* exception table for this script */
JSPrincipals *principals; /* principals for this script */
JSObject *object; /* optional Script-class object wrapper */
};
extern JSClass js_ScriptClass;
extern JSObject *
js_InitScriptClass(JSContext *cx, JSObject *obj);
extern JSScript *
js_NewScript(JSContext *cx, uint32 length);
extern JSScript *
js_NewScriptFromParams(JSContext *cx, jsbytecode *code, uint32 length,
const char *filename, uintN lineno, uintN depth,
jssrcnote *notes, JSTryNote *trynotes,
JSPrincipals *principals);
extern JS_FRIEND_API(JSScript *)
js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg, JSFunction *fun);
extern void
js_DestroyScript(JSContext *cx, JSScript *script);
extern jssrcnote *
js_GetSrcNote(JSScript *script, jsbytecode *pc);
extern uintN
js_PCToLineNumber(JSScript *script, jsbytecode *pc);
extern jsbytecode *
js_LineNumberToPC(JSScript *script, uintN lineno);
extern uintN
js_GetScriptLineExtent(JSScript *script);
extern JSBool
js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *magic);
JS_END_EXTERN_C
#endif /* jsscript_h___ */

View File

@@ -0,0 +1,29 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
Error messages for JSShell. See js.msg for format.
*/
MSG_DEF(JSSMSG_NOT_AN_ERROR, 0, 0, JSEXN_NONE, "<Error #0 is reserved>")
MSG_DEF(JSSMSG_CANT_OPEN, 1, 2, JSEXN_NONE, "can't open {0}: {1}")
MSG_DEF(JSSMSG_TRAP_USAGE, 2, 0, JSEXN_NONE, "usage: trap [fun] [pc] expr")
MSG_DEF(JSSMSG_LINE2PC_USAGE, 3, 0, JSEXN_NONE, "usage: line2pc [fun] line")
MSG_DEF(JSSMSG_FILE_SCRIPTS_ONLY, 4, 0, JSEXN_NONE, "only works on JS scripts read from files")
MSG_DEF(JSSMSG_UNEXPECTED_EOF, 5, 1, JSEXN_NONE, "unexpected EOF in {0}")
MSG_DEF(JSSMSG_DOEXP_USAGE, 6, 0, JSEXN_NONE, "usage: doexp obj id")

63
mozilla/js/src/jsstddef.h Normal file
View File

@@ -0,0 +1,63 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/*
* stddef inclusion here to first declare ptrdif as a signed long instead of a
* signed int.
*/
#ifdef _WINDOWS
# ifndef XP_WIN
# define XP_WIN
# endif
#if defined(_WIN32) || defined(WIN32)
# ifndef XP_WIN32
# define XP_WIN32
# endif
#else
# ifndef XP_WIN16
# define XP_WIN16
# endif
#endif
#endif
#ifdef XP_WIN16
#ifndef _PTRDIFF_T_DEFINED
typedef long ptrdiff_t;
/*
* The Win16 compiler treats pointer differences as 16-bit signed values.
* This macro allows us to treat them as 17-bit signed values, stored in
* a 32-bit type.
*/
#define PTRDIFF(p1, p2, type) \
((((unsigned long)(p1)) - ((unsigned long)(p2))) / sizeof(type))
#define _PTRDIFF_T_DEFINED
#endif /*_PTRDIFF_T_DEFINED*/
#else /*WIN16*/
#define PTRDIFF(p1, p2, type) \
((p1) - (p2))
#endif
#include <stddef.h>

3687
mozilla/js/src/jsstr.c Normal file

File diff suppressed because it is too large Load Diff

269
mozilla/js/src/jsstr.h Normal file
View File

@@ -0,0 +1,269 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsstr_h___
#define jsstr_h___
/*
* JS string type implementation.
*
* A JS string is a counted array of unicode characters. To support handoff
* of API client memory, the chars are allocated separately from the length,
* necessitating a pointer after the count, to form a string header. String
* headers are GC'ed while string bytes are allocated from the malloc heap.
*
* When a string is treated as an object (by following it with . or []), the
* runtime wraps it with a JSObject whose valueOf method returns the unwrapped
* string header.
*/
#include <ctype.h>
#include "jspubtd.h"
#include "jsprvtd.h"
#include "jshash.h"
JS_BEGIN_EXTERN_C
struct JSString {
size_t length;
jschar *chars;
};
struct JSSubString {
size_t length;
const jschar *chars;
};
extern jschar js_empty_ucstr[];
extern JSSubString js_EmptySubString;
/* Unicode character attribute lookup tables. */
extern const uint8 js_X[];
extern const uint8 js_Y[];
extern const uint32 js_A[];
/* Enumerated Unicode general category types. */
typedef enum JSCharType {
JSCT_UNASSIGNED = 0,
JSCT_UPPERCASE_LETTER = 1,
JSCT_LOWERCASE_LETTER = 2,
JSCT_TITLECASE_LETTER = 3,
JSCT_MODIFIER_LETTER = 4,
JSCT_OTHER_LETTER = 5,
JSCT_NON_SPACING_MARK = 6,
JSCT_ENCLOSING_MARK = 7,
JSCT_COMBINING_SPACING_MARK = 8,
JSCT_DECIMAL_DIGIT_NUMBER = 9,
JSCT_LETTER_NUMBER = 10,
JSCT_OTHER_NUMBER = 11,
JSCT_SPACE_SEPARATOR = 12,
JSCT_LINE_SEPARATOR = 13,
JSCT_PARAGRAPH_SEPARATOR = 14,
JSCT_CONTROL = 15,
JSCT_FORMAT = 16,
JSCT_PRIVATE_USE = 18,
JSCT_SURROGATE = 19,
JSCT_DASH_PUNCTUATION = 20,
JSCT_START_PUNCTUATION = 21,
JSCT_END_PUNCTUATION = 22,
JSCT_CONNECTOR_PUNCTUATION = 23,
JSCT_OTHER_PUNCTUATION = 24,
JSCT_MATH_SYMBOL = 25,
JSCT_CURRENCY_SYMBOL = 26,
JSCT_MODIFIER_SYMBOL = 27,
JSCT_OTHER_SYMBOL = 28
} JSCharType;
/* Character classifying and mapping macros, based on java.lang.Character. */
#define JS_CCODE(c) (js_A[js_Y[(js_X[(uint16)(c)>>6]<<6)|((c)&0x3F)]])
#define JS_CTYPE(c) (JS_CCODE(c) & 0x1F)
#define JS_ISALPHA(c) ((((1 << JSCT_UPPERCASE_LETTER) | \
(1 << JSCT_LOWERCASE_LETTER) | \
(1 << JSCT_TITLECASE_LETTER) | \
(1 << JSCT_MODIFIER_LETTER) | \
(1 << JSCT_OTHER_LETTER)) \
>> JS_CTYPE(c)) & 1)
#define JS_ISALNUM(c) ((((1 << JSCT_UPPERCASE_LETTER) | \
(1 << JSCT_LOWERCASE_LETTER) | \
(1 << JSCT_TITLECASE_LETTER) | \
(1 << JSCT_MODIFIER_LETTER) | \
(1 << JSCT_OTHER_LETTER) | \
(1 << JSCT_DECIMAL_DIGIT_NUMBER)) \
>> JS_CTYPE(c)) & 1)
#define JS_ISWORD(c) (JS_ISALNUM(c) || (c) == '_')
/* XXXbe unify on A/X/Y tbls, avoid ctype.h? */
#define JS_ISIDENT(c) ((c) < 128 && (isalpha(c) || (c) == '_' || (c) == '$'))
#define JS_ISIDENT2(c) ((c) < 128 && (isalnum(c) || (c) == '_' || (c) == '$'))
#define JS_ISDIGIT(c) (JS_CTYPE(c) == JSCT_DECIMAL_DIGIT_NUMBER)
/* XXXbe fs, etc. ? */
#define JS_ISSPACE(c) ((JS_CCODE(c) & 0x00070000) == 0x00040000)
#define JS_ISPRINT(c) ((c) < 128 && isprint(c))
#define JS_ISUPPER(c) (JS_CTYPE(c) == JSCT_UPPERCASE_LETTER)
#define JS_ISLOWER(c) (JS_CTYPE(c) == JSCT_LOWERCASE_LETTER)
#ifdef __GNUC__
#define JS_TOUPPER(c) ({uint32 _v = JS_CCODE(c); \
(_v & 0x00100000) ? (c) - ((int32)_v >> 22) : (c);})
#define JS_TOLOWER(c) ({uint32 _v = JS_CCODE(c); \
(_v & 0x00200000) ? (c) + ((int32)_v >> 22) : (c);})
#else /* !__GNUC__ */
#define JS_TOUPPER(c) js_ToUpper((jschar)c)
#define JS_TOLOWER(c) js_ToLower((jschar)c)
extern jschar js_ToUpper(jschar c);
extern jschar js_ToLower(jschar c);
#endif /* !__GNUC__ */
#define JS_TOCTRL(c) ((c) ^ 64) /* XXX unsafe! requires uppercase c */
/* Shorthands for ASCII (7-bit) decimal and hex conversion. */
#define JS7_ISDEC(c) ((c) < 128 && isdigit(c))
#define JS7_UNDEC(c) ((c) - '0')
#define JS7_ISHEX(c) ((c) < 128 && isxdigit(c))
#define JS7_UNHEX(c) (uintN)(isdigit(c) ? (c) - '0' : 10 + tolower(c) - 'a')
#define JS7_ISLET(c) ((c) < 128 && isalpha(c))
/* Initialize truly global state associated with JS strings. */
extern JSBool
js_InitStringGlobals(void);
extern void
js_FreeStringGlobals(void);
/* Initialize the String class, returning its prototype object. */
extern JSObject *
js_InitStringClass(JSContext *cx, JSObject *obj);
/* GC-allocate a string descriptor for the given malloc-allocated chars. */
extern JSString *
js_NewString(JSContext *cx, jschar *chars, size_t length, uintN gcflag);
/* Copy a counted string and GC-allocate a descriptor for it. */
extern JSString *
js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n, uintN gcflag);
/* Copy a C string and GC-allocate a descriptor for it. */
extern JSString *
js_NewStringCopyZ(JSContext *cx, const jschar *s, uintN gcflag);
/* Free the chars held by str when it is finalized by the GC. */
extern void
js_FinalizeString(JSContext *cx, JSString *str);
/* Wrap a string value in a String object. */
extern JSObject *
js_StringToObject(JSContext *cx, JSString *str);
/*
* Convert a value to a string, returning null after reporting an error,
* otherwise returning a new string reference.
*/
extern JSString *
js_ValueToString(JSContext *cx, jsval v);
/*
* Convert a value to its source expression, returning null after reporting
* an error, otherwise returning a new string reference.
*/
extern JSString *
js_ValueToSource(JSContext *cx, jsval v);
#ifdef HT_ENUMERATE_NEXT /* XXX don't require jshash.h */
/*
* Compute a hash function from str.
*/
extern JSHashNumber
js_HashString(const JSString *str);
#endif
/*
* Return less than, equal to, or greater than zero depending on whether
* str1 is less than, equal to, or greater than str2.
*/
extern intN
js_CompareStrings(const JSString *str1, const JSString *str2);
/*
* Boyer-Moore-Horspool superlinear search for pat:patlen in text:textlen.
* The patlen argument must be positive and no greater than BMH_PATLEN_MAX.
* The start argument tells where in text to begin the search.
*
* Return the index of pat in text, or -1 if not found.
*/
#define BMH_CHARSET_SIZE 256 /* ISO-Latin-1 */
#define BMH_PATLEN_MAX 255 /* skip table element is uint8 */
#define BMH_BAD_PATTERN (-2) /* return value if pat is not ISO-Latin-1 */
extern jsint
js_BoyerMooreHorspool(const jschar *text, jsint textlen,
const jschar *pat, jsint patlen,
jsint start);
extern size_t
js_strlen(const jschar *s);
extern jschar *
js_strchr(const jschar *s, jschar c);
extern jschar *
js_strncpy(jschar *t, const jschar *s, size_t n);
/*
* Return s advanced past any Unicode white space characters.
*/
extern const jschar *
js_SkipWhiteSpace(const jschar *s);
/*
* Inflate bytes to JS chars and vice versa. Report out of memory via cx
* and return null on error, otherwise return the jschar or byte vector that
* was JS_malloc'ed.
*/
extern jschar *
js_InflateString(JSContext *cx, const char *bytes, size_t length);
extern char *
js_DeflateString(JSContext *cx, const jschar *chars, size_t length);
/*
* Associate bytes with str in the deflated string cache, returning true on
* successful association, false on out of memory.
*/
extern JSBool
js_SetStringBytes(JSString *str, char *bytes, size_t length);
/*
* Find or create a deflated string cache entry for str that contains its
* characters chopped from Unicode code points into bytes.
*/
extern char *
js_GetStringBytes(JSString *str);
JS_END_EXTERN_C
#endif /* jsstr_h___ */

371
mozilla/js/src/jstypes.h Normal file
View File

@@ -0,0 +1,371 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
** File: jstypes.h
** Description: Definitions of NSPR's basic types
**
** Prototypes and macros used to make up for deficiencies in ANSI environments
** that we have found.
**
** Since we do not wrap <stdlib.h> and all the other standard headers, authors
** of portable code will not know in general that they need these definitions.
** Instead of requiring these authors to find the dependent uses in their code
** and take the following steps only in those C files, we take steps once here
** for all C files.
**/
#ifndef jstypes_h___
#define jstypes_h___
#include <stddef.h>
/***********************************************************************
** MACROS: JS_EXTERN_API
** JS_EXPORT_API
** DESCRIPTION:
** These are only for externally visible routines and globals. For
** internal routines, just use "extern" for type checking and that
** will not export internal cross-file or forward-declared symbols.
** Define a macro for declaring procedures return types. We use this to
** deal with windoze specific type hackery for DLL definitions. Use
** JS_EXTERN_API when the prototype for the method is declared. Use
** JS_EXPORT_API for the implementation of the method.
**
** Example:
** in dowhim.h
** JS_EXTERN_API( void ) DoWhatIMean( void );
** in dowhim.c
** JS_EXPORT_API( void ) DoWhatIMean( void ) { return; }
**
**
***********************************************************************/
#ifdef WIN32
#define JS_EXTERN_API(__type) extern _declspec(dllexport) __type
#define JS_EXPORT_API(__type) _declspec(dllexport) __type
#define JS_EXTERN_DATA(__type) extern _declspec(dllexport) __type
#define JS_EXPORT_DATA(__type) _declspec(dllexport) __type
#define JS_DLL_CALLBACK
#define JS_STATIC_DLL_CALLBACK(__x) static __x
#elif defined(WIN16)
#ifdef _WINDLL
#define JS_EXTERN_API(__type) extern __type _cdecl _export _loadds
#define JS_EXPORT_API(__type) __type _cdecl _export _loadds
#define JS_EXTERN_DATA(__type) extern __type _export
#define JS_EXPORT_DATA(__type) __type _export
#define JS_DLL_CALLBACK __cdecl __loadds
#define JS_STATIC_DLL_CALLBACK(__x) static __x CALLBACK
#else /* this must be .EXE */
#define JS_EXTERN_API(__type) extern __type _cdecl _export
#define JS_EXPORT_API(__type) __type _cdecl _export
#define JS_EXTERN_DATA(__type) extern __type _export
#define JS_EXPORT_DATA(__type) __type _export
#define JS_DLL_CALLBACK __cdecl __loadds
#define JS_STATIC_DLL_CALLBACK(__x) __x JS_DLL_CALLBACK
#endif /* _WINDLL */
#elif defined(XP_MAC)
#define JS_EXTERN_API(__type) extern __declspec(export) __type
#define JS_EXPORT_API(__type) __declspec(export) __type
#define JS_EXTERN_DATA(__type) extern __declspec(export) __type
#define JS_EXPORT_DATA(__type) __declspec(export) __type
#define JS_DLL_CALLBACK
#define JS_STATIC_DLL_CALLBACK(__x) static __x
#elif defined(XP_OS2)
#define JS_EXTERN_API(__type) extern __type
#define JS_EXPORT_API(__type) __type
#define JS_EXTERN_DATA(__type) extern __type
#define JS_EXPORT_DATA(__type) __type
#define JS_DLL_CALLBACK
#define JS_STATIC_DLL_CALLBACK(__x) __x _Optlink
#else /* Unix */
#define JS_EXTERN_API(__type) extern __type
#define JS_EXPORT_API(__type) __type
#define JS_EXTERN_DATA(__type) extern __type
#define JS_EXPORT_DATA(__type) __type
#define JS_DLL_CALLBACK
#define JS_STATIC_DLL_CALLBACK(__x) static __x
#endif
#ifdef _WIN32
# define JS_IMPORT_API(__x) _declspec(dllimport) __x
#else
# define JS_IMPORT_API(__x) JS_EXPORT_API (__x)
#endif
#ifdef _WIN32
# define JS_IMPORT_DATA(__x) _declspec(dllimport) __x
#else
# define JS_IMPORT_DATA(__x) __x
#endif
/*
* The linkage of JS API functions differs depending on whether the file is
* used within the JS library or not. Any source file within the JS
* interpreter should define EXPORT_JS_API whereas any client of the library
* should not.
*/
#ifdef EXPORT_JS_API
#define JS_PUBLIC_API(t) JS_EXPORT_API(t)
#define JS_PUBLIC_DATA(t) JS_EXPORT_DATA(t)
#else
#define JS_PUBLIC_API(t) JS_IMPORT_API(t)
#define JS_PUBLIC_DATA(t) JS_IMPORT_DATA(t)
#endif
#define JS_FRIEND_API(t) JS_PUBLIC_API(t)
#define JS_FRIEND_DATA(t) JS_PUBLIC_DATA(t)
#ifdef _WIN32
# define JS_INLINE __inline
#elif defined(__GNUC__)
# define JS_INLINE
#else
# define JS_INLINE
#endif
/***********************************************************************
** MACROS: JS_BEGIN_MACRO
** JS_END_MACRO
** DESCRIPTION:
** Macro body brackets so that macros with compound statement definitions
** behave syntactically more like functions when called.
***********************************************************************/
#define JS_BEGIN_MACRO do {
#define JS_END_MACRO } while (0)
/***********************************************************************
** MACROS: JS_BEGIN_EXTERN_C
** JS_END_EXTERN_C
** DESCRIPTION:
** Macro shorthands for conditional C++ extern block delimiters.
***********************************************************************/
#ifdef __cplusplus
#define JS_BEGIN_EXTERN_C extern "C" {
#define JS_END_EXTERN_C }
#else
#define JS_BEGIN_EXTERN_C
#define JS_END_EXTERN_C
#endif
/***********************************************************************
** MACROS: JS_BIT
** JS_BITMASK
** DESCRIPTION:
** Bit masking macros. XXX n must be <= 31 to be portable
***********************************************************************/
#define JS_BIT(n) ((JSUint32)1 << (n))
#define JS_BITMASK(n) (JS_BIT(n) - 1)
/***********************************************************************
** MACROS: JS_ROUNDUP
** JS_MIN
** JS_MAX
** DESCRIPTION:
** Commonly used macros for operations on compatible types.
***********************************************************************/
#define JS_ROUNDUP(x,y) ((((x)+((y)-1))/(y))*(y))
#define JS_MIN(x,y) ((x)<(y)?(x):(y))
#define JS_MAX(x,y) ((x)>(y)?(x):(y))
#if defined(XP_MAC) || defined(XP_PC)
# include "jscpucfg.h" /* Use standard Mac or Windows configuration */
#elif XP_UNIX
# include "jsautocfg.h" /* Use auto-detected configuration */
#else
# error "Must define one of XP_PC, XP_MAC or XP_UNIX"
#endif
JS_BEGIN_EXTERN_C
/************************************************************************
** TYPES: JSUint8
** JSInt8
** DESCRIPTION:
** The int8 types are known to be 8 bits each. There is no type that
** is equivalent to a plain "char".
************************************************************************/
#if JS_BYTES_PER_BYTE == 1
typedef unsigned char JSUint8;
typedef signed char JSInt8;
#else
#error No suitable type for JSInt8/JSUint8
#endif
/************************************************************************
** TYPES: JSUint16
** JSInt16
** DESCRIPTION:
** The int16 types are known to be 16 bits each.
************************************************************************/
#if JS_BYTES_PER_SHORT == 2
typedef unsigned short JSUint16;
typedef short JSInt16;
#else
#error No suitable type for JSInt16/JSUint16
#endif
/************************************************************************
** TYPES: JSUint32
** JSInt32
** DESCRIPTION:
** The int32 types are known to be 32 bits each.
************************************************************************/
#if JS_BYTES_PER_INT == 4
typedef unsigned int JSUint32;
typedef int JSInt32;
#define JS_INT32(x) x
#define JS_UINT32(x) x ## U
#elif JS_BYTES_PER_LONG == 4
typedef unsigned long JSUint32;
typedef long JSInt32;
#define JS_INT32(x) x ## L
#define JS_UINT32(x) x ## UL
#else
#error No suitable type for JSInt32/JSUint32
#endif
/************************************************************************
** TYPES: JSUint64
** JSInt64
** DESCRIPTION:
** The int64 types are known to be 64 bits each. Care must be used when
** declaring variables of type JSUint64 or JSInt64. Different hardware
** architectures and even different compilers have varying support for
** 64 bit values. The only guaranteed portability requires the use of
** the JSLL_ macros (see jslong.h).
************************************************************************/
#ifdef JS_HAVE_LONG_LONG
#if JS_BYTES_PER_LONG == 8
typedef long JSInt64;
typedef unsigned long JSUint64;
#elif defined(WIN16)
typedef __int64 JSInt64;
typedef unsigned __int64 JSUint64;
#elif defined(WIN32)
typedef __int64 JSInt64;
typedef unsigned __int64 JSUint64;
#else
typedef long long JSInt64;
typedef unsigned long long JSUint64;
#endif /* JS_BYTES_PER_LONG == 8 */
#else /* !JS_HAVE_LONG_LONG */
typedef struct {
#ifdef IS_LITTLE_ENDIAN
JSUint32 lo, hi;
#else
JSUint32 hi, lo;
#endif
} JSInt64;
typedef JSInt64 JSUint64;
#endif /* !JS_HAVE_LONG_LONG */
/************************************************************************
** TYPES: JSUintn
** JSIntn
** DESCRIPTION:
** The JSIntn types are most appropriate for automatic variables. They are
** guaranteed to be at least 16 bits, though various architectures may
** define them to be wider (e.g., 32 or even 64 bits). These types are
** never valid for fields of a structure.
************************************************************************/
#if JS_BYTES_PER_INT >= 2
typedef int JSIntn;
typedef unsigned int JSUintn;
#else
#error 'sizeof(int)' not sufficient for platform use
#endif
/************************************************************************
** TYPES: JSFloat64
** DESCRIPTION:
** NSPR's floating point type is always 64 bits.
************************************************************************/
typedef double JSFloat64;
/************************************************************************
** TYPES: JSSize
** DESCRIPTION:
** A type for representing the size of objects.
************************************************************************/
typedef size_t JSSize;
/************************************************************************
** TYPES: JSPtrDiff
** DESCRIPTION:
** A type for pointer difference. Variables of this type are suitable
** for storing a pointer or pointer sutraction.
************************************************************************/
typedef ptrdiff_t JSPtrdiff;
/************************************************************************
** TYPES: JSUptrdiff
** DESCRIPTION:
** A type for pointer difference. Variables of this type are suitable
** for storing a pointer or pointer sutraction.
************************************************************************/
typedef unsigned long JSUptrdiff;
/************************************************************************
** TYPES: JSBool
** DESCRIPTION:
** Use JSBool for variables and parameter types. Use JS_FALSE and JS_TRUE
** for clarity of target type in assignments and actual arguments. Use
** 'if (bool)', 'while (!bool)', '(bool) ? x : y' etc., to test booleans
** juast as you would C int-valued conditions.
************************************************************************/
typedef JSIntn JSBool;
#define JS_TRUE (JSIntn)1
#define JS_FALSE (JSIntn)0
/************************************************************************
** TYPES: JSPackedBool
** DESCRIPTION:
** Use PRPackedBOol within structs where bitfields are not desireable
** but minimum and consistant overhead matters.
************************************************************************/
typedef JSUint8 JSPackedBool;
/*
** Status code used by some routines that have a single point of failure or
** special status return.
*/
typedef enum { JS_FAILURE = -1, JS_SUCCESS = 0 } JSStatus;
/*
** A JSWord is an integer that is the same size as a void*
*/
typedef long JSWord;
typedef unsigned long JSUword;
#include "jsotypes.h"
JS_END_EXTERN_C
#endif /* jstypes_h___ */

132
mozilla/js/src/jsutil.c Normal file
View File

@@ -0,0 +1,132 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* PR assertion checker.
*/
#include <stdio.h>
#include <stdlib.h>
#include "jstypes.h"
#include "jsutil.h"
#ifdef WIN32
# include <windows.h>
#endif
#ifdef XP_MAC
# include <Types.h>
# include <stdarg.h>
# include "jsprf.h"
#endif
#ifdef XP_MAC
/*
* PStrFromCStr converts the source C string to a destination
* pascal string as it copies. The dest string will
* be truncated to fit into an Str255 if necessary.
* If the C String pointer is NULL, the pascal string's length is
* set to zero.
*/
static void PStrFromCStr(const char* src, Str255 dst)
{
short length = 0;
/* handle case of overlapping strings */
if ( (void*)src == (void*)dst )
{
unsigned char* curdst = &dst[1];
unsigned char thisChar;
thisChar = *(const unsigned char*)src++;
while ( thisChar != '\0' )
{
unsigned char nextChar;
/*
* Use nextChar so we don't overwrite what we
* are about to read
*/
nextChar = *(const unsigned char*)src++;
*curdst++ = thisChar;
thisChar = nextChar;
if ( ++length >= 255 )
break;
}
}
else if ( src != NULL )
{
unsigned char* curdst = &dst[1];
/* count down so test it loop is faster */
short overflow = 255;
register char temp;
/*
* Can't do the K&R C thing of while (*s++ = *t++)
* because it will copy trailing zero which might
* overrun pascal buffer. Instead we use a temp variable.
*/
while ( (temp = *src++) != 0 )
{
*(char*)curdst++ = temp;
if ( --overflow <= 0 )
break;
}
length = 255 - overflow;
}
dst[0] = length;
}
static void debugstr(const char *debuggerMsg)
{
Str255 pStr;
PStrFromCStr(debuggerMsg, pStr);
DebugStr(pStr);
}
static void dprintf(const char *format, ...)
{
va_list ap;
char *buffer;
va_start(ap, format);
buffer = (char *)JS_vsmprintf(format, ap);
va_end(ap);
debugstr(buffer);
JS_DELETE(buffer);
}
#endif /* XP_MAC */
JS_EXPORT_API(void) JS_Assert(const char *s, const char *file, JSIntn ln)
{
#if defined(XP_UNIX) || defined(XP_OS2)
fprintf(stderr, "Assertion failure: %s, at %s:%d\n", s, file, ln);
#endif
#ifdef XP_MAC
dprintf("Assertion failure: %s, at %s:%d\n", s, file, ln);
#endif
#ifdef WIN32
DebugBreak();
#endif
#ifndef XP_MAC
abort();
#endif
}

84
mozilla/js/src/jsutil.h Normal file
View File

@@ -0,0 +1,84 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* PR assertion checker.
*/
#ifndef jsutil_h___
#define jsutil_h___
JS_BEGIN_EXTERN_C
/***********************************************************************
** FUNCTION: JS_MALLOC()
** DESCRIPTION:
** JS_NEW() allocates an untyped item of size _size from the heap.
** INPUTS: _size: size in bytes of item to be allocated
** OUTPUTS: untyped pointer to the node allocated
** RETURN: pointer to node or error returned from malloc().
***********************************************************************/
#define JS_MALLOC(_bytes) (malloc((_bytes)))
/***********************************************************************
** FUNCTION: JS_DELETE()
** DESCRIPTION:
** JS_DELETE() unallocates an object previosly allocated via JS_NEW()
** or JS_NEWZAP() to the heap.
** INPUTS: pointer to previously allocated object
** OUTPUTS: the referenced object is returned to the heap
** RETURN: void
***********************************************************************/
#define JS_DELETE(_ptr) { free(_ptr); (_ptr) = NULL; }
/***********************************************************************
** FUNCTION: JS_NEW()
** DESCRIPTION:
** JS_NEW() allocates an item of type _struct from the heap.
** INPUTS: _struct: a data type
** OUTPUTS: pointer to _struct
** RETURN: pointer to _struct or error returns from malloc().
***********************************************************************/
#define JS_NEW(_struct) ((_struct *) JS_MALLOC(sizeof(_struct)))
#ifdef DEBUG
JS_EXTERN_API(void) JS_Assert(const char *s, const char *file, JSIntn ln);
#define JS_ASSERT(_expr) \
((_expr)?((void)0):JS_Assert(# _expr,__FILE__,__LINE__))
#define JS_NOT_REACHED(_reasonStr) \
JS_Assert(_reasonStr,__FILE__,__LINE__)
#else
#define JS_ASSERT(expr) ((void) 0)
#define JS_NOT_REACHED(reasonStr)
#endif /* defined(DEBUG) */
/*
** Abort the process in a non-graceful manner. This will cause a core file,
** call to the debugger or other moral equivalent as well as causing the
** entire process to stop.
*/
JS_EXTERN_API(void) JS_Abort(void);
JS_END_EXTERN_C
#endif /* jsutil_h___ */

559
mozilla/js/src/jsxdrapi.c Normal file
View File

@@ -0,0 +1,559 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "jsstddef.h"
#include <string.h>
#include "jstypes.h"
#include "jsutil.h" /* Added by JSIFY */
#include "jsprf.h"
#include "jsapi.h"
#include "jscntxt.h"
#include "jsobj.h" /* js_XDRObject */
#include "jsstr.h"
#include "jsxdrapi.h"
#ifdef DEBUG
#define DBG(x) x
#else
#define DBG(x) ((void)0)
#endif
typedef struct JSXDRMemState {
JSXDRState state;
uint32 count;
uint32 limit;
} JSXDRMemState;
#define MEM_BLOCK 8192
#define MEM_PRIV(xdr) ((JSXDRMemState *)(xdr))
#define MEM_COUNT(xdr) (MEM_PRIV(xdr)->count)
#define MEM_LIMIT(xdr) (MEM_PRIV(xdr)->limit)
#define MEM_LEFT(xdr, bytes) \
JS_BEGIN_MACRO \
if ((xdr)->mode == JSXDR_DECODE && \
MEM_COUNT(xdr) + bytes > MEM_LIMIT(xdr)) { \
JS_ReportErrorNumber((xdr)->cx, js_GetErrorMessage, NULL, \
JSMSG_END_OF_DATA); \
return 0; \
} \
JS_END_MACRO
/* XXXbe why does NEED even allow or cope with non-ENCODE mode? */
#define MEM_NEED(xdr, bytes) \
JS_BEGIN_MACRO \
if ((xdr)->mode == JSXDR_ENCODE) { \
if (MEM_LIMIT(xdr) && \
MEM_COUNT(xdr) + bytes > MEM_LIMIT(xdr)) { \
void *_data = JS_realloc((xdr)->cx, \
(xdr)->data, \
MEM_LIMIT(xdr) + MEM_BLOCK); \
if (!_data) \
return 0; \
(xdr)->data = _data; \
MEM_LIMIT(xdr) += MEM_BLOCK; \
} \
} else { \
if (MEM_LIMIT(xdr) < MEM_COUNT(xdr) + bytes) { \
JS_ReportErrorNumber((xdr)->cx, js_GetErrorMessage, NULL, \
JSMSG_END_OF_DATA); \
return 0; \
} \
} \
JS_END_MACRO
#define MEM_DATA(xdr) ((void *)((char *)(xdr)->data + MEM_COUNT(xdr)))
#define MEM_INCR(xdr,bytes) (MEM_COUNT(xdr) += (bytes))
static JSBool
mem_get32(JSXDRState *xdr, uint32 *lp)
{
MEM_LEFT(xdr, 4);
*lp = *(uint32 *)MEM_DATA(xdr);
MEM_INCR(xdr, 4);
return JS_TRUE;
}
static JSBool
mem_set32(JSXDRState *xdr, uint32 *lp)
{
MEM_NEED(xdr, 4);
*(uint32 *)MEM_DATA(xdr) = *lp;
MEM_INCR(xdr, 4);
return JS_TRUE;
}
static JSBool
mem_getbytes(JSXDRState *xdr, char **bytesp, uint32 len)
{
MEM_LEFT(xdr, len);
memcpy(*bytesp, MEM_DATA(xdr), len);
MEM_INCR(xdr, len);
return JS_TRUE;
}
static JSBool
mem_setbytes(JSXDRState *xdr, char **bytesp, uint32 len)
{
MEM_NEED(xdr, len);
memcpy(MEM_DATA(xdr), *bytesp, len);
MEM_INCR(xdr, len);
return JS_TRUE;
}
static void *
mem_raw(JSXDRState *xdr, uint32 len)
{
void *data;
if (xdr->mode == JSXDR_ENCODE) {
MEM_NEED(xdr, len);
} else if (xdr->mode == JSXDR_DECODE) {
MEM_LEFT(xdr, len);
}
data = MEM_DATA(xdr);
MEM_INCR(xdr, len);
return data;
}
static JSBool
mem_seek(JSXDRState *xdr, int32 offset, JSXDRWhence whence)
{
switch (whence) {
case JSXDR_SEEK_CUR:
if ((int32)MEM_COUNT(xdr) + offset < 0) {
JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
JSMSG_SEEK_BEYOND_START);
return JS_FALSE;
}
if (offset > 0)
MEM_NEED(xdr, offset);
MEM_COUNT(xdr) += offset;
return JS_TRUE;
case JSXDR_SEEK_SET:
if (offset < 0) {
JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
JSMSG_SEEK_BEYOND_START);
return JS_FALSE;
}
if (xdr->mode == JSXDR_ENCODE) {
if ((uint32)offset > MEM_COUNT(xdr))
MEM_NEED(xdr, offset - MEM_COUNT(xdr));
MEM_COUNT(xdr) = offset;
} else {
if ((uint32)offset > MEM_LIMIT(xdr)) {
JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
JSMSG_SEEK_BEYOND_END);
return JS_FALSE;
}
MEM_COUNT(xdr) = offset;
}
return JS_TRUE;
case JSXDR_SEEK_END:
if (offset >= 0 ||
xdr->mode == JSXDR_ENCODE ||
(int32)MEM_LIMIT(xdr) + offset < 0) {
JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
JSMSG_END_SEEK);
return JS_FALSE;
}
MEM_COUNT(xdr) = MEM_LIMIT(xdr) + offset;
return JS_TRUE;
default: {
char numBuf[12];
JS_snprintf(numBuf, sizeof numBuf, "%d", whence);
JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
JSMSG_WHITHER_WHENCE, numBuf);
return JS_FALSE;
}
}
}
static uint32
mem_tell(JSXDRState *xdr)
{
return MEM_COUNT(xdr);
}
static void
mem_finalize(JSXDRState *xdr)
{
JSContext *cx = xdr->cx;
JS_free(cx, xdr->data);
}
static JSXDROps xdrmem_ops = {
mem_get32, mem_set32, mem_getbytes, mem_setbytes,
mem_raw, mem_seek, mem_tell, mem_finalize
};
JS_PUBLIC_API(void)
JS_XDRNewBase(JSContext *cx, JSXDRState *xdr, JSXDRMode mode)
{
xdr->cx = cx;
xdr->mode = mode;
xdr->registry = NULL;
xdr->nclasses = 0;
}
JS_PUBLIC_API(JSXDRState *)
JS_XDRNewMem(JSContext *cx, JSXDRMode mode)
{
JSXDRState *xdr = JS_malloc(cx, sizeof(JSXDRMemState));
if (!xdr)
return NULL;
JS_XDRNewBase(cx, xdr, mode);
if (mode == JSXDR_ENCODE) {
if (!(xdr->data = JS_malloc(cx, MEM_BLOCK))) {
JS_free(cx, xdr);
return NULL;
}
} else {
/* XXXbe ok, so better not deref xdr->data if not ENCODE */
xdr->data = NULL;
}
xdr->ops = &xdrmem_ops;
MEM_PRIV(xdr)->count = 0;
MEM_PRIV(xdr)->limit = MEM_BLOCK;
return xdr;
}
JS_PUBLIC_API(void *)
JS_XDRMemGetData(JSXDRState *xdr, uint32 *lp)
{
if (xdr->ops != &xdrmem_ops)
return NULL;
*lp = MEM_PRIV(xdr)->count;
return xdr->data;
}
JS_PUBLIC_API(void)
JS_XDRMemSetData(JSXDRState *xdr, void *data, uint32 len)
{
if (xdr->ops != &xdrmem_ops)
return;
MEM_PRIV(xdr)->limit = len;
xdr->data = data;
MEM_PRIV(xdr)->count = 0;
}
JS_PUBLIC_API(JSBool)
JS_XDRUint8(JSXDRState *xdr, uint8 *b)
{
uint32 l = *b;
if (!JS_XDRUint32(xdr, &l))
return JS_FALSE;
*b = (uint8) l & 0xff;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_XDRUint16(JSXDRState *xdr, uint16 *s)
{
uint32 l = *s;
if (!JS_XDRUint32(xdr, &l))
return JS_FALSE;
*s = (uint16) l & 0xffff;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_XDRUint32(JSXDRState *xdr, uint32 *lp)
{
JSBool ok = JS_FALSE;
if (xdr->mode == JSXDR_ENCODE) {
uint32 xl = JSXDR_SWAB32(*lp);
ok = xdr->ops->set32(xdr, &xl);
} else if (xdr->mode == JSXDR_DECODE) {
ok = xdr->ops->get32(xdr, lp);
*lp = JSXDR_SWAB32(*lp);
}
return ok;
}
JS_PUBLIC_API(JSBool)
JS_XDRBytes(JSXDRState *xdr, char **bytesp, uint32 len)
{
if (xdr->mode == JSXDR_ENCODE) {
if (!xdr->ops->setbytes(xdr, bytesp, len))
return JS_FALSE;
} else {
if (!xdr->ops->getbytes(xdr, bytesp, len))
return JS_FALSE;
}
len = xdr->ops->tell(xdr);
if (len % JSXDR_ALIGN) {
if (!xdr->ops->seek(xdr, JSXDR_ALIGN - (len % JSXDR_ALIGN),
JSXDR_SEEK_CUR)) {
return JS_FALSE;
}
}
return JS_TRUE;
}
/**
* Convert between a C string and the XDR representation:
* leading 32-bit count, then counted vector of chars,
* then possibly \0 padding to multiple of 4.
*/
JS_PUBLIC_API(JSBool)
JS_XDRCString(JSXDRState *xdr, char **sp)
{
uint32 len;
if (xdr->mode == JSXDR_ENCODE)
len = strlen(*sp);
JS_XDRUint32(xdr, &len);
if (xdr->mode == JSXDR_DECODE) {
if (!(*sp = JS_malloc(xdr->cx, len + 1)))
return JS_FALSE;
}
if (!JS_XDRBytes(xdr, sp, len)) {
if (xdr->mode == JSXDR_DECODE)
JS_free(xdr->cx, *sp);
return JS_FALSE;
}
if (xdr->mode == JSXDR_DECODE) {
(*sp)[len] = '\0';
} else if (xdr->mode == JSXDR_FREE) {
JS_free(xdr->cx, *sp);
*sp = NULL;
}
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_XDRCStringOrNull(JSXDRState *xdr, char **sp)
{
uint32 null = (*sp == NULL);
if (!JS_XDRUint32(xdr, &null))
return JS_FALSE;
if (null) {
*sp = NULL;
return JS_TRUE;
}
return JS_XDRCString(xdr, sp);
}
/*
* Convert between a JS (Unicode) string and the XDR representation.
*/
JS_PUBLIC_API(JSBool)
JS_XDRString(JSXDRState *xdr, JSString **strp)
{
uint32 i, len, nbytes;
jschar *chars = NULL, *raw;
if (xdr->mode == JSXDR_ENCODE)
len = (*strp)->length;
if (!JS_XDRUint32(xdr, &len))
return JS_FALSE;
nbytes = len * sizeof(jschar);
if (xdr->mode == JSXDR_ENCODE) {
chars = (*strp)->chars;
} else if (xdr->mode == JSXDR_DECODE) {
if (!(chars = JS_malloc(xdr->cx, nbytes + sizeof(jschar))))
return JS_FALSE;
}
if (nbytes % JSXDR_ALIGN)
nbytes += JSXDR_ALIGN - (nbytes % JSXDR_ALIGN);
if (!(raw = xdr->ops->raw(xdr, nbytes)))
goto bad;
if (xdr->mode == JSXDR_ENCODE) {
for (i = 0; i < len; i++)
raw[i] = JSXDR_SWAB16(chars[i]);
} else if (xdr->mode == JSXDR_DECODE) {
for (i = 0; i < len; i++)
chars[i] = JSXDR_SWAB16(raw[i]);
if (!(*strp = JS_NewUCString(xdr->cx, chars, len)))
goto bad;
}
return JS_TRUE;
bad:
if (xdr->mode == JSXDR_DECODE)
JS_free(xdr->cx, chars);
return JS_FALSE;
}
JS_PUBLIC_API(JSBool)
JS_XDRStringOrNull(JSXDRState *xdr, JSString **strp)
{
uint32 null = (*strp == NULL);
if (!JS_XDRUint32(xdr, &null))
return JS_FALSE;
if (null) {
*strp = NULL;
return JS_TRUE;
}
return JS_XDRString(xdr, strp);
}
JS_PUBLIC_API(JSBool)
JS_XDRDouble(JSXDRState *xdr, jsdouble **dp)
{
jsdouble d;
if (xdr->mode == JSXDR_ENCODE)
d = **dp;
#if IS_BIG_ENDIAN
if (!JS_XDRUint32(xdr, (uint32 *)&d + 1) ||
!JS_XDRUint32(xdr, (uint32 *)&d))
#else /* !IS_BIG_ENDIAN */
if (!JS_XDRUint32(xdr, (uint32 *)&d) ||
!JS_XDRUint32(xdr, (uint32 *)&d + 1))
#endif /* IS_BIG_ENDIAN */
return JS_FALSE;
if (xdr->mode == JSXDR_DECODE) {
*dp = JS_NewDouble(xdr->cx, d);
if (!*dp)
return JS_FALSE;
}
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_XDRValue(JSXDRState *xdr, jsval *vp)
{
uint32 type = JSVAL_TAG(*vp);
if (!JS_XDRUint32(xdr, &type))
return JS_FALSE;
switch (type) {
case JSVAL_STRING: {
JSString *str = JSVAL_TO_STRING(*vp);
if (!JS_XDRString(xdr, &str))
return JS_FALSE;
if (xdr->mode == JSXDR_DECODE)
*vp = STRING_TO_JSVAL(str);
break;
}
case JSVAL_DOUBLE: {
jsdouble *dp;
if (xdr->mode == JSXDR_ENCODE)
dp = JSVAL_TO_DOUBLE(*vp);
if (!JS_XDRDouble(xdr, &dp))
return JS_FALSE;
if (xdr->mode == JSXDR_DECODE)
*vp = DOUBLE_TO_JSVAL(dp);
break;
}
case JSVAL_OBJECT: {
JSObject *obj;
if (xdr->mode == JSXDR_ENCODE)
obj = JSVAL_TO_OBJECT(*vp);
if (!js_XDRObject(xdr, &obj))
return JS_FALSE;
if (xdr->mode == JSXDR_DECODE)
*vp = OBJECT_TO_JSVAL(obj);
break;
}
case JSVAL_BOOLEAN: {
uint32 b;
if (xdr->mode == JSXDR_ENCODE)
b = (uint32)JSVAL_TO_BOOLEAN(*vp);
if (!JS_XDRUint32(xdr, &b))
return JS_FALSE;
if (xdr->mode == JSXDR_DECODE)
*vp = BOOLEAN_TO_JSVAL((JSBool)b);
break;
}
case JSVAL_VOID:
if (!JS_XDRUint32(xdr, (uint32 *)vp))
return JS_FALSE;
break;
default: {
char numBuf[12];
if (type & JSVAL_INT) {
uint32 i;
if (xdr->mode == JSXDR_ENCODE)
i = JSVAL_TO_INT(*vp);
if (!JS_XDRUint32(xdr, &i))
return JS_FALSE;
if (xdr->mode == JSXDR_DECODE)
*vp = INT_TO_JSVAL(i);
break;
}
JS_snprintf(numBuf, sizeof numBuf, "%#lx", type);
JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
JSMSG_BAD_JVAL_TYPE, type);
return JS_FALSE;
}
}
return JS_TRUE;
}
JS_PUBLIC_API(void)
JS_XDRDestroy(JSXDRState *xdr)
{
JSContext *cx = xdr->cx;
xdr->ops->finalize(xdr);
if (xdr->registry)
JS_free(cx, xdr->registry);
JS_free(cx, xdr);
}
#define REGISTRY_CHUNK 4
JS_PUBLIC_API(JSBool)
JS_RegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *idp)
{
uintN nclasses;
JSClass **registry;
nclasses = xdr->nclasses;
if (nclasses == 0) {
registry = JS_malloc(xdr->cx, REGISTRY_CHUNK * sizeof(JSClass *));
} else if (nclasses % REGISTRY_CHUNK == 0) {
registry = JS_realloc(xdr->cx,
xdr->registry,
(nclasses + REGISTRY_CHUNK) * sizeof(JSClass *));
} else {
registry = xdr->registry;
}
if (!registry)
return JS_FALSE;
registry[nclasses++] = clasp;
xdr->registry = registry;
xdr->nclasses = nclasses;
*idp = nclasses;
return JS_TRUE;
}
JS_PUBLIC_API(uint32)
JS_FindClassIdByName(JSXDRState *xdr, const char *name)
{
uintN i;
for (i = 0; i < xdr->nclasses; i++) {
if (!strcmp(name, xdr->registry[i]->name))
return i+1;
}
return 0;
}
JS_PUBLIC_API(JSClass *)
JS_FindClassById(JSXDRState *xdr, uint32 id)
{
if (id > xdr->nclasses)
return NULL;
return xdr->registry[id-1];
}

158
mozilla/js/src/jsxdrapi.h Normal file
View File

@@ -0,0 +1,158 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef jsxdrapi_h___
#define jsxdrapi_h___
/*
* JS external data representation interface API.
*
* The XDR system is comprised of three major parts:
*
* - the state serialization/deserialization APIs, which allow consumers
* of the API to serialize JS runtime state (script bytecodes, atom maps,
* object graphs, etc.) for later restoration. These portions
* are implemented in various appropriate files, such as jsscript.c
* for the script portions and jsobj.c for object state.
* - the callback APIs through which the runtime requests an opaque
* representation of a native object, and through which the runtime
* constructs a live native object from an opaque representation. These
* portions are the responsibility of the native object implementor.
* - utility functions for en/decoding of primitive types, such as
* JSStrings. This portion is implemented in jsxdrapi.c.
*
* Spiritually guided by Sun's XDR, where appropriate.
*/
#include "jspubtd.h"
#include "jsprvtd.h"
JS_BEGIN_EXTERN_C
/* We use little-endian byteorder for all encoded data */
#if defined IS_LITTLE_ENDIAN
#define JSXDR_SWAB32(x) x
#define JSXDR_SWAB16(x) x
#elif defined IS_BIG_ENDIAN
#define JSXDR_SWAB32(x) (((x) >> 24) | \
(((x) >> 8) & 0xff00) | \
(((x) << 8) & 0xff0000) | \
((x) << 24))
#define JSXDR_SWAB16(x) (((x) >> 8) | ((x) << 8))
#else
#error "unknown byte order"
#endif
#define JSXDR_ALIGN 4
typedef enum JSXDRMode {
JSXDR_ENCODE,
JSXDR_DECODE,
JSXDR_FREE
} JSXDRMode;
typedef enum JSXDRWhence {
JSXDR_SEEK_SET,
JSXDR_SEEK_CUR,
JSXDR_SEEK_END
} JSXDRWhence;
typedef struct JSXDROps {
JSBool (*get32)(JSXDRState *, uint32 *);
JSBool (*set32)(JSXDRState *, uint32 *);
JSBool (*getbytes)(JSXDRState *, char **, uint32);
JSBool (*setbytes)(JSXDRState *, char **, uint32);
void * (*raw)(JSXDRState *, uint32);
JSBool (*seek)(JSXDRState *, int32, JSXDRWhence);
uint32 (*tell)(JSXDRState *);
void (*finalize)(JSXDRState *);
} JSXDROps;
struct JSXDRState {
JSXDRMode mode;
JSXDROps *ops;
JSContext *cx;
JSClass **registry;
uintN nclasses;
void *data;
};
JS_PUBLIC_API(void)
JS_XDRNewBase(JSContext *cx, JSXDRState *xdr, JSXDRMode mode);
JS_PUBLIC_API(JSXDRState *)
JS_XDRNewMem(JSContext *cx, JSXDRMode mode);
JS_PUBLIC_API(void *)
JS_XDRMemGetData(JSXDRState *xdr, uint32 *lp);
JS_PUBLIC_API(void)
JS_XDRMemSetData(JSXDRState *xdr, void *data, uint32 len);
JS_PUBLIC_API(void)
JS_XDRDestroy(JSXDRState *xdr);
JS_PUBLIC_API(JSBool)
JS_XDRUint8(JSXDRState *xdr, uint8 *b);
JS_PUBLIC_API(JSBool)
JS_XDRUint16(JSXDRState *xdr, uint16 *s);
JS_PUBLIC_API(JSBool)
JS_XDRUint32(JSXDRState *xdr, uint32 *lp);
JS_PUBLIC_API(JSBool)
JS_XDRBytes(JSXDRState *xdr, char **bytes, uint32 len);
JS_PUBLIC_API(JSBool)
JS_XDRCString(JSXDRState *xdr, char **sp);
JS_PUBLIC_API(JSBool)
JS_XDRCStringOrNull(JSXDRState *xdr, char **sp);
JS_PUBLIC_API(JSBool)
JS_XDRString(JSXDRState *xdr, JSString **strp);
JS_PUBLIC_API(JSBool)
JS_XDRStringOrNull(JSXDRState *xdr, JSString **strp);
JS_PUBLIC_API(JSBool)
JS_XDRDouble(JSXDRState *xdr, jsdouble **dp);
JS_PUBLIC_API(JSBool)
JS_XDRValue(JSXDRState *xdr, jsval *vp);
JS_PUBLIC_API(JSBool)
JS_RegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *lp);
JS_PUBLIC_API(uint32)
JS_FindClassIdByName(JSXDRState *xdr, const char *name);
JS_PUBLIC_API(JSClass *)
JS_FindClassById(JSXDRState *xdr, uint32 id);
/* Magic values */
#define OBJ_XDRMAGIC 0xdead1000
#define OBJ_XDRTYPE_OBJ 0xdead1001
#define OBJ_XDRTYPE_FUN 0xdead1002
#define OBJ_XDRTYPE_REGEXP 0xdead1003
#define SCRIPT_XDRMAGIC 0xdead0001
#endif /* ! jsxdrapi_h___ */

View File

@@ -0,0 +1,79 @@
!
! atomic compare-and-swap routines for V8 sparc
! and for V8+ (ultrasparc)
!
!
! standard asm linkage macros; this module must be compiled
! with the -P option (use C preprocessor)
#include <sys/asm_linkage.h>
! ======================================================================
!
! Perform the sequence *a = b atomically with respect to previous value
! of a (a0). If *a==a0 then assign *a to b, all in one atomic operation.
! Returns 1 if assignment happened, and 0 otherwise.
!
! usage : old_val = compare_and_swap(address, oldval, newval)
!
! -----------------------
! Note on REGISTER USAGE:
! as this is a LEAF procedure, a new stack frame is not created;
! we use the caller stack frame so what would normally be %i (input)
! registers are actually %o (output registers). Also, we must not
! overwrite the contents of %l (local) registers as they are not
! assumed to be volatile during calls.
!
! So, the registers used are:
! %o0 [input] - the address of the value to increment
! %o1 [input] - the old value to compare with
! %o2 [input] - the new value to set for [%o0]
! %o3 [local] - work register
! -----------------------
#ifndef ULTRA_SPARC
! v8
ENTRY(compare_and_swap) ! standard assembler/ELF prologue
mov -1,%o3 ! busy flag
swap [%o0],%o3 ! get current value
l1: cmp %o3,-1 ! busy?
be,a l1 ! if so, spin
swap [%o0],%o3 ! using branch-delay to swap back value
cmp %o1,%o3 ! compare old with current
be,a l2 ! if equal then swap in new value
swap [%o0],%o2 ! done.
swap [%o0],%o3 ! otherwise, swap back current value
retl
mov 0,%o0 ! return false
l2: retl
mov 1,%o0 ! return true
SET_SIZE(compare_and_swap) ! standard assembler/ELF epilogue
!
! end
!
#else /* ULTRA_SPARC */
! ======================================================================
!
! v9
ENTRY(compare_and_swap) ! standard assembler/ELF prologue
cas [%o0],%o1,%o2 ! compare *w with old value and set to new if equal
cmp %o1,%o2 ! did we succeed?
be,a m1 ! yes
mov 1,%o0 ! return true (annulled when no jump)
mov 0,%o0 ! return false
m1: retl
nop
SET_SIZE(compare_and_swap) ! standard assembler/ELF epilogue
!
! end
!
! ======================================================================
!
#endif

196
mozilla/js/src/makefile.win Normal file
View File

@@ -0,0 +1,196 @@
#// The contents of this file are subject to the Netscape Public License
#// Version 1.0 (the "NPL"); you may not use this file except in
#// compliance with the NPL. You may obtain a copy of the NPL at
#// http://www.mozilla.org/NPL/
#//
#// Software distributed under the NPL is distributed on an "AS IS" basis,
#// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
#// for the specific language governing rights and limitations under the
#// NPL.
#//
#// The Initial Developer of this code under the NPL is Netscape
#// Communications Corporation. Portions created by Netscape are
#// Copyright (C) 1998 Netscape Communications Corporation. All Rights
#// Reserved.
#//------------------------------------------------------------------------
#//
#// Specify the depth of the current directory relative to the
#// root of NS
#//
#//------------------------------------------------------------------------
DEPTH=..\..
include <$(DEPTH)\config\config.mak>
!ifdef MOZ_OJI
DIRS = liveconnect
!endif
DIRS = $(DIRS) fdlibm
#//------------------------------------------------------------------------
#//
#// Define any Public Make Variables here: (ie. PDFFILE, MAPFILE, ...)
#//
#//------------------------------------------------------------------------
DLLNAME = js$(MOZ_BITS)$(VERSION_NUMBER)
DLL1NAME = js1$(MOZ_BITS)$(VERSION_NUMBER)
PDBFILE = $(DLLNAME).pdb
MAPFILE = $(DLLNAME).map
RESFILE = js$(MOZ_BITS)40.res
DLL =.\$(OBJDIR)\$(DLLNAME).dll
MAKE_OBJ_TYPE = DLL
!if "$(MOZ_BITS)" != "16"
LINCS = -I$(PUBLIC)\layout \
-I$(DEPTH)\include \
-I$(PUBLIC)\liblayer
!endif
!if "$(MOZ_BITS)" == "16"
!ifdef NSPR20
DEFFILE = $(DLL1NAME).def
!else
DEFFILE = $(DLLNAME).def
!endif
!endif
FDLIBM_LIBRARY = fdlibm\$(OBJDIR)\fdlibm.lib
LLIBS=$(LIBNSPR) $(FDLIBM_LIBRARY)
LCFLAGS= $(LCFLAGS) -DEXPORT_JS_API
!if "$(MOZ_BITS)"=="32" && defined(MOZ_DEBUG) && defined(GLOWCODE)
LLIBS=$(LLIBS) $(GLOWDIR)\glowcode.lib
!endif
#//------------------------------------------------------------------------
#//
#// Define the files necessary to build the target (ie. OBJS)
#//
#//------------------------------------------------------------------------
OBJS = \
.\$(OBJDIR)\jsapi.obj \
.\$(OBJDIR)\jsarena.obj \
.\$(OBJDIR)\jsarray.obj \
.\$(OBJDIR)\jsatom.obj \
.\$(OBJDIR)\jsbool.obj \
.\$(OBJDIR)\jscntxt.obj \
.\$(OBJDIR)\jsdate.obj \
.\$(OBJDIR)\jsdbgapi.obj \
.\$(OBJDIR)\jsdtoa.obj \
.\$(OBJDIR)\jsemit.obj \
.\$(OBJDIR)\jsexn.obj \
.\$(OBJDIR)\jsfun.obj \
.\$(OBJDIR)\jsgc.obj \
.\$(OBJDIR)\jshash.obj \
.\$(OBJDIR)\jsinterp.obj \
.\$(OBJDIR)\jslock.obj \
.\$(OBJDIR)\jslog2.obj \
.\$(OBJDIR)\jslong.obj \
.\$(OBJDIR)\jsmath.obj \
.\$(OBJDIR)\jsnum.obj \
.\$(OBJDIR)\jsobj.obj \
.\$(OBJDIR)\jsopcode.obj \
.\$(OBJDIR)\jsparse.obj \
.\$(OBJDIR)\jsprf.obj \
.\$(OBJDIR)\jsregexp.obj \
.\$(OBJDIR)\jsscan.obj \
.\$(OBJDIR)\jsscope.obj \
.\$(OBJDIR)\jsscript.obj \
.\$(OBJDIR)\jsstr.obj \
.\$(OBJDIR)\jsutil.obj \
.\$(OBJDIR)\jsxdrapi.obj \
.\$(OBJDIR)\prmjtime.obj \
$(NULL)
#//------------------------------------------------------------------------
#//
#// install headers
#//
#//------------------------------------------------------------------------
INSTALL_DIR=$(PUBLIC)\js
INSTALL_FILE_LIST= \
js.msg \
jsapi.h \
jsarray.h \
jsarena.h \
jsatom.h \
jsbit.h \
jsbool.h \
jsclist.h \
jscntxt.h \
jscompat.h \
jsconfig.h \
jscpucfg.h \
jsdate.h \
jsdbgapi.h \
jsemit.h \
jsfun.h \
jsgc.h \
jshash.h \
jsinterp.h \
jslock.h \
jslong.h \
jsmath.h \
jsnum.h \
jsobj.h \
jsopcode.tbl \
jsopcode.h \
jsosdep.h \
jsotypes.h \
jsparse.h \
jsprf.h \
jsprvtd.h \
jspubtd.h \
jsregexp.h \
jsscan.h \
jsscope.h \
jsscript.h \
jsstr.h \
jstypes.h \
jsutil.h \
jsxdrapi.h \
$(NULL)
#//------------------------------------------------------------------------
#//
#// Include the common makefile rules
#//
#//------------------------------------------------------------------------
include <$(DEPTH)\config\rules.mak>
.\$(OBJDIR)\jsmath.obj: $(FDLIBM_LIBRARY)
#// Ripped from mozilla/config/rule.mak $(DIRS):: rule
$(FDLIBM_LIBRARY):
!if "$(WINOS)" == "WIN95"
!if defined(VERBOSE)
@echo +++ make: cannot recursively make on win95 using command.com, use w95make.
!endif
!else
@echo +++ make: %MAKE_ARGS% in $(MAKEDIR)\$@
@cd fdlibm
@$(NMAKE) -f makefile.win %%MAKE_ARGS%%
@cd $(MAKEDIR)
!endif
export:: $(DLL) INSTALL_FILES
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).dll $(DIST)\bin
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).lib $(DIST)\lib
#//------------------------------------------------------------------------
#//
#// Standalone js.exe interpreter
#//
#//------------------------------------------------------------------------
#//PROGRAM = $(OBJDIR)\js.exe
#//js: $(PROGRAM)
#//
#//$(PROGRAM): $(OBJDIR)\js.obj $(LIBRARY)
#// @$(MAKE_OBJDIR)
#// $(link) /debug /out:$(PROGRAM) $(OBJDIR)\js.obj $(DIST)\lib\pr3240.lib $(LIBRARY) $(LDFLAGS)
#//
#//$(OBJDIR)\js.obj: js.c
#// $(CC) /Fo$(OBJDIR)\js.obj js.c $(CFLAGS) -DJSFILE

39
mozilla/js/src/perfect.js Normal file
View File

@@ -0,0 +1,39 @@
// Some simple testing of new, eval and some string stuff.
// constructor -- expression array initialization
function ExprArray(n,v)
{
// Initializes n values to v coerced to a string.
for (var i = 0; i < n; i++) {
this[i] = "" + v;
}
}
// Print the perfect numbers up to n and the sum expression for n's divisors.
function perfect(n)
{
print("The perfect numbers up to " + n + " are:");
// We build sumOfDivisors[i] to hold a string expression for
// the sum of the divisors of i, excluding i itself.
var sumOfDivisors = new ExprArray(n+1,1);
for (var divisor = 2; divisor <= n; divisor++) {
for (var j = divisor + divisor; j <= n; j += divisor) {
sumOfDivisors[j] += " + " + divisor;
}
// At this point everything up to 'divisor' has its sumOfDivisors
// expression calculated, so we can determine whether it's perfect
// already by evaluating.
if (eval(sumOfDivisors[divisor]) == divisor) {
print("" + divisor + " = " + sumOfDivisors[divisor]);
}
}
print("That's all.");
}
print("\nA number is 'perfect' if it is equal to the sum of its")
print("divisors (excluding itself).\n");
perfect(500);

565
mozilla/js/src/prmjtime.c Normal file
View File

@@ -0,0 +1,565 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* PR time code.
*/
#ifdef SOLARIS
#define _REENTRANT 1
#endif
#include <string.h>
#include <time.h>
#include "jstypes.h"
#include "jsprf.h"
#include "prmjtime.h"
#define PRMJ_DO_MILLISECONDS 1
#ifdef XP_PC
#include <sys/timeb.h>
#endif
#ifdef XP_MAC
#include <OSUtils.h>
#include <TextUtils.h>
#include <Resources.h>
#include <Timer.h>
#endif
#ifdef XP_UNIX
#ifdef _SVID_GETTOD /* Defined only on Solaris, see Solaris <sys/types.h> */
extern int gettimeofday(struct timeval *tv);
#endif
#include <sys/time.h>
#endif /* XP_UNIX */
#ifdef XP_MAC
static UnsignedWide dstLocalBaseMicroseconds;
static unsigned long gJanuaryFirst1970Seconds;
static void MacintoshInitializeTime(void)
{
UnsignedWide upTime;
unsigned long currentLocalTimeSeconds,
startupTimeSeconds;
uint64 startupTimeMicroSeconds;
uint32 upTimeSeconds;
uint64 oneMillion, upTimeSecondsLong, microSecondsToSeconds;
DateTimeRec firstSecondOfUnixTime;
// Figure out in local time what time the machine
// started up. This information can be added to
// upTime to figure out the current local time
// as well as GMT.
Microseconds(&upTime);
GetDateTime(&currentLocalTimeSeconds);
JSLL_I2L(microSecondsToSeconds, PRMJ_USEC_PER_SEC);
JSLL_DIV(upTimeSecondsLong, *((uint64 *)&upTime), microSecondsToSeconds);
JSLL_L2I(upTimeSeconds, upTimeSecondsLong);
startupTimeSeconds = currentLocalTimeSeconds - upTimeSeconds;
// Make sure that we normalize the macintosh base seconds
// to the unix base of January 1, 1970.
firstSecondOfUnixTime.year = 1970;
firstSecondOfUnixTime.month = 1;
firstSecondOfUnixTime.day = 1;
firstSecondOfUnixTime.hour = 0;
firstSecondOfUnixTime.minute = 0;
firstSecondOfUnixTime.second = 0;
firstSecondOfUnixTime.dayOfWeek = 0;
DateToSeconds(&firstSecondOfUnixTime, &gJanuaryFirst1970Seconds);
startupTimeSeconds -= gJanuaryFirst1970Seconds;
// Now convert the startup time into a wide so that we
// can figure out GMT and DST.
JSLL_I2L(startupTimeMicroSeconds, startupTimeSeconds);
JSLL_I2L(oneMillion, PRMJ_USEC_PER_SEC);
JSLL_MUL(dstLocalBaseMicroseconds, oneMillion, startupTimeMicroSeconds);
}
// Because serial port and SLIP conflict with ReadXPram calls,
// we cache the call here
static void MyReadLocation(MachineLocation * loc)
{
static MachineLocation storedLoc; // InsideMac, OSUtilities, page 4-20
static JSBool didReadLocation = JS_FALSE;
if (!didReadLocation)
{
MacintoshInitializeTime();
ReadLocation(&storedLoc);
didReadLocation = JS_TRUE;
}
*loc = storedLoc;
}
#endif /* XP_MAC */
#define IS_LEAP(year) \
(year != 0 && ((((year & 0x3) == 0) && \
((year - ((year/100) * 100)) != 0)) || \
(year - ((year/400) * 400)) == 0))
#define PRMJ_HOUR_SECONDS 3600L
#define PRMJ_DAY_SECONDS (24L * PRMJ_HOUR_SECONDS)
#define PRMJ_YEAR_SECONDS (PRMJ_DAY_SECONDS * 365L)
#define PRMJ_MAX_UNIX_TIMET 2145859200L /*time_t value equiv. to 12/31/2037 */
/* function prototypes */
static void PRMJ_basetime(JSInt64 tsecs, PRMJTime *prtm);
/*
* get the difference in seconds between this time zone and UTC (GMT)
*/
time_t
PRMJ_LocalGMTDifference()
{
#if defined(XP_UNIX) || defined(XP_PC)
struct tm ltime;
/* get the difference between this time zone and GMT */
memset((char *)&ltime,0,sizeof(ltime));
ltime.tm_mday = 2;
ltime.tm_year = 70;
#ifdef SUNOS4
ltime.tm_zone = 0;
ltime.tm_gmtoff = 0;
return timelocal(&ltime) - (24 * 3600);
#else
return mktime(&ltime) - (24L * 3600L);
#endif
#endif
#if defined(XP_MAC)
static time_t zone = -1L;
MachineLocation machineLocation;
JSUint64 gmtOffsetSeconds;
JSUint64 gmtDelta;
JSUint64 dlsOffset;
JSInt32 offset;
/* difference has been set no need to recalculate */
if(zone != -1)
return zone;
/* Get the information about the local machine, including
* its GMT offset and its daylight savings time info.
* Convert each into wides that we can add to
* startupTimeMicroSeconds.
*/
MyReadLocation(&machineLocation);
/* Mask off top eight bits of gmtDelta, sign extend lower three. */
if ((machineLocation.u.gmtDelta & 0x00800000) != 0) {
gmtOffsetSeconds.lo = (machineLocation.u.gmtDelta & 0x00FFFFFF) | 0xFF000000;
gmtOffsetSeconds.hi = 0xFFFFFFFF;
JSLL_UI2L(gmtDelta,0);
} else {
gmtOffsetSeconds.lo = (machineLocation.u.gmtDelta & 0x00FFFFFF);
gmtOffsetSeconds.hi = 0;
JSLL_UI2L(gmtDelta,PRMJ_DAY_SECONDS);
}
/*
* Normalize time to be positive if you are behind GMT. gmtDelta will
* always be positive.
*/
JSLL_SUB(gmtDelta,gmtDelta,gmtOffsetSeconds);
/* Is Daylight Savings On? If so, we need to add an hour to the offset. */
if (machineLocation.u.dlsDelta != 0) {
JSLL_UI2L(dlsOffset, PRMJ_HOUR_SECONDS);
} else {
JSLL_I2L(dlsOffset, 0);
}
JSLL_ADD(gmtDelta,gmtDelta, dlsOffset);
JSLL_L2I(offset,gmtDelta);
zone = offset;
return (time_t)offset;
#endif
}
/* Constants for GMT offset from 1970 */
#define G1970GMTMICROHI 0x00dcdcad /* micro secs to 1970 hi */
#define G1970GMTMICROLOW 0x8b3fa000 /* micro secs to 1970 low */
#define G2037GMTMICROHI 0x00e45fab /* micro secs to 2037 high */
#define G2037GMTMICROLOW 0x7a238000 /* micro secs to 2037 low */
/* Convert from base time to extended time */
static JSInt64
PRMJ_ToExtendedTime(JSInt32 time)
{
JSInt64 exttime;
JSInt64 g1970GMTMicroSeconds;
JSInt64 low;
time_t diff;
JSInt64 tmp;
JSInt64 tmp1;
diff = PRMJ_LocalGMTDifference();
JSLL_UI2L(tmp, PRMJ_USEC_PER_SEC);
JSLL_I2L(tmp1,diff);
JSLL_MUL(tmp,tmp,tmp1);
JSLL_UI2L(g1970GMTMicroSeconds,G1970GMTMICROHI);
JSLL_UI2L(low,G1970GMTMICROLOW);
#ifndef JS_HAVE_LONG_LONG
JSLL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,16);
JSLL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,16);
#else
JSLL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,32);
#endif
JSLL_ADD(g1970GMTMicroSeconds,g1970GMTMicroSeconds,low);
JSLL_I2L(exttime,time);
JSLL_ADD(exttime,exttime,g1970GMTMicroSeconds);
JSLL_SUB(exttime,exttime,tmp);
return exttime;
}
JSInt64
PRMJ_Now(void)
{
#ifdef XP_PC
JSInt64 s, us, ms2us, s2us;
struct timeb b;
#endif /* XP_PC */
#ifdef XP_UNIX
struct timeval tv;
JSInt64 s, us, s2us;
#endif /* XP_UNIX */
#ifdef XP_MAC
UnsignedWide upTime;
JSInt64 localTime;
JSInt64 gmtOffset;
JSInt64 dstOffset;
time_t gmtDiff;
JSInt64 s2us;
#endif /* XP_MAC */
#ifdef XP_PC
ftime(&b);
JSLL_UI2L(ms2us, PRMJ_USEC_PER_MSEC);
JSLL_UI2L(s2us, PRMJ_USEC_PER_SEC);
JSLL_UI2L(s, b.time);
JSLL_UI2L(us, b.millitm);
JSLL_MUL(us, us, ms2us);
JSLL_MUL(s, s, s2us);
JSLL_ADD(s, s, us);
return s;
#endif
#ifdef XP_UNIX
#ifdef _SVID_GETTOD /* Defined only on Solaris, see Solaris <sys/types.h> */
gettimeofday(&tv);
#else
gettimeofday(&tv, 0);
#endif /* _SVID_GETTOD */
JSLL_UI2L(s2us, PRMJ_USEC_PER_SEC);
JSLL_UI2L(s, tv.tv_sec);
JSLL_UI2L(us, tv.tv_usec);
JSLL_MUL(s, s, s2us);
JSLL_ADD(s, s, us);
return s;
#endif /* XP_UNIX */
#ifdef XP_MAC
JSLL_UI2L(localTime,0);
gmtDiff = PRMJ_LocalGMTDifference();
JSLL_I2L(gmtOffset,gmtDiff);
JSLL_UI2L(s2us, PRMJ_USEC_PER_SEC);
JSLL_MUL(gmtOffset,gmtOffset,s2us);
JSLL_UI2L(dstOffset,0);
dstOffset = PRMJ_DSTOffset(dstOffset);
JSLL_SUB(gmtOffset,gmtOffset,dstOffset);
/* don't adjust for DST since it sets ctime and gmtime off on the MAC */
Microseconds(&upTime);
JSLL_ADD(localTime,localTime,gmtOffset);
JSLL_ADD(localTime,localTime, *((JSUint64 *)&dstLocalBaseMicroseconds));
JSLL_ADD(localTime,localTime, *((JSUint64 *)&upTime));
return *((JSUint64 *)&localTime);
#endif /* XP_MAC */
}
/* Get the DST timezone offset for the time passed in */
JSInt64
PRMJ_DSTOffset(JSInt64 time)
{
JSInt64 us2s;
#ifdef XP_MAC
MachineLocation machineLocation;
JSInt64 dlsOffset;
/* Get the information about the local machine, including
* its GMT offset and its daylight savings time info.
* Convert each into wides that we can add to
* startupTimeMicroSeconds.
*/
MyReadLocation(&machineLocation);
/* Is Daylight Savings On? If so, we need to add an hour to the offset. */
if (machineLocation.u.dlsDelta != 0) {
JSLL_UI2L(us2s, PRMJ_USEC_PER_SEC); /* seconds in a microseconds */
JSLL_UI2L(dlsOffset, PRMJ_HOUR_SECONDS); /* seconds in one hour */
JSLL_MUL(dlsOffset, dlsOffset, us2s);
} else {
JSLL_I2L(dlsOffset, 0);
}
return(dlsOffset);
#else
time_t local;
JSInt32 diff;
JSInt64 maxtimet;
struct tm tm;
PRMJTime prtm;
#if defined( XP_PC ) || defined( FREEBSD ) || defined ( HPUX9 ) || defined ( SNI ) || defined ( NETBSD ) || defined ( OPENBSD ) || defined( RHAPSODY )
struct tm *ptm;
#endif
JSLL_UI2L(us2s, PRMJ_USEC_PER_SEC);
JSLL_DIV(time, time, us2s);
/* get the maximum of time_t value */
JSLL_UI2L(maxtimet,PRMJ_MAX_UNIX_TIMET);
if(JSLL_CMP(time,>,maxtimet)){
JSLL_UI2L(time,PRMJ_MAX_UNIX_TIMET);
} else if(!JSLL_GE_ZERO(time)){
/*go ahead a day to make localtime work (does not work with 0) */
JSLL_UI2L(time,PRMJ_DAY_SECONDS);
}
JSLL_L2UI(local,time);
PRMJ_basetime(time,&prtm);
#if defined( XP_PC ) || defined( FREEBSD ) || defined ( HPUX9 ) || defined ( SNI ) || defined ( NETBSD ) || defined ( OPENBSD ) || defined( RHAPSODY )
ptm = localtime(&local);
if(!ptm){
return JSLL_ZERO;
}
tm = *ptm;
#else
localtime_r(&local,&tm); /* get dst information */
#endif
diff = ((tm.tm_hour - prtm.tm_hour) * PRMJ_HOUR_SECONDS) +
((tm.tm_min - prtm.tm_min) * 60);
if(diff < 0){
diff += PRMJ_DAY_SECONDS;
}
JSLL_UI2L(time,diff);
JSLL_MUL(time,time,us2s);
return(time);
#endif
}
/* Format a time value into a buffer. Same semantics as strftime() */
size_t
PRMJ_FormatTime(char *buf, int buflen, char *fmt, PRMJTime *prtm)
{
#if defined(XP_UNIX) || defined(XP_PC) || defined(XP_MAC)
struct tm a;
/* Zero out the tm struct. Linux, SunOS 4 struct tm has extra members int
* tm_gmtoff, char *tm_zone; when tm_zone is garbage, strftime gets
* confused and dumps core. NSPR20 prtime.c attempts to fill these in by
* calling mktime on the partially filled struct, but this doesn't seem to
* work as well; the result string has "can't get timezone" for ECMA-valid
* years. Might still make sense to use this, but find the range of years
* for which valid tz information exists, and map (per ECMA hint) from the
* given year into that range.
* N.B. This hasn't been tested with anything that actually _uses_
* tm_gmtoff; zero might be the wrong thing to set it to if you really need
* to format a time. This fix is for jsdate.c, which only uses
* JS_FormatTime to get a string representing the time zone. */
memset(&a, 0, sizeof(struct tm));
a.tm_sec = prtm->tm_sec;
a.tm_min = prtm->tm_min;
a.tm_hour = prtm->tm_hour;
a.tm_mday = prtm->tm_mday;
a.tm_mon = prtm->tm_mon;
a.tm_wday = prtm->tm_wday;
a.tm_year = prtm->tm_year - 1900;
a.tm_yday = prtm->tm_yday;
a.tm_isdst = prtm->tm_isdst;
/* Even with the above, SunOS 4 seems to detonate if tm_zone and tm_gmtoff
* are null. This doesn't quite work, though - the timezone is off by
* tzoff + dst. (And mktime seems to return -1 for the exact dst
* changeover time.)
* Still not sure if MKLINUX is necessary; this is borrowed from the NSPR20
* prtime.c. I'm leaving it out - My Linux does the right thing without it
* (and the wrong thing with it) even though it has the tm_gmtoff, tm_zone
* fields. Linux seems to be happy so long as the tm struct is zeroed out.
* The #ifdef in nspr is:
* #if defined(SUNOS4) || defined(MKLINUX) || defined (__GLIBC >= 2)
*/
#if defined(SUNOS4)
if (mktime(&a) == -1) {
/* Seems to fail whenever the requested date is outside of the 32-bit
* UNIX epoch. We could proceed at this point (setting a.tm_zone to
* "") but then strftime returns a string with a 2-digit field of
* garbage for the year. So we return 0 and hope jsdate.c
* will fall back on toString.
*/
return 0;
}
#endif
return strftime(buf, buflen, fmt, &a);
#endif
}
/* table for number of days in a month */
static int mtab[] = {
/* jan, feb,mar,apr,may,jun */
31,28,31,30,31,30,
/* july,aug,sep,oct,nov,dec */
31,31,30,31,30,31
};
/*
* basic time calculation functionality for localtime and gmtime
* setups up prtm argument with correct values based upon input number
* of seconds.
*/
static void
PRMJ_basetime(JSInt64 tsecs, PRMJTime *prtm)
{
/* convert tsecs back to year,month,day,hour,secs */
JSInt32 year = 0;
JSInt32 month = 0;
JSInt32 yday = 0;
JSInt32 mday = 0;
JSInt32 wday = 6; /* start on a Sunday */
JSInt32 days = 0;
JSInt32 seconds = 0;
JSInt32 minutes = 0;
JSInt32 hours = 0;
JSInt32 isleap = 0;
JSInt64 result;
JSInt64 result1;
JSInt64 result2;
JSInt64 base;
JSLL_UI2L(result,0);
JSLL_UI2L(result1,0);
JSLL_UI2L(result2,0);
/* get the base time via UTC */
base = PRMJ_ToExtendedTime(0);
JSLL_UI2L(result, PRMJ_USEC_PER_SEC);
JSLL_DIV(base,base,result);
JSLL_ADD(tsecs,tsecs,base);
JSLL_UI2L(result, PRMJ_YEAR_SECONDS);
JSLL_UI2L(result1,PRMJ_DAY_SECONDS);
JSLL_ADD(result2,result,result1);
/* get the year */
while ((isleap == 0) ? !JSLL_CMP(tsecs,<,result) : !JSLL_CMP(tsecs,<,result2)) {
/* subtract a year from tsecs */
JSLL_SUB(tsecs,tsecs,result);
days += 365;
/* is it a leap year ? */
if(IS_LEAP(year)){
JSLL_SUB(tsecs,tsecs,result1);
days++;
}
year++;
isleap = IS_LEAP(year);
}
JSLL_UI2L(result1,PRMJ_DAY_SECONDS);
JSLL_DIV(result,tsecs,result1);
JSLL_L2I(mday,result);
/* let's find the month */
while(((month == 1 && isleap) ?
(mday >= mtab[month] + 1) :
(mday >= mtab[month]))){
yday += mtab[month];
days += mtab[month];
mday -= mtab[month];
/* it's a Feb, check if this is a leap year */
if(month == 1 && isleap != 0){
yday++;
days++;
mday--;
}
month++;
}
/* now adjust tsecs */
JSLL_MUL(result,result,result1);
JSLL_SUB(tsecs,tsecs,result);
mday++; /* day of month always start with 1 */
days += mday;
wday = (days + wday) % 7;
yday += mday;
/* get the hours */
JSLL_UI2L(result1,PRMJ_HOUR_SECONDS);
JSLL_DIV(result,tsecs,result1);
JSLL_L2I(hours,result);
JSLL_MUL(result,result,result1);
JSLL_SUB(tsecs,tsecs,result);
/* get minutes */
JSLL_UI2L(result1,60);
JSLL_DIV(result,tsecs,result1);
JSLL_L2I(minutes,result);
JSLL_MUL(result,result,result1);
JSLL_SUB(tsecs,tsecs,result);
JSLL_L2I(seconds,tsecs);
prtm->tm_usec = 0L;
prtm->tm_sec = (JSInt8)seconds;
prtm->tm_min = (JSInt8)minutes;
prtm->tm_hour = (JSInt8)hours;
prtm->tm_mday = (JSInt8)mday;
prtm->tm_mon = (JSInt8)month;
prtm->tm_wday = (JSInt8)wday;
prtm->tm_year = (JSInt16)year;
prtm->tm_yday = (JSInt16)yday;
}

Some files were not shown because too many files have changed in this diff Show More