Compare commits

..

92 Commits

Author SHA1 Message Date
shaver%netscape.com
cf6db2abdd fix CHECK_BRANCH fencepost
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@31697 18797224-902f-48f8-a5cc-f745e15eee43
1999-05-14 23:54:16 +00:00
rogerl%netscape.com
e973ce2e64 Removed unused reops.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@31277 18797224-902f-48f8-a5cc-f745e15eee43
1999-05-12 18:29:58 +00:00
shaver%netscape.com
a7c924107a use OBJ_THIS_OBJECT in SPROP_[GS]ET to make with(native_obj)'' work correctly
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@31080 18797224-902f-48f8-a5cc-f745e15eee43
1999-05-11 15:47:07 +00:00
rogerl%netscape.com
dd04b345a9 Added Perl5 forward assertions. Removed remaining bytecode cruft.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@28462 18797224-902f-48f8-a5cc-f745e15eee43
1999-04-21 16:34:48 +00:00
jband%netscape.com
196840e43e js_DefaultValue now accepts that it is OK for a request with hint of JSTYPE_OBJECT to result in an object of type JSTYPE_FUNCTION. This is done so that objects that happen to have 'call' ops will not fail when being 'converted' to 'Object'. This Fix is going onto the trunk, SpiderMonkeyDev_BRANCH, and SpiderMonkey140_BRANCH
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@26104 18797224-902f-48f8-a5cc-f745e15eee43
1999-04-02 23:17:14 +00:00
rogerl%netscape.com
f6cc728f7c Switch to experimental new regexp interpreter, hope it doens't hurt too bad
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@25943 18797224-902f-48f8-a5cc-f745e15eee43
1999-04-01 23:38:27 +00:00
norris%netscape.com
b176dfdf14 Fix 4386 crash when using the keyword super
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@25708 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-31 19:01:11 +00:00
norris%netscape.com
306aeb02c4 merge change from 140 branch
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@25707 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-31 18:57:23 +00:00
bjorn%netscape.com
0689998baf Fix for case when js_SuspendThread and js_ResumeThread return before
restoring busy flag.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@25233 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-26 21:52:37 +00:00
wynholds%netscape.com
f82e1076b8 fixing optimized problem and using new linker executable. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@25107 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-25 16:29:23 +00:00
mccabe%netscape.com
36f1b44c5a Removed support for the JSFILE define. Not to be confused with the
'jsfile' js file object, the JSFINE define conditionally compiled
support for allowing the javascript scanner to read from filehandles.
We've decided that it's more annoying to support not supporting that
feature, so we enable it all of the time.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@25060 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-25 04:07:39 +00:00
norris%netscape.com
a01beb172e Fixes for 345701.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@25017 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-25 00:46:55 +00:00
wynholds%netscape.com
87244f2387 some compiler flags for HP. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@24907 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-23 23:03:30 +00:00
norris%netscape.com
bb1700203f Fix 'out of memory' errors running the tests on some systems.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@24856 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-23 19:02:39 +00:00
fur%netscape.com
04f1117a20 Fix for Bugzilla #1282: Don't attempt to mark JS roots that contain scalars
rather than references to GC-able objects.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@24850 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-23 17:27:27 +00:00
mccabe%netscape.com
d7c8c29308 Fix to bugzilla bug 4088; fixed javascript Date string parsing to
handle 12:30 AM and 12:30 PM properly.

(Previously, the code just added 12 hours whenever it saw PM.)


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@24779 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-23 02:48:01 +00:00
mccabe%netscape.com
75045483df Fixed broken C apis js_DateGetYear, etc. to deal correctly with invalid dates. (They previously returned (int) <the date value> which gave MIN_INT for invalid (NaN) dates - a departure from the previous behavior of returning 0.)
Added js_DateIsValid api to detect invalid dates.

Also checked into the SpiderMonkey140_BRANCH for server builds.  (They detected the problem.)


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@24363 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-18 23:12:54 +00:00
wynholds%netscape.com
eb4284dfe3 two updates brought over from the 1.4 branch:
1) now building and packaging the LC jar file
2) now building NT debug with and without msvcrtd.dll
-mw


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@24349 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-18 22:18:21 +00:00
norris%netscape.com
5f08e5453f Fix bug 3521 Communicator4.5 crash --- JavaScript memory leak?
(which also would affect 5.x)


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@24299 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-18 18:05:38 +00:00
rogerl%netscape.com
297a92fed5 Bug fix #344855, needed to convert enumeration to string object on forelem2
path as well.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@24172 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-15 19:09:46 +00:00
rogerl%netscape.com
430ba8a25f When allowing find_split to bump-along past the end of the string, return
-1 as the result (except for 1.2 compatibility). This handles :

"hi".split(new RegExp())

which should return a 2 entry array

["h", "i"]

but had been returning an empty third entry because find_split wanted to
allow it's caller the opportunity to handle end-of-string conditions.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@23714 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-11 19:45:03 +00:00
wynholds%netscape.com
d4c9e5196e NSPR 3.1beta -> 3.1 -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@23648 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-11 01:46:20 +00:00
shaver%netscape.com
92181cdedc quell printf format warnings
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@23531 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-10 18:46:30 +00:00
norris%netscape.com
d42fcb5d9a Fix 337324 Can't read parameter through eval if no actual argument pass
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@23483 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-10 04:07:41 +00:00
brendan%netscape.com
a75043737c Avoid dangling else (egcs warns about it) and else-after-return; other nits.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@22546 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-02 08:05:20 +00:00
brendan%netscape.com
ad5a6cbd9c - Added 'W' format to JS_ConvertArguments, for conversion to string and return
via a jschar* out parameter.
- Fused common string conversion and argv[i] GC-rooting code in JS_ConvertArgs.
- Added to cvtargs test command, which really needs to stop using a hardwired
  format string!
- Fixed char-typed fgetc-receiving variable to be of int type for correct EOF
  comparison on machines with unsigned chars.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@22509 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-02 02:38:45 +00:00
wynholds%netscape.com
b73c93ce31 merging in changes from JS 1.4 -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@21802 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-24 23:50:21 +00:00
norris%netscape.com
74ac28f85b Make sure output parameter is always set before return.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@21775 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-24 18:26:19 +00:00
norris%netscape.com
3d5bbbd416 Fix bug found by Jane Ha in ES:
The separator in String.prototype.split would be modified as a result of
performing the split under version 1.2:

js> version(120)
js> x = " "

js> "abc def".split(x)
abc,def
js> x

js> x.length
0
The problem was that find_split was modifying the separator that was passed
in, and the fix is to use a local for the separator rather than a reference
to the actual separator.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@21763 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-24 17:35:30 +00:00
jband%netscape.com
a659fad23a changed MAP_IS_NATIVE to allow for objects that have their own jsObjectOps but still use the slots in the 'normal' manner
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@21125 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-18 04:56:49 +00:00
fur%netscape.com
0534335359 Don't create PDB file when linking
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@21043 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-17 23:28:23 +00:00
rogerl%netscape.com
d9d9f76b42 Added 'm' flag for RegExp.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@21035 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-17 23:01:41 +00:00
mccabe%netscape.com
2ce568f036 Freed leaked file->path pointer.
Thanks to Greg Scallan for catching this.

From: Greg Scallan <spider@netscape.com>
Subject: Memory Leak

Hey All,

    Not sure if you're aware of this, but (I believe) there is a memory
leak at line  2735 in jsfile.c on the trunk.  file->path is being
assigned via a strdup, when it was already assigned as a result of
calling file_init() several lines above it.  The possible fix is to
essentially check if file->path has a value and if so, to free that
value using JS_free.

fyi,
Greg


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@21034 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-17 22:55:09 +00:00
brendan%netscape.com
2feaadaafd QuoteString must escape backslash (duh; thanks to mccabe).
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@21029 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-17 22:36:49 +00:00
wynholds%netscape.com
4142a81ec0 adding support for IRIX 6.5 -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@20856 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-17 02:23:41 +00:00
wynholds%netscape.com
4eba0d77e0 merging in make changes from SpiderMonkey140_BRANCH to name libraries correctly and package the right stuff. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@20639 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-13 02:45:52 +00:00
rogerl%netscape.com
347f0232ad Fixed bug in *? for flat1 - was picking up wrong character from pc.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@20622 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-12 22:23:48 +00:00
wynholds%netscape.com
2fd0ae6b14 not including libnspr anymore -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@20450 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-11 23:08:33 +00:00
shaver%netscape.com
87f42c5a2a fix leaking of object lock count during XDR function decode
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@20111 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-09 05:08:40 +00:00
mccabe%netscape.com
692d4446f3 Removed trailing nul characters that got appended with the checkin of many
months ago.  Just cleaning up...


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@19961 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-07 09:19:06 +00:00
wynholds%netscape.com
ff9e7d1ae5 fixed for Linux 2.1 and 2.2 -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@19459 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-03 17:06:28 +00:00
wynholds%netscape.com
6faae76e7e fix Linux NSPR component directory name problem. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@19452 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-03 16:52:36 +00:00
wynholds%netscape.com
472ac2feab NSPR_VERSION 19980120 -> v3.0 -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@19365 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-02 20:08:16 +00:00
brendan%netscape.com
e295e36d9e - Fix egregious bug: missing 0 terminator at end of js_EscapeMap.
- Fix QuoteString so it doesn't stop on an embedded \u0000 in its input string.
- Add some comments to QuoteString.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@18975 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-29 01:52:35 +00:00
rogerl%netscape.com
bf8d9a56ec Bug #331783 - separate initialization from increment for 'for in' loop
with index expression in order to prevent side-effects from occuring
when the for loop stops (as in 'for (p[i++] in obj)...')


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@18841 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-28 00:25:33 +00:00
rogerl%netscape.com
73b18ade9c Added change from 140_BRANCH to better handle way long string literals.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@18641 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-26 20:53:38 +00:00
rogerl%netscape.com
6122209dca Don't anchor EOLonly, it can do it for itself. (Brought forward from
140_BRANCH). Bug#340102


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@18638 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-26 20:11:23 +00:00
val4%cornell.edu
e5b764e983 Formatting changed to 80 lines max.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@18194 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-21 20:45:20 +00:00
val4%cornell.edu
84611771f9 Code improvements. Some things were redone as macros, added security
as a macro, warnings, etc.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@18191 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-21 19:59:41 +00:00
val4%cornell.edu
95cb9f8bb7 Various bug fixes
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@18061 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-20 06:21:55 +00:00
val4%cornell.edu
b667832a93 Standard tests now pass
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@18039 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-19 23:47:30 +00:00
val4%cornell.edu
f2a087fb61 Got rid of anonymous union
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@18027 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-19 22:07:52 +00:00
val4%cornell.edu
744a8a6402 Many changes devoted mainly various bug fixes. std_streams.js
and nspr_files.js should mostly pass.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@18026 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-19 21:05:02 +00:00
val4%cornell.edu
2c19d573b9 Some HTML magic for displaying the readme.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@17965 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-18 21:10:40 +00:00
rogerl%netscape.com
44e18f453b Removed redundant code.
Changed anchorRegExp to ignore emptiness as a criteria for inserting an
anchor.
Prevent '\0' from being included in NCCLASS.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@17959 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-18 18:55:38 +00:00
val4%cornell.edu
e8ee11cc30 Background image
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@17944 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-18 03:43:04 +00:00
val4%cornell.edu
f97650ff4d Added toURL() support in jsfile.[c/h]. Needed to change jsstr.*
to accomodate that.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@17756 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-14 22:48:51 +00:00
mccabe%netscape.com
6398fd3969 New config file for 64-bit IRIX 6.2. It just includes IRIX.mk.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@17751 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-14 21:50:48 +00:00
val4%cornell.edu
64bc56432a Combined error messages into classes
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@17728 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-14 08:02:06 +00:00
val4%cornell.edu
9c0688e086 Changed the signature of js_FileInit call, so had to change jsapi.c
to reflect that. Numberious changes in jsfile.c: native support only
works for standard streams and pipes, error handling, macros, url
support, etc.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@17723 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-14 07:45:51 +00:00
val4%cornell.edu
1e17c44fbd I am going to change the native file support to only support pipes and
standard streams. Otherwise, there are too much problems.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@17698 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-14 04:55:40 +00:00
brendan%netscape.com
02486bc176 JSOP_EVAL renaming and related JSVERSION_IS_ECMA simplification.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@17686 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-14 02:33:10 +00:00
brendan%netscape.com
74736d0aa2 Use #if defined XP_PC and _MSC_VER before comparing _LIB_VERSION to _IEEE_ for Windows-only hackaround.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@17685 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-14 02:32:33 +00:00
val4%cornell.edu
e62feeeeb5 Various changes: formating, error handling, minor bugs.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@17684 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-14 02:24:05 +00:00
val4%cornell.edu
25629114ff Moving to SpiderMonkeyDev_BRANCH.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@17669 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-13 23:50:27 +00:00
(no author)
f0dc15e6f1 This commit was manufactured by cvs2svn to create branch
'SpiderMonkeyDev_BRANCH'.

git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@17667 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-13 23:39:47 +00:00
rogerl%netscape.com
767e2ceb35 Added check for end of string to NONALPHA/DIGIT/SPACE anchors so we don't
always find them there.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@17660 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-13 21:29:17 +00:00
rogerl%netscape.com
444c87e0f5 Added define for new MULTILINE instance property
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@17589 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-12 17:19:30 +00:00
rogerl%netscape.com
6995e6db68 Major changes to add Perl5 stuff -
- ungreedy versions of + * {}
- non-capturing parens (?:  )
- multiline as an instance property (set with m flag)
Also bug fixes for -
- "|a" was being interpreted as a 2 char literal instead of an alternate
with an empty first case.
- { } wasn't back-tracking.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@17524 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-12 00:08:36 +00:00
mccabe%netscape.com
036f73d888 Partial work towards fixing array methods to always preserve empty
elements.  Currently turned off via JS_HAS_SPARSE_ARRAYS in jsconfig.h.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@17328 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-07 21:47:50 +00:00
brendan%netscape.com
017f8429a6 Fix anchoring and multiline bol-matching to handle empty match at end (mozilla bug 2157).
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@17210 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-06 00:38:00 +00:00
brade%netscape.com
a548931dc2 checkin to correspond with previous checkin on trunk (add typecasts to reduce Macintosh compiler warnings). r/a mccabe
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@17100 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-04 17:15:58 +00:00
mccabe%netscape.com
2edfbcee56 Fixes to bugzilla bug 2021. Thanks to Rainer Staringer
<rainer@aaa-plus.com> for great memory leak and garbage variable
fixes.

These fixes clear up some leaks in the errors-as-exceptions mechanism
(currently turned off in jsconfig.h), and also some uninitialized
variables that sometimes resulted in garbage fields in the ErrorReport
struct, independent of the exception code.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@16822 18797224-902f-48f8-a5cc-f745e15eee43
1998-12-22 22:12:00 +00:00
rogerl%netscape.com
a2eaa7c8b9 When the current frame has a null script or pc value, try looking at the
next frame to see if it has any idea where the error came from.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@16106 18797224-902f-48f8-a5cc-f745e15eee43
1998-12-09 23:35:48 +00:00
shaver%netscape.com
4d96b37aed fix up AddRoot handling
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@16095 18797224-902f-48f8-a5cc-f745e15eee43
1998-12-09 21:41:20 +00:00
rogerl%netscape.com
be859bc4a8 Added new JSOP_CALLSPECIAL op to decompilation (used to protect eval from
indirect calls)


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@15994 18797224-902f-48f8-a5cc-f745e15eee43
1998-12-08 21:58:17 +00:00
fur%netscape.com
ce4a0d7dfa Compiler-generated file shouldn't be checked in
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@15502 18797224-902f-48f8-a5cc-f745e15eee43
1998-12-01 04:23:35 +00:00
wynholds%netscape.com
c8d156d137 using cp on NT, which is bad, but i can't get copy to work. hmmmm -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@15207 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-24 00:44:45 +00:00
wynholds%netscape.com
afc0070e3a don't need nsinstall-target anymore. -mw
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@15199 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-24 00:13:43 +00:00
fur%netscape.com
6757eb6507 Fix #335449:
[[DefaultValue]] operator doesn't call valueOf() for function/closure
    objects when hint is not JSTYPE_STRING.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@14943 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-19 09:13:48 +00:00
mccabe%netscape.com
921da2b46b Fix wording nits
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@14664 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-14 05:57:58 +00:00
mccabe%netscape.com
774b05a64e Move -lreadline, -ledit etc. to new $(PROG_LIBS) variable, so that
they're not added to the compile lines for libjs, but only to the js
executable.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@14663 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-14 05:51:50 +00:00
jband%netscape.com
eb37b3b03b fixes to make source work right in debugger after mccabe's changes
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@14662 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-14 05:19:00 +00:00
mccabe%netscape.com
c33d03c991 remove &^@!& trailing NUL characters added by cvs checkin!
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@14658 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-14 02:52:28 +00:00
mccabe%netscape.com
03091e4c57 - Added APIs that allow much cleaner support of interactive execution;
this made it possible to remove the TSF_INTERACTIVE flag from the
scanner, and also much SCAN_NEWLINES twiddling.

- Restructured js.c to use the new interactive APIs; interactive
execution now parses the same language grammar as execution from a
file - it's now legal to put opening braces on a new line.  This
fixes a longstanding bug where

while(false)
5

evaluated to 5 in interactive mode.

- Added support for line-editing and history for the standalone
javascript engine; added files for the open-licensed 'editline'
library.  Line-editing is currently enabled for Linux, Irix and SunOS,
and is likely to work elsewhere; see editline/README.

- Fixed rules.mk to recur into PREDIRS and DIRS for clean and clobber.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@14655 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-14 02:24:06 +00:00
mccabe%netscape.com
d3f6fcb126 logmsg
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@14652 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-14 02:14:50 +00:00
rogerl%netscape.com
0351cf31cb Eek, left the debug flag turned on.
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@14600 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-13 19:08:29 +00:00
rogerl%netscape.com
6d3eca4275 Fixed the debug dump for unicode ops.
Fixed bug in ucclass op following anchor1 op - needed to update next pc
value to account for length of ucclass data.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@14599 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-13 18:48:04 +00:00
mccabe%netscape.com
0d867e309d Fix to 333916. Error reports resulting from uncaught exceptions get
the JSREPORT_UNCAUGHT_EXCEPTION flag.  Moved this code out of #if
HAS_ERROR_EXCEPTIONS code, because it applies to all exceptions, not
just error exceptions.


git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@14279 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-09 08:29:28 +00:00
shaver%netscape.com
4eae6b10bd remove old *.mk sanity checking that autoconf doesn't need anymore
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@14192 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-06 06:21:12 +00:00
jband%netscape.com
e2462a0ad5 Converted #define'd ids to enums and moved all enums from jsdebug.h to jsdenums.h for shared use from jsdebug.h classic public api and jsdxpcom XPCOM public api. Added very-not-yet-functional jsdxpcom.h
git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@14161 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-05 21:17:09 +00:00
(no author)
ba07bbb4d5 This commit was manufactured by cvs2svn to create branch
'SpiderMonkeyDev_BRANCH'.

git-svn-id: svn://10.0.0.236/branches/SpiderMonkeyDev_BRANCH@14139 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-05 08:57:25 +00:00
433 changed files with 122896 additions and 5152 deletions

View File

@@ -1,134 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 "Fundamentals.h"
#include "BitSet.h"
// Return the next bit after index set to true or -1 if none.
//
Int32 BitSet::nextOne(Int32 pos) const
{
++pos;
if (pos < 0 || Uint32(pos) >= universeSize)
return -1;
Uint32 offset = getWordOffset(pos);
Uint8 index = getBitOffset(pos);
Word* ptr = &word[offset];
Word currentWord = *ptr++ >> index;
if (currentWord != Word(0)) {
while ((currentWord & Word(1)) == 0) {
++index;
currentWord >>= 1;
}
return (offset << nBitsInWordLog2) + index;
}
Word* limit = &word[getSizeInWords(universeSize)];
while (ptr < limit) {
++offset;
currentWord = *ptr++;
if (currentWord != Word(0)) {
index = 0;
while ((currentWord & Word(1)) == 0) {
++index;
currentWord >>= 1;
}
return (offset << nBitsInWordLog2) + index;
}
}
return -1;
}
// Return the next bit after index set to false or -1 if none.
//
Int32 BitSet::nextZero(Int32 pos) const
{
++pos;
if (pos < 0 || Uint32(pos) >= universeSize)
return -1;
Uint32 offset = getWordOffset(pos);
Uint8 index = getBitOffset(pos);
Word* ptr = &word[offset];
Word currentWord = *ptr++ >> index;
if (currentWord != Word(~0)) {
for (; index < nBitsInWord; ++index) {
if ((currentWord & Word(1)) == 0) {
Int32 ret = (offset << nBitsInWordLog2) + index;
return (Uint32(ret) < universeSize) ? ret : -1;
}
currentWord >>= 1;
}
}
Word* limit = &word[getSizeInWords(universeSize)];
while (ptr < limit) {
++offset;
currentWord = *ptr++;
if (currentWord != Word(~0)) {
for (index = 0; index < nBitsInWord; ++index) {
if ((currentWord & Word(1)) == 0) {
Int32 ret = (offset << nBitsInWordLog2) + index;
return (Uint32(ret) < universeSize) ? ret : -1;
}
currentWord >>= 1;
}
}
}
return -1;
}
#ifdef DEBUG_LOG
// Print the set.
//
void BitSet::printPretty(LogModuleObject log)
{
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("[ "));
for (Int32 i = firstOne(); i != -1; i = nextOne(i)) {
Int32 currentBit = i;
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%d", currentBit));
Int32 nextBit = nextOne(currentBit);
if (nextBit != currentBit + 1) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" "));
continue;
}
while ((nextBit != -1) && (nextBit == (currentBit + 1))) {
currentBit = nextBit;
nextBit = nextOne(nextBit);
}
if (currentBit > (i+1))
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("-%d ", currentBit));
else
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" %d ", currentBit));
i = currentBit;
}
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("]\n"));
}
#endif // DEBUG_LOG

View File

@@ -1,195 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 _BITSET_H_
#define _BITSET_H_
#include "Fundamentals.h"
#include "LogModule.h"
#include "Pool.h"
#include <string.h>
//------------------------------------------------------------------------------
// BitSet -
class BitSet
{
private:
#if (PR_BITS_PER_WORD == 64)
typedef Uint64 Word;
#elif (PR_BITS_PER_WORD == 32)
typedef Uint32 Word;
#endif
static const nBitsInWord = PR_BITS_PER_WORD;
static const nBytesInWord = PR_BYTES_PER_WORD;
static const nBitsInWordLog2 = PR_BITS_PER_WORD_LOG2;
static const nBytesInWordLog2 = PR_BYTES_PER_WORD_LOG2;
// Return the number of Word need to store the universe.
static Uint32 getSizeInWords(Uint32 sizeOfUniverse) {return (sizeOfUniverse + (nBitsInWord - 1)) >> nBitsInWordLog2;}
// Return the given element offset in its containing Word.
static Uint32 getBitOffset(Uint32 element) {return element & (nBitsInWord - 1);}
// Return the Word offset for the given element int the universe.
static Uint32 getWordOffset(Uint32 element) {return element >> nBitsInWordLog2;}
// Return the mask for the given bit index.
static Word getMask(Uint8 index) {return Word(1) << index;}
private:
Uint32 universeSize; // Size of the universe
Word* word; // universe memory.
private:
// No copy constructor.
BitSet(const BitSet&);
// Check if the given set's universe is of the same size than this universe.
void checkUniverseCompatibility(const BitSet& set) const {assert(set.universeSize == universeSize);}
// Check if pos is valid for this set's universe.
void checkMember(Int32 pos) const {assert(pos >=0 && Uint32(pos) < universeSize);}
public:
// Create a bitset of universeSize bits.
BitSet(Pool& pool, Uint32 universeSize) : universeSize(universeSize) {word = new(pool) Word[getSizeInWords(universeSize)]; clear();}
// Return the size of this bitset.
Uint32 getSize() const {return universeSize;}
// Clear the bitset.
void clear() {memset(word, 0x00, getSizeInWords(universeSize) << nBytesInWordLog2);}
// Clear the bit at index.
void clear(Uint32 index) {checkMember(index); word[getWordOffset(index)] &= ~getMask(index);}
// Set the bitset.
void set() {memset(word, 0xFF, getSizeInWords(universeSize) << nBytesInWordLog2);}
// Set the bit at index.
void set(Uint32 index) {checkMember(index); word[getWordOffset(index)] |= getMask(index);}
// Return true if the bit at index is set.
bool test(Uint32 index) const {checkMember(index); return (word[getWordOffset(index)] & getMask(index)) != 0;}
// Union with the given bitset.
inline void or(const BitSet& set);
// Intersection with the given bitset.
inline void and(const BitSet& set);
// Difference with the given bitset.
inline void difference(const BitSet& set);
// Copy set.
inline BitSet& operator = (const BitSet& set);
// Return true if the bitset are identical.
friend bool operator == (const BitSet& set1, const BitSet& set2);
// Return true if the bitset are different.
friend bool operator != (const BitSet& set1, const BitSet& set2);
// Logical operators.
BitSet& operator |= (const BitSet& set) {or(set); return *this;}
BitSet& operator &= (const BitSet& set) {and(set); return *this;}
BitSet& operator -= (const BitSet& set) {difference(set); return *this;}
// Return the first bit at set to true or -1 if none.
Int32 firstOne() const {return nextOne(-1);}
// Return the next bit after index set to true or -1 if none.
Int32 nextOne(Int32 pos) const;
// Return the first bit at set to false or -1 if none.
Int32 firstZero() const {return nextZero(-1);}
// Return the next bit after index set to false or -1 if none.
Int32 nextZero(Int32 pos) const;
// Iterator to conform with the set API.
typedef Int32 iterator;
// Return true if the walk is ordered.
static bool isOrdered() {return true;}
// Return the iterator for the first element of this set.
iterator begin() const {return firstOne();}
// Return the next iterator.
iterator advance(iterator pos) const {return nextOne(pos);}
// Return true if the iterator is at the end of the set.
bool done(iterator pos) const {return pos == -1;}
// Return the element corresponding to the given iterator.
Uint32 get(iterator pos) const {return pos;}
#ifdef DEBUG_LOG
// Print the set.
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
// Union with the given bitset.
//
inline void BitSet::or(const BitSet& set)
{
checkUniverseCompatibility(set);
Word* src = set.word;
Word* dst = word;
Word* limit = &src[getSizeInWords(universeSize)];
while (src < limit)
*dst++ |= *src++;
}
// Intersection with the given bitset.
//
inline void BitSet::and(const BitSet& set)
{
checkUniverseCompatibility(set);
Word* src = set.word;
Word* dst = word;
Word* limit = &src[getSizeInWords(universeSize)];
while (src < limit)
*dst++ &= *src++;
}
// Difference with the given bitset.
//
inline void BitSet::difference(const BitSet& set)
{
checkUniverseCompatibility(set);
Word* src = set.word;
Word* dst = word;
Word* limit = &src[getSizeInWords(universeSize)];
while (src < limit)
*dst++ &= ~*src++;
}
// Copy the given set into this set.
//
inline BitSet& BitSet::operator = (const BitSet& set)
{
checkUniverseCompatibility(set);
if (this != &set)
memcpy(word, set.word, getSizeInWords(universeSize) << nBytesInWordLog2);
return *this;
}
// Return true if the given set is identical to this set.
inline bool operator == (const BitSet& set1, const BitSet& set2)
{
set1.checkUniverseCompatibility(set2);
if (&set1 == &set2)
return true;
return memcmp(set1.word, set2.word, BitSet::getSizeInWords(set1.universeSize) << BitSet::nBytesInWordLog2) == 0;
}
inline bool operator != (const BitSet& set1, const BitSet& set2) {return !(set1 == set2);}
#endif // _BITSET_H

View File

@@ -1,159 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 _COALESCING_H_
#define _COALESCING_H_
#include "Fundamentals.h"
#include "Pool.h"
#include "RegisterPressure.h"
#include "InterferenceGraph.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "SparseSet.h"
#include "RegisterAllocator.h"
#include "RegisterAllocatorTools.h"
#if 1
// Performing an ultra conservative coalescing meens that when we look at
// candidates (source,destination) for coalescing we need to make sure
// that the combined interference of the source and destination register
// will not exceed the total number of register available for the register
// class.
#define ULTRA_CONSERVATIVE_COALESCING
#else
// If we are not doing an ultra conservative coalescing we have to make sure
// that the total number of neighbor whose degree is greater than the total
// number of register is not greater than the total number of register.
#undef ULTRA_CONSERVATIVE_COALESCING
#endif
template <class RegisterPressure>
struct Coalescing
{
static bool coalesce(RegisterAllocator& registerAllocator);
};
template <class RegisterPressure>
bool Coalescing<RegisterPressure>::coalesce(RegisterAllocator& registerAllocator)
{
Pool& pool = registerAllocator.pool;
// Initialize the lookup table
//
Uint32 rangeCount = registerAllocator.rangeCount;
RegisterName* newRange = new RegisterName[2 * rangeCount];
RegisterName* coalescedRange = &newRange[rangeCount];
RegisterName* name2range = registerAllocator.name2range;
init(coalescedRange, rangeCount);
SparseSet interferences(pool, rangeCount);
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
bool removedInstructions = false;
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.lndList;
Uint32 nNodes = controlGraph.nNodes;
// Walk the nodes in the loop nesting depth list.
for (Int32 n = nNodes - 1; n >= 0; n--) {
InstructionList& instructions = nodes[n]->getInstructions();
InstructionList::iterator it = instructions.begin();
while (!instructions.done(it)) {
Instruction& instruction = instructions.get(it);
it = instructions.advance(it);
if ((instruction.getFlags() & ifCopy) != 0) {
assert(instruction.getInstructionUseBegin() != instruction.getInstructionUseEnd() && instruction.getInstructionUseBegin()[0].isRegister());
assert(instruction.getInstructionDefineBegin() != instruction.getInstructionDefineEnd() && instruction.getInstructionDefineBegin()[0].isRegister());
RegisterName source = findRoot(name2range[instruction.getInstructionUseBegin()[0].getRegisterName()], coalescedRange);
RegisterName destination = findRoot(name2range[instruction.getInstructionDefineBegin()[0].getRegisterName()], coalescedRange);
if (source == destination) {
instruction.remove();
} else if (!iGraph.interfere(source, destination)) {
InterferenceVector* sourceVector = iGraph.getInterferenceVector(source);
InterferenceVector* destinationVector = iGraph.getInterferenceVector(destination);
#ifdef ULTRA_CONSERVATIVE_COALESCING
interferences.clear();
InterferenceVector* vector;
for (vector = sourceVector; vector != NULL; vector = vector->next) {
RegisterName* neighbors = vector->neighbors;
for (Uint32 i = 0; i < vector->count; i++)
interferences.set(findRoot(neighbors[i], coalescedRange));
}
for (vector = destinationVector; vector != NULL; vector = vector->next) {
RegisterName* neighbors = vector->neighbors;
for (Uint32 i = 0; i < vector->count; i++)
interferences.set(findRoot(neighbors[i], coalescedRange));
}
Uint32 count = interferences.getSize();
#else // ULTRA_CONSERVATIVE_COALESCING
trespass("not implemented");
Uint32 count = 0;
#endif // ULTRA_CONSERVATIVE_COALESCING
if (count < 6 /* FIX: should get the number from the class */) {
// Update the interferences vector.
if (sourceVector == NULL) {
iGraph.setInterferenceVector(source, destinationVector);
sourceVector = destinationVector;
} else if (destinationVector == NULL)
iGraph.setInterferenceVector(destination, sourceVector);
else {
InterferenceVector* last = NULL;
for (InterferenceVector* v = sourceVector; v != NULL; v = v->next)
last = v;
assert(last);
last->next = destinationVector;
iGraph.setInterferenceVector(destination, sourceVector);
}
// Update the interference matrix.
for (InterferenceVector* v = sourceVector; v != NULL; v = v->next) {
RegisterName* neighbors = v->neighbors;
for (Uint32 i = 0; i < v->count; i++) {
RegisterName neighbor = findRoot(neighbors[i], coalescedRange);
iGraph.setInterference(neighbor, source);
iGraph.setInterference(neighbor, destination);
}
}
instruction.remove();
coalescedRange[source] = destination;
removedInstructions = true;
}
}
}
}
}
registerAllocator.rangeCount = compress(registerAllocator.name2range, coalescedRange, registerAllocator.nameCount, rangeCount);
delete newRange;
return removedInstructions;
}
#endif // _COALESCING_H_

View File

@@ -1,283 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 NEW_LAURENTM_CODE
#include "Coloring.h"
#include "VirtualRegister.h"
#include "FastBitSet.h"
#include "FastBitMatrix.h"
#include "CpuInfo.h"
bool Coloring::
assignRegisters(FastBitMatrix& interferenceMatrix)
{
PRUint32 *stackPtr = new(pool) PRUint32[vRegManager.count()];
return select(interferenceMatrix, stackPtr, simplify(interferenceMatrix, stackPtr));
}
PRInt32 Coloring::
getLowestSpillCostRegister(FastBitSet& bitset)
{
PRInt32 lowest = bitset.firstOne();
if (lowest != -1)
{
Flt32 cost = vRegManager.getVirtualRegister(lowest).spillInfo.spillCost;
for (PRInt32 r = bitset.nextOne(lowest); r != -1; r = bitset.nextOne(r))
{
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
if (!vReg.spillInfo.infiniteSpillCost && (vReg.spillInfo.spillCost < cost))
{
cost = vReg.spillInfo.spillCost;
lowest = r;
}
}
}
return lowest;
}
PRUint32* Coloring::
simplify(FastBitMatrix interferenceMatrix, PRUint32* stackPtr)
{
// first we construct the sets low and high. low contains all nodes of degree
// inferior to the number of register available on the processor. All the
// nodes with an high degree and a finite spill cost are placed in high.
// Nodes of high degree and infinite spill cost are not included in either sets.
PRUint32 nRegisters = vRegManager.count();
FastBitSet low(pool, nRegisters);
FastBitSet high(pool, nRegisters);
FastBitSet stack(pool, nRegisters);
for (VirtualRegisterManager::iterator i = vRegManager.begin(); !vRegManager.done(i); i = vRegManager.advance(i))
{
VirtualRegister& vReg = vRegManager.getVirtualRegister(i);
if (vReg.getClass() == vrcStackSlot)
{
stack.set(i);
vReg.colorRegister(nRegisters);
}
else
{
if (vReg.colorInfo.interferenceDegree < NUMBER_OF_REGISTERS)
low.set(i);
else // if (!vReg.spillInfo.infiniteSpillCost)
high.set(i);
// Set coloring info.
vReg.spillInfo.willSpill = false;
switch(vReg.getClass())
{
case vrcInteger:
vReg.colorRegister(LAST_GREGISTER + 1);
break;
case vrcFloatingPoint:
case vrcFixedPoint:
vReg.colorRegister(LAST_FPREGISTER + 1);
break;
default:
PR_ASSERT(false); // Cannot happen.
}
}
}
// push the stack registers
PRInt32 j;
for (j = stack.firstOne(); j != -1; j = stack.nextOne(j))
*stackPtr++ = j;
// simplify
while (true)
{
PRInt32 r;
while ((r = getLowestSpillCostRegister(low)) != -1)
{
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
/* update low and high */
FastBitSet inter(interferenceMatrix.getRow(r), nRegisters);
for (j = inter.firstOne(); j != -1; j = inter.nextOne(j))
{
VirtualRegister& neighbor = vRegManager.getVirtualRegister(j);
// if the new interference degree of one of his neighbor becomes
// NUMBER_OF_REGISTERS - 1 then it is added to the set 'low'.
PRUint32 maxInterference = 0;
switch (neighbor.getClass())
{
case vrcInteger:
maxInterference = NUMBER_OF_GREGISTERS;
break;
case vrcFloatingPoint:
case vrcFixedPoint:
maxInterference = NUMBER_OF_FPREGISTERS;
break;
default:
PR_ASSERT(false);
}
if ((vRegManager.getVirtualRegister(j).colorInfo.interferenceDegree-- == maxInterference))
{
high.clear(j);
low.set(j);
}
vReg.colorInfo.interferenceDegree--;
interferenceMatrix.clear(r, j);
interferenceMatrix.clear(j, r);
}
low.clear(r);
// Push this register.
*stackPtr++ = r;
}
if ((r = getLowestSpillCostRegister(high)) != -1)
{
high.clear(r);
low.set(r);
}
else
break;
}
return stackPtr;
}
bool Coloring::
select(FastBitMatrix& interferenceMatrix, PRUint32* stackBase, PRUint32* stackPtr)
{
PRUint32 nRegisters = vRegManager.count();
FastBitSet usedRegisters(NUMBER_OF_REGISTERS + 1); // usedRegisters if used for both GR & FPR.
FastBitSet preColoredRegisters(NUMBER_OF_REGISTERS + 1);
FastBitSet usedStack(nRegisters + 1);
bool success = true;
Int32 lastUsedSSR = -1;
// select
while (stackPtr != stackBase)
{
// Pop one register.
PRUint32 r = *--stackPtr;
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
FastBitSet neighbors(interferenceMatrix.getRow(r), nRegisters);
if (vReg.getClass() == vrcStackSlot)
// Stack slots coloring.
{
usedStack.clear();
for (PRInt32 i = neighbors.firstOne(); i != -1; i = neighbors.nextOne(i))
usedStack.set(vRegManager.getVirtualRegister(i).getColor());
Int32 color = usedStack.firstZero();
vReg.colorRegister(color);
if (color > lastUsedSSR)
lastUsedSSR = color;
}
else
// Integer & Floating point register coloring.
{
usedRegisters.clear();
preColoredRegisters.clear();
for (PRInt32 i = neighbors.firstOne(); i != -1; i = neighbors.nextOne(i))
{
VirtualRegister& nvReg = vRegManager.getVirtualRegister(i);
usedRegisters.set(nvReg.getColor());
if (nvReg.isPreColored())
preColoredRegisters.set(nvReg.getPreColor());
}
if (vReg.hasSpecialInterference)
usedRegisters |= vReg.specialInterference;
PRInt8 c = -1;
PRInt8 maxColor = 0;
PRInt8 firstColor = 0;
switch (vReg.getClass())
{
case vrcInteger:
firstColor = FIRST_GREGISTER;
maxColor = LAST_GREGISTER;
break;
case vrcFloatingPoint:
case vrcFixedPoint:
firstColor = FIRST_FPREGISTER;
maxColor = LAST_FPREGISTER;
break;
default:
PR_ASSERT(false);
}
if (vReg.isPreColored())
{
c = vReg.getPreColor();
if (usedRegisters.test(c))
c = -1;
}
else
{
for (c = usedRegisters.nextZero(firstColor - 1); (c >= 0) && (c <= maxColor) && (preColoredRegisters.test(c));
c = usedRegisters.nextZero(c)) {}
}
if ((c >= 0) && (c <= maxColor))
{
vReg.colorRegister(c);
}
else
{
VirtualRegister& stackRegister = vRegManager.newVirtualRegister(vrcStackSlot);
vReg.equivalentRegister[vrcStackSlot] = &stackRegister;
vReg.spillInfo.willSpill = true;
success = false;
}
}
}
#ifdef DEBUG
if (success)
{
for (VirtualRegisterManager::iterator i = vRegManager.begin(); !vRegManager.done(i); i = vRegManager.advance(i))
{
VirtualRegister& vReg = vRegManager.getVirtualRegister(i);
switch (vReg.getClass())
{
case vrcInteger:
if (vReg.getColor() > LAST_GREGISTER)
PR_ASSERT(false);
break;
case vrcFloatingPoint:
case vrcFixedPoint:
#if NUMBER_OF_FPREGISTERS != 0
if (vReg.getColor() > LAST_FPREGISTER)
PR_ASSERT(false);
#endif
break;
default:
break;
}
}
}
#endif
vRegManager.nUsedStackSlots = lastUsedSSR + 1;
return success;
}
#endif // NEW_LAURENTM_CODE

View File

@@ -1,284 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 "Fundamentals.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "RegisterAllocator.h"
#include "VirtualRegister.h"
#include "InterferenceGraph.h"
#include "SparseSet.h"
#include "Spilling.h"
#include "Splits.h"
UT_EXTERN_LOG_MODULE(RegAlloc);
template <class RegisterPressure>
class Coloring
{
private:
static RegisterName* simplify(RegisterAllocator& registerAllocator, RegisterName* coloringStack);
static bool select(RegisterAllocator& registerAllocator, RegisterName* coloringStack, RegisterName* coloringStackPtr);
public:
static bool color(RegisterAllocator& registerAllocator);
static void finalColoring(RegisterAllocator& registerAllocator);
};
template <class RegisterPressure>
void Coloring<RegisterPressure>::finalColoring(RegisterAllocator& registerAllocator)
{
RegisterName* color = registerAllocator.color;
RegisterName* name2range = registerAllocator.name2range;
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
usePtr->setRegisterName(color[name2range[usePtr->getRegisterName()]]);
#ifdef DEBUG
RegisterID rid = usePtr->getRegisterID();
setColoredRegister(rid);
usePtr->setRegisterID(rid);
#endif // DEBUG
}
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
definePtr->setRegisterName(color[name2range[definePtr->getRegisterName()]]);
#ifdef DEBUG
RegisterID rid = definePtr->getRegisterID();
setColoredRegister(rid);
definePtr->setRegisterID(rid);
#endif // DEBUG
}
}
}
}
template <class RegisterPressure>
bool Coloring<RegisterPressure>::select(RegisterAllocator& registerAllocator, RegisterName* coloringStack, RegisterName* coloringStackPtr)
{
Uint32 rangeCount = registerAllocator.rangeCount;
RegisterName* color = new RegisterName[rangeCount];
registerAllocator.color = color;
for (Uint32 r = 1; r < rangeCount; r++)
color[r] = RegisterName(6); // FIX;
// Color the preColored registers.
//
VirtualRegisterManager& vrManager = registerAllocator.vrManager;
RegisterName* name2range = registerAllocator.name2range;
PreColoredRegister* machineEnd = vrManager.getMachineRegistersEnd();
for (PreColoredRegister* machinePtr = vrManager.getMachineRegistersBegin(); machinePtr < machineEnd; machinePtr++)
if (machinePtr->id != invalidID) {
color[name2range[getName(machinePtr->id)]] = machinePtr->color;
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\twill preColor range %d as %d\n", name2range[getName(machinePtr->id)], machinePtr->color));
}
SpillCost* cost = registerAllocator.spillCost;
Pool& pool = registerAllocator.pool;
SparseSet& spill = *new(pool) SparseSet(pool, rangeCount);
registerAllocator.willSpill = &spill;
SparseSet neighborColors(pool, 6); // FIX
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
bool coloringFailed = false;
while (coloringStackPtr > coloringStack) {
RegisterName range = *--coloringStackPtr;
if (!cost[range].infinite && cost[range].cost < 0) {
coloringFailed = true;
spill.set(range);
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tfailed to color %d, will spill.\n", range));
} else {
neighborColors.clear();
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
for (Int32 i = vector->count - 1; i >= 0; --i) {
RegisterName neighborColor = color[vector->neighbors[i]];
if (neighborColor < 6) // FIX
neighborColors.set(neighborColor);
}
if (neighborColors.getSize() == 6) { // FIX
coloringFailed = true;
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tfailed to color %d, ", range));
if (!Splits<RegisterPressure>::findSplit(registerAllocator, color, range)) {
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("will spill.\n"));
spill.set(range);
} else
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("will split.\n"));
} else {
for (Uint32 i = 0; i < 6; i++) // FIX
if (!neighborColors.test(i)) {
fprintf(stdout, "\twill color %d as %d\n", range, i);
color[range] = RegisterName(i);
break;
}
}
}
}
#ifdef DEBUG_LOG
if (coloringFailed) {
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring failed:\n"));
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\twill spill: "));
spill.printPretty(UT_LOG_MODULE(RegAlloc));
} else {
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring succeeded:\n"));
for (Uint32 i = 1; i < rangeCount; i++)
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\trange %d colored as %d\n", i, color[i]));
}
#endif
return !coloringFailed;
}
template <class RegisterPressure>
RegisterName* Coloring<RegisterPressure>::simplify(RegisterAllocator& registerAllocator, RegisterName* coloringStack)
{
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
SpillCost* spillCost = registerAllocator.spillCost;
Uint32 rangeCount = registerAllocator.rangeCount;
Uint32* degree = new Uint32[rangeCount];
for (RegisterName i = RegisterName(1); i < rangeCount; i = RegisterName(i + 1)) {
InterferenceVector* vector = iGraph.getInterferenceVector(i);
degree[i] = (vector != NULL) ? vector->count : 0;
}
Pool& pool = registerAllocator.pool;
SparseSet low(pool, rangeCount);
SparseSet high(pool, rangeCount);
SparseSet highInfinite(pool, rangeCount);
SparseSet preColored(pool, rangeCount);
// Get the precolored registers.
//
VirtualRegisterManager& vrManager = registerAllocator.vrManager;
RegisterName* name2range = registerAllocator.name2range;
PreColoredRegister* machineEnd = vrManager.getMachineRegistersEnd();
for (PreColoredRegister* machinePtr = vrManager.getMachineRegistersBegin(); machinePtr < machineEnd; machinePtr++)
if (machinePtr->id != invalidID)
preColored.set(name2range[getName(machinePtr->id)]);
// Insert the live ranges in the sets.
//
for (Uint32 range = 1; range < rangeCount; range++)
if (!preColored.test(range))
if (degree[range] < 6) // FIX
low.set(range);
else if (!spillCost[range].infinite)
high.set(range);
else
highInfinite.set(range);
#ifdef DEBUG_LOG
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring sets:\n\tlow = "));
low.printPretty(UT_LOG_MODULE(RegAlloc));
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\thigh = "));
high.printPretty(UT_LOG_MODULE(RegAlloc));
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\thighInfinite = "));
highInfinite.printPretty(UT_LOG_MODULE(RegAlloc));
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tpreColored = "));
preColored.printPretty(UT_LOG_MODULE(RegAlloc));
#endif // DEBUG_LOG
RegisterName* coloringStackPtr = coloringStack;
while (low.getSize() != 0 || high.getSize() != 0) {
while (low.getSize() != 0) {
RegisterName range = RegisterName(low.getOne());
low.clear(range);
*coloringStackPtr++ = range;
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
for (Int32 i = (vector->count - 1); i >= 0; --i) {
RegisterName neighbor = vector->neighbors[i];
degree[neighbor]--;
if (degree[neighbor] < 6) // FIX
if (high.test(neighbor)) {
high.clear(neighbor);
low.set(neighbor);
} else if (highInfinite.test(neighbor)) {
highInfinite.clear(neighbor);
low.set(neighbor);
}
}
}
if (high.getSize() != 0) {
RegisterName best = RegisterName(high.getOne());
double bestCost = spillCost[best].cost;
double bestDegree = degree[best];
// Choose the next best candidate.
//
for (SparseSet::iterator i = high.begin(); !high.done(i); i = high.advance(i)) {
RegisterName range = RegisterName(high.get(i));
double thisCost = spillCost[range].cost;
double thisDegree = degree[range];
if (thisCost * bestDegree < bestCost * thisDegree) {
best = range;
bestCost = thisCost;
bestDegree = thisDegree;
}
}
high.clear(best);
low.set(best);
}
}
assert(highInfinite.getSize() == 0);
delete degree;
#ifdef DEBUG_LOG
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring stack:\n\t"));
for (RegisterName* sp = coloringStack; sp < coloringStackPtr; ++sp)
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("%d ", *sp));
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\n"));
#endif // DEBUG_LOG
return coloringStackPtr;
}
template <class RegisterPressure>
bool Coloring<RegisterPressure>::color(RegisterAllocator& registerAllocator)
{
RegisterName* coloringStack = new RegisterName[registerAllocator.rangeCount];
return select(registerAllocator, coloringStack, simplify(registerAllocator, coloringStack));
}

View File

@@ -1,212 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 "Fundamentals.h"
#include <string.h>
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "DominatorGraph.h"
DominatorGraph::DominatorGraph(ControlGraph& controlGraph) : controlGraph(controlGraph)
{
Uint32 nNodes = controlGraph.nNodes;
GtoV = new Uint32[nNodes + 1];
VtoG = new Uint32[nNodes + 1];
Uint32 v = 1;
for (Uint32 n = 0; n < nNodes; n++) {
VtoG[v] = n;
GtoV[n] = v++;
}
// Initialize all the 1-based arrays.
//
parent = new Uint32[v];
semi = new Uint32[v];
vertex = new Uint32[v];
label = new Uint32[v];
size = new Uint32[v];
ancestor = new Uint32[v];
child = new Uint32[v];
dom = new Uint32[v];
bucket = new DGLinkedList*[v];
memset(semi, '\0', v * sizeof(Uint32));
memset(bucket, '\0', v * sizeof(DGLinkedList*));
vCount = v;
build();
delete parent;
delete semi;
delete vertex;
delete label;
delete size;
delete ancestor;
delete child;
delete dom;
delete bucket;
}
Uint32 DominatorGraph::DFS(Uint32 vx, Uint32 n)
{
semi[vx] = ++n;
vertex[n] = label[vx] = vx;
ancestor[vx] = child[vx] = 0;
size[vx] = 1;
ControlNode& node = *controlGraph.dfsList[VtoG[vx]];
ControlEdge* successorEnd = node.getSuccessorsEnd();
for (ControlEdge* successorPtr = node.getSuccessorsBegin(); successorPtr < successorEnd; successorPtr++) {
Uint32 w = GtoV[successorPtr->getTarget().dfsNum];
if (semi[w] == 0) {
parent[w] = vx;
n = DFS(w, n);
}
}
return n;
}
void DominatorGraph::LINK(Uint32 vx, Uint32 w)
{
Uint32 s = w;
while (semi[label[w]] < semi[label[child[s]]]) {
if (size[s] + size[child[child[s]]] >= (size[child[s]] << 1)) {
ancestor[child[s]] = s;
child[s] = child[child[s]];
} else {
size[child[s]] = size[s];
s = ancestor[s] = child[s];
}
}
label[s] = label[w];
size[vx] += size[w];
if(size[vx] < (size[w] << 1)) {
Uint32 t = s;
s = child[vx];
child[vx] = t;
}
while( s != 0 ) {
ancestor[s] = vx;
s = child[s];
}
}
void DominatorGraph::COMPRESS(Uint32 vx)
{
if(ancestor[ancestor[vx]] != 0) {
COMPRESS(ancestor[vx]);
if(semi[label[ancestor[vx]]] < semi[label[vx]])
label[vx] = label[ancestor[vx]];
ancestor[vx] = ancestor[ancestor[vx]];
}
}
Uint32 DominatorGraph::EVAL(Uint32 vx)
{
if(ancestor[vx] == 0)
return label[vx];
COMPRESS(vx);
return (semi[label[ancestor[vx]]] >= semi[label[vx]]) ? label[vx] : label[ancestor[vx]];
}
void DominatorGraph::build()
{
Uint32 n = DFS(GtoV[0], 0);
size[0] = label[0] = semi[0];
for (Uint32 i = n; i >= 2; i--) {
Uint32 w = vertex[i];
ControlNode& node = *controlGraph.dfsList[VtoG[w]];
const DoublyLinkedList<ControlEdge>& predecessors = node.getPredecessors();
for (DoublyLinkedList<ControlEdge>::iterator p = predecessors.begin(); !predecessors.done(p); p = predecessors.advance(p)) {
Uint32 vx = GtoV[predecessors.get(p).getSource().dfsNum];
Uint32 u = EVAL(vx);
if(semi[u] < semi[w])
semi[w] = semi[u];
}
DGLinkedList* elem = new DGLinkedList();
elem->next = bucket[vertex[semi[w]]];
elem->index = w;
bucket[vertex[semi[w]]] = elem;
LINK(parent[w], w);
elem = bucket[parent[w]];
while(elem != NULL) {
Uint32 vx = elem->index;
Uint32 u = EVAL(vx);
dom[vx] = (semi[u] < semi[vx]) ? u : parent[w];
elem = elem->next;
}
}
memset(size, '\0', n * sizeof(Uint32));
Pool& pool = controlGraph.pool;
nodes = new(pool) DGNode[n];
for(Uint32 j = 2; j <= n; j++) {
Uint32 w = vertex[j];
Uint32 d = dom[w];
if(d != vertex[semi[w]]) {
d = dom[d];
dom[w] = d;
}
size[d]++;
}
dom[GtoV[0]] = 0;
for (Uint32 k = 1; k <= n; k++) {
DGNode& node = nodes[VtoG[k]];
Uint32 count = size[k];
node.successorsEnd = node.successorsBegin = (count) ? new(pool) Uint32[count] : (Uint32*) 0;
}
for (Uint32 l = 2; l <= n; l++)
*(nodes[VtoG[dom[l]]].successorsEnd)++ = VtoG[l];
}
#ifdef DEBUG_LOG
void DominatorGraph::printPretty(LogModuleObject log)
{
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Dominator Graph:\n"));
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 i = 0; i < nNodes; i++) {
DGNode& node = nodes[i];
if (node.successorsBegin != node.successorsEnd) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tN%d dominates ", i));
for (Uint32* successorsPtr = node.successorsBegin; successorsPtr < node.successorsEnd; successorsPtr++)
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("N%d ", *successorsPtr));
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
}
}
#endif // DEBUG_LOG

View File

@@ -1,80 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 _DOMINATOR_GRAPH_H_
#define _DOMINATOR_GRAPH_H_
#include "LogModule.h"
class ControlGraph;
struct DGNode
{
Uint32* successorsBegin;
Uint32* successorsEnd;
};
struct DGLinkedList
{
DGLinkedList* next;
Uint32 index;
};
class DominatorGraph
{
private:
ControlGraph& controlGraph;
Uint32 vCount;
Uint32* VtoG;
Uint32* GtoV;
Uint32* parent;
Uint32* semi;
Uint32* vertex;
Uint32* label;
Uint32* size;
Uint32* ancestor;
Uint32* child;
Uint32* dom;
DGLinkedList** bucket;
DGNode* nodes;
private:
void build();
Uint32 DFS(Uint32 vx, Uint32 n);
void LINK(Uint32 vx, Uint32 w);
void COMPRESS(Uint32 vx);
Uint32 EVAL(Uint32 vx);
public:
DominatorGraph(ControlGraph& controlGraph);
Uint32* getSuccessorsBegin(Uint32 n) const {return nodes[n].successorsBegin;}
Uint32* getSuccessorsEnd(Uint32 n) const {return nodes[n].successorsEnd;}
#ifdef DEBUG_LOG
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
#endif // _DOMINATOR_GRAPH_H_

View File

@@ -1,97 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 _HASH_SET_H_
#define _HASH_SET_H_
#include "Fundamentals.h"
#include "Pool.h"
#include <string.h>
struct HashSetElement
{
Uint32 index;
HashSetElement* next;
};
class HashSet
{
private:
static const hashSize = 64;
// Return the hash code for the given element index.
static Uint32 getHashCode(Uint32 index) {return index & (hashSize - 1);} // Could be better !
private:
Pool& allocationPool;
HashSetElement** bucket;
HashSetElement* free;
private:
// No copy constructor.
HashSet(const HashSet&);
// No copy operator.
void operator = (const HashSet&);
public:
// Create a new HashSet.
inline HashSet(Pool& pool, Uint32 universeSize);
// Clear the hashset.
void clear();
// Clear the element for the given index.
void clear(Uint32 index);
// Set the element for the given index.
void set(Uint32 index);
// Return true if the element at index is a member.
bool test(Uint32 index) const;
// Union with the given hashset.
inline void or(const HashSet& set);
// Intersection with the given hashset.
inline void and(const HashSet& set);
// Difference with the given hashset.
inline void difference(const HashSet& set);
// Logical operators.
HashSet& operator |= (const HashSet& set) {or(set); return *this;}
HashSet& operator &= (const HashSet& set) {and(set); return *this;}
HashSet& operator -= (const HashSet& set) {difference(set); return *this;}
// Iterator to conform with the set API.
typedef HashSetElement* iterator;
// Return the iterator for the first element of this set.
iterator begin() const;
// Return the next iterator.
iterator advance(iterator pos) const;
// Return true if the iterator is at the end of the set.
bool done(iterator pos) const {return pos == NULL;}
};
inline HashSet::HashSet(Pool& pool, Uint32 /*universeSize*/)
: allocationPool(pool), free(NULL)
{
bucket = new(pool) HashSetElement*[hashSize];
memset(bucket, '\0', sizeof(HashSetElement*));
}
#endif // _HASH_SET_H_

View File

@@ -1,213 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 _INDEXED_POOL_H_
#define _INDEXED_POOL_H_
#include "Fundamentals.h"
#include <string.h>
#include <stdlib.h>
//------------------------------------------------------------------------------
// IndexedPool<IndexedObjectSubclass> is an indexed pool of objects. The
// template parameter 'IndexedObjectSubclass' must be a subclass of the struct
// IndexedObject.
//
// When the indexed pool is ask to allocate and initialize a new object (using
// the operator new(anIndexedPool) it will zero the memory used to store the
// object and initialize the field 'index' of this object to its position in
// the pool.
//
// An object allocated by the indexed pool can be freed by calling the method
// IndexedPool::release(IndexedElement& objectIndex).
//
// example:
//
// IndexedPool<IndexedElement> elementPool;
//
// IndexedElement& element1 = *new(elementPool) IndexedElement();
// IndexedElement& element2 = *new(elementPool) IndexedElement();
//
// indexedPool.release(element1);
// IndexedElement& element3 = *new(elementPool) IndexedElement();
//
// At this point element1 is no longer a valid object, element2 is at
// index 2 and element3 is at index 1.
//
//------------------------------------------------------------------------------
// IndexedObject -
//
template<class Object>
struct IndexedObject
{
Uint32 index; // Index in the pool.
Object* next; // Used to link IndexedObject together.
Uint32 getIndex() {return index;}
};
//------------------------------------------------------------------------------
// IndexedPool<IndexedObject> -
//
template <class IndexedObject>
class IndexedPool
{
private:
static const blockSize = 4; // Size of one block.
Uint32 nBlocks; // Number of blocks in the pool.
IndexedObject** block; // Array of block pointers.
IndexedObject* freeObjects; // Chained list of free IndexedObjects.
Uint32 nextIndex; // Index of the next free object in the last block.
private:
void allocateAnotherBlock();
IndexedObject& newObject();
public:
IndexedPool() : nBlocks(0), block(NULL), freeObjects(NULL), nextIndex(1) {}
~IndexedPool();
IndexedObject& get(Uint32 index) const;
void release(IndexedObject& object);
void setSize(Uint32 size) {assert(size < nextIndex); nextIndex = size;}
// Return the universe size.
Uint32 getSize() {return nextIndex;}
friend void* operator new(size_t, IndexedPool<IndexedObject>& pool); // Needs to call newObject().
};
// Free all the memory allocated for this object.
//
template <class IndexedObject>
IndexedPool<IndexedObject>::~IndexedPool()
{
for (Uint32 n = 0; n < nBlocks; n++)
free(&((IndexedObject **) &block[n][n*blockSize])[-(n + 1)]);
}
// Release the given. This object will be iserted in the chained
// list of free IndexedObjects. To minimize the fragmentation the chained list
// is ordered by ascending indexes.
//
template <class IndexedObject>
void IndexedPool<IndexedObject>::release(IndexedObject& object)
{
Uint32 index = object.index;
IndexedObject* list = freeObjects;
assert(&object == &get(index)); // Make sure that object is owned by this pool.
if (list == NULL) { // The list is empty.
freeObjects = &object;
object.next = NULL;
} else { // The list contains at least 1 element.
if (index < list->index) { // insert as first element.
freeObjects = &object;
object.next = list;
} else { // Find this object's place.
while ((list->next) != NULL && (list->next->index < index))
list = list->next;
object.next = list->next;
list->next = &object;
}
}
#ifdef DEBUG
// Sanity check to be sure that the list is correctly ordered.
for (IndexedObject* obj = freeObjects; obj != NULL; obj = obj->next)
if (obj->next != NULL)
assert(obj->index < obj->next->index);
#endif
}
// Create a new block of IndexedObjects. We will allocate the memory to
// store IndexedPool::blockSize IndexedObject and the new Array of block
// pointers.
// The newly created IndexedObjects will not be initialized.
//
template <class IndexedObject>
void IndexedPool<IndexedObject>::allocateAnotherBlock()
{
void* memory = (void *) malloc((nBlocks + 1) * sizeof(Uint32) + blockSize * sizeof(IndexedObject));
memcpy(memory, block, nBlocks * sizeof(Uint32));
block = (IndexedObject **) memory;
IndexedObject* objects = (IndexedObject *) &block[nBlocks + 1];
block[nBlocks] = &objects[-(nBlocks * blockSize)];
nBlocks++;
}
// Return the IndexedObject at the position 'index' in the pool.
//
template <class IndexedObject>
IndexedObject& IndexedPool<IndexedObject>::get(Uint32 index) const
{
Uint32 blockIndex = index / blockSize;
assert(blockIndex < nBlocks);
return block[blockIndex][index];
}
// Return the reference of an unused object in the pool.
//
template <class IndexedObject>
IndexedObject& IndexedPool<IndexedObject>::newObject()
{
if (freeObjects != NULL) {
IndexedObject& newObject = *freeObjects;
freeObjects = newObject.next;
return newObject;
}
Uint32 nextIndex = this->nextIndex++;
Uint32 blockIndex = nextIndex / blockSize;
while (blockIndex >= nBlocks)
allocateAnotherBlock();
IndexedObject& newObject = block[blockIndex][nextIndex];
newObject.index = nextIndex;
return newObject;
}
// Return the address of the next unsused object in the given
// indexed pool. The field index of the newly allocated object
// will be initialized to the corresponding index of this object
// in the pool.
//
template <class IndexedObject>
void* operator new(size_t size, IndexedPool<IndexedObject>& pool)
{
assert(size == sizeof(IndexedObject));
return (void *) &pool.newObject();
}
#endif // _INDEXED_POOL_H_

View File

@@ -1,258 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 _INTERFERENCE_GRAPH_H_
#define _INTERFERENCE_GRAPH_H_
#include "Fundamentals.h"
#include "ControlGraph.h"
#include "Primitives.h"
#include "Instruction.h"
#include "VirtualRegister.h"
#include "RegisterPressure.h"
#include "SparseSet.h"
#include <string.h>
struct InterferenceVector
{
Uint32 count;
InterferenceVector* next;
RegisterName* neighbors;
InterferenceVector() : count(0), next(NULL) {}
};
class RegisterAllocator;
template <class RegisterPressure>
class InterferenceGraph
{
private:
RegisterAllocator& registerAllocator;
RegisterPressure::Set* interferences;
InterferenceVector** vector;
Uint32* offset;
Uint32 rangeCount;
private:
// No copy constructor.
InterferenceGraph(const InterferenceGraph&);
// No copy operator.
void operator = (const InterferenceGraph&);
// Check if reg is a member of the universe.
void checkMember(RegisterName name) {assert(name < rangeCount);}
// Return the edge index for the interference between name1 and name2.
Uint32 getEdgeIndex(RegisterName name1, RegisterName name2);
public:
InterferenceGraph(RegisterAllocator& registerAllocator) : registerAllocator(registerAllocator) {}
// Calculate the interferences.
void build();
// Return true if reg1 and reg2 interfere.
bool interfere(RegisterName name1, RegisterName name2);
// Return the interference vector for the given register or NULL if there is none.
InterferenceVector* getInterferenceVector(RegisterName name) {return vector[name];}
// Set the interference between name1 and name2.
void setInterference(RegisterName name1, RegisterName name2);
// Set the interference vector for the given register.
void setInterferenceVector(RegisterName name, InterferenceVector* v) {vector[name] = v;}
#ifdef DEBUG_LOG
// Print the interferences.
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
template <class RegisterPressure>
void InterferenceGraph<RegisterPressure>::build()
{
Pool& pool = registerAllocator.pool;
Uint32 rangeCount = registerAllocator.rangeCount;
this->rangeCount = rangeCount;
// Initialize the structures.
//
offset = new(pool) Uint32[rangeCount + 1];
vector = new(pool) InterferenceVector*[rangeCount];
memset(vector, '\0', sizeof(InterferenceVector*) * rangeCount);
Uint32 o = 0;
offset[0] = 0;
for (Uint32 i = 1; i <= rangeCount; ++i) {
offset[i] = o;
o += i;
}
interferences = new(pool) RegisterPressure::Set(pool, (rangeCount * rangeCount) / 2);
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
RegisterName* name2range = registerAllocator.name2range;
LivenessInfo<RegisterPressure> liveness = Liveness<RegisterPressure>::analysis(controlGraph, rangeCount, name2range);
registerAllocator.liveness = liveness;
SparseSet currentLive(pool, rangeCount);
for (Uint32 n = 0; n < nNodes; n++) {
ControlNode& node = *nodes[n];
currentLive = liveness.liveOut[n];
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
InstructionDefine* definePtr;
// Handle the copy instruction to avoid unnecessary interference between the 2 registers.
if ((instruction.getFlags() & ifCopy) != 0) {
assert(useBegin != useEnd && useBegin[0].isRegister());
currentLive.clear(name2range[useBegin[0].getRegisterName()]);
}
// Create the interferences.
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName define = name2range[definePtr->getRegisterName()];
for (SparseSet::iterator e = currentLive.begin(); !currentLive.done(e); e = currentLive.advance(e)) {
RegisterName live = RegisterName(currentLive.get(e));
if ((live != define) && !interfere(live, define) && registerAllocator.canInterfere(live, define)) {
if (vector[define] == NULL)
vector[define] = new(pool) InterferenceVector();
vector[define]->count++;
if (vector[live] == NULL)
vector[live] = new(pool) InterferenceVector();
vector[live]->count++;
setInterference(live, define);
}
}
}
// Now update the liveness.
//
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
currentLive.clear(name2range[definePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
currentLive.set(name2range[usePtr->getRegisterName()]);
}
}
// Allocate the memory to store the interferences.
//
for (Uint32 e = 0; e < rangeCount; e++)
if (vector[e] != NULL) {
InterferenceVector& v = *vector[e];
v.neighbors = new(pool) RegisterName[v.count];
v.count = 0;
}
// Initialize the edges.
//
if (RegisterPressure::Set::isOrdered()) {
RegisterName name1 = RegisterName(0);
for (RegisterPressure::Set::iterator i = interferences->begin(); !interferences->done(i); i = interferences->advance(i)) {
Uint32 interferenceIndex = interferences->get(i);
while(interferenceIndex >= offset[name1 + 1])
name1 = RegisterName(name1 + 1);
assert((interferenceIndex >= offset[name1]) && (interferenceIndex < offset[name1 + 1]));
RegisterName name2 = RegisterName(interferenceIndex - offset[name1]);
assert(interfere(name1, name2));
InterferenceVector& vector1 = *vector[name1];
vector1.neighbors[vector1.count++] = name2;
InterferenceVector& vector2 = *vector[name2];
vector2.neighbors[vector2.count++] = name1;
}
} else {
trespass("not Implemented"); // FIX: need one more pass to initialize the vectors.
}
}
template <class RegisterPressure>
Uint32 InterferenceGraph<RegisterPressure>::getEdgeIndex(RegisterName name1, RegisterName name2)
{
checkMember(name1); checkMember(name2);
assert(name1 != name2); // This is not possible.
return (name1 < name2) ? offset[name2] + name1 : offset[name1] + name2;
}
template <class RegisterPressure>
void InterferenceGraph<RegisterPressure>::setInterference(RegisterName name1, RegisterName name2)
{
interferences->set(getEdgeIndex(name1, name2));
}
template <class RegisterPressure>
bool InterferenceGraph<RegisterPressure>::interfere(RegisterName name1, RegisterName name2)
{
return interferences->test(getEdgeIndex(name1, name2));
}
#ifdef DEBUG_LOG
template <class RegisterPressure>
void InterferenceGraph<RegisterPressure>::printPretty(LogModuleObject log)
{
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Interference Vectors:\n"));
for (Uint32 i = 1; i < rangeCount; i++) {
if (vector[i] != NULL) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tvr%d: (", i));
for (InterferenceVector* v = vector[i]; v != NULL; v = v->next)
for (Uint32 j = 0; j < v->count; j++) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%d", v->neighbors[j]));
if (v->next != NULL || j != (v->count - 1))
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (","));
}
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (")\n"));
}
}
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Interference Matrix:\n"));
for (RegisterName name1 = RegisterName(1); name1 < rangeCount; name1 = RegisterName(name1 + 1)) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\t%d:\t", name1));
for (RegisterName name2 = RegisterName(1); name2 < rangeCount; name2 = RegisterName(name2 + 1))
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%c", ((name1 != name2) && interfere(name1, name2)) ? '1' : '0'));
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
}
#endif // DEBUG_LOG
#endif // _INTERFERENCE_GRAPH_H_

View File

@@ -1,87 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 _LIVE_RANGE_H_
#define _LIVE_RANGE_H_
#include "Fundamentals.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Primitives.h"
#include "Instruction.h"
#include "RegisterAllocator.h"
#include "RegisterAllocatorTools.h"
template <class RegisterPressure>
struct LiveRange
{
static void build(RegisterAllocator& registerAllocator);
};
template <class RegisterPressure>
void LiveRange<RegisterPressure>::build(RegisterAllocator& registerAllocator)
{
// Intialize the lookup table.
//
Uint32 nameCount = registerAllocator.nameCount;
RegisterName* nameTable = new(registerAllocator.pool) RegisterName[2*nameCount];
RegisterName* rangeName = &nameTable[nameCount];
init(rangeName, nameCount);
// Walk the graph.
//
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
SparseSet destination(registerAllocator.pool, nameCount);
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
destination.clear();
for (InstructionList::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
Instruction& phiNode = phiNodes.get(i);
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
destination.set(findRoot(phiNode.getInstructionDefineBegin()[0].getRegisterName(), rangeName));
}
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& phiNode = phiNodes.get(p);
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
RegisterName destinationName = phiNode.getInstructionDefineBegin()[0].getRegisterName();
RegisterName destinationRoot = findRoot(destinationName, rangeName);
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++) {
assert(usePtr->isRegister());
RegisterName sourceName = usePtr->getRegisterName();
RegisterName sourceRoot = findRoot(sourceName, rangeName);
if (sourceRoot != destinationRoot && !destination.test(sourceRoot))
rangeName[sourceRoot] = destinationRoot;
}
}
}
registerAllocator.rangeCount = compress(registerAllocator.name2range, rangeName, nameCount, nameCount);
}
#endif // _LIVE_RANGE_H_

View File

@@ -1,163 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 _LIVE_RANGE_GRAPH_
#define _LIVE_RANGE_GRAPH_
#include "Fundamentals.h"
#include "Pool.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "RegisterTypes.h"
class RegisterAllocator;
template <class RegisterPressure>
class LiveRangeGraph
{
private:
RegisterAllocator& registerAllocator;
RegisterPressure::Set* edges;
Uint32 rangeCount;
public:
//
//
LiveRangeGraph(RegisterAllocator& registerAllocator) : registerAllocator(registerAllocator) {}
//
//
void build();
//
//
void addEdge(RegisterName name1, RegisterName name2);
//
//
bool haveEdge(RegisterName name1, RegisterName name2);
#ifdef DEBUG_LOG
//
//
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
template <class RegisterPressure>
void LiveRangeGraph<RegisterPressure>::build()
{
Pool& pool = registerAllocator.pool;
Uint32 rangeCount = registerAllocator.rangeCount;
this->rangeCount = rangeCount;
edges = new(pool) RegisterPressure::Set(pool, rangeCount * rangeCount);
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
RegisterName* name2range = registerAllocator.name2range;
LivenessInfo<RegisterPressure>& liveness = registerAllocator.liveness;
SparseSet currentLive(pool, rangeCount);
for (Uint32 n = 0; n < nNodes; n++) {
ControlNode& node = *nodes[n];
currentLive = liveness.liveOut[n];
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
InstructionDefine* definePtr;
if ((instruction.getFlags() & ifCopy) != 0) {
assert(useBegin != useEnd && useBegin[0].isRegister());
currentLive.clear(name2range[useBegin[0].getRegisterName()]);
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName define = name2range[definePtr->getRegisterName()];
for (SparseSet::iterator l = currentLive.begin(); !currentLive.done(l); l = currentLive.advance(l)) {
RegisterName live = RegisterName(currentLive.get(l));
if (define != live && registerAllocator.canInterfere(define, live))
addEdge(define, live);
}
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
currentLive.clear(name2range[definePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
currentLive.set(name2range[usePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName use = name2range[usePtr->getRegisterName()];
for (SparseSet::iterator l = currentLive.begin(); !currentLive.done(l); l = currentLive.advance(l)) {
RegisterName live = RegisterName(currentLive.get(l));
if (use != live && registerAllocator.canInterfere(use, live))
addEdge(use, live);
}
}
}
}
}
template <class RegisterPressure>
void LiveRangeGraph<RegisterPressure>::addEdge(RegisterName name1, RegisterName name2)
{
assert(name1 != name2);
edges->set(name1 * rangeCount + name2);
}
template <class RegisterPressure>
bool LiveRangeGraph<RegisterPressure>::haveEdge(RegisterName name1, RegisterName name2)
{
assert(name1 != name2);
return edges->test(name1 * rangeCount + name2);
}
#ifdef DEBUG_LOG
template <class RegisterPressure>
void LiveRangeGraph<RegisterPressure>::printPretty(LogModuleObject log)
{
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Live ranges graph:\n"));
for (RegisterName name1 = RegisterName(1); name1 < rangeCount; name1 = RegisterName(name1 + 1)) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\t%d:\t", name1));
for (RegisterName name2 = RegisterName(1); name2 < rangeCount; name2 = RegisterName(name2 + 1))
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%c", ((name1 != name2) && haveEdge(name1, name2)) ? '1' : '0'));
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
}
#endif // DEBUG_LOG
#endif // _LIVE_RANGE_GRAPH_

View File

@@ -1,301 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 _LIVENESS_H_
#define _LIVENESS_H_
#include "Fundamentals.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "RegisterTypes.h"
// ----------------------------------------------------------------------------
// LivenessInfo -
template <class RegisterPressure>
struct LivenessInfo
{
RegisterPressure::Set* liveIn;
RegisterPressure::Set* liveOut;
DEBUG_LOG_ONLY(Uint32 size);
#ifdef DEBUG_LOG
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
// ----------------------------------------------------------------------------
// Liveness
//
// The liveness is defined by the following data-flow equations:
//
// LiveIn(n) = LocalLive(n) U (LiveOut(n) - Killed(n)).
// LiveOut(n) = U LiveIn(s) (s a successor of n).
//
// where LocalLive(n) is the set of used registers in the block n, Killed(n)
// is the set of defined registers in the block n, LiveIn(n) is the set of
// live registers at the begining of the block n and LiveOut(n) is the set
// of live registers at the end of the block n.
//
//
// We will compute the liveness analysis in two stages:
//
// 1- Build LocalLive(n) (wich is an approximation of LiveIn(n)) and Killed(n)
// for each block n.
// 2- Perform a backward data-flow analysis to propagate the liveness information
// through the entire control-flow graph.
//
template <class RegisterPressure>
struct Liveness
{
static LivenessInfo<RegisterPressure> analysis(ControlGraph& controlGraph, Uint32 rangeCount, const RegisterName* name2range);
static LivenessInfo<RegisterPressure> analysis(ControlGraph& controlGraph, Uint32 nameCount);
};
template <class RegisterPressure>
LivenessInfo<RegisterPressure> Liveness<RegisterPressure>::analysis(ControlGraph& controlGraph, Uint32 rangeCount, const RegisterName* name2range)
{
Pool& pool = controlGraph.pool;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
// Allocate the temporary sets.
RegisterPressure::Set* killed = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
// Allocate the globals sets.
RegisterPressure::Set* liveIn = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
RegisterPressure::Set* liveOut = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
// First stage of the liveness analysis: Compute the sets LocalLive(stored in LiveIn) and Killed.
//
for (Uint32 n = 0; n < (nNodes - 1); n++) {
ControlNode& node = *nodes[n];
RegisterPressure::Set& currentLocalLive = liveIn[n];
RegisterPressure::Set& currentKilled = killed[n];
// Find the instructions contributions to the sets LocalLive and Killed.
//
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
// If a VirtualRegister is 'used' before being 'defined' then we add it to set LocalLive.
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
Uint32 index = name2range[usePtr->getRegisterName()];
if (!currentKilled.test(index))
currentLocalLive.set(index);
}
// If a Virtualregister is 'defined' then we add it to the set Killed.
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
currentKilled.set(name2range[definePtr->getRegisterName()]);
}
}
// Second stage of the liveness analysis: We propagate the LiveIn & LiveOut through the entire
// control-flow graph.
//
RegisterPressure::Set temp(pool, rangeCount);
bool changed;
do {
changed = false;
// For all nodes is this graph except the endNode.
for (Int32 n = (nNodes - 2); n >= 0; n--) {
ControlNode& node = *nodes[n];
RegisterPressure::Set& currentLiveIn = liveIn[n];
RegisterPressure::Set& currentLiveOut = liveOut[n];
// Compute temp = Union of LiveIn(s) (s a successor of this node) | usedByPhiNodes(n).
// temp will be the new LiveOut(n).
Uint32 nSuccessors = node.nSuccessors();
if (nSuccessors != 0) {
temp = liveIn[node.nthSuccessor(0).getTarget().dfsNum];
for (Uint32 s = 1; s < nSuccessors; s++)
temp |= liveIn[node.nthSuccessor(s).getTarget().dfsNum];
} else
temp.clear();
// If temp and LiveOut(n) differ then set LiveOut(n) = temp and recalculate the
// new LiveIn(n).
if (currentLiveOut != temp) {
currentLiveOut = temp;
temp -= killed[n]; // FIX: could be optimized with one call to unionDiff !
temp |= currentLiveIn;
if (currentLiveIn != temp) {
currentLiveIn = temp;
changed = true;
}
}
}
} while(changed);
LivenessInfo<RegisterPressure> liveness;
liveness.liveIn = liveIn;
liveness.liveOut = liveOut;
DEBUG_LOG_ONLY(liveness.size = nNodes);
return liveness;
}
template <class RegisterPressure>
LivenessInfo<RegisterPressure> Liveness<RegisterPressure>::analysis(ControlGraph& controlGraph, Uint32 nameCount)
{
Pool& pool = controlGraph.pool;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
// Allocate the temporary sets.
RegisterPressure::Set* killed = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
RegisterPressure::Set* usedByPhiNodes = NULL;
// Allocate the globals sets.
RegisterPressure::Set* liveIn = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
RegisterPressure::Set* liveOut = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
// First stage of the liveness analysis: Compute the sets LocalLive(stored in LiveIn) and Killed.
//
for (Uint32 n = 0; n < (nNodes - 1); n++) {
ControlNode& node = *nodes[n];
RegisterPressure::Set& currentLocalLive = liveIn[n];
RegisterPressure::Set& currentKilled = killed[n];
InstructionList& phiNodes = node.getPhiNodeInstructions();
if ((usedByPhiNodes == NULL) && !phiNodes.empty())
usedByPhiNodes = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& phiNode = phiNodes.get(p);
InstructionDefine& define = phiNode.getInstructionDefineBegin()[0];
currentKilled.set(define.getRegisterName());
typedef DoublyLinkedList<ControlEdge> ControlEdgeList;
const ControlEdgeList& predecessors = node.getPredecessors();
ControlEdgeList::iterator p = predecessors.begin();
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++, p = predecessors.advance(p))
if (usePtr->isRegister())
usedByPhiNodes[predecessors.get(p).getSource().dfsNum].set(usePtr->getRegisterName());
}
// Find the instructions contributions to the sets LocalLive and Killed.
//
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
// If a VirtualRegister is 'used' before being 'defined' then we add it to set LocalLive.
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
Uint32 index = usePtr->getRegisterName();
if (!currentKilled.test(index))
currentLocalLive.set(index);
}
// If a Virtualregister is 'defined' then we add it to the set Killed.
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
currentKilled.set(definePtr->getRegisterName());
}
}
// Second stage of the liveness analysis: We propagate the LiveIn & LiveOut through the entire
// control-flow graph.
//
RegisterPressure::Set temp(pool, nameCount);
bool changed;
do {
changed = false;
// For all nodes is this graph except the endNode.
for (Int32 n = (nNodes - 2); n >= 0; n--) {
ControlNode& node = *nodes[n];
RegisterPressure::Set& currentLiveIn = liveIn[n];
RegisterPressure::Set& currentLiveOut = liveOut[n];
// Compute temp = Union of LiveIn(s) (s a successor of this node) | usedByPhiNodes(n).
// temp will be the new LiveOut(n).
Uint32 nSuccessors = node.nSuccessors();
if (nSuccessors != 0) {
temp = liveIn[node.nthSuccessor(0).getTarget().dfsNum];
for (Uint32 s = 1; s < nSuccessors; s++)
temp |= liveIn[node.nthSuccessor(s).getTarget().dfsNum];
} else
temp.clear();
// Insert the phiNodes contribution.
if (usedByPhiNodes != NULL)
temp |= usedByPhiNodes[n];
// If temp and LiveOut(n) differ then set LiveOut(n) = temp and recalculate the
// new LiveIn(n).
if (currentLiveOut != temp) {
currentLiveOut = temp;
temp -= killed[n]; // FIX: could be optimized with one call to unionDiff !
temp |= currentLiveIn;
if (currentLiveIn != temp) {
currentLiveIn = temp;
changed = true;
}
}
}
} while(changed);
LivenessInfo<RegisterPressure> liveness;
liveness.liveIn = liveIn;
liveness.liveOut = liveOut;
DEBUG_LOG_ONLY(liveness.size = nNodes);
return liveness;
}
#ifdef DEBUG_LOG
template <class RegisterPressure>
void LivenessInfo<RegisterPressure>::printPretty(LogModuleObject log)
{
for (Uint32 n = 0; n < size; n++) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Node N%d:\n\tliveIn = ", n));
liveIn[n].printPretty(log);
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tliveOut = "));
liveOut[n].printPretty(log);
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
}
#endif // DEBUG_LOG
#endif // _LIVENESS_H_

View File

@@ -1,40 +0,0 @@
#! gmake
DEPTH = ../..
MODULE_NAME = RegisterAllocator
include $(DEPTH)/config/config.mk
INCLUDES += \
-I$(DEPTH)/Utilities/General \
-I$(DEPTH)/Utilities/zlib \
-I$(DEPTH)/Runtime/ClassReader \
-I$(DEPTH)/Runtime/NativeMethods \
-I$(DEPTH)/Runtime/System \
-I$(DEPTH)/Runtime/ClassInfo \
-I$(DEPTH)/Runtime/FileReader \
-I$(DEPTH)/Compiler/PrimitiveGraph \
-I$(DEPTH)/Compiler/FrontEnd \
-I$(DEPTH)/Compiler/Optimizer \
-I$(DEPTH)/Compiler/CodeGenerator \
-I$(DEPTH)/Compiler/CodeGenerator/md \
-I$(DEPTH)/Compiler/CodeGenerator/md/$(CPU_ARCH) \
-I$(DEPTH)/Compiler/RegisterAllocator \
-I$(DEPTH)/Driver/StandAloneJava \
-I$(DEPTH)/Debugger \
$(NULL)
CXXSRCS = \
RegisterAllocator.cpp \
RegisterAllocatorTools.cpp \
DominatorGraph.cpp \
VirtualRegister.cpp \
BitSet.cpp \
SparseSet.cpp \
$(NULL)
include $(DEPTH)/config/rules.mk
libs:: $(MODULE)

View File

@@ -1,392 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 _PHI_NODE_REMOVER_H_
#define _PHI_NODE_REMOVER_H_
#include "Fundamentals.h"
#include "Pool.h"
#include "ControlGraph.h"
#include "DominatorGraph.h"
#include "VirtualRegister.h"
#include "RegisterPressure.h"
#include "Liveness.h"
#include "Instruction.h"
#include "InstructionEmitter.h"
#include "SparseSet.h"
#include <string.h>
//------------------------------------------------------------------------------
// RegisterNameNode -
struct RegisterNameNode
{
RegisterNameNode* next;
RegisterName newName;
Uint32 nextPushed;
};
//------------------------------------------------------------------------------
// CopyData -
struct CopyData
{
RegisterName source;
RegisterClassKind classKind;
Uint32 useCount;
bool isLiveOut;
RegisterName sourceNameToUse;
RegisterName temporaryName;
RegisterNameNode* newName;
};
//------------------------------------------------------------------------------
// PhiNodeRemover<RegisterPressure> -
template <class RegisterPressure>
struct PhiNodeRemover
{
// Replace the phi nodes by copy instructions.
static void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
};
// Split some of the critical edges and return true if there are still some
// in the graph after that.
//
static bool splitCriticalEdges(ControlGraph& /*cg*/)
{
// FIX: not implemented.
return true;
}
inline void pushName(Pool& pool, RegisterNameNode** stack, SparseSet& pushed, Uint32* nodeListPointer, RegisterName oldName, RegisterName newName)
{
RegisterNameNode& newNode = *new(pool) RegisterNameNode();
if (pushed.test(oldName))
(*stack)->newName = newName;
else {
newNode.newName = newName;
newNode.nextPushed = *nodeListPointer;
*nodeListPointer = oldName;
newNode.next = *stack;
*stack = &newNode;
pushed.set(oldName);
}
}
template <class RegisterPressure>
void PhiNodeRemover<RegisterPressure>::replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
{
Pool& pool = controlGraph.pool;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
// Initialize the local variables.
//
// When we insert the copies we will also need to create new VirtualRegisters for
// the insertion of temporaries. The maximum number of temporary register will not
// exceed the number of phiNodes in the primitive graph.
Uint32 nameCount = vrManager.getSize();
Uint32 maxNameCount = nameCount;
for (Uint32 n = 0; n < nNodes; n++)
maxNameCount += nodes[n]->getPhiNodes().length();
// If the CFG contains some critical edges (backward edge which source has more than one
// outgoing edge and destination has more than one incomimg edge) then we need the liveness
// information to be able to insert temporary copies.
RegisterPressure::Set* liveOut = NULL;
if (splitCriticalEdges(controlGraph))
liveOut = Liveness<LowRegisterPressure>::analysis(controlGraph, nameCount).liveOut;
DominatorGraph dGraph(controlGraph);
SparseSet pushed(pool, maxNameCount);
SparseSet destinationList(pool, maxNameCount);
SparseSet workList(pool, maxNameCount);
CopyData* copyStats = new(pool) CopyData[maxNameCount];
memset(copyStats, '\0', maxNameCount*sizeof(CopyData));
struct NodeStack {
Uint32* next;
Uint32* limit;
Uint32 pushedList;
};
// Allocate the node stack and initialize the node stack pointer.
NodeStack* nodeStack = new(pool) NodeStack[nNodes + 1];
NodeStack* nodeStackPtr = nodeStack;
// We start by the begin node.
Uint32 startNode = 0;
Uint32* next = &startNode;
Uint32* limit = &startNode + 1;
while (true) {
if (next == limit) {
// If there are no more node in the sibling, we have to pop the current
// frame from the stack and update the copyStats of the pushed nodes.
//
if (nodeStackPtr == nodeStack)
// We are at the bottom of the stack and there are no more nodes
// to look at. We are done !
break;
--nodeStackPtr;
// We are done with all the children of this node in the dominator tree.
// We need to update the copy information of all the new names pushed
// during the walk over this node.
Uint32 pushedList = nodeStackPtr->pushedList;
while (pushedList != 0) {
Uint32 nextName = copyStats[pushedList].newName->nextPushed;
copyStats[pushedList].newName = copyStats[pushedList].newName->next;
pushedList = nextName;
}
// restore the previous frame.
next = nodeStackPtr->next;
limit = nodeStackPtr->limit;
} else {
Uint32 currentNode = *next++;
Uint32 pushedList = 0;
// Initialize the sets.
pushed.clear();
destinationList.clear();
// STEP1:
// Walk the instruction list and to replace all the instruction uses with their new name.
// If the instruction is a phi node and its defined register is alive at the end of this
// block then we push the defined register into the stack.
//
ControlNode& node = *nodes[currentNode];
RegisterPressure::Set* currentLiveOut = (liveOut != NULL) ? &liveOut[currentNode] : (RegisterPressure::Set*) 0;
InstructionList& phiNodes = node.getPhiNodeInstructions();
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& phiNode = phiNodes.get(p);
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++) {
assert(usePtr->isRegister());
RegisterName name = usePtr->getRegisterName();
if (copyStats[name].newName != NULL && copyStats[name].newName->newName != name)
usePtr->setRegisterName(copyStats[name].newName->newName);
}
if (currentLiveOut != NULL) {
// This is a phi node and we have to push its defined name if it is live
// at the end of the node. We only need to do this if the CFG has critical edges.
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
RegisterName name = phiNode.getInstructionDefineBegin()[0].getRegisterName();
if (currentLiveOut->test(name))
pushName(pool, &(copyStats[name].newName), pushed, &pushedList, name, name);
}
}
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName name = usePtr->getRegisterName();
if (copyStats[name].newName != NULL && copyStats[name].newName->newName != name)
usePtr->setRegisterName(copyStats[name].newName->newName);
}
}
// STEP2:
// Look at this node's successors' phiNodes. We keep track of the number of time
// a VR will be used by another copy instruction and insert each definition into the
// destinationList. This is the only pass over this node's successors as we will
// get all the information we need in the CopyData structures.
//
ControlEdge* successorEdgeEnd = node.getSuccessorsEnd();
for (ControlEdge* successorEdgePtr = node.getSuccessorsBegin(); successorEdgePtr < successorEdgeEnd; successorEdgePtr++) {
Uint32 useIndex = successorEdgePtr->getIndex();
ControlNode& successor = successorEdgePtr->getTarget();
// Look at its phi nodes. The phi nodes are at the top of the instruction list. We exit
// as soon as we find an instruction which is not a phi node
InstructionList& phiNodes = successor.getPhiNodeInstructions();
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& phiNode = phiNodes.get(p);
assert((phiNode.getInstructionUseBegin() + useIndex) < phiNode.getInstructionUseEnd());
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd());
InstructionUse& source = phiNode.getInstructionUseBegin()[useIndex];
InstructionDefine& destination = phiNode.getInstructionDefineBegin()[0];
assert(source.isRegister() && destination.isRegister());
RegisterName sourceName = source.getRegisterName();
RegisterName destinationName = destination.getRegisterName();
// Get the correct name for the source.
if (copyStats[sourceName].newName != NULL)
sourceName = copyStats[sourceName].newName->newName;
// Update the CopyData structures.
if ((sourceName != rnInvalid) && (sourceName != destinationName)) {
copyStats[destinationName].source = sourceName;
copyStats[destinationName].classKind = destination.getRegisterClass();
copyStats[destinationName].isLiveOut = (currentLiveOut != NULL) ? currentLiveOut->test(destinationName) : false;
copyStats[destinationName].sourceNameToUse = destinationName;
copyStats[sourceName].sourceNameToUse = sourceName;
copyStats[sourceName].useCount++;
destinationList.set(destinationName);
}
}
}
// STEP3:
// Insert into the worklist only the destination registers that will be not used in
// another copy instruction in this block.
//
assert(workList.getSize() == 0);
for (SparseSet::iterator d = destinationList.begin(); !destinationList.done(d); d = destinationList.advance(d)) {
Uint32 dest = destinationList.get(d);
if (copyStats[dest].useCount == 0)
workList.set(dest);
}
// STEP4:
// Insert the copy instructions.
//
Uint32 destinationListSize = destinationList.getSize();
InstructionList::iterator endOfTheNode = instructions.end();
// Find the right place to insert the copy instructions.
if (destinationListSize != 0)
while (instructions.get(endOfTheNode).getFlags() & ifControl)
endOfTheNode = instructions.retreat(endOfTheNode);
while (destinationListSize != 0) {
while(workList.getSize()) {
RegisterName destinationName = RegisterName(workList.getOne());
RegisterName sourceName = copyStats[destinationName].source;
workList.clear(destinationName);
if (copyStats[destinationName].isLiveOut && !copyStats[destinationName].temporaryName) {
// Lost copy problem.
copyStats[destinationName].isLiveOut = false;
RegisterName sourceName = destinationName;
RegisterClassKind classKind = copyStats[sourceName].classKind;
RegisterName destinationName = getName(vrManager.newVirtualRegister(classKind));
assert(destinationName < maxNameCount);
copyStats[destinationName].classKind = classKind;
copyStats[sourceName].useCount = 0;
// We need to insert a copy to a temporary register to keep the
// source register valid at the end of the node defining it.
// This copy will be inserted right after the phi node defining it.
RegisterName from = copyStats[sourceName].sourceNameToUse;
Instruction* definingPhiNode = vrManager.getVirtualRegister(from).getDefiningInstruction();
assert(definingPhiNode && (definingPhiNode->getFlags() & ifPhiNode) != 0);
RegisterID fromID = buildRegisterID(from, classKind);
RegisterID toID = buildRegisterID(destinationName, classKind);
Instruction& copy = emitter.newCopy(*definingPhiNode->getPrimitive(), fromID, toID);
vrManager.getVirtualRegister(destinationName).setDefiningInstruction(copy);
definingPhiNode->getPrimitive()->getContainer()->getInstructions().addFirst(copy);
copyStats[sourceName].temporaryName = destinationName;
copyStats[sourceName].sourceNameToUse = destinationName;
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
}
// Insert the copy instruction at the end of the current node.
RegisterName from = copyStats[sourceName].sourceNameToUse;
RegisterClassKind classKind = copyStats[destinationName].classKind;
RegisterID fromID = buildRegisterID(from, classKind);
RegisterID toID = buildRegisterID(destinationName, classKind);
Instruction& copy = emitter.newCopy(*vrManager.getVirtualRegister(from).getDefiningInstruction()->getPrimitive(), fromID, toID);
instructions.insertAfter(copy, endOfTheNode);
endOfTheNode = instructions.advance(endOfTheNode);
copyStats[sourceName].useCount = 0;
if (destinationList.test(sourceName) && copyStats[sourceName].isLiveOut)
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
copyStats[sourceName].isLiveOut = false;
copyStats[sourceName].sourceNameToUse = destinationName;
if (destinationList.test(sourceName))
workList.set(sourceName);
destinationList.clear(destinationName);
}
destinationListSize = destinationList.getSize();
if (destinationListSize != 0) {
RegisterName sourceName = RegisterName(destinationList.getOne());
RegisterName destinationName;
if (!copyStats[sourceName].temporaryName) {
// Cycle problem.
RegisterClassKind classKind = copyStats[sourceName].classKind;
destinationName = getName(vrManager.newVirtualRegister(classKind));
assert(destinationName < maxNameCount);
copyStats[destinationName].classKind = classKind;
copyStats[sourceName].temporaryName = destinationName;
// Insert the copy instruction at the end of the current node.
RegisterName from = copyStats[sourceName].sourceNameToUse;
RegisterID fromID = buildRegisterID(from, classKind);
RegisterID toID = buildRegisterID(destinationName, classKind);
Instruction& copy = emitter.newCopy(*vrManager.getVirtualRegister(from).getDefiningInstruction()->getPrimitive(), fromID, toID);
vrManager.getVirtualRegister(destinationName).setDefiningInstruction(copy);
instructions.insertAfter(copy, endOfTheNode);
endOfTheNode = instructions.advance(endOfTheNode);
} else
destinationName = copyStats[sourceName].temporaryName;
copyStats[sourceName].useCount = 0;
copyStats[sourceName].isLiveOut = false;
copyStats[sourceName].sourceNameToUse = destinationName;
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
workList.set(sourceName);
}
}
nodeStackPtr->pushedList = pushedList;
nodeStackPtr->next = next;
nodeStackPtr->limit = limit;
++nodeStackPtr;
next = dGraph.getSuccessorsBegin(currentNode);
limit = dGraph.getSuccessorsEnd(currentNode);
}
}
}
#endif // _PHI_NODE_REMOVER_H_

View File

@@ -1,155 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 "Fundamentals.h"
#include "LogModule.h"
#include "RegisterAllocator.h"
#include "RegisterPressure.h"
#include "RegisterAllocatorTools.h"
#include "PhiNodeRemover.h"
#include "LiveRange.h"
#include "Liveness.h"
#include "InterferenceGraph.h"
#include "LiveRangeGraph.h"
#include "Coalescing.h"
#include "Spilling.h"
#include "Coloring.h"
#include "Splits.h"
class Pool;
class ControlGraph;
class VirtualRegisterManager;
class InstructionEmitter;
UT_DEFINE_LOG_MODULE(RegAlloc);
void RegisterAllocator::allocateRegisters(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
{
// Insert the phi node instructions. We want to do this to have a single defined register per instruction.
// If we keep the PhiNode (as a DataNode) and a PhiNode is of DoubleWordKind then we have to execute
// some special code for the high word annotation.
//
RegisterAllocatorTools::insertPhiNodeInstructions(controlGraph, emitter);
// Perform some tests on the instruction graph.
//
DEBUG_ONLY(RegisterAllocatorTools::testTheInstructionGraph(controlGraph, vrManager));
// Replace the phi node instructions by their equivalent copy instructions.
//
PhiNodeRemover<LowRegisterPressure>::replacePhiNodes(controlGraph, vrManager, emitter);
// Do the register allocation.
//
RegisterAllocator registerAllocator(pool, controlGraph, vrManager, emitter);
registerAllocator.doGraphColoring();
}
void RegisterAllocator::doGraphColoring()
{
// Initialize the liverange map.
//
initLiveRanges();
// Build the live ranges. We do this to compress the number of RegisterNames
// used in the insterference graph.
//
LiveRange<LowRegisterPressure>::build(*this);
// Remove unnecessary copies.
//
RegisterAllocatorTools::removeUnnecessaryCopies(*this);
for (Uint8 loop = 0; loop < 10; loop++) {
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("********* RegisterAllocator loop %d *********\n", loop));
while(true) {
// Build the interference graph.
//
iGraph.build();
// Coalesce the copy instructions.
//
if (!Coalescing<LowRegisterPressure>::coalesce(*this))
break;
}
// Print the interference graph.
//
DEBUG_LOG_ONLY(iGraph.printPretty(UT_LOG_MODULE(RegAlloc)));
// Calculate the spill costs.
//
Spilling<LowRegisterPressure>::calculateSpillCosts(*this);
DEBUG_LOG_ONLY(RegisterAllocatorTools::printSpillCosts(*this));
// Calculate the split costs.
//
Splits<LowRegisterPressure>::calculateSplitCosts(*this);
DEBUG_LOG_ONLY(RegisterAllocatorTools::printSplitCosts(*this));
// Build the live range graph.
//
lGraph.build();
DEBUG_LOG_ONLY(lGraph.printPretty(UT_LOG_MODULE(RegAlloc)));
// Color the graph. If it succeeds then we're done with the
// register allocation.
//
if (Coloring<LowRegisterPressure>::color(*this)) {
// Write the final colors in the instruction graph.
//
Coloring<LowRegisterPressure>::finalColoring(*this);
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("********** RegisterAllocator done **********\n"));
DEBUG_LOG_ONLY(RegisterAllocatorTools::printInstructions(*this));
return;
}
// We need to spill some registers.
//
Spilling<LowRegisterPressure>::insertSpillCode(*this);
// Insert the split instructions.
//
Splits<LowRegisterPressure>::insertSplitCode(*this);
// Update the live ranges.
//
// FIX
}
#ifdef DEBUG_LOG
RegisterAllocatorTools::updateInstructionGraph(*this);
RegisterAllocatorTools::printInstructions(*this);
#endif
fprintf(stderr, "!!! Coloring failed after 10 loops !!!\n");
abort();
}
void RegisterAllocator::initLiveRanges()
{
Uint32 count = this->nameCount;
RegisterName* name2range = new(pool) RegisterName[nameCount];
for (RegisterName r = RegisterName(1); r < count; r = RegisterName(r + 1))
name2range[r] = r;
this->name2range = name2range;
rangeCount = count;
}

View File

@@ -1,88 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 _REGISTER_ALLOCATOR_H_
#define _REGISTER_ALLOCATOR_H_
class Pool;
class ControlGraph;
class InstructionEmitter;
struct SpillCost;
struct SplitCost;
#include "Liveness.h"
#include "VirtualRegister.h"
#include "RegisterPressure.h" // This should included by Backend.cpp
#include "InterferenceGraph.h"
#include "LiveRangeGraph.h"
//template <class RegisterPressure>
class RegisterAllocator
{
public:
Pool& pool; //
ControlGraph& controlGraph; //
VirtualRegisterManager& vrManager; //
InstructionEmitter& emitter; //
RegisterName* name2range; //
RegisterName* color; //
SpillCost* spillCost; //
SparseSet* willSpill; //
SplitCost* splitCost; //
NameLinkedList** splitAround; //
InterferenceGraph<LowRegisterPressure> iGraph; //
LiveRangeGraph<LowRegisterPressure> lGraph; //
LivenessInfo<LowRegisterPressure> liveness; //
Uint32 nameCount; //
Uint32 rangeCount; //
bool splitFound; //
private:
//
//
void doGraphColoring();
public:
//
//
inline RegisterAllocator(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
//
//
bool canInterfere(RegisterName /*name1*/, RegisterName /*name2*/) const {return true;}
//
//
void initLiveRanges();
//
//
static void allocateRegisters(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
};
//
//
inline RegisterAllocator::RegisterAllocator(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
: pool(pool), controlGraph(controlGraph), vrManager(vrManager), emitter(emitter), iGraph(*this), lGraph(*this), nameCount(vrManager.getSize()) {}
#endif // _REGISTER_ALLOCATOR_H_

View File

@@ -1,355 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 "Fundamentals.h"
#include "LogModule.h"
#include "RegisterAllocatorTools.h"
#include "Pool.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Primitives.h"
#include "InstructionEmitter.h"
#include "Instruction.h"
#include "RegisterAllocator.h"
#include "Spilling.h"
#include "Splits.h"
#include "BitSet.h"
UT_EXTERN_LOG_MODULE(RegAlloc);
#ifdef DEBUG
void RegisterAllocatorTools::testTheInstructionGraph(ControlGraph& controlGraph, VirtualRegisterManager& vrManager)
{
// Test the declared VirtualRegisters. The register allocator tries to condense the register universe.
// Any gap in the VirtualRegister names will be a loss of efficiency !!!!
Uint32 nameCount = vrManager.getSize();
BitSet registerSeen(controlGraph.pool, nameCount);
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
registerSeen.set(usePtr->getRegisterName());
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
registerSeen.set(definePtr->getRegisterName());
}
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& instruction = phiNodes.get(p);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
registerSeen.set(usePtr->getRegisterName());
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
registerSeen.set(definePtr->getRegisterName());
}
}
bool renameRegisters = false;
for (BitSet::iterator i = registerSeen.nextZero(0); !registerSeen.done(i); i = registerSeen.nextZero(i)) {
renameRegisters = true;
fprintf(stderr,
"WARNING: The VirtualRegister vr%d has been allocated during CodeGeneration but\n"
" is never used nor defined by any instruction in the instruction graph\n"
" PLEASE FIX \n",
i);
}
if (renameRegisters) {
Instruction** definingInstruction = new Instruction*[nameCount];
memset(definingInstruction, '\0', nameCount * sizeof(Instruction*));
RegisterName* newName = new RegisterName[nameCount];
memset(newName, '\0', nameCount * sizeof(RegisterName));
RegisterName nextName = RegisterName(1);
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName name = usePtr->getRegisterName();
if (newName[name] == rnInvalid) {
newName[name] = nextName;
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
nextName = RegisterName(nextName + 1);
}
usePtr->setRegisterName(newName[name]);
}
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName name = definePtr->getRegisterName();
if (newName[name] == rnInvalid) {
newName[name] = nextName;
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
nextName = RegisterName(nextName + 1);
}
definePtr->setRegisterName(newName[name]);
}
}
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& instruction = phiNodes.get(p);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName name = usePtr->getRegisterName();
if (newName[name] == rnInvalid) {
newName[name] = nextName;
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
nextName = RegisterName(nextName + 1);
}
usePtr->setRegisterName(newName[name]);
}
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName name = definePtr->getRegisterName();
if (newName[name] == rnInvalid) {
newName[name] = nextName;
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
nextName = RegisterName(nextName + 1);
}
definePtr->setRegisterName(newName[name]);
}
}
}
vrManager.setSize(nextName);
for (RegisterName r = RegisterName(1); r < nextName; r = RegisterName(r + 1))
vrManager.getVirtualRegister(r).definingInstruction = definingInstruction[r];
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("RegisterMap:\n"));
for (Uint32 i = 1; i < nameCount; i++)
if (newName[i] != 0)
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tvr%d becomes vr%d.\n", i, newName[i]));
else
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tvr%d is dead.\n", i));
delete newName;
delete definingInstruction;
}
}
#endif // DEBUG
void RegisterAllocatorTools::removeUnnecessaryCopies(RegisterAllocator& registerAllocator)
{
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
RegisterName* name2range = registerAllocator.name2range;
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i);) {
Instruction& instruction = instructions.get(i);
i = instructions.advance(i);
if (instruction.getFlags() & ifCopy) {
assert(instruction.getInstructionUseBegin() != instruction.getInstructionUseEnd() && instruction.getInstructionUseBegin()[0].isRegister());
assert(instruction.getInstructionDefineBegin() != instruction.getInstructionDefineEnd() && instruction.getInstructionDefineBegin()[0].isRegister());
RegisterName source = name2range[instruction.getInstructionUseBegin()[0].getRegisterName()];
RegisterName destination = name2range[instruction.getInstructionDefineBegin()[0].getRegisterName()];
if (source == destination)
instruction.remove();
}
}
}
}
void RegisterAllocatorTools::updateInstructionGraph(RegisterAllocator& registerAllocator)
{
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
RegisterName* name2range = registerAllocator.name2range;
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
usePtr->setRegisterName(name2range[usePtr->getRegisterName()]);
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
definePtr->setRegisterName(name2range[definePtr->getRegisterName()]);
}
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& instruction = phiNodes.get(p);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
usePtr->setRegisterName(name2range[usePtr->getRegisterName()]);
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
definePtr->setRegisterName(name2range[definePtr->getRegisterName()]);
}
}
}
void RegisterAllocatorTools::insertPhiNodeInstructions(ControlGraph& controlGraph, InstructionEmitter& emitter)
{
Pool& pool = controlGraph.pool;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
ControlNode& node = *nodes[n];
DoublyLinkedList<PhiNode>& phiNodes = node.getPhiNodes();
if (!phiNodes.empty()) {
// Set the index of the incoming edges.
Uint32 index = 0;
const DoublyLinkedList<ControlEdge>& predecessors = node.getPredecessors();
for (DoublyLinkedList<ControlEdge>::iterator p = predecessors.begin(); !predecessors.done(p); p = predecessors.advance(p))
predecessors.get(p).setIndex(index++);
// Insert the phi node instruction in the instruction list.
for (DoublyLinkedList<PhiNode>::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
PhiNode& phiNode = phiNodes.get(i);
ValueKind kind = phiNode.getKind();
if (!isStorableKind(kind))
continue;
RegisterClassKind classKind = rckGeneral; // FIX: get class kind from phi node kind.
Uint32 nInputs = phiNode.nInputs();
PhiNodeInstruction& phiNodeInstruction = *new(pool) PhiNodeInstruction(&phiNode, pool, nInputs);
emitter.defineProducer(phiNode, phiNodeInstruction, 0, classKind, drLow);
for (Uint32 whichInput = 0; whichInput < nInputs; whichInput++)
emitter.useProducer(phiNode.nthInputVariable(whichInput), phiNodeInstruction, whichInput, classKind, drLow);
node.addPhiNodeInstruction(phiNodeInstruction);
if (isDoublewordKind(kind)) {
PhiNodeInstruction& phiNodeInstruction = *new(pool) PhiNodeInstruction(&phiNode, pool, nInputs);
emitter.defineProducer(phiNode, phiNodeInstruction, 0, classKind, drHigh);
for (Uint32 whichInput = 0; whichInput < nInputs; whichInput++)
emitter.useProducer(phiNode.nthInputVariable(whichInput), phiNodeInstruction, whichInput, classKind, drHigh);
node.addPhiNodeInstruction(phiNodeInstruction);
}
}
}
}
}
#ifdef DEBUG_LOG
void RegisterAllocatorTools::printSpillCosts(RegisterAllocator& registerAllocator)
{
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
Uint32 rangeCount = registerAllocator.rangeCount;
SpillCost* cost = registerAllocator.spillCost;
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Spill costs:\n"));
for (Uint32 i = 1; i < rangeCount; i++) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\trange %d : ", i));
if (cost[i].infinite)
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("infinite\n"));
else
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%f\n", cost[i].cost));
}
}
void RegisterAllocatorTools::printSplitCosts(RegisterAllocator& registerAllocator)
{
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
Uint32 rangeCount = registerAllocator.rangeCount;
SplitCost* cost = registerAllocator.splitCost;
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Split costs:\n"));
for (Uint32 i = 1; i < rangeCount; i++) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\trange %d : loads = %f stores = %f\n", i, cost[i].loads, cost[i].stores));
}
}
void RegisterAllocatorTools::printInstructions(RegisterAllocator& registerAllocator)
{
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
ControlNode** nodes = registerAllocator.controlGraph.dfsList;
Uint32 nNodes = registerAllocator.controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("N%d:\n", n));
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
InstructionList& instructions = nodes[n]->getInstructions();
if (!phiNodes.empty()) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" PhiNodes:\n", n));
for(InstructionList::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
phiNodes.get(i).printPretty(log);
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
if (!instructions.empty())
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" Instructions:\n", n));
}
for(InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
instructions.get(i).printPretty(log);
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
}
}
#endif // DEBUG_LOG

View File

@@ -1,117 +0,0 @@
// -*- mode:C++; tab-width:4; truncate-lines:t -*-
//
// CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF
// NETSCAPE COMMUNICATIONS CORPORATION
// Copyright © 1996, 1997 Netscape Communications Corporation. All Rights
// Reserved. Use of this Source Code is subject to the terms of the
// applicable license agreement from Netscape Communications Corporation.
// The copyright notice(s) in this Source Code does not indicate actual or
// intended publication of this Source Code.
//
// $Id: RegisterAllocatorTools.h,v 1.1.2.1 1999-03-02 16:12:05 fur%netscape.com Exp $
//
#ifndef _REGISTER_ALLOCATOR_TOOLS_H_
#define _REGISTER_ALLOCATOR_TOOLS_H_
#include "LogModule.h"
#include "RegisterTypes.h"
#include <string.h>
class RegisterAllocator;
class ControlGraph;
class InstructionEmitter;
class VirtualRegisterManager;
struct RegisterAllocatorTools
{
//
//
static void insertPhiNodeInstructions(ControlGraph& controlGraph, InstructionEmitter& emitter);
//
//
static void updateInstructionGraph(RegisterAllocator& registerAllocator);
//
//
static void removeUnnecessaryCopies(RegisterAllocator& registerAllocator);
#ifdef DEBUG
//
//
static void testTheInstructionGraph(ControlGraph& controlGraph, VirtualRegisterManager& vrManager);
#endif // DEBUG
#ifdef DEBUG_LOG
//
//
static void printInstructions(RegisterAllocator& registerAllocator);
//
//
static void printSpillCosts(RegisterAllocator& registerAllocator);
//
//
static void printSplitCosts(RegisterAllocator& registerAllocator);
#endif // DEBUG_LOG
};
//
// FIX: this should go in a class (LookupTable ?)
//
inline RegisterName findRoot(RegisterName name, RegisterName* table)
{
RegisterName* stack = table;
RegisterName* stackPtr = stack;
RegisterName newName;
while((newName = table[name]) != name) {
*--stackPtr = name;
name = newName;
}
while (stackPtr != stack)
table[*stackPtr++] = name;
return name;
}
inline void init(RegisterName* table, Uint32 nameCount)
{
for (RegisterName r = RegisterName(0); r < nameCount; r = RegisterName(r + 1))
table[r] = r;
}
inline Uint32 compress(RegisterName* name2range, RegisterName* table, Uint32 nameCount, Uint32 tableSize)
{
RegisterName* liveRange = new RegisterName[tableSize];
memset(liveRange, '\0', tableSize * sizeof(RegisterName));
// Update the lookup table.
for (RegisterName r = RegisterName(1); r < tableSize; r = RegisterName(r + 1))
findRoot(r, table);
// Count the liveranges.
Uint32 liveRangeCount = 1;
for (RegisterName s = RegisterName(1); s < tableSize; s = RegisterName(s + 1))
if (table[s] == s)
liveRange[s] = RegisterName(liveRangeCount++);
for (RegisterName t = RegisterName(1); t < nameCount; t = RegisterName(t + 1))
name2range[t] = liveRange[table[name2range[t]]];
return liveRangeCount;
}
inline double doLog10(Uint32 power)
{
double log = 1.0;
while (power--)
log *= 10.0;
return log;
}
#endif // _REGISTER_ALLOCATOR_TOOLS_H_

View File

@@ -1,104 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 _REGISTER_TYPES_H_
#define _REGISTER_TYPES_H_
#include "Fundamentals.h"
//------------------------------------------------------------------------------
// RegisterName -
//
enum RegisterName {
rnInvalid = 0,
};
//------------------------------------------------------------------------------
// RegisterClassKind -
//
enum RegisterClassKind {
rckInvalid = 0,
rckGeneral,
rckStackSlot,
nRegisterClassKind
};
//------------------------------------------------------------------------------
// RegisterID -
//
enum RegisterID {
invalidID = 0
};
//------------------------------------------------------------------------------
// RegisterKind -
//
enum RegisterKind {
rkCallerSave = 0,
rkCalleeSave,
};
struct NameLinkedList {
RegisterName name;
NameLinkedList* next;
};
#ifdef DEBUG
const registerNameMask = 0x03ffffff;
const coloredRegisterMask = 0x04000000;
const machineRegisterMask = 0x08000000;
const registerClassMask = 0xf0000000;
const registerNameShift = 0;
const coloredRegisterShift = 26;
const machineRegisterShift = 27;
const registerClassShift = 28;
#else // DEBUG
const registerNameMask = 0x0fffffff;
const registerClassMask = 0xf0000000;
const registerNameShift = 0;
const registerClassShift = 28;
#endif // DEBUG
inline RegisterClassKind getClass(RegisterID registerID) {return RegisterClassKind((registerID & registerClassMask) >> registerClassShift);}
inline RegisterName getName(RegisterID registerID) {return RegisterName((registerID & registerNameMask) >> registerNameShift);}
inline void setClass(RegisterID& registerID, RegisterClassKind classKind) {registerID = RegisterID((registerID & ~registerClassMask) | ((classKind << registerClassShift) & registerClassMask));}
inline void setName(RegisterID& registerID, RegisterName name) {assert((name & ~registerNameMask) == 0); registerID = RegisterID((registerID & ~registerNameMask) | ((name << registerNameShift) & registerNameMask));}
inline RegisterID buildRegisterID(RegisterName name, RegisterClassKind classKind) {return RegisterID(((classKind << registerClassShift) & registerClassMask) | ((name << registerNameShift) & registerNameMask));}
#ifdef DEBUG
inline bool isMachineRegister(RegisterID rid) {return (rid & machineRegisterMask) != 0;}
inline void setMachineRegister(RegisterID& rid) {rid = RegisterID(rid | machineRegisterMask);}
inline bool isColoredRegister(RegisterID rid) {return (rid & coloredRegisterMask) != 0;}
inline void setColoredRegister(RegisterID& rid) {rid = RegisterID(rid | coloredRegisterMask);}
#endif // DEBUG
#endif // _REGISTER_TYPES_H_

View File

@@ -1,168 +0,0 @@
// -*- mode:C++; tab-width:4; truncate-lines:t -*-
//
// CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF
// NETSCAPE COMMUNICATIONS CORPORATION
// Copyright © 1996, 1997 Netscape Communications Corporation. All Rights
// Reserved. Use of this Source Code is subject to the terms of the
// applicable license agreement from Netscape Communications Corporation.
// The copyright notice(s) in this Source Code does not indicate actual or
// intended publication of this Source Code.
//
// $Id: SparseSet.h,v 1.1.2.1 1999-03-02 16:12:07 fur%netscape.com Exp $
//
#ifndef _SPARSE_SET_H_
#define _SPARSE_SET_H_
#include "Fundamentals.h"
#include "Pool.h"
#include "LogModule.h"
#include "BitSet.h"
class SparseSet
{
private:
struct Node {
Uint32 element;
Uint32 stackIndex;
};
Node* node;
Uint32 count;
Uint32 universeSize;
private:
// No copy constructor.
SparseSet(const SparseSet&);
// Check if the given set's universe is of the same size than this universe.
void checkUniverseCompatibility(const SparseSet& set) const {assert(set.universeSize == universeSize);}
// Check if pos is valid for this set's universe.
void checkMember(Int32 pos) const {assert(pos >=0 && Uint32(pos) < universeSize);}
public:
SparseSet(Pool& pool, Uint32 universeSize) : universeSize(universeSize) {node = new(pool) Node[universeSize]; clear();}
// Clear the sparse set.
void clear() {count = 0;}
// Clear the element at index.
inline void clear(Uint32 index);
// Set the element at index.
inline void set(Uint32 index);
// Return true if the element at index is set.
inline bool test(Uint32 index) const;
// Union with the given sparse set.
inline void or(const SparseSet& set);
// Intersection with the given sparse set.
inline void and(const SparseSet& set);
// Difference with the given sparse set.
inline void difference(const SparseSet& set);
// Copy set.
inline SparseSet& operator = (const SparseSet& set);
inline SparseSet& operator = (const BitSet& set);
// Return true if the sparse sets are identical.
friend bool operator == (const SparseSet& set1, const SparseSet& set2);
// Return true if the sparse sets are different.
friend bool operator != (const SparseSet& set1, const SparseSet& set2);
// Logical operators.
SparseSet& operator |= (const SparseSet& set) {or(set); return *this;}
SparseSet& operator &= (const SparseSet& set) {and(set); return *this;}
SparseSet& operator -= (const SparseSet& set) {difference(set); return *this;}
// Iterator to conform with the set API.
typedef Int32 iterator;
// Return the iterator for the first element of this set.
iterator begin() const {return count - 1;}
// Return the next iterator.
iterator advance(iterator pos) const {return --pos;}
// Return true if the iterator is at the end of the set.
bool done(iterator pos) const {return pos < 0;}
// Return the element for the given iterator;
Uint32 get(iterator pos) const {return node[pos].element;}
// Return one element of this set.
Uint32 getOne() const {assert(count > 0); return node[0].element;}
// Return the size of this set.
Uint32 getSize() const {return count;}
#ifdef DEBUG_LOG
// Print the set.
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
inline void SparseSet::clear(Uint32 element)
{
checkMember(element);
Uint32 count = this->count;
Node* node = this->node;
Uint32 stackIndex = node[element].stackIndex;
if ((stackIndex < count) && (node[stackIndex].element == element)) {
Uint32 stackTop = node[count - 1].element;
node[stackIndex].element = stackTop;
node[stackTop].stackIndex = stackIndex;
this->count = count - 1;
}
}
inline void SparseSet::set(Uint32 element)
{
checkMember(element);
Uint32 count = this->count;
Node* node = this->node;
Uint32 stackIndex = node[element].stackIndex;
if ((stackIndex >= count) || (node[stackIndex].element != element)) {
node[count].element = element;
node[element].stackIndex = count;
this->count = count + 1;
}
}
inline bool SparseSet::test(Uint32 element) const
{
checkMember(element);
Node* node = this->node;
Uint32 stackIndex = node[element].stackIndex;
return ((stackIndex < count) && (node[stackIndex].element == element));
}
inline SparseSet& SparseSet::operator = (const SparseSet& set)
{
checkUniverseCompatibility(set);
Uint32 sourceCount = set.getSize();
Node* node = this->node;
memcpy(node, set.node, sourceCount * sizeof(Node));
for (Uint32 i = 0; i < sourceCount; i++) {
Uint32 element = node[i].element;
node[element].stackIndex = i;
}
count = sourceCount;
return *this;
}
inline SparseSet& SparseSet::operator = (const BitSet& set)
{
// FIX: there's room for optimization here.
assert(universeSize == set.getSize());
clear();
for (Int32 i = set.firstOne(); i != -1; i = set.nextOne(i))
this->set(i);
return *this;
}
#endif // _SPARSE_SET_H_

View File

@@ -1,270 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 NEW_LAURENTM_CODE
#define INCLUDE_EMITTER
#include "CpuInfo.h"
#include "Fundamentals.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "InstructionEmitter.h"
#include "Spilling.h"
void Spilling::
insertSpillCode(ControlNode** dfsList, Uint32 nNodes)
{
PRUint32 nVirtualRegisters = vRegManager.count();
FastBitSet currentLive(vRegManager.pool, nVirtualRegisters);
FastBitSet usedInThisInstruction(vRegManager.pool, nVirtualRegisters);
RegisterFifo grNeedLoad(nVirtualRegisters);
RegisterFifo fpNeedLoad(nVirtualRegisters);
for (PRInt32 n = nNodes - 1; n >= 0; n--)
{
PR_ASSERT(grNeedLoad.empty() & fpNeedLoad.empty());
ControlNode& node = *dfsList[n];
currentLive = node.liveAtEnd;
PRUint32 nGeneralAlive = 0;
PRUint32 nFloatingPointAlive = 0;
// Get the number of registers alive at the end of this node.
for (PRInt32 j = currentLive.firstOne(); j != -1; j = currentLive.nextOne(j))
{
VirtualRegister& vReg = vRegManager.getVirtualRegister(j);
if (vReg.spillInfo.willSpill)
{
currentLive.clear(j);
}
else
{
switch (vReg.getClass())
{
case vrcInteger:
nGeneralAlive++;
break;
case vrcFloatingPoint:
case vrcFixedPoint:
nFloatingPointAlive++;
break;
default:
break;
}
}
}
// if(node.dfsNum == 8) printf("\n________Begin Node %d________\n", node.dfsNum);
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i))
{
Instruction& instruction = instructions.get(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defEnd = instruction.getInstructionDefineEnd();
InstructionDefine* defPtr;
// if(node.dfsNum == 8) { printf("\n");
// instruction.printPretty(stdout);
// printf("\n"); }
// Handle definitions
for (defPtr = defBegin; defPtr < defEnd; defPtr++)
if (defPtr->isVirtualRegister())
{
VirtualRegister& vReg = defPtr->getVirtualRegister();
currentLive.clear(vReg.getRegisterIndex());
switch (vReg.getClass())
{
case vrcInteger:
nGeneralAlive--;
break;
case vrcFloatingPoint:
case vrcFixedPoint:
nFloatingPointAlive--;
break;
default:
break;
}
}
// Check for deaths
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isVirtualRegister())
{
VirtualRegister& vReg = usePtr->getVirtualRegister();
if (!currentLive.test(vReg.getRegisterIndex()))
// This is the last use of this register.
{
currentLive.set(vReg.getRegisterIndex());
switch (vReg.getClass())
{
case vrcInteger:
nGeneralAlive++;
while (/*(nGeneralAlive > NUMBER_OF_GREGISTERS) &&*/ !grNeedLoad.empty())
{
PRUint32 toLoad = grNeedLoad.get();
currentLive.clear(toLoad);
nGeneralAlive--;
VirtualRegister& nReg = vRegManager.getVirtualRegister(toLoad);
Instruction& lastUsingInstruction = *nReg.spillInfo.lastUsingInstruction;
emitter.emitLoadAfter(*lastUsingInstruction.getPrimitive(), lastUsingInstruction.getLinks().prev,
nReg.getAlias(), *nReg.equivalentRegister[vrcStackSlot]);
nReg.releaseSelf();
}
break;
case vrcFloatingPoint:
case vrcFixedPoint:
nFloatingPointAlive++;
while (/*(nFloatingPointAlive > NUMBER_OF_FPREGISTERS) &&*/ !fpNeedLoad.empty())
{
PRUint32 toLoad = fpNeedLoad.get();
currentLive.clear(toLoad);
nFloatingPointAlive--;
VirtualRegister& nReg = vRegManager.getVirtualRegister(toLoad);
Instruction& lastUsingInstruction = *nReg.spillInfo.lastUsingInstruction;
emitter.emitLoadAfter(*lastUsingInstruction.getPrimitive(), lastUsingInstruction.getLinks().prev,
nReg.getAlias(), *nReg.equivalentRegister[vrcStackSlot]);
nReg.releaseSelf();
}
break;
default:
break;
}
}
}
// Handle uses
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isVirtualRegister())
{
VirtualRegister& vReg = usePtr->getVirtualRegister();
PRUint32 registerIndex = vReg.getRegisterIndex();
if (vReg.spillInfo.willSpill) {
#if defined(GENERATE_FOR_X86)
if (!instruction.switchUseToSpill((usePtr - useBegin), *vReg.equivalentRegister[vrcStackSlot]))
#endif
{
switch (vReg.getClass())
{
case vrcInteger:
if (!grNeedLoad.test(registerIndex))
{
grNeedLoad.put(registerIndex);
VirtualRegister& alias = vRegManager.newVirtualRegister(vrcInteger);
if (vReg.isPreColored())
alias.preColorRegister(vReg.getPreColor());
/* if (vReg.hasSpecialInterference) {
alias.specialInterference.sizeTo(NUMBER_OF_REGISTERS);
alias.specialInterference = vReg.specialInterference;
alias.hasSpecialInterference = true;
} */
vReg.setAlias(alias);
vReg.retainSelf();
}
break;
case vrcFloatingPoint:
case vrcFixedPoint:
if (!fpNeedLoad.test(registerIndex))
{
fpNeedLoad.put(registerIndex);
VirtualRegister& alias = vRegManager.newVirtualRegister(vReg.getClass());
if (vReg.isPreColored())
alias.preColorRegister(vReg.getPreColor());
/*if (vReg.hasSpecialInterference) {
alias.specialInterference.sizeTo(NUMBER_OF_REGISTERS);
alias.specialInterference = vReg.specialInterference;
alias.hasSpecialInterference = true;
} */
vReg.setAlias(alias);
vReg.retainSelf();
}
break;
default:
break;
}
usePtr->getVirtualRegisterPtr().initialize(vReg.getAlias());
usedInThisInstruction.set(registerIndex);
vReg.spillInfo.lastUsingInstruction = &instruction;
}
currentLive.clear(registerIndex);
} else { // will not spill
currentLive.set(registerIndex);
}
}
// Handle definitions
for (defPtr = defBegin; defPtr < defEnd; defPtr++)
if (defPtr->isVirtualRegister())
{
VirtualRegister& vReg = defPtr->getVirtualRegister();
if (vReg.spillInfo.willSpill)
#if defined(GENERATE_FOR_X86)
if (!instruction.switchDefineToSpill((defPtr - defBegin), *vReg.equivalentRegister[vrcStackSlot]))
#endif
{
if (usedInThisInstruction.test(vReg.getRegisterIndex()))
// this virtualRegister was used in this instruction and is also defined. We need to move
// this virtual register to its alias first and then save it to memory.
{
emitter.emitStoreAfter(*instruction.getPrimitive(), &instruction.getLinks(),
vReg.getAlias(), *vReg.equivalentRegister[vrcStackSlot]);
defPtr->getVirtualRegisterPtr().initialize(vReg.getAlias());
}
else
{
emitter.emitStoreAfter(*instruction.getPrimitive(), &instruction.getLinks(),
vReg, *vReg.equivalentRegister[vrcStackSlot]);
}
}
}
}
while (!grNeedLoad.empty())
{
PRUint32 nl = grNeedLoad.get();
VirtualRegister& nlReg = vRegManager.getVirtualRegister(nl);
Instruction& lastUse = *nlReg.spillInfo.lastUsingInstruction;
emitter.emitLoadAfter(*lastUse.getPrimitive(), lastUse.getLinks().prev,
nlReg.getAlias(), *nlReg.equivalentRegister[vrcStackSlot]);
nlReg.releaseSelf();
}
while (!fpNeedLoad.empty())
{
PRUint32 nl = fpNeedLoad.get();
VirtualRegister& nlReg = vRegManager.getVirtualRegister(nl);
Instruction& lastUse = *nlReg.spillInfo.lastUsingInstruction;
emitter.emitLoadAfter(*lastUse.getPrimitive(), lastUse.getLinks().prev,
nlReg.getAlias(), *nlReg.equivalentRegister[vrcStackSlot]);
nlReg.releaseSelf();
}
// if(node.dfsNum == 8) printf("\n________End Node %d________\n", node.dfsNum);
}
}
#endif

View File

@@ -1,269 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 _SPILLING_H_
#define _SPILLING_H_
#include "Fundamentals.h"
#include <string.h>
#include "RegisterAllocator.h"
#include "RegisterAllocatorTools.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "SparseSet.h"
template <class RegisterPressure>
class Spilling
{
private:
static void insertStoreAfter(Instruction& instruction, RegisterName name);
static void insertLoadBefore(Instruction& instruction, RegisterName name);
public:
static void calculateSpillCosts(RegisterAllocator& registerAllocator);
static void insertSpillCode(RegisterAllocator& registerAllocator);
};
struct SpillCost
{
double loads;
double stores;
double copies;
double cost;
bool infinite;
};
template <class RegisterPressure>
void Spilling<RegisterPressure>::insertSpillCode(RegisterAllocator& registerAllocator)
{
Uint32 rangeCount = registerAllocator.rangeCount;
RegisterName* name2range = registerAllocator.name2range;
Pool& pool = registerAllocator.pool;
SparseSet currentLive(pool, rangeCount);
SparseSet needLoad(pool, rangeCount);
SparseSet mustSpill(pool, rangeCount);
SparseSet& willSpill = *registerAllocator.willSpill;
ControlGraph& controlGraph = registerAllocator.controlGraph;
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
needLoad.clear();
currentLive = liveOut[n];
mustSpill = currentLive;
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i);) {
Instruction& instruction = instructions.get(i);
i = instructions.retreat(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
InstructionDefine* definePtr;
bool foundLiveDefine = false;
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
if (currentLive.test(name2range[definePtr->getRegisterName()])) {
foundLiveDefine = true;
break;
}
} else {
foundLiveDefine = true;
break;
}
if (defineBegin != defineEnd && !foundLiveDefine) {
fprintf(stderr, "!!! Removed instruction because it was only defining unused registers !!!\n");
instruction.remove();
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName range = name2range[definePtr->getRegisterName()];
#ifdef DEBUG
if (needLoad.test(range))
if (!mustSpill.test(range) && registerAllocator.spillCost[range].infinite && willSpill.test(range)) {
fprintf(stderr, "Tried to spill a register with infinite spill cost\n");
abort();
}
#endif // DEBUG
if (willSpill.test(range))
insertStoreAfter(instruction, range);
needLoad.clear(range);
}
if (instruction.getFlags() & ifCopy)
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName range = name2range[usePtr->getRegisterName()];
if (!currentLive.test(range))
for (SparseSet::iterator r = needLoad.begin(); !needLoad.done(r); r = needLoad.advance(r)) {
RegisterName load = RegisterName(needLoad.get(r));
if (willSpill.test(load))
insertLoadBefore(instruction, load);
mustSpill.set(load);
}
needLoad.clear();
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
currentLive.clear(name2range[definePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName range = name2range[usePtr->getRegisterName()];
currentLive.set(range);
needLoad.set(range);
}
}
for (SparseSet::iterator l = needLoad.begin(); !needLoad.done(l); l = needLoad.advance(l)) {
RegisterName load = RegisterName(needLoad.get(l));
if (willSpill.test(load))
insertLoadBefore(instructions.first(), load);
}
}
}
template <class RegisterPressure>
void Spilling<RegisterPressure>::insertLoadBefore(Instruction& /*instruction*/, RegisterName name)
{
fprintf(stdout, "will insert load for range %d\n", name);
}
template <class RegisterPressure>
void Spilling<RegisterPressure>::insertStoreAfter(Instruction& /*instruction*/, RegisterName name)
{
fprintf(stdout, "will insert store for range %d\n", name);
}
template <class RegisterPressure>
void Spilling<RegisterPressure>::calculateSpillCosts(RegisterAllocator& registerAllocator)
{
Uint32 rangeCount = registerAllocator.rangeCount;
RegisterName* name2range = registerAllocator.name2range;
Pool& pool = registerAllocator.pool;
SparseSet live(pool, rangeCount);
SparseSet needLoad(pool, rangeCount);
SparseSet mustSpill(pool, rangeCount);
SparseSet alreadyStored(pool, rangeCount); // FIX: should get this from previous spilling.
SpillCost* cost = new SpillCost[rangeCount];
memset(cost, '\0', rangeCount * sizeof(SpillCost));
ControlGraph& controlGraph = registerAllocator.controlGraph;
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
ControlNode& node = *nodes[n];
double weight = doLog10(node.loopDepth);
needLoad.clear();
live = liveOut[n];
mustSpill = live;
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
InstructionDefine* definePtr;
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName range = name2range[definePtr->getRegisterName()];
if (needLoad.test(range))
if (!mustSpill.test(range))
cost[range].infinite = true;
if ((false /* !rematerializable(range) */ || !needLoad.test(range)) && !alreadyStored.test(range))
cost[range].stores += weight;
needLoad.clear(range);
}
if (instruction.getFlags() & ifCopy)
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
if (!live.test(name2range[usePtr->getRegisterName()])) {
for (SparseSet::iterator l = needLoad.begin(); !needLoad.done(l); l = needLoad.advance(l)) {
Uint32 range = needLoad.get(l);
cost[range].loads += weight;
mustSpill.set(range);
}
needLoad.clear();
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
live.clear(name2range[definePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName range = name2range[usePtr->getRegisterName()];
live.set(range);
needLoad.set(range);
}
if (instruction.getFlags() & ifCopy) {
assert(useBegin != useEnd && useBegin[0].isRegister());
assert(defineBegin != defineEnd && defineBegin[0].isRegister());
RegisterName source = name2range[useBegin[0].getRegisterName()];
RegisterName destination = name2range[defineBegin[0].getRegisterName()];
cost[source].copies += weight;
cost[destination].copies += weight;
}
}
for (SparseSet::iterator s = needLoad.begin(); !needLoad.done(s); s = needLoad.advance(s))
cost[needLoad.get(s)].loads += weight;
}
for (Uint32 r = 0; r < rangeCount; r++) {
SpillCost& c = cost[r];
c.cost = 2 * (c.loads + c.stores) - c.copies;
}
registerAllocator.spillCost = cost;
}
#endif // _SPILLING_H_

View File

@@ -1,239 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 _SPLITS_H_
#define _SPLITS_H_
#include "Fundamentals.h"
#include <string.h>
#include "Pool.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "RegisterAllocator.h"
#include "RegisterAllocatorTools.h"
UT_EXTERN_LOG_MODULE(RegAlloc);
template <class RegisterPressure>
struct Splits
{
static void calculateSplitCosts(RegisterAllocator& registerAllocator);
static bool findSplit(RegisterAllocator& registerAllocator, RegisterName* color, RegisterName range);
static void insertSplitCode(RegisterAllocator& registerAllocator);
};
struct SplitCost
{
double loads;
double stores;
};
template <class RegisterPressure>
void Splits<RegisterPressure>::insertSplitCode(RegisterAllocator& /*registerAllocator*/)
{
// FIX
}
template <class RegisterPressure>
bool Splits<RegisterPressure>::findSplit(RegisterAllocator& registerAllocator, RegisterName* color, RegisterName range)
{
Pool& pool = registerAllocator.pool;
NameLinkedList** neighborsWithColor = new(pool) NameLinkedList*[6]; // FIX
memset(neighborsWithColor, '\0', 6 * sizeof(NameLinkedList*));
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
for (Int32 i = vector->count - 1; i >=0; --i) {
RegisterName neighbor = vector->neighbors[i];
RegisterName c = color[neighbor];
if (c < 6) { // FIX
NameLinkedList* node = new(pool) NameLinkedList();
node->name = neighbor;
node->next = neighborsWithColor[c];
neighborsWithColor[c] = node;
}
}
bool splitAroundName = true;
LiveRangeGraph<RegisterPressure>& lGraph = registerAllocator.lGraph;
RegisterName bestColor = RegisterName(6); // FIX
double bestCost = registerAllocator.spillCost[range].cost;
SplitCost* splitCost = registerAllocator.splitCost;
for (RegisterName i = RegisterName(0); i < 6; i = RegisterName(i + 1)) { // FIX
double splitAroundNameCost = 0.0;
bool canSplitAroundName = true;
SplitCost& sCost = splitCost[range];
double addedCost = 2.0 * (sCost.stores + sCost.loads);
for (NameLinkedList* node = neighborsWithColor[i]; node != NULL; node = node->next) {
RegisterName neighbor = node->name;
if (lGraph.haveEdge(neighbor, range)) {
canSplitAroundName = false;
break;
} else
splitAroundNameCost += addedCost;
}
if (canSplitAroundName && splitAroundNameCost < bestCost) {
bestCost = splitAroundNameCost;
bestColor = i;
splitAroundName = true;
}
double splitAroundColorCost = 0.0;
bool canSplitAroundColor = true;
for (NameLinkedList* node = neighborsWithColor[i]; node != NULL; node = node->next) {
RegisterName neighbor = node->name;
if (lGraph.haveEdge(range, neighbor)) {
canSplitAroundColor = false;
break;
} else {
SplitCost& sCost = splitCost[neighbor];
double addedCost = 2.0 * (sCost.stores + sCost.loads);
splitAroundColorCost += addedCost;
}
}
if (canSplitAroundColor && splitAroundColorCost < bestCost) {
bestCost = splitAroundColorCost;
bestColor = i;
splitAroundName = false;
}
}
if (bestColor < RegisterName(6)) {
color[range] = bestColor;
registerAllocator.splitFound = true;
NameLinkedList** splitAround = registerAllocator.splitAround;
if (splitAroundName)
for (NameLinkedList* node = neighborsWithColor[bestColor]; node != NULL; node = node->next) {
NameLinkedList* newNode = new(pool) NameLinkedList();
newNode->name = node->name;
newNode->next = splitAround[range];
splitAround[range] = newNode;
}
else
for (NameLinkedList* node = neighborsWithColor[bestColor]; node != NULL; node = node->next) {
NameLinkedList* newNode = new(pool) NameLinkedList();
RegisterName neighbor = node->name;
newNode->name = range;
newNode->next = splitAround[neighbor];
splitAround[neighbor] = newNode;
}
trespass("Found a split");
return true;
}
return false;
}
template <class RegisterPressure>
void Splits<RegisterPressure>::calculateSplitCosts(RegisterAllocator& registerAllocator)
{
Pool& pool = registerAllocator.pool;
Uint32 rangeCount = registerAllocator.rangeCount;
RegisterName* name2range = registerAllocator.name2range;
SplitCost* splitCost = new(pool) SplitCost[rangeCount];
memset(splitCost, '\0', rangeCount * sizeof(SplitCost));
SparseSet live(pool, rangeCount);
RegisterPressure::Set* liveIn = registerAllocator.liveness.liveIn;
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
ControlNode& node = *nodes[n];
double weight = doLog10(node.loopDepth);
live = liveOut[n];
ControlEdge* successorsEnd = node.getSuccessorsEnd();
for (ControlEdge* successorsPtr = node.getSuccessorsBegin(); successorsPtr < successorsEnd; successorsPtr++) {
ControlNode& successor = successorsPtr->getTarget();
if (successor.getControlKind() != ckEnd) {
RegisterPressure::Set& successorLiveIn = liveIn[successor.dfsNum];
for (SparseSet::iterator i = live.begin(); !live.done(i); i = live.advance(i)) {
RegisterName name = RegisterName(live.get(i));
if (!successorLiveIn.test(name))
splitCost[name].loads += doLog10(successor.loopDepth);
}
}
}
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
InstructionDefine* definePtr;
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
splitCost[name2range[definePtr->getRegisterName()]].stores += weight;
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName range = name2range[usePtr->getRegisterName()];
if (!live.test(range)) {
if (&instruction != &instructions.last())
splitCost[range].loads += weight;
else {
ControlEdge* successorsEnd = node.getSuccessorsEnd();
for (ControlEdge* successorsPtr = node.getSuccessorsBegin(); successorsPtr < successorsEnd; successorsPtr++)
splitCost[range].loads += doLog10(successorsPtr->getTarget().loopDepth);
}
}
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
live.clear(name2range[definePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
live.set(name2range[usePtr->getRegisterName()]);
}
}
NameLinkedList** splitAround = new(pool) NameLinkedList*[rangeCount];
memset(splitAround, '\0', rangeCount * sizeof(NameLinkedList*));
registerAllocator.splitAround = splitAround;
registerAllocator.splitCost = splitCost;
registerAllocator.splitFound = false;
}
#endif // _SPLITS_H_

View File

@@ -1,186 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 "Fundamentals.h"
#include "HashTable.h"
#include "Timer.h"
#include "Pool.h"
static Pool pool; // Pool for the Timer class.
static HashTable<TimerEntry*> timerEntries(pool); // Timers hashtable.
const nTimersInABlock = 128; // Number of timers in a block.
static PRTime *timers = new(pool) PRTime[nTimersInABlock]; // A block of timers.
static Uint8 nextTimer = 0; // nextAvailableTimer.
//
// Calibrate the call to PR_Now().
//
static PRTime calibrate()
{
PRTime t = PR_Now();
PRTime& a = *new(pool) PRTime();
// Call 10 times the PR_Now() function.
a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now();
a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now();
t = (PR_Now() - t + 9) / 10;
return t;
}
static PRTime adjust = calibrate();
//
// Return the named timer..
//
TimerEntry& Timer::getTimerEntry(const char* name)
{
if (!timerEntries.exists(name)) {
TimerEntry* newEntry = new(pool) TimerEntry();
newEntry->accumulator = 0;
newEntry->running = false;
timerEntries.add(name, newEntry);
}
return *timerEntries[name];
}
//
// Return a reference to a new timer.
//
PRTime& Timer::getNewTimer()
{
if (nextTimer >= nTimersInABlock) {
timers = new(pool) PRTime[nTimersInABlock];
nextTimer = 0;
}
return timers[nextTimer++];
}
static Uint32 timersAreFrozen = 0;
//
// Start the named timer.
//
void Timer::start(const char* name)
{
if (timersAreFrozen)
return;
freezeTimers();
TimerEntry& timer = getTimerEntry(name);
PR_ASSERT(!timer.running);
timer.accumulator = 0;
timer.running = true;
timer.done = false;
unfreezeTimers();
}
//
// Stop the named timer.
//
void Timer::stop(const char* name)
{
if (timersAreFrozen)
return;
freezeTimers();
TimerEntry& timer = getTimerEntry(name);
PR_ASSERT(timer.running);
timer.running = false;
timer.done = true;
unfreezeTimers();
}
//
// Freeze all the running timers.
//
void Timer::freezeTimers()
{
PRTime when = PR_Now() - adjust;
if (timersAreFrozen == 0) {
Vector<TimerEntry*> entries = timerEntries;
Uint32 count = entries.size();
for (Uint32 i = 0; i < count; i++) {
TimerEntry& entry = *entries[i];
if (entry.running) {
entry.accumulator += (when - *entry.startTime);
}
}
}
timersAreFrozen++;
}
//
// Unfreeze all the running timers.
//
void Timer::unfreezeTimers()
{
PR_ASSERT(timersAreFrozen != 0);
timersAreFrozen--;
if (timersAreFrozen == 0) {
Vector<TimerEntry *> entries = timerEntries;
Uint32 count = entries.size();
PRTime& newStart = getNewTimer();
for (Uint32 i = 0; i < count; i++) {
TimerEntry& entry = *entries[i];
if (entry.running) {
entry.startTime = &newStart;
}
}
newStart = PR_Now();
}
}
//
// Print the named timer in the file f.
//
void Timer::print(FILE* f, const char *name)
{
if (timersAreFrozen)
return;
freezeTimers();
TimerEntry& timer = getTimerEntry(name);
PR_ASSERT(timer.done);
PRTime elapsed = timer.accumulator;
if (elapsed >> 32) {
fprintf(f, "[timer %s out of range]\n", name);
} else {
fprintf(f, "[%dus in %s]\n", Uint32(elapsed), name);
}
fflush(f);
unfreezeTimers();
}

View File

@@ -1,80 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 _TIMER_H_
#define _TIMER_H_
#include "Fundamentals.h"
#include "HashTable.h"
#include "prtime.h"
//
// Naming convention:
// As the class Timer contains only static methods, the timer's name should start with the
// module name. Otherwise starting 2 timers with the same name will assert.
//
#ifndef NO_TIMER
struct TimerEntry
{
PRTime *startTime; // Current time when we start the timer.
PRTime accumulator; // Time spent in this timer.
bool running; // True if the timer is running.
bool done; // True if the timer was running and was stopped.
};
class Timer
{
private:
// Return the named timer.
static TimerEntry& getTimerEntry(const char* name);
// Return a reference to a new Timer.
static PRTime& getNewTimer();
public:
// Start the timer.
static void start(const char* name);
// Stop the timer.
static void stop(const char* name);
// Freeze all the running timers.
static void freezeTimers();
// Unfreeze all the running timers.
static void unfreezeTimers();
// Print the timer.
static void print(FILE* f, const char *name);
};
inline void startTimer(const char* name) {Timer::start(name);}
inline void stopTimer(const char* name) {Timer::stop(name); Timer::print(stdout, name);}
#define START_TIMER_SAFE Timer::freezeTimers();
#define END_TIMER_SAFE Timer::unfreezeTimers();
#define TIMER_SAFE(x) START_TIMER_SAFE x; END_TIMER_SAFE
#else /* NO_TIMER */
inline void startTimer(const char* /*name*/) {}
inline void stopTimer(const char* /*name*/) {}
#define START_TIMER_SAFE
#define END_TIMER_SAFE
#define TIMER_SAFE(x) x;
#endif /* NO_TIMER */
#endif /* _TIMER_H_ */

View File

@@ -1,116 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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 _VIRTUAL_REGISTER_H_
#define _VIRTUAL_REGISTER_H_
#include "Fundamentals.h"
#include "IndexedPool.h"
#include <string.h>
#include "RegisterTypes.h"
#include "RegisterClass.h"
//------------------------------------------------------------------------------
// VirtualRegister - 24b
class Instruction;
class VirtualRegister : public IndexedObject<VirtualRegister>
{
public:
Instruction* definingInstruction; // Instruction defining this VR.
// Initialize a VR of the given classKind.
VirtualRegister(RegisterClassKind /*classKind*/) : definingInstruction(NULL) {}
// Return the defining instruction for this VR.
Instruction* getDefiningInstruction() const {return definingInstruction;}
// Set the defining instruction.
void setDefiningInstruction(Instruction& insn);
};
// Return true if the VirtualRegisters are equals. The only way 2 VRs can be equal is if
// they have the same index. If they have the same index then they are at the same
// address in the indexed pool.
//
inline bool operator == (const VirtualRegister& regA, const VirtualRegister& regB) {return &regA == &regB;}
//------------------------------------------------------------------------------
// VirtualRegisterManager -
struct PreColoredRegister
{
RegisterID id;
RegisterName color;
};
class VirtualRegisterManager
{
private:
IndexedPool<VirtualRegister> registerPool;
PreColoredRegister machineRegister[6];
public:
VirtualRegisterManager()
{
for (Uint32 i = 0; i < 6; i++)
machineRegister[i].id = invalidID;
}
// Return the VirtualRegister at the given index.
VirtualRegister& getVirtualRegister(RegisterName name) const {return registerPool.get(name);}
// Return a new VirtualRegister.
RegisterID newVirtualRegister(RegisterClassKind classKind)
{
VirtualRegister& vReg = *new(registerPool) VirtualRegister(classKind);
RegisterID rid;
setName(rid, RegisterName(vReg.getIndex()));
setClass(rid, classKind);
return rid;
}
RegisterID newMachineRegister(RegisterName name, RegisterClassKind classKind)
{
RegisterID rid = machineRegister[name].id;
if (rid == invalidID) {
rid = newVirtualRegister(classKind);
DEBUG_ONLY(setMachineRegister(rid));
machineRegister[name].id = rid;
machineRegister[name].color = name;
}
return rid;
}
PreColoredRegister* getMachineRegistersBegin() const {return (PreColoredRegister*) machineRegister;} // FIX
PreColoredRegister* getMachineRegistersEnd() const {return (PreColoredRegister*) &machineRegister[6];} // FIX
// Return the VirtualRegister universe size.
Uint32 getSize() {return registerPool.getSize();}
void setSize(Uint32 size) {registerPool.setSize(size);}
};
#endif // _VIRTUAL_REGISTER_H_

5
mozilla/js/jsd/MANIFEST Normal file
View File

@@ -0,0 +1,5 @@
#
# This is a list of local files which get copied to the mozilla:dist directory
#
jsdebug.h

73
mozilla/js/jsd/Makefile Normal file
View File

@@ -0,0 +1,73 @@
#!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 = ../..
MODULE = jsdebug
LIBRARY_NAME = jsd
# Switching on MOZ_JAVA is a short-term hack. This is really for no Java/IFC
ifdef MOZ_JAVA
JAVA_OR_OJI = 1
endif
ifdef MOZ_OJI
JAVA_OR_OJI = 1
endif
ifdef JAVA_OR_OJI
DIRS = classes
endif
REQUIRES = java js nspr
EXPORTS = jsdebug.h
CSRCS = \
jsdebug.c \
jsd_high.c \
jsd_hook.c \
jsd_scpt.c \
jsd_stak.c \
jsd_text.c \
jsd_lock.c \
$(NULL)
ifndef MOZ_JSD
CSRCS += jsdstubs.c jsd_java.c
JDK_GEN = \
netscape.jsdebug.Script \
netscape.jsdebug.DebugController \
netscape.jsdebug.JSThreadState \
netscape.jsdebug.JSStackFrameInfo \
netscape.jsdebug.JSPC \
netscape.jsdebug.JSSourceTextProvider \
netscape.jsdebug.JSErrorReporter \
$(NULL)
endif
include $(DEPTH)/config/rules.mk
$(OBJDIR)\jsdstubs.o: \
$(JDK_STUB_DIR)\netscape_jsdebug_Script.c \
$(JDK_STUB_DIR)\netscape_jsdebug_DebugController.c \
$(JDK_STUB_DIR)\netscape_jsdebug_JSThreadState.c \
$(JDK_STUB_DIR)\netscape_jsdebug_JSStackFrameInfo.c \
$(JDK_STUB_DIR)\netscape_jsdebug_JSPC.c \
$(JDK_STUB_DIR)\netscape_jsdebug_JSSourceTextProvider.c

View File

@@ -0,0 +1,78 @@
#!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
MODULE = jsdebug
LIBRARY_NAME = jsd
# Switching on MOZ_JAVA is a short-term hack. This is really for no Java/IFC
ifdef MOZ_JAVA
JAVA_OR_OJI = 1
endif
ifdef MOZ_OJI
JAVA_OR_OJI = 1
endif
ifdef JAVA_OR_OJI
DIRS = classes
endif
REQUIRES = java js
EXPORTS = $(srcdir)/jsdebug.h
CSRCS = \
jsdebug.c \
jsd_high.c \
jsd_hook.c \
jsd_scpt.c \
jsd_stak.c \
jsd_text.c \
jsd_lock.c \
$(NULL)
ifndef MOZ_JSD
CSRCS += jsdstubs.c jsd_java.c
JDK_GEN = \
netscape.jsdebug.Script \
netscape.jsdebug.DebugController \
netscape.jsdebug.JSThreadState \
netscape.jsdebug.JSStackFrameInfo \
netscape.jsdebug.JSPC \
netscape.jsdebug.JSSourceTextProvider \
netscape.jsdebug.JSErrorReporter \
$(NULL)
endif
include $(topsrcdir)/config/rules.mk
$(OBJDIR)\jsdstubs.o: \
$(JDK_STUB_DIR)\netscape_jsdebug_Script.c \
$(JDK_STUB_DIR)\netscape_jsdebug_DebugController.c \
$(JDK_STUB_DIR)\netscape_jsdebug_JSThreadState.c \
$(JDK_STUB_DIR)\netscape_jsdebug_JSStackFrameInfo.c \
$(JDK_STUB_DIR)\netscape_jsdebug_JSPC.c \
$(JDK_STUB_DIR)\netscape_jsdebug_JSSourceTextProvider.c

18
mozilla/js/jsd/README Normal file
View File

@@ -0,0 +1,18 @@
/* jband - 10/26/98 - */
js/jsd contains code for debugging support for the C-based JavaScript engine
in js/src.
Currently the makefiles are for Win32 only (using MS nmake.exe from MSDEV 4.2).
jsd.mak will build a standalone dll. jsdshell.mak will build the dll and also
a version of the js/src/js.c shell which will launch a Java VM and run the
JavaSript Debugger (built in js/jsdj). This version assumes that you have a
JRE compatible JVM installed. Only Windows is supported for this Java-based
debugging.
Though only Windows makefiles are supplied, the basic code in js/jsd should
compile for other platforms -- it is a newer version of code that builds and
ships with Communicator 4.x on many platforms.
js/jsd/jsdb is a console debugger using only native code (see README in that
directory)

View File

@@ -0,0 +1,59 @@
#!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 = ../../..
MODULE = java
JJSD = netscape/jsdebug
#
# JDIRS is dependant on JAVA_DESTPATH in config/rules.m[a]k.
# Be sure to touch that directory if you add a new directory to
# JDIRS, or else it will not build. XXX
#
JDIRS = $(JJSD)
JAR_JSD = jsd10.jar
JAR_JSD_CLASSES = $(JJSD)
#
# jars to build at install time
#
JARS = $(JAR_JSD)
include $(DEPTH)/config/rules.mk
JAVA_SOURCEPATH = $(DEPTH)/js/jsd/classes
doc::
$(JAVADOC) -d $(DIST)/doc netscape.jsdebug
natives_list:: FORCE
rm -rf $@
find . -name "*.class" -print | sed 's@\./\(.*\)\.class$$@\1@' | \
sed 's@/@.@g' | xargs $(JVH) -natives | sort > $@
check_natives:: natives_list
rm -f found_natives
nm -B ../$(OBJDIR)/*.o \
| egrep "Java.*_stub" | awk '{ print $$3; }' | sort > found_natives
diff found_natives natives_list
FORCE:

View File

@@ -0,0 +1,64 @@
#!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
MODULE = java
JJSD = netscape/jsdebug
#
# JDIRS is dependant on JAVA_DESTPATH in config/rules.m[a]k.
# Be sure to touch that directory if you add a new directory to
# JDIRS, or else it will not build. XXX
#
JDIRS = $(JJSD)
JAR_JSD = jsd10.jar
JAR_JSD_CLASSES = $(JJSD)
#
# jars to build at install time
#
JARS = $(JAR_JSD)
include $(topsrcdir)/config/rules.mk
JAVA_SOURCEPATH = $(DEPTH)/js/jsd/classes
doc::
$(JAVADOC) -d $(DIST)/doc netscape.jsdebug
natives_list:: FORCE
rm -rf $@
find . -name "*.class" -print | sed 's@\./\(.*\)\.class$$@\1@' | \
sed 's@/@.@g' | xargs $(JVH) -natives | sort > $@
check_natives:: natives_list
rm -f found_natives
nm -B ../$(OBJDIR)/*.o \
| egrep "Java.*_stub" | awk '{ print $$3; }' | sort > found_natives
diff found_natives natives_list
FORCE:

View File

@@ -0,0 +1,64 @@
#!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.
IGNORE_MANIFEST=1
#
#//------------------------------------------------------------------------
#//
#// Makefile to build the JavaScriptDebug tree
#//
#//------------------------------------------------------------------------
DEPTH = ..\..\..
JAVA_SOURCEPATH=$(DEPTH)\js\jsd\classes
#//------------------------------------------------------------------------
#//
#// Define the files necessary to build the target (ie. OBJS)
#//
#//------------------------------------------------------------------------
include <$(DEPTH)\config\config.mak>
all::
MODULE=java
JJSD=netscape/jsdebug
JDIRS=$(JJSD)
JAR_JSD=jsd10.jar
JAR_JSD_CLASSES=$(JJSD)
JARS=$(JAR_JSD)
include <$(DEPTH)\config\rules.mak>
!if "$(MOZ_BITS)" == "32"
$(JAR_JSD):
cd $(JAVA_DESTPATH)
@echo +++ building/updating $@
$(ZIP_PROG) -$(COMP_LEVEL)qu $@ META-INF\build
-for %i in ($(JAR_JSD_CLASSES:/=\)) do @$(ZIP_PROG) -$(COMP_LEVEL)qu $@ %i\*.class
cd $(MAKEDIR)
!endif
jars: $(JARS)
install:: jars
javadoc:
-mkdir $(XPDIST)\javadoc 2> NUL
echo $(JAVADOC) -sourcepath . -d $(XPDIST)\javadoc $(JDIRS:/=.)
$(JAVADOC) -sourcepath . -d $(XPDIST)\javadoc $(JDIRS:/=.)

View File

@@ -0,0 +1,41 @@
/* -*- 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.
*/
package netscape.jsdebug;
/**
* DebugBreakHook must be subclassed to respond when a debug break is
* requested
*
* @author John Bandhauer
* @version 1.0
* @since 1.0
*/
public class DebugBreakHook extends Hook {
/**
* Override this method to respond just before a thread
* reaches a particular instruction.
* <p>
* @param debug ThreadState representing the current state
* @param pc the location of the instruction about to be executed
*/
public void aboutToExecute(ThreadStateBase debug, PC pc) {
// defaults to no action
}
}

View File

@@ -0,0 +1,374 @@
/* -*- 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.
*/
package netscape.jsdebug;
import netscape.util.Hashtable;
import netscape.security.PrivilegeManager;
import netscape.security.ForbiddenTargetException;
/**
* This is the master control panel for observing events in the VM.
* Each method setXHook() must be passed an object that extends
* the class XHook. When an event of the specified type
* occurs, a well-known method on XHook will be called (see the
* various XHook classes for details). The method call takes place
* on the same thread that triggered the event in the first place,
* so that any monitors held by the thread which triggered the hook
* will still be owned in the hook method.
* <p>
* This class is meant to be a singleton and has a private constructor.
* Call the static <code>getDebugController()</code> to get this object.
* <p>
* Note that all functions use netscape.security.PrivilegeManager to verify
* that the caller has the "Debugger" privilege. The exception
* netscape.security.ForbiddenTargetException will be throw if this is
* not enabled.
*
* @author John Bandhauer
* @author Nick Thompson
* @version 1.0
* @since 1.0
* @see netscape.security.PrivilegeManager
* @see netscape.security.ForbiddenTargetException
*/
public final class DebugController {
private static final int majorVersion = 1;
private static final int minorVersion = 0;
private static DebugController controller;
private ScriptHook scriptHook;
private Hashtable instructionHookTable;
private InterruptHook interruptHook;
private DebugBreakHook debugBreakHook;
private JSErrorReporter errorReporter;
/**
* Get the DebugController object for the current VM.
* <p>
* @return the singleton DebugController
*/
public static synchronized DebugController getDebugController()
throws ForbiddenTargetException
{
try {
PrivilegeManager.checkPrivilegeEnabled("Debugger");
if (controller == null)
controller = new DebugController();
return controller;
} catch (ForbiddenTargetException e) {
System.out.println("failed in check Priv in DebugController.getDebugController()");
e.printStackTrace(System.out);
throw e;
}
}
private DebugController()
{
scriptTable = new Hashtable();
_setController(true);
}
/**
* Request notification of Script loading events.
* <p>
* Whenever a Script is loaded into or unloaded from the VM
* the appropriate method of the ScriptHook argument will be called.
* Callers are responsible for chaining hooks if chaining is required.
*
* @param h new script hook
* @return the previous hook object (null if none)
*/
public synchronized ScriptHook setScriptHook(ScriptHook h)
throws ForbiddenTargetException
{
PrivilegeManager.checkPrivilegeEnabled("Debugger");
ScriptHook oldHook = scriptHook;
scriptHook = h;
return oldHook;
}
/**
* Get the current observer of Script events.
* <p>
* @return the current script hook (null if none)
*/
public ScriptHook getScriptHook()
throws ForbiddenTargetException
{
PrivilegeManager.checkPrivilegeEnabled("Debugger");
return scriptHook;
}
/**
* Set a hook at the given program counter value.
* <p>
* When a thread reaches that instruction, a ThreadState
* object will be created and the appropriate method
* of the hook object will be called. Callers are responsible
* for chaining hooks if chaining is required.
*
* @param pc pc at which hook should be set
* @param h new hook for this pc
* @return the previous hook object (null if none)
*/
public synchronized InstructionHook setInstructionHook(
PC pc,
InstructionHook h)
throws ForbiddenTargetException
{
PrivilegeManager.checkPrivilegeEnabled("Debugger");
InstructionHook oldHook;
if (instructionHookTable == null) {
instructionHookTable = new Hashtable();
}
oldHook = (InstructionHook) instructionHookTable.get(pc);
instructionHookTable.put(pc, h);
setInstructionHook0(pc);
return oldHook;
}
private native void setInstructionHook0(PC pc);
/**
* Get the hook at the given program counter value.
* <p>
* @param pc pc for which hook should be found
* @return the hook (null if none)
*/
public InstructionHook getInstructionHook(PC pc)
throws ForbiddenTargetException
{
PrivilegeManager.checkPrivilegeEnabled("Debugger");
return getInstructionHook0(pc);
}
// called by native function
private InstructionHook getInstructionHook0(PC pc)
{
if (instructionHookTable == null)
return null;
else
return (InstructionHook) instructionHookTable.get(pc);
}
/**************************************************************/
/**
* Set the hook at to be called when interrupts occur.
* <p>
* The next instruction which starts to execute after
* <code>sendInterrupt()</code> has been called will
* trigger a call to this hook. A ThreadState
* object will be created and the appropriate method
* of the hook object will be called. Callers are responsible
* for chaining hooks if chaining is required.
*
* @param h new hook
* @return the previous hook object (null if none)
* @see netscape.jsdebug.DebugController#sendInterrupt
*/
public synchronized InterruptHook setInterruptHook( InterruptHook h )
throws ForbiddenTargetException
{
PrivilegeManager.checkPrivilegeEnabled("Debugger");
InterruptHook oldHook = interruptHook;
interruptHook = h;
return oldHook;
}
/**
* Get the current hook to be called on interrupt
* <p>
* @return the hook (null if none)
*/
public InterruptHook getInterruptHook()
throws ForbiddenTargetException
{
PrivilegeManager.checkPrivilegeEnabled("Debugger");
return interruptHook;
}
/**
* Cause the interrupt hook to be called when the next
* JavaScript instruction starts to execute.
* <p>
* The interrupt is self clearing
* @see netscape.jsdebug.DebugController#setInterruptHook
*/
public void sendInterrupt()
throws ForbiddenTargetException
{
PrivilegeManager.checkPrivilegeEnabled("Debugger");
sendInterrupt0();
}
private native void sendInterrupt0();
/**************************************************************/
/**
* Set the hook at to be called when a <i>debug break</i> is requested
* <p>
* Set the hook to be called when <i>JSErrorReporter.DEBUG</i> is returned
* by the <i>error reporter</i> hook. When that happens a ThreadState
* object will be created and the appropriate method
* of the hook object will be called. Callers are responsible
* for chaining hooks if chaining is required.
*
* @param h new hook
* @return the previous hook object (null if none)
* @see netscape.jsdebug.DebugController#setErrorReporter
* @see netscape.jsdebug.JSErrorReporter
*/
public synchronized DebugBreakHook setDebugBreakHook( DebugBreakHook h )
throws ForbiddenTargetException
{
PrivilegeManager.checkPrivilegeEnabled("Debugger");
DebugBreakHook oldHook = debugBreakHook;
debugBreakHook = h;
return oldHook;
}
/**
* Get the current hook to be called on debug break
* <p>
* @return the hook (null if none)
*/
public DebugBreakHook getDebugBreakHook()
throws ForbiddenTargetException
{
PrivilegeManager.checkPrivilegeEnabled("Debugger");
return debugBreakHook;
}
/**************************************************************/
/**
* Get the 'handle' which cooresponds to the native code representing the
* instance of the underlying JavaScript Debugger context.
* <p>
* This would not normally be useful in java. Some of the other classes
* in this package need this. It remains public mostly for historical
* reasons. It serves as a check to see that the native classes have been
* loaded and the built-in native JavaScript Debugger support has been
* initialized. This DebugController is not valid (or useful) when it is
* in a state where this native context equals 0.
*
* @return the native context (0 if none)
*/
public int getNativeContext()
throws ForbiddenTargetException
{
PrivilegeManager.checkPrivilegeEnabled("Debugger");
// System.out.println( "nativecontext = " + _nativeContext + "\n" );
return _nativeContext;
}
private native void _setController( boolean set );
private Hashtable scriptTable;
private int _nativeContext;
/**
* Execute a string as a JavaScript script within a stack frame
* <p>
* This method can be used to execute arbitrary sets of statements on a
* stopped thread. It is useful for inspecting and modifying data.
* <p>
* This method can only be called while the JavaScript thread is stopped
* - i.e. as part of the code responding to a hook. Thgis method
* <b>must</b> be called on the same thread as was executing when the
* hook was called.
* <p>
* If an error occurs while execuing this code, then the error
* reporter hook will be called if present.
*
* @param frame the frame context in which to evaluate this script
* @param text the script text
* @param filename where to tell the JavaScript engine this code came
* from (it is usually best to make this the same as the filename of
* code represented by the frame)
* @param lineno the line number to pass to JS ( >=1 )
* @return The result of the script execution converted to a string.
* (null if the result was null or void)
*/
public String executeScriptInStackFrame( JSStackFrameInfo frame,
String text,
String filename,
int lineno )
throws ForbiddenTargetException
{
PrivilegeManager.checkPrivilegeEnabled("Debugger");
return executeScriptInStackFrame0( frame, text, filename, lineno );
}
private native String executeScriptInStackFrame0( JSStackFrameInfo frame,
String text,
String filename,
int lineno );
/**
* Set the hook at to be called when a JavaScript error occurs
* <p>
* @param er new error reporter hook
* @return the previous hook object (null if none)
* @see netscape.jsdebug.JSErrorReporter
*/
public JSErrorReporter setErrorReporter(JSErrorReporter er)
throws ForbiddenTargetException
{
PrivilegeManager.checkPrivilegeEnabled("Debugger");
JSErrorReporter old = errorReporter;
errorReporter = er;
return old;
}
/**
* Get the hook at to be called when a JavaScript error occurs
* <p>
* @return the hook object (null if none)
* @see netscape.jsdebug.JSErrorReporter
*/
public JSErrorReporter getErrorReporter()
throws ForbiddenTargetException
{
PrivilegeManager.checkPrivilegeEnabled("Debugger");
return errorReporter;
}
/**
* Get the major version number of this module
* <p>
* @return the version number
*/
public static int getMajorVersion() {return majorVersion;}
/**
* Get the minor version number of this module
* <p>
* @return the version number
*/
public static int getMinorVersion() {return minorVersion;}
private static native int getNativeMajorVersion();
private static native int getNativeMinorVersion();
}

View File

@@ -0,0 +1,32 @@
/* -*- 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.
*/
package netscape.jsdebug;
/**
* An instance of this class is returned for each hook set by
* the debugger as a handle for removing the hook later.
*
* @author John Bandhauer
* @author Nick Thompson
* @version 1.0
* @since 1.0
*/
public abstract class Hook {
}

View File

@@ -0,0 +1,55 @@
/* -*- 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.
*/
package netscape.jsdebug;
/**
* InstructionHook must be subclassed to respond to hooks
* at a particular program instruction.
*
* @author John Bandhauer
* @author Nick Thompson
* @version 1.0
* @since 1.0
*/
public class InstructionHook extends Hook {
private PC pc;
/**
* Create an InstructionHook at the given PC value.
*/
public InstructionHook(PC pc) {
this.pc = pc;
}
/**
* Get the instruction that the hook is set at.
*/
public PC getPC() {
return pc;
}
/**
* Override this method to respond just before a thread
* reaches a particular instruction.
*/
/* jband - 03/31/97 - I made this public to allow chaining */
public void aboutToExecute(ThreadStateBase debug) {
// defaults to no action
}
}

View File

@@ -0,0 +1,39 @@
/* -*- 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.
*/
package netscape.jsdebug;
/**
* InterruptHook must be subclassed to respond when interrupts occur
*
* @author John Bandhauer
* @author Nick Thompson
* @version 1.0
* @since 1.0
*/
public class InterruptHook extends Hook {
/**
* Override this method to respond when interrupts occur
* @param debug the state of this thread
* @param pc the pc of the instruction about to execute
*/
public void aboutToExecute(ThreadStateBase debug, PC pc) {
// defaults to no action
}
}

View File

@@ -0,0 +1,46 @@
/* -*- 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.
*/
package netscape.jsdebug;
/**
* Exception to indicate bad thread state etc...
*
* @author John Bandhauer
* @author Nick Thompson
* @version 1.0
* @since 1.0
*/
public class InvalidInfoException extends Exception {
/**
* Constructs a InvalidInfoException without a detail message.
* A detail message is a String that describes this particular exception.
*/
public InvalidInfoException() {
super();
}
/**
* Constructs a InvalidInfoException with a detail message.
* A detail message is a String that describes this particular exception.
* @param s the detail message
*/
public InvalidInfoException(String s) {
super(s);
}
}

View File

@@ -0,0 +1,70 @@
/* -*- 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.
*/
package netscape.jsdebug;
/**
* This is a special kind of hook to respond to JavaScript errors
*
* @author John Bandhauer
* @version 1.0
* @since 1.0
*/
public interface JSErrorReporter
{
/* keep these in sync with the numbers in jsdebug.h */
/**
* returned by <code>reportError()</code> to indicate that the error
* should be passed along to the error reporter that would have been
* called had the debugger not been running
*/
public static final int PASS_ALONG = 0;
/**
* returned by <code>reportError()</code> to indicate that the
* normal error reporter should not be called and that the JavaScript
* engine should do whatever it would normally do after calling the
* error reporter.
*/
public static final int RETURN = 1;
/**
* returned by <code>reportError()</code> to indicate that the
* 'debug break' hook should be called to allow the debugger to
* investigate the state of the process when the error occured
*/
public static final int DEBUG = 2;
/**
* This hook is called when a JavaScript error (compile or runtime) occurs
* <p>
* One of the codes above should be returned to tell the engine how to
* proceed.
* @param msg error message passed through from the JavaScript engine
* @param filename filename (or url) of the code with the error
* @param lineno line number where error was detected
* @param linebuf a copy of the line where the error was detected
* @param tokenOffset the offset into <i>linebuf</i> where the error
* was detected
* @returns one of the codes above
*/
public int reportError( String msg,
String filename,
int lineno,
String linebuf,
int tokenOffset );
}

View File

@@ -0,0 +1,76 @@
/* -*- 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.
*/
package netscape.jsdebug;
/**
* This subclass of PC provides JavaScript-specific information.
*
* @author John Bandhauer
* @version 1.0
* @since 1.0
*/
public final class JSPC extends PC {
private Script script;
private int pc;
public JSPC(Script script, int pc) {
this.script = script;
this.pc = pc;
}
public Script getScript() {
return script;
}
public int getPC() {
return pc;
}
public boolean isValid()
{
return script.isValid();
}
/**
* Get the SourceLocation associated with this PC value.
* returns null if the source location is unavailable.
*/
public native SourceLocation getSourceLocation();
/**
* Ask whether two program counter values are equal.
*/
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof JSPC))
return false;
JSPC jspc = (JSPC) obj;
return (jspc.script == script && jspc.pc == pc);
}
public int hashCode() {
return script.hashCode() + pc;
}
public String toString() {
return "<PC "+script+"+"+pc+">";
}
}

View File

@@ -0,0 +1,63 @@
/* -*- 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.
*/
package netscape.jsdebug;
/**
* JAvaScript specific SourceLocation
*
* @author John Bandhauer
* @version 1.0
* @since 1.0
*/
public class JSSourceLocation extends SourceLocation
{
public JSSourceLocation( JSPC pc, int line )
{
_pc = pc;
_line = line;
_url = pc.getScript().getURL();
}
/**
* Gets the first line number associated with this SourceLocation.
* This is the lowest common denominator information that will be
* available: some implementations may choose to include more
* specific location information in a subclass of SourceLocation.
*/
public int getLine() {return _line;}
public String getURL() {return _url;}
/**
* Get the first PC associated with a given SourceLocation.
* This is the place to set a breakpoint at that location.
* returns null if there is no code corresponding to that source
* location.
*/
public PC getPC() {return _pc;}
public String toString()
{
return "<SourceLocation "+_url+"#"+_line+">";
}
private JSPC _pc;
private int _line;
private String _url;
}

View File

@@ -0,0 +1,130 @@
/* -*- 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.
*/
package netscape.jsdebug;
import netscape.util.Vector;
import netscape.security.PrivilegeManager;
import netscape.security.ForbiddenTargetException;
/**
* This class provides access to SourceText items.
* <p>
* This class is meant to be a singleton and has a private constructor.
* Call the static <code>getSourceTextProvider()</code> to get this object.
* <p>
* Note that all functions use netscape.security.PrivilegeManager to verify
* that the caller has the "Debugger" privilege. The exception
* netscape.security.ForbiddenTargetException will be throw if this is
* not enabled.
*
* @author John Bandhauer
* @version 1.0
* @since 1.0
* @see netscape.security.PrivilegeManager
* @see netscape.security.ForbiddenTargetException
*/
public final class JSSourceTextProvider extends SourceTextProvider
{
private JSSourceTextProvider( long nativeContext )
{
_sourceTextVector = new Vector();
_nativeContext = nativeContext;
}
/**
* Get the SourceTextProvider object for the current VM.
* <p>
* @return the singleton SourceTextProvider
*/
public static synchronized SourceTextProvider getSourceTextProvider()
throws ForbiddenTargetException
{
PrivilegeManager.checkPrivilegeEnabled("Debugger");
if( null == _sourceTextProvider )
{
long nativeContext = DebugController.getDebugController().getNativeContext();
if( 0 != nativeContext )
_sourceTextProvider = new JSSourceTextProvider(nativeContext);
}
return _sourceTextProvider;
}
/**
* Get the SourceText item for the given URL
*/
public SourceTextItem findSourceTextItem( String url )
throws ForbiddenTargetException
{
PrivilegeManager.checkPrivilegeEnabled("Debugger");
return findSourceTextItem0(url);
}
// also called from native code...
private SourceTextItem findSourceTextItem0( String url )
{
synchronized( _sourceTextVector )
{
for (int i = 0; i < _sourceTextVector.size(); i++)
{
SourceTextItem src = (SourceTextItem) _sourceTextVector.elementAt(i);
if( src.getURL().equals(url) )
return src;
}
return null;
}
}
/**
* Return the vector of SourceTextItems.
* <p>
* This is NOT a copy. nor is it necessarily current
*/
public Vector getSourceTextVector()
throws ForbiddenTargetException
{
PrivilegeManager.checkPrivilegeEnabled("Debugger");
return _sourceTextVector;
}
/**
* Load the SourceText item for the given URL
* <p>
* <B>This is not guaranteed to be implemented</B>
*/
public synchronized SourceTextItem loadSourceTextItem( String url )
throws ForbiddenTargetException
{
PrivilegeManager.checkPrivilegeEnabled("Debugger");
return loadSourceTextItem0( url );
}
private native SourceTextItem loadSourceTextItem0( String url );
/**
* Refresh the vector to reflect any changes made in the
* underlying native system
*/
public synchronized native void refreshSourceTextVector();
private static SourceTextProvider _sourceTextProvider = null;
private Vector _sourceTextVector;
private long _nativeContext;
}

View File

@@ -0,0 +1,51 @@
/* -*- 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.
*/
package netscape.jsdebug;
/**
* This interface provides access to the execution stack of a thread.
* It has several subclasses to distinguish between different kinds of
* stack frames: these currently include activations of Java methods
* or JavaScript functions.
* It is possible that synchronize blocks and try blocks deserve their own
* stack frames - to allow for later extensions a debugger should skip over
* stack frames it doesn't understand.
* Note that this appears very Java-specific. However, multiple threads and
* exceptions are relevant to JavaScript as well because of its
* interoperation with Java.
*
* @author John Bandhauer
* @version 1.0
* @since 1.0
*/
public final class JSStackFrameInfo extends StackFrameInfo
{
public JSStackFrameInfo(JSThreadState threadState) {
super(threadState);
}
protected native StackFrameInfo getCaller0()
throws InvalidInfoException;
public native PC getPC()
throws InvalidInfoException;
private int _nativePtr; // used internally
}

View File

@@ -0,0 +1,80 @@
/* -*- 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.
*/
package netscape.jsdebug;
/**
* This is the JavaScript specific implementation of the thread state
*
* @author John Bandhauer
* @version 1.0
* @since 1.0
*/
public final class JSThreadState extends ThreadStateBase
{
/**
* <B><font color="red">Not Implemented.</font></B>
* Always throws <code>InternalError("unimplemented")</code>
*/
public static ThreadStateBase getThreadState(Thread t)
throws InvalidInfoException
{
throw new InternalError("unimplemented");
}
/**
* get the count of frames
*/
public native int countStackFrames()
throws InvalidInfoException;
/**
* get the 'top' frame
*/
public native StackFrameInfo getCurrentFrame()
throws InvalidInfoException;
/**
* <B><font color="red">Not Implemented.</font></B>
* Always throws <code>InternalError("unimplemented")</code>
*/
public Thread getThread()
{
throw new InternalError("unimplemented");
}
/**
* <B><font color="red">Not Implemented.</font></B>
* Always throws <code>InternalError("unimplemented")</code>
*/
public void leaveSuspended()
{
throw new InternalError("unimplemented");
}
/**
* <B><font color="red">Not Implemented.</font></B>
* Always throws <code>InternalError("unimplemented")</code>
*/
protected void resume0()
{
throw new InternalError("unimplemented");
}
protected int nativeThreadState; /* used internally */
}

View File

@@ -0,0 +1,42 @@
/* -*- 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.
*/
package netscape.jsdebug;
/**
* The PC class is an opaque representation of a program counter. It
* may have different implementations for interpreted Java methods,
* methods compiled by the JIT, JavaScript methods, etc.
*
* @author John Bandhauer
* @author Nick Thompson
* @version 1.0
* @since 1.0
*/
public abstract class PC {
/**
* Get the SourceLocation associated with this PC value.
* returns null if the source location is unavailable.
*/
public abstract SourceLocation getSourceLocation();
/**
* Ask whether two program counter values are equal.
*/
public abstract boolean equals(Object obj);
}

View File

@@ -0,0 +1,82 @@
/* -*- 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.
*/
package netscape.jsdebug;
/**
* This instances of this class represent the JavaScript string object. This
* class is intended to only be constructed by the underlying native code.
* The DebugController will construct an instance of this class when scripts
* are created and that instance will always be used to reference the underlying
* script throughout the lifetime of that script.
*
* @author John Bandhauer
* @version 1.0
* @since 1.0
*/
public final class Script
{
public String getURL() {return _url; }
public String getFunction() {return _function; }
public int getBaseLineNumber() {return _baseLineNumber;}
public int getLineExtent() {return _lineExtent; }
public boolean isValid() {return 0 != _nativePtr;}
/**
* Get the PC of the first executable code on or after the given
* line in this script. returns null if none
*/
public native JSPC getClosestPC(int line);
public String toString()
{
int end = _baseLineNumber+_lineExtent-1;
if( null == _function )
return "<Script "+_url+"["+_baseLineNumber+","+end+"]>";
else
return "<Script "+_url+"#"+_function+"()["+_baseLineNumber+","+end+"]>";
}
public int hashCode()
{
return _nativePtr;
}
public boolean equals(Object obj)
{
if( obj == this )
return true;
// In our system the native code is the only code that generates
// these objects. They are never duplicated
return false;
/*
if( !(obj instanceof Script) )
return false;
return 0 != _nativePtr && _nativePtr == ((Script)obj)._nativePtr;
*/
}
private synchronized void _setInvalid() {_nativePtr = 0;}
private String _url;
private String _function;
private int _baseLineNumber;
private int _lineExtent;
private int _nativePtr; // used internally
}

View File

@@ -0,0 +1,57 @@
/* -*- 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.
*/
package netscape.jsdebug;
/**
* ScriptHook must be subclassed to respond to loading and
* unloading of scripts
*
* @author John Bandhauer
* @version 1.0
* @since 1.0
*/
public class ScriptHook extends Hook
{
/**
* Create a ScriptHook for current the current VM.
*/
public ScriptHook() {}
/**
* Override this method to respond when a new script is
* loaded into the VM.
*
* @param script a script object created by the controller to
* represent this script. This exact same object will be used
* in all further references to the script.
*/
public void justLoadedScript(Script script) {
// defaults to no action
}
/**
* Override this method to respond when a class is
* about to be unloaded from the VM.
*
* @param script which will be unloaded
*/
public void aboutToUnloadScript(Script script) {
// defaults to no action
}
}

View File

@@ -0,0 +1,53 @@
/* -*- 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.
*/
package netscape.jsdebug;
/**
* An implementation of the SourceLocation interface is used to represent
* a location in a source file. Java classfiles only make source locations
* available at the line-by-line granularity, but other languages may
* include finer-grain information. At this time only line number
* information is included.
*
* @author John Bandhauer
* @author Nick Thompson
* @version 1.0
* @since 1.0
*/
/* XXX must source locations be contiguous? */
public abstract class SourceLocation {
/**
* Gets the first line number associated with this SourceLocation.
* This is the lowest common denominator information that will be
* available: some implementations may choose to include more
* specific location information in a subclass of SourceLocation.
*
* @returns source line number cooresponding to this location
*/
public abstract int getLine();
/**
* Get the first PC associated with a given SourceLocation.
* This is the place to set a breakpoint at that location.
*
* @returns pc object or null if there is no code corresponding
* to this source location.
*/
public abstract PC getPC();
}

View File

@@ -0,0 +1,107 @@
/* -*- 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.
*/
package netscape.jsdebug;
/**
* This class is used to represent a file or url which contains
* JavaScript source text. The actual JavaScript source may be intermixed
* with other text (as in an html file) or raw. The debugger uses this
* interface to access the source. The file of the actual source need
* not physially exist anywhere; i.e. the underlying engine might synthesize
* it as needed.
* <p>
* The <i>url</i> of this class is immutable -- it represents a key in
* collections of these objects
*
* @author John Bandhauer
* @version 1.0
* @since 1.0
*/
public class SourceTextItem
{
/* these coorespond to jsdebug.h values - change in both places if anywhere */
/**
* This object is initialized, but contains no text
*/
public static final int INITED = 0;
/**
* This object contains the full text
*/
public static final int FULL = 1;
/**
* This object contains the partial text (valid , but more may come later)
*/
public static final int PARTIAL = 2;
/**
* This object may contain partial text, but loading was aborted (by user?)
*/
public static final int ABORTED = 3;
/**
* This object may contain partial text, but loading failed (or the
* underlying debugger support was unable to capture it; e.g.
* not enough memory...)
*/
public static final int FAILED = 4;
/**
* This object contains no text because the debugger has signaled that
* the text is no longer needed
*/
public static final int CLEARED = 5;
/**
* Constuct for url (which is immutable during the lifetime of the object)
* <p>
* Presumably, text will be added later
* @param url url or filename by which this object will be known
*/
public SourceTextItem( String url )
{
this( url, (String)null, INITED );
}
/**
* Constuct for url with text and status
* <p>
* @param url url or filename by which this object will be known
* @param text source text this object should start with
* @param status status this object should start with
*/
public SourceTextItem( String url, String text, int status )
{
_url = url;
_text = text;
_status = status;
_dirty = true;
}
public String getURL() {return _url; }
public String getText() {return _text; }
public int getStatus() {return _status;}
public boolean getDirty() {return _dirty; }
public void setText(String text) {_text = text;}
public void setStatus(int status) {_status = status;}
public void setDirty(boolean b) {_dirty = b; }
private String _url;
private String _text;
private int _status;
private boolean _dirty;
}

View File

@@ -0,0 +1,58 @@
/* -*- 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.
*/
package netscape.jsdebug;
import netscape.util.Vector;
import netscape.security.ForbiddenTargetException;
/**
* Abstract class to represent entity capable of providing access to source text
*
* @author John Bandhauer
* @version 1.0
* @since 1.0
*/
public abstract class SourceTextProvider
{
public static SourceTextProvider getSourceTextProvider() throws Exception
{
return null;
}
/**
* Return the vector of SourceTextItems.
* <p>
* This is not liekly to be a copy. nor is it necessarily current
*/
public abstract Vector getSourceTextVector() throws ForbiddenTargetException;
/**
* Refresh the vector by whatever means to reflect any changes made in the
* underlying native system
*/
public abstract void refreshSourceTextVector();
/**
* Get the SourceText item for the given URL
*/
public abstract SourceTextItem findSourceTextItem( String url ) throws ForbiddenTargetException;
/**
* Load the SourceText item for the given URL
* <p>
* <B>This is not guaranteed to be implemented</B>
*/
public abstract SourceTextItem loadSourceTextItem( String url ) throws ForbiddenTargetException;
}

View File

@@ -0,0 +1,94 @@
/* -*- 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.
*/
package netscape.jsdebug;
/**
* This interface provides access to the execution stack of a thread.
* It has several subclasses to distinguish between different kinds of
* stack frames: these currently include activations of Java methods
* or JavaScript functions.
* It is possible that synchronize blocks and try blocks deserve their own
* stack frames - to allow for later extensions a debugger should skip over
* stack frames it doesn't understand.
* Note that this appears very Java-specific. However, multiple threads and
* exceptions are relevant to JavaScript as well because of its
* interoperation with Java.
*
* @author John Bandhauer
* @author Nick Thompson
* @version 1.0
* @since 1.0
*/
public abstract class StackFrameInfo {
ThreadStateBase threadState;
StackFrameInfo caller;
protected StackFrameInfo(ThreadStateBase threadState) {
this.threadState = threadState;
}
/**
* Return true if this stack frame is still valid. Stack frames
* may become invalid when the thread is resumed (this is more
* conservative than invalidating the frame only when it actually
* returns).
*/
public boolean isValid() {
return threadState.isValid();
}
/**
* Get the stack frame where this one was built, or null for the
* start of the stack.
*/
public synchronized StackFrameInfo getCaller()
throws InvalidInfoException {
if (caller == null)
caller = getCaller0();
if (!isValid())
throw new InvalidInfoException("invalid StackFrameInfo");
return caller;
}
protected abstract StackFrameInfo getCaller0()
throws InvalidInfoException;
/**
* Get the thread that this stack frame is a part of.
*/
public Thread getThread() {
return threadState.getThread();
}
/**
* Get the 'enclosing' thread state
*/
public ThreadStateBase getThreadState() {
return threadState;
}
/**
* Get the current program counter value. Note that the
* class JavaPC supports the getMethod() operation.
*/
public abstract PC getPC()
throws InvalidInfoException;
}

View File

@@ -0,0 +1,241 @@
/* -*- 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.
*/
package netscape.jsdebug;
/*
* jband - 03/19/97
*
* This is an 'abstracted version of netscape.debug.ThreadState
*
* The methods that were 'native' there are 'abstract' here.
* Changed 'private' data to 'protected' (though native access is immune)
* Changed 'private' resume0() to 'protected'
* Removed ThreadHook referneces
*
*/
/**
* When a hook is hit, the debugger records the state of the
* thread before the hook in a ThreadState object. This object
* is then passed to any hook methods that are called, and can
* be used to change the state of the thread when it resumes from the
* hook.
*
* @author John Bandhauer
* @author Nick Thompson
* @version 1.0
* @since 1.0
*/
public abstract class ThreadStateBase {
protected Thread thread;
protected boolean valid;
protected boolean runningHook;
protected boolean resumeWhenDone;
protected int status;
protected int continueState;
protected StackFrameInfo[] stack; /* jband - 03/19/97 - had no access modifier */
protected Object returnValue;
protected Throwable currentException;
protected int currentFramePtr; /* used internally */
protected ThreadStateBase previous;
/**
* <B><font color="red">Not Implemented.</font></B>
* Always throws <code>InternalError("unimplemented")</code>
*/
public static ThreadStateBase getThreadState(Thread t)
throws InvalidInfoException
{
throw new InternalError("unimplemented");
}
/**
* Get the Thread that this ThreadState came from.
*/
public Thread getThread() {
return thread;
}
/**
* Return true if the Thread hasn't been resumed since this ThreadState
* was made.
*/
public boolean isValid() {
return valid;
}
/**
* Return true if the thread is currently running a hook
* for this ThreadState
*/
public boolean isRunningHook() {
return runningHook;
}
/**
* partial list of thread states from sun.debug.ThreadInfo.
* XXX some of these don't apply.
*/
public final static int THR_STATUS_UNKNOWN = 0x01;
public final static int THR_STATUS_ZOMBIE = 0x02;
public final static int THR_STATUS_RUNNING = 0x03;
public final static int THR_STATUS_SLEEPING = 0x04;
public final static int THR_STATUS_MONWAIT = 0x05;
public final static int THR_STATUS_CONDWAIT = 0x06;
public final static int THR_STATUS_SUSPENDED = 0x07;
public final static int THR_STATUS_BREAK = 0x08;
/**
* Get the state of the thread at the time it entered debug mode.
* This can't be modified directly.
*/
public int getStatus() {
return status;
}
/**
* Get the count of the stackframes
*/
public abstract int countStackFrames()
throws InvalidInfoException;
/**
* Get the 'top' stackframe; i.e. the one with the current instruction
*/
public abstract StackFrameInfo getCurrentFrame()
throws InvalidInfoException;
/**
* Get the thread's stack as an array. stack[stack.length-1] is the
* current frame, and stack[0] is the beginning of the stack.
*/
public synchronized StackFrameInfo[] getStack()
throws InvalidInfoException {
// XXX check valid?
if (stack == null) {
stack = new StackFrameInfo[countStackFrames()];
}
if (stack.length == 0)
return stack;
StackFrameInfo frame = getCurrentFrame();
stack[stack.length - 1] = frame;
for (int i = stack.length - 2; i >= 0; i--) {
frame = frame.getCaller();
stack[i] = frame;
}
// should really be read-only for safety
return stack;
}
/**
* Leave the thread in a suspended state when the hook method(s)
* finish. This can be undone by calling resume(). This is the
* default only if the break was the result of
* DebugController.sendInterrupt().
*/
public void leaveSuspended() {
resumeWhenDone = false;
}
/**
* Resume the thread. This is the default unless the break was the result
* of DebugController.sendInterrupt(). This method may be called from a
* hook method, in which case the thread will resume when the
* method returns.
* Alternatively, if there is no active hook method and
* the thread is suspended around in the DebugFrame, this resumes it
* immediately.
*/
public synchronized void resume() {
if (runningHook)
resumeWhenDone = true;
else
resume0();
}
protected abstract void resume0();
/**
* if the continueState is DEAD, the thread cannot
* be restarted.
*/
public final static int DEBUG_STATE_DEAD = 0x01;
/**
* if the continueState is RUN, the thread will
* proceed to the next program counter value when it resumes.
*/
public final static int DEBUG_STATE_RUN = 0x02;
/**
* if the continueState is RETURN, the thread will
* return from the current method with the value in getReturnValue()
* when it resumes.
*/
public final static int DEBUG_STATE_RETURN = 0x03;
/**
* if the continueState is THROW, the thread will
* throw an exception (accessible with getException()) when it
* resumes.
*/
public final static int DEBUG_STATE_THROW = 0x04;
/**
* This gets the current continue state of the debug frame, which
* will be one of the DEBUG_STATE_* values above.
*/
public int getContinueState() {
return continueState;
}
public int setContinueState(int state) {
int old = continueState;
continueState = state;
return old;
}
/**
* If the thread was stopped while in the process of returning
* a value, this call returns an object representing that value.
* non-Object values are wrapped as in the java.lang.reflect api.
* This is only relevant if the continue state is RETURN, and the
* method throws an IllegalStateException otherwise.
*/
public Object getReturnValue() throws IllegalStateException {
if (continueState != DEBUG_STATE_RETURN)
throw new IllegalStateException("no value being returned");
return returnValue;
}
/**
* If the thread was stopped while in the process of throwing an
* exception, this call returns that exception.
* This is only relevant if the continue state is THROW, and it
* throws an IllegalStateException otherwise.
*/
public Throwable getException() throws IllegalStateException {
if (continueState != DEBUG_STATE_THROW)
throw new IllegalStateException("no exception throw in progress");
return currentException;
}
}

View File

@@ -0,0 +1,190 @@
struct Thing {
string s;
long i;
};
interface StringReciever {
void recieveString(
in string arg0
);
void bounce(
in long arg0
);
};
interface TestInterface {
string getFirstAppInList();
void getAppNames(
in ::StringReciever arg0
);
typedef sequence<::Thing> sequence_of_Thing;
::TestInterface::sequence_of_Thing getThings();
void callBounce(
in ::StringReciever arg0,
in long arg1
);
};
interface ISourceTextProvider {
typedef sequence<string> sequence_of_string;
::ISourceTextProvider::sequence_of_string getAllPages();
void refreshAllPages();
boolean hasPage(
in string arg0
);
boolean loadPage(
in string arg0
);
void refreshPage(
in string arg0
);
string getPageText(
in string arg0
);
long getPageStatus(
in string arg0
);
long getPageAlterCount(
in string arg0
);
};
struct IScriptSection {
long base;
long extent;
};
typedef sequence<::IScriptSection> sequence_of_IScriptSection;
struct IScript {
string url;
string funname;
long base;
long extent;
long jsdscript;
::sequence_of_IScriptSection sections;
};
struct IJSPC {
::IScript script;
long offset;
};
struct IJSSourceLocation {
long line;
::IJSPC pc;
};
interface IJSErrorReporter {
long reportError(
in string arg0,
in string arg1,
in long arg2,
in string arg3,
in long arg4
);
};
interface IScriptHook {
void justLoadedScript(
in ::IScript arg0
);
void aboutToUnloadScript(
in ::IScript arg0
);
};
struct IJSStackFrameInfo {
::IJSPC pc;
long jsdframe;
};
typedef sequence<::IJSStackFrameInfo> sequence_of_IJSStackFrameInfo;
struct IJSThreadState {
::sequence_of_IJSStackFrameInfo stack;
long continueState;
string returnValue;
long status;
long jsdthreadstate;
long id;
};
interface IJSExecutionHook {
void aboutToExecute(
in ::IJSThreadState arg0,
in ::IJSPC arg1
);
};
struct IExecResult {
string result;
boolean errorOccured;
string errorMessage;
string errorFilename;
long errorLineNumber;
string errorLineBuffer;
long errorTokenOffset;
};
interface IDebugController {
long getMajorVersion();
long getMinorVersion();
::IJSErrorReporter setErrorReporter(
in ::IJSErrorReporter arg0
);
::IJSErrorReporter getErrorReporter();
::IScriptHook setScriptHook(
in ::IScriptHook arg0
);
::IScriptHook getScriptHook();
::IJSPC getClosestPC(
in ::IScript arg0,
in long arg1
);
::IJSSourceLocation getSourceLocation(
in ::IJSPC arg0
);
::IJSExecutionHook setInterruptHook(
in ::IJSExecutionHook arg0
);
::IJSExecutionHook getInterruptHook();
::IJSExecutionHook setDebugBreakHook(
in ::IJSExecutionHook arg0
);
::IJSExecutionHook getDebugBreakHook();
::IJSExecutionHook setInstructionHook(
in ::IJSExecutionHook arg0,
in ::IJSPC arg1
);
::IJSExecutionHook getInstructionHook(
in ::IJSPC arg0
);
void setThreadContinueState(
in long arg0,
in long arg1
);
void setThreadReturnValue(
in long arg0,
in string arg1
);
void sendInterrupt();
void sendInterruptStepInto(
in long arg0
);
void sendInterruptStepOver(
in long arg0
);
void sendInterruptStepOut(
in long arg0
);
void reinstateStepper(
in long arg0
);
::IExecResult executeScriptInStackFrame(
in long arg0,
in ::IJSStackFrameInfo arg1,
in string arg2,
in string arg3,
in long arg4
);
boolean isRunningHook(
in long arg0
);
boolean isWaitingForResume(
in long arg0
);
void leaveThreadSuspended(
in long arg0
);
void resumeThread(
in long arg0
);
void iterateScripts(
in ::IScriptHook arg0
);
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,777 @@
#ifndef _ifaces_s_hh
#define _ifaces_s_hh
#include "ifaces_c.hh"
/************************************************************************/
/* */
/* This file is automatically generated by ORBeline IDL compiler */
/* Do not modify this file. */
/* */
/* ORBeline (c) is copyrighted by PostModern Computing, Inc. */
/* */
/* The generated code conforms to OMG's IDL C++ mapping as */
/* specified in OMG Document Number: 94-9-14. */
/* */
/************************************************************************/
class _sk_StringReciever : public StringReciever
{
protected:
_sk_StringReciever(const char *object_name = (const char *)NULL);
_sk_StringReciever(const char *service_name, const CORBA::ReferenceData& data);
virtual ~_sk_StringReciever() {}
public:
static const CORBA::TypeInfo _skel_info;
// The following operations need to be implemented by the server.
virtual void recieveString(const char * arg0) = 0;
virtual void bounce(CORBA::Long arg0) = 0;
// Skeleton Operations implemented automatically
static void _recieveString(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _bounce(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
};
template <class T>
class _tie_StringReciever : public StringReciever
{
public:
_tie_StringReciever(T& t, const char *obj_name=(char*)NULL) :
StringReciever(obj_name),
_ref(t) {
_object_name(obj_name);
}
_tie_StringReciever(T& t, const char *service_name,
const CORBA::ReferenceData& id)
:_ref(t) {
_service(service_name, id);
}
~_tie_StringReciever() {}
void recieveString(const char * arg0) {
_ref.recieveString(
arg0);
}
void bounce(CORBA::Long arg0) {
_ref.bounce(
arg0);
}
private:
T& _ref;
};
class _sk_TestInterface : public TestInterface
{
protected:
_sk_TestInterface(const char *object_name = (const char *)NULL);
_sk_TestInterface(const char *service_name, const CORBA::ReferenceData& data);
virtual ~_sk_TestInterface() {}
public:
static const CORBA::TypeInfo _skel_info;
// The following operations need to be implemented by the server.
virtual char * getFirstAppInList() = 0;
virtual void getAppNames(StringReciever_ptr arg0) = 0;
virtual TestInterface::sequence_of_Thing * getThings() = 0;
virtual void callBounce(StringReciever_ptr arg0,
CORBA::Long arg1) = 0;
// Skeleton Operations implemented automatically
static void _getFirstAppInList(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _getAppNames(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _getThings(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _callBounce(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
};
template <class T>
class _tie_TestInterface : public TestInterface
{
public:
_tie_TestInterface(T& t, const char *obj_name=(char*)NULL) :
TestInterface(obj_name),
_ref(t) {
_object_name(obj_name);
}
_tie_TestInterface(T& t, const char *service_name,
const CORBA::ReferenceData& id)
:_ref(t) {
_service(service_name, id);
}
~_tie_TestInterface() {}
char * getFirstAppInList() {
return _ref.getFirstAppInList();
}
void getAppNames(StringReciever_ptr arg0) {
_ref.getAppNames(
arg0);
}
TestInterface::sequence_of_Thing * getThings() {
return _ref.getThings();
}
void callBounce(StringReciever_ptr arg0,
CORBA::Long arg1) {
_ref.callBounce(
arg0,
arg1);
}
private:
T& _ref;
};
class _sk_ISourceTextProvider : public ISourceTextProvider
{
protected:
_sk_ISourceTextProvider(const char *object_name = (const char *)NULL);
_sk_ISourceTextProvider(const char *service_name, const CORBA::ReferenceData& data);
virtual ~_sk_ISourceTextProvider() {}
public:
static const CORBA::TypeInfo _skel_info;
// The following operations need to be implemented by the server.
virtual ISourceTextProvider::sequence_of_string * getAllPages() = 0;
virtual void refreshAllPages() = 0;
virtual CORBA::Boolean hasPage(const char * arg0) = 0;
virtual CORBA::Boolean loadPage(const char * arg0) = 0;
virtual void refreshPage(const char * arg0) = 0;
virtual char * getPageText(const char * arg0) = 0;
virtual CORBA::Long getPageStatus(const char * arg0) = 0;
virtual CORBA::Long getPageAlterCount(const char * arg0) = 0;
// Skeleton Operations implemented automatically
static void _getAllPages(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _refreshAllPages(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _hasPage(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _loadPage(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _refreshPage(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _getPageText(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _getPageStatus(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _getPageAlterCount(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
};
template <class T>
class _tie_ISourceTextProvider : public ISourceTextProvider
{
public:
_tie_ISourceTextProvider(T& t, const char *obj_name=(char*)NULL) :
ISourceTextProvider(obj_name),
_ref(t) {
_object_name(obj_name);
}
_tie_ISourceTextProvider(T& t, const char *service_name,
const CORBA::ReferenceData& id)
:_ref(t) {
_service(service_name, id);
}
~_tie_ISourceTextProvider() {}
ISourceTextProvider::sequence_of_string * getAllPages() {
return _ref.getAllPages();
}
void refreshAllPages() {
_ref.refreshAllPages();
}
CORBA::Boolean hasPage(const char * arg0) {
return _ref.hasPage(
arg0);
}
CORBA::Boolean loadPage(const char * arg0) {
return _ref.loadPage(
arg0);
}
void refreshPage(const char * arg0) {
_ref.refreshPage(
arg0);
}
char * getPageText(const char * arg0) {
return _ref.getPageText(
arg0);
}
CORBA::Long getPageStatus(const char * arg0) {
return _ref.getPageStatus(
arg0);
}
CORBA::Long getPageAlterCount(const char * arg0) {
return _ref.getPageAlterCount(
arg0);
}
private:
T& _ref;
};
class _sk_IJSErrorReporter : public IJSErrorReporter
{
protected:
_sk_IJSErrorReporter(const char *object_name = (const char *)NULL);
_sk_IJSErrorReporter(const char *service_name, const CORBA::ReferenceData& data);
virtual ~_sk_IJSErrorReporter() {}
public:
static const CORBA::TypeInfo _skel_info;
// The following operations need to be implemented by the server.
virtual CORBA::Long reportError(const char * arg0,
const char * arg1,
CORBA::Long arg2,
const char * arg3,
CORBA::Long arg4) = 0;
// Skeleton Operations implemented automatically
static void _reportError(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
};
template <class T>
class _tie_IJSErrorReporter : public IJSErrorReporter
{
public:
_tie_IJSErrorReporter(T& t, const char *obj_name=(char*)NULL) :
IJSErrorReporter(obj_name),
_ref(t) {
_object_name(obj_name);
}
_tie_IJSErrorReporter(T& t, const char *service_name,
const CORBA::ReferenceData& id)
:_ref(t) {
_service(service_name, id);
}
~_tie_IJSErrorReporter() {}
CORBA::Long reportError(const char * arg0,
const char * arg1,
CORBA::Long arg2,
const char * arg3,
CORBA::Long arg4) {
return _ref.reportError(
arg0,
arg1,
arg2,
arg3,
arg4);
}
private:
T& _ref;
};
class _sk_IScriptHook : public IScriptHook
{
protected:
_sk_IScriptHook(const char *object_name = (const char *)NULL);
_sk_IScriptHook(const char *service_name, const CORBA::ReferenceData& data);
virtual ~_sk_IScriptHook() {}
public:
static const CORBA::TypeInfo _skel_info;
// The following operations need to be implemented by the server.
virtual void justLoadedScript(const IScript& arg0) = 0;
virtual void aboutToUnloadScript(const IScript& arg0) = 0;
// Skeleton Operations implemented automatically
static void _justLoadedScript(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _aboutToUnloadScript(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
};
template <class T>
class _tie_IScriptHook : public IScriptHook
{
public:
_tie_IScriptHook(T& t, const char *obj_name=(char*)NULL) :
IScriptHook(obj_name),
_ref(t) {
_object_name(obj_name);
}
_tie_IScriptHook(T& t, const char *service_name,
const CORBA::ReferenceData& id)
:_ref(t) {
_service(service_name, id);
}
~_tie_IScriptHook() {}
void justLoadedScript(const IScript& arg0) {
_ref.justLoadedScript(
arg0);
}
void aboutToUnloadScript(const IScript& arg0) {
_ref.aboutToUnloadScript(
arg0);
}
private:
T& _ref;
};
class _sk_IJSExecutionHook : public IJSExecutionHook
{
protected:
_sk_IJSExecutionHook(const char *object_name = (const char *)NULL);
_sk_IJSExecutionHook(const char *service_name, const CORBA::ReferenceData& data);
virtual ~_sk_IJSExecutionHook() {}
public:
static const CORBA::TypeInfo _skel_info;
// The following operations need to be implemented by the server.
virtual void aboutToExecute(const IJSThreadState& arg0,
const IJSPC& arg1) = 0;
// Skeleton Operations implemented automatically
static void _aboutToExecute(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
};
template <class T>
class _tie_IJSExecutionHook : public IJSExecutionHook
{
public:
_tie_IJSExecutionHook(T& t, const char *obj_name=(char*)NULL) :
IJSExecutionHook(obj_name),
_ref(t) {
_object_name(obj_name);
}
_tie_IJSExecutionHook(T& t, const char *service_name,
const CORBA::ReferenceData& id)
:_ref(t) {
_service(service_name, id);
}
~_tie_IJSExecutionHook() {}
void aboutToExecute(const IJSThreadState& arg0,
const IJSPC& arg1) {
_ref.aboutToExecute(
arg0,
arg1);
}
private:
T& _ref;
};
class _sk_IDebugController : public IDebugController
{
protected:
_sk_IDebugController(const char *object_name = (const char *)NULL);
_sk_IDebugController(const char *service_name, const CORBA::ReferenceData& data);
virtual ~_sk_IDebugController() {}
public:
static const CORBA::TypeInfo _skel_info;
// The following operations need to be implemented by the server.
virtual CORBA::Long getMajorVersion() = 0;
virtual CORBA::Long getMinorVersion() = 0;
virtual IJSErrorReporter_ptr setErrorReporter(IJSErrorReporter_ptr arg0) = 0;
virtual IJSErrorReporter_ptr getErrorReporter() = 0;
virtual IScriptHook_ptr setScriptHook(IScriptHook_ptr arg0) = 0;
virtual IScriptHook_ptr getScriptHook() = 0;
virtual IJSPC * getClosestPC(const IScript& arg0,
CORBA::Long arg1) = 0;
virtual IJSSourceLocation * getSourceLocation(const IJSPC& arg0) = 0;
virtual IJSExecutionHook_ptr setInterruptHook(IJSExecutionHook_ptr arg0) = 0;
virtual IJSExecutionHook_ptr getInterruptHook() = 0;
virtual IJSExecutionHook_ptr setDebugBreakHook(IJSExecutionHook_ptr arg0) = 0;
virtual IJSExecutionHook_ptr getDebugBreakHook() = 0;
virtual IJSExecutionHook_ptr setInstructionHook(IJSExecutionHook_ptr arg0,
const IJSPC& arg1) = 0;
virtual IJSExecutionHook_ptr getInstructionHook(const IJSPC& arg0) = 0;
virtual void setThreadContinueState(CORBA::Long arg0,
CORBA::Long arg1) = 0;
virtual void setThreadReturnValue(CORBA::Long arg0,
const char * arg1) = 0;
virtual void sendInterrupt() = 0;
virtual void sendInterruptStepInto(CORBA::Long arg0) = 0;
virtual void sendInterruptStepOver(CORBA::Long arg0) = 0;
virtual void sendInterruptStepOut(CORBA::Long arg0) = 0;
virtual void reinstateStepper(CORBA::Long arg0) = 0;
virtual IExecResult * executeScriptInStackFrame(CORBA::Long arg0,
const IJSStackFrameInfo& arg1,
const char * arg2,
const char * arg3,
CORBA::Long arg4) = 0;
virtual CORBA::Boolean isRunningHook(CORBA::Long arg0) = 0;
virtual CORBA::Boolean isWaitingForResume(CORBA::Long arg0) = 0;
virtual void leaveThreadSuspended(CORBA::Long arg0) = 0;
virtual void resumeThread(CORBA::Long arg0) = 0;
virtual void iterateScripts(IScriptHook_ptr arg0) = 0;
// Skeleton Operations implemented automatically
static void _getMajorVersion(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _getMinorVersion(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _setErrorReporter(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _getErrorReporter(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _setScriptHook(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _getScriptHook(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _getClosestPC(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _getSourceLocation(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _setInterruptHook(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _getInterruptHook(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _setDebugBreakHook(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _getDebugBreakHook(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _setInstructionHook(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _getInstructionHook(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _setThreadContinueState(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _setThreadReturnValue(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _sendInterrupt(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _sendInterruptStepInto(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _sendInterruptStepOver(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _sendInterruptStepOut(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _reinstateStepper(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _executeScriptInStackFrame(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _isRunningHook(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _isWaitingForResume(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _leaveThreadSuspended(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _resumeThread(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
static void _iterateScripts(void *obj,
CORBA::MarshalStream &strm,
CORBA::Principal_ptr principal,
const char *oper,
void *priv_data);
};
template <class T>
class _tie_IDebugController : public IDebugController
{
public:
_tie_IDebugController(T& t, const char *obj_name=(char*)NULL) :
IDebugController(obj_name),
_ref(t) {
_object_name(obj_name);
}
_tie_IDebugController(T& t, const char *service_name,
const CORBA::ReferenceData& id)
:_ref(t) {
_service(service_name, id);
}
~_tie_IDebugController() {}
CORBA::Long getMajorVersion() {
return _ref.getMajorVersion();
}
CORBA::Long getMinorVersion() {
return _ref.getMinorVersion();
}
IJSErrorReporter_ptr setErrorReporter(IJSErrorReporter_ptr arg0) {
return _ref.setErrorReporter(
arg0);
}
IJSErrorReporter_ptr getErrorReporter() {
return _ref.getErrorReporter();
}
IScriptHook_ptr setScriptHook(IScriptHook_ptr arg0) {
return _ref.setScriptHook(
arg0);
}
IScriptHook_ptr getScriptHook() {
return _ref.getScriptHook();
}
IJSPC * getClosestPC(const IScript& arg0,
CORBA::Long arg1) {
return _ref.getClosestPC(
arg0,
arg1);
}
IJSSourceLocation * getSourceLocation(const IJSPC& arg0) {
return _ref.getSourceLocation(
arg0);
}
IJSExecutionHook_ptr setInterruptHook(IJSExecutionHook_ptr arg0) {
return _ref.setInterruptHook(
arg0);
}
IJSExecutionHook_ptr getInterruptHook() {
return _ref.getInterruptHook();
}
IJSExecutionHook_ptr setDebugBreakHook(IJSExecutionHook_ptr arg0) {
return _ref.setDebugBreakHook(
arg0);
}
IJSExecutionHook_ptr getDebugBreakHook() {
return _ref.getDebugBreakHook();
}
IJSExecutionHook_ptr setInstructionHook(IJSExecutionHook_ptr arg0,
const IJSPC& arg1) {
return _ref.setInstructionHook(
arg0,
arg1);
}
IJSExecutionHook_ptr getInstructionHook(const IJSPC& arg0) {
return _ref.getInstructionHook(
arg0);
}
void setThreadContinueState(CORBA::Long arg0,
CORBA::Long arg1) {
_ref.setThreadContinueState(
arg0,
arg1);
}
void setThreadReturnValue(CORBA::Long arg0,
const char * arg1) {
_ref.setThreadReturnValue(
arg0,
arg1);
}
void sendInterrupt() {
_ref.sendInterrupt();
}
void sendInterruptStepInto(CORBA::Long arg0) {
_ref.sendInterruptStepInto(
arg0);
}
void sendInterruptStepOver(CORBA::Long arg0) {
_ref.sendInterruptStepOver(
arg0);
}
void sendInterruptStepOut(CORBA::Long arg0) {
_ref.sendInterruptStepOut(
arg0);
}
void reinstateStepper(CORBA::Long arg0) {
_ref.reinstateStepper(
arg0);
}
IExecResult * executeScriptInStackFrame(CORBA::Long arg0,
const IJSStackFrameInfo& arg1,
const char * arg2,
const char * arg3,
CORBA::Long arg4) {
return _ref.executeScriptInStackFrame(
arg0,
arg1,
arg2,
arg3,
arg4);
}
CORBA::Boolean isRunningHook(CORBA::Long arg0) {
return _ref.isRunningHook(
arg0);
}
CORBA::Boolean isWaitingForResume(CORBA::Long arg0) {
return _ref.isWaitingForResume(
arg0);
}
void leaveThreadSuspended(CORBA::Long arg0) {
_ref.leaveThreadSuspended(
arg0);
}
void resumeThread(CORBA::Long arg0) {
_ref.resumeThread(
arg0);
}
void iterateScripts(IScriptHook_ptr arg0) {
_ref.iterateScripts(
arg0);
}
private:
T& _ref;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,68 @@
/* -*- 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.
*/
public interface IDebugController extends org.omg.CORBA.Object
{
public int getMajorVersion();
public int getMinorVersion();
public IJSErrorReporter setErrorReporter(IJSErrorReporter er);
public IJSErrorReporter getErrorReporter();
public IScriptHook setScriptHook(IScriptHook h);
public IScriptHook getScriptHook();
public IJSPC getClosestPC(IScript script, int line);
public IJSSourceLocation getSourceLocation(IJSPC pc);
public IJSExecutionHook setInterruptHook(IJSExecutionHook hook);
public IJSExecutionHook getInterruptHook();
public IJSExecutionHook setDebugBreakHook(IJSExecutionHook hook);
public IJSExecutionHook getDebugBreakHook();
public IJSExecutionHook setInstructionHook(IJSExecutionHook hook, IJSPC pc);
public IJSExecutionHook getInstructionHook(IJSPC pc);
public void setThreadContinueState(int threadID, int state);
public void setThreadReturnValue(int threadID, String value);
public void sendInterrupt();
public void sendInterruptStepInto(int threadID);
public void sendInterruptStepOver(int threadID);
public void sendInterruptStepOut(int threadID);
public void reinstateStepper(int threadID);
public IExecResult executeScriptInStackFrame(int threadID,
IJSStackFrameInfo frame,
String text,
String filename,
int lineno);
public boolean isRunningHook(int threadID);
public boolean isWaitingForResume(int threadID);
public void leaveThreadSuspended(int threadID);
public void resumeThread(int threadID);
public void iterateScripts(IScriptHook 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.
*/
public final class IExecResult
{
public String result;
public boolean errorOccured;
public String errorMessage;
public String errorFilename;
public int errorLineNumber;
public String errorLineBuffer;
public int errorTokenOffset;
}

View File

@@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- 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,17 +16,17 @@
* Reserved.
*/
#include "Fundamentals.h"
#include "SSATools.h"
#include "ControlGraph.h"
#include "VirtualRegister.h"
#include "Liveness.h"
void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager)
public interface IJSErrorReporter extends org.omg.CORBA.Object
{
if (!controlGraph.hasBackEdges)
return;
/* keep these in sync with the numbers in jsdebug.h */
public static final int PASS_ALONG = 0;
public static final int RETURN = 1;
public static final int DEBUG = 2;
public int reportError( String msg,
String filename,
int lineno,
String linebuf,
int tokenOffset );
}
Liveness liveness(controlGraph.pool);
liveness.buildLivenessAnalysis(controlGraph, vrManager);
}

View File

@@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- 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,7 @@
* Reserved.
*/
#ifndef _REGISTER_CLASS_H_
#define _REGISTER_CLASS_H_
#include "Fundamentals.h"
#include "RegisterTypes.h"
#endif // _REGISTER_CLASS_H_
public interface IJSExecutionHook extends org.omg.CORBA.Object
{
public void aboutToExecute(IJSThreadState debug, IJSPC pc);
}

View File

@@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- 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,6 +16,9 @@
* Reserved.
*/
#include "Fundamentals.h"
#include "Liveness.h"
public final class IJSPC
{
public IScript script;
public int offset;
}

View File

@@ -0,0 +1,23 @@
/* -*- 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.
*/
public final class IJSSourceLocation
{
public int line;
public IJSPC pc;
}

View File

@@ -0,0 +1,23 @@
/* -*- 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.
*/
public final class IJSStackFrameInfo
{
public IJSPC pc;
public int jsdframe;
}

View File

@@ -0,0 +1,65 @@
/* -*- 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.
*/
public final class IJSThreadState
{
/**
* partial list of thread states from sun.debug.ThreadInfo.
* XXX some of these don't apply.
*/
public final static int THR_STATUS_UNKNOWN = 0x01;
public final static int THR_STATUS_ZOMBIE = 0x02;
public final static int THR_STATUS_RUNNING = 0x03;
public final static int THR_STATUS_SLEEPING = 0x04;
public final static int THR_STATUS_MONWAIT = 0x05;
public final static int THR_STATUS_CONDWAIT = 0x06;
public final static int THR_STATUS_SUSPENDED = 0x07;
public final static int THR_STATUS_BREAK = 0x08;
public final static int DEBUG_STATE_DEAD = 0x01;
/**
* if the continueState is RUN, the thread will
* proceed to the next program counter value when it resumes.
*/
public final static int DEBUG_STATE_RUN = 0x02;
/**
* if the continueState is RETURN, the thread will
* return from the current method with the value in getReturnValue()
* when it resumes.
*/
public final static int DEBUG_STATE_RETURN = 0x03;
/**
* if the continueState is THROW, the thread will
* throw an exception (accessible with getException()) when it
* resumes.
*/
public final static int DEBUG_STATE_THROW = 0x04;
public IJSStackFrameInfo[] stack;
public int continueState;
public String returnValue;
public int status;
public int jsdthreadstate;
public int id; // used for referencing this object
}

View File

@@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- 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,14 +16,13 @@
* Reserved.
*/
#ifndef _SSA_TOOLS_H_
#define _SSA_TOOLS_H_
public final class IScript
{
public String url;
public String funname;
public int base;
public int extent;
public int jsdscript;
public IScriptSection[] sections;
}
#include "Fundamentals.h"
class ControlGraph;
class VirtualRegisterManager;
extern void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager);
#endif // _SSA_TOOLS_H_

View File

@@ -0,0 +1,24 @@
/* -*- 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.
*/
public interface IScriptHook extends org.omg.CORBA.Object
{
public void justLoadedScript(IScript script);
public void aboutToUnloadScript(IScript script);
}

View File

@@ -0,0 +1,23 @@
/* -*- 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.
*/
public final class IScriptSection
{
public int base;
public int extent;
}

View File

@@ -0,0 +1,37 @@
/* -*- 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.
*/
public interface ISourceTextProvider extends org.omg.CORBA.Object
{
/* these coorespond to jsdebug.h values - change in both places if anywhere */
public static final int INITED = 0;
public static final int FULL = 1;
public static final int PARTIAL = 2;
public static final int ABORTED = 3;
public static final int FAILED = 4;
public static final int CLEARED = 5;
public String[] getAllPages();
public void refreshAllPages();
public boolean hasPage(String url);
public boolean loadPage(String url);
public void refreshPage(String url);
public String getPageText(String url);
public int getPageStatus(String url);
public int getPageAlterCount(String url);
}

View File

@@ -0,0 +1,25 @@
/* jband - 09/09/97 - readme for the dreaded js/jsd/corba system */
This stuff in js/jsd/corba/src is used to generate corba source in IDL, Java,
and C++. The raw source is all Java. The 'makefile' is mk.bat which is currently
expected to run only on jband's NT box. All of the important output of this
process should be checked in to cvs. mk.bat is only needed to regenerate new
sources as the interfaces change. Those new sources should then be committed to
cvs.
The main scheme here is to use the Java code in js/jsd/corba/src as idl.
mk.bat uses java2idl, orbeline, and idl2java to generate IDL and stubs and
skeletons in C++ and Java. There are a few hacks to deal with limitations of
these tools.
The C++ output is copied to js/jsd/corba.
The Java output is copied to
js/jsdj/classes/com/netscape/jsdebugging/remote/corba.
Note that the files:
StringReciever.java
TestInterface.java
Thing.java
are used only in test programs and are not part of the product

View File

@@ -0,0 +1,24 @@
/* -*- 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.
*/
public interface StringReciever extends org.omg.CORBA.Object
{
public void recieveString(String s);
public void bounce(int count);
}

View File

@@ -0,0 +1,26 @@
/* -*- 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.
*/
public interface TestInterface extends org.omg.CORBA.Object
{
public String getFirstAppInList();
public void getAppNames( StringReciever sr );
public Thing[] getThings();
public void callBounce( StringReciever sr, int count );
}

View File

@@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- 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,5 +16,9 @@
* Reserved.
*/
#include "Fundamentals.h"
#include "HashSet.h"
public final class Thing
{
public String s;
public int i;
}

BIN
mozilla/js/jsd/corba/src/WAIT.COM Executable file

Binary file not shown.

View File

@@ -0,0 +1,31 @@
/* -*- 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 class only exist to force a forward declaration in the outputed
// idl file.
//
// It should be handed to java2idl after IScriptSection.class but before
// IScript.class
//
public final class bogus0
{
public IScriptSection[] bogus;
}

View File

@@ -0,0 +1,31 @@
/* -*- 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 class only exist to force a forward declaration in the outputed
// idl file.
//
// It should be handed to java2idl after IJSStackFrameInfo.class but before
// IJSThreadState.class
//
public final class bogus1
{
public IJSStackFrameInfo[] bogus;
}

View File

@@ -0,0 +1,43 @@
# -*- 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.
#
# see usage...
#
BEGIN {
skiplines_left = 0
if( 0 == lines || 0 == pat )
{
# show usage...
print "\n"
print "strips some lines when first line contains pattern\n"
print "\tusage -v pat=\"pattern\" -v lines=3"
}
}
{
if( skiplines_left )
skiplines_left--;
else
{
if( match($0, pat) != 0 )
skiplines_left = lines-1;
else
print $0;
}
}

143
mozilla/js/jsd/corba/src/mk.bat Executable file
View File

@@ -0,0 +1,143 @@
@echo off
REM
REM This needs to be run from the src dir. It generates sibling dirs and their
REM contents.
REM
set base_package=com.netscape.jsdebugging.remote.corba
set base_packslash=com\netscape\jsdebugging\remote\corba
set jsdj_classes_dir=..\..\..\jsdj\classes
set DELAY=6
rem -------------------------------------------------------------------------
rem -- show settings
echo.
echo commandline: %0 %1 %2 %3 %4 %5 %6 %7 %8 %9
echo.
echo ES3_ROOT = %ES3_ROOT%
echo base_package = %base_package% // set in this file
echo jsdj_classes_dir = %jsdj_classes_dir% // set in this file
echo.
rem -------------------------------------------------------------------------
rem -- check for environment settings
if "%ES3_ROOT%" == "" goto usage
set jc=sj.exe
set cp=.;%ES3_ROOT%\wai\java\nisb.zip;%ES3_ROOT%\wai\java\WAI.zip;%ES3_ROOT%\plugins\Java\classes\serv3_0.zip
set old_classpath=%CLASSPATH%
set CLASSPATH=%CLASSPATH%;%ES3_ROOT%\wai\java\nisb.zip;%ES3_ROOT%\wai\java\WAI.zip
echo.
echo creating output dirs
if not exist ..\class\NUL mkdir ..\class
if not exist ..\idl\NUL mkdir ..\idl
if not exist ..\java\NUL mkdir ..\java
if not exist ..\cpp\NUL mkdir ..\cpp
echo.
echo compiling raw Java interfaces
%jc% -classpath %cp% *.java -d ..\class
..\src\wait %DELAY%
cd ..\class
echo.
echo.
echo generating idl
echo.
REM
REM THESE ARE HAND ORDERED TO DEAL WITH DEPENDENCIES
REM
%ES3_ROOT%\wai\bin\java2idl Thing.class StringReciever.class TestInterface.class ISourceTextProvider.class IScriptSection.class bogus0.class IScript.class IJSPC.class IJSSourceLocation.class IJSErrorReporter.class IScriptHook.class IJSStackFrameInfo.class bogus1.class IJSThreadState.class IJSExecutionHook.class IExecResult.class IDebugController.class > ..\idl\ifaces.idl
..\src\wait %DELAY%
cd ..\idl
echo.
echo.
echo stripping lines from idl which were added to correctly order declarations
echo.
copy ifaces.idl ifaces_original.idl
REM
REM since we currenly have 2 of these, we can avoid the copy
REM
gawk -v pat="struct bogus0" -v lines=3 -f ..\src\cutlines.awk < ifaces.idl > temp.idl
gawk -v pat="struct bogus1" -v lines=3 -f ..\src\cutlines.awk < temp.idl > ifaces.idl
REM copy temp.idl ifaces.idl
REM ..\src\wait %DELAY%
cd ..\cpp
echo.
echo.
echo generating cpp
echo.
%ES3_ROOT%\wai\bin\orbeline ..\idl\ifaces.idl
..\src\wait %DELAY%
cd ..\java
echo.
echo.
echo generating java
echo.
%ES3_ROOT%\wai\bin\idl2java ..\idl\ifaces.idl -package %base_package% -no_examples -no_tie -no_comments
..\src\wait %DELAY%
cd ..\src
echo.
echo. copying generated files
echo.
REM
REM preserve generated java, but put ours in the outdir
REM
xcopy /Q ..\java\%base_packslash%\*.java ..\java\%base_packslash%\_unused\*.jav
REM
REM *****CUSTOMIZE HERE AS NEW INTERFACES WITH static ints ARE ADDED*****
REM
copy ..\src\package_header.h+..\src\ISourceTextProvider.java ..\java\%base_packslash%\ISourceTextProvider.java
copy ..\src\package_header.h+..\src\IJSErrorReporter.java ..\java\%base_packslash%\IJSErrorReporter.java
copy ..\src\package_header.h+..\src\IJSThreadState.java ..\java\%base_packslash%\IJSThreadState.java
copy ..\src\package_header.h+..\src\IDebugController.java ..\java\%base_packslash%\IDebugController.java
REM
REM
xcopy /Q ..\cpp\ifaces_c.hh ..\
xcopy /Q ..\cpp\ifaces_s.hh ..\
xcopy /Q ..\cpp\ifaces_c.cc ..\ifaces_c.cpp
xcopy /Q ..\cpp\ifaces_s.cc ..\ifaces_s.cpp
if "%jsdj_classes_dir%" == "" goto done
if not exist %jsdj_classes_dir%\NUL goto done
xcopy /Q /S ..\java\*.java %jsdj_classes_dir%
goto done
:usage
echo.
echo usage:
echo mk
echo.
echo See "readme.txt" for details...
echo.
echo Rules:
echo.
echo These must be defined in environment:
echo ES3_ROOT // location of Enterprise Server (e.g. e:\Netscape\SuiteSpot)
echo.
:done
..\src\wait %DELAY%
cd ..\src
set base_package=
set base_packslash=
set jsdj_classes_dir=
set cp=
set jc=
set DELAY=
set CLASSPATH=%old_classpath%
set old_classpath=
echo.
echo.
echo done
echo.

View File

@@ -0,0 +1,3 @@
package com.netscape.jsdebugging.remote.corba;

View File

@@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- 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,23 +16,20 @@
* Reserved.
*/
#ifndef _REGISTER_ASSIGNER_H_
#define _REGISTER_ASSIGNER_H_
/*
* This supplies non-functional stubs for a couple of JNI functions we need
* in order to link LiveConnect
*/
#include "Fundamentals.h"
#include "VirtualRegister.h"
#include "jni.h"
class FastBitMatrix;
class RegisterAssigner
jint JNICALL JNI_GetDefaultJavaVMInitArgs(void * ignored)
{
protected:
VirtualRegisterManager& vRegManager;
public:
RegisterAssigner(VirtualRegisterManager& vrMan) : vRegManager(vrMan) {}
virtual bool assignRegisters(FastBitMatrix& interferenceMatrix) = 0;
};
return 0;
}
jint JNICALL JNI_CreateJavaVM(JavaVM ** vm, JNIEnv ** env, void * ignored)
{
return 0;
}
#endif /* _REGISTER_ASSIGNER_H_ */

View File

@@ -0,0 +1,33 @@
JSDJNI = .
#CLASS_DIR_BASE = $(JSDJNI)\..\..\..\jsdj\dist\classes
# until jsdj moves to mozilla...
CLASS_DIR_BASE = $(JSDJNI)\..\..\..\..\..\ns\js\jsdj\dist\classes
GEN = $(JSDJNI)\_jni
HEADER_FILE = $(GEN)\jsdjnih.h
PACKAGE_SLASH = netscape\jsdebug
PACKAGE_DOT = netscape.jsdebug
STD_CLASSPATH = -classpath $(CLASS_DIR_BASE);$(CLASSPATH)
CLASSES_WITH_NATIVES = \
$(PACKAGE_DOT).DebugController \
$(PACKAGE_DOT).JSPC \
$(PACKAGE_DOT).JSSourceTextProvider \
$(PACKAGE_DOT).JSStackFrameInfo \
$(PACKAGE_DOT).JSThreadState \
$(PACKAGE_DOT).Script \
$(PACKAGE_DOT).SourceTextProvider \
$(PACKAGE_DOT).ThreadStateBase \
$(PACKAGE_DOT).Value
all: $(GEN)
@echo generating JNI headers
@javah -jni -o "$(HEADER_FILE)" $(STD_CLASSPATH) $(CLASSES_WITH_NATIVES)
$(GEN) :
@mkdir $(GEN)
clean:
@if exist $(HEADER_FILE) @del $(HEADER_FILE) > NUL

View File

@@ -0,0 +1,134 @@
/* -*- 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 Sun Microsystems, Inc.
* Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
/*
* Portable JRE support functions - pared this down to minimal set I need
*/
#include <string.h>
#include <stdlib.h>
#include <jni.h>
#include "jre.h"
/*
* Exits the runtime with the specified error message.
*/
void
JRE_FatalError(JNIEnv *env, const char *msg)
{
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
}
(*env)->FatalError(env, msg);
}
/*
* Parses a runtime version string. Returns 0 if the successful, otherwise
* returns -1 if the format of the version string was invalid.
*/
jint
JRE_ParseVersion(const char *ver, char **majorp, char **minorp, char **microp)
{
int n1 = 0, n2 = 0, n3 = 0;
sscanf(ver, "%*[0-9]%n.%*[0-9]%n.%*[0-9a-zA-Z]%n", &n1, &n2, &n3);
if (n1 == 0 || n2 == 0) {
return -1;
}
if (n3 != 0) {
if (n3 != (int)strlen(ver)) {
return -1;
}
} else if (n2 != (int)strlen(ver)) {
return -1;
}
*majorp = JRE_Malloc(n1 + 1);
strncpy(*majorp, ver, n1);
(*majorp)[n1] = 0;
*minorp = JRE_Malloc(n2 - n1);
strncpy(*minorp, ver + n1 + 1, n2 - n1 - 1);
(*minorp)[n2 - n1 - 1] = 0;
if (n3 != 0) {
*microp = JRE_Malloc(n3 - n2);
strncpy(*microp, ver + n2 + 1, n3 - n2 - 1);
(*microp)[n3 - n2 - 1] = 0;
}
return 0;
}
/*
* Creates a version number string from the specified major, minor, and
* micro version numbers.
*/
char *
JRE_MakeVersion(const char *major, const char *minor, const char *micro)
{
char *ver = 0;
if (major != 0 && minor != 0) {
int len = strlen(major) + strlen(minor);
if (micro != 0) {
ver = JRE_Malloc(len + strlen(micro) + 3);
sprintf(ver, "%s.%s.%s", major, minor, micro);
} else {
ver = JRE_Malloc(len + 2);
sprintf(ver, "%s.%s", major, minor);
}
}
return ver;
}
/*
* Allocate memory or die.
*/
void *
JRE_Malloc(size_t size)
{
void *p = malloc(size);
if (p == 0) {
perror("malloc");
exit(1);
}
return p;
}

View File

@@ -0,0 +1,85 @@
/* -*- 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 Sun Microsystems, Inc.
* Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
/*
* Portable JRE support functions - pared this down to minimal set I need
*/
#include <stdio.h>
#include <stdlib.h>
#include <jni.h>
#include "jre_md.h"
/*
* Java runtime settings.
*/
typedef struct JRESettings {
char *javaHome; /* Java home directory */
char *runtimeLib; /* Runtime shared library or DLL */
char *classPath; /* Default class path */
char *compiler; /* Just-in-time (JIT) compiler */
char *majorVersion; /* Major version of runtime */
char *minorVersion; /* Minor version of runtime */
char *microVersion; /* Micro version of runtime */
} JRESettings;
/*
* JRE functions.
*/
void *JRE_LoadLibrary(const char *path);
void JRE_UnloadLibrary(void *handle);
jint JRE_GetDefaultJavaVMInitArgs(void *handle, void *vmargsp);
jint JRE_CreateJavaVM(void *handle, JavaVM **vmp, JNIEnv **envp,
void *vmargsp);
jint JRE_GetCurrentSettings(JRESettings *set);
jint JRE_GetSettings(JRESettings *set, const char *ver);
jint JRE_GetDefaultSettings(JRESettings *set);
jint JRE_ParseVersion(const char *version,
char **majorp, char **minorp, char **microp);
char *JRE_MakeVersion(const char *major, const char *minor, const char *micro);
void *JRE_Malloc(size_t size);
void JRE_FatalError(JNIEnv *env, const char *msg);
char *JRE_GetDefaultRuntimeLib(const char *dir);
char *JRE_GetDefaultClassPath(const char *dir);

View File

@@ -0,0 +1,290 @@
/*
* @(#)jre_md.c 1.6 97/05/15 David Connelly
*
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
/*
* Win32 specific JRE support functions
*/
#include <windows.h>
#include <stdlib.h>
#include <jni.h>
#include "jre.h"
#define JRE_KEY "Software\\JavaSoft\\Java Runtime Environment"
#define JDK_KEY "Software\\JavaSoft\\Java Development Kit"
#define RUNTIME_LIB "javai.dll"
/* From jre_main.c */
extern jboolean debug;
/* Forward Declarations */
jint LoadSettings(JRESettings *set, HKEY key);
jint GetSettings(JRESettings *set, const char *version, const char *keyname);
char *GetStringValue(HKEY key, const char *name);
/*
* Retrieve settings from registry for current runtime version. Returns
* 0 if successful otherwise returns -1 if no installed runtime was found
* or the registry data was invalid.
*/
jint
JRE_GetCurrentSettings(JRESettings *set)
{
jint r = -1;
HKEY key;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, JRE_KEY, 0, KEY_READ, &key) == 0) {
char *ver = GetStringValue(key, "CurrentVersion");
if (ver != 0) {
r = JRE_GetSettings(set, ver);
}
free(ver);
RegCloseKey(key);
}
return r;
}
/*
* Retrieves settings from registry for specified runtime version.
* Searches for either installed JRE and JDK runtimes. Returns 0 if
* successful otherwise returns -1 if requested version of runtime
* could not be found.
*/
jint
JRE_GetSettings(JRESettings *set, const char *version)
{
if (GetSettings(set, version, JRE_KEY) != 0) {
return GetSettings(set, version, JDK_KEY);
}
return 0;
}
jint
GetSettings(JRESettings *set, const char *version, const char *keyname)
{
HKEY key;
int r = -1;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &key) == 0) {
char *major, *minor, *micro = 0;
if (JRE_ParseVersion(version, &major, &minor, &micro) == 0) {
HKEY subkey;
char *ver = JRE_MakeVersion(major, minor, 0);
set->majorVersion = major;
set->minorVersion = minor;
if (RegOpenKeyEx(key, ver, 0, KEY_READ, &subkey) == 0) {
if ((r = LoadSettings(set, subkey)) == 0) {
if (micro != 0) {
if (set->microVersion == 0 ||
strcmp(micro, set->microVersion) != 0) {
r = -1;
}
}
}
RegCloseKey(subkey);
}
free(ver);
}
RegCloseKey(key);
}
return r;
}
/*
* Load runtime settings from specified registry key. Returns 0 if
* successful otherwise -1 if the registry data was invalid.
*/
static jint
LoadSettings(JRESettings *set, HKEY key)
{
/* Full path name of JRE home directory (required) */
set->javaHome = GetStringValue(key, "JavaHome");
if (set->javaHome == 0) {
return -1;
}
/* Full path name of JRE runtime DLL */
set->runtimeLib = GetStringValue(key, "RuntimeLib");
if (set->runtimeLib == 0) {
set->runtimeLib = JRE_GetDefaultRuntimeLib(set->javaHome);
}
/* Class path setting to override default */
set->classPath = GetStringValue(key, "ClassPath");
if (set->classPath == 0) {
set->classPath = JRE_GetDefaultClassPath(set->javaHome);
}
/* Optional JIT compiler library name */
set->compiler = GetStringValue(key, "Compiler");
/* Release micro-version */
set->microVersion = GetStringValue(key, "MicroVersion");
return 0;
}
/*
* Returns string data for the specified registry value name, or
* NULL if not found.
*/
static char *
GetStringValue(HKEY key, const char *name)
{
DWORD type, size;
char *value = 0;
if (RegQueryValueEx(key, name, 0, &type, 0, &size) == 0 &&
type == REG_SZ ) {
value = JRE_Malloc(size);
if (RegQueryValueEx(key, name, 0, 0, value, &size) != 0) {
free(value);
value = 0;
}
}
return value;
}
/*
* Returns default runtime settings based on location of this program.
* Makes best attempt at determining location of runtime. Returns 0
* if successful or -1 if a runtime could not be found.
*/
jint
JRE_GetDefaultSettings(JRESettings *set)
{
char buf[MAX_PATH], *bp;
int n;
// Try to obtain default value for Java home directory based on
// location of this executable.
if ((n = GetModuleFileName(0, buf, MAX_PATH)) == 0) {
return -1;
}
bp = buf + n;
while (*--bp != '\\') ;
bp -= 4;
if (bp < buf || strnicmp(bp, "\\bin", 4) != 0) {
return -1;
}
*bp = '\0';
set->javaHome = strdup(buf);
// Get default runtime library
set->runtimeLib = JRE_GetDefaultRuntimeLib(set->javaHome);
// Get default class path
set->classPath = JRE_GetDefaultClassPath(set->javaHome);
// Reset other fields since these are unknown
set->compiler = 0;
set->majorVersion = 0;
set->minorVersion = 0;
set->microVersion = 0;
return 0;
}
/*
* Return default runtime library for specified Java home directory.
*/
char *
JRE_GetDefaultRuntimeLib(const char *dir)
{
char *cp = JRE_Malloc(strlen(dir) + sizeof(RUNTIME_LIB) + 8);
sprintf(cp, "%s\\bin\\" RUNTIME_LIB, dir);
return cp;
}
/*
* Return default class path for specified Java home directory.
*/
char *
JRE_GetDefaultClassPath(const char *dir)
{
char *cp = JRE_Malloc(strlen(dir) * 4 + 64);
sprintf(cp, "%s\\lib\\rt.jar;%s\\lib\\i18n.jar;%s\\lib\\classes.zip;"
"%s\\classes", dir, dir, dir, dir);
return cp;
}
/*
* Loads the runtime library corresponding to 'libname' and returns
* an opaque handle to the library.
*/
void *
JRE_LoadLibrary(const char *path)
{
return (void *)LoadLibrary(path);
}
/*
* Unloads the runtime library associated with handle.
*/
void
JRE_UnloadLibrary(void *handle)
{
FreeLibrary(handle);
}
/*
* Loads default VM args for the specified runtime library handle.
*/
jint
JRE_GetDefaultJavaVMInitArgs(void *handle, void *vmargs)
{
FARPROC proc = GetProcAddress(handle, "JNI_GetDefaultJavaVMInitArgs");
return proc != 0 ? ((*proc)(vmargs), 0) : -1;
}
/*
* Creates a Java VM for the specified runtime library handle.
*/
jint
JRE_CreateJavaVM(void *handle, JavaVM **vmp, JNIEnv **envp, void *vmargs)
{
FARPROC proc = GetProcAddress(handle, "JNI_CreateJavaVM");
return proc != 0 ? (*proc)(vmp, envp, vmargs) : -1;
}
/*
* Entry point for JREW (Windows-only) version of the runtime loader.
* This entry point is called when the '-subsystem:windows' linker
* option is used, and will cause the resulting executable to run
* detached from the console.
*/
/**
* int WINAPI
* WinMain(HINSTANCE inst, HINSTANCE prevInst, LPSTR cmdLine, int cmdShow)
* {
* __declspec(dllimport) char **__initenv;
*
* __initenv = _environ;
* exit(main(__argc, __argv));
* }
*/

View File

@@ -0,0 +1,36 @@
/*
* @(#)jre_md.h 1.1 97/05/19 David Connelly
*
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
/*
* Win32 specific JRE support definitions
*/
#define FILE_SEPARATOR '\\'
#define PATH_SEPARATOR ';'

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,349 @@
/* -*- 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 Sun Microsystems, Inc.
* Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
/*
* Code to start a Java VM (*some* code from the JRE)
*/
#include "jsdj.h"
/***************************************************************************/
#ifdef JSD_STANDALONE_JAVA_VM
#include "jre.h"
static char* more_classpath[] =
{
{"..\\..\\jsdj\\dist\\classes"},
{"..\\..\\jsdj\\dist\\classes\\ifc11.jar"},
/*
* {"..\\..\\..\\jsdj\\dist\\classes"},
* {"..\\..\\..\\jsdj\\dist\\classes\\ifc12.jar"},
*/
/*
* {"..\\..\\samples\\jslogger"},
* {"classes"},
* {"ifc12.jar"},
* {"jsd10.jar"},
* {"jsdeb15.jar"}
*/
};
#define MORE_CLASSPATH_COUNT (sizeof(more_classpath)/sizeof(more_classpath[0]))
/*
* static char main_class[] = "callnative";
* static char main_class[] = "simpleIFC";
* static char* params[] = {"16 Dec 1997"};
* #define PARAM_COUNT (sizeof(params)/sizeof(params[0]))
*/
/*
* static char main_class[] = "netscape/jslogger/JSLogger";
* static char main_class[] = "LaunchJSDebugger";
*/
static char main_class[] = "com/netscape/jsdebugging/ifcui/launcher/local/LaunchJSDebugger";
static char* params[] = {NULL};
#define PARAM_COUNT 0
/* Globals */
static char **props; /* User-defined properties */
static int numProps, maxProps; /* Current, max number of properties */
static void *handle;
static JavaVM *jvm;
static JNIEnv *env;
/* Check for null value and return */
#define NULL_CHECK(e) if ((e) == 0) return 0
/*
* Adds a user-defined system property definition.
*/
void AddProperty(char *def)
{
if (numProps >= maxProps) {
if (props == 0) {
maxProps = 4;
props = JRE_Malloc(maxProps * sizeof(char **));
} else {
char **tmp;
maxProps *= 2;
tmp = JRE_Malloc(maxProps * sizeof(char **));
memcpy(tmp, props, numProps * sizeof(char **));
free(props);
props = tmp;
}
}
props[numProps++] = def;
}
/*
* Deletes a property definition by name.
*/
void DeleteProperty(const char *name)
{
int i;
for (i = 0; i < numProps; ) {
char *def = props[i];
char *c = strchr(def, '=');
int n;
if (c != 0) {
n = c - def;
} else {
n = strlen(def);
}
if (strncmp(name, def, n) == 0) {
if (i < --numProps) {
memmove(&props[i], &props[i+1], (numProps-i) * sizeof(char **));
}
} else {
i++;
}
}
}
/*
* Creates an array of Java string objects from the specified array of C
* strings. Returns 0 if the array could not be created.
*/
jarray NewStringArray(JNIEnv *env, char **cpp, int count)
{
jclass cls;
jarray ary;
int i;
NULL_CHECK(cls = (*env)->FindClass(env, "java/lang/String"));
NULL_CHECK(ary = (*env)->NewObjectArray(env, count, cls, 0));
for (i = 0; i < count; i++) {
jstring str = (*env)->NewStringUTF(env, *cpp++);
NULL_CHECK(str);
(*env)->SetObjectArrayElement(env, ary, i, str);
(*env)->DeleteLocalRef(env, str);
}
return ary;
}
/***************************************************************************/
static JNIEnv*
_CreateJavaVM(void)
{
JNIEnv* env = NULL;
JDK1_1InitArgs vmargs;
JRESettings set;
printf("Starting Java...\n");
if(JRE_GetCurrentSettings(&set) != 0)
{
if(JRE_GetDefaultSettings(&set) != 0)
{
fprintf(stderr, "Could not locate Java runtime\n");
return NULL;
}
}
/* Load runtime library */
handle = JRE_LoadLibrary(set.runtimeLib);
if (handle == 0) {
fprintf(stderr, "Could not load runtime library: %s\n",
set.runtimeLib);
return NULL;
}
/* Add pre-defined system properties */
if (set.javaHome != 0) {
char *def = JRE_Malloc(strlen(set.javaHome) + 16);
sprintf(def, "java.home=%s", set.javaHome);
AddProperty(def);
}
if (set.compiler != 0) {
char *def = JRE_Malloc(strlen(set.compiler) + 16);
sprintf(def, "java.compiler=%s", set.compiler);
AddProperty(def);
}
/*
* The following is used to specify that we require at least
* JNI version 1.1. Currently, this field is not checked but
* will be starting with JDK/JRE 1.2. The value returned after
* calling JNI_GetDefaultJavaVMInitArgs() is the actual JNI version
* supported, and is always higher that the requested version.
*/
vmargs.version = 0x00010001;
if (JRE_GetDefaultJavaVMInitArgs(handle, &vmargs) != 0) {
fprintf(stderr, "Could not initialize Java VM\n");
return NULL;
}
/* Tack on our classpath */
if(MORE_CLASSPATH_COUNT)
{
int i;
int size = strlen(set.classPath) + 1;
char sep[2];
sep[0] = PATH_SEPARATOR;
sep[1] = 0;
for(i = 0; i < MORE_CLASSPATH_COUNT; i++)
size += strlen(more_classpath[i]) + 1;
vmargs.classpath = malloc(size);
if(vmargs.classpath == 0)
{
fprintf(stderr, "malloc error\n");
return NULL;
}
strcpy(vmargs.classpath, set.classPath);
for(i = 0; i < MORE_CLASSPATH_COUNT; i++)
{
strcat(vmargs.classpath, sep);
strcat(vmargs.classpath, more_classpath[i]);
}
}
else
{
vmargs.classpath = set.classPath;
}
/*
* fprintf(stderr, "classpath: %s\n", vmargs.classpath);
*/
/* Set user-defined system properties for Java VM */
if (props != 0) {
if (numProps == maxProps) {
char **tmp = JRE_Malloc((numProps + 1) * sizeof(char **));
memcpy(tmp, props, numProps * sizeof(char **));
free(props);
props = tmp;
}
props[numProps] = 0;
vmargs.properties = props;
}
/* verbose? */
/*
* vmargs.verbose = JNI_TRUE;
*/
/* Load and initialize Java VM */
if (JRE_CreateJavaVM(handle, &jvm, &env, &vmargs) != 0) {
fprintf(stderr, "Could not create Java VM\n");
return NULL;
}
/* Free properties */
if (props != 0) {
free(props);
}
return env;
}
static JSBool
_StartDebuggerFE(JNIEnv* env)
{
jclass clazz;
jmethodID mid;
jarray args;
/* Find class */
clazz = (*env)->FindClass(env, main_class);
if (clazz == 0) {
fprintf(stderr, "Class not found: %s\n", main_class);
return JS_FALSE;
}
/* Find main method of class */
mid = (*env)->GetStaticMethodID(env, clazz, "main",
"([Ljava/lang/String;)V");
if (mid == 0) {
fprintf(stderr, "In class %s: public static void main(String args[])"
" is not defined\n");
return JS_FALSE;
}
/* Invoke main method */
args = NewStringArray(env, params, PARAM_COUNT);
if (args == 0) {
JRE_FatalError(env, "Couldn't build argument list for main\n");
}
(*env)->CallStaticVoidMethod(env, clazz, mid, args);
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
}
return JS_TRUE;
}
JNIEnv*
jsdj_CreateJavaVMAndStartDebugger(JSDJContext* jsdjc)
{
JNIEnv* env = NULL;
env = _CreateJavaVM();
if( ! env )
return NULL;
jsdj_SetJNIEnvForCurrentThread(jsdjc, env);
if( ! jsdj_RegisterNatives(jsdjc) )
return NULL;
if( ! _StartDebuggerFE(env) )
return NULL;
return env;
}
#endif /* JSD_STANDALONE_JAVA_VM */
/***************************************************************************/

147
mozilla/js/jsd/java/jsdj.h Normal file
View File

@@ -0,0 +1,147 @@
/* -*- 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.
*/
/*
* Header for JavaScript Debugger JNI support (internal functions)
*/
#ifndef jsdj_h___
#define jsdj_h___
/* Get jstypes.h included first. After that we can use PR macros for doing
* this extern "C" stuff!
*/
#ifdef __cplusplus
extern "C"
{
#endif
#include "jstypes.h"
#ifdef __cplusplus
}
#endif
JS_BEGIN_EXTERN_C
#include "jsutil.h" /* Added by JSIFY */
#include "jshash.h" /* Added by JSIFY */
#include "jsdjava.h"
#include "jsobj.h"
#include "jsfun.h"
#include "jsdbgapi.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
JS_END_EXTERN_C
JS_BEGIN_EXTERN_C
/***************************************************************************/
/* defines copied from Java sources.
** NOTE: javah used to put these in the h files, but with JNI does not seem
** to do this anymore. Be careful with synchronization of these
**
*/
/* From: ThreadStateBase.java */
#define THR_STATUS_UNKNOWN 0x01
#define THR_STATUS_ZOMBIE 0x02
#define THR_STATUS_RUNNING 0x03
#define THR_STATUS_SLEEPING 0x04
#define THR_STATUS_MONWAIT 0x05
#define THR_STATUS_CONDWAIT 0x06
#define THR_STATUS_SUSPENDED 0x07
#define THR_STATUS_BREAK 0x08
#define DEBUG_STATE_DEAD 0x01
#define DEBUG_STATE_RUN 0x02
#define DEBUG_STATE_RETURN 0x03
#define DEBUG_STATE_THROW 0x04
/***************************************************************************/
/* Our structures */
typedef struct JSDJContext
{
JSDContext* jsdc;
JSHashTable* envTable;
jobject controller;
JSDJ_UserCallbacks callbacks;
void* user;
JSBool ownJSDC;
} JSDJContext;
/***************************************************************************/
/* Code validation support */
#ifdef DEBUG
extern void JSDJ_ASSERT_VALID_CONTEXT(JSDJContext* jsdjc);
#else
#define JSDJ_ASSERT_VALID_CONTEXT(x) ((void)0)
#endif
/***************************************************************************/
/* higher level functions */
extern JSDJContext*
jsdj_SimpleInitForSingleContextMode(JSDContext* jsdc,
JSDJ_GetJNIEnvProc getEnvProc, void* user);
extern JSBool
jsdj_SetSingleContextMode();
extern JSDJContext*
jsdj_CreateContext();
extern void
jsdj_DestroyContext(JSDJContext* jsdjc);
extern void
jsdj_SetUserCallbacks(JSDJContext* jsdjc, JSDJ_UserCallbacks* callbacks,
void* user);
extern void
jsdj_SetJNIEnvForCurrentThread(JSDJContext* jsdjc, JNIEnv* env);
extern JNIEnv*
jsdj_GetJNIEnvForCurrentThread(JSDJContext* jsdjc);
extern void
jsdj_SetJSDContext(JSDJContext* jsdjc, JSDContext* jsdc);
extern JSDContext*
jsdj_GetJSDContext(JSDJContext* jsdjc);
extern JSBool
jsdj_RegisterNatives(JSDJContext* jsdjc);
/***************************************************************************/
#ifdef JSD_STANDALONE_JAVA_VM
extern JNIEnv*
jsdj_CreateJavaVMAndStartDebugger(JSDJContext* jsdjc);
/**
* extern JNIEnv*
* jsdj_CreateJavaVM(JSDContext* jsdc);
*/
#endif /* JSD_STANDALONE_JAVA_VM */
/***************************************************************************/
JS_END_EXTERN_C
#endif /* jsdj_h___ */

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.
*/
/*
* Public functions to reflect JSD into Java
*/
#include "jsdj.h"
JSDJ_PUBLIC_API(JSDJContext*)
JSDJ_SimpleInitForSingleContextMode(JSDContext* jsdc,
JSDJ_GetJNIEnvProc getEnvProc, void* user)
{
return jsdj_SimpleInitForSingleContextMode(jsdc, getEnvProc, user);
}
JSDJ_PUBLIC_API(JSBool)
JSDJ_SetSingleContextMode()
{
return jsdj_SetSingleContextMode();
}
JSDJ_PUBLIC_API(JSDJContext*)
JSDJ_CreateContext()
{
return jsdj_CreateContext();
}
JSDJ_PUBLIC_API(void)
JSDJ_DestroyContext(JSDJContext* jsdjc)
{
JSDJ_ASSERT_VALID_CONTEXT(jsdjc);
jsdj_DestroyContext(jsdjc);
}
JSDJ_PUBLIC_API(void)
JSDJ_SetUserCallbacks(JSDJContext* jsdjc, JSDJ_UserCallbacks* callbacks,
void* user)
{
JSDJ_ASSERT_VALID_CONTEXT(jsdjc);
JS_ASSERT(!callbacks ||
(callbacks->size > 0 &&
callbacks->size <= sizeof(JSDJ_UserCallbacks)));
jsdj_SetUserCallbacks(jsdjc, callbacks, user);
}
JSDJ_PUBLIC_API(void)
JSDJ_SetJNIEnvForCurrentThread(JSDJContext* jsdjc, JNIEnv* env)
{
JSDJ_ASSERT_VALID_CONTEXT(jsdjc);
JS_ASSERT(env);
jsdj_SetJNIEnvForCurrentThread(jsdjc, env);
}
JSDJ_PUBLIC_API(JNIEnv*)
JSDJ_GetJNIEnvForCurrentThread(JSDJContext* jsdjc)
{
JSDJ_ASSERT_VALID_CONTEXT(jsdjc);
return jsdj_GetJNIEnvForCurrentThread(jsdjc);
}
JSDJ_PUBLIC_API(void)
JSDJ_SetJSDContext(JSDJContext* jsdjc, JSDContext* jsdc)
{
JSDJ_ASSERT_VALID_CONTEXT(jsdjc);
JS_ASSERT(jsdc);
jsdj_SetJSDContext(jsdjc, jsdc);
}
JSDJ_PUBLIC_API(JSDContext*)
JSDJ_GetJSDContext(JSDJContext* jsdjc)
{
JSDJ_ASSERT_VALID_CONTEXT(jsdjc);
return jsdj_GetJSDContext(jsdjc);
}
JSDJ_PUBLIC_API(JSBool)
JSDJ_RegisterNatives(JSDJContext* jsdjc)
{
JSDJ_ASSERT_VALID_CONTEXT(jsdjc);
return jsdj_RegisterNatives(jsdjc);
}
/***************************************************************************/
#ifdef JSD_STANDALONE_JAVA_VM
JSDJ_PUBLIC_API(JNIEnv*)
JSDJ_CreateJavaVMAndStartDebugger(JSDJContext* jsdjc)
{
JSDJ_ASSERT_VALID_CONTEXT(jsdjc);
return jsdj_CreateJavaVMAndStartDebugger(jsdjc);
}
#endif /* JSD_STANDALONE_JAVA_VM */
/***************************************************************************/

View File

@@ -0,0 +1,133 @@
/* -*- 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.
*/
/*
* Header for JavaScript Debugger JNI interfaces
*/
#ifndef jsdjava_h___
#define jsdjava_h___
/* Get jstypes.h included first. After that we can use PR macros for doing
* this extern "C" stuff!
*/
#ifdef __cplusplus
extern "C"
{
#endif
#include "jstypes.h"
#ifdef __cplusplus
}
#endif
JS_BEGIN_EXTERN_C
#include "jsdebug.h"
#include "jni.h"
JS_END_EXTERN_C
JS_BEGIN_EXTERN_C
/*
* The linkage of JSDJ API functions differs depending on whether the file is
* used within the JSDJ library or not. Any source file within the JSDJ
* libraray should define EXPORT_JSDJ_API whereas any client of the library
* should not.
*/
#ifdef EXPORT_JSDJ_API
#define JSDJ_PUBLIC_API(t) JS_EXPORT_API(t)
#define JSDJ_PUBLIC_DATA(t) JS_EXPORT_DATA(t)
#else
#define JSDJ_PUBLIC_API(t) JS_IMPORT_API(t)
#define JSDJ_PUBLIC_DATA(t) JS_IMPORT_DATA(t)
#endif
#define JSDJ_FRIEND_API(t) JSDJ_PUBLIC_API(t)
#define JSDJ_FRIEND_DATA(t) JSDJ_PUBLIC_DATA(t)
/***************************************************************************/
/* Opaque typedefs for handles */
typedef struct JSDJContext JSDJContext;
/***************************************************************************/
/* High Level functions */
#define JSDJ_START_SUCCESS 1
#define JSDJ_START_FAILURE 2
#define JSDJ_STOP 3
typedef void
(*JSDJ_StartStopProc)(JSDJContext* jsdjc, int event, void *user);
typedef JNIEnv*
(*JSDJ_GetJNIEnvProc)(JSDJContext* jsdjc, void* user);
/* This struct could have more fields in future versions */
typedef struct
{
uintN size; /* size of this struct (init before use)*/
JSDJ_StartStopProc startStop;
JSDJ_GetJNIEnvProc getJNIEnv;
} JSDJ_UserCallbacks;
extern JSDJ_PUBLIC_API(JSDJContext*)
JSDJ_SimpleInitForSingleContextMode(JSDContext* jsdc,
JSDJ_GetJNIEnvProc getEnvProc, void* user);
extern JSDJ_PUBLIC_API(JSBool)
JSDJ_SetSingleContextMode();
extern JSDJ_PUBLIC_API(JSDJContext*)
JSDJ_CreateContext();
extern JSDJ_PUBLIC_API(void)
JSDJ_DestroyContext(JSDJContext* jsdjc);
extern JSDJ_PUBLIC_API(void)
JSDJ_SetUserCallbacks(JSDJContext* jsdjc, JSDJ_UserCallbacks* callbacks,
void* user);
extern JSDJ_PUBLIC_API(void)
JSDJ_SetJNIEnvForCurrentThread(JSDJContext* jsdjc, JNIEnv* env);
extern JSDJ_PUBLIC_API(JNIEnv*)
JSDJ_GetJNIEnvForCurrentThread(JSDJContext* jsdjc);
extern JSDJ_PUBLIC_API(void)
JSDJ_SetJSDContext(JSDJContext* jsdjc, JSDContext* jsdc);
extern JSDJ_PUBLIC_API(JSDContext*)
JSDJ_GetJSDContext(JSDJContext* jsdjc);
extern JSDJ_PUBLIC_API(JSBool)
JSDJ_RegisterNatives(JSDJContext* jsdjc);
/***************************************************************************/
#ifdef JSD_STANDALONE_JAVA_VM
extern JSDJ_PUBLIC_API(JNIEnv*)
JSDJ_CreateJavaVMAndStartDebugger(JSDJContext* jsdjc);
#endif /* JSD_STANDALONE_JAVA_VM */
/***************************************************************************/
JS_END_EXTERN_C
#endif /* jsdjava_h___ */

View File

@@ -0,0 +1,78 @@
PROJ = jsdjava
JSDJAVA = .
JSD = $(JSDJAVA)\..
JS = $(JSD)\..\src
JSPROJ = js32
JSDPROJ = jsd
!IF "$(BUILD_OPT)" != ""
OBJ = Release
CC_FLAGS = /DNDEBUG
!ELSE
OBJ = Debug
CC_FLAGS = /DDEBUG
LINK_FLAGS = /DEBUG
!ENDIF
QUIET=@
CFLAGS = /nologo /MDd /W3 /Gm /GX /Zi /Od\
/I $(JS)\
/I $(JSD)\
/I $(JSDJAVA)\
/DDEBUG /DWIN32 /DXP_PC /D_WINDOWS /D_WIN32\
/DJSD_THREADSAFE\
/DEXPORT_JSDJ_API\
/DJSDEBUGGER\
!IF "$(JSD_STANDALONE_JAVA_VM)" != ""
/I $(JSDJAVA)\jre\
/I $(JSDJAVA)\jre\win32\
/DJSD_STANDALONE_JAVA_VM\
!ENDIF
$(CC_FLAGS)\
/c /Fp$(OBJ)\$(PROJ).pch /Fd$(OBJ)\$(PROJ).pdb /YX -Fo$@ $<
LFLAGS = /nologo /subsystem:console /DLL /incremental:no /machine:I386 \
$(LINK_FLAGS) /pdb:$(OBJ)\$(PROJ).pdb -out:$(OBJ)\$(PROJ).dll
LLIBS = kernel32.lib advapi32.lib \
$(JS)\$(OBJ)\$(JSPROJ).lib $(JSD)\$(OBJ)\$(JSDPROJ).lib
CPP=cl.exe
LINK32=link.exe
all: $(OBJ) $(OBJ)\$(PROJ).dll
$(OBJ)\$(PROJ).dll: \
!IF "$(JSD_STANDALONE_JAVA_VM)" != ""
$(OBJ)\jsd_jvm.obj \
$(OBJ)\jre.obj \
$(OBJ)\jre_md.obj \
!ENDIF
$(OBJ)\jsdjava.obj \
$(OBJ)\jsd_jntv.obj
$(QUIET)$(LINK32) $(LFLAGS) $** $(LLIBS)
{$(JSDJAVA)}.c{$(OBJ)}.obj :
$(QUIET)$(CPP) $(CFLAGS)
{$(JSDJAVA)\jre}.c{$(OBJ)}.obj :
$(QUIET)$(CPP) $(CFLAGS)
{$(JSDJAVA)\jre\win32}.c{$(OBJ)}.obj :
$(QUIET)$(CPP) $(CFLAGS)
$(OBJ) :
$(QUIET)mkdir $(OBJ)
clean:
@echo deleting old output
$(QUIET)del $(OBJ)\*.pch >NUL
$(QUIET)del $(OBJ)\*.obj >NUL
$(QUIET)del $(OBJ)\*.exp >NUL
$(QUIET)del $(OBJ)\*.lib >NUL
$(QUIET)del $(OBJ)\*.idb >NUL
$(QUIET)del $(OBJ)\*.pdb >NUL
$(QUIET)del $(OBJ)\*.dll >NUL

View File

@@ -0,0 +1,147 @@
PROJ = nativejsengine
PACKAGE_DOT = com.netscape.nativejsengine
NJSE = .
TESTS = $(NJSE)\tests
GEN = $(NJSE)\_jni
JSD = $(NJSE)\..
JS = $(JSD)\..\src
JSDJAVA = $(JSD)\java
JSPROJ = js32
JSDPROJ = jsd
JSDJAVAPROJ = jsdjava
EXPORT_BIN_BASE_DIR = $(NJSE)\..\..\jsdj\dist\bin
EXPORT_CLASSES_BASE_DIR = $(NJSE)\..\..\jsdj\dist\classes
!IF "$(BUILD_OPT)" != ""
OBJ = Release
CC_FLAGS = /DNDEBUG
!ELSE
OBJ = Debug
CC_FLAGS = /DDEBUG
LINK_FLAGS = /DEBUG
!ENDIF
QUIET=@
EXPORT_BIN_DIR = $(EXPORT_BIN_BASE_DIR)\$(OBJ)
STD_CLASSPATH = -classpath $(EXPORT_CLASSES_BASE_DIR);$(CLASSPATH)
CFLAGS = /nologo /MDd /W3 /Gm /GX /Zi /Od\
/DWIN32 /DXP_PC /D_WINDOWS /D_WIN32\
/I $(JS)\
/I $(JSD)\
/I $(JSDJAVA)\
/DJSDEBUGGER\
/DJSD_THREADSAFE\
$(CC_FLAGS)\
/c /Fp$(OBJ)\$(PROJ).pch /Fd$(OBJ)\$(PROJ).pdb /YX -Fo$@ $<
LFLAGS = /nologo /subsystem:console /incremental:no /DLL /machine:I386 \
$(LINK_FLAGS) /pdb:$(OBJ)\$(PROJ).pdb -out:$(OBJ)\$(PROJ).dll
LLIBS = kernel32.lib advapi32.lib \
$(JS)\$(OBJ)\$(JSPROJ).lib \
$(JSD)\$(OBJ)\$(JSDPROJ).lib \
$(JSDJAVA)\$(OBJ)\$(JSDJAVAPROJ).lib
CPP=cl.exe
LINK32=link.exe
CLASSES_WITH_NATIVES = \
$(PACKAGE_DOT).JSRuntime\
$(PACKAGE_DOT).JSContext
all: $(GEN) $(OBJ) dlls mkjniheaders $(OBJ)\$(PROJ).dll export_binaries
$(OBJ)\$(PROJ).dll: \
$(OBJ)\nativejsengine.obj
$(QUIET)$(LINK32) $(LFLAGS) $** $(LLIBS)
.c{$(OBJ)}.obj:
$(QUIET)$(CPP) $(CFLAGS)
$(GEN) :
@mkdir $(GEN)
$(OBJ) :
@mkdir $(OBJ)
dlls :
$(QUIET)cd ..\..\src
!IF "$(BUILD_OPT)" != ""
$(QUIET)nmake -f js.mak CFG="js - Win32 Release"
!ELSE
$(QUIET)nmake -f js.mak CFG="js - Win32 Debug"
!ENDIF
$(QUIET)cd ..\jsd\javawrap
$(QUIET)cd ..
$(QUIET)nmake -f jsd.mak JSD_THREADSAFE=1 $(OPT)
$(QUIET)cd javawrap
$(QUIET)cd ..\java
$(QUIET)nmake -f jsdjava.mak $(OPT)
$(QUIET)cd ..\javawrap
export_binaries : mk_export_dirs
@echo exporting binaries
$(QUIET)copy $(JS)\$(OBJ)\$(JSPROJ).dll $(EXPORT_BIN_DIR) >NUL
$(QUIET)copy $(JS)\$(OBJ)\$(JSPROJ).pdb $(EXPORT_BIN_DIR) >NUL
$(QUIET)copy $(JSD)\$(OBJ)\$(JSDPROJ).dll $(EXPORT_BIN_DIR) >NUL
$(QUIET)copy $(JSD)\$(OBJ)\$(JSDPROJ).pdb $(EXPORT_BIN_DIR) >NUL
$(QUIET)copy $(JSDJAVA)\$(OBJ)\$(JSDJAVAPROJ).dll $(EXPORT_BIN_DIR) >NUL
$(QUIET)copy $(JSDJAVA)\$(OBJ)\$(JSDJAVAPROJ).pdb $(EXPORT_BIN_DIR) >NUL
$(QUIET)copy $(OBJ)\$(PROJ).pdb $(EXPORT_BIN_DIR) >NUL
$(QUIET)copy $(OBJ)\$(PROJ).dll $(EXPORT_BIN_DIR) >NUL
mkjniheaders :
@echo generating JNI header
$(QUIET)javah -jni -d "$(GEN)" $(STD_CLASSPATH) $(CLASSES_WITH_NATIVES)
@touch *.c >NUL
mk_export_dirs:
@if not exist $(JS)\..\jsdj\dist\NUL @mkdir $(JS)\..\jsdj\dist
@if not exist $(JS)\..\jsdj\dist\bin\NUL @mkdir $(JS)\..\jsdj\dist\bin
@if not exist $(EXPORT_BIN_DIR)\NUL @mkdir $(EXPORT_BIN_DIR)
#mktest :
# @echo compiling Java test file
# @sj $(JAVAFLAGS) $(TEST_CLASSPATH) $(TESTS)\Main.java
# @echo copying js and jsd dlls
# @copy $(JS)\$(OBJ)\$(JSPROJ).dll $(OBJ) >NUL
# @copy $(JS)\$(OBJ)\$(JSPROJ).pdb $(OBJ) >NUL
# @copy $(JSD)\$(OBJ)\$(JSDPROJ).dll $(OBJ) >NUL
# @copy $(JSD)\$(OBJ)\$(JSDPROJ).pdb $(OBJ) >NUL
# @copy $(TESTS)\*.js $(OBJ) >NUL
clean:
@echo deleting old output
$(QUIET)del $(OBJ)\*.pch >NUL
$(QUIET)del $(OBJ)\*.obj >NUL
$(QUIET)del $(OBJ)\*.exp >NUL
$(QUIET)del $(OBJ)\*.lib >NUL
$(QUIET)del $(OBJ)\*.idb >NUL
$(QUIET)del $(OBJ)\*.pdb >NUL
$(QUIET)del $(OBJ)\*.dll >NUL
$(QUIET)del $(GEN)\*.h >NUL
deep_clean: clean
$(QUIET)cd ..\..\src
!IF "$(BUILD_OPT)" != ""
$(QUIET)nmake -f js.mak CFG="js - Win32 Release" clean
!ELSE
$(QUIET)nmake -f js.mak CFG="js - Win32 Debug" clean
!ENDIF
$(QUIET)cd ..\jsd\javawrap
$(QUIET)cd ..
$(QUIET)nmake -f jsd.mak clean
$(QUIET)cd javawrap
$(QUIET)cd ..\java
$(QUIET)nmake -f jsdjava.mak clean
$(QUIET)cd ..\javawrap

1
mozilla/js/jsd/javawrap/mk.bat Executable file
View File

@@ -0,0 +1 @@
nmake -f javawrap.mak %1 %2 %3 %4 %5

View File

@@ -0,0 +1,616 @@
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "_jni/com_netscape_nativejsengine_JSRuntime.h"
#include "_jni/com_netscape_nativejsengine_JSContext.h"
#include "jsapi.h"
#include "jstypes.h"
#include "jsutil.h" /* Added by JSIFY */
#ifdef JSDEBUGGER
#include "jsdebug.h"
#include "jsdjava.h"
#endif
/***************************************************************************/
#define ASSERT_RETURN_VOID(x) \
JS_BEGIN_MACRO \
if(!(x)) \
{ \
JS_ASSERT(0); \
return; \
} \
JS_END_MACRO
#define ASSERT_RETURN_VALUE(x,v)\
JS_BEGIN_MACRO \
if(!(x)) \
{ \
JS_ASSERT(0); \
return v; \
} \
JS_END_MACRO
#define CHECK_RETURN_VOID(x) \
JS_BEGIN_MACRO \
if(!(x)) \
{ \
return; \
} \
JS_END_MACRO
#define CHECK_RETURN_VALUE(x,v) \
JS_BEGIN_MACRO \
if(!(x)) \
{ \
return v; \
} \
JS_END_MACRO
#define ASSERT_GOTO(x,w) \
JS_BEGIN_MACRO \
if(!(x)) \
{ \
JS_ASSERT(0); \
goto w; \
} \
JS_END_MACRO
#define CHECK_GOTO(x,w) \
JS_BEGIN_MACRO \
if(!(x)) \
{ \
goto w; \
} \
JS_END_MACRO
#ifdef DEBUG
#define ASSERT_CLEAR_EXCEPTION(e) \
JS_BEGIN_MACRO \
if((*e)->ExceptionOccurred(e)) \
{ \
(*e)->ExceptionDescribe(e); \
JS_ASSERT(0); \
} \
(*e)->ExceptionClear(e); \
JS_END_MACRO
#else /* ! DEBUG */
#define ASSERT_CLEAR_EXCEPTION(e) (*e)->ExceptionClear(e)
#endif /* DEBUG */
#define CHECK_CLEAR_EXCEPTION(e) (*e)->ExceptionClear(e)
/***************************************************************************/
typedef struct ContextInfo {
JNIEnv* env;
jobject contextObject;
} ContextInfo;
/***************************************************************************/
#ifdef JSDEBUGGER
static void
_jamSourceIntoJSD(JSContext *cx, const char* src, int len, const char* filename)
{
jclass clazz_self;
jclass clazz;
JSDJContext* jsdjc;
jobject rtObject;
jobject contextObject;
jmethodID mid;
jfieldID fid;
ContextInfo* info;
JNIEnv* env;
info = (ContextInfo*) JS_GetContextPrivate(cx);
ASSERT_RETURN_VOID(info);
env = info->env;
ASSERT_RETURN_VOID(env);
contextObject = info->contextObject;
ASSERT_RETURN_VOID(contextObject);
clazz_self = (*env)->GetObjectClass(env, contextObject);
ASSERT_RETURN_VOID(clazz_self);
fid = (*env)->GetFieldID(env, clazz_self, "_runtime",
"Lcom/netscape/nativejsengine/JSRuntime;");
ASSERT_RETURN_VOID(fid);
rtObject = (*env)->GetObjectField(env, contextObject, fid);
ASSERT_RETURN_VOID(rtObject);
clazz = (*env)->GetObjectClass(env, rtObject);
ASSERT_RETURN_VOID(clazz);
mid = (*env)->GetMethodID(env, clazz, "getNativeDebugSupport", "()J");
ASSERT_RETURN_VOID(mid);
jsdjc = (JSDJContext*) (*env)->CallObjectMethod(env, rtObject, mid);
if(jsdjc)
{
JSDContext* jsdc;
jsdc = JSDJ_GetJSDContext(jsdjc);
ASSERT_RETURN_VOID(jsdc);
JSD_AddFullSourceText(jsdc, src, len, filename);
}
}
#endif
static JSBool
_loadSingleFile(JSContext *cx, JSObject *obj, const char* filename)
{
char* buf;
FILE* file;
int file_len;
jsval result;
errno = 0;
file = fopen(filename, "rb");
if (!file) {
JS_ReportError(cx, "can't open %s: %s", filename, strerror(errno));
return JS_FALSE;
}
fseek(file, 0, SEEK_END);
file_len = ftell(file);
fseek(file, 0, SEEK_SET);
if(! file_len) {
fclose(file);
JS_ReportError(cx, "%s is empty", filename);
return JS_FALSE;
}
buf = (char*) malloc(file_len);
if(! buf) {
fclose(file);
JS_ReportError(cx, "memory alloc error while trying to read %s", filename);
return JS_FALSE;
}
fread(buf, 1, file_len, file);
fclose(file);
#ifdef JSDEBUGGER
_jamSourceIntoJSD(cx, buf, file_len, filename);
#endif
JS_EvaluateScript(cx, obj, buf, file_len, filename, 1, &result);
free(buf);
return JS_TRUE;
}
static void _sendPrintStringToJava(JNIEnv* env, jobject contextObject,
jmethodID mid, const char* str)
{
if(! str)
return;
(*env)->CallObjectMethod(env, contextObject, mid,
(*env)->NewStringUTF(env, str));
}
static JSBool
Print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
uintN i, n;
JSString *str;
ContextInfo* info;
jmethodID mid;
jclass clazz;
JNIEnv* env;
info = (ContextInfo*) JS_GetContextPrivate(cx);
ASSERT_RETURN_VALUE(info, JS_FALSE);
env = info->env;
ASSERT_RETURN_VALUE(env, JS_FALSE);
clazz = (*env)->GetObjectClass(env, info->contextObject);
ASSERT_RETURN_VALUE(clazz, JS_FALSE);
mid = (*env)->GetMethodID(env, clazz, "_print", "(Ljava/lang/String;)V");
ASSERT_RETURN_VALUE(mid, JS_FALSE);
for (i = n = 0; i < argc; i++) {
str = JS_ValueToString(cx, argv[i]);
if (!str)
return JS_FALSE;
if(i)
_sendPrintStringToJava(env, info->contextObject, mid, "");
_sendPrintStringToJava(env, info->contextObject, mid, JS_GetStringBytes(str));
n++;
}
if (n)
_sendPrintStringToJava(env, info->contextObject, mid, "\n");
return JS_TRUE;
}
static JSBool
Version(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
if (argc > 0 && JSVAL_IS_INT(argv[0]))
*rval = INT_TO_JSVAL(JS_SetVersion(cx, JSVAL_TO_INT(argv[0])));
else
*rval = INT_TO_JSVAL(JS_GetVersion(cx));
return JS_TRUE;
}
static JSBool
Load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
uintN i;
JSString *str;
const char *filename;
for (i = 0; i < argc; i++) {
str = JS_ValueToString(cx, argv[i]);
if (!str)
return JS_FALSE;
argv[i] = STRING_TO_JSVAL(str);
filename = JS_GetStringBytes(str);
if(! _loadSingleFile(cx, obj, filename))
return JS_FALSE;
}
return JS_TRUE;
}
static JSFunctionSpec shell_functions[] = {
{"version", Version, 0},
{"load", Load, 1},
{"print", Print, 0},
{0}
};
static void
my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
{
ContextInfo* info;
jmethodID mid;
jclass clazz;
JNIEnv* env;
jobject msg = NULL;
jobject filename = NULL;
jobject lineBuf = NULL;
int lineno = 0;
int offset = 0;
info = (ContextInfo*) JS_GetContextPrivate(cx);
ASSERT_RETURN_VOID(info);
env = info->env;
ASSERT_RETURN_VOID(env);
clazz = (*env)->GetObjectClass(env, info->contextObject);
ASSERT_RETURN_VOID(clazz);
mid = (*env)->GetMethodID(env, clazz, "_reportError",
"(Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;I)V");
ASSERT_RETURN_VOID(mid);
if(message)
msg = (*env)->NewStringUTF(env, message);
if(report)
{
lineno = report->lineno;
if(report->filename)
filename = (*env)->NewStringUTF(env, report->filename);
if(report->linebuf)
{
lineBuf = (*env)->NewStringUTF(env, report->linebuf);
if(report->tokenptr)
offset = report->tokenptr - report->linebuf;
}
}
(*env)->CallObjectMethod(env, info->contextObject, mid,
msg, filename, lineno, lineBuf, offset);
}
static JSClass global_class = {
"global", 0,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
};
/*
* Class: com_netscape_nativejsengine_JSRuntime
* Method: _init
* Signature: (Z)Z
*/
JNIEXPORT jboolean JNICALL Java_com_netscape_nativejsengine_JSRuntime__1init
(JNIEnv * env, jobject self, jboolean enableDebugging)
{
JSRuntime *rt;
jclass clazz;
jfieldID fid;
rt = JS_NewRuntime(8L * 1024L * 1024L);
ASSERT_RETURN_VALUE(rt, JNI_FALSE);
clazz = (*env)->GetObjectClass(env, self);
ASSERT_RETURN_VALUE(clazz, JNI_FALSE);
fid = (*env)->GetFieldID(env, clazz, "_nativeRuntime", "J");
ASSERT_RETURN_VALUE(fid, JNI_FALSE);
(*env)->SetLongField(env, self, fid, (long) rt);
#ifdef JSDEBUGGER
if(enableDebugging)
{
JSDJContext* jsdjc;
JSDContext* jsdc;
jsdc = JSD_DebuggerOnForUser(rt, NULL, NULL);
ASSERT_RETURN_VALUE(jsdc, JNI_FALSE);
jsdjc = JSDJ_CreateContext();
ASSERT_RETURN_VALUE(jsdjc, JNI_FALSE);
JSDJ_SetJSDContext(jsdjc, jsdc);
JSDJ_SetJNIEnvForCurrentThread(jsdjc, env);
fid = (*env)->GetFieldID(env, clazz, "_nativeDebugSupport", "J");
ASSERT_RETURN_VALUE(fid, JNI_FALSE);
(*env)->SetLongField(env, self, fid, (long) jsdjc);
}
#else
if(enableDebugging)
printf("ERROR - Context created with enableDebugging flag, but no debugging support compiled in!");
#endif
return JNI_TRUE;
}
/*
* Class: com_netscape_nativejsengine_JSRuntime
* Method: _exit
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_netscape_nativejsengine_JSRuntime__1exit
(JNIEnv * env, jobject self)
{
jfieldID fid;
jclass clazz;
JSRuntime *rt;
JSContext *iterp = NULL;
clazz = (*env)->GetObjectClass(env, self);
ASSERT_RETURN_VOID(clazz);
fid = (*env)->GetFieldID(env, clazz, "_nativeRuntime", "J");
ASSERT_RETURN_VOID(fid);
rt = (JSRuntime *) (*env)->GetLongField(env, self, fid);
ASSERT_RETURN_VOID(rt);
/*
* Can't kill runtime if it holds any contexts
*
* However, JSD may make it's own context(s), so don't ASSERT
*/
CHECK_RETURN_VOID(!JS_ContextIterator(rt, &iterp));
printf("runtime = %d\n", (int)rt);
JS_DestroyRuntime(rt);
}
/***************************************************************************/
/*
* Class: com_netscape_nativejsengine_JSContext
* Method: _init
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_com_netscape_nativejsengine_JSContext__1init
(JNIEnv *env, jobject self)
{
JSContext *cx;
JSObject *glob;
jfieldID fid;
jmethodID mid;
JSRuntime *rt;
jobject rtObject;
jclass clazz;
jclass clazz_self;
JSBool ok;
ContextInfo* info;
#ifdef JSDEBUGGER
JSDJContext* jsdjc;
#endif
clazz_self = (*env)->GetObjectClass(env, self);
ASSERT_RETURN_VALUE(clazz_self, JNI_FALSE);
fid = (*env)->GetFieldID(env, clazz_self, "_runtime",
"Lcom/netscape/nativejsengine/JSRuntime;");
ASSERT_RETURN_VALUE(fid, JNI_FALSE);
rtObject = (*env)->GetObjectField(env, self, fid);
ASSERT_RETURN_VALUE(rtObject, JNI_FALSE);
clazz = (*env)->GetObjectClass(env, rtObject);
ASSERT_RETURN_VALUE(clazz, JNI_FALSE);
mid = (*env)->GetMethodID(env, clazz, "getNativeRuntime", "()J");
ASSERT_RETURN_VALUE(mid, JNI_FALSE);
rt = (JSRuntime *) (*env)->CallObjectMethod(env, rtObject, mid);
ASSERT_RETURN_VALUE(rt, JNI_FALSE);
cx = JS_NewContext(rt, 8192);
ASSERT_RETURN_VALUE(cx, JNI_FALSE);
JS_SetErrorReporter(cx, my_ErrorReporter);
glob = JS_NewObject(cx, &global_class, NULL, NULL);
ASSERT_RETURN_VALUE(glob, JNI_FALSE);
ok = JS_InitStandardClasses(cx, glob);
ASSERT_RETURN_VALUE(ok, JNI_FALSE);
ok = JS_DefineFunctions(cx, glob, shell_functions);
ASSERT_RETURN_VALUE(ok, JNI_FALSE);
fid = (*env)->GetFieldID(env, clazz_self, "_nativeContext", "J");
ASSERT_RETURN_VALUE(fid, JNI_FALSE);
(*env)->SetLongField(env, self, fid, (long) cx);
info = (ContextInfo*) malloc(sizeof(ContextInfo));
ASSERT_RETURN_VALUE(info, JNI_FALSE);
info->env = env;
info->contextObject = self;
JS_SetContextPrivate(cx, info);
#ifdef JSDEBUGGER
mid = (*env)->GetMethodID(env, clazz, "getNativeDebugSupport", "()J");
ASSERT_RETURN_VALUE(mid, JNI_FALSE);
jsdjc = (JSDJContext*) (*env)->CallObjectMethod(env, rtObject, mid);
if(jsdjc)
{
JSDContext* jsdc = JSDJ_GetJSDContext(jsdjc);
ASSERT_RETURN_VALUE(jsdc, JNI_FALSE);
JSDJ_SetJNIEnvForCurrentThread(jsdjc, env);
JSD_JSContextInUse(jsdc, cx);
}
#endif
return JNI_TRUE;
}
/*
* Class: com_netscape_nativejsengine_JSContext
* Method: _exit
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_netscape_nativejsengine_JSContext__1exit
(JNIEnv *env, jobject self)
{
jfieldID fid;
jclass clazz;
JSContext *cx;
ContextInfo* info;
clazz = (*env)->GetObjectClass(env, self);
ASSERT_RETURN_VOID(clazz);
fid = (*env)->GetFieldID(env, clazz, "_nativeContext", "J");
ASSERT_RETURN_VOID(fid);
cx = (JSContext *) (*env)->GetLongField(env, self, fid);
ASSERT_RETURN_VOID(cx);
info = (ContextInfo*) JS_GetContextPrivate(cx);
ASSERT_RETURN_VOID(info);
free(info);
printf("context = %d\n", (int)cx);
JS_DestroyContext(cx);
}
/*
* Class: com_netscape_nativejsengine_JSContext
* Method: _eval
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_com_netscape_nativejsengine_JSContext__1eval
(JNIEnv * env, jobject self, jstring str, jstring filename, jint lineno)
{
jfieldID fid;
jclass clazz_self;
JSContext *cx;
JSObject *glob;
jsval rval;
int len;
const char* Cstr;
const char* Cfilename;
jboolean isCopy;
clazz_self = (*env)->GetObjectClass(env, self);
ASSERT_RETURN_VOID(clazz_self);
fid = (*env)->GetFieldID(env, clazz_self, "_nativeContext", "J");
ASSERT_RETURN_VOID(fid);
cx = (JSContext *) (*env)->GetLongField(env, self, fid);
ASSERT_RETURN_VOID(cx);
glob = JS_GetGlobalObject(cx);
ASSERT_RETURN_VOID(glob);
len = (*env)->GetStringUTFLength(env, str);
Cstr = (*env)->GetStringUTFChars(env, str, &isCopy);
Cfilename = (*env)->GetStringUTFChars(env, filename, &isCopy);
#ifdef JSDEBUGGER
/*
* XXX this just overwrites any previous source for this url!
*/
_jamSourceIntoJSD(cx, Cstr, len, Cfilename);
#endif
JS_EvaluateScript(cx, glob, Cstr, len, Cfilename, lineno, &rval);
(*env)->ReleaseStringUTFChars(env, str, Cstr);
(*env)->ReleaseStringUTFChars(env, filename, Cfilename);
}
/*
* Class: com_netscape_nativejsengine_JSContext
* Method: _load
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_com_netscape_nativejsengine_JSContext__1load
(JNIEnv *env, jobject self, jstring filename)
{
jfieldID fid;
jclass clazz;
JSContext *cx;
const char* Cfilename;
jboolean isCopy;
JSObject *glob;
clazz = (*env)->GetObjectClass(env, self);
ASSERT_RETURN_VOID(clazz);
fid = (*env)->GetFieldID(env, clazz, "_nativeContext", "J");
ASSERT_RETURN_VOID(fid);
cx = (JSContext *) (*env)->GetLongField(env, self, fid);
ASSERT_RETURN_VOID(cx);
glob = JS_GetGlobalObject(cx);
ASSERT_RETURN_VOID(glob);
Cfilename = (*env)->GetStringUTFChars(env, filename, &isCopy);
_loadSingleFile(cx, glob, Cfilename);
(*env)->ReleaseStringUTFChars(env, filename, Cfilename);
}

954
mozilla/js/jsd/jsd.h Normal file
View File

@@ -0,0 +1,954 @@
/* -*- 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.
*/
/*
* Header for JavaScript Debugging support - Internal ONLY declarations
*/
#ifndef jsd_h___
#define jsd_h___
/*
* NOTE: This is a *private* header file and should only be included by
* the sources in js/jsd. Defining EXPORT_JSD_API in an outside module
* using jsd would be bad.
*/
#define EXPORT_JSD_API 1 /* if used, must be set before include of jsdebug.h */
/*
* These can be controled by the makefile, but this allows a place to set
* the values always used in the mozilla client, but perhaps done differnetly
* in other embeddings.
*/
#ifdef MOZILLA_CLIENT
#define JSD_THREADSAFE 1
#define JSD_HAS_DANGEROUS_THREAD 1
#define JSD_USE_NSPR_LOCKS 1
#endif /* MOZILLA_CLIENT */
/* Get jstypes.h included first. After that we can use PR macros for doing
* this extern "C" stuff!
*/
#ifdef __cplusplus
extern "C"
{
#endif
#include "jstypes.h"
#ifdef __cplusplus
}
#endif
JS_BEGIN_EXTERN_C
#include "jsprf.h"
#include "jsutil.h" /* Added by JSIFY */
#include "jshash.h" /* Added by JSIFY */
#include "jsclist.h"
#include "jsdebug.h"
#include "jsapi.h"
#include "jsobj.h"
#include "jsfun.h"
#include "jsdbgapi.h"
#include "jsd_lock.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef LIVEWIRE
#include <base/pblock.h>
#include <base/session.h>
#include <frame/log.h>
#include <frame/req.h>
#endif /* LIVEWIRE */
JS_END_EXTERN_C
JS_BEGIN_EXTERN_C
#define JSD_MAJOR_VERSION 1
#define JSD_MINOR_VERSION 1
/***************************************************************************/
/* handy macros */
#undef CHECK_BIT_FLAG
#define CHECK_BIT_FLAG(f,b) ((f)&(b))
#undef SET_BIT_FLAG
#define SET_BIT_FLAG(f,b) ((f)|=(b))
#undef CLEAR_BIT_FLAG
#define CLEAR_BIT_FLAG(f,b) ((f)&=(~(b)))
/***************************************************************************/
/* These are not exposed in jsdebug.h - typedef here for consistency */
typedef struct JSDExecHook JSDExecHook;
typedef struct JSDAtom JSDAtom;
/***************************************************************************/
/* Our structures */
/*
* XXX What I'm calling a JSDContext is really more of a JSDTaskState.
*/
struct JSDContext
{
JSCList links; /* we are part of a JSCList */
JSBool inited;
JSD_ScriptHookProc scriptHook;
void* scriptHookData;
JSD_ExecutionHookProc interruptHook;
void* interruptHookData;
JSRuntime* jsrt;
JSD_ErrorReporter errorReporter;
void* errorReporterData;
JSCList threadsStates;
JSD_ExecutionHookProc debugBreakHook;
void* debugBreakHookData;
JSD_ExecutionHookProc debuggerHook;
void* debuggerHookData;
JSD_ExecutionHookProc throwHook;
void* throwHookData;
JSContext* dumbContext;
JSObject* glob;
JSD_UserCallbacks userCallbacks;
void* user;
JSCList scripts;
JSCList sources;
JSCList removedSources;
uintN sourceAlterCount;
JSHashTable* atoms;
JSCList objectsList;
JSHashTable* objectsTable;
#ifdef JSD_THREADSAFE
void* scriptsLock;
void* sourceTextLock;
void* objectsLock;
void* atomsLock;
void* threadStatesLock;
#endif /* JSD_THREADSAFE */
#ifdef JSD_HAS_DANGEROUS_THREAD
void* dangerousThread;
#endif /* JSD_HAS_DANGEROUS_THREAD */
};
struct JSDScript
{
JSCList links; /* we are part of a JSCList */
JSDContext* jsdc; /* JSDContext for this jsdscript */
JSScript* script; /* script we are wrapping */
JSFunction* function; /* back pointer to owning function (can be NULL) */
uintN lineBase; /* we cache this */
uintN lineExtent; /* we cache this */
JSCList hooks; /* JSCList of JSDExecHooks for this script */
char* url;
#ifdef LIVEWIRE
LWDBGApp* app;
LWDBGScript* lwscript;
#endif
};
struct JSDSourceText
{
JSCList links; /* we are part of a JSCList */
char* url;
char* text;
uintN textLength;
uintN textSpace;
JSBool dirty;
JSDSourceStatus status;
uintN alterCount;
JSBool doingEval;
};
struct JSDExecHook
{
JSCList links; /* we are part of a JSCList */
JSDScript* jsdscript;
jsuword pc;
JSD_ExecutionHookProc hook;
void* callerdata;
};
struct JSDThreadState
{
JSCList links; /* we are part of a JSCList */
JSContext* context;
void* thread;
JSCList stack;
uintN stackDepth;
};
struct JSDStackFrameInfo
{
JSCList links; /* we are part of a JSCList */
JSDThreadState* jsdthreadstate;
JSDScript* jsdscript;
jsuword pc;
JSStackFrame* fp;
};
#define GOT_PROTO ((short) (1 << 0))
#define GOT_PROPS ((short) (1 << 1))
#define GOT_PARENT ((short) (1 << 2))
#define GOT_CTOR ((short) (1 << 3))
struct JSDValue
{
jsval val;
intN nref;
JSCList props;
JSString* string;
const char* funName;
const char* className;
JSDValue* proto;
JSDValue* parent;
JSDValue* ctor;
uintN flags;
};
struct JSDProperty
{
JSCList links; /* we are part of a JSCList */
intN nref;
JSDValue* val;
JSDValue* name;
JSDValue* alias;
uintN slot;
uintN flags;
};
struct JSDAtom
{
char* str; /* must be first element in stuct for compare */
intN refcount;
};
struct JSDObject
{
JSCList links; /* we are part of a JSCList */
JSObject* obj;
JSDAtom* newURL;
uintN newLineno;
JSDAtom* ctorURL;
uintN ctorLineno;
JSDAtom* ctorName;
};
/***************************************************************************/
/* Code validation support */
#ifdef DEBUG
extern void JSD_ASSERT_VALID_CONTEXT(JSDContext* jsdc);
extern void JSD_ASSERT_VALID_SCRIPT(JSDScript* jsdscript);
extern void JSD_ASSERT_VALID_SOURCE_TEXT(JSDSourceText* jsdsrc);
extern void JSD_ASSERT_VALID_THREAD_STATE(JSDThreadState* jsdthreadstate);
extern void JSD_ASSERT_VALID_STACK_FRAME(JSDStackFrameInfo* jsdframe);
extern void JSD_ASSERT_VALID_EXEC_HOOK(JSDExecHook* jsdhook);
extern void JSD_ASSERT_VALID_VALUE(JSDValue* jsdval);
extern void JSD_ASSERT_VALID_PROPERTY(JSDProperty* jsdprop);
extern void JSD_ASSERT_VALID_OBJECT(JSDObject* jsdobj);
#else
#define JSD_ASSERT_VALID_CONTEXT(x) ((void)0)
#define JSD_ASSERT_VALID_SCRIPT(x) ((void)0)
#define JSD_ASSERT_VALID_SOURCE_TEXT(x) ((void)0)
#define JSD_ASSERT_VALID_THREAD_STATE(x)((void)0)
#define JSD_ASSERT_VALID_STACK_FRAME(x) ((void)0)
#define JSD_ASSERT_VALID_EXEC_HOOK(x) ((void)0)
#define JSD_ASSERT_VALID_VALUE(x) ((void)0)
#define JSD_ASSERT_VALID_PROPERTY(x) ((void)0)
#define JSD_ASSERT_VALID_OBJECT(x) ((void)0)
#endif
/***************************************************************************/
/* higher level functions */
extern JSDContext*
jsd_DebuggerOnForUser(JSRuntime* jsrt,
JSD_UserCallbacks* callbacks,
void* user);
extern JSDContext*
jsd_DebuggerOn(void);
extern void
jsd_DebuggerOff(JSDContext* jsdc);
extern void
jsd_SetUserCallbacks(JSRuntime* jsrt, JSD_UserCallbacks* callbacks, void* user);
extern JSDContext*
jsd_JSDContextForJSContext(JSContext* context);
extern JSBool
jsd_SetErrorReporter(JSDContext* jsdc,
JSD_ErrorReporter reporter,
void* callerdata);
extern JSBool
jsd_GetErrorReporter(JSDContext* jsdc,
JSD_ErrorReporter* reporter,
void** callerdata);
JS_STATIC_DLL_CALLBACK(JSBool)
jsd_DebugErrorHook(JSContext *cx, const char *message,
JSErrorReport *report, void *closure);
/***************************************************************************/
/* Script functions */
extern void
jsd_DestroyAllJSDScripts(JSDContext* jsdc);
extern JSDScript*
jsd_FindJSDScript(JSDContext* jsdc,
JSScript *script);
extern JSDScript*
jsd_IterateScripts(JSDContext* jsdc, JSDScript **iterp);
extern JSBool
jsd_IsActiveScript(JSDContext* jsdc, JSDScript *jsdscript);
extern const char*
jsd_GetScriptFilename(JSDContext* jsdc, JSDScript *jsdscript);
extern const char*
jsd_GetScriptFunctionName(JSDContext* jsdc, JSDScript *jsdscript);
extern uintN
jsd_GetScriptBaseLineNumber(JSDContext* jsdc, JSDScript *jsdscript);
extern uintN
jsd_GetScriptLineExtent(JSDContext* jsdc, JSDScript *jsdscript);
extern JSBool
jsd_SetScriptHook(JSDContext* jsdc, JSD_ScriptHookProc hook, void* callerdata);
extern JSBool
jsd_GetScriptHook(JSDContext* jsdc, JSD_ScriptHookProc* hook, void** callerdata);
extern jsuword
jsd_GetClosestPC(JSDContext* jsdc, JSDScript* jsdscript, uintN line);
extern uintN
jsd_GetClosestLine(JSDContext* jsdc, JSDScript* jsdscript, jsuword pc);
extern void JS_DLL_CALLBACK
jsd_NewScriptHookProc(
JSContext *cx,
const char *filename, /* URL this script loads from */
uintN lineno, /* line where this script starts */
JSScript *script,
JSFunction *fun,
void* callerdata);
extern void JS_DLL_CALLBACK
jsd_DestroyScriptHookProc(
JSContext *cx,
JSScript *script,
void* callerdata);
/* Script execution hook functions */
extern JSBool
jsd_SetExecutionHook(JSDContext* jsdc,
JSDScript* jsdscript,
jsuword pc,
JSD_ExecutionHookProc hook,
void* callerdata);
extern JSBool
jsd_ClearExecutionHook(JSDContext* jsdc,
JSDScript* jsdscript,
jsuword pc);
extern JSBool
jsd_ClearAllExecutionHooksForScript(JSDContext* jsdc, JSDScript* jsdscript);
extern JSBool
jsd_ClearAllExecutionHooks(JSDContext* jsdc);
extern void
jsd_ScriptCreated(JSDContext* jsdc,
JSContext *cx,
const char *filename, /* URL this script loads from */
uintN lineno, /* line where this script starts */
JSScript *script,
JSFunction *fun);
extern void
jsd_ScriptDestroyed(JSDContext* jsdc,
JSContext *cx,
JSScript *script);
/***************************************************************************/
/* Source Text functions */
extern JSDSourceText*
jsd_IterateSources(JSDContext* jsdc, JSDSourceText **iterp);
extern JSDSourceText*
jsd_FindSourceForURL(JSDContext* jsdc, const char* url);
extern const char*
jsd_GetSourceURL(JSDContext* jsdc, JSDSourceText* jsdsrc);
extern JSBool
jsd_GetSourceText(JSDContext* jsdc, JSDSourceText* jsdsrc,
const char** ppBuf, intN* pLen);
extern void
jsd_ClearSourceText(JSDContext* jsdc, JSDSourceText* jsdsrc);
extern JSDSourceStatus
jsd_GetSourceStatus(JSDContext* jsdc, JSDSourceText* jsdsrc);
extern JSBool
jsd_IsSourceDirty(JSDContext* jsdc, JSDSourceText* jsdsrc);
extern void
jsd_SetSourceDirty(JSDContext* jsdc, JSDSourceText* jsdsrc, JSBool dirty);
extern uintN
jsd_GetSourceAlterCount(JSDContext* jsdc, JSDSourceText* jsdsrc);
extern uintN
jsd_IncrementSourceAlterCount(JSDContext* jsdc, JSDSourceText* jsdsrc);
extern JSDSourceText*
jsd_NewSourceText(JSDContext* jsdc, const char* url);
extern JSDSourceText*
jsd_AppendSourceText(JSDContext* jsdc,
JSDSourceText* jsdsrc,
const char* text, /* *not* zero terminated */
size_t length,
JSDSourceStatus status);
extern JSDSourceText*
jsd_AppendUCSourceText(JSDContext* jsdc,
JSDSourceText* jsdsrc,
const jschar* text, /* *not* zero terminated */
size_t length,
JSDSourceStatus status);
/* convienence function for adding complete source of url in one call */
extern JSBool
jsd_AddFullSourceText(JSDContext* jsdc,
const char* text, /* *not* zero terminated */
size_t length,
const char* url);
extern void
jsd_DestroyAllSources(JSDContext* jsdc);
extern const char*
jsd_BuildNormalizedURL(const char* url_string);
extern void
jsd_StartingEvalUsingFilename(JSDContext* jsdc, const char* url);
extern void
jsd_FinishedEvalUsingFilename(JSDContext* jsdc, const char* url);
/***************************************************************************/
/* Interrupt Hook functions */
extern JSBool
jsd_SetInterruptHook(JSDContext* jsdc,
JSD_ExecutionHookProc hook,
void* callerdata);
extern JSBool
jsd_ClearInterruptHook(JSDContext* jsdc);
extern JSBool
jsd_SetDebugBreakHook(JSDContext* jsdc,
JSD_ExecutionHookProc hook,
void* callerdata);
extern JSBool
jsd_ClearDebugBreakHook(JSDContext* jsdc);
extern JSBool
jsd_SetDebuggerHook(JSDContext* jsdc,
JSD_ExecutionHookProc hook,
void* callerdata);
extern JSBool
jsd_ClearDebuggerHook(JSDContext* jsdc);
extern JSTrapStatus
jsd_CallExecutionHook(JSDContext* jsdc,
JSContext *cx,
JSDHookType type,
JSD_ExecutionHookProc hook,
void* hookData,
jsval* rval);
extern JSBool
jsd_SetThrowHook(JSDContext* jsdc,
JSD_ExecutionHookProc hook,
void* callerdata);
extern JSBool
jsd_ClearThrowHook(JSDContext* jsdc);
extern JSTrapStatus JS_DLL_CALLBACK
jsd_DebuggerHandler(JSContext *cx, JSScript *script, jsbytecode *pc,
jsval *rval, void *closure);
extern JSTrapStatus JS_DLL_CALLBACK
jsd_ThrowHandler(JSContext *cx, JSScript *script, jsbytecode *pc,
jsval *rval, void *closure);
/***************************************************************************/
/* Stack Frame functions */
extern uintN
jsd_GetCountOfStackFrames(JSDContext* jsdc, JSDThreadState* jsdthreadstate);
extern JSDStackFrameInfo*
jsd_GetStackFrame(JSDContext* jsdc, JSDThreadState* jsdthreadstate);
extern JSDStackFrameInfo*
jsd_GetCallingStackFrame(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe);
extern JSDScript*
jsd_GetScriptForStackFrame(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe);
extern jsuword
jsd_GetPCForStackFrame(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe);
extern JSDValue*
jsd_GetCallObjectForStackFrame(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe);
extern JSDValue*
jsd_GetScopeChainForStackFrame(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe);
extern JSDValue*
jsd_GetThisForStackFrame(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe);
extern JSDThreadState*
jsd_NewThreadState(JSDContext* jsdc, JSContext *cx);
extern void
jsd_DestroyThreadState(JSDContext* jsdc, JSDThreadState* jsdthreadstate);
extern JSBool
jsd_EvaluateScriptInStackFrame(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe,
const char *bytes, uintN length,
const char *filename, uintN lineno, jsval *rval);
extern JSString*
jsd_ValToStringInStackFrame(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe,
jsval val);
extern JSBool
jsd_IsValidThreadState(JSDContext* jsdc,
JSDThreadState* jsdthreadstate);
extern JSBool
jsd_IsValidFrameInThreadState(JSDContext* jsdc,
JSDThreadState* jsdthreadstate,
JSDStackFrameInfo* jsdframe);
extern JSDValue*
jsd_GetException(JSDContext* jsdc, JSDThreadState* jsdthreadstate);
extern JSBool
jsd_SetException(JSDContext* jsdc, JSDThreadState* jsdthreadstate,
JSDValue* jsdval);
/***************************************************************************/
/* Locking support */
/* protos are in js_lock.h for:
* jsd_CreateLock
* jsd_Lock
* jsd_Unlock
* jsd_IsLocked
* jsd_CurrentThread
*/
#ifdef JSD_THREADSAFE
/* the system-wide lock */
extern void* _jsd_global_lock;
#define JSD_LOCK() \
JS_BEGIN_MACRO \
if(!_jsd_global_lock) \
_jsd_global_lock = jsd_CreateLock(); \
JS_ASSERT(_jsd_global_lock); \
jsd_Lock(_jsd_global_lock); \
JS_END_MACRO
#define JSD_UNLOCK() \
JS_BEGIN_MACRO \
JS_ASSERT(_jsd_global_lock); \
jsd_Unlock(_jsd_global_lock); \
JS_END_MACRO
/* locks for the subsystems of a given context */
#define JSD_INIT_LOCKS(jsdc) \
( (NULL != (jsdc->scriptsLock = jsd_CreateLock())) && \
(NULL != (jsdc->sourceTextLock = jsd_CreateLock())) && \
(NULL != (jsdc->atomsLock = jsd_CreateLock())) && \
(NULL != (jsdc->objectsLock = jsd_CreateLock())) && \
(NULL != (jsdc->threadStatesLock = jsd_CreateLock())) )
#define JSD_LOCK_SCRIPTS(jsdc) jsd_Lock(jsdc->scriptsLock)
#define JSD_UNLOCK_SCRIPTS(jsdc) jsd_Unlock(jsdc->scriptsLock)
#define JSD_LOCK_SOURCE_TEXT(jsdc) jsd_Lock(jsdc->sourceTextLock)
#define JSD_UNLOCK_SOURCE_TEXT(jsdc) jsd_Unlock(jsdc->sourceTextLock)
#define JSD_LOCK_ATOMS(jsdc) jsd_Lock(jsdc->atomsLock)
#define JSD_UNLOCK_ATOMS(jsdc) jsd_Unlock(jsdc->atomsLock)
#define JSD_LOCK_OBJECTS(jsdc) jsd_Lock(jsdc->objectsLock)
#define JSD_UNLOCK_OBJECTS(jsdc) jsd_Unlock(jsdc->objectsLock)
#define JSD_LOCK_THREADSTATES(jsdc) jsd_Lock(jsdc->threadStatesLock)
#define JSD_UNLOCK_THREADSTATES(jsdc) jsd_Unlock(jsdc->threadStatesLock)
#else /* !JSD_THREADSAFE */
#define JSD_LOCK() ((void)0)
#define JSD_UNLOCK() ((void)0)
#define JSD_INIT_LOCKS(jsdc) 1
#define JSD_LOCK_SCRIPTS(jsdc) ((void)0)
#define JSD_UNLOCK_SCRIPTS(jsdc) ((void)0)
#define JSD_LOCK_SOURCE_TEXT(jsdc) ((void)0)
#define JSD_UNLOCK_SOURCE_TEXT(jsdc) ((void)0)
#define JSD_LOCK_ATOMS(jsdc) ((void)0)
#define JSD_UNLOCK_ATOMS(jsdc) ((void)0)
#define JSD_LOCK_OBJECTS(jsdc) ((void)0)
#define JSD_UNLOCK_OBJECTS(jsdc) ((void)0)
#define JSD_LOCK_THREADSTATES(jsdc) ((void)0)
#define JSD_UNLOCK_THREADSTATES(jsdc) ((void)0)
#endif /* JSD_THREADSAFE */
/* NOTE: These are intended for ASSERTs. Thus we supply checks for both
* LOCKED and UNLOCKED (rather that just LOCKED and !LOCKED) so that in
* the DEBUG non-Threadsafe case we can have an ASSERT that always succeeds
* without having to special case things in the code.
*/
#if defined(JSD_THREADSAFE) && defined(DEBUG)
#define JSD_SCRIPTS_LOCKED(jsdc) (jsd_IsLocked(jsdc->scriptsLock))
#define JSD_SOURCE_TEXT_LOCKED(jsdc) (jsd_IsLocked(jsdc->sourceTextLock))
#define JSD_ATOMS_LOCKED(jsdc) (jsd_IsLocked(jsdc->atomsLock))
#define JSD_OBJECTS_LOCKED(jsdc) (jsd_IsLocked(jsdc->objectsLock))
#define JSD_THREADSTATES_LOCKED(jsdc) (jsd_IsLocked(jsdc->threadStatesLock))
#define JSD_SCRIPTS_UNLOCKED(jsdc) (!jsd_IsLocked(jsdc->scriptsLock))
#define JSD_SOURCE_TEXT_UNLOCKED(jsdc) (!jsd_IsLocked(jsdc->sourceTextLock))
#define JSD_ATOMS_UNLOCKED(jsdc) (!jsd_IsLocked(jsdc->atomsLock))
#define JSD_OBJECTS_UNLOCKED(jsdc) (!jsd_IsLocked(jsdc->objectsLock))
#define JSD_THREADSTATES_UNLOCKED(jsdc) (!jsd_IsLocked(jsdc->threadStatesLock))
#else
#define JSD_SCRIPTS_LOCKED(jsdc) 1
#define JSD_SOURCE_TEXT_LOCKED(jsdc) 1
#define JSD_ATOMS_LOCKED(jsdc) 1
#define JSD_OBJECTS_LOCKED(jsdc) 1
#define JSD_THREADSTATES_LOCKED(jsdc) 1
#define JSD_SCRIPTS_UNLOCKED(jsdc) 1
#define JSD_SOURCE_TEXT_UNLOCKED(jsdc) 1
#define JSD_ATOMS_UNLOCKED(jsdc) 1
#define JSD_OBJECTS_UNLOCKED(jsdc) 1
#define JSD_THREADSTATES_UNLOCKED(jsdc) 1
#endif /* defined(JSD_THREADSAFE) && defined(DEBUG) */
/***************************************************************************/
/* Threading support */
#ifdef JSD_THREADSAFE
#define JSD_CURRENT_THREAD() jsd_CurrentThread()
#else /* !JSD_THREADSAFE */
#define JSD_CURRENT_THREAD() ((void*)0)
#endif /* JSD_THREADSAFE */
/***************************************************************************/
/* Dangerous thread support */
#ifdef JSD_HAS_DANGEROUS_THREAD
#define JSD_IS_DANGEROUS_THREAD(jsdc) \
(JSD_CURRENT_THREAD() == jsdc->dangerousThread)
#else /* !JSD_HAS_DANGEROUS_THREAD */
#define JSD_IS_DANGEROUS_THREAD(jsdc) 0
#endif /* JSD_HAS_DANGEROUS_THREAD */
/***************************************************************************/
/* Value and Property Functions */
extern JSDValue*
jsd_NewValue(JSDContext* jsdc, jsval val);
extern void
jsd_DropValue(JSDContext* jsdc, JSDValue* jsdval);
extern jsval
jsd_GetValueWrappedJSVal(JSDContext* jsdc, JSDValue* jsdval);
extern void
jsd_RefreshValue(JSDContext* jsdc, JSDValue* jsdval);
/**************************************************/
extern JSBool
jsd_IsValueObject(JSDContext* jsdc, JSDValue* jsdval);
extern JSBool
jsd_IsValueNumber(JSDContext* jsdc, JSDValue* jsdval);
extern JSBool
jsd_IsValueInt(JSDContext* jsdc, JSDValue* jsdval);
extern JSBool
jsd_IsValueDouble(JSDContext* jsdc, JSDValue* jsdval);
extern JSBool
jsd_IsValueString(JSDContext* jsdc, JSDValue* jsdval);
extern JSBool
jsd_IsValueBoolean(JSDContext* jsdc, JSDValue* jsdval);
extern JSBool
jsd_IsValueNull(JSDContext* jsdc, JSDValue* jsdval);
extern JSBool
jsd_IsValueVoid(JSDContext* jsdc, JSDValue* jsdval);
extern JSBool
jsd_IsValuePrimitive(JSDContext* jsdc, JSDValue* jsdval);
extern JSBool
jsd_IsValueFunction(JSDContext* jsdc, JSDValue* jsdval);
extern JSBool
jsd_IsValueNative(JSDContext* jsdc, JSDValue* jsdval);
/**************************************************/
extern JSBool
jsd_GetValueBoolean(JSDContext* jsdc, JSDValue* jsdval);
extern int32
jsd_GetValueInt(JSDContext* jsdc, JSDValue* jsdval);
extern jsdouble*
jsd_GetValueDouble(JSDContext* jsdc, JSDValue* jsdval);
extern JSString*
jsd_GetValueString(JSDContext* jsdc, JSDValue* jsdval);
extern const char*
jsd_GetValueFunctionName(JSDContext* jsdc, JSDValue* jsdval);
/**************************************************/
extern uintN
jsd_GetCountOfProperties(JSDContext* jsdc, JSDValue* jsdval);
extern JSDProperty*
jsd_IterateProperties(JSDContext* jsdc, JSDValue* jsdval, JSDProperty **iterp);
extern JSDProperty*
jsd_GetValueProperty(JSDContext* jsdc, JSDValue* jsdval, JSString* name);
extern JSDValue*
jsd_GetValuePrototype(JSDContext* jsdc, JSDValue* jsdval);
extern JSDValue*
jsd_GetValueParent(JSDContext* jsdc, JSDValue* jsdval);
extern JSDValue*
jsd_GetValueConstructor(JSDContext* jsdc, JSDValue* jsdval);
extern const char*
jsd_GetValueClassName(JSDContext* jsdc, JSDValue* jsdval);
/**************************************************/
extern void
jsd_DropProperty(JSDContext* jsdc, JSDProperty* jsdprop);
extern JSDValue*
jsd_GetPropertyName(JSDContext* jsdc, JSDProperty* jsdprop);
extern JSDValue*
jsd_GetPropertyValue(JSDContext* jsdc, JSDProperty* jsdprop);
extern JSDValue*
jsd_GetPropertyAlias(JSDContext* jsdc, JSDProperty* jsdprop);
extern JSDPropertyFlags
jsd_GetPropertyFlags(JSDContext* jsdc, JSDProperty* jsdprop);
extern uintN
jsd_GetPropertyVarArgSlot(JSDContext* jsdc, JSDProperty* jsdprop);
/**************************************************/
/* Stepping Functions */
extern void * JS_DLL_CALLBACK
jsd_InterpreterHook(JSContext *cx, JSStackFrame *fp, JSBool before,
JSBool *ok, void *closure);
/**************************************************/
/* Object Functions */
extern JSBool
jsd_InitObjectManager(JSDContext* jsdc);
extern void
jsd_DestroyObjectManager(JSDContext* jsdc);
extern void JS_DLL_CALLBACK
jsd_ObjectHook(JSContext *cx, JSObject *obj, JSBool isNew, void *closure);
extern void
jsd_Constructing(JSDContext* jsdc, JSContext *cx, JSObject *obj,
JSStackFrame *fp);
extern JSDObject*
jsd_IterateObjects(JSDContext* jsdc, JSDObject** iterp);
extern JSObject*
jsd_GetWrappedObject(JSDContext* jsdc, JSDObject* jsdobj);
extern const char*
jsd_GetObjectNewURL(JSDContext* jsdc, JSDObject* jsdobj);
extern uintN
jsd_GetObjectNewLineNumber(JSDContext* jsdc, JSDObject* jsdobj);
extern const char*
jsd_GetObjectConstructorURL(JSDContext* jsdc, JSDObject* jsdobj);
extern uintN
jsd_GetObjectConstructorLineNumber(JSDContext* jsdc, JSDObject* jsdobj);
extern const char*
jsd_GetObjectConstructorName(JSDContext* jsdc, JSDObject* jsdobj);
extern JSDObject*
jsd_GetJSDObjectForJSObject(JSDContext* jsdc, JSObject* jsobj);
extern JSDObject*
jsd_GetObjectForValue(JSDContext* jsdc, JSDValue* jsdval);
/*
* returns new refcounted JSDValue
*/
extern JSDValue*
jsd_GetValueForObject(JSDContext* jsdc, JSDObject* jsdobj);
/**************************************************/
/* Atom Functions */
extern JSBool
jsd_CreateAtomTable(JSDContext* jsdc);
extern void
jsd_DestroyAtomTable(JSDContext* jsdc);
extern JSDAtom*
jsd_AddAtom(JSDContext* jsdc, const char* str);
extern JSDAtom*
jsd_CloneAtom(JSDContext* jsdc, JSDAtom* atom);
extern void
jsd_DropAtom(JSDContext* jsdc, JSDAtom* atom);
#define JSD_ATOM_TO_STRING(a) ((const char*)((a)->str))
/***************************************************************************/
/* Livewire specific API */
#ifdef LIVEWIRE
extern LWDBGScript*
jsdlw_GetLWScript(JSDContext* jsdc, JSDScript* jsdscript);
extern char*
jsdlw_BuildAppRelativeFilename(LWDBGApp* app, const char* filename);
extern JSDSourceText*
jsdlw_PreLoadSource(JSDContext* jsdc, LWDBGApp* app,
const char* filename, JSBool clear);
extern JSDSourceText*
jsdlw_ForceLoadSource(JSDContext* jsdc, JSDSourceText* jsdsrc);
extern JSBool
jsdlw_UserCodeAtPC(JSDContext* jsdc, JSDScript* jsdscript, jsuword pc);
extern JSBool
jsdlw_RawToProcessedLineNumber(JSDContext* jsdc, JSDScript* jsdscript,
uintN lineIn, uintN* lineOut);
extern JSBool
jsdlw_ProcessedToRawLineNumber(JSDContext* jsdc, JSDScript* jsdscript,
uintN lineIn, uintN* lineOut);
#if 0
/* our hook proc for LiveWire app start/stop */
extern void JS_DLL_CALLBACK
jsdlw_AppHookProc(LWDBGApp* app,
JSBool created,
void *callerdata);
#endif
#endif
/***************************************************************************/
JS_END_EXTERN_C
#endif /* jsd_h___ */

70
mozilla/js/jsd/jsd.mak Normal file
View File

@@ -0,0 +1,70 @@
PROJ = jsd
JSD = .
JS = $(JSD)\..\src
JSPROJ = js32
!IF "$(BUILD_OPT)" != ""
OBJ = Release
CC_FLAGS = /DNDEBUG
!ELSE
OBJ = Debug
CC_FLAGS = /DDEBUG
LINK_FLAGS = /DEBUG
!ENDIF
QUIET=@
CFLAGS = /nologo /MDd /W3 /Gm /GX /Zi /Od\
/I $(JS)\
/I $(JSD)\
/DDEBUG /DWIN32 /D_CONSOLE /DXP_PC /D_WINDOWS /D_WIN32\
/DJSDEBUGGER\
!IF "$(JSD_THREADSAFE)" != ""
/DJSD_THREADSAFE\
!ENDIF
/DEXPORT_JSD_API\
$(CC_FLAGS)\
/c /Fp$(OBJ)\$(PROJ).pch /Fd$(OBJ)\$(PROJ).pdb /YX -Fo$@ $<
LFLAGS = /nologo /subsystem:console /DLL /incremental:no /machine:I386 \
$(LINK_FLAGS) /pdb:$(OBJ)\$(PROJ).pdb -out:$(OBJ)\$(PROJ).dll
LLIBS = kernel32.lib advapi32.lib $(JS)\$(OBJ)\$(JSPROJ).lib
# unused... user32.lib gdi32.lib winspool.lib comdlg32.lib shell32.lib
CPP=cl.exe
LINK32=link.exe
all: $(OBJ) $(OBJ)\$(PROJ).dll
$(OBJ)\$(PROJ).dll: \
$(OBJ)\jsdebug.obj \
$(OBJ)\jsd_atom.obj \
$(OBJ)\jsd_high.obj \
$(OBJ)\jsd_hook.obj \
$(OBJ)\jsd_obj.obj \
$(OBJ)\jsd_scpt.obj \
$(OBJ)\jsd_stak.obj \
$(OBJ)\jsd_step.obj \
$(OBJ)\jsd_text.obj \
$(OBJ)\jsd_lock.obj \
$(OBJ)\jsd_val.obj
$(QUIET)$(LINK32) $(LFLAGS) $** $(LLIBS)
{$(JSD)}.c{$(OBJ)}.obj :
$(QUIET)$(CPP) $(CFLAGS)
$(OBJ) :
$(QUIET)mkdir $(OBJ)
clean:
@echo deleting old output
$(QUIET)del $(OBJ)\*.pch >NUL
$(QUIET)del $(OBJ)\*.obj >NUL
$(QUIET)del $(OBJ)\*.exp >NUL
$(QUIET)del $(OBJ)\*.lib >NUL
$(QUIET)del $(OBJ)\*.idb >NUL
$(QUIET)del $(OBJ)\*.pdb >NUL
$(QUIET)del $(OBJ)\*.dll >NUL

View File

@@ -0,0 +1,89 @@
; -*- Mode: Fundamental; tab-width: 4; indent-tabs-mode: nil -*-
;
; 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 JSD1640.DLL
EXETYPE WINDOWS
PROTMODE
DESCRIPTION 'Netscape 16-bit JavaScript Debugger Library'
CODE LOADONCALL MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE SINGLE
HEAPSIZE 8192
EXPORTS
WEP @1 RESIDENTNAME NONAME
_JSD_AppendSourceText
_JSD_ClearAllExecutionHooks
_JSD_ClearAllExecutionHooksForScript
_JSD_ClearDebugBreakHook
_JSD_ClearExecutionHook
_JSD_ClearInterruptHook
_JSD_ClearSourceText
_JSD_DebuggerOff
_JSD_DebuggerOn
_JSD_EvaluateScriptInStackFrame
_JSD_FindSourceForURL
_JSD_GetCallingStackFrame
_JSD_GetClosestLine
_JSD_GetClosestPC
_JSD_GetCountOfStackFrames
_JSD_GetDefaultJSContext
_JSD_GetMajorVersion
_JSD_GetMinorVersion
_JSD_GetPCForStackFrame
_JSD_GetScriptBaseLineNumber
_JSD_GetScriptFilename
_JSD_GetScriptForStackFrame
_JSD_GetScriptFunctionName
_JSD_GetScriptHook
_JSD_GetScriptLineExtent
_JSD_GetSourceAlterCount
_JSD_GetSourceStatus
_JSD_GetSourceText
_JSD_GetSourceURL
_JSD_GetStackFrame
_JSD_IncrementSourceAlterCount
_JSD_IsSourceDirty
_JSD_IterateScripts
_JSD_IterateSources
_JSD_LockScriptSubsystem
_JSD_LockSourceTextSubsystem
_JSD_NewSourceText
_JSD_SetDebugBreakHook
_JSD_SetErrorReporter
_JSD_SetExecutionHook
_JSD_SetInterruptHook
_JSD_SetScriptHook
_JSD_SetSourceDirty
_JSD_SetUserCallbacks
_JSD_UnlockScriptSubsystem
_JSD_UnlockSourceTextSubsystem
_Java_netscape_jsdebug_DebugController__0005fsetController_stub
_Java_netscape_jsdebug_DebugController_executeScriptInStackFrame_stub
_Java_netscape_jsdebug_DebugController_sendInterrupt_stub
_Java_netscape_jsdebug_DebugController_setInstructionHook0_stub
_Java_netscape_jsdebug_JSPC_getSourceLocation_stub
_Java_netscape_jsdebug_JSSourceTextProvider_loadSourceTextItem_stub
_Java_netscape_jsdebug_JSSourceTextProvider_refreshSourceTextVector_stub
_Java_netscape_jsdebug_JSStackFrameInfo_getCaller0_stub
_Java_netscape_jsdebug_JSStackFrameInfo_getPC_stub
_Java_netscape_jsdebug_JSThreadState_countStackFrames_stub
_Java_netscape_jsdebug_JSThreadState_getCurrentFrame_stub
_Java_netscape_jsdebug_Script_getClosestPC_stub

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