Compare commits
228 Commits
STLPORT_FU
...
JS_150_RC2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1be2a254ab | ||
|
|
876455a0c2 | ||
|
|
21e1124549 | ||
|
|
5b9d4d00fe | ||
|
|
ec59086efc | ||
|
|
533b43cde1 | ||
|
|
fe3675bafb | ||
|
|
054615e9b5 | ||
|
|
c254065b69 | ||
|
|
bcd6f01203 | ||
|
|
fe85e51ec1 | ||
|
|
574470d12b | ||
|
|
fb441abad1 | ||
|
|
a53e5b86ae | ||
|
|
80c961899e | ||
|
|
49f0e8fbd7 | ||
|
|
2023ba127b | ||
|
|
d6a3fe495b | ||
|
|
aa56939a15 | ||
|
|
bf7551e324 | ||
|
|
086257b870 | ||
|
|
5192d123ff | ||
|
|
deebc2d183 | ||
|
|
d05b59fdd4 | ||
|
|
b54309d74e | ||
|
|
1f4e9d74e3 | ||
|
|
b93a1b200d | ||
|
|
37448b6cd5 | ||
|
|
4c482a8039 | ||
|
|
1f4e716975 | ||
|
|
8fe71d79fb | ||
|
|
fd89dc645d | ||
|
|
283dbf916a | ||
|
|
abbb64f9b6 | ||
|
|
6cb5a64229 | ||
|
|
f5ea1d5037 | ||
|
|
d25c24214f | ||
|
|
d605064355 | ||
|
|
da7b076b73 | ||
|
|
aceba3cb14 | ||
|
|
cd0a9ee2e5 | ||
|
|
a3f4aa3885 | ||
|
|
70c39b979b | ||
|
|
7bf37c93a1 | ||
|
|
0e025587c6 | ||
|
|
59648a42a7 | ||
|
|
562414f7a2 | ||
|
|
3fdc637ee3 | ||
|
|
75bf2b3286 | ||
|
|
b06d36e874 | ||
|
|
6f9124b236 | ||
|
|
0203addff1 | ||
|
|
8bed19c0f4 | ||
|
|
a353c7af55 | ||
|
|
b3ac151801 | ||
|
|
f9ab048302 | ||
|
|
5258badd5d | ||
|
|
a561ef00c3 | ||
|
|
a7c6f067ba | ||
|
|
52bb6e29f8 | ||
|
|
21cc5761af | ||
|
|
bd485d87d1 | ||
|
|
a92780d770 | ||
|
|
197df3eb6d | ||
|
|
adf04edef9 | ||
|
|
9f2c8a22ab | ||
|
|
0f38fc34ce | ||
|
|
6f9d6935c1 | ||
|
|
6a98845d2e | ||
|
|
52bb0a339f | ||
|
|
08521de430 | ||
|
|
a02313b652 | ||
|
|
d2cd2b7da7 | ||
|
|
db4ea3d12c | ||
|
|
635a8128c2 | ||
|
|
c2a66acc1b | ||
|
|
bbd34bcf56 | ||
|
|
cc337f55c5 | ||
|
|
70ca7352c2 | ||
|
|
ce55e593ed | ||
|
|
e3d813843b | ||
|
|
ad72d6a7d0 | ||
|
|
b62c0ba2a1 | ||
|
|
f4ff6546d0 | ||
|
|
09f7df0c44 | ||
|
|
26f87c8d88 | ||
|
|
a48966bc20 | ||
|
|
7800b6a386 | ||
|
|
52efcf92c2 | ||
|
|
95ad431597 | ||
|
|
54856496e7 | ||
|
|
fcdb5021b6 | ||
|
|
167b9652ed | ||
|
|
c0c2db4c65 | ||
|
|
70845ccdeb | ||
|
|
385e7049b5 | ||
|
|
70e672b557 | ||
|
|
3b81294931 | ||
|
|
a381dc926f | ||
|
|
d7af85ee20 | ||
|
|
486c5bf240 | ||
|
|
9fd9b17356 | ||
|
|
110cd31496 | ||
|
|
3e5e5fc62e | ||
|
|
1d954ee091 | ||
|
|
73c8ac5a65 | ||
|
|
a0f91732e3 | ||
|
|
b3e4027389 | ||
|
|
2e93b95d49 | ||
|
|
75160f506a | ||
|
|
b6f87a4424 | ||
|
|
d76f600e57 | ||
|
|
fa4f81157e | ||
|
|
f67c707f01 | ||
|
|
666c90e0b5 | ||
|
|
82561ae36e | ||
|
|
f3a97337d1 | ||
|
|
f1aaaa287d | ||
|
|
98d754b06b | ||
|
|
a98365dfed | ||
|
|
c1421e9b63 | ||
|
|
70c4ff39d8 | ||
|
|
02e48f1881 | ||
|
|
4b97bec576 | ||
|
|
567fb479a9 | ||
|
|
8934b0b4a8 | ||
|
|
97da702180 | ||
|
|
3af671024c | ||
|
|
d256d4063c | ||
|
|
7dac99e45a | ||
|
|
3bc8962650 | ||
|
|
46ffb41619 | ||
|
|
25ce7279d8 | ||
|
|
be286422e9 | ||
|
|
308345d274 | ||
|
|
0c4a96d4cd | ||
|
|
a3c64268eb | ||
|
|
79786792da | ||
|
|
590cd3db6c | ||
|
|
5ef5627a77 | ||
|
|
c8451d24ff | ||
|
|
ac8d315c84 | ||
|
|
54a4364827 | ||
|
|
5762ef1fd6 | ||
|
|
ab256053d1 | ||
|
|
add96b82b8 | ||
|
|
65d809d86e | ||
|
|
445d95e98f | ||
|
|
620180504e | ||
|
|
a8d2d03cf7 | ||
|
|
b84273a322 | ||
|
|
f38e7dc2dd | ||
|
|
14515507a0 | ||
|
|
2d48c6bdd2 | ||
|
|
dd974603d4 | ||
|
|
397833561e | ||
|
|
9eb2322a70 | ||
|
|
008b385261 | ||
|
|
5781121d8c | ||
|
|
c418b7516e | ||
|
|
7c41e37a91 | ||
|
|
3530f57cf6 | ||
|
|
49f4db362f | ||
|
|
8087d57440 | ||
|
|
ae40919f80 | ||
|
|
a6d254fa73 | ||
|
|
f24222db0c | ||
|
|
7b5c94fdfd | ||
|
|
b93eb7a136 | ||
|
|
ae43a6d29a | ||
|
|
f0444108cf | ||
|
|
e41658ac33 | ||
|
|
ca5318ba6e | ||
|
|
d76813a0c7 | ||
|
|
cdd091d1b8 | ||
|
|
7c3df7d271 | ||
|
|
fdf7b5ce90 | ||
|
|
8203ea88eb | ||
|
|
6e15ece5d5 | ||
|
|
ff91eb02e8 | ||
|
|
ec645543a3 | ||
|
|
974eeafb56 | ||
|
|
f7b4b88523 | ||
|
|
d2b4681dcf | ||
|
|
233eb23916 | ||
|
|
9f4c5558d5 | ||
|
|
0b95d0a63e | ||
|
|
de8926dab3 | ||
|
|
a5bf340b0c | ||
|
|
ce10ed0ff4 | ||
|
|
0791ddd9ce | ||
|
|
f8584ed533 | ||
|
|
add0c9cdb8 | ||
|
|
8a01712169 | ||
|
|
a31a1fc9c6 | ||
|
|
8e9e03a8d5 | ||
|
|
9ed3184949 | ||
|
|
8ce9ec7b53 | ||
|
|
3f5ec18e56 | ||
|
|
74736c0a31 | ||
|
|
589de4e8ac | ||
|
|
28b2fb591d | ||
|
|
f8274b2cfc | ||
|
|
8f09fd4435 | ||
|
|
f78674f4d2 | ||
|
|
dc56a78072 | ||
|
|
2475c1f8ed | ||
|
|
52fb92c9d0 | ||
|
|
47086a9c88 | ||
|
|
0436cd4e6b | ||
|
|
f3042b3427 | ||
|
|
f550faa147 | ||
|
|
438b051bb2 | ||
|
|
be9a6b605e | ||
|
|
596e21c82a | ||
|
|
cdb8546ba8 | ||
|
|
56bedac9da | ||
|
|
5731633fc2 | ||
|
|
de9aaf790a | ||
|
|
8de618903a | ||
|
|
4f776f02d4 | ||
|
|
6ef6f1fd36 | ||
|
|
c222336587 | ||
|
|
2888132355 | ||
|
|
7d3c7affc8 | ||
|
|
691e351a8a | ||
|
|
f375211dd9 | ||
|
|
ec6f6a23f7 |
@@ -1,44 +0,0 @@
|
||||
STLPORT = /usr/local/include/stlport
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -g -ggdb -DDEBUG -DXP_UNIX -Wall -W -Wpointer-arith \
|
||||
-Wbad-function-cast -Wstrict-prototypes -Wmissing-prototypes \
|
||||
-Wno-non-virtual-dtor -I$(STLPORT)
|
||||
|
||||
objs = hash.o \
|
||||
icodegenerator.o \
|
||||
interpreter.o \
|
||||
js2.o \
|
||||
jsmath.o \
|
||||
jstypes.o \
|
||||
numerics.o \
|
||||
parser.o \
|
||||
utilities.o \
|
||||
world.o \
|
||||
vmtypes.o \
|
||||
debugger.o
|
||||
|
||||
gc_path = ../../gc/boehm/
|
||||
|
||||
libs = gc.a -lstdc++ -lm
|
||||
|
||||
%.o : %.cpp
|
||||
$(CC) -c $(CFLAGS) $< -o $@
|
||||
|
||||
js2: $(objs) gc.a
|
||||
$(CC) -o $@ -ggdb $(objs) $(libs)
|
||||
|
||||
gc.a:
|
||||
(cd $(gc_path) ; ln -f -s Makefile.unix Makefile ; make gc.a)
|
||||
ln -f -s $(gc_path)gc.a ./gc.a
|
||||
|
||||
gctest: gc_allocator.o
|
||||
$(CC) -o $@ -ggdb $^ $(libs)
|
||||
|
||||
clean:
|
||||
rm -f $(objs)
|
||||
|
||||
depend:
|
||||
gcc -MM *.cpp > dependencies
|
||||
|
||||
include dependencies
|
||||
@@ -1,111 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="CPlusPlusTests" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=CPlusPlusTests - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "CPlusPlusTests.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "CPlusPlusTests.mak" CFG="CPlusPlusTests - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "CPlusPlusTests - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "CPlusPlusTests - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "CPlusPlusTests - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "CPlusPlusTests - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "CPlusPlusTests - Win32 Release"
|
||||
# Name "CPlusPlusTests - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cplusplustests.cpp
|
||||
|
||||
!IF "$(CFG)" == "CPlusPlusTests - Win32 Release"
|
||||
|
||||
!ELSEIF "$(CFG)" == "CPlusPlusTests - Win32 Debug"
|
||||
|
||||
# ADD CPP /Ob1 /FR
|
||||
# SUBTRACT CPP /O<none> /YX
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -1,29 +0,0 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "CPlusPlusTests"=.\CPlusPlusTests.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Binary file not shown.
@@ -1,129 +0,0 @@
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <new>
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct Arena {
|
||||
const char *name;
|
||||
|
||||
Arena(const char *name): name(name) {}
|
||||
};
|
||||
|
||||
|
||||
void *operator new(size_t size, Arena &arena);
|
||||
void operator delete(void *p);
|
||||
|
||||
void *operator new(size_t size, Arena &arena)
|
||||
{
|
||||
void *p = malloc(size);
|
||||
printf("Allocating %d bytes at %p using arena \"%s\"\n", size, p, arena.name);
|
||||
return p;
|
||||
}
|
||||
|
||||
#ifndef __MWERKS__
|
||||
void operator delete(void *p, Arena &arena)
|
||||
{
|
||||
printf("Deleting object at %p using arena \"%s\"\n", p, arena.name);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void operator delete(void *p)
|
||||
{
|
||||
printf("Deleting object at %p\n", p);
|
||||
}
|
||||
|
||||
|
||||
struct C {
|
||||
int n;
|
||||
|
||||
C(int n, bool bad = false);
|
||||
~C();
|
||||
};
|
||||
|
||||
struct Exception {
|
||||
int num;
|
||||
|
||||
explicit Exception(int n): num(n) {}
|
||||
};
|
||||
|
||||
|
||||
C::C(int n, bool bad): n(n)
|
||||
{
|
||||
printf("Constructing C #%d at %p\n", n, this);
|
||||
if (bad) {
|
||||
printf("Throwing %d; constructor aborted\n", n);
|
||||
throw Exception(n);
|
||||
}
|
||||
}
|
||||
|
||||
C::~C()
|
||||
{
|
||||
printf("Destroying C #%d at %p\n", n, this);
|
||||
}
|
||||
|
||||
|
||||
static void constructorTest1(int n, bool bad)
|
||||
{
|
||||
try {
|
||||
printf("Calling C(%d,%d)\n", n, (int)bad);
|
||||
{
|
||||
C c(n, bad);
|
||||
printf("We have C #%d\n", c.n);
|
||||
}
|
||||
printf("C is out of scope\n");
|
||||
} catch (Exception &e) {
|
||||
printf("Caught exception %d\n", e.num);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
static void constructorTest2(int n, bool bad)
|
||||
{
|
||||
try {
|
||||
printf("Calling new C(%d,%d)\n", n, (int)bad);
|
||||
{
|
||||
C *c = new C(n, bad);
|
||||
printf("We have C #%d\n", c->n);
|
||||
delete c;
|
||||
}
|
||||
printf("C is out of scope\n");
|
||||
} catch (Exception &e) {
|
||||
printf("Caught exception %d\n", e.num);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
static void constructorTest3(int n, bool bad)
|
||||
{
|
||||
try {
|
||||
printf("Calling new(arena) C(%d,%d)\n", n, (int)bad);
|
||||
{
|
||||
Arena arena("My arena");
|
||||
C *c = new(arena) C(n, bad);
|
||||
printf("We have C #%d\n", c->n);
|
||||
}
|
||||
printf("C is out of scope\n");
|
||||
} catch (Exception &e) {
|
||||
printf("Caught exception %d\n", e.num);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("Beginning constructor tests\n\n");
|
||||
constructorTest1(1, false);
|
||||
constructorTest1(2, true);
|
||||
constructorTest2(3, false);
|
||||
constructorTest2(4, true);
|
||||
constructorTest3(5, false);
|
||||
constructorTest3(6, true);
|
||||
printf("Ending constructor tests\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -1,466 +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.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the JavaScript 2 Prototype.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
#include "world.h"
|
||||
#include "debugger.h"
|
||||
|
||||
#include <string>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
namespace JavaScript {
|
||||
namespace Debugger {
|
||||
|
||||
using namespace Interpreter;
|
||||
|
||||
/* keep in sync with list in debugger.h */
|
||||
static const char *shell_cmds[][3] = {
|
||||
{"assemble", "", 0},
|
||||
{"ambiguous", "", "Test command for ambiguous command detection"},
|
||||
{"ambiguous2", "", "Test command for ambiguous command detection"},
|
||||
{"continue", "", "Continue execution until complete."},
|
||||
{"dissassemble", "[start_pc] [end_pc]", "Dissassemble entire module, or subset of module."},
|
||||
{"exit", "", 0},
|
||||
{"help", "", "Display this message."},
|
||||
{"istep", "", "Execute the current opcode and stop."},
|
||||
{"let", "", "Set a debugger environment variable."},
|
||||
{"print", "", 0},
|
||||
{"register", "", "(nyi) Show the value of a single register or all registers, or set the value of a single register."},
|
||||
{"step", "", "Execute the current JS statement and stop."},
|
||||
{0, 0} /* sentry */
|
||||
};
|
||||
|
||||
enum ShellVariable {
|
||||
TRACE_SOURCE,
|
||||
TRACE_ICODE,
|
||||
VARIABLE_COUNT
|
||||
};
|
||||
|
||||
static const char *shell_vars[][3] = {
|
||||
{"tracesource", "", "(bool) Show JS source while executing."},
|
||||
{"traceicode", " ", "(bool) Show opcodes while executing."},
|
||||
{0, 0} /* sentry */
|
||||
};
|
||||
|
||||
/* return true if str2 starts with/is str1
|
||||
* XXX ignore case */
|
||||
static bool
|
||||
startsWith (const String &str1, const String &str2)
|
||||
{
|
||||
uint n;
|
||||
size_t m = str1.size();
|
||||
|
||||
if (m > str2.size())
|
||||
return false;
|
||||
|
||||
for (n = 0; n < m; ++n)
|
||||
if (str1[n] != str2[n])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* locate the best match for |partial| in the command list |list|.
|
||||
* if no matches are found, return |length|, if multiple matches are found,
|
||||
* return |length| plus the number of ambiguous matches
|
||||
*/
|
||||
static uint32
|
||||
matchElement (const String &partial, const char *list[][3], size_t length)
|
||||
{
|
||||
uint32 ambig_matches = 0;
|
||||
uint32 match = length;
|
||||
|
||||
for (uint32 i = 0; i < length ; ++i)
|
||||
{
|
||||
String possibleMatch (widenCString(list[i][0]));
|
||||
if (startsWith(partial, possibleMatch))
|
||||
{
|
||||
if (partial.size() == possibleMatch.size())
|
||||
{
|
||||
/* exact match */
|
||||
ambig_matches = 0;
|
||||
return i;
|
||||
}
|
||||
else if (match == COMMAND_COUNT) /* no match yet */
|
||||
match = i;
|
||||
else
|
||||
++ambig_matches; /* something already matched,
|
||||
* ambiguous command */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (ambig_matches == 0)
|
||||
return match;
|
||||
else
|
||||
return length + ambig_matches;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
showHelp(Formatter &out)
|
||||
{
|
||||
int i;
|
||||
|
||||
out << "JavaScript 2.0 Debugger Help...\n\n";
|
||||
|
||||
for (i = 0; shell_cmds[i][0] != 0; i++)
|
||||
{
|
||||
out << "Command : " << shell_cmds[i][0] << " " <<
|
||||
shell_cmds[i][1] << "\n";
|
||||
|
||||
if (shell_cmds[i][2])
|
||||
out << "Help : " << shell_cmds[i][2] << "\n";
|
||||
else
|
||||
out << "Help : (probably) Not Implemented.\n";
|
||||
}
|
||||
}
|
||||
|
||||
static uint32
|
||||
getClosestSourcePosForPC (Context *cx, InstructionIterator pc)
|
||||
{
|
||||
ICodeModule *iCode = cx->getICode();
|
||||
|
||||
if (iCode->mInstructionMap->begin() == iCode->mInstructionMap->end())
|
||||
return NotABanana;
|
||||
/*NOT_REACHED ("Instruction map is empty, waah.");*/
|
||||
|
||||
InstructionMap::iterator pos_iter =
|
||||
iCode->mInstructionMap->upper_bound (pc - iCode->its_iCode->begin());
|
||||
if (pos_iter != iCode->mInstructionMap->begin())
|
||||
--pos_iter;
|
||||
|
||||
return pos_iter->second;
|
||||
}
|
||||
|
||||
void
|
||||
Shell::showSourceAtPC (Context *cx, InstructionIterator pc)
|
||||
{
|
||||
if (!mResolveFileCallback)
|
||||
{
|
||||
mErr << "Source not available (Debugger was improperly initialized.)\n";
|
||||
return;
|
||||
}
|
||||
|
||||
ICodeModule *iCode = cx->getICode();
|
||||
|
||||
String fn = iCode->getFileName();
|
||||
const Reader *reader = mResolveFileCallback(fn);
|
||||
if (!reader)
|
||||
{
|
||||
mErr << "Source not available.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 pos = getClosestSourcePosForPC(cx, pc);
|
||||
if (pos == NotABanana)
|
||||
{
|
||||
mErr << "Map is empty, cannot display source.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 lineNum = reader->posToLineNum (pos);
|
||||
const char16 *lineBegin, *lineEnd;
|
||||
|
||||
uint32 lineStartPos = reader->getLine (lineNum, lineBegin, lineEnd);
|
||||
String sourceLine (lineBegin, lineEnd);
|
||||
|
||||
mOut << fn << ":" << lineNum << " " << sourceLine << "\n";
|
||||
|
||||
uint padding = fn.length() + (uint32)(lineNum / 10) + 3;
|
||||
uint i;
|
||||
|
||||
for (i = 0; i < padding; i++)
|
||||
mOut << " ";
|
||||
|
||||
padding = (pos - lineStartPos);
|
||||
for (i = 0; i < padding; i++)
|
||||
mOut << ".";
|
||||
|
||||
mOut << "^\n";
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
Shell::showOpAtPC(Context* cx, InstructionIterator pc)
|
||||
{
|
||||
ICodeModule *iCode = cx->getICode();
|
||||
|
||||
if ((pc < iCode->its_iCode->begin()) ||
|
||||
(pc >= iCode->its_iCode->end()))
|
||||
{
|
||||
mErr << "PC Out Of Range.";
|
||||
return;
|
||||
}
|
||||
|
||||
JSValues ®isters = cx->getRegisters();
|
||||
|
||||
printFormat(mOut, "trace [%02u:%04u]: ",
|
||||
iCode->mID, (pc - iCode->its_iCode->begin()));
|
||||
Instruction* i = *pc;
|
||||
stdOut << *i;
|
||||
if (i->op() != BRANCH && i->count() > 0) {
|
||||
mOut << " [";
|
||||
i->printOperands(stdOut, registers);
|
||||
mOut << "]\n";
|
||||
} else {
|
||||
mOut << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Shell::listen(Context* cx, Context::Event event)
|
||||
{
|
||||
InstructionIterator pc = cx->getPC();
|
||||
|
||||
if (mTraceSource)
|
||||
showSourceAtPC (cx, pc);
|
||||
if (mTraceICode)
|
||||
showOpAtPC (cx, pc);
|
||||
|
||||
if (!(mStopMask & event))
|
||||
return;
|
||||
|
||||
if ((mLastCommand == STEP) && (mLastICodeID == cx->getICode()->mID) &&
|
||||
(mLastSourcePos == getClosestSourcePosForPC (cx, cx->getPC())))
|
||||
/* we're in source-step mode, and the source position hasn't
|
||||
* changed yet */
|
||||
return;
|
||||
|
||||
if (!mTraceSource && !mTraceICode)
|
||||
showSourceAtPC (cx, pc);
|
||||
|
||||
static String lastLine(widenCString("help\n"));
|
||||
String line;
|
||||
LineReader reader(mIn);
|
||||
|
||||
do {
|
||||
stdOut << "jsd";
|
||||
if (mLastCommand != COMMAND_COUNT)
|
||||
stdOut << " (" << shell_cmds[mLastCommand][0] << ") ";
|
||||
stdOut << "> ";
|
||||
|
||||
reader.readLine(line);
|
||||
|
||||
if (line[0] == uni::lf)
|
||||
line = lastLine;
|
||||
else
|
||||
lastLine = line;
|
||||
|
||||
} while (doCommand(cx, line));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* lex and execute the debugger command in |source|, return true if the
|
||||
* command does not require the script being debugged to continue (eg, ask
|
||||
* for more debugger input.)
|
||||
*/
|
||||
bool
|
||||
Shell::doCommand (Interpreter::Context *cx, const String &source)
|
||||
{
|
||||
Lexer lex (mWorld, source, widenCString("debugger console"), 0);
|
||||
const String *cmd;
|
||||
uint32 match;
|
||||
bool rv = true;
|
||||
|
||||
const Token &t = lex.get(true);
|
||||
|
||||
if (t.hasKind(Token::identifier))
|
||||
cmd = &(t.getIdentifier());
|
||||
else
|
||||
{
|
||||
mErr << "you idiot.\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
match = matchElement (*cmd, shell_cmds, (size_t)COMMAND_COUNT);
|
||||
|
||||
if (match <= (uint32)COMMAND_COUNT)
|
||||
{
|
||||
switch ((ShellCommand)match)
|
||||
{
|
||||
case COMMAND_COUNT:
|
||||
mErr << "Unknown command '" << *cmd << "'.\n";
|
||||
break;
|
||||
|
||||
case AMBIGUOUS:
|
||||
case AMBIGUOUS2:
|
||||
mErr << "I pity the foogoo.\n";
|
||||
break;
|
||||
|
||||
case CONTINUE:
|
||||
mStopMask &= (Context::EV_ALL ^ Context::EV_STEP);
|
||||
rv = false;
|
||||
break;
|
||||
|
||||
case DISSASSEMBLE:
|
||||
mOut << *cx->getICode();
|
||||
break;
|
||||
|
||||
case HELP:
|
||||
showHelp (mOut);
|
||||
break;
|
||||
|
||||
case PRINT:
|
||||
doPrint (cx, lex);
|
||||
break;
|
||||
|
||||
case STEP:
|
||||
mStopMask |= Context::EV_STEP;
|
||||
rv = false;
|
||||
break;
|
||||
|
||||
case LET:
|
||||
doSetVariable (lex);
|
||||
break;
|
||||
|
||||
default:
|
||||
mErr << "Input '" << *cmd << "' matched unimplemented " <<
|
||||
"command '" << shell_cmds[match][0] << "'.\n";
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
mLastSourcePos = getClosestSourcePosForPC (cx, cx->getPC());
|
||||
mLastICodeID = cx->getICode()->mID;
|
||||
mLastCommand = (ShellCommand)match;
|
||||
|
||||
} else
|
||||
mErr << "Ambiguous command '" << *cmd << "', " <<
|
||||
(match - (uint32)COMMAND_COUNT + 1) << " similar commands.\n";
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
Shell::doSetVariable (Lexer &lex)
|
||||
{
|
||||
uint32 match;
|
||||
const String *varname;
|
||||
const Token *t = &(lex.get(true));
|
||||
|
||||
if (t->hasKind(Token::identifier))
|
||||
varname = &(t->getIdentifier());
|
||||
else
|
||||
{
|
||||
mErr << "invalid variable name.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
match = matchElement (*varname, shell_vars, (size_t)VARIABLE_COUNT);
|
||||
|
||||
if (match <= (uint32)VARIABLE_COUNT)
|
||||
switch ((ShellVariable)match)
|
||||
{
|
||||
case VARIABLE_COUNT:
|
||||
mErr << "Unknown variable '" << *varname << "'.\n";
|
||||
break;
|
||||
|
||||
case TRACE_SOURCE:
|
||||
t = &(lex.get(true));
|
||||
if (t->hasKind(Token::assignment))
|
||||
t = &(lex.get(true)); /* optional = */
|
||||
|
||||
if (t->hasKind(Token::True))
|
||||
mTraceSource = true;
|
||||
else if (t->hasKind(Token::False))
|
||||
mTraceSource = false;
|
||||
else
|
||||
goto badval;
|
||||
break;
|
||||
|
||||
case TRACE_ICODE:
|
||||
t = &(lex.get(true));
|
||||
if (t->hasKind(Token::assignment))
|
||||
t = &(lex.get(true)); /* optional = */
|
||||
|
||||
if (t->hasKind(Token::True))
|
||||
mTraceICode = true;
|
||||
else if (t->hasKind(Token::False))
|
||||
mTraceICode = false;
|
||||
else
|
||||
goto badval;
|
||||
break;
|
||||
|
||||
default:
|
||||
mErr << "Variable '" << *varname <<
|
||||
"' matched unimplemented variable '" <<
|
||||
shell_vars[match][0] << "'.\n";
|
||||
}
|
||||
else
|
||||
mErr << "Ambiguous variable '" << *varname << "', " <<
|
||||
(match - (uint32)COMMAND_COUNT + 1) << " similar variables.\n";
|
||||
|
||||
return;
|
||||
|
||||
badval:
|
||||
mErr << "Invalid value for variable '" <<
|
||||
shell_vars[(ShellVariable)match][0] << "'\n";
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
Shell::doPrint (Context *, Lexer &lex)
|
||||
{
|
||||
const Token *t = &(lex.get(true));
|
||||
|
||||
if (!(t->hasKind(Token::identifier)))
|
||||
{
|
||||
mErr << "Invalid register name.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
const StringAtom *name = &(t->getIdentifier());
|
||||
|
||||
VariableMap::iterator i = ((cx->getICode())->itsVariables)->find(*name);
|
||||
// if (i)
|
||||
mOut << (*i).first << " = " << (*i).second << "\n";
|
||||
// else
|
||||
// mOut << "No " << *name << " defined.\n";
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} /* namespace Debugger */
|
||||
} /* namespace JavaScript */
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the JavaScript 2 Prototype.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
/* this is all vapor, don't take it to serious yet */
|
||||
|
||||
#ifndef debugger_h
|
||||
#define debugger_h
|
||||
|
||||
#include "utilities.h"
|
||||
#include "interpreter.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace JavaScript {
|
||||
namespace Debugger {
|
||||
|
||||
using namespace Interpreter;
|
||||
|
||||
class Shell;
|
||||
|
||||
typedef const Reader *ResolveFileCallback (const String &fileName);
|
||||
typedef bool DebuggerCommandCallback (Shell &debugger, const Lexer &lex);
|
||||
|
||||
class Breakpoint {
|
||||
public:
|
||||
/* representation of a breakpoint */
|
||||
void set();
|
||||
void clear();
|
||||
bool getState();
|
||||
InstructionIterator getPC();
|
||||
};
|
||||
|
||||
struct DebuggerCommand
|
||||
{
|
||||
DebuggerCommand(String aName, String aParamDesc, String aShortHelp,
|
||||
String aLongHelp = widenCString("No more help available."),
|
||||
DebuggerCommandCallback *aCommandFunction = 0)
|
||||
: mName(aName), mParamDesc(aParamDesc), mShortHelp(aShortHelp),
|
||||
mLongHelp(aLongHelp), mCommandFunction(aCommandFunction) {}
|
||||
|
||||
String mName;
|
||||
String mParamDesc;
|
||||
String mShortHelp;
|
||||
String mLongHelp;
|
||||
DebuggerCommandCallback *mCommandFunction;
|
||||
};
|
||||
|
||||
/* keep in sync with list in debugger.cpp */
|
||||
enum ShellCommand {
|
||||
ASSEMBLE,
|
||||
AMBIGUOUS,
|
||||
AMBIGUOUS2,
|
||||
CONTINUE,
|
||||
DISSASSEMBLE,
|
||||
EXIT,
|
||||
HELP,
|
||||
ISTEP,
|
||||
LET,
|
||||
PRINT,
|
||||
REGISTER,
|
||||
STEP,
|
||||
COMMAND_COUNT
|
||||
};
|
||||
|
||||
class Shell : public Context::Listener {
|
||||
public:
|
||||
Shell (World &aWorld, FILE *aIn, Formatter &aOut, Formatter &aErr,
|
||||
ResolveFileCallback *aCallback = 0) :
|
||||
mWorld(aWorld), mIn(aIn), mOut(aOut), mErr(aErr),
|
||||
mResolveFileCallback(aCallback), mStopMask(Context::EV_DEBUG),
|
||||
mTraceSource(false), mTraceICode(false), mLastSourcePos(0),
|
||||
mLastICodeID(NotABanana), mLastCommand(COMMAND_COUNT)
|
||||
{
|
||||
}
|
||||
|
||||
~Shell ()
|
||||
{
|
||||
}
|
||||
|
||||
ResolveFileCallback
|
||||
*setResolveFileCallback (ResolveFileCallback *aCallback)
|
||||
{
|
||||
ResolveFileCallback *rv = mResolveFileCallback;
|
||||
mResolveFileCallback = aCallback;
|
||||
return rv;
|
||||
}
|
||||
|
||||
void listen(Context *context, Context::Event event);
|
||||
|
||||
/**
|
||||
* install on a context
|
||||
*/
|
||||
bool attachToContext (Context *aContext)
|
||||
{
|
||||
aContext->addListener (this);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* detach an icdebugger from a context
|
||||
*/
|
||||
bool detachFromContext (Context *aContext)
|
||||
{
|
||||
aContext->removeListener (this);
|
||||
return true;
|
||||
}
|
||||
|
||||
FILE *getIStream() { return mIn; }
|
||||
Formatter &getOStream() { return mOut; }
|
||||
Formatter &getEStream() { return mErr; }
|
||||
|
||||
private:
|
||||
bool doCommand (Context *cx, const String &aSource);
|
||||
void doSetVariable (Lexer &lex);
|
||||
void doPrint (Context *cx, Lexer &lex);
|
||||
|
||||
void showOpAtPC(Context* cx, InstructionIterator pc);
|
||||
void showSourceAtPC(Context* cx, InstructionIterator pc);
|
||||
|
||||
World &mWorld;
|
||||
FILE *mIn;
|
||||
Formatter &mOut, &mErr;
|
||||
ResolveFileCallback *mResolveFileCallback;
|
||||
uint32 mStopMask;
|
||||
bool mTraceSource, mTraceICode;
|
||||
uint32 mLastSourcePos, mLastICodeID;
|
||||
ShellCommand mLastCommand;
|
||||
};
|
||||
|
||||
} /* namespace Debugger */
|
||||
} /* namespace JavaScript */
|
||||
|
||||
#endif /* debugger_h */
|
||||
@@ -1,26 +0,0 @@
|
||||
debugger.o: debugger.cpp world.h utilities.h systemtypes.h hash.h \
|
||||
parser.h debugger.h interpreter.h jstypes.h gc_allocator.h vmtypes.h \
|
||||
numerics.h jsclasses.h icode.h icodegenerator.h
|
||||
gc_allocator.o: gc_allocator.cpp gc_allocator.h gc_container.h
|
||||
hash.o: hash.cpp hash.h utilities.h systemtypes.h
|
||||
icodegenerator.o: icodegenerator.cpp numerics.h utilities.h \
|
||||
systemtypes.h world.h hash.h parser.h vmtypes.h jstypes.h \
|
||||
gc_allocator.h jsclasses.h icode.h icodegenerator.h interpreter.h
|
||||
interpreter.o: interpreter.cpp interpreter.h utilities.h systemtypes.h \
|
||||
jstypes.h gc_allocator.h vmtypes.h numerics.h jsclasses.h world.h \
|
||||
hash.h parser.h icode.h icodegenerator.h jsmath.h
|
||||
js2.o: js2.cpp world.h utilities.h systemtypes.h hash.h parser.h \
|
||||
interpreter.h jstypes.h gc_allocator.h vmtypes.h numerics.h \
|
||||
jsclasses.h icode.h icodegenerator.h debugger.h
|
||||
jsmath.o: jsmath.cpp jsmath.h jstypes.h utilities.h systemtypes.h \
|
||||
gc_allocator.h
|
||||
jstypes.o: jstypes.cpp jstypes.h utilities.h systemtypes.h \
|
||||
gc_allocator.h jsclasses.h numerics.h icodegenerator.h parser.h \
|
||||
vmtypes.h world.h hash.h icode.h
|
||||
numerics.o: numerics.cpp numerics.h utilities.h systemtypes.h
|
||||
parser.o: parser.cpp numerics.h utilities.h systemtypes.h parser.h \
|
||||
world.h hash.h
|
||||
utilities.o: utilities.cpp utilities.h systemtypes.h
|
||||
vmtypes.o: vmtypes.cpp utilities.h systemtypes.h vmtypes.h numerics.h \
|
||||
jstypes.h gc_allocator.h jsclasses.h world.h hash.h parser.h icode.h
|
||||
world.o: world.cpp world.h utilities.h systemtypes.h hash.h parser.h
|
||||
@@ -1,150 +0,0 @@
|
||||
// -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*-
|
||||
//
|
||||
// The contents of this file are subject to the Netscape Public
|
||||
// License Version 1.1 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of
|
||||
// the License at http://www.mozilla.org/NPL/
|
||||
//
|
||||
// Software distributed under the License is distributed on an "AS
|
||||
// IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
// implied. See the License for the specific language governing
|
||||
// rights and limitations under the License.
|
||||
//
|
||||
// The Original Code is the JavaScript 2 Prototype.
|
||||
//
|
||||
// The Initial Developer of the Original Code is Netscape
|
||||
// Communications Corporation. Portions created by Netscape are
|
||||
// Copyright (C) 2000 Netscape Communications Corporation. All
|
||||
// Rights Reserved.
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "gc_allocator.h"
|
||||
#include "gc_container.h"
|
||||
|
||||
/*
|
||||
namespace JavaScript {
|
||||
|
||||
template <class T>
|
||||
typename gc_allocator<T>::pointer
|
||||
gc_allocator<T>::allocate(gc_allocator<T>::size_type n, const void*)
|
||||
{
|
||||
return static_cast<pointer>(GC_malloc(n*sizeof(T)));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void gc_allocator<T>::deallocate(gc_allocator<T>::pointer ptr, gc_allocator<T>::size_type)
|
||||
{
|
||||
// this can really be a NO-OP with the GC.
|
||||
// ::GC_free(static_cast<void*>(ptr));
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
// test driver for standalone GC development.
|
||||
|
||||
namespace JS = JavaScript;
|
||||
|
||||
template <class T>
|
||||
void* operator new(std::size_t, const JS::gc_allocator<T>& alloc)
|
||||
{
|
||||
return alloc.allocate(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a C++ class that is garbage collectable, and wants to have its destructor
|
||||
* called when it is finalized.
|
||||
*/
|
||||
class A {
|
||||
public:
|
||||
typedef JS::gc_traits_finalizable<A> traits;
|
||||
typedef JS::gc_allocator<A, traits> allocator;
|
||||
friend struct traits;
|
||||
|
||||
static int instances;
|
||||
|
||||
void* operator new(std::size_t)
|
||||
{
|
||||
return allocator::allocate(1);
|
||||
}
|
||||
|
||||
A()
|
||||
{
|
||||
++instances;
|
||||
std::cout << "A::A() here." << std::endl;
|
||||
}
|
||||
|
||||
protected:
|
||||
~A()
|
||||
{
|
||||
--instances;
|
||||
std::cout << "A::~A() here." << std::endl;
|
||||
}
|
||||
|
||||
private:
|
||||
// void operator delete(void*) {}
|
||||
};
|
||||
|
||||
int A::instances = 0;
|
||||
|
||||
int main(int /* argc */, char* /* argv[] */)
|
||||
{
|
||||
using namespace std;
|
||||
using namespace JS;
|
||||
|
||||
cout << "testing the GC allocator." << endl;
|
||||
|
||||
#ifdef XP_MAC
|
||||
// allocate a string, using the GC, and owned by an auto_ptr, that knows how to correctly destroy the string.
|
||||
typedef gc_container<char>::string char_string;
|
||||
typedef gc_allocator<char_string> char_string_alloc;
|
||||
auto_ptr<char_string, char_string_alloc> ptr(new(char_string_alloc()) char_string("This is a garbage collectable string."));
|
||||
const char_string& str = *ptr;
|
||||
cout << str << endl;
|
||||
#endif
|
||||
|
||||
// question, how can we partially evaluate a template?
|
||||
// can we say, typedef template <class T> vector<typename T>.
|
||||
// typedef vector<int, gc_allocator<int> > int_vector;
|
||||
typedef gc_container<int>::vector int_vector;
|
||||
|
||||
// generate 1000 random values.
|
||||
int_vector values;
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
int value = rand() % 32767;
|
||||
values.push_back(value);
|
||||
// allocate a random amount of garbage.
|
||||
if (!GC_malloc(static_cast<size_t>(value)))
|
||||
cerr << "GC_malloc failed." << endl;
|
||||
// allocate an object that has a finalizer to call its destructor.
|
||||
A* a = new A();
|
||||
}
|
||||
|
||||
// run a collection.
|
||||
// gc_allocator<void>::collect();
|
||||
GC_gcollect();
|
||||
|
||||
// print out instance count.
|
||||
cout << "A::instances = " << A::instances << endl;
|
||||
|
||||
// sort the values.
|
||||
sort(values.begin(), values.end());
|
||||
|
||||
// print the values.
|
||||
int_vector::iterator iter = values.begin(), last = values.end();
|
||||
cout << *iter++;
|
||||
while (iter < last)
|
||||
cout << ' ' << *iter++;
|
||||
cout << endl;
|
||||
|
||||
#ifdef XP_MAC
|
||||
// finally, print the string again.
|
||||
cout << str << endl;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
// -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*-
|
||||
//
|
||||
// The contents of this file are subject to the Netscape Public
|
||||
// License Version 1.1 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of
|
||||
// the License at http://www.mozilla.org/NPL/
|
||||
//
|
||||
// Software distributed under the License is distributed on an "AS
|
||||
// IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
// implied. See the License for the specific language governing
|
||||
// rights and limitations under the License.
|
||||
//
|
||||
// The Original Code is the JavaScript 2 Prototype.
|
||||
//
|
||||
// The Initial Developer of the Original Code is Netscape
|
||||
// Communications Corporation. Portions created by Netscape are
|
||||
// Copyright (C) 2000 Netscape Communications Corporation. All
|
||||
// Rights Reserved.
|
||||
|
||||
#ifndef gc_allocator_h
|
||||
#define gc_allocator_h
|
||||
|
||||
#include <memory>
|
||||
|
||||
#ifndef _WIN32 // Microsoft VC6 bug: standard identifiers should be in std namespace
|
||||
using std::size_t;
|
||||
using std::ptrdiff_t;
|
||||
#endif
|
||||
|
||||
namespace JavaScript {
|
||||
extern "C" {
|
||||
void* GC_malloc(size_t bytes);
|
||||
void* GC_malloc_atomic(size_t bytes);
|
||||
void GC_free(void* ptr);
|
||||
void GC_gcollect(void);
|
||||
|
||||
typedef void (*GC_finalization_proc) (void* obj, void* client_data);
|
||||
void GC_register_finalizer(void* obj, GC_finalization_proc proc, void* client_data,
|
||||
GC_finalization_proc *old_proc, void* *old_client_data);
|
||||
}
|
||||
|
||||
#if 0 && !defined(XP_MAC)
|
||||
// for platforms where GC doesn't exist yet.
|
||||
inline void* GC_malloc(size_t bytes) { return ::operator new(bytes); }
|
||||
inline void* GC_malloc_atomic(size_t bytes) { return ::operator new(bytes); }
|
||||
inline void GC_free(void* ptr) { operator delete(ptr); }
|
||||
inline void GC_gcollect() {}
|
||||
inline void GC_register_finalizer(void* obj, GC_finalization_proc proc, void* client_data,
|
||||
GC_finalization_proc *old_proc, void* *old_client_data) {}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* General case: memory for type must be allocated as a conservatively
|
||||
* scanned block of memory.
|
||||
*/
|
||||
template <class T> struct gc_traits {
|
||||
static T* allocate(size_t n) { return static_cast<T*>(GC_malloc(n * sizeof(T))); }
|
||||
};
|
||||
|
||||
/**
|
||||
* Specializations for blocks of atomic types: the macro define_atomic_type(_type)
|
||||
* specializes gc_traits<T> for types that need not be scanned by the
|
||||
* GC. Implementors are free to define other types as atomic, if they are
|
||||
* guaranteed not to contain pointers.
|
||||
*/
|
||||
#define define_atomic_type(_type) \
|
||||
template <> struct gc_traits<_type> { \
|
||||
static _type* allocate(size_t n) \
|
||||
{ \
|
||||
return static_cast<_type*>(GC_malloc_atomic(n * sizeof(_type))); \
|
||||
} \
|
||||
};
|
||||
|
||||
define_atomic_type(char)
|
||||
define_atomic_type(unsigned char)
|
||||
define_atomic_type(short)
|
||||
define_atomic_type(unsigned short)
|
||||
define_atomic_type(int)
|
||||
define_atomic_type(unsigned int)
|
||||
define_atomic_type(long)
|
||||
define_atomic_type(unsigned long)
|
||||
define_atomic_type(float)
|
||||
define_atomic_type(double)
|
||||
|
||||
#undef define_atomic_type
|
||||
|
||||
/**
|
||||
* Traits for classes that need to have their destructor called
|
||||
* when reclaimed by the garbage collector.
|
||||
*/
|
||||
template <class T> struct gc_traits_finalizable {
|
||||
static void finalizer(void* obj, void* client_data)
|
||||
{
|
||||
T* t = static_cast<T*>(obj);
|
||||
size_t n = reinterpret_cast<size_t>(client_data);
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
t[i].~T();
|
||||
}
|
||||
|
||||
static T* allocate(size_t n)
|
||||
{
|
||||
T* t = gc_traits<T>::allocate(n);
|
||||
GC_finalization_proc old_proc; void* old_client_data;
|
||||
GC_register_finalizer(t, &finalizer, reinterpret_cast<void*>(n), &old_proc, &old_client_data);
|
||||
return t;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* An allocator that can be used to allocate objects in the garbage collected heap.
|
||||
*/
|
||||
template <class T, class traits = gc_traits<T> > class gc_allocator {
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef T *pointer;
|
||||
typedef const T *const_pointer;
|
||||
typedef T &reference;
|
||||
typedef const T &const_reference;
|
||||
|
||||
gc_allocator() {}
|
||||
template<typename U, typename UTraits> gc_allocator(const gc_allocator<U, UTraits>&) {}
|
||||
// ~gc_allocator() {}
|
||||
|
||||
static pointer address(reference r) { return &r; }
|
||||
static const_pointer address(const_reference r) { return &r; }
|
||||
|
||||
static pointer allocate(size_type n, const void* /* hint */ = 0) { return traits::allocate(n); }
|
||||
static void deallocate(pointer, size_type) {}
|
||||
|
||||
static void construct(pointer p, const T &val) { new(p) T(val);}
|
||||
static void destroy(pointer p) { p->~T(); }
|
||||
|
||||
#if defined(__GNUC__) || defined(_WIN32)
|
||||
static size_type max_size() { return size_type(-1) / sizeof(T); }
|
||||
#else
|
||||
static size_type max_size() { return std::numeric_limits<size_type>::max() / sizeof(T); }
|
||||
#endif
|
||||
|
||||
template<class U> struct rebind { typedef gc_allocator<U> other; };
|
||||
|
||||
#ifdef _WIN32
|
||||
// raw byte allocator used on some platforms (grrr).
|
||||
typedef char _Char[1];
|
||||
static char* _Charalloc(size_type n) { return (char*) rebind<_Char>::other::allocate(n); }
|
||||
|
||||
// funky operator required for calling basic_string<T> constructor (grrr).
|
||||
template<typename U, typename UTraits> int operator==(const gc_allocator<U, UTraits>&) { return 0; }
|
||||
#endif
|
||||
|
||||
// void* deallocate used on some platforms (grrr).
|
||||
static void deallocate(void*, size_type) {}
|
||||
|
||||
static void collect() { GC_gcollect(); }
|
||||
};
|
||||
|
||||
/**
|
||||
* Generic base class for objects allocated using a gc_allocator. How they are allocated
|
||||
* can be controlled by specializing gc_traits for the specific class.
|
||||
*/
|
||||
template <typename T> class gc_object {
|
||||
public:
|
||||
void* operator new(size_t) { return gc_allocator<T>::allocate(1, 0); }
|
||||
void operator delete(void* /* ptr */) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Simpler base class for classes that have no need to specialize allocation behavior.
|
||||
*/
|
||||
class gc_base {
|
||||
public:
|
||||
void* operator new(size_t n) { return GC_malloc(n); }
|
||||
void operator delete(void*) {}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* gc_allocator_h */
|
||||
@@ -1,71 +0,0 @@
|
||||
// -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*-
|
||||
//
|
||||
// The contents of this file are subject to the Netscape Public
|
||||
// License Version 1.1 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of
|
||||
// the License at http://www.mozilla.org/NPL/
|
||||
//
|
||||
// Software distributed under the License is distributed on an "AS
|
||||
// IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
// implied. See the License for the specific language governing
|
||||
// rights and limitations under the License.
|
||||
//
|
||||
// The Original Code is the JavaScript 2 Prototype.
|
||||
//
|
||||
// The Initial Developer of the Original Code is Netscape
|
||||
// Communications Corporation. Portions created by Netscape are
|
||||
// Copyright (C) 2000 Netscape Communications Corporation. All
|
||||
// Rights Reserved.
|
||||
|
||||
#ifndef gc_container_h
|
||||
#define gc_container_h
|
||||
|
||||
#include "gc_allocator.h"
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#define LIST std::list
|
||||
#define VECTOR std::vector
|
||||
|
||||
#if defined(__GNUC__)
|
||||
// grr, what kind of standard is this?
|
||||
#define STRING basic_string
|
||||
#define CHAR_TRAITS string_char_traits
|
||||
#else
|
||||
#define STRING std::basic_string
|
||||
#define CHAR_TRAITS std::char_traits
|
||||
#endif
|
||||
|
||||
namespace JavaScript {
|
||||
/**
|
||||
* Rebind some of the basic container types to use a GC_allocator.
|
||||
* What I really want is something more general, something like:
|
||||
* template <typename Container, typename T> class gc_rebind {
|
||||
* typedef typename Container<T, gc_allocator<T> > other;
|
||||
* };
|
||||
* But I can't figure out how to do that with C++ templates.
|
||||
*/
|
||||
template <class T> struct gc_container {
|
||||
typedef typename LIST<T, gc_allocator<T> > list;
|
||||
typedef typename VECTOR<T, gc_allocator<T> > vector;
|
||||
typedef typename STRING<T, CHAR_TRAITS<T>, gc_allocator<T> > string;
|
||||
};
|
||||
|
||||
/**
|
||||
* But, it's pretty easy to do with macros:
|
||||
*/
|
||||
#define GC_CONTAINER(container, type) container<T, gc_allocator<T> >
|
||||
|
||||
/*
|
||||
// this gives an "unimplemented C++ feature" error using CWPro5.
|
||||
// maybe someday.
|
||||
template <template<class, class> typename Container, typename T>
|
||||
struct gc_rebind {
|
||||
typedef typename Container<T, gc_allocator<T> > container;
|
||||
};
|
||||
*/
|
||||
}
|
||||
|
||||
#endif /* gc_container_h */
|
||||
@@ -1,173 +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.1 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of
|
||||
// the License at http://www.mozilla.org/NPL/
|
||||
//
|
||||
// Software distributed under the License is distributed on an "AS
|
||||
// IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
// implied. See the License for the specific language governing
|
||||
// rights and limitations under the License.
|
||||
//
|
||||
// The Original Code is the JavaScript 2 Prototype.
|
||||
//
|
||||
// The Initial Developer of the Original Code is Netscape
|
||||
// Communications Corporation. Portions created by Netscape are
|
||||
// Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
// Rights Reserved.
|
||||
|
||||
#include "hash.h"
|
||||
#include <new>
|
||||
namespace JS = JavaScript;
|
||||
|
||||
|
||||
//
|
||||
// Hash Codes
|
||||
//
|
||||
|
||||
|
||||
// General-purpose null-terminated C string hash function
|
||||
JS::HashNumber JS::hashString(const char *s)
|
||||
{
|
||||
HashNumber h = 0;
|
||||
uchar ch;
|
||||
|
||||
while ((ch = (uchar)*s++) != 0)
|
||||
h = (h >> 28) ^ (h << 4) ^ ch;
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
// General-purpose String hash function
|
||||
JS::HashNumber JS::hashString(const String &s)
|
||||
{
|
||||
HashNumber h = 0;
|
||||
String::const_iterator p = s.begin();
|
||||
String::size_type n = s.size();
|
||||
|
||||
if (n < 16)
|
||||
// Hash every character in a short string.
|
||||
while (n--)
|
||||
h = (h >> 28) ^ (h << 4) ^ *p++;
|
||||
else
|
||||
// Sample a la java.lang.String.hash().
|
||||
for (String::size_type m = n / 8; n >= m; p += m, n -= m)
|
||||
h = (h >> 28) ^ (h << 4) ^ *p;
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Hash Tables
|
||||
//
|
||||
|
||||
|
||||
const uint minLgNBuckets = 4;
|
||||
|
||||
|
||||
JS::GenericHashTableIterator::GenericHashTableIterator(GenericHashTable &ht):
|
||||
ht(ht), entry(0), nextBucket(ht.buckets)
|
||||
{
|
||||
DEBUG_ONLY(++ht.nReferences);
|
||||
operator++();
|
||||
}
|
||||
|
||||
|
||||
|
||||
JS::GenericHashTableIterator &
|
||||
JS::GenericHashTableIterator::operator++()
|
||||
{
|
||||
GenericHashEntry *e = entry;
|
||||
|
||||
if (e) {
|
||||
backpointer = &e->next;
|
||||
e = e->next;
|
||||
}
|
||||
if (!e) {
|
||||
GenericHashEntry **const bucketsEnd = ht.bucketsEnd;
|
||||
GenericHashEntry **bucket = nextBucket;
|
||||
|
||||
while (bucket != bucketsEnd) {
|
||||
e = *bucket++;
|
||||
if (e) {
|
||||
backpointer = bucket-1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
nextBucket = bucket;
|
||||
}
|
||||
entry = e;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
JS::GenericHashTable::GenericHashTable(uint32 nEntriesDefault):
|
||||
nEntries(0)
|
||||
{
|
||||
DEBUG_ONLY(nReferences = 0);
|
||||
|
||||
uint lgNBuckets = ceilingLog2(nEntriesDefault);
|
||||
if (lgNBuckets < minLgNBuckets)
|
||||
lgNBuckets = minLgNBuckets;
|
||||
defaultLgNBuckets = lgNBuckets;
|
||||
|
||||
recomputeMinMaxNEntries(lgNBuckets);
|
||||
uint32 nBuckets = JS_BIT(lgNBuckets);
|
||||
buckets = new GenericHashEntry*[nBuckets];
|
||||
// No exceptions after this point unless buckets is deleted.
|
||||
|
||||
bucketsEnd = buckets + nBuckets;
|
||||
zero(buckets, bucketsEnd);
|
||||
}
|
||||
|
||||
|
||||
// Initialize shift, minNEntries, and maxNEntries based on the lg2 of the
|
||||
// number of buckets.
|
||||
void JS::GenericHashTable::recomputeMinMaxNEntries(uint lgNBuckets)
|
||||
{
|
||||
uint32 nBuckets = JS_BIT(lgNBuckets);
|
||||
shift = 32 - lgNBuckets;
|
||||
maxNEntries = nBuckets; // Maximum ratio is 100%
|
||||
minNEntries = lgNBuckets <= defaultLgNBuckets ? 0 : 3*(nBuckets>>3); // Minimum ratio is 37.5%
|
||||
}
|
||||
|
||||
|
||||
// Rehash the table. This method cannot throw out-of-memory exceptions, so it is
|
||||
// safe to call from a destructor.
|
||||
void JS::GenericHashTable::rehash()
|
||||
{
|
||||
uint32 newLgNBuckets = ceilingLog2(nEntries);
|
||||
if (newLgNBuckets < defaultLgNBuckets)
|
||||
newLgNBuckets = defaultLgNBuckets;
|
||||
uint32 newNBuckets = JS_BIT(newLgNBuckets);
|
||||
try {
|
||||
GenericHashEntry **newBuckets = new GenericHashEntry*[newNBuckets];
|
||||
// No exceptions after this point.
|
||||
|
||||
GenericHashEntry **newBucketsEnd = newBuckets + newNBuckets;
|
||||
zero(newBuckets, newBucketsEnd);
|
||||
recomputeMinMaxNEntries(newLgNBuckets);
|
||||
GenericHashEntry **be = bucketsEnd;
|
||||
for (GenericHashEntry **b = buckets; b != be; b++) {
|
||||
GenericHashEntry *e = *b;
|
||||
while (e) {
|
||||
GenericHashEntry *next = e->next;
|
||||
// Place e in the new set of buckets.
|
||||
GenericHashEntry **nb = newBuckets + (e->keyHash*goldenRatio >> shift);
|
||||
e->next = *nb;
|
||||
*nb = e;
|
||||
e = next;
|
||||
}
|
||||
}
|
||||
delete[] buckets;
|
||||
buckets = newBuckets;
|
||||
bucketsEnd = newBucketsEnd;
|
||||
} catch (std::bad_alloc) {
|
||||
// Out of memory. Ignore the error and just relax the resizing boundaries.
|
||||
if (buckets + JS_BIT(newLgNBuckets) > bucketsEnd)
|
||||
maxNEntries >>= 1;
|
||||
else
|
||||
minNEntries <<= 1;
|
||||
}
|
||||
}
|
||||
@@ -1,373 +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.1 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of
|
||||
// the License at http://www.mozilla.org/NPL/
|
||||
//
|
||||
// Software distributed under the License is distributed on an "AS
|
||||
// IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
// implied. See the License for the specific language governing
|
||||
// rights and limitations under the License.
|
||||
//
|
||||
// The Original Code is the JavaScript 2 Prototype.
|
||||
//
|
||||
// The Initial Developer of the Original Code is Netscape
|
||||
// Communications Corporation. Portions created by Netscape are
|
||||
// Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
// Rights Reserved.
|
||||
|
||||
#ifndef hash_h
|
||||
#define hash_h
|
||||
|
||||
#include "utilities.h"
|
||||
|
||||
namespace JavaScript {
|
||||
|
||||
|
||||
//
|
||||
// Hash Codes
|
||||
//
|
||||
|
||||
typedef uint32 HashNumber;
|
||||
|
||||
HashNumber hashString(const char *s);
|
||||
HashNumber hashString(const String &s);
|
||||
|
||||
|
||||
template<class Key>
|
||||
struct Hash {
|
||||
HashNumber operator()(Key key) const;
|
||||
};
|
||||
|
||||
template<class Key>
|
||||
inline HashNumber Hash<Key>::operator()(Key key) const
|
||||
{
|
||||
return hashString(key);
|
||||
}
|
||||
|
||||
|
||||
const HashNumber goldenRatio = 0x9E3779B9U;
|
||||
|
||||
|
||||
//
|
||||
// Private
|
||||
//
|
||||
|
||||
// Base class for user-defined hash entries.
|
||||
// private
|
||||
class GenericHashEntry {
|
||||
public:
|
||||
GenericHashEntry *next; // Link to next entry in the same bucket
|
||||
const HashNumber keyHash; // This entry's hash value
|
||||
|
||||
protected:
|
||||
explicit GenericHashEntry(HashNumber keyHash): next(0), keyHash(keyHash) {}
|
||||
|
||||
friend class GenericHashTable;
|
||||
};
|
||||
|
||||
|
||||
// private
|
||||
class GenericHashTableIterator;
|
||||
class GenericHashTable {
|
||||
protected:
|
||||
GenericHashEntry **buckets; // Vector of hash buckets
|
||||
GenericHashEntry **bucketsEnd; // Pointer past end of vector of hash buckets
|
||||
uint defaultLgNBuckets; // lg2 of minimum number of buckets for which to size the table
|
||||
uint32 nEntries; // Number of entries in table
|
||||
uint32 minNEntries; // Minimum number of entries without rehashing
|
||||
uint32 maxNEntries; // Maximum number of entries without rehashing
|
||||
uint32 shift; // 32 - lg2(number of buckets)
|
||||
#ifdef DEBUG
|
||||
public:
|
||||
uint32 nReferences; // Number of iterators and references currently pointing to this hash table
|
||||
#endif
|
||||
|
||||
public:
|
||||
explicit GenericHashTable(uint32 nEntriesDefault);
|
||||
~GenericHashTable() {
|
||||
#ifndef _WIN32
|
||||
ASSERT(nReferences == 0);
|
||||
#endif
|
||||
delete[] buckets;
|
||||
}
|
||||
|
||||
void recomputeMinMaxNEntries(uint lgNBuckets);
|
||||
void rehash();
|
||||
void maybeGrow() {if (nEntries > maxNEntries) rehash();}
|
||||
void maybeShrink() {if (nEntries < minNEntries) rehash();}
|
||||
|
||||
friend class GenericHashTableIterator;
|
||||
|
||||
typedef GenericHashTableIterator Iterator;
|
||||
};
|
||||
|
||||
// This ought to be GenericHashTable::Iterator, but this doesn't work due to a
|
||||
// Microsoft VC6 bug.
|
||||
class GenericHashTableIterator {
|
||||
protected:
|
||||
GenericHashTable &ht; // Hash table being iterated
|
||||
GenericHashEntry *entry; // Current entry; nil if done
|
||||
GenericHashEntry **backpointer; // Pointer to pointer to current entry
|
||||
GenericHashEntry **nextBucket; // Next bucket; pointer past end of vector of hash buckets if done
|
||||
public:
|
||||
explicit GenericHashTableIterator(GenericHashTable &ht);
|
||||
~GenericHashTableIterator() {ht.maybeShrink(); DEBUG_ONLY(--ht.nReferences);}
|
||||
|
||||
operator bool() const {return entry != 0;} // Return true if there are entries left.
|
||||
GenericHashTableIterator &operator++();
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Hash Tables
|
||||
//
|
||||
|
||||
template<class Data, class Key, class H = Hash<Key> >
|
||||
class HashTable: private GenericHashTable {
|
||||
H hasher; // Hash function
|
||||
|
||||
struct Entry: public GenericHashEntry {
|
||||
Data data;
|
||||
|
||||
Entry(HashNumber keyHash, Key key): GenericHashEntry(keyHash), data(key) {}
|
||||
template<class Value>
|
||||
Entry(HashNumber keyHash, Key key, Value value): GenericHashEntry(keyHash), data(key, value) {}
|
||||
};
|
||||
|
||||
public:
|
||||
class Reference {
|
||||
#ifdef _WIN32 // Microsoft VC6 bug: friend declarations to inner classes don't work
|
||||
public:
|
||||
#endif
|
||||
Entry *entry; // Current entry; nil if done
|
||||
GenericHashEntry **backpointer; // Pointer to pointer to current entry
|
||||
const HashNumber keyHash; // This entry's key's hash value
|
||||
#ifdef DEBUG
|
||||
GenericHashTable *ht; // Hash table to which this Reference points
|
||||
#endif
|
||||
|
||||
public:
|
||||
#ifndef _WIN32
|
||||
Reference(HashTable &ht, Key key); // Search for an entry with the given key.
|
||||
#else // Microsoft VC6 bug: VC6 doesn't allow this to be defined outside the class
|
||||
Reference(HashTable &ht, Key key): keyHash(ht.hasher(key)) {
|
||||
#ifdef DEBUG
|
||||
Reference::ht = &ht;
|
||||
++ht.nReferences;
|
||||
#endif
|
||||
HashNumber kh = keyHash;
|
||||
HashNumber h = kh*goldenRatio >> ht.shift;
|
||||
GenericHashEntry **bp = ht.buckets + h;
|
||||
Entry *e;
|
||||
|
||||
while ((e = static_cast<Entry *>(*bp)) != 0 && !(e->keyHash == kh && e->data == key))
|
||||
bp = &e->next;
|
||||
entry = e;
|
||||
backpointer = bp;
|
||||
}
|
||||
#endif
|
||||
private:
|
||||
Reference(const Reference&); // No copy constructor
|
||||
void operator=(const Reference&); // No assignment operator
|
||||
public:
|
||||
#if defined(DEBUG) && !defined(_WIN32)
|
||||
~Reference() {if (ht) --ht->nReferences;}
|
||||
#endif
|
||||
|
||||
operator bool() const {return entry != 0;} // Return true if an entry was found.
|
||||
Data &operator*() const {ASSERT(entry); return entry->data;} // Return the data of the entry that was found.
|
||||
|
||||
friend class HashTable;
|
||||
};
|
||||
|
||||
class Iterator: public GenericHashTableIterator {
|
||||
public:
|
||||
explicit Iterator(HashTable &ht): GenericHashTableIterator(ht) {}
|
||||
private:
|
||||
Iterator(const Iterator&); // No copy constructor
|
||||
void operator=(const Iterator&); // No assignment operator
|
||||
public:
|
||||
|
||||
// Go to next entry.
|
||||
Iterator &operator++() {return *static_cast<Iterator*>(&GenericHashTableIterator::operator++());}
|
||||
Data &operator*() const {ASSERT(entry); return static_cast<Entry *>(entry)->data;} // Return current entry's data.
|
||||
void erase();
|
||||
};
|
||||
|
||||
HashTable(uint32 nEntriesDefault = 0, const H &hasher = H()): GenericHashTable(nEntriesDefault), hasher(hasher) {}
|
||||
~HashTable();
|
||||
|
||||
template<class Value> Data &insert(Reference &r, Key key, Value value);
|
||||
Data &insert(Reference &r, Key key);
|
||||
Data &insert(Key key);
|
||||
void erase(Reference &r);
|
||||
void erase(Key key);
|
||||
Data *operator[](Key key);
|
||||
|
||||
friend class Reference;
|
||||
friend class Iterator;
|
||||
|
||||
#ifndef _WIN32
|
||||
template<class Value> Data &insert(Key key, Value value);
|
||||
#else // Microsoft VC6 bug: VC6 doesn't allow this to be defined outside the class
|
||||
template<class Value> Data &insert(Key key, Value value) {
|
||||
Reference r(*this, key);
|
||||
if (r)
|
||||
return *r = value;
|
||||
else
|
||||
return insert(r, key, value);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Implementation
|
||||
//
|
||||
|
||||
template<class Data, class Key, class H>
|
||||
HashTable<Data, Key, H>::~HashTable()
|
||||
{
|
||||
GenericHashEntry **be = bucketsEnd;
|
||||
for (GenericHashEntry **b = buckets; b != be; b++) {
|
||||
Entry *e = static_cast<Entry *>(*b);
|
||||
while (e) {
|
||||
Entry *next = static_cast<Entry *>(e->next);
|
||||
delete e;
|
||||
e = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
template<class Data, class Key, class H>
|
||||
HashTable<Data, Key, H>::Reference::Reference(HashTable &ht, Key key):
|
||||
keyHash(ht.hasher(key))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Reference::ht = &ht;
|
||||
++ht.nReferences;
|
||||
#endif
|
||||
HashNumber kh = keyHash;
|
||||
HashNumber h = kh*goldenRatio >> ht.shift;
|
||||
GenericHashEntry **bp = ht.buckets + h;
|
||||
Entry *e;
|
||||
|
||||
while ((e = static_cast<Entry *>(*bp)) != 0 && !(e->keyHash == kh && e->data == key))
|
||||
bp = &e->next;
|
||||
entry = e;
|
||||
backpointer = bp;
|
||||
}
|
||||
|
||||
|
||||
// Insert the given key/value pair into the hash table. Reference must
|
||||
// be the result of an unsuccessful search for that key in the table.
|
||||
// The reference is not valid after this method is called.
|
||||
// Return a reference to the new entry's value.
|
||||
template<class Data, class Key, class H> template<class Value>
|
||||
inline Data &HashTable<Data, Key, H>::insert(Reference &r, Key key, Value value)
|
||||
{
|
||||
ASSERT(r.ht == this && !r.entry);
|
||||
Entry *e = new Entry(r.keyHash, key, value);
|
||||
*r.backpointer = e;
|
||||
++nEntries;
|
||||
maybeGrow();
|
||||
#ifdef DEBUG
|
||||
--r.ht->nReferences;
|
||||
r.ht = 0;
|
||||
#endif
|
||||
return e->data;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Same as above but without a Value argument.
|
||||
template<class Data, class Key, class H>
|
||||
inline Data &HashTable<Data, Key, H>::insert(Reference &r, Key key)
|
||||
{
|
||||
ASSERT(r.ht == this && !r.entry);
|
||||
Entry *e = new Entry(r.keyHash, key);
|
||||
*r.backpointer = e;
|
||||
++nEntries;
|
||||
maybeGrow();
|
||||
#ifdef DEBUG
|
||||
--r.ht->nReferences;
|
||||
r.ht = 0;
|
||||
#endif
|
||||
return e->data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Insert the given key/value pair into the hash table. If an entry with a
|
||||
// matching key already exists, replace that entry's value.
|
||||
// Return a reference to the new entry's value.
|
||||
#ifndef _WIN32 // Microsoft VC6 bug: VC6 doesn't allow this to be defined outside the class
|
||||
template<class Data, class Key, class H> template<class Value>
|
||||
Data &HashTable<Data, Key, H>::insert(Key key, Value value)
|
||||
{
|
||||
Reference r(*this, key);
|
||||
if (r)
|
||||
return *r = value;
|
||||
else
|
||||
return insert(r, key, value);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Same as above but without a Value argument.
|
||||
template<class Data, class Key, class H>
|
||||
Data &HashTable<Data, Key, H>::insert(Key key)
|
||||
{
|
||||
Reference r(*this, key);
|
||||
if (r)
|
||||
return *r;
|
||||
else
|
||||
return insert(r, key);
|
||||
}
|
||||
|
||||
|
||||
// Reference r must point to an existing entry. Delete that entry.
|
||||
// The reference is not valid after this method is called.
|
||||
template<class Data, class Key, class H>
|
||||
inline void HashTable<Data, Key, H>::erase(Reference &r)
|
||||
{
|
||||
Entry *e = r.entry;
|
||||
ASSERT(r.ht == this && e);
|
||||
*r.backpointer = e->next;
|
||||
--nEntries;
|
||||
delete e;
|
||||
#ifdef DEBUG
|
||||
--r.ht->nReferences;
|
||||
r.ht = 0;
|
||||
#endif
|
||||
maybeShrink();
|
||||
}
|
||||
|
||||
|
||||
// Remove the hash table entry, if any, matching the given key.
|
||||
template<class Data, class Key, class H>
|
||||
void HashTable<Data, Key, H>::erase(Key key)
|
||||
{
|
||||
Reference r(*this, key);
|
||||
if (r)
|
||||
erase(r);
|
||||
}
|
||||
|
||||
|
||||
// Return a pointer to the value of the hash table entry matching the given key.
|
||||
// Return nil if no entry matches.
|
||||
template<class Data, class Key, class H>
|
||||
Data *HashTable<Data, Key, H>::operator[](Key key)
|
||||
{
|
||||
Reference r(*this, key);
|
||||
if (r)
|
||||
return &*r;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,306 +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.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the JavaScript 2 Prototype.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
#ifndef icodegenerator_h
|
||||
#define icodegenerator_h
|
||||
|
||||
#include <vector>
|
||||
#include <stack>
|
||||
|
||||
#include "utilities.h"
|
||||
#include "parser.h"
|
||||
#include "vmtypes.h"
|
||||
#include "jsclasses.h"
|
||||
|
||||
|
||||
namespace JavaScript {
|
||||
namespace ICG {
|
||||
|
||||
using namespace VM;
|
||||
using namespace JSTypes;
|
||||
using namespace JSClasses;
|
||||
|
||||
typedef std::map<String, TypedRegister, std::less<String> > VariableList;
|
||||
typedef std::map<uint32, uint32, std::less<uint32> > InstructionMap;
|
||||
|
||||
|
||||
class ICodeModule {
|
||||
public:
|
||||
ICodeModule(InstructionStream *iCode, VariableList *variables,
|
||||
uint32 maxRegister, uint32 maxParameter,
|
||||
InstructionMap *instructionMap) :
|
||||
its_iCode(iCode), itsVariables(variables),
|
||||
itsParameterCount(maxParameter), itsMaxRegister(maxRegister),
|
||||
mID(++sMaxID), mInstructionMap(instructionMap) { }
|
||||
~ICodeModule()
|
||||
{
|
||||
delete its_iCode;
|
||||
delete itsVariables;
|
||||
delete mInstructionMap;
|
||||
}
|
||||
|
||||
Formatter& print(Formatter& f);
|
||||
void setFileName (String aFileName) { mFileName = aFileName; }
|
||||
String getFileName () { return mFileName; }
|
||||
|
||||
InstructionStream *its_iCode;
|
||||
VariableList *itsVariables;
|
||||
uint32 itsParameterCount;
|
||||
uint32 itsMaxRegister;
|
||||
uint32 mID;
|
||||
InstructionMap *mInstructionMap;
|
||||
String mFileName;
|
||||
|
||||
static uint32 sMaxID;
|
||||
|
||||
};
|
||||
|
||||
typedef std::vector<const StringAtom *> LabelSet;
|
||||
class LabelEntry {
|
||||
public:
|
||||
LabelEntry(LabelSet *labelSet, Label *breakLabel)
|
||||
: labelSet(labelSet), breakLabel(breakLabel), continueLabel(NULL) { }
|
||||
LabelEntry(LabelSet *labelSet, Label *breakLabel, Label *continueLabel)
|
||||
: labelSet(labelSet), breakLabel(breakLabel), continueLabel(continueLabel) { }
|
||||
|
||||
bool containsLabel(const StringAtom *label);
|
||||
|
||||
LabelSet *labelSet;
|
||||
Label *breakLabel;
|
||||
Label *continueLabel;
|
||||
};
|
||||
typedef std::vector<LabelEntry *> LabelStack;
|
||||
|
||||
Formatter& operator<<(Formatter &f, ICodeModule &i);
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
// An ICodeGenerator provides the interface between the parser and the
|
||||
// interpreter. The parser constructs one of these for each
|
||||
// function/script, adds statements and expressions to it and then
|
||||
// converts it into an ICodeModule, ready for execution.
|
||||
|
||||
class ICodeGenerator {
|
||||
public:
|
||||
typedef enum { kNoFlags = 0, kIsTopLevel = 0x01, kIsStaticMethod = 0x02, kIsWithinWith = 0x04 } ICodeGeneratorFlags;
|
||||
private:
|
||||
InstructionStream *iCode;
|
||||
bool iCodeOwner;
|
||||
LabelList labels;
|
||||
|
||||
Register mTopRegister; // highest (currently) alloacated register
|
||||
uint32 mParameterCount; // number of parameters declared for the function
|
||||
// these must come before any variables declared.
|
||||
TypedRegister mExceptionRegister; // reserved to carry the exception object.
|
||||
VariableList *variableList; // name|register pair for each variable
|
||||
|
||||
World *mWorld; // used to register strings
|
||||
JSScope *mGlobal; // the scope for compiling within
|
||||
LabelStack mLabelStack; // stack of LabelEntry objects, one per nested looping construct
|
||||
// maps source position to instruction index
|
||||
InstructionMap *mInstructionMap;
|
||||
|
||||
JSClass *mClass; // enclosing class when generating code for methods
|
||||
ICodeGeneratorFlags mFlags; // assorted flags
|
||||
|
||||
std::vector<bool> mPermanentRegister;
|
||||
|
||||
Register getTempRegister()
|
||||
{
|
||||
while (mTopRegister < mPermanentRegister.size())
|
||||
if (!mPermanentRegister[mTopRegister])
|
||||
return mTopRegister++;
|
||||
else
|
||||
++mTopRegister;
|
||||
mPermanentRegister.resize(mTopRegister + 1);
|
||||
mPermanentRegister[mTopRegister] = false;
|
||||
return mTopRegister++;
|
||||
}
|
||||
|
||||
void resetTopRegister() { mTopRegister = mParameterCount; }
|
||||
void resetStatement() { resetTopRegister(); }
|
||||
|
||||
TypedRegister allocateRegister(const StringAtom& name, JSType *type);
|
||||
|
||||
void setRegisterForVariable(const StringAtom& name, TypedRegister r) { (*variableList)[name] = r; }
|
||||
|
||||
JSType *findType(const StringAtom& typeName);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void setLabel(Label *label);
|
||||
|
||||
void jsr(Label *label) { iCode->push_back(new Jsr(label)); }
|
||||
void rts() { iCode->push_back(new Rts()); }
|
||||
void branch(Label *label);
|
||||
GenericBranch *branchTrue(Label *label, TypedRegister condition);
|
||||
GenericBranch *branchFalse(Label *label, TypedRegister condition);
|
||||
|
||||
void beginTry(Label *catchLabel, Label *finallyLabel)
|
||||
{ iCode->push_back(new Tryin(catchLabel, finallyLabel)); }
|
||||
void endTry() { iCode->push_back(new Tryout()); }
|
||||
|
||||
void beginWith(TypedRegister obj) { iCode->push_back(new Within(obj)); }
|
||||
void endWith() { iCode->push_back(new Without()); }
|
||||
|
||||
|
||||
|
||||
void startStatement(uint32 pos) { (*mInstructionMap)[iCode->size()] = pos; }
|
||||
|
||||
ICodeOp mapExprNodeToICodeOp(ExprNode::Kind kind);
|
||||
|
||||
|
||||
bool isTopLevel() { return (mFlags & kIsTopLevel) != 0; }
|
||||
bool isWithinWith() { return (mFlags & kIsWithinWith) != 0; }
|
||||
bool isStaticMethod() { return (mFlags & kIsStaticMethod) != 0; }
|
||||
|
||||
void setFlag(uint32 flag, bool v) { mFlags = (ICodeGeneratorFlags)((v) ? mFlags | flag : mFlags & ~flag); }
|
||||
|
||||
|
||||
typedef enum {Var, Property, Slot, Static, Constructor, Name, Method} LValueKind;
|
||||
|
||||
LValueKind resolveIdentifier(const StringAtom &name, TypedRegister &v, uint32 &slotIndex);
|
||||
TypedRegister handleIdentifier(IdentifierExprNode *p, ExprNode::Kind use, ICodeOp xcrementOp, TypedRegister ret, RegisterList *args);
|
||||
TypedRegister handleDot(BinaryExprNode *b, ExprNode::Kind use, ICodeOp xcrementOp, TypedRegister ret, RegisterList *args);
|
||||
ICodeModule *genFunction(FunctionStmtNode *f, bool isConstructor, JSClass *superClass);
|
||||
|
||||
public:
|
||||
|
||||
ICodeGenerator(World *world, JSScope *global, JSClass *aClass = NULL, ICodeGeneratorFlags flags = kIsTopLevel);
|
||||
|
||||
~ICodeGenerator()
|
||||
{
|
||||
if (iCodeOwner) {
|
||||
delete iCode;
|
||||
delete mInstructionMap;
|
||||
}
|
||||
}
|
||||
|
||||
ICodeModule *complete();
|
||||
|
||||
TypedRegister genExpr(ExprNode *p,
|
||||
bool needBoolValueInBranch = false,
|
||||
Label *trueBranch = NULL,
|
||||
Label *falseBranch = NULL);
|
||||
TypedRegister genStmt(StmtNode *p, LabelSet *currentLabelSet = NULL);
|
||||
|
||||
void returnStmt(TypedRegister r);
|
||||
void returnStmt();
|
||||
void throwStmt(TypedRegister r) { iCode->push_back(new Throw(r)); }
|
||||
void debuggerStmt() { iCode->push_back(new Debugger()); }
|
||||
|
||||
TypedRegister allocateVariable(const StringAtom& name);
|
||||
TypedRegister allocateVariable(const StringAtom& name, const StringAtom& typeName);
|
||||
|
||||
TypedRegister findVariable(const StringAtom& name)
|
||||
{
|
||||
VariableList::iterator i = variableList->find(name);
|
||||
return (i == variableList->end()) ? TypedRegister(NotARegister, &None_Type) : (*i).second;
|
||||
}
|
||||
|
||||
TypedRegister allocateParameter(const StringAtom& name) { mParameterCount++; return allocateRegister(name, &Any_Type); }
|
||||
TypedRegister allocateParameter(const StringAtom& name, const StringAtom& typeName)
|
||||
{ mParameterCount++; return allocateRegister(name, findType(typeName)); }
|
||||
TypedRegister allocateParameter(const StringAtom& name, JSType *type)
|
||||
{ mParameterCount++; return allocateRegister(name, type); }
|
||||
|
||||
Formatter& print(Formatter& f);
|
||||
|
||||
TypedRegister op(ICodeOp op, TypedRegister source);
|
||||
TypedRegister op(ICodeOp op, TypedRegister source1, TypedRegister source2);
|
||||
TypedRegister binaryOp(ICodeOp op, TypedRegister source1, TypedRegister source2);
|
||||
TypedRegister call(TypedRegister base, TypedRegister target, RegisterList *args);
|
||||
TypedRegister getMethod(TypedRegister thisArg, uint32 slotIndex);
|
||||
|
||||
void move(TypedRegister destination, TypedRegister source);
|
||||
TypedRegister logicalNot(TypedRegister source);
|
||||
TypedRegister test(TypedRegister source);
|
||||
|
||||
TypedRegister loadBoolean(bool value);
|
||||
TypedRegister loadImmediate(double value);
|
||||
TypedRegister loadString(const String &value);
|
||||
TypedRegister loadString(const StringAtom &name);
|
||||
|
||||
TypedRegister newObject(TypedRegister constructor);
|
||||
TypedRegister newArray();
|
||||
TypedRegister newFunction(ICodeModule *icm);
|
||||
TypedRegister newClass(JSClass *clazz);
|
||||
|
||||
TypedRegister cast(TypedRegister arg, JSType *toType);
|
||||
|
||||
TypedRegister super();
|
||||
TypedRegister loadName(const StringAtom &name, JSType *t = &Any_Type);
|
||||
void saveName(const StringAtom &name, TypedRegister value);
|
||||
TypedRegister nameXcr(const StringAtom &name, ICodeOp op);
|
||||
|
||||
TypedRegister deleteProperty(TypedRegister base, const StringAtom &name);
|
||||
TypedRegister getProperty(TypedRegister base, const StringAtom &name);
|
||||
void setProperty(TypedRegister base, const StringAtom &name, TypedRegister value);
|
||||
TypedRegister propertyXcr(TypedRegister base, const StringAtom &name, ICodeOp op);
|
||||
|
||||
TypedRegister getStatic(JSClass *base, const String &name);
|
||||
void setStatic(JSClass *base, const StringAtom &name, TypedRegister value);
|
||||
TypedRegister staticXcr(JSClass *base, const StringAtom &name, ICodeOp op);
|
||||
|
||||
TypedRegister getElement(TypedRegister base, TypedRegister index);
|
||||
void setElement(TypedRegister base, TypedRegister index, TypedRegister value);
|
||||
TypedRegister elementXcr(TypedRegister base, TypedRegister index, ICodeOp op);
|
||||
|
||||
TypedRegister getSlot(TypedRegister base, uint32 slot);
|
||||
void setSlot(TypedRegister base, uint32 slot, TypedRegister value);
|
||||
TypedRegister slotXcr(TypedRegister base, uint32 slot, ICodeOp op);
|
||||
|
||||
TypedRegister varXcr(TypedRegister var, ICodeOp op);
|
||||
|
||||
InstructionStream *getICode() { return iCode; }
|
||||
|
||||
Label *getLabel();
|
||||
|
||||
};
|
||||
|
||||
Formatter& operator<<(Formatter &f, ICodeGenerator &i);
|
||||
Formatter& operator<<(Formatter &f, ICodeModule &i);
|
||||
/*
|
||||
std::ostream &operator<<(std::ostream &s, ICodeGenerator &i);
|
||||
std::ostream &operator<<(std::ostream &s, StringAtom &str);
|
||||
*/
|
||||
|
||||
|
||||
|
||||
} /* namespace IGC */
|
||||
} /* namespace JavaScript */
|
||||
|
||||
#endif /* icodegenerator_h */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,113 +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.1 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of
|
||||
// the License at http://www.mozilla.org/NPL/
|
||||
//
|
||||
// Software distributed under the License is distributed on an "AS
|
||||
// IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
// implied. See the License for the specific language governing
|
||||
// rights and limitations under the License.
|
||||
//
|
||||
// The Original Code is the JavaScript 2 Prototype.
|
||||
//
|
||||
// The Initial Developer of the Original Code is Netscape
|
||||
// Communications Corporation. Portions created by Netscape are
|
||||
// Copyright (C) 2000 Netscape Communications Corporation. All
|
||||
// Rights Reserved.
|
||||
|
||||
#ifndef interpreter_h
|
||||
#define interpreter_h
|
||||
|
||||
#include "utilities.h"
|
||||
#include "jstypes.h"
|
||||
#include "vmtypes.h"
|
||||
#include "icodegenerator.h"
|
||||
#include "gc_allocator.h"
|
||||
|
||||
namespace JavaScript {
|
||||
namespace Interpreter {
|
||||
|
||||
using namespace ICG;
|
||||
using namespace JSTypes;
|
||||
|
||||
struct Activation;
|
||||
|
||||
struct Linkage;
|
||||
|
||||
class Context : public gc_base {
|
||||
void initContext();
|
||||
public:
|
||||
explicit Context(World& world, JSScope* aGlobal)
|
||||
: mWorld(world), mGlobal(aGlobal), mLinkage(0), mActivation(0), mHasOperatorsPackageLoaded(false) { initContext(); }
|
||||
|
||||
World& getWorld() { return mWorld; }
|
||||
JSScope* getGlobalObject() { return mGlobal; }
|
||||
InstructionIterator getPC() { return mPC; }
|
||||
|
||||
JSValues& getRegisters();
|
||||
ICodeModule* getICode();
|
||||
|
||||
enum Event {
|
||||
EV_NONE = 0x0000,
|
||||
EV_STEP = 0x0001,
|
||||
EV_THROW = 0x0002,
|
||||
EV_DEBUG = 0x0004,
|
||||
EV_ALL = 0xffff
|
||||
};
|
||||
|
||||
class Listener {
|
||||
public:
|
||||
virtual void listen(Context *context, Event event) = 0;
|
||||
};
|
||||
|
||||
void addListener(Listener* listener);
|
||||
void removeListener(Listener* listener);
|
||||
|
||||
class Frame {
|
||||
public:
|
||||
virtual Frame* getNext() = 0;
|
||||
virtual void getState(InstructionIterator& pc, JSValues*& registers,
|
||||
ICodeModule*& iCode) = 0;
|
||||
};
|
||||
|
||||
Frame* getFrames();
|
||||
|
||||
JSValue interpret(ICodeModule* iCode, const JSValues& args);
|
||||
void doCall(JSFunction *target, Instruction *pc);
|
||||
|
||||
ICodeModule* compile(const String &source);
|
||||
ICodeModule* genCode(StmtNode *p, const String &fileName);
|
||||
JSValue readEvalFile(FILE* in, const String& fileName);
|
||||
|
||||
void addBinaryOperator(BinaryOperator::BinaryOp op, BinaryOperator *fn) { mBinaryOperators[op].push_back(fn); }
|
||||
const JSValue findBinaryOverride(JSValue &operand1, JSValue &operand2, BinaryOperator::BinaryOp op);
|
||||
|
||||
|
||||
bool hasOperatorsPackageLoaded() { return mHasOperatorsPackageLoaded; }
|
||||
|
||||
private:
|
||||
void broadcast(Event event);
|
||||
void initOperatorsPackage();
|
||||
|
||||
private:
|
||||
World& mWorld;
|
||||
JSScope* mGlobal;
|
||||
Linkage* mLinkage;
|
||||
typedef std::vector<Listener*, gc_allocator<Listener*> > ListenerList;
|
||||
typedef ListenerList::iterator ListenerIterator;
|
||||
ListenerList mListeners;
|
||||
Activation* mActivation;
|
||||
bool mHasOperatorsPackageLoaded;
|
||||
|
||||
InstructionIterator mPC;
|
||||
|
||||
BinaryOperatorList mBinaryOperators[BinaryOperator::BinaryOperatorCount];
|
||||
|
||||
}; /* class Context */
|
||||
|
||||
} /* namespace Interpreter */
|
||||
} /* namespace JavaScript */
|
||||
|
||||
#endif /* interpreter_h */
|
||||
@@ -1,33 +0,0 @@
|
||||
class ArithmeticNode extends BinaryNode {
|
||||
|
||||
ArithmeticNode(String aOp, ExpressionNode aLeft, ExpressionNode aRight)
|
||||
{
|
||||
super(aOp, aLeft, aRight);
|
||||
}
|
||||
|
||||
JSValue eval(Environment theEnv)
|
||||
{
|
||||
JSValue lV = left.eval(theEnv);
|
||||
JSValue rV = right.eval(theEnv);
|
||||
|
||||
if (op == "+")
|
||||
return lV.add(theEnv, rV);
|
||||
else
|
||||
if (op == "-")
|
||||
return lV.subtract(theEnv, rV);
|
||||
else
|
||||
if (op == "*")
|
||||
return lV.multiply(theEnv, rV);
|
||||
else
|
||||
if (op == "/")
|
||||
return lV.divide(theEnv, rV);
|
||||
else
|
||||
if (op == "%")
|
||||
return lV.remainder(theEnv, rV);
|
||||
else {
|
||||
System.out.println("missing arithmetic op " + op);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
class AssignmentNode extends BinaryNode {
|
||||
|
||||
AssignmentNode(String aOp, ExpressionNode aLeft, ExpressionNode aRight)
|
||||
{
|
||||
super(aOp, aLeft, aRight);
|
||||
}
|
||||
|
||||
JSValue eval(Environment theEnv)
|
||||
{
|
||||
JSReference lV = left.evalLHS(theEnv);
|
||||
JSValue rV = right.eval(theEnv);
|
||||
|
||||
return lV.base.putProp(theEnv, lV.id, rV);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
class BinaryNode extends ExpressionNode {
|
||||
|
||||
BinaryNode(String aOp, ExpressionNode aLeft, ExpressionNode aRight)
|
||||
{
|
||||
left = aLeft;
|
||||
right = aRight;
|
||||
op = aOp;
|
||||
}
|
||||
|
||||
JSReference evalLHS(Environment theEnv)
|
||||
{
|
||||
if (op == ".") {
|
||||
JSValue lV = left.eval(theEnv);
|
||||
JSString id;
|
||||
if (right instanceof JSIdentifier)
|
||||
id = (JSString)right;
|
||||
else
|
||||
id = right.eval(theEnv).toJSString(theEnv);
|
||||
return new JSReference(lV, id);
|
||||
}
|
||||
else
|
||||
throw new RuntimeException("bad lValue operator " + op);
|
||||
}
|
||||
|
||||
JSValue eval(Environment theEnv)
|
||||
{
|
||||
JSValue lV = left.eval(theEnv);
|
||||
JSValue rV = right.eval(theEnv);
|
||||
|
||||
if (op == ".")
|
||||
return lV.getProp(theEnv, rV.toJSString(theEnv));
|
||||
else
|
||||
if (op == "()")
|
||||
return lV.call(theEnv, rV);
|
||||
else
|
||||
if (op == ",")
|
||||
return JSValueList.buildList(lV, rV);
|
||||
else {
|
||||
System.out.println("missing binary op " + op);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
String print(String indent)
|
||||
{
|
||||
StringBuffer result = new StringBuffer(indent);
|
||||
result.append(getClass().toString());
|
||||
result.append(" ");
|
||||
result.append(op);
|
||||
result.append("\n");
|
||||
indent += " ";
|
||||
if (left == null) {
|
||||
result.append(indent);
|
||||
result.append("null\n");
|
||||
}
|
||||
else
|
||||
result.append(left.print(indent));
|
||||
if (right == null) {
|
||||
result.append(indent);
|
||||
result.append("null\n");
|
||||
}
|
||||
else
|
||||
result.append(right.print(indent));
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
protected ExpressionNode left;
|
||||
protected ExpressionNode right;
|
||||
protected String op;
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
class BitwiseNode extends BinaryNode {
|
||||
|
||||
BitwiseNode(String aOp, ExpressionNode aLeft, ExpressionNode aRight)
|
||||
{
|
||||
super(aOp, aLeft, aRight);
|
||||
}
|
||||
|
||||
JSValue eval(Environment theEnv)
|
||||
{
|
||||
JSInteger lV = left.eval(theEnv).toJSInteger(theEnv);
|
||||
JSValue rV = right.eval(theEnv);
|
||||
|
||||
if (op == "&")
|
||||
return lV.and(theEnv, rV);
|
||||
else
|
||||
if (op == "|")
|
||||
return lV.or(theEnv, rV);
|
||||
else
|
||||
if (op == "^")
|
||||
return lV.xor(theEnv, rV);
|
||||
else
|
||||
if (op == "<<")
|
||||
return lV.shr(theEnv, rV);
|
||||
else
|
||||
if (op == ">>")
|
||||
return lV.shl(theEnv, rV);
|
||||
else
|
||||
if (op == ">>>")
|
||||
return lV.ushl(theEnv, rV);
|
||||
else {
|
||||
System.out.println("missing bitwise op " + op);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
import java.io.*;
|
||||
|
||||
class Brenda {
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
JSLexer lexer = new JSLexer((args != null) ? new DataInputStream(new FileInputStream(args[0])) : new DataInputStream(System.in));
|
||||
JSParser parser = new JSParser(lexer);
|
||||
ControlNodeGroup tree = new ControlNodeGroup();
|
||||
parser.statements(0, tree);
|
||||
System.out.println(ControlNode.printAll());
|
||||
|
||||
Environment theEnv = new Environment();
|
||||
ControlNode c = tree.getHead();
|
||||
while (c != null) c = c.eval(theEnv);
|
||||
|
||||
System.out.println("After eval :\n" + theEnv.print());
|
||||
|
||||
} catch(Exception e) {
|
||||
System.err.println("exception: "+e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
class ConditionalNode extends ControlNode {
|
||||
|
||||
ConditionalNode(ExpressionNode aCondition)
|
||||
{
|
||||
super(aCondition);
|
||||
}
|
||||
|
||||
ConditionalNode(ExpressionNode aCondition, ControlNode aTrueCode)
|
||||
{
|
||||
super(aCondition);
|
||||
trueCode = aTrueCode;
|
||||
}
|
||||
|
||||
ConditionalNode(ExpressionNode aCondition, ControlNode aTrueCode, ControlNode aFalseCode)
|
||||
{
|
||||
super(aCondition);
|
||||
trueCode = aTrueCode;
|
||||
setNext(aFalseCode);
|
||||
}
|
||||
|
||||
void moveNextToTrue()
|
||||
{
|
||||
trueCode = next;
|
||||
setNext(null);
|
||||
}
|
||||
|
||||
ControlNode eval(Environment theEnv)
|
||||
{
|
||||
JSBoolean b = expr.eval(theEnv).toJSBoolean(theEnv);
|
||||
if (b.isTrue())
|
||||
return trueCode;
|
||||
else
|
||||
return next;
|
||||
}
|
||||
|
||||
String print()
|
||||
{
|
||||
StringBuffer result = new StringBuffer("ConditionalNode ");
|
||||
result.append(index);
|
||||
result.append("\nexpr:\n");
|
||||
if (expr == null)
|
||||
result.append("expr = null\n");
|
||||
else
|
||||
result.append(expr.print(""));
|
||||
result.append("true branch:\n");
|
||||
if (trueCode == null)
|
||||
result.append("true branch = null\n");
|
||||
else
|
||||
result.append("true branch->" + trueCode.index + "\n");
|
||||
result.append("false branch:\n");
|
||||
if (next == null)
|
||||
result.append("false branch = null\n");
|
||||
else
|
||||
result.append("false branch->" + next.index + "\n");
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
protected ControlNode trueCode;
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
class ControlNode {
|
||||
|
||||
private static Vector gList = new Vector();
|
||||
|
||||
static String printAll()
|
||||
{
|
||||
StringBuffer result = new StringBuffer();
|
||||
for (int i = 0; i < gList.size(); i++) {
|
||||
result.append(((ControlNode)(gList.elementAt(i))).print());
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
ControlNode(ExpressionNode anExpr)
|
||||
{
|
||||
expr = anExpr;
|
||||
index = gList.size();
|
||||
gList.addElement(this);
|
||||
}
|
||||
|
||||
ExpressionNode getExpression()
|
||||
{
|
||||
return expr;
|
||||
}
|
||||
|
||||
void setNext(ControlNode aNext)
|
||||
{
|
||||
next = aNext;
|
||||
}
|
||||
|
||||
ControlNode eval(Environment theEnv)
|
||||
{
|
||||
if (expr != null) theEnv.resultValue = expr.eval(theEnv);
|
||||
return next;
|
||||
}
|
||||
|
||||
String print()
|
||||
{
|
||||
StringBuffer result = new StringBuffer(getClass().toString().substring(6));
|
||||
result.append(" #");
|
||||
result.append(index);
|
||||
result.append("\nexpr: \n");
|
||||
if (expr == null)
|
||||
result.append("expr = null\n");
|
||||
else
|
||||
result.append(expr.print(""));
|
||||
result.append("next: ");
|
||||
if (next == null)
|
||||
result.append("next = null\n");
|
||||
else
|
||||
result.append("next->" + next.index + "\n");
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
protected ExpressionNode expr;
|
||||
protected ControlNode next;
|
||||
protected int index;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
class ControlNodeGroup {
|
||||
|
||||
ControlNodeGroup()
|
||||
{
|
||||
}
|
||||
|
||||
ControlNodeGroup(ControlNode aHead)
|
||||
{
|
||||
head = aHead;
|
||||
}
|
||||
|
||||
void add(ControlNodeGroup aGroup)
|
||||
{
|
||||
if (head == null) {
|
||||
head = aGroup.head;
|
||||
}
|
||||
else {
|
||||
fixTails(aGroup.getHead());
|
||||
}
|
||||
addTails(aGroup);
|
||||
}
|
||||
|
||||
void add(ControlNode aNode)
|
||||
{
|
||||
fixTails(aNode);
|
||||
addTail(aNode);
|
||||
if (head == null) head = aNode;
|
||||
}
|
||||
|
||||
void addBreak(ControlNode aNode)
|
||||
{
|
||||
fixTails(aNode);
|
||||
addBreakTail(aNode);
|
||||
if (head == null) head = aNode;
|
||||
}
|
||||
|
||||
void addContinue(ControlNode aNode)
|
||||
{
|
||||
fixTails(aNode);
|
||||
addContinueTail(aNode);
|
||||
if (head == null) head = aNode;
|
||||
}
|
||||
|
||||
void fixTails(ControlNode butt)
|
||||
{
|
||||
int count = tails.size();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
ControlNode aNode = (ControlNode)(tails.elementAt(i));
|
||||
aNode.setNext(butt);
|
||||
}
|
||||
tails.removeAllElements();
|
||||
}
|
||||
|
||||
void fixContinues(ControlNode butt, String label)
|
||||
{
|
||||
int count = continueTails.size();
|
||||
int i = 0;
|
||||
while (i < count) {
|
||||
ControlNode c = (ControlNode)(continueTails.elementAt(i));
|
||||
ExpressionNode e = c.getExpression();
|
||||
String tgt = (e == null) ? null : ((JSIdentifier)e).s;
|
||||
if ((tgt == null) || tgt.equals(label)) {
|
||||
c.setNext(butt);
|
||||
continueTails.removeElementAt(i);
|
||||
count--;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void setHead(ControlNode aHead)
|
||||
{
|
||||
head = aHead;
|
||||
}
|
||||
|
||||
ControlNode getHead()
|
||||
{
|
||||
return head;
|
||||
}
|
||||
|
||||
void addTail(ControlNode aTail)
|
||||
{
|
||||
tails.addElement(aTail);
|
||||
}
|
||||
|
||||
void addBreakTail(ControlNode aTail)
|
||||
{
|
||||
breakTails.addElement(aTail);
|
||||
}
|
||||
|
||||
void addContinueTail(ControlNode aTail)
|
||||
{
|
||||
continueTails.addElement(aTail);
|
||||
}
|
||||
|
||||
void removeTail(ControlNode aTail)
|
||||
{
|
||||
tails.removeElement(aTail);
|
||||
}
|
||||
|
||||
void addTails(ControlNodeGroup aGroup)
|
||||
{
|
||||
int count = aGroup.tails.size();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
tails.addElement(aGroup.tails.elementAt(i));
|
||||
}
|
||||
aGroup.tails.removeAllElements();
|
||||
|
||||
count = aGroup.breakTails.size();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
breakTails.addElement(aGroup.breakTails.elementAt(i));
|
||||
}
|
||||
aGroup.breakTails.removeAllElements();
|
||||
|
||||
count = aGroup.continueTails.size();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
continueTails.addElement(aGroup.continueTails.elementAt(i));
|
||||
}
|
||||
aGroup.continueTails.removeAllElements();
|
||||
}
|
||||
|
||||
void shiftBreakTails(String label)
|
||||
{
|
||||
int count = breakTails.size();
|
||||
int i = 0;
|
||||
while (i < count) {
|
||||
ControlNode c = (ControlNode)(breakTails.elementAt(i));
|
||||
ExpressionNode e = c.getExpression();
|
||||
String tgt = (e == null) ? null : ((JSIdentifier)e).s;
|
||||
if ((tgt == null) || tgt.equals(label)) {
|
||||
tails.addElement(c);
|
||||
breakTails.removeElementAt(i);
|
||||
count--;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
ControlNode head;
|
||||
Vector tails = new Vector();
|
||||
Vector breakTails = new Vector();
|
||||
Vector continueTails = new Vector();
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
class Environment {
|
||||
|
||||
JSScope scope = new JSScope("globals");
|
||||
JSScope globalScope = scope;
|
||||
|
||||
|
||||
void enterNewScope(JSScope newScope)
|
||||
{
|
||||
newScope.parent = scope;
|
||||
scope = newScope;
|
||||
}
|
||||
|
||||
void leaveScope()
|
||||
{
|
||||
scope = scope.parent;
|
||||
}
|
||||
|
||||
String print()
|
||||
{
|
||||
StringBuffer result = new StringBuffer("Globals contents :\n");
|
||||
result.append(scope.toString());
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
JSValue resultValue;
|
||||
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
class ExpressionNode {
|
||||
|
||||
ExpressionNode()
|
||||
{
|
||||
}
|
||||
|
||||
String print(String indent)
|
||||
{
|
||||
return indent + "ExpressionNode(" + getClass().toString() + ")\n";
|
||||
}
|
||||
|
||||
JSReference evalLHS(Environment theEnv)
|
||||
{
|
||||
System.out.println("Unimplemented evalLHS for " + print(""));
|
||||
return null;
|
||||
}
|
||||
|
||||
JSValue eval(Environment theEnv)
|
||||
{
|
||||
System.out.println("Unimplemented eval for " + print(""));
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
class FunctionNode extends ExpressionNode {
|
||||
|
||||
FunctionNode(JSIdentifier aName, ControlNodeGroup aBody, ExpressionNode parameterList)
|
||||
{
|
||||
fn = new NativeFunction(aBody.getHead());
|
||||
name = aName;
|
||||
if (parameterList != null) {
|
||||
if (parameterList instanceof BinaryNode)
|
||||
buildParameterVector((BinaryNode)parameterList);
|
||||
else
|
||||
fn.parameters.addElement(parameterList);
|
||||
}
|
||||
}
|
||||
|
||||
void buildParameterVector(BinaryNode x)
|
||||
{
|
||||
if (x.left instanceof BinaryNode) {
|
||||
buildParameterVector((BinaryNode)(x.left));
|
||||
fn.parameters.addElement(x.right);
|
||||
}
|
||||
else {
|
||||
fn.parameters.addElement(x.left);
|
||||
fn.parameters.addElement(x.right);
|
||||
}
|
||||
}
|
||||
|
||||
JSValue eval(Environment theEnv)
|
||||
{
|
||||
theEnv.scope.putProp(theEnv, name, fn);
|
||||
return fn;
|
||||
}
|
||||
|
||||
JSString name;
|
||||
NativeFunction fn;
|
||||
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
class JSBoolean extends JSValue {
|
||||
|
||||
static JSBoolean JSTrue = new JSBoolean(true);
|
||||
static JSBoolean JSFalse = new JSBoolean(false);
|
||||
|
||||
private JSBoolean(boolean p)
|
||||
{
|
||||
b = p;
|
||||
}
|
||||
|
||||
JSValue eval(Environment theEnv)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
boolean isTrue()
|
||||
{
|
||||
return b;
|
||||
}
|
||||
|
||||
boolean isFalse()
|
||||
{
|
||||
return !b;
|
||||
}
|
||||
|
||||
JSValue bang(Environment theEnv) {
|
||||
return (b) ? JSFalse : JSTrue;
|
||||
}
|
||||
|
||||
JSValue typeof(Environment theEnv) {
|
||||
return new JSString("boolean");
|
||||
}
|
||||
|
||||
JSBoolean toJSBoolean(Environment theEnv) {
|
||||
return this;
|
||||
}
|
||||
|
||||
JSValue toPrimitive(Environment theEnv, String hint) {
|
||||
return this;
|
||||
}
|
||||
|
||||
JSString toJSString(Environment theEnv) {
|
||||
return (b) ? new JSString("true") : new JSString("false");
|
||||
}
|
||||
|
||||
JSDouble toJSDouble(Environment theEnv) {
|
||||
return (b) ? new JSDouble(1) : new JSDouble(0);
|
||||
}
|
||||
|
||||
boolean b;
|
||||
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
class JSDouble extends JSNumber {
|
||||
|
||||
JSDouble(double p)
|
||||
{
|
||||
d = p;
|
||||
}
|
||||
|
||||
JSDouble(String s)
|
||||
{
|
||||
d = new Double(s).doubleValue();
|
||||
}
|
||||
|
||||
String print(String indent)
|
||||
{
|
||||
return indent + "JSDouble " + d + "\n";
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return Double.toString(d);
|
||||
}
|
||||
|
||||
JSValue eval(Environment theEnv)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
JSValue plus(Environment theEnv) {
|
||||
return this;
|
||||
}
|
||||
|
||||
JSValue minus(Environment theEnv) {
|
||||
return new JSDouble(-d);
|
||||
}
|
||||
|
||||
JSValue add(Environment theEnv, JSValue rV) {
|
||||
if (rV instanceof JSString)
|
||||
return toJSString(theEnv).add(theEnv, rV);
|
||||
else
|
||||
return new JSDouble(d + rV.toJSDouble(theEnv).d);
|
||||
}
|
||||
|
||||
JSValue subtract(Environment theEnv, JSValue rV) {
|
||||
return new JSDouble(d - rV.toJSDouble(theEnv).d);
|
||||
}
|
||||
|
||||
JSValue multiply(Environment theEnv, JSValue rV) {
|
||||
return new JSDouble(d * rV.toJSDouble(theEnv).d);
|
||||
}
|
||||
|
||||
JSValue divide(Environment theEnv, JSValue rV) {
|
||||
return new JSDouble(d / rV.toJSDouble(theEnv).d);
|
||||
}
|
||||
|
||||
JSValue remainder(Environment theEnv, JSValue rV) {
|
||||
return new JSDouble(d % rV.toJSDouble(theEnv).d);
|
||||
}
|
||||
|
||||
JSValue gt(Environment theEnv, JSValue rV) {
|
||||
return (d > rV.toJSDouble(theEnv).d) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
|
||||
}
|
||||
|
||||
JSValue ge(Environment theEnv, JSValue rV) {
|
||||
return (d >= rV.toJSDouble(theEnv).d) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
|
||||
}
|
||||
|
||||
JSValue lt(Environment theEnv, JSValue rV) {
|
||||
return (d < rV.toJSDouble(theEnv).d) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
|
||||
}
|
||||
|
||||
JSValue le(Environment theEnv, JSValue rV) {
|
||||
return (d <= rV.toJSDouble(theEnv).d) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
|
||||
}
|
||||
|
||||
JSValue eq(Environment theEnv, JSValue rV) {
|
||||
return (d == rV.toJSDouble(theEnv).d) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
|
||||
}
|
||||
|
||||
JSValue ne(Environment theEnv, JSValue rV) {
|
||||
return (d != rV.toJSDouble(theEnv).d) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
|
||||
}
|
||||
|
||||
JSDouble toJSDouble(Environment theEnv) {
|
||||
return this;
|
||||
}
|
||||
|
||||
JSValue toPrimitive(Environment theEnv, String hint) {
|
||||
return this;
|
||||
}
|
||||
|
||||
JSInteger toJSInteger(Environment theEnv) {
|
||||
return new JSInteger((int)d);
|
||||
}
|
||||
|
||||
JSBoolean toJSBoolean(Environment theEnv) {
|
||||
return ((d == d) && (d != 0.0)) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
|
||||
}
|
||||
|
||||
JSString toJSString(Environment theEnv) {
|
||||
return new JSString(Double.toString(d));
|
||||
}
|
||||
|
||||
JSObject toJSObject(Environment theEnv) {
|
||||
return new NativeNumber(d);
|
||||
}
|
||||
|
||||
|
||||
|
||||
double d;
|
||||
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
|
||||
class JSException extends RuntimeException {
|
||||
|
||||
JSException(JSValue x)
|
||||
{
|
||||
value = x;
|
||||
}
|
||||
|
||||
JSValue getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return value.toJSString(null).s;
|
||||
}
|
||||
|
||||
JSValue value;
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,23 +0,0 @@
|
||||
class JSIdentifier extends JSString {
|
||||
|
||||
JSIdentifier(String s)
|
||||
{
|
||||
super(s);
|
||||
}
|
||||
|
||||
String print(String indent)
|
||||
{
|
||||
return indent + "JSIdentifier : " + s + "\n";
|
||||
}
|
||||
|
||||
JSValue eval(Environment theEnv)
|
||||
{
|
||||
return theEnv.scope.getProp(theEnv, this);
|
||||
}
|
||||
|
||||
JSReference evalLHS(Environment theEnv)
|
||||
{
|
||||
return new JSReference(theEnv.scope, this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
class JSInteger extends JSNumber {
|
||||
|
||||
JSInteger(String s)
|
||||
{
|
||||
i = new Integer(s).intValue();
|
||||
}
|
||||
|
||||
JSInteger(int p)
|
||||
{
|
||||
i = p;
|
||||
}
|
||||
|
||||
JSValue eval(Environment theEnv)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
JSBoolean toJSBoolean(Environment theEnv) {
|
||||
return (i != 0) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
|
||||
}
|
||||
|
||||
JSDouble toJSDouble(Environment theEnv) {
|
||||
return new JSDouble(i);
|
||||
}
|
||||
|
||||
JSInteger toJSInteger(Environment theEnv) {
|
||||
return this;
|
||||
}
|
||||
|
||||
JSValue toPrimitive(Environment theEnv, String hint) {
|
||||
return this;
|
||||
}
|
||||
|
||||
JSString toJSString(Environment theEnv) {
|
||||
return new JSString(Integer.toString(i));
|
||||
}
|
||||
|
||||
JSValue twiddle(Environment theEnv) {
|
||||
return new JSInteger(~i);
|
||||
}
|
||||
|
||||
JSValue and(Environment theEnv, JSValue rV) {
|
||||
return new JSInteger(i & rV.toJSInteger(theEnv).i);
|
||||
}
|
||||
|
||||
JSValue or(Environment theEnv, JSValue rV) {
|
||||
return new JSInteger(i | rV.toJSInteger(theEnv).i);
|
||||
}
|
||||
|
||||
JSValue xor(Environment theEnv, JSValue rV) {
|
||||
return new JSInteger(i ^ rV.toJSInteger(theEnv).i);
|
||||
}
|
||||
|
||||
JSValue shl(Environment theEnv, JSValue rV) {
|
||||
return new JSInteger(i >> rV.toJSInteger(theEnv).i);
|
||||
}
|
||||
|
||||
JSValue shr(Environment theEnv, JSValue rV) {
|
||||
return new JSInteger(i << rV.toJSInteger(theEnv).i);
|
||||
}
|
||||
|
||||
JSValue ushl(Environment theEnv, JSValue rV) {
|
||||
return new JSInteger(i >>> rV.toJSInteger(theEnv).i);
|
||||
}
|
||||
|
||||
int i;
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
class JSName extends ExpressionNode {
|
||||
|
||||
JSName(JSIdentifier anID, int aScope)
|
||||
{
|
||||
id = anID;
|
||||
scope = aScope; // this is the scope that the name was used in
|
||||
}
|
||||
|
||||
String print(String indent)
|
||||
{
|
||||
return indent + "JSName : " + id.s + ", scope : " + scope + "\n";
|
||||
}
|
||||
|
||||
JSReference evalLHS(Environment theEnv)
|
||||
{
|
||||
JSScope scope = theEnv.scope;
|
||||
while (scope != null) {
|
||||
if (scope.hasProp(theEnv, id))
|
||||
return new JSReference(scope, id);
|
||||
else
|
||||
scope = scope.parent;
|
||||
}
|
||||
return new JSReference(theEnv.globalScope, id);
|
||||
}
|
||||
|
||||
JSValue eval(Environment theEnv)
|
||||
{
|
||||
JSScope scope = theEnv.scope;
|
||||
while (scope != null) {
|
||||
if (scope.hasProp(theEnv, id))
|
||||
return scope.getProp(theEnv, id);
|
||||
else
|
||||
scope = scope.parent;
|
||||
}
|
||||
throw new JSException(new JSString(id.s + " undefined"));
|
||||
}
|
||||
|
||||
JSIdentifier id;
|
||||
int scope;
|
||||
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
abstract class JSNumber extends JSValue {
|
||||
|
||||
JSValue typeof(Environment theEnv) {
|
||||
return new JSString("number");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
class JSObject extends JSValue {
|
||||
|
||||
static JSObject objectPrototype = new JSObject("Object");
|
||||
static JSObject JSUndefined = new JSObject("undefined");
|
||||
|
||||
JSObject(String aClass)
|
||||
{
|
||||
oClass = aClass;
|
||||
prototype = objectPrototype;
|
||||
}
|
||||
|
||||
void setPrototype(JSObject aPrototype)
|
||||
{
|
||||
prototype = aPrototype;
|
||||
}
|
||||
|
||||
String print(String indent)
|
||||
{
|
||||
return indent + "JSObject : " + oClass + "\n";
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return oClass + contents.toString();
|
||||
}
|
||||
|
||||
JSValue eval(Environment theEnv)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
JSValue typeof(Environment theEnv) {
|
||||
if (this == JSUndefined)
|
||||
return new JSString("undefined");
|
||||
else
|
||||
return new JSString("object");
|
||||
}
|
||||
|
||||
JSBoolean toJSBoolean(Environment theEnv) {
|
||||
return JSBoolean.JSTrue;
|
||||
}
|
||||
|
||||
JSDouble toJSDouble(Environment theEnv) {
|
||||
return toPrimitive(theEnv, "Number").toJSDouble(theEnv);
|
||||
}
|
||||
|
||||
JSValue getProp(Environment theEnv, JSString id)
|
||||
{
|
||||
Object v = contents.get(id.s);
|
||||
if (v == null)
|
||||
if (prototype == null)
|
||||
return JSUndefined;
|
||||
else
|
||||
return prototype.getProp(theEnv, id);
|
||||
else
|
||||
return (JSValue)v;
|
||||
}
|
||||
|
||||
boolean hasProp(Environment theEnv, JSString id)
|
||||
{
|
||||
Object v = contents.get(id.s);
|
||||
if (v == null)
|
||||
if (prototype == null)
|
||||
return false;
|
||||
else
|
||||
return prototype.hasProp(theEnv, id);
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
JSValue putProp(Environment theEnv, JSString id, JSValue rV) {
|
||||
contents.put(id.s, rV);
|
||||
return rV;
|
||||
}
|
||||
|
||||
|
||||
Hashtable contents = new Hashtable();
|
||||
|
||||
String oClass;
|
||||
|
||||
JSObject prototype;
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
class JSReference {
|
||||
|
||||
JSReference(JSValue aBase, JSString aID)
|
||||
{
|
||||
base = aBase;
|
||||
id = aID;
|
||||
}
|
||||
|
||||
JSValue base;
|
||||
JSString id;
|
||||
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
class JSScope extends JSObject {
|
||||
|
||||
JSScope(String s)
|
||||
{
|
||||
super(s);
|
||||
}
|
||||
|
||||
JSScope parent;
|
||||
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
class JSString extends JSValue {
|
||||
|
||||
JSString(String p)
|
||||
{
|
||||
s = p;
|
||||
}
|
||||
|
||||
JSValue eval(Environment theEnv)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
JSValue typeof(Environment theEnv) {
|
||||
return new JSString("string");
|
||||
}
|
||||
|
||||
JSValue add(Environment theEnv, JSValue rV)
|
||||
{
|
||||
return new JSString(s + rV.toJSString(theEnv).s);
|
||||
}
|
||||
|
||||
JSValue gt(Environment theEnv, JSValue rV) {
|
||||
if (rV instanceof JSString)
|
||||
return (s.compareTo(rV.toJSString(theEnv).s) == 1) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
|
||||
else
|
||||
return toJSDouble(theEnv).gt(theEnv, rV);
|
||||
}
|
||||
|
||||
JSValue ge(Environment theEnv, JSValue rV) {
|
||||
if (rV instanceof JSString)
|
||||
return (s.compareTo(rV.toJSString(theEnv).s) != -1) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
|
||||
else
|
||||
return toJSDouble(theEnv).ge(theEnv, rV);
|
||||
}
|
||||
|
||||
JSValue lt(Environment theEnv, JSValue rV) {
|
||||
if (rV instanceof JSString)
|
||||
return (s.compareTo(rV.toJSString(theEnv).s) == -1) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
|
||||
else
|
||||
return toJSDouble(theEnv).lt(theEnv, rV);
|
||||
}
|
||||
|
||||
JSValue le(Environment theEnv, JSValue rV) {
|
||||
if (rV instanceof JSString)
|
||||
return (s.compareTo(rV.toJSString(theEnv).s) != 1) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
|
||||
else
|
||||
return toJSDouble(theEnv).le(theEnv, rV);
|
||||
}
|
||||
|
||||
JSValue eq(Environment theEnv, JSValue rV) {
|
||||
if (rV instanceof JSString)
|
||||
return (s.compareTo(rV.toJSString(theEnv).s) == 0) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
|
||||
else
|
||||
return toJSDouble(theEnv).eq(theEnv, rV);
|
||||
}
|
||||
|
||||
JSValue ne(Environment theEnv, JSValue rV) {
|
||||
if (rV instanceof JSString)
|
||||
return (s.compareTo(rV.toJSString(theEnv).s) != 0) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
|
||||
else
|
||||
return toJSDouble(theEnv).ne(theEnv, rV);
|
||||
}
|
||||
|
||||
JSDouble toJSDouble(Environment theEnv) {
|
||||
return new JSDouble(s); // XXX Way More To Do, see Rhino ScriptRuntime.java
|
||||
}
|
||||
|
||||
JSString toJSString(Environment theEnv) {
|
||||
return this;
|
||||
}
|
||||
|
||||
JSValue toPrimitive(Environment theEnv, String hint) {
|
||||
return this;
|
||||
}
|
||||
|
||||
String print(String indent)
|
||||
{
|
||||
return indent + "JSString : " + s + "\n";
|
||||
}
|
||||
|
||||
protected String s;
|
||||
|
||||
}
|
||||
@@ -1,222 +0,0 @@
|
||||
class JSValue extends ExpressionNode {
|
||||
|
||||
String print(String indent)
|
||||
{
|
||||
return indent + "JSValue\n";
|
||||
}
|
||||
|
||||
JSReference evalLHS(Environment theEnv)
|
||||
{
|
||||
throw new RuntimeException("EvalLHS on non-lvalue");
|
||||
}
|
||||
|
||||
JSValue eval(Environment theEnv)
|
||||
{
|
||||
throw new RuntimeException("Eval on JSValue");
|
||||
}
|
||||
|
||||
JSValue unimplemented(String op)
|
||||
{
|
||||
throw new RuntimeException("unimplemented " + op + " called");
|
||||
}
|
||||
|
||||
JSValue gt(Environment theEnv, JSValue rV) {
|
||||
JSValue lV = toPrimitive(theEnv, "Number");
|
||||
rV = rV.toPrimitive(theEnv, "Number");
|
||||
if ((lV instanceof JSString) && (rV instanceof JSString))
|
||||
return lV.gt(theEnv, rV);
|
||||
else
|
||||
return lV.toJSDouble(theEnv).gt(theEnv, rV.toJSDouble(theEnv));
|
||||
}
|
||||
|
||||
JSValue ge(Environment theEnv, JSValue rV) {
|
||||
JSValue lV = toPrimitive(theEnv, "Number");
|
||||
rV = rV.toPrimitive(theEnv, "Number");
|
||||
if ((lV instanceof JSString) && (rV instanceof JSString))
|
||||
return lV.ge(theEnv, rV);
|
||||
else
|
||||
return lV.toJSDouble(theEnv).ge(theEnv, rV.toJSDouble(theEnv));
|
||||
}
|
||||
|
||||
JSValue lt(Environment theEnv, JSValue rV) {
|
||||
JSValue lV = toPrimitive(theEnv, "Number");
|
||||
rV = rV.toPrimitive(theEnv, "Number");
|
||||
if ((lV instanceof JSString) && (rV instanceof JSString))
|
||||
return lV.lt(theEnv, rV);
|
||||
else
|
||||
return lV.toJSDouble(theEnv).lt(theEnv, rV.toJSDouble(theEnv));
|
||||
}
|
||||
|
||||
JSValue le(Environment theEnv, JSValue rV) {
|
||||
JSValue lV = toPrimitive(theEnv, "Number");
|
||||
rV = rV.toPrimitive(theEnv, "Number");
|
||||
if ((lV instanceof JSString) && (rV instanceof JSString))
|
||||
return lV.le(theEnv, rV);
|
||||
else
|
||||
return lV.toJSDouble(theEnv).le(theEnv, rV.toJSDouble(theEnv));
|
||||
}
|
||||
|
||||
JSValue eq(Environment theEnv, JSValue rV) {
|
||||
JSValue lV = toPrimitive(theEnv, "Number");
|
||||
rV = rV.toPrimitive(theEnv, "Number");
|
||||
if ((lV instanceof JSString) && (rV instanceof JSString))
|
||||
return lV.eq(theEnv, rV);
|
||||
else
|
||||
return lV.toJSDouble(theEnv).eq(theEnv, rV.toJSDouble(theEnv));
|
||||
}
|
||||
|
||||
JSValue ne(Environment theEnv, JSValue rV) {
|
||||
JSValue lV = toPrimitive(theEnv, "Number");
|
||||
rV = rV.toPrimitive(theEnv, "Number");
|
||||
if ((lV instanceof JSString) && (rV instanceof JSString))
|
||||
return lV.ne(theEnv, rV);
|
||||
else
|
||||
return lV.toJSDouble(theEnv).ne(theEnv, rV.toJSDouble(theEnv));
|
||||
}
|
||||
|
||||
JSValue plus(Environment theEnv) {
|
||||
return toJSDouble(theEnv).plus(theEnv);
|
||||
}
|
||||
|
||||
JSValue minus(Environment theEnv) {
|
||||
return toJSDouble(theEnv).minus(theEnv);
|
||||
}
|
||||
|
||||
JSValue twiddle(Environment theEnv) {
|
||||
return toJSInteger(theEnv).twiddle(theEnv);
|
||||
}
|
||||
|
||||
JSValue bang(Environment theEnv) {
|
||||
return toJSBoolean(theEnv).bang(theEnv);
|
||||
}
|
||||
|
||||
JSValue typeof(Environment theEnv) {
|
||||
return unimplemented("typeof");
|
||||
}
|
||||
|
||||
JSValue add(Environment theEnv, JSValue rV) {
|
||||
JSValue lV = toPrimitive(theEnv, "");
|
||||
rV = rV.toPrimitive(theEnv, "");
|
||||
if ((lV instanceof JSString) || (rV instanceof JSString))
|
||||
return lV.add(theEnv, rV);
|
||||
else
|
||||
return lV.toJSDouble(theEnv).add(theEnv, rV);
|
||||
}
|
||||
|
||||
JSValue subtract(Environment theEnv, JSValue rV) {
|
||||
return toJSDouble(theEnv).subtract(theEnv, rV.toJSDouble(theEnv));
|
||||
}
|
||||
|
||||
JSValue multiply(Environment theEnv, JSValue rV) {
|
||||
return toJSDouble(theEnv).multiply(theEnv, rV.toJSDouble(theEnv));
|
||||
}
|
||||
|
||||
JSValue divide(Environment theEnv, JSValue rV) {
|
||||
return toJSDouble(theEnv).divide(theEnv, rV.toJSDouble(theEnv));
|
||||
}
|
||||
|
||||
JSValue remainder(Environment theEnv, JSValue rV) {
|
||||
return toJSDouble(theEnv).remainder(theEnv, rV.toJSDouble(theEnv));
|
||||
}
|
||||
|
||||
JSValue and(Environment theEnv, JSValue rV) {
|
||||
return toJSInteger(theEnv).and(theEnv, rV.toJSInteger(theEnv));
|
||||
}
|
||||
|
||||
JSValue or(Environment theEnv, JSValue rV) {
|
||||
return toJSInteger(theEnv).or(theEnv, rV.toJSInteger(theEnv));
|
||||
}
|
||||
|
||||
JSValue xor(Environment theEnv, JSValue rV) {
|
||||
return toJSInteger(theEnv).xor(theEnv, rV.toJSInteger(theEnv));
|
||||
}
|
||||
|
||||
JSValue shl(Environment theEnv, JSValue rV) {
|
||||
return toJSInteger(theEnv).shl(theEnv, rV.toJSInteger(theEnv));
|
||||
}
|
||||
|
||||
JSValue shr(Environment theEnv, JSValue rV) {
|
||||
return toJSInteger(theEnv).shr(theEnv, rV.toJSInteger(theEnv));
|
||||
}
|
||||
|
||||
JSValue ushl(Environment theEnv, JSValue rV) {
|
||||
return toJSInteger(theEnv).ushl(theEnv, rV.toJSInteger(theEnv));
|
||||
}
|
||||
|
||||
JSValue getProp(Environment theEnv, JSString id) {
|
||||
return toJSObject(theEnv).getProp(theEnv, id);
|
||||
}
|
||||
|
||||
boolean hasProp(Environment theEnv, JSString id) {
|
||||
return toJSObject(theEnv).hasProp(theEnv, id);
|
||||
}
|
||||
|
||||
JSValue putProp(Environment theEnv, JSString id, JSValue rV) {
|
||||
return toJSObject(theEnv).putProp(theEnv, id, rV);
|
||||
}
|
||||
|
||||
JSValue call(Environment theEnv, JSValue rV) {
|
||||
throw new JSException(new JSString("[[call]] not implemented"));
|
||||
}
|
||||
|
||||
JSValue defaultValue(Environment theEnv, String hint) {
|
||||
/*
|
||||
When the [[DefaultValue]] method of O is called with hint String, the following steps are taken:
|
||||
1. Call the [[Get]] method of object O with argument "toString".
|
||||
2. If Result(1) is not an object, go to step 5.
|
||||
3. Call the [[Call]] method of Result(1), with O as the this value and an empty argument list.
|
||||
4. If Result(3) is a primitive value, return Result(3).
|
||||
5. Call the [[Get]] method of object O with argument "valueOf".
|
||||
6. If Result(5) is not an object, go to step 9.
|
||||
7. Call the [[Call]] method of Result(5), with O as the this value and an empty argument list.
|
||||
8. If Result(7) is a primitive value, return Result(7).
|
||||
9. Generate a runtime error.
|
||||
*/
|
||||
JSValue v = null;
|
||||
if (hint.equals("String")) {
|
||||
v = getProp(theEnv, new JSString("toString"));
|
||||
if (v instanceof JSObject) {
|
||||
// invoke 'v.Call' with 'this' as the JS this
|
||||
}
|
||||
else {
|
||||
v = getProp(theEnv, new JSString("valueOf"));
|
||||
if (v instanceof JSObject) {
|
||||
}
|
||||
else
|
||||
throw new JSException(new JSString("No default value"));
|
||||
}
|
||||
}
|
||||
else { // hint.equals("Number")
|
||||
/*
|
||||
When the [[DefaultValue]] method of O is called with hint Number, the following steps are taken:
|
||||
1. Call the [[Get]] method of object O with argument "valueOf".
|
||||
2. If Result(1) is not an object, go to step 5.
|
||||
3. Call the [[Call]] method of Result(1), with O as the this value and an empty argument list.
|
||||
4. If Result(3) is a primitive value, return Result(3).
|
||||
5. Call the [[Get]] method of object O with argument "toString".
|
||||
6. If Result(5) is not an object, go to step 9.
|
||||
7. Call the [[Call]] method of Result(5), with O as the this value and an empty argument list.
|
||||
8. If Result(7) is a primitive value, return Result(7).
|
||||
9. Generate a runtime error.
|
||||
*/
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
JSValue toPrimitive(Environment theEnv, String hint) {
|
||||
JSValue result = defaultValue(theEnv, hint);
|
||||
if (result instanceof JSObject)
|
||||
throw new JSException(new JSString("default value returned object"));
|
||||
else
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
JSObject toJSObject(Environment theEnv) { unimplemented("toJSObjet"); return null; }
|
||||
JSDouble toJSDouble(Environment theEnv) { unimplemented("toJSDouble"); return null; }
|
||||
JSInteger toJSInteger(Environment theEnv) { unimplemented("toJSInteger"); return null; }
|
||||
JSString toJSString(Environment theEnv) { unimplemented("toJSString"); return null; }
|
||||
JSBoolean toJSBoolean(Environment theEnv) { unimplemented("toJSBoolean"); return null; }
|
||||
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
class JSValueList extends JSValue {
|
||||
|
||||
static JSValueList buildList(JSValue left, JSValue right)
|
||||
{
|
||||
JSValueList theList;
|
||||
if (left instanceof JSValueList) {
|
||||
theList = (JSValueList)left;
|
||||
theList.add(right);
|
||||
}
|
||||
else
|
||||
if (right instanceof JSValueList) {
|
||||
theList = (JSValueList)right;
|
||||
theList.add(left);
|
||||
}
|
||||
else {
|
||||
theList = new JSValueList();
|
||||
theList.add(left);
|
||||
theList.add(right);
|
||||
}
|
||||
|
||||
return theList;
|
||||
}
|
||||
|
||||
void add(JSValue v)
|
||||
{
|
||||
if (v instanceof JSValueList) {
|
||||
JSValueList vl = (JSValueList)v;
|
||||
for (int i = 0; i < vl.contents.size(); i++)
|
||||
contents.addElement((JSValue)(vl.contents.elementAt(i)));
|
||||
}
|
||||
else
|
||||
contents.addElement(v);
|
||||
}
|
||||
|
||||
Vector contents = new Vector();
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
class LogicalNode extends BinaryNode {
|
||||
|
||||
LogicalNode(String aOp, ExpressionNode aLeft, ExpressionNode aRight)
|
||||
{
|
||||
super(aOp, aLeft, aRight);
|
||||
}
|
||||
|
||||
JSValue eval(Environment theEnv)
|
||||
{
|
||||
JSBoolean b = left.eval(theEnv).toJSBoolean(theEnv);
|
||||
if (op == "&&") {
|
||||
if (b.isFalse())
|
||||
return b;
|
||||
else {
|
||||
b = right.eval(theEnv).toJSBoolean(theEnv);
|
||||
if (b.isFalse())
|
||||
return b;
|
||||
else
|
||||
return JSBoolean.JSTrue;
|
||||
}
|
||||
}
|
||||
if (op == "||") {
|
||||
if (b.isTrue())
|
||||
return b;
|
||||
else {
|
||||
b = right.eval(theEnv).toJSBoolean(theEnv);
|
||||
if (b.isTrue())
|
||||
return b;
|
||||
else
|
||||
return JSBoolean.JSFalse;
|
||||
}
|
||||
}
|
||||
else {
|
||||
System.out.println("missing logical op " + op);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
class NativeFunction extends JSObject {
|
||||
|
||||
NativeFunction(ControlNode aBody)
|
||||
{
|
||||
super("Function");
|
||||
body = aBody;
|
||||
}
|
||||
|
||||
JSValue call(Environment theEnv, JSValue rV)
|
||||
{
|
||||
|
||||
JSScope args = new JSScope("Arguments");
|
||||
theEnv.enterNewScope(args);
|
||||
|
||||
for (int i = 0; i < parameters.size(); i++) {
|
||||
if (rV instanceof JSValueList)
|
||||
args.putProp(theEnv, (JSString)(parameters.elementAt(i)), (JSValue) ( ((JSValueList)rV).contents.elementAt(i)) );
|
||||
else
|
||||
args.putProp(theEnv, (JSString)(parameters.elementAt(i)), rV );
|
||||
}
|
||||
|
||||
ControlNode c = body;
|
||||
while (c != null) c = c.eval(theEnv);
|
||||
|
||||
theEnv.leaveScope();
|
||||
return theEnv.resultValue;
|
||||
}
|
||||
|
||||
ControlNode body;
|
||||
Vector parameters = new Vector();
|
||||
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
class NativeNumber extends JSObject {
|
||||
|
||||
NativeNumber(double p) {
|
||||
super("Number");
|
||||
d = p;
|
||||
}
|
||||
|
||||
JSValue defaultValue(Environment theEnv, String hint) {
|
||||
if (hint.equals("String"))
|
||||
return new JSString(Double.toString(d));
|
||||
else
|
||||
return new JSDouble(d);
|
||||
}
|
||||
|
||||
double d;
|
||||
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
class RelationalNode extends BinaryNode {
|
||||
|
||||
RelationalNode(String aOp, ExpressionNode aLeft, ExpressionNode aRight)
|
||||
{
|
||||
super(aOp, aLeft, aRight);
|
||||
}
|
||||
|
||||
JSValue eval(Environment theEnv)
|
||||
{
|
||||
JSValue lV = left.eval(theEnv);
|
||||
JSValue rV = right.eval(theEnv);
|
||||
|
||||
if (op == ">")
|
||||
return lV.gt(theEnv, rV);
|
||||
else
|
||||
if (op == ">=")
|
||||
return lV.ge(theEnv, rV);
|
||||
else
|
||||
if (op == "<")
|
||||
return lV.lt(theEnv, rV);
|
||||
else
|
||||
if (op == "<=")
|
||||
return lV.le(theEnv, rV);
|
||||
else
|
||||
if (op == "==")
|
||||
return lV.eq(theEnv, rV);
|
||||
else
|
||||
if (op == "!=")
|
||||
return lV.ne(theEnv, rV);
|
||||
else {
|
||||
System.out.println("missing relational op");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
class SwitchNode extends ControlNode {
|
||||
|
||||
|
||||
SwitchNode(ExpressionNode e)
|
||||
{
|
||||
super(e);
|
||||
}
|
||||
|
||||
void addCase(ExpressionNode e, ControlNode c)
|
||||
{
|
||||
if (e == null)
|
||||
defaultCode = c;
|
||||
else {
|
||||
caseExpr.addElement(e);
|
||||
caseCode.addElement(c);
|
||||
}
|
||||
}
|
||||
|
||||
ControlNode eval(Environment theEnv)
|
||||
{
|
||||
JSValue v = expr.eval(theEnv);
|
||||
int count = caseExpr.size();
|
||||
for (int i = 0; i < count; i++) {
|
||||
ExpressionNode e = (ExpressionNode)(caseExpr.elementAt(i));
|
||||
JSBoolean b = v.eq(theEnv, e.eval(theEnv)).toJSBoolean(theEnv);
|
||||
if (b.isTrue())
|
||||
return (ControlNode)(caseCode.elementAt(i));
|
||||
}
|
||||
if (defaultCode != null)
|
||||
return defaultCode;
|
||||
else
|
||||
return next;
|
||||
}
|
||||
|
||||
Vector caseExpr = new Vector();
|
||||
Vector caseCode = new Vector();
|
||||
|
||||
ControlNode defaultCode;
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
class ThrowNode extends ControlNode {
|
||||
|
||||
ThrowNode(ExpressionNode e)
|
||||
{
|
||||
super(e);
|
||||
}
|
||||
|
||||
ControlNode eval(Environment theEnv)
|
||||
{
|
||||
throw new JSException(expr.eval(theEnv));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
class TryNode extends ControlNode {
|
||||
|
||||
TryNode(ControlNode tryCode)
|
||||
{
|
||||
super(null);
|
||||
tryBody = tryCode;
|
||||
}
|
||||
|
||||
void addFinally(ControlNode finallyCode)
|
||||
{
|
||||
finallyBody = finallyCode;
|
||||
}
|
||||
|
||||
void addCatchClause(ExpressionNode e, ControlNode c)
|
||||
{
|
||||
catchExpr.addElement(e);
|
||||
catchCode.addElement(c);
|
||||
}
|
||||
|
||||
ControlNode eval(Environment theEnv)
|
||||
{
|
||||
try {
|
||||
ControlNode c = tryBody;
|
||||
while (c != null) c = c.eval(theEnv);
|
||||
}
|
||||
catch (JSException x) {
|
||||
int count = catchExpr.size();
|
||||
for (int i = 0; i < count; i++) {
|
||||
ExpressionNode e = (ExpressionNode)(catchExpr.elementAt(i));
|
||||
String id = ((JSObject)e).oClass;
|
||||
theEnv.scope.contents.put(id, x.getValue()); // XXX YAARGH !!!
|
||||
return (ControlNode)(catchCode.elementAt(i));
|
||||
}
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
Vector catchExpr = new Vector();
|
||||
Vector catchCode = new Vector();
|
||||
|
||||
ControlNode tryBody;
|
||||
ControlNode finallyBody;
|
||||
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
class UnaryNode extends ExpressionNode {
|
||||
|
||||
UnaryNode(String aOp, ExpressionNode aChild)
|
||||
{
|
||||
child = aChild;
|
||||
op = aOp;
|
||||
}
|
||||
|
||||
String print(String indent)
|
||||
{
|
||||
StringBuffer result = new StringBuffer(indent);
|
||||
result.append("UnaryNode ");
|
||||
result.append(op);
|
||||
result.append("\n");
|
||||
indent += " ";
|
||||
if (child == null) {
|
||||
result.append(indent);
|
||||
result.append("null\n");
|
||||
}
|
||||
else
|
||||
result.append(child.print(indent));
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
JSValue eval(Environment theEnv)
|
||||
{
|
||||
JSValue cV = child.eval(theEnv);
|
||||
|
||||
if (op == "+")
|
||||
return cV.plus(theEnv);
|
||||
else
|
||||
if (op == "-")
|
||||
return cV.minus(theEnv);
|
||||
else
|
||||
if (op == "~")
|
||||
return cV.twiddle(theEnv);
|
||||
else
|
||||
if (op == "!")
|
||||
return cV.bang(theEnv);
|
||||
else
|
||||
if (op == "typeof")
|
||||
return cV.typeof(theEnv);
|
||||
else {
|
||||
System.out.println("missing unary op " + op);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
String getOperator()
|
||||
{
|
||||
return op;
|
||||
}
|
||||
|
||||
ExpressionNode getChild()
|
||||
{
|
||||
return child;
|
||||
}
|
||||
|
||||
protected ExpressionNode child;
|
||||
protected String op;
|
||||
|
||||
}
|
||||
@@ -1,343 +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.1 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of
|
||||
// the License at http://www.mozilla.org/NPL/
|
||||
//
|
||||
// Software distributed under the License is distributed on an "AS
|
||||
// IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
// implied. See the License for the specific language governing
|
||||
// rights and limitations under the License.
|
||||
//
|
||||
// The Original Code is the JavaScript 2 Prototype.
|
||||
//
|
||||
// The Initial Developer of the Original Code is Netscape
|
||||
// Communications Corporation. Portions created by Netscape are
|
||||
// Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
// Rights Reserved.
|
||||
|
||||
|
||||
//
|
||||
// JS2 shell.
|
||||
//
|
||||
|
||||
#if 1
|
||||
#define DEBUGGER_FOO
|
||||
#define INTERPRET_INPUT
|
||||
#else
|
||||
#undef DEBUGGER_FOO
|
||||
#undef INTERPRET_INPUT
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "world.h"
|
||||
#include "interpreter.h"
|
||||
#include "icodegenerator.h"
|
||||
|
||||
#ifdef DEBUGGER_FOO
|
||||
#include "debugger.h"
|
||||
#endif
|
||||
|
||||
#if defined(XP_MAC) && !defined(XP_MAC_MPW)
|
||||
#include <SIOUX.h>
|
||||
#include <MacTypes.h>
|
||||
|
||||
static char *mac_argv[] = {"js2", 0};
|
||||
|
||||
static void initConsole(StringPtr consoleName,
|
||||
const char* startupMessage,
|
||||
int &argc, char **&argv)
|
||||
{
|
||||
SIOUXSettings.autocloseonquit = false;
|
||||
SIOUXSettings.asktosaveonclose = false;
|
||||
SIOUXSetTitle(consoleName);
|
||||
|
||||
// Set up a buffer for stderr (otherwise it's a pig).
|
||||
static char buffer[BUFSIZ];
|
||||
setvbuf(stderr, buffer, _IOLBF, BUFSIZ);
|
||||
|
||||
JavaScript::stdOut << startupMessage;
|
||||
|
||||
argc = 1;
|
||||
argv = mac_argv;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace JavaScript {
|
||||
namespace Shell {
|
||||
|
||||
using namespace ICG;
|
||||
using namespace JSTypes;
|
||||
using namespace Interpreter;
|
||||
|
||||
// Interactively read a line from the input stream in and put it into
|
||||
// s. Return false if reached the end of input before reading anything.
|
||||
static bool promptLine(LineReader &inReader, string &s, const char *prompt)
|
||||
{
|
||||
if (prompt) {
|
||||
stdOut << prompt;
|
||||
#ifdef XP_MAC_MPW
|
||||
// Print a CR after the prompt because MPW grabs the entire
|
||||
// line when entering an interactive command.
|
||||
stdOut << '\n';
|
||||
#endif
|
||||
}
|
||||
return inReader.readLine(s) != 0;
|
||||
}
|
||||
|
||||
World world;
|
||||
|
||||
/* "filename" of the console */
|
||||
const String ConsoleName = widenCString("<console>");
|
||||
const bool showTokens = false;
|
||||
|
||||
#ifdef DEBUGGER_FOO
|
||||
Reader *sourceReader; /* Reader for console file */
|
||||
|
||||
static
|
||||
const Reader *ResolveFile (const String& fileName)
|
||||
{
|
||||
if (fileName == ConsoleName)
|
||||
return sourceReader;
|
||||
else
|
||||
{
|
||||
stdErr << "Could not locate source for file '" << fileName << "'\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
JavaScript::Debugger::Shell jsd(world, stdin, JavaScript::stdOut,
|
||||
JavaScript::stdOut, &ResolveFile);
|
||||
#endif
|
||||
|
||||
static JSValue print(Context *cx, const JSValues &argv)
|
||||
{
|
||||
size_t n = argv.size();
|
||||
if (n > 1) { // the 'this' parameter is un-interesting
|
||||
stdOut << argv[1];
|
||||
for (size_t i = 2; i < n; ++i)
|
||||
stdOut << ' ' << argv[i];
|
||||
}
|
||||
stdOut << "\n";
|
||||
return kUndefinedValue;
|
||||
}
|
||||
|
||||
static JSValue dump(Context *cx, const JSValues &argv)
|
||||
{
|
||||
size_t n = argv.size();
|
||||
if (n > 1) { // the 'this' parameter is un-interesting
|
||||
if (argv[1].isFunction()) {
|
||||
JSFunction *f = static_cast<JSFunction *>(argv[1].function);
|
||||
if (f->isNative())
|
||||
stdOut << "Native function";
|
||||
else
|
||||
stdOut << *f->getICode();
|
||||
}
|
||||
else
|
||||
stdOut << "Not a function";
|
||||
}
|
||||
stdOut << "\n";
|
||||
return kUndefinedValue;
|
||||
}
|
||||
|
||||
|
||||
inline char narrow(char16 ch) { return char(ch); }
|
||||
|
||||
static JSValue load(Context *cx, const JSValues &argv)
|
||||
{
|
||||
|
||||
JSValue result;
|
||||
size_t n = argv.size();
|
||||
if (n > 1) {
|
||||
for (size_t i = 1; i < n; ++i) {
|
||||
JSValue val = argv[i].toString();
|
||||
if (val.isString()) {
|
||||
String fileName(*val.string);
|
||||
std::string str(fileName.length(), char());
|
||||
std::transform(fileName.begin(), fileName.end(), str.begin(), narrow);
|
||||
FILE* f = fopen(str.c_str(), "r");
|
||||
if (f) {
|
||||
result = cx->readEvalFile(f, fileName);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#if 0 // need a XP version of this, rip off from Monkey?
|
||||
#include <sys/timeb.h>
|
||||
static JSValue time(Context *cx, const JSValues &argv)
|
||||
{
|
||||
struct _timeb timebuffer;
|
||||
_ftime(&timebuffer);
|
||||
|
||||
return JSValue((double)timebuffer.time * 1000 + timebuffer.millitm);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void readEvalPrint(FILE *in, World &world)
|
||||
{
|
||||
JSScope global;
|
||||
Context cx(world, &global);
|
||||
#ifdef DEBUGGER_FOO
|
||||
jsd.attachToContext (&cx);
|
||||
#endif
|
||||
global.defineNativeFunction(world.identifiers["print"], print);
|
||||
global.defineNativeFunction(world.identifiers["dump"], dump);
|
||||
global.defineNativeFunction(world.identifiers["load"], load);
|
||||
// global.defineNativeFunction(world.identifiers["time"], time);
|
||||
|
||||
String buffer;
|
||||
string line;
|
||||
LineReader inReader(in);
|
||||
|
||||
while (promptLine(inReader, line, buffer.empty() ? "js> " : "> ")) {
|
||||
appendChars(buffer, line.data(), line.size());
|
||||
try {
|
||||
Arena a;
|
||||
Parser p(world, a, buffer, ConsoleName);
|
||||
|
||||
if (showTokens) {
|
||||
Lexer &l = p.lexer;
|
||||
while (true) {
|
||||
const Token &t = l.get(true);
|
||||
if (t.hasKind(Token::end))
|
||||
break;
|
||||
stdOut << ' ';
|
||||
t.print(stdOut, true);
|
||||
}
|
||||
stdOut << '\n';
|
||||
} else {
|
||||
StmtNode *parsedStatements = p.parseProgram();
|
||||
ASSERT(p.lexer.peek(true).hasKind(Token::end));
|
||||
{
|
||||
PrettyPrinter f(stdOut, 30);
|
||||
{
|
||||
PrettyPrinter::Block b(f, 2);
|
||||
f << "Program =";
|
||||
f.linearBreak(1);
|
||||
StmtNode::printStatements(f, parsedStatements);
|
||||
}
|
||||
f.end();
|
||||
}
|
||||
stdOut << '\n';
|
||||
#ifdef INTERPRET_INPUT
|
||||
#ifdef DEBUGGER_FOO
|
||||
sourceReader = &(p.lexer.reader);
|
||||
#endif
|
||||
// Generate code for parsedStatements, which is a linked
|
||||
// list of zero or more statements
|
||||
ICodeModule* icm = cx.genCode(parsedStatements, ConsoleName);
|
||||
if (icm) {
|
||||
stdOut << *icm;
|
||||
JSValue result = cx.interpret(icm, JSValues());
|
||||
stdOut << "result = " << result << "\n";
|
||||
delete icm;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
clear(buffer);
|
||||
} catch (Exception &e) {
|
||||
/* If we got a syntax error on the end of input,
|
||||
* then wait for a continuation
|
||||
* of input rather than printing the error message. */
|
||||
if (!(e.hasKind(Exception::syntaxError) &&
|
||||
e.lineNum && e.pos == buffer.size() &&
|
||||
e.sourceFile == ConsoleName)) {
|
||||
stdOut << '\n' << e.fullMessage();
|
||||
clear(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
stdOut << '\n';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Poor man's instruction tracing facility.
|
||||
*/
|
||||
class Tracer : public Context::Listener {
|
||||
typedef InstructionStream::difference_type InstructionOffset;
|
||||
void listen(Context* context, Context::Event event)
|
||||
{
|
||||
if (event & Context::EV_STEP) {
|
||||
ICodeModule *iCode = context->getICode();
|
||||
JSValues ®isters = context->getRegisters();
|
||||
InstructionIterator pc = context->getPC();
|
||||
|
||||
|
||||
InstructionOffset offset = (pc - iCode->its_iCode->begin());
|
||||
printFormat(stdOut, "trace [%02u:%04u]: ",
|
||||
iCode->mID, offset);
|
||||
|
||||
Instruction* i = *pc;
|
||||
stdOut << *i;
|
||||
if (i->op() != BRANCH && i->count() > 0) {
|
||||
stdOut << " [";
|
||||
i->printOperands(stdOut, registers);
|
||||
stdOut << "]\n";
|
||||
} else {
|
||||
stdOut << '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
char * tests[] = {
|
||||
"function fact(n) { if (n > 1) return n * fact(n-1); else return 1; } print(fact(6), \" should be 720\"); return;" ,
|
||||
"a = { f1: 1, f2: 2}; print(a.f2++, \" should be 2\"); print(a.f2 <<= 1, \" should be 6\"); return;" ,
|
||||
"class A { static var b = 3; static function s() { return b++; }function x() { return \"Ax\"; } function y() { return \"Ay\"; } } var a:A = new A; print(a.s(), \" should be 3\"); print(A.b, \" should be 4\"); return;",
|
||||
"class B extends A { function x() { return \"Bx\"; } } var b:B = new B; print(b.x(), \" should be Bx\"); print(b.y(), \" should be Ay\"); return;"
|
||||
};
|
||||
|
||||
static void testCompile()
|
||||
{
|
||||
JSScope glob;
|
||||
Context cx(world, &glob);
|
||||
glob.defineNativeFunction(world.identifiers["print"], print);
|
||||
for (uint i = 0; i < sizeof(tests) / sizeof(char *); i++) {
|
||||
String testScript = widenCString(tests[i]);
|
||||
Arena a;
|
||||
Parser p(world, a, testScript, widenCString("testCompile"));
|
||||
StmtNode *parsedStatements = p.parseProgram();
|
||||
ICodeGenerator icg(&world, &glob);
|
||||
StmtNode *s = parsedStatements;
|
||||
while (s) {
|
||||
icg.genStmt(s);
|
||||
s = s->next;
|
||||
}
|
||||
cx.interpret(icg.complete(), JSValues());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} /* namespace Shell */
|
||||
} /* namespace JavaScript */
|
||||
|
||||
|
||||
#if defined(XP_MAC) && !defined(XP_MAC_MPW)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
initConsole("\pJavaScript Shell", "Welcome to the js2 shell.\n", argc, argv);
|
||||
#else
|
||||
int main(int , char **)
|
||||
{
|
||||
#endif
|
||||
|
||||
using namespace JavaScript;
|
||||
using namespace Shell;
|
||||
#if 1
|
||||
testCompile();
|
||||
#endif
|
||||
readEvalPrint(stdin, world);
|
||||
return 0;
|
||||
// return ProcessArgs(argv + 1, argc - 1);
|
||||
}
|
||||
@@ -1,316 +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.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the JavaScript 2 Prototype.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
#ifndef jsclasses_h
|
||||
#define jsclasses_h
|
||||
|
||||
#include "jstypes.h"
|
||||
|
||||
namespace JavaScript {
|
||||
namespace JSClasses {
|
||||
|
||||
using JSTypes::JSValue;
|
||||
using JSTypes::JSObject;
|
||||
using JSTypes::JSType;
|
||||
using JSTypes::JSScope;
|
||||
using JSTypes::JSFunction;
|
||||
using ICG::ICodeModule;
|
||||
|
||||
|
||||
struct JSSlot {
|
||||
typedef enum { kNoFlag = 0, kIsConstructor = 0x01 } SlotFlags; // <-- readonly, enumerable etc
|
||||
|
||||
JSType* mType;
|
||||
uint32 mIndex;
|
||||
SlotFlags mFlags;
|
||||
|
||||
JSSlot() : mType(0), mFlags(kNoFlag)
|
||||
{
|
||||
}
|
||||
|
||||
bool isConstructor() const { return (mFlags & kIsConstructor) != 0; }
|
||||
};
|
||||
|
||||
#if defined(XP_MAC)
|
||||
// copied from default template parameters in map.
|
||||
typedef gc_allocator<std::pair<const String, JSSlot> > gc_slot_allocator;
|
||||
#elif defined(XP_UNIX)
|
||||
typedef JSTypes::gc_map_allocator gc_slot_allocator;
|
||||
#elif defined(_WIN32)
|
||||
typedef gc_allocator<JSSlot> gc_slot_allocator;
|
||||
#endif
|
||||
|
||||
typedef std::map<String, JSSlot, std::less<const String>, gc_slot_allocator> JSSlots;
|
||||
|
||||
|
||||
typedef std::pair<String, JSFunction*> MethodEntry;
|
||||
typedef std::vector<MethodEntry> JSMethods;
|
||||
|
||||
/**
|
||||
* Represents a class in the JavaScript 2 (ECMA 4) language.
|
||||
* Since a class defines a scope, and is defined in a scope,
|
||||
* a new scope is created whose parent scope is the scope of
|
||||
* class definition.
|
||||
*/
|
||||
class JSClass : public JSType {
|
||||
protected:
|
||||
JSScope* mScope;
|
||||
uint32 mSlotCount;
|
||||
JSSlots mSlots;
|
||||
uint32 mStaticCount;
|
||||
JSSlots mStaticSlots;
|
||||
JSValue* mStaticData;
|
||||
JSMethods mMethods;
|
||||
public:
|
||||
JSClass(JSScope* scope, const String& name, JSClass* superClass = 0)
|
||||
: JSType(name, superClass),
|
||||
mScope(new JSScope(scope)),
|
||||
mSlotCount(superClass ? superClass->mSlotCount : 0),
|
||||
mStaticCount(0),
|
||||
mStaticData(0)
|
||||
{
|
||||
if (superClass) {
|
||||
// inherit superclass methods
|
||||
JSMethods::iterator end = superClass->mMethods.end();
|
||||
for (JSMethods::iterator i = superClass->mMethods.begin(); i != end; i++)
|
||||
mMethods.push_back(*i);
|
||||
}
|
||||
}
|
||||
|
||||
JSClass* getSuperClass()
|
||||
{
|
||||
return static_cast<JSClass*>(mBaseType);
|
||||
}
|
||||
|
||||
JSScope* getScope()
|
||||
{
|
||||
return mScope;
|
||||
}
|
||||
|
||||
const JSSlot& defineSlot(const String& name, JSType* type)
|
||||
{
|
||||
JSSlot& slot = mSlots[name];
|
||||
ASSERT(slot.mType == 0);
|
||||
slot.mType = type;
|
||||
slot.mIndex = mSlotCount++; // starts at 0.
|
||||
return slot;
|
||||
}
|
||||
|
||||
const JSSlot& getSlot(const String& name)
|
||||
{
|
||||
return mSlots[name];
|
||||
}
|
||||
|
||||
bool hasSlot(const String& name)
|
||||
{
|
||||
return (mSlots.find(name) != mSlots.end());
|
||||
}
|
||||
|
||||
JSSlots& getSlots()
|
||||
{
|
||||
return mSlots;
|
||||
}
|
||||
|
||||
uint32 getSlotCount()
|
||||
{
|
||||
return mSlotCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a static/class variable.
|
||||
*/
|
||||
const JSSlot& defineStatic(const String& name, JSType* type)
|
||||
{
|
||||
JSSlot& slot = mStaticSlots[name];
|
||||
ASSERT(slot.mType == 0);
|
||||
slot.mType = type;
|
||||
slot.mIndex = mStaticCount++;
|
||||
return slot;
|
||||
}
|
||||
|
||||
const JSSlot& defineConstructor(const String& name)
|
||||
{
|
||||
JSSlot& slot = mStaticSlots[name];
|
||||
ASSERT(slot.mType == 0);
|
||||
slot.mType = &JSTypes::Function_Type;
|
||||
slot.mIndex = mStaticCount++;
|
||||
slot.mFlags = JSSlot::kIsConstructor;
|
||||
return slot;
|
||||
}
|
||||
|
||||
const JSSlot& getStatic(const String& name)
|
||||
{
|
||||
return mStaticSlots[name];
|
||||
}
|
||||
|
||||
bool hasStatic(const String& name, JSType*& type, bool &isConstructor)
|
||||
{
|
||||
JSSlots::const_iterator i = mStaticSlots.find(name);
|
||||
if (i != mStaticSlots.end()) {
|
||||
type = i->second.mType;
|
||||
isConstructor = i->second.isConstructor();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hasStatic(const String& name)
|
||||
{
|
||||
return (mStaticSlots.find(name) != mStaticSlots.end());
|
||||
}
|
||||
|
||||
bool complete()
|
||||
{
|
||||
mStaticData = new JSValue[mStaticCount];
|
||||
return (mStaticData != 0);
|
||||
}
|
||||
|
||||
JSValue& operator[] (uint32 index)
|
||||
{
|
||||
return mStaticData[index];
|
||||
}
|
||||
|
||||
virtual void printProperties(Formatter& f)
|
||||
{
|
||||
f << "Properties:\n";
|
||||
JSObject::printProperties(f);
|
||||
f << "Statics:\n";
|
||||
printStatics(f);
|
||||
}
|
||||
|
||||
void printStatics(Formatter& f)
|
||||
{
|
||||
JSClass* superClass = getSuperClass();
|
||||
if (superClass) superClass->printStatics(f);
|
||||
for (JSSlots::iterator i = mStaticSlots.begin(), end = mStaticSlots.end(); i != end; ++i) {
|
||||
f << i->first << " : " << mStaticData[i->second.mIndex] << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void defineMethod(const String& name, JSFunction *f)
|
||||
{
|
||||
uint32 slot;
|
||||
if (hasMethod(name, slot))
|
||||
mMethods[slot] = MethodEntry(name, f);
|
||||
else
|
||||
mMethods.push_back(MethodEntry(name, f));
|
||||
}
|
||||
|
||||
bool hasMethod(const String& name, uint32& index)
|
||||
{
|
||||
JSMethods::iterator end = mMethods.end();
|
||||
for (JSMethods::iterator i = mMethods.begin(); i != end; i++) {
|
||||
if (i->first == name) {
|
||||
index = i - mMethods.begin();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
JSFunction* getMethod(uint32 index)
|
||||
{
|
||||
return mMethods[index].second;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents an instance of a JSClass.
|
||||
*/
|
||||
class JSInstance : public JSObject {
|
||||
protected:
|
||||
JSValue mSlots[1];
|
||||
public:
|
||||
void* operator new(size_t n, JSClass* thisClass)
|
||||
{
|
||||
uint32 slotCount = thisClass->getSlotCount();
|
||||
if (slotCount > 0) n += sizeof(JSValue) * (slotCount - 1);
|
||||
return gc_base::operator new(n);
|
||||
}
|
||||
|
||||
#if !defined(XP_MAC)
|
||||
void operator delete(void* /*ptr*/, JSClass* /*thisClass*/) {}
|
||||
#endif
|
||||
|
||||
JSInstance(JSClass* thisClass)
|
||||
{
|
||||
mType = thisClass;
|
||||
// initialize extra slots with undefined.
|
||||
uint32 slotCount = thisClass->getSlotCount();
|
||||
if (slotCount > 0) {
|
||||
std::uninitialized_fill(&mSlots[1], &mSlots[1] + (slotCount - 1),
|
||||
JSTypes::kUndefinedValue);
|
||||
}
|
||||
// for grins, use the prototype link to access methods.
|
||||
setPrototype(thisClass->getScope());
|
||||
}
|
||||
|
||||
JSFunction* getMethod(uint32 index)
|
||||
{
|
||||
return getClass()->getMethod(index);
|
||||
}
|
||||
|
||||
JSClass* getClass()
|
||||
{
|
||||
return static_cast<JSClass*>(mType);
|
||||
}
|
||||
|
||||
JSValue& operator[] (uint32 index)
|
||||
{
|
||||
return mSlots[index];
|
||||
}
|
||||
|
||||
virtual void printProperties(Formatter& f)
|
||||
{
|
||||
f << "Properties:\n";
|
||||
JSObject::printProperties(f);
|
||||
f << "Slots:\n";
|
||||
printSlots(f, getClass());
|
||||
}
|
||||
|
||||
private:
|
||||
void printSlots(Formatter& f, JSClass* thisClass)
|
||||
{
|
||||
JSClass* superClass = thisClass->getSuperClass();
|
||||
if (superClass) printSlots(f, superClass);
|
||||
JSSlots& slots = thisClass->getSlots();
|
||||
for (JSSlots::iterator i = slots.begin(), end = slots.end(); i != end; ++i) {
|
||||
f << i->first << " : " << mSlots[i->second.mIndex] << "\n";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace JSClasses */
|
||||
} /* namespace JavaScript */
|
||||
|
||||
#endif /* jsclasses_h */
|
||||
@@ -1,208 +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.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the JavaScript 2 Prototype.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "jsmath.h"
|
||||
|
||||
namespace JavaScript {
|
||||
namespace JSMathClass {
|
||||
|
||||
using namespace JSTypes;
|
||||
|
||||
#ifndef M_E
|
||||
#define M_E 2.7182818284590452354
|
||||
#endif
|
||||
#ifndef M_LOG2E
|
||||
#define M_LOG2E 1.4426950408889634074
|
||||
#endif
|
||||
#ifndef M_LOG10E
|
||||
#define M_LOG10E 0.43429448190325182765
|
||||
#endif
|
||||
#ifndef M_LN2
|
||||
#define M_LN2 0.69314718055994530942
|
||||
#endif
|
||||
#ifndef M_LN10
|
||||
#define M_LN10 2.30258509299404568402
|
||||
#endif
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
#ifndef M_SQRT2
|
||||
#define M_SQRT2 1.41421356237309504880
|
||||
#endif
|
||||
#ifndef M_SQRT1_2
|
||||
#define M_SQRT1_2 0.70710678118654752440
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Concept copied from SpiderMonkey -
|
||||
fd_XXX needs to be defined either as a call to the fdlibm routine
|
||||
or the native C library routine depending on the platform
|
||||
*/
|
||||
|
||||
#define JS_USE_FDLIBM_MATH 0
|
||||
|
||||
|
||||
#if !JS_USE_FDLIBM_MATH
|
||||
/*
|
||||
* Use system provided math routines.
|
||||
*/
|
||||
|
||||
|
||||
#define fd_acos acos
|
||||
#define fd_asin asin
|
||||
#define fd_atan atan
|
||||
#define fd_atan2 atan2
|
||||
#define fd_ceil ceil
|
||||
#define fd_copysign copysign
|
||||
#define fd_cos cos
|
||||
#define fd_exp exp
|
||||
#define fd_fabs fabs
|
||||
#define fd_floor floor
|
||||
#define fd_fmod fmod
|
||||
#define fd_log log
|
||||
#define fd_pow pow
|
||||
#define fd_sin sin
|
||||
#define fd_sqrt sqrt
|
||||
#define fd_tan tan
|
||||
|
||||
#endif
|
||||
|
||||
JSValue math_abs(Context *cx, const JSValues& argv)
|
||||
{
|
||||
if (argv.size() > 0) {
|
||||
JSValue num = argv[1].toNumber();
|
||||
if (num.isNaN()) return num;
|
||||
if (num.isNegativeZero()) return kPositiveZero;
|
||||
if (num.isNegativeInfinity()) return kPositiveInfinity;
|
||||
if (num.f64 < 0) return JSValue(-num.f64);
|
||||
return num;
|
||||
}
|
||||
return kUndefinedValue;
|
||||
}
|
||||
|
||||
JSValue math_acos(Context *cx, const JSValues& argv)
|
||||
{
|
||||
if (argv.size() > 0) {
|
||||
JSValue num = argv[1].toNumber();
|
||||
return JSValue(fd_acos(num.f64));
|
||||
}
|
||||
return kUndefinedValue;
|
||||
}
|
||||
|
||||
JSValue math_asin(Context *cx, const JSValues& argv)
|
||||
{
|
||||
if (argv.size() > 0) {
|
||||
JSValue num = argv[1].toNumber();
|
||||
return JSValue(fd_asin(num.f64));
|
||||
}
|
||||
return kUndefinedValue;
|
||||
}
|
||||
|
||||
JSValue math_atan(Context *cx, const JSValues& argv)
|
||||
{
|
||||
if (argv.size() > 0) {
|
||||
JSValue num = argv[1].toNumber();
|
||||
return JSValue(fd_atan(num.f64));
|
||||
}
|
||||
return kUndefinedValue;
|
||||
}
|
||||
|
||||
JSValue math_atan2(Context *cx, const JSValues& argv)
|
||||
{
|
||||
if (argv.size() > 1) {
|
||||
JSValue num1 = argv[1].toNumber();
|
||||
JSValue num2 = argv[1].toNumber();
|
||||
return JSValue(fd_atan2(num1.f64, num2.f64));
|
||||
}
|
||||
return kUndefinedValue;
|
||||
}
|
||||
|
||||
JSValue math_ceil(Context *cx, const JSValues& argv)
|
||||
{
|
||||
if (argv.size() > 0) {
|
||||
JSValue num = argv[1].toNumber();
|
||||
return JSValue(fd_ceil(num.f64));
|
||||
}
|
||||
return kUndefinedValue;
|
||||
}
|
||||
|
||||
struct MathFunctionEntry {
|
||||
char *name;
|
||||
JSNativeFunction::JSCode fn;
|
||||
} MathFunctions[] = {
|
||||
{ "abs", math_abs },
|
||||
{ "acos", math_acos },
|
||||
{ "asin", math_asin },
|
||||
{ "atan", math_atan },
|
||||
{ "atan2", math_atan2 },
|
||||
{ "ceil", math_acos },
|
||||
{ "acos", math_acos },
|
||||
{ "acos", math_acos }
|
||||
};
|
||||
|
||||
struct MathConstantEntry {
|
||||
char *name;
|
||||
double value;
|
||||
} MathConstants[] = {
|
||||
{ "E", M_E },
|
||||
{ "LOG2E", M_LOG2E },
|
||||
{ "LOG10E", M_LOG10E },
|
||||
{ "LN2", M_LN2 },
|
||||
{ "LN10", M_LN10 },
|
||||
{ "PI", M_PI },
|
||||
{ "SQRT2", M_SQRT2 },
|
||||
{ "SQRT1_2", M_SQRT1_2 }
|
||||
};
|
||||
|
||||
// There is no constructor for Math, we simply initialize
|
||||
// the properties of the Math object
|
||||
void JSMath::initMathObject(JSScope *g)
|
||||
{
|
||||
int i;
|
||||
JSMath *m = new JSMath();
|
||||
m->setClass(new JSString("Math"));
|
||||
|
||||
for (i = 0; i < sizeof(MathFunctions) / sizeof(MathFunctionEntry); i++)
|
||||
m->setProperty(widenCString(MathFunctions[i].name), JSValue(new JSNativeFunction(MathFunctions[i].fn) ) );
|
||||
|
||||
for (i = 0; i < sizeof(MathConstants) / sizeof(MathConstantEntry); i++)
|
||||
m->setProperty(widenCString(MathConstants[i].name), JSValue(MathConstants[i].value) );
|
||||
|
||||
g->setProperty(widenCString("Math"), JSValue(m));
|
||||
|
||||
}
|
||||
|
||||
} /* JSMathClass */
|
||||
} /* JavaScript */
|
||||
@@ -1,775 +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.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the JavaScript 2 Prototype.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
#include "jstypes.h"
|
||||
#include "jsclasses.h"
|
||||
#include "numerics.h"
|
||||
#include "icodegenerator.h"
|
||||
#include "interpreter.h"
|
||||
|
||||
namespace JavaScript {
|
||||
namespace JSTypes {
|
||||
|
||||
using namespace JSClasses;
|
||||
using namespace Interpreter;
|
||||
|
||||
/********** Object Object Stuff **************************/
|
||||
|
||||
JSValue object_toString(Context *cx, const JSValues& argv)
|
||||
{
|
||||
if (argv.size() > 0) {
|
||||
JSString *s = new JSString("[object ");
|
||||
JSValue theThis = argv[0];
|
||||
ASSERT(theThis.isObject());
|
||||
s->append(theThis.object->getClass());
|
||||
s->append("]");
|
||||
return JSValue(s);
|
||||
}
|
||||
return kUndefinedValue;
|
||||
}
|
||||
|
||||
JSValue objectConstructor(Context *cx, const JSValues& argv)
|
||||
{
|
||||
ASSERT(argv.size() > 0);
|
||||
JSValue theThis = argv[0];
|
||||
|
||||
// the prototype and class have been established already
|
||||
|
||||
return theThis;
|
||||
}
|
||||
|
||||
struct ObjectFunctionEntry {
|
||||
char *name;
|
||||
JSNativeFunction::JSCode fn;
|
||||
} ObjectFunctions[] = {
|
||||
{ "toString", object_toString },
|
||||
};
|
||||
|
||||
|
||||
JSObject *JSObject::objectPrototypeObject = JSObject::initJSObject();
|
||||
String JSObject::ObjectString = widenCString("Object");
|
||||
|
||||
// This establishes the ur-prototype, there's a timing issue
|
||||
// here - the JSObject static initializers have to run before
|
||||
// any other JSObject objects are constructed.
|
||||
JSObject *JSObject::initJSObject()
|
||||
{
|
||||
JSObject *result = new JSObject();
|
||||
|
||||
for (int i = 0; i < sizeof(ObjectFunctions) / sizeof(ObjectFunctionEntry); i++)
|
||||
result->setProperty(widenCString(ObjectFunctions[i].name), JSValue(new JSNativeFunction(ObjectFunctions[i].fn) ) );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Install the 'Object' constructor into the scope, mostly irrelevant since making
|
||||
// a new JSObject does all the work of setting the prototype and [[class]] values.
|
||||
void JSObject::initObjectObject(JSScope *g)
|
||||
{
|
||||
JSNativeFunction *objCon = new JSNativeFunction(objectConstructor);
|
||||
|
||||
objCon->setProperty(widenCString("prototype"), JSValue(objectPrototypeObject));
|
||||
|
||||
|
||||
|
||||
|
||||
g->setProperty(ObjectString, JSValue(objCon));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/********** Function Object Stuff **************************/
|
||||
|
||||
// An empty function that returns undefined
|
||||
JSValue functionPrototypeFunction(Context *cx, const JSValues& argv)
|
||||
{
|
||||
return kUndefinedValue;
|
||||
}
|
||||
|
||||
|
||||
JSValue function_constructor(Context *cx, const JSValues& argv)
|
||||
{
|
||||
// build a function from the arguments into the this.
|
||||
ASSERT(argv.size() > 0);
|
||||
JSValue theThis = argv[0];
|
||||
ASSERT(theThis.isObject());
|
||||
|
||||
if (argv.size() == 2) {
|
||||
JSValue s = JSValue::valueToString(argv[1]);
|
||||
theThis = new JSFunction(cx->compile((String)(*s.string)));
|
||||
}
|
||||
|
||||
return theThis;
|
||||
}
|
||||
|
||||
JSValue function_toString(Context *cx, const JSValues& argv)
|
||||
{
|
||||
return JSValue(new JSString("function XXX() { }" ));
|
||||
}
|
||||
JSValue function_apply(Context *cx, const JSValues& argv)
|
||||
{
|
||||
// XXX
|
||||
return kUndefinedValue;
|
||||
}
|
||||
JSValue function_call(Context *cx, const JSValues& argv)
|
||||
{
|
||||
// XXX
|
||||
return kUndefinedValue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
String JSFunction::FunctionString = widenCString("Function");
|
||||
JSObject *JSFunction::functionPrototypeObject = NULL; // the 'original Function prototype object'
|
||||
|
||||
struct FunctionFunctionEntry {
|
||||
char *name;
|
||||
JSNativeFunction::JSCode fn;
|
||||
} FunctionFunctions[] = {
|
||||
{ "constructor", function_constructor },
|
||||
{ "toString", function_toString },
|
||||
{ "apply", function_apply },
|
||||
{ "call", function_call },
|
||||
};
|
||||
|
||||
void JSFunction::initFunctionObject(JSScope *g)
|
||||
{
|
||||
// first build the Function Prototype Object
|
||||
functionPrototypeObject = new JSNativeFunction(functionPrototypeFunction);
|
||||
for (int i = 0; i < sizeof(FunctionFunctions) / sizeof(FunctionFunctionEntry); i++)
|
||||
functionPrototypeObject->setProperty(widenCString(FunctionFunctions[i].name), JSValue(new JSNativeFunction(FunctionFunctions[i].fn) ) );
|
||||
|
||||
// now the Function Constructor Object
|
||||
JSNativeFunction *functionConstructorObject = new JSNativeFunction(function_constructor);
|
||||
functionConstructorObject->setPrototype(functionPrototypeObject);
|
||||
functionConstructorObject->setProperty(widenCString("length"), JSValue((int32)1));
|
||||
functionConstructorObject->setProperty(widenCString("prototype"), JSValue(functionPrototypeObject));
|
||||
|
||||
// This is interesting - had to use defineVariable here to specify a type because
|
||||
// when left as Any_Type (via setProperty), the Function predefined type interacted
|
||||
// badly with this value. (I think setProperty perhaps should have reset the entry
|
||||
// in mTypes) (?)
|
||||
g->defineVariable(FunctionString, &Function_Type, JSValue(functionConstructorObject));
|
||||
}
|
||||
|
||||
/**************************************************************************************/
|
||||
|
||||
JSType Any_Type = JSType(widenCString("any"), NULL);
|
||||
JSType Integer_Type = JSType(widenCString("Integer"), &Any_Type);
|
||||
JSType Number_Type = JSType(widenCString("Number"), &Integer_Type);
|
||||
JSType Character_Type = JSType(widenCString("Character"), &Any_Type);
|
||||
JSType String_Type = JSType(widenCString("String"), &Character_Type);
|
||||
JSType Function_Type = JSType(widenCString("Function"), &Any_Type);
|
||||
JSType Array_Type = JSType(widenCString("Array"), &Any_Type);
|
||||
JSType Type_Type = JSType(widenCString("Type"), &Any_Type);
|
||||
JSType Boolean_Type = JSType(widenCString("Boolean"), &Any_Type);
|
||||
JSType Null_Type = JSType(widenCString("Null"), &Any_Type);
|
||||
JSType Void_Type = JSType(widenCString("void"), &Any_Type);
|
||||
JSType None_Type = JSType(widenCString("none"), &Any_Type);
|
||||
|
||||
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
#define JSDOUBLE_HI32(x) (((uint32 *)&(x))[1])
|
||||
#define JSDOUBLE_LO32(x) (((uint32 *)&(x))[0])
|
||||
#else
|
||||
#define JSDOUBLE_HI32(x) (((uint32 *)&(x))[0])
|
||||
#define JSDOUBLE_LO32(x) (((uint32 *)&(x))[1])
|
||||
#endif
|
||||
|
||||
#define JSDOUBLE_HI32_SIGNBIT 0x80000000
|
||||
#define JSDOUBLE_HI32_EXPMASK 0x7ff00000
|
||||
#define JSDOUBLE_HI32_MANTMASK 0x000fffff
|
||||
|
||||
#define JSDOUBLE_IS_NaN(x) \
|
||||
((JSDOUBLE_HI32(x) & JSDOUBLE_HI32_EXPMASK) == JSDOUBLE_HI32_EXPMASK && \
|
||||
(JSDOUBLE_LO32(x) || (JSDOUBLE_HI32(x) & JSDOUBLE_HI32_MANTMASK)))
|
||||
|
||||
#define JSDOUBLE_IS_INFINITE(x) \
|
||||
((JSDOUBLE_HI32(x) & ~JSDOUBLE_HI32_SIGNBIT) == JSDOUBLE_HI32_EXPMASK && \
|
||||
!JSDOUBLE_LO32(x))
|
||||
|
||||
#define JSDOUBLE_IS_FINITE(x) \
|
||||
((JSDOUBLE_HI32(x) & JSDOUBLE_HI32_EXPMASK) != JSDOUBLE_HI32_EXPMASK)
|
||||
|
||||
#define JSDOUBLE_IS_NEGZERO(d) (JSDOUBLE_HI32(d) == JSDOUBLE_HI32_SIGNBIT && \
|
||||
JSDOUBLE_LO32(d) == 0)
|
||||
|
||||
|
||||
// the canonical undefined value, etc.
|
||||
const JSValue kUndefinedValue;
|
||||
const JSValue kNaNValue = JSValue(nan);
|
||||
const JSValue kTrueValue = JSValue(true);
|
||||
const JSValue kFalseValue = JSValue(false);
|
||||
const JSValue kNullValue = JSValue((JSObject*)NULL);
|
||||
const JSValue kNegativeZero = JSValue(-0.0);
|
||||
const JSValue kPositiveZero = JSValue(0.0);
|
||||
const JSValue kNegativeInfinity = JSValue(negativeInfinity);
|
||||
const JSValue kPositiveInfinity = JSValue(positiveInfinity);
|
||||
|
||||
|
||||
const JSType *JSValue::getType() const
|
||||
{
|
||||
switch (tag) {
|
||||
case JSValue::i32_tag:
|
||||
return &Integer_Type;
|
||||
case JSValue::u32_tag:
|
||||
return &Integer_Type;
|
||||
case JSValue::integer_tag:
|
||||
return &Integer_Type;
|
||||
case JSValue::f64_tag:
|
||||
return &Number_Type;
|
||||
case JSValue::object_tag:
|
||||
{
|
||||
//
|
||||
// XXX why isn't there a class for Object? XXX
|
||||
//
|
||||
JSClass *clazz = dynamic_cast<JSClass *>(object->getType());
|
||||
if (clazz)
|
||||
return clazz;
|
||||
else
|
||||
return &Any_Type;
|
||||
}
|
||||
case JSValue::array_tag:
|
||||
return &Array_Type;
|
||||
case JSValue::function_tag:
|
||||
return &Function_Type;
|
||||
case JSValue::string_tag:
|
||||
return &String_Type;
|
||||
case JSValue::boolean_tag:
|
||||
return &Boolean_Type;
|
||||
case JSValue::undefined_tag:
|
||||
return &Void_Type;
|
||||
case JSValue::type_tag:
|
||||
return &Type_Type;
|
||||
default:
|
||||
NOT_REACHED("Bad tag");
|
||||
return &None_Type;
|
||||
}
|
||||
}
|
||||
|
||||
bool JSValue::isNaN() const
|
||||
{
|
||||
ASSERT(isNumber());
|
||||
switch (tag) {
|
||||
case i32_tag:
|
||||
case u32_tag:
|
||||
return false;
|
||||
case integer_tag:
|
||||
case f64_tag:
|
||||
return JSDOUBLE_IS_NaN(f64);
|
||||
default:
|
||||
NOT_REACHED("Broken compiler?");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool JSValue::isNegativeInfinity() const
|
||||
{
|
||||
ASSERT(isNumber());
|
||||
switch (tag) {
|
||||
case i32_tag:
|
||||
case u32_tag:
|
||||
return false;
|
||||
case integer_tag:
|
||||
case f64_tag:
|
||||
return (f64 < 0) && JSDOUBLE_IS_INFINITE(f64);
|
||||
default:
|
||||
NOT_REACHED("Broken compiler?");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool JSValue::isPositiveInfinity() const
|
||||
{
|
||||
ASSERT(isNumber());
|
||||
switch (tag) {
|
||||
case i32_tag:
|
||||
case u32_tag:
|
||||
return false;
|
||||
case integer_tag:
|
||||
case f64_tag:
|
||||
return (f64 > 0) && JSDOUBLE_IS_INFINITE(f64);
|
||||
default:
|
||||
NOT_REACHED("Broken compiler?");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool JSValue::isNegativeZero() const
|
||||
{
|
||||
ASSERT(isNumber());
|
||||
switch (tag) {
|
||||
case i32_tag:
|
||||
case u32_tag:
|
||||
return false;
|
||||
case integer_tag:
|
||||
case f64_tag:
|
||||
return JSDOUBLE_IS_NEGZERO(f64);
|
||||
default:
|
||||
NOT_REACHED("Broken compiler?");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool JSValue::isPositiveZero() const
|
||||
{
|
||||
ASSERT(isNumber());
|
||||
switch (tag) {
|
||||
case i32_tag:
|
||||
return (i32 == 0);
|
||||
case u32_tag:
|
||||
return (u32 == 0);
|
||||
case integer_tag:
|
||||
case f64_tag:
|
||||
return (f64 == 0.0) && !JSDOUBLE_IS_NEGZERO(f64);
|
||||
default:
|
||||
NOT_REACHED("Broken compiler?");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
int JSValue::operator==(const JSValue& value) const
|
||||
{
|
||||
if (this->tag == value.tag) {
|
||||
#define CASE(T) case T##_tag: return (this->T == value.T)
|
||||
switch (tag) {
|
||||
CASE(i8); CASE(u8);
|
||||
CASE(i16); CASE(u16);
|
||||
CASE(i32); CASE(u32); CASE(f32);
|
||||
CASE(i64); CASE(u64); CASE(f64);
|
||||
CASE(object); CASE(array); CASE(function); CASE(string);
|
||||
CASE(type); CASE(boolean);
|
||||
#undef CASE
|
||||
case integer_tag : return (this->f64 == value.f64);
|
||||
// question: are all undefined values equal to one another?
|
||||
case undefined_tag: return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Formatter& operator<<(Formatter& f, JSObject& obj)
|
||||
{
|
||||
obj.printProperties(f);
|
||||
return f;
|
||||
}
|
||||
|
||||
void JSObject::printProperties(Formatter& f)
|
||||
{
|
||||
for (JSProperties::const_iterator i = mProperties.begin(); i != mProperties.end(); i++) {
|
||||
f << (*i).first << " : " << (*i).second;
|
||||
f << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
Formatter& operator<<(Formatter& f, const JSValue& value)
|
||||
{
|
||||
switch (value.tag) {
|
||||
case JSValue::i32_tag:
|
||||
f << float64(value.i32);
|
||||
break;
|
||||
case JSValue::u32_tag:
|
||||
f << float64(value.u32);
|
||||
break;
|
||||
case JSValue::integer_tag:
|
||||
case JSValue::f64_tag:
|
||||
f << value.f64;
|
||||
break;
|
||||
case JSValue::object_tag:
|
||||
printFormat(f, "Object @ 0x%08X\n", value.object);
|
||||
f << *value.object;
|
||||
break;
|
||||
case JSValue::array_tag:
|
||||
printFormat(f, "Array @ 0x%08X", value.object);
|
||||
break;
|
||||
case JSValue::function_tag:
|
||||
printFormat(f, "Function @ 0x%08X", value.object);
|
||||
break;
|
||||
case JSValue::string_tag:
|
||||
f << *value.string;
|
||||
break;
|
||||
case JSValue::boolean_tag:
|
||||
f << ((value.boolean) ? "true" : "false");
|
||||
break;
|
||||
case JSValue::undefined_tag:
|
||||
f << "undefined";
|
||||
break;
|
||||
case JSValue::type_tag:
|
||||
printFormat(f, "Type @ 0x%08X\n", value.type);
|
||||
f << *value.type;
|
||||
break;
|
||||
default:
|
||||
NOT_REACHED("Bad tag");
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
JSValue JSValue::toPrimitive(ECMA_type /*hint*/) const
|
||||
{
|
||||
JSObject *obj;
|
||||
switch (tag) {
|
||||
case i32_tag:
|
||||
case u32_tag:
|
||||
case integer_tag:
|
||||
case f64_tag:
|
||||
case string_tag:
|
||||
case boolean_tag:
|
||||
case undefined_tag:
|
||||
return *this;
|
||||
|
||||
case object_tag:
|
||||
obj = object;
|
||||
break;
|
||||
case array_tag:
|
||||
obj = array;
|
||||
break;
|
||||
case function_tag:
|
||||
obj = function;
|
||||
break;
|
||||
|
||||
default:
|
||||
NOT_REACHED("Bad tag");
|
||||
return kUndefinedValue;
|
||||
}
|
||||
|
||||
const JSValue &toString = obj->getProperty(widenCString("toString"));
|
||||
if (toString.isObject()) {
|
||||
if (toString.isFunction()) {
|
||||
}
|
||||
else // right? The spec doesn't say
|
||||
throw new JSException("Runtime error from toPrimitive"); // XXX
|
||||
}
|
||||
|
||||
const JSValue &valueOf = obj->getProperty(widenCString("valueOf"));
|
||||
if (!valueOf.isObject())
|
||||
throw new JSException("Runtime error from toPrimitive"); // XXX
|
||||
|
||||
return kUndefinedValue;
|
||||
|
||||
}
|
||||
|
||||
|
||||
JSValue JSValue::valueToString(const JSValue& value) // can assume value is not a string
|
||||
{
|
||||
const char* chrp;
|
||||
char buf[dtosStandardBufferSize];
|
||||
switch (value.tag) {
|
||||
case i32_tag:
|
||||
chrp = doubleToStr(buf, dtosStandardBufferSize, value.i32, dtosStandard, 0);
|
||||
break;
|
||||
case u32_tag:
|
||||
chrp = doubleToStr(buf, dtosStandardBufferSize, value.u32, dtosStandard, 0);
|
||||
break;
|
||||
case integer_tag:
|
||||
case f64_tag:
|
||||
chrp = doubleToStr(buf, dtosStandardBufferSize, value.f64, dtosStandard, 0);
|
||||
break;
|
||||
case object_tag:
|
||||
chrp = "object";
|
||||
break;
|
||||
case array_tag:
|
||||
chrp = "array";
|
||||
break;
|
||||
case function_tag:
|
||||
chrp = "function";
|
||||
break;
|
||||
case string_tag:
|
||||
return value;
|
||||
case boolean_tag:
|
||||
chrp = (value.boolean) ? "true" : "false";
|
||||
break;
|
||||
case undefined_tag:
|
||||
chrp = "undefined";
|
||||
break;
|
||||
default:
|
||||
NOT_REACHED("Bad tag");
|
||||
}
|
||||
return JSValue(new JSString(chrp));
|
||||
}
|
||||
|
||||
JSValue JSValue::valueToNumber(const JSValue& value) // can assume value is not a number
|
||||
{
|
||||
switch (value.tag) {
|
||||
case i32_tag:
|
||||
return JSValue((float64)value.i32);
|
||||
case u32_tag:
|
||||
return JSValue((float64)value.u32);
|
||||
case integer_tag:
|
||||
case f64_tag:
|
||||
return value;
|
||||
case string_tag:
|
||||
{
|
||||
JSString* str = value.string;
|
||||
const char16 *numEnd;
|
||||
double d = stringToDouble(str->begin(), str->end(), numEnd);
|
||||
return JSValue(d);
|
||||
}
|
||||
case object_tag:
|
||||
case array_tag:
|
||||
case function_tag:
|
||||
// XXX more needed :
|
||||
// toNumber(toPrimitive(hint Number))
|
||||
return kUndefinedValue;
|
||||
case boolean_tag:
|
||||
return JSValue((value.boolean) ? 1.0 : 0.0);
|
||||
case undefined_tag:
|
||||
return kNaNValue;
|
||||
default:
|
||||
NOT_REACHED("Bad tag");
|
||||
return kUndefinedValue;
|
||||
}
|
||||
}
|
||||
|
||||
JSValue JSValue::valueToInteger(const JSValue& value)
|
||||
{
|
||||
JSValue result = valueToNumber(value);
|
||||
ASSERT(result.tag == f64_tag);
|
||||
result.tag = i64_tag;
|
||||
bool neg = (result.f64 < 0);
|
||||
result.f64 = floor((neg) ? -result.f64 : result.f64);
|
||||
result.f64 = (neg) ? -result.f64 : result.f64;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
JSValue JSValue::valueToBoolean(const JSValue& value)
|
||||
{
|
||||
switch (value.tag) {
|
||||
case i32_tag:
|
||||
return JSValue(value.i32 != 0);
|
||||
case u32_tag:
|
||||
return JSValue(value.u32 != 0);
|
||||
case integer_tag:
|
||||
case f64_tag:
|
||||
return JSValue(!(value.f64 == 0.0) || JSDOUBLE_IS_NaN(value.f64));
|
||||
case string_tag:
|
||||
return JSValue(value.string->length() != 0);
|
||||
case boolean_tag:
|
||||
return value;
|
||||
case object_tag:
|
||||
case array_tag:
|
||||
case function_tag:
|
||||
return kTrueValue;
|
||||
case undefined_tag:
|
||||
return kFalseValue;
|
||||
default:
|
||||
NOT_REACHED("Bad tag");
|
||||
return kUndefinedValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const double two32 = 4294967296.0;
|
||||
static const double two31 = 2147483648.0;
|
||||
|
||||
JSValue JSValue::valueToInt32(const JSValue& value)
|
||||
{
|
||||
double d;
|
||||
switch (value.tag) {
|
||||
case i32_tag:
|
||||
return value;
|
||||
case u32_tag:
|
||||
d = value.u32;
|
||||
break;
|
||||
case integer_tag:
|
||||
case f64_tag:
|
||||
d = value.f64;
|
||||
break;
|
||||
case string_tag:
|
||||
{
|
||||
JSString* str = value.string;
|
||||
const char16 *numEnd;
|
||||
d = stringToDouble(str->begin(), str->end(), numEnd);
|
||||
}
|
||||
break;
|
||||
case boolean_tag:
|
||||
return JSValue((int32)((value.boolean) ? 1 : 0));
|
||||
case object_tag:
|
||||
case array_tag:
|
||||
case undefined_tag:
|
||||
// toNumber(toPrimitive(hint Number))
|
||||
return kUndefinedValue;
|
||||
default:
|
||||
NOT_REACHED("Bad tag");
|
||||
return kUndefinedValue;
|
||||
}
|
||||
if ((d == 0.0) || !JSDOUBLE_IS_FINITE(d) )
|
||||
return JSValue((int32)0);
|
||||
d = fmod(d, two32);
|
||||
d = (d >= 0) ? d : d + two32;
|
||||
if (d >= two31)
|
||||
return JSValue((int32)(d - two32));
|
||||
else
|
||||
return JSValue((int32)d);
|
||||
|
||||
}
|
||||
|
||||
JSValue JSValue::valueToUInt32(const JSValue& value)
|
||||
{
|
||||
double d;
|
||||
switch (value.tag) {
|
||||
case i32_tag:
|
||||
return JSValue((uint32)value.i32);
|
||||
case u32_tag:
|
||||
return value;
|
||||
case f64_tag:
|
||||
d = value.f64;
|
||||
break;
|
||||
case string_tag:
|
||||
{
|
||||
JSString* str = value.string;
|
||||
const char16 *numEnd;
|
||||
d = stringToDouble(str->begin(), str->end(), numEnd);
|
||||
}
|
||||
break;
|
||||
case boolean_tag:
|
||||
return JSValue((uint32)((value.boolean) ? 1 : 0));
|
||||
case object_tag:
|
||||
case array_tag:
|
||||
case undefined_tag:
|
||||
// toNumber(toPrimitive(hint Number))
|
||||
return kUndefinedValue;
|
||||
default:
|
||||
NOT_REACHED("Bad tag");
|
||||
return kUndefinedValue;
|
||||
}
|
||||
if ((d == 0.0) || !JSDOUBLE_IS_FINITE(d))
|
||||
return JSValue((uint32)0);
|
||||
bool neg = (d < 0);
|
||||
d = floor(neg ? -d : d);
|
||||
d = neg ? -d : d;
|
||||
d = fmod(d, two32);
|
||||
d = (d >= 0) ? d : d + two32;
|
||||
return JSValue((uint32)d);
|
||||
}
|
||||
|
||||
|
||||
JSValue JSValue::convert(JSType *toType)
|
||||
{
|
||||
if (toType == &Any_Type) // yuck, something wrong with this
|
||||
// maybe the base types should be
|
||||
// a family of classes, not just instances
|
||||
// of JSType ???
|
||||
return *this;
|
||||
else if (toType == &Integer_Type)
|
||||
return valueToInteger(*this);
|
||||
else {
|
||||
JSClass *toClass = dynamic_cast<JSClass *>(toType);
|
||||
if (toClass) {
|
||||
if (tag == object_tag) {
|
||||
JSClass *fromClass = dynamic_cast<JSClass *>(object->getType());
|
||||
if (fromClass) {
|
||||
while (fromClass != toClass) {
|
||||
fromClass = fromClass->getSuperClass();
|
||||
if (fromClass == NULL)
|
||||
throw new JSException("Can't cast to unrelated class");
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
else
|
||||
throw new JSException("Can't cast a generic object to a class");
|
||||
}
|
||||
else
|
||||
throw new JSException("Can't cast a non-object to a class");
|
||||
}
|
||||
}
|
||||
return kUndefinedValue;
|
||||
}
|
||||
|
||||
|
||||
JSFunction::~JSFunction()
|
||||
{
|
||||
delete mICode;
|
||||
}
|
||||
|
||||
JSString::JSString(const String& str)
|
||||
{
|
||||
size_t n = str.size();
|
||||
resize(n);
|
||||
traits_type::copy(begin(), str.begin(), n);
|
||||
}
|
||||
|
||||
JSString::JSString(const String* str)
|
||||
{
|
||||
size_t n = str->size();
|
||||
resize(n);
|
||||
traits_type::copy(begin(), str->begin(), n);
|
||||
}
|
||||
|
||||
JSString::JSString(const char* str)
|
||||
{
|
||||
size_t n = ::strlen(str);
|
||||
resize(n);
|
||||
std::transform(str, str + n, begin(), JavaScript::widen);
|
||||
}
|
||||
|
||||
void JSString::append(const char* str)
|
||||
{
|
||||
size_t n = ::strlen(str);
|
||||
size_t oldSize = size();
|
||||
resize(oldSize + n);
|
||||
std::transform(str, str + n, begin() + oldSize, JavaScript::widen);
|
||||
}
|
||||
|
||||
void JSString::append(const JSStringBase* str)
|
||||
{
|
||||
size_t n = str->size();
|
||||
size_t oldSize = size();
|
||||
resize(oldSize + n);
|
||||
traits_type::copy(begin() + oldSize, str->begin(), n);
|
||||
}
|
||||
|
||||
JSString::operator String()
|
||||
{
|
||||
return String(begin(), size());
|
||||
}
|
||||
|
||||
|
||||
// # of sub-type relationship between this type and the other type
|
||||
// (== MAX_INT if other is not a base type)
|
||||
|
||||
int32 JSType::distance(const JSType *other) const
|
||||
{
|
||||
if (other == this)
|
||||
return 0;
|
||||
if (mBaseType == NULL)
|
||||
return NoRelation;
|
||||
int32 baseDistance = mBaseType->distance(other);
|
||||
if (baseDistance != NoRelation)
|
||||
++baseDistance;
|
||||
return baseDistance;
|
||||
}
|
||||
|
||||
|
||||
} /* namespace JSTypes */
|
||||
} /* namespace JavaScript */
|
||||
@@ -1,579 +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.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the JavaScript 2 Prototype.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
#ifndef jstypes_h
|
||||
#define jstypes_h
|
||||
|
||||
#include "utilities.h"
|
||||
#include "gc_allocator.h"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <stack>
|
||||
|
||||
|
||||
/* forward declare classes from JavaScript::ICG */
|
||||
namespace JavaScript {
|
||||
namespace ICG {
|
||||
class ICodeModule;
|
||||
} /* namespace ICG */
|
||||
namespace Interpreter {
|
||||
class Context;
|
||||
} /* namespace Interpreter */
|
||||
} /* namespace JavaScript */
|
||||
|
||||
namespace JavaScript {
|
||||
namespace JSTypes {
|
||||
|
||||
using ICG::ICodeModule;
|
||||
using Interpreter::Context;
|
||||
|
||||
class JSObject;
|
||||
class JSArray;
|
||||
class JSFunction;
|
||||
class JSScope;
|
||||
class JSString;
|
||||
class JSType;
|
||||
class Context;
|
||||
|
||||
/**
|
||||
* All JavaScript data types.
|
||||
*/
|
||||
struct JSValue {
|
||||
union {
|
||||
int8 i8;
|
||||
uint8 u8;
|
||||
int16 i16;
|
||||
uint16 u16;
|
||||
int32 i32;
|
||||
uint32 u32;
|
||||
int64 i64;
|
||||
uint64 u64;
|
||||
float32 f32;
|
||||
float64 f64;
|
||||
JSObject* object;
|
||||
JSArray* array;
|
||||
JSFunction *function;
|
||||
JSString *string;
|
||||
JSType *type;
|
||||
bool boolean;
|
||||
};
|
||||
|
||||
/* These are the ECMA types, for use in 'toPrimitive' calls */
|
||||
enum ECMA_type {
|
||||
Undefined, Null, Boolean, Number, Object, String,
|
||||
NoHint
|
||||
};
|
||||
|
||||
enum {
|
||||
i8_tag, u8_tag,
|
||||
i16_tag, u16_tag,
|
||||
i32_tag, u32_tag,
|
||||
i64_tag, u64_tag,
|
||||
f32_tag, f64_tag,
|
||||
integer_tag,
|
||||
object_tag, array_tag, function_tag, string_tag, boolean_tag, type_tag,
|
||||
undefined_tag
|
||||
} tag;
|
||||
|
||||
JSValue() : f64(0.0), tag(undefined_tag) {}
|
||||
explicit JSValue(int32 i32) : i32(i32), tag(i32_tag) {}
|
||||
explicit JSValue(uint32 u32) : u32(u32), tag(u32_tag) {}
|
||||
explicit JSValue(float64 f64) : f64(f64), tag(f64_tag) {}
|
||||
explicit JSValue(JSObject* object) : object(object), tag(object_tag) {}
|
||||
explicit JSValue(JSArray* array) : array(array), tag(array_tag) {}
|
||||
explicit JSValue(JSFunction* function) : function(function), tag(function_tag) {}
|
||||
explicit JSValue(JSString* string) : string(string), tag(string_tag) {}
|
||||
explicit JSValue(bool boolean) : boolean(boolean), tag(boolean_tag) {}
|
||||
explicit JSValue(JSType* type) : type(type), tag(type_tag) {}
|
||||
|
||||
int32& operator=(int32 i32) { return (tag = i32_tag, this->i32 = i32); }
|
||||
uint32& operator=(uint32 u32) { return (tag = u32_tag, this->u32 = u32); }
|
||||
float64& operator=(float64 f64) { return (tag = f64_tag, this->f64 = f64); }
|
||||
JSObject*& operator=(JSObject* object) { return (tag = object_tag, this->object = object); }
|
||||
JSArray*& operator=(JSArray* array) { return (tag = array_tag, this->array = array); }
|
||||
JSFunction*& operator=(JSFunction* function) { return (tag = function_tag, this->function = function); }
|
||||
JSString*& operator=(JSString* string) { return (tag = string_tag, this->string = string); }
|
||||
bool& operator=(bool boolean) { return (tag = boolean_tag, this->boolean = boolean); }
|
||||
JSType*& operator=(JSType* type) { return (tag = type_tag, this->type = type); }
|
||||
|
||||
bool isFunction() const { return (tag == function_tag); }
|
||||
bool isObject() const { return ((tag == object_tag) || (tag == function_tag) || (tag == array_tag) || (tag == type_tag)); }
|
||||
bool isString() const { return (tag == string_tag); }
|
||||
bool isBoolean() const { return (tag == boolean_tag); }
|
||||
bool isNumber() const { return (tag == f64_tag) || (tag == integer_tag); }
|
||||
|
||||
/* this is correct wrt ECMA, The i32 & u32 kinds
|
||||
will have to be converted (to doubles?) anyway because
|
||||
we can't have overflow happening in generic arithmetic */
|
||||
|
||||
bool isUndefined() const { return (tag == undefined_tag); }
|
||||
bool isNull() const { return ((tag == object_tag) && (this->object == NULL)); }
|
||||
bool isNaN() const;
|
||||
bool isNegativeInfinity() const;
|
||||
bool isPositiveInfinity() const;
|
||||
bool isNegativeZero() const;
|
||||
bool isPositiveZero() const;
|
||||
bool isType() const { return (tag == type_tag); }
|
||||
|
||||
JSValue toString() const { return (isString() ? *this : valueToString(*this)); }
|
||||
JSValue toNumber() const { return (isNumber() ? *this : valueToNumber(*this)); }
|
||||
JSValue toInt32() const { return ((tag == i32_tag) ? *this : valueToInt32(*this)); }
|
||||
JSValue toUInt32() const { return ((tag == u32_tag) ? *this : valueToUInt32(*this)); }
|
||||
JSValue toBoolean() const { return ((tag == boolean_tag) ? *this : valueToBoolean(*this)); }
|
||||
|
||||
JSValue toPrimitive(ECMA_type hint = NoHint) const;
|
||||
|
||||
JSValue convert(JSType *toType);
|
||||
|
||||
|
||||
static JSValue valueToString(const JSValue& value);
|
||||
static JSValue valueToNumber(const JSValue& value);
|
||||
static JSValue valueToInteger(const JSValue& value);
|
||||
static JSValue valueToInt32(const JSValue& value);
|
||||
static JSValue valueToUInt32(const JSValue& value);
|
||||
static JSValue valueToBoolean(const JSValue& value);
|
||||
|
||||
|
||||
const JSType *getType() const; // map from tag type to JS2 type
|
||||
|
||||
int operator==(const JSValue& value) const;
|
||||
};
|
||||
|
||||
Formatter& operator<<(Formatter& f, const JSValue& value);
|
||||
|
||||
#if defined(XP_MAC)
|
||||
// copied from default template parameters in map.
|
||||
typedef gc_allocator<std::pair<const String, JSValue> > gc_map_allocator;
|
||||
#elif defined(XP_UNIX)
|
||||
// FIXME: in libg++, they assume the map's allocator is a byte allocator,
|
||||
// which is wrapped in a simple_allocator. this is crap.
|
||||
typedef char _Char[1];
|
||||
typedef gc_allocator<_Char> gc_map_allocator;
|
||||
#elif defined(_WIN32)
|
||||
// FIXME: MSVC++'s notion. this is why we had to add _Charalloc().
|
||||
typedef gc_allocator<JSValue> gc_map_allocator;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* GC-scannable array of values.
|
||||
*/
|
||||
typedef std::vector<JSValue, gc_allocator<JSValue> > JSValues;
|
||||
|
||||
extern const JSValue kUndefinedValue;
|
||||
extern const JSValue kNaNValue;
|
||||
extern const JSValue kTrueValue;
|
||||
extern const JSValue kFalseValue;
|
||||
extern const JSValue kNullValue;
|
||||
extern const JSValue kNegativeZero;
|
||||
extern const JSValue kPositiveZero;
|
||||
extern const JSValue kNegativeInfinity;
|
||||
extern const JSValue kPositiveInfinity;
|
||||
|
||||
extern JSType Any_Type;
|
||||
extern JSType Integer_Type;
|
||||
extern JSType Number_Type;
|
||||
extern JSType Character_Type;
|
||||
extern JSType String_Type;
|
||||
extern JSType Function_Type;
|
||||
extern JSType Array_Type;
|
||||
extern JSType Type_Type;
|
||||
extern JSType Boolean_Type;
|
||||
extern JSType Null_Type;
|
||||
extern JSType Void_Type;
|
||||
extern JSType None_Type;
|
||||
|
||||
typedef std::map<String, JSValue, std::less<String>, gc_map_allocator> JSProperties;
|
||||
|
||||
/**
|
||||
* Basic behavior of all JS objects, mapping a name to a value,
|
||||
* with prototype-based inheritance.
|
||||
*/
|
||||
class JSObject : public gc_base {
|
||||
protected:
|
||||
JSProperties mProperties;
|
||||
JSObject* mPrototype;
|
||||
JSType* mType;
|
||||
JSString* mClass; // this is the internal [[Class]] property
|
||||
|
||||
static JSObject *initJSObject();
|
||||
static String ObjectString;
|
||||
static JSObject *objectPrototypeObject;
|
||||
|
||||
void init(JSObject* prototype);
|
||||
|
||||
public:
|
||||
JSObject() { init(objectPrototypeObject); }
|
||||
JSObject(JSValue &constructor) { init(constructor.object->getProperty(widenCString("prototype")).object); }
|
||||
JSObject(JSObject *prototype) { init(prototype); }
|
||||
|
||||
static void initObjectObject(JSScope *g);
|
||||
|
||||
bool hasProperty(const String& name)
|
||||
{
|
||||
return (mProperties.count(name) != 0);
|
||||
}
|
||||
|
||||
const JSValue& getProperty(const String& name)
|
||||
{
|
||||
JSProperties::const_iterator i = mProperties.find(name);
|
||||
if (i != mProperties.end())
|
||||
return i->second;
|
||||
if (mPrototype)
|
||||
return mPrototype->getProperty(name);
|
||||
return kUndefinedValue;
|
||||
}
|
||||
|
||||
// return the property AND the object it's found in
|
||||
// (would rather return references, but couldn't get that to work)
|
||||
const JSValue getReference(JSValue &prop, const String& name)
|
||||
{
|
||||
JSProperties::const_iterator i = mProperties.find(name);
|
||||
if (i != mProperties.end()) {
|
||||
prop = i->second;
|
||||
return JSValue(this);
|
||||
}
|
||||
if (mPrototype)
|
||||
return mPrototype->getReference(prop, name);
|
||||
return kUndefinedValue;
|
||||
}
|
||||
|
||||
JSValue& setProperty(const String& name, const JSValue& value)
|
||||
{
|
||||
return (mProperties[name] = value);
|
||||
}
|
||||
|
||||
const JSValue& deleteProperty(const String& name)
|
||||
{
|
||||
JSProperties::iterator i = mProperties.find(name);
|
||||
if (i != mProperties.end()) {
|
||||
mProperties.erase(i);
|
||||
return kTrueValue;
|
||||
}
|
||||
if (mPrototype)
|
||||
return mPrototype->deleteProperty(name);
|
||||
return kFalseValue;
|
||||
}
|
||||
|
||||
void setPrototype(JSObject* prototype)
|
||||
{
|
||||
mPrototype = prototype;
|
||||
}
|
||||
|
||||
JSObject* getPrototype()
|
||||
{
|
||||
return mPrototype;
|
||||
}
|
||||
|
||||
JSType* getType()
|
||||
{
|
||||
return mType;
|
||||
}
|
||||
|
||||
JSString* getClass()
|
||||
{
|
||||
return mClass;
|
||||
}
|
||||
|
||||
void setClass(JSString* s)
|
||||
{
|
||||
mClass = s;
|
||||
}
|
||||
|
||||
virtual void printProperties(Formatter& f);
|
||||
};
|
||||
|
||||
Formatter& operator<<(Formatter& f, JSObject& obj);
|
||||
|
||||
/**
|
||||
* Private representation of a JavaScript array.
|
||||
*/
|
||||
class JSArray : public JSObject {
|
||||
JSValues elements;
|
||||
public:
|
||||
JSArray() : elements(1) {}
|
||||
JSArray(uint32 size) : elements(size) {}
|
||||
JSArray(const JSValues &v) : elements(v) {}
|
||||
|
||||
uint32 length()
|
||||
{
|
||||
return elements.size();
|
||||
}
|
||||
|
||||
JSValue& operator[](const JSValue& index)
|
||||
{
|
||||
// for now, we can only handle f64 index values.
|
||||
uint32 n = (uint32)index.f64;
|
||||
// obviously, a sparse representation might be better.
|
||||
uint32 size = elements.size();
|
||||
if (n >= size) expand(n, size);
|
||||
return elements[n];
|
||||
}
|
||||
|
||||
JSValue& operator[](uint32 n)
|
||||
{
|
||||
// obviously, a sparse representation might be better.
|
||||
uint32 size = elements.size();
|
||||
if (n >= size) expand(n, size);
|
||||
return elements[n];
|
||||
}
|
||||
|
||||
void resize(uint32 size)
|
||||
{
|
||||
elements.resize(size);
|
||||
}
|
||||
|
||||
private:
|
||||
void expand(uint32 n, uint32 size)
|
||||
{
|
||||
do {
|
||||
size *= 2;
|
||||
} while (n >= size);
|
||||
elements.resize(size);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Private representation of a JS function. This simply
|
||||
* holds a reference to the iCode module that is the
|
||||
* compiled code of the function.
|
||||
*/
|
||||
class JSFunction : public JSObject {
|
||||
static String FunctionString;
|
||||
static JSObject *functionPrototypeObject;
|
||||
ICodeModule* mICode;
|
||||
protected:
|
||||
JSFunction() : mICode(0) {}
|
||||
|
||||
typedef JavaScript::gc_traits_finalizable<JSFunction> traits;
|
||||
typedef gc_allocator<JSFunction, traits> allocator;
|
||||
|
||||
public:
|
||||
static void JSFunction::initFunctionObject(JSScope *g);
|
||||
|
||||
JSFunction(ICodeModule* iCode);
|
||||
~JSFunction();
|
||||
|
||||
void* operator new(size_t) { return allocator::allocate(1); }
|
||||
|
||||
ICodeModule* getICode() { return mICode; }
|
||||
virtual bool isNative() { return false; }
|
||||
};
|
||||
|
||||
class JSNativeFunction : public JSFunction {
|
||||
public:
|
||||
typedef JSValue (*JSCode)(Context *cx, const JSValues& argv);
|
||||
JSCode mCode;
|
||||
JSNativeFunction(JSCode code) : mCode(code) {}
|
||||
virtual bool isNative() { return true; }
|
||||
};
|
||||
|
||||
class JSBinaryOperator : public JSFunction {
|
||||
public:
|
||||
typedef JSValue (*JSBinaryCode)(const JSValue& arg1, const JSValue& arg2);
|
||||
JSBinaryCode mCode;
|
||||
JSBinaryOperator(JSBinaryCode code) : mCode(code) {}
|
||||
virtual bool isNative() { return true; }
|
||||
};
|
||||
|
||||
#ifndef STLPORT
|
||||
# if defined(XP_UNIX)
|
||||
// bastring.cc defines a funky operator new that assumes a byte-allocator.
|
||||
typedef string_char_traits<char16> JSCharTraits;
|
||||
typedef gc_allocator<_Char> JSStringAllocator;
|
||||
# else
|
||||
typedef std::char_traits<char16> JSCharTraits;
|
||||
typedef gc_allocator<char16> JSStringAllocator;
|
||||
# endif
|
||||
#else
|
||||
typedef std::char_traits<char16> JSCharTraits;
|
||||
typedef gc_allocator<char16> JSStringAllocator;
|
||||
#endif
|
||||
|
||||
typedef std::basic_string<char16, JSCharTraits, JSStringAllocator> JSStringBase;
|
||||
|
||||
/**
|
||||
* Garbage collectable UNICODE string.
|
||||
*/
|
||||
class JSString : public JSStringBase, public gc_base {
|
||||
public:
|
||||
JSString() {}
|
||||
explicit JSString(const JSStringBase& str) : JSStringBase(str) {}
|
||||
explicit JSString(const JSStringBase* str) : JSStringBase(*str) {}
|
||||
explicit JSString(const String& str);
|
||||
explicit JSString(const String* str);
|
||||
explicit JSString(const char* str);
|
||||
|
||||
operator String();
|
||||
|
||||
void append(const char* str);
|
||||
void append(const JSStringBase* str);
|
||||
};
|
||||
|
||||
class JSException : public gc_base {
|
||||
public:
|
||||
JSException(char *mess) : value(JSValue(new JSString(mess))) { }
|
||||
JSException(JSValue v) : value(v) { }
|
||||
JSValue value;
|
||||
};
|
||||
|
||||
inline Formatter& operator<<(Formatter& f, const JSString& str)
|
||||
{
|
||||
printString(f, str.begin(), str.end());
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a set of nested scopes.
|
||||
*/
|
||||
class JSScope : public JSObject {
|
||||
protected:
|
||||
JSScope* mParent;
|
||||
JSProperties mTypes;
|
||||
public:
|
||||
JSScope(JSScope* parent = 0, JSObject* prototype = 0)
|
||||
: mParent(parent)
|
||||
{
|
||||
if (prototype)
|
||||
setPrototype(prototype);
|
||||
}
|
||||
|
||||
JSScope* getParent()
|
||||
{
|
||||
return mParent;
|
||||
}
|
||||
|
||||
bool isDefined(const String& name)
|
||||
{
|
||||
if (hasProperty(name))
|
||||
return true;
|
||||
if (mParent)
|
||||
return mParent->isDefined(name);
|
||||
return false;
|
||||
}
|
||||
|
||||
const JSValue& getVariable(const String& name)
|
||||
{
|
||||
const JSValue& ret = getProperty(name);
|
||||
if (ret.isUndefined() && mParent)
|
||||
return mParent->getVariable(name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
JSValue& setVariable(const String& name, const JSValue& value)
|
||||
{
|
||||
return (mProperties[name] = value);
|
||||
}
|
||||
|
||||
JSValue& defineVariable(const String& name, JSType* type, const JSValue& value)
|
||||
{
|
||||
if (type != &Any_Type)
|
||||
mTypes[name] = type;
|
||||
return (mProperties[name] = value);
|
||||
}
|
||||
|
||||
JSValue& defineVariable(const String& name, JSType* type)
|
||||
{
|
||||
if (type != &Any_Type)
|
||||
mTypes[name] = type;
|
||||
return (mProperties[name] = kUndefinedValue);
|
||||
}
|
||||
|
||||
void setType(const String& name, JSType* type)
|
||||
{
|
||||
// only type variables that are defined in this scope.
|
||||
JSProperties::iterator i = mProperties.find(name);
|
||||
if (i != mProperties.end())
|
||||
mTypes[name] = type;
|
||||
else
|
||||
if (mParent)
|
||||
mParent->setType(name, type);
|
||||
}
|
||||
|
||||
JSType* getType(const String& name)
|
||||
{
|
||||
JSType* result = &Any_Type;
|
||||
// only consider types for variables defined in this scope.
|
||||
JSProperties::const_iterator i = mProperties.find(name);
|
||||
if (i != mProperties.end()) {
|
||||
i = mTypes.find(name);
|
||||
if (i != mTypes.end())
|
||||
result = i->second.type;
|
||||
} else {
|
||||
// see if variable is defined in parent scope.
|
||||
if (mParent)
|
||||
result = mParent->getType(name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
JSValue& defineFunction(const String& name, ICodeModule* iCode)
|
||||
{
|
||||
JSValue value(new JSFunction(iCode));
|
||||
return defineVariable(name, &Function_Type, value);
|
||||
}
|
||||
|
||||
JSValue& defineNativeFunction(const String& name, JSNativeFunction::JSCode code)
|
||||
{
|
||||
JSValue value(new JSNativeFunction(code));
|
||||
return defineVariable(name, &Function_Type, value);
|
||||
}
|
||||
};
|
||||
|
||||
class JSType : public JSObject {
|
||||
protected:
|
||||
String mName;
|
||||
JSType *mBaseType;
|
||||
public:
|
||||
JSType(const String &name, JSType *baseType) : mName(name), mBaseType(baseType)
|
||||
{
|
||||
mType = &Type_Type;
|
||||
}
|
||||
|
||||
enum { NoRelation = 0x7FFFFFFF };
|
||||
|
||||
const String& getName() const { return mName; }
|
||||
|
||||
int32 distance(const JSType *other) const;
|
||||
};
|
||||
|
||||
|
||||
inline void JSObject::init(JSObject* prototype) { mPrototype = prototype; mType = &Any_Type; mClass = new JSString(ObjectString); }
|
||||
|
||||
inline JSFunction::JSFunction(ICodeModule* iCode) : mICode(iCode), JSObject(functionPrototypeObject) { setClass(new JSString(FunctionString)); }
|
||||
|
||||
|
||||
} /* namespace JSTypes */
|
||||
} /* namespace JavaScript */
|
||||
|
||||
|
||||
#endif /* jstypes_h */
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -1,2 +0,0 @@
|
||||
#define XP_MAC 1
|
||||
#define XP_MAC_MPW 1
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
MacOS_config.h
|
||||
|
||||
Configuration flags for Macintosh development systems.
|
||||
|
||||
<Revision History>
|
||||
|
||||
11/16/95 pcb Updated compilation flags to reflect latest 4.6 Makefile.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
/* Boehm, November 17, 1995 12:10 pm PST */
|
||||
|
||||
#ifdef __MWERKS__
|
||||
|
||||
// for CodeWarrior Pro with Metrowerks Standard Library (MSL).
|
||||
// #define MSL_USE_PRECOMPILED_HEADERS 0
|
||||
#include <ansi_prefix.mac.h>
|
||||
#ifndef __STDC__
|
||||
#define __STDC__ 0
|
||||
#endif
|
||||
|
||||
#endif /* __MWERKS__ */
|
||||
|
||||
// these are defined again in gc_priv.h.
|
||||
#undef TRUE
|
||||
#undef FALSE
|
||||
|
||||
#define ALL_INTERIOR_POINTERS // follows interior pointers.
|
||||
#define SILENT // no collection messages.
|
||||
//#define DONT_ADD_BYTE_AT_END // no padding.
|
||||
//#define SMALL_CONFIG // whether to use a smaller heap.
|
||||
#define NO_SIGNALS // signals aren't real on the Macintosh.
|
||||
#define USE_TEMPORARY_MEMORY // use Macintosh temporary memory.
|
||||
//#define FIND_LEAK // use as a leak detector.
|
||||
//#define LARGE_CONFIG // try a big heap, for fun.
|
||||
|
||||
// CFLAGS= -O -DNO_SIGNALS -DSILENT -DALL_INTERIOR_POINTERS
|
||||
//
|
||||
//LIBGC_CFLAGS= -O -DNO_SIGNALS -DSILENT \
|
||||
// -DREDIRECT_MALLOC=GC_malloc_uncollectable \
|
||||
// -DDONT_ADD_BYTE_AT_END -DALL_INTERIOR_POINTERS
|
||||
// Flags for building libgc.a -- the last two are required.
|
||||
//
|
||||
// Setjmp_test may yield overly optimistic results when compiled
|
||||
// without optimization.
|
||||
// -DSILENT disables statistics printing, and improves performance.
|
||||
// -DCHECKSUMS reports on erroneously clear dirty bits, and unexpectedly
|
||||
// altered stubborn objects, at substantial performance cost.
|
||||
// Use only for incremental collector debugging.
|
||||
// -DFIND_LEAK causes the collector to assume that all inaccessible
|
||||
// objects should have been explicitly deallocated, and reports exceptions.
|
||||
// Finalization and the test program are not usable in this mode.
|
||||
// -DSOLARIS_THREADS enables support for Solaris (thr_) threads.
|
||||
// (Clients should also define SOLARIS_THREADS and then include
|
||||
// gc.h before performing thr_ or GC_ operations.)
|
||||
// This is broken on nonSPARC machines.
|
||||
// -DALL_INTERIOR_POINTERS allows all pointers to the interior
|
||||
// of objects to be recognized. (See gc_priv.h for consequences.)
|
||||
// -DSMALL_CONFIG tries to tune the collector for small heap sizes,
|
||||
// usually causing it to use less space in such situations.
|
||||
// Incremental collection no longer works in this case.
|
||||
// -DLARGE_CONFIG tunes the collector for unusually large heaps.
|
||||
// Necessary for heaps larger than about 500 MB on most machines.
|
||||
// Recommended for heaps larger than about 64 MB.
|
||||
// -DDONT_ADD_BYTE_AT_END is meaningful only with
|
||||
// -DALL_INTERIOR_POINTERS. Normally -DALL_INTERIOR_POINTERS
|
||||
// causes all objects to be padded so that pointers just past the end of
|
||||
// an object can be recognized. This can be expensive. (The padding
|
||||
// is normally more than one byte due to alignment constraints.)
|
||||
// -DDONT_ADD_BYTE_AT_END disables the padding.
|
||||
// -DNO_SIGNALS does not disable signals during critical parts of
|
||||
// the GC process. This is no less correct than many malloc
|
||||
// implementations, and it sometimes has a significant performance
|
||||
// impact. However, it is dangerous for many not-quite-ANSI C
|
||||
// programs that call things like printf in asynchronous signal handlers.
|
||||
// -DOPERATOR_NEW_ARRAY declares that the C++ compiler supports the
|
||||
// new syntax "operator new[]" for allocating and deleting arrays.
|
||||
// See gc_cpp.h for details. No effect on the C part of the collector.
|
||||
// This is defined implicitly in a few environments.
|
||||
// -DREDIRECT_MALLOC=X causes malloc, realloc, and free to be defined
|
||||
// as aliases for X, GC_realloc, and GC_free, respectively.
|
||||
// Calloc is redefined in terms of the new malloc. X should
|
||||
// be either GC_malloc or GC_malloc_uncollectable.
|
||||
// The former is occasionally useful for working around leaks in code
|
||||
// you don't want to (or can't) look at. It may not work for
|
||||
// existing code, but it often does. Neither works on all platforms,
|
||||
// since some ports use malloc or calloc to obtain system memory.
|
||||
// (Probably works for UNIX, and win32.)
|
||||
// -DNO_DEBUG removes GC_dump and the debugging routines it calls.
|
||||
// Reduces code size slightly at the expense of debuggability.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,153 +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.1 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of
|
||||
// the License at http://www.mozilla.org/NPL/
|
||||
//
|
||||
// Software distributed under the License is distributed on an "AS
|
||||
// IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
// implied. See the License for the specific language governing
|
||||
// rights and limitations under the License.
|
||||
//
|
||||
// The Original Code is the JavaScript 2 Prototype.
|
||||
//
|
||||
// The Initial Developer of the Original Code is Netscape
|
||||
// Communications Corporation. Portions created by Netscape are
|
||||
// Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
// Rights Reserved.
|
||||
|
||||
#ifndef numerics_h
|
||||
#define numerics_h
|
||||
|
||||
#include "utilities.h"
|
||||
#include <cmath>
|
||||
|
||||
/* Use platform-defined floating-point routines.
|
||||
* On platforms with faulty floating-point code
|
||||
* ifdef these out and replace by custom implementations. */
|
||||
|
||||
#ifndef STLPORT
|
||||
# ifndef _WIN32
|
||||
using std::abs;
|
||||
using std::floor;
|
||||
using std::ceil;
|
||||
using std::fmod;
|
||||
using std::sqrt;
|
||||
using std::sin;
|
||||
using std::cos;
|
||||
using std::tan;
|
||||
using std::asin;
|
||||
using std::acos;
|
||||
using std::atan;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace JavaScript {
|
||||
|
||||
//
|
||||
// Double-precision constants
|
||||
//
|
||||
|
||||
extern double positiveInfinity;
|
||||
extern double negativeInfinity;
|
||||
extern double nan;
|
||||
|
||||
//
|
||||
// Portable double-precision floating point to string and back conversions
|
||||
//
|
||||
|
||||
double ulp(double x);
|
||||
int hi0bits(uint32 x);
|
||||
|
||||
class BigInt {
|
||||
enum {maxLgGrossSize = 15}; // Maximum value of lg2(grossSize)
|
||||
static uint32 *freeLists[maxLgGrossSize+1];
|
||||
|
||||
uint lgGrossSize; // lg2(grossSize)
|
||||
public:
|
||||
bool negative; // True if negative. Ignored by most BigInt routines!
|
||||
private:
|
||||
uint32 grossSize; // Number of words allocated for <words>
|
||||
uint32 size; // Actual number of words. If the number is nonzero, the most significant word must be nonzero.
|
||||
// If the number is zero, then size is also 0.
|
||||
uint32 *words; // <size> words of the number, in little endian order
|
||||
|
||||
void allocate(uint lgGrossSize);
|
||||
void recycle();
|
||||
void initCopy(const BigInt &b);
|
||||
void move(BigInt &b);
|
||||
public:
|
||||
BigInt(): words(0) {}
|
||||
explicit BigInt(uint lgGrossSize) {allocate(lgGrossSize);}
|
||||
BigInt(const BigInt &b) {initCopy(b);}
|
||||
void operator=(const BigInt &b) {ASSERT(!words); initCopy(b);}
|
||||
~BigInt() {if (words) recycle();}
|
||||
|
||||
void setLgGrossSize(uint lgGrossSize);
|
||||
void init(uint32 i);
|
||||
void init(double d, int32 &e, int32 &bits);
|
||||
void mulAdd(uint m, uint a);
|
||||
void operator*=(const BigInt &m);
|
||||
void pow2Mul(int32 k);
|
||||
void pow5Mul(int32 k);
|
||||
bool isZero() const {ASSERT(words); return !size;}
|
||||
int cmp(const BigInt &b) const;
|
||||
void initDiff(const BigInt &m, const BigInt &n);
|
||||
uint32 quoRem2(int32 k);
|
||||
int32 quoRem(const BigInt &S);
|
||||
uint32 divRem(uint32 divisor);
|
||||
double b2d(int32 &e) const;
|
||||
double ratio(const BigInt &denominator) const;
|
||||
void s2b(const char *s, int32 nd0, int32 nd, uint32 y9);
|
||||
|
||||
uint32 nWords() const {return size;}
|
||||
uint32 word(uint32 i) const {ASSERT(i < size); return words[i];}
|
||||
};
|
||||
|
||||
|
||||
// Modes for converting floating-point numbers to strings.
|
||||
//
|
||||
// Some of the modes can round-trip; this means that if the number is converted to
|
||||
// a string using one of these mode and then converted back to a number, the result
|
||||
// will be identical to the original number (except that, due to ECMA, -0 will get converted
|
||||
// to +0). These round-trip modes return the minimum number of significand digits that
|
||||
// permit the round trip.
|
||||
//
|
||||
// Some of the modes take an integer parameter <precision>.
|
||||
//
|
||||
// Keep this in sync with doubleToAsciiModes[].
|
||||
enum DToStrMode {
|
||||
dtosStandard, // Either fixed or exponential format; round-trip
|
||||
dtosStandardExponential, // Always exponential format; round-trip
|
||||
dtosFixed, // Round to <precision> digits after the decimal point; exponential if number is large
|
||||
dtosExponential, // Always exponential format; <precision> significant digits
|
||||
dtosPrecision // Either fixed or exponential format; <precision> significant digits
|
||||
};
|
||||
|
||||
|
||||
// Maximum number of characters (including trailing null) that a dtosStandard or dtosStandardExponential
|
||||
// conversion can produce. This maximum is reached for a number like -1.2345678901234567e+123.
|
||||
const int dtosStandardBufferSize = 25;
|
||||
|
||||
// Maximum number of characters (including trailing null) that one of the other conversions
|
||||
// can produce. This maximum is reached for TO_FIXED, which can generate up to 21 digits before the decimal point.
|
||||
#define dtosVariableBufferSize(precision) ((precision)+24 > dtosStandardBufferSize ? (precision)+24 : dtosStandardBufferSize)
|
||||
|
||||
// "-0.0000...(1073 zeros after decimal point)...0001\0" is the longest string that we could produce,
|
||||
// which occurs when printing -5e-324 in binary. We could compute a better estimate of the size of
|
||||
// the output string and malloc fewer bytes depending on d and base, but why bother?
|
||||
const int dtobasesBufferSize = 1078;
|
||||
|
||||
double strToDouble(const char *str, const char *&numEnd);
|
||||
double stringToDouble(const char16 *str, const char16 *strEnd, const char16 *&numEnd);
|
||||
double stringToInteger(const char16 *str, const char16 *strEnd, const char16 *&numEnd, uint base);
|
||||
|
||||
char *doubleToStr(char *buffer, size_t bufferSize, double value, DToStrMode mode, int precision);
|
||||
size_t doubleToBaseStr(char *buffer, double value, uint base);
|
||||
void appendDouble(String &dst, double value, DToStrMode mode = dtosStandard, int precision = 0);
|
||||
inline String &operator+=(String &s, double value) {appendDouble(s, value); return s;}
|
||||
void printDouble(Formatter &f, double value, DToStrMode mode = dtosStandard, int precision = 0);
|
||||
inline Formatter &operator<<(Formatter &f, double value) {printDouble(f, value); return f;}
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,93 +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.1 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of
|
||||
// the License at http://www.mozilla.org/NPL/
|
||||
//
|
||||
// Software distributed under the License is distributed on an "AS
|
||||
// IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
// implied. See the License for the specific language governing
|
||||
// rights and limitations under the License.
|
||||
//
|
||||
// The Original Code is the JavaScript 2 Prototype.
|
||||
//
|
||||
// The Initial Developer of the Original Code is Netscape
|
||||
// Communications Corporation. Portions created by Netscape are
|
||||
// Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
// Rights Reserved.
|
||||
|
||||
#ifndef systemtypes_h
|
||||
#define systemtypes_h
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#ifdef _WIN32
|
||||
// Turn off warnings about identifiers too long in browser information
|
||||
#pragma warning(disable: 4786)
|
||||
#endif
|
||||
|
||||
// Define int8, int16, int32, int64, uint8, uint16, uint32, uint64, and uint.
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned char uchar;
|
||||
|
||||
typedef signed char int8;
|
||||
typedef unsigned char uint8;
|
||||
typedef short int16;
|
||||
typedef unsigned short uint16;
|
||||
#if !defined(XP_MAC) && !defined(_WIN32)
|
||||
typedef int int32;
|
||||
typedef unsigned int uint32;
|
||||
#else
|
||||
typedef long int32;
|
||||
typedef unsigned long uint32;
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
typedef __int64 int64;
|
||||
typedef unsigned __int64 uint64;
|
||||
#else
|
||||
typedef long long int64;
|
||||
typedef unsigned long long uint64;
|
||||
#endif
|
||||
|
||||
// Define this if the machine natively supports 64-bit integers
|
||||
#define NATIVE_INT64
|
||||
|
||||
// Define float32 and float64.
|
||||
typedef double float64;
|
||||
typedef float float32;
|
||||
|
||||
// A UTF-16 character
|
||||
// Use wchar_t on platforms on which wchar_t has 16 bits; otherwise use int16.
|
||||
// Note that in C++ wchar_t is a distinct type rather than a typedef for some integral type.
|
||||
// Like char, a char16 can be either signed or unsigned at the implementation's discretion.
|
||||
#ifdef __GNUC__
|
||||
// GCC's wchar_t is 32 bits, so we can't use it.
|
||||
typedef uint16 char16;
|
||||
typedef uint16 uchar16;
|
||||
#else
|
||||
typedef wchar_t char16;
|
||||
#ifndef _WIN32 // Microsoft VC6 bug: wchar_t should be a built-in type, not a typedef
|
||||
typedef unsigned wchar_t uchar16;
|
||||
#else
|
||||
typedef wchar_t uchar16;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
#ifdef __i386__
|
||||
#define IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
|
||||
// basicAlignment is the maximum alignment required by any native type. An object aligned to
|
||||
// a multiple of basicAlignment can hold any native type. malloc should return a pointer whose
|
||||
// lgBasicAlignment least significant bits are clear.
|
||||
// Currently basicAlignment is set to 8 to allow doubles and int64s to have their natural alignment;
|
||||
// may be customized for individual platforms.
|
||||
const uint lgBasicAlignment = 3;
|
||||
const uint basicAlignment = 1u<<lgBasicAlignment;
|
||||
|
||||
#endif /* systemtypes_h */
|
||||
@@ -1,28 +0,0 @@
|
||||
class A {
|
||||
static var x = 0;
|
||||
|
||||
static function f()
|
||||
{
|
||||
return A.x++;
|
||||
}
|
||||
}
|
||||
|
||||
class Point3D {
|
||||
var x = 0, y = 0, z = 0;
|
||||
|
||||
function set(x, y, z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
return this;
|
||||
}
|
||||
|
||||
function setX(x) { this.x = x; }
|
||||
function getX() { return this.x; }
|
||||
|
||||
function setY(y) { this.y = y; }
|
||||
function getY() { return this.y; }
|
||||
|
||||
function setZ(z) { this.z = z; }
|
||||
function getZ() { return this.z; }
|
||||
}
|
||||
@@ -1,596 +0,0 @@
|
||||
#!perl
|
||||
|
||||
use strict;
|
||||
|
||||
my $tab = " ";
|
||||
my $init_tab = $tab;
|
||||
my $enum_decs = "";
|
||||
my $class_decs = "";
|
||||
my @name_array;
|
||||
my $opcode_maxlen = 0;
|
||||
|
||||
#
|
||||
# fields are:
|
||||
#
|
||||
# * super: Class to inherit from, if super is Instruction_(1|2|3), the script
|
||||
# will automatically append the correct template info based on |params|
|
||||
# * super_has_print: Set to 1 if you want to inherit the print() and print_args()
|
||||
# methods from the superclass, set to 0 (or just don't set)
|
||||
# to generate print methods.
|
||||
# * rem: Remark you want to show up after the enum def, and inside the class.
|
||||
# * params: The parameter list expected by the constructor, you can specify a
|
||||
# default value, using the syntax, [ ("Type = default") ].
|
||||
#
|
||||
# class names will be generated based on the opcode mnemonic. See the
|
||||
# subroutine get_classname for the implementation. Basically underscores will
|
||||
# be removes and the class name will be WordCapped, using the positions where the
|
||||
# underscores were as word boundries. The only exception occurs when a word is
|
||||
# two characters, in which case both characters will be capped,
|
||||
# as in BRANCH_GT -> BranchGT.
|
||||
#
|
||||
|
||||
#
|
||||
# template definitions for compare, arithmetic, and conditional branch ops
|
||||
#
|
||||
my $binary_op =
|
||||
{
|
||||
super => "Instruction_3",
|
||||
super_has_print => 1,
|
||||
rem => "dest, source1, source2",
|
||||
params => [ ("TypedRegister", "TypedRegister", "TypedRegister") ]
|
||||
};
|
||||
|
||||
my $math_op =
|
||||
{
|
||||
super => "Arithmetic",
|
||||
super_has_print => 1,
|
||||
rem => "dest, source1, source2",
|
||||
params => [ ("TypedRegister", "TypedRegister", "TypedRegister") ]
|
||||
};
|
||||
|
||||
my $cbranch_op =
|
||||
{
|
||||
super => "GenericBranch",
|
||||
super_has_print => 1,
|
||||
rem => "target label, condition",
|
||||
params => [ ("Label*", "TypedRegister") ]
|
||||
};
|
||||
|
||||
my $unary_op =
|
||||
{
|
||||
super => "Instruction_2",
|
||||
rem => "dest, source",
|
||||
params => [ ("TypedRegister", "TypedRegister") ]
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# op defititions
|
||||
#
|
||||
my %ops;
|
||||
$ops{"NOP"} =
|
||||
{
|
||||
super => "Instruction",
|
||||
rem => "do nothing and like it",
|
||||
};
|
||||
$ops{"DEBUGGER"} =
|
||||
{
|
||||
super => "Instruction",
|
||||
rem => "drop to the debugger",
|
||||
};
|
||||
$ops{"GENERIC_BINARY_OP"} =
|
||||
{
|
||||
super => "Instruction_4",
|
||||
rem => "dest, op, source1, source2",
|
||||
params => [ ("TypedRegister", "BinaryOperator::BinaryOp", "TypedRegister", "TypedRegister") ]
|
||||
};
|
||||
$ops{"MOVE"} =
|
||||
{
|
||||
super => "Instruction_2",
|
||||
rem => "dest, source",
|
||||
params => [ ("TypedRegister", "TypedRegister") ]
|
||||
};
|
||||
$ops{"LOAD_IMMEDIATE"} =
|
||||
{
|
||||
super => "Instruction_2",
|
||||
rem => "dest, immediate value (double)",
|
||||
params => [ ("TypedRegister", "double" ) ]
|
||||
};
|
||||
$ops{"LOAD_BOOLEAN"} =
|
||||
{
|
||||
super => "Instruction_2",
|
||||
rem => "dest, immediate value (boolean)",
|
||||
params => [ ("TypedRegister", "bool" ) ]
|
||||
};
|
||||
$ops{"LOAD_STRING"} =
|
||||
{
|
||||
super => "Instruction_2",
|
||||
rem => "dest, immediate value (string)",
|
||||
params => [ ("TypedRegister", "JSString*" ) ]
|
||||
};
|
||||
$ops{"LOAD_NAME"} =
|
||||
{
|
||||
super => "Instruction_2",
|
||||
rem => "dest, name",
|
||||
params => [ ("TypedRegister", "const StringAtom*" ) ]
|
||||
};
|
||||
$ops{"SUPER"} =
|
||||
{
|
||||
super => "Instruction_1",
|
||||
rem => "dest",
|
||||
params => [ ("TypedRegister" ) ]
|
||||
};
|
||||
$ops{"SAVE_NAME"} =
|
||||
{
|
||||
super => "Instruction_2",
|
||||
rem => "name, source",
|
||||
params => [ ("const StringAtom*", "TypedRegister") ]
|
||||
};
|
||||
$ops{"NEW_OBJECT"} =
|
||||
{
|
||||
super => "Instruction_2",
|
||||
rem => "dest, constructor",
|
||||
params => [ ("TypedRegister", "TypedRegister") ]
|
||||
};
|
||||
$ops{"NEW_CLASS"} =
|
||||
{
|
||||
super => "Instruction_2",
|
||||
rem => "dest, class",
|
||||
params => [ ("TypedRegister", "JSClass*") ]
|
||||
};
|
||||
$ops{"NEW_FUNCTION"} =
|
||||
{
|
||||
super => "Instruction_2",
|
||||
rem => "dest, ICodeModule",
|
||||
params => [ ("TypedRegister", "ICodeModule*") ]
|
||||
};
|
||||
$ops{"NEW_ARRAY"} =
|
||||
{
|
||||
super => "Instruction_1",
|
||||
rem => "dest",
|
||||
params => [ ("TypedRegister") ]
|
||||
};
|
||||
$ops{"DELETE_PROP"} =
|
||||
{
|
||||
super => "Instruction_3",
|
||||
rem => "dest, object, prop name",
|
||||
params => [ ("TypedRegister", "TypedRegister", "const StringAtom*") ]
|
||||
};
|
||||
$ops{"GET_PROP"} =
|
||||
{
|
||||
super => "Instruction_3",
|
||||
rem => "dest, object, prop name",
|
||||
params => [ ("TypedRegister", "TypedRegister", "const StringAtom*") ]
|
||||
};
|
||||
$ops{"SET_PROP"} =
|
||||
{
|
||||
super => "Instruction_3",
|
||||
rem => "object, name, source",
|
||||
params => [ ("TypedRegister", "const StringAtom*", "TypedRegister") ]
|
||||
};
|
||||
$ops{"GET_SLOT"} =
|
||||
{
|
||||
super => "Instruction_3",
|
||||
rem => "dest, object, slot number",
|
||||
params => [ ("TypedRegister", "TypedRegister", "uint32") ]
|
||||
};
|
||||
$ops{"SET_SLOT"} =
|
||||
{
|
||||
super => "Instruction_3",
|
||||
rem => "object, slot number, source",
|
||||
params => [ ("TypedRegister", "uint32", "TypedRegister") ]
|
||||
};
|
||||
$ops{"GET_STATIC"} =
|
||||
{
|
||||
super => "Instruction_3",
|
||||
rem => "dest, class, index",
|
||||
params => [ ("TypedRegister", "JSClass*", "uint32") ]
|
||||
};
|
||||
$ops{"SET_STATIC"} =
|
||||
{
|
||||
super => "Instruction_3",
|
||||
rem => "class, index, source",
|
||||
params => [ ("JSClass*", "uint32", "TypedRegister") ]
|
||||
};
|
||||
$ops{"STATIC_XCR"} =
|
||||
{
|
||||
super => "Instruction_4",
|
||||
rem => "dest, class, index, value",
|
||||
params => [ ("TypedRegister", "JSClass*", "uint32", "double") ]
|
||||
};
|
||||
$ops{"SLOT_XCR"} =
|
||||
{
|
||||
super => "Instruction_4",
|
||||
rem => "dest, source, slot number, value",
|
||||
params => [ ("TypedRegister", "TypedRegister", "uint32", "double") ]
|
||||
};
|
||||
$ops{"PROP_XCR"} =
|
||||
{
|
||||
super => "Instruction_4",
|
||||
rem => "dest, source, name, value",
|
||||
params => [ ("TypedRegister", "TypedRegister", "const StringAtom*", "double") ]
|
||||
};
|
||||
$ops{"ELEM_XCR"} =
|
||||
{
|
||||
super => "Instruction_4",
|
||||
rem => "dest, base, index, value",
|
||||
params => [ ("TypedRegister", "TypedRegister", "TypedRegister", "double") ]
|
||||
};
|
||||
$ops{"NAME_XCR"} =
|
||||
{
|
||||
super => "Instruction_3",
|
||||
rem => "dest, name, value",
|
||||
params => [ ("TypedRegister", "const StringAtom*", "double") ]
|
||||
};
|
||||
$ops{"VAR_XCR"} =
|
||||
{
|
||||
super => "Instruction_3",
|
||||
rem => "dest, source, value",
|
||||
params => [ ("TypedRegister", "TypedRegister", "double") ]
|
||||
};
|
||||
$ops{"GET_ELEMENT"} =
|
||||
{
|
||||
super => "Instruction_3",
|
||||
rem => "dest, base, index",
|
||||
params => [ ("TypedRegister", "TypedRegister", "TypedRegister") ]
|
||||
};
|
||||
$ops{"SET_ELEMENT"} =
|
||||
{
|
||||
super => "Instruction_3",
|
||||
rem => "base, index, value",
|
||||
params => [ ("TypedRegister", "TypedRegister", "TypedRegister") ]
|
||||
};
|
||||
$ops{"ADD"} = $math_op;
|
||||
$ops{"SUBTRACT"} = $math_op;
|
||||
$ops{"MULTIPLY"} = $math_op;
|
||||
$ops{"DIVIDE"} = $math_op;
|
||||
$ops{"REMAINDER"} = $math_op;
|
||||
$ops{"SHIFTLEFT"} = $math_op;
|
||||
$ops{"SHIFTRIGHT"} = $math_op;
|
||||
$ops{"USHIFTRIGHT"}= $math_op;
|
||||
$ops{"AND"} = $math_op;
|
||||
$ops{"OR"} = $math_op;
|
||||
$ops{"XOR"} = $math_op;
|
||||
$ops{"COMPARE_LT"} = $binary_op;
|
||||
$ops{"COMPARE_LE"} = $binary_op;
|
||||
$ops{"COMPARE_EQ"} = $binary_op;
|
||||
$ops{"COMPARE_NE"} = $binary_op;
|
||||
$ops{"COMPARE_GE"} = $binary_op;
|
||||
$ops{"COMPARE_GT"} = $binary_op;
|
||||
$ops{"COMPARE_IN"} = $binary_op;
|
||||
$ops{"STRICT_EQ"} = $binary_op;
|
||||
$ops{"STRICT_NE"} = $binary_op;
|
||||
$ops{"INSTANCEOF"} = $binary_op;
|
||||
$ops{"BITNOT"} = $unary_op;
|
||||
$ops{"NOT"} = $unary_op;
|
||||
$ops{"TEST"} = $unary_op;
|
||||
$ops{"NEGATE"} = $unary_op;
|
||||
$ops{"POSATE"} = $unary_op;
|
||||
$ops{"BRANCH"} =
|
||||
{
|
||||
super => "GenericBranch",
|
||||
rem => "target label",
|
||||
params => [ ("Label*") ]
|
||||
};
|
||||
$ops{"BRANCH_TRUE"} = $cbranch_op;
|
||||
$ops{"BRANCH_FALSE"} = $cbranch_op;
|
||||
$ops{"RETURN"} =
|
||||
{
|
||||
super => "Instruction_1",
|
||||
rem => "return value",
|
||||
params => [ ("TypedRegister") ]
|
||||
};
|
||||
$ops{"RETURN_VOID"} =
|
||||
{
|
||||
super => "Instruction",
|
||||
rem => "Return without a value"
|
||||
};
|
||||
$ops{"CALL"} =
|
||||
{
|
||||
super => "Instruction_4",
|
||||
rem => "result, base, target, args",
|
||||
params => [ ("TypedRegister", "TypedRegister", "TypedRegister", "RegisterList") ]
|
||||
};
|
||||
$ops{"GET_METHOD"} =
|
||||
{
|
||||
super => "Instruction_3",
|
||||
rem => "result, target base, index",
|
||||
params => [ ("TypedRegister", "TypedRegister", "uint32") ]
|
||||
};
|
||||
$ops{"THROW"} =
|
||||
{
|
||||
super => "Instruction_1",
|
||||
rem => "exception value",
|
||||
params => [ ("TypedRegister") ]
|
||||
};
|
||||
$ops{"TRYIN"} =
|
||||
{
|
||||
super => "Instruction_2",
|
||||
rem => "catch target, finally target",
|
||||
params => [ ("Label*", "Label*") ]
|
||||
};
|
||||
$ops{"TRYOUT"} =
|
||||
{
|
||||
super => "Instruction",
|
||||
rem => "mmm, there is no try, only do",
|
||||
};
|
||||
$ops{"JSR"} =
|
||||
{
|
||||
super => "GenericBranch",
|
||||
rem => "target",
|
||||
params => [ ("Label*") ]
|
||||
};
|
||||
$ops{"RTS"} =
|
||||
{
|
||||
super => "Instruction",
|
||||
rem => "Return to sender",
|
||||
};
|
||||
$ops{"WITHIN"} =
|
||||
{
|
||||
super => "Instruction_1",
|
||||
rem => "within this object",
|
||||
params => [ ("TypedRegister") ]
|
||||
};
|
||||
$ops{"WITHOUT"} =
|
||||
{
|
||||
super => "Instruction",
|
||||
rem => "without this object",
|
||||
};
|
||||
$ops{"CAST"} =
|
||||
{
|
||||
super => "Instruction_3",
|
||||
rem => "dest, rvalue, toType",
|
||||
params => [ ("TypedRegister", "TypedRegister", "JSType*") ]
|
||||
};
|
||||
|
||||
#
|
||||
# nasty perl code, you probably don't need to muck around below this line
|
||||
#
|
||||
|
||||
my $k;
|
||||
|
||||
if (!$ARGV[0]) {
|
||||
# no args, collect all opcodes
|
||||
for $k (sort(keys(%ops))) {
|
||||
&collect($k);
|
||||
}
|
||||
} else {
|
||||
# collect defs for only the opcodes specified on the command line
|
||||
while ($k = pop(@ARGV)) {
|
||||
&collect (uc($k));
|
||||
}
|
||||
}
|
||||
|
||||
&spew;
|
||||
|
||||
sub collect {
|
||||
# grab the info from the $k record in $ops, and append it to
|
||||
# $enum_decs, @name_array, and $class_decs.
|
||||
my ($k) = @_;
|
||||
|
||||
if (length($k) > $opcode_maxlen) {
|
||||
$opcode_maxlen = length($k);
|
||||
}
|
||||
|
||||
my $c = $ops{$k};
|
||||
if (!$c) {
|
||||
die ("Unknown opcode, $k\n");
|
||||
}
|
||||
|
||||
my $opname = $k;
|
||||
my $cname = get_classname ($k);
|
||||
my $super = $c->{"super"};
|
||||
my $constructor = $super;
|
||||
my @params;
|
||||
|
||||
if ($c->{"params"}) {
|
||||
@params = @{$c->{"params"}};
|
||||
} else {
|
||||
@params = ();
|
||||
}
|
||||
|
||||
my $rem = $c->{"rem"};
|
||||
my ($dec_list, $call_list, $template_list) =
|
||||
&get_paramlists(@params);
|
||||
my @types = split (", ", $template_list);
|
||||
|
||||
my $constr_params = $call_list ? $opname . ", " . $call_list : $opname;
|
||||
|
||||
if ($super =~ /Instruction_\d/) {
|
||||
$super .= "<" . $template_list . ">";
|
||||
}
|
||||
|
||||
push (@name_array, $opname);
|
||||
$enum_decs .= "$init_tab$tab$opname, /* $rem */\n";
|
||||
if ($super) {
|
||||
$class_decs .= ($init_tab . "class $cname : public $super {\n" .
|
||||
$init_tab . "public:\n" .
|
||||
$init_tab . $tab . "/* $rem */\n" .
|
||||
$init_tab . $tab . "$cname ($dec_list) :\n" .
|
||||
$init_tab . $tab . $tab . "$super\n" .
|
||||
"$init_tab$tab$tab($constr_params) " .
|
||||
"{};\n");
|
||||
|
||||
if (!$c->{"super_has_print"}) {
|
||||
$class_decs .= ($init_tab . $tab .
|
||||
"virtual Formatter& print(Formatter& f) {\n" .
|
||||
$init_tab . $tab . $tab . "f << opcodeNames[$opname]" .
|
||||
&get_print_body(@types) . ";\n" .
|
||||
$init_tab . $tab . $tab . "return f;\n" .
|
||||
$init_tab . $tab . "}\n");
|
||||
|
||||
my $printops_body = &get_printops_body(@types);
|
||||
my $printops_decl = "virtual Formatter& printOperands(Formatter& f, ";
|
||||
|
||||
$printops_decl .= ($dec_list =~ /RegisterList/) ?
|
||||
"const JSValues& registers" :
|
||||
"const JSValues& /*registers*/";
|
||||
$printops_decl .= ") {\n";
|
||||
|
||||
$class_decs .= ($init_tab . $tab .
|
||||
$printops_decl .
|
||||
$printops_body .
|
||||
$init_tab . $tab . $tab . "return f;\n" .
|
||||
$init_tab . $tab . "}\n");
|
||||
|
||||
} else {
|
||||
$class_decs .= $init_tab . $tab .
|
||||
"/* print() and printOperands() inherited from $super */\n";
|
||||
}
|
||||
|
||||
$class_decs .= $init_tab . "};\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub spew {
|
||||
# print the info in $enum_decs, @name_aray, and $class_decs to stdout.
|
||||
my $opname;
|
||||
|
||||
print "// THIS FILE IS MACHINE GENERATED! DO NOT EDIT BY HAND!\n\n";
|
||||
|
||||
print "#if !defined(OPCODE_NAMES)\n\n";
|
||||
|
||||
print $tab . "enum {\n$enum_decs$tab};\n\n";
|
||||
|
||||
print $class_decs;
|
||||
|
||||
print "#else\n\n";
|
||||
|
||||
print $tab . "char *opcodeNames[] = {\n";
|
||||
|
||||
for $opname (@name_array) {
|
||||
print "$tab$tab\"$opname";
|
||||
for (0 .. $opcode_maxlen - length($opname) - 1) {
|
||||
print " ";
|
||||
}
|
||||
print "\",\n"
|
||||
}
|
||||
print "$tab};\n\n";
|
||||
|
||||
print "#endif\n\n"
|
||||
}
|
||||
|
||||
sub get_classname {
|
||||
# munge an OPCODE_MNEMONIC into a ClassName
|
||||
my ($enum_name) = @_;
|
||||
my @words = split ("_", $enum_name);
|
||||
my $cname = "";
|
||||
my $i = 0;
|
||||
my $word;
|
||||
|
||||
for $word (@words) {
|
||||
if ((length($word) == 2) && ($i != 0)) {
|
||||
$cname .= uc($word);
|
||||
} else {
|
||||
$cname .= uc(substr($word, 0, 1)) . lc(substr($word, 1));
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
return $cname;
|
||||
}
|
||||
|
||||
sub get_paramlists {
|
||||
# parse the params entry (passed into @types) into various parameter lists
|
||||
# used in the class declaration
|
||||
my @types = @_;
|
||||
my @dec;
|
||||
my @call;
|
||||
my @tostr;
|
||||
my @template;
|
||||
my $op = 1;
|
||||
my $type;
|
||||
|
||||
for $type (@types) {
|
||||
my $pfx;
|
||||
my $deref;
|
||||
my $member;
|
||||
my $default;
|
||||
|
||||
($type, $default) = split (" = ", $type);
|
||||
if ($default ne "") {
|
||||
$default = " = " . $default;
|
||||
}
|
||||
|
||||
$pfx = $deref = "";
|
||||
$member = "mOp$op";
|
||||
|
||||
push (@dec, "$type aOp$op" . "$default");
|
||||
push (@call, "aOp$op");
|
||||
push (@template, $type);
|
||||
$op++;
|
||||
}
|
||||
|
||||
return (join (", ", @dec), join (", ", @call), join (", ", @template));
|
||||
}
|
||||
|
||||
sub get_print_body {
|
||||
# generate the body of the print() function
|
||||
my (@types) = @_;
|
||||
my $type;
|
||||
my @oplist;
|
||||
my $op = 1;
|
||||
my $in = $init_tab . $tab . $tab;
|
||||
|
||||
for $type (@types) {
|
||||
|
||||
if ($type eq "TypedRegister") {
|
||||
|
||||
push (@oplist, "mOp$op" );
|
||||
|
||||
# push (@oplist, "\"R\" << ((mOp$op.first == NotARegister) ? -1 : mOp$op.first)");
|
||||
|
||||
} elsif ($type eq "Label*") {
|
||||
push (@oplist, "\"Offset \" << ((mOp$op) ? mOp$op->mOffset : NotAnOffset)")
|
||||
} elsif ($type =~ /String/) {
|
||||
push (@oplist, "\"'\" << *mOp$op << \"'\"");
|
||||
} elsif ($type =~ /JSType\*/) {
|
||||
push (@oplist, "\"'\" << mOp$op->getName() << \"'\"");
|
||||
} elsif ($type =~ /bool/) {
|
||||
push (@oplist, "\"'\" << ((mOp$op) ? \"true\" : \"false\") << \"'\"");
|
||||
} elsif ($type =~ /ICodeModule/) {
|
||||
push (@oplist, "\"ICodeModule\"");
|
||||
} elsif ($type =~ /JSClass\*/) {
|
||||
push (@oplist, "mOp$op->getName()");
|
||||
} else {
|
||||
push (@oplist, "mOp$op");
|
||||
}
|
||||
|
||||
$op++;
|
||||
}
|
||||
|
||||
my $rv = join (" << \", \" << ", @oplist);
|
||||
if ($rv ne "") {
|
||||
$rv = " << \"\\t\" << " . $rv;
|
||||
}
|
||||
|
||||
return $rv;
|
||||
}
|
||||
|
||||
sub get_printops_body {
|
||||
# generate the body of the printOperands() function
|
||||
my (@types) = @_;
|
||||
my $type;
|
||||
my @oplist;
|
||||
my $op = 1;
|
||||
my $in = $init_tab . $tab . $tab;
|
||||
|
||||
for $type (@types) {
|
||||
|
||||
if ($type eq "TypedRegister") {
|
||||
push (@oplist, "mOp$op.first");
|
||||
# push (@oplist, "\"R\" << mOp$op.first << '=' << registers[mOp$op.first]");
|
||||
} elsif ($type eq "RegisterList") {
|
||||
push (@oplist, "ArgList(mOp$op, registers)");
|
||||
}
|
||||
|
||||
$op++;
|
||||
}
|
||||
|
||||
my $rv = join (" << \", \" << ", @oplist);
|
||||
if ($rv ne "") {
|
||||
$rv = $init_tab . $tab . $tab . "f << " . $rv . ";\n";
|
||||
}
|
||||
|
||||
return $rv;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,178 +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.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the JavaScript 2 Prototype.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
#include "utilities.h"
|
||||
#include "vmtypes.h"
|
||||
|
||||
namespace JavaScript {
|
||||
namespace VM {
|
||||
|
||||
using namespace JSTypes;
|
||||
|
||||
#define OPCODE_NAMES
|
||||
#include "icode.h"
|
||||
|
||||
Formatter& operator<< (Formatter& f, Instruction& i)
|
||||
{
|
||||
return i.print(f);
|
||||
}
|
||||
|
||||
Formatter& operator<< (Formatter& f, RegisterList& rl)
|
||||
{
|
||||
TypedRegister* e = rl.end();
|
||||
|
||||
f << "(";
|
||||
for (RegisterList::iterator r = rl.begin(); r != e; r++) {
|
||||
f << "R" << r->first;
|
||||
if ((r + 1) != e)
|
||||
f << ", ";
|
||||
}
|
||||
f << ")";
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
Formatter& operator<< (Formatter& f, const ArgList& al)
|
||||
{
|
||||
const RegisterList& rl = al.mList;
|
||||
const JSValues& registers = al.mRegisters;
|
||||
f << "(";
|
||||
RegisterList::const_iterator i = rl.begin(), e = rl.end();
|
||||
if (i != e) {
|
||||
TypedRegister r = *i++;
|
||||
f << "R" << r.first << '=' << registers[r.first];
|
||||
while (i != e) {
|
||||
r = *i++;
|
||||
f << ", R" << r.first << '=' << registers[r.first];
|
||||
}
|
||||
}
|
||||
f << ")";
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
Formatter& operator<< (Formatter& f, TypedRegister& r)
|
||||
{
|
||||
if (r.first == NotARegister)
|
||||
f << "<NaR>";
|
||||
else
|
||||
f << "R" << r.first;
|
||||
return f;
|
||||
}
|
||||
|
||||
Formatter& operator<< (Formatter &f, InstructionStream &is)
|
||||
{
|
||||
|
||||
for (InstructionIterator i = is.begin();
|
||||
i != is.end(); i++) {
|
||||
/*
|
||||
bool isLabel = false;
|
||||
|
||||
for (LabelList::iterator k = labels.begin();
|
||||
k != labels.end(); k++)
|
||||
if ((ptrdiff_t)(*k)->mOffset == (i - is.begin())) {
|
||||
f << "#" << (uint32)(i - is.begin()) << "\t";
|
||||
isLabel = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isLabel)
|
||||
f << "\t";
|
||||
|
||||
f << **i << "\n";
|
||||
*/
|
||||
|
||||
printFormat(stdOut, "%04u", (uint32)(i - is.begin()));
|
||||
f << ": " << **i << "\n";
|
||||
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
BinaryOperator::BinaryOp BinaryOperator::mapICodeOp(ICodeOp op) {
|
||||
// a table later... or maybe we need a grand opcode re-unification
|
||||
switch (op) {
|
||||
case ADD : return Add;
|
||||
case SUBTRACT : return Subtract;
|
||||
case MULTIPLY : return Multiply;
|
||||
case DIVIDE : return Divide;
|
||||
case REMAINDER : return Remainder;
|
||||
case SHIFTLEFT : return LeftShift;
|
||||
case SHIFTRIGHT : return RightShift;
|
||||
case USHIFTRIGHT: return LogicalRightShift;
|
||||
|
||||
case AND : return BitwiseAnd;
|
||||
case OR : return BitwiseOr;
|
||||
case XOR : return BitwiseXor;
|
||||
|
||||
case COMPARE_LT : return Less;
|
||||
case COMPARE_LE : return LessOrEqual;
|
||||
case COMPARE_EQ : return Equal;
|
||||
case STRICT_EQ : return Identical;
|
||||
default :
|
||||
NOT_REACHED("Unsupported binary op");
|
||||
return (BinaryOp)-1;
|
||||
}
|
||||
}
|
||||
|
||||
Formatter& operator<< (Formatter &f, BinaryOperator::BinaryOp &b)
|
||||
{
|
||||
switch (b) {
|
||||
case BinaryOperator::Add: return f << "Add";
|
||||
case BinaryOperator::Subtract: return f << "Subtract";
|
||||
case BinaryOperator::Multiply: return f << "Multiply";
|
||||
case BinaryOperator::Divide: return f << "Divide";
|
||||
case BinaryOperator::Remainder: return f << "Remainder";
|
||||
case BinaryOperator::LeftShift: return f << "LeftShift";
|
||||
case BinaryOperator::RightShift: return f << "RightShift";
|
||||
case BinaryOperator::LogicalRightShift: return f << "LogicalRightShift";
|
||||
|
||||
case BinaryOperator::BitwiseAnd: return f << "BitwiseAnd";
|
||||
case BinaryOperator::BitwiseOr: return f << "BitwiseOr";
|
||||
case BinaryOperator::BitwiseXor: return f << "BitwiseXor";
|
||||
|
||||
case BinaryOperator::Less: return f << "Less";
|
||||
case BinaryOperator::LessOrEqual: return f << "LessOrEqual";
|
||||
case BinaryOperator::Equal: return f << "Equal";
|
||||
case BinaryOperator::Identical: return f << "Identical";
|
||||
default :
|
||||
NOT_REACHED("inner peace, either");
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace VM */
|
||||
} /* namespace JavaScript */
|
||||
|
||||
|
||||
@@ -1,304 +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.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the JavaScript 2 Prototype.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
#ifndef vmtypes_h
|
||||
#define vmtypes_h
|
||||
|
||||
#include "numerics.h" /* needed for formatter << double */
|
||||
#include "jstypes.h"
|
||||
#include "jsclasses.h"
|
||||
#include "world.h"
|
||||
#include <vector>
|
||||
|
||||
/* forward declare classes from JavaScript::ICG */
|
||||
namespace JavaScript {
|
||||
namespace ICG {
|
||||
class ICodeModule;
|
||||
} /* namespace ICG */
|
||||
} /* namespace JavaScript */
|
||||
|
||||
namespace JavaScript {
|
||||
namespace VM {
|
||||
|
||||
using namespace JSTypes;
|
||||
using namespace JSClasses;
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
typedef uint32 ICodeOp;
|
||||
extern char *opcodeNames[];
|
||||
|
||||
/* super-class for all instructions */
|
||||
class Instruction
|
||||
{
|
||||
public:
|
||||
Instruction(ICodeOp aOpcode) : mOpcode(aOpcode) {}
|
||||
|
||||
virtual Formatter& print(Formatter& f) = 0;
|
||||
virtual Formatter& printOperands(Formatter& f, const JSValues& /*registers*/) = 0;
|
||||
|
||||
ICodeOp op() { return mOpcode; }
|
||||
|
||||
virtual int32 count() { return 0; }
|
||||
|
||||
protected:
|
||||
ICodeOp mOpcode;
|
||||
|
||||
};
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
enum { NotARegister = 0xFFFFFFFF };
|
||||
enum { NotALabel = 0xFFFFFFFF };
|
||||
enum { NotAnOffset = 0xFFFFFFFF };
|
||||
enum { NotABanana = 0xFFFFFFFF };
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
typedef uint32 Register;
|
||||
typedef std::pair<Register, JSType*> TypedRegister;
|
||||
typedef std::vector<TypedRegister> RegisterList;
|
||||
typedef std::vector<Instruction *> InstructionStream;
|
||||
typedef InstructionStream::iterator InstructionIterator;
|
||||
typedef std::map<String, TypedRegister, std::less<String> > VariableMap;
|
||||
|
||||
|
||||
/**
|
||||
* Helper to print Call operands.
|
||||
*/
|
||||
struct ArgList {
|
||||
const RegisterList& mList;
|
||||
const JSValues& mRegisters;
|
||||
ArgList(const RegisterList& rl, const JSValues& registers)
|
||||
: mList(rl), mRegisters(registers) {}
|
||||
};
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
Formatter& operator<< (Formatter& f, Instruction& i);
|
||||
Formatter& operator<< (Formatter& f, RegisterList& rl);
|
||||
Formatter& operator<< (Formatter& f, const ArgList& al);
|
||||
Formatter& operator<< (Formatter& f, InstructionStream& is);
|
||||
Formatter& operator<< (Formatter& f, TypedRegister& r);
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
class Label {
|
||||
public:
|
||||
Label(InstructionStream* aBase) :
|
||||
mBase(aBase), mOffset(NotALabel) {}
|
||||
|
||||
InstructionStream *mBase;
|
||||
uint32 mOffset;
|
||||
};
|
||||
|
||||
typedef std::vector<Label *> LabelList;
|
||||
typedef LabelList::iterator LabelIterator;
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
/* 1, 2 and 3 operand opcode templates */
|
||||
|
||||
template <typename Operand1>
|
||||
class Instruction_1 : public Instruction {
|
||||
public:
|
||||
Instruction_1(ICodeOp aOpcode, Operand1 aOp1) :
|
||||
Instruction(aOpcode), mOp1(aOp1) { }
|
||||
Operand1& o1() { return mOp1; }
|
||||
|
||||
virtual int32 count() { return 1; }
|
||||
|
||||
protected:
|
||||
Operand1 mOp1;
|
||||
};
|
||||
|
||||
template <typename Operand1, typename Operand2>
|
||||
class Instruction_2 : public Instruction {
|
||||
public:
|
||||
Instruction_2(ICodeOp aOpcode, Operand1 aOp1, Operand2 aOp2) :
|
||||
Instruction(aOpcode), mOp1(aOp1), mOp2(aOp2) {}
|
||||
Operand1& o1() { return mOp1; }
|
||||
Operand2& o2() { return mOp2; }
|
||||
|
||||
virtual int32 count() { return 2; }
|
||||
|
||||
protected:
|
||||
Operand1 mOp1;
|
||||
Operand2 mOp2;
|
||||
};
|
||||
|
||||
template <typename Operand1, typename Operand2, typename Operand3>
|
||||
class Instruction_3 : public Instruction {
|
||||
public:
|
||||
Instruction_3(ICodeOp aOpcode, Operand1 aOp1, Operand2 aOp2,
|
||||
Operand3 aOp3) :
|
||||
Instruction(aOpcode), mOp1(aOp1), mOp2(aOp2), mOp3(aOp3) { }
|
||||
Operand1& o1() { return mOp1; }
|
||||
Operand2& o2() { return mOp2; }
|
||||
Operand3& o3() { return mOp3; }
|
||||
|
||||
virtual int32 count() { return 3; }
|
||||
|
||||
protected:
|
||||
Operand1 mOp1;
|
||||
Operand2 mOp2;
|
||||
Operand3 mOp3;
|
||||
};
|
||||
|
||||
template <typename Operand1, typename Operand2, typename Operand3, typename Operand4>
|
||||
class Instruction_4 : public Instruction {
|
||||
public:
|
||||
Instruction_4(ICodeOp aOpcode, Operand1 aOp1, Operand2 aOp2,
|
||||
Operand3 aOp3, Operand4 aOp4) :
|
||||
Instruction(aOpcode), mOp1(aOp1), mOp2(aOp2), mOp3(aOp3), mOp4(aOp4) { }
|
||||
Operand1& o1() { return mOp1; }
|
||||
Operand2& o2() { return mOp2; }
|
||||
Operand3& o3() { return mOp3; }
|
||||
Operand4& o4() { return mOp4; }
|
||||
|
||||
virtual int32 count() { return 4; }
|
||||
|
||||
protected:
|
||||
Operand1 mOp1;
|
||||
Operand2 mOp2;
|
||||
Operand3 mOp3;
|
||||
Operand4 mOp4;
|
||||
};
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
/* Instruction groups */
|
||||
|
||||
class Arithmetic : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
|
||||
public:
|
||||
Arithmetic (ICodeOp aOpcode, TypedRegister aDest, TypedRegister aSrc1,
|
||||
TypedRegister aSrc2) :
|
||||
Instruction_3<TypedRegister, TypedRegister, TypedRegister>(aOpcode, aDest, aSrc1, aSrc2) {}
|
||||
|
||||
virtual Formatter& print(Formatter& f)
|
||||
{
|
||||
f << opcodeNames[mOpcode] << "\tR" << mOp1.first << ", R" << mOp2.first << ", R" << mOp3.first;
|
||||
return f;
|
||||
}
|
||||
|
||||
virtual Formatter& printOperands(Formatter& f, const JSValues& registers)
|
||||
{
|
||||
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first] << ", " << "R" << mOp3.first << '=' << registers[mOp3.first];
|
||||
return f;
|
||||
}
|
||||
};
|
||||
|
||||
class Unary : public Instruction_2<TypedRegister, TypedRegister> {
|
||||
public:
|
||||
Unary(ICodeOp aOpcode, TypedRegister aDest, TypedRegister aSrc) :
|
||||
Instruction_2<TypedRegister, TypedRegister>(aOpcode, aDest, aSrc) {}
|
||||
virtual Formatter& print (Formatter& f) {
|
||||
f << opcodeNames[mOpcode] << "\tR" << mOp1.first << ", R" << mOp2.first;
|
||||
return f;
|
||||
}
|
||||
|
||||
virtual Formatter& printOperands(Formatter& f, const JSValues& registers)
|
||||
{
|
||||
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
|
||||
return f;
|
||||
}
|
||||
};
|
||||
|
||||
class GenericBranch : public Instruction_2<Label*, TypedRegister> {
|
||||
public:
|
||||
GenericBranch (ICodeOp aOpcode, Label* aLabel,
|
||||
TypedRegister aR = TypedRegister(NotARegister, &Any_Type) ) :
|
||||
Instruction_2<Label*, TypedRegister>(aOpcode, aLabel, aR) {}
|
||||
virtual Formatter& print (Formatter& f) {
|
||||
f << opcodeNames[mOpcode] << "\tOffset " << mOp1->mOffset;
|
||||
if (mOp2.first == NotARegister) {
|
||||
f << ", R~";
|
||||
} else {
|
||||
f << ", R" << mOp2.first;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
virtual Formatter& printOperands(Formatter& f, const JSValues& registers)
|
||||
{
|
||||
if (mOp2.first != NotARegister)
|
||||
f << "R" << mOp2.first << '=' << registers[mOp2.first];
|
||||
return f;
|
||||
}
|
||||
|
||||
void resolveTo (uint32 aOffset) { mOp1->mOffset = aOffset; }
|
||||
uint32 getOffset() { return mOp1->mOffset; }
|
||||
void setTarget(Label *label) { mOp1 = label; }
|
||||
};
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
class BinaryOperator {
|
||||
public:
|
||||
|
||||
// Wah, here's a third enumeration of opcodes - ExprNode, ICodeOp and now here, this can't be right??
|
||||
typedef enum {
|
||||
BinaryOperatorFirst,
|
||||
Add = BinaryOperatorFirst, Subtract, Multiply, Divide,
|
||||
Remainder, LeftShift, RightShift, LogicalRightShift,
|
||||
BitwiseOr, BitwiseXor, BitwiseAnd, Less, LessOrEqual,
|
||||
Equal, Identical, BinaryOperatorCount
|
||||
} BinaryOp;
|
||||
|
||||
BinaryOperator(const JSType *t1, const JSType *t2, JSBinaryOperator *function) :
|
||||
t1(t1), t2(t2), function(function) { }
|
||||
|
||||
BinaryOperator(const JSType *t1, const JSType *t2, JSFunction *function) :
|
||||
t1(t1), t2(t2), function(function) { }
|
||||
|
||||
static BinaryOp mapICodeOp(ICodeOp op);
|
||||
|
||||
const JSType *t1;
|
||||
const JSType *t2;
|
||||
JSFunction *function;
|
||||
|
||||
};
|
||||
|
||||
typedef std::vector<BinaryOperator *> BinaryOperatorList;
|
||||
|
||||
Formatter& operator<<(Formatter &f, BinaryOperator::BinaryOp &b);
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
#include "icode.h"
|
||||
|
||||
} /* namespace VM */
|
||||
|
||||
} /* namespace JavaScript */
|
||||
|
||||
#endif /* vmtypes_h */
|
||||
@@ -1,5 +0,0 @@
|
||||
cd ..\..\..\..
|
||||
cvs co mozilla/gc/boehm
|
||||
cd mozilla\gc\boehm
|
||||
nmake -f NT_MAKEFILE gc.lib
|
||||
cd ..\..\js\js2\winbuild
|
||||
@@ -1,234 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="js2" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=js2 - Win32 Partial Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "js2.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "js2.mak" CFG="js2 - Win32 Partial Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "js2 - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "js2 - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "js2 - Win32 Partial Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "js2 - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib gc.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\gc\boehm"
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "js2 - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GR /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "DEBUG" /FR /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG" /d "DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# SUBTRACT BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib gc.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\gc\boehm"
|
||||
|
||||
!ELSEIF "$(CFG)" == "js2 - Win32 Partial Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "js2___Win32_Partial_Debug"
|
||||
# PROP BASE Intermediate_Dir "js2___Win32_Partial_Debug"
|
||||
# PROP BASE Ignore_Export_Lib 0
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "js2___Win32_Partial_Debug"
|
||||
# PROP Intermediate_Dir "js2___Win32_Partial_Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "DEBUG" /FR /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG" /d "DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG" /d "DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# SUBTRACT BASE BSC32 /nologo
|
||||
# SUBTRACT BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib gc.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\gc\boehm"
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib gc.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\gc\boehm"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "js2 - Win32 Release"
|
||||
# Name "js2 - Win32 Debug"
|
||||
# Name "js2 - Win32 Partial Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\debugger.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\hash.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\icodegenerator.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\interpreter.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\js2.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\jsmath.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\jstypes.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\numerics.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\parser.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\utilities.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\vmtypes.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\world.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\cpucfg.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\gc_allocator.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\hash.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\icode.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\icodegenerator.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\interpreter.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\jsclasses.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\jsmath.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\jstypes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\numerics.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\parser.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\systemtypes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\utilities.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\vmtypes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\world.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -1,29 +0,0 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "js2"=.\js2.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -1,39 +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.1 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of
|
||||
// the License at http://www.mozilla.org/NPL/
|
||||
//
|
||||
// Software distributed under the License is distributed on an "AS
|
||||
// IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
// implied. See the License for the specific language governing
|
||||
// rights and limitations under the License.
|
||||
//
|
||||
// The Original Code is the JavaScript 2 Prototype.
|
||||
//
|
||||
// The Initial Developer of the Original Code is Netscape
|
||||
// Communications Corporation. Portions created by Netscape are
|
||||
// Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
// Rights Reserved.
|
||||
|
||||
#include "world.h"
|
||||
namespace JS = JavaScript;
|
||||
|
||||
|
||||
// Return an existing StringAtom corresponding to the String s if there is
|
||||
// one; if not, create a new StringAtom with String s and return that StringAtom.
|
||||
JS::StringAtom &JS::StringAtomTable::operator[](const String &s)
|
||||
{
|
||||
HT::Reference r(ht, s);
|
||||
if (r)
|
||||
return *r;
|
||||
else
|
||||
return ht.insert(r, s);
|
||||
}
|
||||
|
||||
|
||||
JS::World::World()
|
||||
{
|
||||
Token::initKeywords(*this);
|
||||
}
|
||||
@@ -1,73 +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.1 (the "License"); you may not use this file
|
||||
// except in compliance with the License. You may obtain a copy of
|
||||
// the License at http://www.mozilla.org/NPL/
|
||||
//
|
||||
// Software distributed under the License is distributed on an "AS
|
||||
// IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
// implied. See the License for the specific language governing
|
||||
// rights and limitations under the License.
|
||||
//
|
||||
// The Original Code is the JavaScript 2 Prototype.
|
||||
//
|
||||
// The Initial Developer of the Original Code is Netscape
|
||||
// Communications Corporation. Portions created by Netscape are
|
||||
// Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
// Rights Reserved.
|
||||
|
||||
#ifndef world_h
|
||||
#define world_h
|
||||
|
||||
#include "utilities.h"
|
||||
#include "hash.h"
|
||||
#include "parser.h"
|
||||
|
||||
namespace JavaScript {
|
||||
|
||||
//
|
||||
// String atom management
|
||||
//
|
||||
|
||||
// A StringAtom is a String for which the following guarantee applies:
|
||||
// StringAtoms A and B have the same character sequences if and only if A and B are the
|
||||
// same StringAtom.
|
||||
|
||||
class StringAtom: public String {
|
||||
public:
|
||||
Token::Kind tokenKind; // Token::Kind if this is a keyword; Token::identifier if not
|
||||
|
||||
explicit StringAtom(const String &s): String(s), tokenKind(Token::identifier) {}
|
||||
private:
|
||||
StringAtom(const StringAtom&); // No copy constructor
|
||||
void operator=(const StringAtom&); // No assignment operator
|
||||
};
|
||||
|
||||
inline bool operator==(const StringAtom &s1, const StringAtom &s2) {return &s1 == &s2;}
|
||||
inline bool operator!=(const StringAtom &s1, const StringAtom &s2) {return &s1 != &s2;}
|
||||
|
||||
|
||||
class StringAtomTable {
|
||||
typedef HashTable<StringAtom, const String&> HT;
|
||||
HT ht;
|
||||
|
||||
public:
|
||||
StringAtom &operator[](const String &s);
|
||||
|
||||
StringAtom &operator[](const char *s)
|
||||
{
|
||||
return operator[](widenCString(s));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class World {
|
||||
public:
|
||||
StringAtomTable identifiers;
|
||||
|
||||
World();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
48
mozilla/js/src/MANIFEST
Normal file
48
mozilla/js/src/MANIFEST
Normal file
@@ -0,0 +1,48 @@
|
||||
# This file is required for the Mac client mozilla build.
|
||||
# This is a list of local files which get copied to the mozilla:dist directory
|
||||
#
|
||||
|
||||
js.msg
|
||||
jsapi.h
|
||||
jsarena.h
|
||||
jspubtd.h
|
||||
jsarray.h
|
||||
jsatom.h
|
||||
jsbool.h
|
||||
jsclist.h
|
||||
jscntxt.h
|
||||
jscompat.h
|
||||
jsconfig.h
|
||||
jscpucfg.h
|
||||
jsdate.h
|
||||
jsdbgapi.h
|
||||
jsdhash.h
|
||||
jsdtoa.h
|
||||
jsemit.h
|
||||
jsfun.h
|
||||
jsgc.h
|
||||
jshash.h
|
||||
jsinterp.h
|
||||
jslock.h
|
||||
jslong.h
|
||||
jsmath.h
|
||||
jsnum.h
|
||||
jsobj.h
|
||||
jsopcode.tbl
|
||||
jsopcode.h
|
||||
jsosdep.h
|
||||
jsotypes.h
|
||||
jsparse.h
|
||||
jsprf.h
|
||||
jsprvtd.h
|
||||
jspubtd.h
|
||||
jsregexp.h
|
||||
jsscan.h
|
||||
jsscope.h
|
||||
jsscript.h
|
||||
jsstr.h
|
||||
jstypes.h
|
||||
jsutil.h
|
||||
jsxdrapi.h
|
||||
|
||||
|
||||
337
mozilla/js/src/Makefile.in
Normal file
337
mozilla/js/src/Makefile.in
Normal file
@@ -0,0 +1,337 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
#
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = js
|
||||
LIBRARY_NAME = mozjs
|
||||
|
||||
DIRS = fdlibm
|
||||
|
||||
CSRCS = \
|
||||
jsapi.c \
|
||||
jsarena.c \
|
||||
jsarray.c \
|
||||
jsatom.c \
|
||||
jsbool.c \
|
||||
jscntxt.c \
|
||||
jsdate.c \
|
||||
jsdbgapi.c \
|
||||
jsdhash.c \
|
||||
jsdtoa.c \
|
||||
jsemit.c \
|
||||
jsexn.c \
|
||||
jsfun.c \
|
||||
jsgc.c \
|
||||
jshash.c \
|
||||
jsinterp.c \
|
||||
jslock.c \
|
||||
jslog2.c \
|
||||
jslong.c \
|
||||
jsmath.c \
|
||||
jsnum.c \
|
||||
jsobj.c \
|
||||
jsopcode.c \
|
||||
jsparse.c \
|
||||
jsprf.c \
|
||||
jsregexp.c \
|
||||
jsscan.c \
|
||||
jsscope.c \
|
||||
jsscript.c \
|
||||
jsstr.c \
|
||||
jsutil.c \
|
||||
jsxdrapi.c \
|
||||
prmjtime.c \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
js.msg \
|
||||
jsapi.h \
|
||||
jsarray.h \
|
||||
jsarena.h \
|
||||
jsatom.h \
|
||||
jsbit.h \
|
||||
jsbool.h \
|
||||
jsclist.h \
|
||||
jscntxt.h \
|
||||
jscompat.h \
|
||||
jsconfig.h \
|
||||
jsdate.h \
|
||||
jsdbgapi.h \
|
||||
jsdhash.h \
|
||||
jsemit.h \
|
||||
jsfun.h \
|
||||
jsgc.h \
|
||||
jshash.h \
|
||||
jsinterp.h \
|
||||
jslock.h \
|
||||
jslong.h \
|
||||
jsmath.h \
|
||||
jsnum.h \
|
||||
jsobj.h \
|
||||
jsopcode.tbl \
|
||||
jsopcode.h \
|
||||
jsosdep.h \
|
||||
jsotypes.h \
|
||||
jsparse.h \
|
||||
jsprf.h \
|
||||
jsprvtd.h \
|
||||
jspubtd.h \
|
||||
jsregexp.h \
|
||||
jsscan.h \
|
||||
jsscope.h \
|
||||
jsscript.h \
|
||||
jsstr.h \
|
||||
jstypes.h \
|
||||
jsutil.h \
|
||||
jsxdrapi.h \
|
||||
jsstddef.h \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
|
||||
|
||||
FDLIBM_LIBRARY = fdlibm/libfdm.$(LIB_SUFFIX)
|
||||
JSMATH_PRELINK = jsmathtemp.o
|
||||
JS_SAFE_ARENA = 1
|
||||
|
||||
DASH_R = -r
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
ifeq ($(OS_ARCH),OS2)
|
||||
ifneq ($(MOZ_WIDGET_TOOLKIT),os2)
|
||||
ifndef XCFLAGS
|
||||
OS2_IMPLIB = 1
|
||||
LIBRARY = js$(MOZ_BITS)$(VERSION_NUMBER).$(LIB_SUFFIX)
|
||||
DEF_FILE = jsos2$(VERSION_NUMBER).def
|
||||
EXTRA_LIBS = $(NSPR_LIBS) $(LIBNSJAVA)
|
||||
else
|
||||
EXTRA_LIBS = $(NSPR_LIBS) $(LIBNSJAVA) libjs.lib
|
||||
endif
|
||||
OS_CFLAGS += -tm-
|
||||
endif
|
||||
endif
|
||||
|
||||
EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_NSPR_LIBS)
|
||||
|
||||
# When using gcc the assembly is inlined in the C-file (see jslock.c)
|
||||
ifdef NS_USE_NATIVE
|
||||
ASFILES = $(notdir $(wildcard $(srcdir)/*_$(OS_ARCH).s))
|
||||
endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),os2)
|
||||
DEF_OBJS = jsapi.o jsarena.o jsdbgapi.o jsdhash.o jsdtoa.o jsgc.o jshash.o \
|
||||
jsinterp.o jslog2.o jslong.o jsprf.o jsutil.o jsxdrapi.o prmjtime.o
|
||||
#ADD_TO_DEF_FILE = cat < $(srcdir)/extradefs.os2 >>$(DEF_FILE)
|
||||
endif
|
||||
|
||||
ifndef BUILD_OPT
|
||||
MOCHAFILE = 1
|
||||
endif
|
||||
|
||||
ifndef NSBUILDROOT
|
||||
JSJAVA_STUBHEADERS = \
|
||||
-I$(topsrcdir)/sun-java/include/_gen \
|
||||
-I$(topsrcdir)/sun-java/netscape/javascript/_jri \
|
||||
-I$(topsrcdir)/sun-java/netscape/security/_jri
|
||||
else
|
||||
JSJAVA_STUBHEADERS = -I$(JRI_GEN_DIR) -I$(JDK_GEN_DIR)
|
||||
endif
|
||||
|
||||
JSJAVA_CFLAGS = \
|
||||
-I$(topsrcdir)/sun-java/md-include \
|
||||
-I$(topsrcdir)/sun-java/include \
|
||||
$(JSJAVA_STUBHEADERS)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
DEFINES += -DEXPORT_JS_API
|
||||
|
||||
INCLUDES += -I$(srcdir)
|
||||
|
||||
GARBAGE += $(JSMATH_PRELINK) jscpucfg.o jsautocfg.h jsautocfg.tmp jscpucfg
|
||||
|
||||
TARGETS += jscpucfg$(BIN_SUFFIX)
|
||||
|
||||
ifdef JS_SAFE_ARENA
|
||||
DEFINES += -DJS_USE_SAFE_ARENA
|
||||
endif
|
||||
|
||||
ifdef JS_THREADSAFE
|
||||
DEFINES += -DJS_THREADSAFE
|
||||
endif
|
||||
|
||||
ifdef JS_NO_THIN_LOCKS
|
||||
DEFINES += -DJS_USE_ONLY_NSPR_LOCKS
|
||||
endif
|
||||
|
||||
ifdef JS_VERSION
|
||||
DEFINES += -DJS_VERSION=$(JS_VERSION)
|
||||
endif
|
||||
|
||||
ifneq ($(findstring -L,$(NSPR_LIBS)),)
|
||||
NSPR_STATIC_PATH = $(subst -L,,$(findstring -L,$(NSPR_LIBS)))
|
||||
else
|
||||
NSPR_STATIC_PATH = $(DIST)/lib
|
||||
endif
|
||||
|
||||
LDFLAGS += $(pathsubst -l%,$(NSPR_STATIC_PATH)/%.a,$(NSPR_LIBS))
|
||||
|
||||
# BeOS and HP-UX do not require the extra linking of "-lm"
|
||||
ifeq (,$(filter BeOS HP-UX,$(OS_ARCH)))
|
||||
LDFLAGS += -lm
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),FreeBSD)
|
||||
LDFLAGS += -pthread
|
||||
endif
|
||||
ifeq ($(OS_ARCH),IRIX)
|
||||
ifneq ($(basename $(OS_RELEASE)),5)
|
||||
LDFLAGS += -n32
|
||||
DASH_R += -n32
|
||||
endif
|
||||
endif
|
||||
ifeq ($(OS_ARCH),Linux)
|
||||
LDFLAGS += -ldl
|
||||
endif
|
||||
ifeq ($(OS_ARCH),OSF1)
|
||||
LDFLAGS += -lc_r
|
||||
endif
|
||||
ifeq ($(OS_ARCH),SunOS)
|
||||
ifeq ($(CPU_ARCH),sparc)
|
||||
|
||||
ifndef JS_NO_ULTRA
|
||||
ULTRA_OPTIONS := -xarch=v8plus,-DULTRA_SPARC
|
||||
ULTRA_OPTIONSCC := -DULTRA_SPARC
|
||||
else
|
||||
ULTRA_OPTIONS := -xarch=v8
|
||||
ULTRA_OPTIONSCC :=
|
||||
endif
|
||||
|
||||
ifeq ($(shell uname -m),sun4u)
|
||||
ASFLAGS += -Wa,$(ULTRA_OPTIONS),-P,-L,-D_ASM,-D__STDC__=0 $(ULTRA_OPTIONSCC)
|
||||
else
|
||||
ASFLAGS += -Wa,-xarch=v8,-P,-L,-D_ASM,-D__STDC__=0
|
||||
endif
|
||||
|
||||
endif
|
||||
ifeq ($(OS_RELEASE),4.1)
|
||||
LDFLAGS += -ldl -lnsl
|
||||
else
|
||||
LDFLAGS += -lposix4 -ldl -lnsl -lsocket
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),QNX)
|
||||
ifneq ($(OS_TARGET),NTO)
|
||||
# Don't use wildcard here, because we only want this resolved at link time.
|
||||
OBJS += fdlibm/*.o
|
||||
endif
|
||||
endif
|
||||
|
||||
# OS/2 linkers expect to create executables or dlls, not object files
|
||||
# so we pull in what's needed from fdlibm when creating the js dll
|
||||
ifneq ($(MOZ_WIDGET_TOOLKIT),os2)
|
||||
# special rule for jsmath.o since we want to incrementally link
|
||||
# against fdlibm to pull in only what is needed
|
||||
jsmath.o: $(FDLIBM_LIBRARY) $(JSMATH_PRELINK)
|
||||
ifeq ($(OS_ARCH),QNX)
|
||||
ifneq ($(OS_TARGET),NTO)
|
||||
@cp $(JSMATH_PRELINK) $@
|
||||
else
|
||||
$(LD) $(DASH_R) -o $@ $(JSMATH_PRELINK) $(FDLIBM_LIBRARY)
|
||||
endif
|
||||
else
|
||||
$(LD) $(DASH_R) -o $@ $(JSMATH_PRELINK) $(FDLIBM_LIBRARY)
|
||||
endif
|
||||
|
||||
$(JSMATH_PRELINK): jsmath.c
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
$(CC) -Fo$@ -c $(CFLAGS) $<
|
||||
else
|
||||
$(CC) -o $@ -c $(COMPILE_CFLAGS) $<
|
||||
endif
|
||||
endif
|
||||
|
||||
# An AIX Optimization bug causes PR_dtoa() & JS_dtoa to produce wrong result.
|
||||
# This suppresses optimization for this single compilation unit.
|
||||
ifeq ($(OS_ARCH),AIX)
|
||||
jsdtoa.o: jsdtoa.c
|
||||
$(CC) -o $@ -c $(filter-out -O, $(COMPILE_CFLAGS)) $<
|
||||
endif
|
||||
|
||||
$(FDLIBM_LIBRARY):
|
||||
@$(CONTINUE_ON_ERROR) \
|
||||
$(MAKE) -C $(@D) $(@F); \
|
||||
$(EXIT_ON_ERROR)
|
||||
|
||||
jsopcode.h jsopcode.c: jsopcode.tbl
|
||||
|
||||
jsautocfg.h: jscpucfg$(BIN_SUFFIX)
|
||||
@rm -f $@ jsautocfg.tmp
|
||||
./jscpucfg > jsautocfg.tmp
|
||||
mv jsautocfg.tmp $@
|
||||
|
||||
# jscpucfg is a strange target
|
||||
# Needs to be built with the host compiler but needs to include
|
||||
# the mdcpucfg for the target so it needs the appropriate target defines
|
||||
ifdef HOST_NSPR_MDCPUCFG
|
||||
HOST_CC := $(HOST_CC) -DMDCPUCFG=$(TARGET_NSPR_MDCPUCFG)
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),QNX)
|
||||
ifneq ($(OS_TARGET),NTO)
|
||||
# QNX's compiler apparently can't build a binary directly from a source file.
|
||||
jscpucfg.o: jscpucfg.c
|
||||
$(HOST_CC) $(HOST_CFLAGS) -c $(DEFINES) $(NSPR_CFLAGS) -o $@ $<
|
||||
|
||||
jscpucfg: jscpucfg.o
|
||||
$(HOST_CC) $(HOST_CFLAGS) $(DEFINES) -o $@ $<
|
||||
endif
|
||||
else
|
||||
jscpucfg$(BIN_SUFFIX): jscpucfg.c
|
||||
ifeq ($(MOZ_OS2_TOOLS),VACPP)
|
||||
$(HOST_CC) $(HOST_CFLAGS) $(DEFINES) $(NSPR_CFLAGS) /Fe$@ $<
|
||||
else
|
||||
$(HOST_CC) $(HOST_CFLAGS) $(DEFINES) $(NSPR_CFLAGS) -o $@ $<
|
||||
endif
|
||||
endif
|
||||
|
||||
export:: jsautocfg.h
|
||||
$(INSTALL) -m 444 $< $(PUBLIC)
|
||||
|
||||
344
mozilla/js/src/Makefile.ref
Normal file
344
mozilla/js/src/Makefile.ref
Normal file
@@ -0,0 +1,344 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Michael Ang <mang@subcarrier.org>
|
||||
#
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
|
||||
#
|
||||
# JSRef GNUmake makefile.
|
||||
#
|
||||
|
||||
DEPTH = .
|
||||
|
||||
include config.mk
|
||||
|
||||
#NS_USE_NATIVE = 1
|
||||
|
||||
ifdef USE_MSVC
|
||||
OTHER_LIBS += fdlibm/$(OBJDIR)/fdlibm.lib
|
||||
else
|
||||
OTHER_LIBS += -Lfdlibm/$(OBJDIR) -lfdm
|
||||
endif
|
||||
|
||||
ifdef JS_THREADSAFE
|
||||
DEFINES += -DJS_THREADSAFE
|
||||
INCLUDES += -I../../dist/$(OBJDIR)/include
|
||||
ifdef USE_MSVC
|
||||
OTHER_LIBS += ../../dist/$(OBJDIR)/lib/libnspr3.lib
|
||||
else
|
||||
OTHER_LIBS += -L../../dist/$(OBJDIR)/lib -lnspr3
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef JS_NO_THIN_LOCKS
|
||||
DEFINES += -DJS_USE_ONLY_NSPR_LOCKS
|
||||
endif
|
||||
|
||||
ifdef JS_HAS_FILE_OBJECT
|
||||
DEFINES += -DJS_HAS_FILE_OBJECT
|
||||
endif
|
||||
|
||||
#
|
||||
# XCFLAGS may be set in the environment or on the gmake command line
|
||||
#
|
||||
CFLAGS += $(OPTIMIZER) $(OS_CFLAGS) $(DEFINES) $(INCLUDES) $(XCFLAGS)
|
||||
|
||||
LDFLAGS = $(XLDFLAGS)
|
||||
|
||||
ifndef NO_LIBM
|
||||
LDFLAGS += -lm
|
||||
endif
|
||||
|
||||
#
|
||||
# Ask perl what flags it was built with, so we can build js with similar flags
|
||||
# and link properly. Viva gmake.
|
||||
#
|
||||
ifdef JS_PERLCONNECT
|
||||
DEFINES += -DPERLCONNECT -D_GNU_SOURCE
|
||||
|
||||
PERLCFLAGS := $(shell perl -MExtUtils::Embed -e ccopts)
|
||||
PERLLDFLAGS := $(shell perl -MExtUtils::Embed -e ldopts)
|
||||
|
||||
# perl erroneously reports compiler flag -rdynamic (interpreted by ld
|
||||
# as -r) when it really meant -export-dynamic.
|
||||
PERLLDFLAGS := $(subst -rdynamic,-export-dynamic,$(PERLLDFLAGS))
|
||||
|
||||
CFLAGS += $(PERLCFLAGS)
|
||||
LDFLAGS += $(PERLLDFLAGS)
|
||||
endif
|
||||
|
||||
#
|
||||
# Server-related changes :
|
||||
#
|
||||
ifdef NES40
|
||||
DEFINES += -DNES40
|
||||
endif
|
||||
|
||||
#
|
||||
# Line editing support.
|
||||
# Define JS_READLINE or JS_EDITLINE to enable line editing in the
|
||||
# js command-line interpreter.
|
||||
#
|
||||
ifdef JS_READLINE
|
||||
# For those platforms with the readline library installed.
|
||||
DEFINES += -DEDITLINE
|
||||
PROG_LIBS += -lreadline
|
||||
else
|
||||
ifdef JS_EDITLINE
|
||||
# Use the editline library, built locally.
|
||||
PREDIRS += editline
|
||||
DEFINES += -DEDITLINE
|
||||
PROG_LIBS += -Leditline/$(OBJDIR) -ledit
|
||||
endif
|
||||
endif
|
||||
|
||||
# For purify
|
||||
PURE_CFLAGS = -DXP_UNIX $(OPTIMIZER) $(PURE_OS_CFLAGS) $(DEFINES) \
|
||||
$(INCLUDES) $(XCFLAGS)
|
||||
|
||||
#
|
||||
# JS file lists
|
||||
#
|
||||
JS_HFILES = \
|
||||
jsarray.h \
|
||||
jsatom.h \
|
||||
jsbool.h \
|
||||
jsconfig.h \
|
||||
jscntxt.h \
|
||||
jsdate.h \
|
||||
jsemit.h \
|
||||
jsexn.h \
|
||||
jsfun.h \
|
||||
jsgc.h \
|
||||
jsinterp.h \
|
||||
jslibmath.h \
|
||||
jslock.h \
|
||||
jsmath.h \
|
||||
jsnum.h \
|
||||
jsobj.h \
|
||||
jsopcode.h \
|
||||
jsparse.h \
|
||||
jsarena.h \
|
||||
jsclist.h \
|
||||
jsdtoa.h \
|
||||
jshash.h \
|
||||
jslong.h \
|
||||
jsosdep.h \
|
||||
jstypes.h \
|
||||
jsprvtd.h \
|
||||
jspubtd.h \
|
||||
jsregexp.h \
|
||||
jsscan.h \
|
||||
jsscope.h \
|
||||
jsscript.h \
|
||||
jsstr.h \
|
||||
jsxdrapi.h \
|
||||
$(NULL)
|
||||
|
||||
API_HFILES = \
|
||||
jsapi.h \
|
||||
jsdbgapi.h \
|
||||
$(NULL)
|
||||
|
||||
OTHER_HFILES = \
|
||||
jsbit.h \
|
||||
jscompat.h \
|
||||
jscpucfg.h \
|
||||
jsotypes.h \
|
||||
jsstddef.h \
|
||||
prmjtime.h \
|
||||
resource.h \
|
||||
jsopcode.tbl \
|
||||
js.msg \
|
||||
jsshell.msg \
|
||||
$(NULL)
|
||||
|
||||
ifndef PREBUILT_CPUCFG
|
||||
OTHER_HFILES += $(OBJDIR)/jsautocfg.h
|
||||
endif
|
||||
|
||||
HFILES = $(JS_HFILES) $(API_HFILES) $(OTHER_HFILES)
|
||||
|
||||
JS_CFILES = \
|
||||
jsapi.c \
|
||||
jsarena.c \
|
||||
jsarray.c \
|
||||
jsatom.c \
|
||||
jsbool.c \
|
||||
jscntxt.c \
|
||||
jsdate.c \
|
||||
jsdbgapi.c \
|
||||
jsdtoa.c \
|
||||
jsemit.c \
|
||||
jsexn.c \
|
||||
jsfun.c \
|
||||
jsgc.c \
|
||||
jshash.c \
|
||||
jsinterp.c \
|
||||
jslock.c \
|
||||
jslog2.c \
|
||||
jslong.c \
|
||||
jsmath.c \
|
||||
jsnum.c \
|
||||
jsobj.c \
|
||||
jsopcode.c \
|
||||
jsparse.c \
|
||||
jsprf.c \
|
||||
jsregexp.c \
|
||||
jsscan.c \
|
||||
jsscope.c \
|
||||
jsscript.c \
|
||||
jsstr.c \
|
||||
jsutil.c \
|
||||
jsxdrapi.c \
|
||||
prmjtime.c \
|
||||
$(NULL)
|
||||
|
||||
PREDIRS += fdlibm
|
||||
ifdef USE_MSVC
|
||||
FDLIBM_LIBRARY = fdlibm/$(OBJDIR)/fdlibm.lib
|
||||
else
|
||||
FDLIBM_LIBRARY = fdlibm/$(OBJDIR)/libfdm.a
|
||||
endif
|
||||
JSMATH_PRELINK = $(OBJDIR)/jsmathtemp.o
|
||||
# Flag for incremental linking
|
||||
DASH_R = -r
|
||||
|
||||
ifeq ($(OS_ARCH),QNX)
|
||||
ifneq ($(OS_TARGET),NTO)
|
||||
# Don't use wildcard here, because we only want this resolved at link time.
|
||||
OBJS += fdlibm/*.o
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef JS_LIVECONNECT
|
||||
DIRS += liveconnect
|
||||
endif
|
||||
|
||||
ifdef JS_PERLCONNECT
|
||||
JS_CFILES += perlconnect/jsperl.c
|
||||
endif
|
||||
|
||||
ifdef JS_HAS_FILE_OBJECT
|
||||
JS_CFILES += jsfile.c
|
||||
JS_HFILES += jsfile.h
|
||||
endif
|
||||
|
||||
LIB_CFILES = $(JS_CFILES)
|
||||
LIB_ASFILES := $(wildcard *_$(OS_ARCH).s)
|
||||
PROG_CFILES = js.c
|
||||
|
||||
ifdef USE_MSVC
|
||||
LIBRARY = $(OBJDIR)/js32.lib
|
||||
SHARED_LIBRARY = $(OBJDIR)/js32.dll
|
||||
PROGRAM = $(OBJDIR)/js.exe
|
||||
else
|
||||
LIBRARY = $(OBJDIR)/libjs.a
|
||||
SHARED_LIBRARY = $(OBJDIR)/libjs.$(SO_SUFFIX)
|
||||
PROGRAM = $(OBJDIR)/js
|
||||
endif
|
||||
|
||||
include rules.mk
|
||||
|
||||
MOZ_DEPTH = ../..
|
||||
include jsconfig.mk
|
||||
|
||||
nsinstall-target:
|
||||
cd ../../config; $(MAKE) OBJDIR=$(OBJDIR) OBJDIR_NAME=$(OBJDIR)
|
||||
ifdef USE_MSVC
|
||||
$(PROGRAM): $(PROG_OBJS) $(LIBRARY) $(FDLIBM_LIBRARY)
|
||||
link.exe -out:"$@" $(EXE_LINK_FLAGS) $^
|
||||
else
|
||||
$(PROGRAM): $(PROG_OBJS) $(LIBRARY) $(FDLIBM_LIBRARY)
|
||||
$(CC) -o $@ $(CFLAGS) $(PROG_OBJS) $(LIBRARY) $(LDFLAGS) $(OTHER_LIBS) \
|
||||
$(PROG_LIBS)
|
||||
endif
|
||||
|
||||
$(PROGRAM).pure: $(PROG_OBJS) $(LIBRARY)
|
||||
purify $(PUREFLAGS) \
|
||||
$(CC) -o $@ $(PURE_OS_CFLAGS) $(PROG_OBJS) $(LIBRARY) $(LDFLAGS) \
|
||||
$(OTHER_LIBS) $(PROG_LIBS)
|
||||
|
||||
ifndef PREBUILT_CPUCFG
|
||||
$(HFILES) $(CFILES): $(OBJDIR)/jsautocfg.h
|
||||
|
||||
$(OBJDIR)/jsautocfg.h: $(OBJDIR)/jscpucfg
|
||||
rm -f $@
|
||||
$(OBJDIR)/jscpucfg > $@
|
||||
|
||||
$(OBJDIR)/jscpucfg: $(OBJDIR)/jscpucfg.o
|
||||
$(CC) -o $@ $(OBJDIR)/jscpucfg.o
|
||||
|
||||
# Look in OBJDIR to find jsautocfg.h
|
||||
INCLUDES += -I$(OBJDIR)
|
||||
|
||||
# Add to TARGETS for clobber rule
|
||||
TARGETS += $(OBJDIR)/jsautocfg.h $(OBJDIR)/jscpucfg $(OBJDIR)/jscpucfg.o
|
||||
endif
|
||||
|
||||
|
||||
# special rule for jsmath.o since we want to incrementally link
|
||||
# against fdlibm to pull in only what is needed
|
||||
$(OBJDIR)/jsmath.o: $(FDLIBM_LIBRARY) $(JSMATH_PRELINK)
|
||||
ifeq ($(OS_ARCH),QNX)
|
||||
ifneq ($(OS_TARGET),NTO)
|
||||
@cp $(JSMATH_PRELINK) $@
|
||||
else
|
||||
$(LD) $(DASH_R) -o $@ $(JSMATH_PRELINK) $(FDLIBM_LIBRARY)
|
||||
endif
|
||||
else
|
||||
ifdef USE_MSVC
|
||||
@echo Warning: to use $(LIBRARY) must also link against $(FDLIBM_LIBRARY)
|
||||
@cp $(JSMATH_PRELINK) $@
|
||||
endif
|
||||
$(LD) $(DASH_R) -o $@ $(JSMATH_PRELINK) $(FDLIBM_LIBRARY)
|
||||
endif
|
||||
|
||||
$(JSMATH_PRELINK): jsmath.c
|
||||
ifneq (,$(filter OS2 WINNT,$(OS_ARCH)))
|
||||
$(CC) -Fo$@ -c $(CFLAGS) $<
|
||||
else
|
||||
$(CC) -o $@ -c $(CFLAGS) $<
|
||||
endif
|
||||
|
||||
#
|
||||
# Hardwire dependencies on jsopcode.tbl
|
||||
#
|
||||
jsopcode.h jsopcode.c: jsopcode.tbl
|
||||
|
||||
-include $(DEPENDENCIES)
|
||||
|
||||
TARNAME = jsref.tar
|
||||
TARFILES = files `cat files`
|
||||
|
||||
SUFFIXES: .i
|
||||
%.i: %.c
|
||||
$(CC) -C -E $(CFLAGS) $< > $*.i
|
||||
804
mozilla/js/src/README.html
Normal file
804
mozilla/js/src/README.html
Normal file
@@ -0,0 +1,804 @@
|
||||
<!--
|
||||
- The contents of this file are subject to the Netscape Public
|
||||
- License Version 1.1 (the "License"); you may not use this file
|
||||
- except in compliance with the License. You may obtain a copy of
|
||||
- the License at http://www.mozilla.org/NPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS
|
||||
- IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
- implied. See the License for the specific language governing
|
||||
- rights and limitations under the License.
|
||||
-
|
||||
- The Original Code is Mozilla Communicator client code, released
|
||||
- March 31, 1998.
|
||||
-
|
||||
- The Initial Developer of the Original Code is Netscape
|
||||
- Communications Corporation. Portions created by Netscape are
|
||||
- Copyright (C) 1998-1999 Netscape Communications Corporation. All
|
||||
- Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the
|
||||
- terms of the GNU Public License (the "GPL"), in which case the
|
||||
- provisions of the GPL are applicable instead of those above.
|
||||
- If you wish to allow use of your version of this file only
|
||||
- under the terms of the GPL and not to allow others to use your
|
||||
- version of this file under the NPL, indicate your decision by
|
||||
- deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the GPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this
|
||||
- file under either the NPL or the GPL.
|
||||
-->
|
||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="GENERATOR" content="Mozilla/4.5 [en] (WinNT; I) [Netscape]">
|
||||
<title>JavaScript Reference Implementation (JSRef) README</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>
|
||||
Table of Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#Introduction">Introduction</a></li>
|
||||
|
||||
<li>
|
||||
<a href="#Build">Build conventions (standalone JS engine and shell)</a></li>
|
||||
|
||||
<li>
|
||||
<a href="#Debugging">Debugging notes</a></li>
|
||||
|
||||
<li>
|
||||
<a href="#Conventions">Naming and coding conventions</a></li>
|
||||
|
||||
<li>
|
||||
<a href="#JSAPI">Using the JS API</a></li>
|
||||
|
||||
<li>
|
||||
<a href="#Design">Design walk-through</a></li>
|
||||
|
||||
<li>
|
||||
<a href="#Resources">Additional Resources (links, API docs, and newsgroups)</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
<a NAME="Introduction"></a>Introduction</h2>
|
||||
This is the README file for the <span CLASS=LXRSHORTDESC>JavaScript
|
||||
Reference (JSRef) implementation.</span> It consists of build conventions
|
||||
and instructions, source code conventions, a design walk-through, and a
|
||||
brief file-by-file description of the source.
|
||||
<p><span CLASS=LXRLONGDESC>JSRef builds a library or DLL containing the
|
||||
JavaScript runtime (compiler, interpreter, decompiler, garbage collector,
|
||||
atom manager, standard classes). It then compiles a small "shell" program
|
||||
and links that with the library to make an interpreter that can be used
|
||||
interactively and with test .js files to run scripts. The code has
|
||||
no dependencies on the Navigator code.</span>
|
||||
<p><i>Quick start tip</i>: skip to "Using the JS API" below, build the
|
||||
js shell, and play with the object named "it" (start by setting 'it.noisy
|
||||
= true').
|
||||
<h2>
|
||||
<a NAME="Build"></a>Build conventions (standalone JS engine and shell)</h2>
|
||||
These build directions refer only to building the standalone JavaScript
|
||||
engine and shell. To build within the browser, refer to the <a href="http://www.mozilla.org/docs/">build
|
||||
directions</a> on the mozilla.org website.
|
||||
<p>By default, all platforms build a version of the JS engine that is <i>not</i>
|
||||
threadsafe. If you require thread-safety, you must also populate
|
||||
the <tt>mozilla/dist</tt> directory with <a href="http://www.mozilla.org/docs/tplist/catCode/nsprdesc.htm">NSPR</a>
|
||||
headers and libraries. (NSPR implements a portable threading library,
|
||||
among other things. The source is downloadable via <a href="http://www.mozilla.org/cvs.html">CVS</a>
|
||||
from <tt><a href="http://lxr.mozilla.org/mozilla/source/nsprpub">mozilla/nsprpub</a></tt>.)
|
||||
Next, you must define <tt>JS_THREADSAFE</tt> when building the JS engine,
|
||||
either on the command-line (gmake/nmake) or in a universal header file.
|
||||
<h3>
|
||||
Windows</h3>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Use MSVC 4.2 or 5.0.</li>
|
||||
|
||||
<li>
|
||||
For building from the IDE use <tt>js/src/js.mdp</tt>. (<tt>js.mdp</tt>
|
||||
is an MSVC4.2 project file, but if you load it into MSVC5, it will be converted
|
||||
to the newer project file format.) <font color="#CC0000">NOTE: makefile.win
|
||||
is an nmake file used only for building the JS-engine in the Mozilla browser.
|
||||
Don't attempt to use it to build the standalone JS-engine.</font></li>
|
||||
|
||||
<li>
|
||||
If you prefer to build from the command-line, use '<tt>nmake -f js.mak</tt>'</li>
|
||||
|
||||
<li>
|
||||
Executable shell <tt>js.exe</tt> and runtime library <tt>js32.dll</tt>
|
||||
are created in either <tt>js/src/Debug</tt> or <tt>js/src/Release</tt>.</li>
|
||||
</ul>
|
||||
|
||||
<h3>
|
||||
Macintosh</h3>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Use CodeWarrior 3.x</li>
|
||||
|
||||
<li>
|
||||
Load the project file <tt>js:src:macbuild:JSRef.mcp </tt>and select "Make"
|
||||
from the menu.</li>
|
||||
</ul>
|
||||
|
||||
<h3>
|
||||
Unix</h3>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Use '<tt>gmake -f Makefile.ref</tt>' to build. To compile optimized code,
|
||||
pass <tt>BUILD_OPT=1</tt> on the gmake command line or preset it in the
|
||||
environment or <tt>Makefile.ref</tt>. <font color="#CC0000">NOTE:
|
||||
Do not attempt to use Makefile to build the standalone JavaScript engine.
|
||||
This file is used only for building the JS-engine in the Mozilla browser.</font></li>
|
||||
|
||||
<li>
|
||||
<font color="#000000">Each platform on which JS is built must have a <tt>*.mk</tt>
|
||||
configuration file in the <tt>js/src/config</tt> directory. The configuration
|
||||
file specifies the compiler/linker to be used and allows for customization
|
||||
of command-line options. To date, the build system has been tested
|
||||
on Solaris, AIX, HP/UX, OSF, IRIX, x86 Linux and Windows NT.</font></li>
|
||||
|
||||
<li>
|
||||
<font color="#000000">Most platforms will work with either the vendor compiler
|
||||
</font>or
|
||||
<a href="ftp://prep.ai.mit.edu/pub/gnu">gcc</a>.
|
||||
(Except that HP builds only work using the native compiler. gcc won't
|
||||
link correctly with shared libraries on that platform. If someone
|
||||
knows a way to fix this, <a href="mailto:wynholds@netscape.com">let us
|
||||
know</a>.)</li>
|
||||
|
||||
<li>
|
||||
<font color="#000000">If you define <tt>JS_LIVECONNECT</tt>, gmake will
|
||||
descend into the liveconnect directory and build
|
||||
<a href="http://lxr.mozilla.org/mozilla/source/js/src/liveconnect/README.html">LiveConnect</a>
|
||||
after building the JS engine.</font></li>
|
||||
|
||||
<li>
|
||||
To build a binary drop (a zip'ed up file of headers, libraries, binaries),
|
||||
check out <tt>mozilla/config</tt> and <tt>mozilla/nsprpub/config</tt>.
|
||||
Use '<tt>gmake -f Makefile.ref nsinstall-target all export ship</tt>'</li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
<a NAME="Debugging"></a>Debugging notes</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
To turn on GC instrumentation, define <tt>JS_GCMETER</tt>.</li>
|
||||
|
||||
<li>
|
||||
To turn on the arena package's instrumentation, define <tt>JS_ARENAMETER</tt>.</li>
|
||||
|
||||
<li>
|
||||
To turn on the hash table package's metering, define <tt>JS_HASHMETER</tt>.</li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
<a NAME="Conventions"></a>Naming and coding conventions</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Public function names begin with <tt>JS_</tt> followed by capitalized "intercaps",
|
||||
e.g. <tt>JS_NewObject</tt>.</li>
|
||||
|
||||
<li>
|
||||
Extern but library-private function names use a <tt>js_</tt> prefix and
|
||||
mixed case, e.g. <tt>js_LookupSymbol</tt>.</li>
|
||||
|
||||
<li>
|
||||
Most static function names have unprefixed, mixed-case names: <tt>GetChar</tt>.</li>
|
||||
|
||||
<li>
|
||||
But static native methods of JS objects have lowercase, underscore-separated
|
||||
or intercaps names, e.g., <tt>str_indexOf</tt>.</li>
|
||||
|
||||
<li>
|
||||
And library-private and static data use underscores, not intercaps (but
|
||||
library-private data do use a <tt>js_</tt> prefix).</li>
|
||||
|
||||
<li>
|
||||
Scalar type names are lowercase and js-prefixed: <tt>jsdouble</tt>.</li>
|
||||
|
||||
<li>
|
||||
Aggregate type names are JS-prefixed and mixed-case: <tt>JSObject.</tt></li>
|
||||
|
||||
<li>
|
||||
Macros are generally <tt>ALL_CAPS </tt>and underscored, to call out potential
|
||||
side effects, multiple uses of a formal argument, etc. - Four spaces of
|
||||
indentation per statement nesting level.</li>
|
||||
|
||||
<li>
|
||||
Tabs are taken to be eight spaces, and an Emacs magic comment at the top
|
||||
of each file tries to help. If you're using MSVC or similar, you'll want
|
||||
to set tab width to 8, or convert these files to be space-filled.</li>
|
||||
|
||||
<li>
|
||||
DLL entry points have their return type expanded within a <tt>JS_PUBLIC_API()</tt>
|
||||
macro call, to get the right Windows secret type qualifiers in the right
|
||||
places for both 16- and 32-bit builds.</li>
|
||||
|
||||
<li>
|
||||
Callback functions that might be called from a DLL are similarly macroized
|
||||
with <tt>JS_STATIC_DLL_CALLBACK</tt> (if the function otherwise would be
|
||||
static to hide its name) or <tt>JS_DLL_CALLBACK</tt> (this macro takes
|
||||
no type argument; it should be used after the return type and before the
|
||||
function name).</li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
<a NAME="JSAPI"></a>Using the JS API</h2>
|
||||
|
||||
<h4>
|
||||
Starting up</h4>
|
||||
|
||||
<pre><tt> /*
|
||||
* Tune this to avoid wasting space for shallow stacks, while saving on
|
||||
* malloc overhead/fragmentation for deep or highly-variable stacks.
|
||||
*/
|
||||
#define STACK_CHUNK_SIZE 8192
|
||||
|
||||
JSRuntime *rt;
|
||||
JSContext *cx;
|
||||
|
||||
/* You need a runtime and one or more contexts to do anything with JS. */
|
||||
rt = JS_Init(1000000L);
|
||||
if (!rt)
|
||||
fail("can't create JavaScript runtime");
|
||||
cx = JS_NewContext(rt, STACK_CHUNK_SIZE);
|
||||
if (!cx)
|
||||
fail("can't create JavaScript context");
|
||||
|
||||
/*
|
||||
* The context definitely wants a global object, in order to have standard
|
||||
* classes and functions like Date and parseInt. See below for details on
|
||||
* JS_NewObject.
|
||||
*/
|
||||
JSObject *globalObj;
|
||||
|
||||
globalObj = JS_NewObject(cx, &my_global_class, 0, 0);
|
||||
JS_InitStandardClasses(cx, globalObj);</tt></pre>
|
||||
|
||||
<h4>
|
||||
Defining objects and properties</h4>
|
||||
|
||||
<pre><tt> /* Statically initialize a class to make "one-off" objects. */
|
||||
JSClass my_class = {
|
||||
"MyClass",
|
||||
|
||||
/* All of these can be replaced with the corresponding JS_*Stub
|
||||
function pointers. */
|
||||
my_addProperty, my_delProperty, my_getProperty, my_setProperty,
|
||||
my_enumerate, my_resolve, my_convert, my_finalize
|
||||
};
|
||||
|
||||
JSObject *obj;
|
||||
|
||||
/*
|
||||
* Define an object named in the global scope that can be enumerated by
|
||||
* for/in loops. The parent object is passed as the second argument, as
|
||||
* with all other API calls that take an object/name pair. The prototype
|
||||
* passed in is null, so the default object prototype will be used.
|
||||
*/
|
||||
obj = JS_DefineObject(cx, globalObj, "myObject", &my_class, 0,
|
||||
JSPROP_ENUMERATE);
|
||||
|
||||
/*
|
||||
* Define a bunch of properties with a JSPropertySpec array statically
|
||||
* initialized and terminated with a null-name entry. Besides its name,
|
||||
* each property has a "tiny" identifier (MY_COLOR, e.g.) that can be used
|
||||
* in switch statements (in a common my_getProperty function, for example).
|
||||
*/
|
||||
enum my_tinyid {
|
||||
MY_COLOR, MY_HEIGHT, MY_WIDTH, MY_FUNNY, MY_ARRAY, MY_RDONLY
|
||||
};
|
||||
|
||||
static JSPropertySpec my_props[] = {
|
||||
{"color", MY_COLOR, JSPROP_ENUMERATE},
|
||||
{"height", MY_HEIGHT, JSPROP_ENUMERATE},
|
||||
{"width", MY_WIDTH, JSPROP_ENUMERATE},
|
||||
{"funny", MY_FUNNY, JSPROP_ENUMERATE},
|
||||
{"array", MY_ARRAY, JSPROP_ENUMERATE},
|
||||
{"rdonly", MY_RDONLY, JSPROP_READONLY},
|
||||
{0}
|
||||
};
|
||||
|
||||
JS_DefineProperties(cx, obj, my_props);
|
||||
|
||||
/*
|
||||
* Given the above definitions and call to JS_DefineProperties, obj will
|
||||
* need this sort of "getter" method in its class (my_class, above). See
|
||||
* the example for the "It" class in js.c.
|
||||
*/
|
||||
static JSBool
|
||||
my_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
{
|
||||
if (JSVAL_IS_INT(id)) {
|
||||
switch (JSVAL_TO_INT(id)) {
|
||||
case MY_COLOR: *vp = . . .; break;
|
||||
case MY_HEIGHT: *vp = . . .; break;
|
||||
case MY_WIDTH: *vp = . . .; break;
|
||||
case MY_FUNNY: *vp = . . .; break;
|
||||
case MY_ARRAY: *vp = . . .; break;
|
||||
case MY_RDONLY: *vp = . . .; break;
|
||||
}
|
||||
}
|
||||
return JS_TRUE;
|
||||
}</tt></pre>
|
||||
|
||||
<h4>
|
||||
Defining functions</h4>
|
||||
|
||||
<pre><tt> /* Define a bunch of native functions first: */
|
||||
static JSBool
|
||||
my_abs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsdouble x, z;
|
||||
|
||||
if (!JS_ValueToNumber(cx, argv[0], &x))
|
||||
return JS_FALSE;
|
||||
z = (x < 0) ? -x : x;
|
||||
return JS_NewDoubleValue(cx, z, rval);
|
||||
}
|
||||
|
||||
. . .
|
||||
|
||||
/*
|
||||
* Use a JSFunctionSpec array terminated with a null name to define a
|
||||
* bunch of native functions.
|
||||
*/
|
||||
static JSFunctionSpec my_functions[] = {
|
||||
/* name native nargs */
|
||||
{"abs", my_abs, 1},
|
||||
{"acos", my_acos, 1},
|
||||
{"asin", my_asin, 1},
|
||||
. . .
|
||||
{0}
|
||||
};
|
||||
|
||||
/*
|
||||
* Pass a particular object to define methods for it alone. If you pass
|
||||
* a prototype object, the methods will apply to all instances past and
|
||||
* future of the prototype's class (see below for classes).
|
||||
*/
|
||||
JS_DefineFunctions(cx, globalObj, my_functions);</tt></pre>
|
||||
|
||||
<h4>
|
||||
Defining classes</h4>
|
||||
|
||||
<pre><tt> /*
|
||||
* This pulls together the above API elements by defining a constructor
|
||||
* function, a prototype object, and properties of the prototype and of
|
||||
* the constructor, all with one API call.
|
||||
*
|
||||
* Initialize a class by defining its constructor function, prototype, and
|
||||
* per-instance and per-class properties. The latter are called "static"
|
||||
* below by analogy to Java. They are defined in the constructor object's
|
||||
* scope, so that 'MyClass.myStaticProp' works along with 'new MyClass()'.
|
||||
*
|
||||
* JS_InitClass takes a lot of arguments, but you can pass null for any of
|
||||
* the last four if there are no such properties or methods.
|
||||
*
|
||||
* Note that you do not need to call JS_InitClass to make a new instance of
|
||||
* that class -- otherwise there would be a chicken-and-egg problem making
|
||||
* the global object -- but you should call JS_InitClass if you require a
|
||||
* constructor function for script authors to call via new, and/or a class
|
||||
* prototype object ('MyClass.prototype') for authors to extend with new
|
||||
* properties at run-time.
|
||||
*/
|
||||
protoObj = JS_InitClass(cx, globalObj, NULL, &my_class,
|
||||
|
||||
/* native constructor function and min arg count */
|
||||
MyClass, 0,
|
||||
|
||||
/* prototype object properties and methods -- these
|
||||
will be "inherited" by all instances through
|
||||
delegation up the instance's prototype link. */
|
||||
my_props, my_methods,
|
||||
|
||||
/* class constructor properties and methods */
|
||||
my_static_props, my_static_methods);</tt></pre>
|
||||
|
||||
<h4>
|
||||
Running scripts</h4>
|
||||
|
||||
<pre><tt> /* These should indicate source location for diagnostics. */
|
||||
char *filename;
|
||||
uintN lineno;
|
||||
|
||||
/*
|
||||
* The return value comes back here -- if it could be a GC thing, you must
|
||||
* add it to the GC's "root set" with JS_AddRoot(cx, &thing) where thing
|
||||
* is a JSString *, JSObject *, or jsdouble *, and remove the root before
|
||||
* rval goes out of scope, or when rval is no longer needed.
|
||||
*/
|
||||
jsval rval;
|
||||
JSBool ok;
|
||||
|
||||
/*
|
||||
* Some example source in a C string. Larger, non-null-terminated buffers
|
||||
* can be used, if you pass the buffer length to JS_EvaluateScript.
|
||||
*/
|
||||
char *source = "x * f(y)";
|
||||
|
||||
ok = JS_EvaluateScript(cx, globalObj, source, strlen(source),
|
||||
filename, lineno, &rval);
|
||||
|
||||
if (ok) {
|
||||
/* Should get a number back from the example source. */
|
||||
jsdouble d;
|
||||
|
||||
ok = JS_ValueToNumber(cx, rval, &d);
|
||||
. . .
|
||||
}</tt></pre>
|
||||
|
||||
<h4>
|
||||
Calling functions</h4>
|
||||
|
||||
<pre><tt> /* Call a global function named "foo" that takes no arguments. */
|
||||
ok = JS_CallFunctionName(cx, globalObj, "foo", 0, 0, &rval);
|
||||
|
||||
jsval argv[2];
|
||||
|
||||
/* Call a function in obj's scope named "method", passing two arguments. */
|
||||
argv[0] = . . .;
|
||||
argv[1] = . . .;
|
||||
ok = JS_CallFunctionName(cx, obj, "method", 2, argv, &rval);</tt></pre>
|
||||
|
||||
<h4>
|
||||
Shutting down</h4>
|
||||
|
||||
<pre><tt> /* For each context you've created: */
|
||||
JS_DestroyContext(cx);
|
||||
|
||||
/* And finally: */
|
||||
JS_Finish(rt);</tt></pre>
|
||||
|
||||
<h4>
|
||||
Debugging API</h4>
|
||||
See the<tt> trap, untrap, watch, unwatch, line2pc</tt>, and <tt>pc2line</tt>
|
||||
commands in <tt>js.c</tt>. Also the (scant) comments in <i>jsdbgapi.h</i>.
|
||||
<h2>
|
||||
<a NAME="Design"></a>Design walk-through</h2>
|
||||
This section must be brief for now -- it could easily turn into a book.
|
||||
<h4>
|
||||
JS "JavaScript Proper"</h4>
|
||||
JS modules declare and implement the JavaScript compiler, interpreter,
|
||||
decompiler, GC and atom manager, and standard classes.
|
||||
<p>JavaScript uses untyped bytecode and runtime type tagging of data values.
|
||||
The <tt>jsval</tt> type is a signed machine word that contains either a
|
||||
signed integer value (if the low bit is set), or a type-tagged pointer
|
||||
or boolean value (if the low bit is clear). Tagged pointers all refer to
|
||||
8-byte-aligned things in the GC heap.
|
||||
<p>Objects consist of a possibly shared structural description, called
|
||||
the map or scope; and unshared property values in a vector, called the
|
||||
slots. Object properties are associated with nonnegative integers stored
|
||||
in <tt>jsval</tt>'s, or with atoms (unique string descriptors) if named
|
||||
by an identifier or a non-integral index expression.
|
||||
<p>Scripts contain bytecode, source annotations, and a pool of string,
|
||||
number, and identifier literals. Functions are objects that extend scripts
|
||||
or native functions with formal parameters, a literal syntax, and a distinct
|
||||
primitive type ("function").
|
||||
<p>The compiler consists of a recursive-descent parser and a random-logic
|
||||
rather than table-driven lexical scanner. Semantic and lexical feedback
|
||||
are used to disambiguate hard cases such as missing semicolons, assignable
|
||||
expressions ("lvalues" in C parlance), etc. The parser generates bytecode
|
||||
as it parses, using fixup lists for downward branches and code buffering
|
||||
and rewriting for exceptional cases such as for loops. It attempts no error
|
||||
recovery. The interpreter executes the bytecode of top-level scripts, and
|
||||
calls itself indirectly to interpret function bodies (which are also scripts).
|
||||
All state associated with an interpreter instance is passed through formal
|
||||
parameters to the interpreter entry point; most implicit state is collected
|
||||
in a type named JSContext. Therefore, all API and almost all other functions
|
||||
in JSRef take a JSContext pointer as their first argument.
|
||||
<p>The decompiler translates postfix bytecode into infix source by consulting
|
||||
a separate byte-sized code, called source notes, to disambiguate bytecodes
|
||||
that result from more than one grammatical production.
|
||||
<p>The GC is a mark-and-sweep, non-conservative (perfect) collector. It
|
||||
can allocate only fixed-sized things -- the current size is two machine
|
||||
words. It is used to hold JS object and string descriptors (but not property
|
||||
lists or string bytes), and double-precision floating point numbers. It
|
||||
runs automatically only when maxbytes (as passed to <tt>JS_Init()</tt>)
|
||||
bytes of GC things have been allocated and another thing-allocation request
|
||||
is made. JS API users should call <tt>JS_GC()</tt> or <tt>JS_MaybeGC()</tt>
|
||||
between script executions or from the branch callback, as often as necessary.
|
||||
<p>An important point about the GC's "perfection": you must add roots for
|
||||
new objects created by your native methods if you store references to them
|
||||
into a non-JS structure in the malloc heap or in static data. Also, if
|
||||
you make a new object in a native method, but do not store it through the
|
||||
<tt>rval</tt>
|
||||
result parameter (see math_abs in the "Using the JS API" section above)
|
||||
so that it is in a known root, the object is guaranteed to survive only
|
||||
until another new object is created. Either lock the first new object when
|
||||
making two in a row, or store it in a root you've added, or store it via
|
||||
rval.
|
||||
<p>The atom manager consists of a hash table associating strings uniquely
|
||||
with scanner/parser information such as keyword type, index in script or
|
||||
function literal pool, etc. Atoms play three roles in JSRef: as literals
|
||||
referred to by unaligned 16-bit immediate bytecode operands, as unique
|
||||
string descriptors for efficient property name hashing, and as members
|
||||
of the root GC set for perfect GC. This design therefore requires atoms
|
||||
to be manually reference counted, from script literal pools (<tt>JSAtomMap</tt>)
|
||||
and object symbol (<tt>JSSymbol</tt>) entry keys.
|
||||
<p>Native objects and methods for arrays, booleans, dates, functions, numbers,
|
||||
and strings are implemented using the JS API and certain internal interfaces
|
||||
used as "fast paths".
|
||||
<p>In general, errors are signaled by false or unoverloaded-null return
|
||||
values, and are reported using <tt>JS_ReportError()</tt> or one of its
|
||||
variants by the lowest level in order to provide the most detail. Client
|
||||
code can substitute its own error reporting function and suppress errors,
|
||||
or reflect them into Java or some other runtime system as exceptions, GUI
|
||||
dialogs, etc..
|
||||
<h2>
|
||||
File walk-through (BADLY OUT OF DATE!)</h2>
|
||||
|
||||
<h4>
|
||||
jsapi.c, jsapi.h</h4>
|
||||
The public API to be used by almost all client code. If your client
|
||||
code can't make do with <tt>jsapi.h</tt>, and must reach into a friend
|
||||
or private js* file, please let us know so we can extend <tt>jsapi.h</tt>
|
||||
to include what you need in a fashion that we can support over the long
|
||||
run.
|
||||
<h4>
|
||||
jspubtd.h, jsprvtd.h</h4>
|
||||
These files exist to group struct and scalar typedefs so they can be used
|
||||
everywhere without dragging in struct definitions from N different files.
|
||||
The <tt>jspubtd.h</tt> file contains public typedefs, and is included by
|
||||
<tt>jsapi.h</tt>.
|
||||
The <tt>jsprvtd.h</tt> file contains private typedefs and is included by
|
||||
various .h files that need type names, but not type sizes or declarations.
|
||||
<h4>
|
||||
jsdbgapi.c, jsdbgapi.h</h4>
|
||||
The Debugging API, still very much under development. Provided so far:
|
||||
<ul>
|
||||
<li>
|
||||
Traps, with which breakpoints, single-stepping, step over, step out, and
|
||||
so on can be implemented. The debugger will have to consult jsopcode.def
|
||||
on its own to figure out where to plant trap instructions to implement
|
||||
functions like step out, but a future jsdbgapi.h will provide convenience
|
||||
interfaces to do these things. At most one trap per bytecode can be set.
|
||||
When a script (<tt>JSScript</tt>) is destroyed, all traps set in its bytecode
|
||||
are cleared.</li>
|
||||
|
||||
<li>
|
||||
Watchpoints, for intercepting set operations on properties and running
|
||||
a debugger-supplied function that receives the old value and a pointer
|
||||
to the new one, which it can use to modify the new value being set.</li>
|
||||
|
||||
<li>
|
||||
Line number to PC and back mapping functions. The line-to-PC direction
|
||||
"rounds" toward the next bytecode generated from a line greater than or
|
||||
equal to the input line, and may return the PC of a for-loop update part,
|
||||
if given the line number of the loop body's closing brace. Any line after
|
||||
the last one in a script or function maps to a PC one byte beyond the last
|
||||
bytecode in the script. An example, from perfect.js:</li>
|
||||
|
||||
<pre><tt>14 function perfect(n)
|
||||
15 {
|
||||
16 print("The perfect numbers up to " + n + " are:");
|
||||
17
|
||||
18 // We build sumOfDivisors[i] to hold a string expression for
|
||||
19 // the sum of the divisors of i, excluding i itself.
|
||||
20 var sumOfDivisors = new ExprArray(n+1,1);
|
||||
21 for (var divisor = 2; divisor <= n; divisor++) {
|
||||
22 for (var j = divisor + divisor; j <= n; j += divisor) {
|
||||
23 sumOfDivisors[j] += " + " + divisor;
|
||||
24 }
|
||||
25 // At this point everything up to 'divisor' has its sumOfDivisors
|
||||
26 // expression calculated, so we can determine whether it's perfect
|
||||
27 // already by evaluating.
|
||||
28 if (eval(sumOfDivisors[divisor]) == divisor) {
|
||||
29 print("" + divisor + " = " + sumOfDivisors[divisor]);
|
||||
30 }
|
||||
31 }
|
||||
32 delete sumOfDivisors;
|
||||
33 print("That's all.");
|
||||
34 }</tt></pre>
|
||||
The line number to PC and back mappings can be tested using the js program
|
||||
with the following script:
|
||||
<pre><tt> load("perfect.js")
|
||||
print(perfect)
|
||||
dis(perfect)
|
||||
|
||||
print()
|
||||
for (var ln = 0; ln <= 40; ln++) {
|
||||
var pc = line2pc(perfect,ln)
|
||||
var ln2 = pc2line(perfect,pc)
|
||||
print("\tline " + ln + " => pc " + pc + " => line " + ln2)
|
||||
}</tt></pre>
|
||||
The result of the for loop over lines 0 to 40 inclusive is:
|
||||
<pre><tt> line 0 => pc 0 => line 16
|
||||
line 1 => pc 0 => line 16
|
||||
line 2 => pc 0 => line 16
|
||||
line 3 => pc 0 => line 16
|
||||
line 4 => pc 0 => line 16
|
||||
line 5 => pc 0 => line 16
|
||||
line 6 => pc 0 => line 16
|
||||
line 7 => pc 0 => line 16
|
||||
line 8 => pc 0 => line 16
|
||||
line 9 => pc 0 => line 16
|
||||
line 10 => pc 0 => line 16
|
||||
line 11 => pc 0 => line 16
|
||||
line 12 => pc 0 => line 16
|
||||
line 13 => pc 0 => line 16
|
||||
line 14 => pc 0 => line 16
|
||||
line 15 => pc 0 => line 16
|
||||
line 16 => pc 0 => line 16
|
||||
line 17 => pc 19 => line 20
|
||||
line 18 => pc 19 => line 20
|
||||
line 19 => pc 19 => line 20
|
||||
line 20 => pc 19 => line 20
|
||||
line 21 => pc 36 => line 21
|
||||
line 22 => pc 53 => line 22
|
||||
line 23 => pc 74 => line 23
|
||||
line 24 => pc 92 => line 22
|
||||
line 25 => pc 106 => line 28
|
||||
line 26 => pc 106 => line 28
|
||||
line 27 => pc 106 => line 28
|
||||
line 28 => pc 106 => line 28
|
||||
line 29 => pc 127 => line 29
|
||||
line 30 => pc 154 => line 21
|
||||
line 31 => pc 154 => line 21
|
||||
line 32 => pc 161 => line 32
|
||||
line 33 => pc 172 => line 33
|
||||
line 34 => pc 172 => line 33
|
||||
line 35 => pc 172 => line 33
|
||||
line 36 => pc 172 => line 33
|
||||
line 37 => pc 172 => line 33
|
||||
line 38 => pc 172 => line 33
|
||||
line 39 => pc 172 => line 33
|
||||
line 40 => pc 172 => line 33</tt></pre>
|
||||
</ul>
|
||||
|
||||
<h4>
|
||||
jsconfig.h</h4>
|
||||
Various configuration macros defined as 0 or 1 depending on how <tt>JS_VERSION</tt>
|
||||
is defined (as 10 for JavaScript 1.0, 11 for JavaScript 1.1, etc.). Not
|
||||
all macros are tested around related code yet. In particular, JS 1.0 support
|
||||
is missing from JSRef. JS 1.2 support will appear in a future JSRef release.
|
||||
<br>
|
||||
<h4>
|
||||
js.c</h4>
|
||||
The "JS shell", a simple interpreter program that uses the JS API and more
|
||||
than a few internal interfaces (some of these internal interfaces could
|
||||
be replaced by <tt>jsapi.h</tt> calls). The js program built from this
|
||||
source provides a test vehicle for evaluating scripts and calling functions,
|
||||
trying out new debugger primitives, etc.
|
||||
<h4>
|
||||
jsarray.*, jsbool.*, jdsdate.*, jsfun.*, jsmath.*, jsnum.*, jsstr.*</h4>
|
||||
These file pairs implement the standard classes and (where they exist)
|
||||
their underlying primitive types. They have similar structure, generally
|
||||
starting with class definitions and continuing with internal constructors,
|
||||
finalizers, and helper functions.
|
||||
<h4>
|
||||
jsobj.*, jsscope.*</h4>
|
||||
These two pairs declare and implement the JS object system. All of the
|
||||
following happen here:
|
||||
<ul>
|
||||
<li>
|
||||
creating objects by class and prototype, and finalizing objects;</li>
|
||||
|
||||
<li>
|
||||
defining, looking up, getting, setting, and deleting properties;</li>
|
||||
|
||||
<li>
|
||||
creating and destroying properties and binding names to them.</li>
|
||||
</ul>
|
||||
The details of an object map (scope) are mostly hidden in <tt>jsscope.[ch]</tt>,
|
||||
where scopes start out as linked lists of symbols, and grow after some
|
||||
threshold into PR hash tables.
|
||||
<h4>
|
||||
jsatom.c, jsatom.h</h4>
|
||||
The atom manager. Contains well-known string constants, their atoms, the
|
||||
global atom hash table and related state, the js_Atomize() function that
|
||||
turns a counted string of bytes into an atom, and literal pool (<tt>JSAtomMap</tt>)
|
||||
methods.
|
||||
<h4>
|
||||
jsgc.c, jsgc.h</h4>
|
||||
[TBD]
|
||||
<h4>
|
||||
jsinterp.*, jscntxt.*</h4>
|
||||
The bytecode interpreter, and related functions such as Call and AllocStack,
|
||||
live in <i>jsinterp.c</i>. The JSContext constructor and destructor are
|
||||
factored out into <i>jscntxt.c</i> for minimal linking when the compiler
|
||||
part of JS is split from the interpreter part into a separate program.
|
||||
<h4>
|
||||
jsemit.*, jsopcode.tbl, jsopcode.*, jsparse.*, jsscan.*, jsscript.*</h4>
|
||||
Compiler and decompiler modules. The <i>jsopcode.tbl</i> file is a C preprocessor
|
||||
source that defines almost everything there is to know about JS bytecodes.
|
||||
See its major comment for how to use it. For now, a debugger will use it
|
||||
and its dependents such as <i>jsopcode.h</i> directly, but over time we
|
||||
intend to extend <i>jsdbgapi.h</i> to hide uninteresting details and provide
|
||||
conveniences. The code generator is split across paragraphs of code in
|
||||
<i>jsparse.c</i>,
|
||||
and the utility methods called on <tt>JSCodeGenerator</tt> appear in <i>jsemit.c</i>.
|
||||
Source notes generated by <i>jsparse.c</i> and
|
||||
<i>jsemit.c</i> are used
|
||||
in <i>jsscript.c</i> to map line number to program counter and back.
|
||||
<h4>
|
||||
jstypes.h, jslog2.c</h4>
|
||||
Fundamental representation types and utility macros. This file alone among
|
||||
all .h files in JSRef must be included first by .c files. It is not nested
|
||||
in .h files, as other prerequisite .h files generally are, since it is
|
||||
also a direct dependency of most .c files and would be over-included if
|
||||
nested in addition to being directly included. The one "not-quite-a-macro
|
||||
macro" is the <tt>JS_CeilingLog2()</tt> function in <i>jslog2.c</i>.
|
||||
<h4>
|
||||
jsarena.c, jsarena.h</h4>
|
||||
Last-In-First-Out allocation macros that amortize malloc costs and allow
|
||||
for en-masse freeing. See the paper mentioned in prarena.h's major comment.
|
||||
<h4>
|
||||
jsutil.c, jsutil.h</h4>
|
||||
The <tt>JS_ASSERT</tt> macro is used throughout JSRef source as a proof
|
||||
device to make invariants and preconditions clear to the reader, and to
|
||||
hold the line during maintenance and evolution against regressions or violations
|
||||
of assumptions that it would be too expensive to test unconditionally at
|
||||
run-time. Certain assertions are followed by run-time tests that cope with
|
||||
assertion failure, but only where I'm too smart or paranoid to believe
|
||||
the assertion will never fail...
|
||||
<h4>
|
||||
jsclist.h</h4>
|
||||
Doubly-linked circular list struct and macros.
|
||||
<h4>
|
||||
jscpucfg.c</h4>
|
||||
This standalone program generates <i>jscpucfg.h</i>, a header file containing
|
||||
bytes per word and other constants that depend on CPU architecture and
|
||||
C compiler type model. It tries to discover most of these constants by
|
||||
running its own experiments on the build host, so if you are cross-compiling,
|
||||
beware.
|
||||
<h4>
|
||||
prdtoa.c, prdtoa.h</h4>
|
||||
David Gay's portable double-precision floating point to string conversion
|
||||
code, with Permission To Use notice included.
|
||||
<h4>
|
||||
prhash.c, prhash.h</h4>
|
||||
Portable, extensible hash tables. These use multiplicative hash for strength
|
||||
reduction over division hash, yet with very good key distribution over
|
||||
power of two table sizes. Collisions resolve via chaining, so each entry
|
||||
burns a malloc and can fragment the heap.
|
||||
<h4>
|
||||
prlong.c, prlong.h</h4>
|
||||
64-bit integer emulation, and compatible macros that use C's long long
|
||||
type where it exists (my last company mapped long long to a 128-bit type,
|
||||
but no real architecture does 128-bit ints yet).
|
||||
<h4>
|
||||
jsosdep.h</h4>
|
||||
Annoying OS dependencies rationalized into a few "feature-test" macros
|
||||
such as <tt>JS_HAVE_LONG_LONG</tt>.
|
||||
<h4>
|
||||
jsprf.*</h4>
|
||||
Portable, buffer-overrun-resistant sprintf and friends. For no good reason
|
||||
save lack of time, the %e, %f, and %g formats cause your system's native
|
||||
sprintf, rather than <tt>JS_dtoa()</tt>, to be used. This bug doesn't affect
|
||||
JSRef, because it uses its own <tt>JS_dtoa()</tt> call in <i>jsnum.c</i>
|
||||
to convert from double to string, but it's a bug that we'll fix later,
|
||||
and one you should be aware of if you intend to use a <tt>JS_*printf()</tt>
|
||||
function with your own floating type arguments - various vendor sprintf's
|
||||
mishandle NaN, +/-Inf, and some even print normal floating values inaccurately.
|
||||
<h4>
|
||||
prmjtime.c, prmjtime.h</h4>
|
||||
Time functions. These interfaces are named in a way that makes local vs.
|
||||
universal time confusion likely. Caveat emptor, and we're working on it.
|
||||
To make matters worse, Java (and therefore JavaScript) uses "local" time
|
||||
numbers (offsets from the epoch) in its Date class.
|
||||
|
||||
|
||||
<h2>
|
||||
<a NAME="Resources"></a>Additional Resources (links, API docs, and newsgroups)</h2>
|
||||
<ul>
|
||||
<li><a href ="http://www.mozilla.org/js/">http://www.mozilla.org/js/</a>
|
||||
<li><a href ="http://www.mozilla.org/js/spidermonkey/">http://www.mozilla.org/js/spidermonkey/</a>
|
||||
<li><a href ="news://news.mozilla.org/netscape.public.mozilla.jseng">news://news.mozilla.org/netscape.public.mozilla.jseng</a>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
12
mozilla/js/src/SpiderMonkey.rsp
Normal file
12
mozilla/js/src/SpiderMonkey.rsp
Normal file
@@ -0,0 +1,12 @@
|
||||
mozilla/js/src/*
|
||||
mozilla/js/src/config/*
|
||||
mozilla/js/src/fdlibm/*
|
||||
mozilla/js/src/liveconnect/*
|
||||
mozilla/js/src/liveconnect/_jni/*
|
||||
mozilla/js/src/liveconnect/classes/*
|
||||
mozilla/js/src/liveconnect/classes/netscape/*
|
||||
mozilla/js/src/liveconnect/classes/netscape/javascript/*
|
||||
mozilla/js/src/liveconnect/config/*
|
||||
mozilla/js/src/liveconnect/macbuild/*
|
||||
mozilla/js/src/liveconnect/macbuild/JavaSession/*
|
||||
mozilla/js/src/macbuild/*
|
||||
125
mozilla/js/src/config.mk
Normal file
125
mozilla/js/src/config.mk
Normal file
@@ -0,0 +1,125 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998-1999 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
#
|
||||
|
||||
ifdef JS_DIST
|
||||
DIST = $(JS_DIST)
|
||||
else
|
||||
DIST = $(DEPTH)/../../dist/$(OBJDIR)
|
||||
endif
|
||||
|
||||
# Set os+release dependent make variables
|
||||
OS_ARCH := $(subst /,_,$(shell uname -s | sed /\ /s//_/))
|
||||
|
||||
# Attempt to differentiate between SunOS 5.4 and x86 5.4
|
||||
OS_CPUARCH := $(shell uname -m)
|
||||
ifeq ($(OS_CPUARCH),i86pc)
|
||||
OS_RELEASE := $(shell uname -r)_$(OS_CPUARCH)
|
||||
else
|
||||
ifeq ($(OS_ARCH),AIX)
|
||||
OS_RELEASE := $(shell uname -v).$(shell uname -r)
|
||||
else
|
||||
OS_RELEASE := $(shell uname -r)
|
||||
endif
|
||||
endif
|
||||
ifeq ($(OS_ARCH),IRIX64)
|
||||
OS_ARCH := IRIX
|
||||
endif
|
||||
|
||||
# Virtually all Linux versions are identical.
|
||||
# Any distinctions are handled in linux.h
|
||||
ifeq ($(OS_ARCH),Linux)
|
||||
OS_CONFIG := Linux_All
|
||||
else
|
||||
ifeq ($(OS_ARCH),dgux)
|
||||
OS_CONFIG := dgux
|
||||
else
|
||||
OS_CONFIG := $(OS_ARCH)$(OS_OBJTYPE)$(OS_RELEASE)
|
||||
endif
|
||||
endif
|
||||
|
||||
ASFLAGS =
|
||||
DEFINES =
|
||||
|
||||
ifeq ($(OS_ARCH), WINNT)
|
||||
INSTALL = nsinstall
|
||||
CP = cp
|
||||
else
|
||||
INSTALL = $(DEPTH)/../../dist/$(OBJDIR)/bin/nsinstall
|
||||
CP = cp
|
||||
endif
|
||||
|
||||
ifdef BUILD_OPT
|
||||
OPTIMIZER = -O
|
||||
DEFINES += -UDEBUG -DNDEBUG -UDEBUG_$(shell whoami)
|
||||
OBJDIR_TAG = _OPT
|
||||
else
|
||||
ifdef USE_MSVC
|
||||
OPTIMIZER = -Zi
|
||||
else
|
||||
OPTIMIZER = -g
|
||||
endif
|
||||
DEFINES += -DDEBUG -DDEBUG_$(shell whoami)
|
||||
OBJDIR_TAG = _DBG
|
||||
endif
|
||||
|
||||
SO_SUFFIX = so
|
||||
|
||||
NS_USE_NATIVE = 1
|
||||
|
||||
# Java stuff
|
||||
CLASSDIR = $(DEPTH)/liveconnect/classes
|
||||
JAVA_CLASSES = $(patsubst %.java,%.class,$(JAVA_SRCS))
|
||||
TARGETS += $(addprefix $(CLASSDIR)/$(OBJDIR)/$(JARPATH)/, $(JAVA_CLASSES))
|
||||
JAVAC = $(JDK)/bin/javac
|
||||
JAVAC_FLAGS = -classpath "$(CLASSPATH)" -d $(CLASSDIR)/$(OBJDIR)
|
||||
ifeq ($(OS_ARCH), WINNT)
|
||||
SEP = ;
|
||||
else
|
||||
SEP = :
|
||||
endif
|
||||
CLASSPATH = $(JDK)/lib/classes.zip$(SEP)$(CLASSDIR)/$(OBJDIR)
|
||||
|
||||
include $(DEPTH)/config/$(OS_CONFIG).mk
|
||||
|
||||
# Name of the binary code directories
|
||||
ifdef BUILD_IDG
|
||||
OBJDIR = $(OS_CONFIG)$(OBJDIR_TAG).OBJD
|
||||
else
|
||||
OBJDIR = $(OS_CONFIG)$(OBJDIR_TAG).OBJ
|
||||
endif
|
||||
VPATH = $(OBJDIR)
|
||||
|
||||
# Automatic make dependencies file
|
||||
DEPENDENCIES = $(OBJDIR)/.md
|
||||
|
||||
LCJAR = js14lc30.jar
|
||||
59
mozilla/js/src/config/AIX4.1.mk
Normal file
59
mozilla/js/src/config/AIX4.1.mk
Normal file
@@ -0,0 +1,59 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
#
|
||||
|
||||
#
|
||||
# Config stuff for AIX
|
||||
#
|
||||
|
||||
CC = xlC_r
|
||||
CCC = xlC_r
|
||||
|
||||
RANLIB = ranlib
|
||||
|
||||
#.c.o:
|
||||
# $(CC) -c -MD $*.d $(CFLAGS) $<
|
||||
ARCH := aix
|
||||
CPU_ARCH = rs6000
|
||||
GFX_ARCH = x
|
||||
INLINES = js_compare_and_swap:js_fast_lock1:js_fast_unlock1:js_lock_get_slot:js_lock_set_slot:js_lock_scope1
|
||||
|
||||
OS_CFLAGS = -qarch=com -qinline+$(INLINES) -DXP_UNIX -DAIX -DAIXV3 -DSYSV
|
||||
OS_LIBS = -lbsd -lsvld -lm
|
||||
#-lpthreads -lc_r
|
||||
|
||||
MKSHLIB = $(LD) -bM:SRE -bh:4 -bnoentry -berok
|
||||
XLDFLAGS += -lc
|
||||
|
||||
ifdef JS_THREADSAFE
|
||||
XLDFLAGS += -lsvld
|
||||
endif
|
||||
58
mozilla/js/src/config/AIX4.2.mk
Normal file
58
mozilla/js/src/config/AIX4.2.mk
Normal file
@@ -0,0 +1,58 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
#
|
||||
|
||||
#
|
||||
# Config stuff for AIX
|
||||
#
|
||||
|
||||
CC = xlC_r
|
||||
CCC = xlC_r
|
||||
CFLAGS += -qarch=com -qnoansialias -qinline+$(INLINES) -DXP_UNIX -DAIX -DAIXV3 -DSYSV
|
||||
|
||||
RANLIB = ranlib
|
||||
|
||||
#.c.o:
|
||||
# $(CC) -c -MD $*.d $(CFLAGS) $<
|
||||
ARCH := aix
|
||||
CPU_ARCH = rs6000
|
||||
GFX_ARCH = x
|
||||
INLINES = js_compare_and_swap:js_fast_lock1:js_fast_unlock1:js_lock_get_slot:js_lock_set_slot:js_lock_scope1
|
||||
|
||||
#-lpthreads -lc_r
|
||||
|
||||
MKSHLIB = /usr/lpp/xlC/bin/makeC++SharedLib_r -p 0 -G -berok
|
||||
|
||||
ifdef JS_THREADSAFE
|
||||
XLDFLAGS += -ldl
|
||||
endif
|
||||
|
||||
59
mozilla/js/src/config/AIX4.3.mk
Normal file
59
mozilla/js/src/config/AIX4.3.mk
Normal file
@@ -0,0 +1,59 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
#
|
||||
|
||||
#
|
||||
# Config stuff for AIX
|
||||
#
|
||||
|
||||
CC = xlC_r
|
||||
CCC = xlC_r
|
||||
CFLAGS += -qarch=com -qnoansialias -qinline+$(INLINES) -DXP_UNIX -DAIX -DAIXV3 -DSYSV -DAIX4_3
|
||||
|
||||
RANLIB = ranlib
|
||||
|
||||
#.c.o:
|
||||
# $(CC) -c -MD $*.d $(CFLAGS) $<
|
||||
ARCH := aix
|
||||
CPU_ARCH = rs6000
|
||||
GFX_ARCH = x
|
||||
INLINES = js_compare_and_swap:js_fast_lock1:js_fast_unlock1:js_lock_get_slot:js_lock_set_slot:js_lock_scope1
|
||||
|
||||
#-lpthreads -lc_r
|
||||
|
||||
MKSHLIB_BIN = /usr/lpp/xlC/bin/makeC++SharedLib_r
|
||||
MKSHLIB = $(MKSHLIB_BIN) -p 0 -G -berok -bM:UR
|
||||
|
||||
ifdef JS_THREADSAFE
|
||||
XLDFLAGS += -ldl
|
||||
endif
|
||||
|
||||
71
mozilla/js/src/config/HP-UXB.10.10.mk
Normal file
71
mozilla/js/src/config/HP-UXB.10.10.mk
Normal file
@@ -0,0 +1,71 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
#
|
||||
|
||||
#
|
||||
# Config stuff for HPUX
|
||||
#
|
||||
|
||||
# CC = gcc
|
||||
# CCC = g++
|
||||
# CFLAGS += -Wall -Wno-format -fPIC
|
||||
|
||||
CC = cc -Ae +Z
|
||||
CCC = CC -Ae +a1 +eh +Z
|
||||
|
||||
RANLIB = echo
|
||||
MKSHLIB = $(LD) -b
|
||||
|
||||
SO_SUFFIX = sl
|
||||
|
||||
#.c.o:
|
||||
# $(CC) -c -MD $*.d $(CFLAGS) $<
|
||||
|
||||
CPU_ARCH = hppa
|
||||
GFX_ARCH = x
|
||||
|
||||
OS_CFLAGS = -DXP_UNIX -DHPUX -DSYSV
|
||||
OS_LIBS = -ldld
|
||||
|
||||
ifeq ($(OS_RELEASE),B.10)
|
||||
PLATFORM_FLAGS += -DHPUX10 -Dhpux10
|
||||
PORT_FLAGS += -DRW_NO_OVERLOAD_SCHAR -DHAVE_MODEL_H
|
||||
ifeq ($(OS_VERSION),.10)
|
||||
PLATFORM_FLAGS += -DHPUX10_10
|
||||
endif
|
||||
ifeq ($(OS_VERSION),.20)
|
||||
PLATFORM_FLAGS += -DHPUX10_20
|
||||
endif
|
||||
ifeq ($(OS_VERSION),.30)
|
||||
PLATFORM_FLAGS += -DHPUX10_30
|
||||
endif
|
||||
endif
|
||||
71
mozilla/js/src/config/HP-UXB.10.20.mk
Normal file
71
mozilla/js/src/config/HP-UXB.10.20.mk
Normal file
@@ -0,0 +1,71 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
#
|
||||
|
||||
#
|
||||
# Config stuff for HPUX
|
||||
#
|
||||
|
||||
# CC = gcc
|
||||
# CCC = g++
|
||||
# CFLAGS += -Wall -Wno-format -fPIC
|
||||
|
||||
CC = cc -Ae +Z
|
||||
CCC = CC -Ae +a1 +eh +Z
|
||||
|
||||
RANLIB = echo
|
||||
MKSHLIB = $(LD) -b
|
||||
|
||||
SO_SUFFIX = sl
|
||||
|
||||
#.c.o:
|
||||
# $(CC) -c -MD $*.d $(CFLAGS) $<
|
||||
|
||||
CPU_ARCH = hppa
|
||||
GFX_ARCH = x
|
||||
|
||||
OS_CFLAGS = -DXP_UNIX -DHPUX -DSYSV
|
||||
OS_LIBS = -ldld
|
||||
|
||||
ifeq ($(OS_RELEASE),B.10)
|
||||
PLATFORM_FLAGS += -DHPUX10 -Dhpux10
|
||||
PORT_FLAGS += -DRW_NO_OVERLOAD_SCHAR -DHAVE_MODEL_H
|
||||
ifeq ($(OS_VERSION),.10)
|
||||
PLATFORM_FLAGS += -DHPUX10_10
|
||||
endif
|
||||
ifeq ($(OS_VERSION),.20)
|
||||
PLATFORM_FLAGS += -DHPUX10_20
|
||||
endif
|
||||
ifeq ($(OS_VERSION),.30)
|
||||
PLATFORM_FLAGS += -DHPUX10_30
|
||||
endif
|
||||
endif
|
||||
74
mozilla/js/src/config/HP-UXB.11.00.mk
Normal file
74
mozilla/js/src/config/HP-UXB.11.00.mk
Normal file
@@ -0,0 +1,74 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
#
|
||||
|
||||
#
|
||||
# Config stuff for HPUX
|
||||
#
|
||||
|
||||
ifdef NS_USE_NATIVE
|
||||
CC = cc +Z +DAportable +DS2.0 +u4
|
||||
# LD = aCC +Z -b -Wl,+s -Wl,-B,symbolic
|
||||
else
|
||||
CC = gcc -Wall -Wno-format -fPIC
|
||||
CCC = g++ -Wall -Wno-format -fPIC
|
||||
endif
|
||||
|
||||
RANLIB = echo
|
||||
MKSHLIB = $(LD) -b
|
||||
|
||||
SO_SUFFIX = sl
|
||||
|
||||
#.c.o:
|
||||
# $(CC) -c -MD $*.d $(CFLAGS) $<
|
||||
|
||||
CPU_ARCH = hppa
|
||||
GFX_ARCH = x
|
||||
|
||||
OS_CFLAGS = -DXP_UNIX -DHPUX -DSYSV -D_HPUX -DNATIVE -D_POSIX_C_SOURCE=199506L
|
||||
OS_LIBS = -ldld
|
||||
|
||||
XLDFLAGS = -lpthread
|
||||
|
||||
ifeq ($(OS_RELEASE),B.10)
|
||||
PLATFORM_FLAGS += -DHPUX10 -Dhpux10
|
||||
PORT_FLAGS += -DRW_NO_OVERLOAD_SCHAR -DHAVE_MODEL_H
|
||||
ifeq ($(OS_VERSION),.10)
|
||||
PLATFORM_FLAGS += -DHPUX10_10
|
||||
endif
|
||||
ifeq ($(OS_VERSION),.20)
|
||||
PLATFORM_FLAGS += -DHPUX10_20
|
||||
endif
|
||||
ifeq ($(OS_VERSION),.30)
|
||||
PLATFORM_FLAGS += -DHPUX10_30
|
||||
endif
|
||||
endif
|
||||
81
mozilla/js/src/config/IRIX.mk
Normal file
81
mozilla/js/src/config/IRIX.mk
Normal file
@@ -0,0 +1,81 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
#
|
||||
|
||||
#
|
||||
# Config stuff for IRIX
|
||||
#
|
||||
|
||||
CPU_ARCH = mips
|
||||
GFX_ARCH = x
|
||||
|
||||
RANLIB = /bin/true
|
||||
|
||||
#NS_USE_GCC = 1
|
||||
|
||||
ifndef NS_USE_NATIVE
|
||||
CC = gcc
|
||||
CCC = g++
|
||||
AS = $(CC) -x assembler-with-cpp
|
||||
ODD_CFLAGS = -Wall -Wno-format
|
||||
ifdef BUILD_OPT
|
||||
OPTIMIZER = -O6
|
||||
endif
|
||||
else
|
||||
ifeq ($(OS_RELEASE),6.2)
|
||||
CC = cc -n32 -DIRIX6_2
|
||||
endif
|
||||
ifeq ($(OS_RELEASE),6.3)
|
||||
CC = cc -n32 -DIRIX6_3
|
||||
endif
|
||||
ifeq ($(OS_RELEASE),6.5)
|
||||
CC = cc -n32 -DIRIX6_5
|
||||
endif
|
||||
CCC = CC
|
||||
# LD = CC
|
||||
ODD_CFLAGS = -fullwarn -xansi
|
||||
ifdef BUILD_OPT
|
||||
OPTIMIZER += -Olimit 4000
|
||||
endif
|
||||
endif
|
||||
|
||||
# For purify
|
||||
HAVE_PURIFY = 1
|
||||
PURE_OS_CFLAGS = $(ODD_CFLAGS) -DXP_UNIX -DSVR4 -DSW_THREADS -DIRIX
|
||||
|
||||
OS_CFLAGS = $(PURE_OS_CFLAGS) -MDupdate $(DEPENDENCIES)
|
||||
|
||||
BSDECHO = echo
|
||||
MKSHLIB = $(LD) -n32 -shared
|
||||
|
||||
# Use the editline library to provide line-editing support.
|
||||
JS_EDITLINE = 1
|
||||
38
mozilla/js/src/config/IRIX5.3.mk
Normal file
38
mozilla/js/src/config/IRIX5.3.mk
Normal file
@@ -0,0 +1,38 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
#
|
||||
|
||||
#
|
||||
# Config stuff for IRIX5.3
|
||||
#
|
||||
|
||||
include $(DEPTH)/config/IRIX.mk
|
||||
38
mozilla/js/src/config/IRIX6.1.mk
Normal file
38
mozilla/js/src/config/IRIX6.1.mk
Normal file
@@ -0,0 +1,38 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
#
|
||||
|
||||
#
|
||||
# Config stuff for IRIX6.3
|
||||
#
|
||||
|
||||
include $(DEPTH)/config/IRIX.mk
|
||||
38
mozilla/js/src/config/IRIX6.2.mk
Normal file
38
mozilla/js/src/config/IRIX6.2.mk
Normal file
@@ -0,0 +1,38 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
#
|
||||
|
||||
#
|
||||
# Config stuff for IRIX6.3
|
||||
#
|
||||
|
||||
include $(DEPTH)/config/IRIX.mk
|
||||
38
mozilla/js/src/config/IRIX6.3.mk
Normal file
38
mozilla/js/src/config/IRIX6.3.mk
Normal file
@@ -0,0 +1,38 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
#
|
||||
|
||||
#
|
||||
# Config stuff for IRIX6.3
|
||||
#
|
||||
|
||||
include $(DEPTH)/config/IRIX.mk
|
||||
38
mozilla/js/src/config/IRIX6.5.mk
Normal file
38
mozilla/js/src/config/IRIX6.5.mk
Normal file
@@ -0,0 +1,38 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
#
|
||||
|
||||
#
|
||||
# Config stuff for IRIX6.3
|
||||
#
|
||||
|
||||
include $(DEPTH)/config/IRIX.mk
|
||||
82
mozilla/js/src/config/Linux_All.mk
Normal file
82
mozilla/js/src/config/Linux_All.mk
Normal file
@@ -0,0 +1,82 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
#
|
||||
|
||||
#
|
||||
# Config for all versions of Linux
|
||||
#
|
||||
|
||||
CC = gcc
|
||||
CCC = g++
|
||||
CFLAGS += -Wall -Wno-format
|
||||
OS_CFLAGS = -DXP_UNIX -DSVR4 -DSYSV -D_BSD_SOURCE -DPOSIX_SOURCE
|
||||
|
||||
RANLIB = echo
|
||||
MKSHLIB = $(LD) -shared $(XMKSHLIBOPTS)
|
||||
|
||||
#.c.o:
|
||||
# $(CC) -c -MD $*.d $(CFLAGS) $<
|
||||
|
||||
CPU_ARCH = $(shell uname -m)
|
||||
ifeq (86,$(findstring 86,$(CPU_ARCH)))
|
||||
CPU_ARCH = x86
|
||||
OS_CFLAGS+= -DX86_LINUX
|
||||
|
||||
ifeq (gcc, $(CC))
|
||||
# if using gcc on x86, check version for opt bug
|
||||
# (http://bugzilla.mozilla.org/show_bug.cgi?id=24892)
|
||||
GCC_VERSION := $(shell gcc -v 2>&1 | grep version | awk '{ print $$3 }')
|
||||
GCC_LIST:=$(sort 2.91.66 $(GCC_VERSION) )
|
||||
|
||||
ifeq (2.91.66, $(firstword $(GCC_LIST)))
|
||||
CFLAGS+= -DGCC_OPT_BUG
|
||||
endif
|
||||
endif
|
||||
|
||||
endif
|
||||
GFX_ARCH = x
|
||||
|
||||
OS_LIBS = -lm -lc
|
||||
|
||||
ASFLAGS += -x assembler-with-cpp
|
||||
|
||||
|
||||
ifeq ($(CPU_ARCH),alpha)
|
||||
|
||||
# Ask the C compiler on alpha linux to let us work with denormalized
|
||||
# double values, which are required by the ECMA spec.
|
||||
|
||||
OS_CFLAGS += -mieee
|
||||
endif
|
||||
|
||||
# Use the editline library to provide line-editing support.
|
||||
JS_EDITLINE = 1
|
||||
77
mozilla/js/src/config/Mac_OS10.0.mk
Executable file
77
mozilla/js/src/config/Mac_OS10.0.mk
Executable file
@@ -0,0 +1,77 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Steve Zellers (zellers@apple.com)
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
#
|
||||
|
||||
#
|
||||
# Config for Mac OS X as of PR3
|
||||
# Just ripped from Linux config
|
||||
#
|
||||
|
||||
CC = cc
|
||||
CCC = g++
|
||||
CFLAGS += -Wall -Wno-format
|
||||
OS_CFLAGS = -DXP_UNIX -DSVR4 -DSYSV -D_BSD_SOURCE -DPOSIX_SOURCE
|
||||
-DRHAPSODY
|
||||
|
||||
RANLIB = ranlib
|
||||
MKSHLIB = libtool -dynamic $(XMKSHLIBOPTS) -framework System
|
||||
|
||||
#.c.o:
|
||||
# $(CC) -c -MD $*.d $(CFLAGS) $<
|
||||
|
||||
CPU_ARCH = $(shell uname -m)
|
||||
ifeq (86,$(findstring 86,$(CPU_ARCH)))
|
||||
CPU_ARCH = x86
|
||||
OS_CFLAGS+= -DX86_LINUX
|
||||
endif
|
||||
GFX_ARCH = x
|
||||
|
||||
OS_LIBS = -lc -framework System
|
||||
|
||||
ASFLAGS += -x assembler-with-cpp
|
||||
|
||||
ifeq ($(CPU_ARCH),alpha)
|
||||
|
||||
# Ask the C compiler on alpha linux to let us work with denormalized
|
||||
# double values, which are required by the ECMA spec.
|
||||
|
||||
OS_CFLAGS += -mieee
|
||||
endif
|
||||
|
||||
# Use the editline library to provide line-editing support.
|
||||
JS_EDITLINE = 1
|
||||
|
||||
# Don't allow Makefile.ref to use libmath
|
||||
NO_LIBM = 1
|
||||
|
||||
66
mozilla/js/src/config/OSF1V4.0.mk
Normal file
66
mozilla/js/src/config/OSF1V4.0.mk
Normal file
@@ -0,0 +1,66 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
#
|
||||
|
||||
#
|
||||
# Config stuff for Data General DG/UX
|
||||
#
|
||||
|
||||
#
|
||||
# Initial DG/UX port by Marc Fraioli (fraioli@dg-rtp.dg.com)
|
||||
#
|
||||
|
||||
ifndef NS_USE_NATIVE
|
||||
CC = gcc
|
||||
CCC = g++
|
||||
CFLAGS += -mieee -Wall -Wno-format
|
||||
else
|
||||
CC = cc
|
||||
CCC = cxx
|
||||
CFLAGS += -ieee -std
|
||||
# LD = cxx
|
||||
endif
|
||||
|
||||
RANLIB = echo
|
||||
MKSHLIB = $(LD) -shared -taso -all -expect_unresolved "*"
|
||||
|
||||
#
|
||||
# _DGUX_SOURCE is needed to turn on a lot of stuff in the headers if
|
||||
# you're not using DG's compiler. It shouldn't hurt if you are.
|
||||
#
|
||||
# _POSIX4A_DRAFT10_SOURCE is needed to pick up localtime_r, used in
|
||||
# prtime.c
|
||||
#
|
||||
OS_CFLAGS = -DXP_UNIX -DSVR4 -DSYSV -DDGUX -D_DGUX_SOURCE -D_POSIX4A_DRAFT10_SOURCE -DOSF1
|
||||
OS_LIBS = -lsocket -lnsl
|
||||
|
||||
NOSUCHFILE = /no-such-file
|
||||
95
mozilla/js/src/config/SunOS4.1.4.mk
Normal file
95
mozilla/js/src/config/SunOS4.1.4.mk
Normal file
@@ -0,0 +1,95 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
#
|
||||
|
||||
#
|
||||
# Config stuff for SunOS4.1
|
||||
#
|
||||
|
||||
CC = gcc
|
||||
CCC = g++
|
||||
RANLIB = ranlib
|
||||
|
||||
#.c.o:
|
||||
# $(CC) -c -MD $*.d $(CFLAGS) $<
|
||||
|
||||
CPU_ARCH = sparc
|
||||
GFX_ARCH = x
|
||||
|
||||
# A pile of -D's to build xfe on sunos
|
||||
MOZ_CFLAGS = -DSTRINGS_ALIGNED -DNO_REGEX -DNO_ISDIR -DUSE_RE_COMP \
|
||||
-DNO_REGCOMP -DUSE_GETWD -DNO_MEMMOVE -DNO_ALLOCA \
|
||||
-DBOGUS_MB_MAX -DNO_CONST
|
||||
|
||||
# Purify doesn't like -MDupdate
|
||||
NOMD_OS_CFLAGS = -DXP_UNIX -Wall -Wno-format -DSW_THREADS -DSUNOS4 -DNEED_SYSCALL \
|
||||
$(MOZ_CFLAGS)
|
||||
|
||||
OS_CFLAGS = $(NOMD_OS_CFLAGS) -MDupdate $(DEPENDENCIES)
|
||||
OS_LIBS = -ldl -lm
|
||||
|
||||
MKSHLIB = $(LD) -L$(MOTIF)/lib
|
||||
|
||||
HAVE_PURIFY = 1
|
||||
MOTIF = /home/motif/usr
|
||||
MOTIFLIB = -L$(MOTIF)/lib -lXm
|
||||
INCLUDES += -I/usr/X11R5/include -I$(MOTIF)/include
|
||||
|
||||
NOSUCHFILE = /solaris-rm-f-sucks
|
||||
|
||||
LOCALE_MAP = $(DEPTH)/cmd/xfe/intl/sunos.lm
|
||||
|
||||
EN_LOCALE = en_US
|
||||
DE_LOCALE = de
|
||||
FR_LOCALE = fr
|
||||
JP_LOCALE = ja
|
||||
SJIS_LOCALE = ja_JP.SJIS
|
||||
KR_LOCALE = ko
|
||||
CN_LOCALE = zh
|
||||
TW_LOCALE = zh_TW
|
||||
I2_LOCALE = i2
|
||||
IT_LOCALE = it
|
||||
SV_LOCALE = sv
|
||||
ES_LOCALE = es
|
||||
NL_LOCALE = nl
|
||||
PT_LOCALE = pt
|
||||
|
||||
LOC_LIB_DIR = /usr/openwin/lib/locale
|
||||
|
||||
BSDECHO = echo
|
||||
|
||||
#
|
||||
# These defines are for building unix plugins
|
||||
#
|
||||
BUILD_UNIX_PLUGINS = 1
|
||||
DSO_LDOPTS =
|
||||
DSO_LDFLAGS =
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user